@burdenoff/microfe-billing 2026.625.4 → 2026.626.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 (96) hide show
  1. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +192 -187
  2. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  3. package/dist/billing/modules/addons/pages/AddonCreatePage.js +322 -317
  4. package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
  5. package/dist/billing/modules/addons/pages/AddonDetailPage.js +190 -185
  6. package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
  7. package/dist/billing/modules/addons/pages/AddonEditPage.js +297 -292
  8. package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
  9. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +60 -75
  10. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  11. package/dist/billing/modules/addons/pages/AddonsListPage.js +86 -101
  12. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  13. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +124 -121
  14. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  15. package/dist/billing/modules/analytics/pages/AnalyticsPage.js +103 -111
  16. package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
  17. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +196 -160
  18. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  19. package/dist/billing/modules/billing/pages/InvoicesListPage.js +58 -73
  20. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  21. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +65 -75
  22. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  23. package/dist/billing/modules/billing/pages/RefundsPage.js +399 -399
  24. package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
  25. package/dist/billing/modules/billing/pages/TransactionsPage.js +49 -48
  26. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  27. package/dist/billing/modules/billing/pages/UserRefundsPage.js +144 -151
  28. package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
  29. package/dist/billing/modules/checkout/pages/CheckoutPage.js +430 -425
  30. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  31. package/dist/billing/modules/coupons/pages/CouponDetailPage.js +121 -93
  32. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  33. package/dist/billing/modules/coupons/pages/CouponsListPage.js +154 -152
  34. package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
  35. package/dist/billing/modules/coupons/pages/CreateCouponPage.js +467 -462
  36. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  37. package/dist/billing/modules/coupons/pages/EditCouponPage.js +294 -286
  38. package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
  39. package/dist/billing/modules/credits/pages/AdminCreditsPage.js +123 -117
  40. package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
  41. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +43 -42
  42. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
  43. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +192 -207
  44. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  45. package/dist/billing/modules/credits/pages/CreditsPage.js +40 -56
  46. package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
  47. package/dist/billing/modules/dashboard/pages/OverviewPage.js +128 -121
  48. package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
  49. package/dist/billing/modules/discounts/pages/DiscountsListPage.js +165 -180
  50. package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
  51. package/dist/billing/modules/earnings/pages/EarningsPage.js +103 -100
  52. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  53. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +175 -175
  54. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  55. package/dist/billing/modules/earnings/pages/PayoutsPage.js +96 -96
  56. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  57. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +42 -40
  58. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  59. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +45 -38
  60. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
  61. package/dist/billing/modules/plans/pages/PlanCreatePage.js +339 -334
  62. package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
  63. package/dist/billing/modules/plans/pages/PlanDetailPage.js +80 -74
  64. package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
  65. package/dist/billing/modules/plans/pages/PlanEditPage.js +342 -337
  66. package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
  67. package/dist/billing/modules/plans/pages/PlansBrowsePage.js +38 -53
  68. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  69. package/dist/billing/modules/plans/pages/PlansListPage.js +60 -75
  70. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  71. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +242 -237
  72. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  73. package/dist/billing/modules/promotions/pages/PromotionsListPage.js +29 -39
  74. package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
  75. package/dist/billing/modules/quota/pages/QuotaPage.js +1 -0
  76. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +299 -294
  77. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
  78. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +191 -186
  79. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
  80. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +308 -303
  81. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
  82. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +57 -78
  83. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  84. package/dist/billing/modules/settings/pages/SettingsPage.js +79 -78
  85. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  86. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +15 -13
  87. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  88. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +338 -299
  89. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  90. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +82 -103
  91. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  92. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +59 -54
  93. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  94. package/dist/billing/modules/usage/pages/UsagePage.js +172 -215
  95. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  96. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"CreditWithdrawalPage.js","names":[],"sources":["../../../../../src/billing/modules/credits/pages/CreditWithdrawalPage.tsx"],"sourcesContent":["/**\n * Credits Module - Credit Withdrawal Page\n * Allows users to withdraw withdrawable credits (purchased + earned) to a payout account.\n */\n\nimport { useState, useEffect, type FC } from 'react';\nimport {\n CreditWithdrawalHistoryDocument,\n GetCreditBalanceByTypeDocument,\n RequestCreditWithdrawalDocument,\n useGetCostOfCreditsCheckoutQuery,\n} from '../../../../generated/global-operations';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useDefaultBillingAccount } from '../../subscriptions/hooks';\nimport { directBillingGraphqlRequest } from '../../../shared/utils';\nimport {\n fetchPayoutAccounts,\n addPayoutAccount,\n type PayoutAccount,\n type PayoutRequest,\n} from '../../earnings/api';\nimport { formatDate, formatRelativeTime } from '../../../shared/utils/format';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport type { CreditBalanceByType } from '../../../shared/types';\n\n// ============================================================================\n// API helpers (credit-specific)\n// ============================================================================\n\ninterface GatewayContext {\n apiGatewayUrl?: string;\n authToken?: string;\n orgId?: string;\n}\n\nasync function fetchCreditBalanceByType(\n billingAccountId: string,\n ctx: GatewayContext\n): Promise<CreditBalanceByType> {\n const data = await directBillingGraphqlRequest<\n { getCreditBalanceByType: CreditBalanceByType },\n { billingAccountId: string }\n >({\n ...ctx,\n query: GetCreditBalanceByTypeDocument,\n variables: { billingAccountId },\n });\n return data.getCreditBalanceByType;\n}\n\nasync function requestCreditWithdrawal(\n input: {\n billingAccountId: string;\n creditAmount: number;\n payoutAccountId: string;\n currency?: string;\n notes?: string;\n },\n ctx: GatewayContext\n): Promise<{ id: string; status: string; requestedAmount: number; currency: string }> {\n const data = await directBillingGraphqlRequest<\n {\n requestCreditWithdrawal: {\n id: string;\n status: string;\n requestedAmount: number;\n currency: string;\n };\n },\n { input: typeof input }\n >({\n ...ctx,\n query: RequestCreditWithdrawalDocument,\n variables: { input },\n });\n return data.requestCreditWithdrawal;\n}\n\nasync function fetchCreditWithdrawalHistory(\n billingAccountId: string,\n ctx: GatewayContext\n): Promise<PayoutRequest[]> {\n const data = await directBillingGraphqlRequest<\n { myPayoutRequests: { items: PayoutRequest[] } },\n { billingAccountId: string }\n >({\n ...ctx,\n query: CreditWithdrawalHistoryDocument,\n variables: { billingAccountId },\n });\n return data.myPayoutRequests.items;\n}\n\n// ============================================================================\n// Sub-components\n// ============================================================================\n\ninterface BalanceCardProps {\n label: string;\n value: number;\n description?: string;\n highlight?: boolean;\n}\n\nconst BalanceCard: FC<BalanceCardProps> = ({ label, value, description, highlight }) => (\n <div\n className={`border border-border-subtle rounded-lg p-5 ${\n highlight\n ? 'bg-gradient-to-br from-[var(--color-accent-soft)] to-[var(--color-accent-soft)]'\n : 'bg-bg-surface'\n }`}\n >\n <p className=\"text-sm text-text-secondary\">{label}</p>\n <p className={`text-2xl font-bold mt-1 ${highlight ? 'text-text-link' : 'text-text-primary'}`}>\n {value.toLocaleString()} <span className=\"text-base font-normal\">credits</span>\n </p>\n {description && <p className=\"text-xs text-text-secondary mt-1\">{description}</p>}\n </div>\n);\n\nfunction getWithdrawalStatusColor(status: string): string {\n switch (status.toUpperCase()) {\n case 'PAID':\n return statusTokens.success.text;\n case 'APPROVED':\n case 'PROCESSING':\n return statusTokens.info.text;\n case 'REQUESTED':\n return statusTokens.warning.text;\n case 'REJECTED':\n case 'FAILED':\n case 'CANCELED':\n return statusTokens.error.text;\n default:\n return 'text-text-secondary';\n }\n}\n\nfunction getWithdrawalStatusBg(status: string): string {\n switch (status.toUpperCase()) {\n case 'PAID':\n return `${statusTokens.success.bg} ${statusTokens.success.text}`;\n case 'APPROVED':\n case 'PROCESSING':\n return `${statusTokens.info.bg} ${statusTokens.info.text}`;\n case 'REQUESTED':\n return `${statusTokens.warning.bg} ${statusTokens.warning.text}`;\n case 'REJECTED':\n case 'FAILED':\n case 'CANCELED':\n return `${statusTokens.error.bg} ${statusTokens.error.text}`;\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\n// ============================================================================\n// Main Page\n// ============================================================================\n\nexport const CreditWithdrawalPage: FC = () => {\n const permissions = useBillingPermissions();\n const { billingAccount, isLoading: isLoadingAccount } = useDefaultBillingAccount();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n const { emit } = useBillingEventEmitter();\n\n // Balance state\n const [balance, setBalance] = useState<CreditBalanceByType | null>(null);\n const [isLoadingBalance, setIsLoadingBalance] = useState(false);\n const [balanceError, setBalanceError] = useState<string | null>(null);\n\n // Payout accounts state\n const [payoutAccounts, setPayoutAccounts] = useState<PayoutAccount[]>([]);\n const [isLoadingAccounts, setIsLoadingAccounts] = useState(false);\n\n // Withdrawal history state\n const [history, setHistory] = useState<PayoutRequest[]>([]);\n const [isLoadingHistory, setIsLoadingHistory] = useState(false);\n\n // Withdrawal form state\n const [selectedAccountId, setSelectedAccountId] = useState<string>('');\n const [creditAmount, setCreditAmount] = useState<string>('');\n const [notes, setNotes] = useState<string>('');\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [submitSuccess, setSubmitSuccess] = useState(false);\n\n // New payout account form state\n const [showAddAccount, setShowAddAccount] = useState(false);\n const [accountForm, setAccountForm] = useState({\n label: '',\n type: 'BANK_ACCOUNT' as 'BANK_ACCOUNT' | 'UPI',\n accountHolderName: '',\n accountNumber: '',\n ifscCode: '',\n routingNumber: '',\n upiId: '',\n country: '',\n currency: 'USD',\n });\n const [isAddingAccount, setIsAddingAccount] = useState(false);\n const [addAccountError, setAddAccountError] = useState<string | null>(null);\n\n const billingAccountId = billingAccount?.id;\n\n const getCtx = (): GatewayContext => ({\n apiGatewayUrl,\n authToken,\n orgId,\n });\n\n const loadBalance = async () => {\n if (!billingAccountId) return;\n setIsLoadingBalance(true);\n setBalanceError(null);\n try {\n const b = await fetchCreditBalanceByType(billingAccountId, getCtx());\n setBalance(b);\n } catch (e) {\n setBalanceError(e instanceof Error ? e.message : 'Failed to load balance');\n } finally {\n setIsLoadingBalance(false);\n }\n };\n\n const loadAccounts = async () => {\n if (!billingAccountId) return;\n setIsLoadingAccounts(true);\n try {\n const accounts = await fetchPayoutAccounts(billingAccountId, getCtx());\n setPayoutAccounts(accounts);\n const defaultAcc = accounts.find((a) => a.isDefault) ?? accounts[0];\n if (defaultAcc) setSelectedAccountId(defaultAcc.id);\n } catch {\n // silently fail - user will see empty state\n } finally {\n setIsLoadingAccounts(false);\n }\n };\n\n const loadHistory = async () => {\n if (!billingAccountId) return;\n setIsLoadingHistory(true);\n try {\n const items = await fetchCreditWithdrawalHistory(billingAccountId, getCtx());\n setHistory(items);\n } catch {\n // silently fail\n } finally {\n setIsLoadingHistory(false);\n }\n };\n\n useEffect(() => {\n if (billingAccountId) {\n void loadBalance();\n void loadAccounts();\n void loadHistory();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [billingAccountId]);\n\n // Sync payout account currency to billing account currency when it loads\n useEffect(() => {\n if (billingAccount?.currency) {\n setAccountForm((f) => ({ ...f, currency: billingAccount.currency ?? 'USD' }));\n }\n }, [billingAccount?.currency]);\n\n const handleAddAccount = async () => {\n if (!billingAccountId) return;\n setAddAccountError(null);\n setIsAddingAccount(true);\n try {\n const isIndia =\n accountForm.country.trim().toUpperCase() === 'IN' ||\n accountForm.country.trim().toLowerCase() === 'india';\n\n await addPayoutAccount(\n {\n billingAccountId,\n label: accountForm.label,\n type: accountForm.type,\n accountHolderName: accountForm.accountHolderName,\n country: accountForm.country || undefined,\n currency: accountForm.currency,\n ...(accountForm.type === 'BANK_ACCOUNT' && {\n accountNumber: accountForm.accountNumber,\n ...(isIndia\n ? { ifsc: accountForm.ifscCode }\n : { routingNumber: accountForm.routingNumber }),\n }),\n ...(accountForm.type === 'UPI' && { upiId: accountForm.upiId }),\n },\n getCtx()\n );\n emit('billing.payout_account.added', {\n route: '/billing/credits/withdraw',\n entityId: billingAccountId,\n source: 'credit-withdrawal',\n });\n await loadAccounts();\n setShowAddAccount(false);\n setAccountForm({\n label: '',\n type: 'BANK_ACCOUNT' as 'BANK_ACCOUNT' | 'UPI',\n accountHolderName: '',\n accountNumber: '',\n ifscCode: '',\n routingNumber: '',\n upiId: '',\n country: '',\n currency: 'USD',\n });\n } catch (e) {\n setAddAccountError(e instanceof Error ? e.message : 'Failed to add account');\n } finally {\n setIsAddingAccount(false);\n }\n };\n\n const handleWithdraw = async () => {\n if (!billingAccountId || !selectedAccountId) return;\n const amount = parseFloat(creditAmount);\n if (!amount || amount <= 0) return;\n\n setSubmitError(null);\n setIsSubmitting(true);\n try {\n const withdrawal = await requestCreditWithdrawal(\n {\n billingAccountId,\n creditAmount: amount,\n payoutAccountId: selectedAccountId,\n notes: notes || undefined,\n },\n getCtx()\n );\n emit('billing.credits.withdrawal_requested', {\n route: '/billing/credits/withdraw',\n entityId: withdrawal.id,\n source: 'credit-withdrawal',\n amount,\n });\n setSubmitSuccess(true);\n setCreditAmount('');\n setNotes('');\n await loadBalance();\n await loadHistory();\n } catch (e) {\n setSubmitError(e instanceof Error ? e.message : 'Withdrawal request failed');\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const accountCurrency = billingAccount?.currency ?? 'USD';\n const withdrawAmount = parseFloat(creditAmount) || 0;\n\n const { data: costData, loading: isFetchingCost } = useGetCostOfCreditsCheckoutQuery({\n variables: { creditAmount: withdrawAmount, currency: accountCurrency },\n skip: withdrawAmount <= 0 || !billingAccount,\n });\n\n const estimatedPayout = costData?.getCostOfCredits?.amount;\n\n // Permission check\n if (!permissions.canWithdrawCredits) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <div className=\"size-12 mx-auto rounded-full bg-bg-sunken flex items-center justify-center\">\n <svg\n className=\"size-6 text-text-secondary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary\">\n You don&apos;t have permission to withdraw credits.\n </p>\n </div>\n </div>\n );\n }\n\n if (!isLoadingAccount && !billingAccount) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold text-text-primary\">No Billing Account</h2>\n <p className=\"text-sm text-text-secondary\">\n You need a billing account to withdraw credits.\n </p>\n </div>\n </div>\n );\n }\n\n if (isLoadingAccount && !billingAccount) {\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n <div className=\"h-8 w-64 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className=\"border border-border-subtle rounded-lg p-5\">\n <div className=\"h-4 w-24 bg-bg-sunken animate-pulse rounded mb-2\" />\n <div className=\"h-8 w-32 bg-bg-sunken animate-pulse rounded\" />\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n const withdrawable = balance?.withdrawable ?? 0;\n const amountValid = withdrawAmount > 0 && withdrawAmount <= withdrawable;\n const activeAccounts = payoutAccounts.filter((a) => a.status !== 'ARCHIVED');\n\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n {/* Header */}\n <div>\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n Withdraw Credits\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n Convert your withdrawable credits (purchased &amp; earned) to a payout\n </p>\n </div>\n\n {/* Balance breakdown */}\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-4\">\n {isLoadingBalance ? (\n [1, 2, 3, 4].map((i) => (\n <div key={i} className=\"border border-border-subtle rounded-lg p-5\">\n <div className=\"h-4 w-20 bg-bg-sunken animate-pulse rounded mb-2\" />\n <div className=\"h-8 w-28 bg-bg-sunken animate-pulse rounded\" />\n </div>\n ))\n ) : balanceError ? (\n <div className=\"col-span-4 text-sm text-status-error-text\">{balanceError}</div>\n ) : (\n <>\n <BalanceCard\n label=\"Purchased\"\n value={balance?.purchased ?? 0}\n description=\"From credit purchases\"\n />\n <BalanceCard\n label=\"Earned\"\n value={balance?.earned ?? 0}\n description=\"From sales & referrals\"\n />\n <BalanceCard\n label=\"Granted\"\n value={balance?.granted ?? 0}\n description=\"Coupons & admin grants — non-withdrawable\"\n />\n <BalanceCard\n label=\"Withdrawable\"\n value={withdrawable}\n description=\"Purchased + earned\"\n highlight\n />\n </>\n )}\n </div>\n\n {/* Success banner */}\n {submitSuccess && (\n <div className=\"flex items-center gap-3 p-4 rounded-lg bg-status-success-bg-subtle border border-status-success-border text-status-success-text\">\n <svg className=\"size-5 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n <div>\n <p className=\"font-medium\">Withdrawal request submitted</p>\n <p className=\"text-sm opacity-80\">Our team will review and process your request.</p>\n </div>\n <button\n type=\"button\"\n onClick={() => setSubmitSuccess(false)}\n className=\"ml-auto text-current opacity-60 hover:opacity-100\"\n >\n <svg className=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n )}\n\n {/* Main two-column layout */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n {/* Left: Payout account management */}\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-base font-semibold text-text-primary\">Payout Account</h2>\n <button\n type=\"button\"\n onClick={() => setShowAddAccount((v) => !v)}\n className=\"text-sm text-text-link hover:underline\"\n >\n {showAddAccount ? 'Cancel' : '+ Add new'}\n </button>\n </div>\n\n {/* Add account form */}\n {showAddAccount && (\n <div className=\"border border-border-subtle rounded-lg p-4 space-y-3 bg-bg-sunken\">\n <h3 className=\"text-sm font-medium text-text-primary\">New Payout Account</h3>\n\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">Label</label>\n <input\n type=\"text\"\n value={accountForm.label}\n onChange={(e) => setAccountForm((f) => ({ ...f, label: e.target.value }))}\n placeholder=\"e.g. My Bank Account\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">\n Account Holder Name\n </label>\n <input\n type=\"text\"\n value={accountForm.accountHolderName}\n onChange={(e) =>\n setAccountForm((f) => ({ ...f, accountHolderName: e.target.value }))\n }\n placeholder=\"Full name as on bank account\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">Type</label>\n <select\n value={accountForm.type}\n onChange={(e) =>\n setAccountForm((f) => ({\n ...f,\n type: e.target.value as typeof accountForm.type,\n }))\n }\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"BANK_ACCOUNT\">Bank Account</option>\n <option value=\"UPI\">UPI</option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">Country</label>\n <input\n type=\"text\"\n value={accountForm.country}\n onChange={(e) => setAccountForm((f) => ({ ...f, country: e.target.value }))}\n placeholder=\"e.g. India, US, UK\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n\n {accountForm.type === 'BANK_ACCOUNT' && (\n <>\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">Account Number</label>\n <input\n type=\"text\"\n value={accountForm.accountNumber}\n onChange={(e) =>\n setAccountForm((f) => ({ ...f, accountNumber: e.target.value }))\n }\n placeholder=\"Account number\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n {accountForm.country.trim().toUpperCase() === 'IN' ||\n accountForm.country.trim().toLowerCase() === 'india' ? (\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">IFSC Code</label>\n <input\n type=\"text\"\n value={accountForm.ifscCode}\n onChange={(e) =>\n setAccountForm((f) => ({ ...f, ifscCode: e.target.value.toUpperCase() }))\n }\n placeholder=\"e.g. SBIN0001234\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n ) : (\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">\n Routing Number\n </label>\n <input\n type=\"text\"\n value={accountForm.routingNumber}\n onChange={(e) =>\n setAccountForm((f) => ({ ...f, routingNumber: e.target.value }))\n }\n placeholder=\"Routing / sort code\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n )}\n </>\n )}\n\n {accountForm.type === 'UPI' && (\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">UPI ID</label>\n <input\n type=\"text\"\n value={accountForm.upiId}\n onChange={(e) => setAccountForm((f) => ({ ...f, upiId: e.target.value }))}\n placeholder=\"yourname@upi\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n )}\n\n {addAccountError && (\n <p className=\"text-xs text-status-error-text\">{addAccountError}</p>\n )}\n\n <button\n type=\"button\"\n onClick={() => void handleAddAccount()}\n disabled={isAddingAccount || !accountForm.label || !accountForm.accountHolderName}\n className=\"w-full py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isAddingAccount ? 'Saving…' : 'Save Account'}\n </button>\n </div>\n )}\n\n {/* Existing accounts */}\n {isLoadingAccounts ? (\n <div className=\"space-y-2\">\n {[1, 2].map((i) => (\n <div\n key={i}\n className=\"h-16 border border-border-subtle rounded-lg bg-bg-sunken animate-pulse\"\n />\n ))}\n </div>\n ) : activeAccounts.length === 0 && !showAddAccount ? (\n <div className=\"flex flex-col items-center justify-center py-8 border border-dashed border-border-subtle rounded-lg\">\n <svg\n className=\"size-8 text-text-secondary mb-2\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z\"\n />\n </svg>\n <p className=\"text-sm text-text-secondary\">No payout accounts yet</p>\n <button\n type=\"button\"\n onClick={() => setShowAddAccount(true)}\n className=\"mt-2 text-sm text-text-link hover:underline\"\n >\n Add a bank account or UPI\n </button>\n </div>\n ) : (\n <div className=\"space-y-2\">\n {activeAccounts.map((account) => (\n <button\n type=\"button\"\n key={account.id}\n onClick={() => setSelectedAccountId(account.id)}\n className={`w-full text-left p-4 border rounded-lg transition-colors ${\n selectedAccountId === account.id\n ? 'border-border-strong bg-[var(--color-accent-soft)]'\n : 'border-border-subtle bg-bg-surface hover:border-border-strong'\n }`}\n >\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{account.label}</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {account.type.replaceAll('_', ' ')}\n {account.displayName ? ` · ${account.displayName}` : ''}\n {account.accountLast4 ? ` ···${account.accountLast4}` : ''}\n {account.country ? ` · ${account.country}` : ''}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n {account.isDefault && (\n <span className=\"text-xs px-2 py-0.5 rounded bg-[var(--color-accent-soft)] text-text-link font-medium\">\n Default\n </span>\n )}\n <span\n className={`text-xs px-2 py-0.5 rounded font-medium ${\n account.status === 'ACTIVE'\n ? `${statusTokens.success.bg} ${statusTokens.success.text}`\n : account.status === 'PENDING_VERIFICATION'\n ? `${statusTokens.warning.bg} ${statusTokens.warning.text}`\n : `${statusTokens.error.bg} ${statusTokens.error.text}`\n }`}\n >\n {account.status.replaceAll('_', ' ').toLowerCase()}\n </span>\n {selectedAccountId === account.id && (\n <svg\n className=\"size-4 text-text-link shrink-0\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Right: Withdrawal request form */}\n <div className=\"space-y-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">Request Withdrawal</h2>\n\n <div className=\"border border-border-subtle rounded-lg p-5 bg-bg-surface space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Credits to Withdraw\n </label>\n <input\n type=\"number\"\n min={1}\n max={withdrawable}\n step={1}\n value={creditAmount}\n onChange={(e) => setCreditAmount(e.target.value)}\n placeholder=\"Enter credit amount\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">\n Max withdrawable:{' '}\n <span className=\"font-medium\">{withdrawable.toLocaleString()} credits</span>\n </p>\n {withdrawAmount > 0 && withdrawAmount <= withdrawable && (\n <p className=\"text-xs text-text-secondary mt-1\">\n {isFetchingCost ? (\n 'Calculating…'\n ) : estimatedPayout != null ? (\n <>\n Estimated payout:{' '}\n <span className=\"font-semibold text-text-primary\">\n {estimatedPayout.toLocaleString(undefined, {\n style: 'currency',\n currency: accountCurrency,\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}\n </span>{' '}\n at the current credit rate\n </>\n ) : null}\n </p>\n )}\n {withdrawAmount > 0 && withdrawAmount > withdrawable && (\n <p className=\"text-xs text-status-error-text mt-1\">\n Amount exceeds your withdrawable balance\n </p>\n )}\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Notes <span className=\"text-text-secondary font-normal\">(optional)</span>\n </label>\n <textarea\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n placeholder=\"Any notes for this withdrawal request\"\n rows={2}\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n\n {submitError && (\n <div className=\"p-3 rounded-button bg-status-error-bg-subtle border border-status-error-border\">\n <p className=\"text-sm text-status-error-text\">{submitError}</p>\n </div>\n )}\n\n <div className=\"pt-1 border-t border-border-subtle\">\n <p className=\"text-xs text-text-secondary mb-3\">\n Credits will be converted to {accountCurrency} at the current credit rate.\n Withdrawals are reviewed before processing and may take 3–5 business days.\n </p>\n <button\n type=\"button\"\n onClick={() => void handleWithdraw()}\n disabled={\n isSubmitting || !amountValid || !selectedAccountId || activeAccounts.length === 0\n }\n className=\"w-full py-2.5 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isSubmitting ? 'Submitting…' : 'Request Withdrawal'}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n {/* Withdrawal history */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-base font-semibold text-text-primary\">Withdrawal History</h2>\n <button\n type=\"button\"\n onClick={() => void loadHistory()}\n className=\"text-sm text-text-secondary hover:text-text-primary transition-colors\"\n aria-label=\"Refresh withdrawal history\"\n >\n <svg className=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n </button>\n </div>\n\n {isLoadingHistory ? (\n <div className=\"space-y-2\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-16 border border-border-subtle rounded-lg bg-bg-sunken animate-pulse\"\n />\n ))}\n </div>\n ) : history.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-10 border border-dashed border-border-subtle rounded-lg\">\n <svg\n className=\"size-8 text-text-secondary mb-2\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={1.5}\n d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"\n />\n </svg>\n <p className=\"text-sm text-text-secondary\">No withdrawal requests yet</p>\n </div>\n ) : (\n <div className=\"border border-border-subtle rounded-lg overflow-hidden\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-bg-sunken border-b border-border-subtle\">\n <tr>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Amount\n </th>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Status\n </th>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide hidden sm:table-cell\">\n Payout Account\n </th>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide hidden md:table-cell\">\n Requested\n </th>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide hidden md:table-cell\">\n Completed\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-subtle\">\n {history.map((req) => (\n <tr key={req.id} className=\"hover:bg-bg-sunken transition-colors\">\n <td className=\"px-4 py-3 font-medium text-text-primary\">\n {req.requestedAmount.toLocaleString()} {req.currency}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${getWithdrawalStatusBg(req.status)}`}\n >\n {req.status.charAt(0) + req.status.slice(1).toLowerCase()}\n </span>\n {req.failureReason && (\n <p\n className=\"text-xs text-status-error-text mt-0.5 max-w-[180px] truncate\"\n title={req.failureReason}\n >\n {req.failureReason}\n </p>\n )}\n </td>\n <td className=\"px-4 py-3 text-text-secondary hidden sm:table-cell\">\n {req.payoutAccount ? (\n <span>\n {req.payoutAccount.label}\n {req.payoutAccount.accountLast4\n ? ` ···${req.payoutAccount.accountLast4}`\n : ''}\n </span>\n ) : (\n '—'\n )}\n </td>\n <td className=\"px-4 py-3 text-text-secondary hidden md:table-cell\">\n <span title={formatDate(req.createdAt, 'long')}>\n {formatRelativeTime(req.createdAt)}\n </span>\n </td>\n <td className=\"px-4 py-3 text-text-secondary hidden md:table-cell\">\n {req.paidAt ? (\n <span className={getWithdrawalStatusColor('PAID')}>\n {formatDate(req.paidAt, 'short')}\n </span>\n ) : (\n '—'\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"CreditWithdrawalPage.js","names":[],"sources":["../../../../../src/billing/modules/credits/pages/CreditWithdrawalPage.tsx"],"sourcesContent":["/**\n * Credits Module - Credit Withdrawal Page\n * Allows users to withdraw withdrawable credits (purchased + earned) to a payout account.\n */\n\nimport { useState, useEffect, type FC } from 'react';\nimport {\n CreditWithdrawalHistoryDocument,\n GetCreditBalanceByTypeDocument,\n RequestCreditWithdrawalDocument,\n useGetCostOfCreditsCheckoutQuery,\n} from '../../../../generated/global-operations';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useDefaultBillingAccount } from '../../subscriptions/hooks';\nimport { directBillingGraphqlRequest } from '../../../shared/utils';\nimport {\n fetchPayoutAccounts,\n addPayoutAccount,\n type PayoutAccount,\n type PayoutRequest,\n} from '../../earnings/api';\nimport { formatDate, formatRelativeTime } from '../../../shared/utils/format';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport type { CreditBalanceByType } from '../../../shared/types';\nimport { PagePurpose, EmphasisPanel, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\n\n// ============================================================================\n// API helpers (credit-specific)\n// ============================================================================\n\ninterface GatewayContext {\n apiGatewayUrl?: string;\n authToken?: string;\n orgId?: string;\n}\n\nasync function fetchCreditBalanceByType(\n billingAccountId: string,\n ctx: GatewayContext\n): Promise<CreditBalanceByType> {\n const data = await directBillingGraphqlRequest<\n { getCreditBalanceByType: CreditBalanceByType },\n { billingAccountId: string }\n >({\n ...ctx,\n query: GetCreditBalanceByTypeDocument,\n variables: { billingAccountId },\n });\n return data.getCreditBalanceByType;\n}\n\nasync function requestCreditWithdrawal(\n input: {\n billingAccountId: string;\n creditAmount: number;\n payoutAccountId: string;\n currency?: string;\n notes?: string;\n },\n ctx: GatewayContext\n): Promise<{ id: string; status: string; requestedAmount: number; currency: string }> {\n const data = await directBillingGraphqlRequest<\n {\n requestCreditWithdrawal: {\n id: string;\n status: string;\n requestedAmount: number;\n currency: string;\n };\n },\n { input: typeof input }\n >({\n ...ctx,\n query: RequestCreditWithdrawalDocument,\n variables: { input },\n });\n return data.requestCreditWithdrawal;\n}\n\nasync function fetchCreditWithdrawalHistory(\n billingAccountId: string,\n ctx: GatewayContext\n): Promise<PayoutRequest[]> {\n const data = await directBillingGraphqlRequest<\n { myPayoutRequests: { items: PayoutRequest[] } },\n { billingAccountId: string }\n >({\n ...ctx,\n query: CreditWithdrawalHistoryDocument,\n variables: { billingAccountId },\n });\n return data.myPayoutRequests.items;\n}\n\n// ============================================================================\n// Sub-components\n// ============================================================================\n\ninterface BalanceCardProps {\n label: string;\n value: number;\n description?: string;\n highlight?: boolean;\n}\n\nconst BalanceCard: FC<BalanceCardProps> = ({ label, value, description, highlight }) => {\n const body = (\n <>\n <p className=\"text-sm text-text-secondary\">{label}</p>\n <p\n className={`text-2xl font-bold mt-1 ${highlight ? 'text-text-link' : 'text-text-primary'}`}\n >\n {value.toLocaleString()} <span className=\"text-base font-normal\">credits</span>\n </p>\n {description && <p className=\"text-xs text-text-secondary mt-1\">{description}</p>}\n </>\n );\n // The withdrawable balance is the single most important figure on this page —\n // render it as the page's one emphasis zone.\n if (highlight) {\n return <EmphasisPanel className=\"p-5\">{body}</EmphasisPanel>;\n }\n return <div className=\"border border-border-subtle rounded-lg p-5 bg-bg-surface\">{body}</div>;\n};\n\nfunction getWithdrawalStatusColor(status: string): string {\n switch (status.toUpperCase()) {\n case 'PAID':\n return statusTokens.success.text;\n case 'APPROVED':\n case 'PROCESSING':\n return statusTokens.info.text;\n case 'REQUESTED':\n return statusTokens.warning.text;\n case 'REJECTED':\n case 'FAILED':\n case 'CANCELED':\n return statusTokens.error.text;\n default:\n return 'text-text-secondary';\n }\n}\n\nfunction getWithdrawalStatusBg(status: string): string {\n switch (status.toUpperCase()) {\n case 'PAID':\n return `${statusTokens.success.bg} ${statusTokens.success.text}`;\n case 'APPROVED':\n case 'PROCESSING':\n return `${statusTokens.info.bg} ${statusTokens.info.text}`;\n case 'REQUESTED':\n return `${statusTokens.warning.bg} ${statusTokens.warning.text}`;\n case 'REJECTED':\n case 'FAILED':\n case 'CANCELED':\n return `${statusTokens.error.bg} ${statusTokens.error.text}`;\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\n// ============================================================================\n// Main Page\n// ============================================================================\n\nexport const CreditWithdrawalPage: FC = () => {\n const permissions = useBillingPermissions();\n const { billingAccount, isLoading: isLoadingAccount } = useDefaultBillingAccount();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n const { emit } = useBillingEventEmitter();\n\n // Balance state\n const [balance, setBalance] = useState<CreditBalanceByType | null>(null);\n const [isLoadingBalance, setIsLoadingBalance] = useState(false);\n const [balanceError, setBalanceError] = useState<string | null>(null);\n\n // Payout accounts state\n const [payoutAccounts, setPayoutAccounts] = useState<PayoutAccount[]>([]);\n const [isLoadingAccounts, setIsLoadingAccounts] = useState(false);\n\n // Withdrawal history state\n const [history, setHistory] = useState<PayoutRequest[]>([]);\n const [isLoadingHistory, setIsLoadingHistory] = useState(false);\n\n // Withdrawal form state\n const [selectedAccountId, setSelectedAccountId] = useState<string>('');\n const [creditAmount, setCreditAmount] = useState<string>('');\n const [notes, setNotes] = useState<string>('');\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitError, setSubmitError] = useState<string | null>(null);\n const [submitSuccess, setSubmitSuccess] = useState(false);\n\n // New payout account form state\n const [showAddAccount, setShowAddAccount] = useState(false);\n const [accountForm, setAccountForm] = useState({\n label: '',\n type: 'BANK_ACCOUNT' as 'BANK_ACCOUNT' | 'UPI',\n accountHolderName: '',\n accountNumber: '',\n ifscCode: '',\n routingNumber: '',\n upiId: '',\n country: '',\n currency: 'USD',\n });\n const [isAddingAccount, setIsAddingAccount] = useState(false);\n const [addAccountError, setAddAccountError] = useState<string | null>(null);\n\n const billingAccountId = billingAccount?.id;\n\n const getCtx = (): GatewayContext => ({\n apiGatewayUrl,\n authToken,\n orgId,\n });\n\n const loadBalance = async () => {\n if (!billingAccountId) return;\n setIsLoadingBalance(true);\n setBalanceError(null);\n try {\n const b = await fetchCreditBalanceByType(billingAccountId, getCtx());\n setBalance(b);\n } catch (e) {\n setBalanceError(e instanceof Error ? e.message : 'Failed to load balance');\n } finally {\n setIsLoadingBalance(false);\n }\n };\n\n const loadAccounts = async () => {\n if (!billingAccountId) return;\n setIsLoadingAccounts(true);\n try {\n const accounts = await fetchPayoutAccounts(billingAccountId, getCtx());\n setPayoutAccounts(accounts);\n const defaultAcc = accounts.find((a) => a.isDefault) ?? accounts[0];\n if (defaultAcc) setSelectedAccountId(defaultAcc.id);\n } catch {\n // silently fail - user will see empty state\n } finally {\n setIsLoadingAccounts(false);\n }\n };\n\n const loadHistory = async () => {\n if (!billingAccountId) return;\n setIsLoadingHistory(true);\n try {\n const items = await fetchCreditWithdrawalHistory(billingAccountId, getCtx());\n setHistory(items);\n } catch {\n // silently fail\n } finally {\n setIsLoadingHistory(false);\n }\n };\n\n useEffect(() => {\n if (billingAccountId) {\n void loadBalance();\n void loadAccounts();\n void loadHistory();\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [billingAccountId]);\n\n // Sync payout account currency to billing account currency when it loads\n useEffect(() => {\n if (billingAccount?.currency) {\n setAccountForm((f) => ({ ...f, currency: billingAccount.currency ?? 'USD' }));\n }\n }, [billingAccount?.currency]);\n\n const handleAddAccount = async () => {\n if (!billingAccountId) return;\n setAddAccountError(null);\n setIsAddingAccount(true);\n try {\n const isIndia =\n accountForm.country.trim().toUpperCase() === 'IN' ||\n accountForm.country.trim().toLowerCase() === 'india';\n\n await addPayoutAccount(\n {\n billingAccountId,\n label: accountForm.label,\n type: accountForm.type,\n accountHolderName: accountForm.accountHolderName,\n country: accountForm.country || undefined,\n currency: accountForm.currency,\n ...(accountForm.type === 'BANK_ACCOUNT' && {\n accountNumber: accountForm.accountNumber,\n ...(isIndia\n ? { ifsc: accountForm.ifscCode }\n : { routingNumber: accountForm.routingNumber }),\n }),\n ...(accountForm.type === 'UPI' && { upiId: accountForm.upiId }),\n },\n getCtx()\n );\n emit('billing.payout_account.added', {\n route: '/billing/credits/withdraw',\n entityId: billingAccountId,\n source: 'credit-withdrawal',\n });\n await loadAccounts();\n setShowAddAccount(false);\n setAccountForm({\n label: '',\n type: 'BANK_ACCOUNT' as 'BANK_ACCOUNT' | 'UPI',\n accountHolderName: '',\n accountNumber: '',\n ifscCode: '',\n routingNumber: '',\n upiId: '',\n country: '',\n currency: 'USD',\n });\n } catch (e) {\n setAddAccountError(e instanceof Error ? e.message : 'Failed to add account');\n } finally {\n setIsAddingAccount(false);\n }\n };\n\n const handleWithdraw = async () => {\n if (!billingAccountId || !selectedAccountId) return;\n const amount = parseFloat(creditAmount);\n if (!amount || amount <= 0) return;\n\n setSubmitError(null);\n setIsSubmitting(true);\n try {\n const withdrawal = await requestCreditWithdrawal(\n {\n billingAccountId,\n creditAmount: amount,\n payoutAccountId: selectedAccountId,\n notes: notes || undefined,\n },\n getCtx()\n );\n emit('billing.credits.withdrawal_requested', {\n route: '/billing/credits/withdraw',\n entityId: withdrawal.id,\n source: 'credit-withdrawal',\n amount,\n });\n setSubmitSuccess(true);\n setCreditAmount('');\n setNotes('');\n await loadBalance();\n await loadHistory();\n } catch (e) {\n setSubmitError(e instanceof Error ? e.message : 'Withdrawal request failed');\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const accountCurrency = billingAccount?.currency ?? 'USD';\n const withdrawAmount = parseFloat(creditAmount) || 0;\n\n const { data: costData, loading: isFetchingCost } = useGetCostOfCreditsCheckoutQuery({\n variables: { creditAmount: withdrawAmount, currency: accountCurrency },\n skip: withdrawAmount <= 0 || !billingAccount,\n });\n\n const estimatedPayout = costData?.getCostOfCredits?.amount;\n\n // Permission check\n if (!permissions.canWithdrawCredits) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <div className=\"size-12 mx-auto rounded-full bg-bg-sunken flex items-center justify-center\">\n <svg\n className=\"size-6 text-text-secondary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary\">\n You don&apos;t have permission to withdraw credits.\n </p>\n </div>\n </div>\n );\n }\n\n if (!isLoadingAccount && !billingAccount) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <h2 className=\"text-lg font-semibold text-text-primary\">No Billing Account</h2>\n <p className=\"text-sm text-text-secondary\">\n You need a billing account to withdraw credits.\n </p>\n </div>\n </div>\n );\n }\n\n if (isLoadingAccount && !billingAccount) {\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n <div className=\"h-8 w-64 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-4\">\n {[1, 2, 3, 4].map((i) => (\n <div key={i} className=\"border border-border-subtle rounded-lg p-5\">\n <div className=\"h-4 w-24 bg-bg-sunken animate-pulse rounded mb-2\" />\n <div className=\"h-8 w-32 bg-bg-sunken animate-pulse rounded\" />\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n const withdrawable = balance?.withdrawable ?? 0;\n const amountValid = withdrawAmount > 0 && withdrawAmount <= withdrawable;\n const activeAccounts = payoutAccounts.filter((a) => a.status !== 'ARCHIVED');\n\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n {/* Header */}\n <div>\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n Withdraw Credits\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n Convert your withdrawable credits (purchased &amp; earned) to a payout\n </p>\n <PagePurpose className=\"mt-3\">\n Turn the credits you bought or earned (from sales and referrals) back into real money. Add\n a bank account or UPI as a payout destination, request a withdrawal for any amount up to\n your withdrawable balance, and track each request here until it is paid. Granted credits\n (coupons, admin grants) are not withdrawable.\n </PagePurpose>\n </div>\n\n {/* Balance breakdown */}\n <div className=\"grid grid-cols-2 lg:grid-cols-4 gap-4\">\n {isLoadingBalance ? (\n [1, 2, 3, 4].map((i) => (\n <div key={i} className=\"border border-border-subtle rounded-lg p-5\">\n <div className=\"h-4 w-20 bg-bg-sunken animate-pulse rounded mb-2\" />\n <div className=\"h-8 w-28 bg-bg-sunken animate-pulse rounded\" />\n </div>\n ))\n ) : balanceError ? (\n <div className=\"col-span-4 text-sm text-status-error-text\">{balanceError}</div>\n ) : (\n <>\n <BalanceCard\n label=\"Purchased\"\n value={balance?.purchased ?? 0}\n description=\"From credit purchases\"\n />\n <BalanceCard\n label=\"Earned\"\n value={balance?.earned ?? 0}\n description=\"From sales & referrals\"\n />\n <BalanceCard\n label=\"Granted\"\n value={balance?.granted ?? 0}\n description=\"Coupons & admin grants — non-withdrawable\"\n />\n <BalanceCard\n label=\"Withdrawable\"\n value={withdrawable}\n description=\"Purchased + earned\"\n highlight\n />\n </>\n )}\n </div>\n\n {/* Success banner */}\n {submitSuccess && (\n <div className=\"flex items-center gap-3 p-4 rounded-lg bg-status-success-bg-subtle border border-status-success-border text-status-success-text\">\n <svg className=\"size-5 shrink-0\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M5 13l4 4L19 7\" />\n </svg>\n <div>\n <p className=\"font-medium\">Withdrawal request submitted</p>\n <p className=\"text-sm opacity-80\">Our team will review and process your request.</p>\n </div>\n <button\n type=\"button\"\n onClick={() => setSubmitSuccess(false)}\n className=\"ml-auto text-current opacity-60 hover:opacity-100\"\n >\n <svg className=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n </div>\n )}\n\n {/* Main two-column layout */}\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n {/* Left: Payout account management */}\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-base font-semibold text-text-primary\">Payout Account</h2>\n <button\n type=\"button\"\n onClick={() => setShowAddAccount((v) => !v)}\n className=\"text-sm text-text-link hover:underline\"\n >\n {showAddAccount ? 'Cancel' : '+ Add new'}\n </button>\n </div>\n\n {/* Add account form */}\n {showAddAccount && (\n <div className=\"border border-border-subtle rounded-lg p-4 space-y-3 bg-bg-sunken\">\n <h3 className=\"text-sm font-medium text-text-primary\">New Payout Account</h3>\n\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">Label</label>\n <input\n type=\"text\"\n value={accountForm.label}\n onChange={(e) => setAccountForm((f) => ({ ...f, label: e.target.value }))}\n placeholder=\"e.g. My Bank Account\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">\n Account Holder Name\n </label>\n <input\n type=\"text\"\n value={accountForm.accountHolderName}\n onChange={(e) =>\n setAccountForm((f) => ({ ...f, accountHolderName: e.target.value }))\n }\n placeholder=\"Full name as on bank account\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">Type</label>\n <select\n value={accountForm.type}\n onChange={(e) =>\n setAccountForm((f) => ({\n ...f,\n type: e.target.value as typeof accountForm.type,\n }))\n }\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n <option value=\"BANK_ACCOUNT\">Bank Account</option>\n <option value=\"UPI\">UPI</option>\n </select>\n </div>\n\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">Country</label>\n <input\n type=\"text\"\n value={accountForm.country}\n onChange={(e) => setAccountForm((f) => ({ ...f, country: e.target.value }))}\n placeholder=\"e.g. India, US, UK\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n\n {accountForm.type === 'BANK_ACCOUNT' && (\n <>\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">Account Number</label>\n <input\n type=\"text\"\n value={accountForm.accountNumber}\n onChange={(e) =>\n setAccountForm((f) => ({ ...f, accountNumber: e.target.value }))\n }\n placeholder=\"Account number\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n {accountForm.country.trim().toUpperCase() === 'IN' ||\n accountForm.country.trim().toLowerCase() === 'india' ? (\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">IFSC Code</label>\n <input\n type=\"text\"\n value={accountForm.ifscCode}\n onChange={(e) =>\n setAccountForm((f) => ({ ...f, ifscCode: e.target.value.toUpperCase() }))\n }\n placeholder=\"e.g. SBIN0001234\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n ) : (\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">\n Routing Number\n </label>\n <input\n type=\"text\"\n value={accountForm.routingNumber}\n onChange={(e) =>\n setAccountForm((f) => ({ ...f, routingNumber: e.target.value }))\n }\n placeholder=\"Routing / sort code\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n )}\n </>\n )}\n\n {accountForm.type === 'UPI' && (\n <div>\n <label className=\"block text-xs text-text-secondary mb-1\">UPI ID</label>\n <input\n type=\"text\"\n value={accountForm.upiId}\n onChange={(e) => setAccountForm((f) => ({ ...f, upiId: e.target.value }))}\n placeholder=\"yourname@upi\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n )}\n\n {addAccountError && (\n <p className=\"text-xs text-status-error-text\">{addAccountError}</p>\n )}\n\n <button\n type=\"button\"\n onClick={() => void handleAddAccount()}\n disabled={isAddingAccount || !accountForm.label || !accountForm.accountHolderName}\n className=\"w-full py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isAddingAccount ? 'Saving…' : 'Save Account'}\n </button>\n </div>\n )}\n\n {/* Existing accounts */}\n {isLoadingAccounts ? (\n <div className=\"space-y-2\">\n {[1, 2].map((i) => (\n <div\n key={i}\n className=\"h-16 border border-border-subtle rounded-lg bg-bg-sunken animate-pulse\"\n />\n ))}\n </div>\n ) : activeAccounts.length === 0 && !showAddAccount ? (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No payout accounts yet\"\n description=\"Add a bank account or UPI to receive your withdrawn credits.\"\n action={\n <button\n type=\"button\"\n onClick={() => setShowAddAccount(true)}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors\"\n >\n Add a bank account or UPI\n </button>\n }\n />\n ) : (\n <div className=\"space-y-2\">\n {activeAccounts.map((account) => (\n <button\n type=\"button\"\n key={account.id}\n onClick={() => setSelectedAccountId(account.id)}\n className={`w-full text-left p-4 border rounded-lg transition-colors ${\n selectedAccountId === account.id\n ? 'border-border-strong bg-[var(--color-accent-soft)]'\n : 'border-border-subtle bg-bg-surface hover:border-border-strong'\n }`}\n >\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{account.label}</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">\n {account.type.replaceAll('_', ' ')}\n {account.displayName ? ` · ${account.displayName}` : ''}\n {account.accountLast4 ? ` ···${account.accountLast4}` : ''}\n {account.country ? ` · ${account.country}` : ''}\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n {account.isDefault && (\n <span className=\"text-xs px-2 py-0.5 rounded bg-[var(--color-accent-soft)] text-text-link font-medium\">\n Default\n </span>\n )}\n <span\n className={`text-xs px-2 py-0.5 rounded font-medium ${\n account.status === 'ACTIVE'\n ? `${statusTokens.success.bg} ${statusTokens.success.text}`\n : account.status === 'PENDING_VERIFICATION'\n ? `${statusTokens.warning.bg} ${statusTokens.warning.text}`\n : `${statusTokens.error.bg} ${statusTokens.error.text}`\n }`}\n >\n {account.status.replaceAll('_', ' ').toLowerCase()}\n </span>\n {selectedAccountId === account.id && (\n <svg\n className=\"size-4 text-text-link shrink-0\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n )}\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* Right: Withdrawal request form */}\n <div className=\"space-y-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">Request Withdrawal</h2>\n\n <div className=\"border border-border-subtle rounded-lg p-5 bg-bg-surface space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Credits to Withdraw\n </label>\n <input\n type=\"number\"\n min={1}\n max={withdrawable}\n step={1}\n value={creditAmount}\n onChange={(e) => setCreditAmount(e.target.value)}\n placeholder=\"Enter credit amount\"\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n <p className=\"text-xs text-text-secondary mt-1\">\n Max withdrawable:{' '}\n <span className=\"font-medium\">{withdrawable.toLocaleString()} credits</span>\n </p>\n {withdrawAmount > 0 && withdrawAmount <= withdrawable && (\n <p className=\"text-xs text-text-secondary mt-1\">\n {isFetchingCost ? (\n 'Calculating…'\n ) : estimatedPayout != null ? (\n <>\n Estimated payout:{' '}\n <span className=\"font-semibold text-text-primary\">\n {estimatedPayout.toLocaleString(undefined, {\n style: 'currency',\n currency: accountCurrency,\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n })}\n </span>{' '}\n at the current credit rate\n </>\n ) : null}\n </p>\n )}\n {withdrawAmount > 0 && withdrawAmount > withdrawable && (\n <p className=\"text-xs text-status-error-text mt-1\">\n Amount exceeds your withdrawable balance\n </p>\n )}\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-text-primary mb-1\">\n Notes <span className=\"text-text-secondary font-normal\">(optional)</span>\n </label>\n <textarea\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n placeholder=\"Any notes for this withdrawal request\"\n rows={2}\n className=\"w-full px-3 py-2 text-sm border border-border-subtle rounded-button bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none\"\n />\n </div>\n\n {submitError && (\n <div className=\"p-3 rounded-button bg-status-error-bg-subtle border border-status-error-border\">\n <p className=\"text-sm text-status-error-text\">{submitError}</p>\n </div>\n )}\n\n <div className=\"pt-1 border-t border-border-subtle\">\n <p className=\"text-xs text-text-secondary mb-3\">\n Credits will be converted to {accountCurrency} at the current credit rate.\n Withdrawals are reviewed before processing and may take 3–5 business days.\n </p>\n <button\n type=\"button\"\n onClick={() => void handleWithdraw()}\n disabled={\n isSubmitting || !amountValid || !selectedAccountId || activeAccounts.length === 0\n }\n className=\"w-full py-2.5 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors disabled:opacity-50 disabled:cursor-not-allowed\"\n >\n {isSubmitting ? 'Submitting…' : 'Request Withdrawal'}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n {/* Withdrawal history */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-base font-semibold text-text-primary\">Withdrawal History</h2>\n <button\n type=\"button\"\n onClick={() => void loadHistory()}\n className=\"text-sm text-text-secondary hover:text-text-primary transition-colors\"\n aria-label=\"Refresh withdrawal history\"\n >\n <svg className=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15\"\n />\n </svg>\n </button>\n </div>\n\n {isLoadingHistory ? (\n <div className=\"space-y-2\">\n {[1, 2, 3].map((i) => (\n <div\n key={i}\n className=\"h-16 border border-border-subtle rounded-lg bg-bg-sunken animate-pulse\"\n />\n ))}\n </div>\n ) : history.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No withdrawal requests yet\"\n description=\"Once you request a withdrawal, its status will appear here.\"\n />\n ) : (\n <div className=\"border border-border-subtle rounded-lg overflow-hidden\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-bg-sunken border-b border-border-subtle\">\n <tr>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Amount\n </th>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Status\n </th>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide hidden sm:table-cell\">\n Payout Account\n </th>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide hidden md:table-cell\">\n Requested\n </th>\n <th className=\"text-left px-4 py-3 text-xs font-medium text-text-secondary uppercase tracking-wide hidden md:table-cell\">\n Completed\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border-subtle\">\n {history.map((req) => (\n <tr key={req.id} className=\"hover:bg-bg-sunken transition-colors\">\n <td className=\"px-4 py-3 font-medium text-text-primary\">\n {req.requestedAmount.toLocaleString()} {req.currency}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${getWithdrawalStatusBg(req.status)}`}\n >\n {req.status.charAt(0) + req.status.slice(1).toLowerCase()}\n </span>\n {req.failureReason && (\n <p\n className=\"text-xs text-status-error-text mt-0.5 max-w-[180px] truncate\"\n title={req.failureReason}\n >\n {req.failureReason}\n </p>\n )}\n </td>\n <td className=\"px-4 py-3 text-text-secondary hidden sm:table-cell\">\n {req.payoutAccount ? (\n <span>\n {req.payoutAccount.label}\n {req.payoutAccount.accountLast4\n ? ` ···${req.payoutAccount.accountLast4}`\n : ''}\n </span>\n ) : (\n '—'\n )}\n </td>\n <td className=\"px-4 py-3 text-text-secondary hidden md:table-cell\">\n <span title={formatDate(req.createdAt, 'long')}>\n {formatRelativeTime(req.createdAt)}\n </span>\n </td>\n <td className=\"px-4 py-3 text-text-secondary hidden md:table-cell\">\n {req.paidAt ? (\n <span className={getWithdrawalStatusColor('PAID')}>\n {formatDate(req.paidAt, 'short')}\n </span>\n ) : (\n '—'\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -9,16 +9,16 @@ import "../../subscriptions/hooks/index.js";
9
9
  import { useState as u } from "react";
10
10
  import { jsx as d, jsxs as f } from "react/jsx-runtime";
11
11
  import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
- import { EmphasisPanel as m } from "@burdenoff/fe-libs/ui";
12
+ import { EmphasisPanel as m, IllustratedEmptyState as h, PagePurpose as g } from "@burdenoff/fe-libs/ui";
13
13
  //#region src/billing/modules/credits/pages/CreditsPage.tsx
14
- var h = () => {
14
+ var _ = () => {
15
15
  let { t: e } = p(), n = (t, n) => {
16
16
  let r = e(t);
17
17
  return r === t ? n : r;
18
- }, r = s(), i = o(), { billingAccount: a, isLoading: h } = l(), [_, v] = u(30), [y, b] = u("all"), [x, S] = u(1), { transactions: C, pagination: w, isLoading: T, error: E, refetch: D } = c({
18
+ }, r = s(), i = o(), { billingAccount: a, isLoading: _ } = l(), [y, b] = u(30), [x, S] = u("all"), [C, w] = u(1), { transactions: T, pagination: E, isLoading: D, error: O, refetch: k } = c({
19
19
  billingAccountId: a?.id || "",
20
- days: _,
21
- page: x,
20
+ days: y,
21
+ page: C,
22
22
  pageSize: 20
23
23
  });
24
24
  if (!i.canViewCredits) return /* @__PURE__ */ d("div", {
@@ -52,8 +52,8 @@ var h = () => {
52
52
  ]
53
53
  })
54
54
  });
55
- let O = h || T, k = C.filter((e) => y === "all" ? !0 : e.type === y);
56
- if (O && !a) return /* @__PURE__ */ f("div", {
55
+ let A = _ || D, j = T.filter((e) => x === "all" ? !0 : e.type === x);
56
+ if (A && !a) return /* @__PURE__ */ f("div", {
57
57
  className: "space-y-6 px-6 lg:px-8 py-6",
58
58
  children: [/* @__PURE__ */ d("div", { className: "h-8 w-48 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ d("div", {
59
59
  className: "grid grid-cols-1 sm:grid-cols-2 gap-4",
@@ -63,7 +63,7 @@ var h = () => {
63
63
  })
64
64
  })]
65
65
  });
66
- if (E) return /* @__PURE__ */ d("div", {
66
+ if (O) return /* @__PURE__ */ d("div", {
67
67
  className: "flex items-center justify-center h-full min-h-[400px]",
68
68
  children: /* @__PURE__ */ f("div", {
69
69
  className: "text-center space-y-4",
@@ -89,30 +89,37 @@ var h = () => {
89
89
  }),
90
90
  /* @__PURE__ */ d("p", {
91
91
  className: "text-sm text-text-secondary",
92
- children: E.message
92
+ children: O.message
93
93
  }),
94
94
  /* @__PURE__ */ d("button", {
95
95
  type: "button",
96
- onClick: () => D(),
96
+ onClick: () => k(),
97
97
  className: "px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors",
98
98
  children: "Try Again"
99
99
  })
100
100
  ]
101
101
  })
102
102
  });
103
- let A = a?.creditAmount || 0;
103
+ let M = a?.creditAmount || 0;
104
104
  return /* @__PURE__ */ f("div", {
105
105
  className: "space-y-6 px-6 lg:px-8 py-6",
106
106
  children: [
107
107
  /* @__PURE__ */ f("div", {
108
108
  className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
109
- children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("h1", {
110
- className: "text-2xl md:text-3xl font-semibold tracking-tight text-text-primary",
111
- children: n("billing.credits.title", "Credits")
112
- }), /* @__PURE__ */ d("p", {
113
- className: "text-sm text-text-secondary mt-1",
114
- children: "Manage your credit balance and view transaction history"
115
- })] }), /* @__PURE__ */ f("div", {
109
+ children: [/* @__PURE__ */ f("div", { children: [
110
+ /* @__PURE__ */ d("h1", {
111
+ className: "text-2xl md:text-3xl font-semibold tracking-tight text-text-primary",
112
+ children: n("billing.credits.title", "Credits")
113
+ }),
114
+ /* @__PURE__ */ d("p", {
115
+ className: "text-sm text-text-secondary mt-1",
116
+ children: "Manage your credit balance and view transaction history"
117
+ }),
118
+ /* @__PURE__ */ d(g, {
119
+ className: "mt-3",
120
+ children: n("billing.credits.purpose", "Credits are prepaid balance you can spend on usage and purchases instead of paying per invoice. See your available balance, top it up, withdraw unused credits, and review every credit purchase, grant and deduction over time.")
121
+ })
122
+ ] }), /* @__PURE__ */ f("div", {
116
123
  className: "flex items-center gap-2",
117
124
  children: [/* @__PURE__ */ f("button", {
118
125
  type: "button",
@@ -160,7 +167,7 @@ var h = () => {
160
167
  }),
161
168
  /* @__PURE__ */ f("p", {
162
169
  className: "text-3xl font-bold tabular-nums text-text-primary mt-2",
163
- children: [A.toLocaleString(), " Credits"]
170
+ children: [M.toLocaleString(), " Credits"]
164
171
  }),
165
172
  /* @__PURE__ */ d("p", {
166
173
  className: "text-sm text-text-secondary mt-2",
@@ -174,13 +181,13 @@ var h = () => {
174
181
  className: "text-sm text-text-secondary",
175
182
  children: [
176
183
  "Transactions (",
177
- _,
184
+ y,
178
185
  "d)"
179
186
  ]
180
187
  }),
181
188
  /* @__PURE__ */ d("p", {
182
189
  className: "text-2xl md:text-3xl font-semibold tracking-tight text-text-primary mt-2",
183
- children: w.totalCount
190
+ children: E.totalCount
184
191
  }),
185
192
  /* @__PURE__ */ d("p", {
186
193
  className: "text-sm text-text-secondary mt-2",
@@ -199,8 +206,8 @@ var h = () => {
199
206
  90
200
207
  ].map((e) => /* @__PURE__ */ f("button", {
201
208
  type: "button",
202
- onClick: () => v(e),
203
- className: `px-3 py-1.5 text-sm font-medium rounded-button transition-colors ${_ === e ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-secondary hover:text-text-primary"}`,
209
+ onClick: () => b(e),
210
+ className: `px-3 py-1.5 text-sm font-medium rounded-button transition-colors ${y === e ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-secondary hover:text-text-primary"}`,
204
211
  children: [e, "d"]
205
212
  }, e))
206
213
  }), /* @__PURE__ */ d("div", {
@@ -213,46 +220,23 @@ var h = () => {
213
220
  "granted"
214
221
  ].map((e) => /* @__PURE__ */ d("button", {
215
222
  type: "button",
216
- onClick: () => b(e),
217
- className: `px-3 py-1.5 text-sm font-medium rounded-button transition-colors capitalize ${y === e ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-secondary hover:text-text-primary"}`,
223
+ onClick: () => S(e),
224
+ className: `px-3 py-1.5 text-sm font-medium rounded-button transition-colors capitalize ${x === e ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-secondary hover:text-text-primary"}`,
218
225
  children: e === "all" ? "All" : t(e)
219
226
  }, e))
220
227
  })]
221
228
  }),
222
- k.length === 0 ? /* @__PURE__ */ f("div", {
223
- className: "flex flex-col items-center justify-center py-12 border border-dashed border-border-subtle rounded-lg",
224
- children: [
225
- /* @__PURE__ */ d("div", {
226
- className: "size-12 rounded-full bg-bg-sunken flex items-center justify-center mb-4",
227
- children: /* @__PURE__ */ d("svg", {
228
- className: "size-6 text-text-secondary",
229
- fill: "none",
230
- viewBox: "0 0 24 24",
231
- stroke: "currentColor",
232
- children: /* @__PURE__ */ d("path", {
233
- strokeLinecap: "round",
234
- strokeLinejoin: "round",
235
- strokeWidth: 2,
236
- d: "M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
237
- })
238
- })
239
- }),
240
- /* @__PURE__ */ d("h3", {
241
- className: "text-lg font-medium text-text-primary",
242
- children: "No transactions found"
243
- }),
244
- /* @__PURE__ */ d("p", {
245
- className: "text-sm text-text-secondary mt-1",
246
- children: y === "all" ? "No credit transactions in this period." : "No transactions match your filter."
247
- })
248
- ]
229
+ j.length === 0 ? /* @__PURE__ */ d(h, {
230
+ illustration: x === "all" ? "empty-data" : "empty-search",
231
+ title: "No transactions found",
232
+ description: x === "all" ? "No credit transactions in this period." : "No transactions match your filter."
249
233
  }) : /* @__PURE__ */ f("div", {
250
234
  className: "space-y-3",
251
- children: [k.map((e) => /* @__PURE__ */ d(g, { transaction: e }, e.id)), w.hasMore && /* @__PURE__ */ d("div", {
235
+ children: [j.map((e) => /* @__PURE__ */ d(v, { transaction: e }, e.id)), E.hasMore && /* @__PURE__ */ d("div", {
252
236
  className: "flex justify-center pt-4",
253
237
  children: /* @__PURE__ */ d("button", {
254
238
  type: "button",
255
- onClick: () => S((e) => e + 1),
239
+ onClick: () => w((e) => e + 1),
256
240
  className: "px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors",
257
241
  children: "Load More"
258
242
  })
@@ -260,7 +244,7 @@ var h = () => {
260
244
  })
261
245
  ]
262
246
  });
263
- }, g = ({ transaction: o }) => {
247
+ }, v = ({ transaction: o }) => {
264
248
  let s = i(o.status), c = o.type === "purchase" || o.type === "adjustment" || o.type === "granted";
265
249
  return /* @__PURE__ */ f("div", {
266
250
  className: "flex items-center gap-4 p-4 border border-border-seam rounded-card bg-bg-surface shadow-elevation-1 hover:shadow-sm transition-shadow",
@@ -326,6 +310,6 @@ var h = () => {
326
310
  });
327
311
  };
328
312
  //#endregion
329
- export { h as CreditsPage };
313
+ export { _ as CreditsPage };
330
314
 
331
315
  //# sourceMappingURL=CreditsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CreditsPage.js","names":[],"sources":["../../../../../src/billing/modules/credits/pages/CreditsPage.tsx"],"sourcesContent":["/**\n * Credits Module - Credits Page\n * Displays credit balance and transaction history\n */\n\nimport { useState, type FC } from 'react';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { useCreditTransactions } from '../hooks/useCredits';\nimport { useDefaultBillingAccount } from '../../subscriptions/hooks';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport {\n formatDate,\n formatRelativeTime,\n formatCreditTransactionType,\n} from '../../../shared/utils/format';\nimport {\n getCreditTransactionStatusColor,\n getStatusBadgeClasses,\n} from '../../../shared/utils/status';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport type { CreditTransaction, CreditTransactionType } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { EmphasisPanel } from '@burdenoff/fe-libs/ui';\n\ntype FilterType = 'all' | CreditTransactionType;\n\nexport const CreditsPage: 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 navigateTo = useBillingNavigate();\n const permissions = useBillingPermissions();\n const { billingAccount, isLoading: isLoadingAccount } = useDefaultBillingAccount();\n\n const [days, setDays] = useState(30);\n const [filterType, setFilterType] = useState<FilterType>('all');\n const [page, setPage] = useState(1);\n\n const {\n transactions,\n pagination,\n isLoading: isLoadingTransactions,\n error,\n refetch,\n } = useCreditTransactions({\n billingAccountId: billingAccount?.id || '',\n days,\n page,\n pageSize: 20,\n });\n\n // Permission check\n if (!permissions.canViewCredits) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <div className=\"size-12 mx-auto rounded-full bg-bg-sunken flex items-center justify-center\">\n <svg\n className=\"size-6 text-text-secondary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary max-w-sm\">\n You don&apos;t have permission to view credits.\n </p>\n </div>\n </div>\n );\n }\n\n const isLoading = isLoadingAccount || isLoadingTransactions;\n\n // Filter transactions\n const filteredTransactions = transactions.filter((tx) => {\n if (filterType === 'all') return true;\n return tx.type === filterType;\n });\n\n // Loading state\n if (isLoading && !billingAccount) {\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n <div className=\"h-8 w-48 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div className=\"border border-border-subtle rounded-lg p-6\">\n <div className=\"h-6 w-24 bg-bg-sunken animate-pulse rounded mb-2\" />\n <div className=\"h-10 w-32 bg-bg-sunken animate-pulse rounded\" />\n </div>\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-4\">\n <div className=\"size-12 mx-auto rounded-full bg-status-error-bg-subtle flex items-center justify-center\">\n <svg\n className=\"size-6 text-status-error-text\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Failed to load credits</h2>\n <p className=\"text-sm text-text-secondary\">{error.message}</p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors\"\n >\n Try Again\n </button>\n </div>\n </div>\n );\n }\n\n const creditBalance = billingAccount?.creditAmount || 0;\n\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n {tr('billing.credits.title', 'Credits')}\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n Manage your credit balance and view transaction history\n </p>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/credits/withdraw')}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n <svg className=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z\"\n />\n </svg>\n Withdraw\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/checkout/credits')}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors\"\n >\n <svg className=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Purchase Credits\n </button>\n </div>\n </div>\n\n {/* Balance Card */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n <EmphasisPanel className=\"p-6\">\n <p className=\"text-sm text-text-secondary\">Available Balance</p>\n <p className=\"text-3xl font-bold tabular-nums text-text-primary mt-2\">\n {creditBalance.toLocaleString()} Credits\n </p>\n <p className=\"text-sm text-text-secondary mt-2\">{billingAccount?.name}</p>\n </EmphasisPanel>\n\n <div className=\"border border-border-seam rounded-card bg-bg-surface shadow-elevation-1 p-5\">\n <p className=\"text-sm text-text-secondary\">Transactions ({days}d)</p>\n <p className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary mt-2\">\n {pagination.totalCount}\n </p>\n <p className=\"text-sm text-text-secondary mt-2\">Total transactions</p>\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-wrap items-center gap-4 pb-4 border-b border-border-subtle\">\n {/* Time Range */}\n <div className=\"inline-flex rounded-lg border border-border-subtle p-1 bg-bg-sunken\">\n {[7, 30, 90].map((d) => (\n <button\n type=\"button\"\n key={d}\n onClick={() => setDays(d)}\n className={`px-3 py-1.5 text-sm font-medium rounded-button transition-colors ${\n days === d\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n {d}d\n </button>\n ))}\n </div>\n\n {/* Transaction Type Filter */}\n <div className=\"inline-flex rounded-lg border border-border-subtle p-1 bg-bg-sunken\">\n {(['all', 'purchase', 'usage', 'adjustment', 'granted'] as FilterType[]).map((type) => (\n <button\n type=\"button\"\n key={type}\n onClick={() => setFilterType(type)}\n className={`px-3 py-1.5 text-sm font-medium rounded-button transition-colors capitalize ${\n filterType === type\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n {type === 'all' ? 'All' : formatCreditTransactionType(type as CreditTransactionType)}\n </button>\n ))}\n </div>\n </div>\n\n {/* Transactions List */}\n {filteredTransactions.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center py-12 border border-dashed border-border-subtle rounded-lg\">\n <div className=\"size-12 rounded-full bg-bg-sunken flex items-center justify-center mb-4\">\n <svg\n className=\"size-6 text-text-secondary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n </div>\n <h3 className=\"text-lg font-medium text-text-primary\">No transactions found</h3>\n <p className=\"text-sm text-text-secondary mt-1\">\n {filterType !== 'all'\n ? 'No transactions match your filter.'\n : 'No credit transactions in this period.'}\n </p>\n </div>\n ) : (\n <div className=\"space-y-3\">\n {filteredTransactions.map((tx) => (\n <TransactionRow key={tx.id} transaction={tx} />\n ))}\n\n {/* Pagination */}\n {pagination.hasMore && (\n <div className=\"flex justify-center pt-4\">\n <button\n type=\"button\"\n onClick={() => setPage((p) => p + 1)}\n className=\"px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n Load More\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n\n// ============================================================================\n// Transaction Row Component\n// ============================================================================\n\ninterface TransactionRowProps {\n transaction: CreditTransaction;\n}\n\nconst TransactionRow: FC<TransactionRowProps> = ({ transaction }) => {\n const statusColor = getCreditTransactionStatusColor(transaction.status);\n const isCredit =\n transaction.type === 'purchase' ||\n transaction.type === 'adjustment' ||\n transaction.type === 'granted';\n\n return (\n <div className=\"flex items-center gap-4 p-4 border border-border-seam rounded-card bg-bg-surface shadow-elevation-1 hover:shadow-sm transition-shadow\">\n {/* Icon */}\n <div\n className={`size-10 rounded-full flex items-center justify-center ${\n isCredit ? statusTokens.success.bg : statusTokens.warning.bg\n }`}\n >\n {isCredit ? (\n <svg\n className={`size-5 ${statusTokens.success.icon}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n ) : (\n <svg\n className={`size-5 ${statusTokens.warning.icon}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M20 12H4\" />\n </svg>\n )}\n </div>\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <p className=\"font-medium text-text-primary capitalize\">\n {formatCreditTransactionType(transaction.type)}\n </p>\n <span\n className={`px-2 py-0.5 text-xs font-medium rounded ${getStatusBadgeClasses(statusColor)}`}\n >\n {transaction.status}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary mt-0.5\">\n {formatRelativeTime(transaction.createdAt)} • {formatDate(transaction.createdAt, 'short')}\n </p>\n </div>\n\n {/* Amount */}\n <div className=\"text-right\">\n <p\n className={`font-semibold ${isCredit ? statusTokens.success.text : 'text-text-primary'}`}\n >\n {isCredit ? '+' : '-'}\n {transaction.amount.toLocaleString()} credits\n </p>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"CreditsPage.js","names":[],"sources":["../../../../../src/billing/modules/credits/pages/CreditsPage.tsx"],"sourcesContent":["/**\n * Credits Module - Credits Page\n * Displays credit balance and transaction history\n */\n\nimport { useState, type FC } from 'react';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { useCreditTransactions } from '../hooks/useCredits';\nimport { useDefaultBillingAccount } from '../../subscriptions/hooks';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport {\n formatDate,\n formatRelativeTime,\n formatCreditTransactionType,\n} from '../../../shared/utils/format';\nimport {\n getCreditTransactionStatusColor,\n getStatusBadgeClasses,\n} from '../../../shared/utils/status';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport type { CreditTransaction, CreditTransactionType } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { EmphasisPanel, PagePurpose, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\n\ntype FilterType = 'all' | CreditTransactionType;\n\nexport const CreditsPage: 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 navigateTo = useBillingNavigate();\n const permissions = useBillingPermissions();\n const { billingAccount, isLoading: isLoadingAccount } = useDefaultBillingAccount();\n\n const [days, setDays] = useState(30);\n const [filterType, setFilterType] = useState<FilterType>('all');\n const [page, setPage] = useState(1);\n\n const {\n transactions,\n pagination,\n isLoading: isLoadingTransactions,\n error,\n refetch,\n } = useCreditTransactions({\n billingAccountId: billingAccount?.id || '',\n days,\n page,\n pageSize: 20,\n });\n\n // Permission check\n if (!permissions.canViewCredits) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-2\">\n <div className=\"size-12 mx-auto rounded-full bg-bg-sunken flex items-center justify-center\">\n <svg\n className=\"size-6 text-text-secondary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Access Denied</h2>\n <p className=\"text-sm text-text-secondary max-w-sm\">\n You don&apos;t have permission to view credits.\n </p>\n </div>\n </div>\n );\n }\n\n const isLoading = isLoadingAccount || isLoadingTransactions;\n\n // Filter transactions\n const filteredTransactions = transactions.filter((tx) => {\n if (filterType === 'all') return true;\n return tx.type === filterType;\n });\n\n // Loading state\n if (isLoading && !billingAccount) {\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n <div className=\"h-8 w-48 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n <div className=\"border border-border-subtle rounded-lg p-6\">\n <div className=\"h-6 w-24 bg-bg-sunken animate-pulse rounded mb-2\" />\n <div className=\"h-10 w-32 bg-bg-sunken animate-pulse rounded\" />\n </div>\n </div>\n </div>\n );\n }\n\n // Error state\n if (error) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-4\">\n <div className=\"size-12 mx-auto rounded-full bg-status-error-bg-subtle flex items-center justify-center\">\n <svg\n className=\"size-6 text-status-error-text\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z\"\n />\n </svg>\n </div>\n <h2 className=\"text-lg font-semibold text-text-primary\">Failed to load credits</h2>\n <p className=\"text-sm text-text-secondary\">{error.message}</p>\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors\"\n >\n Try Again\n </button>\n </div>\n </div>\n );\n }\n\n const creditBalance = billingAccount?.creditAmount || 0;\n\n return (\n <div className=\"space-y-6 px-6 lg:px-8 py-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary\">\n {tr('billing.credits.title', 'Credits')}\n </h1>\n <p className=\"text-sm text-text-secondary mt-1\">\n Manage your credit balance and view transaction history\n </p>\n <PagePurpose className=\"mt-3\">\n {tr(\n 'billing.credits.purpose',\n 'Credits are prepaid balance you can spend on usage and purchases instead of paying per invoice. See your available balance, top it up, withdraw unused credits, and review every credit purchase, grant and deduction over time.'\n )}\n </PagePurpose>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/credits/withdraw')}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n <svg className=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z\"\n />\n </svg>\n Withdraw\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/checkout/credits')}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors\"\n >\n <svg className=\"size-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M12 4v16m8-8H4\"\n />\n </svg>\n Purchase Credits\n </button>\n </div>\n </div>\n\n {/* Balance Card */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n <EmphasisPanel className=\"p-6\">\n <p className=\"text-sm text-text-secondary\">Available Balance</p>\n <p className=\"text-3xl font-bold tabular-nums text-text-primary mt-2\">\n {creditBalance.toLocaleString()} Credits\n </p>\n <p className=\"text-sm text-text-secondary mt-2\">{billingAccount?.name}</p>\n </EmphasisPanel>\n\n <div className=\"border border-border-seam rounded-card bg-bg-surface shadow-elevation-1 p-5\">\n <p className=\"text-sm text-text-secondary\">Transactions ({days}d)</p>\n <p className=\"text-2xl md:text-3xl font-semibold tracking-tight text-text-primary mt-2\">\n {pagination.totalCount}\n </p>\n <p className=\"text-sm text-text-secondary mt-2\">Total transactions</p>\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-wrap items-center gap-4 pb-4 border-b border-border-subtle\">\n {/* Time Range */}\n <div className=\"inline-flex rounded-lg border border-border-subtle p-1 bg-bg-sunken\">\n {[7, 30, 90].map((d) => (\n <button\n type=\"button\"\n key={d}\n onClick={() => setDays(d)}\n className={`px-3 py-1.5 text-sm font-medium rounded-button transition-colors ${\n days === d\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n {d}d\n </button>\n ))}\n </div>\n\n {/* Transaction Type Filter */}\n <div className=\"inline-flex rounded-lg border border-border-subtle p-1 bg-bg-sunken\">\n {(['all', 'purchase', 'usage', 'adjustment', 'granted'] as FilterType[]).map((type) => (\n <button\n type=\"button\"\n key={type}\n onClick={() => setFilterType(type)}\n className={`px-3 py-1.5 text-sm font-medium rounded-button transition-colors capitalize ${\n filterType === type\n ? 'bg-bg-surface text-text-primary shadow-sm'\n : 'text-text-secondary hover:text-text-primary'\n }`}\n >\n {type === 'all' ? 'All' : formatCreditTransactionType(type as CreditTransactionType)}\n </button>\n ))}\n </div>\n </div>\n\n {/* Transactions List */}\n {filteredTransactions.length === 0 ? (\n <IllustratedEmptyState\n illustration={filterType !== 'all' ? 'empty-search' : 'empty-data'}\n title=\"No transactions found\"\n description={\n filterType !== 'all'\n ? 'No transactions match your filter.'\n : 'No credit transactions in this period.'\n }\n />\n ) : (\n <div className=\"space-y-3\">\n {filteredTransactions.map((tx) => (\n <TransactionRow key={tx.id} transaction={tx} />\n ))}\n\n {/* Pagination */}\n {pagination.hasMore && (\n <div className=\"flex justify-center pt-4\">\n <button\n type=\"button\"\n onClick={() => setPage((p) => p + 1)}\n className=\"px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors\"\n >\n Load More\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n\n// ============================================================================\n// Transaction Row Component\n// ============================================================================\n\ninterface TransactionRowProps {\n transaction: CreditTransaction;\n}\n\nconst TransactionRow: FC<TransactionRowProps> = ({ transaction }) => {\n const statusColor = getCreditTransactionStatusColor(transaction.status);\n const isCredit =\n transaction.type === 'purchase' ||\n transaction.type === 'adjustment' ||\n transaction.type === 'granted';\n\n return (\n <div className=\"flex items-center gap-4 p-4 border border-border-seam rounded-card bg-bg-surface shadow-elevation-1 hover:shadow-sm transition-shadow\">\n {/* Icon */}\n <div\n className={`size-10 rounded-full flex items-center justify-center ${\n isCredit ? statusTokens.success.bg : statusTokens.warning.bg\n }`}\n >\n {isCredit ? (\n <svg\n className={`size-5 ${statusTokens.success.icon}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M12 4v16m8-8H4\" />\n </svg>\n ) : (\n <svg\n className={`size-5 ${statusTokens.warning.icon}`}\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M20 12H4\" />\n </svg>\n )}\n </div>\n\n {/* Info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <p className=\"font-medium text-text-primary capitalize\">\n {formatCreditTransactionType(transaction.type)}\n </p>\n <span\n className={`px-2 py-0.5 text-xs font-medium rounded ${getStatusBadgeClasses(statusColor)}`}\n >\n {transaction.status}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary mt-0.5\">\n {formatRelativeTime(transaction.createdAt)} • {formatDate(transaction.createdAt, 'short')}\n </p>\n </div>\n\n {/* Amount */}\n <div className=\"text-right\">\n <p\n className={`font-semibold ${isCredit ? statusTokens.success.text : 'text-text-primary'}`}\n >\n {isCredit ? '+' : '-'}\n {transaction.amount.toLocaleString()} credits\n </p>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}