@xiwebdesign/xicms-core 4.17.1 → 5.0.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 (169) hide show
  1. package/dist/XiCMSProvider.d.ts +7 -0
  2. package/dist/XiCMSProvider.js +32 -7
  3. package/dist/XiCMSProvider.js.map +1 -1
  4. package/dist/admin/blockEditors/GenericEditor.d.ts +22 -0
  5. package/dist/admin/blockEditors/GenericEditor.js +201 -0
  6. package/dist/admin/blockEditors/GenericEditor.js.map +1 -0
  7. package/dist/admin/blockEditors/SymbolRefEditor.d.ts +2 -0
  8. package/dist/admin/blockEditors/SymbolRefEditor.js +55 -0
  9. package/dist/admin/blockEditors/SymbolRefEditor.js.map +1 -0
  10. package/dist/admin/blockEditors/index.d.ts +11 -6
  11. package/dist/admin/blockEditors/index.js +49 -620
  12. package/dist/admin/blockEditors/index.js.map +1 -1
  13. package/dist/admin/customBlocks/CustomBlocksPanel.d.ts +3 -0
  14. package/dist/admin/customBlocks/CustomBlocksPanel.js +145 -0
  15. package/dist/admin/customBlocks/CustomBlocksPanel.js.map +1 -0
  16. package/dist/admin/lib/compressImage.d.ts +4 -2
  17. package/dist/admin/lib/compressImage.js +7 -5
  18. package/dist/admin/lib/compressImage.js.map +1 -1
  19. package/dist/admin/lib/mediaUsage.d.ts +4 -3
  20. package/dist/admin/lib/mediaUsage.js +21 -10
  21. package/dist/admin/lib/mediaUsage.js.map +1 -1
  22. package/dist/admin/lib/symbolsClient.d.ts +13 -0
  23. package/dist/admin/lib/symbolsClient.js +51 -0
  24. package/dist/admin/lib/symbolsClient.js.map +1 -0
  25. package/dist/admin/lib/upload.d.ts +4 -0
  26. package/dist/admin/lib/upload.js +26 -6
  27. package/dist/admin/lib/upload.js.map +1 -1
  28. package/dist/admin/lib/zodFields.d.ts +18 -0
  29. package/dist/admin/lib/zodFields.js +65 -2
  30. package/dist/admin/lib/zodFields.js.map +1 -1
  31. package/dist/admin/media/MediaManager.js +23 -7
  32. package/dist/admin/media/MediaManager.js.map +1 -1
  33. package/dist/admin/media/MediaPicker.js +12 -2
  34. package/dist/admin/media/MediaPicker.js.map +1 -1
  35. package/dist/admin/panelRegistry.js +3 -0
  36. package/dist/admin/panelRegistry.js.map +1 -1
  37. package/dist/admin/settings/SettingsPanel.js +6 -1
  38. package/dist/admin/settings/SettingsPanel.js.map +1 -1
  39. package/dist/admin/settings/SnapshotsCard.d.ts +3 -0
  40. package/dist/admin/settings/SnapshotsCard.js +98 -0
  41. package/dist/admin/settings/SnapshotsCard.js.map +1 -0
  42. package/dist/admin/visual/TranslationPanel.d.ts +13 -0
  43. package/dist/admin/visual/TranslationPanel.js +73 -0
  44. package/dist/admin/visual/TranslationPanel.js.map +1 -0
  45. package/dist/admin/visual/VisualEditor.js +146 -18
  46. package/dist/admin/visual/VisualEditor.js.map +1 -1
  47. package/dist/admin.css +1 -1
  48. package/dist/agentFiles/catalog.d.ts +21 -0
  49. package/dist/agentFiles/catalog.js +78 -0
  50. package/dist/agentFiles/catalog.js.map +1 -0
  51. package/dist/agentFiles/files.d.ts +59 -0
  52. package/dist/agentFiles/files.js +109 -0
  53. package/dist/agentFiles/files.js.map +1 -0
  54. package/dist/blocks/builtins/Agenda.d.ts +6 -0
  55. package/dist/blocks/builtins/Agenda.js +14 -6
  56. package/dist/blocks/builtins/Agenda.js.map +1 -1
  57. package/dist/blocks/builtins/BeforeAfter.js +1 -0
  58. package/dist/blocks/builtins/BeforeAfter.js.map +1 -1
  59. package/dist/blocks/builtins/Breadcrumbs.js +5 -1
  60. package/dist/blocks/builtins/Breadcrumbs.js.map +1 -1
  61. package/dist/blocks/builtins/Cards.js +4 -2
  62. package/dist/blocks/builtins/Cards.js.map +1 -1
  63. package/dist/blocks/builtins/Contact.js +2 -1
  64. package/dist/blocks/builtins/Contact.js.map +1 -1
  65. package/dist/blocks/builtins/Cta.js +1 -0
  66. package/dist/blocks/builtins/Cta.js.map +1 -1
  67. package/dist/blocks/builtins/Elements.js +1 -0
  68. package/dist/blocks/builtins/Elements.js.map +1 -1
  69. package/dist/blocks/builtins/Faq.js +5 -4
  70. package/dist/blocks/builtins/Faq.js.map +1 -1
  71. package/dist/blocks/builtins/Gallery.js +2 -2
  72. package/dist/blocks/builtins/Gallery.js.map +1 -1
  73. package/dist/blocks/builtins/Hero.js +2 -2
  74. package/dist/blocks/builtins/Hero.js.map +1 -1
  75. package/dist/blocks/builtins/Jobs.d.ts +8 -1
  76. package/dist/blocks/builtins/Jobs.js +38 -21
  77. package/dist/blocks/builtins/Jobs.js.map +1 -1
  78. package/dist/blocks/builtins/MapBlock.js +31 -4
  79. package/dist/blocks/builtins/MapBlock.js.map +1 -1
  80. package/dist/blocks/builtins/PdfBlock.js +2 -3
  81. package/dist/blocks/builtins/PdfBlock.js.map +1 -1
  82. package/dist/blocks/builtins/Portfolio.js +2 -2
  83. package/dist/blocks/builtins/Portfolio.js.map +1 -1
  84. package/dist/blocks/builtins/Pricing.d.ts +2 -0
  85. package/dist/blocks/builtins/Pricing.js +18 -10
  86. package/dist/blocks/builtins/Pricing.js.map +1 -1
  87. package/dist/blocks/builtins/Sections.js +4 -2
  88. package/dist/blocks/builtins/Sections.js.map +1 -1
  89. package/dist/blocks/builtins/Slider.js +21 -3
  90. package/dist/blocks/builtins/Slider.js.map +1 -1
  91. package/dist/blocks/builtins/SymbolRef.d.ts +2 -0
  92. package/dist/blocks/builtins/SymbolRef.js +61 -0
  93. package/dist/blocks/builtins/SymbolRef.js.map +1 -0
  94. package/dist/blocks/builtins/Testimonials.js +21 -18
  95. package/dist/blocks/builtins/Testimonials.js.map +1 -1
  96. package/dist/blocks/builtins/WhatsappChat.js +1 -1
  97. package/dist/blocks/builtins/WhatsappChat.js.map +1 -1
  98. package/dist/blocks/builtins/Widgets.js +2 -3
  99. package/dist/blocks/builtins/Widgets.js.map +1 -1
  100. package/dist/blocks/builtins/lib/ics.js +1 -1
  101. package/dist/blocks/builtins/lib/ics.js.map +1 -1
  102. package/dist/blocks/builtins/lib/openingHours.d.ts +4 -1
  103. package/dist/blocks/builtins/lib/openingHours.js +11 -5
  104. package/dist/blocks/builtins/lib/openingHours.js.map +1 -1
  105. package/dist/blocks/customTemplate/definition.d.ts +7 -0
  106. package/dist/blocks/customTemplate/definition.js +34 -0
  107. package/dist/blocks/customTemplate/definition.js.map +1 -0
  108. package/dist/blocks/customTemplate/interpret.d.ts +10 -0
  109. package/dist/blocks/customTemplate/interpret.js +136 -0
  110. package/dist/blocks/customTemplate/interpret.js.map +1 -0
  111. package/dist/blocks/registry.d.ts +8 -0
  112. package/dist/blocks/registry.js.map +1 -1
  113. package/dist/demo/demoStore.d.ts +11 -1
  114. package/dist/demo/demoStore.js +50 -0
  115. package/dist/demo/demoStore.js.map +1 -1
  116. package/dist/firebase/client.js +2 -1
  117. package/dist/firebase/client.js.map +1 -1
  118. package/dist/i18n/overlay.d.ts +61 -0
  119. package/dist/i18n/overlay.js +90 -0
  120. package/dist/i18n/overlay.js.map +1 -0
  121. package/dist/index.d.ts +11 -9
  122. package/dist/index.js +34 -9
  123. package/dist/index.js.map +1 -1
  124. package/dist/modules/builtins.js +3 -2
  125. package/dist/modules/builtins.js.map +1 -1
  126. package/dist/modules/consent/useConsent.js +15 -3
  127. package/dist/modules/consent/useConsent.js.map +1 -1
  128. package/dist/schema/blocks.d.ts +183 -3
  129. package/dist/schema/blocks.js +12 -1
  130. package/dist/schema/blocks.js.map +1 -1
  131. package/dist/schema/customBlocks.d.ts +47 -0
  132. package/dist/schema/customBlocks.js +32 -0
  133. package/dist/schema/customBlocks.js.map +1 -0
  134. package/dist/schema/fields.d.ts +122 -0
  135. package/dist/schema/fields.js +120 -0
  136. package/dist/schema/fields.js.map +1 -0
  137. package/dist/schema/forms.d.ts +6 -6
  138. package/dist/schema/pages.d.ts +15 -1
  139. package/dist/schema/pages.js +6 -2
  140. package/dist/schema/pages.js.map +1 -1
  141. package/dist/schema/siteConfig.d.ts +14 -8
  142. package/dist/schema/siteConfig.js +2 -1
  143. package/dist/schema/siteConfig.js.map +1 -1
  144. package/dist/schema/symbols.d.ts +205 -0
  145. package/dist/schema/symbols.js +18 -0
  146. package/dist/schema/symbols.js.map +1 -0
  147. package/dist/server/index.d.ts +2 -1
  148. package/dist/server/index.js +24 -0
  149. package/dist/server/index.js.map +1 -1
  150. package/dist/server/pages.d.ts +21 -0
  151. package/dist/server/pages.js +77 -0
  152. package/dist/server/pages.js.map +1 -1
  153. package/dist/server/seo.d.ts +12 -3
  154. package/dist/server/seo.js +23 -11
  155. package/dist/server/seo.js.map +1 -1
  156. package/dist/styles.css +62 -6
  157. package/package.json +1 -1
  158. package/dist/components/EditableImage.d.ts +0 -18
  159. package/dist/components/EditableImage.js +0 -62
  160. package/dist/components/EditableImage.js.map +0 -1
  161. package/dist/components/EditableRichText.d.ts +0 -14
  162. package/dist/components/EditableRichText.js +0 -26
  163. package/dist/components/EditableRichText.js.map +0 -1
  164. package/dist/components/EditableText.d.ts +0 -21
  165. package/dist/components/EditableText.js +0 -25
  166. package/dist/components/EditableText.js.map +0 -1
  167. package/dist/content/ContentProvider.d.ts +0 -23
  168. package/dist/content/ContentProvider.js +0 -86
  169. package/dist/content/ContentProvider.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useState } from "react";
4
4
  import { collection, getDocs } from "firebase/firestore";
5
5
  import { getDb } from "../../firebase/client";
@@ -10,7 +10,8 @@ import { ArrayEditor } from "../ui/ArrayEditor";
10
10
  import { RichTextEditor } from "../editors/RichTextEditor";
11
11
  import { MediaPickerButton } from "../media/MediaPicker";
12
12
  import { useRegistry } from "../../blocks/context";
13
- import { introspectObjectSchema } from "../lib/zodFields";
13
+ import { GenericEditor } from "./GenericEditor";
14
+ import { SymbolRefEditor } from "./SymbolRefEditor";
14
15
  const VARIANT_OPTIONS = [
15
16
  { value: "primary", label: "Primair" },
16
17
  { value: "secondary", label: "Secundair" },
@@ -135,61 +136,25 @@ function ImageEditor({ block, siteId, onChange }) {
135
136
  ] })
136
137
  ] });
137
138
  }
138
- function CtaEditor({ block, onChange }) {
139
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
140
- /* @__PURE__ */ jsx(Field, { label: "Titel", children: /* @__PURE__ */ jsx(Input, { value: block.title ?? "", onChange: (e) => patch(block, onChange, { title: e.target.value }) }) }),
141
- /* @__PURE__ */ jsx(Field, { label: "Tekst", children: /* @__PURE__ */ jsx(Textarea, { rows: 2, value: block.text ?? "", onChange: (e) => patch(block, onChange, { text: e.target.value }) }) }),
142
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
143
- /* @__PURE__ */ jsx(Field, { label: "Knoptekst", children: /* @__PURE__ */ jsx(Input, { value: block.buttonLabel ?? "", onChange: (e) => patch(block, onChange, { buttonLabel: e.target.value }) }) }),
144
- /* @__PURE__ */ jsx(Field, { label: "Knoplink", children: /* @__PURE__ */ jsx(Input, { value: block.buttonHref ?? "", onChange: (e) => patch(block, onChange, { buttonHref: e.target.value }) }) }),
145
- /* @__PURE__ */ jsx(Field, { label: "Knopstijl", children: /* @__PURE__ */ jsx(Select, { value: block.buttonVariant ?? "primary", onValueChange: (v) => patch(block, onChange, { buttonVariant: v }), options: VARIANT_OPTIONS }) }),
146
- /* @__PURE__ */ jsx(Field, { label: "Achtergrondkleur (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.backgroundColor ?? "", onChange: (e) => patch(block, onChange, { backgroundColor: e.target.value }), placeholder: "#f8fafc" }) }),
147
- /* @__PURE__ */ jsx(Field, { label: "Tweede knop \u2014 tekst (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.button2Label ?? "", onChange: (e) => patch(block, onChange, { button2Label: e.target.value }) }) }),
148
- /* @__PURE__ */ jsx(Field, { label: "Tweede knop \u2014 link", children: /* @__PURE__ */ jsx(Input, { value: block.button2Href ?? "", onChange: (e) => patch(block, onChange, { button2Href: e.target.value }) }) })
149
- ] }),
150
- /* @__PURE__ */ jsx(Field, { label: "Weergave", children: /* @__PURE__ */ jsx(
151
- Select,
152
- {
153
- value: block.sticky ? "sticky" : "section",
154
- onValueChange: (v) => patch(block, onChange, { sticky: v === "sticky" }),
155
- options: [
156
- { value: "section", label: "Sectie in de pagina" },
157
- { value: "sticky", label: "Vaste balk onderaan (sticky)" }
158
- ]
159
- }
160
- ) })
161
- ] });
162
- }
163
139
  function FaqEditor({ block, siteId, onChange }) {
164
140
  const items = block.items ?? [];
165
- const set = (next) => patch(block, onChange, { items: next });
166
141
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
167
142
  /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
168
143
  /* @__PURE__ */ jsx(ToggleField, { label: "Items standaard open tonen", checked: block.defaultOpen === true, onChange: (v) => patch(block, onChange, { defaultOpen: v }) }),
169
- items.map((it, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2 rounded-lg border border-slate-200 p-3", children: [
170
- /* @__PURE__ */ jsx(Field, { label: `Vraag ${i + 1}`, children: /* @__PURE__ */ jsx(Input, { value: it.q ?? "", onChange: (e) => set(items.map((x, j) => j === i ? { ...x, q: e.target.value } : x)) }) }),
171
- it.aHtml !== void 0 ? /* @__PURE__ */ jsx(Field, { label: "Antwoord (met opmaak)", children: /* @__PURE__ */ jsx(RichTextEditor, { siteId, value: it.aHtml, onChange: (html) => set(items.map((x, j) => j === i ? { ...x, aHtml: html } : x)) }) }) : /* @__PURE__ */ jsx(Field, { label: "Antwoord", children: /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.a ?? "", onChange: (e) => set(items.map((x, j) => j === i ? { ...x, a: e.target.value } : x)) }) }),
172
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
173
- it.aHtml === void 0 ? /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(items.map((x, j) => j === i ? { ...x, aHtml: x.a ? `<p>${x.a}</p>` : "<p></p>" } : x)), children: "Opmaak gebruiken" }) : /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(items.map((x, j) => j === i ? { q: x.q, a: x.a } : x)), children: "Terug naar platte tekst" }),
174
- /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(items.filter((_, j) => j !== i)), children: "Verwijderen" })
175
- ] })
176
- ] }, i)),
177
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...items, { q: "", a: "" }]), children: "+ Vraag toevoegen" }) })
178
- ] });
179
- }
180
- function OpeningHoursEditor({ block, onChange }) {
181
- const rows = block.rows ?? [];
182
- const set = (next) => patch(block, onChange, { rows: next });
183
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
184
- /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
185
- rows.map((r, i) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_1fr_auto] items-end gap-2", children: [
186
- /* @__PURE__ */ jsx(Field, { label: "Dag(en)", children: /* @__PURE__ */ jsx(Input, { value: r.day ?? "", onChange: (e) => set(rows.map((x, j) => j === i ? { ...x, day: e.target.value } : x)) }) }),
187
- /* @__PURE__ */ jsx(Field, { label: "Tijden", children: /* @__PURE__ */ jsx(Input, { value: r.hours ?? "", onChange: (e) => set(rows.map((x, j) => j === i ? { ...x, hours: e.target.value } : x)) }) }),
188
- /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(rows.filter((_, j) => j !== i)), children: "\u2715" })
189
- ] }, i)),
190
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...rows, { day: "", hours: "" }]), children: "+ Rij toevoegen" }) }),
191
- /* @__PURE__ */ jsx(ToggleField, { label: "'Nu geopend'-badge", checked: Boolean(block.showStatus), onChange: (v) => patch(block, onChange, { showStatus: v }) }),
192
- /* @__PURE__ */ jsx(ToggleField, { label: "JSON-LD (openingstijden voor Google)", checked: Boolean(block.jsonLd), onChange: (v) => patch(block, onChange, { jsonLd: v }) })
144
+ /* @__PURE__ */ jsx(
145
+ ArrayEditor,
146
+ {
147
+ items,
148
+ onChange: (next) => patch(block, onChange, { items: next }),
149
+ newItem: () => ({ q: "", a: "" }),
150
+ addLabel: "+ Vraag toevoegen",
151
+ renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
152
+ /* @__PURE__ */ jsx(Field, { label: "Vraag", children: /* @__PURE__ */ jsx(Input, { value: it.q ?? "", onChange: (e) => update({ q: e.target.value }) }) }),
153
+ it.aHtml !== void 0 ? /* @__PURE__ */ jsx(Field, { label: "Antwoord (met opmaak)", children: /* @__PURE__ */ jsx(RichTextEditor, { siteId, value: it.aHtml, onChange: (html) => update({ aHtml: html }) }) }) : /* @__PURE__ */ jsx(Field, { label: "Antwoord", children: /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.a ?? "", onChange: (e) => update({ a: e.target.value }) }) }),
154
+ it.aHtml === void 0 ? /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => update({ aHtml: it.a ? `<p>${it.a}</p>` : "<p></p>" }), children: "Opmaak gebruiken" }) }) : /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => update({ aHtml: void 0 }), children: "Terug naar platte tekst" }) })
155
+ ] })
156
+ }
157
+ )
193
158
  ] });
194
159
  }
195
160
  function PricingEditor({ block, onChange }) {
@@ -289,21 +254,6 @@ function FormEditor({ block, siteId, onChange }) {
289
254
  missing && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-600", children: "Dit formulier-id bestaat niet (meer). Kies een bestaand formulier." })
290
255
  ] });
291
256
  }
292
- function SpacerEditor({ block, onChange }) {
293
- return /* @__PURE__ */ jsx(Field, { label: "Hoogte", children: /* @__PURE__ */ jsx(
294
- Select,
295
- {
296
- value: block.size ?? "md",
297
- onValueChange: (v) => patch(block, onChange, { size: v }),
298
- options: [
299
- { value: "sm", label: "Klein" },
300
- { value: "md", label: "Normaal" },
301
- { value: "lg", label: "Groot" },
302
- { value: "xl", label: "Extra groot" }
303
- ]
304
- }
305
- ) });
306
- }
307
257
  function GalleryEditor({ block, siteId, onChange }) {
308
258
  const items = block.items ?? [];
309
259
  const set = (next) => patch(block, onChange, { items: next });
@@ -360,67 +310,6 @@ function GalleryEditor({ block, siteId, onChange }) {
360
310
  /* @__PURE__ */ jsx(ToggleField, { label: "Filterbalk op tags", checked: Boolean(block.showFilter), onChange: (v) => patch(block, onChange, { showFilter: v }) })
361
311
  ] });
362
312
  }
363
- function TestimonialsEditor({ block, siteId, onChange }) {
364
- const items = block.items ?? [];
365
- const set = (next) => patch(block, onChange, { items: next });
366
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
367
- /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
368
- items.map((it, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2 rounded-lg border border-slate-200 p-3", children: [
369
- /* @__PURE__ */ jsx(Field, { label: "Quote", children: /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.quote ?? "", onChange: (e) => set(items.map((x, j) => j === i ? { ...x, quote: e.target.value } : x)) }) }),
370
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
371
- /* @__PURE__ */ jsx(Field, { label: "Naam", children: /* @__PURE__ */ jsx(Input, { value: it.author ?? "", onChange: (e) => set(items.map((x, j) => j === i ? { ...x, author: e.target.value } : x)) }) }),
372
- /* @__PURE__ */ jsx(Field, { label: "Functie", children: /* @__PURE__ */ jsx(Input, { value: it.role ?? "", onChange: (e) => set(items.map((x, j) => j === i ? { ...x, role: e.target.value } : x)) }) }),
373
- /* @__PURE__ */ jsx(Field, { label: "Sterren (1-5)", children: /* @__PURE__ */ jsx(Input, { type: "number", value: String(it.rating ?? ""), onChange: (e) => set(items.map((x, j) => j === i ? { ...x, rating: e.target.value ? Math.max(1, Math.min(5, Number(e.target.value))) : void 0 } : x)) }) })
374
- ] }),
375
- /* @__PURE__ */ jsx(Field, { label: "Avatar", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
376
- /* @__PURE__ */ jsx(Input, { value: it.avatarUrl ?? "", onChange: (e) => set(items.map((x, j) => j === i ? { ...x, avatarUrl: e.target.value } : x)), placeholder: "URL of upload \u2192" }),
377
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => set(items.map((x, j) => j === i ? { ...x, avatarUrl: url } : x)) })
378
- ] }) }),
379
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(items.filter((_, j) => j !== i)), children: "Verwijderen" }) })
380
- ] }, i)),
381
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...items, { quote: "", author: "", rating: 5 }]), children: "+ Review toevoegen" }) })
382
- ] });
383
- }
384
- function TeamEditor({ block, siteId, onChange }) {
385
- const members = block.members ?? [];
386
- const set = (next) => patch(block, onChange, { members: next });
387
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
388
- /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
389
- members.map((m, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2 rounded-lg border border-slate-200 p-3", children: [
390
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
391
- /* @__PURE__ */ jsx(Field, { label: "Naam", children: /* @__PURE__ */ jsx(Input, { value: m.name ?? "", onChange: (e) => set(members.map((x, j) => j === i ? { ...x, name: e.target.value } : x)) }) }),
392
- /* @__PURE__ */ jsx(Field, { label: "Functie", children: /* @__PURE__ */ jsx(Input, { value: m.role ?? "", onChange: (e) => set(members.map((x, j) => j === i ? { ...x, role: e.target.value } : x)) }) })
393
- ] }),
394
- /* @__PURE__ */ jsx(Field, { label: "Foto", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
395
- /* @__PURE__ */ jsx(Input, { value: m.photoUrl ?? "", onChange: (e) => set(members.map((x, j) => j === i ? { ...x, photoUrl: e.target.value } : x)), placeholder: "URL of upload \u2192" }),
396
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => set(members.map((x, j) => j === i ? { ...x, photoUrl: url } : x)) })
397
- ] }) }),
398
- /* @__PURE__ */ jsx(Field, { label: "Bio", children: /* @__PURE__ */ jsx(Textarea, { rows: 2, value: m.bio ?? "", onChange: (e) => set(members.map((x, j) => j === i ? { ...x, bio: e.target.value } : x)) }) }),
399
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
400
- /* @__PURE__ */ jsx(Field, { label: "E-mail (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: m.email ?? "", onChange: (e) => set(members.map((x, j) => j === i ? { ...x, email: e.target.value } : x)) }) }),
401
- /* @__PURE__ */ jsx(Field, { label: "Telefoon (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: m.phone ?? "", onChange: (e) => set(members.map((x, j) => j === i ? { ...x, phone: e.target.value } : x)) }) })
402
- ] }),
403
- /* @__PURE__ */ jsx(Field, { label: "Social (platform|url, \xE9\xE9n per regel)", children: /* @__PURE__ */ jsx(
404
- Textarea,
405
- {
406
- rows: 2,
407
- value: (m.social ?? []).map((s) => `${s.platform}|${s.href}`).join("\n"),
408
- onChange: (e) => set(
409
- members.map(
410
- (x, j) => j === i ? {
411
- ...x,
412
- social: e.target.value.split("\n").map((line) => line.split("|")).filter((p) => p[0] && p[1]).map(([platform, href]) => ({ platform: platform.trim(), href: href.trim() }))
413
- } : x
414
- )
415
- )
416
- }
417
- ) }),
418
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(members.filter((_, j) => j !== i)), children: "Verwijderen" }) })
419
- ] }, i)),
420
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...members, { name: "" }]), children: "+ Lid toevoegen" }) }),
421
- /* @__PURE__ */ jsx(ToggleField, { label: "Groeperen per afdeling", checked: Boolean(block.groupByDepartment), onChange: (v) => patch(block, onChange, { groupByDepartment: v }) })
422
- ] });
423
- }
424
313
  function AgendaEditor({ block, onChange }) {
425
314
  const events = block.events ?? [];
426
315
  const set = (next) => patch(block, onChange, { events: next });
@@ -438,22 +327,6 @@ function AgendaEditor({ block, onChange }) {
438
327
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...events, { title: "", start: "" }]), children: "+ Evenement toevoegen" }) })
439
328
  ] });
440
329
  }
441
- function SearchEditor({ block, onChange }) {
442
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
443
- /* @__PURE__ */ jsx(Field, { label: "Placeholder", children: /* @__PURE__ */ jsx(Input, { value: block.placeholder ?? "Zoeken\u2026", onChange: (e) => patch(block, onChange, { placeholder: e.target.value }) }) }),
444
- /* @__PURE__ */ jsx(Field, { label: "Nieuws meenemen", children: /* @__PURE__ */ jsx(
445
- Select,
446
- {
447
- value: block.includeNews === false ? "no" : "yes",
448
- onValueChange: (v) => patch(block, onChange, { includeNews: v === "yes" }),
449
- options: [
450
- { value: "yes", label: "Ja, ook nieuwsartikelen" },
451
- { value: "no", label: "Nee, alleen pagina's" }
452
- ]
453
- }
454
- ) })
455
- ] });
456
- }
457
330
  function HeadingField({ block, onChange }) {
458
331
  return /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) });
459
332
  }
@@ -478,79 +351,6 @@ function FeatureEditor({ block, siteId, onChange }) {
478
351
  ] })
479
352
  ] });
480
353
  }
481
- function CountersEditor({ block, siteId, onChange }) {
482
- const items = block.items ?? [];
483
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
484
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
485
- /* @__PURE__ */ jsx(
486
- ArrayEditor,
487
- {
488
- items,
489
- onChange: (next) => patch(block, onChange, { items: next }),
490
- newItem: () => ({ value: "", label: "" }),
491
- addLabel: "+ Teller",
492
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-4 gap-2", children: [
493
- /* @__PURE__ */ jsx(Input, { value: it.prefix ?? "", placeholder: "\xB1", onChange: (e) => update({ prefix: e.target.value }) }),
494
- /* @__PURE__ */ jsx(Input, { value: it.value, placeholder: "100", onChange: (e) => update({ value: e.target.value }) }),
495
- /* @__PURE__ */ jsx(Input, { value: it.suffix ?? "", placeholder: "+", onChange: (e) => update({ suffix: e.target.value }) }),
496
- /* @__PURE__ */ jsx(Input, { value: it.label, placeholder: "Label", onChange: (e) => update({ label: e.target.value }) })
497
- ] })
498
- }
499
- ),
500
- /* @__PURE__ */ jsx(ToggleField, { label: "Tel-animatie bij scrollen", checked: block.animate !== false, onChange: (v) => patch(block, onChange, { animate: v }) })
501
- ] });
502
- }
503
- function LogosEditor({ block, siteId, onChange }) {
504
- const items = block.items ?? [];
505
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
506
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
507
- /* @__PURE__ */ jsx(
508
- ArrayEditor,
509
- {
510
- items,
511
- onChange: (next) => patch(block, onChange, { items: next }),
512
- newItem: () => ({ src: "", alt: "" }),
513
- addLabel: "+ Logo",
514
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
515
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
516
- /* @__PURE__ */ jsx(Input, { value: it.src, placeholder: "URL of upload \u2192", onChange: (e) => update({ src: e.target.value }) }),
517
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => update({ src: url }) })
518
- ] }),
519
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
520
- /* @__PURE__ */ jsx(Input, { value: it.alt, placeholder: "Alt-tekst", onChange: (e) => update({ alt: e.target.value }) }),
521
- /* @__PURE__ */ jsx(Input, { value: it.href ?? "", placeholder: "Link (optioneel)", onChange: (e) => update({ href: e.target.value }) })
522
- ] })
523
- ] })
524
- }
525
- ),
526
- /* @__PURE__ */ jsx(ToggleField, { label: "Logo's in grijstinten", checked: block.grayscale !== false, onChange: (v) => patch(block, onChange, { grayscale: v }) }),
527
- /* @__PURE__ */ jsx(ToggleField, { label: "Doorlopende band (marquee)", checked: Boolean(block.marquee), onChange: (v) => patch(block, onChange, { marquee: v }) })
528
- ] });
529
- }
530
- function TimelineEditor({ block, siteId, onChange }) {
531
- const items = block.items ?? [];
532
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
533
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
534
- /* @__PURE__ */ jsx(
535
- ArrayEditor,
536
- {
537
- items,
538
- onChange: (next) => patch(block, onChange, { items: next }),
539
- newItem: () => ({ title: "" }),
540
- addLabel: "+ Stap",
541
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
542
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[3rem_1fr_1fr] gap-2", children: [
543
- /* @__PURE__ */ jsx(Input, { value: it.icon ?? "", placeholder: "\u{1F528}", title: "Icoon (emoji)", onChange: (e) => update({ icon: e.target.value || void 0 }) }),
544
- /* @__PURE__ */ jsx(Input, { value: it.title, placeholder: "Titel", onChange: (e) => update({ title: e.target.value }) }),
545
- /* @__PURE__ */ jsx(Input, { value: it.date ?? "", placeholder: "Datum/label", onChange: (e) => update({ date: e.target.value }) })
546
- ] }),
547
- /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.text ?? "", placeholder: "Toelichting", onChange: (e) => update({ text: e.target.value }) })
548
- ] })
549
- }
550
- ),
551
- /* @__PURE__ */ jsx(ToggleField, { label: "Alternerende layout (links/rechts)", checked: Boolean(block.alternate), onChange: (v) => patch(block, onChange, { alternate: v }) })
552
- ] });
553
- }
554
354
  function VideoEditor({ block, siteId, onChange }) {
555
355
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
556
356
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
@@ -566,18 +366,6 @@ function VideoEditor({ block, siteId, onChange }) {
566
366
  /* @__PURE__ */ jsx(ToggleField, { label: "Click-to-play (speler laadt pas na klik \u2014 sneller & privacyvriendelijker)", checked: Boolean(block.facade), onChange: (v) => patch(block, onChange, { facade: v }) })
567
367
  ] });
568
368
  }
569
- function BannerEditor({ block, onChange }) {
570
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
571
- /* @__PURE__ */ jsx(Field, { label: "Tekst", children: /* @__PURE__ */ jsx(Input, { value: block.text ?? "", onChange: (e) => patch(block, onChange, { text: e.target.value }) }) }),
572
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
573
- /* @__PURE__ */ jsx(Field, { label: "Link", children: /* @__PURE__ */ jsx(Input, { value: block.href ?? "", onChange: (e) => patch(block, onChange, { href: e.target.value }) }) }),
574
- /* @__PURE__ */ jsx(Field, { label: "Linktekst", children: /* @__PURE__ */ jsx(Input, { value: block.linkLabel ?? "", onChange: (e) => patch(block, onChange, { linkLabel: e.target.value }) }) }),
575
- /* @__PURE__ */ jsx(Field, { label: "Stijl", children: /* @__PURE__ */ jsx(Select, { value: block.tone ?? "info", onValueChange: (v) => patch(block, onChange, { tone: v }), options: [{ value: "info", label: "Info" }, { value: "success", label: "Succes" }, { value: "warning", label: "Waarschuwing" }] }) })
576
- ] }),
577
- /* @__PURE__ */ jsx(ToggleField, { label: "Sluitbaar", checked: block.dismissible !== false, onChange: (v) => patch(block, onChange, { dismissible: v }) }),
578
- block.dismissible !== false && /* @__PURE__ */ jsx(Field, { label: "Versie", hint: "Wijzig (bv. '2') als de tekst verandert \u2014 wie de oude balk wegklikte ziet de nieuwe weer", children: /* @__PURE__ */ jsx(Input, { value: block.dismissVersion ?? "", onChange: (e) => patch(block, onChange, { dismissVersion: e.target.value || void 0 }) }) })
579
- ] });
580
- }
581
369
  function GeoField({ value, onChange }) {
582
370
  const [text, setText] = useState(value ? `${value.lat}, ${value.lng}` : "");
583
371
  return /* @__PURE__ */ jsx(Field, { label: "Co\xF6rdinaten (lat, lng)", hint: "bv. 52.0907, 5.1214 \u2014 toont het bedrijf op de juiste plek in Google", children: /* @__PURE__ */ jsx(
@@ -618,32 +406,42 @@ function ContactEditor({ block, siteId, onChange }) {
618
406
  /* @__PURE__ */ jsx(ToggleField, { label: "JSON-LD (LocalBusiness)", checked: Boolean(block.jsonLd), onChange: (v) => patch(block, onChange, { jsonLd: v }) })
619
407
  ] });
620
408
  }
621
- function SocialEditor({ block, siteId, onChange }) {
622
- const items = block.items ?? [];
623
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
624
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
625
- /* @__PURE__ */ jsx(
626
- ArrayEditor,
627
- {
628
- items,
629
- onChange: (next) => patch(block, onChange, { items: next }),
630
- newItem: () => ({ platform: "", href: "" }),
631
- addLabel: "+ Social-link",
632
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
633
- /* @__PURE__ */ jsx(Input, { value: it.platform, placeholder: "bv. Instagram", onChange: (e) => update({ platform: e.target.value }) }),
634
- /* @__PURE__ */ jsx(Input, { value: it.href, placeholder: "https://\u2026", onChange: (e) => update({ href: e.target.value }) })
635
- ] })
409
+ function MapCoordField({ block, onChange }) {
410
+ const lat = block.lat;
411
+ const lng = block.lng;
412
+ const [text, setText] = useState(lat != null && lng != null ? `${lat}, ${lng}` : "");
413
+ return /* @__PURE__ */ jsx(Field, { label: "Co\xF6rdinaten (lat, lng)", hint: "bv. 51.9958, 5.0924 \u2014 toont een echte kaart i.p.v. de wereldkaart. Co\xF6rdinaten vind je door in openstreetmap.org rechts te klikken \u2192 'Toon adres'.", children: /* @__PURE__ */ jsx(
414
+ Input,
415
+ {
416
+ value: text,
417
+ placeholder: "51.9958, 5.0924",
418
+ onChange: (e) => {
419
+ setText(e.target.value);
420
+ const t = e.target.value.trim();
421
+ if (t === "") {
422
+ patch(block, onChange, { lat: void 0, lng: void 0 });
423
+ return;
424
+ }
425
+ const m = t.match(/^(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)$/);
426
+ if (!m) return;
427
+ const la = Number(m[1]);
428
+ const ln = Number(m[2]);
429
+ if (Math.abs(la) <= 90 && Math.abs(ln) <= 180) patch(block, onChange, { lat: la, lng: ln });
636
430
  }
637
- )
638
- ] });
431
+ }
432
+ ) });
639
433
  }
640
- function MapEditor({ block, onChange }) {
434
+ function MapEditor({ block, siteId, onChange }) {
435
+ const isGoogle = block.provider === "google";
641
436
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
642
437
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
643
- /* @__PURE__ */ jsx(Field, { label: "Aanbieder", children: /* @__PURE__ */ jsx(Select, { value: block.provider ?? "osm", onValueChange: (v) => patch(block, onChange, { provider: v }), options: [{ value: "osm", label: "OpenStreetMap (adres)" }, { value: "google", label: "Google (embed-URL)" }] }) }),
438
+ /* @__PURE__ */ jsx(Field, { label: "Aanbieder", children: /* @__PURE__ */ jsx(Select, { value: block.provider ?? "osm", onValueChange: (v) => patch(block, onChange, { provider: v }), options: [{ value: "osm", label: "OpenStreetMap (co\xF6rdinaten)" }, { value: "google", label: "Google (embed-URL)" }] }) }),
644
439
  /* @__PURE__ */ jsx(Field, { label: "Hoogte (px)", children: /* @__PURE__ */ jsx(Input, { type: "number", value: String(block.height ?? 360), onChange: (e) => patch(block, onChange, { height: Math.max(150, Math.min(800, Number(e.target.value) || 360)) }) }) })
645
440
  ] }),
646
- /* @__PURE__ */ jsx(Field, { label: block.provider === "google" ? "Embed-URL" : "Adres / zoekterm", children: /* @__PURE__ */ jsx(Input, { value: block.query ?? "", onChange: (e) => patch(block, onChange, { query: e.target.value }) }) }),
441
+ isGoogle ? /* @__PURE__ */ jsx(Field, { label: "Embed-URL", children: /* @__PURE__ */ jsx(Input, { value: block.query ?? "", onChange: (e) => patch(block, onChange, { query: e.target.value }) }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
442
+ /* @__PURE__ */ jsx(MapCoordField, { block, siteId, onChange }),
443
+ /* @__PURE__ */ jsx(Field, { label: "Zoom (1\u201320)", children: /* @__PURE__ */ jsx(Input, { type: "number", value: String(block.zoom ?? 14), onChange: (e) => patch(block, onChange, { zoom: Math.max(1, Math.min(20, Number(e.target.value) || 14)) }) }) })
444
+ ] }),
647
445
  /* @__PURE__ */ jsx(ToggleField, { label: "Pas tonen na cookie-toestemming", checked: block.consentGated !== false, onChange: (v) => patch(block, onChange, { consentGated: v }) })
648
446
  ] });
649
447
  }
@@ -723,48 +521,6 @@ function BookingEditor({ block, siteId, onChange }) {
723
521
  /* @__PURE__ */ jsx(ToggleField, { label: "Pas tonen na cookie-toestemming", checked: block.consentGated !== false, onChange: (v) => patch(block, onChange, { consentGated: v }) })
724
522
  ] });
725
523
  }
726
- function ButtonsEditor({ block, onChange }) {
727
- const items = block.items ?? [];
728
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
729
- /* @__PURE__ */ jsx(Field, { label: "Uitlijning", children: /* @__PURE__ */ jsx(
730
- Select,
731
- {
732
- value: block.align ?? "left",
733
- onValueChange: (v) => patch(block, onChange, { align: v }),
734
- options: [{ value: "left", label: "Links" }, { value: "center", label: "Midden" }, { value: "right", label: "Rechts" }]
735
- }
736
- ) }),
737
- /* @__PURE__ */ jsx(
738
- ArrayEditor,
739
- {
740
- items,
741
- onChange: (next) => patch(block, onChange, { items: next }),
742
- newItem: () => ({ label: "", href: "#", variant: "primary" }),
743
- addLabel: "+ Knop",
744
- renderRow: (b, update) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
745
- /* @__PURE__ */ jsx(Input, { value: b.label, placeholder: "Label", onChange: (e) => update({ label: e.target.value }) }),
746
- /* @__PURE__ */ jsx(Input, { value: b.href, placeholder: "/pad of https://\u2026", onChange: (e) => update({ href: e.target.value }) }),
747
- /* @__PURE__ */ jsx(Select, { value: b.variant, onValueChange: (v) => update({ variant: v }), options: VARIANT_OPTIONS })
748
- ] })
749
- }
750
- )
751
- ] });
752
- }
753
- function QuoteEditor({ block, onChange }) {
754
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
755
- /* @__PURE__ */ jsx(Field, { label: "Uitspraak", children: /* @__PURE__ */ jsx(Textarea, { rows: 3, value: block.text ?? "", onChange: (e) => patch(block, onChange, { text: e.target.value }) }) }),
756
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
757
- /* @__PURE__ */ jsx(Field, { label: "Auteur", children: /* @__PURE__ */ jsx(Input, { value: block.author ?? "", onChange: (e) => patch(block, onChange, { author: e.target.value }) }) }),
758
- /* @__PURE__ */ jsx(Field, { label: "Functie", children: /* @__PURE__ */ jsx(Input, { value: block.role ?? "", onChange: (e) => patch(block, onChange, { role: e.target.value }) }) })
759
- ] })
760
- ] });
761
- }
762
- function DividerEditor({ block, onChange }) {
763
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
764
- /* @__PURE__ */ jsx(Field, { label: "Stijl", children: /* @__PURE__ */ jsx(Select, { value: block.variant ?? "line", onValueChange: (v) => patch(block, onChange, { variant: v }), options: [{ value: "line", label: "Lijn" }, { value: "dots", label: "Stippen" }, { value: "space", label: "Alleen ruimte" }] }) }),
765
- /* @__PURE__ */ jsx(Field, { label: "Ruimte", children: /* @__PURE__ */ jsx(Select, { value: block.spacing ?? "md", onValueChange: (v) => patch(block, onChange, { spacing: v }), options: [{ value: "sm", label: "Klein" }, { value: "md", label: "Normaal" }, { value: "lg", label: "Groot" }] }) })
766
- ] });
767
- }
768
524
  function AccordionEditor({ block, siteId, onChange }) {
769
525
  const items = block.items ?? [];
770
526
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
@@ -959,103 +715,6 @@ function TabsEditor({ block, siteId, onChange }) {
959
715
  tabs.length < 10 && /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...tabs, { label: `Tab ${tabs.length + 1}`, blocks: [] }]), children: "+ Tab toevoegen" })
960
716
  ] });
961
717
  }
962
- function CardsEditor({ block, siteId, onChange }) {
963
- const items = block.items ?? [];
964
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
965
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
966
- /* @__PURE__ */ jsx(Field, { label: "Intro (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.intro ?? "", onChange: (e) => patch(block, onChange, { intro: e.target.value }) }) }),
967
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
968
- /* @__PURE__ */ jsx(Field, { label: "Kolommen", children: /* @__PURE__ */ jsx(Input, { type: "number", value: String(block.columns ?? 3), onChange: (e) => patch(block, onChange, { columns: Math.max(1, Math.min(4, Number(e.target.value) || 3)) }) }) }),
969
- /* @__PURE__ */ jsx(Field, { label: "Beeldstijl", hint: "cover = beeld tot de kaartranden", children: /* @__PURE__ */ jsx(
970
- Select,
971
- {
972
- value: block.imageStyle ?? "inset",
973
- onValueChange: (v) => patch(block, onChange, { imageStyle: v }),
974
- options: [
975
- { value: "inset", label: "Ingekaderd" },
976
- { value: "cover", label: "Edge-to-edge (postkaart)" }
977
- ]
978
- }
979
- ) })
980
- ] }),
981
- /* @__PURE__ */ jsx(
982
- ArrayEditor,
983
- {
984
- items,
985
- onChange: (next) => patch(block, onChange, { items: next }),
986
- newItem: () => ({ icon: "", title: "", text: "" }),
987
- addLabel: "+ Kaart",
988
- renderRow: (it, update, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
989
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
990
- /* @__PURE__ */ jsx(Field, { label: "Icoon (emoji)", children: /* @__PURE__ */ jsx(Input, { value: it.icon ?? "", onChange: (e) => update({ icon: e.target.value }) }) }),
991
- /* @__PURE__ */ jsx(Field, { label: "Titel", children: /* @__PURE__ */ jsx(Input, { value: it.title, onChange: (e) => update({ title: e.target.value }) }) })
992
- ] }),
993
- /* @__PURE__ */ jsx(Field, { label: "Tekst", children: /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.text ?? "", onChange: (e) => update({ text: e.target.value }) }) }),
994
- /* @__PURE__ */ jsx(Field, { label: "Afbeelding (optioneel)", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
995
- /* @__PURE__ */ jsx(Input, { value: it.imageUrl ?? "", onChange: (e) => update({ imageUrl: e.target.value }), placeholder: "URL of upload \u2192" }),
996
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => update({ imageUrl: url }) }, i)
997
- ] }) }),
998
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
999
- /* @__PURE__ */ jsx(Field, { label: "Link (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: it.href ?? "", onChange: (e) => update({ href: e.target.value }) }) }),
1000
- /* @__PURE__ */ jsx(Field, { label: "Linktekst", children: /* @__PURE__ */ jsx(Input, { value: it.linkLabel ?? "", onChange: (e) => update({ linkLabel: e.target.value }) }) })
1001
- ] }),
1002
- /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1.5 text-xs text-slate-600", children: [
1003
- /* @__PURE__ */ jsx("input", { type: "checkbox", checked: Boolean(it.featured), onChange: (e) => update({ featured: e.target.checked }) }),
1004
- "Uitgelicht (accentrand)"
1005
- ] })
1006
- ] })
1007
- }
1008
- )
1009
- ] });
1010
- }
1011
- function DownloadsEditor({ block, siteId, onChange }) {
1012
- const items = block.items ?? [];
1013
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1014
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1015
- /* @__PURE__ */ jsx(
1016
- ArrayEditor,
1017
- {
1018
- items,
1019
- onChange: (next) => patch(block, onChange, { items: next }),
1020
- newItem: () => ({ label: "", href: "", meta: "" }),
1021
- addLabel: "+ Document",
1022
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1023
- /* @__PURE__ */ jsx(Input, { value: it.label, placeholder: "Naam (bv. Brochure 2026)", onChange: (e) => update({ label: e.target.value }) }),
1024
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1025
- /* @__PURE__ */ jsx(Input, { value: it.href, placeholder: "URL naar bestand", onChange: (e) => update({ href: e.target.value }) }),
1026
- /* @__PURE__ */ jsx(Input, { value: it.meta ?? "", placeholder: "PDF \xB7 1,2 MB", onChange: (e) => update({ meta: e.target.value }) })
1027
- ] })
1028
- ] })
1029
- }
1030
- )
1031
- ] });
1032
- }
1033
- function PdfEditor({ block, siteId, onChange }) {
1034
- const docs = block.documents ?? [];
1035
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1036
- /* @__PURE__ */ jsxs("p", { className: "rounded-md bg-slate-50 p-2 text-xs text-slate-600", children: [
1037
- "Toon \xE9\xE9n of meer ",
1038
- /* @__PURE__ */ jsx("strong", { children: "PDF's" }),
1039
- " (bv. lunch-, diner- en wijnkaart). Bij meerdere verschijnen tabs. Vervang een kaart door simpelweg de URL te wijzigen."
1040
- ] }),
1041
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1042
- /* @__PURE__ */ jsx(
1043
- ArrayEditor,
1044
- {
1045
- items: docs,
1046
- onChange: (next) => patch(block, onChange, { documents: next }),
1047
- newItem: () => ({ label: "", url: "" }),
1048
- addLabel: "+ PDF",
1049
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1050
- /* @__PURE__ */ jsx(Input, { value: it.label, placeholder: "Naam (bv. Lunchkaart)", onChange: (e) => update({ label: e.target.value }) }),
1051
- /* @__PURE__ */ jsx(Input, { value: it.url, placeholder: "URL naar de PDF", onChange: (e) => update({ url: e.target.value }) })
1052
- ] })
1053
- }
1054
- ),
1055
- /* @__PURE__ */ jsx(Field, { label: "Hoogte (px)", children: /* @__PURE__ */ jsx(Input, { type: "number", value: String(block.height ?? 820), onChange: (e) => patch(block, onChange, { height: Math.max(300, Math.min(1600, Number(e.target.value) || 820)) }) }) }),
1056
- /* @__PURE__ */ jsx(ToggleField, { label: "Open/Download-link tonen", checked: block.showDownload !== false, onChange: (v) => patch(block, onChange, { showDownload: v }) })
1057
- ] });
1058
- }
1059
718
  function CountdownEditor({ block, onChange }) {
1060
719
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1061
720
  /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
@@ -1324,263 +983,32 @@ function CountdownWidgetEditor({ block, onChange }) {
1324
983
  /* @__PURE__ */ jsx(Field, { label: "Tekst als de tijd om is", children: /* @__PURE__ */ jsx(Input, { value: block.expiredText ?? "", onChange: (e) => patch(block, onChange, { expiredText: e.target.value }) }) })
1325
984
  ] });
1326
985
  }
1327
- function GenericEditor({ block, siteId, onChange }) {
1328
- const registry = useRegistry();
1329
- const def = registry.get(String(block._type ?? ""));
1330
- const fields = def ? introspectObjectSchema(def.schema) : [];
1331
- if (fields.length === 0) {
1332
- return /* @__PURE__ */ jsx("p", { className: "text-sm text-slate-500", children: "Voor dit bloktype is geen editor beschikbaar." });
1333
- }
1334
- return /* @__PURE__ */ jsx("div", { className: "grid gap-3", children: fields.map((f) => {
1335
- if (f.kind === "boolean") {
1336
- return /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
1337
- /* @__PURE__ */ jsx(Switch, { checked: Boolean(block[f.key]), onCheckedChange: (v) => patch(block, onChange, { [f.key]: v }) }),
1338
- f.label
1339
- ] }, f.key);
1340
- }
1341
- if (f.kind === "enum") {
1342
- return /* @__PURE__ */ jsx(Field, { label: f.label, children: /* @__PURE__ */ jsx(
1343
- Select,
1344
- {
1345
- value: String(block[f.key] ?? f.options?.[0] ?? ""),
1346
- onValueChange: (v) => patch(block, onChange, { [f.key]: v }),
1347
- options: (f.options ?? []).map((o) => ({ value: o, label: o }))
1348
- }
1349
- ) }, f.key);
1350
- }
1351
- if (f.kind === "number") {
1352
- return /* @__PURE__ */ jsx(Field, { label: f.label, children: /* @__PURE__ */ jsx(
1353
- Input,
1354
- {
1355
- type: "number",
1356
- value: String(block[f.key] ?? ""),
1357
- onChange: (e) => patch(block, onChange, { [f.key]: e.target.value === "" ? void 0 : Number(e.target.value) })
1358
- }
1359
- ) }, f.key);
1360
- }
1361
- if (f.kind === "json") {
1362
- return /* @__PURE__ */ jsx(GenericJsonField, { field: f, block, onChange }, f.key);
1363
- }
1364
- if (f.key === "html") {
1365
- return /* @__PURE__ */ jsx(Field, { label: "Tekst", children: /* @__PURE__ */ jsx(RichTextEditor, { siteId, value: block.html ?? "", onChange: (html) => patch(block, onChange, { html }) }) }, f.key);
1366
- }
1367
- const isImage = /image|photo|foto|logo|cover|avatar/i.test(f.key);
1368
- if (isImage) {
1369
- return /* @__PURE__ */ jsx(Field, { label: f.label, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1370
- /* @__PURE__ */ jsx(Input, { value: String(block[f.key] ?? ""), onChange: (e) => patch(block, onChange, { [f.key]: e.target.value }), placeholder: "URL of kies \u2192" }),
1371
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => patch(block, onChange, { [f.key]: url }) })
1372
- ] }) }, f.key);
1373
- }
1374
- const long = (f.maxLength ?? 0) > 500;
1375
- return /* @__PURE__ */ jsx(Field, { label: f.label, children: long ? /* @__PURE__ */ jsx(Textarea, { rows: 4, value: String(block[f.key] ?? ""), onChange: (e) => patch(block, onChange, { [f.key]: e.target.value }) }) : /* @__PURE__ */ jsx(Input, { value: String(block[f.key] ?? ""), onChange: (e) => patch(block, onChange, { [f.key]: e.target.value }) }) }, f.key);
1376
- }) });
1377
- }
1378
- function GenericJsonField({
1379
- field,
1380
- block,
1381
- onChange
1382
- }) {
1383
- const [text, setText] = useState(() => JSON.stringify(block[field.key] ?? null, null, 2));
1384
- const [error, setError] = useState(null);
1385
- const commit = () => {
1386
- try {
1387
- const parsed = JSON.parse(text);
1388
- const res = field.schema.safeParse(parsed);
1389
- if (!res.success) {
1390
- setError("Voldoet niet aan het verwachte formaat van dit veld.");
1391
- return;
1392
- }
1393
- setError(null);
1394
- patch(block, onChange, { [field.key]: res.data });
1395
- } catch {
1396
- setError("Geen geldige JSON.");
1397
- }
1398
- };
1399
- return /* @__PURE__ */ jsxs(Field, { label: `${field.label} (JSON)`, hint: "Geavanceerd veld \u2014 wordt gecontroleerd v\xF3\xF3r opslaan.", children: [
1400
- /* @__PURE__ */ jsx(
1401
- Textarea,
1402
- {
1403
- rows: 6,
1404
- value: text,
1405
- onChange: (e) => setText(e.target.value),
1406
- onBlur: commit,
1407
- spellCheck: false,
1408
- className: "font-mono text-xs"
1409
- }
1410
- ),
1411
- error && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-600", children: error })
1412
- ] });
1413
- }
1414
- function WhatsappChatEditor({ block, onChange }) {
1415
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1416
- /* @__PURE__ */ jsx(Field, { label: "Telefoonnummer (internationaal)", hint: "bv. 31612345678 \u2014 zonder + of spaties mag ook", children: /* @__PURE__ */ jsx(Input, { value: block.phone ?? "", onChange: (e) => patch(block, onChange, { phone: e.target.value }) }) }),
1417
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1418
- /* @__PURE__ */ jsx(Field, { label: "Label (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.label ?? "", onChange: (e) => patch(block, onChange, { label: e.target.value || void 0 }) }) }),
1419
- /* @__PURE__ */ jsx(Field, { label: "Positie", children: /* @__PURE__ */ jsx(
1420
- Select,
1421
- {
1422
- value: block.position ?? "br",
1423
- onValueChange: (v) => patch(block, onChange, { position: v }),
1424
- options: [
1425
- { value: "br", label: "Rechtsonder" },
1426
- { value: "bl", label: "Linksonder" }
1427
- ]
1428
- }
1429
- ) })
1430
- ] }),
1431
- /* @__PURE__ */ jsx(Field, { label: "Vooringevuld bericht (optioneel)", hint: "Staat alvast in het WhatsApp-venster van de bezoeker", children: /* @__PURE__ */ jsx(Input, { value: block.prefilledText ?? "", onChange: (e) => patch(block, onChange, { prefilledText: e.target.value || void 0 }) }) })
1432
- ] });
1433
- }
1434
- function BeforeAfterEditor({ block, siteId, onChange }) {
1435
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1436
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1437
- /* @__PURE__ */ jsx(Field, { label: "Foto v\xF3\xF3r", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1438
- /* @__PURE__ */ jsx(Input, { value: block.beforeUrl ?? "", onChange: (e) => patch(block, onChange, { beforeUrl: e.target.value }), placeholder: "URL of upload \u2192" }),
1439
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => patch(block, onChange, { beforeUrl: url }) })
1440
- ] }) }),
1441
- /* @__PURE__ */ jsx(Field, { label: "Foto n\xE1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1442
- /* @__PURE__ */ jsx(Input, { value: block.afterUrl ?? "", onChange: (e) => patch(block, onChange, { afterUrl: e.target.value }), placeholder: "URL of upload \u2192" }),
1443
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => patch(block, onChange, { afterUrl: url }) })
1444
- ] }) }),
1445
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
1446
- /* @__PURE__ */ jsx(Field, { label: "Label v\xF3\xF3r", children: /* @__PURE__ */ jsx(Input, { value: block.beforeLabel ?? "Voor", onChange: (e) => patch(block, onChange, { beforeLabel: e.target.value }) }) }),
1447
- /* @__PURE__ */ jsx(Field, { label: "Label n\xE1", children: /* @__PURE__ */ jsx(Input, { value: block.afterLabel ?? "Na", onChange: (e) => patch(block, onChange, { afterLabel: e.target.value }) }) }),
1448
- /* @__PURE__ */ jsx(Field, { label: "Beeldverhouding", children: /* @__PURE__ */ jsx(
1449
- Select,
1450
- {
1451
- value: block.aspectRatio ?? "4/3",
1452
- onValueChange: (v) => patch(block, onChange, { aspectRatio: v }),
1453
- options: [
1454
- { value: "16/9", label: "16:9" },
1455
- { value: "4/3", label: "4:3" },
1456
- { value: "3/2", label: "3:2" },
1457
- { value: "1/1", label: "Vierkant" }
1458
- ]
1459
- }
1460
- ) })
1461
- ] }),
1462
- /* @__PURE__ */ jsx(Field, { label: "Alt-tekst", children: /* @__PURE__ */ jsx(Input, { value: block.alt ?? "", onChange: (e) => patch(block, onChange, { alt: e.target.value }) }) })
1463
- ] });
1464
- }
1465
- function PortfolioEditor({ block, siteId, onChange }) {
1466
- const items = block.items ?? [];
1467
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1468
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1469
- /* @__PURE__ */ jsx(Field, { label: "Intro (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.intro ?? "", onChange: (e) => patch(block, onChange, { intro: e.target.value || void 0 }) }) }),
1470
- /* @__PURE__ */ jsx(
1471
- ArrayEditor,
1472
- {
1473
- items,
1474
- onChange: (next) => patch(block, onChange, { items: next }),
1475
- newItem: () => ({ imageUrl: "", title: "" }),
1476
- addLabel: "+ Project",
1477
- renderRow: (it, update, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1478
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1479
- /* @__PURE__ */ jsx(Input, { value: it.imageUrl, placeholder: "URL of upload \u2192", onChange: (e) => update({ imageUrl: e.target.value }) }),
1480
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => update({ imageUrl: url }) }, i)
1481
- ] }),
1482
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1483
- /* @__PURE__ */ jsx(Input, { value: it.title, placeholder: "Titel", onChange: (e) => update({ title: e.target.value }) }),
1484
- /* @__PURE__ */ jsx(Input, { value: it.category ?? "", placeholder: "Categorie (voor filter)", onChange: (e) => update({ category: e.target.value || void 0 }) })
1485
- ] }),
1486
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1487
- /* @__PURE__ */ jsx(Input, { value: it.description ?? "", placeholder: "Korte omschrijving", onChange: (e) => update({ description: e.target.value || void 0 }) }),
1488
- /* @__PURE__ */ jsx(Input, { value: it.href ?? "", placeholder: "Link (optioneel, i.p.v. lightbox)", onChange: (e) => update({ href: e.target.value || void 0 }) })
1489
- ] })
1490
- ] })
1491
- }
1492
- ),
1493
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 items-end gap-2", children: [
1494
- /* @__PURE__ */ jsx(Field, { label: "Kolommen", children: /* @__PURE__ */ jsx(Input, { type: "number", value: String(block.columns ?? 3), onChange: (e) => patch(block, onChange, { columns: Math.max(1, Math.min(4, Number(e.target.value) || 3)) }) }) }),
1495
- /* @__PURE__ */ jsx(ToggleField, { label: "Filterbalk", checked: block.showFilter !== false, onChange: (v) => patch(block, onChange, { showFilter: v }) }),
1496
- /* @__PURE__ */ jsx(ToggleField, { label: "Lightbox", checked: block.lightbox !== false, onChange: (v) => patch(block, onChange, { lightbox: v }) })
1497
- ] })
1498
- ] });
1499
- }
1500
- function JobsEditor({ block, siteId, onChange }) {
1501
- const items = block.items ?? [];
1502
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1503
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1504
- /* @__PURE__ */ jsx(Field, { label: "Intro (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.intro ?? "", onChange: (e) => patch(block, onChange, { intro: e.target.value || void 0 }) }) }),
1505
- /* @__PURE__ */ jsx(
1506
- ArrayEditor,
1507
- {
1508
- items,
1509
- onChange: (next) => patch(block, onChange, { items: next }),
1510
- newItem: () => ({ title: "" }),
1511
- addLabel: "+ Vacature",
1512
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1513
- /* @__PURE__ */ jsx(Input, { value: it.title, placeholder: "Functietitel", onChange: (e) => update({ title: e.target.value }) }),
1514
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
1515
- /* @__PURE__ */ jsx(Input, { value: it.employmentType ?? "", placeholder: "Fulltime/Parttime", onChange: (e) => update({ employmentType: e.target.value || void 0 }) }),
1516
- /* @__PURE__ */ jsx(Input, { value: it.location ?? "", placeholder: "Plaats", onChange: (e) => update({ location: e.target.value || void 0 }) }),
1517
- /* @__PURE__ */ jsx(Input, { value: it.salary ?? "", placeholder: "Salaris (optioneel)", onChange: (e) => update({ salary: e.target.value || void 0 }) })
1518
- ] }),
1519
- /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.description ?? "", placeholder: "Korte omschrijving", onChange: (e) => update({ description: e.target.value || void 0 }) }),
1520
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1521
- /* @__PURE__ */ jsx(Input, { value: it.applyUrl ?? "", placeholder: "Sollicitatielink (optioneel)", onChange: (e) => update({ applyUrl: e.target.value || void 0 }) }),
1522
- /* @__PURE__ */ jsx(Input, { type: "date", value: it.datePosted ?? "", title: "Plaatsingsdatum (voor Google Jobs)", onChange: (e) => update({ datePosted: e.target.value || void 0 }) })
1523
- ] })
1524
- ] })
1525
- }
1526
- ),
1527
- /* @__PURE__ */ jsx(ToggleField, { label: "JSON-LD (Google Jobs)", checked: block.jsonLd !== false, onChange: (v) => patch(block, onChange, { jsonLd: v }) })
1528
- ] });
1529
- }
1530
- function BreadcrumbsEditor({ block, onChange }) {
1531
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1532
- /* @__PURE__ */ jsx(Field, { label: "Home-label", children: /* @__PURE__ */ jsx(Input, { value: block.homeLabel ?? "Home", onChange: (e) => patch(block, onChange, { homeLabel: e.target.value }) }) }),
1533
- /* @__PURE__ */ jsx(ToggleField, { label: "JSON-LD (BreadcrumbList)", checked: block.jsonLd !== false, onChange: (v) => patch(block, onChange, { jsonLd: v }) }),
1534
- /* @__PURE__ */ jsx("p", { className: "text-xs text-slate-500", children: "Labels worden automatisch afgeleid van de URL (bv. /diensten/tuinaanleg \u2192 Diensten / Tuinaanleg)." })
1535
- ] });
1536
- }
1537
986
  const builtinBlockEditors = {
1538
987
  hero: HeroEditor,
1539
988
  richText: RichTextBlockEditor,
1540
989
  image: ImageEditor,
1541
- cta: CtaEditor,
1542
990
  faq: FaqEditor,
1543
- openingHours: OpeningHoursEditor,
1544
991
  pricing: PricingEditor,
1545
992
  newsList: NewsListEditor,
1546
993
  form: FormEditor,
1547
- spacer: SpacerEditor,
1548
994
  gallery: GalleryEditor,
1549
- testimonials: TestimonialsEditor,
1550
- team: TeamEditor,
1551
995
  agenda: AgendaEditor,
1552
- search: SearchEditor,
1553
996
  feature: FeatureEditor,
1554
- counters: CountersEditor,
1555
- logos: LogosEditor,
1556
- timeline: TimelineEditor,
1557
997
  video: VideoEditor,
1558
- banner: BannerEditor,
1559
998
  contact: ContactEditor,
1560
- social: SocialEditor,
1561
999
  map: MapEditor,
1562
1000
  newsletter: NewsletterEditor,
1563
1001
  booking: BookingEditor,
1564
- buttons: ButtonsEditor,
1565
- quote: QuoteEditor,
1566
- divider: DividerEditor,
1567
1002
  accordion: AccordionEditor,
1568
1003
  embed: EmbedEditor,
1004
+ symbolRef: SymbolRefEditor,
1569
1005
  // Indeling
1570
1006
  columns: ColumnsEditor,
1571
1007
  withSidebar: WithSidebarEditor,
1572
1008
  tabs: TabsEditor,
1573
1009
  // Nieuwe modules
1574
- cards: CardsEditor,
1575
- downloads: DownloadsEditor,
1576
- pdf: PdfEditor,
1577
1010
  countdown: CountdownEditor,
1578
1011
  slider: SliderEditor,
1579
- whatsappChat: WhatsappChatEditor,
1580
- beforeAfter: BeforeAfterEditor,
1581
- portfolio: PortfolioEditor,
1582
- jobs: JobsEditor,
1583
- breadcrumbs: BreadcrumbsEditor,
1584
1012
  // Widgets
1585
1013
  newsWidget: NewsWidgetEditor,
1586
1014
  agendaWidget: AgendaWidgetEditor,
@@ -1597,6 +1025,7 @@ const builtinBlockEditors = {
1597
1025
  };
1598
1026
  export {
1599
1027
  GenericEditor,
1028
+ NestedBlocksEditor,
1600
1029
  builtinBlockEditors
1601
1030
  };
1602
1031
  //# sourceMappingURL=index.js.map