@xiwebdesign/xicms-core 7.31.0 → 8.16.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 (482) hide show
  1. package/dist/XiCMSProvider.js +23 -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 -60
  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 +248 -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 +159 -0
  133. package/dist/admin/settings/BedrijfInstellingen.js.map +1 -0
  134. package/dist/admin/settings/MailTemplates.js +5 -4
  135. package/dist/admin/settings/MailTemplates.js.map +1 -1
  136. package/dist/admin/settings/SettingsPanel.js +120 -78
  137. package/dist/admin/settings/SettingsPanel.js.map +1 -1
  138. package/dist/admin/settings/SnapshotsCard.js +4 -4
  139. package/dist/admin/settings/SnapshotsCard.js.map +1 -1
  140. package/dist/admin/settings/VorigeTerugzetten.d.ts +15 -0
  141. package/dist/admin/settings/VorigeTerugzetten.js +89 -0
  142. package/dist/admin/settings/VorigeTerugzetten.js.map +1 -0
  143. package/dist/admin/shop/CategoriesTab.js +6 -4
  144. package/dist/admin/shop/CategoriesTab.js.map +1 -1
  145. package/dist/admin/shop/DiscountsTab.js +4 -2
  146. package/dist/admin/shop/DiscountsTab.js.map +1 -1
  147. package/dist/admin/shop/OrdersTab.js +57 -19
  148. package/dist/admin/shop/OrdersTab.js.map +1 -1
  149. package/dist/admin/shop/ProductPaneel.js +2 -1
  150. package/dist/admin/shop/ProductPaneel.js.map +1 -1
  151. package/dist/admin/shop/ProductsTab.js +40 -19
  152. package/dist/admin/shop/ProductsTab.js.map +1 -1
  153. package/dist/admin/shop/ShopPanel.js +13 -1
  154. package/dist/admin/shop/ShopPanel.js.map +1 -1
  155. package/dist/admin/shop/ShopSettingsTab.js +56 -17
  156. package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
  157. package/dist/admin/shop/productClient.js +7 -3
  158. package/dist/admin/shop/productClient.js.map +1 -1
  159. package/dist/admin/stats/NietGevonden.d.ts +10 -0
  160. package/dist/admin/stats/NietGevonden.js +78 -0
  161. package/dist/admin/stats/NietGevonden.js.map +1 -0
  162. package/dist/admin/stats/StatsPanel.js +6 -1
  163. package/dist/admin/stats/StatsPanel.js.map +1 -1
  164. package/dist/admin/stats/lib.d.ts +2 -0
  165. package/dist/admin/stats/lib.js.map +1 -1
  166. package/dist/admin/ui/ConfirmDialog.js +10 -1
  167. package/dist/admin/ui/ConfirmDialog.js.map +1 -1
  168. package/dist/admin/ui/Icon.d.ts +34 -0
  169. package/dist/admin/ui/Icon.js +44 -0
  170. package/dist/admin/ui/Icon.js.map +1 -0
  171. package/dist/admin/ui/ImageField.d.ts +15 -0
  172. package/dist/admin/ui/ImageField.js +67 -0
  173. package/dist/admin/ui/ImageField.js.map +1 -0
  174. package/dist/admin/ui/KleurVeld.d.ts +25 -0
  175. package/dist/admin/ui/KleurVeld.js +76 -0
  176. package/dist/admin/ui/KleurVeld.js.map +1 -0
  177. package/dist/admin/ui/LaadStaat.d.ts +21 -0
  178. package/dist/admin/ui/LaadStaat.js +43 -0
  179. package/dist/admin/ui/LaadStaat.js.map +1 -0
  180. package/dist/admin/ui/LeesbaarheidPaneel.d.ts +10 -0
  181. package/dist/admin/ui/LeesbaarheidPaneel.js +68 -0
  182. package/dist/admin/ui/LeesbaarheidPaneel.js.map +1 -0
  183. package/dist/admin/ui/LinkDialog.d.ts +22 -0
  184. package/dist/admin/ui/LinkDialog.js +131 -0
  185. package/dist/admin/ui/LinkDialog.js.map +1 -0
  186. package/dist/admin/ui/LinkVeld.d.ts +14 -0
  187. package/dist/admin/ui/LinkVeld.js +49 -0
  188. package/dist/admin/ui/LinkVeld.js.map +1 -0
  189. package/dist/admin/ui/PreviewLinkResultaat.d.ts +14 -0
  190. package/dist/admin/ui/PreviewLinkResultaat.js +52 -0
  191. package/dist/admin/ui/PreviewLinkResultaat.js.map +1 -0
  192. package/dist/admin/ui/charts.js +5 -5
  193. package/dist/admin/ui/charts.js.map +1 -1
  194. package/dist/admin/ui/primitives.d.ts +16 -6
  195. package/dist/admin/ui/primitives.js +98 -26
  196. package/dist/admin/ui/primitives.js.map +1 -1
  197. package/dist/admin/ui/select.js +5 -2
  198. package/dist/admin/ui/select.js.map +1 -1
  199. package/dist/admin/ui/switch.d.ts +3 -1
  200. package/dist/admin/ui/switch.js +6 -3
  201. package/dist/admin/ui/switch.js.map +1 -1
  202. package/dist/admin/ui/toast.d.ts +2 -1
  203. package/dist/admin/ui/toast.js +17 -11
  204. package/dist/admin/ui/toast.js.map +1 -1
  205. package/dist/admin/visual/BlokKiezer.d.ts +34 -0
  206. package/dist/admin/visual/BlokKiezer.js +225 -0
  207. package/dist/admin/visual/BlokKiezer.js.map +1 -0
  208. package/dist/admin/visual/InlineGereedschap.d.ts +52 -0
  209. package/dist/admin/visual/InlineGereedschap.js +356 -0
  210. package/dist/admin/visual/InlineGereedschap.js.map +1 -0
  211. package/dist/admin/visual/InlineRijkeTekst.d.ts +23 -0
  212. package/dist/admin/visual/InlineRijkeTekst.js +152 -0
  213. package/dist/admin/visual/InlineRijkeTekst.js.map +1 -0
  214. package/dist/admin/visual/VisualEditor.js +273 -125
  215. package/dist/admin/visual/VisualEditor.js.map +1 -1
  216. package/dist/admin.css +1 -1
  217. package/dist/auth/AuthProvider.js +1 -0
  218. package/dist/auth/AuthProvider.js.map +1 -1
  219. package/dist/bedrijf/bedrijf.d.ts +44 -0
  220. package/dist/bedrijf/bedrijf.js +125 -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 +37 -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 +3 -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/consentEmbed.js +26 -9
  309. package/dist/blocks/builtins/consentEmbed.js.map +1 -1
  310. package/dist/blocks/builtins/index.d.ts +3 -0
  311. package/dist/blocks/builtins/index.js +6 -0
  312. package/dist/blocks/builtins/index.js.map +1 -1
  313. package/dist/blocks/builtins/lib/autoComplete.d.ts +7 -0
  314. package/dist/blocks/builtins/lib/autoComplete.js +20 -0
  315. package/dist/blocks/builtins/lib/autoComplete.js.map +1 -0
  316. package/dist/blocks/builtins/lib/bookingUrl.d.ts +2 -2
  317. package/dist/blocks/builtins/lib/bookingUrl.js +1 -1
  318. package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -1
  319. package/dist/blocks/builtins/lib/ical.d.ts +24 -0
  320. package/dist/blocks/builtins/lib/ical.js +82 -0
  321. package/dist/blocks/builtins/lib/ical.js.map +1 -0
  322. package/dist/blocks/builtins/lib/vandaag.d.ts +8 -0
  323. package/dist/blocks/builtins/lib/vandaag.js +22 -0
  324. package/dist/blocks/builtins/lib/vandaag.js.map +1 -0
  325. package/dist/blocks/registry.d.ts +6 -0
  326. package/dist/blocks/registry.js.map +1 -1
  327. package/dist/blocks/ui/index.js +1 -0
  328. package/dist/blocks/ui/index.js.map +1 -1
  329. package/dist/components/EditBar.js +2 -4
  330. package/dist/components/EditBar.js.map +1 -1
  331. package/dist/components/News.js +26 -18
  332. package/dist/components/News.js.map +1 -1
  333. package/dist/components/PageView.d.ts +7 -1
  334. package/dist/components/PageView.js +17 -0
  335. package/dist/components/PageView.js.map +1 -1
  336. package/dist/components/ResponsiveImage.js +18 -20
  337. package/dist/components/ResponsiveImage.js.map +1 -1
  338. package/dist/components/onderOffset.d.ts +13 -0
  339. package/dist/components/onderOffset.js +74 -0
  340. package/dist/components/onderOffset.js.map +1 -0
  341. package/dist/components/site/Bedrijfsnummers.d.ts +9 -0
  342. package/dist/components/site/Bedrijfsnummers.js +12 -0
  343. package/dist/components/site/Bedrijfsnummers.js.map +1 -0
  344. package/dist/components/site/SiteFooter.d.ts +6 -1
  345. package/dist/components/site/SiteFooter.js +62 -9
  346. package/dist/components/site/SiteFooter.js.map +1 -1
  347. package/dist/components/site/SiteHeader.d.ts +15 -0
  348. package/dist/components/site/SiteHeader.js +70 -0
  349. package/dist/components/site/SiteHeader.js.map +1 -0
  350. package/dist/components/site/SiteNav.d.ts +2 -0
  351. package/dist/components/site/SiteNav.js +29 -5
  352. package/dist/components/site/SiteNav.js.map +1 -1
  353. package/dist/demo/DemoStudio.js +2 -2
  354. package/dist/demo/DemoStudio.js.map +1 -1
  355. package/dist/demo/demoStore.d.ts +13 -0
  356. package/dist/demo/demoStore.js +36 -0
  357. package/dist/demo/demoStore.js.map +1 -1
  358. package/dist/editor/EditorProvider.js +15 -4
  359. package/dist/editor/EditorProvider.js.map +1 -1
  360. package/dist/firebase/functionsClient.js +5 -1
  361. package/dist/firebase/functionsClient.js.map +1 -1
  362. package/dist/index.d.ts +5 -1
  363. package/dist/index.js +20 -1
  364. package/dist/index.js.map +1 -1
  365. package/dist/media/ImageContext.d.ts +17 -0
  366. package/dist/media/ImageContext.js +65 -20
  367. package/dist/media/ImageContext.js.map +1 -1
  368. package/dist/media/altInHtml.d.ts +9 -0
  369. package/dist/media/altInHtml.js +17 -0
  370. package/dist/media/altInHtml.js.map +1 -0
  371. package/dist/media/srcset.d.ts +12 -0
  372. package/dist/media/srcset.js +13 -0
  373. package/dist/media/srcset.js.map +1 -0
  374. package/dist/modules/builtins.d.ts +1 -0
  375. package/dist/modules/builtins.js +22 -9
  376. package/dist/modules/builtins.js.map +1 -1
  377. package/dist/modules/consent/ConsentBanner.d.ts +5 -0
  378. package/dist/modules/consent/ConsentBanner.js +8 -7
  379. package/dist/modules/consent/ConsentBanner.js.map +1 -1
  380. package/dist/modules/consent/standaard.d.ts +12 -0
  381. package/dist/modules/consent/standaard.js +10 -0
  382. package/dist/modules/consent/standaard.js.map +1 -0
  383. package/dist/modules/consent/useConsent.d.ts +4 -0
  384. package/dist/modules/consent/useConsent.js +30 -1
  385. package/dist/modules/consent/useConsent.js.map +1 -1
  386. package/dist/modules/shop/blocks/Cart.js +5 -3
  387. package/dist/modules/shop/blocks/Cart.js.map +1 -1
  388. package/dist/modules/shop/blocks/Checkout.js +56 -35
  389. package/dist/modules/shop/blocks/Checkout.js.map +1 -1
  390. package/dist/modules/shop/blocks/Donation.js +4 -4
  391. package/dist/modules/shop/blocks/Donation.js.map +1 -1
  392. package/dist/modules/shop/blocks/ProductDetail.js +19 -3
  393. package/dist/modules/shop/blocks/ProductDetail.js.map +1 -1
  394. package/dist/modules/shop/blocks/ProductGrid.d.ts +3 -1
  395. package/dist/modules/shop/blocks/ProductGrid.js +8 -4
  396. package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
  397. package/dist/modules/shop/blocks/ShopCategories.js +4 -3
  398. package/dist/modules/shop/blocks/ShopCategories.js.map +1 -1
  399. package/dist/modules/shop/lib.d.ts +4 -0
  400. package/dist/modules/shop/lib.js +14 -0
  401. package/dist/modules/shop/lib.js.map +1 -1
  402. package/dist/modules/shop/settings.d.ts +3 -0
  403. package/dist/modules/shop/settings.js +14 -0
  404. package/dist/modules/shop/settings.js.map +1 -1
  405. package/dist/modules/shop/strings.d.ts +4 -0
  406. package/dist/modules/shop/strings.js +8 -0
  407. package/dist/modules/shop/strings.js.map +1 -1
  408. package/dist/next/envCheck.d.ts +42 -0
  409. package/dist/next/envCheck.js +106 -0
  410. package/dist/next/envCheck.js.map +1 -0
  411. package/dist/next/index.cjs +185 -2
  412. package/dist/next/index.d.ts +2 -0
  413. package/dist/next/index.js +8 -1
  414. package/dist/next/index.js.map +1 -1
  415. package/dist/next/securityHeaders.d.ts +36 -0
  416. package/dist/next/securityHeaders.js +74 -0
  417. package/dist/next/securityHeaders.js.map +1 -0
  418. package/dist/patterns/builtins.d.ts +7 -0
  419. package/dist/patterns/builtins.js +138 -3
  420. package/dist/patterns/builtins.js.map +1 -1
  421. package/dist/releaseNotes.js +148 -0
  422. package/dist/releaseNotes.js.map +1 -1
  423. package/dist/render/PublishedPage.d.ts +2 -1
  424. package/dist/render/PublishedPage.js +10 -4
  425. package/dist/render/PublishedPage.js.map +1 -1
  426. package/dist/schema/blocks.d.ts +473 -0
  427. package/dist/schema/blocks.js +105 -5
  428. package/dist/schema/blocks.js.map +1 -1
  429. package/dist/schema/business.d.ts +118 -0
  430. package/dist/schema/business.js +75 -0
  431. package/dist/schema/business.js.map +1 -0
  432. package/dist/schema/fields.d.ts +2 -1
  433. package/dist/schema/fields.js.map +1 -1
  434. package/dist/schema/forms.d.ts +18 -0
  435. package/dist/schema/forms.js +18 -3
  436. package/dist/schema/forms.js.map +1 -1
  437. package/dist/schema/mail.d.ts +10 -0
  438. package/dist/schema/mail.js +7 -0
  439. package/dist/schema/mail.js.map +1 -1
  440. package/dist/schema/settings.d.ts +103 -0
  441. package/dist/schema/settings.js +24 -3
  442. package/dist/schema/settings.js.map +1 -1
  443. package/dist/schema/shop.d.ts +2 -0
  444. package/dist/schema/shop.js +4 -0
  445. package/dist/schema/shop.js.map +1 -1
  446. package/dist/schema/shopGeld.d.ts +1 -0
  447. package/dist/schema/shopGeld.js +1 -0
  448. package/dist/schema/shopGeld.js.map +1 -1
  449. package/dist/schema/siteConfig.d.ts +69 -1
  450. package/dist/schema/siteConfig.js +7 -2
  451. package/dist/schema/siteConfig.js.map +1 -1
  452. package/dist/server/blockData.d.ts +1 -1
  453. package/dist/server/blockData.js +74 -18
  454. package/dist/server/blockData.js.map +1 -1
  455. package/dist/server/cspRapport.d.ts +20 -0
  456. package/dist/server/cspRapport.js +56 -0
  457. package/dist/server/cspRapport.js.map +1 -0
  458. package/dist/server/fonts.d.ts +3 -0
  459. package/dist/server/fonts.js +39 -0
  460. package/dist/server/fonts.js.map +1 -0
  461. package/dist/server/index.d.ts +3 -0
  462. package/dist/server/index.js +8 -0
  463. package/dist/server/index.js.map +1 -1
  464. package/dist/server/sanitize.js +2 -0
  465. package/dist/server/sanitize.js.map +1 -1
  466. package/dist/settings/useSiteSettings.js +4 -1
  467. package/dist/settings/useSiteSettings.js.map +1 -1
  468. package/dist/starters/starters.d.ts +69 -0
  469. package/dist/starters/starters.js +171 -0
  470. package/dist/starters/starters.js.map +1 -0
  471. package/dist/styles.css +1181 -212
  472. package/dist/theme/color.d.ts +10 -0
  473. package/dist/theme/color.js +17 -1
  474. package/dist/theme/color.js.map +1 -1
  475. package/dist/theme/fontFallback.d.ts +23 -0
  476. package/dist/theme/fontFallback.js +58 -0
  477. package/dist/theme/fontFallback.js.map +1 -0
  478. package/dist/theme/fonts.d.ts +11 -0
  479. package/dist/theme/fonts.js +16 -0
  480. package/dist/theme/fonts.js.map +1 -0
  481. package/dist/version.js +1 -1
  482. package/package.json +5 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/blocks/blockStyle.ts"],"sourcesContent":["import type { CSSProperties } from \"react\";\nimport type { BlockStyle } from \"../schema/blocks\";\n\nexport interface BlockStyleAttrs {\n id?: string;\n className: string;\n style: CSSProperties;\n dataAnimate?: string;\n}\n\n/**\n * Vertaalt de gedeelde `_style` van een block naar wrapper-attributen. Gebruikt classNames +\n * CSS-variabelen (te overschrijven per site) en alleen inline-CSS waar een vrije waarde nodig is\n * (achtergrondkleur). Geeft `null` terug als er niets te stylen valt (dan rendert het block kaal).\n */\nexport function blockStyleAttrs(style: BlockStyle | undefined): BlockStyleAttrs | null {\n if (!style || Object.keys(style).length === 0) return null;\n const cls = [\"xicms-block\"];\n if (style.paddingY) cls.push(`xicms-block--pad-${style.paddingY}`);\n if (style.width) cls.push(`xicms-block--${style.width}`);\n if (style.align) cls.push(`xicms-block--align-${style.align}`);\n const css: CSSProperties = {};\n if (style.background) css.background = style.background;\n return { id: style.anchorId || undefined, className: cls.join(\" \"), style: css, dataAnimate: style.animate };\n}\n"],"mappings":"AAeO,SAAS,gBAAgB,OAAuD;AACrF,MAAI,CAAC,SAAS,OAAO,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO;AACtD,QAAM,MAAM,CAAC,aAAa;AAC1B,MAAI,MAAM,SAAU,KAAI,KAAK,oBAAoB,MAAM,QAAQ,EAAE;AACjE,MAAI,MAAM,MAAO,KAAI,KAAK,gBAAgB,MAAM,KAAK,EAAE;AACvD,MAAI,MAAM,MAAO,KAAI,KAAK,sBAAsB,MAAM,KAAK,EAAE;AAC7D,QAAM,MAAqB,CAAC;AAC5B,MAAI,MAAM,WAAY,KAAI,aAAa,MAAM;AAC7C,SAAO,EAAE,IAAI,MAAM,YAAY,QAAW,WAAW,IAAI,KAAK,GAAG,GAAG,OAAO,KAAK,aAAa,MAAM,QAAQ;AAC7G;","names":[]}
1
+ {"version":3,"sources":["../../src/blocks/blockStyle.ts"],"sourcesContent":["import type { CSSProperties } from \"react\";\nimport type { BlockStyle } from \"../schema/blocks\";\nimport { tekstOpKleur } from \"../theme/color\";\n\nexport interface BlockStyleAttrs {\n id?: string;\n className: string;\n style: CSSProperties;\n dataAnimate?: string;\n}\n\n/**\n * Vertaalt de gedeelde `_style` van een block naar wrapper-attributen. Gebruikt classNames +\n * CSS-variabelen (te overschrijven per site) en alleen inline-CSS waar een vrije waarde nodig is\n * (achtergrondkleur). Geeft `null` terug als er niets te stylen valt (dan rendert het block kaal).\n *\n * 8.10 — een achtergrondkleur is een vlak, geen verfstreep:\n * - de tekstkleur rekent mee (wit of donker, wat het meeste contrast geeft). Tot nu toe bleef de\n * tekst in de themakleur: donkere tekst op donkerblauw, of — in donkere modus — witte tekst op\n * de staal \"Wit\";\n * - zonder gekozen ruimte krijgt het vlak lucht (`pad-lg`), anders plakt de tekst tegen de rand;\n * - een oude, niet-hex waarde (gradient, var(), url()) werkt zoals altijd, zonder automatiek.\n */\nexport function blockStyleAttrs(style: BlockStyle | undefined): BlockStyleAttrs | null {\n if (!style || Object.keys(style).length === 0) return null;\n const cls = [\"xicms-block\"];\n const css: CSSProperties & Record<`--${string}`, string> = {};\n const bg = style.background?.trim();\n const tekst = bg ? tekstOpKleur(bg) : null;\n if (bg && tekst) {\n css.backgroundColor = bg.startsWith(\"#\") ? bg : `#${bg}`;\n css.color = tekst;\n css[\"--xicms-fg\"] = tekst;\n css[\"--color-text-primary\"] = tekst;\n css[\"--color-text-secondary\"] = tekst === \"#ffffff\" ? \"rgba(255, 255, 255, 0.78)\" : \"rgba(15, 23, 42, 0.72)\";\n cls.push(\"xicms-block--bg\", tekst === \"#ffffff\" ? \"xicms-block--bg-donker\" : \"xicms-block--bg-licht\");\n } else if (bg) {\n css.background = bg;\n }\n const paddingY = style.paddingY ?? (bg && tekst ? \"lg\" : undefined);\n if (paddingY) cls.push(`xicms-block--pad-${paddingY}`);\n if (style.width) cls.push(`xicms-block--${style.width}`);\n if (style.align) cls.push(`xicms-block--align-${style.align}`);\n return { id: style.anchorId || undefined, className: cls.join(\" \"), style: css, dataAnimate: style.animate };\n}\n"],"mappings":"AAEA,SAAS,oBAAoB;AAqBtB,SAAS,gBAAgB,OAAuD;AACrF,MAAI,CAAC,SAAS,OAAO,KAAK,KAAK,EAAE,WAAW,EAAG,QAAO;AACtD,QAAM,MAAM,CAAC,aAAa;AAC1B,QAAM,MAAqD,CAAC;AAC5D,QAAM,KAAK,MAAM,YAAY,KAAK;AAClC,QAAM,QAAQ,KAAK,aAAa,EAAE,IAAI;AACtC,MAAI,MAAM,OAAO;AACf,QAAI,kBAAkB,GAAG,WAAW,GAAG,IAAI,KAAK,IAAI,EAAE;AACtD,QAAI,QAAQ;AACZ,QAAI,YAAY,IAAI;AACpB,QAAI,sBAAsB,IAAI;AAC9B,QAAI,wBAAwB,IAAI,UAAU,YAAY,8BAA8B;AACpF,QAAI,KAAK,mBAAmB,UAAU,YAAY,2BAA2B,uBAAuB;AAAA,EACtG,WAAW,IAAI;AACb,QAAI,aAAa;AAAA,EACnB;AACA,QAAM,WAAW,MAAM,aAAa,MAAM,QAAQ,OAAO;AACzD,MAAI,SAAU,KAAI,KAAK,oBAAoB,QAAQ,EAAE;AACrD,MAAI,MAAM,MAAO,KAAI,KAAK,gBAAgB,MAAM,KAAK,EAAE;AACvD,MAAI,MAAM,MAAO,KAAI,KAAK,sBAAsB,MAAM,KAAK,EAAE;AAC7D,SAAO,EAAE,IAAI,MAAM,YAAY,QAAW,WAAW,IAAI,KAAK,GAAG,GAAG,OAAO,KAAK,aAAa,MAAM,QAAQ;AAC7G;","names":[]}
@@ -9,6 +9,9 @@ import {
9
9
  BreadcrumbsBlockSchema,
10
10
  ButtonsBlockSchema,
11
11
  CardsBlockSchema,
12
+ PriceListBlockSchema,
13
+ SectionHeadingBlockSchema,
14
+ AvailabilityBlockSchema,
12
15
  CardsWidgetSchema,
13
16
  ColumnsBlockSchema,
14
17
  ContactBlockSchema,
@@ -70,6 +73,9 @@ const builtinBlockSchemas = {
70
73
  breadcrumbs: BreadcrumbsBlockSchema,
71
74
  buttons: ButtonsBlockSchema,
72
75
  cards: CardsBlockSchema,
76
+ priceList: PriceListBlockSchema,
77
+ sectionHeading: SectionHeadingBlockSchema,
78
+ availability: AvailabilityBlockSchema,
73
79
  cardsWidget: CardsWidgetSchema,
74
80
  columns: ColumnsBlockSchema,
75
81
  contact: ContactBlockSchema,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/blocks/builtinSchemas.ts"],"sourcesContent":["/**\n * Lazy schema-registratie voor de ingebouwde blokken (7.13).\n *\n * De schema's zijn EDITOR-kennis: het formulier in het zijpaneel, de inline-veldlabels, de\n * vertaal-overlay en de validatie bij bewerken komen eruit voort. Een publieke bezoeker heeft\n * er niets aan — en toch reisden alle schema's plus de zod-runtime (±73 KB gzip) mee in élke\n * paginabundel, omdat elk blok zijn schema in zijn eigen client-module droeg.\n *\n * Dit bestand is de enige plek die de schema's nog als WAARDE importeert, en het wordt alleen\n * geladen door de admin/editor-chunks (AdminApp, VisualEditor) — die waren al lazy. Het plugt\n * ook de zod-parser in de registry (`setSchemaParser`), zodat validatie weer volledig is zodra\n * er bewerkt wordt; publiek volstaat de lichte vormcheck (zie registry.validateBlocks).\n *\n * NIEUW BLOK? `npm test` bewaakt dat elk ingebouwd blok hier een schema heeft (builtinSchemas.test).\n */\nimport { safeParse, type $ZodType } from \"zod/v4/core\";\nimport {\n AccordionBlockSchema,\n AgendaBlockSchema,\n AgendaWidgetSchema,\n BannerBlockSchema,\n BeforeAfterBlockSchema,\n BookingBlockSchema,\n BreadcrumbsBlockSchema,\n ButtonsBlockSchema,\n CardsBlockSchema,\n CardsWidgetSchema,\n ColumnsBlockSchema,\n ContactBlockSchema,\n ContactWidgetSchema,\n CountdownBlockSchema,\n CountdownWidgetSchema,\n CountersBlockSchema,\n CtaBlockSchema,\n CtaWidgetSchema,\n DividerBlockSchema,\n DownloadsBlockSchema,\n DownloadsWidgetSchema,\n EmbedBlockSchema,\n FaqBlockSchema,\n FeatureBlockSchema,\n FormBlockSchema,\n GalleryBlockSchema,\n GalleryWidgetSchema,\n HeroBlockSchema,\n ImageBlockSchema,\n JobsBlockSchema,\n LogosBlockSchema,\n MapBlockSchema,\n NewsListBlockSchema,\n NewsWidgetSchema,\n NewsletterBlockSchema,\n NewsletterWidgetSchema,\n OpeningHoursBlockSchema,\n OpeningHoursWidgetSchema,\n PdfBlockSchema,\n PortfolioBlockSchema,\n PricingBlockSchema,\n QuoteBlockSchema,\n RichTextBlockSchema,\n SearchBlockSchema,\n SliderBlockSchema,\n SocialBlockSchema,\n SocialWidgetSchema,\n SpacerBlockSchema,\n SymbolRefBlockSchema,\n TabsBlockSchema,\n TeamBlockSchema,\n TestimonialsBlockSchema,\n TestimonialsWidgetSchema,\n TimelineBlockSchema,\n VideoBlockSchema,\n WhatsappChatBlockSchema,\n WithSidebarBlockSchema,\n} from \"../schema/blocks\";\nimport { setSchemaParser, type BlockDefinition } from \"./registry\";\nimport { builtinBlocks } from \"./builtins/index\";\n\n/** type → schema, voor elk ingebouwd blok. */\nexport const builtinBlockSchemas: Record<string, $ZodType> = {\n accordion: AccordionBlockSchema,\n agenda: AgendaBlockSchema,\n agendaWidget: AgendaWidgetSchema,\n banner: BannerBlockSchema,\n beforeAfter: BeforeAfterBlockSchema,\n booking: BookingBlockSchema,\n breadcrumbs: BreadcrumbsBlockSchema,\n buttons: ButtonsBlockSchema,\n cards: CardsBlockSchema,\n cardsWidget: CardsWidgetSchema,\n columns: ColumnsBlockSchema,\n contact: ContactBlockSchema,\n contactWidget: ContactWidgetSchema,\n countdown: CountdownBlockSchema,\n countdownWidget: CountdownWidgetSchema,\n counters: CountersBlockSchema,\n cta: CtaBlockSchema,\n ctaWidget: CtaWidgetSchema,\n divider: DividerBlockSchema,\n downloads: DownloadsBlockSchema,\n downloadsWidget: DownloadsWidgetSchema,\n embed: EmbedBlockSchema,\n faq: FaqBlockSchema,\n feature: FeatureBlockSchema,\n form: FormBlockSchema,\n gallery: GalleryBlockSchema,\n galleryWidget: GalleryWidgetSchema,\n hero: HeroBlockSchema,\n image: ImageBlockSchema,\n jobs: JobsBlockSchema,\n logos: LogosBlockSchema,\n map: MapBlockSchema,\n newsList: NewsListBlockSchema,\n newsWidget: NewsWidgetSchema,\n newsletter: NewsletterBlockSchema,\n newsletterWidget: NewsletterWidgetSchema,\n openingHours: OpeningHoursBlockSchema,\n openingHoursWidget: OpeningHoursWidgetSchema,\n pdf: PdfBlockSchema,\n portfolio: PortfolioBlockSchema,\n pricing: PricingBlockSchema,\n quote: QuoteBlockSchema,\n richText: RichTextBlockSchema,\n search: SearchBlockSchema,\n slider: SliderBlockSchema,\n social: SocialBlockSchema,\n socialWidget: SocialWidgetSchema,\n spacer: SpacerBlockSchema,\n symbolRef: SymbolRefBlockSchema,\n tabs: TabsBlockSchema,\n team: TeamBlockSchema,\n testimonials: TestimonialsBlockSchema,\n testimonialsWidget: TestimonialsWidgetSchema,\n timeline: TimelineBlockSchema,\n video: VideoBlockSchema,\n whatsappChat: WhatsappChatBlockSchema,\n withSidebar: WithSidebarBlockSchema,\n};\n\nlet geregistreerd = false;\n\n/**\n * Hangt de schema's aan de (module-singleton) builtin-defs en plugt de zod-parser in.\n * Idempotent; aan te roepen vanuit elke admin/editor-ingang.\n */\nexport function registerBuiltinSchemas(): void {\n if (geregistreerd) return;\n geregistreerd = true;\n setSchemaParser((schema, raw) => {\n const res = safeParse(schema, raw);\n return res.success ? { success: true, data: res.data } : { success: false, issues: res.error.issues };\n });\n for (const def of builtinBlocks as Array<BlockDefinition & { schema?: unknown }>) {\n if (!def.schema && builtinBlockSchemas[def.type]) def.schema = builtinBlockSchemas[def.type];\n }\n}\n"],"mappings":"AAeA,SAAS,iBAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAA6C;AACtD,SAAS,qBAAqB;AAGvB,MAAM,sBAAgD;AAAA,EAC3D,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAS;AAAA,EACT,aAAa;AAAA,EACb,SAAS;AAAA,EACT,OAAO;AAAA,EACP,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,eAAe;AAAA,EACf,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM;AAAA,EACN,MAAM;AAAA,EACN,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,OAAO;AAAA,EACP,cAAc;AAAA,EACd,aAAa;AACf;AAEA,IAAI,gBAAgB;AAMb,SAAS,yBAA+B;AAC7C,MAAI,cAAe;AACnB,kBAAgB;AAChB,kBAAgB,CAAC,QAAQ,QAAQ;AAC/B,UAAM,MAAM,UAAU,QAAQ,GAAG;AACjC,WAAO,IAAI,UAAU,EAAE,SAAS,MAAM,MAAM,IAAI,KAAK,IAAI,EAAE,SAAS,OAAO,QAAQ,IAAI,MAAM,OAAO;AAAA,EACtG,CAAC;AACD,aAAW,OAAO,eAAgE;AAChF,QAAI,CAAC,IAAI,UAAU,oBAAoB,IAAI,IAAI,EAAG,KAAI,SAAS,oBAAoB,IAAI,IAAI;AAAA,EAC7F;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/blocks/builtinSchemas.ts"],"sourcesContent":["/**\n * Lazy schema-registratie voor de ingebouwde blokken (7.13).\n *\n * De schema's zijn EDITOR-kennis: het formulier in het zijpaneel, de inline-veldlabels, de\n * vertaal-overlay en de validatie bij bewerken komen eruit voort. Een publieke bezoeker heeft\n * er niets aan — en toch reisden alle schema's plus de zod-runtime (±73 KB gzip) mee in élke\n * paginabundel, omdat elk blok zijn schema in zijn eigen client-module droeg.\n *\n * Dit bestand is de enige plek die de schema's nog als WAARDE importeert, en het wordt alleen\n * geladen door de admin/editor-chunks (AdminApp, VisualEditor) — die waren al lazy. Het plugt\n * ook de zod-parser in de registry (`setSchemaParser`), zodat validatie weer volledig is zodra\n * er bewerkt wordt; publiek volstaat de lichte vormcheck (zie registry.validateBlocks).\n *\n * NIEUW BLOK? `npm test` bewaakt dat elk ingebouwd blok hier een schema heeft (builtinSchemas.test).\n */\nimport { safeParse, type $ZodType } from \"zod/v4/core\";\nimport {\n AccordionBlockSchema,\n AgendaBlockSchema,\n AgendaWidgetSchema,\n BannerBlockSchema,\n BeforeAfterBlockSchema,\n BookingBlockSchema,\n BreadcrumbsBlockSchema,\n ButtonsBlockSchema,\n CardsBlockSchema,\n PriceListBlockSchema,\n SectionHeadingBlockSchema,\n AvailabilityBlockSchema,\n CardsWidgetSchema,\n ColumnsBlockSchema,\n ContactBlockSchema,\n ContactWidgetSchema,\n CountdownBlockSchema,\n CountdownWidgetSchema,\n CountersBlockSchema,\n CtaBlockSchema,\n CtaWidgetSchema,\n DividerBlockSchema,\n DownloadsBlockSchema,\n DownloadsWidgetSchema,\n EmbedBlockSchema,\n FaqBlockSchema,\n FeatureBlockSchema,\n FormBlockSchema,\n GalleryBlockSchema,\n GalleryWidgetSchema,\n HeroBlockSchema,\n ImageBlockSchema,\n JobsBlockSchema,\n LogosBlockSchema,\n MapBlockSchema,\n NewsListBlockSchema,\n NewsWidgetSchema,\n NewsletterBlockSchema,\n NewsletterWidgetSchema,\n OpeningHoursBlockSchema,\n OpeningHoursWidgetSchema,\n PdfBlockSchema,\n PortfolioBlockSchema,\n PricingBlockSchema,\n QuoteBlockSchema,\n RichTextBlockSchema,\n SearchBlockSchema,\n SliderBlockSchema,\n SocialBlockSchema,\n SocialWidgetSchema,\n SpacerBlockSchema,\n SymbolRefBlockSchema,\n TabsBlockSchema,\n TeamBlockSchema,\n TestimonialsBlockSchema,\n TestimonialsWidgetSchema,\n TimelineBlockSchema,\n VideoBlockSchema,\n WhatsappChatBlockSchema,\n WithSidebarBlockSchema,\n} from \"../schema/blocks\";\nimport { setSchemaParser, type BlockDefinition } from \"./registry\";\nimport { builtinBlocks } from \"./builtins/index\";\n\n/** type → schema, voor elk ingebouwd blok. */\nexport const builtinBlockSchemas: Record<string, $ZodType> = {\n accordion: AccordionBlockSchema,\n agenda: AgendaBlockSchema,\n agendaWidget: AgendaWidgetSchema,\n banner: BannerBlockSchema,\n beforeAfter: BeforeAfterBlockSchema,\n booking: BookingBlockSchema,\n breadcrumbs: BreadcrumbsBlockSchema,\n buttons: ButtonsBlockSchema,\n cards: CardsBlockSchema,\n priceList: PriceListBlockSchema,\n sectionHeading: SectionHeadingBlockSchema,\n availability: AvailabilityBlockSchema,\n cardsWidget: CardsWidgetSchema,\n columns: ColumnsBlockSchema,\n contact: ContactBlockSchema,\n contactWidget: ContactWidgetSchema,\n countdown: CountdownBlockSchema,\n countdownWidget: CountdownWidgetSchema,\n counters: CountersBlockSchema,\n cta: CtaBlockSchema,\n ctaWidget: CtaWidgetSchema,\n divider: DividerBlockSchema,\n downloads: DownloadsBlockSchema,\n downloadsWidget: DownloadsWidgetSchema,\n embed: EmbedBlockSchema,\n faq: FaqBlockSchema,\n feature: FeatureBlockSchema,\n form: FormBlockSchema,\n gallery: GalleryBlockSchema,\n galleryWidget: GalleryWidgetSchema,\n hero: HeroBlockSchema,\n image: ImageBlockSchema,\n jobs: JobsBlockSchema,\n logos: LogosBlockSchema,\n map: MapBlockSchema,\n newsList: NewsListBlockSchema,\n newsWidget: NewsWidgetSchema,\n newsletter: NewsletterBlockSchema,\n newsletterWidget: NewsletterWidgetSchema,\n openingHours: OpeningHoursBlockSchema,\n openingHoursWidget: OpeningHoursWidgetSchema,\n pdf: PdfBlockSchema,\n portfolio: PortfolioBlockSchema,\n pricing: PricingBlockSchema,\n quote: QuoteBlockSchema,\n richText: RichTextBlockSchema,\n search: SearchBlockSchema,\n slider: SliderBlockSchema,\n social: SocialBlockSchema,\n socialWidget: SocialWidgetSchema,\n spacer: SpacerBlockSchema,\n symbolRef: SymbolRefBlockSchema,\n tabs: TabsBlockSchema,\n team: TeamBlockSchema,\n testimonials: TestimonialsBlockSchema,\n testimonialsWidget: TestimonialsWidgetSchema,\n timeline: TimelineBlockSchema,\n video: VideoBlockSchema,\n whatsappChat: WhatsappChatBlockSchema,\n withSidebar: WithSidebarBlockSchema,\n};\n\nlet geregistreerd = false;\n\n/**\n * Hangt de schema's aan de (module-singleton) builtin-defs en plugt de zod-parser in.\n * Idempotent; aan te roepen vanuit elke admin/editor-ingang.\n */\nexport function registerBuiltinSchemas(): void {\n if (geregistreerd) return;\n geregistreerd = true;\n setSchemaParser((schema, raw) => {\n const res = safeParse(schema, raw);\n return res.success ? { success: true, data: res.data } : { success: false, issues: res.error.issues };\n });\n for (const def of builtinBlocks as Array<BlockDefinition & { schema?: unknown }>) {\n if (!def.schema && builtinBlockSchemas[def.type]) def.schema = builtinBlockSchemas[def.type];\n }\n}\n"],"mappings":"AAeA,SAAS,iBAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAA6C;AACtD,SAAS,qBAAqB;AAGvB,MAAM,sBAAgD;AAAA,EAC3D,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,SAAS;AAAA,EACT,aAAa;AAAA,EACb,SAAS;AAAA,EACT,OAAO;AAAA,EACP,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,aAAa;AAAA,EACb,SAAS;AAAA,EACT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,KAAK;AAAA,EACL,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,eAAe;AAAA,EACf,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AAAA,EACL,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,KAAK;AAAA,EACL,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM;AAAA,EACN,MAAM;AAAA,EACN,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,UAAU;AAAA,EACV,OAAO;AAAA,EACP,cAAc;AAAA,EACd,aAAa;AACf;AAEA,IAAI,gBAAgB;AAMb,SAAS,yBAA+B;AAC7C,MAAI,cAAe;AACnB,kBAAgB;AAChB,kBAAgB,CAAC,QAAQ,QAAQ;AAC/B,UAAM,MAAM,UAAU,QAAQ,GAAG;AACjC,WAAO,IAAI,UAAU,EAAE,SAAS,MAAM,MAAM,IAAI,KAAK,IAAI,EAAE,SAAS,OAAO,QAAQ,IAAI,MAAM,OAAO;AAAA,EACtG,CAAC;AACD,aAAW,OAAO,eAAgE;AAChF,QAAI,CAAC,IAAI,UAAU,oBAAoB,IAAI,IAAI,EAAG,KAAI,SAAS,oBAAoB,IAAI,IAAI;AAAA,EAC7F;AACF;","names":[]}
@@ -10,7 +10,18 @@ export interface AgendaEvent {
10
10
  location?: string;
11
11
  description?: string;
12
12
  url?: string;
13
+ /** 8.15: terugkerend. */
14
+ herhaal?: "wekelijks" | "tweewekelijks" | "maandelijks";
15
+ /** Laatste datum van de herhaling ("2027-06-30"); leeg = een jaar vooruit. */
16
+ herhaalTot?: string;
13
17
  }
18
+ /**
19
+ * Terugkerende activiteiten uitvouwen (8.15): "elke dinsdag koor" staat één keer in het beheer en
20
+ * verschijnt op de site als losse data — tot de einddatum, anders een jaar vooruit, en nooit meer
21
+ * dan 60 keer. Elke herhaling houdt de index van het origineel (`_i`), dus bewerken op de pagina
22
+ * past de reeks aan.
23
+ */
24
+ export declare function vouwHerhalingenUit<T extends AgendaEvent>(events: T[], vanaf?: Date): T[];
14
25
  /**
15
26
  * Parseert een event-datum als LOKALE tijd. Cruciaal voor datum-zonder-tijd: `new Date("2026-08-01")`
16
27
  * is per spec UTC-middernacht, waardoor west-van-UTC-bezoekers "31 juli" te zien kregen (en de
@@ -28,7 +39,18 @@ export declare function formatEventDate(value: string): string;
28
39
  export declare function selectAgendaEvents<T extends AgendaEvent>(events: T[] | undefined, opts?: {
29
40
  hidePast?: boolean;
30
41
  limit?: number;
42
+ vandaag?: Date | null;
31
43
  }): T[];
44
+ /**
45
+ * Event-JSON-LD (8.14 vollediger): adres (eigen adres of dat uit het bedrijfsprofiel), afbeelding,
46
+ * prijs, status (afgelast/verplaatst/online) en de organisator. Google vroeg in Search Console bij
47
+ * de oude versie om "ontbrekend veld: address / image / offers / organizer".
48
+ */
49
+ export declare function eventJsonLd(events: Agenda["events"], bedrijf?: {
50
+ name?: string;
51
+ url?: string;
52
+ address?: string;
53
+ }): Record<string, unknown>;
32
54
  /** Agenda/evenementen. Server-safe (geen client-state); `hidePast` filtert verlopen events. */
33
55
  export declare function AgendaRender({ block }: BlockRenderProps<Agenda>): import("react").JSX.Element | null;
34
56
  export {};
@@ -1,7 +1,40 @@
1
+ "use client";
1
2
  import { jsx, jsxs } from "react/jsx-runtime";
2
3
  import { jsonLdHtml } from "./jsonld.js";
4
+ import { useVandaag } from "./lib/vandaag.js";
3
5
  import { Heading } from "../ui/index.js";
4
6
  import { icsDataUrl } from "./lib/ics.js";
7
+ import { useMergedSiteConfig } from "../../settings/useSiteSettings.js";
8
+ import { adresRegels } from "../../bedrijf/bedrijf.js";
9
+ function verschuif(waarde, dagen, maanden) {
10
+ const metTijd = waarde.includes("T");
11
+ const d = parseEventDate(waarde);
12
+ if (Number.isNaN(d.getTime())) return waarde;
13
+ d.setMonth(d.getMonth() + maanden);
14
+ d.setDate(d.getDate() + dagen);
15
+ const p = (n) => String(n).padStart(2, "0");
16
+ const datum = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
17
+ return metTijd ? `${datum}T${p(d.getHours())}:${p(d.getMinutes())}` : datum;
18
+ }
19
+ function vouwHerhalingenUit(events, vanaf = /* @__PURE__ */ new Date()) {
20
+ const uit = [];
21
+ for (const e of events) {
22
+ uit.push(e);
23
+ if (!e.herhaal || !e.start) continue;
24
+ const start = parseEventDate(e.start);
25
+ if (Number.isNaN(start.getTime())) continue;
26
+ const grens = e.herhaalTot ? parseEventDate(e.herhaalTot) : new Date(vanaf.getFullYear() + 1, vanaf.getMonth(), vanaf.getDate());
27
+ grens.setHours(23, 59, 59, 999);
28
+ for (let n = 1; n <= 60; n++) {
29
+ const dagen = e.herhaal === "wekelijks" ? 7 * n : e.herhaal === "tweewekelijks" ? 14 * n : 0;
30
+ const maanden = e.herhaal === "maandelijks" ? n : 0;
31
+ const volgendeStart = verschuif(e.start, dagen, maanden);
32
+ if (parseEventDate(volgendeStart) > grens) break;
33
+ uit.push({ ...e, start: volgendeStart, ...e.end ? { end: verschuif(e.end, dagen, maanden) } : {} });
34
+ }
35
+ }
36
+ return uit;
37
+ }
5
38
  function parseEventDate(value) {
6
39
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
7
40
  if (m) return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
@@ -21,9 +54,9 @@ function formatEventDate(value) {
21
54
  });
22
55
  }
23
56
  function selectAgendaEvents(events, opts = {}) {
24
- let list = (events ?? []).filter((e) => e.title);
25
- if (opts.hidePast) {
26
- const today = /* @__PURE__ */ new Date();
57
+ let list = vouwHerhalingenUit((events ?? []).filter((e) => e.title), opts.vandaag ?? void 0);
58
+ if (opts.hidePast && opts.vandaag !== null) {
59
+ const today = opts.vandaag ? new Date(opts.vandaag) : /* @__PURE__ */ new Date();
27
60
  today.setHours(0, 0, 0, 0);
28
61
  list = list.filter((e) => {
29
62
  const d = parseEventDate(e.end || e.start);
@@ -40,7 +73,17 @@ function selectAgendaEvents(events, opts = {}) {
40
73
  });
41
74
  return typeof opts.limit === "number" ? list.slice(0, opts.limit) : list;
42
75
  }
43
- function eventJsonLd(events) {
76
+ function eventJsonLd(events, bedrijf) {
77
+ const prijsGetal = (p) => {
78
+ if (!p) return void 0;
79
+ if (/gratis|vrij/i.test(p)) return 0;
80
+ const m = /(\d+(?:[.,]\d{1,2})?)/.exec(p.replace(/\s/g, ""));
81
+ return m ? Number(m[1].replace(",", ".")) : void 0;
82
+ };
83
+ const statusUrl = {
84
+ afgelast: "https://schema.org/EventCancelled",
85
+ verplaatst: "https://schema.org/EventRescheduled"
86
+ };
44
87
  return {
45
88
  "@context": "https://schema.org",
46
89
  "@type": "ItemList",
@@ -54,15 +97,27 @@ function eventJsonLd(events) {
54
97
  name: e.title,
55
98
  startDate: e.start,
56
99
  ...e.end ? { endDate: e.end } : {},
57
- location: { "@type": "Place", name: e.location },
100
+ eventStatus: statusUrl[e.status ?? ""] ?? "https://schema.org/EventScheduled",
101
+ eventAttendanceMode: e.status === "online" ? "https://schema.org/OnlineEventAttendanceMode" : "https://schema.org/OfflineEventAttendanceMode",
102
+ location: e.status === "online" ? { "@type": "VirtualLocation", url: e.url || bedrijf?.url || "" } : { "@type": "Place", name: e.location, ...e.address || bedrijf?.address ? { address: e.address || bedrijf?.address } : {} },
103
+ ...e.imageUrl ? { image: [e.imageUrl] } : {},
58
104
  ...e.description ? { description: e.description } : {},
59
- ...e.url ? { url: e.url } : {}
105
+ ...e.url ? { url: e.url } : {},
106
+ ...prijsGetal(e.price) !== void 0 ? { offers: { "@type": "Offer", price: prijsGetal(e.price).toFixed(2), priceCurrency: "EUR", availability: "https://schema.org/InStock", ...e.url ? { url: e.url } : {} } } : {},
107
+ ...bedrijf?.name ? { organizer: { "@type": "Organization", name: bedrijf.name, ...bedrijf.url ? { url: bedrijf.url } : {} } } : {}
60
108
  }
61
109
  }))
62
110
  };
63
111
  }
64
112
  function AgendaRender({ block }) {
65
- const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast });
113
+ const vandaag = useVandaag();
114
+ const cfg = useMergedSiteConfig();
115
+ const organisator = {
116
+ name: cfg.business?.name || cfg.name,
117
+ url: cfg.domain ? `https://${cfg.domain}` : void 0,
118
+ address: adresRegels(cfg.business).join(", ") || void 0
119
+ };
120
+ const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast, vandaag });
66
121
  if (events.length === 0) return null;
67
122
  return /* @__PURE__ */ jsxs("section", { className: "xicms-agenda", children: [
68
123
  block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
@@ -70,7 +125,10 @@ function AgendaRender({ block }) {
70
125
  /* @__PURE__ */ jsx("time", { className: "xicms-agenda__date", dateTime: e.start, children: formatEventDate(e.start) }),
71
126
  /* @__PURE__ */ jsxs("div", { className: "xicms-agenda__body", children: [
72
127
  /* @__PURE__ */ jsx("strong", { className: "xicms-agenda__title", children: e.url ? /* @__PURE__ */ jsx("a", { href: e.url, "data-xicms-edit": `events.${e._i}.title`, children: e.title }) : /* @__PURE__ */ jsx("span", { "data-xicms-edit": `events.${e._i}.title`, children: e.title }) }),
128
+ e.status === "afgelast" && /* @__PURE__ */ jsx("span", { className: "xicms-agenda__status", "data-status": "afgelast", children: "Afgelast" }),
129
+ e.status === "verplaatst" && /* @__PURE__ */ jsx("span", { className: "xicms-agenda__status", "data-status": "verplaatst", children: "Verplaatst" }),
73
130
  e.location && /* @__PURE__ */ jsx("span", { className: "xicms-agenda__location", "data-xicms-edit": `events.${e._i}.location`, children: e.location }),
131
+ e.price && /* @__PURE__ */ jsx("span", { className: "xicms-agenda__prijs", "data-xicms-edit": `events.${e._i}.price`, children: e.price }),
74
132
  e.description && /* @__PURE__ */ jsx("p", { className: "xicms-agenda__desc", "data-xicms-edit": `events.${e._i}.description`, children: e.description }),
75
133
  (() => {
76
134
  const ics = icsDataUrl(e);
@@ -82,15 +140,17 @@ function AgendaRender({ block }) {
82
140
  "script",
83
141
  {
84
142
  type: "application/ld+json",
85
- dangerouslySetInnerHTML: { __html: jsonLdHtml(eventJsonLd(events)) }
143
+ dangerouslySetInnerHTML: { __html: jsonLdHtml(eventJsonLd(events, organisator)) }
86
144
  }
87
145
  )
88
146
  ] });
89
147
  }
90
148
  export {
91
149
  AgendaRender,
150
+ eventJsonLd,
92
151
  formatEventDate,
93
152
  parseEventDate,
94
- selectAgendaEvents
153
+ selectAgendaEvents,
154
+ vouwHerhalingenUit
95
155
  };
96
156
  //# sourceMappingURL=AgendaRender.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/AgendaRender.tsx"],"sourcesContent":["import type { z } from \"zod\";\nimport { jsonLdHtml } from \"./jsonld\";\nimport type { AgendaBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Heading } from \"../ui\";\nimport { icsDataUrl } from \"./lib/ics\";\n\ntype Agenda = z.infer<typeof AgendaBlockSchema>;\n\n/** Eén event zoals zowel het Agenda-blok als de Agenda-widget het kennen. */\nexport interface AgendaEvent {\n title: string;\n start: string;\n end?: string;\n location?: string;\n description?: string;\n url?: string;\n}\n\n/**\n * Parseert een event-datum als LOKALE tijd. Cruciaal voor datum-zonder-tijd: `new Date(\"2026-08-01\")`\n * is per spec UTC-middernacht, waardoor west-van-UTC-bezoekers \"31 juli\" te zien kregen (en de\n * server/client bij hydration konden verschillen). \"2026-08-01\" is hier gewoon 1 augustus, overal.\n */\nexport function parseEventDate(value: string): Date {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value.trim());\n if (m) return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));\n return new Date(value);\n}\n\n/** Toont een datum leesbaar (nl-NL). Valt terug op de ruwe string bij ongeldige invoer. */\nexport function formatEventDate(value: string): string {\n if (!value) return \"\";\n const d = parseEventDate(value);\n if (Number.isNaN(d.getTime())) return value;\n const hasTime = value.includes(\"T\");\n return d.toLocaleDateString(\"nl-NL\", {\n weekday: \"short\",\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n ...(hasTime ? { hour: \"2-digit\", minute: \"2-digit\" } : {}),\n });\n}\n\n/**\n * Selecteert de te tonen events: filtert lege titels, optioneel verlopen events, sorteert\n * chronologisch (events zonder geldige datum achteraan, in invoervolgorde) en limiteert. Gedeeld\n * door het volwaardige Agenda-blok en de compacte Agenda-widget — zo \"haalt\" de widget alles\n * uit dezelfde logica als de volledige versie.\n */\nexport function selectAgendaEvents<T extends AgendaEvent>(\n events: T[] | undefined,\n opts: { hidePast?: boolean; limit?: number } = {},\n): T[] {\n let list = (events ?? []).filter((e) => e.title);\n if (opts.hidePast) {\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n list = list.filter((e) => {\n const d = parseEventDate(e.end || e.start);\n return Number.isNaN(d.getTime()) || d >= today;\n });\n }\n list = [...list].sort((a, b) => {\n const ta = parseEventDate(a.start).getTime();\n const tb = parseEventDate(b.start).getTime();\n if (Number.isNaN(ta) && Number.isNaN(tb)) return 0;\n if (Number.isNaN(ta)) return 1;\n if (Number.isNaN(tb)) return -1;\n return ta - tb;\n });\n return typeof opts.limit === \"number\" ? list.slice(0, opts.limit) : list;\n}\n\nfunction eventJsonLd(events: Agenda[\"events\"]): Record<string, unknown> {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"ItemList\",\n // Google vereist `location` voor Event-rich-results: events zonder locatie renderen wel op\n // de pagina, maar blijven uit de JSON-LD (voorkomt gegarandeerde Search-Console-errors).\n itemListElement: events\n .filter((e) => e.title && e.start && e.location)\n .map((e, i) => ({\n \"@type\": \"ListItem\",\n position: i + 1,\n item: {\n \"@type\": \"Event\",\n name: e.title,\n startDate: e.start,\n ...(e.end ? { endDate: e.end } : {}),\n location: { \"@type\": \"Place\", name: e.location },\n ...(e.description ? { description: e.description } : {}),\n ...(e.url ? { url: e.url } : {}),\n },\n })),\n };\n}\n\n/** Agenda/evenementen. Server-safe (geen client-state); `hidePast` filtert verlopen events. */\nexport function AgendaRender({ block }: BlockRenderProps<Agenda>) {\n const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast });\n if (events.length === 0) return null;\n\n return (\n <section className=\"xicms-agenda\">\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n <ul className=\"xicms-agenda__list\">\n {events.map((e) => (\n <li key={e._i} className=\"xicms-agenda__item\">\n <time className=\"xicms-agenda__date\" dateTime={e.start}>\n {formatEventDate(e.start)}\n </time>\n <div className=\"xicms-agenda__body\">\n <strong className=\"xicms-agenda__title\">\n {e.url\n ? <a href={e.url} data-xicms-edit={`events.${e._i}.title`}>{e.title}</a>\n : <span data-xicms-edit={`events.${e._i}.title`}>{e.title}</span>}\n </strong>\n {e.location && <span className=\"xicms-agenda__location\" data-xicms-edit={`events.${e._i}.location`}>{e.location}</span>}\n {e.description && <p className=\"xicms-agenda__desc\" data-xicms-edit={`events.${e._i}.description`}>{e.description}</p>}\n {(() => {\n const ics = icsDataUrl(e);\n return ics ? (\n <a className=\"xicms-agenda__ics\" href={ics} download={`${(e.title || \"evenement\").toLowerCase().replace(/\\s+/g, \"-\").slice(0, 40)}.ics`}>\n 📅 Zet in agenda\n </a>\n ) : null;\n })()}\n </div>\n </li>\n ))}\n </ul>\n {block.jsonLd && (\n <script\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: jsonLdHtml(eventJsonLd(events)) }}\n />\n )}\n </section>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/AgendaRender.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport { jsonLdHtml } from \"./jsonld\";\nimport { useVandaag } from \"./lib/vandaag\";\nimport type { AgendaBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Heading } from \"../ui\";\nimport { icsDataUrl } from \"./lib/ics\";\nimport { useMergedSiteConfig } from \"../../settings/useSiteSettings\";\nimport { adresRegels } from \"../../bedrijf/bedrijf\";\n\ntype Agenda = z.infer<typeof AgendaBlockSchema>;\n\n/** Eén event zoals zowel het Agenda-blok als de Agenda-widget het kennen. */\nexport interface AgendaEvent {\n title: string;\n start: string;\n end?: string;\n location?: string;\n description?: string;\n url?: string;\n /** 8.15: terugkerend. */\n herhaal?: \"wekelijks\" | \"tweewekelijks\" | \"maandelijks\";\n /** Laatste datum van de herhaling (\"2027-06-30\"); leeg = een jaar vooruit. */\n herhaalTot?: string;\n}\n\n/** ISO-string met dezelfde vorm als het origineel (alleen datum, of datum + tijd), verschoven. */\nfunction verschuif(waarde: string, dagen: number, maanden: number): string {\n const metTijd = waarde.includes(\"T\");\n const d = parseEventDate(waarde);\n if (Number.isNaN(d.getTime())) return waarde;\n d.setMonth(d.getMonth() + maanden);\n d.setDate(d.getDate() + dagen);\n const p = (n: number) => String(n).padStart(2, \"0\");\n const datum = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n return metTijd ? `${datum}T${p(d.getHours())}:${p(d.getMinutes())}` : datum;\n}\n\n/**\n * Terugkerende activiteiten uitvouwen (8.15): \"elke dinsdag koor\" staat één keer in het beheer en\n * verschijnt op de site als losse data — tot de einddatum, anders een jaar vooruit, en nooit meer\n * dan 60 keer. Elke herhaling houdt de index van het origineel (`_i`), dus bewerken op de pagina\n * past de reeks aan.\n */\nexport function vouwHerhalingenUit<T extends AgendaEvent>(events: T[], vanaf: Date = new Date()): T[] {\n const uit: T[] = [];\n for (const e of events) {\n uit.push(e);\n if (!e.herhaal || !e.start) continue;\n const start = parseEventDate(e.start);\n if (Number.isNaN(start.getTime())) continue;\n const grens = e.herhaalTot ? parseEventDate(e.herhaalTot) : new Date(vanaf.getFullYear() + 1, vanaf.getMonth(), vanaf.getDate());\n grens.setHours(23, 59, 59, 999);\n for (let n = 1; n <= 60; n++) {\n const dagen = e.herhaal === \"wekelijks\" ? 7 * n : e.herhaal === \"tweewekelijks\" ? 14 * n : 0;\n const maanden = e.herhaal === \"maandelijks\" ? n : 0;\n const volgendeStart = verschuif(e.start, dagen, maanden);\n if (parseEventDate(volgendeStart) > grens) break;\n uit.push({ ...e, start: volgendeStart, ...(e.end ? { end: verschuif(e.end, dagen, maanden) } : {}) });\n }\n }\n return uit;\n}\n\n/**\n * Parseert een event-datum als LOKALE tijd. Cruciaal voor datum-zonder-tijd: `new Date(\"2026-08-01\")`\n * is per spec UTC-middernacht, waardoor west-van-UTC-bezoekers \"31 juli\" te zien kregen (en de\n * server/client bij hydration konden verschillen). \"2026-08-01\" is hier gewoon 1 augustus, overal.\n */\nexport function parseEventDate(value: string): Date {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value.trim());\n if (m) return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));\n return new Date(value);\n}\n\n/** Toont een datum leesbaar (nl-NL). Valt terug op de ruwe string bij ongeldige invoer. */\nexport function formatEventDate(value: string): string {\n if (!value) return \"\";\n const d = parseEventDate(value);\n if (Number.isNaN(d.getTime())) return value;\n const hasTime = value.includes(\"T\");\n return d.toLocaleDateString(\"nl-NL\", {\n weekday: \"short\",\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n ...(hasTime ? { hour: \"2-digit\", minute: \"2-digit\" } : {}),\n });\n}\n\n/**\n * Selecteert de te tonen events: filtert lege titels, optioneel verlopen events, sorteert\n * chronologisch (events zonder geldige datum achteraan, in invoervolgorde) en limiteert. Gedeeld\n * door het volwaardige Agenda-blok en de compacte Agenda-widget — zo \"haalt\" de widget alles\n * uit dezelfde logica als de volledige versie.\n */\nexport function selectAgendaEvents<T extends AgendaEvent>(\n events: T[] | undefined,\n opts: { hidePast?: boolean; limit?: number; vandaag?: Date | null } = {},\n): T[] {\n let list = vouwHerhalingenUit((events ?? []).filter((e) => e.title), opts.vandaag ?? undefined);\n // `vandaag: null` = server-render/hydratie (zie useVandaag): dan nog niet op datum filteren.\n if (opts.hidePast && opts.vandaag !== null) {\n const today = opts.vandaag ? new Date(opts.vandaag) : new Date();\n today.setHours(0, 0, 0, 0);\n list = list.filter((e) => {\n const d = parseEventDate(e.end || e.start);\n return Number.isNaN(d.getTime()) || d >= today;\n });\n }\n list = [...list].sort((a, b) => {\n const ta = parseEventDate(a.start).getTime();\n const tb = parseEventDate(b.start).getTime();\n if (Number.isNaN(ta) && Number.isNaN(tb)) return 0;\n if (Number.isNaN(ta)) return 1;\n if (Number.isNaN(tb)) return -1;\n return ta - tb;\n });\n return typeof opts.limit === \"number\" ? list.slice(0, opts.limit) : list;\n}\n\n/**\n * Event-JSON-LD (8.14 vollediger): adres (eigen adres of dat uit het bedrijfsprofiel), afbeelding,\n * prijs, status (afgelast/verplaatst/online) en de organisator. Google vroeg in Search Console bij\n * de oude versie om \"ontbrekend veld: address / image / offers / organizer\".\n */\nexport function eventJsonLd(\n events: Agenda[\"events\"],\n bedrijf?: { name?: string; url?: string; address?: string },\n): Record<string, unknown> {\n const prijsGetal = (p?: string) => {\n if (!p) return undefined;\n if (/gratis|vrij/i.test(p)) return 0;\n const m = /(\\d+(?:[.,]\\d{1,2})?)/.exec(p.replace(/\\s/g, \"\"));\n return m ? Number(m[1].replace(\",\", \".\")) : undefined;\n };\n const statusUrl: Record<string, string> = {\n afgelast: \"https://schema.org/EventCancelled\",\n verplaatst: \"https://schema.org/EventRescheduled\",\n };\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"ItemList\",\n // Google vereist `location` voor Event-rich-results: events zonder locatie renderen wel op\n // de pagina, maar blijven uit de JSON-LD (voorkomt gegarandeerde Search-Console-errors).\n itemListElement: events\n .filter((e) => e.title && e.start && e.location)\n .map((e, i) => ({\n \"@type\": \"ListItem\",\n position: i + 1,\n item: {\n \"@type\": \"Event\",\n name: e.title,\n startDate: e.start,\n ...(e.end ? { endDate: e.end } : {}),\n eventStatus: statusUrl[e.status ?? \"\"] ?? \"https://schema.org/EventScheduled\",\n eventAttendanceMode: e.status === \"online\" ? \"https://schema.org/OnlineEventAttendanceMode\" : \"https://schema.org/OfflineEventAttendanceMode\",\n location:\n e.status === \"online\"\n ? { \"@type\": \"VirtualLocation\", url: e.url || bedrijf?.url || \"\" }\n : { \"@type\": \"Place\", name: e.location, ...((e.address || bedrijf?.address) ? { address: e.address || bedrijf?.address } : {}) },\n ...(e.imageUrl ? { image: [e.imageUrl] } : {}),\n ...(e.description ? { description: e.description } : {}),\n ...(e.url ? { url: e.url } : {}),\n ...(prijsGetal(e.price) !== undefined\n ? { offers: { \"@type\": \"Offer\", price: prijsGetal(e.price)!.toFixed(2), priceCurrency: \"EUR\", availability: \"https://schema.org/InStock\", ...(e.url ? { url: e.url } : {}) } }\n : {}),\n ...(bedrijf?.name ? { organizer: { \"@type\": \"Organization\", name: bedrijf.name, ...(bedrijf.url ? { url: bedrijf.url } : {}) } } : {}),\n },\n })),\n };\n}\n\n/** Agenda/evenementen. Server-safe (geen client-state); `hidePast` filtert verlopen events. */\nexport function AgendaRender({ block }: BlockRenderProps<Agenda>) {\n // Client-component (8.1): \"verlopen verbergen\" filtert op de datum van de bezoeker, en dat moet\n // hydratie-veilig (zie useVandaag) — de server-HTML kan een dag oud zijn.\n const vandaag = useVandaag();\n const cfg = useMergedSiteConfig();\n const organisator = {\n name: cfg.business?.name || cfg.name,\n url: cfg.domain ? `https://${cfg.domain}` : undefined,\n address: adresRegels(cfg.business).join(\", \") || undefined,\n };\n const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast, vandaag });\n if (events.length === 0) return null;\n\n return (\n <section className=\"xicms-agenda\">\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n <ul className=\"xicms-agenda__list\">\n {events.map((e) => (\n <li key={e._i} className=\"xicms-agenda__item\">\n <time className=\"xicms-agenda__date\" dateTime={e.start}>\n {formatEventDate(e.start)}\n </time>\n <div className=\"xicms-agenda__body\">\n <strong className=\"xicms-agenda__title\">\n {e.url\n ? <a href={e.url} data-xicms-edit={`events.${e._i}.title`}>{e.title}</a>\n : <span data-xicms-edit={`events.${e._i}.title`}>{e.title}</span>}\n </strong>\n {e.status === \"afgelast\" && <span className=\"xicms-agenda__status\" data-status=\"afgelast\">Afgelast</span>}\n {e.status === \"verplaatst\" && <span className=\"xicms-agenda__status\" data-status=\"verplaatst\">Verplaatst</span>}\n {e.location && <span className=\"xicms-agenda__location\" data-xicms-edit={`events.${e._i}.location`}>{e.location}</span>}\n {e.price && <span className=\"xicms-agenda__prijs\" data-xicms-edit={`events.${e._i}.price`}>{e.price}</span>}\n {e.description && <p className=\"xicms-agenda__desc\" data-xicms-edit={`events.${e._i}.description`}>{e.description}</p>}\n {(() => {\n const ics = icsDataUrl(e);\n return ics ? (\n <a className=\"xicms-agenda__ics\" href={ics} download={`${(e.title || \"evenement\").toLowerCase().replace(/\\s+/g, \"-\").slice(0, 40)}.ics`}>\n 📅 Zet in agenda\n </a>\n ) : null;\n })()}\n </div>\n </li>\n ))}\n </ul>\n {block.jsonLd && (\n <script\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: jsonLdHtml(eventJsonLd(events, organisator)) }}\n />\n )}\n </section>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1 @@
1
+ export declare const availabilityBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -0,0 +1,23 @@
1
+ import dynamic from "next/dynamic";
2
+ import { defineBlock } from "../registry.js";
3
+ const availabilityBlock = defineBlock({
4
+ type: "availability",
5
+ Render: dynamic(() => import("./AvailabilityRender.js").then((m) => m.AvailabilityRender)),
6
+ label: "Beschikbaarheid",
7
+ icon: "\u{1F4C5}",
8
+ fields: { "units.icalUrl": { type: "url", hint: "De iCal-export van je boekingssysteem (Airbnb, Booking.com, availcalendar \u2026): begint met https:// of webcal://." } },
9
+ defaults: () => ({
10
+ heading: "Beschikbaarheid",
11
+ units: [{ label: "Ons verblijf", icalUrl: "" }],
12
+ months: 4,
13
+ minNights: 2,
14
+ requestPath: "/contact",
15
+ requestLabel: "Aanvragen",
16
+ periodField: "verblijf",
17
+ unitField: "accommodatie"
18
+ })
19
+ });
20
+ export {
21
+ availabilityBlock
22
+ };
23
+ //# sourceMappingURL=Availability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Availability.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const availabilityBlock = defineBlock({\n type: \"availability\",\n Render: dynamic(() => import(\"./AvailabilityRender\").then((m) => m.AvailabilityRender)),\n label: \"Beschikbaarheid\",\n icon: \"📅\",\n fields: { \"units.icalUrl\": { type: \"url\", hint: \"De iCal-export van je boekingssysteem (Airbnb, Booking.com, availcalendar …): begint met https:// of webcal://.\" } },\n defaults: () => ({\n heading: \"Beschikbaarheid\",\n units: [{ label: \"Ons verblijf\", icalUrl: \"\" }],\n months: 4,\n minNights: 2,\n requestPath: \"/contact\",\n requestLabel: \"Aanvragen\",\n periodField: \"verblijf\",\n unitField: \"accommodatie\",\n }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,oBAAoB,YAAY;AAAA,EAC3C,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC;AAAA,EACtF,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ,EAAE,iBAAiB,EAAE,MAAM,OAAO,MAAM,uHAAkH,EAAE;AAAA,EACpK,UAAU,OAAO;AAAA,IACf,SAAS;AAAA,IACT,OAAO,CAAC,EAAE,OAAO,gBAAgB,SAAS,GAAG,CAAC;AAAA,IAC9C,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,aAAa;AAAA,IACb,cAAc;AAAA,IACd,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF,CAAC;","names":[]}
@@ -0,0 +1,12 @@
1
+ import type { z } from "zod";
2
+ import type { AvailabilityBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type Beschikbaarheid = z.infer<typeof AvailabilityBlockSchema>;
5
+ /**
6
+ * Beschikbaarheidskalender (8.15). De bezette nachten komen van de server (seed "beschikbaarheid",
7
+ * per iCal-link, een uur gecachet); zonder seed toont de kalender alles als vrij met een eerlijke
8
+ * melding. Klik een aankomstdag en een vertrekdag; "Aanvragen" opent het formulier met
9
+ * `?verblijf=van/tot&accommodatie=…`, dat de velden "Periode" en "Verborgen" (8.14) invullen.
10
+ */
11
+ export declare function AvailabilityRender({ block, mode }: BlockRenderProps<Beschikbaarheid>): import("react").JSX.Element | null;
12
+ export {};
@@ -0,0 +1,105 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useMemo, useState } from "react";
4
+ import { useBlockData } from "../context.js";
5
+ import { Btn, Heading } from "../ui/index.js";
6
+ import { isBezet, maandRaster, periodeVrij } from "./lib/ical.js";
7
+ import { useVandaag } from "./lib/vandaag.js";
8
+ import { isoDatum } from "../../bedrijf/bedrijf.js";
9
+ const DAGEN = ["ma", "di", "wo", "do", "vr", "za", "zo"];
10
+ function nachten(van, tot) {
11
+ return Math.round((Date.parse(tot) - Date.parse(van)) / 864e5);
12
+ }
13
+ function mooi(iso) {
14
+ const [j, m, d] = iso.split("-").map(Number);
15
+ return new Date(j, m - 1, d).toLocaleDateString("nl-NL", { weekday: "short", day: "numeric", month: "short" });
16
+ }
17
+ function AvailabilityRender({ block, mode }) {
18
+ const seed = useBlockData("beschikbaarheid");
19
+ const units = (block.units ?? []).filter((u) => u.label || u.icalUrl);
20
+ const [actief, setActief] = useState(0);
21
+ const [van, setVan] = useState(null);
22
+ const [tot, setTot] = useState(null);
23
+ const vandaagDatum = useVandaag();
24
+ const vandaagIso = vandaagDatum ? isoDatum(vandaagDatum) : null;
25
+ const unit = units[Math.min(actief, Math.max(units.length - 1, 0))];
26
+ const bezet = unit?.icalUrl ? seed?.[unit.icalUrl] : void 0;
27
+ const onbekend = Boolean(unit?.icalUrl) && !Array.isArray(bezet);
28
+ const maanden = useMemo(() => {
29
+ const basis = vandaagDatum ?? /* @__PURE__ */ new Date();
30
+ return Array.from({ length: block.months ?? 4 }, (_, i) => {
31
+ const d = new Date(basis.getFullYear(), basis.getMonth() + i, 1);
32
+ return { jaar: d.getFullYear(), maand: d.getMonth(), naam: d.toLocaleDateString("nl-NL", { month: "long", year: "numeric" }) };
33
+ });
34
+ }, [vandaagDatum, block.months]);
35
+ if (units.length === 0) {
36
+ return mode === "preview" ? /* @__PURE__ */ jsx("p", { className: "xicms-ve__hint", children: "Beschikbaarheid: voeg een accommodatie toe met de iCal-link uit je boekingssysteem." }) : null;
37
+ }
38
+ const lijst = Array.isArray(bezet) ? bezet : [];
39
+ const vandaag = vandaagIso ?? "0000-00-00";
40
+ const kies = (dag) => {
41
+ if (!van || tot || dag <= van) {
42
+ setVan(isBezet(dag, lijst) ? null : dag);
43
+ setTot(null);
44
+ return;
45
+ }
46
+ setTot(dag);
47
+ };
48
+ const geldig = van && tot && periodeVrij(van, tot, lijst) && nachten(van, tot) >= (block.minNights ?? 1);
49
+ const link = van && tot ? `${block.requestPath || "/contact"}?${encodeURIComponent(block.periodField || "verblijf")}=${van}/${tot}&${encodeURIComponent(block.unitField || "accommodatie")}=${encodeURIComponent(unit?.label ?? "")}` : void 0;
50
+ return /* @__PURE__ */ jsxs("section", { className: "xicms-beschikbaar", children: [
51
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
52
+ block.intro && /* @__PURE__ */ jsx("p", { className: "xicms-beschikbaar__intro", "data-xicms-edit": "intro", children: block.intro }),
53
+ units.length > 1 && /* @__PURE__ */ jsx("div", { className: "xicms-beschikbaar__tabs", role: "tablist", "aria-label": "Accommodatie", children: units.map((u, i) => /* @__PURE__ */ jsx("button", { type: "button", role: "tab", "aria-selected": i === actief, onClick: () => {
54
+ setActief(i);
55
+ setVan(null);
56
+ setTot(null);
57
+ }, children: u.label || `Accommodatie ${i + 1}` }, i)) }),
58
+ unit?.note && /* @__PURE__ */ jsx("p", { className: "xicms-beschikbaar__noot", children: unit.note }),
59
+ onbekend && /* @__PURE__ */ jsx("p", { className: "xicms-beschikbaar__melding", role: "status", children: "De actuele bezetting kon niet worden geladen. Vraag gerust aan \u2014 we laten snel weten of het past." }),
60
+ /* @__PURE__ */ jsx("div", { className: "xicms-beschikbaar__maanden", children: maanden.map((m) => /* @__PURE__ */ jsxs("div", { className: "xicms-beschikbaar__maand", children: [
61
+ /* @__PURE__ */ jsx("p", { className: "xicms-beschikbaar__maandnaam", children: m.naam }),
62
+ /* @__PURE__ */ jsxs("table", { children: [
63
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: DAGEN.map((d) => /* @__PURE__ */ jsx("th", { scope: "col", children: d }, d)) }) }),
64
+ /* @__PURE__ */ jsx("tbody", { children: maandRaster(m.jaar, m.maand).map((week, wi) => /* @__PURE__ */ jsx("tr", { children: week.map((dag, di) => {
65
+ if (!dag) return /* @__PURE__ */ jsx("td", {}, di);
66
+ const verleden = dag < vandaag;
67
+ const vol = isBezet(dag, lijst);
68
+ const gekozen = van && (dag === van || tot && dag >= van && dag < tot || dag === tot);
69
+ return /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(
70
+ "button",
71
+ {
72
+ type: "button",
73
+ disabled: verleden || vol && !(van && !tot && dag > van),
74
+ "data-status": verleden ? "voorbij" : vol ? "bezet" : "vrij",
75
+ "data-gekozen": gekozen ? "1" : void 0,
76
+ "aria-label": `${mooi(dag)}${vol ? ", bezet" : ", vrij"}`,
77
+ "aria-pressed": Boolean(gekozen),
78
+ onClick: () => kies(dag),
79
+ children: Number(dag.slice(8))
80
+ }
81
+ ) }, di);
82
+ }) }, wi)) })
83
+ ] })
84
+ ] }, `${m.jaar}-${m.maand}`)) }),
85
+ /* @__PURE__ */ jsxs("div", { className: "xicms-beschikbaar__voet", children: [
86
+ /* @__PURE__ */ jsxs("span", { className: "xicms-beschikbaar__legenda", children: [
87
+ /* @__PURE__ */ jsx("i", { "data-status": "vrij" }),
88
+ " vrij ",
89
+ /* @__PURE__ */ jsx("i", { "data-status": "bezet" }),
90
+ " bezet"
91
+ ] }),
92
+ /* @__PURE__ */ jsxs("span", { className: "xicms-beschikbaar__keuze", "aria-live": "polite", children: [
93
+ !van && "Kies je aankomstdag.",
94
+ van && !tot && `Aankomst ${mooi(van)} \u2014 kies je vertrekdag.`,
95
+ van && tot && !geldig && (periodeVrij(van, tot, lijst) ? `Minimaal ${block.minNights} ${block.minNights === 1 ? "nacht" : "nachten"}.` : "In deze periode is het al bezet. Kies andere data."),
96
+ van && tot && geldig && `${mooi(van)} \u2013 ${mooi(tot)} \xB7 ${nachten(van, tot)} ${nachten(van, tot) === 1 ? "nacht" : "nachten"}`
97
+ ] }),
98
+ geldig && link && /* @__PURE__ */ jsx(Btn, { label: block.requestLabel || "Aanvragen", href: link, size: "md" })
99
+ ] })
100
+ ] });
101
+ }
102
+ export {
103
+ AvailabilityRender
104
+ };
105
+ //# sourceMappingURL=AvailabilityRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/AvailabilityRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { AvailabilityBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { useBlockData } from \"../context\";\nimport { Btn, Heading } from \"../ui\";\nimport { isBezet, maandRaster, periodeVrij, type Bezet } from \"./lib/ical\";\nimport { useVandaag } from \"./lib/vandaag\";\nimport { isoDatum } from \"../../bedrijf/bedrijf\";\n\ntype Beschikbaarheid = z.infer<typeof AvailabilityBlockSchema>;\n\nconst DAGEN = [\"ma\", \"di\", \"wo\", \"do\", \"vr\", \"za\", \"zo\"];\n\nfunction nachten(van: string, tot: string): number {\n return Math.round((Date.parse(tot) - Date.parse(van)) / 86_400_000);\n}\n\nfunction mooi(iso: string): string {\n const [j, m, d] = iso.split(\"-\").map(Number);\n return new Date(j, m - 1, d).toLocaleDateString(\"nl-NL\", { weekday: \"short\", day: \"numeric\", month: \"short\" });\n}\n\n/**\n * Beschikbaarheidskalender (8.15). De bezette nachten komen van de server (seed \"beschikbaarheid\",\n * per iCal-link, een uur gecachet); zonder seed toont de kalender alles als vrij met een eerlijke\n * melding. Klik een aankomstdag en een vertrekdag; \"Aanvragen\" opent het formulier met\n * `?verblijf=van/tot&accommodatie=…`, dat de velden \"Periode\" en \"Verborgen\" (8.14) invullen.\n */\nexport function AvailabilityRender({ block, mode }: BlockRenderProps<Beschikbaarheid>) {\n const seed = useBlockData<Record<string, Bezet[] | null>>(\"beschikbaarheid\");\n const units = (block.units ?? []).filter((u) => u.label || u.icalUrl);\n const [actief, setActief] = useState(0);\n const [van, setVan] = useState<string | null>(null);\n const [tot, setTot] = useState<string | null>(null);\n // Null tijdens server-render en hydratie (zie useVandaag): dan nog geen dagen als \"voorbij\".\n const vandaagDatum = useVandaag();\n const vandaagIso = vandaagDatum ? isoDatum(vandaagDatum) : null;\n const unit = units[Math.min(actief, Math.max(units.length - 1, 0))];\n const bezet = unit?.icalUrl ? seed?.[unit.icalUrl] : undefined;\n const onbekend = Boolean(unit?.icalUrl) && !Array.isArray(bezet);\n\n const maanden = useMemo(() => {\n const basis = vandaagDatum ?? new Date();\n return Array.from({ length: block.months ?? 4 }, (_, i) => {\n const d = new Date(basis.getFullYear(), basis.getMonth() + i, 1);\n return { jaar: d.getFullYear(), maand: d.getMonth(), naam: d.toLocaleDateString(\"nl-NL\", { month: \"long\", year: \"numeric\" }) };\n });\n }, [vandaagDatum, block.months]);\n\n if (units.length === 0) {\n return mode === \"preview\" ? <p className=\"xicms-ve__hint\">Beschikbaarheid: voeg een accommodatie toe met de iCal-link uit je boekingssysteem.</p> : null;\n }\n\n const lijst = Array.isArray(bezet) ? bezet : [];\n const vandaag = vandaagIso ?? \"0000-00-00\";\n const kies = (dag: string) => {\n if (!van || tot || dag <= van) {\n setVan(isBezet(dag, lijst) ? null : dag);\n setTot(null);\n return;\n }\n setTot(dag);\n };\n const geldig = van && tot && periodeVrij(van, tot, lijst) && nachten(van, tot) >= (block.minNights ?? 1);\n const link = van && tot\n ? `${block.requestPath || \"/contact\"}?${encodeURIComponent(block.periodField || \"verblijf\")}=${van}/${tot}&${encodeURIComponent(block.unitField || \"accommodatie\")}=${encodeURIComponent(unit?.label ?? \"\")}`\n : undefined;\n\n return (\n <section className=\"xicms-beschikbaar\">\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n {block.intro && <p className=\"xicms-beschikbaar__intro\" data-xicms-edit=\"intro\">{block.intro}</p>}\n {units.length > 1 && (\n <div className=\"xicms-beschikbaar__tabs\" role=\"tablist\" aria-label=\"Accommodatie\">\n {units.map((u, i) => (\n <button key={i} type=\"button\" role=\"tab\" aria-selected={i === actief} onClick={() => { setActief(i); setVan(null); setTot(null); }}>\n {u.label || `Accommodatie ${i + 1}`}\n </button>\n ))}\n </div>\n )}\n {unit?.note && <p className=\"xicms-beschikbaar__noot\">{unit.note}</p>}\n {onbekend && (\n <p className=\"xicms-beschikbaar__melding\" role=\"status\">\n De actuele bezetting kon niet worden geladen. Vraag gerust aan — we laten snel weten of het past.\n </p>\n )}\n <div className=\"xicms-beschikbaar__maanden\">\n {maanden.map((m) => (\n <div key={`${m.jaar}-${m.maand}`} className=\"xicms-beschikbaar__maand\">\n <p className=\"xicms-beschikbaar__maandnaam\">{m.naam}</p>\n <table>\n <thead>\n <tr>{DAGEN.map((d) => <th key={d} scope=\"col\">{d}</th>)}</tr>\n </thead>\n <tbody>\n {maandRaster(m.jaar, m.maand).map((week, wi) => (\n <tr key={wi}>\n {week.map((dag, di) => {\n if (!dag) return <td key={di} />;\n const verleden = dag < vandaag;\n const vol = isBezet(dag, lijst);\n const gekozen = van && (dag === van || (tot && dag >= van && dag < tot) || dag === tot);\n return (\n <td key={di}>\n <button\n type=\"button\"\n disabled={verleden || (vol && !(van && !tot && dag > van))}\n data-status={verleden ? \"voorbij\" : vol ? \"bezet\" : \"vrij\"}\n data-gekozen={gekozen ? \"1\" : undefined}\n aria-label={`${mooi(dag)}${vol ? \", bezet\" : \", vrij\"}`}\n aria-pressed={Boolean(gekozen)}\n onClick={() => kies(dag)}\n >\n {Number(dag.slice(8))}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ))}\n </div>\n <div className=\"xicms-beschikbaar__voet\">\n <span className=\"xicms-beschikbaar__legenda\"><i data-status=\"vrij\" /> vrij <i data-status=\"bezet\" /> bezet</span>\n <span className=\"xicms-beschikbaar__keuze\" aria-live=\"polite\">\n {!van && \"Kies je aankomstdag.\"}\n {van && !tot && `Aankomst ${mooi(van)} — kies je vertrekdag.`}\n {van && tot && !geldig && (periodeVrij(van, tot, lijst)\n ? `Minimaal ${block.minNights} ${block.minNights === 1 ? \"nacht\" : \"nachten\"}.`\n : \"In deze periode is het al bezet. Kies andere data.\")}\n {van && tot && geldig && `${mooi(van)} – ${mooi(tot)} · ${nachten(van, tot)} ${nachten(van, tot) === 1 ? \"nacht\" : \"nachten\"}`}\n </span>\n {geldig && link && <Btn label={block.requestLabel || \"Aanvragen\"} href={link} size=\"md\" />}\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,14 +1,15 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
+ import { SeedImg } from "../../media/ImageContext.js";
4
5
  function BeforeAfterRender({ block }) {
5
6
  const [pos, setPos] = useState(50);
6
7
  if (!block.beforeUrl || !block.afterUrl) return null;
7
- return /* @__PURE__ */ jsxs("figure", { className: "xicms-beforeafter", style: { aspectRatio: block.aspectRatio.replace("/", " / ") }, children: [
8
+ return /* @__PURE__ */ jsxs("figure", { className: "xicms-beforeafter", style: { aspectRatio: (block.aspectRatio ?? "4/3").replace("/", " / ") }, children: [
8
9
  block.heading && /* @__PURE__ */ jsx("figcaption", { className: "xicms-beforeafter__heading", "data-xicms-edit": "heading", children: block.heading }),
9
10
  /* @__PURE__ */ jsxs("div", { className: "xicms-beforeafter__stage", children: [
10
- /* @__PURE__ */ jsx("img", { className: "xicms-beforeafter__img", src: block.beforeUrl, alt: block.alt || block.beforeLabel, loading: "lazy" }),
11
- /* @__PURE__ */ jsx("div", { className: "xicms-beforeafter__clip", style: { clipPath: `inset(0 0 0 ${pos}%)` }, "aria-hidden": true, children: /* @__PURE__ */ jsx("img", { className: "xicms-beforeafter__img", src: block.afterUrl, alt: "", loading: "lazy" }) }),
11
+ /* @__PURE__ */ jsx(SeedImg, { className: "xicms-beforeafter__img", src: block.beforeUrl, alt: block.alt || block.beforeLabel, sizes: "(max-width: 900px) 100vw, 900px" }),
12
+ /* @__PURE__ */ jsx("div", { className: "xicms-beforeafter__clip", style: { clipPath: `inset(0 0 0 ${pos}%)` }, "aria-hidden": true, children: /* @__PURE__ */ jsx(SeedImg, { className: "xicms-beforeafter__img", src: block.afterUrl, alt: "", sizes: "(max-width: 900px) 100vw, 900px" }) }),
12
13
  /* @__PURE__ */ jsx("div", { className: "xicms-beforeafter__divider", style: { left: `${pos}%` }, "aria-hidden": true, children: /* @__PURE__ */ jsx("span", { className: "xicms-beforeafter__handle", children: "\u27E8\u27E9" }) }),
13
14
  /* @__PURE__ */ jsx("span", { className: "xicms-beforeafter__badge xicms-beforeafter__badge--before", "data-xicms-edit": "beforeLabel", children: block.beforeLabel }),
14
15
  /* @__PURE__ */ jsx("span", { className: "xicms-beforeafter__badge xicms-beforeafter__badge--after", "data-xicms-edit": "afterLabel", children: block.afterLabel }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/BeforeAfterRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { BeforeAfterBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\n\ntype BeforeAfter = z.infer<typeof BeforeAfterBlockSchema>;\n\n/**\n * Voor/na-vergelijker: het \"na\"-beeld wordt geclipt op de sleppositie. De greep is een échte\n * range-input (over de hele breedte, transparant) — slepen, klikken én pijltjestoetsen werken\n * daarmee gratis en toegankelijk (aria-label + waarde in %).\n */\nexport function BeforeAfterRender({ block }: BlockRenderProps<BeforeAfter>) {\n const [pos, setPos] = useState(50);\n if (!block.beforeUrl || !block.afterUrl) return null;\n return (\n <figure className=\"xicms-beforeafter\" style={{ aspectRatio: block.aspectRatio.replace(\"/\", \" / \") }}>\n {block.heading && <figcaption className=\"xicms-beforeafter__heading\" data-xicms-edit=\"heading\">{block.heading}</figcaption>}\n <div className=\"xicms-beforeafter__stage\">\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img className=\"xicms-beforeafter__img\" src={block.beforeUrl} alt={block.alt || block.beforeLabel} loading=\"lazy\" />\n <div className=\"xicms-beforeafter__clip\" style={{ clipPath: `inset(0 0 0 ${pos}%)` }} aria-hidden>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img className=\"xicms-beforeafter__img\" src={block.afterUrl} alt=\"\" loading=\"lazy\" />\n </div>\n <div className=\"xicms-beforeafter__divider\" style={{ left: `${pos}%` }} aria-hidden>\n <span className=\"xicms-beforeafter__handle\">⟨⟩</span>\n </div>\n <span className=\"xicms-beforeafter__badge xicms-beforeafter__badge--before\" data-xicms-edit=\"beforeLabel\">{block.beforeLabel}</span>\n <span className=\"xicms-beforeafter__badge xicms-beforeafter__badge--after\" data-xicms-edit=\"afterLabel\">{block.afterLabel}</span>\n <input\n className=\"xicms-beforeafter__range\"\n type=\"range\"\n min={0}\n max={100}\n value={pos}\n onChange={(e) => setPos(Number(e.target.value))}\n aria-label={`Vergelijk ${block.beforeLabel} en ${block.afterLabel}`}\n aria-valuetext={`${pos}% ${block.afterLabel}`}\n />\n </div>\n </figure>\n );\n}\n"],"mappings":";AAmBwB,cAClB,YADkB;AAjBxB,SAAS,gBAAgB;AAYlB,SAAS,kBAAkB,EAAE,MAAM,GAAkC;AAC1E,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,EAAE;AACjC,MAAI,CAAC,MAAM,aAAa,CAAC,MAAM,SAAU,QAAO;AAChD,SACE,qBAAC,YAAO,WAAU,qBAAoB,OAAO,EAAE,aAAa,MAAM,YAAY,QAAQ,KAAK,KAAK,EAAE,GAC/F;AAAA,UAAM,WAAW,oBAAC,gBAAW,WAAU,8BAA6B,mBAAgB,WAAW,gBAAM,SAAQ;AAAA,IAC9G,qBAAC,SAAI,WAAU,4BAEb;AAAA,0BAAC,SAAI,WAAU,0BAAyB,KAAK,MAAM,WAAW,KAAK,MAAM,OAAO,MAAM,aAAa,SAAQ,QAAO;AAAA,MAClH,oBAAC,SAAI,WAAU,2BAA0B,OAAO,EAAE,UAAU,eAAe,GAAG,KAAK,GAAG,eAAW,MAE/F,8BAAC,SAAI,WAAU,0BAAyB,KAAK,MAAM,UAAU,KAAI,IAAG,SAAQ,QAAO,GACrF;AAAA,MACA,oBAAC,SAAI,WAAU,8BAA6B,OAAO,EAAE,MAAM,GAAG,GAAG,IAAI,GAAG,eAAW,MACjF,8BAAC,UAAK,WAAU,6BAA4B,0BAAE,GAChD;AAAA,MACA,oBAAC,UAAK,WAAU,6DAA4D,mBAAgB,eAAe,gBAAM,aAAY;AAAA,MAC7H,oBAAC,UAAK,WAAU,4DAA2D,mBAAgB,cAAc,gBAAM,YAAW;AAAA,MAC1H;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,UAC9C,cAAY,aAAa,MAAM,WAAW,OAAO,MAAM,UAAU;AAAA,UACjE,kBAAgB,GAAG,GAAG,KAAK,MAAM,UAAU;AAAA;AAAA,MAC7C;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/BeforeAfterRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { BeforeAfterBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { SeedImg } from \"../../media/ImageContext\";\n\ntype BeforeAfter = z.infer<typeof BeforeAfterBlockSchema>;\n\n/**\n * Voor/na-vergelijker: het \"na\"-beeld wordt geclipt op de sleppositie. De greep is een échte\n * range-input (over de hele breedte, transparant) — slepen, klikken én pijltjestoetsen werken\n * daarmee gratis en toegankelijk (aria-label + waarde in %).\n */\nexport function BeforeAfterRender({ block }: BlockRenderProps<BeforeAfter>) {\n const [pos, setPos] = useState(50);\n if (!block.beforeUrl || !block.afterUrl) return null;\n return (\n <figure className=\"xicms-beforeafter\" style={{ aspectRatio: (block.aspectRatio ?? \"4/3\").replace(\"/\", \" / \") }}>\n {block.heading && <figcaption className=\"xicms-beforeafter__heading\" data-xicms-edit=\"heading\">{block.heading}</figcaption>}\n <div className=\"xicms-beforeafter__stage\">\n <SeedImg className=\"xicms-beforeafter__img\" src={block.beforeUrl} alt={block.alt || block.beforeLabel} sizes=\"(max-width: 900px) 100vw, 900px\" />\n <div className=\"xicms-beforeafter__clip\" style={{ clipPath: `inset(0 0 0 ${pos}%)` }} aria-hidden>\n <SeedImg className=\"xicms-beforeafter__img\" src={block.afterUrl} alt=\"\" sizes=\"(max-width: 900px) 100vw, 900px\" />\n </div>\n <div className=\"xicms-beforeafter__divider\" style={{ left: `${pos}%` }} aria-hidden>\n <span className=\"xicms-beforeafter__handle\">⟨⟩</span>\n </div>\n <span className=\"xicms-beforeafter__badge xicms-beforeafter__badge--before\" data-xicms-edit=\"beforeLabel\">{block.beforeLabel}</span>\n <span className=\"xicms-beforeafter__badge xicms-beforeafter__badge--after\" data-xicms-edit=\"afterLabel\">{block.afterLabel}</span>\n <input\n className=\"xicms-beforeafter__range\"\n type=\"range\"\n min={0}\n max={100}\n value={pos}\n onChange={(e) => setPos(Number(e.target.value))}\n aria-label={`Vergelijk ${block.beforeLabel} en ${block.afterLabel}`}\n aria-valuetext={`${pos}% ${block.afterLabel}`}\n />\n </div>\n </figure>\n );\n}\n"],"mappings":";AAoBwB,cAClB,YADkB;AAlBxB,SAAS,gBAAgB;AAIzB,SAAS,eAAe;AASjB,SAAS,kBAAkB,EAAE,MAAM,GAAkC;AAC1E,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,EAAE;AACjC,MAAI,CAAC,MAAM,aAAa,CAAC,MAAM,SAAU,QAAO;AAChD,SACE,qBAAC,YAAO,WAAU,qBAAoB,OAAO,EAAE,cAAc,MAAM,eAAe,OAAO,QAAQ,KAAK,KAAK,EAAE,GAC1G;AAAA,UAAM,WAAW,oBAAC,gBAAW,WAAU,8BAA6B,mBAAgB,WAAW,gBAAM,SAAQ;AAAA,IAC9G,qBAAC,SAAI,WAAU,4BACb;AAAA,0BAAC,WAAQ,WAAU,0BAAyB,KAAK,MAAM,WAAW,KAAK,MAAM,OAAO,MAAM,aAAa,OAAM,mCAAkC;AAAA,MAC/I,oBAAC,SAAI,WAAU,2BAA0B,OAAO,EAAE,UAAU,eAAe,GAAG,KAAK,GAAG,eAAW,MAC/F,8BAAC,WAAQ,WAAU,0BAAyB,KAAK,MAAM,UAAU,KAAI,IAAG,OAAM,mCAAkC,GAClH;AAAA,MACA,oBAAC,SAAI,WAAU,8BAA6B,OAAO,EAAE,MAAM,GAAG,GAAG,IAAI,GAAG,eAAW,MACjF,8BAAC,UAAK,WAAU,6BAA4B,0BAAE,GAChD;AAAA,MACA,oBAAC,UAAK,WAAU,6DAA4D,mBAAgB,eAAe,gBAAM,aAAY;AAAA,MAC7H,oBAAC,UAAK,WAAU,4DAA2D,mBAAgB,cAAc,gBAAM,YAAW;AAAA,MAC1H;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,UAC9C,cAAY,aAAa,MAAM,WAAW,OAAO,MAAM,UAAU;AAAA,UACjE,kBAAgB,GAAG,GAAG,KAAK,MAAM,UAAU;AAAA;AAAA,MAC7C;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
@@ -3,7 +3,7 @@ import { defineBlock } from "../registry.js";
3
3
  const bookingBlock = defineBlock({
4
4
  type: "booking",
5
5
  Render: dynamic(() => import("./BookingRender.js").then((m) => m.BookingRender)),
6
- label: "Afspraak/booking",
6
+ label: "Afspraak maken",
7
7
  icon: "\u{1F4C6}",
8
8
  defaults: () => ({ embedUrl: "", height: 630, consentGated: true })
9
9
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/Booking.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const bookingBlock = defineBlock({\n type: \"booking\",\n Render: dynamic(() => import(\"./BookingRender\").then((m) => m.BookingRender)),\n label: \"Afspraak/booking\",\n icon: \"📆\",\n defaults: () => ({ embedUrl: \"\", height: 630, consentGated: true }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,eAAe,YAAY;AAAA,EACtC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC;AAAA,EAC5E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,UAAU,IAAI,QAAQ,KAAK,cAAc,KAAK;AACnE,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Booking.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const bookingBlock = defineBlock({\n type: \"booking\",\n Render: dynamic(() => import(\"./BookingRender\").then((m) => m.BookingRender)),\n label: \"Afspraak maken\",\n icon: \"📆\",\n defaults: () => ({ embedUrl: \"\", height: 630, consentGated: true }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,eAAe,YAAY;AAAA,EACtC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC;AAAA,EAC5E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,UAAU,IAAI,QAAQ,KAAK,cAAc,KAAK;AACnE,CAAC;","names":[]}
@@ -7,12 +7,13 @@ export interface Crumb {
7
7
  href: string;
8
8
  }
9
9
  /** Kruimels uit een pad: "/diensten/tuinaanleg" → Home / Diensten / Tuinaanleg. Puur en getest. */
10
- export declare function crumbsFromPath(path: string, homeLabel?: string): Crumb[];
10
+ export declare function crumbsFromPath(path: string, homeLabel?: string, titels?: Record<string, string>): Crumb[];
11
11
  /** BreadcrumbList-JSON-LD. Puur en getest. */
12
12
  export declare function breadcrumbsJsonLd(crumbs: Crumb[]): Record<string, unknown>;
13
13
  /**
14
- * Kruimelpad, afgeleid van de URL (client, ná mount — hydration-veilig). Op de homepage
15
- * (alleen "Home") wordt niets getoond.
14
+ * Kruimelpad. Sinds 8.3 server-side uit de seed (pad + paginatitels, zie server/blockData.ts);
15
+ * zonder seed (editor, oudere site) zoals vroeger: uit de URL, ná mount — hydratie-veilig.
16
+ * Op de homepage (alleen "Home") wordt niets getoond.
16
17
  */
17
18
  export declare function BreadcrumbsRender({ block, mode }: BlockRenderProps<Breadcrumbs>): import("react").JSX.Element | null;
18
19
  export {};