@xiwebdesign/xicms-core 4.18.0 → 5.0.1

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 (117) hide show
  1. package/dist/XiCMSProvider.d.ts +7 -0
  2. package/dist/XiCMSProvider.js +29 -6
  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 +4 -608
  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/symbolsClient.d.ts +13 -0
  17. package/dist/admin/lib/symbolsClient.js +51 -0
  18. package/dist/admin/lib/symbolsClient.js.map +1 -0
  19. package/dist/admin/lib/zodFields.d.ts +18 -0
  20. package/dist/admin/lib/zodFields.js +65 -2
  21. package/dist/admin/lib/zodFields.js.map +1 -1
  22. package/dist/admin/panelRegistry.js +3 -0
  23. package/dist/admin/panelRegistry.js.map +1 -1
  24. package/dist/admin/settings/SettingsPanel.js +2 -0
  25. package/dist/admin/settings/SettingsPanel.js.map +1 -1
  26. package/dist/admin/settings/SnapshotsCard.d.ts +3 -0
  27. package/dist/admin/settings/SnapshotsCard.js +98 -0
  28. package/dist/admin/settings/SnapshotsCard.js.map +1 -0
  29. package/dist/admin/ui/dialog.js +11 -4
  30. package/dist/admin/ui/dialog.js.map +1 -1
  31. package/dist/admin/visual/TranslationPanel.d.ts +13 -0
  32. package/dist/admin/visual/TranslationPanel.js +73 -0
  33. package/dist/admin/visual/TranslationPanel.js.map +1 -0
  34. package/dist/admin/visual/VisualEditor.js +142 -17
  35. package/dist/admin/visual/VisualEditor.js.map +1 -1
  36. package/dist/admin.css +1 -1
  37. package/dist/agentFiles/catalog.d.ts +21 -0
  38. package/dist/agentFiles/catalog.js +78 -0
  39. package/dist/agentFiles/catalog.js.map +1 -0
  40. package/dist/agentFiles/files.d.ts +59 -0
  41. package/dist/agentFiles/files.js +109 -0
  42. package/dist/agentFiles/files.js.map +1 -0
  43. package/dist/blocks/builtins/BeforeAfter.js +1 -0
  44. package/dist/blocks/builtins/BeforeAfter.js.map +1 -1
  45. package/dist/blocks/builtins/Cards.js +1 -0
  46. package/dist/blocks/builtins/Cards.js.map +1 -1
  47. package/dist/blocks/builtins/Cta.js +1 -0
  48. package/dist/blocks/builtins/Cta.js.map +1 -1
  49. package/dist/blocks/builtins/Elements.js +1 -0
  50. package/dist/blocks/builtins/Elements.js.map +1 -1
  51. package/dist/blocks/builtins/Hero.js +2 -2
  52. package/dist/blocks/builtins/Hero.js.map +1 -1
  53. package/dist/blocks/builtins/Jobs.js +1 -0
  54. package/dist/blocks/builtins/Jobs.js.map +1 -1
  55. package/dist/blocks/builtins/Sections.js +1 -0
  56. package/dist/blocks/builtins/Sections.js.map +1 -1
  57. package/dist/blocks/builtins/SymbolRef.d.ts +2 -0
  58. package/dist/blocks/builtins/SymbolRef.js +61 -0
  59. package/dist/blocks/builtins/SymbolRef.js.map +1 -0
  60. package/dist/blocks/customTemplate/definition.d.ts +7 -0
  61. package/dist/blocks/customTemplate/definition.js +34 -0
  62. package/dist/blocks/customTemplate/definition.js.map +1 -0
  63. package/dist/blocks/customTemplate/interpret.d.ts +10 -0
  64. package/dist/blocks/customTemplate/interpret.js +136 -0
  65. package/dist/blocks/customTemplate/interpret.js.map +1 -0
  66. package/dist/blocks/registry.d.ts +8 -0
  67. package/dist/blocks/registry.js.map +1 -1
  68. package/dist/i18n/overlay.d.ts +61 -0
  69. package/dist/i18n/overlay.js +90 -0
  70. package/dist/i18n/overlay.js.map +1 -0
  71. package/dist/index.d.ts +10 -8
  72. package/dist/index.js +32 -9
  73. package/dist/index.js.map +1 -1
  74. package/dist/modules/builtins.js +3 -2
  75. package/dist/modules/builtins.js.map +1 -1
  76. package/dist/schema/blocks.d.ts +159 -0
  77. package/dist/schema/blocks.js +8 -0
  78. package/dist/schema/blocks.js.map +1 -1
  79. package/dist/schema/customBlocks.d.ts +47 -0
  80. package/dist/schema/customBlocks.js +32 -0
  81. package/dist/schema/customBlocks.js.map +1 -0
  82. package/dist/schema/fields.d.ts +122 -0
  83. package/dist/schema/fields.js +120 -0
  84. package/dist/schema/fields.js.map +1 -0
  85. package/dist/schema/forms.d.ts +6 -6
  86. package/dist/schema/pages.d.ts +15 -1
  87. package/dist/schema/pages.js +6 -2
  88. package/dist/schema/pages.js.map +1 -1
  89. package/dist/schema/siteConfig.d.ts +14 -8
  90. package/dist/schema/siteConfig.js +2 -1
  91. package/dist/schema/siteConfig.js.map +1 -1
  92. package/dist/schema/symbols.d.ts +205 -0
  93. package/dist/schema/symbols.js +18 -0
  94. package/dist/schema/symbols.js.map +1 -0
  95. package/dist/server/index.d.ts +2 -1
  96. package/dist/server/index.js +24 -0
  97. package/dist/server/index.js.map +1 -1
  98. package/dist/server/pages.d.ts +21 -0
  99. package/dist/server/pages.js +77 -0
  100. package/dist/server/pages.js.map +1 -1
  101. package/dist/server/seo.d.ts +10 -3
  102. package/dist/server/seo.js +22 -10
  103. package/dist/server/seo.js.map +1 -1
  104. package/dist/styles.css +27 -0
  105. package/package.json +9 -9
  106. package/dist/components/EditableImage.d.ts +0 -18
  107. package/dist/components/EditableImage.js +0 -62
  108. package/dist/components/EditableImage.js.map +0 -1
  109. package/dist/components/EditableRichText.d.ts +0 -14
  110. package/dist/components/EditableRichText.js +0 -26
  111. package/dist/components/EditableRichText.js.map +0 -1
  112. package/dist/components/EditableText.d.ts +0 -21
  113. package/dist/components/EditableText.js +0 -25
  114. package/dist/components/EditableText.js.map +0 -1
  115. package/dist/content/ContentProvider.d.ts +0 -23
  116. package/dist/content/ContentProvider.js +0 -86
  117. package/dist/content/ContentProvider.js.map +0 -1
@@ -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,31 +136,6 @@ 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
141
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
@@ -181,21 +157,6 @@ function FaqEditor({ block, siteId, onChange }) {
181
157
  )
182
158
  ] });
183
159
  }
184
- function OpeningHoursEditor({ block, onChange }) {
185
- const rows = block.rows ?? [];
186
- const set = (next) => patch(block, onChange, { rows: next });
187
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
188
- /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
189
- rows.map((r, i) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_1fr_auto] items-end gap-2", children: [
190
- /* @__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)) }) }),
191
- /* @__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)) }) }),
192
- /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(rows.filter((_, j) => j !== i)), children: "\u2715" })
193
- ] }, i)),
194
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...rows, { day: "", hours: "" }]), children: "+ Rij toevoegen" }) }),
195
- /* @__PURE__ */ jsx(ToggleField, { label: "'Nu geopend'-badge", checked: Boolean(block.showStatus), onChange: (v) => patch(block, onChange, { showStatus: v }) }),
196
- /* @__PURE__ */ jsx(ToggleField, { label: "JSON-LD (openingstijden voor Google)", checked: Boolean(block.jsonLd), onChange: (v) => patch(block, onChange, { jsonLd: v }) })
197
- ] });
198
- }
199
160
  function PricingEditor({ block, onChange }) {
200
161
  const items = block.items ?? [];
201
162
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
@@ -293,21 +254,6 @@ function FormEditor({ block, siteId, onChange }) {
293
254
  missing && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-600", children: "Dit formulier-id bestaat niet (meer). Kies een bestaand formulier." })
294
255
  ] });
295
256
  }
296
- function SpacerEditor({ block, onChange }) {
297
- return /* @__PURE__ */ jsx(Field, { label: "Hoogte", children: /* @__PURE__ */ jsx(
298
- Select,
299
- {
300
- value: block.size ?? "md",
301
- onValueChange: (v) => patch(block, onChange, { size: v }),
302
- options: [
303
- { value: "sm", label: "Klein" },
304
- { value: "md", label: "Normaal" },
305
- { value: "lg", label: "Groot" },
306
- { value: "xl", label: "Extra groot" }
307
- ]
308
- }
309
- ) });
310
- }
311
257
  function GalleryEditor({ block, siteId, onChange }) {
312
258
  const items = block.items ?? [];
313
259
  const set = (next) => patch(block, onChange, { items: next });
@@ -364,67 +310,6 @@ function GalleryEditor({ block, siteId, onChange }) {
364
310
  /* @__PURE__ */ jsx(ToggleField, { label: "Filterbalk op tags", checked: Boolean(block.showFilter), onChange: (v) => patch(block, onChange, { showFilter: v }) })
365
311
  ] });
366
312
  }
367
- function TestimonialsEditor({ block, siteId, onChange }) {
368
- const items = block.items ?? [];
369
- const set = (next) => patch(block, onChange, { items: next });
370
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
371
- /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
372
- items.map((it, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2 rounded-lg border border-slate-200 p-3", children: [
373
- /* @__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)) }) }),
374
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
375
- /* @__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)) }) }),
376
- /* @__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)) }) }),
377
- /* @__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)) }) })
378
- ] }),
379
- /* @__PURE__ */ jsx(Field, { label: "Avatar", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
380
- /* @__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" }),
381
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => set(items.map((x, j) => j === i ? { ...x, avatarUrl: url } : x)) })
382
- ] }) }),
383
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(items.filter((_, j) => j !== i)), children: "Verwijderen" }) })
384
- ] }, i)),
385
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...items, { quote: "", author: "", rating: 5 }]), children: "+ Review toevoegen" }) })
386
- ] });
387
- }
388
- function TeamEditor({ block, siteId, onChange }) {
389
- const members = block.members ?? [];
390
- const set = (next) => patch(block, onChange, { members: next });
391
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
392
- /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
393
- members.map((m, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2 rounded-lg border border-slate-200 p-3", children: [
394
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
395
- /* @__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)) }) }),
396
- /* @__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)) }) })
397
- ] }),
398
- /* @__PURE__ */ jsx(Field, { label: "Foto", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
399
- /* @__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" }),
400
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => set(members.map((x, j) => j === i ? { ...x, photoUrl: url } : x)) })
401
- ] }) }),
402
- /* @__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)) }) }),
403
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
404
- /* @__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)) }) }),
405
- /* @__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)) }) })
406
- ] }),
407
- /* @__PURE__ */ jsx(Field, { label: "Social (platform|url, \xE9\xE9n per regel)", children: /* @__PURE__ */ jsx(
408
- Textarea,
409
- {
410
- rows: 2,
411
- value: (m.social ?? []).map((s) => `${s.platform}|${s.href}`).join("\n"),
412
- onChange: (e) => set(
413
- members.map(
414
- (x, j) => j === i ? {
415
- ...x,
416
- 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() }))
417
- } : x
418
- )
419
- )
420
- }
421
- ) }),
422
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => set(members.filter((_, j) => j !== i)), children: "Verwijderen" }) })
423
- ] }, i)),
424
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...members, { name: "" }]), children: "+ Lid toevoegen" }) }),
425
- /* @__PURE__ */ jsx(ToggleField, { label: "Groeperen per afdeling", checked: Boolean(block.groupByDepartment), onChange: (v) => patch(block, onChange, { groupByDepartment: v }) })
426
- ] });
427
- }
428
313
  function AgendaEditor({ block, onChange }) {
429
314
  const events = block.events ?? [];
430
315
  const set = (next) => patch(block, onChange, { events: next });
@@ -442,22 +327,6 @@ function AgendaEditor({ block, onChange }) {
442
327
  /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { type: "button", variant: "secondary", size: "sm", onClick: () => set([...events, { title: "", start: "" }]), children: "+ Evenement toevoegen" }) })
443
328
  ] });
444
329
  }
445
- function SearchEditor({ block, onChange }) {
446
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
447
- /* @__PURE__ */ jsx(Field, { label: "Placeholder", children: /* @__PURE__ */ jsx(Input, { value: block.placeholder ?? "Zoeken\u2026", onChange: (e) => patch(block, onChange, { placeholder: e.target.value }) }) }),
448
- /* @__PURE__ */ jsx(Field, { label: "Nieuws meenemen", children: /* @__PURE__ */ jsx(
449
- Select,
450
- {
451
- value: block.includeNews === false ? "no" : "yes",
452
- onValueChange: (v) => patch(block, onChange, { includeNews: v === "yes" }),
453
- options: [
454
- { value: "yes", label: "Ja, ook nieuwsartikelen" },
455
- { value: "no", label: "Nee, alleen pagina's" }
456
- ]
457
- }
458
- ) })
459
- ] });
460
- }
461
330
  function HeadingField({ block, onChange }) {
462
331
  return /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) });
463
332
  }
@@ -482,79 +351,6 @@ function FeatureEditor({ block, siteId, onChange }) {
482
351
  ] })
483
352
  ] });
484
353
  }
485
- function CountersEditor({ block, siteId, onChange }) {
486
- const items = block.items ?? [];
487
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
488
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
489
- /* @__PURE__ */ jsx(
490
- ArrayEditor,
491
- {
492
- items,
493
- onChange: (next) => patch(block, onChange, { items: next }),
494
- newItem: () => ({ value: "", label: "" }),
495
- addLabel: "+ Teller",
496
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-4 gap-2", children: [
497
- /* @__PURE__ */ jsx(Input, { value: it.prefix ?? "", placeholder: "\xB1", onChange: (e) => update({ prefix: e.target.value }) }),
498
- /* @__PURE__ */ jsx(Input, { value: it.value, placeholder: "100", onChange: (e) => update({ value: e.target.value }) }),
499
- /* @__PURE__ */ jsx(Input, { value: it.suffix ?? "", placeholder: "+", onChange: (e) => update({ suffix: e.target.value }) }),
500
- /* @__PURE__ */ jsx(Input, { value: it.label, placeholder: "Label", onChange: (e) => update({ label: e.target.value }) })
501
- ] })
502
- }
503
- ),
504
- /* @__PURE__ */ jsx(ToggleField, { label: "Tel-animatie bij scrollen", checked: block.animate !== false, onChange: (v) => patch(block, onChange, { animate: v }) })
505
- ] });
506
- }
507
- function LogosEditor({ block, siteId, onChange }) {
508
- const items = block.items ?? [];
509
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
510
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
511
- /* @__PURE__ */ jsx(
512
- ArrayEditor,
513
- {
514
- items,
515
- onChange: (next) => patch(block, onChange, { items: next }),
516
- newItem: () => ({ src: "", alt: "" }),
517
- addLabel: "+ Logo",
518
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
519
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
520
- /* @__PURE__ */ jsx(Input, { value: it.src, placeholder: "URL of upload \u2192", onChange: (e) => update({ src: e.target.value }) }),
521
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => update({ src: url }) })
522
- ] }),
523
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
524
- /* @__PURE__ */ jsx(Input, { value: it.alt, placeholder: "Alt-tekst", onChange: (e) => update({ alt: e.target.value }) }),
525
- /* @__PURE__ */ jsx(Input, { value: it.href ?? "", placeholder: "Link (optioneel)", onChange: (e) => update({ href: e.target.value }) })
526
- ] })
527
- ] })
528
- }
529
- ),
530
- /* @__PURE__ */ jsx(ToggleField, { label: "Logo's in grijstinten", checked: block.grayscale !== false, onChange: (v) => patch(block, onChange, { grayscale: v }) }),
531
- /* @__PURE__ */ jsx(ToggleField, { label: "Doorlopende band (marquee)", checked: Boolean(block.marquee), onChange: (v) => patch(block, onChange, { marquee: v }) })
532
- ] });
533
- }
534
- function TimelineEditor({ block, siteId, onChange }) {
535
- const items = block.items ?? [];
536
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
537
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
538
- /* @__PURE__ */ jsx(
539
- ArrayEditor,
540
- {
541
- items,
542
- onChange: (next) => patch(block, onChange, { items: next }),
543
- newItem: () => ({ title: "" }),
544
- addLabel: "+ Stap",
545
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
546
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[3rem_1fr_1fr] gap-2", children: [
547
- /* @__PURE__ */ jsx(Input, { value: it.icon ?? "", placeholder: "\u{1F528}", title: "Icoon (emoji)", onChange: (e) => update({ icon: e.target.value || void 0 }) }),
548
- /* @__PURE__ */ jsx(Input, { value: it.title, placeholder: "Titel", onChange: (e) => update({ title: e.target.value }) }),
549
- /* @__PURE__ */ jsx(Input, { value: it.date ?? "", placeholder: "Datum/label", onChange: (e) => update({ date: e.target.value }) })
550
- ] }),
551
- /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.text ?? "", placeholder: "Toelichting", onChange: (e) => update({ text: e.target.value }) })
552
- ] })
553
- }
554
- ),
555
- /* @__PURE__ */ jsx(ToggleField, { label: "Alternerende layout (links/rechts)", checked: Boolean(block.alternate), onChange: (v) => patch(block, onChange, { alternate: v }) })
556
- ] });
557
- }
558
354
  function VideoEditor({ block, siteId, onChange }) {
559
355
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
560
356
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
@@ -570,18 +366,6 @@ function VideoEditor({ block, siteId, onChange }) {
570
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 }) })
571
367
  ] });
572
368
  }
573
- function BannerEditor({ block, onChange }) {
574
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
575
- /* @__PURE__ */ jsx(Field, { label: "Tekst", children: /* @__PURE__ */ jsx(Input, { value: block.text ?? "", onChange: (e) => patch(block, onChange, { text: e.target.value }) }) }),
576
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
577
- /* @__PURE__ */ jsx(Field, { label: "Link", children: /* @__PURE__ */ jsx(Input, { value: block.href ?? "", onChange: (e) => patch(block, onChange, { href: e.target.value }) }) }),
578
- /* @__PURE__ */ jsx(Field, { label: "Linktekst", children: /* @__PURE__ */ jsx(Input, { value: block.linkLabel ?? "", onChange: (e) => patch(block, onChange, { linkLabel: e.target.value }) }) }),
579
- /* @__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" }] }) })
580
- ] }),
581
- /* @__PURE__ */ jsx(ToggleField, { label: "Sluitbaar", checked: block.dismissible !== false, onChange: (v) => patch(block, onChange, { dismissible: v }) }),
582
- 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 }) }) })
583
- ] });
584
- }
585
369
  function GeoField({ value, onChange }) {
586
370
  const [text, setText] = useState(value ? `${value.lat}, ${value.lng}` : "");
587
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(
@@ -622,25 +406,6 @@ function ContactEditor({ block, siteId, onChange }) {
622
406
  /* @__PURE__ */ jsx(ToggleField, { label: "JSON-LD (LocalBusiness)", checked: Boolean(block.jsonLd), onChange: (v) => patch(block, onChange, { jsonLd: v }) })
623
407
  ] });
624
408
  }
625
- function SocialEditor({ block, siteId, onChange }) {
626
- const items = block.items ?? [];
627
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
628
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
629
- /* @__PURE__ */ jsx(
630
- ArrayEditor,
631
- {
632
- items,
633
- onChange: (next) => patch(block, onChange, { items: next }),
634
- newItem: () => ({ platform: "", href: "" }),
635
- addLabel: "+ Social-link",
636
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
637
- /* @__PURE__ */ jsx(Input, { value: it.platform, placeholder: "bv. Instagram", onChange: (e) => update({ platform: e.target.value }) }),
638
- /* @__PURE__ */ jsx(Input, { value: it.href, placeholder: "https://\u2026", onChange: (e) => update({ href: e.target.value }) })
639
- ] })
640
- }
641
- )
642
- ] });
643
- }
644
409
  function MapCoordField({ block, onChange }) {
645
410
  const lat = block.lat;
646
411
  const lng = block.lng;
@@ -756,48 +521,6 @@ function BookingEditor({ block, siteId, onChange }) {
756
521
  /* @__PURE__ */ jsx(ToggleField, { label: "Pas tonen na cookie-toestemming", checked: block.consentGated !== false, onChange: (v) => patch(block, onChange, { consentGated: v }) })
757
522
  ] });
758
523
  }
759
- function ButtonsEditor({ block, onChange }) {
760
- const items = block.items ?? [];
761
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
762
- /* @__PURE__ */ jsx(Field, { label: "Uitlijning", children: /* @__PURE__ */ jsx(
763
- Select,
764
- {
765
- value: block.align ?? "left",
766
- onValueChange: (v) => patch(block, onChange, { align: v }),
767
- options: [{ value: "left", label: "Links" }, { value: "center", label: "Midden" }, { value: "right", label: "Rechts" }]
768
- }
769
- ) }),
770
- /* @__PURE__ */ jsx(
771
- ArrayEditor,
772
- {
773
- items,
774
- onChange: (next) => patch(block, onChange, { items: next }),
775
- newItem: () => ({ label: "", href: "#", variant: "primary" }),
776
- addLabel: "+ Knop",
777
- renderRow: (b, update) => /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
778
- /* @__PURE__ */ jsx(Input, { value: b.label, placeholder: "Label", onChange: (e) => update({ label: e.target.value }) }),
779
- /* @__PURE__ */ jsx(Input, { value: b.href, placeholder: "/pad of https://\u2026", onChange: (e) => update({ href: e.target.value }) }),
780
- /* @__PURE__ */ jsx(Select, { value: b.variant, onValueChange: (v) => update({ variant: v }), options: VARIANT_OPTIONS })
781
- ] })
782
- }
783
- )
784
- ] });
785
- }
786
- function QuoteEditor({ block, onChange }) {
787
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
788
- /* @__PURE__ */ jsx(Field, { label: "Uitspraak", children: /* @__PURE__ */ jsx(Textarea, { rows: 3, value: block.text ?? "", onChange: (e) => patch(block, onChange, { text: e.target.value }) }) }),
789
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
790
- /* @__PURE__ */ jsx(Field, { label: "Auteur", children: /* @__PURE__ */ jsx(Input, { value: block.author ?? "", onChange: (e) => patch(block, onChange, { author: e.target.value }) }) }),
791
- /* @__PURE__ */ jsx(Field, { label: "Functie", children: /* @__PURE__ */ jsx(Input, { value: block.role ?? "", onChange: (e) => patch(block, onChange, { role: e.target.value }) }) })
792
- ] })
793
- ] });
794
- }
795
- function DividerEditor({ block, onChange }) {
796
- return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
797
- /* @__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" }] }) }),
798
- /* @__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" }] }) })
799
- ] });
800
- }
801
524
  function AccordionEditor({ block, siteId, onChange }) {
802
525
  const items = block.items ?? [];
803
526
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
@@ -992,103 +715,6 @@ function TabsEditor({ block, siteId, onChange }) {
992
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" })
993
716
  ] });
994
717
  }
995
- function CardsEditor({ block, siteId, onChange }) {
996
- const items = block.items ?? [];
997
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
998
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
999
- /* @__PURE__ */ jsx(Field, { label: "Intro (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.intro ?? "", onChange: (e) => patch(block, onChange, { intro: e.target.value }) }) }),
1000
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
1001
- /* @__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)) }) }) }),
1002
- /* @__PURE__ */ jsx(Field, { label: "Beeldstijl", hint: "cover = beeld tot de kaartranden", children: /* @__PURE__ */ jsx(
1003
- Select,
1004
- {
1005
- value: block.imageStyle ?? "inset",
1006
- onValueChange: (v) => patch(block, onChange, { imageStyle: v }),
1007
- options: [
1008
- { value: "inset", label: "Ingekaderd" },
1009
- { value: "cover", label: "Edge-to-edge (postkaart)" }
1010
- ]
1011
- }
1012
- ) })
1013
- ] }),
1014
- /* @__PURE__ */ jsx(
1015
- ArrayEditor,
1016
- {
1017
- items,
1018
- onChange: (next) => patch(block, onChange, { items: next }),
1019
- newItem: () => ({ icon: "", title: "", text: "" }),
1020
- addLabel: "+ Kaart",
1021
- renderRow: (it, update, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1022
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1023
- /* @__PURE__ */ jsx(Field, { label: "Icoon (emoji)", children: /* @__PURE__ */ jsx(Input, { value: it.icon ?? "", onChange: (e) => update({ icon: e.target.value }) }) }),
1024
- /* @__PURE__ */ jsx(Field, { label: "Titel", children: /* @__PURE__ */ jsx(Input, { value: it.title, onChange: (e) => update({ title: e.target.value }) }) })
1025
- ] }),
1026
- /* @__PURE__ */ jsx(Field, { label: "Tekst", children: /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.text ?? "", onChange: (e) => update({ text: e.target.value }) }) }),
1027
- /* @__PURE__ */ jsx(Field, { label: "Afbeelding (optioneel)", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1028
- /* @__PURE__ */ jsx(Input, { value: it.imageUrl ?? "", onChange: (e) => update({ imageUrl: e.target.value }), placeholder: "URL of upload \u2192" }),
1029
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => update({ imageUrl: url }) }, i)
1030
- ] }) }),
1031
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1032
- /* @__PURE__ */ jsx(Field, { label: "Link (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: it.href ?? "", onChange: (e) => update({ href: e.target.value }) }) }),
1033
- /* @__PURE__ */ jsx(Field, { label: "Linktekst", children: /* @__PURE__ */ jsx(Input, { value: it.linkLabel ?? "", onChange: (e) => update({ linkLabel: e.target.value }) }) })
1034
- ] }),
1035
- /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-1.5 text-xs text-slate-600", children: [
1036
- /* @__PURE__ */ jsx("input", { type: "checkbox", checked: Boolean(it.featured), onChange: (e) => update({ featured: e.target.checked }) }),
1037
- "Uitgelicht (accentrand)"
1038
- ] })
1039
- ] })
1040
- }
1041
- )
1042
- ] });
1043
- }
1044
- function DownloadsEditor({ block, siteId, onChange }) {
1045
- const items = block.items ?? [];
1046
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1047
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1048
- /* @__PURE__ */ jsx(
1049
- ArrayEditor,
1050
- {
1051
- items,
1052
- onChange: (next) => patch(block, onChange, { items: next }),
1053
- newItem: () => ({ label: "", href: "", meta: "" }),
1054
- addLabel: "+ Document",
1055
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1056
- /* @__PURE__ */ jsx(Input, { value: it.label, placeholder: "Naam (bv. Brochure 2026)", onChange: (e) => update({ label: e.target.value }) }),
1057
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1058
- /* @__PURE__ */ jsx(Input, { value: it.href, placeholder: "URL naar bestand", onChange: (e) => update({ href: e.target.value }) }),
1059
- /* @__PURE__ */ jsx(Input, { value: it.meta ?? "", placeholder: "PDF \xB7 1,2 MB", onChange: (e) => update({ meta: e.target.value }) })
1060
- ] })
1061
- ] })
1062
- }
1063
- )
1064
- ] });
1065
- }
1066
- function PdfEditor({ block, siteId, onChange }) {
1067
- const docs = block.documents ?? [];
1068
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1069
- /* @__PURE__ */ jsxs("p", { className: "rounded-md bg-slate-50 p-2 text-xs text-slate-600", children: [
1070
- "Toon \xE9\xE9n of meer ",
1071
- /* @__PURE__ */ jsx("strong", { children: "PDF's" }),
1072
- " (bv. lunch-, diner- en wijnkaart). Bij meerdere verschijnen tabs. Vervang een kaart door simpelweg de URL te wijzigen."
1073
- ] }),
1074
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1075
- /* @__PURE__ */ jsx(
1076
- ArrayEditor,
1077
- {
1078
- items: docs,
1079
- onChange: (next) => patch(block, onChange, { documents: next }),
1080
- newItem: () => ({ label: "", url: "" }),
1081
- addLabel: "+ PDF",
1082
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1083
- /* @__PURE__ */ jsx(Input, { value: it.label, placeholder: "Naam (bv. Lunchkaart)", onChange: (e) => update({ label: e.target.value }) }),
1084
- /* @__PURE__ */ jsx(Input, { value: it.url, placeholder: "URL naar de PDF", onChange: (e) => update({ url: e.target.value }) })
1085
- ] })
1086
- }
1087
- ),
1088
- /* @__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)) }) }) }),
1089
- /* @__PURE__ */ jsx(ToggleField, { label: "Open/Download-link tonen", checked: block.showDownload !== false, onChange: (v) => patch(block, onChange, { showDownload: v }) })
1090
- ] });
1091
- }
1092
718
  function CountdownEditor({ block, onChange }) {
1093
719
  return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1094
720
  /* @__PURE__ */ jsx(Field, { label: "Kop", children: /* @__PURE__ */ jsx(Input, { value: block.heading ?? "", onChange: (e) => patch(block, onChange, { heading: e.target.value }) }) }),
@@ -1357,263 +983,32 @@ function CountdownWidgetEditor({ block, onChange }) {
1357
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 }) }) })
1358
984
  ] });
1359
985
  }
1360
- function GenericEditor({ block, siteId, onChange }) {
1361
- const registry = useRegistry();
1362
- const def = registry.get(String(block._type ?? ""));
1363
- const fields = def ? introspectObjectSchema(def.schema) : [];
1364
- if (fields.length === 0) {
1365
- return /* @__PURE__ */ jsx("p", { className: "text-sm text-slate-500", children: "Voor dit bloktype is geen editor beschikbaar." });
1366
- }
1367
- return /* @__PURE__ */ jsx("div", { className: "grid gap-3", children: fields.map((f) => {
1368
- if (f.kind === "boolean") {
1369
- return /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2 text-sm", children: [
1370
- /* @__PURE__ */ jsx(Switch, { checked: Boolean(block[f.key]), onCheckedChange: (v) => patch(block, onChange, { [f.key]: v }) }),
1371
- f.label
1372
- ] }, f.key);
1373
- }
1374
- if (f.kind === "enum") {
1375
- return /* @__PURE__ */ jsx(Field, { label: f.label, children: /* @__PURE__ */ jsx(
1376
- Select,
1377
- {
1378
- value: String(block[f.key] ?? f.options?.[0] ?? ""),
1379
- onValueChange: (v) => patch(block, onChange, { [f.key]: v }),
1380
- options: (f.options ?? []).map((o) => ({ value: o, label: o }))
1381
- }
1382
- ) }, f.key);
1383
- }
1384
- if (f.kind === "number") {
1385
- return /* @__PURE__ */ jsx(Field, { label: f.label, children: /* @__PURE__ */ jsx(
1386
- Input,
1387
- {
1388
- type: "number",
1389
- value: String(block[f.key] ?? ""),
1390
- onChange: (e) => patch(block, onChange, { [f.key]: e.target.value === "" ? void 0 : Number(e.target.value) })
1391
- }
1392
- ) }, f.key);
1393
- }
1394
- if (f.kind === "json") {
1395
- return /* @__PURE__ */ jsx(GenericJsonField, { field: f, block, onChange }, f.key);
1396
- }
1397
- if (f.key === "html") {
1398
- return /* @__PURE__ */ jsx(Field, { label: "Tekst", children: /* @__PURE__ */ jsx(RichTextEditor, { siteId, value: block.html ?? "", onChange: (html) => patch(block, onChange, { html }) }) }, f.key);
1399
- }
1400
- const isImage = /image|photo|foto|logo|cover|avatar/i.test(f.key);
1401
- if (isImage) {
1402
- return /* @__PURE__ */ jsx(Field, { label: f.label, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1403
- /* @__PURE__ */ jsx(Input, { value: String(block[f.key] ?? ""), onChange: (e) => patch(block, onChange, { [f.key]: e.target.value }), placeholder: "URL of kies \u2192" }),
1404
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => patch(block, onChange, { [f.key]: url }) })
1405
- ] }) }, f.key);
1406
- }
1407
- const long = (f.maxLength ?? 0) > 500;
1408
- 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);
1409
- }) });
1410
- }
1411
- function GenericJsonField({
1412
- field,
1413
- block,
1414
- onChange
1415
- }) {
1416
- const [text, setText] = useState(() => JSON.stringify(block[field.key] ?? null, null, 2));
1417
- const [error, setError] = useState(null);
1418
- const commit = () => {
1419
- try {
1420
- const parsed = JSON.parse(text);
1421
- const res = field.schema.safeParse(parsed);
1422
- if (!res.success) {
1423
- setError("Voldoet niet aan het verwachte formaat van dit veld.");
1424
- return;
1425
- }
1426
- setError(null);
1427
- patch(block, onChange, { [field.key]: res.data });
1428
- } catch {
1429
- setError("Geen geldige JSON.");
1430
- }
1431
- };
1432
- return /* @__PURE__ */ jsxs(Field, { label: `${field.label} (JSON)`, hint: "Geavanceerd veld \u2014 wordt gecontroleerd v\xF3\xF3r opslaan.", children: [
1433
- /* @__PURE__ */ jsx(
1434
- Textarea,
1435
- {
1436
- rows: 6,
1437
- value: text,
1438
- onChange: (e) => setText(e.target.value),
1439
- onBlur: commit,
1440
- spellCheck: false,
1441
- className: "font-mono text-xs"
1442
- }
1443
- ),
1444
- error && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-600", children: error })
1445
- ] });
1446
- }
1447
- function WhatsappChatEditor({ block, onChange }) {
1448
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1449
- /* @__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 }) }) }),
1450
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1451
- /* @__PURE__ */ jsx(Field, { label: "Label (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.label ?? "", onChange: (e) => patch(block, onChange, { label: e.target.value || void 0 }) }) }),
1452
- /* @__PURE__ */ jsx(Field, { label: "Positie", children: /* @__PURE__ */ jsx(
1453
- Select,
1454
- {
1455
- value: block.position ?? "br",
1456
- onValueChange: (v) => patch(block, onChange, { position: v }),
1457
- options: [
1458
- { value: "br", label: "Rechtsonder" },
1459
- { value: "bl", label: "Linksonder" }
1460
- ]
1461
- }
1462
- ) })
1463
- ] }),
1464
- /* @__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 }) }) })
1465
- ] });
1466
- }
1467
- function BeforeAfterEditor({ block, siteId, onChange }) {
1468
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1469
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1470
- /* @__PURE__ */ jsx(Field, { label: "Foto v\xF3\xF3r", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1471
- /* @__PURE__ */ jsx(Input, { value: block.beforeUrl ?? "", onChange: (e) => patch(block, onChange, { beforeUrl: e.target.value }), placeholder: "URL of upload \u2192" }),
1472
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => patch(block, onChange, { beforeUrl: url }) })
1473
- ] }) }),
1474
- /* @__PURE__ */ jsx(Field, { label: "Foto n\xE1", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1475
- /* @__PURE__ */ jsx(Input, { value: block.afterUrl ?? "", onChange: (e) => patch(block, onChange, { afterUrl: e.target.value }), placeholder: "URL of upload \u2192" }),
1476
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => patch(block, onChange, { afterUrl: url }) })
1477
- ] }) }),
1478
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
1479
- /* @__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 }) }) }),
1480
- /* @__PURE__ */ jsx(Field, { label: "Label n\xE1", children: /* @__PURE__ */ jsx(Input, { value: block.afterLabel ?? "Na", onChange: (e) => patch(block, onChange, { afterLabel: e.target.value }) }) }),
1481
- /* @__PURE__ */ jsx(Field, { label: "Beeldverhouding", children: /* @__PURE__ */ jsx(
1482
- Select,
1483
- {
1484
- value: block.aspectRatio ?? "4/3",
1485
- onValueChange: (v) => patch(block, onChange, { aspectRatio: v }),
1486
- options: [
1487
- { value: "16/9", label: "16:9" },
1488
- { value: "4/3", label: "4:3" },
1489
- { value: "3/2", label: "3:2" },
1490
- { value: "1/1", label: "Vierkant" }
1491
- ]
1492
- }
1493
- ) })
1494
- ] }),
1495
- /* @__PURE__ */ jsx(Field, { label: "Alt-tekst", children: /* @__PURE__ */ jsx(Input, { value: block.alt ?? "", onChange: (e) => patch(block, onChange, { alt: e.target.value }) }) })
1496
- ] });
1497
- }
1498
- function PortfolioEditor({ block, siteId, onChange }) {
1499
- const items = block.items ?? [];
1500
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1501
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1502
- /* @__PURE__ */ jsx(Field, { label: "Intro (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.intro ?? "", onChange: (e) => patch(block, onChange, { intro: e.target.value || void 0 }) }) }),
1503
- /* @__PURE__ */ jsx(
1504
- ArrayEditor,
1505
- {
1506
- items,
1507
- onChange: (next) => patch(block, onChange, { items: next }),
1508
- newItem: () => ({ imageUrl: "", title: "" }),
1509
- addLabel: "+ Project",
1510
- renderRow: (it, update, i) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1511
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
1512
- /* @__PURE__ */ jsx(Input, { value: it.imageUrl, placeholder: "URL of upload \u2192", onChange: (e) => update({ imageUrl: e.target.value }) }),
1513
- /* @__PURE__ */ jsx(ImageUploadButton, { siteId, onUploaded: (url) => update({ imageUrl: url }) }, i)
1514
- ] }),
1515
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1516
- /* @__PURE__ */ jsx(Input, { value: it.title, placeholder: "Titel", onChange: (e) => update({ title: e.target.value }) }),
1517
- /* @__PURE__ */ jsx(Input, { value: it.category ?? "", placeholder: "Categorie (voor filter)", onChange: (e) => update({ category: e.target.value || void 0 }) })
1518
- ] }),
1519
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1520
- /* @__PURE__ */ jsx(Input, { value: it.description ?? "", placeholder: "Korte omschrijving", onChange: (e) => update({ description: e.target.value || void 0 }) }),
1521
- /* @__PURE__ */ jsx(Input, { value: it.href ?? "", placeholder: "Link (optioneel, i.p.v. lightbox)", onChange: (e) => update({ href: e.target.value || void 0 }) })
1522
- ] })
1523
- ] })
1524
- }
1525
- ),
1526
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 items-end gap-2", children: [
1527
- /* @__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)) }) }) }),
1528
- /* @__PURE__ */ jsx(ToggleField, { label: "Filterbalk", checked: block.showFilter !== false, onChange: (v) => patch(block, onChange, { showFilter: v }) }),
1529
- /* @__PURE__ */ jsx(ToggleField, { label: "Lightbox", checked: block.lightbox !== false, onChange: (v) => patch(block, onChange, { lightbox: v }) })
1530
- ] })
1531
- ] });
1532
- }
1533
- function JobsEditor({ block, siteId, onChange }) {
1534
- const items = block.items ?? [];
1535
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1536
- /* @__PURE__ */ jsx(HeadingField, { block, siteId, onChange }),
1537
- /* @__PURE__ */ jsx(Field, { label: "Intro (optioneel)", children: /* @__PURE__ */ jsx(Input, { value: block.intro ?? "", onChange: (e) => patch(block, onChange, { intro: e.target.value || void 0 }) }) }),
1538
- /* @__PURE__ */ jsx(
1539
- ArrayEditor,
1540
- {
1541
- items,
1542
- onChange: (next) => patch(block, onChange, { items: next }),
1543
- newItem: () => ({ title: "" }),
1544
- addLabel: "+ Vacature",
1545
- renderRow: (it, update) => /* @__PURE__ */ jsxs("div", { className: "grid gap-2", children: [
1546
- /* @__PURE__ */ jsx(Input, { value: it.title, placeholder: "Functietitel", onChange: (e) => update({ title: e.target.value }) }),
1547
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
1548
- /* @__PURE__ */ jsx(Input, { value: it.employmentType ?? "", placeholder: "Fulltime/Parttime", onChange: (e) => update({ employmentType: e.target.value || void 0 }) }),
1549
- /* @__PURE__ */ jsx(Input, { value: it.location ?? "", placeholder: "Plaats", onChange: (e) => update({ location: e.target.value || void 0 }) }),
1550
- /* @__PURE__ */ jsx(Input, { value: it.salary ?? "", placeholder: "Salaris (optioneel)", onChange: (e) => update({ salary: e.target.value || void 0 }) })
1551
- ] }),
1552
- /* @__PURE__ */ jsx(Textarea, { rows: 2, value: it.description ?? "", placeholder: "Korte omschrijving", onChange: (e) => update({ description: e.target.value || void 0 }) }),
1553
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
1554
- /* @__PURE__ */ jsx(Input, { value: it.applyUrl ?? "", placeholder: "Sollicitatielink (optioneel)", onChange: (e) => update({ applyUrl: e.target.value || void 0 }) }),
1555
- /* @__PURE__ */ jsx(Input, { type: "date", value: it.datePosted ?? "", title: "Plaatsingsdatum (voor Google Jobs)", onChange: (e) => update({ datePosted: e.target.value || void 0 }) })
1556
- ] })
1557
- ] })
1558
- }
1559
- ),
1560
- /* @__PURE__ */ jsx(ToggleField, { label: "JSON-LD (Google Jobs)", checked: block.jsonLd !== false, onChange: (v) => patch(block, onChange, { jsonLd: v }) })
1561
- ] });
1562
- }
1563
- function BreadcrumbsEditor({ block, onChange }) {
1564
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
1565
- /* @__PURE__ */ jsx(Field, { label: "Home-label", children: /* @__PURE__ */ jsx(Input, { value: block.homeLabel ?? "Home", onChange: (e) => patch(block, onChange, { homeLabel: e.target.value }) }) }),
1566
- /* @__PURE__ */ jsx(ToggleField, { label: "JSON-LD (BreadcrumbList)", checked: block.jsonLd !== false, onChange: (v) => patch(block, onChange, { jsonLd: v }) }),
1567
- /* @__PURE__ */ jsx("p", { className: "text-xs text-slate-500", children: "Labels worden automatisch afgeleid van de URL (bv. /diensten/tuinaanleg \u2192 Diensten / Tuinaanleg)." })
1568
- ] });
1569
- }
1570
986
  const builtinBlockEditors = {
1571
987
  hero: HeroEditor,
1572
988
  richText: RichTextBlockEditor,
1573
989
  image: ImageEditor,
1574
- cta: CtaEditor,
1575
990
  faq: FaqEditor,
1576
- openingHours: OpeningHoursEditor,
1577
991
  pricing: PricingEditor,
1578
992
  newsList: NewsListEditor,
1579
993
  form: FormEditor,
1580
- spacer: SpacerEditor,
1581
994
  gallery: GalleryEditor,
1582
- testimonials: TestimonialsEditor,
1583
- team: TeamEditor,
1584
995
  agenda: AgendaEditor,
1585
- search: SearchEditor,
1586
996
  feature: FeatureEditor,
1587
- counters: CountersEditor,
1588
- logos: LogosEditor,
1589
- timeline: TimelineEditor,
1590
997
  video: VideoEditor,
1591
- banner: BannerEditor,
1592
998
  contact: ContactEditor,
1593
- social: SocialEditor,
1594
999
  map: MapEditor,
1595
1000
  newsletter: NewsletterEditor,
1596
1001
  booking: BookingEditor,
1597
- buttons: ButtonsEditor,
1598
- quote: QuoteEditor,
1599
- divider: DividerEditor,
1600
1002
  accordion: AccordionEditor,
1601
1003
  embed: EmbedEditor,
1004
+ symbolRef: SymbolRefEditor,
1602
1005
  // Indeling
1603
1006
  columns: ColumnsEditor,
1604
1007
  withSidebar: WithSidebarEditor,
1605
1008
  tabs: TabsEditor,
1606
1009
  // Nieuwe modules
1607
- cards: CardsEditor,
1608
- downloads: DownloadsEditor,
1609
- pdf: PdfEditor,
1610
1010
  countdown: CountdownEditor,
1611
1011
  slider: SliderEditor,
1612
- whatsappChat: WhatsappChatEditor,
1613
- beforeAfter: BeforeAfterEditor,
1614
- portfolio: PortfolioEditor,
1615
- jobs: JobsEditor,
1616
- breadcrumbs: BreadcrumbsEditor,
1617
1012
  // Widgets
1618
1013
  newsWidget: NewsWidgetEditor,
1619
1014
  agendaWidget: AgendaWidgetEditor,
@@ -1630,6 +1025,7 @@ const builtinBlockEditors = {
1630
1025
  };
1631
1026
  export {
1632
1027
  GenericEditor,
1028
+ NestedBlocksEditor,
1633
1029
  builtinBlockEditors
1634
1030
  };
1635
1031
  //# sourceMappingURL=index.js.map