@kb0912/notification-brevo 2.0.2 → 2.0.3

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.
@@ -145,22 +145,104 @@ const config$1 = adminSdk.defineRouteConfig({
145
145
  label: "Email Analytics",
146
146
  icon: icons.ChartBar
147
147
  });
148
+ const MultiSelectModal = ({
149
+ title,
150
+ options,
151
+ selected,
152
+ onClose,
153
+ onSave
154
+ }) => {
155
+ const [search, setSearch] = react.useState("");
156
+ const [checked, setChecked] = react.useState(new Set(selected));
157
+ const filtered = options.filter(
158
+ (o) => o.label.toLowerCase().includes(search.toLowerCase()) || o.value.toLowerCase().includes(search.toLowerCase())
159
+ );
160
+ const toggle = (val) => {
161
+ setChecked((prev) => {
162
+ const next = new Set(prev);
163
+ next.has(val) ? next.delete(val) : next.add(val);
164
+ return next;
165
+ });
166
+ };
167
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40", onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-xl shadow-2xl w-[420px] max-h-[520px] flex flex-col", onClick: (e) => e.stopPropagation(), children: [
168
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-5 py-4 border-b", children: [
169
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "font-semibold text-base", children: title }),
170
+ /* @__PURE__ */ jsxRuntime.jsx(
171
+ ui.Input,
172
+ {
173
+ className: "mt-2",
174
+ placeholder: "Search...",
175
+ value: search,
176
+ onChange: (e) => setSearch(e.target.value)
177
+ }
178
+ )
179
+ ] }),
180
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto px-5 py-3", children: [
181
+ filtered.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-sm", children: "No results" }),
182
+ filtered.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-center gap-3 py-1.5 cursor-pointer hover:bg-ui-bg-base-hover rounded px-2 -mx-2", children: [
183
+ /* @__PURE__ */ jsxRuntime.jsx(
184
+ "input",
185
+ {
186
+ type: "checkbox",
187
+ className: "accent-ui-fg-interactive w-4 h-4",
188
+ checked: checked.has(opt.value),
189
+ onChange: () => toggle(opt.value)
190
+ }
191
+ ),
192
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm", children: opt.label }),
193
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-ui-fg-subtle font-mono ml-auto", children: opt.value.toUpperCase() })
194
+ ] }, opt.value))
195
+ ] }),
196
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-5 py-3 border-t flex items-center justify-between", children: [
197
+ /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { className: "text-xs text-ui-fg-subtle", children: [
198
+ checked.size,
199
+ " selected"
200
+ ] }),
201
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
202
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: onClose, children: "Cancel" }),
203
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { size: "small", onClick: () => {
204
+ onSave(Array.from(checked));
205
+ onClose();
206
+ }, children: "Apply" })
207
+ ] })
208
+ ] })
209
+ ] }) });
210
+ };
148
211
  const BrevoSettingsPage = () => {
149
212
  const [settings, setSettings] = react.useState(null);
150
213
  const [loading, setLoading] = react.useState(true);
151
214
  const [saving, setSaving] = react.useState(false);
152
215
  const [intervalsText, setIntervalsText] = react.useState("");
153
216
  const [currencies, setCurrencies] = react.useState([]);
217
+ const [countries, setCountries] = react.useState([]);
218
+ const [modal, setModal] = react.useState(null);
154
219
  react.useEffect(() => {
155
220
  Promise.all([
156
221
  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]) => {
222
+ fetch("/admin/currencies", { credentials: "include" }).then((r) => r.json()).catch(() => ({ currencies: [] })),
223
+ fetch("/admin/regions", { credentials: "include" }).then((r) => r.json()).catch(() => ({ regions: [] }))
224
+ ]).then(([settingsData, currData, regionData]) => {
159
225
  setSettings(settingsData.settings);
160
226
  const intervals = Array.isArray(settingsData.settings.abandoned_cart_intervals) ? settingsData.settings.abandoned_cart_intervals : [];
161
227
  setIntervalsText(intervals.join(", "));
162
- const codes = (currData.currencies || []).map((c) => c.code).filter(Boolean).sort();
163
- setCurrencies(codes);
228
+ const currOpts = (currData.currencies || []).map((c) => ({
229
+ value: c.code,
230
+ label: `${c.name || c.code.toUpperCase()} (${c.code.toUpperCase()})`
231
+ })).sort((a, b) => a.label.localeCompare(b.label));
232
+ setCurrencies(currOpts);
233
+ const countryMap = /* @__PURE__ */ new Map();
234
+ for (const region of regionData.regions || []) {
235
+ for (const c of region.countries || []) {
236
+ if (c.iso_2 && !countryMap.has(c.iso_2)) {
237
+ countryMap.set(c.iso_2, c.display_name || c.name || c.iso_2.toUpperCase());
238
+ }
239
+ }
240
+ }
241
+ const countryOpts = Array.from(countryMap.entries()).map(([code, name]) => ({
242
+ value: code,
243
+ label: name
244
+ })).sort((a, b) => a.label.localeCompare(b.label));
245
+ setCountries(countryOpts);
164
246
  setLoading(false);
165
247
  }).catch(() => {
166
248
  ui.toast.error("Failed to load Brevo settings");
@@ -347,70 +429,25 @@ const BrevoSettingsPage = () => {
347
429
  ] }),
348
430
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2", children: [
349
431
  /* @__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." })
432
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies." }),
433
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
434
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_currencies", title: "Select Excluded Currencies", options: currencies }), children: "Select Currencies" }),
435
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
436
+ (settings.promotion_excluded_currencies || []).map((c) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
437
+ (settings.promotion_excluded_currencies || []).length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
438
+ ] })
373
439
  ] })
374
440
  ] }),
375
441
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2", children: [
376
442
  /* @__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
- }) })
443
+ /* @__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." }),
444
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
445
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_countries", title: "Select Excluded Countries", options: countries }), children: "Select Countries" }),
446
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
447
+ (settings.promotion_excluded_countries || []).map((c) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
448
+ (settings.promotion_excluded_countries || []).length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
449
+ ] })
450
+ ] })
414
451
  ] })
415
452
  ] })
416
453
  ] }) }),
@@ -593,29 +630,24 @@ const BrevoSettingsPage = () => {
593
630
  ] }),
594
631
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2", children: [
595
632
  /* @__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." })
633
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies." }),
634
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
635
+ /* @__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" }),
636
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
637
+ (settings.abandoned_cart_discount_excluded_currencies || []).map((c) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
638
+ (settings.abandoned_cart_discount_excluded_currencies || []).length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
639
+ ] })
640
+ ] })
641
+ ] }),
642
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "col-span-2", children: [
643
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { children: "Excluded Countries" }),
644
+ /* @__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." }),
645
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
646
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_countries", title: "Select Excluded Countries", options: countries }), children: "Select Countries" }),
647
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-1", children: [
648
+ (settings.promotion_excluded_countries || []).map((c) => /* @__PURE__ */ jsxRuntime.jsx(ui.Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
649
+ (settings.promotion_excluded_countries || []).length === 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
650
+ ] })
619
651
  ] })
620
652
  ] })
621
653
  ] })
@@ -1007,7 +1039,17 @@ const BrevoSettingsPage = () => {
1007
1039
  )
1008
1040
  ] })
1009
1041
  ] })
1010
- ] }) })
1042
+ ] }) }),
1043
+ modal && settings && /* @__PURE__ */ jsxRuntime.jsx(
1044
+ MultiSelectModal,
1045
+ {
1046
+ title: modal.title,
1047
+ options: modal.options,
1048
+ selected: settings[modal.key] || [],
1049
+ onClose: () => setModal(null),
1050
+ onSave: (values) => update(modal.key, values)
1051
+ }
1052
+ )
1011
1053
  ] });
1012
1054
  };
1013
1055
  const config = adminSdk.defineRouteConfig({
@@ -144,22 +144,104 @@ const config$1 = defineRouteConfig({
144
144
  label: "Email Analytics",
145
145
  icon: ChartBar
146
146
  });
147
+ const MultiSelectModal = ({
148
+ title,
149
+ options,
150
+ selected,
151
+ onClose,
152
+ onSave
153
+ }) => {
154
+ const [search, setSearch] = useState("");
155
+ const [checked, setChecked] = useState(new Set(selected));
156
+ const filtered = options.filter(
157
+ (o) => o.label.toLowerCase().includes(search.toLowerCase()) || o.value.toLowerCase().includes(search.toLowerCase())
158
+ );
159
+ const toggle = (val) => {
160
+ setChecked((prev) => {
161
+ const next = new Set(prev);
162
+ next.has(val) ? next.delete(val) : next.add(val);
163
+ return next;
164
+ });
165
+ };
166
+ return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/40", onClick: onClose, children: /* @__PURE__ */ jsxs("div", { className: "bg-white rounded-xl shadow-2xl w-[420px] max-h-[520px] flex flex-col", onClick: (e) => e.stopPropagation(), children: [
167
+ /* @__PURE__ */ jsxs("div", { className: "px-5 py-4 border-b", children: [
168
+ /* @__PURE__ */ jsx(Text, { className: "font-semibold text-base", children: title }),
169
+ /* @__PURE__ */ jsx(
170
+ Input,
171
+ {
172
+ className: "mt-2",
173
+ placeholder: "Search...",
174
+ value: search,
175
+ onChange: (e) => setSearch(e.target.value)
176
+ }
177
+ )
178
+ ] }),
179
+ /* @__PURE__ */ jsxs("div", { className: "flex-1 overflow-y-auto px-5 py-3", children: [
180
+ filtered.length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-sm", children: "No results" }),
181
+ filtered.map((opt) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-3 py-1.5 cursor-pointer hover:bg-ui-bg-base-hover rounded px-2 -mx-2", children: [
182
+ /* @__PURE__ */ jsx(
183
+ "input",
184
+ {
185
+ type: "checkbox",
186
+ className: "accent-ui-fg-interactive w-4 h-4",
187
+ checked: checked.has(opt.value),
188
+ onChange: () => toggle(opt.value)
189
+ }
190
+ ),
191
+ /* @__PURE__ */ jsx("span", { className: "text-sm", children: opt.label }),
192
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-ui-fg-subtle font-mono ml-auto", children: opt.value.toUpperCase() })
193
+ ] }, opt.value))
194
+ ] }),
195
+ /* @__PURE__ */ jsxs("div", { className: "px-5 py-3 border-t flex items-center justify-between", children: [
196
+ /* @__PURE__ */ jsxs(Text, { className: "text-xs text-ui-fg-subtle", children: [
197
+ checked.size,
198
+ " selected"
199
+ ] }),
200
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
201
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: onClose, children: "Cancel" }),
202
+ /* @__PURE__ */ jsx(Button, { size: "small", onClick: () => {
203
+ onSave(Array.from(checked));
204
+ onClose();
205
+ }, children: "Apply" })
206
+ ] })
207
+ ] })
208
+ ] }) });
209
+ };
147
210
  const BrevoSettingsPage = () => {
148
211
  const [settings, setSettings] = useState(null);
149
212
  const [loading, setLoading] = useState(true);
150
213
  const [saving, setSaving] = useState(false);
151
214
  const [intervalsText, setIntervalsText] = useState("");
152
215
  const [currencies, setCurrencies] = useState([]);
216
+ const [countries, setCountries] = useState([]);
217
+ const [modal, setModal] = useState(null);
153
218
  useEffect(() => {
154
219
  Promise.all([
155
220
  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]) => {
221
+ fetch("/admin/currencies", { credentials: "include" }).then((r) => r.json()).catch(() => ({ currencies: [] })),
222
+ fetch("/admin/regions", { credentials: "include" }).then((r) => r.json()).catch(() => ({ regions: [] }))
223
+ ]).then(([settingsData, currData, regionData]) => {
158
224
  setSettings(settingsData.settings);
159
225
  const intervals = Array.isArray(settingsData.settings.abandoned_cart_intervals) ? settingsData.settings.abandoned_cart_intervals : [];
160
226
  setIntervalsText(intervals.join(", "));
161
- const codes = (currData.currencies || []).map((c) => c.code).filter(Boolean).sort();
162
- setCurrencies(codes);
227
+ const currOpts = (currData.currencies || []).map((c) => ({
228
+ value: c.code,
229
+ label: `${c.name || c.code.toUpperCase()} (${c.code.toUpperCase()})`
230
+ })).sort((a, b) => a.label.localeCompare(b.label));
231
+ setCurrencies(currOpts);
232
+ const countryMap = /* @__PURE__ */ new Map();
233
+ for (const region of regionData.regions || []) {
234
+ for (const c of region.countries || []) {
235
+ if (c.iso_2 && !countryMap.has(c.iso_2)) {
236
+ countryMap.set(c.iso_2, c.display_name || c.name || c.iso_2.toUpperCase());
237
+ }
238
+ }
239
+ }
240
+ const countryOpts = Array.from(countryMap.entries()).map(([code, name]) => ({
241
+ value: code,
242
+ label: name
243
+ })).sort((a, b) => a.label.localeCompare(b.label));
244
+ setCountries(countryOpts);
163
245
  setLoading(false);
164
246
  }).catch(() => {
165
247
  toast.error("Failed to load Brevo settings");
@@ -346,70 +428,25 @@ const BrevoSettingsPage = () => {
346
428
  ] }),
347
429
  /* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
348
430
  /* @__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." })
431
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies." }),
432
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
433
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_currencies", title: "Select Excluded Currencies", options: currencies }), children: "Select Currencies" }),
434
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
435
+ (settings.promotion_excluded_currencies || []).map((c) => /* @__PURE__ */ jsx(Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
436
+ (settings.promotion_excluded_currencies || []).length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
437
+ ] })
372
438
  ] })
373
439
  ] }),
374
440
  /* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
375
441
  /* @__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
- }) })
442
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Customers from these countries will NOT receive a promotion code." }),
443
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
444
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_countries", title: "Select Excluded Countries", options: countries }), children: "Select Countries" }),
445
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
446
+ (settings.promotion_excluded_countries || []).map((c) => /* @__PURE__ */ jsx(Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
447
+ (settings.promotion_excluded_countries || []).length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
448
+ ] })
449
+ ] })
413
450
  ] })
414
451
  ] })
415
452
  ] }) }),
@@ -592,29 +629,24 @@ const BrevoSettingsPage = () => {
592
629
  ] }),
593
630
  /* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
594
631
  /* @__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." })
632
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Discount will NOT apply to orders in these currencies." }),
633
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
634
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "abandoned_cart_discount_excluded_currencies", title: "Select Excluded Currencies", options: currencies }), children: "Select Currencies" }),
635
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
636
+ (settings.abandoned_cart_discount_excluded_currencies || []).map((c) => /* @__PURE__ */ jsx(Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
637
+ (settings.abandoned_cart_discount_excluded_currencies || []).length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
638
+ ] })
639
+ ] })
640
+ ] }),
641
+ /* @__PURE__ */ jsxs("div", { className: "col-span-2", children: [
642
+ /* @__PURE__ */ jsx(Label, { children: "Excluded Countries" }),
643
+ /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs mb-2", children: "Customers from these countries will NOT receive a discount code." }),
644
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mt-1", children: [
645
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", size: "small", onClick: () => setModal({ key: "promotion_excluded_countries", title: "Select Excluded Countries", options: countries }), children: "Select Countries" }),
646
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-1", children: [
647
+ (settings.promotion_excluded_countries || []).map((c) => /* @__PURE__ */ jsx(Badge, { color: "red", className: "font-mono text-xs", children: c.toUpperCase() }, c)),
648
+ (settings.promotion_excluded_countries || []).length === 0 && /* @__PURE__ */ jsx(Text, { className: "text-ui-fg-subtle text-xs", children: "None" })
649
+ ] })
618
650
  ] })
619
651
  ] })
620
652
  ] })
@@ -1006,7 +1038,17 @@ const BrevoSettingsPage = () => {
1006
1038
  )
1007
1039
  ] })
1008
1040
  ] })
1009
- ] }) })
1041
+ ] }) }),
1042
+ modal && settings && /* @__PURE__ */ jsx(
1043
+ MultiSelectModal,
1044
+ {
1045
+ title: modal.title,
1046
+ options: modal.options,
1047
+ selected: settings[modal.key] || [],
1048
+ onClose: () => setModal(null),
1049
+ onSave: (values) => update(modal.key, values)
1050
+ }
1051
+ )
1010
1052
  ] });
1011
1053
  };
1012
1054
  const config = defineRouteConfig({
@@ -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.3",
4
4
  "description": "Sending email notification using Brevo.",
5
5
  "author": "KB (https://medusajs.com)",
6
6
  "license": "MIT",