Blog categories (hasMany), shipping-address contact fields, product SKU on invoices

- Posts.categories is now hasMany — blog list/detail/live-preview render
  a comma-joined list instead of a single category.
- Checkout's "Abweichende Lieferadresse" gains optional Firma + Kontakt-
  E-Mail/Telefon fields (handed to the shipping carrier, not used for
  customer communication).
- Customer profile can now store its own shipping address (mirroring
  Customers.ts's new "Lieferadresse" tab), prefilling the checkout
  override instead of always starting blank.
- Product-level optional SKU (previously only on variants) snapshots onto
  each order item and shows up on invoices (visual + EN16931 XML),
  the confirmation email, and the account order detail page.
This commit is contained in:
Marco
2026-07-30 08:41:39 +00:00
parent 1467750db6
commit e3352d7e32
18 changed files with 403 additions and 34 deletions
+8 -8
View File
@@ -21,7 +21,7 @@ export type BlogPost = {
id: number;
title: string;
slug: string;
category: string;
categories: string[];
readTime: number;
excerpt: string;
thumbnail: string | null;
@@ -33,7 +33,7 @@ type PayloadPost = {
id: number;
title: string;
slug: string;
category: { name: string } | number | null;
categories: ({ name: string } | number)[];
readTime: number;
excerpt: string;
thumbnail: { url: string } | number | null;
@@ -73,10 +73,9 @@ export async function getBlogPosts(limit = 3): Promise<BlogPost[]> {
id: post.id,
title: post.title,
slug: post.slug,
category:
typeof post.category === "object" && post.category
? post.category.name
: "",
categories: (post.categories ?? [])
.map((c) => (typeof c === "object" && c ? c.name : null))
.filter((name): name is string => Boolean(name)),
readTime: post.readTime,
excerpt: post.excerpt,
thumbnail:
@@ -125,8 +124,9 @@ export function mapPayloadPost(doc: PayloadPostDetail): PostDetail {
id: doc.id,
title: doc.title,
slug: doc.slug,
category:
typeof doc.category === "object" && doc.category ? doc.category.name : "",
categories: (doc.categories ?? [])
.map((c) => (typeof c === "object" && c ? c.name : null))
.filter((name): name is string => Boolean(name)),
readTime: doc.readTime,
excerpt: doc.excerpt,
thumbnail: