@burdenoff/microfe-billing 2026.526.1 → 2026.528.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/billing/BillingAdminRoutes.js +1 -1
  2. package/dist/billing/BillingAdminRoutes.js.map +1 -1
  3. package/dist/billing/BillingUserRoutes.js +1 -1
  4. package/dist/billing/BillingUserRoutes.js.map +1 -1
  5. package/dist/billing/modules/addons/components/FloatingCartDrawer.js +15 -8
  6. package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
  7. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +13 -6
  8. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  9. package/dist/billing/modules/addons/pages/AddonCreatePage.js +1 -1
  10. package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
  11. package/dist/billing/modules/addons/pages/AddonDetailPage.js +8 -4
  12. package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
  13. package/dist/billing/modules/addons/pages/AddonEditPage.js +3 -2
  14. package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
  15. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +44 -23
  16. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  17. package/dist/billing/modules/addons/pages/AddonsListPage.js +60 -31
  18. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  19. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +9 -9
  20. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  21. package/dist/billing/modules/analytics/pages/AnalyticsPage.js +8 -8
  22. package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
  23. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +16 -10
  24. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  25. package/dist/billing/modules/billing/pages/InvoicesListPage.js +24 -16
  26. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  27. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +5 -1
  28. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  29. package/dist/billing/modules/billing/pages/RefundsPage.js +46 -29
  30. package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
  31. package/dist/billing/modules/billing/pages/TransactionsPage.js +34 -22
  32. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  33. package/dist/billing/modules/checkout/components/BillingAccountSelector.js +10 -10
  34. package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
  35. package/dist/billing/modules/checkout/components/CreditsAmountInput.js +3 -3
  36. package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
  37. package/dist/billing/modules/checkout/components/NativeCheckoutView.js +7 -0
  38. package/dist/billing/modules/checkout/components/NativeCheckoutView.js.map +1 -1
  39. package/dist/billing/modules/checkout/components/OrderSummary.js +13 -13
  40. package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
  41. package/dist/billing/modules/checkout/components/PromoCodeInput.js +5 -5
  42. package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
  43. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js +5 -5
  44. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
  45. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js +4 -4
  46. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
  47. package/dist/billing/modules/checkout/components/StripePaymentForm.js +11 -11
  48. package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
  49. package/dist/billing/modules/checkout/components/SubscriptionSelector.js +3 -3
  50. package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
  51. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js +8 -8
  52. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
  53. package/dist/billing/modules/checkout/pages/CheckoutPage.js +61 -52
  54. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  55. package/dist/billing/modules/coupons/pages/CouponDetailPage.js +22 -15
  56. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  57. package/dist/billing/modules/coupons/pages/CouponsListPage.js +30 -21
  58. package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
  59. package/dist/billing/modules/coupons/pages/CreateCouponPage.js +9 -8
  60. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  61. package/dist/billing/modules/coupons/pages/EditCouponPage.js +11 -8
  62. package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
  63. package/dist/billing/modules/credits/pages/AdminCreditsPage.js +1 -1
  64. package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
  65. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +22 -17
  66. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
  67. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +15 -8
  68. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  69. package/dist/billing/modules/credits/pages/CreditsPage.js +17 -11
  70. package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
  71. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js +15 -11
  72. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
  73. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js +21 -17
  74. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
  75. package/dist/billing/modules/dashboard/components/BillingAccountCard.js +14 -11
  76. package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
  77. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js +32 -26
  78. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
  79. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js +14 -10
  80. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
  81. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js +18 -11
  82. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
  83. package/dist/billing/modules/dashboard/pages/OverviewPage.js +44 -32
  84. package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
  85. package/dist/billing/modules/discounts/pages/DiscountsListPage.js +35 -26
  86. package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
  87. package/dist/billing/modules/earnings/pages/EarningsPage.js +15 -15
  88. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  89. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +11 -11
  90. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  91. package/dist/billing/modules/earnings/pages/PayoutsPage.js +5 -5
  92. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  93. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +9 -4
  94. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
  95. package/dist/billing/modules/plans/pages/PlanCreatePage.js +1 -1
  96. package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
  97. package/dist/billing/modules/plans/pages/PlanDetailPage.js +13 -8
  98. package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
  99. package/dist/billing/modules/plans/pages/PlanEditPage.js +3 -2
  100. package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
  101. package/dist/billing/modules/plans/pages/PlansBrowsePage.js +14 -7
  102. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  103. package/dist/billing/modules/plans/pages/PlansListPage.js +23 -9
  104. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  105. package/dist/billing/modules/quota/pages/QuotaPage.js +11 -7
  106. package/dist/billing/modules/quota/pages/QuotaPage.js.map +1 -1
  107. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +3 -3
  108. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
  109. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +6 -2
  110. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
  111. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +5 -4
  112. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
  113. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +26 -12
  114. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  115. package/dist/billing/modules/settings/pages/SettingsPage.js +356 -349
  116. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  117. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +157 -123
  118. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  119. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js +13 -8
  120. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
  121. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +15 -7
  122. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  123. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +30 -20
  124. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  125. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +25 -16
  126. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  127. package/dist/billing/modules/usage/pages/UsagePage.js +50 -34
  128. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  129. package/dist/billing/shared/components/AccessDenied.js +2 -2
  130. package/dist/billing/shared/components/AccessDenied.js.map +1 -1
  131. package/dist/billing/shared/components/ActorIdentity.js +67 -0
  132. package/dist/billing/shared/components/ActorIdentity.js.map +1 -0
  133. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js +6 -2
  134. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
  135. package/dist/billing/shared/components/EmptyState.js +7 -21
  136. package/dist/billing/shared/components/EmptyState.js.map +1 -1
  137. package/dist/billing/shared/components/PageHeader.js +7 -19
  138. package/dist/billing/shared/components/PageHeader.js.map +1 -1
  139. package/dist/billing/shared/components/ServerError.js +5 -4
  140. package/dist/billing/shared/components/ServerError.js.map +1 -1
  141. package/dist/billing/shared/components/index.js +1 -0
  142. package/dist/billing/shared/hooks/index.js +1 -0
  143. package/dist/billing/shared/hooks/useActorProfiles.js +113 -0
  144. package/dist/billing/shared/hooks/useActorProfiles.js.map +1 -0
  145. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"OverviewPage.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/pages/OverviewPage.tsx"],"sourcesContent":["/**\n * Billing Overview Page\n * Main dashboard for billing showing accounts, subscriptions, payment methods, and addons\n */\n\nimport { type FC, useState, useCallback, useEffect } from 'react';\nimport {\n Plus,\n Building2,\n RefreshCw,\n Loader2,\n Wallet,\n ChevronDown,\n Check,\n Activity,\n Receipt,\n ArrowRight,\n Sparkles,\n Crown,\n Coins,\n} from 'lucide-react';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { StatCard } from '../../../shared/components/StatCard';\nimport { EmptyState } from '../../../shared/components/EmptyState';\nimport { ServerError } from '../../../shared/components/ServerError';\nimport { AccessDenied } from '../../../shared/components/AccessDenied';\nimport { isServerError } from '../../../shared/utils';\nimport { useBillingOverviewData, useDashboardMutations } from '../hooks';\nimport {\n BillingAccountCard,\n PaymentMethodsSection,\n ActiveSubscriptionCard,\n RecommendedAddonsSection,\n CreateBillingAccountModal,\n AddPaymentMethodModal,\n} from '../components';\nimport { useAddonCartStore } from '../../addons/store/addonCartStore';\nimport { FloatingCartDrawer } from '../../addons/components/FloatingCartDrawer';\nimport {\n getStoredBillingAccountId,\n setStoredBillingAccountId,\n} from '../../../hooks/useBillingAccountSelection';\nimport { withBillingAccountId } from '../../../shared/utils/navigation';\nimport type {\n BillingAccount,\n CreateBillingAccountInput,\n SetBillingAddressInput,\n Addon,\n} from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\nexport const OverviewPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const { navigate, basePath, orgId, productId } = useBilling();\n const permissions = useBillingPermissions();\n const { emit } = useBillingEventEmitter();\n\n const [selectedAccountId, setSelectedAccountIdState] = useState<string | null>(() =>\n getStoredBillingAccountId(orgId)\n );\n\n const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n const [isAccountSelectorOpen, setIsAccountSelectorOpen] = useState(false);\n const [isAddPaymentModalOpen, setIsAddPaymentModalOpen] = useState(false);\n const [selectedSubscriptionIndex, setSelectedSubscriptionIndex] = useState(0);\n const [isSubscriptionSelectorOpen, setIsSubscriptionSelectorOpen] = useState(false);\n\n const {\n billingAccounts,\n currentAccount,\n paymentMethods,\n activeSubscriptions,\n hasActiveSubscription,\n recommendedAddons,\n isLoading,\n error,\n refetchAll,\n } = useBillingOverviewData(selectedAccountId, productId);\n\n const currentAccountId = currentAccount?.id;\n const isLoadingAddons = isLoading;\n\n const setSelectedAccountId = useCallback(\n (accountId: string | null) => {\n setSelectedAccountIdState(accountId);\n setStoredBillingAccountId(orgId, accountId);\n },\n [orgId]\n );\n\n // Addon cart store for add to cart functionality\n const { addToCart, isInCart, getCartItem, updateQuantity, removeFromCart } = useAddonCartStore();\n\n const {\n createBillingAccount,\n setBillingAddress,\n setDefaultPaymentMethod,\n deletePaymentMethod,\n isCreatingAccount,\n } = useDashboardMutations();\n\n // Reset subscription selector when account changes or subscriptions change\n useEffect(() => {\n setSelectedSubscriptionIndex(0);\n setIsSubscriptionSelectorOpen(false);\n }, [currentAccountId, activeSubscriptions.length]);\n\n useEffect(() => {\n if (selectedAccountId && billingAccounts.length > 0) {\n const accountExists = billingAccounts.some((account) => account.id === selectedAccountId);\n if (!accountExists) {\n setSelectedAccountId(null);\n }\n }\n }, [billingAccounts, selectedAccountId, setSelectedAccountId]);\n\n useEffect(() => {\n if (!selectedAccountId && billingAccounts.length > 0) {\n const defaultAccount =\n billingAccounts.find((account) => account.isDefault) ?? billingAccounts[0];\n setSelectedAccountId(defaultAccount.id);\n }\n }, [billingAccounts, selectedAccountId, setSelectedAccountId]);\n\n // Derive selected subscription from active subscriptions\n const selectedSubscription =\n activeSubscriptions[selectedSubscriptionIndex] || activeSubscriptions[0] || null;\n\n // Helper for navigation - properly joins basePath and path\n const navigateTo = useCallback(\n (path: string) => {\n // Handle path joining to avoid double slashes (e.g., / + /plans = //plans)\n let fullPath = path;\n if (basePath && basePath !== '/') {\n // Remove trailing slash from basePath and leading slash from path if needed\n const base = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;\n const suffix = path.startsWith('/') ? path : `/${path}`;\n fullPath = `${base}${suffix}`;\n }\n navigate(fullPath);\n },\n [navigate, basePath]\n );\n\n // Handlers\n const handleCreateAccount = useCallback(\n async (\n input: CreateBillingAccountInput,\n address?: Omit<SetBillingAddressInput, 'billingAccountId'>\n ) => {\n setCreateError(null);\n try {\n const newAccount = await createBillingAccount(input);\n\n // If address data provided, set the billing address\n if (address && newAccount.id) {\n await setBillingAddress({\n billingAccountId: newAccount.id,\n ...address,\n });\n }\n\n setIsCreateModalOpen(false);\n setSelectedAccountId(newAccount.id);\n emit('billing.billing_account.created', {\n route: '/billing/overview',\n entityId: newAccount.id,\n source: 'overview',\n });\n await refetchAll();\n } catch (err) {\n setCreateError(err instanceof Error ? err.message : 'Failed to create billing account');\n }\n },\n [createBillingAccount, emit, refetchAll, setBillingAddress, setSelectedAccountId]\n );\n\n const handleAddPaymentMethod = useCallback(() => {\n setIsAddPaymentModalOpen(true);\n }, []);\n\n // Helper to refetch the current account data\n const refetchCurrentAccount = useCallback(async () => {\n await refetchAll();\n }, [refetchAll]);\n\n const handlePaymentMethodAdded = useCallback(async () => {\n emit('billing.payment_method.added', {\n route: '/billing/overview',\n entityId: currentAccountId,\n source: 'overview',\n });\n await refetchCurrentAccount();\n }, [currentAccountId, emit, refetchCurrentAccount]);\n\n const handleSetDefaultPaymentMethod = useCallback(\n async (id: string) => {\n if (!currentAccountId) return;\n await setDefaultPaymentMethod(id, currentAccountId);\n emit('billing.payment_method.default_set', {\n route: '/billing/overview',\n entityId: id,\n source: 'overview',\n });\n await refetchCurrentAccount();\n },\n [currentAccountId, emit, setDefaultPaymentMethod, refetchCurrentAccount]\n );\n\n const handleDeletePaymentMethod = useCallback(\n async (id: string) => {\n if (!currentAccountId) return;\n await deletePaymentMethod(id, currentAccountId);\n emit('billing.payment_method.deleted', {\n route: '/billing/overview',\n entityId: id,\n source: 'overview',\n });\n await refetchCurrentAccount();\n },\n [currentAccountId, deletePaymentMethod, emit, refetchCurrentAccount]\n );\n\n const handleSelectAccount = useCallback(\n (account: BillingAccount) => {\n setSelectedAccountId(account.id);\n setIsAccountSelectorOpen(false);\n },\n [setSelectedAccountId]\n );\n\n const handleRefresh = useCallback(async () => {\n await refetchAll();\n }, [refetchAll]);\n\n // Handler for adding addon to cart\n const handleAddToCart = useCallback(\n (addon: Addon) => {\n addToCart(addon);\n },\n [addToCart]\n );\n\n // Handler to check if addon is in cart\n const handleIsInCart = useCallback(\n (addonId: string) => {\n return isInCart(addonId);\n },\n [isInCart]\n );\n\n // Handler to get cart quantity for addon\n const handleGetCartQuantity = useCallback(\n (addonId: string) => {\n const item = getCartItem(addonId);\n return item?.quantity || 0;\n },\n [getCartItem]\n );\n\n // Handler to update quantity in cart\n const handleUpdateQuantity = useCallback(\n (addonId: string, quantity: number) => {\n if (quantity <= 0) {\n removeFromCart(addonId);\n } else {\n updateQuantity(addonId, quantity);\n }\n },\n [updateQuantity, removeFromCart]\n );\n\n // Handler to remove from cart\n const handleRemoveFromCart = useCallback(\n (addonId: string) => {\n removeFromCart(addonId);\n },\n [removeFromCart]\n );\n\n // Permission check - must be after all hooks are defined\n if (!permissions.canViewBillingAccount) {\n return <AccessDenied message=\"You don't have permission to view billing information.\" />;\n }\n\n // Error state\n if (error && isServerError(error) && !isLoading) {\n return (\n <div className=\"p-6\">\n <ServerError\n title=\"Server Unavailable\"\n message=\"Unable to load billing overview. The server might be down or experiencing issues.\"\n onRetry={handleRefresh}\n showRetry\n />\n </div>\n );\n }\n\n // Loading state\n if (isLoading && !currentAccount) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"flex flex-col items-center gap-3\">\n <Loader2 className=\"w-8 h-8 animate-spin text-primary\" />\n <p className=\"text-sm text-muted-foreground\">\n {tr('billing.overview.loadingInfo', 'Loading billing information...')}\n </p>\n </div>\n </div>\n );\n }\n\n // No billing accounts state\n if (!isLoading && billingAccounts.length === 0) {\n return (\n <div className=\"p-6\">\n <header className=\"mb-8\">\n <h1 className=\"text-2xl font-bold text-foreground\">\n {tr('billing.overview.title', 'Billing Overview')}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {tr(\n 'billing.overview.emptySetupDescription',\n 'Set up billing to manage subscriptions, payments, and invoices'\n )}\n </p>\n </header>\n <EmptyState\n icon={<Building2 className=\"w-6 h-6 text-muted-foreground\" />}\n title={tr('billing.overview.emptyTitle', 'No billing account')}\n description={tr(\n 'billing.overview.emptyDescription',\n 'Create a billing account to start managing your subscriptions and payments'\n )}\n action={\n permissions.canManageBillingAccount ? (\n <button\n onClick={() => setIsCreateModalOpen(true)}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-primary-foreground bg-primary rounded-lg hover:bg-primary/90 transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n {tr('billing.overview.createBillingAccount', 'Create Billing Account')}\n </button>\n ) : undefined\n }\n />\n\n <CreateBillingAccountModal\n isOpen={isCreateModalOpen}\n onClose={() => {\n setIsCreateModalOpen(false);\n setCreateError(null);\n }}\n onSubmit={handleCreateAccount}\n isSubmitting={isCreatingAccount}\n error={createError}\n />\n </div>\n );\n }\n\n return (\n <div className=\"p-4 sm:p-6 space-y-6 sm:space-y-8\">\n {/* Header */}\n <header className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl font-bold text-foreground\">\n {tr('billing.overview.title', 'Billing Overview')}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {tr(\n 'billing.overview.description',\n 'Manage your billing accounts, subscriptions, and payment methods'\n )}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={handleRefresh}\n className=\"p-2 rounded-lg border border-border hover:bg-muted text-muted-foreground hover:text-foreground transition-colors\"\n aria-label={tr('billing.overview.refresh', 'Refresh')}\n >\n <RefreshCw className={`w-4 h-4 ${isLoading ? 'animate-spin' : ''}`} />\n </button>\n {permissions.canManageBillingAccount && billingAccounts.length > 0 && (\n <button\n onClick={() => setIsCreateModalOpen(true)}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-primary-foreground bg-primary rounded-lg hover:bg-primary/90 transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n <span className=\"hidden sm:inline\">\n {tr('billing.overview.newAccount', 'New Account')}\n </span>\n </button>\n )}\n </div>\n </header>\n\n {/* Account Selector (if multiple accounts) */}\n {billingAccounts.length > 1 && (\n <div className=\"relative\">\n <button\n onClick={() => setIsAccountSelectorOpen(!isAccountSelectorOpen)}\n className=\"w-full sm:w-auto flex items-center justify-between gap-3 px-4 py-3 border border-border rounded-lg bg-card hover:bg-muted/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"w-8 h-8 rounded-lg bg-primary/10 flex items-center justify-center\">\n <Building2 className=\"w-4 h-4 text-primary\" />\n </div>\n <div className=\"text-left\">\n <p className=\"text-sm font-medium text-foreground\">\n {currentAccount?.name || tr('billing.overview.selectAccount', 'Select Account')}\n </p>\n <p className=\"text-xs text-muted-foreground\">{currentAccount?.email}</p>\n </div>\n </div>\n <ChevronDown\n className={`w-4 h-4 text-muted-foreground transition-transform ${isAccountSelectorOpen ? 'rotate-180' : ''}`}\n />\n </button>\n\n {isAccountSelectorOpen && (\n <>\n <div className=\"fixed inset-0 z-10\" onClick={() => setIsAccountSelectorOpen(false)} />\n <div className=\"absolute top-full left-0 right-0 sm:right-auto mt-1 w-full sm:w-80 bg-popover border border-border rounded-lg shadow-lg z-20 py-1 max-h-60 overflow-y-auto\">\n {billingAccounts.map((account) => (\n <button\n key={account.id}\n onClick={() => handleSelectAccount(account)}\n className=\"w-full flex items-center justify-between gap-3 px-4 py-3 hover:bg-muted transition-colors\"\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"w-8 h-8 rounded-lg bg-muted flex items-center justify-center flex-shrink-0\">\n <Building2 className=\"w-4 h-4 text-muted-foreground\" />\n </div>\n <div className=\"text-left min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {account.name}\n </p>\n <p className=\"text-xs text-muted-foreground truncate\">{account.email}</p>\n </div>\n </div>\n {currentAccount?.id === account.id && (\n <Check className=\"w-4 h-4 text-primary flex-shrink-0\" />\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Stats Row */}\n {currentAccount && (\n <div className=\"grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4\">\n <StatCard\n label={tr('billing.overview.stats.creditBalance', 'Credit Balance')}\n value={`${(currentAccount.creditAmount || 0).toLocaleString()} Credits`}\n icon={<Wallet className=\"w-5 h-5\" />}\n />\n <StatCard\n label={tr('billing.overview.stats.activePlans', 'Active Plans')}\n value={\n activeSubscriptions.length > 0\n ? activeSubscriptions.length === 1\n ? activeSubscriptions[0]?.plan?.name || '1 Plan'\n : `${activeSubscriptions.length} ${tr('billing.overview.stats.plansSuffix', 'Plans')}`\n : tr('billing.overview.stats.none', 'None')\n }\n icon={<RefreshCw className=\"w-5 h-5\" />}\n />\n <StatCard\n label={tr('billing.overview.stats.paymentMethods', 'Payment Methods')}\n value={paymentMethods.length}\n icon={<Building2 className=\"w-5 h-5\" />}\n />\n <StatCard\n label={tr('billing.overview.stats.paymentCurrency', 'Payment Currency')}\n value={currentAccount.currency || 'USD'}\n icon={<Building2 className=\"w-5 h-5\" />}\n />\n </div>\n )}\n\n {/* Main Content Grid */}\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Left Column - Billing Account & Subscription */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Billing Account Card */}\n {currentAccount && (\n <BillingAccountCard\n account={currentAccount}\n isDefault={currentAccount.isDefault ?? false}\n onEdit={() =>\n currentAccount && navigateTo(`/settings?billingAccountId=${currentAccount.id}`)\n }\n onViewTransactions={() => navigateTo(`/transactions/${currentAccount.id}`)}\n onViewCreditTransactions={() =>\n navigateTo(`/creditTransactions/${currentAccount.id}`)\n }\n />\n )}\n\n {/* Active Subscriptions */}\n <div className=\"space-y-3\">\n {/* Subscription Selector (if multiple subscriptions) */}\n {activeSubscriptions.length > 1 && (\n <div className=\"relative\">\n <button\n onClick={() => setIsSubscriptionSelectorOpen(!isSubscriptionSelectorOpen)}\n className=\"w-full sm:w-auto flex items-center justify-between gap-3 px-4 py-3 border border-border rounded-lg bg-card hover:bg-muted/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"w-8 h-8 rounded-lg bg-primary/10 flex items-center justify-center\">\n <Crown className=\"w-4 h-4 text-primary\" />\n </div>\n <div className=\"text-left\">\n <p className=\"text-sm font-medium text-foreground\">\n {selectedSubscription?.plan?.name ||\n tr('billing.overview.selectSubscription', 'Select Subscription')}\n {selectedSubscription?.plan?.product?.name && (\n <span className=\"text-muted-foreground font-normal\">\n {' '}\n · {selectedSubscription.plan.product.name}\n </span>\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {activeSubscriptions.length}{' '}\n {tr('billing.overview.activeSubscriptions', 'active subscriptions')}\n </p>\n </div>\n </div>\n <ChevronDown\n className={`w-4 h-4 text-muted-foreground transition-transform ${isSubscriptionSelectorOpen ? 'rotate-180' : ''}`}\n />\n </button>\n\n {isSubscriptionSelectorOpen && (\n <>\n <div\n className=\"fixed inset-0 z-10\"\n onClick={() => setIsSubscriptionSelectorOpen(false)}\n />\n <div className=\"absolute top-full left-0 right-0 sm:right-auto mt-1 w-full sm:w-80 bg-popover border border-border rounded-lg shadow-lg z-20 py-1 max-h-60 overflow-y-auto\">\n {activeSubscriptions.map((subscription, index) => (\n <button\n key={subscription.id}\n onClick={() => {\n setSelectedSubscriptionIndex(index);\n setIsSubscriptionSelectorOpen(false);\n }}\n className=\"w-full flex items-center justify-between gap-3 px-4 py-3 hover:bg-muted transition-colors\"\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"w-8 h-8 rounded-lg bg-muted flex items-center justify-center flex-shrink-0\">\n <Crown className=\"w-4 h-4 text-muted-foreground\" />\n </div>\n <div className=\"text-left min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {subscription.plan?.name ||\n tr('billing.overview.subscription', 'Subscription')}\n </p>\n <p className=\"text-xs text-muted-foreground truncate\">\n {subscription.plan?.product?.name ||\n tr('billing.overview.unknownProduct', 'Unknown Product')}{' '}\n · {tr('billing.overview.ends', 'Ends')}{' '}\n {new Date(subscription.endDate).toLocaleDateString()}\n </p>\n </div>\n </div>\n {selectedSubscriptionIndex === index && (\n <Check className=\"w-4 h-4 text-primary flex-shrink-0\" />\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Single Subscription Card */}\n <ActiveSubscriptionCard\n subscription={selectedSubscription}\n onViewDetails={() =>\n selectedSubscription &&\n navigateTo(\n withBillingAccountId(\n `/subscriptions/${selectedSubscription.id}`,\n selectedSubscription.billingAccountId ?? currentAccount?.id\n )\n )\n }\n onUpgrade={() =>\n selectedSubscription &&\n navigateTo(\n withBillingAccountId(\n `/subscriptions/${selectedSubscription.id}/upgrade`,\n selectedSubscription.billingAccountId ?? currentAccount?.id\n )\n )\n }\n onManage={() =>\n currentAccount && navigateTo(`/subscriptions?billingAccountId=${currentAccount.id}`)\n }\n onPurchasePlan={() => navigateTo('/plans')}\n />\n </div>\n\n {/* Payment Methods */}\n {currentAccount && (\n <PaymentMethodsSection\n paymentMethods={paymentMethods}\n billingAccountId={currentAccount.id}\n onAddPaymentMethod={handleAddPaymentMethod}\n onSetDefault={handleSetDefaultPaymentMethod}\n onDelete={handleDeletePaymentMethod}\n isLoading={isLoading}\n />\n )}\n </div>\n\n {/* Right Column - Quick Actions & Info */}\n <div className=\"space-y-6\">\n {/* Quick Actions */}\n <section className=\"border border-border rounded-lg bg-card p-4\">\n <h3 className=\"font-semibold text-foreground mb-4\">Quick Actions</h3>\n <div className=\"space-y-2\">\n <button\n onClick={() => currentAccount && navigateTo(`/transactions/${currentAccount.id}`)}\n disabled={!currentAccount}\n className=\"w-full flex items-center gap-3 px-3 py-2.5 text-sm text-left text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"w-8 h-8 rounded bg-status-info-bg-subtle flex items-center justify-center\">\n <Receipt className=\"w-4 h-4 text-accent-blue\" />\n </div>\n View Transactions\n </button>\n <button\n onClick={() =>\n currentAccount && navigateTo(`/creditTransactions/${currentAccount.id}`)\n }\n disabled={!currentAccount}\n className=\"w-full flex items-center gap-3 px-3 py-2.5 text-sm text-left text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"w-8 h-8 rounded bg-status-warning-bg-subtle flex items-center justify-center\">\n <Wallet className=\"w-4 h-4 text-status-warning-text\" />\n </div>\n Credit History\n </button>\n <button\n onClick={() => navigateTo('/checkout/credits')}\n className=\"w-full flex items-center gap-3 px-3 py-2.5 text-sm text-left text-foreground hover:bg-muted rounded-lg transition-colors\"\n >\n <div className=\"w-8 h-8 rounded bg-status-success-bg-subtle flex items-center justify-center\">\n <Coins className=\"w-4 h-4 text-status-success-text\" />\n </div>\n Purchase Credits\n </button>\n <button\n onClick={() =>\n currentAccount && navigateTo(`/usage?billingAccountId=${currentAccount.id}`)\n }\n disabled={!currentAccount}\n className=\"w-full flex items-center gap-3 px-3 py-2.5 text-sm text-left text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"w-8 h-8 rounded bg-accent-violet-subtle flex items-center justify-center\">\n <Activity className=\"w-4 h-4 text-accent-violet\" />\n </div>\n Usage Analytics\n </button>\n </div>\n </section>\n\n {/* Get Started (if no subscription) */}\n {!hasActiveSubscription && (\n <section className=\"border border-border rounded-lg bg-gradient-to-br from-primary/5 to-primary/10 p-4\">\n <div className=\"flex items-start gap-3 mb-4\">\n <div className=\"w-10 h-10 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0\">\n <Sparkles className=\"w-5 h-5 text-primary\" />\n </div>\n <div>\n <h3 className=\"font-semibold text-foreground\">Get Started</h3>\n <p className=\"text-sm text-muted-foreground mt-1\">\n Choose a plan that fits your needs to unlock all features\n </p>\n </div>\n </div>\n <button\n onClick={() => navigateTo('/plans')}\n className=\"w-full flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium text-primary-foreground bg-primary rounded-lg hover:bg-primary/90 transition-colors\"\n >\n Browse Plans\n <ArrowRight className=\"w-4 h-4\" />\n </button>\n </section>\n )}\n </div>\n </div>\n\n {/* Recommended Addons (only if has subscription) - Limited to 3 with cart support */}\n <RecommendedAddonsSection\n addons={recommendedAddons}\n hasSubscription={hasActiveSubscription}\n onViewAddon={(addonId) => navigateTo(`/addons/${addonId}`)}\n onPurchaseAddon={(addonId) => navigateTo(`/addons/${addonId}?action=purchase`)}\n onViewAllAddons={() => navigateTo('/addons')}\n onAddToCart={handleAddToCart}\n isInCart={handleIsInCart}\n getCartQuantity={handleGetCartQuantity}\n onUpdateQuantity={handleUpdateQuantity}\n onRemoveFromCart={handleRemoveFromCart}\n maxAddons={3}\n isLoading={isLoadingAddons}\n />\n\n {/* Floating Cart Drawer - shows when items are in cart */}\n <FloatingCartDrawer />\n\n {/* Create Billing Account Modal */}\n <CreateBillingAccountModal\n isOpen={isCreateModalOpen}\n onClose={() => {\n setIsCreateModalOpen(false);\n setCreateError(null);\n }}\n onSubmit={handleCreateAccount}\n isSubmitting={isCreatingAccount}\n error={createError}\n />\n\n {/* Add Payment Method Modal */}\n {currentAccount && (\n <AddPaymentMethodModal\n isOpen={isAddPaymentModalOpen}\n onClose={() => setIsAddPaymentModalOpen(false)}\n billingAccountId={currentAccount.id}\n currency={currentAccount.currency}\n country={currentAccount.billingAddresses?.[0]?.country}\n onSuccess={handlePaymentMethodAdded}\n />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"OverviewPage.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/pages/OverviewPage.tsx"],"sourcesContent":["/**\n * Billing Overview Page\n * Main dashboard for billing showing accounts, subscriptions, payment methods, and addons\n */\n\nimport { type FC, useState, useCallback, useEffect } from 'react';\nimport {\n Plus,\n Building2,\n RefreshCw,\n Loader2,\n Wallet,\n ChevronDown,\n Check,\n Activity,\n Receipt,\n ArrowRight,\n Sparkles,\n Crown,\n Coins,\n} from 'lucide-react';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { StatCard } from '../../../shared/components/StatCard';\nimport { EmptyState } from '../../../shared/components/EmptyState';\nimport { ServerError } from '../../../shared/components/ServerError';\nimport { AccessDenied } from '../../../shared/components/AccessDenied';\nimport { isServerError } from '../../../shared/utils';\nimport { useBillingOverviewData, useDashboardMutations } from '../hooks';\nimport {\n BillingAccountCard,\n PaymentMethodsSection,\n ActiveSubscriptionCard,\n RecommendedAddonsSection,\n CreateBillingAccountModal,\n AddPaymentMethodModal,\n} from '../components';\nimport { useAddonCartStore } from '../../addons/store/addonCartStore';\nimport { FloatingCartDrawer } from '../../addons/components/FloatingCartDrawer';\nimport {\n getStoredBillingAccountId,\n setStoredBillingAccountId,\n} from '../../../hooks/useBillingAccountSelection';\nimport { withBillingAccountId } from '../../../shared/utils/navigation';\nimport type {\n BillingAccount,\n CreateBillingAccountInput,\n SetBillingAddressInput,\n Addon,\n} from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\nexport const OverviewPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const { navigate, basePath, orgId, productId } = useBilling();\n const permissions = useBillingPermissions();\n const { emit } = useBillingEventEmitter();\n\n const [selectedAccountId, setSelectedAccountIdState] = useState<string | null>(() =>\n getStoredBillingAccountId(orgId)\n );\n\n const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);\n const [createError, setCreateError] = useState<string | null>(null);\n const [isAccountSelectorOpen, setIsAccountSelectorOpen] = useState(false);\n const [isAddPaymentModalOpen, setIsAddPaymentModalOpen] = useState(false);\n const [selectedSubscriptionIndex, setSelectedSubscriptionIndex] = useState(0);\n const [isSubscriptionSelectorOpen, setIsSubscriptionSelectorOpen] = useState(false);\n\n const {\n billingAccounts,\n currentAccount,\n paymentMethods,\n activeSubscriptions,\n hasActiveSubscription,\n recommendedAddons,\n isLoading,\n error,\n refetchAll,\n } = useBillingOverviewData(selectedAccountId, productId);\n\n const currentAccountId = currentAccount?.id;\n const isLoadingAddons = isLoading;\n\n const setSelectedAccountId = useCallback(\n (accountId: string | null) => {\n setSelectedAccountIdState(accountId);\n setStoredBillingAccountId(orgId, accountId);\n },\n [orgId]\n );\n\n // Addon cart store for add to cart functionality\n const { addToCart, isInCart, getCartItem, updateQuantity, removeFromCart } = useAddonCartStore();\n\n const {\n createBillingAccount,\n setBillingAddress,\n setDefaultPaymentMethod,\n deletePaymentMethod,\n isCreatingAccount,\n } = useDashboardMutations();\n\n // Reset subscription selector when account changes or subscriptions change\n useEffect(() => {\n setSelectedSubscriptionIndex(0);\n setIsSubscriptionSelectorOpen(false);\n }, [currentAccountId, activeSubscriptions.length]);\n\n useEffect(() => {\n if (selectedAccountId && billingAccounts.length > 0) {\n const accountExists = billingAccounts.some((account) => account.id === selectedAccountId);\n if (!accountExists) {\n setSelectedAccountId(null);\n }\n }\n }, [billingAccounts, selectedAccountId, setSelectedAccountId]);\n\n useEffect(() => {\n if (!selectedAccountId && billingAccounts.length > 0) {\n const defaultAccount =\n billingAccounts.find((account) => account.isDefault) ?? billingAccounts[0];\n setSelectedAccountId(defaultAccount.id);\n }\n }, [billingAccounts, selectedAccountId, setSelectedAccountId]);\n\n // Derive selected subscription from active subscriptions\n const selectedSubscription =\n activeSubscriptions[selectedSubscriptionIndex] || activeSubscriptions[0] || null;\n\n // Helper for navigation - properly joins basePath and path\n const navigateTo = useCallback(\n (path: string) => {\n // Handle path joining to avoid double slashes (e.g., / + /plans = //plans)\n let fullPath = path;\n if (basePath && basePath !== '/') {\n // Remove trailing slash from basePath and leading slash from path if needed\n const base = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath;\n const suffix = path.startsWith('/') ? path : `/${path}`;\n fullPath = `${base}${suffix}`;\n }\n navigate(fullPath);\n },\n [navigate, basePath]\n );\n\n // Handlers\n const handleCreateAccount = useCallback(\n async (\n input: CreateBillingAccountInput,\n address?: Omit<SetBillingAddressInput, 'billingAccountId'>\n ) => {\n setCreateError(null);\n try {\n const newAccount = await createBillingAccount(input);\n\n // If address data provided, set the billing address\n if (address && newAccount.id) {\n await setBillingAddress({\n billingAccountId: newAccount.id,\n ...address,\n });\n }\n\n setIsCreateModalOpen(false);\n setSelectedAccountId(newAccount.id);\n emit('billing.billing_account.created', {\n route: '/billing/overview',\n entityId: newAccount.id,\n source: 'overview',\n });\n await refetchAll();\n } catch (err) {\n setCreateError(err instanceof Error ? err.message : 'Failed to create billing account');\n }\n },\n [createBillingAccount, emit, refetchAll, setBillingAddress, setSelectedAccountId]\n );\n\n const handleAddPaymentMethod = useCallback(() => {\n setIsAddPaymentModalOpen(true);\n }, []);\n\n // Helper to refetch the current account data\n const refetchCurrentAccount = useCallback(async () => {\n await refetchAll();\n }, [refetchAll]);\n\n const handlePaymentMethodAdded = useCallback(async () => {\n emit('billing.payment_method.added', {\n route: '/billing/overview',\n entityId: currentAccountId,\n source: 'overview',\n });\n await refetchCurrentAccount();\n }, [currentAccountId, emit, refetchCurrentAccount]);\n\n const handleSetDefaultPaymentMethod = useCallback(\n async (id: string) => {\n if (!currentAccountId) return;\n await setDefaultPaymentMethod(id, currentAccountId);\n emit('billing.payment_method.default_set', {\n route: '/billing/overview',\n entityId: id,\n source: 'overview',\n });\n await refetchCurrentAccount();\n },\n [currentAccountId, emit, setDefaultPaymentMethod, refetchCurrentAccount]\n );\n\n const handleDeletePaymentMethod = useCallback(\n async (id: string) => {\n if (!currentAccountId) return;\n await deletePaymentMethod(id, currentAccountId);\n emit('billing.payment_method.deleted', {\n route: '/billing/overview',\n entityId: id,\n source: 'overview',\n });\n await refetchCurrentAccount();\n },\n [currentAccountId, deletePaymentMethod, emit, refetchCurrentAccount]\n );\n\n const handleSelectAccount = useCallback(\n (account: BillingAccount) => {\n setSelectedAccountId(account.id);\n setIsAccountSelectorOpen(false);\n },\n [setSelectedAccountId]\n );\n\n const handleRefresh = useCallback(async () => {\n await refetchAll();\n }, [refetchAll]);\n\n // Handler for adding addon to cart\n const handleAddToCart = useCallback(\n (addon: Addon) => {\n addToCart(addon);\n },\n [addToCart]\n );\n\n // Handler to check if addon is in cart\n const handleIsInCart = useCallback(\n (addonId: string) => {\n return isInCart(addonId);\n },\n [isInCart]\n );\n\n // Handler to get cart quantity for addon\n const handleGetCartQuantity = useCallback(\n (addonId: string) => {\n const item = getCartItem(addonId);\n return item?.quantity || 0;\n },\n [getCartItem]\n );\n\n // Handler to update quantity in cart\n const handleUpdateQuantity = useCallback(\n (addonId: string, quantity: number) => {\n if (quantity <= 0) {\n removeFromCart(addonId);\n } else {\n updateQuantity(addonId, quantity);\n }\n },\n [updateQuantity, removeFromCart]\n );\n\n // Handler to remove from cart\n const handleRemoveFromCart = useCallback(\n (addonId: string) => {\n removeFromCart(addonId);\n },\n [removeFromCart]\n );\n\n // Permission check - must be after all hooks are defined\n if (!permissions.canViewBillingAccount) {\n return <AccessDenied message=\"You don't have permission to view billing information.\" />;\n }\n\n // Error state\n if (error && isServerError(error) && !isLoading) {\n return (\n <div className=\"p-6\">\n <ServerError\n title=\"Server Unavailable\"\n message=\"Unable to load billing overview. The server might be down or experiencing issues.\"\n onRetry={handleRefresh}\n showRetry\n />\n </div>\n );\n }\n\n // Loading state\n if (isLoading && !currentAccount) {\n return (\n <div className=\"flex items-center justify-center min-h-[400px]\">\n <div className=\"flex flex-col items-center gap-3\">\n <Loader2 className=\"size-8 animate-spin text-primary\" />\n <p className=\"text-sm text-muted-foreground\">\n {tr('billing.overview.loadingInfo', 'Loading billing information...')}\n </p>\n </div>\n </div>\n );\n }\n\n // No billing accounts state\n if (!isLoading && billingAccounts.length === 0) {\n return (\n <div className=\"p-6\">\n <header className=\"mb-8\">\n <h1 className=\"text-2xl font-bold text-foreground\">\n {tr('billing.overview.title', 'Billing Overview')}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {tr(\n 'billing.overview.emptySetupDescription',\n 'Set up billing to manage subscriptions, payments, and invoices'\n )}\n </p>\n </header>\n <EmptyState\n icon={<Building2 className=\"size-6 text-muted-foreground\" />}\n title={tr('billing.overview.emptyTitle', 'No billing account')}\n description={tr(\n 'billing.overview.emptyDescription',\n 'Create a billing account to start managing your subscriptions and payments'\n )}\n action={\n permissions.canManageBillingAccount ? (\n <button\n type=\"button\"\n onClick={() => setIsCreateModalOpen(true)}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-primary-foreground bg-primary rounded-lg hover:bg-primary/90 transition-colors\"\n >\n <Plus className=\"size-4\" />\n {tr('billing.overview.createBillingAccount', 'Create Billing Account')}\n </button>\n ) : undefined\n }\n />\n\n <CreateBillingAccountModal\n isOpen={isCreateModalOpen}\n onClose={() => {\n setIsCreateModalOpen(false);\n setCreateError(null);\n }}\n onSubmit={handleCreateAccount}\n isSubmitting={isCreatingAccount}\n error={createError}\n />\n </div>\n );\n }\n\n return (\n <div className=\"p-4 sm:p-6 space-y-6 sm:space-y-8\">\n {/* Header */}\n <header className=\"flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4\">\n <div>\n <h1 className=\"text-2xl font-bold text-foreground\">\n {tr('billing.overview.title', 'Billing Overview')}\n </h1>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {tr(\n 'billing.overview.description',\n 'Manage your billing accounts, subscriptions, and payment methods'\n )}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={handleRefresh}\n className=\"p-2 rounded-lg border border-border hover:bg-muted text-muted-foreground hover:text-foreground transition-colors\"\n aria-label={tr('billing.overview.refresh', 'Refresh')}\n >\n <RefreshCw className={`size-4 ${isLoading ? 'animate-spin' : ''}`} />\n </button>\n {permissions.canManageBillingAccount && billingAccounts.length > 0 && (\n <button\n type=\"button\"\n onClick={() => setIsCreateModalOpen(true)}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-primary-foreground bg-primary rounded-lg hover:bg-primary/90 transition-colors\"\n >\n <Plus className=\"size-4\" />\n <span className=\"hidden sm:inline\">\n {tr('billing.overview.newAccount', 'New Account')}\n </span>\n </button>\n )}\n </div>\n </header>\n\n {/* Account Selector (if multiple accounts) */}\n {billingAccounts.length > 1 && (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setIsAccountSelectorOpen(!isAccountSelectorOpen)}\n className=\"w-full sm:w-auto flex items-center justify-between gap-3 px-4 py-3 border border-border rounded-lg bg-card hover:bg-muted/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-8 rounded-lg bg-primary/10 flex items-center justify-center\">\n <Building2 className=\"size-4 text-primary\" />\n </div>\n <div className=\"text-left\">\n <p className=\"text-sm font-medium text-foreground\">\n {currentAccount?.name || tr('billing.overview.selectAccount', 'Select Account')}\n </p>\n <p className=\"text-xs text-muted-foreground\">{currentAccount?.email}</p>\n </div>\n </div>\n <ChevronDown\n className={`size-4 text-muted-foreground transition-transform ${isAccountSelectorOpen ? 'rotate-180' : ''}`}\n />\n </button>\n\n {isAccountSelectorOpen && (\n <>\n <div className=\"fixed inset-0 z-10\" onClick={() => setIsAccountSelectorOpen(false)} />\n <div className=\"absolute top-full left-0 right-0 sm:right-auto mt-1 w-full sm:w-80 bg-popover border border-border rounded-lg shadow-lg z-20 py-1 max-h-60 overflow-y-auto\">\n {billingAccounts.map((account) => (\n <button\n type=\"button\"\n key={account.id}\n onClick={() => handleSelectAccount(account)}\n className=\"w-full flex items-center justify-between gap-3 px-4 py-3 hover:bg-muted transition-colors\"\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-8 rounded-lg bg-muted flex items-center justify-center flex-shrink-0\">\n <Building2 className=\"size-4 text-muted-foreground\" />\n </div>\n <div className=\"text-left min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {account.name}\n </p>\n <p className=\"text-xs text-muted-foreground truncate\">{account.email}</p>\n </div>\n </div>\n {currentAccount?.id === account.id && (\n <Check className=\"size-4 text-primary flex-shrink-0\" />\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Stats Row */}\n {currentAccount && (\n <div className=\"grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4\">\n <StatCard\n label={tr('billing.overview.stats.creditBalance', 'Credit Balance')}\n value={`${(currentAccount.creditAmount || 0).toLocaleString()} Credits`}\n icon={<Wallet className=\"size-5\" />}\n />\n <StatCard\n label={tr('billing.overview.stats.activePlans', 'Active Plans')}\n value={\n activeSubscriptions.length > 0\n ? activeSubscriptions.length === 1\n ? activeSubscriptions[0]?.plan?.name || '1 Plan'\n : `${activeSubscriptions.length} ${tr('billing.overview.stats.plansSuffix', 'Plans')}`\n : tr('billing.overview.stats.none', 'None')\n }\n icon={<RefreshCw className=\"size-5\" />}\n />\n <StatCard\n label={tr('billing.overview.stats.paymentMethods', 'Payment Methods')}\n value={paymentMethods.length}\n icon={<Building2 className=\"size-5\" />}\n />\n <StatCard\n label={tr('billing.overview.stats.paymentCurrency', 'Payment Currency')}\n value={currentAccount.currency || 'USD'}\n icon={<Building2 className=\"size-5\" />}\n />\n </div>\n )}\n\n {/* Main Content Grid */}\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Left Column - Billing Account & Subscription */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Billing Account Card */}\n {currentAccount && (\n <BillingAccountCard\n account={currentAccount}\n isDefault={currentAccount.isDefault ?? false}\n onEdit={() =>\n currentAccount && navigateTo(`/settings?billingAccountId=${currentAccount.id}`)\n }\n onViewTransactions={() => navigateTo(`/transactions/${currentAccount.id}`)}\n onViewCreditTransactions={() =>\n navigateTo(`/creditTransactions/${currentAccount.id}`)\n }\n />\n )}\n\n {/* Active Subscriptions */}\n <div className=\"space-y-3\">\n {/* Subscription Selector (if multiple subscriptions) */}\n {activeSubscriptions.length > 1 && (\n <div className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setIsSubscriptionSelectorOpen(!isSubscriptionSelectorOpen)}\n className=\"w-full sm:w-auto flex items-center justify-between gap-3 px-4 py-3 border border-border rounded-lg bg-card hover:bg-muted/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-8 rounded-lg bg-primary/10 flex items-center justify-center\">\n <Crown className=\"size-4 text-primary\" />\n </div>\n <div className=\"text-left\">\n <p className=\"text-sm font-medium text-foreground\">\n {selectedSubscription?.plan?.name ||\n tr('billing.overview.selectSubscription', 'Select Subscription')}\n {selectedSubscription?.plan?.product?.name && (\n <span className=\"text-muted-foreground font-normal\">\n {' '}\n · {selectedSubscription.plan.product.name}\n </span>\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {activeSubscriptions.length}{' '}\n {tr('billing.overview.activeSubscriptions', 'active subscriptions')}\n </p>\n </div>\n </div>\n <ChevronDown\n className={`size-4 text-muted-foreground transition-transform ${isSubscriptionSelectorOpen ? 'rotate-180' : ''}`}\n />\n </button>\n\n {isSubscriptionSelectorOpen && (\n <>\n <div\n className=\"fixed inset-0 z-10\"\n onClick={() => setIsSubscriptionSelectorOpen(false)}\n />\n <div className=\"absolute top-full left-0 right-0 sm:right-auto mt-1 w-full sm:w-80 bg-popover border border-border rounded-lg shadow-lg z-20 py-1 max-h-60 overflow-y-auto\">\n {activeSubscriptions.map((subscription, index) => (\n <button\n type=\"button\"\n key={subscription.id}\n onClick={() => {\n setSelectedSubscriptionIndex(index);\n setIsSubscriptionSelectorOpen(false);\n }}\n className=\"w-full flex items-center justify-between gap-3 px-4 py-3 hover:bg-muted transition-colors\"\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-8 rounded-lg bg-muted flex items-center justify-center flex-shrink-0\">\n <Crown className=\"size-4 text-muted-foreground\" />\n </div>\n <div className=\"text-left min-w-0\">\n <p className=\"text-sm font-medium text-foreground truncate\">\n {subscription.plan?.name ||\n tr('billing.overview.subscription', 'Subscription')}\n </p>\n <p className=\"text-xs text-muted-foreground truncate\">\n {subscription.plan?.product?.name ||\n tr('billing.overview.unknownProduct', 'Unknown Product')}{' '}\n · {tr('billing.overview.ends', 'Ends')}{' '}\n {new Date(subscription.endDate).toLocaleDateString()}\n </p>\n </div>\n </div>\n {selectedSubscriptionIndex === index && (\n <Check className=\"size-4 text-primary flex-shrink-0\" />\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Single Subscription Card */}\n <ActiveSubscriptionCard\n subscription={selectedSubscription}\n onViewDetails={() =>\n selectedSubscription &&\n navigateTo(\n withBillingAccountId(\n `/subscriptions/${selectedSubscription.id}`,\n selectedSubscription.billingAccountId ?? currentAccount?.id\n )\n )\n }\n onUpgrade={() =>\n selectedSubscription &&\n navigateTo(\n withBillingAccountId(\n `/subscriptions/${selectedSubscription.id}/upgrade`,\n selectedSubscription.billingAccountId ?? currentAccount?.id\n )\n )\n }\n onManage={() =>\n currentAccount && navigateTo(`/subscriptions?billingAccountId=${currentAccount.id}`)\n }\n onPurchasePlan={() => navigateTo('/plans')}\n />\n </div>\n\n {/* Payment Methods */}\n {currentAccount && (\n <PaymentMethodsSection\n paymentMethods={paymentMethods}\n billingAccountId={currentAccount.id}\n onAddPaymentMethod={handleAddPaymentMethod}\n onSetDefault={handleSetDefaultPaymentMethod}\n onDelete={handleDeletePaymentMethod}\n isLoading={isLoading}\n />\n )}\n </div>\n\n {/* Right Column - Quick Actions & Info */}\n <div className=\"space-y-6\">\n {/* Quick Actions */}\n <section className=\"border border-border rounded-lg bg-card p-4\">\n <h3 className=\"font-semibold text-foreground mb-4\">Quick Actions</h3>\n <div className=\"space-y-2\">\n <button\n type=\"button\"\n onClick={() => currentAccount && navigateTo(`/transactions/${currentAccount.id}`)}\n disabled={!currentAccount}\n className=\"w-full flex items-center gap-3 px-3 py-2.5 text-sm text-left text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-8 rounded bg-status-info-bg-subtle flex items-center justify-center\">\n <Receipt className=\"size-4 text-accent-blue\" />\n </div>\n View Transactions\n </button>\n <button\n type=\"button\"\n onClick={() =>\n currentAccount && navigateTo(`/creditTransactions/${currentAccount.id}`)\n }\n disabled={!currentAccount}\n className=\"w-full flex items-center gap-3 px-3 py-2.5 text-sm text-left text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-8 rounded bg-status-warning-bg-subtle flex items-center justify-center\">\n <Wallet className=\"size-4 text-status-warning-text\" />\n </div>\n Credit History\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/checkout/credits')}\n className=\"w-full flex items-center gap-3 px-3 py-2.5 text-sm text-left text-foreground hover:bg-muted rounded-lg transition-colors\"\n >\n <div className=\"size-8 rounded bg-status-success-bg-subtle flex items-center justify-center\">\n <Coins className=\"size-4 text-status-success-text\" />\n </div>\n Purchase Credits\n </button>\n <button\n type=\"button\"\n onClick={() =>\n currentAccount && navigateTo(`/usage?billingAccountId=${currentAccount.id}`)\n }\n disabled={!currentAccount}\n className=\"w-full flex items-center gap-3 px-3 py-2.5 text-sm text-left text-foreground hover:bg-muted rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-8 rounded bg-accent-violet-subtle flex items-center justify-center\">\n <Activity className=\"size-4 text-accent-violet\" />\n </div>\n Usage Analytics\n </button>\n </div>\n </section>\n\n {/* Get Started (if no subscription) */}\n {!hasActiveSubscription && (\n <section className=\"border border-border rounded-lg bg-gradient-to-br from-primary/5 to-primary/10 p-4\">\n <div className=\"flex items-start gap-3 mb-4\">\n <div className=\"size-10 rounded-lg bg-primary/10 flex items-center justify-center flex-shrink-0\">\n <Sparkles className=\"size-5 text-primary\" />\n </div>\n <div>\n <h3 className=\"font-semibold text-foreground\">Get Started</h3>\n <p className=\"text-sm text-muted-foreground mt-1\">\n Choose a plan that fits your needs to unlock all features\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo('/plans')}\n className=\"w-full flex items-center justify-center gap-2 px-4 py-2.5 text-sm font-medium text-primary-foreground bg-primary rounded-lg hover:bg-primary/90 transition-colors\"\n >\n Browse Plans\n <ArrowRight className=\"size-4\" />\n </button>\n </section>\n )}\n </div>\n </div>\n\n {/* Recommended Addons (only if has subscription) - Limited to 3 with cart support */}\n <RecommendedAddonsSection\n addons={recommendedAddons}\n hasSubscription={hasActiveSubscription}\n onViewAddon={(addonId) => navigateTo(`/addons/${addonId}`)}\n onPurchaseAddon={(addonId) => navigateTo(`/addons/${addonId}?action=purchase`)}\n onViewAllAddons={() => navigateTo('/addons')}\n onAddToCart={handleAddToCart}\n isInCart={handleIsInCart}\n getCartQuantity={handleGetCartQuantity}\n onUpdateQuantity={handleUpdateQuantity}\n onRemoveFromCart={handleRemoveFromCart}\n maxAddons={3}\n isLoading={isLoadingAddons}\n />\n\n {/* Floating Cart Drawer - shows when items are in cart */}\n <FloatingCartDrawer />\n\n {/* Create Billing Account Modal */}\n <CreateBillingAccountModal\n isOpen={isCreateModalOpen}\n onClose={() => {\n setIsCreateModalOpen(false);\n setCreateError(null);\n }}\n onSubmit={handleCreateAccount}\n isSubmitting={isCreatingAccount}\n error={createError}\n />\n\n {/* Add Payment Method Modal */}\n {currentAccount && (\n <AddPaymentMethodModal\n isOpen={isAddPaymentModalOpen}\n onClose={() => setIsAddPaymentModalOpen(false)}\n billingAccountId={currentAccount.id}\n currency={currentAccount.currency}\n country={currentAccount.billingAddresses?.[0]?.country}\n onSuccess={handlePaymentMethodAdded}\n />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -139,7 +139,7 @@ var g = {
139
139
  className: "border border-border rounded-lg p-4",
140
140
  children: /* @__PURE__ */ f("div", {
141
141
  className: "flex items-center gap-4",
142
- children: [/* @__PURE__ */ d("div", { className: "h-10 w-10 bg-muted animate-pulse rounded" }), /* @__PURE__ */ f("div", {
142
+ children: [/* @__PURE__ */ d("div", { className: "size-10 bg-muted animate-pulse rounded" }), /* @__PURE__ */ f("div", {
143
143
  className: "flex-1 space-y-2",
144
144
  children: [/* @__PURE__ */ d("div", { className: "h-4 w-32 bg-muted animate-pulse rounded" }), /* @__PURE__ */ d("div", { className: "h-3 w-48 bg-muted animate-pulse rounded" })]
145
145
  })]
@@ -153,9 +153,9 @@ var g = {
153
153
  className: "text-center space-y-4",
154
154
  children: [
155
155
  /* @__PURE__ */ d("div", {
156
- className: "w-12 h-12 mx-auto rounded-full bg-destructive/10 flex items-center justify-center",
156
+ className: "size-12 mx-auto rounded-full bg-destructive/10 flex items-center justify-center",
157
157
  children: /* @__PURE__ */ d("svg", {
158
- className: "w-6 h-6 text-destructive",
158
+ className: "size-6 text-destructive",
159
159
  fill: "none",
160
160
  viewBox: "0 0 24 24",
161
161
  stroke: "currentColor",
@@ -176,6 +176,7 @@ var g = {
176
176
  children: x.message
177
177
  }),
178
178
  /* @__PURE__ */ d("button", {
179
+ type: "button",
179
180
  onClick: () => S(),
180
181
  className: "px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors",
181
182
  children: "Try Again"
@@ -194,10 +195,11 @@ var g = {
194
195
  className: "text-sm text-muted-foreground mt-1",
195
196
  children: "Create, view, and manage discount codes for billing"
196
197
  })] }), /* @__PURE__ */ f("button", {
198
+ type: "button",
197
199
  onClick: Z,
198
200
  className: "inline-flex items-center gap-2 px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors",
199
201
  children: [/* @__PURE__ */ d("svg", {
200
- className: "w-4 h-4",
202
+ className: "size-4",
201
203
  fill: "none",
202
204
  viewBox: "0 0 24 24",
203
205
  stroke: "currentColor",
@@ -250,7 +252,7 @@ var g = {
250
252
  children: /* @__PURE__ */ f("div", {
251
253
  className: "relative flex-1 min-w-0 w-full sm:max-w-md",
252
254
  children: [/* @__PURE__ */ d("svg", {
253
- className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground",
255
+ className: "absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground",
254
256
  fill: "none",
255
257
  viewBox: "0 0 24 24",
256
258
  stroke: "currentColor",
@@ -281,7 +283,7 @@ var g = {
281
283
  },
282
284
  onChange: (e) => $(e.target.checked),
283
285
  "aria-label": "Select all discounts",
284
- className: "h-4 w-4 rounded border-border text-primary"
286
+ className: "size-4 rounded border-border text-primary"
285
287
  }), /* @__PURE__ */ d("span", { children: "Select all visible" })]
286
288
  }), /* @__PURE__ */ f("div", {
287
289
  className: "flex items-center gap-2",
@@ -291,6 +293,7 @@ var g = {
291
293
  children: [z.size, " selected"]
292
294
  }),
293
295
  z.size > 0 && /* @__PURE__ */ d("button", {
296
+ type: "button",
294
297
  onClick: () => {
295
298
  B(/* @__PURE__ */ new Set()), H(!1);
296
299
  },
@@ -298,6 +301,7 @@ var g = {
298
301
  children: "Clear selection"
299
302
  }),
300
303
  /* @__PURE__ */ f("button", {
304
+ type: "button",
301
305
  onClick: () => H(!0),
302
306
  disabled: G.length === 0 || O,
303
307
  className: "inline-flex items-center gap-2 px-3 py-2 text-sm font-medium border border-destructive/30 text-destructive rounded-md hover:bg-destructive/10 transition-colors disabled:opacity-50",
@@ -325,10 +329,12 @@ var g = {
325
329
  })] }), /* @__PURE__ */ f("div", {
326
330
  className: "flex items-center gap-2",
327
331
  children: [/* @__PURE__ */ d("button", {
332
+ type: "button",
328
333
  onClick: () => H(!1),
329
334
  className: "px-3 py-2 text-sm font-medium text-muted-foreground hover:text-foreground",
330
335
  children: "Cancel"
331
336
  }), /* @__PURE__ */ d("button", {
337
+ type: "button",
332
338
  onClick: se,
333
339
  disabled: O,
334
340
  className: "inline-flex items-center gap-2 rounded-md bg-destructive px-3 py-2 text-sm font-medium text-destructive-foreground hover:bg-destructive/90 disabled:opacity-50",
@@ -341,9 +347,9 @@ var g = {
341
347
  className: "flex flex-col items-center justify-center py-12 border border-dashed border-border rounded-lg",
342
348
  children: [
343
349
  /* @__PURE__ */ d("div", {
344
- className: "w-12 h-12 rounded-full bg-muted flex items-center justify-center mb-4",
350
+ className: "size-12 rounded-full bg-muted flex items-center justify-center mb-4",
345
351
  children: /* @__PURE__ */ d("svg", {
346
- className: "w-6 h-6 text-muted-foreground",
352
+ className: "size-6 text-muted-foreground",
347
353
  fill: "none",
348
354
  viewBox: "0 0 24 24",
349
355
  stroke: "currentColor",
@@ -364,6 +370,7 @@ var g = {
364
370
  children: k ? "No discount codes match your search." : "Create your first discount code to get started."
365
371
  }),
366
372
  !k && /* @__PURE__ */ d("button", {
373
+ type: "button",
367
374
  onClick: Z,
368
375
  className: "mt-4 px-4 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors",
369
376
  children: "Create your first discount"
@@ -388,7 +395,7 @@ var g = {
388
395
  },
389
396
  onChange: (e) => $(e.target.checked),
390
397
  "aria-label": "Select all discounts",
391
- className: "h-4 w-4 rounded border-border text-primary"
398
+ className: "size-4 rounded border-border text-primary"
392
399
  })
393
400
  }),
394
401
  /* @__PURE__ */ d("th", {
@@ -453,7 +460,7 @@ var g = {
453
460
  onClick: Q,
454
461
  className: "p-1.5 rounded hover:bg-muted transition-colors",
455
462
  children: /* @__PURE__ */ d("svg", {
456
- className: "w-5 h-5 text-muted-foreground",
463
+ className: "size-5 text-muted-foreground",
457
464
  fill: "none",
458
465
  viewBox: "0 0 24 24",
459
466
  stroke: "currentColor",
@@ -680,7 +687,7 @@ var g = {
680
687
  onClick: Q,
681
688
  className: "p-1.5 rounded hover:bg-muted transition-colors",
682
689
  children: /* @__PURE__ */ d("svg", {
683
- className: "w-5 h-5 text-muted-foreground",
690
+ className: "size-5 text-muted-foreground",
684
691
  fill: "none",
685
692
  viewBox: "0 0 24 24",
686
693
  stroke: "currentColor",
@@ -812,7 +819,7 @@ var g = {
812
819
  onClick: Q,
813
820
  className: "p-1.5 rounded hover:bg-muted transition-colors",
814
821
  children: /* @__PURE__ */ d("svg", {
815
- className: "w-5 h-5 text-muted-foreground",
822
+ className: "size-5 text-muted-foreground",
816
823
  fill: "none",
817
824
  viewBox: "0 0 24 24",
818
825
  stroke: "currentColor",
@@ -832,9 +839,9 @@ var g = {
832
839
  /* @__PURE__ */ f("div", {
833
840
  className: "flex items-start gap-3",
834
841
  children: [/* @__PURE__ */ d("div", {
835
- className: "w-10 h-10 rounded-full bg-destructive/10 flex items-center justify-center shrink-0",
842
+ className: "size-10 rounded-full bg-destructive/10 flex items-center justify-center shrink-0",
836
843
  children: /* @__PURE__ */ d("svg", {
837
- className: "w-5 h-5 text-destructive",
844
+ className: "size-5 text-destructive",
838
845
  fill: "none",
839
846
  viewBox: "0 0 24 24",
840
847
  stroke: "currentColor",
@@ -897,53 +904,53 @@ var g = {
897
904
  className: `hover:bg-muted/30 transition-colors ${t ? "bg-muted/20" : ""}`,
898
905
  children: [
899
906
  /* @__PURE__ */ d("td", {
900
- className: "px-4 py-4",
907
+ className: "p-4",
901
908
  children: /* @__PURE__ */ d("input", {
902
909
  type: "checkbox",
903
910
  checked: t,
904
911
  onChange: (t) => r(e.id, t.target.checked),
905
912
  "aria-label": `Select discount ${e.code}`,
906
- className: "h-4 w-4 rounded border-border text-primary"
913
+ className: "size-4 rounded border-border text-primary"
907
914
  })
908
915
  }),
909
916
  /* @__PURE__ */ d("td", {
910
- className: "px-4 py-4",
917
+ className: "p-4",
911
918
  children: /* @__PURE__ */ d("span", {
912
919
  className: "font-mono font-medium text-foreground",
913
920
  children: e.code
914
921
  })
915
922
  }),
916
923
  /* @__PURE__ */ d("td", {
917
- className: "px-4 py-4",
924
+ className: "p-4",
918
925
  children: /* @__PURE__ */ d("span", {
919
926
  className: "text-sm text-muted-foreground",
920
927
  children: e.type === "PERCENTAGE" ? "Percentage" : "Fixed"
921
928
  })
922
929
  }),
923
930
  /* @__PURE__ */ d("td", {
924
- className: "px-4 py-4",
931
+ className: "p-4",
925
932
  children: /* @__PURE__ */ d("span", {
926
933
  className: "text-sm font-medium text-foreground",
927
934
  children: h(e)
928
935
  })
929
936
  }),
930
937
  /* @__PURE__ */ d("td", {
931
- className: "px-4 py-4 hidden md:table-cell",
938
+ className: "p-4 hidden md:table-cell",
932
939
  children: /* @__PURE__ */ f("span", {
933
940
  className: "text-sm text-muted-foreground",
934
941
  children: [e.usedCount, e.maxUses == null ? " / ∞" : ` / ${e.maxUses}`]
935
942
  })
936
943
  }),
937
944
  /* @__PURE__ */ d("td", {
938
- className: "px-4 py-4 text-sm text-muted-foreground hidden lg:table-cell",
945
+ className: "p-4 text-sm text-muted-foreground hidden lg:table-cell",
939
946
  children: e.validFrom ? n(e.validFrom, "short") : "—"
940
947
  }),
941
948
  /* @__PURE__ */ d("td", {
942
- className: "px-4 py-4 text-sm text-muted-foreground hidden sm:table-cell",
949
+ className: "p-4 text-sm text-muted-foreground hidden sm:table-cell",
943
950
  children: e.validUntil ? n(e.validUntil, "short") : "—"
944
951
  }),
945
952
  /* @__PURE__ */ d("td", {
946
- className: "px-4 py-4",
953
+ className: "p-4",
947
954
  children: o ? /* @__PURE__ */ d("span", {
948
955
  className: "inline-flex px-2 py-1 text-xs font-medium rounded bg-status-warning-bg-subtle text-status-warning-text",
949
956
  children: "Expired"
@@ -953,15 +960,16 @@ var g = {
953
960
  })
954
961
  }),
955
962
  /* @__PURE__ */ d("td", {
956
- className: "px-4 py-4 text-right",
963
+ className: "p-4 text-right",
957
964
  children: /* @__PURE__ */ f("div", {
958
965
  className: "flex items-center justify-end gap-2",
959
966
  children: [/* @__PURE__ */ d("button", {
967
+ type: "button",
960
968
  onClick: () => i(e),
961
969
  className: "px-3 py-1.5 text-sm font-medium text-foreground hover:bg-muted rounded-md transition-colors",
962
970
  title: "Edit discount",
963
971
  children: /* @__PURE__ */ d("svg", {
964
- className: "w-4 h-4",
972
+ className: "size-4",
965
973
  fill: "none",
966
974
  viewBox: "0 0 24 24",
967
975
  stroke: "currentColor",
@@ -973,11 +981,12 @@ var g = {
973
981
  })
974
982
  })
975
983
  }), /* @__PURE__ */ d("button", {
984
+ type: "button",
976
985
  onClick: () => a(e),
977
986
  className: "px-3 py-1.5 text-sm font-medium text-destructive hover:bg-destructive/10 rounded-md transition-colors",
978
987
  title: "Delete discount",
979
988
  children: /* @__PURE__ */ d("svg", {
980
- className: "w-4 h-4",
989
+ className: "size-4",
981
990
  fill: "none",
982
991
  viewBox: "0 0 24 24",
983
992
  stroke: "currentColor",