@burdenoff/microfe-subscriberbot 2026.706.1 → 2026.706.2

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 (23) hide show
  1. package/dist/subscriberbot/components/Modal.js +51 -0
  2. package/dist/subscriberbot/components/Modal.js.map +1 -0
  3. package/dist/subscriberbot/hooks/useSubscriberBotApi.js +358 -163
  4. package/dist/subscriberbot/hooks/useSubscriberBotApi.js.map +1 -1
  5. package/dist/subscriberbot/pages/InboxPage.js +339 -66
  6. package/dist/subscriberbot/pages/InboxPage.js.map +1 -1
  7. package/dist/subscriberbot/pages/InvoicesPage.js +496 -73
  8. package/dist/subscriberbot/pages/InvoicesPage.js.map +1 -1
  9. package/dist/subscriberbot/pages/WorkflowsPage.js +136 -150
  10. package/dist/subscriberbot/pages/WorkflowsPage.js.map +1 -1
  11. package/dist/subscriberbot/pages/agents/AgentDetailPage.js +197 -58
  12. package/dist/subscriberbot/pages/agents/AgentDetailPage.js.map +1 -1
  13. package/dist/subscriberbot/pages/agents/AgentsListPage.js +2 -0
  14. package/dist/subscriberbot/pages/agents/AgentsListPage.js.map +1 -1
  15. package/dist/subscriberbot/pages/providers/ProviderDetailPage.js +538 -71
  16. package/dist/subscriberbot/pages/providers/ProviderDetailPage.js.map +1 -1
  17. package/dist/subscriberbot/pages/providers/ProvidersListPage.js +2 -0
  18. package/dist/subscriberbot/pages/providers/ProvidersListPage.js.map +1 -1
  19. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js +664 -126
  20. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js.map +1 -1
  21. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js +18 -16
  22. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js.map +1 -1
  23. package/package.json +1 -1
@@ -4,14 +4,40 @@ import { formatCurrency as n, formatDate as r, formatEnumLabel as i, formatInter
4
4
  import { StatusBadge as o } from "../../components/StatusBadge.js";
5
5
  import { EmptyState as s } from "../../components/EmptyState.js";
6
6
  import { ErrorView as c, LoadingView as l, Section as u } from "../../components/StateViews.js";
7
- import { useCancelRelationship as d, useRelationship as f, useTransitionRelationship as p } from "../../hooks/useSubscriberBotApi.js";
8
- import { useState as m } from "react";
9
- import { Activity as h, ArrowLeft as g, Building2 as _, CalendarClock as v, CreditCard as y, Paperclip as b, ShieldCheck as x, Tag as S } from "lucide-react";
10
- import { useParams as C } from "react-router-dom";
11
- import { jsx as w, jsxs as T } from "react/jsx-runtime";
12
- import { GlassCard as E } from "@burdenoff/fe-libs/ui";
7
+ import { useCancelRelationship as d, useCreateAsset as f, useCreateEntitlement as p, useFileDownloadUrl as m, usePlans as h, useProviders as g, useRelationship as _, useTransitionRelationship as v, useUpdateRelationship as y, useUploadFile as b } from "../../hooks/useSubscriberBotApi.js";
8
+ import { Modal as x } from "../../components/Modal.js";
9
+ import { useState as S } from "react";
10
+ import { Activity as C, ArrowLeft as w, Building2 as T, CalendarClock as E, CreditCard as D, Download as O, Paperclip as k, Pencil as A, Plus as j, ShieldCheck as M, Tag as N } from "lucide-react";
11
+ import { useParams as P } from "react-router-dom";
12
+ import { jsx as F, jsxs as I } from "react/jsx-runtime";
13
+ import { GlassCard as L } from "@burdenoff/fe-libs/ui";
13
14
  //#region src/subscriberbot/pages/relationships/RelationshipDetailPage.tsx
14
- var D = [
15
+ var R = "w-full rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]", z = "mb-1 block text-xs font-medium text-text-secondary", B = [
16
+ "MONTHLY",
17
+ "YEARLY",
18
+ "QUARTERLY",
19
+ "WEEKLY",
20
+ "DAILY",
21
+ "USAGE_BASED",
22
+ "LIFETIME",
23
+ "FREE"
24
+ ], V = [
25
+ "FEATURE_ACCESS",
26
+ "SEAT",
27
+ "USAGE_QUOTA",
28
+ "CONTENT",
29
+ "DISCOUNT",
30
+ "SUPPORT_TIER"
31
+ ], H = [
32
+ "RECEIPT",
33
+ "INVOICE",
34
+ "CONTRACT",
35
+ "LICENSE_KEY",
36
+ "CREDENTIAL",
37
+ "CERTIFICATE",
38
+ "WARRANTY",
39
+ "DOMAIN"
40
+ ], U = [
15
41
  {
16
42
  status: "ACTIVE",
17
43
  label: "Activate"
@@ -25,208 +51,720 @@ var D = [
25
51
  label: "Mark expired"
26
52
  }
27
53
  ];
28
- function O() {
29
- let { id: O } = C(), { navigateTo: k } = e(), { data: A, isLoading: j, isError: M, refetch: N } = f(O), P = p(), F = d(), [I, L] = m(null);
30
- if (j) return /* @__PURE__ */ w(t, {
54
+ function W(e) {
55
+ if (!e) return "";
56
+ let t = new Date(e);
57
+ return Number.isNaN(t.getTime()) ? "" : t.toISOString().slice(0, 10);
58
+ }
59
+ function G({ relationship: e, onClose: t }) {
60
+ let n = y(), r = g({ pagination: {
61
+ limit: 100,
62
+ offset: 0
63
+ } }), [i, a] = S(e.label), [o, s] = S(e.providerId ?? ""), [c, l] = S(e.planId ?? ""), [u, d] = S(String(e.amount ?? "")), [f, p] = S(e.currency), [m, _] = S(e.interval), [v, b] = S(W(e.renewsAt)), [C, w] = S(e.autoRenew), [T, E] = S(e.healthScore == null ? "" : String(e.healthScore)), [D, O] = S(e.notes ?? ""), [k, A] = S(null), j = h(o || void 0), M = (() => {
64
+ let t = r.data?.items ?? [];
65
+ return e.provider && !t.some((t) => t.id === e.provider?.id) ? [e.provider, ...t] : t;
66
+ })(), N = j.data ?? [];
67
+ return /* @__PURE__ */ F(x, {
68
+ title: "Edit relationship",
69
+ onClose: t,
70
+ maxWidthClassName: "max-w-2xl",
71
+ children: /* @__PURE__ */ I("form", {
72
+ onSubmit: (r) => {
73
+ if (r.preventDefault(), A(null), !i.trim()) {
74
+ A("A label is required.");
75
+ return;
76
+ }
77
+ let a = {
78
+ label: i.trim(),
79
+ interval: m,
80
+ autoRenew: C,
81
+ currency: f.trim() || "USD",
82
+ notes: D.trim(),
83
+ ...o ? { providerId: o } : {},
84
+ ...c ? { planId: c } : {},
85
+ ...u.trim() ? { amount: Number(u) } : {},
86
+ ...T.trim() ? { healthScore: Number(T) } : {},
87
+ ...v ? { renewsAt: new Date(v).toISOString() } : {}
88
+ };
89
+ n.mutate({
90
+ id: e.id,
91
+ input: a
92
+ }, {
93
+ onSuccess: () => t(),
94
+ onError: (e) => A(e instanceof Error ? e.message : "Could not update relationship.")
95
+ });
96
+ },
97
+ className: "space-y-4",
98
+ children: [
99
+ k && /* @__PURE__ */ F("div", {
100
+ className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
101
+ children: k
102
+ }),
103
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ I("label", {
104
+ htmlFor: "edit-label",
105
+ className: z,
106
+ children: ["Label ", /* @__PURE__ */ F("span", {
107
+ className: "text-status-error-text",
108
+ children: "*"
109
+ })]
110
+ }), /* @__PURE__ */ F("input", {
111
+ id: "edit-label",
112
+ type: "text",
113
+ value: i,
114
+ onChange: (e) => a(e.target.value),
115
+ className: R,
116
+ required: !0
117
+ })] }),
118
+ /* @__PURE__ */ I("div", {
119
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
120
+ children: [/* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
121
+ htmlFor: "edit-provider",
122
+ className: z,
123
+ children: "Provider"
124
+ }), /* @__PURE__ */ I("select", {
125
+ id: "edit-provider",
126
+ value: o,
127
+ onChange: (e) => {
128
+ s(e.target.value), l("");
129
+ },
130
+ className: R,
131
+ children: [/* @__PURE__ */ F("option", {
132
+ value: "",
133
+ children: "— None —"
134
+ }), M.map((e) => /* @__PURE__ */ F("option", {
135
+ value: e.id,
136
+ children: e.name
137
+ }, e.id))]
138
+ })] }), /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
139
+ htmlFor: "edit-plan",
140
+ className: z,
141
+ children: "Plan"
142
+ }), /* @__PURE__ */ I("select", {
143
+ id: "edit-plan",
144
+ value: c,
145
+ onChange: (e) => l(e.target.value),
146
+ className: R,
147
+ disabled: !o || N.length === 0,
148
+ children: [/* @__PURE__ */ F("option", {
149
+ value: "",
150
+ children: "— None —"
151
+ }), N.map((e) => /* @__PURE__ */ F("option", {
152
+ value: e.id,
153
+ children: e.name
154
+ }, e.id))]
155
+ })] })]
156
+ }),
157
+ /* @__PURE__ */ I("div", {
158
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
159
+ children: [
160
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
161
+ htmlFor: "edit-amount",
162
+ className: z,
163
+ children: "Amount"
164
+ }), /* @__PURE__ */ F("input", {
165
+ id: "edit-amount",
166
+ type: "number",
167
+ min: "0",
168
+ step: "0.01",
169
+ value: u,
170
+ onChange: (e) => d(e.target.value),
171
+ className: R
172
+ })] }),
173
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
174
+ htmlFor: "edit-currency",
175
+ className: z,
176
+ children: "Currency"
177
+ }), /* @__PURE__ */ F("input", {
178
+ id: "edit-currency",
179
+ type: "text",
180
+ value: f,
181
+ onChange: (e) => p(e.target.value.toUpperCase()),
182
+ maxLength: 3,
183
+ className: R
184
+ })] }),
185
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
186
+ htmlFor: "edit-interval",
187
+ className: z,
188
+ children: "Billing interval"
189
+ }), /* @__PURE__ */ F("select", {
190
+ id: "edit-interval",
191
+ value: m,
192
+ onChange: (e) => _(e.target.value),
193
+ className: R,
194
+ children: B.map((e) => /* @__PURE__ */ F("option", {
195
+ value: e,
196
+ children: e.replace(/_/g, " ")
197
+ }, e))
198
+ })] })
199
+ ]
200
+ }),
201
+ /* @__PURE__ */ I("div", {
202
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
203
+ children: [
204
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
205
+ htmlFor: "edit-renews",
206
+ className: z,
207
+ children: "Renews on"
208
+ }), /* @__PURE__ */ F("input", {
209
+ id: "edit-renews",
210
+ type: "date",
211
+ value: v,
212
+ onChange: (e) => b(e.target.value),
213
+ className: R
214
+ })] }),
215
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
216
+ htmlFor: "edit-health",
217
+ className: z,
218
+ children: "Health score (0–100)"
219
+ }), /* @__PURE__ */ F("input", {
220
+ id: "edit-health",
221
+ type: "number",
222
+ min: "0",
223
+ max: "100",
224
+ value: T,
225
+ onChange: (e) => E(e.target.value),
226
+ className: R
227
+ })] }),
228
+ /* @__PURE__ */ F("div", {
229
+ className: "flex items-end",
230
+ children: /* @__PURE__ */ I("label", {
231
+ className: "flex items-center gap-2 text-sm text-text-primary",
232
+ children: [/* @__PURE__ */ F("input", {
233
+ type: "checkbox",
234
+ checked: C,
235
+ onChange: (e) => w(e.target.checked),
236
+ className: "size-4 rounded border-border-subtle"
237
+ }), "Auto-renews"]
238
+ })
239
+ })
240
+ ]
241
+ }),
242
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
243
+ htmlFor: "edit-notes",
244
+ className: z,
245
+ children: "Notes"
246
+ }), /* @__PURE__ */ F("textarea", {
247
+ id: "edit-notes",
248
+ value: D,
249
+ onChange: (e) => O(e.target.value),
250
+ rows: 3,
251
+ className: R
252
+ })] }),
253
+ /* @__PURE__ */ I("div", {
254
+ className: "flex justify-end gap-3",
255
+ children: [/* @__PURE__ */ F("button", {
256
+ type: "button",
257
+ onClick: t,
258
+ className: "rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
259
+ children: "Cancel"
260
+ }), /* @__PURE__ */ F("button", {
261
+ type: "submit",
262
+ disabled: n.isPending,
263
+ className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50",
264
+ children: n.isPending ? "Saving…" : "Save changes"
265
+ })]
266
+ })
267
+ ]
268
+ })
269
+ });
270
+ }
271
+ function K({ relationshipId: e, onClose: t }) {
272
+ let n = p(), [r, i] = S(""), [a, o] = S("FEATURE_ACCESS"), [s, c] = S(""), [l, u] = S(""), [d, f] = S(""), [m, h] = S(null);
273
+ return /* @__PURE__ */ F(x, {
274
+ title: "Add entitlement",
275
+ onClose: t,
276
+ children: /* @__PURE__ */ I("form", {
277
+ onSubmit: (i) => {
278
+ if (i.preventDefault(), h(null), !r.trim()) {
279
+ h("An entitlement name is required.");
280
+ return;
281
+ }
282
+ n.mutate({
283
+ relationshipId: e,
284
+ name: r.trim(),
285
+ type: a,
286
+ ...s.trim() ? { quota: Number(s) } : {},
287
+ ...l.trim() ? { unit: l.trim() } : {},
288
+ ...d.trim() ? { description: d.trim() } : {}
289
+ }, {
290
+ onSuccess: () => t(),
291
+ onError: (e) => h(e instanceof Error ? e.message : "Could not add entitlement.")
292
+ });
293
+ },
294
+ className: "space-y-4",
295
+ children: [
296
+ m && /* @__PURE__ */ F("div", {
297
+ className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
298
+ children: m
299
+ }),
300
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ I("label", {
301
+ htmlFor: "ent-name",
302
+ className: z,
303
+ children: ["Name ", /* @__PURE__ */ F("span", {
304
+ className: "text-status-error-text",
305
+ children: "*"
306
+ })]
307
+ }), /* @__PURE__ */ F("input", {
308
+ id: "ent-name",
309
+ type: "text",
310
+ value: r,
311
+ onChange: (e) => i(e.target.value),
312
+ placeholder: "e.g. Seats, API calls, Priority support",
313
+ className: R,
314
+ required: !0
315
+ })] }),
316
+ /* @__PURE__ */ I("div", {
317
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
318
+ children: [
319
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
320
+ htmlFor: "ent-type",
321
+ className: z,
322
+ children: "Type"
323
+ }), /* @__PURE__ */ F("select", {
324
+ id: "ent-type",
325
+ value: a,
326
+ onChange: (e) => o(e.target.value),
327
+ className: R,
328
+ children: V.map((e) => /* @__PURE__ */ F("option", {
329
+ value: e,
330
+ children: e.replace(/_/g, " ")
331
+ }, e))
332
+ })] }),
333
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
334
+ htmlFor: "ent-quota",
335
+ className: z,
336
+ children: "Quota"
337
+ }), /* @__PURE__ */ F("input", {
338
+ id: "ent-quota",
339
+ type: "number",
340
+ min: "0",
341
+ value: s,
342
+ onChange: (e) => c(e.target.value),
343
+ placeholder: "e.g. 5",
344
+ className: R
345
+ })] }),
346
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
347
+ htmlFor: "ent-unit",
348
+ className: z,
349
+ children: "Unit"
350
+ }), /* @__PURE__ */ F("input", {
351
+ id: "ent-unit",
352
+ type: "text",
353
+ value: l,
354
+ onChange: (e) => u(e.target.value),
355
+ placeholder: "e.g. seats, GB",
356
+ className: R
357
+ })] })
358
+ ]
359
+ }),
360
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
361
+ htmlFor: "ent-desc",
362
+ className: z,
363
+ children: "Description"
364
+ }), /* @__PURE__ */ F("textarea", {
365
+ id: "ent-desc",
366
+ value: d,
367
+ onChange: (e) => f(e.target.value),
368
+ rows: 2,
369
+ className: R
370
+ })] }),
371
+ /* @__PURE__ */ I("div", {
372
+ className: "flex justify-end gap-3",
373
+ children: [/* @__PURE__ */ F("button", {
374
+ type: "button",
375
+ onClick: t,
376
+ className: "rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
377
+ children: "Cancel"
378
+ }), /* @__PURE__ */ F("button", {
379
+ type: "submit",
380
+ disabled: n.isPending,
381
+ className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50",
382
+ children: n.isPending ? "Adding…" : "Add entitlement"
383
+ })]
384
+ })
385
+ ]
386
+ })
387
+ });
388
+ }
389
+ function q({ relationshipId: e, onClose: t }) {
390
+ let n = f(), { uploadFile: r, progress: i, isUploading: a } = b(), [o, s] = S(""), [c, l] = S("RECEIPT"), [u, d] = S(null), [p, m] = S(""), [h, g] = S(null), _ = a || n.isPending;
391
+ return /* @__PURE__ */ F(x, {
392
+ title: "Attach asset",
393
+ onClose: t,
394
+ children: /* @__PURE__ */ I("form", {
395
+ onSubmit: async (i) => {
396
+ if (i.preventDefault(), g(null), !u) {
397
+ g("Choose a file to attach.");
398
+ return;
399
+ }
400
+ try {
401
+ let { fileId: i, fileName: a } = await r(u);
402
+ await n.mutateAsync({
403
+ relationshipId: e,
404
+ name: o.trim() || a,
405
+ type: c,
406
+ fileId: i,
407
+ ...p ? { expiresAt: new Date(p).toISOString() } : {}
408
+ }), t();
409
+ } catch (e) {
410
+ g(e instanceof Error ? e.message : "Could not attach the asset.");
411
+ }
412
+ },
413
+ className: "space-y-4",
414
+ children: [
415
+ h && /* @__PURE__ */ F("div", {
416
+ className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
417
+ children: h
418
+ }),
419
+ /* @__PURE__ */ I("div", { children: [
420
+ /* @__PURE__ */ I("label", {
421
+ htmlFor: "asset-file",
422
+ className: z,
423
+ children: ["File ", /* @__PURE__ */ F("span", {
424
+ className: "text-status-error-text",
425
+ children: "*"
426
+ })]
427
+ }),
428
+ /* @__PURE__ */ F("input", {
429
+ id: "asset-file",
430
+ type: "file",
431
+ onChange: (e) => {
432
+ let t = e.target.files?.[0] ?? null;
433
+ d(t), t && !o.trim() && s(t.name);
434
+ },
435
+ className: "w-full text-sm text-text-secondary file:mr-3 file:rounded-lg file:border file:border-border-subtle file:bg-bg-surface file:px-3 file:py-1.5 file:text-sm file:font-medium file:text-text-primary hover:file:bg-bg-sunken"
436
+ }),
437
+ /* @__PURE__ */ F("p", {
438
+ className: "mt-1 text-xs text-text-secondary",
439
+ children: "Stored securely in files — only a reference is kept here."
440
+ })
441
+ ] }),
442
+ /* @__PURE__ */ I("div", {
443
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
444
+ children: [/* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
445
+ htmlFor: "asset-name",
446
+ className: z,
447
+ children: "Name"
448
+ }), /* @__PURE__ */ F("input", {
449
+ id: "asset-name",
450
+ type: "text",
451
+ value: o,
452
+ onChange: (e) => s(e.target.value),
453
+ placeholder: "Defaults to the file name",
454
+ className: R
455
+ })] }), /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
456
+ htmlFor: "asset-type",
457
+ className: z,
458
+ children: "Type"
459
+ }), /* @__PURE__ */ F("select", {
460
+ id: "asset-type",
461
+ value: c,
462
+ onChange: (e) => l(e.target.value),
463
+ className: R,
464
+ children: H.map((e) => /* @__PURE__ */ F("option", {
465
+ value: e,
466
+ children: e.replace(/_/g, " ")
467
+ }, e))
468
+ })] })]
469
+ }),
470
+ /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("label", {
471
+ htmlFor: "asset-expires",
472
+ className: z,
473
+ children: "Expires on"
474
+ }), /* @__PURE__ */ F("input", {
475
+ id: "asset-expires",
476
+ type: "date",
477
+ value: p,
478
+ onChange: (e) => m(e.target.value),
479
+ className: R
480
+ })] }),
481
+ a && /* @__PURE__ */ I("p", {
482
+ className: "text-xs text-text-secondary",
483
+ children: [
484
+ "Uploading… ",
485
+ i,
486
+ "%"
487
+ ]
488
+ }),
489
+ /* @__PURE__ */ I("div", {
490
+ className: "flex justify-end gap-3",
491
+ children: [/* @__PURE__ */ F("button", {
492
+ type: "button",
493
+ onClick: t,
494
+ className: "rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
495
+ children: "Cancel"
496
+ }), /* @__PURE__ */ F("button", {
497
+ type: "submit",
498
+ disabled: _,
499
+ className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90 disabled:opacity-50",
500
+ children: _ ? "Attaching…" : "Attach asset"
501
+ })]
502
+ })
503
+ ]
504
+ })
505
+ });
506
+ }
507
+ function J({ asset: e }) {
508
+ let t = m(), [n, a] = S(!1);
509
+ return /* @__PURE__ */ I("div", {
510
+ className: "flex items-center justify-between gap-3 p-3",
511
+ children: [/* @__PURE__ */ I("div", {
512
+ className: "flex min-w-0 items-center gap-2",
513
+ children: [/* @__PURE__ */ F(k, { className: "h-4 w-4 shrink-0 text-text-secondary" }), /* @__PURE__ */ I("div", {
514
+ className: "min-w-0",
515
+ children: [/* @__PURE__ */ F("p", {
516
+ className: "truncate text-sm font-medium text-text-primary",
517
+ children: e.name
518
+ }), /* @__PURE__ */ F("p", {
519
+ className: "text-xs text-text-secondary",
520
+ children: i(e.type)
521
+ })]
522
+ })]
523
+ }), /* @__PURE__ */ I("div", {
524
+ className: "flex shrink-0 items-center gap-3",
525
+ children: [e.expiresAt && /* @__PURE__ */ I("span", {
526
+ className: "text-xs text-text-secondary",
527
+ children: ["Expires ", r(e.expiresAt)]
528
+ }), e.file?.id && /* @__PURE__ */ I("button", {
529
+ type: "button",
530
+ onClick: async () => {
531
+ if (e.file?.id) {
532
+ a(!0);
533
+ try {
534
+ let n = await t(e.file.id);
535
+ window.open(n, "_blank", "noopener,noreferrer");
536
+ } catch {} finally {
537
+ a(!1);
538
+ }
539
+ }
540
+ },
541
+ disabled: n,
542
+ className: "inline-flex items-center gap-1 rounded-lg border border-border-subtle px-2.5 py-1 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50",
543
+ children: [
544
+ /* @__PURE__ */ F(O, { className: "h-3.5 w-3.5" }),
545
+ " ",
546
+ n ? "Opening…" : "Download"
547
+ ]
548
+ })]
549
+ })]
550
+ });
551
+ }
552
+ function Y() {
553
+ let { id: f } = P(), { navigateTo: p } = e(), { data: m, isLoading: h, isError: g, refetch: y } = _(f), b = v(), x = d(), [O, k] = S(null), [R, z] = S(!1), [B, V] = S(!1), [H, W] = S(!1);
554
+ if (h) return /* @__PURE__ */ F(t, {
31
555
  title: "Relationship",
32
- children: /* @__PURE__ */ w(l, { label: "Loading relationship…" })
556
+ children: /* @__PURE__ */ F(l, { label: "Loading relationship…" })
33
557
  });
34
- if (M) return /* @__PURE__ */ w(t, {
558
+ if (g) return /* @__PURE__ */ F(t, {
35
559
  title: "Relationship",
36
- children: /* @__PURE__ */ w(c, {
560
+ children: /* @__PURE__ */ F(c, {
37
561
  message: "Could not load this relationship.",
38
- onRetry: () => void N()
562
+ onRetry: () => void y()
39
563
  })
40
564
  });
41
- if (!A) return /* @__PURE__ */ w(t, {
565
+ if (!m) return /* @__PURE__ */ F(t, {
42
566
  title: "Relationship",
43
- children: /* @__PURE__ */ w(s, {
567
+ children: /* @__PURE__ */ F(s, {
44
568
  illustration: "empty-data",
45
569
  title: "Relationship not found",
46
570
  description: "It may have been removed, or you may not have access to it.",
47
- action: /* @__PURE__ */ w("button", {
571
+ action: /* @__PURE__ */ F("button", {
48
572
  type: "button",
49
- onClick: () => k("/relationships"),
573
+ onClick: () => p("/relationships"),
50
574
  className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
51
575
  children: "Back to relationships"
52
576
  })
53
577
  })
54
578
  });
55
- let R = A, z = P.isPending || F.isPending, B = (e) => {
56
- L(null), P.mutate({
57
- id: R.id,
579
+ let Y = m, X = b.isPending || x.isPending, Z = (e) => {
580
+ k(null), b.mutate({
581
+ id: Y.id,
58
582
  status: e
59
- }, { onError: (e) => L(e instanceof Error ? e.message : "Transition failed") });
583
+ }, { onError: (e) => k(e instanceof Error ? e.message : "Transition failed") });
60
584
  };
61
- return /* @__PURE__ */ T(t, {
62
- title: R.label,
63
- description: R.provider?.name ?? i(R.kind),
64
- actions: /* @__PURE__ */ T("button", {
65
- type: "button",
66
- onClick: () => k("/relationships"),
67
- className: "inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
68
- children: [/* @__PURE__ */ w(g, { className: "h-4 w-4" }), " Back"]
585
+ return /* @__PURE__ */ I(t, {
586
+ title: Y.label,
587
+ description: Y.provider?.name ?? i(Y.kind),
588
+ actions: /* @__PURE__ */ I("div", {
589
+ className: "flex items-center gap-2",
590
+ children: [/* @__PURE__ */ I("button", {
591
+ type: "button",
592
+ onClick: () => z(!0),
593
+ className: "inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
594
+ children: [/* @__PURE__ */ F(A, { className: "h-4 w-4" }), " Edit"]
595
+ }), /* @__PURE__ */ I("button", {
596
+ type: "button",
597
+ onClick: () => p("/relationships"),
598
+ className: "inline-flex items-center gap-2 rounded-lg border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
599
+ children: [/* @__PURE__ */ F(w, { className: "h-4 w-4" }), " Back"]
600
+ })]
69
601
  }),
70
602
  children: [
71
- /* @__PURE__ */ T("div", {
603
+ /* @__PURE__ */ I("div", {
72
604
  className: "flex flex-wrap items-center gap-3",
73
605
  children: [
74
- /* @__PURE__ */ w(o, { status: R.status }),
75
- /* @__PURE__ */ w("span", {
606
+ /* @__PURE__ */ F(o, { status: Y.status }),
607
+ /* @__PURE__ */ F("span", {
76
608
  className: "text-sm text-text-secondary",
77
- children: i(R.kind)
609
+ children: i(Y.kind)
78
610
  }),
79
- /* @__PURE__ */ w("span", {
611
+ /* @__PURE__ */ F("span", {
80
612
  className: "text-sm text-text-secondary",
81
613
  children: "·"
82
614
  }),
83
- /* @__PURE__ */ T("span", {
615
+ /* @__PURE__ */ I("span", {
84
616
  className: "text-sm font-semibold text-text-primary",
85
- children: [n(R.amount, R.currency), /* @__PURE__ */ w("span", {
617
+ children: [n(Y.amount, Y.currency), /* @__PURE__ */ F("span", {
86
618
  className: "text-xs font-normal text-text-secondary",
87
- children: a(R.interval)
619
+ children: a(Y.interval)
88
620
  })]
89
621
  }),
90
- R.autoRenew && /* @__PURE__ */ w("span", {
622
+ Y.autoRenew && /* @__PURE__ */ F("span", {
91
623
  className: "text-xs text-text-secondary",
92
624
  children: "Auto-renews"
93
625
  })
94
626
  ]
95
627
  }),
96
- I && /* @__PURE__ */ w("div", {
628
+ O && /* @__PURE__ */ F("div", {
97
629
  className: "mt-4 rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
98
- children: I
630
+ children: O
99
631
  }),
100
- /* @__PURE__ */ T("div", {
632
+ /* @__PURE__ */ I("div", {
101
633
  className: "mt-5 flex flex-wrap gap-2",
102
- children: [D.filter((e) => e.status !== R.status).map((e) => /* @__PURE__ */ w("button", {
634
+ children: [U.filter((e) => e.status !== Y.status).map((e) => /* @__PURE__ */ F("button", {
103
635
  type: "button",
104
- disabled: z,
105
- onClick: () => B(e.status),
636
+ disabled: X,
637
+ onClick: () => Z(e.status),
106
638
  className: "rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50",
107
639
  children: e.label
108
- }, e.status)), R.status !== "CANCELLED" && /* @__PURE__ */ w("button", {
640
+ }, e.status)), Y.status !== "CANCELLED" && /* @__PURE__ */ F("button", {
109
641
  type: "button",
110
- disabled: z,
642
+ disabled: X,
111
643
  onClick: () => {
112
- L(null), F.mutate(R.id, { onError: (e) => L(e instanceof Error ? e.message : "Cancel failed") });
644
+ k(null), x.mutate(Y.id, { onError: (e) => k(e instanceof Error ? e.message : "Cancel failed") });
113
645
  },
114
646
  className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-3 py-1.5 text-xs font-medium text-status-error-text hover:opacity-90 disabled:opacity-50",
115
647
  children: "Cancel relationship"
116
648
  })]
117
649
  }),
118
- /* @__PURE__ */ T("div", {
650
+ /* @__PURE__ */ I("div", {
119
651
  className: "mt-6 grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
120
652
  children: [
121
- /* @__PURE__ */ T(E, {
653
+ /* @__PURE__ */ I(L, {
122
654
  treatment: "metric",
123
655
  className: "p-4",
124
- children: [/* @__PURE__ */ T("div", {
656
+ children: [/* @__PURE__ */ I("div", {
125
657
  className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
126
- children: [/* @__PURE__ */ w(_, { className: "h-3.5 w-3.5" }), " Provider"]
127
- }), /* @__PURE__ */ w("p", {
658
+ children: [/* @__PURE__ */ F(T, { className: "h-3.5 w-3.5" }), " Provider"]
659
+ }), /* @__PURE__ */ F("p", {
128
660
  className: "mt-1.5 text-sm text-text-primary",
129
- children: R.provider?.name ?? "—"
661
+ children: Y.provider?.name ?? "—"
130
662
  })]
131
663
  }),
132
- /* @__PURE__ */ T(E, {
664
+ /* @__PURE__ */ I(L, {
133
665
  treatment: "metric",
134
666
  className: "p-4",
135
- children: [/* @__PURE__ */ T("div", {
667
+ children: [/* @__PURE__ */ I("div", {
136
668
  className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
137
- children: [/* @__PURE__ */ w(y, { className: "h-3.5 w-3.5" }), " Plan"]
138
- }), /* @__PURE__ */ w("p", {
669
+ children: [/* @__PURE__ */ F(D, { className: "h-3.5 w-3.5" }), " Plan"]
670
+ }), /* @__PURE__ */ F("p", {
139
671
  className: "mt-1.5 text-sm text-text-primary",
140
- children: R.plan?.name ?? "—"
672
+ children: Y.plan?.name ?? "—"
141
673
  })]
142
674
  }),
143
- /* @__PURE__ */ T(E, {
675
+ /* @__PURE__ */ I(L, {
144
676
  treatment: "metric",
145
677
  className: "p-4",
146
- children: [/* @__PURE__ */ T("div", {
678
+ children: [/* @__PURE__ */ I("div", {
147
679
  className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
148
- children: [/* @__PURE__ */ w(v, { className: "h-3.5 w-3.5" }), " Next renewal"]
149
- }), /* @__PURE__ */ w("p", {
680
+ children: [/* @__PURE__ */ F(E, { className: "h-3.5 w-3.5" }), " Next renewal"]
681
+ }), /* @__PURE__ */ F("p", {
150
682
  className: "mt-1.5 text-sm text-text-primary",
151
- children: R.renewsAt ? r(R.renewsAt) : "—"
683
+ children: Y.renewsAt ? r(Y.renewsAt) : "—"
152
684
  })]
153
685
  }),
154
- /* @__PURE__ */ T(E, {
686
+ /* @__PURE__ */ I(L, {
155
687
  treatment: "metric",
156
688
  className: "p-4",
157
- children: [/* @__PURE__ */ T("div", {
689
+ children: [/* @__PURE__ */ I("div", {
158
690
  className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
159
- children: [/* @__PURE__ */ w(h, { className: "h-3.5 w-3.5" }), " Health score"]
160
- }), /* @__PURE__ */ w("p", {
691
+ children: [/* @__PURE__ */ F(C, { className: "h-3.5 w-3.5" }), " Health score"]
692
+ }), /* @__PURE__ */ F("p", {
161
693
  className: "mt-1.5 text-sm text-text-primary",
162
- children: R.healthScore == null ? "—" : `${R.healthScore}/100`
694
+ children: Y.healthScore == null ? "—" : `${Y.healthScore}/100`
163
695
  })]
164
696
  }),
165
- /* @__PURE__ */ T(E, {
697
+ /* @__PURE__ */ I(L, {
166
698
  treatment: "metric",
167
699
  className: "p-4",
168
- children: [/* @__PURE__ */ T("div", {
700
+ children: [/* @__PURE__ */ I("div", {
169
701
  className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
170
- children: [/* @__PURE__ */ w(x, { className: "h-3.5 w-3.5" }), " Discovery"]
171
- }), /* @__PURE__ */ w("p", {
702
+ children: [/* @__PURE__ */ F(M, { className: "h-3.5 w-3.5" }), " Discovery"]
703
+ }), /* @__PURE__ */ F("p", {
172
704
  className: "mt-1.5 text-sm text-text-primary",
173
- children: i(R.discoverySource)
705
+ children: i(Y.discoverySource)
174
706
  })]
175
707
  }),
176
- /* @__PURE__ */ T(E, {
708
+ /* @__PURE__ */ I(L, {
177
709
  treatment: "metric",
178
710
  className: "p-4",
179
- children: [/* @__PURE__ */ T("div", {
711
+ children: [/* @__PURE__ */ I("div", {
180
712
  className: "flex items-center gap-2 text-xs font-medium text-text-secondary",
181
- children: [/* @__PURE__ */ w(v, { className: "h-3.5 w-3.5" }), " Started"]
182
- }), /* @__PURE__ */ w("p", {
713
+ children: [/* @__PURE__ */ F(E, { className: "h-3.5 w-3.5" }), " Started"]
714
+ }), /* @__PURE__ */ F("p", {
183
715
  className: "mt-1.5 text-sm text-text-primary",
184
- children: R.startedAt ? r(R.startedAt) : "—"
716
+ children: Y.startedAt ? r(Y.startedAt) : "—"
185
717
  })]
186
718
  })
187
719
  ]
188
720
  }),
189
- R.tags.length > 0 && /* @__PURE__ */ T("div", {
721
+ Y.tags.length > 0 && /* @__PURE__ */ I("div", {
190
722
  className: "mt-5 flex flex-wrap items-center gap-2",
191
- children: [/* @__PURE__ */ w(S, { className: "h-3.5 w-3.5 text-text-secondary" }), R.tags.map((e) => /* @__PURE__ */ w("span", {
723
+ children: [/* @__PURE__ */ F(N, { className: "h-3.5 w-3.5 text-text-secondary" }), Y.tags.map((e) => /* @__PURE__ */ F("span", {
192
724
  className: "rounded-full bg-bg-sunken px-2.5 py-0.5 text-xs text-text-secondary",
193
725
  children: e
194
726
  }, e))]
195
727
  }),
196
- R.notes && /* @__PURE__ */ T("div", {
728
+ Y.notes && /* @__PURE__ */ I("div", {
197
729
  className: "mt-5 rounded-lg border border-border-subtle bg-bg-surface p-4",
198
- children: [/* @__PURE__ */ w("p", {
730
+ children: [/* @__PURE__ */ F("p", {
199
731
  className: "text-xs font-medium text-text-secondary",
200
732
  children: "Notes"
201
- }), /* @__PURE__ */ w("p", {
733
+ }), /* @__PURE__ */ F("p", {
202
734
  className: "mt-1 whitespace-pre-wrap text-sm text-text-primary",
203
- children: R.notes
735
+ children: Y.notes
204
736
  })]
205
737
  }),
206
- /* @__PURE__ */ w(u, {
738
+ /* @__PURE__ */ F(u, {
207
739
  title: "Entitlements",
208
740
  description: "What this relationship grants you",
209
- children: !R.entitlements || R.entitlements.length === 0 ? /* @__PURE__ */ w(s, {
741
+ action: /* @__PURE__ */ I("button", {
742
+ type: "button",
743
+ onClick: () => V(!0),
744
+ className: "inline-flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken",
745
+ children: [/* @__PURE__ */ F(j, { className: "h-3.5 w-3.5" }), " Add entitlement"]
746
+ }),
747
+ children: !Y.entitlements || Y.entitlements.length === 0 ? /* @__PURE__ */ F(s, {
210
748
  illustration: "empty-data",
211
749
  title: "No entitlements",
212
750
  description: "Entitlements (seats, quotas, feature access) will appear here."
213
- }) : /* @__PURE__ */ w("div", {
751
+ }) : /* @__PURE__ */ F("div", {
214
752
  className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
215
- children: R.entitlements.map((e) => /* @__PURE__ */ T("div", {
753
+ children: Y.entitlements.map((e) => /* @__PURE__ */ I("div", {
216
754
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
217
755
  children: [
218
- /* @__PURE__ */ T("div", {
756
+ /* @__PURE__ */ I("div", {
219
757
  className: "flex items-start justify-between gap-2",
220
- children: [/* @__PURE__ */ w("p", {
758
+ children: [/* @__PURE__ */ F("p", {
221
759
  className: "text-sm font-medium text-text-primary",
222
760
  children: e.name
223
- }), /* @__PURE__ */ w(o, { status: e.isActive ? "ACTIVE" : "DISABLED" })]
761
+ }), /* @__PURE__ */ F(o, { status: e.isActive ? "ACTIVE" : "DISABLED" })]
224
762
  }),
225
- /* @__PURE__ */ w("p", {
763
+ /* @__PURE__ */ F("p", {
226
764
  className: "mt-1 text-xs text-text-secondary",
227
765
  children: i(e.type)
228
766
  }),
229
- e.quota != null && /* @__PURE__ */ T("p", {
767
+ e.quota != null && /* @__PURE__ */ I("p", {
230
768
  className: "mt-2 text-xs text-text-secondary",
231
769
  children: [
232
770
  "Used ",
@@ -240,67 +778,67 @@ function O() {
240
778
  }, e.id))
241
779
  })
242
780
  }),
243
- /* @__PURE__ */ w(u, {
781
+ /* @__PURE__ */ F(u, {
244
782
  title: "Assets",
245
783
  description: "Invoices, contracts, licenses and credentials",
246
- children: !R.assets || R.assets.length === 0 ? /* @__PURE__ */ w(s, {
784
+ action: /* @__PURE__ */ I("button", {
785
+ type: "button",
786
+ onClick: () => W(!0),
787
+ className: "inline-flex items-center gap-1.5 rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-primary hover:bg-bg-sunken",
788
+ children: [/* @__PURE__ */ F(j, { className: "h-3.5 w-3.5" }), " Attach asset"]
789
+ }),
790
+ children: !Y.assets || Y.assets.length === 0 ? /* @__PURE__ */ F(s, {
247
791
  illustration: "empty-data",
248
792
  title: "No assets attached",
249
793
  description: "Attach invoices, contracts, licenses or receipts to this relationship."
250
- }) : /* @__PURE__ */ w("div", {
794
+ }) : /* @__PURE__ */ F("div", {
251
795
  className: "divide-y divide-border-subtle rounded-lg border border-border-subtle bg-bg-surface",
252
- children: R.assets.map((e) => /* @__PURE__ */ T("div", {
253
- className: "flex items-center justify-between gap-3 p-3",
254
- children: [/* @__PURE__ */ T("div", {
255
- className: "flex min-w-0 items-center gap-2",
256
- children: [/* @__PURE__ */ w(b, { className: "h-4 w-4 shrink-0 text-text-secondary" }), /* @__PURE__ */ T("div", {
257
- className: "min-w-0",
258
- children: [/* @__PURE__ */ w("p", {
259
- className: "truncate text-sm font-medium text-text-primary",
260
- children: e.name
261
- }), /* @__PURE__ */ w("p", {
262
- className: "text-xs text-text-secondary",
263
- children: i(e.type)
264
- })]
265
- })]
266
- }), e.expiresAt && /* @__PURE__ */ T("span", {
267
- className: "shrink-0 text-xs text-text-secondary",
268
- children: ["Expires ", r(e.expiresAt)]
269
- })]
270
- }, e.id))
796
+ children: Y.assets.map((e) => /* @__PURE__ */ F(J, { asset: e }, e.id))
271
797
  })
272
798
  }),
273
- /* @__PURE__ */ w(u, {
799
+ /* @__PURE__ */ F(u, {
274
800
  title: "Renewal timeline",
275
801
  description: "Detected renewals and price changes",
276
- children: !R.renewalEvents || R.renewalEvents.length === 0 ? /* @__PURE__ */ w(s, {
802
+ children: !Y.renewalEvents || Y.renewalEvents.length === 0 ? /* @__PURE__ */ F(s, {
277
803
  illustration: "empty-calendar",
278
804
  title: "No renewal events",
279
805
  description: "Renewals and price changes detected for this relationship will appear here."
280
- }) : /* @__PURE__ */ w("div", {
806
+ }) : /* @__PURE__ */ F("div", {
281
807
  className: "divide-y divide-border-subtle rounded-lg border border-border-subtle bg-bg-surface",
282
- children: R.renewalEvents.map((e) => /* @__PURE__ */ T("div", {
808
+ children: Y.renewalEvents.map((e) => /* @__PURE__ */ I("div", {
283
809
  className: "flex items-center justify-between gap-3 p-3",
284
- children: [/* @__PURE__ */ T("div", {
810
+ children: [/* @__PURE__ */ I("div", {
285
811
  className: "min-w-0",
286
- children: [/* @__PURE__ */ w("p", {
812
+ children: [/* @__PURE__ */ F("p", {
287
813
  className: "truncate text-sm font-medium text-text-primary",
288
814
  children: i(e.eventType)
289
- }), /* @__PURE__ */ T("p", {
815
+ }), /* @__PURE__ */ I("p", {
290
816
  className: "text-xs text-text-secondary",
291
817
  children: [r(e.occursAt), e.detail ? ` · ${e.detail}` : ""]
292
818
  })]
293
- }), e.amount != null && /* @__PURE__ */ w("span", {
819
+ }), e.amount != null && /* @__PURE__ */ F("span", {
294
820
  className: "shrink-0 text-sm font-semibold tabular-nums text-text-primary",
295
- children: n(e.amount, e.currency ?? R.currency)
821
+ children: n(e.amount, e.currency ?? Y.currency)
296
822
  })]
297
823
  }, e.id))
298
824
  })
825
+ }),
826
+ R && /* @__PURE__ */ F(G, {
827
+ relationship: Y,
828
+ onClose: () => z(!1)
829
+ }),
830
+ B && /* @__PURE__ */ F(K, {
831
+ relationshipId: Y.id,
832
+ onClose: () => V(!1)
833
+ }),
834
+ H && /* @__PURE__ */ F(q, {
835
+ relationshipId: Y.id,
836
+ onClose: () => W(!1)
299
837
  })
300
838
  ]
301
839
  });
302
840
  }
303
841
  //#endregion
304
- export { O as RelationshipDetailPage };
842
+ export { Y as RelationshipDetailPage };
305
843
 
306
844
  //# sourceMappingURL=RelationshipDetailPage.js.map