@burdenoff/microfe-subscriberbot 2026.629.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 +355 -159
  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
@@ -5,14 +5,15 @@ import { MetricsCard as r } from "../components/MetricsCard.js";
5
5
  import { formatCurrency as i, formatDate as a } from "../utils/formatters.js";
6
6
  import { StatusBadge as o } from "../components/StatusBadge.js";
7
7
  import { EmptyState as s } from "../components/EmptyState.js";
8
- import { ErrorView as c, LoadingView as l } from "../components/StateViews.js";
9
- import { useInvoices as u, useMarkInvoicePaid as d } from "../hooks/useSubscriberBotApi.js";
10
- import { useMemo as f, useState as p } from "react";
11
- import { FileText as m, Receipt as h } from "lucide-react";
12
- import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
13
- import { PagePurpose as y } from "@burdenoff/fe-libs/ui";
8
+ import { ErrorView as c, LoadingView as l, Section as u } from "../components/StateViews.js";
9
+ import { useCreateInvoice as d, useCreatePaymentInstrument as f, useInvoices as p, useMarkInvoicePaid as m, usePaymentInstruments as h, useRelationships as g, useRemovePaymentInstrument as _ } from "../hooks/useSubscriberBotApi.js";
10
+ import { Modal as v } from "../components/Modal.js";
11
+ import { useMemo as y, useState as b } from "react";
12
+ import { CreditCard as x, FileText as S, Plus as C, Receipt as w, Star as T, Trash2 as E } from "lucide-react";
13
+ import { Fragment as D, jsx as O, jsxs as k } from "react/jsx-runtime";
14
+ import { PagePurpose as A } from "@burdenoff/fe-libs/ui";
14
15
  //#region src/subscriberbot/pages/InvoicesPage.tsx
15
- var b = 25, x = [
16
+ var j = 25, M = "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)]", N = "mb-1 block text-xs font-medium text-text-secondary", P = [
16
17
  {
17
18
  value: "",
18
19
  label: "All statuses"
@@ -45,130 +46,550 @@ var b = 25, x = [
45
46
  value: "REFUNDED",
46
47
  label: "Refunded"
47
48
  }
48
- ], S = new Set([
49
+ ], F = [
50
+ "ISSUED",
51
+ "DRAFT",
52
+ "OVERDUE",
53
+ "PAID",
54
+ "FAILED",
55
+ "CANCELLED",
56
+ "REFUNDED"
57
+ ], I = [
58
+ "CARD",
59
+ "BANK_ACCOUNT",
60
+ "PAYPAL",
61
+ "UPI",
62
+ "WALLET",
63
+ "OTHER"
64
+ ], L = new Set([
49
65
  "ISSUED",
50
66
  "OVERDUE",
51
67
  "FAILED"
52
68
  ]);
53
- function C() {
54
- let { navigateTo: C } = e(), [w, T] = p(0), [E, D] = p(""), { data: O, isLoading: k, isError: A, refetch: j, isFetching: M } = u({
55
- status: E || void 0,
69
+ function R({ onClose: e }) {
70
+ let t = d(), n = g({ pagination: {
71
+ limit: 100,
72
+ offset: 0
73
+ } }).data?.items ?? [], [r, i] = b(""), [a, o] = b(""), [s, c] = b("ISSUED"), [l, u] = b("USD"), [f, p] = b(""), [m, h] = b(""), [_, y] = b(""), [x, S] = b(""), [C, w] = b(""), [T, E] = b(null);
74
+ return /* @__PURE__ */ O(v, {
75
+ title: "Create invoice",
76
+ onClose: e,
77
+ maxWidthClassName: "max-w-xl",
78
+ children: /* @__PURE__ */ k("form", {
79
+ onSubmit: (n) => {
80
+ if (n.preventDefault(), E(null), !r) {
81
+ E("Select the relationship this invoice belongs to.");
82
+ return;
83
+ }
84
+ t.mutate({
85
+ relationshipId: r,
86
+ status: s,
87
+ currency: l.trim() || "USD",
88
+ ...a.trim() ? { number: a.trim() } : {},
89
+ ...f.trim() ? { subtotal: Number(f) } : {},
90
+ ...m.trim() ? { taxAmount: Number(m) } : {},
91
+ ..._.trim() ? { total: Number(_) } : {},
92
+ ...x ? { issueDate: new Date(x).toISOString() } : {},
93
+ ...C ? { dueDate: new Date(C).toISOString() } : {}
94
+ }, {
95
+ onSuccess: () => e(),
96
+ onError: (e) => E(e instanceof Error ? e.message : "Could not create invoice.")
97
+ });
98
+ },
99
+ className: "space-y-4",
100
+ children: [
101
+ T && /* @__PURE__ */ O("div", {
102
+ className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
103
+ children: T
104
+ }),
105
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ k("label", {
106
+ htmlFor: "inv-relationship",
107
+ className: N,
108
+ children: ["Relationship ", /* @__PURE__ */ O("span", {
109
+ className: "text-status-error-text",
110
+ children: "*"
111
+ })]
112
+ }), /* @__PURE__ */ k("select", {
113
+ id: "inv-relationship",
114
+ value: r,
115
+ onChange: (e) => i(e.target.value),
116
+ className: M,
117
+ required: !0,
118
+ children: [/* @__PURE__ */ O("option", {
119
+ value: "",
120
+ children: "— Select a relationship —"
121
+ }), n.map((e) => /* @__PURE__ */ O("option", {
122
+ value: e.id,
123
+ children: e.label
124
+ }, e.id))]
125
+ })] }),
126
+ /* @__PURE__ */ k("div", {
127
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
128
+ children: [
129
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
130
+ htmlFor: "inv-number",
131
+ className: N,
132
+ children: "Number"
133
+ }), /* @__PURE__ */ O("input", {
134
+ id: "inv-number",
135
+ type: "text",
136
+ value: a,
137
+ onChange: (e) => o(e.target.value),
138
+ placeholder: "INV-0001",
139
+ className: M
140
+ })] }),
141
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
142
+ htmlFor: "inv-status",
143
+ className: N,
144
+ children: "Status"
145
+ }), /* @__PURE__ */ O("select", {
146
+ id: "inv-status",
147
+ value: s,
148
+ onChange: (e) => c(e.target.value),
149
+ className: M,
150
+ children: F.map((e) => /* @__PURE__ */ O("option", {
151
+ value: e,
152
+ children: e.replace(/_/g, " ")
153
+ }, e))
154
+ })] }),
155
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
156
+ htmlFor: "inv-currency",
157
+ className: N,
158
+ children: "Currency"
159
+ }), /* @__PURE__ */ O("input", {
160
+ id: "inv-currency",
161
+ type: "text",
162
+ value: l,
163
+ onChange: (e) => u(e.target.value.toUpperCase()),
164
+ maxLength: 3,
165
+ className: M
166
+ })] })
167
+ ]
168
+ }),
169
+ /* @__PURE__ */ k("div", {
170
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
171
+ children: [
172
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
173
+ htmlFor: "inv-subtotal",
174
+ className: N,
175
+ children: "Subtotal"
176
+ }), /* @__PURE__ */ O("input", {
177
+ id: "inv-subtotal",
178
+ type: "number",
179
+ min: "0",
180
+ step: "0.01",
181
+ value: f,
182
+ onChange: (e) => p(e.target.value),
183
+ className: M
184
+ })] }),
185
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
186
+ htmlFor: "inv-tax",
187
+ className: N,
188
+ children: "Tax"
189
+ }), /* @__PURE__ */ O("input", {
190
+ id: "inv-tax",
191
+ type: "number",
192
+ min: "0",
193
+ step: "0.01",
194
+ value: m,
195
+ onChange: (e) => h(e.target.value),
196
+ className: M
197
+ })] }),
198
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
199
+ htmlFor: "inv-total",
200
+ className: N,
201
+ children: "Total"
202
+ }), /* @__PURE__ */ O("input", {
203
+ id: "inv-total",
204
+ type: "number",
205
+ min: "0",
206
+ step: "0.01",
207
+ value: _,
208
+ onChange: (e) => y(e.target.value),
209
+ className: M
210
+ })] })
211
+ ]
212
+ }),
213
+ /* @__PURE__ */ k("div", {
214
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
215
+ children: [/* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
216
+ htmlFor: "inv-issue",
217
+ className: N,
218
+ children: "Issue date"
219
+ }), /* @__PURE__ */ O("input", {
220
+ id: "inv-issue",
221
+ type: "date",
222
+ value: x,
223
+ onChange: (e) => S(e.target.value),
224
+ className: M
225
+ })] }), /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
226
+ htmlFor: "inv-due",
227
+ className: N,
228
+ children: "Due date"
229
+ }), /* @__PURE__ */ O("input", {
230
+ id: "inv-due",
231
+ type: "date",
232
+ value: C,
233
+ onChange: (e) => w(e.target.value),
234
+ className: M
235
+ })] })]
236
+ }),
237
+ /* @__PURE__ */ k("div", {
238
+ className: "flex justify-end gap-3",
239
+ children: [/* @__PURE__ */ O("button", {
240
+ type: "button",
241
+ onClick: e,
242
+ className: "rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
243
+ children: "Cancel"
244
+ }), /* @__PURE__ */ O("button", {
245
+ type: "submit",
246
+ disabled: t.isPending,
247
+ 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",
248
+ children: t.isPending ? "Creating…" : "Create invoice"
249
+ })]
250
+ })
251
+ ]
252
+ })
253
+ });
254
+ }
255
+ function z({ onClose: e }) {
256
+ let t = f(), [n, r] = b(""), [i, a] = b("CARD"), [o, s] = b(""), [c, l] = b(""), [u, d] = b(""), [p, m] = b(""), [h, g] = b(!1), [_, y] = b(null);
257
+ return /* @__PURE__ */ O(v, {
258
+ title: "Add payment method",
259
+ description: "A passive annotation of which external card/account pays for a subscription — no full card numbers or CVV.",
260
+ onClose: e,
261
+ maxWidthClassName: "max-w-xl",
262
+ children: /* @__PURE__ */ k("form", {
263
+ onSubmit: (r) => {
264
+ if (r.preventDefault(), y(null), !n.trim()) {
265
+ y("A label is required.");
266
+ return;
267
+ }
268
+ t.mutate({
269
+ label: n.trim(),
270
+ type: i,
271
+ isDefault: h,
272
+ ...o.trim() ? { brand: o.trim() } : {},
273
+ ...c.trim() ? { last4: c.trim() } : {},
274
+ ...u.trim() ? { expiryMonth: Number(u) } : {},
275
+ ...p.trim() ? { expiryYear: Number(p) } : {}
276
+ }, {
277
+ onSuccess: () => e(),
278
+ onError: (e) => y(e instanceof Error ? e.message : "Could not add payment method.")
279
+ });
280
+ },
281
+ className: "space-y-4",
282
+ children: [
283
+ _ && /* @__PURE__ */ O("div", {
284
+ className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
285
+ children: _
286
+ }),
287
+ /* @__PURE__ */ k("div", {
288
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
289
+ children: [/* @__PURE__ */ k("div", { children: [/* @__PURE__ */ k("label", {
290
+ htmlFor: "pm-label",
291
+ className: N,
292
+ children: ["Label ", /* @__PURE__ */ O("span", {
293
+ className: "text-status-error-text",
294
+ children: "*"
295
+ })]
296
+ }), /* @__PURE__ */ O("input", {
297
+ id: "pm-label",
298
+ type: "text",
299
+ value: n,
300
+ onChange: (e) => r(e.target.value),
301
+ placeholder: "e.g. Personal Visa",
302
+ className: M,
303
+ required: !0
304
+ })] }), /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
305
+ htmlFor: "pm-type",
306
+ className: N,
307
+ children: "Type"
308
+ }), /* @__PURE__ */ O("select", {
309
+ id: "pm-type",
310
+ value: i,
311
+ onChange: (e) => a(e.target.value),
312
+ className: M,
313
+ children: I.map((e) => /* @__PURE__ */ O("option", {
314
+ value: e,
315
+ children: e.replace(/_/g, " ")
316
+ }, e))
317
+ })] })]
318
+ }),
319
+ /* @__PURE__ */ k("div", {
320
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
321
+ children: [
322
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
323
+ htmlFor: "pm-brand",
324
+ className: N,
325
+ children: "Brand"
326
+ }), /* @__PURE__ */ O("input", {
327
+ id: "pm-brand",
328
+ type: "text",
329
+ value: o,
330
+ onChange: (e) => s(e.target.value),
331
+ placeholder: "Visa, Amex…",
332
+ className: M
333
+ })] }),
334
+ /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
335
+ htmlFor: "pm-last4",
336
+ className: N,
337
+ children: "Last 4"
338
+ }), /* @__PURE__ */ O("input", {
339
+ id: "pm-last4",
340
+ type: "text",
341
+ inputMode: "numeric",
342
+ maxLength: 4,
343
+ value: c,
344
+ onChange: (e) => l(e.target.value.replace(/\D/g, "")),
345
+ placeholder: "4242",
346
+ className: M
347
+ })] }),
348
+ /* @__PURE__ */ k("div", {
349
+ className: "grid grid-cols-2 gap-2",
350
+ children: [/* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
351
+ htmlFor: "pm-exp-month",
352
+ className: N,
353
+ children: "Exp. mo."
354
+ }), /* @__PURE__ */ O("input", {
355
+ id: "pm-exp-month",
356
+ type: "number",
357
+ min: "1",
358
+ max: "12",
359
+ value: u,
360
+ onChange: (e) => d(e.target.value),
361
+ placeholder: "12",
362
+ className: M
363
+ })] }), /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("label", {
364
+ htmlFor: "pm-exp-year",
365
+ className: N,
366
+ children: "Exp. yr."
367
+ }), /* @__PURE__ */ O("input", {
368
+ id: "pm-exp-year",
369
+ type: "number",
370
+ min: "2024",
371
+ max: "2099",
372
+ value: p,
373
+ onChange: (e) => m(e.target.value),
374
+ placeholder: "2028",
375
+ className: M
376
+ })] })]
377
+ })
378
+ ]
379
+ }),
380
+ /* @__PURE__ */ k("label", {
381
+ className: "flex items-center gap-2 text-sm text-text-primary",
382
+ children: [/* @__PURE__ */ O("input", {
383
+ type: "checkbox",
384
+ checked: h,
385
+ onChange: (e) => g(e.target.checked),
386
+ className: "size-4 rounded border-border-subtle"
387
+ }), "Set as default"]
388
+ }),
389
+ /* @__PURE__ */ k("div", {
390
+ className: "flex justify-end gap-3",
391
+ children: [/* @__PURE__ */ O("button", {
392
+ type: "button",
393
+ onClick: e,
394
+ className: "rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
395
+ children: "Cancel"
396
+ }), /* @__PURE__ */ O("button", {
397
+ type: "submit",
398
+ disabled: t.isPending,
399
+ 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",
400
+ children: t.isPending ? "Adding…" : "Add payment method"
401
+ })]
402
+ })
403
+ ]
404
+ })
405
+ });
406
+ }
407
+ function B() {
408
+ let { data: e, isLoading: t, isError: n, refetch: r } = h(), i = _(), [a, d] = b(!1), f = e ?? [];
409
+ return /* @__PURE__ */ k(u, {
410
+ title: "Payment methods",
411
+ description: "Which external cards and accounts pay for your subscriptions",
412
+ action: /* @__PURE__ */ k("button", {
413
+ type: "button",
414
+ onClick: () => d(!0),
415
+ 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",
416
+ children: [/* @__PURE__ */ O(C, { className: "h-3.5 w-3.5" }), " Add payment method"]
417
+ }),
418
+ children: [t ? /* @__PURE__ */ O(l, { label: "Loading payment methods…" }) : n ? /* @__PURE__ */ O(c, {
419
+ message: "Could not load payment methods.",
420
+ onRetry: () => void r()
421
+ }) : f.length === 0 ? /* @__PURE__ */ O(s, {
422
+ illustration: "empty-data",
423
+ icon: /* @__PURE__ */ O(x, { className: "h-12 w-12" }),
424
+ title: "No payment methods",
425
+ description: "Annotate which card or account pays for each subscription. No full card numbers are stored."
426
+ }) : /* @__PURE__ */ O("div", {
427
+ className: "divide-y divide-border-subtle rounded-lg border border-border-subtle bg-bg-surface",
428
+ children: f.map((e) => /* @__PURE__ */ k("div", {
429
+ className: "flex items-center justify-between gap-3 p-3",
430
+ children: [/* @__PURE__ */ k("div", {
431
+ className: "flex min-w-0 items-center gap-2",
432
+ children: [/* @__PURE__ */ O(x, { className: "h-4 w-4 shrink-0 text-text-secondary" }), /* @__PURE__ */ k("div", {
433
+ className: "min-w-0",
434
+ children: [/* @__PURE__ */ k("p", {
435
+ className: "flex items-center gap-1.5 truncate text-sm font-medium text-text-primary",
436
+ children: [e.label, e.isDefault && /* @__PURE__ */ O(T, { className: "h-3 w-3 fill-current text-status-warning-text" })]
437
+ }), /* @__PURE__ */ O("p", {
438
+ className: "text-xs text-text-secondary",
439
+ children: [
440
+ e.brand,
441
+ e.last4 ? `•••• ${e.last4}` : null,
442
+ e.expiryMonth && e.expiryYear ? `${e.expiryMonth}/${e.expiryYear}` : null
443
+ ].filter(Boolean).join(" · ") || e.type.replace(/_/g, " ")
444
+ })]
445
+ })]
446
+ }), /* @__PURE__ */ k("div", {
447
+ className: "flex shrink-0 items-center gap-2",
448
+ children: [/* @__PURE__ */ O(o, { status: e.status }), /* @__PURE__ */ O("button", {
449
+ type: "button",
450
+ "aria-label": `Remove ${e.label}`,
451
+ disabled: i.isPending,
452
+ onClick: () => i.mutate(e.id),
453
+ className: "rounded-lg border border-border-subtle p-1.5 text-text-secondary hover:bg-status-error-bg-subtle hover:text-status-error-text disabled:opacity-50",
454
+ children: /* @__PURE__ */ O(E, { className: "h-4 w-4" })
455
+ })]
456
+ })]
457
+ }, e.id))
458
+ }), a && /* @__PURE__ */ O(z, { onClose: () => d(!1) })]
459
+ });
460
+ }
461
+ function V() {
462
+ let { navigateTo: u } = e(), [d, f] = b(0), [h, g] = b(""), [_, v] = b(!1), { data: x, isLoading: T, isError: E, refetch: M, isFetching: N } = p({
463
+ status: h || void 0,
56
464
  pagination: {
57
- limit: b,
58
- offset: w * b
465
+ limit: j,
466
+ offset: d * j
59
467
  }
60
- }), N = d(), P = f(() => O?.items ?? [], [O]), F = O?.pageInfo.hasMore ?? !1, I = f(() => {
61
- let e = P.filter((e) => S.has(e.status)), t = P[0]?.currency ?? "USD";
468
+ }), F = m(), I = y(() => x?.items ?? [], [x]), z = x?.pageInfo.hasMore ?? !1, V = y(() => {
469
+ let e = I.filter((e) => L.has(e.status)), t = I[0]?.currency ?? "USD";
62
470
  return {
63
471
  outstandingCount: e.length,
64
472
  outstandingTotal: e.reduce((e, t) => e + t.total, 0),
65
473
  currency: t
66
474
  };
67
- }, [P]);
68
- return /* @__PURE__ */ v(n, {
475
+ }, [I]);
476
+ return /* @__PURE__ */ k(n, {
69
477
  title: "Invoices",
70
478
  description: "Your billing ledger across every relationship",
479
+ actions: /* @__PURE__ */ k("button", {
480
+ type: "button",
481
+ onClick: () => v(!0),
482
+ className: "inline-flex items-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
483
+ children: [/* @__PURE__ */ O(C, { className: "h-4 w-4" }), " Create invoice"]
484
+ }),
71
485
  children: [
72
- /* @__PURE__ */ _(y, {
486
+ /* @__PURE__ */ O(A, {
73
487
  className: "mb-4",
74
488
  children: "Every invoice from your recurring relationships in one ledger. Filter by status and settle issued or overdue invoices directly."
75
489
  }),
76
- !k && !A && P.length > 0 && /* @__PURE__ */ v("div", {
490
+ !T && !E && I.length > 0 && /* @__PURE__ */ k("div", {
77
491
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
78
- children: [/* @__PURE__ */ _(r, {
492
+ children: [/* @__PURE__ */ O(r, {
79
493
  featured: !0,
80
- icon: /* @__PURE__ */ _(h, {}),
81
- value: i(I.outstandingTotal, I.currency, { maximumFractionDigits: 0 }),
494
+ icon: /* @__PURE__ */ O(w, {}),
495
+ value: i(V.outstandingTotal, V.currency, { maximumFractionDigits: 0 }),
82
496
  label: "Outstanding (this page)"
83
- }), /* @__PURE__ */ _(r, {
84
- icon: /* @__PURE__ */ _(m, {}),
85
- value: I.outstandingCount,
497
+ }), /* @__PURE__ */ O(r, {
498
+ icon: /* @__PURE__ */ O(S, {}),
499
+ value: V.outstandingCount,
86
500
  label: "Open invoices (this page)"
87
501
  })]
88
502
  }),
89
- /* @__PURE__ */ _("div", {
503
+ /* @__PURE__ */ O("div", {
90
504
  className: "mt-6 flex flex-wrap items-center gap-3",
91
- children: /* @__PURE__ */ _("select", {
92
- value: E,
505
+ children: /* @__PURE__ */ O("select", {
506
+ "aria-label": "Filter by status",
507
+ value: h,
93
508
  onChange: (e) => {
94
- D(e.target.value), T(0);
509
+ g(e.target.value), f(0);
95
510
  },
96
511
  className: "rounded-lg border border-border-subtle bg-bg-surface px-3 py-2 text-xs text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
97
- children: x.map((e) => /* @__PURE__ */ _("option", {
512
+ children: P.map((e) => /* @__PURE__ */ O("option", {
98
513
  value: e.value,
99
514
  children: e.label
100
515
  }, e.value))
101
516
  })
102
517
  }),
103
- k ? /* @__PURE__ */ _(l, { label: "Loading invoices…" }) : A ? /* @__PURE__ */ _(c, {
518
+ T ? /* @__PURE__ */ O(l, { label: "Loading invoices…" }) : E ? /* @__PURE__ */ O(c, {
104
519
  message: "Could not load invoices.",
105
- onRetry: () => void j()
106
- }) : P.length === 0 ? /* @__PURE__ */ _("div", {
520
+ onRetry: () => void M()
521
+ }) : I.length === 0 ? /* @__PURE__ */ O("div", {
107
522
  className: "mt-6",
108
- children: /* @__PURE__ */ _(s, {
523
+ children: /* @__PURE__ */ O(s, {
109
524
  illustration: "empty-data",
110
- icon: /* @__PURE__ */ _(h, { className: "h-12 w-12" }),
525
+ icon: /* @__PURE__ */ O(w, { className: "h-12 w-12" }),
111
526
  title: "No invoices",
112
- description: E ? "No invoices match this status filter." : "Invoices from your relationships will appear here."
527
+ description: h ? "No invoices match this status filter." : "Invoices from your relationships will appear here — or create one manually.",
528
+ action: /* @__PURE__ */ O("button", {
529
+ type: "button",
530
+ onClick: () => v(!0),
531
+ className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
532
+ children: "Create invoice"
533
+ })
113
534
  })
114
- }) : /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ v("div", {
535
+ }) : /* @__PURE__ */ k(D, { children: [/* @__PURE__ */ k("div", {
115
536
  className: "mt-6 overflow-hidden rounded-lg border border-border-subtle bg-bg-surface",
116
- children: [/* @__PURE__ */ v("div", {
537
+ children: [/* @__PURE__ */ k("div", {
117
538
  className: "hidden grid-cols-[1.5fr_1fr_1fr_1fr_auto] gap-4 border-b border-border-subtle bg-bg-sunken px-4 py-2.5 text-xs font-medium text-text-secondary sm:grid",
118
539
  children: [
119
- /* @__PURE__ */ _("span", { children: "Invoice" }),
120
- /* @__PURE__ */ _("span", { children: "Status" }),
121
- /* @__PURE__ */ _("span", {
540
+ /* @__PURE__ */ O("span", { children: "Invoice" }),
541
+ /* @__PURE__ */ O("span", { children: "Status" }),
542
+ /* @__PURE__ */ O("span", {
122
543
  className: "text-right",
123
544
  children: "Total"
124
545
  }),
125
- /* @__PURE__ */ _("span", {
546
+ /* @__PURE__ */ O("span", {
126
547
  className: "text-right",
127
548
  children: "Due"
128
549
  }),
129
- /* @__PURE__ */ _("span", {
550
+ /* @__PURE__ */ O("span", {
130
551
  className: "text-right",
131
552
  children: "Action"
132
553
  })
133
554
  ]
134
- }), /* @__PURE__ */ _("div", {
555
+ }), /* @__PURE__ */ O("div", {
135
556
  className: "divide-y divide-border-subtle",
136
- children: P.map((e) => /* @__PURE__ */ v("div", {
557
+ children: I.map((e) => /* @__PURE__ */ k("div", {
137
558
  className: "grid grid-cols-1 gap-2 px-4 py-3 sm:grid-cols-[1.5fr_1fr_1fr_1fr_auto] sm:items-center sm:gap-4",
138
559
  children: [
139
- /* @__PURE__ */ v("button", {
560
+ /* @__PURE__ */ k("button", {
140
561
  type: "button",
141
- onClick: () => C(`/relationships/${e.relationshipId}`),
562
+ onClick: () => u(`/relationships/${e.relationshipId}`),
142
563
  className: "min-w-0 text-left",
143
- children: [/* @__PURE__ */ _("p", {
564
+ children: [/* @__PURE__ */ O("p", {
144
565
  className: "truncate text-sm font-medium text-text-primary",
145
566
  children: e.number || `Invoice ${e.id.slice(0, 8)}`
146
- }), /* @__PURE__ */ _("p", {
567
+ }), /* @__PURE__ */ O("p", {
147
568
  className: "text-xs text-text-secondary",
148
569
  children: e.issueDate ? `Issued ${a(e.issueDate)}` : "—"
149
570
  })]
150
571
  }),
151
- /* @__PURE__ */ _("span", { children: /* @__PURE__ */ _(o, { status: e.status }) }),
152
- /* @__PURE__ */ _("span", {
572
+ /* @__PURE__ */ O("span", { children: /* @__PURE__ */ O(o, { status: e.status }) }),
573
+ /* @__PURE__ */ O("span", {
153
574
  className: "text-sm font-semibold tabular-nums text-text-primary sm:text-right",
154
575
  children: i(e.total, e.currency)
155
576
  }),
156
- /* @__PURE__ */ _("span", {
577
+ /* @__PURE__ */ O("span", {
157
578
  className: "text-xs text-text-secondary sm:text-right",
158
579
  children: e.dueDate ? a(e.dueDate) : "—"
159
580
  }),
160
- /* @__PURE__ */ _("span", {
581
+ /* @__PURE__ */ O("span", {
161
582
  className: "sm:text-right",
162
- children: S.has(e.status) ? /* @__PURE__ */ _("button", {
583
+ children: L.has(e.status) ? /* @__PURE__ */ O("button", {
163
584
  type: "button",
164
- disabled: N.isPending,
165
- onClick: () => N.mutate(e.id),
585
+ disabled: F.isPending,
586
+ onClick: () => F.mutate(e.id),
166
587
  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",
167
588
  children: "Mark paid"
168
- }) : e.paidAt ? /* @__PURE__ */ v("span", {
589
+ }) : e.paidAt ? /* @__PURE__ */ k("span", {
169
590
  className: "text-xs text-text-secondary",
170
591
  children: ["Paid ", a(e.paidAt)]
171
- }) : /* @__PURE__ */ _("span", {
592
+ }) : /* @__PURE__ */ O("span", {
172
593
  className: "text-xs text-text-secondary",
173
594
  children: "—"
174
595
  })
@@ -176,36 +597,38 @@ function C() {
176
597
  ]
177
598
  }, e.id))
178
599
  })]
179
- }), /* @__PURE__ */ v("div", {
600
+ }), /* @__PURE__ */ k("div", {
180
601
  className: "mt-4 flex items-center justify-between",
181
- children: [/* @__PURE__ */ v("p", {
602
+ children: [/* @__PURE__ */ k("p", {
182
603
  className: "text-xs text-text-secondary",
183
604
  children: [
184
605
  "Page ",
185
- w + 1,
186
- M ? " · refreshing…" : ""
606
+ d + 1,
607
+ N ? " · refreshing…" : ""
187
608
  ]
188
- }), /* @__PURE__ */ v("div", {
609
+ }), /* @__PURE__ */ k("div", {
189
610
  className: "flex gap-2",
190
- children: [/* @__PURE__ */ _("button", {
611
+ children: [/* @__PURE__ */ O("button", {
191
612
  type: "button",
192
- disabled: w === 0,
193
- onClick: () => T((e) => Math.max(0, e - 1)),
194
- className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", w === 0 ? "cursor-not-allowed text-text-secondary opacity-50" : "text-text-primary hover:bg-bg-sunken"),
613
+ disabled: d === 0,
614
+ onClick: () => f((e) => Math.max(0, e - 1)),
615
+ className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", d === 0 ? "cursor-not-allowed text-text-secondary opacity-50" : "text-text-primary hover:bg-bg-sunken"),
195
616
  children: "Previous"
196
- }), /* @__PURE__ */ _("button", {
617
+ }), /* @__PURE__ */ O("button", {
197
618
  type: "button",
198
- disabled: !F,
199
- onClick: () => T((e) => e + 1),
200
- className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", F ? "text-text-primary hover:bg-bg-sunken" : "cursor-not-allowed text-text-secondary opacity-50"),
619
+ disabled: !z,
620
+ onClick: () => f((e) => e + 1),
621
+ className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", z ? "text-text-primary hover:bg-bg-sunken" : "cursor-not-allowed text-text-secondary opacity-50"),
201
622
  children: "Next"
202
623
  })]
203
624
  })]
204
- })] })
625
+ })] }),
626
+ /* @__PURE__ */ O(B, {}),
627
+ _ && /* @__PURE__ */ O(R, { onClose: () => v(!1) })
205
628
  ]
206
629
  });
207
630
  }
208
631
  //#endregion
209
- export { C as InvoicesPage };
632
+ export { V as InvoicesPage };
210
633
 
211
634
  //# sourceMappingURL=InvoicesPage.js.map