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