@xiwebdesign/xicms-core 7.30.0 → 8.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/XiCMSProvider.js +22 -7
- package/dist/XiCMSProvider.js.map +1 -1
- package/dist/admin/AdminApp.js +175 -93
- package/dist/admin/AdminApp.js.map +1 -1
- package/dist/admin/AdminHelp.d.ts +1 -1
- package/dist/admin/AdminHelp.js +44 -36
- package/dist/admin/AdminHelp.js.map +1 -1
- package/dist/admin/CoreVersion.d.ts +6 -3
- package/dist/admin/CoreVersion.js +60 -24
- package/dist/admin/CoreVersion.js.map +1 -1
- package/dist/admin/NewsEditor.d.ts +7 -0
- package/dist/admin/NewsEditor.js +117 -75
- package/dist/admin/NewsEditor.js.map +1 -1
- package/dist/admin/SuperadminPanel.js +1 -1
- package/dist/admin/SuperadminPanel.js.map +1 -1
- package/dist/admin/ZoekPalet.d.ts +15 -0
- package/dist/admin/ZoekPalet.js +123 -0
- package/dist/admin/ZoekPalet.js.map +1 -0
- package/dist/admin/blockEditors/GenericEditor.js +36 -18
- package/dist/admin/blockEditors/GenericEditor.js.map +1 -1
- package/dist/admin/blockEditors/StyleEditor.js +37 -3
- package/dist/admin/blockEditors/StyleEditor.js.map +1 -1
- package/dist/admin/blockEditors/SymbolRefEditor.js +44 -2
- package/dist/admin/blockEditors/SymbolRefEditor.js.map +1 -1
- package/dist/admin/blockEditors/index.js +154 -73
- package/dist/admin/blockEditors/index.js.map +1 -1
- package/dist/admin/customBlocks/CustomBlocksPanel.js +18 -7
- package/dist/admin/customBlocks/CustomBlocksPanel.js.map +1 -1
- package/dist/admin/dashboard/DashboardPanel.js +26 -16
- package/dist/admin/dashboard/DashboardPanel.js.map +1 -1
- package/dist/admin/editors/RichTextEditor.d.ts +4 -3
- package/dist/admin/editors/RichTextEditor.js +19 -56
- package/dist/admin/editors/RichTextEditor.js.map +1 -1
- package/dist/admin/editors/fontSizeExtension.js +7 -1
- package/dist/admin/editors/fontSizeExtension.js.map +1 -1
- package/dist/admin/editors/slashMenu.d.ts +18 -0
- package/dist/admin/editors/slashMenu.js +34 -0
- package/dist/admin/editors/slashMenu.js.map +1 -0
- package/dist/admin/editors/useRijkeTekst.d.ts +48 -0
- package/dist/admin/editors/useRijkeTekst.js +310 -0
- package/dist/admin/editors/useRijkeTekst.js.map +1 -0
- package/dist/admin/forms/FormsPanel.d.ts +11 -2
- package/dist/admin/forms/FormsPanel.js +218 -65
- package/dist/admin/forms/FormsPanel.js.map +1 -1
- package/dist/admin/lib/blokInfo.d.ts +17 -0
- package/dist/admin/lib/blokInfo.js +80 -0
- package/dist/admin/lib/blokInfo.js.map +1 -0
- package/dist/admin/lib/foutNaarMens.d.ts +1 -0
- package/dist/admin/lib/foutNaarMens.js +22 -0
- package/dist/admin/lib/foutNaarMens.js.map +1 -0
- package/dist/admin/lib/gewisteVelden.d.ts +13 -0
- package/dist/admin/lib/gewisteVelden.js +31 -0
- package/dist/admin/lib/gewisteVelden.js.map +1 -0
- package/dist/admin/lib/heroHulp.d.ts +11 -0
- package/dist/admin/lib/heroHulp.js +18 -0
- package/dist/admin/lib/heroHulp.js.map +1 -0
- package/dist/admin/lib/kleur.js +2 -3
- package/dist/admin/lib/kleur.js.map +1 -1
- package/dist/admin/lib/leesbaarheid.d.ts +34 -0
- package/dist/admin/lib/leesbaarheid.js +82 -0
- package/dist/admin/lib/leesbaarheid.js.map +1 -0
- package/dist/admin/lib/lengteAdvies.d.ts +1 -0
- package/dist/admin/lib/lengteAdvies.js +16 -0
- package/dist/admin/lib/lengteAdvies.js.map +1 -0
- package/dist/admin/lib/mediaLijst.d.ts +26 -0
- package/dist/admin/lib/mediaLijst.js +42 -0
- package/dist/admin/lib/mediaLijst.js.map +1 -0
- package/dist/admin/lib/mediaUsage.d.ts +12 -1
- package/dist/admin/lib/mediaUsage.js +43 -33
- package/dist/admin/lib/mediaUsage.js.map +1 -1
- package/dist/admin/lib/menuHulp.d.ts +16 -0
- package/dist/admin/lib/menuHulp.js +41 -0
- package/dist/admin/lib/menuHulp.js.map +1 -0
- package/dist/admin/lib/onopgeslagen.d.ts +10 -0
- package/dist/admin/lib/onopgeslagen.js +35 -0
- package/dist/admin/lib/onopgeslagen.js.map +1 -0
- package/dist/admin/lib/pagesClient.d.ts +55 -2
- package/dist/admin/lib/pagesClient.js +126 -28
- package/dist/admin/lib/pagesClient.js.map +1 -1
- package/dist/admin/lib/paginaGebruik.d.ts +56 -0
- package/dist/admin/lib/paginaGebruik.js +109 -0
- package/dist/admin/lib/paginaGebruik.js.map +1 -0
- package/dist/admin/lib/publicatieCheck.d.ts +25 -0
- package/dist/admin/lib/publicatieCheck.js +114 -0
- package/dist/admin/lib/publicatieCheck.js.map +1 -0
- package/dist/admin/lib/scrollNaarDetail.d.ts +6 -0
- package/dist/admin/lib/scrollNaarDetail.js +20 -0
- package/dist/admin/lib/scrollNaarDetail.js.map +1 -0
- package/dist/admin/lib/symbolsClient.d.ts +10 -0
- package/dist/admin/lib/symbolsClient.js +14 -1
- package/dist/admin/lib/symbolsClient.js.map +1 -1
- package/dist/admin/lib/tekstVeld.d.ts +8 -0
- package/dist/admin/lib/tekstVeld.js +10 -0
- package/dist/admin/lib/tekstVeld.js.map +1 -0
- package/dist/admin/lib/useIsSuperadmin.d.ts +2 -0
- package/dist/admin/lib/useIsSuperadmin.js +13 -0
- package/dist/admin/lib/useIsSuperadmin.js.map +1 -0
- package/dist/admin/lib/veldTaal.d.ts +14 -0
- package/dist/admin/lib/veldTaal.js +247 -0
- package/dist/admin/lib/veldTaal.js.map +1 -0
- package/dist/admin/lib/versieVergelijk.d.ts +17 -0
- package/dist/admin/lib/versieVergelijk.js +24 -0
- package/dist/admin/lib/versieVergelijk.js.map +1 -0
- package/dist/admin/lib/zodFields.js +22 -4
- package/dist/admin/lib/zodFields.js.map +1 -1
- package/dist/admin/lib/zodFout.d.ts +9 -0
- package/dist/admin/lib/zodFout.js +63 -0
- package/dist/admin/lib/zodFout.js.map +1 -0
- package/dist/admin/media/MediaManager.js +162 -32
- package/dist/admin/media/MediaManager.js.map +1 -1
- package/dist/admin/media/MediaPicker.d.ts +3 -0
- package/dist/admin/media/MediaPicker.js +84 -31
- package/dist/admin/media/MediaPicker.js.map +1 -1
- package/dist/admin/menu/MenuPanel.js +144 -83
- package/dist/admin/menu/MenuPanel.js.map +1 -1
- package/dist/admin/navContext.d.ts +3 -0
- package/dist/admin/navContext.js +13 -1
- package/dist/admin/navContext.js.map +1 -1
- package/dist/admin/pages/PageEditor.js +146 -30
- package/dist/admin/pages/PageEditor.js.map +1 -1
- package/dist/admin/pages/PagesPanel.js +215 -61
- package/dist/admin/pages/PagesPanel.js.map +1 -1
- package/dist/admin/pages/StarterKiezer.d.ts +12 -0
- package/dist/admin/pages/StarterKiezer.js +113 -0
- package/dist/admin/pages/StarterKiezer.js.map +1 -0
- package/dist/admin/panelRegistry.d.ts +1 -1
- package/dist/admin/panelRegistry.js +2 -1
- package/dist/admin/panelRegistry.js.map +1 -1
- package/dist/admin/patterns/PatternInserter.js +1 -1
- package/dist/admin/patterns/PatternInserter.js.map +1 -1
- package/dist/admin/settings/BedrijfInstellingen.d.ts +20 -0
- package/dist/admin/settings/BedrijfInstellingen.js +144 -0
- package/dist/admin/settings/BedrijfInstellingen.js.map +1 -0
- package/dist/admin/settings/MailSettings.js +2 -2
- package/dist/admin/settings/MailSettings.js.map +1 -1
- package/dist/admin/settings/MailTemplates.js +5 -4
- package/dist/admin/settings/MailTemplates.js.map +1 -1
- package/dist/admin/settings/SettingsPanel.js +120 -78
- package/dist/admin/settings/SettingsPanel.js.map +1 -1
- package/dist/admin/settings/SnapshotsCard.js +4 -4
- package/dist/admin/settings/SnapshotsCard.js.map +1 -1
- package/dist/admin/settings/VorigeTerugzetten.d.ts +15 -0
- package/dist/admin/settings/VorigeTerugzetten.js +89 -0
- package/dist/admin/settings/VorigeTerugzetten.js.map +1 -0
- package/dist/admin/shop/CategoriesTab.js +6 -4
- package/dist/admin/shop/CategoriesTab.js.map +1 -1
- package/dist/admin/shop/DiscountsTab.js +4 -2
- package/dist/admin/shop/DiscountsTab.js.map +1 -1
- package/dist/admin/shop/OrdersTab.js +57 -19
- package/dist/admin/shop/OrdersTab.js.map +1 -1
- package/dist/admin/shop/ProductPaneel.js +2 -1
- package/dist/admin/shop/ProductPaneel.js.map +1 -1
- package/dist/admin/shop/ProductsTab.js +40 -19
- package/dist/admin/shop/ProductsTab.js.map +1 -1
- package/dist/admin/shop/ShopPanel.js +13 -1
- package/dist/admin/shop/ShopPanel.js.map +1 -1
- package/dist/admin/shop/ShopSettingsTab.js +27 -1
- package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
- package/dist/admin/shop/productClient.js +7 -3
- package/dist/admin/shop/productClient.js.map +1 -1
- package/dist/admin/stats/NietGevonden.d.ts +10 -0
- package/dist/admin/stats/NietGevonden.js +78 -0
- package/dist/admin/stats/NietGevonden.js.map +1 -0
- package/dist/admin/stats/StatsPanel.js +6 -1
- package/dist/admin/stats/StatsPanel.js.map +1 -1
- package/dist/admin/stats/lib.d.ts +2 -0
- package/dist/admin/stats/lib.js.map +1 -1
- package/dist/admin/ui/ConfirmDialog.js +10 -1
- package/dist/admin/ui/ConfirmDialog.js.map +1 -1
- package/dist/admin/ui/Icon.d.ts +34 -0
- package/dist/admin/ui/Icon.js +44 -0
- package/dist/admin/ui/Icon.js.map +1 -0
- package/dist/admin/ui/ImageField.d.ts +15 -0
- package/dist/admin/ui/ImageField.js +67 -0
- package/dist/admin/ui/ImageField.js.map +1 -0
- package/dist/admin/ui/KleurVeld.d.ts +25 -0
- package/dist/admin/ui/KleurVeld.js +76 -0
- package/dist/admin/ui/KleurVeld.js.map +1 -0
- package/dist/admin/ui/LaadStaat.d.ts +21 -0
- package/dist/admin/ui/LaadStaat.js +43 -0
- package/dist/admin/ui/LaadStaat.js.map +1 -0
- package/dist/admin/ui/LeesbaarheidPaneel.d.ts +10 -0
- package/dist/admin/ui/LeesbaarheidPaneel.js +68 -0
- package/dist/admin/ui/LeesbaarheidPaneel.js.map +1 -0
- package/dist/admin/ui/LinkDialog.d.ts +22 -0
- package/dist/admin/ui/LinkDialog.js +131 -0
- package/dist/admin/ui/LinkDialog.js.map +1 -0
- package/dist/admin/ui/LinkVeld.d.ts +14 -0
- package/dist/admin/ui/LinkVeld.js +49 -0
- package/dist/admin/ui/LinkVeld.js.map +1 -0
- package/dist/admin/ui/PreviewLinkResultaat.d.ts +14 -0
- package/dist/admin/ui/PreviewLinkResultaat.js +52 -0
- package/dist/admin/ui/PreviewLinkResultaat.js.map +1 -0
- package/dist/admin/ui/charts.js +5 -5
- package/dist/admin/ui/charts.js.map +1 -1
- package/dist/admin/ui/primitives.d.ts +16 -6
- package/dist/admin/ui/primitives.js +98 -26
- package/dist/admin/ui/primitives.js.map +1 -1
- package/dist/admin/ui/select.js +5 -2
- package/dist/admin/ui/select.js.map +1 -1
- package/dist/admin/ui/switch.d.ts +3 -1
- package/dist/admin/ui/switch.js +6 -3
- package/dist/admin/ui/switch.js.map +1 -1
- package/dist/admin/ui/toast.d.ts +2 -1
- package/dist/admin/ui/toast.js +17 -11
- package/dist/admin/ui/toast.js.map +1 -1
- package/dist/admin/visual/BlokKiezer.d.ts +34 -0
- package/dist/admin/visual/BlokKiezer.js +225 -0
- package/dist/admin/visual/BlokKiezer.js.map +1 -0
- package/dist/admin/visual/InlineGereedschap.d.ts +52 -0
- package/dist/admin/visual/InlineGereedschap.js +356 -0
- package/dist/admin/visual/InlineGereedschap.js.map +1 -0
- package/dist/admin/visual/InlineRijkeTekst.d.ts +23 -0
- package/dist/admin/visual/InlineRijkeTekst.js +152 -0
- package/dist/admin/visual/InlineRijkeTekst.js.map +1 -0
- package/dist/admin/visual/VisualEditor.js +273 -125
- package/dist/admin/visual/VisualEditor.js.map +1 -1
- package/dist/admin.css +1 -1
- package/dist/bedrijf/bedrijf.d.ts +36 -0
- package/dist/bedrijf/bedrijf.js +110 -0
- package/dist/bedrijf/bedrijf.js.map +1 -0
- package/dist/blocks/BlockRenderer.js +11 -1
- package/dist/blocks/BlockRenderer.js.map +1 -1
- package/dist/blocks/blockStyle.d.ts +7 -0
- package/dist/blocks/blockStyle.js +16 -3
- package/dist/blocks/blockStyle.js.map +1 -1
- package/dist/blocks/builtinSchemas.js +6 -0
- package/dist/blocks/builtinSchemas.js.map +1 -1
- package/dist/blocks/builtins/AgendaRender.d.ts +22 -0
- package/dist/blocks/builtins/AgendaRender.js +69 -9
- package/dist/blocks/builtins/AgendaRender.js.map +1 -1
- package/dist/blocks/builtins/Availability.d.ts +1 -0
- package/dist/blocks/builtins/Availability.js +23 -0
- package/dist/blocks/builtins/Availability.js.map +1 -0
- package/dist/blocks/builtins/AvailabilityRender.d.ts +12 -0
- package/dist/blocks/builtins/AvailabilityRender.js +105 -0
- package/dist/blocks/builtins/AvailabilityRender.js.map +1 -0
- package/dist/blocks/builtins/BeforeAfterRender.js +4 -3
- package/dist/blocks/builtins/BeforeAfterRender.js.map +1 -1
- package/dist/blocks/builtins/Booking.js +1 -1
- package/dist/blocks/builtins/Booking.js.map +1 -1
- package/dist/blocks/builtins/BreadcrumbsRender.d.ts +4 -3
- package/dist/blocks/builtins/BreadcrumbsRender.js +14 -8
- package/dist/blocks/builtins/BreadcrumbsRender.js.map +1 -1
- package/dist/blocks/builtins/ColumnsRender.d.ts +1 -1
- package/dist/blocks/builtins/ColumnsRender.js +3 -1
- package/dist/blocks/builtins/ColumnsRender.js.map +1 -1
- package/dist/blocks/builtins/Contact.js +1 -1
- package/dist/blocks/builtins/Contact.js.map +1 -1
- package/dist/blocks/builtins/ContactRender.d.ts +1 -1
- package/dist/blocks/builtins/ContactRender.js +29 -8
- package/dist/blocks/builtins/ContactRender.js.map +1 -1
- package/dist/blocks/builtins/Cta.js +1 -1
- package/dist/blocks/builtins/Cta.js.map +1 -1
- package/dist/blocks/builtins/CtaRender.d.ts +1 -1
- package/dist/blocks/builtins/CtaRender.js +5 -4
- package/dist/blocks/builtins/CtaRender.js.map +1 -1
- package/dist/blocks/builtins/Embed.js +1 -1
- package/dist/blocks/builtins/Embed.js.map +1 -1
- package/dist/blocks/builtins/FormBlock.js +1 -0
- package/dist/blocks/builtins/FormBlock.js.map +1 -1
- package/dist/blocks/builtins/FormBlockRender.d.ts +6 -0
- package/dist/blocks/builtins/FormBlockRender.js +88 -16
- package/dist/blocks/builtins/FormBlockRender.js.map +1 -1
- package/dist/blocks/builtins/GalleryRender.js +3 -2
- package/dist/blocks/builtins/GalleryRender.js.map +1 -1
- package/dist/blocks/builtins/Hero.js +1 -1
- package/dist/blocks/builtins/Hero.js.map +1 -1
- package/dist/blocks/builtins/HeroRender.js +7 -3
- package/dist/blocks/builtins/HeroRender.js.map +1 -1
- package/dist/blocks/builtins/OpenNowBadge.d.ts +4 -2
- package/dist/blocks/builtins/OpenNowBadge.js +6 -6
- package/dist/blocks/builtins/OpenNowBadge.js.map +1 -1
- package/dist/blocks/builtins/OpeningHoursRender.d.ts +8 -2
- package/dist/blocks/builtins/OpeningHoursRender.js +27 -6
- package/dist/blocks/builtins/OpeningHoursRender.js.map +1 -1
- package/dist/blocks/builtins/PriceList.d.ts +1 -0
- package/dist/blocks/builtins/PriceList.js +25 -0
- package/dist/blocks/builtins/PriceList.js.map +1 -0
- package/dist/blocks/builtins/PriceListRender.d.ts +17 -0
- package/dist/blocks/builtins/PriceListRender.js +87 -0
- package/dist/blocks/builtins/PriceListRender.js.map +1 -0
- package/dist/blocks/builtins/RichTextBlockRender.js +6 -1
- package/dist/blocks/builtins/RichTextBlockRender.js.map +1 -1
- package/dist/blocks/builtins/SectionHeading.d.ts +1 -0
- package/dist/blocks/builtins/SectionHeading.js +14 -0
- package/dist/blocks/builtins/SectionHeading.js.map +1 -0
- package/dist/blocks/builtins/SectionHeadingRender.d.ts +7 -0
- package/dist/blocks/builtins/SectionHeadingRender.js +14 -0
- package/dist/blocks/builtins/SectionHeadingRender.js.map +1 -0
- package/dist/blocks/builtins/SliderRender.js +3 -2
- package/dist/blocks/builtins/SliderRender.js.map +1 -1
- package/dist/blocks/builtins/SymbolRef.js +1 -1
- package/dist/blocks/builtins/SymbolRef.js.map +1 -1
- package/dist/blocks/builtins/TeamRender.js +6 -1
- package/dist/blocks/builtins/TeamRender.js.map +1 -1
- package/dist/blocks/builtins/Testimonials.js +3 -1
- package/dist/blocks/builtins/Testimonials.js.map +1 -1
- package/dist/blocks/builtins/TestimonialsRender.js +4 -0
- package/dist/blocks/builtins/TestimonialsRender.js.map +1 -1
- package/dist/blocks/builtins/WhatsappChatRender.d.ts +1 -1
- package/dist/blocks/builtins/WhatsappChatRender.js +1 -1
- package/dist/blocks/builtins/WhatsappChatRender.js.map +1 -1
- package/dist/blocks/builtins/Widgets.js +2 -2
- package/dist/blocks/builtins/Widgets.js.map +1 -1
- package/dist/blocks/builtins/WidgetsRender.js +3 -1
- package/dist/blocks/builtins/WidgetsRender.js.map +1 -1
- package/dist/blocks/builtins/index.d.ts +3 -0
- package/dist/blocks/builtins/index.js +6 -0
- package/dist/blocks/builtins/index.js.map +1 -1
- package/dist/blocks/builtins/lib/autoComplete.d.ts +7 -0
- package/dist/blocks/builtins/lib/autoComplete.js +20 -0
- package/dist/blocks/builtins/lib/autoComplete.js.map +1 -0
- package/dist/blocks/builtins/lib/bookingUrl.d.ts +2 -2
- package/dist/blocks/builtins/lib/bookingUrl.js +1 -1
- package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -1
- package/dist/blocks/builtins/lib/ical.d.ts +24 -0
- package/dist/blocks/builtins/lib/ical.js +82 -0
- package/dist/blocks/builtins/lib/ical.js.map +1 -0
- package/dist/blocks/builtins/lib/vandaag.d.ts +8 -0
- package/dist/blocks/builtins/lib/vandaag.js +22 -0
- package/dist/blocks/builtins/lib/vandaag.js.map +1 -0
- package/dist/blocks/registry.d.ts +6 -0
- package/dist/blocks/registry.js.map +1 -1
- package/dist/blocks/ui/index.js +1 -0
- package/dist/blocks/ui/index.js.map +1 -1
- package/dist/components/EditBar.js +2 -4
- package/dist/components/EditBar.js.map +1 -1
- package/dist/components/News.js +26 -18
- package/dist/components/News.js.map +1 -1
- package/dist/components/PageView.d.ts +7 -1
- package/dist/components/PageView.js +17 -0
- package/dist/components/PageView.js.map +1 -1
- package/dist/components/ResponsiveImage.js +18 -20
- package/dist/components/ResponsiveImage.js.map +1 -1
- package/dist/components/site/SiteFooter.d.ts +6 -1
- package/dist/components/site/SiteFooter.js +61 -9
- package/dist/components/site/SiteFooter.js.map +1 -1
- package/dist/components/site/SiteHeader.d.ts +15 -0
- package/dist/components/site/SiteHeader.js +70 -0
- package/dist/components/site/SiteHeader.js.map +1 -0
- package/dist/components/site/SiteNav.d.ts +2 -0
- package/dist/components/site/SiteNav.js +29 -5
- package/dist/components/site/SiteNav.js.map +1 -1
- package/dist/demo/DemoStudio.js +2 -2
- package/dist/demo/DemoStudio.js.map +1 -1
- package/dist/demo/demoStore.d.ts +13 -0
- package/dist/demo/demoStore.js +36 -0
- package/dist/demo/demoStore.js.map +1 -1
- package/dist/editor/EditorProvider.js +15 -4
- package/dist/editor/EditorProvider.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/media/ImageContext.d.ts +17 -0
- package/dist/media/ImageContext.js +65 -20
- package/dist/media/ImageContext.js.map +1 -1
- package/dist/media/altInHtml.d.ts +9 -0
- package/dist/media/altInHtml.js +17 -0
- package/dist/media/altInHtml.js.map +1 -0
- package/dist/media/srcset.d.ts +12 -0
- package/dist/media/srcset.js +13 -0
- package/dist/media/srcset.js.map +1 -0
- package/dist/modules/builtins.d.ts +1 -0
- package/dist/modules/builtins.js +16 -3
- package/dist/modules/builtins.js.map +1 -1
- package/dist/modules/shop/blocks/Cart.js +5 -3
- package/dist/modules/shop/blocks/Cart.js.map +1 -1
- package/dist/modules/shop/blocks/Checkout.js +56 -35
- package/dist/modules/shop/blocks/Checkout.js.map +1 -1
- package/dist/modules/shop/blocks/Donation.js +4 -4
- package/dist/modules/shop/blocks/Donation.js.map +1 -1
- package/dist/modules/shop/blocks/ProductDetail.js +19 -3
- package/dist/modules/shop/blocks/ProductDetail.js.map +1 -1
- package/dist/modules/shop/blocks/ProductGrid.d.ts +3 -1
- package/dist/modules/shop/blocks/ProductGrid.js +8 -4
- package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
- package/dist/modules/shop/blocks/ShopCategories.js +4 -3
- package/dist/modules/shop/blocks/ShopCategories.js.map +1 -1
- package/dist/modules/shop/lib.d.ts +4 -0
- package/dist/modules/shop/lib.js +14 -0
- package/dist/modules/shop/lib.js.map +1 -1
- package/dist/modules/shop/settings.d.ts +3 -0
- package/dist/modules/shop/settings.js +14 -0
- package/dist/modules/shop/settings.js.map +1 -1
- package/dist/modules/shop/strings.d.ts +4 -0
- package/dist/modules/shop/strings.js +8 -0
- package/dist/modules/shop/strings.js.map +1 -1
- package/dist/next/envCheck.d.ts +42 -0
- package/dist/next/envCheck.js +106 -0
- package/dist/next/envCheck.js.map +1 -0
- package/dist/next/index.cjs +185 -2
- package/dist/next/index.d.ts +2 -0
- package/dist/next/index.js +8 -1
- package/dist/next/index.js.map +1 -1
- package/dist/next/securityHeaders.d.ts +36 -0
- package/dist/next/securityHeaders.js +74 -0
- package/dist/next/securityHeaders.js.map +1 -0
- package/dist/patterns/builtins.d.ts +7 -0
- package/dist/patterns/builtins.js +138 -3
- package/dist/patterns/builtins.js.map +1 -1
- package/dist/releaseNotes.js +140 -0
- package/dist/releaseNotes.js.map +1 -1
- package/dist/render/PublishedPage.d.ts +2 -1
- package/dist/render/PublishedPage.js +10 -4
- package/dist/render/PublishedPage.js.map +1 -1
- package/dist/schema/blocks.d.ts +470 -0
- package/dist/schema/blocks.js +102 -4
- package/dist/schema/blocks.js.map +1 -1
- package/dist/schema/business.d.ts +117 -0
- package/dist/schema/business.js +73 -0
- package/dist/schema/business.js.map +1 -0
- package/dist/schema/fields.d.ts +2 -1
- package/dist/schema/fields.js.map +1 -1
- package/dist/schema/forms.d.ts +18 -0
- package/dist/schema/forms.js +18 -3
- package/dist/schema/forms.js.map +1 -1
- package/dist/schema/mail.d.ts +10 -0
- package/dist/schema/mail.js +7 -0
- package/dist/schema/mail.js.map +1 -1
- package/dist/schema/settings.d.ts +101 -0
- package/dist/schema/settings.js +24 -3
- package/dist/schema/settings.js.map +1 -1
- package/dist/schema/shop.d.ts +2 -0
- package/dist/schema/shop.js +4 -0
- package/dist/schema/shop.js.map +1 -1
- package/dist/schema/shopGeld.d.ts +1 -0
- package/dist/schema/shopGeld.js +1 -0
- package/dist/schema/shopGeld.js.map +1 -1
- package/dist/schema/siteConfig.d.ts +68 -1
- package/dist/schema/siteConfig.js +7 -2
- package/dist/schema/siteConfig.js.map +1 -1
- package/dist/server/blockData.d.ts +1 -1
- package/dist/server/blockData.js +74 -18
- package/dist/server/blockData.js.map +1 -1
- package/dist/server/cspRapport.d.ts +20 -0
- package/dist/server/cspRapport.js +56 -0
- package/dist/server/cspRapport.js.map +1 -0
- package/dist/server/fonts.d.ts +3 -0
- package/dist/server/fonts.js +39 -0
- package/dist/server/fonts.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/sanitize.js +15 -2
- package/dist/server/sanitize.js.map +1 -1
- package/dist/settings/useSiteSettings.js +4 -1
- package/dist/settings/useSiteSettings.js.map +1 -1
- package/dist/starters/starters.d.ts +69 -0
- package/dist/starters/starters.js +171 -0
- package/dist/starters/starters.js.map +1 -0
- package/dist/styles.css +1149 -208
- package/dist/theme/color.d.ts +10 -0
- package/dist/theme/color.js +17 -1
- package/dist/theme/color.js.map +1 -1
- package/dist/theme/fontFallback.d.ts +23 -0
- package/dist/theme/fontFallback.js +58 -0
- package/dist/theme/fontFallback.js.map +1 -0
- package/dist/theme/fonts.d.ts +11 -0
- package/dist/theme/fonts.js +16 -0
- package/dist/theme/fonts.js.map +1 -0
- package/dist/version.js +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { bepaalWijzigingen } from "../visual/wijzigingen.js";
|
|
2
|
+
function vergelijkVersie(huidig, versie, labelVoor) {
|
|
3
|
+
const uit = [];
|
|
4
|
+
if ((versie.title ?? "") !== (huidig.title ?? "")) uit.push(`Titel wordt \u201C${versie.title ?? ""}\u201D (nu \u201C${huidig.title ?? ""}\u201D).`);
|
|
5
|
+
if ((versie.path ?? "") !== (huidig.path ?? "")) uit.push(`Adres wordt ${versie.path} (nu ${huidig.path}).`);
|
|
6
|
+
if ((versie.seo?.description ?? "") !== (huidig.seo?.description ?? "")) uit.push("De omschrijving voor Google is anders.");
|
|
7
|
+
const v = versie.blocks ?? [];
|
|
8
|
+
const h = huidig.blocks ?? [];
|
|
9
|
+
const w = bepaalWijzigingen(v, h);
|
|
10
|
+
const anders = v.filter((b) => w.blokken.has(String(b._key ?? "")) || w.velden.has(String(b._key ?? "")));
|
|
11
|
+
if (anders.length > 0) {
|
|
12
|
+
const namen = [...new Set(anders.map((b) => labelVoor(String(b._type ?? ""))))];
|
|
13
|
+
uit.push(`${anders.length === 1 ? "1 blok is" : `${anders.length} blokken zijn`} anders: ${namen.slice(0, 6).join(", ")}${namen.length > 6 ? " \u2026" : ""}.`);
|
|
14
|
+
}
|
|
15
|
+
if (w.verwijderd > 0) {
|
|
16
|
+
uit.push(w.verwijderd === 1 ? "1 blok dat er nu staat, verdwijnt." : `${w.verwijderd} blokken die er nu staan, verdwijnen.`);
|
|
17
|
+
}
|
|
18
|
+
if (uit.length === 0) uit.push("Deze versie is gelijk aan je huidige werkversie.");
|
|
19
|
+
return uit;
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
vergelijkVersie
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=versieVergelijk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/lib/versieVergelijk.ts"],"sourcesContent":["import { bepaalWijzigingen } from \"../visual/wijzigingen\";\n\ntype Blok = { _key?: unknown; _type?: unknown } & Record<string, unknown>;\ninterface Versie {\n title?: string;\n path?: string;\n blocks?: unknown[];\n seo?: { title?: string; description?: string };\n}\n\n/**\n * \"Wat verandert er als ik deze versie terugzet?\" (8.4) — in zinnen, vóór je op Herstellen drukt.\n * Eerst was herstellen blind: je zag alleen een datum. Bouwt op dezelfde blokvergelijking als de\n * rode markeringen in de editor (`bepaalWijzigingen`), met de versie als \"werk\" en de huidige\n * werkversie als maatstaf.\n */\nexport function vergelijkVersie(huidig: Versie, versie: Versie, labelVoor: (type: string) => string): string[] {\n const uit: string[] = [];\n if ((versie.title ?? \"\") !== (huidig.title ?? \"\")) uit.push(`Titel wordt “${versie.title ?? \"\"}” (nu “${huidig.title ?? \"\"}”).`);\n if ((versie.path ?? \"\") !== (huidig.path ?? \"\")) uit.push(`Adres wordt ${versie.path} (nu ${huidig.path}).`);\n if ((versie.seo?.description ?? \"\") !== (huidig.seo?.description ?? \"\")) uit.push(\"De omschrijving voor Google is anders.\");\n\n const v = (versie.blocks ?? []) as Blok[];\n const h = (huidig.blocks ?? []) as Blok[];\n const w = bepaalWijzigingen(v, h);\n const anders = v.filter((b) => w.blokken.has(String(b._key ?? \"\")) || w.velden.has(String(b._key ?? \"\")));\n if (anders.length > 0) {\n const namen = [...new Set(anders.map((b) => labelVoor(String(b._type ?? \"\"))))];\n uit.push(`${anders.length === 1 ? \"1 blok is\" : `${anders.length} blokken zijn`} anders: ${namen.slice(0, 6).join(\", \")}${namen.length > 6 ? \" …\" : \"\"}.`);\n }\n if (w.verwijderd > 0) {\n uit.push(w.verwijderd === 1 ? \"1 blok dat er nu staat, verdwijnt.\" : `${w.verwijderd} blokken die er nu staan, verdwijnen.`);\n }\n if (uit.length === 0) uit.push(\"Deze versie is gelijk aan je huidige werkversie.\");\n return uit;\n}\n"],"mappings":"AAAA,SAAS,yBAAyB;AAgB3B,SAAS,gBAAgB,QAAgB,QAAgB,WAA+C;AAC7G,QAAM,MAAgB,CAAC;AACvB,OAAK,OAAO,SAAS,SAAS,OAAO,SAAS,IAAK,KAAI,KAAK,qBAAgB,OAAO,SAAS,EAAE,oBAAU,OAAO,SAAS,EAAE,UAAK;AAC/H,OAAK,OAAO,QAAQ,SAAS,OAAO,QAAQ,IAAK,KAAI,KAAK,eAAe,OAAO,IAAI,QAAQ,OAAO,IAAI,IAAI;AAC3G,OAAK,OAAO,KAAK,eAAe,SAAS,OAAO,KAAK,eAAe,IAAK,KAAI,KAAK,wCAAwC;AAE1H,QAAM,IAAK,OAAO,UAAU,CAAC;AAC7B,QAAM,IAAK,OAAO,UAAU,CAAC;AAC7B,QAAM,IAAI,kBAAkB,GAAG,CAAC;AAChC,QAAM,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;AACxG,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,UAAU,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9E,QAAI,KAAK,GAAG,OAAO,WAAW,IAAI,cAAc,GAAG,OAAO,MAAM,eAAe,YAAY,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG,MAAM,SAAS,IAAI,YAAO,EAAE,GAAG;AAAA,EAC3J;AACA,MAAI,EAAE,aAAa,GAAG;AACpB,QAAI,KAAK,EAAE,eAAe,IAAI,uCAAuC,GAAG,EAAE,UAAU,uCAAuC;AAAA,EAC7H;AACA,MAAI,IAAI,WAAW,EAAG,KAAI,KAAK,kDAAkD;AACjF,SAAO;AACT;","names":[]}
|
|
@@ -7,6 +7,15 @@ function maxLengthOf(def) {
|
|
|
7
7
|
}
|
|
8
8
|
return void 0;
|
|
9
9
|
}
|
|
10
|
+
function grenzenVan(def) {
|
|
11
|
+
const uit = {};
|
|
12
|
+
for (const c of def?.checks ?? []) {
|
|
13
|
+
const rule = c?._zod?.def;
|
|
14
|
+
if (rule?.check === "greater_than" && typeof rule.value === "number") uit.min = rule.value;
|
|
15
|
+
if (rule?.check === "less_than" && typeof rule.value === "number") uit.max = rule.value;
|
|
16
|
+
}
|
|
17
|
+
return uit;
|
|
18
|
+
}
|
|
10
19
|
const valuesOf = (def) => Object.values(def?.entries ?? {});
|
|
11
20
|
function shapeOf(schema) {
|
|
12
21
|
const def = defOf(schema);
|
|
@@ -20,13 +29,22 @@ function describedAs(s) {
|
|
|
20
29
|
function unwrap(schema) {
|
|
21
30
|
let s = schema;
|
|
22
31
|
let description = describedAs(s);
|
|
32
|
+
let standaard;
|
|
23
33
|
for (; ; ) {
|
|
24
34
|
const def = defOf(s);
|
|
25
35
|
if (def?.type !== "default" && def?.type !== "optional" && def?.type !== "nullable") break;
|
|
36
|
+
if (def.type === "default" && standaard === void 0) {
|
|
37
|
+
const d = def.defaultValue;
|
|
38
|
+
try {
|
|
39
|
+
standaard = typeof d === "function" ? d() : d;
|
|
40
|
+
} catch {
|
|
41
|
+
standaard = void 0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
26
44
|
s = def.innerType;
|
|
27
45
|
description = description ?? describedAs(s);
|
|
28
46
|
}
|
|
29
|
-
return { def: defOf(s), description, inner: s };
|
|
47
|
+
return { def: defOf(s), description, inner: s, standaard };
|
|
30
48
|
}
|
|
31
49
|
function introspectObjectSchema(schema) {
|
|
32
50
|
if (!schema) return [];
|
|
@@ -72,20 +90,20 @@ function introspectToFields(schema, hints, prefix = "") {
|
|
|
72
90
|
const out = [];
|
|
73
91
|
for (const [key, raw] of Object.entries(shape)) {
|
|
74
92
|
if (key.startsWith("_")) continue;
|
|
75
|
-
const { def: inner, description, inner: innerSchema } = unwrap(raw);
|
|
93
|
+
const { def: inner, description, inner: innerSchema, standaard } = unwrap(raw);
|
|
76
94
|
const label = description ?? key;
|
|
77
95
|
const path = prefix ? `${prefix}.${key}` : key;
|
|
78
96
|
const hint = hints?.[path];
|
|
79
97
|
const push = (f) => out.push({ ...f, ...hint, key, label: hint?.label ?? label });
|
|
80
98
|
switch (inner?.type) {
|
|
81
99
|
case "number":
|
|
82
|
-
push({ key, label, type: "number" });
|
|
100
|
+
push({ key, label, type: "number", ...grenzenVan(inner) });
|
|
83
101
|
break;
|
|
84
102
|
case "boolean":
|
|
85
103
|
push({ key, label, type: "switch" });
|
|
86
104
|
break;
|
|
87
105
|
case "enum":
|
|
88
|
-
push({ key, label, type: "select", options: valuesOf(inner).map((v) => ({ value: v, label: v })) });
|
|
106
|
+
push({ key, label, type: "select", options: valuesOf(inner).map((v) => ({ value: v, label: v })), standaard: typeof standaard === "string" ? standaard : void 0 });
|
|
89
107
|
break;
|
|
90
108
|
case "string": {
|
|
91
109
|
const max = maxLengthOf(inner);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/lib/zodFields.ts"],"sourcesContent":["/**\n * Zod-introspectie voor automatisch gegenereerde formulieren. Gedeeld door:\n * - de `GenericEditor` (fallback-editor voor blokken zonder eigen `Editor`), en\n * - het `ModuleSettingsForm` (instellingen van een module in /beheer).\n *\n * Twee lagen:\n * - `introspectObjectSchema` (legacy, plat): simpele kinds — blijft bestaan voor module-settings.\n * - `introspectToFields` (5.0): levert de rijke **Field-IR** (schema/fields.ts, primo-port) met\n * échte repeaters/groepen (recursief), richtext-/image-/link-detectie en optionele per-block\n * hints (`defineBlock({ fields })`). De GenericEditor 2.0 rendert deze IR.\n *\n * Een veld krijgt zijn label uit `.describe(\"…\")` op het schema; zonder beschrijving valt het\n * terug op de veldsleutel. Puur (geen React) — apart testbaar.\n */\nimport { globalRegistry } from \"zod/mini\";\nimport type { $ZodType as ZodTypeAny } from \"zod/v4/core\";\nimport type { Field } from \"../../schema/fields\";\n\nexport interface SchemaField {\n key: string;\n kind: \"number\" | \"boolean\" | \"string\" | \"enum\" | \"json\";\n /** Leesbaar label: `.describe()` van het schema, anders de veldsleutel. */\n label: string;\n options?: string[];\n /** Max-lengte van een string (bepaalt Input vs Textarea in de UI). */\n maxLength?: number;\n /** Het volledige veld-schema — voor validatie van json-velden vóór commit. */\n schema: ZodTypeAny;\n}\n\n/**\n * Zod 4-interne vorm. In Zod 3 heette dit `_def.typeName` (\"ZodObject\") met `shape` als FUNCTIE en\n * de beschrijving op `_def.description`; sinds Zod 4 is het `_def.type` (\"object\") met `shape` als\n * gewoon object, staat de beschrijving op de schema-instantie, dragen enums hun waarden in\n * `entries`, en zit een string-check achter `checks[i]._zod.def` als\n * `{ check: \"max_length\", maximum: n }`.\n *\n * Dit blijft leunen op interne velden — er is geen publieke introspectie-API in Zod. De\n * Field-IR-tests (fields.test.ts) zijn daarom het vangnet: die vallen om zodra Zod zijn interne\n * vorm opnieuw wijzigt, in plaats van dat de GenericEditor stilletjes lege formulieren toont.\n */\ntype ZodKind =\n | \"object\" | \"string\" | \"number\" | \"boolean\" | \"enum\" | \"array\" | \"record\"\n | \"default\" | \"optional\" | \"nullable\" | \"literal\" | (string & {});\n\ninterface AnyDef {\n type?: ZodKind;\n innerType?: unknown;\n entries?: Record<string, string>;\n element?: unknown;\n checks?: { _zod?: { def?: { check?: string; maximum?: number } } }[];\n shape?: Record<string, unknown>;\n}\n\n/**\n * De interne definitie van een schema.\n *\n * LET OP: `_def` is een alias die alléén de classic-façade aanbiedt — `zod/mini` (waar core op\n * draait) heeft hem niet en zet alles op `_zod.def`. Lees dus `_zod.def` eerst, met `_def` als\n * terugval voor classic-schema's uit een klantrepo. Zonder die volgorde levert introspectie\n * stilletjes niets op en toont de GenericEditor lege formulieren.\n */\nconst defOf = (schema: unknown): AnyDef | undefined =>\n (schema as { _zod?: { def?: AnyDef } })?._zod?.def ?? (schema as { _def?: AnyDef })?._def;\n\n/** Max-lengte van een string-schema (Zod 4: checks dragen hun regel onder `_zod.def`). */\nfunction maxLengthOf(def: AnyDef | undefined): number | undefined {\n for (const c of def?.checks ?? []) {\n const rule = c?._zod?.def;\n if (rule?.check === \"max_length\") return rule.maximum;\n }\n return undefined;\n}\n\n/** Waarden van een enum (Zod 4 levert een entries-map i.p.v. een values-array). */\nconst valuesOf = (def: AnyDef | undefined): string[] => Object.values(def?.entries ?? {});\n\n/** De velden van een objectschema; leeg als het geen object is. */\nfunction shapeOf(schema: unknown): Record<string, unknown> | null {\n const def = defOf(schema);\n if (def?.type !== \"object\" || !def.shape || typeof def.shape !== \"object\") return null;\n return def.shape;\n}\n\n/**\n * De beschrijving van een schema — de bron van de veldlabels in /beheer.\n *\n * `zod/mini` heeft géén `.description`-getter (die hoort bij de classic-façade), maar `.describe()`\n * en `.register()` schrijven allebei naar dezelfde `globalRegistry`. Die lezen we hier dus direct,\n * met de getter als terugval zodat een classic-schema uit een klantrepo blijft werken.\n */\nfunction describedAs(s: unknown): string | undefined {\n const uitRegister = globalRegistry.get(s as never)?.description;\n return uitRegister ?? (s as { description?: string } | null)?.description;\n}\n\n/** Pakt het binnenste type uit default/optional/nullable; bewaart de buitenste beschrijving. */\nfunction unwrap(schema: unknown): { def?: AnyDef; description?: string; inner?: unknown } {\n let s: unknown = schema;\n let description = describedAs(s);\n for (;;) {\n const def = defOf(s);\n if (def?.type !== \"default\" && def?.type !== \"optional\" && def?.type !== \"nullable\") break;\n s = def.innerType;\n description = description ?? describedAs(s);\n }\n return { def: defOf(s), description, inner: s };\n}\n\n/**\n * Leidt een formulier-beschrijving af uit een Zod-objectschema. Interne velden (`_key`/`_type`/\n * `_style`) worden overgeslagen — die beheren de editor-chrome en de StyleEditor. Complexe velden\n * (array/object/record) worden als `json` teruggegeven zodat een fallback-editor ze tóch kan\n * aanbieden; een aanroeper die alleen simpele velden wil, filtert op `kind !== \"json\"`.\n */\nexport function introspectObjectSchema(schema: ZodTypeAny | undefined): SchemaField[] {\n if (!schema) return [];\n const shape = shapeOf(schema);\n if (!shape) return [];\n const out: SchemaField[] = [];\n for (const [key, field] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) continue;\n const { def: inner, description } = unwrap(field);\n const label = description ?? key;\n const fieldSchema = field as ZodTypeAny;\n switch (inner?.type) {\n case \"number\":\n out.push({ key, kind: \"number\", label, schema: fieldSchema });\n break;\n case \"boolean\":\n out.push({ key, kind: \"boolean\", label, schema: fieldSchema });\n break;\n case \"enum\":\n out.push({ key, kind: \"enum\", label, options: valuesOf(inner), schema: fieldSchema });\n break;\n case \"string\": {\n out.push({ key, kind: \"string\", label, maxLength: maxLengthOf(inner), schema: fieldSchema });\n break;\n }\n case \"array\":\n case \"object\":\n case \"record\":\n out.push({ key, kind: \"json\", label, schema: fieldSchema });\n break;\n default:\n // ZodLiteral (bv. _type), unions e.d.: geen zinvol generiek veld.\n break;\n }\n }\n return out;\n}\n\nexport type { FieldHints } from \"../../schema/fields\";\nimport type { FieldHints } from \"../../schema/fields\";\n\n/** Herkent een beeld-URL-veld aan de sleutelnaam (zelfde heuristiek als de oude GenericEditor). */\nconst IMAGE_KEY = /image|photo|foto|logo|cover|avatar|poster/i;\n/** Herkent een URL-veld aan de sleutelnaam. */\nconst URL_KEY = /^(href|url|link)$|Url$|Href$/;\n\n/**\n * Leidt de rijke Field-IR af uit een Zod-objectschema (5.0). Verschillen met de platte laag:\n * - `z.array(z.object)` → **repeater** met recursief geïntrospecteerde subvelden;\n * - genest `z.object` → **group** (of **link** als de vorm exact `{label, href}` is);\n * - stringvelden `html`/`*Html` → **richtext**, beeld-sleutels → **image**, URL-sleutels → **url**;\n * - al het overige (records, scalar-arrays, unions) → **json** (laatste redmiddel).\n * `hints` verfijnt per (dotted) sleutel: type-overrides (date/slider/…) en `showIf`.\n */\nexport function introspectToFields(schema: ZodTypeAny | undefined, hints?: FieldHints, prefix = \"\"): Field[] {\n // Lazy schema's (7.13): vóór registerBuiltinSchemas kan een def nog geen schema hebben —\n // dan geen velden i.p.v. een crash (komt in de praktijk alleen in tests/randgevallen voor).\n if (!schema) return [];\n const shape = shapeOf(schema);\n if (!shape) return [];\n const out: Field[] = [];\n for (const [key, raw] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) continue;\n const { def: inner, description, inner: innerSchema } = unwrap(raw);\n const label = description ?? key;\n const path = prefix ? `${prefix}.${key}` : key;\n const hint = hints?.[path];\n const push = (f: Field) => out.push({ ...f, ...(hint as Partial<Field>), key, label: (hint?.label as string) ?? label } as Field);\n switch (inner?.type) {\n case \"number\":\n push({ key, label, type: \"number\" });\n break;\n case \"boolean\":\n push({ key, label, type: \"switch\" });\n break;\n case \"enum\":\n push({ key, label, type: \"select\", options: valuesOf(inner).map((v) => ({ value: v, label: v })) });\n break;\n case \"string\": {\n const max = maxLengthOf(inner);\n if (key === \"html\" || key.endsWith(\"Html\")) push({ key, label, type: \"richtext\" });\n else if (IMAGE_KEY.test(key)) push({ key, label, type: \"image\" });\n else if (URL_KEY.test(key)) push({ key, label, type: \"url\" });\n else if ((max ?? 0) > 500) push({ key, label, type: \"textarea\", maxLength: max });\n else push({ key, label, type: \"text\", maxLength: max });\n break;\n }\n case \"object\": {\n const sub = introspectToFields(innerSchema as ZodTypeAny, hints, path);\n const isLink = sub.length === 2 && sub.some((f) => f.key === \"label\") && sub.some((f) => f.key === \"href\");\n if (isLink) push({ key, label, type: \"link\" });\n else if (sub.length > 0) push({ key, label, type: \"group\", fields: sub });\n else push({ key, label, type: \"json\" });\n break;\n }\n case \"array\": {\n const { def: elDef, inner: elSchema } = unwrap(inner?.element);\n if (elDef?.type === \"object\") {\n const sub = introspectToFields(elSchema as ZodTypeAny, hints, path);\n if (sub.length > 0) {\n push({ key, label, type: \"repeater\", fields: sub });\n break;\n }\n }\n push({ key, label, type: \"json\" });\n break;\n }\n case \"record\":\n push({ key, label, type: \"json\" });\n break;\n default:\n break;\n }\n }\n return out;\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/lib/zodFields.ts"],"sourcesContent":["/**\n * Zod-introspectie voor automatisch gegenereerde formulieren. Gedeeld door:\n * - de `GenericEditor` (fallback-editor voor blokken zonder eigen `Editor`), en\n * - het `ModuleSettingsForm` (instellingen van een module in /beheer).\n *\n * Twee lagen:\n * - `introspectObjectSchema` (legacy, plat): simpele kinds — blijft bestaan voor module-settings.\n * - `introspectToFields` (5.0): levert de rijke **Field-IR** (schema/fields.ts, primo-port) met\n * échte repeaters/groepen (recursief), richtext-/image-/link-detectie en optionele per-block\n * hints (`defineBlock({ fields })`). De GenericEditor 2.0 rendert deze IR.\n *\n * Een veld krijgt zijn label uit `.describe(\"…\")` op het schema; zonder beschrijving valt het\n * terug op de veldsleutel. Puur (geen React) — apart testbaar.\n */\nimport { globalRegistry } from \"zod/mini\";\nimport type { $ZodType as ZodTypeAny } from \"zod/v4/core\";\nimport type { Field } from \"../../schema/fields\";\n\nexport interface SchemaField {\n key: string;\n kind: \"number\" | \"boolean\" | \"string\" | \"enum\" | \"json\";\n /** Leesbaar label: `.describe()` van het schema, anders de veldsleutel. */\n label: string;\n options?: string[];\n /** Max-lengte van een string (bepaalt Input vs Textarea in de UI). */\n maxLength?: number;\n /** Het volledige veld-schema — voor validatie van json-velden vóór commit. */\n schema: ZodTypeAny;\n}\n\n/**\n * Zod 4-interne vorm. In Zod 3 heette dit `_def.typeName` (\"ZodObject\") met `shape` als FUNCTIE en\n * de beschrijving op `_def.description`; sinds Zod 4 is het `_def.type` (\"object\") met `shape` als\n * gewoon object, staat de beschrijving op de schema-instantie, dragen enums hun waarden in\n * `entries`, en zit een string-check achter `checks[i]._zod.def` als\n * `{ check: \"max_length\", maximum: n }`.\n *\n * Dit blijft leunen op interne velden — er is geen publieke introspectie-API in Zod. De\n * Field-IR-tests (fields.test.ts) zijn daarom het vangnet: die vallen om zodra Zod zijn interne\n * vorm opnieuw wijzigt, in plaats van dat de GenericEditor stilletjes lege formulieren toont.\n */\ntype ZodKind =\n | \"object\" | \"string\" | \"number\" | \"boolean\" | \"enum\" | \"array\" | \"record\"\n | \"default\" | \"optional\" | \"nullable\" | \"literal\" | (string & {});\n\ninterface AnyDef {\n type?: ZodKind;\n innerType?: unknown;\n entries?: Record<string, string>;\n element?: unknown;\n checks?: { _zod?: { def?: { check?: string; maximum?: number } } }[];\n shape?: Record<string, unknown>;\n}\n\n/**\n * De interne definitie van een schema.\n *\n * LET OP: `_def` is een alias die alléén de classic-façade aanbiedt — `zod/mini` (waar core op\n * draait) heeft hem niet en zet alles op `_zod.def`. Lees dus `_zod.def` eerst, met `_def` als\n * terugval voor classic-schema's uit een klantrepo. Zonder die volgorde levert introspectie\n * stilletjes niets op en toont de GenericEditor lege formulieren.\n */\nconst defOf = (schema: unknown): AnyDef | undefined =>\n (schema as { _zod?: { def?: AnyDef } })?._zod?.def ?? (schema as { _def?: AnyDef })?._def;\n\n/** Max-lengte van een string-schema (Zod 4: checks dragen hun regel onder `_zod.def`). */\nfunction maxLengthOf(def: AnyDef | undefined): number | undefined {\n for (const c of def?.checks ?? []) {\n const rule = c?._zod?.def;\n if (rule?.check === \"max_length\") return rule.maximum;\n }\n return undefined;\n}\n\n/** Onder- en bovengrens van een getal (`z.minimum`/`z.maximum`), voor een knoppenrij i.p.v. een vrij veld. */\nfunction grenzenVan(def: AnyDef | undefined): { min?: number; max?: number } {\n const uit: { min?: number; max?: number } = {};\n for (const c of def?.checks ?? []) {\n const rule = c?._zod?.def as { check?: string; value?: unknown } | undefined;\n if (rule?.check === \"greater_than\" && typeof rule.value === \"number\") uit.min = rule.value;\n if (rule?.check === \"less_than\" && typeof rule.value === \"number\") uit.max = rule.value;\n }\n return uit;\n}\n\n/** Waarden van een enum (Zod 4 levert een entries-map i.p.v. een values-array). */\nconst valuesOf = (def: AnyDef | undefined): string[] => Object.values(def?.entries ?? {});\n\n/** De velden van een objectschema; leeg als het geen object is. */\nfunction shapeOf(schema: unknown): Record<string, unknown> | null {\n const def = defOf(schema);\n if (def?.type !== \"object\" || !def.shape || typeof def.shape !== \"object\") return null;\n return def.shape;\n}\n\n/**\n * De beschrijving van een schema — de bron van de veldlabels in /beheer.\n *\n * `zod/mini` heeft géén `.description`-getter (die hoort bij de classic-façade), maar `.describe()`\n * en `.register()` schrijven allebei naar dezelfde `globalRegistry`. Die lezen we hier dus direct,\n * met de getter als terugval zodat een classic-schema uit een klantrepo blijft werken.\n */\nfunction describedAs(s: unknown): string | undefined {\n const uitRegister = globalRegistry.get(s as never)?.description;\n return uitRegister ?? (s as { description?: string } | null)?.description;\n}\n\n/** Pakt het binnenste type uit default/optional/nullable; bewaart de buitenste beschrijving. */\nfunction unwrap(schema: unknown): { def?: AnyDef; description?: string; inner?: unknown; standaard?: unknown } {\n let s: unknown = schema;\n let description = describedAs(s);\n let standaard: unknown;\n for (;;) {\n const def = defOf(s);\n if (def?.type !== \"default\" && def?.type !== \"optional\" && def?.type !== \"nullable\") break;\n if (def.type === \"default\" && standaard === undefined) {\n // 8.10: de default meenemen — een keuzelijst toont dan wat er echt gerenderd wordt.\n const d = (def as { defaultValue?: unknown }).defaultValue;\n try {\n standaard = typeof d === \"function\" ? (d as () => unknown)() : d;\n } catch {\n standaard = undefined;\n }\n }\n s = def.innerType;\n description = description ?? describedAs(s);\n }\n return { def: defOf(s), description, inner: s, standaard };\n}\n\n/**\n * Leidt een formulier-beschrijving af uit een Zod-objectschema. Interne velden (`_key`/`_type`/\n * `_style`) worden overgeslagen — die beheren de editor-chrome en de StyleEditor. Complexe velden\n * (array/object/record) worden als `json` teruggegeven zodat een fallback-editor ze tóch kan\n * aanbieden; een aanroeper die alleen simpele velden wil, filtert op `kind !== \"json\"`.\n */\nexport function introspectObjectSchema(schema: ZodTypeAny | undefined): SchemaField[] {\n if (!schema) return [];\n const shape = shapeOf(schema);\n if (!shape) return [];\n const out: SchemaField[] = [];\n for (const [key, field] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) continue;\n const { def: inner, description } = unwrap(field);\n const label = description ?? key;\n const fieldSchema = field as ZodTypeAny;\n switch (inner?.type) {\n case \"number\":\n out.push({ key, kind: \"number\", label, schema: fieldSchema });\n break;\n case \"boolean\":\n out.push({ key, kind: \"boolean\", label, schema: fieldSchema });\n break;\n case \"enum\":\n out.push({ key, kind: \"enum\", label, options: valuesOf(inner), schema: fieldSchema });\n break;\n case \"string\": {\n out.push({ key, kind: \"string\", label, maxLength: maxLengthOf(inner), schema: fieldSchema });\n break;\n }\n case \"array\":\n case \"object\":\n case \"record\":\n out.push({ key, kind: \"json\", label, schema: fieldSchema });\n break;\n default:\n // ZodLiteral (bv. _type), unions e.d.: geen zinvol generiek veld.\n break;\n }\n }\n return out;\n}\n\nexport type { FieldHints } from \"../../schema/fields\";\nimport type { FieldHints } from \"../../schema/fields\";\n\n/** Herkent een beeld-URL-veld aan de sleutelnaam (zelfde heuristiek als de oude GenericEditor). */\nconst IMAGE_KEY = /image|photo|foto|logo|cover|avatar|poster/i;\n/** Herkent een URL-veld aan de sleutelnaam. */\nconst URL_KEY = /^(href|url|link)$|Url$|Href$/;\n\n/**\n * Leidt de rijke Field-IR af uit een Zod-objectschema (5.0). Verschillen met de platte laag:\n * - `z.array(z.object)` → **repeater** met recursief geïntrospecteerde subvelden;\n * - genest `z.object` → **group** (of **link** als de vorm exact `{label, href}` is);\n * - stringvelden `html`/`*Html` → **richtext**, beeld-sleutels → **image**, URL-sleutels → **url**;\n * - al het overige (records, scalar-arrays, unions) → **json** (laatste redmiddel).\n * `hints` verfijnt per (dotted) sleutel: type-overrides (date/slider/…) en `showIf`.\n */\nexport function introspectToFields(schema: ZodTypeAny | undefined, hints?: FieldHints, prefix = \"\"): Field[] {\n // Lazy schema's (7.13): vóór registerBuiltinSchemas kan een def nog geen schema hebben —\n // dan geen velden i.p.v. een crash (komt in de praktijk alleen in tests/randgevallen voor).\n if (!schema) return [];\n const shape = shapeOf(schema);\n if (!shape) return [];\n const out: Field[] = [];\n for (const [key, raw] of Object.entries(shape)) {\n if (key.startsWith(\"_\")) continue;\n const { def: inner, description, inner: innerSchema, standaard } = unwrap(raw);\n const label = description ?? key;\n const path = prefix ? `${prefix}.${key}` : key;\n const hint = hints?.[path];\n const push = (f: Field) => out.push({ ...f, ...(hint as Partial<Field>), key, label: (hint?.label as string) ?? label } as Field);\n switch (inner?.type) {\n case \"number\":\n push({ key, label, type: \"number\", ...grenzenVan(inner) });\n break;\n case \"boolean\":\n push({ key, label, type: \"switch\" });\n break;\n case \"enum\":\n push({ key, label, type: \"select\", options: valuesOf(inner).map((v) => ({ value: v, label: v })), standaard: typeof standaard === \"string\" ? standaard : undefined });\n break;\n case \"string\": {\n const max = maxLengthOf(inner);\n if (key === \"html\" || key.endsWith(\"Html\")) push({ key, label, type: \"richtext\" });\n else if (IMAGE_KEY.test(key)) push({ key, label, type: \"image\" });\n else if (URL_KEY.test(key)) push({ key, label, type: \"url\" });\n else if ((max ?? 0) > 500) push({ key, label, type: \"textarea\", maxLength: max });\n else push({ key, label, type: \"text\", maxLength: max });\n break;\n }\n case \"object\": {\n const sub = introspectToFields(innerSchema as ZodTypeAny, hints, path);\n const isLink = sub.length === 2 && sub.some((f) => f.key === \"label\") && sub.some((f) => f.key === \"href\");\n if (isLink) push({ key, label, type: \"link\" });\n else if (sub.length > 0) push({ key, label, type: \"group\", fields: sub });\n else push({ key, label, type: \"json\" });\n break;\n }\n case \"array\": {\n const { def: elDef, inner: elSchema } = unwrap(inner?.element);\n if (elDef?.type === \"object\") {\n const sub = introspectToFields(elSchema as ZodTypeAny, hints, path);\n if (sub.length > 0) {\n push({ key, label, type: \"repeater\", fields: sub });\n break;\n }\n }\n push({ key, label, type: \"json\" });\n break;\n }\n case \"record\":\n push({ key, label, type: \"json\" });\n break;\n default:\n break;\n }\n }\n return out;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const NAMEN = {
|
|
2
|
+
name: "Sitenaam",
|
|
3
|
+
contactEmail: "Contact-e-mail",
|
|
4
|
+
domain: "Domein",
|
|
5
|
+
nav: "Menu",
|
|
6
|
+
children: "submenu",
|
|
7
|
+
footer: "Footer",
|
|
8
|
+
columns: "kolom",
|
|
9
|
+
links: "link",
|
|
10
|
+
social: "social-link",
|
|
11
|
+
copyright: "copyright",
|
|
12
|
+
heading: "kop",
|
|
13
|
+
label: "tekst",
|
|
14
|
+
href: "adres",
|
|
15
|
+
platform: "naam",
|
|
16
|
+
redirects: "Doorverwijzing",
|
|
17
|
+
from: "van",
|
|
18
|
+
to: "naar",
|
|
19
|
+
theme: "Huisstijl",
|
|
20
|
+
primary: "merkkleur",
|
|
21
|
+
accent: "accentkleur",
|
|
22
|
+
background: "achtergrondkleur",
|
|
23
|
+
foreground: "tekstkleur",
|
|
24
|
+
seoDefaults: "SEO",
|
|
25
|
+
description: "omschrijving",
|
|
26
|
+
forms: "Formulieren",
|
|
27
|
+
title: "titel",
|
|
28
|
+
slug: "adres",
|
|
29
|
+
price: "prijs",
|
|
30
|
+
priceCents: "prijs",
|
|
31
|
+
fields: "veld",
|
|
32
|
+
options: "keuze",
|
|
33
|
+
code: "code",
|
|
34
|
+
percent: "percentage",
|
|
35
|
+
stock: "voorraad",
|
|
36
|
+
variants: "variant"
|
|
37
|
+
};
|
|
38
|
+
function zodFoutTekst(issue) {
|
|
39
|
+
if (!issue) return "Onbekende fout.";
|
|
40
|
+
const delen = [];
|
|
41
|
+
for (const p of issue.path ?? []) {
|
|
42
|
+
if (typeof p === "number") {
|
|
43
|
+
if (delen.length) delen[delen.length - 1] += ` ${p + 1}`;
|
|
44
|
+
else delen.push(`item ${p + 1}`);
|
|
45
|
+
} else {
|
|
46
|
+
delen.push(NAMEN[String(p)] ?? String(p));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const waar = delen.join(", ");
|
|
50
|
+
let wat;
|
|
51
|
+
if (issue.code === "too_small" && issue.origin === "string") wat = "is leeg";
|
|
52
|
+
else if (issue.code === "too_small") wat = "is te klein of te kort";
|
|
53
|
+
else if (issue.code === "too_big") wat = "is te lang";
|
|
54
|
+
else if (issue.code === "invalid_format" && issue.format === "email") wat = "is geen geldig e-mailadres";
|
|
55
|
+
else if (issue.code === "invalid_format") wat = "heeft een ongeldige vorm";
|
|
56
|
+
else if (issue.code === "invalid_type") wat = "ontbreekt of heeft een verkeerde waarde";
|
|
57
|
+
else wat = issue.message ?? "klopt niet";
|
|
58
|
+
return waar ? `${waar[0].toUpperCase()}${waar.slice(1)}: ${wat}.` : `${wat[0].toUpperCase()}${wat.slice(1)}.`;
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
zodFoutTekst
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=zodFout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/lib/zodFout.ts"],"sourcesContent":["/**\n * Een zod-fout in mensentaal (8.10).\n *\n * Bij opslaan van de instellingen kreeg de klant \"Too small: expected string to have >=1\n * characters\" — Engels, zonder te zeggen wélk veld. Dit maakt er \"Footer, kolom 2, link 1: de tekst\n * is leeg\" van. Onbekende velden krijgen hun sleutel; dat is nog altijd beter dan niets.\n */\nconst NAMEN: Record<string, string> = {\n name: \"Sitenaam\",\n contactEmail: \"Contact-e-mail\",\n domain: \"Domein\",\n nav: \"Menu\",\n children: \"submenu\",\n footer: \"Footer\",\n columns: \"kolom\",\n links: \"link\",\n social: \"social-link\",\n copyright: \"copyright\",\n heading: \"kop\",\n label: \"tekst\",\n href: \"adres\",\n platform: \"naam\",\n redirects: \"Doorverwijzing\",\n from: \"van\",\n to: \"naar\",\n theme: \"Huisstijl\",\n primary: \"merkkleur\",\n accent: \"accentkleur\",\n background: \"achtergrondkleur\",\n foreground: \"tekstkleur\",\n seoDefaults: \"SEO\",\n description: \"omschrijving\",\n forms: \"Formulieren\",\n title: \"titel\",\n slug: \"adres\",\n price: \"prijs\",\n priceCents: \"prijs\",\n fields: \"veld\",\n options: \"keuze\",\n code: \"code\",\n percent: \"percentage\",\n stock: \"voorraad\",\n variants: \"variant\",\n};\n\ninterface Issue {\n path?: PropertyKey[];\n code?: string;\n message?: string;\n origin?: string;\n format?: string;\n}\n\nexport function zodFoutTekst(issue: Issue | undefined): string {\n if (!issue) return \"Onbekende fout.\";\n const delen: string[] = [];\n for (const p of issue.path ?? []) {\n if (typeof p === \"number\") {\n if (delen.length) delen[delen.length - 1] += ` ${p + 1}`;\n else delen.push(`item ${p + 1}`);\n } else {\n delen.push(NAMEN[String(p)] ?? String(p));\n }\n }\n const waar = delen.join(\", \");\n let wat: string;\n if (issue.code === \"too_small\" && issue.origin === \"string\") wat = \"is leeg\";\n else if (issue.code === \"too_small\") wat = \"is te klein of te kort\";\n else if (issue.code === \"too_big\") wat = \"is te lang\";\n else if (issue.code === \"invalid_format\" && issue.format === \"email\") wat = \"is geen geldig e-mailadres\";\n else if (issue.code === \"invalid_format\") wat = \"heeft een ongeldige vorm\";\n else if (issue.code === \"invalid_type\") wat = \"ontbreekt of heeft een verkeerde waarde\";\n else wat = issue.message ?? \"klopt niet\";\n return waar ? `${waar[0].toUpperCase()}${waar.slice(1)}: ${wat}.` : `${wat[0].toUpperCase()}${wat.slice(1)}.`;\n}\n"],"mappings":"AAOA,MAAM,QAAgC;AAAA,EACpC,MAAM;AAAA,EACN,cAAc;AAAA,EACd,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,WAAW;AAAA,EACX,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,aAAa;AAAA,EACb,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,UAAU;AACZ;AAUO,SAAS,aAAa,OAAkC;AAC7D,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAkB,CAAC;AACzB,aAAW,KAAK,MAAM,QAAQ,CAAC,GAAG;AAChC,QAAI,OAAO,MAAM,UAAU;AACzB,UAAI,MAAM,OAAQ,OAAM,MAAM,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC;AAAA,UACjD,OAAM,KAAK,QAAQ,IAAI,CAAC,EAAE;AAAA,IACjC,OAAO;AACL,YAAM,KAAK,MAAM,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC;AAAA,IAC1C;AAAA,EACF;AACA,QAAM,OAAO,MAAM,KAAK,IAAI;AAC5B,MAAI;AACJ,MAAI,MAAM,SAAS,eAAe,MAAM,WAAW,SAAU,OAAM;AAAA,WAC1D,MAAM,SAAS,YAAa,OAAM;AAAA,WAClC,MAAM,SAAS,UAAW,OAAM;AAAA,WAChC,MAAM,SAAS,oBAAoB,MAAM,WAAW,QAAS,OAAM;AAAA,WACnE,MAAM,SAAS,iBAAkB,OAAM;AAAA,WACvC,MAAM,SAAS,eAAgB,OAAM;AAAA,MACzC,OAAM,MAAM,WAAW;AAC5B,SAAO,OAAO,GAAG,KAAK,CAAC,EAAE,YAAY,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC,EAAE,YAAY,CAAC,GAAG,IAAI,MAAM,CAAC,CAAC;AAC5G;","names":[]}
|
|
@@ -14,12 +14,15 @@ import {
|
|
|
14
14
|
} from "firebase/firestore";
|
|
15
15
|
import { deleteObject, ref as storageRef } from "firebase/storage";
|
|
16
16
|
import { getBucket, getDb } from "../../firebase/client.js";
|
|
17
|
-
import { DEMO_EVENT, isDemoActive, listDemoMediaAll } from "../../demo/demoStore.js";
|
|
18
|
-
import { Button, Card, Badge, Input } from "../ui/primitives.js";
|
|
17
|
+
import { DEMO_EVENT, isDemoActive, listDemoMediaAll, removeDemoMedia } from "../../demo/demoStore.js";
|
|
18
|
+
import { Button, Card, Badge, Input, LegeStaat } from "../ui/primitives.js";
|
|
19
19
|
import { useToast } from "../ui/toast.js";
|
|
20
|
+
import { Switch } from "../ui/switch.js";
|
|
20
21
|
import { useConfirm } from "../ui/ConfirmDialog.js";
|
|
21
22
|
import { uploadImage } from "../lib/upload.js";
|
|
22
23
|
import { findMediaUsage, findUnusedMedia } from "../lib/mediaUsage.js";
|
|
24
|
+
import { korteDatum, leesbareGrootte, MEDIA_SORTERINGEN, sorteerMedia } from "../lib/mediaLijst.js";
|
|
25
|
+
import { Select } from "../ui/select.js";
|
|
23
26
|
const PAGE_SIZE = 48;
|
|
24
27
|
function MediaManager({ siteId }) {
|
|
25
28
|
const { toast } = useToast();
|
|
@@ -32,7 +35,10 @@ function MediaManager({ siteId }) {
|
|
|
32
35
|
const [hasMore, setHasMore] = useState(false);
|
|
33
36
|
const inputRef = useRef(null);
|
|
34
37
|
const [zoek, setZoek] = useState("");
|
|
38
|
+
const [zonderAlt, setZonderAlt] = useState(false);
|
|
35
39
|
const [sleepOver, setSleepOver] = useState(false);
|
|
40
|
+
const [sortering, setSortering] = useState("nieuw");
|
|
41
|
+
const [geselecteerd, setGeselecteerd] = useState(() => /* @__PURE__ */ new Set());
|
|
36
42
|
useEffect(() => {
|
|
37
43
|
if (isDemoActive()) {
|
|
38
44
|
const sync = () => setItems(listDemoMediaAll(siteId));
|
|
@@ -92,14 +98,13 @@ function MediaManager({ siteId }) {
|
|
|
92
98
|
}
|
|
93
99
|
}
|
|
94
100
|
async function remove(item) {
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const usedOn = await findMediaUsage(siteId, item);
|
|
101
|
+
const demo = isDemoActive();
|
|
102
|
+
if (!demo && !getDb()) return;
|
|
103
|
+
const usedOn = demo ? [] : await findMediaUsage(siteId, item);
|
|
99
104
|
const ok = await confirm({
|
|
100
105
|
title: "Afbeelding verwijderen?",
|
|
101
|
-
description: usedOn.length > 0 ? `Let op: deze afbeelding wordt gebruikt
|
|
102
|
-
confirmLabel: "Verwijderen",
|
|
106
|
+
description: usedOn === null ? "Er kon niet worden nagegaan of deze afbeelding nog ergens gebruikt wordt. Wordt hij dat wel, dan verschijnt daar een gebroken afbeelding." : usedOn.length > 0 ? `Let op: deze afbeelding wordt nog gebruikt (${usedOn.slice(0, 5).join(", ")}${usedOn.length > 5 ? " \u2026" : ""}). Daar verschijnt dan een gebroken afbeelding.` : "De afbeelding wordt nergens gebruikt en wordt definitief verwijderd.",
|
|
107
|
+
confirmLabel: usedOn && usedOn.length > 0 ? "Toch verwijderen" : "Verwijderen",
|
|
103
108
|
tone: "danger"
|
|
104
109
|
});
|
|
105
110
|
if (!ok) return;
|
|
@@ -110,7 +115,67 @@ function MediaManager({ siteId }) {
|
|
|
110
115
|
toast({ title: "Verwijderen mislukt", description: e.message, tone: "error" });
|
|
111
116
|
}
|
|
112
117
|
}
|
|
118
|
+
async function verwijderSelectie() {
|
|
119
|
+
const doelen = items.filter((it) => geselecteerd.has(it.id));
|
|
120
|
+
if (doelen.length === 0) return;
|
|
121
|
+
setBusy(true);
|
|
122
|
+
let inGebruik = isDemoActive() ? 0 : null;
|
|
123
|
+
try {
|
|
124
|
+
if (!isDemoActive()) {
|
|
125
|
+
const vrij = new Set(await findUnusedMedia(siteId, doelen));
|
|
126
|
+
inGebruik = doelen.filter((d) => !vrij.has(d.id)).length;
|
|
127
|
+
}
|
|
128
|
+
} catch {
|
|
129
|
+
inGebruik = null;
|
|
130
|
+
}
|
|
131
|
+
setBusy(false);
|
|
132
|
+
const ok = await confirm({
|
|
133
|
+
title: `${doelen.length} foto('s) verwijderen?`,
|
|
134
|
+
description: inGebruik === null ? "Kon niet nagaan of deze foto's nog op de site staan. Waar ze gebruikt worden, verschijnt dan een gebroken afbeelding." : inGebruik > 0 ? `Let op: ${inGebruik} hiervan ${inGebruik === 1 ? "wordt" : "worden"} nog gebruikt (of ${inGebruik === 1 ? "is" : "zijn"} net ge\xFCpload). Daar verschijnt dan een gebroken afbeelding.` : "Geen van deze foto's wordt nog gebruikt. Ze worden definitief verwijderd.",
|
|
135
|
+
confirmLabel: "Verwijderen",
|
|
136
|
+
tone: "danger"
|
|
137
|
+
});
|
|
138
|
+
if (!ok) return;
|
|
139
|
+
setBusy(true);
|
|
140
|
+
let gelukt = 0;
|
|
141
|
+
const fouten = [];
|
|
142
|
+
for (const it of doelen) {
|
|
143
|
+
try {
|
|
144
|
+
await verwijderItem(it);
|
|
145
|
+
gelukt++;
|
|
146
|
+
} catch (e) {
|
|
147
|
+
fouten.push(`${it.name}: ${e.message}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
setGeselecteerd(/* @__PURE__ */ new Set());
|
|
151
|
+
setBusy(false);
|
|
152
|
+
if (gelukt) toast({ title: `${gelukt} foto('s) verwijderd`, tone: "success" });
|
|
153
|
+
if (fouten.length) toast({ title: "Niet alles kon weg", description: fouten.join(" \xB7 "), tone: "error" });
|
|
154
|
+
}
|
|
155
|
+
async function download(item) {
|
|
156
|
+
try {
|
|
157
|
+
const res = await fetch(item.url);
|
|
158
|
+
if (!res.ok) throw new Error(String(res.status));
|
|
159
|
+
const url = URL.createObjectURL(await res.blob());
|
|
160
|
+
const a = document.createElement("a");
|
|
161
|
+
a.href = url;
|
|
162
|
+
a.download = item.name || "foto";
|
|
163
|
+
a.click();
|
|
164
|
+
setTimeout(() => URL.revokeObjectURL(url), 1e3);
|
|
165
|
+
} catch {
|
|
166
|
+
window.open(item.url, "_blank", "noopener");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function wisselSelectie(id) {
|
|
170
|
+
setGeselecteerd((s) => {
|
|
171
|
+
const n = new Set(s);
|
|
172
|
+
if (n.has(id)) n.delete(id);
|
|
173
|
+
else n.add(id);
|
|
174
|
+
return n;
|
|
175
|
+
});
|
|
176
|
+
}
|
|
113
177
|
async function verwijderItem(item) {
|
|
178
|
+
if (isDemoActive()) return removeDemoMedia(siteId, item.id);
|
|
114
179
|
const db = getDb();
|
|
115
180
|
const bucket = getBucket();
|
|
116
181
|
if (!db) throw new Error("Geen databaseverbinding.");
|
|
@@ -169,7 +234,13 @@ function MediaManager({ siteId }) {
|
|
|
169
234
|
if (fouten.length) toast({ title: "Niet alles kon weg", description: fouten.join(" \xB7 "), tone: "error" });
|
|
170
235
|
}
|
|
171
236
|
const term = zoek.trim().toLowerCase();
|
|
172
|
-
const
|
|
237
|
+
const aantalZonderAlt = items.filter((m) => !m.alt?.trim()).length;
|
|
238
|
+
const getoond = sorteerMedia(
|
|
239
|
+
items.filter((m) => !zonderAlt || !m.alt?.trim()).filter((m) => !term || `${m.name ?? ""} ${m.alt ?? ""}`.toLowerCase().includes(term)),
|
|
240
|
+
sortering
|
|
241
|
+
);
|
|
242
|
+
const aantalGeselecteerd = items.filter((m) => geselecteerd.has(m.id)).length;
|
|
243
|
+
const allesGetoondGeselecteerd = getoond.length > 0 && getoond.every((m) => geselecteerd.has(m.id));
|
|
173
244
|
return /* @__PURE__ */ jsxs(
|
|
174
245
|
"div",
|
|
175
246
|
{
|
|
@@ -205,7 +276,48 @@ function MediaManager({ siteId }) {
|
|
|
205
276
|
/* @__PURE__ */ jsx("strong", { children: "focuspunt" }),
|
|
206
277
|
" te kiezen: dat deel blijft in beeld als de foto wordt bijgesneden (bijvoorbeeld een brede kopfoto op een telefoon)."
|
|
207
278
|
] }),
|
|
208
|
-
|
|
279
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-3", children: [
|
|
280
|
+
items.length > 8 && /* @__PURE__ */ jsx("div", { className: "w-full max-w-xs", children: /* @__PURE__ */ jsx(Input, { value: zoek, onChange: (e) => setZoek(e.target.value), placeholder: "Zoek op naam of beschrijving\u2026", "aria-label": "Zoek in mediabibliotheek" }) }),
|
|
281
|
+
(aantalZonderAlt > 0 || zonderAlt) && /* @__PURE__ */ jsx(
|
|
282
|
+
Switch,
|
|
283
|
+
{
|
|
284
|
+
checked: zonderAlt,
|
|
285
|
+
onCheckedChange: setZonderAlt,
|
|
286
|
+
label: `Alleen zonder beschrijving (${aantalZonderAlt})`
|
|
287
|
+
}
|
|
288
|
+
),
|
|
289
|
+
items.length > 1 && /* @__PURE__ */ jsx("div", { className: "w-48", children: /* @__PURE__ */ jsx(
|
|
290
|
+
Select,
|
|
291
|
+
{
|
|
292
|
+
value: sortering,
|
|
293
|
+
onValueChange: (v) => setSortering(v || "nieuw"),
|
|
294
|
+
options: MEDIA_SORTERINGEN,
|
|
295
|
+
placeholder: "Sorteren"
|
|
296
|
+
}
|
|
297
|
+
) })
|
|
298
|
+
] }),
|
|
299
|
+
aantalGeselecteerd > 0 && /* @__PURE__ */ jsxs(
|
|
300
|
+
"div",
|
|
301
|
+
{
|
|
302
|
+
role: "region",
|
|
303
|
+
"aria-label": "Selectie",
|
|
304
|
+
className: "sticky top-2 z-10 mt-3 flex flex-wrap items-center gap-2 rounded-lg border border-brand-500/40 bg-brand-50 px-3 py-2 text-sm shadow-sm",
|
|
305
|
+
children: [
|
|
306
|
+
/* @__PURE__ */ jsxs("strong", { children: [
|
|
307
|
+
aantalGeselecteerd,
|
|
308
|
+
" geselecteerd"
|
|
309
|
+
] }),
|
|
310
|
+
!allesGetoondGeselecteerd && /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setGeselecteerd(/* @__PURE__ */ new Set([...geselecteerd, ...getoond.map((m) => m.id)])), children: [
|
|
311
|
+
"Alles selecteren (",
|
|
312
|
+
getoond.length,
|
|
313
|
+
")"
|
|
314
|
+
] }),
|
|
315
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: () => setGeselecteerd(/* @__PURE__ */ new Set()), children: "Selectie wissen" }),
|
|
316
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1" }),
|
|
317
|
+
/* @__PURE__ */ jsx(Button, { loading: busy, variant: "danger", size: "sm", disabled: busy, onClick: () => void verwijderSelectie(), children: `Verwijderen (${aantalGeselecteerd})` })
|
|
318
|
+
]
|
|
319
|
+
}
|
|
320
|
+
),
|
|
209
321
|
/* @__PURE__ */ jsx(
|
|
210
322
|
"input",
|
|
211
323
|
{
|
|
@@ -222,32 +334,49 @@ function MediaManager({ siteId }) {
|
|
|
222
334
|
)
|
|
223
335
|
] }),
|
|
224
336
|
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-4", children: [
|
|
225
|
-
getoond.map((m) => /* @__PURE__ */ jsxs(Card, { className:
|
|
226
|
-
/* @__PURE__ */
|
|
337
|
+
getoond.map((m) => /* @__PURE__ */ jsxs(Card, { className: `p-3 ${geselecteerd.has(m.id) ? "ring-2 ring-brand-500" : ""}`, children: [
|
|
338
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
339
|
+
/* @__PURE__ */ jsx(FocusFoto, { item: m, onFocus: (f) => void zetFocus(m, f) }),
|
|
340
|
+
/* @__PURE__ */ jsx("label", { className: "absolute top-1.5 left-1.5 flex h-7 w-7 cursor-pointer items-center justify-center rounded-md bg-white/90 shadow", children: /* @__PURE__ */ jsx(
|
|
341
|
+
"input",
|
|
342
|
+
{
|
|
343
|
+
type: "checkbox",
|
|
344
|
+
className: "h-4 w-4 cursor-pointer accent-brand-600",
|
|
345
|
+
checked: geselecteerd.has(m.id),
|
|
346
|
+
onChange: () => wisselSelectie(m.id),
|
|
347
|
+
"aria-label": `Selecteer ${m.name ?? "foto"}`
|
|
348
|
+
}
|
|
349
|
+
) })
|
|
350
|
+
] }),
|
|
227
351
|
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between gap-1", children: [
|
|
228
|
-
/* @__PURE__ */ jsxs("span", { className: "
|
|
229
|
-
m.name,
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
m.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
] })
|
|
352
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0 text-xs text-slate-500", children: [
|
|
353
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate", title: m.name, children: m.name }),
|
|
354
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate", children: [
|
|
355
|
+
m.width && m.height ? `${m.width}\xD7${m.height}` : "",
|
|
356
|
+
leesbareGrootte(m.size),
|
|
357
|
+
korteDatum(m.createdAt)
|
|
358
|
+
].filter(Boolean).join(" \xB7 ") })
|
|
236
359
|
] }),
|
|
237
360
|
m.status === "processing" ? /* @__PURE__ */ jsx(Badge, { tone: "amber", children: "verwerken" }) : ongebruikt?.includes(m.id) ? /* @__PURE__ */ jsx(Badge, { tone: "amber", children: "ongebruikt" }) : /* @__PURE__ */ jsx(Badge, { tone: "green", children: "klaar" })
|
|
238
361
|
] }),
|
|
239
362
|
/* @__PURE__ */ jsx(AltInput, { item: m, onSave: saveAlt }),
|
|
240
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-1", children: [
|
|
241
|
-
/* @__PURE__ */ jsx(
|
|
242
|
-
|
|
363
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
364
|
+
/* @__PURE__ */ jsx(
|
|
365
|
+
Button,
|
|
366
|
+
{
|
|
367
|
+
variant: "ghost",
|
|
368
|
+
size: "sm",
|
|
369
|
+
className: "text-xs",
|
|
370
|
+
onClick: () => void navigator.clipboard?.writeText(m.url).then(() => toast({ title: "Adres gekopieerd", tone: "success" })).catch(() => toast({ title: "Kopi\xEBren lukte niet", description: m.url, tone: "error" })),
|
|
371
|
+
children: "Kopieer adres"
|
|
372
|
+
}
|
|
373
|
+
),
|
|
374
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", className: "text-xs", onClick: () => void download(m), children: "Download" }),
|
|
375
|
+
/* @__PURE__ */ jsx(Button, { variant: "dangerGhost", size: "sm", className: "text-xs", onClick: () => void remove(m), children: "Verwijderen" })
|
|
243
376
|
] })
|
|
244
377
|
] }, m.id)),
|
|
245
|
-
items.length === 0 && /* @__PURE__ */ jsx(
|
|
246
|
-
items.length > 0 && getoond.length === 0 && /* @__PURE__ */
|
|
247
|
-
"Geen foto's gevonden voor \u201C",
|
|
248
|
-
zoek,
|
|
249
|
-
"\u201D."
|
|
250
|
-
] })
|
|
378
|
+
items.length === 0 && /* @__PURE__ */ jsx(LegeStaat, { titel: "Nog geen foto's", tekst: "Sleep foto's hierheen of gebruik Uploaden. Ze worden vanzelf verkleind en in meerdere formaten klaargezet." }),
|
|
379
|
+
items.length > 0 && getoond.length === 0 && /* @__PURE__ */ jsx("p", { className: "text-sm text-slate-500", children: zonderAlt && !term ? "Alle foto's hebben een beschrijving." : `Geen foto's gevonden voor \u201C${zoek}\u201D.` })
|
|
251
380
|
] }),
|
|
252
381
|
hasMore && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", onClick: () => setPageCount((c) => c + 1), children: "Meer laden\u2026" }) })
|
|
253
382
|
]
|
|
@@ -264,13 +393,14 @@ function AltInput({ item, onSave }) {
|
|
|
264
393
|
Input,
|
|
265
394
|
{
|
|
266
395
|
value,
|
|
267
|
-
placeholder: "
|
|
268
|
-
|
|
396
|
+
placeholder: "Beschrijving (alt-tekst)",
|
|
397
|
+
"aria-label": `Beschrijving van ${item.name ?? "de foto"} voor schermlezers en Google`,
|
|
398
|
+
className: "mb-2 text-xs",
|
|
269
399
|
onChange: (e) => setValue(e.target.value),
|
|
270
400
|
onFocus: () => setFocused(true),
|
|
271
401
|
onBlur: () => {
|
|
272
402
|
setFocused(false);
|
|
273
|
-
void onSave(item, value);
|
|
403
|
+
if (value !== (item.alt ?? "")) void onSave(item, value);
|
|
274
404
|
}
|
|
275
405
|
}
|
|
276
406
|
);
|