@vicacha-devs/strapi-plugin-broadcasts 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +15 -2
  3. package/dist/admin/BroadcastsHomePage-CM_N_spo.mjs +1210 -0
  4. package/dist/admin/BroadcastsHomePage-DQueM7nj.js +1228 -0
  5. package/dist/admin/SettingsPage-TawvAAiv.js +1187 -0
  6. package/dist/admin/SettingsPage-ikcb0cfh.mjs +1169 -0
  7. package/dist/admin/ar-vwekVqfp.js +232 -0
  8. package/dist/admin/ar-wZTCd3Za.mjs +232 -0
  9. package/dist/admin/de-IZicxuvv.mjs +232 -0
  10. package/dist/admin/de-Qa2SQQfY.js +232 -0
  11. package/dist/admin/en-B-HnZo8U.mjs +232 -0
  12. package/dist/admin/en-D1byrK0s.js +232 -0
  13. package/dist/admin/es-Co7PmAj8.mjs +232 -0
  14. package/dist/admin/es-Dgylqagv.js +232 -0
  15. package/dist/admin/fr-B9zZn3z1.mjs +232 -0
  16. package/dist/admin/fr-C7-MIWnw.js +232 -0
  17. package/dist/admin/index-CApLw9Uu.mjs +1036 -0
  18. package/dist/admin/index-Dw6J7U1v.js +1053 -0
  19. package/dist/admin/index.js +6 -0
  20. package/dist/admin/index.mjs +6 -0
  21. package/dist/admin/it-DJU9iBqT.mjs +232 -0
  22. package/dist/admin/it-D_mulZtx.js +232 -0
  23. package/dist/admin/pt-B9swwjPu.js +232 -0
  24. package/dist/admin/pt-Dr8u5we0.mjs +232 -0
  25. package/dist/admin/ru-B0NNiMNA.js +232 -0
  26. package/dist/admin/ru-Bd4cEKDV.mjs +232 -0
  27. package/dist/admin/selectOptions-BlvNrhvc.mjs +150 -0
  28. package/dist/admin/selectOptions-DuHQ0KK3.js +149 -0
  29. package/dist/admin/src/components/AutomationAndLogsTabs.d.ts +16 -0
  30. package/dist/admin/src/components/BridgesSandboxTab.d.ts +8 -0
  31. package/dist/admin/src/components/CampaignComposerForm.d.ts +26 -0
  32. package/dist/admin/src/components/CampaignsTableSection.d.ts +27 -0
  33. package/dist/admin/src/components/DeliveryLedgerSection.d.ts +17 -0
  34. package/dist/admin/src/components/Initializer.d.ts +6 -0
  35. package/dist/admin/src/components/OrganizationEmailTab.d.ts +10 -0
  36. package/dist/admin/src/components/PluginIcon.d.ts +3 -0
  37. package/dist/admin/src/components/WhatsAppTransportTab.d.ts +11 -0
  38. package/dist/admin/src/index.d.ts +24 -0
  39. package/dist/admin/src/pages/BroadcastsHomePage.d.ts +2 -0
  40. package/dist/admin/src/pages/SettingsPage.d.ts +3 -0
  41. package/dist/admin/src/permissions.d.ts +30 -0
  42. package/dist/admin/src/pluginId.d.ts +2 -0
  43. package/dist/admin/src/translations/cmLabels.d.ts +1 -0
  44. package/dist/admin/src/translations/cmLabelsExtra.d.ts +1 -0
  45. package/dist/admin/src/translations/cmPlaceholders.d.ts +1 -0
  46. package/dist/admin/src/translations/cmPlaceholdersExtra.d.ts +1 -0
  47. package/dist/admin/src/utils/extractApiError.d.ts +1 -0
  48. package/dist/admin/src/utils/selectOptions.d.ts +21 -0
  49. package/dist/admin/tr-Cc-ItZUP.js +232 -0
  50. package/dist/admin/tr-DlyHa2Vk.mjs +232 -0
  51. package/dist/admin/zh-CLzJ7x3y.mjs +232 -0
  52. package/dist/admin/zh-CaqwZk-p.js +232 -0
  53. package/dist/server/index.js +3399 -0
  54. package/dist/server/index.mjs +3399 -0
  55. package/dist/server/src/bootstrap.d.ts +5 -0
  56. package/dist/server/src/config/index.d.ts +5 -0
  57. package/dist/server/src/content-types/automation-rule/index.d.ts +90 -0
  58. package/dist/server/src/content-types/automation-rule/schema.json.d.ts +90 -0
  59. package/dist/server/src/content-types/campaign/index.d.ts +118 -0
  60. package/dist/server/src/content-types/campaign/schema.json.d.ts +118 -0
  61. package/dist/server/src/content-types/delivery-log/index.d.ts +71 -0
  62. package/dist/server/src/content-types/delivery-log/schema.json.d.ts +71 -0
  63. package/dist/server/src/content-types/index.d.ts +279 -0
  64. package/dist/server/src/controllers/broadcastController.d.ts +32 -0
  65. package/dist/server/src/controllers/index.d.ts +22 -0
  66. package/dist/server/src/destroy.d.ts +5 -0
  67. package/dist/server/src/eventHubRegistry.d.ts +5 -0
  68. package/dist/server/src/index.d.ts +463 -0
  69. package/dist/server/src/register.d.ts +5 -0
  70. package/dist/server/src/routes/admin.d.ts +17 -0
  71. package/dist/server/src/routes/content-api.d.ts +13 -0
  72. package/dist/server/src/routes/index.d.ts +31 -0
  73. package/dist/server/src/services/automationService.d.ts +33 -0
  74. package/dist/server/src/services/campaignChannelDispatch.d.ts +20 -0
  75. package/dist/server/src/services/campaignHelpers.d.ts +20 -0
  76. package/dist/server/src/services/campaignLifecycle.d.ts +23 -0
  77. package/dist/server/src/services/campaignService.d.ts +54 -0
  78. package/dist/server/src/services/deliveryLedger.d.ts +18 -0
  79. package/dist/server/src/services/emailDesignerBridge.d.ts +30 -0
  80. package/dist/server/src/services/idempotency.d.ts +5 -0
  81. package/dist/server/src/services/index.d.ts +119 -0
  82. package/dist/server/src/services/settings.d.ts +12 -0
  83. package/dist/server/src/services/transportService.d.ts +70 -0
  84. package/dist/shared/index.d.ts +1 -0
  85. package/dist/shared/index.js +825 -0
  86. package/dist/shared/index.mjs +823 -0
  87. package/package.json +109 -3
@@ -0,0 +1,1169 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Box, Flex, Typography, Badge, Field, TextInput, SingleSelect, SingleSelectOption, MultiSelect, MultiSelectOption, Checkbox, Main, Button, Tabs } from "@strapi/design-system";
3
+ import { useFetchClient } from "@strapi/strapi/admin";
4
+ import * as React from "react";
5
+ import { useIntl } from "react-intl";
6
+ import { m as mergeSelectOptions, L as LOCALE_OPTIONS, p as parseCsvList, D as DEFAULT_BROADCAST_SETTINGS, P as PLUGIN_ID } from "./index-CApLw9Uu.mjs";
7
+ import { g as getBroadcastTopicOptions, b as getWhatsAppDriverOptions, e as extractApiErrorMessage } from "./selectOptions-BlvNrhvc.mjs";
8
+ const orgEmailCardBorderStyle = {
9
+ border: "1px solid rgba(128, 128, 128, 0.22)",
10
+ borderTopLeftRadius: 0,
11
+ borderTopRightRadius: 0
12
+ };
13
+ const OrganizationEmailTab = ({
14
+ settings,
15
+ setSettings,
16
+ t
17
+ }) => {
18
+ const localeOpts = mergeSelectOptions(
19
+ LOCALE_OPTIONS,
20
+ settings.supportedLocales
21
+ );
22
+ const topicOpts = mergeSelectOptions(
23
+ getBroadcastTopicOptions(t),
24
+ settings.availableTopics
25
+ );
26
+ return /* @__PURE__ */ jsxs(
27
+ Box,
28
+ {
29
+ padding: 6,
30
+ background: "neutral0",
31
+ hasRadius: true,
32
+ shadow: "filterShadow",
33
+ style: orgEmailCardBorderStyle,
34
+ children: [
35
+ /* @__PURE__ */ jsxs(
36
+ Flex,
37
+ {
38
+ justifyContent: "space-between",
39
+ alignItems: "center",
40
+ paddingBottom: 2,
41
+ wrap: "wrap",
42
+ gap: 2,
43
+ children: [
44
+ /* @__PURE__ */ jsxs(Box, { children: [
45
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", children: t(
46
+ "settings.ui.1_organization_multi_language_email_hijri_calend",
47
+ "Organization, Multi-Language & Email"
48
+ ) }),
49
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
50
+ "settings.ui.configure_organization_identity_sender_reply_to_",
51
+ "Configure organization identity, sender/reply-to email addresses, supported locales, and broadcast topic segments."
52
+ ) })
53
+ ] }),
54
+ /* @__PURE__ */ jsxs(Badge, { children: [
55
+ (settings.supportedLocales || []).length,
56
+ " ",
57
+ t("settings.ui.active_locales_label", "Active Locales")
58
+ ] })
59
+ ]
60
+ }
61
+ ),
62
+ /* @__PURE__ */ jsxs(
63
+ Box,
64
+ {
65
+ paddingTop: 4,
66
+ style: {
67
+ display: "grid",
68
+ gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
69
+ gap: 20
70
+ },
71
+ children: [
72
+ /* @__PURE__ */ jsxs(
73
+ Field.Root,
74
+ {
75
+ name: "organizationName",
76
+ hint: t(
77
+ "settings.ui.organization_name_hint",
78
+ "Injected into broadcast templates via the '{{organizationName}}' variable."
79
+ ),
80
+ children: [
81
+ /* @__PURE__ */ jsx(Field.Label, { children: t("field.organization_name", "Organization Name") }),
82
+ /* @__PURE__ */ jsx(
83
+ TextInput,
84
+ {
85
+ name: "organizationName",
86
+ placeholder: t(
87
+ "placeholder.e_g_mezquita_central_abu_bakr_as_siddiq_bogot",
88
+ "e.g., Abu Bakr As-Siddiq Central Mosque — Bogotá"
89
+ ),
90
+ value: settings.organizationName || "",
91
+ onChange: (e) => setSettings({ ...settings, organizationName: e.target.value })
92
+ }
93
+ ),
94
+ /* @__PURE__ */ jsx(Field.Hint, {})
95
+ ]
96
+ }
97
+ ),
98
+ /* @__PURE__ */ jsxs(
99
+ Field.Root,
100
+ {
101
+ name: "siteBaseUrl",
102
+ hint: t(
103
+ "settings.ui.site_base_url_hint",
104
+ "Base URL used for CTA links, 1-click unsubscribe links, and '{{siteBaseUrl}}' placeholders."
105
+ ),
106
+ children: [
107
+ /* @__PURE__ */ jsx(Field.Label, { children: t("field.public_site_base_url", "Public Site Base URL") }),
108
+ /* @__PURE__ */ jsx(
109
+ TextInput,
110
+ {
111
+ name: "siteBaseUrl",
112
+ placeholder: t(
113
+ "placeholder.e_g_https_mezquitabogota_org",
114
+ "e.g., https://mezquitabogota.org"
115
+ ),
116
+ value: settings.siteBaseUrl || "",
117
+ onChange: (e) => setSettings({ ...settings, siteBaseUrl: e.target.value })
118
+ }
119
+ ),
120
+ /* @__PURE__ */ jsx(Field.Hint, {})
121
+ ]
122
+ }
123
+ ),
124
+ /* @__PURE__ */ jsxs(
125
+ Field.Root,
126
+ {
127
+ name: "emailFromAddress",
128
+ hint: t(
129
+ "settings.ui.verified_sender_address_used_when_dispatching_em",
130
+ "Verified sender address used when dispatching email newsletters and bulletins."
131
+ ),
132
+ children: [
133
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
134
+ "field.email_sender_from_address",
135
+ "Email Sender (From Address)"
136
+ ) }),
137
+ /* @__PURE__ */ jsx(
138
+ TextInput,
139
+ {
140
+ name: "emailFromAddress",
141
+ placeholder: t(
142
+ "placeholder.e_g_no_reply_mezquitabogota_org",
143
+ "e.g., no-reply@mezquitabogota.org"
144
+ ),
145
+ value: settings.emailFromAddress || "",
146
+ onChange: (e) => setSettings({ ...settings, emailFromAddress: e.target.value })
147
+ }
148
+ ),
149
+ /* @__PURE__ */ jsx(Field.Hint, {})
150
+ ]
151
+ }
152
+ ),
153
+ /* @__PURE__ */ jsxs(
154
+ Field.Root,
155
+ {
156
+ name: "emailReplyToAddress",
157
+ hint: t(
158
+ "settings.ui.reply_to_inbox_where_community_members_can_respo",
159
+ "Reply-to inbox where community members can respond to email broadcasts."
160
+ ),
161
+ children: [
162
+ /* @__PURE__ */ jsx(Field.Label, { children: t("field.email_reply_to_address", "Email Reply-To Address") }),
163
+ /* @__PURE__ */ jsx(
164
+ TextInput,
165
+ {
166
+ name: "emailReplyToAddress",
167
+ placeholder: t(
168
+ "placeholder.e_g_info_mezquitabogota_org",
169
+ "e.g., info@mezquitabogota.org"
170
+ ),
171
+ value: settings.emailReplyToAddress || "",
172
+ onChange: (e) => setSettings({ ...settings, emailReplyToAddress: e.target.value })
173
+ }
174
+ ),
175
+ /* @__PURE__ */ jsx(Field.Hint, {})
176
+ ]
177
+ }
178
+ ),
179
+ /* @__PURE__ */ jsxs(
180
+ Field.Root,
181
+ {
182
+ name: "defaultLocale",
183
+ hint: t(
184
+ "settings.ui.fallback_language_when_a_recipient_does_not_have",
185
+ "Fallback language when a recipient does not have a preferred locale on file."
186
+ ),
187
+ children: [
188
+ /* @__PURE__ */ jsx(Field.Label, { children: t("field.default_broadcast_locale", "Default Broadcast Locale") }),
189
+ /* @__PURE__ */ jsx(
190
+ SingleSelect,
191
+ {
192
+ placeholder: t(
193
+ "placeholder.select_default_locale",
194
+ "Select default locale"
195
+ ),
196
+ value: settings.defaultLocale || "es",
197
+ onChange: (val) => setSettings({ ...settings, defaultLocale: String(val) }),
198
+ children: localeOpts.map((opt) => /* @__PURE__ */ jsx(SingleSelectOption, { value: opt.value, children: opt.label }, opt.value))
199
+ }
200
+ ),
201
+ /* @__PURE__ */ jsx(Field.Hint, {})
202
+ ]
203
+ }
204
+ ),
205
+ /* @__PURE__ */ jsxs(
206
+ Field.Root,
207
+ {
208
+ name: "supportedLocales",
209
+ hint: t(
210
+ "settings.ui.languages_enabled_for_localized_campaign_subject",
211
+ "Languages enabled for localized campaign subject/body templates."
212
+ ),
213
+ children: [
214
+ /* @__PURE__ */ jsx(Field.Label, { children: t("field.supported_locales", "Supported Locales") }),
215
+ /* @__PURE__ */ jsx(
216
+ MultiSelect,
217
+ {
218
+ name: "supportedLocales",
219
+ withTags: true,
220
+ placeholder: t(
221
+ "placeholder.select_supported_locales",
222
+ "Select supported locales..."
223
+ ),
224
+ value: settings.supportedLocales || ["es", "en", "ar", "tr"],
225
+ onChange: (nextValues) => setSettings({
226
+ ...settings,
227
+ supportedLocales: nextValues.length > 0 ? nextValues : ["es"]
228
+ }),
229
+ onClear: () => setSettings({
230
+ ...settings,
231
+ supportedLocales: ["es"]
232
+ }),
233
+ children: localeOpts.map((opt) => /* @__PURE__ */ jsx(MultiSelectOption, { value: opt.value, children: opt.label }, opt.value))
234
+ }
235
+ ),
236
+ /* @__PURE__ */ jsx(Field.Hint, {})
237
+ ]
238
+ }
239
+ ),
240
+ /* @__PURE__ */ jsx(Box, { style: { gridColumn: "span 2" }, children: /* @__PURE__ */ jsxs(
241
+ Field.Root,
242
+ {
243
+ name: "availableTopics",
244
+ hint: t(
245
+ "settings.ui.topic_segments_used_to_target_confirmed_subscrib",
246
+ "Topic segments used to target confirmed subscribers and Telegram forum threads."
247
+ ),
248
+ children: [
249
+ /* @__PURE__ */ jsx(Field.Label, { children: t("field.broadcast_topic_segments", "Broadcast Topic Segments") }),
250
+ /* @__PURE__ */ jsx(
251
+ MultiSelect,
252
+ {
253
+ name: "availableTopics",
254
+ withTags: true,
255
+ placeholder: t(
256
+ "placeholder.select_broadcast_topic_segments",
257
+ "Select broadcast topic segments..."
258
+ ),
259
+ value: settings.availableTopics || ["announcements"],
260
+ onChange: (nextValues) => setSettings({
261
+ ...settings,
262
+ availableTopics: nextValues.length > 0 ? nextValues : ["announcements"]
263
+ }),
264
+ onClear: () => setSettings({
265
+ ...settings,
266
+ availableTopics: ["announcements"]
267
+ }),
268
+ children: topicOpts.map((opt) => /* @__PURE__ */ jsx(MultiSelectOption, { value: opt.value, children: opt.label }, opt.value))
269
+ }
270
+ ),
271
+ /* @__PURE__ */ jsx(Field.Hint, {})
272
+ ]
273
+ }
274
+ ) }),
275
+ /* @__PURE__ */ jsxs(
276
+ Field.Root,
277
+ {
278
+ name: "defaultEmailTemplateRef",
279
+ hint: t(
280
+ "settings.ui.default_email_template_ref_hint",
281
+ "Optional default Email Designer 5 template ID or base name used when a campaign does not specify its own template."
282
+ ),
283
+ children: [
284
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
285
+ "field.default_email_template_ref",
286
+ "Default Email Designer Template Ref (optional)"
287
+ ) }),
288
+ /* @__PURE__ */ jsx(
289
+ TextInput,
290
+ {
291
+ name: "defaultEmailTemplateRef",
292
+ placeholder: t(
293
+ "placeholder.e_g_401_or_broadcastnewsletter",
294
+ "e.g., 401 or broadcastNewsletter"
295
+ ),
296
+ value: settings.defaultEmailTemplateRef || "",
297
+ onChange: (e) => setSettings({
298
+ ...settings,
299
+ defaultEmailTemplateRef: e.target.value
300
+ })
301
+ }
302
+ ),
303
+ /* @__PURE__ */ jsx(Field.Hint, {})
304
+ ]
305
+ }
306
+ )
307
+ ]
308
+ }
309
+ )
310
+ ]
311
+ }
312
+ );
313
+ };
314
+ const cardBorderStyle$2 = {
315
+ border: "1px solid rgba(128, 128, 128, 0.22)",
316
+ borderTopLeftRadius: 0,
317
+ borderTopRightRadius: 0
318
+ };
319
+ const subCardStyle = {
320
+ border: "1px solid rgba(128, 128, 128, 0.22)",
321
+ display: "flex",
322
+ flexDirection: "column",
323
+ justifyContent: "space-between"
324
+ };
325
+ const BridgesSandboxTab = ({
326
+ settings,
327
+ setSettings,
328
+ t
329
+ }) => {
330
+ const enabledText = t("common.enabled", "Enabled");
331
+ const disabledText = t("common.disabled", "Disabled");
332
+ return /* @__PURE__ */ jsxs(
333
+ Box,
334
+ {
335
+ padding: 6,
336
+ background: "neutral0",
337
+ hasRadius: true,
338
+ shadow: "filterShadow",
339
+ style: cardBorderStyle$2,
340
+ children: [
341
+ /* @__PURE__ */ jsxs(
342
+ Flex,
343
+ {
344
+ justifyContent: "space-between",
345
+ alignItems: "center",
346
+ paddingBottom: 2,
347
+ wrap: "wrap",
348
+ gap: 2,
349
+ children: [
350
+ /* @__PURE__ */ jsxs(Box, { children: [
351
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", children: t(
352
+ "settings.ui.4_ecosystem_bridges_sandbox_mode",
353
+ "Ecosystem Bridges & Sandbox Mode"
354
+ ) }),
355
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
356
+ "settings.ui.bridges_sandbox_subtitle",
357
+ "Control dry-run simulation mode, subscriber segmentation from @vicacha-devs/strapi-plugin-inbox, Email Designer 5 HTML templates, and automatic EventHub triggers."
358
+ ) })
359
+ ] }),
360
+ /* @__PURE__ */ jsx(Badge, { children: settings.dryRun ? t("settings.ui.sandbox_mode_active", "Sandbox Mode Active") : t("settings.ui.live_production_mode", "Live Production Mode") })
361
+ ]
362
+ }
363
+ ),
364
+ /* @__PURE__ */ jsxs(
365
+ Box,
366
+ {
367
+ paddingTop: 4,
368
+ style: {
369
+ display: "grid",
370
+ gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))",
371
+ gap: 16
372
+ },
373
+ children: [
374
+ /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral100", hasRadius: true, style: subCardStyle, children: [
375
+ /* @__PURE__ */ jsxs(Box, { children: [
376
+ /* @__PURE__ */ jsxs(
377
+ Flex,
378
+ {
379
+ justifyContent: "space-between",
380
+ alignItems: "center",
381
+ paddingBottom: 2,
382
+ children: [
383
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: t("settings.ui.dry_run_sandbox_mode", "Dry-Run Sandbox Mode") }),
384
+ /* @__PURE__ */ jsx(Badge, { children: settings.dryRun ? t("settings.ui.simulated", "Simulated") : t("settings.ui.live", "Live") })
385
+ ]
386
+ }
387
+ ),
388
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
389
+ "settings.ui.dry_run_description",
390
+ "Records full delivery logs and idempotency keys with status simulated without calling external Email, Telegram, or WhatsApp APIs."
391
+ ) })
392
+ ] }),
393
+ /* @__PURE__ */ jsx(Box, { paddingTop: 3, children: /* @__PURE__ */ jsx(
394
+ Checkbox,
395
+ {
396
+ checked: Boolean(settings.dryRun),
397
+ onCheckedChange: (checked) => setSettings({ ...settings, dryRun: Boolean(checked) }),
398
+ children: t(
399
+ "checkbox.enable_dry_run_sandbox_mode",
400
+ "Enable Dry-Run Sandbox Mode"
401
+ )
402
+ }
403
+ ) })
404
+ ] }),
405
+ /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral100", hasRadius: true, style: subCardStyle, children: [
406
+ /* @__PURE__ */ jsxs(Box, { children: [
407
+ /* @__PURE__ */ jsxs(
408
+ Flex,
409
+ {
410
+ justifyContent: "space-between",
411
+ alignItems: "center",
412
+ paddingBottom: 2,
413
+ children: [
414
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: t(
415
+ "settings.ui.inbox_subscriber_bridge",
416
+ "Inbox Subscriber Bridge"
417
+ ) }),
418
+ /* @__PURE__ */ jsx(Badge, { children: settings.enableInboxSubscriberBridge ? enabledText : disabledText })
419
+ ]
420
+ }
421
+ ),
422
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
423
+ "settings.ui.inbox_bridge_description",
424
+ "Automatically queries confirmed double opt-in subscribers from @vicacha-devs/strapi-plugin-inbox segmented by topic and locale."
425
+ ) })
426
+ ] }),
427
+ /* @__PURE__ */ jsx(Box, { paddingTop: 3, children: /* @__PURE__ */ jsx(
428
+ Checkbox,
429
+ {
430
+ checked: Boolean(settings.enableInboxSubscriberBridge),
431
+ onCheckedChange: (checked) => setSettings({
432
+ ...settings,
433
+ enableInboxSubscriberBridge: Boolean(checked)
434
+ }),
435
+ children: t(
436
+ "checkbox.segment_confirmed_subscribers_via_inbox_bridge",
437
+ "Segment confirmed subscribers via Inbox Bridge"
438
+ )
439
+ }
440
+ ) })
441
+ ] }),
442
+ /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral100", hasRadius: true, style: subCardStyle, children: [
443
+ /* @__PURE__ */ jsxs(Box, { children: [
444
+ /* @__PURE__ */ jsxs(
445
+ Flex,
446
+ {
447
+ justifyContent: "space-between",
448
+ alignItems: "center",
449
+ paddingBottom: 2,
450
+ children: [
451
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: t(
452
+ "settings.ui.eventhub_auto_broadcasts",
453
+ "EventHub Auto-Broadcasts"
454
+ ) }),
455
+ /* @__PURE__ */ jsx(Badge, { children: settings.enableEventHubAutomations ? enabledText : disabledText })
456
+ ]
457
+ }
458
+ ),
459
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
460
+ "settings.ui.eventhub_bridge_description",
461
+ "Listens for Strapi EventHub events (e.g., inbox.alert.published, event.published) and triggers matching automation rules automatically."
462
+ ) })
463
+ ] }),
464
+ /* @__PURE__ */ jsx(Box, { paddingTop: 3, children: /* @__PURE__ */ jsx(
465
+ Checkbox,
466
+ {
467
+ checked: Boolean(settings.enableEventHubAutomations),
468
+ onCheckedChange: (checked) => setSettings({
469
+ ...settings,
470
+ enableEventHubAutomations: Boolean(checked)
471
+ }),
472
+ children: t(
473
+ "checkbox.enable_eventhub_auto_broadcast_triggers",
474
+ "Enable EventHub Auto-Broadcast Triggers"
475
+ )
476
+ }
477
+ ) })
478
+ ] }),
479
+ /* @__PURE__ */ jsxs(Box, { padding: 4, background: "neutral100", hasRadius: true, style: subCardStyle, children: [
480
+ /* @__PURE__ */ jsxs(Box, { children: [
481
+ /* @__PURE__ */ jsxs(
482
+ Flex,
483
+ {
484
+ justifyContent: "space-between",
485
+ alignItems: "center",
486
+ paddingBottom: 2,
487
+ children: [
488
+ /* @__PURE__ */ jsx(Typography, { fontWeight: "bold", children: t(
489
+ "settings.ui.email_designer_html_templates",
490
+ "Email Designer 5 HTML Templates"
491
+ ) }),
492
+ /* @__PURE__ */ jsx(Badge, { children: settings.enableEmailDesignerBridge !== false ? enabledText : disabledText })
493
+ ]
494
+ }
495
+ ),
496
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
497
+ "settings.ui.email_designer_bridge_description",
498
+ "Optionally renders email broadcasts through strapi-plugin-email-designer-5 with automatic locale matching (es/en/ar/tr) and fallback to inline HTML."
499
+ ) })
500
+ ] }),
501
+ /* @__PURE__ */ jsx(Box, { paddingTop: 3, children: /* @__PURE__ */ jsx(
502
+ Checkbox,
503
+ {
504
+ checked: settings.enableEmailDesignerBridge !== false,
505
+ onCheckedChange: (checked) => setSettings({
506
+ ...settings,
507
+ enableEmailDesignerBridge: Boolean(checked)
508
+ }),
509
+ children: t(
510
+ "checkbox.enable_email_designer_5_html_template_bridge",
511
+ "Enable Email Designer 5 HTML Template Bridge"
512
+ )
513
+ }
514
+ ) })
515
+ ] })
516
+ ]
517
+ }
518
+ )
519
+ ]
520
+ }
521
+ );
522
+ };
523
+ const cardBorderStyle$1 = {
524
+ border: "1px solid rgba(128, 128, 128, 0.22)",
525
+ borderTopLeftRadius: 0,
526
+ borderTopRightRadius: 0
527
+ };
528
+ const WhatsAppDefaultRecipientsField = ({
529
+ settings,
530
+ setSettings,
531
+ t
532
+ }) => {
533
+ const canonicalRecipients = (settings.whatsappDefaultRecipients || []).join(
534
+ ", "
535
+ );
536
+ const [recipientsDraft, setRecipientsDraft] = React.useState(canonicalRecipients);
537
+ React.useEffect(() => {
538
+ setRecipientsDraft(
539
+ (prev) => parseCsvList(prev).join(", ") === canonicalRecipients ? prev : canonicalRecipients
540
+ );
541
+ }, [canonicalRecipients]);
542
+ return /* @__PURE__ */ jsxs(
543
+ Field.Root,
544
+ {
545
+ name: "whatsappDefaultRecipients",
546
+ hint: t(
547
+ "settings.ui.whatsapp_default_recipients_hint",
548
+ "WhatsApp Group JIDs (@g.us), Channel JIDs (@newsletter), or E.164 phone numbers that receive WhatsApp broadcasts alongside topic subscribers."
549
+ ),
550
+ children: [
551
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
552
+ "field.whatsapp_default_recipients",
553
+ "Default WhatsApp Groups / Channels / Numbers (comma-separated)"
554
+ ) }),
555
+ /* @__PURE__ */ jsx(
556
+ TextInput,
557
+ {
558
+ name: "whatsappDefaultRecipients",
559
+ placeholder: t(
560
+ "placeholder.whatsapp_default_recipients",
561
+ "e.g., 120363025891234567@g.us, 120363099999999999@newsletter, +573101234567"
562
+ ),
563
+ value: recipientsDraft,
564
+ onChange: (e) => {
565
+ const nextRaw = e.target.value;
566
+ setRecipientsDraft(nextRaw);
567
+ setSettings({
568
+ ...settings,
569
+ whatsappDefaultRecipients: parseCsvList(nextRaw)
570
+ });
571
+ },
572
+ onBlur: () => setRecipientsDraft(canonicalRecipients)
573
+ }
574
+ ),
575
+ /* @__PURE__ */ jsx(Field.Hint, {})
576
+ ]
577
+ }
578
+ );
579
+ };
580
+ const WhatsAppTransportTab = ({
581
+ settings,
582
+ setSettings,
583
+ t
584
+ }) => {
585
+ const driverOptions = getWhatsAppDriverOptions(t);
586
+ return /* @__PURE__ */ jsxs(
587
+ Box,
588
+ {
589
+ padding: 6,
590
+ background: "neutral0",
591
+ hasRadius: true,
592
+ shadow: "filterShadow",
593
+ style: cardBorderStyle$1,
594
+ children: [
595
+ /* @__PURE__ */ jsxs(
596
+ Flex,
597
+ {
598
+ justifyContent: "space-between",
599
+ alignItems: "center",
600
+ paddingBottom: 2,
601
+ wrap: "wrap",
602
+ gap: 2,
603
+ children: [
604
+ /* @__PURE__ */ jsxs(Box, { children: [
605
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", children: t(
606
+ "settings.ui.3_whatsapp_transport_meta_cloud_api_evolution_op",
607
+ "WhatsApp Transport (Meta Cloud API / Evolution / OpenWA)"
608
+ ) }),
609
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
610
+ "settings.ui.configure_official_meta_whatsapp_business_cloud_",
611
+ "Configure official Meta WhatsApp Business Cloud API (WABA) or self-hosted Evolution / OpenWA gateways with SSRF protection."
612
+ ) })
613
+ ] }),
614
+ /* @__PURE__ */ jsx(
615
+ Checkbox,
616
+ {
617
+ checked: Boolean(settings.whatsappEnabled),
618
+ onCheckedChange: (checked) => setSettings({ ...settings, whatsappEnabled: Boolean(checked) }),
619
+ children: t("checkbox.enable_whatsapp_transport", "Enable WhatsApp Transport")
620
+ }
621
+ )
622
+ ]
623
+ }
624
+ ),
625
+ /* @__PURE__ */ jsxs(
626
+ Box,
627
+ {
628
+ paddingTop: 4,
629
+ style: {
630
+ display: "grid",
631
+ gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
632
+ gap: 20
633
+ },
634
+ children: [
635
+ /* @__PURE__ */ jsxs(
636
+ Field.Root,
637
+ {
638
+ name: "whatsappDriver",
639
+ hint: t(
640
+ "settings.ui.choose_meta_cloud_api_for_official_templates_or_",
641
+ "Choose Meta Cloud API for official templates or Evolution/OpenWA for self-hosted gateways."
642
+ ),
643
+ children: [
644
+ /* @__PURE__ */ jsx(Field.Label, { children: t("field.whatsapp_transport_driver", "WhatsApp Transport Driver") }),
645
+ /* @__PURE__ */ jsx(
646
+ SingleSelect,
647
+ {
648
+ placeholder: t(
649
+ "placeholder.select_whatsapp_driver",
650
+ "Select WhatsApp driver"
651
+ ),
652
+ value: settings.whatsappDriver || "meta-cloud",
653
+ onChange: (val) => setSettings({
654
+ ...settings,
655
+ whatsappDriver: String(val)
656
+ }),
657
+ children: driverOptions.map((opt) => /* @__PURE__ */ jsx(SingleSelectOption, { value: opt.value, children: opt.label }, opt.value))
658
+ }
659
+ ),
660
+ /* @__PURE__ */ jsx(Field.Hint, {})
661
+ ]
662
+ }
663
+ ),
664
+ /* @__PURE__ */ jsxs(
665
+ Field.Root,
666
+ {
667
+ name: "whatsappPhoneNumberId",
668
+ hint: t(
669
+ "settings.ui.meta_phone_number_id_hint",
670
+ "Numeric Phone Number ID from Meta Developer Console (used when driver is meta-cloud)."
671
+ ),
672
+ children: [
673
+ /* @__PURE__ */ jsx(Field.Label, { children: t("field.meta_waba_phone_number_id", "Meta WABA Phone Number ID") }),
674
+ /* @__PURE__ */ jsx(
675
+ TextInput,
676
+ {
677
+ name: "whatsappPhoneNumberId",
678
+ placeholder: t(
679
+ "placeholder.e_g_109876543210123",
680
+ "e.g., 109876543210123"
681
+ ),
682
+ value: settings.whatsappPhoneNumberId || "",
683
+ onChange: (e) => setSettings({
684
+ ...settings,
685
+ whatsappPhoneNumberId: e.target.value
686
+ })
687
+ }
688
+ ),
689
+ /* @__PURE__ */ jsx(Field.Hint, {})
690
+ ]
691
+ }
692
+ ),
693
+ /* @__PURE__ */ jsxs(
694
+ Field.Root,
695
+ {
696
+ name: "whatsappAccessToken",
697
+ hint: t(
698
+ "settings.ui.system_user_bearer_token_for_graph_facebook_com_",
699
+ "System user bearer token for graph.facebook.com WABA message dispatch."
700
+ ),
701
+ children: [
702
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
703
+ "field.meta_cloud_api_permanent_access_token",
704
+ "Meta Cloud API Permanent Access Token"
705
+ ) }),
706
+ /* @__PURE__ */ jsx(
707
+ TextInput,
708
+ {
709
+ name: "whatsappAccessToken",
710
+ type: "password",
711
+ placeholder: t(
712
+ "placeholder.e_g_eaagm0px4zcpsba",
713
+ "e.g., EAAGm0PX4ZCpsBA..."
714
+ ),
715
+ value: settings.whatsappAccessToken || "",
716
+ onChange: (e) => setSettings({
717
+ ...settings,
718
+ whatsappAccessToken: e.target.value
719
+ })
720
+ }
721
+ ),
722
+ /* @__PURE__ */ jsx(Field.Hint, {})
723
+ ]
724
+ }
725
+ ),
726
+ /* @__PURE__ */ jsxs(
727
+ Field.Root,
728
+ {
729
+ name: "whatsappGatewayUrl",
730
+ hint: t(
731
+ "settings.ui.https_base_url_of_your_evolution_api_or_openwa_i",
732
+ "HTTPS base URL of your Evolution API or OpenWA instance (validated against SSRF rules)."
733
+ ),
734
+ children: [
735
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
736
+ "field.self_hosted_gateway_url_evolution_openwa",
737
+ "Self-Hosted Gateway URL (Evolution / OpenWA)"
738
+ ) }),
739
+ /* @__PURE__ */ jsx(
740
+ TextInput,
741
+ {
742
+ name: "whatsappGatewayUrl",
743
+ placeholder: t(
744
+ "placeholder.e_g_https_wa_gateway_mezquitabogota_org",
745
+ "e.g., https://wa-gateway.mezquitabogota.org"
746
+ ),
747
+ value: settings.whatsappGatewayUrl || "",
748
+ onChange: (e) => setSettings({ ...settings, whatsappGatewayUrl: e.target.value })
749
+ }
750
+ ),
751
+ /* @__PURE__ */ jsx(Field.Hint, {})
752
+ ]
753
+ }
754
+ ),
755
+ /* @__PURE__ */ jsxs(
756
+ Field.Root,
757
+ {
758
+ name: "whatsappGatewaySession",
759
+ hint: t(
760
+ "settings.ui.session_or_instance_identifier_on_the_self_hoste",
761
+ "Session or instance identifier on the self-hosted WhatsApp gateway."
762
+ ),
763
+ children: [
764
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
765
+ "field.gateway_instance_session_name",
766
+ "Gateway Instance / Session Name"
767
+ ) }),
768
+ /* @__PURE__ */ jsx(
769
+ TextInput,
770
+ {
771
+ name: "whatsappGatewaySession",
772
+ placeholder: t(
773
+ "placeholder.e_g_default_or_mezquita_bogota",
774
+ "e.g., default or mezquita-bogota"
775
+ ),
776
+ value: settings.whatsappGatewaySession || "",
777
+ onChange: (e) => setSettings({
778
+ ...settings,
779
+ whatsappGatewaySession: e.target.value
780
+ })
781
+ }
782
+ ),
783
+ /* @__PURE__ */ jsx(Field.Hint, {})
784
+ ]
785
+ }
786
+ ),
787
+ /* @__PURE__ */ jsxs(
788
+ Field.Root,
789
+ {
790
+ name: "whatsappGatewayApiKey",
791
+ hint: t(
792
+ "settings.ui.api_key_sent_via_apikey_authorization_header_to_",
793
+ "API key sent via apikey / Authorization header to the self-hosted gateway."
794
+ ),
795
+ children: [
796
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
797
+ "field.gateway_api_key_evolution_openwa",
798
+ "Gateway API Key (Evolution / OpenWA)"
799
+ ) }),
800
+ /* @__PURE__ */ jsx(
801
+ TextInput,
802
+ {
803
+ name: "whatsappGatewayApiKey",
804
+ type: "password",
805
+ placeholder: t(
806
+ "placeholder.e_g_evo_live_key",
807
+ "e.g., evo_live_key_..."
808
+ ),
809
+ value: settings.whatsappGatewayApiKey || "",
810
+ onChange: (e) => setSettings({
811
+ ...settings,
812
+ whatsappGatewayApiKey: e.target.value
813
+ })
814
+ }
815
+ ),
816
+ /* @__PURE__ */ jsx(Field.Hint, {})
817
+ ]
818
+ }
819
+ ),
820
+ /* @__PURE__ */ jsx(
821
+ WhatsAppDefaultRecipientsField,
822
+ {
823
+ settings,
824
+ setSettings,
825
+ t
826
+ }
827
+ )
828
+ ]
829
+ }
830
+ )
831
+ ]
832
+ }
833
+ );
834
+ };
835
+ const cardBorderStyle = {
836
+ border: "1px solid rgba(128, 128, 128, 0.22)",
837
+ borderTopLeftRadius: 0,
838
+ borderTopRightRadius: 0
839
+ };
840
+ const TelegramTransportTab = ({
841
+ settings,
842
+ setSettings,
843
+ t
844
+ }) => /* @__PURE__ */ jsxs(
845
+ Box,
846
+ {
847
+ padding: 6,
848
+ background: "neutral0",
849
+ hasRadius: true,
850
+ shadow: "filterShadow",
851
+ style: cardBorderStyle,
852
+ children: [
853
+ /* @__PURE__ */ jsxs(
854
+ Flex,
855
+ {
856
+ justifyContent: "space-between",
857
+ alignItems: "center",
858
+ paddingBottom: 2,
859
+ wrap: "wrap",
860
+ gap: 2,
861
+ children: [
862
+ /* @__PURE__ */ jsxs(Box, { children: [
863
+ /* @__PURE__ */ jsx(Typography, { variant: "beta", tag: "h2", children: t(
864
+ "settings.ui.2_telegram_bot_channel_forum_topic_configuration",
865
+ "Telegram Bot & Channel / Forum Topic Configuration"
866
+ ) }),
867
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: t(
868
+ "settings.ui.dispatch_announcements_to_your_official_telegram",
869
+ "Dispatch announcements to your official Telegram channel or supergroup forum topics via the Telegram Bot API."
870
+ ) })
871
+ ] }),
872
+ /* @__PURE__ */ jsx(
873
+ Checkbox,
874
+ {
875
+ checked: Boolean(settings.telegramEnabled),
876
+ onCheckedChange: (checked) => setSettings({ ...settings, telegramEnabled: Boolean(checked) }),
877
+ children: t("checkbox.enable_telegram_transport", "Enable Telegram Transport")
878
+ }
879
+ )
880
+ ]
881
+ }
882
+ ),
883
+ /* @__PURE__ */ jsxs(
884
+ Box,
885
+ {
886
+ paddingTop: 4,
887
+ style: {
888
+ display: "grid",
889
+ gridTemplateColumns: "repeat(2, minmax(0, 1fr))",
890
+ gap: 20
891
+ },
892
+ children: [
893
+ /* @__PURE__ */ jsxs(
894
+ Field.Root,
895
+ {
896
+ name: "telegramDefaultChatId",
897
+ hint: t(
898
+ "settings.ui.public_channel_handle_mezquitacentralbogota_or_n",
899
+ "Public channel handle (@MezquitaCentralBogota) or numeric supergroup ID (-100...)."
900
+ ),
901
+ children: [
902
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
903
+ "field.default_channel_handle_or_supergroup_chat_id",
904
+ "Default Channel Handle or Supergroup Chat ID"
905
+ ) }),
906
+ /* @__PURE__ */ jsx(
907
+ TextInput,
908
+ {
909
+ name: "telegramDefaultChatId",
910
+ placeholder: t(
911
+ "placeholder.e_g_mezquitacentralbogota_or_1001234567890",
912
+ "e.g., @MezquitaCentralBogota or -1001234567890"
913
+ ),
914
+ value: settings.telegramDefaultChatId || "",
915
+ onChange: (e) => setSettings({
916
+ ...settings,
917
+ telegramDefaultChatId: e.target.value
918
+ })
919
+ }
920
+ ),
921
+ /* @__PURE__ */ jsx(Field.Hint, {})
922
+ ]
923
+ }
924
+ ),
925
+ /* @__PURE__ */ jsxs(
926
+ Field.Root,
927
+ {
928
+ name: "telegramBotToken",
929
+ hint: t(
930
+ "settings.ui.bot_token_with_administrator_permission_to_post_",
931
+ "Bot token with administrator permission to post messages in the target channel/supergroup."
932
+ ),
933
+ children: [
934
+ /* @__PURE__ */ jsx(Field.Label, { children: t(
935
+ "field.telegram_bot_api_token_from_botfather",
936
+ "Telegram Bot API Token (from @BotFather)"
937
+ ) }),
938
+ /* @__PURE__ */ jsx(
939
+ TextInput,
940
+ {
941
+ name: "telegramBotToken",
942
+ type: "password",
943
+ placeholder: t(
944
+ "placeholder.e_g_123456789_abcdefghijklmnopqrstuvwxyz",
945
+ "e.g., 123456789:ABCdefGhIJKlmNoPQRsTUVwxyZ"
946
+ ),
947
+ value: settings.telegramBotToken || "",
948
+ onChange: (e) => setSettings({ ...settings, telegramBotToken: e.target.value })
949
+ }
950
+ ),
951
+ /* @__PURE__ */ jsx(Field.Hint, {})
952
+ ]
953
+ }
954
+ )
955
+ ]
956
+ }
957
+ )
958
+ ]
959
+ }
960
+ );
961
+ const SettingsPage = () => {
962
+ const { formatMessage } = useIntl();
963
+ const t = (id, defaultMessage) => formatMessage({ id: `${PLUGIN_ID}.${id}`, defaultMessage });
964
+ const { get, put } = useFetchClient();
965
+ const [settings, setSettings] = React.useState(
966
+ DEFAULT_BROADCAST_SETTINGS
967
+ );
968
+ const [savedNotice, setSavedNotice] = React.useState("");
969
+ const [noticeIsError, setNoticeIsError] = React.useState(false);
970
+ const [isSaving, setIsSaving] = React.useState(false);
971
+ React.useEffect(() => {
972
+ let isMounted = true;
973
+ const fetchSettings = async () => {
974
+ try {
975
+ const res = await get(
976
+ `/${PLUGIN_ID}/settings`
977
+ );
978
+ if (isMounted && res?.data?.data) {
979
+ setSettings({
980
+ ...DEFAULT_BROADCAST_SETTINGS,
981
+ ...res.data.data
982
+ });
983
+ }
984
+ } catch {
985
+ }
986
+ };
987
+ void fetchSettings();
988
+ return () => {
989
+ isMounted = false;
990
+ };
991
+ }, [get]);
992
+ const handleSave = async () => {
993
+ if (isSaving) return;
994
+ setIsSaving(true);
995
+ setNoticeIsError(false);
996
+ try {
997
+ const res = await put(
998
+ `/${PLUGIN_ID}/settings`,
999
+ settings
1000
+ );
1001
+ if (res?.data?.data) {
1002
+ setSettings({
1003
+ ...DEFAULT_BROADCAST_SETTINGS,
1004
+ ...res.data.data
1005
+ });
1006
+ }
1007
+ setSavedNotice(
1008
+ t(
1009
+ "settings.ui.settings_saved_notice",
1010
+ "Omnichannel Broadcast transport & channel settings saved successfully."
1011
+ )
1012
+ );
1013
+ } catch (err) {
1014
+ setNoticeIsError(true);
1015
+ setSavedNotice(
1016
+ extractApiErrorMessage(
1017
+ err,
1018
+ t("settings.ui.save_failed", "Failed to save broadcast settings.")
1019
+ )
1020
+ );
1021
+ } finally {
1022
+ setIsSaving(false);
1023
+ }
1024
+ };
1025
+ const handleResetDefaults = () => {
1026
+ if (isSaving) return;
1027
+ setSettings(DEFAULT_BROADCAST_SETTINGS);
1028
+ setNoticeIsError(false);
1029
+ setSavedNotice(
1030
+ t(
1031
+ "settings.ui.settings_reset_notice",
1032
+ 'Settings reset to defaults in editor. Click "Save Settings" to persist.'
1033
+ )
1034
+ );
1035
+ };
1036
+ const enabledText = t("common.enabled", "Enabled");
1037
+ const disabledText = t("common.disabled", "Disabled");
1038
+ const tgStatus = settings.telegramEnabled ? enabledText : disabledText;
1039
+ const waStatus = settings.whatsappEnabled ? settings.whatsappDriver : disabledText;
1040
+ const modeStatus = settings.dryRun ? t("settings.ui.dry_run_sandbox", "Dry-Run Sandbox") : t("settings.ui.live_dispatch", "Live Dispatch");
1041
+ return /* @__PURE__ */ jsx(Main, { children: /* @__PURE__ */ jsxs(Box, { padding: 8, children: [
1042
+ /* @__PURE__ */ jsxs(
1043
+ Flex,
1044
+ {
1045
+ justifyContent: "space-between",
1046
+ alignItems: "flex-start",
1047
+ paddingBottom: 6,
1048
+ wrap: "wrap",
1049
+ gap: 4,
1050
+ children: [
1051
+ /* @__PURE__ */ jsxs(Box, { children: [
1052
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", tag: "h1", children: t(
1053
+ "settings.ui.broadcast_transport_channel_settings",
1054
+ "Broadcast Transport & Channel Settings"
1055
+ ) }),
1056
+ /* @__PURE__ */ jsx(Box, { paddingTop: 1, children: /* @__PURE__ */ jsx(Typography, { variant: "epsilon", textColor: "neutral600", children: t(
1057
+ "settings.ui.configure_email_newsletters_telegram_bot_forum_t",
1058
+ "Configure Email newsletters, Telegram Bot & Forum Topics, WhatsApp Cloud API / Gateways, and EventHub auto-triggers"
1059
+ ) }) }),
1060
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, paddingTop: 3, wrap: "wrap", children: [
1061
+ /* @__PURE__ */ jsxs(Badge, { children: [
1062
+ (settings.supportedLocales || []).length,
1063
+ " ",
1064
+ t("settings.ui.active_locales_label", "Active Locales")
1065
+ ] }),
1066
+ /* @__PURE__ */ jsxs(Badge, { children: [
1067
+ t("settings.ui.telegram_badge_prefix", "Telegram:"),
1068
+ " ",
1069
+ tgStatus
1070
+ ] }),
1071
+ /* @__PURE__ */ jsxs(Badge, { children: [
1072
+ t("settings.ui.whatsapp_badge_prefix", "WhatsApp:"),
1073
+ " ",
1074
+ waStatus
1075
+ ] }),
1076
+ /* @__PURE__ */ jsxs(Badge, { children: [
1077
+ t("settings.ui.mode_badge_prefix", "Mode:"),
1078
+ " ",
1079
+ modeStatus
1080
+ ] })
1081
+ ] })
1082
+ ] }),
1083
+ /* @__PURE__ */ jsxs(Flex, { gap: 2, children: [
1084
+ /* @__PURE__ */ jsx(
1085
+ Button,
1086
+ {
1087
+ variant: "tertiary",
1088
+ disabled: isSaving,
1089
+ onClick: handleResetDefaults,
1090
+ children: t("settings.ui.reset_to_defaults", "Reset to Defaults")
1091
+ }
1092
+ ),
1093
+ /* @__PURE__ */ jsx(Button, { loading: isSaving, disabled: isSaving, onClick: handleSave, children: t("settings.ui.save_settings", "Save Settings") })
1094
+ ] })
1095
+ ]
1096
+ }
1097
+ ),
1098
+ savedNotice && /* @__PURE__ */ jsx(
1099
+ Box,
1100
+ {
1101
+ padding: 3,
1102
+ marginBottom: 4,
1103
+ background: noticeIsError ? "danger100" : "success100",
1104
+ hasRadius: true,
1105
+ role: noticeIsError ? "alert" : "status",
1106
+ children: /* @__PURE__ */ jsx(
1107
+ Typography,
1108
+ {
1109
+ textColor: noticeIsError ? "danger700" : "success700",
1110
+ fontWeight: "semiBold",
1111
+ children: savedNotice
1112
+ }
1113
+ )
1114
+ }
1115
+ ),
1116
+ /* @__PURE__ */ jsxs(Tabs.Root, { defaultValue: "organization", children: [
1117
+ /* @__PURE__ */ jsxs(
1118
+ Tabs.List,
1119
+ {
1120
+ "aria-label": t(
1121
+ "settings.ui.broadcast_transport_channel_settings",
1122
+ "Broadcast Transport & Channel Settings"
1123
+ ),
1124
+ children: [
1125
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "organization", children: t("settings.tab.organization", "Organization, Locales & Email") }),
1126
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "telegram", children: t("settings.tab.telegram", "Telegram Bot & Channel") }),
1127
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "whatsapp", children: t("settings.tab.whatsapp", "WhatsApp Transport") }),
1128
+ /* @__PURE__ */ jsx(Tabs.Trigger, { value: "bridges", children: t("settings.tab.bridges", "Ecosystem Bridges & Sandbox") })
1129
+ ]
1130
+ }
1131
+ ),
1132
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "organization", children: /* @__PURE__ */ jsx(
1133
+ OrganizationEmailTab,
1134
+ {
1135
+ settings,
1136
+ setSettings,
1137
+ t
1138
+ }
1139
+ ) }),
1140
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "telegram", children: /* @__PURE__ */ jsx(
1141
+ TelegramTransportTab,
1142
+ {
1143
+ settings,
1144
+ setSettings,
1145
+ t
1146
+ }
1147
+ ) }),
1148
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "whatsapp", children: /* @__PURE__ */ jsx(
1149
+ WhatsAppTransportTab,
1150
+ {
1151
+ settings,
1152
+ setSettings,
1153
+ t
1154
+ }
1155
+ ) }),
1156
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "bridges", children: /* @__PURE__ */ jsx(
1157
+ BridgesSandboxTab,
1158
+ {
1159
+ settings,
1160
+ setSettings,
1161
+ t
1162
+ }
1163
+ ) })
1164
+ ] })
1165
+ ] }) });
1166
+ };
1167
+ export {
1168
+ SettingsPage
1169
+ };