@burdenoff/fe-libs 2026.1021.13 → 2026.1021.15
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/dist/admin-overview/AdminOverviewActionsContext.d.ts +11 -0
- package/dist/admin-overview/AdminOverviewActionsContext.js +17 -0
- package/dist/admin-overview/AdminOverviewPage.d.ts +4 -0
- package/dist/admin-overview/AdminOverviewPage.js +524 -0
- package/dist/admin-overview/buildHierarchyGraph.d.ts +36 -0
- package/dist/admin-overview/buildHierarchyGraph.js +172 -0
- package/dist/admin-overview/index.d.ts +10 -0
- package/dist/admin-overview/nodes/OrganizationNode.d.ts +9 -0
- package/dist/admin-overview/nodes/OrganizationNode.js +85 -0
- package/dist/admin-overview/nodes/ProjectNode.d.ts +9 -0
- package/dist/admin-overview/nodes/ProjectNode.js +69 -0
- package/dist/admin-overview/nodes/TenantNode.d.ts +9 -0
- package/dist/admin-overview/nodes/TenantNode.js +78 -0
- package/dist/admin-overview/nodes/WorkspaceNode.d.ts +9 -0
- package/dist/admin-overview/nodes/WorkspaceNode.js +136 -0
- package/dist/admin-overview/nodes/nodeStyles.d.ts +7 -0
- package/dist/admin-overview/nodes/nodeStyles.js +10 -0
- package/dist/admin-overview/operations.d.ts +45 -0
- package/dist/admin-overview/operations.js +42 -0
- package/dist/admin-overview.d.ts +2 -0
- package/dist/admin-overview.js +3 -0
- package/dist/chrome/GlobalSearch.js +9 -9
- package/dist/chrome/HeaderThemeSwitcher.js +7 -7
- package/dist/chrome.js +44 -44
- package/dist/platform-pages/AcceptShareRoute.d.ts +33 -0
- package/dist/platform-pages/AcceptShareRoute.js +72 -0
- package/dist/platform-pages/AffiliatesPage.d.ts +16 -0
- package/dist/platform-pages/AffiliatesPage.js +583 -0
- package/dist/platform-pages/AppearanceSettingsPage.d.ts +14 -0
- package/dist/platform-pages/AppearanceSettingsPage.js +14 -0
- package/dist/platform-pages/index.d.ts +20 -0
- package/dist/platform-pages.d.ts +2 -0
- package/dist/platform-pages.js +4 -0
- package/dist/shared/components/DocsLink.d.ts +56 -0
- package/dist/shared/components/DocsLink.js +97 -0
- package/dist/shared/components/index.d.ts +2 -0
- package/dist/shared/config/docsUrls.d.ts +91 -0
- package/dist/shared/config/docsUrls.js +70 -0
- package/dist/shared/config/index.d.ts +2 -0
- package/dist/shared/config/shellRoutes.js +7 -0
- package/dist/shared/feature-flags/FeatureFlagProvider.d.ts +10 -0
- package/dist/shared/feature-flags/FeatureFlagProvider.js +4 -1
- package/dist/shared/feature-flags/index.d.ts +2 -2
- package/dist/shared/feature-flags/useFeatureFlag.d.ts +26 -1
- package/dist/shared/feature-flags/useFeatureFlag.js +25 -12
- package/dist/shared/hooks/usePushDeviceRegistration.js +1 -1
- package/dist/shared/providers/AppShellProvider.js +6 -6
- package/dist/shared-components.js +7 -6
- package/dist/shared-config.js +10 -9
- package/dist/shared-feature-flags.js +4 -4
- package/dist/shared-hooks.js +25 -25
- package/dist/shared-native.js +15 -15
- package/dist/shared-providers-shell.js +12 -12
- package/dist/shared.js +132 -130
- package/dist/shell-native/push-optin.js +4 -4
- package/package.json +16 -3
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
import { resolveGatewayUrls as e } from "../shared/config/gatewayUrls.js";
|
|
2
|
+
import "../shared-config.js";
|
|
3
|
+
import { useAuth as t } from "../shared/providers/shell/AuthProvider.js";
|
|
4
|
+
import { useAuthToken as n } from "../shared/providers/shell/AuthTokenProvider.js";
|
|
5
|
+
import { useCallback as r, useEffect as i, useMemo as a, useReducer as o, useState as s } from "react";
|
|
6
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
7
|
+
//#region src/platform-pages/AffiliatesPage.tsx
|
|
8
|
+
function u(e) {
|
|
9
|
+
return {
|
|
10
|
+
label: "",
|
|
11
|
+
productSlug: e,
|
|
12
|
+
destinationUrl: ""
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
var d = {
|
|
16
|
+
codes: [],
|
|
17
|
+
loading: !0,
|
|
18
|
+
error: null
|
|
19
|
+
};
|
|
20
|
+
function f(e, t) {
|
|
21
|
+
switch (t.type) {
|
|
22
|
+
case "load:start": return {
|
|
23
|
+
...e,
|
|
24
|
+
loading: !0,
|
|
25
|
+
error: null
|
|
26
|
+
};
|
|
27
|
+
case "load:success": return {
|
|
28
|
+
...e,
|
|
29
|
+
loading: !1,
|
|
30
|
+
codes: t.codes
|
|
31
|
+
};
|
|
32
|
+
case "error": return {
|
|
33
|
+
...e,
|
|
34
|
+
loading: !1,
|
|
35
|
+
error: t.message
|
|
36
|
+
};
|
|
37
|
+
case "error:clear": return {
|
|
38
|
+
...e,
|
|
39
|
+
error: null
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
var p = {
|
|
44
|
+
selectedCodeId: null,
|
|
45
|
+
analytics: null,
|
|
46
|
+
notes: []
|
|
47
|
+
};
|
|
48
|
+
function m(e, t) {
|
|
49
|
+
switch (t.type) {
|
|
50
|
+
case "select": return e.selectedCodeId === t.id ? e : {
|
|
51
|
+
selectedCodeId: t.id,
|
|
52
|
+
analytics: null,
|
|
53
|
+
notes: []
|
|
54
|
+
};
|
|
55
|
+
case "detail:loaded": return {
|
|
56
|
+
...e,
|
|
57
|
+
analytics: t.analytics,
|
|
58
|
+
notes: t.notes
|
|
59
|
+
};
|
|
60
|
+
case "notes:set": return {
|
|
61
|
+
...e,
|
|
62
|
+
notes: t.notes
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
async function h(e) {
|
|
67
|
+
let t = await fetch(e.url, {
|
|
68
|
+
method: "POST",
|
|
69
|
+
headers: {
|
|
70
|
+
"content-type": "application/json",
|
|
71
|
+
...e.authToken ? { authorization: `Bearer ${e.authToken}` } : {},
|
|
72
|
+
...e.actorId ? {
|
|
73
|
+
"x-actor-id": e.actorId,
|
|
74
|
+
"x-actor-type": "user"
|
|
75
|
+
} : {}
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify({
|
|
78
|
+
query: e.query,
|
|
79
|
+
variables: e.variables ?? {}
|
|
80
|
+
})
|
|
81
|
+
}), n = await t.json();
|
|
82
|
+
if (!t.ok || n.errors?.length || !n.data) throw Error(n.errors?.[0]?.message ?? "Request failed");
|
|
83
|
+
return n.data;
|
|
84
|
+
}
|
|
85
|
+
function g({ productSlug: g }) {
|
|
86
|
+
let { user: x } = t(), { accessToken: S } = n(), C = S ?? "", w = `${a(() => e(), []).globalBaseUrl}/global/graphql`, [T, E] = o(f, d), [D, O] = o(m, p), [k, A] = s(""), [j, M] = s(() => u(g)), { codes: N, loading: P, error: F } = T, { selectedCodeId: I, analytics: L, notes: R } = D, z = x?.id ?? "", B = r(async () => {
|
|
87
|
+
if (z) {
|
|
88
|
+
E({ type: "load:start" });
|
|
89
|
+
try {
|
|
90
|
+
E({
|
|
91
|
+
type: "load:success",
|
|
92
|
+
codes: (await h({
|
|
93
|
+
url: w,
|
|
94
|
+
authToken: C,
|
|
95
|
+
actorId: z,
|
|
96
|
+
query: "query MyAffiliateCodes {\n myAffiliateCodes(limit: 50, offset: 0) {\n items {\n id code ownerUserId productSlug label description destinationUrl\n isActive visits signups paidConversions storePurchases\n revenueAmount rewardAmount createdAt\n }\n totalCount\n }\n }"
|
|
97
|
+
})).myAffiliateCodes.items
|
|
98
|
+
});
|
|
99
|
+
} catch (e) {
|
|
100
|
+
E({
|
|
101
|
+
type: "error",
|
|
102
|
+
message: e instanceof Error ? e.message : String(e)
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}, [
|
|
107
|
+
w,
|
|
108
|
+
C,
|
|
109
|
+
z
|
|
110
|
+
]);
|
|
111
|
+
i(() => {
|
|
112
|
+
Promise.resolve().then(() => B());
|
|
113
|
+
}, [B]), i(() => {
|
|
114
|
+
!I || !z || Promise.all([h({
|
|
115
|
+
url: w,
|
|
116
|
+
authToken: C,
|
|
117
|
+
actorId: z,
|
|
118
|
+
query: "query CodeAnalytics($id: ID!) {\n affiliateCodeAnalytics(id: $id) {\n visits uniqueJourneys signups paidConversions storePurchases\n revenueAmount rewardAmount conversionRate\n topCountries { country visits conversions }\n topModes { mode visits conversions }\n }\n }",
|
|
119
|
+
variables: { id: I }
|
|
120
|
+
}), h({
|
|
121
|
+
url: w,
|
|
122
|
+
authToken: C,
|
|
123
|
+
actorId: z,
|
|
124
|
+
query: "query CodeNotes($id: ID!) {\n affiliateCode(id: $id) {\n id\n notes { id body authorType createdAt }\n }\n }",
|
|
125
|
+
variables: { id: I }
|
|
126
|
+
})]).then(([e, t]) => {
|
|
127
|
+
O({
|
|
128
|
+
type: "detail:loaded",
|
|
129
|
+
analytics: e.affiliateCodeAnalytics,
|
|
130
|
+
notes: t.affiliateCode?.notes ?? []
|
|
131
|
+
});
|
|
132
|
+
}).catch((e) => E({
|
|
133
|
+
type: "error",
|
|
134
|
+
message: e instanceof Error ? e.message : String(e)
|
|
135
|
+
}));
|
|
136
|
+
}, [
|
|
137
|
+
I,
|
|
138
|
+
w,
|
|
139
|
+
C,
|
|
140
|
+
z
|
|
141
|
+
]);
|
|
142
|
+
let V = r(async () => {
|
|
143
|
+
if (z) try {
|
|
144
|
+
await h({
|
|
145
|
+
url: w,
|
|
146
|
+
authToken: C,
|
|
147
|
+
actorId: z,
|
|
148
|
+
query: "mutation CreateCode($input: CreateAffiliateCodeInput!) {\n createAffiliateCode(input: $input) { id code }\n }",
|
|
149
|
+
variables: { input: j }
|
|
150
|
+
}), M(u(g)), await B();
|
|
151
|
+
} catch (e) {
|
|
152
|
+
E({
|
|
153
|
+
type: "error",
|
|
154
|
+
message: e instanceof Error ? e.message : String(e)
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}, [
|
|
158
|
+
w,
|
|
159
|
+
C,
|
|
160
|
+
z,
|
|
161
|
+
j,
|
|
162
|
+
B,
|
|
163
|
+
g
|
|
164
|
+
]), H = r(async (e) => {
|
|
165
|
+
if (z) try {
|
|
166
|
+
await h({
|
|
167
|
+
url: w,
|
|
168
|
+
authToken: C,
|
|
169
|
+
actorId: z,
|
|
170
|
+
query: "mutation Regen($id: ID!) {\n regenerateAffiliateCode(id: $id) { id code }\n }",
|
|
171
|
+
variables: { id: e }
|
|
172
|
+
}), await B();
|
|
173
|
+
} catch (e) {
|
|
174
|
+
E({
|
|
175
|
+
type: "error",
|
|
176
|
+
message: e instanceof Error ? e.message : String(e)
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}, [
|
|
180
|
+
w,
|
|
181
|
+
C,
|
|
182
|
+
z,
|
|
183
|
+
B
|
|
184
|
+
]), U = r(async (e) => {
|
|
185
|
+
if (z) try {
|
|
186
|
+
await h({
|
|
187
|
+
url: w,
|
|
188
|
+
authToken: C,
|
|
189
|
+
actorId: z,
|
|
190
|
+
query: "mutation Deactivate($id: ID!) {\n deactivateAffiliateCode(id: $id) { id isActive }\n }",
|
|
191
|
+
variables: { id: e }
|
|
192
|
+
}), await B();
|
|
193
|
+
} catch (e) {
|
|
194
|
+
E({
|
|
195
|
+
type: "error",
|
|
196
|
+
message: e instanceof Error ? e.message : String(e)
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}, [
|
|
200
|
+
w,
|
|
201
|
+
C,
|
|
202
|
+
z,
|
|
203
|
+
B
|
|
204
|
+
]), W = r(async () => {
|
|
205
|
+
if (!(!z || !I || !k.trim())) try {
|
|
206
|
+
await h({
|
|
207
|
+
url: w,
|
|
208
|
+
authToken: C,
|
|
209
|
+
actorId: z,
|
|
210
|
+
query: "mutation AddNote($input: AddAffiliateCodeNoteInput!) {\n addAffiliateCodeNote(input: $input) { id body createdAt }\n }",
|
|
211
|
+
variables: { input: {
|
|
212
|
+
codeId: I,
|
|
213
|
+
body: k.trim()
|
|
214
|
+
} }
|
|
215
|
+
}), A(""), O({
|
|
216
|
+
type: "notes:set",
|
|
217
|
+
notes: (await h({
|
|
218
|
+
url: w,
|
|
219
|
+
authToken: C,
|
|
220
|
+
actorId: z,
|
|
221
|
+
query: "query CodeNotes($id: ID!) {\n affiliateCode(id: $id) {\n notes { id body authorType createdAt }\n }\n }",
|
|
222
|
+
variables: { id: I }
|
|
223
|
+
})).affiliateCode?.notes ?? []
|
|
224
|
+
});
|
|
225
|
+
} catch (e) {
|
|
226
|
+
E({
|
|
227
|
+
type: "error",
|
|
228
|
+
message: e instanceof Error ? e.message : String(e)
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}, [
|
|
232
|
+
w,
|
|
233
|
+
C,
|
|
234
|
+
z,
|
|
235
|
+
I,
|
|
236
|
+
k
|
|
237
|
+
]), G = r((e) => {
|
|
238
|
+
O({
|
|
239
|
+
type: "select",
|
|
240
|
+
id: e
|
|
241
|
+
});
|
|
242
|
+
}, []);
|
|
243
|
+
return /* @__PURE__ */ l("div", {
|
|
244
|
+
className: "p-6 space-y-6",
|
|
245
|
+
children: [
|
|
246
|
+
/* @__PURE__ */ l("header", {
|
|
247
|
+
className: "flex items-center justify-between",
|
|
248
|
+
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h1", {
|
|
249
|
+
className: "text-2xl font-semibold text-foreground",
|
|
250
|
+
children: "Affiliates"
|
|
251
|
+
}), /* @__PURE__ */ c("p", {
|
|
252
|
+
className: "text-sm text-muted-foreground",
|
|
253
|
+
children: "Manage your referral codes, see clicks/conversions/earnings, add internal notes."
|
|
254
|
+
})] }), /* @__PURE__ */ c("button", {
|
|
255
|
+
type: "button",
|
|
256
|
+
onClick: () => void B(),
|
|
257
|
+
className: "rounded-md border border-border bg-card px-3 py-2 text-sm font-medium text-foreground",
|
|
258
|
+
children: "Refresh"
|
|
259
|
+
})]
|
|
260
|
+
}),
|
|
261
|
+
F ? /* @__PURE__ */ c("div", {
|
|
262
|
+
className: "rounded-lg border border-destructive bg-card p-3 text-sm text-destructive",
|
|
263
|
+
children: F
|
|
264
|
+
}) : null,
|
|
265
|
+
/* @__PURE__ */ c(_, {
|
|
266
|
+
form: j,
|
|
267
|
+
onChange: M,
|
|
268
|
+
onSubmit: () => void V()
|
|
269
|
+
}),
|
|
270
|
+
/* @__PURE__ */ c(v, {
|
|
271
|
+
loading: P,
|
|
272
|
+
codes: N,
|
|
273
|
+
selectedCodeId: I,
|
|
274
|
+
onSelect: G,
|
|
275
|
+
onRegenerate: (e) => void H(e),
|
|
276
|
+
onDeactivate: (e) => void U(e)
|
|
277
|
+
}),
|
|
278
|
+
I && L ? /* @__PURE__ */ c(y, { analytics: L }) : null,
|
|
279
|
+
I ? /* @__PURE__ */ c(b, {
|
|
280
|
+
notes: R,
|
|
281
|
+
newNote: k,
|
|
282
|
+
onNewNoteChange: A,
|
|
283
|
+
onSubmit: () => void W()
|
|
284
|
+
}) : null
|
|
285
|
+
]
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
function _(e) {
|
|
289
|
+
let { form: t, onChange: n, onSubmit: r } = e;
|
|
290
|
+
return /* @__PURE__ */ l("section", {
|
|
291
|
+
className: "rounded-lg border border-border bg-card p-4",
|
|
292
|
+
children: [
|
|
293
|
+
/* @__PURE__ */ c("h2", {
|
|
294
|
+
className: "mb-3 text-lg font-semibold text-foreground",
|
|
295
|
+
children: "Create new code"
|
|
296
|
+
}),
|
|
297
|
+
/* @__PURE__ */ l("div", {
|
|
298
|
+
className: "grid gap-3 md:grid-cols-3",
|
|
299
|
+
children: [
|
|
300
|
+
/* @__PURE__ */ c("input", {
|
|
301
|
+
"aria-label": "Label (e.g. Summer launch)",
|
|
302
|
+
value: t.label,
|
|
303
|
+
onChange: (e) => n({
|
|
304
|
+
...t,
|
|
305
|
+
label: e.target.value
|
|
306
|
+
}),
|
|
307
|
+
placeholder: "Label (e.g. Summer launch)",
|
|
308
|
+
className: "rounded-md border border-border bg-background px-3 py-2 text-sm"
|
|
309
|
+
}),
|
|
310
|
+
/* @__PURE__ */ c("input", {
|
|
311
|
+
"aria-label": "Product slug",
|
|
312
|
+
value: t.productSlug,
|
|
313
|
+
onChange: (e) => n({
|
|
314
|
+
...t,
|
|
315
|
+
productSlug: e.target.value
|
|
316
|
+
}),
|
|
317
|
+
placeholder: "Product slug",
|
|
318
|
+
className: "rounded-md border border-border bg-background px-3 py-2 text-sm"
|
|
319
|
+
}),
|
|
320
|
+
/* @__PURE__ */ c("input", {
|
|
321
|
+
"aria-label": "Destination URL",
|
|
322
|
+
value: t.destinationUrl,
|
|
323
|
+
onChange: (e) => n({
|
|
324
|
+
...t,
|
|
325
|
+
destinationUrl: e.target.value
|
|
326
|
+
}),
|
|
327
|
+
placeholder: "Destination URL",
|
|
328
|
+
className: "rounded-md border border-border bg-background px-3 py-2 text-sm"
|
|
329
|
+
})
|
|
330
|
+
]
|
|
331
|
+
}),
|
|
332
|
+
/* @__PURE__ */ c("button", {
|
|
333
|
+
type: "button",
|
|
334
|
+
onClick: r,
|
|
335
|
+
className: "mt-3 rounded-md border border-border bg-primary px-3 py-2 text-sm font-medium text-primary-foreground",
|
|
336
|
+
children: "Create code"
|
|
337
|
+
})
|
|
338
|
+
]
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
function v(e) {
|
|
342
|
+
let { loading: t, codes: n, selectedCodeId: r, onSelect: i, onRegenerate: a, onDeactivate: o } = e;
|
|
343
|
+
return /* @__PURE__ */ l("section", {
|
|
344
|
+
className: "rounded-lg border border-border bg-card p-4",
|
|
345
|
+
children: [/* @__PURE__ */ c("h2", {
|
|
346
|
+
className: "mb-3 text-lg font-semibold text-foreground",
|
|
347
|
+
children: "My codes"
|
|
348
|
+
}), t ? /* @__PURE__ */ c("p", {
|
|
349
|
+
className: "text-sm text-muted-foreground",
|
|
350
|
+
children: "Loading…"
|
|
351
|
+
}) : n.length === 0 ? /* @__PURE__ */ c("p", {
|
|
352
|
+
className: "text-sm text-muted-foreground",
|
|
353
|
+
children: "No codes yet. Create one above."
|
|
354
|
+
}) : /* @__PURE__ */ l("table", {
|
|
355
|
+
className: "min-w-full text-sm",
|
|
356
|
+
children: [/* @__PURE__ */ c("thead", {
|
|
357
|
+
className: "text-left text-muted-foreground",
|
|
358
|
+
children: /* @__PURE__ */ l("tr", {
|
|
359
|
+
className: "border-b border-border",
|
|
360
|
+
children: [
|
|
361
|
+
/* @__PURE__ */ c("th", {
|
|
362
|
+
className: "px-3 py-2",
|
|
363
|
+
children: "Code"
|
|
364
|
+
}),
|
|
365
|
+
/* @__PURE__ */ c("th", {
|
|
366
|
+
className: "px-3 py-2",
|
|
367
|
+
children: "Label"
|
|
368
|
+
}),
|
|
369
|
+
/* @__PURE__ */ c("th", {
|
|
370
|
+
className: "px-3 py-2",
|
|
371
|
+
children: "Product"
|
|
372
|
+
}),
|
|
373
|
+
/* @__PURE__ */ c("th", {
|
|
374
|
+
className: "px-3 py-2",
|
|
375
|
+
children: "Visits"
|
|
376
|
+
}),
|
|
377
|
+
/* @__PURE__ */ c("th", {
|
|
378
|
+
className: "px-3 py-2",
|
|
379
|
+
children: "Conversions"
|
|
380
|
+
}),
|
|
381
|
+
/* @__PURE__ */ c("th", {
|
|
382
|
+
className: "px-3 py-2",
|
|
383
|
+
children: "Reward"
|
|
384
|
+
}),
|
|
385
|
+
/* @__PURE__ */ c("th", {
|
|
386
|
+
className: "px-3 py-2",
|
|
387
|
+
children: "Status"
|
|
388
|
+
}),
|
|
389
|
+
/* @__PURE__ */ c("th", {
|
|
390
|
+
className: "px-3 py-2",
|
|
391
|
+
children: "Actions"
|
|
392
|
+
})
|
|
393
|
+
]
|
|
394
|
+
})
|
|
395
|
+
}), /* @__PURE__ */ c("tbody", { children: n.map((e) => /* @__PURE__ */ l("tr", {
|
|
396
|
+
className: `cursor-pointer border-b border-border/70 ${r === e.id ? "bg-muted/40" : ""}`,
|
|
397
|
+
onClick: () => i(e.id),
|
|
398
|
+
children: [
|
|
399
|
+
/* @__PURE__ */ c("td", {
|
|
400
|
+
className: "px-3 py-2 font-mono text-foreground",
|
|
401
|
+
children: e.code
|
|
402
|
+
}),
|
|
403
|
+
/* @__PURE__ */ c("td", {
|
|
404
|
+
className: "px-3 py-2",
|
|
405
|
+
children: e.label ?? "—"
|
|
406
|
+
}),
|
|
407
|
+
/* @__PURE__ */ c("td", {
|
|
408
|
+
className: "px-3 py-2",
|
|
409
|
+
children: e.productSlug ?? "—"
|
|
410
|
+
}),
|
|
411
|
+
/* @__PURE__ */ c("td", {
|
|
412
|
+
className: "px-3 py-2",
|
|
413
|
+
children: e.visits
|
|
414
|
+
}),
|
|
415
|
+
/* @__PURE__ */ c("td", {
|
|
416
|
+
className: "px-3 py-2",
|
|
417
|
+
children: e.paidConversions + e.storePurchases
|
|
418
|
+
}),
|
|
419
|
+
/* @__PURE__ */ c("td", {
|
|
420
|
+
className: "px-3 py-2",
|
|
421
|
+
children: e.rewardAmount.toFixed(2)
|
|
422
|
+
}),
|
|
423
|
+
/* @__PURE__ */ c("td", {
|
|
424
|
+
className: "px-3 py-2",
|
|
425
|
+
children: e.isActive ? "Active" : "Inactive"
|
|
426
|
+
}),
|
|
427
|
+
/* @__PURE__ */ l("td", {
|
|
428
|
+
className: "px-3 py-2",
|
|
429
|
+
children: [/* @__PURE__ */ c("button", {
|
|
430
|
+
type: "button",
|
|
431
|
+
onClick: (t) => {
|
|
432
|
+
t.stopPropagation(), a(e.id);
|
|
433
|
+
},
|
|
434
|
+
className: "mr-2 rounded border border-border px-2 py-1 text-xs",
|
|
435
|
+
children: "Regenerate"
|
|
436
|
+
}), e.isActive ? /* @__PURE__ */ c("button", {
|
|
437
|
+
type: "button",
|
|
438
|
+
onClick: (t) => {
|
|
439
|
+
t.stopPropagation(), o(e.id);
|
|
440
|
+
},
|
|
441
|
+
className: "rounded border border-border px-2 py-1 text-xs",
|
|
442
|
+
children: "Deactivate"
|
|
443
|
+
}) : null]
|
|
444
|
+
})
|
|
445
|
+
]
|
|
446
|
+
}, e.id)) })]
|
|
447
|
+
})]
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
function y({ analytics: e }) {
|
|
451
|
+
return /* @__PURE__ */ l("section", {
|
|
452
|
+
className: "rounded-lg border border-border bg-card p-4",
|
|
453
|
+
children: [
|
|
454
|
+
/* @__PURE__ */ c("h2", {
|
|
455
|
+
className: "mb-3 text-lg font-semibold text-foreground",
|
|
456
|
+
children: "Analytics"
|
|
457
|
+
}),
|
|
458
|
+
/* @__PURE__ */ l("div", {
|
|
459
|
+
className: "grid gap-3 md:grid-cols-4",
|
|
460
|
+
children: [
|
|
461
|
+
/* @__PURE__ */ c(x, {
|
|
462
|
+
label: "Visits",
|
|
463
|
+
value: e.visits
|
|
464
|
+
}),
|
|
465
|
+
/* @__PURE__ */ c(x, {
|
|
466
|
+
label: "Unique journeys",
|
|
467
|
+
value: e.uniqueJourneys
|
|
468
|
+
}),
|
|
469
|
+
/* @__PURE__ */ c(x, {
|
|
470
|
+
label: "Signups",
|
|
471
|
+
value: e.signups
|
|
472
|
+
}),
|
|
473
|
+
/* @__PURE__ */ c(x, {
|
|
474
|
+
label: "Conversion rate",
|
|
475
|
+
value: `${(e.conversionRate * 100).toFixed(1)}%`
|
|
476
|
+
}),
|
|
477
|
+
/* @__PURE__ */ c(x, {
|
|
478
|
+
label: "Paid",
|
|
479
|
+
value: e.paidConversions
|
|
480
|
+
}),
|
|
481
|
+
/* @__PURE__ */ c(x, {
|
|
482
|
+
label: "Store",
|
|
483
|
+
value: e.storePurchases
|
|
484
|
+
}),
|
|
485
|
+
/* @__PURE__ */ c(x, {
|
|
486
|
+
label: "Revenue",
|
|
487
|
+
value: e.revenueAmount.toFixed(2)
|
|
488
|
+
}),
|
|
489
|
+
/* @__PURE__ */ c(x, {
|
|
490
|
+
label: "Reward",
|
|
491
|
+
value: e.rewardAmount.toFixed(2)
|
|
492
|
+
})
|
|
493
|
+
]
|
|
494
|
+
}),
|
|
495
|
+
/* @__PURE__ */ l("div", {
|
|
496
|
+
className: "mt-4 grid gap-3 md:grid-cols-2",
|
|
497
|
+
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h3", {
|
|
498
|
+
className: "mb-2 text-sm font-medium text-foreground",
|
|
499
|
+
children: "Top countries"
|
|
500
|
+
}), e.topCountries.length ? /* @__PURE__ */ c("ul", {
|
|
501
|
+
className: "space-y-1 text-sm",
|
|
502
|
+
children: e.topCountries.map((e) => /* @__PURE__ */ l("li", {
|
|
503
|
+
className: "flex justify-between",
|
|
504
|
+
children: [/* @__PURE__ */ c("span", { children: e.country }), /* @__PURE__ */ c("span", { children: e.visits })]
|
|
505
|
+
}, e.country))
|
|
506
|
+
}) : /* @__PURE__ */ c("p", {
|
|
507
|
+
className: "text-sm text-muted-foreground",
|
|
508
|
+
children: "No data"
|
|
509
|
+
})] }), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h3", {
|
|
510
|
+
className: "mb-2 text-sm font-medium text-foreground",
|
|
511
|
+
children: "Top modes"
|
|
512
|
+
}), e.topModes.length ? /* @__PURE__ */ c("ul", {
|
|
513
|
+
className: "space-y-1 text-sm",
|
|
514
|
+
children: e.topModes.map((e) => /* @__PURE__ */ l("li", {
|
|
515
|
+
className: "flex justify-between",
|
|
516
|
+
children: [/* @__PURE__ */ c("span", { children: e.mode }), /* @__PURE__ */ c("span", { children: e.visits })]
|
|
517
|
+
}, e.mode))
|
|
518
|
+
}) : /* @__PURE__ */ c("p", {
|
|
519
|
+
className: "text-sm text-muted-foreground",
|
|
520
|
+
children: "No data"
|
|
521
|
+
})] })]
|
|
522
|
+
})
|
|
523
|
+
]
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
function b(e) {
|
|
527
|
+
let { notes: t, newNote: n, onNewNoteChange: r, onSubmit: i } = e;
|
|
528
|
+
return /* @__PURE__ */ l("section", {
|
|
529
|
+
className: "rounded-lg border border-border bg-card p-4",
|
|
530
|
+
children: [
|
|
531
|
+
/* @__PURE__ */ c("h2", {
|
|
532
|
+
className: "mb-3 text-lg font-semibold text-foreground",
|
|
533
|
+
children: "Internal notes"
|
|
534
|
+
}),
|
|
535
|
+
/* @__PURE__ */ l("div", {
|
|
536
|
+
className: "flex items-center gap-2",
|
|
537
|
+
children: [/* @__PURE__ */ c("input", {
|
|
538
|
+
"aria-label": "Note for this code",
|
|
539
|
+
value: n,
|
|
540
|
+
onChange: (e) => r(e.target.value),
|
|
541
|
+
placeholder: "Add a note for this code…",
|
|
542
|
+
className: "flex-1 rounded-md border border-border bg-background px-3 py-2 text-sm"
|
|
543
|
+
}), /* @__PURE__ */ c("button", {
|
|
544
|
+
type: "button",
|
|
545
|
+
onClick: i,
|
|
546
|
+
className: "rounded-md border border-border bg-primary px-3 py-2 text-sm font-medium text-primary-foreground",
|
|
547
|
+
children: "Add"
|
|
548
|
+
})]
|
|
549
|
+
}),
|
|
550
|
+
/* @__PURE__ */ l("ul", {
|
|
551
|
+
className: "mt-4 space-y-2",
|
|
552
|
+
children: [t.map((e) => /* @__PURE__ */ l("li", {
|
|
553
|
+
className: "rounded-md border border-border bg-background p-2 text-sm",
|
|
554
|
+
children: [/* @__PURE__ */ l("div", {
|
|
555
|
+
className: "text-xs text-muted-foreground",
|
|
556
|
+
children: [
|
|
557
|
+
e.authorType,
|
|
558
|
+
" · ",
|
|
559
|
+
new Date(e.createdAt).toLocaleString()
|
|
560
|
+
]
|
|
561
|
+
}), /* @__PURE__ */ c("div", { children: e.body })]
|
|
562
|
+
}, e.id)), t.length === 0 ? /* @__PURE__ */ c("li", {
|
|
563
|
+
className: "text-sm text-muted-foreground",
|
|
564
|
+
children: "No notes yet."
|
|
565
|
+
}) : null]
|
|
566
|
+
})
|
|
567
|
+
]
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
function x({ label: e, value: t }) {
|
|
571
|
+
return /* @__PURE__ */ l("div", {
|
|
572
|
+
className: "rounded-md border border-border bg-background p-3",
|
|
573
|
+
children: [/* @__PURE__ */ c("p", {
|
|
574
|
+
className: "text-xs text-muted-foreground",
|
|
575
|
+
children: e
|
|
576
|
+
}), /* @__PURE__ */ c("p", {
|
|
577
|
+
className: "text-lg font-semibold text-foreground",
|
|
578
|
+
children: t
|
|
579
|
+
})]
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
//#endregion
|
|
583
|
+
export { g as AffiliatesPage };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Appearance / Theme Preferences page.
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around the shared Boff UI 2.0 `ThemePreferences` customizer
|
|
5
|
+
* (fe-libs/chrome). It exposes the full system: the six built-in themes,
|
|
6
|
+
* per-product accent, density, typography, glass intensity, reduced motion,
|
|
7
|
+
* and user-designed CUSTOM themes (create / save / apply / delete) — all wired
|
|
8
|
+
* straight to the fe-libs ThemeProvider and persisted, with a live preview.
|
|
9
|
+
*
|
|
10
|
+
* Shared by every app shell (`@burdenoff/fe-libs/platform-pages`); mount it at
|
|
11
|
+
* `/settings/appearance`. It is purely client-side, so it needs no gateway.
|
|
12
|
+
*/
|
|
13
|
+
export declare function AppearanceSettingsPage(): import('react/jsx-runtime').JSX.Element;
|
|
14
|
+
export default AppearanceSettingsPage;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ThemePreferences as e } from "../chrome/ThemePreferences.js";
|
|
2
|
+
import { jsx as t } from "react/jsx-runtime";
|
|
3
|
+
//#region src/platform-pages/AppearanceSettingsPage.tsx
|
|
4
|
+
function n() {
|
|
5
|
+
return /* @__PURE__ */ t("div", {
|
|
6
|
+
className: "min-h-full bg-bg-canvas",
|
|
7
|
+
children: /* @__PURE__ */ t("div", {
|
|
8
|
+
className: "mx-auto w-full max-w-6xl px-4 py-6 md:px-6 lg:px-8",
|
|
9
|
+
children: /* @__PURE__ */ t(e, {})
|
|
10
|
+
})
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { n as default };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @burdenoff/fe-libs/platform-pages
|
|
3
|
+
*
|
|
4
|
+
* Platform pages that every app shell mounts at the same paths. They used to be
|
|
5
|
+
* copied into each shell (vibecontrols-app first), so the copies drifted; the
|
|
6
|
+
* shells now import them from here.
|
|
7
|
+
*
|
|
8
|
+
* | Page | Path | Mount |
|
|
9
|
+
* |--------------------------|--------------------------|--------------------------------|
|
|
10
|
+
* | `AppearanceSettingsPage` | `/settings/appearance` | protected, no gateway |
|
|
11
|
+
* | `AffiliatesPage` | `/affiliates` | protected (global gateway URL) |
|
|
12
|
+
* | `AcceptShareRoute` | `/share/accept/:token` | protected (workspace gateway) |
|
|
13
|
+
*
|
|
14
|
+
* `AdminOverviewPage` (`/admin/overview`) lives in
|
|
15
|
+
* `@burdenoff/fe-libs/admin-overview` because it needs the optional
|
|
16
|
+
* `@xyflow/react` peer.
|
|
17
|
+
*/
|
|
18
|
+
export { AppearanceSettingsPage } from './AppearanceSettingsPage';
|
|
19
|
+
export { AffiliatesPage, type AffiliatesPageProps } from './AffiliatesPage';
|
|
20
|
+
export { AcceptShareRoute, resolveAcceptedShareDestination, type AcceptShareRouteProps, } from './AcceptShareRoute';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import e from "./platform-pages/AppearanceSettingsPage.js";
|
|
2
|
+
import { AffiliatesPage as t } from "./platform-pages/AffiliatesPage.js";
|
|
3
|
+
import { AcceptShareRoute as n, resolveAcceptedShareDestination as r } from "./platform-pages/AcceptShareRoute.js";
|
|
4
|
+
export { n as AcceptShareRoute, t as AffiliatesPage, e as AppearanceSettingsPage, r as resolveAcceptedShareDestination };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AnchorHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import { DocsEnvironment } from '../config/docsUrls';
|
|
3
|
+
export declare const PUBLIC_PRODUCT_DOCS_URL_QUERY: import('graphql').DocumentNode;
|
|
4
|
+
/** Minimal client surface the registry lookup needs (an ApolloClient satisfies it). */
|
|
5
|
+
export interface DocsRegistryClient {
|
|
6
|
+
query: (options: {
|
|
7
|
+
query: typeof PUBLIC_PRODUCT_DOCS_URL_QUERY;
|
|
8
|
+
variables: {
|
|
9
|
+
slug: string;
|
|
10
|
+
};
|
|
11
|
+
fetchPolicy: 'cache-first';
|
|
12
|
+
}) => Promise<{
|
|
13
|
+
data?: unknown;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
/** Read `publicProduct.docsUrl` out of a query result, trusted origins only. */
|
|
17
|
+
export declare function readRegistryDocsUrl(data: unknown): string | null;
|
|
18
|
+
/** The cached registry docsUrl for a slug: string, `null` (none), or undefined (not fetched). */
|
|
19
|
+
export declare function getCachedRegistryDocsUrl(productSlug: string): string | null | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Look up the registry docsUrl once per slug. Failures resolve to `null` (the
|
|
22
|
+
* catalog default stays in use) and are not cached, so a later mount retries.
|
|
23
|
+
*/
|
|
24
|
+
export declare function fetchRegistryDocsUrl(client: DocsRegistryClient, productSlug: string): Promise<string | null>;
|
|
25
|
+
/** Test seam: forget every cached registry answer. */
|
|
26
|
+
export declare function resetRegistryDocsUrlCache(): void;
|
|
27
|
+
export interface UseProductDocsOptions {
|
|
28
|
+
/** Another product's docs instead of the running shell's. */
|
|
29
|
+
productSlug?: string;
|
|
30
|
+
/** Skip the registry lookup and use the static catalog default only. */
|
|
31
|
+
registry?: boolean;
|
|
32
|
+
/** Override the detected environment (tests, previews). */
|
|
33
|
+
environment?: DocsEnvironment;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* The environment-correct docs origin for the running shell's product, e.g.
|
|
37
|
+
* `https://docs.vibecontrols.com` or `https://alphadocs.vibecontrols.com`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function useProductDocsOrigin(options?: UseProductDocsOptions): string | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* The environment-correct docs URL for a page of the running shell's product.
|
|
42
|
+
* `path` is site-relative (`/users/workflows`); undefined when it is not, or
|
|
43
|
+
* when the product has no trusted docs host.
|
|
44
|
+
*/
|
|
45
|
+
export declare function useProductDocsUrl(path?: string, options?: UseProductDocsOptions): string | undefined;
|
|
46
|
+
export interface DocsLinkProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href' | 'target' | 'rel'>, UseProductDocsOptions {
|
|
47
|
+
/** Site-relative docs path, e.g. `/users/workflows`. Defaults to the docs home. */
|
|
48
|
+
path?: string;
|
|
49
|
+
children: ReactNode;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A new-tab link to the product's docs for the current environment. Renders
|
|
53
|
+
* its children without a link when no trusted docs URL resolves, so a page
|
|
54
|
+
* never shows a dead "Learn more".
|
|
55
|
+
*/
|
|
56
|
+
export declare function DocsLink({ path, productSlug, registry, environment, children, ...anchorProps }: DocsLinkProps): import('react/jsx-runtime').JSX.Element;
|