@xiwebdesign/xicms-core 7.30.0 → 8.15.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.
Files changed (463) hide show
  1. package/dist/XiCMSProvider.js +22 -7
  2. package/dist/XiCMSProvider.js.map +1 -1
  3. package/dist/admin/AdminApp.js +175 -93
  4. package/dist/admin/AdminApp.js.map +1 -1
  5. package/dist/admin/AdminHelp.d.ts +1 -1
  6. package/dist/admin/AdminHelp.js +44 -36
  7. package/dist/admin/AdminHelp.js.map +1 -1
  8. package/dist/admin/CoreVersion.d.ts +6 -3
  9. package/dist/admin/CoreVersion.js +60 -24
  10. package/dist/admin/CoreVersion.js.map +1 -1
  11. package/dist/admin/NewsEditor.d.ts +7 -0
  12. package/dist/admin/NewsEditor.js +117 -75
  13. package/dist/admin/NewsEditor.js.map +1 -1
  14. package/dist/admin/SuperadminPanel.js +1 -1
  15. package/dist/admin/SuperadminPanel.js.map +1 -1
  16. package/dist/admin/ZoekPalet.d.ts +15 -0
  17. package/dist/admin/ZoekPalet.js +123 -0
  18. package/dist/admin/ZoekPalet.js.map +1 -0
  19. package/dist/admin/blockEditors/GenericEditor.js +36 -18
  20. package/dist/admin/blockEditors/GenericEditor.js.map +1 -1
  21. package/dist/admin/blockEditors/StyleEditor.js +37 -3
  22. package/dist/admin/blockEditors/StyleEditor.js.map +1 -1
  23. package/dist/admin/blockEditors/SymbolRefEditor.js +44 -2
  24. package/dist/admin/blockEditors/SymbolRefEditor.js.map +1 -1
  25. package/dist/admin/blockEditors/index.js +154 -73
  26. package/dist/admin/blockEditors/index.js.map +1 -1
  27. package/dist/admin/customBlocks/CustomBlocksPanel.js +18 -7
  28. package/dist/admin/customBlocks/CustomBlocksPanel.js.map +1 -1
  29. package/dist/admin/dashboard/DashboardPanel.js +26 -16
  30. package/dist/admin/dashboard/DashboardPanel.js.map +1 -1
  31. package/dist/admin/editors/RichTextEditor.d.ts +4 -3
  32. package/dist/admin/editors/RichTextEditor.js +19 -56
  33. package/dist/admin/editors/RichTextEditor.js.map +1 -1
  34. package/dist/admin/editors/fontSizeExtension.js +7 -1
  35. package/dist/admin/editors/fontSizeExtension.js.map +1 -1
  36. package/dist/admin/editors/slashMenu.d.ts +18 -0
  37. package/dist/admin/editors/slashMenu.js +34 -0
  38. package/dist/admin/editors/slashMenu.js.map +1 -0
  39. package/dist/admin/editors/useRijkeTekst.d.ts +48 -0
  40. package/dist/admin/editors/useRijkeTekst.js +310 -0
  41. package/dist/admin/editors/useRijkeTekst.js.map +1 -0
  42. package/dist/admin/forms/FormsPanel.d.ts +11 -2
  43. package/dist/admin/forms/FormsPanel.js +218 -65
  44. package/dist/admin/forms/FormsPanel.js.map +1 -1
  45. package/dist/admin/lib/blokInfo.d.ts +17 -0
  46. package/dist/admin/lib/blokInfo.js +80 -0
  47. package/dist/admin/lib/blokInfo.js.map +1 -0
  48. package/dist/admin/lib/foutNaarMens.d.ts +1 -0
  49. package/dist/admin/lib/foutNaarMens.js +22 -0
  50. package/dist/admin/lib/foutNaarMens.js.map +1 -0
  51. package/dist/admin/lib/gewisteVelden.d.ts +13 -0
  52. package/dist/admin/lib/gewisteVelden.js +31 -0
  53. package/dist/admin/lib/gewisteVelden.js.map +1 -0
  54. package/dist/admin/lib/heroHulp.d.ts +11 -0
  55. package/dist/admin/lib/heroHulp.js +18 -0
  56. package/dist/admin/lib/heroHulp.js.map +1 -0
  57. package/dist/admin/lib/kleur.js +2 -3
  58. package/dist/admin/lib/kleur.js.map +1 -1
  59. package/dist/admin/lib/leesbaarheid.d.ts +34 -0
  60. package/dist/admin/lib/leesbaarheid.js +82 -0
  61. package/dist/admin/lib/leesbaarheid.js.map +1 -0
  62. package/dist/admin/lib/lengteAdvies.d.ts +1 -0
  63. package/dist/admin/lib/lengteAdvies.js +16 -0
  64. package/dist/admin/lib/lengteAdvies.js.map +1 -0
  65. package/dist/admin/lib/mediaLijst.d.ts +26 -0
  66. package/dist/admin/lib/mediaLijst.js +42 -0
  67. package/dist/admin/lib/mediaLijst.js.map +1 -0
  68. package/dist/admin/lib/mediaUsage.d.ts +12 -1
  69. package/dist/admin/lib/mediaUsage.js +43 -33
  70. package/dist/admin/lib/mediaUsage.js.map +1 -1
  71. package/dist/admin/lib/menuHulp.d.ts +16 -0
  72. package/dist/admin/lib/menuHulp.js +41 -0
  73. package/dist/admin/lib/menuHulp.js.map +1 -0
  74. package/dist/admin/lib/onopgeslagen.d.ts +10 -0
  75. package/dist/admin/lib/onopgeslagen.js +35 -0
  76. package/dist/admin/lib/onopgeslagen.js.map +1 -0
  77. package/dist/admin/lib/pagesClient.d.ts +55 -2
  78. package/dist/admin/lib/pagesClient.js +126 -28
  79. package/dist/admin/lib/pagesClient.js.map +1 -1
  80. package/dist/admin/lib/paginaGebruik.d.ts +56 -0
  81. package/dist/admin/lib/paginaGebruik.js +109 -0
  82. package/dist/admin/lib/paginaGebruik.js.map +1 -0
  83. package/dist/admin/lib/publicatieCheck.d.ts +25 -0
  84. package/dist/admin/lib/publicatieCheck.js +114 -0
  85. package/dist/admin/lib/publicatieCheck.js.map +1 -0
  86. package/dist/admin/lib/scrollNaarDetail.d.ts +6 -0
  87. package/dist/admin/lib/scrollNaarDetail.js +20 -0
  88. package/dist/admin/lib/scrollNaarDetail.js.map +1 -0
  89. package/dist/admin/lib/symbolsClient.d.ts +10 -0
  90. package/dist/admin/lib/symbolsClient.js +14 -1
  91. package/dist/admin/lib/symbolsClient.js.map +1 -1
  92. package/dist/admin/lib/tekstVeld.d.ts +8 -0
  93. package/dist/admin/lib/tekstVeld.js +10 -0
  94. package/dist/admin/lib/tekstVeld.js.map +1 -0
  95. package/dist/admin/lib/useIsSuperadmin.d.ts +2 -0
  96. package/dist/admin/lib/useIsSuperadmin.js +13 -0
  97. package/dist/admin/lib/useIsSuperadmin.js.map +1 -0
  98. package/dist/admin/lib/veldTaal.d.ts +14 -0
  99. package/dist/admin/lib/veldTaal.js +247 -0
  100. package/dist/admin/lib/veldTaal.js.map +1 -0
  101. package/dist/admin/lib/versieVergelijk.d.ts +17 -0
  102. package/dist/admin/lib/versieVergelijk.js +24 -0
  103. package/dist/admin/lib/versieVergelijk.js.map +1 -0
  104. package/dist/admin/lib/zodFields.js +22 -4
  105. package/dist/admin/lib/zodFields.js.map +1 -1
  106. package/dist/admin/lib/zodFout.d.ts +9 -0
  107. package/dist/admin/lib/zodFout.js +63 -0
  108. package/dist/admin/lib/zodFout.js.map +1 -0
  109. package/dist/admin/media/MediaManager.js +162 -32
  110. package/dist/admin/media/MediaManager.js.map +1 -1
  111. package/dist/admin/media/MediaPicker.d.ts +3 -0
  112. package/dist/admin/media/MediaPicker.js +84 -31
  113. package/dist/admin/media/MediaPicker.js.map +1 -1
  114. package/dist/admin/menu/MenuPanel.js +144 -83
  115. package/dist/admin/menu/MenuPanel.js.map +1 -1
  116. package/dist/admin/navContext.d.ts +3 -0
  117. package/dist/admin/navContext.js +13 -1
  118. package/dist/admin/navContext.js.map +1 -1
  119. package/dist/admin/pages/PageEditor.js +146 -30
  120. package/dist/admin/pages/PageEditor.js.map +1 -1
  121. package/dist/admin/pages/PagesPanel.js +215 -61
  122. package/dist/admin/pages/PagesPanel.js.map +1 -1
  123. package/dist/admin/pages/StarterKiezer.d.ts +12 -0
  124. package/dist/admin/pages/StarterKiezer.js +113 -0
  125. package/dist/admin/pages/StarterKiezer.js.map +1 -0
  126. package/dist/admin/panelRegistry.d.ts +1 -1
  127. package/dist/admin/panelRegistry.js +2 -1
  128. package/dist/admin/panelRegistry.js.map +1 -1
  129. package/dist/admin/patterns/PatternInserter.js +1 -1
  130. package/dist/admin/patterns/PatternInserter.js.map +1 -1
  131. package/dist/admin/settings/BedrijfInstellingen.d.ts +20 -0
  132. package/dist/admin/settings/BedrijfInstellingen.js +144 -0
  133. package/dist/admin/settings/BedrijfInstellingen.js.map +1 -0
  134. package/dist/admin/settings/MailSettings.js +2 -2
  135. package/dist/admin/settings/MailSettings.js.map +1 -1
  136. package/dist/admin/settings/MailTemplates.js +5 -4
  137. package/dist/admin/settings/MailTemplates.js.map +1 -1
  138. package/dist/admin/settings/SettingsPanel.js +120 -78
  139. package/dist/admin/settings/SettingsPanel.js.map +1 -1
  140. package/dist/admin/settings/SnapshotsCard.js +4 -4
  141. package/dist/admin/settings/SnapshotsCard.js.map +1 -1
  142. package/dist/admin/settings/VorigeTerugzetten.d.ts +15 -0
  143. package/dist/admin/settings/VorigeTerugzetten.js +89 -0
  144. package/dist/admin/settings/VorigeTerugzetten.js.map +1 -0
  145. package/dist/admin/shop/CategoriesTab.js +6 -4
  146. package/dist/admin/shop/CategoriesTab.js.map +1 -1
  147. package/dist/admin/shop/DiscountsTab.js +4 -2
  148. package/dist/admin/shop/DiscountsTab.js.map +1 -1
  149. package/dist/admin/shop/OrdersTab.js +57 -19
  150. package/dist/admin/shop/OrdersTab.js.map +1 -1
  151. package/dist/admin/shop/ProductPaneel.js +2 -1
  152. package/dist/admin/shop/ProductPaneel.js.map +1 -1
  153. package/dist/admin/shop/ProductsTab.js +40 -19
  154. package/dist/admin/shop/ProductsTab.js.map +1 -1
  155. package/dist/admin/shop/ShopPanel.js +13 -1
  156. package/dist/admin/shop/ShopPanel.js.map +1 -1
  157. package/dist/admin/shop/ShopSettingsTab.js +27 -1
  158. package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
  159. package/dist/admin/shop/productClient.js +7 -3
  160. package/dist/admin/shop/productClient.js.map +1 -1
  161. package/dist/admin/stats/NietGevonden.d.ts +10 -0
  162. package/dist/admin/stats/NietGevonden.js +78 -0
  163. package/dist/admin/stats/NietGevonden.js.map +1 -0
  164. package/dist/admin/stats/StatsPanel.js +6 -1
  165. package/dist/admin/stats/StatsPanel.js.map +1 -1
  166. package/dist/admin/stats/lib.d.ts +2 -0
  167. package/dist/admin/stats/lib.js.map +1 -1
  168. package/dist/admin/ui/ConfirmDialog.js +10 -1
  169. package/dist/admin/ui/ConfirmDialog.js.map +1 -1
  170. package/dist/admin/ui/Icon.d.ts +34 -0
  171. package/dist/admin/ui/Icon.js +44 -0
  172. package/dist/admin/ui/Icon.js.map +1 -0
  173. package/dist/admin/ui/ImageField.d.ts +15 -0
  174. package/dist/admin/ui/ImageField.js +67 -0
  175. package/dist/admin/ui/ImageField.js.map +1 -0
  176. package/dist/admin/ui/KleurVeld.d.ts +25 -0
  177. package/dist/admin/ui/KleurVeld.js +76 -0
  178. package/dist/admin/ui/KleurVeld.js.map +1 -0
  179. package/dist/admin/ui/LaadStaat.d.ts +21 -0
  180. package/dist/admin/ui/LaadStaat.js +43 -0
  181. package/dist/admin/ui/LaadStaat.js.map +1 -0
  182. package/dist/admin/ui/LeesbaarheidPaneel.d.ts +10 -0
  183. package/dist/admin/ui/LeesbaarheidPaneel.js +68 -0
  184. package/dist/admin/ui/LeesbaarheidPaneel.js.map +1 -0
  185. package/dist/admin/ui/LinkDialog.d.ts +22 -0
  186. package/dist/admin/ui/LinkDialog.js +131 -0
  187. package/dist/admin/ui/LinkDialog.js.map +1 -0
  188. package/dist/admin/ui/LinkVeld.d.ts +14 -0
  189. package/dist/admin/ui/LinkVeld.js +49 -0
  190. package/dist/admin/ui/LinkVeld.js.map +1 -0
  191. package/dist/admin/ui/PreviewLinkResultaat.d.ts +14 -0
  192. package/dist/admin/ui/PreviewLinkResultaat.js +52 -0
  193. package/dist/admin/ui/PreviewLinkResultaat.js.map +1 -0
  194. package/dist/admin/ui/charts.js +5 -5
  195. package/dist/admin/ui/charts.js.map +1 -1
  196. package/dist/admin/ui/primitives.d.ts +16 -6
  197. package/dist/admin/ui/primitives.js +98 -26
  198. package/dist/admin/ui/primitives.js.map +1 -1
  199. package/dist/admin/ui/select.js +5 -2
  200. package/dist/admin/ui/select.js.map +1 -1
  201. package/dist/admin/ui/switch.d.ts +3 -1
  202. package/dist/admin/ui/switch.js +6 -3
  203. package/dist/admin/ui/switch.js.map +1 -1
  204. package/dist/admin/ui/toast.d.ts +2 -1
  205. package/dist/admin/ui/toast.js +17 -11
  206. package/dist/admin/ui/toast.js.map +1 -1
  207. package/dist/admin/visual/BlokKiezer.d.ts +34 -0
  208. package/dist/admin/visual/BlokKiezer.js +225 -0
  209. package/dist/admin/visual/BlokKiezer.js.map +1 -0
  210. package/dist/admin/visual/InlineGereedschap.d.ts +52 -0
  211. package/dist/admin/visual/InlineGereedschap.js +356 -0
  212. package/dist/admin/visual/InlineGereedschap.js.map +1 -0
  213. package/dist/admin/visual/InlineRijkeTekst.d.ts +23 -0
  214. package/dist/admin/visual/InlineRijkeTekst.js +152 -0
  215. package/dist/admin/visual/InlineRijkeTekst.js.map +1 -0
  216. package/dist/admin/visual/VisualEditor.js +273 -125
  217. package/dist/admin/visual/VisualEditor.js.map +1 -1
  218. package/dist/admin.css +1 -1
  219. package/dist/bedrijf/bedrijf.d.ts +36 -0
  220. package/dist/bedrijf/bedrijf.js +110 -0
  221. package/dist/bedrijf/bedrijf.js.map +1 -0
  222. package/dist/blocks/BlockRenderer.js +11 -1
  223. package/dist/blocks/BlockRenderer.js.map +1 -1
  224. package/dist/blocks/blockStyle.d.ts +7 -0
  225. package/dist/blocks/blockStyle.js +16 -3
  226. package/dist/blocks/blockStyle.js.map +1 -1
  227. package/dist/blocks/builtinSchemas.js +6 -0
  228. package/dist/blocks/builtinSchemas.js.map +1 -1
  229. package/dist/blocks/builtins/AgendaRender.d.ts +22 -0
  230. package/dist/blocks/builtins/AgendaRender.js +69 -9
  231. package/dist/blocks/builtins/AgendaRender.js.map +1 -1
  232. package/dist/blocks/builtins/Availability.d.ts +1 -0
  233. package/dist/blocks/builtins/Availability.js +23 -0
  234. package/dist/blocks/builtins/Availability.js.map +1 -0
  235. package/dist/blocks/builtins/AvailabilityRender.d.ts +12 -0
  236. package/dist/blocks/builtins/AvailabilityRender.js +105 -0
  237. package/dist/blocks/builtins/AvailabilityRender.js.map +1 -0
  238. package/dist/blocks/builtins/BeforeAfterRender.js +4 -3
  239. package/dist/blocks/builtins/BeforeAfterRender.js.map +1 -1
  240. package/dist/blocks/builtins/Booking.js +1 -1
  241. package/dist/blocks/builtins/Booking.js.map +1 -1
  242. package/dist/blocks/builtins/BreadcrumbsRender.d.ts +4 -3
  243. package/dist/blocks/builtins/BreadcrumbsRender.js +14 -8
  244. package/dist/blocks/builtins/BreadcrumbsRender.js.map +1 -1
  245. package/dist/blocks/builtins/ColumnsRender.d.ts +1 -1
  246. package/dist/blocks/builtins/ColumnsRender.js +3 -1
  247. package/dist/blocks/builtins/ColumnsRender.js.map +1 -1
  248. package/dist/blocks/builtins/Contact.js +1 -1
  249. package/dist/blocks/builtins/Contact.js.map +1 -1
  250. package/dist/blocks/builtins/ContactRender.d.ts +1 -1
  251. package/dist/blocks/builtins/ContactRender.js +29 -8
  252. package/dist/blocks/builtins/ContactRender.js.map +1 -1
  253. package/dist/blocks/builtins/Cta.js +1 -1
  254. package/dist/blocks/builtins/Cta.js.map +1 -1
  255. package/dist/blocks/builtins/CtaRender.d.ts +1 -1
  256. package/dist/blocks/builtins/CtaRender.js +5 -4
  257. package/dist/blocks/builtins/CtaRender.js.map +1 -1
  258. package/dist/blocks/builtins/Embed.js +1 -1
  259. package/dist/blocks/builtins/Embed.js.map +1 -1
  260. package/dist/blocks/builtins/FormBlock.js +1 -0
  261. package/dist/blocks/builtins/FormBlock.js.map +1 -1
  262. package/dist/blocks/builtins/FormBlockRender.d.ts +6 -0
  263. package/dist/blocks/builtins/FormBlockRender.js +88 -16
  264. package/dist/blocks/builtins/FormBlockRender.js.map +1 -1
  265. package/dist/blocks/builtins/GalleryRender.js +3 -2
  266. package/dist/blocks/builtins/GalleryRender.js.map +1 -1
  267. package/dist/blocks/builtins/Hero.js +1 -1
  268. package/dist/blocks/builtins/Hero.js.map +1 -1
  269. package/dist/blocks/builtins/HeroRender.js +7 -3
  270. package/dist/blocks/builtins/HeroRender.js.map +1 -1
  271. package/dist/blocks/builtins/OpenNowBadge.d.ts +4 -2
  272. package/dist/blocks/builtins/OpenNowBadge.js +6 -6
  273. package/dist/blocks/builtins/OpenNowBadge.js.map +1 -1
  274. package/dist/blocks/builtins/OpeningHoursRender.d.ts +8 -2
  275. package/dist/blocks/builtins/OpeningHoursRender.js +27 -6
  276. package/dist/blocks/builtins/OpeningHoursRender.js.map +1 -1
  277. package/dist/blocks/builtins/PriceList.d.ts +1 -0
  278. package/dist/blocks/builtins/PriceList.js +25 -0
  279. package/dist/blocks/builtins/PriceList.js.map +1 -0
  280. package/dist/blocks/builtins/PriceListRender.d.ts +17 -0
  281. package/dist/blocks/builtins/PriceListRender.js +87 -0
  282. package/dist/blocks/builtins/PriceListRender.js.map +1 -0
  283. package/dist/blocks/builtins/RichTextBlockRender.js +6 -1
  284. package/dist/blocks/builtins/RichTextBlockRender.js.map +1 -1
  285. package/dist/blocks/builtins/SectionHeading.d.ts +1 -0
  286. package/dist/blocks/builtins/SectionHeading.js +14 -0
  287. package/dist/blocks/builtins/SectionHeading.js.map +1 -0
  288. package/dist/blocks/builtins/SectionHeadingRender.d.ts +7 -0
  289. package/dist/blocks/builtins/SectionHeadingRender.js +14 -0
  290. package/dist/blocks/builtins/SectionHeadingRender.js.map +1 -0
  291. package/dist/blocks/builtins/SliderRender.js +3 -2
  292. package/dist/blocks/builtins/SliderRender.js.map +1 -1
  293. package/dist/blocks/builtins/SymbolRef.js +1 -1
  294. package/dist/blocks/builtins/SymbolRef.js.map +1 -1
  295. package/dist/blocks/builtins/TeamRender.js +6 -1
  296. package/dist/blocks/builtins/TeamRender.js.map +1 -1
  297. package/dist/blocks/builtins/Testimonials.js +3 -1
  298. package/dist/blocks/builtins/Testimonials.js.map +1 -1
  299. package/dist/blocks/builtins/TestimonialsRender.js +4 -0
  300. package/dist/blocks/builtins/TestimonialsRender.js.map +1 -1
  301. package/dist/blocks/builtins/WhatsappChatRender.d.ts +1 -1
  302. package/dist/blocks/builtins/WhatsappChatRender.js +1 -1
  303. package/dist/blocks/builtins/WhatsappChatRender.js.map +1 -1
  304. package/dist/blocks/builtins/Widgets.js +2 -2
  305. package/dist/blocks/builtins/Widgets.js.map +1 -1
  306. package/dist/blocks/builtins/WidgetsRender.js +3 -1
  307. package/dist/blocks/builtins/WidgetsRender.js.map +1 -1
  308. package/dist/blocks/builtins/index.d.ts +3 -0
  309. package/dist/blocks/builtins/index.js +6 -0
  310. package/dist/blocks/builtins/index.js.map +1 -1
  311. package/dist/blocks/builtins/lib/autoComplete.d.ts +7 -0
  312. package/dist/blocks/builtins/lib/autoComplete.js +20 -0
  313. package/dist/blocks/builtins/lib/autoComplete.js.map +1 -0
  314. package/dist/blocks/builtins/lib/bookingUrl.d.ts +2 -2
  315. package/dist/blocks/builtins/lib/bookingUrl.js +1 -1
  316. package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -1
  317. package/dist/blocks/builtins/lib/ical.d.ts +24 -0
  318. package/dist/blocks/builtins/lib/ical.js +82 -0
  319. package/dist/blocks/builtins/lib/ical.js.map +1 -0
  320. package/dist/blocks/builtins/lib/vandaag.d.ts +8 -0
  321. package/dist/blocks/builtins/lib/vandaag.js +22 -0
  322. package/dist/blocks/builtins/lib/vandaag.js.map +1 -0
  323. package/dist/blocks/registry.d.ts +6 -0
  324. package/dist/blocks/registry.js.map +1 -1
  325. package/dist/blocks/ui/index.js +1 -0
  326. package/dist/blocks/ui/index.js.map +1 -1
  327. package/dist/components/EditBar.js +2 -4
  328. package/dist/components/EditBar.js.map +1 -1
  329. package/dist/components/News.js +26 -18
  330. package/dist/components/News.js.map +1 -1
  331. package/dist/components/PageView.d.ts +7 -1
  332. package/dist/components/PageView.js +17 -0
  333. package/dist/components/PageView.js.map +1 -1
  334. package/dist/components/ResponsiveImage.js +18 -20
  335. package/dist/components/ResponsiveImage.js.map +1 -1
  336. package/dist/components/site/SiteFooter.d.ts +6 -1
  337. package/dist/components/site/SiteFooter.js +61 -9
  338. package/dist/components/site/SiteFooter.js.map +1 -1
  339. package/dist/components/site/SiteHeader.d.ts +15 -0
  340. package/dist/components/site/SiteHeader.js +70 -0
  341. package/dist/components/site/SiteHeader.js.map +1 -0
  342. package/dist/components/site/SiteNav.d.ts +2 -0
  343. package/dist/components/site/SiteNav.js +29 -5
  344. package/dist/components/site/SiteNav.js.map +1 -1
  345. package/dist/demo/DemoStudio.js +2 -2
  346. package/dist/demo/DemoStudio.js.map +1 -1
  347. package/dist/demo/demoStore.d.ts +13 -0
  348. package/dist/demo/demoStore.js +36 -0
  349. package/dist/demo/demoStore.js.map +1 -1
  350. package/dist/editor/EditorProvider.js +15 -4
  351. package/dist/editor/EditorProvider.js.map +1 -1
  352. package/dist/index.d.ts +4 -1
  353. package/dist/index.js +16 -1
  354. package/dist/index.js.map +1 -1
  355. package/dist/media/ImageContext.d.ts +17 -0
  356. package/dist/media/ImageContext.js +65 -20
  357. package/dist/media/ImageContext.js.map +1 -1
  358. package/dist/media/altInHtml.d.ts +9 -0
  359. package/dist/media/altInHtml.js +17 -0
  360. package/dist/media/altInHtml.js.map +1 -0
  361. package/dist/media/srcset.d.ts +12 -0
  362. package/dist/media/srcset.js +13 -0
  363. package/dist/media/srcset.js.map +1 -0
  364. package/dist/modules/builtins.d.ts +1 -0
  365. package/dist/modules/builtins.js +16 -3
  366. package/dist/modules/builtins.js.map +1 -1
  367. package/dist/modules/shop/blocks/Cart.js +5 -3
  368. package/dist/modules/shop/blocks/Cart.js.map +1 -1
  369. package/dist/modules/shop/blocks/Checkout.js +56 -35
  370. package/dist/modules/shop/blocks/Checkout.js.map +1 -1
  371. package/dist/modules/shop/blocks/Donation.js +4 -4
  372. package/dist/modules/shop/blocks/Donation.js.map +1 -1
  373. package/dist/modules/shop/blocks/ProductDetail.js +19 -3
  374. package/dist/modules/shop/blocks/ProductDetail.js.map +1 -1
  375. package/dist/modules/shop/blocks/ProductGrid.d.ts +3 -1
  376. package/dist/modules/shop/blocks/ProductGrid.js +8 -4
  377. package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
  378. package/dist/modules/shop/blocks/ShopCategories.js +4 -3
  379. package/dist/modules/shop/blocks/ShopCategories.js.map +1 -1
  380. package/dist/modules/shop/lib.d.ts +4 -0
  381. package/dist/modules/shop/lib.js +14 -0
  382. package/dist/modules/shop/lib.js.map +1 -1
  383. package/dist/modules/shop/settings.d.ts +3 -0
  384. package/dist/modules/shop/settings.js +14 -0
  385. package/dist/modules/shop/settings.js.map +1 -1
  386. package/dist/modules/shop/strings.d.ts +4 -0
  387. package/dist/modules/shop/strings.js +8 -0
  388. package/dist/modules/shop/strings.js.map +1 -1
  389. package/dist/next/envCheck.d.ts +42 -0
  390. package/dist/next/envCheck.js +106 -0
  391. package/dist/next/envCheck.js.map +1 -0
  392. package/dist/next/index.cjs +185 -2
  393. package/dist/next/index.d.ts +2 -0
  394. package/dist/next/index.js +8 -1
  395. package/dist/next/index.js.map +1 -1
  396. package/dist/next/securityHeaders.d.ts +36 -0
  397. package/dist/next/securityHeaders.js +74 -0
  398. package/dist/next/securityHeaders.js.map +1 -0
  399. package/dist/patterns/builtins.d.ts +7 -0
  400. package/dist/patterns/builtins.js +138 -3
  401. package/dist/patterns/builtins.js.map +1 -1
  402. package/dist/releaseNotes.js +140 -0
  403. package/dist/releaseNotes.js.map +1 -1
  404. package/dist/render/PublishedPage.d.ts +2 -1
  405. package/dist/render/PublishedPage.js +10 -4
  406. package/dist/render/PublishedPage.js.map +1 -1
  407. package/dist/schema/blocks.d.ts +470 -0
  408. package/dist/schema/blocks.js +102 -4
  409. package/dist/schema/blocks.js.map +1 -1
  410. package/dist/schema/business.d.ts +117 -0
  411. package/dist/schema/business.js +73 -0
  412. package/dist/schema/business.js.map +1 -0
  413. package/dist/schema/fields.d.ts +2 -1
  414. package/dist/schema/fields.js.map +1 -1
  415. package/dist/schema/forms.d.ts +18 -0
  416. package/dist/schema/forms.js +18 -3
  417. package/dist/schema/forms.js.map +1 -1
  418. package/dist/schema/mail.d.ts +10 -0
  419. package/dist/schema/mail.js +7 -0
  420. package/dist/schema/mail.js.map +1 -1
  421. package/dist/schema/settings.d.ts +101 -0
  422. package/dist/schema/settings.js +24 -3
  423. package/dist/schema/settings.js.map +1 -1
  424. package/dist/schema/shop.d.ts +2 -0
  425. package/dist/schema/shop.js +4 -0
  426. package/dist/schema/shop.js.map +1 -1
  427. package/dist/schema/shopGeld.d.ts +1 -0
  428. package/dist/schema/shopGeld.js +1 -0
  429. package/dist/schema/shopGeld.js.map +1 -1
  430. package/dist/schema/siteConfig.d.ts +68 -1
  431. package/dist/schema/siteConfig.js +7 -2
  432. package/dist/schema/siteConfig.js.map +1 -1
  433. package/dist/server/blockData.d.ts +1 -1
  434. package/dist/server/blockData.js +74 -18
  435. package/dist/server/blockData.js.map +1 -1
  436. package/dist/server/cspRapport.d.ts +20 -0
  437. package/dist/server/cspRapport.js +56 -0
  438. package/dist/server/cspRapport.js.map +1 -0
  439. package/dist/server/fonts.d.ts +3 -0
  440. package/dist/server/fonts.js +39 -0
  441. package/dist/server/fonts.js.map +1 -0
  442. package/dist/server/index.d.ts +3 -0
  443. package/dist/server/index.js +8 -0
  444. package/dist/server/index.js.map +1 -1
  445. package/dist/server/sanitize.js +15 -2
  446. package/dist/server/sanitize.js.map +1 -1
  447. package/dist/settings/useSiteSettings.js +4 -1
  448. package/dist/settings/useSiteSettings.js.map +1 -1
  449. package/dist/starters/starters.d.ts +69 -0
  450. package/dist/starters/starters.js +171 -0
  451. package/dist/starters/starters.js.map +1 -0
  452. package/dist/styles.css +1149 -208
  453. package/dist/theme/color.d.ts +10 -0
  454. package/dist/theme/color.js +17 -1
  455. package/dist/theme/color.js.map +1 -1
  456. package/dist/theme/fontFallback.d.ts +23 -0
  457. package/dist/theme/fontFallback.js +58 -0
  458. package/dist/theme/fontFallback.js.map +1 -0
  459. package/dist/theme/fonts.d.ts +11 -0
  460. package/dist/theme/fonts.js +16 -0
  461. package/dist/theme/fonts.js.map +1 -0
  462. package/dist/version.js +1 -1
  463. package/package.json +6 -4
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/media/srcset.ts"],"sourcesContent":["/**\n * De srcset voor een geüpload beeld (8.3). De upload-pipeline maakt een WebP-ladder (320…1280) én\n * een volle WebP (tot 2048). Tot 8.3 stond die volle WebP als enige kandidaat in een\n * `<source type=\"image/webp\">` — en elke moderne browser kiest de `<source>`, dus de ladder op de\n * `<img>` werd nooit gebruikt: een telefoon downloadde het 2048-beeld voor een kaartje van 300px.\n * Nu één srcset met de hele ladder plus de volle versie als grootste trede; de browser kiest zelf.\n */\nexport interface Variant {\n url: string;\n width: number;\n}\n\nexport function bronSet(ladder: Variant[] | undefined, volle?: Variant | null): string | undefined {\n const treden = [...(ladder ?? [])].filter((v) => v.url && v.width > 0);\n const grootste = treden.reduce((m, v) => Math.max(m, v.width), 0);\n if (volle?.url && volle.width > grootste) treden.push(volle);\n if (treden.length === 0) return undefined;\n const uniek = new Map<number, Variant>();\n for (const v of treden) if (!uniek.has(v.width)) uniek.set(v.width, v);\n return [...uniek.values()]\n .sort((a, b) => a.width - b.width)\n .map((v) => `${v.url} ${v.width}w`)\n .join(\", \");\n}\n"],"mappings":"AAYO,SAAS,QAAQ,QAA+B,OAA4C;AACjG,QAAM,SAAS,CAAC,GAAI,UAAU,CAAC,CAAE,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC;AACrE,QAAM,WAAW,OAAO,OAAO,CAAC,GAAG,MAAM,KAAK,IAAI,GAAG,EAAE,KAAK,GAAG,CAAC;AAChE,MAAI,OAAO,OAAO,MAAM,QAAQ,SAAU,QAAO,KAAK,KAAK;AAC3D,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,QAAQ,oBAAI,IAAqB;AACvC,aAAW,KAAK,OAAQ,KAAI,CAAC,MAAM,IAAI,EAAE,KAAK,EAAG,OAAM,IAAI,EAAE,OAAO,CAAC;AACrE,SAAO,CAAC,GAAG,MAAM,OAAO,CAAC,EACtB,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,EAAE,KAAK,GAAG,EACjC,KAAK,IAAI;AACd;","names":[]}
@@ -27,6 +27,7 @@ export declare const videoModule: ModuleDefinition;
27
27
  export declare const bannerModule: ModuleDefinition;
28
28
  export declare const contactModule: ModuleDefinition;
29
29
  export declare const newsletterModule: ModuleDefinition;
30
+ export declare const verhuurModule: ModuleDefinition;
30
31
  export declare const bookingModule: ModuleDefinition;
31
32
  export declare const accordionModule: ModuleDefinition;
32
33
  export declare const embedModule: ModuleDefinition;
@@ -10,6 +10,9 @@ import { galleryBlock } from "../blocks/builtins/Gallery.js";
10
10
  import { faqBlock } from "../blocks/builtins/Faq.js";
11
11
  import { openingHoursBlock } from "../blocks/builtins/OpeningHours.js";
12
12
  import { pricingBlock } from "../blocks/builtins/Pricing.js";
13
+ import { priceListBlock } from "../blocks/builtins/PriceList.js";
14
+ import { sectionHeadingBlock } from "../blocks/builtins/SectionHeading.js";
15
+ import { availabilityBlock } from "../blocks/builtins/Availability.js";
13
16
  import { newsListBlock } from "../blocks/builtins/NewsListBlock.js";
14
17
  import { formBlock } from "../blocks/builtins/FormBlock.js";
15
18
  import { testimonialsBlock } from "../blocks/builtins/Testimonials.js";
@@ -59,7 +62,7 @@ const contentModule = defineModule({
59
62
  label: "Basisinhoud",
60
63
  description: "Kern-bouwstenen: hero, tekst, afbeelding, CTA, kolommen, zijbalk, witruimte.",
61
64
  core: true,
62
- blocks: [heroBlock, richTextBlock, imageBlock, ctaBlock, columnsBlock, withSidebarBlock, spacerBlock, buttonsBlock, quoteBlock, dividerBlock, ctaWidget, symbolRefBlock]
65
+ blocks: [heroBlock, sectionHeadingBlock, richTextBlock, imageBlock, ctaBlock, columnsBlock, withSidebarBlock, spacerBlock, buttonsBlock, quoteBlock, dividerBlock, ctaWidget, symbolRefBlock]
63
66
  });
64
67
  const galleryModule = defineModule({
65
68
  id: "gallery",
@@ -93,7 +96,7 @@ const pricingModule = defineModule({
93
96
  id: "pricing",
94
97
  version: CORE_VERSION,
95
98
  label: "Prijzen",
96
- blocks: [pricingBlock]
99
+ blocks: [pricingBlock, priceListBlock]
97
100
  });
98
101
  const pagesModule = defineModule({
99
102
  id: "pages",
@@ -241,10 +244,18 @@ const newsletterModule = defineModule({
241
244
  defaultEnabled: false,
242
245
  blocks: [newsletterBlock, newsletterWidget]
243
246
  });
247
+ const verhuurModule = defineModule({
248
+ id: "verhuur",
249
+ version: CORE_VERSION,
250
+ label: "Verhuur & beschikbaarheid",
251
+ description: "Beschikbaarheidskalender uit de iCal-link van je boekingssysteem, met aanvragen voor een gekozen periode.",
252
+ defaultEnabled: false,
253
+ blocks: [availabilityBlock]
254
+ });
244
255
  const bookingModule = defineModule({
245
256
  id: "booking",
246
257
  version: CORE_VERSION,
247
- label: "Afspraak/booking",
258
+ label: "Afspraak maken",
248
259
  description: "Boekings-embed (bv. Calendly), consent-gated.",
249
260
  defaultEnabled: false,
250
261
  blocks: [bookingBlock]
@@ -402,6 +413,7 @@ const builtinModules = [
402
413
  contactModule,
403
414
  newsletterModule,
404
415
  bookingModule,
416
+ verhuurModule,
405
417
  accordionModule,
406
418
  embedModule,
407
419
  cardsModule,
@@ -455,6 +467,7 @@ export {
455
467
  teamModule,
456
468
  testimonialsModule,
457
469
  timelineModule,
470
+ verhuurModule,
458
471
  videoModule,
459
472
  whatsappModule
460
473
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/modules/builtins.ts"],"sourcesContent":["/**\n * Ingebouwde modules (XiCMS 3.0). Elke \"feature\" van 2.x is hier een first-class module geworden,\n * zodat hij per site aan/uit kan en los te verbeteren is. De bijbehorende admin-panelen staan in\n * `@xiwebdesign/xicms-core/admin` (paneel-registry), gekoppeld via dezelfde `id`/`featureKey`.\n *\n * Backward compatible: zonder `SiteConfig.modules`/`features` zijn alle modules actief — identiek\n * aan 2.x. De `content`-module is `core: true` en kan niet uitgezet worden (de basis-bouwstenen).\n */\nimport * as z from \"zod/mini\";\nimport { defineModule } from \"./defineModule\";\nimport type { ModuleDefinition } from \"./types\";\n\nimport { heroBlock } from \"../blocks/builtins/Hero\";\nimport { richTextBlock } from \"../blocks/builtins/RichTextBlock\";\nimport { imageBlock } from \"../blocks/builtins/ImageBlock\";\nimport { ctaBlock } from \"../blocks/builtins/Cta\";\nimport { columnsBlock } from \"../blocks/builtins/Columns\";\nimport { spacerBlock } from \"../blocks/builtins/Spacer\";\nimport { galleryBlock } from \"../blocks/builtins/Gallery\";\nimport { faqBlock } from \"../blocks/builtins/Faq\";\nimport { openingHoursBlock } from \"../blocks/builtins/OpeningHours\";\nimport { pricingBlock } from \"../blocks/builtins/Pricing\";\nimport { newsListBlock } from \"../blocks/builtins/NewsListBlock\";\nimport { formBlock } from \"../blocks/builtins/FormBlock\";\nimport { testimonialsBlock } from \"../blocks/builtins/Testimonials\";\nimport { teamBlock } from \"../blocks/builtins/Team\";\nimport { agendaBlock } from \"../blocks/builtins/Agenda\";\nimport { searchBlock } from \"../blocks/builtins/Search\";\nimport { featureBlock, countersBlock, logosBlock, timelineBlock } from \"../blocks/builtins/Sections\";\nimport { symbolRefBlock } from \"../blocks/builtins/SymbolRef\";\nimport { videoBlock } from \"../blocks/builtins/Video\";\nimport { bannerBlock } from \"../blocks/builtins/Banner\";\nimport { contactBlock, socialBlock } from \"../blocks/builtins/Contact\";\nimport { mapBlock } from \"../blocks/builtins/MapBlock\";\nimport { newsletterBlock } from \"../blocks/builtins/Newsletter\";\nimport { bookingBlock } from \"../blocks/builtins/Booking\";\nimport { buttonsBlock, quoteBlock, dividerBlock } from \"../blocks/builtins/Elements\";\nimport { accordionBlock } from \"../blocks/builtins/Accordion\";\nimport { embedBlock } from \"../blocks/builtins/Embed\";\nimport { withSidebarBlock, tabsBlock } from \"../blocks/builtins/Layout\";\nimport { cardsBlock } from \"../blocks/builtins/Cards\";\nimport { downloadsBlock } from \"../blocks/builtins/Downloads\";\nimport { pdfBlock } from \"../blocks/builtins/PdfBlock\";\nimport { countdownBlock } from \"../blocks/builtins/Countdown\";\nimport { sliderBlock } from \"../blocks/builtins/Slider\";\nimport { whatsappChatBlock } from \"../blocks/builtins/WhatsappChat\";\nimport { beforeAfterBlock } from \"../blocks/builtins/BeforeAfter\";\nimport { portfolioBlock } from \"../blocks/builtins/Portfolio\";\nimport { jobsBlock } from \"../blocks/builtins/Jobs\";\nimport { breadcrumbsBlock } from \"../blocks/builtins/Breadcrumbs\";\nimport {\n newsWidget,\n agendaWidget,\n openingHoursWidget,\n contactWidget,\n socialWidget as socialWidgetBlock,\n newsletterWidget,\n ctaWidget,\n galleryWidget,\n testimonialsWidget,\n cardsWidget,\n downloadsWidget,\n countdownWidget,\n} from \"../blocks/builtins/Widgets\";\n\nconst CORE_VERSION = \"5.0.0\";\n\n/**\n * Basis-bouwstenen — altijd aanwezig (niet uit te zetten). Bevat ook de indelingsblokken\n * (kolommen, \"Met zijbalk\") waarmee je widgets naast je hoofdinhoud plaatst, plus de\n * compacte CTA-widget.\n */\nexport const contentModule = defineModule({\n id: \"content\",\n version: CORE_VERSION,\n label: \"Basisinhoud\",\n description: \"Kern-bouwstenen: hero, tekst, afbeelding, CTA, kolommen, zijbalk, witruimte.\",\n core: true,\n blocks: [heroBlock, richTextBlock, imageBlock, ctaBlock, columnsBlock, withSidebarBlock, spacerBlock, buttonsBlock, quoteBlock, dividerBlock, ctaWidget, symbolRefBlock],\n});\n\nexport const galleryModule = defineModule({\n id: \"gallery\",\n version: CORE_VERSION,\n label: \"Fotogalerij\",\n description: \"Galerij-block met grid en (optioneel) lightbox + compacte fotostrip-widget.\",\n blocks: [galleryBlock, galleryWidget],\n // Per-site instelbaar door de agent/klant (modules.gallery.config) zonder core te forken.\n // `.describe()` = het label dat de klant in /beheer ziet.\n settingsSchema: z.object({\n columns: z._default(z.int().check(z.minimum(1)).check(z.maximum(6)), 3).register(z.globalRegistry, { description: \"Kolommen\" }),\n lightbox: z._default(z.boolean(), true).register(z.globalRegistry, { description: \"Lightbox bij klikken\" }),\n }),\n defaultSettings: { columns: 3, lightbox: true },\n});\n\nexport const faqModule = defineModule({\n id: \"faq\",\n version: CORE_VERSION,\n label: \"FAQ\",\n description: \"Veelgestelde vragen (accordeon) met optionele zoek + FAQ-JSON-LD.\",\n blocks: [faqBlock],\n});\n\nexport const openingHoursModule = defineModule({\n id: \"openingHours\",\n version: CORE_VERSION,\n label: \"Openingstijden\",\n description: \"Openingstijden-tabel + compacte widget met 'vandaag' gemarkeerd.\",\n blocks: [openingHoursBlock, openingHoursWidget],\n});\n\nexport const pricingModule = defineModule({\n id: \"pricing\",\n version: CORE_VERSION,\n label: \"Prijzen\",\n blocks: [pricingBlock],\n});\n\nexport const pagesModule = defineModule({\n id: \"pages\",\n version: CORE_VERSION,\n label: \"Pagina's\",\n featureKey: \"pages\",\n description: \"Paginabouwer (draft → publish + versiegeschiedenis).\",\n});\n\nexport const newsModule = defineModule({\n id: \"news\",\n version: CORE_VERSION,\n label: \"Nieuws\",\n featureKey: \"news\",\n description: \"Nieuwsartikelen + nieuwslijst-block + 'laatste nieuws'-widget voor de zijbalk.\",\n blocks: [newsListBlock, newsWidget],\n});\n\nexport const mediaModule = defineModule({\n id: \"media\",\n version: CORE_VERSION,\n label: \"Media\",\n featureKey: \"media\",\n description: \"Mediabeheer met compressie + webp/srcset-varianten.\",\n requires: [{ kind: \"function\", name: \"onMediaUpload\" }, { kind: \"storage\", prefix: \"sites/\" }],\n});\n\nexport const formsModule = defineModule({\n id: \"forms\",\n version: CORE_VERSION,\n label: \"Formulieren\",\n featureKey: \"forms\",\n description: \"Formulierbouwer + inzendingen + e-mailnotificatie.\",\n blocks: [formBlock],\n requires: [\n { kind: \"function\", name: \"submitForm\" },\n { kind: \"firestore\", collection: \"forms\" },\n ],\n});\n\nexport const statsModule = defineModule({\n id: \"stats\",\n version: CORE_VERSION,\n label: \"Statistieken\",\n featureKey: \"stats\",\n description: \"Privacy-vriendelijke bezoekersstatistieken (geen cookies).\",\n requires: [{ kind: \"function\", name: \"trackView\" }],\n});\n\nexport const settingsModule = defineModule({\n id: \"settings\",\n version: CORE_VERSION,\n label: \"Instellingen\",\n core: true,\n description: \"Site-instellingen (nav, thema, SEO, formulier-afzender) — alleen siteadmin.\",\n});\n\n// Opt-in modules (defaultEnabled: false): worden bij installatie of later aangezet via\n// `modules: { <id>: true }`. Geen extra backend nodig — data leeft in de page-blocks.\nexport const testimonialsModule = defineModule({\n id: \"testimonials\",\n version: CORE_VERSION,\n label: \"Reviews\",\n description: \"Klantquotes/reviews met sterren, optionele Review-JSON-LD + compacte review-widget.\",\n defaultEnabled: false,\n blocks: [testimonialsBlock, testimonialsWidget],\n});\n\nexport const teamModule = defineModule({\n id: \"team\",\n version: CORE_VERSION,\n label: \"Team\",\n description: \"Team-/medewerkersoverzicht met foto, functie en bio.\",\n defaultEnabled: false,\n blocks: [teamBlock],\n});\n\nexport const agendaModule = defineModule({\n id: \"agenda\",\n version: CORE_VERSION,\n label: \"Agenda\",\n description: \"Evenementen/agenda (chronologisch) met Event-JSON-LD + 'komende agenda'-widget.\",\n defaultEnabled: false,\n blocks: [agendaBlock, agendaWidget],\n});\n\nexport const searchModule = defineModule({\n id: \"search\",\n version: CORE_VERSION,\n label: \"Zoeken\",\n description: \"Site-zoekblok dat gepubliceerde pagina's (en nieuws) client-side doorzoekt.\",\n defaultEnabled: false,\n blocks: [searchBlock],\n});\n\nexport const featureModule = defineModule({\n id: \"feature\",\n version: CORE_VERSION,\n label: \"Beeld + tekst\",\n description: \"Feature-sectie met afbeelding links/rechts en tekst.\",\n defaultEnabled: false,\n blocks: [featureBlock],\n});\n\nexport const countersModule = defineModule({\n id: \"counters\",\n version: CORE_VERSION,\n label: \"Tellers\",\n description: \"Statistiek-tellers (bv. “100+ klanten”).\",\n defaultEnabled: false,\n blocks: [countersBlock],\n});\n\nexport const logosModule = defineModule({\n id: \"logos\",\n version: CORE_VERSION,\n label: \"Logo's\",\n description: \"Partner-/klantlogo-strip.\",\n defaultEnabled: false,\n blocks: [logosBlock],\n});\n\nexport const timelineModule = defineModule({\n id: \"timeline\",\n version: CORE_VERSION,\n label: \"Tijdlijn\",\n description: \"Stappen/proces als tijdlijn.\",\n defaultEnabled: false,\n blocks: [timelineBlock],\n});\n\nexport const videoModule = defineModule({\n id: \"video\",\n version: CORE_VERSION,\n label: \"Video\",\n description: \"YouTube/Vimeo/MP4-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [videoBlock],\n});\n\nexport const bannerModule = defineModule({\n id: \"banner\",\n version: CORE_VERSION,\n label: \"Aankondiging\",\n description: \"Aankondigingsbalk, optioneel sluitbaar.\",\n defaultEnabled: false,\n blocks: [bannerBlock],\n});\n\nexport const contactModule = defineModule({\n id: \"contact\",\n version: CORE_VERSION,\n label: \"Contact + kaart + social\",\n description: \"Contactgegevens (JSON-LD), kaart (consent-gated), social-links + compacte widgets.\",\n defaultEnabled: false,\n blocks: [contactBlock, mapBlock, socialBlock, contactWidget, socialWidgetBlock],\n});\n\nexport const newsletterModule = defineModule({\n id: \"newsletter\",\n version: CORE_VERSION,\n label: \"Nieuwsbrief\",\n description: \"Aanmeldformulier via een externe provider-URL + compacte nieuwsbrief-widget.\",\n defaultEnabled: false,\n blocks: [newsletterBlock, newsletterWidget],\n});\n\nexport const bookingModule = defineModule({\n id: \"booking\",\n version: CORE_VERSION,\n label: \"Afspraak/booking\",\n description: \"Boekings-embed (bv. Calendly), consent-gated.\",\n defaultEnabled: false,\n blocks: [bookingBlock],\n});\n\nexport const accordionModule = defineModule({\n id: \"accordion\",\n version: CORE_VERSION,\n label: \"Accordeon\",\n description: \"Generieke in-/uitklapbare panelen.\",\n defaultEnabled: false,\n blocks: [accordionBlock],\n});\n\nexport const embedModule = defineModule({\n id: \"embed\",\n version: CORE_VERSION,\n label: \"Embed\",\n description: \"Generieke responsive iframe-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [embedBlock],\n});\n\n/* ── Nieuwe modules (3.1) — veelgebruikt op websites, volwaardig + widget waar zinvol ── */\n\nexport const cardsModule = defineModule({\n id: \"cards\",\n version: CORE_VERSION,\n label: \"Diensten / kaarten\",\n description: \"Diensten-/featurekaarten in een grid (icoon of beeld) + compacte 'uitgelicht'-widget.\",\n defaultEnabled: false,\n blocks: [cardsBlock, cardsWidget],\n});\n\nexport const tabsModule = defineModule({\n id: \"tabs\",\n version: CORE_VERSION,\n label: \"Tabbladen\",\n description: \"Tabblad-indeling: per tab een eigen set blokken (bv. beschrijving / specificaties).\",\n defaultEnabled: false,\n blocks: [tabsBlock],\n});\n\nexport const downloadsModule = defineModule({\n id: \"downloads\",\n version: CORE_VERSION,\n label: \"Downloads\",\n description: \"Lijst met downloadbare documenten (brochures, prijslijsten) + compacte widget.\",\n defaultEnabled: false,\n blocks: [downloadsBlock, downloadsWidget],\n});\n\nexport const pdfModule = defineModule({\n id: \"pdf\",\n version: CORE_VERSION,\n label: \"PDF-lezer\",\n description: \"Inline PDF-lezer voor menukaarten/documenten; meerdere PDF's met tabs, zelf te vervangen.\",\n defaultEnabled: false,\n blocks: [pdfBlock],\n});\n\nexport const countdownModule = defineModule({\n id: \"countdown\",\n version: CORE_VERSION,\n label: \"Aftelteller\",\n description: \"Tikkende countdown naar een datum (lancering, evenement, aanbieding) + widget.\",\n defaultEnabled: false,\n blocks: [countdownBlock, countdownWidget],\n});\n\nexport const sliderModule = defineModule({\n id: \"slider\",\n version: CORE_VERSION,\n label: \"Carrousel / slider\",\n description: \"Beeld-/contentcarrousel met dots, pijlen en optioneel autoplay (reduced-motion-veilig).\",\n defaultEnabled: false,\n blocks: [sliderBlock],\n});\n\n/* ── 4.16: nieuwe modules (allemaal opt-in) ──────────────────────────────── */\n\nexport const whatsappModule = defineModule({\n id: \"whatsapp\",\n version: CORE_VERSION,\n label: \"WhatsApp-knop\",\n description: \"Zwevende WhatsApp-/chatknop — laagdrempelig contact (wa.me-link, geen consent nodig).\",\n defaultEnabled: false,\n blocks: [whatsappChatBlock],\n});\n\nexport const beforeAfterModule = defineModule({\n id: \"beforeAfter\",\n version: CORE_VERSION,\n label: \"Voor / na\",\n description: \"Voor/na-vergelijker met sleepbare scheiding — sterk voor hoveniers, schilders, salons.\",\n defaultEnabled: false,\n blocks: [beforeAfterBlock],\n});\n\nexport const portfolioModule = defineModule({\n id: \"portfolio\",\n version: CORE_VERSION,\n label: \"Portfolio / projecten\",\n description: \"Projecten/cases-grid met categorie-filter en lightbox.\",\n defaultEnabled: false,\n blocks: [portfolioBlock],\n});\n\nexport const jobsModule = defineModule({\n id: \"jobs\",\n version: CORE_VERSION,\n label: \"Vacatures\",\n description: \"Vacature-overzicht met JobPosting-JSON-LD (vindbaar via Google Jobs).\",\n defaultEnabled: false,\n blocks: [jobsBlock],\n});\n\nexport const breadcrumbsModule = defineModule({\n id: \"breadcrumbs\",\n version: CORE_VERSION,\n label: \"Kruimelpad\",\n description: \"Kruimelpad afgeleid van de URL, met BreadcrumbList-JSON-LD (SEO).\",\n defaultEnabled: false,\n blocks: [breadcrumbsBlock],\n});\n\n/* ── 5.5: webwinkel + donaties ───────────────────────────────────────────────\n * 6.0: de shop-module zit NIET meer in de default-bundel. Hij is opt-in via de\n * subpath `@xiwebdesign/xicms-core/modules/shop` (+ `/admin/shop`, `/server/shop`),\n * of via de backward-compat-barrel `@xiwebdesign/xicms-core/all`. Zo landt shop-code\n * alleen in de build van sites die 'm daadwerkelijk aanzetten. */\n\nexport const consentModule = defineModule({\n id: \"consent\",\n version: CORE_VERSION,\n label: \"Cookie-consent (AVG)\",\n description: \"Toestemmingsbanner + consent-opslag; stelt niet-essentiële scripts uit.\",\n defaultEnabled: false,\n settingsSchema: z.object({\n message: z._default(z.string(), \"We gebruiken cookies om de site te verbeteren. Kies hieronder je voorkeuren.\").register(z.globalRegistry, { description: \"Bannertekst\" }),\n privacyUrl: z.optional(z.string()).register(z.globalRegistry, { description: \"Link naar privacyverklaring\" }),\n version: z.optional(z.string()).register(z.globalRegistry, { description: \"Beleidsversie (wijzig → banner opnieuw tonen)\" }),\n showReopen: z._default(z.boolean(), true).register(z.globalRegistry, { description: \"Zwevend cookie-knopje om keuze te wijzigen\" }),\n categories: z._default(z.array(z.object({\n id: z.string(),\n label: z.string(),\n description: z.optional(z.string()),\n required: z._default(z.boolean(), false),\n })), [\n { id: \"necessary\", label: \"Noodzakelijk\", description: \"Nodig om de site te laten werken.\", required: true },\n { id: \"analytics\", label: \"Statistieken\", description: \"Anonieme statistieken om de site te verbeteren.\", required: false },\n { id: \"marketing\", label: \"Marketing\", description: \"Externe embeds zoals video's en kaarten.\", required: false },\n ]),\n }),\n defaultSettings: {},\n});\n\n/** Alle ingebouwde modules (volgorde bepaalt block- en tab-volgorde). */\nexport const builtinModules: ModuleDefinition[] = [\n contentModule,\n pagesModule,\n newsModule,\n mediaModule,\n galleryModule,\n faqModule,\n openingHoursModule,\n pricingModule,\n formsModule,\n statsModule,\n settingsModule,\n testimonialsModule,\n teamModule,\n agendaModule,\n searchModule,\n featureModule,\n countersModule,\n logosModule,\n timelineModule,\n videoModule,\n bannerModule,\n contactModule,\n newsletterModule,\n bookingModule,\n accordionModule,\n embedModule,\n cardsModule,\n tabsModule,\n downloadsModule,\n pdfModule,\n countdownModule,\n sliderModule,\n whatsappModule,\n beforeAfterModule,\n portfolioModule,\n jobsModule,\n breadcrumbsModule,\n consentModule,\n];\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/modules/builtins.ts"],"sourcesContent":["/**\n * Ingebouwde modules (XiCMS 3.0). Elke \"feature\" van 2.x is hier een first-class module geworden,\n * zodat hij per site aan/uit kan en los te verbeteren is. De bijbehorende admin-panelen staan in\n * `@xiwebdesign/xicms-core/admin` (paneel-registry), gekoppeld via dezelfde `id`/`featureKey`.\n *\n * Backward compatible: zonder `SiteConfig.modules`/`features` zijn alle modules actief — identiek\n * aan 2.x. De `content`-module is `core: true` en kan niet uitgezet worden (de basis-bouwstenen).\n */\nimport * as z from \"zod/mini\";\nimport { defineModule } from \"./defineModule\";\nimport type { ModuleDefinition } from \"./types\";\n\nimport { heroBlock } from \"../blocks/builtins/Hero\";\nimport { richTextBlock } from \"../blocks/builtins/RichTextBlock\";\nimport { imageBlock } from \"../blocks/builtins/ImageBlock\";\nimport { ctaBlock } from \"../blocks/builtins/Cta\";\nimport { columnsBlock } from \"../blocks/builtins/Columns\";\nimport { spacerBlock } from \"../blocks/builtins/Spacer\";\nimport { galleryBlock } from \"../blocks/builtins/Gallery\";\nimport { faqBlock } from \"../blocks/builtins/Faq\";\nimport { openingHoursBlock } from \"../blocks/builtins/OpeningHours\";\nimport { pricingBlock } from \"../blocks/builtins/Pricing\";\nimport { priceListBlock } from \"../blocks/builtins/PriceList\";\nimport { sectionHeadingBlock } from \"../blocks/builtins/SectionHeading\";\nimport { availabilityBlock } from \"../blocks/builtins/Availability\";\nimport { newsListBlock } from \"../blocks/builtins/NewsListBlock\";\nimport { formBlock } from \"../blocks/builtins/FormBlock\";\nimport { testimonialsBlock } from \"../blocks/builtins/Testimonials\";\nimport { teamBlock } from \"../blocks/builtins/Team\";\nimport { agendaBlock } from \"../blocks/builtins/Agenda\";\nimport { searchBlock } from \"../blocks/builtins/Search\";\nimport { featureBlock, countersBlock, logosBlock, timelineBlock } from \"../blocks/builtins/Sections\";\nimport { symbolRefBlock } from \"../blocks/builtins/SymbolRef\";\nimport { videoBlock } from \"../blocks/builtins/Video\";\nimport { bannerBlock } from \"../blocks/builtins/Banner\";\nimport { contactBlock, socialBlock } from \"../blocks/builtins/Contact\";\nimport { mapBlock } from \"../blocks/builtins/MapBlock\";\nimport { newsletterBlock } from \"../blocks/builtins/Newsletter\";\nimport { bookingBlock } from \"../blocks/builtins/Booking\";\nimport { buttonsBlock, quoteBlock, dividerBlock } from \"../blocks/builtins/Elements\";\nimport { accordionBlock } from \"../blocks/builtins/Accordion\";\nimport { embedBlock } from \"../blocks/builtins/Embed\";\nimport { withSidebarBlock, tabsBlock } from \"../blocks/builtins/Layout\";\nimport { cardsBlock } from \"../blocks/builtins/Cards\";\nimport { downloadsBlock } from \"../blocks/builtins/Downloads\";\nimport { pdfBlock } from \"../blocks/builtins/PdfBlock\";\nimport { countdownBlock } from \"../blocks/builtins/Countdown\";\nimport { sliderBlock } from \"../blocks/builtins/Slider\";\nimport { whatsappChatBlock } from \"../blocks/builtins/WhatsappChat\";\nimport { beforeAfterBlock } from \"../blocks/builtins/BeforeAfter\";\nimport { portfolioBlock } from \"../blocks/builtins/Portfolio\";\nimport { jobsBlock } from \"../blocks/builtins/Jobs\";\nimport { breadcrumbsBlock } from \"../blocks/builtins/Breadcrumbs\";\nimport {\n newsWidget,\n agendaWidget,\n openingHoursWidget,\n contactWidget,\n socialWidget as socialWidgetBlock,\n newsletterWidget,\n ctaWidget,\n galleryWidget,\n testimonialsWidget,\n cardsWidget,\n downloadsWidget,\n countdownWidget,\n} from \"../blocks/builtins/Widgets\";\n\nconst CORE_VERSION = \"5.0.0\";\n\n/**\n * Basis-bouwstenen — altijd aanwezig (niet uit te zetten). Bevat ook de indelingsblokken\n * (kolommen, \"Met zijbalk\") waarmee je widgets naast je hoofdinhoud plaatst, plus de\n * compacte CTA-widget.\n */\nexport const contentModule = defineModule({\n id: \"content\",\n version: CORE_VERSION,\n label: \"Basisinhoud\",\n description: \"Kern-bouwstenen: hero, tekst, afbeelding, CTA, kolommen, zijbalk, witruimte.\",\n core: true,\n blocks: [heroBlock, sectionHeadingBlock, richTextBlock, imageBlock, ctaBlock, columnsBlock, withSidebarBlock, spacerBlock, buttonsBlock, quoteBlock, dividerBlock, ctaWidget, symbolRefBlock],\n});\n\nexport const galleryModule = defineModule({\n id: \"gallery\",\n version: CORE_VERSION,\n label: \"Fotogalerij\",\n description: \"Galerij-block met grid en (optioneel) lightbox + compacte fotostrip-widget.\",\n blocks: [galleryBlock, galleryWidget],\n // Per-site instelbaar door de agent/klant (modules.gallery.config) zonder core te forken.\n // `.describe()` = het label dat de klant in /beheer ziet.\n settingsSchema: z.object({\n columns: z._default(z.int().check(z.minimum(1)).check(z.maximum(6)), 3).register(z.globalRegistry, { description: \"Kolommen\" }),\n lightbox: z._default(z.boolean(), true).register(z.globalRegistry, { description: \"Lightbox bij klikken\" }),\n }),\n defaultSettings: { columns: 3, lightbox: true },\n});\n\nexport const faqModule = defineModule({\n id: \"faq\",\n version: CORE_VERSION,\n label: \"FAQ\",\n description: \"Veelgestelde vragen (accordeon) met optionele zoek + FAQ-JSON-LD.\",\n blocks: [faqBlock],\n});\n\nexport const openingHoursModule = defineModule({\n id: \"openingHours\",\n version: CORE_VERSION,\n label: \"Openingstijden\",\n description: \"Openingstijden-tabel + compacte widget met 'vandaag' gemarkeerd.\",\n blocks: [openingHoursBlock, openingHoursWidget],\n});\n\nexport const pricingModule = defineModule({\n id: \"pricing\",\n version: CORE_VERSION,\n label: \"Prijzen\",\n blocks: [pricingBlock, priceListBlock],\n});\n\nexport const pagesModule = defineModule({\n id: \"pages\",\n version: CORE_VERSION,\n label: \"Pagina's\",\n featureKey: \"pages\",\n description: \"Paginabouwer (draft → publish + versiegeschiedenis).\",\n});\n\nexport const newsModule = defineModule({\n id: \"news\",\n version: CORE_VERSION,\n label: \"Nieuws\",\n featureKey: \"news\",\n description: \"Nieuwsartikelen + nieuwslijst-block + 'laatste nieuws'-widget voor de zijbalk.\",\n blocks: [newsListBlock, newsWidget],\n});\n\nexport const mediaModule = defineModule({\n id: \"media\",\n version: CORE_VERSION,\n label: \"Media\",\n featureKey: \"media\",\n description: \"Mediabeheer met compressie + webp/srcset-varianten.\",\n requires: [{ kind: \"function\", name: \"onMediaUpload\" }, { kind: \"storage\", prefix: \"sites/\" }],\n});\n\nexport const formsModule = defineModule({\n id: \"forms\",\n version: CORE_VERSION,\n label: \"Formulieren\",\n featureKey: \"forms\",\n description: \"Formulierbouwer + inzendingen + e-mailnotificatie.\",\n blocks: [formBlock],\n requires: [\n { kind: \"function\", name: \"submitForm\" },\n { kind: \"firestore\", collection: \"forms\" },\n ],\n});\n\nexport const statsModule = defineModule({\n id: \"stats\",\n version: CORE_VERSION,\n label: \"Statistieken\",\n featureKey: \"stats\",\n description: \"Privacy-vriendelijke bezoekersstatistieken (geen cookies).\",\n requires: [{ kind: \"function\", name: \"trackView\" }],\n});\n\nexport const settingsModule = defineModule({\n id: \"settings\",\n version: CORE_VERSION,\n label: \"Instellingen\",\n core: true,\n description: \"Site-instellingen (nav, thema, SEO, formulier-afzender) — alleen siteadmin.\",\n});\n\n// Opt-in modules (defaultEnabled: false): worden bij installatie of later aangezet via\n// `modules: { <id>: true }`. Geen extra backend nodig — data leeft in de page-blocks.\nexport const testimonialsModule = defineModule({\n id: \"testimonials\",\n version: CORE_VERSION,\n label: \"Reviews\",\n description: \"Klantquotes/reviews met sterren, optionele Review-JSON-LD + compacte review-widget.\",\n defaultEnabled: false,\n blocks: [testimonialsBlock, testimonialsWidget],\n});\n\nexport const teamModule = defineModule({\n id: \"team\",\n version: CORE_VERSION,\n label: \"Team\",\n description: \"Team-/medewerkersoverzicht met foto, functie en bio.\",\n defaultEnabled: false,\n blocks: [teamBlock],\n});\n\nexport const agendaModule = defineModule({\n id: \"agenda\",\n version: CORE_VERSION,\n label: \"Agenda\",\n description: \"Evenementen/agenda (chronologisch) met Event-JSON-LD + 'komende agenda'-widget.\",\n defaultEnabled: false,\n blocks: [agendaBlock, agendaWidget],\n});\n\nexport const searchModule = defineModule({\n id: \"search\",\n version: CORE_VERSION,\n label: \"Zoeken\",\n description: \"Site-zoekblok dat gepubliceerde pagina's (en nieuws) client-side doorzoekt.\",\n defaultEnabled: false,\n blocks: [searchBlock],\n});\n\nexport const featureModule = defineModule({\n id: \"feature\",\n version: CORE_VERSION,\n label: \"Beeld + tekst\",\n description: \"Feature-sectie met afbeelding links/rechts en tekst.\",\n defaultEnabled: false,\n blocks: [featureBlock],\n});\n\nexport const countersModule = defineModule({\n id: \"counters\",\n version: CORE_VERSION,\n label: \"Tellers\",\n description: \"Statistiek-tellers (bv. “100+ klanten”).\",\n defaultEnabled: false,\n blocks: [countersBlock],\n});\n\nexport const logosModule = defineModule({\n id: \"logos\",\n version: CORE_VERSION,\n label: \"Logo's\",\n description: \"Partner-/klantlogo-strip.\",\n defaultEnabled: false,\n blocks: [logosBlock],\n});\n\nexport const timelineModule = defineModule({\n id: \"timeline\",\n version: CORE_VERSION,\n label: \"Tijdlijn\",\n description: \"Stappen/proces als tijdlijn.\",\n defaultEnabled: false,\n blocks: [timelineBlock],\n});\n\nexport const videoModule = defineModule({\n id: \"video\",\n version: CORE_VERSION,\n label: \"Video\",\n description: \"YouTube/Vimeo/MP4-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [videoBlock],\n});\n\nexport const bannerModule = defineModule({\n id: \"banner\",\n version: CORE_VERSION,\n label: \"Aankondiging\",\n description: \"Aankondigingsbalk, optioneel sluitbaar.\",\n defaultEnabled: false,\n blocks: [bannerBlock],\n});\n\nexport const contactModule = defineModule({\n id: \"contact\",\n version: CORE_VERSION,\n label: \"Contact + kaart + social\",\n description: \"Contactgegevens (JSON-LD), kaart (consent-gated), social-links + compacte widgets.\",\n defaultEnabled: false,\n blocks: [contactBlock, mapBlock, socialBlock, contactWidget, socialWidgetBlock],\n});\n\nexport const newsletterModule = defineModule({\n id: \"newsletter\",\n version: CORE_VERSION,\n label: \"Nieuwsbrief\",\n description: \"Aanmeldformulier via een externe provider-URL + compacte nieuwsbrief-widget.\",\n defaultEnabled: false,\n blocks: [newsletterBlock, newsletterWidget],\n});\n\nexport const verhuurModule = defineModule({\n id: \"verhuur\",\n version: CORE_VERSION,\n label: \"Verhuur & beschikbaarheid\",\n description: \"Beschikbaarheidskalender uit de iCal-link van je boekingssysteem, met aanvragen voor een gekozen periode.\",\n defaultEnabled: false,\n blocks: [availabilityBlock],\n});\n\nexport const bookingModule = defineModule({\n id: \"booking\",\n version: CORE_VERSION,\n label: \"Afspraak maken\",\n description: \"Boekings-embed (bv. Calendly), consent-gated.\",\n defaultEnabled: false,\n blocks: [bookingBlock],\n});\n\nexport const accordionModule = defineModule({\n id: \"accordion\",\n version: CORE_VERSION,\n label: \"Accordeon\",\n description: \"Generieke in-/uitklapbare panelen.\",\n defaultEnabled: false,\n blocks: [accordionBlock],\n});\n\nexport const embedModule = defineModule({\n id: \"embed\",\n version: CORE_VERSION,\n label: \"Embed\",\n description: \"Generieke responsive iframe-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [embedBlock],\n});\n\n/* ── Nieuwe modules (3.1) — veelgebruikt op websites, volwaardig + widget waar zinvol ── */\n\nexport const cardsModule = defineModule({\n id: \"cards\",\n version: CORE_VERSION,\n label: \"Diensten / kaarten\",\n description: \"Diensten-/featurekaarten in een grid (icoon of beeld) + compacte 'uitgelicht'-widget.\",\n defaultEnabled: false,\n blocks: [cardsBlock, cardsWidget],\n});\n\nexport const tabsModule = defineModule({\n id: \"tabs\",\n version: CORE_VERSION,\n label: \"Tabbladen\",\n description: \"Tabblad-indeling: per tab een eigen set blokken (bv. beschrijving / specificaties).\",\n defaultEnabled: false,\n blocks: [tabsBlock],\n});\n\nexport const downloadsModule = defineModule({\n id: \"downloads\",\n version: CORE_VERSION,\n label: \"Downloads\",\n description: \"Lijst met downloadbare documenten (brochures, prijslijsten) + compacte widget.\",\n defaultEnabled: false,\n blocks: [downloadsBlock, downloadsWidget],\n});\n\nexport const pdfModule = defineModule({\n id: \"pdf\",\n version: CORE_VERSION,\n label: \"PDF-lezer\",\n description: \"Inline PDF-lezer voor menukaarten/documenten; meerdere PDF's met tabs, zelf te vervangen.\",\n defaultEnabled: false,\n blocks: [pdfBlock],\n});\n\nexport const countdownModule = defineModule({\n id: \"countdown\",\n version: CORE_VERSION,\n label: \"Aftelteller\",\n description: \"Tikkende countdown naar een datum (lancering, evenement, aanbieding) + widget.\",\n defaultEnabled: false,\n blocks: [countdownBlock, countdownWidget],\n});\n\nexport const sliderModule = defineModule({\n id: \"slider\",\n version: CORE_VERSION,\n label: \"Carrousel / slider\",\n description: \"Beeld-/contentcarrousel met dots, pijlen en optioneel autoplay (reduced-motion-veilig).\",\n defaultEnabled: false,\n blocks: [sliderBlock],\n});\n\n/* ── 4.16: nieuwe modules (allemaal opt-in) ──────────────────────────────── */\n\nexport const whatsappModule = defineModule({\n id: \"whatsapp\",\n version: CORE_VERSION,\n label: \"WhatsApp-knop\",\n description: \"Zwevende WhatsApp-/chatknop — laagdrempelig contact (wa.me-link, geen consent nodig).\",\n defaultEnabled: false,\n blocks: [whatsappChatBlock],\n});\n\nexport const beforeAfterModule = defineModule({\n id: \"beforeAfter\",\n version: CORE_VERSION,\n label: \"Voor / na\",\n description: \"Voor/na-vergelijker met sleepbare scheiding — sterk voor hoveniers, schilders, salons.\",\n defaultEnabled: false,\n blocks: [beforeAfterBlock],\n});\n\nexport const portfolioModule = defineModule({\n id: \"portfolio\",\n version: CORE_VERSION,\n label: \"Portfolio / projecten\",\n description: \"Projecten/cases-grid met categorie-filter en lightbox.\",\n defaultEnabled: false,\n blocks: [portfolioBlock],\n});\n\nexport const jobsModule = defineModule({\n id: \"jobs\",\n version: CORE_VERSION,\n label: \"Vacatures\",\n description: \"Vacature-overzicht met JobPosting-JSON-LD (vindbaar via Google Jobs).\",\n defaultEnabled: false,\n blocks: [jobsBlock],\n});\n\nexport const breadcrumbsModule = defineModule({\n id: \"breadcrumbs\",\n version: CORE_VERSION,\n label: \"Kruimelpad\",\n description: \"Kruimelpad afgeleid van de URL, met BreadcrumbList-JSON-LD (SEO).\",\n defaultEnabled: false,\n blocks: [breadcrumbsBlock],\n});\n\n/* ── 5.5: webwinkel + donaties ───────────────────────────────────────────────\n * 6.0: de shop-module zit NIET meer in de default-bundel. Hij is opt-in via de\n * subpath `@xiwebdesign/xicms-core/modules/shop` (+ `/admin/shop`, `/server/shop`),\n * of via de backward-compat-barrel `@xiwebdesign/xicms-core/all`. Zo landt shop-code\n * alleen in de build van sites die 'm daadwerkelijk aanzetten. */\n\nexport const consentModule = defineModule({\n id: \"consent\",\n version: CORE_VERSION,\n label: \"Cookie-consent (AVG)\",\n description: \"Toestemmingsbanner + consent-opslag; stelt niet-essentiële scripts uit.\",\n defaultEnabled: false,\n settingsSchema: z.object({\n message: z._default(z.string(), \"We gebruiken cookies om de site te verbeteren. Kies hieronder je voorkeuren.\").register(z.globalRegistry, { description: \"Bannertekst\" }),\n privacyUrl: z.optional(z.string()).register(z.globalRegistry, { description: \"Link naar privacyverklaring\" }),\n version: z.optional(z.string()).register(z.globalRegistry, { description: \"Beleidsversie (wijzig → banner opnieuw tonen)\" }),\n showReopen: z._default(z.boolean(), true).register(z.globalRegistry, { description: \"Zwevend cookie-knopje om keuze te wijzigen\" }),\n categories: z._default(z.array(z.object({\n id: z.string(),\n label: z.string(),\n description: z.optional(z.string()),\n required: z._default(z.boolean(), false),\n })), [\n { id: \"necessary\", label: \"Noodzakelijk\", description: \"Nodig om de site te laten werken.\", required: true },\n { id: \"analytics\", label: \"Statistieken\", description: \"Anonieme statistieken om de site te verbeteren.\", required: false },\n { id: \"marketing\", label: \"Marketing\", description: \"Externe embeds zoals video's en kaarten.\", required: false },\n ]),\n }),\n defaultSettings: {},\n});\n\n/** Alle ingebouwde modules (volgorde bepaalt block- en tab-volgorde). */\nexport const builtinModules: ModuleDefinition[] = [\n contentModule,\n pagesModule,\n newsModule,\n mediaModule,\n galleryModule,\n faqModule,\n openingHoursModule,\n pricingModule,\n formsModule,\n statsModule,\n settingsModule,\n testimonialsModule,\n teamModule,\n agendaModule,\n searchModule,\n featureModule,\n countersModule,\n logosModule,\n timelineModule,\n videoModule,\n bannerModule,\n contactModule,\n newsletterModule,\n bookingModule,\n verhuurModule,\n accordionModule,\n embedModule,\n cardsModule,\n tabsModule,\n downloadsModule,\n pdfModule,\n countdownModule,\n sliderModule,\n whatsappModule,\n beforeAfterModule,\n portfolioModule,\n jobsModule,\n breadcrumbsModule,\n consentModule,\n];\n"],"mappings":"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","names":[]}
@@ -6,7 +6,8 @@ import { Card, Heading, Text } from "../../../blocks/ui/index.js";
6
6
  import { cartLineKey, cartRemove, cartSetQty, useCart } from "../cartStore.js";
7
7
  import { AantalInvoer } from "./AantalInvoer.js";
8
8
  import { useShopStrings } from "../strings.js";
9
- import { useShopSettings } from "../lib.js";
9
+ import { useShopSettings, productHref } from "../lib.js";
10
+ import { SeedImg } from "../../../media/ImageContext.js";
10
11
  function CartRender({ block, siteId }) {
11
12
  const settings = useShopSettings();
12
13
  const t = useShopStrings();
@@ -29,9 +30,9 @@ function CartRender({ block, siteId }) {
29
30
  /* @__PURE__ */ jsx("a", { href: settings.shopPath, children: t("toShop") })
30
31
  ] }) }) : /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "1rem", marginTop: "1rem" }, children: [
31
32
  lines.map((l) => /* @__PURE__ */ jsx(Card, { padding: 3, children: /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "1rem", alignItems: "center", flexWrap: "wrap" }, children: [
32
- l.imageUrl && /* @__PURE__ */ jsx("img", { src: l.imageUrl, alt: "", style: { width: 72, height: 72, objectFit: "cover", borderRadius: 8 } }),
33
+ l.imageUrl && /* @__PURE__ */ jsx(SeedImg, { src: l.imageUrl, alt: "", sizes: "72px", style: { width: 72, height: 72, objectFit: "cover", borderRadius: 8 } }),
33
34
  /* @__PURE__ */ jsxs("div", { style: { flex: "1 1 200px" }, children: [
34
- /* @__PURE__ */ jsx("a", { href: `${settings.detailPath}?p=${encodeURIComponent(l.slug)}`, style: { textDecoration: "none", color: "inherit" }, children: /* @__PURE__ */ jsx(Text, { weight: "bold", display: "block", children: l.name }) }),
35
+ /* @__PURE__ */ jsx("a", { href: productHref(settings.detailPath, l.slug, settings.mooieUrls), style: { textDecoration: "none", color: "inherit" }, children: /* @__PURE__ */ jsx(Text, { weight: "bold", display: "block", children: l.name }) }),
35
36
  l.variantLabel && /* @__PURE__ */ jsx(Text, { size: "sm", display: "block", style: { opacity: 0.75 }, children: l.variantLabel }),
36
37
  l.personalizationLabel && /* @__PURE__ */ jsx(Text, { size: "sm", display: "block", style: { opacity: 0.75 }, children: l.personalizationLabel }),
37
38
  /* @__PURE__ */ jsxs(Text, { size: "sm", display: "block", style: { marginTop: 2 }, children: [
@@ -95,6 +96,7 @@ const cartBlock = defineBlock({
95
96
  Render: CartRender,
96
97
  label: "Winkelwagen",
97
98
  icon: "\u{1F6D2}",
99
+ essentieel: "Zonder dit blok kunnen klanten hun winkelwagen niet zien en niet afrekenen.",
98
100
  defaults: () => ({ heading: "Winkelwagen" })
99
101
  });
100
102
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/shop/blocks/Cart.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport { formatCents, shippingCentsFor } from \"../../../schema/shopGeld\";\nimport type { CartBlockSchema } from \"../../../schema/shop\";\nimport { defineBlock, type BlockRenderProps } from \"../../../blocks/registry\";\nimport { Card, Heading, Text } from \"../../../blocks/ui\";\nimport { cartLineKey, cartRemove, cartSetQty, useCart } from \"../cartStore\";\nimport { AantalInvoer } from \"./AantalInvoer\";\nimport { useShopStrings } from \"../strings\";\nimport { useShopSettings } from \"../lib\";\n\ntype Blk = z.infer<typeof CartBlockSchema>;\n\nfunction CartRender({ block, siteId }: BlockRenderProps<Blk>) {\n const settings = useShopSettings();\n const t = useShopStrings();\n const { lines, itemsCents } = useCart(siteId);\n /**\n * Verzendkosten in de winkelwagen zijn een RICHTBEDRAG voor het standaardland: de klant kiest\n * zijn land (en een eventuele kortingscode) pas bij het afrekenen. Met zones staat dat er nu\n * ook bij, zodat \"€ 7,25\" niet als een belofte leest voor een Belgische bezoeker.\n */\n const shippingCents = shippingCentsFor(\n itemsCents,\n {\n shippingFlatCents: settings.shippingFlatCents,\n shippingFreeFromCents: settings.shippingFreeFromCents || undefined,\n shippingZones: settings.shippingZones,\n },\n lines.length > 0,\n );\n const meerdereZones = (settings.shippingZones ?? []).length > 1;\n\n return (\n <div className=\"xicms-shop-cart\">\n {block.heading && <Heading level={1} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n\n {lines.length === 0 ? (\n <Card padding={4} variant=\"muted\" style={{ marginTop: \"1rem\" }}>\n <Text>\n {t(\"cartEmpty\")} <a href={settings.shopPath}>{t(\"toShop\")}</a>\n </Text>\n </Card>\n ) : (\n <div style={{ display: \"grid\", gap: \"1rem\", marginTop: \"1rem\" }}>\n {lines.map((l) => (\n <Card key={cartLineKey(l)} padding={3}>\n <div style={{ display: \"flex\", gap: \"1rem\", alignItems: \"center\", flexWrap: \"wrap\" }}>\n {l.imageUrl && (\n <img src={l.imageUrl} alt=\"\" style={{ width: 72, height: 72, objectFit: \"cover\", borderRadius: 8 }} />\n )}\n <div style={{ flex: \"1 1 200px\" }}>\n <a href={`${settings.detailPath}?p=${encodeURIComponent(l.slug)}`} style={{ textDecoration: \"none\", color: \"inherit\" }}>\n <Text weight=\"bold\" display=\"block\">{l.name}</Text>\n </a>\n {l.variantLabel && <Text size=\"sm\" display=\"block\" style={{ opacity: 0.75 }}>{l.variantLabel}</Text>}\n {l.personalizationLabel && (\n <Text size=\"sm\" display=\"block\" style={{ opacity: 0.75 }}>{l.personalizationLabel}</Text>\n )}\n <Text size=\"sm\" display=\"block\" style={{ marginTop: 2 }}>\n {formatCents(l.unitPriceCents, settings.currency)} {t(\"perPiece\")}\n </Text>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n {/* min 1: een leeg veld mag nooit de regel uit de wagen gooien — weghalen doe\n je met het kruisje hiernaast. */}\n <AantalInvoer\n value={l.qty}\n onChange={(n) => cartSetQty(siteId, l, n)}\n min={1}\n max={999}\n ariaLabel={`${t(\"qty\")} ${l.name}`}\n style={{ width: 72 }}\n />\n <Text weight=\"bold\" style={{ minWidth: 80, textAlign: \"right\" }}>\n {formatCents(l.unitPriceCents * l.qty, settings.currency)}\n </Text>\n <button\n type=\"button\"\n aria-label={`Verwijder ${l.name}`}\n onClick={() => cartRemove(siteId, l)}\n style={{ background: \"none\", border: \"none\", cursor: \"pointer\", fontSize: \"1.1rem\", opacity: 0.6 }}\n >\n ✕\n </button>\n </div>\n </div>\n </Card>\n ))}\n\n <Card padding={3} variant=\"muted\">\n <div style={{ display: \"grid\", gap: 4, justifyContent: \"end\", textAlign: \"right\" }}>\n <Text size=\"sm\">{t(\"subtotal\")}: {formatCents(itemsCents, settings.currency)}</Text>\n <Text size=\"sm\">\n {t(\"shippingCosts\")}: {shippingCents === 0 ? t(\"free\") : formatCents(shippingCents, settings.currency)}\n {meerdereZones ? ` ${t(\"shippingFromCountry\")}` : \"\"}\n </Text>\n <Text weight=\"bold\">{t(\"total\")}: {formatCents(itemsCents + shippingCents, settings.currency)}</Text>\n </div>\n </Card>\n\n <div style={{ display: \"flex\", gap: 12, flexWrap: \"wrap\" }}>\n <a className=\"xicms-btn xicms-btn--primary\" href={settings.checkoutPath}>{t(\"checkout\")}</a>\n <a className=\"xicms-btn xicms-btn--secondary\" href={settings.shopPath}>{t(\"continueShopping\")}</a>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport const cartBlock = defineBlock({\n type: \"cart\",\n Render: CartRender,\n label: \"Winkelwagen\",\n icon: \"🛒\",\n defaults: () => ({ heading: \"Winkelwagen\" }),\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/shop/blocks/Cart.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport { formatCents, shippingCentsFor } from \"../../../schema/shopGeld\";\nimport type { CartBlockSchema } from \"../../../schema/shop\";\nimport { defineBlock, type BlockRenderProps } from \"../../../blocks/registry\";\nimport { Card, Heading, Text } from \"../../../blocks/ui\";\nimport { cartLineKey, cartRemove, cartSetQty, useCart } from \"../cartStore\";\nimport { AantalInvoer } from \"./AantalInvoer\";\nimport { useShopStrings } from \"../strings\";\nimport { useShopSettings, productHref } from \"../lib\";\nimport { SeedImg } from \"../../../media/ImageContext\";\n\ntype Blk = z.infer<typeof CartBlockSchema>;\n\nfunction CartRender({ block, siteId }: BlockRenderProps<Blk>) {\n const settings = useShopSettings();\n const t = useShopStrings();\n const { lines, itemsCents } = useCart(siteId);\n /**\n * Verzendkosten in de winkelwagen zijn een RICHTBEDRAG voor het standaardland: de klant kiest\n * zijn land (en een eventuele kortingscode) pas bij het afrekenen. Met zones staat dat er nu\n * ook bij, zodat \"€ 7,25\" niet als een belofte leest voor een Belgische bezoeker.\n */\n const shippingCents = shippingCentsFor(\n itemsCents,\n {\n shippingFlatCents: settings.shippingFlatCents,\n shippingFreeFromCents: settings.shippingFreeFromCents || undefined,\n shippingZones: settings.shippingZones,\n },\n lines.length > 0,\n );\n const meerdereZones = (settings.shippingZones ?? []).length > 1;\n\n return (\n <div className=\"xicms-shop-cart\">\n {block.heading && <Heading level={1} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n\n {lines.length === 0 ? (\n <Card padding={4} variant=\"muted\" style={{ marginTop: \"1rem\" }}>\n <Text>\n {t(\"cartEmpty\")} <a href={settings.shopPath}>{t(\"toShop\")}</a>\n </Text>\n </Card>\n ) : (\n <div style={{ display: \"grid\", gap: \"1rem\", marginTop: \"1rem\" }}>\n {lines.map((l) => (\n <Card key={cartLineKey(l)} padding={3}>\n <div style={{ display: \"flex\", gap: \"1rem\", alignItems: \"center\", flexWrap: \"wrap\" }}>\n {l.imageUrl && (\n <SeedImg src={l.imageUrl} alt=\"\" sizes=\"72px\" style={{ width: 72, height: 72, objectFit: \"cover\", borderRadius: 8 }} />\n )}\n <div style={{ flex: \"1 1 200px\" }}>\n <a href={productHref(settings.detailPath, l.slug, settings.mooieUrls)} style={{ textDecoration: \"none\", color: \"inherit\" }}>\n <Text weight=\"bold\" display=\"block\">{l.name}</Text>\n </a>\n {l.variantLabel && <Text size=\"sm\" display=\"block\" style={{ opacity: 0.75 }}>{l.variantLabel}</Text>}\n {l.personalizationLabel && (\n <Text size=\"sm\" display=\"block\" style={{ opacity: 0.75 }}>{l.personalizationLabel}</Text>\n )}\n <Text size=\"sm\" display=\"block\" style={{ marginTop: 2 }}>\n {formatCents(l.unitPriceCents, settings.currency)} {t(\"perPiece\")}\n </Text>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n {/* min 1: een leeg veld mag nooit de regel uit de wagen gooien — weghalen doe\n je met het kruisje hiernaast. */}\n <AantalInvoer\n value={l.qty}\n onChange={(n) => cartSetQty(siteId, l, n)}\n min={1}\n max={999}\n ariaLabel={`${t(\"qty\")} ${l.name}`}\n style={{ width: 72 }}\n />\n <Text weight=\"bold\" style={{ minWidth: 80, textAlign: \"right\" }}>\n {formatCents(l.unitPriceCents * l.qty, settings.currency)}\n </Text>\n <button\n type=\"button\"\n aria-label={`Verwijder ${l.name}`}\n onClick={() => cartRemove(siteId, l)}\n style={{ background: \"none\", border: \"none\", cursor: \"pointer\", fontSize: \"1.1rem\", opacity: 0.6 }}\n >\n ✕\n </button>\n </div>\n </div>\n </Card>\n ))}\n\n <Card padding={3} variant=\"muted\">\n <div style={{ display: \"grid\", gap: 4, justifyContent: \"end\", textAlign: \"right\" }}>\n <Text size=\"sm\">{t(\"subtotal\")}: {formatCents(itemsCents, settings.currency)}</Text>\n <Text size=\"sm\">\n {t(\"shippingCosts\")}: {shippingCents === 0 ? t(\"free\") : formatCents(shippingCents, settings.currency)}\n {meerdereZones ? ` ${t(\"shippingFromCountry\")}` : \"\"}\n </Text>\n <Text weight=\"bold\">{t(\"total\")}: {formatCents(itemsCents + shippingCents, settings.currency)}</Text>\n </div>\n </Card>\n\n <div style={{ display: \"flex\", gap: 12, flexWrap: \"wrap\" }}>\n <a className=\"xicms-btn xicms-btn--primary\" href={settings.checkoutPath}>{t(\"checkout\")}</a>\n <a className=\"xicms-btn xicms-btn--secondary\" href={settings.shopPath}>{t(\"continueShopping\")}</a>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nexport const cartBlock = defineBlock({\n type: \"cart\",\n Render: CartRender,\n label: \"Winkelwagen\",\n icon: \"🛒\",\n essentieel: \"Zonder dit blok kunnen klanten hun winkelwagen niet zien en niet afrekenen.\",\n defaults: () => ({ heading: \"Winkelwagen\" }),\n});\n"],"mappings":"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","names":[]}
@@ -22,6 +22,8 @@ function CheckoutRender({ block, siteId, mode }) {
22
22
  const [giftWrap, setGiftWrap] = useState(false);
23
23
  const [giftCardText, setGiftCardText] = useState("");
24
24
  const [giftNote, setGiftNote] = useState("");
25
+ const [pickupChoice, setPickupChoice] = useState(false);
26
+ const pickup = settings.pickupEnabled && pickupChoice;
25
27
  const landOpties = useMemo(() => {
26
28
  const uit = verzendLanden({ shippingZones: settings.shippingZones });
27
29
  return uit.length > 0 ? uit : ["NL"];
@@ -39,7 +41,7 @@ function CheckoutRender({ block, siteId, mode }) {
39
41
  shippingZones: settings.shippingZones
40
42
  },
41
43
  lines.length > 0,
42
- { land: v.country, freeShipping: discount?.valid && discount.freeShipping }
44
+ { land: v.country, freeShipping: discount?.valid && discount.freeShipping, pickup }
43
45
  );
44
46
  const discountCents = discount?.valid ? Math.min(discount.discountCents ?? 0, itemsCents) : 0;
45
47
  const giftWrapCents = giftWrap ? settings.giftWrapPriceCents : 0;
@@ -72,8 +74,9 @@ function CheckoutRender({ block, siteId, mode }) {
72
74
  personalization: l.personalization
73
75
  })),
74
76
  customer: { email: v.email, name: v.name, phone: v.phone || void 0 },
75
- shipping: { address: v.address, zip: v.zip, city: v.city, country: v.country || "NL" },
76
- billing: billingDiffers ? { address: billing.address, zip: billing.zip, city: billing.city, country: billing.country || "NL" } : void 0,
77
+ shipping: pickup ? void 0 : { address: v.address, zip: v.zip, city: v.city, country: v.country || "NL" },
78
+ pickup: pickup || void 0,
79
+ billing: billingDiffers && !pickup ? { address: billing.address, zip: billing.zip, city: billing.city, country: billing.country || "NL" } : void 0,
77
80
  note: v.note || void 0,
78
81
  giftWrap: giftWrap ? { cardText: giftCardText.trim() || void 0, note: giftNote.trim() || void 0 } : void 0,
79
82
  discountCode: discount?.valid ? discount.code : void 0,
@@ -99,43 +102,60 @@ function CheckoutRender({ block, siteId, mode }) {
99
102
  /* @__PURE__ */ jsxs("form", { onSubmit: submit, style: { display: "grid", gap: "0.9rem", alignContent: "start" }, children: [
100
103
  block.heading && /* @__PURE__ */ jsx(Heading, { level: 1, "data-xicms-edit": "heading", children: block.heading }),
101
104
  block.introText && /* @__PURE__ */ jsx(Text, { "data-xicms-edit": "introText", children: block.introText }),
102
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldName")} *`, value: v.name, onChange: (x) => setV((p) => ({ ...p, name: x })) }),
103
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldEmail")} *`, type: "email", value: v.email, onChange: (x) => setV((p) => ({ ...p, email: x })) }),
104
- /* @__PURE__ */ jsx(TextInput, { label: t("fieldPhone"), value: v.phone, onChange: (x) => setV((p) => ({ ...p, phone: x })) }),
105
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldAddress")} *`, value: v.address, onChange: (x) => setV((p) => ({ ...p, address: x })) }),
106
- /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.9rem", gridTemplateColumns: "140px 1fr" }, children: [
107
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldZip")} *`, value: v.zip, onChange: (x) => setV((p) => ({ ...p, zip: x })) }),
108
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldCity")} *`, value: v.city, onChange: (x) => setV((p) => ({ ...p, city: x })) })
105
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldName")} *`, autoComplete: "name", value: v.name, onChange: (x) => setV((p) => ({ ...p, name: x })) }),
106
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldEmail")} *`, type: "email", autoComplete: "email", value: v.email, onChange: (x) => setV((p) => ({ ...p, email: x })) }),
107
+ /* @__PURE__ */ jsx(TextInput, { label: t("fieldPhone"), autoComplete: "tel", value: v.phone, onChange: (x) => setV((p) => ({ ...p, phone: x })) }),
108
+ settings.pickupEnabled && /* @__PURE__ */ jsxs("div", { className: "xicms-shop-checkout__delivery", style: { display: "grid", gap: "0.5rem" }, children: [
109
+ /* @__PURE__ */ jsx(Heading, { level: 3, children: t("deliveryHeading") }),
110
+ /* @__PURE__ */ jsxs("label", { style: { display: "flex", gap: 8, alignItems: "center", cursor: "pointer" }, children: [
111
+ /* @__PURE__ */ jsx("input", { type: "radio", name: "xicms-delivery", checked: !pickup, onChange: () => setPickupChoice(false) }),
112
+ /* @__PURE__ */ jsx("span", { children: t("deliveryShip") })
113
+ ] }),
114
+ /* @__PURE__ */ jsxs("label", { style: { display: "flex", gap: 8, alignItems: "center", cursor: "pointer" }, children: [
115
+ /* @__PURE__ */ jsx("input", { type: "radio", name: "xicms-delivery", checked: pickup, onChange: () => setPickupChoice(true) }),
116
+ /* @__PURE__ */ jsx("span", { children: t("deliveryPickup") })
117
+ ] }),
118
+ pickup && settings.pickupNote.trim() && /* @__PURE__ */ jsxs(Card, { padding: 3, variant: "muted", children: [
119
+ /* @__PURE__ */ jsx(Text, { size: "sm", weight: "bold", children: t("pickupHeading") }),
120
+ /* @__PURE__ */ jsx(Text, { size: "sm", style: { whiteSpace: "pre-wrap" }, children: settings.pickupNote })
121
+ ] })
109
122
  ] }),
110
- /* @__PURE__ */ jsx("div", { children: landOpties.length > 1 && /* @__PURE__ */ jsxs("label", { style: { display: "grid", gap: 4 }, children: [
111
- /* @__PURE__ */ jsxs("span", { style: { fontSize: "0.9rem" }, children: [
112
- t("fieldCountry"),
113
- " *"
123
+ !pickup && /* @__PURE__ */ jsxs(Fragment, { children: [
124
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldAddress")} *`, autoComplete: "shipping street-address", value: v.address, onChange: (x) => setV((p) => ({ ...p, address: x })) }),
125
+ /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.9rem", gridTemplateColumns: "140px 1fr" }, children: [
126
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldZip")} *`, autoComplete: "shipping postal-code", value: v.zip, onChange: (x) => setV((p) => ({ ...p, zip: x })) }),
127
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldCity")} *`, autoComplete: "shipping address-level2", value: v.city, onChange: (x) => setV((p) => ({ ...p, city: x })) })
114
128
  ] }),
129
+ /* @__PURE__ */ jsx("div", { children: landOpties.length > 1 && /* @__PURE__ */ jsxs("label", { style: { display: "grid", gap: 4 }, children: [
130
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: "0.9rem" }, children: [
131
+ t("fieldCountry"),
132
+ " *"
133
+ ] }),
134
+ /* @__PURE__ */ jsx(
135
+ "select",
136
+ {
137
+ className: "xicms-input",
138
+ value: v.country,
139
+ onChange: (e) => setV((p) => ({ ...p, country: e.target.value })),
140
+ children: landOpties.map((c) => /* @__PURE__ */ jsx("option", { value: c, children: LANDNAMEN.of(c) ?? c }, c))
141
+ }
142
+ )
143
+ ] }) }),
115
144
  /* @__PURE__ */ jsx(
116
- "select",
145
+ CheckboxInput,
117
146
  {
118
- className: "xicms-input",
119
- value: v.country,
120
- onChange: (e) => setV((p) => ({ ...p, country: e.target.value })),
121
- children: landOpties.map((c) => /* @__PURE__ */ jsx("option", { value: c, children: LANDNAMEN.of(c) ?? c }, c))
147
+ label: t("billingSame"),
148
+ value: !billingDiffers,
149
+ onChange: (checked) => setBillingDiffers(!checked)
122
150
  }
123
- )
124
- ] }) }),
125
- /* @__PURE__ */ jsx(
126
- CheckboxInput,
127
- {
128
- label: t("billingSame"),
129
- value: !billingDiffers,
130
- onChange: (checked) => setBillingDiffers(!checked)
131
- }
132
- ),
133
- billingDiffers && /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.9rem" }, children: [
134
- /* @__PURE__ */ jsx(Heading, { level: 3, children: t("billingHeading") }),
135
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldAddress")} *`, value: billing.address, onChange: (x) => setBilling((p) => ({ ...p, address: x })) }),
136
- /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.9rem", gridTemplateColumns: "140px 1fr" }, children: [
137
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldZip")} *`, value: billing.zip, onChange: (x) => setBilling((p) => ({ ...p, zip: x })) }),
138
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldCity")} *`, value: billing.city, onChange: (x) => setBilling((p) => ({ ...p, city: x })) })
151
+ ),
152
+ billingDiffers && /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.9rem" }, children: [
153
+ /* @__PURE__ */ jsx(Heading, { level: 3, children: t("billingHeading") }),
154
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldAddress")} *`, autoComplete: "billing street-address", value: billing.address, onChange: (x) => setBilling((p) => ({ ...p, address: x })) }),
155
+ /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.9rem", gridTemplateColumns: "140px 1fr" }, children: [
156
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldZip")} *`, autoComplete: "billing postal-code", value: billing.zip, onChange: (x) => setBilling((p) => ({ ...p, zip: x })) }),
157
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldCity")} *`, autoComplete: "billing address-level2", value: billing.city, onChange: (x) => setBilling((p) => ({ ...p, city: x })) })
158
+ ] })
139
159
  ] })
140
160
  ] }),
141
161
  settings.giftWrapEnabled && /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.9rem" }, children: [
@@ -236,6 +256,7 @@ const checkoutBlock = defineBlock({
236
256
  Render: CheckoutRender,
237
257
  label: "Afrekenen",
238
258
  icon: "\u{1F4B3}",
259
+ essentieel: "Zonder dit blok kunnen klanten niet afrekenen \u2014 er komen dan geen bestellingen meer binnen.",
239
260
  defaults: () => ({ heading: "Afrekenen" })
240
261
  });
241
262
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/modules/shop/blocks/Checkout.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState, type FormEvent } from \"react\";\nimport type { z } from \"zod\";\nimport { formatCents, shippingCentsFor, verzendLanden } from \"../../../schema/shopGeld\";\nimport type { CheckoutBlockSchema } from \"../../../schema/shop\";\nimport { defineBlock, type BlockRenderProps } from \"../../../blocks/registry\";\nimport { Card, Heading, Text } from \"../../../blocks/ui\";\nimport { TextInput } from \"@astryxdesign/core/TextInput\";\nimport { TextArea } from \"@astryxdesign/core/TextArea\";\nimport { CheckboxInput } from \"@astryxdesign/core/CheckboxInput\";\nimport { cartLineKey, useCart } from \"../cartStore\";\nimport { useShopStrings } from \"../strings\";\nimport { createOrderCall, useShopSettings, validateDiscountCall, type DiscountPreview } from \"../lib\";\n\ntype Blk = z.infer<typeof CheckoutBlockSchema>;\n\n/**\n * Afrekenen — klantgegevens + overzicht + kortingscode; `createOrder` herrekent server-side\n * (incl. korting en personalisatie-meerprijs) en geeft de Stripe Checkout-URL terug. De cart\n * wordt pas geleegd op de bedankt-pagina, zodat een geannuleerde betaling niets kwijtraakt.\n * NB: verplichte velden dragen een \" *\" in het label (de Engelse Astryx-chip blijft uit).\n */\n/** Landnamen in het Nederlands (\"BE\" → \"België\"); valt terug op de code als de browser hem niet kent. */\nconst LANDNAMEN = new Intl.DisplayNames([\"nl\"], { type: \"region\" });\n\nfunction CheckoutRender({ block, siteId, mode }: BlockRenderProps<Blk>) {\n const settings = useShopSettings();\n const t = useShopStrings();\n const { lines, itemsCents } = useCart(siteId);\n const [v, setV] = useState({ name: \"\", email: \"\", phone: \"\", address: \"\", zip: \"\", city: \"\", country: \"NL\", note: \"\" });\n const [hp, setHp] = useState(\"\");\n // Factuuradres: standaard hetzelfde als het verzendadres — alleen tonen als de klant expliciet\n // aangeeft dat het afwijkt (bv. bedrijfsadres op de factuur, cadeau naar een ander adres).\n const [billingDiffers, setBillingDiffers] = useState(false);\n const [billing, setBilling] = useState({ address: \"\", zip: \"\", city: \"\", country: \"NL\" });\n // Cadeauverpakking (7.27): de meerprijs komt server-side uit de shopconfig, hier alleen de keuze\n // + wat er op het kaartje moet staan.\n const [giftWrap, setGiftWrap] = useState(false);\n const [giftCardText, setGiftCardText] = useState(\"\");\n const [giftNote, setGiftNote] = useState(\"\");\n // Welke landen bedient deze winkel? Leeg (of geen zones) = alleen het standaardland.\n const landOpties = useMemo(() => {\n const uit = verzendLanden({ shippingZones: settings.shippingZones });\n return uit.length > 0 ? uit : [\"NL\"];\n }, [settings.shippingZones]);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [codeInput, setCodeInput] = useState(\"\");\n const [codeBusy, setCodeBusy] = useState(false);\n const [discount, setDiscount] = useState<DiscountPreview | null>(null);\n\n // Eén rekenfunctie voor winkelwagen, afrekenen en server (zie shopGeld.ts): het land bepaalt de\n // zone, en een kortingscode met gratis verzending zit er nu ín in plaats van eromheen.\n const shippingCents = shippingCentsFor(\n itemsCents,\n {\n shippingFlatCents: settings.shippingFlatCents,\n shippingFreeFromCents: settings.shippingFreeFromCents || undefined,\n shippingZones: settings.shippingZones,\n },\n lines.length > 0,\n { land: v.country, freeShipping: discount?.valid && discount.freeShipping },\n );\n const discountCents = discount?.valid ? Math.min(discount.discountCents ?? 0, itemsCents) : 0;\n const giftWrapCents = giftWrap ? settings.giftWrapPriceCents : 0;\n const totalCents = Math.max(0, itemsCents - discountCents) + shippingCents + giftWrapCents;\n\n async function applyCode() {\n const code = codeInput.trim().toUpperCase();\n if (!code || codeBusy) return;\n setCodeBusy(true);\n try {\n const res = await validateDiscountCall(siteId, code, itemsCents);\n setDiscount(res.valid ? { ...res, code } : { valid: false });\n } catch {\n setDiscount({ valid: false });\n } finally {\n setCodeBusy(false);\n }\n }\n\n async function submit(e: FormEvent) {\n e.preventDefault();\n if (mode === \"preview\" || busy) return;\n setBusy(true);\n setError(null);\n try {\n const { url } = await createOrderCall({\n siteId,\n items: lines.map((l) => ({\n productId: l.productId,\n variantKey: l.variantKey,\n qty: l.qty,\n personalization: l.personalization,\n })),\n customer: { email: v.email, name: v.name, phone: v.phone || undefined },\n shipping: { address: v.address, zip: v.zip, city: v.city, country: v.country || \"NL\" },\n billing: billingDiffers\n ? { address: billing.address, zip: billing.zip, city: billing.city, country: billing.country || \"NL\" }\n : undefined,\n note: v.note || undefined,\n giftWrap: giftWrap ? { cardText: giftCardText.trim() || undefined, note: giftNote.trim() || undefined } : undefined,\n discountCode: discount?.valid ? discount.code : undefined,\n successPath: settings.successPath,\n cancelPath: settings.cartPath,\n _hp: hp || undefined,\n });\n window.location.assign(url);\n } catch (err) {\n console.error(\"[xicms] checkout mislukt:\", err);\n setError(t(\"checkoutFailed\"));\n setBusy(false);\n }\n }\n\n if (lines.length === 0) {\n return (\n <Card padding={4} variant=\"muted\">\n <Text>\n {t(\"cartEmpty\")} <a href={settings.shopPath}>{t(\"toShop\")}</a>\n </Text>\n </Card>\n );\n }\n\n return (\n <div className=\"xicms-shop-checkout\" style={{ display: \"grid\", gap: \"2rem\", gridTemplateColumns: \"repeat(auto-fit, minmax(min(320px, 100%), 1fr))\" }}>\n <form onSubmit={submit} style={{ display: \"grid\", gap: \"0.9rem\", alignContent: \"start\" }}>\n {block.heading && <Heading level={1} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n {block.introText && <Text data-xicms-edit=\"introText\">{block.introText}</Text>}\n\n <TextInput label={`${t(\"fieldName\")} *`} value={v.name} onChange={(x) => setV((p) => ({ ...p, name: x }))} />\n <TextInput label={`${t(\"fieldEmail\")} *`} type=\"email\" value={v.email} onChange={(x) => setV((p) => ({ ...p, email: x }))} />\n <TextInput label={t(\"fieldPhone\")} value={v.phone} onChange={(x) => setV((p) => ({ ...p, phone: x }))} />\n <TextInput label={`${t(\"fieldAddress\")} *`} value={v.address} onChange={(x) => setV((p) => ({ ...p, address: x }))} />\n <div style={{ display: \"grid\", gap: \"0.9rem\", gridTemplateColumns: \"140px 1fr\" }}>\n <TextInput label={`${t(\"fieldZip\")} *`} value={v.zip} onChange={(x) => setV((p) => ({ ...p, zip: x }))} />\n <TextInput label={`${t(\"fieldCity\")} *`} value={v.city} onChange={(x) => setV((p) => ({ ...p, city: x }))} />\n </div>\n <div>\n {/* Landkeuze alleen tonen wanneer de winkel meer dan één land bedient — anders is het\n een keuzemenu met één optie, en dat is ruis op een afrekenpagina. */}\n {landOpties.length > 1 && (\n <label style={{ display: \"grid\", gap: 4 }}>\n <span style={{ fontSize: \"0.9rem\" }}>{t(\"fieldCountry\")} *</span>\n <select\n className=\"xicms-input\"\n value={v.country}\n onChange={(e) => setV((p) => ({ ...p, country: e.target.value }))}\n >\n {landOpties.map((c) => (\n <option key={c} value={c}>\n {LANDNAMEN.of(c) ?? c}\n </option>\n ))}\n </select>\n </label>\n )}\n </div>\n <CheckboxInput\n label={t(\"billingSame\")}\n value={!billingDiffers}\n onChange={(checked) => setBillingDiffers(!checked)}\n />\n {billingDiffers && (\n <div style={{ display: \"grid\", gap: \"0.9rem\" }}>\n <Heading level={3}>{t(\"billingHeading\")}</Heading>\n <TextInput label={`${t(\"fieldAddress\")} *`} value={billing.address} onChange={(x) => setBilling((p) => ({ ...p, address: x }))} />\n <div style={{ display: \"grid\", gap: \"0.9rem\", gridTemplateColumns: \"140px 1fr\" }}>\n <TextInput label={`${t(\"fieldZip\")} *`} value={billing.zip} onChange={(x) => setBilling((p) => ({ ...p, zip: x }))} />\n <TextInput label={`${t(\"fieldCity\")} *`} value={billing.city} onChange={(x) => setBilling((p) => ({ ...p, city: x }))} />\n </div>\n </div>\n )}\n\n {settings.giftWrapEnabled && (\n <div style={{ display: \"grid\", gap: \"0.9rem\" }}>\n <CheckboxInput\n label={t(\"giftWrapLabel\", { bedrag: formatCents(settings.giftWrapPriceCents, settings.currency) })}\n value={giftWrap}\n onChange={setGiftWrap}\n />\n {giftWrap && (\n <>\n <TextInput label={t(\"giftWrapCardText\")} value={giftCardText} onChange={setGiftCardText} />\n <TextArea label={t(\"giftWrapNote\")} rows={2} value={giftNote} onChange={setGiftNote} />\n </>\n )}\n </div>\n )}\n\n <TextArea label={t(\"fieldNote\")} rows={3} value={v.note} onChange={(x) => setV((p) => ({ ...p, note: x }))} />\n\n {/* Honeypot — verborgen voor mensen, bots vullen 'm vaak wel in. */}\n <input\n type=\"text\"\n tabIndex={-1}\n autoComplete=\"off\"\n value={hp}\n onChange={(e) => setHp(e.target.value)}\n style={{ position: \"absolute\", left: \"-9999px\", width: 1, height: 1 }}\n aria-hidden\n />\n\n {error && <Text role=\"alert\" style={{ color: \"var(--color-error, #c0392b)\" }}>{error}</Text>}\n\n <button\n type=\"submit\"\n className=\"xicms-btn xicms-btn--primary\"\n disabled={busy}\n style={{ cursor: busy ? \"wait\" : \"pointer\", width: \"fit-content\" }}\n >\n {busy ? t(\"busy\") : t(\"pay\", { bedrag: formatCents(totalCents, settings.currency) })}\n </button>\n <Text size=\"sm\" style={{ opacity: 0.7 }}>{t(\"secureNote\")}</Text>\n </form>\n\n <Card padding={3} variant=\"muted\" style={{ alignSelf: \"start\" }}>\n <Heading level={2}>{t(\"yourOrder\")}</Heading>\n <div style={{ display: \"grid\", gap: 8, marginTop: \"0.75rem\" }}>\n {lines.map((l) => (\n <div key={cartLineKey(l)} style={{ display: \"flex\", justifyContent: \"space-between\", gap: 12 }}>\n <Text size=\"sm\">\n {l.qty}× {l.name}\n {l.variantLabel ? ` (${l.variantLabel})` : \"\"}\n {l.personalizationLabel ? ` — ${l.personalizationLabel}` : \"\"}\n </Text>\n <Text size=\"sm\">{formatCents(l.unitPriceCents * l.qty, settings.currency)}</Text>\n </div>\n ))}\n\n {/* Kortingscode */}\n <div className=\"xicms-shop-checkout__discount\" style={{ display: \"flex\", gap: 8, marginTop: 4 }}>\n <input\n className=\"xicms-input\"\n type=\"text\"\n placeholder={t(\"discountCode\")}\n value={codeInput}\n onChange={(e) => setCodeInput(e.target.value.toUpperCase())}\n style={{ flex: 1, textTransform: \"uppercase\" }}\n />\n <button type=\"button\" className=\"xicms-btn xicms-btn--secondary\" disabled={codeBusy || !codeInput.trim()} onClick={applyCode}>\n {codeBusy ? t(\"busy\") : t(\"discountApply\")}\n </button>\n </div>\n {discount && !discount.valid && (\n <Text size=\"sm\" role=\"alert\" style={{ color: \"var(--color-error, #c0392b)\" }}>{t(\"discountInvalid\")}</Text>\n )}\n {discount?.valid && (\n <Text size=\"sm\" style={{ color: \"var(--xicms-primary, #4d7fb0)\", fontWeight: 600 }}>\n {t(\"discountApplied\", { code: discount.code ?? \"\" })}\n </Text>\n )}\n\n <hr style={{ border: \"none\", borderTop: \"1px solid rgba(0,0,0,0.1)\" }} />\n {discountCents > 0 && (\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <Text size=\"sm\">{t(\"discount\")}</Text>\n <Text size=\"sm\">−{formatCents(discountCents, settings.currency)}</Text>\n </div>\n )}\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <Text size=\"sm\">{t(\"shippingCosts\")}</Text>\n <Text size=\"sm\">{shippingCents === 0 ? t(\"free\") : formatCents(shippingCents, settings.currency)}</Text>\n </div>\n {giftWrapCents > 0 && (\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <Text size=\"sm\">{t(\"giftWrap\")}</Text>\n <Text size=\"sm\">{formatCents(giftWrapCents, settings.currency)}</Text>\n </div>\n )}\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <Text weight=\"bold\">{t(\"total\")}</Text>\n <Text weight=\"bold\">{formatCents(totalCents, settings.currency)}</Text>\n </div>\n </div>\n </Card>\n </div>\n );\n}\n\nexport const checkoutBlock = defineBlock({\n type: \"checkout\",\n Render: CheckoutRender,\n label: \"Afrekenen\",\n icon: \"💳\",\n defaults: () => ({ heading: \"Afrekenen\" }),\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../src/modules/shop/blocks/Checkout.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState, type FormEvent } from \"react\";\nimport type { z } from \"zod\";\nimport { formatCents, shippingCentsFor, verzendLanden } from \"../../../schema/shopGeld\";\nimport type { CheckoutBlockSchema } from \"../../../schema/shop\";\nimport { defineBlock, type BlockRenderProps } from \"../../../blocks/registry\";\nimport { Card, Heading, Text } from \"../../../blocks/ui\";\nimport { TextInput } from \"@astryxdesign/core/TextInput\";\nimport { TextArea } from \"@astryxdesign/core/TextArea\";\nimport { CheckboxInput } from \"@astryxdesign/core/CheckboxInput\";\nimport { cartLineKey, useCart } from \"../cartStore\";\nimport { useShopStrings } from \"../strings\";\nimport { createOrderCall, useShopSettings, validateDiscountCall, type DiscountPreview } from \"../lib\";\n\ntype Blk = z.infer<typeof CheckoutBlockSchema>;\n\n/**\n * Afrekenen — klantgegevens + overzicht + kortingscode; `createOrder` herrekent server-side\n * (incl. korting en personalisatie-meerprijs) en geeft de Stripe Checkout-URL terug. De cart\n * wordt pas geleegd op de bedankt-pagina, zodat een geannuleerde betaling niets kwijtraakt.\n * NB: verplichte velden dragen een \" *\" in het label (de Engelse Astryx-chip blijft uit).\n */\n/** Landnamen in het Nederlands (\"BE\" → \"België\"); valt terug op de code als de browser hem niet kent. */\nconst LANDNAMEN = new Intl.DisplayNames([\"nl\"], { type: \"region\" });\n\nfunction CheckoutRender({ block, siteId, mode }: BlockRenderProps<Blk>) {\n const settings = useShopSettings();\n const t = useShopStrings();\n const { lines, itemsCents } = useCart(siteId);\n const [v, setV] = useState({ name: \"\", email: \"\", phone: \"\", address: \"\", zip: \"\", city: \"\", country: \"NL\", note: \"\" });\n const [hp, setHp] = useState(\"\");\n // Factuuradres: standaard hetzelfde als het verzendadres — alleen tonen als de klant expliciet\n // aangeeft dat het afwijkt (bv. bedrijfsadres op de factuur, cadeau naar een ander adres).\n const [billingDiffers, setBillingDiffers] = useState(false);\n const [billing, setBilling] = useState({ address: \"\", zip: \"\", city: \"\", country: \"NL\" });\n // Cadeauverpakking (7.27): de meerprijs komt server-side uit de shopconfig, hier alleen de keuze\n // + wat er op het kaartje moet staan.\n const [giftWrap, setGiftWrap] = useState(false);\n const [giftCardText, setGiftCardText] = useState(\"\");\n const [giftNote, setGiftNote] = useState(\"\");\n // Afhalen (7.33): alleen te kiezen als de winkel het aanbiedt; de server controleert dat opnieuw.\n const [pickupChoice, setPickupChoice] = useState(false);\n const pickup = settings.pickupEnabled && pickupChoice;\n // Welke landen bedient deze winkel? Leeg (of geen zones) = alleen het standaardland.\n const landOpties = useMemo(() => {\n const uit = verzendLanden({ shippingZones: settings.shippingZones });\n return uit.length > 0 ? uit : [\"NL\"];\n }, [settings.shippingZones]);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [codeInput, setCodeInput] = useState(\"\");\n const [codeBusy, setCodeBusy] = useState(false);\n const [discount, setDiscount] = useState<DiscountPreview | null>(null);\n\n // Eén rekenfunctie voor winkelwagen, afrekenen en server (zie shopGeld.ts): het land bepaalt de\n // zone, en een kortingscode met gratis verzending zit er nu ín in plaats van eromheen.\n const shippingCents = shippingCentsFor(\n itemsCents,\n {\n shippingFlatCents: settings.shippingFlatCents,\n shippingFreeFromCents: settings.shippingFreeFromCents || undefined,\n shippingZones: settings.shippingZones,\n },\n lines.length > 0,\n { land: v.country, freeShipping: discount?.valid && discount.freeShipping, pickup },\n );\n const discountCents = discount?.valid ? Math.min(discount.discountCents ?? 0, itemsCents) : 0;\n const giftWrapCents = giftWrap ? settings.giftWrapPriceCents : 0;\n const totalCents = Math.max(0, itemsCents - discountCents) + shippingCents + giftWrapCents;\n\n async function applyCode() {\n const code = codeInput.trim().toUpperCase();\n if (!code || codeBusy) return;\n setCodeBusy(true);\n try {\n const res = await validateDiscountCall(siteId, code, itemsCents);\n setDiscount(res.valid ? { ...res, code } : { valid: false });\n } catch {\n setDiscount({ valid: false });\n } finally {\n setCodeBusy(false);\n }\n }\n\n async function submit(e: FormEvent) {\n e.preventDefault();\n if (mode === \"preview\" || busy) return;\n setBusy(true);\n setError(null);\n try {\n const { url } = await createOrderCall({\n siteId,\n items: lines.map((l) => ({\n productId: l.productId,\n variantKey: l.variantKey,\n qty: l.qty,\n personalization: l.personalization,\n })),\n customer: { email: v.email, name: v.name, phone: v.phone || undefined },\n shipping: pickup ? undefined : { address: v.address, zip: v.zip, city: v.city, country: v.country || \"NL\" },\n pickup: pickup || undefined,\n billing: billingDiffers && !pickup\n ? { address: billing.address, zip: billing.zip, city: billing.city, country: billing.country || \"NL\" }\n : undefined,\n note: v.note || undefined,\n giftWrap: giftWrap ? { cardText: giftCardText.trim() || undefined, note: giftNote.trim() || undefined } : undefined,\n discountCode: discount?.valid ? discount.code : undefined,\n successPath: settings.successPath,\n cancelPath: settings.cartPath,\n _hp: hp || undefined,\n });\n window.location.assign(url);\n } catch (err) {\n console.error(\"[xicms] checkout mislukt:\", err);\n setError(t(\"checkoutFailed\"));\n setBusy(false);\n }\n }\n\n if (lines.length === 0) {\n return (\n <Card padding={4} variant=\"muted\">\n <Text>\n {t(\"cartEmpty\")} <a href={settings.shopPath}>{t(\"toShop\")}</a>\n </Text>\n </Card>\n );\n }\n\n return (\n <div className=\"xicms-shop-checkout\" style={{ display: \"grid\", gap: \"2rem\", gridTemplateColumns: \"repeat(auto-fit, minmax(min(320px, 100%), 1fr))\" }}>\n <form onSubmit={submit} style={{ display: \"grid\", gap: \"0.9rem\", alignContent: \"start\" }}>\n {block.heading && <Heading level={1} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n {block.introText && <Text data-xicms-edit=\"introText\">{block.introText}</Text>}\n\n <TextInput label={`${t(\"fieldName\")} *`} autoComplete=\"name\" value={v.name} onChange={(x) => setV((p) => ({ ...p, name: x }))} />\n <TextInput label={`${t(\"fieldEmail\")} *`} type=\"email\" autoComplete=\"email\" value={v.email} onChange={(x) => setV((p) => ({ ...p, email: x }))} />\n <TextInput label={t(\"fieldPhone\")} autoComplete=\"tel\" value={v.phone} onChange={(x) => setV((p) => ({ ...p, phone: x }))} />\n {settings.pickupEnabled && (\n <div className=\"xicms-shop-checkout__delivery\" style={{ display: \"grid\", gap: \"0.5rem\" }}>\n <Heading level={3}>{t(\"deliveryHeading\")}</Heading>\n <label style={{ display: \"flex\", gap: 8, alignItems: \"center\", cursor: \"pointer\" }}>\n <input type=\"radio\" name=\"xicms-delivery\" checked={!pickup} onChange={() => setPickupChoice(false)} />\n <span>{t(\"deliveryShip\")}</span>\n </label>\n <label style={{ display: \"flex\", gap: 8, alignItems: \"center\", cursor: \"pointer\" }}>\n <input type=\"radio\" name=\"xicms-delivery\" checked={pickup} onChange={() => setPickupChoice(true)} />\n <span>{t(\"deliveryPickup\")}</span>\n </label>\n {pickup && settings.pickupNote.trim() && (\n <Card padding={3} variant=\"muted\">\n <Text size=\"sm\" weight=\"bold\">{t(\"pickupHeading\")}</Text>\n <Text size=\"sm\" style={{ whiteSpace: \"pre-wrap\" }}>{settings.pickupNote}</Text>\n </Card>\n )}\n </div>\n )}\n {!pickup && (\n <>\n <TextInput label={`${t(\"fieldAddress\")} *`} autoComplete=\"shipping street-address\" value={v.address} onChange={(x) => setV((p) => ({ ...p, address: x }))} />\n <div style={{ display: \"grid\", gap: \"0.9rem\", gridTemplateColumns: \"140px 1fr\" }}>\n <TextInput label={`${t(\"fieldZip\")} *`} autoComplete=\"shipping postal-code\" value={v.zip} onChange={(x) => setV((p) => ({ ...p, zip: x }))} />\n <TextInput label={`${t(\"fieldCity\")} *`} autoComplete=\"shipping address-level2\" value={v.city} onChange={(x) => setV((p) => ({ ...p, city: x }))} />\n </div>\n <div>\n {/* Landkeuze alleen tonen wanneer de winkel meer dan één land bedient — anders is het\n een keuzemenu met één optie, en dat is ruis op een afrekenpagina. */}\n {landOpties.length > 1 && (\n <label style={{ display: \"grid\", gap: 4 }}>\n <span style={{ fontSize: \"0.9rem\" }}>{t(\"fieldCountry\")} *</span>\n <select\n className=\"xicms-input\"\n value={v.country}\n onChange={(e) => setV((p) => ({ ...p, country: e.target.value }))}\n >\n {landOpties.map((c) => (\n <option key={c} value={c}>\n {LANDNAMEN.of(c) ?? c}\n </option>\n ))}\n </select>\n </label>\n )}\n </div>\n <CheckboxInput\n label={t(\"billingSame\")}\n value={!billingDiffers}\n onChange={(checked) => setBillingDiffers(!checked)}\n />\n {billingDiffers && (\n <div style={{ display: \"grid\", gap: \"0.9rem\" }}>\n <Heading level={3}>{t(\"billingHeading\")}</Heading>\n <TextInput label={`${t(\"fieldAddress\")} *`} autoComplete=\"billing street-address\" value={billing.address} onChange={(x) => setBilling((p) => ({ ...p, address: x }))} />\n <div style={{ display: \"grid\", gap: \"0.9rem\", gridTemplateColumns: \"140px 1fr\" }}>\n <TextInput label={`${t(\"fieldZip\")} *`} autoComplete=\"billing postal-code\" value={billing.zip} onChange={(x) => setBilling((p) => ({ ...p, zip: x }))} />\n <TextInput label={`${t(\"fieldCity\")} *`} autoComplete=\"billing address-level2\" value={billing.city} onChange={(x) => setBilling((p) => ({ ...p, city: x }))} />\n </div>\n </div>\n )}\n </>\n )}\n {settings.giftWrapEnabled && (\n <div style={{ display: \"grid\", gap: \"0.9rem\" }}>\n <CheckboxInput\n label={t(\"giftWrapLabel\", { bedrag: formatCents(settings.giftWrapPriceCents, settings.currency) })}\n value={giftWrap}\n onChange={setGiftWrap}\n />\n {giftWrap && (\n <>\n <TextInput label={t(\"giftWrapCardText\")} value={giftCardText} onChange={setGiftCardText} />\n <TextArea label={t(\"giftWrapNote\")} rows={2} value={giftNote} onChange={setGiftNote} />\n </>\n )}\n </div>\n )}\n\n <TextArea label={t(\"fieldNote\")} rows={3} value={v.note} onChange={(x) => setV((p) => ({ ...p, note: x }))} />\n\n {/* Honeypot — verborgen voor mensen, bots vullen 'm vaak wel in. */}\n <input\n type=\"text\"\n tabIndex={-1}\n autoComplete=\"off\"\n value={hp}\n onChange={(e) => setHp(e.target.value)}\n style={{ position: \"absolute\", left: \"-9999px\", width: 1, height: 1 }}\n aria-hidden\n />\n\n {error && <Text role=\"alert\" style={{ color: \"var(--color-error, #c0392b)\" }}>{error}</Text>}\n\n <button\n type=\"submit\"\n className=\"xicms-btn xicms-btn--primary\"\n disabled={busy}\n style={{ cursor: busy ? \"wait\" : \"pointer\", width: \"fit-content\" }}\n >\n {busy ? t(\"busy\") : t(\"pay\", { bedrag: formatCents(totalCents, settings.currency) })}\n </button>\n <Text size=\"sm\" style={{ opacity: 0.7 }}>{t(\"secureNote\")}</Text>\n </form>\n\n <Card padding={3} variant=\"muted\" style={{ alignSelf: \"start\" }}>\n <Heading level={2}>{t(\"yourOrder\")}</Heading>\n <div style={{ display: \"grid\", gap: 8, marginTop: \"0.75rem\" }}>\n {lines.map((l) => (\n <div key={cartLineKey(l)} style={{ display: \"flex\", justifyContent: \"space-between\", gap: 12 }}>\n <Text size=\"sm\">\n {l.qty}× {l.name}\n {l.variantLabel ? ` (${l.variantLabel})` : \"\"}\n {l.personalizationLabel ? ` — ${l.personalizationLabel}` : \"\"}\n </Text>\n <Text size=\"sm\">{formatCents(l.unitPriceCents * l.qty, settings.currency)}</Text>\n </div>\n ))}\n\n {/* Kortingscode */}\n <div className=\"xicms-shop-checkout__discount\" style={{ display: \"flex\", gap: 8, marginTop: 4 }}>\n <input\n className=\"xicms-input\"\n type=\"text\"\n placeholder={t(\"discountCode\")}\n value={codeInput}\n onChange={(e) => setCodeInput(e.target.value.toUpperCase())}\n style={{ flex: 1, textTransform: \"uppercase\" }}\n />\n <button type=\"button\" className=\"xicms-btn xicms-btn--secondary\" disabled={codeBusy || !codeInput.trim()} onClick={applyCode}>\n {codeBusy ? t(\"busy\") : t(\"discountApply\")}\n </button>\n </div>\n {discount && !discount.valid && (\n <Text size=\"sm\" role=\"alert\" style={{ color: \"var(--color-error, #c0392b)\" }}>{t(\"discountInvalid\")}</Text>\n )}\n {discount?.valid && (\n <Text size=\"sm\" style={{ color: \"var(--xicms-primary, #4d7fb0)\", fontWeight: 600 }}>\n {t(\"discountApplied\", { code: discount.code ?? \"\" })}\n </Text>\n )}\n\n <hr style={{ border: \"none\", borderTop: \"1px solid rgba(0,0,0,0.1)\" }} />\n {discountCents > 0 && (\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <Text size=\"sm\">{t(\"discount\")}</Text>\n <Text size=\"sm\">−{formatCents(discountCents, settings.currency)}</Text>\n </div>\n )}\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <Text size=\"sm\">{t(\"shippingCosts\")}</Text>\n <Text size=\"sm\">{shippingCents === 0 ? t(\"free\") : formatCents(shippingCents, settings.currency)}</Text>\n </div>\n {giftWrapCents > 0 && (\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <Text size=\"sm\">{t(\"giftWrap\")}</Text>\n <Text size=\"sm\">{formatCents(giftWrapCents, settings.currency)}</Text>\n </div>\n )}\n <div style={{ display: \"flex\", justifyContent: \"space-between\" }}>\n <Text weight=\"bold\">{t(\"total\")}</Text>\n <Text weight=\"bold\">{formatCents(totalCents, settings.currency)}</Text>\n </div>\n </div>\n </Card>\n </div>\n );\n}\n\nexport const checkoutBlock = defineBlock({\n type: \"checkout\",\n Render: CheckoutRender,\n label: \"Afrekenen\",\n icon: \"💳\",\n essentieel: \"Zonder dit blok kunnen klanten niet afrekenen — er komen dan geen bestellingen meer binnen.\",\n defaults: () => ({ heading: \"Afrekenen\" }),\n});\n"],"mappings":"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","names":[]}
@@ -10,7 +10,7 @@ import { useShopStrings } from "../strings.js";
10
10
  function DonationRender({ block, siteId, mode }) {
11
11
  const settings = useShopSettings();
12
12
  const t = useShopStrings();
13
- const [amountCents, setAmountCents] = useState(block.amountsCents[0] ?? null);
13
+ const [amountCents, setAmountCents] = useState(block.amountsCents?.[0] ?? null);
14
14
  const [customEuro, setCustomEuro] = useState("");
15
15
  const [custom, setCustom] = useState(false);
16
16
  const [v, setV] = useState({ name: "", email: "" });
@@ -44,7 +44,7 @@ function DonationRender({ block, siteId, mode }) {
44
44
  block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
45
45
  block.introText && /* @__PURE__ */ jsx(Text, { "data-xicms-edit": "introText", children: block.introText }),
46
46
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, role: "group", "aria-label": "Kies een bedrag", children: [
47
- block.amountsCents.map((c) => {
47
+ (block.amountsCents ?? []).map((c) => {
48
48
  const active = !custom && amountCents === c;
49
49
  return /* @__PURE__ */ jsx(
50
50
  "button",
@@ -97,8 +97,8 @@ function DonationRender({ block, siteId, mode }) {
97
97
  }
98
98
  ),
99
99
  /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: "0.9rem", gridTemplateColumns: "repeat(auto-fit, minmax(min(220px, 100%), 1fr))" }, children: [
100
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldName")} *`, value: v.name, onChange: (x) => setV((p) => ({ ...p, name: x })) }),
101
- /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldEmail")} *`, type: "email", value: v.email, onChange: (x) => setV((p) => ({ ...p, email: x })) })
100
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldName")} *`, autoComplete: "name", value: v.name, onChange: (x) => setV((p) => ({ ...p, name: x })) }),
101
+ /* @__PURE__ */ jsx(TextInput, { label: `${t("fieldEmail")} *`, type: "email", autoComplete: "email", value: v.email, onChange: (x) => setV((p) => ({ ...p, email: x })) })
102
102
  ] }),
103
103
  /* @__PURE__ */ jsx(
104
104
  "input",