@xiwebdesign/xicms-core 5.8.3 → 6.1.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/admin/panelRegistry.js +1 -3
- package/dist/admin/panelRegistry.js.map +1 -1
- package/dist/admin/settings/MailSettings.d.ts +10 -0
- package/dist/admin/settings/MailSettings.js +166 -0
- package/dist/admin/settings/MailSettings.js.map +1 -0
- package/dist/admin/settings/SettingsPanel.js +8 -2
- package/dist/admin/settings/SettingsPanel.js.map +1 -1
- package/dist/admin/shop/ConnectionsTab.d.ts +7 -3
- package/dist/admin/shop/ConnectionsTab.js +8 -116
- package/dist/admin/shop/ConnectionsTab.js.map +1 -1
- package/dist/admin/shop/ShopPanel.d.ts +2 -1
- package/dist/admin/shop/ShopPanel.js.map +1 -1
- package/dist/admin/shop/index.d.ts +9 -0
- package/dist/admin/shop/index.js +14 -0
- package/dist/admin/shop/index.js.map +1 -0
- package/dist/all.d.ts +6 -0
- package/dist/all.js +15 -0
- package/dist/all.js.map +1 -0
- package/dist/modules/builtins.d.ts +0 -1
- package/dist/modules/builtins.js +0 -4
- package/dist/modules/builtins.js.map +1 -1
- package/dist/modules/shop/index.d.ts +13 -0
- package/dist/modules/shop/index.js +15 -0
- package/dist/modules/shop/index.js.map +1 -0
- package/dist/schema/blocks.d.ts +1285 -1285
- package/dist/schema/customBlocks.d.ts +2 -2
- package/dist/schema/forms.d.ts +6 -6
- package/dist/schema/pages.d.ts +59 -59
- package/dist/schema/seo.d.ts +2 -2
- package/dist/schema/settings.d.ts +222 -222
- package/dist/schema/shop.d.ts +48 -48
- package/dist/schema/siteConfig.d.ts +108 -108
- package/dist/schema/symbols.d.ts +14 -14
- package/dist/server/index.d.ts +0 -1
- package/dist/server/index.js +0 -14
- package/dist/server/index.js.map +1 -1
- package/package.json +17 -1
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useCallback, useEffect, useState } from "react";
|
|
4
4
|
import { Badge, Button, Card, Field, Input } from "../ui/primitives";
|
|
5
|
-
import { Switch } from "../ui/switch";
|
|
6
5
|
import { useToast } from "../ui/toast";
|
|
7
6
|
import { shopCallable } from "./lib";
|
|
8
7
|
function Segmented({
|
|
@@ -28,30 +27,16 @@ function ConnectionsTab({ siteId }) {
|
|
|
28
27
|
const [payProvider, setPayProvider] = useState("stripe");
|
|
29
28
|
const [stripeKey, setStripeKey] = useState("");
|
|
30
29
|
const [mollieKey, setMollieKey] = useState("");
|
|
31
|
-
const [mailProvider, setMailProvider] = useState("smtp");
|
|
32
|
-
const [resendKey, setResendKey] = useState("");
|
|
33
|
-
const [postmarkToken, setPostmarkToken] = useState("");
|
|
34
|
-
const [smtp, setSmtp] = useState({ host: "", port: "465", secure: true, user: "", pass: "" });
|
|
35
|
-
const [fromName, setFromName] = useState("");
|
|
36
|
-
const [fromEmail, setFromEmail] = useState("");
|
|
37
|
-
const [notifyTo, setNotifyTo] = useState("");
|
|
38
30
|
const refresh = useCallback(async () => {
|
|
39
31
|
try {
|
|
40
32
|
const raw = await shopCallable("getShopStatus")({ siteId });
|
|
41
33
|
const s = {
|
|
42
34
|
provider: raw.provider ?? "stripe",
|
|
43
35
|
stripe: raw.stripe ?? { configured: false, webhookConfigured: false },
|
|
44
|
-
mollie: raw.mollie ?? { configured: false }
|
|
45
|
-
mail: raw.mail ?? { configured: false }
|
|
36
|
+
mollie: raw.mollie ?? { configured: false }
|
|
46
37
|
};
|
|
47
38
|
setStatus(s);
|
|
48
39
|
setPayProvider(s.provider ?? "stripe");
|
|
49
|
-
const m = s.mail ?? {};
|
|
50
|
-
setMailProvider(m.provider ?? (m.host ? "smtp" : m.hasPostmarkToken ? "postmark" : m.hasResendKey ? "resend" : "smtp"));
|
|
51
|
-
setSmtp((p) => ({ ...p, host: m.host ?? p.host, port: String(m.port ?? 465), secure: m.secure !== false, user: m.user ?? p.user }));
|
|
52
|
-
setFromName(m.fromName ?? "");
|
|
53
|
-
setFromEmail(m.fromEmail ?? "");
|
|
54
|
-
setNotifyTo(m.notifyTo ?? "");
|
|
55
40
|
} catch {
|
|
56
41
|
setStatus(null);
|
|
57
42
|
}
|
|
@@ -100,42 +85,6 @@ function ConnectionsTab({ siteId }) {
|
|
|
100
85
|
}
|
|
101
86
|
}
|
|
102
87
|
}
|
|
103
|
-
async function saveMail() {
|
|
104
|
-
setBusy(true);
|
|
105
|
-
try {
|
|
106
|
-
const mail = { provider: mailProvider, fromName, fromEmail, notifyTo };
|
|
107
|
-
if (mailProvider === "resend") mail.resendApiKey = resendKey.trim() || void 0;
|
|
108
|
-
if (mailProvider === "postmark") mail.postmarkToken = postmarkToken.trim() || void 0;
|
|
109
|
-
if (mailProvider === "smtp") {
|
|
110
|
-
mail.host = smtp.host.trim();
|
|
111
|
-
mail.port = Number(smtp.port) || 465;
|
|
112
|
-
mail.secure = smtp.secure;
|
|
113
|
-
mail.user = smtp.user.trim();
|
|
114
|
-
if (smtp.pass) mail.pass = smtp.pass;
|
|
115
|
-
}
|
|
116
|
-
await shopCallable("saveMailSettings")({ siteId, mail });
|
|
117
|
-
toast({ title: "E-mailinstellingen opgeslagen", tone: "success" });
|
|
118
|
-
setResendKey("");
|
|
119
|
-
setPostmarkToken("");
|
|
120
|
-
setSmtp((p) => ({ ...p, pass: "" }));
|
|
121
|
-
await refresh();
|
|
122
|
-
} catch (e) {
|
|
123
|
-
toast({ title: "Opslaan mislukt", description: e instanceof Error ? e.message : void 0, tone: "error" });
|
|
124
|
-
} finally {
|
|
125
|
-
setBusy(false);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
async function sendTest() {
|
|
129
|
-
setBusy(true);
|
|
130
|
-
try {
|
|
131
|
-
const res = await shopCallable("sendShopTestMail")({ siteId });
|
|
132
|
-
toast({ title: "Testmail verstuurd", description: `Naar ${res.to} \u2014 check de inbox (en spam).`, tone: "success" });
|
|
133
|
-
} catch (e) {
|
|
134
|
-
toast({ title: "Testmail mislukt", description: e instanceof Error ? e.message : void 0, tone: "error" });
|
|
135
|
-
} finally {
|
|
136
|
-
setBusy(false);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
88
|
const payConfigured = payProvider === "stripe" ? status?.stripe.configured : status?.mollie.configured;
|
|
140
89
|
return /* @__PURE__ */ jsxs("div", { className: "grid gap-4", children: [
|
|
141
90
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs("div", { className: "grid gap-4", children: [
|
|
@@ -193,76 +142,19 @@ function ConnectionsTab({ siteId }) {
|
|
|
193
142
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Button, { onClick: savePayment, disabled: busy || !mollieKey.trim(), children: "Koppel Mollie" }) })
|
|
194
143
|
] })
|
|
195
144
|
] }) }),
|
|
196
|
-
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs("div", { className: "grid gap-4", children: [
|
|
197
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
|
|
198
|
-
/* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold", children: "E-mail (bestelbevestigingen & formulieren)" }),
|
|
199
|
-
status && /* @__PURE__ */ jsx(Badge, { tone: status.mail.configured ? "green" : "amber", children: status.mail.configured ? `${mailProviderLabel(mailProvider)} actief` : "Nog niet ingesteld" })
|
|
200
|
-
] }),
|
|
201
|
-
/* @__PURE__ */ jsx(
|
|
202
|
-
Segmented,
|
|
203
|
-
{
|
|
204
|
-
value: mailProvider,
|
|
205
|
-
onChange: setMailProvider,
|
|
206
|
-
options: [
|
|
207
|
-
{ value: "smtp", label: "Eigen SMTP" },
|
|
208
|
-
{ value: "resend", label: "Resend" },
|
|
209
|
-
{ value: "postmark", label: "Postmark" }
|
|
210
|
-
]
|
|
211
|
-
}
|
|
212
|
-
),
|
|
213
|
-
mailProvider === "smtp" && /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
|
|
214
|
-
/* @__PURE__ */ jsxs("p", { className: "text-sm text-slate-600", children: [
|
|
215
|
-
"Via je eigen mailbox: bv. het adres bij je hostingpartij, of Gmail (smtp.gmail.com, poort 465, met een",
|
|
216
|
-
" ",
|
|
217
|
-
/* @__PURE__ */ jsx("a", { className: "underline", href: "https://myaccount.google.com/apppasswords", target: "_blank", rel: "noreferrer", children: "app-wachtwoord" }),
|
|
218
|
-
")."
|
|
219
|
-
] }),
|
|
220
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 md:grid-cols-[1fr_110px]", children: [
|
|
221
|
-
/* @__PURE__ */ jsx(Field, { label: "SMTP-server", children: /* @__PURE__ */ jsx(Input, { value: smtp.host, onChange: (e) => setSmtp((p) => ({ ...p, host: e.target.value })), placeholder: "smtp.gmail.com" }) }),
|
|
222
|
-
/* @__PURE__ */ jsx(Field, { label: "Poort", children: /* @__PURE__ */ jsx(Input, { value: smtp.port, onChange: (e) => setSmtp((p) => ({ ...p, port: e.target.value })), placeholder: "465" }) })
|
|
223
|
-
] }),
|
|
224
|
-
/* @__PURE__ */ jsx(Switch, { checked: smtp.secure, onCheckedChange: (v) => setSmtp((p) => ({ ...p, secure: v })), label: "SSL (poort 465). Uit = STARTTLS (poort 587)" }),
|
|
225
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 md:grid-cols-2", children: [
|
|
226
|
-
/* @__PURE__ */ jsx(Field, { label: "Gebruikersnaam", children: /* @__PURE__ */ jsx(Input, { value: smtp.user, onChange: (e) => setSmtp((p) => ({ ...p, user: e.target.value })), placeholder: "info@jouwdomein.nl" }) }),
|
|
227
|
-
/* @__PURE__ */ jsx(Field, { label: "Wachtwoord", hint: status?.mail.hasSmtpPass ? "Leeg laten = ongewijzigd" : void 0, children: /* @__PURE__ */ jsx(Input, { type: "password", value: smtp.pass, onChange: (e) => setSmtp((p) => ({ ...p, pass: e.target.value })) }) })
|
|
228
|
-
] })
|
|
229
|
-
] }),
|
|
230
|
-
mailProvider === "resend" && /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
|
|
231
|
-
/* @__PURE__ */ jsxs("p", { className: "text-sm text-slate-600", children: [
|
|
232
|
-
/* @__PURE__ */ jsx("a", { className: "underline", href: "https://resend.com", target: "_blank", rel: "noreferrer", children: "Resend" }),
|
|
233
|
-
" verstuurt vanaf een geverifieerd domein. Maak een API-sleutel (re_\u2026) en verifieer je afzenderdomein in het Resend-dashboard."
|
|
234
|
-
] }),
|
|
235
|
-
/* @__PURE__ */ jsx(Field, { label: "Resend API-sleutel (re_\u2026)", hint: status?.mail.hasResendKey ? "Leeg laten = ongewijzigd" : void 0, children: /* @__PURE__ */ jsx(Input, { type: "password", value: resendKey, onChange: (e) => setResendKey(e.target.value), placeholder: "re_\u2026" }) })
|
|
236
|
-
] }),
|
|
237
|
-
mailProvider === "postmark" && /* @__PURE__ */ jsxs("div", { className: "grid gap-3", children: [
|
|
238
|
-
/* @__PURE__ */ jsxs("p", { className: "text-sm text-slate-600", children: [
|
|
239
|
-
/* @__PURE__ */ jsx("a", { className: "underline", href: "https://postmarkapp.com", target: "_blank", rel: "noreferrer", children: "Postmark" }),
|
|
240
|
-
" verstuurt vanaf een geverifieerde afzender/domein (Sender Signature). Kopieer het Server-token."
|
|
241
|
-
] }),
|
|
242
|
-
/* @__PURE__ */ jsx(Field, { label: "Postmark server-token", hint: status?.mail.hasPostmarkToken ? "Leeg laten = ongewijzigd" : void 0, children: /* @__PURE__ */ jsx(Input, { type: "password", value: postmarkToken, onChange: (e) => setPostmarkToken(e.target.value), placeholder: "xxxxxxxx-xxxx-\u2026" }) })
|
|
243
|
-
] }),
|
|
244
|
-
/* @__PURE__ */ jsxs("div", { className: "grid gap-3 md:grid-cols-2", children: [
|
|
245
|
-
/* @__PURE__ */ jsx(Field, { label: "Afzendernaam", children: /* @__PURE__ */ jsx(Input, { value: fromName, onChange: (e) => setFromName(e.target.value), placeholder: "Christelijk Kraamcadeau" }) }),
|
|
246
|
-
/* @__PURE__ */ jsx(Field, { label: "Afzenderadres", children: /* @__PURE__ */ jsx(Input, { value: fromEmail, onChange: (e) => setFromEmail(e.target.value), placeholder: "info@jouwdomein.nl" }) })
|
|
247
|
-
] }),
|
|
248
|
-
/* @__PURE__ */ jsx(Field, { label: "Notificatie-adres", hint: "Hier ontvang je zelf een mail bij elke bestelling; ook het doel van de testmail", children: /* @__PURE__ */ jsx(Input, { value: notifyTo, onChange: (e) => setNotifyTo(e.target.value), placeholder: "bestellingen@jouwdomein.nl" }) }),
|
|
249
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
250
|
-
/* @__PURE__ */ jsx(Button, { onClick: saveMail, disabled: busy, children: "Opslaan" }),
|
|
251
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: sendTest, disabled: busy || !status?.mail.configured, children: "Stuur testmail" })
|
|
252
|
-
] })
|
|
253
|
-
] }) }),
|
|
254
145
|
/* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs("p", { className: "text-sm text-slate-600", children: [
|
|
255
|
-
"
|
|
256
|
-
/* @__PURE__ */ jsx("strong", { children: "
|
|
257
|
-
"
|
|
146
|
+
"De ",
|
|
147
|
+
/* @__PURE__ */ jsx("strong", { children: "e-mailprovider" }),
|
|
148
|
+
" (bestelbevestigingen \xE9n formulieren) stel je site-breed in onder ",
|
|
149
|
+
/* @__PURE__ */ jsx("strong", { children: "Instellingen \u2192 E-mail" }),
|
|
150
|
+
". Verzendkosten, valuta, ordernummer-prefix en bedrijfsgegevens (factuur) staan onder het tabblad ",
|
|
151
|
+
/* @__PURE__ */ jsx("strong", { children: "Instellingen" }),
|
|
152
|
+
"; mailteksten onder ",
|
|
258
153
|
/* @__PURE__ */ jsx("strong", { children: "E-mails" }),
|
|
259
154
|
"."
|
|
260
155
|
] }) })
|
|
261
156
|
] });
|
|
262
157
|
}
|
|
263
|
-
function mailProviderLabel(p) {
|
|
264
|
-
return p === "smtp" ? "Eigen SMTP" : p === "resend" ? "Resend" : "Postmark";
|
|
265
|
-
}
|
|
266
158
|
export {
|
|
267
159
|
ConnectionsTab
|
|
268
160
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/shop/ConnectionsTab.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Badge, Button, Card, Field, Input } from \"../ui/primitives\";\nimport { Switch } from \"../ui/switch\";\nimport { useToast } from \"../ui/toast\";\nimport { shopCallable } from \"./lib\";\n\ntype PayProvider = \"stripe\" | \"mollie\";\ntype MailProvider = \"resend\" | \"postmark\" | \"smtp\";\n\ninterface ShopStatus {\n provider: PayProvider;\n stripe: { configured: boolean; account?: string; webhookConfigured: boolean };\n mollie: { configured: boolean; profile?: string };\n mail: {\n provider?: MailProvider;\n configured: boolean;\n host?: string;\n port?: number;\n secure?: boolean;\n user?: string;\n fromName?: string;\n fromEmail?: string;\n notifyTo?: string;\n hasResendKey?: boolean;\n hasPostmarkToken?: boolean;\n hasSmtpPass?: boolean;\n };\n}\n\n/** Segmented control voor providerkeuze. */\nfunction Segmented<T extends string>({\n value,\n options,\n onChange,\n}: {\n value: T;\n options: { value: T; label: string }[];\n onChange: (v: T) => void;\n}) {\n return (\n <div className=\"inline-flex rounded-lg border border-slate-200 bg-slate-50 p-0.5\">\n {options.map((o) => (\n <button\n key={o.value}\n type=\"button\"\n onClick={() => onChange(o.value)}\n className={`rounded-md px-3 py-1.5 text-sm font-medium transition ${\n value === o.value ? \"bg-white text-brand-700 shadow-sm\" : \"text-slate-500 hover:text-slate-700\"\n }`}\n >\n {o.label}\n </button>\n ))}\n </div>\n );\n}\n\n/**\n * Koppelingen — betaalprovider (Stripe of Mollie) en mailprovider (Resend, Postmark of eigen SMTP).\n * Geheimen gaan uitsluitend via callables naar `sites/{siteId}/private/*` (deny-all rules); dit\n * paneel toont alleen gemaskeerde status. Alleen een siteadmin kan opslaan.\n */\nexport function ConnectionsTab({ siteId }: { siteId: string }) {\n const { toast } = useToast();\n const [status, setStatus] = useState<ShopStatus | null>(null);\n const [busy, setBusy] = useState(false);\n\n // Betaling\n const [payProvider, setPayProvider] = useState<PayProvider>(\"stripe\");\n const [stripeKey, setStripeKey] = useState(\"\");\n const [mollieKey, setMollieKey] = useState(\"\");\n\n // Mail\n const [mailProvider, setMailProvider] = useState<MailProvider>(\"smtp\");\n const [resendKey, setResendKey] = useState(\"\");\n const [postmarkToken, setPostmarkToken] = useState(\"\");\n const [smtp, setSmtp] = useState({ host: \"\", port: \"465\", secure: true, user: \"\", pass: \"\" });\n const [fromName, setFromName] = useState(\"\");\n const [fromEmail, setFromEmail] = useState(\"\");\n const [notifyTo, setNotifyTo] = useState(\"\");\n\n const refresh = useCallback(async () => {\n try {\n const raw = await shopCallable<{ siteId: string }, Partial<ShopStatus>>(\"getShopStatus\")({ siteId });\n // Normaliseer naar de volledige vorm zodat de render nooit op een ontbrekend deel-object\n // (bv. een oudere functions-versie zonder mollie/mail) kan crashen.\n const s: ShopStatus = {\n provider: raw.provider ?? \"stripe\",\n stripe: raw.stripe ?? { configured: false, webhookConfigured: false },\n mollie: raw.mollie ?? { configured: false },\n mail: raw.mail ?? { configured: false },\n };\n setStatus(s);\n setPayProvider(s.provider ?? \"stripe\");\n const m = s.mail ?? {};\n setMailProvider(m.provider ?? (m.host ? \"smtp\" : m.hasPostmarkToken ? \"postmark\" : m.hasResendKey ? \"resend\" : \"smtp\"));\n setSmtp((p) => ({ ...p, host: m.host ?? p.host, port: String(m.port ?? 465), secure: m.secure !== false, user: m.user ?? p.user }));\n setFromName(m.fromName ?? \"\");\n setFromEmail(m.fromEmail ?? \"\");\n setNotifyTo(m.notifyTo ?? \"\");\n } catch {\n setStatus(null);\n }\n }, [siteId]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n async function savePayment() {\n setBusy(true);\n try {\n const payload: Record<string, unknown> = { siteId, provider: payProvider };\n if (payProvider === \"stripe\") {\n if (!stripeKey.trim().startsWith(\"sk_\") && !stripeKey.trim().startsWith(\"rk_\")) {\n toast({ title: \"Ongeldige sleutel\", description: \"Plak een Stripe geheime sleutel (sk_…) of restricted key (rk_…).\", tone: \"error\" });\n setBusy(false);\n return;\n }\n payload.stripe = { secretKey: stripeKey.trim() };\n } else {\n if (!/^(test|live)_/.test(mollieKey.trim())) {\n toast({ title: \"Ongeldige sleutel\", description: \"Plak een Mollie API-sleutel (test_… of live_…).\", tone: \"error\" });\n setBusy(false);\n return;\n }\n payload.mollie = { apiKey: mollieKey.trim() };\n }\n const res = await shopCallable<Record<string, unknown>, { account?: string }>(\"saveShopSecrets\")(payload);\n toast({ title: `${payProvider === \"stripe\" ? \"Stripe\" : \"Mollie\"} gekoppeld`, description: res.account ? `Account: ${res.account}` : undefined, tone: \"success\" });\n setStripeKey(\"\");\n setMollieKey(\"\");\n await refresh();\n } catch (e) {\n toast({ title: \"Koppelen mislukt\", description: e instanceof Error ? e.message : undefined, tone: \"error\" });\n } finally {\n setBusy(false);\n }\n }\n\n async function switchActiveProvider(p: PayProvider) {\n setPayProvider(p);\n // Alleen de actieve provider wisselen als de andere al geconfigureerd is (anders vraagt het formulier eerst een sleutel).\n const otherConfigured = p === \"stripe\" ? status?.stripe.configured : status?.mollie.configured;\n if (otherConfigured) {\n try {\n await shopCallable<{ siteId: string; provider: PayProvider }, unknown>(\"saveShopSecrets\")({ siteId, provider: p });\n await refresh();\n } catch {\n /* stil — de gebruiker kan alsnog opslaan */\n }\n }\n }\n\n async function saveMail() {\n setBusy(true);\n try {\n const mail: Record<string, unknown> = { provider: mailProvider, fromName, fromEmail, notifyTo };\n if (mailProvider === \"resend\") mail.resendApiKey = resendKey.trim() || undefined;\n if (mailProvider === \"postmark\") mail.postmarkToken = postmarkToken.trim() || undefined;\n if (mailProvider === \"smtp\") {\n mail.host = smtp.host.trim();\n mail.port = Number(smtp.port) || 465;\n mail.secure = smtp.secure;\n mail.user = smtp.user.trim();\n if (smtp.pass) mail.pass = smtp.pass;\n }\n await shopCallable<{ siteId: string; mail: Record<string, unknown> }, { ok: boolean }>(\"saveMailSettings\")({ siteId, mail });\n toast({ title: \"E-mailinstellingen opgeslagen\", tone: \"success\" });\n setResendKey(\"\");\n setPostmarkToken(\"\");\n setSmtp((p) => ({ ...p, pass: \"\" }));\n await refresh();\n } catch (e) {\n toast({ title: \"Opslaan mislukt\", description: e instanceof Error ? e.message : undefined, tone: \"error\" });\n } finally {\n setBusy(false);\n }\n }\n\n async function sendTest() {\n setBusy(true);\n try {\n const res = await shopCallable<{ siteId: string }, { to: string }>(\"sendShopTestMail\")({ siteId });\n toast({ title: \"Testmail verstuurd\", description: `Naar ${res.to} — check de inbox (en spam).`, tone: \"success\" });\n } catch (e) {\n toast({ title: \"Testmail mislukt\", description: e instanceof Error ? e.message : undefined, tone: \"error\" });\n } finally {\n setBusy(false);\n }\n }\n\n const payConfigured = payProvider === \"stripe\" ? status?.stripe.configured : status?.mollie.configured;\n\n return (\n <div className=\"grid gap-4\">\n {/* ── Betalingen ─────────────────────────────────────────────── */}\n <Card>\n <div className=\"grid gap-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold\">Betalingen</h3>\n {status && (\n <Badge tone={payConfigured ? \"green\" : \"amber\"}>\n {payProvider === \"stripe\"\n ? status.stripe.configured\n ? `Stripe actief${status.stripe.account ? ` — ${status.stripe.account}` : \"\"}`\n : \"Stripe nog niet gekoppeld\"\n : status.mollie.configured\n ? `Mollie actief${status.mollie.profile ? ` — ${status.mollie.profile}` : \"\"}`\n : \"Mollie nog niet gekoppeld\"}\n </Badge>\n )}\n </div>\n\n <Segmented\n value={payProvider}\n onChange={(v) => void switchActiveProvider(v)}\n options={[\n { value: \"stripe\", label: \"Stripe\" },\n { value: \"mollie\", label: \"Mollie\" },\n ]}\n />\n\n {payProvider === \"stripe\" ? (\n <div className=\"grid gap-3\">\n <ol className=\"grid list-decimal gap-1 pl-5 text-sm text-slate-600\">\n <li>Maak een gratis account op <a className=\"underline\" href=\"https://dashboard.stripe.com/register\" target=\"_blank\" rel=\"noreferrer\">stripe.com</a> en activeer het (IBAN, KVK).</li>\n <li>Zet onder <em>Settings → Payment methods</em> iDEAL aan.</li>\n <li>Maak onder <em>Developers → API keys</em> een sleutel aan en plak hem hieronder — de webhook wordt automatisch aangemaakt.</li>\n </ol>\n <Field label=\"Stripe geheime sleutel (sk_live_… of rk_live_…)\" hint=\"Wordt veilig opgeslagen; nooit zichtbaar in de browser\">\n <Input type=\"password\" value={stripeKey} onChange={(e) => setStripeKey(e.target.value)} placeholder=\"sk_live_…\" />\n </Field>\n {status?.stripe.configured && !status.stripe.webhookConfigured && (\n <p className=\"rounded-lg bg-amber-50 px-3 py-2 text-sm text-amber-700\">\n Webhook nog niet geregistreerd — koppel opnieuw met een sleutel die webhook-rechten heeft.\n </p>\n )}\n <div><Button onClick={savePayment} disabled={busy || !stripeKey.trim()}>Koppel Stripe</Button></div>\n </div>\n ) : (\n <div className=\"grid gap-3\">\n <ol className=\"grid list-decimal gap-1 pl-5 text-sm text-slate-600\">\n <li>Maak een account op <a className=\"underline\" href=\"https://www.mollie.com/dashboard/signup\" target=\"_blank\" rel=\"noreferrer\">mollie.com</a> en doorloop de onboarding.</li>\n <li>Zet in het Mollie-dashboard de gewenste betaalmethoden (o.a. iDEAL) aan.</li>\n <li>Kopieer onder <em>Developers → API-keys</em> je live- of test-sleutel en plak hem hieronder. Mollie heeft geen aparte webhook-registratie nodig.</li>\n </ol>\n <Field label=\"Mollie API-sleutel (live_… of test_…)\" hint=\"Wordt veilig opgeslagen; nooit zichtbaar in de browser\">\n <Input type=\"password\" value={mollieKey} onChange={(e) => setMollieKey(e.target.value)} placeholder=\"live_…\" />\n </Field>\n <div><Button onClick={savePayment} disabled={busy || !mollieKey.trim()}>Koppel Mollie</Button></div>\n </div>\n )}\n </div>\n </Card>\n\n {/* ── E-mail ─────────────────────────────────────────────────── */}\n <Card>\n <div className=\"grid gap-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold\">E-mail (bestelbevestigingen & formulieren)</h3>\n {status && (\n <Badge tone={status.mail.configured ? \"green\" : \"amber\"}>\n {status.mail.configured ? `${mailProviderLabel(mailProvider)} actief` : \"Nog niet ingesteld\"}\n </Badge>\n )}\n </div>\n\n <Segmented\n value={mailProvider}\n onChange={setMailProvider}\n options={[\n { value: \"smtp\", label: \"Eigen SMTP\" },\n { value: \"resend\", label: \"Resend\" },\n { value: \"postmark\", label: \"Postmark\" },\n ]}\n />\n\n {mailProvider === \"smtp\" && (\n <div className=\"grid gap-3\">\n <p className=\"text-sm text-slate-600\">\n Via je eigen mailbox: bv. het adres bij je hostingpartij, of Gmail (smtp.gmail.com, poort 465, met een{\" \"}\n <a className=\"underline\" href=\"https://myaccount.google.com/apppasswords\" target=\"_blank\" rel=\"noreferrer\">app-wachtwoord</a>).\n </p>\n <div className=\"grid gap-3 md:grid-cols-[1fr_110px]\">\n <Field label=\"SMTP-server\"><Input value={smtp.host} onChange={(e) => setSmtp((p) => ({ ...p, host: e.target.value }))} placeholder=\"smtp.gmail.com\" /></Field>\n <Field label=\"Poort\"><Input value={smtp.port} onChange={(e) => setSmtp((p) => ({ ...p, port: e.target.value }))} placeholder=\"465\" /></Field>\n </div>\n <Switch checked={smtp.secure} onCheckedChange={(v) => setSmtp((p) => ({ ...p, secure: v }))} label=\"SSL (poort 465). Uit = STARTTLS (poort 587)\" />\n <div className=\"grid gap-3 md:grid-cols-2\">\n <Field label=\"Gebruikersnaam\"><Input value={smtp.user} onChange={(e) => setSmtp((p) => ({ ...p, user: e.target.value }))} placeholder=\"info@jouwdomein.nl\" /></Field>\n <Field label=\"Wachtwoord\" hint={status?.mail.hasSmtpPass ? \"Leeg laten = ongewijzigd\" : undefined}>\n <Input type=\"password\" value={smtp.pass} onChange={(e) => setSmtp((p) => ({ ...p, pass: e.target.value }))} />\n </Field>\n </div>\n </div>\n )}\n\n {mailProvider === \"resend\" && (\n <div className=\"grid gap-3\">\n <p className=\"text-sm text-slate-600\">\n <a className=\"underline\" href=\"https://resend.com\" target=\"_blank\" rel=\"noreferrer\">Resend</a> verstuurt vanaf een geverifieerd domein.\n Maak een API-sleutel (re_…) en verifieer je afzenderdomein in het Resend-dashboard.\n </p>\n <Field label=\"Resend API-sleutel (re_…)\" hint={status?.mail.hasResendKey ? \"Leeg laten = ongewijzigd\" : undefined}>\n <Input type=\"password\" value={resendKey} onChange={(e) => setResendKey(e.target.value)} placeholder=\"re_…\" />\n </Field>\n </div>\n )}\n\n {mailProvider === \"postmark\" && (\n <div className=\"grid gap-3\">\n <p className=\"text-sm text-slate-600\">\n <a className=\"underline\" href=\"https://postmarkapp.com\" target=\"_blank\" rel=\"noreferrer\">Postmark</a> verstuurt vanaf een geverifieerde afzender/domein (Sender Signature).\n Kopieer het Server-token.\n </p>\n <Field label=\"Postmark server-token\" hint={status?.mail.hasPostmarkToken ? \"Leeg laten = ongewijzigd\" : undefined}>\n <Input type=\"password\" value={postmarkToken} onChange={(e) => setPostmarkToken(e.target.value)} placeholder=\"xxxxxxxx-xxxx-…\" />\n </Field>\n </div>\n )}\n\n {/* Gedeelde afzender-velden */}\n <div className=\"grid gap-3 md:grid-cols-2\">\n <Field label=\"Afzendernaam\"><Input value={fromName} onChange={(e) => setFromName(e.target.value)} placeholder=\"Christelijk Kraamcadeau\" /></Field>\n <Field label=\"Afzenderadres\"><Input value={fromEmail} onChange={(e) => setFromEmail(e.target.value)} placeholder=\"info@jouwdomein.nl\" /></Field>\n </div>\n <Field label=\"Notificatie-adres\" hint=\"Hier ontvang je zelf een mail bij elke bestelling; ook het doel van de testmail\">\n <Input value={notifyTo} onChange={(e) => setNotifyTo(e.target.value)} placeholder=\"bestellingen@jouwdomein.nl\" />\n </Field>\n\n <div className=\"flex items-center gap-2\">\n <Button onClick={saveMail} disabled={busy}>Opslaan</Button>\n <Button variant=\"secondary\" onClick={sendTest} disabled={busy || !status?.mail.configured}>Stuur testmail</Button>\n </div>\n </div>\n </Card>\n\n <Card>\n <p className=\"text-sm text-slate-600\">\n Verzendkosten, valuta, ordernummer-prefix en bedrijfsgegevens (factuur) stel je in onder het tabblad\n <strong> Instellingen</strong>. Mailteksten pas je aan onder <strong>E-mails</strong>.\n </p>\n </Card>\n </div>\n );\n}\n\nfunction mailProviderLabel(p: MailProvider): string {\n return p === \"smtp\" ? \"Eigen SMTP\" : p === \"resend\" ? \"Resend\" : \"Postmark\";\n}\n"],"mappings":";AA4CQ,cA6JE,YA7JF;AA1CR,SAAS,aAAa,WAAW,gBAAgB;AACjD,SAAS,OAAO,QAAQ,MAAM,OAAO,aAAa;AAClD,SAAS,cAAc;AACvB,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AA0B7B,SAAS,UAA4B;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,SACE,oBAAC,SAAI,WAAU,oEACZ,kBAAQ,IAAI,CAAC,MACZ;AAAA,IAAC;AAAA;AAAA,MAEC,MAAK;AAAA,MACL,SAAS,MAAM,SAAS,EAAE,KAAK;AAAA,MAC/B,WAAW,yDACT,UAAU,EAAE,QAAQ,sCAAsC,qCAC5D;AAAA,MAEC,YAAE;AAAA;AAAA,IAPE,EAAE;AAAA,EAQT,CACD,GACH;AAEJ;AAOO,SAAS,eAAe,EAAE,OAAO,GAAuB;AAC7D,QAAM,EAAE,MAAM,IAAI,SAAS;AAC3B,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA4B,IAAI;AAC5D,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AAGtC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAsB,QAAQ;AACpE,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,EAAE;AAC7C,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,EAAE;AAG7C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAuB,MAAM;AACrE,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,EAAE;AAC7C,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,EAAE;AACrD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE,MAAM,IAAI,MAAM,OAAO,QAAQ,MAAM,MAAM,IAAI,MAAM,GAAG,CAAC;AAC5F,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,EAAE;AAC7C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAE3C,QAAM,UAAU,YAAY,YAAY;AACtC,QAAI;AACF,YAAM,MAAM,MAAM,aAAsD,eAAe,EAAE,EAAE,OAAO,CAAC;AAGnG,YAAM,IAAgB;AAAA,QACpB,UAAU,IAAI,YAAY;AAAA,QAC1B,QAAQ,IAAI,UAAU,EAAE,YAAY,OAAO,mBAAmB,MAAM;AAAA,QACpE,QAAQ,IAAI,UAAU,EAAE,YAAY,MAAM;AAAA,QAC1C,MAAM,IAAI,QAAQ,EAAE,YAAY,MAAM;AAAA,MACxC;AACA,gBAAU,CAAC;AACX,qBAAe,EAAE,YAAY,QAAQ;AACrC,YAAM,IAAI,EAAE,QAAQ,CAAC;AACrB,sBAAgB,EAAE,aAAa,EAAE,OAAO,SAAS,EAAE,mBAAmB,aAAa,EAAE,eAAe,WAAW,OAAO;AACtH,cAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,MAAM,OAAO,EAAE,QAAQ,GAAG,GAAG,QAAQ,EAAE,WAAW,OAAO,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;AAClI,kBAAY,EAAE,YAAY,EAAE;AAC5B,mBAAa,EAAE,aAAa,EAAE;AAC9B,kBAAY,EAAE,YAAY,EAAE;AAAA,IAC9B,QAAQ;AACN,gBAAU,IAAI;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,YAAU,MAAM;AACd,SAAK,QAAQ;AAAA,EACf,GAAG,CAAC,OAAO,CAAC;AAEZ,iBAAe,cAAc;AAC3B,YAAQ,IAAI;AACZ,QAAI;AACF,YAAM,UAAmC,EAAE,QAAQ,UAAU,YAAY;AACzE,UAAI,gBAAgB,UAAU;AAC5B,YAAI,CAAC,UAAU,KAAK,EAAE,WAAW,KAAK,KAAK,CAAC,UAAU,KAAK,EAAE,WAAW,KAAK,GAAG;AAC9E,gBAAM,EAAE,OAAO,qBAAqB,aAAa,8EAAoE,MAAM,QAAQ,CAAC;AACpI,kBAAQ,KAAK;AACb;AAAA,QACF;AACA,gBAAQ,SAAS,EAAE,WAAW,UAAU,KAAK,EAAE;AAAA,MACjD,OAAO;AACL,YAAI,CAAC,gBAAgB,KAAK,UAAU,KAAK,CAAC,GAAG;AAC3C,gBAAM,EAAE,OAAO,qBAAqB,aAAa,6DAAmD,MAAM,QAAQ,CAAC;AACnH,kBAAQ,KAAK;AACb;AAAA,QACF;AACA,gBAAQ,SAAS,EAAE,QAAQ,UAAU,KAAK,EAAE;AAAA,MAC9C;AACA,YAAM,MAAM,MAAM,aAA4D,iBAAiB,EAAE,OAAO;AACxG,YAAM,EAAE,OAAO,GAAG,gBAAgB,WAAW,WAAW,QAAQ,cAAc,aAAa,IAAI,UAAU,YAAY,IAAI,OAAO,KAAK,QAAW,MAAM,UAAU,CAAC;AACjK,mBAAa,EAAE;AACf,mBAAa,EAAE;AACf,YAAM,QAAQ;AAAA,IAChB,SAAS,GAAG;AACV,YAAM,EAAE,OAAO,oBAAoB,aAAa,aAAa,QAAQ,EAAE,UAAU,QAAW,MAAM,QAAQ,CAAC;AAAA,IAC7G,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,iBAAe,qBAAqB,GAAgB;AAClD,mBAAe,CAAC;AAEhB,UAAM,kBAAkB,MAAM,WAAW,QAAQ,OAAO,aAAa,QAAQ,OAAO;AACpF,QAAI,iBAAiB;AACnB,UAAI;AACF,cAAM,aAAiE,iBAAiB,EAAE,EAAE,QAAQ,UAAU,EAAE,CAAC;AACjH,cAAM,QAAQ;AAAA,MAChB,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAEA,iBAAe,WAAW;AACxB,YAAQ,IAAI;AACZ,QAAI;AACF,YAAM,OAAgC,EAAE,UAAU,cAAc,UAAU,WAAW,SAAS;AAC9F,UAAI,iBAAiB,SAAU,MAAK,eAAe,UAAU,KAAK,KAAK;AACvE,UAAI,iBAAiB,WAAY,MAAK,gBAAgB,cAAc,KAAK,KAAK;AAC9E,UAAI,iBAAiB,QAAQ;AAC3B,aAAK,OAAO,KAAK,KAAK,KAAK;AAC3B,aAAK,OAAO,OAAO,KAAK,IAAI,KAAK;AACjC,aAAK,SAAS,KAAK;AACnB,aAAK,OAAO,KAAK,KAAK,KAAK;AAC3B,YAAI,KAAK,KAAM,MAAK,OAAO,KAAK;AAAA,MAClC;AACA,YAAM,aAAiF,kBAAkB,EAAE,EAAE,QAAQ,KAAK,CAAC;AAC3H,YAAM,EAAE,OAAO,iCAAiC,MAAM,UAAU,CAAC;AACjE,mBAAa,EAAE;AACf,uBAAiB,EAAE;AACnB,cAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,EAAE;AACnC,YAAM,QAAQ;AAAA,IAChB,SAAS,GAAG;AACV,YAAM,EAAE,OAAO,mBAAmB,aAAa,aAAa,QAAQ,EAAE,UAAU,QAAW,MAAM,QAAQ,CAAC;AAAA,IAC5G,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,iBAAe,WAAW;AACxB,YAAQ,IAAI;AACZ,QAAI;AACF,YAAM,MAAM,MAAM,aAAiD,kBAAkB,EAAE,EAAE,OAAO,CAAC;AACjG,YAAM,EAAE,OAAO,sBAAsB,aAAa,QAAQ,IAAI,EAAE,qCAAgC,MAAM,UAAU,CAAC;AAAA,IACnH,SAAS,GAAG;AACV,YAAM,EAAE,OAAO,oBAAoB,aAAa,aAAa,QAAQ,EAAE,UAAU,QAAW,MAAM,QAAQ,CAAC;AAAA,IAC7G,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,QAAM,gBAAgB,gBAAgB,WAAW,QAAQ,OAAO,aAAa,QAAQ,OAAO;AAE5F,SACE,qBAAC,SAAI,WAAU,cAEb;AAAA,wBAAC,QACC,+BAAC,SAAI,WAAU,cACb;AAAA,2BAAC,SAAI,WAAU,qDACb;AAAA,4BAAC,QAAG,WAAU,yBAAwB,wBAAU;AAAA,QAC/C,UACC,oBAAC,SAAM,MAAM,gBAAgB,UAAU,SACpC,0BAAgB,WACb,OAAO,OAAO,aACZ,gBAAgB,OAAO,OAAO,UAAU,WAAM,OAAO,OAAO,OAAO,KAAK,EAAE,KAC1E,8BACF,OAAO,OAAO,aACZ,gBAAgB,OAAO,OAAO,UAAU,WAAM,OAAO,OAAO,OAAO,KAAK,EAAE,KAC1E,6BACR;AAAA,SAEJ;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,KAAK,qBAAqB,CAAC;AAAA,UAC5C,SAAS;AAAA,YACP,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,YACnC,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,UACrC;AAAA;AAAA,MACF;AAAA,MAEC,gBAAgB,WACf,qBAAC,SAAI,WAAU,cACb;AAAA,6BAAC,QAAG,WAAU,uDACZ;AAAA,+BAAC,QAAG;AAAA;AAAA,YAA2B,oBAAC,OAAE,WAAU,aAAY,MAAK,yCAAwC,QAAO,UAAS,KAAI,cAAa,wBAAU;AAAA,YAAI;AAAA,aAA6B;AAAA,UACjL,qBAAC,QAAG;AAAA;AAAA,YAAU,oBAAC,QAAG,6CAA0B;AAAA,YAAK;AAAA,aAAW;AAAA,UAC5D,qBAAC,QAAG;AAAA;AAAA,YAAW,oBAAC,QAAG,wCAAqB;AAAA,YAAK;AAAA,aAAiF;AAAA,WAChI;AAAA,QACA,oBAAC,SAAM,OAAM,6DAAkD,MAAK,0DAClE,8BAAC,SAAM,MAAK,YAAW,OAAO,WAAW,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK,GAAG,aAAY,kBAAY,GAClH;AAAA,QACC,QAAQ,OAAO,cAAc,CAAC,OAAO,OAAO,qBAC3C,oBAAC,OAAE,WAAU,2DAA0D,6GAEvE;AAAA,QAEF,oBAAC,SAAI,8BAAC,UAAO,SAAS,aAAa,UAAU,QAAQ,CAAC,UAAU,KAAK,GAAG,2BAAa,GAAS;AAAA,SAChG,IAEA,qBAAC,SAAI,WAAU,cACb;AAAA,6BAAC,QAAG,WAAU,uDACZ;AAAA,+BAAC,QAAG;AAAA;AAAA,YAAoB,oBAAC,OAAE,WAAU,aAAY,MAAK,2CAA0C,QAAO,UAAS,KAAI,cAAa,wBAAU;AAAA,YAAI;AAAA,aAA2B;AAAA,UAC1K,oBAAC,QAAG,sFAAwE;AAAA,UAC5E,qBAAC,QAAG;AAAA;AAAA,YAAc,oBAAC,QAAG,wCAAqB;AAAA,YAAK;AAAA,aAAoG;AAAA,WACtJ;AAAA,QACA,oBAAC,SAAM,OAAM,mDAAwC,MAAK,0DACxD,8BAAC,SAAM,MAAK,YAAW,OAAO,WAAW,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK,GAAG,aAAY,eAAS,GAC/G;AAAA,QACA,oBAAC,SAAI,8BAAC,UAAO,SAAS,aAAa,UAAU,QAAQ,CAAC,UAAU,KAAK,GAAG,2BAAa,GAAS;AAAA,SAChG;AAAA,OAEJ,GACF;AAAA,IAGA,oBAAC,QACC,+BAAC,SAAI,WAAU,cACb;AAAA,2BAAC,SAAI,WAAU,qDACb;AAAA,4BAAC,QAAG,WAAU,yBAAwB,wDAA0C;AAAA,QAC/E,UACC,oBAAC,SAAM,MAAM,OAAO,KAAK,aAAa,UAAU,SAC7C,iBAAO,KAAK,aAAa,GAAG,kBAAkB,YAAY,CAAC,YAAY,sBAC1E;AAAA,SAEJ;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU;AAAA,UACV,SAAS;AAAA,YACP,EAAE,OAAO,QAAQ,OAAO,aAAa;AAAA,YACrC,EAAE,OAAO,UAAU,OAAO,SAAS;AAAA,YACnC,EAAE,OAAO,YAAY,OAAO,WAAW;AAAA,UACzC;AAAA;AAAA,MACF;AAAA,MAEC,iBAAiB,UAChB,qBAAC,SAAI,WAAU,cACb;AAAA,6BAAC,OAAE,WAAU,0BAAyB;AAAA;AAAA,UACmE;AAAA,UACvG,oBAAC,OAAE,WAAU,aAAY,MAAK,6CAA4C,QAAO,UAAS,KAAI,cAAa,4BAAc;AAAA,UAAI;AAAA,WAC/H;AAAA,QACA,qBAAC,SAAI,WAAU,uCACb;AAAA,8BAAC,SAAM,OAAM,eAAc,8BAAC,SAAM,OAAO,KAAK,MAAM,UAAU,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,EAAE,OAAO,MAAM,EAAE,GAAG,aAAY,kBAAiB,GAAE;AAAA,UACtJ,oBAAC,SAAM,OAAM,SAAQ,8BAAC,SAAM,OAAO,KAAK,MAAM,UAAU,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,EAAE,OAAO,MAAM,EAAE,GAAG,aAAY,OAAM,GAAE;AAAA,WACvI;AAAA,QACA,oBAAC,UAAO,SAAS,KAAK,QAAQ,iBAAiB,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,QAAQ,EAAE,EAAE,GAAG,OAAM,+CAA8C;AAAA,QACjJ,qBAAC,SAAI,WAAU,6BACb;AAAA,8BAAC,SAAM,OAAM,kBAAiB,8BAAC,SAAM,OAAO,KAAK,MAAM,UAAU,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,EAAE,OAAO,MAAM,EAAE,GAAG,aAAY,sBAAqB,GAAE;AAAA,UAC7J,oBAAC,SAAM,OAAM,cAAa,MAAM,QAAQ,KAAK,cAAc,6BAA6B,QACtF,8BAAC,SAAM,MAAK,YAAW,OAAO,KAAK,MAAM,UAAU,CAAC,MAAM,QAAQ,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,EAAE,OAAO,MAAM,EAAE,GAAG,GAC9G;AAAA,WACF;AAAA,SACF;AAAA,MAGD,iBAAiB,YAChB,qBAAC,SAAI,WAAU,cACb;AAAA,6BAAC,OAAE,WAAU,0BACX;AAAA,8BAAC,OAAE,WAAU,aAAY,MAAK,sBAAqB,QAAO,UAAS,KAAI,cAAa,oBAAM;AAAA,UAAI;AAAA,WAEhG;AAAA,QACA,oBAAC,SAAM,OAAM,kCAA4B,MAAM,QAAQ,KAAK,eAAe,6BAA6B,QACtG,8BAAC,SAAM,MAAK,YAAW,OAAO,WAAW,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK,GAAG,aAAY,aAAO,GAC7G;AAAA,SACF;AAAA,MAGD,iBAAiB,cAChB,qBAAC,SAAI,WAAU,cACb;AAAA,6BAAC,OAAE,WAAU,0BACX;AAAA,8BAAC,OAAE,WAAU,aAAY,MAAK,2BAA0B,QAAO,UAAS,KAAI,cAAa,sBAAQ;AAAA,UAAI;AAAA,WAEvG;AAAA,QACA,oBAAC,SAAM,OAAM,yBAAwB,MAAM,QAAQ,KAAK,mBAAmB,6BAA6B,QACtG,8BAAC,SAAM,MAAK,YAAW,OAAO,eAAe,UAAU,CAAC,MAAM,iBAAiB,EAAE,OAAO,KAAK,GAAG,aAAY,wBAAkB,GAChI;AAAA,SACF;AAAA,MAIF,qBAAC,SAAI,WAAU,6BACb;AAAA,4BAAC,SAAM,OAAM,gBAAe,8BAAC,SAAM,OAAO,UAAU,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK,GAAG,aAAY,2BAA0B,GAAE;AAAA,QAC1I,oBAAC,SAAM,OAAM,iBAAgB,8BAAC,SAAM,OAAO,WAAW,UAAU,CAAC,MAAM,aAAa,EAAE,OAAO,KAAK,GAAG,aAAY,sBAAqB,GAAE;AAAA,SAC1I;AAAA,MACA,oBAAC,SAAM,OAAM,qBAAoB,MAAK,mFACpC,8BAAC,SAAM,OAAO,UAAU,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK,GAAG,aAAY,8BAA6B,GACjH;AAAA,MAEA,qBAAC,SAAI,WAAU,2BACb;AAAA,4BAAC,UAAO,SAAS,UAAU,UAAU,MAAM,qBAAO;AAAA,QAClD,oBAAC,UAAO,SAAQ,aAAY,SAAS,UAAU,UAAU,QAAQ,CAAC,QAAQ,KAAK,YAAY,4BAAc;AAAA,SAC3G;AAAA,OACF,GACF;AAAA,IAEA,oBAAC,QACC,+BAAC,OAAE,WAAU,0BAAyB;AAAA;AAAA,MAEpC,oBAAC,YAAO,2BAAa;AAAA,MAAS;AAAA,MAA+B,oBAAC,YAAO,qBAAO;AAAA,MAAS;AAAA,OACvF,GACF;AAAA,KACF;AAEJ;AAEA,SAAS,kBAAkB,GAAyB;AAClD,SAAO,MAAM,SAAS,eAAe,MAAM,WAAW,WAAW;AACnE;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/shop/ConnectionsTab.tsx"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Badge, Button, Card, Field, Input } from \"../ui/primitives\";\nimport { useToast } from \"../ui/toast\";\nimport { shopCallable } from \"./lib\";\n\ntype PayProvider = \"stripe\" | \"mollie\";\n\ninterface ShopStatus {\n provider: PayProvider;\n stripe: { configured: boolean; account?: string; webhookConfigured: boolean };\n mollie: { configured: boolean; profile?: string };\n}\n\n/** Segmented control voor providerkeuze. */\nfunction Segmented<T extends string>({\n value,\n options,\n onChange,\n}: {\n value: T;\n options: { value: T; label: string }[];\n onChange: (v: T) => void;\n}) {\n return (\n <div className=\"inline-flex rounded-lg border border-slate-200 bg-slate-50 p-0.5\">\n {options.map((o) => (\n <button\n key={o.value}\n type=\"button\"\n onClick={() => onChange(o.value)}\n className={`rounded-md px-3 py-1.5 text-sm font-medium transition ${\n value === o.value ? \"bg-white text-brand-700 shadow-sm\" : \"text-slate-500 hover:text-slate-700\"\n }`}\n >\n {o.label}\n </button>\n ))}\n </div>\n );\n}\n\n/**\n * Koppelingen — betaalprovider (Stripe of Mollie) voor de shop. Geheimen gaan uitsluitend via\n * callables naar `sites/{siteId}/private/*` (deny-all rules); dit paneel toont alleen gemaskeerde\n * status. Alleen een siteadmin kan opslaan.\n *\n * NB: de mailprovider (Resend/Postmark/SMTP) is een SITE-BREDE instelling — die staat niet meer\n * hier maar onder Instellingen → E-mail (zie docs/SHARED-SETTINGS.md), zodat ook sites zónder shop\n * hun formulier-mail kunnen instellen.\n */\nexport function ConnectionsTab({ siteId }: { siteId: string }) {\n const { toast } = useToast();\n const [status, setStatus] = useState<ShopStatus | null>(null);\n const [busy, setBusy] = useState(false);\n\n // Betaling\n const [payProvider, setPayProvider] = useState<PayProvider>(\"stripe\");\n const [stripeKey, setStripeKey] = useState(\"\");\n const [mollieKey, setMollieKey] = useState(\"\");\n\n const refresh = useCallback(async () => {\n try {\n const raw = await shopCallable<{ siteId: string }, Partial<ShopStatus>>(\"getShopStatus\")({ siteId });\n // Normaliseer naar de volledige vorm zodat de render nooit op een ontbrekend deel-object\n // (bv. een oudere functions-versie zonder mollie) kan crashen.\n const s: ShopStatus = {\n provider: raw.provider ?? \"stripe\",\n stripe: raw.stripe ?? { configured: false, webhookConfigured: false },\n mollie: raw.mollie ?? { configured: false },\n };\n setStatus(s);\n setPayProvider(s.provider ?? \"stripe\");\n } catch {\n setStatus(null);\n }\n }, [siteId]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n async function savePayment() {\n setBusy(true);\n try {\n const payload: Record<string, unknown> = { siteId, provider: payProvider };\n if (payProvider === \"stripe\") {\n if (!stripeKey.trim().startsWith(\"sk_\") && !stripeKey.trim().startsWith(\"rk_\")) {\n toast({ title: \"Ongeldige sleutel\", description: \"Plak een Stripe geheime sleutel (sk_…) of restricted key (rk_…).\", tone: \"error\" });\n setBusy(false);\n return;\n }\n payload.stripe = { secretKey: stripeKey.trim() };\n } else {\n if (!/^(test|live)_/.test(mollieKey.trim())) {\n toast({ title: \"Ongeldige sleutel\", description: \"Plak een Mollie API-sleutel (test_… of live_…).\", tone: \"error\" });\n setBusy(false);\n return;\n }\n payload.mollie = { apiKey: mollieKey.trim() };\n }\n const res = await shopCallable<Record<string, unknown>, { account?: string }>(\"saveShopSecrets\")(payload);\n toast({ title: `${payProvider === \"stripe\" ? \"Stripe\" : \"Mollie\"} gekoppeld`, description: res.account ? `Account: ${res.account}` : undefined, tone: \"success\" });\n setStripeKey(\"\");\n setMollieKey(\"\");\n await refresh();\n } catch (e) {\n toast({ title: \"Koppelen mislukt\", description: e instanceof Error ? e.message : undefined, tone: \"error\" });\n } finally {\n setBusy(false);\n }\n }\n\n async function switchActiveProvider(p: PayProvider) {\n setPayProvider(p);\n // Alleen de actieve provider wisselen als de andere al geconfigureerd is (anders vraagt het formulier eerst een sleutel).\n const otherConfigured = p === \"stripe\" ? status?.stripe.configured : status?.mollie.configured;\n if (otherConfigured) {\n try {\n await shopCallable<{ siteId: string; provider: PayProvider }, unknown>(\"saveShopSecrets\")({ siteId, provider: p });\n await refresh();\n } catch {\n /* stil — de gebruiker kan alsnog opslaan */\n }\n }\n }\n\n const payConfigured = payProvider === \"stripe\" ? status?.stripe.configured : status?.mollie.configured;\n\n return (\n <div className=\"grid gap-4\">\n {/* ── Betalingen ─────────────────────────────────────────────── */}\n <Card>\n <div className=\"grid gap-4\">\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h3 className=\"text-sm font-semibold\">Betalingen</h3>\n {status && (\n <Badge tone={payConfigured ? \"green\" : \"amber\"}>\n {payProvider === \"stripe\"\n ? status.stripe.configured\n ? `Stripe actief${status.stripe.account ? ` — ${status.stripe.account}` : \"\"}`\n : \"Stripe nog niet gekoppeld\"\n : status.mollie.configured\n ? `Mollie actief${status.mollie.profile ? ` — ${status.mollie.profile}` : \"\"}`\n : \"Mollie nog niet gekoppeld\"}\n </Badge>\n )}\n </div>\n\n <Segmented\n value={payProvider}\n onChange={(v) => void switchActiveProvider(v)}\n options={[\n { value: \"stripe\", label: \"Stripe\" },\n { value: \"mollie\", label: \"Mollie\" },\n ]}\n />\n\n {payProvider === \"stripe\" ? (\n <div className=\"grid gap-3\">\n <ol className=\"grid list-decimal gap-1 pl-5 text-sm text-slate-600\">\n <li>Maak een gratis account op <a className=\"underline\" href=\"https://dashboard.stripe.com/register\" target=\"_blank\" rel=\"noreferrer\">stripe.com</a> en activeer het (IBAN, KVK).</li>\n <li>Zet onder <em>Settings → Payment methods</em> iDEAL aan.</li>\n <li>Maak onder <em>Developers → API keys</em> een sleutel aan en plak hem hieronder — de webhook wordt automatisch aangemaakt.</li>\n </ol>\n <Field label=\"Stripe geheime sleutel (sk_live_… of rk_live_…)\" hint=\"Wordt veilig opgeslagen; nooit zichtbaar in de browser\">\n <Input type=\"password\" value={stripeKey} onChange={(e) => setStripeKey(e.target.value)} placeholder=\"sk_live_…\" />\n </Field>\n {status?.stripe.configured && !status.stripe.webhookConfigured && (\n <p className=\"rounded-lg bg-amber-50 px-3 py-2 text-sm text-amber-700\">\n Webhook nog niet geregistreerd — koppel opnieuw met een sleutel die webhook-rechten heeft.\n </p>\n )}\n <div><Button onClick={savePayment} disabled={busy || !stripeKey.trim()}>Koppel Stripe</Button></div>\n </div>\n ) : (\n <div className=\"grid gap-3\">\n <ol className=\"grid list-decimal gap-1 pl-5 text-sm text-slate-600\">\n <li>Maak een account op <a className=\"underline\" href=\"https://www.mollie.com/dashboard/signup\" target=\"_blank\" rel=\"noreferrer\">mollie.com</a> en doorloop de onboarding.</li>\n <li>Zet in het Mollie-dashboard de gewenste betaalmethoden (o.a. iDEAL) aan.</li>\n <li>Kopieer onder <em>Developers → API-keys</em> je live- of test-sleutel en plak hem hieronder. Mollie heeft geen aparte webhook-registratie nodig.</li>\n </ol>\n <Field label=\"Mollie API-sleutel (live_… of test_…)\" hint=\"Wordt veilig opgeslagen; nooit zichtbaar in de browser\">\n <Input type=\"password\" value={mollieKey} onChange={(e) => setMollieKey(e.target.value)} placeholder=\"live_…\" />\n </Field>\n <div><Button onClick={savePayment} disabled={busy || !mollieKey.trim()}>Koppel Mollie</Button></div>\n </div>\n )}\n </div>\n </Card>\n\n <Card>\n <p className=\"text-sm text-slate-600\">\n De <strong>e-mailprovider</strong> (bestelbevestigingen én formulieren) stel je site-breed in\n onder <strong>Instellingen → E-mail</strong>. Verzendkosten, valuta, ordernummer-prefix en\n bedrijfsgegevens (factuur) staan onder het tabblad <strong>Instellingen</strong>; mailteksten\n onder <strong>E-mails</strong>.\n </p>\n </Card>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Webwinkel-beheer: bestellingen, producten, categorieën, kortingscodes, e-mailtemplates,
|
|
3
|
-
* winkel-instellingen en koppelingen (Stripe/
|
|
3
|
+
* winkel-instellingen en koppelingen (betaalprovider Stripe/Mollie). De mailprovider is
|
|
4
|
+
* site-breed en staat onder Instellingen → E-mail (zie docs/SHARED-SETTINGS.md).
|
|
4
5
|
*/
|
|
5
6
|
export declare function ShopPanel({ siteId }: {
|
|
6
7
|
siteId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/shop/ShopPanel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../ui/tabs\";\nimport { ProductsTab } from \"./ProductsTab\";\nimport { CategoriesTab } from \"./CategoriesTab\";\nimport { OrdersTab } from \"./OrdersTab\";\nimport { DiscountsTab } from \"./DiscountsTab\";\nimport { EmailsTab } from \"./EmailsTab\";\nimport { ShopSettingsTab } from \"./ShopSettingsTab\";\nimport { ConnectionsTab } from \"./ConnectionsTab\";\n\n/**\n * Webwinkel-beheer: bestellingen, producten, categorieën, kortingscodes, e-mailtemplates,\n * winkel-instellingen en koppelingen (Stripe/
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/shop/ShopPanel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"../ui/tabs\";\nimport { ProductsTab } from \"./ProductsTab\";\nimport { CategoriesTab } from \"./CategoriesTab\";\nimport { OrdersTab } from \"./OrdersTab\";\nimport { DiscountsTab } from \"./DiscountsTab\";\nimport { EmailsTab } from \"./EmailsTab\";\nimport { ShopSettingsTab } from \"./ShopSettingsTab\";\nimport { ConnectionsTab } from \"./ConnectionsTab\";\n\n/**\n * Webwinkel-beheer: bestellingen, producten, categorieën, kortingscodes, e-mailtemplates,\n * winkel-instellingen en koppelingen (betaalprovider Stripe/Mollie). De mailprovider is\n * site-breed en staat onder Instellingen → E-mail (zie docs/SHARED-SETTINGS.md).\n */\nexport function ShopPanel({ siteId }: { siteId: string }) {\n return (\n <Tabs defaultValue=\"orders\">\n <TabsList>\n <TabsTrigger value=\"orders\">Bestellingen</TabsTrigger>\n <TabsTrigger value=\"products\">Producten</TabsTrigger>\n <TabsTrigger value=\"categories\">Categorieën</TabsTrigger>\n <TabsTrigger value=\"discounts\">Kortingen</TabsTrigger>\n <TabsTrigger value=\"emails\">E-mails</TabsTrigger>\n <TabsTrigger value=\"settings\">Instellingen</TabsTrigger>\n <TabsTrigger value=\"connections\">Koppelingen</TabsTrigger>\n </TabsList>\n <TabsContent value=\"orders\">\n <OrdersTab siteId={siteId} />\n </TabsContent>\n <TabsContent value=\"products\">\n <ProductsTab siteId={siteId} />\n </TabsContent>\n <TabsContent value=\"categories\">\n <CategoriesTab siteId={siteId} />\n </TabsContent>\n <TabsContent value=\"discounts\">\n <DiscountsTab siteId={siteId} />\n </TabsContent>\n <TabsContent value=\"emails\">\n <EmailsTab siteId={siteId} />\n </TabsContent>\n <TabsContent value=\"settings\">\n <ShopSettingsTab siteId={siteId} />\n </TabsContent>\n <TabsContent value=\"connections\">\n <ConnectionsTab siteId={siteId} />\n </TabsContent>\n </Tabs>\n );\n}\n"],"mappings":";AAmBM,SACE,KADF;AAjBN,SAAS,MAAM,aAAa,UAAU,mBAAmB;AACzD,SAAS,mBAAmB;AAC5B,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAC1B,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,uBAAuB;AAChC,SAAS,sBAAsB;AAOxB,SAAS,UAAU,EAAE,OAAO,GAAuB;AACxD,SACE,qBAAC,QAAK,cAAa,UACjB;AAAA,yBAAC,YACC;AAAA,0BAAC,eAAY,OAAM,UAAS,0BAAY;AAAA,MACxC,oBAAC,eAAY,OAAM,YAAW,uBAAS;AAAA,MACvC,oBAAC,eAAY,OAAM,cAAa,4BAAW;AAAA,MAC3C,oBAAC,eAAY,OAAM,aAAY,uBAAS;AAAA,MACxC,oBAAC,eAAY,OAAM,UAAS,qBAAO;AAAA,MACnC,oBAAC,eAAY,OAAM,YAAW,0BAAY;AAAA,MAC1C,oBAAC,eAAY,OAAM,eAAc,yBAAW;AAAA,OAC9C;AAAA,IACA,oBAAC,eAAY,OAAM,UACjB,8BAAC,aAAU,QAAgB,GAC7B;AAAA,IACA,oBAAC,eAAY,OAAM,YACjB,8BAAC,eAAY,QAAgB,GAC/B;AAAA,IACA,oBAAC,eAAY,OAAM,cACjB,8BAAC,iBAAc,QAAgB,GACjC;AAAA,IACA,oBAAC,eAAY,OAAM,aACjB,8BAAC,gBAAa,QAAgB,GAChC;AAAA,IACA,oBAAC,eAAY,OAAM,UACjB,8BAAC,aAAU,QAAgB,GAC7B;AAAA,IACA,oBAAC,eAAY,OAAM,YACjB,8BAAC,mBAAgB,QAAgB,GACnC;AAAA,IACA,oBAAC,eAAY,OAAM,eACjB,8BAAC,kBAAe,QAAgB,GAClC;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in shop-adminpaneel (6.0), subpath `@xiwebdesign/xicms-core/admin/shop`.
|
|
3
|
+
* Geef `shopPanel` mee aan `AdminApp extraPanels={[shopPanel]}` op sites met shop
|
|
4
|
+
* (of gebruik de gegenereerde `enabledPanels`, zie docs/MODULES.md).
|
|
5
|
+
*/
|
|
6
|
+
import type { PanelDefinition } from "../panelRegistry";
|
|
7
|
+
export { ShopPanel } from "./ShopPanel";
|
|
8
|
+
/** Paneldefinitie zoals die vroeger in builtinPanels stond (order 45, "Webwinkel"). */
|
|
9
|
+
export declare const shopPanel: PanelDefinition;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ShopPanel } from "./ShopPanel";
|
|
2
|
+
import { ShopPanel as ShopPanel2 } from "./ShopPanel";
|
|
3
|
+
const shopPanel = {
|
|
4
|
+
moduleId: "shop",
|
|
5
|
+
label: "Webwinkel",
|
|
6
|
+
order: 45,
|
|
7
|
+
minRole: "editor",
|
|
8
|
+
Panel: ShopPanel
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
ShopPanel2 as ShopPanel,
|
|
12
|
+
shopPanel
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/shop/index.ts"],"sourcesContent":["/**\n * Opt-in shop-adminpaneel (6.0), subpath `@xiwebdesign/xicms-core/admin/shop`.\n * Geef `shopPanel` mee aan `AdminApp extraPanels={[shopPanel]}` op sites met shop\n * (of gebruik de gegenereerde `enabledPanels`, zie docs/MODULES.md).\n */\nimport type { PanelDefinition } from \"../panelRegistry\";\nimport { ShopPanel } from \"./ShopPanel\";\n\nexport { ShopPanel } from \"./ShopPanel\";\n\n/** Paneldefinitie zoals die vroeger in builtinPanels stond (order 45, \"Webwinkel\"). */\nexport const shopPanel: PanelDefinition = {\n moduleId: \"shop\",\n label: \"Webwinkel\",\n order: 45,\n minRole: \"editor\",\n Panel: ShopPanel,\n};\n"],"mappings":"AAMA,SAAS,iBAAiB;AAE1B,SAAS,aAAAA,kBAAiB;AAGnB,MAAM,YAA6B;AAAA,EACxC,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AACT;","names":["ShopPanel"]}
|
package/dist/all.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Alle modules incl. shop (5.x-gedrag). */
|
|
2
|
+
export declare const allModules: import("./modules").ModuleDefinition[];
|
|
3
|
+
/** Alle admin-panelen incl. het shop-paneel (5.x-gedrag). */
|
|
4
|
+
export declare const allPanels: import("./admin").PanelDefinition[];
|
|
5
|
+
export { shopModule } from "./modules/shop";
|
|
6
|
+
export { shopPanel } from "./admin/shop";
|
package/dist/all.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { builtinModules } from "./modules/builtins";
|
|
2
|
+
import { shopModule } from "./modules/shop";
|
|
3
|
+
import { builtinPanels } from "./admin/panelRegistry";
|
|
4
|
+
import { shopPanel } from "./admin/shop";
|
|
5
|
+
const allModules = [...builtinModules, shopModule];
|
|
6
|
+
const allPanels = [...builtinPanels, shopPanel];
|
|
7
|
+
import { shopModule as shopModule2 } from "./modules/shop";
|
|
8
|
+
import { shopPanel as shopPanel2 } from "./admin/shop";
|
|
9
|
+
export {
|
|
10
|
+
allModules,
|
|
11
|
+
allPanels,
|
|
12
|
+
shopModule2 as shopModule,
|
|
13
|
+
shopPanel2 as shopPanel
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=all.js.map
|
package/dist/all.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/all.ts"],"sourcesContent":["/**\n * Backward-compat-barrel (6.0), subpath `@xiwebdesign/xicms-core/all`.\n *\n * Sinds 6.0 zit de shop-module NIET meer in de default-bundel (tree-shaking per site).\n * Deze barrel her-exporteert het oude \"alle modules\"-gedrag: een site importeert `allModules`\n * en `allPanels` uit de `/all`-subpath en gedraagt zich als 5.x (shop meegebundeld), zodat een\n * bump naar 6.0 niets breekt. Migreren naar de slanke, per-site opt-in (via de gegenereerde\n * `enabledModules`/`enabledPanels`) kan daarna op je gemak — zie docs/MODULES.md voor het\n * gebruik in `SiteProviders`/`AdminApp`.\n */\nimport { builtinModules } from \"./modules/builtins\";\nimport { shopModule } from \"./modules/shop\";\nimport { builtinPanels } from \"./admin/panelRegistry\";\nimport { shopPanel } from \"./admin/shop\";\n\n/** Alle modules incl. shop (5.x-gedrag). */\nexport const allModules = [...builtinModules, shopModule];\n/** Alle admin-panelen incl. het shop-paneel (5.x-gedrag). */\nexport const allPanels = [...builtinPanels, shopPanel];\n\nexport { shopModule } from \"./modules/shop\";\nexport { shopPanel } from \"./admin/shop\";\n"],"mappings":"AAUA,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAGnB,MAAM,aAAa,CAAC,GAAG,gBAAgB,UAAU;AAEjD,MAAM,YAAY,CAAC,GAAG,eAAe,SAAS;AAErD,SAAS,cAAAA,mBAAkB;AAC3B,SAAS,aAAAC,kBAAiB;","names":["shopModule","shopPanel"]}
|
|
@@ -41,7 +41,6 @@ export declare const beforeAfterModule: ModuleDefinition;
|
|
|
41
41
|
export declare const portfolioModule: ModuleDefinition;
|
|
42
42
|
export declare const jobsModule: ModuleDefinition;
|
|
43
43
|
export declare const breadcrumbsModule: ModuleDefinition;
|
|
44
|
-
export { shopModule } from "./shop/module";
|
|
45
44
|
export declare const consentModule: ModuleDefinition;
|
|
46
45
|
/** Alle ingebouwde modules (volgorde bepaalt block- en tab-volgorde). */
|
|
47
46
|
export declare const builtinModules: ModuleDefinition[];
|
package/dist/modules/builtins.js
CHANGED
|
@@ -353,8 +353,6 @@ const breadcrumbsModule = defineModule({
|
|
|
353
353
|
defaultEnabled: false,
|
|
354
354
|
blocks: [breadcrumbsBlock]
|
|
355
355
|
});
|
|
356
|
-
import { shopModule } from "./shop/module";
|
|
357
|
-
import { shopModule as shopModule2 } from "./shop/module";
|
|
358
356
|
const consentModule = defineModule({
|
|
359
357
|
id: "consent",
|
|
360
358
|
version: CORE_VERSION,
|
|
@@ -419,7 +417,6 @@ const builtinModules = [
|
|
|
419
417
|
portfolioModule,
|
|
420
418
|
jobsModule,
|
|
421
419
|
breadcrumbsModule,
|
|
422
|
-
shopModule2,
|
|
423
420
|
consentModule
|
|
424
421
|
];
|
|
425
422
|
export {
|
|
@@ -454,7 +451,6 @@ export {
|
|
|
454
451
|
pricingModule,
|
|
455
452
|
searchModule,
|
|
456
453
|
settingsModule,
|
|
457
|
-
shopModule,
|
|
458
454
|
sliderModule,
|
|
459
455
|
statsModule,
|
|
460
456
|
tabsModule,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/modules/builtins.ts"],"sourcesContent":["/**\n * Ingebouwde modules (XiCMS 3.0). Elke \"feature\" van 2.x is hier een first-class module geworden,\n * zodat hij per site aan/uit kan en los te verbeteren is. De bijbehorende admin-panelen staan in\n * `@xiwebdesign/xicms-core/admin` (paneel-registry), gekoppeld via dezelfde `id`/`featureKey`.\n *\n * Backward compatible: zonder `SiteConfig.modules`/`features` zijn alle modules actief — identiek\n * aan 2.x. De `content`-module is `core: true` en kan niet uitgezet worden (de basis-bouwstenen).\n */\nimport { z } from \"zod\";\nimport { defineModule } from \"./defineModule\";\nimport type { ModuleDefinition } from \"./types\";\n\nimport { heroBlock } from \"../blocks/builtins/Hero\";\nimport { richTextBlock } from \"../blocks/builtins/RichTextBlock\";\nimport { imageBlock } from \"../blocks/builtins/ImageBlock\";\nimport { ctaBlock } from \"../blocks/builtins/Cta\";\nimport { columnsBlock } from \"../blocks/builtins/Columns\";\nimport { spacerBlock } from \"../blocks/builtins/Spacer\";\nimport { galleryBlock } from \"../blocks/builtins/Gallery\";\nimport { faqBlock } from \"../blocks/builtins/Faq\";\nimport { openingHoursBlock } from \"../blocks/builtins/OpeningHours\";\nimport { pricingBlock } from \"../blocks/builtins/Pricing\";\nimport { newsListBlock } from \"../blocks/builtins/NewsListBlock\";\nimport { formBlock } from \"../blocks/builtins/FormBlock\";\nimport { testimonialsBlock } from \"../blocks/builtins/Testimonials\";\nimport { teamBlock } from \"../blocks/builtins/Team\";\nimport { agendaBlock } from \"../blocks/builtins/Agenda\";\nimport { searchBlock } from \"../blocks/builtins/Search\";\nimport { featureBlock, countersBlock, logosBlock, timelineBlock } from \"../blocks/builtins/Sections\";\nimport { symbolRefBlock } from \"../blocks/builtins/SymbolRef\";\nimport { videoBlock } from \"../blocks/builtins/Video\";\nimport { bannerBlock } from \"../blocks/builtins/Banner\";\nimport { contactBlock, socialBlock } from \"../blocks/builtins/Contact\";\nimport { mapBlock } from \"../blocks/builtins/MapBlock\";\nimport { newsletterBlock } from \"../blocks/builtins/Newsletter\";\nimport { bookingBlock } from \"../blocks/builtins/Booking\";\nimport { buttonsBlock, quoteBlock, dividerBlock } from \"../blocks/builtins/Elements\";\nimport { accordionBlock } from \"../blocks/builtins/Accordion\";\nimport { embedBlock } from \"../blocks/builtins/Embed\";\nimport { withSidebarBlock, tabsBlock } from \"../blocks/builtins/Layout\";\nimport { cardsBlock } from \"../blocks/builtins/Cards\";\nimport { downloadsBlock } from \"../blocks/builtins/Downloads\";\nimport { pdfBlock } from \"../blocks/builtins/PdfBlock\";\nimport { countdownBlock } from \"../blocks/builtins/Countdown\";\nimport { sliderBlock } from \"../blocks/builtins/Slider\";\nimport { whatsappChatBlock } from \"../blocks/builtins/WhatsappChat\";\nimport { beforeAfterBlock } from \"../blocks/builtins/BeforeAfter\";\nimport { portfolioBlock } from \"../blocks/builtins/Portfolio\";\nimport { jobsBlock } from \"../blocks/builtins/Jobs\";\nimport { breadcrumbsBlock } from \"../blocks/builtins/Breadcrumbs\";\nimport {\n newsWidget,\n agendaWidget,\n openingHoursWidget,\n contactWidget,\n socialWidget as socialWidgetBlock,\n newsletterWidget,\n ctaWidget,\n galleryWidget,\n testimonialsWidget,\n cardsWidget,\n downloadsWidget,\n countdownWidget,\n} from \"../blocks/builtins/Widgets\";\n\nconst CORE_VERSION = \"5.0.0\";\n\n/**\n * Basis-bouwstenen — altijd aanwezig (niet uit te zetten). Bevat ook de indelingsblokken\n * (kolommen, \"Met zijbalk\") waarmee je widgets naast je hoofdinhoud plaatst, plus de\n * compacte CTA-widget.\n */\nexport const contentModule = defineModule({\n id: \"content\",\n version: CORE_VERSION,\n label: \"Basisinhoud\",\n description: \"Kern-bouwstenen: hero, tekst, afbeelding, CTA, kolommen, zijbalk, witruimte.\",\n core: true,\n blocks: [heroBlock, richTextBlock, imageBlock, ctaBlock, columnsBlock, withSidebarBlock, spacerBlock, buttonsBlock, quoteBlock, dividerBlock, ctaWidget, symbolRefBlock],\n});\n\nexport const galleryModule = defineModule({\n id: \"gallery\",\n version: CORE_VERSION,\n label: \"Fotogalerij\",\n description: \"Galerij-block met grid en (optioneel) lightbox + compacte fotostrip-widget.\",\n blocks: [galleryBlock, galleryWidget],\n // Per-site instelbaar door de agent/klant (modules.gallery.config) zonder core te forken.\n // `.describe()` = het label dat de klant in /beheer ziet.\n settingsSchema: z.object({\n columns: z.number().int().min(1).max(6).default(3).describe(\"Kolommen\"),\n lightbox: z.boolean().default(true).describe(\"Lightbox bij klikken\"),\n }),\n defaultSettings: { columns: 3, lightbox: true },\n});\n\nexport const faqModule = defineModule({\n id: \"faq\",\n version: CORE_VERSION,\n label: \"FAQ\",\n description: \"Veelgestelde vragen (accordeon) met optionele zoek + FAQ-JSON-LD.\",\n blocks: [faqBlock],\n});\n\nexport const openingHoursModule = defineModule({\n id: \"openingHours\",\n version: CORE_VERSION,\n label: \"Openingstijden\",\n description: \"Openingstijden-tabel + compacte widget met 'vandaag' gemarkeerd.\",\n blocks: [openingHoursBlock, openingHoursWidget],\n});\n\nexport const pricingModule = defineModule({\n id: \"pricing\",\n version: CORE_VERSION,\n label: \"Prijzen\",\n blocks: [pricingBlock],\n});\n\nexport const pagesModule = defineModule({\n id: \"pages\",\n version: CORE_VERSION,\n label: \"Pagina's\",\n featureKey: \"pages\",\n description: \"Paginabouwer (draft → publish + versiegeschiedenis).\",\n});\n\nexport const newsModule = defineModule({\n id: \"news\",\n version: CORE_VERSION,\n label: \"Nieuws\",\n featureKey: \"news\",\n description: \"Nieuwsartikelen + nieuwslijst-block + 'laatste nieuws'-widget voor de zijbalk.\",\n blocks: [newsListBlock, newsWidget],\n});\n\nexport const mediaModule = defineModule({\n id: \"media\",\n version: CORE_VERSION,\n label: \"Media\",\n featureKey: \"media\",\n description: \"Mediabeheer met compressie + webp/srcset-varianten.\",\n requires: [{ kind: \"function\", name: \"onMediaUpload\" }, { kind: \"storage\", prefix: \"sites/\" }],\n});\n\nexport const formsModule = defineModule({\n id: \"forms\",\n version: CORE_VERSION,\n label: \"Formulieren\",\n featureKey: \"forms\",\n description: \"Formulierbouwer + inzendingen + e-mailnotificatie.\",\n blocks: [formBlock],\n requires: [\n { kind: \"function\", name: \"submitForm\" },\n { kind: \"firestore\", collection: \"forms\" },\n ],\n});\n\nexport const statsModule = defineModule({\n id: \"stats\",\n version: CORE_VERSION,\n label: \"Statistieken\",\n featureKey: \"stats\",\n description: \"Privacy-vriendelijke bezoekersstatistieken (geen cookies).\",\n requires: [{ kind: \"function\", name: \"trackView\" }],\n});\n\nexport const settingsModule = defineModule({\n id: \"settings\",\n version: CORE_VERSION,\n label: \"Instellingen\",\n core: true,\n description: \"Site-instellingen (nav, thema, SEO, formulier-afzender) — alleen siteadmin.\",\n});\n\n// Opt-in modules (defaultEnabled: false): worden bij installatie of later aangezet via\n// `modules: { <id>: true }`. Geen extra backend nodig — data leeft in de page-blocks.\nexport const testimonialsModule = defineModule({\n id: \"testimonials\",\n version: CORE_VERSION,\n label: \"Reviews\",\n description: \"Klantquotes/reviews met sterren, optionele Review-JSON-LD + compacte review-widget.\",\n defaultEnabled: false,\n blocks: [testimonialsBlock, testimonialsWidget],\n});\n\nexport const teamModule = defineModule({\n id: \"team\",\n version: CORE_VERSION,\n label: \"Team\",\n description: \"Team-/medewerkersoverzicht met foto, functie en bio.\",\n defaultEnabled: false,\n blocks: [teamBlock],\n});\n\nexport const agendaModule = defineModule({\n id: \"agenda\",\n version: CORE_VERSION,\n label: \"Agenda\",\n description: \"Evenementen/agenda (chronologisch) met Event-JSON-LD + 'komende agenda'-widget.\",\n defaultEnabled: false,\n blocks: [agendaBlock, agendaWidget],\n});\n\nexport const searchModule = defineModule({\n id: \"search\",\n version: CORE_VERSION,\n label: \"Zoeken\",\n description: \"Site-zoekblok dat gepubliceerde pagina's (en nieuws) client-side doorzoekt.\",\n defaultEnabled: false,\n blocks: [searchBlock],\n});\n\nexport const featureModule = defineModule({\n id: \"feature\",\n version: CORE_VERSION,\n label: \"Beeld + tekst\",\n description: \"Feature-sectie met afbeelding links/rechts en tekst.\",\n defaultEnabled: false,\n blocks: [featureBlock],\n});\n\nexport const countersModule = defineModule({\n id: \"counters\",\n version: CORE_VERSION,\n label: \"Tellers\",\n description: \"Statistiek-tellers (bv. “100+ klanten”).\",\n defaultEnabled: false,\n blocks: [countersBlock],\n});\n\nexport const logosModule = defineModule({\n id: \"logos\",\n version: CORE_VERSION,\n label: \"Logo's\",\n description: \"Partner-/klantlogo-strip.\",\n defaultEnabled: false,\n blocks: [logosBlock],\n});\n\nexport const timelineModule = defineModule({\n id: \"timeline\",\n version: CORE_VERSION,\n label: \"Tijdlijn\",\n description: \"Stappen/proces als tijdlijn.\",\n defaultEnabled: false,\n blocks: [timelineBlock],\n});\n\nexport const videoModule = defineModule({\n id: \"video\",\n version: CORE_VERSION,\n label: \"Video\",\n description: \"YouTube/Vimeo/MP4-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [videoBlock],\n});\n\nexport const bannerModule = defineModule({\n id: \"banner\",\n version: CORE_VERSION,\n label: \"Aankondiging\",\n description: \"Aankondigingsbalk, optioneel sluitbaar.\",\n defaultEnabled: false,\n blocks: [bannerBlock],\n});\n\nexport const contactModule = defineModule({\n id: \"contact\",\n version: CORE_VERSION,\n label: \"Contact + kaart + social\",\n description: \"Contactgegevens (JSON-LD), kaart (consent-gated), social-links + compacte widgets.\",\n defaultEnabled: false,\n blocks: [contactBlock, mapBlock, socialBlock, contactWidget, socialWidgetBlock],\n});\n\nexport const newsletterModule = defineModule({\n id: \"newsletter\",\n version: CORE_VERSION,\n label: \"Nieuwsbrief\",\n description: \"Aanmeldformulier via een externe provider-URL + compacte nieuwsbrief-widget.\",\n defaultEnabled: false,\n blocks: [newsletterBlock, newsletterWidget],\n});\n\nexport const bookingModule = defineModule({\n id: \"booking\",\n version: CORE_VERSION,\n label: \"Afspraak/booking\",\n description: \"Boekings-embed (bv. Calendly), consent-gated.\",\n defaultEnabled: false,\n blocks: [bookingBlock],\n});\n\nexport const accordionModule = defineModule({\n id: \"accordion\",\n version: CORE_VERSION,\n label: \"Accordeon\",\n description: \"Generieke in-/uitklapbare panelen.\",\n defaultEnabled: false,\n blocks: [accordionBlock],\n});\n\nexport const embedModule = defineModule({\n id: \"embed\",\n version: CORE_VERSION,\n label: \"Embed\",\n description: \"Generieke responsive iframe-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [embedBlock],\n});\n\n/* ── Nieuwe modules (3.1) — veelgebruikt op websites, volwaardig + widget waar zinvol ── */\n\nexport const cardsModule = defineModule({\n id: \"cards\",\n version: CORE_VERSION,\n label: \"Diensten / kaarten\",\n description: \"Diensten-/featurekaarten in een grid (icoon of beeld) + compacte 'uitgelicht'-widget.\",\n defaultEnabled: false,\n blocks: [cardsBlock, cardsWidget],\n});\n\nexport const tabsModule = defineModule({\n id: \"tabs\",\n version: CORE_VERSION,\n label: \"Tabbladen\",\n description: \"Tabblad-indeling: per tab een eigen set blokken (bv. beschrijving / specificaties).\",\n defaultEnabled: false,\n blocks: [tabsBlock],\n});\n\nexport const downloadsModule = defineModule({\n id: \"downloads\",\n version: CORE_VERSION,\n label: \"Downloads\",\n description: \"Lijst met downloadbare documenten (brochures, prijslijsten) + compacte widget.\",\n defaultEnabled: false,\n blocks: [downloadsBlock, downloadsWidget],\n});\n\nexport const pdfModule = defineModule({\n id: \"pdf\",\n version: CORE_VERSION,\n label: \"PDF-lezer\",\n description: \"Inline PDF-lezer voor menukaarten/documenten; meerdere PDF's met tabs, zelf te vervangen.\",\n defaultEnabled: false,\n blocks: [pdfBlock],\n});\n\nexport const countdownModule = defineModule({\n id: \"countdown\",\n version: CORE_VERSION,\n label: \"Aftelteller\",\n description: \"Tikkende countdown naar een datum (lancering, evenement, aanbieding) + widget.\",\n defaultEnabled: false,\n blocks: [countdownBlock, countdownWidget],\n});\n\nexport const sliderModule = defineModule({\n id: \"slider\",\n version: CORE_VERSION,\n label: \"Carrousel / slider\",\n description: \"Beeld-/contentcarrousel met dots, pijlen en optioneel autoplay (reduced-motion-veilig).\",\n defaultEnabled: false,\n blocks: [sliderBlock],\n});\n\n/* ── 4.16: nieuwe modules (allemaal opt-in) ──────────────────────────────── */\n\nexport const whatsappModule = defineModule({\n id: \"whatsapp\",\n version: CORE_VERSION,\n label: \"WhatsApp-knop\",\n description: \"Zwevende WhatsApp-/chatknop — laagdrempelig contact (wa.me-link, geen consent nodig).\",\n defaultEnabled: false,\n blocks: [whatsappChatBlock],\n});\n\nexport const beforeAfterModule = defineModule({\n id: \"beforeAfter\",\n version: CORE_VERSION,\n label: \"Voor / na\",\n description: \"Voor/na-vergelijker met sleepbare scheiding — sterk voor hoveniers, schilders, salons.\",\n defaultEnabled: false,\n blocks: [beforeAfterBlock],\n});\n\nexport const portfolioModule = defineModule({\n id: \"portfolio\",\n version: CORE_VERSION,\n label: \"Portfolio / projecten\",\n description: \"Projecten/cases-grid met categorie-filter en lightbox.\",\n defaultEnabled: false,\n blocks: [portfolioBlock],\n});\n\nexport const jobsModule = defineModule({\n id: \"jobs\",\n version: CORE_VERSION,\n label: \"Vacatures\",\n description: \"Vacature-overzicht met JobPosting-JSON-LD (vindbaar via Google Jobs).\",\n defaultEnabled: false,\n blocks: [jobsBlock],\n});\n\nexport const breadcrumbsModule = defineModule({\n id: \"breadcrumbs\",\n version: CORE_VERSION,\n label: \"Kruimelpad\",\n description: \"Kruimelpad afgeleid van de URL, met BreadcrumbList-JSON-LD (SEO).\",\n defaultEnabled: false,\n blocks: [breadcrumbsBlock],\n});\n\n/* ── 5.5: webwinkel + donaties ───────────────────────────────────────────── */\nexport { shopModule } from \"./shop/module\";\nimport { shopModule } from \"./shop/module\";\n\nexport const consentModule = defineModule({\n id: \"consent\",\n version: CORE_VERSION,\n label: \"Cookie-consent (AVG)\",\n description: \"Toestemmingsbanner + consent-opslag; stelt niet-essentiële scripts uit.\",\n defaultEnabled: false,\n settingsSchema: z.object({\n message: z\n .string()\n .default(\"We gebruiken cookies om de site te verbeteren. Kies hieronder je voorkeuren.\")\n .describe(\"Bannertekst\"),\n privacyUrl: z.string().optional().describe(\"Link naar privacyverklaring\"),\n version: z.string().optional().describe(\"Beleidsversie (wijzig → banner opnieuw tonen)\"),\n showReopen: z.boolean().default(true).describe(\"Zwevend cookie-knopje om keuze te wijzigen\"),\n categories: z\n .array(\n z.object({\n id: z.string(),\n label: z.string(),\n description: z.string().optional(),\n required: z.boolean().default(false),\n }),\n )\n .default([\n { id: \"necessary\", label: \"Noodzakelijk\", description: \"Nodig om de site te laten werken.\", required: true },\n { id: \"analytics\", label: \"Statistieken\", description: \"Anonieme statistieken om de site te verbeteren.\", required: false },\n { id: \"marketing\", label: \"Marketing\", description: \"Externe embeds zoals video's en kaarten.\", required: false },\n ]),\n }),\n defaultSettings: {},\n});\n\n/** Alle ingebouwde modules (volgorde bepaalt block- en tab-volgorde). */\nexport const builtinModules: ModuleDefinition[] = [\n contentModule,\n pagesModule,\n newsModule,\n mediaModule,\n galleryModule,\n faqModule,\n openingHoursModule,\n pricingModule,\n formsModule,\n statsModule,\n settingsModule,\n testimonialsModule,\n teamModule,\n agendaModule,\n searchModule,\n featureModule,\n countersModule,\n logosModule,\n timelineModule,\n videoModule,\n bannerModule,\n contactModule,\n newsletterModule,\n bookingModule,\n accordionModule,\n embedModule,\n cardsModule,\n tabsModule,\n downloadsModule,\n pdfModule,\n countdownModule,\n sliderModule,\n whatsappModule,\n beforeAfterModule,\n portfolioModule,\n jobsModule,\n breadcrumbsModule,\n shopModule,\n consentModule,\n];\n"],"mappings":"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","names":["shopModule"]}
|
|
1
|
+
{"version":3,"sources":["../../src/modules/builtins.ts"],"sourcesContent":["/**\n * Ingebouwde modules (XiCMS 3.0). Elke \"feature\" van 2.x is hier een first-class module geworden,\n * zodat hij per site aan/uit kan en los te verbeteren is. De bijbehorende admin-panelen staan in\n * `@xiwebdesign/xicms-core/admin` (paneel-registry), gekoppeld via dezelfde `id`/`featureKey`.\n *\n * Backward compatible: zonder `SiteConfig.modules`/`features` zijn alle modules actief — identiek\n * aan 2.x. De `content`-module is `core: true` en kan niet uitgezet worden (de basis-bouwstenen).\n */\nimport { z } from \"zod\";\nimport { defineModule } from \"./defineModule\";\nimport type { ModuleDefinition } from \"./types\";\n\nimport { heroBlock } from \"../blocks/builtins/Hero\";\nimport { richTextBlock } from \"../blocks/builtins/RichTextBlock\";\nimport { imageBlock } from \"../blocks/builtins/ImageBlock\";\nimport { ctaBlock } from \"../blocks/builtins/Cta\";\nimport { columnsBlock } from \"../blocks/builtins/Columns\";\nimport { spacerBlock } from \"../blocks/builtins/Spacer\";\nimport { galleryBlock } from \"../blocks/builtins/Gallery\";\nimport { faqBlock } from \"../blocks/builtins/Faq\";\nimport { openingHoursBlock } from \"../blocks/builtins/OpeningHours\";\nimport { pricingBlock } from \"../blocks/builtins/Pricing\";\nimport { newsListBlock } from \"../blocks/builtins/NewsListBlock\";\nimport { formBlock } from \"../blocks/builtins/FormBlock\";\nimport { testimonialsBlock } from \"../blocks/builtins/Testimonials\";\nimport { teamBlock } from \"../blocks/builtins/Team\";\nimport { agendaBlock } from \"../blocks/builtins/Agenda\";\nimport { searchBlock } from \"../blocks/builtins/Search\";\nimport { featureBlock, countersBlock, logosBlock, timelineBlock } from \"../blocks/builtins/Sections\";\nimport { symbolRefBlock } from \"../blocks/builtins/SymbolRef\";\nimport { videoBlock } from \"../blocks/builtins/Video\";\nimport { bannerBlock } from \"../blocks/builtins/Banner\";\nimport { contactBlock, socialBlock } from \"../blocks/builtins/Contact\";\nimport { mapBlock } from \"../blocks/builtins/MapBlock\";\nimport { newsletterBlock } from \"../blocks/builtins/Newsletter\";\nimport { bookingBlock } from \"../blocks/builtins/Booking\";\nimport { buttonsBlock, quoteBlock, dividerBlock } from \"../blocks/builtins/Elements\";\nimport { accordionBlock } from \"../blocks/builtins/Accordion\";\nimport { embedBlock } from \"../blocks/builtins/Embed\";\nimport { withSidebarBlock, tabsBlock } from \"../blocks/builtins/Layout\";\nimport { cardsBlock } from \"../blocks/builtins/Cards\";\nimport { downloadsBlock } from \"../blocks/builtins/Downloads\";\nimport { pdfBlock } from \"../blocks/builtins/PdfBlock\";\nimport { countdownBlock } from \"../blocks/builtins/Countdown\";\nimport { sliderBlock } from \"../blocks/builtins/Slider\";\nimport { whatsappChatBlock } from \"../blocks/builtins/WhatsappChat\";\nimport { beforeAfterBlock } from \"../blocks/builtins/BeforeAfter\";\nimport { portfolioBlock } from \"../blocks/builtins/Portfolio\";\nimport { jobsBlock } from \"../blocks/builtins/Jobs\";\nimport { breadcrumbsBlock } from \"../blocks/builtins/Breadcrumbs\";\nimport {\n newsWidget,\n agendaWidget,\n openingHoursWidget,\n contactWidget,\n socialWidget as socialWidgetBlock,\n newsletterWidget,\n ctaWidget,\n galleryWidget,\n testimonialsWidget,\n cardsWidget,\n downloadsWidget,\n countdownWidget,\n} from \"../blocks/builtins/Widgets\";\n\nconst CORE_VERSION = \"5.0.0\";\n\n/**\n * Basis-bouwstenen — altijd aanwezig (niet uit te zetten). Bevat ook de indelingsblokken\n * (kolommen, \"Met zijbalk\") waarmee je widgets naast je hoofdinhoud plaatst, plus de\n * compacte CTA-widget.\n */\nexport const contentModule = defineModule({\n id: \"content\",\n version: CORE_VERSION,\n label: \"Basisinhoud\",\n description: \"Kern-bouwstenen: hero, tekst, afbeelding, CTA, kolommen, zijbalk, witruimte.\",\n core: true,\n blocks: [heroBlock, richTextBlock, imageBlock, ctaBlock, columnsBlock, withSidebarBlock, spacerBlock, buttonsBlock, quoteBlock, dividerBlock, ctaWidget, symbolRefBlock],\n});\n\nexport const galleryModule = defineModule({\n id: \"gallery\",\n version: CORE_VERSION,\n label: \"Fotogalerij\",\n description: \"Galerij-block met grid en (optioneel) lightbox + compacte fotostrip-widget.\",\n blocks: [galleryBlock, galleryWidget],\n // Per-site instelbaar door de agent/klant (modules.gallery.config) zonder core te forken.\n // `.describe()` = het label dat de klant in /beheer ziet.\n settingsSchema: z.object({\n columns: z.number().int().min(1).max(6).default(3).describe(\"Kolommen\"),\n lightbox: z.boolean().default(true).describe(\"Lightbox bij klikken\"),\n }),\n defaultSettings: { columns: 3, lightbox: true },\n});\n\nexport const faqModule = defineModule({\n id: \"faq\",\n version: CORE_VERSION,\n label: \"FAQ\",\n description: \"Veelgestelde vragen (accordeon) met optionele zoek + FAQ-JSON-LD.\",\n blocks: [faqBlock],\n});\n\nexport const openingHoursModule = defineModule({\n id: \"openingHours\",\n version: CORE_VERSION,\n label: \"Openingstijden\",\n description: \"Openingstijden-tabel + compacte widget met 'vandaag' gemarkeerd.\",\n blocks: [openingHoursBlock, openingHoursWidget],\n});\n\nexport const pricingModule = defineModule({\n id: \"pricing\",\n version: CORE_VERSION,\n label: \"Prijzen\",\n blocks: [pricingBlock],\n});\n\nexport const pagesModule = defineModule({\n id: \"pages\",\n version: CORE_VERSION,\n label: \"Pagina's\",\n featureKey: \"pages\",\n description: \"Paginabouwer (draft → publish + versiegeschiedenis).\",\n});\n\nexport const newsModule = defineModule({\n id: \"news\",\n version: CORE_VERSION,\n label: \"Nieuws\",\n featureKey: \"news\",\n description: \"Nieuwsartikelen + nieuwslijst-block + 'laatste nieuws'-widget voor de zijbalk.\",\n blocks: [newsListBlock, newsWidget],\n});\n\nexport const mediaModule = defineModule({\n id: \"media\",\n version: CORE_VERSION,\n label: \"Media\",\n featureKey: \"media\",\n description: \"Mediabeheer met compressie + webp/srcset-varianten.\",\n requires: [{ kind: \"function\", name: \"onMediaUpload\" }, { kind: \"storage\", prefix: \"sites/\" }],\n});\n\nexport const formsModule = defineModule({\n id: \"forms\",\n version: CORE_VERSION,\n label: \"Formulieren\",\n featureKey: \"forms\",\n description: \"Formulierbouwer + inzendingen + e-mailnotificatie.\",\n blocks: [formBlock],\n requires: [\n { kind: \"function\", name: \"submitForm\" },\n { kind: \"firestore\", collection: \"forms\" },\n ],\n});\n\nexport const statsModule = defineModule({\n id: \"stats\",\n version: CORE_VERSION,\n label: \"Statistieken\",\n featureKey: \"stats\",\n description: \"Privacy-vriendelijke bezoekersstatistieken (geen cookies).\",\n requires: [{ kind: \"function\", name: \"trackView\" }],\n});\n\nexport const settingsModule = defineModule({\n id: \"settings\",\n version: CORE_VERSION,\n label: \"Instellingen\",\n core: true,\n description: \"Site-instellingen (nav, thema, SEO, formulier-afzender) — alleen siteadmin.\",\n});\n\n// Opt-in modules (defaultEnabled: false): worden bij installatie of later aangezet via\n// `modules: { <id>: true }`. Geen extra backend nodig — data leeft in de page-blocks.\nexport const testimonialsModule = defineModule({\n id: \"testimonials\",\n version: CORE_VERSION,\n label: \"Reviews\",\n description: \"Klantquotes/reviews met sterren, optionele Review-JSON-LD + compacte review-widget.\",\n defaultEnabled: false,\n blocks: [testimonialsBlock, testimonialsWidget],\n});\n\nexport const teamModule = defineModule({\n id: \"team\",\n version: CORE_VERSION,\n label: \"Team\",\n description: \"Team-/medewerkersoverzicht met foto, functie en bio.\",\n defaultEnabled: false,\n blocks: [teamBlock],\n});\n\nexport const agendaModule = defineModule({\n id: \"agenda\",\n version: CORE_VERSION,\n label: \"Agenda\",\n description: \"Evenementen/agenda (chronologisch) met Event-JSON-LD + 'komende agenda'-widget.\",\n defaultEnabled: false,\n blocks: [agendaBlock, agendaWidget],\n});\n\nexport const searchModule = defineModule({\n id: \"search\",\n version: CORE_VERSION,\n label: \"Zoeken\",\n description: \"Site-zoekblok dat gepubliceerde pagina's (en nieuws) client-side doorzoekt.\",\n defaultEnabled: false,\n blocks: [searchBlock],\n});\n\nexport const featureModule = defineModule({\n id: \"feature\",\n version: CORE_VERSION,\n label: \"Beeld + tekst\",\n description: \"Feature-sectie met afbeelding links/rechts en tekst.\",\n defaultEnabled: false,\n blocks: [featureBlock],\n});\n\nexport const countersModule = defineModule({\n id: \"counters\",\n version: CORE_VERSION,\n label: \"Tellers\",\n description: \"Statistiek-tellers (bv. “100+ klanten”).\",\n defaultEnabled: false,\n blocks: [countersBlock],\n});\n\nexport const logosModule = defineModule({\n id: \"logos\",\n version: CORE_VERSION,\n label: \"Logo's\",\n description: \"Partner-/klantlogo-strip.\",\n defaultEnabled: false,\n blocks: [logosBlock],\n});\n\nexport const timelineModule = defineModule({\n id: \"timeline\",\n version: CORE_VERSION,\n label: \"Tijdlijn\",\n description: \"Stappen/proces als tijdlijn.\",\n defaultEnabled: false,\n blocks: [timelineBlock],\n});\n\nexport const videoModule = defineModule({\n id: \"video\",\n version: CORE_VERSION,\n label: \"Video\",\n description: \"YouTube/Vimeo/MP4-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [videoBlock],\n});\n\nexport const bannerModule = defineModule({\n id: \"banner\",\n version: CORE_VERSION,\n label: \"Aankondiging\",\n description: \"Aankondigingsbalk, optioneel sluitbaar.\",\n defaultEnabled: false,\n blocks: [bannerBlock],\n});\n\nexport const contactModule = defineModule({\n id: \"contact\",\n version: CORE_VERSION,\n label: \"Contact + kaart + social\",\n description: \"Contactgegevens (JSON-LD), kaart (consent-gated), social-links + compacte widgets.\",\n defaultEnabled: false,\n blocks: [contactBlock, mapBlock, socialBlock, contactWidget, socialWidgetBlock],\n});\n\nexport const newsletterModule = defineModule({\n id: \"newsletter\",\n version: CORE_VERSION,\n label: \"Nieuwsbrief\",\n description: \"Aanmeldformulier via een externe provider-URL + compacte nieuwsbrief-widget.\",\n defaultEnabled: false,\n blocks: [newsletterBlock, newsletterWidget],\n});\n\nexport const bookingModule = defineModule({\n id: \"booking\",\n version: CORE_VERSION,\n label: \"Afspraak/booking\",\n description: \"Boekings-embed (bv. Calendly), consent-gated.\",\n defaultEnabled: false,\n blocks: [bookingBlock],\n});\n\nexport const accordionModule = defineModule({\n id: \"accordion\",\n version: CORE_VERSION,\n label: \"Accordeon\",\n description: \"Generieke in-/uitklapbare panelen.\",\n defaultEnabled: false,\n blocks: [accordionBlock],\n});\n\nexport const embedModule = defineModule({\n id: \"embed\",\n version: CORE_VERSION,\n label: \"Embed\",\n description: \"Generieke responsive iframe-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [embedBlock],\n});\n\n/* ── Nieuwe modules (3.1) — veelgebruikt op websites, volwaardig + widget waar zinvol ── */\n\nexport const cardsModule = defineModule({\n id: \"cards\",\n version: CORE_VERSION,\n label: \"Diensten / kaarten\",\n description: \"Diensten-/featurekaarten in een grid (icoon of beeld) + compacte 'uitgelicht'-widget.\",\n defaultEnabled: false,\n blocks: [cardsBlock, cardsWidget],\n});\n\nexport const tabsModule = defineModule({\n id: \"tabs\",\n version: CORE_VERSION,\n label: \"Tabbladen\",\n description: \"Tabblad-indeling: per tab een eigen set blokken (bv. beschrijving / specificaties).\",\n defaultEnabled: false,\n blocks: [tabsBlock],\n});\n\nexport const downloadsModule = defineModule({\n id: \"downloads\",\n version: CORE_VERSION,\n label: \"Downloads\",\n description: \"Lijst met downloadbare documenten (brochures, prijslijsten) + compacte widget.\",\n defaultEnabled: false,\n blocks: [downloadsBlock, downloadsWidget],\n});\n\nexport const pdfModule = defineModule({\n id: \"pdf\",\n version: CORE_VERSION,\n label: \"PDF-lezer\",\n description: \"Inline PDF-lezer voor menukaarten/documenten; meerdere PDF's met tabs, zelf te vervangen.\",\n defaultEnabled: false,\n blocks: [pdfBlock],\n});\n\nexport const countdownModule = defineModule({\n id: \"countdown\",\n version: CORE_VERSION,\n label: \"Aftelteller\",\n description: \"Tikkende countdown naar een datum (lancering, evenement, aanbieding) + widget.\",\n defaultEnabled: false,\n blocks: [countdownBlock, countdownWidget],\n});\n\nexport const sliderModule = defineModule({\n id: \"slider\",\n version: CORE_VERSION,\n label: \"Carrousel / slider\",\n description: \"Beeld-/contentcarrousel met dots, pijlen en optioneel autoplay (reduced-motion-veilig).\",\n defaultEnabled: false,\n blocks: [sliderBlock],\n});\n\n/* ── 4.16: nieuwe modules (allemaal opt-in) ──────────────────────────────── */\n\nexport const whatsappModule = defineModule({\n id: \"whatsapp\",\n version: CORE_VERSION,\n label: \"WhatsApp-knop\",\n description: \"Zwevende WhatsApp-/chatknop — laagdrempelig contact (wa.me-link, geen consent nodig).\",\n defaultEnabled: false,\n blocks: [whatsappChatBlock],\n});\n\nexport const beforeAfterModule = defineModule({\n id: \"beforeAfter\",\n version: CORE_VERSION,\n label: \"Voor / na\",\n description: \"Voor/na-vergelijker met sleepbare scheiding — sterk voor hoveniers, schilders, salons.\",\n defaultEnabled: false,\n blocks: [beforeAfterBlock],\n});\n\nexport const portfolioModule = defineModule({\n id: \"portfolio\",\n version: CORE_VERSION,\n label: \"Portfolio / projecten\",\n description: \"Projecten/cases-grid met categorie-filter en lightbox.\",\n defaultEnabled: false,\n blocks: [portfolioBlock],\n});\n\nexport const jobsModule = defineModule({\n id: \"jobs\",\n version: CORE_VERSION,\n label: \"Vacatures\",\n description: \"Vacature-overzicht met JobPosting-JSON-LD (vindbaar via Google Jobs).\",\n defaultEnabled: false,\n blocks: [jobsBlock],\n});\n\nexport const breadcrumbsModule = defineModule({\n id: \"breadcrumbs\",\n version: CORE_VERSION,\n label: \"Kruimelpad\",\n description: \"Kruimelpad afgeleid van de URL, met BreadcrumbList-JSON-LD (SEO).\",\n defaultEnabled: false,\n blocks: [breadcrumbsBlock],\n});\n\n/* ── 5.5: webwinkel + donaties ───────────────────────────────────────────────\n * 6.0: de shop-module zit NIET meer in de default-bundel. Hij is opt-in via de\n * subpath `@xiwebdesign/xicms-core/modules/shop` (+ `/admin/shop`, `/server/shop`),\n * of via de backward-compat-barrel `@xiwebdesign/xicms-core/all`. Zo landt shop-code\n * alleen in de build van sites die 'm daadwerkelijk aanzetten. */\n\nexport const consentModule = defineModule({\n id: \"consent\",\n version: CORE_VERSION,\n label: \"Cookie-consent (AVG)\",\n description: \"Toestemmingsbanner + consent-opslag; stelt niet-essentiële scripts uit.\",\n defaultEnabled: false,\n settingsSchema: z.object({\n message: z\n .string()\n .default(\"We gebruiken cookies om de site te verbeteren. Kies hieronder je voorkeuren.\")\n .describe(\"Bannertekst\"),\n privacyUrl: z.string().optional().describe(\"Link naar privacyverklaring\"),\n version: z.string().optional().describe(\"Beleidsversie (wijzig → banner opnieuw tonen)\"),\n showReopen: z.boolean().default(true).describe(\"Zwevend cookie-knopje om keuze te wijzigen\"),\n categories: z\n .array(\n z.object({\n id: z.string(),\n label: z.string(),\n description: z.string().optional(),\n required: z.boolean().default(false),\n }),\n )\n .default([\n { id: \"necessary\", label: \"Noodzakelijk\", description: \"Nodig om de site te laten werken.\", required: true },\n { id: \"analytics\", label: \"Statistieken\", description: \"Anonieme statistieken om de site te verbeteren.\", required: false },\n { id: \"marketing\", label: \"Marketing\", description: \"Externe embeds zoals video's en kaarten.\", required: false },\n ]),\n }),\n defaultSettings: {},\n});\n\n/** Alle ingebouwde modules (volgorde bepaalt block- en tab-volgorde). */\nexport const builtinModules: ModuleDefinition[] = [\n contentModule,\n pagesModule,\n newsModule,\n mediaModule,\n galleryModule,\n faqModule,\n openingHoursModule,\n pricingModule,\n formsModule,\n statsModule,\n settingsModule,\n testimonialsModule,\n teamModule,\n agendaModule,\n searchModule,\n featureModule,\n countersModule,\n logosModule,\n timelineModule,\n videoModule,\n bannerModule,\n contactModule,\n newsletterModule,\n bookingModule,\n accordionModule,\n embedModule,\n cardsModule,\n tabsModule,\n downloadsModule,\n pdfModule,\n countdownModule,\n sliderModule,\n whatsappModule,\n beforeAfterModule,\n portfolioModule,\n jobsModule,\n breadcrumbsModule,\n consentModule,\n];\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in shop-module (6.0). Importeer dit alleen op sites die de webwinkel gebruiken,
|
|
3
|
+
* via de subpath `@xiwebdesign/xicms-core/modules/shop`. Zo landt de shop-code niet in
|
|
4
|
+
* de bundel van sites zonder shop. Zet 'm aan via `modules={[shopModule]}` op
|
|
5
|
+
* `XiCMSProvider` (of gebruik de gegenereerde `enabledModules`, zie docs/MODULES.md).
|
|
6
|
+
*
|
|
7
|
+
* Admin-paneel: `@xiwebdesign/xicms-core/admin/shop`. Server-readers: `.../server/shop`.
|
|
8
|
+
*/
|
|
9
|
+
export { shopModule } from "./module";
|
|
10
|
+
export * from "./types";
|
|
11
|
+
export * from "./settings";
|
|
12
|
+
export { useCart, cartAdd, cartSetQty, cartRemove, cartClear, type CartLine, type CartState } from "./cartStore";
|
|
13
|
+
export { useShopSettings } from "./lib";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { shopModule } from "./module";
|
|
2
|
+
export * from "./types";
|
|
3
|
+
export * from "./settings";
|
|
4
|
+
import { useCart, cartAdd, cartSetQty, cartRemove, cartClear } from "./cartStore";
|
|
5
|
+
import { useShopSettings } from "./lib";
|
|
6
|
+
export {
|
|
7
|
+
cartAdd,
|
|
8
|
+
cartClear,
|
|
9
|
+
cartRemove,
|
|
10
|
+
cartSetQty,
|
|
11
|
+
shopModule,
|
|
12
|
+
useCart,
|
|
13
|
+
useShopSettings
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/shop/index.ts"],"sourcesContent":["/**\n * Opt-in shop-module (6.0). Importeer dit alleen op sites die de webwinkel gebruiken,\n * via de subpath `@xiwebdesign/xicms-core/modules/shop`. Zo landt de shop-code niet in\n * de bundel van sites zonder shop. Zet 'm aan via `modules={[shopModule]}` op\n * `XiCMSProvider` (of gebruik de gegenereerde `enabledModules`, zie docs/MODULES.md).\n *\n * Admin-paneel: `@xiwebdesign/xicms-core/admin/shop`. Server-readers: `.../server/shop`.\n */\nexport { shopModule } from \"./module\";\nexport * from \"./types\";\nexport * from \"./settings\";\n// Winkelwagen-hooks/helpers (localStorage-cart) — voor shop-sites die een cart-teller tonen.\nexport { useCart, cartAdd, cartSetQty, cartRemove, cartClear, type CartLine, type CartState } from \"./cartStore\";\nexport { useShopSettings } from \"./lib\";\n"],"mappings":"AAQA,SAAS,kBAAkB;AAC3B,cAAc;AACd,cAAc;AAEd,SAAS,SAAS,SAAS,YAAY,YAAY,iBAAgD;AACnG,SAAS,uBAAuB;","names":[]}
|