@kb0912/notification-brevo 2.0.2 → 2.0.4
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/.medusa/server/src/admin/index.js +117 -87
- package/.medusa/server/src/admin/index.mjs +118 -88
- package/.medusa/server/src/modules/brevo-settings/migrations/Migration20260307170711.js +14 -0
- package/.medusa/server/src/modules/brevo-settings/migrations/Migration20260308000200.js +14 -0
- package/package.json +1 -1
|
@@ -151,16 +151,36 @@ const BrevoSettingsPage = () => {
|
|
|
151
151
|
const [saving, setSaving] = react.useState(false);
|
|
152
152
|
const [intervalsText, setIntervalsText] = react.useState("");
|
|
153
153
|
const [currencies, setCurrencies] = react.useState([]);
|
|
154
|
+
const [countries, setCountries] = react.useState([]);
|
|
155
|
+
const [modal, setModal] = react.useState(null);
|
|
156
|
+
const [drawerSearch, setDrawerSearch] = react.useState("");
|
|
154
157
|
react.useEffect(() => {
|
|
155
158
|
Promise.all([
|
|
156
159
|
fetch("/admin/brevo-plugin-settings", { credentials: "include" }).then((r) => r.json()),
|
|
157
|
-
fetch("/admin/currencies", { credentials: "include" }).then((r) => r.json()).catch(() => ({ currencies: [] }))
|
|
158
|
-
|
|
160
|
+
fetch("/admin/currencies", { credentials: "include" }).then((r) => r.json()).catch(() => ({ currencies: [] })),
|
|
161
|
+
fetch("/admin/regions", { credentials: "include" }).then((r) => r.json()).catch(() => ({ regions: [] }))
|
|
162
|
+
]).then(([settingsData, currData, regionData]) => {
|
|
159
163
|
setSettings(settingsData.settings);
|
|
160
164
|
const intervals = Array.isArray(settingsData.settings.abandoned_cart_intervals) ? settingsData.settings.abandoned_cart_intervals : [];
|
|
161
165
|
setIntervalsText(intervals.join(", "));
|
|
162
|
-
const
|
|
163
|
-
|
|
166
|
+
const currOpts = (currData.currencies || []).map((c) => ({
|
|
167
|
+
value: c.code,
|
|
168
|
+
label: `${c.name || c.code.toUpperCase()} (${c.code.toUpperCase()})`
|
|
169
|
+
})).sort((a, b) => a.label.localeCompare(b.label));
|
|
170
|
+
setCurrencies(currOpts);
|
|
171
|
+
const countryMap = /* @__PURE__ */ new Map();
|
|
172
|
+
for (const region of regionData.regions || []) {
|
|
173
|
+
for (const c of region.countries || []) {
|
|
174
|
+
if (c.iso_2 && !countryMap.has(c.iso_2)) {
|
|
175
|
+
countryMap.set(c.iso_2, c.display_name || c.name || c.iso_2.toUpperCase());
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const countryOpts = Array.from(countryMap.entries()).map(([code, name]) => ({
|
|
180
|
+
value: code,
|
|
181
|
+
label: name
|
|
182
|
+
})).sort((a, b) => a.label.localeCompare(b.label));
|
|
183
|
+
setCountries(countryOpts);
|
|
164
184
|
setLoading(false);
|
|
165
185
|
}).catch(() => {
|
|
166
186
|
ui.toast.error("Failed to load Brevo settings");
|
|
@@ -347,70 +367,25 @@ const BrevoSettingsPage = () => {
|
|
|
347
367
|
] }),
|
|
348
368
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2", children: [
|
|
349
369
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Excluded Currencies" }),
|
|
350
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies.
|
|
351
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
{
|
|
358
|
-
type: "button",
|
|
359
|
-
className: `px-2 py-1 rounded text-xs font-mono border transition-colors ${isExcluded ? "bg-red-100 border-red-300 text-red-700" : "bg-ui-bg-base border-ui-border-base text-ui-fg-subtle hover:bg-ui-bg-base-hover"}`,
|
|
360
|
-
onClick: () => {
|
|
361
|
-
const next = isExcluded ? excluded.filter((c) => c !== cur) : [...excluded, cur];
|
|
362
|
-
update("promotion_excluded_currencies", next);
|
|
363
|
-
},
|
|
364
|
-
children: [
|
|
365
|
-
cur.toUpperCase(),
|
|
366
|
-
isExcluded ? " ✕" : ""
|
|
367
|
-
]
|
|
368
|
-
},
|
|
369
|
-
cur
|
|
370
|
-
);
|
|
371
|
-
}),
|
|
372
|
-
currencies.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "No currencies found in store." })
|
|
370
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies." }),
|
|
371
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
372
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_currencies", title: "Select Excluded Currencies", options: currencies }), children: "Select Currencies" }),
|
|
373
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
374
|
+
(settings.promotion_excluded_currencies || []).map((c) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
|
|
375
|
+
(settings.promotion_excluded_currencies || []).length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
|
|
376
|
+
] })
|
|
373
377
|
] })
|
|
374
378
|
] }),
|
|
375
379
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2", children: [
|
|
376
380
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Excluded Countries" }),
|
|
377
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Customers from these countries will NOT receive a promotion code.
|
|
378
|
-
/* @__PURE__ */ jsxRuntime.
|
|
379
|
-
{
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
{ code: "gb", label: "🇬🇧 GB" },
|
|
386
|
-
{ code: "sg", label: "🇸🇬 SG" },
|
|
387
|
-
{ code: "my", label: "🇲🇾 MY" },
|
|
388
|
-
{ code: "id", label: "🇮🇩 ID" },
|
|
389
|
-
{ code: "ph", label: "🇵🇭 PH" },
|
|
390
|
-
{ code: "au", label: "🇦🇺 AU" },
|
|
391
|
-
{ code: "in", label: "🇮🇳 IN" },
|
|
392
|
-
{ code: "tw", label: "🇹🇼 TW" },
|
|
393
|
-
{ code: "hk", label: "🇭🇰 HK" }
|
|
394
|
-
].map((country) => {
|
|
395
|
-
const excluded = Array.isArray(settings.promotion_excluded_countries) ? settings.promotion_excluded_countries : [];
|
|
396
|
-
const isExcluded = excluded.includes(country.code);
|
|
397
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
398
|
-
"button",
|
|
399
|
-
{
|
|
400
|
-
type: "button",
|
|
401
|
-
className: `px-2 py-1 rounded text-xs border transition-colors ${isExcluded ? "bg-red-100 border-red-300 text-red-700" : "bg-ui-bg-base border-ui-border-base text-ui-fg-subtle hover:bg-ui-bg-base-hover"}`,
|
|
402
|
-
onClick: () => {
|
|
403
|
-
const next = isExcluded ? excluded.filter((c) => c !== country.code) : [...excluded, country.code];
|
|
404
|
-
update("promotion_excluded_countries", next);
|
|
405
|
-
},
|
|
406
|
-
children: [
|
|
407
|
-
country.label,
|
|
408
|
-
isExcluded ? " ✕" : ""
|
|
409
|
-
]
|
|
410
|
-
},
|
|
411
|
-
country.code
|
|
412
|
-
);
|
|
413
|
-
}) })
|
|
381
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Customers from these countries will NOT receive a promotion code." }),
|
|
382
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
383
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_countries", title: "Select Excluded Countries", options: countries }), children: "Select Countries" }),
|
|
384
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
385
|
+
(settings.promotion_excluded_countries || []).map((c) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
|
|
386
|
+
(settings.promotion_excluded_countries || []).length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
|
|
387
|
+
] })
|
|
388
|
+
] })
|
|
414
389
|
] })
|
|
415
390
|
] })
|
|
416
391
|
] }) }),
|
|
@@ -593,29 +568,24 @@ const BrevoSettingsPage = () => {
|
|
|
593
568
|
] }),
|
|
594
569
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2", children: [
|
|
595
570
|
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Excluded Currencies" }),
|
|
596
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies.
|
|
597
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
},
|
|
615
|
-
cur
|
|
616
|
-
);
|
|
617
|
-
}),
|
|
618
|
-
currencies.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "No currencies found in store." })
|
|
571
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies." }),
|
|
572
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
573
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "abandoned_cart_discount_excluded_currencies", title: "Select Excluded Currencies", options: currencies }), children: "Select Currencies" }),
|
|
574
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
575
|
+
(settings.abandoned_cart_discount_excluded_currencies || []).map((c) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
|
|
576
|
+
(settings.abandoned_cart_discount_excluded_currencies || []).length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
|
|
577
|
+
] })
|
|
578
|
+
] })
|
|
579
|
+
] }),
|
|
580
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2", children: [
|
|
581
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Excluded Countries" }),
|
|
582
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Customers from these countries will NOT receive a discount code." }),
|
|
583
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
584
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_countries", title: "Select Excluded Countries", options: countries }), children: "Select Countries" }),
|
|
585
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
586
|
+
(settings.promotion_excluded_countries || []).map((c) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
|
|
587
|
+
(settings.promotion_excluded_countries || []).length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
|
|
588
|
+
] })
|
|
619
589
|
] })
|
|
620
590
|
] })
|
|
621
591
|
] })
|
|
@@ -1007,6 +977,66 @@ const BrevoSettingsPage = () => {
|
|
|
1007
977
|
)
|
|
1008
978
|
] })
|
|
1009
979
|
] })
|
|
980
|
+
] }) }),
|
|
981
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer, { open: !!modal, onOpenChange: (open) => {
|
|
982
|
+
if (!open) {
|
|
983
|
+
setModal(null);
|
|
984
|
+
setDrawerSearch("");
|
|
985
|
+
}
|
|
986
|
+
}, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Drawer.Content, { children: [
|
|
987
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Title, { children: (modal == null ? void 0 : modal.title) || "" }) }),
|
|
988
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Body, { className: "overflow-y-auto", children: modal && (() => {
|
|
989
|
+
const [search, setSearch] = [drawerSearch, setDrawerSearch];
|
|
990
|
+
const currentSelected = new Set((settings == null ? void 0 : settings[modal.key]) || []);
|
|
991
|
+
const filtered = modal.options.filter(
|
|
992
|
+
(o) => o.label.toLowerCase().includes(search.toLowerCase()) || o.value.toLowerCase().includes(search.toLowerCase())
|
|
993
|
+
);
|
|
994
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
|
|
995
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
996
|
+
ui.Input,
|
|
997
|
+
{
|
|
998
|
+
placeholder: "Search...",
|
|
999
|
+
value: search,
|
|
1000
|
+
onChange: (e) => setSearch(e.target.value)
|
|
1001
|
+
}
|
|
1002
|
+
),
|
|
1003
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-3 space-y-0.5", children: [
|
|
1004
|
+
filtered.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-sm py-4 text-center", children: "No results" }),
|
|
1005
|
+
filtered.map((opt) => {
|
|
1006
|
+
const isChecked = currentSelected.has(opt.value);
|
|
1007
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1008
|
+
"label",
|
|
1009
|
+
{
|
|
1010
|
+
className: "flex items-center gap-3 py-2 px-3 cursor-pointer hover:bg-ui-bg-base-hover rounded-lg",
|
|
1011
|
+
children: [
|
|
1012
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1013
|
+
ui.Checkbox,
|
|
1014
|
+
{
|
|
1015
|
+
checked: isChecked,
|
|
1016
|
+
onCheckedChange: () => {
|
|
1017
|
+
const arr = (settings == null ? void 0 : settings[modal.key]) || [];
|
|
1018
|
+
const next = isChecked ? arr.filter((c) => c !== opt.value) : [...arr, opt.value];
|
|
1019
|
+
update(modal.key, next);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
),
|
|
1023
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm flex-1", children: opt.label }),
|
|
1024
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-ui-fg-subtle font-mono", children: opt.value.toUpperCase() })
|
|
1025
|
+
]
|
|
1026
|
+
},
|
|
1027
|
+
opt.value
|
|
1028
|
+
);
|
|
1029
|
+
})
|
|
1030
|
+
] })
|
|
1031
|
+
] });
|
|
1032
|
+
})() }),
|
|
1033
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Drawer.Footer, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between w-full", children: [
|
|
1034
|
+
/* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-xs text-ui-fg-subtle", children: [
|
|
1035
|
+
((settings == null ? void 0 : settings[(modal == null ? void 0 : modal.key) || ""]) || []).length,
|
|
1036
|
+
" selected"
|
|
1037
|
+
] }),
|
|
1038
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => setModal(null), children: "Done" })
|
|
1039
|
+
] }) })
|
|
1010
1040
|
] }) })
|
|
1011
1041
|
] });
|
|
1012
1042
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { defineRouteConfig } from "@medusajs/admin-sdk";
|
|
3
|
-
import { Container, Text, Heading, Badge, Table, toast, Toaster, Button, Label, Input, Switch, Select } from "@medusajs/ui";
|
|
3
|
+
import { Container, Text, Heading, Badge, Table, toast, Toaster, Button, Label, Input, Switch, Select, Drawer, Checkbox } from "@medusajs/ui";
|
|
4
4
|
import { ChartBar, EnvelopeSolid } from "@medusajs/icons";
|
|
5
5
|
import { useState, useEffect } from "react";
|
|
6
6
|
const EVENT_LABELS = {
|
|
@@ -150,16 +150,36 @@ const BrevoSettingsPage = () => {
|
|
|
150
150
|
const [saving, setSaving] = useState(false);
|
|
151
151
|
const [intervalsText, setIntervalsText] = useState("");
|
|
152
152
|
const [currencies, setCurrencies] = useState([]);
|
|
153
|
+
const [countries, setCountries] = useState([]);
|
|
154
|
+
const [modal, setModal] = useState(null);
|
|
155
|
+
const [drawerSearch, setDrawerSearch] = useState("");
|
|
153
156
|
useEffect(() => {
|
|
154
157
|
Promise.all([
|
|
155
158
|
fetch("/admin/brevo-plugin-settings", { credentials: "include" }).then((r) => r.json()),
|
|
156
|
-
fetch("/admin/currencies", { credentials: "include" }).then((r) => r.json()).catch(() => ({ currencies: [] }))
|
|
157
|
-
|
|
159
|
+
fetch("/admin/currencies", { credentials: "include" }).then((r) => r.json()).catch(() => ({ currencies: [] })),
|
|
160
|
+
fetch("/admin/regions", { credentials: "include" }).then((r) => r.json()).catch(() => ({ regions: [] }))
|
|
161
|
+
]).then(([settingsData, currData, regionData]) => {
|
|
158
162
|
setSettings(settingsData.settings);
|
|
159
163
|
const intervals = Array.isArray(settingsData.settings.abandoned_cart_intervals) ? settingsData.settings.abandoned_cart_intervals : [];
|
|
160
164
|
setIntervalsText(intervals.join(", "));
|
|
161
|
-
const
|
|
162
|
-
|
|
165
|
+
const currOpts = (currData.currencies || []).map((c) => ({
|
|
166
|
+
value: c.code,
|
|
167
|
+
label: `${c.name || c.code.toUpperCase()} (${c.code.toUpperCase()})`
|
|
168
|
+
})).sort((a, b) => a.label.localeCompare(b.label));
|
|
169
|
+
setCurrencies(currOpts);
|
|
170
|
+
const countryMap = /* @__PURE__ */ new Map();
|
|
171
|
+
for (const region of regionData.regions || []) {
|
|
172
|
+
for (const c of region.countries || []) {
|
|
173
|
+
if (c.iso_2 && !countryMap.has(c.iso_2)) {
|
|
174
|
+
countryMap.set(c.iso_2, c.display_name || c.name || c.iso_2.toUpperCase());
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const countryOpts = Array.from(countryMap.entries()).map(([code, name]) => ({
|
|
179
|
+
value: code,
|
|
180
|
+
label: name
|
|
181
|
+
})).sort((a, b) => a.label.localeCompare(b.label));
|
|
182
|
+
setCountries(countryOpts);
|
|
163
183
|
setLoading(false);
|
|
164
184
|
}).catch(() => {
|
|
165
185
|
toast.error("Failed to load Brevo settings");
|
|
@@ -346,70 +366,25 @@ const BrevoSettingsPage = () => {
|
|
|
346
366
|
] }),
|
|
347
367
|
/* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
|
|
348
368
|
/* @__PURE__ */ jsx(Label, { children: "Excluded Currencies" }),
|
|
349
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies.
|
|
350
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
{
|
|
357
|
-
type: "button",
|
|
358
|
-
className: `px-2 py-1 rounded text-xs font-mono border transition-colors ${isExcluded ? "bg-red-100 border-red-300 text-red-700" : "bg-ui-bg-base border-ui-border-base text-ui-fg-subtle hover:bg-ui-bg-base-hover"}`,
|
|
359
|
-
onClick: () => {
|
|
360
|
-
const next = isExcluded ? excluded.filter((c) => c !== cur) : [...excluded, cur];
|
|
361
|
-
update("promotion_excluded_currencies", next);
|
|
362
|
-
},
|
|
363
|
-
children: [
|
|
364
|
-
cur.toUpperCase(),
|
|
365
|
-
isExcluded ? " ✕" : ""
|
|
366
|
-
]
|
|
367
|
-
},
|
|
368
|
-
cur
|
|
369
|
-
);
|
|
370
|
-
}),
|
|
371
|
-
currencies.length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "No currencies found in store." })
|
|
369
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies." }),
|
|
370
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
371
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_currencies", title: "Select Excluded Currencies", options: currencies }), children: "Select Currencies" }),
|
|
372
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
373
|
+
(settings.promotion_excluded_currencies || []).map((c) => /* @__PURE__ */ jsx(Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
|
|
374
|
+
(settings.promotion_excluded_currencies || []).length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
|
|
375
|
+
] })
|
|
372
376
|
] })
|
|
373
377
|
] }),
|
|
374
378
|
/* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
|
|
375
379
|
/* @__PURE__ */ jsx(Label, { children: "Excluded Countries" }),
|
|
376
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Customers from these countries will NOT receive a promotion code.
|
|
377
|
-
/* @__PURE__ */
|
|
378
|
-
{
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
{ code: "gb", label: "🇬🇧 GB" },
|
|
385
|
-
{ code: "sg", label: "🇸🇬 SG" },
|
|
386
|
-
{ code: "my", label: "🇲🇾 MY" },
|
|
387
|
-
{ code: "id", label: "🇮🇩 ID" },
|
|
388
|
-
{ code: "ph", label: "🇵🇭 PH" },
|
|
389
|
-
{ code: "au", label: "🇦🇺 AU" },
|
|
390
|
-
{ code: "in", label: "🇮🇳 IN" },
|
|
391
|
-
{ code: "tw", label: "🇹🇼 TW" },
|
|
392
|
-
{ code: "hk", label: "🇭🇰 HK" }
|
|
393
|
-
].map((country) => {
|
|
394
|
-
const excluded = Array.isArray(settings.promotion_excluded_countries) ? settings.promotion_excluded_countries : [];
|
|
395
|
-
const isExcluded = excluded.includes(country.code);
|
|
396
|
-
return /* @__PURE__ */ jsxs(
|
|
397
|
-
"button",
|
|
398
|
-
{
|
|
399
|
-
type: "button",
|
|
400
|
-
className: `px-2 py-1 rounded text-xs border transition-colors ${isExcluded ? "bg-red-100 border-red-300 text-red-700" : "bg-ui-bg-base border-ui-border-base text-ui-fg-subtle hover:bg-ui-bg-base-hover"}`,
|
|
401
|
-
onClick: () => {
|
|
402
|
-
const next = isExcluded ? excluded.filter((c) => c !== country.code) : [...excluded, country.code];
|
|
403
|
-
update("promotion_excluded_countries", next);
|
|
404
|
-
},
|
|
405
|
-
children: [
|
|
406
|
-
country.label,
|
|
407
|
-
isExcluded ? " ✕" : ""
|
|
408
|
-
]
|
|
409
|
-
},
|
|
410
|
-
country.code
|
|
411
|
-
);
|
|
412
|
-
}) })
|
|
380
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Customers from these countries will NOT receive a promotion code." }),
|
|
381
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
382
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_countries", title: "Select Excluded Countries", options: countries }), children: "Select Countries" }),
|
|
383
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
384
|
+
(settings.promotion_excluded_countries || []).map((c) => /* @__PURE__ */ jsx(Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
|
|
385
|
+
(settings.promotion_excluded_countries || []).length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
|
|
386
|
+
] })
|
|
387
|
+
] })
|
|
413
388
|
] })
|
|
414
389
|
] })
|
|
415
390
|
] }) }),
|
|
@@ -592,29 +567,24 @@ const BrevoSettingsPage = () => {
|
|
|
592
567
|
] }),
|
|
593
568
|
/* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
|
|
594
569
|
/* @__PURE__ */ jsx(Label, { children: "Excluded Currencies" }),
|
|
595
|
-
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies.
|
|
596
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
},
|
|
614
|
-
cur
|
|
615
|
-
);
|
|
616
|
-
}),
|
|
617
|
-
currencies.length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "No currencies found in store." })
|
|
570
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies." }),
|
|
571
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
572
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "abandoned_cart_discount_excluded_currencies", title: "Select Excluded Currencies", options: currencies }), children: "Select Currencies" }),
|
|
573
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
574
|
+
(settings.abandoned_cart_discount_excluded_currencies || []).map((c) => /* @__PURE__ */ jsx(Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
|
|
575
|
+
(settings.abandoned_cart_discount_excluded_currencies || []).length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
|
|
576
|
+
] })
|
|
577
|
+
] })
|
|
578
|
+
] }),
|
|
579
|
+
/* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
|
|
580
|
+
/* @__PURE__ */ jsx(Label, { children: "Excluded Countries" }),
|
|
581
|
+
/* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Customers from these countries will NOT receive a discount code." }),
|
|
582
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
|
|
583
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_countries", title: "Select Excluded Countries", options: countries }), children: "Select Countries" }),
|
|
584
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
|
|
585
|
+
(settings.promotion_excluded_countries || []).map((c) => /* @__PURE__ */ jsx(Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
|
|
586
|
+
(settings.promotion_excluded_countries || []).length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
|
|
587
|
+
] })
|
|
618
588
|
] })
|
|
619
589
|
] })
|
|
620
590
|
] })
|
|
@@ -1006,6 +976,66 @@ const BrevoSettingsPage = () => {
|
|
|
1006
976
|
)
|
|
1007
977
|
] })
|
|
1008
978
|
] })
|
|
979
|
+
] }) }),
|
|
980
|
+
/* @__PURE__ */ jsx(Drawer, { open: !!modal, onOpenChange: (open) => {
|
|
981
|
+
if (!open) {
|
|
982
|
+
setModal(null);
|
|
983
|
+
setDrawerSearch("");
|
|
984
|
+
}
|
|
985
|
+
}, children: /* @__PURE__ */ jsxs(Drawer.Content, { children: [
|
|
986
|
+
/* @__PURE__ */ jsx(Drawer.Header, { children: /* @__PURE__ */ jsx(Drawer.Title, { children: (modal == null ? void 0 : modal.title) || "" }) }),
|
|
987
|
+
/* @__PURE__ */ jsx(Drawer.Body, { className: "overflow-y-auto", children: modal && (() => {
|
|
988
|
+
const [search, setSearch] = [drawerSearch, setDrawerSearch];
|
|
989
|
+
const currentSelected = new Set((settings == null ? void 0 : settings[modal.key]) || []);
|
|
990
|
+
const filtered = modal.options.filter(
|
|
991
|
+
(o) => o.label.toLowerCase().includes(search.toLowerCase()) || o.value.toLowerCase().includes(search.toLowerCase())
|
|
992
|
+
);
|
|
993
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
994
|
+
/* @__PURE__ */ jsx(
|
|
995
|
+
Input,
|
|
996
|
+
{
|
|
997
|
+
placeholder: "Search...",
|
|
998
|
+
value: search,
|
|
999
|
+
onChange: (e) => setSearch(e.target.value)
|
|
1000
|
+
}
|
|
1001
|
+
),
|
|
1002
|
+
/* @__PURE__ */ jsxs("div", { className: "mt-3 space-y-0.5", children: [
|
|
1003
|
+
filtered.length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-sm py-4 text-center", children: "No results" }),
|
|
1004
|
+
filtered.map((opt) => {
|
|
1005
|
+
const isChecked = currentSelected.has(opt.value);
|
|
1006
|
+
return /* @__PURE__ */ jsxs(
|
|
1007
|
+
"label",
|
|
1008
|
+
{
|
|
1009
|
+
className: "flex items-center gap-3 py-2 px-3 cursor-pointer hover:bg-ui-bg-base-hover rounded-lg",
|
|
1010
|
+
children: [
|
|
1011
|
+
/* @__PURE__ */ jsx(
|
|
1012
|
+
Checkbox,
|
|
1013
|
+
{
|
|
1014
|
+
checked: isChecked,
|
|
1015
|
+
onCheckedChange: () => {
|
|
1016
|
+
const arr = (settings == null ? void 0 : settings[modal.key]) || [];
|
|
1017
|
+
const next = isChecked ? arr.filter((c) => c !== opt.value) : [...arr, opt.value];
|
|
1018
|
+
update(modal.key, next);
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
),
|
|
1022
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm flex-1", children: opt.label }),
|
|
1023
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-ui-fg-subtle font-mono", children: opt.value.toUpperCase() })
|
|
1024
|
+
]
|
|
1025
|
+
},
|
|
1026
|
+
opt.value
|
|
1027
|
+
);
|
|
1028
|
+
})
|
|
1029
|
+
] })
|
|
1030
|
+
] });
|
|
1031
|
+
})() }),
|
|
1032
|
+
/* @__PURE__ */ jsx(Drawer.Footer, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between w-full", children: [
|
|
1033
|
+
/* @__PURE__ */ jsxs(Text, { className: "text-xs text-ui-fg-subtle", children: [
|
|
1034
|
+
((settings == null ? void 0 : settings[(modal == null ? void 0 : modal.key) || ""]) || []).length,
|
|
1035
|
+
" selected"
|
|
1036
|
+
] }),
|
|
1037
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal(null), children: "Done" })
|
|
1038
|
+
] }) })
|
|
1009
1039
|
] }) })
|
|
1010
1040
|
] });
|
|
1011
1041
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260307170711 = void 0;
|
|
4
|
+
const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
|
|
5
|
+
class Migration20260307170711 extends migrations_1.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
this.addSql(`alter table if exists "brevo_settings" add column if not exists "promotion_excluded_countries" jsonb null;`);
|
|
8
|
+
}
|
|
9
|
+
async down() {
|
|
10
|
+
this.addSql(`alter table if exists "brevo_settings" drop column if exists "promotion_excluded_countries";`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.Migration20260307170711 = Migration20260307170711;
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNjAzMDcxNzA3MTEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9icmV2by1zZXR0aW5ncy9taWdyYXRpb25zL01pZ3JhdGlvbjIwMjYwMzA3MTcwNzExLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlFQUFxRTtBQUVyRSxNQUFhLHVCQUF3QixTQUFRLHNCQUFTO0lBRTNDLEtBQUssQ0FBQyxFQUFFO1FBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyw0R0FBNEcsQ0FBQyxDQUFDO0lBQzVILENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSTtRQUNqQixJQUFJLENBQUMsTUFBTSxDQUFDLDhGQUE4RixDQUFDLENBQUM7SUFDOUcsQ0FBQztDQUVGO0FBVkQsMERBVUMifQ==
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Migration20260308000200 = void 0;
|
|
4
|
+
const migrations_1 = require("@medusajs/framework/mikro-orm/migrations");
|
|
5
|
+
class Migration20260308000200 extends migrations_1.Migration {
|
|
6
|
+
async up() {
|
|
7
|
+
this.addSql(`alter table if exists "brevo_settings" add column if not exists "promotion_excluded_countries" jsonb null;`);
|
|
8
|
+
}
|
|
9
|
+
async down() {
|
|
10
|
+
this.addSql(`alter table if exists "brevo_settings" drop column if exists "promotion_excluded_countries";`);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.Migration20260308000200 = Migration20260308000200;
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWlncmF0aW9uMjAyNjAzMDgwMDAyMDAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9icmV2by1zZXR0aW5ncy9taWdyYXRpb25zL01pZ3JhdGlvbjIwMjYwMzA4MDAwMjAwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlFQUFxRTtBQUVyRSxNQUFhLHVCQUF3QixTQUFRLHNCQUFTO0lBRXpDLEtBQUssQ0FBQyxFQUFFO1FBQ2IsSUFBSSxDQUFDLE1BQU0sQ0FBQyw0R0FBNEcsQ0FBQyxDQUFDO0lBQzlILENBQUM7SUFFUSxLQUFLLENBQUMsSUFBSTtRQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsOEZBQThGLENBQUMsQ0FBQztJQUNoSCxDQUFDO0NBRUo7QUFWRCwwREFVQyJ9
|