@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.
@@ -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
- ]).then(([settingsData, currData]) => {
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 codes = (currData.currencies || []).map((c) => c.code).filter(Boolean).sort();
163
- setCurrencies(codes);
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. Click to toggle." }),
351
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
352
- currencies.map((cur) => {
353
- const excluded = Array.isArray(settings.promotion_excluded_currencies) ? settings.promotion_excluded_currencies : [];
354
- const isExcluded = excluded.includes(cur);
355
- return /* @__PURE__ */ jsxRuntime.jsxs(
356
- "button",
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. Checks shipping address country code & phone prefix." }),
378
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: [
379
- { code: "vn", label: "🇻🇳 VN" },
380
- { code: "th", label: "🇹🇭 TH" },
381
- { code: "ko", label: "🇰🇷 KR" },
382
- { code: "ja", label: "🇯🇵 JP" },
383
- { code: "cn", label: "🇨🇳 CN" },
384
- { code: "us", label: "🇺🇸 US" },
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. Click to toggle." }),
597
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
598
- currencies.map((cur) => {
599
- const excluded = Array.isArray(settings.abandoned_cart_discount_excluded_currencies) ? settings.abandoned_cart_discount_excluded_currencies : [];
600
- const isExcluded = excluded.includes(cur);
601
- return /* @__PURE__ */ jsxRuntime.jsxs(
602
- "button",
603
- {
604
- type: "button",
605
- 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"}`,
606
- onClick: () => {
607
- const next = isExcluded ? excluded.filter((c) => c !== cur) : [...excluded, cur];
608
- update("abandoned_cart_discount_excluded_currencies", next);
609
- },
610
- children: [
611
- cur.toUpperCase(),
612
- isExcluded ? " " : ""
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
- ]).then(([settingsData, currData]) => {
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 codes = (currData.currencies || []).map((c) => c.code).filter(Boolean).sort();
162
- setCurrencies(codes);
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. Click to toggle." }),
350
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
351
- currencies.map((cur) => {
352
- const excluded = Array.isArray(settings.promotion_excluded_currencies) ? settings.promotion_excluded_currencies : [];
353
- const isExcluded = excluded.includes(cur);
354
- return /* @__PURE__ */ jsxs(
355
- "button",
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. Checks shipping address country code & phone prefix." }),
377
- /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: [
378
- { code: "vn", label: "🇻🇳 VN" },
379
- { code: "th", label: "🇹🇭 TH" },
380
- { code: "ko", label: "🇰🇷 KR" },
381
- { code: "ja", label: "🇯🇵 JP" },
382
- { code: "cn", label: "🇨🇳 CN" },
383
- { code: "us", label: "🇺🇸 US" },
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. Click to toggle." }),
596
- /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
597
- currencies.map((cur) => {
598
- const excluded = Array.isArray(settings.abandoned_cart_discount_excluded_currencies) ? settings.abandoned_cart_discount_excluded_currencies : [];
599
- const isExcluded = excluded.includes(cur);
600
- return /* @__PURE__ */ jsxs(
601
- "button",
602
- {
603
- type: "button",
604
- 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"}`,
605
- onClick: () => {
606
- const next = isExcluded ? excluded.filter((c) => c !== cur) : [...excluded, cur];
607
- update("abandoned_cart_discount_excluded_currencies", next);
608
- },
609
- children: [
610
- cur.toUpperCase(),
611
- isExcluded ? " " : ""
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kb0912/notification-brevo",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "Sending email notification using Brevo.",
5
5
  "author": "KB (https://medusajs.com)",
6
6
  "license": "MIT",