@xiwebdesign/xicms-core 6.1.1 → 6.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -333,84 +333,7 @@ export declare const DiscountCodeSchema: z.ZodObject<{
333
333
  usedCount?: number | undefined;
334
334
  }>;
335
335
  export type DiscountCode = z.infer<typeof DiscountCodeSchema>;
336
- export declare const MAIL_TEMPLATE_KEYS: readonly ["orderConfirmation", "orderShipped", "orderCancelled", "orderRefunded", "donationThanks", "formConfirmation"];
337
- export type MailTemplateKey = (typeof MAIL_TEMPLATE_KEYS)[number];
338
- /**
339
- * `sites/{siteId}/settings/mailTemplates` — per template onderwerp + platte tekst met
340
- * `{{placeholders}}` ({{naam}}, {{ordernummer}}, {{regels}}, {{totaal}}, {{verzendadres}},
341
- * {{trackingUrl}}, {{sitenaam}}, {{notitie}}). Ontbrekend veld → ingebouwde default.
342
- */
343
- export declare const MailTemplateSchema: z.ZodObject<{
344
- subject: z.ZodOptional<z.ZodString>;
345
- bodyText: z.ZodOptional<z.ZodString>;
346
- }, "strip", z.ZodTypeAny, {
347
- subject?: string | undefined;
348
- bodyText?: string | undefined;
349
- }, {
350
- subject?: string | undefined;
351
- bodyText?: string | undefined;
352
- }>;
353
- export declare const MailTemplatesSchema: z.ZodObject<Record<"orderConfirmation" | "orderShipped" | "orderCancelled" | "orderRefunded" | "donationThanks" | "formConfirmation", z.ZodOptional<z.ZodObject<{
354
- subject: z.ZodOptional<z.ZodString>;
355
- bodyText: z.ZodOptional<z.ZodString>;
356
- }, "strip", z.ZodTypeAny, {
357
- subject?: string | undefined;
358
- bodyText?: string | undefined;
359
- }, {
360
- subject?: string | undefined;
361
- bodyText?: string | undefined;
362
- }>>>, "strip", z.ZodTypeAny, {
363
- orderConfirmation?: {
364
- subject?: string | undefined;
365
- bodyText?: string | undefined;
366
- } | undefined;
367
- orderShipped?: {
368
- subject?: string | undefined;
369
- bodyText?: string | undefined;
370
- } | undefined;
371
- orderCancelled?: {
372
- subject?: string | undefined;
373
- bodyText?: string | undefined;
374
- } | undefined;
375
- orderRefunded?: {
376
- subject?: string | undefined;
377
- bodyText?: string | undefined;
378
- } | undefined;
379
- donationThanks?: {
380
- subject?: string | undefined;
381
- bodyText?: string | undefined;
382
- } | undefined;
383
- formConfirmation?: {
384
- subject?: string | undefined;
385
- bodyText?: string | undefined;
386
- } | undefined;
387
- }, {
388
- orderConfirmation?: {
389
- subject?: string | undefined;
390
- bodyText?: string | undefined;
391
- } | undefined;
392
- orderShipped?: {
393
- subject?: string | undefined;
394
- bodyText?: string | undefined;
395
- } | undefined;
396
- orderCancelled?: {
397
- subject?: string | undefined;
398
- bodyText?: string | undefined;
399
- } | undefined;
400
- orderRefunded?: {
401
- subject?: string | undefined;
402
- bodyText?: string | undefined;
403
- } | undefined;
404
- donationThanks?: {
405
- subject?: string | undefined;
406
- bodyText?: string | undefined;
407
- } | undefined;
408
- formConfirmation?: {
409
- subject?: string | undefined;
410
- bodyText?: string | undefined;
411
- } | undefined;
412
- }>;
413
- export type MailTemplates = z.infer<typeof MailTemplatesSchema>;
336
+ export { MAIL_TEMPLATE_KEYS, MAIL_TEMPLATE_DEFS, MailTemplateSchema, MailTemplatesSchema, type MailTemplateKey, type MailTemplates, } from "./mail";
414
337
  export declare const OrderStatusSchema: z.ZodEnum<["pending", "paid", "shipped", "cancelled", "refunded"]>;
415
338
  export type OrderStatus = z.infer<typeof OrderStatusSchema>;
416
339
  /** Orderregel: snapshot van naam/prijs op besteldatum — blijft kloppen als het product wijzigt. */
@@ -93,21 +93,12 @@ const DiscountCodeSchema = z.object({
93
93
  maxUses: z.number().int().min(0).max(1e6).default(0),
94
94
  usedCount: z.number().int().min(0).default(0)
95
95
  });
96
- const MAIL_TEMPLATE_KEYS = [
97
- "orderConfirmation",
98
- "orderShipped",
99
- "orderCancelled",
100
- "orderRefunded",
101
- "donationThanks",
102
- "formConfirmation"
103
- ];
104
- const MailTemplateSchema = z.object({
105
- subject: z.string().max(200).optional(),
106
- bodyText: z.string().max(1e4).optional()
107
- });
108
- const MailTemplatesSchema = z.object(
109
- Object.fromEntries(MAIL_TEMPLATE_KEYS.map((k) => [k, MailTemplateSchema.optional()]))
110
- );
96
+ import {
97
+ MAIL_TEMPLATE_KEYS,
98
+ MAIL_TEMPLATE_DEFS,
99
+ MailTemplateSchema,
100
+ MailTemplatesSchema
101
+ } from "./mail";
111
102
  const OrderStatusSchema = z.enum(["pending", "paid", "shipped", "cancelled", "refunded"]);
112
103
  const OrderItemSchema = z.object({
113
104
  kind: z.enum(["product", "donation"]).default("product"),
@@ -271,6 +262,7 @@ export {
271
262
  CreateOrderItemInputSchema,
272
263
  DiscountCodeSchema,
273
264
  DonationBlockSchema,
265
+ MAIL_TEMPLATE_DEFS,
274
266
  MAIL_TEMPLATE_KEYS,
275
267
  MailTemplateSchema,
276
268
  MailTemplatesSchema,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/schema/shop.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { blockBase } from \"./blocks\";\n\n/**\n * Shop-schema's (5.5) — webwinkel + donaties. Pure Zod: gedeeld door core, admin en Functions.\n *\n * Datamodel per tenant:\n * sites/{siteId}/shopCategories/{id} — categorieën (editor-write, publiek leesbaar)\n * sites/{siteId}/products/{id} — producten (editor-write, publiek leesbaar als actief)\n * sites/{siteId}/orders/{id} — bestellingen (ALLEEN via Functions; editor leest,\n * en mag alleen status/verzendvelden muteren)\n * sites/{siteId}/private/shop — geheimen (Stripe-key, SMTP) — deny-all, alleen Functions\n *\n * Geld is ALTIJD een integer in centen (nooit floats). Publieke shopconfig (verzendkosten,\n * paden, donatie-grenzen) leeft in de module-settings van de `shop`-module\n * (settings/public.modules.shop.config) — zie modules/shop/module.ts.\n */\n\n/* ── Categorieën ─────────────────────────────────────────────────────────── */\n\nexport const ShopCategorySchema = z.object({\n name: z.string().min(1).max(120),\n slug: z\n .string()\n .min(1)\n .max(120)\n .regex(/^[a-z0-9-]+$/, \"slug: alleen kleine letters, cijfers en streepjes\"),\n description: z.string().max(2000).optional(),\n imageUrl: z.string().max(2000).optional(),\n order: z.number().int().min(0).max(9999).default(0),\n visible: z.boolean().default(true),\n});\nexport type ShopCategory = z.infer<typeof ShopCategorySchema>;\n\n/* ── Producten ───────────────────────────────────────────────────────────── */\n\n/** Optie-as, bv. { name: \"Maat\", values: [\"56\",\"62\",\"68\",\"74\"] }. Max 3 assen per product. */\nexport const ProductOptionSchema = z.object({\n name: z.string().min(1).max(40),\n values: z.array(z.string().min(1).max(60)).min(1).max(30),\n /**\n * 5.6: afbeelding per optieWAARDE (praktijk: de kleur-as) — `{ \"Roze\": \"https://…\" }`.\n * De detailpagina wisselt het hoofdbeeld mee met de keuze; bewust per as en niet per\n * variant-combinatie (maat × kleur zou het aantal afbeeldingen laten exploderen).\n */\n images: z.record(z.string(), z.string().max(2000)).optional(),\n});\nexport type ProductOption = z.infer<typeof ProductOptionSchema>;\n\n/**\n * Personalisatie-veld (5.6): de klant geeft eigen tekst of een eigen afbeelding op\n * (bv. \"rompertje met naam\"). Meerprijs telt server-side mee in `createOrder`.\n */\nexport const PersonalizationFieldSchema = z.object({\n key: z\n .string()\n .min(1)\n .max(40)\n .regex(/^[a-zA-Z][a-zA-Z0-9_]*$/, \"sleutel: letters/cijfers/underscore, beginnend met een letter\"),\n label: z.string().min(1).max(120),\n type: z.enum([\"text\", \"image\"]),\n required: z.boolean().default(false),\n /** Alleen voor type \"text\". */\n maxLength: z.number().int().min(1).max(200).default(40),\n /** Meerprijs in centen (per stuk). */\n priceCents: z.number().int().min(0).max(1_000_000_00).default(0),\n helpText: z.string().max(200).optional(),\n});\nexport type PersonalizationField = z.infer<typeof PersonalizationFieldSchema>;\n\n/** Ingevulde personalisatie op een orderregel/cartregel: per veld-key tekst of upload-pad. */\nexport const PersonalizationValueSchema = z.record(\n z.string(),\n z.object({\n text: z.string().max(200).optional(),\n /** Storage-pad uit de uploadPersonalization-callable (géén vrije URL). */\n imagePath: z.string().max(400).optional(),\n /** Oorspronkelijke bestandsnaam (weergave in beheer/mail). */\n fileName: z.string().max(200).optional(),\n }),\n);\nexport type PersonalizationValue = z.infer<typeof PersonalizationValueSchema>;\n\n/**\n * Variant = één combinatie van optiewaarden. `key` is de waarden gejoined met \"|\" in\n * optie-volgorde (bv. \"68|Roze\"). Alleen aanwezig waar hij afwijkt van de product-defaults.\n */\nexport const ProductVariantSchema = z.object({\n key: z.string().min(1).max(200),\n priceCents: z.number().int().min(0).max(1_000_000_00).optional(),\n stock: z.number().int().min(0).max(1_000_000).optional(),\n sku: z.string().max(60).optional(),\n active: z.boolean().default(true),\n});\nexport type ProductVariant = z.infer<typeof ProductVariantSchema>;\n\nexport const ProductStatusSchema = z.enum([\"draft\", \"active\", \"archived\"]);\nexport type ProductStatus = z.infer<typeof ProductStatusSchema>;\n\nexport const ProductSchema = z.object({\n name: z.string().min(1).max(200),\n slug: z\n .string()\n .min(1)\n .max(120)\n .regex(/^[a-z0-9-]+$/, \"slug: alleen kleine letters, cijfers en streepjes\"),\n /**\n * Beschrijving als platte tekst (regeleinden blijven behouden). Bewust géén HTML:\n * producten worden client-side door editors geschreven (rules-pad, niet via de\n * publish-sanitizer), dus HTML zou hier een XSS-route zijn.\n */\n description: z.string().max(20_000).default(\"\"),\n categoryIds: z.array(z.string().max(80)).max(20).default([]),\n /** Afbeeldings-URL's (via de mediabibliotheek). Eerste = hoofdbeeld. */\n images: z.array(z.string().max(2000)).max(12).default([]),\n /** Prijs incl. btw, in centen. */\n priceCents: z.number().int().min(0).max(1_000_000_00).default(0),\n /** Doorgestreepte \"van\"-prijs (optioneel). */\n compareAtCents: z.number().int().min(0).max(1_000_000_00).optional(),\n /** Btw-tarief (NL): 21, 9 of 0. Prijzen zijn inclusief. */\n vatRate: z.union([z.literal(21), z.literal(9), z.literal(0)]).default(21),\n options: z.array(ProductOptionSchema).max(3).default([]),\n variants: z.array(ProductVariantSchema).max(200).default([]),\n /** Voorraad bijhouden? false = altijd bestelbaar (op-maat/print-on-demand). */\n trackStock: z.boolean().default(false),\n /** Voorraad voor producten zónder varianten (met varianten telt de variant-stock). */\n stock: z.number().int().min(0).max(1_000_000).optional(),\n status: ProductStatusSchema.default(\"draft\"),\n /** Sorteervolgorde binnen een categorie (laag = eerst). */\n order: z.number().int().min(0).max(9999).default(0),\n featured: z.boolean().default(false),\n /** 5.6: personalisatie-velden (eigen naam/logo) — max 3 per product. */\n personalization: z.array(PersonalizationFieldSchema).max(3).optional(),\n});\nexport type Product = z.infer<typeof ProductSchema>;\n\n/* ── Kortingscodes ───────────────────────────────────────────────────────── */\n\n/** `sites/{siteId}/discountCodes/{CODE}` (doc-id = code in hoofdletters; editor beheert). */\nexport const DiscountCodeSchema = z.object({\n code: z\n .string()\n .min(3)\n .max(30)\n .regex(/^[A-Z0-9-]+$/, \"code: hoofdletters, cijfers en streepjes\"),\n type: z.enum([\"percent\", \"fixed\"]),\n /** percent: 1–100; fixed: bedrag in centen. */\n value: z.number().int().min(1).max(1_000_000_00),\n minOrderCents: z.number().int().min(0).max(1_000_000_00).default(0),\n freeShipping: z.boolean().default(false),\n active: z.boolean().default(true),\n /** ISO-datums (yyyy-mm-dd); leeg = geen grens. */\n startsAt: z.string().max(10).optional(),\n endsAt: z.string().max(10).optional(),\n /** 0 = onbeperkt. `usedCount` wordt door de webhook transactioneel opgehoogd. */\n maxUses: z.number().int().min(0).max(1_000_000).default(0),\n usedCount: z.number().int().min(0).default(0),\n});\nexport type DiscountCode = z.infer<typeof DiscountCodeSchema>;\n\n/* ── Mail-templates ──────────────────────────────────────────────────────── */\n\nexport const MAIL_TEMPLATE_KEYS = [\n \"orderConfirmation\",\n \"orderShipped\",\n \"orderCancelled\",\n \"orderRefunded\",\n \"donationThanks\",\n \"formConfirmation\",\n] as const;\nexport type MailTemplateKey = (typeof MAIL_TEMPLATE_KEYS)[number];\n\n/**\n * `sites/{siteId}/settings/mailTemplates` — per template onderwerp + platte tekst met\n * `{{placeholders}}` ({{naam}}, {{ordernummer}}, {{regels}}, {{totaal}}, {{verzendadres}},\n * {{trackingUrl}}, {{sitenaam}}, {{notitie}}). Ontbrekend veld → ingebouwde default.\n */\nexport const MailTemplateSchema = z.object({\n subject: z.string().max(200).optional(),\n bodyText: z.string().max(10_000).optional(),\n});\nexport const MailTemplatesSchema = z.object(\n Object.fromEntries(MAIL_TEMPLATE_KEYS.map((k) => [k, MailTemplateSchema.optional()])) as Record<\n MailTemplateKey,\n z.ZodOptional<typeof MailTemplateSchema>\n >,\n);\nexport type MailTemplates = z.infer<typeof MailTemplatesSchema>;\n\n/* ── Bestellingen ────────────────────────────────────────────────────────── */\n\nexport const OrderStatusSchema = z.enum([\"pending\", \"paid\", \"shipped\", \"cancelled\", \"refunded\"]);\nexport type OrderStatus = z.infer<typeof OrderStatusSchema>;\n\n/** Orderregel: snapshot van naam/prijs op besteldatum — blijft kloppen als het product wijzigt. */\nexport const OrderItemSchema = z.object({\n kind: z.enum([\"product\", \"donation\"]).default(\"product\"),\n productId: z.string().max(80).optional(),\n name: z.string().min(1).max(240),\n variantKey: z.string().max(200).optional(),\n qty: z.number().int().min(1).max(999),\n /** Incl. eventuele personalisatie-meerprijs. */\n unitPriceCents: z.number().int().min(0).max(1_000_000_00),\n vatRate: z.union([z.literal(21), z.literal(9), z.literal(0)]).default(21),\n /** 5.6: ingevulde personalisatie (\"Naam: Boaz\", upload-pad). */\n personalization: PersonalizationValueSchema.optional(),\n});\nexport type OrderItem = z.infer<typeof OrderItemSchema>;\n\nexport const OrderAddressSchema = z.object({\n address: z.string().min(1).max(200),\n zip: z.string().min(1).max(20),\n city: z.string().min(1).max(120),\n country: z.string().min(2).max(2).default(\"NL\"),\n});\nexport type OrderAddress = z.infer<typeof OrderAddressSchema>;\n\nexport const OrderCustomerSchema = z.object({\n email: z.string().email().max(200),\n name: z.string().min(1).max(200),\n phone: z.string().max(40).optional(),\n});\nexport type OrderCustomer = z.infer<typeof OrderCustomerSchema>;\n\n/** Volledige order zoals door Functions geschreven (timestamps komen daarbovenop). */\nexport const OrderSchema = z.object({\n number: z.string().min(1).max(40),\n status: OrderStatusSchema,\n items: z.array(OrderItemSchema).min(1).max(50),\n amount: z.object({\n itemsCents: z.number().int().min(0),\n shippingCents: z.number().int().min(0),\n /** 5.6: toegepaste korting (0 = geen). */\n discountCents: z.number().int().min(0).default(0),\n totalCents: z.number().int().min(0),\n }),\n /** 5.6: toegepaste kortingscode (snapshot). */\n discount: z\n .object({\n code: z.string().max(30),\n type: z.enum([\"percent\", \"fixed\"]),\n value: z.number().int(),\n freeShipping: z.boolean().default(false),\n })\n .optional(),\n customer: OrderCustomerSchema,\n shipping: OrderAddressSchema.optional(),\n note: z.string().max(2000).optional(),\n /** 5.6: track & trace-link (gezet bij \"verzonden\"). */\n trackingUrl: z.string().max(500).optional(),\n /** 5.6: factuur-pad in Storage (gezet door de webhook). */\n invoicePath: z.string().max(400).optional(),\n stripe: z\n .object({\n sessionId: z.string().max(200).optional(),\n paymentIntentId: z.string().max(200).optional(),\n })\n .default({}),\n});\nexport type Order = z.infer<typeof OrderSchema>;\n\n/* ── Callable-input (checkout) ───────────────────────────────────────────── */\n\n/**\n * Input van de `createOrder`-callable. Client-prijzen worden NOOIT vertrouwd: de functie\n * herrekent alles tegen de opgeslagen product-docs. Alleen `donationCents` komt van de\n * client (binnen de per-site ingestelde min/max van het donatie-block).\n */\nexport const CreateOrderItemInputSchema = z.object({\n productId: z.string().min(1).max(80).optional(),\n variantKey: z.string().max(200).optional(),\n qty: z.number().int().min(1).max(999).default(1),\n /** Alleen voor donaties (zonder productId). */\n donationCents: z.number().int().min(50).max(1_000_000_00).optional(),\n /** 5.6: personalisatie-invoer (gevalideerd tegen product.personalization). */\n personalization: PersonalizationValueSchema.optional(),\n});\n\nexport const CreateOrderInputSchema = z.object({\n siteId: z.string().min(1).max(80),\n items: z.array(CreateOrderItemInputSchema).min(1).max(50),\n customer: OrderCustomerSchema,\n shipping: OrderAddressSchema.optional(),\n note: z.string().max(2000).optional(),\n /** 5.6: kortingscode (server-side gevalideerd en verrekend). */\n discountCode: z.string().max(30).optional(),\n /** Paden op de klantsite waarheen Stripe terug redirect. */\n successPath: z.string().max(400).default(\"/bedankt\"),\n cancelPath: z.string().max(400).default(\"/winkelwagen\"),\n /** Honeypot — moet leeg zijn (bot-detectie). */\n _hp: z.string().max(0).optional(),\n});\nexport type CreateOrderInput = z.infer<typeof CreateOrderInputSchema>;\n\n/* ── Block-schema's ──────────────────────────────────────────────────────── */\n\nexport const ShopCategoriesBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"shopCategories\"),\n heading: z.string().max(200).optional(),\n columns: z.number().int().min(2).max(4).default(3),\n});\n\nexport const ProductGridBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"productGrid\"),\n heading: z.string().max(200).optional(),\n /** Vast categorie-filter (slug). Leeg + useQueryCategory → filter via `?cat=` in de URL. */\n categorySlug: z.string().max(120).optional(),\n useQueryCategory: z.boolean().default(true),\n featuredOnly: z.boolean().default(false),\n columns: z.number().int().min(2).max(4).default(3),\n limit: z.number().int().min(1).max(200).default(60),\n sort: z.enum([\"order\", \"name\", \"priceAsc\", \"priceDesc\"]).default(\"order\"),\n /** 5.6: filterchips (kleur/maat) + sorteerkeuze boven het grid. */\n showFilters: z.boolean().default(false),\n});\n\nexport const ProductDetailBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"productDetail\"),\n /** Vast product (slug); leeg → product uit `?p=` in de URL (één generieke detailpagina). */\n slug: z.string().max(120).optional(),\n /** 5.6: \"Ook leuk\"-rij met producten uit dezelfde categorie. */\n showRelated: z.boolean().default(true),\n});\n\nexport const CartBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"cart\"),\n heading: z.string().max(200).optional(),\n});\n\nexport const CheckoutBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"checkout\"),\n heading: z.string().max(200).optional(),\n introText: z.string().max(2000).optional(),\n});\n\nexport const DonationBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"donation\"),\n heading: z.string().max(200).optional(),\n introText: z.string().max(2000).optional(),\n /** Voorgestelde bedragen in centen. */\n amountsCents: z.array(z.number().int().min(50).max(1_000_000_00)).max(8).default([500, 1000, 2500]),\n allowCustom: z.boolean().default(true),\n customMinCents: z.number().int().min(50).default(100),\n customMaxCents: z.number().int().max(1_000_000_00).default(100_000),\n buttonLabel: z.string().max(80).default(\"Doneer\"),\n});\n\nexport const OrderStatusBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"orderStatus\"),\n successTitle: z.string().max(200).default(\"Bedankt voor je bestelling!\"),\n successText: z.string().max(2000).default(\"Je ontvangt zo een bevestiging per e-mail.\"),\n cancelledTitle: z.string().max(200).default(\"Betaling niet afgerond\"),\n cancelledText: z.string().max(2000).default(\"Je bestelling is niet betaald. Probeer het gerust opnieuw.\"),\n});\n\n/* ── Helpers (gedeeld client/server) ─────────────────────────────────────── */\n\n/** Variant-key uit gekozen optiewaarden, in optie-volgorde: [\"68\",\"Roze\"] → \"68|Roze\". */\nexport function variantKeyFor(values: string[]): string {\n return values.join(\"|\");\n}\n\n/** Effectieve prijs van een product(-variant) in centen. */\nexport function productPriceCents(product: Pick<Product, \"priceCents\" | \"variants\">, variantKey?: string): number {\n if (variantKey) {\n const v = product.variants?.find((x) => x.key === variantKey);\n if (v?.priceCents !== undefined) return v.priceCents;\n }\n return product.priceCents;\n}\n\n/** Verzendkosten volgens de publieke shopconfig (flat + gratis-vanaf). Donatie-only = gratis. */\nexport function shippingCentsFor(\n itemsCents: number,\n cfg: { shippingFlatCents?: number; shippingFreeFromCents?: number },\n hasShippableItems: boolean,\n): number {\n if (!hasShippableItems) return 0;\n const flat = cfg.shippingFlatCents ?? 0;\n const freeFrom = cfg.shippingFreeFromCents;\n if (freeFrom !== undefined && freeFrom > 0 && itemsCents >= freeFrom) return 0;\n return flat;\n}\n\n/** Centen → \"€ 13,95\" (nl-NL). */\nexport function formatCents(cents: number, currency = \"EUR\"): string {\n return new Intl.NumberFormat(\"nl-NL\", { style: \"currency\", currency }).format(cents / 100);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/schema/shop.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { blockBase } from \"./blocks\";\n\n/**\n * Shop-schema's (5.5) — webwinkel + donaties. Pure Zod: gedeeld door core, admin en Functions.\n *\n * Datamodel per tenant:\n * sites/{siteId}/shopCategories/{id} — categorieën (editor-write, publiek leesbaar)\n * sites/{siteId}/products/{id} — producten (editor-write, publiek leesbaar als actief)\n * sites/{siteId}/orders/{id} — bestellingen (ALLEEN via Functions; editor leest,\n * en mag alleen status/verzendvelden muteren)\n * sites/{siteId}/private/shop — geheimen (Stripe-key, SMTP) — deny-all, alleen Functions\n *\n * Geld is ALTIJD een integer in centen (nooit floats). Publieke shopconfig (verzendkosten,\n * paden, donatie-grenzen) leeft in de module-settings van de `shop`-module\n * (settings/public.modules.shop.config) — zie modules/shop/module.ts.\n */\n\n/* ── Categorieën ─────────────────────────────────────────────────────────── */\n\nexport const ShopCategorySchema = z.object({\n name: z.string().min(1).max(120),\n slug: z\n .string()\n .min(1)\n .max(120)\n .regex(/^[a-z0-9-]+$/, \"slug: alleen kleine letters, cijfers en streepjes\"),\n description: z.string().max(2000).optional(),\n imageUrl: z.string().max(2000).optional(),\n order: z.number().int().min(0).max(9999).default(0),\n visible: z.boolean().default(true),\n});\nexport type ShopCategory = z.infer<typeof ShopCategorySchema>;\n\n/* ── Producten ───────────────────────────────────────────────────────────── */\n\n/** Optie-as, bv. { name: \"Maat\", values: [\"56\",\"62\",\"68\",\"74\"] }. Max 3 assen per product. */\nexport const ProductOptionSchema = z.object({\n name: z.string().min(1).max(40),\n values: z.array(z.string().min(1).max(60)).min(1).max(30),\n /**\n * 5.6: afbeelding per optieWAARDE (praktijk: de kleur-as) — `{ \"Roze\": \"https://…\" }`.\n * De detailpagina wisselt het hoofdbeeld mee met de keuze; bewust per as en niet per\n * variant-combinatie (maat × kleur zou het aantal afbeeldingen laten exploderen).\n */\n images: z.record(z.string(), z.string().max(2000)).optional(),\n});\nexport type ProductOption = z.infer<typeof ProductOptionSchema>;\n\n/**\n * Personalisatie-veld (5.6): de klant geeft eigen tekst of een eigen afbeelding op\n * (bv. \"rompertje met naam\"). Meerprijs telt server-side mee in `createOrder`.\n */\nexport const PersonalizationFieldSchema = z.object({\n key: z\n .string()\n .min(1)\n .max(40)\n .regex(/^[a-zA-Z][a-zA-Z0-9_]*$/, \"sleutel: letters/cijfers/underscore, beginnend met een letter\"),\n label: z.string().min(1).max(120),\n type: z.enum([\"text\", \"image\"]),\n required: z.boolean().default(false),\n /** Alleen voor type \"text\". */\n maxLength: z.number().int().min(1).max(200).default(40),\n /** Meerprijs in centen (per stuk). */\n priceCents: z.number().int().min(0).max(1_000_000_00).default(0),\n helpText: z.string().max(200).optional(),\n});\nexport type PersonalizationField = z.infer<typeof PersonalizationFieldSchema>;\n\n/** Ingevulde personalisatie op een orderregel/cartregel: per veld-key tekst of upload-pad. */\nexport const PersonalizationValueSchema = z.record(\n z.string(),\n z.object({\n text: z.string().max(200).optional(),\n /** Storage-pad uit de uploadPersonalization-callable (géén vrije URL). */\n imagePath: z.string().max(400).optional(),\n /** Oorspronkelijke bestandsnaam (weergave in beheer/mail). */\n fileName: z.string().max(200).optional(),\n }),\n);\nexport type PersonalizationValue = z.infer<typeof PersonalizationValueSchema>;\n\n/**\n * Variant = één combinatie van optiewaarden. `key` is de waarden gejoined met \"|\" in\n * optie-volgorde (bv. \"68|Roze\"). Alleen aanwezig waar hij afwijkt van de product-defaults.\n */\nexport const ProductVariantSchema = z.object({\n key: z.string().min(1).max(200),\n priceCents: z.number().int().min(0).max(1_000_000_00).optional(),\n stock: z.number().int().min(0).max(1_000_000).optional(),\n sku: z.string().max(60).optional(),\n active: z.boolean().default(true),\n});\nexport type ProductVariant = z.infer<typeof ProductVariantSchema>;\n\nexport const ProductStatusSchema = z.enum([\"draft\", \"active\", \"archived\"]);\nexport type ProductStatus = z.infer<typeof ProductStatusSchema>;\n\nexport const ProductSchema = z.object({\n name: z.string().min(1).max(200),\n slug: z\n .string()\n .min(1)\n .max(120)\n .regex(/^[a-z0-9-]+$/, \"slug: alleen kleine letters, cijfers en streepjes\"),\n /**\n * Beschrijving als platte tekst (regeleinden blijven behouden). Bewust géén HTML:\n * producten worden client-side door editors geschreven (rules-pad, niet via de\n * publish-sanitizer), dus HTML zou hier een XSS-route zijn.\n */\n description: z.string().max(20_000).default(\"\"),\n categoryIds: z.array(z.string().max(80)).max(20).default([]),\n /** Afbeeldings-URL's (via de mediabibliotheek). Eerste = hoofdbeeld. */\n images: z.array(z.string().max(2000)).max(12).default([]),\n /** Prijs incl. btw, in centen. */\n priceCents: z.number().int().min(0).max(1_000_000_00).default(0),\n /** Doorgestreepte \"van\"-prijs (optioneel). */\n compareAtCents: z.number().int().min(0).max(1_000_000_00).optional(),\n /** Btw-tarief (NL): 21, 9 of 0. Prijzen zijn inclusief. */\n vatRate: z.union([z.literal(21), z.literal(9), z.literal(0)]).default(21),\n options: z.array(ProductOptionSchema).max(3).default([]),\n variants: z.array(ProductVariantSchema).max(200).default([]),\n /** Voorraad bijhouden? false = altijd bestelbaar (op-maat/print-on-demand). */\n trackStock: z.boolean().default(false),\n /** Voorraad voor producten zónder varianten (met varianten telt de variant-stock). */\n stock: z.number().int().min(0).max(1_000_000).optional(),\n status: ProductStatusSchema.default(\"draft\"),\n /** Sorteervolgorde binnen een categorie (laag = eerst). */\n order: z.number().int().min(0).max(9999).default(0),\n featured: z.boolean().default(false),\n /** 5.6: personalisatie-velden (eigen naam/logo) — max 3 per product. */\n personalization: z.array(PersonalizationFieldSchema).max(3).optional(),\n});\nexport type Product = z.infer<typeof ProductSchema>;\n\n/* ── Kortingscodes ───────────────────────────────────────────────────────── */\n\n/** `sites/{siteId}/discountCodes/{CODE}` (doc-id = code in hoofdletters; editor beheert). */\nexport const DiscountCodeSchema = z.object({\n code: z\n .string()\n .min(3)\n .max(30)\n .regex(/^[A-Z0-9-]+$/, \"code: hoofdletters, cijfers en streepjes\"),\n type: z.enum([\"percent\", \"fixed\"]),\n /** percent: 1–100; fixed: bedrag in centen. */\n value: z.number().int().min(1).max(1_000_000_00),\n minOrderCents: z.number().int().min(0).max(1_000_000_00).default(0),\n freeShipping: z.boolean().default(false),\n active: z.boolean().default(true),\n /** ISO-datums (yyyy-mm-dd); leeg = geen grens. */\n startsAt: z.string().max(10).optional(),\n endsAt: z.string().max(10).optional(),\n /** 0 = onbeperkt. `usedCount` wordt door de webhook transactioneel opgehoogd. */\n maxUses: z.number().int().min(0).max(1_000_000).default(0),\n usedCount: z.number().int().min(0).default(0),\n});\nexport type DiscountCode = z.infer<typeof DiscountCodeSchema>;\n\n/* ── Mail-templates ──────────────────────────────────────────────────────── */\n\n// Mailtemplates zijn site-breed (ook zonder shop) — de canonieke definitie staat in `./mail`.\n// Hier her-geëxporteerd voor backward-compat van bestaande shop-importeurs.\nexport {\n MAIL_TEMPLATE_KEYS,\n MAIL_TEMPLATE_DEFS,\n MailTemplateSchema,\n MailTemplatesSchema,\n type MailTemplateKey,\n type MailTemplates,\n} from \"./mail\";\n\n/* ── Bestellingen ────────────────────────────────────────────────────────── */\n\nexport const OrderStatusSchema = z.enum([\"pending\", \"paid\", \"shipped\", \"cancelled\", \"refunded\"]);\nexport type OrderStatus = z.infer<typeof OrderStatusSchema>;\n\n/** Orderregel: snapshot van naam/prijs op besteldatum — blijft kloppen als het product wijzigt. */\nexport const OrderItemSchema = z.object({\n kind: z.enum([\"product\", \"donation\"]).default(\"product\"),\n productId: z.string().max(80).optional(),\n name: z.string().min(1).max(240),\n variantKey: z.string().max(200).optional(),\n qty: z.number().int().min(1).max(999),\n /** Incl. eventuele personalisatie-meerprijs. */\n unitPriceCents: z.number().int().min(0).max(1_000_000_00),\n vatRate: z.union([z.literal(21), z.literal(9), z.literal(0)]).default(21),\n /** 5.6: ingevulde personalisatie (\"Naam: Boaz\", upload-pad). */\n personalization: PersonalizationValueSchema.optional(),\n});\nexport type OrderItem = z.infer<typeof OrderItemSchema>;\n\nexport const OrderAddressSchema = z.object({\n address: z.string().min(1).max(200),\n zip: z.string().min(1).max(20),\n city: z.string().min(1).max(120),\n country: z.string().min(2).max(2).default(\"NL\"),\n});\nexport type OrderAddress = z.infer<typeof OrderAddressSchema>;\n\nexport const OrderCustomerSchema = z.object({\n email: z.string().email().max(200),\n name: z.string().min(1).max(200),\n phone: z.string().max(40).optional(),\n});\nexport type OrderCustomer = z.infer<typeof OrderCustomerSchema>;\n\n/** Volledige order zoals door Functions geschreven (timestamps komen daarbovenop). */\nexport const OrderSchema = z.object({\n number: z.string().min(1).max(40),\n status: OrderStatusSchema,\n items: z.array(OrderItemSchema).min(1).max(50),\n amount: z.object({\n itemsCents: z.number().int().min(0),\n shippingCents: z.number().int().min(0),\n /** 5.6: toegepaste korting (0 = geen). */\n discountCents: z.number().int().min(0).default(0),\n totalCents: z.number().int().min(0),\n }),\n /** 5.6: toegepaste kortingscode (snapshot). */\n discount: z\n .object({\n code: z.string().max(30),\n type: z.enum([\"percent\", \"fixed\"]),\n value: z.number().int(),\n freeShipping: z.boolean().default(false),\n })\n .optional(),\n customer: OrderCustomerSchema,\n shipping: OrderAddressSchema.optional(),\n note: z.string().max(2000).optional(),\n /** 5.6: track & trace-link (gezet bij \"verzonden\"). */\n trackingUrl: z.string().max(500).optional(),\n /** 5.6: factuur-pad in Storage (gezet door de webhook). */\n invoicePath: z.string().max(400).optional(),\n stripe: z\n .object({\n sessionId: z.string().max(200).optional(),\n paymentIntentId: z.string().max(200).optional(),\n })\n .default({}),\n});\nexport type Order = z.infer<typeof OrderSchema>;\n\n/* ── Callable-input (checkout) ───────────────────────────────────────────── */\n\n/**\n * Input van de `createOrder`-callable. Client-prijzen worden NOOIT vertrouwd: de functie\n * herrekent alles tegen de opgeslagen product-docs. Alleen `donationCents` komt van de\n * client (binnen de per-site ingestelde min/max van het donatie-block).\n */\nexport const CreateOrderItemInputSchema = z.object({\n productId: z.string().min(1).max(80).optional(),\n variantKey: z.string().max(200).optional(),\n qty: z.number().int().min(1).max(999).default(1),\n /** Alleen voor donaties (zonder productId). */\n donationCents: z.number().int().min(50).max(1_000_000_00).optional(),\n /** 5.6: personalisatie-invoer (gevalideerd tegen product.personalization). */\n personalization: PersonalizationValueSchema.optional(),\n});\n\nexport const CreateOrderInputSchema = z.object({\n siteId: z.string().min(1).max(80),\n items: z.array(CreateOrderItemInputSchema).min(1).max(50),\n customer: OrderCustomerSchema,\n shipping: OrderAddressSchema.optional(),\n note: z.string().max(2000).optional(),\n /** 5.6: kortingscode (server-side gevalideerd en verrekend). */\n discountCode: z.string().max(30).optional(),\n /** Paden op de klantsite waarheen Stripe terug redirect. */\n successPath: z.string().max(400).default(\"/bedankt\"),\n cancelPath: z.string().max(400).default(\"/winkelwagen\"),\n /** Honeypot — moet leeg zijn (bot-detectie). */\n _hp: z.string().max(0).optional(),\n});\nexport type CreateOrderInput = z.infer<typeof CreateOrderInputSchema>;\n\n/* ── Block-schema's ──────────────────────────────────────────────────────── */\n\nexport const ShopCategoriesBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"shopCategories\"),\n heading: z.string().max(200).optional(),\n columns: z.number().int().min(2).max(4).default(3),\n});\n\nexport const ProductGridBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"productGrid\"),\n heading: z.string().max(200).optional(),\n /** Vast categorie-filter (slug). Leeg + useQueryCategory → filter via `?cat=` in de URL. */\n categorySlug: z.string().max(120).optional(),\n useQueryCategory: z.boolean().default(true),\n featuredOnly: z.boolean().default(false),\n columns: z.number().int().min(2).max(4).default(3),\n limit: z.number().int().min(1).max(200).default(60),\n sort: z.enum([\"order\", \"name\", \"priceAsc\", \"priceDesc\"]).default(\"order\"),\n /** 5.6: filterchips (kleur/maat) + sorteerkeuze boven het grid. */\n showFilters: z.boolean().default(false),\n});\n\nexport const ProductDetailBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"productDetail\"),\n /** Vast product (slug); leeg → product uit `?p=` in de URL (één generieke detailpagina). */\n slug: z.string().max(120).optional(),\n /** 5.6: \"Ook leuk\"-rij met producten uit dezelfde categorie. */\n showRelated: z.boolean().default(true),\n});\n\nexport const CartBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"cart\"),\n heading: z.string().max(200).optional(),\n});\n\nexport const CheckoutBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"checkout\"),\n heading: z.string().max(200).optional(),\n introText: z.string().max(2000).optional(),\n});\n\nexport const DonationBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"donation\"),\n heading: z.string().max(200).optional(),\n introText: z.string().max(2000).optional(),\n /** Voorgestelde bedragen in centen. */\n amountsCents: z.array(z.number().int().min(50).max(1_000_000_00)).max(8).default([500, 1000, 2500]),\n allowCustom: z.boolean().default(true),\n customMinCents: z.number().int().min(50).default(100),\n customMaxCents: z.number().int().max(1_000_000_00).default(100_000),\n buttonLabel: z.string().max(80).default(\"Doneer\"),\n});\n\nexport const OrderStatusBlockSchema = z.object({\n ...blockBase,\n _type: z.literal(\"orderStatus\"),\n successTitle: z.string().max(200).default(\"Bedankt voor je bestelling!\"),\n successText: z.string().max(2000).default(\"Je ontvangt zo een bevestiging per e-mail.\"),\n cancelledTitle: z.string().max(200).default(\"Betaling niet afgerond\"),\n cancelledText: z.string().max(2000).default(\"Je bestelling is niet betaald. Probeer het gerust opnieuw.\"),\n});\n\n/* ── Helpers (gedeeld client/server) ─────────────────────────────────────── */\n\n/** Variant-key uit gekozen optiewaarden, in optie-volgorde: [\"68\",\"Roze\"] → \"68|Roze\". */\nexport function variantKeyFor(values: string[]): string {\n return values.join(\"|\");\n}\n\n/** Effectieve prijs van een product(-variant) in centen. */\nexport function productPriceCents(product: Pick<Product, \"priceCents\" | \"variants\">, variantKey?: string): number {\n if (variantKey) {\n const v = product.variants?.find((x) => x.key === variantKey);\n if (v?.priceCents !== undefined) return v.priceCents;\n }\n return product.priceCents;\n}\n\n/** Verzendkosten volgens de publieke shopconfig (flat + gratis-vanaf). Donatie-only = gratis. */\nexport function shippingCentsFor(\n itemsCents: number,\n cfg: { shippingFlatCents?: number; shippingFreeFromCents?: number },\n hasShippableItems: boolean,\n): number {\n if (!hasShippableItems) return 0;\n const flat = cfg.shippingFlatCents ?? 0;\n const freeFrom = cfg.shippingFreeFromCents;\n if (freeFrom !== undefined && freeFrom > 0 && itemsCents >= freeFrom) return 0;\n return flat;\n}\n\n/** Centen → \"€ 13,95\" (nl-NL). */\nexport function formatCents(cents: number, currency = \"EUR\"): string {\n return new Intl.NumberFormat(\"nl-NL\", { style: \"currency\", currency }).format(cents / 100);\n}\n"],"mappings":"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","names":[]}
@@ -78,6 +78,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
78
78
  theme: z.ZodObject<{
79
79
  primary: z.ZodString;
80
80
  accent: z.ZodOptional<z.ZodString>;
81
+ logo: z.ZodOptional<z.ZodString>;
81
82
  background: z.ZodOptional<z.ZodString>;
82
83
  foreground: z.ZodOptional<z.ZodString>;
83
84
  fontFamily: z.ZodOptional<z.ZodString>;
@@ -156,6 +157,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
156
157
  xs?: string | undefined;
157
158
  } | undefined;
158
159
  accent?: string | undefined;
160
+ logo?: string | undefined;
159
161
  foreground?: string | undefined;
160
162
  fontFamily?: string | undefined;
161
163
  headingFont?: string | undefined;
@@ -186,6 +188,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
186
188
  xs?: string | undefined;
187
189
  } | undefined;
188
190
  accent?: string | undefined;
191
+ logo?: string | undefined;
189
192
  foreground?: string | undefined;
190
193
  fontFamily?: string | undefined;
191
194
  headingFont?: string | undefined;
@@ -273,6 +276,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
273
276
  theme: z.ZodObject<{
274
277
  primary: z.ZodString;
275
278
  accent: z.ZodOptional<z.ZodString>;
279
+ logo: z.ZodOptional<z.ZodString>;
276
280
  background: z.ZodOptional<z.ZodString>;
277
281
  foreground: z.ZodOptional<z.ZodString>;
278
282
  fontFamily: z.ZodOptional<z.ZodString>;
@@ -351,6 +355,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
351
355
  xs?: string | undefined;
352
356
  } | undefined;
353
357
  accent?: string | undefined;
358
+ logo?: string | undefined;
354
359
  foreground?: string | undefined;
355
360
  fontFamily?: string | undefined;
356
361
  headingFont?: string | undefined;
@@ -381,6 +386,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
381
386
  xs?: string | undefined;
382
387
  } | undefined;
383
388
  accent?: string | undefined;
389
+ logo?: string | undefined;
384
390
  foreground?: string | undefined;
385
391
  fontFamily?: string | undefined;
386
392
  headingFont?: string | undefined;
@@ -468,6 +474,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
468
474
  theme: z.ZodObject<{
469
475
  primary: z.ZodString;
470
476
  accent: z.ZodOptional<z.ZodString>;
477
+ logo: z.ZodOptional<z.ZodString>;
471
478
  background: z.ZodOptional<z.ZodString>;
472
479
  foreground: z.ZodOptional<z.ZodString>;
473
480
  fontFamily: z.ZodOptional<z.ZodString>;
@@ -546,6 +553,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
546
553
  xs?: string | undefined;
547
554
  } | undefined;
548
555
  accent?: string | undefined;
556
+ logo?: string | undefined;
549
557
  foreground?: string | undefined;
550
558
  fontFamily?: string | undefined;
551
559
  headingFont?: string | undefined;
@@ -576,6 +584,7 @@ export declare const SiteConfigSchema: z.ZodObject<{
576
584
  xs?: string | undefined;
577
585
  } | undefined;
578
586
  accent?: string | undefined;
587
+ logo?: string | undefined;
579
588
  foreground?: string | undefined;
580
589
  fontFamily?: string | undefined;
581
590
  headingFont?: string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xiwebdesign/xicms-core",
3
- "version": "6.1.1",
3
+ "version": "6.2.0",
4
4
  "description": "XiCMS engine: gestructureerde content, pagina's, draft/publish, admin (TipTap+Radix), SEO en beveiliging voor klantsites.",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -1,8 +0,0 @@
1
- /**
2
- * E-mails — bewerkbare templates in `settings/mailTemplates` (siteadmin). Leeg veld = de
3
- * ingebouwde standaardtekst; er gaat dus altijd een correcte mail uit. Platte tekst met
4
- * placeholders; de opmaak (afzender, huisstijl) regelt de engine.
5
- */
6
- export declare function EmailsTab({ siteId }: {
7
- siteId: string;
8
- }): import("react").JSX.Element;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/admin/shop/EmailsTab.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { doc, getDoc, setDoc } from \"firebase/firestore\";\nimport { getDb } from \"../../firebase/client\";\nimport { MAIL_TEMPLATE_KEYS, type MailTemplateKey, type MailTemplates } from \"../../schema/shop\";\nimport { Button, Card, Field, Input, Textarea } from \"../ui/primitives\";\nimport { useToast } from \"../ui/toast\";\nimport { shopCallable } from \"./lib\";\n\nconst TEMPLATE_INFO: Record<MailTemplateKey, { label: string; hint: string }> = {\n orderConfirmation: { label: \"Bestelbevestiging\", hint: \"Naar de klant zodra de betaling binnen is.\" },\n orderShipped: { label: \"Bestelling verzonden\", hint: \"Naar de klant wanneer je de status op ‘verzonden’ zet.\" },\n orderCancelled: { label: \"Bestelling geannuleerd\", hint: \"Naar de klant bij annulering.\" },\n orderRefunded: { label: \"Terugbetaald\", hint: \"Naar de klant na een terugbetaling.\" },\n donationThanks: { label: \"Donatie-bedankje\", hint: \"Naar de gever na een donatie.\" },\n formConfirmation: { label: \"Formulier-bevestiging\", hint: \"Ontvangstbevestiging van formulieren (site-breed).\" },\n};\n\nconst PLACEHOLDERS =\n \"{{naam}} {{ordernummer}} {{regels}} {{totaal}} {{verzendadres}} {{trackingUrl}} {{notitie}} {{sitenaam}} {{formulier}}\";\n\n/**\n * E-mails — bewerkbare templates in `settings/mailTemplates` (siteadmin). Leeg veld = de\n * ingebouwde standaardtekst; er gaat dus altijd een correcte mail uit. Platte tekst met\n * placeholders; de opmaak (afzender, huisstijl) regelt de engine.\n */\nexport function EmailsTab({ siteId }: { siteId: string }) {\n const { toast } = useToast();\n const [templates, setTemplates] = useState<MailTemplates | null>(null);\n const [busy, setBusy] = useState<string | null>(null);\n\n useEffect(() => {\n const db = getDb();\n if (!db) return;\n void getDoc(doc(db, \"sites\", siteId, \"settings\", \"mailTemplates\")).then((snap) =>\n setTemplates((snap.data() as MailTemplates | undefined) ?? {}),\n );\n }, [siteId]);\n\n async function save() {\n const db = getDb();\n if (!db || !templates) return;\n setBusy(\"save\");\n try {\n await setDoc(doc(db, \"sites\", siteId, \"settings\", \"mailTemplates\"), templates);\n toast({ title: \"Templates opgeslagen\", tone: \"success\" });\n } catch (e) {\n toast({ title: \"Opslaan mislukt\", description: e instanceof Error ? e.message : undefined, tone: \"error\" });\n } finally {\n setBusy(null);\n }\n }\n\n async function preview(key: MailTemplateKey) {\n setBusy(key);\n try {\n const res = await shopCallable<{ siteId: string; template: MailTemplateKey }, { to: string }>(\"sendTemplatePreview\")({\n siteId,\n template: key,\n });\n toast({ title: \"Voorbeeld verstuurd\", description: `Naar ${res.to} (met voorbeeldgegevens).`, tone: \"success\" });\n } catch (e) {\n toast({ title: \"Voorbeeld mislukt\", description: e instanceof Error ? e.message : undefined, tone: \"error\" });\n } finally {\n setBusy(null);\n }\n }\n\n if (!templates) return <Card><p className=\"text-sm text-slate-500\">Laden…</p></Card>;\n\n return (\n <div className=\"grid gap-4\">\n <Card>\n <p className=\"text-sm text-slate-600\">\n Laat een veld leeg om de standaardtekst te gebruiken. Beschikbare invulvelden:{\" \"}\n <code className=\"rounded bg-slate-100 px-1 py-0.5 text-xs\">{PLACEHOLDERS}</code>\n </p>\n </Card>\n\n {MAIL_TEMPLATE_KEYS.map((key) => {\n const info = TEMPLATE_INFO[key];\n const tpl = templates[key] ?? {};\n const set = (patch: { subject?: string; bodyText?: string }) =>\n setTemplates((p) => ({ ...p, [key]: { ...p?.[key], ...patch } }));\n return (\n <Card key={key}>\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <div>\n <h3 className=\"text-sm font-semibold\">{info.label}</h3>\n <p className=\"text-xs text-slate-500\">{info.hint}</p>\n </div>\n <Button size=\"sm\" variant=\"secondary\" disabled={busy !== null} onClick={() => preview(key)}>\n {busy === key ? \"Versturen…\" : \"Stuur voorbeeld naar mij\"}\n </Button>\n </div>\n <div className=\"grid gap-3\">\n <Field label=\"Onderwerp\" hint=\"Leeg = standaard\">\n <Input value={tpl.subject ?? \"\"} onChange={(e) => set({ subject: e.target.value })} />\n </Field>\n <Field label=\"Tekst\" hint=\"Leeg = standaard\">\n <Textarea rows={5} value={tpl.bodyText ?? \"\"} onChange={(e) => set({ bodyText: e.target.value })} />\n </Field>\n </div>\n </Card>\n );\n })}\n\n <div>\n <Button onClick={save} disabled={busy !== null}>Alles opslaan</Button>\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}