@carlonicora/nextjs-jsonapi 1.29.1 → 1.29.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BlockNoteEditor-7BDLLHRA.js → BlockNoteEditor-BEWKLGW3.js} +13 -13
- package/dist/{BlockNoteEditor-7BDLLHRA.js.map → BlockNoteEditor-BEWKLGW3.js.map} +1 -1
- package/dist/{BlockNoteEditor-F5KCNLVF.mjs → BlockNoteEditor-GNFK7ZVR.mjs} +3 -3
- package/dist/billing/index.js +334 -333
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +8 -7
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-YLSLXQ3O.mjs → chunk-IJSB4FH6.mjs} +3 -3
- package/dist/{chunk-DU64WMZD.mjs → chunk-NYNLJEPF.mjs} +4 -4
- package/dist/chunk-NYNLJEPF.mjs.map +1 -0
- package/dist/{chunk-J22NEVSK.js → chunk-UYBCHXXL.js} +4 -4
- package/dist/chunk-UYBCHXXL.js.map +1 -0
- package/dist/{chunk-7M7NPKOF.js → chunk-XU4MY6OG.js} +427 -427
- package/dist/{chunk-7M7NPKOF.js.map → chunk-XU4MY6OG.js.map} +1 -1
- package/dist/client/index.js +3 -3
- package/dist/client/index.mjs +2 -2
- package/dist/components/index.js +3 -3
- package/dist/components/index.mjs +2 -2
- package/dist/contexts/index.js +3 -3
- package/dist/contexts/index.mjs +2 -2
- package/dist/core/index.js +2 -2
- package/dist/core/index.mjs +1 -1
- package/dist/index.js +2 -2
- package/dist/index.mjs +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/package.json +1 -1
- package/src/core/abstracts/AbstractService.ts +2 -2
- package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +5 -4
- package/src/utils/blocknote-diff.util.ts +1 -1
- package/dist/chunk-DU64WMZD.mjs.map +0 -1
- package/dist/chunk-J22NEVSK.js.map +0 -1
- /package/dist/{BlockNoteEditor-F5KCNLVF.mjs.map → BlockNoteEditor-GNFK7ZVR.mjs.map} +0 -0
- /package/dist/{chunk-YLSLXQ3O.mjs.map → chunk-IJSB4FH6.mjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/features/billing/components/cards/SubscriptionSummaryCard.tsx","../../src/features/billing/components/cards/PaymentMethodSummaryCard.tsx","../../src/features/billing/components/cards/CustomerInfoCard.tsx","../../src/features/billing/components/cards/InvoicesSummaryCard.tsx","../../src/features/billing/components/cards/BillingUsageSummaryCard.tsx","../../src/features/billing/components/containers/BillingDashboardContainer.tsx","../../src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx","../../src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx","../../src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx","../../src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx","../../src/features/billing/stripe-customer/components/lists/PaymentMethodsList.tsx","../../src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx","../../src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx","../../src/features/billing/components/utils/currency.ts","../../src/features/billing/components/utils/date.ts","../../src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx","../../src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx","../../src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx","../../src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx","../../src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx","../../src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx","../../src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx","../../src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx","../../src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx","../../src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx","../../src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx","../../src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx","../../src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx","../../src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx","../../src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts","../../src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx","../../src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx","../../src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx","../../src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx","../../src/features/billing/stripe-usage/components/containers/UsageContainer.tsx","../../src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx","../../src/features/billing/stripe-usage/components/widgets/UsageSummaryCards.tsx","../../src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx","../../src/features/billing/components/modals/BillingDetailModal.tsx","../../src/features/billing/components/widgets/BillingAlertBanner.tsx","../../src/features/billing/components/providers/StripeProvider.tsx","../../src/features/billing/stripe-price/components/forms/PriceEditor.tsx","../../src/features/billing/stripe-price/components/lists/PricesList.tsx","../../src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx","../../src/features/billing/stripe-product/components/forms/ProductEditor.tsx","../../src/features/billing/stripe-product/components/lists/ProductsList.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronRight, CreditCard } from \"lucide-react\";\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle, Skeleton } from \"../../../../shadcnui\";\nimport { StripeSubscriptionInterface, SubscriptionStatus } from \"../../stripe-subscription\";\n\ntype SubscriptionSummaryCardProps = {\n subscriptions: StripeSubscriptionInterface[];\n loading?: boolean;\n error?: string;\n onManageClick: () => void;\n};\n\nfunction getStatusBadgeVariant(status: SubscriptionStatus): \"default\" | \"secondary\" | \"destructive\" | \"outline\" {\n switch (status) {\n case SubscriptionStatus.ACTIVE:\n return \"default\";\n case SubscriptionStatus.TRIALING:\n return \"secondary\";\n case SubscriptionStatus.PAST_DUE:\n case SubscriptionStatus.UNPAID:\n case SubscriptionStatus.CANCELED:\n return \"destructive\";\n default:\n return \"outline\";\n }\n}\n\nfunction formatDate(date: Date): string {\n return new Date(date).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nfunction formatPrice(amount: number | undefined, currency: string | undefined): string {\n if (amount === undefined) return \"N/A\";\n const currencyCode = currency?.toUpperCase() || \"USD\";\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: currencyCode,\n }).format(amount / 100);\n}\n\nfunction formatPlanName(subscription: StripeSubscriptionInterface): string {\n const productName = subscription.price?.product?.name || \"\";\n const nickname = subscription.price?.nickname || \"\";\n\n if (productName && nickname) {\n return `${productName} - ${nickname}`;\n }\n return productName || nickname || \"Subscription\";\n}\n\nexport function SubscriptionSummaryCard({\n subscriptions,\n loading,\n error,\n onManageClick,\n}: SubscriptionSummaryCardProps) {\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Subscriptions</CardTitle>\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-32 mb-2\" />\n <Skeleton className=\"h-4 w-24 mb-1\" />\n <Skeleton className=\"h-4 w-40\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Subscriptions</CardTitle>\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n const activeSubscriptions = subscriptions.filter(\n (sub) => sub.status === SubscriptionStatus.ACTIVE || sub.status === SubscriptionStatus.TRIALING,\n );\n const primarySubscription = activeSubscriptions[0];\n\n return (\n <Card className=\"cursor-pointer hover:bg-accent/50 transition-colors\" onClick={onManageClick}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Subscriptions</CardTitle>\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n {subscriptions.length === 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold text-muted-foreground\">No active plan</p>\n <p className=\"text-xs text-muted-foreground\">Subscribe to get started</p>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2\"\n onClick={(e) => {\n e.stopPropagation();\n onManageClick();\n }}\n >\n View Plans\n <ChevronRight className=\"h-4 w-4 ml-1\" />\n </Button>\n </div>\n ) : primarySubscription ? (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-xl font-bold\">{formatPlanName(primarySubscription)}</p>\n <Badge variant={primarySubscription.cancelAtPeriodEnd ? \"secondary\" : getStatusBadgeVariant(primarySubscription.status)}>\n {primarySubscription.cancelAtPeriodEnd ? \"Canceling\" : primarySubscription.status}\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {formatPrice(primarySubscription.price?.unitAmount, primarySubscription.price?.currency)}\n {primarySubscription.price?.recurring && <span>/{primarySubscription.price.recurring.interval}</span>}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {primarySubscription.cancelAtPeriodEnd\n ? `Cancels on ${formatDate(primarySubscription.currentPeriodEnd)}`\n : `Renews on ${formatDate(primarySubscription.currentPeriodEnd)}`}\n </p>\n {activeSubscriptions.length > 1 && (\n <p className=\"text-xs text-muted-foreground\">+{activeSubscriptions.length - 1} more subscription(s)</p>\n )}\n </div>\n ) : null}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { Wallet, ChevronRight } from \"lucide-react\";\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Button,\n Skeleton,\n} from \"../../../../shadcnui\";\nimport { PaymentMethodInterface } from \"../../stripe-customer\";\n\ntype PaymentMethodSummaryCardProps = {\n paymentMethods: PaymentMethodInterface[];\n defaultPaymentMethodId?: string;\n loading?: boolean;\n error?: string;\n onManageClick: () => void;\n};\n\nfunction getCardBrandIcon(brand: string): string {\n const brandMap: Record<string, string> = {\n visa: \"Visa\",\n mastercard: \"Mastercard\",\n amex: \"Amex\",\n discover: \"Discover\",\n diners: \"Diners\",\n jcb: \"JCB\",\n unionpay: \"UnionPay\",\n };\n return brandMap[brand.toLowerCase()] || brand;\n}\n\nexport function PaymentMethodSummaryCard({\n paymentMethods,\n defaultPaymentMethodId,\n loading,\n error,\n onManageClick,\n}: PaymentMethodSummaryCardProps) {\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Payment Method</CardTitle>\n <Wallet className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-32 mb-2\" />\n <Skeleton className=\"h-4 w-24\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Payment Method</CardTitle>\n <Wallet className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n // Find default payment method or use first one\n const defaultMethod = paymentMethods.find((pm) => pm.id === defaultPaymentMethodId) || paymentMethods[0];\n\n return (\n <Card className=\"cursor-pointer hover:bg-accent/50 transition-colors\" onClick={onManageClick}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Payment Method</CardTitle>\n <Wallet className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n {paymentMethods.length === 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold text-muted-foreground\">No payment method</p>\n <p className=\"text-xs text-muted-foreground\">\n Add a card to enable subscriptions\n </p>\n <Button variant=\"outline\" size=\"sm\" className=\"mt-2\" onClick={(e) => { e.stopPropagation(); onManageClick(); }}>\n Add Card\n <ChevronRight className=\"h-4 w-4 ml-1\" />\n </Button>\n </div>\n ) : defaultMethod?.card ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold\">\n {getCardBrandIcon(defaultMethod.card.brand)} ****{defaultMethod.card.last4}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n Expires {String(defaultMethod.card.expMonth).padStart(2, \"0\")}/{defaultMethod.card.expYear}\n </p>\n {paymentMethods.length > 1 && (\n <p className=\"text-xs text-muted-foreground\">\n +{paymentMethods.length - 1} more card(s)\n </p>\n )}\n </div>\n ) : (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold\">{defaultMethod?.type || \"Payment Method\"}</p>\n {paymentMethods.length > 1 && (\n <p className=\"text-xs text-muted-foreground\">\n +{paymentMethods.length - 1} more method(s)\n </p>\n )}\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { ExternalLink, User } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Button, Card, CardContent, CardHeader, CardTitle, Skeleton } from \"../../../../shadcnui\";\nimport { StripeCustomerInterface, StripeCustomerService } from \"../../stripe-customer\";\n\ntype CustomerInfoCardProps = {\n customer: StripeCustomerInterface | null;\n loading?: boolean;\n error?: string;\n};\n\nfunction formatBalance(balance: number | undefined, currency: string | undefined): string {\n if (balance === undefined || balance === 0) return \"$0.00\";\n const currencyCode = currency?.toUpperCase() || \"USD\";\n // Balance in Stripe is negative when customer has credit\n const displayBalance = -balance;\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: currencyCode,\n }).format(displayBalance / 100);\n}\n\nexport function CustomerInfoCard({ customer, loading, error }: CustomerInfoCardProps) {\n const [portalLoading, setPortalLoading] = useState(false);\n\n const handlePortalClick = async (e: React.MouseEvent) => {\n e.stopPropagation();\n setPortalLoading(true);\n try {\n const { url } = await StripeCustomerService.createPortalSession();\n window.open(url, \"_blank\");\n } catch (err) {\n console.error(\"[CustomerInfoCard] Failed to create portal session:\", err);\n } finally {\n setPortalLoading(false);\n }\n };\n\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Billing Account</CardTitle>\n <User className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-32 mb-2\" />\n <Skeleton className=\"h-4 w-48 mb-1\" />\n <Skeleton className=\"h-4 w-24\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Billing Account</CardTitle>\n <User className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n if (!customer) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Billing Account</CardTitle>\n <User className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-xl font-bold text-muted-foreground\">Not set up</p>\n <p className=\"text-xs text-muted-foreground\">Billing account will be created when you subscribe</p>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Billing Account</CardTitle>\n <User className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n {customer.name && <p className=\"text-xl font-bold\">{customer.name}</p>}\n {customer.email && <p className=\"text-sm text-muted-foreground\">{customer.email}</p>}\n {customer.balance !== undefined && customer.balance !== 0 && (\n <p className=\"text-sm\">\n <span className=\"text-muted-foreground\">Credit Balance: </span>\n <span className={customer.balance < 0 ? \"text-green-600\" : \"text-destructive\"}>\n {formatBalance(customer.balance, customer.currency)}\n </span>\n </p>\n )}\n <Button variant=\"outline\" size=\"sm\" className=\"mt-2\" onClick={handlePortalClick} disabled={portalLoading}>\n {portalLoading ? \"Loading...\" : \"Manage in Stripe Portal\"}\n <ExternalLink className=\"h-4 w-4 ml-1\" />\n </Button>\n </div>\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { ChevronRight, ReceiptIcon } from \"lucide-react\";\nimport { Badge, Card, CardContent, CardHeader, CardTitle, Skeleton } from \"../../../../shadcnui\";\nimport { InvoiceStatus, StripeInvoiceInterface } from \"../../stripe-invoice\";\n\ntype InvoicesSummaryCardProps = {\n invoices: StripeInvoiceInterface[];\n loading?: boolean;\n error?: string;\n onViewAllClick: () => void;\n};\n\nfunction getStatusBadgeVariant(status: InvoiceStatus): \"default\" | \"secondary\" | \"destructive\" | \"outline\" {\n switch (status) {\n case InvoiceStatus.PAID:\n return \"default\";\n case InvoiceStatus.OPEN:\n return \"secondary\";\n case InvoiceStatus.UNCOLLECTIBLE:\n case InvoiceStatus.VOID:\n return \"destructive\";\n default:\n return \"outline\";\n }\n}\n\nfunction formatDate(date: Date): string {\n return new Date(date).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nfunction formatAmount(amount: number, currency: string): string {\n const currencyCode = currency?.toUpperCase() || \"USD\";\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: currencyCode,\n }).format(amount / 100);\n}\n\nexport function InvoicesSummaryCard({ invoices, loading, error, onViewAllClick }: InvoicesSummaryCardProps) {\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Recent Invoices</CardTitle>\n <ReceiptIcon className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-24 mb-2\" />\n <Skeleton className=\"h-4 w-32 mb-1\" />\n <Skeleton className=\"h-4 w-20\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Recent Invoices</CardTitle>\n <ReceiptIcon className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n // Get the most recent invoice\n const latestInvoice = invoices[0];\n const paidInvoices = invoices.filter((inv) => inv.status === InvoiceStatus.PAID);\n const openInvoices = invoices.filter((inv) => inv.status === InvoiceStatus.OPEN);\n\n return (\n <Card className=\"cursor-pointer hover:bg-accent/50 transition-colors\" onClick={onViewAllClick}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Recent Invoices</CardTitle>\n <ReceiptIcon className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n {invoices.length === 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold text-muted-foreground\">No invoices yet</p>\n <p className=\"text-xs text-muted-foreground\">Invoices will appear after your first billing cycle</p>\n </div>\n ) : latestInvoice ? (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-xl font-bold\">{formatAmount(latestInvoice.total, latestInvoice.currency)}</p>\n <Badge variant={getStatusBadgeVariant(latestInvoice.status)}>{latestInvoice.status}</Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {latestInvoice.stripeInvoiceNumber || `Invoice from ${formatDate(latestInvoice.periodStart)}`}\n </p>\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n {paidInvoices.length > 0 && <span>{paidInvoices.length} paid</span>}\n {openInvoices.length > 0 && <span className=\"text-orange-600\">{openInvoices.length} open</span>}\n <span className=\"flex items-center\">\n View all\n <ChevronRight className=\"h-3 w-3 ml-1\" />\n </span>\n </div>\n </div>\n ) : null}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { Activity, ChevronRight } from \"lucide-react\";\nimport { Card, CardContent, CardHeader, CardTitle, Skeleton } from \"../../../../shadcnui\";\nimport { MeterInterface, MeterSummaryInterface } from \"../../stripe-usage\";\n\ntype BillingUsageSummaryCardProps = {\n meters: MeterInterface[];\n summaries: Record<string, MeterSummaryInterface | null>;\n loading?: boolean;\n error?: string;\n onViewDetailsClick: () => void;\n};\n\nfunction formatNumber(value: number): string {\n return new Intl.NumberFormat(undefined, {\n notation: \"compact\",\n compactDisplay: \"short\",\n }).format(value);\n}\n\nexport function BillingUsageSummaryCard({\n meters,\n summaries,\n loading,\n error,\n onViewDetailsClick,\n}: BillingUsageSummaryCardProps) {\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Usage This Month</CardTitle>\n <Activity className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-24 mb-2\" />\n <Skeleton className=\"h-4 w-32\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Usage This Month</CardTitle>\n <Activity className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n // Calculate total usage across all meters\n const totalUsage = Object.values(summaries).reduce((acc, summary) => {\n return acc + (summary?.aggregatedValue || 0);\n }, 0);\n\n // Get first meter with data for display\n const primaryMeter = meters.find((m) => summaries[m.id]?.aggregatedValue);\n const primarySummary = primaryMeter ? summaries[primaryMeter.id] : null;\n\n return (\n <Card className=\"cursor-pointer hover:bg-accent/50 transition-colors\" onClick={onViewDetailsClick}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Usage This Month</CardTitle>\n <Activity className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n {meters.length === 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold text-muted-foreground\">No meters</p>\n <p className=\"text-xs text-muted-foreground\">No usage meters are configured</p>\n </div>\n ) : (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold\">{formatNumber(totalUsage)} units</p>\n {primaryMeter && primarySummary && (\n <p className=\"text-sm text-muted-foreground\">\n {primaryMeter.displayName}: {formatNumber(primarySummary.aggregatedValue)}\n </p>\n )}\n {meters.length > 1 && <p className=\"text-xs text-muted-foreground\">Across {meters.length} meters</p>}\n <span className=\"flex items-center text-xs text-muted-foreground\">\n View details\n <ChevronRight className=\"h-3 w-3 ml-1\" />\n </span>\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { CreditCard, Loader2, Wallet } from \"lucide-react\";\nimport { useSearchParams } from \"next/navigation\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Button, Card, CardContent, CardDescription, CardHeader, CardTitle } from \"../../../../shadcnui\";\nimport { PaymentMethodInterface, StripeCustomerInterface, StripeCustomerService } from \"../../stripe-customer\";\nimport { PaymentMethodsContainer } from \"../../stripe-customer/components\";\nimport { StripeInvoiceInterface, StripeInvoiceService } from \"../../stripe-invoice\";\nimport { InvoicesContainer } from \"../../stripe-invoice/components\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService, SubscriptionStatus } from \"../../stripe-subscription\";\nimport { SubscriptionsContainer } from \"../../stripe-subscription/components\";\nimport { SubscriptionWizard } from \"../../stripe-subscription/components/wizards\";\nimport { MeterInterface, MeterSummaryInterface, StripeUsageService } from \"../../stripe-usage\";\nimport { UsageContainer } from \"../../stripe-usage/components\";\nimport {\n BillingUsageSummaryCard,\n CustomerInfoCard,\n InvoicesSummaryCard,\n PaymentMethodSummaryCard,\n SubscriptionSummaryCard,\n} from \"../cards\";\nimport { BillingDetailModal } from \"../modals/BillingDetailModal\";\nimport { BillingAlertBanner } from \"../widgets/BillingAlertBanner\";\n\ntype ModalType = \"subscriptions\" | \"payment-methods\" | \"invoices\" | \"usage\" | null;\n\ntype DataState = {\n customer: StripeCustomerInterface | null;\n subscriptions: StripeSubscriptionInterface[];\n paymentMethods: PaymentMethodInterface[];\n invoices: StripeInvoiceInterface[];\n meters: MeterInterface[];\n meterSummaries: Record<string, MeterSummaryInterface | null>;\n};\n\ntype LoadingState = {\n customer: boolean;\n subscriptions: boolean;\n paymentMethods: boolean;\n invoices: boolean;\n usage: boolean;\n};\n\ntype ErrorState = {\n customer: string | null;\n subscriptions: string | null;\n paymentMethods: string | null;\n invoices: string | null;\n usage: string | null;\n};\n\nexport function BillingDashboardContainer() {\n const [data, setData] = useState<DataState>({\n customer: null,\n subscriptions: [],\n paymentMethods: [],\n invoices: [],\n meters: [],\n meterSummaries: {},\n });\n\n const [loading, setLoading] = useState<LoadingState>({\n customer: true,\n subscriptions: true,\n paymentMethods: true,\n invoices: true,\n usage: true,\n });\n\n const [errors, setErrors] = useState<ErrorState>({\n customer: null,\n subscriptions: null,\n paymentMethods: null,\n invoices: null,\n usage: null,\n });\n\n const [activeModal, setActiveModal] = useState<ModalType>(null);\n const [noCustomerExists, setNoCustomerExists] = useState(false);\n const [creatingCustomer, setCreatingCustomer] = useState(false);\n const searchParams = useSearchParams();\n\n // Wizard state - lifted from SubscriptionsContainer to avoid nested dialogs\n const [showWizard, setShowWizard] = useState(false);\n const [editingSubscription, setEditingSubscription] = useState<StripeSubscriptionInterface | null>(null);\n\n // Check if company has metered subscriptions\n const hasMeteredSubscriptions = useCallback((): boolean => {\n return data.subscriptions.some((sub) => sub.price?.recurring?.usageType === \"metered\");\n }, [data.subscriptions]);\n\n // Check if user has active recurring subscription (for wizard filtering)\n const hasActiveRecurringSubscription = useMemo(() => {\n return data.subscriptions.some(\n (sub) =>\n (sub.status === SubscriptionStatus.ACTIVE || sub.status === SubscriptionStatus.TRIALING) &&\n sub.price?.priceType === \"recurring\",\n );\n }, [data.subscriptions]);\n\n // Fetch all data - first check customer, then fetch rest if customer exists\n const fetchAllData = useCallback(async () => {\n setNoCustomerExists(false);\n\n // First, try to fetch customer\n let customer: StripeCustomerInterface | null = null;\n try {\n customer = await StripeCustomerService.getCustomer();\n setData((prev) => ({ ...prev, customer }));\n setErrors((prev) => ({ ...prev, customer: null }));\n setNoCustomerExists(false);\n } catch (error: unknown) {\n console.error(\"[BillingDashboard] Failed to load customer:\", error);\n // Check if this is a \"not found\" error indicating no customer exists\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes(\"Not Found\") || errorMessage.includes(\"not found\")) {\n setNoCustomerExists(true);\n // Stop loading all sections since no customer exists\n setLoading({\n customer: false,\n subscriptions: false,\n paymentMethods: false,\n invoices: false,\n usage: false,\n });\n return; // Don't try to fetch other data\n }\n setErrors((prev) => ({ ...prev, customer: \"Failed to load billing account\" }));\n } finally {\n setLoading((prev) => ({ ...prev, customer: false }));\n }\n\n // If we have a customer, fetch the rest of the data\n if (customer) {\n // Fetch subscriptions\n const fetchSubscriptions = async () => {\n try {\n const subscriptions = await StripeSubscriptionService.listSubscriptions();\n setData((prev) => ({ ...prev, subscriptions }));\n setErrors((prev) => ({ ...prev, subscriptions: null }));\n return subscriptions;\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to load subscriptions:\", error);\n setErrors((prev) => ({ ...prev, subscriptions: \"Failed to load subscriptions\" }));\n return [];\n } finally {\n setLoading((prev) => ({ ...prev, subscriptions: false }));\n }\n };\n\n // Fetch payment methods\n const fetchPaymentMethods = async () => {\n try {\n const paymentMethods = await StripeCustomerService.listPaymentMethods();\n setData((prev) => ({ ...prev, paymentMethods }));\n setErrors((prev) => ({ ...prev, paymentMethods: null }));\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to load payment methods:\", error);\n setErrors((prev) => ({ ...prev, paymentMethods: \"Failed to load payment methods\" }));\n } finally {\n setLoading((prev) => ({ ...prev, paymentMethods: false }));\n }\n };\n\n // Fetch invoices\n const fetchInvoices = async () => {\n try {\n const invoices = await StripeInvoiceService.listInvoices();\n setData((prev) => ({ ...prev, invoices }));\n setErrors((prev) => ({ ...prev, invoices: null }));\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to load invoices:\", error);\n setErrors((prev) => ({ ...prev, invoices: \"Failed to load invoices\" }));\n } finally {\n setLoading((prev) => ({ ...prev, invoices: false }));\n }\n };\n\n // Execute all in parallel\n const [subscriptions] = await Promise.all([fetchSubscriptions(), fetchPaymentMethods(), fetchInvoices()]);\n\n // Check if there are metered subscriptions and fetch usage data\n const hasMetered = subscriptions.some(\n (sub: StripeSubscriptionInterface) => sub.price?.recurring?.usageType === \"metered\",\n );\n\n if (hasMetered) {\n await fetchUsageData();\n } else {\n setLoading((prev) => ({ ...prev, usage: false }));\n }\n }\n }, []);\n\n // Create a new Stripe customer for the company\n const handleCreateCustomer = async () => {\n setCreatingCustomer(true);\n try {\n await StripeCustomerService.createCustomer();\n setNoCustomerExists(false);\n // Refresh all data after customer creation\n await fetchAllData();\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to create customer:\", error);\n setErrors((prev) => ({ ...prev, customer: \"Failed to set up billing\" }));\n } finally {\n setCreatingCustomer(false);\n }\n };\n\n // Fetch usage data (called conditionally)\n const fetchUsageData = async () => {\n try {\n const meters = await StripeUsageService.listMeters();\n setData((prev) => ({ ...prev, meters }));\n\n // Load summaries for each meter (current month)\n const summariesMap: Record<string, MeterSummaryInterface | null> = {};\n const now = new Date();\n const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);\n const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);\n\n for (const meter of meters) {\n try {\n const meterSummaries = await StripeUsageService.getMeterSummaries({\n meterId: meter.id,\n startTime: startOfMonth,\n endTime: endOfMonth,\n });\n summariesMap[meter.id] = meterSummaries.length > 0 ? meterSummaries[0] : null;\n } catch (error) {\n console.error(`[BillingDashboard] Failed to load summaries for meter ${meter.id}:`, error);\n summariesMap[meter.id] = null;\n }\n }\n\n setData((prev) => ({ ...prev, meterSummaries: summariesMap }));\n setErrors((prev) => ({ ...prev, usage: null }));\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to load usage data:\", error);\n setErrors((prev) => ({ ...prev, usage: \"Failed to load usage data\" }));\n } finally {\n setLoading((prev) => ({ ...prev, usage: false }));\n }\n };\n\n // Refresh data after modal actions\n const refreshData = useCallback(async () => {\n // Reset loading states for a refresh\n setLoading({\n customer: true,\n subscriptions: true,\n paymentMethods: true,\n invoices: true,\n usage: true,\n });\n await fetchAllData();\n }, [fetchAllData]);\n\n // Handler to open wizard (can be called from SubscriptionsContainer)\n const handleOpenWizard = useCallback((subscription?: StripeSubscriptionInterface) => {\n setEditingSubscription(subscription || null);\n setShowWizard(true);\n }, []);\n\n // Handler to close wizard\n const handleWizardClose = useCallback(() => {\n setShowWizard(false);\n setEditingSubscription(null);\n refreshData();\n }, [refreshData]);\n\n // Initial data load\n useEffect(() => {\n fetchAllData();\n }, [fetchAllData]);\n\n // Handle URL action parameter for deep linking\n useEffect(() => {\n const action = searchParams.get(\"action\");\n if (action === \"subscribe\") {\n // Open wizard directly (no wrapper modal)\n setShowWizard(true);\n // Clear the URL param to prevent re-triggering on refresh\n window.history.replaceState({}, \"\", window.location.pathname);\n }\n }, [searchParams]);\n\n // Detect critical subscriptions for alert banners\n const criticalSubscriptions = data.subscriptions.filter(\n (sub) =>\n sub.status === SubscriptionStatus.PAST_DUE ||\n (sub.status === SubscriptionStatus.TRIALING &&\n sub.trialEnd &&\n new Date(sub.trialEnd).getTime() - new Date().getTime() <= 7 * 24 * 60 * 60 * 1000),\n );\n\n // Handle modal close with refresh\n const handleModalClose = (open: boolean) => {\n if (!open) {\n setActiveModal(null);\n refreshData();\n }\n };\n\n // Get modal title based on type\n const getModalTitle = (type: ModalType): string => {\n switch (type) {\n case \"subscriptions\":\n return \"Manage Subscriptions\";\n case \"payment-methods\":\n return \"Payment Methods\";\n case \"invoices\":\n return \"Invoice History\";\n case \"usage\":\n return \"Usage Tracking\";\n default:\n return \"\";\n }\n };\n\n // Show loading state while checking for customer\n const isInitialLoading = loading.customer && !noCustomerExists && !data.customer;\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center gap-x-3\">\n <Wallet className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Billing</h1>\n </div>\n\n {/* Initial Loading State */}\n {isInitialLoading && (\n <Card>\n <CardContent className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </CardContent>\n </Card>\n )}\n\n {/* No Customer State - Show Setup Prompt */}\n {noCustomerExists && !isInitialLoading && (\n <Card>\n <CardHeader className=\"text-center\">\n <div className=\"mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10\">\n <CreditCard className=\"h-8 w-8 text-primary\" />\n </div>\n <CardTitle>Set Up Billing</CardTitle>\n <CardDescription>\n Your company doesn't have a billing account yet. Set one up to manage subscriptions, payment methods,\n and view invoices.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"flex justify-center pb-8\">\n <Button onClick={handleCreateCustomer} disabled={creatingCustomer} size=\"lg\">\n {creatingCustomer ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Setting up...\n </>\n ) : (\n \"Set Up Billing Account\"\n )}\n </Button>\n </CardContent>\n {errors.customer && (\n <CardContent className=\"pt-0\">\n <p className=\"text-center text-sm text-destructive\">{errors.customer}</p>\n </CardContent>\n )}\n </Card>\n )}\n\n {/* Main Dashboard Content - Only shown when customer exists */}\n {!noCustomerExists && !isInitialLoading && (\n <>\n {/* Alert Banners */}\n {criticalSubscriptions.map((subscription) => (\n <BillingAlertBanner\n key={subscription.id}\n subscription={subscription}\n onUpdatePayment={() => setActiveModal(\"payment-methods\")}\n onAddPayment={() => setActiveModal(\"payment-methods\")}\n />\n ))}\n\n {/* Summary Cards Grid */}\n <div className=\"grid gap-4 md:grid-cols-2\">\n <SubscriptionSummaryCard\n subscriptions={data.subscriptions}\n loading={loading.subscriptions}\n error={errors.subscriptions || undefined}\n onManageClick={() => {\n if (data.subscriptions.length === 0) {\n // No subscriptions - open wizard directly\n setShowWizard(true);\n } else {\n // Has subscriptions - open manage modal\n setActiveModal(\"subscriptions\");\n }\n }}\n />\n\n <PaymentMethodSummaryCard\n paymentMethods={data.paymentMethods}\n defaultPaymentMethodId={data.customer?.defaultPaymentMethodId}\n loading={loading.paymentMethods}\n error={errors.paymentMethods || undefined}\n onManageClick={() => setActiveModal(\"payment-methods\")}\n />\n\n <CustomerInfoCard\n customer={data.customer}\n loading={loading.customer}\n error={errors.customer || undefined}\n />\n\n <InvoicesSummaryCard\n invoices={data.invoices}\n loading={loading.invoices}\n error={errors.invoices || undefined}\n onViewAllClick={() => setActiveModal(\"invoices\")}\n />\n\n {/* Usage Card - only shown when metered subscriptions exist */}\n {hasMeteredSubscriptions() && (\n <BillingUsageSummaryCard\n meters={data.meters}\n summaries={data.meterSummaries}\n loading={loading.usage}\n error={errors.usage || undefined}\n onViewDetailsClick={() => setActiveModal(\"usage\")}\n />\n )}\n </div>\n\n {/* Detail Modals */}\n <BillingDetailModal\n open={activeModal === \"subscriptions\"}\n onOpenChange={handleModalClose}\n title={getModalTitle(\"subscriptions\")}\n >\n <SubscriptionsContainer onOpenWizard={handleOpenWizard} />\n </BillingDetailModal>\n\n <BillingDetailModal\n open={activeModal === \"payment-methods\"}\n onOpenChange={handleModalClose}\n title={getModalTitle(\"payment-methods\")}\n >\n <PaymentMethodsContainer />\n </BillingDetailModal>\n\n <BillingDetailModal\n open={activeModal === \"invoices\"}\n onOpenChange={handleModalClose}\n title={getModalTitle(\"invoices\")}\n >\n <InvoicesContainer />\n </BillingDetailModal>\n\n <BillingDetailModal\n open={activeModal === \"usage\"}\n onOpenChange={handleModalClose}\n title={getModalTitle(\"usage\")}\n >\n <UsageContainer />\n </BillingDetailModal>\n\n {/* Subscription Wizard - rendered at dashboard level to avoid nested dialogs */}\n <SubscriptionWizard\n open={showWizard}\n onOpenChange={(open) => !open && handleWizardClose()}\n onSuccess={refreshData}\n hasActiveRecurringSubscription={hasActiveRecurringSubscription}\n subscription={editingSubscription ?? undefined}\n />\n </>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { CreditCard } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { PaymentMethodInterface, StripeCustomerService } from \"../../data\";\nimport { PaymentMethodEditor } from \"../forms/PaymentMethodEditor\";\nimport { PaymentMethodsList } from \"../lists/PaymentMethodsList\";\n\nexport function PaymentMethodsContainer() {\n const [paymentMethods, setPaymentMethods] = useState<PaymentMethodInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [showAddPaymentMethod, setShowAddPaymentMethod] = useState<boolean>(false);\n\n const loadPaymentMethods = async () => {\n setLoading(true);\n try {\n const fetchedPaymentMethods = await StripeCustomerService.listPaymentMethods();\n setPaymentMethods(fetchedPaymentMethods);\n } catch (error) {\n console.error(\"[PaymentMethodsContainer] Failed to load payment methods:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadPaymentMethods();\n }, []);\n\n if (loading) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-muted-foreground\">Loading payment methods...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-x-3\">\n <CreditCard className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Payment Methods</h1>\n </div>\n <Button onClick={() => setShowAddPaymentMethod(true)}>Add Payment Method</Button>\n </div>\n\n {/* Empty State */}\n {paymentMethods.length === 0 && (\n <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\">\n <CreditCard className=\"h-16 w-16 text-muted-foreground\" />\n <div className=\"text-center\">\n <h3 className=\"mb-2 text-xl font-semibold\">No payment methods</h3>\n <p className=\"mb-4 text-muted-foreground\">\n Add a payment method to enable subscriptions and secure checkout.\n </p>\n <Button onClick={() => setShowAddPaymentMethod(true)}>Add Your First Card</Button>\n </div>\n </div>\n )}\n\n {/* Payment Methods List */}\n {paymentMethods.length > 0 && (\n <PaymentMethodsList paymentMethods={paymentMethods} onUpdate={loadPaymentMethods} />\n )}\n\n {/* Add Payment Method Modal */}\n {showAddPaymentMethod && (\n <PaymentMethodEditor\n open={showAddPaymentMethod}\n onOpenChange={setShowAddPaymentMethod}\n onSuccess={loadPaymentMethods}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { CardElement, useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport { useEffect, useState } from \"react\";\nimport {\n Alert,\n AlertDescription,\n Button,\n Checkbox,\n Label,\n} from \"../../../../../shadcnui\";\nimport { StripeCustomerService } from \"../../data\";\n\ntype PaymentMethodFormProps = {\n onSuccess: () => void;\n onCancel: () => void;\n isLoading?: boolean;\n};\n\nexport function PaymentMethodForm({ onSuccess, onCancel, isLoading = false }: PaymentMethodFormProps) {\n const stripe = useStripe();\n const elements = useElements();\n\n const [setupIntent, setSetupIntent] = useState<{ clientSecret: string } | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [setAsDefault, setSetAsDefault] = useState<boolean>(true);\n\n // Fetch setup intent on component mount\n useEffect(() => {\n const fetchSetupIntent = async () => {\n setLoading(true);\n try {\n const intent = await StripeCustomerService.createSetupIntent();\n setSetupIntent(intent);\n } catch (err) {\n console.error(\"[PaymentMethodForm] Failed to create setup intent:\", err);\n setError(\"Failed to initialize payment form. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n fetchSetupIntent();\n }, []);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!stripe || !elements || !setupIntent) {\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n const cardElement = elements.getElement(CardElement);\n if (!cardElement) {\n throw new Error(\"Card element not found\");\n }\n\n // Confirm card setup with Stripe\n const { error: stripeError, setupIntent: confirmedSetupIntent } = await stripe.confirmCardSetup(\n setupIntent.clientSecret,\n {\n payment_method: {\n card: cardElement,\n },\n },\n );\n\n if (stripeError) {\n console.error(\"[PaymentMethodForm] Stripe error:\", stripeError);\n setError(stripeError.message || \"Failed to add payment method. Please check your card details.\");\n setIsSubmitting(false);\n return;\n }\n\n // Set as default if checkbox is checked\n if (setAsDefault && confirmedSetupIntent?.payment_method) {\n await StripeCustomerService.setDefaultPaymentMethod({\n paymentMethodId:\n typeof confirmedSetupIntent.payment_method === \"string\"\n ? confirmedSetupIntent.payment_method\n : confirmedSetupIntent.payment_method.id,\n });\n }\n\n onSuccess();\n } catch (err: any) {\n console.error(\"[PaymentMethodForm] Error:\", err);\n setError(err.message || \"An unexpected error occurred. Please try again.\");\n } finally {\n setIsSubmitting(false);\n }\n };\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center py-8\">\n <p className=\"text-muted-foreground\">Loading payment form...</p>\n </div>\n );\n }\n\n if (!setupIntent && error) {\n return (\n <Alert variant=\"destructive\" className=\"bg-red-50 border-red-200\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-y-4\">\n {/* Card Element */}\n <div className=\"rounded-md border border-gray-300 p-3\">\n <CardElement\n options={{\n style: {\n base: {\n fontSize: \"16px\",\n color: \"#424770\",\n \"::placeholder\": {\n color: \"#aab7c4\",\n },\n },\n invalid: {\n color: \"#9e2146\",\n },\n },\n }}\n />\n </div>\n\n {/* Set as Default Checkbox */}\n <div className=\"flex items-center gap-x-2\">\n <Checkbox\n id=\"setAsDefault\"\n checked={setAsDefault}\n onCheckedChange={(checked) => setSetAsDefault(!!checked)}\n />\n <Label htmlFor=\"setAsDefault\" className=\"text-sm font-normal\">\n Set as default payment method\n </Label>\n </div>\n\n {/* Error Alert */}\n {error && (\n <Alert variant=\"destructive\" className=\"bg-red-50 border-red-200\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n )}\n\n {/* Action Buttons */}\n <div className=\"flex justify-end gap-x-2\">\n <Button type=\"button\" variant=\"outline\" onClick={onCancel} disabled={isSubmitting || isLoading}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={!stripe || isSubmitting || isLoading}>\n {isSubmitting ? \"Processing...\" : \"Add Card\"}\n </Button>\n </div>\n </form>\n );\n}\n","\"use client\";\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../../../../../shadcnui\";\nimport { PaymentMethodForm } from \"./PaymentMethodForm\";\n\ntype PaymentMethodEditorProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n};\n\nexport function PaymentMethodEditor({ open, onOpenChange, onSuccess }: PaymentMethodEditorProps) {\n const handleSuccess = () => {\n onSuccess();\n onOpenChange(false);\n };\n\n const handleCancel = () => {\n onOpenChange(false);\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Add Payment Method</DialogTitle>\n <DialogDescription>\n Add a new payment method to your account. Your card information is securely processed by Stripe.\n </DialogDescription>\n </DialogHeader>\n {open && (\n <PaymentMethodForm\n onSuccess={handleSuccess}\n onCancel={handleCancel}\n />\n )}\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { MoreVertical } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"../../../../../shadcnui\";\nimport { PaymentMethodInterface, StripeCustomerInterface, StripeCustomerService } from \"../../data\";\n\ntype PaymentMethodCardProps = {\n paymentMethod: PaymentMethodInterface;\n onUpdate: () => void;\n};\n\n// Card brand icons mapping\nconst brandIcons: Record<string, string> = {\n visa: \"💳\",\n mastercard: \"💳\",\n amex: \"💳\",\n discover: \"💳\",\n};\n\nexport function PaymentMethodCard({ paymentMethod, onUpdate }: PaymentMethodCardProps) {\n const [loading, setLoading] = useState<boolean>(false);\n const [customer, setCustomer] = useState<StripeCustomerInterface | null>(null);\n const [showRemoveDialog, setShowRemoveDialog] = useState<boolean>(false);\n\n // Load customer to check default payment method\n useEffect(() => {\n const loadCustomer = async () => {\n try {\n const fetchedCustomer = await StripeCustomerService.getCustomer();\n setCustomer(fetchedCustomer);\n } catch (error) {\n console.error(\"[PaymentMethodCard] Failed to load customer:\", error);\n }\n };\n\n loadCustomer();\n }, []);\n\n const isDefault = customer?.defaultPaymentMethodId === paymentMethod.id;\n const brand = paymentMethod.card?.brand || \"card\";\n const last4 = paymentMethod.card?.last4 || \"****\";\n const expMonth = paymentMethod.card?.expMonth || 0;\n const expYear = paymentMethod.card?.expYear || 0;\n const brandIcon = brandIcons[brand.toLowerCase()] || \"💳\";\n\n const handleSetDefault = async () => {\n setLoading(true);\n try {\n await StripeCustomerService.setDefaultPaymentMethod({ paymentMethodId: paymentMethod.id });\n onUpdate();\n } catch (error) {\n console.error(\"[PaymentMethodCard] Failed to set as default:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n const handleRemove = async () => {\n setLoading(true);\n try {\n await StripeCustomerService.removePaymentMethod({ paymentMethodId: paymentMethod.id });\n setShowRemoveDialog(false);\n onUpdate();\n } catch (error) {\n console.error(\"[PaymentMethodCard] Failed to remove:\", error);\n setLoading(false);\n }\n };\n\n return (\n <>\n <Card className=\"relative\">\n {/* Default Badge */}\n {isDefault && (\n <Badge className=\"absolute right-2 top-2 bg-green-100 text-green-800 hover:bg-green-100\">Default</Badge>\n )}\n\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <div className=\"flex items-center gap-x-2\">\n <span className=\"text-2xl\">{brandIcon}</span>\n <span className=\"text-sm font-medium capitalize\">{brand}</span>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger>\n <Button render={<div />} nativeButton={false} variant=\"ghost\" size=\"sm\" disabled={loading} className=\"h-8 w-8 p-0\">\n <MoreVertical className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {!isDefault && (\n <DropdownMenuItem onClick={handleSetDefault} disabled={loading}>\n Set as Default\n </DropdownMenuItem>\n )}\n <DropdownMenuItem onClick={() => setShowRemoveDialog(true)} disabled={loading} className=\"text-red-600\">\n Remove\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </CardHeader>\n\n <CardContent>\n <div className=\"flex flex-col gap-y-1\">\n <p className=\"text-lg font-semibold\">•••• {last4}</p>\n <p className=\"text-sm text-muted-foreground\">\n Expires {String(expMonth).padStart(2, \"0\")}/{expYear}\n </p>\n </div>\n </CardContent>\n </Card>\n\n {/* Remove Confirmation Dialog */}\n <AlertDialog open={showRemoveDialog} onOpenChange={setShowRemoveDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Remove Payment Method</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to remove this payment method? This action cannot be undone.\n {isDefault && \" This is your default payment method.\"}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={loading}>Cancel</AlertDialogCancel>\n <AlertDialogAction onClick={handleRemove} disabled={loading} className=\"bg-red-600 hover:bg-red-700\">\n {loading ? \"Removing...\" : \"Remove\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n","\"use client\";\n\nimport { PaymentMethodInterface } from \"../../data\";\nimport { PaymentMethodCard } from \"../details/PaymentMethodCard\";\n\ntype PaymentMethodsListProps = {\n paymentMethods: PaymentMethodInterface[];\n onUpdate: () => void;\n};\n\nexport function PaymentMethodsList({ paymentMethods, onUpdate }: PaymentMethodsListProps) {\n return (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {paymentMethods.map((paymentMethod) => (\n <PaymentMethodCard key={paymentMethod.id} paymentMethod={paymentMethod} onUpdate={onUpdate} />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Tabs, TabsList, TabsTrigger } from \"../../../../../shadcnui\";\nimport { InvoiceStatus, StripeInvoiceInterface } from \"../../data/stripe-invoice.interface\";\nimport { StripeInvoiceService } from \"../../data/stripe-invoice.service\";\nimport { InvoicesList } from \"../lists/InvoicesList\";\n\ntype StatusFilter = InvoiceStatus | \"all\";\n\nexport function InvoicesContainer() {\n const [invoices, setInvoices] = useState<StripeInvoiceInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [statusFilter, setStatusFilter] = useState<StatusFilter>(\"all\");\n\n const loadInvoices = async () => {\n setLoading(true);\n try {\n const params = statusFilter !== \"all\" ? { status: statusFilter } : undefined;\n const data = await StripeInvoiceService.listInvoices(params);\n setInvoices(data);\n } catch (error) {\n console.error(\"[InvoicesContainer] Failed to load invoices:\", error);\n setInvoices([]);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadInvoices();\n }, [statusFilter]);\n\n const handleFilterChange = (value: string) => {\n setStatusFilter(value as StatusFilter);\n };\n\n return (\n <div className=\"space-y-4\">\n {/* Status Filter Tabs */}\n <Tabs value={statusFilter} onValueChange={handleFilterChange}>\n <TabsList>\n <TabsTrigger value=\"all\">All</TabsTrigger>\n <TabsTrigger value={InvoiceStatus.PAID}>Paid</TabsTrigger>\n <TabsTrigger value={InvoiceStatus.OPEN}>Open</TabsTrigger>\n <TabsTrigger value={InvoiceStatus.VOID}>Void</TabsTrigger>\n <TabsTrigger value={InvoiceStatus.UNCOLLECTIBLE}>Uncollectible</TabsTrigger>\n </TabsList>\n </Tabs>\n\n {/* Loading State */}\n {loading && <div className=\"text-center py-8 text-muted-foreground\">Loading invoices...</div>}\n\n {/* Empty State */}\n {!loading && invoices.length === 0 && (\n <div className=\"border border-dashed border-gray-300 rounded-lg p-8 text-center\">\n <p className=\"text-lg font-medium text-muted-foreground mb-2\">No invoices yet</p>\n <p className=\"text-sm text-muted-foreground\">Invoices will appear here after your first billing cycle</p>\n </div>\n )}\n\n {/* Invoices List */}\n {!loading && invoices.length > 0 && <InvoicesList invoices={invoices} onInvoicesChange={loadInvoices} />}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\nimport { StripeInvoiceInterface } from \"../../data/stripe-invoice.interface\";\nimport { InvoiceDetails } from \"../details/InvoiceDetails\";\nimport { InvoiceStatusBadge } from \"../widgets/InvoiceStatusBadge\";\n\ntype InvoicesListProps = {\n invoices: StripeInvoiceInterface[];\n onInvoicesChange: () => void;\n};\n\nexport function InvoicesList({ invoices, onInvoicesChange }: InvoicesListProps) {\n const [selectedInvoice, setSelectedInvoice] = useState<StripeInvoiceInterface | null>(null);\n\n const handleRowClick = (invoice: StripeInvoiceInterface) => {\n setSelectedInvoice(invoice);\n };\n\n const getInvoiceNumber = (invoice: StripeInvoiceInterface): string => {\n if (invoice.stripeInvoiceNumber) {\n return invoice.stripeInvoiceNumber;\n }\n // Use last 8 characters of stripeInvoiceId as fallback\n return invoice.stripeInvoiceId.slice(-8);\n };\n\n return (\n <>\n <div className=\"border rounded-lg overflow-hidden\">\n <Table>\n <TableHeader className=\"bg-muted\">\n <TableRow>\n <TableHead>Invoice #</TableHead>\n <TableHead>Date</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Amount</TableHead>\n <TableHead>Period</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {invoices.map((invoice) => {\n const invoiceNumber = getInvoiceNumber(invoice);\n const date = formatDate(invoice.periodStart);\n const amount = formatCurrency(invoice.total, invoice.currency);\n const period = `${formatDate(invoice.periodStart)} - ${formatDate(invoice.periodEnd)}`;\n\n return (\n <TableRow\n key={invoice.id}\n onClick={() => handleRowClick(invoice)}\n className=\"cursor-pointer hover:bg-muted/50\"\n >\n <TableCell className=\"font-medium\">{invoiceNumber}</TableCell>\n <TableCell className=\"text-muted-foreground text-sm\">{date}</TableCell>\n <TableCell>\n <InvoiceStatusBadge status={invoice.status} />\n </TableCell>\n <TableCell className=\"text-right font-medium\">{amount}</TableCell>\n <TableCell className=\"text-muted-foreground text-sm\">{period}</TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n\n {/* Invoice Details Dialog */}\n {selectedInvoice && (\n <InvoiceDetails\n invoice={selectedInvoice}\n open={!!selectedInvoice}\n onOpenChange={(open) => !open && setSelectedInvoice(null)}\n onInvoiceChange={() => {\n onInvoicesChange();\n setSelectedInvoice(null);\n }}\n />\n )}\n </>\n );\n}\n","import { StripePriceInterface } from \"../../stripe-price/data/stripe-price.interface\";\n\n/**\n * Format price recurring interval for display\n * @param price - Stripe price object\n * @returns Formatted interval string (e.g., \"/month\", \"/year\", \"/2 weeks\", \"one-time\")\n */\nexport function formatInterval(price: StripePriceInterface): string {\n if (price.priceType === \"one_time\" || !price.recurring) {\n return \"one-time\";\n }\n\n const { interval, intervalCount } = price.recurring;\n\n if (intervalCount === 1) {\n return `/${interval}`;\n }\n\n // Pluralize the interval for counts > 1\n const pluralInterval =\n interval === \"day\" ? \"days\" : interval === \"week\" ? \"weeks\" : interval === \"month\" ? \"months\" : \"years\";\n return `/${intervalCount} ${pluralInterval}`;\n}\n\n/**\n * Format currency amount from cents to localized currency string\n * @param amount - Amount in cents\n * @param currency - Currency code (e.g., \"USD\", \"EUR\", \"GBP\")\n * @returns Formatted currency string (e.g., \"$9.99\", \"€9,99\")\n */\nexport function formatCurrency(amount: number | undefined, currency: string): string {\n if (amount === undefined) return \"$0.00\";\n\n // Convert cents to dollars\n const dollars = amount / 100;\n\n try {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: currency.toUpperCase(),\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(dollars);\n } catch (error) {\n console.error(\"Error formatting currency:\", error);\n // Fallback if currency code is invalid\n return `$${dollars.toFixed(2)}`;\n }\n}\n","/**\n * Format a date to a localized date string\n * @param date - Date object or ISO string\n * @returns Formatted date string (e.g., \"Jan 15, 2025\")\n */\nexport function formatDate(date: Date | string | undefined): string {\n if (!date) return \"N/A\";\n\n const dateObj = typeof date === \"string\" ? new Date(date) : date;\n\n try {\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n }).format(dateObj);\n } catch (error) {\n console.error(\"Error formatting date:\", error);\n return \"Invalid Date\";\n }\n}\n","\"use client\";\n\nimport { Download, ExternalLink, RefreshCw } from \"lucide-react\";\nimport { Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\nimport { InvoiceStatus, StripeInvoiceInterface } from \"../../data/stripe-invoice.interface\";\nimport { InvoiceStatusBadge } from \"../widgets/InvoiceStatusBadge\";\n\ntype InvoiceDetailsProps = {\n invoice: StripeInvoiceInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onInvoiceChange: () => void;\n};\n\nexport function InvoiceDetails({ invoice, open, onOpenChange, onInvoiceChange }: InvoiceDetailsProps) {\n const handleDownloadPDF = () => {\n if (invoice.stripePdfUrl) {\n window.open(invoice.stripePdfUrl, \"_blank\");\n }\n };\n\n const handleRetryPayment = async () => {\n // TODO: Implement retry payment logic\n };\n\n const handleViewInStripe = () => {\n if (invoice.stripeHostedInvoiceUrl) {\n window.open(invoice.stripeHostedInvoiceUrl, \"_blank\");\n }\n };\n\n const getInvoiceNumber = (): string => {\n if (invoice.stripeInvoiceNumber) {\n return invoice.stripeInvoiceNumber;\n }\n return invoice.stripeInvoiceId.slice(-8);\n };\n\n const productName = invoice.subscription?.price?.product?.name || \"Subscription\";\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>Invoice {getInvoiceNumber()}</DialogTitle>\n <DialogDescription>{formatDate(invoice.periodStart)}</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-6\">\n {/* Status */}\n <div className=\"flex items-center gap-x-3\">\n <span className=\"text-sm font-medium text-muted-foreground\">Status:</span>\n <InvoiceStatusBadge status={invoice.status} />\n </div>\n\n {/* Invoice Info Grid */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <span className=\"text-sm font-medium text-muted-foreground\">Billing Period:</span>\n <p className=\"font-medium\">\n {formatDate(invoice.periodStart)} - {formatDate(invoice.periodEnd)}\n </p>\n </div>\n\n {invoice.dueDate && (\n <div>\n <span className=\"text-sm font-medium text-muted-foreground\">Due Date:</span>\n <p className=\"font-medium\">{formatDate(invoice.dueDate)}</p>\n </div>\n )}\n\n {invoice.paidAt && (\n <div>\n <span className=\"text-sm font-medium text-muted-foreground\">Paid Date:</span>\n <p className=\"font-medium\">{formatDate(invoice.paidAt)}</p>\n </div>\n )}\n\n <div>\n <span className=\"text-sm font-medium text-muted-foreground\">Attempt Count:</span>\n <p className=\"font-medium\">{invoice.attemptCount}</p>\n </div>\n </div>\n\n {/* Line Items */}\n <div>\n <h4 className=\"text-sm font-medium text-muted-foreground mb-2\">Line Items</h4>\n <div className=\"border rounded-lg overflow-hidden\">\n <table className=\"w-full\">\n <thead className=\"bg-muted\">\n <tr>\n <th className=\"text-left p-3 text-sm font-medium\">Description</th>\n <th className=\"text-right p-3 text-sm font-medium\">Amount</th>\n </tr>\n </thead>\n <tbody>\n <tr className=\"border-t\">\n <td className=\"p-3\">{productName}</td>\n <td className=\"p-3 text-right\">{formatCurrency(invoice.subtotal, invoice.currency)}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Amount Breakdown */}\n <div className=\"space-y-2 border-t pt-4\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Subtotal:</span>\n <span className=\"font-medium\">{formatCurrency(invoice.subtotal, invoice.currency)}</span>\n </div>\n\n {invoice.tax !== undefined && invoice.tax > 0 && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Tax:</span>\n <span className=\"font-medium\">{formatCurrency(invoice.tax, invoice.currency)}</span>\n </div>\n )}\n\n <div className=\"flex justify-between text-lg font-semibold border-t pt-2\">\n <span>Total:</span>\n <span>{formatCurrency(invoice.total, invoice.currency)}</span>\n </div>\n\n {invoice.amountPaid > 0 && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Amount Paid:</span>\n <span className=\"font-medium text-green-600\">\n {formatCurrency(invoice.amountPaid, invoice.currency)}\n </span>\n </div>\n )}\n\n {invoice.amountRemaining > 0 && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Amount Due:</span>\n <span className=\"font-medium text-red-600\">\n {formatCurrency(invoice.amountRemaining, invoice.currency)}\n </span>\n </div>\n )}\n </div>\n\n {/* Action Buttons */}\n <div className=\"flex flex-wrap gap-2 pt-4 border-t\">\n {invoice.stripePdfUrl && (\n <Button variant=\"outline\" onClick={handleDownloadPDF}>\n <Download className=\"mr-2 h-4 w-4\" />\n Download PDF\n </Button>\n )}\n\n {invoice.status === InvoiceStatus.OPEN && invoice.attempted && (\n <Button variant=\"default\" onClick={handleRetryPayment}>\n <RefreshCw className=\"mr-2 h-4 w-4\" />\n Retry Payment\n </Button>\n )}\n\n {invoice.stripeHostedInvoiceUrl && (\n <Button variant=\"outline\" onClick={handleViewInStripe}>\n <ExternalLink className=\"mr-2 h-4 w-4\" />\n View in Stripe\n </Button>\n )}\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { InvoiceStatus } from \"../../data/stripe-invoice.interface\";\n\ntype InvoiceStatusBadgeProps = {\n status: InvoiceStatus;\n};\n\ntype StatusConfig = {\n label: string;\n color: string;\n};\n\nconst statusConfig: Record<InvoiceStatus, StatusConfig> = {\n [InvoiceStatus.DRAFT]: {\n label: \"Draft\",\n color: \"bg-gray-100 text-gray-800\",\n },\n [InvoiceStatus.OPEN]: {\n label: \"Open\",\n color: \"bg-blue-100 text-blue-800\",\n },\n [InvoiceStatus.PAID]: {\n label: \"Paid\",\n color: \"bg-green-100 text-green-800\",\n },\n [InvoiceStatus.VOID]: {\n label: \"Void\",\n color: \"bg-gray-100 text-gray-800\",\n },\n [InvoiceStatus.UNCOLLECTIBLE]: {\n label: \"Uncollectible\",\n color: \"bg-red-100 text-red-800\",\n },\n};\n\nexport function InvoiceStatusBadge({ status }: InvoiceStatusBadgeProps) {\n const config = statusConfig[status] || statusConfig[InvoiceStatus.DRAFT];\n\n return <span className={`${config.color} text-xs px-2 py-1 rounded-full font-medium`}>{config.label}</span>;\n}\n","\"use client\";\n\nimport { CreditCard } from \"lucide-react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { BillingAlertBanner } from \"../../../components\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService, SubscriptionStatus } from \"../../data\";\nimport { SubscriptionsList } from \"../lists\";\n\ntype SubscriptionsContainerProps = {\n onOpenWizard?: (subscription?: StripeSubscriptionInterface) => void;\n};\n\nexport function SubscriptionsContainer({ onOpenWizard }: SubscriptionsContainerProps) {\n const [subscriptions, setSubscriptions] = useState<StripeSubscriptionInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n\n const loadSubscriptions = useCallback(async () => {\n setLoading(true);\n try {\n const fetchedSubscriptions = await StripeSubscriptionService.listSubscriptions();\n setSubscriptions(fetchedSubscriptions);\n } catch (error) {\n console.error(\"[SubscriptionsContainer] Failed to load subscriptions:\", error);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n loadSubscriptions();\n }, []);\n\n // Detect critical subscriptions\n const criticalSubscriptions = subscriptions.filter(\n (sub) =>\n sub.status === SubscriptionStatus.PAST_DUE ||\n (sub.status === SubscriptionStatus.TRIALING &&\n sub.trialEnd &&\n new Date(sub.trialEnd).getTime() - new Date().getTime() <= 7 * 24 * 60 * 60 * 1000),\n );\n\n if (loading) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-muted-foreground\">Loading subscriptions...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-x-3\">\n <CreditCard className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Subscriptions</h1>\n </div>\n {subscriptions.length > 0 && (\n <Button onClick={() => onOpenWizard?.()}>Subscribe to a Plan</Button>\n )}\n </div>\n\n {/* Alert Banners */}\n {criticalSubscriptions.map((subscription) => (\n <BillingAlertBanner key={subscription.id} subscription={subscription} />\n ))}\n\n {/* Empty state CTA */}\n {subscriptions.length === 0 && (\n <div className=\"flex flex-col items-center justify-center py-12 space-y-4\">\n <CreditCard className=\"h-16 w-16 text-muted-foreground\" />\n <div className=\"text-center\">\n <h3 className=\"text-xl font-semibold mb-2\">No Active Subscriptions</h3>\n <p className=\"text-muted-foreground mb-6\">\n Choose a subscription plan to get started with our services.\n </p>\n <Button onClick={() => onOpenWizard?.()}>Subscribe to a Plan</Button>\n </div>\n </div>\n )}\n\n {/* Subscriptions List */}\n {subscriptions.length > 0 && (\n <SubscriptionsList\n subscriptions={subscriptions}\n onSubscriptionsChange={loadSubscriptions}\n onChangePlan={(sub) => onOpenWizard?.(sub)}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { StripeSubscriptionInterface } from \"../../data\";\nimport { SubscriptionDetails } from \"../details/SubscriptionDetails\";\nimport { SubscriptionStatusBadge } from \"../widgets/SubscriptionStatusBadge\";\n\n/**\n * Formats the plan name from price data.\n * Format: \"Product Name - Nickname (Interval)\" e.g., \"Only 35 - Pro (Monthly)\"\n */\nfunction formatPlanName(price: StripePriceInterface | undefined): string {\n if (!price) return \"N/A\";\n\n const productName = price.product?.name || \"\";\n const nickname = price.nickname || \"\";\n\n // Format interval: \"month\" -> \"Monthly\", \"year\" -> \"Yearly\", etc.\n let interval = \"\";\n if (price.recurring?.interval) {\n const intervalMap: Record<string, string> = {\n day: \"Daily\",\n week: \"Weekly\",\n month: \"Monthly\",\n year: \"Yearly\",\n };\n interval = intervalMap[price.recurring.interval] || price.recurring.interval;\n }\n\n // Build the plan label: \"Product - Nickname\" or just \"Product\"\n const parts = [productName, nickname].filter(Boolean);\n const planLabel = parts.join(\" - \");\n\n // Add interval in parentheses if available\n return interval ? `${planLabel} (${interval})` : planLabel || \"N/A\";\n}\n\ntype SubscriptionsListProps = {\n subscriptions: StripeSubscriptionInterface[];\n onSubscriptionsChange: () => void;\n onChangePlan?: (subscription: StripeSubscriptionInterface) => void;\n};\n\nexport function SubscriptionsList({ subscriptions, onSubscriptionsChange, onChangePlan }: SubscriptionsListProps) {\n const [selectedSub, setSelectedSub] = useState<StripeSubscriptionInterface | null>(null);\n\n const handleRowClick = (subscription: StripeSubscriptionInterface) => {\n setSelectedSub(subscription);\n };\n\n return (\n <>\n <div className=\"border rounded-lg overflow-hidden\">\n <Table>\n <TableHeader className=\"bg-muted\">\n <TableRow>\n <TableHead>Status</TableHead>\n <TableHead>Plan</TableHead>\n <TableHead>Period</TableHead>\n <TableHead className=\"text-right\">Amount</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {subscriptions.map((subscription) => {\n const price = subscription.price;\n const amount = price?.unitAmount ? formatCurrency(price.unitAmount, price.currency) : \"N/A\";\n const period = `${formatDate(subscription.currentPeriodStart)} - ${formatDate(subscription.currentPeriodEnd)}`;\n\n return (\n <TableRow\n key={subscription.id}\n onClick={() => handleRowClick(subscription)}\n className=\"cursor-pointer hover:bg-muted/50\"\n >\n <TableCell>\n <SubscriptionStatusBadge status={subscription.status} cancelAtPeriodEnd={subscription.cancelAtPeriodEnd} />\n </TableCell>\n <TableCell className=\"font-medium\">{formatPlanName(price)}</TableCell>\n <TableCell className=\"text-muted-foreground text-sm\">{period}</TableCell>\n <TableCell className=\"text-right font-medium\">{amount}</TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n\n {/* Subscription Details Dialog */}\n {selectedSub && (\n <SubscriptionDetails\n subscription={selectedSub}\n open={!!selectedSub}\n onOpenChange={(open) => !open && setSelectedSub(null)}\n onSubscriptionChange={() => {\n onSubscriptionsChange();\n setSelectedSub(null);\n }}\n onChangePlan={\n onChangePlan\n ? (sub) => {\n setSelectedSub(null); // Close details dialog first\n onChangePlan(sub); // Then open wizard at parent level\n }\n : undefined\n }\n />\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\nimport { StripeCustomerService } from \"../../../stripe-customer\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService, SubscriptionStatus } from \"../../data\";\nimport { CancelSubscriptionDialog } from \"../forms/CancelSubscriptionDialog\";\nimport { SubscriptionStatusBadge } from \"../widgets/SubscriptionStatusBadge\";\n\n/**\n * Formats the plan name from price data.\n * Format: \"Product Name - Nickname (Interval)\" e.g., \"Only 35 - Pro (Monthly)\"\n */\nfunction formatPlanName(price: StripePriceInterface | undefined): string {\n if (!price) return \"N/A\";\n\n const productName = price.product?.name || \"\";\n const nickname = price.nickname || \"\";\n\n // Format interval: \"month\" -> \"Monthly\", \"year\" -> \"Yearly\", etc.\n let interval = \"\";\n if (price.recurring?.interval) {\n const intervalMap: Record<string, string> = {\n day: \"Daily\",\n week: \"Weekly\",\n month: \"Monthly\",\n year: \"Yearly\",\n };\n interval = intervalMap[price.recurring.interval] || price.recurring.interval;\n }\n\n // Build the plan label: \"Product - Nickname\" or just \"Product\"\n const parts = [productName, nickname].filter(Boolean);\n const planLabel = parts.join(\" - \");\n\n // Add interval in parentheses if available\n return interval ? `${planLabel} (${interval})` : planLabel || \"N/A\";\n}\n\n/**\n * Formats the billing amount from price data.\n */\nfunction formatBillingAmount(price: StripePriceInterface | undefined): string {\n if (!price?.unitAmount) return \"N/A\";\n return formatCurrency(price.unitAmount, price.currency);\n}\n\ntype SubscriptionDetailsProps = {\n subscription: StripeSubscriptionInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSubscriptionChange: () => void;\n onChangePlan?: (subscription: StripeSubscriptionInterface) => void;\n};\n\nexport function SubscriptionDetails({\n subscription,\n open,\n onOpenChange,\n onSubscriptionChange,\n onChangePlan,\n}: SubscriptionDetailsProps) {\n const [showCancel, setShowCancel] = useState<boolean>(false);\n const [isProcessing, setIsProcessing] = useState<boolean>(false);\n\n const handlePause = async () => {\n setIsProcessing(true);\n try {\n await StripeSubscriptionService.pauseSubscription({ subscriptionId: subscription.id });\n onSubscriptionChange();\n } catch (error) {\n console.error(\"[SubscriptionDetails] Failed to pause subscription:\", error);\n } finally {\n setIsProcessing(false);\n }\n };\n\n const handleResume = async () => {\n setIsProcessing(true);\n try {\n await StripeSubscriptionService.resumeSubscription({ subscriptionId: subscription.id });\n onSubscriptionChange();\n } catch (error) {\n console.error(\"[SubscriptionDetails] Failed to resume subscription:\", error);\n } finally {\n setIsProcessing(false);\n }\n };\n\n const handleManageViaPortal = async () => {\n try {\n const { url } = await StripeCustomerService.createPortalSession();\n window.open(url, \"_blank\");\n } catch (error) {\n console.error(\"[SubscriptionDetails] Failed to create portal session:\", error);\n }\n };\n\n const canPause = subscription.status === SubscriptionStatus.ACTIVE;\n const canResume = subscription.status === SubscriptionStatus.PAUSED;\n const canCancel =\n subscription.status === SubscriptionStatus.ACTIVE ||\n subscription.status === SubscriptionStatus.TRIALING ||\n subscription.status === SubscriptionStatus.PAUSED;\n\n return (\n <>\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>Subscription Details</DialogTitle>\n <DialogDescription>View and manage your subscription</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-6\">\n {/* Status */}\n <div className=\"flex items-center gap-x-3\">\n <span className=\"text-sm font-medium text-muted-foreground\">Status:</span>\n <SubscriptionStatusBadge status={subscription.status} cancelAtPeriodEnd={subscription.cancelAtPeriodEnd} />\n </div>\n\n {/* Plan Info */}\n <div className=\"space-y-2\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Plan:</span>\n <span className=\"font-medium\">{formatPlanName(subscription.price)}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Billing Amount:</span>\n <span className=\"font-medium\">{formatBillingAmount(subscription.price)}</span>\n </div>\n </div>\n\n {/* Current Period */}\n <div className=\"space-y-2\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Current Period:</span>\n <span className=\"font-medium\">\n {formatDate(subscription.currentPeriodStart)} - {formatDate(subscription.currentPeriodEnd)}\n </span>\n </div>\n </div>\n\n {/* Trial Info */}\n {subscription.trialEnd && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Trial Ends:</span>\n <span className=\"font-medium\">{formatDate(subscription.trialEnd)}</span>\n </div>\n )}\n\n {/* Cancellation Warning */}\n {subscription.cancelAtPeriodEnd && (\n <div className=\"bg-yellow-50 border border-yellow-200 rounded-lg p-3\">\n <p className=\"text-sm text-yellow-800\">\n This subscription will be canceled at the end of the current period on{\" \"}\n {formatDate(subscription.currentPeriodEnd)}.\n </p>\n </div>\n )}\n\n {/* Action Buttons */}\n <div className=\"flex flex-wrap gap-2 pt-4 border-t\">\n {onChangePlan && (\n <Button variant=\"default\" onClick={() => onChangePlan(subscription)}>\n Change Plan\n </Button>\n )}\n\n {canPause && (\n <Button variant=\"outline\" onClick={handlePause} disabled={isProcessing}>\n {isProcessing ? \"Pausing...\" : \"Pause\"}\n </Button>\n )}\n\n {canResume && (\n <Button variant=\"outline\" onClick={handleResume} disabled={isProcessing}>\n {isProcessing ? \"Resuming...\" : \"Resume\"}\n </Button>\n )}\n\n {canCancel && (\n <Button variant=\"destructive\" onClick={() => setShowCancel(true)}>\n Cancel\n </Button>\n )}\n\n <Button variant=\"outline\" onClick={handleManageViaPortal}>\n Manage via Portal\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n\n {/* Cancel Subscription Dialog */}\n {showCancel && (\n <CancelSubscriptionDialog\n subscription={subscription}\n open={showCancel}\n onOpenChange={setShowCancel}\n onSuccess={() => {\n onSubscriptionChange();\n setShowCancel(false);\n }}\n />\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { useState } from \"react\";\nimport { SubmitHandler, useForm } from \"react-hook-form\";\nimport { z } from \"zod\";\nimport { FormCheckbox, FormTextarea } from \"../../../../../components\";\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n Form,\n} from \"../../../../../shadcnui\";\nimport { formatDate } from \"../../../components/utils\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService } from \"../../data\";\n\ntype CancelSubscriptionDialogProps = {\n subscription: StripeSubscriptionInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n};\n\nconst formSchema = z.object({\n cancelImmediately: z.boolean(),\n reason: z.string().optional(),\n});\n\nexport function CancelSubscriptionDialog({\n subscription,\n open,\n onOpenChange,\n onSuccess,\n}: CancelSubscriptionDialogProps) {\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n cancelImmediately: false,\n reason: \"\",\n },\n });\n\n const cancelImmediately = form.watch(\"cancelImmediately\");\n\n const onSubmit: SubmitHandler<z.infer<typeof formSchema>> = async (values) => {\n setIsSubmitting(true);\n\n try {\n await StripeSubscriptionService.cancelSubscription({\n id: subscription.id,\n cancelImmediately: values.cancelImmediately,\n });\n\n onSuccess();\n onOpenChange(false);\n } catch (error) {\n console.error(\"[CancelSubscriptionDialog] Failed to cancel subscription:\", error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const periodEndDate = formatDate(subscription.currentPeriodEnd);\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Cancel Subscription</DialogTitle>\n <DialogDescription>\n Are you sure you want to cancel this subscription? This action cannot be undone.\n </DialogDescription>\n </DialogHeader>\n\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col gap-y-4\">\n <FormCheckbox form={form} id=\"cancelImmediately\" name=\"Cancel Immediately\" />\n\n {cancelImmediately ? (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-800\">\n Your subscription will be canceled immediately and you will lose access right away.\n </div>\n ) : (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-3 text-sm text-blue-800\">\n Your subscription will remain active until {periodEndDate}. You can continue using the service until\n then.\n </div>\n )}\n\n <FormTextarea\n form={form}\n id=\"reason\"\n name=\"Reason (Optional)\"\n placeholder=\"Let us know why you're canceling...\"\n className=\"min-h-24\"\n />\n\n <div className=\"flex gap-x-2 justify-end pt-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)} disabled={isSubmitting}>\n Keep Subscription\n </Button>\n <Button type=\"submit\" variant=\"destructive\" disabled={isSubmitting}>\n {isSubmitting ? \"Canceling...\" : \"Confirm Cancellation\"}\n </Button>\n </div>\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { SubscriptionStatus } from \"../../data\";\n\ntype SubscriptionStatusBadgeProps = {\n status: SubscriptionStatus;\n cancelAtPeriodEnd?: boolean;\n};\n\ntype StatusConfig = {\n label: string;\n color: string;\n};\n\nconst statusConfig: Record<SubscriptionStatus, StatusConfig> = {\n [SubscriptionStatus.ACTIVE]: {\n label: \"Active\",\n color: \"bg-green-100 text-green-800\",\n },\n [SubscriptionStatus.TRIALING]: {\n label: \"Trial\",\n color: \"bg-blue-100 text-blue-800\",\n },\n [SubscriptionStatus.PAST_DUE]: {\n label: \"Past Due\",\n color: \"bg-red-100 text-red-800\",\n },\n [SubscriptionStatus.CANCELED]: {\n label: \"Canceled\",\n color: \"bg-gray-100 text-gray-800\",\n },\n [SubscriptionStatus.PAUSED]: {\n label: \"Paused\",\n color: \"bg-yellow-100 text-yellow-800\",\n },\n [SubscriptionStatus.UNPAID]: {\n label: \"Unpaid\",\n color: \"bg-orange-100 text-orange-800\",\n },\n [SubscriptionStatus.INCOMPLETE]: {\n label: \"Incomplete\",\n color: \"bg-gray-100 text-gray-800\",\n },\n [SubscriptionStatus.INCOMPLETE_EXPIRED]: {\n label: \"Expired\",\n color: \"bg-gray-100 text-gray-800\",\n },\n};\n\nconst cancelingConfig: StatusConfig = {\n label: \"Canceling\",\n color: \"bg-amber-100 text-amber-800\",\n};\n\nexport function SubscriptionStatusBadge({ status, cancelAtPeriodEnd }: SubscriptionStatusBadgeProps) {\n // Show \"Canceling\" when subscription is set to cancel at period end\n const config = cancelAtPeriodEnd ? cancelingConfig : statusConfig[status] || statusConfig[SubscriptionStatus.CANCELED];\n\n return <span className={`${config.color} text-xs px-2 py-1 rounded-full font-medium`}>{config.label}</span>;\n}\n","\"use client\";\n\nimport { Tabs, TabsList, TabsTrigger } from \"../../../../../shadcnui\";\n\nexport type BillingInterval = \"month\" | \"year\";\n\nexport type IntervalToggleProps = {\n value: BillingInterval;\n onChange: (interval: BillingInterval) => void;\n hasMonthly: boolean;\n hasYearly: boolean;\n};\n\nexport function IntervalToggle({ value, onChange, hasMonthly, hasYearly }: IntervalToggleProps) {\n // Only render if BOTH intervals are available\n if (!hasMonthly || !hasYearly) {\n return null;\n }\n\n return (\n <Tabs value={value} onValueChange={(v) => onChange(v as BillingInterval)}>\n <TabsList>\n <TabsTrigger value=\"month\">Monthly</TabsTrigger>\n <TabsTrigger value=\"year\">Yearly</TabsTrigger>\n </TabsList>\n </Tabs>\n );\n}\n","\"use client\";\n\nimport { Check } from \"lucide-react\";\nimport { KeyboardEvent } from \"react\";\nimport { Badge, Button, Card, CardContent, CardFooter, CardHeader } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatInterval } from \"../../../components/utils\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { cn } from \"../../../../../utils/cn\";\n\nexport type PricingCardProps = {\n price: StripePriceInterface;\n isCurrentPlan?: boolean;\n isSelected?: boolean;\n isDisabled?: boolean;\n isLoading?: boolean;\n onSelect: (price: StripePriceInterface) => void;\n};\n\nexport function PricingCard({ price, isCurrentPlan = false, isSelected = false, isDisabled = false, isLoading = false, onSelect }: PricingCardProps) {\n const description = price.description || price.nickname || \"Standard\";\n const features = price.features || [];\n const formattedPrice = formatCurrency(price.unitAmount, price.currency);\n const interval = formatInterval(price);\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if ((e.key === \"Enter\" || e.key === \" \") && !isDisabled && !isCurrentPlan) {\n e.preventDefault();\n onSelect(price);\n }\n };\n\n const handleClick = () => {\n if (!isDisabled && !isCurrentPlan && !isLoading) {\n onSelect(price);\n }\n };\n\n return (\n <Card\n role=\"radio\"\n aria-checked={isSelected}\n aria-label={`${description} plan at ${formattedPrice} ${interval}`}\n tabIndex={isDisabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n className={cn(\n \"relative cursor-pointer transition-all duration-200 flex flex-col h-full\",\n \"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n isCurrentPlan && \"bg-muted/30\",\n isSelected && !isCurrentPlan && \"ring-2 ring-primary\",\n !isDisabled && !isCurrentPlan && \"hover:shadow-md hover:border-primary/50\",\n isDisabled && \"opacity-50 pointer-events-none\",\n isLoading && \"pointer-events-none\"\n )}\n >\n {isCurrentPlan && (\n <Badge variant=\"secondary\" className=\"absolute top-2 right-2\">\n Current\n </Badge>\n )}\n\n <CardHeader className=\"pb-2\">\n <h3 className=\"font-semibold text-lg\">{description}</h3>\n </CardHeader>\n\n <CardContent className=\"pb-4 grow\">\n <div className=\"mb-4\">\n <span className=\"text-3xl font-bold\">{formattedPrice}</span>\n <span className=\"text-muted-foreground ml-1\">{interval}</span>\n </div>\n\n {features.length > 0 && (\n <ul className=\"space-y-2\">\n {features.map((feature, index) => (\n <li key={index} className=\"flex items-start gap-2\">\n <Check className=\"h-4 w-4 text-green-500 mt-0.5 shrink-0\" />\n <span className=\"text-sm text-muted-foreground\">{feature}</span>\n </li>\n ))}\n </ul>\n )}\n </CardContent>\n\n <CardFooter>\n <Button\n variant={isCurrentPlan ? \"secondary\" : isSelected ? \"default\" : \"outline\"}\n className=\"w-full\"\n disabled={isDisabled || isCurrentPlan || isLoading}\n >\n {isLoading ? \"Processing...\" : isCurrentPlan ? \"Current Plan\" : isSelected ? \"Selected\" : \"Select Plan\"}\n </Button>\n </CardFooter>\n </Card>\n );\n}\n","\"use client\";\n\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { StripeProductInterface } from \"../../../stripe-product\";\nimport { PricingCard } from \"./PricingCard\";\n\nexport type ProductPricingRowProps = {\n product: StripeProductInterface;\n prices: StripePriceInterface[]; // Multiple prices for this product\n currentPriceId?: string;\n selectedPriceId?: string;\n loadingPriceId?: string;\n onSelectPrice: (price: StripePriceInterface) => void;\n};\n\nexport function ProductPricingRow({\n product,\n prices,\n currentPriceId,\n selectedPriceId,\n loadingPriceId,\n onSelectPrice,\n}: ProductPricingRowProps) {\n if (prices.length === 0) {\n return null;\n }\n\n return (\n <div className=\"space-y-3\">\n {/* Product name header */}\n <h3 className=\"font-semibold text-lg\">{product.name}</h3>\n\n {/* Price cards in columns */}\n <div\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n role=\"radiogroup\"\n aria-label={`Pricing options for ${product.name}`}\n >\n {prices\n .sort((a, b) => (a.unitAmount ?? 0) - (b.unitAmount ?? 0))\n .map((price) => (\n <PricingCard\n key={price.id}\n price={price}\n isCurrentPlan={price.id === currentPriceId}\n isSelected={price.id === selectedPriceId}\n isLoading={price.id === loadingPriceId}\n onSelect={onSelectPrice}\n />\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { Skeleton } from \"../../../../../shadcnui\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { StripeProductInterface } from \"../../../stripe-product\";\nimport { BillingInterval } from \"./IntervalToggle\";\nimport { ProductPricingRow } from \"./ProductPricingRow\";\n\nexport type ProductPricingListProps = {\n products: StripeProductInterface[];\n selectedInterval: BillingInterval;\n currentPriceId?: string;\n selectedPriceId?: string;\n loadingPriceId?: string;\n loading?: boolean;\n onSelectPrice: (price: StripePriceInterface) => void;\n hideRecurringPrices?: boolean;\n};\n\nfunction isRecurringProduct(prices: StripePriceInterface[]): boolean {\n return prices.some((p) => p.priceType === \"recurring\");\n}\n\nfunction getFilteredPrices(prices: StripePriceInterface[], selectedInterval: BillingInterval): StripePriceInterface[] {\n const isRecurring = isRecurringProduct(prices);\n\n if (!isRecurring) {\n return prices.filter((p) => p.priceType === \"one_time\");\n }\n\n const intervalPrices = prices.filter(\n (p) => p.priceType === \"recurring\" && p.recurring?.interval === selectedInterval,\n );\n\n if (intervalPrices.length === 0) {\n const fallbackInterval = selectedInterval === \"month\" ? \"year\" : \"month\";\n return prices.filter((p) => p.priceType === \"recurring\" && p.recurring?.interval === fallbackInterval);\n }\n\n return intervalPrices;\n}\n\nexport function ProductPricingList({\n products,\n selectedInterval,\n currentPriceId,\n selectedPriceId,\n loadingPriceId,\n loading = false,\n onSelectPrice,\n hideRecurringPrices = false,\n}: ProductPricingListProps) {\n if (loading) {\n return <ProductPricingListSkeleton />;\n }\n\n if (products.length === 0) {\n return <div className=\"text-center py-8 text-muted-foreground\">No plans available</div>;\n }\n\n const sortedProducts = [...products].sort((a, b) => {\n const aRecurring = isRecurringProduct(a.stripePrices || []);\n const bRecurring = isRecurringProduct(b.stripePrices || []);\n if (aRecurring && !bRecurring) return -1;\n if (!aRecurring && bRecurring) return 1;\n return 0;\n });\n\n // Filter products based on hideRecurringPrices\n const filteredProducts = hideRecurringPrices\n ? sortedProducts\n .map((product) => ({\n ...product,\n stripePrices: (product.stripePrices || []).filter((price) => price.priceType !== \"recurring\"),\n }))\n .filter((product) => product.stripePrices.length > 0)\n : sortedProducts;\n\n return (\n <div className=\"space-y-6\">\n {filteredProducts.map((product) => {\n const allPrices = product.stripePrices || [];\n const filteredPrices = getFilteredPrices(allPrices, selectedInterval);\n\n if (filteredPrices.length === 0) {\n return null;\n }\n\n return (\n <ProductPricingRow\n key={product.id}\n product={product}\n prices={filteredPrices}\n currentPriceId={currentPriceId}\n selectedPriceId={selectedPriceId}\n loadingPriceId={loadingPriceId}\n onSelectPrice={onSelectPrice}\n />\n );\n })}\n </div>\n );\n}\n\nfunction ProductPricingListSkeleton() {\n return (\n <div className=\"space-y-6\">\n {[1, 2].map((rowIndex) => (\n <div key={rowIndex} className=\"space-y-3\">\n <Skeleton className=\"h-6 w-32\" />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3].map((cardIndex) => (\n <div key={cardIndex} className=\"p-4 rounded-lg border animate-pulse space-y-3\">\n <Skeleton className=\"h-6 w-24\" />\n <Skeleton className=\"h-8 w-32\" />\n <div className=\"space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n </div>\n <Skeleton className=\"h-10 w-full\" />\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { ProrationPreviewInterface } from \"../../../stripe-invoice/data/stripe-invoice.interface\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\n\ntype ProrationPreviewProps = {\n preview: ProrationPreviewInterface;\n};\n\nexport function ProrationPreview({ preview }: ProrationPreviewProps) {\n return (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4\">\n <h4 className=\"font-semibold text-blue-900 mb-3\">Proration Breakdown</h4>\n\n <div className=\"space-y-2\">\n {preview.lineItems.map((item, index) => (\n <div key={index} className=\"flex justify-between text-sm\">\n <span className=\"text-blue-800\">{item.description}</span>\n <span className={`font-medium ${item.amount < 0 ? \"text-green-600\" : \"text-blue-900\"}`}>\n {formatCurrency(item.amount, preview.currency)}\n </span>\n </div>\n ))}\n\n <div className=\"border-t border-blue-200 pt-2 mt-2\">\n <div className=\"flex justify-between font-semibold\">\n <span className=\"text-blue-900\">Net Due Today</span>\n <span className=\"text-blue-900\">{formatCurrency(preview.immediateCharge, preview.currency)}</span>\n </div>\n </div>\n\n {preview.lineItems.length > 0 && preview.lineItems[0].period && (\n <div className=\"text-xs text-blue-700 mt-2\">\n Next invoice on {formatDate(preview.lineItems[0].period.end)} for{\" \"}\n {formatCurrency(preview.amountDue, preview.currency)}\n </div>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { Check, Loader2 } from \"lucide-react\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatInterval } from \"../../../components/utils\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\n\ntype SubscriptionConfirmationProps = {\n price: StripePriceInterface;\n isLoading: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nexport function SubscriptionConfirmation({ price, isLoading, onConfirm, onCancel }: SubscriptionConfirmationProps) {\n const productName = price.product?.name || price.nickname || \"Selected Plan\";\n const productDescription = price.product?.description || price.description;\n const features = price.features || [];\n\n return (\n <div className=\"bg-accent/10 border border-accent/30 rounded-lg p-4\">\n <h4 className=\"font-semibold mb-3\">Confirm Your Subscription</h4>\n\n <div className=\"space-y-3\">\n {/* Plan name and description */}\n <div>\n <div className=\"font-medium\">{productName}</div>\n {productDescription && <div className=\"text-sm text-muted-foreground\">{productDescription}</div>}\n </div>\n\n {/* Price */}\n <div className=\"text-lg font-semibold\">\n {formatCurrency(price.unitAmount, price.currency)}\n <span className=\"text-sm font-normal text-muted-foreground\">{formatInterval(price)}</span>\n </div>\n\n {/* Features */}\n {features.length > 0 && (\n <div className=\"space-y-1\">\n {features.map((feature, index) => (\n <div key={index} className=\"flex items-center gap-2 text-sm \">\n <Check className=\"h-4 w-4 text-primary\" />\n <span>{feature}</span>\n </div>\n ))}\n </div>\n )}\n\n {/* Action buttons */}\n <div className=\"flex justify-end gap-3 pt-2 border-t border-accent/30\">\n <Button variant=\"outline\" onClick={onCancel} disabled={isLoading}>\n Cancel\n </Button>\n <Button onClick={onConfirm} disabled={isLoading}>\n {isLoading ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin mr-2\" />\n Processing...\n </>\n ) : (\n \"Subscribe\"\n )}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../../../../../shadcnui\";\nimport { StripeSubscriptionInterface } from \"../../data\";\nimport { useSubscriptionWizard } from \"../../hooks/useSubscriptionWizard\";\nimport { WizardProgressIndicator } from \"./WizardProgressIndicator\";\nimport { WizardStepPlanSelection } from \"./WizardStepPlanSelection\";\nimport { WizardStepReview } from \"./WizardStepReview\";\nimport { WizardStepPaymentMethod } from \"./WizardStepPaymentMethod\";\n\nexport type SubscriptionWizardProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n hasActiveRecurringSubscription: boolean;\n subscription?: StripeSubscriptionInterface;\n};\n\nexport function SubscriptionWizard({\n open,\n onOpenChange,\n onSuccess,\n hasActiveRecurringSubscription,\n subscription,\n}: SubscriptionWizardProps) {\n const handleClose = useCallback(() => onOpenChange(false), [onOpenChange]);\n\n const { state, actions } = useSubscriptionWizard({\n subscription,\n onSuccess,\n onClose: handleClose,\n });\n\n // Track if we've already checked payment method for this open state\n const hasCheckedRef = useRef(false);\n\n // Check payment method on mount\n useEffect(() => {\n if (open && !hasCheckedRef.current) {\n hasCheckedRef.current = true;\n actions.checkPaymentMethod();\n }\n if (!open) {\n hasCheckedRef.current = false;\n }\n }, [open, actions.checkPaymentMethod]);\n\n // Reset state when dialog closes\n useEffect(() => {\n if (!open) {\n actions.reset();\n }\n }, [open, actions.reset]);\n\n const dialogTitle = subscription ? \"Change Subscription Plan\" : \"Subscribe to a Plan\";\n const dialogDescription = subscription\n ? \"Select a new plan for your subscription\"\n : \"Choose a subscription plan to get started\";\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{dialogTitle}</DialogTitle>\n <DialogDescription>{dialogDescription}</DialogDescription>\n </DialogHeader>\n\n <WizardProgressIndicator currentStep={state.step} />\n\n {state.step === \"plan-selection\" && (\n <WizardStepPlanSelection\n selectedPrice={state.selectedPrice}\n selectedInterval={state.selectedInterval}\n currentPriceId={subscription?.price?.id}\n hideRecurringPrices={hasActiveRecurringSubscription && !subscription}\n onSelectPrice={actions.selectPrice}\n onIntervalChange={actions.setInterval}\n onNext={actions.goToReview}\n isProcessing={state.isProcessing}\n />\n )}\n\n {state.step === \"review\" && (\n <WizardStepReview\n selectedPrice={state.selectedPrice}\n subscription={subscription}\n prorationPreview={state.prorationPreview}\n hasPaymentMethod={state.hasPaymentMethod}\n error={state.error}\n isProcessing={state.isProcessing}\n onBack={() => actions.goToStep(\"plan-selection\")}\n onAddPaymentMethod={() => actions.goToStep(\"payment-method\")}\n onConfirm={actions.confirmSubscription}\n />\n )}\n\n {state.step === \"payment-method\" && (\n <WizardStepPaymentMethod\n onBack={() => actions.goToStep(\"review\")}\n onSuccess={actions.handlePaymentMethodSuccess}\n isProcessing={state.isProcessing}\n />\n )}\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useCallback, useMemo, useReducer, useRef } from \"react\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService } from \"../data\";\nimport { StripePriceInterface } from \"../../stripe-price/data/stripe-price.interface\";\nimport { BillingInterval } from \"../components/widgets/IntervalToggle\";\nimport { StripeCustomerService } from \"../../stripe-customer/data/stripe-customer.service\";\nimport { ProrationPreviewInterface } from \"../../stripe-invoice/data/stripe-invoice.interface\";\n\nexport type WizardStep = \"plan-selection\" | \"review\" | \"payment-method\";\n\nexport type WizardState = {\n step: WizardStep;\n selectedPrice: StripePriceInterface | null;\n selectedInterval: BillingInterval;\n hasPaymentMethod: boolean;\n isProcessing: boolean;\n error: string | null;\n prorationPreview: ProrationPreviewInterface | null;\n};\n\ntype WizardAction =\n | { type: \"SET_STEP\"; step: WizardStep }\n | { type: \"SELECT_PRICE\"; price: StripePriceInterface }\n | { type: \"SET_INTERVAL\"; interval: BillingInterval }\n | { type: \"SET_HAS_PAYMENT_METHOD\"; hasMethod: boolean }\n | { type: \"SET_PROCESSING\"; isProcessing: boolean }\n | { type: \"SET_ERROR\"; error: string | null }\n | { type: \"SET_PRORATION_PREVIEW\"; preview: ProrationPreviewInterface | null }\n | { type: \"RESET\" };\n\nconst initialState: WizardState = {\n step: \"plan-selection\",\n selectedPrice: null,\n selectedInterval: \"month\",\n hasPaymentMethod: false,\n isProcessing: false,\n error: null,\n prorationPreview: null,\n};\n\nfunction wizardReducer(state: WizardState, action: WizardAction): WizardState {\n switch (action.type) {\n case \"SET_STEP\":\n return { ...state, step: action.step, error: null };\n case \"SELECT_PRICE\":\n return { ...state, selectedPrice: action.price };\n case \"SET_INTERVAL\":\n return { ...state, selectedInterval: action.interval };\n case \"SET_HAS_PAYMENT_METHOD\":\n return { ...state, hasPaymentMethod: action.hasMethod };\n case \"SET_PROCESSING\":\n return { ...state, isProcessing: action.isProcessing };\n case \"SET_ERROR\":\n return { ...state, error: action.error };\n case \"SET_PRORATION_PREVIEW\":\n return { ...state, prorationPreview: action.preview };\n case \"RESET\":\n return initialState;\n default:\n return state;\n }\n}\n\nexport type UseSubscriptionWizardOptions = {\n subscription?: StripeSubscriptionInterface;\n onSuccess: () => void;\n onClose: () => void;\n};\n\nexport function useSubscriptionWizard({ subscription, onSuccess, onClose }: UseSubscriptionWizardOptions) {\n const [state, dispatch] = useReducer(wizardReducer, {\n ...initialState,\n selectedPrice: subscription?.price || null,\n });\n\n // Use refs for callbacks to avoid dependency changes\n const onSuccessRef = useRef(onSuccess);\n const onCloseRef = useRef(onClose);\n onSuccessRef.current = onSuccess;\n onCloseRef.current = onClose;\n\n const checkPaymentMethod = useCallback(async () => {\n try {\n const methods = await StripeCustomerService.listPaymentMethods();\n dispatch({ type: \"SET_HAS_PAYMENT_METHOD\", hasMethod: methods.length > 0 });\n } catch (error) {\n console.error(\"[useSubscriptionWizard] Failed to check payment methods:\", error);\n dispatch({ type: \"SET_HAS_PAYMENT_METHOD\", hasMethod: false });\n }\n }, []);\n\n const selectPrice = useCallback((price: StripePriceInterface) => {\n dispatch({ type: \"SELECT_PRICE\", price });\n }, []);\n\n const setInterval = useCallback((interval: BillingInterval) => {\n dispatch({ type: \"SET_INTERVAL\", interval });\n }, []);\n\n const goToStep = useCallback((step: WizardStep) => {\n dispatch({ type: \"SET_STEP\", step });\n }, []);\n\n const goToReview = useCallback(async () => {\n if (!state.selectedPrice) return;\n\n dispatch({ type: \"SET_PROCESSING\", isProcessing: true });\n\n try {\n // Check payment method first\n await checkPaymentMethod();\n\n // If editing subscription, get proration preview\n if (subscription && state.selectedPrice.id !== subscription.price?.id) {\n const preview = await StripeSubscriptionService.getProrationPreview({\n subscriptionId: subscription.id,\n newPriceId: state.selectedPrice.id,\n });\n dispatch({ type: \"SET_PRORATION_PREVIEW\", preview });\n }\n\n dispatch({ type: \"SET_STEP\", step: \"review\" });\n } catch (error: any) {\n console.error(\"[useSubscriptionWizard] Error preparing review:\", error);\n dispatch({ type: \"SET_ERROR\", error: error?.message || \"Failed to prepare review\" });\n } finally {\n dispatch({ type: \"SET_PROCESSING\", isProcessing: false });\n }\n }, [state.selectedPrice, subscription, checkPaymentMethod]);\n\n const confirmSubscription = useCallback(async () => {\n if (!state.selectedPrice) return;\n\n dispatch({ type: \"SET_PROCESSING\", isProcessing: true });\n dispatch({ type: \"SET_ERROR\", error: null });\n\n try {\n if (subscription) {\n // Change existing subscription\n await StripeSubscriptionService.changePlan({\n id: subscription.id,\n newPriceId: state.selectedPrice.id,\n });\n } else {\n // Create new subscription\n await StripeSubscriptionService.createSubscription({\n id: crypto.randomUUID(),\n priceId: state.selectedPrice.id,\n });\n }\n\n onSuccessRef.current();\n onCloseRef.current();\n } catch (error: any) {\n console.error(\"[useSubscriptionWizard] Subscription error:\", error);\n\n // Handle 409 Conflict - duplicate recurring subscription\n if (error?.status === 409 || error?.response?.status === 409) {\n dispatch({\n type: \"SET_ERROR\",\n error: \"You already have an active subscription. Please change your existing plan instead.\",\n });\n return;\n }\n\n // Handle 402 - payment method required\n if (error?.status === 402 || error?.response?.status === 402) {\n dispatch({ type: \"SET_HAS_PAYMENT_METHOD\", hasMethod: false });\n dispatch({ type: \"SET_STEP\", step: \"payment-method\" });\n return;\n }\n\n dispatch({ type: \"SET_ERROR\", error: error?.message || \"Failed to process subscription\" });\n } finally {\n dispatch({ type: \"SET_PROCESSING\", isProcessing: false });\n }\n }, [state.selectedPrice, subscription]);\n\n const handlePaymentMethodSuccess = useCallback(async () => {\n dispatch({ type: \"SET_HAS_PAYMENT_METHOD\", hasMethod: true });\n // Go back to review to confirm subscription\n dispatch({ type: \"SET_STEP\", step: \"review\" });\n }, []);\n\n const reset = useCallback(() => {\n dispatch({ type: \"RESET\" });\n }, []);\n\n const actions = useMemo(\n () => ({\n selectPrice,\n setInterval,\n goToStep,\n goToReview,\n confirmSubscription,\n handlePaymentMethodSuccess,\n checkPaymentMethod,\n reset,\n }),\n [\n selectPrice,\n setInterval,\n goToStep,\n goToReview,\n confirmSubscription,\n handlePaymentMethodSuccess,\n checkPaymentMethod,\n reset,\n ],\n );\n\n return {\n state,\n actions,\n };\n}\n","\"use client\";\n\nimport { Check } from \"lucide-react\";\nimport { WizardStep } from \"../../hooks/useSubscriptionWizard\";\n\ntype WizardProgressIndicatorProps = {\n currentStep: WizardStep;\n};\n\nconst STEPS: { key: WizardStep; label: string }[] = [\n { key: \"plan-selection\", label: \"Select Plan\" },\n { key: \"review\", label: \"Review\" },\n { key: \"payment-method\", label: \"Payment\" },\n];\n\nfunction getStepIndex(step: WizardStep): number {\n return STEPS.findIndex((s) => s.key === step);\n}\n\nexport function WizardProgressIndicator({ currentStep }: WizardProgressIndicatorProps) {\n const currentIndex = getStepIndex(currentStep);\n\n return (\n <div className=\"flex items-center justify-center gap-x-2 py-4\">\n {STEPS.map((step, index) => {\n const isCompleted = index < currentIndex;\n const isCurrent = index === currentIndex;\n\n return (\n <div key={step.key} className=\"flex items-center gap-x-2\">\n {/* Step Indicator */}\n <div\n className={`flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium ${\n isCompleted\n ? \"bg-primary text-primary-foreground\"\n : isCurrent\n ? \"bg-primary text-primary-foreground\"\n : \"bg-muted text-muted-foreground\"\n }`}\n >\n {isCompleted ? <Check className=\"h-4 w-4\" /> : index + 1}\n </div>\n\n {/* Step Label */}\n <span\n className={`text-sm ${\n isCurrent ? \"font-medium text-foreground\" : \"text-muted-foreground\"\n }`}\n >\n {step.label}\n </span>\n\n {/* Connector */}\n {index < STEPS.length - 1 && (\n <div\n className={`h-0.5 w-8 ${\n index < currentIndex ? \"bg-primary\" : \"bg-muted\"\n }`}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { StripeProductInterface, StripeProductService } from \"../../../stripe-product\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { BillingInterval, IntervalToggle } from \"../widgets/IntervalToggle\";\nimport { ProductPricingList } from \"../widgets/ProductPricingList\";\n\ntype WizardStepPlanSelectionProps = {\n selectedPrice: StripePriceInterface | null;\n selectedInterval: BillingInterval;\n currentPriceId?: string;\n hideRecurringPrices: boolean;\n onSelectPrice: (price: StripePriceInterface) => void;\n onIntervalChange: (interval: BillingInterval) => void;\n onNext: () => void;\n isProcessing: boolean;\n};\n\nexport function WizardStepPlanSelection({\n selectedPrice,\n selectedInterval,\n currentPriceId,\n hideRecurringPrices,\n onSelectPrice,\n onIntervalChange,\n onNext,\n isProcessing,\n}: WizardStepPlanSelectionProps) {\n const [products, setProducts] = useState<StripeProductInterface[]>([]);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n const loadProducts = async () => {\n try {\n const fetchedProducts = await StripeProductService.listProducts({ active: true });\n setProducts(fetchedProducts);\n } catch (error) {\n console.error(\"[WizardStepPlanSelection] Failed to load products:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n loadProducts();\n }, []);\n\n // Compute available intervals from products\n const { hasMonthly, hasYearly } = useMemo(() => {\n let hasMonthly = false;\n let hasYearly = false;\n\n for (const product of products) {\n for (const price of product.stripePrices || []) {\n if (price.priceType === \"recurring\" && price.recurring?.interval === \"month\") {\n hasMonthly = true;\n }\n if (price.priceType === \"recurring\" && price.recurring?.interval === \"year\") {\n hasYearly = true;\n }\n }\n }\n\n return { hasMonthly, hasYearly };\n }, [products]);\n\n const handleSelectPrice = (price: StripePriceInterface) => {\n onSelectPrice(price);\n };\n\n return (\n <div className=\"space-y-6\">\n {/* Interval Toggle */}\n <div className=\"flex justify-center\">\n <IntervalToggle\n value={selectedInterval}\n onChange={onIntervalChange}\n hasMonthly={hasMonthly}\n hasYearly={hasYearly}\n />\n </div>\n\n {/* Product Pricing List */}\n <ProductPricingList\n products={products}\n selectedInterval={selectedInterval}\n currentPriceId={currentPriceId}\n selectedPriceId={selectedPrice?.id}\n loading={loading}\n hideRecurringPrices={hideRecurringPrices}\n onSelectPrice={handleSelectPrice}\n />\n\n {/* Action Buttons */}\n <div className=\"flex justify-end pt-4 border-t\">\n <Button onClick={onNext} disabled={!selectedPrice || isProcessing}>\n {isProcessing ? \"Loading...\" : \"Next: Review\"}\n </Button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { AlertCircle } from \"lucide-react\";\nimport { Alert, AlertDescription, Button } from \"../../../../../shadcnui\";\nimport { formatCurrency } from \"../../../components/utils/currency\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { ProrationPreviewInterface } from \"../../../stripe-invoice/data/stripe-invoice.interface\";\nimport { StripeSubscriptionInterface } from \"../../data\";\n\ntype WizardStepReviewProps = {\n selectedPrice: StripePriceInterface | null;\n subscription?: StripeSubscriptionInterface;\n prorationPreview: ProrationPreviewInterface | null;\n hasPaymentMethod: boolean;\n error: string | null;\n isProcessing: boolean;\n onBack: () => void;\n onAddPaymentMethod: () => void;\n onConfirm: () => void;\n};\n\nexport function WizardStepReview({\n selectedPrice,\n subscription,\n prorationPreview,\n hasPaymentMethod,\n error,\n isProcessing,\n onBack,\n onAddPaymentMethod,\n onConfirm,\n}: WizardStepReviewProps) {\n if (!selectedPrice) {\n return (\n <div className=\"text-center py-8 text-muted-foreground\">\n No plan selected. Please go back and select a plan.\n </div>\n );\n }\n\n const isChangingPlan = subscription && subscription.price?.id !== selectedPrice.id;\n\n const formatInterval = (price: StripePriceInterface) => {\n if (price.priceType === \"one_time\") return \"one-time\";\n const interval = price.recurring?.interval || \"month\";\n return interval === \"year\" ? \"yearly\" : \"monthly\";\n };\n\n return (\n <div className=\"space-y-6\">\n {/* Selected Plan Summary */}\n <div className=\"bg-muted/50 rounded-lg p-4 space-y-3\">\n <h3 className=\"font-semibold text-lg\">Selected Plan</h3>\n <div className=\"flex justify-between items-center\">\n <div>\n <p className=\"font-medium\">{selectedPrice.product?.name}</p>\n {selectedPrice.nickname && (\n <p className=\"text-sm text-muted-foreground\">{selectedPrice.nickname}</p>\n )}\n </div>\n <div className=\"text-right\">\n <p className=\"font-semibold text-lg\">\n {formatCurrency(selectedPrice.unitAmount || 0, selectedPrice.currency)}\n </p>\n <p className=\"text-sm text-muted-foreground\">{formatInterval(selectedPrice)}</p>\n </div>\n </div>\n </div>\n\n {/* Proration Preview (for plan changes) */}\n {isChangingPlan && prorationPreview && (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4 space-y-2\">\n <h4 className=\"font-medium text-blue-800\">Proration Summary</h4>\n <p className=\"text-sm text-blue-700\">\n Your next charge will be adjusted to account for the plan change.\n </p>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-blue-600\">Amount due now:</span>\n <span className=\"font-medium text-blue-800\">\n {formatCurrency(prorationPreview.amountDue, prorationPreview.currency)}\n </span>\n </div>\n </div>\n )}\n\n {/* Payment Method Status */}\n <div className=\"border rounded-lg p-4\">\n <div className=\"flex justify-between items-center\">\n <div>\n <h4 className=\"font-medium\">Payment Method</h4>\n <p className=\"text-sm text-muted-foreground\">\n {hasPaymentMethod\n ? \"A payment method is on file\"\n : \"No payment method on file\"}\n </p>\n </div>\n {!hasPaymentMethod && (\n <Button variant=\"outline\" onClick={onAddPaymentMethod}>\n Add Payment Method\n </Button>\n )}\n </div>\n </div>\n\n {/* Error Display */}\n {error && (\n <Alert variant=\"destructive\">\n <AlertCircle className=\"h-4 w-4\" />\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n )}\n\n {/* Action Buttons */}\n <div className=\"flex justify-between pt-4 border-t\">\n <Button variant=\"outline\" onClick={onBack} disabled={isProcessing}>\n Back\n </Button>\n <Button\n onClick={hasPaymentMethod ? onConfirm : onAddPaymentMethod}\n disabled={isProcessing}\n >\n {isProcessing\n ? \"Processing...\"\n : hasPaymentMethod\n ? isChangingPlan\n ? \"Confirm Plan Change\"\n : \"Subscribe Now\"\n : \"Add Payment Method\"}\n </Button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { PaymentMethodForm } from \"../../../stripe-customer/components/forms/PaymentMethodForm\";\n\ntype WizardStepPaymentMethodProps = {\n onBack: () => void;\n onSuccess: () => void;\n isProcessing: boolean;\n};\n\nexport function WizardStepPaymentMethod({\n onBack,\n onSuccess,\n isProcessing,\n}: WizardStepPaymentMethodProps) {\n return (\n <div className=\"space-y-6\">\n <div className=\"text-center\">\n <h3 className=\"font-semibold text-lg\">Add Payment Method</h3>\n <p className=\"text-sm text-muted-foreground\">\n Enter your card details to complete your subscription\n </p>\n </div>\n\n <PaymentMethodForm\n onSuccess={onSuccess}\n onCancel={onBack}\n isLoading={isProcessing}\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { Activity } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService } from \"../../../stripe-subscription\";\nimport { MeterInterface, MeterSummaryInterface } from \"../../data/stripe-usage.interface\";\nimport { StripeUsageService } from \"../../data/stripe-usage.service\";\nimport { UsageSummaryCards } from \"../widgets/UsageSummaryCards\";\n\nexport function UsageContainer() {\n const [meters, setMeters] = useState<MeterInterface[]>([]);\n const [summaries, setSummaries] = useState<Record<string, MeterSummaryInterface | null>>({});\n const [loading, setLoading] = useState<boolean>(true);\n const [subscriptions, setSubscriptions] = useState<StripeSubscriptionInterface[]>([]);\n\n useEffect(() => {\n loadUsageData();\n }, []);\n\n const loadUsageData = async () => {\n setLoading(true);\n\n try {\n // First, check if there are any metered subscriptions\n const fetchedSubscriptions = await StripeSubscriptionService.listSubscriptions();\n setSubscriptions(fetchedSubscriptions);\n\n const hasMeteredSubscriptions = fetchedSubscriptions.some((sub) => sub.price?.recurring?.usageType === \"metered\");\n\n if (!hasMeteredSubscriptions) {\n setLoading(false);\n return;\n }\n\n // Load meters\n const fetchedMeters = await StripeUsageService.listMeters();\n setMeters(fetchedMeters);\n\n // Load summaries for each meter (current month)\n const summariesMap: Record<string, MeterSummaryInterface | null> = {};\n const now = new Date();\n const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);\n const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);\n\n for (const meter of fetchedMeters) {\n try {\n const meterSummaries = await StripeUsageService.getMeterSummaries({\n meterId: meter.id,\n startTime: startOfMonth,\n endTime: endOfMonth,\n });\n // Use the first (most recent) summary\n summariesMap[meter.id] = meterSummaries.length > 0 ? meterSummaries[0] : null;\n } catch (error) {\n console.error(`[UsageContainer] Failed to load summaries for meter ${meter.id}:`, error);\n summariesMap[meter.id] = null;\n }\n }\n\n setSummaries(summariesMap);\n } catch (error) {\n console.error(\"[UsageContainer] Failed to load usage data:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n // Check if there are any metered subscriptions\n const hasMeteredSubscriptions = subscriptions.some((sub) => sub.price?.recurring?.usageType === \"metered\");\n\n // Don't render if no metered subscriptions\n if (!loading && !hasMeteredSubscriptions) {\n return null;\n }\n\n if (loading) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-muted-foreground\">Loading usage data...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center gap-x-3\">\n <Activity className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Usage Tracking</h1>\n </div>\n\n {/* Empty State */}\n {meters.length === 0 && (\n <div className=\"bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 p-12\">\n <Activity className=\"text-muted-foreground h-16 w-16\" />\n <div className=\"text-center\">\n <h3 className=\"mb-2 text-xl font-semibold\">No usage meters configured</h3>\n <p className=\"text-muted-foreground\">\n Usage tracking will appear here when you have metered subscriptions with configured meters.\n </p>\n </div>\n </div>\n )}\n\n {/* Usage Summary Cards */}\n {meters.length > 0 && <UsageSummaryCards meters={meters} summaries={summaries} />}\n </div>\n );\n}\n","\"use client\";\n\nimport { Activity } from \"lucide-react\";\nimport { Card, CardContent, CardHeader } from \"../../../../../shadcnui\";\nimport { MeterInterface, MeterSummaryInterface } from \"../../data/stripe-usage.interface\";\n\ntype UsageSummaryCardProps = {\n meter: MeterInterface;\n summary: MeterSummaryInterface | null;\n};\n\n/**\n * Get progress bar color based on usage percentage\n */\nfunction getProgressColor(percentage: number | null): string {\n if (percentage === null) return \"bg-blue-500\";\n if (percentage >= 90) return \"bg-red-500\";\n if (percentage >= 75) return \"bg-orange-500\";\n return \"bg-green-500\";\n}\n\n/**\n * Format a Unix timestamp to readable date\n */\nfunction formatDate(date: Date | undefined): string {\n if (!date) return \"N/A\";\n\n try {\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n }).format(new Date(date));\n } catch (error) {\n return \"Invalid Date\";\n }\n}\n\nexport function UsageSummaryCard({ meter, summary }: UsageSummaryCardProps) {\n const currentUsage = summary?.aggregatedValue ?? 0;\n const limit = (meter as any).limit; // Meters may have optional limit field\n const percentage = limit && limit > 0 ? (currentUsage / limit) * 100 : null;\n const progressColor = getProgressColor(percentage);\n const progressWidth = percentage !== null ? Math.min(percentage, 100) : 0;\n\n const displayName = meter.displayName || meter.eventName;\n const hasLimit = limit !== null && limit !== undefined;\n\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center gap-x-3 pb-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600\">\n <Activity className=\"h-5 w-5\" />\n </div>\n <div className=\"flex flex-col\">\n <h3 className=\"font-semibold\">{displayName}</h3>\n <p className=\"text-xs text-gray-500\">{meter.id}</p>\n </div>\n </CardHeader>\n\n <CardContent className=\"flex flex-col gap-y-4\">\n {/* Current Usage */}\n <div>\n <p className=\"text-3xl font-bold\">{currentUsage.toLocaleString()}</p>\n {hasLimit && <p className=\"text-sm text-gray-500\">of {limit.toLocaleString()} used</p>}\n </div>\n\n {/* Progress Bar */}\n {hasLimit ? (\n <div className=\"flex flex-col gap-y-2\">\n <div className=\"h-2 w-full overflow-hidden rounded-full bg-gray-200\">\n <div className={`h-full transition-all ${progressColor}`} style={{ width: `${progressWidth}%` }} />\n </div>\n <p className=\"text-sm text-gray-500\">{percentage?.toFixed(1)}% used</p>\n </div>\n ) : (\n <p className=\"text-sm text-gray-500\">No limit set</p>\n )}\n\n {/* Period Information */}\n {summary && summary.start && summary.end && (\n <div className=\"border-t pt-3\">\n <p className=\"text-xs text-gray-500\">\n Period: {formatDate(summary.start)} - {formatDate(summary.end)}\n </p>\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { MeterInterface, MeterSummaryInterface } from \"../../data/stripe-usage.interface\";\nimport { UsageSummaryCard } from \"../details/UsageSummaryCard\";\n\ntype UsageSummaryCardsProps = {\n meters: MeterInterface[];\n summaries: Record<string, MeterSummaryInterface | null>;\n};\n\nexport function UsageSummaryCards({ meters, summaries }: UsageSummaryCardsProps) {\n return (\n <div className=\"grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {meters.map((meter) => (\n <UsageSummaryCard key={meter.id} meter={meter} summary={summaries[meter.id] || null} />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"../../../../../shadcnui\";\nimport { StripeUsageInterface } from \"../../data/stripe-usage.interface\";\n\ntype UsageHistoryTableProps = {\n usageRecords: StripeUsageInterface[];\n};\n\n/**\n * Format a date with time for usage history\n */\nfunction formatDateTime(date: Date | string | undefined): string {\n if (!date) return \"N/A\";\n\n const dateObj = typeof date === \"string\" ? new Date(date) : date;\n\n try {\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n }).format(dateObj);\n } catch (error) {\n return \"Invalid Date\";\n }\n}\n\nexport function UsageHistoryTable({ usageRecords }: UsageHistoryTableProps) {\n if (usageRecords.length === 0) {\n return (\n <div className=\"rounded-lg border p-8 text-center\">\n <p className=\"text-muted-foreground\">No usage history available.</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-4\">\n <h2 className=\"text-xl font-semibold\">Usage History</h2>\n <div className=\"overflow-hidden rounded-lg border\">\n <Table>\n <TableHeader className=\"bg-muted\">\n <TableRow>\n <TableHead>Date & Time</TableHead>\n <TableHead>Meter Event</TableHead>\n <TableHead className=\"text-right\">Quantity</TableHead>\n <TableHead>Event ID</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {usageRecords.map((record) => {\n const dateTime = formatDateTime(record.timestamp);\n const quantity = record.quantity.toLocaleString();\n\n return (\n <TableRow key={record.id}>\n <TableCell className=\"font-medium\">{dateTime}</TableCell>\n <TableCell className=\"text-muted-foreground\">{record.meterEventName}</TableCell>\n <TableCell className=\"text-right font-medium\">{quantity}</TableCell>\n <TableCell className=\"text-muted-foreground text-sm font-mono\">{record.stripeEventId}</TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { ReactNode } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from \"../../../../shadcnui\";\n\ntype BillingDetailModalProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n children: ReactNode;\n className?: string;\n};\n\nexport function BillingDetailModal({\n open,\n onOpenChange,\n title,\n children,\n className,\n}: BillingDetailModalProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className={className ?? \"max-w-4xl max-h-[90vh] overflow-y-auto\"}>\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n </DialogHeader>\n {children}\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { AlertCircle } from \"lucide-react\";\nimport { Button } from \"../../../../shadcnui\";\nimport { StripeSubscriptionInterface, SubscriptionStatus } from \"../../stripe-subscription\";\n\ntype BillingAlertBannerProps = {\n subscription: StripeSubscriptionInterface;\n onUpdatePayment?: () => void;\n onAddPayment?: () => void;\n};\n\nexport function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }: BillingAlertBannerProps) {\n // Payment failed alert (past_due)\n if (subscription.status === SubscriptionStatus.PAST_DUE) {\n return (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-4 flex items-start gap-x-3\">\n <AlertCircle className=\"h-5 w-5 text-red-600 mt-0.5\" />\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-red-900\">Payment Failed</h3>\n <p className=\"text-sm text-red-700 mt-1\">\n Your last payment failed. Please update your payment method to avoid service interruption.\n </p>\n </div>\n {onUpdatePayment && (\n <Button variant=\"outline\" size=\"sm\" onClick={onUpdatePayment} className=\"border-red-300 text-red-700\">\n Update Payment Method\n </Button>\n )}\n </div>\n );\n }\n\n // Trial ending soon alert (trialing with ≤7 days remaining)\n if (subscription.status === SubscriptionStatus.TRIALING && subscription.trialEnd) {\n const trialEnd = new Date(subscription.trialEnd);\n const now = new Date();\n const daysRemaining = Math.ceil((trialEnd.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));\n\n if (daysRemaining <= 7) {\n return (\n <div className=\"bg-yellow-50 border border-yellow-200 rounded-lg p-4 flex items-start gap-x-3\">\n <AlertCircle className=\"h-5 w-5 text-yellow-600 mt-0.5\" />\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-yellow-900\">Trial Ending Soon</h3>\n <p className=\"text-sm text-yellow-700 mt-1\">\n Your trial ends in {daysRemaining} {daysRemaining === 1 ? \"day\" : \"days\"}. Add a payment method to\n continue your subscription.\n </p>\n </div>\n {onAddPayment && (\n <Button variant=\"outline\" size=\"sm\" onClick={onAddPayment} className=\"border-yellow-300 text-yellow-700\">\n Add Payment Method\n </Button>\n )}\n </div>\n );\n }\n }\n\n // No critical state\n return null;\n}\n","\"use client\";\n\nimport { Elements } from \"@stripe/react-stripe-js\";\nimport { loadStripe, Stripe } from \"@stripe/stripe-js\";\nimport { ReactNode, useMemo } from \"react\";\nimport { getStripePublishableKey } from \"../../../../client/config\";\n\n// Cache the stripe promise to avoid recreating on each render\nlet stripePromiseCache: { key: string; promise: Promise<Stripe | null> } | null = null;\n\nfunction getStripePromise(publishableKey: string | undefined): Promise<Stripe | null> {\n if (!publishableKey) {\n return Promise.resolve(null);\n }\n\n // Return cached promise if key matches\n if (stripePromiseCache?.key === publishableKey) {\n return stripePromiseCache.promise;\n }\n\n // Create and cache new promise\n const promise = loadStripe(publishableKey);\n stripePromiseCache = { key: publishableKey, promise };\n return promise;\n}\n\nexport function StripeProvider({ children }: { children: ReactNode }) {\n // Evaluate key at render time, not module load time\n const publishableKey = getStripePublishableKey();\n const stripePromise = useMemo(() => getStripePromise(publishableKey), [publishableKey]);\n const options = useMemo(() => ({}), []);\n\n // If no Stripe key is configured, just render children without Stripe context\n if (!publishableKey) {\n return <>{children}</>;\n }\n\n return (\n <Elements stripe={stripePromise} options={options}>\n {children}\n </Elements>\n );\n}\n\n// Helper function to check if Stripe is configured\nexport function isStripeConfigured(): boolean {\n return !!getStripePublishableKey();\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { AlertCircle, PlusIcon, XIcon } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { SubmitHandler, useForm } from \"react-hook-form\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\nimport { FormCheckbox, FormInput, FormSelect, FormTextarea } from \"../../../../../components\";\nimport { CommonEditorButtons } from \"../../../../../components/forms/CommonEditorButtons\";\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n Form,\n Input,\n Label,\n} from \"../../../../../shadcnui\";\nimport { StripePriceInterface, StripePriceService } from \"../../data\";\n\ntype PriceEditorProps = {\n productId: string;\n price?: StripePriceInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n};\n\ntype PriceFormValues = {\n unitAmount: number;\n currency: string;\n interval: \"one_time\" | \"day\" | \"week\" | \"month\" | \"year\";\n intervalCount?: number;\n usageType?: \"licensed\" | \"metered\";\n nickname?: string;\n active: boolean;\n description?: string;\n features: string[];\n token: string;\n};\n\nexport function PriceEditor({ productId, price, open, onOpenChange, onSuccess }: PriceEditorProps) {\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n\n const formSchema = z.object({\n unitAmount: z.preprocess(\n (val) => (typeof val === \"string\" ? parseFloat(val) : val),\n z.number().min(0, { message: \"Amount must be 0 or greater\" }),\n ),\n currency: z.string().min(1, { message: \"Currency is required\" }),\n interval: z.enum([\"one_time\", \"day\", \"week\", \"month\", \"year\"]),\n intervalCount: z.preprocess(\n (val) => (val === \"\" || val === undefined ? undefined : typeof val === \"string\" ? parseInt(val, 10) : val),\n z.number().min(1).optional(),\n ),\n usageType: z.enum([\"licensed\", \"metered\"]).optional(),\n nickname: z.string().optional(),\n active: z.boolean(),\n description: z.string().optional(),\n features: z.array(z.string()),\n token: z.string(),\n });\n\n const isEditMode = !!price;\n\n // Convert cents to dollars for display\n const defaultUnitAmount = price?.unitAmount ? price.unitAmount / 100 : 0;\n\n const form = useForm<PriceFormValues>({\n resolver: zodResolver(formSchema) as any,\n defaultValues: {\n unitAmount: defaultUnitAmount,\n currency: price?.currency || \"usd\",\n interval: price?.priceType === \"one_time\" ? \"one_time\" : price?.recurring?.interval || \"month\",\n intervalCount: price?.recurring?.intervalCount || 1,\n usageType: price?.recurring?.usageType || \"licensed\",\n nickname: price?.nickname || \"\",\n active: price?.active ?? true,\n description: price?.description || \"\",\n features: price?.features || [],\n token: price?.token?.toString() ?? \"\",\n },\n });\n\n // Reset form when dialog opens to ensure fresh state\n useEffect(() => {\n if (open) {\n form.reset({\n unitAmount: price?.unitAmount ? price.unitAmount / 100 : 0,\n currency: price?.currency || \"usd\",\n interval: price?.priceType === \"one_time\" ? \"one_time\" : price?.recurring?.interval || \"month\",\n intervalCount: price?.recurring?.intervalCount || 1,\n usageType: price?.recurring?.usageType || \"licensed\",\n nickname: price?.nickname || \"\",\n active: price?.active ?? true,\n description: price?.description || \"\",\n features: price?.features || [],\n token: price?.token?.toString() ?? \"\",\n });\n }\n }, [open, price?.id]);\n\n const watchInterval = form.watch(\"interval\");\n const isRecurring = watchInterval !== \"one_time\";\n\n const onSubmit: SubmitHandler<PriceFormValues> = async (values) => {\n setIsSubmitting(true);\n\n try {\n // Convert dollars to cents\n const unitAmountInCents = Math.round(values.unitAmount * 100);\n\n if (isEditMode) {\n // Update existing price (nickname, description, features, token can be updated - Stripe fields are limited)\n await StripePriceService.updatePrice({\n id: price.id,\n nickname: values.nickname || undefined,\n description: values.description || undefined,\n features: values.features.filter((f) => f.trim()) || undefined,\n token: values.token ? parseInt(values.token, 10) : undefined,\n });\n } else {\n // Create new price\n const createInput: any = {\n id: v4(),\n productId: productId,\n currency: values.currency,\n unitAmount: unitAmountInCents,\n };\n\n // Add recurring details if interval is not one_time\n if (isRecurring) {\n createInput.recurring = {\n interval: values.interval as \"day\" | \"week\" | \"month\" | \"year\",\n intervalCount: values.intervalCount || 1,\n usageType: values.usageType || \"licensed\",\n };\n }\n\n if (values.nickname) {\n createInput.nickname = values.nickname;\n }\n\n if (values.description) {\n createInput.description = values.description;\n }\n\n const filteredFeatures = values.features.filter((f) => f.trim());\n if (filteredFeatures.length > 0) {\n createInput.features = filteredFeatures;\n }\n\n if (values.token) {\n createInput.token = parseInt(values.token, 10);\n }\n\n await StripePriceService.createPrice(createInput);\n }\n\n onSuccess();\n onOpenChange(false);\n } catch (error) {\n console.error(\"[PriceEditor] Failed to save price:\", error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const currencyOptions = [\n { id: \"usd\", text: \"USD ($)\" },\n { id: \"eur\", text: \"EUR (€)\" },\n { id: \"gbp\", text: \"GBP (£)\" },\n ];\n\n const intervalOptions = [\n { id: \"one_time\", text: \"One-time\" },\n { id: \"day\", text: \"Daily\" },\n { id: \"week\", text: \"Weekly\" },\n { id: \"month\", text: \"Monthly\" },\n { id: \"year\", text: \"Yearly\" },\n ];\n\n const usageTypeOptions = [\n { id: \"licensed\", text: \"Licensed (per unit)\" },\n { id: \"metered\", text: \"Metered (usage-based)\" },\n ];\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{isEditMode ? \"Edit Price\" : \"Create Price\"}</DialogTitle>\n <DialogDescription>\n {isEditMode\n ? \"Update the price details. Note: Only nickname and active status can be changed.\"\n : \"Create a new price for this product\"}\n </DialogDescription>\n </DialogHeader>\n\n {isEditMode && (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4 flex gap-x-3\">\n <AlertCircle className=\"h-5 w-5 text-blue-600 flex-shrink-0 mt-0.5\" />\n <div className=\"text-sm text-blue-800\">\n <p className=\"font-semibold mb-1\">Stripe Price Immutability</p>\n <p>\n Due to Stripe's architecture, only the nickname and active status can be modified after creation. To\n change amount, currency, or billing interval, create a new price.\n </p>\n </div>\n </div>\n )}\n\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col gap-y-4\">\n <div className=\"grid grid-cols-2 gap-x-4\">\n <FormInput\n form={form}\n id=\"unitAmount\"\n name=\"Amount (in dollars)\"\n placeholder=\"9.99\"\n disabled={isEditMode}\n isRequired\n />\n\n <FormSelect form={form} id=\"currency\" name=\"Currency\" values={currencyOptions} disabled={isEditMode} />\n </div>\n\n <FormSelect\n form={form}\n id=\"interval\"\n name=\"Billing Interval\"\n values={intervalOptions}\n disabled={isEditMode}\n />\n\n {isRecurring && (\n <div className=\"grid grid-cols-2 gap-x-4\">\n <FormInput\n form={form}\n id=\"intervalCount\"\n name=\"Interval Count\"\n placeholder=\"1\"\n type=\"number\"\n disabled={isEditMode}\n />\n\n <FormSelect\n form={form}\n id=\"usageType\"\n name=\"Usage Type\"\n values={usageTypeOptions}\n disabled={isEditMode}\n />\n </div>\n )}\n\n <FormInput\n form={form}\n id=\"nickname\"\n name=\"Nickname (optional)\"\n placeholder=\"e.g., Standard Plan, Pro Tier\"\n />\n\n <FormTextarea\n form={form}\n id=\"description\"\n name=\"Description (optional)\"\n placeholder=\"Describe what this price tier includes...\"\n className=\"min-h-24\"\n />\n\n <FormInput form={form} id=\"token\" name=\"Token (optional)\" placeholder=\"Enter token value\" />\n\n {/* Features List */}\n <div className=\"space-y-2\">\n <Label>Features (optional)</Label>\n <div className=\"space-y-2\">\n {form.watch(\"features\").map((_, index) => (\n <div key={index} className=\"flex gap-2\">\n <Input\n {...form.register(`features.${index}`)}\n placeholder={`Feature ${index + 1}`}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => {\n const currentFeatures = form.getValues(\"features\");\n form.setValue(\n \"features\",\n currentFeatures.filter((_, i) => i !== index),\n );\n }}\n >\n <XIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n const currentFeatures = form.getValues(\"features\");\n form.setValue(\"features\", [...currentFeatures, \"\"]);\n }}\n className=\"mt-2\"\n >\n <PlusIcon className=\"h-4 w-4 mr-2\" />\n Add Feature\n </Button>\n </div>\n </div>\n\n <FormCheckbox form={form} id=\"active\" name=\"Active\" />\n\n <CommonEditorButtons isEdit={isEditMode} form={form} disabled={isSubmitting} setOpen={onOpenChange} />\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { Archive, DollarSign, Edit, RotateCcw } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Button,\n} from \"../../../../../shadcnui\";\nimport { formatCurrency } from \"../../../components/utils/currency\";\nimport { StripePriceService } from \"../../data\";\nimport { StripePriceInterface } from \"../../data/stripe-price.interface\";\nimport { PriceEditor } from \"../forms/PriceEditor\";\n\ntype PricesListProps = {\n productId: string;\n onPricesChange: () => void;\n};\n\nexport function PricesList({ productId, onPricesChange }: PricesListProps) {\n const [prices, setPrices] = useState<StripePriceInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [showCreatePrice, setShowCreatePrice] = useState<boolean>(false);\n const [editingPrice, setEditingPrice] = useState<StripePriceInterface | null>(null);\n const [priceToArchive, setPriceToArchive] = useState<StripePriceInterface | null>(null);\n const [priceToReactivate, setPriceToReactivate] = useState<StripePriceInterface | null>(null);\n const [archivingPriceId, setArchivingPriceId] = useState<string | null>(null);\n const [reactivatingPriceId, setReactivatingPriceId] = useState<string | null>(null);\n\n const loadPrices = async () => {\n setLoading(true);\n try {\n const fetchedPrices = await StripePriceService.listPrices({ productId });\n setPrices(fetchedPrices);\n } catch (error) {\n console.error(\"[PricesList] Failed to load prices:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadPrices();\n }, [productId]);\n\n const handleArchive = async () => {\n if (!priceToArchive) {\n return;\n }\n\n setArchivingPriceId(priceToArchive.id);\n try {\n await StripePriceService.archivePrice({ id: priceToArchive.id });\n setPriceToArchive(null); // Close dialog on success\n await loadPrices();\n onPricesChange();\n } catch (error) {\n console.error(\"[PricesList] Failed to archive price:\", error);\n // Keep dialog open on error so user can retry or cancel\n } finally {\n setArchivingPriceId(null);\n }\n };\n\n const handleReactivate = async () => {\n if (!priceToReactivate) {\n return;\n }\n\n setReactivatingPriceId(priceToReactivate.id);\n try {\n await StripePriceService.reactivatePrice({ id: priceToReactivate.id });\n setPriceToReactivate(null); // Close dialog on success\n await loadPrices();\n onPricesChange();\n } catch (error) {\n console.error(\"[PricesList] Failed to reactivate price:\", error);\n // Keep dialog open on error so user can retry or cancel\n } finally {\n setReactivatingPriceId(null);\n }\n };\n\n const formatInterval = (price: StripePriceInterface): string => {\n if (price.priceType === \"one_time\") {\n return \"one-time\";\n }\n\n if (price.recurring) {\n const count = price.recurring.intervalCount;\n const interval = price.recurring.interval;\n\n if (count === 1) {\n return `/ ${interval}`;\n } else {\n return `/ ${count} ${interval}s`;\n }\n }\n\n return \"\";\n };\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center py-8\">\n <p className=\"text-muted-foreground\">Loading prices...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-y-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h4 className=\"text-lg font-semibold\">Prices</h4>\n <Button size=\"sm\" onClick={() => setShowCreatePrice(true)}>\n Add Price\n </Button>\n </div>\n\n {/* Empty State */}\n {prices.length === 0 && (\n <div className=\"bg-background flex flex-col items-center justify-center gap-y-3 rounded-lg border border-dashed p-8\">\n <DollarSign className=\"text-muted-foreground h-12 w-12\" />\n <p className=\"text-muted-foreground text-sm\">No prices yet. Add a price to enable subscriptions.</p>\n <Button size=\"sm\" onClick={() => setShowCreatePrice(true)}>\n Add Price\n </Button>\n </div>\n )}\n\n {/* Prices Grid */}\n {prices.length > 0 && (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {prices.map((price) => {\n const isArchiving = archivingPriceId === price.id;\n const isReactivating = reactivatingPriceId === price.id;\n\n return (\n <div key={price.id} className=\"border rounded-lg bg-white p-4 hover:shadow-sm transition-shadow\">\n <div className=\"flex items-start justify-between mb-3\">\n <DollarSign className=\"h-5 w-5 text-primary\" />\n <div className=\"flex gap-1\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setEditingPrice(price)} className=\"h-8 w-8 p-0\">\n <Edit className=\"h-4 w-4\" />\n </Button>\n {price.active ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setPriceToArchive(price)}\n className=\"h-8 w-8 p-0\"\n disabled={isArchiving}\n >\n <Archive className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setPriceToReactivate(price)}\n className=\"h-8 w-8 p-0\"\n disabled={isReactivating}\n >\n <RotateCcw className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n </div>\n\n <div className=\"mb-2\">\n <div className=\"text-2xl font-bold\">\n {formatCurrency(price.unitAmount, price.currency)}{\" \"}\n <span className=\"text-muted-foreground text-sm font-normal\">{formatInterval(price)}</span>\n </div>\n </div>\n\n {price.metadata?.nickname && <p className=\"text-sm font-medium mb-2\">{price.metadata.nickname}</p>}\n\n <div className=\"flex flex-wrap gap-2\">\n {price.active ? (\n <span className=\"bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium\">Active</span>\n ) : (\n <span className=\"bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium\">Inactive</span>\n )}\n\n {price.recurring?.usageType === \"metered\" && (\n <span className=\"bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full font-medium\">Metered</span>\n )}\n\n <span className=\"bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium uppercase\">\n {price.currency}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Create Price Modal */}\n {showCreatePrice && (\n <PriceEditor\n productId={productId}\n open={showCreatePrice}\n onOpenChange={setShowCreatePrice}\n onSuccess={() => {\n loadPrices();\n onPricesChange();\n }}\n />\n )}\n\n {/* Edit Price Modal */}\n {editingPrice && (\n <PriceEditor\n productId={productId}\n price={editingPrice}\n open={!!editingPrice}\n onOpenChange={(open) => !open && setEditingPrice(null)}\n onSuccess={() => {\n loadPrices();\n onPricesChange();\n setEditingPrice(null);\n }}\n />\n )}\n\n {/* Archive Price Confirmation Dialog */}\n <AlertDialog open={!!priceToArchive} onOpenChange={(open) => !open && setPriceToArchive(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Archive Price</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to archive the price for{\" \"}\n {priceToArchive && `${formatCurrency(priceToArchive.unitAmount, priceToArchive.currency)} ${formatInterval(priceToArchive)}`}\n ? This will prevent new subscriptions but existing ones will continue.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={!!archivingPriceId}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleArchive}\n disabled={!!archivingPriceId}\n className=\"bg-red-600 hover:bg-red-700\"\n >\n {archivingPriceId ? \"Archiving...\" : \"Archive\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {/* Reactivate Price Confirmation Dialog */}\n <AlertDialog open={!!priceToReactivate} onOpenChange={(open) => !open && setPriceToReactivate(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Reactivate Price</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to reactivate the price for{\" \"}\n {priceToReactivate && `${formatCurrency(priceToReactivate.unitAmount, priceToReactivate.currency)} ${formatInterval(priceToReactivate)}`}\n ? This will allow new subscriptions again.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={!!reactivatingPriceId}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleReactivate}\n disabled={!!reactivatingPriceId}\n className=\"bg-green-600 hover:bg-green-700\"\n >\n {reactivatingPriceId ? \"Reactivating...\" : \"Reactivate\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n","\"use client\";\n\nimport { Package } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { getRoleId } from \"../../../../../roles\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { useCurrentUserContext } from \"../../../../user/contexts\";\nimport { StripeProductInterface } from \"../../data/stripe-product.interface\";\nimport { StripeProductService } from \"../../data/stripe-product.service\";\nimport { ProductEditor } from \"../forms/ProductEditor\";\nimport { ProductsList } from \"../lists/ProductsList\";\n\nexport function ProductsAdminContainer() {\n const { hasRole } = useCurrentUserContext();\n const [products, setProducts] = useState<StripeProductInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [showCreateProduct, setShowCreateProduct] = useState<boolean>(false);\n\n // Check if user has Administrator role\n if (!hasRole(getRoleId().Administrator)) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-red-600 font-semibold\">Permission denied. Administrator access required.</p>\n </div>\n );\n }\n\n const loadProducts = async () => {\n setLoading(true);\n try {\n const fetchedProducts = await StripeProductService.listProducts();\n setProducts(fetchedProducts);\n } catch (error) {\n console.error(\"[ProductsAdminContainer] Failed to load products:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadProducts();\n }, []);\n\n if (loading) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-muted-foreground\">Loading products...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-x-3\">\n <Package className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Product & Price Management</h1>\n </div>\n <Button onClick={() => setShowCreateProduct(true)}>Create Product</Button>\n </div>\n\n {/* Empty State */}\n {products.length === 0 && (\n <div className=\"bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed p-12\">\n <Package className=\"text-muted-foreground h-16 w-16\" />\n <div className=\"text-center\">\n <h3 className=\"mb-2 text-xl font-semibold\">No products yet</h3>\n <p className=\"text-muted-foreground mb-4\">\n Create your first product to start offering subscriptions to your customers.\n </p>\n <Button onClick={() => setShowCreateProduct(true)}>Create Your First Product</Button>\n </div>\n </div>\n )}\n\n {/* Products List */}\n {products.length > 0 && <ProductsList products={products} onProductsChange={loadProducts} />}\n\n {/* Create Product Modal */}\n {showCreateProduct && (\n <ProductEditor open={showCreateProduct} onOpenChange={setShowCreateProduct} onSuccess={loadProducts} />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { useState } from \"react\";\nimport { SubmitHandler, useForm } from \"react-hook-form\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\nimport { FormCheckbox, FormInput, FormTextarea } from \"../../../../../components\";\nimport { CommonEditorButtons } from \"../../../../../components/forms/CommonEditorButtons\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Form } from \"../../../../../shadcnui\";\nimport { StripeProductInterface } from \"../../data/stripe-product.interface\";\nimport { StripeProductService } from \"../../data/stripe-product.service\";\n\ntype ProductEditorProps = {\n product?: StripeProductInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n};\n\nexport function ProductEditor({ product, open, onOpenChange, onSuccess }: ProductEditorProps) {\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n\n const formSchema = z.object({\n name: z.string().min(1, { message: \"Product name is required\" }),\n description: z.string().min(1, { message: \"Description is required\" }),\n active: z.boolean(),\n });\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n name: product?.name || \"\",\n description: product?.description || \"\",\n active: product?.active ?? true,\n },\n });\n\n const onSubmit: SubmitHandler<z.infer<typeof formSchema>> = async (values) => {\n setIsSubmitting(true);\n\n try {\n if (product) {\n // Update existing product\n await StripeProductService.updateProduct({\n id: product.id,\n name: values.name,\n description: values.description,\n active: values.active,\n });\n } else {\n // Create new product\n await StripeProductService.createProduct({\n id: v4(),\n name: values.name,\n description: values.description,\n active: values.active,\n });\n }\n\n onSuccess();\n onOpenChange(false);\n } catch (error) {\n console.error(\"[ProductEditor] Failed to save product:\", error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{product ? \"Edit Product\" : \"Create Product\"}</DialogTitle>\n <DialogDescription>\n {product ? `Update the details for ${product.name}` : \"Create a new product to offer to your customers\"}\n </DialogDescription>\n </DialogHeader>\n\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col gap-y-4\">\n <FormInput form={form} id=\"name\" name=\"Product Name\" placeholder=\"Enter product name\" isRequired />\n\n <FormTextarea\n form={form}\n id=\"description\"\n name=\"Description\"\n placeholder=\"Enter product description\"\n className=\"min-h-32\"\n />\n\n <FormCheckbox form={form} id=\"active\" name=\"Active\" />\n\n <CommonEditorButtons isEdit={!!product} form={form} disabled={isSubmitting} setOpen={onOpenChange} />\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { Archive, ChevronDown, ChevronUp, Edit, Package, RefreshCw } from \"lucide-react\";\nimport { useState } from \"react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Button,\n} from \"../../../../../shadcnui\";\nimport { PricesList } from \"../../../stripe-price/components/lists/PricesList\";\nimport { StripeProductInterface } from \"../../data/stripe-product.interface\";\nimport { StripeProductService } from \"../../data/stripe-product.service\";\nimport { ProductEditor } from \"../forms/ProductEditor\";\n\ntype ProductsListProps = {\n products: StripeProductInterface[];\n onProductsChange: () => void;\n};\n\nexport function ProductsList({ products, onProductsChange }: ProductsListProps) {\n const [expandedProductId, setExpandedProductId] = useState<string | null>(null);\n const [editingProduct, setEditingProduct] = useState<StripeProductInterface | null>(null);\n const [archivingProductId, setArchivingProductId] = useState<string | null>(null);\n const [reactivatingProductId, setReactivatingProductId] = useState<string | null>(null);\n const [productToArchive, setProductToArchive] = useState<StripeProductInterface | null>(null);\n const [productToReactivate, setProductToReactivate] = useState<StripeProductInterface | null>(null);\n\n const handleArchive = async () => {\n if (!productToArchive) {\n return;\n }\n\n setArchivingProductId(productToArchive.id);\n try {\n const archivedProduct = await StripeProductService.archiveProduct({ id: productToArchive.id });\n setProductToArchive(null); // Close dialog on success\n onProductsChange();\n } catch (error) {\n console.error(\"[ProductsList] Failed to archive product:\", error);\n // Keep dialog open on error so user can retry or cancel\n } finally {\n setArchivingProductId(null);\n }\n };\n\n const handleReactivate = async () => {\n if (!productToReactivate) {\n return;\n }\n\n setReactivatingProductId(productToReactivate.id);\n try {\n const reactivatedProduct = await StripeProductService.reactivateProduct({ id: productToReactivate.id });\n setProductToReactivate(null); // Close dialog on success\n onProductsChange();\n } catch (error) {\n // Keep dialog open on error so user can retry or cancel\n } finally {\n setReactivatingProductId(null);\n }\n };\n\n const toggleExpand = (productId: string) => {\n setExpandedProductId(expandedProductId === productId ? null : productId);\n };\n\n return (\n <div className=\"flex flex-col gap-y-4\">\n {products.map((product) => {\n const isExpanded = expandedProductId === product.id;\n const isArchiving = archivingProductId === product.id;\n const isReactivating = reactivatingProductId === product.id;\n\n return (\n <div key={product.id} className=\"border rounded-lg bg-white shadow-sm hover:shadow-md transition-shadow\">\n {/* Product Card Header */}\n <div className=\"flex items-center justify-between p-6\">\n <div className=\"flex items-center gap-x-4 flex-1\">\n <Package className=\"h-6 w-6 text-primary\" />\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-x-3\">\n <h3 className=\"text-lg font-semibold\">{product.name}</h3>\n {product.active ? (\n <span className=\"bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium\">\n Active\n </span>\n ) : (\n <span className=\"bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium\">\n Inactive\n </span>\n )}\n </div>\n {product.description && <p className=\"text-muted-foreground text-sm mt-1\">{product.description}</p>}\n </div>\n </div>\n\n {/* Action Buttons */}\n <div className=\"flex items-center gap-x-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => setEditingProduct(product)}>\n <Edit className=\"h-4 w-4 mr-1\" />\n Edit\n </Button>\n {product.active ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setProductToArchive(product)}\n disabled={isArchiving}\n >\n <Archive className=\"h-4 w-4 mr-1\" />\n {isArchiving ? \"Archiving...\" : \"Archive\"}\n </Button>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setProductToReactivate(product)}\n disabled={isReactivating}\n >\n <RefreshCw className=\"h-4 w-4 mr-1\" />\n {isReactivating ? \"Reactivating...\" : \"Reactivate\"}\n </Button>\n )}\n <Button variant=\"ghost\" size=\"sm\" onClick={() => toggleExpand(product.id)}>\n {isExpanded ? <ChevronUp className=\"h-5 w-5\" /> : <ChevronDown className=\"h-5 w-5\" />}\n </Button>\n </div>\n </div>\n\n {/* Expandable Prices Section */}\n {isExpanded && (\n <div className=\"border-t bg-muted/30 p-6\">\n <PricesList productId={product.id} onPricesChange={onProductsChange} />\n </div>\n )}\n </div>\n );\n })}\n\n {/* Edit Product Modal */}\n {editingProduct && (\n <ProductEditor\n product={editingProduct}\n open={!!editingProduct}\n onOpenChange={(open) => !open && setEditingProduct(null)}\n onSuccess={() => {\n onProductsChange();\n setEditingProduct(null);\n }}\n />\n )}\n\n {/* Archive Product Confirmation Dialog */}\n <AlertDialog open={!!productToArchive} onOpenChange={(open) => !open && setProductToArchive(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Archive Product</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to archive "{productToArchive?.name}"? This will deactivate it and it will\n no longer be available for new subscriptions.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={!!archivingProductId}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleArchive}\n disabled={!!archivingProductId}\n className=\"bg-red-600 hover:bg-red-700\"\n >\n {archivingProductId ? \"Archiving...\" : \"Archive\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {/* Reactivate Product Confirmation Dialog */}\n <AlertDialog open={!!productToReactivate} onOpenChange={(open) => !open && setProductToReactivate(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Reactivate Product</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to reactivate "{productToReactivate?.name}"? This will make it available\n for new subscriptions again.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={!!reactivatingProductId}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleReactivate}\n disabled={!!reactivatingProductId}\n className=\"bg-green-600 hover:bg-green-700\"\n >\n {reactivatingProductId ? \"Reactivating...\" : \"Reactivate\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"],"mappings":"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","names":["ChevronRight","jsx","jsxs","ChevronRight","jsx","jsxs","ChevronRight","jsx","jsxs","getStatusBadgeVariant","formatDate","ChevronRight","ChevronRight","jsx","jsxs","ChevronRight","CreditCard","Loader2","Wallet","useCallback","useEffect","useMemo","useState","CreditCard","useEffect","useState","useState","jsx","jsxs","useState","jsx","jsxs","useEffect","useState","jsx","jsxs","useState","useEffect","jsx","jsx","jsxs","useState","useEffect","CreditCard","useEffect","useState","useState","formatDate","ExternalLink","jsx","jsx","jsxs","formatDate","ExternalLink","Fragment","jsx","jsxs","useState","formatDate","jsx","jsxs","useState","useEffect","CreditCard","useEffect","useState","useState","useState","useState","jsx","jsxs","useState","formatDate","jsx","statusConfig","Fragment","jsx","jsxs","formatPlanName","useState","formatDate","Fragment","jsx","jsxs","formatPlanName","useState","formatDate","jsx","jsxs","useState","useEffect","CreditCard","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","formatDate","Check","Fragment","jsx","jsxs","Check","useCallback","useEffect","useRef","useCallback","useCallback","Check","jsx","jsxs","Check","useEffect","useMemo","useState","jsx","jsxs","useState","useEffect","useMemo","hasMonthly","hasYearly","jsx","jsxs","formatInterval","jsx","jsxs","jsx","jsxs","useCallback","useRef","useEffect","Activity","useEffect","useState","Activity","jsx","jsxs","formatDate","Activity","jsx","jsx","jsxs","useState","useEffect","hasMeteredSubscriptions","Activity","jsx","jsxs","jsx","jsxs","AlertCircle","jsx","jsxs","AlertCircle","Fragment","jsx","jsxs","useState","useCallback","useMemo","subscriptions","useEffect","Wallet","Loader2","CreditCard","useMemo","Fragment","jsx","useMemo","zodResolver","AlertCircle","useEffect","useState","useForm","z","jsx","jsxs","useState","formSchema","z","useForm","zodResolver","useEffect","AlertCircle","_","useEffect","useState","jsx","jsxs","useState","useEffect","formatInterval","Package","useEffect","useState","zodResolver","useState","useForm","v4","z","jsx","jsxs","useState","formSchema","z","useForm","zodResolver","v4","Archive","Edit","RefreshCw","useState","jsx","jsxs","useState","Edit","Archive","RefreshCw","jsx","jsxs","useState","useEffect","Package"]}
|
|
1
|
+
{"version":3,"sources":["../../src/features/billing/components/cards/SubscriptionSummaryCard.tsx","../../src/features/billing/components/cards/PaymentMethodSummaryCard.tsx","../../src/features/billing/components/cards/CustomerInfoCard.tsx","../../src/features/billing/components/cards/InvoicesSummaryCard.tsx","../../src/features/billing/components/cards/BillingUsageSummaryCard.tsx","../../src/features/billing/components/containers/BillingDashboardContainer.tsx","../../src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx","../../src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx","../../src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx","../../src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx","../../src/features/billing/stripe-customer/components/lists/PaymentMethodsList.tsx","../../src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx","../../src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx","../../src/features/billing/components/utils/currency.ts","../../src/features/billing/components/utils/date.ts","../../src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx","../../src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx","../../src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx","../../src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx","../../src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx","../../src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx","../../src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx","../../src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx","../../src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx","../../src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx","../../src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx","../../src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx","../../src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx","../../src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx","../../src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts","../../src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx","../../src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx","../../src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx","../../src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx","../../src/features/billing/stripe-usage/components/containers/UsageContainer.tsx","../../src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx","../../src/features/billing/stripe-usage/components/widgets/UsageSummaryCards.tsx","../../src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx","../../src/features/billing/components/modals/BillingDetailModal.tsx","../../src/features/billing/components/widgets/BillingAlertBanner.tsx","../../src/features/billing/components/providers/StripeProvider.tsx","../../src/features/billing/stripe-price/components/forms/PriceEditor.tsx","../../src/features/billing/stripe-price/components/lists/PricesList.tsx","../../src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx","../../src/features/billing/stripe-product/components/forms/ProductEditor.tsx","../../src/features/billing/stripe-product/components/lists/ProductsList.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronRight, CreditCard } from \"lucide-react\";\nimport { Badge, Button, Card, CardContent, CardHeader, CardTitle, Skeleton } from \"../../../../shadcnui\";\nimport { StripeSubscriptionInterface, SubscriptionStatus } from \"../../stripe-subscription\";\n\ntype SubscriptionSummaryCardProps = {\n subscriptions: StripeSubscriptionInterface[];\n loading?: boolean;\n error?: string;\n onManageClick: () => void;\n};\n\nfunction getStatusBadgeVariant(status: SubscriptionStatus): \"default\" | \"secondary\" | \"destructive\" | \"outline\" {\n switch (status) {\n case SubscriptionStatus.ACTIVE:\n return \"default\";\n case SubscriptionStatus.TRIALING:\n return \"secondary\";\n case SubscriptionStatus.PAST_DUE:\n case SubscriptionStatus.UNPAID:\n case SubscriptionStatus.CANCELED:\n return \"destructive\";\n default:\n return \"outline\";\n }\n}\n\nfunction formatDate(date: Date): string {\n return new Date(date).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nfunction formatPrice(amount: number | undefined, currency: string | undefined): string {\n if (amount === undefined) return \"N/A\";\n const currencyCode = currency?.toUpperCase() || \"USD\";\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: currencyCode,\n }).format(amount / 100);\n}\n\nfunction formatPlanName(subscription: StripeSubscriptionInterface): string {\n const productName = subscription.price?.product?.name || \"\";\n const nickname = subscription.price?.nickname || \"\";\n\n if (productName && nickname) {\n return `${productName} - ${nickname}`;\n }\n return productName || nickname || \"Subscription\";\n}\n\nexport function SubscriptionSummaryCard({\n subscriptions,\n loading,\n error,\n onManageClick,\n}: SubscriptionSummaryCardProps) {\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Subscriptions</CardTitle>\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-32 mb-2\" />\n <Skeleton className=\"h-4 w-24 mb-1\" />\n <Skeleton className=\"h-4 w-40\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Subscriptions</CardTitle>\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n const activeSubscriptions = subscriptions.filter(\n (sub) => sub.status === SubscriptionStatus.ACTIVE || sub.status === SubscriptionStatus.TRIALING,\n );\n const primarySubscription = activeSubscriptions[0];\n\n return (\n <Card className=\"cursor-pointer hover:bg-accent/50 transition-colors\" onClick={onManageClick}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Subscriptions</CardTitle>\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n {subscriptions.length === 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold text-muted-foreground\">No active plan</p>\n <p className=\"text-xs text-muted-foreground\">Subscribe to get started</p>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2\"\n onClick={(e) => {\n e.stopPropagation();\n onManageClick();\n }}\n >\n View Plans\n <ChevronRight className=\"h-4 w-4 ml-1\" />\n </Button>\n </div>\n ) : primarySubscription ? (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-xl font-bold\">{formatPlanName(primarySubscription)}</p>\n <Badge variant={primarySubscription.cancelAtPeriodEnd ? \"secondary\" : getStatusBadgeVariant(primarySubscription.status)}>\n {primarySubscription.cancelAtPeriodEnd ? \"Canceling\" : primarySubscription.status}\n </Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {formatPrice(primarySubscription.price?.unitAmount, primarySubscription.price?.currency)}\n {primarySubscription.price?.recurring && <span>/{primarySubscription.price.recurring.interval}</span>}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {primarySubscription.cancelAtPeriodEnd\n ? `Cancels on ${formatDate(primarySubscription.currentPeriodEnd)}`\n : `Renews on ${formatDate(primarySubscription.currentPeriodEnd)}`}\n </p>\n {activeSubscriptions.length > 1 && (\n <p className=\"text-xs text-muted-foreground\">+{activeSubscriptions.length - 1} more subscription(s)</p>\n )}\n </div>\n ) : null}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { Wallet, ChevronRight } from \"lucide-react\";\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Button,\n Skeleton,\n} from \"../../../../shadcnui\";\nimport { PaymentMethodInterface } from \"../../stripe-customer\";\n\ntype PaymentMethodSummaryCardProps = {\n paymentMethods: PaymentMethodInterface[];\n defaultPaymentMethodId?: string;\n loading?: boolean;\n error?: string;\n onManageClick: () => void;\n};\n\nfunction getCardBrandIcon(brand: string): string {\n const brandMap: Record<string, string> = {\n visa: \"Visa\",\n mastercard: \"Mastercard\",\n amex: \"Amex\",\n discover: \"Discover\",\n diners: \"Diners\",\n jcb: \"JCB\",\n unionpay: \"UnionPay\",\n };\n return brandMap[brand.toLowerCase()] || brand;\n}\n\nexport function PaymentMethodSummaryCard({\n paymentMethods,\n defaultPaymentMethodId,\n loading,\n error,\n onManageClick,\n}: PaymentMethodSummaryCardProps) {\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Payment Method</CardTitle>\n <Wallet className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-32 mb-2\" />\n <Skeleton className=\"h-4 w-24\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Payment Method</CardTitle>\n <Wallet className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n // Find default payment method or use first one\n const defaultMethod = paymentMethods.find((pm) => pm.id === defaultPaymentMethodId) || paymentMethods[0];\n\n return (\n <Card className=\"cursor-pointer hover:bg-accent/50 transition-colors\" onClick={onManageClick}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Payment Method</CardTitle>\n <Wallet className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n {paymentMethods.length === 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold text-muted-foreground\">No payment method</p>\n <p className=\"text-xs text-muted-foreground\">\n Add a card to enable subscriptions\n </p>\n <Button variant=\"outline\" size=\"sm\" className=\"mt-2\" onClick={(e) => { e.stopPropagation(); onManageClick(); }}>\n Add Card\n <ChevronRight className=\"h-4 w-4 ml-1\" />\n </Button>\n </div>\n ) : defaultMethod?.card ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold\">\n {getCardBrandIcon(defaultMethod.card.brand)} ****{defaultMethod.card.last4}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n Expires {String(defaultMethod.card.expMonth).padStart(2, \"0\")}/{defaultMethod.card.expYear}\n </p>\n {paymentMethods.length > 1 && (\n <p className=\"text-xs text-muted-foreground\">\n +{paymentMethods.length - 1} more card(s)\n </p>\n )}\n </div>\n ) : (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold\">{defaultMethod?.type || \"Payment Method\"}</p>\n {paymentMethods.length > 1 && (\n <p className=\"text-xs text-muted-foreground\">\n +{paymentMethods.length - 1} more method(s)\n </p>\n )}\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { ExternalLink, User } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Button, Card, CardContent, CardHeader, CardTitle, Skeleton } from \"../../../../shadcnui\";\nimport { StripeCustomerInterface, StripeCustomerService } from \"../../stripe-customer\";\n\ntype CustomerInfoCardProps = {\n customer: StripeCustomerInterface | null;\n loading?: boolean;\n error?: string;\n};\n\nfunction formatBalance(balance: number | undefined, currency: string | undefined): string {\n if (balance === undefined || balance === 0) return \"$0.00\";\n const currencyCode = currency?.toUpperCase() || \"USD\";\n // Balance in Stripe is negative when customer has credit\n const displayBalance = -balance;\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: currencyCode,\n }).format(displayBalance / 100);\n}\n\nexport function CustomerInfoCard({ customer, loading, error }: CustomerInfoCardProps) {\n const [portalLoading, setPortalLoading] = useState(false);\n\n const handlePortalClick = async (e: React.MouseEvent) => {\n e.stopPropagation();\n setPortalLoading(true);\n try {\n const { url } = await StripeCustomerService.createPortalSession();\n window.open(url, \"_blank\");\n } catch (err) {\n console.error(\"[CustomerInfoCard] Failed to create portal session:\", err);\n } finally {\n setPortalLoading(false);\n }\n };\n\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Billing Account</CardTitle>\n <User className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-32 mb-2\" />\n <Skeleton className=\"h-4 w-48 mb-1\" />\n <Skeleton className=\"h-4 w-24\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Billing Account</CardTitle>\n <User className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n if (!customer) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Billing Account</CardTitle>\n <User className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-xl font-bold text-muted-foreground\">Not set up</p>\n <p className=\"text-xs text-muted-foreground\">Billing account will be created when you subscribe</p>\n </CardContent>\n </Card>\n );\n }\n\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Billing Account</CardTitle>\n <User className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <div className=\"space-y-2\">\n {customer.name && <p className=\"text-xl font-bold\">{customer.name}</p>}\n {customer.email && <p className=\"text-sm text-muted-foreground\">{customer.email}</p>}\n {customer.balance !== undefined && customer.balance !== 0 && (\n <p className=\"text-sm\">\n <span className=\"text-muted-foreground\">Credit Balance: </span>\n <span className={customer.balance < 0 ? \"text-green-600\" : \"text-destructive\"}>\n {formatBalance(customer.balance, customer.currency)}\n </span>\n </p>\n )}\n <Button variant=\"outline\" size=\"sm\" className=\"mt-2\" onClick={handlePortalClick} disabled={portalLoading}>\n {portalLoading ? \"Loading...\" : \"Manage in Stripe Portal\"}\n <ExternalLink className=\"h-4 w-4 ml-1\" />\n </Button>\n </div>\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { ChevronRight, ReceiptIcon } from \"lucide-react\";\nimport { Badge, Card, CardContent, CardHeader, CardTitle, Skeleton } from \"../../../../shadcnui\";\nimport { InvoiceStatus, StripeInvoiceInterface } from \"../../stripe-invoice\";\n\ntype InvoicesSummaryCardProps = {\n invoices: StripeInvoiceInterface[];\n loading?: boolean;\n error?: string;\n onViewAllClick: () => void;\n};\n\nfunction getStatusBadgeVariant(status: InvoiceStatus): \"default\" | \"secondary\" | \"destructive\" | \"outline\" {\n switch (status) {\n case InvoiceStatus.PAID:\n return \"default\";\n case InvoiceStatus.OPEN:\n return \"secondary\";\n case InvoiceStatus.UNCOLLECTIBLE:\n case InvoiceStatus.VOID:\n return \"destructive\";\n default:\n return \"outline\";\n }\n}\n\nfunction formatDate(date: Date): string {\n return new Date(date).toLocaleDateString(undefined, {\n year: \"numeric\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nfunction formatAmount(amount: number, currency: string): string {\n const currencyCode = currency?.toUpperCase() || \"USD\";\n return new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency: currencyCode,\n }).format(amount / 100);\n}\n\nexport function InvoicesSummaryCard({ invoices, loading, error, onViewAllClick }: InvoicesSummaryCardProps) {\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Recent Invoices</CardTitle>\n <ReceiptIcon className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-24 mb-2\" />\n <Skeleton className=\"h-4 w-32 mb-1\" />\n <Skeleton className=\"h-4 w-20\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Recent Invoices</CardTitle>\n <ReceiptIcon className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n // Get the most recent invoice\n const latestInvoice = invoices[0];\n const paidInvoices = invoices.filter((inv) => inv.status === InvoiceStatus.PAID);\n const openInvoices = invoices.filter((inv) => inv.status === InvoiceStatus.OPEN);\n\n return (\n <Card className=\"cursor-pointer hover:bg-accent/50 transition-colors\" onClick={onViewAllClick}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Recent Invoices</CardTitle>\n <ReceiptIcon className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n {invoices.length === 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold text-muted-foreground\">No invoices yet</p>\n <p className=\"text-xs text-muted-foreground\">Invoices will appear after your first billing cycle</p>\n </div>\n ) : latestInvoice ? (\n <div className=\"space-y-2\">\n <div className=\"flex items-center gap-2\">\n <p className=\"text-xl font-bold\">{formatAmount(latestInvoice.total, latestInvoice.currency)}</p>\n <Badge variant={getStatusBadgeVariant(latestInvoice.status)}>{latestInvoice.status}</Badge>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {latestInvoice.stripeInvoiceNumber || `Invoice from ${formatDate(latestInvoice.periodStart)}`}\n </p>\n <div className=\"flex items-center gap-4 text-xs text-muted-foreground\">\n {paidInvoices.length > 0 && <span>{paidInvoices.length} paid</span>}\n {openInvoices.length > 0 && <span className=\"text-orange-600\">{openInvoices.length} open</span>}\n <span className=\"flex items-center\">\n View all\n <ChevronRight className=\"h-3 w-3 ml-1\" />\n </span>\n </div>\n </div>\n ) : null}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { Activity, ChevronRight } from \"lucide-react\";\nimport { Card, CardContent, CardHeader, CardTitle, Skeleton } from \"../../../../shadcnui\";\nimport { MeterInterface, MeterSummaryInterface } from \"../../stripe-usage\";\n\ntype BillingUsageSummaryCardProps = {\n meters: MeterInterface[];\n summaries: Record<string, MeterSummaryInterface | null>;\n loading?: boolean;\n error?: string;\n onViewDetailsClick: () => void;\n};\n\nfunction formatNumber(value: number): string {\n return new Intl.NumberFormat(undefined, {\n notation: \"compact\",\n compactDisplay: \"short\",\n }).format(value);\n}\n\nexport function BillingUsageSummaryCard({\n meters,\n summaries,\n loading,\n error,\n onViewDetailsClick,\n}: BillingUsageSummaryCardProps) {\n if (loading) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Usage This Month</CardTitle>\n <Activity className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <Skeleton className=\"h-6 w-24 mb-2\" />\n <Skeleton className=\"h-4 w-32\" />\n </CardContent>\n </Card>\n );\n }\n\n if (error) {\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Usage This Month</CardTitle>\n <Activity className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n <p className=\"text-sm text-destructive\">{error}</p>\n </CardContent>\n </Card>\n );\n }\n\n // Calculate total usage across all meters\n const totalUsage = Object.values(summaries).reduce((acc, summary) => {\n return acc + (summary?.aggregatedValue || 0);\n }, 0);\n\n // Get first meter with data for display\n const primaryMeter = meters.find((m) => summaries[m.id]?.aggregatedValue);\n const primarySummary = primaryMeter ? summaries[primaryMeter.id] : null;\n\n return (\n <Card className=\"cursor-pointer hover:bg-accent/50 transition-colors\" onClick={onViewDetailsClick}>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0 pb-2\">\n <CardTitle className=\"text-sm font-medium\">Usage This Month</CardTitle>\n <Activity className=\"h-4 w-4 text-muted-foreground\" />\n </CardHeader>\n <CardContent>\n {meters.length === 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold text-muted-foreground\">No meters</p>\n <p className=\"text-xs text-muted-foreground\">No usage meters are configured</p>\n </div>\n ) : (\n <div className=\"space-y-2\">\n <p className=\"text-xl font-bold\">{formatNumber(totalUsage)} units</p>\n {primaryMeter && primarySummary && (\n <p className=\"text-sm text-muted-foreground\">\n {primaryMeter.displayName}: {formatNumber(primarySummary.aggregatedValue)}\n </p>\n )}\n {meters.length > 1 && <p className=\"text-xs text-muted-foreground\">Across {meters.length} meters</p>}\n <span className=\"flex items-center text-xs text-muted-foreground\">\n View details\n <ChevronRight className=\"h-3 w-3 ml-1\" />\n </span>\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { CreditCard, Loader2, Wallet } from \"lucide-react\";\nimport { useSearchParams } from \"next/navigation\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { Button, Card, CardContent, CardDescription, CardHeader, CardTitle } from \"../../../../shadcnui\";\nimport { PaymentMethodInterface, StripeCustomerInterface, StripeCustomerService } from \"../../stripe-customer\";\nimport { PaymentMethodsContainer } from \"../../stripe-customer/components\";\nimport { StripeInvoiceInterface, StripeInvoiceService } from \"../../stripe-invoice\";\nimport { InvoicesContainer } from \"../../stripe-invoice/components\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService, SubscriptionStatus } from \"../../stripe-subscription\";\nimport { SubscriptionsContainer } from \"../../stripe-subscription/components\";\nimport { SubscriptionWizard } from \"../../stripe-subscription/components/wizards\";\nimport { MeterInterface, MeterSummaryInterface, StripeUsageService } from \"../../stripe-usage\";\nimport { UsageContainer } from \"../../stripe-usage/components\";\nimport {\n BillingUsageSummaryCard,\n CustomerInfoCard,\n InvoicesSummaryCard,\n PaymentMethodSummaryCard,\n SubscriptionSummaryCard,\n} from \"../cards\";\nimport { BillingDetailModal } from \"../modals/BillingDetailModal\";\nimport { BillingAlertBanner } from \"../widgets/BillingAlertBanner\";\n\ntype ModalType = \"subscriptions\" | \"payment-methods\" | \"invoices\" | \"usage\" | null;\n\ntype DataState = {\n customer: StripeCustomerInterface | null;\n subscriptions: StripeSubscriptionInterface[];\n paymentMethods: PaymentMethodInterface[];\n invoices: StripeInvoiceInterface[];\n meters: MeterInterface[];\n meterSummaries: Record<string, MeterSummaryInterface | null>;\n};\n\ntype LoadingState = {\n customer: boolean;\n subscriptions: boolean;\n paymentMethods: boolean;\n invoices: boolean;\n usage: boolean;\n};\n\ntype ErrorState = {\n customer: string | null;\n subscriptions: string | null;\n paymentMethods: string | null;\n invoices: string | null;\n usage: string | null;\n};\n\nexport function BillingDashboardContainer() {\n const [data, setData] = useState<DataState>({\n customer: null,\n subscriptions: [],\n paymentMethods: [],\n invoices: [],\n meters: [],\n meterSummaries: {},\n });\n\n const [loading, setLoading] = useState<LoadingState>({\n customer: true,\n subscriptions: true,\n paymentMethods: true,\n invoices: true,\n usage: true,\n });\n\n const [errors, setErrors] = useState<ErrorState>({\n customer: null,\n subscriptions: null,\n paymentMethods: null,\n invoices: null,\n usage: null,\n });\n\n const [activeModal, setActiveModal] = useState<ModalType>(null);\n const [noCustomerExists, setNoCustomerExists] = useState(false);\n const [creatingCustomer, setCreatingCustomer] = useState(false);\n const searchParams = useSearchParams();\n\n // Wizard state - lifted from SubscriptionsContainer to avoid nested dialogs\n const [showWizard, setShowWizard] = useState(false);\n const [editingSubscription, setEditingSubscription] = useState<StripeSubscriptionInterface | null>(null);\n\n // Check if company has metered subscriptions\n const hasMeteredSubscriptions = useCallback((): boolean => {\n return data.subscriptions.some((sub) => sub.price?.recurring?.usageType === \"metered\");\n }, [data.subscriptions]);\n\n // Check if user has active recurring subscription (for wizard filtering)\n const hasActiveRecurringSubscription = useMemo(() => {\n return data.subscriptions.some(\n (sub) =>\n (sub.status === SubscriptionStatus.ACTIVE || sub.status === SubscriptionStatus.TRIALING) &&\n sub.price?.priceType === \"recurring\",\n );\n }, [data.subscriptions]);\n\n // Fetch all data - first check customer, then fetch rest if customer exists\n const fetchAllData = useCallback(async () => {\n setNoCustomerExists(false);\n\n // First, try to fetch customer\n let customer: StripeCustomerInterface | null = null;\n try {\n customer = await StripeCustomerService.getCustomer();\n setData((prev) => ({ ...prev, customer }));\n setErrors((prev) => ({ ...prev, customer: null }));\n setNoCustomerExists(false);\n } catch (error: unknown) {\n console.error(\"[BillingDashboard] Failed to load customer:\", error);\n // Check if this is a \"not found\" error indicating no customer exists\n const errorMessage = error instanceof Error ? error.message : String(error);\n if (errorMessage.includes(\"Not Found\") || errorMessage.includes(\"not found\")) {\n setNoCustomerExists(true);\n // Stop loading all sections since no customer exists\n setLoading({\n customer: false,\n subscriptions: false,\n paymentMethods: false,\n invoices: false,\n usage: false,\n });\n return; // Don't try to fetch other data\n }\n setErrors((prev) => ({ ...prev, customer: \"Failed to load billing account\" }));\n } finally {\n setLoading((prev) => ({ ...prev, customer: false }));\n }\n\n // If we have a customer, fetch the rest of the data\n if (customer) {\n // Fetch subscriptions\n const fetchSubscriptions = async () => {\n try {\n const subscriptions = await StripeSubscriptionService.listSubscriptions();\n setData((prev) => ({ ...prev, subscriptions }));\n setErrors((prev) => ({ ...prev, subscriptions: null }));\n return subscriptions;\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to load subscriptions:\", error);\n setErrors((prev) => ({ ...prev, subscriptions: \"Failed to load subscriptions\" }));\n return [];\n } finally {\n setLoading((prev) => ({ ...prev, subscriptions: false }));\n }\n };\n\n // Fetch payment methods\n const fetchPaymentMethods = async () => {\n try {\n const paymentMethods = await StripeCustomerService.listPaymentMethods();\n setData((prev) => ({ ...prev, paymentMethods }));\n setErrors((prev) => ({ ...prev, paymentMethods: null }));\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to load payment methods:\", error);\n setErrors((prev) => ({ ...prev, paymentMethods: \"Failed to load payment methods\" }));\n } finally {\n setLoading((prev) => ({ ...prev, paymentMethods: false }));\n }\n };\n\n // Fetch invoices\n const fetchInvoices = async () => {\n try {\n const invoices = await StripeInvoiceService.listInvoices();\n setData((prev) => ({ ...prev, invoices }));\n setErrors((prev) => ({ ...prev, invoices: null }));\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to load invoices:\", error);\n setErrors((prev) => ({ ...prev, invoices: \"Failed to load invoices\" }));\n } finally {\n setLoading((prev) => ({ ...prev, invoices: false }));\n }\n };\n\n // Execute all in parallel\n const [subscriptions] = await Promise.all([fetchSubscriptions(), fetchPaymentMethods(), fetchInvoices()]);\n\n // Check if there are metered subscriptions and fetch usage data\n const hasMetered = subscriptions.some(\n (sub: StripeSubscriptionInterface) => sub.price?.recurring?.usageType === \"metered\",\n );\n\n if (hasMetered) {\n await fetchUsageData();\n } else {\n setLoading((prev) => ({ ...prev, usage: false }));\n }\n }\n }, []);\n\n // Create a new Stripe customer for the company\n const handleCreateCustomer = async () => {\n setCreatingCustomer(true);\n try {\n await StripeCustomerService.createCustomer();\n setNoCustomerExists(false);\n // Refresh all data after customer creation\n await fetchAllData();\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to create customer:\", error);\n setErrors((prev) => ({ ...prev, customer: \"Failed to set up billing\" }));\n } finally {\n setCreatingCustomer(false);\n }\n };\n\n // Fetch usage data (called conditionally)\n const fetchUsageData = async () => {\n try {\n const meters = await StripeUsageService.listMeters();\n setData((prev) => ({ ...prev, meters }));\n\n // Load summaries for each meter (current month)\n const summariesMap: Record<string, MeterSummaryInterface | null> = {};\n const now = new Date();\n const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);\n const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);\n\n for (const meter of meters) {\n try {\n const meterSummaries = await StripeUsageService.getMeterSummaries({\n meterId: meter.id,\n startTime: startOfMonth,\n endTime: endOfMonth,\n });\n summariesMap[meter.id] = meterSummaries.length > 0 ? meterSummaries[0] : null;\n } catch (error) {\n console.error(`[BillingDashboard] Failed to load summaries for meter ${meter.id}:`, error);\n summariesMap[meter.id] = null;\n }\n }\n\n setData((prev) => ({ ...prev, meterSummaries: summariesMap }));\n setErrors((prev) => ({ ...prev, usage: null }));\n } catch (error) {\n console.error(\"[BillingDashboard] Failed to load usage data:\", error);\n setErrors((prev) => ({ ...prev, usage: \"Failed to load usage data\" }));\n } finally {\n setLoading((prev) => ({ ...prev, usage: false }));\n }\n };\n\n // Refresh data after modal actions\n const refreshData = useCallback(async () => {\n // Reset loading states for a refresh\n setLoading({\n customer: true,\n subscriptions: true,\n paymentMethods: true,\n invoices: true,\n usage: true,\n });\n await fetchAllData();\n }, [fetchAllData]);\n\n // Handler to open wizard (can be called from SubscriptionsContainer)\n const handleOpenWizard = useCallback((subscription?: StripeSubscriptionInterface) => {\n setEditingSubscription(subscription || null);\n setShowWizard(true);\n }, []);\n\n // Handler to close wizard\n const handleWizardClose = useCallback(() => {\n setShowWizard(false);\n setEditingSubscription(null);\n refreshData();\n }, [refreshData]);\n\n // Initial data load\n useEffect(() => {\n fetchAllData();\n }, [fetchAllData]);\n\n // Handle URL action parameter for deep linking\n useEffect(() => {\n const action = searchParams.get(\"action\");\n if (action === \"subscribe\") {\n // Open wizard directly (no wrapper modal)\n setShowWizard(true);\n // Clear the URL param to prevent re-triggering on refresh\n window.history.replaceState({}, \"\", window.location.pathname);\n }\n }, [searchParams]);\n\n // Detect critical subscriptions for alert banners\n const criticalSubscriptions = data.subscriptions.filter(\n (sub) =>\n sub.status === SubscriptionStatus.PAST_DUE ||\n (sub.status === SubscriptionStatus.TRIALING &&\n sub.trialEnd &&\n new Date(sub.trialEnd).getTime() - new Date().getTime() <= 7 * 24 * 60 * 60 * 1000),\n );\n\n // Handle modal close with refresh\n const handleModalClose = (open: boolean) => {\n if (!open) {\n setActiveModal(null);\n refreshData();\n }\n };\n\n // Get modal title based on type\n const getModalTitle = (type: ModalType): string => {\n switch (type) {\n case \"subscriptions\":\n return \"Manage Subscriptions\";\n case \"payment-methods\":\n return \"Payment Methods\";\n case \"invoices\":\n return \"Invoice History\";\n case \"usage\":\n return \"Usage Tracking\";\n default:\n return \"\";\n }\n };\n\n // Show loading state while checking for customer\n const isInitialLoading = loading.customer && !noCustomerExists && !data.customer;\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center gap-x-3\">\n <Wallet className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Billing</h1>\n </div>\n\n {/* Initial Loading State */}\n {isInitialLoading && (\n <Card>\n <CardContent className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-muted-foreground\" />\n </CardContent>\n </Card>\n )}\n\n {/* No Customer State - Show Setup Prompt */}\n {noCustomerExists && !isInitialLoading && (\n <Card>\n <CardHeader className=\"text-center\">\n <div className=\"mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10\">\n <CreditCard className=\"h-8 w-8 text-primary\" />\n </div>\n <CardTitle>Set Up Billing</CardTitle>\n <CardDescription>\n Your company doesn't have a billing account yet. Set one up to manage subscriptions, payment methods,\n and view invoices.\n </CardDescription>\n </CardHeader>\n <CardContent className=\"flex justify-center pb-8\">\n <Button onClick={handleCreateCustomer} disabled={creatingCustomer} size=\"lg\">\n {creatingCustomer ? (\n <>\n <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />\n Setting up...\n </>\n ) : (\n \"Set Up Billing Account\"\n )}\n </Button>\n </CardContent>\n {errors.customer && (\n <CardContent className=\"pt-0\">\n <p className=\"text-center text-sm text-destructive\">{errors.customer}</p>\n </CardContent>\n )}\n </Card>\n )}\n\n {/* Main Dashboard Content - Only shown when customer exists */}\n {!noCustomerExists && !isInitialLoading && (\n <>\n {/* Alert Banners */}\n {criticalSubscriptions.map((subscription) => (\n <BillingAlertBanner\n key={subscription.id}\n subscription={subscription}\n onUpdatePayment={() => setActiveModal(\"payment-methods\")}\n onAddPayment={() => setActiveModal(\"payment-methods\")}\n />\n ))}\n\n {/* Summary Cards Grid */}\n <div className=\"grid gap-4 md:grid-cols-2\">\n <SubscriptionSummaryCard\n subscriptions={data.subscriptions}\n loading={loading.subscriptions}\n error={errors.subscriptions || undefined}\n onManageClick={() => {\n if (data.subscriptions.length === 0) {\n // No subscriptions - open wizard directly\n setShowWizard(true);\n } else {\n // Has subscriptions - open manage modal\n setActiveModal(\"subscriptions\");\n }\n }}\n />\n\n <PaymentMethodSummaryCard\n paymentMethods={data.paymentMethods}\n defaultPaymentMethodId={data.customer?.defaultPaymentMethodId}\n loading={loading.paymentMethods}\n error={errors.paymentMethods || undefined}\n onManageClick={() => setActiveModal(\"payment-methods\")}\n />\n\n <CustomerInfoCard\n customer={data.customer}\n loading={loading.customer}\n error={errors.customer || undefined}\n />\n\n <InvoicesSummaryCard\n invoices={data.invoices}\n loading={loading.invoices}\n error={errors.invoices || undefined}\n onViewAllClick={() => setActiveModal(\"invoices\")}\n />\n\n {/* Usage Card - only shown when metered subscriptions exist */}\n {hasMeteredSubscriptions() && (\n <BillingUsageSummaryCard\n meters={data.meters}\n summaries={data.meterSummaries}\n loading={loading.usage}\n error={errors.usage || undefined}\n onViewDetailsClick={() => setActiveModal(\"usage\")}\n />\n )}\n </div>\n\n {/* Detail Modals */}\n <BillingDetailModal\n open={activeModal === \"subscriptions\"}\n onOpenChange={handleModalClose}\n title={getModalTitle(\"subscriptions\")}\n >\n <SubscriptionsContainer onOpenWizard={handleOpenWizard} />\n </BillingDetailModal>\n\n <BillingDetailModal\n open={activeModal === \"payment-methods\"}\n onOpenChange={handleModalClose}\n title={getModalTitle(\"payment-methods\")}\n >\n <PaymentMethodsContainer />\n </BillingDetailModal>\n\n <BillingDetailModal\n open={activeModal === \"invoices\"}\n onOpenChange={handleModalClose}\n title={getModalTitle(\"invoices\")}\n >\n <InvoicesContainer />\n </BillingDetailModal>\n\n <BillingDetailModal\n open={activeModal === \"usage\"}\n onOpenChange={handleModalClose}\n title={getModalTitle(\"usage\")}\n >\n <UsageContainer />\n </BillingDetailModal>\n\n {/* Subscription Wizard - rendered at dashboard level to avoid nested dialogs */}\n <SubscriptionWizard\n open={showWizard}\n onOpenChange={(open) => !open && handleWizardClose()}\n onSuccess={refreshData}\n hasActiveRecurringSubscription={hasActiveRecurringSubscription}\n subscription={editingSubscription ?? undefined}\n />\n </>\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { CreditCard } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { PaymentMethodInterface, StripeCustomerService } from \"../../data\";\nimport { PaymentMethodEditor } from \"../forms/PaymentMethodEditor\";\nimport { PaymentMethodsList } from \"../lists/PaymentMethodsList\";\n\nexport function PaymentMethodsContainer() {\n const [paymentMethods, setPaymentMethods] = useState<PaymentMethodInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [showAddPaymentMethod, setShowAddPaymentMethod] = useState<boolean>(false);\n\n const loadPaymentMethods = async () => {\n setLoading(true);\n try {\n const fetchedPaymentMethods = await StripeCustomerService.listPaymentMethods();\n setPaymentMethods(fetchedPaymentMethods);\n } catch (error) {\n console.error(\"[PaymentMethodsContainer] Failed to load payment methods:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadPaymentMethods();\n }, []);\n\n if (loading) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-muted-foreground\">Loading payment methods...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-x-3\">\n <CreditCard className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Payment Methods</h1>\n </div>\n <Button onClick={() => setShowAddPaymentMethod(true)}>Add Payment Method</Button>\n </div>\n\n {/* Empty State */}\n {paymentMethods.length === 0 && (\n <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\">\n <CreditCard className=\"h-16 w-16 text-muted-foreground\" />\n <div className=\"text-center\">\n <h3 className=\"mb-2 text-xl font-semibold\">No payment methods</h3>\n <p className=\"mb-4 text-muted-foreground\">\n Add a payment method to enable subscriptions and secure checkout.\n </p>\n <Button onClick={() => setShowAddPaymentMethod(true)}>Add Your First Card</Button>\n </div>\n </div>\n )}\n\n {/* Payment Methods List */}\n {paymentMethods.length > 0 && (\n <PaymentMethodsList paymentMethods={paymentMethods} onUpdate={loadPaymentMethods} />\n )}\n\n {/* Add Payment Method Modal */}\n {showAddPaymentMethod && (\n <PaymentMethodEditor\n open={showAddPaymentMethod}\n onOpenChange={setShowAddPaymentMethod}\n onSuccess={loadPaymentMethods}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { CardElement, useElements, useStripe } from \"@stripe/react-stripe-js\";\nimport { useEffect, useState } from \"react\";\nimport {\n Alert,\n AlertDescription,\n Button,\n Checkbox,\n Label,\n} from \"../../../../../shadcnui\";\nimport { StripeCustomerService } from \"../../data\";\n\ntype PaymentMethodFormProps = {\n onSuccess: () => void;\n onCancel: () => void;\n isLoading?: boolean;\n};\n\nexport function PaymentMethodForm({ onSuccess, onCancel, isLoading = false }: PaymentMethodFormProps) {\n const stripe = useStripe();\n const elements = useElements();\n\n const [setupIntent, setSetupIntent] = useState<{ clientSecret: string } | null>(null);\n const [loading, setLoading] = useState<boolean>(true);\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n const [error, setError] = useState<string | null>(null);\n const [setAsDefault, setSetAsDefault] = useState<boolean>(true);\n\n // Fetch setup intent on component mount\n useEffect(() => {\n const fetchSetupIntent = async () => {\n setLoading(true);\n try {\n const intent = await StripeCustomerService.createSetupIntent();\n setSetupIntent(intent);\n } catch (err) {\n console.error(\"[PaymentMethodForm] Failed to create setup intent:\", err);\n setError(\"Failed to initialize payment form. Please try again.\");\n } finally {\n setLoading(false);\n }\n };\n\n fetchSetupIntent();\n }, []);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n\n if (!stripe || !elements || !setupIntent) {\n return;\n }\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n const cardElement = elements.getElement(CardElement);\n if (!cardElement) {\n throw new Error(\"Card element not found\");\n }\n\n // Confirm card setup with Stripe\n const { error: stripeError, setupIntent: confirmedSetupIntent } = await stripe.confirmCardSetup(\n setupIntent.clientSecret,\n {\n payment_method: {\n card: cardElement,\n },\n },\n );\n\n if (stripeError) {\n console.error(\"[PaymentMethodForm] Stripe error:\", stripeError);\n setError(stripeError.message || \"Failed to add payment method. Please check your card details.\");\n setIsSubmitting(false);\n return;\n }\n\n // Set as default if checkbox is checked\n if (setAsDefault && confirmedSetupIntent?.payment_method) {\n await StripeCustomerService.setDefaultPaymentMethod({\n paymentMethodId:\n typeof confirmedSetupIntent.payment_method === \"string\"\n ? confirmedSetupIntent.payment_method\n : confirmedSetupIntent.payment_method.id,\n });\n }\n\n onSuccess();\n } catch (err: any) {\n console.error(\"[PaymentMethodForm] Error:\", err);\n setError(err.message || \"An unexpected error occurred. Please try again.\");\n } finally {\n setIsSubmitting(false);\n }\n };\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center py-8\">\n <p className=\"text-muted-foreground\">Loading payment form...</p>\n </div>\n );\n }\n\n if (!setupIntent && error) {\n return (\n <Alert variant=\"destructive\" className=\"bg-red-50 border-red-200\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className=\"flex flex-col gap-y-4\">\n {/* Card Element */}\n <div className=\"rounded-md border border-gray-300 p-3\">\n <CardElement\n options={{\n style: {\n base: {\n fontSize: \"16px\",\n color: \"#424770\",\n \"::placeholder\": {\n color: \"#aab7c4\",\n },\n },\n invalid: {\n color: \"#9e2146\",\n },\n },\n }}\n />\n </div>\n\n {/* Set as Default Checkbox */}\n <div className=\"flex items-center gap-x-2\">\n <Checkbox\n id=\"setAsDefault\"\n checked={setAsDefault}\n onCheckedChange={(checked) => setSetAsDefault(!!checked)}\n />\n <Label htmlFor=\"setAsDefault\" className=\"text-sm font-normal\">\n Set as default payment method\n </Label>\n </div>\n\n {/* Error Alert */}\n {error && (\n <Alert variant=\"destructive\" className=\"bg-red-50 border-red-200\">\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n )}\n\n {/* Action Buttons */}\n <div className=\"flex justify-end gap-x-2\">\n <Button type=\"button\" variant=\"outline\" onClick={onCancel} disabled={isSubmitting || isLoading}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={!stripe || isSubmitting || isLoading}>\n {isSubmitting ? \"Processing...\" : \"Add Card\"}\n </Button>\n </div>\n </form>\n );\n}\n","\"use client\";\n\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../../../../../shadcnui\";\nimport { PaymentMethodForm } from \"./PaymentMethodForm\";\n\ntype PaymentMethodEditorProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n};\n\nexport function PaymentMethodEditor({ open, onOpenChange, onSuccess }: PaymentMethodEditorProps) {\n const handleSuccess = () => {\n onSuccess();\n onOpenChange(false);\n };\n\n const handleCancel = () => {\n onOpenChange(false);\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Add Payment Method</DialogTitle>\n <DialogDescription>\n Add a new payment method to your account. Your card information is securely processed by Stripe.\n </DialogDescription>\n </DialogHeader>\n {open && (\n <PaymentMethodForm\n onSuccess={handleSuccess}\n onCancel={handleCancel}\n />\n )}\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { MoreVertical } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from \"../../../../../shadcnui\";\nimport { PaymentMethodInterface, StripeCustomerInterface, StripeCustomerService } from \"../../data\";\n\ntype PaymentMethodCardProps = {\n paymentMethod: PaymentMethodInterface;\n onUpdate: () => void;\n};\n\n// Card brand icons mapping\nconst brandIcons: Record<string, string> = {\n visa: \"💳\",\n mastercard: \"💳\",\n amex: \"💳\",\n discover: \"💳\",\n};\n\nexport function PaymentMethodCard({ paymentMethod, onUpdate }: PaymentMethodCardProps) {\n const [loading, setLoading] = useState<boolean>(false);\n const [customer, setCustomer] = useState<StripeCustomerInterface | null>(null);\n const [showRemoveDialog, setShowRemoveDialog] = useState<boolean>(false);\n\n // Load customer to check default payment method\n useEffect(() => {\n const loadCustomer = async () => {\n try {\n const fetchedCustomer = await StripeCustomerService.getCustomer();\n setCustomer(fetchedCustomer);\n } catch (error) {\n console.error(\"[PaymentMethodCard] Failed to load customer:\", error);\n }\n };\n\n loadCustomer();\n }, []);\n\n const isDefault = customer?.defaultPaymentMethodId === paymentMethod.id;\n const brand = paymentMethod.card?.brand || \"card\";\n const last4 = paymentMethod.card?.last4 || \"****\";\n const expMonth = paymentMethod.card?.expMonth || 0;\n const expYear = paymentMethod.card?.expYear || 0;\n const brandIcon = brandIcons[brand.toLowerCase()] || \"💳\";\n\n const handleSetDefault = async () => {\n setLoading(true);\n try {\n await StripeCustomerService.setDefaultPaymentMethod({ paymentMethodId: paymentMethod.id });\n onUpdate();\n } catch (error) {\n console.error(\"[PaymentMethodCard] Failed to set as default:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n const handleRemove = async () => {\n setLoading(true);\n try {\n await StripeCustomerService.removePaymentMethod({ paymentMethodId: paymentMethod.id });\n setShowRemoveDialog(false);\n onUpdate();\n } catch (error) {\n console.error(\"[PaymentMethodCard] Failed to remove:\", error);\n setLoading(false);\n }\n };\n\n return (\n <>\n <Card className=\"relative\">\n {/* Default Badge */}\n {isDefault && (\n <Badge className=\"absolute right-2 top-2 bg-green-100 text-green-800 hover:bg-green-100\">Default</Badge>\n )}\n\n <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n <div className=\"flex items-center gap-x-2\">\n <span className=\"text-2xl\">{brandIcon}</span>\n <span className=\"text-sm font-medium capitalize\">{brand}</span>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger>\n <Button render={<div />} nativeButton={false} variant=\"ghost\" size=\"sm\" disabled={loading} className=\"h-8 w-8 p-0\">\n <MoreVertical className=\"h-4 w-4\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {!isDefault && (\n <DropdownMenuItem onClick={handleSetDefault} disabled={loading}>\n Set as Default\n </DropdownMenuItem>\n )}\n <DropdownMenuItem onClick={() => setShowRemoveDialog(true)} disabled={loading} className=\"text-red-600\">\n Remove\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </CardHeader>\n\n <CardContent>\n <div className=\"flex flex-col gap-y-1\">\n <p className=\"text-lg font-semibold\">•••• {last4}</p>\n <p className=\"text-sm text-muted-foreground\">\n Expires {String(expMonth).padStart(2, \"0\")}/{expYear}\n </p>\n </div>\n </CardContent>\n </Card>\n\n {/* Remove Confirmation Dialog */}\n <AlertDialog open={showRemoveDialog} onOpenChange={setShowRemoveDialog}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Remove Payment Method</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to remove this payment method? This action cannot be undone.\n {isDefault && \" This is your default payment method.\"}\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={loading}>Cancel</AlertDialogCancel>\n <AlertDialogAction onClick={handleRemove} disabled={loading} className=\"bg-red-600 hover:bg-red-700\">\n {loading ? \"Removing...\" : \"Remove\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </>\n );\n}\n","\"use client\";\n\nimport { PaymentMethodInterface } from \"../../data\";\nimport { PaymentMethodCard } from \"../details/PaymentMethodCard\";\n\ntype PaymentMethodsListProps = {\n paymentMethods: PaymentMethodInterface[];\n onUpdate: () => void;\n};\n\nexport function PaymentMethodsList({ paymentMethods, onUpdate }: PaymentMethodsListProps) {\n return (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {paymentMethods.map((paymentMethod) => (\n <PaymentMethodCard key={paymentMethod.id} paymentMethod={paymentMethod} onUpdate={onUpdate} />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { Tabs, TabsList, TabsTrigger } from \"../../../../../shadcnui\";\nimport { InvoiceStatus, StripeInvoiceInterface } from \"../../data/stripe-invoice.interface\";\nimport { StripeInvoiceService } from \"../../data/stripe-invoice.service\";\nimport { InvoicesList } from \"../lists/InvoicesList\";\n\ntype StatusFilter = InvoiceStatus | \"all\";\n\nexport function InvoicesContainer() {\n const [invoices, setInvoices] = useState<StripeInvoiceInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [statusFilter, setStatusFilter] = useState<StatusFilter>(\"all\");\n\n const loadInvoices = async () => {\n setLoading(true);\n try {\n const params = statusFilter !== \"all\" ? { status: statusFilter } : undefined;\n const data = await StripeInvoiceService.listInvoices(params);\n setInvoices(data);\n } catch (error) {\n console.error(\"[InvoicesContainer] Failed to load invoices:\", error);\n setInvoices([]);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadInvoices();\n }, [statusFilter]);\n\n const handleFilterChange = (value: string) => {\n setStatusFilter(value as StatusFilter);\n };\n\n return (\n <div className=\"space-y-4\">\n {/* Status Filter Tabs */}\n <Tabs value={statusFilter} onValueChange={handleFilterChange}>\n <TabsList>\n <TabsTrigger value=\"all\">All</TabsTrigger>\n <TabsTrigger value={InvoiceStatus.PAID}>Paid</TabsTrigger>\n <TabsTrigger value={InvoiceStatus.OPEN}>Open</TabsTrigger>\n <TabsTrigger value={InvoiceStatus.VOID}>Void</TabsTrigger>\n <TabsTrigger value={InvoiceStatus.UNCOLLECTIBLE}>Uncollectible</TabsTrigger>\n </TabsList>\n </Tabs>\n\n {/* Loading State */}\n {loading && <div className=\"text-center py-8 text-muted-foreground\">Loading invoices...</div>}\n\n {/* Empty State */}\n {!loading && invoices.length === 0 && (\n <div className=\"border border-dashed border-gray-300 rounded-lg p-8 text-center\">\n <p className=\"text-lg font-medium text-muted-foreground mb-2\">No invoices yet</p>\n <p className=\"text-sm text-muted-foreground\">Invoices will appear here after your first billing cycle</p>\n </div>\n )}\n\n {/* Invoices List */}\n {!loading && invoices.length > 0 && <InvoicesList invoices={invoices} onInvoicesChange={loadInvoices} />}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\nimport { StripeInvoiceInterface } from \"../../data/stripe-invoice.interface\";\nimport { InvoiceDetails } from \"../details/InvoiceDetails\";\nimport { InvoiceStatusBadge } from \"../widgets/InvoiceStatusBadge\";\n\ntype InvoicesListProps = {\n invoices: StripeInvoiceInterface[];\n onInvoicesChange: () => void;\n};\n\nexport function InvoicesList({ invoices, onInvoicesChange }: InvoicesListProps) {\n const [selectedInvoice, setSelectedInvoice] = useState<StripeInvoiceInterface | null>(null);\n\n const handleRowClick = (invoice: StripeInvoiceInterface) => {\n setSelectedInvoice(invoice);\n };\n\n const getInvoiceNumber = (invoice: StripeInvoiceInterface): string => {\n if (invoice.stripeInvoiceNumber) {\n return invoice.stripeInvoiceNumber;\n }\n // Use last 8 characters of stripeInvoiceId as fallback\n return invoice.stripeInvoiceId.slice(-8);\n };\n\n return (\n <>\n <div className=\"border rounded-lg overflow-hidden\">\n <Table>\n <TableHeader className=\"bg-muted\">\n <TableRow>\n <TableHead>Invoice #</TableHead>\n <TableHead>Date</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"text-right\">Amount</TableHead>\n <TableHead>Period</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {invoices.map((invoice) => {\n const invoiceNumber = getInvoiceNumber(invoice);\n const date = formatDate(invoice.periodStart);\n const amount = formatCurrency(invoice.total, invoice.currency);\n const period = `${formatDate(invoice.periodStart)} - ${formatDate(invoice.periodEnd)}`;\n\n return (\n <TableRow\n key={invoice.id}\n onClick={() => handleRowClick(invoice)}\n className=\"cursor-pointer hover:bg-muted/50\"\n >\n <TableCell className=\"font-medium\">{invoiceNumber}</TableCell>\n <TableCell className=\"text-muted-foreground text-sm\">{date}</TableCell>\n <TableCell>\n <InvoiceStatusBadge status={invoice.status} />\n </TableCell>\n <TableCell className=\"text-right font-medium\">{amount}</TableCell>\n <TableCell className=\"text-muted-foreground text-sm\">{period}</TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n\n {/* Invoice Details Dialog */}\n {selectedInvoice && (\n <InvoiceDetails\n invoice={selectedInvoice}\n open={!!selectedInvoice}\n onOpenChange={(open) => !open && setSelectedInvoice(null)}\n onInvoiceChange={() => {\n onInvoicesChange();\n setSelectedInvoice(null);\n }}\n />\n )}\n </>\n );\n}\n","import { StripePriceInterface } from \"../../stripe-price/data/stripe-price.interface\";\n\n/**\n * Format price recurring interval for display\n * @param price - Stripe price object\n * @returns Formatted interval string (e.g., \"/month\", \"/year\", \"/2 weeks\", \"one-time\")\n */\nexport function formatInterval(price: StripePriceInterface): string {\n if (price.priceType === \"one_time\" || !price.recurring) {\n return \"one-time\";\n }\n\n const { interval, intervalCount } = price.recurring;\n\n if (intervalCount === 1) {\n return `/${interval}`;\n }\n\n // Pluralize the interval for counts > 1\n const pluralInterval =\n interval === \"day\" ? \"days\" : interval === \"week\" ? \"weeks\" : interval === \"month\" ? \"months\" : \"years\";\n return `/${intervalCount} ${pluralInterval}`;\n}\n\n/**\n * Format currency amount from cents to localized currency string\n * @param amount - Amount in cents\n * @param currency - Currency code (e.g., \"USD\", \"EUR\", \"GBP\")\n * @returns Formatted currency string (e.g., \"$9.99\", \"€9,99\")\n */\nexport function formatCurrency(amount: number | undefined, currency: string): string {\n if (amount === undefined) return \"$0.00\";\n\n // Convert cents to dollars\n const dollars = amount / 100;\n\n try {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: currency.toUpperCase(),\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(dollars);\n } catch (error) {\n console.error(\"Error formatting currency:\", error);\n // Fallback if currency code is invalid\n return `$${dollars.toFixed(2)}`;\n }\n}\n","/**\n * Format a date to a localized date string\n * @param date - Date object or ISO string\n * @returns Formatted date string (e.g., \"Jan 15, 2025\")\n */\nexport function formatDate(date: Date | string | undefined): string {\n if (!date) return \"N/A\";\n\n const dateObj = typeof date === \"string\" ? new Date(date) : date;\n\n try {\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n }).format(dateObj);\n } catch (error) {\n console.error(\"Error formatting date:\", error);\n return \"Invalid Date\";\n }\n}\n","\"use client\";\n\nimport { Download, ExternalLink, RefreshCw } from \"lucide-react\";\nimport { Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\nimport { InvoiceStatus, StripeInvoiceInterface } from \"../../data/stripe-invoice.interface\";\nimport { InvoiceStatusBadge } from \"../widgets/InvoiceStatusBadge\";\n\ntype InvoiceDetailsProps = {\n invoice: StripeInvoiceInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onInvoiceChange: () => void;\n};\n\nexport function InvoiceDetails({ invoice, open, onOpenChange, onInvoiceChange }: InvoiceDetailsProps) {\n const handleDownloadPDF = () => {\n if (invoice.stripePdfUrl) {\n window.open(invoice.stripePdfUrl, \"_blank\");\n }\n };\n\n const handleRetryPayment = async () => {\n // TODO: Implement retry payment logic\n };\n\n const handleViewInStripe = () => {\n if (invoice.stripeHostedInvoiceUrl) {\n window.open(invoice.stripeHostedInvoiceUrl, \"_blank\");\n }\n };\n\n const getInvoiceNumber = (): string => {\n if (invoice.stripeInvoiceNumber) {\n return invoice.stripeInvoiceNumber;\n }\n return invoice.stripeInvoiceId.slice(-8);\n };\n\n const productName = invoice.subscription?.price?.product?.name || \"Subscription\";\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>Invoice {getInvoiceNumber()}</DialogTitle>\n <DialogDescription>{formatDate(invoice.periodStart)}</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-6\">\n {/* Status */}\n <div className=\"flex items-center gap-x-3\">\n <span className=\"text-sm font-medium text-muted-foreground\">Status:</span>\n <InvoiceStatusBadge status={invoice.status} />\n </div>\n\n {/* Invoice Info Grid */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <span className=\"text-sm font-medium text-muted-foreground\">Billing Period:</span>\n <p className=\"font-medium\">\n {formatDate(invoice.periodStart)} - {formatDate(invoice.periodEnd)}\n </p>\n </div>\n\n {invoice.dueDate && (\n <div>\n <span className=\"text-sm font-medium text-muted-foreground\">Due Date:</span>\n <p className=\"font-medium\">{formatDate(invoice.dueDate)}</p>\n </div>\n )}\n\n {invoice.paidAt && (\n <div>\n <span className=\"text-sm font-medium text-muted-foreground\">Paid Date:</span>\n <p className=\"font-medium\">{formatDate(invoice.paidAt)}</p>\n </div>\n )}\n\n <div>\n <span className=\"text-sm font-medium text-muted-foreground\">Attempt Count:</span>\n <p className=\"font-medium\">{invoice.attemptCount}</p>\n </div>\n </div>\n\n {/* Line Items */}\n <div>\n <h4 className=\"text-sm font-medium text-muted-foreground mb-2\">Line Items</h4>\n <div className=\"border rounded-lg overflow-hidden\">\n <table className=\"w-full\">\n <thead className=\"bg-muted\">\n <tr>\n <th className=\"text-left p-3 text-sm font-medium\">Description</th>\n <th className=\"text-right p-3 text-sm font-medium\">Amount</th>\n </tr>\n </thead>\n <tbody>\n <tr className=\"border-t\">\n <td className=\"p-3\">{productName}</td>\n <td className=\"p-3 text-right\">{formatCurrency(invoice.subtotal, invoice.currency)}</td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n\n {/* Amount Breakdown */}\n <div className=\"space-y-2 border-t pt-4\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Subtotal:</span>\n <span className=\"font-medium\">{formatCurrency(invoice.subtotal, invoice.currency)}</span>\n </div>\n\n {invoice.tax !== undefined && invoice.tax > 0 && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Tax:</span>\n <span className=\"font-medium\">{formatCurrency(invoice.tax, invoice.currency)}</span>\n </div>\n )}\n\n <div className=\"flex justify-between text-lg font-semibold border-t pt-2\">\n <span>Total:</span>\n <span>{formatCurrency(invoice.total, invoice.currency)}</span>\n </div>\n\n {invoice.amountPaid > 0 && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Amount Paid:</span>\n <span className=\"font-medium text-green-600\">\n {formatCurrency(invoice.amountPaid, invoice.currency)}\n </span>\n </div>\n )}\n\n {invoice.amountRemaining > 0 && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Amount Due:</span>\n <span className=\"font-medium text-red-600\">\n {formatCurrency(invoice.amountRemaining, invoice.currency)}\n </span>\n </div>\n )}\n </div>\n\n {/* Action Buttons */}\n <div className=\"flex flex-wrap gap-2 pt-4 border-t\">\n {invoice.stripePdfUrl && (\n <Button variant=\"outline\" onClick={handleDownloadPDF}>\n <Download className=\"mr-2 h-4 w-4\" />\n Download PDF\n </Button>\n )}\n\n {invoice.status === InvoiceStatus.OPEN && invoice.attempted && (\n <Button variant=\"default\" onClick={handleRetryPayment}>\n <RefreshCw className=\"mr-2 h-4 w-4\" />\n Retry Payment\n </Button>\n )}\n\n {invoice.stripeHostedInvoiceUrl && (\n <Button variant=\"outline\" onClick={handleViewInStripe}>\n <ExternalLink className=\"mr-2 h-4 w-4\" />\n View in Stripe\n </Button>\n )}\n </div>\n </div>\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { InvoiceStatus } from \"../../data/stripe-invoice.interface\";\n\ntype InvoiceStatusBadgeProps = {\n status: InvoiceStatus;\n};\n\ntype StatusConfig = {\n label: string;\n color: string;\n};\n\nconst statusConfig: Record<InvoiceStatus, StatusConfig> = {\n [InvoiceStatus.DRAFT]: {\n label: \"Draft\",\n color: \"bg-gray-100 text-gray-800\",\n },\n [InvoiceStatus.OPEN]: {\n label: \"Open\",\n color: \"bg-blue-100 text-blue-800\",\n },\n [InvoiceStatus.PAID]: {\n label: \"Paid\",\n color: \"bg-green-100 text-green-800\",\n },\n [InvoiceStatus.VOID]: {\n label: \"Void\",\n color: \"bg-gray-100 text-gray-800\",\n },\n [InvoiceStatus.UNCOLLECTIBLE]: {\n label: \"Uncollectible\",\n color: \"bg-red-100 text-red-800\",\n },\n};\n\nexport function InvoiceStatusBadge({ status }: InvoiceStatusBadgeProps) {\n const config = statusConfig[status] || statusConfig[InvoiceStatus.DRAFT];\n\n return <span className={`${config.color} text-xs px-2 py-1 rounded-full font-medium`}>{config.label}</span>;\n}\n","\"use client\";\n\nimport { CreditCard } from \"lucide-react\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { BillingAlertBanner } from \"../../../components\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService, SubscriptionStatus } from \"../../data\";\nimport { SubscriptionsList } from \"../lists\";\n\ntype SubscriptionsContainerProps = {\n onOpenWizard?: (subscription?: StripeSubscriptionInterface) => void;\n};\n\nexport function SubscriptionsContainer({ onOpenWizard }: SubscriptionsContainerProps) {\n const [subscriptions, setSubscriptions] = useState<StripeSubscriptionInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n\n const loadSubscriptions = useCallback(async () => {\n setLoading(true);\n try {\n const fetchedSubscriptions = await StripeSubscriptionService.listSubscriptions();\n setSubscriptions(fetchedSubscriptions);\n } catch (error) {\n console.error(\"[SubscriptionsContainer] Failed to load subscriptions:\", error);\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect(() => {\n loadSubscriptions();\n }, []);\n\n // Detect critical subscriptions\n const criticalSubscriptions = subscriptions.filter(\n (sub) =>\n sub.status === SubscriptionStatus.PAST_DUE ||\n (sub.status === SubscriptionStatus.TRIALING &&\n sub.trialEnd &&\n new Date(sub.trialEnd).getTime() - new Date().getTime() <= 7 * 24 * 60 * 60 * 1000),\n );\n\n if (loading) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-muted-foreground\">Loading subscriptions...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-x-3\">\n <CreditCard className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Subscriptions</h1>\n </div>\n {subscriptions.length > 0 && (\n <Button onClick={() => onOpenWizard?.()}>Subscribe to a Plan</Button>\n )}\n </div>\n\n {/* Alert Banners */}\n {criticalSubscriptions.map((subscription) => (\n <BillingAlertBanner key={subscription.id} subscription={subscription} />\n ))}\n\n {/* Empty state CTA */}\n {subscriptions.length === 0 && (\n <div className=\"flex flex-col items-center justify-center py-12 space-y-4\">\n <CreditCard className=\"h-16 w-16 text-muted-foreground\" />\n <div className=\"text-center\">\n <h3 className=\"text-xl font-semibold mb-2\">No Active Subscriptions</h3>\n <p className=\"text-muted-foreground mb-6\">\n Choose a subscription plan to get started with our services.\n </p>\n <Button onClick={() => onOpenWizard?.()}>Subscribe to a Plan</Button>\n </div>\n </div>\n )}\n\n {/* Subscriptions List */}\n {subscriptions.length > 0 && (\n <SubscriptionsList\n subscriptions={subscriptions}\n onSubscriptionsChange={loadSubscriptions}\n onChangePlan={(sub) => onOpenWizard?.(sub)}\n />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { StripeSubscriptionInterface } from \"../../data\";\nimport { SubscriptionDetails } from \"../details/SubscriptionDetails\";\nimport { SubscriptionStatusBadge } from \"../widgets/SubscriptionStatusBadge\";\n\n/**\n * Formats the plan name from price data.\n * Format: \"Product Name - Nickname (Interval)\" e.g., \"Only 35 - Pro (Monthly)\"\n */\nfunction formatPlanName(price: StripePriceInterface | undefined): string {\n if (!price) return \"N/A\";\n\n const productName = price.product?.name || \"\";\n const nickname = price.nickname || \"\";\n\n // Format interval: \"month\" -> \"Monthly\", \"year\" -> \"Yearly\", etc.\n let interval = \"\";\n if (price.recurring?.interval) {\n const intervalMap: Record<string, string> = {\n day: \"Daily\",\n week: \"Weekly\",\n month: \"Monthly\",\n year: \"Yearly\",\n };\n interval = intervalMap[price.recurring.interval] || price.recurring.interval;\n }\n\n // Build the plan label: \"Product - Nickname\" or just \"Product\"\n const parts = [productName, nickname].filter(Boolean);\n const planLabel = parts.join(\" - \");\n\n // Add interval in parentheses if available\n return interval ? `${planLabel} (${interval})` : planLabel || \"N/A\";\n}\n\ntype SubscriptionsListProps = {\n subscriptions: StripeSubscriptionInterface[];\n onSubscriptionsChange: () => void;\n onChangePlan?: (subscription: StripeSubscriptionInterface) => void;\n};\n\nexport function SubscriptionsList({ subscriptions, onSubscriptionsChange, onChangePlan }: SubscriptionsListProps) {\n const [selectedSub, setSelectedSub] = useState<StripeSubscriptionInterface | null>(null);\n\n const handleRowClick = (subscription: StripeSubscriptionInterface) => {\n setSelectedSub(subscription);\n };\n\n return (\n <>\n <div className=\"border rounded-lg overflow-hidden\">\n <Table>\n <TableHeader className=\"bg-muted\">\n <TableRow>\n <TableHead>Status</TableHead>\n <TableHead>Plan</TableHead>\n <TableHead>Period</TableHead>\n <TableHead className=\"text-right\">Amount</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {subscriptions.map((subscription) => {\n const price = subscription.price;\n const amount = price?.unitAmount ? formatCurrency(price.unitAmount, price.currency) : \"N/A\";\n const period = `${formatDate(subscription.currentPeriodStart)} - ${formatDate(subscription.currentPeriodEnd)}`;\n\n return (\n <TableRow\n key={subscription.id}\n onClick={() => handleRowClick(subscription)}\n className=\"cursor-pointer hover:bg-muted/50\"\n >\n <TableCell>\n <SubscriptionStatusBadge status={subscription.status} cancelAtPeriodEnd={subscription.cancelAtPeriodEnd} />\n </TableCell>\n <TableCell className=\"font-medium\">{formatPlanName(price)}</TableCell>\n <TableCell className=\"text-muted-foreground text-sm\">{period}</TableCell>\n <TableCell className=\"text-right font-medium\">{amount}</TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n\n {/* Subscription Details Dialog */}\n {selectedSub && (\n <SubscriptionDetails\n subscription={selectedSub}\n open={!!selectedSub}\n onOpenChange={(open) => !open && setSelectedSub(null)}\n onSubscriptionChange={() => {\n onSubscriptionsChange();\n setSelectedSub(null);\n }}\n onChangePlan={\n onChangePlan\n ? (sub) => {\n setSelectedSub(null); // Close details dialog first\n onChangePlan(sub); // Then open wizard at parent level\n }\n : undefined\n }\n />\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { useState } from \"react\";\nimport { Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\nimport { StripeCustomerService } from \"../../../stripe-customer\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService, SubscriptionStatus } from \"../../data\";\nimport { CancelSubscriptionDialog } from \"../forms/CancelSubscriptionDialog\";\nimport { SubscriptionStatusBadge } from \"../widgets/SubscriptionStatusBadge\";\n\n/**\n * Formats the plan name from price data.\n * Format: \"Product Name - Nickname (Interval)\" e.g., \"Only 35 - Pro (Monthly)\"\n */\nfunction formatPlanName(price: StripePriceInterface | undefined): string {\n if (!price) return \"N/A\";\n\n const productName = price.product?.name || \"\";\n const nickname = price.nickname || \"\";\n\n // Format interval: \"month\" -> \"Monthly\", \"year\" -> \"Yearly\", etc.\n let interval = \"\";\n if (price.recurring?.interval) {\n const intervalMap: Record<string, string> = {\n day: \"Daily\",\n week: \"Weekly\",\n month: \"Monthly\",\n year: \"Yearly\",\n };\n interval = intervalMap[price.recurring.interval] || price.recurring.interval;\n }\n\n // Build the plan label: \"Product - Nickname\" or just \"Product\"\n const parts = [productName, nickname].filter(Boolean);\n const planLabel = parts.join(\" - \");\n\n // Add interval in parentheses if available\n return interval ? `${planLabel} (${interval})` : planLabel || \"N/A\";\n}\n\n/**\n * Formats the billing amount from price data.\n */\nfunction formatBillingAmount(price: StripePriceInterface | undefined): string {\n if (!price?.unitAmount) return \"N/A\";\n return formatCurrency(price.unitAmount, price.currency);\n}\n\ntype SubscriptionDetailsProps = {\n subscription: StripeSubscriptionInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSubscriptionChange: () => void;\n onChangePlan?: (subscription: StripeSubscriptionInterface) => void;\n};\n\nexport function SubscriptionDetails({\n subscription,\n open,\n onOpenChange,\n onSubscriptionChange,\n onChangePlan,\n}: SubscriptionDetailsProps) {\n const [showCancel, setShowCancel] = useState<boolean>(false);\n const [isProcessing, setIsProcessing] = useState<boolean>(false);\n\n const handlePause = async () => {\n setIsProcessing(true);\n try {\n await StripeSubscriptionService.pauseSubscription({ subscriptionId: subscription.id });\n onSubscriptionChange();\n } catch (error) {\n console.error(\"[SubscriptionDetails] Failed to pause subscription:\", error);\n } finally {\n setIsProcessing(false);\n }\n };\n\n const handleResume = async () => {\n setIsProcessing(true);\n try {\n await StripeSubscriptionService.resumeSubscription({ subscriptionId: subscription.id });\n onSubscriptionChange();\n } catch (error) {\n console.error(\"[SubscriptionDetails] Failed to resume subscription:\", error);\n } finally {\n setIsProcessing(false);\n }\n };\n\n const handleManageViaPortal = async () => {\n try {\n const { url } = await StripeCustomerService.createPortalSession();\n window.open(url, \"_blank\");\n } catch (error) {\n console.error(\"[SubscriptionDetails] Failed to create portal session:\", error);\n }\n };\n\n const canPause = subscription.status === SubscriptionStatus.ACTIVE;\n const canResume = subscription.status === SubscriptionStatus.PAUSED;\n const canCancel =\n subscription.status === SubscriptionStatus.ACTIVE ||\n subscription.status === SubscriptionStatus.TRIALING ||\n subscription.status === SubscriptionStatus.PAUSED;\n\n return (\n <>\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>Subscription Details</DialogTitle>\n <DialogDescription>View and manage your subscription</DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-6\">\n {/* Status */}\n <div className=\"flex items-center gap-x-3\">\n <span className=\"text-sm font-medium text-muted-foreground\">Status:</span>\n <SubscriptionStatusBadge status={subscription.status} cancelAtPeriodEnd={subscription.cancelAtPeriodEnd} />\n </div>\n\n {/* Plan Info */}\n <div className=\"space-y-2\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Plan:</span>\n <span className=\"font-medium\">{formatPlanName(subscription.price)}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Billing Amount:</span>\n <span className=\"font-medium\">{formatBillingAmount(subscription.price)}</span>\n </div>\n </div>\n\n {/* Current Period */}\n <div className=\"space-y-2\">\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Current Period:</span>\n <span className=\"font-medium\">\n {formatDate(subscription.currentPeriodStart)} - {formatDate(subscription.currentPeriodEnd)}\n </span>\n </div>\n </div>\n\n {/* Trial Info */}\n {subscription.trialEnd && (\n <div className=\"flex justify-between\">\n <span className=\"text-sm font-medium text-muted-foreground\">Trial Ends:</span>\n <span className=\"font-medium\">{formatDate(subscription.trialEnd)}</span>\n </div>\n )}\n\n {/* Cancellation Warning */}\n {subscription.cancelAtPeriodEnd && (\n <div className=\"bg-yellow-50 border border-yellow-200 rounded-lg p-3\">\n <p className=\"text-sm text-yellow-800\">\n This subscription will be canceled at the end of the current period on{\" \"}\n {formatDate(subscription.currentPeriodEnd)}.\n </p>\n </div>\n )}\n\n {/* Action Buttons */}\n <div className=\"flex flex-wrap gap-2 pt-4 border-t\">\n {onChangePlan && (\n <Button variant=\"default\" onClick={() => onChangePlan(subscription)}>\n Change Plan\n </Button>\n )}\n\n {canPause && (\n <Button variant=\"outline\" onClick={handlePause} disabled={isProcessing}>\n {isProcessing ? \"Pausing...\" : \"Pause\"}\n </Button>\n )}\n\n {canResume && (\n <Button variant=\"outline\" onClick={handleResume} disabled={isProcessing}>\n {isProcessing ? \"Resuming...\" : \"Resume\"}\n </Button>\n )}\n\n {canCancel && (\n <Button variant=\"destructive\" onClick={() => setShowCancel(true)}>\n Cancel\n </Button>\n )}\n\n <Button variant=\"outline\" onClick={handleManageViaPortal}>\n Manage via Portal\n </Button>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n\n {/* Cancel Subscription Dialog */}\n {showCancel && (\n <CancelSubscriptionDialog\n subscription={subscription}\n open={showCancel}\n onOpenChange={setShowCancel}\n onSuccess={() => {\n onSubscriptionChange();\n setShowCancel(false);\n }}\n />\n )}\n </>\n );\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { useState } from \"react\";\nimport { SubmitHandler, useForm } from \"react-hook-form\";\nimport { z } from \"zod\";\nimport { FormCheckbox, FormTextarea } from \"../../../../../components\";\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n Form,\n} from \"../../../../../shadcnui\";\nimport { formatDate } from \"../../../components/utils\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService } from \"../../data\";\n\ntype CancelSubscriptionDialogProps = {\n subscription: StripeSubscriptionInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n};\n\nconst formSchema = z.object({\n cancelImmediately: z.boolean(),\n reason: z.string().optional(),\n});\n\nexport function CancelSubscriptionDialog({\n subscription,\n open,\n onOpenChange,\n onSuccess,\n}: CancelSubscriptionDialogProps) {\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n cancelImmediately: false,\n reason: \"\",\n },\n });\n\n const cancelImmediately = form.watch(\"cancelImmediately\");\n\n const onSubmit: SubmitHandler<z.infer<typeof formSchema>> = async (values) => {\n setIsSubmitting(true);\n\n try {\n await StripeSubscriptionService.cancelSubscription({\n id: subscription.id,\n cancelImmediately: values.cancelImmediately,\n });\n\n onSuccess();\n onOpenChange(false);\n } catch (error) {\n console.error(\"[CancelSubscriptionDialog] Failed to cancel subscription:\", error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const periodEndDate = formatDate(subscription.currentPeriodEnd);\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-md\">\n <DialogHeader>\n <DialogTitle>Cancel Subscription</DialogTitle>\n <DialogDescription>\n Are you sure you want to cancel this subscription? This action cannot be undone.\n </DialogDescription>\n </DialogHeader>\n\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col gap-y-4\">\n <FormCheckbox form={form} id=\"cancelImmediately\" name=\"Cancel Immediately\" />\n\n {cancelImmediately ? (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-800\">\n Your subscription will be canceled immediately and you will lose access right away.\n </div>\n ) : (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-3 text-sm text-blue-800\">\n Your subscription will remain active until {periodEndDate}. You can continue using the service until\n then.\n </div>\n )}\n\n <FormTextarea\n form={form}\n id=\"reason\"\n name=\"Reason (Optional)\"\n placeholder=\"Let us know why you're canceling...\"\n className=\"min-h-24\"\n />\n\n <div className=\"flex gap-x-2 justify-end pt-2\">\n <Button type=\"button\" variant=\"outline\" onClick={() => onOpenChange(false)} disabled={isSubmitting}>\n Keep Subscription\n </Button>\n <Button type=\"submit\" variant=\"destructive\" disabled={isSubmitting}>\n {isSubmitting ? \"Canceling...\" : \"Confirm Cancellation\"}\n </Button>\n </div>\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { SubscriptionStatus } from \"../../data\";\n\ntype SubscriptionStatusBadgeProps = {\n status: SubscriptionStatus;\n cancelAtPeriodEnd?: boolean;\n};\n\ntype StatusConfig = {\n label: string;\n color: string;\n};\n\nconst statusConfig: Record<SubscriptionStatus, StatusConfig> = {\n [SubscriptionStatus.ACTIVE]: {\n label: \"Active\",\n color: \"bg-green-100 text-green-800\",\n },\n [SubscriptionStatus.TRIALING]: {\n label: \"Trial\",\n color: \"bg-blue-100 text-blue-800\",\n },\n [SubscriptionStatus.PAST_DUE]: {\n label: \"Past Due\",\n color: \"bg-red-100 text-red-800\",\n },\n [SubscriptionStatus.CANCELED]: {\n label: \"Canceled\",\n color: \"bg-gray-100 text-gray-800\",\n },\n [SubscriptionStatus.PAUSED]: {\n label: \"Paused\",\n color: \"bg-yellow-100 text-yellow-800\",\n },\n [SubscriptionStatus.UNPAID]: {\n label: \"Unpaid\",\n color: \"bg-orange-100 text-orange-800\",\n },\n [SubscriptionStatus.INCOMPLETE]: {\n label: \"Incomplete\",\n color: \"bg-gray-100 text-gray-800\",\n },\n [SubscriptionStatus.INCOMPLETE_EXPIRED]: {\n label: \"Expired\",\n color: \"bg-gray-100 text-gray-800\",\n },\n};\n\nconst cancelingConfig: StatusConfig = {\n label: \"Canceling\",\n color: \"bg-amber-100 text-amber-800\",\n};\n\nexport function SubscriptionStatusBadge({ status, cancelAtPeriodEnd }: SubscriptionStatusBadgeProps) {\n // Show \"Canceling\" when subscription is set to cancel at period end\n const config = cancelAtPeriodEnd ? cancelingConfig : statusConfig[status] || statusConfig[SubscriptionStatus.CANCELED];\n\n return <span className={`${config.color} text-xs px-2 py-1 rounded-full font-medium`}>{config.label}</span>;\n}\n","\"use client\";\n\nimport { Tabs, TabsList, TabsTrigger } from \"../../../../../shadcnui\";\n\nexport type BillingInterval = \"month\" | \"year\";\n\nexport type IntervalToggleProps = {\n value: BillingInterval;\n onChange: (interval: BillingInterval) => void;\n hasMonthly: boolean;\n hasYearly: boolean;\n};\n\nexport function IntervalToggle({ value, onChange, hasMonthly, hasYearly }: IntervalToggleProps) {\n // Only render if BOTH intervals are available\n if (!hasMonthly || !hasYearly) {\n return null;\n }\n\n return (\n <Tabs value={value} onValueChange={(v) => onChange(v as BillingInterval)}>\n <TabsList>\n <TabsTrigger value=\"month\">Monthly</TabsTrigger>\n <TabsTrigger value=\"year\">Yearly</TabsTrigger>\n </TabsList>\n </Tabs>\n );\n}\n","\"use client\";\n\nimport { Check } from \"lucide-react\";\nimport { KeyboardEvent } from \"react\";\nimport { Badge, Button, Card, CardContent, CardFooter, CardHeader } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatInterval } from \"../../../components/utils\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { cn } from \"../../../../../utils/cn\";\n\nexport type PricingCardProps = {\n price: StripePriceInterface;\n isCurrentPlan?: boolean;\n isSelected?: boolean;\n isDisabled?: boolean;\n isLoading?: boolean;\n onSelect: (price: StripePriceInterface) => void;\n};\n\nexport function PricingCard({ price, isCurrentPlan = false, isSelected = false, isDisabled = false, isLoading = false, onSelect }: PricingCardProps) {\n const description = price.description || price.nickname || \"Standard\";\n const features = price.features || [];\n const formattedPrice = formatCurrency(price.unitAmount, price.currency);\n const interval = formatInterval(price);\n\n const handleKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if ((e.key === \"Enter\" || e.key === \" \") && !isDisabled && !isCurrentPlan) {\n e.preventDefault();\n onSelect(price);\n }\n };\n\n const handleClick = () => {\n if (!isDisabled && !isCurrentPlan && !isLoading) {\n onSelect(price);\n }\n };\n\n return (\n <Card\n role=\"radio\"\n aria-checked={isSelected}\n aria-label={`${description} plan at ${formattedPrice} ${interval}`}\n tabIndex={isDisabled ? -1 : 0}\n onKeyDown={handleKeyDown}\n onClick={handleClick}\n className={cn(\n \"relative cursor-pointer transition-all duration-200 flex flex-col h-full\",\n \"focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\",\n isCurrentPlan && \"bg-muted/30\",\n isSelected && !isCurrentPlan && \"ring-2 ring-primary\",\n !isDisabled && !isCurrentPlan && \"hover:shadow-md hover:border-primary/50\",\n isDisabled && \"opacity-50 pointer-events-none\",\n isLoading && \"pointer-events-none\"\n )}\n >\n {isCurrentPlan && (\n <Badge variant=\"secondary\" className=\"absolute top-2 right-2\">\n Current\n </Badge>\n )}\n\n <CardHeader className=\"pb-2\">\n <h3 className=\"font-semibold text-lg\">{description}</h3>\n </CardHeader>\n\n <CardContent className=\"pb-4 grow\">\n <div className=\"mb-4\">\n <span className=\"text-3xl font-bold\">{formattedPrice}</span>\n <span className=\"text-muted-foreground ml-1\">{interval}</span>\n </div>\n\n {features.length > 0 && (\n <ul className=\"space-y-2\">\n {features.map((feature, index) => (\n <li key={index} className=\"flex items-start gap-2\">\n <Check className=\"h-4 w-4 text-green-500 mt-0.5 shrink-0\" />\n <span className=\"text-sm text-muted-foreground\">{feature}</span>\n </li>\n ))}\n </ul>\n )}\n </CardContent>\n\n <CardFooter>\n <Button\n variant={isCurrentPlan ? \"secondary\" : isSelected ? \"default\" : \"outline\"}\n className=\"w-full\"\n disabled={isDisabled || isCurrentPlan || isLoading}\n >\n {isLoading ? \"Processing...\" : isCurrentPlan ? \"Current Plan\" : isSelected ? \"Selected\" : \"Select Plan\"}\n </Button>\n </CardFooter>\n </Card>\n );\n}\n","\"use client\";\n\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { StripeProductInterface } from \"../../../stripe-product\";\nimport { PricingCard } from \"./PricingCard\";\n\nexport type ProductPricingRowProps = {\n product: StripeProductInterface;\n prices: StripePriceInterface[]; // Multiple prices for this product\n currentPriceId?: string;\n selectedPriceId?: string;\n loadingPriceId?: string;\n onSelectPrice: (price: StripePriceInterface) => void;\n};\n\nexport function ProductPricingRow({\n product,\n prices,\n currentPriceId,\n selectedPriceId,\n loadingPriceId,\n onSelectPrice,\n}: ProductPricingRowProps) {\n if (prices.length === 0) {\n return null;\n }\n\n return (\n <div className=\"space-y-3\">\n {/* Product name header */}\n <h3 className=\"font-semibold text-lg\">{product.name}</h3>\n\n {/* Price cards in columns */}\n <div\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\"\n role=\"radiogroup\"\n aria-label={`Pricing options for ${product.name}`}\n >\n {prices\n .sort((a, b) => (a.unitAmount ?? 0) - (b.unitAmount ?? 0))\n .map((price) => (\n <PricingCard\n key={price.id}\n price={price}\n isCurrentPlan={price.id === currentPriceId}\n isSelected={price.id === selectedPriceId}\n isLoading={price.id === loadingPriceId}\n onSelect={onSelectPrice}\n />\n ))}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { Skeleton } from \"../../../../../shadcnui\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { StripeProductInterface } from \"../../../stripe-product\";\nimport { BillingInterval } from \"./IntervalToggle\";\nimport { ProductPricingRow } from \"./ProductPricingRow\";\n\nexport type ProductPricingListProps = {\n products: StripeProductInterface[];\n selectedInterval: BillingInterval;\n currentPriceId?: string;\n selectedPriceId?: string;\n loadingPriceId?: string;\n loading?: boolean;\n onSelectPrice: (price: StripePriceInterface) => void;\n hideRecurringPrices?: boolean;\n};\n\nfunction isRecurringProduct(prices: StripePriceInterface[]): boolean {\n return prices.some((p) => p.priceType === \"recurring\");\n}\n\nfunction getFilteredPrices(prices: StripePriceInterface[], selectedInterval: BillingInterval): StripePriceInterface[] {\n const isRecurring = isRecurringProduct(prices);\n\n if (!isRecurring) {\n return prices.filter((p) => p.priceType === \"one_time\");\n }\n\n const intervalPrices = prices.filter(\n (p) => p.priceType === \"recurring\" && p.recurring?.interval === selectedInterval,\n );\n\n if (intervalPrices.length === 0) {\n const fallbackInterval = selectedInterval === \"month\" ? \"year\" : \"month\";\n return prices.filter((p) => p.priceType === \"recurring\" && p.recurring?.interval === fallbackInterval);\n }\n\n return intervalPrices;\n}\n\nexport function ProductPricingList({\n products,\n selectedInterval,\n currentPriceId,\n selectedPriceId,\n loadingPriceId,\n loading = false,\n onSelectPrice,\n hideRecurringPrices = false,\n}: ProductPricingListProps) {\n if (loading) {\n return <ProductPricingListSkeleton />;\n }\n\n if (products.length === 0) {\n return <div className=\"text-center py-8 text-muted-foreground\">No plans available</div>;\n }\n\n const sortedProducts = [...products].sort((a, b) => {\n const aRecurring = isRecurringProduct(a.stripePrices || []);\n const bRecurring = isRecurringProduct(b.stripePrices || []);\n if (aRecurring && !bRecurring) return -1;\n if (!aRecurring && bRecurring) return 1;\n return 0;\n });\n\n // Filter products based on hideRecurringPrices\n const filteredProducts = hideRecurringPrices\n ? sortedProducts\n .map((product) => ({\n ...product,\n stripePrices: (product.stripePrices || []).filter((price) => price.priceType !== \"recurring\"),\n }))\n .filter((product) => product.stripePrices.length > 0)\n : sortedProducts;\n\n return (\n <div className=\"space-y-6\">\n {filteredProducts.map((product) => {\n const allPrices = product.stripePrices || [];\n const filteredPrices = getFilteredPrices(allPrices, selectedInterval);\n\n if (filteredPrices.length === 0) {\n return null;\n }\n\n return (\n <ProductPricingRow\n key={product.id}\n product={product}\n prices={filteredPrices}\n currentPriceId={currentPriceId}\n selectedPriceId={selectedPriceId}\n loadingPriceId={loadingPriceId}\n onSelectPrice={onSelectPrice}\n />\n );\n })}\n </div>\n );\n}\n\nfunction ProductPricingListSkeleton() {\n return (\n <div className=\"space-y-6\">\n {[1, 2].map((rowIndex) => (\n <div key={rowIndex} className=\"space-y-3\">\n <Skeleton className=\"h-6 w-32\" />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n {[1, 2, 3].map((cardIndex) => (\n <div key={cardIndex} className=\"p-4 rounded-lg border animate-pulse space-y-3\">\n <Skeleton className=\"h-6 w-24\" />\n <Skeleton className=\"h-8 w-32\" />\n <div className=\"space-y-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n </div>\n <Skeleton className=\"h-10 w-full\" />\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { ProrationPreviewInterface } from \"../../../stripe-invoice/data/stripe-invoice.interface\";\nimport { formatCurrency, formatDate } from \"../../../components/utils\";\n\ntype ProrationPreviewProps = {\n preview: ProrationPreviewInterface;\n};\n\nexport function ProrationPreview({ preview }: ProrationPreviewProps) {\n return (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4\">\n <h4 className=\"font-semibold text-blue-900 mb-3\">Proration Breakdown</h4>\n\n <div className=\"space-y-2\">\n {preview.lineItems.map((item, index) => (\n <div key={index} className=\"flex justify-between text-sm\">\n <span className=\"text-blue-800\">{item.description}</span>\n <span className={`font-medium ${item.amount < 0 ? \"text-green-600\" : \"text-blue-900\"}`}>\n {formatCurrency(item.amount, preview.currency)}\n </span>\n </div>\n ))}\n\n <div className=\"border-t border-blue-200 pt-2 mt-2\">\n <div className=\"flex justify-between font-semibold\">\n <span className=\"text-blue-900\">Net Due Today</span>\n <span className=\"text-blue-900\">{formatCurrency(preview.immediateCharge, preview.currency)}</span>\n </div>\n </div>\n\n {preview.lineItems.length > 0 && preview.lineItems[0].period && (\n <div className=\"text-xs text-blue-700 mt-2\">\n Next invoice on {formatDate(preview.lineItems[0].period.end)} for{\" \"}\n {formatCurrency(preview.amountDue, preview.currency)}\n </div>\n )}\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { Check, Loader2 } from \"lucide-react\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { formatCurrency, formatInterval } from \"../../../components/utils\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\n\ntype SubscriptionConfirmationProps = {\n price: StripePriceInterface;\n isLoading: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n};\n\nexport function SubscriptionConfirmation({ price, isLoading, onConfirm, onCancel }: SubscriptionConfirmationProps) {\n const productName = price.product?.name || price.nickname || \"Selected Plan\";\n const productDescription = price.product?.description || price.description;\n const features = price.features || [];\n\n return (\n <div className=\"bg-accent/10 border border-accent/30 rounded-lg p-4\">\n <h4 className=\"font-semibold mb-3\">Confirm Your Subscription</h4>\n\n <div className=\"space-y-3\">\n {/* Plan name and description */}\n <div>\n <div className=\"font-medium\">{productName}</div>\n {productDescription && <div className=\"text-sm text-muted-foreground\">{productDescription}</div>}\n </div>\n\n {/* Price */}\n <div className=\"text-lg font-semibold\">\n {formatCurrency(price.unitAmount, price.currency)}\n <span className=\"text-sm font-normal text-muted-foreground\">{formatInterval(price)}</span>\n </div>\n\n {/* Features */}\n {features.length > 0 && (\n <div className=\"space-y-1\">\n {features.map((feature, index) => (\n <div key={index} className=\"flex items-center gap-2 text-sm \">\n <Check className=\"h-4 w-4 text-primary\" />\n <span>{feature}</span>\n </div>\n ))}\n </div>\n )}\n\n {/* Action buttons */}\n <div className=\"flex justify-end gap-3 pt-2 border-t border-accent/30\">\n <Button variant=\"outline\" onClick={onCancel} disabled={isLoading}>\n Cancel\n </Button>\n <Button onClick={onConfirm} disabled={isLoading}>\n {isLoading ? (\n <>\n <Loader2 className=\"h-4 w-4 animate-spin mr-2\" />\n Processing...\n </>\n ) : (\n \"Subscribe\"\n )}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useRef } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n} from \"../../../../../shadcnui\";\nimport { StripeSubscriptionInterface } from \"../../data\";\nimport { useSubscriptionWizard } from \"../../hooks/useSubscriptionWizard\";\nimport { WizardProgressIndicator } from \"./WizardProgressIndicator\";\nimport { WizardStepPlanSelection } from \"./WizardStepPlanSelection\";\nimport { WizardStepReview } from \"./WizardStepReview\";\nimport { WizardStepPaymentMethod } from \"./WizardStepPaymentMethod\";\n\nexport type SubscriptionWizardProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n hasActiveRecurringSubscription: boolean;\n subscription?: StripeSubscriptionInterface;\n};\n\nexport function SubscriptionWizard({\n open,\n onOpenChange,\n onSuccess,\n hasActiveRecurringSubscription,\n subscription,\n}: SubscriptionWizardProps) {\n const handleClose = useCallback(() => onOpenChange(false), [onOpenChange]);\n\n const { state, actions } = useSubscriptionWizard({\n subscription,\n onSuccess,\n onClose: handleClose,\n });\n\n // Track if we've already checked payment method for this open state\n const hasCheckedRef = useRef(false);\n\n // Check payment method on mount\n useEffect(() => {\n if (open && !hasCheckedRef.current) {\n hasCheckedRef.current = true;\n actions.checkPaymentMethod();\n }\n if (!open) {\n hasCheckedRef.current = false;\n }\n }, [open, actions.checkPaymentMethod]);\n\n // Reset state when dialog closes\n useEffect(() => {\n if (!open) {\n actions.reset();\n }\n }, [open, actions.reset]);\n\n const dialogTitle = subscription ? \"Change Subscription Plan\" : \"Subscribe to a Plan\";\n const dialogDescription = subscription\n ? \"Select a new plan for your subscription\"\n : \"Choose a subscription plan to get started\";\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{dialogTitle}</DialogTitle>\n <DialogDescription>{dialogDescription}</DialogDescription>\n </DialogHeader>\n\n <WizardProgressIndicator currentStep={state.step} />\n\n {state.step === \"plan-selection\" && (\n <WizardStepPlanSelection\n selectedPrice={state.selectedPrice}\n selectedInterval={state.selectedInterval}\n currentPriceId={subscription?.price?.id}\n hideRecurringPrices={hasActiveRecurringSubscription && !subscription}\n onSelectPrice={actions.selectPrice}\n onIntervalChange={actions.setInterval}\n onNext={actions.goToReview}\n isProcessing={state.isProcessing}\n />\n )}\n\n {state.step === \"review\" && (\n <WizardStepReview\n selectedPrice={state.selectedPrice}\n subscription={subscription}\n prorationPreview={state.prorationPreview}\n hasPaymentMethod={state.hasPaymentMethod}\n error={state.error}\n isProcessing={state.isProcessing}\n onBack={() => actions.goToStep(\"plan-selection\")}\n onAddPaymentMethod={() => actions.goToStep(\"payment-method\")}\n onConfirm={actions.confirmSubscription}\n />\n )}\n\n {state.step === \"payment-method\" && (\n <WizardStepPaymentMethod\n onBack={() => actions.goToStep(\"review\")}\n onSuccess={actions.handlePaymentMethodSuccess}\n isProcessing={state.isProcessing}\n />\n )}\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { useCallback, useMemo, useReducer, useRef } from \"react\";\nimport { v4 } from \"uuid\";\nimport { StripeCustomerService } from \"../../stripe-customer/data/stripe-customer.service\";\nimport { ProrationPreviewInterface } from \"../../stripe-invoice/data/stripe-invoice.interface\";\nimport { StripePriceInterface } from \"../../stripe-price/data/stripe-price.interface\";\nimport { BillingInterval } from \"../components/widgets/IntervalToggle\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService } from \"../data\";\n\nexport type WizardStep = \"plan-selection\" | \"review\" | \"payment-method\";\n\nexport type WizardState = {\n step: WizardStep;\n selectedPrice: StripePriceInterface | null;\n selectedInterval: BillingInterval;\n hasPaymentMethod: boolean;\n isProcessing: boolean;\n error: string | null;\n prorationPreview: ProrationPreviewInterface | null;\n};\n\ntype WizardAction =\n | { type: \"SET_STEP\"; step: WizardStep }\n | { type: \"SELECT_PRICE\"; price: StripePriceInterface }\n | { type: \"SET_INTERVAL\"; interval: BillingInterval }\n | { type: \"SET_HAS_PAYMENT_METHOD\"; hasMethod: boolean }\n | { type: \"SET_PROCESSING\"; isProcessing: boolean }\n | { type: \"SET_ERROR\"; error: string | null }\n | { type: \"SET_PRORATION_PREVIEW\"; preview: ProrationPreviewInterface | null }\n | { type: \"RESET\" };\n\nconst initialState: WizardState = {\n step: \"plan-selection\",\n selectedPrice: null,\n selectedInterval: \"month\",\n hasPaymentMethod: false,\n isProcessing: false,\n error: null,\n prorationPreview: null,\n};\n\nfunction wizardReducer(state: WizardState, action: WizardAction): WizardState {\n switch (action.type) {\n case \"SET_STEP\":\n return { ...state, step: action.step, error: null };\n case \"SELECT_PRICE\":\n return { ...state, selectedPrice: action.price };\n case \"SET_INTERVAL\":\n return { ...state, selectedInterval: action.interval };\n case \"SET_HAS_PAYMENT_METHOD\":\n return { ...state, hasPaymentMethod: action.hasMethod };\n case \"SET_PROCESSING\":\n return { ...state, isProcessing: action.isProcessing };\n case \"SET_ERROR\":\n return { ...state, error: action.error };\n case \"SET_PRORATION_PREVIEW\":\n return { ...state, prorationPreview: action.preview };\n case \"RESET\":\n return initialState;\n default:\n return state;\n }\n}\n\nexport type UseSubscriptionWizardOptions = {\n subscription?: StripeSubscriptionInterface;\n onSuccess: () => void;\n onClose: () => void;\n};\n\nexport function useSubscriptionWizard({ subscription, onSuccess, onClose }: UseSubscriptionWizardOptions) {\n const [state, dispatch] = useReducer(wizardReducer, {\n ...initialState,\n selectedPrice: subscription?.price || null,\n });\n\n // Use refs for callbacks to avoid dependency changes\n const onSuccessRef = useRef(onSuccess);\n const onCloseRef = useRef(onClose);\n onSuccessRef.current = onSuccess;\n onCloseRef.current = onClose;\n\n const checkPaymentMethod = useCallback(async () => {\n try {\n const methods = await StripeCustomerService.listPaymentMethods();\n dispatch({ type: \"SET_HAS_PAYMENT_METHOD\", hasMethod: methods.length > 0 });\n } catch (error) {\n console.error(\"[useSubscriptionWizard] Failed to check payment methods:\", error);\n dispatch({ type: \"SET_HAS_PAYMENT_METHOD\", hasMethod: false });\n }\n }, []);\n\n const selectPrice = useCallback((price: StripePriceInterface) => {\n dispatch({ type: \"SELECT_PRICE\", price });\n }, []);\n\n const setInterval = useCallback((interval: BillingInterval) => {\n dispatch({ type: \"SET_INTERVAL\", interval });\n }, []);\n\n const goToStep = useCallback((step: WizardStep) => {\n dispatch({ type: \"SET_STEP\", step });\n }, []);\n\n const goToReview = useCallback(async () => {\n if (!state.selectedPrice) return;\n\n dispatch({ type: \"SET_PROCESSING\", isProcessing: true });\n\n try {\n // Check payment method first\n await checkPaymentMethod();\n\n // If editing subscription, get proration preview\n if (subscription && state.selectedPrice.id !== subscription.price?.id) {\n const preview = await StripeSubscriptionService.getProrationPreview({\n subscriptionId: subscription.id,\n newPriceId: state.selectedPrice.id,\n });\n dispatch({ type: \"SET_PRORATION_PREVIEW\", preview });\n }\n\n dispatch({ type: \"SET_STEP\", step: \"review\" });\n } catch (error: any) {\n console.error(\"[useSubscriptionWizard] Error preparing review:\", error);\n dispatch({ type: \"SET_ERROR\", error: error?.message || \"Failed to prepare review\" });\n } finally {\n dispatch({ type: \"SET_PROCESSING\", isProcessing: false });\n }\n }, [state.selectedPrice, subscription, checkPaymentMethod]);\n\n const confirmSubscription = useCallback(async () => {\n if (!state.selectedPrice) return;\n\n dispatch({ type: \"SET_PROCESSING\", isProcessing: true });\n dispatch({ type: \"SET_ERROR\", error: null });\n\n try {\n if (subscription) {\n // Change existing subscription\n await StripeSubscriptionService.changePlan({\n id: subscription.id,\n newPriceId: state.selectedPrice.id,\n });\n } else {\n // Create new subscription\n await StripeSubscriptionService.createSubscription({\n id: v4(),\n priceId: state.selectedPrice.id,\n });\n }\n\n onSuccessRef.current();\n onCloseRef.current();\n } catch (error: any) {\n console.error(\"[useSubscriptionWizard] Subscription error:\", error);\n\n // Handle 409 Conflict - duplicate recurring subscription\n if (error?.status === 409 || error?.response?.status === 409) {\n dispatch({\n type: \"SET_ERROR\",\n error: \"You already have an active subscription. Please change your existing plan instead.\",\n });\n return;\n }\n\n // Handle 402 - payment method required\n if (error?.status === 402 || error?.response?.status === 402) {\n dispatch({ type: \"SET_HAS_PAYMENT_METHOD\", hasMethod: false });\n dispatch({ type: \"SET_STEP\", step: \"payment-method\" });\n return;\n }\n\n dispatch({ type: \"SET_ERROR\", error: error?.message || \"Failed to process subscription\" });\n } finally {\n dispatch({ type: \"SET_PROCESSING\", isProcessing: false });\n }\n }, [state.selectedPrice, subscription]);\n\n const handlePaymentMethodSuccess = useCallback(async () => {\n dispatch({ type: \"SET_HAS_PAYMENT_METHOD\", hasMethod: true });\n // Go back to review to confirm subscription\n dispatch({ type: \"SET_STEP\", step: \"review\" });\n }, []);\n\n const reset = useCallback(() => {\n dispatch({ type: \"RESET\" });\n }, []);\n\n const actions = useMemo(\n () => ({\n selectPrice,\n setInterval,\n goToStep,\n goToReview,\n confirmSubscription,\n handlePaymentMethodSuccess,\n checkPaymentMethod,\n reset,\n }),\n [\n selectPrice,\n setInterval,\n goToStep,\n goToReview,\n confirmSubscription,\n handlePaymentMethodSuccess,\n checkPaymentMethod,\n reset,\n ],\n );\n\n return {\n state,\n actions,\n };\n}\n","\"use client\";\n\nimport { Check } from \"lucide-react\";\nimport { WizardStep } from \"../../hooks/useSubscriptionWizard\";\n\ntype WizardProgressIndicatorProps = {\n currentStep: WizardStep;\n};\n\nconst STEPS: { key: WizardStep; label: string }[] = [\n { key: \"plan-selection\", label: \"Select Plan\" },\n { key: \"review\", label: \"Review\" },\n { key: \"payment-method\", label: \"Payment\" },\n];\n\nfunction getStepIndex(step: WizardStep): number {\n return STEPS.findIndex((s) => s.key === step);\n}\n\nexport function WizardProgressIndicator({ currentStep }: WizardProgressIndicatorProps) {\n const currentIndex = getStepIndex(currentStep);\n\n return (\n <div className=\"flex items-center justify-center gap-x-2 py-4\">\n {STEPS.map((step, index) => {\n const isCompleted = index < currentIndex;\n const isCurrent = index === currentIndex;\n\n return (\n <div key={step.key} className=\"flex items-center gap-x-2\">\n {/* Step Indicator */}\n <div\n className={`flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium ${\n isCompleted\n ? \"bg-primary text-primary-foreground\"\n : isCurrent\n ? \"bg-primary text-primary-foreground\"\n : \"bg-muted text-muted-foreground\"\n }`}\n >\n {isCompleted ? <Check className=\"h-4 w-4\" /> : index + 1}\n </div>\n\n {/* Step Label */}\n <span\n className={`text-sm ${\n isCurrent ? \"font-medium text-foreground\" : \"text-muted-foreground\"\n }`}\n >\n {step.label}\n </span>\n\n {/* Connector */}\n {index < STEPS.length - 1 && (\n <div\n className={`h-0.5 w-8 ${\n index < currentIndex ? \"bg-primary\" : \"bg-muted\"\n }`}\n />\n )}\n </div>\n );\n })}\n </div>\n );\n}\n","\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { StripeProductInterface, StripeProductService } from \"../../../stripe-product\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { BillingInterval, IntervalToggle } from \"../widgets/IntervalToggle\";\nimport { ProductPricingList } from \"../widgets/ProductPricingList\";\n\ntype WizardStepPlanSelectionProps = {\n selectedPrice: StripePriceInterface | null;\n selectedInterval: BillingInterval;\n currentPriceId?: string;\n hideRecurringPrices: boolean;\n onSelectPrice: (price: StripePriceInterface) => void;\n onIntervalChange: (interval: BillingInterval) => void;\n onNext: () => void;\n isProcessing: boolean;\n};\n\nexport function WizardStepPlanSelection({\n selectedPrice,\n selectedInterval,\n currentPriceId,\n hideRecurringPrices,\n onSelectPrice,\n onIntervalChange,\n onNext,\n isProcessing,\n}: WizardStepPlanSelectionProps) {\n const [products, setProducts] = useState<StripeProductInterface[]>([]);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n const loadProducts = async () => {\n try {\n const fetchedProducts = await StripeProductService.listProducts({ active: true });\n setProducts(fetchedProducts);\n } catch (error) {\n console.error(\"[WizardStepPlanSelection] Failed to load products:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n loadProducts();\n }, []);\n\n // Compute available intervals from products\n const { hasMonthly, hasYearly } = useMemo(() => {\n let hasMonthly = false;\n let hasYearly = false;\n\n for (const product of products) {\n for (const price of product.stripePrices || []) {\n if (price.priceType === \"recurring\" && price.recurring?.interval === \"month\") {\n hasMonthly = true;\n }\n if (price.priceType === \"recurring\" && price.recurring?.interval === \"year\") {\n hasYearly = true;\n }\n }\n }\n\n return { hasMonthly, hasYearly };\n }, [products]);\n\n const handleSelectPrice = (price: StripePriceInterface) => {\n onSelectPrice(price);\n };\n\n return (\n <div className=\"space-y-6\">\n {/* Interval Toggle */}\n <div className=\"flex justify-center\">\n <IntervalToggle\n value={selectedInterval}\n onChange={onIntervalChange}\n hasMonthly={hasMonthly}\n hasYearly={hasYearly}\n />\n </div>\n\n {/* Product Pricing List */}\n <ProductPricingList\n products={products}\n selectedInterval={selectedInterval}\n currentPriceId={currentPriceId}\n selectedPriceId={selectedPrice?.id}\n loading={loading}\n hideRecurringPrices={hideRecurringPrices}\n onSelectPrice={handleSelectPrice}\n />\n\n {/* Action Buttons */}\n <div className=\"flex justify-end pt-4 border-t\">\n <Button onClick={onNext} disabled={!selectedPrice || isProcessing}>\n {isProcessing ? \"Loading...\" : \"Next: Review\"}\n </Button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { AlertCircle } from \"lucide-react\";\nimport { Alert, AlertDescription, Button } from \"../../../../../shadcnui\";\nimport { formatCurrency } from \"../../../components/utils/currency\";\nimport { StripePriceInterface } from \"../../../stripe-price/data/stripe-price.interface\";\nimport { ProrationPreviewInterface } from \"../../../stripe-invoice/data/stripe-invoice.interface\";\nimport { StripeSubscriptionInterface } from \"../../data\";\n\ntype WizardStepReviewProps = {\n selectedPrice: StripePriceInterface | null;\n subscription?: StripeSubscriptionInterface;\n prorationPreview: ProrationPreviewInterface | null;\n hasPaymentMethod: boolean;\n error: string | null;\n isProcessing: boolean;\n onBack: () => void;\n onAddPaymentMethod: () => void;\n onConfirm: () => void;\n};\n\nexport function WizardStepReview({\n selectedPrice,\n subscription,\n prorationPreview,\n hasPaymentMethod,\n error,\n isProcessing,\n onBack,\n onAddPaymentMethod,\n onConfirm,\n}: WizardStepReviewProps) {\n if (!selectedPrice) {\n return (\n <div className=\"text-center py-8 text-muted-foreground\">\n No plan selected. Please go back and select a plan.\n </div>\n );\n }\n\n const isChangingPlan = subscription && subscription.price?.id !== selectedPrice.id;\n\n const formatInterval = (price: StripePriceInterface) => {\n if (price.priceType === \"one_time\") return \"one-time\";\n const interval = price.recurring?.interval || \"month\";\n return interval === \"year\" ? \"yearly\" : \"monthly\";\n };\n\n return (\n <div className=\"space-y-6\">\n {/* Selected Plan Summary */}\n <div className=\"bg-muted/50 rounded-lg p-4 space-y-3\">\n <h3 className=\"font-semibold text-lg\">Selected Plan</h3>\n <div className=\"flex justify-between items-center\">\n <div>\n <p className=\"font-medium\">{selectedPrice.product?.name}</p>\n {selectedPrice.nickname && (\n <p className=\"text-sm text-muted-foreground\">{selectedPrice.nickname}</p>\n )}\n </div>\n <div className=\"text-right\">\n <p className=\"font-semibold text-lg\">\n {formatCurrency(selectedPrice.unitAmount || 0, selectedPrice.currency)}\n </p>\n <p className=\"text-sm text-muted-foreground\">{formatInterval(selectedPrice)}</p>\n </div>\n </div>\n </div>\n\n {/* Proration Preview (for plan changes) */}\n {isChangingPlan && prorationPreview && (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4 space-y-2\">\n <h4 className=\"font-medium text-blue-800\">Proration Summary</h4>\n <p className=\"text-sm text-blue-700\">\n Your next charge will be adjusted to account for the plan change.\n </p>\n <div className=\"flex justify-between text-sm\">\n <span className=\"text-blue-600\">Amount due now:</span>\n <span className=\"font-medium text-blue-800\">\n {formatCurrency(prorationPreview.amountDue, prorationPreview.currency)}\n </span>\n </div>\n </div>\n )}\n\n {/* Payment Method Status */}\n <div className=\"border rounded-lg p-4\">\n <div className=\"flex justify-between items-center\">\n <div>\n <h4 className=\"font-medium\">Payment Method</h4>\n <p className=\"text-sm text-muted-foreground\">\n {hasPaymentMethod\n ? \"A payment method is on file\"\n : \"No payment method on file\"}\n </p>\n </div>\n {!hasPaymentMethod && (\n <Button variant=\"outline\" onClick={onAddPaymentMethod}>\n Add Payment Method\n </Button>\n )}\n </div>\n </div>\n\n {/* Error Display */}\n {error && (\n <Alert variant=\"destructive\">\n <AlertCircle className=\"h-4 w-4\" />\n <AlertDescription>{error}</AlertDescription>\n </Alert>\n )}\n\n {/* Action Buttons */}\n <div className=\"flex justify-between pt-4 border-t\">\n <Button variant=\"outline\" onClick={onBack} disabled={isProcessing}>\n Back\n </Button>\n <Button\n onClick={hasPaymentMethod ? onConfirm : onAddPaymentMethod}\n disabled={isProcessing}\n >\n {isProcessing\n ? \"Processing...\"\n : hasPaymentMethod\n ? isChangingPlan\n ? \"Confirm Plan Change\"\n : \"Subscribe Now\"\n : \"Add Payment Method\"}\n </Button>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { PaymentMethodForm } from \"../../../stripe-customer/components/forms/PaymentMethodForm\";\n\ntype WizardStepPaymentMethodProps = {\n onBack: () => void;\n onSuccess: () => void;\n isProcessing: boolean;\n};\n\nexport function WizardStepPaymentMethod({\n onBack,\n onSuccess,\n isProcessing,\n}: WizardStepPaymentMethodProps) {\n return (\n <div className=\"space-y-6\">\n <div className=\"text-center\">\n <h3 className=\"font-semibold text-lg\">Add Payment Method</h3>\n <p className=\"text-sm text-muted-foreground\">\n Enter your card details to complete your subscription\n </p>\n </div>\n\n <PaymentMethodForm\n onSuccess={onSuccess}\n onCancel={onBack}\n isLoading={isProcessing}\n />\n </div>\n );\n}\n","\"use client\";\n\nimport { Activity } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { StripeSubscriptionInterface, StripeSubscriptionService } from \"../../../stripe-subscription\";\nimport { MeterInterface, MeterSummaryInterface } from \"../../data/stripe-usage.interface\";\nimport { StripeUsageService } from \"../../data/stripe-usage.service\";\nimport { UsageSummaryCards } from \"../widgets/UsageSummaryCards\";\n\nexport function UsageContainer() {\n const [meters, setMeters] = useState<MeterInterface[]>([]);\n const [summaries, setSummaries] = useState<Record<string, MeterSummaryInterface | null>>({});\n const [loading, setLoading] = useState<boolean>(true);\n const [subscriptions, setSubscriptions] = useState<StripeSubscriptionInterface[]>([]);\n\n useEffect(() => {\n loadUsageData();\n }, []);\n\n const loadUsageData = async () => {\n setLoading(true);\n\n try {\n // First, check if there are any metered subscriptions\n const fetchedSubscriptions = await StripeSubscriptionService.listSubscriptions();\n setSubscriptions(fetchedSubscriptions);\n\n const hasMeteredSubscriptions = fetchedSubscriptions.some((sub) => sub.price?.recurring?.usageType === \"metered\");\n\n if (!hasMeteredSubscriptions) {\n setLoading(false);\n return;\n }\n\n // Load meters\n const fetchedMeters = await StripeUsageService.listMeters();\n setMeters(fetchedMeters);\n\n // Load summaries for each meter (current month)\n const summariesMap: Record<string, MeterSummaryInterface | null> = {};\n const now = new Date();\n const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);\n const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);\n\n for (const meter of fetchedMeters) {\n try {\n const meterSummaries = await StripeUsageService.getMeterSummaries({\n meterId: meter.id,\n startTime: startOfMonth,\n endTime: endOfMonth,\n });\n // Use the first (most recent) summary\n summariesMap[meter.id] = meterSummaries.length > 0 ? meterSummaries[0] : null;\n } catch (error) {\n console.error(`[UsageContainer] Failed to load summaries for meter ${meter.id}:`, error);\n summariesMap[meter.id] = null;\n }\n }\n\n setSummaries(summariesMap);\n } catch (error) {\n console.error(\"[UsageContainer] Failed to load usage data:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n // Check if there are any metered subscriptions\n const hasMeteredSubscriptions = subscriptions.some((sub) => sub.price?.recurring?.usageType === \"metered\");\n\n // Don't render if no metered subscriptions\n if (!loading && !hasMeteredSubscriptions) {\n return null;\n }\n\n if (loading) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-muted-foreground\">Loading usage data...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center gap-x-3\">\n <Activity className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Usage Tracking</h1>\n </div>\n\n {/* Empty State */}\n {meters.length === 0 && (\n <div className=\"bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 p-12\">\n <Activity className=\"text-muted-foreground h-16 w-16\" />\n <div className=\"text-center\">\n <h3 className=\"mb-2 text-xl font-semibold\">No usage meters configured</h3>\n <p className=\"text-muted-foreground\">\n Usage tracking will appear here when you have metered subscriptions with configured meters.\n </p>\n </div>\n </div>\n )}\n\n {/* Usage Summary Cards */}\n {meters.length > 0 && <UsageSummaryCards meters={meters} summaries={summaries} />}\n </div>\n );\n}\n","\"use client\";\n\nimport { Activity } from \"lucide-react\";\nimport { Card, CardContent, CardHeader } from \"../../../../../shadcnui\";\nimport { MeterInterface, MeterSummaryInterface } from \"../../data/stripe-usage.interface\";\n\ntype UsageSummaryCardProps = {\n meter: MeterInterface;\n summary: MeterSummaryInterface | null;\n};\n\n/**\n * Get progress bar color based on usage percentage\n */\nfunction getProgressColor(percentage: number | null): string {\n if (percentage === null) return \"bg-blue-500\";\n if (percentage >= 90) return \"bg-red-500\";\n if (percentage >= 75) return \"bg-orange-500\";\n return \"bg-green-500\";\n}\n\n/**\n * Format a Unix timestamp to readable date\n */\nfunction formatDate(date: Date | undefined): string {\n if (!date) return \"N/A\";\n\n try {\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n }).format(new Date(date));\n } catch (error) {\n return \"Invalid Date\";\n }\n}\n\nexport function UsageSummaryCard({ meter, summary }: UsageSummaryCardProps) {\n const currentUsage = summary?.aggregatedValue ?? 0;\n const limit = (meter as any).limit; // Meters may have optional limit field\n const percentage = limit && limit > 0 ? (currentUsage / limit) * 100 : null;\n const progressColor = getProgressColor(percentage);\n const progressWidth = percentage !== null ? Math.min(percentage, 100) : 0;\n\n const displayName = meter.displayName || meter.eventName;\n const hasLimit = limit !== null && limit !== undefined;\n\n return (\n <Card>\n <CardHeader className=\"flex flex-row items-center gap-x-3 pb-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600\">\n <Activity className=\"h-5 w-5\" />\n </div>\n <div className=\"flex flex-col\">\n <h3 className=\"font-semibold\">{displayName}</h3>\n <p className=\"text-xs text-gray-500\">{meter.id}</p>\n </div>\n </CardHeader>\n\n <CardContent className=\"flex flex-col gap-y-4\">\n {/* Current Usage */}\n <div>\n <p className=\"text-3xl font-bold\">{currentUsage.toLocaleString()}</p>\n {hasLimit && <p className=\"text-sm text-gray-500\">of {limit.toLocaleString()} used</p>}\n </div>\n\n {/* Progress Bar */}\n {hasLimit ? (\n <div className=\"flex flex-col gap-y-2\">\n <div className=\"h-2 w-full overflow-hidden rounded-full bg-gray-200\">\n <div className={`h-full transition-all ${progressColor}`} style={{ width: `${progressWidth}%` }} />\n </div>\n <p className=\"text-sm text-gray-500\">{percentage?.toFixed(1)}% used</p>\n </div>\n ) : (\n <p className=\"text-sm text-gray-500\">No limit set</p>\n )}\n\n {/* Period Information */}\n {summary && summary.start && summary.end && (\n <div className=\"border-t pt-3\">\n <p className=\"text-xs text-gray-500\">\n Period: {formatDate(summary.start)} - {formatDate(summary.end)}\n </p>\n </div>\n )}\n </CardContent>\n </Card>\n );\n}\n","\"use client\";\n\nimport { MeterInterface, MeterSummaryInterface } from \"../../data/stripe-usage.interface\";\nimport { UsageSummaryCard } from \"../details/UsageSummaryCard\";\n\ntype UsageSummaryCardsProps = {\n meters: MeterInterface[];\n summaries: Record<string, MeterSummaryInterface | null>;\n};\n\nexport function UsageSummaryCards({ meters, summaries }: UsageSummaryCardsProps) {\n return (\n <div className=\"grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3\">\n {meters.map((meter) => (\n <UsageSummaryCard key={meter.id} meter={meter} summary={summaries[meter.id] || null} />\n ))}\n </div>\n );\n}\n","\"use client\";\n\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from \"../../../../../shadcnui\";\nimport { StripeUsageInterface } from \"../../data/stripe-usage.interface\";\n\ntype UsageHistoryTableProps = {\n usageRecords: StripeUsageInterface[];\n};\n\n/**\n * Format a date with time for usage history\n */\nfunction formatDateTime(date: Date | string | undefined): string {\n if (!date) return \"N/A\";\n\n const dateObj = typeof date === \"string\" ? new Date(date) : date;\n\n try {\n return new Intl.DateTimeFormat(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n hour: \"numeric\",\n minute: \"2-digit\",\n }).format(dateObj);\n } catch (error) {\n return \"Invalid Date\";\n }\n}\n\nexport function UsageHistoryTable({ usageRecords }: UsageHistoryTableProps) {\n if (usageRecords.length === 0) {\n return (\n <div className=\"rounded-lg border p-8 text-center\">\n <p className=\"text-muted-foreground\">No usage history available.</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-4\">\n <h2 className=\"text-xl font-semibold\">Usage History</h2>\n <div className=\"overflow-hidden rounded-lg border\">\n <Table>\n <TableHeader className=\"bg-muted\">\n <TableRow>\n <TableHead>Date & Time</TableHead>\n <TableHead>Meter Event</TableHead>\n <TableHead className=\"text-right\">Quantity</TableHead>\n <TableHead>Event ID</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {usageRecords.map((record) => {\n const dateTime = formatDateTime(record.timestamp);\n const quantity = record.quantity.toLocaleString();\n\n return (\n <TableRow key={record.id}>\n <TableCell className=\"font-medium\">{dateTime}</TableCell>\n <TableCell className=\"text-muted-foreground\">{record.meterEventName}</TableCell>\n <TableCell className=\"text-right font-medium\">{quantity}</TableCell>\n <TableCell className=\"text-muted-foreground text-sm font-mono\">{record.stripeEventId}</TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </div>\n </div>\n );\n}\n","\"use client\";\n\nimport { ReactNode } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from \"../../../../shadcnui\";\n\ntype BillingDetailModalProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: string;\n children: ReactNode;\n className?: string;\n};\n\nexport function BillingDetailModal({\n open,\n onOpenChange,\n title,\n children,\n className,\n}: BillingDetailModalProps) {\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className={className ?? \"max-w-4xl max-h-[90vh] overflow-y-auto\"}>\n <DialogHeader>\n <DialogTitle>{title}</DialogTitle>\n </DialogHeader>\n {children}\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { AlertCircle } from \"lucide-react\";\nimport { Button } from \"../../../../shadcnui\";\nimport { StripeSubscriptionInterface, SubscriptionStatus } from \"../../stripe-subscription\";\n\ntype BillingAlertBannerProps = {\n subscription: StripeSubscriptionInterface;\n onUpdatePayment?: () => void;\n onAddPayment?: () => void;\n};\n\nexport function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }: BillingAlertBannerProps) {\n // Payment failed alert (past_due)\n if (subscription.status === SubscriptionStatus.PAST_DUE) {\n return (\n <div className=\"bg-red-50 border border-red-200 rounded-lg p-4 flex items-start gap-x-3\">\n <AlertCircle className=\"h-5 w-5 text-red-600 mt-0.5\" />\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-red-900\">Payment Failed</h3>\n <p className=\"text-sm text-red-700 mt-1\">\n Your last payment failed. Please update your payment method to avoid service interruption.\n </p>\n </div>\n {onUpdatePayment && (\n <Button variant=\"outline\" size=\"sm\" onClick={onUpdatePayment} className=\"border-red-300 text-red-700\">\n Update Payment Method\n </Button>\n )}\n </div>\n );\n }\n\n // Trial ending soon alert (trialing with ≤7 days remaining)\n if (subscription.status === SubscriptionStatus.TRIALING && subscription.trialEnd) {\n const trialEnd = new Date(subscription.trialEnd);\n const now = new Date();\n const daysRemaining = Math.ceil((trialEnd.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));\n\n if (daysRemaining <= 7) {\n return (\n <div className=\"bg-yellow-50 border border-yellow-200 rounded-lg p-4 flex items-start gap-x-3\">\n <AlertCircle className=\"h-5 w-5 text-yellow-600 mt-0.5\" />\n <div className=\"flex-1\">\n <h3 className=\"font-semibold text-yellow-900\">Trial Ending Soon</h3>\n <p className=\"text-sm text-yellow-700 mt-1\">\n Your trial ends in {daysRemaining} {daysRemaining === 1 ? \"day\" : \"days\"}. Add a payment method to\n continue your subscription.\n </p>\n </div>\n {onAddPayment && (\n <Button variant=\"outline\" size=\"sm\" onClick={onAddPayment} className=\"border-yellow-300 text-yellow-700\">\n Add Payment Method\n </Button>\n )}\n </div>\n );\n }\n }\n\n // No critical state\n return null;\n}\n","\"use client\";\n\nimport { Elements } from \"@stripe/react-stripe-js\";\nimport { loadStripe, Stripe } from \"@stripe/stripe-js\";\nimport { ReactNode, useMemo } from \"react\";\nimport { getStripePublishableKey } from \"../../../../client/config\";\n\n// Cache the stripe promise to avoid recreating on each render\nlet stripePromiseCache: { key: string; promise: Promise<Stripe | null> } | null = null;\n\nfunction getStripePromise(publishableKey: string | undefined): Promise<Stripe | null> {\n if (!publishableKey) {\n return Promise.resolve(null);\n }\n\n // Return cached promise if key matches\n if (stripePromiseCache?.key === publishableKey) {\n return stripePromiseCache.promise;\n }\n\n // Create and cache new promise\n const promise = loadStripe(publishableKey);\n stripePromiseCache = { key: publishableKey, promise };\n return promise;\n}\n\nexport function StripeProvider({ children }: { children: ReactNode }) {\n // Evaluate key at render time, not module load time\n const publishableKey = getStripePublishableKey();\n const stripePromise = useMemo(() => getStripePromise(publishableKey), [publishableKey]);\n const options = useMemo(() => ({}), []);\n\n // If no Stripe key is configured, just render children without Stripe context\n if (!publishableKey) {\n return <>{children}</>;\n }\n\n return (\n <Elements stripe={stripePromise} options={options}>\n {children}\n </Elements>\n );\n}\n\n// Helper function to check if Stripe is configured\nexport function isStripeConfigured(): boolean {\n return !!getStripePublishableKey();\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { AlertCircle, PlusIcon, XIcon } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { SubmitHandler, useForm } from \"react-hook-form\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\nimport { FormCheckbox, FormInput, FormSelect, FormTextarea } from \"../../../../../components\";\nimport { CommonEditorButtons } from \"../../../../../components/forms/CommonEditorButtons\";\nimport {\n Button,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n Form,\n Input,\n Label,\n} from \"../../../../../shadcnui\";\nimport { StripePriceInterface, StripePriceService } from \"../../data\";\n\ntype PriceEditorProps = {\n productId: string;\n price?: StripePriceInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n};\n\ntype PriceFormValues = {\n unitAmount: number;\n currency: string;\n interval: \"one_time\" | \"day\" | \"week\" | \"month\" | \"year\";\n intervalCount?: number;\n usageType?: \"licensed\" | \"metered\";\n nickname?: string;\n active: boolean;\n description?: string;\n features: string[];\n token: string;\n};\n\nexport function PriceEditor({ productId, price, open, onOpenChange, onSuccess }: PriceEditorProps) {\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n\n const formSchema = z.object({\n unitAmount: z.preprocess(\n (val) => (typeof val === \"string\" ? parseFloat(val) : val),\n z.number().min(0, { message: \"Amount must be 0 or greater\" }),\n ),\n currency: z.string().min(1, { message: \"Currency is required\" }),\n interval: z.enum([\"one_time\", \"day\", \"week\", \"month\", \"year\"]),\n intervalCount: z.preprocess(\n (val) => (val === \"\" || val === undefined ? undefined : typeof val === \"string\" ? parseInt(val, 10) : val),\n z.number().min(1).optional(),\n ),\n usageType: z.enum([\"licensed\", \"metered\"]).optional(),\n nickname: z.string().optional(),\n active: z.boolean(),\n description: z.string().optional(),\n features: z.array(z.string()),\n token: z.string(),\n });\n\n const isEditMode = !!price;\n\n // Convert cents to dollars for display\n const defaultUnitAmount = price?.unitAmount ? price.unitAmount / 100 : 0;\n\n const form = useForm<PriceFormValues>({\n resolver: zodResolver(formSchema) as any,\n defaultValues: {\n unitAmount: defaultUnitAmount,\n currency: price?.currency || \"usd\",\n interval: price?.priceType === \"one_time\" ? \"one_time\" : price?.recurring?.interval || \"month\",\n intervalCount: price?.recurring?.intervalCount || 1,\n usageType: price?.recurring?.usageType || \"licensed\",\n nickname: price?.nickname || \"\",\n active: price?.active ?? true,\n description: price?.description || \"\",\n features: price?.features || [],\n token: price?.token?.toString() ?? \"\",\n },\n });\n\n // Reset form when dialog opens to ensure fresh state\n useEffect(() => {\n if (open) {\n form.reset({\n unitAmount: price?.unitAmount ? price.unitAmount / 100 : 0,\n currency: price?.currency || \"usd\",\n interval: price?.priceType === \"one_time\" ? \"one_time\" : price?.recurring?.interval || \"month\",\n intervalCount: price?.recurring?.intervalCount || 1,\n usageType: price?.recurring?.usageType || \"licensed\",\n nickname: price?.nickname || \"\",\n active: price?.active ?? true,\n description: price?.description || \"\",\n features: price?.features || [],\n token: price?.token?.toString() ?? \"\",\n });\n }\n }, [open, price?.id]);\n\n const watchInterval = form.watch(\"interval\");\n const isRecurring = watchInterval !== \"one_time\";\n\n const onSubmit: SubmitHandler<PriceFormValues> = async (values) => {\n setIsSubmitting(true);\n\n try {\n // Convert dollars to cents\n const unitAmountInCents = Math.round(values.unitAmount * 100);\n\n if (isEditMode) {\n // Update existing price (nickname, description, features, token can be updated - Stripe fields are limited)\n await StripePriceService.updatePrice({\n id: price.id,\n nickname: values.nickname || undefined,\n description: values.description || undefined,\n features: values.features.filter((f) => f.trim()) || undefined,\n token: values.token ? parseInt(values.token, 10) : undefined,\n });\n } else {\n // Create new price\n const createInput: any = {\n id: v4(),\n productId: productId,\n currency: values.currency,\n unitAmount: unitAmountInCents,\n };\n\n // Add recurring details if interval is not one_time\n if (isRecurring) {\n createInput.recurring = {\n interval: values.interval as \"day\" | \"week\" | \"month\" | \"year\",\n intervalCount: values.intervalCount || 1,\n usageType: values.usageType || \"licensed\",\n };\n }\n\n if (values.nickname) {\n createInput.nickname = values.nickname;\n }\n\n if (values.description) {\n createInput.description = values.description;\n }\n\n const filteredFeatures = values.features.filter((f) => f.trim());\n if (filteredFeatures.length > 0) {\n createInput.features = filteredFeatures;\n }\n\n if (values.token) {\n createInput.token = parseInt(values.token, 10);\n }\n\n await StripePriceService.createPrice(createInput);\n }\n\n onSuccess();\n onOpenChange(false);\n } catch (error) {\n console.error(\"[PriceEditor] Failed to save price:\", error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const currencyOptions = [\n { id: \"usd\", text: \"USD ($)\" },\n { id: \"eur\", text: \"EUR (€)\" },\n { id: \"gbp\", text: \"GBP (£)\" },\n ];\n\n const intervalOptions = [\n { id: \"one_time\", text: \"One-time\" },\n { id: \"day\", text: \"Daily\" },\n { id: \"week\", text: \"Weekly\" },\n { id: \"month\", text: \"Monthly\" },\n { id: \"year\", text: \"Yearly\" },\n ];\n\n const usageTypeOptions = [\n { id: \"licensed\", text: \"Licensed (per unit)\" },\n { id: \"metered\", text: \"Metered (usage-based)\" },\n ];\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{isEditMode ? \"Edit Price\" : \"Create Price\"}</DialogTitle>\n <DialogDescription>\n {isEditMode\n ? \"Update the price details. Note: Only nickname and active status can be changed.\"\n : \"Create a new price for this product\"}\n </DialogDescription>\n </DialogHeader>\n\n {isEditMode && (\n <div className=\"bg-blue-50 border border-blue-200 rounded-lg p-4 flex gap-x-3\">\n <AlertCircle className=\"h-5 w-5 text-blue-600 flex-shrink-0 mt-0.5\" />\n <div className=\"text-sm text-blue-800\">\n <p className=\"font-semibold mb-1\">Stripe Price Immutability</p>\n <p>\n Due to Stripe's architecture, only the nickname and active status can be modified after creation. To\n change amount, currency, or billing interval, create a new price.\n </p>\n </div>\n </div>\n )}\n\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col gap-y-4\">\n <div className=\"grid grid-cols-2 gap-x-4\">\n <FormInput\n form={form}\n id=\"unitAmount\"\n name=\"Amount (in dollars)\"\n placeholder=\"9.99\"\n disabled={isEditMode}\n isRequired\n />\n\n <FormSelect form={form} id=\"currency\" name=\"Currency\" values={currencyOptions} disabled={isEditMode} />\n </div>\n\n <FormSelect\n form={form}\n id=\"interval\"\n name=\"Billing Interval\"\n values={intervalOptions}\n disabled={isEditMode}\n />\n\n {isRecurring && (\n <div className=\"grid grid-cols-2 gap-x-4\">\n <FormInput\n form={form}\n id=\"intervalCount\"\n name=\"Interval Count\"\n placeholder=\"1\"\n type=\"number\"\n disabled={isEditMode}\n />\n\n <FormSelect\n form={form}\n id=\"usageType\"\n name=\"Usage Type\"\n values={usageTypeOptions}\n disabled={isEditMode}\n />\n </div>\n )}\n\n <FormInput\n form={form}\n id=\"nickname\"\n name=\"Nickname (optional)\"\n placeholder=\"e.g., Standard Plan, Pro Tier\"\n />\n\n <FormTextarea\n form={form}\n id=\"description\"\n name=\"Description (optional)\"\n placeholder=\"Describe what this price tier includes...\"\n className=\"min-h-24\"\n />\n\n <FormInput form={form} id=\"token\" name=\"Token (optional)\" placeholder=\"Enter token value\" />\n\n {/* Features List */}\n <div className=\"space-y-2\">\n <Label>Features (optional)</Label>\n <div className=\"space-y-2\">\n {form.watch(\"features\").map((_, index) => (\n <div key={index} className=\"flex gap-2\">\n <Input\n {...form.register(`features.${index}`)}\n placeholder={`Feature ${index + 1}`}\n className=\"flex-1\"\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => {\n const currentFeatures = form.getValues(\"features\");\n form.setValue(\n \"features\",\n currentFeatures.filter((_, i) => i !== index),\n );\n }}\n >\n <XIcon className=\"h-4 w-4\" />\n </Button>\n </div>\n ))}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => {\n const currentFeatures = form.getValues(\"features\");\n form.setValue(\"features\", [...currentFeatures, \"\"]);\n }}\n className=\"mt-2\"\n >\n <PlusIcon className=\"h-4 w-4 mr-2\" />\n Add Feature\n </Button>\n </div>\n </div>\n\n <FormCheckbox form={form} id=\"active\" name=\"Active\" />\n\n <CommonEditorButtons isEdit={isEditMode} form={form} disabled={isSubmitting} setOpen={onOpenChange} />\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { Archive, DollarSign, Edit, RotateCcw } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Button,\n} from \"../../../../../shadcnui\";\nimport { formatCurrency } from \"../../../components/utils/currency\";\nimport { StripePriceService } from \"../../data\";\nimport { StripePriceInterface } from \"../../data/stripe-price.interface\";\nimport { PriceEditor } from \"../forms/PriceEditor\";\n\ntype PricesListProps = {\n productId: string;\n onPricesChange: () => void;\n};\n\nexport function PricesList({ productId, onPricesChange }: PricesListProps) {\n const [prices, setPrices] = useState<StripePriceInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [showCreatePrice, setShowCreatePrice] = useState<boolean>(false);\n const [editingPrice, setEditingPrice] = useState<StripePriceInterface | null>(null);\n const [priceToArchive, setPriceToArchive] = useState<StripePriceInterface | null>(null);\n const [priceToReactivate, setPriceToReactivate] = useState<StripePriceInterface | null>(null);\n const [archivingPriceId, setArchivingPriceId] = useState<string | null>(null);\n const [reactivatingPriceId, setReactivatingPriceId] = useState<string | null>(null);\n\n const loadPrices = async () => {\n setLoading(true);\n try {\n const fetchedPrices = await StripePriceService.listPrices({ productId });\n setPrices(fetchedPrices);\n } catch (error) {\n console.error(\"[PricesList] Failed to load prices:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadPrices();\n }, [productId]);\n\n const handleArchive = async () => {\n if (!priceToArchive) {\n return;\n }\n\n setArchivingPriceId(priceToArchive.id);\n try {\n await StripePriceService.archivePrice({ id: priceToArchive.id });\n setPriceToArchive(null); // Close dialog on success\n await loadPrices();\n onPricesChange();\n } catch (error) {\n console.error(\"[PricesList] Failed to archive price:\", error);\n // Keep dialog open on error so user can retry or cancel\n } finally {\n setArchivingPriceId(null);\n }\n };\n\n const handleReactivate = async () => {\n if (!priceToReactivate) {\n return;\n }\n\n setReactivatingPriceId(priceToReactivate.id);\n try {\n await StripePriceService.reactivatePrice({ id: priceToReactivate.id });\n setPriceToReactivate(null); // Close dialog on success\n await loadPrices();\n onPricesChange();\n } catch (error) {\n console.error(\"[PricesList] Failed to reactivate price:\", error);\n // Keep dialog open on error so user can retry or cancel\n } finally {\n setReactivatingPriceId(null);\n }\n };\n\n const formatInterval = (price: StripePriceInterface): string => {\n if (price.priceType === \"one_time\") {\n return \"one-time\";\n }\n\n if (price.recurring) {\n const count = price.recurring.intervalCount;\n const interval = price.recurring.interval;\n\n if (count === 1) {\n return `/ ${interval}`;\n } else {\n return `/ ${count} ${interval}s`;\n }\n }\n\n return \"\";\n };\n\n if (loading) {\n return (\n <div className=\"flex items-center justify-center py-8\">\n <p className=\"text-muted-foreground\">Loading prices...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col gap-y-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h4 className=\"text-lg font-semibold\">Prices</h4>\n <Button size=\"sm\" onClick={() => setShowCreatePrice(true)}>\n Add Price\n </Button>\n </div>\n\n {/* Empty State */}\n {prices.length === 0 && (\n <div className=\"bg-background flex flex-col items-center justify-center gap-y-3 rounded-lg border border-dashed p-8\">\n <DollarSign className=\"text-muted-foreground h-12 w-12\" />\n <p className=\"text-muted-foreground text-sm\">No prices yet. Add a price to enable subscriptions.</p>\n <Button size=\"sm\" onClick={() => setShowCreatePrice(true)}>\n Add Price\n </Button>\n </div>\n )}\n\n {/* Prices Grid */}\n {prices.length > 0 && (\n <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {prices.map((price) => {\n const isArchiving = archivingPriceId === price.id;\n const isReactivating = reactivatingPriceId === price.id;\n\n return (\n <div key={price.id} className=\"border rounded-lg bg-white p-4 hover:shadow-sm transition-shadow\">\n <div className=\"flex items-start justify-between mb-3\">\n <DollarSign className=\"h-5 w-5 text-primary\" />\n <div className=\"flex gap-1\">\n <Button variant=\"ghost\" size=\"sm\" onClick={() => setEditingPrice(price)} className=\"h-8 w-8 p-0\">\n <Edit className=\"h-4 w-4\" />\n </Button>\n {price.active ? (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setPriceToArchive(price)}\n className=\"h-8 w-8 p-0\"\n disabled={isArchiving}\n >\n <Archive className=\"h-4 w-4\" />\n </Button>\n ) : (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => setPriceToReactivate(price)}\n className=\"h-8 w-8 p-0\"\n disabled={isReactivating}\n >\n <RotateCcw className=\"h-4 w-4\" />\n </Button>\n )}\n </div>\n </div>\n\n <div className=\"mb-2\">\n <div className=\"text-2xl font-bold\">\n {formatCurrency(price.unitAmount, price.currency)}{\" \"}\n <span className=\"text-muted-foreground text-sm font-normal\">{formatInterval(price)}</span>\n </div>\n </div>\n\n {price.metadata?.nickname && <p className=\"text-sm font-medium mb-2\">{price.metadata.nickname}</p>}\n\n <div className=\"flex flex-wrap gap-2\">\n {price.active ? (\n <span className=\"bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium\">Active</span>\n ) : (\n <span className=\"bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium\">Inactive</span>\n )}\n\n {price.recurring?.usageType === \"metered\" && (\n <span className=\"bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full font-medium\">Metered</span>\n )}\n\n <span className=\"bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium uppercase\">\n {price.currency}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n )}\n\n {/* Create Price Modal */}\n {showCreatePrice && (\n <PriceEditor\n productId={productId}\n open={showCreatePrice}\n onOpenChange={setShowCreatePrice}\n onSuccess={() => {\n loadPrices();\n onPricesChange();\n }}\n />\n )}\n\n {/* Edit Price Modal */}\n {editingPrice && (\n <PriceEditor\n productId={productId}\n price={editingPrice}\n open={!!editingPrice}\n onOpenChange={(open) => !open && setEditingPrice(null)}\n onSuccess={() => {\n loadPrices();\n onPricesChange();\n setEditingPrice(null);\n }}\n />\n )}\n\n {/* Archive Price Confirmation Dialog */}\n <AlertDialog open={!!priceToArchive} onOpenChange={(open) => !open && setPriceToArchive(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Archive Price</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to archive the price for{\" \"}\n {priceToArchive && `${formatCurrency(priceToArchive.unitAmount, priceToArchive.currency)} ${formatInterval(priceToArchive)}`}\n ? This will prevent new subscriptions but existing ones will continue.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={!!archivingPriceId}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleArchive}\n disabled={!!archivingPriceId}\n className=\"bg-red-600 hover:bg-red-700\"\n >\n {archivingPriceId ? \"Archiving...\" : \"Archive\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {/* Reactivate Price Confirmation Dialog */}\n <AlertDialog open={!!priceToReactivate} onOpenChange={(open) => !open && setPriceToReactivate(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Reactivate Price</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to reactivate the price for{\" \"}\n {priceToReactivate && `${formatCurrency(priceToReactivate.unitAmount, priceToReactivate.currency)} ${formatInterval(priceToReactivate)}`}\n ? This will allow new subscriptions again.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={!!reactivatingPriceId}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleReactivate}\n disabled={!!reactivatingPriceId}\n className=\"bg-green-600 hover:bg-green-700\"\n >\n {reactivatingPriceId ? \"Reactivating...\" : \"Reactivate\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n","\"use client\";\n\nimport { Package } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { getRoleId } from \"../../../../../roles\";\nimport { Button } from \"../../../../../shadcnui\";\nimport { useCurrentUserContext } from \"../../../../user/contexts\";\nimport { StripeProductInterface } from \"../../data/stripe-product.interface\";\nimport { StripeProductService } from \"../../data/stripe-product.service\";\nimport { ProductEditor } from \"../forms/ProductEditor\";\nimport { ProductsList } from \"../lists/ProductsList\";\n\nexport function ProductsAdminContainer() {\n const { hasRole } = useCurrentUserContext();\n const [products, setProducts] = useState<StripeProductInterface[]>([]);\n const [loading, setLoading] = useState<boolean>(true);\n const [showCreateProduct, setShowCreateProduct] = useState<boolean>(false);\n\n // Check if user has Administrator role\n if (!hasRole(getRoleId().Administrator)) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-red-600 font-semibold\">Permission denied. Administrator access required.</p>\n </div>\n );\n }\n\n const loadProducts = async () => {\n setLoading(true);\n try {\n const fetchedProducts = await StripeProductService.listProducts();\n setProducts(fetchedProducts);\n } catch (error) {\n console.error(\"[ProductsAdminContainer] Failed to load products:\", error);\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n loadProducts();\n }, []);\n\n if (loading) {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <p className=\"text-muted-foreground\">Loading products...</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-y-6\">\n {/* Header */}\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-x-3\">\n <Package className=\"h-8 w-8\" />\n <h1 className=\"text-3xl font-bold\">Product & Price Management</h1>\n </div>\n <Button onClick={() => setShowCreateProduct(true)}>Create Product</Button>\n </div>\n\n {/* Empty State */}\n {products.length === 0 && (\n <div className=\"bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed p-12\">\n <Package className=\"text-muted-foreground h-16 w-16\" />\n <div className=\"text-center\">\n <h3 className=\"mb-2 text-xl font-semibold\">No products yet</h3>\n <p className=\"text-muted-foreground mb-4\">\n Create your first product to start offering subscriptions to your customers.\n </p>\n <Button onClick={() => setShowCreateProduct(true)}>Create Your First Product</Button>\n </div>\n </div>\n )}\n\n {/* Products List */}\n {products.length > 0 && <ProductsList products={products} onProductsChange={loadProducts} />}\n\n {/* Create Product Modal */}\n {showCreateProduct && (\n <ProductEditor open={showCreateProduct} onOpenChange={setShowCreateProduct} onSuccess={loadProducts} />\n )}\n </div>\n );\n}\n","\"use client\";\n\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport { useState } from \"react\";\nimport { SubmitHandler, useForm } from \"react-hook-form\";\nimport { v4 } from \"uuid\";\nimport { z } from \"zod\";\nimport { FormCheckbox, FormInput, FormTextarea } from \"../../../../../components\";\nimport { CommonEditorButtons } from \"../../../../../components/forms/CommonEditorButtons\";\nimport { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Form } from \"../../../../../shadcnui\";\nimport { StripeProductInterface } from \"../../data/stripe-product.interface\";\nimport { StripeProductService } from \"../../data/stripe-product.service\";\n\ntype ProductEditorProps = {\n product?: StripeProductInterface;\n open: boolean;\n onOpenChange: (open: boolean) => void;\n onSuccess: () => void;\n};\n\nexport function ProductEditor({ product, open, onOpenChange, onSuccess }: ProductEditorProps) {\n const [isSubmitting, setIsSubmitting] = useState<boolean>(false);\n\n const formSchema = z.object({\n name: z.string().min(1, { message: \"Product name is required\" }),\n description: z.string().min(1, { message: \"Description is required\" }),\n active: z.boolean(),\n });\n\n const form = useForm<z.infer<typeof formSchema>>({\n resolver: zodResolver(formSchema),\n defaultValues: {\n name: product?.name || \"\",\n description: product?.description || \"\",\n active: product?.active ?? true,\n },\n });\n\n const onSubmit: SubmitHandler<z.infer<typeof formSchema>> = async (values) => {\n setIsSubmitting(true);\n\n try {\n if (product) {\n // Update existing product\n await StripeProductService.updateProduct({\n id: product.id,\n name: values.name,\n description: values.description,\n active: values.active,\n });\n } else {\n // Create new product\n await StripeProductService.createProduct({\n id: v4(),\n name: values.name,\n description: values.description,\n active: values.active,\n });\n }\n\n onSuccess();\n onOpenChange(false);\n } catch (error) {\n console.error(\"[ProductEditor] Failed to save product:\", error);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"max-w-2xl\">\n <DialogHeader>\n <DialogTitle>{product ? \"Edit Product\" : \"Create Product\"}</DialogTitle>\n <DialogDescription>\n {product ? `Update the details for ${product.name}` : \"Create a new product to offer to your customers\"}\n </DialogDescription>\n </DialogHeader>\n\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"flex flex-col gap-y-4\">\n <FormInput form={form} id=\"name\" name=\"Product Name\" placeholder=\"Enter product name\" isRequired />\n\n <FormTextarea\n form={form}\n id=\"description\"\n name=\"Description\"\n placeholder=\"Enter product description\"\n className=\"min-h-32\"\n />\n\n <FormCheckbox form={form} id=\"active\" name=\"Active\" />\n\n <CommonEditorButtons isEdit={!!product} form={form} disabled={isSubmitting} setOpen={onOpenChange} />\n </form>\n </Form>\n </DialogContent>\n </Dialog>\n );\n}\n","\"use client\";\n\nimport { Archive, ChevronDown, ChevronUp, Edit, Package, RefreshCw } from \"lucide-react\";\nimport { useState } from \"react\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n Button,\n} from \"../../../../../shadcnui\";\nimport { PricesList } from \"../../../stripe-price/components/lists/PricesList\";\nimport { StripeProductInterface } from \"../../data/stripe-product.interface\";\nimport { StripeProductService } from \"../../data/stripe-product.service\";\nimport { ProductEditor } from \"../forms/ProductEditor\";\n\ntype ProductsListProps = {\n products: StripeProductInterface[];\n onProductsChange: () => void;\n};\n\nexport function ProductsList({ products, onProductsChange }: ProductsListProps) {\n const [expandedProductId, setExpandedProductId] = useState<string | null>(null);\n const [editingProduct, setEditingProduct] = useState<StripeProductInterface | null>(null);\n const [archivingProductId, setArchivingProductId] = useState<string | null>(null);\n const [reactivatingProductId, setReactivatingProductId] = useState<string | null>(null);\n const [productToArchive, setProductToArchive] = useState<StripeProductInterface | null>(null);\n const [productToReactivate, setProductToReactivate] = useState<StripeProductInterface | null>(null);\n\n const handleArchive = async () => {\n if (!productToArchive) {\n return;\n }\n\n setArchivingProductId(productToArchive.id);\n try {\n const archivedProduct = await StripeProductService.archiveProduct({ id: productToArchive.id });\n setProductToArchive(null); // Close dialog on success\n onProductsChange();\n } catch (error) {\n console.error(\"[ProductsList] Failed to archive product:\", error);\n // Keep dialog open on error so user can retry or cancel\n } finally {\n setArchivingProductId(null);\n }\n };\n\n const handleReactivate = async () => {\n if (!productToReactivate) {\n return;\n }\n\n setReactivatingProductId(productToReactivate.id);\n try {\n const reactivatedProduct = await StripeProductService.reactivateProduct({ id: productToReactivate.id });\n setProductToReactivate(null); // Close dialog on success\n onProductsChange();\n } catch (error) {\n // Keep dialog open on error so user can retry or cancel\n } finally {\n setReactivatingProductId(null);\n }\n };\n\n const toggleExpand = (productId: string) => {\n setExpandedProductId(expandedProductId === productId ? null : productId);\n };\n\n return (\n <div className=\"flex flex-col gap-y-4\">\n {products.map((product) => {\n const isExpanded = expandedProductId === product.id;\n const isArchiving = archivingProductId === product.id;\n const isReactivating = reactivatingProductId === product.id;\n\n return (\n <div key={product.id} className=\"border rounded-lg bg-white shadow-sm hover:shadow-md transition-shadow\">\n {/* Product Card Header */}\n <div className=\"flex items-center justify-between p-6\">\n <div className=\"flex items-center gap-x-4 flex-1\">\n <Package className=\"h-6 w-6 text-primary\" />\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-x-3\">\n <h3 className=\"text-lg font-semibold\">{product.name}</h3>\n {product.active ? (\n <span className=\"bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium\">\n Active\n </span>\n ) : (\n <span className=\"bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium\">\n Inactive\n </span>\n )}\n </div>\n {product.description && <p className=\"text-muted-foreground text-sm mt-1\">{product.description}</p>}\n </div>\n </div>\n\n {/* Action Buttons */}\n <div className=\"flex items-center gap-x-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => setEditingProduct(product)}>\n <Edit className=\"h-4 w-4 mr-1\" />\n Edit\n </Button>\n {product.active ? (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setProductToArchive(product)}\n disabled={isArchiving}\n >\n <Archive className=\"h-4 w-4 mr-1\" />\n {isArchiving ? \"Archiving...\" : \"Archive\"}\n </Button>\n ) : (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setProductToReactivate(product)}\n disabled={isReactivating}\n >\n <RefreshCw className=\"h-4 w-4 mr-1\" />\n {isReactivating ? \"Reactivating...\" : \"Reactivate\"}\n </Button>\n )}\n <Button variant=\"ghost\" size=\"sm\" onClick={() => toggleExpand(product.id)}>\n {isExpanded ? <ChevronUp className=\"h-5 w-5\" /> : <ChevronDown className=\"h-5 w-5\" />}\n </Button>\n </div>\n </div>\n\n {/* Expandable Prices Section */}\n {isExpanded && (\n <div className=\"border-t bg-muted/30 p-6\">\n <PricesList productId={product.id} onPricesChange={onProductsChange} />\n </div>\n )}\n </div>\n );\n })}\n\n {/* Edit Product Modal */}\n {editingProduct && (\n <ProductEditor\n product={editingProduct}\n open={!!editingProduct}\n onOpenChange={(open) => !open && setEditingProduct(null)}\n onSuccess={() => {\n onProductsChange();\n setEditingProduct(null);\n }}\n />\n )}\n\n {/* Archive Product Confirmation Dialog */}\n <AlertDialog open={!!productToArchive} onOpenChange={(open) => !open && setProductToArchive(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Archive Product</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to archive "{productToArchive?.name}"? This will deactivate it and it will\n no longer be available for new subscriptions.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={!!archivingProductId}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleArchive}\n disabled={!!archivingProductId}\n className=\"bg-red-600 hover:bg-red-700\"\n >\n {archivingProductId ? \"Archiving...\" : \"Archive\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n\n {/* Reactivate Product Confirmation Dialog */}\n <AlertDialog open={!!productToReactivate} onOpenChange={(open) => !open && setProductToReactivate(null)}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>Reactivate Product</AlertDialogTitle>\n <AlertDialogDescription>\n Are you sure you want to reactivate "{productToReactivate?.name}"? This will make it available\n for new subscriptions again.\n </AlertDialogDescription>\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel disabled={!!reactivatingProductId}>Cancel</AlertDialogCancel>\n <AlertDialogAction\n onClick={handleReactivate}\n disabled={!!reactivatingProductId}\n className=\"bg-green-600 hover:bg-green-700\"\n >\n {reactivatingProductId ? \"Reactivating...\" : \"Reactivate\"}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n </div>\n );\n}\n"],"mappings":"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","names":["ChevronRight","jsx","jsxs","ChevronRight","jsx","jsxs","ChevronRight","jsx","jsxs","getStatusBadgeVariant","formatDate","ChevronRight","ChevronRight","jsx","jsxs","ChevronRight","CreditCard","Loader2","Wallet","useCallback","useEffect","useMemo","useState","CreditCard","useEffect","useState","useState","jsx","jsxs","useState","jsx","jsxs","useEffect","useState","jsx","jsxs","useState","useEffect","jsx","jsx","jsxs","useState","useEffect","CreditCard","useEffect","useState","useState","formatDate","ExternalLink","jsx","jsx","jsxs","formatDate","ExternalLink","Fragment","jsx","jsxs","useState","formatDate","jsx","jsxs","useState","useEffect","CreditCard","useEffect","useState","useState","useState","useState","jsx","jsxs","useState","formatDate","jsx","statusConfig","Fragment","jsx","jsxs","formatPlanName","useState","formatDate","Fragment","jsx","jsxs","formatPlanName","useState","formatDate","jsx","jsxs","useState","useEffect","CreditCard","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","jsx","jsxs","formatDate","Check","Fragment","jsx","jsxs","Check","useCallback","useEffect","useRef","useCallback","useCallback","Check","jsx","jsxs","Check","useEffect","useMemo","useState","jsx","jsxs","useState","useEffect","useMemo","hasMonthly","hasYearly","jsx","jsxs","formatInterval","jsx","jsxs","jsx","jsxs","useCallback","useRef","useEffect","Activity","useEffect","useState","Activity","jsx","jsxs","formatDate","Activity","jsx","jsx","jsxs","useState","useEffect","hasMeteredSubscriptions","Activity","jsx","jsxs","jsx","jsxs","AlertCircle","jsx","jsxs","AlertCircle","Fragment","jsx","jsxs","useState","useCallback","useMemo","subscriptions","useEffect","Wallet","Loader2","CreditCard","useMemo","Fragment","jsx","useMemo","zodResolver","AlertCircle","useEffect","useState","useForm","v4","z","jsx","jsxs","useState","formSchema","z","useForm","zodResolver","useEffect","v4","AlertCircle","_","useEffect","useState","jsx","jsxs","useState","useEffect","formatInterval","Package","useEffect","useState","zodResolver","useState","useForm","v4","z","jsx","jsxs","useState","formSchema","z","useForm","zodResolver","v4","Archive","Edit","RefreshCw","useState","jsx","jsxs","useState","Edit","Archive","RefreshCw","jsx","jsxs","useState","useEffect","Package"]}
|