@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.
- package/README.md +42 -0
- package/dist/AiSkillsPicker-dbFhcanE.js +373 -0
- package/dist/ContentAccessPage-D0HRqPFc.js +264 -0
- package/dist/DataTable-fe6yRVpF.js +1984 -0
- package/dist/DetailPageHeader-D_v7924k.js +69 -0
- package/dist/EditionEmail-CyhC8232.js +8382 -0
- package/dist/GuideContent-DBXKCu7r.js +7580 -0
- package/dist/HostMediaTab-BsIBEQ1v.js +440 -0
- package/dist/InboxPage-C8ivCKdx.js +1112 -0
- package/dist/NewsletterCanvasEditor--B06apn3.js +11453 -0
- package/dist/NewsletterSetupWizard-BqV6-fa5.js +347 -0
- package/dist/NewsletterSignup-DRVZIpOs.js +224 -0
- package/dist/Page-D3u8IZ2a.js +14 -0
- package/dist/Toaster-Cde0i6IA.js +18 -0
- package/dist/Tooltip-CqxUlW1d.js +746 -0
- package/dist/_collectionSlug_-B3UN6M-Q.js +308 -0
- package/dist/_collection_-Qz4k_Qjl.js +139 -0
- package/dist/_edition_-DQXwkI_-.js +301 -0
- package/dist/_id_-CtT7rT9f.js +257 -0
- package/dist/_id_-CzScE4Qn.js +1197 -0
- package/dist/_virtual_gatewaze-modules-BeloWlOa.js +991 -0
- package/dist/admin-B0Mmrh_O.js +1239 -0
- package/dist/admin-CcfoK6vD.js +17 -0
- package/dist/admin-embed.js +21844 -0
- package/dist/admin.css +2 -0
- package/dist/block-editor-vXBShAue.js +226 -0
- package/dist/brand-DklYwIeA.js +11 -0
- package/dist/brick-editor-CmBitMMK.js +225 -0
- package/dist/broadcastService-CBqXNt_N.js +190 -0
- package/dist/classnames-uWIYaD6z.js +44 -0
- package/dist/contentAccessService-Cs7tdAo-.js +59 -0
- package/dist/context-jzuubYRz.js +5 -0
- package/dist/createSafeContext-P1pK0sAN.js +17 -0
- package/dist/detail-B8SVFJJr.js +26285 -0
- package/dist/detail-uFBxRbLF.js +2966 -0
- package/dist/dist-DTrOExw8.js +38806 -0
- package/dist/edition-slug-CARO24Bs.js +7 -0
- package/dist/export-edition-html-C_hdXQu5.js +18893 -0
- package/dist/floating-ui.dom-Cyv879E9.js +987 -0
- package/dist/hooks-C377EXJG.js +2974 -0
- package/dist/img/mlops-logo.png +0 -0
- package/dist/img/mlops-logo2.png +0 -0
- package/dist/index.d.ts +105 -0
- package/dist/jsx-runtime-CjozyJt-.js +180 -0
- package/dist/lib-CylJmhlJ.js +828 -0
- package/dist/list-C0cz0aQz.js +451 -0
- package/dist/list-CIVgIGsU.js +166 -0
- package/dist/logo/mlops-alt.png +0 -0
- package/dist/logo/mlops-logo.png +0 -0
- package/dist/new-r4KWpqa6.js +80 -0
- package/dist/outline-DwDYhYcF.js +6538 -0
- package/dist/pages-Ersfxcz7.js +216 -0
- package/dist/preview/12627f.jpg +0 -0
- package/dist/preview/af009d.jpg +0 -0
- package/dist/public-api-LD11kMxh.js +238 -0
- package/dist/react-DB2tPNit.js +933 -0
- package/dist/react-dom-giQNVXng.js +267 -0
- package/dist/registry-4XrV9iNG.js +7 -0
- package/dist/render-BtUWfMUt.js +59634 -0
- package/dist/resolvePeopleByEmail-hivX2l07.js +828 -0
- package/dist/runtime-config.js +10 -0
- package/dist/sends-BkPO6PG2.js +182 -0
- package/dist/server.browser-Pj3QUa7k.js +15227 -0
- package/dist/shim-BCerG8nb.js +6681 -0
- package/dist/sonnerHostBridge-CXuCMM3R.js +665 -0
- package/dist/src-BWDAOzZO.js +799 -0
- package/dist/starter-templates-CFs-QUdF.js +3077 -0
- package/dist/storage-VDSvnkvR.js +39 -0
- package/dist/templateParser-BQ2IsJ6c.js +49 -0
- package/dist/templates-rjQjWsRr.js +253 -0
- package/dist/theme/gatewaze/android-icon-144x144.png +0 -0
- package/dist/theme/gatewaze/android-icon-192x192.png +0 -0
- package/dist/theme/gatewaze/android-icon-36x36.png +0 -0
- package/dist/theme/gatewaze/android-icon-48x48.png +0 -0
- package/dist/theme/gatewaze/android-icon-72x72.png +0 -0
- package/dist/theme/gatewaze/android-icon-96x96.png +0 -0
- package/dist/theme/gatewaze/favicon-144x144.png +0 -0
- package/dist/theme/gatewaze/favicon-16x16.png +0 -0
- package/dist/theme/gatewaze/favicon-192x192.png +0 -0
- package/dist/theme/gatewaze/favicon-32x32.png +0 -0
- package/dist/theme/gatewaze/favicon-96x96.png +0 -0
- package/dist/theme/gatewaze/favicon.ico +0 -0
- package/dist/theme/gatewaze/gatewaze-icon-512.png +0 -0
- package/dist/theme/gatewaze/gatewaze-logo-black.svg +24 -0
- package/dist/theme/gatewaze/gatewaze-logo-white.svg +20 -0
- package/dist/theme/gatewaze/gatewaze-poweredby-black.svg +25 -0
- package/dist/theme/gatewaze/gatewaze-poweredby-white.svg +25 -0
- package/dist/theme/gatewaze/logo_black.svg +24 -0
- package/dist/theme/gatewaze/logo_white.svg +20 -0
- package/dist/theme-D6odw5nx.js +586 -0
- package/dist/ui-DRIo9Krs.js +9747 -0
- package/dist/upload-DMNfZ6FX.js +505 -0
- package/dist/useModuleFeature-DgsFIUpv.js +8 -0
- package/dist/utils-BcVvIjaY.js +36 -0
- package/dist/with-selector-B8eSdVx_.js +100 -0
- 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 };
|