@carlonicora/nextjs-jsonapi 1.28.0 → 1.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BlockNoteEditor-CAUNVZUF.js → BlockNoteEditor-YBVEOPV4.js} +13 -13
- package/dist/{BlockNoteEditor-CAUNVZUF.js.map → BlockNoteEditor-YBVEOPV4.js.map} +1 -1
- package/dist/{BlockNoteEditor-EOA4OEVX.mjs → BlockNoteEditor-ZM4YPXHO.mjs} +3 -3
- package/dist/billing/index.d.mts +47 -17
- package/dist/billing/index.d.ts +47 -17
- package/dist/billing/index.js +1241 -1073
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +1375 -1207
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-IXI4GAKB.js → chunk-3X7EEFMN.js} +488 -431
- package/dist/chunk-3X7EEFMN.js.map +1 -0
- package/dist/{chunk-ORFXBO7F.mjs → chunk-DU64WMZD.mjs} +6 -3
- package/dist/chunk-DU64WMZD.mjs.map +1 -0
- package/dist/{chunk-TSEU4KZ2.js → chunk-J22NEVSK.js} +21 -18
- package/dist/chunk-J22NEVSK.js.map +1 -0
- package/dist/{chunk-PYASRX75.mjs → chunk-UCD5CUE4.mjs} +81 -24
- package/dist/chunk-UCD5CUE4.mjs.map +1 -0
- package/dist/client/index.d.mts +14 -5
- package/dist/client/index.d.ts +14 -5
- package/dist/client/index.js +5 -3
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +4 -2
- package/dist/components/index.d.mts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +3 -3
- package/dist/components/index.mjs +2 -2
- package/dist/{config-B4pZpLT9.d.ts → config-CHwoRDOp.d.ts} +1 -1
- package/dist/{config-DT1K-t6I.d.mts → config-DiWyJzk9.d.mts} +1 -1
- package/dist/{content.interface-B2Ldg0vg.d.mts → content.interface-BSpowEiW.d.mts} +1 -1
- package/dist/{content.interface-D8NHv3DX.d.ts → content.interface-DFQ7mkpL.d.ts} +1 -1
- package/dist/contexts/index.d.mts +2 -2
- package/dist/contexts/index.d.ts +2 -2
- package/dist/contexts/index.js +3 -3
- package/dist/contexts/index.mjs +2 -2
- package/dist/core/index.d.mts +39 -37
- package/dist/core/index.d.ts +39 -37
- package/dist/core/index.js +2 -2
- package/dist/core/index.mjs +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/{notification.interface-H0L9WBge.d.ts → notification.interface-CmKmObIU.d.ts} +1 -0
- package/dist/{notification.interface-DEn-Yp_b.d.mts → notification.interface-D5MbtfZK.d.mts} +1 -0
- package/dist/{s3.service-BNytYanU.d.mts → s3.service-BMT7W6KS.d.mts} +19 -19
- package/dist/{s3.service-C7f_Ygz5.d.ts → s3.service-DsXo9nop.d.ts} +19 -19
- package/dist/server/index.d.mts +3 -3
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/dist/{useSocket-BcnThTD0.d.mts → useSocket-DUqGoPya.d.mts} +1 -1
- package/dist/{useSocket-QZTOCzRF.d.ts → useSocket-QuHa0ZmO.d.ts} +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +1 -0
- package/src/components/forms/FormSelect.tsx +2 -1
- package/src/features/auth/data/auth.ts +0 -2
- package/src/features/billing/components/containers/BillingDashboardContainer.tsx +60 -3
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +12 -152
- package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +168 -0
- package/src/features/billing/stripe-customer/components/forms/index.ts +1 -0
- package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +19 -1
- package/src/features/billing/stripe-product/components/forms/ProductEditor.tsx +2 -2
- package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +24 -235
- package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +7 -18
- package/src/features/billing/stripe-subscription/components/forms/index.ts +0 -1
- package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +10 -1
- package/src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx +28 -0
- package/src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx +128 -0
- package/src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx +54 -0
- package/src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx +68 -0
- package/src/features/billing/stripe-subscription/components/widgets/index.ts +4 -1
- package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +114 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx +66 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +32 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx +103 -0
- package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +133 -0
- package/src/features/billing/stripe-subscription/components/wizards/index.ts +6 -0
- package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +217 -0
- package/src/features/billing/stripe-subscription/index.ts +3 -2
- package/src/features/company/components/details/TokenStatusIndicator.tsx +19 -9
- package/src/features/company/data/company.interface.ts +2 -0
- package/src/features/company/data/company.ts +7 -0
- package/src/features/company/hooks/index.ts +1 -0
- package/src/features/company/hooks/useSubscriptionStatus.ts +71 -0
- package/src/features/user/components/forms/UserEditor.tsx +1 -1
- package/src/features/user/components/lists/AdminUsersList.tsx +1 -1
- package/src/features/user/contexts/CurrentUserContext.tsx +1 -1
- package/src/features/user/data/user.ts +1 -1
- package/dist/chunk-IXI4GAKB.js.map +0 -1
- package/dist/chunk-ORFXBO7F.mjs.map +0 -1
- package/dist/chunk-PYASRX75.mjs.map +0 -1
- package/dist/chunk-TSEU4KZ2.js.map +0 -1
- package/src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx +0 -331
- package/src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx +0 -110
- /package/dist/{BlockNoteEditor-EOA4OEVX.mjs.map → BlockNoteEditor-ZM4YPXHO.mjs.map} +0 -0
package/dist/billing/index.js
CHANGED
|
@@ -47,8 +47,7 @@
|
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
var _chunkIXI4GAKBjs = require('../chunk-IXI4GAKB.js');
|
|
50
|
+
var _chunk3X7EEFMNjs = require('../chunk-3X7EEFMN.js');
|
|
52
51
|
|
|
53
52
|
|
|
54
53
|
|
|
@@ -61,7 +60,7 @@ var _chunkEW6QPMN3js = require('../chunk-EW6QPMN3.js');
|
|
|
61
60
|
|
|
62
61
|
|
|
63
62
|
|
|
64
|
-
var
|
|
63
|
+
var _chunkJ22NEVSKjs = require('../chunk-J22NEVSK.js');
|
|
65
64
|
require('../chunk-LXKSUWAV.js');
|
|
66
65
|
require('../chunk-IBS6NI7D.js');
|
|
67
66
|
require('../chunk-FM6WRAN5.js');
|
|
@@ -121,41 +120,41 @@ function SubscriptionSummaryCard({
|
|
|
121
120
|
onManageClick
|
|
122
121
|
}) {
|
|
123
122
|
if (loading) {
|
|
124
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
125
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
126
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
123
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
124
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
125
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Subscriptions" }),
|
|
127
126
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-4 w-4 text-muted-foreground" })
|
|
128
127
|
] }),
|
|
129
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
130
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
131
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
132
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
128
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: [
|
|
129
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-6 w-32 mb-2" }),
|
|
130
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-24 mb-1" }),
|
|
131
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-40" })
|
|
133
132
|
] })
|
|
134
133
|
] });
|
|
135
134
|
}
|
|
136
135
|
if (error) {
|
|
137
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
138
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
139
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
136
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
137
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
138
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Subscriptions" }),
|
|
140
139
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-4 w-4 text-muted-foreground" })
|
|
141
140
|
] }),
|
|
142
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
141
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
|
|
143
142
|
] });
|
|
144
143
|
}
|
|
145
144
|
const activeSubscriptions = subscriptions.filter(
|
|
146
145
|
(sub) => sub.status === "active" /* ACTIVE */ || sub.status === "trialing" /* TRIALING */
|
|
147
146
|
);
|
|
148
147
|
const primarySubscription = activeSubscriptions[0];
|
|
149
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
150
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
151
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
148
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { className: "cursor-pointer hover:bg-accent/50 transition-colors", onClick: onManageClick, children: [
|
|
149
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
150
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Subscriptions" }),
|
|
152
151
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-4 w-4 text-muted-foreground" })
|
|
153
152
|
] }),
|
|
154
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
153
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: subscriptions.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
155
154
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "No active plan" }),
|
|
156
155
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "Subscribe to get started" }),
|
|
157
156
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
158
|
-
|
|
157
|
+
_chunk3X7EEFMNjs.Button,
|
|
159
158
|
{
|
|
160
159
|
variant: "outline",
|
|
161
160
|
size: "sm",
|
|
@@ -173,7 +172,7 @@ function SubscriptionSummaryCard({
|
|
|
173
172
|
] }) : primarySubscription ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
174
173
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
|
|
175
174
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold", children: formatPlanName(primarySubscription) }),
|
|
176
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
175
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Badge, { variant: primarySubscription.cancelAtPeriodEnd ? "secondary" : getStatusBadgeVariant(primarySubscription.status), children: primarySubscription.cancelAtPeriodEnd ? "Canceling" : primarySubscription.status })
|
|
177
176
|
] }),
|
|
178
177
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-muted-foreground", children: [
|
|
179
178
|
formatPrice(_optionalChain([primarySubscription, 'access', _10 => _10.price, 'optionalAccess', _11 => _11.unitAmount]), _optionalChain([primarySubscription, 'access', _12 => _12.price, 'optionalAccess', _13 => _13.currency])),
|
|
@@ -217,36 +216,36 @@ function PaymentMethodSummaryCard({
|
|
|
217
216
|
onManageClick
|
|
218
217
|
}) {
|
|
219
218
|
if (loading) {
|
|
220
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
221
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
222
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
219
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
220
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
221
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Payment Method" }),
|
|
223
222
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Wallet, { className: "h-4 w-4 text-muted-foreground" })
|
|
224
223
|
] }),
|
|
225
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
226
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
227
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
224
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: [
|
|
225
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-6 w-32 mb-2" }),
|
|
226
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-24" })
|
|
228
227
|
] })
|
|
229
228
|
] });
|
|
230
229
|
}
|
|
231
230
|
if (error) {
|
|
232
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
233
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
234
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
231
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
232
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
233
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Payment Method" }),
|
|
235
234
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Wallet, { className: "h-4 w-4 text-muted-foreground" })
|
|
236
235
|
] }),
|
|
237
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
236
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
|
|
238
237
|
] });
|
|
239
238
|
}
|
|
240
239
|
const defaultMethod = paymentMethods.find((pm) => pm.id === defaultPaymentMethodId) || paymentMethods[0];
|
|
241
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
242
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
243
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
240
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { className: "cursor-pointer hover:bg-accent/50 transition-colors", onClick: onManageClick, children: [
|
|
241
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
242
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Payment Method" }),
|
|
244
243
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Wallet, { className: "h-4 w-4 text-muted-foreground" })
|
|
245
244
|
] }),
|
|
246
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
245
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: paymentMethods.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
247
246
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "No payment method" }),
|
|
248
247
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "Add a card to enable subscriptions" }),
|
|
249
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
248
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", size: "sm", className: "mt-2", onClick: (e) => {
|
|
250
249
|
e.stopPropagation();
|
|
251
250
|
onManageClick();
|
|
252
251
|
}, children: [
|
|
@@ -302,7 +301,7 @@ function CustomerInfoCard({ customer, loading, error }) {
|
|
|
302
301
|
e.stopPropagation();
|
|
303
302
|
setPortalLoading(true);
|
|
304
303
|
try {
|
|
305
|
-
const { url } = await
|
|
304
|
+
const { url } = await _chunkJ22NEVSKjs.StripeCustomerService.createPortalSession();
|
|
306
305
|
window.open(url, "_blank");
|
|
307
306
|
} catch (err) {
|
|
308
307
|
console.error("[CustomerInfoCard] Failed to create portal session:", err);
|
|
@@ -311,52 +310,52 @@ function CustomerInfoCard({ customer, loading, error }) {
|
|
|
311
310
|
}
|
|
312
311
|
}, "handlePortalClick");
|
|
313
312
|
if (loading) {
|
|
314
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
315
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
316
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
313
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
314
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
315
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Billing Account" }),
|
|
317
316
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.User, { className: "h-4 w-4 text-muted-foreground" })
|
|
318
317
|
] }),
|
|
319
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
320
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
321
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
322
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
318
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: [
|
|
319
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-6 w-32 mb-2" }),
|
|
320
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-48 mb-1" }),
|
|
321
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-24" })
|
|
323
322
|
] })
|
|
324
323
|
] });
|
|
325
324
|
}
|
|
326
325
|
if (error) {
|
|
327
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
328
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
329
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
326
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
327
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
328
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Billing Account" }),
|
|
330
329
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.User, { className: "h-4 w-4 text-muted-foreground" })
|
|
331
330
|
] }),
|
|
332
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
331
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
|
|
333
332
|
] });
|
|
334
333
|
}
|
|
335
334
|
if (!customer) {
|
|
336
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
337
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
338
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
335
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
336
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
337
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Billing Account" }),
|
|
339
338
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.User, { className: "h-4 w-4 text-muted-foreground" })
|
|
340
339
|
] }),
|
|
341
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
340
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: [
|
|
342
341
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "Not set up" }),
|
|
343
342
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "Billing account will be created when you subscribe" })
|
|
344
343
|
] })
|
|
345
344
|
] });
|
|
346
345
|
}
|
|
347
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
348
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
349
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
346
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
347
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
348
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Billing Account" }),
|
|
350
349
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.User, { className: "h-4 w-4 text-muted-foreground" })
|
|
351
350
|
] }),
|
|
352
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
351
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
353
352
|
customer.name && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold", children: customer.name }),
|
|
354
353
|
customer.email && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: customer.email }),
|
|
355
354
|
customer.balance !== void 0 && customer.balance !== 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm", children: [
|
|
356
355
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-muted-foreground", children: "Credit Balance: " }),
|
|
357
356
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: customer.balance < 0 ? "text-green-600" : "text-destructive", children: formatBalance(customer.balance, customer.currency) })
|
|
358
357
|
] }),
|
|
359
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
358
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", size: "sm", className: "mt-2", onClick: handlePortalClick, disabled: portalLoading, children: [
|
|
360
359
|
portalLoading ? "Loading..." : "Manage in Stripe Portal",
|
|
361
360
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ExternalLink, { className: "h-4 w-4 ml-1" })
|
|
362
361
|
] })
|
|
@@ -400,42 +399,42 @@ function formatAmount(amount, currency) {
|
|
|
400
399
|
_chunk7QVYU63Ejs.__name.call(void 0, formatAmount, "formatAmount");
|
|
401
400
|
function InvoicesSummaryCard({ invoices, loading, error, onViewAllClick }) {
|
|
402
401
|
if (loading) {
|
|
403
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
404
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
405
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
402
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
403
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
404
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Recent Invoices" }),
|
|
406
405
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ReceiptIcon, { className: "h-4 w-4 text-muted-foreground" })
|
|
407
406
|
] }),
|
|
408
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
409
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
410
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
411
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
407
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: [
|
|
408
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-6 w-24 mb-2" }),
|
|
409
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-32 mb-1" }),
|
|
410
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-20" })
|
|
412
411
|
] })
|
|
413
412
|
] });
|
|
414
413
|
}
|
|
415
414
|
if (error) {
|
|
416
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
417
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
418
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
415
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
416
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
417
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Recent Invoices" }),
|
|
419
418
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ReceiptIcon, { className: "h-4 w-4 text-muted-foreground" })
|
|
420
419
|
] }),
|
|
421
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
420
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
|
|
422
421
|
] });
|
|
423
422
|
}
|
|
424
423
|
const latestInvoice = invoices[0];
|
|
425
424
|
const paidInvoices = invoices.filter((inv) => inv.status === "paid" /* PAID */);
|
|
426
425
|
const openInvoices = invoices.filter((inv) => inv.status === "open" /* OPEN */);
|
|
427
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
428
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
429
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
426
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { className: "cursor-pointer hover:bg-accent/50 transition-colors", onClick: onViewAllClick, children: [
|
|
427
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
428
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Recent Invoices" }),
|
|
430
429
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ReceiptIcon, { className: "h-4 w-4 text-muted-foreground" })
|
|
431
430
|
] }),
|
|
432
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
431
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: invoices.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
433
432
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "No invoices yet" }),
|
|
434
433
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "Invoices will appear after your first billing cycle" })
|
|
435
434
|
] }) : latestInvoice ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
436
435
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
|
|
437
436
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold", children: formatAmount(latestInvoice.total, latestInvoice.currency) }),
|
|
438
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
437
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Badge, { variant: getStatusBadgeVariant2(latestInvoice.status), children: latestInvoice.status })
|
|
439
438
|
] }),
|
|
440
439
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: latestInvoice.stripeInvoiceNumber || `Invoice from ${formatDate2(latestInvoice.periodStart)}` }),
|
|
441
440
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-4 text-xs text-muted-foreground", children: [
|
|
@@ -475,24 +474,24 @@ function BillingUsageSummaryCard({
|
|
|
475
474
|
onViewDetailsClick
|
|
476
475
|
}) {
|
|
477
476
|
if (loading) {
|
|
478
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
479
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
480
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
477
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
478
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
479
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Usage This Month" }),
|
|
481
480
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "h-4 w-4 text-muted-foreground" })
|
|
482
481
|
] }),
|
|
483
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
484
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
485
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
482
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: [
|
|
483
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-6 w-24 mb-2" }),
|
|
484
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-32" })
|
|
486
485
|
] })
|
|
487
486
|
] });
|
|
488
487
|
}
|
|
489
488
|
if (error) {
|
|
490
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
491
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
492
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
489
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
490
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
491
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Usage This Month" }),
|
|
493
492
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "h-4 w-4 text-muted-foreground" })
|
|
494
493
|
] }),
|
|
495
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
494
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-destructive", children: error }) })
|
|
496
495
|
] });
|
|
497
496
|
}
|
|
498
497
|
const totalUsage = Object.values(summaries).reduce((acc, summary) => {
|
|
@@ -500,12 +499,12 @@ function BillingUsageSummaryCard({
|
|
|
500
499
|
}, 0);
|
|
501
500
|
const primaryMeter = meters.find((m) => _optionalChain([summaries, 'access', _23 => _23[m.id], 'optionalAccess', _24 => _24.aggregatedValue]));
|
|
502
501
|
const primarySummary = primaryMeter ? summaries[primaryMeter.id] : null;
|
|
503
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
504
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
505
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
502
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { className: "cursor-pointer hover:bg-accent/50 transition-colors", onClick: onViewDetailsClick, children: [
|
|
503
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between space-y-0 pb-2", children: [
|
|
504
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { className: "text-sm font-medium", children: "Usage This Month" }),
|
|
506
505
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Activity, { className: "h-4 w-4 text-muted-foreground" })
|
|
507
506
|
] }),
|
|
508
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
507
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: meters.length === 0 ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
509
508
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xl font-bold text-muted-foreground", children: "No meters" }),
|
|
510
509
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-muted-foreground", children: "No usage meters are configured" })
|
|
511
510
|
] }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
@@ -534,17 +533,18 @@ _chunk7QVYU63Ejs.__name.call(void 0, BillingUsageSummaryCard, "BillingUsageSumma
|
|
|
534
533
|
|
|
535
534
|
// src/features/billing/components/containers/BillingDashboardContainer.tsx
|
|
536
535
|
|
|
536
|
+
var _navigation = require('next/navigation');
|
|
537
537
|
|
|
538
538
|
|
|
539
539
|
// src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx
|
|
540
540
|
|
|
541
541
|
|
|
542
542
|
|
|
543
|
-
// src/features/billing/stripe-customer/components/forms/
|
|
543
|
+
// src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx
|
|
544
544
|
var _reactstripejs = require('@stripe/react-stripe-js');
|
|
545
545
|
|
|
546
546
|
|
|
547
|
-
function
|
|
547
|
+
function PaymentMethodForm({ onSuccess, onCancel, isLoading = false }) {
|
|
548
548
|
const stripe = _reactstripejs.useStripe.call(void 0, );
|
|
549
549
|
const elements = _reactstripejs.useElements.call(void 0, );
|
|
550
550
|
const [setupIntent, setSetupIntent] = _react.useState.call(void 0, null);
|
|
@@ -556,19 +556,17 @@ function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
|
|
|
556
556
|
const fetchSetupIntent = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
557
557
|
setLoading(true);
|
|
558
558
|
try {
|
|
559
|
-
const intent = await
|
|
559
|
+
const intent = await _chunkJ22NEVSKjs.StripeCustomerService.createSetupIntent();
|
|
560
560
|
setSetupIntent(intent);
|
|
561
561
|
} catch (err) {
|
|
562
|
-
console.error("[
|
|
562
|
+
console.error("[PaymentMethodForm] Failed to create setup intent:", err);
|
|
563
563
|
setError("Failed to initialize payment form. Please try again.");
|
|
564
564
|
} finally {
|
|
565
565
|
setLoading(false);
|
|
566
566
|
}
|
|
567
567
|
}, "fetchSetupIntent");
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
}
|
|
571
|
-
}, [open]);
|
|
568
|
+
fetchSetupIntent();
|
|
569
|
+
}, []);
|
|
572
570
|
const handleSubmit = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (e) => {
|
|
573
571
|
e.preventDefault();
|
|
574
572
|
if (!stripe || !elements || !setupIntent) {
|
|
@@ -590,69 +588,92 @@ function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
|
|
|
590
588
|
}
|
|
591
589
|
);
|
|
592
590
|
if (stripeError) {
|
|
593
|
-
console.error("[
|
|
591
|
+
console.error("[PaymentMethodForm] Stripe error:", stripeError);
|
|
594
592
|
setError(stripeError.message || "Failed to add payment method. Please check your card details.");
|
|
595
593
|
setIsSubmitting(false);
|
|
596
594
|
return;
|
|
597
595
|
}
|
|
598
596
|
if (setAsDefault && _optionalChain([confirmedSetupIntent, 'optionalAccess', _25 => _25.payment_method])) {
|
|
599
|
-
await
|
|
597
|
+
await _chunkJ22NEVSKjs.StripeCustomerService.setDefaultPaymentMethod({
|
|
600
598
|
paymentMethodId: typeof confirmedSetupIntent.payment_method === "string" ? confirmedSetupIntent.payment_method : confirmedSetupIntent.payment_method.id
|
|
601
599
|
});
|
|
602
600
|
}
|
|
603
601
|
onSuccess();
|
|
604
|
-
onOpenChange(false);
|
|
605
602
|
} catch (err) {
|
|
606
|
-
console.error("[
|
|
603
|
+
console.error("[PaymentMethodForm] Error:", err);
|
|
607
604
|
setError(err.message || "An unexpected error occurred. Please try again.");
|
|
608
605
|
} finally {
|
|
609
606
|
setIsSubmitting(false);
|
|
610
607
|
}
|
|
611
608
|
}, "handleSubmit");
|
|
612
|
-
|
|
613
|
-
/* @__PURE__ */ _jsxruntime.
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
}
|
|
630
|
-
},
|
|
631
|
-
invalid: {
|
|
632
|
-
color: "#9e2146"
|
|
609
|
+
if (loading) {
|
|
610
|
+
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 payment form..." }) });
|
|
611
|
+
}
|
|
612
|
+
if (!setupIntent && error) {
|
|
613
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDescription, { children: error }) });
|
|
614
|
+
}
|
|
615
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: handleSubmit, className: "flex flex-col gap-y-4", children: [
|
|
616
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "rounded-md border border-gray-300 p-3", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
617
|
+
_reactstripejs.CardElement,
|
|
618
|
+
{
|
|
619
|
+
options: {
|
|
620
|
+
style: {
|
|
621
|
+
base: {
|
|
622
|
+
fontSize: "16px",
|
|
623
|
+
color: "#424770",
|
|
624
|
+
"::placeholder": {
|
|
625
|
+
color: "#aab7c4"
|
|
633
626
|
}
|
|
627
|
+
},
|
|
628
|
+
invalid: {
|
|
629
|
+
color: "#9e2146"
|
|
634
630
|
}
|
|
635
631
|
}
|
|
636
632
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.AlertDescription, { children: error }) }),
|
|
650
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-x-2", children: [
|
|
651
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isSubmitting, children: "Cancel" }),
|
|
652
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Button, { type: "submit", disabled: !stripe || isSubmitting, children: isSubmitting ? "Processing..." : "Add Card" })
|
|
653
|
-
] })
|
|
633
|
+
}
|
|
634
|
+
) }),
|
|
635
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-2", children: [
|
|
636
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
637
|
+
_chunk3X7EEFMNjs.Checkbox,
|
|
638
|
+
{
|
|
639
|
+
id: "setAsDefault",
|
|
640
|
+
checked: setAsDefault,
|
|
641
|
+
onCheckedChange: (checked) => setSetAsDefault(!!checked)
|
|
642
|
+
}
|
|
643
|
+
),
|
|
644
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Label, { htmlFor: "setAsDefault", className: "text-sm font-normal", children: "Set as default payment method" })
|
|
654
645
|
] }),
|
|
655
|
-
|
|
646
|
+
error && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDescription, { children: error }) }),
|
|
647
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-x-2", children: [
|
|
648
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { type: "button", variant: "outline", onClick: onCancel, disabled: isSubmitting || isLoading, children: "Cancel" }),
|
|
649
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { type: "submit", disabled: !stripe || isSubmitting || isLoading, children: isSubmitting ? "Processing..." : "Add Card" })
|
|
650
|
+
] })
|
|
651
|
+
] });
|
|
652
|
+
}
|
|
653
|
+
_chunk7QVYU63Ejs.__name.call(void 0, PaymentMethodForm, "PaymentMethodForm");
|
|
654
|
+
|
|
655
|
+
// src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx
|
|
656
|
+
|
|
657
|
+
function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
|
|
658
|
+
const handleSuccess = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
|
|
659
|
+
onSuccess();
|
|
660
|
+
onOpenChange(false);
|
|
661
|
+
}, "handleSuccess");
|
|
662
|
+
const handleCancel = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
|
|
663
|
+
onOpenChange(false);
|
|
664
|
+
}, "handleCancel");
|
|
665
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogContent, { className: "max-w-md", children: [
|
|
666
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogHeader, { children: [
|
|
667
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogTitle, { children: "Add Payment Method" }),
|
|
668
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogDescription, { children: "Add a new payment method to your account. Your card information is securely processed by Stripe." })
|
|
669
|
+
] }),
|
|
670
|
+
open && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
671
|
+
PaymentMethodForm,
|
|
672
|
+
{
|
|
673
|
+
onSuccess: handleSuccess,
|
|
674
|
+
onCancel: handleCancel
|
|
675
|
+
}
|
|
676
|
+
)
|
|
656
677
|
] }) });
|
|
657
678
|
}
|
|
658
679
|
_chunk7QVYU63Ejs.__name.call(void 0, PaymentMethodEditor, "PaymentMethodEditor");
|
|
@@ -674,7 +695,7 @@ function PaymentMethodCard({ paymentMethod, onUpdate }) {
|
|
|
674
695
|
_react.useEffect.call(void 0, () => {
|
|
675
696
|
const loadCustomer = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
676
697
|
try {
|
|
677
|
-
const fetchedCustomer = await
|
|
698
|
+
const fetchedCustomer = await _chunkJ22NEVSKjs.StripeCustomerService.getCustomer();
|
|
678
699
|
setCustomer(fetchedCustomer);
|
|
679
700
|
} catch (error) {
|
|
680
701
|
console.error("[PaymentMethodCard] Failed to load customer:", error);
|
|
@@ -691,7 +712,7 @@ function PaymentMethodCard({ paymentMethod, onUpdate }) {
|
|
|
691
712
|
const handleSetDefault = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
692
713
|
setLoading(true);
|
|
693
714
|
try {
|
|
694
|
-
await
|
|
715
|
+
await _chunkJ22NEVSKjs.StripeCustomerService.setDefaultPaymentMethod({ paymentMethodId: paymentMethod.id });
|
|
695
716
|
onUpdate();
|
|
696
717
|
} catch (error) {
|
|
697
718
|
console.error("[PaymentMethodCard] Failed to set as default:", error);
|
|
@@ -702,7 +723,7 @@ function PaymentMethodCard({ paymentMethod, onUpdate }) {
|
|
|
702
723
|
const handleRemove = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
703
724
|
setLoading(true);
|
|
704
725
|
try {
|
|
705
|
-
await
|
|
726
|
+
await _chunkJ22NEVSKjs.StripeCustomerService.removePaymentMethod({ paymentMethodId: paymentMethod.id });
|
|
706
727
|
setShowRemoveDialog(false);
|
|
707
728
|
onUpdate();
|
|
708
729
|
} catch (error) {
|
|
@@ -711,22 +732,22 @@ function PaymentMethodCard({ paymentMethod, onUpdate }) {
|
|
|
711
732
|
}
|
|
712
733
|
}, "handleRemove");
|
|
713
734
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
714
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
715
|
-
isDefault && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
716
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
735
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { className: "relative", children: [
|
|
736
|
+
isDefault && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Badge, { className: "absolute right-2 top-2 bg-green-100 text-green-800 hover:bg-green-100", children: "Default" }),
|
|
737
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center justify-between pb-2", children: [
|
|
717
738
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-2", children: [
|
|
718
739
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-2xl", children: brandIcon }),
|
|
719
740
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-medium capitalize", children: brand })
|
|
720
741
|
] }),
|
|
721
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
722
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
723
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
724
|
-
!isDefault && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
725
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
742
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DropdownMenu, { children: [
|
|
743
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DropdownMenuTrigger, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.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" }) }) }),
|
|
744
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DropdownMenuContent, { align: "end", children: [
|
|
745
|
+
!isDefault && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DropdownMenuItem, { onClick: handleSetDefault, disabled: loading, children: "Set as Default" }),
|
|
746
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DropdownMenuItem, { onClick: () => setShowRemoveDialog(true), disabled: loading, className: "text-red-600", children: "Remove" })
|
|
726
747
|
] })
|
|
727
748
|
] })
|
|
728
749
|
] }),
|
|
729
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
750
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-y-1", children: [
|
|
730
751
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-lg font-semibold", children: [
|
|
731
752
|
"\u2022\u2022\u2022\u2022 ",
|
|
732
753
|
last4
|
|
@@ -739,17 +760,17 @@ function PaymentMethodCard({ paymentMethod, onUpdate }) {
|
|
|
739
760
|
] })
|
|
740
761
|
] }) })
|
|
741
762
|
] }),
|
|
742
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
743
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
744
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
745
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
763
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialog, { open: showRemoveDialog, onOpenChange: setShowRemoveDialog, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogContent, { children: [
|
|
764
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogHeader, { children: [
|
|
765
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogTitle, { children: "Remove Payment Method" }),
|
|
766
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogDescription, { children: [
|
|
746
767
|
"Are you sure you want to remove this payment method? This action cannot be undone.",
|
|
747
768
|
isDefault && " This is your default payment method."
|
|
748
769
|
] })
|
|
749
770
|
] }),
|
|
750
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
751
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
752
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
771
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogFooter, { children: [
|
|
772
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogCancel, { disabled: loading, children: "Cancel" }),
|
|
773
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogAction, { onClick: handleRemove, disabled: loading, className: "bg-red-600 hover:bg-red-700", children: loading ? "Removing..." : "Remove" })
|
|
753
774
|
] })
|
|
754
775
|
] }) })
|
|
755
776
|
] });
|
|
@@ -772,7 +793,7 @@ function PaymentMethodsContainer() {
|
|
|
772
793
|
const loadPaymentMethods = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
773
794
|
setLoading(true);
|
|
774
795
|
try {
|
|
775
|
-
const fetchedPaymentMethods = await
|
|
796
|
+
const fetchedPaymentMethods = await _chunkJ22NEVSKjs.StripeCustomerService.listPaymentMethods();
|
|
776
797
|
setPaymentMethods(fetchedPaymentMethods);
|
|
777
798
|
} catch (error) {
|
|
778
799
|
console.error("[PaymentMethodsContainer] Failed to load payment methods:", error);
|
|
@@ -792,14 +813,14 @@ function PaymentMethodsContainer() {
|
|
|
792
813
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-8 w-8" }),
|
|
793
814
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Payment Methods" })
|
|
794
815
|
] }),
|
|
795
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
816
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: () => setShowAddPaymentMethod(true), children: "Add Payment Method" })
|
|
796
817
|
] }),
|
|
797
818
|
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: [
|
|
798
819
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-16 w-16 text-muted-foreground" }),
|
|
799
820
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
|
|
800
821
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-2 text-xl font-semibold", children: "No payment methods" }),
|
|
801
822
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-4 text-muted-foreground", children: "Add a payment method to enable subscriptions and secure checkout." }),
|
|
802
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
823
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: () => setShowAddPaymentMethod(true), children: "Add Your First Card" })
|
|
803
824
|
] })
|
|
804
825
|
] }),
|
|
805
826
|
paymentMethods.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PaymentMethodsList, { paymentMethods, onUpdate: loadPaymentMethods }),
|
|
@@ -923,13 +944,13 @@ function InvoiceDetails({ invoice, open, onOpenChange, onInvoiceChange }) {
|
|
|
923
944
|
return invoice.stripeInvoiceId.slice(-8);
|
|
924
945
|
}, "getInvoiceNumber");
|
|
925
946
|
const productName = _optionalChain([invoice, 'access', _35 => _35.subscription, 'optionalAccess', _36 => _36.price, 'optionalAccess', _37 => _37.product, 'optionalAccess', _38 => _38.name]) || "Subscription";
|
|
926
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
927
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
928
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
947
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogContent, { className: "max-w-2xl", children: [
|
|
948
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogHeader, { children: [
|
|
949
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogTitle, { children: [
|
|
929
950
|
"Invoice ",
|
|
930
951
|
getInvoiceNumber()
|
|
931
952
|
] }),
|
|
932
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
953
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogDescription, { children: formatDate3(invoice.periodStart) })
|
|
933
954
|
] }),
|
|
934
955
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
|
|
935
956
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
|
|
@@ -994,15 +1015,15 @@ function InvoiceDetails({ invoice, open, onOpenChange, onInvoiceChange }) {
|
|
|
994
1015
|
] })
|
|
995
1016
|
] }),
|
|
996
1017
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap gap-2 pt-4 border-t", children: [
|
|
997
|
-
invoice.stripePdfUrl && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1018
|
+
invoice.stripePdfUrl && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", onClick: handleDownloadPDF, children: [
|
|
998
1019
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Download, { className: "mr-2 h-4 w-4" }),
|
|
999
1020
|
"Download PDF"
|
|
1000
1021
|
] }),
|
|
1001
|
-
invoice.status === "open" /* OPEN */ && invoice.attempted && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1022
|
+
invoice.status === "open" /* OPEN */ && invoice.attempted && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "default", onClick: handleRetryPayment, children: [
|
|
1002
1023
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.RefreshCw, { className: "mr-2 h-4 w-4" }),
|
|
1003
1024
|
"Retry Payment"
|
|
1004
1025
|
] }),
|
|
1005
|
-
invoice.stripeHostedInvoiceUrl && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1026
|
+
invoice.stripeHostedInvoiceUrl && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", onClick: handleViewInStripe, children: [
|
|
1006
1027
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.ExternalLink, { className: "mr-2 h-4 w-4" }),
|
|
1007
1028
|
"View in Stripe"
|
|
1008
1029
|
] })
|
|
@@ -1026,30 +1047,30 @@ function InvoicesList({ invoices, onInvoicesChange }) {
|
|
|
1026
1047
|
return invoice.stripeInvoiceId.slice(-8);
|
|
1027
1048
|
}, "getInvoiceNumber");
|
|
1028
1049
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1029
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1030
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1031
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1032
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1033
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1034
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1035
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1050
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Table, { children: [
|
|
1051
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHeader, { className: "bg-muted", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.TableRow, { children: [
|
|
1052
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Invoice #" }),
|
|
1053
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Date" }),
|
|
1054
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Status" }),
|
|
1055
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { className: "text-right", children: "Amount" }),
|
|
1056
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Period" })
|
|
1036
1057
|
] }) }),
|
|
1037
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1058
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableBody, { children: invoices.map((invoice) => {
|
|
1038
1059
|
const invoiceNumber = getInvoiceNumber(invoice);
|
|
1039
1060
|
const date = formatDate3(invoice.periodStart);
|
|
1040
1061
|
const amount = formatCurrency(invoice.total, invoice.currency);
|
|
1041
1062
|
const period = `${formatDate3(invoice.periodStart)} - ${formatDate3(invoice.periodEnd)}`;
|
|
1042
1063
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1043
|
-
|
|
1064
|
+
_chunk3X7EEFMNjs.TableRow,
|
|
1044
1065
|
{
|
|
1045
1066
|
onClick: () => handleRowClick(invoice),
|
|
1046
1067
|
className: "cursor-pointer hover:bg-muted/50",
|
|
1047
1068
|
children: [
|
|
1048
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1049
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1050
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1051
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1052
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1069
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "font-medium", children: invoiceNumber }),
|
|
1070
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "text-muted-foreground text-sm", children: date }),
|
|
1071
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InvoiceStatusBadge, { status: invoice.status }) }),
|
|
1072
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "text-right font-medium", children: amount }),
|
|
1073
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "text-muted-foreground text-sm", children: period })
|
|
1053
1074
|
]
|
|
1054
1075
|
},
|
|
1055
1076
|
invoice.id
|
|
@@ -1082,7 +1103,7 @@ function InvoicesContainer() {
|
|
|
1082
1103
|
setLoading(true);
|
|
1083
1104
|
try {
|
|
1084
1105
|
const params = statusFilter !== "all" ? { status: statusFilter } : void 0;
|
|
1085
|
-
const data = await
|
|
1106
|
+
const data = await _chunkJ22NEVSKjs.StripeInvoiceService.listInvoices(params);
|
|
1086
1107
|
setInvoices(data);
|
|
1087
1108
|
} catch (error) {
|
|
1088
1109
|
console.error("[InvoicesContainer] Failed to load invoices:", error);
|
|
@@ -1098,12 +1119,12 @@ function InvoicesContainer() {
|
|
|
1098
1119
|
setStatusFilter(value);
|
|
1099
1120
|
}, "handleFilterChange");
|
|
1100
1121
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
|
|
1101
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1102
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1103
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1104
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1105
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1106
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1122
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Tabs, { value: statusFilter, onValueChange: handleFilterChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.TabsList, { children: [
|
|
1123
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TabsTrigger, { value: "all", children: "All" }),
|
|
1124
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TabsTrigger, { value: "paid" /* PAID */, children: "Paid" }),
|
|
1125
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TabsTrigger, { value: "open" /* OPEN */, children: "Open" }),
|
|
1126
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TabsTrigger, { value: "void" /* VOID */, children: "Void" }),
|
|
1127
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TabsTrigger, { value: "uncollectible" /* UNCOLLECTIBLE */, children: "Uncollectible" })
|
|
1107
1128
|
] }) }),
|
|
1108
1129
|
loading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-center py-8 text-muted-foreground", children: "Loading invoices..." }),
|
|
1109
1130
|
!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: [
|
|
@@ -1118,71 +1139,12 @@ _chunk7QVYU63Ejs.__name.call(void 0, InvoicesContainer, "InvoicesContainer");
|
|
|
1118
1139
|
// src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx
|
|
1119
1140
|
|
|
1120
1141
|
|
|
1121
|
-
var _uuid = require('uuid');
|
|
1122
1142
|
|
|
1123
|
-
// src/features/billing/stripe-subscription/
|
|
1143
|
+
// src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
|
|
1124
1144
|
|
|
1125
1145
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
const [isConfirming, setIsConfirming] = _react.useState.call(void 0, false);
|
|
1129
|
-
const confirmPayment = _react.useCallback.call(void 0,
|
|
1130
|
-
async (clientSecret) => {
|
|
1131
|
-
if (!stripe) {
|
|
1132
|
-
console.error("[useConfirmSubscriptionPayment] Stripe not initialized");
|
|
1133
|
-
return {
|
|
1134
|
-
success: false,
|
|
1135
|
-
error: "Payment system not initialized. Please refresh the page and try again."
|
|
1136
|
-
};
|
|
1137
|
-
}
|
|
1138
|
-
if (!clientSecret) {
|
|
1139
|
-
console.error("[useConfirmSubscriptionPayment] No client secret provided");
|
|
1140
|
-
return {
|
|
1141
|
-
success: false,
|
|
1142
|
-
error: "Payment confirmation failed. Missing payment details."
|
|
1143
|
-
};
|
|
1144
|
-
}
|
|
1145
|
-
setIsConfirming(true);
|
|
1146
|
-
try {
|
|
1147
|
-
const { error: stripeError, paymentIntent } = await stripe.confirmCardPayment(clientSecret);
|
|
1148
|
-
if (stripeError) {
|
|
1149
|
-
console.error("[useConfirmSubscriptionPayment] Stripe error:", stripeError);
|
|
1150
|
-
return {
|
|
1151
|
-
success: false,
|
|
1152
|
-
error: stripeError.message || "Payment confirmation failed. Please try again."
|
|
1153
|
-
};
|
|
1154
|
-
}
|
|
1155
|
-
if (_optionalChain([paymentIntent, 'optionalAccess', _39 => _39.status]) === "succeeded") {
|
|
1156
|
-
return { success: true };
|
|
1157
|
-
}
|
|
1158
|
-
if (_optionalChain([paymentIntent, 'optionalAccess', _40 => _40.status]) === "requires_action") {
|
|
1159
|
-
return {
|
|
1160
|
-
success: false,
|
|
1161
|
-
error: "Additional authentication required. Please complete the verification."
|
|
1162
|
-
};
|
|
1163
|
-
}
|
|
1164
|
-
return {
|
|
1165
|
-
success: false,
|
|
1166
|
-
error: "Payment could not be completed. Please try again."
|
|
1167
|
-
};
|
|
1168
|
-
} catch (err) {
|
|
1169
|
-
console.error("[useConfirmSubscriptionPayment] Unexpected error:", err);
|
|
1170
|
-
return {
|
|
1171
|
-
success: false,
|
|
1172
|
-
error: err.message || "An unexpected error occurred during payment confirmation."
|
|
1173
|
-
};
|
|
1174
|
-
} finally {
|
|
1175
|
-
setIsConfirming(false);
|
|
1176
|
-
}
|
|
1177
|
-
},
|
|
1178
|
-
[stripe]
|
|
1179
|
-
);
|
|
1180
|
-
return {
|
|
1181
|
-
confirmPayment,
|
|
1182
|
-
isConfirming
|
|
1183
|
-
};
|
|
1184
|
-
}
|
|
1185
|
-
_chunk7QVYU63Ejs.__name.call(void 0, useConfirmSubscriptionPayment, "useConfirmSubscriptionPayment");
|
|
1146
|
+
// src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx
|
|
1147
|
+
|
|
1186
1148
|
|
|
1187
1149
|
// src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx
|
|
1188
1150
|
var _zod = require('@hookform/resolvers/zod');
|
|
@@ -1212,7 +1174,7 @@ function CancelSubscriptionDialog({
|
|
|
1212
1174
|
const onSubmit = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (values) => {
|
|
1213
1175
|
setIsSubmitting(true);
|
|
1214
1176
|
try {
|
|
1215
|
-
await
|
|
1177
|
+
await _chunkJ22NEVSKjs.StripeSubscriptionService.cancelSubscription({
|
|
1216
1178
|
id: subscription.id,
|
|
1217
1179
|
cancelImmediately: values.cancelImmediately
|
|
1218
1180
|
});
|
|
@@ -1225,20 +1187,20 @@ function CancelSubscriptionDialog({
|
|
|
1225
1187
|
}
|
|
1226
1188
|
}, "onSubmit");
|
|
1227
1189
|
const periodEndDate = formatDate3(subscription.currentPeriodEnd);
|
|
1228
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1229
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1230
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1231
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1190
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogContent, { className: "max-w-md", children: [
|
|
1191
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogHeader, { children: [
|
|
1192
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogTitle, { children: "Cancel Subscription" }),
|
|
1193
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogDescription, { children: "Are you sure you want to cancel this subscription? This action cannot be undone." })
|
|
1232
1194
|
] }),
|
|
1233
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1234
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1195
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Form, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
|
|
1196
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.FormCheckbox, { form, id: "cancelImmediately", name: "Cancel Immediately" }),
|
|
1235
1197
|
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: [
|
|
1236
1198
|
"Your subscription will remain active until ",
|
|
1237
1199
|
periodEndDate,
|
|
1238
1200
|
". You can continue using the service until then."
|
|
1239
1201
|
] }),
|
|
1240
1202
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1241
|
-
|
|
1203
|
+
_chunk3X7EEFMNjs.FormTextarea,
|
|
1242
1204
|
{
|
|
1243
1205
|
form,
|
|
1244
1206
|
id: "reason",
|
|
@@ -1248,404 +1210,14 @@ function CancelSubscriptionDialog({
|
|
|
1248
1210
|
}
|
|
1249
1211
|
),
|
|
1250
1212
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-x-2 justify-end pt-2", children: [
|
|
1251
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1252
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1213
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isSubmitting, children: "Keep Subscription" }),
|
|
1214
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { type: "submit", variant: "destructive", disabled: isSubmitting, children: isSubmitting ? "Canceling..." : "Confirm Cancellation" })
|
|
1253
1215
|
] })
|
|
1254
1216
|
] }) })
|
|
1255
1217
|
] }) });
|
|
1256
1218
|
}
|
|
1257
1219
|
_chunk7QVYU63Ejs.__name.call(void 0, CancelSubscriptionDialog, "CancelSubscriptionDialog");
|
|
1258
1220
|
|
|
1259
|
-
// src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
// src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
function PricingCard({ price, isCurrentPlan = false, isSelected = false, isDisabled = false, isLoading = false, onSelect }) {
|
|
1268
|
-
const description = price.description || price.nickname || "Standard";
|
|
1269
|
-
const features = price.features || [];
|
|
1270
|
-
const formattedPrice = formatCurrency(price.unitAmount, price.currency);
|
|
1271
|
-
const interval = formatInterval(price);
|
|
1272
|
-
const handleKeyDown = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (e) => {
|
|
1273
|
-
if ((e.key === "Enter" || e.key === " ") && !isDisabled && !isCurrentPlan) {
|
|
1274
|
-
e.preventDefault();
|
|
1275
|
-
onSelect(price);
|
|
1276
|
-
}
|
|
1277
|
-
}, "handleKeyDown");
|
|
1278
|
-
const handleClick = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
|
|
1279
|
-
if (!isDisabled && !isCurrentPlan && !isLoading) {
|
|
1280
|
-
onSelect(price);
|
|
1281
|
-
}
|
|
1282
|
-
}, "handleClick");
|
|
1283
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1284
|
-
_chunkIXI4GAKBjs.Card,
|
|
1285
|
-
{
|
|
1286
|
-
role: "radio",
|
|
1287
|
-
"aria-checked": isSelected,
|
|
1288
|
-
"aria-label": `${description} plan at ${formattedPrice} ${interval}`,
|
|
1289
|
-
tabIndex: isDisabled ? -1 : 0,
|
|
1290
|
-
onKeyDown: handleKeyDown,
|
|
1291
|
-
onClick: handleClick,
|
|
1292
|
-
className: _chunkTSEU4KZ2js.cn.call(void 0,
|
|
1293
|
-
"relative cursor-pointer transition-all duration-200 flex flex-col h-full",
|
|
1294
|
-
"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
1295
|
-
isCurrentPlan && "bg-muted/30",
|
|
1296
|
-
isSelected && !isCurrentPlan && "ring-2 ring-primary",
|
|
1297
|
-
!isDisabled && !isCurrentPlan && "hover:shadow-md hover:border-primary/50",
|
|
1298
|
-
isDisabled && "opacity-50 pointer-events-none",
|
|
1299
|
-
isLoading && "pointer-events-none"
|
|
1300
|
-
),
|
|
1301
|
-
children: [
|
|
1302
|
-
isCurrentPlan && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Badge, { variant: "secondary", className: "absolute top-2 right-2", children: "Current" }),
|
|
1303
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.CardHeader, { className: "pb-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-lg", children: description }) }),
|
|
1304
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.CardContent, { className: "pb-4 grow", children: [
|
|
1305
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-4", children: [
|
|
1306
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-3xl font-bold", children: formattedPrice }),
|
|
1307
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-muted-foreground ml-1", children: interval })
|
|
1308
|
-
] }),
|
|
1309
|
-
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: [
|
|
1310
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Check, { className: "h-4 w-4 text-green-500 mt-0.5 shrink-0" }),
|
|
1311
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm text-muted-foreground", children: feature })
|
|
1312
|
-
] }, index)) })
|
|
1313
|
-
] }),
|
|
1314
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.CardFooter, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1315
|
-
_chunkIXI4GAKBjs.Button,
|
|
1316
|
-
{
|
|
1317
|
-
variant: isCurrentPlan ? "secondary" : isSelected ? "default" : "outline",
|
|
1318
|
-
className: "w-full",
|
|
1319
|
-
disabled: isDisabled || isCurrentPlan || isLoading,
|
|
1320
|
-
children: isLoading ? "Processing..." : isCurrentPlan ? "Current Plan" : isSelected ? "Selected" : "Select Plan"
|
|
1321
|
-
}
|
|
1322
|
-
) })
|
|
1323
|
-
]
|
|
1324
|
-
}
|
|
1325
|
-
);
|
|
1326
|
-
}
|
|
1327
|
-
_chunk7QVYU63Ejs.__name.call(void 0, PricingCard, "PricingCard");
|
|
1328
|
-
|
|
1329
|
-
// src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx
|
|
1330
|
-
|
|
1331
|
-
function PricingCardsGrid({
|
|
1332
|
-
products,
|
|
1333
|
-
pricesByProduct,
|
|
1334
|
-
currentPriceId,
|
|
1335
|
-
selectedPriceId,
|
|
1336
|
-
loadingPriceId,
|
|
1337
|
-
loading = false,
|
|
1338
|
-
onSelectPrice
|
|
1339
|
-
}) {
|
|
1340
|
-
if (loading) {
|
|
1341
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, PricingCardsGridSkeleton, {});
|
|
1342
|
-
}
|
|
1343
|
-
if (products.length === 0) {
|
|
1344
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-center py-8 text-muted-foreground", children: "No plans available" });
|
|
1345
|
-
}
|
|
1346
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-8", role: "radiogroup", "aria-label": "Available pricing plans", children: products.map((product) => {
|
|
1347
|
-
const prices = pricesByProduct.get(product.id) || [];
|
|
1348
|
-
if (prices.length === 0) return null;
|
|
1349
|
-
const sortedPrices = [...prices].sort((a, b) => (_nullishCoalesce(a.unitAmount, () => ( 0))) - (_nullishCoalesce(b.unitAmount, () => ( 0))));
|
|
1350
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
|
|
1351
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-lg font-semibold", children: product.name }),
|
|
1352
|
-
/* @__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,
|
|
1353
|
-
PricingCard,
|
|
1354
|
-
{
|
|
1355
|
-
price,
|
|
1356
|
-
isCurrentPlan: price.stripePriceId === currentPriceId,
|
|
1357
|
-
isSelected: price.stripePriceId === selectedPriceId,
|
|
1358
|
-
isLoading: price.stripePriceId === loadingPriceId,
|
|
1359
|
-
onSelect: onSelectPrice
|
|
1360
|
-
},
|
|
1361
|
-
price.stripePriceId
|
|
1362
|
-
)) })
|
|
1363
|
-
] }, product.id);
|
|
1364
|
-
}) });
|
|
1365
|
-
}
|
|
1366
|
-
_chunk7QVYU63Ejs.__name.call(void 0, PricingCardsGrid, "PricingCardsGrid");
|
|
1367
|
-
function PricingCardsGridSkeleton() {
|
|
1368
|
-
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: [
|
|
1369
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-6 w-32" }),
|
|
1370
|
-
/* @__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, _chunkIXI4GAKBjs.Card, { className: "animate-pulse", children: [
|
|
1371
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.CardHeader, { className: "pb-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-5 w-24" }) }),
|
|
1372
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.CardContent, { className: "pb-4", children: [
|
|
1373
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-4", children: [
|
|
1374
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-9 w-20 inline-block" }),
|
|
1375
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-4 w-12 inline-block ml-2" })
|
|
1376
|
-
] }),
|
|
1377
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
1378
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
|
|
1379
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-4 w-4 rounded-full" }),
|
|
1380
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-4 w-32" })
|
|
1381
|
-
] }),
|
|
1382
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2", children: [
|
|
1383
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-4 w-4 rounded-full" }),
|
|
1384
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-4 w-28" })
|
|
1385
|
-
] })
|
|
1386
|
-
] })
|
|
1387
|
-
] }),
|
|
1388
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.CardFooter, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Skeleton, { className: "h-9 w-full" }) })
|
|
1389
|
-
] }, cardIndex)) })
|
|
1390
|
-
] }, productIndex)) });
|
|
1391
|
-
}
|
|
1392
|
-
_chunk7QVYU63Ejs.__name.call(void 0, PricingCardsGridSkeleton, "PricingCardsGridSkeleton");
|
|
1393
|
-
|
|
1394
|
-
// src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx
|
|
1395
|
-
|
|
1396
|
-
function ProrationPreview({ preview }) {
|
|
1397
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4", children: [
|
|
1398
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "font-semibold text-blue-900 mb-3", children: "Proration Breakdown" }),
|
|
1399
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
1400
|
-
preview.lineItems.map((item, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between text-sm", children: [
|
|
1401
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-800", children: item.description }),
|
|
1402
|
-
/* @__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) })
|
|
1403
|
-
] }, index)),
|
|
1404
|
-
/* @__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: [
|
|
1405
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-900", children: "Net Due Today" }),
|
|
1406
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-900", children: formatCurrency(preview.immediateCharge, preview.currency) })
|
|
1407
|
-
] }) }),
|
|
1408
|
-
preview.lineItems.length > 0 && preview.lineItems[0].period && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-xs text-blue-700 mt-2", children: [
|
|
1409
|
-
"Next invoice on ",
|
|
1410
|
-
formatDate3(preview.lineItems[0].period.end),
|
|
1411
|
-
" for",
|
|
1412
|
-
" ",
|
|
1413
|
-
formatCurrency(preview.amountDue, preview.currency)
|
|
1414
|
-
] })
|
|
1415
|
-
] })
|
|
1416
|
-
] });
|
|
1417
|
-
}
|
|
1418
|
-
_chunk7QVYU63Ejs.__name.call(void 0, ProrationPreview, "ProrationPreview");
|
|
1419
|
-
|
|
1420
|
-
// src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx
|
|
1421
|
-
|
|
1422
|
-
function SubscriptionEditor({
|
|
1423
|
-
subscription,
|
|
1424
|
-
open,
|
|
1425
|
-
onOpenChange,
|
|
1426
|
-
onSuccess,
|
|
1427
|
-
onAddPaymentMethod
|
|
1428
|
-
}) {
|
|
1429
|
-
const { confirmPayment, isConfirming } = useConfirmSubscriptionPayment();
|
|
1430
|
-
const [products, setProducts] = _react.useState.call(void 0, []);
|
|
1431
|
-
const [pricesByProduct, setPricesByProduct] = _react.useState.call(void 0, /* @__PURE__ */ new Map());
|
|
1432
|
-
const [loading, setLoading] = _react.useState.call(void 0, true);
|
|
1433
|
-
const [selectedPriceId, setSelectedPriceId] = _react.useState.call(void 0, null);
|
|
1434
|
-
const [loadingPriceId, setLoadingPriceId] = _react.useState.call(void 0, null);
|
|
1435
|
-
const [prorationPreview, setProrationPreview] = _react.useState.call(void 0, null);
|
|
1436
|
-
const [loadingProration, setLoadingProration] = _react.useState.call(void 0, false);
|
|
1437
|
-
const [hasPaymentMethod, setHasPaymentMethod] = _react.useState.call(void 0, true);
|
|
1438
|
-
const [loadingPaymentMethods, setLoadingPaymentMethods] = _react.useState.call(void 0, true);
|
|
1439
|
-
const [paymentRequiredError, setPaymentRequiredError] = _react.useState.call(void 0, false);
|
|
1440
|
-
const [paymentConfirmationState, setPaymentConfirmationState] = _react.useState.call(void 0, "idle");
|
|
1441
|
-
const [paymentError, setPaymentError] = _react.useState.call(void 0, null);
|
|
1442
|
-
const currentPriceId = _optionalChain([subscription, 'optionalAccess', _41 => _41.price, 'optionalAccess', _42 => _42.id]);
|
|
1443
|
-
const isEditMode = !!subscription;
|
|
1444
|
-
_react.useEffect.call(void 0, () => {
|
|
1445
|
-
const checkPaymentMethods = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
1446
|
-
if (subscription) {
|
|
1447
|
-
setLoadingPaymentMethods(false);
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
setLoadingPaymentMethods(true);
|
|
1451
|
-
try {
|
|
1452
|
-
const paymentMethods = await _chunkTSEU4KZ2js.StripeCustomerService.listPaymentMethods();
|
|
1453
|
-
const hasMethod = paymentMethods.length > 0;
|
|
1454
|
-
setHasPaymentMethod(hasMethod);
|
|
1455
|
-
} catch (error) {
|
|
1456
|
-
console.error("[SubscriptionEditor] Failed to check payment methods:", error);
|
|
1457
|
-
setHasPaymentMethod(false);
|
|
1458
|
-
} finally {
|
|
1459
|
-
setLoadingPaymentMethods(false);
|
|
1460
|
-
}
|
|
1461
|
-
}, "checkPaymentMethods");
|
|
1462
|
-
if (open) {
|
|
1463
|
-
checkPaymentMethods();
|
|
1464
|
-
}
|
|
1465
|
-
}, [open, subscription]);
|
|
1466
|
-
_react.useEffect.call(void 0, () => {
|
|
1467
|
-
const loadData = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
1468
|
-
setLoading(true);
|
|
1469
|
-
try {
|
|
1470
|
-
const fetchedProducts = await _chunkTSEU4KZ2js.StripeProductService.listProducts({ active: true });
|
|
1471
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
1472
|
-
for (const product of fetchedProducts) {
|
|
1473
|
-
if (product.stripePrices && product.stripePrices.length > 0) {
|
|
1474
|
-
grouped.set(product.id, product.stripePrices);
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
setProducts(fetchedProducts);
|
|
1478
|
-
setPricesByProduct(grouped);
|
|
1479
|
-
} catch (error) {
|
|
1480
|
-
console.error("[SubscriptionEditor] Failed to load products/prices:", error);
|
|
1481
|
-
} finally {
|
|
1482
|
-
setLoading(false);
|
|
1483
|
-
}
|
|
1484
|
-
}, "loadData");
|
|
1485
|
-
if (open) {
|
|
1486
|
-
loadData();
|
|
1487
|
-
}
|
|
1488
|
-
}, [open]);
|
|
1489
|
-
_react.useEffect.call(void 0, () => {
|
|
1490
|
-
const loadProration = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
1491
|
-
if (!subscription || !selectedPriceId || selectedPriceId === currentPriceId) {
|
|
1492
|
-
setProrationPreview(null);
|
|
1493
|
-
return;
|
|
1494
|
-
}
|
|
1495
|
-
setLoadingProration(true);
|
|
1496
|
-
try {
|
|
1497
|
-
const preview = await _chunkTSEU4KZ2js.StripeSubscriptionService.getProrationPreview({
|
|
1498
|
-
subscriptionId: subscription.id,
|
|
1499
|
-
newPriceId: selectedPriceId
|
|
1500
|
-
});
|
|
1501
|
-
setProrationPreview(preview);
|
|
1502
|
-
} catch (error) {
|
|
1503
|
-
console.error("[SubscriptionEditor] Failed to load proration preview:", error);
|
|
1504
|
-
setProrationPreview(null);
|
|
1505
|
-
} finally {
|
|
1506
|
-
setLoadingProration(false);
|
|
1507
|
-
}
|
|
1508
|
-
}, "loadProration");
|
|
1509
|
-
loadProration();
|
|
1510
|
-
}, [selectedPriceId, subscription, currentPriceId]);
|
|
1511
|
-
const handleSelectPrice = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (price) => {
|
|
1512
|
-
const priceId = price.id;
|
|
1513
|
-
if (isEditMode) {
|
|
1514
|
-
setSelectedPriceId(priceId);
|
|
1515
|
-
} else {
|
|
1516
|
-
setLoadingPriceId(priceId);
|
|
1517
|
-
setSelectedPriceId(priceId);
|
|
1518
|
-
setPaymentError(null);
|
|
1519
|
-
setPaymentConfirmationState("idle");
|
|
1520
|
-
try {
|
|
1521
|
-
const result = await _chunkTSEU4KZ2js.StripeSubscriptionService.createSubscription({
|
|
1522
|
-
id: _uuid.v4.call(void 0, ),
|
|
1523
|
-
priceId
|
|
1524
|
-
});
|
|
1525
|
-
if (result.meta.requiresAction && result.meta.clientSecret) {
|
|
1526
|
-
setPaymentConfirmationState("confirming");
|
|
1527
|
-
const confirmation = await confirmPayment(result.meta.clientSecret);
|
|
1528
|
-
if (!confirmation.success) {
|
|
1529
|
-
console.error("[SubscriptionEditor] Payment confirmation failed:", confirmation.error);
|
|
1530
|
-
setPaymentConfirmationState("error");
|
|
1531
|
-
setPaymentError(confirmation.error || "Payment confirmation failed");
|
|
1532
|
-
setLoadingPriceId(null);
|
|
1533
|
-
return;
|
|
1534
|
-
}
|
|
1535
|
-
await _chunkTSEU4KZ2js.StripeSubscriptionService.syncSubscription({
|
|
1536
|
-
subscriptionId: result.subscription.id
|
|
1537
|
-
});
|
|
1538
|
-
}
|
|
1539
|
-
setPaymentConfirmationState("success");
|
|
1540
|
-
setTimeout(() => {
|
|
1541
|
-
onSuccess();
|
|
1542
|
-
onOpenChange(false);
|
|
1543
|
-
}, 1e3);
|
|
1544
|
-
} catch (error) {
|
|
1545
|
-
console.error("[SubscriptionEditor] Failed to create subscription:", error);
|
|
1546
|
-
if (_optionalChain([error, 'optionalAccess', _43 => _43.status]) === 402 || _optionalChain([error, 'optionalAccess', _44 => _44.response, 'optionalAccess', _45 => _45.status]) === 402) {
|
|
1547
|
-
setPaymentRequiredError(true);
|
|
1548
|
-
setHasPaymentMethod(false);
|
|
1549
|
-
} else {
|
|
1550
|
-
setPaymentConfirmationState("error");
|
|
1551
|
-
setPaymentError(_optionalChain([error, 'optionalAccess', _46 => _46.message]) || "Failed to create subscription");
|
|
1552
|
-
}
|
|
1553
|
-
setLoadingPriceId(null);
|
|
1554
|
-
}
|
|
1555
|
-
}
|
|
1556
|
-
}, "handleSelectPrice");
|
|
1557
|
-
const handleConfirmPlanChange = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
1558
|
-
if (!subscription || !selectedPriceId) return;
|
|
1559
|
-
setLoadingPriceId(selectedPriceId);
|
|
1560
|
-
try {
|
|
1561
|
-
await _chunkTSEU4KZ2js.StripeSubscriptionService.changePlan({
|
|
1562
|
-
id: subscription.id,
|
|
1563
|
-
newPriceId: selectedPriceId
|
|
1564
|
-
});
|
|
1565
|
-
onSuccess();
|
|
1566
|
-
onOpenChange(false);
|
|
1567
|
-
} catch (error) {
|
|
1568
|
-
console.error("[SubscriptionEditor] Failed to change plan:", error);
|
|
1569
|
-
} finally {
|
|
1570
|
-
setLoadingPriceId(null);
|
|
1571
|
-
}
|
|
1572
|
-
}, "handleConfirmPlanChange");
|
|
1573
|
-
const handleCancel = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
|
|
1574
|
-
setSelectedPriceId(null);
|
|
1575
|
-
setProrationPreview(null);
|
|
1576
|
-
}, "handleCancel");
|
|
1577
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.DialogContent, { className: "max-w-4xl max-h-[90vh] overflow-y-auto", children: [
|
|
1578
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.DialogHeader, { children: [
|
|
1579
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.DialogTitle, { children: subscription ? "Change Plan" : "Subscribe to a Plan" }),
|
|
1580
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.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." })
|
|
1581
|
-
] }),
|
|
1582
|
-
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, _chunkIXI4GAKBjs.Alert, { variant: "destructive", children: [
|
|
1583
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.AlertTitle, { children: "Payment Method Required" }),
|
|
1584
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.AlertDescription, { className: "mt-2", children: [
|
|
1585
|
-
/* @__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." }),
|
|
1586
|
-
onAddPaymentMethod && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Button, { onClick: onAddPaymentMethod, variant: "outline", children: "Add Payment Method" })
|
|
1587
|
-
] })
|
|
1588
|
-
] }) : paymentConfirmationState === "confirming" || isConfirming ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
|
|
1589
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Loader2, { className: "h-8 w-8 animate-spin text-primary" }),
|
|
1590
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
|
|
1591
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium", children: "Processing payment..." }),
|
|
1592
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Please complete any verification if prompted." })
|
|
1593
|
-
] })
|
|
1594
|
-
] }) : paymentConfirmationState === "success" ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
|
|
1595
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CheckCircle, { className: "h-12 w-12 text-green-500" }),
|
|
1596
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
|
|
1597
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium text-green-600", children: "Payment successful!" }),
|
|
1598
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Your subscription is now active." })
|
|
1599
|
-
] })
|
|
1600
|
-
] }) : paymentConfirmationState === "error" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-4", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.Alert, { variant: "destructive", children: [
|
|
1601
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.AlertTitle, { children: "Payment Failed" }),
|
|
1602
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.AlertDescription, { className: "mt-2", children: [
|
|
1603
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-4", children: paymentError || "We couldn't process your payment. Please try again." }),
|
|
1604
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1605
|
-
_chunkIXI4GAKBjs.Button,
|
|
1606
|
-
{
|
|
1607
|
-
onClick: () => {
|
|
1608
|
-
setPaymentConfirmationState("idle");
|
|
1609
|
-
setPaymentError(null);
|
|
1610
|
-
setLoadingPriceId(null);
|
|
1611
|
-
},
|
|
1612
|
-
variant: "outline",
|
|
1613
|
-
children: "Try Again"
|
|
1614
|
-
}
|
|
1615
|
-
)
|
|
1616
|
-
] })
|
|
1617
|
-
] }) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
|
|
1618
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1619
|
-
PricingCardsGrid,
|
|
1620
|
-
{
|
|
1621
|
-
products,
|
|
1622
|
-
pricesByProduct,
|
|
1623
|
-
currentPriceId,
|
|
1624
|
-
selectedPriceId: _nullishCoalesce(selectedPriceId, () => ( void 0)),
|
|
1625
|
-
loadingPriceId: _nullishCoalesce(loadingPriceId, () => ( void 0)),
|
|
1626
|
-
loading,
|
|
1627
|
-
onSelectPrice: handleSelectPrice
|
|
1628
|
-
}
|
|
1629
|
-
),
|
|
1630
|
-
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..." }),
|
|
1631
|
-
isEditMode && prorationPreview && !loadingProration && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-4", children: [
|
|
1632
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ProrationPreview, { preview: prorationPreview }),
|
|
1633
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-3", children: [
|
|
1634
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Button, { variant: "outline", onClick: handleCancel, disabled: !!loadingPriceId, children: "Cancel" }),
|
|
1635
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.Button, { onClick: handleConfirmPlanChange, disabled: !!loadingPriceId, children: loadingPriceId ? "Processing..." : "Confirm Plan Change" })
|
|
1636
|
-
] })
|
|
1637
|
-
] })
|
|
1638
|
-
] })
|
|
1639
|
-
] }) });
|
|
1640
|
-
}
|
|
1641
|
-
_chunk7QVYU63Ejs.__name.call(void 0, SubscriptionEditor, "SubscriptionEditor");
|
|
1642
|
-
|
|
1643
|
-
// src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
// src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
1221
|
// src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx
|
|
1650
1222
|
|
|
1651
1223
|
var statusConfig2 = {
|
|
@@ -1696,10 +1268,10 @@ _chunk7QVYU63Ejs.__name.call(void 0, SubscriptionStatusBadge, "SubscriptionStatu
|
|
|
1696
1268
|
|
|
1697
1269
|
function formatPlanName2(price) {
|
|
1698
1270
|
if (!price) return "N/A";
|
|
1699
|
-
const productName = _optionalChain([price, 'access',
|
|
1271
|
+
const productName = _optionalChain([price, 'access', _39 => _39.product, 'optionalAccess', _40 => _40.name]) || "";
|
|
1700
1272
|
const nickname = price.nickname || "";
|
|
1701
1273
|
let interval = "";
|
|
1702
|
-
if (_optionalChain([price, 'access',
|
|
1274
|
+
if (_optionalChain([price, 'access', _41 => _41.recurring, 'optionalAccess', _42 => _42.interval])) {
|
|
1703
1275
|
const intervalMap = {
|
|
1704
1276
|
day: "Daily",
|
|
1705
1277
|
week: "Weekly",
|
|
@@ -1714,7 +1286,7 @@ function formatPlanName2(price) {
|
|
|
1714
1286
|
}
|
|
1715
1287
|
_chunk7QVYU63Ejs.__name.call(void 0, formatPlanName2, "formatPlanName");
|
|
1716
1288
|
function formatBillingAmount(price) {
|
|
1717
|
-
if (!_optionalChain([price, 'optionalAccess',
|
|
1289
|
+
if (!_optionalChain([price, 'optionalAccess', _43 => _43.unitAmount])) return "N/A";
|
|
1718
1290
|
return formatCurrency(price.unitAmount, price.currency);
|
|
1719
1291
|
}
|
|
1720
1292
|
_chunk7QVYU63Ejs.__name.call(void 0, formatBillingAmount, "formatBillingAmount");
|
|
@@ -1722,15 +1294,15 @@ function SubscriptionDetails({
|
|
|
1722
1294
|
subscription,
|
|
1723
1295
|
open,
|
|
1724
1296
|
onOpenChange,
|
|
1725
|
-
onSubscriptionChange
|
|
1297
|
+
onSubscriptionChange,
|
|
1298
|
+
onChangePlan
|
|
1726
1299
|
}) {
|
|
1727
|
-
const [showEdit, setShowEdit] = _react.useState.call(void 0, false);
|
|
1728
1300
|
const [showCancel, setShowCancel] = _react.useState.call(void 0, false);
|
|
1729
1301
|
const [isProcessing, setIsProcessing] = _react.useState.call(void 0, false);
|
|
1730
1302
|
const handlePause = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
1731
1303
|
setIsProcessing(true);
|
|
1732
1304
|
try {
|
|
1733
|
-
await
|
|
1305
|
+
await _chunkJ22NEVSKjs.StripeSubscriptionService.pauseSubscription({ subscriptionId: subscription.id });
|
|
1734
1306
|
onSubscriptionChange();
|
|
1735
1307
|
} catch (error) {
|
|
1736
1308
|
console.error("[SubscriptionDetails] Failed to pause subscription:", error);
|
|
@@ -1741,7 +1313,7 @@ function SubscriptionDetails({
|
|
|
1741
1313
|
const handleResume = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
1742
1314
|
setIsProcessing(true);
|
|
1743
1315
|
try {
|
|
1744
|
-
await
|
|
1316
|
+
await _chunkJ22NEVSKjs.StripeSubscriptionService.resumeSubscription({ subscriptionId: subscription.id });
|
|
1745
1317
|
onSubscriptionChange();
|
|
1746
1318
|
} catch (error) {
|
|
1747
1319
|
console.error("[SubscriptionDetails] Failed to resume subscription:", error);
|
|
@@ -1751,7 +1323,7 @@ function SubscriptionDetails({
|
|
|
1751
1323
|
}, "handleResume");
|
|
1752
1324
|
const handleManageViaPortal = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
1753
1325
|
try {
|
|
1754
|
-
const { url } = await
|
|
1326
|
+
const { url } = await _chunkJ22NEVSKjs.StripeCustomerService.createPortalSession();
|
|
1755
1327
|
window.open(url, "_blank");
|
|
1756
1328
|
} catch (error) {
|
|
1757
1329
|
console.error("[SubscriptionDetails] Failed to create portal session:", error);
|
|
@@ -1761,10 +1333,10 @@ function SubscriptionDetails({
|
|
|
1761
1333
|
const canResume = subscription.status === "paused" /* PAUSED */;
|
|
1762
1334
|
const canCancel = subscription.status === "active" /* ACTIVE */ || subscription.status === "trialing" /* TRIALING */ || subscription.status === "paused" /* PAUSED */;
|
|
1763
1335
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1764
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1765
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1766
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1767
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1336
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogContent, { className: "max-w-2xl", children: [
|
|
1337
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogHeader, { children: [
|
|
1338
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogTitle, { children: "Subscription Details" }),
|
|
1339
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogDescription, { children: "View and manage your subscription" })
|
|
1768
1340
|
] }),
|
|
1769
1341
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
|
|
1770
1342
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
|
|
@@ -1800,26 +1372,14 @@ function SubscriptionDetails({
|
|
|
1800
1372
|
"."
|
|
1801
1373
|
] }) }),
|
|
1802
1374
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap gap-2 pt-4 border-t", children: [
|
|
1803
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1804
|
-
canPause && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1805
|
-
canResume && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1806
|
-
canCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1807
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1375
|
+
onChangePlan && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "default", onClick: () => onChangePlan(subscription), children: "Change Plan" }),
|
|
1376
|
+
canPause && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", onClick: handlePause, disabled: isProcessing, children: isProcessing ? "Pausing..." : "Pause" }),
|
|
1377
|
+
canResume && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", onClick: handleResume, disabled: isProcessing, children: isProcessing ? "Resuming..." : "Resume" }),
|
|
1378
|
+
canCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "destructive", onClick: () => setShowCancel(true), children: "Cancel" }),
|
|
1379
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", onClick: handleManageViaPortal, children: "Manage via Portal" })
|
|
1808
1380
|
] })
|
|
1809
1381
|
] })
|
|
1810
1382
|
] }) }),
|
|
1811
|
-
showEdit && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1812
|
-
SubscriptionEditor,
|
|
1813
|
-
{
|
|
1814
|
-
subscription,
|
|
1815
|
-
open: showEdit,
|
|
1816
|
-
onOpenChange: setShowEdit,
|
|
1817
|
-
onSuccess: () => {
|
|
1818
|
-
onSubscriptionChange();
|
|
1819
|
-
setShowEdit(false);
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
),
|
|
1823
1383
|
showCancel && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1824
1384
|
CancelSubscriptionDialog,
|
|
1825
1385
|
{
|
|
@@ -1836,290 +1396,839 @@ function SubscriptionDetails({
|
|
|
1836
1396
|
}
|
|
1837
1397
|
_chunk7QVYU63Ejs.__name.call(void 0, SubscriptionDetails, "SubscriptionDetails");
|
|
1838
1398
|
|
|
1839
|
-
// src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
|
|
1399
|
+
// src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
|
|
1400
|
+
|
|
1401
|
+
function formatPlanName3(price) {
|
|
1402
|
+
if (!price) return "N/A";
|
|
1403
|
+
const productName = _optionalChain([price, 'access', _44 => _44.product, 'optionalAccess', _45 => _45.name]) || "";
|
|
1404
|
+
const nickname = price.nickname || "";
|
|
1405
|
+
let interval = "";
|
|
1406
|
+
if (_optionalChain([price, 'access', _46 => _46.recurring, 'optionalAccess', _47 => _47.interval])) {
|
|
1407
|
+
const intervalMap = {
|
|
1408
|
+
day: "Daily",
|
|
1409
|
+
week: "Weekly",
|
|
1410
|
+
month: "Monthly",
|
|
1411
|
+
year: "Yearly"
|
|
1412
|
+
};
|
|
1413
|
+
interval = intervalMap[price.recurring.interval] || price.recurring.interval;
|
|
1414
|
+
}
|
|
1415
|
+
const parts = [productName, nickname].filter(Boolean);
|
|
1416
|
+
const planLabel = parts.join(" - ");
|
|
1417
|
+
return interval ? `${planLabel} (${interval})` : planLabel || "N/A";
|
|
1418
|
+
}
|
|
1419
|
+
_chunk7QVYU63Ejs.__name.call(void 0, formatPlanName3, "formatPlanName");
|
|
1420
|
+
function SubscriptionsList({ subscriptions, onSubscriptionsChange, onChangePlan }) {
|
|
1421
|
+
const [selectedSub, setSelectedSub] = _react.useState.call(void 0, null);
|
|
1422
|
+
const handleRowClick = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (subscription) => {
|
|
1423
|
+
setSelectedSub(subscription);
|
|
1424
|
+
}, "handleRowClick");
|
|
1425
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1426
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Table, { children: [
|
|
1427
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHeader, { className: "bg-muted", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.TableRow, { children: [
|
|
1428
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Status" }),
|
|
1429
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Plan" }),
|
|
1430
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Period" }),
|
|
1431
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { className: "text-right", children: "Amount" })
|
|
1432
|
+
] }) }),
|
|
1433
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableBody, { children: subscriptions.map((subscription) => {
|
|
1434
|
+
const price = subscription.price;
|
|
1435
|
+
const amount = _optionalChain([price, 'optionalAccess', _48 => _48.unitAmount]) ? formatCurrency(price.unitAmount, price.currency) : "N/A";
|
|
1436
|
+
const period = `${formatDate3(subscription.currentPeriodStart)} - ${formatDate3(subscription.currentPeriodEnd)}`;
|
|
1437
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1438
|
+
_chunk3X7EEFMNjs.TableRow,
|
|
1439
|
+
{
|
|
1440
|
+
onClick: () => handleRowClick(subscription),
|
|
1441
|
+
className: "cursor-pointer hover:bg-muted/50",
|
|
1442
|
+
children: [
|
|
1443
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SubscriptionStatusBadge, { status: subscription.status, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd }) }),
|
|
1444
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "font-medium", children: formatPlanName3(price) }),
|
|
1445
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "text-muted-foreground text-sm", children: period }),
|
|
1446
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "text-right font-medium", children: amount })
|
|
1447
|
+
]
|
|
1448
|
+
},
|
|
1449
|
+
subscription.id
|
|
1450
|
+
);
|
|
1451
|
+
}) })
|
|
1452
|
+
] }) }),
|
|
1453
|
+
selectedSub && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1454
|
+
SubscriptionDetails,
|
|
1455
|
+
{
|
|
1456
|
+
subscription: selectedSub,
|
|
1457
|
+
open: !!selectedSub,
|
|
1458
|
+
onOpenChange: (open) => !open && setSelectedSub(null),
|
|
1459
|
+
onSubscriptionChange: () => {
|
|
1460
|
+
onSubscriptionsChange();
|
|
1461
|
+
setSelectedSub(null);
|
|
1462
|
+
},
|
|
1463
|
+
onChangePlan: onChangePlan ? (sub) => {
|
|
1464
|
+
setSelectedSub(null);
|
|
1465
|
+
onChangePlan(sub);
|
|
1466
|
+
} : void 0
|
|
1467
|
+
}
|
|
1468
|
+
)
|
|
1469
|
+
] });
|
|
1470
|
+
}
|
|
1471
|
+
_chunk7QVYU63Ejs.__name.call(void 0, SubscriptionsList, "SubscriptionsList");
|
|
1472
|
+
|
|
1473
|
+
// src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx
|
|
1474
|
+
|
|
1475
|
+
function SubscriptionsContainer({ onOpenWizard }) {
|
|
1476
|
+
const [subscriptions, setSubscriptions] = _react.useState.call(void 0, []);
|
|
1477
|
+
const [loading, setLoading] = _react.useState.call(void 0, true);
|
|
1478
|
+
const loadSubscriptions = _react.useCallback.call(void 0, async () => {
|
|
1479
|
+
setLoading(true);
|
|
1480
|
+
try {
|
|
1481
|
+
const fetchedSubscriptions = await _chunkJ22NEVSKjs.StripeSubscriptionService.listSubscriptions();
|
|
1482
|
+
setSubscriptions(fetchedSubscriptions);
|
|
1483
|
+
} catch (error) {
|
|
1484
|
+
console.error("[SubscriptionsContainer] Failed to load subscriptions:", error);
|
|
1485
|
+
} finally {
|
|
1486
|
+
setLoading(false);
|
|
1487
|
+
}
|
|
1488
|
+
}, []);
|
|
1489
|
+
_react.useEffect.call(void 0, () => {
|
|
1490
|
+
loadSubscriptions();
|
|
1491
|
+
}, []);
|
|
1492
|
+
const criticalSubscriptions = subscriptions.filter(
|
|
1493
|
+
(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
|
|
1494
|
+
);
|
|
1495
|
+
if (loading) {
|
|
1496
|
+
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..." }) });
|
|
1497
|
+
}
|
|
1498
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-y-6", children: [
|
|
1499
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between", children: [
|
|
1500
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-3", children: [
|
|
1501
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-8 w-8" }),
|
|
1502
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Subscriptions" })
|
|
1503
|
+
] }),
|
|
1504
|
+
subscriptions.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: () => _optionalChain([onOpenWizard, 'optionalCall', _49 => _49()]), children: "Subscribe to a Plan" })
|
|
1505
|
+
] }),
|
|
1506
|
+
criticalSubscriptions.map((subscription) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, BillingAlertBanner, { subscription }, subscription.id)),
|
|
1507
|
+
subscriptions.length === 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
|
|
1508
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "h-16 w-16 text-muted-foreground" }),
|
|
1509
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
|
|
1510
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "text-xl font-semibold mb-2", children: "No Active Subscriptions" }),
|
|
1511
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground mb-6", children: "Choose a subscription plan to get started with our services." }),
|
|
1512
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: () => _optionalChain([onOpenWizard, 'optionalCall', _50 => _50()]), children: "Subscribe to a Plan" })
|
|
1513
|
+
] })
|
|
1514
|
+
] }),
|
|
1515
|
+
subscriptions.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1516
|
+
SubscriptionsList,
|
|
1517
|
+
{
|
|
1518
|
+
subscriptions,
|
|
1519
|
+
onSubscriptionsChange: loadSubscriptions,
|
|
1520
|
+
onChangePlan: (sub) => _optionalChain([onOpenWizard, 'optionalCall', _51 => _51(sub)])
|
|
1521
|
+
}
|
|
1522
|
+
)
|
|
1523
|
+
] });
|
|
1524
|
+
}
|
|
1525
|
+
_chunk7QVYU63Ejs.__name.call(void 0, SubscriptionsContainer, "SubscriptionsContainer");
|
|
1526
|
+
|
|
1527
|
+
// src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx
|
|
1528
|
+
|
|
1529
|
+
function IntervalToggle({ value, onChange, hasMonthly, hasYearly }) {
|
|
1530
|
+
if (!hasMonthly || !hasYearly) {
|
|
1531
|
+
return null;
|
|
1532
|
+
}
|
|
1533
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Tabs, { value, onValueChange: (v) => onChange(v), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.TabsList, { children: [
|
|
1534
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TabsTrigger, { value: "month", children: "Monthly" }),
|
|
1535
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TabsTrigger, { value: "year", children: "Yearly" })
|
|
1536
|
+
] }) });
|
|
1537
|
+
}
|
|
1538
|
+
_chunk7QVYU63Ejs.__name.call(void 0, IntervalToggle, "IntervalToggle");
|
|
1539
|
+
|
|
1540
|
+
// src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx
|
|
1541
|
+
|
|
1542
|
+
|
|
1543
|
+
function PricingCard({ price, isCurrentPlan = false, isSelected = false, isDisabled = false, isLoading = false, onSelect }) {
|
|
1544
|
+
const description = price.description || price.nickname || "Standard";
|
|
1545
|
+
const features = price.features || [];
|
|
1546
|
+
const formattedPrice = formatCurrency(price.unitAmount, price.currency);
|
|
1547
|
+
const interval = formatInterval(price);
|
|
1548
|
+
const handleKeyDown = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (e) => {
|
|
1549
|
+
if ((e.key === "Enter" || e.key === " ") && !isDisabled && !isCurrentPlan) {
|
|
1550
|
+
e.preventDefault();
|
|
1551
|
+
onSelect(price);
|
|
1552
|
+
}
|
|
1553
|
+
}, "handleKeyDown");
|
|
1554
|
+
const handleClick = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, () => {
|
|
1555
|
+
if (!isDisabled && !isCurrentPlan && !isLoading) {
|
|
1556
|
+
onSelect(price);
|
|
1557
|
+
}
|
|
1558
|
+
}, "handleClick");
|
|
1559
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1560
|
+
_chunk3X7EEFMNjs.Card,
|
|
1561
|
+
{
|
|
1562
|
+
role: "radio",
|
|
1563
|
+
"aria-checked": isSelected,
|
|
1564
|
+
"aria-label": `${description} plan at ${formattedPrice} ${interval}`,
|
|
1565
|
+
tabIndex: isDisabled ? -1 : 0,
|
|
1566
|
+
onKeyDown: handleKeyDown,
|
|
1567
|
+
onClick: handleClick,
|
|
1568
|
+
className: _chunkJ22NEVSKjs.cn.call(void 0,
|
|
1569
|
+
"relative cursor-pointer transition-all duration-200 flex flex-col h-full",
|
|
1570
|
+
"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
|
1571
|
+
isCurrentPlan && "bg-muted/30",
|
|
1572
|
+
isSelected && !isCurrentPlan && "ring-2 ring-primary",
|
|
1573
|
+
!isDisabled && !isCurrentPlan && "hover:shadow-md hover:border-primary/50",
|
|
1574
|
+
isDisabled && "opacity-50 pointer-events-none",
|
|
1575
|
+
isLoading && "pointer-events-none"
|
|
1576
|
+
),
|
|
1577
|
+
children: [
|
|
1578
|
+
isCurrentPlan && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Badge, { variant: "secondary", className: "absolute top-2 right-2", children: "Current" }),
|
|
1579
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "pb-2", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-lg", children: description }) }),
|
|
1580
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardContent, { className: "pb-4 grow", children: [
|
|
1581
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "mb-4", children: [
|
|
1582
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-3xl font-bold", children: formattedPrice }),
|
|
1583
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-muted-foreground ml-1", children: interval })
|
|
1584
|
+
] }),
|
|
1585
|
+
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: [
|
|
1586
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Check, { className: "h-4 w-4 text-green-500 mt-0.5 shrink-0" }),
|
|
1587
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm text-muted-foreground", children: feature })
|
|
1588
|
+
] }, index)) })
|
|
1589
|
+
] }),
|
|
1590
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardFooter, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1591
|
+
_chunk3X7EEFMNjs.Button,
|
|
1592
|
+
{
|
|
1593
|
+
variant: isCurrentPlan ? "secondary" : isSelected ? "default" : "outline",
|
|
1594
|
+
className: "w-full",
|
|
1595
|
+
disabled: isDisabled || isCurrentPlan || isLoading,
|
|
1596
|
+
children: isLoading ? "Processing..." : isCurrentPlan ? "Current Plan" : isSelected ? "Selected" : "Select Plan"
|
|
1597
|
+
}
|
|
1598
|
+
) })
|
|
1599
|
+
]
|
|
1600
|
+
}
|
|
1601
|
+
);
|
|
1602
|
+
}
|
|
1603
|
+
_chunk7QVYU63Ejs.__name.call(void 0, PricingCard, "PricingCard");
|
|
1604
|
+
|
|
1605
|
+
// src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx
|
|
1606
|
+
|
|
1607
|
+
function ProductPricingRow({
|
|
1608
|
+
product,
|
|
1609
|
+
prices,
|
|
1610
|
+
currentPriceId,
|
|
1611
|
+
selectedPriceId,
|
|
1612
|
+
loadingPriceId,
|
|
1613
|
+
onSelectPrice
|
|
1614
|
+
}) {
|
|
1615
|
+
if (prices.length === 0) {
|
|
1616
|
+
return null;
|
|
1617
|
+
}
|
|
1618
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-3", children: [
|
|
1619
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-lg", children: product.name }),
|
|
1620
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1621
|
+
"div",
|
|
1622
|
+
{
|
|
1623
|
+
className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
|
|
1624
|
+
role: "radiogroup",
|
|
1625
|
+
"aria-label": `Pricing options for ${product.name}`,
|
|
1626
|
+
children: prices.sort((a, b) => (_nullishCoalesce(a.unitAmount, () => ( 0))) - (_nullishCoalesce(b.unitAmount, () => ( 0)))).map((price) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1627
|
+
PricingCard,
|
|
1628
|
+
{
|
|
1629
|
+
price,
|
|
1630
|
+
isCurrentPlan: price.id === currentPriceId,
|
|
1631
|
+
isSelected: price.id === selectedPriceId,
|
|
1632
|
+
isLoading: price.id === loadingPriceId,
|
|
1633
|
+
onSelect: onSelectPrice
|
|
1634
|
+
},
|
|
1635
|
+
price.id
|
|
1636
|
+
))
|
|
1637
|
+
}
|
|
1638
|
+
)
|
|
1639
|
+
] });
|
|
1640
|
+
}
|
|
1641
|
+
_chunk7QVYU63Ejs.__name.call(void 0, ProductPricingRow, "ProductPricingRow");
|
|
1642
|
+
|
|
1643
|
+
// src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx
|
|
1644
|
+
|
|
1645
|
+
function isRecurringProduct(prices) {
|
|
1646
|
+
return prices.some((p) => p.priceType === "recurring");
|
|
1647
|
+
}
|
|
1648
|
+
_chunk7QVYU63Ejs.__name.call(void 0, isRecurringProduct, "isRecurringProduct");
|
|
1649
|
+
function getFilteredPrices(prices, selectedInterval) {
|
|
1650
|
+
const isRecurring = isRecurringProduct(prices);
|
|
1651
|
+
if (!isRecurring) {
|
|
1652
|
+
return prices.filter((p) => p.priceType === "one_time");
|
|
1653
|
+
}
|
|
1654
|
+
const intervalPrices = prices.filter(
|
|
1655
|
+
(p) => p.priceType === "recurring" && _optionalChain([p, 'access', _52 => _52.recurring, 'optionalAccess', _53 => _53.interval]) === selectedInterval
|
|
1656
|
+
);
|
|
1657
|
+
if (intervalPrices.length === 0) {
|
|
1658
|
+
const fallbackInterval = selectedInterval === "month" ? "year" : "month";
|
|
1659
|
+
return prices.filter((p) => p.priceType === "recurring" && _optionalChain([p, 'access', _54 => _54.recurring, 'optionalAccess', _55 => _55.interval]) === fallbackInterval);
|
|
1660
|
+
}
|
|
1661
|
+
return intervalPrices;
|
|
1662
|
+
}
|
|
1663
|
+
_chunk7QVYU63Ejs.__name.call(void 0, getFilteredPrices, "getFilteredPrices");
|
|
1664
|
+
function ProductPricingList({
|
|
1665
|
+
products,
|
|
1666
|
+
selectedInterval,
|
|
1667
|
+
currentPriceId,
|
|
1668
|
+
selectedPriceId,
|
|
1669
|
+
loadingPriceId,
|
|
1670
|
+
loading = false,
|
|
1671
|
+
onSelectPrice,
|
|
1672
|
+
hideRecurringPrices = false
|
|
1673
|
+
}) {
|
|
1674
|
+
if (loading) {
|
|
1675
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ProductPricingListSkeleton, {});
|
|
1676
|
+
}
|
|
1677
|
+
if (products.length === 0) {
|
|
1678
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-center py-8 text-muted-foreground", children: "No plans available" });
|
|
1679
|
+
}
|
|
1680
|
+
const sortedProducts = [...products].sort((a, b) => {
|
|
1681
|
+
const aRecurring = isRecurringProduct(a.stripePrices || []);
|
|
1682
|
+
const bRecurring = isRecurringProduct(b.stripePrices || []);
|
|
1683
|
+
if (aRecurring && !bRecurring) return -1;
|
|
1684
|
+
if (!aRecurring && bRecurring) return 1;
|
|
1685
|
+
return 0;
|
|
1686
|
+
});
|
|
1687
|
+
const filteredProducts = hideRecurringPrices ? sortedProducts.map((product) => ({
|
|
1688
|
+
...product,
|
|
1689
|
+
stripePrices: (product.stripePrices || []).filter((price) => price.priceType !== "recurring")
|
|
1690
|
+
})).filter((product) => product.stripePrices.length > 0) : sortedProducts;
|
|
1691
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-6", children: filteredProducts.map((product) => {
|
|
1692
|
+
const allPrices = product.stripePrices || [];
|
|
1693
|
+
const filteredPrices = getFilteredPrices(allPrices, selectedInterval);
|
|
1694
|
+
if (filteredPrices.length === 0) {
|
|
1695
|
+
return null;
|
|
1696
|
+
}
|
|
1697
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1698
|
+
ProductPricingRow,
|
|
1699
|
+
{
|
|
1700
|
+
product,
|
|
1701
|
+
prices: filteredPrices,
|
|
1702
|
+
currentPriceId,
|
|
1703
|
+
selectedPriceId,
|
|
1704
|
+
loadingPriceId,
|
|
1705
|
+
onSelectPrice
|
|
1706
|
+
},
|
|
1707
|
+
product.id
|
|
1708
|
+
);
|
|
1709
|
+
}) });
|
|
1710
|
+
}
|
|
1711
|
+
_chunk7QVYU63Ejs.__name.call(void 0, ProductPricingList, "ProductPricingList");
|
|
1712
|
+
function ProductPricingListSkeleton() {
|
|
1713
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-6", children: [1, 2].map((rowIndex) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-3", children: [
|
|
1714
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-6 w-32" }),
|
|
1715
|
+
/* @__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, "div", { className: "p-4 rounded-lg border animate-pulse space-y-3", children: [
|
|
1716
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-6 w-24" }),
|
|
1717
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-8 w-32" }),
|
|
1718
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
1719
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-full" }),
|
|
1720
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-4 w-3/4" })
|
|
1721
|
+
] }),
|
|
1722
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Skeleton, { className: "h-10 w-full" })
|
|
1723
|
+
] }, cardIndex)) })
|
|
1724
|
+
] }, rowIndex)) });
|
|
1725
|
+
}
|
|
1726
|
+
_chunk7QVYU63Ejs.__name.call(void 0, ProductPricingListSkeleton, "ProductPricingListSkeleton");
|
|
1727
|
+
|
|
1728
|
+
// src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx
|
|
1729
|
+
|
|
1730
|
+
function ProrationPreview({ preview }) {
|
|
1731
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4", children: [
|
|
1732
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "font-semibold text-blue-900 mb-3", children: "Proration Breakdown" }),
|
|
1733
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
1734
|
+
preview.lineItems.map((item, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between text-sm", children: [
|
|
1735
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-800", children: item.description }),
|
|
1736
|
+
/* @__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) })
|
|
1737
|
+
] }, index)),
|
|
1738
|
+
/* @__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: [
|
|
1739
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-900", children: "Net Due Today" }),
|
|
1740
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-900", children: formatCurrency(preview.immediateCharge, preview.currency) })
|
|
1741
|
+
] }) }),
|
|
1742
|
+
preview.lineItems.length > 0 && preview.lineItems[0].period && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-xs text-blue-700 mt-2", children: [
|
|
1743
|
+
"Next invoice on ",
|
|
1744
|
+
formatDate3(preview.lineItems[0].period.end),
|
|
1745
|
+
" for",
|
|
1746
|
+
" ",
|
|
1747
|
+
formatCurrency(preview.amountDue, preview.currency)
|
|
1748
|
+
] })
|
|
1749
|
+
] })
|
|
1750
|
+
] });
|
|
1751
|
+
}
|
|
1752
|
+
_chunk7QVYU63Ejs.__name.call(void 0, ProrationPreview, "ProrationPreview");
|
|
1753
|
+
|
|
1754
|
+
// src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx
|
|
1755
|
+
|
|
1840
1756
|
|
|
1841
|
-
function
|
|
1842
|
-
|
|
1843
|
-
const
|
|
1844
|
-
const
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
}
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableHead, { children: "Status" }),
|
|
1869
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableHead, { children: "Plan" }),
|
|
1870
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableHead, { children: "Period" }),
|
|
1871
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableHead, { className: "text-right", children: "Amount" })
|
|
1872
|
-
] }) }),
|
|
1873
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableBody, { children: subscriptions.map((subscription) => {
|
|
1874
|
-
const price = subscription.price;
|
|
1875
|
-
const amount = _optionalChain([price, 'optionalAccess', _56 => _56.unitAmount]) ? formatCurrency(price.unitAmount, price.currency) : "N/A";
|
|
1876
|
-
const period = `${formatDate3(subscription.currentPeriodStart)} - ${formatDate3(subscription.currentPeriodEnd)}`;
|
|
1877
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1878
|
-
_chunkIXI4GAKBjs.TableRow,
|
|
1879
|
-
{
|
|
1880
|
-
onClick: () => handleRowClick(subscription),
|
|
1881
|
-
className: "cursor-pointer hover:bg-muted/50",
|
|
1882
|
-
children: [
|
|
1883
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableCell, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SubscriptionStatusBadge, { status: subscription.status, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd }) }),
|
|
1884
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableCell, { className: "font-medium", children: formatPlanName3(price) }),
|
|
1885
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableCell, { className: "text-muted-foreground text-sm", children: period }),
|
|
1886
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.TableCell, { className: "text-right font-medium", children: amount })
|
|
1887
|
-
]
|
|
1888
|
-
},
|
|
1889
|
-
subscription.id
|
|
1890
|
-
);
|
|
1891
|
-
}) })
|
|
1892
|
-
] }) }),
|
|
1893
|
-
selectedSub && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1894
|
-
SubscriptionDetails,
|
|
1895
|
-
{
|
|
1896
|
-
subscription: selectedSub,
|
|
1897
|
-
open: !!selectedSub,
|
|
1898
|
-
onOpenChange: (open) => !open && setSelectedSub(null),
|
|
1899
|
-
onSubscriptionChange: () => {
|
|
1900
|
-
onSubscriptionsChange();
|
|
1901
|
-
setSelectedSub(null);
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
)
|
|
1757
|
+
function SubscriptionConfirmation({ price, isLoading, onConfirm, onCancel }) {
|
|
1758
|
+
const productName = _optionalChain([price, 'access', _56 => _56.product, 'optionalAccess', _57 => _57.name]) || price.nickname || "Selected Plan";
|
|
1759
|
+
const productDescription = _optionalChain([price, 'access', _58 => _58.product, 'optionalAccess', _59 => _59.description]) || price.description;
|
|
1760
|
+
const features = price.features || [];
|
|
1761
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-accent/10 border border-accent/30 rounded-lg p-4", children: [
|
|
1762
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "font-semibold mb-3", children: "Confirm Your Subscription" }),
|
|
1763
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-3", children: [
|
|
1764
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
1765
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "font-medium", children: productName }),
|
|
1766
|
+
productDescription && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-sm text-muted-foreground", children: productDescription })
|
|
1767
|
+
] }),
|
|
1768
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-lg font-semibold", children: [
|
|
1769
|
+
formatCurrency(price.unitAmount, price.currency),
|
|
1770
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-sm font-normal text-muted-foreground", children: formatInterval(price) })
|
|
1771
|
+
] }),
|
|
1772
|
+
features.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "space-y-1", children: features.map((feature, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-2 text-sm ", children: [
|
|
1773
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Check, { className: "h-4 w-4 text-primary" }),
|
|
1774
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: feature })
|
|
1775
|
+
] }, index)) }),
|
|
1776
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-end gap-3 pt-2 border-t border-accent/30", children: [
|
|
1777
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", onClick: onCancel, disabled: isLoading, children: "Cancel" }),
|
|
1778
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: onConfirm, disabled: isLoading, children: isLoading ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1779
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Loader2, { className: "h-4 w-4 animate-spin mr-2" }),
|
|
1780
|
+
"Processing..."
|
|
1781
|
+
] }) : "Subscribe" })
|
|
1782
|
+
] })
|
|
1783
|
+
] })
|
|
1905
1784
|
] });
|
|
1906
1785
|
}
|
|
1907
|
-
_chunk7QVYU63Ejs.__name.call(void 0,
|
|
1786
|
+
_chunk7QVYU63Ejs.__name.call(void 0, SubscriptionConfirmation, "SubscriptionConfirmation");
|
|
1908
1787
|
|
|
1909
|
-
// src/features/billing/stripe-subscription/components/
|
|
1788
|
+
// src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx
|
|
1910
1789
|
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1790
|
+
|
|
1791
|
+
// src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts
|
|
1792
|
+
|
|
1793
|
+
var initialState = {
|
|
1794
|
+
step: "plan-selection",
|
|
1795
|
+
selectedPrice: null,
|
|
1796
|
+
selectedInterval: "month",
|
|
1797
|
+
hasPaymentMethod: false,
|
|
1798
|
+
isProcessing: false,
|
|
1799
|
+
error: null,
|
|
1800
|
+
prorationPreview: null
|
|
1801
|
+
};
|
|
1802
|
+
function wizardReducer(state, action) {
|
|
1803
|
+
switch (action.type) {
|
|
1804
|
+
case "SET_STEP":
|
|
1805
|
+
return { ...state, step: action.step, error: null };
|
|
1806
|
+
case "SELECT_PRICE":
|
|
1807
|
+
return { ...state, selectedPrice: action.price };
|
|
1808
|
+
case "SET_INTERVAL":
|
|
1809
|
+
return { ...state, selectedInterval: action.interval };
|
|
1810
|
+
case "SET_HAS_PAYMENT_METHOD":
|
|
1811
|
+
return { ...state, hasPaymentMethod: action.hasMethod };
|
|
1812
|
+
case "SET_PROCESSING":
|
|
1813
|
+
return { ...state, isProcessing: action.isProcessing };
|
|
1814
|
+
case "SET_ERROR":
|
|
1815
|
+
return { ...state, error: action.error };
|
|
1816
|
+
case "SET_PRORATION_PREVIEW":
|
|
1817
|
+
return { ...state, prorationPreview: action.preview };
|
|
1818
|
+
case "RESET":
|
|
1819
|
+
return initialState;
|
|
1820
|
+
default:
|
|
1821
|
+
return state;
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
_chunk7QVYU63Ejs.__name.call(void 0, wizardReducer, "wizardReducer");
|
|
1825
|
+
function useSubscriptionWizard({ subscription, onSuccess, onClose }) {
|
|
1826
|
+
const [state, dispatch] = _react.useReducer.call(void 0, wizardReducer, {
|
|
1827
|
+
...initialState,
|
|
1828
|
+
selectedPrice: _optionalChain([subscription, 'optionalAccess', _60 => _60.price]) || null
|
|
1829
|
+
});
|
|
1830
|
+
const onSuccessRef = _react.useRef.call(void 0, onSuccess);
|
|
1831
|
+
const onCloseRef = _react.useRef.call(void 0, onClose);
|
|
1832
|
+
onSuccessRef.current = onSuccess;
|
|
1833
|
+
onCloseRef.current = onClose;
|
|
1834
|
+
const checkPaymentMethod = _react.useCallback.call(void 0, async () => {
|
|
1927
1835
|
try {
|
|
1928
|
-
const
|
|
1929
|
-
|
|
1836
|
+
const methods = await _chunkJ22NEVSKjs.StripeCustomerService.listPaymentMethods();
|
|
1837
|
+
dispatch({ type: "SET_HAS_PAYMENT_METHOD", hasMethod: methods.length > 0 });
|
|
1930
1838
|
} catch (error) {
|
|
1931
|
-
console.error("[
|
|
1932
|
-
|
|
1933
|
-
setLoading(false);
|
|
1839
|
+
console.error("[useSubscriptionWizard] Failed to check payment methods:", error);
|
|
1840
|
+
dispatch({ type: "SET_HAS_PAYMENT_METHOD", hasMethod: false });
|
|
1934
1841
|
}
|
|
1935
|
-
},
|
|
1936
|
-
const
|
|
1937
|
-
|
|
1842
|
+
}, []);
|
|
1843
|
+
const selectPrice = _react.useCallback.call(void 0, (price) => {
|
|
1844
|
+
dispatch({ type: "SELECT_PRICE", price });
|
|
1845
|
+
}, []);
|
|
1846
|
+
const setInterval = _react.useCallback.call(void 0, (interval) => {
|
|
1847
|
+
dispatch({ type: "SET_INTERVAL", interval });
|
|
1848
|
+
}, []);
|
|
1849
|
+
const goToStep = _react.useCallback.call(void 0, (step) => {
|
|
1850
|
+
dispatch({ type: "SET_STEP", step });
|
|
1851
|
+
}, []);
|
|
1852
|
+
const goToReview = _react.useCallback.call(void 0, async () => {
|
|
1853
|
+
if (!state.selectedPrice) return;
|
|
1854
|
+
dispatch({ type: "SET_PROCESSING", isProcessing: true });
|
|
1938
1855
|
try {
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
}
|
|
1856
|
+
await checkPaymentMethod();
|
|
1857
|
+
if (subscription && state.selectedPrice.id !== _optionalChain([subscription, 'access', _61 => _61.price, 'optionalAccess', _62 => _62.id])) {
|
|
1858
|
+
const preview = await _chunkJ22NEVSKjs.StripeSubscriptionService.getProrationPreview({
|
|
1859
|
+
subscriptionId: subscription.id,
|
|
1860
|
+
newPriceId: state.selectedPrice.id
|
|
1861
|
+
});
|
|
1862
|
+
dispatch({ type: "SET_PRORATION_PREVIEW", preview });
|
|
1945
1863
|
}
|
|
1946
|
-
|
|
1947
|
-
setPricesByProduct(grouped);
|
|
1864
|
+
dispatch({ type: "SET_STEP", step: "review" });
|
|
1948
1865
|
} catch (error) {
|
|
1949
|
-
console.error("[
|
|
1866
|
+
console.error("[useSubscriptionWizard] Error preparing review:", error);
|
|
1867
|
+
dispatch({ type: "SET_ERROR", error: _optionalChain([error, 'optionalAccess', _63 => _63.message]) || "Failed to prepare review" });
|
|
1950
1868
|
} finally {
|
|
1951
|
-
|
|
1869
|
+
dispatch({ type: "SET_PROCESSING", isProcessing: false });
|
|
1952
1870
|
}
|
|
1953
|
-
},
|
|
1954
|
-
const
|
|
1871
|
+
}, [state.selectedPrice, subscription, checkPaymentMethod]);
|
|
1872
|
+
const confirmSubscription = _react.useCallback.call(void 0, async () => {
|
|
1873
|
+
if (!state.selectedPrice) return;
|
|
1874
|
+
dispatch({ type: "SET_PROCESSING", isProcessing: true });
|
|
1875
|
+
dispatch({ type: "SET_ERROR", error: null });
|
|
1955
1876
|
try {
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
setCreatingSubscription(true);
|
|
1966
|
-
setPaymentError(null);
|
|
1967
|
-
setPaymentConfirmationState("idle");
|
|
1968
|
-
try {
|
|
1969
|
-
const result = await _chunkTSEU4KZ2js.StripeSubscriptionService.createSubscription({
|
|
1970
|
-
id: _uuid.v4.call(void 0, ),
|
|
1971
|
-
priceId
|
|
1972
|
-
});
|
|
1973
|
-
if (result.meta.requiresAction && result.meta.clientSecret) {
|
|
1974
|
-
setPaymentConfirmationState("confirming");
|
|
1975
|
-
const confirmation = await confirmPayment(result.meta.clientSecret);
|
|
1976
|
-
if (!confirmation.success) {
|
|
1977
|
-
console.error("[SubscriptionsContainer] Payment confirmation failed:", confirmation.error);
|
|
1978
|
-
setPaymentConfirmationState("error");
|
|
1979
|
-
setPaymentError(confirmation.error || "Payment confirmation failed");
|
|
1980
|
-
setCreatingSubscription(false);
|
|
1981
|
-
return;
|
|
1982
|
-
}
|
|
1983
|
-
await _chunkTSEU4KZ2js.StripeSubscriptionService.syncSubscription({
|
|
1984
|
-
subscriptionId: result.subscription.id
|
|
1877
|
+
if (subscription) {
|
|
1878
|
+
await _chunkJ22NEVSKjs.StripeSubscriptionService.changePlan({
|
|
1879
|
+
id: subscription.id,
|
|
1880
|
+
newPriceId: state.selectedPrice.id
|
|
1881
|
+
});
|
|
1882
|
+
} else {
|
|
1883
|
+
await _chunkJ22NEVSKjs.StripeSubscriptionService.createSubscription({
|
|
1884
|
+
id: crypto.randomUUID(),
|
|
1885
|
+
priceId: state.selectedPrice.id
|
|
1985
1886
|
});
|
|
1986
1887
|
}
|
|
1987
|
-
|
|
1988
|
-
|
|
1888
|
+
onSuccessRef.current();
|
|
1889
|
+
onCloseRef.current();
|
|
1989
1890
|
} catch (error) {
|
|
1990
|
-
console.error("[
|
|
1991
|
-
if (_optionalChain([error, 'optionalAccess',
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1891
|
+
console.error("[useSubscriptionWizard] Subscription error:", error);
|
|
1892
|
+
if (_optionalChain([error, 'optionalAccess', _64 => _64.status]) === 409 || _optionalChain([error, 'optionalAccess', _65 => _65.response, 'optionalAccess', _66 => _66.status]) === 409) {
|
|
1893
|
+
dispatch({
|
|
1894
|
+
type: "SET_ERROR",
|
|
1895
|
+
error: "You already have an active subscription. Please change your existing plan instead."
|
|
1896
|
+
});
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1899
|
+
if (_optionalChain([error, 'optionalAccess', _67 => _67.status]) === 402 || _optionalChain([error, 'optionalAccess', _68 => _68.response, 'optionalAccess', _69 => _69.status]) === 402) {
|
|
1900
|
+
dispatch({ type: "SET_HAS_PAYMENT_METHOD", hasMethod: false });
|
|
1901
|
+
dispatch({ type: "SET_STEP", step: "payment-method" });
|
|
1902
|
+
return;
|
|
1998
1903
|
}
|
|
1904
|
+
dispatch({ type: "SET_ERROR", error: _optionalChain([error, 'optionalAccess', _70 => _70.message]) || "Failed to process subscription" });
|
|
1999
1905
|
} finally {
|
|
2000
|
-
|
|
2001
|
-
}
|
|
2002
|
-
}, "createSubscriptionWithPrice");
|
|
2003
|
-
const handleSelectPrice = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (price) => {
|
|
2004
|
-
const priceId = price.id;
|
|
2005
|
-
if (!hasPaymentMethod) {
|
|
2006
|
-
setPendingPriceId(priceId);
|
|
2007
|
-
setShowPaymentMethodEditor(true);
|
|
2008
|
-
return;
|
|
2009
|
-
}
|
|
2010
|
-
await createSubscriptionWithPrice(priceId);
|
|
2011
|
-
}, "handleSelectPrice");
|
|
2012
|
-
const handlePaymentMethodSuccess = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2013
|
-
setShowPaymentMethodEditor(false);
|
|
2014
|
-
setHasPaymentMethod(true);
|
|
2015
|
-
if (pendingPriceId) {
|
|
2016
|
-
await createSubscriptionWithPrice(pendingPriceId);
|
|
2017
|
-
setPendingPriceId(null);
|
|
1906
|
+
dispatch({ type: "SET_PROCESSING", isProcessing: false });
|
|
2018
1907
|
}
|
|
2019
|
-
},
|
|
2020
|
-
_react.
|
|
2021
|
-
|
|
1908
|
+
}, [state.selectedPrice, subscription]);
|
|
1909
|
+
const handlePaymentMethodSuccess = _react.useCallback.call(void 0, async () => {
|
|
1910
|
+
dispatch({ type: "SET_HAS_PAYMENT_METHOD", hasMethod: true });
|
|
1911
|
+
dispatch({ type: "SET_STEP", step: "review" });
|
|
1912
|
+
}, []);
|
|
1913
|
+
const reset = _react.useCallback.call(void 0, () => {
|
|
1914
|
+
dispatch({ type: "RESET" });
|
|
2022
1915
|
}, []);
|
|
1916
|
+
const actions = _react.useMemo.call(void 0,
|
|
1917
|
+
() => ({
|
|
1918
|
+
selectPrice,
|
|
1919
|
+
setInterval,
|
|
1920
|
+
goToStep,
|
|
1921
|
+
goToReview,
|
|
1922
|
+
confirmSubscription,
|
|
1923
|
+
handlePaymentMethodSuccess,
|
|
1924
|
+
checkPaymentMethod,
|
|
1925
|
+
reset
|
|
1926
|
+
}),
|
|
1927
|
+
[
|
|
1928
|
+
selectPrice,
|
|
1929
|
+
setInterval,
|
|
1930
|
+
goToStep,
|
|
1931
|
+
goToReview,
|
|
1932
|
+
confirmSubscription,
|
|
1933
|
+
handlePaymentMethodSuccess,
|
|
1934
|
+
checkPaymentMethod,
|
|
1935
|
+
reset
|
|
1936
|
+
]
|
|
1937
|
+
);
|
|
1938
|
+
return {
|
|
1939
|
+
state,
|
|
1940
|
+
actions
|
|
1941
|
+
};
|
|
1942
|
+
}
|
|
1943
|
+
_chunk7QVYU63Ejs.__name.call(void 0, useSubscriptionWizard, "useSubscriptionWizard");
|
|
1944
|
+
|
|
1945
|
+
// src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx
|
|
1946
|
+
|
|
1947
|
+
|
|
1948
|
+
var STEPS = [
|
|
1949
|
+
{ key: "plan-selection", label: "Select Plan" },
|
|
1950
|
+
{ key: "review", label: "Review" },
|
|
1951
|
+
{ key: "payment-method", label: "Payment" }
|
|
1952
|
+
];
|
|
1953
|
+
function getStepIndex(step) {
|
|
1954
|
+
return STEPS.findIndex((s) => s.key === step);
|
|
1955
|
+
}
|
|
1956
|
+
_chunk7QVYU63Ejs.__name.call(void 0, getStepIndex, "getStepIndex");
|
|
1957
|
+
function WizardProgressIndicator({ currentStep }) {
|
|
1958
|
+
const currentIndex = getStepIndex(currentStep);
|
|
1959
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex items-center justify-center gap-x-2 py-4", children: STEPS.map((step, index) => {
|
|
1960
|
+
const isCompleted = index < currentIndex;
|
|
1961
|
+
const isCurrent = index === currentIndex;
|
|
1962
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-2", children: [
|
|
1963
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1964
|
+
"div",
|
|
1965
|
+
{
|
|
1966
|
+
className: `flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium ${isCompleted ? "bg-primary text-primary-foreground" : isCurrent ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
|
|
1967
|
+
children: isCompleted ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Check, { className: "h-4 w-4" }) : index + 1
|
|
1968
|
+
}
|
|
1969
|
+
),
|
|
1970
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1971
|
+
"span",
|
|
1972
|
+
{
|
|
1973
|
+
className: `text-sm ${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}`,
|
|
1974
|
+
children: step.label
|
|
1975
|
+
}
|
|
1976
|
+
),
|
|
1977
|
+
index < STEPS.length - 1 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1978
|
+
"div",
|
|
1979
|
+
{
|
|
1980
|
+
className: `h-0.5 w-8 ${index < currentIndex ? "bg-primary" : "bg-muted"}`
|
|
1981
|
+
}
|
|
1982
|
+
)
|
|
1983
|
+
] }, step.key);
|
|
1984
|
+
}) });
|
|
1985
|
+
}
|
|
1986
|
+
_chunk7QVYU63Ejs.__name.call(void 0, WizardProgressIndicator, "WizardProgressIndicator");
|
|
1987
|
+
|
|
1988
|
+
// src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx
|
|
1989
|
+
|
|
1990
|
+
|
|
1991
|
+
function WizardStepPlanSelection({
|
|
1992
|
+
selectedPrice,
|
|
1993
|
+
selectedInterval,
|
|
1994
|
+
currentPriceId,
|
|
1995
|
+
hideRecurringPrices,
|
|
1996
|
+
onSelectPrice,
|
|
1997
|
+
onIntervalChange,
|
|
1998
|
+
onNext,
|
|
1999
|
+
isProcessing
|
|
2000
|
+
}) {
|
|
2001
|
+
const [products, setProducts] = _react.useState.call(void 0, []);
|
|
2002
|
+
const [loading, setLoading] = _react.useState.call(void 0, true);
|
|
2023
2003
|
_react.useEffect.call(void 0, () => {
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2004
|
+
const loadProducts = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2005
|
+
try {
|
|
2006
|
+
const fetchedProducts = await _chunkJ22NEVSKjs.StripeProductService.listProducts({ active: true });
|
|
2007
|
+
setProducts(fetchedProducts);
|
|
2008
|
+
} catch (error) {
|
|
2009
|
+
console.error("[WizardStepPlanSelection] Failed to load products:", error);
|
|
2010
|
+
} finally {
|
|
2011
|
+
setLoading(false);
|
|
2012
|
+
}
|
|
2013
|
+
}, "loadProducts");
|
|
2014
|
+
loadProducts();
|
|
2015
|
+
}, []);
|
|
2016
|
+
const { hasMonthly, hasYearly } = _react.useMemo.call(void 0, () => {
|
|
2017
|
+
let hasMonthly2 = false;
|
|
2018
|
+
let hasYearly2 = false;
|
|
2019
|
+
for (const product of products) {
|
|
2020
|
+
for (const price of product.stripePrices || []) {
|
|
2021
|
+
if (price.priceType === "recurring" && _optionalChain([price, 'access', _71 => _71.recurring, 'optionalAccess', _72 => _72.interval]) === "month") {
|
|
2022
|
+
hasMonthly2 = true;
|
|
2023
|
+
}
|
|
2024
|
+
if (price.priceType === "recurring" && _optionalChain([price, 'access', _73 => _73.recurring, 'optionalAccess', _74 => _74.interval]) === "year") {
|
|
2025
|
+
hasYearly2 = true;
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
2027
2028
|
}
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2029
|
+
return { hasMonthly: hasMonthly2, hasYearly: hasYearly2 };
|
|
2030
|
+
}, [products]);
|
|
2031
|
+
const handleSelectPrice = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (price) => {
|
|
2032
|
+
onSelectPrice(price);
|
|
2033
|
+
}, "handleSelectPrice");
|
|
2034
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
|
|
2035
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-center", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2036
|
+
IntervalToggle,
|
|
2037
|
+
{
|
|
2038
|
+
value: selectedInterval,
|
|
2039
|
+
onChange: onIntervalChange,
|
|
2040
|
+
hasMonthly,
|
|
2041
|
+
hasYearly
|
|
2042
|
+
}
|
|
2043
|
+
) }),
|
|
2044
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2045
|
+
ProductPricingList,
|
|
2046
|
+
{
|
|
2047
|
+
products,
|
|
2048
|
+
selectedInterval,
|
|
2049
|
+
currentPriceId,
|
|
2050
|
+
selectedPriceId: _optionalChain([selectedPrice, 'optionalAccess', _75 => _75.id]),
|
|
2051
|
+
loading,
|
|
2052
|
+
hideRecurringPrices,
|
|
2053
|
+
onSelectPrice: handleSelectPrice
|
|
2054
|
+
}
|
|
2055
|
+
),
|
|
2056
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "flex justify-end pt-4 border-t", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: onNext, disabled: !selectedPrice || isProcessing, children: isProcessing ? "Loading..." : "Next: Review" }) })
|
|
2057
|
+
] });
|
|
2058
|
+
}
|
|
2059
|
+
_chunk7QVYU63Ejs.__name.call(void 0, WizardStepPlanSelection, "WizardStepPlanSelection");
|
|
2060
|
+
|
|
2061
|
+
// src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx
|
|
2062
|
+
|
|
2063
|
+
|
|
2064
|
+
function WizardStepReview({
|
|
2065
|
+
selectedPrice,
|
|
2066
|
+
subscription,
|
|
2067
|
+
prorationPreview,
|
|
2068
|
+
hasPaymentMethod,
|
|
2069
|
+
error,
|
|
2070
|
+
isProcessing,
|
|
2071
|
+
onBack,
|
|
2072
|
+
onAddPaymentMethod,
|
|
2073
|
+
onConfirm
|
|
2074
|
+
}) {
|
|
2075
|
+
if (!selectedPrice) {
|
|
2076
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "text-center py-8 text-muted-foreground", children: "No plan selected. Please go back and select a plan." });
|
|
2034
2077
|
}
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium", children: "Processing payment..." }),
|
|
2049
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Please complete any verification if prompted." })
|
|
2050
|
-
] })
|
|
2051
|
-
] }),
|
|
2052
|
-
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: [
|
|
2053
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CheckCircle, { className: "h-12 w-12 text-green-500" }),
|
|
2054
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
|
|
2055
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium text-green-600", children: "Payment successful!" }),
|
|
2056
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Your subscription is now active." })
|
|
2057
|
-
] })
|
|
2058
|
-
] }),
|
|
2059
|
-
paymentConfirmationState === "error" && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.Alert, { variant: "destructive", children: [
|
|
2060
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunkIXI4GAKBjs.AlertTitle, { children: "Payment Failed" }),
|
|
2061
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunkIXI4GAKBjs.AlertDescription, { className: "mt-2", children: [
|
|
2062
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "mb-4", children: paymentError || "We couldn't process your payment. Please try again." }),
|
|
2063
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2064
|
-
_chunkIXI4GAKBjs.Button,
|
|
2065
|
-
{
|
|
2066
|
-
onClick: () => {
|
|
2067
|
-
setPaymentConfirmationState("idle");
|
|
2068
|
-
setPaymentError(null);
|
|
2069
|
-
},
|
|
2070
|
-
variant: "outline",
|
|
2071
|
-
children: "Try Again"
|
|
2072
|
-
}
|
|
2073
|
-
)
|
|
2074
|
-
] })
|
|
2075
|
-
] }),
|
|
2076
|
-
paymentConfirmationState === "idle" && !isConfirming && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2077
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
|
|
2078
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.CreditCard, { className: "text-muted-foreground mx-auto h-16 w-16 mb-4" }),
|
|
2079
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-2 text-xl font-semibold", children: "Choose Your Plan" }),
|
|
2080
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground mb-6", children: "Select a subscription plan to get started with our services." })
|
|
2078
|
+
const isChangingPlan = subscription && _optionalChain([subscription, 'access', _76 => _76.price, 'optionalAccess', _77 => _77.id]) !== selectedPrice.id;
|
|
2079
|
+
const formatInterval2 = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, (price) => {
|
|
2080
|
+
if (price.priceType === "one_time") return "one-time";
|
|
2081
|
+
const interval = _optionalChain([price, 'access', _78 => _78.recurring, 'optionalAccess', _79 => _79.interval]) || "month";
|
|
2082
|
+
return interval === "year" ? "yearly" : "monthly";
|
|
2083
|
+
}, "formatInterval");
|
|
2084
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
|
|
2085
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-muted/50 rounded-lg p-4 space-y-3", children: [
|
|
2086
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-lg", children: "Selected Plan" }),
|
|
2087
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between items-center", children: [
|
|
2088
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
2089
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-medium", children: _optionalChain([selectedPrice, 'access', _80 => _80.product, 'optionalAccess', _81 => _81.name]) }),
|
|
2090
|
+
selectedPrice.nickname && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: selectedPrice.nickname })
|
|
2081
2091
|
] }),
|
|
2082
|
-
/* @__PURE__ */ _jsxruntime.
|
|
2083
|
-
|
|
2084
|
-
{
|
|
2085
|
-
|
|
2086
|
-
pricesByProduct,
|
|
2087
|
-
loading: loadingPricing,
|
|
2088
|
-
loadingPriceId: creatingSubscription ? _nullishCoalesce(pendingPriceId, () => ( void 0)) : void 0,
|
|
2089
|
-
onSelectPrice: handleSelectPrice
|
|
2090
|
-
}
|
|
2091
|
-
)
|
|
2092
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-right", children: [
|
|
2093
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "font-semibold text-lg", children: formatCurrency(selectedPrice.unitAmount || 0, selectedPrice.currency) }),
|
|
2094
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: formatInterval2(selectedPrice) })
|
|
2095
|
+
] })
|
|
2092
2096
|
] })
|
|
2093
2097
|
] }),
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
{
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2098
|
+
isChangingPlan && prorationPreview && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4 space-y-2", children: [
|
|
2099
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "font-medium text-blue-800", children: "Proration Summary" }),
|
|
2100
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-blue-700", children: "Your next charge will be adjusted to account for the plan change." }),
|
|
2101
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between text-sm", children: [
|
|
2102
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-blue-600", children: "Amount due now:" }),
|
|
2103
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "font-medium text-blue-800", children: formatCurrency(prorationPreview.amountDue, prorationPreview.currency) })
|
|
2104
|
+
] })
|
|
2105
|
+
] }),
|
|
2106
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "border rounded-lg p-4", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between items-center", children: [
|
|
2107
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
2108
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "font-medium", children: "Payment Method" }),
|
|
2109
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: hasPaymentMethod ? "A payment method is on file" : "No payment method on file" })
|
|
2110
|
+
] }),
|
|
2111
|
+
!hasPaymentMethod && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", onClick: onAddPaymentMethod, children: "Add Payment Method" })
|
|
2112
|
+
] }) }),
|
|
2113
|
+
error && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Alert, { variant: "destructive", children: [
|
|
2114
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertCircle, { className: "h-4 w-4" }),
|
|
2115
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDescription, { children: error })
|
|
2116
|
+
] }),
|
|
2117
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex justify-between pt-4 border-t", children: [
|
|
2118
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", onClick: onBack, disabled: isProcessing, children: "Back" }),
|
|
2119
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2120
|
+
_chunk3X7EEFMNjs.Button,
|
|
2121
|
+
{
|
|
2122
|
+
onClick: hasPaymentMethod ? onConfirm : onAddPaymentMethod,
|
|
2123
|
+
disabled: isProcessing,
|
|
2124
|
+
children: isProcessing ? "Processing..." : hasPaymentMethod ? isChangingPlan ? "Confirm Plan Change" : "Subscribe Now" : "Add Payment Method"
|
|
2104
2125
|
}
|
|
2126
|
+
)
|
|
2127
|
+
] })
|
|
2128
|
+
] });
|
|
2129
|
+
}
|
|
2130
|
+
_chunk7QVYU63Ejs.__name.call(void 0, WizardStepReview, "WizardStepReview");
|
|
2131
|
+
|
|
2132
|
+
// src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx
|
|
2133
|
+
|
|
2134
|
+
function WizardStepPaymentMethod({
|
|
2135
|
+
onBack,
|
|
2136
|
+
onSuccess,
|
|
2137
|
+
isProcessing
|
|
2138
|
+
}) {
|
|
2139
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-6", children: [
|
|
2140
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
|
|
2141
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-lg", children: "Add Payment Method" }),
|
|
2142
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-muted-foreground", children: "Enter your card details to complete your subscription" })
|
|
2143
|
+
] }),
|
|
2144
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2145
|
+
PaymentMethodForm,
|
|
2146
|
+
{
|
|
2147
|
+
onSuccess,
|
|
2148
|
+
onCancel: onBack,
|
|
2149
|
+
isLoading: isProcessing
|
|
2150
|
+
}
|
|
2151
|
+
)
|
|
2152
|
+
] });
|
|
2153
|
+
}
|
|
2154
|
+
_chunk7QVYU63Ejs.__name.call(void 0, WizardStepPaymentMethod, "WizardStepPaymentMethod");
|
|
2155
|
+
|
|
2156
|
+
// src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx
|
|
2157
|
+
|
|
2158
|
+
function SubscriptionWizard({
|
|
2159
|
+
open,
|
|
2160
|
+
onOpenChange,
|
|
2161
|
+
onSuccess,
|
|
2162
|
+
hasActiveRecurringSubscription,
|
|
2163
|
+
subscription
|
|
2164
|
+
}) {
|
|
2165
|
+
const handleClose = _react.useCallback.call(void 0, () => onOpenChange(false), [onOpenChange]);
|
|
2166
|
+
const { state, actions } = useSubscriptionWizard({
|
|
2167
|
+
subscription,
|
|
2168
|
+
onSuccess,
|
|
2169
|
+
onClose: handleClose
|
|
2170
|
+
});
|
|
2171
|
+
const hasCheckedRef = _react.useRef.call(void 0, false);
|
|
2172
|
+
_react.useEffect.call(void 0, () => {
|
|
2173
|
+
if (open && !hasCheckedRef.current) {
|
|
2174
|
+
hasCheckedRef.current = true;
|
|
2175
|
+
actions.checkPaymentMethod();
|
|
2176
|
+
}
|
|
2177
|
+
if (!open) {
|
|
2178
|
+
hasCheckedRef.current = false;
|
|
2179
|
+
}
|
|
2180
|
+
}, [open, actions.checkPaymentMethod]);
|
|
2181
|
+
_react.useEffect.call(void 0, () => {
|
|
2182
|
+
if (!open) {
|
|
2183
|
+
actions.reset();
|
|
2184
|
+
}
|
|
2185
|
+
}, [open, actions.reset]);
|
|
2186
|
+
const dialogTitle = subscription ? "Change Subscription Plan" : "Subscribe to a Plan";
|
|
2187
|
+
const dialogDescription = subscription ? "Select a new plan for your subscription" : "Choose a subscription plan to get started";
|
|
2188
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogContent, { className: "max-w-2xl", children: [
|
|
2189
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogHeader, { children: [
|
|
2190
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogTitle, { children: dialogTitle }),
|
|
2191
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogDescription, { children: dialogDescription })
|
|
2192
|
+
] }),
|
|
2193
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, WizardProgressIndicator, { currentStep: state.step }),
|
|
2194
|
+
state.step === "plan-selection" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2195
|
+
WizardStepPlanSelection,
|
|
2196
|
+
{
|
|
2197
|
+
selectedPrice: state.selectedPrice,
|
|
2198
|
+
selectedInterval: state.selectedInterval,
|
|
2199
|
+
currentPriceId: _optionalChain([subscription, 'optionalAccess', _82 => _82.price, 'optionalAccess', _83 => _83.id]),
|
|
2200
|
+
hideRecurringPrices: hasActiveRecurringSubscription && !subscription,
|
|
2201
|
+
onSelectPrice: actions.selectPrice,
|
|
2202
|
+
onIntervalChange: actions.setInterval,
|
|
2203
|
+
onNext: actions.goToReview,
|
|
2204
|
+
isProcessing: state.isProcessing
|
|
2105
2205
|
}
|
|
2106
2206
|
),
|
|
2107
|
-
|
|
2108
|
-
|
|
2207
|
+
state.step === "review" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2208
|
+
WizardStepReview,
|
|
2109
2209
|
{
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2210
|
+
selectedPrice: state.selectedPrice,
|
|
2211
|
+
subscription,
|
|
2212
|
+
prorationPreview: state.prorationPreview,
|
|
2213
|
+
hasPaymentMethod: state.hasPaymentMethod,
|
|
2214
|
+
error: state.error,
|
|
2215
|
+
isProcessing: state.isProcessing,
|
|
2216
|
+
onBack: () => actions.goToStep("plan-selection"),
|
|
2217
|
+
onAddPaymentMethod: () => actions.goToStep("payment-method"),
|
|
2218
|
+
onConfirm: actions.confirmSubscription
|
|
2219
|
+
}
|
|
2220
|
+
),
|
|
2221
|
+
state.step === "payment-method" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2222
|
+
WizardStepPaymentMethod,
|
|
2223
|
+
{
|
|
2224
|
+
onBack: () => actions.goToStep("review"),
|
|
2225
|
+
onSuccess: actions.handlePaymentMethodSuccess,
|
|
2226
|
+
isProcessing: state.isProcessing
|
|
2118
2227
|
}
|
|
2119
2228
|
)
|
|
2120
|
-
] });
|
|
2229
|
+
] }) });
|
|
2121
2230
|
}
|
|
2122
|
-
_chunk7QVYU63Ejs.__name.call(void 0,
|
|
2231
|
+
_chunk7QVYU63Ejs.__name.call(void 0, SubscriptionWizard, "SubscriptionWizard");
|
|
2123
2232
|
|
|
2124
2233
|
// src/features/billing/stripe-usage/components/containers/UsageContainer.tsx
|
|
2125
2234
|
|
|
@@ -2148,22 +2257,22 @@ function formatDate4(date) {
|
|
|
2148
2257
|
}
|
|
2149
2258
|
_chunk7QVYU63Ejs.__name.call(void 0, formatDate4, "formatDate");
|
|
2150
2259
|
function UsageSummaryCard({ meter, summary }) {
|
|
2151
|
-
const currentUsage = _nullishCoalesce(_optionalChain([summary, 'optionalAccess',
|
|
2260
|
+
const currentUsage = _nullishCoalesce(_optionalChain([summary, 'optionalAccess', _84 => _84.aggregatedValue]), () => ( 0));
|
|
2152
2261
|
const limit = meter.limit;
|
|
2153
2262
|
const percentage = limit && limit > 0 ? currentUsage / limit * 100 : null;
|
|
2154
2263
|
const progressColor = getProgressColor(percentage);
|
|
2155
2264
|
const progressWidth = percentage !== null ? Math.min(percentage, 100) : 0;
|
|
2156
2265
|
const displayName = meter.displayName || meter.eventName;
|
|
2157
2266
|
const hasLimit = limit !== null && limit !== void 0;
|
|
2158
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2159
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2267
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
2268
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "flex flex-row items-center gap-x-3 pb-3", children: [
|
|
2160
2269
|
/* @__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" }) }),
|
|
2161
2270
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col", children: [
|
|
2162
2271
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold", children: displayName }),
|
|
2163
2272
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-xs text-gray-500", children: meter.id })
|
|
2164
2273
|
] })
|
|
2165
2274
|
] }),
|
|
2166
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2275
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardContent, { className: "flex flex-col gap-y-4", children: [
|
|
2167
2276
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
2168
2277
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-3xl font-bold", children: currentUsage.toLocaleString() }),
|
|
2169
2278
|
hasLimit && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-gray-500", children: [
|
|
@@ -2175,7 +2284,7 @@ function UsageSummaryCard({ meter, summary }) {
|
|
|
2175
2284
|
hasLimit ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-y-2", children: [
|
|
2176
2285
|
/* @__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}%` } }) }),
|
|
2177
2286
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "text-sm text-gray-500", children: [
|
|
2178
|
-
_optionalChain([percentage, 'optionalAccess',
|
|
2287
|
+
_optionalChain([percentage, 'optionalAccess', _85 => _85.toFixed, 'call', _86 => _86(1)]),
|
|
2179
2288
|
"% used"
|
|
2180
2289
|
] })
|
|
2181
2290
|
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm text-gray-500", children: "No limit set" }),
|
|
@@ -2210,14 +2319,14 @@ function UsageContainer() {
|
|
|
2210
2319
|
const loadUsageData = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2211
2320
|
setLoading(true);
|
|
2212
2321
|
try {
|
|
2213
|
-
const fetchedSubscriptions = await
|
|
2322
|
+
const fetchedSubscriptions = await _chunkJ22NEVSKjs.StripeSubscriptionService.listSubscriptions();
|
|
2214
2323
|
setSubscriptions(fetchedSubscriptions);
|
|
2215
|
-
const hasMeteredSubscriptions2 = fetchedSubscriptions.some((sub) => _optionalChain([sub, 'access',
|
|
2324
|
+
const hasMeteredSubscriptions2 = fetchedSubscriptions.some((sub) => _optionalChain([sub, 'access', _87 => _87.price, 'optionalAccess', _88 => _88.recurring, 'optionalAccess', _89 => _89.usageType]) === "metered");
|
|
2216
2325
|
if (!hasMeteredSubscriptions2) {
|
|
2217
2326
|
setLoading(false);
|
|
2218
2327
|
return;
|
|
2219
2328
|
}
|
|
2220
|
-
const fetchedMeters = await
|
|
2329
|
+
const fetchedMeters = await _chunkJ22NEVSKjs.StripeUsageService.listMeters();
|
|
2221
2330
|
setMeters(fetchedMeters);
|
|
2222
2331
|
const summariesMap = {};
|
|
2223
2332
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -2225,7 +2334,7 @@ function UsageContainer() {
|
|
|
2225
2334
|
const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
|
|
2226
2335
|
for (const meter of fetchedMeters) {
|
|
2227
2336
|
try {
|
|
2228
|
-
const meterSummaries = await
|
|
2337
|
+
const meterSummaries = await _chunkJ22NEVSKjs.StripeUsageService.getMeterSummaries({
|
|
2229
2338
|
meterId: meter.id,
|
|
2230
2339
|
startTime: startOfMonth,
|
|
2231
2340
|
endTime: endOfMonth
|
|
@@ -2243,7 +2352,7 @@ function UsageContainer() {
|
|
|
2243
2352
|
setLoading(false);
|
|
2244
2353
|
}
|
|
2245
2354
|
}, "loadUsageData");
|
|
2246
|
-
const hasMeteredSubscriptions = subscriptions.some((sub) => _optionalChain([sub, 'access',
|
|
2355
|
+
const hasMeteredSubscriptions = subscriptions.some((sub) => _optionalChain([sub, 'access', _90 => _90.price, 'optionalAccess', _91 => _91.recurring, 'optionalAccess', _92 => _92.usageType]) === "metered");
|
|
2247
2356
|
if (!loading && !hasMeteredSubscriptions) {
|
|
2248
2357
|
return null;
|
|
2249
2358
|
}
|
|
@@ -2291,21 +2400,21 @@ function UsageHistoryTable({ usageRecords }) {
|
|
|
2291
2400
|
}
|
|
2292
2401
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex w-full flex-col gap-y-4", children: [
|
|
2293
2402
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "text-xl font-semibold", children: "Usage History" }),
|
|
2294
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "overflow-hidden rounded-lg border", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2295
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2296
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2297
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2298
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2299
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2403
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "overflow-hidden rounded-lg border", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Table, { children: [
|
|
2404
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHeader, { className: "bg-muted", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.TableRow, { children: [
|
|
2405
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Date & Time" }),
|
|
2406
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Meter Event" }),
|
|
2407
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { className: "text-right", children: "Quantity" }),
|
|
2408
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableHead, { children: "Event ID" })
|
|
2300
2409
|
] }) }),
|
|
2301
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2410
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableBody, { children: usageRecords.map((record) => {
|
|
2302
2411
|
const dateTime = formatDateTime(record.timestamp);
|
|
2303
2412
|
const quantity = record.quantity.toLocaleString();
|
|
2304
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2305
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2306
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2307
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2308
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2413
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.TableRow, { children: [
|
|
2414
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "font-medium", children: dateTime }),
|
|
2415
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "text-muted-foreground", children: record.meterEventName }),
|
|
2416
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "text-right font-medium", children: quantity }),
|
|
2417
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.TableCell, { className: "text-muted-foreground text-sm font-mono", children: record.stripeEventId })
|
|
2309
2418
|
] }, record.id);
|
|
2310
2419
|
}) })
|
|
2311
2420
|
] }) })
|
|
@@ -2322,8 +2431,8 @@ function BillingDetailModal({
|
|
|
2322
2431
|
children,
|
|
2323
2432
|
className
|
|
2324
2433
|
}) {
|
|
2325
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2326
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2434
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogContent, { className: _nullishCoalesce(className, () => ( "max-w-4xl max-h-[90vh] overflow-y-auto")), children: [
|
|
2435
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogHeader, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogTitle, { children: title }) }),
|
|
2327
2436
|
children
|
|
2328
2437
|
] }) });
|
|
2329
2438
|
}
|
|
@@ -2340,7 +2449,7 @@ function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }) {
|
|
|
2340
2449
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "font-semibold text-red-900", children: "Payment Failed" }),
|
|
2341
2450
|
/* @__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." })
|
|
2342
2451
|
] }),
|
|
2343
|
-
onUpdatePayment && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2452
|
+
onUpdatePayment && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", size: "sm", onClick: onUpdatePayment, className: "border-red-300 text-red-700", children: "Update Payment Method" })
|
|
2344
2453
|
] });
|
|
2345
2454
|
}
|
|
2346
2455
|
if (subscription.status === "trialing" /* TRIALING */ && subscription.trialEnd) {
|
|
@@ -2360,7 +2469,7 @@ function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }) {
|
|
|
2360
2469
|
". Add a payment method to continue your subscription."
|
|
2361
2470
|
] })
|
|
2362
2471
|
] }),
|
|
2363
|
-
onAddPayment && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2472
|
+
onAddPayment && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", size: "sm", onClick: onAddPayment, className: "border-yellow-300 text-yellow-700", children: "Add Payment Method" })
|
|
2364
2473
|
] });
|
|
2365
2474
|
}
|
|
2366
2475
|
}
|
|
@@ -2396,14 +2505,22 @@ function BillingDashboardContainer() {
|
|
|
2396
2505
|
const [activeModal, setActiveModal] = _react.useState.call(void 0, null);
|
|
2397
2506
|
const [noCustomerExists, setNoCustomerExists] = _react.useState.call(void 0, false);
|
|
2398
2507
|
const [creatingCustomer, setCreatingCustomer] = _react.useState.call(void 0, false);
|
|
2508
|
+
const searchParams = _navigation.useSearchParams.call(void 0, );
|
|
2509
|
+
const [showWizard, setShowWizard] = _react.useState.call(void 0, false);
|
|
2510
|
+
const [editingSubscription, setEditingSubscription] = _react.useState.call(void 0, null);
|
|
2399
2511
|
const hasMeteredSubscriptions = _react.useCallback.call(void 0, () => {
|
|
2400
|
-
return data.subscriptions.some((sub) => _optionalChain([sub, 'access',
|
|
2512
|
+
return data.subscriptions.some((sub) => _optionalChain([sub, 'access', _93 => _93.price, 'optionalAccess', _94 => _94.recurring, 'optionalAccess', _95 => _95.usageType]) === "metered");
|
|
2513
|
+
}, [data.subscriptions]);
|
|
2514
|
+
const hasActiveRecurringSubscription = _react.useMemo.call(void 0, () => {
|
|
2515
|
+
return data.subscriptions.some(
|
|
2516
|
+
(sub) => (sub.status === "active" /* ACTIVE */ || sub.status === "trialing" /* TRIALING */) && _optionalChain([sub, 'access', _96 => _96.price, 'optionalAccess', _97 => _97.priceType]) === "recurring"
|
|
2517
|
+
);
|
|
2401
2518
|
}, [data.subscriptions]);
|
|
2402
2519
|
const fetchAllData = _react.useCallback.call(void 0, async () => {
|
|
2403
2520
|
setNoCustomerExists(false);
|
|
2404
2521
|
let customer = null;
|
|
2405
2522
|
try {
|
|
2406
|
-
customer = await
|
|
2523
|
+
customer = await _chunkJ22NEVSKjs.StripeCustomerService.getCustomer();
|
|
2407
2524
|
setData((prev) => ({ ...prev, customer }));
|
|
2408
2525
|
setErrors((prev) => ({ ...prev, customer: null }));
|
|
2409
2526
|
setNoCustomerExists(false);
|
|
@@ -2428,7 +2545,7 @@ function BillingDashboardContainer() {
|
|
|
2428
2545
|
if (customer) {
|
|
2429
2546
|
const fetchSubscriptions = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2430
2547
|
try {
|
|
2431
|
-
const subscriptions2 = await
|
|
2548
|
+
const subscriptions2 = await _chunkJ22NEVSKjs.StripeSubscriptionService.listSubscriptions();
|
|
2432
2549
|
setData((prev) => ({ ...prev, subscriptions: subscriptions2 }));
|
|
2433
2550
|
setErrors((prev) => ({ ...prev, subscriptions: null }));
|
|
2434
2551
|
return subscriptions2;
|
|
@@ -2442,7 +2559,7 @@ function BillingDashboardContainer() {
|
|
|
2442
2559
|
}, "fetchSubscriptions");
|
|
2443
2560
|
const fetchPaymentMethods = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2444
2561
|
try {
|
|
2445
|
-
const paymentMethods = await
|
|
2562
|
+
const paymentMethods = await _chunkJ22NEVSKjs.StripeCustomerService.listPaymentMethods();
|
|
2446
2563
|
setData((prev) => ({ ...prev, paymentMethods }));
|
|
2447
2564
|
setErrors((prev) => ({ ...prev, paymentMethods: null }));
|
|
2448
2565
|
} catch (error) {
|
|
@@ -2454,7 +2571,7 @@ function BillingDashboardContainer() {
|
|
|
2454
2571
|
}, "fetchPaymentMethods");
|
|
2455
2572
|
const fetchInvoices = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2456
2573
|
try {
|
|
2457
|
-
const invoices = await
|
|
2574
|
+
const invoices = await _chunkJ22NEVSKjs.StripeInvoiceService.listInvoices();
|
|
2458
2575
|
setData((prev) => ({ ...prev, invoices }));
|
|
2459
2576
|
setErrors((prev) => ({ ...prev, invoices: null }));
|
|
2460
2577
|
} catch (error) {
|
|
@@ -2466,7 +2583,7 @@ function BillingDashboardContainer() {
|
|
|
2466
2583
|
}, "fetchInvoices");
|
|
2467
2584
|
const [subscriptions] = await Promise.all([fetchSubscriptions(), fetchPaymentMethods(), fetchInvoices()]);
|
|
2468
2585
|
const hasMetered = subscriptions.some(
|
|
2469
|
-
(sub) => _optionalChain([sub, 'access',
|
|
2586
|
+
(sub) => _optionalChain([sub, 'access', _98 => _98.price, 'optionalAccess', _99 => _99.recurring, 'optionalAccess', _100 => _100.usageType]) === "metered"
|
|
2470
2587
|
);
|
|
2471
2588
|
if (hasMetered) {
|
|
2472
2589
|
await fetchUsageData();
|
|
@@ -2478,7 +2595,7 @@ function BillingDashboardContainer() {
|
|
|
2478
2595
|
const handleCreateCustomer = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2479
2596
|
setCreatingCustomer(true);
|
|
2480
2597
|
try {
|
|
2481
|
-
await
|
|
2598
|
+
await _chunkJ22NEVSKjs.StripeCustomerService.createCustomer();
|
|
2482
2599
|
setNoCustomerExists(false);
|
|
2483
2600
|
await fetchAllData();
|
|
2484
2601
|
} catch (error) {
|
|
@@ -2490,7 +2607,7 @@ function BillingDashboardContainer() {
|
|
|
2490
2607
|
}, "handleCreateCustomer");
|
|
2491
2608
|
const fetchUsageData = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2492
2609
|
try {
|
|
2493
|
-
const meters = await
|
|
2610
|
+
const meters = await _chunkJ22NEVSKjs.StripeUsageService.listMeters();
|
|
2494
2611
|
setData((prev) => ({ ...prev, meters }));
|
|
2495
2612
|
const summariesMap = {};
|
|
2496
2613
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -2498,7 +2615,7 @@ function BillingDashboardContainer() {
|
|
|
2498
2615
|
const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
|
|
2499
2616
|
for (const meter of meters) {
|
|
2500
2617
|
try {
|
|
2501
|
-
const meterSummaries = await
|
|
2618
|
+
const meterSummaries = await _chunkJ22NEVSKjs.StripeUsageService.getMeterSummaries({
|
|
2502
2619
|
meterId: meter.id,
|
|
2503
2620
|
startTime: startOfMonth,
|
|
2504
2621
|
endTime: endOfMonth
|
|
@@ -2528,9 +2645,25 @@ function BillingDashboardContainer() {
|
|
|
2528
2645
|
});
|
|
2529
2646
|
await fetchAllData();
|
|
2530
2647
|
}, [fetchAllData]);
|
|
2648
|
+
const handleOpenWizard = _react.useCallback.call(void 0, (subscription) => {
|
|
2649
|
+
setEditingSubscription(subscription || null);
|
|
2650
|
+
setShowWizard(true);
|
|
2651
|
+
}, []);
|
|
2652
|
+
const handleWizardClose = _react.useCallback.call(void 0, () => {
|
|
2653
|
+
setShowWizard(false);
|
|
2654
|
+
setEditingSubscription(null);
|
|
2655
|
+
refreshData();
|
|
2656
|
+
}, [refreshData]);
|
|
2531
2657
|
_react.useEffect.call(void 0, () => {
|
|
2532
2658
|
fetchAllData();
|
|
2533
2659
|
}, [fetchAllData]);
|
|
2660
|
+
_react.useEffect.call(void 0, () => {
|
|
2661
|
+
const action = searchParams.get("action");
|
|
2662
|
+
if (action === "subscribe") {
|
|
2663
|
+
setShowWizard(true);
|
|
2664
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
2665
|
+
}
|
|
2666
|
+
}, [searchParams]);
|
|
2534
2667
|
const criticalSubscriptions = data.subscriptions.filter(
|
|
2535
2668
|
(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
|
|
2536
2669
|
);
|
|
@@ -2560,18 +2693,18 @@ function BillingDashboardContainer() {
|
|
|
2560
2693
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Wallet, { className: "h-8 w-8" }),
|
|
2561
2694
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Billing" })
|
|
2562
2695
|
] }),
|
|
2563
|
-
isInitialLoading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2564
|
-
noCustomerExists && !isInitialLoading && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2565
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2696
|
+
isInitialLoading && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Card, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.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" }) }) }),
|
|
2697
|
+
noCustomerExists && !isInitialLoading && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Card, { children: [
|
|
2698
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.CardHeader, { className: "text-center", children: [
|
|
2566
2699
|
/* @__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" }) }),
|
|
2567
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2568
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2700
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardTitle, { children: "Set Up Billing" }),
|
|
2701
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardDescription, { children: "Your company doesn't have a billing account yet. Set one up to manage subscriptions, payment methods, and view invoices." })
|
|
2569
2702
|
] }),
|
|
2570
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2703
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { className: "flex justify-center pb-8", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: handleCreateCustomer, disabled: creatingCustomer, size: "lg", children: creatingCustomer ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2571
2704
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Loader2, { className: "mr-2 h-4 w-4 animate-spin" }),
|
|
2572
2705
|
"Setting up..."
|
|
2573
2706
|
] }) : "Set Up Billing Account" }) }),
|
|
2574
|
-
errors.customer && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2707
|
+
errors.customer && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CardContent, { className: "pt-0", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-center text-sm text-destructive", children: errors.customer }) })
|
|
2575
2708
|
] }),
|
|
2576
2709
|
!noCustomerExists && !isInitialLoading && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
2577
2710
|
criticalSubscriptions.map((subscription) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -2590,14 +2723,20 @@ function BillingDashboardContainer() {
|
|
|
2590
2723
|
subscriptions: data.subscriptions,
|
|
2591
2724
|
loading: loading.subscriptions,
|
|
2592
2725
|
error: errors.subscriptions || void 0,
|
|
2593
|
-
onManageClick: () =>
|
|
2726
|
+
onManageClick: () => {
|
|
2727
|
+
if (data.subscriptions.length === 0) {
|
|
2728
|
+
setShowWizard(true);
|
|
2729
|
+
} else {
|
|
2730
|
+
setActiveModal("subscriptions");
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2594
2733
|
}
|
|
2595
2734
|
),
|
|
2596
2735
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2597
2736
|
PaymentMethodSummaryCard,
|
|
2598
2737
|
{
|
|
2599
2738
|
paymentMethods: data.paymentMethods,
|
|
2600
|
-
defaultPaymentMethodId: _optionalChain([data, 'access',
|
|
2739
|
+
defaultPaymentMethodId: _optionalChain([data, 'access', _101 => _101.customer, 'optionalAccess', _102 => _102.defaultPaymentMethodId]),
|
|
2601
2740
|
loading: loading.paymentMethods,
|
|
2602
2741
|
error: errors.paymentMethods || void 0,
|
|
2603
2742
|
onManageClick: () => setActiveModal("payment-methods")
|
|
@@ -2637,7 +2776,7 @@ function BillingDashboardContainer() {
|
|
|
2637
2776
|
open: activeModal === "subscriptions",
|
|
2638
2777
|
onOpenChange: handleModalClose,
|
|
2639
2778
|
title: getModalTitle("subscriptions"),
|
|
2640
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SubscriptionsContainer, {})
|
|
2779
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, SubscriptionsContainer, { onOpenWizard: handleOpenWizard })
|
|
2641
2780
|
}
|
|
2642
2781
|
),
|
|
2643
2782
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
@@ -2666,6 +2805,16 @@ function BillingDashboardContainer() {
|
|
|
2666
2805
|
title: getModalTitle("usage"),
|
|
2667
2806
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UsageContainer, {})
|
|
2668
2807
|
}
|
|
2808
|
+
),
|
|
2809
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2810
|
+
SubscriptionWizard,
|
|
2811
|
+
{
|
|
2812
|
+
open: showWizard,
|
|
2813
|
+
onOpenChange: (open) => !open && handleWizardClose(),
|
|
2814
|
+
onSuccess: refreshData,
|
|
2815
|
+
hasActiveRecurringSubscription,
|
|
2816
|
+
subscription: _nullishCoalesce(editingSubscription, () => ( void 0))
|
|
2817
|
+
}
|
|
2669
2818
|
)
|
|
2670
2819
|
] })
|
|
2671
2820
|
] });
|
|
@@ -2682,7 +2831,7 @@ function getStripePromise(publishableKey) {
|
|
|
2682
2831
|
if (!publishableKey) {
|
|
2683
2832
|
return Promise.resolve(null);
|
|
2684
2833
|
}
|
|
2685
|
-
if (_optionalChain([stripePromiseCache, 'optionalAccess',
|
|
2834
|
+
if (_optionalChain([stripePromiseCache, 'optionalAccess', _103 => _103.key]) === publishableKey) {
|
|
2686
2835
|
return stripePromiseCache.promise;
|
|
2687
2836
|
}
|
|
2688
2837
|
const promise = _stripejs.loadStripe.call(void 0, publishableKey);
|
|
@@ -2710,7 +2859,7 @@ _chunk7QVYU63Ejs.__name.call(void 0, isStripeConfigured, "isStripeConfigured");
|
|
|
2710
2859
|
|
|
2711
2860
|
|
|
2712
2861
|
|
|
2713
|
-
|
|
2862
|
+
var _uuid = require('uuid');
|
|
2714
2863
|
|
|
2715
2864
|
|
|
2716
2865
|
function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
@@ -2734,22 +2883,38 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2734
2883
|
token: _zod3.z.string()
|
|
2735
2884
|
});
|
|
2736
2885
|
const isEditMode = !!price;
|
|
2737
|
-
const defaultUnitAmount = _optionalChain([price, 'optionalAccess',
|
|
2886
|
+
const defaultUnitAmount = _optionalChain([price, 'optionalAccess', _104 => _104.unitAmount]) ? price.unitAmount / 100 : 0;
|
|
2738
2887
|
const form = _reacthookform.useForm.call(void 0, {
|
|
2739
2888
|
resolver: _zod.zodResolver.call(void 0, formSchema2),
|
|
2740
2889
|
defaultValues: {
|
|
2741
2890
|
unitAmount: defaultUnitAmount,
|
|
2742
|
-
currency: _optionalChain([price, 'optionalAccess',
|
|
2743
|
-
interval: _optionalChain([price, 'optionalAccess',
|
|
2744
|
-
intervalCount: _optionalChain([price, 'optionalAccess',
|
|
2745
|
-
usageType: _optionalChain([price, 'optionalAccess',
|
|
2746
|
-
nickname: _optionalChain([price, 'optionalAccess',
|
|
2747
|
-
active: _nullishCoalesce(_optionalChain([price, 'optionalAccess',
|
|
2748
|
-
description: _optionalChain([price, 'optionalAccess',
|
|
2749
|
-
features: _optionalChain([price, 'optionalAccess',
|
|
2750
|
-
token: _nullishCoalesce(_optionalChain([price, 'optionalAccess',
|
|
2891
|
+
currency: _optionalChain([price, 'optionalAccess', _105 => _105.currency]) || "usd",
|
|
2892
|
+
interval: _optionalChain([price, 'optionalAccess', _106 => _106.priceType]) === "one_time" ? "one_time" : _optionalChain([price, 'optionalAccess', _107 => _107.recurring, 'optionalAccess', _108 => _108.interval]) || "month",
|
|
2893
|
+
intervalCount: _optionalChain([price, 'optionalAccess', _109 => _109.recurring, 'optionalAccess', _110 => _110.intervalCount]) || 1,
|
|
2894
|
+
usageType: _optionalChain([price, 'optionalAccess', _111 => _111.recurring, 'optionalAccess', _112 => _112.usageType]) || "licensed",
|
|
2895
|
+
nickname: _optionalChain([price, 'optionalAccess', _113 => _113.nickname]) || "",
|
|
2896
|
+
active: _nullishCoalesce(_optionalChain([price, 'optionalAccess', _114 => _114.active]), () => ( true)),
|
|
2897
|
+
description: _optionalChain([price, 'optionalAccess', _115 => _115.description]) || "",
|
|
2898
|
+
features: _optionalChain([price, 'optionalAccess', _116 => _116.features]) || [],
|
|
2899
|
+
token: _nullishCoalesce(_optionalChain([price, 'optionalAccess', _117 => _117.token, 'optionalAccess', _118 => _118.toString, 'call', _119 => _119()]), () => ( ""))
|
|
2751
2900
|
}
|
|
2752
2901
|
});
|
|
2902
|
+
_react.useEffect.call(void 0, () => {
|
|
2903
|
+
if (open) {
|
|
2904
|
+
form.reset({
|
|
2905
|
+
unitAmount: _optionalChain([price, 'optionalAccess', _120 => _120.unitAmount]) ? price.unitAmount / 100 : 0,
|
|
2906
|
+
currency: _optionalChain([price, 'optionalAccess', _121 => _121.currency]) || "usd",
|
|
2907
|
+
interval: _optionalChain([price, 'optionalAccess', _122 => _122.priceType]) === "one_time" ? "one_time" : _optionalChain([price, 'optionalAccess', _123 => _123.recurring, 'optionalAccess', _124 => _124.interval]) || "month",
|
|
2908
|
+
intervalCount: _optionalChain([price, 'optionalAccess', _125 => _125.recurring, 'optionalAccess', _126 => _126.intervalCount]) || 1,
|
|
2909
|
+
usageType: _optionalChain([price, 'optionalAccess', _127 => _127.recurring, 'optionalAccess', _128 => _128.usageType]) || "licensed",
|
|
2910
|
+
nickname: _optionalChain([price, 'optionalAccess', _129 => _129.nickname]) || "",
|
|
2911
|
+
active: _nullishCoalesce(_optionalChain([price, 'optionalAccess', _130 => _130.active]), () => ( true)),
|
|
2912
|
+
description: _optionalChain([price, 'optionalAccess', _131 => _131.description]) || "",
|
|
2913
|
+
features: _optionalChain([price, 'optionalAccess', _132 => _132.features]) || [],
|
|
2914
|
+
token: _nullishCoalesce(_optionalChain([price, 'optionalAccess', _133 => _133.token, 'optionalAccess', _134 => _134.toString, 'call', _135 => _135()]), () => ( ""))
|
|
2915
|
+
});
|
|
2916
|
+
}
|
|
2917
|
+
}, [open, _optionalChain([price, 'optionalAccess', _136 => _136.id])]);
|
|
2753
2918
|
const watchInterval = form.watch("interval");
|
|
2754
2919
|
const isRecurring = watchInterval !== "one_time";
|
|
2755
2920
|
const onSubmit = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (values) => {
|
|
@@ -2757,7 +2922,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2757
2922
|
try {
|
|
2758
2923
|
const unitAmountInCents = Math.round(values.unitAmount * 100);
|
|
2759
2924
|
if (isEditMode) {
|
|
2760
|
-
await
|
|
2925
|
+
await _chunkJ22NEVSKjs.StripePriceService.updatePrice({
|
|
2761
2926
|
id: price.id,
|
|
2762
2927
|
nickname: values.nickname || void 0,
|
|
2763
2928
|
description: values.description || void 0,
|
|
@@ -2791,7 +2956,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2791
2956
|
if (values.token) {
|
|
2792
2957
|
createInput.token = parseInt(values.token, 10);
|
|
2793
2958
|
}
|
|
2794
|
-
await
|
|
2959
|
+
await _chunkJ22NEVSKjs.StripePriceService.createPrice(createInput);
|
|
2795
2960
|
}
|
|
2796
2961
|
onSuccess();
|
|
2797
2962
|
onOpenChange(false);
|
|
@@ -2817,10 +2982,10 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2817
2982
|
{ id: "licensed", text: "Licensed (per unit)" },
|
|
2818
2983
|
{ id: "metered", text: "Metered (usage-based)" }
|
|
2819
2984
|
];
|
|
2820
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2821
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2822
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2823
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2985
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogContent, { className: "max-w-2xl", children: [
|
|
2986
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogHeader, { children: [
|
|
2987
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogTitle, { children: isEditMode ? "Edit Price" : "Create Price" }),
|
|
2988
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogDescription, { children: isEditMode ? "Update the price details. Note: Only nickname and active status can be changed." : "Create a new price for this product" })
|
|
2824
2989
|
] }),
|
|
2825
2990
|
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: [
|
|
2826
2991
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.AlertCircle, { className: "h-5 w-5 text-blue-600 flex-shrink-0 mt-0.5" }),
|
|
@@ -2829,10 +2994,10 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2829
2994
|
/* @__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." })
|
|
2830
2995
|
] })
|
|
2831
2996
|
] }),
|
|
2832
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2997
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Form, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
|
|
2833
2998
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-x-4", children: [
|
|
2834
2999
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2835
|
-
|
|
3000
|
+
_chunk3X7EEFMNjs.FormInput,
|
|
2836
3001
|
{
|
|
2837
3002
|
form,
|
|
2838
3003
|
id: "unitAmount",
|
|
@@ -2842,10 +3007,10 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2842
3007
|
isRequired: true
|
|
2843
3008
|
}
|
|
2844
3009
|
),
|
|
2845
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3010
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.FormSelect, { form, id: "currency", name: "Currency", values: currencyOptions, disabled: isEditMode })
|
|
2846
3011
|
] }),
|
|
2847
3012
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2848
|
-
|
|
3013
|
+
_chunk3X7EEFMNjs.FormSelect,
|
|
2849
3014
|
{
|
|
2850
3015
|
form,
|
|
2851
3016
|
id: "interval",
|
|
@@ -2856,7 +3021,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2856
3021
|
),
|
|
2857
3022
|
isRecurring && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "grid grid-cols-2 gap-x-4", children: [
|
|
2858
3023
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2859
|
-
|
|
3024
|
+
_chunk3X7EEFMNjs.FormInput,
|
|
2860
3025
|
{
|
|
2861
3026
|
form,
|
|
2862
3027
|
id: "intervalCount",
|
|
@@ -2867,7 +3032,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2867
3032
|
}
|
|
2868
3033
|
),
|
|
2869
3034
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2870
|
-
|
|
3035
|
+
_chunk3X7EEFMNjs.FormSelect,
|
|
2871
3036
|
{
|
|
2872
3037
|
form,
|
|
2873
3038
|
id: "usageType",
|
|
@@ -2878,7 +3043,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2878
3043
|
)
|
|
2879
3044
|
] }),
|
|
2880
3045
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2881
|
-
|
|
3046
|
+
_chunk3X7EEFMNjs.FormInput,
|
|
2882
3047
|
{
|
|
2883
3048
|
form,
|
|
2884
3049
|
id: "nickname",
|
|
@@ -2887,7 +3052,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2887
3052
|
}
|
|
2888
3053
|
),
|
|
2889
3054
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2890
|
-
|
|
3055
|
+
_chunk3X7EEFMNjs.FormTextarea,
|
|
2891
3056
|
{
|
|
2892
3057
|
form,
|
|
2893
3058
|
id: "description",
|
|
@@ -2896,13 +3061,13 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2896
3061
|
className: "min-h-24"
|
|
2897
3062
|
}
|
|
2898
3063
|
),
|
|
2899
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3064
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.FormInput, { form, id: "token", name: "Token (optional)", placeholder: "Enter token value" }),
|
|
2900
3065
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
2901
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3066
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Label, { children: "Features (optional)" }),
|
|
2902
3067
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "space-y-2", children: [
|
|
2903
3068
|
form.watch("features").map((_, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-2", children: [
|
|
2904
3069
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2905
|
-
|
|
3070
|
+
_chunk3X7EEFMNjs.Input,
|
|
2906
3071
|
{
|
|
2907
3072
|
...form.register(`features.${index}`),
|
|
2908
3073
|
placeholder: `Feature ${index + 1}`,
|
|
@@ -2910,7 +3075,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2910
3075
|
}
|
|
2911
3076
|
),
|
|
2912
3077
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2913
|
-
|
|
3078
|
+
_chunk3X7EEFMNjs.Button,
|
|
2914
3079
|
{
|
|
2915
3080
|
type: "button",
|
|
2916
3081
|
variant: "outline",
|
|
@@ -2927,7 +3092,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2927
3092
|
)
|
|
2928
3093
|
] }, index)),
|
|
2929
3094
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2930
|
-
|
|
3095
|
+
_chunk3X7EEFMNjs.Button,
|
|
2931
3096
|
{
|
|
2932
3097
|
type: "button",
|
|
2933
3098
|
variant: "outline",
|
|
@@ -2945,8 +3110,8 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
2945
3110
|
)
|
|
2946
3111
|
] })
|
|
2947
3112
|
] }),
|
|
2948
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2949
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3113
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.FormCheckbox, { form, id: "active", name: "Active" }),
|
|
3114
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CommonEditorButtons, { isEdit: isEditMode, form, disabled: isSubmitting, setOpen: onOpenChange })
|
|
2950
3115
|
] }) })
|
|
2951
3116
|
] }) });
|
|
2952
3117
|
}
|
|
@@ -2968,7 +3133,7 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
2968
3133
|
const loadPrices = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
2969
3134
|
setLoading(true);
|
|
2970
3135
|
try {
|
|
2971
|
-
const fetchedPrices = await
|
|
3136
|
+
const fetchedPrices = await _chunkJ22NEVSKjs.StripePriceService.listPrices({ productId });
|
|
2972
3137
|
setPrices(fetchedPrices);
|
|
2973
3138
|
} catch (error) {
|
|
2974
3139
|
console.error("[PricesList] Failed to load prices:", error);
|
|
@@ -2985,7 +3150,7 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
2985
3150
|
}
|
|
2986
3151
|
setArchivingPriceId(priceToArchive.id);
|
|
2987
3152
|
try {
|
|
2988
|
-
await
|
|
3153
|
+
await _chunkJ22NEVSKjs.StripePriceService.archivePrice({ id: priceToArchive.id });
|
|
2989
3154
|
setPriceToArchive(null);
|
|
2990
3155
|
await loadPrices();
|
|
2991
3156
|
onPricesChange();
|
|
@@ -3001,7 +3166,7 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3001
3166
|
}
|
|
3002
3167
|
setReactivatingPriceId(priceToReactivate.id);
|
|
3003
3168
|
try {
|
|
3004
|
-
await
|
|
3169
|
+
await _chunkJ22NEVSKjs.StripePriceService.reactivatePrice({ id: priceToReactivate.id });
|
|
3005
3170
|
setPriceToReactivate(null);
|
|
3006
3171
|
await loadPrices();
|
|
3007
3172
|
onPricesChange();
|
|
@@ -3032,12 +3197,12 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3032
3197
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-col gap-y-4", children: [
|
|
3033
3198
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center justify-between mb-4", children: [
|
|
3034
3199
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { className: "text-lg font-semibold", children: "Prices" }),
|
|
3035
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3200
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
|
|
3036
3201
|
] }),
|
|
3037
3202
|
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: [
|
|
3038
3203
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.DollarSign, { className: "text-muted-foreground h-12 w-12" }),
|
|
3039
3204
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-muted-foreground text-sm", children: "No prices yet. Add a price to enable subscriptions." }),
|
|
3040
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3205
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
|
|
3041
3206
|
] }),
|
|
3042
3207
|
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) => {
|
|
3043
3208
|
const isArchiving = archivingPriceId === price.id;
|
|
@@ -3046,9 +3211,9 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3046
3211
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-start justify-between mb-3", children: [
|
|
3047
3212
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.DollarSign, { className: "h-5 w-5 text-primary" }),
|
|
3048
3213
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex gap-1", children: [
|
|
3049
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3214
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.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" }) }),
|
|
3050
3215
|
price.active ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3051
|
-
|
|
3216
|
+
_chunk3X7EEFMNjs.Button,
|
|
3052
3217
|
{
|
|
3053
3218
|
variant: "ghost",
|
|
3054
3219
|
size: "sm",
|
|
@@ -3058,7 +3223,7 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3058
3223
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Archive, { className: "h-4 w-4" })
|
|
3059
3224
|
}
|
|
3060
3225
|
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3061
|
-
|
|
3226
|
+
_chunk3X7EEFMNjs.Button,
|
|
3062
3227
|
{
|
|
3063
3228
|
variant: "ghost",
|
|
3064
3229
|
size: "sm",
|
|
@@ -3075,10 +3240,10 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3075
3240
|
" ",
|
|
3076
3241
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "text-muted-foreground text-sm font-normal", children: formatInterval2(price) })
|
|
3077
3242
|
] }) }),
|
|
3078
|
-
_optionalChain([price, 'access',
|
|
3243
|
+
_optionalChain([price, 'access', _137 => _137.metadata, 'optionalAccess', _138 => _138.nickname]) && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "text-sm font-medium mb-2", children: price.metadata.nickname }),
|
|
3079
3244
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex flex-wrap gap-2", children: [
|
|
3080
3245
|
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" }),
|
|
3081
|
-
_optionalChain([price, 'access',
|
|
3246
|
+
_optionalChain([price, 'access', _139 => _139.recurring, 'optionalAccess', _140 => _140.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" }),
|
|
3082
3247
|
/* @__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 })
|
|
3083
3248
|
] })
|
|
3084
3249
|
] }, price.id);
|
|
@@ -3109,20 +3274,20 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3109
3274
|
}
|
|
3110
3275
|
}
|
|
3111
3276
|
),
|
|
3112
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3113
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3114
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3115
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3277
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialog, { open: !!priceToArchive, onOpenChange: (open) => !open && setPriceToArchive(null), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogContent, { children: [
|
|
3278
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogHeader, { children: [
|
|
3279
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogTitle, { children: "Archive Price" }),
|
|
3280
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogDescription, { children: [
|
|
3116
3281
|
"Are you sure you want to archive the price for",
|
|
3117
3282
|
" ",
|
|
3118
3283
|
priceToArchive && `${formatCurrency(priceToArchive.unitAmount, priceToArchive.currency)} ${formatInterval2(priceToArchive)}`,
|
|
3119
3284
|
"? This will prevent new subscriptions but existing ones will continue."
|
|
3120
3285
|
] })
|
|
3121
3286
|
] }),
|
|
3122
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3123
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3287
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogFooter, { children: [
|
|
3288
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogCancel, { disabled: !!archivingPriceId, children: "Cancel" }),
|
|
3124
3289
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3125
|
-
|
|
3290
|
+
_chunk3X7EEFMNjs.AlertDialogAction,
|
|
3126
3291
|
{
|
|
3127
3292
|
onClick: handleArchive,
|
|
3128
3293
|
disabled: !!archivingPriceId,
|
|
@@ -3132,20 +3297,20 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3132
3297
|
)
|
|
3133
3298
|
] })
|
|
3134
3299
|
] }) }),
|
|
3135
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3136
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3137
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3138
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3300
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialog, { open: !!priceToReactivate, onOpenChange: (open) => !open && setPriceToReactivate(null), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogContent, { children: [
|
|
3301
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogHeader, { children: [
|
|
3302
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogTitle, { children: "Reactivate Price" }),
|
|
3303
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogDescription, { children: [
|
|
3139
3304
|
"Are you sure you want to reactivate the price for",
|
|
3140
3305
|
" ",
|
|
3141
3306
|
priceToReactivate && `${formatCurrency(priceToReactivate.unitAmount, priceToReactivate.currency)} ${formatInterval2(priceToReactivate)}`,
|
|
3142
3307
|
"? This will allow new subscriptions again."
|
|
3143
3308
|
] })
|
|
3144
3309
|
] }),
|
|
3145
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3146
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3310
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogFooter, { children: [
|
|
3311
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogCancel, { disabled: !!reactivatingPriceId, children: "Cancel" }),
|
|
3147
3312
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3148
|
-
|
|
3313
|
+
_chunk3X7EEFMNjs.AlertDialogAction,
|
|
3149
3314
|
{
|
|
3150
3315
|
onClick: handleReactivate,
|
|
3151
3316
|
disabled: !!reactivatingPriceId,
|
|
@@ -3174,29 +3339,29 @@ function ProductEditor({ product, open, onOpenChange, onSuccess }) {
|
|
|
3174
3339
|
const [isSubmitting, setIsSubmitting] = _react.useState.call(void 0, false);
|
|
3175
3340
|
const formSchema2 = _zod3.z.object({
|
|
3176
3341
|
name: _zod3.z.string().min(1, { message: "Product name is required" }),
|
|
3177
|
-
description: _zod3.z.string().
|
|
3342
|
+
description: _zod3.z.string().min(1, { message: "Description is required" }),
|
|
3178
3343
|
active: _zod3.z.boolean()
|
|
3179
3344
|
});
|
|
3180
3345
|
const form = _reacthookform.useForm.call(void 0, {
|
|
3181
3346
|
resolver: _zod.zodResolver.call(void 0, formSchema2),
|
|
3182
3347
|
defaultValues: {
|
|
3183
|
-
name: _optionalChain([product, 'optionalAccess',
|
|
3184
|
-
description: _optionalChain([product, 'optionalAccess',
|
|
3185
|
-
active: _nullishCoalesce(_optionalChain([product, 'optionalAccess',
|
|
3348
|
+
name: _optionalChain([product, 'optionalAccess', _141 => _141.name]) || "",
|
|
3349
|
+
description: _optionalChain([product, 'optionalAccess', _142 => _142.description]) || "",
|
|
3350
|
+
active: _nullishCoalesce(_optionalChain([product, 'optionalAccess', _143 => _143.active]), () => ( true))
|
|
3186
3351
|
}
|
|
3187
3352
|
});
|
|
3188
3353
|
const onSubmit = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async (values) => {
|
|
3189
3354
|
setIsSubmitting(true);
|
|
3190
3355
|
try {
|
|
3191
3356
|
if (product) {
|
|
3192
|
-
await
|
|
3357
|
+
await _chunkJ22NEVSKjs.StripeProductService.updateProduct({
|
|
3193
3358
|
id: product.id,
|
|
3194
3359
|
name: values.name,
|
|
3195
3360
|
description: values.description,
|
|
3196
3361
|
active: values.active
|
|
3197
3362
|
});
|
|
3198
3363
|
} else {
|
|
3199
|
-
await
|
|
3364
|
+
await _chunkJ22NEVSKjs.StripeProductService.createProduct({
|
|
3200
3365
|
id: _uuid.v4.call(void 0, ),
|
|
3201
3366
|
name: values.name,
|
|
3202
3367
|
description: values.description,
|
|
@@ -3211,25 +3376,25 @@ function ProductEditor({ product, open, onOpenChange, onSuccess }) {
|
|
|
3211
3376
|
setIsSubmitting(false);
|
|
3212
3377
|
}
|
|
3213
3378
|
}, "onSubmit");
|
|
3214
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3215
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3216
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3217
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3379
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Dialog, { open, onOpenChange, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogContent, { className: "max-w-2xl", children: [
|
|
3380
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.DialogHeader, { children: [
|
|
3381
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogTitle, { children: product ? "Edit Product" : "Create Product" }),
|
|
3382
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.DialogDescription, { children: product ? `Update the details for ${product.name}` : "Create a new product to offer to your customers" })
|
|
3218
3383
|
] }),
|
|
3219
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3220
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3384
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Form, { ...form, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
|
|
3385
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.FormInput, { form, id: "name", name: "Product Name", placeholder: "Enter product name", isRequired: true }),
|
|
3221
3386
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3222
|
-
|
|
3387
|
+
_chunk3X7EEFMNjs.FormTextarea,
|
|
3223
3388
|
{
|
|
3224
3389
|
form,
|
|
3225
3390
|
id: "description",
|
|
3226
3391
|
name: "Description",
|
|
3227
|
-
placeholder: "Enter product description
|
|
3392
|
+
placeholder: "Enter product description",
|
|
3228
3393
|
className: "min-h-32"
|
|
3229
3394
|
}
|
|
3230
3395
|
),
|
|
3231
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3232
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3396
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.FormCheckbox, { form, id: "active", name: "Active" }),
|
|
3397
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.CommonEditorButtons, { isEdit: !!product, form, disabled: isSubmitting, setOpen: onOpenChange })
|
|
3233
3398
|
] }) })
|
|
3234
3399
|
] }) });
|
|
3235
3400
|
}
|
|
@@ -3252,7 +3417,7 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3252
3417
|
}
|
|
3253
3418
|
setArchivingProductId(productToArchive.id);
|
|
3254
3419
|
try {
|
|
3255
|
-
const archivedProduct = await
|
|
3420
|
+
const archivedProduct = await _chunkJ22NEVSKjs.StripeProductService.archiveProduct({ id: productToArchive.id });
|
|
3256
3421
|
setProductToArchive(null);
|
|
3257
3422
|
onProductsChange();
|
|
3258
3423
|
} catch (error) {
|
|
@@ -3267,7 +3432,7 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3267
3432
|
}
|
|
3268
3433
|
setReactivatingProductId(productToReactivate.id);
|
|
3269
3434
|
try {
|
|
3270
|
-
const reactivatedProduct = await
|
|
3435
|
+
const reactivatedProduct = await _chunkJ22NEVSKjs.StripeProductService.reactivateProduct({ id: productToReactivate.id });
|
|
3271
3436
|
setProductToReactivate(null);
|
|
3272
3437
|
onProductsChange();
|
|
3273
3438
|
} catch (error) {
|
|
@@ -3296,12 +3461,12 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3296
3461
|
] })
|
|
3297
3462
|
] }),
|
|
3298
3463
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "flex items-center gap-x-2", children: [
|
|
3299
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3464
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.Button, { variant: "outline", size: "sm", onClick: () => setEditingProduct(product), children: [
|
|
3300
3465
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Edit, { className: "h-4 w-4 mr-1" }),
|
|
3301
3466
|
"Edit"
|
|
3302
3467
|
] }),
|
|
3303
3468
|
product.active ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3304
|
-
|
|
3469
|
+
_chunk3X7EEFMNjs.Button,
|
|
3305
3470
|
{
|
|
3306
3471
|
variant: "outline",
|
|
3307
3472
|
size: "sm",
|
|
@@ -3313,7 +3478,7 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3313
3478
|
]
|
|
3314
3479
|
}
|
|
3315
3480
|
) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3316
|
-
|
|
3481
|
+
_chunk3X7EEFMNjs.Button,
|
|
3317
3482
|
{
|
|
3318
3483
|
variant: "outline",
|
|
3319
3484
|
size: "sm",
|
|
@@ -3325,7 +3490,7 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3325
3490
|
]
|
|
3326
3491
|
}
|
|
3327
3492
|
),
|
|
3328
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3493
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.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" }) })
|
|
3329
3494
|
] })
|
|
3330
3495
|
] }),
|
|
3331
3496
|
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 }) })
|
|
@@ -3343,19 +3508,19 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3343
3508
|
}
|
|
3344
3509
|
}
|
|
3345
3510
|
),
|
|
3346
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3347
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3348
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3349
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3511
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialog, { open: !!productToArchive, onOpenChange: (open) => !open && setProductToArchive(null), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogContent, { children: [
|
|
3512
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogHeader, { children: [
|
|
3513
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogTitle, { children: "Archive Product" }),
|
|
3514
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogDescription, { children: [
|
|
3350
3515
|
'Are you sure you want to archive "',
|
|
3351
|
-
_optionalChain([productToArchive, 'optionalAccess',
|
|
3516
|
+
_optionalChain([productToArchive, 'optionalAccess', _144 => _144.name]),
|
|
3352
3517
|
'"? This will deactivate it and it will no longer be available for new subscriptions.'
|
|
3353
3518
|
] })
|
|
3354
3519
|
] }),
|
|
3355
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3356
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3520
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogFooter, { children: [
|
|
3521
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogCancel, { disabled: !!archivingProductId, children: "Cancel" }),
|
|
3357
3522
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3358
|
-
|
|
3523
|
+
_chunk3X7EEFMNjs.AlertDialogAction,
|
|
3359
3524
|
{
|
|
3360
3525
|
onClick: handleArchive,
|
|
3361
3526
|
disabled: !!archivingProductId,
|
|
@@ -3365,19 +3530,19 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3365
3530
|
)
|
|
3366
3531
|
] })
|
|
3367
3532
|
] }) }),
|
|
3368
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3369
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3370
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3371
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3533
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialog, { open: !!productToReactivate, onOpenChange: (open) => !open && setProductToReactivate(null), children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogContent, { children: [
|
|
3534
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogHeader, { children: [
|
|
3535
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogTitle, { children: "Reactivate Product" }),
|
|
3536
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogDescription, { children: [
|
|
3372
3537
|
'Are you sure you want to reactivate "',
|
|
3373
|
-
_optionalChain([productToReactivate, 'optionalAccess',
|
|
3538
|
+
_optionalChain([productToReactivate, 'optionalAccess', _145 => _145.name]),
|
|
3374
3539
|
'"? This will make it available for new subscriptions again.'
|
|
3375
3540
|
] })
|
|
3376
3541
|
] }),
|
|
3377
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3378
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3542
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _chunk3X7EEFMNjs.AlertDialogFooter, { children: [
|
|
3543
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.AlertDialogCancel, { disabled: !!reactivatingProductId, children: "Cancel" }),
|
|
3379
3544
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3380
|
-
|
|
3545
|
+
_chunk3X7EEFMNjs.AlertDialogAction,
|
|
3381
3546
|
{
|
|
3382
3547
|
onClick: handleReactivate,
|
|
3383
3548
|
disabled: !!reactivatingProductId,
|
|
@@ -3394,7 +3559,7 @@ _chunk7QVYU63Ejs.__name.call(void 0, ProductsList, "ProductsList");
|
|
|
3394
3559
|
// src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx
|
|
3395
3560
|
|
|
3396
3561
|
function ProductsAdminContainer() {
|
|
3397
|
-
const { hasRole } =
|
|
3562
|
+
const { hasRole } = _chunk3X7EEFMNjs.useCurrentUserContext.call(void 0, );
|
|
3398
3563
|
const [products, setProducts] = _react.useState.call(void 0, []);
|
|
3399
3564
|
const [loading, setLoading] = _react.useState.call(void 0, true);
|
|
3400
3565
|
const [showCreateProduct, setShowCreateProduct] = _react.useState.call(void 0, false);
|
|
@@ -3404,7 +3569,7 @@ function ProductsAdminContainer() {
|
|
|
3404
3569
|
const loadProducts = /* @__PURE__ */ _chunk7QVYU63Ejs.__name.call(void 0, async () => {
|
|
3405
3570
|
setLoading(true);
|
|
3406
3571
|
try {
|
|
3407
|
-
const fetchedProducts = await
|
|
3572
|
+
const fetchedProducts = await _chunkJ22NEVSKjs.StripeProductService.listProducts();
|
|
3408
3573
|
setProducts(fetchedProducts);
|
|
3409
3574
|
} catch (error) {
|
|
3410
3575
|
console.error("[ProductsAdminContainer] Failed to load products:", error);
|
|
@@ -3424,14 +3589,14 @@ function ProductsAdminContainer() {
|
|
|
3424
3589
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Package, { className: "h-8 w-8" }),
|
|
3425
3590
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { className: "text-3xl font-bold", children: "Product & Price Management" })
|
|
3426
3591
|
] }),
|
|
3427
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3592
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: () => setShowCreateProduct(true), children: "Create Product" })
|
|
3428
3593
|
] }),
|
|
3429
3594
|
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: [
|
|
3430
3595
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _lucidereact.Package, { className: "text-muted-foreground h-16 w-16" }),
|
|
3431
3596
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "text-center", children: [
|
|
3432
3597
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { className: "mb-2 text-xl font-semibold", children: "No products yet" }),
|
|
3433
3598
|
/* @__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." }),
|
|
3434
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3599
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, _chunk3X7EEFMNjs.Button, { onClick: () => setShowCreateProduct(true), children: "Create Your First Product" })
|
|
3435
3600
|
] })
|
|
3436
3601
|
] }),
|
|
3437
3602
|
products.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ProductsList, { products, onProductsChange: loadProducts }),
|
|
@@ -3479,5 +3644,8 @@ _chunk7QVYU63Ejs.__name.call(void 0, ProductsAdminContainer, "ProductsAdminConta
|
|
|
3479
3644
|
|
|
3480
3645
|
|
|
3481
3646
|
|
|
3482
|
-
|
|
3647
|
+
|
|
3648
|
+
|
|
3649
|
+
|
|
3650
|
+
exports.BillingAlertBanner = BillingAlertBanner; exports.BillingDashboardContainer = BillingDashboardContainer; exports.BillingDetailModal = BillingDetailModal; exports.BillingUsageSummaryCard = BillingUsageSummaryCard; exports.CancelSubscriptionDialog = CancelSubscriptionDialog; exports.CustomerInfoCard = CustomerInfoCard; exports.IntervalToggle = IntervalToggle; exports.InvoiceDetails = InvoiceDetails; exports.InvoiceStatusBadge = InvoiceStatusBadge; exports.InvoicesContainer = InvoicesContainer; exports.InvoicesList = InvoicesList; exports.InvoicesSummaryCard = InvoicesSummaryCard; exports.PaymentMethodCard = PaymentMethodCard; exports.PaymentMethodEditor = PaymentMethodEditor; exports.PaymentMethodForm = PaymentMethodForm; exports.PaymentMethodSummaryCard = PaymentMethodSummaryCard; exports.PaymentMethodsContainer = PaymentMethodsContainer; exports.PaymentMethodsList = PaymentMethodsList; exports.PriceEditor = PriceEditor; exports.PricesList = PricesList; exports.PricingCard = PricingCard; exports.ProductEditor = ProductEditor; exports.ProductPricingList = ProductPricingList; exports.ProductPricingRow = ProductPricingRow; exports.ProductsAdminContainer = ProductsAdminContainer; exports.ProductsList = ProductsList; exports.ProrationPreview = ProrationPreview; exports.StripeProvider = StripeProvider; exports.SubscriptionConfirmation = SubscriptionConfirmation; exports.SubscriptionDetails = SubscriptionDetails; 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;
|
|
3483
3651
|
//# sourceMappingURL=index.js.map
|