@burdenoff/microfe-subscriberbot 2026.801.1 → 2026.829.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/subscriberbot/admin/AdminDashboardPage.d.ts.map +1 -1
  2. package/dist/subscriberbot/admin/AdminDashboardPage.js +80 -83
  3. package/dist/subscriberbot/admin/AdminDashboardPage.js.map +1 -1
  4. package/dist/subscriberbot/components/viz.js +51 -27
  5. package/dist/subscriberbot/components/viz.js.map +1 -1
  6. package/dist/subscriberbot/hooks/index.d.ts +2 -1
  7. package/dist/subscriberbot/hooks/index.d.ts.map +1 -1
  8. package/dist/subscriberbot/hooks/index.js +1 -0
  9. package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts +12 -1
  10. package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts.map +1 -1
  11. package/dist/subscriberbot/hooks/useSubscriberBotApi.js +82 -56
  12. package/dist/subscriberbot/hooks/useSubscriberBotApi.js.map +1 -1
  13. package/dist/subscriberbot/hooks/useTr.d.ts +17 -0
  14. package/dist/subscriberbot/hooks/useTr.d.ts.map +1 -0
  15. package/dist/subscriberbot/hooks/useTr.js +14 -0
  16. package/dist/subscriberbot/hooks/useTr.js.map +1 -0
  17. package/dist/subscriberbot/pages/AssetVaultPage.d.ts.map +1 -1
  18. package/dist/subscriberbot/pages/AssetVaultPage.js +155 -97
  19. package/dist/subscriberbot/pages/AssetVaultPage.js.map +1 -1
  20. package/dist/subscriberbot/pages/DashboardPage.d.ts.map +1 -1
  21. package/dist/subscriberbot/pages/DashboardPage.js +113 -105
  22. package/dist/subscriberbot/pages/DashboardPage.js.map +1 -1
  23. package/dist/subscriberbot/pages/InboxPage.d.ts.map +1 -1
  24. package/dist/subscriberbot/pages/InboxPage.js +404 -369
  25. package/dist/subscriberbot/pages/InboxPage.js.map +1 -1
  26. package/dist/subscriberbot/pages/InsightsPage.d.ts.map +1 -1
  27. package/dist/subscriberbot/pages/InsightsPage.js +94 -93
  28. package/dist/subscriberbot/pages/InsightsPage.js.map +1 -1
  29. package/dist/subscriberbot/pages/InvoicesPage.d.ts +3 -2
  30. package/dist/subscriberbot/pages/InvoicesPage.d.ts.map +1 -1
  31. package/dist/subscriberbot/pages/InvoicesPage.js +368 -362
  32. package/dist/subscriberbot/pages/InvoicesPage.js.map +1 -1
  33. package/dist/subscriberbot/pages/WorkflowsPage.d.ts.map +1 -1
  34. package/dist/subscriberbot/pages/WorkflowsPage.js +209 -193
  35. package/dist/subscriberbot/pages/WorkflowsPage.js.map +1 -1
  36. package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts +3 -1
  37. package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts.map +1 -1
  38. package/dist/subscriberbot/pages/agents/AgentDetailPage.js +296 -228
  39. package/dist/subscriberbot/pages/agents/AgentDetailPage.js.map +1 -1
  40. package/dist/subscriberbot/pages/agents/AgentNewPage.d.ts.map +1 -1
  41. package/dist/subscriberbot/pages/agents/AgentNewPage.js +96 -76
  42. package/dist/subscriberbot/pages/agents/AgentNewPage.js.map +1 -1
  43. package/dist/subscriberbot/pages/agents/AgentsListPage.d.ts.map +1 -1
  44. package/dist/subscriberbot/pages/agents/AgentsListPage.js +145 -161
  45. package/dist/subscriberbot/pages/agents/AgentsListPage.js.map +1 -1
  46. package/dist/subscriberbot/pages/providers/ProviderDetailPage.d.ts +4 -2
  47. package/dist/subscriberbot/pages/providers/ProviderDetailPage.d.ts.map +1 -1
  48. package/dist/subscriberbot/pages/providers/ProviderDetailPage.js +577 -402
  49. package/dist/subscriberbot/pages/providers/ProviderDetailPage.js.map +1 -1
  50. package/dist/subscriberbot/pages/providers/ProviderNewPage.d.ts.map +1 -1
  51. package/dist/subscriberbot/pages/providers/ProviderNewPage.js +167 -129
  52. package/dist/subscriberbot/pages/providers/ProviderNewPage.js.map +1 -1
  53. package/dist/subscriberbot/pages/providers/ProvidersListPage.d.ts.map +1 -1
  54. package/dist/subscriberbot/pages/providers/ProvidersListPage.js +171 -218
  55. package/dist/subscriberbot/pages/providers/ProvidersListPage.js.map +1 -1
  56. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.d.ts.map +1 -1
  57. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js +340 -279
  58. package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js.map +1 -1
  59. package/dist/subscriberbot/pages/relationships/RelationshipNewPage.d.ts.map +1 -1
  60. package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js +185 -166
  61. package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js.map +1 -1
  62. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.d.ts.map +1 -1
  63. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js +153 -182
  64. package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js.map +1 -1
  65. package/dist/subscriberbot/types/index.d.ts +37 -0
  66. package/dist/subscriberbot/types/index.d.ts.map +1 -1
  67. package/package.json +2 -2
@@ -2,52 +2,28 @@ import { useSubscriberBot as e } from "../context/SubscriberBotContext.js";
2
2
  import { cn as t } from "../utils/cn.js";
3
3
  import { PageLayout as n } from "../components/PageLayout.js";
4
4
  import { MetricsCard as r } from "../components/MetricsCard.js";
5
- import { formatCurrency as i, formatDate as a } from "../utils/formatters.js";
6
- import { StatusBadge as o } from "../components/StatusBadge.js";
7
- import { EmptyState as s } from "../components/EmptyState.js";
8
- import { Modal as c } from "../components/Modal.js";
9
- import { ErrorView as l, LoadingView as u, Section as d } from "../components/StateViews.js";
10
- import { CHART_COLORS as f, Donut as p, Legend as m } from "../components/viz.js";
11
- import { useCreateInvoice as h, useCreatePaymentInstrument as g, useInvoices as _, useMarkInvoicePaid as v, usePaymentInstruments as y, useRelationships as b, useRemovePaymentInstrument as x } from "../hooks/useSubscriberBotApi.js";
12
- import { useMemo as S, useState as C } from "react";
13
- import { AlertTriangle as w, CheckCircle2 as T, CreditCard as E, FileText as D, Plus as O, Receipt as k, Star as A, Trash2 as j } from "lucide-react";
14
- import { Fragment as M, jsx as N, jsxs as P } from "react/jsx-runtime";
15
- import { GlassCard as F, PagePurpose as I } from "@burdenoff/fe-libs/ui";
5
+ import { formatCurrency as i, formatDate as a, formatEnumLabel as o } from "../utils/formatters.js";
6
+ import { StatusBadge as s } from "../components/StatusBadge.js";
7
+ import { EmptyState as c } from "../components/EmptyState.js";
8
+ import { Modal as l } from "../components/Modal.js";
9
+ import { ErrorView as u, LoadingView as d, Section as f } from "../components/StateViews.js";
10
+ import { CHART_COLORS as p, Donut as m, Legend as h } from "../components/viz.js";
11
+ import { useCreateInvoice as g, useCreatePaymentInstrument as _, useInvoices as v, useMarkInvoicePaid as y, usePaymentInstruments as b, useRelationships as x, useRemovePaymentInstrument as S } from "../hooks/useSubscriberBotApi.js";
12
+ import { useTr as C } from "../hooks/useTr.js";
13
+ import { useMemo as w, useState as T } from "react";
14
+ import { AlertTriangle as E, CheckCircle2 as D, CreditCard as O, FileText as ee, Plus as k, Receipt as A, Star as j, Trash2 as M } from "lucide-react";
15
+ import { Fragment as N, jsx as P, jsxs as F } from "react/jsx-runtime";
16
+ import { GlassCard as I, PagePurpose as te } from "@burdenoff/fe-libs/ui";
16
17
  //#region src/subscriberbot/pages/InvoicesPage.tsx
17
- var L = 25, 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 = [
18
- {
19
- value: "",
20
- label: "All statuses"
21
- },
22
- {
23
- value: "ISSUED",
24
- label: "Issued"
25
- },
26
- {
27
- value: "OVERDUE",
28
- label: "Overdue"
29
- },
30
- {
31
- value: "PAID",
32
- label: "Paid"
33
- },
34
- {
35
- value: "FAILED",
36
- label: "Failed"
37
- },
38
- {
39
- value: "DRAFT",
40
- label: "Draft"
41
- },
42
- {
43
- value: "CANCELLED",
44
- label: "Cancelled"
45
- },
46
- {
47
- value: "REFUNDED",
48
- label: "Refunded"
49
- }
50
- ], V = [
18
+ var L = 25, 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 = {
19
+ ISSUED: "invoices.filters.issued",
20
+ OVERDUE: "invoices.filters.overdue",
21
+ PAID: "invoices.filters.paid",
22
+ FAILED: "invoices.filters.failed",
23
+ DRAFT: "invoices.filters.draft",
24
+ CANCELLED: "invoices.filters.cancelled",
25
+ REFUNDED: "invoices.filters.refunded"
26
+ }, V = [
51
27
  "ISSUED",
52
28
  "DRAFT",
53
29
  "OVERDUE",
@@ -76,185 +52,189 @@ var L = 25, R = "w-full rounded-lg border border-border-subtle bg-bg-surface px-
76
52
  REFUNDED: "var(--color-status-warning-text)"
77
53
  };
78
54
  function G({ onClose: e }) {
79
- let t = h(), n = b({ pagination: {
55
+ let t = C(), n = g(), r = x({ pagination: {
80
56
  limit: 100,
81
57
  offset: 0
82
- } }).data?.items ?? [], [r, i] = C(""), [a, o] = C(""), [s, l] = C("ISSUED"), [u, d] = C("USD"), [f, p] = C(""), [m, g] = C(""), [_, v] = C(""), [y, x] = C(""), [S, w] = C(""), [T, E] = C(null);
83
- return /* @__PURE__ */ N(c, {
84
- title: "Create invoice",
58
+ } }).data?.items ?? [], [i, a] = T(""), [o, s] = T(""), [c, u] = T("ISSUED"), [d, f] = T("USD"), [p, m] = T(""), [h, _] = T(""), [v, y] = T(""), [b, S] = T(""), [w, E] = T(""), [D, O] = T(null);
59
+ return /* @__PURE__ */ P(l, {
60
+ title: t("invoices.createModal.title", "Create invoice"),
85
61
  onClose: e,
86
62
  maxWidthClassName: "max-w-xl",
87
- children: /* @__PURE__ */ P("form", {
88
- onSubmit: (n) => {
89
- if (n.preventDefault(), E(null), !r) {
90
- E("Select the relationship this invoice belongs to.");
63
+ children: /* @__PURE__ */ F("form", {
64
+ onSubmit: (r) => {
65
+ if (r.preventDefault(), O(null), !i) {
66
+ O(t("invoices.createModal.relationshipRequired", "Select the relationship this invoice belongs to."));
91
67
  return;
92
68
  }
93
- t.mutate({
94
- relationshipId: r,
95
- status: s,
96
- currency: u.trim() || "USD",
97
- ...a.trim() ? { number: a.trim() } : {},
98
- ...f.trim() ? { subtotal: Number(f) } : {},
99
- ...m.trim() ? { taxAmount: Number(m) } : {},
100
- ..._.trim() ? { total: Number(_) } : {},
101
- ...y ? { issueDate: new Date(y).toISOString() } : {},
102
- ...S ? { dueDate: new Date(S).toISOString() } : {}
69
+ n.mutate({
70
+ relationshipId: i,
71
+ status: c,
72
+ currency: d.trim() || "USD",
73
+ ...o.trim() ? { number: o.trim() } : {},
74
+ ...p.trim() ? { subtotal: Number(p) } : {},
75
+ ...h.trim() ? { taxAmount: Number(h) } : {},
76
+ ...v.trim() ? { total: Number(v) } : {},
77
+ ...b ? { issueDate: new Date(b).toISOString() } : {},
78
+ ...w ? { dueDate: new Date(w).toISOString() } : {}
103
79
  }, {
104
80
  onSuccess: () => e(),
105
- onError: (e) => E(e instanceof Error ? e.message : "Could not create invoice.")
81
+ onError: (e) => O(e instanceof Error ? e.message : t("invoices.createModal.error", "Could not create invoice."))
106
82
  });
107
83
  },
108
84
  className: "space-y-4",
109
85
  children: [
110
- T && /* @__PURE__ */ N("div", {
86
+ D && /* @__PURE__ */ P("div", {
111
87
  className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
112
- children: T
88
+ children: D
113
89
  }),
114
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ P("label", {
90
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ F("label", {
115
91
  htmlFor: "inv-relationship",
116
92
  className: z,
117
- children: ["Relationship ", /* @__PURE__ */ N("span", {
118
- className: "text-status-error-text",
119
- children: "*"
120
- })]
121
- }), /* @__PURE__ */ P("select", {
93
+ children: [
94
+ t("invoices.createModal.relationshipLabel", "Relationship"),
95
+ " ",
96
+ /* @__PURE__ */ P("span", {
97
+ className: "text-status-error-text",
98
+ children: "*"
99
+ })
100
+ ]
101
+ }), /* @__PURE__ */ F("select", {
122
102
  id: "inv-relationship",
123
- value: r,
124
- onChange: (e) => i(e.target.value),
103
+ value: i,
104
+ onChange: (e) => a(e.target.value),
125
105
  className: R,
126
106
  required: !0,
127
- children: [/* @__PURE__ */ N("option", {
107
+ children: [/* @__PURE__ */ P("option", {
128
108
  value: "",
129
- children: "— Select a relationship —"
130
- }), n.map((e) => /* @__PURE__ */ N("option", {
109
+ children: t("invoices.createModal.relationshipPlaceholder", "— Select a relationship —")
110
+ }), r.map((e) => /* @__PURE__ */ P("option", {
131
111
  value: e.id,
132
112
  children: e.label
133
113
  }, e.id))]
134
114
  })] }),
135
- /* @__PURE__ */ P("div", {
115
+ /* @__PURE__ */ F("div", {
136
116
  className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
137
117
  children: [
138
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
118
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
139
119
  htmlFor: "inv-number",
140
120
  className: z,
141
- children: "Number"
142
- }), /* @__PURE__ */ N("input", {
121
+ children: t("invoices.createModal.numberLabel", "Number")
122
+ }), /* @__PURE__ */ P("input", {
143
123
  id: "inv-number",
144
124
  type: "text",
145
- value: a,
146
- onChange: (e) => o(e.target.value),
147
- placeholder: "INV-0001",
125
+ value: o,
126
+ onChange: (e) => s(e.target.value),
127
+ placeholder: t("invoices.createModal.numberPlaceholder", "INV-0001"),
148
128
  className: R
149
129
  })] }),
150
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
130
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
151
131
  htmlFor: "inv-status",
152
132
  className: z,
153
- children: "Status"
154
- }), /* @__PURE__ */ N("select", {
133
+ children: t("invoices.createModal.statusLabel", "Status")
134
+ }), /* @__PURE__ */ P("select", {
155
135
  id: "inv-status",
156
- value: s,
157
- onChange: (e) => l(e.target.value),
136
+ value: c,
137
+ onChange: (e) => u(e.target.value),
158
138
  className: R,
159
- children: V.map((e) => /* @__PURE__ */ N("option", {
139
+ children: V.map((e) => /* @__PURE__ */ P("option", {
160
140
  value: e,
161
- children: e.replace(/_/g, " ")
141
+ children: t(B[e], e)
162
142
  }, e))
163
143
  })] }),
164
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
144
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
165
145
  htmlFor: "inv-currency",
166
146
  className: z,
167
- children: "Currency"
168
- }), /* @__PURE__ */ N("input", {
147
+ children: t("invoices.createModal.currencyLabel", "Currency")
148
+ }), /* @__PURE__ */ P("input", {
169
149
  id: "inv-currency",
170
150
  type: "text",
171
- value: u,
172
- onChange: (e) => d(e.target.value.toUpperCase()),
151
+ value: d,
152
+ onChange: (e) => f(e.target.value.toUpperCase()),
173
153
  maxLength: 3,
174
154
  className: R
175
155
  })] })
176
156
  ]
177
157
  }),
178
- /* @__PURE__ */ P("div", {
158
+ /* @__PURE__ */ F("div", {
179
159
  className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
180
160
  children: [
181
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
161
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
182
162
  htmlFor: "inv-subtotal",
183
163
  className: z,
184
- children: "Subtotal"
185
- }), /* @__PURE__ */ N("input", {
164
+ children: t("invoices.createModal.subtotalLabel", "Subtotal")
165
+ }), /* @__PURE__ */ P("input", {
186
166
  id: "inv-subtotal",
187
167
  type: "number",
188
168
  min: "0",
189
169
  step: "0.01",
190
- value: f,
191
- onChange: (e) => p(e.target.value),
170
+ value: p,
171
+ onChange: (e) => m(e.target.value),
192
172
  className: R
193
173
  })] }),
194
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
174
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
195
175
  htmlFor: "inv-tax",
196
176
  className: z,
197
- children: "Tax"
198
- }), /* @__PURE__ */ N("input", {
177
+ children: t("invoices.createModal.taxLabel", "Tax")
178
+ }), /* @__PURE__ */ P("input", {
199
179
  id: "inv-tax",
200
180
  type: "number",
201
181
  min: "0",
202
182
  step: "0.01",
203
- value: m,
204
- onChange: (e) => g(e.target.value),
183
+ value: h,
184
+ onChange: (e) => _(e.target.value),
205
185
  className: R
206
186
  })] }),
207
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
187
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
208
188
  htmlFor: "inv-total",
209
189
  className: z,
210
- children: "Total"
211
- }), /* @__PURE__ */ N("input", {
190
+ children: t("invoices.createModal.totalLabel", "Total")
191
+ }), /* @__PURE__ */ P("input", {
212
192
  id: "inv-total",
213
193
  type: "number",
214
194
  min: "0",
215
195
  step: "0.01",
216
- value: _,
217
- onChange: (e) => v(e.target.value),
196
+ value: v,
197
+ onChange: (e) => y(e.target.value),
218
198
  className: R
219
199
  })] })
220
200
  ]
221
201
  }),
222
- /* @__PURE__ */ P("div", {
202
+ /* @__PURE__ */ F("div", {
223
203
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
224
- children: [/* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
204
+ children: [/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
225
205
  htmlFor: "inv-issue",
226
206
  className: z,
227
- children: "Issue date"
228
- }), /* @__PURE__ */ N("input", {
207
+ children: t("invoices.createModal.issueDateLabel", "Issue date")
208
+ }), /* @__PURE__ */ P("input", {
229
209
  id: "inv-issue",
230
210
  type: "date",
231
- value: y,
232
- onChange: (e) => x(e.target.value),
211
+ value: b,
212
+ onChange: (e) => S(e.target.value),
233
213
  className: R
234
- })] }), /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
214
+ })] }), /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
235
215
  htmlFor: "inv-due",
236
216
  className: z,
237
- children: "Due date"
238
- }), /* @__PURE__ */ N("input", {
217
+ children: t("invoices.createModal.dueDateLabel", "Due date")
218
+ }), /* @__PURE__ */ P("input", {
239
219
  id: "inv-due",
240
220
  type: "date",
241
- value: S,
242
- onChange: (e) => w(e.target.value),
221
+ value: w,
222
+ onChange: (e) => E(e.target.value),
243
223
  className: R
244
224
  })] })]
245
225
  }),
246
- /* @__PURE__ */ P("div", {
226
+ /* @__PURE__ */ F("div", {
247
227
  className: "flex justify-end gap-3",
248
- children: [/* @__PURE__ */ N("button", {
228
+ children: [/* @__PURE__ */ P("button", {
249
229
  type: "button",
250
230
  onClick: e,
251
231
  className: "rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
252
- children: "Cancel"
253
- }), /* @__PURE__ */ N("button", {
232
+ children: t("invoices.createModal.cancel", "Cancel")
233
+ }), /* @__PURE__ */ P("button", {
254
234
  type: "submit",
255
- disabled: t.isPending,
235
+ disabled: n.isPending,
256
236
  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",
257
- children: t.isPending ? "Creating…" : "Create invoice"
237
+ children: n.isPending ? t("invoices.creating", "Creating…") : t("invoices.createModal.submit", "Create invoice")
258
238
  })]
259
239
  })
260
240
  ]
@@ -262,151 +242,155 @@ function G({ onClose: e }) {
262
242
  });
263
243
  }
264
244
  function K({ onClose: e }) {
265
- let t = g(), [n, r] = C(""), [i, a] = C("CARD"), [o, s] = C(""), [l, u] = C(""), [d, f] = C(""), [p, m] = C(""), [h, _] = C(!1), [v, y] = C(null);
266
- return /* @__PURE__ */ N(c, {
267
- title: "Add payment method",
268
- description: "A passive annotation of which external card/account pays for a subscription — no full card numbers or CVV.",
245
+ let t = C(), n = _(), [r, i] = T(""), [a, s] = T("CARD"), [c, u] = T(""), [d, f] = T(""), [p, m] = T(""), [h, g] = T(""), [v, y] = T(!1), [b, x] = T(null);
246
+ return /* @__PURE__ */ P(l, {
247
+ title: t("invoices.addPaymentMethodModal.title", "Add payment method"),
248
+ description: t("invoices.addPaymentMethodModal.description", "A passive annotation of which external card/account pays for a subscription — no full card numbers or CVV."),
269
249
  onClose: e,
270
250
  maxWidthClassName: "max-w-xl",
271
- children: /* @__PURE__ */ P("form", {
272
- onSubmit: (r) => {
273
- if (r.preventDefault(), y(null), !n.trim()) {
274
- y("A label is required.");
251
+ children: /* @__PURE__ */ F("form", {
252
+ onSubmit: (i) => {
253
+ if (i.preventDefault(), x(null), !r.trim()) {
254
+ x(t("invoices.addPaymentMethodModal.labelRequired", "A label is required."));
275
255
  return;
276
256
  }
277
- t.mutate({
278
- label: n.trim(),
279
- type: i,
280
- isDefault: h,
281
- ...o.trim() ? { brand: o.trim() } : {},
282
- ...l.trim() ? { last4: l.trim() } : {},
283
- ...d.trim() ? { expiryMonth: Number(d) } : {},
284
- ...p.trim() ? { expiryYear: Number(p) } : {}
257
+ n.mutate({
258
+ label: r.trim(),
259
+ type: a,
260
+ isDefault: v,
261
+ ...c.trim() ? { brand: c.trim() } : {},
262
+ ...d.trim() ? { last4: d.trim() } : {},
263
+ ...p.trim() ? { expiryMonth: Number(p) } : {},
264
+ ...h.trim() ? { expiryYear: Number(h) } : {}
285
265
  }, {
286
266
  onSuccess: () => e(),
287
- onError: (e) => y(e instanceof Error ? e.message : "Could not add payment method.")
267
+ onError: (e) => x(e instanceof Error ? e.message : t("invoices.addPaymentMethodModal.error", "Could not add payment method."))
288
268
  });
289
269
  },
290
270
  className: "space-y-4",
291
271
  children: [
292
- v && /* @__PURE__ */ N("div", {
272
+ b && /* @__PURE__ */ P("div", {
293
273
  className: "rounded-lg border border-status-error-text/30 bg-status-error-bg-subtle px-4 py-2 text-sm text-status-error-text",
294
- children: v
274
+ children: b
295
275
  }),
296
- /* @__PURE__ */ P("div", {
276
+ /* @__PURE__ */ F("div", {
297
277
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
298
- children: [/* @__PURE__ */ P("div", { children: [/* @__PURE__ */ P("label", {
278
+ children: [/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ F("label", {
299
279
  htmlFor: "pm-label",
300
280
  className: z,
301
- children: ["Label ", /* @__PURE__ */ N("span", {
302
- className: "text-status-error-text",
303
- children: "*"
304
- })]
305
- }), /* @__PURE__ */ N("input", {
281
+ children: [
282
+ t("invoices.addPaymentMethodModal.labelLabel", "Label"),
283
+ " ",
284
+ /* @__PURE__ */ P("span", {
285
+ className: "text-status-error-text",
286
+ children: "*"
287
+ })
288
+ ]
289
+ }), /* @__PURE__ */ P("input", {
306
290
  id: "pm-label",
307
291
  type: "text",
308
- value: n,
309
- onChange: (e) => r(e.target.value),
310
- placeholder: "e.g. Personal Visa",
292
+ value: r,
293
+ onChange: (e) => i(e.target.value),
294
+ placeholder: t("invoices.addPaymentMethodModal.labelPlaceholder", "e.g. Personal Visa"),
311
295
  className: R,
312
296
  required: !0
313
- })] }), /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
297
+ })] }), /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
314
298
  htmlFor: "pm-type",
315
299
  className: z,
316
- children: "Type"
317
- }), /* @__PURE__ */ N("select", {
300
+ children: t("invoices.addPaymentMethodModal.typeLabel", "Type")
301
+ }), /* @__PURE__ */ P("select", {
318
302
  id: "pm-type",
319
- value: i,
320
- onChange: (e) => a(e.target.value),
303
+ value: a,
304
+ onChange: (e) => s(e.target.value),
321
305
  className: R,
322
- children: H.map((e) => /* @__PURE__ */ N("option", {
306
+ children: H.map((e) => /* @__PURE__ */ P("option", {
323
307
  value: e,
324
- children: e.replace(/_/g, " ")
308
+ children: o(e)
325
309
  }, e))
326
310
  })] })]
327
311
  }),
328
- /* @__PURE__ */ P("div", {
312
+ /* @__PURE__ */ F("div", {
329
313
  className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
330
314
  children: [
331
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
315
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
332
316
  htmlFor: "pm-brand",
333
317
  className: z,
334
- children: "Brand"
335
- }), /* @__PURE__ */ N("input", {
318
+ children: t("invoices.addPaymentMethodModal.brandLabel", "Brand")
319
+ }), /* @__PURE__ */ P("input", {
336
320
  id: "pm-brand",
337
321
  type: "text",
338
- value: o,
339
- onChange: (e) => s(e.target.value),
340
- placeholder: "Visa, Amex…",
322
+ value: c,
323
+ onChange: (e) => u(e.target.value),
324
+ placeholder: t("invoices.addPaymentMethodModal.brandPlaceholder", "Visa, Amex…"),
341
325
  className: R
342
326
  })] }),
343
- /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
327
+ /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
344
328
  htmlFor: "pm-last4",
345
329
  className: z,
346
- children: "Last 4"
347
- }), /* @__PURE__ */ N("input", {
330
+ children: t("invoices.addPaymentMethodModal.last4Label", "Last 4")
331
+ }), /* @__PURE__ */ P("input", {
348
332
  id: "pm-last4",
349
333
  type: "text",
350
334
  inputMode: "numeric",
351
335
  maxLength: 4,
352
- value: l,
353
- onChange: (e) => u(e.target.value.replace(/\D/g, "")),
354
- placeholder: "4242",
336
+ value: d,
337
+ onChange: (e) => f(e.target.value.replace(/\D/g, "")),
338
+ placeholder: t("invoices.addPaymentMethodModal.last4Placeholder", "4242"),
355
339
  className: R
356
340
  })] }),
357
- /* @__PURE__ */ P("div", {
341
+ /* @__PURE__ */ F("div", {
358
342
  className: "grid grid-cols-2 gap-2",
359
- children: [/* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
343
+ children: [/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
360
344
  htmlFor: "pm-exp-month",
361
345
  className: z,
362
- children: "Exp. mo."
363
- }), /* @__PURE__ */ N("input", {
346
+ children: t("invoices.addPaymentMethodModal.expMonthLabel", "Exp. mo.")
347
+ }), /* @__PURE__ */ P("input", {
364
348
  id: "pm-exp-month",
365
349
  type: "number",
366
350
  min: "1",
367
351
  max: "12",
368
- value: d,
369
- onChange: (e) => f(e.target.value),
370
- placeholder: "12",
352
+ value: p,
353
+ onChange: (e) => m(e.target.value),
354
+ placeholder: t("invoices.addPaymentMethodModal.expMonthPlaceholder", "12"),
371
355
  className: R
372
- })] }), /* @__PURE__ */ P("div", { children: [/* @__PURE__ */ N("label", {
356
+ })] }), /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
373
357
  htmlFor: "pm-exp-year",
374
358
  className: z,
375
- children: "Exp. yr."
376
- }), /* @__PURE__ */ N("input", {
359
+ children: t("invoices.addPaymentMethodModal.expYearLabel", "Exp. yr.")
360
+ }), /* @__PURE__ */ P("input", {
377
361
  id: "pm-exp-year",
378
362
  type: "number",
379
363
  min: "2024",
380
364
  max: "2099",
381
- value: p,
382
- onChange: (e) => m(e.target.value),
383
- placeholder: "2028",
365
+ value: h,
366
+ onChange: (e) => g(e.target.value),
367
+ placeholder: t("invoices.addPaymentMethodModal.expYearPlaceholder", "2028"),
384
368
  className: R
385
369
  })] })]
386
370
  })
387
371
  ]
388
372
  }),
389
- /* @__PURE__ */ P("label", {
373
+ /* @__PURE__ */ F("label", {
390
374
  className: "flex items-center gap-2 text-sm text-text-primary",
391
- children: [/* @__PURE__ */ N("input", {
375
+ children: [/* @__PURE__ */ P("input", {
392
376
  type: "checkbox",
393
- checked: h,
394
- onChange: (e) => _(e.target.checked),
377
+ checked: v,
378
+ onChange: (e) => y(e.target.checked),
395
379
  className: "size-4 rounded border-border-subtle"
396
- }), "Set as default"]
380
+ }), t("invoices.addPaymentMethodModal.defaultLabel", "Set as default")]
397
381
  }),
398
- /* @__PURE__ */ P("div", {
382
+ /* @__PURE__ */ F("div", {
399
383
  className: "flex justify-end gap-3",
400
- children: [/* @__PURE__ */ N("button", {
384
+ children: [/* @__PURE__ */ P("button", {
401
385
  type: "button",
402
386
  onClick: e,
403
387
  className: "rounded-lg border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
404
- children: "Cancel"
405
- }), /* @__PURE__ */ N("button", {
388
+ children: t("invoices.addPaymentMethodModal.cancel", "Cancel")
389
+ }), /* @__PURE__ */ P("button", {
406
390
  type: "submit",
407
- disabled: t.isPending,
391
+ disabled: n.isPending,
408
392
  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",
409
- children: t.isPending ? "Adding…" : "Add payment method"
393
+ children: n.isPending ? t("invoices.addPaymentMethodModal.adding", "Adding…") : t("invoices.addPaymentMethodModal.submit", "Add payment method")
410
394
  })]
411
395
  })
412
396
  ]
@@ -414,170 +398,191 @@ function K({ onClose: e }) {
414
398
  });
415
399
  }
416
400
  function q() {
417
- let { data: e, isLoading: t, isError: n, refetch: r } = y(), i = x(), [a, c] = C(!1), f = e ?? [];
418
- return /* @__PURE__ */ P(d, {
419
- title: "Payment methods",
420
- description: "Which external cards and accounts pay for your subscriptions",
421
- action: /* @__PURE__ */ P("button", {
401
+ let e = C(), { data: t, isLoading: n, isError: r, refetch: i } = b(), a = S(), [l, p] = T(!1), m = t ?? [];
402
+ return /* @__PURE__ */ F(f, {
403
+ title: e("invoices.paymentMethods.title", "Payment methods"),
404
+ description: e("invoices.paymentMethods.description", "Which external cards and accounts pay for your subscriptions"),
405
+ action: /* @__PURE__ */ F("button", {
422
406
  type: "button",
423
- onClick: () => c(!0),
407
+ onClick: () => p(!0),
424
408
  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",
425
- children: [/* @__PURE__ */ N(O, { className: "h-3.5 w-3.5" }), " Add payment method"]
409
+ children: [
410
+ /* @__PURE__ */ P(k, { className: "h-3.5 w-3.5" }),
411
+ " ",
412
+ e("invoices.paymentMethods.add", "Add payment method")
413
+ ]
426
414
  }),
427
- children: [t ? /* @__PURE__ */ N(u, { label: "Loading payment methods…" }) : n ? /* @__PURE__ */ N(l, {
428
- message: "Could not load payment methods.",
429
- onRetry: () => void r()
430
- }) : f.length === 0 ? /* @__PURE__ */ N(s, {
415
+ children: [n ? /* @__PURE__ */ P(d, { label: e("invoices.paymentMethods.loading", "Loading payment methods…") }) : r ? /* @__PURE__ */ P(u, {
416
+ message: e("invoices.paymentMethods.error", "Could not load payment methods."),
417
+ onRetry: () => void i()
418
+ }) : m.length === 0 ? /* @__PURE__ */ P(c, {
431
419
  illustration: "empty-data",
432
- icon: /* @__PURE__ */ N(E, { className: "h-12 w-12" }),
433
- title: "No payment methods",
434
- description: "Annotate which card or account pays for each subscription. No full card numbers are stored."
435
- }) : /* @__PURE__ */ N("div", {
420
+ icon: /* @__PURE__ */ P(O, { className: "h-12 w-12" }),
421
+ title: e("invoices.paymentMethods.emptyTitle", "No payment methods"),
422
+ description: e("invoices.paymentMethods.emptyDescription", "Annotate which card or account pays for each subscription. No full card numbers are stored.")
423
+ }) : /* @__PURE__ */ P("div", {
436
424
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3",
437
- children: f.map((e) => {
438
- let t = [e.expiryMonth && e.expiryYear ? `Exp ${String(e.expiryMonth).padStart(2, "0")}/${String(e.expiryYear).slice(-2)}` : null].filter(Boolean);
439
- return /* @__PURE__ */ P(F, {
425
+ children: m.map((t) => {
426
+ let n = [t.expiryMonth && t.expiryYear ? `Exp ${String(t.expiryMonth).padStart(2, "0")}/${String(t.expiryYear).slice(-2)}` : null].filter(Boolean);
427
+ return /* @__PURE__ */ F(I, {
440
428
  treatment: "metric",
441
429
  className: "flex flex-col gap-4 p-4",
442
- children: [/* @__PURE__ */ P("div", {
430
+ children: [/* @__PURE__ */ F("div", {
443
431
  className: "flex items-start justify-between gap-2",
444
- children: [/* @__PURE__ */ P("div", {
432
+ children: [/* @__PURE__ */ F("div", {
445
433
  className: "flex items-center gap-3",
446
- children: [/* @__PURE__ */ N("span", {
434
+ children: [/* @__PURE__ */ P("span", {
447
435
  className: "grid h-9 w-12 place-items-center rounded-md bg-[var(--color-accent-soft)] text-text-primary",
448
- children: /* @__PURE__ */ N(E, {
436
+ children: /* @__PURE__ */ P(O, {
449
437
  className: "h-4 w-4",
450
438
  "aria-hidden": !0
451
439
  })
452
- }), /* @__PURE__ */ P("div", {
440
+ }), /* @__PURE__ */ F("div", {
453
441
  className: "min-w-0",
454
- children: [/* @__PURE__ */ P("p", {
442
+ children: [/* @__PURE__ */ F("p", {
455
443
  className: "flex items-center gap-1.5 truncate text-sm font-semibold text-text-primary",
456
- children: [e.brand || e.label, e.isDefault && /* @__PURE__ */ P("span", {
444
+ children: [t.brand || t.label, t.isDefault && /* @__PURE__ */ F("span", {
457
445
  className: "inline-flex items-center gap-1 rounded-full bg-status-success-bg-subtle px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-status-success-text",
458
- children: [/* @__PURE__ */ N(A, {
446
+ children: [/* @__PURE__ */ P(j, {
459
447
  className: "h-2.5 w-2.5 fill-current",
460
448
  "aria-hidden": !0
461
- }), "Default"]
449
+ }), e("invoices.paymentMethods.default", "Default")]
462
450
  })]
463
- }), /* @__PURE__ */ N("p", {
451
+ }), /* @__PURE__ */ P("p", {
464
452
  className: "font-mono text-sm tracking-[0.15em] text-text-secondary",
465
- children: e.last4 ? `•••• ${e.last4}` : e.type.replace(/_/g, " ")
453
+ children: t.last4 ? `•••• ${t.last4}` : o(t.type)
466
454
  })]
467
455
  })]
468
- }), /* @__PURE__ */ N(o, { status: e.status })]
469
- }), /* @__PURE__ */ P("div", {
456
+ }), /* @__PURE__ */ P(s, { status: t.status })]
457
+ }), /* @__PURE__ */ F("div", {
470
458
  className: "mt-auto flex items-center justify-between border-t border-border-subtle pt-3",
471
- children: [/* @__PURE__ */ N("p", {
459
+ children: [/* @__PURE__ */ P("p", {
472
460
  className: "truncate text-xs text-text-secondary",
473
- children: [e.label, ...t].filter(Boolean).join(" · ")
474
- }), /* @__PURE__ */ P("button", {
461
+ children: [t.label, ...n].filter(Boolean).join(" · ")
462
+ }), /* @__PURE__ */ F("button", {
475
463
  type: "button",
476
- "aria-label": `Remove ${e.label}`,
477
- disabled: i.isPending,
478
- onClick: () => i.mutate(e.id),
464
+ "aria-label": e("invoices.paymentMethods.removeAria", "Remove {{label}}", { label: t.label }),
465
+ disabled: a.isPending,
466
+ onClick: () => a.mutate(t.id),
479
467
  className: "inline-flex shrink-0 items-center gap-1 rounded-lg border border-border-subtle px-2.5 py-1 text-xs font-medium text-text-secondary hover:border-status-error-text/40 hover:bg-status-error-bg-subtle hover:text-status-error-text disabled:opacity-50",
480
- children: [/* @__PURE__ */ N(j, {
468
+ children: [/* @__PURE__ */ P(M, {
481
469
  className: "h-3.5 w-3.5",
482
470
  "aria-hidden": !0
483
- }), "Remove"]
471
+ }), e("invoices.paymentMethods.remove", "Remove")]
484
472
  })]
485
473
  })]
486
- }, e.id);
474
+ }, t.id);
487
475
  })
488
- }), a && /* @__PURE__ */ N(K, { onClose: () => c(!1) })]
476
+ }), l && /* @__PURE__ */ P(K, { onClose: () => p(!1) })]
489
477
  });
490
478
  }
491
479
  function J() {
492
- let { navigateTo: c } = e(), [d, h] = C(0), [g, y] = C(""), [b, x] = C(!1), { data: E, isLoading: A, isError: j, refetch: R, isFetching: z } = _({
493
- status: g || void 0,
480
+ let o = C(), { navigateTo: l } = e(), [f, g] = T(0), [_, b] = T(""), [S, O] = T(!1), j = [{
481
+ value: "",
482
+ label: o("invoices.filters.allStatuses", "All statuses")
483
+ }, ...V.map((e) => ({
484
+ value: e,
485
+ label: o(B[e], e)
486
+ }))], { data: M, isLoading: R, isError: z, refetch: H, isFetching: K } = v({
487
+ status: _ || void 0,
494
488
  pagination: {
495
489
  limit: L,
496
- offset: d * L
490
+ offset: f * L
497
491
  }
498
- }), V = v(), H = S(() => E?.items ?? [], [E]), K = E?.pageInfo.hasMore ?? !1, J = S(() => {
499
- let e = H.filter((e) => U.has(e.status)), t = H[0]?.currency ?? "USD", n = /* @__PURE__ */ new Map();
500
- for (let e of H) n.set(e.status, (n.get(e.status) ?? 0) + 1);
492
+ }), J = y(), Y = x({ pagination: {
493
+ limit: 100,
494
+ offset: 0
495
+ } }), X = w(() => {
496
+ let e = /* @__PURE__ */ new Map();
497
+ for (let t of Y.data?.items ?? []) e.set(t.id, t.label);
498
+ return e;
499
+ }, [Y.data]), Z = w(() => M?.items ?? [], [M]), Q = M?.pageInfo.hasMore ?? !1, $ = w(() => {
500
+ let e = Z.filter((e) => U.has(e.status)), t = Z[0]?.currency ?? "USD", n = /* @__PURE__ */ new Map();
501
+ for (let e of Z) n.set(e.status, (n.get(e.status) ?? 0) + 1);
501
502
  let r = Array.from(n.entries()).sort((e, t) => t[1] - e[1]).map(([e, t], n) => ({
502
- label: e.charAt(0) + e.slice(1).toLowerCase(),
503
+ label: o(B[e], e.charAt(0) + e.slice(1).toLowerCase()),
503
504
  value: t,
504
- color: W[e] ?? f[n % f.length]
505
+ color: W[e] ?? p[n % p.length]
505
506
  }));
506
507
  return {
507
508
  outstandingCount: e.length,
508
509
  outstandingTotal: e.reduce((e, t) => e + t.total, 0),
509
- paidCount: H.filter((e) => e.status === "PAID").length,
510
- overdueCount: H.filter((e) => e.status === "OVERDUE").length,
510
+ paidCount: Z.filter((e) => e.status === "PAID").length,
511
+ overdueCount: Z.filter((e) => e.status === "OVERDUE").length,
511
512
  distribution: r,
512
513
  currency: t
513
514
  };
514
- }, [H]);
515
- return /* @__PURE__ */ P(n, {
516
- title: "Invoices",
517
- description: "Your billing ledger across every relationship",
518
- actions: /* @__PURE__ */ P("button", {
515
+ }, [Z, o]);
516
+ return /* @__PURE__ */ F(n, {
517
+ title: o("invoices.title", "Invoices"),
518
+ description: o("invoices.description", "Your billing ledger across every relationship"),
519
+ actions: /* @__PURE__ */ F("button", {
519
520
  type: "button",
520
- onClick: () => x(!0),
521
+ onClick: () => O(!0),
521
522
  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",
522
- children: [/* @__PURE__ */ N(O, { className: "h-4 w-4" }), " Create invoice"]
523
+ children: [
524
+ /* @__PURE__ */ P(k, { className: "h-4 w-4" }),
525
+ " ",
526
+ o("invoices.create", "Create invoice")
527
+ ]
523
528
  }),
524
529
  children: [
525
- /* @__PURE__ */ N(I, {
530
+ /* @__PURE__ */ P(te, {
526
531
  className: "mb-4",
527
- children: "Every invoice from your recurring relationships in one ledger. Filter by status and settle issued or overdue invoices directly."
532
+ children: o("invoices.purpose", "Every invoice from your recurring relationships in one ledger. Filter by status and settle issued or overdue invoices directly.")
528
533
  }),
529
- !A && !j && H.length > 0 && /* @__PURE__ */ P("div", {
534
+ !R && !z && Z.length > 0 && /* @__PURE__ */ F("div", {
530
535
  className: "grid grid-cols-1 gap-4 lg:grid-cols-3",
531
- children: [/* @__PURE__ */ P("div", {
536
+ children: [/* @__PURE__ */ F("div", {
532
537
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:col-span-2",
533
538
  children: [
534
- /* @__PURE__ */ N(r, {
539
+ /* @__PURE__ */ P(r, {
535
540
  featured: !0,
536
- icon: /* @__PURE__ */ N(k, {}),
537
- value: i(J.outstandingTotal, J.currency, { maximumFractionDigits: 0 }),
538
- label: "Outstanding · this page"
541
+ icon: /* @__PURE__ */ P(A, {}),
542
+ value: i($.outstandingTotal, $.currency, { maximumFractionDigits: 0 }),
543
+ label: o("invoices.metrics.outstanding", "Outstanding · this page")
539
544
  }),
540
- /* @__PURE__ */ N(r, {
541
- icon: /* @__PURE__ */ N(D, {}),
542
- value: J.outstandingCount,
543
- label: "Open invoices"
545
+ /* @__PURE__ */ P(r, {
546
+ icon: /* @__PURE__ */ P(ee, {}),
547
+ value: $.outstandingCount,
548
+ label: o("invoices.metrics.openInvoices", "Open invoices")
544
549
  }),
545
- /* @__PURE__ */ N(r, {
546
- icon: /* @__PURE__ */ N(w, {}),
547
- value: J.overdueCount,
548
- label: "Overdue",
549
- ...J.overdueCount > 0 ? { trend: "down" } : {}
550
+ /* @__PURE__ */ P(r, {
551
+ icon: /* @__PURE__ */ P(E, {}),
552
+ value: $.overdueCount,
553
+ label: o("invoices.metrics.overdue", "Overdue"),
554
+ ...$.overdueCount > 0 ? { trend: "down" } : {}
550
555
  }),
551
- /* @__PURE__ */ N(r, {
552
- icon: /* @__PURE__ */ N(T, {}),
553
- value: J.paidCount,
554
- label: "Paid",
555
- ...J.paidCount > 0 ? { trend: "up" } : {}
556
+ /* @__PURE__ */ P(r, {
557
+ icon: /* @__PURE__ */ P(D, {}),
558
+ value: $.paidCount,
559
+ label: o("invoices.metrics.paid", "Paid"),
560
+ ...$.paidCount > 0 ? { trend: "up" } : {}
556
561
  })
557
562
  ]
558
- }), /* @__PURE__ */ P(F, {
563
+ }), /* @__PURE__ */ F(I, {
559
564
  treatment: "insight",
560
565
  className: "p-6",
561
566
  children: [
562
- /* @__PURE__ */ N("p", {
567
+ /* @__PURE__ */ P("p", {
563
568
  className: "text-sm font-semibold text-text-primary",
564
- children: "Status breakdown"
569
+ children: o("invoices.metrics.statusBreakdown", "Status breakdown")
565
570
  }),
566
- /* @__PURE__ */ N("p", {
571
+ /* @__PURE__ */ P("p", {
567
572
  className: "text-xs text-text-secondary",
568
- children: "Across the invoices on this page"
573
+ children: o("invoices.metrics.statusBreakdownHint", "Across the invoices on this page")
569
574
  }),
570
- /* @__PURE__ */ P("div", {
575
+ /* @__PURE__ */ F("div", {
571
576
  className: "mt-4 flex flex-col items-center gap-5 sm:flex-row sm:items-center lg:flex-col xl:flex-row",
572
- children: [/* @__PURE__ */ N(p, {
573
- data: J.distribution,
577
+ children: [/* @__PURE__ */ P(m, {
578
+ data: $.distribution,
574
579
  size: 132,
575
580
  thickness: 16,
576
- centerLabel: String(H.length),
577
- centerSub: "invoices",
581
+ centerLabel: String(Z.length),
582
+ centerSub: o("invoices.metrics.invoices", "invoices"),
578
583
  className: "shrink-0"
579
- }), /* @__PURE__ */ N(m, {
580
- data: J.distribution,
584
+ }), /* @__PURE__ */ P(h, {
585
+ data: $.distribution,
581
586
  className: "w-full min-w-0 flex-1",
582
587
  valueFormat: (e) => String(e)
583
588
  })]
@@ -585,99 +590,104 @@ function J() {
585
590
  ]
586
591
  })]
587
592
  }),
588
- /* @__PURE__ */ N("div", {
593
+ /* @__PURE__ */ P("div", {
589
594
  className: "mt-6 flex flex-wrap items-center gap-3",
590
- children: /* @__PURE__ */ N("select", {
591
- "aria-label": "Filter by status",
592
- value: g,
595
+ children: /* @__PURE__ */ P("select", {
596
+ "aria-label": o("invoices.filters.statusLabel", "Filter by status"),
597
+ value: _,
593
598
  onChange: (e) => {
594
- y(e.target.value), h(0);
599
+ b(e.target.value), g(0);
595
600
  },
596
601
  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)]",
597
- children: B.map((e) => /* @__PURE__ */ N("option", {
602
+ children: j.map((e) => /* @__PURE__ */ P("option", {
598
603
  value: e.value,
599
604
  children: e.label
600
605
  }, e.value))
601
606
  })
602
607
  }),
603
- A ? /* @__PURE__ */ N(u, { label: "Loading invoices…" }) : j ? /* @__PURE__ */ N(l, {
604
- message: "Could not load invoices.",
605
- onRetry: () => void R()
606
- }) : H.length === 0 ? /* @__PURE__ */ N("div", {
608
+ R ? /* @__PURE__ */ P(d, { label: o("invoices.loading", "Loading invoices…") }) : z ? /* @__PURE__ */ P(u, {
609
+ message: o("invoices.error", "Could not load invoices."),
610
+ onRetry: () => void H()
611
+ }) : Z.length === 0 ? /* @__PURE__ */ P("div", {
607
612
  className: "mt-6",
608
- children: /* @__PURE__ */ N(s, {
613
+ children: /* @__PURE__ */ P(c, {
609
614
  illustration: "empty-data",
610
- icon: /* @__PURE__ */ N(k, { className: "h-12 w-12" }),
611
- title: "No invoices",
612
- description: g ? "No invoices match this status filter." : "Invoices from your relationships will appear here — or create one manually.",
613
- action: /* @__PURE__ */ N("button", {
615
+ icon: /* @__PURE__ */ P(A, { className: "h-12 w-12" }),
616
+ title: o("invoices.emptyTitle", "No invoices"),
617
+ description: _ ? o("invoices.emptyDescriptionFiltered", "No invoices match this status filter.") : o("invoices.emptyDescription", "Invoices from your relationships will appear here — or create one manually."),
618
+ action: /* @__PURE__ */ P("button", {
614
619
  type: "button",
615
- onClick: () => x(!0),
620
+ onClick: () => O(!0),
616
621
  className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
617
- children: "Create invoice"
622
+ children: o("invoices.create", "Create invoice")
618
623
  })
619
624
  })
620
- }) : /* @__PURE__ */ P(M, { children: [/* @__PURE__ */ P("div", {
625
+ }) : /* @__PURE__ */ F(N, { children: [/* @__PURE__ */ F("div", {
621
626
  className: "mt-6 overflow-hidden rounded-lg border border-border-subtle bg-bg-surface",
622
- children: [/* @__PURE__ */ P("div", {
623
- 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",
627
+ children: [/* @__PURE__ */ F("div", {
628
+ className: "hidden grid-cols-[1.3fr_1.2fr_0.8fr_0.8fr_0.8fr_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",
624
629
  children: [
625
- /* @__PURE__ */ N("span", { children: "Invoice" }),
626
- /* @__PURE__ */ N("span", { children: "Status" }),
627
- /* @__PURE__ */ N("span", {
630
+ /* @__PURE__ */ P("span", { children: o("invoices.table.invoice", "Invoice") }),
631
+ /* @__PURE__ */ P("span", { children: o("invoices.table.subscription", "Subscription") }),
632
+ /* @__PURE__ */ P("span", { children: o("invoices.table.status", "Status") }),
633
+ /* @__PURE__ */ P("span", {
628
634
  className: "text-right",
629
- children: "Total"
635
+ children: o("invoices.table.total", "Total")
630
636
  }),
631
- /* @__PURE__ */ N("span", {
637
+ /* @__PURE__ */ P("span", {
632
638
  className: "text-right",
633
- children: "Due"
639
+ children: o("invoices.table.due", "Due")
634
640
  }),
635
- /* @__PURE__ */ N("span", {
641
+ /* @__PURE__ */ P("span", {
636
642
  className: "text-right",
637
- children: "Action"
643
+ children: o("invoices.table.action", "Action")
638
644
  })
639
645
  ]
640
- }), /* @__PURE__ */ N("div", {
646
+ }), /* @__PURE__ */ P("div", {
641
647
  className: "divide-y divide-border-subtle",
642
- children: H.map((e) => /* @__PURE__ */ P("div", {
643
- className: "grid grid-cols-1 gap-2 px-4 py-3 transition-colors hover:bg-bg-sunken/50 sm:grid-cols-[1.5fr_1fr_1fr_1fr_auto] sm:items-center sm:gap-4",
648
+ children: Z.map((e) => /* @__PURE__ */ F("div", {
649
+ className: "grid grid-cols-1 gap-2 px-4 py-3 transition-colors hover:bg-bg-sunken/50 sm:grid-cols-[1.3fr_1.2fr_0.8fr_0.8fr_0.8fr_auto] sm:items-center sm:gap-4",
644
650
  children: [
645
- /* @__PURE__ */ P("button", {
651
+ /* @__PURE__ */ F("button", {
646
652
  type: "button",
647
- onClick: () => c(`/relationships/${e.relationshipId}`),
653
+ onClick: () => l(`/relationships/${e.relationshipId}`),
648
654
  className: "min-w-0 text-left",
649
- children: [/* @__PURE__ */ N("p", {
655
+ children: [/* @__PURE__ */ P("p", {
650
656
  className: "truncate text-sm font-medium text-text-primary",
651
- children: e.number || `Invoice ${e.id.slice(0, 8)}`
652
- }), /* @__PURE__ */ N("p", {
657
+ children: e.number || `${o("invoices.table.invoice", "Invoice")} ${e.id.slice(0, 8)}`
658
+ }), /* @__PURE__ */ P("p", {
653
659
  className: "text-xs text-text-secondary",
654
- children: e.issueDate ? `Issued ${a(e.issueDate)}` : "—"
660
+ children: e.issueDate ? o("invoices.table.issued", "Issued {{date}}", { date: a(e.issueDate) }) : "—"
655
661
  })]
656
662
  }),
657
- /* @__PURE__ */ N("span", { children: /* @__PURE__ */ N(o, { status: e.status }) }),
658
- /* @__PURE__ */ N("span", {
663
+ /* @__PURE__ */ P("span", {
664
+ className: "min-w-0 truncate text-sm text-text-secondary",
665
+ children: X.get(e.relationshipId) ?? "—"
666
+ }),
667
+ /* @__PURE__ */ P("span", { children: /* @__PURE__ */ P(s, { status: e.status }) }),
668
+ /* @__PURE__ */ P("span", {
659
669
  className: "text-sm font-semibold tabular-nums text-text-primary sm:text-right",
660
670
  children: i(e.total, e.currency)
661
671
  }),
662
- /* @__PURE__ */ N("span", {
672
+ /* @__PURE__ */ P("span", {
663
673
  className: "text-xs text-text-secondary sm:text-right",
664
674
  children: e.dueDate ? a(e.dueDate) : "—"
665
675
  }),
666
- /* @__PURE__ */ N("span", {
676
+ /* @__PURE__ */ P("span", {
667
677
  className: "sm:text-right",
668
- children: U.has(e.status) ? /* @__PURE__ */ P("button", {
678
+ children: U.has(e.status) ? /* @__PURE__ */ F("button", {
669
679
  type: "button",
670
- disabled: V.isPending,
671
- onClick: () => V.mutate(e.id),
680
+ disabled: J.isPending,
681
+ onClick: () => J.mutate(e.id),
672
682
  className: "inline-flex items-center gap-1.5 rounded-lg border border-status-success-text/30 bg-status-success-bg-subtle px-3 py-1.5 text-xs font-medium text-status-success-text hover:opacity-90 disabled:opacity-50",
673
- children: [/* @__PURE__ */ N(T, {
683
+ children: [/* @__PURE__ */ P(D, {
674
684
  className: "h-3.5 w-3.5",
675
685
  "aria-hidden": !0
676
- }), "Mark paid"]
686
+ }), o("invoices.table.markPaid", "Mark paid")]
677
687
  }) : e.paidAt ? /* @__PURE__ */ P("span", {
678
688
  className: "text-xs text-text-secondary",
679
- children: ["Paid ", a(e.paidAt)]
680
- }) : /* @__PURE__ */ N("span", {
689
+ children: o("invoices.table.paidAt", "Paid {{date}}", { date: a(e.paidAt) })
690
+ }) : /* @__PURE__ */ P("span", {
681
691
  className: "text-xs text-text-secondary",
682
692
  children: "—"
683
693
  })
@@ -685,34 +695,30 @@ function J() {
685
695
  ]
686
696
  }, e.id))
687
697
  })]
688
- }), /* @__PURE__ */ P("div", {
698
+ }), /* @__PURE__ */ F("div", {
689
699
  className: "mt-4 flex items-center justify-between",
690
- children: [/* @__PURE__ */ P("p", {
700
+ children: [/* @__PURE__ */ F("p", {
691
701
  className: "text-xs text-text-secondary",
692
- children: [
693
- "Page ",
694
- d + 1,
695
- z ? " · refreshing…" : ""
696
- ]
697
- }), /* @__PURE__ */ P("div", {
702
+ children: [o("invoices.pagination.page", "Page {{page}}", { page: f + 1 }), K ? ` · ${o("invoices.pagination.refreshing", "refreshing…")}` : ""]
703
+ }), /* @__PURE__ */ F("div", {
698
704
  className: "flex gap-2",
699
- children: [/* @__PURE__ */ N("button", {
705
+ children: [/* @__PURE__ */ P("button", {
700
706
  type: "button",
701
- disabled: d === 0,
702
- onClick: () => h((e) => Math.max(0, e - 1)),
703
- 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"),
704
- children: "Previous"
705
- }), /* @__PURE__ */ N("button", {
707
+ disabled: f === 0,
708
+ onClick: () => g((e) => Math.max(0, e - 1)),
709
+ className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", f === 0 ? "cursor-not-allowed text-text-secondary opacity-50" : "text-text-primary hover:bg-bg-sunken"),
710
+ children: o("invoices.pagination.previous", "Previous")
711
+ }), /* @__PURE__ */ P("button", {
706
712
  type: "button",
707
- disabled: !K,
708
- onClick: () => h((e) => e + 1),
709
- className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", K ? "text-text-primary hover:bg-bg-sunken" : "cursor-not-allowed text-text-secondary opacity-50"),
710
- children: "Next"
713
+ disabled: !Q,
714
+ onClick: () => g((e) => e + 1),
715
+ className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium", Q ? "text-text-primary hover:bg-bg-sunken" : "cursor-not-allowed text-text-secondary opacity-50"),
716
+ children: o("invoices.pagination.next", "Next")
711
717
  })]
712
718
  })]
713
719
  })] }),
714
- /* @__PURE__ */ N(q, {}),
715
- b && /* @__PURE__ */ N(G, { onClose: () => x(!1) })
720
+ /* @__PURE__ */ P(q, {}),
721
+ S && /* @__PURE__ */ P(G, { onClose: () => O(!1) })
716
722
  ]
717
723
  });
718
724
  }