@carlonicora/nextjs-jsonapi 1.28.0 → 1.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/{BlockNoteEditor-CAUNVZUF.js → BlockNoteEditor-YBVEOPV4.js} +13 -13
  2. package/dist/{BlockNoteEditor-CAUNVZUF.js.map → BlockNoteEditor-YBVEOPV4.js.map} +1 -1
  3. package/dist/{BlockNoteEditor-EOA4OEVX.mjs → BlockNoteEditor-ZM4YPXHO.mjs} +3 -3
  4. package/dist/billing/index.d.mts +47 -17
  5. package/dist/billing/index.d.ts +47 -17
  6. package/dist/billing/index.js +1241 -1073
  7. package/dist/billing/index.js.map +1 -1
  8. package/dist/billing/index.mjs +1375 -1207
  9. package/dist/billing/index.mjs.map +1 -1
  10. package/dist/{chunk-IXI4GAKB.js → chunk-3X7EEFMN.js} +488 -431
  11. package/dist/chunk-3X7EEFMN.js.map +1 -0
  12. package/dist/{chunk-ORFXBO7F.mjs → chunk-DU64WMZD.mjs} +6 -3
  13. package/dist/chunk-DU64WMZD.mjs.map +1 -0
  14. package/dist/{chunk-TSEU4KZ2.js → chunk-J22NEVSK.js} +21 -18
  15. package/dist/chunk-J22NEVSK.js.map +1 -0
  16. package/dist/{chunk-PYASRX75.mjs → chunk-UCD5CUE4.mjs} +81 -24
  17. package/dist/chunk-UCD5CUE4.mjs.map +1 -0
  18. package/dist/client/index.d.mts +14 -5
  19. package/dist/client/index.d.ts +14 -5
  20. package/dist/client/index.js +5 -3
  21. package/dist/client/index.js.map +1 -1
  22. package/dist/client/index.mjs +4 -2
  23. package/dist/components/index.d.mts +2 -2
  24. package/dist/components/index.d.ts +2 -2
  25. package/dist/components/index.js +3 -3
  26. package/dist/components/index.mjs +2 -2
  27. package/dist/{config-B4pZpLT9.d.ts → config-CHwoRDOp.d.ts} +1 -1
  28. package/dist/{config-DT1K-t6I.d.mts → config-DiWyJzk9.d.mts} +1 -1
  29. package/dist/{content.interface-B2Ldg0vg.d.mts → content.interface-BSpowEiW.d.mts} +1 -1
  30. package/dist/{content.interface-D8NHv3DX.d.ts → content.interface-DFQ7mkpL.d.ts} +1 -1
  31. package/dist/contexts/index.d.mts +2 -2
  32. package/dist/contexts/index.d.ts +2 -2
  33. package/dist/contexts/index.js +3 -3
  34. package/dist/contexts/index.mjs +2 -2
  35. package/dist/core/index.d.mts +39 -37
  36. package/dist/core/index.d.ts +39 -37
  37. package/dist/core/index.js +2 -2
  38. package/dist/core/index.mjs +1 -1
  39. package/dist/index.d.mts +4 -4
  40. package/dist/index.d.ts +4 -4
  41. package/dist/index.js +2 -2
  42. package/dist/index.mjs +1 -1
  43. package/dist/{notification.interface-H0L9WBge.d.ts → notification.interface-CmKmObIU.d.ts} +1 -0
  44. package/dist/{notification.interface-DEn-Yp_b.d.mts → notification.interface-D5MbtfZK.d.mts} +1 -0
  45. package/dist/{s3.service-BNytYanU.d.mts → s3.service-BMT7W6KS.d.mts} +19 -19
  46. package/dist/{s3.service-C7f_Ygz5.d.ts → s3.service-DsXo9nop.d.ts} +19 -19
  47. package/dist/server/index.d.mts +3 -3
  48. package/dist/server/index.d.ts +3 -3
  49. package/dist/server/index.js +3 -3
  50. package/dist/server/index.mjs +1 -1
  51. package/dist/{useSocket-BcnThTD0.d.mts → useSocket-DUqGoPya.d.mts} +1 -1
  52. package/dist/{useSocket-QZTOCzRF.d.ts → useSocket-QuHa0ZmO.d.ts} +1 -1
  53. package/package.json +1 -1
  54. package/src/client/index.ts +1 -0
  55. package/src/components/forms/FormSelect.tsx +2 -1
  56. package/src/features/auth/data/auth.ts +0 -2
  57. package/src/features/billing/components/containers/BillingDashboardContainer.tsx +60 -3
  58. package/src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx +12 -152
  59. package/src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx +168 -0
  60. package/src/features/billing/stripe-customer/components/forms/index.ts +1 -0
  61. package/src/features/billing/stripe-price/components/forms/PriceEditor.tsx +19 -1
  62. package/src/features/billing/stripe-product/components/forms/ProductEditor.tsx +2 -2
  63. package/src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx +24 -235
  64. package/src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx +7 -18
  65. package/src/features/billing/stripe-subscription/components/forms/index.ts +0 -1
  66. package/src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx +10 -1
  67. package/src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx +28 -0
  68. package/src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx +128 -0
  69. package/src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx +54 -0
  70. package/src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx +68 -0
  71. package/src/features/billing/stripe-subscription/components/widgets/index.ts +4 -1
  72. package/src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx +114 -0
  73. package/src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx +66 -0
  74. package/src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx +32 -0
  75. package/src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx +103 -0
  76. package/src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx +133 -0
  77. package/src/features/billing/stripe-subscription/components/wizards/index.ts +6 -0
  78. package/src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts +217 -0
  79. package/src/features/billing/stripe-subscription/index.ts +3 -2
  80. package/src/features/company/components/details/TokenStatusIndicator.tsx +19 -9
  81. package/src/features/company/data/company.interface.ts +2 -0
  82. package/src/features/company/data/company.ts +7 -0
  83. package/src/features/company/hooks/index.ts +1 -0
  84. package/src/features/company/hooks/useSubscriptionStatus.ts +71 -0
  85. package/src/features/user/components/forms/UserEditor.tsx +1 -1
  86. package/src/features/user/components/lists/AdminUsersList.tsx +1 -1
  87. package/src/features/user/contexts/CurrentUserContext.tsx +1 -1
  88. package/src/features/user/data/user.ts +1 -1
  89. package/dist/chunk-IXI4GAKB.js.map +0 -1
  90. package/dist/chunk-ORFXBO7F.mjs.map +0 -1
  91. package/dist/chunk-PYASRX75.mjs.map +0 -1
  92. package/dist/chunk-TSEU4KZ2.js.map +0 -1
  93. package/src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx +0 -331
  94. package/src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx +0 -110
  95. /package/dist/{BlockNoteEditor-EOA4OEVX.mjs.map → BlockNoteEditor-ZM4YPXHO.mjs.map} +0 -0
@@ -10,7 +10,6 @@ import {
10
10
  AlertDialogFooter,
11
11
  AlertDialogHeader,
12
12
  AlertDialogTitle,
13
- AlertTitle,
14
13
  Badge,
15
14
  Button,
16
15
  Card,
@@ -48,7 +47,7 @@ import {
48
47
  TabsList,
49
48
  TabsTrigger,
50
49
  useCurrentUserContext
51
- } from "../chunk-PYASRX75.mjs";
50
+ } from "../chunk-UCD5CUE4.mjs";
52
51
  import {
53
52
  getRoleId,
54
53
  getStripePublishableKey
@@ -61,7 +60,7 @@ import {
61
60
  StripeSubscriptionService,
62
61
  StripeUsageService,
63
62
  cn
64
- } from "../chunk-ORFXBO7F.mjs";
63
+ } from "../chunk-DU64WMZD.mjs";
65
64
  import "../chunk-AUXK7QSA.mjs";
66
65
  import "../chunk-C7C7VY4F.mjs";
67
66
  import "../chunk-U4MTVHOC.mjs";
@@ -533,18 +532,19 @@ function BillingUsageSummaryCard({
533
532
  __name(BillingUsageSummaryCard, "BillingUsageSummaryCard");
534
533
 
535
534
  // src/features/billing/components/containers/BillingDashboardContainer.tsx
536
- import { CreditCard as CreditCard4, Loader2 as Loader23, Wallet as Wallet2 } from "lucide-react";
537
- import { useCallback as useCallback2, useEffect as useEffect8, useState as useState14 } from "react";
535
+ import { CreditCard as CreditCard4, Loader2 as Loader22, Wallet as Wallet2 } from "lucide-react";
536
+ import { useSearchParams } from "next/navigation";
537
+ import { useCallback as useCallback4, useEffect as useEffect9, useMemo as useMemo3, useState as useState13 } from "react";
538
538
 
539
539
  // src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx
540
540
  import { CreditCard as CreditCard2 } from "lucide-react";
541
541
  import { useEffect as useEffect3, useState as useState4 } from "react";
542
542
 
543
- // src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx
543
+ // src/features/billing/stripe-customer/components/forms/PaymentMethodForm.tsx
544
544
  import { CardElement, useElements, useStripe } from "@stripe/react-stripe-js";
545
545
  import { useEffect, useState as useState2 } from "react";
546
546
  import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
547
- function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
547
+ function PaymentMethodForm({ onSuccess, onCancel, isLoading = false }) {
548
548
  const stripe = useStripe();
549
549
  const elements = useElements();
550
550
  const [setupIntent, setSetupIntent] = useState2(null);
@@ -559,16 +559,14 @@ function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
559
559
  const intent = await StripeCustomerService.createSetupIntent();
560
560
  setSetupIntent(intent);
561
561
  } catch (err) {
562
- console.error("[PaymentMethodEditor] Failed to create setup intent:", err);
562
+ console.error("[PaymentMethodForm] Failed to create setup intent:", err);
563
563
  setError("Failed to initialize payment form. Please try again.");
564
564
  } finally {
565
565
  setLoading(false);
566
566
  }
567
567
  }, "fetchSetupIntent");
568
- if (open) {
569
- fetchSetupIntent();
570
- }
571
- }, [open]);
568
+ fetchSetupIntent();
569
+ }, []);
572
570
  const handleSubmit = /* @__PURE__ */ __name(async (e) => {
573
571
  e.preventDefault();
574
572
  if (!stripe || !elements || !setupIntent) {
@@ -590,7 +588,7 @@ function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
590
588
  }
591
589
  );
592
590
  if (stripeError) {
593
- console.error("[PaymentMethodEditor] Stripe error:", stripeError);
591
+ console.error("[PaymentMethodForm] Stripe error:", stripeError);
594
592
  setError(stripeError.message || "Failed to add payment method. Please check your card details.");
595
593
  setIsSubmitting(false);
596
594
  return;
@@ -601,58 +599,81 @@ function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
601
599
  });
602
600
  }
603
601
  onSuccess();
604
- onOpenChange(false);
605
602
  } catch (err) {
606
- console.error("[PaymentMethodEditor] Error:", err);
603
+ console.error("[PaymentMethodForm] Error:", err);
607
604
  setError(err.message || "An unexpected error occurred. Please try again.");
608
605
  } finally {
609
606
  setIsSubmitting(false);
610
607
  }
611
608
  }, "handleSubmit");
612
- return /* @__PURE__ */ jsx6(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs6(DialogContent, { className: "max-w-md", children: [
613
- /* @__PURE__ */ jsxs6(DialogHeader, { children: [
614
- /* @__PURE__ */ jsx6(DialogTitle, { children: "Add Payment Method" }),
615
- /* @__PURE__ */ jsx6(DialogDescription, { children: "Add a new payment method to your account. Your card information is securely processed by Stripe." })
616
- ] }),
617
- loading && /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground", children: "Loading payment form..." }) }),
618
- !loading && setupIntent && /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className: "flex flex-col gap-y-4", children: [
619
- /* @__PURE__ */ jsx6("div", { className: "rounded-md border border-gray-300 p-3", children: /* @__PURE__ */ jsx6(
620
- CardElement,
621
- {
622
- options: {
623
- style: {
624
- base: {
625
- fontSize: "16px",
626
- color: "#424770",
627
- "::placeholder": {
628
- color: "#aab7c4"
629
- }
630
- },
631
- invalid: {
632
- color: "#9e2146"
609
+ if (loading) {
610
+ return /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground", children: "Loading payment form..." }) });
611
+ }
612
+ if (!setupIntent && error) {
613
+ return /* @__PURE__ */ jsx6(Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ jsx6(AlertDescription, { children: error }) });
614
+ }
615
+ return /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className: "flex flex-col gap-y-4", children: [
616
+ /* @__PURE__ */ jsx6("div", { className: "rounded-md border border-gray-300 p-3", children: /* @__PURE__ */ jsx6(
617
+ CardElement,
618
+ {
619
+ options: {
620
+ style: {
621
+ base: {
622
+ fontSize: "16px",
623
+ color: "#424770",
624
+ "::placeholder": {
625
+ color: "#aab7c4"
633
626
  }
627
+ },
628
+ invalid: {
629
+ color: "#9e2146"
634
630
  }
635
631
  }
636
632
  }
637
- ) }),
638
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-2", children: [
639
- /* @__PURE__ */ jsx6(
640
- Checkbox,
641
- {
642
- id: "setAsDefault",
643
- checked: setAsDefault,
644
- onCheckedChange: (checked) => setSetAsDefault(!!checked)
645
- }
646
- ),
647
- /* @__PURE__ */ jsx6(Label, { htmlFor: "setAsDefault", className: "text-sm font-normal", children: "Set as default payment method" })
648
- ] }),
649
- error && /* @__PURE__ */ jsx6(Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ jsx6(AlertDescription, { children: error }) }),
650
- /* @__PURE__ */ jsxs6("div", { className: "flex justify-end gap-x-2", children: [
651
- /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isSubmitting, children: "Cancel" }),
652
- /* @__PURE__ */ jsx6(Button, { type: "submit", disabled: !stripe || isSubmitting, children: isSubmitting ? "Processing..." : "Add Card" })
653
- ] })
633
+ }
634
+ ) }),
635
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-x-2", children: [
636
+ /* @__PURE__ */ jsx6(
637
+ Checkbox,
638
+ {
639
+ id: "setAsDefault",
640
+ checked: setAsDefault,
641
+ onCheckedChange: (checked) => setSetAsDefault(!!checked)
642
+ }
643
+ ),
644
+ /* @__PURE__ */ jsx6(Label, { htmlFor: "setAsDefault", className: "text-sm font-normal", children: "Set as default payment method" })
654
645
  ] }),
655
- !loading && !setupIntent && error && /* @__PURE__ */ jsx6(Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ jsx6(AlertDescription, { children: error }) })
646
+ error && /* @__PURE__ */ jsx6(Alert, { variant: "destructive", className: "bg-red-50 border-red-200", children: /* @__PURE__ */ jsx6(AlertDescription, { children: error }) }),
647
+ /* @__PURE__ */ jsxs6("div", { className: "flex justify-end gap-x-2", children: [
648
+ /* @__PURE__ */ jsx6(Button, { type: "button", variant: "outline", onClick: onCancel, disabled: isSubmitting || isLoading, children: "Cancel" }),
649
+ /* @__PURE__ */ jsx6(Button, { type: "submit", disabled: !stripe || isSubmitting || isLoading, children: isSubmitting ? "Processing..." : "Add Card" })
650
+ ] })
651
+ ] });
652
+ }
653
+ __name(PaymentMethodForm, "PaymentMethodForm");
654
+
655
+ // src/features/billing/stripe-customer/components/forms/PaymentMethodEditor.tsx
656
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
657
+ function PaymentMethodEditor({ open, onOpenChange, onSuccess }) {
658
+ const handleSuccess = /* @__PURE__ */ __name(() => {
659
+ onSuccess();
660
+ onOpenChange(false);
661
+ }, "handleSuccess");
662
+ const handleCancel = /* @__PURE__ */ __name(() => {
663
+ onOpenChange(false);
664
+ }, "handleCancel");
665
+ return /* @__PURE__ */ jsx7(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs7(DialogContent, { className: "max-w-md", children: [
666
+ /* @__PURE__ */ jsxs7(DialogHeader, { children: [
667
+ /* @__PURE__ */ jsx7(DialogTitle, { children: "Add Payment Method" }),
668
+ /* @__PURE__ */ jsx7(DialogDescription, { children: "Add a new payment method to your account. Your card information is securely processed by Stripe." })
669
+ ] }),
670
+ open && /* @__PURE__ */ jsx7(
671
+ PaymentMethodForm,
672
+ {
673
+ onSuccess: handleSuccess,
674
+ onCancel: handleCancel
675
+ }
676
+ )
656
677
  ] }) });
657
678
  }
658
679
  __name(PaymentMethodEditor, "PaymentMethodEditor");
@@ -660,7 +681,7 @@ __name(PaymentMethodEditor, "PaymentMethodEditor");
660
681
  // src/features/billing/stripe-customer/components/details/PaymentMethodCard.tsx
661
682
  import { MoreVertical } from "lucide-react";
662
683
  import { useEffect as useEffect2, useState as useState3 } from "react";
663
- import { Fragment, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
684
+ import { Fragment, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
664
685
  var brandIcons = {
665
686
  visa: "\u{1F4B3}",
666
687
  mastercard: "\u{1F4B3}",
@@ -710,28 +731,28 @@ function PaymentMethodCard({ paymentMethod, onUpdate }) {
710
731
  setLoading(false);
711
732
  }
712
733
  }, "handleRemove");
713
- return /* @__PURE__ */ jsxs7(Fragment, { children: [
714
- /* @__PURE__ */ jsxs7(Card, { className: "relative", children: [
715
- isDefault && /* @__PURE__ */ jsx7(Badge, { className: "absolute right-2 top-2 bg-green-100 text-green-800 hover:bg-green-100", children: "Default" }),
716
- /* @__PURE__ */ jsxs7(CardHeader, { className: "flex flex-row items-center justify-between pb-2", children: [
717
- /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-x-2", children: [
718
- /* @__PURE__ */ jsx7("span", { className: "text-2xl", children: brandIcon }),
719
- /* @__PURE__ */ jsx7("span", { className: "text-sm font-medium capitalize", children: brand })
734
+ return /* @__PURE__ */ jsxs8(Fragment, { children: [
735
+ /* @__PURE__ */ jsxs8(Card, { className: "relative", children: [
736
+ isDefault && /* @__PURE__ */ jsx8(Badge, { className: "absolute right-2 top-2 bg-green-100 text-green-800 hover:bg-green-100", children: "Default" }),
737
+ /* @__PURE__ */ jsxs8(CardHeader, { className: "flex flex-row items-center justify-between pb-2", children: [
738
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-x-2", children: [
739
+ /* @__PURE__ */ jsx8("span", { className: "text-2xl", children: brandIcon }),
740
+ /* @__PURE__ */ jsx8("span", { className: "text-sm font-medium capitalize", children: brand })
720
741
  ] }),
721
- /* @__PURE__ */ jsxs7(DropdownMenu, { children: [
722
- /* @__PURE__ */ jsx7(DropdownMenuTrigger, { children: /* @__PURE__ */ jsx7(Button, { render: /* @__PURE__ */ jsx7("div", {}), nativeButton: false, variant: "ghost", size: "sm", disabled: loading, className: "h-8 w-8 p-0", children: /* @__PURE__ */ jsx7(MoreVertical, { className: "h-4 w-4" }) }) }),
723
- /* @__PURE__ */ jsxs7(DropdownMenuContent, { align: "end", children: [
724
- !isDefault && /* @__PURE__ */ jsx7(DropdownMenuItem, { onClick: handleSetDefault, disabled: loading, children: "Set as Default" }),
725
- /* @__PURE__ */ jsx7(DropdownMenuItem, { onClick: () => setShowRemoveDialog(true), disabled: loading, className: "text-red-600", children: "Remove" })
742
+ /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
743
+ /* @__PURE__ */ jsx8(DropdownMenuTrigger, { children: /* @__PURE__ */ jsx8(Button, { render: /* @__PURE__ */ jsx8("div", {}), nativeButton: false, variant: "ghost", size: "sm", disabled: loading, className: "h-8 w-8 p-0", children: /* @__PURE__ */ jsx8(MoreVertical, { className: "h-4 w-4" }) }) }),
744
+ /* @__PURE__ */ jsxs8(DropdownMenuContent, { align: "end", children: [
745
+ !isDefault && /* @__PURE__ */ jsx8(DropdownMenuItem, { onClick: handleSetDefault, disabled: loading, children: "Set as Default" }),
746
+ /* @__PURE__ */ jsx8(DropdownMenuItem, { onClick: () => setShowRemoveDialog(true), disabled: loading, className: "text-red-600", children: "Remove" })
726
747
  ] })
727
748
  ] })
728
749
  ] }),
729
- /* @__PURE__ */ jsx7(CardContent, { children: /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-y-1", children: [
730
- /* @__PURE__ */ jsxs7("p", { className: "text-lg font-semibold", children: [
750
+ /* @__PURE__ */ jsx8(CardContent, { children: /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-y-1", children: [
751
+ /* @__PURE__ */ jsxs8("p", { className: "text-lg font-semibold", children: [
731
752
  "\u2022\u2022\u2022\u2022 ",
732
753
  last4
733
754
  ] }),
734
- /* @__PURE__ */ jsxs7("p", { className: "text-sm text-muted-foreground", children: [
755
+ /* @__PURE__ */ jsxs8("p", { className: "text-sm text-muted-foreground", children: [
735
756
  "Expires ",
736
757
  String(expMonth).padStart(2, "0"),
737
758
  "/",
@@ -739,17 +760,17 @@ function PaymentMethodCard({ paymentMethod, onUpdate }) {
739
760
  ] })
740
761
  ] }) })
741
762
  ] }),
742
- /* @__PURE__ */ jsx7(AlertDialog, { open: showRemoveDialog, onOpenChange: setShowRemoveDialog, children: /* @__PURE__ */ jsxs7(AlertDialogContent, { children: [
743
- /* @__PURE__ */ jsxs7(AlertDialogHeader, { children: [
744
- /* @__PURE__ */ jsx7(AlertDialogTitle, { children: "Remove Payment Method" }),
745
- /* @__PURE__ */ jsxs7(AlertDialogDescription, { children: [
763
+ /* @__PURE__ */ jsx8(AlertDialog, { open: showRemoveDialog, onOpenChange: setShowRemoveDialog, children: /* @__PURE__ */ jsxs8(AlertDialogContent, { children: [
764
+ /* @__PURE__ */ jsxs8(AlertDialogHeader, { children: [
765
+ /* @__PURE__ */ jsx8(AlertDialogTitle, { children: "Remove Payment Method" }),
766
+ /* @__PURE__ */ jsxs8(AlertDialogDescription, { children: [
746
767
  "Are you sure you want to remove this payment method? This action cannot be undone.",
747
768
  isDefault && " This is your default payment method."
748
769
  ] })
749
770
  ] }),
750
- /* @__PURE__ */ jsxs7(AlertDialogFooter, { children: [
751
- /* @__PURE__ */ jsx7(AlertDialogCancel, { disabled: loading, children: "Cancel" }),
752
- /* @__PURE__ */ jsx7(AlertDialogAction, { onClick: handleRemove, disabled: loading, className: "bg-red-600 hover:bg-red-700", children: loading ? "Removing..." : "Remove" })
771
+ /* @__PURE__ */ jsxs8(AlertDialogFooter, { children: [
772
+ /* @__PURE__ */ jsx8(AlertDialogCancel, { disabled: loading, children: "Cancel" }),
773
+ /* @__PURE__ */ jsx8(AlertDialogAction, { onClick: handleRemove, disabled: loading, className: "bg-red-600 hover:bg-red-700", children: loading ? "Removing..." : "Remove" })
753
774
  ] })
754
775
  ] }) })
755
776
  ] });
@@ -757,14 +778,14 @@ function PaymentMethodCard({ paymentMethod, onUpdate }) {
757
778
  __name(PaymentMethodCard, "PaymentMethodCard");
758
779
 
759
780
  // src/features/billing/stripe-customer/components/lists/PaymentMethodsList.tsx
760
- import { jsx as jsx8 } from "react/jsx-runtime";
781
+ import { jsx as jsx9 } from "react/jsx-runtime";
761
782
  function PaymentMethodsList({ paymentMethods, onUpdate }) {
762
- return /* @__PURE__ */ jsx8("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3", children: paymentMethods.map((paymentMethod) => /* @__PURE__ */ jsx8(PaymentMethodCard, { paymentMethod, onUpdate }, paymentMethod.id)) });
783
+ return /* @__PURE__ */ jsx9("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3", children: paymentMethods.map((paymentMethod) => /* @__PURE__ */ jsx9(PaymentMethodCard, { paymentMethod, onUpdate }, paymentMethod.id)) });
763
784
  }
764
785
  __name(PaymentMethodsList, "PaymentMethodsList");
765
786
 
766
787
  // src/features/billing/stripe-customer/components/containers/PaymentMethodsContainer.tsx
767
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
788
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
768
789
  function PaymentMethodsContainer() {
769
790
  const [paymentMethods, setPaymentMethods] = useState4([]);
770
791
  const [loading, setLoading] = useState4(true);
@@ -784,26 +805,26 @@ function PaymentMethodsContainer() {
784
805
  loadPaymentMethods();
785
806
  }, []);
786
807
  if (loading) {
787
- return /* @__PURE__ */ jsx9("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground", children: "Loading payment methods..." }) });
808
+ return /* @__PURE__ */ jsx10("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx10("p", { className: "text-muted-foreground", children: "Loading payment methods..." }) });
788
809
  }
789
- return /* @__PURE__ */ jsxs8("div", { className: "flex w-full flex-col gap-y-6", children: [
790
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between", children: [
791
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-x-3", children: [
792
- /* @__PURE__ */ jsx9(CreditCard2, { className: "h-8 w-8" }),
793
- /* @__PURE__ */ jsx9("h1", { className: "text-3xl font-bold", children: "Payment Methods" })
810
+ return /* @__PURE__ */ jsxs9("div", { className: "flex w-full flex-col gap-y-6", children: [
811
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
812
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-x-3", children: [
813
+ /* @__PURE__ */ jsx10(CreditCard2, { className: "h-8 w-8" }),
814
+ /* @__PURE__ */ jsx10("h1", { className: "text-3xl font-bold", children: "Payment Methods" })
794
815
  ] }),
795
- /* @__PURE__ */ jsx9(Button, { onClick: () => setShowAddPaymentMethod(true), children: "Add Payment Method" })
816
+ /* @__PURE__ */ jsx10(Button, { onClick: () => setShowAddPaymentMethod(true), children: "Add Payment Method" })
796
817
  ] }),
797
- paymentMethods.length === 0 && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 bg-muted/50 p-12", children: [
798
- /* @__PURE__ */ jsx9(CreditCard2, { className: "h-16 w-16 text-muted-foreground" }),
799
- /* @__PURE__ */ jsxs8("div", { className: "text-center", children: [
800
- /* @__PURE__ */ jsx9("h3", { className: "mb-2 text-xl font-semibold", children: "No payment methods" }),
801
- /* @__PURE__ */ jsx9("p", { className: "mb-4 text-muted-foreground", children: "Add a payment method to enable subscriptions and secure checkout." }),
802
- /* @__PURE__ */ jsx9(Button, { onClick: () => setShowAddPaymentMethod(true), children: "Add Your First Card" })
818
+ paymentMethods.length === 0 && /* @__PURE__ */ jsxs9("div", { className: "flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 bg-muted/50 p-12", children: [
819
+ /* @__PURE__ */ jsx10(CreditCard2, { className: "h-16 w-16 text-muted-foreground" }),
820
+ /* @__PURE__ */ jsxs9("div", { className: "text-center", children: [
821
+ /* @__PURE__ */ jsx10("h3", { className: "mb-2 text-xl font-semibold", children: "No payment methods" }),
822
+ /* @__PURE__ */ jsx10("p", { className: "mb-4 text-muted-foreground", children: "Add a payment method to enable subscriptions and secure checkout." }),
823
+ /* @__PURE__ */ jsx10(Button, { onClick: () => setShowAddPaymentMethod(true), children: "Add Your First Card" })
803
824
  ] })
804
825
  ] }),
805
- paymentMethods.length > 0 && /* @__PURE__ */ jsx9(PaymentMethodsList, { paymentMethods, onUpdate: loadPaymentMethods }),
806
- showAddPaymentMethod && /* @__PURE__ */ jsx9(
826
+ paymentMethods.length > 0 && /* @__PURE__ */ jsx10(PaymentMethodsList, { paymentMethods, onUpdate: loadPaymentMethods }),
827
+ showAddPaymentMethod && /* @__PURE__ */ jsx10(
807
828
  PaymentMethodEditor,
808
829
  {
809
830
  open: showAddPaymentMethod,
@@ -872,7 +893,7 @@ __name(formatDate3, "formatDate");
872
893
  import { Download, ExternalLink as ExternalLink2, RefreshCw } from "lucide-react";
873
894
 
874
895
  // src/features/billing/stripe-invoice/components/widgets/InvoiceStatusBadge.tsx
875
- import { jsx as jsx10 } from "react/jsx-runtime";
896
+ import { jsx as jsx11 } from "react/jsx-runtime";
876
897
  var statusConfig = {
877
898
  ["draft" /* DRAFT */]: {
878
899
  label: "Draft",
@@ -897,12 +918,12 @@ var statusConfig = {
897
918
  };
898
919
  function InvoiceStatusBadge({ status }) {
899
920
  const config = statusConfig[status] || statusConfig["draft" /* DRAFT */];
900
- return /* @__PURE__ */ jsx10("span", { className: `${config.color} text-xs px-2 py-1 rounded-full font-medium`, children: config.label });
921
+ return /* @__PURE__ */ jsx11("span", { className: `${config.color} text-xs px-2 py-1 rounded-full font-medium`, children: config.label });
901
922
  }
902
923
  __name(InvoiceStatusBadge, "InvoiceStatusBadge");
903
924
 
904
925
  // src/features/billing/stripe-invoice/components/details/InvoiceDetails.tsx
905
- import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
926
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
906
927
  function InvoiceDetails({ invoice, open, onOpenChange, onInvoiceChange }) {
907
928
  const handleDownloadPDF = /* @__PURE__ */ __name(() => {
908
929
  if (invoice.stripePdfUrl) {
@@ -923,87 +944,87 @@ function InvoiceDetails({ invoice, open, onOpenChange, onInvoiceChange }) {
923
944
  return invoice.stripeInvoiceId.slice(-8);
924
945
  }, "getInvoiceNumber");
925
946
  const productName = invoice.subscription?.price?.product?.name || "Subscription";
926
- return /* @__PURE__ */ jsx11(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs9(DialogContent, { className: "max-w-2xl", children: [
927
- /* @__PURE__ */ jsxs9(DialogHeader, { children: [
928
- /* @__PURE__ */ jsxs9(DialogTitle, { children: [
947
+ return /* @__PURE__ */ jsx12(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs10(DialogContent, { className: "max-w-2xl", children: [
948
+ /* @__PURE__ */ jsxs10(DialogHeader, { children: [
949
+ /* @__PURE__ */ jsxs10(DialogTitle, { children: [
929
950
  "Invoice ",
930
951
  getInvoiceNumber()
931
952
  ] }),
932
- /* @__PURE__ */ jsx11(DialogDescription, { children: formatDate3(invoice.periodStart) })
953
+ /* @__PURE__ */ jsx12(DialogDescription, { children: formatDate3(invoice.periodStart) })
933
954
  ] }),
934
- /* @__PURE__ */ jsxs9("div", { className: "space-y-6", children: [
935
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-x-3", children: [
936
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Status:" }),
937
- /* @__PURE__ */ jsx11(InvoiceStatusBadge, { status: invoice.status })
955
+ /* @__PURE__ */ jsxs10("div", { className: "space-y-6", children: [
956
+ /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-x-3", children: [
957
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Status:" }),
958
+ /* @__PURE__ */ jsx12(InvoiceStatusBadge, { status: invoice.status })
938
959
  ] }),
939
- /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-2 gap-4", children: [
940
- /* @__PURE__ */ jsxs9("div", { children: [
941
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Billing Period:" }),
942
- /* @__PURE__ */ jsxs9("p", { className: "font-medium", children: [
960
+ /* @__PURE__ */ jsxs10("div", { className: "grid grid-cols-2 gap-4", children: [
961
+ /* @__PURE__ */ jsxs10("div", { children: [
962
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Billing Period:" }),
963
+ /* @__PURE__ */ jsxs10("p", { className: "font-medium", children: [
943
964
  formatDate3(invoice.periodStart),
944
965
  " - ",
945
966
  formatDate3(invoice.periodEnd)
946
967
  ] })
947
968
  ] }),
948
- invoice.dueDate && /* @__PURE__ */ jsxs9("div", { children: [
949
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Due Date:" }),
950
- /* @__PURE__ */ jsx11("p", { className: "font-medium", children: formatDate3(invoice.dueDate) })
969
+ invoice.dueDate && /* @__PURE__ */ jsxs10("div", { children: [
970
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Due Date:" }),
971
+ /* @__PURE__ */ jsx12("p", { className: "font-medium", children: formatDate3(invoice.dueDate) })
951
972
  ] }),
952
- invoice.paidAt && /* @__PURE__ */ jsxs9("div", { children: [
953
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Paid Date:" }),
954
- /* @__PURE__ */ jsx11("p", { className: "font-medium", children: formatDate3(invoice.paidAt) })
973
+ invoice.paidAt && /* @__PURE__ */ jsxs10("div", { children: [
974
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Paid Date:" }),
975
+ /* @__PURE__ */ jsx12("p", { className: "font-medium", children: formatDate3(invoice.paidAt) })
955
976
  ] }),
956
- /* @__PURE__ */ jsxs9("div", { children: [
957
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Attempt Count:" }),
958
- /* @__PURE__ */ jsx11("p", { className: "font-medium", children: invoice.attemptCount })
977
+ /* @__PURE__ */ jsxs10("div", { children: [
978
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Attempt Count:" }),
979
+ /* @__PURE__ */ jsx12("p", { className: "font-medium", children: invoice.attemptCount })
959
980
  ] })
960
981
  ] }),
961
- /* @__PURE__ */ jsxs9("div", { children: [
962
- /* @__PURE__ */ jsx11("h4", { className: "text-sm font-medium text-muted-foreground mb-2", children: "Line Items" }),
963
- /* @__PURE__ */ jsx11("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs9("table", { className: "w-full", children: [
964
- /* @__PURE__ */ jsx11("thead", { className: "bg-muted", children: /* @__PURE__ */ jsxs9("tr", { children: [
965
- /* @__PURE__ */ jsx11("th", { className: "text-left p-3 text-sm font-medium", children: "Description" }),
966
- /* @__PURE__ */ jsx11("th", { className: "text-right p-3 text-sm font-medium", children: "Amount" })
982
+ /* @__PURE__ */ jsxs10("div", { children: [
983
+ /* @__PURE__ */ jsx12("h4", { className: "text-sm font-medium text-muted-foreground mb-2", children: "Line Items" }),
984
+ /* @__PURE__ */ jsx12("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs10("table", { className: "w-full", children: [
985
+ /* @__PURE__ */ jsx12("thead", { className: "bg-muted", children: /* @__PURE__ */ jsxs10("tr", { children: [
986
+ /* @__PURE__ */ jsx12("th", { className: "text-left p-3 text-sm font-medium", children: "Description" }),
987
+ /* @__PURE__ */ jsx12("th", { className: "text-right p-3 text-sm font-medium", children: "Amount" })
967
988
  ] }) }),
968
- /* @__PURE__ */ jsx11("tbody", { children: /* @__PURE__ */ jsxs9("tr", { className: "border-t", children: [
969
- /* @__PURE__ */ jsx11("td", { className: "p-3", children: productName }),
970
- /* @__PURE__ */ jsx11("td", { className: "p-3 text-right", children: formatCurrency(invoice.subtotal, invoice.currency) })
989
+ /* @__PURE__ */ jsx12("tbody", { children: /* @__PURE__ */ jsxs10("tr", { className: "border-t", children: [
990
+ /* @__PURE__ */ jsx12("td", { className: "p-3", children: productName }),
991
+ /* @__PURE__ */ jsx12("td", { className: "p-3 text-right", children: formatCurrency(invoice.subtotal, invoice.currency) })
971
992
  ] }) })
972
993
  ] }) })
973
994
  ] }),
974
- /* @__PURE__ */ jsxs9("div", { className: "space-y-2 border-t pt-4", children: [
975
- /* @__PURE__ */ jsxs9("div", { className: "flex justify-between", children: [
976
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Subtotal:" }),
977
- /* @__PURE__ */ jsx11("span", { className: "font-medium", children: formatCurrency(invoice.subtotal, invoice.currency) })
995
+ /* @__PURE__ */ jsxs10("div", { className: "space-y-2 border-t pt-4", children: [
996
+ /* @__PURE__ */ jsxs10("div", { className: "flex justify-between", children: [
997
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Subtotal:" }),
998
+ /* @__PURE__ */ jsx12("span", { className: "font-medium", children: formatCurrency(invoice.subtotal, invoice.currency) })
978
999
  ] }),
979
- invoice.tax !== void 0 && invoice.tax > 0 && /* @__PURE__ */ jsxs9("div", { className: "flex justify-between", children: [
980
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Tax:" }),
981
- /* @__PURE__ */ jsx11("span", { className: "font-medium", children: formatCurrency(invoice.tax, invoice.currency) })
1000
+ invoice.tax !== void 0 && invoice.tax > 0 && /* @__PURE__ */ jsxs10("div", { className: "flex justify-between", children: [
1001
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Tax:" }),
1002
+ /* @__PURE__ */ jsx12("span", { className: "font-medium", children: formatCurrency(invoice.tax, invoice.currency) })
982
1003
  ] }),
983
- /* @__PURE__ */ jsxs9("div", { className: "flex justify-between text-lg font-semibold border-t pt-2", children: [
984
- /* @__PURE__ */ jsx11("span", { children: "Total:" }),
985
- /* @__PURE__ */ jsx11("span", { children: formatCurrency(invoice.total, invoice.currency) })
1004
+ /* @__PURE__ */ jsxs10("div", { className: "flex justify-between text-lg font-semibold border-t pt-2", children: [
1005
+ /* @__PURE__ */ jsx12("span", { children: "Total:" }),
1006
+ /* @__PURE__ */ jsx12("span", { children: formatCurrency(invoice.total, invoice.currency) })
986
1007
  ] }),
987
- invoice.amountPaid > 0 && /* @__PURE__ */ jsxs9("div", { className: "flex justify-between", children: [
988
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Amount Paid:" }),
989
- /* @__PURE__ */ jsx11("span", { className: "font-medium text-green-600", children: formatCurrency(invoice.amountPaid, invoice.currency) })
1008
+ invoice.amountPaid > 0 && /* @__PURE__ */ jsxs10("div", { className: "flex justify-between", children: [
1009
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Amount Paid:" }),
1010
+ /* @__PURE__ */ jsx12("span", { className: "font-medium text-green-600", children: formatCurrency(invoice.amountPaid, invoice.currency) })
990
1011
  ] }),
991
- invoice.amountRemaining > 0 && /* @__PURE__ */ jsxs9("div", { className: "flex justify-between", children: [
992
- /* @__PURE__ */ jsx11("span", { className: "text-sm font-medium text-muted-foreground", children: "Amount Due:" }),
993
- /* @__PURE__ */ jsx11("span", { className: "font-medium text-red-600", children: formatCurrency(invoice.amountRemaining, invoice.currency) })
1012
+ invoice.amountRemaining > 0 && /* @__PURE__ */ jsxs10("div", { className: "flex justify-between", children: [
1013
+ /* @__PURE__ */ jsx12("span", { className: "text-sm font-medium text-muted-foreground", children: "Amount Due:" }),
1014
+ /* @__PURE__ */ jsx12("span", { className: "font-medium text-red-600", children: formatCurrency(invoice.amountRemaining, invoice.currency) })
994
1015
  ] })
995
1016
  ] }),
996
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-wrap gap-2 pt-4 border-t", children: [
997
- invoice.stripePdfUrl && /* @__PURE__ */ jsxs9(Button, { variant: "outline", onClick: handleDownloadPDF, children: [
998
- /* @__PURE__ */ jsx11(Download, { className: "mr-2 h-4 w-4" }),
1017
+ /* @__PURE__ */ jsxs10("div", { className: "flex flex-wrap gap-2 pt-4 border-t", children: [
1018
+ invoice.stripePdfUrl && /* @__PURE__ */ jsxs10(Button, { variant: "outline", onClick: handleDownloadPDF, children: [
1019
+ /* @__PURE__ */ jsx12(Download, { className: "mr-2 h-4 w-4" }),
999
1020
  "Download PDF"
1000
1021
  ] }),
1001
- invoice.status === "open" /* OPEN */ && invoice.attempted && /* @__PURE__ */ jsxs9(Button, { variant: "default", onClick: handleRetryPayment, children: [
1002
- /* @__PURE__ */ jsx11(RefreshCw, { className: "mr-2 h-4 w-4" }),
1022
+ invoice.status === "open" /* OPEN */ && invoice.attempted && /* @__PURE__ */ jsxs10(Button, { variant: "default", onClick: handleRetryPayment, children: [
1023
+ /* @__PURE__ */ jsx12(RefreshCw, { className: "mr-2 h-4 w-4" }),
1003
1024
  "Retry Payment"
1004
1025
  ] }),
1005
- invoice.stripeHostedInvoiceUrl && /* @__PURE__ */ jsxs9(Button, { variant: "outline", onClick: handleViewInStripe, children: [
1006
- /* @__PURE__ */ jsx11(ExternalLink2, { className: "mr-2 h-4 w-4" }),
1026
+ invoice.stripeHostedInvoiceUrl && /* @__PURE__ */ jsxs10(Button, { variant: "outline", onClick: handleViewInStripe, children: [
1027
+ /* @__PURE__ */ jsx12(ExternalLink2, { className: "mr-2 h-4 w-4" }),
1007
1028
  "View in Stripe"
1008
1029
  ] })
1009
1030
  ] })
@@ -1013,7 +1034,7 @@ function InvoiceDetails({ invoice, open, onOpenChange, onInvoiceChange }) {
1013
1034
  __name(InvoiceDetails, "InvoiceDetails");
1014
1035
 
1015
1036
  // src/features/billing/stripe-invoice/components/lists/InvoicesList.tsx
1016
- import { Fragment as Fragment2, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
1037
+ import { Fragment as Fragment2, jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1017
1038
  function InvoicesList({ invoices, onInvoicesChange }) {
1018
1039
  const [selectedInvoice, setSelectedInvoice] = useState5(null);
1019
1040
  const handleRowClick = /* @__PURE__ */ __name((invoice) => {
@@ -1025,38 +1046,38 @@ function InvoicesList({ invoices, onInvoicesChange }) {
1025
1046
  }
1026
1047
  return invoice.stripeInvoiceId.slice(-8);
1027
1048
  }, "getInvoiceNumber");
1028
- return /* @__PURE__ */ jsxs10(Fragment2, { children: [
1029
- /* @__PURE__ */ jsx12("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs10(Table, { children: [
1030
- /* @__PURE__ */ jsx12(TableHeader, { className: "bg-muted", children: /* @__PURE__ */ jsxs10(TableRow, { children: [
1031
- /* @__PURE__ */ jsx12(TableHead, { children: "Invoice #" }),
1032
- /* @__PURE__ */ jsx12(TableHead, { children: "Date" }),
1033
- /* @__PURE__ */ jsx12(TableHead, { children: "Status" }),
1034
- /* @__PURE__ */ jsx12(TableHead, { className: "text-right", children: "Amount" }),
1035
- /* @__PURE__ */ jsx12(TableHead, { children: "Period" })
1049
+ return /* @__PURE__ */ jsxs11(Fragment2, { children: [
1050
+ /* @__PURE__ */ jsx13("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs11(Table, { children: [
1051
+ /* @__PURE__ */ jsx13(TableHeader, { className: "bg-muted", children: /* @__PURE__ */ jsxs11(TableRow, { children: [
1052
+ /* @__PURE__ */ jsx13(TableHead, { children: "Invoice #" }),
1053
+ /* @__PURE__ */ jsx13(TableHead, { children: "Date" }),
1054
+ /* @__PURE__ */ jsx13(TableHead, { children: "Status" }),
1055
+ /* @__PURE__ */ jsx13(TableHead, { className: "text-right", children: "Amount" }),
1056
+ /* @__PURE__ */ jsx13(TableHead, { children: "Period" })
1036
1057
  ] }) }),
1037
- /* @__PURE__ */ jsx12(TableBody, { children: invoices.map((invoice) => {
1058
+ /* @__PURE__ */ jsx13(TableBody, { children: invoices.map((invoice) => {
1038
1059
  const invoiceNumber = getInvoiceNumber(invoice);
1039
1060
  const date = formatDate3(invoice.periodStart);
1040
1061
  const amount = formatCurrency(invoice.total, invoice.currency);
1041
1062
  const period = `${formatDate3(invoice.periodStart)} - ${formatDate3(invoice.periodEnd)}`;
1042
- return /* @__PURE__ */ jsxs10(
1063
+ return /* @__PURE__ */ jsxs11(
1043
1064
  TableRow,
1044
1065
  {
1045
1066
  onClick: () => handleRowClick(invoice),
1046
1067
  className: "cursor-pointer hover:bg-muted/50",
1047
1068
  children: [
1048
- /* @__PURE__ */ jsx12(TableCell, { className: "font-medium", children: invoiceNumber }),
1049
- /* @__PURE__ */ jsx12(TableCell, { className: "text-muted-foreground text-sm", children: date }),
1050
- /* @__PURE__ */ jsx12(TableCell, { children: /* @__PURE__ */ jsx12(InvoiceStatusBadge, { status: invoice.status }) }),
1051
- /* @__PURE__ */ jsx12(TableCell, { className: "text-right font-medium", children: amount }),
1052
- /* @__PURE__ */ jsx12(TableCell, { className: "text-muted-foreground text-sm", children: period })
1069
+ /* @__PURE__ */ jsx13(TableCell, { className: "font-medium", children: invoiceNumber }),
1070
+ /* @__PURE__ */ jsx13(TableCell, { className: "text-muted-foreground text-sm", children: date }),
1071
+ /* @__PURE__ */ jsx13(TableCell, { children: /* @__PURE__ */ jsx13(InvoiceStatusBadge, { status: invoice.status }) }),
1072
+ /* @__PURE__ */ jsx13(TableCell, { className: "text-right font-medium", children: amount }),
1073
+ /* @__PURE__ */ jsx13(TableCell, { className: "text-muted-foreground text-sm", children: period })
1053
1074
  ]
1054
1075
  },
1055
1076
  invoice.id
1056
1077
  );
1057
1078
  }) })
1058
1079
  ] }) }),
1059
- selectedInvoice && /* @__PURE__ */ jsx12(
1080
+ selectedInvoice && /* @__PURE__ */ jsx13(
1060
1081
  InvoiceDetails,
1061
1082
  {
1062
1083
  invoice: selectedInvoice,
@@ -1073,7 +1094,7 @@ function InvoicesList({ invoices, onInvoicesChange }) {
1073
1094
  __name(InvoicesList, "InvoicesList");
1074
1095
 
1075
1096
  // src/features/billing/stripe-invoice/components/containers/InvoicesContainer.tsx
1076
- import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
1097
+ import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1077
1098
  function InvoicesContainer() {
1078
1099
  const [invoices, setInvoices] = useState6([]);
1079
1100
  const [loading, setLoading] = useState6(true);
@@ -1097,99 +1118,40 @@ function InvoicesContainer() {
1097
1118
  const handleFilterChange = /* @__PURE__ */ __name((value) => {
1098
1119
  setStatusFilter(value);
1099
1120
  }, "handleFilterChange");
1100
- return /* @__PURE__ */ jsxs11("div", { className: "space-y-4", children: [
1101
- /* @__PURE__ */ jsx13(Tabs, { value: statusFilter, onValueChange: handleFilterChange, children: /* @__PURE__ */ jsxs11(TabsList, { children: [
1102
- /* @__PURE__ */ jsx13(TabsTrigger, { value: "all", children: "All" }),
1103
- /* @__PURE__ */ jsx13(TabsTrigger, { value: "paid" /* PAID */, children: "Paid" }),
1104
- /* @__PURE__ */ jsx13(TabsTrigger, { value: "open" /* OPEN */, children: "Open" }),
1105
- /* @__PURE__ */ jsx13(TabsTrigger, { value: "void" /* VOID */, children: "Void" }),
1106
- /* @__PURE__ */ jsx13(TabsTrigger, { value: "uncollectible" /* UNCOLLECTIBLE */, children: "Uncollectible" })
1121
+ return /* @__PURE__ */ jsxs12("div", { className: "space-y-4", children: [
1122
+ /* @__PURE__ */ jsx14(Tabs, { value: statusFilter, onValueChange: handleFilterChange, children: /* @__PURE__ */ jsxs12(TabsList, { children: [
1123
+ /* @__PURE__ */ jsx14(TabsTrigger, { value: "all", children: "All" }),
1124
+ /* @__PURE__ */ jsx14(TabsTrigger, { value: "paid" /* PAID */, children: "Paid" }),
1125
+ /* @__PURE__ */ jsx14(TabsTrigger, { value: "open" /* OPEN */, children: "Open" }),
1126
+ /* @__PURE__ */ jsx14(TabsTrigger, { value: "void" /* VOID */, children: "Void" }),
1127
+ /* @__PURE__ */ jsx14(TabsTrigger, { value: "uncollectible" /* UNCOLLECTIBLE */, children: "Uncollectible" })
1107
1128
  ] }) }),
1108
- loading && /* @__PURE__ */ jsx13("div", { className: "text-center py-8 text-muted-foreground", children: "Loading invoices..." }),
1109
- !loading && invoices.length === 0 && /* @__PURE__ */ jsxs11("div", { className: "border border-dashed border-gray-300 rounded-lg p-8 text-center", children: [
1110
- /* @__PURE__ */ jsx13("p", { className: "text-lg font-medium text-muted-foreground mb-2", children: "No invoices yet" }),
1111
- /* @__PURE__ */ jsx13("p", { className: "text-sm text-muted-foreground", children: "Invoices will appear here after your first billing cycle" })
1129
+ loading && /* @__PURE__ */ jsx14("div", { className: "text-center py-8 text-muted-foreground", children: "Loading invoices..." }),
1130
+ !loading && invoices.length === 0 && /* @__PURE__ */ jsxs12("div", { className: "border border-dashed border-gray-300 rounded-lg p-8 text-center", children: [
1131
+ /* @__PURE__ */ jsx14("p", { className: "text-lg font-medium text-muted-foreground mb-2", children: "No invoices yet" }),
1132
+ /* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: "Invoices will appear here after your first billing cycle" })
1112
1133
  ] }),
1113
- !loading && invoices.length > 0 && /* @__PURE__ */ jsx13(InvoicesList, { invoices, onInvoicesChange: loadInvoices })
1134
+ !loading && invoices.length > 0 && /* @__PURE__ */ jsx14(InvoicesList, { invoices, onInvoicesChange: loadInvoices })
1114
1135
  ] });
1115
1136
  }
1116
1137
  __name(InvoicesContainer, "InvoicesContainer");
1117
1138
 
1118
1139
  // src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx
1119
- import { CheckCircle as CheckCircle2, CreditCard as CreditCard3, Loader2 as Loader22 } from "lucide-react";
1120
- import { useEffect as useEffect6, useState as useState12 } from "react";
1121
- import { v4 as v42 } from "uuid";
1140
+ import { CreditCard as CreditCard3 } from "lucide-react";
1141
+ import { useCallback, useEffect as useEffect5, useState as useState10 } from "react";
1122
1142
 
1123
- // src/features/billing/stripe-subscription/hooks/useConfirmSubscriptionPayment.ts
1124
- import { useStripe as useStripe2 } from "@stripe/react-stripe-js";
1125
- import { useCallback, useState as useState7 } from "react";
1126
- function useConfirmSubscriptionPayment() {
1127
- const stripe = useStripe2();
1128
- const [isConfirming, setIsConfirming] = useState7(false);
1129
- const confirmPayment = useCallback(
1130
- async (clientSecret) => {
1131
- if (!stripe) {
1132
- console.error("[useConfirmSubscriptionPayment] Stripe not initialized");
1133
- return {
1134
- success: false,
1135
- error: "Payment system not initialized. Please refresh the page and try again."
1136
- };
1137
- }
1138
- if (!clientSecret) {
1139
- console.error("[useConfirmSubscriptionPayment] No client secret provided");
1140
- return {
1141
- success: false,
1142
- error: "Payment confirmation failed. Missing payment details."
1143
- };
1144
- }
1145
- setIsConfirming(true);
1146
- try {
1147
- const { error: stripeError, paymentIntent } = await stripe.confirmCardPayment(clientSecret);
1148
- if (stripeError) {
1149
- console.error("[useConfirmSubscriptionPayment] Stripe error:", stripeError);
1150
- return {
1151
- success: false,
1152
- error: stripeError.message || "Payment confirmation failed. Please try again."
1153
- };
1154
- }
1155
- if (paymentIntent?.status === "succeeded") {
1156
- return { success: true };
1157
- }
1158
- if (paymentIntent?.status === "requires_action") {
1159
- return {
1160
- success: false,
1161
- error: "Additional authentication required. Please complete the verification."
1162
- };
1163
- }
1164
- return {
1165
- success: false,
1166
- error: "Payment could not be completed. Please try again."
1167
- };
1168
- } catch (err) {
1169
- console.error("[useConfirmSubscriptionPayment] Unexpected error:", err);
1170
- return {
1171
- success: false,
1172
- error: err.message || "An unexpected error occurred during payment confirmation."
1173
- };
1174
- } finally {
1175
- setIsConfirming(false);
1176
- }
1177
- },
1178
- [stripe]
1179
- );
1180
- return {
1181
- confirmPayment,
1182
- isConfirming
1183
- };
1184
- }
1185
- __name(useConfirmSubscriptionPayment, "useConfirmSubscriptionPayment");
1143
+ // src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
1144
+ import { useState as useState9 } from "react";
1145
+
1146
+ // src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx
1147
+ import { useState as useState8 } from "react";
1186
1148
 
1187
1149
  // src/features/billing/stripe-subscription/components/forms/CancelSubscriptionDialog.tsx
1188
1150
  import { zodResolver } from "@hookform/resolvers/zod";
1189
- import { useState as useState8 } from "react";
1151
+ import { useState as useState7 } from "react";
1190
1152
  import { useForm } from "react-hook-form";
1191
1153
  import { z } from "zod";
1192
- import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
1154
+ import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1193
1155
  var formSchema = z.object({
1194
1156
  cancelImmediately: z.boolean(),
1195
1157
  reason: z.string().optional()
@@ -1200,7 +1162,7 @@ function CancelSubscriptionDialog({
1200
1162
  onOpenChange,
1201
1163
  onSuccess
1202
1164
  }) {
1203
- const [isSubmitting, setIsSubmitting] = useState8(false);
1165
+ const [isSubmitting, setIsSubmitting] = useState7(false);
1204
1166
  const form = useForm({
1205
1167
  resolver: zodResolver(formSchema),
1206
1168
  defaultValues: {
@@ -1225,19 +1187,19 @@ function CancelSubscriptionDialog({
1225
1187
  }
1226
1188
  }, "onSubmit");
1227
1189
  const periodEndDate = formatDate3(subscription.currentPeriodEnd);
1228
- return /* @__PURE__ */ jsx14(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs12(DialogContent, { className: "max-w-md", children: [
1229
- /* @__PURE__ */ jsxs12(DialogHeader, { children: [
1230
- /* @__PURE__ */ jsx14(DialogTitle, { children: "Cancel Subscription" }),
1231
- /* @__PURE__ */ jsx14(DialogDescription, { children: "Are you sure you want to cancel this subscription? This action cannot be undone." })
1190
+ return /* @__PURE__ */ jsx15(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs13(DialogContent, { className: "max-w-md", children: [
1191
+ /* @__PURE__ */ jsxs13(DialogHeader, { children: [
1192
+ /* @__PURE__ */ jsx15(DialogTitle, { children: "Cancel Subscription" }),
1193
+ /* @__PURE__ */ jsx15(DialogDescription, { children: "Are you sure you want to cancel this subscription? This action cannot be undone." })
1232
1194
  ] }),
1233
- /* @__PURE__ */ jsx14(Form, { ...form, children: /* @__PURE__ */ jsxs12("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
1234
- /* @__PURE__ */ jsx14(FormCheckbox, { form, id: "cancelImmediately", name: "Cancel Immediately" }),
1235
- cancelImmediately ? /* @__PURE__ */ jsx14("div", { className: "bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-800", children: "Your subscription will be canceled immediately and you will lose access right away." }) : /* @__PURE__ */ jsxs12("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 text-sm text-blue-800", children: [
1195
+ /* @__PURE__ */ jsx15(Form, { ...form, children: /* @__PURE__ */ jsxs13("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
1196
+ /* @__PURE__ */ jsx15(FormCheckbox, { form, id: "cancelImmediately", name: "Cancel Immediately" }),
1197
+ cancelImmediately ? /* @__PURE__ */ jsx15("div", { className: "bg-red-50 border border-red-200 rounded-lg p-3 text-sm text-red-800", children: "Your subscription will be canceled immediately and you will lose access right away." }) : /* @__PURE__ */ jsxs13("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 text-sm text-blue-800", children: [
1236
1198
  "Your subscription will remain active until ",
1237
1199
  periodEndDate,
1238
1200
  ". You can continue using the service until then."
1239
1201
  ] }),
1240
- /* @__PURE__ */ jsx14(
1202
+ /* @__PURE__ */ jsx15(
1241
1203
  FormTextarea,
1242
1204
  {
1243
1205
  form,
@@ -1247,407 +1209,17 @@ function CancelSubscriptionDialog({
1247
1209
  className: "min-h-24"
1248
1210
  }
1249
1211
  ),
1250
- /* @__PURE__ */ jsxs12("div", { className: "flex gap-x-2 justify-end pt-2", children: [
1251
- /* @__PURE__ */ jsx14(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isSubmitting, children: "Keep Subscription" }),
1252
- /* @__PURE__ */ jsx14(Button, { type: "submit", variant: "destructive", disabled: isSubmitting, children: isSubmitting ? "Canceling..." : "Confirm Cancellation" })
1212
+ /* @__PURE__ */ jsxs13("div", { className: "flex gap-x-2 justify-end pt-2", children: [
1213
+ /* @__PURE__ */ jsx15(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), disabled: isSubmitting, children: "Keep Subscription" }),
1214
+ /* @__PURE__ */ jsx15(Button, { type: "submit", variant: "destructive", disabled: isSubmitting, children: isSubmitting ? "Canceling..." : "Confirm Cancellation" })
1253
1215
  ] })
1254
1216
  ] }) })
1255
1217
  ] }) });
1256
1218
  }
1257
1219
  __name(CancelSubscriptionDialog, "CancelSubscriptionDialog");
1258
1220
 
1259
- // src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx
1260
- import { CheckCircle, Loader2 } from "lucide-react";
1261
- import { useEffect as useEffect5, useState as useState9 } from "react";
1262
- import { v4 } from "uuid";
1263
-
1264
- // src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx
1265
- import { Check } from "lucide-react";
1266
- import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
1267
- function PricingCard({ price, isCurrentPlan = false, isSelected = false, isDisabled = false, isLoading = false, onSelect }) {
1268
- const description = price.description || price.nickname || "Standard";
1269
- const features = price.features || [];
1270
- const formattedPrice = formatCurrency(price.unitAmount, price.currency);
1271
- const interval = formatInterval(price);
1272
- const handleKeyDown = /* @__PURE__ */ __name((e) => {
1273
- if ((e.key === "Enter" || e.key === " ") && !isDisabled && !isCurrentPlan) {
1274
- e.preventDefault();
1275
- onSelect(price);
1276
- }
1277
- }, "handleKeyDown");
1278
- const handleClick = /* @__PURE__ */ __name(() => {
1279
- if (!isDisabled && !isCurrentPlan && !isLoading) {
1280
- onSelect(price);
1281
- }
1282
- }, "handleClick");
1283
- return /* @__PURE__ */ jsxs13(
1284
- Card,
1285
- {
1286
- role: "radio",
1287
- "aria-checked": isSelected,
1288
- "aria-label": `${description} plan at ${formattedPrice} ${interval}`,
1289
- tabIndex: isDisabled ? -1 : 0,
1290
- onKeyDown: handleKeyDown,
1291
- onClick: handleClick,
1292
- className: cn(
1293
- "relative cursor-pointer transition-all duration-200 flex flex-col h-full",
1294
- "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
1295
- isCurrentPlan && "bg-muted/30",
1296
- isSelected && !isCurrentPlan && "ring-2 ring-primary",
1297
- !isDisabled && !isCurrentPlan && "hover:shadow-md hover:border-primary/50",
1298
- isDisabled && "opacity-50 pointer-events-none",
1299
- isLoading && "pointer-events-none"
1300
- ),
1301
- children: [
1302
- isCurrentPlan && /* @__PURE__ */ jsx15(Badge, { variant: "secondary", className: "absolute top-2 right-2", children: "Current" }),
1303
- /* @__PURE__ */ jsx15(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx15("h3", { className: "font-semibold text-lg", children: description }) }),
1304
- /* @__PURE__ */ jsxs13(CardContent, { className: "pb-4 grow", children: [
1305
- /* @__PURE__ */ jsxs13("div", { className: "mb-4", children: [
1306
- /* @__PURE__ */ jsx15("span", { className: "text-3xl font-bold", children: formattedPrice }),
1307
- /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground ml-1", children: interval })
1308
- ] }),
1309
- features.length > 0 && /* @__PURE__ */ jsx15("ul", { className: "space-y-2", children: features.map((feature, index) => /* @__PURE__ */ jsxs13("li", { className: "flex items-start gap-2", children: [
1310
- /* @__PURE__ */ jsx15(Check, { className: "h-4 w-4 text-green-500 mt-0.5 shrink-0" }),
1311
- /* @__PURE__ */ jsx15("span", { className: "text-sm text-muted-foreground", children: feature })
1312
- ] }, index)) })
1313
- ] }),
1314
- /* @__PURE__ */ jsx15(CardFooter, { children: /* @__PURE__ */ jsx15(
1315
- Button,
1316
- {
1317
- variant: isCurrentPlan ? "secondary" : isSelected ? "default" : "outline",
1318
- className: "w-full",
1319
- disabled: isDisabled || isCurrentPlan || isLoading,
1320
- children: isLoading ? "Processing..." : isCurrentPlan ? "Current Plan" : isSelected ? "Selected" : "Select Plan"
1321
- }
1322
- ) })
1323
- ]
1324
- }
1325
- );
1326
- }
1327
- __name(PricingCard, "PricingCard");
1328
-
1329
- // src/features/billing/stripe-subscription/components/widgets/PricingCardsGrid.tsx
1330
- import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
1331
- function PricingCardsGrid({
1332
- products,
1333
- pricesByProduct,
1334
- currentPriceId,
1335
- selectedPriceId,
1336
- loadingPriceId,
1337
- loading = false,
1338
- onSelectPrice
1339
- }) {
1340
- if (loading) {
1341
- return /* @__PURE__ */ jsx16(PricingCardsGridSkeleton, {});
1342
- }
1343
- if (products.length === 0) {
1344
- return /* @__PURE__ */ jsx16("div", { className: "text-center py-8 text-muted-foreground", children: "No plans available" });
1345
- }
1346
- return /* @__PURE__ */ jsx16("div", { className: "space-y-8", role: "radiogroup", "aria-label": "Available pricing plans", children: products.map((product) => {
1347
- const prices = pricesByProduct.get(product.id) || [];
1348
- if (prices.length === 0) return null;
1349
- const sortedPrices = [...prices].sort((a, b) => (a.unitAmount ?? 0) - (b.unitAmount ?? 0));
1350
- return /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
1351
- /* @__PURE__ */ jsx16("h3", { className: "text-lg font-semibold", children: product.name }),
1352
- /* @__PURE__ */ jsx16("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: sortedPrices.map((price) => /* @__PURE__ */ jsx16(
1353
- PricingCard,
1354
- {
1355
- price,
1356
- isCurrentPlan: price.stripePriceId === currentPriceId,
1357
- isSelected: price.stripePriceId === selectedPriceId,
1358
- isLoading: price.stripePriceId === loadingPriceId,
1359
- onSelect: onSelectPrice
1360
- },
1361
- price.stripePriceId
1362
- )) })
1363
- ] }, product.id);
1364
- }) });
1365
- }
1366
- __name(PricingCardsGrid, "PricingCardsGrid");
1367
- function PricingCardsGridSkeleton() {
1368
- return /* @__PURE__ */ jsx16("div", { className: "space-y-8", children: [1, 2].map((productIndex) => /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
1369
- /* @__PURE__ */ jsx16(Skeleton, { className: "h-6 w-32" }),
1370
- /* @__PURE__ */ jsx16("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: [1, 2, 3].map((cardIndex) => /* @__PURE__ */ jsxs14(Card, { className: "animate-pulse", children: [
1371
- /* @__PURE__ */ jsx16(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx16(Skeleton, { className: "h-5 w-24" }) }),
1372
- /* @__PURE__ */ jsxs14(CardContent, { className: "pb-4", children: [
1373
- /* @__PURE__ */ jsxs14("div", { className: "mb-4", children: [
1374
- /* @__PURE__ */ jsx16(Skeleton, { className: "h-9 w-20 inline-block" }),
1375
- /* @__PURE__ */ jsx16(Skeleton, { className: "h-4 w-12 inline-block ml-2" })
1376
- ] }),
1377
- /* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
1378
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
1379
- /* @__PURE__ */ jsx16(Skeleton, { className: "h-4 w-4 rounded-full" }),
1380
- /* @__PURE__ */ jsx16(Skeleton, { className: "h-4 w-32" })
1381
- ] }),
1382
- /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
1383
- /* @__PURE__ */ jsx16(Skeleton, { className: "h-4 w-4 rounded-full" }),
1384
- /* @__PURE__ */ jsx16(Skeleton, { className: "h-4 w-28" })
1385
- ] })
1386
- ] })
1387
- ] }),
1388
- /* @__PURE__ */ jsx16(CardFooter, { children: /* @__PURE__ */ jsx16(Skeleton, { className: "h-9 w-full" }) })
1389
- ] }, cardIndex)) })
1390
- ] }, productIndex)) });
1391
- }
1392
- __name(PricingCardsGridSkeleton, "PricingCardsGridSkeleton");
1393
-
1394
- // src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx
1395
- import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
1396
- function ProrationPreview({ preview }) {
1397
- return /* @__PURE__ */ jsxs15("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4", children: [
1398
- /* @__PURE__ */ jsx17("h4", { className: "font-semibold text-blue-900 mb-3", children: "Proration Breakdown" }),
1399
- /* @__PURE__ */ jsxs15("div", { className: "space-y-2", children: [
1400
- preview.lineItems.map((item, index) => /* @__PURE__ */ jsxs15("div", { className: "flex justify-between text-sm", children: [
1401
- /* @__PURE__ */ jsx17("span", { className: "text-blue-800", children: item.description }),
1402
- /* @__PURE__ */ jsx17("span", { className: `font-medium ${item.amount < 0 ? "text-green-600" : "text-blue-900"}`, children: formatCurrency(item.amount, preview.currency) })
1403
- ] }, index)),
1404
- /* @__PURE__ */ jsx17("div", { className: "border-t border-blue-200 pt-2 mt-2", children: /* @__PURE__ */ jsxs15("div", { className: "flex justify-between font-semibold", children: [
1405
- /* @__PURE__ */ jsx17("span", { className: "text-blue-900", children: "Net Due Today" }),
1406
- /* @__PURE__ */ jsx17("span", { className: "text-blue-900", children: formatCurrency(preview.immediateCharge, preview.currency) })
1407
- ] }) }),
1408
- preview.lineItems.length > 0 && preview.lineItems[0].period && /* @__PURE__ */ jsxs15("div", { className: "text-xs text-blue-700 mt-2", children: [
1409
- "Next invoice on ",
1410
- formatDate3(preview.lineItems[0].period.end),
1411
- " for",
1412
- " ",
1413
- formatCurrency(preview.amountDue, preview.currency)
1414
- ] })
1415
- ] })
1416
- ] });
1417
- }
1418
- __name(ProrationPreview, "ProrationPreview");
1419
-
1420
- // src/features/billing/stripe-subscription/components/forms/SubscriptionEditor.tsx
1421
- import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
1422
- function SubscriptionEditor({
1423
- subscription,
1424
- open,
1425
- onOpenChange,
1426
- onSuccess,
1427
- onAddPaymentMethod
1428
- }) {
1429
- const { confirmPayment, isConfirming } = useConfirmSubscriptionPayment();
1430
- const [products, setProducts] = useState9([]);
1431
- const [pricesByProduct, setPricesByProduct] = useState9(/* @__PURE__ */ new Map());
1432
- const [loading, setLoading] = useState9(true);
1433
- const [selectedPriceId, setSelectedPriceId] = useState9(null);
1434
- const [loadingPriceId, setLoadingPriceId] = useState9(null);
1435
- const [prorationPreview, setProrationPreview] = useState9(null);
1436
- const [loadingProration, setLoadingProration] = useState9(false);
1437
- const [hasPaymentMethod, setHasPaymentMethod] = useState9(true);
1438
- const [loadingPaymentMethods, setLoadingPaymentMethods] = useState9(true);
1439
- const [paymentRequiredError, setPaymentRequiredError] = useState9(false);
1440
- const [paymentConfirmationState, setPaymentConfirmationState] = useState9("idle");
1441
- const [paymentError, setPaymentError] = useState9(null);
1442
- const currentPriceId = subscription?.price?.id;
1443
- const isEditMode = !!subscription;
1444
- useEffect5(() => {
1445
- const checkPaymentMethods = /* @__PURE__ */ __name(async () => {
1446
- if (subscription) {
1447
- setLoadingPaymentMethods(false);
1448
- return;
1449
- }
1450
- setLoadingPaymentMethods(true);
1451
- try {
1452
- const paymentMethods = await StripeCustomerService.listPaymentMethods();
1453
- const hasMethod = paymentMethods.length > 0;
1454
- setHasPaymentMethod(hasMethod);
1455
- } catch (error) {
1456
- console.error("[SubscriptionEditor] Failed to check payment methods:", error);
1457
- setHasPaymentMethod(false);
1458
- } finally {
1459
- setLoadingPaymentMethods(false);
1460
- }
1461
- }, "checkPaymentMethods");
1462
- if (open) {
1463
- checkPaymentMethods();
1464
- }
1465
- }, [open, subscription]);
1466
- useEffect5(() => {
1467
- const loadData = /* @__PURE__ */ __name(async () => {
1468
- setLoading(true);
1469
- try {
1470
- const fetchedProducts = await StripeProductService.listProducts({ active: true });
1471
- const grouped = /* @__PURE__ */ new Map();
1472
- for (const product of fetchedProducts) {
1473
- if (product.stripePrices && product.stripePrices.length > 0) {
1474
- grouped.set(product.id, product.stripePrices);
1475
- }
1476
- }
1477
- setProducts(fetchedProducts);
1478
- setPricesByProduct(grouped);
1479
- } catch (error) {
1480
- console.error("[SubscriptionEditor] Failed to load products/prices:", error);
1481
- } finally {
1482
- setLoading(false);
1483
- }
1484
- }, "loadData");
1485
- if (open) {
1486
- loadData();
1487
- }
1488
- }, [open]);
1489
- useEffect5(() => {
1490
- const loadProration = /* @__PURE__ */ __name(async () => {
1491
- if (!subscription || !selectedPriceId || selectedPriceId === currentPriceId) {
1492
- setProrationPreview(null);
1493
- return;
1494
- }
1495
- setLoadingProration(true);
1496
- try {
1497
- const preview = await StripeSubscriptionService.getProrationPreview({
1498
- subscriptionId: subscription.id,
1499
- newPriceId: selectedPriceId
1500
- });
1501
- setProrationPreview(preview);
1502
- } catch (error) {
1503
- console.error("[SubscriptionEditor] Failed to load proration preview:", error);
1504
- setProrationPreview(null);
1505
- } finally {
1506
- setLoadingProration(false);
1507
- }
1508
- }, "loadProration");
1509
- loadProration();
1510
- }, [selectedPriceId, subscription, currentPriceId]);
1511
- const handleSelectPrice = /* @__PURE__ */ __name(async (price) => {
1512
- const priceId = price.id;
1513
- if (isEditMode) {
1514
- setSelectedPriceId(priceId);
1515
- } else {
1516
- setLoadingPriceId(priceId);
1517
- setSelectedPriceId(priceId);
1518
- setPaymentError(null);
1519
- setPaymentConfirmationState("idle");
1520
- try {
1521
- const result = await StripeSubscriptionService.createSubscription({
1522
- id: v4(),
1523
- priceId
1524
- });
1525
- if (result.meta.requiresAction && result.meta.clientSecret) {
1526
- setPaymentConfirmationState("confirming");
1527
- const confirmation = await confirmPayment(result.meta.clientSecret);
1528
- if (!confirmation.success) {
1529
- console.error("[SubscriptionEditor] Payment confirmation failed:", confirmation.error);
1530
- setPaymentConfirmationState("error");
1531
- setPaymentError(confirmation.error || "Payment confirmation failed");
1532
- setLoadingPriceId(null);
1533
- return;
1534
- }
1535
- await StripeSubscriptionService.syncSubscription({
1536
- subscriptionId: result.subscription.id
1537
- });
1538
- }
1539
- setPaymentConfirmationState("success");
1540
- setTimeout(() => {
1541
- onSuccess();
1542
- onOpenChange(false);
1543
- }, 1e3);
1544
- } catch (error) {
1545
- console.error("[SubscriptionEditor] Failed to create subscription:", error);
1546
- if (error?.status === 402 || error?.response?.status === 402) {
1547
- setPaymentRequiredError(true);
1548
- setHasPaymentMethod(false);
1549
- } else {
1550
- setPaymentConfirmationState("error");
1551
- setPaymentError(error?.message || "Failed to create subscription");
1552
- }
1553
- setLoadingPriceId(null);
1554
- }
1555
- }
1556
- }, "handleSelectPrice");
1557
- const handleConfirmPlanChange = /* @__PURE__ */ __name(async () => {
1558
- if (!subscription || !selectedPriceId) return;
1559
- setLoadingPriceId(selectedPriceId);
1560
- try {
1561
- await StripeSubscriptionService.changePlan({
1562
- id: subscription.id,
1563
- newPriceId: selectedPriceId
1564
- });
1565
- onSuccess();
1566
- onOpenChange(false);
1567
- } catch (error) {
1568
- console.error("[SubscriptionEditor] Failed to change plan:", error);
1569
- } finally {
1570
- setLoadingPriceId(null);
1571
- }
1572
- }, "handleConfirmPlanChange");
1573
- const handleCancel = /* @__PURE__ */ __name(() => {
1574
- setSelectedPriceId(null);
1575
- setProrationPreview(null);
1576
- }, "handleCancel");
1577
- return /* @__PURE__ */ jsx18(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs16(DialogContent, { className: "max-w-4xl max-h-[90vh] overflow-y-auto", children: [
1578
- /* @__PURE__ */ jsxs16(DialogHeader, { children: [
1579
- /* @__PURE__ */ jsx18(DialogTitle, { children: subscription ? "Change Plan" : "Subscribe to a Plan" }),
1580
- /* @__PURE__ */ jsx18(DialogDescription, { children: subscription ? "Select a new plan to switch to. You'll see a proration preview before confirming." : "Choose a plan to start your subscription." })
1581
- ] }),
1582
- loadingPaymentMethods && !subscription ? /* @__PURE__ */ jsx18("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx18("div", { className: "text-muted-foreground", children: "Checking payment methods..." }) }) : !hasPaymentMethod && !subscription ? /* @__PURE__ */ jsxs16(Alert, { variant: "destructive", children: [
1583
- /* @__PURE__ */ jsx18(AlertTitle, { children: "Payment Method Required" }),
1584
- /* @__PURE__ */ jsxs16(AlertDescription, { className: "mt-2", children: [
1585
- /* @__PURE__ */ jsx18("p", { className: "mb-4", children: paymentRequiredError ? "Your subscription could not be created because no payment method is on file." : "You need to add a payment method before you can subscribe to a plan." }),
1586
- onAddPaymentMethod && /* @__PURE__ */ jsx18(Button, { onClick: onAddPaymentMethod, variant: "outline", children: "Add Payment Method" })
1587
- ] })
1588
- ] }) : paymentConfirmationState === "confirming" || isConfirming ? /* @__PURE__ */ jsxs16("div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
1589
- /* @__PURE__ */ jsx18(Loader2, { className: "h-8 w-8 animate-spin text-primary" }),
1590
- /* @__PURE__ */ jsxs16("div", { className: "text-center", children: [
1591
- /* @__PURE__ */ jsx18("p", { className: "font-medium", children: "Processing payment..." }),
1592
- /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: "Please complete any verification if prompted." })
1593
- ] })
1594
- ] }) : paymentConfirmationState === "success" ? /* @__PURE__ */ jsxs16("div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
1595
- /* @__PURE__ */ jsx18(CheckCircle, { className: "h-12 w-12 text-green-500" }),
1596
- /* @__PURE__ */ jsxs16("div", { className: "text-center", children: [
1597
- /* @__PURE__ */ jsx18("p", { className: "font-medium text-green-600", children: "Payment successful!" }),
1598
- /* @__PURE__ */ jsx18("p", { className: "text-sm text-muted-foreground", children: "Your subscription is now active." })
1599
- ] })
1600
- ] }) : paymentConfirmationState === "error" ? /* @__PURE__ */ jsx18("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs16(Alert, { variant: "destructive", children: [
1601
- /* @__PURE__ */ jsx18(AlertTitle, { children: "Payment Failed" }),
1602
- /* @__PURE__ */ jsxs16(AlertDescription, { className: "mt-2", children: [
1603
- /* @__PURE__ */ jsx18("p", { className: "mb-4", children: paymentError || "We couldn't process your payment. Please try again." }),
1604
- /* @__PURE__ */ jsx18(
1605
- Button,
1606
- {
1607
- onClick: () => {
1608
- setPaymentConfirmationState("idle");
1609
- setPaymentError(null);
1610
- setLoadingPriceId(null);
1611
- },
1612
- variant: "outline",
1613
- children: "Try Again"
1614
- }
1615
- )
1616
- ] })
1617
- ] }) }) : /* @__PURE__ */ jsxs16("div", { className: "space-y-6", children: [
1618
- /* @__PURE__ */ jsx18(
1619
- PricingCardsGrid,
1620
- {
1621
- products,
1622
- pricesByProduct,
1623
- currentPriceId,
1624
- selectedPriceId: selectedPriceId ?? void 0,
1625
- loadingPriceId: loadingPriceId ?? void 0,
1626
- loading,
1627
- onSelectPrice: handleSelectPrice
1628
- }
1629
- ),
1630
- isEditMode && loadingProration && /* @__PURE__ */ jsx18("div", { className: "bg-muted/50 rounded-lg p-4 text-sm text-muted-foreground text-center", children: "Loading proration preview..." }),
1631
- isEditMode && prorationPreview && !loadingProration && /* @__PURE__ */ jsxs16("div", { className: "space-y-4", children: [
1632
- /* @__PURE__ */ jsx18(ProrationPreview, { preview: prorationPreview }),
1633
- /* @__PURE__ */ jsxs16("div", { className: "flex justify-end gap-3", children: [
1634
- /* @__PURE__ */ jsx18(Button, { variant: "outline", onClick: handleCancel, disabled: !!loadingPriceId, children: "Cancel" }),
1635
- /* @__PURE__ */ jsx18(Button, { onClick: handleConfirmPlanChange, disabled: !!loadingPriceId, children: loadingPriceId ? "Processing..." : "Confirm Plan Change" })
1636
- ] })
1637
- ] })
1638
- ] })
1639
- ] }) });
1640
- }
1641
- __name(SubscriptionEditor, "SubscriptionEditor");
1642
-
1643
- // src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
1644
- import { useState as useState11 } from "react";
1645
-
1646
- // src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx
1647
- import { useState as useState10 } from "react";
1648
-
1649
1221
  // src/features/billing/stripe-subscription/components/widgets/SubscriptionStatusBadge.tsx
1650
- import { jsx as jsx19 } from "react/jsx-runtime";
1222
+ import { jsx as jsx16 } from "react/jsx-runtime";
1651
1223
  var statusConfig2 = {
1652
1224
  ["active" /* ACTIVE */]: {
1653
1225
  label: "Active",
@@ -1688,12 +1260,12 @@ var cancelingConfig = {
1688
1260
  };
1689
1261
  function SubscriptionStatusBadge({ status, cancelAtPeriodEnd }) {
1690
1262
  const config = cancelAtPeriodEnd ? cancelingConfig : statusConfig2[status] || statusConfig2["canceled" /* CANCELED */];
1691
- return /* @__PURE__ */ jsx19("span", { className: `${config.color} text-xs px-2 py-1 rounded-full font-medium`, children: config.label });
1263
+ return /* @__PURE__ */ jsx16("span", { className: `${config.color} text-xs px-2 py-1 rounded-full font-medium`, children: config.label });
1692
1264
  }
1693
1265
  __name(SubscriptionStatusBadge, "SubscriptionStatusBadge");
1694
1266
 
1695
1267
  // src/features/billing/stripe-subscription/components/details/SubscriptionDetails.tsx
1696
- import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
1268
+ import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs14 } from "react/jsx-runtime";
1697
1269
  function formatPlanName2(price) {
1698
1270
  if (!price) return "N/A";
1699
1271
  const productName = price.product?.name || "";
@@ -1722,11 +1294,11 @@ function SubscriptionDetails({
1722
1294
  subscription,
1723
1295
  open,
1724
1296
  onOpenChange,
1725
- onSubscriptionChange
1297
+ onSubscriptionChange,
1298
+ onChangePlan
1726
1299
  }) {
1727
- const [showEdit, setShowEdit] = useState10(false);
1728
- const [showCancel, setShowCancel] = useState10(false);
1729
- const [isProcessing, setIsProcessing] = useState10(false);
1300
+ const [showCancel, setShowCancel] = useState8(false);
1301
+ const [isProcessing, setIsProcessing] = useState8(false);
1730
1302
  const handlePause = /* @__PURE__ */ __name(async () => {
1731
1303
  setIsProcessing(true);
1732
1304
  try {
@@ -1760,67 +1332,55 @@ function SubscriptionDetails({
1760
1332
  const canPause = subscription.status === "active" /* ACTIVE */;
1761
1333
  const canResume = subscription.status === "paused" /* PAUSED */;
1762
1334
  const canCancel = subscription.status === "active" /* ACTIVE */ || subscription.status === "trialing" /* TRIALING */ || subscription.status === "paused" /* PAUSED */;
1763
- return /* @__PURE__ */ jsxs17(Fragment3, { children: [
1764
- /* @__PURE__ */ jsx20(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs17(DialogContent, { className: "max-w-2xl", children: [
1765
- /* @__PURE__ */ jsxs17(DialogHeader, { children: [
1766
- /* @__PURE__ */ jsx20(DialogTitle, { children: "Subscription Details" }),
1767
- /* @__PURE__ */ jsx20(DialogDescription, { children: "View and manage your subscription" })
1335
+ return /* @__PURE__ */ jsxs14(Fragment3, { children: [
1336
+ /* @__PURE__ */ jsx17(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs14(DialogContent, { className: "max-w-2xl", children: [
1337
+ /* @__PURE__ */ jsxs14(DialogHeader, { children: [
1338
+ /* @__PURE__ */ jsx17(DialogTitle, { children: "Subscription Details" }),
1339
+ /* @__PURE__ */ jsx17(DialogDescription, { children: "View and manage your subscription" })
1768
1340
  ] }),
1769
- /* @__PURE__ */ jsxs17("div", { className: "space-y-6", children: [
1770
- /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-x-3", children: [
1771
- /* @__PURE__ */ jsx20("span", { className: "text-sm font-medium text-muted-foreground", children: "Status:" }),
1772
- /* @__PURE__ */ jsx20(SubscriptionStatusBadge, { status: subscription.status, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd })
1341
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-6", children: [
1342
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-x-3", children: [
1343
+ /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium text-muted-foreground", children: "Status:" }),
1344
+ /* @__PURE__ */ jsx17(SubscriptionStatusBadge, { status: subscription.status, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd })
1773
1345
  ] }),
1774
- /* @__PURE__ */ jsxs17("div", { className: "space-y-2", children: [
1775
- /* @__PURE__ */ jsxs17("div", { className: "flex justify-between", children: [
1776
- /* @__PURE__ */ jsx20("span", { className: "text-sm font-medium text-muted-foreground", children: "Plan:" }),
1777
- /* @__PURE__ */ jsx20("span", { className: "font-medium", children: formatPlanName2(subscription.price) })
1346
+ /* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
1347
+ /* @__PURE__ */ jsxs14("div", { className: "flex justify-between", children: [
1348
+ /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium text-muted-foreground", children: "Plan:" }),
1349
+ /* @__PURE__ */ jsx17("span", { className: "font-medium", children: formatPlanName2(subscription.price) })
1778
1350
  ] }),
1779
- /* @__PURE__ */ jsxs17("div", { className: "flex justify-between", children: [
1780
- /* @__PURE__ */ jsx20("span", { className: "text-sm font-medium text-muted-foreground", children: "Billing Amount:" }),
1781
- /* @__PURE__ */ jsx20("span", { className: "font-medium", children: formatBillingAmount(subscription.price) })
1351
+ /* @__PURE__ */ jsxs14("div", { className: "flex justify-between", children: [
1352
+ /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium text-muted-foreground", children: "Billing Amount:" }),
1353
+ /* @__PURE__ */ jsx17("span", { className: "font-medium", children: formatBillingAmount(subscription.price) })
1782
1354
  ] })
1783
1355
  ] }),
1784
- /* @__PURE__ */ jsx20("div", { className: "space-y-2", children: /* @__PURE__ */ jsxs17("div", { className: "flex justify-between", children: [
1785
- /* @__PURE__ */ jsx20("span", { className: "text-sm font-medium text-muted-foreground", children: "Current Period:" }),
1786
- /* @__PURE__ */ jsxs17("span", { className: "font-medium", children: [
1356
+ /* @__PURE__ */ jsx17("div", { className: "space-y-2", children: /* @__PURE__ */ jsxs14("div", { className: "flex justify-between", children: [
1357
+ /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium text-muted-foreground", children: "Current Period:" }),
1358
+ /* @__PURE__ */ jsxs14("span", { className: "font-medium", children: [
1787
1359
  formatDate3(subscription.currentPeriodStart),
1788
1360
  " - ",
1789
1361
  formatDate3(subscription.currentPeriodEnd)
1790
1362
  ] })
1791
1363
  ] }) }),
1792
- subscription.trialEnd && /* @__PURE__ */ jsxs17("div", { className: "flex justify-between", children: [
1793
- /* @__PURE__ */ jsx20("span", { className: "text-sm font-medium text-muted-foreground", children: "Trial Ends:" }),
1794
- /* @__PURE__ */ jsx20("span", { className: "font-medium", children: formatDate3(subscription.trialEnd) })
1364
+ subscription.trialEnd && /* @__PURE__ */ jsxs14("div", { className: "flex justify-between", children: [
1365
+ /* @__PURE__ */ jsx17("span", { className: "text-sm font-medium text-muted-foreground", children: "Trial Ends:" }),
1366
+ /* @__PURE__ */ jsx17("span", { className: "font-medium", children: formatDate3(subscription.trialEnd) })
1795
1367
  ] }),
1796
- subscription.cancelAtPeriodEnd && /* @__PURE__ */ jsx20("div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-3", children: /* @__PURE__ */ jsxs17("p", { className: "text-sm text-yellow-800", children: [
1368
+ subscription.cancelAtPeriodEnd && /* @__PURE__ */ jsx17("div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-3", children: /* @__PURE__ */ jsxs14("p", { className: "text-sm text-yellow-800", children: [
1797
1369
  "This subscription will be canceled at the end of the current period on",
1798
1370
  " ",
1799
1371
  formatDate3(subscription.currentPeriodEnd),
1800
1372
  "."
1801
1373
  ] }) }),
1802
- /* @__PURE__ */ jsxs17("div", { className: "flex flex-wrap gap-2 pt-4 border-t", children: [
1803
- /* @__PURE__ */ jsx20(Button, { variant: "default", onClick: () => setShowEdit(true), children: "Change Plan" }),
1804
- canPause && /* @__PURE__ */ jsx20(Button, { variant: "outline", onClick: handlePause, disabled: isProcessing, children: isProcessing ? "Pausing..." : "Pause" }),
1805
- canResume && /* @__PURE__ */ jsx20(Button, { variant: "outline", onClick: handleResume, disabled: isProcessing, children: isProcessing ? "Resuming..." : "Resume" }),
1806
- canCancel && /* @__PURE__ */ jsx20(Button, { variant: "destructive", onClick: () => setShowCancel(true), children: "Cancel" }),
1807
- /* @__PURE__ */ jsx20(Button, { variant: "outline", onClick: handleManageViaPortal, children: "Manage via Portal" })
1374
+ /* @__PURE__ */ jsxs14("div", { className: "flex flex-wrap gap-2 pt-4 border-t", children: [
1375
+ onChangePlan && /* @__PURE__ */ jsx17(Button, { variant: "default", onClick: () => onChangePlan(subscription), children: "Change Plan" }),
1376
+ canPause && /* @__PURE__ */ jsx17(Button, { variant: "outline", onClick: handlePause, disabled: isProcessing, children: isProcessing ? "Pausing..." : "Pause" }),
1377
+ canResume && /* @__PURE__ */ jsx17(Button, { variant: "outline", onClick: handleResume, disabled: isProcessing, children: isProcessing ? "Resuming..." : "Resume" }),
1378
+ canCancel && /* @__PURE__ */ jsx17(Button, { variant: "destructive", onClick: () => setShowCancel(true), children: "Cancel" }),
1379
+ /* @__PURE__ */ jsx17(Button, { variant: "outline", onClick: handleManageViaPortal, children: "Manage via Portal" })
1808
1380
  ] })
1809
1381
  ] })
1810
1382
  ] }) }),
1811
- showEdit && /* @__PURE__ */ jsx20(
1812
- SubscriptionEditor,
1813
- {
1814
- subscription,
1815
- open: showEdit,
1816
- onOpenChange: setShowEdit,
1817
- onSuccess: () => {
1818
- onSubscriptionChange();
1819
- setShowEdit(false);
1820
- }
1821
- }
1822
- ),
1823
- showCancel && /* @__PURE__ */ jsx20(
1383
+ showCancel && /* @__PURE__ */ jsx17(
1824
1384
  CancelSubscriptionDialog,
1825
1385
  {
1826
1386
  subscription,
@@ -1837,7 +1397,7 @@ function SubscriptionDetails({
1837
1397
  __name(SubscriptionDetails, "SubscriptionDetails");
1838
1398
 
1839
1399
  // src/features/billing/stripe-subscription/components/lists/SubscriptionsList.tsx
1840
- import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
1400
+ import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
1841
1401
  function formatPlanName3(price) {
1842
1402
  if (!price) return "N/A";
1843
1403
  const productName = price.product?.name || "";
@@ -1857,277 +1417,826 @@ function formatPlanName3(price) {
1857
1417
  return interval ? `${planLabel} (${interval})` : planLabel || "N/A";
1858
1418
  }
1859
1419
  __name(formatPlanName3, "formatPlanName");
1860
- function SubscriptionsList({ subscriptions, onSubscriptionsChange }) {
1861
- const [selectedSub, setSelectedSub] = useState11(null);
1420
+ function SubscriptionsList({ subscriptions, onSubscriptionsChange, onChangePlan }) {
1421
+ const [selectedSub, setSelectedSub] = useState9(null);
1862
1422
  const handleRowClick = /* @__PURE__ */ __name((subscription) => {
1863
1423
  setSelectedSub(subscription);
1864
1424
  }, "handleRowClick");
1865
- return /* @__PURE__ */ jsxs18(Fragment4, { children: [
1866
- /* @__PURE__ */ jsx21("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs18(Table, { children: [
1867
- /* @__PURE__ */ jsx21(TableHeader, { className: "bg-muted", children: /* @__PURE__ */ jsxs18(TableRow, { children: [
1868
- /* @__PURE__ */ jsx21(TableHead, { children: "Status" }),
1869
- /* @__PURE__ */ jsx21(TableHead, { children: "Plan" }),
1870
- /* @__PURE__ */ jsx21(TableHead, { children: "Period" }),
1871
- /* @__PURE__ */ jsx21(TableHead, { className: "text-right", children: "Amount" })
1425
+ return /* @__PURE__ */ jsxs15(Fragment4, { children: [
1426
+ /* @__PURE__ */ jsx18("div", { className: "border rounded-lg overflow-hidden", children: /* @__PURE__ */ jsxs15(Table, { children: [
1427
+ /* @__PURE__ */ jsx18(TableHeader, { className: "bg-muted", children: /* @__PURE__ */ jsxs15(TableRow, { children: [
1428
+ /* @__PURE__ */ jsx18(TableHead, { children: "Status" }),
1429
+ /* @__PURE__ */ jsx18(TableHead, { children: "Plan" }),
1430
+ /* @__PURE__ */ jsx18(TableHead, { children: "Period" }),
1431
+ /* @__PURE__ */ jsx18(TableHead, { className: "text-right", children: "Amount" })
1872
1432
  ] }) }),
1873
- /* @__PURE__ */ jsx21(TableBody, { children: subscriptions.map((subscription) => {
1433
+ /* @__PURE__ */ jsx18(TableBody, { children: subscriptions.map((subscription) => {
1874
1434
  const price = subscription.price;
1875
1435
  const amount = price?.unitAmount ? formatCurrency(price.unitAmount, price.currency) : "N/A";
1876
1436
  const period = `${formatDate3(subscription.currentPeriodStart)} - ${formatDate3(subscription.currentPeriodEnd)}`;
1877
- return /* @__PURE__ */ jsxs18(
1437
+ return /* @__PURE__ */ jsxs15(
1878
1438
  TableRow,
1879
1439
  {
1880
- onClick: () => handleRowClick(subscription),
1881
- className: "cursor-pointer hover:bg-muted/50",
1882
- children: [
1883
- /* @__PURE__ */ jsx21(TableCell, { children: /* @__PURE__ */ jsx21(SubscriptionStatusBadge, { status: subscription.status, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd }) }),
1884
- /* @__PURE__ */ jsx21(TableCell, { className: "font-medium", children: formatPlanName3(price) }),
1885
- /* @__PURE__ */ jsx21(TableCell, { className: "text-muted-foreground text-sm", children: period }),
1886
- /* @__PURE__ */ jsx21(TableCell, { className: "text-right font-medium", children: amount })
1887
- ]
1440
+ onClick: () => handleRowClick(subscription),
1441
+ className: "cursor-pointer hover:bg-muted/50",
1442
+ children: [
1443
+ /* @__PURE__ */ jsx18(TableCell, { children: /* @__PURE__ */ jsx18(SubscriptionStatusBadge, { status: subscription.status, cancelAtPeriodEnd: subscription.cancelAtPeriodEnd }) }),
1444
+ /* @__PURE__ */ jsx18(TableCell, { className: "font-medium", children: formatPlanName3(price) }),
1445
+ /* @__PURE__ */ jsx18(TableCell, { className: "text-muted-foreground text-sm", children: period }),
1446
+ /* @__PURE__ */ jsx18(TableCell, { className: "text-right font-medium", children: amount })
1447
+ ]
1448
+ },
1449
+ subscription.id
1450
+ );
1451
+ }) })
1452
+ ] }) }),
1453
+ selectedSub && /* @__PURE__ */ jsx18(
1454
+ SubscriptionDetails,
1455
+ {
1456
+ subscription: selectedSub,
1457
+ open: !!selectedSub,
1458
+ onOpenChange: (open) => !open && setSelectedSub(null),
1459
+ onSubscriptionChange: () => {
1460
+ onSubscriptionsChange();
1461
+ setSelectedSub(null);
1462
+ },
1463
+ onChangePlan: onChangePlan ? (sub) => {
1464
+ setSelectedSub(null);
1465
+ onChangePlan(sub);
1466
+ } : void 0
1467
+ }
1468
+ )
1469
+ ] });
1470
+ }
1471
+ __name(SubscriptionsList, "SubscriptionsList");
1472
+
1473
+ // src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx
1474
+ import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
1475
+ function SubscriptionsContainer({ onOpenWizard }) {
1476
+ const [subscriptions, setSubscriptions] = useState10([]);
1477
+ const [loading, setLoading] = useState10(true);
1478
+ const loadSubscriptions = useCallback(async () => {
1479
+ setLoading(true);
1480
+ try {
1481
+ const fetchedSubscriptions = await StripeSubscriptionService.listSubscriptions();
1482
+ setSubscriptions(fetchedSubscriptions);
1483
+ } catch (error) {
1484
+ console.error("[SubscriptionsContainer] Failed to load subscriptions:", error);
1485
+ } finally {
1486
+ setLoading(false);
1487
+ }
1488
+ }, []);
1489
+ useEffect5(() => {
1490
+ loadSubscriptions();
1491
+ }, []);
1492
+ const criticalSubscriptions = subscriptions.filter(
1493
+ (sub) => sub.status === "past_due" /* PAST_DUE */ || sub.status === "trialing" /* TRIALING */ && sub.trialEnd && new Date(sub.trialEnd).getTime() - (/* @__PURE__ */ new Date()).getTime() <= 7 * 24 * 60 * 60 * 1e3
1494
+ );
1495
+ if (loading) {
1496
+ return /* @__PURE__ */ jsx19("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx19("p", { className: "text-muted-foreground", children: "Loading subscriptions..." }) });
1497
+ }
1498
+ return /* @__PURE__ */ jsxs16("div", { className: "flex w-full flex-col gap-y-6", children: [
1499
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between", children: [
1500
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-x-3", children: [
1501
+ /* @__PURE__ */ jsx19(CreditCard3, { className: "h-8 w-8" }),
1502
+ /* @__PURE__ */ jsx19("h1", { className: "text-3xl font-bold", children: "Subscriptions" })
1503
+ ] }),
1504
+ subscriptions.length > 0 && /* @__PURE__ */ jsx19(Button, { onClick: () => onOpenWizard?.(), children: "Subscribe to a Plan" })
1505
+ ] }),
1506
+ criticalSubscriptions.map((subscription) => /* @__PURE__ */ jsx19(BillingAlertBanner, { subscription }, subscription.id)),
1507
+ subscriptions.length === 0 && /* @__PURE__ */ jsxs16("div", { className: "flex flex-col items-center justify-center py-12 space-y-4", children: [
1508
+ /* @__PURE__ */ jsx19(CreditCard3, { className: "h-16 w-16 text-muted-foreground" }),
1509
+ /* @__PURE__ */ jsxs16("div", { className: "text-center", children: [
1510
+ /* @__PURE__ */ jsx19("h3", { className: "text-xl font-semibold mb-2", children: "No Active Subscriptions" }),
1511
+ /* @__PURE__ */ jsx19("p", { className: "text-muted-foreground mb-6", children: "Choose a subscription plan to get started with our services." }),
1512
+ /* @__PURE__ */ jsx19(Button, { onClick: () => onOpenWizard?.(), children: "Subscribe to a Plan" })
1513
+ ] })
1514
+ ] }),
1515
+ subscriptions.length > 0 && /* @__PURE__ */ jsx19(
1516
+ SubscriptionsList,
1517
+ {
1518
+ subscriptions,
1519
+ onSubscriptionsChange: loadSubscriptions,
1520
+ onChangePlan: (sub) => onOpenWizard?.(sub)
1521
+ }
1522
+ )
1523
+ ] });
1524
+ }
1525
+ __name(SubscriptionsContainer, "SubscriptionsContainer");
1526
+
1527
+ // src/features/billing/stripe-subscription/components/widgets/IntervalToggle.tsx
1528
+ import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
1529
+ function IntervalToggle({ value, onChange, hasMonthly, hasYearly }) {
1530
+ if (!hasMonthly || !hasYearly) {
1531
+ return null;
1532
+ }
1533
+ return /* @__PURE__ */ jsx20(Tabs, { value, onValueChange: (v) => onChange(v), children: /* @__PURE__ */ jsxs17(TabsList, { children: [
1534
+ /* @__PURE__ */ jsx20(TabsTrigger, { value: "month", children: "Monthly" }),
1535
+ /* @__PURE__ */ jsx20(TabsTrigger, { value: "year", children: "Yearly" })
1536
+ ] }) });
1537
+ }
1538
+ __name(IntervalToggle, "IntervalToggle");
1539
+
1540
+ // src/features/billing/stripe-subscription/components/widgets/PricingCard.tsx
1541
+ import { Check } from "lucide-react";
1542
+ import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
1543
+ function PricingCard({ price, isCurrentPlan = false, isSelected = false, isDisabled = false, isLoading = false, onSelect }) {
1544
+ const description = price.description || price.nickname || "Standard";
1545
+ const features = price.features || [];
1546
+ const formattedPrice = formatCurrency(price.unitAmount, price.currency);
1547
+ const interval = formatInterval(price);
1548
+ const handleKeyDown = /* @__PURE__ */ __name((e) => {
1549
+ if ((e.key === "Enter" || e.key === " ") && !isDisabled && !isCurrentPlan) {
1550
+ e.preventDefault();
1551
+ onSelect(price);
1552
+ }
1553
+ }, "handleKeyDown");
1554
+ const handleClick = /* @__PURE__ */ __name(() => {
1555
+ if (!isDisabled && !isCurrentPlan && !isLoading) {
1556
+ onSelect(price);
1557
+ }
1558
+ }, "handleClick");
1559
+ return /* @__PURE__ */ jsxs18(
1560
+ Card,
1561
+ {
1562
+ role: "radio",
1563
+ "aria-checked": isSelected,
1564
+ "aria-label": `${description} plan at ${formattedPrice} ${interval}`,
1565
+ tabIndex: isDisabled ? -1 : 0,
1566
+ onKeyDown: handleKeyDown,
1567
+ onClick: handleClick,
1568
+ className: cn(
1569
+ "relative cursor-pointer transition-all duration-200 flex flex-col h-full",
1570
+ "focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
1571
+ isCurrentPlan && "bg-muted/30",
1572
+ isSelected && !isCurrentPlan && "ring-2 ring-primary",
1573
+ !isDisabled && !isCurrentPlan && "hover:shadow-md hover:border-primary/50",
1574
+ isDisabled && "opacity-50 pointer-events-none",
1575
+ isLoading && "pointer-events-none"
1576
+ ),
1577
+ children: [
1578
+ isCurrentPlan && /* @__PURE__ */ jsx21(Badge, { variant: "secondary", className: "absolute top-2 right-2", children: "Current" }),
1579
+ /* @__PURE__ */ jsx21(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsx21("h3", { className: "font-semibold text-lg", children: description }) }),
1580
+ /* @__PURE__ */ jsxs18(CardContent, { className: "pb-4 grow", children: [
1581
+ /* @__PURE__ */ jsxs18("div", { className: "mb-4", children: [
1582
+ /* @__PURE__ */ jsx21("span", { className: "text-3xl font-bold", children: formattedPrice }),
1583
+ /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground ml-1", children: interval })
1584
+ ] }),
1585
+ features.length > 0 && /* @__PURE__ */ jsx21("ul", { className: "space-y-2", children: features.map((feature, index) => /* @__PURE__ */ jsxs18("li", { className: "flex items-start gap-2", children: [
1586
+ /* @__PURE__ */ jsx21(Check, { className: "h-4 w-4 text-green-500 mt-0.5 shrink-0" }),
1587
+ /* @__PURE__ */ jsx21("span", { className: "text-sm text-muted-foreground", children: feature })
1588
+ ] }, index)) })
1589
+ ] }),
1590
+ /* @__PURE__ */ jsx21(CardFooter, { children: /* @__PURE__ */ jsx21(
1591
+ Button,
1592
+ {
1593
+ variant: isCurrentPlan ? "secondary" : isSelected ? "default" : "outline",
1594
+ className: "w-full",
1595
+ disabled: isDisabled || isCurrentPlan || isLoading,
1596
+ children: isLoading ? "Processing..." : isCurrentPlan ? "Current Plan" : isSelected ? "Selected" : "Select Plan"
1597
+ }
1598
+ ) })
1599
+ ]
1600
+ }
1601
+ );
1602
+ }
1603
+ __name(PricingCard, "PricingCard");
1604
+
1605
+ // src/features/billing/stripe-subscription/components/widgets/ProductPricingRow.tsx
1606
+ import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
1607
+ function ProductPricingRow({
1608
+ product,
1609
+ prices,
1610
+ currentPriceId,
1611
+ selectedPriceId,
1612
+ loadingPriceId,
1613
+ onSelectPrice
1614
+ }) {
1615
+ if (prices.length === 0) {
1616
+ return null;
1617
+ }
1618
+ return /* @__PURE__ */ jsxs19("div", { className: "space-y-3", children: [
1619
+ /* @__PURE__ */ jsx22("h3", { className: "font-semibold text-lg", children: product.name }),
1620
+ /* @__PURE__ */ jsx22(
1621
+ "div",
1622
+ {
1623
+ className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4",
1624
+ role: "radiogroup",
1625
+ "aria-label": `Pricing options for ${product.name}`,
1626
+ children: prices.sort((a, b) => (a.unitAmount ?? 0) - (b.unitAmount ?? 0)).map((price) => /* @__PURE__ */ jsx22(
1627
+ PricingCard,
1628
+ {
1629
+ price,
1630
+ isCurrentPlan: price.id === currentPriceId,
1631
+ isSelected: price.id === selectedPriceId,
1632
+ isLoading: price.id === loadingPriceId,
1633
+ onSelect: onSelectPrice
1888
1634
  },
1889
- subscription.id
1890
- );
1891
- }) })
1892
- ] }) }),
1893
- selectedSub && /* @__PURE__ */ jsx21(
1894
- SubscriptionDetails,
1895
- {
1896
- subscription: selectedSub,
1897
- open: !!selectedSub,
1898
- onOpenChange: (open) => !open && setSelectedSub(null),
1899
- onSubscriptionChange: () => {
1900
- onSubscriptionsChange();
1901
- setSelectedSub(null);
1902
- }
1635
+ price.id
1636
+ ))
1903
1637
  }
1904
1638
  )
1905
1639
  ] });
1906
1640
  }
1907
- __name(SubscriptionsList, "SubscriptionsList");
1641
+ __name(ProductPricingRow, "ProductPricingRow");
1908
1642
 
1909
- // src/features/billing/stripe-subscription/components/containers/SubscriptionsContainer.tsx
1910
- import { Fragment as Fragment5, jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
1911
- function SubscriptionsContainer() {
1912
- const { confirmPayment, isConfirming } = useConfirmSubscriptionPayment();
1913
- const [subscriptions, setSubscriptions] = useState12([]);
1914
- const [loading, setLoading] = useState12(true);
1915
- const [showCreateSubscription, setShowCreateSubscription] = useState12(false);
1916
- const [showPaymentMethodEditor, setShowPaymentMethodEditor] = useState12(false);
1917
- const [products, setProducts] = useState12([]);
1918
- const [pricesByProduct, setPricesByProduct] = useState12(/* @__PURE__ */ new Map());
1919
- const [loadingPricing, setLoadingPricing] = useState12(false);
1920
- const [hasPaymentMethod, setHasPaymentMethod] = useState12(null);
1921
- const [pendingPriceId, setPendingPriceId] = useState12(null);
1922
- const [creatingSubscription, setCreatingSubscription] = useState12(false);
1923
- const [paymentConfirmationState, setPaymentConfirmationState] = useState12("idle");
1924
- const [paymentError, setPaymentError] = useState12(null);
1925
- const loadSubscriptions = /* @__PURE__ */ __name(async () => {
1926
- setLoading(true);
1643
+ // src/features/billing/stripe-subscription/components/widgets/ProductPricingList.tsx
1644
+ import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
1645
+ function isRecurringProduct(prices) {
1646
+ return prices.some((p) => p.priceType === "recurring");
1647
+ }
1648
+ __name(isRecurringProduct, "isRecurringProduct");
1649
+ function getFilteredPrices(prices, selectedInterval) {
1650
+ const isRecurring = isRecurringProduct(prices);
1651
+ if (!isRecurring) {
1652
+ return prices.filter((p) => p.priceType === "one_time");
1653
+ }
1654
+ const intervalPrices = prices.filter(
1655
+ (p) => p.priceType === "recurring" && p.recurring?.interval === selectedInterval
1656
+ );
1657
+ if (intervalPrices.length === 0) {
1658
+ const fallbackInterval = selectedInterval === "month" ? "year" : "month";
1659
+ return prices.filter((p) => p.priceType === "recurring" && p.recurring?.interval === fallbackInterval);
1660
+ }
1661
+ return intervalPrices;
1662
+ }
1663
+ __name(getFilteredPrices, "getFilteredPrices");
1664
+ function ProductPricingList({
1665
+ products,
1666
+ selectedInterval,
1667
+ currentPriceId,
1668
+ selectedPriceId,
1669
+ loadingPriceId,
1670
+ loading = false,
1671
+ onSelectPrice,
1672
+ hideRecurringPrices = false
1673
+ }) {
1674
+ if (loading) {
1675
+ return /* @__PURE__ */ jsx23(ProductPricingListSkeleton, {});
1676
+ }
1677
+ if (products.length === 0) {
1678
+ return /* @__PURE__ */ jsx23("div", { className: "text-center py-8 text-muted-foreground", children: "No plans available" });
1679
+ }
1680
+ const sortedProducts = [...products].sort((a, b) => {
1681
+ const aRecurring = isRecurringProduct(a.stripePrices || []);
1682
+ const bRecurring = isRecurringProduct(b.stripePrices || []);
1683
+ if (aRecurring && !bRecurring) return -1;
1684
+ if (!aRecurring && bRecurring) return 1;
1685
+ return 0;
1686
+ });
1687
+ const filteredProducts = hideRecurringPrices ? sortedProducts.map((product) => ({
1688
+ ...product,
1689
+ stripePrices: (product.stripePrices || []).filter((price) => price.priceType !== "recurring")
1690
+ })).filter((product) => product.stripePrices.length > 0) : sortedProducts;
1691
+ return /* @__PURE__ */ jsx23("div", { className: "space-y-6", children: filteredProducts.map((product) => {
1692
+ const allPrices = product.stripePrices || [];
1693
+ const filteredPrices = getFilteredPrices(allPrices, selectedInterval);
1694
+ if (filteredPrices.length === 0) {
1695
+ return null;
1696
+ }
1697
+ return /* @__PURE__ */ jsx23(
1698
+ ProductPricingRow,
1699
+ {
1700
+ product,
1701
+ prices: filteredPrices,
1702
+ currentPriceId,
1703
+ selectedPriceId,
1704
+ loadingPriceId,
1705
+ onSelectPrice
1706
+ },
1707
+ product.id
1708
+ );
1709
+ }) });
1710
+ }
1711
+ __name(ProductPricingList, "ProductPricingList");
1712
+ function ProductPricingListSkeleton() {
1713
+ return /* @__PURE__ */ jsx23("div", { className: "space-y-6", children: [1, 2].map((rowIndex) => /* @__PURE__ */ jsxs20("div", { className: "space-y-3", children: [
1714
+ /* @__PURE__ */ jsx23(Skeleton, { className: "h-6 w-32" }),
1715
+ /* @__PURE__ */ jsx23("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4", children: [1, 2, 3].map((cardIndex) => /* @__PURE__ */ jsxs20("div", { className: "p-4 rounded-lg border animate-pulse space-y-3", children: [
1716
+ /* @__PURE__ */ jsx23(Skeleton, { className: "h-6 w-24" }),
1717
+ /* @__PURE__ */ jsx23(Skeleton, { className: "h-8 w-32" }),
1718
+ /* @__PURE__ */ jsxs20("div", { className: "space-y-2", children: [
1719
+ /* @__PURE__ */ jsx23(Skeleton, { className: "h-4 w-full" }),
1720
+ /* @__PURE__ */ jsx23(Skeleton, { className: "h-4 w-3/4" })
1721
+ ] }),
1722
+ /* @__PURE__ */ jsx23(Skeleton, { className: "h-10 w-full" })
1723
+ ] }, cardIndex)) })
1724
+ ] }, rowIndex)) });
1725
+ }
1726
+ __name(ProductPricingListSkeleton, "ProductPricingListSkeleton");
1727
+
1728
+ // src/features/billing/stripe-subscription/components/widgets/ProrationPreview.tsx
1729
+ import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
1730
+ function ProrationPreview({ preview }) {
1731
+ return /* @__PURE__ */ jsxs21("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4", children: [
1732
+ /* @__PURE__ */ jsx24("h4", { className: "font-semibold text-blue-900 mb-3", children: "Proration Breakdown" }),
1733
+ /* @__PURE__ */ jsxs21("div", { className: "space-y-2", children: [
1734
+ preview.lineItems.map((item, index) => /* @__PURE__ */ jsxs21("div", { className: "flex justify-between text-sm", children: [
1735
+ /* @__PURE__ */ jsx24("span", { className: "text-blue-800", children: item.description }),
1736
+ /* @__PURE__ */ jsx24("span", { className: `font-medium ${item.amount < 0 ? "text-green-600" : "text-blue-900"}`, children: formatCurrency(item.amount, preview.currency) })
1737
+ ] }, index)),
1738
+ /* @__PURE__ */ jsx24("div", { className: "border-t border-blue-200 pt-2 mt-2", children: /* @__PURE__ */ jsxs21("div", { className: "flex justify-between font-semibold", children: [
1739
+ /* @__PURE__ */ jsx24("span", { className: "text-blue-900", children: "Net Due Today" }),
1740
+ /* @__PURE__ */ jsx24("span", { className: "text-blue-900", children: formatCurrency(preview.immediateCharge, preview.currency) })
1741
+ ] }) }),
1742
+ preview.lineItems.length > 0 && preview.lineItems[0].period && /* @__PURE__ */ jsxs21("div", { className: "text-xs text-blue-700 mt-2", children: [
1743
+ "Next invoice on ",
1744
+ formatDate3(preview.lineItems[0].period.end),
1745
+ " for",
1746
+ " ",
1747
+ formatCurrency(preview.amountDue, preview.currency)
1748
+ ] })
1749
+ ] })
1750
+ ] });
1751
+ }
1752
+ __name(ProrationPreview, "ProrationPreview");
1753
+
1754
+ // src/features/billing/stripe-subscription/components/widgets/SubscriptionConfirmation.tsx
1755
+ import { Check as Check2, Loader2 } from "lucide-react";
1756
+ import { Fragment as Fragment5, jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
1757
+ function SubscriptionConfirmation({ price, isLoading, onConfirm, onCancel }) {
1758
+ const productName = price.product?.name || price.nickname || "Selected Plan";
1759
+ const productDescription = price.product?.description || price.description;
1760
+ const features = price.features || [];
1761
+ return /* @__PURE__ */ jsxs22("div", { className: "bg-accent/10 border border-accent/30 rounded-lg p-4", children: [
1762
+ /* @__PURE__ */ jsx25("h4", { className: "font-semibold mb-3", children: "Confirm Your Subscription" }),
1763
+ /* @__PURE__ */ jsxs22("div", { className: "space-y-3", children: [
1764
+ /* @__PURE__ */ jsxs22("div", { children: [
1765
+ /* @__PURE__ */ jsx25("div", { className: "font-medium", children: productName }),
1766
+ productDescription && /* @__PURE__ */ jsx25("div", { className: "text-sm text-muted-foreground", children: productDescription })
1767
+ ] }),
1768
+ /* @__PURE__ */ jsxs22("div", { className: "text-lg font-semibold", children: [
1769
+ formatCurrency(price.unitAmount, price.currency),
1770
+ /* @__PURE__ */ jsx25("span", { className: "text-sm font-normal text-muted-foreground", children: formatInterval(price) })
1771
+ ] }),
1772
+ features.length > 0 && /* @__PURE__ */ jsx25("div", { className: "space-y-1", children: features.map((feature, index) => /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 text-sm ", children: [
1773
+ /* @__PURE__ */ jsx25(Check2, { className: "h-4 w-4 text-primary" }),
1774
+ /* @__PURE__ */ jsx25("span", { children: feature })
1775
+ ] }, index)) }),
1776
+ /* @__PURE__ */ jsxs22("div", { className: "flex justify-end gap-3 pt-2 border-t border-accent/30", children: [
1777
+ /* @__PURE__ */ jsx25(Button, { variant: "outline", onClick: onCancel, disabled: isLoading, children: "Cancel" }),
1778
+ /* @__PURE__ */ jsx25(Button, { onClick: onConfirm, disabled: isLoading, children: isLoading ? /* @__PURE__ */ jsxs22(Fragment5, { children: [
1779
+ /* @__PURE__ */ jsx25(Loader2, { className: "h-4 w-4 animate-spin mr-2" }),
1780
+ "Processing..."
1781
+ ] }) : "Subscribe" })
1782
+ ] })
1783
+ ] })
1784
+ ] });
1785
+ }
1786
+ __name(SubscriptionConfirmation, "SubscriptionConfirmation");
1787
+
1788
+ // src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx
1789
+ import { useCallback as useCallback3, useEffect as useEffect7, useRef as useRef2 } from "react";
1790
+
1791
+ // src/features/billing/stripe-subscription/hooks/useSubscriptionWizard.ts
1792
+ import { useCallback as useCallback2, useMemo, useReducer, useRef } from "react";
1793
+ var initialState = {
1794
+ step: "plan-selection",
1795
+ selectedPrice: null,
1796
+ selectedInterval: "month",
1797
+ hasPaymentMethod: false,
1798
+ isProcessing: false,
1799
+ error: null,
1800
+ prorationPreview: null
1801
+ };
1802
+ function wizardReducer(state, action) {
1803
+ switch (action.type) {
1804
+ case "SET_STEP":
1805
+ return { ...state, step: action.step, error: null };
1806
+ case "SELECT_PRICE":
1807
+ return { ...state, selectedPrice: action.price };
1808
+ case "SET_INTERVAL":
1809
+ return { ...state, selectedInterval: action.interval };
1810
+ case "SET_HAS_PAYMENT_METHOD":
1811
+ return { ...state, hasPaymentMethod: action.hasMethod };
1812
+ case "SET_PROCESSING":
1813
+ return { ...state, isProcessing: action.isProcessing };
1814
+ case "SET_ERROR":
1815
+ return { ...state, error: action.error };
1816
+ case "SET_PRORATION_PREVIEW":
1817
+ return { ...state, prorationPreview: action.preview };
1818
+ case "RESET":
1819
+ return initialState;
1820
+ default:
1821
+ return state;
1822
+ }
1823
+ }
1824
+ __name(wizardReducer, "wizardReducer");
1825
+ function useSubscriptionWizard({ subscription, onSuccess, onClose }) {
1826
+ const [state, dispatch] = useReducer(wizardReducer, {
1827
+ ...initialState,
1828
+ selectedPrice: subscription?.price || null
1829
+ });
1830
+ const onSuccessRef = useRef(onSuccess);
1831
+ const onCloseRef = useRef(onClose);
1832
+ onSuccessRef.current = onSuccess;
1833
+ onCloseRef.current = onClose;
1834
+ const checkPaymentMethod = useCallback2(async () => {
1927
1835
  try {
1928
- const fetchedSubscriptions = await StripeSubscriptionService.listSubscriptions();
1929
- setSubscriptions(fetchedSubscriptions);
1836
+ const methods = await StripeCustomerService.listPaymentMethods();
1837
+ dispatch({ type: "SET_HAS_PAYMENT_METHOD", hasMethod: methods.length > 0 });
1930
1838
  } catch (error) {
1931
- console.error("[SubscriptionsContainer] Failed to load subscriptions:", error);
1932
- } finally {
1933
- setLoading(false);
1839
+ console.error("[useSubscriptionWizard] Failed to check payment methods:", error);
1840
+ dispatch({ type: "SET_HAS_PAYMENT_METHOD", hasMethod: false });
1934
1841
  }
1935
- }, "loadSubscriptions");
1936
- const loadPricingData = /* @__PURE__ */ __name(async () => {
1937
- setLoadingPricing(true);
1842
+ }, []);
1843
+ const selectPrice = useCallback2((price) => {
1844
+ dispatch({ type: "SELECT_PRICE", price });
1845
+ }, []);
1846
+ const setInterval = useCallback2((interval) => {
1847
+ dispatch({ type: "SET_INTERVAL", interval });
1848
+ }, []);
1849
+ const goToStep = useCallback2((step) => {
1850
+ dispatch({ type: "SET_STEP", step });
1851
+ }, []);
1852
+ const goToReview = useCallback2(async () => {
1853
+ if (!state.selectedPrice) return;
1854
+ dispatch({ type: "SET_PROCESSING", isProcessing: true });
1938
1855
  try {
1939
- const fetchedProducts = await StripeProductService.listProducts({ active: true });
1940
- const grouped = /* @__PURE__ */ new Map();
1941
- for (const product of fetchedProducts) {
1942
- if (product.stripePrices && product.stripePrices.length > 0) {
1943
- grouped.set(product.id, product.stripePrices);
1944
- }
1856
+ await checkPaymentMethod();
1857
+ if (subscription && state.selectedPrice.id !== subscription.price?.id) {
1858
+ const preview = await StripeSubscriptionService.getProrationPreview({
1859
+ subscriptionId: subscription.id,
1860
+ newPriceId: state.selectedPrice.id
1861
+ });
1862
+ dispatch({ type: "SET_PRORATION_PREVIEW", preview });
1945
1863
  }
1946
- setProducts(fetchedProducts);
1947
- setPricesByProduct(grouped);
1864
+ dispatch({ type: "SET_STEP", step: "review" });
1948
1865
  } catch (error) {
1949
- console.error("[SubscriptionsContainer] Failed to load pricing data:", error);
1866
+ console.error("[useSubscriptionWizard] Error preparing review:", error);
1867
+ dispatch({ type: "SET_ERROR", error: error?.message || "Failed to prepare review" });
1950
1868
  } finally {
1951
- setLoadingPricing(false);
1952
- }
1953
- }, "loadPricingData");
1954
- const checkPaymentMethod = /* @__PURE__ */ __name(async () => {
1955
- try {
1956
- const paymentMethods = await StripeCustomerService.listPaymentMethods();
1957
- const hasMethod = paymentMethods.length > 0;
1958
- setHasPaymentMethod(hasMethod);
1959
- } catch (error) {
1960
- console.error("[SubscriptionsContainer] Failed to check payment methods:", error);
1961
- setHasPaymentMethod(false);
1869
+ dispatch({ type: "SET_PROCESSING", isProcessing: false });
1962
1870
  }
1963
- }, "checkPaymentMethod");
1964
- const createSubscriptionWithPrice = /* @__PURE__ */ __name(async (priceId) => {
1965
- setCreatingSubscription(true);
1966
- setPaymentError(null);
1967
- setPaymentConfirmationState("idle");
1871
+ }, [state.selectedPrice, subscription, checkPaymentMethod]);
1872
+ const confirmSubscription = useCallback2(async () => {
1873
+ if (!state.selectedPrice) return;
1874
+ dispatch({ type: "SET_PROCESSING", isProcessing: true });
1875
+ dispatch({ type: "SET_ERROR", error: null });
1968
1876
  try {
1969
- const result = await StripeSubscriptionService.createSubscription({
1970
- id: v42(),
1971
- priceId
1972
- });
1973
- if (result.meta.requiresAction && result.meta.clientSecret) {
1974
- setPaymentConfirmationState("confirming");
1975
- const confirmation = await confirmPayment(result.meta.clientSecret);
1976
- if (!confirmation.success) {
1977
- console.error("[SubscriptionsContainer] Payment confirmation failed:", confirmation.error);
1978
- setPaymentConfirmationState("error");
1979
- setPaymentError(confirmation.error || "Payment confirmation failed");
1980
- setCreatingSubscription(false);
1981
- return;
1982
- }
1983
- await StripeSubscriptionService.syncSubscription({
1984
- subscriptionId: result.subscription.id
1877
+ if (subscription) {
1878
+ await StripeSubscriptionService.changePlan({
1879
+ id: subscription.id,
1880
+ newPriceId: state.selectedPrice.id
1881
+ });
1882
+ } else {
1883
+ await StripeSubscriptionService.createSubscription({
1884
+ id: crypto.randomUUID(),
1885
+ priceId: state.selectedPrice.id
1985
1886
  });
1986
1887
  }
1987
- setPaymentConfirmationState("success");
1988
- await loadSubscriptions();
1888
+ onSuccessRef.current();
1889
+ onCloseRef.current();
1989
1890
  } catch (error) {
1990
- console.error("[SubscriptionsContainer] Failed to create subscription:", error);
1891
+ console.error("[useSubscriptionWizard] Subscription error:", error);
1892
+ if (error?.status === 409 || error?.response?.status === 409) {
1893
+ dispatch({
1894
+ type: "SET_ERROR",
1895
+ error: "You already have an active subscription. Please change your existing plan instead."
1896
+ });
1897
+ return;
1898
+ }
1991
1899
  if (error?.status === 402 || error?.response?.status === 402) {
1992
- setPendingPriceId(priceId);
1993
- setHasPaymentMethod(false);
1994
- setShowPaymentMethodEditor(true);
1995
- } else {
1996
- setPaymentConfirmationState("error");
1997
- setPaymentError(error?.message || "Failed to create subscription");
1900
+ dispatch({ type: "SET_HAS_PAYMENT_METHOD", hasMethod: false });
1901
+ dispatch({ type: "SET_STEP", step: "payment-method" });
1902
+ return;
1998
1903
  }
1904
+ dispatch({ type: "SET_ERROR", error: error?.message || "Failed to process subscription" });
1999
1905
  } finally {
2000
- setCreatingSubscription(false);
1906
+ dispatch({ type: "SET_PROCESSING", isProcessing: false });
2001
1907
  }
2002
- }, "createSubscriptionWithPrice");
2003
- const handleSelectPrice = /* @__PURE__ */ __name(async (price) => {
2004
- const priceId = price.id;
2005
- if (!hasPaymentMethod) {
2006
- setPendingPriceId(priceId);
2007
- setShowPaymentMethodEditor(true);
2008
- return;
2009
- }
2010
- await createSubscriptionWithPrice(priceId);
2011
- }, "handleSelectPrice");
2012
- const handlePaymentMethodSuccess = /* @__PURE__ */ __name(async () => {
2013
- setShowPaymentMethodEditor(false);
2014
- setHasPaymentMethod(true);
2015
- if (pendingPriceId) {
2016
- await createSubscriptionWithPrice(pendingPriceId);
2017
- setPendingPriceId(null);
2018
- }
2019
- }, "handlePaymentMethodSuccess");
2020
- useEffect6(() => {
2021
- loadSubscriptions();
1908
+ }, [state.selectedPrice, subscription]);
1909
+ const handlePaymentMethodSuccess = useCallback2(async () => {
1910
+ dispatch({ type: "SET_HAS_PAYMENT_METHOD", hasMethod: true });
1911
+ dispatch({ type: "SET_STEP", step: "review" });
2022
1912
  }, []);
1913
+ const reset = useCallback2(() => {
1914
+ dispatch({ type: "RESET" });
1915
+ }, []);
1916
+ const actions = useMemo(
1917
+ () => ({
1918
+ selectPrice,
1919
+ setInterval,
1920
+ goToStep,
1921
+ goToReview,
1922
+ confirmSubscription,
1923
+ handlePaymentMethodSuccess,
1924
+ checkPaymentMethod,
1925
+ reset
1926
+ }),
1927
+ [
1928
+ selectPrice,
1929
+ setInterval,
1930
+ goToStep,
1931
+ goToReview,
1932
+ confirmSubscription,
1933
+ handlePaymentMethodSuccess,
1934
+ checkPaymentMethod,
1935
+ reset
1936
+ ]
1937
+ );
1938
+ return {
1939
+ state,
1940
+ actions
1941
+ };
1942
+ }
1943
+ __name(useSubscriptionWizard, "useSubscriptionWizard");
1944
+
1945
+ // src/features/billing/stripe-subscription/components/wizards/WizardProgressIndicator.tsx
1946
+ import { Check as Check3 } from "lucide-react";
1947
+ import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
1948
+ var STEPS = [
1949
+ { key: "plan-selection", label: "Select Plan" },
1950
+ { key: "review", label: "Review" },
1951
+ { key: "payment-method", label: "Payment" }
1952
+ ];
1953
+ function getStepIndex(step) {
1954
+ return STEPS.findIndex((s) => s.key === step);
1955
+ }
1956
+ __name(getStepIndex, "getStepIndex");
1957
+ function WizardProgressIndicator({ currentStep }) {
1958
+ const currentIndex = getStepIndex(currentStep);
1959
+ return /* @__PURE__ */ jsx26("div", { className: "flex items-center justify-center gap-x-2 py-4", children: STEPS.map((step, index) => {
1960
+ const isCompleted = index < currentIndex;
1961
+ const isCurrent = index === currentIndex;
1962
+ return /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-x-2", children: [
1963
+ /* @__PURE__ */ jsx26(
1964
+ "div",
1965
+ {
1966
+ className: `flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium ${isCompleted ? "bg-primary text-primary-foreground" : isCurrent ? "bg-primary text-primary-foreground" : "bg-muted text-muted-foreground"}`,
1967
+ children: isCompleted ? /* @__PURE__ */ jsx26(Check3, { className: "h-4 w-4" }) : index + 1
1968
+ }
1969
+ ),
1970
+ /* @__PURE__ */ jsx26(
1971
+ "span",
1972
+ {
1973
+ className: `text-sm ${isCurrent ? "font-medium text-foreground" : "text-muted-foreground"}`,
1974
+ children: step.label
1975
+ }
1976
+ ),
1977
+ index < STEPS.length - 1 && /* @__PURE__ */ jsx26(
1978
+ "div",
1979
+ {
1980
+ className: `h-0.5 w-8 ${index < currentIndex ? "bg-primary" : "bg-muted"}`
1981
+ }
1982
+ )
1983
+ ] }, step.key);
1984
+ }) });
1985
+ }
1986
+ __name(WizardProgressIndicator, "WizardProgressIndicator");
1987
+
1988
+ // src/features/billing/stripe-subscription/components/wizards/WizardStepPlanSelection.tsx
1989
+ import { useEffect as useEffect6, useMemo as useMemo2, useState as useState11 } from "react";
1990
+ import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
1991
+ function WizardStepPlanSelection({
1992
+ selectedPrice,
1993
+ selectedInterval,
1994
+ currentPriceId,
1995
+ hideRecurringPrices,
1996
+ onSelectPrice,
1997
+ onIntervalChange,
1998
+ onNext,
1999
+ isProcessing
2000
+ }) {
2001
+ const [products, setProducts] = useState11([]);
2002
+ const [loading, setLoading] = useState11(true);
2023
2003
  useEffect6(() => {
2024
- if (!loading && subscriptions.length === 0) {
2025
- loadPricingData();
2026
- checkPaymentMethod();
2004
+ const loadProducts = /* @__PURE__ */ __name(async () => {
2005
+ try {
2006
+ const fetchedProducts = await StripeProductService.listProducts({ active: true });
2007
+ setProducts(fetchedProducts);
2008
+ } catch (error) {
2009
+ console.error("[WizardStepPlanSelection] Failed to load products:", error);
2010
+ } finally {
2011
+ setLoading(false);
2012
+ }
2013
+ }, "loadProducts");
2014
+ loadProducts();
2015
+ }, []);
2016
+ const { hasMonthly, hasYearly } = useMemo2(() => {
2017
+ let hasMonthly2 = false;
2018
+ let hasYearly2 = false;
2019
+ for (const product of products) {
2020
+ for (const price of product.stripePrices || []) {
2021
+ if (price.priceType === "recurring" && price.recurring?.interval === "month") {
2022
+ hasMonthly2 = true;
2023
+ }
2024
+ if (price.priceType === "recurring" && price.recurring?.interval === "year") {
2025
+ hasYearly2 = true;
2026
+ }
2027
+ }
2027
2028
  }
2028
- }, [loading, subscriptions.length]);
2029
- const criticalSubscriptions = subscriptions.filter(
2030
- (sub) => sub.status === "past_due" /* PAST_DUE */ || sub.status === "trialing" /* TRIALING */ && sub.trialEnd && new Date(sub.trialEnd).getTime() - (/* @__PURE__ */ new Date()).getTime() <= 7 * 24 * 60 * 60 * 1e3
2031
- );
2032
- if (loading) {
2033
- return /* @__PURE__ */ jsx22("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx22("p", { className: "text-muted-foreground", children: "Loading subscriptions..." }) });
2029
+ return { hasMonthly: hasMonthly2, hasYearly: hasYearly2 };
2030
+ }, [products]);
2031
+ const handleSelectPrice = /* @__PURE__ */ __name((price) => {
2032
+ onSelectPrice(price);
2033
+ }, "handleSelectPrice");
2034
+ return /* @__PURE__ */ jsxs24("div", { className: "space-y-6", children: [
2035
+ /* @__PURE__ */ jsx27("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx27(
2036
+ IntervalToggle,
2037
+ {
2038
+ value: selectedInterval,
2039
+ onChange: onIntervalChange,
2040
+ hasMonthly,
2041
+ hasYearly
2042
+ }
2043
+ ) }),
2044
+ /* @__PURE__ */ jsx27(
2045
+ ProductPricingList,
2046
+ {
2047
+ products,
2048
+ selectedInterval,
2049
+ currentPriceId,
2050
+ selectedPriceId: selectedPrice?.id,
2051
+ loading,
2052
+ hideRecurringPrices,
2053
+ onSelectPrice: handleSelectPrice
2054
+ }
2055
+ ),
2056
+ /* @__PURE__ */ jsx27("div", { className: "flex justify-end pt-4 border-t", children: /* @__PURE__ */ jsx27(Button, { onClick: onNext, disabled: !selectedPrice || isProcessing, children: isProcessing ? "Loading..." : "Next: Review" }) })
2057
+ ] });
2058
+ }
2059
+ __name(WizardStepPlanSelection, "WizardStepPlanSelection");
2060
+
2061
+ // src/features/billing/stripe-subscription/components/wizards/WizardStepReview.tsx
2062
+ import { AlertCircle } from "lucide-react";
2063
+ import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
2064
+ function WizardStepReview({
2065
+ selectedPrice,
2066
+ subscription,
2067
+ prorationPreview,
2068
+ hasPaymentMethod,
2069
+ error,
2070
+ isProcessing,
2071
+ onBack,
2072
+ onAddPaymentMethod,
2073
+ onConfirm
2074
+ }) {
2075
+ if (!selectedPrice) {
2076
+ return /* @__PURE__ */ jsx28("div", { className: "text-center py-8 text-muted-foreground", children: "No plan selected. Please go back and select a plan." });
2034
2077
  }
2035
- return /* @__PURE__ */ jsxs19("div", { className: "flex w-full flex-col gap-y-6", children: [
2036
- /* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between", children: [
2037
- /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-x-3", children: [
2038
- /* @__PURE__ */ jsx22(CreditCard3, { className: "h-8 w-8" }),
2039
- /* @__PURE__ */ jsx22("h1", { className: "text-3xl font-bold", children: "Subscriptions" })
2040
- ] }),
2041
- subscriptions.length > 0 && /* @__PURE__ */ jsx22(Button, { onClick: () => setShowCreateSubscription(true), children: "Subscribe to a Plan" })
2042
- ] }),
2043
- criticalSubscriptions.map((subscription) => /* @__PURE__ */ jsx22(BillingAlertBanner, { subscription }, subscription.id)),
2044
- subscriptions.length === 0 && /* @__PURE__ */ jsxs19("div", { className: "space-y-6", children: [
2045
- (paymentConfirmationState === "confirming" || isConfirming) && /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center justify-center py-12 space-y-4 bg-muted/50 rounded-lg", children: [
2046
- /* @__PURE__ */ jsx22(Loader22, { className: "h-8 w-8 animate-spin text-primary" }),
2047
- /* @__PURE__ */ jsxs19("div", { className: "text-center", children: [
2048
- /* @__PURE__ */ jsx22("p", { className: "font-medium", children: "Processing payment..." }),
2049
- /* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Please complete any verification if prompted." })
2050
- ] })
2051
- ] }),
2052
- paymentConfirmationState === "success" && /* @__PURE__ */ jsxs19("div", { className: "flex flex-col items-center justify-center py-8 space-y-4 bg-green-50 rounded-lg border border-green-200", children: [
2053
- /* @__PURE__ */ jsx22(CheckCircle2, { className: "h-12 w-12 text-green-500" }),
2054
- /* @__PURE__ */ jsxs19("div", { className: "text-center", children: [
2055
- /* @__PURE__ */ jsx22("p", { className: "font-medium text-green-600", children: "Payment successful!" }),
2056
- /* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Your subscription is now active." })
2057
- ] })
2058
- ] }),
2059
- paymentConfirmationState === "error" && /* @__PURE__ */ jsxs19(Alert, { variant: "destructive", children: [
2060
- /* @__PURE__ */ jsx22(AlertTitle, { children: "Payment Failed" }),
2061
- /* @__PURE__ */ jsxs19(AlertDescription, { className: "mt-2", children: [
2062
- /* @__PURE__ */ jsx22("p", { className: "mb-4", children: paymentError || "We couldn't process your payment. Please try again." }),
2063
- /* @__PURE__ */ jsx22(
2064
- Button,
2065
- {
2066
- onClick: () => {
2067
- setPaymentConfirmationState("idle");
2068
- setPaymentError(null);
2069
- },
2070
- variant: "outline",
2071
- children: "Try Again"
2072
- }
2073
- )
2074
- ] })
2075
- ] }),
2076
- paymentConfirmationState === "idle" && !isConfirming && /* @__PURE__ */ jsxs19(Fragment5, { children: [
2077
- /* @__PURE__ */ jsxs19("div", { className: "text-center", children: [
2078
- /* @__PURE__ */ jsx22(CreditCard3, { className: "text-muted-foreground mx-auto h-16 w-16 mb-4" }),
2079
- /* @__PURE__ */ jsx22("h3", { className: "mb-2 text-xl font-semibold", children: "Choose Your Plan" }),
2080
- /* @__PURE__ */ jsx22("p", { className: "text-muted-foreground mb-6", children: "Select a subscription plan to get started with our services." })
2078
+ const isChangingPlan = subscription && subscription.price?.id !== selectedPrice.id;
2079
+ const formatInterval2 = /* @__PURE__ */ __name((price) => {
2080
+ if (price.priceType === "one_time") return "one-time";
2081
+ const interval = price.recurring?.interval || "month";
2082
+ return interval === "year" ? "yearly" : "monthly";
2083
+ }, "formatInterval");
2084
+ return /* @__PURE__ */ jsxs25("div", { className: "space-y-6", children: [
2085
+ /* @__PURE__ */ jsxs25("div", { className: "bg-muted/50 rounded-lg p-4 space-y-3", children: [
2086
+ /* @__PURE__ */ jsx28("h3", { className: "font-semibold text-lg", children: "Selected Plan" }),
2087
+ /* @__PURE__ */ jsxs25("div", { className: "flex justify-between items-center", children: [
2088
+ /* @__PURE__ */ jsxs25("div", { children: [
2089
+ /* @__PURE__ */ jsx28("p", { className: "font-medium", children: selectedPrice.product?.name }),
2090
+ selectedPrice.nickname && /* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: selectedPrice.nickname })
2081
2091
  ] }),
2082
- /* @__PURE__ */ jsx22(
2083
- PricingCardsGrid,
2084
- {
2085
- products,
2086
- pricesByProduct,
2087
- loading: loadingPricing,
2088
- loadingPriceId: creatingSubscription ? pendingPriceId ?? void 0 : void 0,
2089
- onSelectPrice: handleSelectPrice
2090
- }
2091
- )
2092
+ /* @__PURE__ */ jsxs25("div", { className: "text-right", children: [
2093
+ /* @__PURE__ */ jsx28("p", { className: "font-semibold text-lg", children: formatCurrency(selectedPrice.unitAmount || 0, selectedPrice.currency) }),
2094
+ /* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: formatInterval2(selectedPrice) })
2095
+ ] })
2092
2096
  ] })
2093
2097
  ] }),
2094
- subscriptions.length > 0 && /* @__PURE__ */ jsx22(SubscriptionsList, { subscriptions, onSubscriptionsChange: loadSubscriptions }),
2095
- showCreateSubscription && /* @__PURE__ */ jsx22(
2096
- SubscriptionEditor,
2097
- {
2098
- open: showCreateSubscription,
2099
- onOpenChange: setShowCreateSubscription,
2100
- onSuccess: loadSubscriptions,
2101
- onAddPaymentMethod: () => {
2102
- setShowCreateSubscription(false);
2103
- setShowPaymentMethodEditor(true);
2098
+ isChangingPlan && prorationPreview && /* @__PURE__ */ jsxs25("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4 space-y-2", children: [
2099
+ /* @__PURE__ */ jsx28("h4", { className: "font-medium text-blue-800", children: "Proration Summary" }),
2100
+ /* @__PURE__ */ jsx28("p", { className: "text-sm text-blue-700", children: "Your next charge will be adjusted to account for the plan change." }),
2101
+ /* @__PURE__ */ jsxs25("div", { className: "flex justify-between text-sm", children: [
2102
+ /* @__PURE__ */ jsx28("span", { className: "text-blue-600", children: "Amount due now:" }),
2103
+ /* @__PURE__ */ jsx28("span", { className: "font-medium text-blue-800", children: formatCurrency(prorationPreview.amountDue, prorationPreview.currency) })
2104
+ ] })
2105
+ ] }),
2106
+ /* @__PURE__ */ jsx28("div", { className: "border rounded-lg p-4", children: /* @__PURE__ */ jsxs25("div", { className: "flex justify-between items-center", children: [
2107
+ /* @__PURE__ */ jsxs25("div", { children: [
2108
+ /* @__PURE__ */ jsx28("h4", { className: "font-medium", children: "Payment Method" }),
2109
+ /* @__PURE__ */ jsx28("p", { className: "text-sm text-muted-foreground", children: hasPaymentMethod ? "A payment method is on file" : "No payment method on file" })
2110
+ ] }),
2111
+ !hasPaymentMethod && /* @__PURE__ */ jsx28(Button, { variant: "outline", onClick: onAddPaymentMethod, children: "Add Payment Method" })
2112
+ ] }) }),
2113
+ error && /* @__PURE__ */ jsxs25(Alert, { variant: "destructive", children: [
2114
+ /* @__PURE__ */ jsx28(AlertCircle, { className: "h-4 w-4" }),
2115
+ /* @__PURE__ */ jsx28(AlertDescription, { children: error })
2116
+ ] }),
2117
+ /* @__PURE__ */ jsxs25("div", { className: "flex justify-between pt-4 border-t", children: [
2118
+ /* @__PURE__ */ jsx28(Button, { variant: "outline", onClick: onBack, disabled: isProcessing, children: "Back" }),
2119
+ /* @__PURE__ */ jsx28(
2120
+ Button,
2121
+ {
2122
+ onClick: hasPaymentMethod ? onConfirm : onAddPaymentMethod,
2123
+ disabled: isProcessing,
2124
+ children: isProcessing ? "Processing..." : hasPaymentMethod ? isChangingPlan ? "Confirm Plan Change" : "Subscribe Now" : "Add Payment Method"
2104
2125
  }
2126
+ )
2127
+ ] })
2128
+ ] });
2129
+ }
2130
+ __name(WizardStepReview, "WizardStepReview");
2131
+
2132
+ // src/features/billing/stripe-subscription/components/wizards/WizardStepPaymentMethod.tsx
2133
+ import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
2134
+ function WizardStepPaymentMethod({
2135
+ onBack,
2136
+ onSuccess,
2137
+ isProcessing
2138
+ }) {
2139
+ return /* @__PURE__ */ jsxs26("div", { className: "space-y-6", children: [
2140
+ /* @__PURE__ */ jsxs26("div", { className: "text-center", children: [
2141
+ /* @__PURE__ */ jsx29("h3", { className: "font-semibold text-lg", children: "Add Payment Method" }),
2142
+ /* @__PURE__ */ jsx29("p", { className: "text-sm text-muted-foreground", children: "Enter your card details to complete your subscription" })
2143
+ ] }),
2144
+ /* @__PURE__ */ jsx29(
2145
+ PaymentMethodForm,
2146
+ {
2147
+ onSuccess,
2148
+ onCancel: onBack,
2149
+ isLoading: isProcessing
2150
+ }
2151
+ )
2152
+ ] });
2153
+ }
2154
+ __name(WizardStepPaymentMethod, "WizardStepPaymentMethod");
2155
+
2156
+ // src/features/billing/stripe-subscription/components/wizards/SubscriptionWizard.tsx
2157
+ import { jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
2158
+ function SubscriptionWizard({
2159
+ open,
2160
+ onOpenChange,
2161
+ onSuccess,
2162
+ hasActiveRecurringSubscription,
2163
+ subscription
2164
+ }) {
2165
+ const handleClose = useCallback3(() => onOpenChange(false), [onOpenChange]);
2166
+ const { state, actions } = useSubscriptionWizard({
2167
+ subscription,
2168
+ onSuccess,
2169
+ onClose: handleClose
2170
+ });
2171
+ const hasCheckedRef = useRef2(false);
2172
+ useEffect7(() => {
2173
+ if (open && !hasCheckedRef.current) {
2174
+ hasCheckedRef.current = true;
2175
+ actions.checkPaymentMethod();
2176
+ }
2177
+ if (!open) {
2178
+ hasCheckedRef.current = false;
2179
+ }
2180
+ }, [open, actions.checkPaymentMethod]);
2181
+ useEffect7(() => {
2182
+ if (!open) {
2183
+ actions.reset();
2184
+ }
2185
+ }, [open, actions.reset]);
2186
+ const dialogTitle = subscription ? "Change Subscription Plan" : "Subscribe to a Plan";
2187
+ const dialogDescription = subscription ? "Select a new plan for your subscription" : "Choose a subscription plan to get started";
2188
+ return /* @__PURE__ */ jsx30(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs27(DialogContent, { className: "max-w-2xl", children: [
2189
+ /* @__PURE__ */ jsxs27(DialogHeader, { children: [
2190
+ /* @__PURE__ */ jsx30(DialogTitle, { children: dialogTitle }),
2191
+ /* @__PURE__ */ jsx30(DialogDescription, { children: dialogDescription })
2192
+ ] }),
2193
+ /* @__PURE__ */ jsx30(WizardProgressIndicator, { currentStep: state.step }),
2194
+ state.step === "plan-selection" && /* @__PURE__ */ jsx30(
2195
+ WizardStepPlanSelection,
2196
+ {
2197
+ selectedPrice: state.selectedPrice,
2198
+ selectedInterval: state.selectedInterval,
2199
+ currentPriceId: subscription?.price?.id,
2200
+ hideRecurringPrices: hasActiveRecurringSubscription && !subscription,
2201
+ onSelectPrice: actions.selectPrice,
2202
+ onIntervalChange: actions.setInterval,
2203
+ onNext: actions.goToReview,
2204
+ isProcessing: state.isProcessing
2105
2205
  }
2106
2206
  ),
2107
- showPaymentMethodEditor && /* @__PURE__ */ jsx22(
2108
- PaymentMethodEditor,
2207
+ state.step === "review" && /* @__PURE__ */ jsx30(
2208
+ WizardStepReview,
2109
2209
  {
2110
- open: showPaymentMethodEditor,
2111
- onOpenChange: (open) => {
2112
- setShowPaymentMethodEditor(open);
2113
- if (!open) {
2114
- setPendingPriceId(null);
2115
- }
2116
- },
2117
- onSuccess: handlePaymentMethodSuccess
2210
+ selectedPrice: state.selectedPrice,
2211
+ subscription,
2212
+ prorationPreview: state.prorationPreview,
2213
+ hasPaymentMethod: state.hasPaymentMethod,
2214
+ error: state.error,
2215
+ isProcessing: state.isProcessing,
2216
+ onBack: () => actions.goToStep("plan-selection"),
2217
+ onAddPaymentMethod: () => actions.goToStep("payment-method"),
2218
+ onConfirm: actions.confirmSubscription
2219
+ }
2220
+ ),
2221
+ state.step === "payment-method" && /* @__PURE__ */ jsx30(
2222
+ WizardStepPaymentMethod,
2223
+ {
2224
+ onBack: () => actions.goToStep("review"),
2225
+ onSuccess: actions.handlePaymentMethodSuccess,
2226
+ isProcessing: state.isProcessing
2118
2227
  }
2119
2228
  )
2120
- ] });
2229
+ ] }) });
2121
2230
  }
2122
- __name(SubscriptionsContainer, "SubscriptionsContainer");
2231
+ __name(SubscriptionWizard, "SubscriptionWizard");
2123
2232
 
2124
2233
  // src/features/billing/stripe-usage/components/containers/UsageContainer.tsx
2125
2234
  import { Activity as Activity3 } from "lucide-react";
2126
- import { useEffect as useEffect7, useState as useState13 } from "react";
2235
+ import { useEffect as useEffect8, useState as useState12 } from "react";
2127
2236
 
2128
2237
  // src/features/billing/stripe-usage/components/details/UsageSummaryCard.tsx
2129
2238
  import { Activity as Activity2 } from "lucide-react";
2130
- import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
2239
+ import { jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
2131
2240
  function getProgressColor(percentage) {
2132
2241
  if (percentage === null) return "bg-blue-500";
2133
2242
  if (percentage >= 90) return "bg-red-500";
@@ -2155,31 +2264,31 @@ function UsageSummaryCard({ meter, summary }) {
2155
2264
  const progressWidth = percentage !== null ? Math.min(percentage, 100) : 0;
2156
2265
  const displayName = meter.displayName || meter.eventName;
2157
2266
  const hasLimit = limit !== null && limit !== void 0;
2158
- return /* @__PURE__ */ jsxs20(Card, { children: [
2159
- /* @__PURE__ */ jsxs20(CardHeader, { className: "flex flex-row items-center gap-x-3 pb-3", children: [
2160
- /* @__PURE__ */ jsx23("div", { className: "flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600", children: /* @__PURE__ */ jsx23(Activity2, { className: "h-5 w-5" }) }),
2161
- /* @__PURE__ */ jsxs20("div", { className: "flex flex-col", children: [
2162
- /* @__PURE__ */ jsx23("h3", { className: "font-semibold", children: displayName }),
2163
- /* @__PURE__ */ jsx23("p", { className: "text-xs text-gray-500", children: meter.id })
2267
+ return /* @__PURE__ */ jsxs28(Card, { children: [
2268
+ /* @__PURE__ */ jsxs28(CardHeader, { className: "flex flex-row items-center gap-x-3 pb-3", children: [
2269
+ /* @__PURE__ */ jsx31("div", { className: "flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-blue-600", children: /* @__PURE__ */ jsx31(Activity2, { className: "h-5 w-5" }) }),
2270
+ /* @__PURE__ */ jsxs28("div", { className: "flex flex-col", children: [
2271
+ /* @__PURE__ */ jsx31("h3", { className: "font-semibold", children: displayName }),
2272
+ /* @__PURE__ */ jsx31("p", { className: "text-xs text-gray-500", children: meter.id })
2164
2273
  ] })
2165
2274
  ] }),
2166
- /* @__PURE__ */ jsxs20(CardContent, { className: "flex flex-col gap-y-4", children: [
2167
- /* @__PURE__ */ jsxs20("div", { children: [
2168
- /* @__PURE__ */ jsx23("p", { className: "text-3xl font-bold", children: currentUsage.toLocaleString() }),
2169
- hasLimit && /* @__PURE__ */ jsxs20("p", { className: "text-sm text-gray-500", children: [
2275
+ /* @__PURE__ */ jsxs28(CardContent, { className: "flex flex-col gap-y-4", children: [
2276
+ /* @__PURE__ */ jsxs28("div", { children: [
2277
+ /* @__PURE__ */ jsx31("p", { className: "text-3xl font-bold", children: currentUsage.toLocaleString() }),
2278
+ hasLimit && /* @__PURE__ */ jsxs28("p", { className: "text-sm text-gray-500", children: [
2170
2279
  "of ",
2171
2280
  limit.toLocaleString(),
2172
2281
  " used"
2173
2282
  ] })
2174
2283
  ] }),
2175
- hasLimit ? /* @__PURE__ */ jsxs20("div", { className: "flex flex-col gap-y-2", children: [
2176
- /* @__PURE__ */ jsx23("div", { className: "h-2 w-full overflow-hidden rounded-full bg-gray-200", children: /* @__PURE__ */ jsx23("div", { className: `h-full transition-all ${progressColor}`, style: { width: `${progressWidth}%` } }) }),
2177
- /* @__PURE__ */ jsxs20("p", { className: "text-sm text-gray-500", children: [
2284
+ hasLimit ? /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-y-2", children: [
2285
+ /* @__PURE__ */ jsx31("div", { className: "h-2 w-full overflow-hidden rounded-full bg-gray-200", children: /* @__PURE__ */ jsx31("div", { className: `h-full transition-all ${progressColor}`, style: { width: `${progressWidth}%` } }) }),
2286
+ /* @__PURE__ */ jsxs28("p", { className: "text-sm text-gray-500", children: [
2178
2287
  percentage?.toFixed(1),
2179
2288
  "% used"
2180
2289
  ] })
2181
- ] }) : /* @__PURE__ */ jsx23("p", { className: "text-sm text-gray-500", children: "No limit set" }),
2182
- summary && summary.start && summary.end && /* @__PURE__ */ jsx23("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsxs20("p", { className: "text-xs text-gray-500", children: [
2290
+ ] }) : /* @__PURE__ */ jsx31("p", { className: "text-sm text-gray-500", children: "No limit set" }),
2291
+ summary && summary.start && summary.end && /* @__PURE__ */ jsx31("div", { className: "border-t pt-3", children: /* @__PURE__ */ jsxs28("p", { className: "text-xs text-gray-500", children: [
2183
2292
  "Period: ",
2184
2293
  formatDate4(summary.start),
2185
2294
  " - ",
@@ -2191,20 +2300,20 @@ function UsageSummaryCard({ meter, summary }) {
2191
2300
  __name(UsageSummaryCard, "UsageSummaryCard");
2192
2301
 
2193
2302
  // src/features/billing/stripe-usage/components/widgets/UsageSummaryCards.tsx
2194
- import { jsx as jsx24 } from "react/jsx-runtime";
2303
+ import { jsx as jsx32 } from "react/jsx-runtime";
2195
2304
  function UsageSummaryCards({ meters, summaries }) {
2196
- return /* @__PURE__ */ jsx24("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3", children: meters.map((meter) => /* @__PURE__ */ jsx24(UsageSummaryCard, { meter, summary: summaries[meter.id] || null }, meter.id)) });
2305
+ return /* @__PURE__ */ jsx32("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3", children: meters.map((meter) => /* @__PURE__ */ jsx32(UsageSummaryCard, { meter, summary: summaries[meter.id] || null }, meter.id)) });
2197
2306
  }
2198
2307
  __name(UsageSummaryCards, "UsageSummaryCards");
2199
2308
 
2200
2309
  // src/features/billing/stripe-usage/components/containers/UsageContainer.tsx
2201
- import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
2310
+ import { jsx as jsx33, jsxs as jsxs29 } from "react/jsx-runtime";
2202
2311
  function UsageContainer() {
2203
- const [meters, setMeters] = useState13([]);
2204
- const [summaries, setSummaries] = useState13({});
2205
- const [loading, setLoading] = useState13(true);
2206
- const [subscriptions, setSubscriptions] = useState13([]);
2207
- useEffect7(() => {
2312
+ const [meters, setMeters] = useState12([]);
2313
+ const [summaries, setSummaries] = useState12({});
2314
+ const [loading, setLoading] = useState12(true);
2315
+ const [subscriptions, setSubscriptions] = useState12([]);
2316
+ useEffect8(() => {
2208
2317
  loadUsageData();
2209
2318
  }, []);
2210
2319
  const loadUsageData = /* @__PURE__ */ __name(async () => {
@@ -2248,27 +2357,27 @@ function UsageContainer() {
2248
2357
  return null;
2249
2358
  }
2250
2359
  if (loading) {
2251
- return /* @__PURE__ */ jsx25("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: "Loading usage data..." }) });
2360
+ return /* @__PURE__ */ jsx33("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx33("p", { className: "text-muted-foreground", children: "Loading usage data..." }) });
2252
2361
  }
2253
- return /* @__PURE__ */ jsxs21("div", { className: "flex w-full flex-col gap-y-6", children: [
2254
- /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-x-3", children: [
2255
- /* @__PURE__ */ jsx25(Activity3, { className: "h-8 w-8" }),
2256
- /* @__PURE__ */ jsx25("h1", { className: "text-3xl font-bold", children: "Usage Tracking" })
2362
+ return /* @__PURE__ */ jsxs29("div", { className: "flex w-full flex-col gap-y-6", children: [
2363
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-x-3", children: [
2364
+ /* @__PURE__ */ jsx33(Activity3, { className: "h-8 w-8" }),
2365
+ /* @__PURE__ */ jsx33("h1", { className: "text-3xl font-bold", children: "Usage Tracking" })
2257
2366
  ] }),
2258
- meters.length === 0 && /* @__PURE__ */ jsxs21("div", { className: "bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 p-12", children: [
2259
- /* @__PURE__ */ jsx25(Activity3, { className: "text-muted-foreground h-16 w-16" }),
2260
- /* @__PURE__ */ jsxs21("div", { className: "text-center", children: [
2261
- /* @__PURE__ */ jsx25("h3", { className: "mb-2 text-xl font-semibold", children: "No usage meters configured" }),
2262
- /* @__PURE__ */ jsx25("p", { className: "text-muted-foreground", children: "Usage tracking will appear here when you have metered subscriptions with configured meters." })
2367
+ meters.length === 0 && /* @__PURE__ */ jsxs29("div", { className: "bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed border-gray-300 p-12", children: [
2368
+ /* @__PURE__ */ jsx33(Activity3, { className: "text-muted-foreground h-16 w-16" }),
2369
+ /* @__PURE__ */ jsxs29("div", { className: "text-center", children: [
2370
+ /* @__PURE__ */ jsx33("h3", { className: "mb-2 text-xl font-semibold", children: "No usage meters configured" }),
2371
+ /* @__PURE__ */ jsx33("p", { className: "text-muted-foreground", children: "Usage tracking will appear here when you have metered subscriptions with configured meters." })
2263
2372
  ] })
2264
2373
  ] }),
2265
- meters.length > 0 && /* @__PURE__ */ jsx25(UsageSummaryCards, { meters, summaries })
2374
+ meters.length > 0 && /* @__PURE__ */ jsx33(UsageSummaryCards, { meters, summaries })
2266
2375
  ] });
2267
2376
  }
2268
2377
  __name(UsageContainer, "UsageContainer");
2269
2378
 
2270
2379
  // src/features/billing/stripe-usage/components/lists/UsageHistoryTable.tsx
2271
- import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
2380
+ import { jsx as jsx34, jsxs as jsxs30 } from "react/jsx-runtime";
2272
2381
  function formatDateTime(date) {
2273
2382
  if (!date) return "N/A";
2274
2383
  const dateObj = typeof date === "string" ? new Date(date) : date;
@@ -2287,25 +2396,25 @@ function formatDateTime(date) {
2287
2396
  __name(formatDateTime, "formatDateTime");
2288
2397
  function UsageHistoryTable({ usageRecords }) {
2289
2398
  if (usageRecords.length === 0) {
2290
- return /* @__PURE__ */ jsx26("div", { className: "rounded-lg border p-8 text-center", children: /* @__PURE__ */ jsx26("p", { className: "text-muted-foreground", children: "No usage history available." }) });
2399
+ return /* @__PURE__ */ jsx34("div", { className: "rounded-lg border p-8 text-center", children: /* @__PURE__ */ jsx34("p", { className: "text-muted-foreground", children: "No usage history available." }) });
2291
2400
  }
2292
- return /* @__PURE__ */ jsxs22("div", { className: "flex w-full flex-col gap-y-4", children: [
2293
- /* @__PURE__ */ jsx26("h2", { className: "text-xl font-semibold", children: "Usage History" }),
2294
- /* @__PURE__ */ jsx26("div", { className: "overflow-hidden rounded-lg border", children: /* @__PURE__ */ jsxs22(Table, { children: [
2295
- /* @__PURE__ */ jsx26(TableHeader, { className: "bg-muted", children: /* @__PURE__ */ jsxs22(TableRow, { children: [
2296
- /* @__PURE__ */ jsx26(TableHead, { children: "Date & Time" }),
2297
- /* @__PURE__ */ jsx26(TableHead, { children: "Meter Event" }),
2298
- /* @__PURE__ */ jsx26(TableHead, { className: "text-right", children: "Quantity" }),
2299
- /* @__PURE__ */ jsx26(TableHead, { children: "Event ID" })
2401
+ return /* @__PURE__ */ jsxs30("div", { className: "flex w-full flex-col gap-y-4", children: [
2402
+ /* @__PURE__ */ jsx34("h2", { className: "text-xl font-semibold", children: "Usage History" }),
2403
+ /* @__PURE__ */ jsx34("div", { className: "overflow-hidden rounded-lg border", children: /* @__PURE__ */ jsxs30(Table, { children: [
2404
+ /* @__PURE__ */ jsx34(TableHeader, { className: "bg-muted", children: /* @__PURE__ */ jsxs30(TableRow, { children: [
2405
+ /* @__PURE__ */ jsx34(TableHead, { children: "Date & Time" }),
2406
+ /* @__PURE__ */ jsx34(TableHead, { children: "Meter Event" }),
2407
+ /* @__PURE__ */ jsx34(TableHead, { className: "text-right", children: "Quantity" }),
2408
+ /* @__PURE__ */ jsx34(TableHead, { children: "Event ID" })
2300
2409
  ] }) }),
2301
- /* @__PURE__ */ jsx26(TableBody, { children: usageRecords.map((record) => {
2410
+ /* @__PURE__ */ jsx34(TableBody, { children: usageRecords.map((record) => {
2302
2411
  const dateTime = formatDateTime(record.timestamp);
2303
2412
  const quantity = record.quantity.toLocaleString();
2304
- return /* @__PURE__ */ jsxs22(TableRow, { children: [
2305
- /* @__PURE__ */ jsx26(TableCell, { className: "font-medium", children: dateTime }),
2306
- /* @__PURE__ */ jsx26(TableCell, { className: "text-muted-foreground", children: record.meterEventName }),
2307
- /* @__PURE__ */ jsx26(TableCell, { className: "text-right font-medium", children: quantity }),
2308
- /* @__PURE__ */ jsx26(TableCell, { className: "text-muted-foreground text-sm font-mono", children: record.stripeEventId })
2413
+ return /* @__PURE__ */ jsxs30(TableRow, { children: [
2414
+ /* @__PURE__ */ jsx34(TableCell, { className: "font-medium", children: dateTime }),
2415
+ /* @__PURE__ */ jsx34(TableCell, { className: "text-muted-foreground", children: record.meterEventName }),
2416
+ /* @__PURE__ */ jsx34(TableCell, { className: "text-right font-medium", children: quantity }),
2417
+ /* @__PURE__ */ jsx34(TableCell, { className: "text-muted-foreground text-sm font-mono", children: record.stripeEventId })
2309
2418
  ] }, record.id);
2310
2419
  }) })
2311
2420
  ] }) })
@@ -2314,7 +2423,7 @@ function UsageHistoryTable({ usageRecords }) {
2314
2423
  __name(UsageHistoryTable, "UsageHistoryTable");
2315
2424
 
2316
2425
  // src/features/billing/components/modals/BillingDetailModal.tsx
2317
- import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
2426
+ import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
2318
2427
  function BillingDetailModal({
2319
2428
  open,
2320
2429
  onOpenChange,
@@ -2322,25 +2431,25 @@ function BillingDetailModal({
2322
2431
  children,
2323
2432
  className
2324
2433
  }) {
2325
- return /* @__PURE__ */ jsx27(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs23(DialogContent, { className: className ?? "max-w-4xl max-h-[90vh] overflow-y-auto", children: [
2326
- /* @__PURE__ */ jsx27(DialogHeader, { children: /* @__PURE__ */ jsx27(DialogTitle, { children: title }) }),
2434
+ return /* @__PURE__ */ jsx35(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs31(DialogContent, { className: className ?? "max-w-4xl max-h-[90vh] overflow-y-auto", children: [
2435
+ /* @__PURE__ */ jsx35(DialogHeader, { children: /* @__PURE__ */ jsx35(DialogTitle, { children: title }) }),
2327
2436
  children
2328
2437
  ] }) });
2329
2438
  }
2330
2439
  __name(BillingDetailModal, "BillingDetailModal");
2331
2440
 
2332
2441
  // src/features/billing/components/widgets/BillingAlertBanner.tsx
2333
- import { AlertCircle } from "lucide-react";
2334
- import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
2442
+ import { AlertCircle as AlertCircle2 } from "lucide-react";
2443
+ import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
2335
2444
  function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }) {
2336
2445
  if (subscription.status === "past_due" /* PAST_DUE */) {
2337
- return /* @__PURE__ */ jsxs24("div", { className: "bg-red-50 border border-red-200 rounded-lg p-4 flex items-start gap-x-3", children: [
2338
- /* @__PURE__ */ jsx28(AlertCircle, { className: "h-5 w-5 text-red-600 mt-0.5" }),
2339
- /* @__PURE__ */ jsxs24("div", { className: "flex-1", children: [
2340
- /* @__PURE__ */ jsx28("h3", { className: "font-semibold text-red-900", children: "Payment Failed" }),
2341
- /* @__PURE__ */ jsx28("p", { className: "text-sm text-red-700 mt-1", children: "Your last payment failed. Please update your payment method to avoid service interruption." })
2446
+ return /* @__PURE__ */ jsxs32("div", { className: "bg-red-50 border border-red-200 rounded-lg p-4 flex items-start gap-x-3", children: [
2447
+ /* @__PURE__ */ jsx36(AlertCircle2, { className: "h-5 w-5 text-red-600 mt-0.5" }),
2448
+ /* @__PURE__ */ jsxs32("div", { className: "flex-1", children: [
2449
+ /* @__PURE__ */ jsx36("h3", { className: "font-semibold text-red-900", children: "Payment Failed" }),
2450
+ /* @__PURE__ */ jsx36("p", { className: "text-sm text-red-700 mt-1", children: "Your last payment failed. Please update your payment method to avoid service interruption." })
2342
2451
  ] }),
2343
- onUpdatePayment && /* @__PURE__ */ jsx28(Button, { variant: "outline", size: "sm", onClick: onUpdatePayment, className: "border-red-300 text-red-700", children: "Update Payment Method" })
2452
+ onUpdatePayment && /* @__PURE__ */ jsx36(Button, { variant: "outline", size: "sm", onClick: onUpdatePayment, className: "border-red-300 text-red-700", children: "Update Payment Method" })
2344
2453
  ] });
2345
2454
  }
2346
2455
  if (subscription.status === "trialing" /* TRIALING */ && subscription.trialEnd) {
@@ -2348,11 +2457,11 @@ function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }) {
2348
2457
  const now = /* @__PURE__ */ new Date();
2349
2458
  const daysRemaining = Math.ceil((trialEnd.getTime() - now.getTime()) / (1e3 * 60 * 60 * 24));
2350
2459
  if (daysRemaining <= 7) {
2351
- return /* @__PURE__ */ jsxs24("div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-4 flex items-start gap-x-3", children: [
2352
- /* @__PURE__ */ jsx28(AlertCircle, { className: "h-5 w-5 text-yellow-600 mt-0.5" }),
2353
- /* @__PURE__ */ jsxs24("div", { className: "flex-1", children: [
2354
- /* @__PURE__ */ jsx28("h3", { className: "font-semibold text-yellow-900", children: "Trial Ending Soon" }),
2355
- /* @__PURE__ */ jsxs24("p", { className: "text-sm text-yellow-700 mt-1", children: [
2460
+ return /* @__PURE__ */ jsxs32("div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-4 flex items-start gap-x-3", children: [
2461
+ /* @__PURE__ */ jsx36(AlertCircle2, { className: "h-5 w-5 text-yellow-600 mt-0.5" }),
2462
+ /* @__PURE__ */ jsxs32("div", { className: "flex-1", children: [
2463
+ /* @__PURE__ */ jsx36("h3", { className: "font-semibold text-yellow-900", children: "Trial Ending Soon" }),
2464
+ /* @__PURE__ */ jsxs32("p", { className: "text-sm text-yellow-700 mt-1", children: [
2356
2465
  "Your trial ends in ",
2357
2466
  daysRemaining,
2358
2467
  " ",
@@ -2360,7 +2469,7 @@ function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }) {
2360
2469
  ". Add a payment method to continue your subscription."
2361
2470
  ] })
2362
2471
  ] }),
2363
- onAddPayment && /* @__PURE__ */ jsx28(Button, { variant: "outline", size: "sm", onClick: onAddPayment, className: "border-yellow-300 text-yellow-700", children: "Add Payment Method" })
2472
+ onAddPayment && /* @__PURE__ */ jsx36(Button, { variant: "outline", size: "sm", onClick: onAddPayment, className: "border-yellow-300 text-yellow-700", children: "Add Payment Method" })
2364
2473
  ] });
2365
2474
  }
2366
2475
  }
@@ -2369,9 +2478,9 @@ function BillingAlertBanner({ subscription, onUpdatePayment, onAddPayment }) {
2369
2478
  __name(BillingAlertBanner, "BillingAlertBanner");
2370
2479
 
2371
2480
  // src/features/billing/components/containers/BillingDashboardContainer.tsx
2372
- import { Fragment as Fragment6, jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
2481
+ import { Fragment as Fragment6, jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
2373
2482
  function BillingDashboardContainer() {
2374
- const [data, setData] = useState14({
2483
+ const [data, setData] = useState13({
2375
2484
  customer: null,
2376
2485
  subscriptions: [],
2377
2486
  paymentMethods: [],
@@ -2379,27 +2488,35 @@ function BillingDashboardContainer() {
2379
2488
  meters: [],
2380
2489
  meterSummaries: {}
2381
2490
  });
2382
- const [loading, setLoading] = useState14({
2491
+ const [loading, setLoading] = useState13({
2383
2492
  customer: true,
2384
2493
  subscriptions: true,
2385
2494
  paymentMethods: true,
2386
2495
  invoices: true,
2387
2496
  usage: true
2388
2497
  });
2389
- const [errors, setErrors] = useState14({
2498
+ const [errors, setErrors] = useState13({
2390
2499
  customer: null,
2391
2500
  subscriptions: null,
2392
2501
  paymentMethods: null,
2393
2502
  invoices: null,
2394
2503
  usage: null
2395
2504
  });
2396
- const [activeModal, setActiveModal] = useState14(null);
2397
- const [noCustomerExists, setNoCustomerExists] = useState14(false);
2398
- const [creatingCustomer, setCreatingCustomer] = useState14(false);
2399
- const hasMeteredSubscriptions = useCallback2(() => {
2505
+ const [activeModal, setActiveModal] = useState13(null);
2506
+ const [noCustomerExists, setNoCustomerExists] = useState13(false);
2507
+ const [creatingCustomer, setCreatingCustomer] = useState13(false);
2508
+ const searchParams = useSearchParams();
2509
+ const [showWizard, setShowWizard] = useState13(false);
2510
+ const [editingSubscription, setEditingSubscription] = useState13(null);
2511
+ const hasMeteredSubscriptions = useCallback4(() => {
2400
2512
  return data.subscriptions.some((sub) => sub.price?.recurring?.usageType === "metered");
2401
2513
  }, [data.subscriptions]);
2402
- const fetchAllData = useCallback2(async () => {
2514
+ const hasActiveRecurringSubscription = useMemo3(() => {
2515
+ return data.subscriptions.some(
2516
+ (sub) => (sub.status === "active" /* ACTIVE */ || sub.status === "trialing" /* TRIALING */) && sub.price?.priceType === "recurring"
2517
+ );
2518
+ }, [data.subscriptions]);
2519
+ const fetchAllData = useCallback4(async () => {
2403
2520
  setNoCustomerExists(false);
2404
2521
  let customer = null;
2405
2522
  try {
@@ -2518,7 +2635,7 @@ function BillingDashboardContainer() {
2518
2635
  setLoading((prev) => ({ ...prev, usage: false }));
2519
2636
  }
2520
2637
  }, "fetchUsageData");
2521
- const refreshData = useCallback2(async () => {
2638
+ const refreshData = useCallback4(async () => {
2522
2639
  setLoading({
2523
2640
  customer: true,
2524
2641
  subscriptions: true,
@@ -2528,9 +2645,25 @@ function BillingDashboardContainer() {
2528
2645
  });
2529
2646
  await fetchAllData();
2530
2647
  }, [fetchAllData]);
2531
- useEffect8(() => {
2648
+ const handleOpenWizard = useCallback4((subscription) => {
2649
+ setEditingSubscription(subscription || null);
2650
+ setShowWizard(true);
2651
+ }, []);
2652
+ const handleWizardClose = useCallback4(() => {
2653
+ setShowWizard(false);
2654
+ setEditingSubscription(null);
2655
+ refreshData();
2656
+ }, [refreshData]);
2657
+ useEffect9(() => {
2532
2658
  fetchAllData();
2533
2659
  }, [fetchAllData]);
2660
+ useEffect9(() => {
2661
+ const action = searchParams.get("action");
2662
+ if (action === "subscribe") {
2663
+ setShowWizard(true);
2664
+ window.history.replaceState({}, "", window.location.pathname);
2665
+ }
2666
+ }, [searchParams]);
2534
2667
  const criticalSubscriptions = data.subscriptions.filter(
2535
2668
  (sub) => sub.status === "past_due" /* PAST_DUE */ || sub.status === "trialing" /* TRIALING */ && sub.trialEnd && new Date(sub.trialEnd).getTime() - (/* @__PURE__ */ new Date()).getTime() <= 7 * 24 * 60 * 60 * 1e3
2536
2669
  );
@@ -2555,26 +2688,26 @@ function BillingDashboardContainer() {
2555
2688
  }
2556
2689
  }, "getModalTitle");
2557
2690
  const isInitialLoading = loading.customer && !noCustomerExists && !data.customer;
2558
- return /* @__PURE__ */ jsxs25("div", { className: "flex w-full flex-col gap-y-6", children: [
2559
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-x-3", children: [
2560
- /* @__PURE__ */ jsx29(Wallet2, { className: "h-8 w-8" }),
2561
- /* @__PURE__ */ jsx29("h1", { className: "text-3xl font-bold", children: "Billing" })
2691
+ return /* @__PURE__ */ jsxs33("div", { className: "flex w-full flex-col gap-y-6", children: [
2692
+ /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-x-3", children: [
2693
+ /* @__PURE__ */ jsx37(Wallet2, { className: "h-8 w-8" }),
2694
+ /* @__PURE__ */ jsx37("h1", { className: "text-3xl font-bold", children: "Billing" })
2562
2695
  ] }),
2563
- isInitialLoading && /* @__PURE__ */ jsx29(Card, { children: /* @__PURE__ */ jsx29(CardContent, { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx29(Loader23, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }) }),
2564
- noCustomerExists && !isInitialLoading && /* @__PURE__ */ jsxs25(Card, { children: [
2565
- /* @__PURE__ */ jsxs25(CardHeader, { className: "text-center", children: [
2566
- /* @__PURE__ */ jsx29("div", { className: "mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx29(CreditCard4, { className: "h-8 w-8 text-primary" }) }),
2567
- /* @__PURE__ */ jsx29(CardTitle, { children: "Set Up Billing" }),
2568
- /* @__PURE__ */ jsx29(CardDescription, { children: "Your company doesn't have a billing account yet. Set one up to manage subscriptions, payment methods, and view invoices." })
2696
+ isInitialLoading && /* @__PURE__ */ jsx37(Card, { children: /* @__PURE__ */ jsx37(CardContent, { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx37(Loader22, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }) }),
2697
+ noCustomerExists && !isInitialLoading && /* @__PURE__ */ jsxs33(Card, { children: [
2698
+ /* @__PURE__ */ jsxs33(CardHeader, { className: "text-center", children: [
2699
+ /* @__PURE__ */ jsx37("div", { className: "mx-auto mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx37(CreditCard4, { className: "h-8 w-8 text-primary" }) }),
2700
+ /* @__PURE__ */ jsx37(CardTitle, { children: "Set Up Billing" }),
2701
+ /* @__PURE__ */ jsx37(CardDescription, { children: "Your company doesn't have a billing account yet. Set one up to manage subscriptions, payment methods, and view invoices." })
2569
2702
  ] }),
2570
- /* @__PURE__ */ jsx29(CardContent, { className: "flex justify-center pb-8", children: /* @__PURE__ */ jsx29(Button, { onClick: handleCreateCustomer, disabled: creatingCustomer, size: "lg", children: creatingCustomer ? /* @__PURE__ */ jsxs25(Fragment6, { children: [
2571
- /* @__PURE__ */ jsx29(Loader23, { className: "mr-2 h-4 w-4 animate-spin" }),
2703
+ /* @__PURE__ */ jsx37(CardContent, { className: "flex justify-center pb-8", children: /* @__PURE__ */ jsx37(Button, { onClick: handleCreateCustomer, disabled: creatingCustomer, size: "lg", children: creatingCustomer ? /* @__PURE__ */ jsxs33(Fragment6, { children: [
2704
+ /* @__PURE__ */ jsx37(Loader22, { className: "mr-2 h-4 w-4 animate-spin" }),
2572
2705
  "Setting up..."
2573
2706
  ] }) : "Set Up Billing Account" }) }),
2574
- errors.customer && /* @__PURE__ */ jsx29(CardContent, { className: "pt-0", children: /* @__PURE__ */ jsx29("p", { className: "text-center text-sm text-destructive", children: errors.customer }) })
2707
+ errors.customer && /* @__PURE__ */ jsx37(CardContent, { className: "pt-0", children: /* @__PURE__ */ jsx37("p", { className: "text-center text-sm text-destructive", children: errors.customer }) })
2575
2708
  ] }),
2576
- !noCustomerExists && !isInitialLoading && /* @__PURE__ */ jsxs25(Fragment6, { children: [
2577
- criticalSubscriptions.map((subscription) => /* @__PURE__ */ jsx29(
2709
+ !noCustomerExists && !isInitialLoading && /* @__PURE__ */ jsxs33(Fragment6, { children: [
2710
+ criticalSubscriptions.map((subscription) => /* @__PURE__ */ jsx37(
2578
2711
  BillingAlertBanner,
2579
2712
  {
2580
2713
  subscription,
@@ -2583,17 +2716,23 @@ function BillingDashboardContainer() {
2583
2716
  },
2584
2717
  subscription.id
2585
2718
  )),
2586
- /* @__PURE__ */ jsxs25("div", { className: "grid gap-4 md:grid-cols-2", children: [
2587
- /* @__PURE__ */ jsx29(
2719
+ /* @__PURE__ */ jsxs33("div", { className: "grid gap-4 md:grid-cols-2", children: [
2720
+ /* @__PURE__ */ jsx37(
2588
2721
  SubscriptionSummaryCard,
2589
2722
  {
2590
2723
  subscriptions: data.subscriptions,
2591
2724
  loading: loading.subscriptions,
2592
2725
  error: errors.subscriptions || void 0,
2593
- onManageClick: () => setActiveModal("subscriptions")
2726
+ onManageClick: () => {
2727
+ if (data.subscriptions.length === 0) {
2728
+ setShowWizard(true);
2729
+ } else {
2730
+ setActiveModal("subscriptions");
2731
+ }
2732
+ }
2594
2733
  }
2595
2734
  ),
2596
- /* @__PURE__ */ jsx29(
2735
+ /* @__PURE__ */ jsx37(
2597
2736
  PaymentMethodSummaryCard,
2598
2737
  {
2599
2738
  paymentMethods: data.paymentMethods,
@@ -2603,7 +2742,7 @@ function BillingDashboardContainer() {
2603
2742
  onManageClick: () => setActiveModal("payment-methods")
2604
2743
  }
2605
2744
  ),
2606
- /* @__PURE__ */ jsx29(
2745
+ /* @__PURE__ */ jsx37(
2607
2746
  CustomerInfoCard,
2608
2747
  {
2609
2748
  customer: data.customer,
@@ -2611,7 +2750,7 @@ function BillingDashboardContainer() {
2611
2750
  error: errors.customer || void 0
2612
2751
  }
2613
2752
  ),
2614
- /* @__PURE__ */ jsx29(
2753
+ /* @__PURE__ */ jsx37(
2615
2754
  InvoicesSummaryCard,
2616
2755
  {
2617
2756
  invoices: data.invoices,
@@ -2620,7 +2759,7 @@ function BillingDashboardContainer() {
2620
2759
  onViewAllClick: () => setActiveModal("invoices")
2621
2760
  }
2622
2761
  ),
2623
- hasMeteredSubscriptions() && /* @__PURE__ */ jsx29(
2762
+ hasMeteredSubscriptions() && /* @__PURE__ */ jsx37(
2624
2763
  BillingUsageSummaryCard,
2625
2764
  {
2626
2765
  meters: data.meters,
@@ -2631,40 +2770,50 @@ function BillingDashboardContainer() {
2631
2770
  }
2632
2771
  )
2633
2772
  ] }),
2634
- /* @__PURE__ */ jsx29(
2773
+ /* @__PURE__ */ jsx37(
2635
2774
  BillingDetailModal,
2636
2775
  {
2637
2776
  open: activeModal === "subscriptions",
2638
2777
  onOpenChange: handleModalClose,
2639
2778
  title: getModalTitle("subscriptions"),
2640
- children: /* @__PURE__ */ jsx29(SubscriptionsContainer, {})
2779
+ children: /* @__PURE__ */ jsx37(SubscriptionsContainer, { onOpenWizard: handleOpenWizard })
2641
2780
  }
2642
2781
  ),
2643
- /* @__PURE__ */ jsx29(
2782
+ /* @__PURE__ */ jsx37(
2644
2783
  BillingDetailModal,
2645
2784
  {
2646
2785
  open: activeModal === "payment-methods",
2647
2786
  onOpenChange: handleModalClose,
2648
2787
  title: getModalTitle("payment-methods"),
2649
- children: /* @__PURE__ */ jsx29(PaymentMethodsContainer, {})
2788
+ children: /* @__PURE__ */ jsx37(PaymentMethodsContainer, {})
2650
2789
  }
2651
2790
  ),
2652
- /* @__PURE__ */ jsx29(
2791
+ /* @__PURE__ */ jsx37(
2653
2792
  BillingDetailModal,
2654
2793
  {
2655
2794
  open: activeModal === "invoices",
2656
2795
  onOpenChange: handleModalClose,
2657
2796
  title: getModalTitle("invoices"),
2658
- children: /* @__PURE__ */ jsx29(InvoicesContainer, {})
2797
+ children: /* @__PURE__ */ jsx37(InvoicesContainer, {})
2659
2798
  }
2660
2799
  ),
2661
- /* @__PURE__ */ jsx29(
2800
+ /* @__PURE__ */ jsx37(
2662
2801
  BillingDetailModal,
2663
2802
  {
2664
2803
  open: activeModal === "usage",
2665
2804
  onOpenChange: handleModalClose,
2666
2805
  title: getModalTitle("usage"),
2667
- children: /* @__PURE__ */ jsx29(UsageContainer, {})
2806
+ children: /* @__PURE__ */ jsx37(UsageContainer, {})
2807
+ }
2808
+ ),
2809
+ /* @__PURE__ */ jsx37(
2810
+ SubscriptionWizard,
2811
+ {
2812
+ open: showWizard,
2813
+ onOpenChange: (open) => !open && handleWizardClose(),
2814
+ onSuccess: refreshData,
2815
+ hasActiveRecurringSubscription,
2816
+ subscription: editingSubscription ?? void 0
2668
2817
  }
2669
2818
  )
2670
2819
  ] })
@@ -2675,8 +2824,8 @@ __name(BillingDashboardContainer, "BillingDashboardContainer");
2675
2824
  // src/features/billing/components/providers/StripeProvider.tsx
2676
2825
  import { Elements } from "@stripe/react-stripe-js";
2677
2826
  import { loadStripe } from "@stripe/stripe-js";
2678
- import { useMemo } from "react";
2679
- import { Fragment as Fragment7, jsx as jsx30 } from "react/jsx-runtime";
2827
+ import { useMemo as useMemo4 } from "react";
2828
+ import { Fragment as Fragment7, jsx as jsx38 } from "react/jsx-runtime";
2680
2829
  var stripePromiseCache = null;
2681
2830
  function getStripePromise(publishableKey) {
2682
2831
  if (!publishableKey) {
@@ -2692,12 +2841,12 @@ function getStripePromise(publishableKey) {
2692
2841
  __name(getStripePromise, "getStripePromise");
2693
2842
  function StripeProvider({ children }) {
2694
2843
  const publishableKey = getStripePublishableKey();
2695
- const stripePromise = useMemo(() => getStripePromise(publishableKey), [publishableKey]);
2696
- const options = useMemo(() => ({}), []);
2844
+ const stripePromise = useMemo4(() => getStripePromise(publishableKey), [publishableKey]);
2845
+ const options = useMemo4(() => ({}), []);
2697
2846
  if (!publishableKey) {
2698
- return /* @__PURE__ */ jsx30(Fragment7, { children });
2847
+ return /* @__PURE__ */ jsx38(Fragment7, { children });
2699
2848
  }
2700
- return /* @__PURE__ */ jsx30(Elements, { stripe: stripePromise, options, children });
2849
+ return /* @__PURE__ */ jsx38(Elements, { stripe: stripePromise, options, children });
2701
2850
  }
2702
2851
  __name(StripeProvider, "StripeProvider");
2703
2852
  function isStripeConfigured() {
@@ -2707,14 +2856,14 @@ __name(isStripeConfigured, "isStripeConfigured");
2707
2856
 
2708
2857
  // src/features/billing/stripe-price/components/forms/PriceEditor.tsx
2709
2858
  import { zodResolver as zodResolver2 } from "@hookform/resolvers/zod";
2710
- import { AlertCircle as AlertCircle2, PlusIcon, XIcon } from "lucide-react";
2711
- import { useState as useState15 } from "react";
2859
+ import { AlertCircle as AlertCircle3, PlusIcon, XIcon } from "lucide-react";
2860
+ import { useEffect as useEffect10, useState as useState14 } from "react";
2712
2861
  import { useForm as useForm2 } from "react-hook-form";
2713
- import { v4 as v43 } from "uuid";
2862
+ import { v4 } from "uuid";
2714
2863
  import { z as z2 } from "zod";
2715
- import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
2864
+ import { jsx as jsx39, jsxs as jsxs34 } from "react/jsx-runtime";
2716
2865
  function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2717
- const [isSubmitting, setIsSubmitting] = useState15(false);
2866
+ const [isSubmitting, setIsSubmitting] = useState14(false);
2718
2867
  const formSchema2 = z2.object({
2719
2868
  unitAmount: z2.preprocess(
2720
2869
  (val) => typeof val === "string" ? parseFloat(val) : val,
@@ -2750,6 +2899,22 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2750
2899
  token: price?.token?.toString() ?? ""
2751
2900
  }
2752
2901
  });
2902
+ useEffect10(() => {
2903
+ if (open) {
2904
+ form.reset({
2905
+ unitAmount: price?.unitAmount ? price.unitAmount / 100 : 0,
2906
+ currency: price?.currency || "usd",
2907
+ interval: price?.priceType === "one_time" ? "one_time" : price?.recurring?.interval || "month",
2908
+ intervalCount: price?.recurring?.intervalCount || 1,
2909
+ usageType: price?.recurring?.usageType || "licensed",
2910
+ nickname: price?.nickname || "",
2911
+ active: price?.active ?? true,
2912
+ description: price?.description || "",
2913
+ features: price?.features || [],
2914
+ token: price?.token?.toString() ?? ""
2915
+ });
2916
+ }
2917
+ }, [open, price?.id]);
2753
2918
  const watchInterval = form.watch("interval");
2754
2919
  const isRecurring = watchInterval !== "one_time";
2755
2920
  const onSubmit = /* @__PURE__ */ __name(async (values) => {
@@ -2766,7 +2931,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2766
2931
  });
2767
2932
  } else {
2768
2933
  const createInput = {
2769
- id: v43(),
2934
+ id: v4(),
2770
2935
  productId,
2771
2936
  currency: values.currency,
2772
2937
  unitAmount: unitAmountInCents
@@ -2817,21 +2982,21 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2817
2982
  { id: "licensed", text: "Licensed (per unit)" },
2818
2983
  { id: "metered", text: "Metered (usage-based)" }
2819
2984
  ];
2820
- return /* @__PURE__ */ jsx31(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs26(DialogContent, { className: "max-w-2xl", children: [
2821
- /* @__PURE__ */ jsxs26(DialogHeader, { children: [
2822
- /* @__PURE__ */ jsx31(DialogTitle, { children: isEditMode ? "Edit Price" : "Create Price" }),
2823
- /* @__PURE__ */ jsx31(DialogDescription, { children: isEditMode ? "Update the price details. Note: Only nickname and active status can be changed." : "Create a new price for this product" })
2985
+ return /* @__PURE__ */ jsx39(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs34(DialogContent, { className: "max-w-2xl", children: [
2986
+ /* @__PURE__ */ jsxs34(DialogHeader, { children: [
2987
+ /* @__PURE__ */ jsx39(DialogTitle, { children: isEditMode ? "Edit Price" : "Create Price" }),
2988
+ /* @__PURE__ */ jsx39(DialogDescription, { children: isEditMode ? "Update the price details. Note: Only nickname and active status can be changed." : "Create a new price for this product" })
2824
2989
  ] }),
2825
- isEditMode && /* @__PURE__ */ jsxs26("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4 flex gap-x-3", children: [
2826
- /* @__PURE__ */ jsx31(AlertCircle2, { className: "h-5 w-5 text-blue-600 flex-shrink-0 mt-0.5" }),
2827
- /* @__PURE__ */ jsxs26("div", { className: "text-sm text-blue-800", children: [
2828
- /* @__PURE__ */ jsx31("p", { className: "font-semibold mb-1", children: "Stripe Price Immutability" }),
2829
- /* @__PURE__ */ jsx31("p", { children: "Due to Stripe's architecture, only the nickname and active status can be modified after creation. To change amount, currency, or billing interval, create a new price." })
2990
+ isEditMode && /* @__PURE__ */ jsxs34("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-4 flex gap-x-3", children: [
2991
+ /* @__PURE__ */ jsx39(AlertCircle3, { className: "h-5 w-5 text-blue-600 flex-shrink-0 mt-0.5" }),
2992
+ /* @__PURE__ */ jsxs34("div", { className: "text-sm text-blue-800", children: [
2993
+ /* @__PURE__ */ jsx39("p", { className: "font-semibold mb-1", children: "Stripe Price Immutability" }),
2994
+ /* @__PURE__ */ jsx39("p", { children: "Due to Stripe's architecture, only the nickname and active status can be modified after creation. To change amount, currency, or billing interval, create a new price." })
2830
2995
  ] })
2831
2996
  ] }),
2832
- /* @__PURE__ */ jsx31(Form, { ...form, children: /* @__PURE__ */ jsxs26("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
2833
- /* @__PURE__ */ jsxs26("div", { className: "grid grid-cols-2 gap-x-4", children: [
2834
- /* @__PURE__ */ jsx31(
2997
+ /* @__PURE__ */ jsx39(Form, { ...form, children: /* @__PURE__ */ jsxs34("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
2998
+ /* @__PURE__ */ jsxs34("div", { className: "grid grid-cols-2 gap-x-4", children: [
2999
+ /* @__PURE__ */ jsx39(
2835
3000
  FormInput,
2836
3001
  {
2837
3002
  form,
@@ -2842,9 +3007,9 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2842
3007
  isRequired: true
2843
3008
  }
2844
3009
  ),
2845
- /* @__PURE__ */ jsx31(FormSelect, { form, id: "currency", name: "Currency", values: currencyOptions, disabled: isEditMode })
3010
+ /* @__PURE__ */ jsx39(FormSelect, { form, id: "currency", name: "Currency", values: currencyOptions, disabled: isEditMode })
2846
3011
  ] }),
2847
- /* @__PURE__ */ jsx31(
3012
+ /* @__PURE__ */ jsx39(
2848
3013
  FormSelect,
2849
3014
  {
2850
3015
  form,
@@ -2854,8 +3019,8 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2854
3019
  disabled: isEditMode
2855
3020
  }
2856
3021
  ),
2857
- isRecurring && /* @__PURE__ */ jsxs26("div", { className: "grid grid-cols-2 gap-x-4", children: [
2858
- /* @__PURE__ */ jsx31(
3022
+ isRecurring && /* @__PURE__ */ jsxs34("div", { className: "grid grid-cols-2 gap-x-4", children: [
3023
+ /* @__PURE__ */ jsx39(
2859
3024
  FormInput,
2860
3025
  {
2861
3026
  form,
@@ -2866,7 +3031,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2866
3031
  disabled: isEditMode
2867
3032
  }
2868
3033
  ),
2869
- /* @__PURE__ */ jsx31(
3034
+ /* @__PURE__ */ jsx39(
2870
3035
  FormSelect,
2871
3036
  {
2872
3037
  form,
@@ -2877,7 +3042,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2877
3042
  }
2878
3043
  )
2879
3044
  ] }),
2880
- /* @__PURE__ */ jsx31(
3045
+ /* @__PURE__ */ jsx39(
2881
3046
  FormInput,
2882
3047
  {
2883
3048
  form,
@@ -2886,7 +3051,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2886
3051
  placeholder: "e.g., Standard Plan, Pro Tier"
2887
3052
  }
2888
3053
  ),
2889
- /* @__PURE__ */ jsx31(
3054
+ /* @__PURE__ */ jsx39(
2890
3055
  FormTextarea,
2891
3056
  {
2892
3057
  form,
@@ -2896,12 +3061,12 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2896
3061
  className: "min-h-24"
2897
3062
  }
2898
3063
  ),
2899
- /* @__PURE__ */ jsx31(FormInput, { form, id: "token", name: "Token (optional)", placeholder: "Enter token value" }),
2900
- /* @__PURE__ */ jsxs26("div", { className: "space-y-2", children: [
2901
- /* @__PURE__ */ jsx31(Label, { children: "Features (optional)" }),
2902
- /* @__PURE__ */ jsxs26("div", { className: "space-y-2", children: [
2903
- form.watch("features").map((_, index) => /* @__PURE__ */ jsxs26("div", { className: "flex gap-2", children: [
2904
- /* @__PURE__ */ jsx31(
3064
+ /* @__PURE__ */ jsx39(FormInput, { form, id: "token", name: "Token (optional)", placeholder: "Enter token value" }),
3065
+ /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
3066
+ /* @__PURE__ */ jsx39(Label, { children: "Features (optional)" }),
3067
+ /* @__PURE__ */ jsxs34("div", { className: "space-y-2", children: [
3068
+ form.watch("features").map((_, index) => /* @__PURE__ */ jsxs34("div", { className: "flex gap-2", children: [
3069
+ /* @__PURE__ */ jsx39(
2905
3070
  Input,
2906
3071
  {
2907
3072
  ...form.register(`features.${index}`),
@@ -2909,7 +3074,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2909
3074
  className: "flex-1"
2910
3075
  }
2911
3076
  ),
2912
- /* @__PURE__ */ jsx31(
3077
+ /* @__PURE__ */ jsx39(
2913
3078
  Button,
2914
3079
  {
2915
3080
  type: "button",
@@ -2922,11 +3087,11 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2922
3087
  currentFeatures.filter((_2, i) => i !== index)
2923
3088
  );
2924
3089
  },
2925
- children: /* @__PURE__ */ jsx31(XIcon, { className: "h-4 w-4" })
3090
+ children: /* @__PURE__ */ jsx39(XIcon, { className: "h-4 w-4" })
2926
3091
  }
2927
3092
  )
2928
3093
  ] }, index)),
2929
- /* @__PURE__ */ jsxs26(
3094
+ /* @__PURE__ */ jsxs34(
2930
3095
  Button,
2931
3096
  {
2932
3097
  type: "button",
@@ -2938,15 +3103,15 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
2938
3103
  },
2939
3104
  className: "mt-2",
2940
3105
  children: [
2941
- /* @__PURE__ */ jsx31(PlusIcon, { className: "h-4 w-4 mr-2" }),
3106
+ /* @__PURE__ */ jsx39(PlusIcon, { className: "h-4 w-4 mr-2" }),
2942
3107
  "Add Feature"
2943
3108
  ]
2944
3109
  }
2945
3110
  )
2946
3111
  ] })
2947
3112
  ] }),
2948
- /* @__PURE__ */ jsx31(FormCheckbox, { form, id: "active", name: "Active" }),
2949
- /* @__PURE__ */ jsx31(CommonEditorButtons, { isEdit: isEditMode, form, disabled: isSubmitting, setOpen: onOpenChange })
3113
+ /* @__PURE__ */ jsx39(FormCheckbox, { form, id: "active", name: "Active" }),
3114
+ /* @__PURE__ */ jsx39(CommonEditorButtons, { isEdit: isEditMode, form, disabled: isSubmitting, setOpen: onOpenChange })
2950
3115
  ] }) })
2951
3116
  ] }) });
2952
3117
  }
@@ -2954,17 +3119,17 @@ __name(PriceEditor, "PriceEditor");
2954
3119
 
2955
3120
  // src/features/billing/stripe-price/components/lists/PricesList.tsx
2956
3121
  import { Archive, DollarSign, Edit, RotateCcw } from "lucide-react";
2957
- import { useEffect as useEffect9, useState as useState16 } from "react";
2958
- import { jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
3122
+ import { useEffect as useEffect11, useState as useState15 } from "react";
3123
+ import { jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
2959
3124
  function PricesList({ productId, onPricesChange }) {
2960
- const [prices, setPrices] = useState16([]);
2961
- const [loading, setLoading] = useState16(true);
2962
- const [showCreatePrice, setShowCreatePrice] = useState16(false);
2963
- const [editingPrice, setEditingPrice] = useState16(null);
2964
- const [priceToArchive, setPriceToArchive] = useState16(null);
2965
- const [priceToReactivate, setPriceToReactivate] = useState16(null);
2966
- const [archivingPriceId, setArchivingPriceId] = useState16(null);
2967
- const [reactivatingPriceId, setReactivatingPriceId] = useState16(null);
3125
+ const [prices, setPrices] = useState15([]);
3126
+ const [loading, setLoading] = useState15(true);
3127
+ const [showCreatePrice, setShowCreatePrice] = useState15(false);
3128
+ const [editingPrice, setEditingPrice] = useState15(null);
3129
+ const [priceToArchive, setPriceToArchive] = useState15(null);
3130
+ const [priceToReactivate, setPriceToReactivate] = useState15(null);
3131
+ const [archivingPriceId, setArchivingPriceId] = useState15(null);
3132
+ const [reactivatingPriceId, setReactivatingPriceId] = useState15(null);
2968
3133
  const loadPrices = /* @__PURE__ */ __name(async () => {
2969
3134
  setLoading(true);
2970
3135
  try {
@@ -2976,7 +3141,7 @@ function PricesList({ productId, onPricesChange }) {
2976
3141
  setLoading(false);
2977
3142
  }
2978
3143
  }, "loadPrices");
2979
- useEffect9(() => {
3144
+ useEffect11(() => {
2980
3145
  loadPrices();
2981
3146
  }, [productId]);
2982
3147
  const handleArchive = /* @__PURE__ */ __name(async () => {
@@ -3027,27 +3192,27 @@ function PricesList({ productId, onPricesChange }) {
3027
3192
  return "";
3028
3193
  }, "formatInterval");
3029
3194
  if (loading) {
3030
- return /* @__PURE__ */ jsx32("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx32("p", { className: "text-muted-foreground", children: "Loading prices..." }) });
3195
+ return /* @__PURE__ */ jsx40("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx40("p", { className: "text-muted-foreground", children: "Loading prices..." }) });
3031
3196
  }
3032
- return /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-y-4", children: [
3033
- /* @__PURE__ */ jsxs27("div", { className: "flex items-center justify-between mb-4", children: [
3034
- /* @__PURE__ */ jsx32("h4", { className: "text-lg font-semibold", children: "Prices" }),
3035
- /* @__PURE__ */ jsx32(Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
3197
+ return /* @__PURE__ */ jsxs35("div", { className: "flex flex-col gap-y-4", children: [
3198
+ /* @__PURE__ */ jsxs35("div", { className: "flex items-center justify-between mb-4", children: [
3199
+ /* @__PURE__ */ jsx40("h4", { className: "text-lg font-semibold", children: "Prices" }),
3200
+ /* @__PURE__ */ jsx40(Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
3036
3201
  ] }),
3037
- prices.length === 0 && /* @__PURE__ */ jsxs27("div", { className: "bg-background flex flex-col items-center justify-center gap-y-3 rounded-lg border border-dashed p-8", children: [
3038
- /* @__PURE__ */ jsx32(DollarSign, { className: "text-muted-foreground h-12 w-12" }),
3039
- /* @__PURE__ */ jsx32("p", { className: "text-muted-foreground text-sm", children: "No prices yet. Add a price to enable subscriptions." }),
3040
- /* @__PURE__ */ jsx32(Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
3202
+ prices.length === 0 && /* @__PURE__ */ jsxs35("div", { className: "bg-background flex flex-col items-center justify-center gap-y-3 rounded-lg border border-dashed p-8", children: [
3203
+ /* @__PURE__ */ jsx40(DollarSign, { className: "text-muted-foreground h-12 w-12" }),
3204
+ /* @__PURE__ */ jsx40("p", { className: "text-muted-foreground text-sm", children: "No prices yet. Add a price to enable subscriptions." }),
3205
+ /* @__PURE__ */ jsx40(Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
3041
3206
  ] }),
3042
- prices.length > 0 && /* @__PURE__ */ jsx32("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: prices.map((price) => {
3207
+ prices.length > 0 && /* @__PURE__ */ jsx40("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: prices.map((price) => {
3043
3208
  const isArchiving = archivingPriceId === price.id;
3044
3209
  const isReactivating = reactivatingPriceId === price.id;
3045
- return /* @__PURE__ */ jsxs27("div", { className: "border rounded-lg bg-white p-4 hover:shadow-sm transition-shadow", children: [
3046
- /* @__PURE__ */ jsxs27("div", { className: "flex items-start justify-between mb-3", children: [
3047
- /* @__PURE__ */ jsx32(DollarSign, { className: "h-5 w-5 text-primary" }),
3048
- /* @__PURE__ */ jsxs27("div", { className: "flex gap-1", children: [
3049
- /* @__PURE__ */ jsx32(Button, { variant: "ghost", size: "sm", onClick: () => setEditingPrice(price), className: "h-8 w-8 p-0", children: /* @__PURE__ */ jsx32(Edit, { className: "h-4 w-4" }) }),
3050
- price.active ? /* @__PURE__ */ jsx32(
3210
+ return /* @__PURE__ */ jsxs35("div", { className: "border rounded-lg bg-white p-4 hover:shadow-sm transition-shadow", children: [
3211
+ /* @__PURE__ */ jsxs35("div", { className: "flex items-start justify-between mb-3", children: [
3212
+ /* @__PURE__ */ jsx40(DollarSign, { className: "h-5 w-5 text-primary" }),
3213
+ /* @__PURE__ */ jsxs35("div", { className: "flex gap-1", children: [
3214
+ /* @__PURE__ */ jsx40(Button, { variant: "ghost", size: "sm", onClick: () => setEditingPrice(price), className: "h-8 w-8 p-0", children: /* @__PURE__ */ jsx40(Edit, { className: "h-4 w-4" }) }),
3215
+ price.active ? /* @__PURE__ */ jsx40(
3051
3216
  Button,
3052
3217
  {
3053
3218
  variant: "ghost",
@@ -3055,9 +3220,9 @@ function PricesList({ productId, onPricesChange }) {
3055
3220
  onClick: () => setPriceToArchive(price),
3056
3221
  className: "h-8 w-8 p-0",
3057
3222
  disabled: isArchiving,
3058
- children: /* @__PURE__ */ jsx32(Archive, { className: "h-4 w-4" })
3223
+ children: /* @__PURE__ */ jsx40(Archive, { className: "h-4 w-4" })
3059
3224
  }
3060
- ) : /* @__PURE__ */ jsx32(
3225
+ ) : /* @__PURE__ */ jsx40(
3061
3226
  Button,
3062
3227
  {
3063
3228
  variant: "ghost",
@@ -3065,25 +3230,25 @@ function PricesList({ productId, onPricesChange }) {
3065
3230
  onClick: () => setPriceToReactivate(price),
3066
3231
  className: "h-8 w-8 p-0",
3067
3232
  disabled: isReactivating,
3068
- children: /* @__PURE__ */ jsx32(RotateCcw, { className: "h-4 w-4" })
3233
+ children: /* @__PURE__ */ jsx40(RotateCcw, { className: "h-4 w-4" })
3069
3234
  }
3070
3235
  )
3071
3236
  ] })
3072
3237
  ] }),
3073
- /* @__PURE__ */ jsx32("div", { className: "mb-2", children: /* @__PURE__ */ jsxs27("div", { className: "text-2xl font-bold", children: [
3238
+ /* @__PURE__ */ jsx40("div", { className: "mb-2", children: /* @__PURE__ */ jsxs35("div", { className: "text-2xl font-bold", children: [
3074
3239
  formatCurrency(price.unitAmount, price.currency),
3075
3240
  " ",
3076
- /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground text-sm font-normal", children: formatInterval2(price) })
3241
+ /* @__PURE__ */ jsx40("span", { className: "text-muted-foreground text-sm font-normal", children: formatInterval2(price) })
3077
3242
  ] }) }),
3078
- price.metadata?.nickname && /* @__PURE__ */ jsx32("p", { className: "text-sm font-medium mb-2", children: price.metadata.nickname }),
3079
- /* @__PURE__ */ jsxs27("div", { className: "flex flex-wrap gap-2", children: [
3080
- price.active ? /* @__PURE__ */ jsx32("span", { className: "bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium", children: "Active" }) : /* @__PURE__ */ jsx32("span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium", children: "Inactive" }),
3081
- price.recurring?.usageType === "metered" && /* @__PURE__ */ jsx32("span", { className: "bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full font-medium", children: "Metered" }),
3082
- /* @__PURE__ */ jsx32("span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium uppercase", children: price.currency })
3243
+ price.metadata?.nickname && /* @__PURE__ */ jsx40("p", { className: "text-sm font-medium mb-2", children: price.metadata.nickname }),
3244
+ /* @__PURE__ */ jsxs35("div", { className: "flex flex-wrap gap-2", children: [
3245
+ price.active ? /* @__PURE__ */ jsx40("span", { className: "bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium", children: "Active" }) : /* @__PURE__ */ jsx40("span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium", children: "Inactive" }),
3246
+ price.recurring?.usageType === "metered" && /* @__PURE__ */ jsx40("span", { className: "bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full font-medium", children: "Metered" }),
3247
+ /* @__PURE__ */ jsx40("span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium uppercase", children: price.currency })
3083
3248
  ] })
3084
3249
  ] }, price.id);
3085
3250
  }) }),
3086
- showCreatePrice && /* @__PURE__ */ jsx32(
3251
+ showCreatePrice && /* @__PURE__ */ jsx40(
3087
3252
  PriceEditor,
3088
3253
  {
3089
3254
  productId,
@@ -3095,7 +3260,7 @@ function PricesList({ productId, onPricesChange }) {
3095
3260
  }
3096
3261
  }
3097
3262
  ),
3098
- editingPrice && /* @__PURE__ */ jsx32(
3263
+ editingPrice && /* @__PURE__ */ jsx40(
3099
3264
  PriceEditor,
3100
3265
  {
3101
3266
  productId,
@@ -3109,19 +3274,19 @@ function PricesList({ productId, onPricesChange }) {
3109
3274
  }
3110
3275
  }
3111
3276
  ),
3112
- /* @__PURE__ */ jsx32(AlertDialog, { open: !!priceToArchive, onOpenChange: (open) => !open && setPriceToArchive(null), children: /* @__PURE__ */ jsxs27(AlertDialogContent, { children: [
3113
- /* @__PURE__ */ jsxs27(AlertDialogHeader, { children: [
3114
- /* @__PURE__ */ jsx32(AlertDialogTitle, { children: "Archive Price" }),
3115
- /* @__PURE__ */ jsxs27(AlertDialogDescription, { children: [
3277
+ /* @__PURE__ */ jsx40(AlertDialog, { open: !!priceToArchive, onOpenChange: (open) => !open && setPriceToArchive(null), children: /* @__PURE__ */ jsxs35(AlertDialogContent, { children: [
3278
+ /* @__PURE__ */ jsxs35(AlertDialogHeader, { children: [
3279
+ /* @__PURE__ */ jsx40(AlertDialogTitle, { children: "Archive Price" }),
3280
+ /* @__PURE__ */ jsxs35(AlertDialogDescription, { children: [
3116
3281
  "Are you sure you want to archive the price for",
3117
3282
  " ",
3118
3283
  priceToArchive && `${formatCurrency(priceToArchive.unitAmount, priceToArchive.currency)} ${formatInterval2(priceToArchive)}`,
3119
3284
  "? This will prevent new subscriptions but existing ones will continue."
3120
3285
  ] })
3121
3286
  ] }),
3122
- /* @__PURE__ */ jsxs27(AlertDialogFooter, { children: [
3123
- /* @__PURE__ */ jsx32(AlertDialogCancel, { disabled: !!archivingPriceId, children: "Cancel" }),
3124
- /* @__PURE__ */ jsx32(
3287
+ /* @__PURE__ */ jsxs35(AlertDialogFooter, { children: [
3288
+ /* @__PURE__ */ jsx40(AlertDialogCancel, { disabled: !!archivingPriceId, children: "Cancel" }),
3289
+ /* @__PURE__ */ jsx40(
3125
3290
  AlertDialogAction,
3126
3291
  {
3127
3292
  onClick: handleArchive,
@@ -3132,19 +3297,19 @@ function PricesList({ productId, onPricesChange }) {
3132
3297
  )
3133
3298
  ] })
3134
3299
  ] }) }),
3135
- /* @__PURE__ */ jsx32(AlertDialog, { open: !!priceToReactivate, onOpenChange: (open) => !open && setPriceToReactivate(null), children: /* @__PURE__ */ jsxs27(AlertDialogContent, { children: [
3136
- /* @__PURE__ */ jsxs27(AlertDialogHeader, { children: [
3137
- /* @__PURE__ */ jsx32(AlertDialogTitle, { children: "Reactivate Price" }),
3138
- /* @__PURE__ */ jsxs27(AlertDialogDescription, { children: [
3300
+ /* @__PURE__ */ jsx40(AlertDialog, { open: !!priceToReactivate, onOpenChange: (open) => !open && setPriceToReactivate(null), children: /* @__PURE__ */ jsxs35(AlertDialogContent, { children: [
3301
+ /* @__PURE__ */ jsxs35(AlertDialogHeader, { children: [
3302
+ /* @__PURE__ */ jsx40(AlertDialogTitle, { children: "Reactivate Price" }),
3303
+ /* @__PURE__ */ jsxs35(AlertDialogDescription, { children: [
3139
3304
  "Are you sure you want to reactivate the price for",
3140
3305
  " ",
3141
3306
  priceToReactivate && `${formatCurrency(priceToReactivate.unitAmount, priceToReactivate.currency)} ${formatInterval2(priceToReactivate)}`,
3142
3307
  "? This will allow new subscriptions again."
3143
3308
  ] })
3144
3309
  ] }),
3145
- /* @__PURE__ */ jsxs27(AlertDialogFooter, { children: [
3146
- /* @__PURE__ */ jsx32(AlertDialogCancel, { disabled: !!reactivatingPriceId, children: "Cancel" }),
3147
- /* @__PURE__ */ jsx32(
3310
+ /* @__PURE__ */ jsxs35(AlertDialogFooter, { children: [
3311
+ /* @__PURE__ */ jsx40(AlertDialogCancel, { disabled: !!reactivatingPriceId, children: "Cancel" }),
3312
+ /* @__PURE__ */ jsx40(
3148
3313
  AlertDialogAction,
3149
3314
  {
3150
3315
  onClick: handleReactivate,
@@ -3161,20 +3326,20 @@ __name(PricesList, "PricesList");
3161
3326
 
3162
3327
  // src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx
3163
3328
  import { Package as Package2 } from "lucide-react";
3164
- import { useEffect as useEffect10, useState as useState19 } from "react";
3329
+ import { useEffect as useEffect12, useState as useState18 } from "react";
3165
3330
 
3166
3331
  // src/features/billing/stripe-product/components/forms/ProductEditor.tsx
3167
3332
  import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
3168
- import { useState as useState17 } from "react";
3333
+ import { useState as useState16 } from "react";
3169
3334
  import { useForm as useForm3 } from "react-hook-form";
3170
- import { v4 as v44 } from "uuid";
3335
+ import { v4 as v42 } from "uuid";
3171
3336
  import { z as z3 } from "zod";
3172
- import { jsx as jsx33, jsxs as jsxs28 } from "react/jsx-runtime";
3337
+ import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
3173
3338
  function ProductEditor({ product, open, onOpenChange, onSuccess }) {
3174
- const [isSubmitting, setIsSubmitting] = useState17(false);
3339
+ const [isSubmitting, setIsSubmitting] = useState16(false);
3175
3340
  const formSchema2 = z3.object({
3176
3341
  name: z3.string().min(1, { message: "Product name is required" }),
3177
- description: z3.string().optional(),
3342
+ description: z3.string().min(1, { message: "Description is required" }),
3178
3343
  active: z3.boolean()
3179
3344
  });
3180
3345
  const form = useForm3({
@@ -3197,7 +3362,7 @@ function ProductEditor({ product, open, onOpenChange, onSuccess }) {
3197
3362
  });
3198
3363
  } else {
3199
3364
  await StripeProductService.createProduct({
3200
- id: v44(),
3365
+ id: v42(),
3201
3366
  name: values.name,
3202
3367
  description: values.description,
3203
3368
  active: values.active
@@ -3211,25 +3376,25 @@ function ProductEditor({ product, open, onOpenChange, onSuccess }) {
3211
3376
  setIsSubmitting(false);
3212
3377
  }
3213
3378
  }, "onSubmit");
3214
- return /* @__PURE__ */ jsx33(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs28(DialogContent, { className: "max-w-2xl", children: [
3215
- /* @__PURE__ */ jsxs28(DialogHeader, { children: [
3216
- /* @__PURE__ */ jsx33(DialogTitle, { children: product ? "Edit Product" : "Create Product" }),
3217
- /* @__PURE__ */ jsx33(DialogDescription, { children: product ? `Update the details for ${product.name}` : "Create a new product to offer to your customers" })
3379
+ return /* @__PURE__ */ jsx41(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs36(DialogContent, { className: "max-w-2xl", children: [
3380
+ /* @__PURE__ */ jsxs36(DialogHeader, { children: [
3381
+ /* @__PURE__ */ jsx41(DialogTitle, { children: product ? "Edit Product" : "Create Product" }),
3382
+ /* @__PURE__ */ jsx41(DialogDescription, { children: product ? `Update the details for ${product.name}` : "Create a new product to offer to your customers" })
3218
3383
  ] }),
3219
- /* @__PURE__ */ jsx33(Form, { ...form, children: /* @__PURE__ */ jsxs28("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
3220
- /* @__PURE__ */ jsx33(FormInput, { form, id: "name", name: "Product Name", placeholder: "Enter product name", isRequired: true }),
3221
- /* @__PURE__ */ jsx33(
3384
+ /* @__PURE__ */ jsx41(Form, { ...form, children: /* @__PURE__ */ jsxs36("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
3385
+ /* @__PURE__ */ jsx41(FormInput, { form, id: "name", name: "Product Name", placeholder: "Enter product name", isRequired: true }),
3386
+ /* @__PURE__ */ jsx41(
3222
3387
  FormTextarea,
3223
3388
  {
3224
3389
  form,
3225
3390
  id: "description",
3226
3391
  name: "Description",
3227
- placeholder: "Enter product description (optional)",
3392
+ placeholder: "Enter product description",
3228
3393
  className: "min-h-32"
3229
3394
  }
3230
3395
  ),
3231
- /* @__PURE__ */ jsx33(FormCheckbox, { form, id: "active", name: "Active" }),
3232
- /* @__PURE__ */ jsx33(CommonEditorButtons, { isEdit: !!product, form, disabled: isSubmitting, setOpen: onOpenChange })
3396
+ /* @__PURE__ */ jsx41(FormCheckbox, { form, id: "active", name: "Active" }),
3397
+ /* @__PURE__ */ jsx41(CommonEditorButtons, { isEdit: !!product, form, disabled: isSubmitting, setOpen: onOpenChange })
3233
3398
  ] }) })
3234
3399
  ] }) });
3235
3400
  }
@@ -3237,15 +3402,15 @@ __name(ProductEditor, "ProductEditor");
3237
3402
 
3238
3403
  // src/features/billing/stripe-product/components/lists/ProductsList.tsx
3239
3404
  import { Archive as Archive2, ChevronDown, ChevronUp, Edit as Edit2, Package, RefreshCw as RefreshCw2 } from "lucide-react";
3240
- import { useState as useState18 } from "react";
3241
- import { jsx as jsx34, jsxs as jsxs29 } from "react/jsx-runtime";
3405
+ import { useState as useState17 } from "react";
3406
+ import { jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
3242
3407
  function ProductsList({ products, onProductsChange }) {
3243
- const [expandedProductId, setExpandedProductId] = useState18(null);
3244
- const [editingProduct, setEditingProduct] = useState18(null);
3245
- const [archivingProductId, setArchivingProductId] = useState18(null);
3246
- const [reactivatingProductId, setReactivatingProductId] = useState18(null);
3247
- const [productToArchive, setProductToArchive] = useState18(null);
3248
- const [productToReactivate, setProductToReactivate] = useState18(null);
3408
+ const [expandedProductId, setExpandedProductId] = useState17(null);
3409
+ const [editingProduct, setEditingProduct] = useState17(null);
3410
+ const [archivingProductId, setArchivingProductId] = useState17(null);
3411
+ const [reactivatingProductId, setReactivatingProductId] = useState17(null);
3412
+ const [productToArchive, setProductToArchive] = useState17(null);
3413
+ const [productToReactivate, setProductToReactivate] = useState17(null);
3249
3414
  const handleArchive = /* @__PURE__ */ __name(async () => {
3250
3415
  if (!productToArchive) {
3251
3416
  return;
@@ -3278,29 +3443,29 @@ function ProductsList({ products, onProductsChange }) {
3278
3443
  const toggleExpand = /* @__PURE__ */ __name((productId) => {
3279
3444
  setExpandedProductId(expandedProductId === productId ? null : productId);
3280
3445
  }, "toggleExpand");
3281
- return /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-y-4", children: [
3446
+ return /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-y-4", children: [
3282
3447
  products.map((product) => {
3283
3448
  const isExpanded = expandedProductId === product.id;
3284
3449
  const isArchiving = archivingProductId === product.id;
3285
3450
  const isReactivating = reactivatingProductId === product.id;
3286
- return /* @__PURE__ */ jsxs29("div", { className: "border rounded-lg bg-white shadow-sm hover:shadow-md transition-shadow", children: [
3287
- /* @__PURE__ */ jsxs29("div", { className: "flex items-center justify-between p-6", children: [
3288
- /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-x-4 flex-1", children: [
3289
- /* @__PURE__ */ jsx34(Package, { className: "h-6 w-6 text-primary" }),
3290
- /* @__PURE__ */ jsxs29("div", { className: "flex-1", children: [
3291
- /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-x-3", children: [
3292
- /* @__PURE__ */ jsx34("h3", { className: "text-lg font-semibold", children: product.name }),
3293
- product.active ? /* @__PURE__ */ jsx34("span", { className: "bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium", children: "Active" }) : /* @__PURE__ */ jsx34("span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium", children: "Inactive" })
3451
+ return /* @__PURE__ */ jsxs37("div", { className: "border rounded-lg bg-white shadow-sm hover:shadow-md transition-shadow", children: [
3452
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-between p-6", children: [
3453
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-x-4 flex-1", children: [
3454
+ /* @__PURE__ */ jsx42(Package, { className: "h-6 w-6 text-primary" }),
3455
+ /* @__PURE__ */ jsxs37("div", { className: "flex-1", children: [
3456
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-x-3", children: [
3457
+ /* @__PURE__ */ jsx42("h3", { className: "text-lg font-semibold", children: product.name }),
3458
+ product.active ? /* @__PURE__ */ jsx42("span", { className: "bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full font-medium", children: "Active" }) : /* @__PURE__ */ jsx42("span", { className: "bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full font-medium", children: "Inactive" })
3294
3459
  ] }),
3295
- product.description && /* @__PURE__ */ jsx34("p", { className: "text-muted-foreground text-sm mt-1", children: product.description })
3460
+ product.description && /* @__PURE__ */ jsx42("p", { className: "text-muted-foreground text-sm mt-1", children: product.description })
3296
3461
  ] })
3297
3462
  ] }),
3298
- /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-x-2", children: [
3299
- /* @__PURE__ */ jsxs29(Button, { variant: "outline", size: "sm", onClick: () => setEditingProduct(product), children: [
3300
- /* @__PURE__ */ jsx34(Edit2, { className: "h-4 w-4 mr-1" }),
3463
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-x-2", children: [
3464
+ /* @__PURE__ */ jsxs37(Button, { variant: "outline", size: "sm", onClick: () => setEditingProduct(product), children: [
3465
+ /* @__PURE__ */ jsx42(Edit2, { className: "h-4 w-4 mr-1" }),
3301
3466
  "Edit"
3302
3467
  ] }),
3303
- product.active ? /* @__PURE__ */ jsxs29(
3468
+ product.active ? /* @__PURE__ */ jsxs37(
3304
3469
  Button,
3305
3470
  {
3306
3471
  variant: "outline",
@@ -3308,11 +3473,11 @@ function ProductsList({ products, onProductsChange }) {
3308
3473
  onClick: () => setProductToArchive(product),
3309
3474
  disabled: isArchiving,
3310
3475
  children: [
3311
- /* @__PURE__ */ jsx34(Archive2, { className: "h-4 w-4 mr-1" }),
3476
+ /* @__PURE__ */ jsx42(Archive2, { className: "h-4 w-4 mr-1" }),
3312
3477
  isArchiving ? "Archiving..." : "Archive"
3313
3478
  ]
3314
3479
  }
3315
- ) : /* @__PURE__ */ jsxs29(
3480
+ ) : /* @__PURE__ */ jsxs37(
3316
3481
  Button,
3317
3482
  {
3318
3483
  variant: "outline",
@@ -3320,18 +3485,18 @@ function ProductsList({ products, onProductsChange }) {
3320
3485
  onClick: () => setProductToReactivate(product),
3321
3486
  disabled: isReactivating,
3322
3487
  children: [
3323
- /* @__PURE__ */ jsx34(RefreshCw2, { className: "h-4 w-4 mr-1" }),
3488
+ /* @__PURE__ */ jsx42(RefreshCw2, { className: "h-4 w-4 mr-1" }),
3324
3489
  isReactivating ? "Reactivating..." : "Reactivate"
3325
3490
  ]
3326
3491
  }
3327
3492
  ),
3328
- /* @__PURE__ */ jsx34(Button, { variant: "ghost", size: "sm", onClick: () => toggleExpand(product.id), children: isExpanded ? /* @__PURE__ */ jsx34(ChevronUp, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx34(ChevronDown, { className: "h-5 w-5" }) })
3493
+ /* @__PURE__ */ jsx42(Button, { variant: "ghost", size: "sm", onClick: () => toggleExpand(product.id), children: isExpanded ? /* @__PURE__ */ jsx42(ChevronUp, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx42(ChevronDown, { className: "h-5 w-5" }) })
3329
3494
  ] })
3330
3495
  ] }),
3331
- isExpanded && /* @__PURE__ */ jsx34("div", { className: "border-t bg-muted/30 p-6", children: /* @__PURE__ */ jsx34(PricesList, { productId: product.id, onPricesChange: onProductsChange }) })
3496
+ isExpanded && /* @__PURE__ */ jsx42("div", { className: "border-t bg-muted/30 p-6", children: /* @__PURE__ */ jsx42(PricesList, { productId: product.id, onPricesChange: onProductsChange }) })
3332
3497
  ] }, product.id);
3333
3498
  }),
3334
- editingProduct && /* @__PURE__ */ jsx34(
3499
+ editingProduct && /* @__PURE__ */ jsx42(
3335
3500
  ProductEditor,
3336
3501
  {
3337
3502
  product: editingProduct,
@@ -3343,18 +3508,18 @@ function ProductsList({ products, onProductsChange }) {
3343
3508
  }
3344
3509
  }
3345
3510
  ),
3346
- /* @__PURE__ */ jsx34(AlertDialog, { open: !!productToArchive, onOpenChange: (open) => !open && setProductToArchive(null), children: /* @__PURE__ */ jsxs29(AlertDialogContent, { children: [
3347
- /* @__PURE__ */ jsxs29(AlertDialogHeader, { children: [
3348
- /* @__PURE__ */ jsx34(AlertDialogTitle, { children: "Archive Product" }),
3349
- /* @__PURE__ */ jsxs29(AlertDialogDescription, { children: [
3511
+ /* @__PURE__ */ jsx42(AlertDialog, { open: !!productToArchive, onOpenChange: (open) => !open && setProductToArchive(null), children: /* @__PURE__ */ jsxs37(AlertDialogContent, { children: [
3512
+ /* @__PURE__ */ jsxs37(AlertDialogHeader, { children: [
3513
+ /* @__PURE__ */ jsx42(AlertDialogTitle, { children: "Archive Product" }),
3514
+ /* @__PURE__ */ jsxs37(AlertDialogDescription, { children: [
3350
3515
  'Are you sure you want to archive "',
3351
3516
  productToArchive?.name,
3352
3517
  '"? This will deactivate it and it will no longer be available for new subscriptions.'
3353
3518
  ] })
3354
3519
  ] }),
3355
- /* @__PURE__ */ jsxs29(AlertDialogFooter, { children: [
3356
- /* @__PURE__ */ jsx34(AlertDialogCancel, { disabled: !!archivingProductId, children: "Cancel" }),
3357
- /* @__PURE__ */ jsx34(
3520
+ /* @__PURE__ */ jsxs37(AlertDialogFooter, { children: [
3521
+ /* @__PURE__ */ jsx42(AlertDialogCancel, { disabled: !!archivingProductId, children: "Cancel" }),
3522
+ /* @__PURE__ */ jsx42(
3358
3523
  AlertDialogAction,
3359
3524
  {
3360
3525
  onClick: handleArchive,
@@ -3365,18 +3530,18 @@ function ProductsList({ products, onProductsChange }) {
3365
3530
  )
3366
3531
  ] })
3367
3532
  ] }) }),
3368
- /* @__PURE__ */ jsx34(AlertDialog, { open: !!productToReactivate, onOpenChange: (open) => !open && setProductToReactivate(null), children: /* @__PURE__ */ jsxs29(AlertDialogContent, { children: [
3369
- /* @__PURE__ */ jsxs29(AlertDialogHeader, { children: [
3370
- /* @__PURE__ */ jsx34(AlertDialogTitle, { children: "Reactivate Product" }),
3371
- /* @__PURE__ */ jsxs29(AlertDialogDescription, { children: [
3533
+ /* @__PURE__ */ jsx42(AlertDialog, { open: !!productToReactivate, onOpenChange: (open) => !open && setProductToReactivate(null), children: /* @__PURE__ */ jsxs37(AlertDialogContent, { children: [
3534
+ /* @__PURE__ */ jsxs37(AlertDialogHeader, { children: [
3535
+ /* @__PURE__ */ jsx42(AlertDialogTitle, { children: "Reactivate Product" }),
3536
+ /* @__PURE__ */ jsxs37(AlertDialogDescription, { children: [
3372
3537
  'Are you sure you want to reactivate "',
3373
3538
  productToReactivate?.name,
3374
3539
  '"? This will make it available for new subscriptions again.'
3375
3540
  ] })
3376
3541
  ] }),
3377
- /* @__PURE__ */ jsxs29(AlertDialogFooter, { children: [
3378
- /* @__PURE__ */ jsx34(AlertDialogCancel, { disabled: !!reactivatingProductId, children: "Cancel" }),
3379
- /* @__PURE__ */ jsx34(
3542
+ /* @__PURE__ */ jsxs37(AlertDialogFooter, { children: [
3543
+ /* @__PURE__ */ jsx42(AlertDialogCancel, { disabled: !!reactivatingProductId, children: "Cancel" }),
3544
+ /* @__PURE__ */ jsx42(
3380
3545
  AlertDialogAction,
3381
3546
  {
3382
3547
  onClick: handleReactivate,
@@ -3392,14 +3557,14 @@ function ProductsList({ products, onProductsChange }) {
3392
3557
  __name(ProductsList, "ProductsList");
3393
3558
 
3394
3559
  // src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx
3395
- import { jsx as jsx35, jsxs as jsxs30 } from "react/jsx-runtime";
3560
+ import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
3396
3561
  function ProductsAdminContainer() {
3397
3562
  const { hasRole } = useCurrentUserContext();
3398
- const [products, setProducts] = useState19([]);
3399
- const [loading, setLoading] = useState19(true);
3400
- const [showCreateProduct, setShowCreateProduct] = useState19(false);
3563
+ const [products, setProducts] = useState18([]);
3564
+ const [loading, setLoading] = useState18(true);
3565
+ const [showCreateProduct, setShowCreateProduct] = useState18(false);
3401
3566
  if (!hasRole(getRoleId().Administrator)) {
3402
- return /* @__PURE__ */ jsx35("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx35("p", { className: "text-red-600 font-semibold", children: "Permission denied. Administrator access required." }) });
3567
+ return /* @__PURE__ */ jsx43("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx43("p", { className: "text-red-600 font-semibold", children: "Permission denied. Administrator access required." }) });
3403
3568
  }
3404
3569
  const loadProducts = /* @__PURE__ */ __name(async () => {
3405
3570
  setLoading(true);
@@ -3412,30 +3577,30 @@ function ProductsAdminContainer() {
3412
3577
  setLoading(false);
3413
3578
  }
3414
3579
  }, "loadProducts");
3415
- useEffect10(() => {
3580
+ useEffect12(() => {
3416
3581
  loadProducts();
3417
3582
  }, []);
3418
3583
  if (loading) {
3419
- return /* @__PURE__ */ jsx35("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx35("p", { className: "text-muted-foreground", children: "Loading products..." }) });
3584
+ return /* @__PURE__ */ jsx43("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx43("p", { className: "text-muted-foreground", children: "Loading products..." }) });
3420
3585
  }
3421
- return /* @__PURE__ */ jsxs30("div", { className: "flex w-full flex-col gap-y-6", children: [
3422
- /* @__PURE__ */ jsxs30("div", { className: "flex items-center justify-between", children: [
3423
- /* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-x-3", children: [
3424
- /* @__PURE__ */ jsx35(Package2, { className: "h-8 w-8" }),
3425
- /* @__PURE__ */ jsx35("h1", { className: "text-3xl font-bold", children: "Product & Price Management" })
3586
+ return /* @__PURE__ */ jsxs38("div", { className: "flex w-full flex-col gap-y-6", children: [
3587
+ /* @__PURE__ */ jsxs38("div", { className: "flex items-center justify-between", children: [
3588
+ /* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-x-3", children: [
3589
+ /* @__PURE__ */ jsx43(Package2, { className: "h-8 w-8" }),
3590
+ /* @__PURE__ */ jsx43("h1", { className: "text-3xl font-bold", children: "Product & Price Management" })
3426
3591
  ] }),
3427
- /* @__PURE__ */ jsx35(Button, { onClick: () => setShowCreateProduct(true), children: "Create Product" })
3592
+ /* @__PURE__ */ jsx43(Button, { onClick: () => setShowCreateProduct(true), children: "Create Product" })
3428
3593
  ] }),
3429
- products.length === 0 && /* @__PURE__ */ jsxs30("div", { className: "bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed p-12", children: [
3430
- /* @__PURE__ */ jsx35(Package2, { className: "text-muted-foreground h-16 w-16" }),
3431
- /* @__PURE__ */ jsxs30("div", { className: "text-center", children: [
3432
- /* @__PURE__ */ jsx35("h3", { className: "mb-2 text-xl font-semibold", children: "No products yet" }),
3433
- /* @__PURE__ */ jsx35("p", { className: "text-muted-foreground mb-4", children: "Create your first product to start offering subscriptions to your customers." }),
3434
- /* @__PURE__ */ jsx35(Button, { onClick: () => setShowCreateProduct(true), children: "Create Your First Product" })
3594
+ products.length === 0 && /* @__PURE__ */ jsxs38("div", { className: "bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed p-12", children: [
3595
+ /* @__PURE__ */ jsx43(Package2, { className: "text-muted-foreground h-16 w-16" }),
3596
+ /* @__PURE__ */ jsxs38("div", { className: "text-center", children: [
3597
+ /* @__PURE__ */ jsx43("h3", { className: "mb-2 text-xl font-semibold", children: "No products yet" }),
3598
+ /* @__PURE__ */ jsx43("p", { className: "text-muted-foreground mb-4", children: "Create your first product to start offering subscriptions to your customers." }),
3599
+ /* @__PURE__ */ jsx43(Button, { onClick: () => setShowCreateProduct(true), children: "Create Your First Product" })
3435
3600
  ] })
3436
3601
  ] }),
3437
- products.length > 0 && /* @__PURE__ */ jsx35(ProductsList, { products, onProductsChange: loadProducts }),
3438
- showCreateProduct && /* @__PURE__ */ jsx35(ProductEditor, { open: showCreateProduct, onOpenChange: setShowCreateProduct, onSuccess: loadProducts })
3602
+ products.length > 0 && /* @__PURE__ */ jsx43(ProductsList, { products, onProductsChange: loadProducts }),
3603
+ showCreateProduct && /* @__PURE__ */ jsx43(ProductEditor, { open: showCreateProduct, onOpenChange: setShowCreateProduct, onSuccess: loadProducts })
3439
3604
  ] });
3440
3605
  }
3441
3606
  __name(ProductsAdminContainer, "ProductsAdminContainer");
@@ -3446,6 +3611,7 @@ export {
3446
3611
  BillingUsageSummaryCard,
3447
3612
  CancelSubscriptionDialog,
3448
3613
  CustomerInfoCard,
3614
+ IntervalToggle,
3449
3615
  InvoiceDetails,
3450
3616
  InvoiceStatusBadge,
3451
3617
  InvoicesContainer,
@@ -3453,20 +3619,22 @@ export {
3453
3619
  InvoicesSummaryCard,
3454
3620
  PaymentMethodCard,
3455
3621
  PaymentMethodEditor,
3622
+ PaymentMethodForm,
3456
3623
  PaymentMethodSummaryCard,
3457
3624
  PaymentMethodsContainer,
3458
3625
  PaymentMethodsList,
3459
3626
  PriceEditor,
3460
3627
  PricesList,
3461
3628
  PricingCard,
3462
- PricingCardsGrid,
3463
3629
  ProductEditor,
3630
+ ProductPricingList,
3631
+ ProductPricingRow,
3464
3632
  ProductsAdminContainer,
3465
3633
  ProductsList,
3466
3634
  ProrationPreview,
3467
3635
  StripeProvider,
3636
+ SubscriptionConfirmation,
3468
3637
  SubscriptionDetails,
3469
- SubscriptionEditor,
3470
3638
  SubscriptionStatusBadge,
3471
3639
  SubscriptionSummaryCard,
3472
3640
  SubscriptionsContainer,