@burdenoff/microfe-subscriberbot 2026.827.1 → 2026.1014.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.
- package/dist/subscriberbot/admin/AdminDashboardPage.d.ts.map +1 -1
- package/dist/subscriberbot/admin/AdminDashboardPage.js +80 -83
- package/dist/subscriberbot/admin/AdminDashboardPage.js.map +1 -1
- package/dist/subscriberbot/hooks/index.d.ts +1 -0
- package/dist/subscriberbot/hooks/index.d.ts.map +1 -1
- package/dist/subscriberbot/hooks/index.js +1 -0
- package/dist/subscriberbot/hooks/useTr.d.ts +17 -0
- package/dist/subscriberbot/hooks/useTr.d.ts.map +1 -0
- package/dist/subscriberbot/hooks/useTr.js +14 -0
- package/dist/subscriberbot/hooks/useTr.js.map +1 -0
- package/dist/subscriberbot/pages/AssetVaultPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/AssetVaultPage.js +111 -109
- package/dist/subscriberbot/pages/AssetVaultPage.js.map +1 -1
- package/dist/subscriberbot/pages/DashboardPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/DashboardPage.js +113 -105
- package/dist/subscriberbot/pages/DashboardPage.js.map +1 -1
- package/dist/subscriberbot/pages/InboxPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/InboxPage.js +404 -369
- package/dist/subscriberbot/pages/InboxPage.js.map +1 -1
- package/dist/subscriberbot/pages/InsightsPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/InsightsPage.js +94 -93
- package/dist/subscriberbot/pages/InsightsPage.js.map +1 -1
- package/dist/subscriberbot/pages/InvoicesPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/InvoicesPage.js +360 -366
- package/dist/subscriberbot/pages/InvoicesPage.js.map +1 -1
- package/dist/subscriberbot/pages/WorkflowsPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/WorkflowsPage.js +209 -193
- package/dist/subscriberbot/pages/WorkflowsPage.js.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js +268 -236
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentNewPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentNewPage.js +96 -76
- package/dist/subscriberbot/pages/agents/AgentNewPage.js.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentsListPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentsListPage.js +145 -161
- package/dist/subscriberbot/pages/agents/AgentsListPage.js.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.js +514 -441
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.js.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderNewPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderNewPage.js +167 -129
- package/dist/subscriberbot/pages/providers/ProviderNewPage.js.map +1 -1
- package/dist/subscriberbot/pages/providers/ProvidersListPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/providers/ProvidersListPage.js +171 -218
- package/dist/subscriberbot/pages/providers/ProvidersListPage.js.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js +340 -279
- package/dist/subscriberbot/pages/relationships/RelationshipDetailPage.js.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipNewPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js +185 -166
- package/dist/subscriberbot/pages/relationships/RelationshipNewPage.js.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipsListPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js +153 -182
- package/dist/subscriberbot/pages/relationships/RelationshipsListPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
7
|
-
import { EmptyState as
|
|
8
|
-
import { Modal as
|
|
9
|
-
import { ErrorView as
|
|
10
|
-
import { CHART_COLORS as
|
|
11
|
-
import { useCreateInvoice as
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
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
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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 =
|
|
55
|
+
let t = C(), n = g(), r = x({ pagination: {
|
|
80
56
|
limit: 100,
|
|
81
57
|
offset: 0
|
|
82
|
-
} }).data?.items ?? [], [
|
|
83
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
88
|
-
onSubmit: (
|
|
89
|
-
if (
|
|
90
|
-
|
|
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
|
-
|
|
94
|
-
relationshipId:
|
|
95
|
-
status:
|
|
96
|
-
currency:
|
|
97
|
-
...
|
|
98
|
-
...
|
|
99
|
-
...
|
|
100
|
-
...
|
|
101
|
-
...
|
|
102
|
-
...
|
|
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) =>
|
|
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
|
-
|
|
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:
|
|
88
|
+
children: D
|
|
113
89
|
}),
|
|
114
|
-
/* @__PURE__ */
|
|
90
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ F("label", {
|
|
115
91
|
htmlFor: "inv-relationship",
|
|
116
92
|
className: z,
|
|
117
|
-
children: [
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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:
|
|
124
|
-
onChange: (e) =>
|
|
103
|
+
value: i,
|
|
104
|
+
onChange: (e) => a(e.target.value),
|
|
125
105
|
className: R,
|
|
126
106
|
required: !0,
|
|
127
|
-
children: [/* @__PURE__ */
|
|
107
|
+
children: [/* @__PURE__ */ P("option", {
|
|
128
108
|
value: "",
|
|
129
|
-
children: "— Select a relationship —"
|
|
130
|
-
}),
|
|
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__ */
|
|
115
|
+
/* @__PURE__ */ F("div", {
|
|
136
116
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
|
|
137
117
|
children: [
|
|
138
|
-
/* @__PURE__ */
|
|
118
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
139
119
|
htmlFor: "inv-number",
|
|
140
120
|
className: z,
|
|
141
|
-
children: "Number"
|
|
142
|
-
}), /* @__PURE__ */
|
|
121
|
+
children: t("invoices.createModal.numberLabel", "Number")
|
|
122
|
+
}), /* @__PURE__ */ P("input", {
|
|
143
123
|
id: "inv-number",
|
|
144
124
|
type: "text",
|
|
145
|
-
value:
|
|
146
|
-
onChange: (e) =>
|
|
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__ */
|
|
130
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
151
131
|
htmlFor: "inv-status",
|
|
152
132
|
className: z,
|
|
153
|
-
children: "Status"
|
|
154
|
-
}), /* @__PURE__ */
|
|
133
|
+
children: t("invoices.createModal.statusLabel", "Status")
|
|
134
|
+
}), /* @__PURE__ */ P("select", {
|
|
155
135
|
id: "inv-status",
|
|
156
|
-
value:
|
|
157
|
-
onChange: (e) =>
|
|
136
|
+
value: c,
|
|
137
|
+
onChange: (e) => u(e.target.value),
|
|
158
138
|
className: R,
|
|
159
|
-
children: V.map((e) => /* @__PURE__ */
|
|
139
|
+
children: V.map((e) => /* @__PURE__ */ P("option", {
|
|
160
140
|
value: e,
|
|
161
|
-
children: e
|
|
141
|
+
children: t(B[e], e)
|
|
162
142
|
}, e))
|
|
163
143
|
})] }),
|
|
164
|
-
/* @__PURE__ */
|
|
144
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
165
145
|
htmlFor: "inv-currency",
|
|
166
146
|
className: z,
|
|
167
|
-
children: "Currency"
|
|
168
|
-
}), /* @__PURE__ */
|
|
147
|
+
children: t("invoices.createModal.currencyLabel", "Currency")
|
|
148
|
+
}), /* @__PURE__ */ P("input", {
|
|
169
149
|
id: "inv-currency",
|
|
170
150
|
type: "text",
|
|
171
|
-
value:
|
|
172
|
-
onChange: (e) =>
|
|
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__ */
|
|
158
|
+
/* @__PURE__ */ F("div", {
|
|
179
159
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
|
|
180
160
|
children: [
|
|
181
|
-
/* @__PURE__ */
|
|
161
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
182
162
|
htmlFor: "inv-subtotal",
|
|
183
163
|
className: z,
|
|
184
|
-
children: "Subtotal"
|
|
185
|
-
}), /* @__PURE__ */
|
|
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:
|
|
191
|
-
onChange: (e) =>
|
|
170
|
+
value: p,
|
|
171
|
+
onChange: (e) => m(e.target.value),
|
|
192
172
|
className: R
|
|
193
173
|
})] }),
|
|
194
|
-
/* @__PURE__ */
|
|
174
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
195
175
|
htmlFor: "inv-tax",
|
|
196
176
|
className: z,
|
|
197
|
-
children: "Tax"
|
|
198
|
-
}), /* @__PURE__ */
|
|
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:
|
|
204
|
-
onChange: (e) =>
|
|
183
|
+
value: h,
|
|
184
|
+
onChange: (e) => _(e.target.value),
|
|
205
185
|
className: R
|
|
206
186
|
})] }),
|
|
207
|
-
/* @__PURE__ */
|
|
187
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
208
188
|
htmlFor: "inv-total",
|
|
209
189
|
className: z,
|
|
210
|
-
children: "Total"
|
|
211
|
-
}), /* @__PURE__ */
|
|
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) =>
|
|
196
|
+
value: v,
|
|
197
|
+
onChange: (e) => y(e.target.value),
|
|
218
198
|
className: R
|
|
219
199
|
})] })
|
|
220
200
|
]
|
|
221
201
|
}),
|
|
222
|
-
/* @__PURE__ */
|
|
202
|
+
/* @__PURE__ */ F("div", {
|
|
223
203
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
224
|
-
children: [/* @__PURE__ */
|
|
204
|
+
children: [/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
225
205
|
htmlFor: "inv-issue",
|
|
226
206
|
className: z,
|
|
227
|
-
children: "Issue date"
|
|
228
|
-
}), /* @__PURE__ */
|
|
207
|
+
children: t("invoices.createModal.issueDateLabel", "Issue date")
|
|
208
|
+
}), /* @__PURE__ */ P("input", {
|
|
229
209
|
id: "inv-issue",
|
|
230
210
|
type: "date",
|
|
231
|
-
value:
|
|
232
|
-
onChange: (e) =>
|
|
211
|
+
value: b,
|
|
212
|
+
onChange: (e) => S(e.target.value),
|
|
233
213
|
className: R
|
|
234
|
-
})] }), /* @__PURE__ */
|
|
214
|
+
})] }), /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
235
215
|
htmlFor: "inv-due",
|
|
236
216
|
className: z,
|
|
237
|
-
children: "Due date"
|
|
238
|
-
}), /* @__PURE__ */
|
|
217
|
+
children: t("invoices.createModal.dueDateLabel", "Due date")
|
|
218
|
+
}), /* @__PURE__ */ P("input", {
|
|
239
219
|
id: "inv-due",
|
|
240
220
|
type: "date",
|
|
241
|
-
value:
|
|
242
|
-
onChange: (e) =>
|
|
221
|
+
value: w,
|
|
222
|
+
onChange: (e) => E(e.target.value),
|
|
243
223
|
className: R
|
|
244
224
|
})] })]
|
|
245
225
|
}),
|
|
246
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ F("div", {
|
|
247
227
|
className: "flex justify-end gap-3",
|
|
248
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
232
|
+
children: t("invoices.createModal.cancel", "Cancel")
|
|
233
|
+
}), /* @__PURE__ */ P("button", {
|
|
254
234
|
type: "submit",
|
|
255
|
-
disabled:
|
|
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:
|
|
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 =
|
|
266
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
272
|
-
onSubmit: (
|
|
273
|
-
if (
|
|
274
|
-
|
|
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
|
-
|
|
278
|
-
label:
|
|
279
|
-
type:
|
|
280
|
-
isDefault:
|
|
281
|
-
...
|
|
282
|
-
...
|
|
283
|
-
...
|
|
284
|
-
...
|
|
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) =>
|
|
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
|
-
|
|
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:
|
|
274
|
+
children: b
|
|
295
275
|
}),
|
|
296
|
-
/* @__PURE__ */
|
|
276
|
+
/* @__PURE__ */ F("div", {
|
|
297
277
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
298
|
-
children: [/* @__PURE__ */
|
|
278
|
+
children: [/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ F("label", {
|
|
299
279
|
htmlFor: "pm-label",
|
|
300
280
|
className: z,
|
|
301
|
-
children: [
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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:
|
|
309
|
-
onChange: (e) =>
|
|
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__ */
|
|
297
|
+
})] }), /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
314
298
|
htmlFor: "pm-type",
|
|
315
299
|
className: z,
|
|
316
|
-
children: "Type"
|
|
317
|
-
}), /* @__PURE__ */
|
|
300
|
+
children: t("invoices.addPaymentMethodModal.typeLabel", "Type")
|
|
301
|
+
}), /* @__PURE__ */ P("select", {
|
|
318
302
|
id: "pm-type",
|
|
319
|
-
value:
|
|
320
|
-
onChange: (e) =>
|
|
303
|
+
value: a,
|
|
304
|
+
onChange: (e) => s(e.target.value),
|
|
321
305
|
className: R,
|
|
322
|
-
children: H.map((e) => /* @__PURE__ */
|
|
306
|
+
children: H.map((e) => /* @__PURE__ */ P("option", {
|
|
323
307
|
value: e,
|
|
324
|
-
children: e
|
|
308
|
+
children: o(e)
|
|
325
309
|
}, e))
|
|
326
310
|
})] })]
|
|
327
311
|
}),
|
|
328
|
-
/* @__PURE__ */
|
|
312
|
+
/* @__PURE__ */ F("div", {
|
|
329
313
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
|
|
330
314
|
children: [
|
|
331
|
-
/* @__PURE__ */
|
|
315
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
332
316
|
htmlFor: "pm-brand",
|
|
333
317
|
className: z,
|
|
334
|
-
children: "Brand"
|
|
335
|
-
}), /* @__PURE__ */
|
|
318
|
+
children: t("invoices.addPaymentMethodModal.brandLabel", "Brand")
|
|
319
|
+
}), /* @__PURE__ */ P("input", {
|
|
336
320
|
id: "pm-brand",
|
|
337
321
|
type: "text",
|
|
338
|
-
value:
|
|
339
|
-
onChange: (e) =>
|
|
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__ */
|
|
327
|
+
/* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
344
328
|
htmlFor: "pm-last4",
|
|
345
329
|
className: z,
|
|
346
|
-
children: "Last 4"
|
|
347
|
-
}), /* @__PURE__ */
|
|
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:
|
|
353
|
-
onChange: (e) =>
|
|
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__ */
|
|
341
|
+
/* @__PURE__ */ F("div", {
|
|
358
342
|
className: "grid grid-cols-2 gap-2",
|
|
359
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
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:
|
|
369
|
-
onChange: (e) =>
|
|
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__ */
|
|
356
|
+
})] }), /* @__PURE__ */ F("div", { children: [/* @__PURE__ */ P("label", {
|
|
373
357
|
htmlFor: "pm-exp-year",
|
|
374
358
|
className: z,
|
|
375
|
-
children: "Exp. yr."
|
|
376
|
-
}), /* @__PURE__ */
|
|
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:
|
|
382
|
-
onChange: (e) =>
|
|
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__ */
|
|
373
|
+
/* @__PURE__ */ F("label", {
|
|
390
374
|
className: "flex items-center gap-2 text-sm text-text-primary",
|
|
391
|
-
children: [/* @__PURE__ */
|
|
375
|
+
children: [/* @__PURE__ */ P("input", {
|
|
392
376
|
type: "checkbox",
|
|
393
|
-
checked:
|
|
394
|
-
onChange: (e) =>
|
|
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__ */
|
|
382
|
+
/* @__PURE__ */ F("div", {
|
|
399
383
|
className: "flex justify-end gap-3",
|
|
400
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
388
|
+
children: t("invoices.addPaymentMethodModal.cancel", "Cancel")
|
|
389
|
+
}), /* @__PURE__ */ P("button", {
|
|
406
390
|
type: "submit",
|
|
407
|
-
disabled:
|
|
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:
|
|
393
|
+
children: n.isPending ? t("invoices.addPaymentMethodModal.adding", "Adding…") : t("invoices.addPaymentMethodModal.submit", "Add payment method")
|
|
410
394
|
})]
|
|
411
395
|
})
|
|
412
396
|
]
|
|
@@ -414,177 +398,191 @@ function K({ onClose: e }) {
|
|
|
414
398
|
});
|
|
415
399
|
}
|
|
416
400
|
function q() {
|
|
417
|
-
let { data:
|
|
418
|
-
return /* @__PURE__ */
|
|
419
|
-
title: "Payment methods",
|
|
420
|
-
description: "Which external cards and accounts pay for your subscriptions",
|
|
421
|
-
action: /* @__PURE__ */
|
|
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: () =>
|
|
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: [
|
|
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: [
|
|
428
|
-
message: "Could not load payment methods.",
|
|
429
|
-
onRetry: () => void
|
|
430
|
-
}) :
|
|
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__ */
|
|
433
|
-
title: "No payment methods",
|
|
434
|
-
description: "Annotate which card or account pays for each subscription. No full card numbers are stored."
|
|
435
|
-
}) : /* @__PURE__ */
|
|
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:
|
|
438
|
-
let
|
|
439
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
430
|
+
children: [/* @__PURE__ */ F("div", {
|
|
443
431
|
className: "flex items-start justify-between gap-2",
|
|
444
|
-
children: [/* @__PURE__ */
|
|
432
|
+
children: [/* @__PURE__ */ F("div", {
|
|
445
433
|
className: "flex items-center gap-3",
|
|
446
|
-
children: [/* @__PURE__ */
|
|
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__ */
|
|
436
|
+
children: /* @__PURE__ */ P(O, {
|
|
449
437
|
className: "h-4 w-4",
|
|
450
438
|
"aria-hidden": !0
|
|
451
439
|
})
|
|
452
|
-
}), /* @__PURE__ */
|
|
440
|
+
}), /* @__PURE__ */ F("div", {
|
|
453
441
|
className: "min-w-0",
|
|
454
|
-
children: [/* @__PURE__ */
|
|
442
|
+
children: [/* @__PURE__ */ F("p", {
|
|
455
443
|
className: "flex items-center gap-1.5 truncate text-sm font-semibold text-text-primary",
|
|
456
|
-
children: [
|
|
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__ */
|
|
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__ */
|
|
451
|
+
}), /* @__PURE__ */ P("p", {
|
|
464
452
|
className: "font-mono text-sm tracking-[0.15em] text-text-secondary",
|
|
465
|
-
children:
|
|
453
|
+
children: t.last4 ? `•••• ${t.last4}` : o(t.type)
|
|
466
454
|
})]
|
|
467
455
|
})]
|
|
468
|
-
}), /* @__PURE__ */
|
|
469
|
-
}), /* @__PURE__ */
|
|
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__ */
|
|
459
|
+
children: [/* @__PURE__ */ P("p", {
|
|
472
460
|
className: "truncate text-xs text-text-secondary",
|
|
473
|
-
children: [
|
|
474
|
-
}), /* @__PURE__ */
|
|
461
|
+
children: [t.label, ...n].filter(Boolean).join(" · ")
|
|
462
|
+
}), /* @__PURE__ */ F("button", {
|
|
475
463
|
type: "button",
|
|
476
|
-
"aria-label":
|
|
477
|
-
disabled:
|
|
478
|
-
onClick: () =>
|
|
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__ */
|
|
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
|
-
},
|
|
474
|
+
}, t.id);
|
|
487
475
|
})
|
|
488
|
-
}),
|
|
476
|
+
}), l && /* @__PURE__ */ P(K, { onClose: () => p(!1) })]
|
|
489
477
|
});
|
|
490
478
|
}
|
|
491
479
|
function J() {
|
|
492
|
-
let { navigateTo:
|
|
493
|
-
|
|
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:
|
|
490
|
+
offset: f * L
|
|
497
491
|
}
|
|
498
|
-
}),
|
|
492
|
+
}), J = y(), Y = x({ pagination: {
|
|
499
493
|
limit: 100,
|
|
500
494
|
offset: 0
|
|
501
|
-
} }),
|
|
495
|
+
} }), X = w(() => {
|
|
502
496
|
let e = /* @__PURE__ */ new Map();
|
|
503
|
-
for (let t of
|
|
497
|
+
for (let t of Y.data?.items ?? []) e.set(t.id, t.label);
|
|
504
498
|
return e;
|
|
505
|
-
}, [
|
|
506
|
-
let e =
|
|
507
|
-
for (let e of
|
|
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);
|
|
508
502
|
let r = Array.from(n.entries()).sort((e, t) => t[1] - e[1]).map(([e, t], n) => ({
|
|
509
|
-
label: e.charAt(0) + e.slice(1).toLowerCase(),
|
|
503
|
+
label: o(B[e], e.charAt(0) + e.slice(1).toLowerCase()),
|
|
510
504
|
value: t,
|
|
511
|
-
color: W[e] ??
|
|
505
|
+
color: W[e] ?? p[n % p.length]
|
|
512
506
|
}));
|
|
513
507
|
return {
|
|
514
508
|
outstandingCount: e.length,
|
|
515
509
|
outstandingTotal: e.reduce((e, t) => e + t.total, 0),
|
|
516
|
-
paidCount:
|
|
517
|
-
overdueCount:
|
|
510
|
+
paidCount: Z.filter((e) => e.status === "PAID").length,
|
|
511
|
+
overdueCount: Z.filter((e) => e.status === "OVERDUE").length,
|
|
518
512
|
distribution: r,
|
|
519
513
|
currency: t
|
|
520
514
|
};
|
|
521
|
-
}, [
|
|
522
|
-
return /* @__PURE__ */
|
|
523
|
-
title: "Invoices",
|
|
524
|
-
description: "Your billing ledger across every relationship",
|
|
525
|
-
actions: /* @__PURE__ */
|
|
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", {
|
|
526
520
|
type: "button",
|
|
527
|
-
onClick: () =>
|
|
521
|
+
onClick: () => O(!0),
|
|
528
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",
|
|
529
|
-
children: [
|
|
523
|
+
children: [
|
|
524
|
+
/* @__PURE__ */ P(k, { className: "h-4 w-4" }),
|
|
525
|
+
" ",
|
|
526
|
+
o("invoices.create", "Create invoice")
|
|
527
|
+
]
|
|
530
528
|
}),
|
|
531
529
|
children: [
|
|
532
|
-
/* @__PURE__ */
|
|
530
|
+
/* @__PURE__ */ P(te, {
|
|
533
531
|
className: "mb-4",
|
|
534
|
-
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.")
|
|
535
533
|
}),
|
|
536
|
-
!
|
|
534
|
+
!R && !z && Z.length > 0 && /* @__PURE__ */ F("div", {
|
|
537
535
|
className: "grid grid-cols-1 gap-4 lg:grid-cols-3",
|
|
538
|
-
children: [/* @__PURE__ */
|
|
536
|
+
children: [/* @__PURE__ */ F("div", {
|
|
539
537
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:col-span-2",
|
|
540
538
|
children: [
|
|
541
|
-
/* @__PURE__ */
|
|
539
|
+
/* @__PURE__ */ P(r, {
|
|
542
540
|
featured: !0,
|
|
543
|
-
icon: /* @__PURE__ */
|
|
544
|
-
value: i(
|
|
545
|
-
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")
|
|
546
544
|
}),
|
|
547
|
-
/* @__PURE__ */
|
|
548
|
-
icon: /* @__PURE__ */
|
|
549
|
-
value:
|
|
550
|
-
label: "Open invoices"
|
|
545
|
+
/* @__PURE__ */ P(r, {
|
|
546
|
+
icon: /* @__PURE__ */ P(ee, {}),
|
|
547
|
+
value: $.outstandingCount,
|
|
548
|
+
label: o("invoices.metrics.openInvoices", "Open invoices")
|
|
551
549
|
}),
|
|
552
|
-
/* @__PURE__ */
|
|
553
|
-
icon: /* @__PURE__ */
|
|
554
|
-
value:
|
|
555
|
-
label: "Overdue",
|
|
556
|
-
|
|
550
|
+
/* @__PURE__ */ P(r, {
|
|
551
|
+
icon: /* @__PURE__ */ P(E, {}),
|
|
552
|
+
value: $.overdueCount,
|
|
553
|
+
label: o("invoices.metrics.overdue", "Overdue"),
|
|
554
|
+
...$.overdueCount > 0 ? { trend: "down" } : {}
|
|
557
555
|
}),
|
|
558
|
-
/* @__PURE__ */
|
|
559
|
-
icon: /* @__PURE__ */
|
|
560
|
-
value:
|
|
561
|
-
label: "Paid",
|
|
562
|
-
|
|
556
|
+
/* @__PURE__ */ P(r, {
|
|
557
|
+
icon: /* @__PURE__ */ P(D, {}),
|
|
558
|
+
value: $.paidCount,
|
|
559
|
+
label: o("invoices.metrics.paid", "Paid"),
|
|
560
|
+
...$.paidCount > 0 ? { trend: "up" } : {}
|
|
563
561
|
})
|
|
564
562
|
]
|
|
565
|
-
}), /* @__PURE__ */
|
|
563
|
+
}), /* @__PURE__ */ F(I, {
|
|
566
564
|
treatment: "insight",
|
|
567
565
|
className: "p-6",
|
|
568
566
|
children: [
|
|
569
|
-
/* @__PURE__ */
|
|
567
|
+
/* @__PURE__ */ P("p", {
|
|
570
568
|
className: "text-sm font-semibold text-text-primary",
|
|
571
|
-
children: "Status breakdown"
|
|
569
|
+
children: o("invoices.metrics.statusBreakdown", "Status breakdown")
|
|
572
570
|
}),
|
|
573
|
-
/* @__PURE__ */
|
|
571
|
+
/* @__PURE__ */ P("p", {
|
|
574
572
|
className: "text-xs text-text-secondary",
|
|
575
|
-
children: "Across the invoices on this page"
|
|
573
|
+
children: o("invoices.metrics.statusBreakdownHint", "Across the invoices on this page")
|
|
576
574
|
}),
|
|
577
|
-
/* @__PURE__ */
|
|
575
|
+
/* @__PURE__ */ F("div", {
|
|
578
576
|
className: "mt-4 flex flex-col items-center gap-5 sm:flex-row sm:items-center lg:flex-col xl:flex-row",
|
|
579
|
-
children: [/* @__PURE__ */
|
|
580
|
-
data:
|
|
577
|
+
children: [/* @__PURE__ */ P(m, {
|
|
578
|
+
data: $.distribution,
|
|
581
579
|
size: 132,
|
|
582
580
|
thickness: 16,
|
|
583
|
-
centerLabel: String(
|
|
584
|
-
centerSub: "invoices",
|
|
581
|
+
centerLabel: String(Z.length),
|
|
582
|
+
centerSub: o("invoices.metrics.invoices", "invoices"),
|
|
585
583
|
className: "shrink-0"
|
|
586
|
-
}), /* @__PURE__ */
|
|
587
|
-
data:
|
|
584
|
+
}), /* @__PURE__ */ P(h, {
|
|
585
|
+
data: $.distribution,
|
|
588
586
|
className: "w-full min-w-0 flex-1",
|
|
589
587
|
valueFormat: (e) => String(e)
|
|
590
588
|
})]
|
|
@@ -592,104 +590,104 @@ function J() {
|
|
|
592
590
|
]
|
|
593
591
|
})]
|
|
594
592
|
}),
|
|
595
|
-
/* @__PURE__ */
|
|
593
|
+
/* @__PURE__ */ P("div", {
|
|
596
594
|
className: "mt-6 flex flex-wrap items-center gap-3",
|
|
597
|
-
children: /* @__PURE__ */
|
|
598
|
-
"aria-label": "Filter by status",
|
|
599
|
-
value:
|
|
595
|
+
children: /* @__PURE__ */ P("select", {
|
|
596
|
+
"aria-label": o("invoices.filters.statusLabel", "Filter by status"),
|
|
597
|
+
value: _,
|
|
600
598
|
onChange: (e) => {
|
|
601
|
-
|
|
599
|
+
b(e.target.value), g(0);
|
|
602
600
|
},
|
|
603
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)]",
|
|
604
|
-
children:
|
|
602
|
+
children: j.map((e) => /* @__PURE__ */ P("option", {
|
|
605
603
|
value: e.value,
|
|
606
604
|
children: e.label
|
|
607
605
|
}, e.value))
|
|
608
606
|
})
|
|
609
607
|
}),
|
|
610
|
-
|
|
611
|
-
message: "Could not load invoices.",
|
|
612
|
-
onRetry: () => void
|
|
613
|
-
}) :
|
|
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", {
|
|
614
612
|
className: "mt-6",
|
|
615
|
-
children: /* @__PURE__ */
|
|
613
|
+
children: /* @__PURE__ */ P(c, {
|
|
616
614
|
illustration: "empty-data",
|
|
617
|
-
icon: /* @__PURE__ */
|
|
618
|
-
title: "No invoices",
|
|
619
|
-
description:
|
|
620
|
-
action: /* @__PURE__ */
|
|
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", {
|
|
621
619
|
type: "button",
|
|
622
|
-
onClick: () =>
|
|
620
|
+
onClick: () => O(!0),
|
|
623
621
|
className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:opacity-90",
|
|
624
|
-
children: "Create invoice"
|
|
622
|
+
children: o("invoices.create", "Create invoice")
|
|
625
623
|
})
|
|
626
624
|
})
|
|
627
|
-
}) : /* @__PURE__ */
|
|
625
|
+
}) : /* @__PURE__ */ F(N, { children: [/* @__PURE__ */ F("div", {
|
|
628
626
|
className: "mt-6 overflow-hidden rounded-lg border border-border-subtle bg-bg-surface",
|
|
629
|
-
children: [/* @__PURE__ */
|
|
627
|
+
children: [/* @__PURE__ */ F("div", {
|
|
630
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",
|
|
631
629
|
children: [
|
|
632
|
-
/* @__PURE__ */
|
|
633
|
-
/* @__PURE__ */
|
|
634
|
-
/* @__PURE__ */
|
|
635
|
-
/* @__PURE__ */
|
|
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", {
|
|
636
634
|
className: "text-right",
|
|
637
|
-
children: "Total"
|
|
635
|
+
children: o("invoices.table.total", "Total")
|
|
638
636
|
}),
|
|
639
|
-
/* @__PURE__ */
|
|
637
|
+
/* @__PURE__ */ P("span", {
|
|
640
638
|
className: "text-right",
|
|
641
|
-
children: "Due"
|
|
639
|
+
children: o("invoices.table.due", "Due")
|
|
642
640
|
}),
|
|
643
|
-
/* @__PURE__ */
|
|
641
|
+
/* @__PURE__ */ P("span", {
|
|
644
642
|
className: "text-right",
|
|
645
|
-
children: "Action"
|
|
643
|
+
children: o("invoices.table.action", "Action")
|
|
646
644
|
})
|
|
647
645
|
]
|
|
648
|
-
}), /* @__PURE__ */
|
|
646
|
+
}), /* @__PURE__ */ P("div", {
|
|
649
647
|
className: "divide-y divide-border-subtle",
|
|
650
|
-
children:
|
|
648
|
+
children: Z.map((e) => /* @__PURE__ */ F("div", {
|
|
651
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",
|
|
652
650
|
children: [
|
|
653
|
-
/* @__PURE__ */
|
|
651
|
+
/* @__PURE__ */ F("button", {
|
|
654
652
|
type: "button",
|
|
655
|
-
onClick: () =>
|
|
653
|
+
onClick: () => l(`/relationships/${e.relationshipId}`),
|
|
656
654
|
className: "min-w-0 text-left",
|
|
657
|
-
children: [/* @__PURE__ */
|
|
655
|
+
children: [/* @__PURE__ */ P("p", {
|
|
658
656
|
className: "truncate text-sm font-medium text-text-primary",
|
|
659
|
-
children: e.number ||
|
|
660
|
-
}), /* @__PURE__ */
|
|
657
|
+
children: e.number || `${o("invoices.table.invoice", "Invoice")} ${e.id.slice(0, 8)}`
|
|
658
|
+
}), /* @__PURE__ */ P("p", {
|
|
661
659
|
className: "text-xs text-text-secondary",
|
|
662
|
-
children: e.issueDate ?
|
|
660
|
+
children: e.issueDate ? o("invoices.table.issued", "Issued {{date}}", { date: a(e.issueDate) }) : "—"
|
|
663
661
|
})]
|
|
664
662
|
}),
|
|
665
|
-
/* @__PURE__ */
|
|
663
|
+
/* @__PURE__ */ P("span", {
|
|
666
664
|
className: "min-w-0 truncate text-sm text-text-secondary",
|
|
667
|
-
children:
|
|
665
|
+
children: X.get(e.relationshipId) ?? "—"
|
|
668
666
|
}),
|
|
669
|
-
/* @__PURE__ */
|
|
670
|
-
/* @__PURE__ */
|
|
667
|
+
/* @__PURE__ */ P("span", { children: /* @__PURE__ */ P(s, { status: e.status }) }),
|
|
668
|
+
/* @__PURE__ */ P("span", {
|
|
671
669
|
className: "text-sm font-semibold tabular-nums text-text-primary sm:text-right",
|
|
672
670
|
children: i(e.total, e.currency)
|
|
673
671
|
}),
|
|
674
|
-
/* @__PURE__ */
|
|
672
|
+
/* @__PURE__ */ P("span", {
|
|
675
673
|
className: "text-xs text-text-secondary sm:text-right",
|
|
676
674
|
children: e.dueDate ? a(e.dueDate) : "—"
|
|
677
675
|
}),
|
|
678
|
-
/* @__PURE__ */
|
|
676
|
+
/* @__PURE__ */ P("span", {
|
|
679
677
|
className: "sm:text-right",
|
|
680
|
-
children: U.has(e.status) ? /* @__PURE__ */
|
|
678
|
+
children: U.has(e.status) ? /* @__PURE__ */ F("button", {
|
|
681
679
|
type: "button",
|
|
682
|
-
disabled:
|
|
683
|
-
onClick: () =>
|
|
680
|
+
disabled: J.isPending,
|
|
681
|
+
onClick: () => J.mutate(e.id),
|
|
684
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",
|
|
685
|
-
children: [/* @__PURE__ */
|
|
683
|
+
children: [/* @__PURE__ */ P(D, {
|
|
686
684
|
className: "h-3.5 w-3.5",
|
|
687
685
|
"aria-hidden": !0
|
|
688
|
-
}), "Mark paid"]
|
|
686
|
+
}), o("invoices.table.markPaid", "Mark paid")]
|
|
689
687
|
}) : e.paidAt ? /* @__PURE__ */ P("span", {
|
|
690
688
|
className: "text-xs text-text-secondary",
|
|
691
|
-
children:
|
|
692
|
-
}) : /* @__PURE__ */
|
|
689
|
+
children: o("invoices.table.paidAt", "Paid {{date}}", { date: a(e.paidAt) })
|
|
690
|
+
}) : /* @__PURE__ */ P("span", {
|
|
693
691
|
className: "text-xs text-text-secondary",
|
|
694
692
|
children: "—"
|
|
695
693
|
})
|
|
@@ -697,34 +695,30 @@ function J() {
|
|
|
697
695
|
]
|
|
698
696
|
}, e.id))
|
|
699
697
|
})]
|
|
700
|
-
}), /* @__PURE__ */
|
|
698
|
+
}), /* @__PURE__ */ F("div", {
|
|
701
699
|
className: "mt-4 flex items-center justify-between",
|
|
702
|
-
children: [/* @__PURE__ */
|
|
700
|
+
children: [/* @__PURE__ */ F("p", {
|
|
703
701
|
className: "text-xs text-text-secondary",
|
|
704
|
-
children: [
|
|
705
|
-
|
|
706
|
-
d + 1,
|
|
707
|
-
V ? " · refreshing…" : ""
|
|
708
|
-
]
|
|
709
|
-
}), /* @__PURE__ */ P("div", {
|
|
702
|
+
children: [o("invoices.pagination.page", "Page {{page}}", { page: f + 1 }), K ? ` · ${o("invoices.pagination.refreshing", "refreshing…")}` : ""]
|
|
703
|
+
}), /* @__PURE__ */ F("div", {
|
|
710
704
|
className: "flex gap-2",
|
|
711
|
-
children: [/* @__PURE__ */
|
|
705
|
+
children: [/* @__PURE__ */ P("button", {
|
|
712
706
|
type: "button",
|
|
713
|
-
disabled:
|
|
714
|
-
onClick: () =>
|
|
715
|
-
className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium",
|
|
716
|
-
children: "Previous"
|
|
717
|
-
}), /* @__PURE__ */
|
|
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", {
|
|
718
712
|
type: "button",
|
|
719
|
-
disabled: !
|
|
720
|
-
onClick: () =>
|
|
721
|
-
className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium",
|
|
722
|
-
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")
|
|
723
717
|
})]
|
|
724
718
|
})]
|
|
725
719
|
})] }),
|
|
726
|
-
/* @__PURE__ */
|
|
727
|
-
|
|
720
|
+
/* @__PURE__ */ P(q, {}),
|
|
721
|
+
S && /* @__PURE__ */ P(G, { onClose: () => O(!1) })
|
|
728
722
|
]
|
|
729
723
|
});
|
|
730
724
|
}
|