@gatewaze/admin-embed 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 (96) hide show
  1. package/README.md +42 -0
  2. package/dist/AiSkillsPicker-dbFhcanE.js +373 -0
  3. package/dist/ContentAccessPage-D0HRqPFc.js +264 -0
  4. package/dist/DataTable-fe6yRVpF.js +1984 -0
  5. package/dist/DetailPageHeader-D_v7924k.js +69 -0
  6. package/dist/EditionEmail-CyhC8232.js +8382 -0
  7. package/dist/GuideContent-DBXKCu7r.js +7580 -0
  8. package/dist/HostMediaTab-BsIBEQ1v.js +440 -0
  9. package/dist/InboxPage-C8ivCKdx.js +1112 -0
  10. package/dist/NewsletterCanvasEditor--B06apn3.js +11453 -0
  11. package/dist/NewsletterSetupWizard-BqV6-fa5.js +347 -0
  12. package/dist/NewsletterSignup-DRVZIpOs.js +224 -0
  13. package/dist/Page-D3u8IZ2a.js +14 -0
  14. package/dist/Toaster-Cde0i6IA.js +18 -0
  15. package/dist/Tooltip-CqxUlW1d.js +746 -0
  16. package/dist/_collectionSlug_-B3UN6M-Q.js +308 -0
  17. package/dist/_collection_-Qz4k_Qjl.js +139 -0
  18. package/dist/_edition_-DQXwkI_-.js +301 -0
  19. package/dist/_id_-CtT7rT9f.js +257 -0
  20. package/dist/_id_-CzScE4Qn.js +1197 -0
  21. package/dist/_virtual_gatewaze-modules-BeloWlOa.js +991 -0
  22. package/dist/admin-B0Mmrh_O.js +1239 -0
  23. package/dist/admin-CcfoK6vD.js +17 -0
  24. package/dist/admin-embed.js +21844 -0
  25. package/dist/admin.css +2 -0
  26. package/dist/block-editor-vXBShAue.js +226 -0
  27. package/dist/brand-DklYwIeA.js +11 -0
  28. package/dist/brick-editor-CmBitMMK.js +225 -0
  29. package/dist/broadcastService-CBqXNt_N.js +190 -0
  30. package/dist/classnames-uWIYaD6z.js +44 -0
  31. package/dist/contentAccessService-Cs7tdAo-.js +59 -0
  32. package/dist/context-jzuubYRz.js +5 -0
  33. package/dist/createSafeContext-P1pK0sAN.js +17 -0
  34. package/dist/detail-B8SVFJJr.js +26285 -0
  35. package/dist/detail-uFBxRbLF.js +2966 -0
  36. package/dist/dist-DTrOExw8.js +38806 -0
  37. package/dist/edition-slug-CARO24Bs.js +7 -0
  38. package/dist/export-edition-html-C_hdXQu5.js +18893 -0
  39. package/dist/floating-ui.dom-Cyv879E9.js +987 -0
  40. package/dist/hooks-C377EXJG.js +2974 -0
  41. package/dist/img/mlops-logo.png +0 -0
  42. package/dist/img/mlops-logo2.png +0 -0
  43. package/dist/index.d.ts +105 -0
  44. package/dist/jsx-runtime-CjozyJt-.js +180 -0
  45. package/dist/lib-CylJmhlJ.js +828 -0
  46. package/dist/list-C0cz0aQz.js +451 -0
  47. package/dist/list-CIVgIGsU.js +166 -0
  48. package/dist/logo/mlops-alt.png +0 -0
  49. package/dist/logo/mlops-logo.png +0 -0
  50. package/dist/new-r4KWpqa6.js +80 -0
  51. package/dist/outline-DwDYhYcF.js +6538 -0
  52. package/dist/pages-Ersfxcz7.js +216 -0
  53. package/dist/preview/12627f.jpg +0 -0
  54. package/dist/preview/af009d.jpg +0 -0
  55. package/dist/public-api-LD11kMxh.js +238 -0
  56. package/dist/react-DB2tPNit.js +933 -0
  57. package/dist/react-dom-giQNVXng.js +267 -0
  58. package/dist/registry-4XrV9iNG.js +7 -0
  59. package/dist/render-BtUWfMUt.js +59634 -0
  60. package/dist/resolvePeopleByEmail-hivX2l07.js +828 -0
  61. package/dist/runtime-config.js +10 -0
  62. package/dist/sends-BkPO6PG2.js +182 -0
  63. package/dist/server.browser-Pj3QUa7k.js +15227 -0
  64. package/dist/shim-BCerG8nb.js +6681 -0
  65. package/dist/sonnerHostBridge-CXuCMM3R.js +665 -0
  66. package/dist/src-BWDAOzZO.js +799 -0
  67. package/dist/starter-templates-CFs-QUdF.js +3077 -0
  68. package/dist/storage-VDSvnkvR.js +39 -0
  69. package/dist/templateParser-BQ2IsJ6c.js +49 -0
  70. package/dist/templates-rjQjWsRr.js +253 -0
  71. package/dist/theme/gatewaze/android-icon-144x144.png +0 -0
  72. package/dist/theme/gatewaze/android-icon-192x192.png +0 -0
  73. package/dist/theme/gatewaze/android-icon-36x36.png +0 -0
  74. package/dist/theme/gatewaze/android-icon-48x48.png +0 -0
  75. package/dist/theme/gatewaze/android-icon-72x72.png +0 -0
  76. package/dist/theme/gatewaze/android-icon-96x96.png +0 -0
  77. package/dist/theme/gatewaze/favicon-144x144.png +0 -0
  78. package/dist/theme/gatewaze/favicon-16x16.png +0 -0
  79. package/dist/theme/gatewaze/favicon-192x192.png +0 -0
  80. package/dist/theme/gatewaze/favicon-32x32.png +0 -0
  81. package/dist/theme/gatewaze/favicon-96x96.png +0 -0
  82. package/dist/theme/gatewaze/favicon.ico +0 -0
  83. package/dist/theme/gatewaze/gatewaze-icon-512.png +0 -0
  84. package/dist/theme/gatewaze/gatewaze-logo-black.svg +24 -0
  85. package/dist/theme/gatewaze/gatewaze-logo-white.svg +20 -0
  86. package/dist/theme/gatewaze/gatewaze-poweredby-black.svg +25 -0
  87. package/dist/theme/gatewaze/gatewaze-poweredby-white.svg +25 -0
  88. package/dist/theme/gatewaze/logo_black.svg +24 -0
  89. package/dist/theme/gatewaze/logo_white.svg +20 -0
  90. package/dist/theme-D6odw5nx.js +586 -0
  91. package/dist/ui-DRIo9Krs.js +9747 -0
  92. package/dist/upload-DMNfZ6FX.js +505 -0
  93. package/dist/useModuleFeature-DgsFIUpv.js +8 -0
  94. package/dist/utils-BcVvIjaY.js +36 -0
  95. package/dist/with-selector-B8eSdVx_.js +100 -0
  96. package/package.json +33 -0
@@ -0,0 +1,2966 @@
1
+ import { c as e, t } from "./react-DB2tPNit.js";
2
+ import { d as n } from "./shim-BCerG8nb.js";
3
+ import { t as r } from "./jsx-runtime-CjozyJt-.js";
4
+ import { B as i, D as a, E as o, O as s, f as c, k as l, u, y as d } from "./ui-DRIo9Krs.js";
5
+ import { n as f, t as p } from "./resolvePeopleByEmail-hivX2l07.js";
6
+ import { a as m, i as h, n as g, o as _, r as v, t as y } from "./NewsletterCanvasEditor--B06apn3.js";
7
+ import { n as b, t as x } from "./export-edition-html-C_hdXQu5.js";
8
+ import { a as S, s as C } from "./hooks-C377EXJG.js";
9
+ import { n as w } from "./sonnerHostBridge-CXuCMM3R.js";
10
+ import { t as T } from "./outline-DwDYhYcF.js";
11
+ import { t as E } from "./Page-D3u8IZ2a.js";
12
+ import { c as D, d as ee, f as O, i as te, o as ne, t as re, u as ie } from "./broadcastService-CBqXNt_N.js";
13
+ //#region ../../node_modules/.pnpm/@heroicons+react@2.2.0_react@19.2.4/node_modules/@heroicons/react/24/outline/esm/MapPinIcon.js
14
+ var k = /* @__PURE__ */ e(t());
15
+ function ae({ title: e, titleId: t, ...n }, r) {
16
+ return /*#__PURE__*/ k.createElement("svg", Object.assign({
17
+ xmlns: "http://www.w3.org/2000/svg",
18
+ fill: "none",
19
+ viewBox: "0 0 24 24",
20
+ strokeWidth: 1.5,
21
+ stroke: "currentColor",
22
+ "aria-hidden": "true",
23
+ "data-slot": "icon",
24
+ ref: r,
25
+ "aria-labelledby": t
26
+ }, n), e ? /*#__PURE__*/ k.createElement("title", { id: t }, e) : null, /*#__PURE__*/ k.createElement("path", {
27
+ strokeLinecap: "round",
28
+ strokeLinejoin: "round",
29
+ d: "M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z"
30
+ }), /*#__PURE__*/ k.createElement("path", {
31
+ strokeLinecap: "round",
32
+ strokeLinejoin: "round",
33
+ d: "M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z"
34
+ }));
35
+ }
36
+ var oe = /*#__PURE__*/ k.forwardRef(ae), se = [
37
+ {
38
+ value: "email",
39
+ label: "Email",
40
+ type: "string"
41
+ },
42
+ {
43
+ value: "full_name",
44
+ label: "Full Name",
45
+ type: "string"
46
+ },
47
+ {
48
+ value: "attributes.first_name",
49
+ label: "First Name",
50
+ type: "string"
51
+ },
52
+ {
53
+ value: "attributes.last_name",
54
+ label: "Last Name",
55
+ type: "string"
56
+ },
57
+ {
58
+ value: "attributes.company",
59
+ label: "Company",
60
+ type: "string"
61
+ },
62
+ {
63
+ value: "attributes.job_title",
64
+ label: "Job Title",
65
+ type: "string"
66
+ },
67
+ {
68
+ value: "attributes.country",
69
+ label: "Country",
70
+ type: "string"
71
+ },
72
+ {
73
+ value: "attributes.state",
74
+ label: "State / Province",
75
+ type: "string"
76
+ },
77
+ {
78
+ value: "attributes.city",
79
+ label: "City",
80
+ type: "string"
81
+ },
82
+ {
83
+ value: "attributes.postal",
84
+ label: "Postal / ZIP code",
85
+ type: "string"
86
+ },
87
+ {
88
+ value: "attributes.region",
89
+ label: "Region (continent)",
90
+ type: "string"
91
+ },
92
+ {
93
+ value: "attributes.linkedin_url",
94
+ label: "LinkedIn URL",
95
+ type: "string"
96
+ },
97
+ {
98
+ value: "attributes.twitter_handle",
99
+ label: "Twitter Handle",
100
+ type: "string"
101
+ }
102
+ ], A = [
103
+ {
104
+ value: "equals",
105
+ label: "equals",
106
+ requiresValue: !0
107
+ },
108
+ {
109
+ value: "not_equals",
110
+ label: "does not equal",
111
+ requiresValue: !0
112
+ },
113
+ {
114
+ value: "contains",
115
+ label: "contains",
116
+ requiresValue: !0
117
+ },
118
+ {
119
+ value: "not_contains",
120
+ label: "does not contain",
121
+ requiresValue: !0
122
+ },
123
+ {
124
+ value: "starts_with",
125
+ label: "starts with",
126
+ requiresValue: !0
127
+ },
128
+ {
129
+ value: "ends_with",
130
+ label: "ends with",
131
+ requiresValue: !0
132
+ },
133
+ {
134
+ value: "is_set",
135
+ label: "is set",
136
+ requiresValue: !1
137
+ },
138
+ {
139
+ value: "is_not_set",
140
+ label: "is not set",
141
+ requiresValue: !1
142
+ },
143
+ {
144
+ value: "greater_than",
145
+ label: "is greater than",
146
+ requiresValue: !0
147
+ },
148
+ {
149
+ value: "less_than",
150
+ label: "is less than",
151
+ requiresValue: !0
152
+ },
153
+ {
154
+ value: "in_list",
155
+ label: "is in list",
156
+ requiresValue: !0
157
+ },
158
+ {
159
+ value: "not_in_list",
160
+ label: "is not in list",
161
+ requiresValue: !0
162
+ }
163
+ ], j = [
164
+ {
165
+ value: "performed",
166
+ label: "has performed",
167
+ requiresValue: !1
168
+ },
169
+ {
170
+ value: "not_performed",
171
+ label: "has not performed",
172
+ requiresValue: !1
173
+ },
174
+ {
175
+ value: "performed_at_least",
176
+ label: "has performed at least",
177
+ requiresValue: !0
178
+ },
179
+ {
180
+ value: "performed_at_most",
181
+ label: "has performed at most",
182
+ requiresValue: !0
183
+ },
184
+ {
185
+ value: "performed_count",
186
+ label: "has performed exactly",
187
+ requiresValue: !0
188
+ }
189
+ ], ce = [
190
+ {
191
+ value: "days",
192
+ label: "days"
193
+ },
194
+ {
195
+ value: "weeks",
196
+ label: "weeks"
197
+ },
198
+ {
199
+ value: "months",
200
+ label: "months"
201
+ },
202
+ {
203
+ value: "years",
204
+ label: "years"
205
+ }
206
+ ];
207
+ function le() {
208
+ return {
209
+ match: "all",
210
+ conditions: []
211
+ };
212
+ }
213
+ function M() {
214
+ return {
215
+ type: "attribute",
216
+ field: "",
217
+ operator: "equals",
218
+ value: ""
219
+ };
220
+ }
221
+ function ue() {
222
+ return {
223
+ type: "event",
224
+ event_type: "",
225
+ operator: "performed"
226
+ };
227
+ }
228
+ function de() {
229
+ return {
230
+ type: "group",
231
+ match: "all",
232
+ conditions: [M()]
233
+ };
234
+ }
235
+ function N(e) {
236
+ return e.type === "attribute";
237
+ }
238
+ function P(e) {
239
+ return e.type === "event";
240
+ }
241
+ function fe(e) {
242
+ return e.type === "group";
243
+ }
244
+ var pe = [
245
+ "attribute",
246
+ "event",
247
+ "group"
248
+ ];
249
+ function F(e) {
250
+ return !pe.includes(e.type);
251
+ }
252
+ function me(e) {
253
+ let t = { type: e.kind };
254
+ return e.operators?.length && (t.operator = e.operators[0]), t;
255
+ }
256
+ function I(e) {
257
+ return !e.match || !["all", "any"].includes(e.match) || !Array.isArray(e.conditions) || e.conditions.length === 0 ? !1 : e.conditions.every(L);
258
+ }
259
+ function L(e) {
260
+ return N(e) ? !!(e.field && e.operator) : P(e) ? !!(e.event_type && e.operator) : fe(e) ? ["all", "any"].includes(e.match) && Array.isArray(e.conditions) && e.conditions.length > 0 && e.conditions.every(L) : F(e) ? !!e.type : !1;
261
+ }
262
+ //#endregion
263
+ //#region src/lib/segments/segmentService.ts
264
+ var he = class {
265
+ supabase;
266
+ constructor(e) {
267
+ this.supabase = e;
268
+ }
269
+ async listSegments(e = {}) {
270
+ let { status: t, type: n, account_id: r, page: i = 0, page_size: a = 50, search: o } = e, s = this.supabase.from("segments").select("*", { count: "exact" });
271
+ t && (s = s.eq("status", t)), n && (s = s.eq("type", n)), r && (s = s.eq("account_id", r)), o && (s = s.or(`name.ilike.%${o}%,description.ilike.%${o}%`)), s = s.order("created_at", { ascending: !1 }).range(i * a, (i + 1) * a - 1);
272
+ let { data: c, error: l, count: u } = await s;
273
+ if (l) throw l;
274
+ let d = u || 0;
275
+ return {
276
+ data: c || [],
277
+ total: d,
278
+ page: i,
279
+ page_size: a,
280
+ total_pages: Math.ceil(d / a)
281
+ };
282
+ }
283
+ async getSegment(e) {
284
+ let { data: t, error: n } = await this.supabase.from("segments").select("*").eq("id", e).single();
285
+ if (n) {
286
+ if (n.code === "PGRST116") return null;
287
+ throw n;
288
+ }
289
+ return t;
290
+ }
291
+ async createSegment(e) {
292
+ let { data: t, error: n } = await this.supabase.from("segments").insert({
293
+ name: e.name,
294
+ description: e.description,
295
+ definition: e.definition,
296
+ type: e.type || "dynamic",
297
+ account_id: e.account_id
298
+ }).select().single();
299
+ if (n) throw n;
300
+ return await this.recalculateSegment(t.id), await this.getSegment(t.id);
301
+ }
302
+ async updateSegment(e, t) {
303
+ let n = {};
304
+ t.name !== void 0 && (n.name = t.name), t.description !== void 0 && (n.description = t.description), t.definition !== void 0 && (n.definition = t.definition), t.status !== void 0 && (n.status = t.status);
305
+ let { data: r, error: i } = await this.supabase.from("segments").update(n).eq("id", e).select().single();
306
+ if (i) throw i;
307
+ return t.definition && await this.recalculateSegment(e), await this.getSegment(e);
308
+ }
309
+ async deleteSegment(e) {
310
+ let { error: t } = await this.supabase.from("segments").delete().eq("id", e);
311
+ if (t) throw t;
312
+ }
313
+ async archiveSegment(e) {
314
+ return this.updateSegment(e, { status: "archived" });
315
+ }
316
+ async previewSegment(e) {
317
+ let { data: t, error: n } = await this.supabase.rpc("segments_preview", {
318
+ p_definition: e,
319
+ p_limit: 10
320
+ });
321
+ if (n) throw n;
322
+ return {
323
+ count: t?.count || 0,
324
+ sample: t?.sample || [],
325
+ isEstimate: t?.is_estimate || !1
326
+ };
327
+ }
328
+ async listEventNames() {
329
+ let { data: e, error: t } = await this.supabase.rpc("segments_event_names");
330
+ if (t) throw t;
331
+ return e || [];
332
+ }
333
+ async listConditionSources(e) {
334
+ let { data: t, error: n } = await this.supabase.rpc("segments_sources_catalog", {
335
+ p_search: e ?? null,
336
+ p_entity_limit: 200
337
+ });
338
+ if (n) return [];
339
+ let r = t?.sources;
340
+ return Array.isArray(r) ? r : [];
341
+ }
342
+ async geocodePlace(e) {
343
+ let { data: t, error: n } = await this.supabase.rpc("segments_geocode_place", { p_place: e });
344
+ if (n || !t) return null;
345
+ let r = t;
346
+ return typeof r.lat == "number" && typeof r.lng == "number" ? {
347
+ lat: r.lat,
348
+ lng: r.lng,
349
+ n: r.n
350
+ } : null;
351
+ }
352
+ async geoAggregate(e, t = 500) {
353
+ let { data: n, error: r } = await this.supabase.rpc("segments_geo_aggregate", {
354
+ p_definition: e,
355
+ p_limit: t
356
+ });
357
+ if (r) throw r;
358
+ return (n || []).filter((e) => typeof e.lat == "number" && typeof e.lng == "number");
359
+ }
360
+ async getSegmentCount(e, t = !0) {
361
+ let { data: n, error: r } = await this.supabase.rpc("segments_get_member_count", {
362
+ p_segment_id: e,
363
+ p_use_cache: t
364
+ });
365
+ if (r) throw r;
366
+ return n || 0;
367
+ }
368
+ async getSegmentMembers(e, t = {}) {
369
+ let { page: n = 0, page_size: r = 50, search: i } = t, { data: a, error: o } = await this.supabase.rpc("segments_get_members_paginated", {
370
+ p_segment_id: e,
371
+ p_offset: n * r,
372
+ p_limit: r,
373
+ p_search: i || null
374
+ });
375
+ if (o) throw o;
376
+ return {
377
+ members: a?.members || [],
378
+ total: a?.total || 0
379
+ };
380
+ }
381
+ async recalculateSegment(e) {
382
+ let t = null;
383
+ for (let n = 0; n < 1e4; n++) {
384
+ let { data: n, error: r } = await this.supabase.rpc("segments_calculate_members_batch", {
385
+ p_segment_id: e,
386
+ p_after: t,
387
+ p_limit: 25e3
388
+ });
389
+ if (r) throw r;
390
+ let i = n ?? {};
391
+ if (!i.remaining || (t = i.last_person_id ?? null, t === null)) return;
392
+ }
393
+ throw Error("Segment recalculation did not converge");
394
+ }
395
+ async exportSegmentCSV(e) {
396
+ let { members: t } = await this.getSegmentMembers(e, { page_size: 1e5 }), n = [
397
+ "email",
398
+ "first_name",
399
+ "last_name",
400
+ "company",
401
+ "job_title",
402
+ "country",
403
+ "city"
404
+ ], r = t.map((e) => [
405
+ e.email || "",
406
+ e.attributes?.first_name || "",
407
+ e.attributes?.last_name || "",
408
+ e.attributes?.company || "",
409
+ e.attributes?.job_title || "",
410
+ e.attributes?.country || "",
411
+ e.attributes?.city || ""
412
+ ].map((e) => `"${String(e).replace(/"/g, "\"\"")}"`).join(","));
413
+ return [n.join(","), ...r].join("\n");
414
+ }
415
+ async exportSegmentBlob(e) {
416
+ let t = await this.exportSegmentCSV(e);
417
+ return new Blob([t], { type: "text/csv;charset=utf-8;" });
418
+ }
419
+ async duplicateSegment(e, t) {
420
+ let n = await this.getSegment(e);
421
+ if (!n) throw Error("Segment not found");
422
+ return this.createSegment({
423
+ name: t || `${n.name} (Copy)`,
424
+ description: n.description,
425
+ definition: n.definition,
426
+ type: n.type,
427
+ account_id: n.account_id || void 0
428
+ });
429
+ }
430
+ async getCalculationHistory(e, t = 20) {
431
+ let { data: n, error: r } = await this.supabase.from("segments_calculation_history").select("calculated_at, member_count, calculation_duration_ms, triggered_by").eq("segment_id", e).order("calculated_at", { ascending: !1 }).limit(t);
432
+ if (r) throw r;
433
+ return n || [];
434
+ }
435
+ async addMembersToSegment(e, t) {
436
+ let n = t.map((t) => ({
437
+ segment_id: e,
438
+ person_id: t,
439
+ source: "manual"
440
+ })), { error: r } = await this.supabase.from("segments_memberships").upsert(n, { onConflict: "segment_id,person_id" });
441
+ if (r) throw r;
442
+ let { count: i } = await this.supabase.from("segments_memberships").select("*", {
443
+ count: "exact",
444
+ head: !0
445
+ }).eq("segment_id", e);
446
+ await this.supabase.from("segments").update({
447
+ cached_count: i || 0,
448
+ last_calculated_at: (/* @__PURE__ */ new Date()).toISOString()
449
+ }).eq("id", e);
450
+ }
451
+ async removeMembersFromSegment(e, t) {
452
+ let { error: n } = await this.supabase.from("segments_memberships").delete().eq("segment_id", e).in("person_id", t);
453
+ if (n) throw n;
454
+ let { count: r } = await this.supabase.from("segments_memberships").select("*", {
455
+ count: "exact",
456
+ head: !0
457
+ }).eq("segment_id", e);
458
+ await this.supabase.from("segments").update({
459
+ cached_count: r || 0,
460
+ last_calculated_at: (/* @__PURE__ */ new Date()).toISOString()
461
+ }).eq("id", e);
462
+ }
463
+ };
464
+ function R(e) {
465
+ return new he(e);
466
+ }
467
+ //#endregion
468
+ //#region src/components/charts/PersonLocationMap.tsx
469
+ var z = r();
470
+ function ge({ locations: e, loading: t = !1 }) {
471
+ let n = (0, k.useMemo)(() => e.reduce((e, t) => e + t.count, 0), [e]), r = (0, k.useMemo)(() => {
472
+ if (e.length === 0) return {
473
+ center: [20, 0],
474
+ zoom: 2
475
+ };
476
+ let t = e.map((e) => e.lat), n = e.map((e) => e.lng), r = (Math.min(...t) + Math.max(...t)) / 2, i = (Math.min(...n) + Math.max(...n)) / 2, a = Math.max(...t) - Math.min(...t), o = Math.max(...n) - Math.min(...n), s = Math.max(a, o), c = 2;
477
+ return s < 1 ? c = 10 : s < 5 ? c = 7 : s < 10 ? c = 5 : s < 50 && (c = 3), {
478
+ center: [r, i],
479
+ zoom: c
480
+ };
481
+ }, [e]), i = (e) => {
482
+ let t = e / n * 100;
483
+ return Math.max(5, Math.min(40, Math.sqrt(t) * 8));
484
+ }, a = new Set(e.map((e) => e.country)).size, o = e.length, s = e[0];
485
+ return t ? /* @__PURE__ */ (0, z.jsx)("div", {
486
+ className: "flex items-center justify-center h-96 bg-gray-50 dark:bg-gray-900 rounded-lg",
487
+ children: /* @__PURE__ */ (0, z.jsxs)("div", {
488
+ className: "text-center",
489
+ children: [/* @__PURE__ */ (0, z.jsx)("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600 mx-auto" }), /* @__PURE__ */ (0, z.jsx)("p", {
490
+ className: "mt-2 text-sm text-gray-500 dark:text-gray-400",
491
+ children: "Loading people locations..."
492
+ })]
493
+ })
494
+ }) : /* @__PURE__ */ (0, z.jsxs)("div", {
495
+ className: "space-y-6",
496
+ children: [
497
+ /* @__PURE__ */ (0, z.jsxs)("div", {
498
+ className: "flex items-center justify-between",
499
+ children: [/* @__PURE__ */ (0, z.jsx)("h3", {
500
+ className: "text-sm font-medium text-gray-700 dark:text-gray-300",
501
+ children: "People Locations"
502
+ }), /* @__PURE__ */ (0, z.jsxs)("div", {
503
+ className: "text-sm text-gray-500 dark:text-gray-400",
504
+ children: [n.toLocaleString(), " people with location data"]
505
+ })]
506
+ }),
507
+ /* @__PURE__ */ (0, z.jsxs)("div", { children: [/* @__PURE__ */ (0, z.jsx)("h4", {
508
+ className: "text-xs font-medium text-gray-600 dark:text-gray-400 mb-2",
509
+ children: "Geographic Distribution - Circle size represents people concentration"
510
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
511
+ className: "bg-white dark:bg-gray-800 p-2 rounded-lg",
512
+ children: e.length > 0 ? /* @__PURE__ */ (0, z.jsx)("div", {
513
+ className: "w-full h-96 rounded-lg overflow-hidden border border-gray-200 dark:border-gray-700",
514
+ children: /* @__PURE__ */ (0, z.jsxs)(m, {
515
+ center: r.center,
516
+ zoom: r.zoom,
517
+ style: {
518
+ height: "100%",
519
+ width: "100%"
520
+ },
521
+ scrollWheelZoom: !1,
522
+ children: [/* @__PURE__ */ (0, z.jsx)(h, {
523
+ attribution: "© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
524
+ url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
525
+ }), e.map((e, t) => /* @__PURE__ */ (0, z.jsx)(_, {
526
+ center: [e.lat, e.lng],
527
+ radius: i(e.count),
528
+ fillColor: "#3B82F6",
529
+ fillOpacity: .6,
530
+ color: "#3B82F6",
531
+ weight: 2,
532
+ children: /* @__PURE__ */ (0, z.jsx)(v, { children: /* @__PURE__ */ (0, z.jsxs)("div", { children: [
533
+ /* @__PURE__ */ (0, z.jsx)("strong", { children: e.city || "Unknown City" }),
534
+ /* @__PURE__ */ (0, z.jsx)("br", {}),
535
+ e.country || "Unknown Country",
536
+ /* @__PURE__ */ (0, z.jsx)("br", {}),
537
+ "People: ",
538
+ e.count,
539
+ /* @__PURE__ */ (0, z.jsx)("br", {}),
540
+ "Percentage: ",
541
+ (e.count / n * 100).toFixed(1),
542
+ "%"
543
+ ] }) })
544
+ }, t))]
545
+ })
546
+ }) : /* @__PURE__ */ (0, z.jsxs)("div", {
547
+ className: "flex flex-col items-center justify-center h-96 bg-gray-50 dark:bg-gray-900 rounded-lg text-gray-500",
548
+ children: [
549
+ /* @__PURE__ */ (0, z.jsx)(oe, { className: "h-12 w-12 text-gray-400 mb-3" }),
550
+ /* @__PURE__ */ (0, z.jsx)("p", {
551
+ className: "text-sm font-medium text-gray-900 dark:text-white",
552
+ children: "No location data available"
553
+ }),
554
+ /* @__PURE__ */ (0, z.jsx)("p", {
555
+ className: "text-xs text-gray-500 dark:text-gray-400 mt-1",
556
+ children: "People need city and country to appear on the map"
557
+ })
558
+ ]
559
+ })
560
+ })] }),
561
+ e.length > 0 && /* @__PURE__ */ (0, z.jsxs)("div", { children: [/* @__PURE__ */ (0, z.jsx)("h4", {
562
+ className: "text-xs font-medium text-gray-600 dark:text-gray-400 mb-2",
563
+ children: "Top Locations"
564
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
565
+ className: "bg-white dark:bg-gray-800 rounded-lg overflow-hidden",
566
+ children: /* @__PURE__ */ (0, z.jsx)("div", {
567
+ className: "max-h-64 overflow-y-auto",
568
+ children: /* @__PURE__ */ (0, z.jsxs)("table", {
569
+ className: "w-full",
570
+ children: [/* @__PURE__ */ (0, z.jsx)("thead", {
571
+ className: "bg-gray-50 dark:bg-gray-900 sticky top-0",
572
+ children: /* @__PURE__ */ (0, z.jsxs)("tr", { children: [
573
+ /* @__PURE__ */ (0, z.jsx)("th", {
574
+ className: "px-4 py-2 text-left text-xs font-medium text-gray-600 dark:text-gray-400",
575
+ children: "Location"
576
+ }),
577
+ /* @__PURE__ */ (0, z.jsx)("th", {
578
+ className: "px-4 py-2 text-right text-xs font-medium text-gray-600 dark:text-gray-400",
579
+ children: "People"
580
+ }),
581
+ /* @__PURE__ */ (0, z.jsx)("th", {
582
+ className: "px-4 py-2 text-right text-xs font-medium text-gray-600 dark:text-gray-400",
583
+ children: "%"
584
+ })
585
+ ] })
586
+ }), /* @__PURE__ */ (0, z.jsx)("tbody", {
587
+ className: "divide-y divide-gray-200 dark:divide-gray-700",
588
+ children: e.slice(0, 15).map((e, t) => /* @__PURE__ */ (0, z.jsxs)("tr", {
589
+ className: "hover:bg-gray-50 dark:hover:bg-gray-900",
590
+ children: [
591
+ /* @__PURE__ */ (0, z.jsx)("td", {
592
+ className: "px-4 py-2 text-sm",
593
+ children: /* @__PURE__ */ (0, z.jsxs)("div", { children: [/* @__PURE__ */ (0, z.jsx)("div", {
594
+ className: "font-medium text-gray-900 dark:text-white",
595
+ children: e.city || "Unknown City"
596
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
597
+ className: "text-xs text-gray-500 dark:text-gray-400",
598
+ children: e.country || "Unknown Country"
599
+ })] })
600
+ }),
601
+ /* @__PURE__ */ (0, z.jsx)("td", {
602
+ className: "px-4 py-2 text-sm text-right text-gray-900 dark:text-white",
603
+ children: e.count
604
+ }),
605
+ /* @__PURE__ */ (0, z.jsxs)("td", {
606
+ className: "px-4 py-2 text-sm text-right text-gray-500 dark:text-gray-400",
607
+ children: [(e.count / n * 100).toFixed(1), "%"]
608
+ })
609
+ ]
610
+ }, t))
611
+ })]
612
+ })
613
+ })
614
+ })] }),
615
+ /* @__PURE__ */ (0, z.jsxs)("div", {
616
+ className: "grid grid-cols-3 gap-4",
617
+ children: [
618
+ /* @__PURE__ */ (0, z.jsxs)("div", {
619
+ className: "bg-gray-50 dark:bg-gray-800 p-4 rounded-lg",
620
+ children: [/* @__PURE__ */ (0, z.jsx)("div", {
621
+ className: "text-xs font-medium text-gray-600 dark:text-gray-400 uppercase",
622
+ children: "Countries"
623
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
624
+ className: "text-2xl font-bold mt-1",
625
+ children: a
626
+ })]
627
+ }),
628
+ /* @__PURE__ */ (0, z.jsxs)("div", {
629
+ className: "bg-gray-50 dark:bg-gray-800 p-4 rounded-lg",
630
+ children: [/* @__PURE__ */ (0, z.jsx)("div", {
631
+ className: "text-xs font-medium text-gray-600 dark:text-gray-400 uppercase",
632
+ children: "Locations"
633
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
634
+ className: "text-2xl font-bold mt-1",
635
+ children: o
636
+ })]
637
+ }),
638
+ /* @__PURE__ */ (0, z.jsxs)("div", {
639
+ className: "bg-gray-50 dark:bg-gray-800 p-4 rounded-lg",
640
+ children: [
641
+ /* @__PURE__ */ (0, z.jsx)("div", {
642
+ className: "text-xs font-medium text-gray-600 dark:text-gray-400 uppercase",
643
+ children: "Top Location"
644
+ }),
645
+ /* @__PURE__ */ (0, z.jsx)("div", {
646
+ className: "text-lg font-bold mt-1",
647
+ children: s ? s.city || "Unknown" : "N/A"
648
+ }),
649
+ s && /* @__PURE__ */ (0, z.jsxs)("div", {
650
+ className: "text-xs text-gray-500 dark:text-gray-400",
651
+ children: [
652
+ s.count,
653
+ " people (",
654
+ (s.count / n * 100).toFixed(1),
655
+ "%)"
656
+ ]
657
+ })
658
+ ]
659
+ })
660
+ ]
661
+ })
662
+ ]
663
+ });
664
+ }
665
+ //#endregion
666
+ //#region ../../../gatewaze-modules/modules/segments/admin/pages/components/SegmentBuilder/AttributeConditionFields.tsx
667
+ var B = T();
668
+ function _e({ condition: e, onChange: t }) {
669
+ let n = A.find((t) => t.value === e.operator)?.requiresValue !== !1, r = (n) => {
670
+ t({
671
+ ...e,
672
+ field: n
673
+ });
674
+ }, i = (n) => {
675
+ t({
676
+ ...e,
677
+ operator: n,
678
+ value: A.find((e) => e.value === n)?.requiresValue ? e.value : ""
679
+ });
680
+ }, a = (n) => {
681
+ t({
682
+ ...e,
683
+ value: n
684
+ });
685
+ };
686
+ return /* @__PURE__ */ (0, z.jsxs)("div", {
687
+ className: "flex items-end gap-3 flex-wrap",
688
+ children: [
689
+ /* @__PURE__ */ (0, z.jsxs)("div", {
690
+ className: "flex-1 min-w-[180px]",
691
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
692
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
693
+ children: "Field"
694
+ }), /* @__PURE__ */ (0, z.jsxs)("select", {
695
+ value: e.field,
696
+ onChange: (e) => r(e.target.value),
697
+ className: "w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
698
+ children: [
699
+ /* @__PURE__ */ (0, z.jsx)("option", {
700
+ value: "",
701
+ children: "Select field..."
702
+ }),
703
+ se.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
704
+ value: e.value,
705
+ children: e.label
706
+ }, e.value)),
707
+ /* @__PURE__ */ (0, z.jsx)("option", {
708
+ value: "custom",
709
+ children: "Custom field..."
710
+ })
711
+ ]
712
+ })]
713
+ }),
714
+ e.field === "custom" && /* @__PURE__ */ (0, z.jsxs)("div", {
715
+ className: "min-w-[160px]",
716
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
717
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
718
+ children: "Field Path"
719
+ }), /* @__PURE__ */ (0, z.jsx)(u, {
720
+ placeholder: "attributes.field_name",
721
+ value: e.field === "custom" ? "" : e.field,
722
+ onChange: (e) => r(e.target.value),
723
+ classNames: { root: "w-full" }
724
+ })]
725
+ }),
726
+ /* @__PURE__ */ (0, z.jsxs)("div", {
727
+ className: "min-w-[160px]",
728
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
729
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
730
+ children: "Operator"
731
+ }), /* @__PURE__ */ (0, z.jsx)("select", {
732
+ value: e.operator,
733
+ onChange: (e) => i(e.target.value),
734
+ className: "w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
735
+ children: A.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
736
+ value: e.value,
737
+ children: e.label
738
+ }, e.value))
739
+ })]
740
+ }),
741
+ n && /* @__PURE__ */ (0, z.jsxs)("div", {
742
+ className: "flex-1 min-w-[200px]",
743
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
744
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
745
+ children: "Value"
746
+ }), e.operator === "in_list" || e.operator === "not_in_list" ? /* @__PURE__ */ (0, z.jsx)(u, {
747
+ placeholder: "value1, value2, value3",
748
+ value: Array.isArray(e.value) ? e.value.join(", ") : e.value || "",
749
+ onChange: (n) => {
750
+ let r = n.target.value.split(",").map((e) => e.trim()).filter(Boolean);
751
+ t({
752
+ ...e,
753
+ value: r
754
+ });
755
+ },
756
+ classNames: { root: "w-full" }
757
+ }) : /* @__PURE__ */ (0, z.jsx)(u, {
758
+ placeholder: "Enter value...",
759
+ value: e.value || "",
760
+ onChange: (e) => a(e.target.value),
761
+ classNames: { root: "w-full" }
762
+ })]
763
+ })
764
+ ]
765
+ });
766
+ }
767
+ //#endregion
768
+ //#region ../../../gatewaze-modules/modules/segments/admin/pages/components/SegmentBuilder/EventConditionFields.tsx
769
+ var ve = [
770
+ {
771
+ value: "event_city",
772
+ label: "Event city"
773
+ },
774
+ {
775
+ value: "event_country_code",
776
+ label: "Event country (ISO-2)"
777
+ },
778
+ {
779
+ value: "event_title",
780
+ label: "Event title"
781
+ },
782
+ {
783
+ value: "event_id",
784
+ label: "Event ID"
785
+ },
786
+ {
787
+ value: "status",
788
+ label: "Registration status"
789
+ }
790
+ ], ye = [
791
+ {
792
+ value: "equals",
793
+ label: "is"
794
+ },
795
+ {
796
+ value: "not_equals",
797
+ label: "is not"
798
+ },
799
+ {
800
+ value: "contains",
801
+ label: "contains"
802
+ },
803
+ {
804
+ value: "starts_with",
805
+ label: "starts with"
806
+ }
807
+ ], V = null, H = null;
808
+ function be() {
809
+ return V ? Promise.resolve(V) : (H ||= (async () => {
810
+ if (!n) return [];
811
+ try {
812
+ let e = await R(n).listEventNames();
813
+ return V = e, e;
814
+ } catch {
815
+ return [];
816
+ }
817
+ })(), H);
818
+ }
819
+ function xe({ condition: e, onChange: t }) {
820
+ let [n, r] = (0, k.useState)(V || []);
821
+ (0, k.useEffect)(() => {
822
+ let e = !0;
823
+ return be().then((t) => {
824
+ e && r(t);
825
+ }), () => {
826
+ e = !1;
827
+ };
828
+ }, []);
829
+ let i = j.find((t) => t.value === e.operator)?.requiresValue === !0, a = (n) => {
830
+ t({
831
+ ...e,
832
+ event_type: n
833
+ });
834
+ }, o = (n) => {
835
+ t({
836
+ ...e,
837
+ operator: n,
838
+ value: i ? e.value || 1 : void 0
839
+ });
840
+ }, s = (n) => {
841
+ t({
842
+ ...e,
843
+ value: n
844
+ });
845
+ }, c = (n) => {
846
+ if (n) t({
847
+ ...e,
848
+ time_window: {
849
+ type: "relative",
850
+ relative_value: 30,
851
+ relative_unit: "days"
852
+ }
853
+ });
854
+ else {
855
+ let { time_window: n, ...r } = e;
856
+ t(r);
857
+ }
858
+ }, l = (n) => {
859
+ t({
860
+ ...e,
861
+ time_window: {
862
+ ...e.time_window,
863
+ ...n
864
+ }
865
+ });
866
+ }, d = e.event_filters ?? [], f = (n) => {
867
+ let { event_filters: r, ...i } = e;
868
+ t(n.length > 0 ? {
869
+ ...i,
870
+ event_filters: n
871
+ } : i);
872
+ }, p = () => f([...d, {
873
+ property: "event_city",
874
+ operator: "equals",
875
+ value: ""
876
+ }]), m = (e, t) => f(d.map((n, r) => r === e ? {
877
+ ...n,
878
+ ...t
879
+ } : n)), h = (e) => f(d.filter((t, n) => n !== e));
880
+ return /* @__PURE__ */ (0, z.jsxs)("div", {
881
+ className: "space-y-3",
882
+ children: [
883
+ /* @__PURE__ */ (0, z.jsxs)("div", {
884
+ className: "flex items-end gap-3 flex-wrap",
885
+ children: [
886
+ /* @__PURE__ */ (0, z.jsxs)("div", {
887
+ className: "min-w-[160px]",
888
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
889
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
890
+ children: "Condition"
891
+ }), /* @__PURE__ */ (0, z.jsx)("select", {
892
+ value: e.operator,
893
+ onChange: (e) => o(e.target.value),
894
+ className: "w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
895
+ children: j.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
896
+ value: e.value,
897
+ children: e.label
898
+ }, e.value))
899
+ })]
900
+ }),
901
+ /* @__PURE__ */ (0, z.jsxs)("div", {
902
+ className: "flex-1 min-w-[200px]",
903
+ children: [
904
+ /* @__PURE__ */ (0, z.jsx)("label", {
905
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
906
+ children: "Event"
907
+ }),
908
+ /* @__PURE__ */ (0, z.jsx)("input", {
909
+ list: "segment-event-names",
910
+ value: e.event_type,
911
+ onChange: (e) => a(e.target.value),
912
+ placeholder: "e.g. event_registered",
913
+ className: "w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500"
914
+ }),
915
+ /* @__PURE__ */ (0, z.jsx)("datalist", {
916
+ id: "segment-event-names",
917
+ children: n.map((e) => /* @__PURE__ */ (0, z.jsx)("option", { value: e }, e))
918
+ })
919
+ ]
920
+ }),
921
+ i && /* @__PURE__ */ (0, z.jsxs)("div", {
922
+ className: "w-24",
923
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
924
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
925
+ children: "Times"
926
+ }), /* @__PURE__ */ (0, z.jsx)(u, {
927
+ type: "number",
928
+ min: 1,
929
+ value: e.value || 1,
930
+ onChange: (e) => s(parseInt(e.target.value) || 1),
931
+ classNames: { root: "w-full" }
932
+ })]
933
+ }),
934
+ /* @__PURE__ */ (0, z.jsxs)("div", {
935
+ className: "min-w-[120px]",
936
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
937
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
938
+ children: "Time Filter"
939
+ }), /* @__PURE__ */ (0, z.jsxs)("select", {
940
+ value: e.time_window ? "enabled" : "disabled",
941
+ onChange: (e) => c(e.target.value === "enabled"),
942
+ className: "w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
943
+ children: [/* @__PURE__ */ (0, z.jsx)("option", {
944
+ value: "disabled",
945
+ children: "Any time"
946
+ }), /* @__PURE__ */ (0, z.jsx)("option", {
947
+ value: "enabled",
948
+ children: "Within..."
949
+ })]
950
+ })]
951
+ })
952
+ ]
953
+ }),
954
+ e.time_window && /* @__PURE__ */ (0, z.jsxs)("div", {
955
+ className: "flex items-center gap-3 pl-4 border-l-2 border-gray-200 dark:border-gray-600",
956
+ children: [
957
+ /* @__PURE__ */ (0, z.jsx)("span", {
958
+ className: "text-sm text-gray-600 dark:text-gray-400",
959
+ children: "In the last"
960
+ }),
961
+ /* @__PURE__ */ (0, z.jsx)("div", {
962
+ className: "w-20",
963
+ children: /* @__PURE__ */ (0, z.jsx)(u, {
964
+ type: "number",
965
+ min: 1,
966
+ value: e.time_window.relative_value || 30,
967
+ onChange: (e) => l({ relative_value: parseInt(e.target.value) || 1 }),
968
+ classNames: { root: "w-full" }
969
+ })
970
+ }),
971
+ /* @__PURE__ */ (0, z.jsx)("select", {
972
+ value: e.time_window.relative_unit || "days",
973
+ onChange: (e) => l({ relative_unit: e.target.value }),
974
+ className: "rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
975
+ children: ce.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
976
+ value: e.value,
977
+ children: e.label
978
+ }, e.value))
979
+ })
980
+ ]
981
+ }),
982
+ /* @__PURE__ */ (0, z.jsxs)("div", {
983
+ className: "pl-4 border-l-2 border-gray-200 dark:border-gray-600 space-y-2",
984
+ children: [d.map((e, t) => /* @__PURE__ */ (0, z.jsxs)("div", {
985
+ className: "flex items-end gap-2 flex-wrap",
986
+ children: [
987
+ /* @__PURE__ */ (0, z.jsx)("span", {
988
+ className: "text-sm text-gray-600 dark:text-gray-400 pb-2",
989
+ children: "where the event's"
990
+ }),
991
+ /* @__PURE__ */ (0, z.jsx)("select", {
992
+ value: e.property,
993
+ onChange: (e) => m(t, { property: e.target.value }),
994
+ className: "rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-2 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
995
+ children: ve.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
996
+ value: e.value,
997
+ children: e.label
998
+ }, e.value))
999
+ }),
1000
+ /* @__PURE__ */ (0, z.jsx)("select", {
1001
+ value: e.operator,
1002
+ onChange: (e) => m(t, { operator: e.target.value }),
1003
+ className: "rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-2 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
1004
+ children: ye.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
1005
+ value: e.value,
1006
+ children: e.label
1007
+ }, e.value))
1008
+ }),
1009
+ /* @__PURE__ */ (0, z.jsx)("input", {
1010
+ value: typeof e.value == "string" ? e.value : "",
1011
+ onChange: (e) => m(t, { value: e.target.value }),
1012
+ placeholder: "e.g. San Francisco",
1013
+ className: "flex-1 min-w-[140px] rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500"
1014
+ }),
1015
+ /* @__PURE__ */ (0, z.jsx)("button", {
1016
+ type: "button",
1017
+ onClick: () => h(t),
1018
+ title: "Remove filter",
1019
+ className: "p-2 text-gray-400 hover:text-red-500",
1020
+ children: /* @__PURE__ */ (0, z.jsx)(B.TrashIcon, { className: "size-4" })
1021
+ })
1022
+ ]
1023
+ }, t)), /* @__PURE__ */ (0, z.jsxs)("button", {
1024
+ type: "button",
1025
+ onClick: p,
1026
+ className: "inline-flex items-center gap-1 text-xs font-medium text-primary-600 dark:text-primary-400 hover:underline",
1027
+ children: [/* @__PURE__ */ (0, z.jsx)(B.PlusIcon, { className: "size-3" }), " Add event property filter (e.g. event city)"]
1028
+ })]
1029
+ }),
1030
+ !e.event_type && /* @__PURE__ */ (0, z.jsx)("div", {
1031
+ className: "text-xs text-gray-500 dark:text-gray-400 pl-1",
1032
+ children: "Pick a tracked event, or type a custom event name."
1033
+ })
1034
+ ]
1035
+ });
1036
+ }
1037
+ //#endregion
1038
+ //#region ../../../gatewaze-modules/modules/segments/admin/pages/components/SegmentBuilder/SourceConditionFields.tsx
1039
+ var U = "w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500";
1040
+ function W(e) {
1041
+ return e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
1042
+ }
1043
+ function Se({ condition: e, source: t, onChange: r }) {
1044
+ let [i, a] = (0, k.useState)(""), o = t.params_schema?.properties ?? {}, s = Object.entries(o).find(([, e]) => e?.["x-entity-source"])?.[0] ?? null, c = (t) => r({
1045
+ ...e,
1046
+ ...t
1047
+ });
1048
+ async function l(e) {
1049
+ if (!e.trim() || !n) {
1050
+ c({
1051
+ lat: null,
1052
+ lng: null
1053
+ });
1054
+ return;
1055
+ }
1056
+ try {
1057
+ let t = await R(n).geocodePlace(e.trim());
1058
+ t ? (c({
1059
+ lat: t.lat,
1060
+ lng: t.lng
1061
+ }), a(`Located from ${t.n ?? 0} nearby contact${t.n === 1 ? "" : "s"}.`)) : (c({
1062
+ lat: null,
1063
+ lng: null
1064
+ }), a(`Couldn't locate "${e}" from our data — this will match nobody. Try a larger nearby city.`));
1065
+ } catch {
1066
+ a("Geocoding failed.");
1067
+ }
1068
+ }
1069
+ return /* @__PURE__ */ (0, z.jsxs)("div", {
1070
+ className: "space-y-3",
1071
+ children: [
1072
+ /* @__PURE__ */ (0, z.jsxs)("div", {
1073
+ className: "flex items-end gap-3 flex-wrap",
1074
+ children: [t.operators && t.operators.length > 0 && /* @__PURE__ */ (0, z.jsxs)("div", {
1075
+ className: "min-w-[120px]",
1076
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
1077
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
1078
+ children: "Condition"
1079
+ }), /* @__PURE__ */ (0, z.jsx)("select", {
1080
+ value: e.operator ?? t.operators[0],
1081
+ onChange: (e) => c({ operator: e.target.value }),
1082
+ className: U,
1083
+ children: t.operators.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
1084
+ value: e,
1085
+ children: W(e)
1086
+ }, e))
1087
+ })]
1088
+ }), s && /* @__PURE__ */ (0, z.jsxs)("div", {
1089
+ className: "flex-1 min-w-[220px]",
1090
+ children: [
1091
+ /* @__PURE__ */ (0, z.jsx)("label", {
1092
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
1093
+ children: t.label
1094
+ }),
1095
+ /* @__PURE__ */ (0, z.jsxs)("select", {
1096
+ value: e[s] ?? "",
1097
+ onChange: (e) => c({ [s]: e.target.value }),
1098
+ className: U,
1099
+ children: [/* @__PURE__ */ (0, z.jsx)("option", {
1100
+ value: "",
1101
+ children: "Select…"
1102
+ }), (t.entities ?? []).map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
1103
+ value: e.id,
1104
+ children: e.label
1105
+ }, e.id))]
1106
+ }),
1107
+ t.entities_truncated && /* @__PURE__ */ (0, z.jsx)("p", {
1108
+ className: "text-xs text-gray-400 mt-1",
1109
+ children: "List truncated — type in the copilot if the one you want is missing."
1110
+ })
1111
+ ]
1112
+ })]
1113
+ }),
1114
+ /* @__PURE__ */ (0, z.jsx)("div", {
1115
+ className: "flex items-end gap-3 flex-wrap",
1116
+ children: Object.entries(o).map(([n, r]) => {
1117
+ if (n === s || n === "lat" || n === "lng") return null;
1118
+ let i = t.kind === "geo_radius" && n === "place", a = r?.type === "number" || n === "radius_km", o = r?.type === "array", u = e[n];
1119
+ return /* @__PURE__ */ (0, z.jsxs)("div", {
1120
+ className: i ? "flex-1 min-w-[200px]" : "min-w-[140px]",
1121
+ children: [/* @__PURE__ */ (0, z.jsxs)("label", {
1122
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
1123
+ children: [W(n), a && n === "radius_km" ? " (km)" : ""]
1124
+ }), Array.isArray(r?.enum) ? /* @__PURE__ */ (0, z.jsxs)("select", {
1125
+ value: u ?? "",
1126
+ onChange: (e) => c({ [n]: e.target.value }),
1127
+ className: U,
1128
+ children: [/* @__PURE__ */ (0, z.jsx)("option", {
1129
+ value: "",
1130
+ children: "Any"
1131
+ }), r.enum.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
1132
+ value: e,
1133
+ children: e
1134
+ }, e))]
1135
+ }) : o ? /* @__PURE__ */ (0, z.jsx)("input", {
1136
+ value: Array.isArray(u) ? u.join(", ") : "",
1137
+ onChange: (e) => c({ [n]: e.target.value.split(",").map((e) => e.trim()).filter(Boolean) }),
1138
+ placeholder: "comma,separated",
1139
+ className: U
1140
+ }) : /* @__PURE__ */ (0, z.jsx)("input", {
1141
+ type: a ? "number" : "text",
1142
+ value: u ?? "",
1143
+ onChange: (e) => c({ [n]: e.target.value }),
1144
+ onBlur: i ? (e) => l(e.target.value) : void 0,
1145
+ placeholder: i ? "e.g. San Francisco" : "",
1146
+ className: U
1147
+ })]
1148
+ }, n);
1149
+ })
1150
+ }),
1151
+ t.kind === "geo_radius" && (i || e.lat != null) && /* @__PURE__ */ (0, z.jsx)("p", {
1152
+ className: "text-xs text-gray-500 dark:text-gray-400 pl-1",
1153
+ children: e.lat != null && !i ? "Centre located from our contact data." : i
1154
+ })
1155
+ ]
1156
+ });
1157
+ }
1158
+ //#endregion
1159
+ //#region ../../../gatewaze-modules/modules/segments/admin/pages/components/SegmentBuilder/ConditionRow.tsx
1160
+ function Ce({ condition: e, onChange: t, onRemove: n, depth: r, sources: i = [] }) {
1161
+ let s = [
1162
+ {
1163
+ value: "attribute",
1164
+ label: "Person Attribute"
1165
+ },
1166
+ {
1167
+ value: "event",
1168
+ label: "Person Event"
1169
+ },
1170
+ ...i.map((e) => ({
1171
+ value: e.kind,
1172
+ label: e.label
1173
+ }))
1174
+ ], c = (e) => {
1175
+ if (e === "attribute") {
1176
+ t(M());
1177
+ return;
1178
+ }
1179
+ if (e === "event") {
1180
+ t(ue());
1181
+ return;
1182
+ }
1183
+ let n = i.find((t) => t.kind === e);
1184
+ n && t(me(n));
1185
+ }, l = N(e) ? "attribute" : P(e) ? "event" : e.type, u = F(e) ? i.find((t) => t.kind === e.type) : void 0;
1186
+ return /* @__PURE__ */ (0, z.jsx)(o, {
1187
+ skin: "bordered",
1188
+ className: "p-4 hover:shadow-sm transition-shadow",
1189
+ children: /* @__PURE__ */ (0, z.jsxs)("div", {
1190
+ className: "flex items-start gap-4",
1191
+ children: [
1192
+ /* @__PURE__ */ (0, z.jsxs)("div", {
1193
+ className: "flex-shrink-0 w-44",
1194
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
1195
+ className: "block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1",
1196
+ children: "Type"
1197
+ }), /* @__PURE__ */ (0, z.jsx)("select", {
1198
+ value: l,
1199
+ onChange: (e) => c(e.target.value),
1200
+ className: "w-full rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
1201
+ children: s.map((e) => /* @__PURE__ */ (0, z.jsx)("option", {
1202
+ value: e.value,
1203
+ children: e.label
1204
+ }, e.value))
1205
+ })]
1206
+ }),
1207
+ /* @__PURE__ */ (0, z.jsxs)("div", {
1208
+ className: "flex-1 min-w-0",
1209
+ children: [
1210
+ N(e) && /* @__PURE__ */ (0, z.jsx)(_e, {
1211
+ condition: e,
1212
+ onChange: t
1213
+ }),
1214
+ P(e) && /* @__PURE__ */ (0, z.jsx)(xe, {
1215
+ condition: e,
1216
+ onChange: t
1217
+ }),
1218
+ F(e) && u && /* @__PURE__ */ (0, z.jsx)(Se, {
1219
+ condition: e,
1220
+ source: u,
1221
+ onChange: t
1222
+ }),
1223
+ F(e) && !u && /* @__PURE__ */ (0, z.jsxs)("div", {
1224
+ className: "text-xs text-gray-500 dark:text-gray-400 py-2",
1225
+ children: [
1226
+ "This condition type (",
1227
+ e.type,
1228
+ ") isn't available here."
1229
+ ]
1230
+ })
1231
+ ]
1232
+ }),
1233
+ /* @__PURE__ */ (0, z.jsx)(a, {
1234
+ variant: "flat",
1235
+ color: "error",
1236
+ isIcon: !0,
1237
+ className: "size-9 flex-shrink-0 mt-5",
1238
+ onClick: n,
1239
+ title: "Remove condition",
1240
+ children: /* @__PURE__ */ (0, z.jsx)(B.TrashIcon, { className: "size-4" })
1241
+ })
1242
+ ]
1243
+ })
1244
+ });
1245
+ }
1246
+ //#endregion
1247
+ //#region ../../../gatewaze-modules/modules/segments/admin/pages/components/SegmentBuilder/ConditionGroup.tsx
1248
+ var G = [
1249
+ "border-l-blue-500",
1250
+ "border-l-purple-500",
1251
+ "border-l-orange-500",
1252
+ "border-l-green-500"
1253
+ ];
1254
+ function we({ conditions: e, onChange: t, match: n, depth: r, sources: i = [] }) {
1255
+ let s = (n, r) => {
1256
+ let i = [...e];
1257
+ i[n] = r, t(i);
1258
+ }, c = (n) => {
1259
+ t(e.filter((e, t) => t !== n));
1260
+ }, l = (t, n) => {
1261
+ let r = e[t], i = n === "group" ? de() : M(), a = {
1262
+ ...r,
1263
+ conditions: [...r.conditions, i]
1264
+ };
1265
+ s(t, a);
1266
+ }, u = (t, n) => {
1267
+ let r = e[t];
1268
+ s(t, {
1269
+ ...r,
1270
+ match: n
1271
+ });
1272
+ }, d = (t, n) => {
1273
+ let r = e[t];
1274
+ s(t, {
1275
+ ...r,
1276
+ conditions: n
1277
+ });
1278
+ }, f = n === "all" ? "AND" : "OR", p = G[r % G.length];
1279
+ return /* @__PURE__ */ (0, z.jsx)("div", {
1280
+ className: "space-y-3",
1281
+ children: e.map((e, t) => /* @__PURE__ */ (0, z.jsxs)(k.Fragment, { children: [t > 0 && /* @__PURE__ */ (0, z.jsxs)("div", {
1282
+ className: "flex items-center gap-2 pl-4",
1283
+ children: [
1284
+ /* @__PURE__ */ (0, z.jsx)("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" }),
1285
+ /* @__PURE__ */ (0, z.jsx)("span", {
1286
+ className: `text-xs font-semibold px-2 py-1 rounded ${n === "all" ? "bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400" : "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400"}`,
1287
+ children: f
1288
+ }),
1289
+ /* @__PURE__ */ (0, z.jsx)("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" })
1290
+ ]
1291
+ }), fe(e) ? /* @__PURE__ */ (0, z.jsx)(o, {
1292
+ skin: "bordered",
1293
+ className: `p-4 border-l-4 ${p} bg-gray-50/50 dark:bg-gray-800/30`,
1294
+ children: /* @__PURE__ */ (0, z.jsxs)("div", {
1295
+ className: "space-y-4",
1296
+ children: [
1297
+ /* @__PURE__ */ (0, z.jsxs)("div", {
1298
+ className: "flex items-center justify-between flex-wrap gap-2",
1299
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", {
1300
+ className: "flex items-center gap-2",
1301
+ children: [
1302
+ /* @__PURE__ */ (0, z.jsx)("span", {
1303
+ className: "text-sm text-gray-600 dark:text-gray-400",
1304
+ children: "Match"
1305
+ }),
1306
+ /* @__PURE__ */ (0, z.jsxs)("select", {
1307
+ value: e.match,
1308
+ onChange: (e) => u(t, e.target.value),
1309
+ className: "rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-2 py-1 text-sm font-medium text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
1310
+ children: [/* @__PURE__ */ (0, z.jsx)("option", {
1311
+ value: "all",
1312
+ children: "ALL"
1313
+ }), /* @__PURE__ */ (0, z.jsx)("option", {
1314
+ value: "any",
1315
+ children: "ANY"
1316
+ })]
1317
+ }),
1318
+ /* @__PURE__ */ (0, z.jsx)("span", {
1319
+ className: "text-sm text-gray-600 dark:text-gray-400",
1320
+ children: "conditions in this group"
1321
+ })
1322
+ ]
1323
+ }), /* @__PURE__ */ (0, z.jsx)(a, {
1324
+ variant: "flat",
1325
+ color: "error",
1326
+ size: "sm",
1327
+ onClick: () => c(t),
1328
+ children: "Remove Group"
1329
+ })]
1330
+ }),
1331
+ /* @__PURE__ */ (0, z.jsx)(we, {
1332
+ conditions: e.conditions,
1333
+ onChange: (e) => d(t, e),
1334
+ match: e.match,
1335
+ depth: r + 1,
1336
+ sources: i
1337
+ }),
1338
+ /* @__PURE__ */ (0, z.jsxs)("div", {
1339
+ className: "flex gap-2 pt-2 border-t border-gray-200 dark:border-gray-700",
1340
+ children: [/* @__PURE__ */ (0, z.jsxs)(a, {
1341
+ variant: "flat",
1342
+ size: "sm",
1343
+ onClick: () => l(t, "attribute"),
1344
+ className: "gap-1",
1345
+ children: [/* @__PURE__ */ (0, z.jsx)(B.PlusIcon, { className: "size-3" }), "Add Condition"]
1346
+ }), /* @__PURE__ */ (0, z.jsxs)(a, {
1347
+ variant: "flat",
1348
+ color: "secondary",
1349
+ size: "sm",
1350
+ onClick: () => l(t, "group"),
1351
+ className: "gap-1",
1352
+ children: [/* @__PURE__ */ (0, z.jsx)(B.PlusIcon, { className: "size-3" }), "Add Nested Group"]
1353
+ })]
1354
+ })
1355
+ ]
1356
+ })
1357
+ }) : /* @__PURE__ */ (0, z.jsx)(Ce, {
1358
+ condition: e,
1359
+ onChange: (e) => s(t, e),
1360
+ onRemove: () => c(t),
1361
+ depth: r,
1362
+ sources: i
1363
+ })] }, t))
1364
+ });
1365
+ }
1366
+ //#endregion
1367
+ //#region ../../../gatewaze-modules/modules/segments/admin/pages/components/SegmentPreview.tsx
1368
+ function Te(e) {
1369
+ if (e instanceof Error) return e.message;
1370
+ if (e && typeof e == "object") {
1371
+ let t = e;
1372
+ return t.message || t.details || t.hint || JSON.stringify(e);
1373
+ }
1374
+ return String(e);
1375
+ }
1376
+ function Ee({ definition: e, debounceMs: t = 800 }) {
1377
+ let [r, a] = (0, k.useState)(!1), [c, u] = (0, k.useState)(null), [f, p] = (0, k.useState)([]), [m, h] = (0, k.useState)(null), [g, _] = (0, k.useState)(!1), [v] = i(e, t);
1378
+ (0, k.useEffect)(() => {
1379
+ (async () => {
1380
+ if (!I(v)) {
1381
+ u(null), p([]), h(null), _(!1);
1382
+ return;
1383
+ }
1384
+ if (!n) {
1385
+ h("Database connection not available");
1386
+ return;
1387
+ }
1388
+ a(!0), h(null);
1389
+ try {
1390
+ let e = await R(n).previewSegment(v);
1391
+ u(e.count), p(e.sample), _(e.isEstimate || !1);
1392
+ } catch (e) {
1393
+ console.error("Preview error:", e);
1394
+ let t = Te(e);
1395
+ t.includes("timeout") || t.includes("57014") ? h("Preview timed out. The segment will still work when saved.") : h(t || "Failed to generate preview"), u(null), p([]), _(!1);
1396
+ } finally {
1397
+ a(!1);
1398
+ }
1399
+ })();
1400
+ }, [v]);
1401
+ let y = I(e);
1402
+ return /* @__PURE__ */ (0, z.jsxs)(o, {
1403
+ skin: "bordered",
1404
+ className: `p-5 transition-all duration-300 ${m ? "bg-red-50 dark:bg-red-900/10 border-red-200 dark:border-red-800" : y ? "bg-gradient-to-br from-blue-50 to-indigo-50 dark:from-blue-900/20 dark:to-indigo-900/20 border-blue-200 dark:border-blue-800" : "bg-gray-50 dark:bg-gray-800/50 border-gray-200 dark:border-gray-700"}`,
1405
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", {
1406
+ className: "flex items-center justify-between mb-4",
1407
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", {
1408
+ className: "flex items-center gap-2",
1409
+ children: [/* @__PURE__ */ (0, z.jsx)("div", {
1410
+ className: `p-2 rounded-lg ${m ? "bg-red-100 dark:bg-red-900/30" : "bg-blue-100 dark:bg-blue-900/30"}`,
1411
+ children: m ? /* @__PURE__ */ (0, z.jsx)(B.ExclamationTriangleIcon, { className: "size-5 text-red-600 dark:text-red-400" }) : /* @__PURE__ */ (0, z.jsx)(B.UserGroupIcon, { className: "size-5 text-blue-600 dark:text-blue-400" })
1412
+ }), /* @__PURE__ */ (0, z.jsx)("span", {
1413
+ className: "font-semibold text-gray-800 dark:text-gray-200",
1414
+ children: "Live Preview"
1415
+ })]
1416
+ }), r && /* @__PURE__ */ (0, z.jsx)(d, { className: "size-5" })]
1417
+ }), m ? /* @__PURE__ */ (0, z.jsx)("div", {
1418
+ className: "text-red-600 dark:text-red-400 text-sm",
1419
+ children: m
1420
+ }) : y ? c === null ? /* @__PURE__ */ (0, z.jsx)("div", {
1421
+ className: "text-gray-500 dark:text-gray-400 text-sm",
1422
+ children: "Calculating..."
1423
+ }) : /* @__PURE__ */ (0, z.jsxs)("div", {
1424
+ className: "space-y-4",
1425
+ children: [
1426
+ /* @__PURE__ */ (0, z.jsxs)("div", {
1427
+ className: "flex items-baseline gap-3",
1428
+ children: [/* @__PURE__ */ (0, z.jsx)("span", {
1429
+ className: "text-4xl font-bold text-blue-700 dark:text-blue-300 tabular-nums",
1430
+ children: g ? `${c.toLocaleString()}+` : c.toLocaleString()
1431
+ }), /* @__PURE__ */ (0, z.jsxs)("span", {
1432
+ className: "text-sm text-blue-600 dark:text-blue-400",
1433
+ children: [
1434
+ c === 1 ? "person matches" : "people match",
1435
+ " this segment",
1436
+ g && " (estimate)"
1437
+ ]
1438
+ })]
1439
+ }),
1440
+ f.length > 0 && /* @__PURE__ */ (0, z.jsxs)("div", {
1441
+ className: "space-y-3",
1442
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", {
1443
+ className: "flex items-center gap-2",
1444
+ children: [/* @__PURE__ */ (0, z.jsx)("span", {
1445
+ className: "text-xs font-medium text-gray-600 dark:text-gray-400 uppercase tracking-wide",
1446
+ children: "Sample members"
1447
+ }), /* @__PURE__ */ (0, z.jsx)("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" })]
1448
+ }), /* @__PURE__ */ (0, z.jsxs)("div", {
1449
+ className: "flex flex-wrap gap-2",
1450
+ children: [f.slice(0, 8).map((e) => /* @__PURE__ */ (0, z.jsxs)("div", {
1451
+ className: "flex items-center gap-2 bg-white dark:bg-gray-800 px-3 py-2 rounded-lg shadow-sm border border-gray-100 dark:border-gray-700",
1452
+ children: [/* @__PURE__ */ (0, z.jsx)(l, {
1453
+ name: e.attributes?.first_name && e.attributes?.last_name ? `${e.attributes.first_name} ${e.attributes.last_name}` : e.email,
1454
+ size: 7,
1455
+ initialColor: "auto"
1456
+ }), /* @__PURE__ */ (0, z.jsxs)("div", {
1457
+ className: "min-w-0",
1458
+ children: [/* @__PURE__ */ (0, z.jsx)("div", {
1459
+ className: "text-sm font-medium text-gray-900 dark:text-white truncate max-w-[150px]",
1460
+ children: e.attributes?.first_name ? `${e.attributes.first_name} ${e.attributes.last_name || ""}` : e.email
1461
+ }), e.attributes?.company && /* @__PURE__ */ (0, z.jsx)("div", {
1462
+ className: "text-xs text-gray-500 dark:text-gray-400 truncate max-w-[150px]",
1463
+ children: e.attributes.company
1464
+ })]
1465
+ })]
1466
+ }, e.id)), f.length > 8 && /* @__PURE__ */ (0, z.jsxs)(s, {
1467
+ variant: "soft",
1468
+ color: "info",
1469
+ className: "self-center",
1470
+ children: [
1471
+ "+",
1472
+ f.length - 8,
1473
+ " more"
1474
+ ]
1475
+ })]
1476
+ })]
1477
+ }),
1478
+ c === 0 && /* @__PURE__ */ (0, z.jsx)("div", {
1479
+ className: "text-sm text-gray-500 dark:text-gray-400 bg-white/50 dark:bg-gray-800/50 rounded-lg p-3",
1480
+ children: "No people match these conditions. Try adjusting your criteria."
1481
+ })
1482
+ ]
1483
+ }) : /* @__PURE__ */ (0, z.jsx)("div", {
1484
+ className: "text-gray-500 dark:text-gray-400 text-sm",
1485
+ children: "Complete your segment conditions to see a preview of matching people."
1486
+ })]
1487
+ });
1488
+ }
1489
+ //#endregion
1490
+ //#region ../../../gatewaze-modules/modules/segments/admin/pages/components/SegmentBuilder/index.tsx
1491
+ function De({ value: e, onChange: t, showPreview: r = !0 }) {
1492
+ let [i, s] = (0, k.useState)([]);
1493
+ (0, k.useEffect)(() => {
1494
+ n && R(n).listConditionSources().then(s).catch(() => s([]));
1495
+ }, []);
1496
+ let c = (n) => {
1497
+ t({
1498
+ ...e,
1499
+ match: n
1500
+ });
1501
+ };
1502
+ return /* @__PURE__ */ (0, z.jsxs)("div", {
1503
+ className: "space-y-6",
1504
+ children: [
1505
+ /* @__PURE__ */ (0, z.jsx)(o, {
1506
+ skin: "bordered",
1507
+ className: "p-4 bg-gray-50/50 dark:bg-gray-800/50",
1508
+ children: /* @__PURE__ */ (0, z.jsxs)("div", {
1509
+ className: "flex items-center gap-3 flex-wrap",
1510
+ children: [/* @__PURE__ */ (0, z.jsx)("span", {
1511
+ className: "text-sm font-medium text-gray-700 dark:text-gray-300",
1512
+ children: "Include people where"
1513
+ }), /* @__PURE__ */ (0, z.jsxs)("select", {
1514
+ value: e.match,
1515
+ onChange: (e) => c(e.target.value),
1516
+ className: "rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-3 py-2 text-sm font-medium text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-primary-500",
1517
+ children: [/* @__PURE__ */ (0, z.jsx)("option", {
1518
+ value: "all",
1519
+ children: "ALL of the following are true"
1520
+ }), /* @__PURE__ */ (0, z.jsx)("option", {
1521
+ value: "any",
1522
+ children: "ANY of the following are true"
1523
+ })]
1524
+ })]
1525
+ })
1526
+ }),
1527
+ e.conditions.length > 0 && /* @__PURE__ */ (0, z.jsx)(we, {
1528
+ conditions: e.conditions,
1529
+ onChange: (n) => {
1530
+ t({
1531
+ ...e,
1532
+ conditions: n
1533
+ });
1534
+ },
1535
+ match: e.match,
1536
+ depth: 0,
1537
+ sources: i
1538
+ }),
1539
+ /* @__PURE__ */ (0, z.jsxs)("div", {
1540
+ className: "flex gap-3 flex-wrap",
1541
+ children: [/* @__PURE__ */ (0, z.jsxs)(a, {
1542
+ variant: "outlined",
1543
+ onClick: () => {
1544
+ t({
1545
+ ...e,
1546
+ conditions: [...e.conditions, M()]
1547
+ });
1548
+ },
1549
+ className: "gap-2",
1550
+ children: [/* @__PURE__ */ (0, z.jsx)(B.PlusIcon, { className: "size-4" }), "Add Condition"]
1551
+ }), /* @__PURE__ */ (0, z.jsxs)(a, {
1552
+ variant: "outlined",
1553
+ color: "secondary",
1554
+ onClick: () => {
1555
+ t({
1556
+ ...e,
1557
+ conditions: [...e.conditions, de()]
1558
+ });
1559
+ },
1560
+ className: "gap-2",
1561
+ children: [/* @__PURE__ */ (0, z.jsx)(B.PlusIcon, { className: "size-4" }), "Add Group"]
1562
+ })]
1563
+ }),
1564
+ r && /* @__PURE__ */ (0, z.jsx)(Ee, { definition: e })
1565
+ ]
1566
+ });
1567
+ }
1568
+ //#endregion
1569
+ //#region ../../../gatewaze-modules/modules/broadcasts/admin/components/SegmentCopilot.tsx
1570
+ var Oe = 0, K = () => `m${++Oe}`, ke = [
1571
+ "Everyone who attended the last San Francisco Forum event",
1572
+ "All people in New York",
1573
+ "Job titles containing \"machine learning engineer\"",
1574
+ "People at companies in the US who registered for an event in the last 90 days"
1575
+ ], q = {
1576
+ rootInitial: {
1577
+ display: "flex",
1578
+ flexDirection: "column",
1579
+ justifyContent: "flex-end",
1580
+ height: "100%",
1581
+ minHeight: 0,
1582
+ padding: 12,
1583
+ gap: 12,
1584
+ fontSize: 13,
1585
+ lineHeight: 1.4,
1586
+ color: "var(--gray-12)",
1587
+ boxSizing: "border-box"
1588
+ },
1589
+ rootChat: {
1590
+ display: "flex",
1591
+ flexDirection: "column",
1592
+ height: "100%",
1593
+ minHeight: 0,
1594
+ padding: 0,
1595
+ fontSize: 13,
1596
+ lineHeight: 1.45,
1597
+ color: "var(--gray-12)",
1598
+ boxSizing: "border-box"
1599
+ },
1600
+ headerBar: {
1601
+ padding: "12px 14px 10px",
1602
+ fontSize: 14,
1603
+ fontWeight: 600,
1604
+ color: "var(--gray-12)",
1605
+ borderBottom: "1px solid var(--gray-5)"
1606
+ },
1607
+ messages: {
1608
+ flex: 1,
1609
+ overflowY: "auto",
1610
+ padding: "14px 14px 8px",
1611
+ display: "flex",
1612
+ flexDirection: "column",
1613
+ gap: 10,
1614
+ minHeight: 0
1615
+ },
1616
+ userBubble: {
1617
+ alignSelf: "flex-end",
1618
+ maxWidth: "85%",
1619
+ padding: "8px 12px",
1620
+ fontSize: 13,
1621
+ lineHeight: 1.45,
1622
+ color: "var(--gray-12)",
1623
+ background: "var(--accent-4)",
1624
+ borderRadius: 14,
1625
+ borderTopRightRadius: 4,
1626
+ wordBreak: "break-word"
1627
+ },
1628
+ assistantLine: {
1629
+ alignSelf: "flex-start",
1630
+ maxWidth: "95%",
1631
+ fontSize: 13,
1632
+ lineHeight: 1.5,
1633
+ color: "var(--gray-11)",
1634
+ whiteSpace: "pre-wrap",
1635
+ wordBreak: "break-word"
1636
+ },
1637
+ metaLine: {
1638
+ fontSize: 11,
1639
+ color: "var(--gray-10)",
1640
+ marginTop: 4
1641
+ },
1642
+ footer: {
1643
+ padding: "8px 12px 12px",
1644
+ borderTop: "1px solid var(--gray-5)",
1645
+ display: "flex",
1646
+ flexDirection: "column",
1647
+ gap: 8
1648
+ },
1649
+ footerInitial: {
1650
+ padding: 0,
1651
+ borderTop: "none",
1652
+ display: "flex",
1653
+ flexDirection: "column",
1654
+ gap: 10
1655
+ },
1656
+ composer: {
1657
+ display: "flex",
1658
+ flexDirection: "column",
1659
+ border: "1px solid var(--gray-7)",
1660
+ borderRadius: 14,
1661
+ background: "var(--color-surface)",
1662
+ overflow: "hidden",
1663
+ transition: "border-color 120ms ease, box-shadow 120ms ease"
1664
+ },
1665
+ composerFocused: {
1666
+ borderColor: "var(--accent-8)",
1667
+ boxShadow: "0 0 0 1px var(--accent-8)"
1668
+ },
1669
+ textarea: {
1670
+ width: "100%",
1671
+ minHeight: 56,
1672
+ maxHeight: 260,
1673
+ padding: "12px 14px",
1674
+ fontFamily: "inherit",
1675
+ fontSize: 13,
1676
+ lineHeight: 1.45,
1677
+ color: "inherit",
1678
+ background: "transparent",
1679
+ border: "none",
1680
+ outline: "none",
1681
+ resize: "none",
1682
+ boxSizing: "border-box"
1683
+ },
1684
+ actionsRow: {
1685
+ display: "flex",
1686
+ alignItems: "center",
1687
+ gap: 6,
1688
+ padding: "6px 8px 8px 8px"
1689
+ },
1690
+ iconButton: {
1691
+ display: "inline-flex",
1692
+ alignItems: "center",
1693
+ justifyContent: "center",
1694
+ width: 30,
1695
+ height: 30,
1696
+ padding: 0,
1697
+ background: "transparent",
1698
+ border: "1px solid transparent",
1699
+ borderRadius: 8,
1700
+ cursor: "pointer",
1701
+ color: "var(--gray-11)"
1702
+ },
1703
+ sendButton: {
1704
+ display: "inline-flex",
1705
+ alignItems: "center",
1706
+ justifyContent: "center",
1707
+ width: 30,
1708
+ height: 30,
1709
+ marginLeft: "auto",
1710
+ padding: 0,
1711
+ color: "#fff",
1712
+ background: "var(--accent-9)",
1713
+ border: "1px solid transparent",
1714
+ borderRadius: "50%",
1715
+ cursor: "pointer"
1716
+ },
1717
+ sendButtonDisabled: {
1718
+ opacity: .4,
1719
+ cursor: "not-allowed"
1720
+ }
1721
+ };
1722
+ function Ae() {
1723
+ return /* @__PURE__ */ (0, z.jsx)("svg", {
1724
+ width: "15",
1725
+ height: "15",
1726
+ viewBox: "0 0 24 24",
1727
+ fill: "none",
1728
+ stroke: "currentColor",
1729
+ strokeWidth: "2",
1730
+ strokeLinecap: "round",
1731
+ strokeLinejoin: "round",
1732
+ children: /* @__PURE__ */ (0, z.jsx)("path", { d: "M12 19V5M5 12l7-7 7 7" })
1733
+ });
1734
+ }
1735
+ function je({ brand: e, currentDefinition: t, onDefinition: n }) {
1736
+ let [r, i] = (0, k.useState)([]), [a, o] = (0, k.useState)(""), [s, c] = (0, k.useState)(!1), [l, u] = (0, k.useState)(!1), d = (0, k.useRef)(null), f = (0, k.useRef)(null);
1737
+ (0, k.useEffect)(() => {
1738
+ f.current?.scrollIntoView({ behavior: "smooth" });
1739
+ }, [r, s]), (0, k.useEffect)(() => {
1740
+ let e = d.current;
1741
+ e && (e.style.height = "auto", e.style.height = `${Math.min(e.scrollHeight, 260)}px`);
1742
+ }, [a]);
1743
+ async function p(r) {
1744
+ let l = (r ?? a).trim();
1745
+ if (!(!l || s)) {
1746
+ o(""), i((e) => [...e, {
1747
+ id: K(),
1748
+ role: "user",
1749
+ text: l
1750
+ }]), c(!0);
1751
+ try {
1752
+ let r = await te(l, {
1753
+ brand: e,
1754
+ currentDefinition: t
1755
+ });
1756
+ if (!r.success || !r.definition) {
1757
+ i((e) => [...e, {
1758
+ id: K(),
1759
+ role: "assistant",
1760
+ text: r.error || "I couldn’t build that — try rephrasing."
1761
+ }]);
1762
+ return;
1763
+ }
1764
+ n(r.definition, { suggestedName: r.suggested_name }), i((e) => [...e, {
1765
+ id: K(),
1766
+ role: "assistant",
1767
+ text: r.explanation || "Updated the audience criteria.",
1768
+ warnings: r.warnings,
1769
+ count: r.count
1770
+ }]);
1771
+ } catch (e) {
1772
+ w.error(e instanceof Error ? e.message : "Copilot failed");
1773
+ } finally {
1774
+ c(!1);
1775
+ }
1776
+ }
1777
+ }
1778
+ function m(e) {
1779
+ e.key === "Enter" && !e.shiftKey && (e.preventDefault(), p());
1780
+ }
1781
+ let h = !!a.trim(), g = r.length === 0 && !s, _ = /* @__PURE__ */ (0, z.jsxs)("div", {
1782
+ style: {
1783
+ ...q.composer,
1784
+ ...l ? q.composerFocused : {}
1785
+ },
1786
+ children: [/* @__PURE__ */ (0, z.jsx)("textarea", {
1787
+ ref: d,
1788
+ rows: 2,
1789
+ value: a,
1790
+ onChange: (e) => o(e.target.value),
1791
+ onKeyDown: m,
1792
+ onFocus: () => u(!0),
1793
+ onBlur: () => u(!1),
1794
+ placeholder: "Describe your audience…",
1795
+ maxLength: 2e3,
1796
+ style: q.textarea,
1797
+ autoFocus: g
1798
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
1799
+ style: q.actionsRow,
1800
+ children: /* @__PURE__ */ (0, z.jsx)("button", {
1801
+ type: "button",
1802
+ "aria-label": "Send prompt",
1803
+ onClick: () => p(),
1804
+ disabled: !h || s,
1805
+ style: {
1806
+ ...q.sendButton,
1807
+ ...!h || s ? q.sendButtonDisabled : {}
1808
+ },
1809
+ children: /* @__PURE__ */ (0, z.jsx)(Ae, {})
1810
+ })
1811
+ })]
1812
+ });
1813
+ return g ? /* @__PURE__ */ (0, z.jsxs)("div", {
1814
+ style: q.rootInitial,
1815
+ role: "region",
1816
+ "aria-label": "Audience copilot",
1817
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", {
1818
+ style: {
1819
+ flex: 1,
1820
+ minHeight: 0,
1821
+ display: "flex",
1822
+ flexDirection: "column",
1823
+ justifyContent: "center",
1824
+ gap: 14,
1825
+ padding: "8px 4px"
1826
+ },
1827
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", { children: [/* @__PURE__ */ (0, z.jsx)("div", {
1828
+ style: {
1829
+ fontSize: 16,
1830
+ fontWeight: 600,
1831
+ color: "var(--gray-12)"
1832
+ },
1833
+ children: "Describe your audience"
1834
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
1835
+ style: {
1836
+ fontSize: 13,
1837
+ color: "var(--gray-10)",
1838
+ marginTop: 2
1839
+ },
1840
+ children: "Tell the copilot who should receive this broadcast — it builds the criteria, and you can refine by chatting."
1841
+ })] }), /* @__PURE__ */ (0, z.jsx)("div", {
1842
+ style: {
1843
+ display: "flex",
1844
+ flexDirection: "column",
1845
+ gap: 8
1846
+ },
1847
+ children: ke.map((e) => /* @__PURE__ */ (0, z.jsx)("button", {
1848
+ type: "button",
1849
+ onClick: () => p(e),
1850
+ style: {
1851
+ textAlign: "left",
1852
+ fontSize: 13,
1853
+ padding: "10px 12px",
1854
+ borderRadius: 10,
1855
+ border: "1px solid var(--gray-6)",
1856
+ background: "var(--color-surface)",
1857
+ color: "var(--gray-11)",
1858
+ cursor: "pointer"
1859
+ },
1860
+ children: e
1861
+ }, e))
1862
+ })]
1863
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
1864
+ style: q.footerInitial,
1865
+ children: _
1866
+ })]
1867
+ }) : /* @__PURE__ */ (0, z.jsxs)("div", {
1868
+ style: q.rootChat,
1869
+ role: "region",
1870
+ "aria-label": "Audience copilot",
1871
+ children: [
1872
+ /* @__PURE__ */ (0, z.jsx)("div", {
1873
+ style: q.headerBar,
1874
+ children: "Audience builder"
1875
+ }),
1876
+ /* @__PURE__ */ (0, z.jsxs)("div", {
1877
+ style: q.messages,
1878
+ "aria-live": "polite",
1879
+ children: [
1880
+ r.map((e) => e.role === "user" ? /* @__PURE__ */ (0, z.jsx)("div", {
1881
+ style: q.userBubble,
1882
+ children: e.text
1883
+ }, e.id) : /* @__PURE__ */ (0, z.jsxs)("div", {
1884
+ style: q.assistantLine,
1885
+ children: [
1886
+ /* @__PURE__ */ (0, z.jsx)("div", { children: e.text }),
1887
+ typeof e.count == "number" && /* @__PURE__ */ (0, z.jsxs)("div", {
1888
+ style: q.metaLine,
1889
+ children: [
1890
+ "≈ ",
1891
+ e.count.toLocaleString(),
1892
+ " people match"
1893
+ ]
1894
+ }),
1895
+ e.warnings && e.warnings.length > 0 && /* @__PURE__ */ (0, z.jsx)("ul", {
1896
+ style: {
1897
+ ...q.metaLine,
1898
+ paddingLeft: 16,
1899
+ listStyle: "disc",
1900
+ color: "var(--amber-11)"
1901
+ },
1902
+ children: e.warnings.map((e, t) => /* @__PURE__ */ (0, z.jsx)("li", { children: e }, t))
1903
+ })
1904
+ ]
1905
+ }, e.id)),
1906
+ s && /* @__PURE__ */ (0, z.jsx)("div", {
1907
+ style: q.assistantLine,
1908
+ children: "Thinking…"
1909
+ }),
1910
+ /* @__PURE__ */ (0, z.jsx)("div", { ref: f })
1911
+ ]
1912
+ }),
1913
+ /* @__PURE__ */ (0, z.jsx)("div", {
1914
+ style: q.footer,
1915
+ children: _
1916
+ })
1917
+ ]
1918
+ });
1919
+ }
1920
+ //#endregion
1921
+ //#region ../../../gatewaze-modules/modules/broadcasts/lib/link-tracking.ts
1922
+ var Me = /^(mailto:|tel:|sms:|#|javascript:)/i, Ne = /\{\{|\}\}|\{%|%\}/, Pe = /(^|_)(link|url|href|src)$/i;
1923
+ function Fe(e) {
1924
+ if (!e) return !1;
1925
+ let t = e.trim();
1926
+ return !t || Me.test(t) || Ne.test(t) || /unsubscribe|view[-_]?in[-_]?browser/i.test(t) ? !1 : /^https?:\/\//i.test(t) || t.startsWith("/");
1927
+ }
1928
+ function Ie(e) {
1929
+ return /^https?:\/\//i.test(e.trim());
1930
+ }
1931
+ var Le = /href\s*=\s*["']([^"']+)["']/gi;
1932
+ function Re(e) {
1933
+ let t = [], n;
1934
+ for (Le.lastIndex = 0; (n = Le.exec(e)) !== null;) t.push(n[1]);
1935
+ return t;
1936
+ }
1937
+ function ze(e, t, n) {
1938
+ if (!Fe(n)) return;
1939
+ let r = e.fieldCount.get(t) ?? 0;
1940
+ e.fieldCount.set(t, r + 1), e.occ.push({
1941
+ block_id: e.block.id,
1942
+ brick_id: e.brickId,
1943
+ block_type: e.block.block_type,
1944
+ tracking_slug: e.block.tracking_slug ?? null,
1945
+ field: t,
1946
+ link_index: r,
1947
+ original_url: n
1948
+ });
1949
+ }
1950
+ function J(e, t, n) {
1951
+ if (typeof e == "string") {
1952
+ if (e.includes("<") && /href\s*=/i.test(e)) for (let r of Re(e)) ze(n, t, r);
1953
+ else Ie(e) && Pe.test(t.replace(/\[\d+\]/g, "")) && ze(n, t, e);
1954
+ return;
1955
+ }
1956
+ if (Array.isArray(e)) {
1957
+ e.forEach((e, r) => J(e, `${t}[${r}]`, n));
1958
+ return;
1959
+ }
1960
+ if (e && typeof e == "object") for (let [r, i] of Object.entries(e)) J(i, t ? `${t}.${r}` : r, n);
1961
+ }
1962
+ function Be(e) {
1963
+ let t = [], n = [...e].sort((e, t) => e.sort_order - t.sort_order);
1964
+ for (let e of n) {
1965
+ let n = /* @__PURE__ */ new Map(), r = {
1966
+ occ: t,
1967
+ fieldCount: n,
1968
+ block: e,
1969
+ brickId: null
1970
+ };
1971
+ J(e.content ?? {}, "", r);
1972
+ let i = [...e.bricks ?? []].sort((e, t) => e.sort_order - t.sort_order);
1973
+ for (let r of i) {
1974
+ let i = {
1975
+ occ: t,
1976
+ fieldCount: n,
1977
+ block: e,
1978
+ brickId: r.id
1979
+ };
1980
+ J(r.content ?? {}, `brick:${r.brick_type}`, i);
1981
+ }
1982
+ }
1983
+ return t;
1984
+ }
1985
+ var Ve = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
1986
+ function He(e = 10) {
1987
+ let t = new Uint8Array(e);
1988
+ crypto.getRandomValues(t);
1989
+ let n = "";
1990
+ for (let r = 0; r < e; r++) n += Ve[t[r] % 62];
1991
+ return n;
1992
+ }
1993
+ function Ue(e, t) {
1994
+ let n = e.indexOf("#"), r = n >= 0 ? e.slice(n) : "", i = n >= 0 ? e.slice(0, n) : e, a = i.indexOf("?"), o = a >= 0 ? i.slice(0, a) : i, s = (a >= 0 ? i.slice(a + 1) : "").split("&").filter((e) => e && !/^nlb=/i.test(e));
1995
+ return s.push(`nlb=${encodeURIComponent(t)}`), `${o}?${s.join("&")}${r}`;
1996
+ }
1997
+ function We(e, t) {
1998
+ let n = "", r = 0;
1999
+ for (let i of t) {
2000
+ let t = Ue(i.original_url, i.tracking_key), a = `href="${i.original_url}"`, o = `href='${i.original_url}'`, s = e.indexOf(a, r), c = a.length, l = `href="${t}"`, u = e.indexOf(o, r);
2001
+ u >= 0 && (s < 0 || u < s) && (s = u, c = o.length, l = `href='${t}'`), !(s < 0) && (n += e.slice(r, s) + l, r = s + c);
2002
+ }
2003
+ return n += e.slice(r), n;
2004
+ }
2005
+ //#endregion
2006
+ //#region ../../../gatewaze-modules/modules/broadcasts/lib/broadcast-links.ts
2007
+ function Y(e, t, n) {
2008
+ return `${e}|${t}|${n}`;
2009
+ }
2010
+ function Ge(e, t, n = /* @__PURE__ */ new Map()) {
2011
+ let r = Be(t), i = [], a = [];
2012
+ for (let t of r) {
2013
+ let r = Y(t.block_id, t.field, t.link_index), o = n.get(r) ?? He();
2014
+ i.push({
2015
+ broadcast_id: e,
2016
+ block_id: t.block_id,
2017
+ brick_id: t.brick_id,
2018
+ tracking_key: o,
2019
+ block_type: t.block_type,
2020
+ tracking_slug: t.tracking_slug,
2021
+ field: t.field,
2022
+ link_index: t.link_index,
2023
+ original_url: t.original_url
2024
+ }), a.push({
2025
+ original_url: t.original_url,
2026
+ tracking_key: o
2027
+ });
2028
+ }
2029
+ return {
2030
+ rows: i,
2031
+ taggable: a
2032
+ };
2033
+ }
2034
+ //#endregion
2035
+ //#region ../../../gatewaze-modules/modules/broadcasts/admin/lib/broadcastBlockService.ts
2036
+ var Ke = "id, broadcast_id, templates_block_def_id, block_type, owner_module, sort_order, tracking_slug, content, bricks:broadcast_bricks(id, block_id, templates_brick_def_id, brick_type, sort_order, content)";
2037
+ async function X(e) {
2038
+ let { data: t, error: r } = await n.from("broadcast_blocks").select(Ke).eq("broadcast_id", e).order("sort_order");
2039
+ if (r) throw r;
2040
+ let i = t ?? [];
2041
+ for (let e of i) (e.bricks ??= []).sort((e, t) => e.sort_order - t.sort_order);
2042
+ return i;
2043
+ }
2044
+ async function qe(e, t) {
2045
+ let r = t.sort_order ?? await Je(e), { data: i, error: a } = await n.from("broadcast_blocks").insert({
2046
+ broadcast_id: e,
2047
+ templates_block_def_id: t.templates_block_def_id,
2048
+ block_type: t.block_type,
2049
+ owner_module: t.owner_module ?? null,
2050
+ content: t.content ?? {},
2051
+ tracking_slug: t.tracking_slug ?? null,
2052
+ sort_order: r
2053
+ }).select(Ke).single();
2054
+ if (a) throw a;
2055
+ return i;
2056
+ }
2057
+ async function Je(e) {
2058
+ let { data: t } = await n.from("broadcast_blocks").select("sort_order").eq("broadcast_id", e).order("sort_order", { ascending: !1 }).limit(1).maybeSingle(), r = t?.sort_order;
2059
+ return typeof r == "number" ? r + 1 : 0;
2060
+ }
2061
+ var Z = /* @__PURE__ */ new Map();
2062
+ async function Ye(e, t) {
2063
+ let r = Z.get(e);
2064
+ if (r) return r;
2065
+ let i = (async () => {
2066
+ let r = await X(e);
2067
+ if (r.length > 0) {
2068
+ let t = r.filter((e) => e.block_type === "richtext");
2069
+ return t.length > 0 ? (await Promise.all(t.map((e) => n.from("broadcast_blocks").update({
2070
+ block_type: "text",
2071
+ content: { body: e.content?.html ?? e.content?.body ?? "" }
2072
+ }).eq("id", e.id))), X(e)) : r;
2073
+ }
2074
+ return await qe(e, {
2075
+ templates_block_def_id: null,
2076
+ block_type: "text",
2077
+ owner_module: null,
2078
+ content: { body: (t?.content_json && typeof t.content_json.html == "string" ? t.content_json.html : null) ?? t?.rendered_html ?? null ?? "" },
2079
+ sort_order: 0
2080
+ }), X(e);
2081
+ })();
2082
+ Z.set(e, i);
2083
+ try {
2084
+ return await i;
2085
+ } finally {
2086
+ Z.delete(e);
2087
+ }
2088
+ }
2089
+ function Xe(e) {
2090
+ return {
2091
+ id: e.id,
2092
+ block_type: e.block_type,
2093
+ content: e.content ?? {},
2094
+ sort_order: e.sort_order,
2095
+ tracking_slug: e.tracking_slug,
2096
+ bricks: (e.bricks ?? []).map((e) => ({
2097
+ id: e.id,
2098
+ brick_type: e.brick_type,
2099
+ content: e.content ?? {},
2100
+ sort_order: e.sort_order
2101
+ }))
2102
+ };
2103
+ }
2104
+ async function Ze(e, t) {
2105
+ let { data: r } = await n.from("broadcast_links").select("id, block_id, field, link_index, tracking_key").eq("broadcast_id", e), i = /* @__PURE__ */ new Map();
2106
+ for (let e of r ?? []) i.set(Y(e.block_id, e.field, e.link_index), e.tracking_key);
2107
+ let { rows: a, taggable: o } = Ge(e, t.map(Xe), i);
2108
+ if (a.length > 0) {
2109
+ let { error: e } = await n.from("broadcast_links").upsert(a, { onConflict: "block_id,field,link_index" });
2110
+ if (e) throw e;
2111
+ }
2112
+ let s = new Set(a.map((e) => Y(e.block_id, e.field, e.link_index))), c = (r ?? []).filter((e) => !s.has(Y(e.block_id, e.field, e.link_index))).map((e) => e.id);
2113
+ return c.length > 0 && await n.from("broadcast_links").delete().in("id", c), o;
2114
+ }
2115
+ function Qe(e) {
2116
+ return {
2117
+ version: 2,
2118
+ block_ids: [...e].sort((e, t) => e.sort_order - t.sort_order).map((e) => e.id)
2119
+ };
2120
+ }
2121
+ async function $e(e, t) {
2122
+ let { data: r, error: i } = await n.from("broadcast_blocks").select("id").eq("broadcast_id", e);
2123
+ if (i) throw i;
2124
+ let a = new Set((r ?? []).map((e) => e.id)), o = t.map((t, n) => ({
2125
+ id: t.id,
2126
+ broadcast_id: e,
2127
+ templates_block_def_id: t.block_template?.id ? t.block_template.id : null,
2128
+ block_type: t.block_template?.block_type ?? "text",
2129
+ owner_module: null,
2130
+ sort_order: typeof t.sort_order == "number" ? t.sort_order : (n + 1) * 1e3,
2131
+ tracking_slug: null,
2132
+ content: t.content ?? {}
2133
+ }));
2134
+ if (o.length > 0) {
2135
+ let { error: e } = await n.from("broadcast_blocks").upsert(o, { onConflict: "id" });
2136
+ if (e) throw e;
2137
+ }
2138
+ let s = new Set(o.map((e) => e.id)), c = [...a].filter((e) => !s.has(e));
2139
+ if (c.length > 0) {
2140
+ let { error: e } = await n.from("broadcast_blocks").delete().in("id", c);
2141
+ if (e) throw e;
2142
+ }
2143
+ }
2144
+ async function et(e, t) {
2145
+ let r = await X(e), { error: i } = await n.from("broadcasts").update({
2146
+ rendered_html: t,
2147
+ content_json: Qe(r)
2148
+ }).eq("id", e);
2149
+ if (i) throw i;
2150
+ }
2151
+ //#endregion
2152
+ //#region ../../../gatewaze-modules/modules/broadcasts/admin/components/BroadcastContentEditor.tsx
2153
+ var Q = b([], []), tt = [], nt = [], rt = /* @__PURE__ */ new Set([
2154
+ "ai_summary",
2155
+ "ai_section",
2156
+ "agent_infrastructure",
2157
+ "hot_take",
2158
+ "job_of_week",
2159
+ "podcast",
2160
+ "ml_confessions",
2161
+ "mlops_community",
2162
+ "meme_of_week",
2163
+ "hidden_gems",
2164
+ "last_weeks_take",
2165
+ "reading_group",
2166
+ "how_we_help",
2167
+ "sponsored_ad",
2168
+ "email_only_intro",
2169
+ "intro_paragraph",
2170
+ "cart_summary",
2171
+ "order_receipt",
2172
+ "shipping_tracker",
2173
+ "product_card",
2174
+ "product_grid",
2175
+ "pricing_card",
2176
+ "pricing_comparison"
2177
+ ]), it = [...Q.keys()].filter((e) => !rt.has(e));
2178
+ function at(e) {
2179
+ return {
2180
+ id: e.id,
2181
+ block_template: {
2182
+ id: e.templates_block_def_id ?? "",
2183
+ name: e.block_type,
2184
+ block_type: e.block_type,
2185
+ render_kind: "react-email",
2186
+ content: {
2187
+ html_template: "",
2188
+ rich_text_template: null,
2189
+ has_bricks: !1,
2190
+ schema: {}
2191
+ }
2192
+ },
2193
+ content: e.content ?? {},
2194
+ sort_order: e.sort_order,
2195
+ bricks: []
2196
+ };
2197
+ }
2198
+ function ot(e) {
2199
+ let t = /* @__PURE__ */ new Map();
2200
+ for (let n of e.blocks) {
2201
+ let e = n.block_template, r = e.component_id || e.block_type, i = Q.has(e.block_type) || e.render_kind === "react-email" || e.render_kind === "declarative";
2202
+ t.set(n.id, i ? {
2203
+ render_kind: "react-email",
2204
+ component_id: r
2205
+ } : {
2206
+ render_kind: "mustache",
2207
+ mustache_html: n.block_template.content.html_template ?? ""
2208
+ });
2209
+ }
2210
+ return t;
2211
+ }
2212
+ function st({ broadcast: e, editable: t, onSaved: n, onProceedToSending: r }) {
2213
+ let [i, o] = (0, k.useState)(null), [s, c] = (0, k.useState)(!1), l = (0, k.useMemo)(() => e.created_at ? e.created_at.slice(0, 10) : (/* @__PURE__ */ new Date()).toISOString().slice(0, 10), [e.created_at]), u = (0, k.useRef)(null), [d, f] = (0, k.useState)(null);
2214
+ (0, k.useEffect)(() => {
2215
+ function e() {
2216
+ let e = u.current;
2217
+ if (!e) return;
2218
+ let t = e.getBoundingClientRect().top, n = window.visualViewport?.height ?? window.innerHeight, r = Math.max(320, Math.floor(n - t - 24));
2219
+ f((e) => e === r ? e : r);
2220
+ }
2221
+ e(), window.addEventListener("resize", e), window.visualViewport?.addEventListener("resize", e);
2222
+ let t = new ResizeObserver(e);
2223
+ return u.current && t.observe(u.current), () => {
2224
+ window.removeEventListener("resize", e), window.visualViewport?.removeEventListener("resize", e), t.disconnect();
2225
+ };
2226
+ }, [i]), (0, k.useEffect)(() => {
2227
+ let t = !1;
2228
+ return (async () => {
2229
+ try {
2230
+ let n = await Ye(e.id, {
2231
+ content_json: e.content_json,
2232
+ rendered_html: e.rendered_html
2233
+ });
2234
+ if (t) return;
2235
+ o({
2236
+ id: e.id,
2237
+ edition_date: l,
2238
+ subject: e.subject ?? void 0,
2239
+ preheader: e.preheader ?? void 0,
2240
+ blocks: n.map(at)
2241
+ });
2242
+ } catch (e) {
2243
+ t || w.error(e instanceof Error ? e.message : "Failed to load content");
2244
+ }
2245
+ })(), () => {
2246
+ t = !0;
2247
+ };
2248
+ }, [
2249
+ e.id,
2250
+ l,
2251
+ e.content_json,
2252
+ e.rendered_html,
2253
+ e.subject,
2254
+ e.preheader
2255
+ ]);
2256
+ async function p() {
2257
+ if (!i) return null;
2258
+ await $e(e.id, i.blocks);
2259
+ let t = await X(e.id), n = await Ze(e.id, t), r = await x({
2260
+ edition: i,
2261
+ format: "email",
2262
+ blockMeta: ot(i),
2263
+ wrapperTemplate: null,
2264
+ registry: Q,
2265
+ forSend: !0
2266
+ });
2267
+ return await et(e.id, We(r, n)), D(e.id);
2268
+ }
2269
+ async function m(e) {
2270
+ if (!(!i || s)) {
2271
+ c(!0);
2272
+ try {
2273
+ let t = await p();
2274
+ w.success("Content saved"), t && n(t), e && r();
2275
+ } catch (e) {
2276
+ w.error(e instanceof Error ? e.message : "Failed to save content");
2277
+ } finally {
2278
+ c(!1);
2279
+ }
2280
+ }
2281
+ }
2282
+ let h = t ? /* @__PURE__ */ (0, z.jsxs)(z.Fragment, { children: [/* @__PURE__ */ (0, z.jsx)(a, {
2283
+ variant: "soft",
2284
+ onClick: () => m(!1),
2285
+ disabled: s,
2286
+ children: s ? "Saving…" : "Save"
2287
+ }), /* @__PURE__ */ (0, z.jsx)(a, {
2288
+ variant: "solid",
2289
+ onClick: () => m(!0),
2290
+ disabled: s,
2291
+ children: "Send…"
2292
+ })] }) : null;
2293
+ return i ? /* @__PURE__ */ (0, z.jsx)("div", {
2294
+ ref: u,
2295
+ style: {
2296
+ height: d == null ? "calc(100vh - 260px)" : `${d}px`,
2297
+ overflow: "hidden",
2298
+ boxSizing: "border-box"
2299
+ },
2300
+ children: /* @__PURE__ */ (0, z.jsx)(y, {
2301
+ edition: i,
2302
+ blockTemplates: tt,
2303
+ brickTemplates: nt,
2304
+ enabledRegistryComponentIds: it,
2305
+ wrapperTemplate: null,
2306
+ collectionId: e.id,
2307
+ isSaving: s,
2308
+ onChange: o,
2309
+ hideDefaultActions: !0,
2310
+ toolbarActions: h
2311
+ })
2312
+ }) : /* @__PURE__ */ (0, z.jsx)("p", {
2313
+ className: "text-sm text-[var(--gray-10)]",
2314
+ children: "Loading content…"
2315
+ });
2316
+ }
2317
+ //#endregion
2318
+ //#region ../../../gatewaze-modules/modules/broadcasts/admin/components/BroadcastRepliesTab.tsx
2319
+ var ct = "id, from_email, from_name, subject, body_text, body_html, is_read, is_starred, is_archived, is_auto_reply, auto_reply_reason, forwarded_to, forwarded_at, created_at";
2320
+ function lt({ broadcastId: e }) {
2321
+ let [t, r] = (0, k.useState)([]), [i, a] = (0, k.useState)([]), [o, s] = (0, k.useState)({}), [c, l] = (0, k.useState)(!0), u = (0, k.useCallback)(async () => {
2322
+ let [t, i] = await Promise.all([n.from("broadcast_replies").select(ct).eq("broadcast_id", e).order("created_at", { ascending: !1 }), n.from("broadcast_reply_messages").select("id, reply_id, from_address, to_address, subject, body_html, body_text, attachments, created_at").eq("broadcast_id", e).order("created_at", { ascending: !0 })]), o = t.data || [];
2323
+ r(o), a(i.data || []), s(await p(o.map((e) => e.from_email))), l(!1);
2324
+ }, [e]);
2325
+ return (0, k.useEffect)(() => {
2326
+ u();
2327
+ }, [u]), (0, k.useEffect)(() => {
2328
+ let e = setInterval(u, 3e4);
2329
+ return () => clearInterval(e);
2330
+ }, [u]), c ? /* @__PURE__ */ (0, z.jsx)("div", {
2331
+ className: "flex justify-center py-12",
2332
+ children: /* @__PURE__ */ (0, z.jsx)("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-[var(--accent-9)]" })
2333
+ }) : /* @__PURE__ */ (0, z.jsx)(f, {
2334
+ kind: "broadcast",
2335
+ replies: t,
2336
+ sent: i,
2337
+ personByEmail: o,
2338
+ onReload: u,
2339
+ emptyHint: "Replies to this broadcast will appear here"
2340
+ });
2341
+ }
2342
+ //#endregion
2343
+ //#region ../../../gatewaze-modules/modules/broadcasts/admin/pages/detail.tsx
2344
+ var ut = [
2345
+ {
2346
+ id: "audience",
2347
+ label: "1. Audience"
2348
+ },
2349
+ {
2350
+ id: "content",
2351
+ label: "2. Content"
2352
+ },
2353
+ {
2354
+ id: "sending",
2355
+ label: "3. Sending"
2356
+ },
2357
+ {
2358
+ id: "replies",
2359
+ label: "Replies"
2360
+ }
2361
+ ], $ = "w-full rounded-md border border-[var(--gray-7)] bg-[var(--color-surface)] px-3 py-2 text-sm disabled:opacity-60", dt = (e) => !!e && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e.trim());
2362
+ function ft() {
2363
+ let { id: e, tab: t } = C(), r = S(), i = t && ut.some((e) => e.id === t) ? t : "audience", [a, o] = (0, k.useState)(null), [s, l] = (0, k.useState)(!0), [u, d] = (0, k.useState)(null), [f, p] = (0, k.useState)(null), m = (0, k.useCallback)(async () => {
2364
+ if (e) try {
2365
+ let t = await D(e);
2366
+ if (!t) {
2367
+ w.error("Broadcast not found"), r("/broadcasts");
2368
+ return;
2369
+ }
2370
+ o(t);
2371
+ } catch (e) {
2372
+ w.error(e instanceof Error ? e.message : "Failed to load broadcast");
2373
+ } finally {
2374
+ l(!1);
2375
+ }
2376
+ }, [e, r]);
2377
+ (0, k.useEffect)(() => {
2378
+ m();
2379
+ }, [m]), (0, k.useEffect)(() => {
2380
+ if (!a?.segment_id) {
2381
+ d(null);
2382
+ return;
2383
+ }
2384
+ let e = !1;
2385
+ return R(n).getSegment(a.segment_id).then((t) => {
2386
+ e || d(t?.cached_count ?? null);
2387
+ }).catch(() => {
2388
+ e || d(null);
2389
+ }), () => {
2390
+ e = !0;
2391
+ };
2392
+ }, [a?.segment_id]);
2393
+ let [h, _] = (0, k.useState)([]);
2394
+ (0, k.useEffect)(() => {
2395
+ ie().then(_).catch(() => _([]));
2396
+ }, []);
2397
+ let v = (0, k.useMemo)(() => {
2398
+ if (!a) return null;
2399
+ let e = a.audience_type === "segment" ? !!a.segment_id : (a.list_ids?.length ?? 0) > 0;
2400
+ return {
2401
+ domainKey: "broadcast",
2402
+ title: "Send Broadcast",
2403
+ parentId: a.id,
2404
+ sendsTable: "broadcast_sends",
2405
+ parentFkColumn: "broadcast_id",
2406
+ logSendIdColumn: "broadcast_send_id",
2407
+ tzBreakdownRpc: "broadcast_send_timezone_breakdown",
2408
+ sendEndpoint: "broadcast-send",
2409
+ canSend: !!a.rendered_html && e && !!a.category_list_id && dt(a.from_address),
2410
+ canSendReason: a.rendered_html ? e ? a.category_list_id ? dt(a.from_address) ? void 0 : "Set a valid From address before sending" : "Choose an unsubscribe list before sending" : "Set an audience first" : "Add content before sending",
2411
+ features: {
2412
+ deliveryStrategy: !0,
2413
+ excludeSent: !0
2414
+ },
2415
+ emailDetails: {
2416
+ editable: !0,
2417
+ values: {
2418
+ subject: a.subject || "",
2419
+ preheader: a.preheader || "",
2420
+ fromAddress: a.from_address || "",
2421
+ fromName: a.from_name || "",
2422
+ replyTo: a.reply_to || "",
2423
+ forwardRepliesTo: a.forward_replies_to || ""
2424
+ },
2425
+ async save(e) {
2426
+ let t = await O(a.id, {
2427
+ subject: e.subject || null,
2428
+ preheader: e.preheader || null,
2429
+ from_address: e.fromAddress || null,
2430
+ from_name: e.fromName || null,
2431
+ reply_to: e.replyTo || null,
2432
+ forward_replies_to: e.forwardRepliesTo || null
2433
+ });
2434
+ o(t);
2435
+ }
2436
+ },
2437
+ recipients: {
2438
+ display: a.audience_type === "segment" ? `Segment audience${u == null ? "" : ` (${u.toLocaleString()})`}` : `${a.list_ids?.length ?? 0} list${(a.list_ids?.length ?? 0) === 1 ? "" : "s"}`,
2439
+ editable: !0,
2440
+ editHref: `/broadcasts/${a.id}/audience`,
2441
+ editLabel: "Edit"
2442
+ },
2443
+ unsubscribeList: {
2444
+ options: h,
2445
+ value: a.category_list_id,
2446
+ required: !0,
2447
+ label: "Unsubscribe list",
2448
+ helpText: "Required. Recipients unsubscribe from this list; the footer is added automatically, and only its subscribers within the audience are emailed.",
2449
+ async save(e) {
2450
+ let t = await O(a.id, { category_list_id: e });
2451
+ o(t);
2452
+ }
2453
+ },
2454
+ recipientCount: u,
2455
+ async countRecipients(e, t) {
2456
+ let { data: r, error: i } = await n.rpc("broadcast_recipient_preview_count", {
2457
+ p_audience_type: a.audience_type,
2458
+ p_segment_id: a.audience_type === "segment" ? a.segment_id : null,
2459
+ p_list_ids: a.audience_type === "list" ? a.list_ids ?? [] : null,
2460
+ p_suppression_topic: "broadcasts",
2461
+ p_exclude_send_ids: e.length > 0 ? e : null,
2462
+ p_category_list_id: t ?? a.category_list_id,
2463
+ p_include_prospects: a.include_prospects ?? !1
2464
+ });
2465
+ if (i) throw i;
2466
+ return r ?? 0;
2467
+ },
2468
+ async previewSchedule(e) {
2469
+ let { data: t, error: r } = await n.rpc("broadcast_preview_send_schedule", {
2470
+ p_audience_type: a.audience_type,
2471
+ p_segment_id: a.audience_type === "segment" ? a.segment_id : null,
2472
+ p_list_ids: a.audience_type === "list" ? a.list_ids ?? [] : null,
2473
+ p_category_list_id: a.category_list_id,
2474
+ p_include_prospects: a.include_prospects ?? !1,
2475
+ p_scheduled_at: e.scheduledAt,
2476
+ p_target_local: e.targetLocal,
2477
+ p_default_timezone: e.defaultTimezone,
2478
+ p_suppression_topic: "broadcasts"
2479
+ });
2480
+ if (r) throw r;
2481
+ return t || [];
2482
+ },
2483
+ async createSend(e) {
2484
+ return ne(a.id, e);
2485
+ },
2486
+ async rerenderContent(e) {
2487
+ let { error: t } = await n.from("broadcast_sends").update({
2488
+ subject: a.subject,
2489
+ preheader: a.preheader,
2490
+ from_address: a.from_address,
2491
+ from_name: a.from_name,
2492
+ reply_to: a.reply_to,
2493
+ rendered_html: a.rendered_html,
2494
+ content_json: a.content_json,
2495
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
2496
+ }).eq("id", e);
2497
+ if (t) throw t;
2498
+ },
2499
+ async sendTest(e) {
2500
+ let { data: t, error: r } = await n.functions.invoke("broadcast-send", { body: { test_send: {
2501
+ broadcast_id: a.id,
2502
+ email: e
2503
+ } } });
2504
+ if (r) throw r;
2505
+ let i = t;
2506
+ if (!i?.success) throw Error(i?.error || "Test send failed");
2507
+ }
2508
+ };
2509
+ }, [
2510
+ a,
2511
+ u,
2512
+ h
2513
+ ]);
2514
+ if (s || !a) return /* @__PURE__ */ (0, z.jsx)(E, {
2515
+ title: "Broadcast",
2516
+ children: /* @__PURE__ */ (0, z.jsx)(c, {
2517
+ title: "Broadcasts",
2518
+ children: /* @__PURE__ */ (0, z.jsx)("div", {
2519
+ className: "flex justify-center py-16",
2520
+ children: /* @__PURE__ */ (0, z.jsx)("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-[var(--accent-9)]" })
2521
+ })
2522
+ })
2523
+ });
2524
+ let y = (e) => r(`/broadcasts/${a.id}/${e}`);
2525
+ return /* @__PURE__ */ (0, z.jsx)(E, {
2526
+ title: `Broadcast: ${a.name}`,
2527
+ children: /* @__PURE__ */ (0, z.jsxs)(c, {
2528
+ title: `Broadcasts: ${a.name}`,
2529
+ tabs: ut,
2530
+ activeTabId: i,
2531
+ onTabChange: y,
2532
+ actions: /* @__PURE__ */ (0, z.jsx)("div", {
2533
+ className: "flex items-center gap-3",
2534
+ children: f
2535
+ }),
2536
+ children: [
2537
+ i === "audience" && /* @__PURE__ */ (0, z.jsx)(pt, {
2538
+ b: a,
2539
+ editable: !0,
2540
+ setHeaderActions: p,
2541
+ onSaved: (e) => {
2542
+ o(e), y("content");
2543
+ }
2544
+ }),
2545
+ i === "content" && /* @__PURE__ */ (0, z.jsx)(Tt, {
2546
+ b: a,
2547
+ editable: !0,
2548
+ setHeaderActions: p,
2549
+ onSaved: o,
2550
+ onProceedToSending: () => y("sending")
2551
+ }),
2552
+ i === "sending" && v && /* @__PURE__ */ (0, z.jsxs)("div", {
2553
+ className: "space-y-4",
2554
+ children: [/* @__PURE__ */ (0, z.jsx)(Ct, {
2555
+ b: a,
2556
+ editable: !0,
2557
+ onChanged: o
2558
+ }), /* @__PURE__ */ (0, z.jsx)(g, { adapter: v })]
2559
+ }),
2560
+ i === "replies" && /* @__PURE__ */ (0, z.jsx)(lt, { broadcastId: a.id })
2561
+ ]
2562
+ })
2563
+ });
2564
+ }
2565
+ function pt({ b: e, editable: t, setHeaderActions: r, onSaved: i }) {
2566
+ let [o, s] = (0, k.useState)(le()), [c, l] = (0, k.useState)(!1), [u, d] = (0, k.useState)(!1), [f, p] = (0, k.useState)(!1), [m, h] = (0, k.useState)(""), [g, _] = (0, k.useState)(null), [v, y] = (0, k.useState)([]), [b, x] = (0, k.useState)("table"), S = _t(o), C = S ? b : "table";
2567
+ (0, k.useEffect)(() => {
2568
+ if (!e.segment_id) {
2569
+ d(!0);
2570
+ return;
2571
+ }
2572
+ R(n).getSegment(e.segment_id).then((e) => {
2573
+ e?.definition && (s(e.definition), l(!0));
2574
+ }).catch(() => {}).finally(() => d(!0));
2575
+ }, [e.segment_id]), (0, k.useEffect)(() => {
2576
+ if (!c || !I(o)) {
2577
+ _(null), y([]);
2578
+ return;
2579
+ }
2580
+ let e = setTimeout(() => {
2581
+ R(n).previewSegment(o).then((e) => {
2582
+ _(e.count), y(e.sample ?? []);
2583
+ }).catch(() => {
2584
+ _(null), y([]);
2585
+ });
2586
+ }, 700);
2587
+ return () => clearTimeout(e);
2588
+ }, [o, c]);
2589
+ let T = (0, k.useRef)(null), [E, D] = (0, k.useState)(null);
2590
+ (0, k.useEffect)(() => {
2591
+ function e() {
2592
+ let e = T.current;
2593
+ if (!e) return;
2594
+ let t = e.getBoundingClientRect().top, n = window.visualViewport?.height ?? window.innerHeight, r = Math.max(360, Math.floor(n - t - 24));
2595
+ D((e) => e === r ? e : r);
2596
+ }
2597
+ e(), window.addEventListener("resize", e), window.visualViewport?.addEventListener("resize", e);
2598
+ let t = typeof ResizeObserver < "u" ? new ResizeObserver(e) : null;
2599
+ return t && T.current && t.observe(T.current), () => {
2600
+ window.removeEventListener("resize", e), window.visualViewport?.removeEventListener("resize", e), t?.disconnect();
2601
+ };
2602
+ }, [u]);
2603
+ async function ee() {
2604
+ if (!I(o)) {
2605
+ w.error("Describe an audience first");
2606
+ return;
2607
+ }
2608
+ p(!0);
2609
+ try {
2610
+ let t = R(n), r = (m || `${e.name} audience`).slice(0, 120), a = e.segment_id;
2611
+ a ? (await t.updateSegment(a, { definition: o }), await t.recalculateSegment(a).catch(() => {})) : a = (await t.createSegment({
2612
+ name: r,
2613
+ definition: o
2614
+ })).id;
2615
+ let s = await O(e.id, {
2616
+ audience_type: "segment",
2617
+ segment_id: a
2618
+ });
2619
+ w.success("Audience saved"), i(s);
2620
+ } catch (e) {
2621
+ w.error(e instanceof Error ? e.message : "Failed to save audience");
2622
+ } finally {
2623
+ p(!1);
2624
+ }
2625
+ }
2626
+ return (0, k.useEffect)(() => t ? (r(/* @__PURE__ */ (0, z.jsx)(a, {
2627
+ variant: "solid",
2628
+ onClick: ee,
2629
+ disabled: f || !c,
2630
+ children: f ? "Saving…" : "Save audience & continue"
2631
+ })), () => r(null)) : (r(null), () => r(null)), [
2632
+ t,
2633
+ f,
2634
+ c,
2635
+ o,
2636
+ m
2637
+ ]), u ? /* @__PURE__ */ (0, z.jsxs)("div", {
2638
+ ref: T,
2639
+ className: "-mb-6 flex gap-4 overflow-hidden",
2640
+ style: { height: E == null ? "calc(100vh - 260px)" : `${E}px` },
2641
+ children: [/* @__PURE__ */ (0, z.jsx)("div", {
2642
+ className: "w-[400px] shrink-0 h-full overflow-hidden rounded-xl border border-[var(--gray-5)] bg-[var(--gray-2)]",
2643
+ children: /* @__PURE__ */ (0, z.jsx)(je, {
2644
+ brand: e.brand,
2645
+ currentDefinition: c ? o : null,
2646
+ onDefinition: (e, t) => {
2647
+ s(e), l(!0), t.suggestedName && h(t.suggestedName);
2648
+ }
2649
+ })
2650
+ }), /* @__PURE__ */ (0, z.jsxs)("div", {
2651
+ className: "flex-1 h-full flex flex-col overflow-hidden rounded-xl border border-[var(--gray-5)] bg-[var(--gray-2)]",
2652
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", {
2653
+ className: "flex-1 overflow-y-auto p-4",
2654
+ children: [/* @__PURE__ */ (0, z.jsx)("div", {
2655
+ className: "text-sm font-medium text-[var(--gray-12)] mb-2",
2656
+ children: "Audience criteria"
2657
+ }), /* @__PURE__ */ (0, z.jsx)("div", {
2658
+ className: "rounded-lg border border-[var(--gray-5)] bg-[var(--color-surface)] p-4",
2659
+ children: /* @__PURE__ */ (0, z.jsx)(De, {
2660
+ value: o,
2661
+ onChange: (e) => {
2662
+ s(e), l(!0);
2663
+ },
2664
+ showPreview: !1
2665
+ })
2666
+ })]
2667
+ }), /* @__PURE__ */ (0, z.jsxs)("div", {
2668
+ className: "shrink-0 border-t border-[var(--gray-5)] bg-[var(--color-surface)]",
2669
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", {
2670
+ className: "px-4 py-2 border-b border-[var(--gray-5)] flex items-center justify-between",
2671
+ children: [/* @__PURE__ */ (0, z.jsx)("span", {
2672
+ className: "text-xs font-medium text-[var(--gray-11)]",
2673
+ children: g == null ? "No audience selected yet" : `${g.toLocaleString()} ${g === 1 ? "person" : "people"} in this filter`
2674
+ }), S && /* @__PURE__ */ (0, z.jsx)("div", {
2675
+ className: "inline-flex rounded-md border border-[var(--gray-6)] overflow-hidden text-xs",
2676
+ children: ["table", "map"].map((e) => /* @__PURE__ */ (0, z.jsx)("button", {
2677
+ type: "button",
2678
+ onClick: () => x(e),
2679
+ className: `px-2.5 py-1 ${C === e ? "bg-[var(--accent-9)] text-white" : "text-[var(--gray-11)] hover:bg-[var(--gray-3)]"}`,
2680
+ children: e === "table" ? "Table" : "Map"
2681
+ }, e))
2682
+ })]
2683
+ }), C === "map" ? /* @__PURE__ */ (0, z.jsx)(St, { definition: o }) : /* @__PURE__ */ (0, z.jsx)(xt, {
2684
+ definition: o,
2685
+ sample: v,
2686
+ locationCriteria: S
2687
+ })]
2688
+ })]
2689
+ })]
2690
+ }) : /* @__PURE__ */ (0, z.jsx)("div", {
2691
+ className: "py-10 text-center text-sm text-[var(--gray-10)]",
2692
+ children: "Loading audience…"
2693
+ });
2694
+ }
2695
+ var mt = [
2696
+ {
2697
+ key: "first_name",
2698
+ label: "First name"
2699
+ },
2700
+ {
2701
+ key: "last_name",
2702
+ label: "Last name"
2703
+ },
2704
+ {
2705
+ key: "company",
2706
+ label: "Company"
2707
+ },
2708
+ {
2709
+ key: "job_title",
2710
+ label: "Job title"
2711
+ }
2712
+ ], ht = {
2713
+ city: "City",
2714
+ state: "State",
2715
+ country: "Country",
2716
+ region: "Region",
2717
+ postal: "Postal",
2718
+ email: "Email",
2719
+ timezone: "Timezone",
2720
+ linkedin_url: "LinkedIn",
2721
+ twitter_handle: "Twitter"
2722
+ }, gt = [
2723
+ "city",
2724
+ "state",
2725
+ "region",
2726
+ "country",
2727
+ "postal",
2728
+ "location"
2729
+ ];
2730
+ function _t(e) {
2731
+ let t = !1, n = (e) => {
2732
+ for (let r of e ?? []) r?.type === "geo_radius" || r?.type === "attribute" && typeof r.field == "string" && gt.includes(r.field.replace(/^attributes\./, "")) ? t = !0 : r?.type === "group" && n(r.conditions);
2733
+ };
2734
+ return n(e.conditions), t;
2735
+ }
2736
+ function vt(e) {
2737
+ return ht[e] ?? e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
2738
+ }
2739
+ function yt(e) {
2740
+ let t = [], n = (e) => {
2741
+ for (let r of e ?? []) r?.type === "attribute" && typeof r.field == "string" ? t.push(r.field === "email" ? "email" : r.field.replace(/^attributes\./, "")) : r?.type === "group" && n(r.conditions);
2742
+ };
2743
+ return n(e.conditions), Array.from(new Set(t));
2744
+ }
2745
+ function bt(e, t) {
2746
+ if (t === "email") return e.email ?? "";
2747
+ let n = e.attributes?.[t];
2748
+ return n == null ? "" : String(n);
2749
+ }
2750
+ function xt({ definition: e, sample: t, locationCriteria: n }) {
2751
+ let r = n ? [
2752
+ "city",
2753
+ "state",
2754
+ "region",
2755
+ "country"
2756
+ ] : [], i = Array.from(/* @__PURE__ */ new Set([
2757
+ ...r,
2758
+ ...yt(e),
2759
+ "email"
2760
+ ])).filter((e) => !mt.some((t) => t.key === e)), a = [...mt, ...i.map((e) => ({
2761
+ key: e,
2762
+ label: vt(e)
2763
+ }))];
2764
+ return t.length === 0 ? /* @__PURE__ */ (0, z.jsx)("div", {
2765
+ className: "px-4 py-4 text-xs text-[var(--gray-10)]",
2766
+ children: "No matching people to preview yet."
2767
+ }) : /* @__PURE__ */ (0, z.jsx)("div", {
2768
+ className: "overflow-auto",
2769
+ style: { maxHeight: 180 },
2770
+ children: /* @__PURE__ */ (0, z.jsxs)("table", {
2771
+ className: "w-full text-xs border-collapse",
2772
+ children: [/* @__PURE__ */ (0, z.jsx)("thead", {
2773
+ className: "sticky top-0 bg-[var(--gray-2)]",
2774
+ children: /* @__PURE__ */ (0, z.jsx)("tr", { children: a.map((e) => /* @__PURE__ */ (0, z.jsx)("th", {
2775
+ className: "text-left font-medium text-[var(--gray-10)] px-3 py-1.5 whitespace-nowrap",
2776
+ children: e.label
2777
+ }, e.key)) })
2778
+ }), /* @__PURE__ */ (0, z.jsx)("tbody", { children: t.map((e) => /* @__PURE__ */ (0, z.jsx)("tr", {
2779
+ className: "border-t border-[var(--gray-4)]",
2780
+ children: a.map((t) => /* @__PURE__ */ (0, z.jsx)("td", {
2781
+ className: "px-3 py-1.5 text-[var(--gray-12)] whitespace-nowrap",
2782
+ children: bt(e, t.key) || /* @__PURE__ */ (0, z.jsx)("span", {
2783
+ className: "text-[var(--gray-8)]",
2784
+ children: "—"
2785
+ })
2786
+ }, t.key))
2787
+ }, e.id)) })]
2788
+ })
2789
+ });
2790
+ }
2791
+ function St({ definition: e }) {
2792
+ let [t, r] = (0, k.useState)([]), [i, a] = (0, k.useState)(!0);
2793
+ (0, k.useEffect)(() => {
2794
+ if (!I(e)) {
2795
+ r([]), a(!1);
2796
+ return;
2797
+ }
2798
+ a(!0);
2799
+ let t = setTimeout(() => {
2800
+ R(n).geoAggregate(e).then(r).catch(() => r([])).finally(() => a(!1));
2801
+ }, 500);
2802
+ return () => clearTimeout(t);
2803
+ }, [e]);
2804
+ let o = t.reduce((e, t) => e + t.count, 0);
2805
+ return /* @__PURE__ */ (0, z.jsxs)("div", {
2806
+ className: "p-4 overflow-auto",
2807
+ style: { maxHeight: 480 },
2808
+ children: [/* @__PURE__ */ (0, z.jsx)(ge, {
2809
+ locations: t,
2810
+ loading: i
2811
+ }), !i && /* @__PURE__ */ (0, z.jsx)("p", {
2812
+ className: "mt-2 text-xs text-[var(--gray-9)]",
2813
+ children: t.length > 0 ? `${o.toLocaleString()} located across ${t.length} ${t.length === 1 ? "city" : "cities"} (grouped; contacts without coordinates aren't shown).` : "No location data for this audience yet — dots appear for contacts that have coordinates."
2814
+ })]
2815
+ });
2816
+ }
2817
+ function Ct({ b: e, editable: t, onChanged: n }) {
2818
+ let [r, i] = (0, k.useState)(!1), a = e.include_prospects ?? !1;
2819
+ async function s() {
2820
+ i(!0);
2821
+ try {
2822
+ n(await O(e.id, { include_prospects: !a }));
2823
+ } catch (e) {
2824
+ w.error(e instanceof Error ? e.message : "Failed to update outreach setting");
2825
+ } finally {
2826
+ i(!1);
2827
+ }
2828
+ }
2829
+ return /* @__PURE__ */ (0, z.jsx)(o, {
2830
+ className: `p-4 ${a ? "border-amber-500/60" : ""}`,
2831
+ children: /* @__PURE__ */ (0, z.jsxs)("label", {
2832
+ className: "flex items-start gap-3 cursor-pointer",
2833
+ children: [/* @__PURE__ */ (0, z.jsx)("input", {
2834
+ type: "checkbox",
2835
+ className: "mt-0.5 rounded",
2836
+ checked: a,
2837
+ disabled: !t || r,
2838
+ onChange: s
2839
+ }), /* @__PURE__ */ (0, z.jsxs)("span", { children: [
2840
+ /* @__PURE__ */ (0, z.jsx)("span", {
2841
+ className: "block text-sm font-medium text-[var(--gray-12)]",
2842
+ children: "Outreach send — include prospects"
2843
+ }),
2844
+ /* @__PURE__ */ (0, z.jsx)("span", {
2845
+ className: "block text-xs text-[var(--gray-10)] mt-0.5",
2846
+ children: "Prospects are contacts stored under legitimate interest (e.g. potential speakers or sponsors) who have not opted in. They are excluded from broadcasts unless this is enabled. Only enable for deliberate, targeted outreach (CFP invitations, sponsorship) — never for general marketing. Unsubscribes are honoured either way."
2847
+ }),
2848
+ a && /* @__PURE__ */ (0, z.jsx)("span", {
2849
+ className: "block text-xs font-medium text-amber-600 dark:text-amber-500 mt-1",
2850
+ children: "This send may reach people who never consented to marketing email. Keep it targeted and relevant."
2851
+ })
2852
+ ] })]
2853
+ })
2854
+ });
2855
+ }
2856
+ function wt({ b: e, editable: t, onSaved: n }) {
2857
+ let [r, i] = (0, k.useState)(e.name), [o, s] = (0, k.useState)(!1);
2858
+ (0, k.useEffect)(() => {
2859
+ i(e.name);
2860
+ }, [e.name]);
2861
+ let c = r.trim(), l = t && !o && c.length > 0 && c !== e.name;
2862
+ async function u() {
2863
+ if (l) {
2864
+ s(!0);
2865
+ try {
2866
+ n(await O(e.id, { name: c }));
2867
+ } catch (e) {
2868
+ w.error(e instanceof Error ? e.message : "Failed to rename broadcast");
2869
+ } finally {
2870
+ s(!1);
2871
+ }
2872
+ }
2873
+ }
2874
+ return /* @__PURE__ */ (0, z.jsxs)("div", {
2875
+ className: "flex flex-wrap items-center gap-2",
2876
+ children: [
2877
+ /* @__PURE__ */ (0, z.jsx)("label", {
2878
+ className: "text-sm font-medium text-[var(--gray-12)] shrink-0",
2879
+ children: "Name"
2880
+ }),
2881
+ /* @__PURE__ */ (0, z.jsx)("input", {
2882
+ className: `${$} max-w-md`,
2883
+ value: r,
2884
+ onChange: (e) => i(e.target.value),
2885
+ onKeyDown: (e) => {
2886
+ e.key === "Enter" && u();
2887
+ },
2888
+ disabled: !t || o
2889
+ }),
2890
+ /* @__PURE__ */ (0, z.jsx)(a, {
2891
+ size: "sm",
2892
+ onClick: u,
2893
+ disabled: !l,
2894
+ children: "Save"
2895
+ })
2896
+ ]
2897
+ });
2898
+ }
2899
+ function Tt({ b: e, editable: t, setHeaderActions: n, onSaved: r, onProceedToSending: i }) {
2900
+ let [a, o] = (0, k.useState)([]), [s, c] = (0, k.useState)(e.event_id ?? "");
2901
+ (0, k.useEffect)(() => {
2902
+ ee().then(o).catch(() => o([]));
2903
+ }, []), (0, k.useEffect)(() => (n(null), () => n(null)), [n]);
2904
+ async function l(t) {
2905
+ c(t);
2906
+ try {
2907
+ await O(e.id, { event_id: t || null });
2908
+ } catch (e) {
2909
+ w.error(e instanceof Error ? e.message : "Failed to link event");
2910
+ }
2911
+ }
2912
+ return /* @__PURE__ */ (0, z.jsxs)("div", {
2913
+ className: "space-y-2",
2914
+ children: [
2915
+ /* @__PURE__ */ (0, z.jsxs)("div", {
2916
+ className: "flex flex-wrap items-center justify-between gap-2",
2917
+ children: [/* @__PURE__ */ (0, z.jsxs)("div", {
2918
+ className: "flex flex-wrap items-center gap-2",
2919
+ children: [/* @__PURE__ */ (0, z.jsx)("label", {
2920
+ className: "text-sm font-medium text-[var(--gray-12)] shrink-0",
2921
+ children: "Linked event"
2922
+ }), /* @__PURE__ */ (0, z.jsxs)("select", {
2923
+ className: `${$} max-w-md`,
2924
+ value: s,
2925
+ onChange: (e) => l(e.target.value),
2926
+ disabled: !t,
2927
+ children: [/* @__PURE__ */ (0, z.jsx)("option", {
2928
+ value: "",
2929
+ children: "No linked event (optional — for CFP / event promotion)"
2930
+ }), a.map((e) => /* @__PURE__ */ (0, z.jsxs)("option", {
2931
+ value: e.id,
2932
+ children: [e.event_title || "(untitled event)", e.event_start ? ` — ${new Date(e.event_start).toLocaleDateString()}` : ""]
2933
+ }, e.id))]
2934
+ })]
2935
+ }), /* @__PURE__ */ (0, z.jsx)(wt, {
2936
+ b: e,
2937
+ editable: t,
2938
+ onSaved: r
2939
+ })]
2940
+ }),
2941
+ /* @__PURE__ */ (0, z.jsxs)("p", {
2942
+ className: "text-xs text-[var(--gray-10)]",
2943
+ children: [
2944
+ "Recipient merge fields: ",
2945
+ "{{first_name}}",
2946
+ " ",
2947
+ "{{name}}",
2948
+ " ",
2949
+ "{{company}}",
2950
+ " ",
2951
+ "{{job_title}}",
2952
+ ". The unsubscribe link is added automatically.",
2953
+ s ? ` Event variables: ${re.map((e) => e.token).join(" ")}.` : ""
2954
+ ]
2955
+ }),
2956
+ /* @__PURE__ */ (0, z.jsx)(st, {
2957
+ broadcast: e,
2958
+ editable: t,
2959
+ onSaved: r,
2960
+ onProceedToSending: i
2961
+ })
2962
+ ]
2963
+ });
2964
+ }
2965
+ //#endregion
2966
+ export { ft as default, $ as inputCls };