@carlonicora/nextjs-jsonapi 1.23.0 → 1.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/ApiDataInterface-DPP8s46n.d.mts +21 -0
  2. package/dist/ApiDataInterface-DPP8s46n.d.ts +21 -0
  3. package/dist/ApiRequestDataTypeInterface-CUKFDBx2.d.mts +20 -0
  4. package/dist/ApiRequestDataTypeInterface-CUKFDBx2.d.ts +20 -0
  5. package/dist/{ApiResponseInterface-BKyod24U.d.ts → ApiResponseInterface-CAIAeP5d.d.ts} +1 -1
  6. package/dist/{ApiResponseInterface-Dqvu09tz.d.mts → ApiResponseInterface-zeewugD7.d.mts} +1 -1
  7. package/dist/AuthComponent-hxOPs9o8.d.mts +11 -0
  8. package/dist/AuthComponent-hxOPs9o8.d.ts +11 -0
  9. package/dist/{BlockNoteEditor-KQTKURH6.js → BlockNoteEditor-UCHRVVVZ.js} +15 -15
  10. package/dist/{BlockNoteEditor-KQTKURH6.js.map → BlockNoteEditor-UCHRVVVZ.js.map} +1 -1
  11. package/dist/{BlockNoteEditor-VKN4LZUV.mjs → BlockNoteEditor-ZYZZ6B45.mjs} +5 -5
  12. package/dist/JsonApiRequest-GR3L56A5.js +24 -0
  13. package/dist/{JsonApiRequest-54ZBO7WQ.js.map → JsonApiRequest-GR3L56A5.js.map} +1 -1
  14. package/dist/{JsonApiRequest-XWQWTFEQ.mjs → JsonApiRequest-K5BRU7RE.mjs} +2 -2
  15. package/dist/billing/index.d.mts +249 -0
  16. package/dist/billing/index.d.ts +249 -0
  17. package/dist/billing/index.js +3479 -0
  18. package/dist/billing/index.js.map +1 -0
  19. package/dist/billing/index.mjs +3479 -0
  20. package/dist/billing/index.mjs.map +1 -0
  21. package/dist/{chunk-KUFWHMMY.mjs → chunk-5U4NJJOF.mjs} +5 -5
  22. package/dist/{chunk-YF5KBA7H.mjs → chunk-CU4RXSNY.mjs} +168 -3578
  23. package/dist/chunk-CU4RXSNY.mjs.map +1 -0
  24. package/dist/{chunk-LSIUPIYQ.js → chunk-EW6QPMN3.js} +3 -3
  25. package/dist/{chunk-LSIUPIYQ.js.map → chunk-EW6QPMN3.js.map} +1 -1
  26. package/dist/{chunk-LI6CPNJI.js → chunk-FM6WRAN5.js} +1 -1
  27. package/dist/{chunk-LI6CPNJI.js.map → chunk-FM6WRAN5.js.map} +1 -1
  28. package/dist/{chunk-L6XLESU5.mjs → chunk-GR4QPP36.mjs} +2 -2
  29. package/dist/{chunk-ODNMW2CG.js → chunk-ILKUML3Z.js} +761 -4171
  30. package/dist/chunk-ILKUML3Z.js.map +1 -0
  31. package/dist/{chunk-UYY34W7R.js → chunk-NQVPCNRS.js} +26 -26
  32. package/dist/{chunk-UYY34W7R.js.map → chunk-NQVPCNRS.js.map} +1 -1
  33. package/dist/{chunk-3VM3WAOV.mjs → chunk-U4MTVHOC.mjs} +1 -1
  34. package/dist/client/index.d.mts +7 -6
  35. package/dist/client/index.d.ts +7 -6
  36. package/dist/client/index.js +5 -5
  37. package/dist/client/index.mjs +4 -4
  38. package/dist/components/index.d.mts +8 -250
  39. package/dist/components/index.d.ts +8 -250
  40. package/dist/components/index.js +5 -83
  41. package/dist/components/index.js.map +1 -1
  42. package/dist/components/index.mjs +4 -82
  43. package/dist/{config--nwiW74Z.d.ts → config-D_91hrI-.d.ts} +1 -1
  44. package/dist/{config-BKSQmUWU.d.mts → config-h0hNLceh.d.mts} +1 -1
  45. package/dist/{content.interface-4VICFRA0.d.ts → content.interface-CUIEQ0jk.d.ts} +2 -2
  46. package/dist/{content.interface-CFc97-Cj.d.mts → content.interface-QcsFR5Ad.d.mts} +2 -2
  47. package/dist/contexts/index.d.mts +4 -3
  48. package/dist/contexts/index.d.ts +4 -3
  49. package/dist/contexts/index.js +5 -5
  50. package/dist/contexts/index.mjs +4 -4
  51. package/dist/core/index.d.mts +12 -10
  52. package/dist/core/index.d.ts +12 -10
  53. package/dist/core/index.js +3 -3
  54. package/dist/core/index.mjs +2 -2
  55. package/dist/index.d.mts +9 -7
  56. package/dist/index.d.ts +9 -7
  57. package/dist/index.js +4 -4
  58. package/dist/index.mjs +3 -3
  59. package/dist/{notification.interface-CqwaOIgM.d.ts → notification.interface-D7_g5SnS.d.ts} +2 -1
  60. package/dist/{notification.interface-BGaPiCUM.d.mts → notification.interface-blT8r47t.d.mts} +2 -1
  61. package/dist/{s3.service-BYs88XEE.d.ts → s3.service-B83hUhqV.d.ts} +4 -3
  62. package/dist/{s3.service-C0BjOdvn.d.mts → s3.service-DSDfcr0S.d.mts} +4 -3
  63. package/dist/server/index.d.mts +6 -5
  64. package/dist/server/index.d.ts +6 -5
  65. package/dist/server/index.js +15 -15
  66. package/dist/server/index.js.map +1 -1
  67. package/dist/server/index.mjs +5 -5
  68. package/dist/{stripe-subscription.interface-B-TM40Io.d.ts → stripe-subscription.interface-CFtupgYh.d.mts} +2 -12
  69. package/dist/{stripe-subscription.interface-DDxnpj0F.d.mts → stripe-subscription.interface-CNTsrbAx.d.ts} +2 -12
  70. package/dist/testing/index.d.mts +3 -2
  71. package/dist/testing/index.d.ts +3 -2
  72. package/dist/{useSocket-BNj9PrRw.d.mts → useSocket-B5M_a4bD.d.mts} +1 -1
  73. package/dist/{useSocket-Dwt8cz1x.d.ts → useSocket-Dd03muLJ.d.ts} +1 -1
  74. package/package.json +36 -31
  75. package/src/billing/index.ts +8 -0
  76. package/src/components/index.ts +1 -7
  77. package/src/components/pages/PageContentContainer.tsx +1 -2
  78. package/src/shadcnui/ui/resizable.tsx +7 -7
  79. package/dist/ApiRequestDataTypeInterface-DIEOFn9s.d.mts +0 -40
  80. package/dist/ApiRequestDataTypeInterface-DIEOFn9s.d.ts +0 -40
  81. package/dist/JsonApiRequest-54ZBO7WQ.js +0 -24
  82. package/dist/chunk-ODNMW2CG.js.map +0 -1
  83. package/dist/chunk-YF5KBA7H.mjs.map +0 -1
  84. /package/dist/{BlockNoteEditor-VKN4LZUV.mjs.map → BlockNoteEditor-ZYZZ6B45.mjs.map} +0 -0
  85. /package/dist/{JsonApiRequest-XWQWTFEQ.mjs.map → JsonApiRequest-K5BRU7RE.mjs.map} +0 -0
  86. /package/dist/{chunk-KUFWHMMY.mjs.map → chunk-5U4NJJOF.mjs.map} +0 -0
  87. /package/dist/{chunk-L6XLESU5.mjs.map → chunk-GR4QPP36.mjs.map} +0 -0
  88. /package/dist/{chunk-3VM3WAOV.mjs.map → chunk-U4MTVHOC.mjs.map} +0 -0
@@ -0,0 +1,3479 @@
1
+ "use client";
2
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+ var _chunkILKUML3Zjs = require('../chunk-ILKUML3Z.js');
55
+
56
+
57
+
58
+ var _chunkEW6QPMN3js = require('../chunk-EW6QPMN3.js');
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+ var _chunkNQVPCNRSjs = require('../chunk-NQVPCNRS.js');
68
+ require('../chunk-LXKSUWAV.js');
69
+ require('../chunk-IBS6NI7D.js');
70
+ require('../chunk-FM6WRAN5.js');
71
+ require('../chunk-3EPNHTMH.js');
72
+
73
+
74
+ var _chunk7QVYU63Ejs = require('../chunk-7QVYU63E.js');
75
+
76
+ // src/features/billing/components/cards/SubscriptionSummaryCard.tsx
77
+ var _lucidereact = require('lucide-react');
78
+ var _jsxruntime = require('react/jsx-runtime');
79
+ function getStatusBadgeVariant(status) {
80
+ switch (status) {
81
+ case "active" /* ACTIVE */:
82
+ return "default";
83
+ case "trialing" /* TRIALING */:
84
+ return "secondary";
85
+ case "past_due" /* PAST_DUE */:
86
+ case "unpaid" /* UNPAID */:
87
+ case "canceled" /* CANCELED */:
88
+ return "destructive";
89
+ default:
90
+ return "outline";
91
+ }
92
+ }
93
+ _chunk7QVYU63Ejs.__name.call(void 0, getStatusBadgeVariant, "getStatusBadgeVariant");
94
+ function formatDate(date) {
95
+ return new Date(date).toLocaleDateString(void 0, {
96
+ year: "numeric",
97
+ month: "short",
98
+ day: "numeric"
99
+ });
100
+ }
101
+ _chunk7QVYU63Ejs.__name.call(void 0, formatDate, "formatDate");
102
+ function formatPrice(amount, currency) {
103
+ if (amount === void 0) return "N/A";
104
+ const currencyCode = _optionalChain([currency, 'optionalAccess', _3 => _3.toUpperCase, 'call', _4 => _4()]) || "USD";
105
+ return new Intl.NumberFormat(void 0, {
106
+ style: "currency",
107
+ currency: currencyCode
108
+ }).format(amount / 100);
109
+ }
110
+ _chunk7QVYU63Ejs.__name.call(void 0, formatPrice, "formatPrice");
111
+ function formatPlanName(subscription) {
112
+ const productName = _optionalChain([subscription, 'access', _5 => _5.price, 'optionalAccess', _6 => _6.product, 'optionalAccess', _7 => _7.name]) || "";
113
+ const nickname = _optionalChain([subscription, 'access', _8 => _8.price, 'optionalAccess', _9 => _9.nickname]) || "";
114
+ if (productName && nickname) {
115
+ return `${productName} - ${nickname}`;
116
+ }
117
+ return productName || nickname || "Subscription";
118
+ }
119
+ _chunk7QVYU63Ejs.__name.call(void 0, formatPlanName, "formatPlanName");
120
+ function SubscriptionSummaryCard({
121
+ subscriptions,
122
+ loading,
123
+ error,
124
+ onManageClick
125
+ }) {
126
+ if (loading) {
127
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
128
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
129
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Subscriptions" }),
130
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-4 w-4 text-muted-foreground" })
131
+ ] }),
132
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { children: [
133
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-6 w-32 mb-2" }),
134
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-24 mb-1" }),
135
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-40" })
136
+ ] })
137
+ ] });
138
+ }
139
+ if (error) {
140
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
141
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
142
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Subscriptions" }),
143
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-4 w-4 text-muted-foreground" })
144
+ ] }),
145
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
146
+ ] });
147
+ }
148
+ const activeSubscriptions = subscriptions.filter(
149
+ (sub) => sub.status === "active" /* ACTIVE */ || sub.status === "trialing" /* TRIALING */
150
+ );
151
+ const primarySubscription = activeSubscriptions[0];
152
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { className: "cursor-pointer hover:bg-accent/50 transition-colors", onClick: onManageClick, children: [
153
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
154
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Subscriptions" }),
155
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-4 w-4 text-muted-foreground" })
156
+ ] }),
157
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: subscriptions.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
158
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "No active plan" }),
159
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "Subscribe to get started" }),
160
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
161
+ _chunkILKUML3Zjs.Button,
162
+ {
163
+ variant: "outline",
164
+ size: "sm",
165
+ className: "mt-2",
166
+ onClick: (e) => {
167
+ e.stopPropagation();
168
+ onManageClick();
169
+ },
170
+ children: [
171
+ "View Plans",
172
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronRight, { className: "h-4 w-4 ml-1" })
173
+ ]
174
+ }
175
+ )
176
+ ] }) : primarySubscription ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
177
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
178
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold", children: formatPlanName(primarySubscription) }),
179
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Badge, { variant: primarySubscription.cancelAtPeriodEnd ? "secondary" : getStatusBadgeVariant(primarySubscription.status), children: primarySubscription.cancelAtPeriodEnd ? "Canceling" : primarySubscription.status })
180
+ ] }),
181
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-muted-foreground", children: [
182
+ formatPrice(_optionalChain([primarySubscription, 'access', _10 => _10.price, 'optionalAccess', _11 => _11.unitAmount]), _optionalChain([primarySubscription, 'access', _12 => _12.price, 'optionalAccess', _13 => _13.currency])),
183
+ _optionalChain([primarySubscription, 'access', _14 => _14.price, 'optionalAccess', _15 => _15.recurring]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { children: [
184
+ "/",
185
+ primarySubscription.price.recurring.interval
186
+ ] })
187
+ ] }),
188
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: primarySubscription.cancelAtPeriodEnd ? `Cancels on ${formatDate(primarySubscription.currentPeriodEnd)}` : `Renews on ${formatDate(primarySubscription.currentPeriodEnd)}` }),
189
+ activeSubscriptions.length > 1 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-xs text-muted-foreground", children: [
190
+ "+",
191
+ activeSubscriptions.length - 1,
192
+ " more subscription(s)"
193
+ ] })
194
+ ] }) : null })
195
+ ] });
196
+ }
197
+ _chunk7QVYU63Ejs.__name.call(void 0, SubscriptionSummaryCard, "SubscriptionSummaryCard");
198
+
199
+ // src/features/billing/components/cards/PaymentMethodSummaryCard.tsx
200
+
201
+
202
+ function getCardBrandIcon(brand) {
203
+ const brandMap = {
204
+ visa: "Visa",
205
+ mastercard: "Mastercard",
206
+ amex: "Amex",
207
+ discover: "Discover",
208
+ diners: "Diners",
209
+ jcb: "JCB",
210
+ unionpay: "UnionPay"
211
+ };
212
+ return brandMap[brand.toLowerCase()] || brand;
213
+ }
214
+ _chunk7QVYU63Ejs.__name.call(void 0, getCardBrandIcon, "getCardBrandIcon");
215
+ function PaymentMethodSummaryCard({
216
+ paymentMethods,
217
+ defaultPaymentMethodId,
218
+ loading,
219
+ error,
220
+ onManageClick
221
+ }) {
222
+ if (loading) {
223
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
224
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
225
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Payment Method" }),
226
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Wallet, { className: "h-4 w-4 text-muted-foreground" })
227
+ ] }),
228
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { children: [
229
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-6 w-32 mb-2" }),
230
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-24" })
231
+ ] })
232
+ ] });
233
+ }
234
+ if (error) {
235
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
236
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
237
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Payment Method" }),
238
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Wallet, { className: "h-4 w-4 text-muted-foreground" })
239
+ ] }),
240
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
241
+ ] });
242
+ }
243
+ const defaultMethod = paymentMethods.find((pm) => pm.id === defaultPaymentMethodId) || paymentMethods[0];
244
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { className: "cursor-pointer hover:bg-accent/50 transition-colors", onClick: onManageClick, children: [
245
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
246
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Payment Method" }),
247
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Wallet, { className: "h-4 w-4 text-muted-foreground" })
248
+ ] }),
249
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: paymentMethods.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
250
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "No payment method" }),
251
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "Add a card to enable subscriptions" }),
252
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", size: "sm", className: "mt-2", onClick: (e) => {
253
+ e.stopPropagation();
254
+ onManageClick();
255
+ }, children: [
256
+ "Add Card",
257
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronRight, { className: "h-4 w-4 ml-1" })
258
+ ] })
259
+ ] }) : _optionalChain([defaultMethod, 'optionalAccess', _16 => _16.card]) ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
260
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-xl font-bold", children: [
261
+ getCardBrandIcon(defaultMethod.card.brand),
262
+ " ****",
263
+ defaultMethod.card.last4
264
+ ] }),
265
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-muted-foreground", children: [
266
+ "Expires ",
267
+ String(defaultMethod.card.expMonth).padStart(2, "0"),
268
+ "/",
269
+ defaultMethod.card.expYear
270
+ ] }),
271
+ paymentMethods.length > 1 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-xs text-muted-foreground", children: [
272
+ "+",
273
+ paymentMethods.length - 1,
274
+ " more card(s)"
275
+ ] })
276
+ ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
277
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold", children: _optionalChain([defaultMethod, 'optionalAccess', _17 => _17.type]) || "Payment Method" }),
278
+ paymentMethods.length > 1 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-xs text-muted-foreground", children: [
279
+ "+",
280
+ paymentMethods.length - 1,
281
+ " more method(s)"
282
+ ] })
283
+ ] }) })
284
+ ] });
285
+ }
286
+ _chunk7QVYU63Ejs.__name.call(void 0, PaymentMethodSummaryCard, "PaymentMethodSummaryCard");
287
+
288
+ // src/features/billing/components/cards/CustomerInfoCard.tsx
289
+
290
+ var _react = require('react');
291
+
292
+ function formatBalance(balance, currency) {
293
+ if (balance === void 0 || balance === 0) return "$0.00";
294
+ const currencyCode = _optionalChain([currency, 'optionalAccess', _18 => _18.toUpperCase, 'call', _19 => _19()]) || "USD";
295
+ const displayBalance = -balance;
296
+ return new Intl.NumberFormat(void 0, {
297
+ style: "currency",
298
+ currency: currencyCode
299
+ }).format(displayBalance / 100);
300
+ }
301
+ _chunk7QVYU63Ejs.__name.call(void 0, formatBalance, "formatBalance");
302
+ function CustomerInfoCard({ customer, loading, error }) {
303
+ const [portalLoading, setPortalLoading] = _react.useState.call(void 0, false);
304
+ const handlePortalClick = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (e) => {
305
+ e.stopPropagation();
306
+ setPortalLoading(true);
307
+ try {
308
+ const { url } = await _chunkNQVPCNRSjs.StripeCustomerService.createPortalSession();
309
+ window.open(url, "_blank");
310
+ } catch (err) {
311
+ console.error("[CustomerInfoCard] Failed to create portal session:", err);
312
+ } finally {
313
+ setPortalLoading(false);
314
+ }
315
+ }, "handlePortalClick");
316
+ if (loading) {
317
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
318
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
319
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Billing Account" }),
320
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.User, { className: "h-4 w-4 text-muted-foreground" })
321
+ ] }),
322
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { children: [
323
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-6 w-32 mb-2" }),
324
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-48 mb-1" }),
325
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-24" })
326
+ ] })
327
+ ] });
328
+ }
329
+ if (error) {
330
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
331
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
332
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Billing Account" }),
333
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.User, { className: "h-4 w-4 text-muted-foreground" })
334
+ ] }),
335
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
336
+ ] });
337
+ }
338
+ if (!customer) {
339
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
340
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
341
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Billing Account" }),
342
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.User, { className: "h-4 w-4 text-muted-foreground" })
343
+ ] }),
344
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { children: [
345
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "Not set up" }),
346
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "Billing account will be created when you subscribe" })
347
+ ] })
348
+ ] });
349
+ }
350
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
351
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
352
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Billing Account" }),
353
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.User, { className: "h-4 w-4 text-muted-foreground" })
354
+ ] }),
355
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
356
+ customer.name && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold", children: customer.name }),
357
+ customer.email && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: customer.email }),
358
+ customer.balance !== void 0 && customer.balance !== 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm", children: [
359
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-muted-foreground", children: "Credit Balance: " }),
360
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: customer.balance < 0 ? "text-green-600" : "text-destructive", children: formatBalance(customer.balance, customer.currency) })
361
+ ] }),
362
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", size: "sm", className: "mt-2", onClick: handlePortalClick, disabled: portalLoading, children: [
363
+ portalLoading ? "Loading..." : "Manage in Stripe Portal",
364
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ExternalLink, { className: "h-4 w-4 ml-1" })
365
+ ] })
366
+ ] }) })
367
+ ] });
368
+ }
369
+ _chunk7QVYU63Ejs.__name.call(void 0, CustomerInfoCard, "CustomerInfoCard");
370
+
371
+ // src/features/billing/components/cards/InvoicesSummaryCard.tsx
372
+
373
+
374
+ function getStatusBadgeVariant2(status) {
375
+ switch (status) {
376
+ case "paid" /* PAID */:
377
+ return "default";
378
+ case "open" /* OPEN */:
379
+ return "secondary";
380
+ case "uncollectible" /* UNCOLLECTIBLE */:
381
+ case "void" /* VOID */:
382
+ return "destructive";
383
+ default:
384
+ return "outline";
385
+ }
386
+ }
387
+ _chunk7QVYU63Ejs.__name.call(void 0, getStatusBadgeVariant2, "getStatusBadgeVariant");
388
+ function formatDate2(date) {
389
+ return new Date(date).toLocaleDateString(void 0, {
390
+ year: "numeric",
391
+ month: "short",
392
+ day: "numeric"
393
+ });
394
+ }
395
+ _chunk7QVYU63Ejs.__name.call(void 0, formatDate2, "formatDate");
396
+ function formatAmount(amount, currency) {
397
+ const currencyCode = _optionalChain([currency, 'optionalAccess', _20 => _20.toUpperCase, 'call', _21 => _21()]) || "USD";
398
+ return new Intl.NumberFormat(void 0, {
399
+ style: "currency",
400
+ currency: currencyCode
401
+ }).format(amount / 100);
402
+ }
403
+ _chunk7QVYU63Ejs.__name.call(void 0, formatAmount, "formatAmount");
404
+ function InvoicesSummaryCard({ invoices, loading, error, onViewAllClick }) {
405
+ if (loading) {
406
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
407
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
408
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Recent Invoices" }),
409
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ReceiptIcon, { className: "h-4 w-4 text-muted-foreground" })
410
+ ] }),
411
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { children: [
412
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-6 w-24 mb-2" }),
413
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-32 mb-1" }),
414
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-20" })
415
+ ] })
416
+ ] });
417
+ }
418
+ if (error) {
419
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
420
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
421
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Recent Invoices" }),
422
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ReceiptIcon, { className: "h-4 w-4 text-muted-foreground" })
423
+ ] }),
424
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
425
+ ] });
426
+ }
427
+ const latestInvoice = invoices[0];
428
+ const paidInvoices = invoices.filter((inv) => inv.status === "paid" /* PAID */);
429
+ const openInvoices = invoices.filter((inv) => inv.status === "open" /* OPEN */);
430
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { className: "cursor-pointer hover:bg-accent/50 transition-colors", onClick: onViewAllClick, children: [
431
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
432
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Recent Invoices" }),
433
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ReceiptIcon, { className: "h-4 w-4 text-muted-foreground" })
434
+ ] }),
435
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: invoices.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
436
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "No invoices yet" }),
437
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "Invoices will appear after your first billing cycle" })
438
+ ] }) : latestInvoice ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
439
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
440
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold", children: formatAmount(latestInvoice.total, latestInvoice.currency) }),
441
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Badge, { variant: getStatusBadgeVariant2(latestInvoice.status), children: latestInvoice.status })
442
+ ] }),
443
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: latestInvoice.stripeInvoiceNumber || `Invoice from ${formatDate2(latestInvoice.periodStart)}` }),
444
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-4 text-xs text-muted-foreground", children: [
445
+ paidInvoices.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { children: [
446
+ paidInvoices.length,
447
+ " paid"
448
+ ] }),
449
+ openInvoices.length > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "text-orange-600", children: [
450
+ openInvoices.length,
451
+ " open"
452
+ ] }),
453
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex items-center", children: [
454
+ "View all",
455
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronRight, { className: "h-3 w-3 ml-1" })
456
+ ] })
457
+ ] })
458
+ ] }) : null })
459
+ ] });
460
+ }
461
+ _chunk7QVYU63Ejs.__name.call(void 0, InvoicesSummaryCard, "InvoicesSummaryCard");
462
+
463
+ // src/features/billing/components/cards/BillingUsageSummaryCard.tsx
464
+
465
+
466
+ function formatNumber(value) {
467
+ return new Intl.NumberFormat(void 0, {
468
+ notation: "compact",
469
+ compactDisplay: "short"
470
+ }).format(value);
471
+ }
472
+ _chunk7QVYU63Ejs.__name.call(void 0, formatNumber, "formatNumber");
473
+ function BillingUsageSummaryCard({
474
+ meters,
475
+ summaries,
476
+ loading,
477
+ error,
478
+ onViewDetailsClick
479
+ }) {
480
+ if (loading) {
481
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
482
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
483
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Usage This Month" }),
484
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "h-4 w-4 text-muted-foreground" })
485
+ ] }),
486
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { children: [
487
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-6 w-24 mb-2" }),
488
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-32" })
489
+ ] })
490
+ ] });
491
+ }
492
+ if (error) {
493
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
494
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
495
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Usage This Month" }),
496
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "h-4 w-4 text-muted-foreground" })
497
+ ] }),
498
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
499
+ ] });
500
+ }
501
+ const totalUsage = Object.values(summaries).reduce((acc, summary) => {
502
+ return acc + (_optionalChain([summary, 'optionalAccess', _22 => _22.aggregatedValue]) || 0);
503
+ }, 0);
504
+ const primaryMeter = meters.find((m) => _optionalChain([summaries, 'access', _23 => _23[m.id], 'optionalAccess', _24 => _24.aggregatedValue]));
505
+ const primarySummary = primaryMeter ? summaries[primaryMeter.id] : null;
506
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { className: "cursor-pointer hover:bg-accent/50 transition-colors", onClick: onViewDetailsClick, children: [
507
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
508
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { className: "text-sm font-medium", children: "Usage This Month" }),
509
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "h-4 w-4 text-muted-foreground" })
510
+ ] }),
511
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: meters.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
512
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "No meters" }),
513
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "No usage meters are configured" })
514
+ ] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
515
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-xl font-bold", children: [
516
+ formatNumber(totalUsage),
517
+ " units"
518
+ ] }),
519
+ primaryMeter && primarySummary && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-muted-foreground", children: [
520
+ primaryMeter.displayName,
521
+ ": ",
522
+ formatNumber(primarySummary.aggregatedValue)
523
+ ] }),
524
+ meters.length > 1 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-xs text-muted-foreground", children: [
525
+ "Across ",
526
+ meters.length,
527
+ " meters"
528
+ ] }),
529
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "flex items-center text-xs text-muted-foreground", children: [
530
+ "View details",
531
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronRight, { className: "h-3 w-3 ml-1" })
532
+ ] })
533
+ ] }) })
534
+ ] });
535
+ }
536
+ _chunk7QVYU63Ejs.__name.call(void 0, BillingUsageSummaryCard, "BillingUsageSummaryCard");
537
+
538
+ // src/features/billing/components/containers/BillingDashboardContainer.tsx
539
+
540
+
541
+
542
+ // src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx
543
+
544
+
545
+
546
+ // src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx
547
+ var _reactstripejs = require('@stripe/react-stripe-js');
548
+
549
+
550
+ function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
551
+ const stripe = _reactstripejs.useStripe.call(void 0, );
552
+ const elements = _reactstripejs.useElements.call(void 0, );
553
+ const [setupIntent, setSetupIntent] = _react.useState.call(void 0, null);
554
+ const [loading, setLoading] = _react.useState.call(void 0, true);
555
+ const [isSubmitting, setIsSubmitting] = _react.useState.call(void 0, false);
556
+ const [error, setError] = _react.useState.call(void 0, null);
557
+ const [setAsDefault, setSetAsDefault] = _react.useState.call(void 0, true);
558
+ _react.useEffect.call(void 0, () => {
559
+ const fetchSetupIntent = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
560
+ setLoading(true);
561
+ try {
562
+ const intent = await _chunkNQVPCNRSjs.StripeCustomerService.createSetupIntent();
563
+ setSetupIntent(intent);
564
+ } catch (err) {
565
+ console.error("[PaymentMethodEditor] Failed to create setup intent:", err);
566
+ setError("Failed to initialize payment form. Please try again.");
567
+ } finally {
568
+ setLoading(false);
569
+ }
570
+ }, "fetchSetupIntent");
571
+ if (open) {
572
+ fetchSetupIntent();
573
+ }
574
+ }, [open]);
575
+ const handleSubmit = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (e) => {
576
+ e.preventDefault();
577
+ if (!stripe || !elements || !setupIntent) {
578
+ return;
579
+ }
580
+ setIsSubmitting(true);
581
+ setError(null);
582
+ try {
583
+ const cardElement = elements.getElement(_reactstripejs.CardElement);
584
+ if (!cardElement) {
585
+ throw new Error("Card element not found");
586
+ }
587
+ const { error: stripeError, setupIntent: confirmedSetupIntent } = await stripe.confirmCardSetup(
588
+ setupIntent.clientSecret,
589
+ {
590
+ payment_method: {
591
+ card: cardElement
592
+ }
593
+ }
594
+ );
595
+ if (stripeError) {
596
+ console.error("[PaymentMethodEditor] Stripe error:", stripeError);
597
+ setError(stripeError.message || "Failed to add payment method. Please check your card details.");
598
+ setIsSubmitting(false);
599
+ return;
600
+ }
601
+ if (setAsDefault && _optionalChain([confirmedSetupIntent, 'optionalAccess', _25 => _25.payment_method])) {
602
+ await _chunkNQVPCNRSjs.StripeCustomerService.setDefaultPaymentMethod({
603
+ paymentMethodId: typeof confirmedSetupIntent.payment_method === "string" ? confirmedSetupIntent.payment_method : confirmedSetupIntent.payment_method.id
604
+ });
605
+ }
606
+ onSuccess();
607
+ onOpenChange(false);
608
+ } catch (err) {
609
+ console.error("[PaymentMethodEditor] Error:", err);
610
+ setError(err.message || "An unexpected error occurred. Please try again.");
611
+ } finally {
612
+ setIsSubmitting(false);
613
+ }
614
+ }, "handleSubmit");
615
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogContent, { className: "max-w-md", children: [
616
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogHeader, { children: [
617
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogTitle, { children: "Add Payment Method" }),
618
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogDescription, { children: "Add a new payment method to your account. Your card information is securely processed by Stripe." })
619
+ ] }),
620
+ loading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground", children: "Loading payment form..." }) }),
621
+ !loading && setupIntent && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: handleSubmit, className: "flex flex-col gap-y-4", children: [
622
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rounded-md border border-gray-300 p-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
623
+ _reactstripejs.CardElement,
624
+ {
625
+ options: {
626
+ style: {
627
+ base: {
628
+ fontSize: "16px",
629
+ color: "#424770",
630
+ "::placeholder": {
631
+ color: "#aab7c4"
632
+ }
633
+ },
634
+ invalid: {
635
+ color: "#9e2146"
636
+ }
637
+ }
638
+ }
639
+ }
640
+ ) }),
641
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-2", children: [
642
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
643
+ _chunkILKUML3Zjs.Checkbox,
644
+ {
645
+ id: "setAsDefault",
646
+ checked: setAsDefault,
647
+ onCheckedChange: (checked) => setSetAsDefault(!!checked)
648
+ }
649
+ ),
650
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Label, { htmlFor: "setAsDefault", className: "text-sm font-normal", children: "Set as default payment method" })
651
+ ] }),
652
+ error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDescription, { children: error }) }),
653
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-x-2", children: [
654
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isSubmitting, children: "Cancel" }),
655
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { type: "submit", disabled: !stripe || isSubmitting, children: isSubmitting ? "Processing..." : "Add Card" })
656
+ ] })
657
+ ] }),
658
+ !loading && !setupIntent && error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDescription, { children: error }) })
659
+ ] }) });
660
+ }
661
+ _chunk7QVYU63Ejs.__name.call(void 0, PaymentMethodEditor, "PaymentMethodEditor");
662
+
663
+ // src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx
664
+
665
+
666
+
667
+ var brandIcons = {
668
+ visa: "\u{1F4B3}",
669
+ mastercard: "\u{1F4B3}",
670
+ amex: "\u{1F4B3}",
671
+ discover: "\u{1F4B3}"
672
+ };
673
+ function PaymentMethodCard({ paymentMethod, onUpdate }) {
674
+ const [loading, setLoading] = _react.useState.call(void 0, false);
675
+ const [customer, setCustomer] = _react.useState.call(void 0, null);
676
+ const [showRemoveDialog, setShowRemoveDialog] = _react.useState.call(void 0, false);
677
+ _react.useEffect.call(void 0, () => {
678
+ const loadCustomer = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
679
+ try {
680
+ const fetchedCustomer = await _chunkNQVPCNRSjs.StripeCustomerService.getCustomer();
681
+ setCustomer(fetchedCustomer);
682
+ } catch (error) {
683
+ console.error("[PaymentMethodCard] Failed to load customer:", error);
684
+ }
685
+ }, "loadCustomer");
686
+ loadCustomer();
687
+ }, []);
688
+ const isDefault = _optionalChain([customer, 'optionalAccess', _26 => _26.defaultPaymentMethodId]) === paymentMethod.id;
689
+ const brand = _optionalChain([paymentMethod, 'access', _27 => _27.card, 'optionalAccess', _28 => _28.brand]) || "card";
690
+ const last4 = _optionalChain([paymentMethod, 'access', _29 => _29.card, 'optionalAccess', _30 => _30.last4]) || "****";
691
+ const expMonth = _optionalChain([paymentMethod, 'access', _31 => _31.card, 'optionalAccess', _32 => _32.expMonth]) || 0;
692
+ const expYear = _optionalChain([paymentMethod, 'access', _33 => _33.card, 'optionalAccess', _34 => _34.expYear]) || 0;
693
+ const brandIcon = brandIcons[brand.toLowerCase()] || "\u{1F4B3}";
694
+ const handleSetDefault = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
695
+ setLoading(true);
696
+ try {
697
+ await _chunkNQVPCNRSjs.StripeCustomerService.setDefaultPaymentMethod({ paymentMethodId: paymentMethod.id });
698
+ onUpdate();
699
+ } catch (error) {
700
+ console.error("[PaymentMethodCard] Failed to set as default:", error);
701
+ } finally {
702
+ setLoading(false);
703
+ }
704
+ }, "handleSetDefault");
705
+ const handleRemove = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
706
+ setLoading(true);
707
+ try {
708
+ await _chunkNQVPCNRSjs.StripeCustomerService.removePaymentMethod({ paymentMethodId: paymentMethod.id });
709
+ setShowRemoveDialog(false);
710
+ onUpdate();
711
+ } catch (error) {
712
+ console.error("[PaymentMethodCard] Failed to remove:", error);
713
+ setLoading(false);
714
+ }
715
+ }, "handleRemove");
716
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
717
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { className: "relative", children: [
718
+ isDefault && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Badge, { className: "absolute right-2 top-2 bg-green-100 text-green-800 hover:bg-green-100", children: "Default" }),
719
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center justify-between pb-2", children: [
720
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-2", children: [
721
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-2xl", children: brandIcon }),
722
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium capitalize", children: brand })
723
+ ] }),
724
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DropdownMenu, { children: [
725
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DropdownMenuTrigger, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { render: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", {}), nativeButton: false, variant: "ghost", size: "sm", disabled: loading, className: "h-8 w-8 p-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.MoreVertical, { className: "h-4 w-4" }) }) }),
726
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DropdownMenuContent, { align: "end", children: [
727
+ !isDefault && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DropdownMenuItem, { onClick: handleSetDefault, disabled: loading, children: "Set as Default" }),
728
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DropdownMenuItem, { onClick: () => setShowRemoveDialog(true), disabled: loading, className: "text-red-600", children: "Remove" })
729
+ ] })
730
+ ] })
731
+ ] }),
732
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-y-1", children: [
733
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-lg font-semibold", children: [
734
+ "\u2022\u2022\u2022\u2022 ",
735
+ last4
736
+ ] }),
737
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-muted-foreground", children: [
738
+ "Expires ",
739
+ String(expMonth).padStart(2, "0"),
740
+ "/",
741
+ expYear
742
+ ] })
743
+ ] }) })
744
+ ] }),
745
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialog, { open: showRemoveDialog, onOpenChange: setShowRemoveDialog, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogContent, { children: [
746
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogHeader, { children: [
747
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogTitle, { children: "Remove Payment Method" }),
748
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogDescription, { children: [
749
+ "Are you sure you want to remove this payment method? This action cannot be undone.",
750
+ isDefault && " This is your default payment method."
751
+ ] })
752
+ ] }),
753
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogFooter, { children: [
754
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogCancel, { disabled: loading, children: "Cancel" }),
755
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogAction, { onClick: handleRemove, disabled: loading, className: "bg-red-600 hover:bg-red-700", children: loading ? "Removing..." : "Remove" })
756
+ ] })
757
+ ] }) })
758
+ ] });
759
+ }
760
+ _chunk7QVYU63Ejs.__name.call(void 0, PaymentMethodCard, "PaymentMethodCard");
761
+
762
+ // src/features/billing/stripe-customer/components/lists/PaymentMethodsList.tsx
763
+
764
+ function PaymentMethodsList({ paymentMethods, onUpdate }) {
765
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3", children: paymentMethods.map((paymentMethod) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PaymentMethodCard, { paymentMethod, onUpdate }, paymentMethod.id)) });
766
+ }
767
+ _chunk7QVYU63Ejs.__name.call(void 0, PaymentMethodsList, "PaymentMethodsList");
768
+
769
+ // src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx
770
+
771
+ function PaymentMethodsContainer() {
772
+ const [paymentMethods, setPaymentMethods] = _react.useState.call(void 0, []);
773
+ const [loading, setLoading] = _react.useState.call(void 0, true);
774
+ const [showAddPaymentMethod, setShowAddPaymentMethod] = _react.useState.call(void 0, false);
775
+ const loadPaymentMethods = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
776
+ setLoading(true);
777
+ try {
778
+ const fetchedPaymentMethods = await _chunkNQVPCNRSjs.StripeCustomerService.listPaymentMethods();
779
+ setPaymentMethods(fetchedPaymentMethods);
780
+ } catch (error) {
781
+ console.error("[PaymentMethodsContainer] Failed to load payment methods:", error);
782
+ } finally {
783
+ setLoading(false);
784
+ }
785
+ }, "loadPaymentMethods");
786
+ _react.useEffect.call(void 0, () => {
787
+ loadPaymentMethods();
788
+ }, []);
789
+ if (loading) {
790
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground", children: "Loading payment methods..." }) });
791
+ }
792
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-y-6", children: [
793
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between", children: [
794
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
795
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-8 w-8" }),
796
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Payment Methods" })
797
+ ] }),
798
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { onClick: () => setShowAddPaymentMethod(true), children: "Add Payment Method" })
799
+ ] }),
800
+ paymentMethods.length === 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 bg-muted/50 p-12", children: [
801
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-16 w-16 text-muted-foreground" }),
802
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
803
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-2 text-xl font-semibold", children: "No payment methods" }),
804
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-4 text-muted-foreground", children: "Add a payment method to enable subscriptions and secure checkout." }),
805
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { onClick: () => setShowAddPaymentMethod(true), children: "Add Your First Card" })
806
+ ] })
807
+ ] }),
808
+ paymentMethods.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PaymentMethodsList, { paymentMethods, onUpdate: loadPaymentMethods }),
809
+ showAddPaymentMethod && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
810
+ PaymentMethodEditor,
811
+ {
812
+ open: showAddPaymentMethod,
813
+ onOpenChange: setShowAddPaymentMethod,
814
+ onSuccess: loadPaymentMethods
815
+ }
816
+ )
817
+ ] });
818
+ }
819
+ _chunk7QVYU63Ejs.__name.call(void 0, PaymentMethodsContainer, "PaymentMethodsContainer");
820
+
821
+ // src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx
822
+
823
+
824
+ // src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx
825
+
826
+
827
+ // src/features/billing/components/utils/currency.ts
828
+ function formatInterval(price) {
829
+ if (price.priceType === "one_time" || !price.recurring) {
830
+ return "one-time";
831
+ }
832
+ const { interval, intervalCount } = price.recurring;
833
+ if (intervalCount === 1) {
834
+ return `/${interval}`;
835
+ }
836
+ const pluralInterval = interval === "day" ? "days" : interval === "week" ? "weeks" : interval === "month" ? "months" : "years";
837
+ return `/${intervalCount} ${pluralInterval}`;
838
+ }
839
+ _chunk7QVYU63Ejs.__name.call(void 0, formatInterval, "formatInterval");
840
+ function formatCurrency(amount, currency) {
841
+ if (amount === void 0) return "$0.00";
842
+ const dollars = amount / 100;
843
+ try {
844
+ return new Intl.NumberFormat("en-US", {
845
+ style: "currency",
846
+ currency: currency.toUpperCase(),
847
+ minimumFractionDigits: 2,
848
+ maximumFractionDigits: 2
849
+ }).format(dollars);
850
+ } catch (error) {
851
+ console.error("Error formatting currency:", error);
852
+ return `$${dollars.toFixed(2)}`;
853
+ }
854
+ }
855
+ _chunk7QVYU63Ejs.__name.call(void 0, formatCurrency, "formatCurrency");
856
+
857
+ // src/features/billing/components/utils/date.ts
858
+ function formatDate3(date) {
859
+ if (!date) return "N/A";
860
+ const dateObj = typeof date === "string" ? new Date(date) : date;
861
+ try {
862
+ return new Intl.DateTimeFormat("en-US", {
863
+ month: "short",
864
+ day: "numeric",
865
+ year: "numeric"
866
+ }).format(dateObj);
867
+ } catch (error) {
868
+ console.error("Error formatting date:", error);
869
+ return "Invalid Date";
870
+ }
871
+ }
872
+ _chunk7QVYU63Ejs.__name.call(void 0, formatDate3, "formatDate");
873
+
874
+ // src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx
875
+
876
+
877
+ // src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx
878
+
879
+ var statusConfig = {
880
+ ["draft" /* DRAFT */]: {
881
+ label: "Draft",
882
+ color: "bg-gray-100 text-gray-800"
883
+ },
884
+ ["open" /* OPEN */]: {
885
+ label: "Open",
886
+ color: "bg-blue-100 text-blue-800"
887
+ },
888
+ ["paid" /* PAID */]: {
889
+ label: "Paid",
890
+ color: "bg-green-100 text-green-800"
891
+ },
892
+ ["void" /* VOID */]: {
893
+ label: "Void",
894
+ color: "bg-gray-100 text-gray-800"
895
+ },
896
+ ["uncollectible" /* UNCOLLECTIBLE */]: {
897
+ label: "Uncollectible",
898
+ color: "bg-red-100 text-red-800"
899
+ }
900
+ };
901
+ function InvoiceStatusBadge({ status }) {
902
+ const config = statusConfig[status] || statusConfig["draft" /* DRAFT */];
903
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `${config.color} text-xs px-2 py-1 rounded-full font-medium`, children: config.label });
904
+ }
905
+ _chunk7QVYU63Ejs.__name.call(void 0, InvoiceStatusBadge, "InvoiceStatusBadge");
906
+
907
+ // src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx
908
+
909
+ function InvoiceDetails({ invoice, open, onOpenChange, onInvoiceChange }) {
910
+ const handleDownloadPDF = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
911
+ if (invoice.stripePdfUrl) {
912
+ window.open(invoice.stripePdfUrl, "_blank");
913
+ }
914
+ }, "handleDownloadPDF");
915
+ const handleRetryPayment = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
916
+ }, "handleRetryPayment");
917
+ const handleViewInStripe = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
918
+ if (invoice.stripeHostedInvoiceUrl) {
919
+ window.open(invoice.stripeHostedInvoiceUrl, "_blank");
920
+ }
921
+ }, "handleViewInStripe");
922
+ const getInvoiceNumber = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
923
+ if (invoice.stripeInvoiceNumber) {
924
+ return invoice.stripeInvoiceNumber;
925
+ }
926
+ return invoice.stripeInvoiceId.slice(-8);
927
+ }, "getInvoiceNumber");
928
+ const productName = _optionalChain([invoice, 'access', _35 => _35.subscription, 'optionalAccess', _36 => _36.price, 'optionalAccess', _37 => _37.product, 'optionalAccess', _38 => _38.name]) || "Subscription";
929
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogContent, { className: "max-w-2xl", children: [
930
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogHeader, { children: [
931
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogTitle, { children: [
932
+ "Invoice ",
933
+ getInvoiceNumber()
934
+ ] }),
935
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogDescription, { children: formatDate3(invoice.periodStart) })
936
+ ] }),
937
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
938
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
939
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Status:" }),
940
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InvoiceStatusBadge, { status: invoice.status })
941
+ ] }),
942
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-4", children: [
943
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
944
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Billing Period:" }),
945
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "font-medium", children: [
946
+ formatDate3(invoice.periodStart),
947
+ " - ",
948
+ formatDate3(invoice.periodEnd)
949
+ ] })
950
+ ] }),
951
+ invoice.dueDate && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
952
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Due Date:" }),
953
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium", children: formatDate3(invoice.dueDate) })
954
+ ] }),
955
+ invoice.paidAt && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
956
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Paid Date:" }),
957
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium", children: formatDate3(invoice.paidAt) })
958
+ ] }),
959
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
960
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Attempt Count:" }),
961
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium", children: invoice.attemptCount })
962
+ ] })
963
+ ] }),
964
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
965
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "text-sm font-medium text-muted-foreground mb-2", children: "Line Items" }),
966
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { className: "w-full", children: [
967
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { className: "bg-muted", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
968
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: "text-left p-3 text-sm font-medium", children: "Description" }),
969
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { className: "text-right p-3 text-sm font-medium", children: "Amount" })
970
+ ] }) }),
971
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tbody", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { className: "border-t", children: [
972
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: "p-3", children: productName }),
973
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { className: "p-3 text-right", children: formatCurrency(invoice.subtotal, invoice.currency) })
974
+ ] }) })
975
+ ] }) })
976
+ ] }),
977
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2 border-t pt-4", children: [
978
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between", children: [
979
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Subtotal:" }),
980
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium", children: formatCurrency(invoice.subtotal, invoice.currency) })
981
+ ] }),
982
+ invoice.tax !== void 0 && invoice.tax > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between", children: [
983
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Tax:" }),
984
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium", children: formatCurrency(invoice.tax, invoice.currency) })
985
+ ] }),
986
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between text-lg font-semibold border-t pt-2", children: [
987
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Total:" }),
988
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: formatCurrency(invoice.total, invoice.currency) })
989
+ ] }),
990
+ invoice.amountPaid > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between", children: [
991
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Amount Paid:" }),
992
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-green-600", children: formatCurrency(invoice.amountPaid, invoice.currency) })
993
+ ] }),
994
+ invoice.amountRemaining > 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between", children: [
995
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Amount Due:" }),
996
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-red-600", children: formatCurrency(invoice.amountRemaining, invoice.currency) })
997
+ ] })
998
+ ] }),
999
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap gap-2 pt-4 border-t", children: [
1000
+ invoice.stripePdfUrl && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", onClick: handleDownloadPDF, children: [
1001
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Download, { className: "mr-2 h-4 w-4" }),
1002
+ "Download PDF"
1003
+ ] }),
1004
+ invoice.status === "open" /* OPEN */ && invoice.attempted && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Button, { variant: "default", onClick: handleRetryPayment, children: [
1005
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.RefreshCw, { className: "mr-2 h-4 w-4" }),
1006
+ "Retry Payment"
1007
+ ] }),
1008
+ invoice.stripeHostedInvoiceUrl && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", onClick: handleViewInStripe, children: [
1009
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ExternalLink, { className: "mr-2 h-4 w-4" }),
1010
+ "View in Stripe"
1011
+ ] })
1012
+ ] })
1013
+ ] })
1014
+ ] }) });
1015
+ }
1016
+ _chunk7QVYU63Ejs.__name.call(void 0, InvoiceDetails, "InvoiceDetails");
1017
+
1018
+ // src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx
1019
+
1020
+ function InvoicesList({ invoices, onInvoicesChange }) {
1021
+ const [selectedInvoice, setSelectedInvoice] = _react.useState.call(void 0, null);
1022
+ const handleRowClick = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (invoice) => {
1023
+ setSelectedInvoice(invoice);
1024
+ }, "handleRowClick");
1025
+ const getInvoiceNumber = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (invoice) => {
1026
+ if (invoice.stripeInvoiceNumber) {
1027
+ return invoice.stripeInvoiceNumber;
1028
+ }
1029
+ return invoice.stripeInvoiceId.slice(-8);
1030
+ }, "getInvoiceNumber");
1031
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1032
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Table, { children: [
1033
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHeader, { className: "bg-muted", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.TableRow, { children: [
1034
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Invoice #" }),
1035
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Date" }),
1036
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Status" }),
1037
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { className: "text-right", children: "Amount" }),
1038
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Period" })
1039
+ ] }) }),
1040
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableBody, { children: invoices.map((invoice) => {
1041
+ const invoiceNumber = getInvoiceNumber(invoice);
1042
+ const date = formatDate3(invoice.periodStart);
1043
+ const amount = formatCurrency(invoice.total, invoice.currency);
1044
+ const period = `${formatDate3(invoice.periodStart)} - ${formatDate3(invoice.periodEnd)}`;
1045
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1046
+ _chunkILKUML3Zjs.TableRow,
1047
+ {
1048
+ onClick: () => handleRowClick(invoice),
1049
+ className: "cursor-pointer hover:bg-muted/50",
1050
+ children: [
1051
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "font-medium", children: invoiceNumber }),
1052
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "text-muted-foreground text-sm", children: date }),
1053
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InvoiceStatusBadge, { status: invoice.status }) }),
1054
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "text-right font-medium", children: amount }),
1055
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "text-muted-foreground text-sm", children: period })
1056
+ ]
1057
+ },
1058
+ invoice.id
1059
+ );
1060
+ }) })
1061
+ ] }) }),
1062
+ selectedInvoice && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1063
+ InvoiceDetails,
1064
+ {
1065
+ invoice: selectedInvoice,
1066
+ open: !!selectedInvoice,
1067
+ onOpenChange: (open) => !open && setSelectedInvoice(null),
1068
+ onInvoiceChange: () => {
1069
+ onInvoicesChange();
1070
+ setSelectedInvoice(null);
1071
+ }
1072
+ }
1073
+ )
1074
+ ] });
1075
+ }
1076
+ _chunk7QVYU63Ejs.__name.call(void 0, InvoicesList, "InvoicesList");
1077
+
1078
+ // src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx
1079
+
1080
+ function InvoicesContainer() {
1081
+ const [invoices, setInvoices] = _react.useState.call(void 0, []);
1082
+ const [loading, setLoading] = _react.useState.call(void 0, true);
1083
+ const [statusFilter, setStatusFilter] = _react.useState.call(void 0, "all");
1084
+ const loadInvoices = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1085
+ setLoading(true);
1086
+ try {
1087
+ const params = statusFilter !== "all" ? { status: statusFilter } : void 0;
1088
+ const data = await _chunkNQVPCNRSjs.StripeInvoiceService.listInvoices(params);
1089
+ setInvoices(data);
1090
+ } catch (error) {
1091
+ console.error("[InvoicesContainer] Failed to load invoices:", error);
1092
+ setInvoices([]);
1093
+ } finally {
1094
+ setLoading(false);
1095
+ }
1096
+ }, "loadInvoices");
1097
+ _react.useEffect.call(void 0, () => {
1098
+ loadInvoices();
1099
+ }, [statusFilter]);
1100
+ const handleFilterChange = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (value) => {
1101
+ setStatusFilter(value);
1102
+ }, "handleFilterChange");
1103
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
1104
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Tabs, { value: statusFilter, onValueChange: handleFilterChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.TabsList, { children: [
1105
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TabsTrigger, { value: "all", children: "All" }),
1106
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TabsTrigger, { value: "paid" /* PAID */, children: "Paid" }),
1107
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TabsTrigger, { value: "open" /* OPEN */, children: "Open" }),
1108
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TabsTrigger, { value: "void" /* VOID */, children: "Void" }),
1109
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TabsTrigger, { value: "uncollectible" /* UNCOLLECTIBLE */, children: "Uncollectible" })
1110
+ ] }) }),
1111
+ loading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-center py-8 text-muted-foreground", children: "Loading invoices..." }),
1112
+ !loading && invoices.length === 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "border border-dashed border-gray-300 rounded-lg p-8 text-center", children: [
1113
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-lg font-medium text-muted-foreground mb-2", children: "No invoices yet" }),
1114
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Invoices will appear here after your first billing cycle" })
1115
+ ] }),
1116
+ !loading && invoices.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InvoicesList, { invoices, onInvoicesChange: loadInvoices })
1117
+ ] });
1118
+ }
1119
+ _chunk7QVYU63Ejs.__name.call(void 0, InvoicesContainer, "InvoicesContainer");
1120
+
1121
+ // src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx
1122
+
1123
+
1124
+ var _uuid = require('uuid');
1125
+
1126
+ // src/features/billing/stripe-subscription/hooks/useConfirmSubscriptionPayment.ts
1127
+
1128
+
1129
+ function useConfirmSubscriptionPayment() {
1130
+ const stripe = _reactstripejs.useStripe.call(void 0, );
1131
+ const [isConfirming, setIsConfirming] = _react.useState.call(void 0, false);
1132
+ const confirmPayment = _react.useCallback.call(void 0,
1133
+ async (clientSecret) => {
1134
+ if (!stripe) {
1135
+ console.error("[useConfirmSubscriptionPayment] Stripe not initialized");
1136
+ return {
1137
+ success: false,
1138
+ error: "Payment system not initialized. Please refresh the page and try again."
1139
+ };
1140
+ }
1141
+ if (!clientSecret) {
1142
+ console.error("[useConfirmSubscriptionPayment] No client secret provided");
1143
+ return {
1144
+ success: false,
1145
+ error: "Payment confirmation failed. Missing payment details."
1146
+ };
1147
+ }
1148
+ setIsConfirming(true);
1149
+ try {
1150
+ const { error: stripeError, paymentIntent } = await stripe.confirmCardPayment(clientSecret);
1151
+ if (stripeError) {
1152
+ console.error("[useConfirmSubscriptionPayment] Stripe error:", stripeError);
1153
+ return {
1154
+ success: false,
1155
+ error: stripeError.message || "Payment confirmation failed. Please try again."
1156
+ };
1157
+ }
1158
+ if (_optionalChain([paymentIntent, 'optionalAccess', _39 => _39.status]) === "succeeded") {
1159
+ return { success: true };
1160
+ }
1161
+ if (_optionalChain([paymentIntent, 'optionalAccess', _40 => _40.status]) === "requires_action") {
1162
+ return {
1163
+ success: false,
1164
+ error: "Additional authentication required. Please complete the verification."
1165
+ };
1166
+ }
1167
+ return {
1168
+ success: false,
1169
+ error: "Payment could not be completed. Please try again."
1170
+ };
1171
+ } catch (err) {
1172
+ console.error("[useConfirmSubscriptionPayment] Unexpected error:", err);
1173
+ return {
1174
+ success: false,
1175
+ error: err.message || "An unexpected error occurred during payment confirmation."
1176
+ };
1177
+ } finally {
1178
+ setIsConfirming(false);
1179
+ }
1180
+ },
1181
+ [stripe]
1182
+ );
1183
+ return {
1184
+ confirmPayment,
1185
+ isConfirming
1186
+ };
1187
+ }
1188
+ _chunk7QVYU63Ejs.__name.call(void 0, useConfirmSubscriptionPayment, "useConfirmSubscriptionPayment");
1189
+
1190
+ // src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx
1191
+ var _zod = require('@hookform/resolvers/zod');
1192
+
1193
+ var _reacthookform = require('react-hook-form');
1194
+ var _zod3 = require('zod');
1195
+
1196
+ var formSchema = _zod3.z.object({
1197
+ cancelImmediately: _zod3.z.boolean(),
1198
+ reason: _zod3.z.string().optional()
1199
+ });
1200
+ function CancelSubscriptionDialog({
1201
+ subscription,
1202
+ open,
1203
+ onOpenChange,
1204
+ onSuccess
1205
+ }) {
1206
+ const [isSubmitting, setIsSubmitting] = _react.useState.call(void 0, false);
1207
+ const form = _reacthookform.useForm.call(void 0, {
1208
+ resolver: _zod.zodResolver.call(void 0, formSchema),
1209
+ defaultValues: {
1210
+ cancelImmediately: false,
1211
+ reason: ""
1212
+ }
1213
+ });
1214
+ const cancelImmediately = form.watch("cancelImmediately");
1215
+ const onSubmit = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (values) => {
1216
+ setIsSubmitting(true);
1217
+ try {
1218
+ await _chunkNQVPCNRSjs.StripeSubscriptionService.cancelSubscription({
1219
+ id: subscription.id,
1220
+ cancelImmediately: values.cancelImmediately
1221
+ });
1222
+ onSuccess();
1223
+ onOpenChange(false);
1224
+ } catch (error) {
1225
+ console.error("[CancelSubscriptionDialog] Failed to cancel subscription:", error);
1226
+ } finally {
1227
+ setIsSubmitting(false);
1228
+ }
1229
+ }, "onSubmit");
1230
+ const periodEndDate = formatDate3(subscription.currentPeriodEnd);
1231
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogContent, { className: "max-w-md", children: [
1232
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogHeader, { children: [
1233
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogTitle, { children: "Cancel Subscription" }),
1234
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogDescription, { children: "Are you sure you want to cancel this subscription? This action cannot be undone." })
1235
+ ] }),
1236
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Form, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
1237
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.FormCheckbox, { form, id: "cancelImmediately", name: "Cancel Immediately" }),
1238
+ cancelImmediately ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-800", children: "Your subscription will be canceled immediately and you will lose access right away." }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 text-sm text-blue-800", children: [
1239
+ "Your subscription will remain active until ",
1240
+ periodEndDate,
1241
+ ". You can continue using the service until then."
1242
+ ] }),
1243
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1244
+ _chunkILKUML3Zjs.FormTextarea,
1245
+ {
1246
+ form,
1247
+ id: "reason",
1248
+ name: "Reason (Optional)",
1249
+ placeholder: "Let us know why you're canceling...",
1250
+ className: "min-h-24"
1251
+ }
1252
+ ),
1253
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-x-2 justify-end pt-2", children: [
1254
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isSubmitting, children: "Keep Subscription" }),
1255
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { type: "submit", variant: "destructive", disabled: isSubmitting, children: isSubmitting ? "Canceling..." : "Confirm Cancellation" })
1256
+ ] })
1257
+ ] }) })
1258
+ ] }) });
1259
+ }
1260
+ _chunk7QVYU63Ejs.__name.call(void 0, CancelSubscriptionDialog, "CancelSubscriptionDialog");
1261
+
1262
+ // src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx
1263
+
1264
+
1265
+
1266
+
1267
+ // src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx
1268
+
1269
+
1270
+ function PricingCard({ price, isCurrentPlan = false, isSelected = false, isDisabled = false, isLoading = false, onSelect }) {
1271
+ const description = price.description || price.nickname || "Standard";
1272
+ const features = price.features || [];
1273
+ const formattedPrice = formatCurrency(price.unitAmount, price.currency);
1274
+ const interval = formatInterval(price);
1275
+ const handleKeyDown = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (e) => {
1276
+ if ((e.key === "Enter" || e.key === " ") && !isDisabled && !isCurrentPlan) {
1277
+ e.preventDefault();
1278
+ onSelect(price);
1279
+ }
1280
+ }, "handleKeyDown");
1281
+ const handleClick = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
1282
+ if (!isDisabled && !isCurrentPlan && !isLoading) {
1283
+ onSelect(price);
1284
+ }
1285
+ }, "handleClick");
1286
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1287
+ _chunkILKUML3Zjs.Card,
1288
+ {
1289
+ role: "radio",
1290
+ "aria-checked": isSelected,
1291
+ "aria-label": `${description} plan at ${formattedPrice} ${interval}`,
1292
+ tabIndex: isDisabled ? -1 : 0,
1293
+ onKeyDown: handleKeyDown,
1294
+ onClick: handleClick,
1295
+ className: _chunkNQVPCNRSjs.cn.call(void 0,
1296
+ "relative cursor-pointer transition-all duration-200 flex flex-col h-full",
1297
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
1298
+ isCurrentPlan && "bg-muted/30",
1299
+ isSelected && !isCurrentPlan && "ring-2 ring-primary",
1300
+ !isDisabled && !isCurrentPlan && "hover:shadow-md hover:border-primary/50",
1301
+ isDisabled && "opacity-50 pointer-events-none",
1302
+ isLoading && "pointer-events-none"
1303
+ ),
1304
+ children: [
1305
+ isCurrentPlan && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Badge, { variant: "secondary", className: "absolute top-2 right-2", children: "Current" }),
1306
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "pb-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-lg", children: description }) }),
1307
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { className: "pb-4 grow", children: [
1308
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-4", children: [
1309
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-3xl font-bold", children: formattedPrice }),
1310
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-muted-foreground ml-1", children: interval })
1311
+ ] }),
1312
+ features.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "ul", { className: "space-y-2", children: features.map((feature, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { className: "flex items-start gap-2", children: [
1313
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Check, { className: "h-4 w-4 text-green-500 mt-0.5 shrink-0" }),
1314
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm text-muted-foreground", children: feature })
1315
+ ] }, index)) })
1316
+ ] }),
1317
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardFooter, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1318
+ _chunkILKUML3Zjs.Button,
1319
+ {
1320
+ variant: isCurrentPlan ? "secondary" : isSelected ? "default" : "outline",
1321
+ className: "w-full",
1322
+ disabled: isDisabled || isCurrentPlan || isLoading,
1323
+ children: isLoading ? "Processing..." : isCurrentPlan ? "Current Plan" : isSelected ? "Selected" : "Select Plan"
1324
+ }
1325
+ ) })
1326
+ ]
1327
+ }
1328
+ );
1329
+ }
1330
+ _chunk7QVYU63Ejs.__name.call(void 0, PricingCard, "PricingCard");
1331
+
1332
+ // src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx
1333
+
1334
+ function PricingCardsGrid({
1335
+ products,
1336
+ pricesByProduct,
1337
+ currentPriceId,
1338
+ selectedPriceId,
1339
+ loadingPriceId,
1340
+ loading = false,
1341
+ onSelectPrice
1342
+ }) {
1343
+ if (loading) {
1344
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PricingCardsGridSkeleton, {});
1345
+ }
1346
+ if (products.length === 0) {
1347
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-center py-8 text-muted-foreground", children: "No plans available" });
1348
+ }
1349
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-8", role: "radiogroup", "aria-label": "Available pricing plans", children: products.map((product) => {
1350
+ const prices = pricesByProduct.get(product.id) || [];
1351
+ if (prices.length === 0) return null;
1352
+ const sortedPrices = [...prices].sort((a, b) => (_nullishCoalesce(a.unitAmount, () => ( 0))) - (_nullishCoalesce(b.unitAmount, () => ( 0))));
1353
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
1354
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-lg font-semibold", children: product.name }),
1355
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: sortedPrices.map((price) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1356
+ PricingCard,
1357
+ {
1358
+ price,
1359
+ isCurrentPlan: price.stripePriceId === currentPriceId,
1360
+ isSelected: price.stripePriceId === selectedPriceId,
1361
+ isLoading: price.stripePriceId === loadingPriceId,
1362
+ onSelect: onSelectPrice
1363
+ },
1364
+ price.stripePriceId
1365
+ )) })
1366
+ ] }, product.id);
1367
+ }) });
1368
+ }
1369
+ _chunk7QVYU63Ejs.__name.call(void 0, PricingCardsGrid, "PricingCardsGrid");
1370
+ function PricingCardsGridSkeleton() {
1371
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-8", children: [1, 2].map((productIndex) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
1372
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-6 w-32" }),
1373
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: [1, 2, 3].map((cardIndex) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { className: "animate-pulse", children: [
1374
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "pb-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-5 w-24" }) }),
1375
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { className: "pb-4", children: [
1376
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-4", children: [
1377
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-9 w-20 inline-block" }),
1378
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-12 inline-block ml-2" })
1379
+ ] }),
1380
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
1381
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
1382
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-4 rounded-full" }),
1383
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-32" })
1384
+ ] }),
1385
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
1386
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-4 rounded-full" }),
1387
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-4 w-28" })
1388
+ ] })
1389
+ ] })
1390
+ ] }),
1391
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardFooter, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Skeleton, { className: "h-9 w-full" }) })
1392
+ ] }, cardIndex)) })
1393
+ ] }, productIndex)) });
1394
+ }
1395
+ _chunk7QVYU63Ejs.__name.call(void 0, PricingCardsGridSkeleton, "PricingCardsGridSkeleton");
1396
+
1397
+ // src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx
1398
+
1399
+ function ProrationPreview({ preview }) {
1400
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4", children: [
1401
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "font-semibold text-blue-900 mb-3", children: "Proration Breakdown" }),
1402
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
1403
+ preview.lineItems.map((item, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between text-sm", children: [
1404
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-800", children: item.description }),
1405
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `font-medium ${item.amount < 0 ? "text-green-600" : "text-blue-900"}`, children: formatCurrency(item.amount, preview.currency) })
1406
+ ] }, index)),
1407
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-t border-blue-200 pt-2 mt-2", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between font-semibold", children: [
1408
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-900", children: "Net Due Today" }),
1409
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-900", children: formatCurrency(preview.immediateCharge, preview.currency) })
1410
+ ] }) }),
1411
+ preview.lineItems.length > 0 && preview.lineItems[0].period && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-xs text-blue-700 mt-2", children: [
1412
+ "Next invoice on ",
1413
+ formatDate3(preview.lineItems[0].period.end),
1414
+ " for",
1415
+ " ",
1416
+ formatCurrency(preview.amountDue, preview.currency)
1417
+ ] })
1418
+ ] })
1419
+ ] });
1420
+ }
1421
+ _chunk7QVYU63Ejs.__name.call(void 0, ProrationPreview, "ProrationPreview");
1422
+
1423
+ // src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx
1424
+
1425
+ function SubscriptionEditor({
1426
+ subscription,
1427
+ open,
1428
+ onOpenChange,
1429
+ onSuccess,
1430
+ onAddPaymentMethod
1431
+ }) {
1432
+ const { confirmPayment, isConfirming } = useConfirmSubscriptionPayment();
1433
+ const [products, setProducts] = _react.useState.call(void 0, []);
1434
+ const [pricesByProduct, setPricesByProduct] = _react.useState.call(void 0, /* @__PURE__ */ new Map());
1435
+ const [loading, setLoading] = _react.useState.call(void 0, true);
1436
+ const [selectedPriceId, setSelectedPriceId] = _react.useState.call(void 0, null);
1437
+ const [loadingPriceId, setLoadingPriceId] = _react.useState.call(void 0, null);
1438
+ const [prorationPreview, setProrationPreview] = _react.useState.call(void 0, null);
1439
+ const [loadingProration, setLoadingProration] = _react.useState.call(void 0, false);
1440
+ const [hasPaymentMethod, setHasPaymentMethod] = _react.useState.call(void 0, true);
1441
+ const [loadingPaymentMethods, setLoadingPaymentMethods] = _react.useState.call(void 0, true);
1442
+ const [paymentRequiredError, setPaymentRequiredError] = _react.useState.call(void 0, false);
1443
+ const [paymentConfirmationState, setPaymentConfirmationState] = _react.useState.call(void 0, "idle");
1444
+ const [paymentError, setPaymentError] = _react.useState.call(void 0, null);
1445
+ const currentPriceId = _optionalChain([subscription, 'optionalAccess', _41 => _41.price, 'optionalAccess', _42 => _42.id]);
1446
+ const isEditMode = !!subscription;
1447
+ _react.useEffect.call(void 0, () => {
1448
+ const checkPaymentMethods = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1449
+ if (subscription) {
1450
+ setLoadingPaymentMethods(false);
1451
+ return;
1452
+ }
1453
+ setLoadingPaymentMethods(true);
1454
+ try {
1455
+ const paymentMethods = await _chunkNQVPCNRSjs.StripeCustomerService.listPaymentMethods();
1456
+ const hasMethod = paymentMethods.length > 0;
1457
+ setHasPaymentMethod(hasMethod);
1458
+ } catch (error) {
1459
+ console.error("[SubscriptionEditor] Failed to check payment methods:", error);
1460
+ setHasPaymentMethod(false);
1461
+ } finally {
1462
+ setLoadingPaymentMethods(false);
1463
+ }
1464
+ }, "checkPaymentMethods");
1465
+ if (open) {
1466
+ checkPaymentMethods();
1467
+ }
1468
+ }, [open, subscription]);
1469
+ _react.useEffect.call(void 0, () => {
1470
+ const loadData = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1471
+ setLoading(true);
1472
+ try {
1473
+ const fetchedProducts = await _chunkNQVPCNRSjs.StripeProductService.listProducts({ active: true });
1474
+ const grouped = /* @__PURE__ */ new Map();
1475
+ for (const product of fetchedProducts) {
1476
+ if (product.stripePrices && product.stripePrices.length > 0) {
1477
+ grouped.set(product.id, product.stripePrices);
1478
+ }
1479
+ }
1480
+ setProducts(fetchedProducts);
1481
+ setPricesByProduct(grouped);
1482
+ } catch (error) {
1483
+ console.error("[SubscriptionEditor] Failed to load products/prices:", error);
1484
+ } finally {
1485
+ setLoading(false);
1486
+ }
1487
+ }, "loadData");
1488
+ if (open) {
1489
+ loadData();
1490
+ }
1491
+ }, [open]);
1492
+ _react.useEffect.call(void 0, () => {
1493
+ const loadProration = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1494
+ if (!subscription || !selectedPriceId || selectedPriceId === currentPriceId) {
1495
+ setProrationPreview(null);
1496
+ return;
1497
+ }
1498
+ setLoadingProration(true);
1499
+ try {
1500
+ const preview = await _chunkNQVPCNRSjs.StripeSubscriptionService.getProrationPreview({
1501
+ subscriptionId: subscription.id,
1502
+ newPriceId: selectedPriceId
1503
+ });
1504
+ setProrationPreview(preview);
1505
+ } catch (error) {
1506
+ console.error("[SubscriptionEditor] Failed to load proration preview:", error);
1507
+ setProrationPreview(null);
1508
+ } finally {
1509
+ setLoadingProration(false);
1510
+ }
1511
+ }, "loadProration");
1512
+ loadProration();
1513
+ }, [selectedPriceId, subscription, currentPriceId]);
1514
+ const handleSelectPrice = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (price) => {
1515
+ const priceId = price.id;
1516
+ if (isEditMode) {
1517
+ setSelectedPriceId(priceId);
1518
+ } else {
1519
+ setLoadingPriceId(priceId);
1520
+ setSelectedPriceId(priceId);
1521
+ setPaymentError(null);
1522
+ setPaymentConfirmationState("idle");
1523
+ try {
1524
+ const result = await _chunkNQVPCNRSjs.StripeSubscriptionService.createSubscription({
1525
+ id: _uuid.v4.call(void 0, ),
1526
+ priceId
1527
+ });
1528
+ if (result.meta.requiresAction && result.meta.clientSecret) {
1529
+ setPaymentConfirmationState("confirming");
1530
+ const confirmation = await confirmPayment(result.meta.clientSecret);
1531
+ if (!confirmation.success) {
1532
+ console.error("[SubscriptionEditor] Payment confirmation failed:", confirmation.error);
1533
+ setPaymentConfirmationState("error");
1534
+ setPaymentError(confirmation.error || "Payment confirmation failed");
1535
+ setLoadingPriceId(null);
1536
+ return;
1537
+ }
1538
+ await _chunkNQVPCNRSjs.StripeSubscriptionService.syncSubscription({
1539
+ subscriptionId: result.subscription.id
1540
+ });
1541
+ }
1542
+ setPaymentConfirmationState("success");
1543
+ setTimeout(() => {
1544
+ onSuccess();
1545
+ onOpenChange(false);
1546
+ }, 1e3);
1547
+ } catch (error) {
1548
+ console.error("[SubscriptionEditor] Failed to create subscription:", error);
1549
+ if (_optionalChain([error, 'optionalAccess', _43 => _43.status]) === 402 || _optionalChain([error, 'optionalAccess', _44 => _44.response, 'optionalAccess', _45 => _45.status]) === 402) {
1550
+ setPaymentRequiredError(true);
1551
+ setHasPaymentMethod(false);
1552
+ } else {
1553
+ setPaymentConfirmationState("error");
1554
+ setPaymentError(_optionalChain([error, 'optionalAccess', _46 => _46.message]) || "Failed to create subscription");
1555
+ }
1556
+ setLoadingPriceId(null);
1557
+ }
1558
+ }
1559
+ }, "handleSelectPrice");
1560
+ const handleConfirmPlanChange = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1561
+ if (!subscription || !selectedPriceId) return;
1562
+ setLoadingPriceId(selectedPriceId);
1563
+ try {
1564
+ await _chunkNQVPCNRSjs.StripeSubscriptionService.changePlan({
1565
+ id: subscription.id,
1566
+ newPriceId: selectedPriceId
1567
+ });
1568
+ onSuccess();
1569
+ onOpenChange(false);
1570
+ } catch (error) {
1571
+ console.error("[SubscriptionEditor] Failed to change plan:", error);
1572
+ } finally {
1573
+ setLoadingPriceId(null);
1574
+ }
1575
+ }, "handleConfirmPlanChange");
1576
+ const handleCancel = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
1577
+ setSelectedPriceId(null);
1578
+ setProrationPreview(null);
1579
+ }, "handleCancel");
1580
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogContent, { className: "max-w-4xl max-h-[90vh] overflow-y-auto", children: [
1581
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogHeader, { children: [
1582
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogTitle, { children: subscription ? "Change Plan" : "Subscribe to a Plan" }),
1583
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogDescription, { children: subscription ? "Select a new plan to switch to. You'll see a proration preview before confirming." : "Choose a plan to start your subscription." })
1584
+ ] }),
1585
+ loadingPaymentMethods && !subscription ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-muted-foreground", children: "Checking payment methods..." }) }) : !hasPaymentMethod && !subscription ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Alert, { variant: "destructive", children: [
1586
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertTitle, { children: "Payment Method Required" }),
1587
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDescription, { className: "mt-2", children: [
1588
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-4", children: paymentRequiredError ? "Your subscription could not be created because no payment method is on file." : "You need to add a payment method before you can subscribe to a plan." }),
1589
+ onAddPaymentMethod && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { onClick: onAddPaymentMethod, variant: "outline", children: "Add Payment Method" })
1590
+ ] })
1591
+ ] }) : paymentConfirmationState === "confirming" || isConfirming ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
1592
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Loader2, { className: "h-8 w-8 animate-spin text-primary" }),
1593
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
1594
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium", children: "Processing payment..." }),
1595
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Please complete any verification if prompted." })
1596
+ ] })
1597
+ ] }) : paymentConfirmationState === "success" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
1598
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CheckCircle, { className: "h-12 w-12 text-green-500" }),
1599
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
1600
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium text-green-600", children: "Payment successful!" }),
1601
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Your subscription is now active." })
1602
+ ] })
1603
+ ] }) : paymentConfirmationState === "error" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-4", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Alert, { variant: "destructive", children: [
1604
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertTitle, { children: "Payment Failed" }),
1605
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDescription, { className: "mt-2", children: [
1606
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-4", children: paymentError || "We couldn't process your payment. Please try again." }),
1607
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1608
+ _chunkILKUML3Zjs.Button,
1609
+ {
1610
+ onClick: () => {
1611
+ setPaymentConfirmationState("idle");
1612
+ setPaymentError(null);
1613
+ setLoadingPriceId(null);
1614
+ },
1615
+ variant: "outline",
1616
+ children: "Try Again"
1617
+ }
1618
+ )
1619
+ ] })
1620
+ ] }) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
1621
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1622
+ PricingCardsGrid,
1623
+ {
1624
+ products,
1625
+ pricesByProduct,
1626
+ currentPriceId,
1627
+ selectedPriceId: _nullishCoalesce(selectedPriceId, () => ( void 0)),
1628
+ loadingPriceId: _nullishCoalesce(loadingPriceId, () => ( void 0)),
1629
+ loading,
1630
+ onSelectPrice: handleSelectPrice
1631
+ }
1632
+ ),
1633
+ isEditMode && loadingProration && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-muted/50 rounded-lg p-4 text-sm text-muted-foreground text-center", children: "Loading proration preview..." }),
1634
+ isEditMode && prorationPreview && !loadingProration && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
1635
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ProrationPreview, { preview: prorationPreview }),
1636
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-3", children: [
1637
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", onClick: handleCancel, disabled: !!loadingPriceId, children: "Cancel" }),
1638
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { onClick: handleConfirmPlanChange, disabled: !!loadingPriceId, children: loadingPriceId ? "Processing..." : "Confirm Plan Change" })
1639
+ ] })
1640
+ ] })
1641
+ ] })
1642
+ ] }) });
1643
+ }
1644
+ _chunk7QVYU63Ejs.__name.call(void 0, SubscriptionEditor, "SubscriptionEditor");
1645
+
1646
+ // src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
1647
+
1648
+
1649
+ // src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx
1650
+
1651
+
1652
+ // src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx
1653
+
1654
+ var statusConfig2 = {
1655
+ ["active" /* ACTIVE */]: {
1656
+ label: "Active",
1657
+ color: "bg-green-100 text-green-800"
1658
+ },
1659
+ ["trialing" /* TRIALING */]: {
1660
+ label: "Trial",
1661
+ color: "bg-blue-100 text-blue-800"
1662
+ },
1663
+ ["past_due" /* PAST_DUE */]: {
1664
+ label: "Past Due",
1665
+ color: "bg-red-100 text-red-800"
1666
+ },
1667
+ ["canceled" /* CANCELED */]: {
1668
+ label: "Canceled",
1669
+ color: "bg-gray-100 text-gray-800"
1670
+ },
1671
+ ["paused" /* PAUSED */]: {
1672
+ label: "Paused",
1673
+ color: "bg-yellow-100 text-yellow-800"
1674
+ },
1675
+ ["unpaid" /* UNPAID */]: {
1676
+ label: "Unpaid",
1677
+ color: "bg-orange-100 text-orange-800"
1678
+ },
1679
+ ["incomplete" /* INCOMPLETE */]: {
1680
+ label: "Incomplete",
1681
+ color: "bg-gray-100 text-gray-800"
1682
+ },
1683
+ ["incomplete_expired" /* INCOMPLETE_EXPIRED */]: {
1684
+ label: "Expired",
1685
+ color: "bg-gray-100 text-gray-800"
1686
+ }
1687
+ };
1688
+ var cancelingConfig = {
1689
+ label: "Canceling",
1690
+ color: "bg-amber-100 text-amber-800"
1691
+ };
1692
+ function SubscriptionStatusBadge({ status, cancelAtPeriodEnd }) {
1693
+ const config = cancelAtPeriodEnd ? cancelingConfig : statusConfig2[status] || statusConfig2["canceled" /* CANCELED */];
1694
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: `${config.color} text-xs px-2 py-1 rounded-full font-medium`, children: config.label });
1695
+ }
1696
+ _chunk7QVYU63Ejs.__name.call(void 0, SubscriptionStatusBadge, "SubscriptionStatusBadge");
1697
+
1698
+ // src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx
1699
+
1700
+ function formatPlanName2(price) {
1701
+ if (!price) return "N/A";
1702
+ const productName = _optionalChain([price, 'access', _47 => _47.product, 'optionalAccess', _48 => _48.name]) || "";
1703
+ const nickname = price.nickname || "";
1704
+ let interval = "";
1705
+ if (_optionalChain([price, 'access', _49 => _49.recurring, 'optionalAccess', _50 => _50.interval])) {
1706
+ const intervalMap = {
1707
+ day: "Daily",
1708
+ week: "Weekly",
1709
+ month: "Monthly",
1710
+ year: "Yearly"
1711
+ };
1712
+ interval = intervalMap[price.recurring.interval] || price.recurring.interval;
1713
+ }
1714
+ const parts = [productName, nickname].filter(Boolean);
1715
+ const planLabel = parts.join(" - ");
1716
+ return interval ? `${planLabel} (${interval})` : planLabel || "N/A";
1717
+ }
1718
+ _chunk7QVYU63Ejs.__name.call(void 0, formatPlanName2, "formatPlanName");
1719
+ function formatBillingAmount(price) {
1720
+ if (!_optionalChain([price, 'optionalAccess', _51 => _51.unitAmount])) return "N/A";
1721
+ return formatCurrency(price.unitAmount, price.currency);
1722
+ }
1723
+ _chunk7QVYU63Ejs.__name.call(void 0, formatBillingAmount, "formatBillingAmount");
1724
+ function SubscriptionDetails({
1725
+ subscription,
1726
+ open,
1727
+ onOpenChange,
1728
+ onSubscriptionChange
1729
+ }) {
1730
+ const [showEdit, setShowEdit] = _react.useState.call(void 0, false);
1731
+ const [showCancel, setShowCancel] = _react.useState.call(void 0, false);
1732
+ const [isProcessing, setIsProcessing] = _react.useState.call(void 0, false);
1733
+ const handlePause = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1734
+ setIsProcessing(true);
1735
+ try {
1736
+ await _chunkNQVPCNRSjs.StripeSubscriptionService.pauseSubscription({ subscriptionId: subscription.id });
1737
+ onSubscriptionChange();
1738
+ } catch (error) {
1739
+ console.error("[SubscriptionDetails] Failed to pause subscription:", error);
1740
+ } finally {
1741
+ setIsProcessing(false);
1742
+ }
1743
+ }, "handlePause");
1744
+ const handleResume = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1745
+ setIsProcessing(true);
1746
+ try {
1747
+ await _chunkNQVPCNRSjs.StripeSubscriptionService.resumeSubscription({ subscriptionId: subscription.id });
1748
+ onSubscriptionChange();
1749
+ } catch (error) {
1750
+ console.error("[SubscriptionDetails] Failed to resume subscription:", error);
1751
+ } finally {
1752
+ setIsProcessing(false);
1753
+ }
1754
+ }, "handleResume");
1755
+ const handleManageViaPortal = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1756
+ try {
1757
+ const { url } = await _chunkNQVPCNRSjs.StripeCustomerService.createPortalSession();
1758
+ window.open(url, "_blank");
1759
+ } catch (error) {
1760
+ console.error("[SubscriptionDetails] Failed to create portal session:", error);
1761
+ }
1762
+ }, "handleManageViaPortal");
1763
+ const canPause = subscription.status === "active" /* ACTIVE */;
1764
+ const canResume = subscription.status === "paused" /* PAUSED */;
1765
+ const canCancel = subscription.status === "active" /* ACTIVE */ || subscription.status === "trialing" /* TRIALING */ || subscription.status === "paused" /* PAUSED */;
1766
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1767
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogContent, { className: "max-w-2xl", children: [
1768
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogHeader, { children: [
1769
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogTitle, { children: "Subscription Details" }),
1770
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogDescription, { children: "View and manage your subscription" })
1771
+ ] }),
1772
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
1773
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
1774
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Status:" }),
1775
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SubscriptionStatusBadge, { status: subscription.status, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd })
1776
+ ] }),
1777
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
1778
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between", children: [
1779
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Plan:" }),
1780
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium", children: formatPlanName2(subscription.price) })
1781
+ ] }),
1782
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between", children: [
1783
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Billing Amount:" }),
1784
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium", children: formatBillingAmount(subscription.price) })
1785
+ ] })
1786
+ ] }),
1787
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-2", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between", children: [
1788
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Current Period:" }),
1789
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { className: "font-medium", children: [
1790
+ formatDate3(subscription.currentPeriodStart),
1791
+ " - ",
1792
+ formatDate3(subscription.currentPeriodEnd)
1793
+ ] })
1794
+ ] }) }),
1795
+ subscription.trialEnd && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between", children: [
1796
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium text-muted-foreground", children: "Trial Ends:" }),
1797
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium", children: formatDate3(subscription.trialEnd) })
1798
+ ] }),
1799
+ subscription.cancelAtPeriodEnd && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-3", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-yellow-800", children: [
1800
+ "This subscription will be canceled at the end of the current period on",
1801
+ " ",
1802
+ formatDate3(subscription.currentPeriodEnd),
1803
+ "."
1804
+ ] }) }),
1805
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap gap-2 pt-4 border-t", children: [
1806
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "default", onClick: () => setShowEdit(true), children: "Change Plan" }),
1807
+ canPause && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", onClick: handlePause, disabled: isProcessing, children: isProcessing ? "Pausing..." : "Pause" }),
1808
+ canResume && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", onClick: handleResume, disabled: isProcessing, children: isProcessing ? "Resuming..." : "Resume" }),
1809
+ canCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "destructive", onClick: () => setShowCancel(true), children: "Cancel" }),
1810
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", onClick: handleManageViaPortal, children: "Manage via Portal" })
1811
+ ] })
1812
+ ] })
1813
+ ] }) }),
1814
+ showEdit && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1815
+ SubscriptionEditor,
1816
+ {
1817
+ subscription,
1818
+ open: showEdit,
1819
+ onOpenChange: setShowEdit,
1820
+ onSuccess: () => {
1821
+ onSubscriptionChange();
1822
+ setShowEdit(false);
1823
+ }
1824
+ }
1825
+ ),
1826
+ showCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1827
+ CancelSubscriptionDialog,
1828
+ {
1829
+ subscription,
1830
+ open: showCancel,
1831
+ onOpenChange: setShowCancel,
1832
+ onSuccess: () => {
1833
+ onSubscriptionChange();
1834
+ setShowCancel(false);
1835
+ }
1836
+ }
1837
+ )
1838
+ ] });
1839
+ }
1840
+ _chunk7QVYU63Ejs.__name.call(void 0, SubscriptionDetails, "SubscriptionDetails");
1841
+
1842
+ // src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
1843
+
1844
+ function formatPlanName3(price) {
1845
+ if (!price) return "N/A";
1846
+ const productName = _optionalChain([price, 'access', _52 => _52.product, 'optionalAccess', _53 => _53.name]) || "";
1847
+ const nickname = price.nickname || "";
1848
+ let interval = "";
1849
+ if (_optionalChain([price, 'access', _54 => _54.recurring, 'optionalAccess', _55 => _55.interval])) {
1850
+ const intervalMap = {
1851
+ day: "Daily",
1852
+ week: "Weekly",
1853
+ month: "Monthly",
1854
+ year: "Yearly"
1855
+ };
1856
+ interval = intervalMap[price.recurring.interval] || price.recurring.interval;
1857
+ }
1858
+ const parts = [productName, nickname].filter(Boolean);
1859
+ const planLabel = parts.join(" - ");
1860
+ return interval ? `${planLabel} (${interval})` : planLabel || "N/A";
1861
+ }
1862
+ _chunk7QVYU63Ejs.__name.call(void 0, formatPlanName3, "formatPlanName");
1863
+ function SubscriptionsList({ subscriptions, onSubscriptionsChange }) {
1864
+ const [selectedSub, setSelectedSub] = _react.useState.call(void 0, null);
1865
+ const handleRowClick = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (subscription) => {
1866
+ setSelectedSub(subscription);
1867
+ }, "handleRowClick");
1868
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
1869
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Table, { children: [
1870
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHeader, { className: "bg-muted", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.TableRow, { children: [
1871
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Status" }),
1872
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Plan" }),
1873
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Period" }),
1874
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { className: "text-right", children: "Amount" })
1875
+ ] }) }),
1876
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableBody, { children: subscriptions.map((subscription) => {
1877
+ const price = subscription.price;
1878
+ const amount = _optionalChain([price, 'optionalAccess', _56 => _56.unitAmount]) ? formatCurrency(price.unitAmount, price.currency) : "N/A";
1879
+ const period = `${formatDate3(subscription.currentPeriodStart)} - ${formatDate3(subscription.currentPeriodEnd)}`;
1880
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1881
+ _chunkILKUML3Zjs.TableRow,
1882
+ {
1883
+ onClick: () => handleRowClick(subscription),
1884
+ className: "cursor-pointer hover:bg-muted/50",
1885
+ children: [
1886
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SubscriptionStatusBadge, { status: subscription.status, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd }) }),
1887
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "font-medium", children: formatPlanName3(price) }),
1888
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "text-muted-foreground text-sm", children: period }),
1889
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "text-right font-medium", children: amount })
1890
+ ]
1891
+ },
1892
+ subscription.id
1893
+ );
1894
+ }) })
1895
+ ] }) }),
1896
+ selectedSub && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1897
+ SubscriptionDetails,
1898
+ {
1899
+ subscription: selectedSub,
1900
+ open: !!selectedSub,
1901
+ onOpenChange: (open) => !open && setSelectedSub(null),
1902
+ onSubscriptionChange: () => {
1903
+ onSubscriptionsChange();
1904
+ setSelectedSub(null);
1905
+ }
1906
+ }
1907
+ )
1908
+ ] });
1909
+ }
1910
+ _chunk7QVYU63Ejs.__name.call(void 0, SubscriptionsList, "SubscriptionsList");
1911
+
1912
+ // src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx
1913
+
1914
+ function SubscriptionsContainer() {
1915
+ const { confirmPayment, isConfirming } = useConfirmSubscriptionPayment();
1916
+ const [subscriptions, setSubscriptions] = _react.useState.call(void 0, []);
1917
+ const [loading, setLoading] = _react.useState.call(void 0, true);
1918
+ const [showCreateSubscription, setShowCreateSubscription] = _react.useState.call(void 0, false);
1919
+ const [showPaymentMethodEditor, setShowPaymentMethodEditor] = _react.useState.call(void 0, false);
1920
+ const [products, setProducts] = _react.useState.call(void 0, []);
1921
+ const [pricesByProduct, setPricesByProduct] = _react.useState.call(void 0, /* @__PURE__ */ new Map());
1922
+ const [loadingPricing, setLoadingPricing] = _react.useState.call(void 0, false);
1923
+ const [hasPaymentMethod, setHasPaymentMethod] = _react.useState.call(void 0, null);
1924
+ const [pendingPriceId, setPendingPriceId] = _react.useState.call(void 0, null);
1925
+ const [creatingSubscription, setCreatingSubscription] = _react.useState.call(void 0, false);
1926
+ const [paymentConfirmationState, setPaymentConfirmationState] = _react.useState.call(void 0, "idle");
1927
+ const [paymentError, setPaymentError] = _react.useState.call(void 0, null);
1928
+ const loadSubscriptions = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1929
+ setLoading(true);
1930
+ try {
1931
+ const fetchedSubscriptions = await _chunkNQVPCNRSjs.StripeSubscriptionService.listSubscriptions();
1932
+ setSubscriptions(fetchedSubscriptions);
1933
+ } catch (error) {
1934
+ console.error("[SubscriptionsContainer] Failed to load subscriptions:", error);
1935
+ } finally {
1936
+ setLoading(false);
1937
+ }
1938
+ }, "loadSubscriptions");
1939
+ const loadPricingData = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1940
+ setLoadingPricing(true);
1941
+ try {
1942
+ const fetchedProducts = await _chunkNQVPCNRSjs.StripeProductService.listProducts({ active: true });
1943
+ const grouped = /* @__PURE__ */ new Map();
1944
+ for (const product of fetchedProducts) {
1945
+ if (product.stripePrices && product.stripePrices.length > 0) {
1946
+ grouped.set(product.id, product.stripePrices);
1947
+ }
1948
+ }
1949
+ setProducts(fetchedProducts);
1950
+ setPricesByProduct(grouped);
1951
+ } catch (error) {
1952
+ console.error("[SubscriptionsContainer] Failed to load pricing data:", error);
1953
+ } finally {
1954
+ setLoadingPricing(false);
1955
+ }
1956
+ }, "loadPricingData");
1957
+ const checkPaymentMethod = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
1958
+ try {
1959
+ const paymentMethods = await _chunkNQVPCNRSjs.StripeCustomerService.listPaymentMethods();
1960
+ const hasMethod = paymentMethods.length > 0;
1961
+ setHasPaymentMethod(hasMethod);
1962
+ } catch (error) {
1963
+ console.error("[SubscriptionsContainer] Failed to check payment methods:", error);
1964
+ setHasPaymentMethod(false);
1965
+ }
1966
+ }, "checkPaymentMethod");
1967
+ const createSubscriptionWithPrice = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (priceId) => {
1968
+ setCreatingSubscription(true);
1969
+ setPaymentError(null);
1970
+ setPaymentConfirmationState("idle");
1971
+ try {
1972
+ const result = await _chunkNQVPCNRSjs.StripeSubscriptionService.createSubscription({
1973
+ id: _uuid.v4.call(void 0, ),
1974
+ priceId
1975
+ });
1976
+ if (result.meta.requiresAction && result.meta.clientSecret) {
1977
+ setPaymentConfirmationState("confirming");
1978
+ const confirmation = await confirmPayment(result.meta.clientSecret);
1979
+ if (!confirmation.success) {
1980
+ console.error("[SubscriptionsContainer] Payment confirmation failed:", confirmation.error);
1981
+ setPaymentConfirmationState("error");
1982
+ setPaymentError(confirmation.error || "Payment confirmation failed");
1983
+ setCreatingSubscription(false);
1984
+ return;
1985
+ }
1986
+ await _chunkNQVPCNRSjs.StripeSubscriptionService.syncSubscription({
1987
+ subscriptionId: result.subscription.id
1988
+ });
1989
+ }
1990
+ setPaymentConfirmationState("success");
1991
+ await loadSubscriptions();
1992
+ } catch (error) {
1993
+ console.error("[SubscriptionsContainer] Failed to create subscription:", error);
1994
+ if (_optionalChain([error, 'optionalAccess', _57 => _57.status]) === 402 || _optionalChain([error, 'optionalAccess', _58 => _58.response, 'optionalAccess', _59 => _59.status]) === 402) {
1995
+ setPendingPriceId(priceId);
1996
+ setHasPaymentMethod(false);
1997
+ setShowPaymentMethodEditor(true);
1998
+ } else {
1999
+ setPaymentConfirmationState("error");
2000
+ setPaymentError(_optionalChain([error, 'optionalAccess', _60 => _60.message]) || "Failed to create subscription");
2001
+ }
2002
+ } finally {
2003
+ setCreatingSubscription(false);
2004
+ }
2005
+ }, "createSubscriptionWithPrice");
2006
+ const handleSelectPrice = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (price) => {
2007
+ const priceId = price.id;
2008
+ if (!hasPaymentMethod) {
2009
+ setPendingPriceId(priceId);
2010
+ setShowPaymentMethodEditor(true);
2011
+ return;
2012
+ }
2013
+ await createSubscriptionWithPrice(priceId);
2014
+ }, "handleSelectPrice");
2015
+ const handlePaymentMethodSuccess = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2016
+ setShowPaymentMethodEditor(false);
2017
+ setHasPaymentMethod(true);
2018
+ if (pendingPriceId) {
2019
+ await createSubscriptionWithPrice(pendingPriceId);
2020
+ setPendingPriceId(null);
2021
+ }
2022
+ }, "handlePaymentMethodSuccess");
2023
+ _react.useEffect.call(void 0, () => {
2024
+ loadSubscriptions();
2025
+ }, []);
2026
+ _react.useEffect.call(void 0, () => {
2027
+ if (!loading && subscriptions.length === 0) {
2028
+ loadPricingData();
2029
+ checkPaymentMethod();
2030
+ }
2031
+ }, [loading, subscriptions.length]);
2032
+ const criticalSubscriptions = subscriptions.filter(
2033
+ (sub) => sub.status === "past_due" /* PAST_DUE */ || sub.status === "trialing" /* TRIALING */ && sub.trialEnd && new Date(sub.trialEnd).getTime() - (/* @__PURE__ */ new Date()).getTime() <= 7 * 24 * 60 * 60 * 1e3
2034
+ );
2035
+ if (loading) {
2036
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground", children: "Loading subscriptions..." }) });
2037
+ }
2038
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-y-6", children: [
2039
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between", children: [
2040
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
2041
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-8 w-8" }),
2042
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Subscriptions" })
2043
+ ] }),
2044
+ subscriptions.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { onClick: () => setShowCreateSubscription(true), children: "Subscribe to a Plan" })
2045
+ ] }),
2046
+ criticalSubscriptions.map((subscription) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BillingAlertBanner, { subscription }, subscription.id)),
2047
+ subscriptions.length === 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
2048
+ (paymentConfirmationState === "confirming" || isConfirming) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center py-12 space-y-4 bg-muted/50 rounded-lg", children: [
2049
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Loader2, { className: "h-8 w-8 animate-spin text-primary" }),
2050
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
2051
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium", children: "Processing payment..." }),
2052
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Please complete any verification if prompted." })
2053
+ ] })
2054
+ ] }),
2055
+ paymentConfirmationState === "success" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center py-8 space-y-4 bg-green-50 rounded-lg border border-green-200", children: [
2056
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CheckCircle, { className: "h-12 w-12 text-green-500" }),
2057
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
2058
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium text-green-600", children: "Payment successful!" }),
2059
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Your subscription is now active." })
2060
+ ] })
2061
+ ] }),
2062
+ paymentConfirmationState === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Alert, { variant: "destructive", children: [
2063
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertTitle, { children: "Payment Failed" }),
2064
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDescription, { className: "mt-2", children: [
2065
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-4", children: paymentError || "We couldn't process your payment. Please try again." }),
2066
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2067
+ _chunkILKUML3Zjs.Button,
2068
+ {
2069
+ onClick: () => {
2070
+ setPaymentConfirmationState("idle");
2071
+ setPaymentError(null);
2072
+ },
2073
+ variant: "outline",
2074
+ children: "Try Again"
2075
+ }
2076
+ )
2077
+ ] })
2078
+ ] }),
2079
+ paymentConfirmationState === "idle" && !isConfirming && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2080
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
2081
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "text-muted-foreground mx-auto h-16 w-16 mb-4" }),
2082
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-2 text-xl font-semibold", children: "Choose Your Plan" }),
2083
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground mb-6", children: "Select a subscription plan to get started with our services." })
2084
+ ] }),
2085
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2086
+ PricingCardsGrid,
2087
+ {
2088
+ products,
2089
+ pricesByProduct,
2090
+ loading: loadingPricing,
2091
+ loadingPriceId: creatingSubscription ? _nullishCoalesce(pendingPriceId, () => ( void 0)) : void 0,
2092
+ onSelectPrice: handleSelectPrice
2093
+ }
2094
+ )
2095
+ ] })
2096
+ ] }),
2097
+ subscriptions.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SubscriptionsList, { subscriptions, onSubscriptionsChange: loadSubscriptions }),
2098
+ showCreateSubscription && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2099
+ SubscriptionEditor,
2100
+ {
2101
+ open: showCreateSubscription,
2102
+ onOpenChange: setShowCreateSubscription,
2103
+ onSuccess: loadSubscriptions,
2104
+ onAddPaymentMethod: () => {
2105
+ setShowCreateSubscription(false);
2106
+ setShowPaymentMethodEditor(true);
2107
+ }
2108
+ }
2109
+ ),
2110
+ showPaymentMethodEditor && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2111
+ PaymentMethodEditor,
2112
+ {
2113
+ open: showPaymentMethodEditor,
2114
+ onOpenChange: (open) => {
2115
+ setShowPaymentMethodEditor(open);
2116
+ if (!open) {
2117
+ setPendingPriceId(null);
2118
+ }
2119
+ },
2120
+ onSuccess: handlePaymentMethodSuccess
2121
+ }
2122
+ )
2123
+ ] });
2124
+ }
2125
+ _chunk7QVYU63Ejs.__name.call(void 0, SubscriptionsContainer, "SubscriptionsContainer");
2126
+
2127
+ // src/features/billing/stripe-usage/components/containers/UsageContainer.tsx
2128
+
2129
+
2130
+
2131
+ // src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx
2132
+
2133
+
2134
+ function getProgressColor(percentage) {
2135
+ if (percentage === null) return "bg-blue-500";
2136
+ if (percentage >= 90) return "bg-red-500";
2137
+ if (percentage >= 75) return "bg-orange-500";
2138
+ return "bg-green-500";
2139
+ }
2140
+ _chunk7QVYU63Ejs.__name.call(void 0, getProgressColor, "getProgressColor");
2141
+ function formatDate4(date) {
2142
+ if (!date) return "N/A";
2143
+ try {
2144
+ return new Intl.DateTimeFormat("en-US", {
2145
+ month: "short",
2146
+ day: "numeric"
2147
+ }).format(new Date(date));
2148
+ } catch (error) {
2149
+ return "Invalid Date";
2150
+ }
2151
+ }
2152
+ _chunk7QVYU63Ejs.__name.call(void 0, formatDate4, "formatDate");
2153
+ function UsageSummaryCard({ meter, summary }) {
2154
+ const currentUsage = _nullishCoalesce(_optionalChain([summary, 'optionalAccess', _61 => _61.aggregatedValue]), () => ( 0));
2155
+ const limit = meter.limit;
2156
+ const percentage = limit && limit > 0 ? currentUsage / limit * 100 : null;
2157
+ const progressColor = getProgressColor(percentage);
2158
+ const progressWidth = percentage !== null ? Math.min(percentage, 100) : 0;
2159
+ const displayName = meter.displayName || meter.eventName;
2160
+ const hasLimit = limit !== null && limit !== void 0;
2161
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
2162
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "flex flex-row items-center gap-x-3 pb-3", children: [
2163
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "h-5 w-5" }) }),
2164
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
2165
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold", children: displayName }),
2166
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-gray-500", children: meter.id })
2167
+ ] })
2168
+ ] }),
2169
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardContent, { className: "flex flex-col gap-y-4", children: [
2170
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
2171
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-3xl font-bold", children: currentUsage.toLocaleString() }),
2172
+ hasLimit && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-gray-500", children: [
2173
+ "of ",
2174
+ limit.toLocaleString(),
2175
+ " used"
2176
+ ] })
2177
+ ] }),
2178
+ hasLimit ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-y-2", children: [
2179
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "h-2 w-full overflow-hidden rounded-full bg-gray-200", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: `h-full transition-all ${progressColor}`, style: { width: `${progressWidth}%` } }) }),
2180
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-gray-500", children: [
2181
+ _optionalChain([percentage, 'optionalAccess', _62 => _62.toFixed, 'call', _63 => _63(1)]),
2182
+ "% used"
2183
+ ] })
2184
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-gray-500", children: "No limit set" }),
2185
+ summary && summary.start && summary.end && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-t pt-3", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-xs text-gray-500", children: [
2186
+ "Period: ",
2187
+ formatDate4(summary.start),
2188
+ " - ",
2189
+ formatDate4(summary.end)
2190
+ ] }) })
2191
+ ] })
2192
+ ] });
2193
+ }
2194
+ _chunk7QVYU63Ejs.__name.call(void 0, UsageSummaryCard, "UsageSummaryCard");
2195
+
2196
+ // src/features/billing/stripe-usage/components/widgets/UsageSummaryCards.tsx
2197
+
2198
+ function UsageSummaryCards({ meters, summaries }) {
2199
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3", children: meters.map((meter) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UsageSummaryCard, { meter, summary: summaries[meter.id] || null }, meter.id)) });
2200
+ }
2201
+ _chunk7QVYU63Ejs.__name.call(void 0, UsageSummaryCards, "UsageSummaryCards");
2202
+
2203
+ // src/features/billing/stripe-usage/components/containers/UsageContainer.tsx
2204
+
2205
+ function UsageContainer() {
2206
+ const [meters, setMeters] = _react.useState.call(void 0, []);
2207
+ const [summaries, setSummaries] = _react.useState.call(void 0, {});
2208
+ const [loading, setLoading] = _react.useState.call(void 0, true);
2209
+ const [subscriptions, setSubscriptions] = _react.useState.call(void 0, []);
2210
+ _react.useEffect.call(void 0, () => {
2211
+ loadUsageData();
2212
+ }, []);
2213
+ const loadUsageData = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2214
+ setLoading(true);
2215
+ try {
2216
+ const fetchedSubscriptions = await _chunkNQVPCNRSjs.StripeSubscriptionService.listSubscriptions();
2217
+ setSubscriptions(fetchedSubscriptions);
2218
+ const hasMeteredSubscriptions2 = fetchedSubscriptions.some((sub) => _optionalChain([sub, 'access', _64 => _64.price, 'optionalAccess', _65 => _65.recurring, 'optionalAccess', _66 => _66.usageType]) === "metered");
2219
+ if (!hasMeteredSubscriptions2) {
2220
+ setLoading(false);
2221
+ return;
2222
+ }
2223
+ const fetchedMeters = await _chunkNQVPCNRSjs.StripeUsageService.listMeters();
2224
+ setMeters(fetchedMeters);
2225
+ const summariesMap = {};
2226
+ const now = /* @__PURE__ */ new Date();
2227
+ const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
2228
+ const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
2229
+ for (const meter of fetchedMeters) {
2230
+ try {
2231
+ const meterSummaries = await _chunkNQVPCNRSjs.StripeUsageService.getMeterSummaries({
2232
+ meterId: meter.id,
2233
+ startTime: startOfMonth,
2234
+ endTime: endOfMonth
2235
+ });
2236
+ summariesMap[meter.id] = meterSummaries.length > 0 ? meterSummaries[0] : null;
2237
+ } catch (error) {
2238
+ console.error(`[UsageContainer] Failed to load summaries for meter ${meter.id}:`, error);
2239
+ summariesMap[meter.id] = null;
2240
+ }
2241
+ }
2242
+ setSummaries(summariesMap);
2243
+ } catch (error) {
2244
+ console.error("[UsageContainer] Failed to load usage data:", error);
2245
+ } finally {
2246
+ setLoading(false);
2247
+ }
2248
+ }, "loadUsageData");
2249
+ const hasMeteredSubscriptions = subscriptions.some((sub) => _optionalChain([sub, 'access', _67 => _67.price, 'optionalAccess', _68 => _68.recurring, 'optionalAccess', _69 => _69.usageType]) === "metered");
2250
+ if (!loading && !hasMeteredSubscriptions) {
2251
+ return null;
2252
+ }
2253
+ if (loading) {
2254
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground", children: "Loading usage data..." }) });
2255
+ }
2256
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-y-6", children: [
2257
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
2258
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "h-8 w-8" }),
2259
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Usage Tracking" })
2260
+ ] }),
2261
+ meters.length === 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 p-12", children: [
2262
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "text-muted-foreground h-16 w-16" }),
2263
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
2264
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-2 text-xl font-semibold", children: "No usage meters configured" }),
2265
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground", children: "Usage tracking will appear here when you have metered subscriptions with configured meters." })
2266
+ ] })
2267
+ ] }),
2268
+ meters.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UsageSummaryCards, { meters, summaries })
2269
+ ] });
2270
+ }
2271
+ _chunk7QVYU63Ejs.__name.call(void 0, UsageContainer, "UsageContainer");
2272
+
2273
+ // src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx
2274
+
2275
+ function formatDateTime(date) {
2276
+ if (!date) return "N/A";
2277
+ const dateObj = typeof date === "string" ? new Date(date) : date;
2278
+ try {
2279
+ return new Intl.DateTimeFormat("en-US", {
2280
+ month: "short",
2281
+ day: "numeric",
2282
+ year: "numeric",
2283
+ hour: "numeric",
2284
+ minute: "2-digit"
2285
+ }).format(dateObj);
2286
+ } catch (error) {
2287
+ return "Invalid Date";
2288
+ }
2289
+ }
2290
+ _chunk7QVYU63Ejs.__name.call(void 0, formatDateTime, "formatDateTime");
2291
+ function UsageHistoryTable({ usageRecords }) {
2292
+ if (usageRecords.length === 0) {
2293
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rounded-lg border p-8 text-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground", children: "No usage history available." }) });
2294
+ }
2295
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-y-4", children: [
2296
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "text-xl font-semibold", children: "Usage History" }),
2297
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "overflow-hidden rounded-lg border", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Table, { children: [
2298
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHeader, { className: "bg-muted", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.TableRow, { children: [
2299
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Date & Time" }),
2300
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Meter Event" }),
2301
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { className: "text-right", children: "Quantity" }),
2302
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableHead, { children: "Event ID" })
2303
+ ] }) }),
2304
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableBody, { children: usageRecords.map((record) => {
2305
+ const dateTime = formatDateTime(record.timestamp);
2306
+ const quantity = record.quantity.toLocaleString();
2307
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.TableRow, { children: [
2308
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "font-medium", children: dateTime }),
2309
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "text-muted-foreground", children: record.meterEventName }),
2310
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "text-right font-medium", children: quantity }),
2311
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.TableCell, { className: "text-muted-foreground text-sm font-mono", children: record.stripeEventId })
2312
+ ] }, record.id);
2313
+ }) })
2314
+ ] }) })
2315
+ ] });
2316
+ }
2317
+ _chunk7QVYU63Ejs.__name.call(void 0, UsageHistoryTable, "UsageHistoryTable");
2318
+
2319
+ // src/features/billing/components/modals/BillingDetailModal.tsx
2320
+
2321
+ function BillingDetailModal({
2322
+ open,
2323
+ onOpenChange,
2324
+ title,
2325
+ children,
2326
+ className
2327
+ }) {
2328
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogContent, { className: _nullishCoalesce(className, () => ( "max-w-4xl max-h-[90vh] overflow-y-auto")), children: [
2329
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogHeader, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogTitle, { children: title }) }),
2330
+ children
2331
+ ] }) });
2332
+ }
2333
+ _chunk7QVYU63Ejs.__name.call(void 0, BillingDetailModal, "BillingDetailModal");
2334
+
2335
+ // src/features/billing/components/widgets/BillingAlertBanner.tsx
2336
+
2337
+
2338
+ function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }) {
2339
+ if (subscription.status === "past_due" /* PAST_DUE */) {
2340
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-red-50 border border-red-200 rounded-lg p-4 flex items-start gap-x-3", children: [
2341
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertCircle, { className: "h-5 w-5 text-red-600 mt-0.5" }),
2342
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1", children: [
2343
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-red-900", children: "Payment Failed" }),
2344
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-red-700 mt-1", children: "Your last payment failed. Please update your payment method to avoid service interruption." })
2345
+ ] }),
2346
+ onUpdatePayment && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", size: "sm", onClick: onUpdatePayment, className: "border-red-300 text-red-700", children: "Update Payment Method" })
2347
+ ] });
2348
+ }
2349
+ if (subscription.status === "trialing" /* TRIALING */ && subscription.trialEnd) {
2350
+ const trialEnd = new Date(subscription.trialEnd);
2351
+ const now = /* @__PURE__ */ new Date();
2352
+ const daysRemaining = Math.ceil((trialEnd.getTime() - now.getTime()) / (1e3 * 60 * 60 * 24));
2353
+ if (daysRemaining <= 7) {
2354
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-4 flex items-start gap-x-3", children: [
2355
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertCircle, { className: "h-5 w-5 text-yellow-600 mt-0.5" }),
2356
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1", children: [
2357
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-yellow-900", children: "Trial Ending Soon" }),
2358
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-yellow-700 mt-1", children: [
2359
+ "Your trial ends in ",
2360
+ daysRemaining,
2361
+ " ",
2362
+ daysRemaining === 1 ? "day" : "days",
2363
+ ". Add a payment method to continue your subscription."
2364
+ ] })
2365
+ ] }),
2366
+ onAddPayment && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", size: "sm", onClick: onAddPayment, className: "border-yellow-300 text-yellow-700", children: "Add Payment Method" })
2367
+ ] });
2368
+ }
2369
+ }
2370
+ return null;
2371
+ }
2372
+ _chunk7QVYU63Ejs.__name.call(void 0, BillingAlertBanner, "BillingAlertBanner");
2373
+
2374
+ // src/features/billing/components/containers/BillingDashboardContainer.tsx
2375
+
2376
+ function BillingDashboardContainer() {
2377
+ const [data, setData] = _react.useState.call(void 0, {
2378
+ customer: null,
2379
+ subscriptions: [],
2380
+ paymentMethods: [],
2381
+ invoices: [],
2382
+ meters: [],
2383
+ meterSummaries: {}
2384
+ });
2385
+ const [loading, setLoading] = _react.useState.call(void 0, {
2386
+ customer: true,
2387
+ subscriptions: true,
2388
+ paymentMethods: true,
2389
+ invoices: true,
2390
+ usage: true
2391
+ });
2392
+ const [errors, setErrors] = _react.useState.call(void 0, {
2393
+ customer: null,
2394
+ subscriptions: null,
2395
+ paymentMethods: null,
2396
+ invoices: null,
2397
+ usage: null
2398
+ });
2399
+ const [activeModal, setActiveModal] = _react.useState.call(void 0, null);
2400
+ const [noCustomerExists, setNoCustomerExists] = _react.useState.call(void 0, false);
2401
+ const [creatingCustomer, setCreatingCustomer] = _react.useState.call(void 0, false);
2402
+ const hasMeteredSubscriptions = _react.useCallback.call(void 0, () => {
2403
+ return data.subscriptions.some((sub) => _optionalChain([sub, 'access', _70 => _70.price, 'optionalAccess', _71 => _71.recurring, 'optionalAccess', _72 => _72.usageType]) === "metered");
2404
+ }, [data.subscriptions]);
2405
+ const fetchAllData = _react.useCallback.call(void 0, async () => {
2406
+ setNoCustomerExists(false);
2407
+ let customer = null;
2408
+ try {
2409
+ customer = await _chunkNQVPCNRSjs.StripeCustomerService.getCustomer();
2410
+ setData((prev) => ({ ...prev, customer }));
2411
+ setErrors((prev) => ({ ...prev, customer: null }));
2412
+ setNoCustomerExists(false);
2413
+ } catch (error) {
2414
+ console.error("[BillingDashboard] Failed to load customer:", error);
2415
+ const errorMessage = error instanceof Error ? error.message : String(error);
2416
+ if (errorMessage.includes("Not Found") || errorMessage.includes("not found")) {
2417
+ setNoCustomerExists(true);
2418
+ setLoading({
2419
+ customer: false,
2420
+ subscriptions: false,
2421
+ paymentMethods: false,
2422
+ invoices: false,
2423
+ usage: false
2424
+ });
2425
+ return;
2426
+ }
2427
+ setErrors((prev) => ({ ...prev, customer: "Failed to load billing account" }));
2428
+ } finally {
2429
+ setLoading((prev) => ({ ...prev, customer: false }));
2430
+ }
2431
+ if (customer) {
2432
+ const fetchSubscriptions = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2433
+ try {
2434
+ const subscriptions2 = await _chunkNQVPCNRSjs.StripeSubscriptionService.listSubscriptions();
2435
+ setData((prev) => ({ ...prev, subscriptions: subscriptions2 }));
2436
+ setErrors((prev) => ({ ...prev, subscriptions: null }));
2437
+ return subscriptions2;
2438
+ } catch (error) {
2439
+ console.error("[BillingDashboard] Failed to load subscriptions:", error);
2440
+ setErrors((prev) => ({ ...prev, subscriptions: "Failed to load subscriptions" }));
2441
+ return [];
2442
+ } finally {
2443
+ setLoading((prev) => ({ ...prev, subscriptions: false }));
2444
+ }
2445
+ }, "fetchSubscriptions");
2446
+ const fetchPaymentMethods = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2447
+ try {
2448
+ const paymentMethods = await _chunkNQVPCNRSjs.StripeCustomerService.listPaymentMethods();
2449
+ setData((prev) => ({ ...prev, paymentMethods }));
2450
+ setErrors((prev) => ({ ...prev, paymentMethods: null }));
2451
+ } catch (error) {
2452
+ console.error("[BillingDashboard] Failed to load payment methods:", error);
2453
+ setErrors((prev) => ({ ...prev, paymentMethods: "Failed to load payment methods" }));
2454
+ } finally {
2455
+ setLoading((prev) => ({ ...prev, paymentMethods: false }));
2456
+ }
2457
+ }, "fetchPaymentMethods");
2458
+ const fetchInvoices = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2459
+ try {
2460
+ const invoices = await _chunkNQVPCNRSjs.StripeInvoiceService.listInvoices();
2461
+ setData((prev) => ({ ...prev, invoices }));
2462
+ setErrors((prev) => ({ ...prev, invoices: null }));
2463
+ } catch (error) {
2464
+ console.error("[BillingDashboard] Failed to load invoices:", error);
2465
+ setErrors((prev) => ({ ...prev, invoices: "Failed to load invoices" }));
2466
+ } finally {
2467
+ setLoading((prev) => ({ ...prev, invoices: false }));
2468
+ }
2469
+ }, "fetchInvoices");
2470
+ const [subscriptions] = await Promise.all([fetchSubscriptions(), fetchPaymentMethods(), fetchInvoices()]);
2471
+ const hasMetered = subscriptions.some(
2472
+ (sub) => _optionalChain([sub, 'access', _73 => _73.price, 'optionalAccess', _74 => _74.recurring, 'optionalAccess', _75 => _75.usageType]) === "metered"
2473
+ );
2474
+ if (hasMetered) {
2475
+ await fetchUsageData();
2476
+ } else {
2477
+ setLoading((prev) => ({ ...prev, usage: false }));
2478
+ }
2479
+ }
2480
+ }, []);
2481
+ const handleCreateCustomer = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2482
+ setCreatingCustomer(true);
2483
+ try {
2484
+ await _chunkNQVPCNRSjs.StripeCustomerService.createCustomer();
2485
+ setNoCustomerExists(false);
2486
+ await fetchAllData();
2487
+ } catch (error) {
2488
+ console.error("[BillingDashboard] Failed to create customer:", error);
2489
+ setErrors((prev) => ({ ...prev, customer: "Failed to set up billing" }));
2490
+ } finally {
2491
+ setCreatingCustomer(false);
2492
+ }
2493
+ }, "handleCreateCustomer");
2494
+ const fetchUsageData = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2495
+ try {
2496
+ const meters = await _chunkNQVPCNRSjs.StripeUsageService.listMeters();
2497
+ setData((prev) => ({ ...prev, meters }));
2498
+ const summariesMap = {};
2499
+ const now = /* @__PURE__ */ new Date();
2500
+ const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
2501
+ const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
2502
+ for (const meter of meters) {
2503
+ try {
2504
+ const meterSummaries = await _chunkNQVPCNRSjs.StripeUsageService.getMeterSummaries({
2505
+ meterId: meter.id,
2506
+ startTime: startOfMonth,
2507
+ endTime: endOfMonth
2508
+ });
2509
+ summariesMap[meter.id] = meterSummaries.length > 0 ? meterSummaries[0] : null;
2510
+ } catch (error) {
2511
+ console.error(`[BillingDashboard] Failed to load summaries for meter ${meter.id}:`, error);
2512
+ summariesMap[meter.id] = null;
2513
+ }
2514
+ }
2515
+ setData((prev) => ({ ...prev, meterSummaries: summariesMap }));
2516
+ setErrors((prev) => ({ ...prev, usage: null }));
2517
+ } catch (error) {
2518
+ console.error("[BillingDashboard] Failed to load usage data:", error);
2519
+ setErrors((prev) => ({ ...prev, usage: "Failed to load usage data" }));
2520
+ } finally {
2521
+ setLoading((prev) => ({ ...prev, usage: false }));
2522
+ }
2523
+ }, "fetchUsageData");
2524
+ const refreshData = _react.useCallback.call(void 0, async () => {
2525
+ setLoading({
2526
+ customer: true,
2527
+ subscriptions: true,
2528
+ paymentMethods: true,
2529
+ invoices: true,
2530
+ usage: true
2531
+ });
2532
+ await fetchAllData();
2533
+ }, [fetchAllData]);
2534
+ _react.useEffect.call(void 0, () => {
2535
+ fetchAllData();
2536
+ }, [fetchAllData]);
2537
+ const criticalSubscriptions = data.subscriptions.filter(
2538
+ (sub) => sub.status === "past_due" /* PAST_DUE */ || sub.status === "trialing" /* TRIALING */ && sub.trialEnd && new Date(sub.trialEnd).getTime() - (/* @__PURE__ */ new Date()).getTime() <= 7 * 24 * 60 * 60 * 1e3
2539
+ );
2540
+ const handleModalClose = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (open) => {
2541
+ if (!open) {
2542
+ setActiveModal(null);
2543
+ refreshData();
2544
+ }
2545
+ }, "handleModalClose");
2546
+ const getModalTitle = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (type) => {
2547
+ switch (type) {
2548
+ case "subscriptions":
2549
+ return "Manage Subscriptions";
2550
+ case "payment-methods":
2551
+ return "Payment Methods";
2552
+ case "invoices":
2553
+ return "Invoice History";
2554
+ case "usage":
2555
+ return "Usage Tracking";
2556
+ default:
2557
+ return "";
2558
+ }
2559
+ }, "getModalTitle");
2560
+ const isInitialLoading = loading.customer && !noCustomerExists && !data.customer;
2561
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-y-6", children: [
2562
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
2563
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Wallet, { className: "h-8 w-8" }),
2564
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Billing" })
2565
+ ] }),
2566
+ isInitialLoading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Card, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Loader2, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }) }),
2567
+ noCustomerExists && !isInitialLoading && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Card, { children: [
2568
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.CardHeader, { className: "text-center", children: [
2569
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-8 w-8 text-primary" }) }),
2570
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardTitle, { children: "Set Up Billing" }),
2571
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardDescription, { children: "Your company doesn't have a billing account yet. Set one up to manage subscriptions, payment methods, and view invoices." })
2572
+ ] }),
2573
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { className: "flex justify-center pb-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { onClick: handleCreateCustomer, disabled: creatingCustomer, size: "lg", children: creatingCustomer ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2574
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
2575
+ "Setting up..."
2576
+ ] }) : "Set Up Billing Account" }) }),
2577
+ errors.customer && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CardContent, { className: "pt-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-center text-sm text-destructive", children: errors.customer }) })
2578
+ ] }),
2579
+ !noCustomerExists && !isInitialLoading && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2580
+ criticalSubscriptions.map((subscription) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2581
+ BillingAlertBanner,
2582
+ {
2583
+ subscription,
2584
+ onUpdatePayment: () => setActiveModal("payment-methods"),
2585
+ onAddPayment: () => setActiveModal("payment-methods")
2586
+ },
2587
+ subscription.id
2588
+ )),
2589
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid gap-4 md:grid-cols-2", children: [
2590
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2591
+ SubscriptionSummaryCard,
2592
+ {
2593
+ subscriptions: data.subscriptions,
2594
+ loading: loading.subscriptions,
2595
+ error: errors.subscriptions || void 0,
2596
+ onManageClick: () => setActiveModal("subscriptions")
2597
+ }
2598
+ ),
2599
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2600
+ PaymentMethodSummaryCard,
2601
+ {
2602
+ paymentMethods: data.paymentMethods,
2603
+ defaultPaymentMethodId: _optionalChain([data, 'access', _76 => _76.customer, 'optionalAccess', _77 => _77.defaultPaymentMethodId]),
2604
+ loading: loading.paymentMethods,
2605
+ error: errors.paymentMethods || void 0,
2606
+ onManageClick: () => setActiveModal("payment-methods")
2607
+ }
2608
+ ),
2609
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2610
+ CustomerInfoCard,
2611
+ {
2612
+ customer: data.customer,
2613
+ loading: loading.customer,
2614
+ error: errors.customer || void 0
2615
+ }
2616
+ ),
2617
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2618
+ InvoicesSummaryCard,
2619
+ {
2620
+ invoices: data.invoices,
2621
+ loading: loading.invoices,
2622
+ error: errors.invoices || void 0,
2623
+ onViewAllClick: () => setActiveModal("invoices")
2624
+ }
2625
+ ),
2626
+ hasMeteredSubscriptions() && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2627
+ BillingUsageSummaryCard,
2628
+ {
2629
+ meters: data.meters,
2630
+ summaries: data.meterSummaries,
2631
+ loading: loading.usage,
2632
+ error: errors.usage || void 0,
2633
+ onViewDetailsClick: () => setActiveModal("usage")
2634
+ }
2635
+ )
2636
+ ] }),
2637
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2638
+ BillingDetailModal,
2639
+ {
2640
+ open: activeModal === "subscriptions",
2641
+ onOpenChange: handleModalClose,
2642
+ title: getModalTitle("subscriptions"),
2643
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SubscriptionsContainer, {})
2644
+ }
2645
+ ),
2646
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2647
+ BillingDetailModal,
2648
+ {
2649
+ open: activeModal === "payment-methods",
2650
+ onOpenChange: handleModalClose,
2651
+ title: getModalTitle("payment-methods"),
2652
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PaymentMethodsContainer, {})
2653
+ }
2654
+ ),
2655
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2656
+ BillingDetailModal,
2657
+ {
2658
+ open: activeModal === "invoices",
2659
+ onOpenChange: handleModalClose,
2660
+ title: getModalTitle("invoices"),
2661
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InvoicesContainer, {})
2662
+ }
2663
+ ),
2664
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2665
+ BillingDetailModal,
2666
+ {
2667
+ open: activeModal === "usage",
2668
+ onOpenChange: handleModalClose,
2669
+ title: getModalTitle("usage"),
2670
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UsageContainer, {})
2671
+ }
2672
+ )
2673
+ ] })
2674
+ ] });
2675
+ }
2676
+ _chunk7QVYU63Ejs.__name.call(void 0, BillingDashboardContainer, "BillingDashboardContainer");
2677
+
2678
+ // src/features/billing/components/providers/StripeProvider.tsx
2679
+
2680
+ var _stripejs = require('@stripe/stripe-js');
2681
+
2682
+
2683
+ var stripePromiseCache = null;
2684
+ function getStripePromise(publishableKey) {
2685
+ if (!publishableKey) {
2686
+ return Promise.resolve(null);
2687
+ }
2688
+ if (_optionalChain([stripePromiseCache, 'optionalAccess', _78 => _78.key]) === publishableKey) {
2689
+ return stripePromiseCache.promise;
2690
+ }
2691
+ const promise = _stripejs.loadStripe.call(void 0, publishableKey);
2692
+ stripePromiseCache = { key: publishableKey, promise };
2693
+ return promise;
2694
+ }
2695
+ _chunk7QVYU63Ejs.__name.call(void 0, getStripePromise, "getStripePromise");
2696
+ function StripeProvider({ children }) {
2697
+ const publishableKey = _chunkEW6QPMN3js.getStripePublishableKey.call(void 0, );
2698
+ const stripePromise = _react.useMemo.call(void 0, () => getStripePromise(publishableKey), [publishableKey]);
2699
+ const options = _react.useMemo.call(void 0, () => ({}), []);
2700
+ if (!publishableKey) {
2701
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
2702
+ }
2703
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactstripejs.Elements, { stripe: stripePromise, options, children });
2704
+ }
2705
+ _chunk7QVYU63Ejs.__name.call(void 0, StripeProvider, "StripeProvider");
2706
+ function isStripeConfigured() {
2707
+ return !!_chunkEW6QPMN3js.getStripePublishableKey.call(void 0, );
2708
+ }
2709
+ _chunk7QVYU63Ejs.__name.call(void 0, isStripeConfigured, "isStripeConfigured");
2710
+
2711
+ // src/features/billing/stripe-price/components/forms/PriceEditor.tsx
2712
+
2713
+
2714
+
2715
+
2716
+
2717
+
2718
+
2719
+ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2720
+ const [isSubmitting, setIsSubmitting] = _react.useState.call(void 0, false);
2721
+ const formSchema2 = _zod3.z.object({
2722
+ unitAmount: _zod3.z.preprocess(
2723
+ (val) => typeof val === "string" ? parseFloat(val) : val,
2724
+ _zod3.z.number().min(0, { message: "Amount must be 0 or greater" })
2725
+ ),
2726
+ currency: _zod3.z.string().min(1, { message: "Currency is required" }),
2727
+ interval: _zod3.z.enum(["one_time", "day", "week", "month", "year"]),
2728
+ intervalCount: _zod3.z.preprocess(
2729
+ (val) => val === "" || val === void 0 ? void 0 : typeof val === "string" ? parseInt(val, 10) : val,
2730
+ _zod3.z.number().min(1).optional()
2731
+ ),
2732
+ usageType: _zod3.z.enum(["licensed", "metered"]).optional(),
2733
+ nickname: _zod3.z.string().optional(),
2734
+ active: _zod3.z.boolean(),
2735
+ description: _zod3.z.string().optional(),
2736
+ features: _zod3.z.array(_zod3.z.string())
2737
+ });
2738
+ const isEditMode = !!price;
2739
+ const defaultUnitAmount = _optionalChain([price, 'optionalAccess', _79 => _79.unitAmount]) ? price.unitAmount / 100 : 0;
2740
+ const form = _reacthookform.useForm.call(void 0, {
2741
+ resolver: _zod.zodResolver.call(void 0, formSchema2),
2742
+ defaultValues: {
2743
+ unitAmount: defaultUnitAmount,
2744
+ currency: _optionalChain([price, 'optionalAccess', _80 => _80.currency]) || "usd",
2745
+ interval: _optionalChain([price, 'optionalAccess', _81 => _81.priceType]) === "one_time" ? "one_time" : _optionalChain([price, 'optionalAccess', _82 => _82.recurring, 'optionalAccess', _83 => _83.interval]) || "month",
2746
+ intervalCount: _optionalChain([price, 'optionalAccess', _84 => _84.recurring, 'optionalAccess', _85 => _85.intervalCount]) || 1,
2747
+ usageType: _optionalChain([price, 'optionalAccess', _86 => _86.recurring, 'optionalAccess', _87 => _87.usageType]) || "licensed",
2748
+ nickname: _optionalChain([price, 'optionalAccess', _88 => _88.nickname]) || "",
2749
+ active: _nullishCoalesce(_optionalChain([price, 'optionalAccess', _89 => _89.active]), () => ( true)),
2750
+ description: _optionalChain([price, 'optionalAccess', _90 => _90.description]) || "",
2751
+ features: _optionalChain([price, 'optionalAccess', _91 => _91.features]) || []
2752
+ }
2753
+ });
2754
+ const watchInterval = form.watch("interval");
2755
+ const isRecurring = watchInterval !== "one_time";
2756
+ const onSubmit = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (values) => {
2757
+ setIsSubmitting(true);
2758
+ try {
2759
+ const unitAmountInCents = Math.round(values.unitAmount * 100);
2760
+ if (isEditMode) {
2761
+ await _chunkNQVPCNRSjs.StripePriceService.updatePrice({
2762
+ id: price.id,
2763
+ nickname: values.nickname || void 0,
2764
+ description: values.description || void 0,
2765
+ features: values.features.filter((f) => f.trim()) || void 0
2766
+ });
2767
+ } else {
2768
+ const createInput = {
2769
+ id: _uuid.v4.call(void 0, ),
2770
+ productId,
2771
+ currency: values.currency,
2772
+ unitAmount: unitAmountInCents
2773
+ };
2774
+ if (isRecurring) {
2775
+ createInput.recurring = {
2776
+ interval: values.interval,
2777
+ intervalCount: values.intervalCount || 1,
2778
+ usageType: values.usageType || "licensed"
2779
+ };
2780
+ }
2781
+ if (values.nickname) {
2782
+ createInput.nickname = values.nickname;
2783
+ }
2784
+ if (values.description) {
2785
+ createInput.description = values.description;
2786
+ }
2787
+ const filteredFeatures = values.features.filter((f) => f.trim());
2788
+ if (filteredFeatures.length > 0) {
2789
+ createInput.features = filteredFeatures;
2790
+ }
2791
+ await _chunkNQVPCNRSjs.StripePriceService.createPrice(createInput);
2792
+ }
2793
+ onSuccess();
2794
+ onOpenChange(false);
2795
+ } catch (error) {
2796
+ console.error("[PriceEditor] Failed to save price:", error);
2797
+ } finally {
2798
+ setIsSubmitting(false);
2799
+ }
2800
+ }, "onSubmit");
2801
+ const currencyOptions = [
2802
+ { id: "usd", text: "USD ($)" },
2803
+ { id: "eur", text: "EUR (\u20AC)" },
2804
+ { id: "gbp", text: "GBP (\xA3)" }
2805
+ ];
2806
+ const intervalOptions = [
2807
+ { id: "one_time", text: "One-time" },
2808
+ { id: "day", text: "Daily" },
2809
+ { id: "week", text: "Weekly" },
2810
+ { id: "month", text: "Monthly" },
2811
+ { id: "year", text: "Yearly" }
2812
+ ];
2813
+ const usageTypeOptions = [
2814
+ { id: "licensed", text: "Licensed (per unit)" },
2815
+ { id: "metered", text: "Metered (usage-based)" }
2816
+ ];
2817
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogContent, { className: "max-w-2xl", children: [
2818
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogHeader, { children: [
2819
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogTitle, { children: isEditMode ? "Edit Price" : "Create Price" }),
2820
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogDescription, { children: isEditMode ? "Update the price details. Note: Only nickname and active status can be changed." : "Create a new price for this product" })
2821
+ ] }),
2822
+ isEditMode && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4 flex gap-x-3", children: [
2823
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertCircle, { className: "h-5 w-5 text-blue-600 flex-shrink-0 mt-0.5" }),
2824
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-sm text-blue-800", children: [
2825
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-semibold mb-1", children: "Stripe Price Immutability" }),
2826
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "Due to Stripe's architecture, only the nickname and active status can be modified after creation. To change amount, currency, or billing interval, create a new price." })
2827
+ ] })
2828
+ ] }),
2829
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Form, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
2830
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-x-4", children: [
2831
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2832
+ _chunkILKUML3Zjs.FormInput,
2833
+ {
2834
+ form,
2835
+ id: "unitAmount",
2836
+ name: "Amount (in dollars)",
2837
+ placeholder: "9.99",
2838
+ disabled: isEditMode,
2839
+ isRequired: true
2840
+ }
2841
+ ),
2842
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.FormSelect, { form, id: "currency", name: "Currency", values: currencyOptions, disabled: isEditMode })
2843
+ ] }),
2844
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2845
+ _chunkILKUML3Zjs.FormSelect,
2846
+ {
2847
+ form,
2848
+ id: "interval",
2849
+ name: "Billing Interval",
2850
+ values: intervalOptions,
2851
+ disabled: isEditMode
2852
+ }
2853
+ ),
2854
+ isRecurring && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-x-4", children: [
2855
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2856
+ _chunkILKUML3Zjs.FormInput,
2857
+ {
2858
+ form,
2859
+ id: "intervalCount",
2860
+ name: "Interval Count",
2861
+ placeholder: "1",
2862
+ type: "number",
2863
+ disabled: isEditMode
2864
+ }
2865
+ ),
2866
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2867
+ _chunkILKUML3Zjs.FormSelect,
2868
+ {
2869
+ form,
2870
+ id: "usageType",
2871
+ name: "Usage Type",
2872
+ values: usageTypeOptions,
2873
+ disabled: isEditMode
2874
+ }
2875
+ )
2876
+ ] }),
2877
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2878
+ _chunkILKUML3Zjs.FormInput,
2879
+ {
2880
+ form,
2881
+ id: "nickname",
2882
+ name: "Nickname (optional)",
2883
+ placeholder: "e.g., Standard Plan, Pro Tier"
2884
+ }
2885
+ ),
2886
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2887
+ _chunkILKUML3Zjs.FormTextarea,
2888
+ {
2889
+ form,
2890
+ id: "description",
2891
+ name: "Description (optional)",
2892
+ placeholder: "Describe what this price tier includes...",
2893
+ className: "min-h-24"
2894
+ }
2895
+ ),
2896
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.FormItem, { children: [
2897
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.FormLabel, { children: "Features (optional)" }),
2898
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
2899
+ form.watch("features").map((_, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2", children: [
2900
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.FormControl, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2901
+ _chunkILKUML3Zjs.Input,
2902
+ {
2903
+ ...form.register(`features.${index}`),
2904
+ placeholder: `Feature ${index + 1}`,
2905
+ className: "flex-1"
2906
+ }
2907
+ ) }),
2908
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2909
+ _chunkILKUML3Zjs.Button,
2910
+ {
2911
+ type: "button",
2912
+ variant: "outline",
2913
+ size: "icon",
2914
+ onClick: () => {
2915
+ const currentFeatures = form.getValues("features");
2916
+ form.setValue(
2917
+ "features",
2918
+ currentFeatures.filter((_2, i) => i !== index)
2919
+ );
2920
+ },
2921
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.XIcon, { className: "h-4 w-4" })
2922
+ }
2923
+ )
2924
+ ] }, index)),
2925
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2926
+ _chunkILKUML3Zjs.Button,
2927
+ {
2928
+ type: "button",
2929
+ variant: "outline",
2930
+ size: "sm",
2931
+ onClick: () => {
2932
+ const currentFeatures = form.getValues("features");
2933
+ form.setValue("features", [...currentFeatures, ""]);
2934
+ },
2935
+ className: "mt-2",
2936
+ children: [
2937
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.PlusIcon, { className: "h-4 w-4 mr-2" }),
2938
+ "Add Feature"
2939
+ ]
2940
+ }
2941
+ )
2942
+ ] })
2943
+ ] }),
2944
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.FormCheckbox, { form, id: "active", name: "Active" }),
2945
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CommonEditorButtons, { isEdit: isEditMode, form, disabled: isSubmitting, setOpen: onOpenChange })
2946
+ ] }) })
2947
+ ] }) });
2948
+ }
2949
+ _chunk7QVYU63Ejs.__name.call(void 0, PriceEditor, "PriceEditor");
2950
+
2951
+ // src/features/billing/stripe-price/components/lists/PricesList.tsx
2952
+
2953
+
2954
+
2955
+ function PricesList({ productId, onPricesChange }) {
2956
+ const [prices, setPrices] = _react.useState.call(void 0, []);
2957
+ const [loading, setLoading] = _react.useState.call(void 0, true);
2958
+ const [showCreatePrice, setShowCreatePrice] = _react.useState.call(void 0, false);
2959
+ const [editingPrice, setEditingPrice] = _react.useState.call(void 0, null);
2960
+ const [priceToArchive, setPriceToArchive] = _react.useState.call(void 0, null);
2961
+ const [priceToReactivate, setPriceToReactivate] = _react.useState.call(void 0, null);
2962
+ const [archivingPriceId, setArchivingPriceId] = _react.useState.call(void 0, null);
2963
+ const [reactivatingPriceId, setReactivatingPriceId] = _react.useState.call(void 0, null);
2964
+ const loadPrices = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2965
+ setLoading(true);
2966
+ try {
2967
+ const fetchedPrices = await _chunkNQVPCNRSjs.StripePriceService.listPrices({ productId });
2968
+ setPrices(fetchedPrices);
2969
+ } catch (error) {
2970
+ console.error("[PricesList] Failed to load prices:", error);
2971
+ } finally {
2972
+ setLoading(false);
2973
+ }
2974
+ }, "loadPrices");
2975
+ _react.useEffect.call(void 0, () => {
2976
+ loadPrices();
2977
+ }, [productId]);
2978
+ const handleArchive = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2979
+ if (!priceToArchive) {
2980
+ return;
2981
+ }
2982
+ setArchivingPriceId(priceToArchive.id);
2983
+ try {
2984
+ await _chunkNQVPCNRSjs.StripePriceService.archivePrice({ id: priceToArchive.id });
2985
+ setPriceToArchive(null);
2986
+ await loadPrices();
2987
+ onPricesChange();
2988
+ } catch (error) {
2989
+ console.error("[PricesList] Failed to archive price:", error);
2990
+ } finally {
2991
+ setArchivingPriceId(null);
2992
+ }
2993
+ }, "handleArchive");
2994
+ const handleReactivate = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
2995
+ if (!priceToReactivate) {
2996
+ return;
2997
+ }
2998
+ setReactivatingPriceId(priceToReactivate.id);
2999
+ try {
3000
+ await _chunkNQVPCNRSjs.StripePriceService.reactivatePrice({ id: priceToReactivate.id });
3001
+ setPriceToReactivate(null);
3002
+ await loadPrices();
3003
+ onPricesChange();
3004
+ } catch (error) {
3005
+ console.error("[PricesList] Failed to reactivate price:", error);
3006
+ } finally {
3007
+ setReactivatingPriceId(null);
3008
+ }
3009
+ }, "handleReactivate");
3010
+ const formatInterval2 = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (price) => {
3011
+ if (price.priceType === "one_time") {
3012
+ return "one-time";
3013
+ }
3014
+ if (price.recurring) {
3015
+ const count = price.recurring.intervalCount;
3016
+ const interval = price.recurring.interval;
3017
+ if (count === 1) {
3018
+ return `/ ${interval}`;
3019
+ } else {
3020
+ return `/ ${count} ${interval}s`;
3021
+ }
3022
+ }
3023
+ return "";
3024
+ }, "formatInterval");
3025
+ if (loading) {
3026
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground", children: "Loading prices..." }) });
3027
+ }
3028
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-y-4", children: [
3029
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between mb-4", children: [
3030
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "text-lg font-semibold", children: "Prices" }),
3031
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
3032
+ ] }),
3033
+ prices.length === 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-background flex flex-col items-center justify-center gap-y-3 rounded-lg border border-dashed p-8", children: [
3034
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.DollarSign, { className: "text-muted-foreground h-12 w-12" }),
3035
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground text-sm", children: "No prices yet. Add a price to enable subscriptions." }),
3036
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
3037
+ ] }),
3038
+ prices.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: prices.map((price) => {
3039
+ const isArchiving = archivingPriceId === price.id;
3040
+ const isReactivating = reactivatingPriceId === price.id;
3041
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "border rounded-lg bg-white p-4 hover:shadow-sm transition-shadow", children: [
3042
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-start justify-between mb-3", children: [
3043
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.DollarSign, { className: "h-5 w-5 text-primary" }),
3044
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-1", children: [
3045
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "ghost", size: "sm", onClick: () => setEditingPrice(price), className: "h-8 w-8 p-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Edit, { className: "h-4 w-4" }) }),
3046
+ price.active ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3047
+ _chunkILKUML3Zjs.Button,
3048
+ {
3049
+ variant: "ghost",
3050
+ size: "sm",
3051
+ onClick: () => setPriceToArchive(price),
3052
+ className: "h-8 w-8 p-0",
3053
+ disabled: isArchiving,
3054
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Archive, { className: "h-4 w-4" })
3055
+ }
3056
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3057
+ _chunkILKUML3Zjs.Button,
3058
+ {
3059
+ variant: "ghost",
3060
+ size: "sm",
3061
+ onClick: () => setPriceToReactivate(price),
3062
+ className: "h-8 w-8 p-0",
3063
+ disabled: isReactivating,
3064
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.RotateCcw, { className: "h-4 w-4" })
3065
+ }
3066
+ )
3067
+ ] })
3068
+ ] }),
3069
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "mb-2", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-2xl font-bold", children: [
3070
+ formatCurrency(price.unitAmount, price.currency),
3071
+ " ",
3072
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-muted-foreground text-sm font-normal", children: formatInterval2(price) })
3073
+ ] }) }),
3074
+ _optionalChain([price, 'access', _92 => _92.metadata, 'optionalAccess', _93 => _93.nickname]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm font-medium mb-2", children: price.metadata.nickname }),
3075
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap gap-2", children: [
3076
+ price.active ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium", children: "Active" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium", children: "Inactive" }),
3077
+ _optionalChain([price, 'access', _94 => _94.recurring, 'optionalAccess', _95 => _95.usageType]) === "metered" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full font-medium", children: "Metered" }),
3078
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium uppercase", children: price.currency })
3079
+ ] })
3080
+ ] }, price.id);
3081
+ }) }),
3082
+ showCreatePrice && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3083
+ PriceEditor,
3084
+ {
3085
+ productId,
3086
+ open: showCreatePrice,
3087
+ onOpenChange: setShowCreatePrice,
3088
+ onSuccess: () => {
3089
+ loadPrices();
3090
+ onPricesChange();
3091
+ }
3092
+ }
3093
+ ),
3094
+ editingPrice && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3095
+ PriceEditor,
3096
+ {
3097
+ productId,
3098
+ price: editingPrice,
3099
+ open: !!editingPrice,
3100
+ onOpenChange: (open) => !open && setEditingPrice(null),
3101
+ onSuccess: () => {
3102
+ loadPrices();
3103
+ onPricesChange();
3104
+ setEditingPrice(null);
3105
+ }
3106
+ }
3107
+ ),
3108
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialog, { open: !!priceToArchive, onOpenChange: (open) => !open && setPriceToArchive(null), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogContent, { children: [
3109
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogHeader, { children: [
3110
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogTitle, { children: "Archive Price" }),
3111
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogDescription, { children: [
3112
+ "Are you sure you want to archive the price for",
3113
+ " ",
3114
+ priceToArchive && `${formatCurrency(priceToArchive.unitAmount, priceToArchive.currency)} ${formatInterval2(priceToArchive)}`,
3115
+ "? This will prevent new subscriptions but existing ones will continue."
3116
+ ] })
3117
+ ] }),
3118
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogFooter, { children: [
3119
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogCancel, { disabled: !!archivingPriceId, children: "Cancel" }),
3120
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3121
+ _chunkILKUML3Zjs.AlertDialogAction,
3122
+ {
3123
+ onClick: handleArchive,
3124
+ disabled: !!archivingPriceId,
3125
+ className: "bg-red-600 hover:bg-red-700",
3126
+ children: archivingPriceId ? "Archiving..." : "Archive"
3127
+ }
3128
+ )
3129
+ ] })
3130
+ ] }) }),
3131
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialog, { open: !!priceToReactivate, onOpenChange: (open) => !open && setPriceToReactivate(null), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogContent, { children: [
3132
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogHeader, { children: [
3133
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogTitle, { children: "Reactivate Price" }),
3134
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogDescription, { children: [
3135
+ "Are you sure you want to reactivate the price for",
3136
+ " ",
3137
+ priceToReactivate && `${formatCurrency(priceToReactivate.unitAmount, priceToReactivate.currency)} ${formatInterval2(priceToReactivate)}`,
3138
+ "? This will allow new subscriptions again."
3139
+ ] })
3140
+ ] }),
3141
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogFooter, { children: [
3142
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogCancel, { disabled: !!reactivatingPriceId, children: "Cancel" }),
3143
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3144
+ _chunkILKUML3Zjs.AlertDialogAction,
3145
+ {
3146
+ onClick: handleReactivate,
3147
+ disabled: !!reactivatingPriceId,
3148
+ className: "bg-green-600 hover:bg-green-700",
3149
+ children: reactivatingPriceId ? "Reactivating..." : "Reactivate"
3150
+ }
3151
+ )
3152
+ ] })
3153
+ ] }) })
3154
+ ] });
3155
+ }
3156
+ _chunk7QVYU63Ejs.__name.call(void 0, PricesList, "PricesList");
3157
+
3158
+ // src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx
3159
+
3160
+
3161
+
3162
+ // src/features/billing/stripe-product/components/forms/ProductEditor.tsx
3163
+
3164
+
3165
+
3166
+
3167
+
3168
+
3169
+ function ProductEditor({ product, open, onOpenChange, onSuccess }) {
3170
+ const [isSubmitting, setIsSubmitting] = _react.useState.call(void 0, false);
3171
+ const formSchema2 = _zod3.z.object({
3172
+ name: _zod3.z.string().min(1, { message: "Product name is required" }),
3173
+ description: _zod3.z.string().optional(),
3174
+ active: _zod3.z.boolean()
3175
+ });
3176
+ const form = _reacthookform.useForm.call(void 0, {
3177
+ resolver: _zod.zodResolver.call(void 0, formSchema2),
3178
+ defaultValues: {
3179
+ name: _optionalChain([product, 'optionalAccess', _96 => _96.name]) || "",
3180
+ description: _optionalChain([product, 'optionalAccess', _97 => _97.description]) || "",
3181
+ active: _nullishCoalesce(_optionalChain([product, 'optionalAccess', _98 => _98.active]), () => ( true))
3182
+ }
3183
+ });
3184
+ const onSubmit = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (values) => {
3185
+ setIsSubmitting(true);
3186
+ try {
3187
+ if (product) {
3188
+ await _chunkNQVPCNRSjs.StripeProductService.updateProduct({
3189
+ id: product.id,
3190
+ name: values.name,
3191
+ description: values.description,
3192
+ active: values.active
3193
+ });
3194
+ } else {
3195
+ await _chunkNQVPCNRSjs.StripeProductService.createProduct({
3196
+ id: _uuid.v4.call(void 0, ),
3197
+ name: values.name,
3198
+ description: values.description,
3199
+ active: values.active
3200
+ });
3201
+ }
3202
+ onSuccess();
3203
+ onOpenChange(false);
3204
+ } catch (error) {
3205
+ console.error("[ProductEditor] Failed to save product:", error);
3206
+ } finally {
3207
+ setIsSubmitting(false);
3208
+ }
3209
+ }, "onSubmit");
3210
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogContent, { className: "max-w-2xl", children: [
3211
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.DialogHeader, { children: [
3212
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogTitle, { children: product ? "Edit Product" : "Create Product" }),
3213
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.DialogDescription, { children: product ? `Update the details for ${product.name}` : "Create a new product to offer to your customers" })
3214
+ ] }),
3215
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Form, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
3216
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.FormInput, { form, id: "name", name: "Product Name", placeholder: "Enter product name", isRequired: true }),
3217
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3218
+ _chunkILKUML3Zjs.FormTextarea,
3219
+ {
3220
+ form,
3221
+ id: "description",
3222
+ name: "Description",
3223
+ placeholder: "Enter product description (optional)",
3224
+ className: "min-h-32"
3225
+ }
3226
+ ),
3227
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.FormCheckbox, { form, id: "active", name: "Active" }),
3228
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.CommonEditorButtons, { isEdit: !!product, form, disabled: isSubmitting, setOpen: onOpenChange })
3229
+ ] }) })
3230
+ ] }) });
3231
+ }
3232
+ _chunk7QVYU63Ejs.__name.call(void 0, ProductEditor, "ProductEditor");
3233
+
3234
+ // src/features/billing/stripe-product/components/lists/ProductsList.tsx
3235
+
3236
+
3237
+
3238
+ function ProductsList({ products, onProductsChange }) {
3239
+ const [expandedProductId, setExpandedProductId] = _react.useState.call(void 0, null);
3240
+ const [editingProduct, setEditingProduct] = _react.useState.call(void 0, null);
3241
+ const [archivingProductId, setArchivingProductId] = _react.useState.call(void 0, null);
3242
+ const [reactivatingProductId, setReactivatingProductId] = _react.useState.call(void 0, null);
3243
+ const [productToArchive, setProductToArchive] = _react.useState.call(void 0, null);
3244
+ const [productToReactivate, setProductToReactivate] = _react.useState.call(void 0, null);
3245
+ const handleArchive = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
3246
+ if (!productToArchive) {
3247
+ return;
3248
+ }
3249
+ setArchivingProductId(productToArchive.id);
3250
+ try {
3251
+ const archivedProduct = await _chunkNQVPCNRSjs.StripeProductService.archiveProduct({ id: productToArchive.id });
3252
+ setProductToArchive(null);
3253
+ onProductsChange();
3254
+ } catch (error) {
3255
+ console.error("[ProductsList] Failed to archive product:", error);
3256
+ } finally {
3257
+ setArchivingProductId(null);
3258
+ }
3259
+ }, "handleArchive");
3260
+ const handleReactivate = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
3261
+ if (!productToReactivate) {
3262
+ return;
3263
+ }
3264
+ setReactivatingProductId(productToReactivate.id);
3265
+ try {
3266
+ const reactivatedProduct = await _chunkNQVPCNRSjs.StripeProductService.reactivateProduct({ id: productToReactivate.id });
3267
+ setProductToReactivate(null);
3268
+ onProductsChange();
3269
+ } catch (error) {
3270
+ } finally {
3271
+ setReactivatingProductId(null);
3272
+ }
3273
+ }, "handleReactivate");
3274
+ const toggleExpand = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (productId) => {
3275
+ setExpandedProductId(expandedProductId === productId ? null : productId);
3276
+ }, "toggleExpand");
3277
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-y-4", children: [
3278
+ products.map((product) => {
3279
+ const isExpanded = expandedProductId === product.id;
3280
+ const isArchiving = archivingProductId === product.id;
3281
+ const isReactivating = reactivatingProductId === product.id;
3282
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "border rounded-lg bg-white shadow-sm hover:shadow-md transition-shadow", children: [
3283
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between p-6", children: [
3284
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-4 flex-1", children: [
3285
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Package, { className: "h-6 w-6 text-primary" }),
3286
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex-1", children: [
3287
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
3288
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-lg font-semibold", children: product.name }),
3289
+ product.active ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium", children: "Active" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium", children: "Inactive" })
3290
+ ] }),
3291
+ product.description && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground text-sm mt-1", children: product.description })
3292
+ ] })
3293
+ ] }),
3294
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-2", children: [
3295
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.Button, { variant: "outline", size: "sm", onClick: () => setEditingProduct(product), children: [
3296
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Edit, { className: "h-4 w-4 mr-1" }),
3297
+ "Edit"
3298
+ ] }),
3299
+ product.active ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3300
+ _chunkILKUML3Zjs.Button,
3301
+ {
3302
+ variant: "outline",
3303
+ size: "sm",
3304
+ onClick: () => setProductToArchive(product),
3305
+ disabled: isArchiving,
3306
+ children: [
3307
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Archive, { className: "h-4 w-4 mr-1" }),
3308
+ isArchiving ? "Archiving..." : "Archive"
3309
+ ]
3310
+ }
3311
+ ) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3312
+ _chunkILKUML3Zjs.Button,
3313
+ {
3314
+ variant: "outline",
3315
+ size: "sm",
3316
+ onClick: () => setProductToReactivate(product),
3317
+ disabled: isReactivating,
3318
+ children: [
3319
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.RefreshCw, { className: "h-4 w-4 mr-1" }),
3320
+ isReactivating ? "Reactivating..." : "Reactivate"
3321
+ ]
3322
+ }
3323
+ ),
3324
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { variant: "ghost", size: "sm", onClick: () => toggleExpand(product.id), children: isExpanded ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronUp, { className: "h-5 w-5" }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ChevronDown, { className: "h-5 w-5" }) })
3325
+ ] })
3326
+ ] }),
3327
+ isExpanded && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border-t bg-muted/30 p-6", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PricesList, { productId: product.id, onPricesChange: onProductsChange }) })
3328
+ ] }, product.id);
3329
+ }),
3330
+ editingProduct && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3331
+ ProductEditor,
3332
+ {
3333
+ product: editingProduct,
3334
+ open: !!editingProduct,
3335
+ onOpenChange: (open) => !open && setEditingProduct(null),
3336
+ onSuccess: () => {
3337
+ onProductsChange();
3338
+ setEditingProduct(null);
3339
+ }
3340
+ }
3341
+ ),
3342
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialog, { open: !!productToArchive, onOpenChange: (open) => !open && setProductToArchive(null), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogContent, { children: [
3343
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogHeader, { children: [
3344
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogTitle, { children: "Archive Product" }),
3345
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogDescription, { children: [
3346
+ 'Are you sure you want to archive "',
3347
+ _optionalChain([productToArchive, 'optionalAccess', _99 => _99.name]),
3348
+ '"? This will deactivate it and it will no longer be available for new subscriptions.'
3349
+ ] })
3350
+ ] }),
3351
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogFooter, { children: [
3352
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogCancel, { disabled: !!archivingProductId, children: "Cancel" }),
3353
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3354
+ _chunkILKUML3Zjs.AlertDialogAction,
3355
+ {
3356
+ onClick: handleArchive,
3357
+ disabled: !!archivingProductId,
3358
+ className: "bg-red-600 hover:bg-red-700",
3359
+ children: archivingProductId ? "Archiving..." : "Archive"
3360
+ }
3361
+ )
3362
+ ] })
3363
+ ] }) }),
3364
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialog, { open: !!productToReactivate, onOpenChange: (open) => !open && setProductToReactivate(null), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogContent, { children: [
3365
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogHeader, { children: [
3366
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogTitle, { children: "Reactivate Product" }),
3367
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogDescription, { children: [
3368
+ 'Are you sure you want to reactivate "',
3369
+ _optionalChain([productToReactivate, 'optionalAccess', _100 => _100.name]),
3370
+ '"? This will make it available for new subscriptions again.'
3371
+ ] })
3372
+ ] }),
3373
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkILKUML3Zjs.AlertDialogFooter, { children: [
3374
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.AlertDialogCancel, { disabled: !!reactivatingProductId, children: "Cancel" }),
3375
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3376
+ _chunkILKUML3Zjs.AlertDialogAction,
3377
+ {
3378
+ onClick: handleReactivate,
3379
+ disabled: !!reactivatingProductId,
3380
+ className: "bg-green-600 hover:bg-green-700",
3381
+ children: reactivatingProductId ? "Reactivating..." : "Reactivate"
3382
+ }
3383
+ )
3384
+ ] })
3385
+ ] }) })
3386
+ ] });
3387
+ }
3388
+ _chunk7QVYU63Ejs.__name.call(void 0, ProductsList, "ProductsList");
3389
+
3390
+ // src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx
3391
+
3392
+ function ProductsAdminContainer() {
3393
+ const { hasRole } = _chunkILKUML3Zjs.useCurrentUserContext.call(void 0, );
3394
+ const [products, setProducts] = _react.useState.call(void 0, []);
3395
+ const [loading, setLoading] = _react.useState.call(void 0, true);
3396
+ const [showCreateProduct, setShowCreateProduct] = _react.useState.call(void 0, false);
3397
+ if (!hasRole(_chunkEW6QPMN3js.getRoleId.call(void 0, ).Administrator)) {
3398
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-red-600 font-semibold", children: "Permission denied. Administrator access required." }) });
3399
+ }
3400
+ const loadProducts = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
3401
+ setLoading(true);
3402
+ try {
3403
+ const fetchedProducts = await _chunkNQVPCNRSjs.StripeProductService.listProducts();
3404
+ setProducts(fetchedProducts);
3405
+ } catch (error) {
3406
+ console.error("[ProductsAdminContainer] Failed to load products:", error);
3407
+ } finally {
3408
+ setLoading(false);
3409
+ }
3410
+ }, "loadProducts");
3411
+ _react.useEffect.call(void 0, () => {
3412
+ loadProducts();
3413
+ }, []);
3414
+ if (loading) {
3415
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground", children: "Loading products..." }) });
3416
+ }
3417
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-y-6", children: [
3418
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between", children: [
3419
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
3420
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Package, { className: "h-8 w-8" }),
3421
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Product & Price Management" })
3422
+ ] }),
3423
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { onClick: () => setShowCreateProduct(true), children: "Create Product" })
3424
+ ] }),
3425
+ products.length === 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed p-12", children: [
3426
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Package, { className: "text-muted-foreground h-16 w-16" }),
3427
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
3428
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-2 text-xl font-semibold", children: "No products yet" }),
3429
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground mb-4", children: "Create your first product to start offering subscriptions to your customers." }),
3430
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkILKUML3Zjs.Button, { onClick: () => setShowCreateProduct(true), children: "Create Your First Product" })
3431
+ ] })
3432
+ ] }),
3433
+ products.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ProductsList, { products, onProductsChange: loadProducts }),
3434
+ showCreateProduct && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ProductEditor, { open: showCreateProduct, onOpenChange: setShowCreateProduct, onSuccess: loadProducts })
3435
+ ] });
3436
+ }
3437
+ _chunk7QVYU63Ejs.__name.call(void 0, ProductsAdminContainer, "ProductsAdminContainer");
3438
+
3439
+
3440
+
3441
+
3442
+
3443
+
3444
+
3445
+
3446
+
3447
+
3448
+
3449
+
3450
+
3451
+
3452
+
3453
+
3454
+
3455
+
3456
+
3457
+
3458
+
3459
+
3460
+
3461
+
3462
+
3463
+
3464
+
3465
+
3466
+
3467
+
3468
+
3469
+
3470
+
3471
+
3472
+
3473
+
3474
+
3475
+
3476
+
3477
+
3478
+ exports.BillingAlertBanner = BillingAlertBanner; exports.BillingDashboardContainer = BillingDashboardContainer; exports.BillingDetailModal = BillingDetailModal; exports.BillingUsageSummaryCard = BillingUsageSummaryCard; exports.CancelSubscriptionDialog = CancelSubscriptionDialog; exports.CustomerInfoCard = CustomerInfoCard; exports.InvoiceDetails = InvoiceDetails; exports.InvoiceStatusBadge = InvoiceStatusBadge; exports.InvoicesContainer = InvoicesContainer; exports.InvoicesList = InvoicesList; exports.InvoicesSummaryCard = InvoicesSummaryCard; exports.PaymentMethodCard = PaymentMethodCard; exports.PaymentMethodEditor = PaymentMethodEditor; exports.PaymentMethodSummaryCard = PaymentMethodSummaryCard; exports.PaymentMethodsContainer = PaymentMethodsContainer; exports.PaymentMethodsList = PaymentMethodsList; exports.PriceEditor = PriceEditor; exports.PricesList = PricesList; exports.PricingCard = PricingCard; exports.PricingCardsGrid = PricingCardsGrid; exports.ProductEditor = ProductEditor; exports.ProductsAdminContainer = ProductsAdminContainer; exports.ProductsList = ProductsList; exports.ProrationPreview = ProrationPreview; exports.StripeProvider = StripeProvider; exports.SubscriptionDetails = SubscriptionDetails; exports.SubscriptionEditor = SubscriptionEditor; exports.SubscriptionStatusBadge = SubscriptionStatusBadge; exports.SubscriptionSummaryCard = SubscriptionSummaryCard; exports.SubscriptionsContainer = SubscriptionsContainer; exports.SubscriptionsList = SubscriptionsList; exports.UsageContainer = UsageContainer; exports.UsageHistoryTable = UsageHistoryTable; exports.UsageSummaryCard = UsageSummaryCard; exports.UsageSummaryCards = UsageSummaryCards; exports.formatCurrency = formatCurrency; exports.formatDate = formatDate3; exports.formatInterval = formatInterval; exports.isStripeConfigured = isStripeConfigured;
3479
+ //# sourceMappingURL=index.js.map