@burdenoff/microfe-billing 2026.805.1 → 2026.821.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.
@@ -136,7 +136,7 @@ var _ = () => {
136
136
  children: v("billing.overview.loadingInfo", "Loading billing information...")
137
137
  })]
138
138
  })
139
- }) : !V && I.length === 0 ? /* @__PURE__ */ m("div", {
139
+ }) : !V && I.length === 0 && !L ? /* @__PURE__ */ m("div", {
140
140
  className: "px-6 lg:px-8 py-6",
141
141
  children: [
142
142
  /* @__PURE__ */ m("header", {
@@ -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 { 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';\nimport {\n Button,\n CTAOverflowMenu,\n GlassCard,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\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-text-link\" />\n <p className=\"text-sm text-text-secondary\">\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=\"px-6 lg:px-8 py-6\">\n <header className=\"relative overflow-hidden mb-8 rounded-card\">\n <AuroraBackground intensity=\"subtle\" />\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n <GradientText>{tr('billing.overview.title', 'Billing Overview')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n {tr(\n 'billing.overview.emptySetupDescription',\n 'Set up billing to manage subscriptions, payments, and invoices'\n )}\n </p>\n </header>\n <IllustratedEmptyState\n illustration=\"onboarding\"\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-action-primary-text bg-action-primary-bg rounded-button hover:bg-action-primary-bgHover transition-colors duration-200\"\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=\"px-6 lg:px-8 py-6 space-y-6 sm:space-y-8\">\n {/* Header */}\n <header className=\"relative overflow-hidden rounded-card flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4\">\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n <GradientText>{tr('billing.overview.title', 'Billing Overview')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n {tr(\n 'billing.overview.description',\n 'Manage your billing accounts, subscriptions, and payment methods'\n )}\n </p>\n <PagePurpose className=\"mt-3\">\n {tr(\n 'billing.overview.purpose',\n 'Your billing home base — see your current plan, credit balance and payment methods at a glance, and jump to transactions, usage, credits or new plans. Start here to understand what you are paying for and manage it.'\n )}\n </PagePurpose>\n </div>\n <CTAOverflowMenu\n primary={\n permissions.canManageBillingAccount && billingAccounts.length > 0\n ? {\n label: tr('billing.overview.newAccount', 'New Account'),\n onSelect: () => setIsCreateModalOpen(true),\n icon: <Plus className=\"size-4\" />,\n }\n : undefined\n }\n actions={[\n {\n label: tr('billing.overview.refresh', 'Refresh'),\n onSelect: () => {\n void handleRefresh();\n },\n icon: <RefreshCw className={`size-4 ${isLoading ? 'animate-spin' : ''}`} />,\n },\n ]}\n />\n </header>\n\n {/* Account Selector (if multiple accounts) */}\n {billingAccounts.length > 1 && (\n <div className=\"relative\" data-tour=\"billing-overview-account-selector\">\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-seam rounded-card bg-bg-surface hover:bg-bg-sunken hover:border-border-strong transition-all duration-200\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-9 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <Building2 className=\"size-4 text-text-link\" />\n </div>\n <div className=\"text-left\">\n <p className=\"text-sm font-medium text-text-primary\">\n {currentAccount?.name || tr('billing.overview.selectAccount', 'Select Account')}\n </p>\n <p className=\"text-xs text-text-secondary\">{currentAccount?.email}</p>\n </div>\n </div>\n <ChevronDown\n className={`size-4 text-text-muted 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-bg-elevated border border-border-seam rounded-card shadow-elevation-3 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-bg-sunken transition-colors\"\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-9 rounded-lg bg-bg-sunken flex items-center justify-center flex-shrink-0\">\n <Building2 className=\"size-4 text-text-secondary\" />\n </div>\n <div className=\"text-left min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {account.name}\n </p>\n <p className=\"text-xs text-text-secondary truncate\">{account.email}</p>\n </div>\n </div>\n {currentAccount?.id === account.id && (\n <Check className=\"size-4 text-text-link flex-shrink-0\" />\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Stats Row */}\n {currentAccount && (\n <div\n className=\"grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4\"\n data-tour=\"billing-overview-stats-row\"\n >\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 dataTour=\"billing-overview-billing-account-card\"\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-seam rounded-card bg-bg-surface hover:bg-bg-sunken hover:border-border-strong transition-all duration-200\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-9 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <Crown className=\"size-4 text-text-link\" />\n </div>\n <div className=\"text-left\">\n <p className=\"text-sm font-medium text-text-primary\">\n {selectedSubscription?.plan?.name ||\n tr('billing.overview.selectSubscription', 'Select Subscription')}\n {selectedSubscription?.plan?.product?.name && (\n <span className=\"text-text-secondary font-normal\">\n {' '}\n · {selectedSubscription.plan.product.name}\n </span>\n )}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {activeSubscriptions.length}{' '}\n {tr('billing.overview.activeSubscriptions', 'active subscriptions')}\n </p>\n </div>\n </div>\n <ChevronDown\n className={`size-4 text-text-muted 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-bg-elevated border border-border-seam rounded-card shadow-elevation-3 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-bg-sunken transition-colors\"\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-9 rounded-lg bg-bg-sunken flex items-center justify-center flex-shrink-0\">\n <Crown className=\"size-4 text-text-secondary\" />\n </div>\n <div className=\"text-left min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {subscription.plan?.name ||\n tr('billing.overview.subscription', 'Subscription')}\n </p>\n <p className=\"text-xs text-text-secondary 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-text-link flex-shrink-0\" />\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Single Subscription Card */}\n <ActiveSubscriptionCard\n dataTour=\"billing-overview-active-subscription-card\"\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 dataTour=\"billing-overview-payment-methods-section\"\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\n className=\"border border-border-seam rounded-card bg-bg-surface shadow-elevation-1 p-5\"\n data-tour=\"billing-overview-quick-actions\"\n >\n <h3 className=\"font-semibold text-text-primary mb-4\">Quick Actions</h3>\n <div className=\"space-y-1.5\">\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-text-primary hover:bg-bg-sunken rounded-button transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-9 rounded-lg bg-status-info-bg-subtle flex items-center justify-center\">\n <Receipt className=\"size-4 text-status-info-text\" />\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-text-primary hover:bg-bg-sunken rounded-button transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-9 rounded-lg 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-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n <div className=\"size-9 rounded-lg 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-text-primary hover:bg-bg-sunken rounded-button transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-9 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <Activity className=\"size-4 text-text-link\" />\n </div>\n Usage Analytics\n </button>\n </div>\n </section>\n\n {/* Get Started (if no subscription) — primary emphasis zone */}\n {!hasActiveSubscription && (\n <GlassCard treatment=\"glass\" glow className=\"p-5\">\n <div className=\"flex items-start gap-3 mb-4\">\n <div className=\"size-10 rounded-lg bg-bg-surface flex items-center justify-center flex-shrink-0 shadow-elevation-1\">\n <Sparkles className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h3 className=\"font-semibold text-text-primary\">Get Started</h3>\n <p className=\"text-sm text-text-secondary mt-1\">\n Choose a plan that fits your needs to unlock all features\n </p>\n </div>\n </div>\n <Button type=\"button\" onClick={() => navigateTo('/plans')} className=\"w-full\">\n Browse Plans\n <ArrowRight className=\"size-4\" />\n </Button>\n </GlassCard>\n )}\n </div>\n </div>\n\n {/* Recommended Addons (only if has subscription) - Limited to 3 with cart support */}\n <RecommendedAddonsSection\n dataTour=\"billing-overview-recommended-addons\"\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 { 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';\nimport {\n Button,\n CTAOverflowMenu,\n GlassCard,\n AuroraBackground,\n GradientText,\n IllustratedEmptyState,\n PagePurpose,\n} from '@burdenoff/fe-libs/ui';\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-text-link\" />\n <p className=\"text-sm text-text-secondary\">\n {tr('billing.overview.loadingInfo', 'Loading billing information...')}\n </p>\n </div>\n </div>\n );\n }\n\n // No billing accounts state. Checked against `billingAccounts` AND\n // `currentAccount` (not just the list) because getDefaultBillingAccount\n // lazy-creates a default account for a brand-new org — on that exact\n // first request, getBillingAccountsByOrg's plain read can still observe\n // zero rows in the same response that returned a real, freshly-created\n // currentAccount. A valid currentAccount always means there's a real\n // billing account regardless of what the (possibly momentarily stale)\n // list says.\n if (!isLoading && billingAccounts.length === 0 && !currentAccount) {\n return (\n <div className=\"px-6 lg:px-8 py-6\">\n <header className=\"relative overflow-hidden mb-8 rounded-card\">\n <AuroraBackground intensity=\"subtle\" />\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n <GradientText>{tr('billing.overview.title', 'Billing Overview')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n {tr(\n 'billing.overview.emptySetupDescription',\n 'Set up billing to manage subscriptions, payments, and invoices'\n )}\n </p>\n </header>\n <IllustratedEmptyState\n illustration=\"onboarding\"\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-action-primary-text bg-action-primary-bg rounded-button hover:bg-action-primary-bgHover transition-colors duration-200\"\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=\"px-6 lg:px-8 py-6 space-y-6 sm:space-y-8\">\n {/* Header */}\n <header className=\"relative overflow-hidden rounded-card flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4\">\n <AuroraBackground intensity=\"subtle\" />\n <div>\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n <GradientText>{tr('billing.overview.title', 'Billing Overview')}</GradientText>\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n {tr(\n 'billing.overview.description',\n 'Manage your billing accounts, subscriptions, and payment methods'\n )}\n </p>\n <PagePurpose className=\"mt-3\">\n {tr(\n 'billing.overview.purpose',\n 'Your billing home base — see your current plan, credit balance and payment methods at a glance, and jump to transactions, usage, credits or new plans. Start here to understand what you are paying for and manage it.'\n )}\n </PagePurpose>\n </div>\n <CTAOverflowMenu\n primary={\n permissions.canManageBillingAccount && billingAccounts.length > 0\n ? {\n label: tr('billing.overview.newAccount', 'New Account'),\n onSelect: () => setIsCreateModalOpen(true),\n icon: <Plus className=\"size-4\" />,\n }\n : undefined\n }\n actions={[\n {\n label: tr('billing.overview.refresh', 'Refresh'),\n onSelect: () => {\n void handleRefresh();\n },\n icon: <RefreshCw className={`size-4 ${isLoading ? 'animate-spin' : ''}`} />,\n },\n ]}\n />\n </header>\n\n {/* Account Selector (if multiple accounts) */}\n {billingAccounts.length > 1 && (\n <div className=\"relative\" data-tour=\"billing-overview-account-selector\">\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-seam rounded-card bg-bg-surface hover:bg-bg-sunken hover:border-border-strong transition-all duration-200\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-9 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <Building2 className=\"size-4 text-text-link\" />\n </div>\n <div className=\"text-left\">\n <p className=\"text-sm font-medium text-text-primary\">\n {currentAccount?.name || tr('billing.overview.selectAccount', 'Select Account')}\n </p>\n <p className=\"text-xs text-text-secondary\">{currentAccount?.email}</p>\n </div>\n </div>\n <ChevronDown\n className={`size-4 text-text-muted 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-bg-elevated border border-border-seam rounded-card shadow-elevation-3 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-bg-sunken transition-colors\"\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-9 rounded-lg bg-bg-sunken flex items-center justify-center flex-shrink-0\">\n <Building2 className=\"size-4 text-text-secondary\" />\n </div>\n <div className=\"text-left min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {account.name}\n </p>\n <p className=\"text-xs text-text-secondary truncate\">{account.email}</p>\n </div>\n </div>\n {currentAccount?.id === account.id && (\n <Check className=\"size-4 text-text-link flex-shrink-0\" />\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Stats Row */}\n {currentAccount && (\n <div\n className=\"grid grid-cols-1 xs:grid-cols-2 sm:grid-cols-4 gap-3 sm:gap-4\"\n data-tour=\"billing-overview-stats-row\"\n >\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 dataTour=\"billing-overview-billing-account-card\"\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-seam rounded-card bg-bg-surface hover:bg-bg-sunken hover:border-border-strong transition-all duration-200\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-9 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <Crown className=\"size-4 text-text-link\" />\n </div>\n <div className=\"text-left\">\n <p className=\"text-sm font-medium text-text-primary\">\n {selectedSubscription?.plan?.name ||\n tr('billing.overview.selectSubscription', 'Select Subscription')}\n {selectedSubscription?.plan?.product?.name && (\n <span className=\"text-text-secondary font-normal\">\n {' '}\n · {selectedSubscription.plan.product.name}\n </span>\n )}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {activeSubscriptions.length}{' '}\n {tr('billing.overview.activeSubscriptions', 'active subscriptions')}\n </p>\n </div>\n </div>\n <ChevronDown\n className={`size-4 text-text-muted 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-bg-elevated border border-border-seam rounded-card shadow-elevation-3 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-bg-sunken transition-colors\"\n >\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-9 rounded-lg bg-bg-sunken flex items-center justify-center flex-shrink-0\">\n <Crown className=\"size-4 text-text-secondary\" />\n </div>\n <div className=\"text-left min-w-0\">\n <p className=\"text-sm font-medium text-text-primary truncate\">\n {subscription.plan?.name ||\n tr('billing.overview.subscription', 'Subscription')}\n </p>\n <p className=\"text-xs text-text-secondary 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-text-link flex-shrink-0\" />\n )}\n </button>\n ))}\n </div>\n </>\n )}\n </div>\n )}\n\n {/* Single Subscription Card */}\n <ActiveSubscriptionCard\n dataTour=\"billing-overview-active-subscription-card\"\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 dataTour=\"billing-overview-payment-methods-section\"\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\n className=\"border border-border-seam rounded-card bg-bg-surface shadow-elevation-1 p-5\"\n data-tour=\"billing-overview-quick-actions\"\n >\n <h3 className=\"font-semibold text-text-primary mb-4\">Quick Actions</h3>\n <div className=\"space-y-1.5\">\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-text-primary hover:bg-bg-sunken rounded-button transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-9 rounded-lg bg-status-info-bg-subtle flex items-center justify-center\">\n <Receipt className=\"size-4 text-status-info-text\" />\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-text-primary hover:bg-bg-sunken rounded-button transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-9 rounded-lg 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-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n <div className=\"size-9 rounded-lg 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-text-primary hover:bg-bg-sunken rounded-button transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n <div className=\"size-9 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <Activity className=\"size-4 text-text-link\" />\n </div>\n Usage Analytics\n </button>\n </div>\n </section>\n\n {/* Get Started (if no subscription) — primary emphasis zone */}\n {!hasActiveSubscription && (\n <GlassCard treatment=\"glass\" glow className=\"p-5\">\n <div className=\"flex items-start gap-3 mb-4\">\n <div className=\"size-10 rounded-lg bg-bg-surface flex items-center justify-center flex-shrink-0 shadow-elevation-1\">\n <Sparkles className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h3 className=\"font-semibold text-text-primary\">Get Started</h3>\n <p className=\"text-sm text-text-secondary mt-1\">\n Choose a plan that fits your needs to unlock all features\n </p>\n </div>\n </div>\n <Button type=\"button\" onClick={() => navigateTo('/plans')} className=\"w-full\">\n Browse Plans\n <ArrowRight className=\"size-4\" />\n </Button>\n </GlassCard>\n )}\n </div>\n </div>\n\n {/* Recommended Addons (only if has subscription) - Limited to 3 with cart support */}\n <RecommendedAddonsSection\n dataTour=\"billing-overview-recommended-addons\"\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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"}
@@ -3100,6 +3100,7 @@ t`
3100
3100
  quotaName: $quotaName
3101
3101
  productId: $productId
3102
3102
  ) {
3103
+ assigned
3103
3104
  limitLeft
3104
3105
  noLimit
3105
3106
  }