feat: extract shop from mp/shop — initial libreshop/shop
Some checks failed
Build and publish / build (push) Failing after 19s

Source moved verbatim from mp/shop/ on 2026-04-29; mp was the first
concrete adapter consuming the libreshop toolkit. Builds and publishes
git.librete.ch/libreshop/shop on every main / v* push via the standard
.gitea/workflows/build.yml shared across libreshop components.
This commit is contained in:
Michael Czechowski
2026-04-29 17:48:56 +02:00
commit 44107c0734
134 changed files with 19521 additions and 0 deletions

267
types/index.ts Normal file
View File

@@ -0,0 +1,267 @@
// Simplified types for Nuxt frontend (independent of CMS Strapi types)
export interface MediaData {
id: number;
name: string;
alternativeText: string | null;
caption: string | null;
width: number | null;
height: number | null;
formats: {
[key: string]:
| {
ext: string;
url: string;
hash: string;
mime: string;
size: number;
width: number;
height: number;
}
| null
| undefined;
} | null;
hash: string;
ext: string;
mime: string;
size: number;
url: string;
previewUrl: string | null;
provider: string;
}
export interface StructuredAddress {
givenName: string;
familyName: string;
streetAddress: string;
postalCode: string;
addressLevel2: string; // city
country?: string;
}
export interface Address {
name: string;
surname: string;
street: string;
postalCode: string;
city: string;
}
export interface Product {
id: number;
name: string;
slug: string;
description?: string;
price?: number;
totalProductPrice?: number;
publishedAt?: string;
image?: MediaData;
images?: {
images: MediaData[];
};
cover?: ProductCover;
ruling?: ProductRuling;
pages?: ProductPages;
pattern?: ProductPattern;
attributes?: {
name: string;
slug: string;
description?: string;
price?: number;
[key: string]: unknown;
};
}
export interface ProductCover {
id: number;
name: string;
binding?: string;
sort?: number;
copyText?: CopyText;
slides?: MediaData[];
icon?: MediaData;
productVariant?: {
id: number;
slug: string;
};
attributes?: {
name: string;
binding?: string;
sort?: number;
copyText?: CopyText;
};
}
export interface CopyText {
format?: string;
details?: string;
paper?: string;
cover?: string;
text?: string;
banderole?: string;
}
export interface ProductPages {
id: number;
name: string;
count?: number;
icon?: MediaData;
productVariant?: {
id: number;
slug: string;
};
attributes?: {
name: string;
count?: number;
};
}
export interface ProductRuling {
id: number;
name: string;
icon?: MediaData;
productVariant?: {
id: number;
slug: string;
};
attributes?: {
name: string;
icon?: { data: { attributes: MediaData } };
};
}
export interface ProductPattern {
id: number;
name: string;
description?: string;
image?: MediaData;
productVariant?: {
id: number;
slug: string;
};
attributes?: {
name: string;
description?: string;
image?: { data: { attributes: MediaData } };
};
}
export interface DeliveryMethod {
id: number;
name: string;
price: number;
description: string | null;
}
export interface PaymentMethod {
id: number;
name: string;
price: number;
description: string | null;
}
export interface CartProduct {
id: number;
count: number;
product: Product;
}
export interface Cart {
uuid: string;
products: CartProduct[] | null;
productsCount: number;
total: number;
subtotal: number;
VAT: number;
emailAddress: string;
delivery: number;
invoiceAddress: string;
deliveryAddress: string;
deliveryMethod: number | null;
invoiceAddressStructured: StructuredAddress | null;
deliveryAddressStructured: StructuredAddress | null;
acceptedTermsAndConditionsAt: boolean;
}
export interface Order {
id?: number;
uuid: string;
subtotal: number | null;
VAT: number | null;
total: number;
email: string | null;
cart?: CartProduct[] | null;
invoiceAddress: string | null;
deliveryAddress: string | null;
acceptedTermsAndConditionsAt: boolean | null;
invoiceAddressStructured?: StructuredAddress;
deliveryAddressStructured?: StructuredAddress;
delivery?: DeliveryMethod | null;
payment?: PaymentMethod | null;
paymentAuthorised?: boolean;
}
export type OrderUpdateBody = Partial<Order>;
export interface ProductVariantResponse {
pages: ProductPages[];
cover: ProductCover[];
ruling: ProductRuling[];
}
export interface PatternVariantsResponse {
patterns: {
id: number;
name: string;
description: string;
image: {
id: number;
url: string;
};
productVariant?: Product;
}[];
}
export type Legal = Record<LegalPage, string>;
export type LegalPage = "imprint" | "contact" | "terms" | "privacy" | "delivery" | "payment";
export interface Testimonial {
name?: string;
purpose?: string;
avatar?: string;
comment: string;
rating: number;
}
export type Content = Record<ContentPage, string>;
export type ContentPage = "production";
// API Response wrapper
export interface ApiResponse<T> {
data: T[];
meta: {
pagination: {
page: number;
pageCount: number;
pageSize: number;
total: number;
};
};
}
// Website navigation item
export interface WebsiteNavItem {
id: string | number;
label: string;
showInHeader: boolean;
showInFooter: boolean;
}
// Cover navigation item
export interface CoverNavItem {
id: string | number;
label: string;
slug: string;
description?: string;
sort?: number;
}