@burdenoff/fe-libs 2026.1021.14 → 2026.1022.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/admin-overview/AdminOverviewActionsContext.d.ts +11 -0
  2. package/dist/admin-overview/AdminOverviewActionsContext.js +17 -0
  3. package/dist/admin-overview/AdminOverviewPage.d.ts +4 -0
  4. package/dist/admin-overview/AdminOverviewPage.js +524 -0
  5. package/dist/admin-overview/buildHierarchyGraph.d.ts +36 -0
  6. package/dist/admin-overview/buildHierarchyGraph.js +172 -0
  7. package/dist/admin-overview/index.d.ts +10 -0
  8. package/dist/admin-overview/nodes/OrganizationNode.d.ts +9 -0
  9. package/dist/admin-overview/nodes/OrganizationNode.js +85 -0
  10. package/dist/admin-overview/nodes/ProjectNode.d.ts +9 -0
  11. package/dist/admin-overview/nodes/ProjectNode.js +69 -0
  12. package/dist/admin-overview/nodes/TenantNode.d.ts +9 -0
  13. package/dist/admin-overview/nodes/TenantNode.js +78 -0
  14. package/dist/admin-overview/nodes/WorkspaceNode.d.ts +9 -0
  15. package/dist/admin-overview/nodes/WorkspaceNode.js +136 -0
  16. package/dist/admin-overview/nodes/nodeStyles.d.ts +7 -0
  17. package/dist/admin-overview/nodes/nodeStyles.js +10 -0
  18. package/dist/admin-overview/operations.d.ts +45 -0
  19. package/dist/admin-overview/operations.js +42 -0
  20. package/dist/admin-overview.d.ts +2 -0
  21. package/dist/admin-overview.js +3 -0
  22. package/dist/chrome/GlobalSearch.js +9 -9
  23. package/dist/chrome/HeaderThemeSwitcher.js +7 -7
  24. package/dist/chrome.js +44 -44
  25. package/dist/platform-pages/AcceptShareRoute.d.ts +33 -0
  26. package/dist/platform-pages/AcceptShareRoute.js +72 -0
  27. package/dist/platform-pages/AffiliatesPage.d.ts +16 -0
  28. package/dist/platform-pages/AffiliatesPage.js +583 -0
  29. package/dist/platform-pages/AppearanceSettingsPage.d.ts +14 -0
  30. package/dist/platform-pages/AppearanceSettingsPage.js +14 -0
  31. package/dist/platform-pages/index.d.ts +20 -0
  32. package/dist/platform-pages.d.ts +2 -0
  33. package/dist/platform-pages.js +4 -0
  34. package/dist/shared/config/shellRoutes.js +7 -0
  35. package/dist/shared/feature-flags/FeatureFlagProvider.d.ts +10 -0
  36. package/dist/shared/feature-flags/FeatureFlagProvider.js +4 -1
  37. package/dist/shared/feature-flags/index.d.ts +2 -2
  38. package/dist/shared/feature-flags/useFeatureFlag.d.ts +26 -1
  39. package/dist/shared/feature-flags/useFeatureFlag.js +25 -12
  40. package/dist/shared/hooks/shell/useGlobalSearch.d.ts +11 -2
  41. package/dist/shared/hooks/shell/useGlobalSearch.js +54 -23
  42. package/dist/shared/hooks/usePushDeviceRegistration.js +1 -1
  43. package/dist/shared/providers/AppShellProvider.js +6 -6
  44. package/dist/shared-feature-flags.js +4 -4
  45. package/dist/shared-hooks.js +25 -25
  46. package/dist/shared-native.js +15 -15
  47. package/dist/shared-providers-shell.js +12 -12
  48. package/dist/shared.js +94 -94
  49. package/dist/shell-native/push-optin.js +4 -4
  50. 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,2 @@
1
+ export * from './platform-pages/index.js'
2
+ export {}
@@ -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 };
@@ -152,6 +152,13 @@ var e = {
152
152
  showFooter: !1,
153
153
  showBreadcrumb: !1
154
154
  },
155
+ {
156
+ pattern: /^\/vault\/share\//,
157
+ showHeader: !1,
158
+ showSidebar: !1,
159
+ showFooter: !1,
160
+ showBreadcrumb: !1
161
+ },
155
162
  {
156
163
  pattern: /^\/share\/accept\//,
157
164
  showHeader: !1,
@@ -44,3 +44,13 @@ debug, defaultEnabled, }: FeatureFlagProviderProps): import('react/jsx-runtime')
44
44
  * ```
45
45
  */
46
46
  export declare function useFeatureFlags(): FeatureFlagContextValue;
47
+ /**
48
+ * Like `useFeatureFlags`, but returns `null` instead of throwing when no
49
+ * `FeatureFlagProvider` is mounted above the caller.
50
+ *
51
+ * For code that runs in hosts it does not control — a microfrontend or SDK
52
+ * component mounted by many app shells, only some of which mount the provider.
53
+ * Shell code should keep using `useFeatureFlags`, whose throw surfaces a missing
54
+ * provider at once.
55
+ */
56
+ export declare function useOptionalFeatureFlags(): FeatureFlagContextValue | null;
@@ -107,5 +107,8 @@ function f() {
107
107
  if (!e) throw Error("useFeatureFlags must be used within a FeatureFlagProvider");
108
108
  return e;
109
109
  }
110
+ function p() {
111
+ return n(u);
112
+ }
110
113
  //#endregion
111
- export { d as FeatureFlagProvider, f as useFeatureFlags };
114
+ export { d as FeatureFlagProvider, f as useFeatureFlags, p as useOptionalFeatureFlags };
@@ -29,9 +29,9 @@
29
29
  * </FeatureGate>
30
30
  * ```
31
31
  */
32
- export { FeatureFlagProvider, useFeatureFlags } from './FeatureFlagProvider';
32
+ export { FeatureFlagProvider, useFeatureFlags, useOptionalFeatureFlags, } from './FeatureFlagProvider';
33
33
  export type { FeatureFlagProviderProps } from './FeatureFlagProvider';
34
- export { useFeatureFlag, useFeatureFlagValue, useFeatureFlagDetails } from './useFeatureFlag';
34
+ export { useFeatureFlag, useOptionalFeatureFlag, useFeatureFlagValue, useFeatureFlagDetails, } from './useFeatureFlag';
35
35
  export { FeatureGate } from './FeatureGate';
36
36
  export type { FeatureGateProps } from './FeatureGate';
37
37
  export type { FlagValue, FlagType, FlagStatus, FlagEvaluation, BulkEvaluationResponse, FeatureFlagProviderConfig, FeatureFlagContextValue, } from './types';