@burdenoff/microfe-billing 2026.601.1 → 2026.601.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,341 +1,7 @@
1
- import { formatDate as e, formatNumber as t, formatPercentage as n, formatQuotaStatus as r } from "../../../shared/utils/format.js";
2
- import { getQuotaProgressBgColor as i, getQuotaProgressColor as a, getQuotaStatusColor as o, getStatusBadgeClasses as s } from "../../../shared/utils/status.js";
3
- import { useBillingPermissions as c } from "../../../hooks/useBillingPermissions.js";
4
- import { useDefaultBillingAccount as l } from "../../subscriptions/hooks/useSubscriptions.js";
1
+ import "../../../shared/utils/format.js";
2
+ import "../../../hooks/useBillingPermissions.js";
5
3
  import "../../subscriptions/hooks/index.js";
6
- import { useBillingAccountQuotasSummary as u, useQuotaAssignmentsWithAnalytics as d } from "../hooks/useQuota.js";
7
- import { useState as f } from "react";
8
- import { jsx as p, jsxs as m } from "react/jsx-runtime";
9
- import { useI18n as h } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
10
- //#region src/billing/modules/quota/pages/QuotaPage.tsx
11
- var g = () => {
12
- let { t: e } = h(), t = (t, n) => {
13
- let r = e(t);
14
- return r === t ? n : r;
15
- }, n = c(), { billingAccount: i, isLoading: a } = l(), [o, s] = f("all"), [g, v] = f(""), [y, b] = f(1), { summary: x, isLoading: S } = u(i?.id), { quotaAssignments: C, pagination: w, isLoading: T, error: E, refetch: D } = d({
16
- billingAccountId: i?.id || "",
17
- page: y,
18
- pageSize: 10,
19
- searchQuery: g || void 0,
20
- status: o === "all" ? void 0 : [o]
21
- });
22
- if (!n.canViewUsage) return /* @__PURE__ */ p("div", {
23
- className: "flex items-center justify-center h-full min-h-[400px]",
24
- children: /* @__PURE__ */ m("div", {
25
- className: "text-center space-y-2",
26
- children: [
27
- /* @__PURE__ */ p("div", {
28
- className: "size-12 mx-auto rounded-full bg-muted flex items-center justify-center",
29
- children: /* @__PURE__ */ p("svg", {
30
- className: "size-6 text-muted-foreground",
31
- fill: "none",
32
- viewBox: "0 0 24 24",
33
- stroke: "currentColor",
34
- children: /* @__PURE__ */ p("path", {
35
- strokeLinecap: "round",
36
- strokeLinejoin: "round",
37
- strokeWidth: 2,
38
- d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z"
39
- })
40
- })
41
- }),
42
- /* @__PURE__ */ p("h2", {
43
- className: "text-lg font-semibold text-foreground",
44
- children: "Access Denied"
45
- }),
46
- /* @__PURE__ */ p("p", {
47
- className: "text-sm text-muted-foreground max-w-sm",
48
- children: "You don't have permission to view quotas."
49
- })
50
- ]
51
- })
52
- });
53
- if ((a || S || T) && !i) return /* @__PURE__ */ m("div", {
54
- className: "space-y-6 p-6",
55
- children: [/* @__PURE__ */ p("div", { className: "h-8 w-48 bg-muted animate-pulse rounded" }), /* @__PURE__ */ p("div", {
56
- className: "grid grid-cols-1 sm:grid-cols-4 gap-4",
57
- children: [
58
- 1,
59
- 2,
60
- 3,
61
- 4
62
- ].map((e) => /* @__PURE__ */ m("div", {
63
- className: "border border-border rounded-lg p-4",
64
- children: [/* @__PURE__ */ p("div", { className: "h-4 w-20 bg-muted animate-pulse rounded mb-2" }), /* @__PURE__ */ p("div", { className: "h-8 w-16 bg-muted animate-pulse rounded" })]
65
- }, e))
66
- })]
67
- });
68
- if (E) return /* @__PURE__ */ p("div", {
69
- className: "flex items-center justify-center h-full min-h-[400px]",
70
- children: /* @__PURE__ */ m("div", {
71
- className: "text-center space-y-4",
72
- children: [
73
- /* @__PURE__ */ p("div", {
74
- className: "size-12 mx-auto rounded-full bg-destructive/10 flex items-center justify-center",
75
- children: /* @__PURE__ */ p("svg", {
76
- className: "size-6 text-destructive",
77
- fill: "none",
78
- viewBox: "0 0 24 24",
79
- stroke: "currentColor",
80
- children: /* @__PURE__ */ p("path", {
81
- strokeLinecap: "round",
82
- strokeLinejoin: "round",
83
- strokeWidth: 2,
84
- d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
85
- })
86
- })
87
- }),
88
- /* @__PURE__ */ p("h2", {
89
- className: "text-lg font-semibold text-foreground",
90
- children: t("billing.quota.failedToLoad", "Failed to load quotas")
91
- }),
92
- /* @__PURE__ */ p("p", {
93
- className: "text-sm text-muted-foreground",
94
- children: E.message
95
- }),
96
- /* @__PURE__ */ p("button", {
97
- type: "button",
98
- onClick: () => D(),
99
- className: "px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors",
100
- children: "Try Again"
101
- })
102
- ]
103
- })
104
- });
105
- let O = [...x?.pooledQuotas || [], ...x?.subscriptionQuotas || []], k = O.filter((e) => e.usagePercentage < 75).length, A = O.filter((e) => e.usagePercentage >= 75 && e.usagePercentage < 90).length, j = O.filter((e) => e.usagePercentage >= 90 && e.usagePercentage < 100).length, M = O.filter((e) => e.usagePercentage >= 100).length;
106
- return /* @__PURE__ */ m("div", {
107
- className: "space-y-6 p-6",
108
- children: [
109
- /* @__PURE__ */ p("div", {
110
- className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
111
- children: /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("h1", {
112
- className: "text-2xl font-bold text-foreground",
113
- children: t("billing.quota.title", "Quotas")
114
- }), /* @__PURE__ */ p("p", {
115
- className: "text-sm text-muted-foreground mt-1",
116
- children: "Monitor your quota allocations and usage"
117
- })] })
118
- }),
119
- /* @__PURE__ */ m("div", {
120
- className: "grid grid-cols-2 sm:grid-cols-4 gap-4",
121
- children: [
122
- /* @__PURE__ */ m("div", {
123
- className: "border border-border rounded-lg bg-status-success-bg-subtle p-4",
124
- children: [/* @__PURE__ */ p("p", {
125
- className: "text-sm text-status-success-text",
126
- children: t("billing.quota.healthy", "Healthy")
127
- }), /* @__PURE__ */ p("p", {
128
- className: "text-2xl font-bold text-status-success-text mt-1",
129
- children: k
130
- })]
131
- }),
132
- /* @__PURE__ */ m("div", {
133
- className: "border border-border rounded-lg bg-status-warning-bg-subtle p-4",
134
- children: [/* @__PURE__ */ p("p", {
135
- className: "text-sm text-status-warning-text",
136
- children: "Warning"
137
- }), /* @__PURE__ */ p("p", {
138
- className: "text-2xl font-bold text-status-warning-text mt-1",
139
- children: A
140
- })]
141
- }),
142
- /* @__PURE__ */ m("div", {
143
- className: "border border-border rounded-lg bg-status-error-bg-subtle p-4",
144
- children: [/* @__PURE__ */ p("p", {
145
- className: "text-sm text-status-error-text",
146
- children: "Critical"
147
- }), /* @__PURE__ */ p("p", {
148
- className: "text-2xl font-bold text-status-error-text mt-1",
149
- children: j
150
- })]
151
- }),
152
- /* @__PURE__ */ m("div", {
153
- className: "border border-border rounded-lg bg-bg-canvas p-4",
154
- children: [/* @__PURE__ */ p("p", {
155
- className: "text-sm text-text-secondary",
156
- children: "Exhausted"
157
- }), /* @__PURE__ */ p("p", {
158
- className: "text-2xl font-bold text-text-secondary mt-1",
159
- children: M
160
- })]
161
- })
162
- ]
163
- }),
164
- /* @__PURE__ */ m("div", {
165
- className: "flex flex-wrap items-center gap-4 pb-4 border-b border-border",
166
- children: [/* @__PURE__ */ p("div", {
167
- className: "inline-flex rounded-lg border border-border p-1 bg-muted/50 flex-wrap",
168
- children: [
169
- "all",
170
- "HEALTHY",
171
- "WARNING",
172
- "CRITICAL",
173
- "EXHAUSTED"
174
- ].map((e) => /* @__PURE__ */ p("button", {
175
- type: "button",
176
- onClick: () => s(e),
177
- className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${o === e ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
178
- children: e === "all" ? "All" : r(e)
179
- }, e))
180
- }), /* @__PURE__ */ m("div", {
181
- className: "relative flex-1 min-w-0 w-full sm:max-w-md",
182
- children: [/* @__PURE__ */ p("svg", {
183
- className: "absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground",
184
- fill: "none",
185
- viewBox: "0 0 24 24",
186
- stroke: "currentColor",
187
- children: /* @__PURE__ */ p("path", {
188
- strokeLinecap: "round",
189
- strokeLinejoin: "round",
190
- strokeWidth: 2,
191
- d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
192
- })
193
- }), /* @__PURE__ */ p("input", {
194
- type: "text",
195
- placeholder: "Search quotas...",
196
- value: g,
197
- onChange: (e) => v(e.target.value),
198
- className: "w-full pl-[3.25rem] pr-4 py-2 text-sm border border-border rounded-md bg-background text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent"
199
- })]
200
- })]
201
- }),
202
- C.length === 0 ? /* @__PURE__ */ m("div", {
203
- className: "flex flex-col items-center justify-center py-12 border border-dashed border-border rounded-lg",
204
- children: [
205
- /* @__PURE__ */ p("div", {
206
- className: "size-12 rounded-full bg-muted flex items-center justify-center mb-4",
207
- children: /* @__PURE__ */ p("svg", {
208
- className: "size-6 text-muted-foreground",
209
- fill: "none",
210
- viewBox: "0 0 24 24",
211
- stroke: "currentColor",
212
- children: /* @__PURE__ */ p("path", {
213
- strokeLinecap: "round",
214
- strokeLinejoin: "round",
215
- strokeWidth: 2,
216
- d: "M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"
217
- })
218
- })
219
- }),
220
- /* @__PURE__ */ p("h3", {
221
- className: "text-lg font-medium text-foreground",
222
- children: "No quotas found"
223
- }),
224
- /* @__PURE__ */ p("p", {
225
- className: "text-sm text-muted-foreground mt-1",
226
- children: o !== "all" || g ? "No quotas match your filters." : "No quota assignments available."
227
- })
228
- ]
229
- }) : /* @__PURE__ */ m("div", {
230
- className: "space-y-4",
231
- children: [C.map((e) => /* @__PURE__ */ p(_, { quota: e }, e.id)), w.totalPages > 1 && /* @__PURE__ */ m("div", {
232
- className: "flex items-center justify-center gap-2 pt-4",
233
- children: [
234
- /* @__PURE__ */ p("button", {
235
- type: "button",
236
- onClick: () => b((e) => Math.max(1, e - 1)),
237
- disabled: y === 1,
238
- className: "px-3 py-1.5 text-sm font-medium border border-border rounded-md disabled:opacity-50",
239
- children: "Previous"
240
- }),
241
- /* @__PURE__ */ m("span", {
242
- className: "text-sm text-muted-foreground",
243
- children: [
244
- "Page ",
245
- y,
246
- " of ",
247
- w.totalPages
248
- ]
249
- }),
250
- /* @__PURE__ */ p("button", {
251
- type: "button",
252
- onClick: () => b((e) => Math.min(w.totalPages, e + 1)),
253
- disabled: y === w.totalPages,
254
- className: "px-3 py-1.5 text-sm font-medium border border-border rounded-md disabled:opacity-50",
255
- children: "Next"
256
- })
257
- ]
258
- })]
259
- })
260
- ]
261
- });
262
- }, _ = ({ quota: c }) => {
263
- let l = o(c.status), u = a(c.usagePercentage), d = i(c.usagePercentage), f = c.limits?.value || 0;
264
- return /* @__PURE__ */ m("div", {
265
- className: "border border-border rounded-lg bg-card p-6 hover:shadow-sm transition-shadow",
266
- children: [
267
- /* @__PURE__ */ m("div", {
268
- className: "flex flex-col sm:flex-row sm:items-start gap-4",
269
- children: [/* @__PURE__ */ m("div", {
270
- className: "flex-1 min-w-0",
271
- children: [/* @__PURE__ */ m("div", {
272
- className: "flex items-center gap-2 flex-wrap",
273
- children: [
274
- /* @__PURE__ */ p("h3", {
275
- className: "font-semibold text-foreground",
276
- children: c.name
277
- }),
278
- /* @__PURE__ */ p("span", {
279
- className: `px-2 py-0.5 text-xs font-medium rounded ${s(l)}`,
280
- children: r(c.status)
281
- }),
282
- /* @__PURE__ */ p("span", {
283
- className: "px-2 py-0.5 text-xs font-medium bg-muted text-muted-foreground rounded",
284
- children: c.quotaType
285
- })
286
- ]
287
- }), /* @__PURE__ */ m("p", {
288
- className: "text-sm text-muted-foreground mt-1",
289
- children: ["Expires: ", e(c.endtime, "short")]
290
- })]
291
- }), /* @__PURE__ */ m("div", {
292
- className: "text-right",
293
- children: [/* @__PURE__ */ m("p", {
294
- className: "text-2xl font-bold text-foreground",
295
- children: [
296
- t(c.currentUsageSum),
297
- " / ",
298
- f > 0 ? t(f) : "∞"
299
- ]
300
- }), /* @__PURE__ */ m("p", {
301
- className: "text-sm text-muted-foreground",
302
- children: [n(c.usagePercentage), " used"]
303
- })]
304
- })]
305
- }),
306
- /* @__PURE__ */ m("div", {
307
- className: "mt-4",
308
- children: [/* @__PURE__ */ p("div", {
309
- className: `h-2 rounded-full overflow-hidden ${d}`,
310
- children: /* @__PURE__ */ p("div", {
311
- className: `h-full transition-all duration-500 ${u}`,
312
- style: { width: `${Math.min(100, c.usagePercentage)}%` }
313
- })
314
- }), /* @__PURE__ */ m("div", {
315
- className: "flex items-center justify-between mt-2 text-xs text-muted-foreground",
316
- children: [/* @__PURE__ */ m("span", { children: [t(c.limitLeft), " remaining"] }), /* @__PURE__ */ m("span", { children: [c.totalUsageCount, " usage records"] })]
317
- })]
318
- }),
319
- c.analytics?.trends && /* @__PURE__ */ m("div", {
320
- className: "mt-4 pt-4 border-t border-border flex flex-wrap gap-4 text-sm",
321
- children: [c.analytics.trends.averageDailyUsage !== void 0 && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("span", {
322
- className: "text-muted-foreground",
323
- children: "Avg. Daily: "
324
- }), /* @__PURE__ */ p("span", {
325
- className: "font-medium text-foreground",
326
- children: t(c.analytics.trends.averageDailyUsage, 1)
327
- })] }), c.analytics.trends.growthRate !== void 0 && /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p("span", {
328
- className: "text-muted-foreground",
329
- children: "Growth: "
330
- }), /* @__PURE__ */ m("span", {
331
- className: `font-medium ${c.analytics.trends.growthRate > 0 ? "text-status-error-text" : "text-status-success-text"}`,
332
- children: [c.analytics.trends.growthRate > 0 ? "+" : "", n(c.analytics.trends.growthRate)]
333
- })] })]
334
- })
335
- ]
336
- });
337
- };
338
- //#endregion
339
- export { g as QuotaPage };
340
-
341
- //# sourceMappingURL=QuotaPage.js.map
4
+ import "../hooks/useQuota.js";
5
+ import "react";
6
+ import "react/jsx-runtime";
7
+ import "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
@@ -1,24 +1,24 @@
1
- import { CreditTransactionType as e, InvoiceStatus as t, PlanDuration as n, QuotaStatus as r, SubscriptionStatus as i } from "../types/graphql.js";
2
- import { formatCurrency as a, formatDate as o, formatDateTime as s, formatNumber as c, formatPercentage as l, formatRelativeTime as u } from "@burdenoff/fe-libs/shared/utils";
1
+ import { CreditTransactionType as e, InvoiceStatus as t, PlanDuration as n, SubscriptionStatus as r } from "../types/graphql.js";
2
+ import { formatCurrency as i, formatDate as a, formatDateTime as o, formatNumber as s, formatPercentage as c, formatRelativeTime as l } from "@burdenoff/fe-libs/shared/utils";
3
3
  //#region src/billing/shared/utils/format.ts
4
- function d(e, t = "USD", n = "en-US") {
5
- return t.toUpperCase() === "CREDITS" ? f(e) : a(e, t, n);
4
+ function u(e, t = "USD", n = "en-US") {
5
+ return t.toUpperCase() === "CREDITS" ? d(e) : i(e, t, n);
6
6
  }
7
- function f(e) {
7
+ function d(e) {
8
8
  return Number.isInteger(e) ? `${e.toLocaleString()} Credits` : `${e.toLocaleString(void 0, {
9
9
  minimumFractionDigits: 0,
10
10
  maximumFractionDigits: 2
11
11
  })} Credits`;
12
12
  }
13
- function p(e) {
13
+ function f(e) {
14
14
  return {
15
- [i.ACTIVE]: "Active",
16
- [i.CANCELED]: "Canceled",
17
- [i.EXPIRED]: "Expired",
18
- [i.UPGRADED]: "Upgraded"
15
+ [r.ACTIVE]: "Active",
16
+ [r.CANCELED]: "Canceled",
17
+ [r.EXPIRED]: "Expired",
18
+ [r.UPGRADED]: "Upgraded"
19
19
  }[e] || e;
20
20
  }
21
- function m(e) {
21
+ function p(e) {
22
22
  return {
23
23
  [t.DRAFT]: "Draft",
24
24
  [t.OPEN]: "Open",
@@ -27,28 +27,19 @@ function m(e) {
27
27
  [t.UNCOLLECTIBLE]: "Uncollectible"
28
28
  }[e] || e;
29
29
  }
30
- function h(e) {
31
- return {
32
- [r.HEALTHY]: "Healthy",
33
- [r.WARNING]: "Warning",
34
- [r.CRITICAL]: "Critical",
35
- [r.EXHAUSTED]: "Exhausted",
36
- [r.INACTIVE]: "Inactive"
37
- }[e] || e;
38
- }
39
- function g(e) {
30
+ function m(e) {
40
31
  return {
41
32
  [n.MONTHLY]: "month",
42
33
  [n.YEARLY]: "year"
43
34
  }[e] || e;
44
35
  }
45
- function _(e) {
36
+ function h(e) {
46
37
  return {
47
38
  [n.MONTHLY]: "Monthly",
48
39
  [n.YEARLY]: "Yearly"
49
40
  }[e] || e;
50
41
  }
51
- function v(t) {
42
+ function g(t) {
52
43
  return {
53
44
  [e.PURCHASE]: "Purchase",
54
45
  [e.USAGE]: "Usage",
@@ -56,10 +47,10 @@ function v(t) {
56
47
  [e.GRANTED]: "Granted"
57
48
  }[t] || t;
58
49
  }
59
- function y(e) {
50
+ function _(e) {
60
51
  return `#${e}`;
61
52
  }
62
53
  //#endregion
63
- export { v as formatCreditTransactionType, f as formatCredits, d as formatCurrency, o as formatDate, s as formatDateTime, y as formatInvoiceNumber, m as formatInvoiceStatus, c as formatNumber, l as formatPercentage, g as formatPlanDuration, _ as formatPlanDurationLabel, h as formatQuotaStatus, u as formatRelativeTime, p as formatSubscriptionStatus };
54
+ export { g as formatCreditTransactionType, d as formatCredits, u as formatCurrency, a as formatDate, o as formatDateTime, _ as formatInvoiceNumber, p as formatInvoiceStatus, s as formatNumber, c as formatPercentage, m as formatPlanDuration, h as formatPlanDurationLabel, l as formatRelativeTime, f as formatSubscriptionStatus };
64
55
 
65
56
  //# sourceMappingURL=format.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","names":[],"sources":["../../../../src/billing/shared/utils/format.ts"],"sourcesContent":["/**\n * Formatting utilities for the billing module\n *\n * Re-exports common formatting utilities from fe-libs and adds billing-specific ones.\n */\n\nimport {\n SubscriptionStatus,\n InvoiceStatus,\n PaymentStatus,\n ChargeStatus,\n QuotaStatus,\n PlanDuration,\n PaymentMethodType,\n TransactionType,\n CreditTransactionType,\n} from '../types';\n\n// Re-export common formatting utilities from fe-libs\nexport {\n formatCurrency as formatCurrencyBase,\n formatCurrencyCompact as formatCurrencyCompactBase,\n formatDate,\n formatDateTime,\n formatRelativeTime,\n formatDuration,\n formatNumber,\n formatPercentage,\n formatBytes,\n formatCompactNumber,\n} from '@burdenoff/fe-libs/shared/utils';\n\n// Import for internal use\nimport {\n formatCurrency as formatCurrencyBase,\n formatCurrencyCompact as formatCurrencyCompactBase,\n} from '@burdenoff/fe-libs/shared/utils';\n\n// ============================================================================\n// Billing-specific Currency Formatting (handles CREDITS)\n// ============================================================================\n\nexport function formatCurrency(amount: number, currency = 'USD', locale = 'en-US'): string {\n // Handle CREDITS specially - credits are not a real currency\n if (currency.toUpperCase() === 'CREDITS') {\n return formatCredits(amount);\n }\n return formatCurrencyBase(amount, currency, locale);\n}\n\n/**\n * Format credits as \"X Credits\" or \"X.XX Credits\"\n * Credits are always displayed as a unit count, not as currency\n */\nexport function formatCredits(amount: number): string {\n // For whole numbers, show without decimals\n if (Number.isInteger(amount)) {\n return `${amount.toLocaleString()} Credits`;\n }\n // For fractional credits, show up to 2 decimals\n return `${amount.toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} Credits`;\n}\n\nexport function formatCurrencyCompact(amount: number, currency = 'USD'): string {\n if (currency.toUpperCase() === 'CREDITS') {\n return formatCredits(amount);\n }\n return formatCurrencyCompactBase(amount, currency);\n}\n\n// ============================================================================\n// Status Formatting\n// ============================================================================\n\nexport function formatSubscriptionStatus(status: SubscriptionStatus): string {\n const labels: Record<SubscriptionStatus, string> = {\n [SubscriptionStatus.ACTIVE]: 'Active',\n [SubscriptionStatus.CANCELED]: 'Canceled',\n [SubscriptionStatus.EXPIRED]: 'Expired',\n [SubscriptionStatus.UPGRADED]: 'Upgraded',\n };\n return labels[status] || status;\n}\n\nexport function formatInvoiceStatus(status: InvoiceStatus): string {\n const labels: Record<InvoiceStatus, string> = {\n [InvoiceStatus.DRAFT]: 'Draft',\n [InvoiceStatus.OPEN]: 'Open',\n [InvoiceStatus.PAID]: 'Paid',\n [InvoiceStatus.VOID]: 'Void',\n [InvoiceStatus.UNCOLLECTIBLE]: 'Uncollectible',\n };\n return labels[status] || status;\n}\n\nexport function formatPaymentStatus(status: PaymentStatus): string {\n const labels: Record<PaymentStatus, string> = {\n [PaymentStatus.PENDING]: 'Pending',\n [PaymentStatus.SUCCEEDED]: 'Succeeded',\n [PaymentStatus.FAILED]: 'Failed',\n [PaymentStatus.CANCELED]: 'Canceled',\n [PaymentStatus.REFUNDED]: 'Refunded',\n };\n return labels[status] || status;\n}\n\nexport function formatChargeStatus(status: ChargeStatus): string {\n const labels: Record<ChargeStatus, string> = {\n [ChargeStatus.PENDING]: 'Pending',\n [ChargeStatus.SUCCEEDED]: 'Succeeded',\n [ChargeStatus.FAILED]: 'Failed',\n [ChargeStatus.REFUNDED]: 'Refunded',\n };\n return labels[status] || status;\n}\n\nexport function formatQuotaStatus(status: QuotaStatus): string {\n const labels: Record<QuotaStatus, string> = {\n [QuotaStatus.HEALTHY]: 'Healthy',\n [QuotaStatus.WARNING]: 'Warning',\n [QuotaStatus.CRITICAL]: 'Critical',\n [QuotaStatus.EXHAUSTED]: 'Exhausted',\n [QuotaStatus.INACTIVE]: 'Inactive',\n };\n return labels[status] || status;\n}\n\n// ============================================================================\n// Plan & Duration Formatting\n// ============================================================================\n\nexport function formatPlanDuration(duration: PlanDuration): string {\n const labels: Record<PlanDuration, string> = {\n [PlanDuration.MONTHLY]: 'month',\n [PlanDuration.YEARLY]: 'year',\n };\n return labels[duration] || duration;\n}\n\nexport function formatPlanDurationLabel(duration: PlanDuration): string {\n const labels: Record<PlanDuration, string> = {\n [PlanDuration.MONTHLY]: 'Monthly',\n [PlanDuration.YEARLY]: 'Yearly',\n };\n return labels[duration] || duration;\n}\n\nexport function formatPlanPrice(price: number, currency: string, duration: PlanDuration): string {\n return `${formatCurrency(price, currency)}/${formatPlanDuration(duration)}`;\n}\n\n// ============================================================================\n// Payment Method Formatting\n// ============================================================================\n\nexport function formatPaymentMethodType(type: PaymentMethodType): string {\n const labels: Record<PaymentMethodType, string> = {\n [PaymentMethodType.CREDIT_CARD]: 'Credit Card',\n [PaymentMethodType.DEBIT_CARD]: 'Debit Card',\n [PaymentMethodType.BANK_TRANSFER]: 'Bank Transfer',\n [PaymentMethodType.PAYPAL]: 'PayPal',\n [PaymentMethodType.CRYPTO]: 'Cryptocurrency',\n [PaymentMethodType.WALLET]: 'Wallet',\n [PaymentMethodType.NETBANKING]: 'Netbanking',\n };\n return labels[type] || type;\n}\n\nexport function formatCardBrand(brand?: string): string {\n if (!brand) return 'Card';\n return brand.charAt(0).toUpperCase() + brand.slice(1).toLowerCase();\n}\n\nexport function formatCardNumber(last4?: string): string {\n if (!last4) return '****';\n return `•••• ${last4}`;\n}\n\nexport function formatCardExpiry(month?: number, year?: number): string {\n if (!month || !year) return '';\n return `${month.toString().padStart(2, '0')}/${year.toString().slice(-2)}`;\n}\n\n// ============================================================================\n// Transaction Formatting\n// ============================================================================\n\nexport function formatTransactionType(type: TransactionType): string {\n const labels: Record<TransactionType, string> = {\n [TransactionType.PAYMENT]: 'Payment',\n [TransactionType.REFUND]: 'Refund',\n [TransactionType.ADJUSTMENT]: 'Adjustment',\n };\n return labels[type] || type;\n}\n\nexport function formatCreditTransactionType(type: CreditTransactionType): string {\n const labels: Record<CreditTransactionType, string> = {\n [CreditTransactionType.PURCHASE]: 'Purchase',\n [CreditTransactionType.USAGE]: 'Usage',\n [CreditTransactionType.ADJUSTMENT]: 'Earned',\n [CreditTransactionType.GRANTED]: 'Granted',\n };\n return labels[type] || type;\n}\n\n// ============================================================================\n// Text Formatting\n// ============================================================================\n\nexport function truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return `${text.slice(0, maxLength - 3)}...`;\n}\n\nexport function capitalizeFirst(text: string): string {\n if (!text) return '';\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();\n}\n\nexport function formatInvoiceNumber(number: string): string {\n return `#${number}`;\n}\n"],"mappings":";;;AA0CA,SAAgB,EAAe,GAAgB,IAAW,OAAO,IAAS,SAAiB;AAKzF,QAHI,EAAS,aAAa,KAAK,YACtB,EAAc,EAAO,GAEvB,EAAmB,GAAQ,GAAU,EAAO;;AAOrD,SAAgB,EAAc,GAAwB;AAMpD,QAJI,OAAO,UAAU,EAAO,GACnB,GAAG,EAAO,gBAAgB,CAAC,YAG7B,GAAG,EAAO,eAAe,KAAA,GAAW;EAAE,uBAAuB;EAAG,uBAAuB;EAAG,CAAC,CAAC;;AAcrG,SAAgB,EAAyB,GAAoC;AAO3E,QANmD;GAChD,EAAmB,SAAS;GAC5B,EAAmB,WAAW;GAC9B,EAAmB,UAAU;GAC7B,EAAmB,WAAW;EAChC,CACa,MAAW;;AAG3B,SAAgB,EAAoB,GAA+B;AAQjE,QAP8C;GAC3C,EAAc,QAAQ;GACtB,EAAc,OAAO;GACrB,EAAc,OAAO;GACrB,EAAc,OAAO;GACrB,EAAc,gBAAgB;EAChC,CACa,MAAW;;AAwB3B,SAAgB,EAAkB,GAA6B;AAQ7D,QAP4C;GACzC,EAAY,UAAU;GACtB,EAAY,UAAU;GACtB,EAAY,WAAW;GACvB,EAAY,YAAY;GACxB,EAAY,WAAW;EACzB,CACa,MAAW;;AAO3B,SAAgB,EAAmB,GAAgC;AAKjE,QAJ6C;GAC1C,EAAa,UAAU;GACvB,EAAa,SAAS;EACxB,CACa,MAAa;;AAG7B,SAAgB,EAAwB,GAAgC;AAKtE,QAJ6C;GAC1C,EAAa,UAAU;GACvB,EAAa,SAAS;EACxB,CACa,MAAa;;AAoD7B,SAAgB,EAA4B,GAAqC;AAO/E,QANsD;GACnD,EAAsB,WAAW;GACjC,EAAsB,QAAQ;GAC9B,EAAsB,aAAa;GACnC,EAAsB,UAAU;EAClC,CACa,MAAS;;AAiBzB,SAAgB,EAAoB,GAAwB;AAC1D,QAAO,IAAI"}
1
+ {"version":3,"file":"format.js","names":[],"sources":["../../../../src/billing/shared/utils/format.ts"],"sourcesContent":["/**\n * Formatting utilities for the billing module\n *\n * Re-exports common formatting utilities from fe-libs and adds billing-specific ones.\n */\n\nimport {\n SubscriptionStatus,\n InvoiceStatus,\n PaymentStatus,\n ChargeStatus,\n QuotaStatus,\n PlanDuration,\n PaymentMethodType,\n TransactionType,\n CreditTransactionType,\n} from '../types';\n\n// Re-export common formatting utilities from fe-libs\nexport {\n formatCurrency as formatCurrencyBase,\n formatCurrencyCompact as formatCurrencyCompactBase,\n formatDate,\n formatDateTime,\n formatRelativeTime,\n formatDuration,\n formatNumber,\n formatPercentage,\n formatBytes,\n formatCompactNumber,\n} from '@burdenoff/fe-libs/shared/utils';\n\n// Import for internal use\nimport {\n formatCurrency as formatCurrencyBase,\n formatCurrencyCompact as formatCurrencyCompactBase,\n} from '@burdenoff/fe-libs/shared/utils';\n\n// ============================================================================\n// Billing-specific Currency Formatting (handles CREDITS)\n// ============================================================================\n\nexport function formatCurrency(amount: number, currency = 'USD', locale = 'en-US'): string {\n // Handle CREDITS specially - credits are not a real currency\n if (currency.toUpperCase() === 'CREDITS') {\n return formatCredits(amount);\n }\n return formatCurrencyBase(amount, currency, locale);\n}\n\n/**\n * Format credits as \"X Credits\" or \"X.XX Credits\"\n * Credits are always displayed as a unit count, not as currency\n */\nexport function formatCredits(amount: number): string {\n // For whole numbers, show without decimals\n if (Number.isInteger(amount)) {\n return `${amount.toLocaleString()} Credits`;\n }\n // For fractional credits, show up to 2 decimals\n return `${amount.toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 })} Credits`;\n}\n\nexport function formatCurrencyCompact(amount: number, currency = 'USD'): string {\n if (currency.toUpperCase() === 'CREDITS') {\n return formatCredits(amount);\n }\n return formatCurrencyCompactBase(amount, currency);\n}\n\n// ============================================================================\n// Status Formatting\n// ============================================================================\n\nexport function formatSubscriptionStatus(status: SubscriptionStatus): string {\n const labels: Record<SubscriptionStatus, string> = {\n [SubscriptionStatus.ACTIVE]: 'Active',\n [SubscriptionStatus.CANCELED]: 'Canceled',\n [SubscriptionStatus.EXPIRED]: 'Expired',\n [SubscriptionStatus.UPGRADED]: 'Upgraded',\n };\n return labels[status] || status;\n}\n\nexport function formatInvoiceStatus(status: InvoiceStatus): string {\n const labels: Record<InvoiceStatus, string> = {\n [InvoiceStatus.DRAFT]: 'Draft',\n [InvoiceStatus.OPEN]: 'Open',\n [InvoiceStatus.PAID]: 'Paid',\n [InvoiceStatus.VOID]: 'Void',\n [InvoiceStatus.UNCOLLECTIBLE]: 'Uncollectible',\n };\n return labels[status] || status;\n}\n\nexport function formatPaymentStatus(status: PaymentStatus): string {\n const labels: Record<PaymentStatus, string> = {\n [PaymentStatus.PENDING]: 'Pending',\n [PaymentStatus.SUCCEEDED]: 'Succeeded',\n [PaymentStatus.FAILED]: 'Failed',\n [PaymentStatus.CANCELED]: 'Canceled',\n [PaymentStatus.REFUNDED]: 'Refunded',\n };\n return labels[status] || status;\n}\n\nexport function formatChargeStatus(status: ChargeStatus): string {\n const labels: Record<ChargeStatus, string> = {\n [ChargeStatus.PENDING]: 'Pending',\n [ChargeStatus.SUCCEEDED]: 'Succeeded',\n [ChargeStatus.FAILED]: 'Failed',\n [ChargeStatus.REFUNDED]: 'Refunded',\n };\n return labels[status] || status;\n}\n\nexport function formatQuotaStatus(status: QuotaStatus): string {\n const labels: Record<QuotaStatus, string> = {\n [QuotaStatus.HEALTHY]: 'Healthy',\n [QuotaStatus.WARNING]: 'Warning',\n [QuotaStatus.CRITICAL]: 'Critical',\n [QuotaStatus.EXHAUSTED]: 'Exhausted',\n [QuotaStatus.INACTIVE]: 'Inactive',\n };\n return labels[status] || status;\n}\n\n// ============================================================================\n// Plan & Duration Formatting\n// ============================================================================\n\nexport function formatPlanDuration(duration: PlanDuration): string {\n const labels: Record<PlanDuration, string> = {\n [PlanDuration.MONTHLY]: 'month',\n [PlanDuration.YEARLY]: 'year',\n };\n return labels[duration] || duration;\n}\n\nexport function formatPlanDurationLabel(duration: PlanDuration): string {\n const labels: Record<PlanDuration, string> = {\n [PlanDuration.MONTHLY]: 'Monthly',\n [PlanDuration.YEARLY]: 'Yearly',\n };\n return labels[duration] || duration;\n}\n\nexport function formatPlanPrice(price: number, currency: string, duration: PlanDuration): string {\n return `${formatCurrency(price, currency)}/${formatPlanDuration(duration)}`;\n}\n\n// ============================================================================\n// Payment Method Formatting\n// ============================================================================\n\nexport function formatPaymentMethodType(type: PaymentMethodType): string {\n const labels: Record<PaymentMethodType, string> = {\n [PaymentMethodType.CREDIT_CARD]: 'Credit Card',\n [PaymentMethodType.DEBIT_CARD]: 'Debit Card',\n [PaymentMethodType.BANK_TRANSFER]: 'Bank Transfer',\n [PaymentMethodType.PAYPAL]: 'PayPal',\n [PaymentMethodType.CRYPTO]: 'Cryptocurrency',\n [PaymentMethodType.WALLET]: 'Wallet',\n [PaymentMethodType.NETBANKING]: 'Netbanking',\n };\n return labels[type] || type;\n}\n\nexport function formatCardBrand(brand?: string): string {\n if (!brand) return 'Card';\n return brand.charAt(0).toUpperCase() + brand.slice(1).toLowerCase();\n}\n\nexport function formatCardNumber(last4?: string): string {\n if (!last4) return '****';\n return `•••• ${last4}`;\n}\n\nexport function formatCardExpiry(month?: number, year?: number): string {\n if (!month || !year) return '';\n return `${month.toString().padStart(2, '0')}/${year.toString().slice(-2)}`;\n}\n\n// ============================================================================\n// Transaction Formatting\n// ============================================================================\n\nexport function formatTransactionType(type: TransactionType): string {\n const labels: Record<TransactionType, string> = {\n [TransactionType.PAYMENT]: 'Payment',\n [TransactionType.REFUND]: 'Refund',\n [TransactionType.ADJUSTMENT]: 'Adjustment',\n };\n return labels[type] || type;\n}\n\nexport function formatCreditTransactionType(type: CreditTransactionType): string {\n const labels: Record<CreditTransactionType, string> = {\n [CreditTransactionType.PURCHASE]: 'Purchase',\n [CreditTransactionType.USAGE]: 'Usage',\n [CreditTransactionType.ADJUSTMENT]: 'Earned',\n [CreditTransactionType.GRANTED]: 'Granted',\n };\n return labels[type] || type;\n}\n\n// ============================================================================\n// Text Formatting\n// ============================================================================\n\nexport function truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) return text;\n return `${text.slice(0, maxLength - 3)}...`;\n}\n\nexport function capitalizeFirst(text: string): string {\n if (!text) return '';\n return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();\n}\n\nexport function formatInvoiceNumber(number: string): string {\n return `#${number}`;\n}\n"],"mappings":";;;AA0CA,SAAgB,EAAe,GAAgB,IAAW,OAAO,IAAS,SAAiB;AAKzF,QAHI,EAAS,aAAa,KAAK,YACtB,EAAc,EAAO,GAEvB,EAAmB,GAAQ,GAAU,EAAO;;AAOrD,SAAgB,EAAc,GAAwB;AAMpD,QAJI,OAAO,UAAU,EAAO,GACnB,GAAG,EAAO,gBAAgB,CAAC,YAG7B,GAAG,EAAO,eAAe,KAAA,GAAW;EAAE,uBAAuB;EAAG,uBAAuB;EAAG,CAAC,CAAC;;AAcrG,SAAgB,EAAyB,GAAoC;AAO3E,QANmD;GAChD,EAAmB,SAAS;GAC5B,EAAmB,WAAW;GAC9B,EAAmB,UAAU;GAC7B,EAAmB,WAAW;EAChC,CACa,MAAW;;AAG3B,SAAgB,EAAoB,GAA+B;AAQjE,QAP8C;GAC3C,EAAc,QAAQ;GACtB,EAAc,OAAO;GACrB,EAAc,OAAO;GACrB,EAAc,OAAO;GACrB,EAAc,gBAAgB;EAChC,CACa,MAAW;;AAuC3B,SAAgB,EAAmB,GAAgC;AAKjE,QAJ6C;GAC1C,EAAa,UAAU;GACvB,EAAa,SAAS;EACxB,CACa,MAAa;;AAG7B,SAAgB,EAAwB,GAAgC;AAKtE,QAJ6C;GAC1C,EAAa,UAAU;GACvB,EAAa,SAAS;EACxB,CACa,MAAa;;AAoD7B,SAAgB,EAA4B,GAAqC;AAO/E,QANsD;GACnD,EAAsB,WAAW;GACjC,EAAsB,QAAQ;GAC9B,EAAsB,aAAa;GACnC,EAAsB,UAAU;EAClC,CACa,MAAS;;AAiBzB,SAAgB,EAAoB,GAAwB;AAC1D,QAAO,IAAI"}
@@ -1,15 +1,15 @@
1
1
  import { getProgressTokens as e, getStatusBadgeTokens as t } from "./tokens.js";
2
- import { CreditTransactionStatus as n, InvoiceStatus as r, QuotaStatus as i, SubscriptionStatus as a, TransactionStatus as o } from "../types/graphql.js";
2
+ import { CreditTransactionStatus as n, InvoiceStatus as r, SubscriptionStatus as i, TransactionStatus as a } from "../types/graphql.js";
3
3
  //#region src/billing/shared/utils/status.ts
4
- function s(e) {
4
+ function o(e) {
5
5
  return {
6
- [a.ACTIVE]: "success",
7
- [a.CANCELED]: "error",
8
- [a.EXPIRED]: "neutral",
9
- [a.UPGRADED]: "info"
6
+ [i.ACTIVE]: "success",
7
+ [i.CANCELED]: "error",
8
+ [i.EXPIRED]: "neutral",
9
+ [i.UPGRADED]: "info"
10
10
  }[e] || "neutral";
11
11
  }
12
- function c(e) {
12
+ function s(e) {
13
13
  return {
14
14
  [r.DRAFT]: "neutral",
15
15
  [r.OPEN]: "info",
@@ -18,23 +18,14 @@ function c(e) {
18
18
  [r.UNCOLLECTIBLE]: "error"
19
19
  }[e] || "neutral";
20
20
  }
21
- function l(e) {
22
- return {
23
- [i.HEALTHY]: "success",
24
- [i.WARNING]: "warning",
25
- [i.CRITICAL]: "error",
26
- [i.EXHAUSTED]: "error",
27
- [i.INACTIVE]: "neutral"
28
- }[e] || "neutral";
29
- }
30
- function u(e) {
21
+ function c(e) {
31
22
  return {
32
- [o.PENDING]: "warning",
33
- [o.SUCCESS]: "success",
34
- [o.FAILED]: "error"
23
+ [a.PENDING]: "warning",
24
+ [a.SUCCESS]: "success",
25
+ [a.FAILED]: "error"
35
26
  }[e] || "neutral";
36
27
  }
37
- function d(e) {
28
+ function l(e) {
38
29
  return {
39
30
  [n.PENDING]: "warning",
40
31
  [n.SUCCESS]: "success",
@@ -42,16 +33,13 @@ function d(e) {
42
33
  [n.REFUND]: "info"
43
34
  }[e] || "neutral";
44
35
  }
45
- function f(e) {
36
+ function u(e) {
46
37
  return t(e);
47
38
  }
48
- function p(t) {
39
+ function d(t) {
49
40
  return e(t).bar;
50
41
  }
51
- function m(t) {
52
- return e(t).track;
53
- }
54
42
  //#endregion
55
- export { d as getCreditTransactionStatusColor, c as getInvoiceStatusColor, m as getQuotaProgressBgColor, p as getQuotaProgressColor, l as getQuotaStatusColor, f as getStatusBadgeClasses, s as getSubscriptionStatusColor, u as getTransactionStatusColor };
43
+ export { l as getCreditTransactionStatusColor, s as getInvoiceStatusColor, d as getQuotaProgressColor, u as getStatusBadgeClasses, o as getSubscriptionStatusColor, c as getTransactionStatusColor };
56
44
 
57
45
  //# sourceMappingURL=status.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","names":[],"sources":["../../../../src/billing/shared/utils/status.ts"],"sourcesContent":["/**\n * Status utilities for the billing module\n * Provides status colors, icons, and helper functions\n *\n * Uses semantic design tokens from tokens.ts for consistent theming\n */\n\nimport {\n SubscriptionStatus,\n InvoiceStatus,\n PaymentStatus,\n ChargeStatus,\n RefundStatus,\n QuotaStatus,\n TransactionStatus,\n CreditTransactionStatus,\n} from '../types';\nimport { type SemanticStatus, getStatusBadgeTokens, getProgressTokens } from './tokens';\n\n// ============================================================================\n// Status Color Types\n// ============================================================================\n\nexport type StatusColor = SemanticStatus;\n\n// ============================================================================\n// Status Color Mappings\n// ============================================================================\n\nexport function getSubscriptionStatusColor(status: SubscriptionStatus): StatusColor {\n const colors: Record<SubscriptionStatus, StatusColor> = {\n [SubscriptionStatus.ACTIVE]: 'success',\n [SubscriptionStatus.CANCELED]: 'error',\n [SubscriptionStatus.EXPIRED]: 'neutral',\n [SubscriptionStatus.UPGRADED]: 'info',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getInvoiceStatusColor(status: InvoiceStatus): StatusColor {\n const colors: Record<InvoiceStatus, StatusColor> = {\n [InvoiceStatus.DRAFT]: 'neutral',\n [InvoiceStatus.OPEN]: 'info',\n [InvoiceStatus.PAID]: 'success',\n [InvoiceStatus.VOID]: 'neutral',\n [InvoiceStatus.UNCOLLECTIBLE]: 'error',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getPaymentStatusColor(status: PaymentStatus): StatusColor {\n const colors: Record<PaymentStatus, StatusColor> = {\n [PaymentStatus.PENDING]: 'warning',\n [PaymentStatus.SUCCEEDED]: 'success',\n [PaymentStatus.FAILED]: 'error',\n [PaymentStatus.CANCELED]: 'neutral',\n [PaymentStatus.REFUNDED]: 'info',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getChargeStatusColor(status: ChargeStatus): StatusColor {\n const colors: Record<ChargeStatus, StatusColor> = {\n [ChargeStatus.PENDING]: 'warning',\n [ChargeStatus.SUCCEEDED]: 'success',\n [ChargeStatus.FAILED]: 'error',\n [ChargeStatus.REFUNDED]: 'info',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getRefundStatusColor(status: RefundStatus): StatusColor {\n const colors: Record<RefundStatus, StatusColor> = {\n [RefundStatus.PENDING]: 'warning',\n [RefundStatus.SUCCEEDED]: 'success',\n [RefundStatus.FAILED]: 'error',\n [RefundStatus.CANCELED]: 'neutral',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getQuotaStatusColor(status: QuotaStatus): StatusColor {\n const colors: Record<QuotaStatus, StatusColor> = {\n [QuotaStatus.HEALTHY]: 'success',\n [QuotaStatus.WARNING]: 'warning',\n [QuotaStatus.CRITICAL]: 'error',\n [QuotaStatus.EXHAUSTED]: 'error',\n [QuotaStatus.INACTIVE]: 'neutral',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getTransactionStatusColor(status: TransactionStatus): StatusColor {\n const colors: Record<TransactionStatus, StatusColor> = {\n [TransactionStatus.PENDING]: 'warning',\n [TransactionStatus.SUCCESS]: 'success',\n [TransactionStatus.FAILED]: 'error',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getCreditTransactionStatusColor(status: CreditTransactionStatus): StatusColor {\n const colors: Record<CreditTransactionStatus, StatusColor> = {\n [CreditTransactionStatus.PENDING]: 'warning',\n [CreditTransactionStatus.SUCCESS]: 'success',\n [CreditTransactionStatus.FAILED]: 'error',\n [CreditTransactionStatus.REFUND]: 'info',\n };\n return colors[status] || 'neutral';\n}\n\n// ============================================================================\n// CSS Class Mappings (using semantic tokens)\n// ============================================================================\n\n/**\n * Get combined badge classes for a status.\n */\nexport function getStatusBadgeClasses(color: StatusColor): string {\n return getStatusBadgeTokens(color);\n}\n\n// ============================================================================\n// Quota Status Helpers\n// ============================================================================\n\nexport function getQuotaStatusFromPercentage(percentage: number): QuotaStatus {\n if (percentage >= 100) return QuotaStatus.EXHAUSTED;\n if (percentage >= 90) return QuotaStatus.CRITICAL;\n if (percentage >= 75) return QuotaStatus.WARNING;\n return QuotaStatus.HEALTHY;\n}\n\nexport function getQuotaProgressColor(percentage: number): string {\n const tokens = getProgressTokens(percentage);\n return tokens.bar;\n}\n\nexport function getQuotaProgressBgColor(percentage: number): string {\n const tokens = getProgressTokens(percentage);\n return tokens.track;\n}\n\n// ============================================================================\n// Status Checks\n// ============================================================================\n\nexport function isActiveSubscription(status: SubscriptionStatus): boolean {\n return status === SubscriptionStatus.ACTIVE;\n}\n\nexport function isPaidInvoice(status: InvoiceStatus): boolean {\n return status === InvoiceStatus.PAID;\n}\n\nexport function isOpenInvoice(status: InvoiceStatus): boolean {\n return status === InvoiceStatus.OPEN;\n}\n\nexport function isSuccessfulPayment(status: PaymentStatus): boolean {\n return status === PaymentStatus.SUCCEEDED;\n}\n\nexport function isPendingPayment(status: PaymentStatus): boolean {\n return status === PaymentStatus.PENDING;\n}\n\nexport function isHealthyQuota(status: QuotaStatus): boolean {\n return status === QuotaStatus.HEALTHY;\n}\n\nexport function isQuotaAtRisk(status: QuotaStatus): boolean {\n return status === QuotaStatus.WARNING || status === QuotaStatus.CRITICAL;\n}\n\nexport function isQuotaExhausted(status: QuotaStatus): boolean {\n return status === QuotaStatus.EXHAUSTED;\n}\n"],"mappings":";;;AA6BA,SAAgB,EAA2B,GAAyC;AAOlF,QANwD;GACrD,EAAmB,SAAS;GAC5B,EAAmB,WAAW;GAC9B,EAAmB,UAAU;GAC7B,EAAmB,WAAW;EAChC,CACa,MAAW;;AAG3B,SAAgB,EAAsB,GAAoC;AAQxE,QAPmD;GAChD,EAAc,QAAQ;GACtB,EAAc,OAAO;GACrB,EAAc,OAAO;GACrB,EAAc,OAAO;GACrB,EAAc,gBAAgB;EAChC,CACa,MAAW;;AAkC3B,SAAgB,EAAoB,GAAkC;AAQpE,QAPiD;GAC9C,EAAY,UAAU;GACtB,EAAY,UAAU;GACtB,EAAY,WAAW;GACvB,EAAY,YAAY;GACxB,EAAY,WAAW;EACzB,CACa,MAAW;;AAG3B,SAAgB,EAA0B,GAAwC;AAMhF,QALuD;GACpD,EAAkB,UAAU;GAC5B,EAAkB,UAAU;GAC5B,EAAkB,SAAS;EAC7B,CACa,MAAW;;AAG3B,SAAgB,EAAgC,GAA8C;AAO5F,QAN6D;GAC1D,EAAwB,UAAU;GAClC,EAAwB,UAAU;GAClC,EAAwB,SAAS;GACjC,EAAwB,SAAS;EACnC,CACa,MAAW;;AAU3B,SAAgB,EAAsB,GAA4B;AAChE,QAAO,EAAqB,EAAM;;AAcpC,SAAgB,EAAsB,GAA4B;AAEhE,QADe,EAAkB,EAAW,CAC9B;;AAGhB,SAAgB,EAAwB,GAA4B;AAElE,QADe,EAAkB,EAAW,CAC9B"}
1
+ {"version":3,"file":"status.js","names":[],"sources":["../../../../src/billing/shared/utils/status.ts"],"sourcesContent":["/**\n * Status utilities for the billing module\n * Provides status colors, icons, and helper functions\n *\n * Uses semantic design tokens from tokens.ts for consistent theming\n */\n\nimport {\n SubscriptionStatus,\n InvoiceStatus,\n PaymentStatus,\n ChargeStatus,\n RefundStatus,\n QuotaStatus,\n TransactionStatus,\n CreditTransactionStatus,\n} from '../types';\nimport { type SemanticStatus, getStatusBadgeTokens, getProgressTokens } from './tokens';\n\n// ============================================================================\n// Status Color Types\n// ============================================================================\n\nexport type StatusColor = SemanticStatus;\n\n// ============================================================================\n// Status Color Mappings\n// ============================================================================\n\nexport function getSubscriptionStatusColor(status: SubscriptionStatus): StatusColor {\n const colors: Record<SubscriptionStatus, StatusColor> = {\n [SubscriptionStatus.ACTIVE]: 'success',\n [SubscriptionStatus.CANCELED]: 'error',\n [SubscriptionStatus.EXPIRED]: 'neutral',\n [SubscriptionStatus.UPGRADED]: 'info',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getInvoiceStatusColor(status: InvoiceStatus): StatusColor {\n const colors: Record<InvoiceStatus, StatusColor> = {\n [InvoiceStatus.DRAFT]: 'neutral',\n [InvoiceStatus.OPEN]: 'info',\n [InvoiceStatus.PAID]: 'success',\n [InvoiceStatus.VOID]: 'neutral',\n [InvoiceStatus.UNCOLLECTIBLE]: 'error',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getPaymentStatusColor(status: PaymentStatus): StatusColor {\n const colors: Record<PaymentStatus, StatusColor> = {\n [PaymentStatus.PENDING]: 'warning',\n [PaymentStatus.SUCCEEDED]: 'success',\n [PaymentStatus.FAILED]: 'error',\n [PaymentStatus.CANCELED]: 'neutral',\n [PaymentStatus.REFUNDED]: 'info',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getChargeStatusColor(status: ChargeStatus): StatusColor {\n const colors: Record<ChargeStatus, StatusColor> = {\n [ChargeStatus.PENDING]: 'warning',\n [ChargeStatus.SUCCEEDED]: 'success',\n [ChargeStatus.FAILED]: 'error',\n [ChargeStatus.REFUNDED]: 'info',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getRefundStatusColor(status: RefundStatus): StatusColor {\n const colors: Record<RefundStatus, StatusColor> = {\n [RefundStatus.PENDING]: 'warning',\n [RefundStatus.SUCCEEDED]: 'success',\n [RefundStatus.FAILED]: 'error',\n [RefundStatus.CANCELED]: 'neutral',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getQuotaStatusColor(status: QuotaStatus): StatusColor {\n const colors: Record<QuotaStatus, StatusColor> = {\n [QuotaStatus.HEALTHY]: 'success',\n [QuotaStatus.WARNING]: 'warning',\n [QuotaStatus.CRITICAL]: 'error',\n [QuotaStatus.EXHAUSTED]: 'error',\n [QuotaStatus.INACTIVE]: 'neutral',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getTransactionStatusColor(status: TransactionStatus): StatusColor {\n const colors: Record<TransactionStatus, StatusColor> = {\n [TransactionStatus.PENDING]: 'warning',\n [TransactionStatus.SUCCESS]: 'success',\n [TransactionStatus.FAILED]: 'error',\n };\n return colors[status] || 'neutral';\n}\n\nexport function getCreditTransactionStatusColor(status: CreditTransactionStatus): StatusColor {\n const colors: Record<CreditTransactionStatus, StatusColor> = {\n [CreditTransactionStatus.PENDING]: 'warning',\n [CreditTransactionStatus.SUCCESS]: 'success',\n [CreditTransactionStatus.FAILED]: 'error',\n [CreditTransactionStatus.REFUND]: 'info',\n };\n return colors[status] || 'neutral';\n}\n\n// ============================================================================\n// CSS Class Mappings (using semantic tokens)\n// ============================================================================\n\n/**\n * Get combined badge classes for a status.\n */\nexport function getStatusBadgeClasses(color: StatusColor): string {\n return getStatusBadgeTokens(color);\n}\n\n// ============================================================================\n// Quota Status Helpers\n// ============================================================================\n\nexport function getQuotaStatusFromPercentage(percentage: number): QuotaStatus {\n if (percentage >= 100) return QuotaStatus.EXHAUSTED;\n if (percentage >= 90) return QuotaStatus.CRITICAL;\n if (percentage >= 75) return QuotaStatus.WARNING;\n return QuotaStatus.HEALTHY;\n}\n\nexport function getQuotaProgressColor(percentage: number): string {\n const tokens = getProgressTokens(percentage);\n return tokens.bar;\n}\n\nexport function getQuotaProgressBgColor(percentage: number): string {\n const tokens = getProgressTokens(percentage);\n return tokens.track;\n}\n\n// ============================================================================\n// Status Checks\n// ============================================================================\n\nexport function isActiveSubscription(status: SubscriptionStatus): boolean {\n return status === SubscriptionStatus.ACTIVE;\n}\n\nexport function isPaidInvoice(status: InvoiceStatus): boolean {\n return status === InvoiceStatus.PAID;\n}\n\nexport function isOpenInvoice(status: InvoiceStatus): boolean {\n return status === InvoiceStatus.OPEN;\n}\n\nexport function isSuccessfulPayment(status: PaymentStatus): boolean {\n return status === PaymentStatus.SUCCEEDED;\n}\n\nexport function isPendingPayment(status: PaymentStatus): boolean {\n return status === PaymentStatus.PENDING;\n}\n\nexport function isHealthyQuota(status: QuotaStatus): boolean {\n return status === QuotaStatus.HEALTHY;\n}\n\nexport function isQuotaAtRisk(status: QuotaStatus): boolean {\n return status === QuotaStatus.WARNING || status === QuotaStatus.CRITICAL;\n}\n\nexport function isQuotaExhausted(status: QuotaStatus): boolean {\n return status === QuotaStatus.EXHAUSTED;\n}\n"],"mappings":";;;AA6BA,SAAgB,EAA2B,GAAyC;AAOlF,QANwD;GACrD,EAAmB,SAAS;GAC5B,EAAmB,WAAW;GAC9B,EAAmB,UAAU;GAC7B,EAAmB,WAAW;EAChC,CACa,MAAW;;AAG3B,SAAgB,EAAsB,GAAoC;AAQxE,QAPmD;GAChD,EAAc,QAAQ;GACtB,EAAc,OAAO;GACrB,EAAc,OAAO;GACrB,EAAc,OAAO;GACrB,EAAc,gBAAgB;EAChC,CACa,MAAW;;AA6C3B,SAAgB,EAA0B,GAAwC;AAMhF,QALuD;GACpD,EAAkB,UAAU;GAC5B,EAAkB,UAAU;GAC5B,EAAkB,SAAS;EAC7B,CACa,MAAW;;AAG3B,SAAgB,EAAgC,GAA8C;AAO5F,QAN6D;GAC1D,EAAwB,UAAU;GAClC,EAAwB,UAAU;GAClC,EAAwB,SAAS;GACjC,EAAwB,SAAS;EACnC,CACa,MAAW;;AAU3B,SAAgB,EAAsB,GAA4B;AAChE,QAAO,EAAqB,EAAM;;AAcpC,SAAgB,EAAsB,GAA4B;AAEhE,QADe,EAAkB,EAAW,CAC9B"}