@xiwebdesign/xicms-core 7.19.1 → 7.21.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.
- package/dist/admin/settings/SettingsPanel.js +8 -1
- package/dist/admin/settings/SettingsPanel.js.map +1 -1
- package/dist/admin/shop/OrdersTab.js +9 -2
- package/dist/admin/shop/OrdersTab.js.map +1 -1
- package/dist/admin/shop/ProductsTab.d.ts +0 -6
- package/dist/admin/shop/ProductsTab.js +26 -0
- package/dist/admin/shop/ProductsTab.js.map +1 -1
- package/dist/admin/shop/ShopSettingsTab.js +57 -2
- package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
- package/dist/admin.css +1 -1
- package/dist/modules/shop/blocks/Cart.js +8 -2
- package/dist/modules/shop/blocks/Cart.js.map +1 -1
- package/dist/modules/shop/blocks/Checkout.js +32 -8
- package/dist/modules/shop/blocks/Checkout.js.map +1 -1
- package/dist/modules/shop/blocks/ProductGrid.js +5 -1
- package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
- package/dist/modules/shop/settings.d.ts +8 -0
- package/dist/modules/shop/settings.js +21 -1
- package/dist/modules/shop/settings.js.map +1 -1
- package/dist/modules/shop/strings.d.ts +2 -0
- package/dist/modules/shop/strings.js +4 -0
- package/dist/modules/shop/strings.js.map +1 -1
- package/dist/schema/shopGeld.d.ts +30 -3
- package/dist/schema/shopGeld.js +19 -4
- package/dist/schema/shopGeld.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/modules/shop/settings.ts"],"sourcesContent":["import * as z from \"zod/mini\";\n\n/**\n * Publieke shop-instellingen (per site, via `settings/public.modules.shop.config` of\n * `SiteConfig.modules.shop.config`). Server-safe: alleen Zod. De SettingsPanel rendert hier\n * automatisch een formulier voor (moduleSettingsForm); de Functions lezen dezelfde config\n * server-side. Geheimen (Stripe-key, SMTP) horen hier NIET — die staan in\n * `sites/{siteId}/private/shop` en lopen via callables.\n */\nexport const ShopSettingsSchema = z.object({\n shopPath: z._default(z.string().check(z.maxLength(200)), \"/webwinkel\").register(z.globalRegistry, { description: \"Pad van de winkelpagina\" }),\n detailPath: z._default(z.string().check(z.maxLength(200)), \"/product\").register(z.globalRegistry, { description: \"Pad van de productpagina\" }),\n cartPath: z._default(z.string().check(z.maxLength(200)), \"/winkelwagen\").register(z.globalRegistry, { description: \"Pad van de winkelwagen\" }),\n checkoutPath: z._default(z.string().check(z.maxLength(200)), \"/afrekenen\").register(z.globalRegistry, { description: \"Pad van de afrekenpagina\" }),\n successPath: z._default(z.string().check(z.maxLength(200)), \"/bedankt\").register(z.globalRegistry, { description: \"Pad van de bedankt-pagina\" }),\n currency: z._default(z.string().check(z.minLength(3)).check(z.maxLength(3)), \"EUR\").register(z.globalRegistry, { description: \"Valuta (ISO-code)\" }),\n shippingFlatCents: z._default(z.int().check(z.minimum(0)).check(z.maximum(100_000)), 495).register(z.globalRegistry, { description: \"Verzendkosten (centen)\" }),\n shippingFreeFromCents: z._default(z.int().check(z.minimum(0)).check(z.maximum(1_000_000_00)), 0).register(z.globalRegistry, { description: \"Gratis verzending vanaf (centen, 0 = nooit)\" }),\n orderPrefix: z._default(z.string().check(z.maxLength(12)), \"ORDER\").register(z.globalRegistry, { description: \"Ordernummer-prefix\" }),\n /**\n * Prefix van de FACTUURreeks (7.18). Leeg = dezelfde als het ordernummer. De factuurreeks is\n * een eigen doorlopende nummering die alleen bij betaling ophoogt en per jaar herstart —\n * het ordernummer mag gaten hebben (afgebroken checkouts), een factuurreeks niet.\n */\n invoicePrefix: z._default(z.string().check(z.maxLength(12)), \"\").register(z.globalRegistry, { description: \"Factuurnummer-prefix (leeg = zelfde als ordernummer)\" }),\n /* Bedrijfsgegevens — komen op de factuur-PDF (5.6). */\n businessName: z._default(z.string().check(z.maxLength(120)), \"\").register(z.globalRegistry, { description: \"Bedrijfsnaam (factuur)\" }),\n businessAddress: z._default(z.string().check(z.maxLength(200)), \"\").register(z.globalRegistry, { description: \"Adres (factuur)\" }),\n businessZip: z._default(z.string().check(z.maxLength(20)), \"\").register(z.globalRegistry, { description: \"Postcode (factuur)\" }),\n businessCity: z._default(z.string().check(z.maxLength(120)), \"\").register(z.globalRegistry, { description: \"Plaats (factuur)\" }),\n businessKvk: z._default(z.string().check(z.maxLength(20)), \"\").register(z.globalRegistry, { description: \"KVK-nummer (factuur)\" }),\n businessBtw: z._default(z.string().check(z.maxLength(30)), \"\").register(z.globalRegistry, { description: \"Btw-nummer (factuur)\" }),\n});\nexport type ShopSettings = z.infer<typeof ShopSettingsSchema>;\n\nexport const defaultShopSettings: ShopSettings = ShopSettingsSchema.parse({});\n"],"mappings":"AAAA,YAAY,OAAO;AASZ,MAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,CAAC,GAAG,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,0BAA0B,CAAC;AAAA,EAC5I,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,CAAC,GAAG,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,2BAA2B,CAAC;AAAA,EAC7I,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,CAAC,GAAG,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,yBAAyB,CAAC;AAAA,EAC7I,cAAc,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,CAAC,GAAG,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,2BAA2B,CAAC;AAAA,EACjJ,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,CAAC,GAAG,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,4BAA4B,CAAC;AAAA,EAC/I,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,oBAAoB,CAAC;AAAA,EACnJ,mBAAmB,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAO,CAAC,GAAG,GAAG,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,yBAAyB,CAAC;AAAA,EAC9J,uBAAuB,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,GAAY,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,8CAA8C,CAAC;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/shop/settings.ts"],"sourcesContent":["import * as z from \"zod/mini\";\n\n/**\n * Publieke shop-instellingen (per site, via `settings/public.modules.shop.config` of\n * `SiteConfig.modules.shop.config`). Server-safe: alleen Zod. De SettingsPanel rendert hier\n * automatisch een formulier voor (moduleSettingsForm); de Functions lezen dezelfde config\n * server-side. Geheimen (Stripe-key, SMTP) horen hier NIET — die staan in\n * `sites/{siteId}/private/shop` en lopen via callables.\n */\nexport const ShopSettingsSchema = z.object({\n shopPath: z._default(z.string().check(z.maxLength(200)), \"/webwinkel\").register(z.globalRegistry, { description: \"Pad van de winkelpagina\" }),\n detailPath: z._default(z.string().check(z.maxLength(200)), \"/product\").register(z.globalRegistry, { description: \"Pad van de productpagina\" }),\n cartPath: z._default(z.string().check(z.maxLength(200)), \"/winkelwagen\").register(z.globalRegistry, { description: \"Pad van de winkelwagen\" }),\n checkoutPath: z._default(z.string().check(z.maxLength(200)), \"/afrekenen\").register(z.globalRegistry, { description: \"Pad van de afrekenpagina\" }),\n successPath: z._default(z.string().check(z.maxLength(200)), \"/bedankt\").register(z.globalRegistry, { description: \"Pad van de bedankt-pagina\" }),\n currency: z._default(z.string().check(z.minLength(3)).check(z.maxLength(3)), \"EUR\").register(z.globalRegistry, { description: \"Valuta (ISO-code)\" }),\n shippingFlatCents: z._default(z.int().check(z.minimum(0)).check(z.maximum(100_000)), 495).register(z.globalRegistry, { description: \"Verzendkosten (centen)\" }),\n shippingFreeFromCents: z._default(z.int().check(z.minimum(0)).check(z.maximum(1_000_000_00)), 0).register(z.globalRegistry, { description: \"Gratis verzending vanaf (centen, 0 = nooit)\" }),\n /**\n * Verzendzones (7.20): tarief per (groep) land(en). Leeg = het enkele tarief hierboven voor\n * alles — het gedrag van vóór 7.20, dus bestaande winkels merken niets. Een zone ZONDER landen\n * is de \"overige landen\"-zone; staat die er niet, dan verzendt de winkel alleen naar de landen\n * die wél in een zone staan (en toont de checkout precies die keuze).\n */\n shippingZones: z._default(z.array(z.object({\n naam: z.string().check(z.minLength(1)).check(z.maxLength(60)),\n landen: z._default(z.array(z.string().check(z.maxLength(2))).check(z.maxLength(60)), []),\n flatCents: z._default(z.int().check(z.minimum(0)).check(z.maximum(100_000)), 0),\n freeFromCents: z._default(z.int().check(z.minimum(0)).check(z.maximum(1_000_000_00)), 0),\n })).check(z.maxLength(10)), []).register(z.globalRegistry, { description: \"Verzendzones (tarief per land)\" }),\n orderPrefix: z._default(z.string().check(z.maxLength(12)), \"ORDER\").register(z.globalRegistry, { description: \"Ordernummer-prefix\" }),\n /**\n * Prefix van de FACTUURreeks (7.18). Leeg = dezelfde als het ordernummer. De factuurreeks is\n * een eigen doorlopende nummering die alleen bij betaling ophoogt en per jaar herstart —\n * het ordernummer mag gaten hebben (afgebroken checkouts), een factuurreeks niet.\n */\n invoicePrefix: z._default(z.string().check(z.maxLength(12)), \"\").register(z.globalRegistry, { description: \"Factuurnummer-prefix (leeg = zelfde als ordernummer)\" }),\n /* Bedrijfsgegevens — komen op de factuur-PDF (5.6). */\n businessName: z._default(z.string().check(z.maxLength(120)), \"\").register(z.globalRegistry, { description: \"Bedrijfsnaam (factuur)\" }),\n businessAddress: z._default(z.string().check(z.maxLength(200)), \"\").register(z.globalRegistry, { description: \"Adres (factuur)\" }),\n businessZip: z._default(z.string().check(z.maxLength(20)), \"\").register(z.globalRegistry, { description: \"Postcode (factuur)\" }),\n businessCity: z._default(z.string().check(z.maxLength(120)), \"\").register(z.globalRegistry, { description: \"Plaats (factuur)\" }),\n businessKvk: z._default(z.string().check(z.maxLength(20)), \"\").register(z.globalRegistry, { description: \"KVK-nummer (factuur)\" }),\n businessBtw: z._default(z.string().check(z.maxLength(30)), \"\").register(z.globalRegistry, { description: \"Btw-nummer (factuur)\" }),\n /**\n * Contactgegevens in de mailfooter en op de factuur (7.21). `businessEmail` werd al door\n * `mailLayout.ts` en `invoice.ts` UITGELEZEN, maar bestond nergens als instelling — een dood\n * veld op drie plekken, waardoor de klant in zijn bestelbevestiging geen enkel adres zag om\n * op te reageren.\n */\n businessEmail: z._default(z.string().check(z.maxLength(200)), \"\").register(z.globalRegistry, { description: \"Contact-e-mail (factuur + mailfooter)\" }),\n businessPhone: z._default(z.string().check(z.maxLength(40)), \"\").register(z.globalRegistry, { description: \"Telefoon (factuur + mailfooter)\" }),\n});\nexport type ShopSettings = z.infer<typeof ShopSettingsSchema>;\n\nexport const defaultShopSettings: ShopSettings = ShopSettingsSchema.parse({});\n"],"mappings":"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","names":[]}
|
|
@@ -36,6 +36,8 @@ const NL = {
|
|
|
36
36
|
fieldAddress: "Straat + huisnummer",
|
|
37
37
|
fieldZip: "Postcode",
|
|
38
38
|
fieldCity: "Plaats",
|
|
39
|
+
fieldCountry: "Land",
|
|
40
|
+
shippingFromCountry: "(bij bezorging in Nederland \u2014 kies je land bij het afrekenen)",
|
|
39
41
|
fieldNote: "Opmerking (optioneel)",
|
|
40
42
|
choose: "Kies\u2026",
|
|
41
43
|
discountCode: "Kortingscode",
|
|
@@ -96,6 +98,8 @@ const EN = {
|
|
|
96
98
|
fieldAddress: "Street + number",
|
|
97
99
|
fieldZip: "Postal code",
|
|
98
100
|
fieldCity: "City",
|
|
101
|
+
fieldCountry: "Country",
|
|
102
|
+
shippingFromCountry: "(for delivery in the Netherlands \u2014 choose your country at checkout)",
|
|
99
103
|
fieldNote: "Note (optional)",
|
|
100
104
|
choose: "Choose\u2026",
|
|
101
105
|
discountCode: "Discount code",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/modules/shop/strings.ts"],"sourcesContent":["\"use client\";\n\n/**\n * UI-teksten van de shop-blocks, gelokaliseerd op `SiteConfig.lang` (nl = default, en).\n * Interpolatie via `{naam}`-placeholders. Bewust een platte tabel — geen i18n-framework;\n * de shop-strings zijn de enige plek in de blocks met vaste UI-tekst.\n */\nimport { useSiteConfig } from \"../../config\";\n\nconst NL = {\n addToCart: \"In winkelwagen\",\n added: \"✓ Toegevoegd aan je winkelwagen.\",\n addedGoToCart: \"✓ In winkelwagen — bekijk\",\n view: \"Bekijk\",\n toCart: \"Naar winkelwagen\",\n continueShopping: \"Verder winkelen\",\n checkout: \"Afrekenen\",\n cartEmpty: \"Je winkelwagen is leeg.\",\n toShop: \"Naar de winkel\",\n subtotal: \"Subtotaal\",\n shippingCosts: \"Verzendkosten\",\n free: \"gratis\",\n total: \"Totaal\",\n perPiece: \"p/st\",\n qty: \"Aantal\",\n outOfStock: \"Uitverkocht in deze uitvoering.\",\n variantUnavailable: \"Deze combinatie is niet leverbaar.\",\n stockLeft: \"Nog {n} beschikbaar\",\n soldOut: \"Uitverkocht\",\n productNotFound: \"Product niet gevonden.\",\n backToShop: \"Terug naar de winkel\",\n noProducts: \"Geen producten gevonden.\",\n noCategories: \"Nog geen categorieën.\",\n allCategories: \"Alle categorieën\",\n pay: \"Betalen — {bedrag}\",\n busy: \"Bezig…\",\n checkoutFailed: \"Afrekenen is niet gelukt. Controleer je gegevens en probeer het opnieuw.\",\n secureNote: \"Je rekent veilig af via een beveiligde betaalpagina (o.a. iDEAL). Na betaling ontvang je een bevestiging per e-mail.\",\n yourOrder: \"Je bestelling\",\n fieldName: \"Naam\",\n fieldEmail: \"E-mail\",\n fieldPhone: \"Telefoon (optioneel)\",\n fieldAddress: \"Straat + huisnummer\",\n fieldZip: \"Postcode\",\n fieldCity: \"Plaats\",\n fieldNote: \"Opmerking (optioneel)\",\n choose: \"Kies…\",\n discountCode: \"Kortingscode\",\n discountApply: \"Toepassen\",\n discount: \"Korting\",\n discountInvalid: \"Deze code is niet (meer) geldig.\",\n discountApplied: \"Korting toegepast: {code}\",\n related: \"Ook leuk\",\n filterAll: \"Alles\",\n sortLabel: \"Sorteren\",\n sortDefault: \"Aanbevolen\",\n sortName: \"Naam\",\n sortPriceAsc: \"Prijs (laag-hoog)\",\n sortPriceDesc: \"Prijs (hoog-laag)\",\n personalizationUpload: \"Kies bestand…\",\n personalizationUploading: \"Uploaden…\",\n personalizationUploaded: \"✓ Geüpload\",\n personalizationTooBig: \"Bestand te groot (max 5 MB).\",\n personalizationFailed: \"Uploaden mislukt — probeer het opnieuw.\",\n personalizationSurcharge: \"+ {bedrag}\",\n donationFailed: \"Doneren is niet gelukt. Probeer het later opnieuw.\",\n donationCustomAmount: \"Ander bedrag\",\n donationAmountLabel: \"Bedrag in euro's (min. {min})\",\n};\n\nconst EN: typeof NL = {\n addToCart: \"Add to cart\",\n added: \"✓ Added to your cart.\",\n addedGoToCart: \"✓ In cart — view\",\n view: \"View\",\n toCart: \"Go to cart\",\n continueShopping: \"Continue shopping\",\n checkout: \"Checkout\",\n cartEmpty: \"Your cart is empty.\",\n toShop: \"Go to the shop\",\n subtotal: \"Subtotal\",\n shippingCosts: \"Shipping\",\n free: \"free\",\n total: \"Total\",\n perPiece: \"each\",\n qty: \"Quantity\",\n outOfStock: \"Sold out in this variant.\",\n variantUnavailable: \"This combination is unavailable.\",\n stockLeft: \"Only {n} left\",\n soldOut: \"Sold out\",\n productNotFound: \"Product not found.\",\n backToShop: \"Back to the shop\",\n noProducts: \"No products found.\",\n noCategories: \"No categories yet.\",\n allCategories: \"All categories\",\n pay: \"Pay — {bedrag}\",\n busy: \"Working…\",\n checkoutFailed: \"Checkout failed. Check your details and try again.\",\n secureNote: \"You pay securely via a protected checkout page (incl. iDEAL). You will receive a confirmation email after payment.\",\n yourOrder: \"Your order\",\n fieldName: \"Name\",\n fieldEmail: \"Email\",\n fieldPhone: \"Phone (optional)\",\n fieldAddress: \"Street + number\",\n fieldZip: \"Postal code\",\n fieldCity: \"City\",\n fieldNote: \"Note (optional)\",\n choose: \"Choose…\",\n discountCode: \"Discount code\",\n discountApply: \"Apply\",\n discount: \"Discount\",\n discountInvalid: \"This code is not (or no longer) valid.\",\n discountApplied: \"Discount applied: {code}\",\n related: \"You may also like\",\n filterAll: \"All\",\n sortLabel: \"Sort\",\n sortDefault: \"Recommended\",\n sortName: \"Name\",\n sortPriceAsc: \"Price (low-high)\",\n sortPriceDesc: \"Price (high-low)\",\n personalizationUpload: \"Choose file…\",\n personalizationUploading: \"Uploading…\",\n personalizationUploaded: \"✓ Uploaded\",\n personalizationTooBig: \"File too large (max 5 MB).\",\n personalizationFailed: \"Upload failed — please try again.\",\n personalizationSurcharge: \"+ {bedrag}\",\n donationFailed: \"Donation failed. Please try again later.\",\n donationCustomAmount: \"Custom amount\",\n donationAmountLabel: \"Amount in euros (min. {min})\",\n};\n\nexport type ShopStringKey = keyof typeof NL;\nconst TABLES: Record<string, typeof NL> = { nl: NL, en: EN };\n\nexport type ShopT = (key: ShopStringKey, vars?: Record<string, string | number>) => string;\n\n/** Vertaalfunctie voor shop-blocks: `t(\"addToCart\")`, `t(\"stockLeft\", { n: 3 })`. */\nexport function useShopStrings(): ShopT {\n const lang = (useSiteConfig().lang ?? \"nl\").slice(0, 2).toLowerCase();\n const table = TABLES[lang] ?? NL;\n return (key, vars) => {\n let s = table[key] ?? NL[key] ?? key;\n if (vars) for (const [k, v] of Object.entries(vars)) s = s.replaceAll(`{${k}}`, String(v));\n return s;\n };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/shop/strings.ts"],"sourcesContent":["\"use client\";\n\n/**\n * UI-teksten van de shop-blocks, gelokaliseerd op `SiteConfig.lang` (nl = default, en).\n * Interpolatie via `{naam}`-placeholders. Bewust een platte tabel — geen i18n-framework;\n * de shop-strings zijn de enige plek in de blocks met vaste UI-tekst.\n */\nimport { useSiteConfig } from \"../../config\";\n\nconst NL = {\n addToCart: \"In winkelwagen\",\n added: \"✓ Toegevoegd aan je winkelwagen.\",\n addedGoToCart: \"✓ In winkelwagen — bekijk\",\n view: \"Bekijk\",\n toCart: \"Naar winkelwagen\",\n continueShopping: \"Verder winkelen\",\n checkout: \"Afrekenen\",\n cartEmpty: \"Je winkelwagen is leeg.\",\n toShop: \"Naar de winkel\",\n subtotal: \"Subtotaal\",\n shippingCosts: \"Verzendkosten\",\n free: \"gratis\",\n total: \"Totaal\",\n perPiece: \"p/st\",\n qty: \"Aantal\",\n outOfStock: \"Uitverkocht in deze uitvoering.\",\n variantUnavailable: \"Deze combinatie is niet leverbaar.\",\n stockLeft: \"Nog {n} beschikbaar\",\n soldOut: \"Uitverkocht\",\n productNotFound: \"Product niet gevonden.\",\n backToShop: \"Terug naar de winkel\",\n noProducts: \"Geen producten gevonden.\",\n noCategories: \"Nog geen categorieën.\",\n allCategories: \"Alle categorieën\",\n pay: \"Betalen — {bedrag}\",\n busy: \"Bezig…\",\n checkoutFailed: \"Afrekenen is niet gelukt. Controleer je gegevens en probeer het opnieuw.\",\n secureNote: \"Je rekent veilig af via een beveiligde betaalpagina (o.a. iDEAL). Na betaling ontvang je een bevestiging per e-mail.\",\n yourOrder: \"Je bestelling\",\n fieldName: \"Naam\",\n fieldEmail: \"E-mail\",\n fieldPhone: \"Telefoon (optioneel)\",\n fieldAddress: \"Straat + huisnummer\",\n fieldZip: \"Postcode\",\n fieldCity: \"Plaats\",\n fieldCountry: \"Land\",\n shippingFromCountry: \"(bij bezorging in Nederland — kies je land bij het afrekenen)\",\n fieldNote: \"Opmerking (optioneel)\",\n choose: \"Kies…\",\n discountCode: \"Kortingscode\",\n discountApply: \"Toepassen\",\n discount: \"Korting\",\n discountInvalid: \"Deze code is niet (meer) geldig.\",\n discountApplied: \"Korting toegepast: {code}\",\n related: \"Ook leuk\",\n filterAll: \"Alles\",\n sortLabel: \"Sorteren\",\n sortDefault: \"Aanbevolen\",\n sortName: \"Naam\",\n sortPriceAsc: \"Prijs (laag-hoog)\",\n sortPriceDesc: \"Prijs (hoog-laag)\",\n personalizationUpload: \"Kies bestand…\",\n personalizationUploading: \"Uploaden…\",\n personalizationUploaded: \"✓ Geüpload\",\n personalizationTooBig: \"Bestand te groot (max 5 MB).\",\n personalizationFailed: \"Uploaden mislukt — probeer het opnieuw.\",\n personalizationSurcharge: \"+ {bedrag}\",\n donationFailed: \"Doneren is niet gelukt. Probeer het later opnieuw.\",\n donationCustomAmount: \"Ander bedrag\",\n donationAmountLabel: \"Bedrag in euro's (min. {min})\",\n};\n\nconst EN: typeof NL = {\n addToCart: \"Add to cart\",\n added: \"✓ Added to your cart.\",\n addedGoToCart: \"✓ In cart — view\",\n view: \"View\",\n toCart: \"Go to cart\",\n continueShopping: \"Continue shopping\",\n checkout: \"Checkout\",\n cartEmpty: \"Your cart is empty.\",\n toShop: \"Go to the shop\",\n subtotal: \"Subtotal\",\n shippingCosts: \"Shipping\",\n free: \"free\",\n total: \"Total\",\n perPiece: \"each\",\n qty: \"Quantity\",\n outOfStock: \"Sold out in this variant.\",\n variantUnavailable: \"This combination is unavailable.\",\n stockLeft: \"Only {n} left\",\n soldOut: \"Sold out\",\n productNotFound: \"Product not found.\",\n backToShop: \"Back to the shop\",\n noProducts: \"No products found.\",\n noCategories: \"No categories yet.\",\n allCategories: \"All categories\",\n pay: \"Pay — {bedrag}\",\n busy: \"Working…\",\n checkoutFailed: \"Checkout failed. Check your details and try again.\",\n secureNote: \"You pay securely via a protected checkout page (incl. iDEAL). You will receive a confirmation email after payment.\",\n yourOrder: \"Your order\",\n fieldName: \"Name\",\n fieldEmail: \"Email\",\n fieldPhone: \"Phone (optional)\",\n fieldAddress: \"Street + number\",\n fieldZip: \"Postal code\",\n fieldCity: \"City\",\n fieldCountry: \"Country\",\n shippingFromCountry: \"(for delivery in the Netherlands — choose your country at checkout)\",\n fieldNote: \"Note (optional)\",\n choose: \"Choose…\",\n discountCode: \"Discount code\",\n discountApply: \"Apply\",\n discount: \"Discount\",\n discountInvalid: \"This code is not (or no longer) valid.\",\n discountApplied: \"Discount applied: {code}\",\n related: \"You may also like\",\n filterAll: \"All\",\n sortLabel: \"Sort\",\n sortDefault: \"Recommended\",\n sortName: \"Name\",\n sortPriceAsc: \"Price (low-high)\",\n sortPriceDesc: \"Price (high-low)\",\n personalizationUpload: \"Choose file…\",\n personalizationUploading: \"Uploading…\",\n personalizationUploaded: \"✓ Uploaded\",\n personalizationTooBig: \"File too large (max 5 MB).\",\n personalizationFailed: \"Upload failed — please try again.\",\n personalizationSurcharge: \"+ {bedrag}\",\n donationFailed: \"Donation failed. Please try again later.\",\n donationCustomAmount: \"Custom amount\",\n donationAmountLabel: \"Amount in euros (min. {min})\",\n};\n\nexport type ShopStringKey = keyof typeof NL;\nconst TABLES: Record<string, typeof NL> = { nl: NL, en: EN };\n\nexport type ShopT = (key: ShopStringKey, vars?: Record<string, string | number>) => string;\n\n/** Vertaalfunctie voor shop-blocks: `t(\"addToCart\")`, `t(\"stockLeft\", { n: 3 })`. */\nexport function useShopStrings(): ShopT {\n const lang = (useSiteConfig().lang ?? \"nl\").slice(0, 2).toLowerCase();\n const table = TABLES[lang] ?? NL;\n return (key, vars) => {\n let s = table[key] ?? NL[key] ?? key;\n if (vars) for (const [k, v] of Object.entries(vars)) s = s.replaceAll(`{${k}}`, String(v));\n return s;\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -9,10 +9,37 @@ import type { Product } from "./shop.js";
|
|
|
9
9
|
export declare function variantKeyFor(values: string[]): string;
|
|
10
10
|
/** Effectieve prijs van een product(-variant) in centen. */
|
|
11
11
|
export declare function productPriceCents(product: Pick<Product, "priceCents" | "variants">, variantKey?: string): number;
|
|
12
|
-
/**
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Verzendtarief per land (7.20). `landen` is een lijst ISO-landcodes; leeg = "alle overige".
|
|
14
|
+
* Zo dekt één rij "NL", een tweede "BE, DE" en een laatste zonder landen de rest van de wereld.
|
|
15
|
+
*/
|
|
16
|
+
export interface Verzendzone {
|
|
17
|
+
naam: string;
|
|
18
|
+
landen?: string[];
|
|
19
|
+
flatCents: number;
|
|
20
|
+
/** Gratis vanaf dit orderbedrag (0/leeg = nooit gratis in deze zone). */
|
|
21
|
+
freeFromCents?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface VerzendConfig {
|
|
14
24
|
shippingFlatCents?: number;
|
|
15
25
|
shippingFreeFromCents?: number;
|
|
16
|
-
|
|
26
|
+
/** Zones hebben voorrang; zonder zones geldt het enkele tarief hierboven (gedrag vóór 7.20). */
|
|
27
|
+
shippingZones?: Verzendzone[];
|
|
28
|
+
}
|
|
29
|
+
/** De zone die bij een land hoort: eerst een expliciete match, anders de zone zónder landenlijst. */
|
|
30
|
+
export declare function zoneVoorLand(cfg: VerzendConfig, land: string | undefined): Verzendzone | undefined;
|
|
31
|
+
/** Landen waarheen deze winkel verzendt; leeg = geen beperking (er is een "overige"-zone). */
|
|
32
|
+
export declare function verzendLanden(cfg: VerzendConfig): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Verzendkosten. Donatie-only = gratis; een kortingscode met gratis verzending maakt het 0.
|
|
35
|
+
*
|
|
36
|
+
* Eén functie voor winkelwagen, afrekenen én server. Er waren drie implementaties: de winkelwagen
|
|
37
|
+
* kende de kortingscode niet (toonde dus altijd de volle verzendkosten), de afrekenpagina lapte
|
|
38
|
+
* `freeShipping` er los omheen, en de server rekende het nog eens over. Nu telt alleen deze.
|
|
39
|
+
*/
|
|
40
|
+
export declare function shippingCentsFor(itemsCents: number, cfg: VerzendConfig, hasShippableItems: boolean, opties?: {
|
|
41
|
+
land?: string;
|
|
42
|
+
freeShipping?: boolean;
|
|
43
|
+
}): number;
|
|
17
44
|
/** Centen → "€ 13,95" (nl-NL). */
|
|
18
45
|
export declare function formatCents(cents: number, currency?: string): string;
|
package/dist/schema/shopGeld.js
CHANGED
|
@@ -8,10 +8,23 @@ function productPriceCents(product, variantKey) {
|
|
|
8
8
|
}
|
|
9
9
|
return product.priceCents;
|
|
10
10
|
}
|
|
11
|
-
function
|
|
11
|
+
function zoneVoorLand(cfg, land) {
|
|
12
|
+
const zones = cfg.shippingZones ?? [];
|
|
13
|
+
if (zones.length === 0) return void 0;
|
|
14
|
+
const code = (land ?? "NL").trim().toUpperCase();
|
|
15
|
+
return zones.find((z) => (z.landen ?? []).some((l) => l.trim().toUpperCase() === code)) ?? zones.find((z) => (z.landen ?? []).length === 0);
|
|
16
|
+
}
|
|
17
|
+
function verzendLanden(cfg) {
|
|
18
|
+
const zones = cfg.shippingZones ?? [];
|
|
19
|
+
if (zones.length === 0 || zones.some((z) => (z.landen ?? []).length === 0)) return [];
|
|
20
|
+
return [...new Set(zones.flatMap((z) => (z.landen ?? []).map((l) => l.trim().toUpperCase())))];
|
|
21
|
+
}
|
|
22
|
+
function shippingCentsFor(itemsCents, cfg, hasShippableItems, opties) {
|
|
12
23
|
if (!hasShippableItems) return 0;
|
|
13
|
-
|
|
14
|
-
const
|
|
24
|
+
if (opties?.freeShipping) return 0;
|
|
25
|
+
const zone = zoneVoorLand(cfg, opties?.land);
|
|
26
|
+
const flat = zone ? zone.flatCents : cfg.shippingFlatCents ?? 0;
|
|
27
|
+
const freeFrom = zone ? zone.freeFromCents : cfg.shippingFreeFromCents;
|
|
15
28
|
if (freeFrom !== void 0 && freeFrom > 0 && itemsCents >= freeFrom) return 0;
|
|
16
29
|
return flat;
|
|
17
30
|
}
|
|
@@ -22,6 +35,8 @@ export {
|
|
|
22
35
|
formatCents,
|
|
23
36
|
productPriceCents,
|
|
24
37
|
shippingCentsFor,
|
|
25
|
-
variantKeyFor
|
|
38
|
+
variantKeyFor,
|
|
39
|
+
verzendLanden,
|
|
40
|
+
zoneVoorLand
|
|
26
41
|
};
|
|
27
42
|
//# sourceMappingURL=shopGeld.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/schema/shopGeld.ts"],"sourcesContent":["/**\n * Geld- en variant-helpers van de shop — in een eigen, zod-VRIJE module (7.14). Ze stonden in\n * schema/shop.ts, en omdat de shop-blokken ze in hun Render nodig hebben trok élke shop-pagina\n * daarmee alle shop-schema's plus de zod-runtime de bezoekersbundel in. Pure rekenfuncties;\n * schema/shop.ts her-exporteert ze ongewijzigd.\n */\nimport type { Product } from \"./shop\";\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/**
|
|
1
|
+
{"version":3,"sources":["../../src/schema/shopGeld.ts"],"sourcesContent":["/**\n * Geld- en variant-helpers van de shop — in een eigen, zod-VRIJE module (7.14). Ze stonden in\n * schema/shop.ts, en omdat de shop-blokken ze in hun Render nodig hebben trok élke shop-pagina\n * daarmee alle shop-schema's plus de zod-runtime de bezoekersbundel in. Pure rekenfuncties;\n * schema/shop.ts her-exporteert ze ongewijzigd.\n */\nimport type { Product } from \"./shop\";\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/**\n * Verzendtarief per land (7.20). `landen` is een lijst ISO-landcodes; leeg = \"alle overige\".\n * Zo dekt één rij \"NL\", een tweede \"BE, DE\" en een laatste zonder landen de rest van de wereld.\n */\nexport interface Verzendzone {\n naam: string;\n landen?: string[];\n flatCents: number;\n /** Gratis vanaf dit orderbedrag (0/leeg = nooit gratis in deze zone). */\n freeFromCents?: number;\n}\n\nexport interface VerzendConfig {\n shippingFlatCents?: number;\n shippingFreeFromCents?: number;\n /** Zones hebben voorrang; zonder zones geldt het enkele tarief hierboven (gedrag vóór 7.20). */\n shippingZones?: Verzendzone[];\n}\n\n/** De zone die bij een land hoort: eerst een expliciete match, anders de zone zónder landenlijst. */\nexport function zoneVoorLand(cfg: VerzendConfig, land: string | undefined): Verzendzone | undefined {\n const zones = cfg.shippingZones ?? [];\n if (zones.length === 0) return undefined;\n const code = (land ?? \"NL\").trim().toUpperCase();\n return zones.find((z) => (z.landen ?? []).some((l) => l.trim().toUpperCase() === code)) ?? zones.find((z) => (z.landen ?? []).length === 0);\n}\n\n/** Landen waarheen deze winkel verzendt; leeg = geen beperking (er is een \"overige\"-zone). */\nexport function verzendLanden(cfg: VerzendConfig): string[] {\n const zones = cfg.shippingZones ?? [];\n if (zones.length === 0 || zones.some((z) => (z.landen ?? []).length === 0)) return [];\n return [...new Set(zones.flatMap((z) => (z.landen ?? []).map((l) => l.trim().toUpperCase())))];\n}\n\n/**\n * Verzendkosten. Donatie-only = gratis; een kortingscode met gratis verzending maakt het 0.\n *\n * Eén functie voor winkelwagen, afrekenen én server. Er waren drie implementaties: de winkelwagen\n * kende de kortingscode niet (toonde dus altijd de volle verzendkosten), de afrekenpagina lapte\n * `freeShipping` er los omheen, en de server rekende het nog eens over. Nu telt alleen deze.\n */\nexport function shippingCentsFor(\n itemsCents: number,\n cfg: VerzendConfig,\n hasShippableItems: boolean,\n opties?: { land?: string; freeShipping?: boolean },\n): number {\n if (!hasShippableItems) return 0;\n if (opties?.freeShipping) return 0;\n const zone = zoneVoorLand(cfg, opties?.land);\n const flat = zone ? zone.flatCents : (cfg.shippingFlatCents ?? 0);\n const freeFrom = zone ? zone.freeFromCents : 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":"AASO,SAAS,cAAc,QAA0B;AACtD,SAAO,OAAO,KAAK,GAAG;AACxB;AAGO,SAAS,kBAAkB,SAAmD,YAA6B;AAChH,MAAI,YAAY;AACd,UAAM,IAAI,QAAQ,UAAU,KAAK,CAAC,MAAM,EAAE,QAAQ,UAAU;AAC5D,QAAI,GAAG,eAAe,OAAW,QAAO,EAAE;AAAA,EAC5C;AACA,SAAO,QAAQ;AACjB;AAsBO,SAAS,aAAa,KAAoB,MAAmD;AAClG,QAAM,QAAQ,IAAI,iBAAiB,CAAC;AACpC,MAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,QAAM,QAAQ,QAAQ,MAAM,KAAK,EAAE,YAAY;AAC/C,SAAO,MAAM,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,MAAM,IAAI,CAAC,KAAK,MAAM,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,WAAW,CAAC;AAC5I;AAGO,SAAS,cAAc,KAA8B;AAC1D,QAAM,QAAQ,IAAI,iBAAiB,CAAC;AACpC,MAAI,MAAM,WAAW,KAAK,MAAM,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,WAAW,CAAC,EAAG,QAAO,CAAC;AACpF,SAAO,CAAC,GAAG,IAAI,IAAI,MAAM,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AAC/F;AASO,SAAS,iBACd,YACA,KACA,mBACA,QACQ;AACR,MAAI,CAAC,kBAAmB,QAAO;AAC/B,MAAI,QAAQ,aAAc,QAAO;AACjC,QAAM,OAAO,aAAa,KAAK,QAAQ,IAAI;AAC3C,QAAM,OAAO,OAAO,KAAK,YAAa,IAAI,qBAAqB;AAC/D,QAAM,WAAW,OAAO,KAAK,gBAAgB,IAAI;AACjD,MAAI,aAAa,UAAa,WAAW,KAAK,cAAc,SAAU,QAAO;AAC7E,SAAO;AACT;AAGO,SAAS,YAAY,OAAe,WAAW,OAAe;AACnE,SAAO,IAAI,KAAK,aAAa,SAAS,EAAE,OAAO,YAAY,SAAS,CAAC,EAAE,OAAO,QAAQ,GAAG;AAC3F;","names":[]}
|
package/dist/version.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const CORE_VERSION = true ? "7.
|
|
1
|
+
const CORE_VERSION = true ? "7.21.0" : "0.0.0-dev";
|
|
2
2
|
const CORE_PACKAGE = "@xiwebdesign/xicms-core";
|
|
3
3
|
function isNieuwer(beschikbaar, huidig) {
|
|
4
4
|
const delen = (v) => v.split("-")[0].split(".").map((n) => Number.parseInt(n, 10) || 0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiwebdesign/xicms-core",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.21.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": {
|