@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.
- 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/components/viz.js +51 -27
- package/dist/subscriberbot/components/viz.js.map +1 -1
- package/dist/subscriberbot/hooks/index.d.ts +2 -1
- package/dist/subscriberbot/hooks/index.d.ts.map +1 -1
- package/dist/subscriberbot/hooks/index.js +1 -0
- package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts +12 -1
- package/dist/subscriberbot/hooks/useSubscriberBotApi.d.ts.map +1 -1
- package/dist/subscriberbot/hooks/useSubscriberBotApi.js +82 -56
- package/dist/subscriberbot/hooks/useSubscriberBotApi.js.map +1 -1
- 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 +155 -97
- 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 +3 -2
- package/dist/subscriberbot/pages/InvoicesPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/InvoicesPage.js +368 -362
- 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 +3 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/agents/AgentDetailPage.js +296 -228
- 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 +4 -2
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.d.ts.map +1 -1
- package/dist/subscriberbot/pages/providers/ProviderDetailPage.js +577 -402
- 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/dist/subscriberbot/types/index.d.ts +37 -0
- package/dist/subscriberbot/types/index.d.ts.map +1 -1
- 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
|
|
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,170 +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
|
-
}),
|
|
499
|
-
|
|
500
|
-
|
|
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] ??
|
|
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:
|
|
510
|
-
overdueCount:
|
|
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
|
-
}, [
|
|
515
|
-
return /* @__PURE__ */
|
|
516
|
-
title: "Invoices",
|
|
517
|
-
description: "Your billing ledger across every relationship",
|
|
518
|
-
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", {
|
|
519
520
|
type: "button",
|
|
520
|
-
onClick: () =>
|
|
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: [
|
|
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__ */
|
|
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
|
-
!
|
|
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__ */
|
|
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__ */
|
|
539
|
+
/* @__PURE__ */ P(r, {
|
|
535
540
|
featured: !0,
|
|
536
|
-
icon: /* @__PURE__ */
|
|
537
|
-
value: i(
|
|
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__ */
|
|
541
|
-
icon: /* @__PURE__ */
|
|
542
|
-
value:
|
|
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__ */
|
|
546
|
-
icon: /* @__PURE__ */
|
|
547
|
-
value:
|
|
548
|
-
label: "Overdue",
|
|
549
|
-
|
|
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__ */
|
|
552
|
-
icon: /* @__PURE__ */
|
|
553
|
-
value:
|
|
554
|
-
label: "Paid",
|
|
555
|
-
|
|
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__ */
|
|
563
|
+
}), /* @__PURE__ */ F(I, {
|
|
559
564
|
treatment: "insight",
|
|
560
565
|
className: "p-6",
|
|
561
566
|
children: [
|
|
562
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
573
|
-
data:
|
|
577
|
+
children: [/* @__PURE__ */ P(m, {
|
|
578
|
+
data: $.distribution,
|
|
574
579
|
size: 132,
|
|
575
580
|
thickness: 16,
|
|
576
|
-
centerLabel: String(
|
|
577
|
-
centerSub: "invoices",
|
|
581
|
+
centerLabel: String(Z.length),
|
|
582
|
+
centerSub: o("invoices.metrics.invoices", "invoices"),
|
|
578
583
|
className: "shrink-0"
|
|
579
|
-
}), /* @__PURE__ */
|
|
580
|
-
data:
|
|
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__ */
|
|
593
|
+
/* @__PURE__ */ P("div", {
|
|
589
594
|
className: "mt-6 flex flex-wrap items-center gap-3",
|
|
590
|
-
children: /* @__PURE__ */
|
|
591
|
-
"aria-label": "Filter by status",
|
|
592
|
-
value:
|
|
595
|
+
children: /* @__PURE__ */ P("select", {
|
|
596
|
+
"aria-label": o("invoices.filters.statusLabel", "Filter by status"),
|
|
597
|
+
value: _,
|
|
593
598
|
onChange: (e) => {
|
|
594
|
-
|
|
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:
|
|
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
|
-
|
|
604
|
-
message: "Could not load invoices.",
|
|
605
|
-
onRetry: () => void
|
|
606
|
-
}) :
|
|
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__ */
|
|
613
|
+
children: /* @__PURE__ */ P(c, {
|
|
609
614
|
illustration: "empty-data",
|
|
610
|
-
icon: /* @__PURE__ */
|
|
611
|
-
title: "No invoices",
|
|
612
|
-
description:
|
|
613
|
-
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", {
|
|
614
619
|
type: "button",
|
|
615
|
-
onClick: () =>
|
|
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__ */
|
|
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__ */
|
|
623
|
-
className: "hidden grid-cols-[1.
|
|
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__ */
|
|
626
|
-
/* @__PURE__ */
|
|
627
|
-
/* @__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", {
|
|
628
634
|
className: "text-right",
|
|
629
|
-
children: "Total"
|
|
635
|
+
children: o("invoices.table.total", "Total")
|
|
630
636
|
}),
|
|
631
|
-
/* @__PURE__ */
|
|
637
|
+
/* @__PURE__ */ P("span", {
|
|
632
638
|
className: "text-right",
|
|
633
|
-
children: "Due"
|
|
639
|
+
children: o("invoices.table.due", "Due")
|
|
634
640
|
}),
|
|
635
|
-
/* @__PURE__ */
|
|
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__ */
|
|
646
|
+
}), /* @__PURE__ */ P("div", {
|
|
641
647
|
className: "divide-y divide-border-subtle",
|
|
642
|
-
children:
|
|
643
|
-
className: "grid grid-cols-1 gap-2 px-4 py-3 transition-colors hover:bg-bg-sunken/50 sm:grid-cols-[1.
|
|
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__ */
|
|
651
|
+
/* @__PURE__ */ F("button", {
|
|
646
652
|
type: "button",
|
|
647
|
-
onClick: () =>
|
|
653
|
+
onClick: () => l(`/relationships/${e.relationshipId}`),
|
|
648
654
|
className: "min-w-0 text-left",
|
|
649
|
-
children: [/* @__PURE__ */
|
|
655
|
+
children: [/* @__PURE__ */ P("p", {
|
|
650
656
|
className: "truncate text-sm font-medium text-text-primary",
|
|
651
|
-
children: e.number ||
|
|
652
|
-
}), /* @__PURE__ */
|
|
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 ?
|
|
660
|
+
children: e.issueDate ? o("invoices.table.issued", "Issued {{date}}", { date: a(e.issueDate) }) : "—"
|
|
655
661
|
})]
|
|
656
662
|
}),
|
|
657
|
-
/* @__PURE__ */
|
|
658
|
-
|
|
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__ */
|
|
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__ */
|
|
676
|
+
/* @__PURE__ */ P("span", {
|
|
667
677
|
className: "sm:text-right",
|
|
668
|
-
children: U.has(e.status) ? /* @__PURE__ */
|
|
678
|
+
children: U.has(e.status) ? /* @__PURE__ */ F("button", {
|
|
669
679
|
type: "button",
|
|
670
|
-
disabled:
|
|
671
|
-
onClick: () =>
|
|
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__ */
|
|
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:
|
|
680
|
-
}) : /* @__PURE__ */
|
|
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__ */
|
|
698
|
+
}), /* @__PURE__ */ F("div", {
|
|
689
699
|
className: "mt-4 flex items-center justify-between",
|
|
690
|
-
children: [/* @__PURE__ */
|
|
700
|
+
children: [/* @__PURE__ */ F("p", {
|
|
691
701
|
className: "text-xs text-text-secondary",
|
|
692
|
-
children: [
|
|
693
|
-
|
|
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__ */
|
|
705
|
+
children: [/* @__PURE__ */ P("button", {
|
|
700
706
|
type: "button",
|
|
701
|
-
disabled:
|
|
702
|
-
onClick: () =>
|
|
703
|
-
className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium",
|
|
704
|
-
children: "Previous"
|
|
705
|
-
}), /* @__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", {
|
|
706
712
|
type: "button",
|
|
707
|
-
disabled: !
|
|
708
|
-
onClick: () =>
|
|
709
|
-
className: t("rounded-lg border border-border-subtle px-3 py-1.5 text-xs font-medium",
|
|
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__ */
|
|
715
|
-
|
|
720
|
+
/* @__PURE__ */ P(q, {}),
|
|
721
|
+
S && /* @__PURE__ */ P(G, { onClose: () => O(!1) })
|
|
716
722
|
]
|
|
717
723
|
});
|
|
718
724
|
}
|