@burdenoff/microfe-billing 2026.821.1 → 2026.825.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/billing/BillingAdminRoutes.js.map +1 -1
  2. package/dist/billing/BillingRoot.js.map +1 -1
  3. package/dist/billing/BillingUserRoutes.js.map +1 -1
  4. package/dist/billing/hooks/useBillingAccountSelection.js.map +1 -1
  5. package/dist/billing/hooks/useBillingEventEmitter.js.map +1 -1
  6. package/dist/billing/hooks/useBillingNavigate.js.map +1 -1
  7. package/dist/billing/hooks/useBillingPermissions.js.map +1 -1
  8. package/dist/billing/hooks/useDefaultBillingCurrency.js.map +1 -1
  9. package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
  10. package/dist/billing/modules/addons/hooks/useAddons.js.map +1 -1
  11. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  12. package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
  13. package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
  14. package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
  15. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  16. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  17. package/dist/billing/modules/addons/store/addonCartStore.js.map +1 -1
  18. package/dist/billing/modules/affiliate/api.js.map +1 -1
  19. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +107 -107
  20. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  21. package/dist/billing/modules/analytics/pages/AnalyticsPage.js +80 -81
  22. package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
  23. package/dist/billing/modules/billing/hooks/useInvoices.js.map +1 -1
  24. package/dist/billing/modules/billing/hooks/useRefunds.js.map +1 -1
  25. package/dist/billing/modules/billing/hooks/useTransactions.js.map +1 -1
  26. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  27. package/dist/billing/modules/billing/pages/InvoicesListPage.js +1 -1
  28. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  29. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  30. package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
  31. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  32. package/dist/billing/modules/billing/pages/UserRefundsPage.js +127 -127
  33. package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
  34. package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
  35. package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js.map +1 -1
  36. package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
  37. package/dist/billing/modules/checkout/components/NativeCheckoutView.js.map +1 -1
  38. package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
  39. package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
  40. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
  41. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
  42. package/dist/billing/modules/checkout/components/StoreShippingSection.js.map +1 -1
  43. package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
  44. package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
  45. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
  46. package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js.map +1 -1
  47. package/dist/billing/modules/checkout/hooks/useCheckout.js +0 -1
  48. package/dist/billing/modules/checkout/hooks/useCheckout.js.map +1 -1
  49. package/dist/billing/modules/checkout/hooks/useNativeCheckout.js.map +1 -1
  50. package/dist/billing/modules/checkout/hooks/usePaymentProviders.js.map +1 -1
  51. package/dist/billing/modules/checkout/hooks/usePaymentStatusPolling.js.map +1 -1
  52. package/dist/billing/modules/checkout/hooks/useStoreShipping.js.map +1 -1
  53. package/dist/billing/modules/checkout/pages/CheckoutPage.js +412 -395
  54. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  55. package/dist/billing/modules/checkout/utils/storeOrder.js.map +1 -1
  56. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  57. package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
  58. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  59. package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
  60. package/dist/billing/modules/credits/hooks/useCredits.js.map +1 -1
  61. package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
  62. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
  63. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  64. package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
  65. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
  66. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
  67. package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
  68. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
  69. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
  70. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
  71. package/dist/billing/modules/dashboard/hooks/useBillingOverviewData.js.map +1 -1
  72. package/dist/billing/modules/dashboard/hooks/useDashboard.js.map +1 -1
  73. package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
  74. package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
  75. package/dist/billing/modules/earnings/api.js.map +1 -1
  76. package/dist/billing/modules/earnings/pages/DeveloperRevenueAdminPage.js +145 -145
  77. package/dist/billing/modules/earnings/pages/DeveloperRevenueAdminPage.js.map +1 -1
  78. package/dist/billing/modules/earnings/pages/EarningsPage.js +133 -133
  79. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  80. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +7 -9
  81. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  82. package/dist/billing/modules/earnings/pages/PayoutsPage.js +95 -95
  83. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  84. package/dist/billing/modules/plans/constants/featuredQuotas.js.map +1 -1
  85. package/dist/billing/modules/plans/hooks/usePlans.js.map +1 -1
  86. package/dist/billing/modules/plans/hooks/useQuotas.js.map +1 -1
  87. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  88. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
  89. package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
  90. package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
  91. package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
  92. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  93. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  94. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  95. package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
  96. package/dist/billing/modules/quota/hooks/useQuotaTemplates.js.map +1 -1
  97. package/dist/billing/modules/quota/pages/QuotaAssignFreePage.js.map +1 -1
  98. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
  99. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
  100. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
  101. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  102. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  103. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  104. package/dist/billing/modules/store/pages/StoreCheckoutPage.js +5 -6
  105. package/dist/billing/modules/store/pages/StoreCheckoutPage.js.map +1 -1
  106. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
  107. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.js.map +1 -1
  108. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  109. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  110. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  111. package/dist/billing/modules/usage/hooks/useUsage.js +14 -9
  112. package/dist/billing/modules/usage/hooks/useUsage.js.map +1 -1
  113. package/dist/billing/modules/usage/pages/UsagePage.js +481 -453
  114. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  115. package/dist/billing/providers/BillingProvider.js.map +1 -1
  116. package/dist/billing/shared/components/AccessDenied.js.map +1 -1
  117. package/dist/billing/shared/components/ActorIdentity.js.map +1 -1
  118. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
  119. package/dist/billing/shared/components/EmptyState.js.map +1 -1
  120. package/dist/billing/shared/components/PageHeader.js.map +1 -1
  121. package/dist/billing/shared/components/ServerError.js.map +1 -1
  122. package/dist/billing/shared/components/StatCard.js.map +1 -1
  123. package/dist/billing/shared/hooks/useActorProfiles.js.map +1 -1
  124. package/dist/billing/shared/types/graphql.js.map +1 -1
  125. package/dist/billing/shared/ui/Card.js.map +1 -1
  126. package/dist/billing/shared/ui/MetricCard.js.map +1 -1
  127. package/dist/billing/shared/ui/ProgressBar.js.map +1 -1
  128. package/dist/billing/shared/ui/StatusPill.js.map +1 -1
  129. package/dist/billing/shared/utils/directBillingGraphql.js.map +1 -1
  130. package/dist/billing/shared/utils/error.js.map +1 -1
  131. package/dist/billing/shared/utils/format.js.map +1 -1
  132. package/dist/billing/shared/utils/gatewayGraphql.js.map +1 -1
  133. package/dist/billing/shared/utils/navigation.js.map +1 -1
  134. package/dist/billing/shared/utils/paymentTheme.js.map +1 -1
  135. package/dist/billing/shared/utils/planFeatureQuantity.js.map +1 -1
  136. package/dist/billing/shared/utils/status.js.map +1 -1
  137. package/dist/billing/shared/utils/tokens.js.map +1 -1
  138. package/dist/generated/global-operations.js +5 -1
  139. package/dist/generated/global-operations.js.map +1 -1
  140. package/dist/generated/global-types.js.map +1 -1
  141. package/dist/generated/wspace-operations.js +1 -1
  142. package/dist/generated/wspace-operations.js.map +1 -1
  143. package/dist/node_modules/@capacitor/core/dist/index.js +1 -1
  144. package/dist/node_modules/@capacitor/core/dist/index.js.map +1 -1
  145. package/package.json +13 -10
@@ -1 +1 @@
1
- {"version":3,"file":"AddPaymentMethodModal.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/components/AddPaymentMethodModal.tsx"],"sourcesContent":["/**\n * Add Payment Method Modal Component\n * Modal for adding a new payment method via Stripe or Razorpay SDKs\n */\n\nimport { type FC, useState, useCallback, useEffect, useRef } from 'react';\nimport { X, CreditCard, Loader2, AlertCircle, CheckCircle2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { usePaymentProviderConfig, useDashboardMutations } from '../hooks';\nimport { PaymentProviderPreference } from '../../../shared/types';\nimport { getStripeCardElementStyle } from '../../../shared/utils';\n\n// Stripe types (loaded dynamically)\ndeclare global {\n interface Window {\n Stripe?: (key: string) => StripeInstance;\n Razorpay?: new (options: RazorpayOptions) => RazorpayInstance;\n }\n}\n\ninterface StripeInstance {\n elements: () => StripeElements;\n createPaymentMethod: (options: {\n type: 'card';\n card: StripeCardElement;\n billing_details?: { name?: string };\n }) => Promise<{\n paymentMethod?: {\n id: string;\n card?: { brand: string; last4: string; exp_month: number; exp_year: number };\n };\n error?: { message: string };\n }>;\n confirmCardSetup: (\n clientSecret: string,\n options?: {\n payment_method?: {\n card: StripeCardElement;\n billing_details?: { name?: string };\n };\n }\n ) => Promise<{\n setupIntent?: {\n id: string;\n status: string;\n payment_method?: string;\n };\n error?: { message: string };\n }>;\n}\n\ninterface StripeElements {\n create: (type: 'card', options?: object) => StripeCardElement;\n}\n\ninterface StripeCardElement {\n mount: (element: HTMLElement | string) => void;\n unmount: () => void;\n on: (\n event: string,\n handler: (event: { complete: boolean; error?: { message: string } }) => void\n ) => void;\n destroy: () => void;\n}\n\ninterface RazorpayOptions {\n key: string;\n amount: number;\n currency: string;\n order_id: string;\n customer_id?: string;\n name: string;\n description: string;\n method?: 'card' | 'upi' | 'netbanking' | 'wallet' | 'emi' | 'cardless_emi';\n handler: (response: RazorpayResponse) => void;\n modal?: { ondismiss?: () => void };\n prefill?: { name?: string; email?: string; contact?: string };\n notes?: Record<string, string>;\n config?: {\n display?: {\n hide?: Array<{ method: string }>;\n preferences?: {\n show_default_blocks?: boolean;\n };\n };\n };\n}\n\ninterface RazorpayInstance {\n open: () => void;\n close: () => void;\n}\n\ninterface RazorpayResponse {\n razorpay_payment_id: string;\n razorpay_token?: string;\n}\n\ninterface AddPaymentMethodModalProps {\n isOpen: boolean;\n onClose: () => void;\n billingAccountId: string;\n currency: string; // e.g., 'INR', 'USD'\n country?: string; // e.g., 'IN', 'US' - from billing address\n onSuccess?: () => void;\n}\n\ntype ModalStep = 'select-provider' | 'add-card' | 'processing' | 'success';\n\n// Load external script dynamically\nconst loadScript = (src: string, id: string): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (document.getElementById(id)) {\n resolve();\n return;\n }\n const script = document.createElement('script');\n script.id = id;\n script.src = src;\n script.async = true;\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\n document.head.appendChild(script);\n });\n};\n\nexport const AddPaymentMethodModal: FC<AddPaymentMethodModalProps> = ({\n isOpen,\n onClose,\n billingAccountId,\n currency,\n country,\n onSuccess,\n}) => {\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 modalRef = useRef<HTMLDivElement>(null);\n const cardElementRef = useRef<HTMLDivElement>(null);\n const stripeCardElementRef = useRef<StripeCardElement | null>(null);\n const stripeRef = useRef<StripeInstance | null>(null);\n\n // Only fetch payment provider config when modal is open\n const {\n stripeEnabled,\n stripePublishableKey,\n razorpayEnabled,\n isLoading: isLoadingConfig,\n } = usePaymentProviderConfig(!isOpen);\n const { isAddingPaymentMethod, verifyPaymentMethod } = useDashboardMutations();\n\n // Determine which providers to show based on currency and country\n // Razorpay: India only (INR currency OR IN country)\n // Stripe: International (non-INR OR non-IN country)\n const isIndianAccount = currency?.toUpperCase() === 'INR' || country?.toUpperCase() === 'IN';\n const showRazorpay = razorpayEnabled && isIndianAccount;\n const showStripe = stripeEnabled && !isIndianAccount;\n\n const [step, setStep] = useState<ModalStep>('select-provider');\n const [selectedProvider, setSelectedProvider] = useState<'stripe' | 'razorpay' | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isProcessing, setIsProcessing] = useState(false);\n const [isLoadingSdk, setIsLoadingSdk] = useState(false);\n const [cardholderName, setCardholderName] = useState('');\n const [setAsDefault, setSetAsDefault] = useState(true);\n const [isCardComplete, setIsCardComplete] = useState(false);\n\n // Must be declared before the effects that reference it\n const handleSelectProvider = useCallback((provider: 'stripe' | 'razorpay') => {\n setSelectedProvider(provider);\n setStep('add-card');\n setError(null);\n }, []);\n\n // Reset state when modal opens/closes\n useEffect(() => {\n if (isOpen) {\n setStep('select-provider');\n setSelectedProvider(null);\n setError(null);\n setCardholderName('');\n setSetAsDefault(true);\n setIsCardComplete(false);\n } else {\n // Cleanup Stripe element when modal closes\n if (stripeCardElementRef.current) {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n }\n }\n }, [isOpen]);\n\n // Auto-select provider when only one is available (skip the select-provider screen)\n useEffect(() => {\n if (step !== 'select-provider' || isLoadingConfig) return;\n if (showStripe && !showRazorpay) {\n handleSelectProvider('stripe');\n } else if (showRazorpay && !showStripe) {\n handleSelectProvider('razorpay');\n }\n }, [step, isLoadingConfig, showStripe, showRazorpay, handleSelectProvider]);\n\n // Initialize Stripe when provider is selected\n useEffect(() => {\n if (step !== 'add-card' || selectedProvider !== 'stripe') return;\n\n // Show error if config loaded but key is missing\n if (!stripePublishableKey && !isLoadingConfig) {\n setError('Stripe is not configured. Please contact support.');\n return;\n }\n\n if (!stripePublishableKey) return;\n\n const initStripe = async () => {\n setIsLoadingSdk(true);\n try {\n await loadScript('https://js.stripe.com/v3/', 'stripe-js');\n\n if (!window.Stripe) {\n throw new Error('Stripe SDK failed to load');\n }\n\n const stripe = window.Stripe(stripePublishableKey);\n stripeRef.current = stripe;\n\n // Wait for the card element container to be mounted in the DOM\n let attempts = 0;\n while (!cardElementRef.current && attempts < 50) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n\n if (!cardElementRef.current) {\n throw new Error('Card element container not found after 5 seconds');\n }\n\n if (stripeCardElementRef.current) {\n return;\n }\n\n const elements = stripe.elements();\n const cardElement = elements.create('card', {\n style: getStripeCardElementStyle('system-ui, -apple-system, sans-serif'),\n });\n\n cardElement.mount(cardElementRef.current);\n stripeCardElementRef.current = cardElement;\n\n cardElement.on('change', (event) => {\n setIsCardComplete(event.complete);\n if (event.error) {\n setError(event.error.message);\n } else {\n setError(null);\n }\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load Stripe');\n } finally {\n setIsLoadingSdk(false);\n }\n };\n\n initStripe();\n\n return () => {\n if (stripeCardElementRef.current) {\n try {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n } catch {\n // Stripe element may already be detached during modal teardown.\n }\n }\n };\n }, [step, selectedProvider, stripePublishableKey, isLoadingConfig]);\n\n // Handle escape key\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen && !isProcessing) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, isProcessing, onClose]);\n\n const handleStripeSubmit = useCallback(async () => {\n if (!stripeRef.current || !stripeCardElementRef.current) {\n setError('Stripe not initialized');\n return;\n }\n\n if (!cardholderName.trim()) {\n setError('Please enter the cardholder name');\n return;\n }\n\n setIsProcessing(true);\n setError(null);\n\n try {\n // Step 1: Call backend to create SetupIntent and get client secret\n const verificationResult = await verifyPaymentMethod({\n billingAccountId,\n currency: 'USD',\n provider: PaymentProviderPreference.STRIPE,\n setAsDefault,\n });\n\n if (!verificationResult.clientSecret) {\n throw new Error('Failed to initiate card verification');\n }\n\n // Step 2: Confirm card setup using the client secret (no charge)\n const { setupIntent, error: stripeError } = await stripeRef.current.confirmCardSetup(\n verificationResult.clientSecret,\n {\n payment_method: {\n card: stripeCardElementRef.current,\n billing_details: { name: cardholderName },\n },\n }\n );\n\n if (stripeError) {\n throw new Error(stripeError.message);\n }\n\n if (setupIntent?.status !== 'succeeded') {\n throw new Error('Card verification failed');\n }\n\n // Step 3: Show success (webhook will save the payment method)\n setStep('success');\n\n // Wait for webhook to process (2 seconds) before refetching\n await new Promise((resolve) => setTimeout(resolve, 2000));\n onSuccess?.();\n\n // Show success message briefly before closing\n setTimeout(() => {\n onClose();\n }, 500);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add payment method');\n setIsProcessing(false);\n }\n }, [cardholderName, setAsDefault, billingAccountId, verifyPaymentMethod, onSuccess, onClose]);\n\n const handleRazorpaySubmit = useCallback(async () => {\n setIsProcessing(true);\n setError(null);\n\n try {\n // Load Razorpay SDK\n setIsLoadingSdk(true);\n try {\n await loadScript('https://checkout.razorpay.com/v1/checkout.js', 'razorpay-sdk');\n } catch {\n setError('Failed to load Razorpay SDK');\n setIsProcessing(false);\n setIsLoadingSdk(false);\n return;\n }\n setIsLoadingSdk(false);\n\n // Initiate ₹1 verification payment\n const verificationResult = await verifyPaymentMethod({\n billingAccountId,\n currency: 'INR',\n provider: PaymentProviderPreference.RAZORPAY,\n setAsDefault,\n });\n\n if (\n !verificationResult.success ||\n !verificationResult.orderId ||\n !verificationResult.razorpayKeyId\n ) {\n setError(verificationResult.error || 'Failed to initiate verification');\n setIsProcessing(false);\n return;\n }\n\n // Open Razorpay checkout with ALL payment methods\n if (!window.Razorpay) {\n setError('Razorpay SDK not loaded');\n setIsProcessing(false);\n return;\n }\n\n const options = {\n key: verificationResult.razorpayKeyId,\n amount: (verificationResult.amount ?? 0) * 100, // Convert to paise\n currency: verificationResult.currency.toUpperCase(),\n order_id: verificationResult.orderId,\n customer_id: verificationResult.razorpayCustomerId, // Link to customer for saving\n name: 'Add Payment Method',\n description: `₹${verificationResult.amount} verification charge (refundable)`,\n prefill: {\n name: verificationResult.prefillName,\n email: verificationResult.prefillEmail,\n contact: verificationResult.prefillContact,\n },\n notes: {\n purchaseType: 'PAYMENT_METHOD_VERIFICATION',\n default_method: setAsDefault.toString(),\n },\n handler: async () => {\n // Payment successful - payment method will be saved via webhook\n setStep('success');\n\n // Wait for webhook to process (2 seconds) before refetching\n await new Promise((resolve) => setTimeout(resolve, 2000));\n onSuccess?.();\n\n // Show success message briefly before closing\n setTimeout(() => {\n onClose();\n }, 500);\n },\n modal: {\n ondismiss: () => {\n setIsProcessing(false);\n setError('Payment cancelled');\n },\n },\n };\n\n const rzp = new window.Razorpay(options);\n rzp.open();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add payment method');\n setIsProcessing(false);\n }\n }, [setAsDefault, billingAccountId, verifyPaymentMethod, onSuccess, onClose]);\n\n const handleSubmit = useCallback(() => {\n if (selectedProvider === 'stripe') {\n handleStripeSubmit();\n } else if (selectedProvider === 'razorpay') {\n handleRazorpaySubmit();\n }\n }, [selectedProvider, handleStripeSubmit, handleRazorpaySubmit]);\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"modal-title\"\n >\n {/* Backdrop */}\n <div\n className=\"absolute inset-0 bg-bg-overlay backdrop-blur-sm\"\n onClick={!isProcessing ? onClose : undefined}\n aria-hidden=\"true\"\n />\n\n {/* Modal */}\n <div\n ref={modalRef}\n className=\"relative w-full max-w-md max-h-[90vh] mx-4 bg-bg-surface border border-border-seam rounded-card shadow-[var(--shadow-elevation-4)] flex flex-col\"\n >\n {/* Header */}\n <header className=\"flex items-center justify-between p-4 border-b border-border-subtle flex-shrink-0\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <CreditCard className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h2 id=\"modal-title\" className=\"text-lg font-semibold text-text-primary\">\n {step === 'success' ? 'Payment Method Added' : 'Add Payment Method'}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {step === 'select-provider' && 'Choose a payment provider'}\n {step === 'add-card' &&\n (selectedProvider === 'stripe'\n ? 'Add card via Stripe'\n : 'Add payment method with ₹1 verification')}\n {step === 'processing' && 'Processing...'}\n {step === 'success' && 'Your payment method has been saved'}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isProcessing}\n className=\"p-2 rounded-button hover:bg-bg-sunken text-text-secondary hover:text-text-primary transition-colors disabled:opacity-50\"\n aria-label=\"Close modal\"\n >\n <X className=\"size-5\" />\n </button>\n </header>\n\n {/* Content */}\n <div className=\"p-4 overflow-y-auto flex-1\">\n {isLoadingConfig ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"size-6 animate-spin text-text-secondary\" />\n </div>\n ) : step === 'select-provider' ? (\n <div className=\"space-y-3\">\n {showStripe && (\n <button\n type=\"button\"\n onClick={() => handleSelectProvider('stripe')}\n className=\"w-full flex items-center gap-4 p-4 border border-border-subtle rounded-lg hover:border-border-strong hover:bg-[var(--color-accent-soft)] transition-colors text-left\"\n >\n <div className=\"size-12 rounded-lg bg-accent-violet-subtle flex items-center justify-center\">\n <CreditCard className=\"size-6 text-accent-violet\" />\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">Stripe</p>\n <p className=\"text-sm text-text-secondary\">Cards, Apple Pay, Google Pay</p>\n </div>\n </button>\n )}\n {showRazorpay && (\n <button\n type=\"button\"\n onClick={() => handleSelectProvider('razorpay')}\n className=\"w-full flex items-center gap-4 p-4 border border-border-subtle rounded-lg hover:border-border-strong hover:bg-[var(--color-accent-soft)] transition-colors text-left\"\n >\n <div className=\"size-12 rounded-lg bg-status-info-bg-subtle flex items-center justify-center\">\n <CreditCard className=\"size-6 text-accent-blue\" />\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">Razorpay</p>\n <p className=\"text-sm text-text-secondary\">UPI, Netbanking, Cards</p>\n </div>\n </button>\n )}\n {!showStripe && !showRazorpay && (\n <div className=\"flex flex-col items-center py-8 text-center\">\n <AlertCircle className=\"size-12 text-status-warning-text mb-3\" />\n <p className=\"font-medium text-text-primary\">\n {tr('billing.overview.noPaymentProviders', 'No Payment Providers Available')}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">\n {isIndianAccount\n ? 'Razorpay is not configured for Indian accounts. Please contact support.'\n : 'Stripe is not configured for international accounts. Please contact support.'}\n </p>\n </div>\n )}\n </div>\n ) : step === 'add-card' ? (\n <div className=\"space-y-4\">\n {/* Error Message */}\n {error && (\n <div className=\"flex items-center gap-2 p-3 rounded-lg bg-status-error-bg-subtle border border-status-error-border text-status-error-text\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <p className=\"text-sm\">{error}</p>\n </div>\n )}\n\n {/* Cardholder Name - only for Stripe */}\n {selectedProvider === 'stripe' && (\n <div className=\"space-y-1.5\">\n <label\n htmlFor=\"cardholderName\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n Cardholder Name\n </label>\n <input\n type=\"text\"\n id=\"cardholderName\"\n value={cardholderName}\n onChange={(e) => setCardholderName(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder=\"John Doe\"\n disabled={isProcessing}\n />\n </div>\n )}\n\n {/* Stripe Card Element */}\n {selectedProvider === 'stripe' && (\n <div className=\"space-y-1.5\">\n <label className=\"block text-sm font-medium text-text-primary\">\n {tr('billing.overview.cardDetails', 'Card Details')}\n </label>\n <div className=\"relative\">\n <div\n ref={cardElementRef}\n className=\"p-3 border border-border-default rounded-lg bg-bg-surface min-h-[56px]\"\n />\n {isLoadingSdk && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-bg-overlay rounded-lg\">\n <Loader2 className=\"size-5 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-sm text-text-secondary\">Loading Stripe…</span>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Razorpay - Verification Info */}\n {selectedProvider === 'razorpay' && (\n <div className=\"p-3 border border-border-subtle rounded-lg bg-status-info-bg-subtle\">\n <p className=\"text-sm text-status-info-text\">\n <strong>Verification Process:</strong> A ₹1 charge will be made to verify your\n payment method. This amount will be refunded immediately after verification.\n </p>\n </div>\n )}\n\n {/* Set as default */}\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={setAsDefault}\n onChange={(e) => setSetAsDefault(e.target.checked)}\n className=\"size-4 rounded border-border-default text-text-link focus:ring-[var(--color-focus-ring)]\"\n disabled={isProcessing}\n />\n <span className=\"text-sm text-text-primary\">\n {tr('billing.overview.setAsDefault', 'Set as default payment method')}\n </span>\n </label>\n\n {/* Provider badge */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-subtle\">\n <span className=\"text-xs text-text-secondary\">Secured by</span>\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${\n selectedProvider === 'stripe'\n ? 'bg-accent-violet-subtle text-accent-violet'\n : 'bg-status-info-bg-subtle text-status-info-text'\n }`}\n >\n {selectedProvider === 'stripe' ? 'Stripe' : 'Razorpay'}\n </span>\n </div>\n </div>\n ) : (\n /* Success state */\n <div className=\"flex flex-col items-center py-8 text-center\">\n <div className=\"size-16 rounded-full bg-status-success-bg-subtle flex items-center justify-center mb-4\">\n <CheckCircle2 className=\"size-8 text-status-success-text\" />\n </div>\n <p className=\"font-medium text-text-primary\">\n {tr('billing.overview.paymentMethodAdded', 'Payment method added successfully!')}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">\n Your payment method has been securely saved.\n </p>\n </div>\n )}\n </div>\n\n {/* Footer */}\n {step !== 'success' && (\n <footer className=\"flex items-center justify-between gap-3 p-4 border-t border-border-subtle bg-bg-sunken rounded-b-lg flex-shrink-0\">\n {step === 'add-card' && showStripe && showRazorpay ? (\n <button\n type=\"button\"\n onClick={() => {\n setStep('select-provider');\n setSelectedProvider(null);\n setError(null);\n // Cleanup Stripe element\n if (stripeCardElementRef.current) {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n }\n }}\n disabled={isProcessing}\n className=\"px-4 py-2 text-sm font-medium text-text-primary hover:text-text-link transition-colors disabled:opacity-50\"\n >\n Back\n </button>\n ) : (\n <div />\n )}\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isProcessing}\n className=\"px-4 py-2 text-sm font-medium text-text-primary border border-border-subtle rounded-lg hover:bg-bg-sunken transition-colors disabled:opacity-50\"\n >\n Cancel\n </button>\n {step === 'add-card' && (\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={\n isProcessing ||\n isAddingPaymentMethod ||\n isLoadingSdk ||\n (selectedProvider === 'stripe' && !isCardComplete)\n }\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-lg hover:bg-action-primary-bgHover transition-colors disabled:opacity-50\"\n >\n {isProcessing || isAddingPaymentMethod ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {selectedProvider === 'razorpay' ? 'Processing...' : 'Saving...'}\n </>\n ) : isLoadingSdk ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Loading…\n </>\n ) : selectedProvider === 'stripe' ? (\n 'Add Card'\n ) : (\n 'Add Payment Method (₹1)'\n )}\n </button>\n )}\n </div>\n </footer>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;AA8GA,IAAM,KAAc,GAAa,MACxB,IAAI,SAAS,GAAS,MAAW;AACtC,KAAI,SAAS,eAAe,EAAG,EAAE;AAC/B,KAAS;AACT;;CAEF,IAAM,IAAS,SAAS,cAAc,SAAS;AAM/C,CALA,EAAO,KAAK,GACZ,EAAO,MAAM,GACb,EAAO,QAAQ,IACf,EAAO,eAAe,GAAS,EAC/B,EAAO,gBAAgB,EAAO,gBAAI,MAAM,kBAAkB,IAAM,CAAC,EACjE,SAAS,KAAK,YAAY,EAAO;EACjC,EAGS,KAAyD,EACpE,WACA,YACA,qBACA,aACA,YACA,mBACI;CACJ,IAAM,EAAE,SAAM,IAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAEnC,KAAW,EAAuB,KAAK,EACvC,IAAiB,EAAuB,KAAK,EAC7C,IAAuB,EAAiC,KAAK,EAC7D,IAAY,EAA8B,KAAK,EAG/C,EACJ,kBACA,yBACA,oBACA,WAAW,MACT,EAAyB,CAAC,EAAO,EAC/B,EAAE,0BAAuB,2BAAwB,GAAuB,EAKxE,IAAkB,GAAU,aAAa,KAAK,SAAS,GAAS,aAAa,KAAK,MAClF,IAAe,KAAmB,GAClC,IAAa,KAAiB,CAAC,GAE/B,CAAC,GAAM,KAAW,EAAoB,kBAAkB,EACxD,CAAC,GAAkB,KAAuB,EAAuC,KAAK,EACtF,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,GAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,GAAgB,KAAqB,EAAS,GAAG,EAClD,CAAC,GAAc,KAAmB,EAAS,GAAK,EAChD,CAAC,IAAgB,KAAqB,EAAS,GAAM,EAGrD,IAAuB,GAAa,MAAoC;AAG5E,EAFA,EAAoB,EAAS,EAC7B,EAAQ,WAAW,EACnB,EAAS,KAAK;IACb,EAAE,CAAC;AA2GN,CAxGA,QAAgB;AACd,EAAI,KACF,EAAQ,kBAAkB,EAC1B,EAAoB,KAAK,EACzB,EAAS,KAAK,EACd,EAAkB,GAAG,EACrB,EAAgB,GAAK,EACrB,EAAkB,GAAM,IAKtB,EAAqB,aADrB,EAAqB,QAAQ,SAAS,EACP;IAGlC,CAAC,EAAO,CAAC,EAGZ,QAAgB;AACV,QAAS,qBAAqB,MAC9B,KAAc,CAAC,IACjB,EAAqB,SAAS,GACrB,KAAgB,CAAC,KAC1B,EAAqB,WAAW;IAEjC;EAAC;EAAM;EAAiB;EAAY;EAAc;EAAqB,CAAC,EAG3E,QAAgB;AACV,cAAS,cAAc,MAAqB,WAGhD;OAAI,CAAC,KAAwB,CAAC,GAAiB;AAC7C,MAAS,oDAAoD;AAC7D;;AAyDF,UAtDK,MAEc,YAAY;AAC7B,MAAgB,GAAK;AACrB,QAAI;AAGF,SAFA,MAAM,EAAW,6BAA6B,YAAY,EAEtD,CAAC,OAAO,OACV,OAAU,MAAM,4BAA4B;KAG9C,IAAM,IAAS,OAAO,OAAO,EAAqB;AAClD,OAAU,UAAU;KAGpB,IAAI,IAAW;AACf,YAAO,CAAC,EAAe,WAAW,IAAW,IAE3C,CADA,MAAM,IAAI,SAAS,MAAY,WAAW,GAAS,IAAI,CAAC,EACxD;AAGF,SAAI,CAAC,EAAe,QAClB,OAAU,MAAM,mDAAmD;AAGrE,SAAI,EAAqB,QACvB;KAIF,IAAM,IADW,EAAO,UAAU,CACL,OAAO,QAAQ,EAC1C,OAAO,EAA0B,uCAAuC,EACzE,CAAC;AAKF,KAHA,EAAY,MAAM,EAAe,QAAQ,EACzC,EAAqB,UAAU,GAE/B,EAAY,GAAG,WAAW,MAAU;AAElC,MADA,EAAkB,EAAM,SAAS,EAC7B,EAAM,QACR,EAAS,EAAM,MAAM,QAAQ,GAE7B,EAAS,KAAK;OAEhB;aACK,GAAK;AACZ,OAAS,aAAe,QAAQ,EAAI,UAAU,wBAAwB;cAC9D;AACR,OAAgB,GAAM;;OAId,QAEC;AACX,QAAI,EAAqB,QACvB,KAAI;AAEF,KADA,EAAqB,QAAQ,SAAS,EACtC,EAAqB,UAAU;YACzB;QA3De;;IAgE1B;EAAC;EAAM;EAAkB;EAAsB;EAAgB,CAAC,EAGnE,QAAgB;EACd,IAAM,KAAiB,MAAqB;AAC1C,GAAI,EAAE,QAAQ,YAAY,KAAU,CAAC,KACnC,GAAS;;AAIb,SADA,SAAS,iBAAiB,WAAW,EAAc,QACtC,SAAS,oBAAoB,WAAW,EAAc;IAClE;EAAC;EAAQ;EAAc;EAAQ,CAAC;CAEnC,IAAM,IAAqB,EAAY,YAAY;AACjD,MAAI,CAAC,EAAU,WAAW,CAAC,EAAqB,SAAS;AACvD,KAAS,yBAAyB;AAClC;;AAGF,MAAI,CAAC,EAAe,MAAM,EAAE;AAC1B,KAAS,mCAAmC;AAC5C;;AAIF,EADA,EAAgB,GAAK,EACrB,EAAS,KAAK;AAEd,MAAI;GAEF,IAAM,IAAqB,MAAM,EAAoB;IACnD;IACA,UAAU;IACV,UAAU,EAA0B;IACpC;IACD,CAAC;AAEF,OAAI,CAAC,EAAmB,aACtB,OAAU,MAAM,uCAAuC;GAIzD,IAAM,EAAE,gBAAa,OAAO,MAAgB,MAAM,EAAU,QAAQ,iBAClE,EAAmB,cACnB,EACE,gBAAgB;IACd,MAAM,EAAqB;IAC3B,iBAAiB,EAAE,MAAM,GAAgB;IAC1C,EACF,CACF;AAED,OAAI,EACF,OAAU,MAAM,EAAY,QAAQ;AAGtC,OAAI,GAAa,WAAW,YAC1B,OAAU,MAAM,2BAA2B;AAW7C,GAPA,EAAQ,UAAU,EAGlB,MAAM,IAAI,SAAS,MAAY,WAAW,GAAS,IAAK,CAAC,EACzD,KAAa,EAGb,iBAAiB;AACf,OAAS;MACR,IAAI;WACA,GAAK;AAEZ,GADA,EAAS,aAAe,QAAQ,EAAI,UAAU,+BAA+B,EAC7E,EAAgB,GAAM;;IAEvB;EAAC;EAAgB;EAAc;EAAkB;EAAqB;EAAW;EAAQ,CAAC,EAEvF,IAAuB,EAAY,YAAY;AAEnD,EADA,EAAgB,GAAK,EACrB,EAAS,KAAK;AAEd,MAAI;AAEF,KAAgB,GAAK;AACrB,OAAI;AACF,UAAM,EAAW,gDAAgD,eAAe;WAC1E;AAGN,IAFA,EAAS,8BAA8B,EACvC,EAAgB,GAAM,EACtB,EAAgB,GAAM;AACtB;;AAEF,KAAgB,GAAM;GAGtB,IAAM,IAAqB,MAAM,EAAoB;IACnD;IACA,UAAU;IACV,UAAU,EAA0B;IACpC;IACD,CAAC;AAEF,OACE,CAAC,EAAmB,WACpB,CAAC,EAAmB,WACpB,CAAC,EAAmB,eACpB;AAEA,IADA,EAAS,EAAmB,SAAS,kCAAkC,EACvE,EAAgB,GAAM;AACtB;;AAIF,OAAI,CAAC,OAAO,UAAU;AAEpB,IADA,EAAS,0BAA0B,EACnC,EAAgB,GAAM;AACtB;;GAGF,IAAM,IAAU;IACd,KAAK,EAAmB;IACxB,SAAS,EAAmB,UAAU,KAAK;IAC3C,UAAU,EAAmB,SAAS,aAAa;IACnD,UAAU,EAAmB;IAC7B,aAAa,EAAmB;IAChC,MAAM;IACN,aAAa,IAAI,EAAmB,OAAO;IAC3C,SAAS;KACP,MAAM,EAAmB;KACzB,OAAO,EAAmB;KAC1B,SAAS,EAAmB;KAC7B;IACD,OAAO;KACL,cAAc;KACd,gBAAgB,EAAa,UAAU;KACxC;IACD,SAAS,YAAY;AASnB,KAPA,EAAQ,UAAU,EAGlB,MAAM,IAAI,SAAS,MAAY,WAAW,GAAS,IAAK,CAAC,EACzD,KAAa,EAGb,iBAAiB;AACf,SAAS;QACR,IAAI;;IAET,OAAO,EACL,iBAAiB;AAEf,KADA,EAAgB,GAAM,EACtB,EAAS,oBAAoB;OAEhC;IACF;AAEW,OAAI,OAAO,SAAS,EAAQ,CACpC,MAAM;WACH,GAAK;AAEZ,GADA,EAAS,aAAe,QAAQ,EAAI,UAAU,+BAA+B,EAC7E,EAAgB,GAAM;;IAEvB;EAAC;EAAc;EAAkB;EAAqB;EAAW;EAAQ,CAAC,EAEvE,KAAe,QAAkB;AACrC,EAAI,MAAqB,WACvB,GAAoB,GACX,MAAqB,cAC9B,GAAsB;IAEvB;EAAC;EAAkB;EAAoB;EAAqB,CAAC;AAIhE,QAFK,IAGH,kBAAC,OAAD;EACE,WAAU;EACV,MAAK;EACL,cAAW;EACX,mBAAgB;YAJlB,CAOE,kBAAC,OAAD;GACE,WAAU;GACV,SAAU,IAAyB,KAAA,IAAV;GACzB,eAAY;GACZ,CAAA,EAGF,kBAAC,OAAD;GACE,KAAK;GACL,WAAU;aAFZ;IAKE,kBAAC,UAAD;KAAQ,WAAU;eAAlB,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAY,WAAU,yBAA0B,CAAA;OAC5C,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;OAAI,IAAG;OAAc,WAAU;iBAC5B,MAAS,YAAY,yBAAyB;OAC5C,CAAA,EACL,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,MAAS,qBAAqB;QAC9B,MAAS,eACP,MAAqB,WAClB,wBACA;QACL,MAAS,gBAAgB;QACzB,MAAS,aAAa;QACrB;SACA,EAAA,CAAA,CACF;SACN,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,UAAU;MACV,WAAU;MACV,cAAW;gBAEX,kBAAC,IAAD,EAAG,WAAU,UAAW,CAAA;MACjB,CAAA,CACF;;IAGT,kBAAC,OAAD;KAAK,WAAU;eACZ,IACC,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD,EAAS,WAAU,2CAA4C,CAAA;MAC3D,CAAA,GACJ,MAAS,oBACX,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACG,KACC,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAqB,SAAS;QAC7C,WAAU;kBAHZ,CAKE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAY,WAAU,6BAA8B,CAAA;SAChD,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAgC;SAAU,CAAA,EACvD,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAAgC,CAAA,CACvE,EAAA,CAAA,CACC;;OAEV,KACC,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAqB,WAAW;QAC/C,WAAU;kBAHZ,CAKE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,GAAD,EAAY,WAAU,2BAA4B,CAAA;SAC9C,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;SAAG,WAAU;mBAAgC;SAAY,CAAA,EACzD,kBAAC,KAAD;SAAG,WAAU;mBAA8B;SAA0B,CAAA,CACjE,EAAA,CAAA,CACC;;OAEV,CAAC,KAAc,CAAC,KACf,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,GAAD,EAAa,WAAU,yCAA0C,CAAA;SACjE,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAG,uCAAuC,iCAAiC;UAC1E,CAAA;SACJ,kBAAC,KAAD;UAAG,WAAU;oBACV,IACG,4EACA;UACF,CAAA;SACA;;OAEJ;UACJ,MAAS,aACX,kBAAC,OAAD;MAAK,WAAU;gBAAf;OAEG,KACC,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAa,WAAU,wBAAyB,CAAA,EAChD,kBAAC,KAAD;SAAG,WAAU;mBAAW;SAAU,CAAA,CAC9B;;OAIP,MAAqB,YACpB,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SACE,SAAQ;SACR,WAAU;mBACX;SAEO,CAAA,EACR,kBAAC,SAAD;SACE,MAAK;SACL,IAAG;SACH,OAAO;SACP,WAAW,MAAM,EAAkB,EAAE,OAAO,MAAM;SAClD,WAAU;SACV,aAAY;SACZ,UAAU;SACV,CAAA,CACE;;OAIP,MAAqB,YACpB,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,SAAD;SAAO,WAAU;mBACd,EAAG,gCAAgC,eAAe;SAC7C,CAAA,EACR,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD;UACE,KAAK;UACL,WAAU;UACV,CAAA,EACD,KACC,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,GAAD,EAAS,WAAU,2CAA4C,CAAA,EAC/D,kBAAC,QAAD;WAAM,WAAU;qBAAmC;WAAsB,CAAA,CACrE;YAEJ;WACF;;OAIP,MAAqB,cACpB,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,KAAD;SAAG,WAAU;mBAAb,CACE,kBAAC,UAAD,EAAA,UAAQ,yBAA8B,CAAA,EAAA,wHAEpC;;QACA,CAAA;OAIR,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CACE,kBAAC,SAAD;SACE,MAAK;SACL,SAAS;SACT,WAAW,MAAM,EAAgB,EAAE,OAAO,QAAQ;SAClD,WAAU;SACV,UAAU;SACV,CAAA,EACF,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAG,iCAAiC,gCAAgC;SAChE,CAAA,CACD;;OAGR,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAA8B;SAAiB,CAAA,EAC/D,kBAAC,QAAD;SACE,WAAW,oEACT,MAAqB,WACjB,+CACA;mBAGL,MAAqB,WAAW,WAAW;SACvC,CAAA,CACH;;OACF;UAGN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAc,WAAU,mCAAoC,CAAA;QACxD,CAAA;OACN,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAG,uCAAuC,qCAAqC;QAC9E,CAAA;OACJ,kBAAC,KAAD;QAAG,WAAU;kBAAmC;QAE5C,CAAA;OACA;;KAEJ,CAAA;IAGL,MAAS,aACR,kBAAC,UAAD;KAAQ,WAAU;eAAlB,CACG,MAAS,cAAc,KAAc,IACpC,kBAAC,UAAD;MACE,MAAK;MACL,eAAe;AAKb,OAJA,EAAQ,kBAAkB,EAC1B,EAAoB,KAAK,EACzB,EAAS,KAAK,EAEd,AAEE,EAAqB,aADrB,EAAqB,QAAQ,SAAS,EACP;;MAGnC,UAAU;MACV,WAAU;gBACX;MAEQ,CAAA,GAET,kBAAC,OAAD,EAAO,CAAA,EAET,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,UAAU;OACV,WAAU;iBACX;OAEQ,CAAA,EACR,MAAS,cACR,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,UACE,KACA,KACA,KACC,MAAqB,YAAY,CAAC;OAErC,WAAU;iBAET,KAAgB,IACf,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,WAAU,uBAAwB,CAAA,EAC1C,MAAqB,aAAa,kBAAkB,YACpD,EAAA,CAAA,GACD,IACF,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,GAAD,EAAS,WAAU,uBAAwB,CAAA,EAAA,WAE1C,EAAA,CAAA,GACD,MAAqB,WACvB,aAEA;OAEK,CAAA,CAEP;QACC;;IAEP;KACF;MArRY"}
1
+ {"version":3,"file":"AddPaymentMethodModal.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/components/AddPaymentMethodModal.tsx"],"sourcesContent":["/**\n * Add Payment Method Modal Component\n * Modal for adding a new payment method via Stripe or Razorpay SDKs\n */\n\nimport { type FC, useState, useCallback, useEffect, useRef } from 'react';\nimport { X, CreditCard, Loader2, AlertCircle, CheckCircle2 } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { usePaymentProviderConfig, useDashboardMutations } from '../hooks';\nimport { PaymentProviderPreference } from '../../../shared/types';\nimport { getStripeCardElementStyle } from '../../../shared/utils';\n\n// Stripe types (loaded dynamically)\ndeclare global {\n interface Window {\n Stripe?: (key: string) => StripeInstance;\n Razorpay?: new (options: RazorpayOptions) => RazorpayInstance;\n }\n}\n\ninterface StripeInstance {\n elements: () => StripeElements;\n createPaymentMethod: (options: {\n type: 'card';\n card: StripeCardElement;\n billing_details?: { name?: string };\n }) => Promise<{\n paymentMethod?: {\n id: string;\n card?: { brand: string; last4: string; exp_month: number; exp_year: number };\n };\n error?: { message: string };\n }>;\n confirmCardSetup: (\n clientSecret: string,\n options?: {\n payment_method?: {\n card: StripeCardElement;\n billing_details?: { name?: string };\n };\n }\n ) => Promise<{\n setupIntent?: {\n id: string;\n status: string;\n payment_method?: string;\n };\n error?: { message: string };\n }>;\n}\n\ninterface StripeElements {\n create: (type: 'card', options?: object) => StripeCardElement;\n}\n\ninterface StripeCardElement {\n mount: (element: HTMLElement | string) => void;\n unmount: () => void;\n on: (\n event: string,\n handler: (event: { complete: boolean; error?: { message: string } }) => void\n ) => void;\n destroy: () => void;\n}\n\ninterface RazorpayOptions {\n key: string;\n amount: number;\n currency: string;\n order_id: string;\n customer_id?: string;\n name: string;\n description: string;\n method?: 'card' | 'upi' | 'netbanking' | 'wallet' | 'emi' | 'cardless_emi';\n handler: (response: RazorpayResponse) => void;\n modal?: { ondismiss?: () => void };\n prefill?: { name?: string; email?: string; contact?: string };\n notes?: Record<string, string>;\n config?: {\n display?: {\n hide?: Array<{ method: string }>;\n preferences?: {\n show_default_blocks?: boolean;\n };\n };\n };\n}\n\ninterface RazorpayInstance {\n open: () => void;\n close: () => void;\n}\n\ninterface RazorpayResponse {\n razorpay_payment_id: string;\n razorpay_token?: string;\n}\n\ninterface AddPaymentMethodModalProps {\n isOpen: boolean;\n onClose: () => void;\n billingAccountId: string;\n currency: string; // e.g., 'INR', 'USD'\n country?: string; // e.g., 'IN', 'US' - from billing address\n onSuccess?: () => void;\n}\n\ntype ModalStep = 'select-provider' | 'add-card' | 'processing' | 'success';\n\n// Load external script dynamically\nconst loadScript = (src: string, id: string): Promise<void> => {\n return new Promise((resolve, reject) => {\n if (document.getElementById(id)) {\n resolve();\n return;\n }\n const script = document.createElement('script');\n script.id = id;\n script.src = src;\n script.async = true;\n script.onload = () => resolve();\n script.onerror = () => reject(new Error(`Failed to load ${src}`));\n document.head.appendChild(script);\n });\n};\n\nexport const AddPaymentMethodModal: FC<AddPaymentMethodModalProps> = ({\n isOpen,\n onClose,\n billingAccountId,\n currency,\n country,\n onSuccess,\n}) => {\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 modalRef = useRef<HTMLDivElement>(null);\n const cardElementRef = useRef<HTMLDivElement>(null);\n const stripeCardElementRef = useRef<StripeCardElement | null>(null);\n const stripeRef = useRef<StripeInstance | null>(null);\n\n // Only fetch payment provider config when modal is open\n const {\n stripeEnabled,\n stripePublishableKey,\n razorpayEnabled,\n isLoading: isLoadingConfig,\n } = usePaymentProviderConfig(!isOpen);\n const { isAddingPaymentMethod, verifyPaymentMethod } = useDashboardMutations();\n\n // Determine which providers to show based on currency and country\n // Razorpay: India only (INR currency OR IN country)\n // Stripe: International (non-INR OR non-IN country)\n const isIndianAccount = currency?.toUpperCase() === 'INR' || country?.toUpperCase() === 'IN';\n const showRazorpay = razorpayEnabled && isIndianAccount;\n const showStripe = stripeEnabled && !isIndianAccount;\n\n const [step, setStep] = useState<ModalStep>('select-provider');\n const [selectedProvider, setSelectedProvider] = useState<'stripe' | 'razorpay' | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isProcessing, setIsProcessing] = useState(false);\n const [isLoadingSdk, setIsLoadingSdk] = useState(false);\n const [cardholderName, setCardholderName] = useState('');\n const [setAsDefault, setSetAsDefault] = useState(true);\n const [isCardComplete, setIsCardComplete] = useState(false);\n\n // Must be declared before the effects that reference it\n const handleSelectProvider = useCallback((provider: 'stripe' | 'razorpay') => {\n setSelectedProvider(provider);\n setStep('add-card');\n setError(null);\n }, []);\n\n // Reset state when modal opens/closes\n useEffect(() => {\n if (isOpen) {\n setStep('select-provider');\n setSelectedProvider(null);\n setError(null);\n setCardholderName('');\n setSetAsDefault(true);\n setIsCardComplete(false);\n } else {\n // Cleanup Stripe element when modal closes\n if (stripeCardElementRef.current) {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n }\n }\n }, [isOpen]);\n\n // Auto-select provider when only one is available (skip the select-provider screen)\n useEffect(() => {\n if (step !== 'select-provider' || isLoadingConfig) return;\n if (showStripe && !showRazorpay) {\n handleSelectProvider('stripe');\n } else if (showRazorpay && !showStripe) {\n handleSelectProvider('razorpay');\n }\n }, [step, isLoadingConfig, showStripe, showRazorpay, handleSelectProvider]);\n\n // Initialize Stripe when provider is selected\n useEffect(() => {\n if (step !== 'add-card' || selectedProvider !== 'stripe') return;\n\n // Show error if config loaded but key is missing\n if (!stripePublishableKey && !isLoadingConfig) {\n setError('Stripe is not configured. Please contact support.');\n return;\n }\n\n if (!stripePublishableKey) return;\n\n const initStripe = async () => {\n setIsLoadingSdk(true);\n try {\n await loadScript('https://js.stripe.com/v3/', 'stripe-js');\n\n if (!window.Stripe) {\n throw new Error('Stripe SDK failed to load');\n }\n\n const stripe = window.Stripe(stripePublishableKey);\n stripeRef.current = stripe;\n\n // Wait for the card element container to be mounted in the DOM\n let attempts = 0;\n while (!cardElementRef.current && attempts < 50) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n\n if (!cardElementRef.current) {\n throw new Error('Card element container not found after 5 seconds');\n }\n\n if (stripeCardElementRef.current) {\n return;\n }\n\n const elements = stripe.elements();\n const cardElement = elements.create('card', {\n style: getStripeCardElementStyle('system-ui, -apple-system, sans-serif'),\n });\n\n cardElement.mount(cardElementRef.current);\n stripeCardElementRef.current = cardElement;\n\n cardElement.on('change', (event) => {\n setIsCardComplete(event.complete);\n if (event.error) {\n setError(event.error.message);\n } else {\n setError(null);\n }\n });\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load Stripe');\n } finally {\n setIsLoadingSdk(false);\n }\n };\n\n initStripe();\n\n return () => {\n if (stripeCardElementRef.current) {\n try {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n } catch {\n // Stripe element may already be detached during modal teardown.\n }\n }\n };\n }, [step, selectedProvider, stripePublishableKey, isLoadingConfig]);\n\n // Handle escape key\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen && !isProcessing) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, isProcessing, onClose]);\n\n const handleStripeSubmit = useCallback(async () => {\n if (!stripeRef.current || !stripeCardElementRef.current) {\n setError('Stripe not initialized');\n return;\n }\n\n if (!cardholderName.trim()) {\n setError('Please enter the cardholder name');\n return;\n }\n\n setIsProcessing(true);\n setError(null);\n\n try {\n // Step 1: Call backend to create SetupIntent and get client secret\n const verificationResult = await verifyPaymentMethod({\n billingAccountId,\n currency: 'USD',\n provider: PaymentProviderPreference.STRIPE,\n setAsDefault,\n });\n\n if (!verificationResult.clientSecret) {\n throw new Error('Failed to initiate card verification');\n }\n\n // Step 2: Confirm card setup using the client secret (no charge)\n const { setupIntent, error: stripeError } = await stripeRef.current.confirmCardSetup(\n verificationResult.clientSecret,\n {\n payment_method: {\n card: stripeCardElementRef.current,\n billing_details: { name: cardholderName },\n },\n }\n );\n\n if (stripeError) {\n throw new Error(stripeError.message);\n }\n\n if (setupIntent?.status !== 'succeeded') {\n throw new Error('Card verification failed');\n }\n\n // Step 3: Show success (webhook will save the payment method)\n setStep('success');\n\n // Wait for webhook to process (2 seconds) before refetching\n await new Promise((resolve) => setTimeout(resolve, 2000));\n onSuccess?.();\n\n // Show success message briefly before closing\n setTimeout(() => {\n onClose();\n }, 500);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add payment method');\n setIsProcessing(false);\n }\n }, [cardholderName, setAsDefault, billingAccountId, verifyPaymentMethod, onSuccess, onClose]);\n\n const handleRazorpaySubmit = useCallback(async () => {\n setIsProcessing(true);\n setError(null);\n\n try {\n // Load Razorpay SDK\n setIsLoadingSdk(true);\n try {\n await loadScript('https://checkout.razorpay.com/v1/checkout.js', 'razorpay-sdk');\n } catch {\n setError('Failed to load Razorpay SDK');\n setIsProcessing(false);\n setIsLoadingSdk(false);\n return;\n }\n setIsLoadingSdk(false);\n\n // Initiate ₹1 verification payment\n const verificationResult = await verifyPaymentMethod({\n billingAccountId,\n currency: 'INR',\n provider: PaymentProviderPreference.RAZORPAY,\n setAsDefault,\n });\n\n if (\n !verificationResult.success ||\n !verificationResult.orderId ||\n !verificationResult.razorpayKeyId\n ) {\n setError(verificationResult.error || 'Failed to initiate verification');\n setIsProcessing(false);\n return;\n }\n\n // Open Razorpay checkout with ALL payment methods\n if (!window.Razorpay) {\n setError('Razorpay SDK not loaded');\n setIsProcessing(false);\n return;\n }\n\n const options = {\n key: verificationResult.razorpayKeyId,\n amount: (verificationResult.amount ?? 0) * 100, // Convert to paise\n currency: verificationResult.currency.toUpperCase(),\n order_id: verificationResult.orderId,\n customer_id: verificationResult.razorpayCustomerId, // Link to customer for saving\n name: 'Add Payment Method',\n description: `₹${verificationResult.amount} verification charge (refundable)`,\n prefill: {\n name: verificationResult.prefillName,\n email: verificationResult.prefillEmail,\n contact: verificationResult.prefillContact,\n },\n notes: {\n purchaseType: 'PAYMENT_METHOD_VERIFICATION',\n default_method: setAsDefault.toString(),\n },\n handler: async () => {\n // Payment successful - payment method will be saved via webhook\n setStep('success');\n\n // Wait for webhook to process (2 seconds) before refetching\n await new Promise((resolve) => setTimeout(resolve, 2000));\n onSuccess?.();\n\n // Show success message briefly before closing\n setTimeout(() => {\n onClose();\n }, 500);\n },\n modal: {\n ondismiss: () => {\n setIsProcessing(false);\n setError('Payment cancelled');\n },\n },\n };\n\n const rzp = new window.Razorpay(options);\n rzp.open();\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to add payment method');\n setIsProcessing(false);\n }\n }, [setAsDefault, billingAccountId, verifyPaymentMethod, onSuccess, onClose]);\n\n const handleSubmit = useCallback(() => {\n if (selectedProvider === 'stripe') {\n handleStripeSubmit();\n } else if (selectedProvider === 'razorpay') {\n handleRazorpaySubmit();\n }\n }, [selectedProvider, handleStripeSubmit, handleRazorpaySubmit]);\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"modal-title\"\n >\n {/* Backdrop */}\n <div\n className=\"absolute inset-0 bg-bg-overlay backdrop-blur-sm\"\n onClick={!isProcessing ? onClose : undefined}\n aria-hidden=\"true\"\n />\n\n {/* Modal */}\n <div\n ref={modalRef}\n className=\"relative w-full max-w-md max-h-[90vh] mx-4 bg-bg-surface border border-border-seam rounded-card shadow-[var(--shadow-elevation-4)] flex flex-col\"\n >\n {/* Header */}\n <header className=\"flex items-center justify-between p-4 border-b border-border-subtle flex-shrink-0\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <CreditCard className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h2 id=\"modal-title\" className=\"text-lg font-semibold text-text-primary\">\n {step === 'success' ? 'Payment Method Added' : 'Add Payment Method'}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {step === 'select-provider' && 'Choose a payment provider'}\n {step === 'add-card' &&\n (selectedProvider === 'stripe'\n ? 'Add card via Stripe'\n : 'Add payment method with ₹1 verification')}\n {step === 'processing' && 'Processing...'}\n {step === 'success' && 'Your payment method has been saved'}\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isProcessing}\n className=\"p-2 rounded-button hover:bg-bg-sunken text-text-secondary hover:text-text-primary transition-colors disabled:opacity-50\"\n aria-label=\"Close modal\"\n >\n <X className=\"size-5\" />\n </button>\n </header>\n\n {/* Content */}\n <div className=\"p-4 overflow-y-auto flex-1\">\n {isLoadingConfig ? (\n <div className=\"flex items-center justify-center py-8\">\n <Loader2 className=\"size-6 animate-spin text-text-secondary\" />\n </div>\n ) : step === 'select-provider' ? (\n <div className=\"space-y-3\">\n {showStripe && (\n <button\n type=\"button\"\n onClick={() => handleSelectProvider('stripe')}\n className=\"w-full flex items-center gap-4 p-4 border border-border-subtle rounded-lg hover:border-border-strong hover:bg-[var(--color-accent-soft)] transition-colors text-left\"\n >\n <div className=\"size-12 rounded-lg bg-accent-violet-subtle flex items-center justify-center\">\n <CreditCard className=\"size-6 text-accent-violet\" />\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">Stripe</p>\n <p className=\"text-sm text-text-secondary\">Cards, Apple Pay, Google Pay</p>\n </div>\n </button>\n )}\n {showRazorpay && (\n <button\n type=\"button\"\n onClick={() => handleSelectProvider('razorpay')}\n className=\"w-full flex items-center gap-4 p-4 border border-border-subtle rounded-lg hover:border-border-strong hover:bg-[var(--color-accent-soft)] transition-colors text-left\"\n >\n <div className=\"size-12 rounded-lg bg-status-info-bg-subtle flex items-center justify-center\">\n <CreditCard className=\"size-6 text-accent-blue\" />\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">Razorpay</p>\n <p className=\"text-sm text-text-secondary\">UPI, Netbanking, Cards</p>\n </div>\n </button>\n )}\n {!showStripe && !showRazorpay && (\n <div className=\"flex flex-col items-center py-8 text-center\">\n <AlertCircle className=\"size-12 text-status-warning-text mb-3\" />\n <p className=\"font-medium text-text-primary\">\n {tr('billing.overview.noPaymentProviders', 'No Payment Providers Available')}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">\n {isIndianAccount\n ? 'Razorpay is not configured for Indian accounts. Please contact support.'\n : 'Stripe is not configured for international accounts. Please contact support.'}\n </p>\n </div>\n )}\n </div>\n ) : step === 'add-card' ? (\n <div className=\"space-y-4\">\n {/* Error Message */}\n {error && (\n <div className=\"flex items-center gap-2 p-3 rounded-lg bg-status-error-bg-subtle border border-status-error-border text-status-error-text\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <p className=\"text-sm\">{error}</p>\n </div>\n )}\n\n {/* Cardholder Name - only for Stripe */}\n {selectedProvider === 'stripe' && (\n <div className=\"space-y-1.5\">\n <label\n htmlFor=\"cardholderName\"\n className=\"block text-sm font-medium text-text-primary\"\n >\n Cardholder Name\n </label>\n <input\n type=\"text\"\n id=\"cardholderName\"\n value={cardholderName}\n onChange={(e) => setCardholderName(e.target.value)}\n className=\"w-full px-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder=\"John Doe\"\n disabled={isProcessing}\n />\n </div>\n )}\n\n {/* Stripe Card Element */}\n {selectedProvider === 'stripe' && (\n <div className=\"space-y-1.5\">\n <label className=\"block text-sm font-medium text-text-primary\">\n {tr('billing.overview.cardDetails', 'Card Details')}\n </label>\n <div className=\"relative\">\n <div\n ref={cardElementRef}\n className=\"p-3 border border-border-default rounded-lg bg-bg-surface min-h-[56px]\"\n />\n {isLoadingSdk && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-bg-overlay rounded-lg\">\n <Loader2 className=\"size-5 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-sm text-text-secondary\">Loading Stripe…</span>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Razorpay - Verification Info */}\n {selectedProvider === 'razorpay' && (\n <div className=\"p-3 border border-border-subtle rounded-lg bg-status-info-bg-subtle\">\n <p className=\"text-sm text-status-info-text\">\n <strong>Verification Process:</strong> A ₹1 charge will be made to verify your\n payment method. This amount will be refunded immediately after verification.\n </p>\n </div>\n )}\n\n {/* Set as default */}\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={setAsDefault}\n onChange={(e) => setSetAsDefault(e.target.checked)}\n className=\"size-4 rounded border-border-default text-text-link focus:ring-[var(--color-focus-ring)]\"\n disabled={isProcessing}\n />\n <span className=\"text-sm text-text-primary\">\n {tr('billing.overview.setAsDefault', 'Set as default payment method')}\n </span>\n </label>\n\n {/* Provider badge */}\n <div className=\"flex items-center gap-2 pt-2 border-t border-border-subtle\">\n <span className=\"text-xs text-text-secondary\">Secured by</span>\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${\n selectedProvider === 'stripe'\n ? 'bg-accent-violet-subtle text-accent-violet'\n : 'bg-status-info-bg-subtle text-status-info-text'\n }`}\n >\n {selectedProvider === 'stripe' ? 'Stripe' : 'Razorpay'}\n </span>\n </div>\n </div>\n ) : (\n /* Success state */\n <div className=\"flex flex-col items-center py-8 text-center\">\n <div className=\"size-16 rounded-full bg-status-success-bg-subtle flex items-center justify-center mb-4\">\n <CheckCircle2 className=\"size-8 text-status-success-text\" />\n </div>\n <p className=\"font-medium text-text-primary\">\n {tr('billing.overview.paymentMethodAdded', 'Payment method added successfully!')}\n </p>\n <p className=\"text-sm text-text-secondary mt-1\">\n Your payment method has been securely saved.\n </p>\n </div>\n )}\n </div>\n\n {/* Footer */}\n {step !== 'success' && (\n <footer className=\"flex items-center justify-between gap-3 p-4 border-t border-border-subtle bg-bg-sunken rounded-b-lg flex-shrink-0\">\n {step === 'add-card' && showStripe && showRazorpay ? (\n <button\n type=\"button\"\n onClick={() => {\n setStep('select-provider');\n setSelectedProvider(null);\n setError(null);\n // Cleanup Stripe element\n if (stripeCardElementRef.current) {\n stripeCardElementRef.current.destroy();\n stripeCardElementRef.current = null;\n }\n }}\n disabled={isProcessing}\n className=\"px-4 py-2 text-sm font-medium text-text-primary hover:text-text-link transition-colors disabled:opacity-50\"\n >\n Back\n </button>\n ) : (\n <div />\n )}\n <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isProcessing}\n className=\"px-4 py-2 text-sm font-medium text-text-primary border border-border-subtle rounded-lg hover:bg-bg-sunken transition-colors disabled:opacity-50\"\n >\n Cancel\n </button>\n {step === 'add-card' && (\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={\n isProcessing ||\n isAddingPaymentMethod ||\n isLoadingSdk ||\n (selectedProvider === 'stripe' && !isCardComplete)\n }\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-lg hover:bg-action-primary-bgHover transition-colors disabled:opacity-50\"\n >\n {isProcessing || isAddingPaymentMethod ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {selectedProvider === 'razorpay' ? 'Processing...' : 'Saving...'}\n </>\n ) : isLoadingSdk ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Loading…\n </>\n ) : selectedProvider === 'stripe' ? (\n 'Add Card'\n ) : (\n 'Add Payment Method (₹1)'\n )}\n </button>\n )}\n </div>\n </footer>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BillingAccountCard.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/components/BillingAccountCard.tsx"],"sourcesContent":["/**\n * Billing Account Card Component\n * Displays billing account details with actions\n */\n\nimport { type FC, useState } from 'react';\nimport {\n Building2,\n Mail,\n CreditCard,\n Edit2,\n ChevronRight,\n Coins,\n Check,\n Calendar,\n} from 'lucide-react';\nimport type { BillingAccount } from '../../../shared/types';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface BillingAccountCardProps {\n account: BillingAccount;\n isDefault?: boolean;\n isSelected?: boolean;\n onSelect?: () => void;\n onEdit?: () => void;\n onViewTransactions?: () => void;\n onViewCreditTransactions?: () => void;\n className?: string;\n /** Optional tour anchor applied to the card root (for onboarding tours). */\n dataTour?: string;\n}\n\nexport const BillingAccountCard: FC<BillingAccountCardProps> = ({\n account,\n isDefault = false,\n isSelected = false,\n onSelect,\n onEdit,\n onViewTransactions,\n onViewCreditTransactions,\n className = '',\n dataTour,\n}) => {\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 [isHovered, setIsHovered] = useState(false);\n\n const formatDate = (dateString: string) => {\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n };\n\n return (\n <article\n data-tour={dataTour}\n className={`\n relative border rounded-card bg-bg-surface transition-[box-shadow,transform] duration-200 ease-[var(--motion-easing-out)]\n ${isSelected ? 'border-border-strong ring-1 ring-[var(--color-focus-ring)]' : 'border-border-seam'}\n ${isHovered ? 'shadow-elevation-2 motion-safe:-translate-y-[var(--pop-lift-y)]' : 'shadow-[var(--shadow-pop)]'}\n ${onSelect ? 'cursor-pointer' : ''}\n ${className}\n `}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={onSelect}\n role={onSelect ? 'button' : 'article'}\n tabIndex={onSelect ? 0 : undefined}\n onKeyDown={(e) => {\n if (onSelect && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onSelect();\n }\n }}\n >\n {/* Header */}\n <header className=\"p-4 border-b border-border-subtle\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-10 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center flex-shrink-0\">\n <Building2 className=\"size-5 text-text-link\" />\n </div>\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"font-semibold text-text-primary truncate\">{account.name}</h3>\n {isDefault && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-[var(--color-accent-soft)] text-text-link\">\n {tr('billing.overview.default', 'Default')}\n </span>\n )}\n {isSelected && (\n <span className=\"inline-flex items-center justify-center size-5 rounded-full bg-action-primary-bg\">\n <Check className=\"size-3 text-action-primary-text\" />\n </span>\n )}\n </div>\n <p className=\"text-sm text-text-secondary truncate flex items-center gap-1\">\n <Mail className=\"size-3.5\" />\n {account.email}\n </p>\n </div>\n </div>\n {onEdit && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit();\n }}\n className=\"p-2 rounded-button hover:bg-bg-sunken text-text-secondary hover:text-text-primary transition-colors\"\n aria-label=\"Edit billing account\"\n >\n <Edit2 className=\"size-4\" />\n </button>\n )}\n </div>\n </header>\n\n {/* Body */}\n <div className=\"p-4 space-y-4\">\n {/* Stats Grid */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-1\">\n <p className=\"text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Credit Balance\n </p>\n <p className=\"text-lg font-semibold text-text-primary flex items-center gap-1.5\">\n <Coins className={`size-4 ${statusTokens.warning.icon}`} />\n {(account.creditAmount || 0).toLocaleString()} Credits\n </p>\n </div>\n <div className=\"space-y-1\">\n <p className=\"text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Payment Currency\n </p>\n <p className=\"text-lg font-semibold text-text-primary flex items-center gap-1.5\">\n <CreditCard className=\"size-4 text-text-link\" />\n {account.currency || 'USD'}\n </p>\n </div>\n </div>\n\n {/* Meta Info */}\n <div className=\"pt-3 border-t border-border-subtle\">\n <p className=\"text-xs text-text-secondary flex items-center gap-1\">\n <Calendar className=\"size-3.5\" />\n Created {formatDate(account.createdAt)}\n </p>\n </div>\n </div>\n\n {/* Footer Actions */}\n {(onViewTransactions || onViewCreditTransactions) && (\n <footer className=\"px-4 py-3 border-t border-border-subtle bg-bg-sunken rounded-b-card\">\n <div className=\"flex items-center gap-2\">\n {onViewTransactions && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onViewTransactions();\n }}\n className=\"flex-1 flex items-center justify-center gap-1.5 px-3 py-2 text-sm font-medium text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n Transactions\n <ChevronRight className=\"size-4\" />\n </button>\n )}\n {onViewCreditTransactions && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onViewCreditTransactions();\n }}\n className=\"flex-1 flex items-center justify-center gap-1.5 px-3 py-2 text-sm font-medium text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n Credit History\n <ChevronRight className=\"size-4\" />\n </button>\n )}\n </div>\n </footer>\n )}\n\n {/* Status indicator */}\n {!account.isActive && (\n <div className=\"absolute inset-0 bg-bg-overlay backdrop-blur-sm rounded-card flex items-center justify-center\">\n <span className=\"px-3 py-1.5 rounded-full bg-status-error-bg-subtle text-status-error-text text-sm font-medium\">\n Inactive\n </span>\n </div>\n )}\n </article>\n );\n};\n"],"mappings":";;;;;;AAiCA,IAAa,KAAmD,EAC9D,YACA,eAAY,IACZ,gBAAa,IACb,aACA,WACA,uBACA,6BACA,eAAY,IACZ,kBACI;CACJ,IAAM,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAEnC,CAAC,GAAW,KAAgB,EAAS,GAAM;AAUjD,QACE,kBAAC,WAAD;EACE,aAAW;EACX,WAAW;;UAEP,IAAa,+DAA+D,qBAAqB;UACjG,IAAY,oEAAoE,6BAA6B;UAC7G,IAAW,mBAAmB,GAAG;UACjC,EAAU;;EAEd,oBAAoB,EAAa,GAAK;EACtC,oBAAoB,EAAa,GAAM;EACvC,SAAS;EACT,MAAM,IAAW,WAAW;EAC5B,UAAU,IAAW,IAAI,KAAA;EACzB,YAAY,MAAM;AAChB,GAAI,MAAa,EAAE,QAAQ,WAAW,EAAE,QAAQ,SAC9C,EAAE,gBAAgB,EAClB,GAAU;;YAjBhB;GAsBE,kBAAC,UAAD;IAAQ,WAAU;cAChB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAW,WAAU,yBAA0B,CAAA;OAC3C,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,MAAD;UAAI,WAAU;oBAA4C,EAAQ;UAAU,CAAA;SAC3E,KACC,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAG,4BAA4B,UAAU;UACrC,CAAA;SAER,KACC,kBAAC,QAAD;UAAM,WAAU;oBACd,kBAAC,GAAD,EAAO,WAAU,mCAAoC,CAAA;UAChD,CAAA;SAEL;WACN,kBAAC,KAAD;QAAG,WAAU;kBAAb,CACE,kBAAC,GAAD,EAAM,WAAU,YAAa,CAAA,EAC5B,EAAQ,MACP;UACA;SACF;SACL,KACC,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,MAAM;AAEd,OADA,EAAE,iBAAiB,EACnB,GAAQ;;MAEV,WAAU;MACV,cAAW;gBAEX,kBAAC,GAAD,EAAO,WAAU,UAAW,CAAA;MACrB,CAAA,CAEP;;IACC,CAAA;GAGT,kBAAC,OAAD;IAAK,WAAU;cAAf,CAEE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAkE;OAE3E,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACE,kBAAC,GAAD,EAAO,WAAW,UAAU,EAAa,QAAQ,QAAU,CAAA;SACzD,EAAQ,gBAAgB,GAAG,gBAAgB;QAAC;QAC5C;SACA;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAkE;OAE3E,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb,CACE,kBAAC,GAAD,EAAY,WAAU,yBAA0B,CAAA,EAC/C,EAAQ,YAAY,MACnB;SACA;QACF;QAGN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,KAAD;MAAG,WAAU;gBAAb;OACE,kBAAC,GAAD,EAAU,WAAU,YAAa,CAAA;;SApGvB,MACX,IAAI,KAAK,EAAW,CAAC,mBAAmB,SAAS;QACtD,MAAM;QACN,OAAO;QACP,KAAK;QACN,CAAC,EAgG0B,EAAQ,UAAU;OACpC;;KACA,CAAA,CACF;;IAGJ,KAAsB,MACtB,kBAAC,UAAD;IAAQ,WAAU;cAChB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACG,KACC,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,MAAM;AAEd,OADA,EAAE,iBAAiB,EACnB,GAAoB;;MAEtB,WAAU;gBANZ,CAOC,gBAEC,kBAAC,GAAD,EAAc,WAAU,UAAW,CAAA,CAC5B;SAEV,KACC,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,MAAM;AAEd,OADA,EAAE,iBAAiB,EACnB,GAA0B;;MAE5B,WAAU;gBANZ,CAOC,kBAEC,kBAAC,GAAD,EAAc,WAAU,UAAW,CAAA,CAC5B;QAEP;;IACC,CAAA;GAIV,CAAC,EAAQ,YACR,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,QAAD;KAAM,WAAU;eAAgG;KAEzG,CAAA;IACH,CAAA;GAEA"}
1
+ {"version":3,"file":"BillingAccountCard.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/components/BillingAccountCard.tsx"],"sourcesContent":["/**\n * Billing Account Card Component\n * Displays billing account details with actions\n */\n\nimport { type FC, useState } from 'react';\nimport {\n Building2,\n Mail,\n CreditCard,\n Edit2,\n ChevronRight,\n Coins,\n Check,\n Calendar,\n} from 'lucide-react';\nimport type { BillingAccount } from '../../../shared/types';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface BillingAccountCardProps {\n account: BillingAccount;\n isDefault?: boolean;\n isSelected?: boolean;\n onSelect?: () => void;\n onEdit?: () => void;\n onViewTransactions?: () => void;\n onViewCreditTransactions?: () => void;\n className?: string;\n /** Optional tour anchor applied to the card root (for onboarding tours). */\n dataTour?: string;\n}\n\nexport const BillingAccountCard: FC<BillingAccountCardProps> = ({\n account,\n isDefault = false,\n isSelected = false,\n onSelect,\n onEdit,\n onViewTransactions,\n onViewCreditTransactions,\n className = '',\n dataTour,\n}) => {\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 [isHovered, setIsHovered] = useState(false);\n\n const formatDate = (dateString: string) => {\n return new Date(dateString).toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n };\n\n return (\n <article\n data-tour={dataTour}\n className={`\n relative border rounded-card bg-bg-surface transition-[box-shadow,transform] duration-200 ease-[var(--motion-easing-out)]\n ${isSelected ? 'border-border-strong ring-1 ring-[var(--color-focus-ring)]' : 'border-border-seam'}\n ${isHovered ? 'shadow-elevation-2 motion-safe:-translate-y-[var(--pop-lift-y)]' : 'shadow-[var(--shadow-pop)]'}\n ${onSelect ? 'cursor-pointer' : ''}\n ${className}\n `}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={onSelect}\n role={onSelect ? 'button' : 'article'}\n tabIndex={onSelect ? 0 : undefined}\n onKeyDown={(e) => {\n if (onSelect && (e.key === 'Enter' || e.key === ' ')) {\n e.preventDefault();\n onSelect();\n }\n }}\n >\n {/* Header */}\n <header className=\"p-4 border-b border-border-subtle\">\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex items-center gap-3 min-w-0\">\n <div className=\"size-10 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center flex-shrink-0\">\n <Building2 className=\"size-5 text-text-link\" />\n </div>\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <h3 className=\"font-semibold text-text-primary truncate\">{account.name}</h3>\n {isDefault && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-[var(--color-accent-soft)] text-text-link\">\n {tr('billing.overview.default', 'Default')}\n </span>\n )}\n {isSelected && (\n <span className=\"inline-flex items-center justify-center size-5 rounded-full bg-action-primary-bg\">\n <Check className=\"size-3 text-action-primary-text\" />\n </span>\n )}\n </div>\n <p className=\"text-sm text-text-secondary truncate flex items-center gap-1\">\n <Mail className=\"size-3.5\" />\n {account.email}\n </p>\n </div>\n </div>\n {onEdit && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onEdit();\n }}\n className=\"p-2 rounded-button hover:bg-bg-sunken text-text-secondary hover:text-text-primary transition-colors\"\n aria-label=\"Edit billing account\"\n >\n <Edit2 className=\"size-4\" />\n </button>\n )}\n </div>\n </header>\n\n {/* Body */}\n <div className=\"p-4 space-y-4\">\n {/* Stats Grid */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-1\">\n <p className=\"text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Credit Balance\n </p>\n <p className=\"text-lg font-semibold text-text-primary flex items-center gap-1.5\">\n <Coins className={`size-4 ${statusTokens.warning.icon}`} />\n {(account.creditAmount || 0).toLocaleString()} Credits\n </p>\n </div>\n <div className=\"space-y-1\">\n <p className=\"text-xs font-medium text-text-secondary uppercase tracking-wide\">\n Payment Currency\n </p>\n <p className=\"text-lg font-semibold text-text-primary flex items-center gap-1.5\">\n <CreditCard className=\"size-4 text-text-link\" />\n {account.currency || 'USD'}\n </p>\n </div>\n </div>\n\n {/* Meta Info */}\n <div className=\"pt-3 border-t border-border-subtle\">\n <p className=\"text-xs text-text-secondary flex items-center gap-1\">\n <Calendar className=\"size-3.5\" />\n Created {formatDate(account.createdAt)}\n </p>\n </div>\n </div>\n\n {/* Footer Actions */}\n {(onViewTransactions || onViewCreditTransactions) && (\n <footer className=\"px-4 py-3 border-t border-border-subtle bg-bg-sunken rounded-b-card\">\n <div className=\"flex items-center gap-2\">\n {onViewTransactions && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onViewTransactions();\n }}\n className=\"flex-1 flex items-center justify-center gap-1.5 px-3 py-2 text-sm font-medium text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n Transactions\n <ChevronRight className=\"size-4\" />\n </button>\n )}\n {onViewCreditTransactions && (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onViewCreditTransactions();\n }}\n className=\"flex-1 flex items-center justify-center gap-1.5 px-3 py-2 text-sm font-medium text-text-secondary hover:text-text-primary hover:bg-bg-sunken rounded-button transition-colors\"\n >\n Credit History\n <ChevronRight className=\"size-4\" />\n </button>\n )}\n </div>\n </footer>\n )}\n\n {/* Status indicator */}\n {!account.isActive && (\n <div className=\"absolute inset-0 bg-bg-overlay backdrop-blur-sm rounded-card flex items-center justify-center\">\n <span className=\"px-3 py-1.5 rounded-full bg-status-error-bg-subtle text-status-error-text text-sm font-medium\">\n Inactive\n </span>\n </div>\n )}\n </article>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CreateBillingAccountModal.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/components/CreateBillingAccountModal.tsx"],"sourcesContent":["/**\n * Create Billing Account Modal Component\n * Modal for creating a new billing account\n */\n\nimport { type FC, useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport {\n X,\n Building2,\n Mail,\n FileText,\n Loader2,\n AlertCircle,\n ChevronDown,\n Search,\n Check,\n MapPin,\n} from 'lucide-react';\nimport type { CreateBillingAccountInput, SetBillingAddressInput } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface CreateBillingAccountModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (\n input: CreateBillingAccountInput,\n address?: Omit<SetBillingAddressInput, 'billingAccountId'>\n ) => Promise<void>;\n isSubmitting?: boolean;\n error?: string | null;\n}\n\n// Form data includes both account and address fields\ninterface FormData extends CreateBillingAccountInput {\n // Address fields\n country: string;\n line1: string;\n line2: string;\n city: string;\n state: string;\n postalCode: string;\n}\n\n// Common countries (sorted by usage)\nconst COUNTRIES = [\n { code: 'IN', name: 'India' },\n { code: 'US', name: 'United States' },\n { code: 'GB', name: 'United Kingdom' },\n { code: 'CA', name: 'Canada' },\n { code: 'AU', name: 'Australia' },\n { code: 'DE', name: 'Germany' },\n { code: 'FR', name: 'France' },\n { code: 'SG', name: 'Singapore' },\n { code: 'AE', name: 'United Arab Emirates' },\n { code: 'JP', name: 'Japan' },\n { code: 'NL', name: 'Netherlands' },\n { code: 'CH', name: 'Switzerland' },\n { code: 'SE', name: 'Sweden' },\n { code: 'NO', name: 'Norway' },\n { code: 'DK', name: 'Denmark' },\n { code: 'NZ', name: 'New Zealand' },\n { code: 'IE', name: 'Ireland' },\n { code: 'IT', name: 'Italy' },\n { code: 'ES', name: 'Spain' },\n { code: 'BR', name: 'Brazil' },\n { code: 'MX', name: 'Mexico' },\n { code: 'ZA', name: 'South Africa' },\n { code: 'KR', name: 'South Korea' },\n { code: 'HK', name: 'Hong Kong' },\n { code: 'MY', name: 'Malaysia' },\n { code: 'ID', name: 'Indonesia' },\n { code: 'PH', name: 'Philippines' },\n { code: 'TH', name: 'Thailand' },\n { code: 'VN', name: 'Vietnam' },\n { code: 'PK', name: 'Pakistan' },\n { code: 'BD', name: 'Bangladesh' },\n { code: 'LK', name: 'Sri Lanka' },\n];\n\n// Indian states and union territories (for GST IGST vs CGST+SGST determination)\nconst INDIAN_STATES = [\n 'Andaman and Nicobar Islands',\n 'Andhra Pradesh',\n 'Arunachal Pradesh',\n 'Assam',\n 'Bihar',\n 'Chandigarh',\n 'Chhattisgarh',\n 'Dadra and Nagar Haveli and Daman and Diu',\n 'Delhi',\n 'Goa',\n 'Gujarat',\n 'Haryana',\n 'Himachal Pradesh',\n 'Jammu and Kashmir',\n 'Jharkhand',\n 'Karnataka',\n 'Kerala',\n 'Ladakh',\n 'Lakshadweep',\n 'Madhya Pradesh',\n 'Maharashtra',\n 'Manipur',\n 'Meghalaya',\n 'Mizoram',\n 'Nagaland',\n 'Odisha',\n 'Puducherry',\n 'Punjab',\n 'Rajasthan',\n 'Sikkim',\n 'Tamil Nadu',\n 'Telangana',\n 'Tripura',\n 'Uttar Pradesh',\n 'Uttarakhand',\n 'West Bengal',\n];\n\ninterface CurrencyOption {\n code: string;\n name: string;\n symbol: string;\n flag: string;\n}\n\n// All major currencies supported (sorted by popularity/usage)\nconst CURRENCY_OPTIONS: CurrencyOption[] = [\n // Most common\n { code: 'USD', name: 'US Dollar', symbol: '$', flag: 'US' },\n { code: 'EUR', name: 'Euro', symbol: '€', flag: 'EU' },\n { code: 'GBP', name: 'British Pound', symbol: '£', flag: 'GB' },\n { code: 'INR', name: 'Indian Rupee', symbol: '₹', flag: 'IN' },\n { code: 'CAD', name: 'Canadian Dollar', symbol: 'C$', flag: 'CA' },\n { code: 'AUD', name: 'Australian Dollar', symbol: 'A$', flag: 'AU' },\n { code: 'JPY', name: 'Japanese Yen', symbol: '¥', flag: 'JP' },\n { code: 'CNY', name: 'Chinese Yuan', symbol: '¥', flag: 'CN' },\n { code: 'CHF', name: 'Swiss Franc', symbol: 'CHF', flag: 'CH' },\n { code: 'SGD', name: 'Singapore Dollar', symbol: 'S$', flag: 'SG' },\n { code: 'HKD', name: 'Hong Kong Dollar', symbol: 'HK$', flag: 'HK' },\n { code: 'NZD', name: 'New Zealand Dollar', symbol: 'NZ$', flag: 'NZ' },\n { code: 'SEK', name: 'Swedish Krona', symbol: 'kr', flag: 'SE' },\n { code: 'NOK', name: 'Norwegian Krone', symbol: 'kr', flag: 'NO' },\n { code: 'DKK', name: 'Danish Krone', symbol: 'kr', flag: 'DK' },\n { code: 'MXN', name: 'Mexican Peso', symbol: '$', flag: 'MX' },\n { code: 'BRL', name: 'Brazilian Real', symbol: 'R$', flag: 'BR' },\n { code: 'KRW', name: 'South Korean Won', symbol: '₩', flag: 'KR' },\n { code: 'ZAR', name: 'South African Rand', symbol: 'R', flag: 'ZA' },\n { code: 'AED', name: 'UAE Dirham', symbol: 'د.إ', flag: 'AE' },\n { code: 'SAR', name: 'Saudi Riyal', symbol: '﷼', flag: 'SA' },\n { code: 'PLN', name: 'Polish Złoty', symbol: 'zł', flag: 'PL' },\n { code: 'THB', name: 'Thai Baht', symbol: '฿', flag: 'TH' },\n { code: 'MYR', name: 'Malaysian Ringgit', symbol: 'RM', flag: 'MY' },\n { code: 'IDR', name: 'Indonesian Rupiah', symbol: 'Rp', flag: 'ID' },\n { code: 'PHP', name: 'Philippine Peso', symbol: '₱', flag: 'PH' },\n { code: 'TWD', name: 'Taiwan Dollar', symbol: 'NT$', flag: 'TW' },\n { code: 'CZK', name: 'Czech Koruna', symbol: 'Kč', flag: 'CZ' },\n { code: 'HUF', name: 'Hungarian Forint', symbol: 'Ft', flag: 'HU' },\n { code: 'ILS', name: 'Israeli Shekel', symbol: '₪', flag: 'IL' },\n { code: 'CLP', name: 'Chilean Peso', symbol: '$', flag: 'CL' },\n { code: 'COP', name: 'Colombian Peso', symbol: '$', flag: 'CO' },\n { code: 'PEN', name: 'Peruvian Sol', symbol: 'S/', flag: 'PE' },\n { code: 'ARS', name: 'Argentine Peso', symbol: '$', flag: 'AR' },\n { code: 'VND', name: 'Vietnamese Dong', symbol: '₫', flag: 'VN' },\n { code: 'EGP', name: 'Egyptian Pound', symbol: 'E£', flag: 'EG' },\n { code: 'NGN', name: 'Nigerian Naira', symbol: '₦', flag: 'NG' },\n { code: 'KES', name: 'Kenyan Shilling', symbol: 'KSh', flag: 'KE' },\n { code: 'PKR', name: 'Pakistani Rupee', symbol: '₨', flag: 'PK' },\n { code: 'BDT', name: 'Bangladeshi Taka', symbol: '৳', flag: 'BD' },\n { code: 'LKR', name: 'Sri Lankan Rupee', symbol: 'Rs', flag: 'LK' },\n { code: 'RON', name: 'Romanian Leu', symbol: 'lei', flag: 'RO' },\n { code: 'BGN', name: 'Bulgarian Lev', symbol: 'лв', flag: 'BG' },\n { code: 'HRK', name: 'Croatian Kuna', symbol: 'kn', flag: 'HR' },\n { code: 'UAH', name: 'Ukrainian Hryvnia', symbol: '₴', flag: 'UA' },\n { code: 'TRY', name: 'Turkish Lira', symbol: '₺', flag: 'TR' },\n { code: 'RUB', name: 'Russian Ruble', symbol: '₽', flag: 'RU' },\n { code: 'QAR', name: 'Qatari Riyal', symbol: 'ر.ق', flag: 'QA' },\n { code: 'KWD', name: 'Kuwaiti Dinar', symbol: 'د.ك', flag: 'KW' },\n { code: 'BHD', name: 'Bahraini Dinar', symbol: '.د.ب', flag: 'BH' },\n { code: 'OMR', name: 'Omani Rial', symbol: 'ر.ع.', flag: 'OM' },\n];\n\n/**\n * Convert country/region code to flag emoji\n */\nfunction getFlagEmoji(countryCode: string): string {\n if (countryCode === 'EU') return '🇪🇺';\n const codePoints = countryCode\n .toUpperCase()\n .split('')\n .map((char) => 127397 + char.charCodeAt(0));\n return String.fromCodePoint(...codePoints);\n}\n\nexport const CreateBillingAccountModal: FC<CreateBillingAccountModalProps> = ({\n isOpen,\n onClose,\n onSubmit,\n isSubmitting = false,\n error = null,\n}) => {\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 [formData, setFormData] = useState<FormData>({\n name: '',\n email: '',\n billingEmail: '',\n currency: 'USD',\n taxId: '',\n // Address fields\n country: '',\n line1: '',\n line2: '',\n city: '',\n state: '',\n postalCode: '',\n });\n const [validationErrors, setValidationErrors] = useState<Record<string, string>>({});\n const [currencyDropdownOpen, setCurrencyDropdownOpen] = useState(false);\n const [currencySearch, setCurrencySearch] = useState('');\n const modalRef = useRef<HTMLDivElement>(null);\n const firstInputRef = useRef<HTMLInputElement>(null);\n const currencyDropdownRef = useRef<HTMLDivElement>(null);\n const currencySearchInputRef = useRef<HTMLInputElement>(null);\n\n // Filter currencies by search query\n const filteredCurrencies = useMemo(() => {\n if (!currencySearch.trim()) return CURRENCY_OPTIONS;\n const query = currencySearch.toLowerCase();\n return CURRENCY_OPTIONS.filter(\n (c) =>\n c.code.toLowerCase().includes(query) ||\n c.name.toLowerCase().includes(query) ||\n c.symbol.includes(query)\n );\n }, [currencySearch]);\n\n // Get selected currency details\n const selectedCurrencyDetails = useMemo(() => {\n return CURRENCY_OPTIONS.find((c) => c.code === formData.currency) || CURRENCY_OPTIONS[0];\n }, [formData.currency]);\n\n // Reset form when modal opens\n useEffect(() => {\n if (isOpen) {\n setFormData({\n name: '',\n email: '',\n billingEmail: '',\n currency: 'USD',\n taxId: '',\n // Address fields\n country: '',\n line1: '',\n line2: '',\n city: '',\n state: '',\n postalCode: '',\n });\n setValidationErrors({});\n setCurrencyDropdownOpen(false);\n setCurrencySearch('');\n const focusTimer = setTimeout(() => firstInputRef.current?.focus(), 100);\n return () => clearTimeout(focusTimer);\n }\n return undefined;\n }, [isOpen]);\n\n // Close currency dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n currencyDropdownRef.current &&\n !currencyDropdownRef.current.contains(event.target as Node)\n ) {\n setCurrencyDropdownOpen(false);\n setCurrencySearch('');\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n // Focus search input when currency dropdown opens\n useEffect(() => {\n if (currencyDropdownOpen && currencySearchInputRef.current) {\n currencySearchInputRef.current.focus();\n }\n }, [currencyDropdownOpen]);\n\n // Handle escape key\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen && !isSubmitting) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, isSubmitting, onClose]);\n\n // Trap focus within modal\n useEffect(() => {\n if (!isOpen) return;\n\n const modal = modalRef.current;\n if (!modal) return;\n\n const focusableElements = modal.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;\n\n const handleTabKey = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n\n if (e.shiftKey) {\n if (document.activeElement === firstElement) {\n e.preventDefault();\n lastElement.focus();\n }\n } else {\n if (document.activeElement === lastElement) {\n e.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n modal.addEventListener('keydown', handleTabKey);\n return () => modal.removeEventListener('keydown', handleTabKey);\n }, [isOpen]);\n\n const validateForm = useCallback(() => {\n const errors: Record<string, string> = {};\n\n if (!formData.name.trim()) {\n errors.name = 'Account name is required';\n }\n\n if (!formData.email.trim()) {\n errors.email = 'Email is required';\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\n errors.email = 'Please enter a valid email address';\n }\n\n if (formData.billingEmail && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.billingEmail)) {\n errors.billingEmail = 'Please enter a valid email address';\n }\n\n // Address validation (required for proper tax calculation)\n if (!formData.country) {\n errors.country = 'Country is required';\n }\n\n if (!formData.line1.trim()) {\n errors.line1 = 'Address line 1 is required';\n }\n\n if (!formData.city.trim()) {\n errors.city = 'City is required';\n }\n\n // State is required for India (for IGST vs CGST+SGST determination)\n if (formData.country === 'IN' && !formData.state) {\n errors.state = 'State is required for India';\n }\n\n if (!formData.postalCode.trim()) {\n errors.postalCode = 'Postal code is required';\n }\n\n setValidationErrors(errors);\n return Object.keys(errors).length === 0;\n }, [formData]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!validateForm()) return;\n\n const input: CreateBillingAccountInput = {\n name: formData.name.trim(),\n email: formData.email.trim(),\n currency: formData.currency,\n };\n\n if (formData.billingEmail?.trim()) {\n input.billingEmail = formData.billingEmail.trim();\n }\n if (formData.taxId?.trim()) {\n input.taxId = formData.taxId.trim();\n }\n\n // Build address data (without billingAccountId - will be added by parent)\n const address: Omit<SetBillingAddressInput, 'billingAccountId'> = {\n country: formData.country,\n line1: formData.line1.trim(),\n city: formData.city.trim(),\n postalCode: formData.postalCode.trim(),\n };\n\n if (formData.line2?.trim()) {\n address.line2 = formData.line2.trim();\n }\n if (formData.state) {\n address.state = formData.state;\n }\n\n await onSubmit(input, address);\n };\n\n const handleChange = (field: keyof FormData, value: string) => {\n setFormData((prev) => {\n const updated = { ...prev, [field]: value };\n // Auto-set currency to INR when India is selected\n if (field === 'country' && value === 'IN' && prev.currency !== 'INR') {\n updated.currency = 'INR';\n }\n // Clear state when country changes (to avoid invalid state for new country)\n if (field === 'country' && value !== prev.country) {\n updated.state = '';\n }\n return updated;\n });\n // Clear validation error when user types\n if (validationErrors[field]) {\n setValidationErrors((prev) => {\n const next = { ...prev };\n delete next[field];\n return next;\n });\n }\n };\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"modal-title\"\n >\n {/* Backdrop */}\n <div\n className=\"absolute inset-0 bg-bg-overlay backdrop-blur-sm\"\n onClick={!isSubmitting ? onClose : undefined}\n aria-hidden=\"true\"\n />\n\n {/* Modal */}\n <div\n ref={modalRef}\n className=\"relative w-full max-w-2xl mx-4 bg-bg-surface border border-border-seam rounded-card shadow-[var(--shadow-elevation-4)] max-h-[90vh] flex flex-col overflow-hidden\"\n >\n {/* Header */}\n <header className=\"flex items-center justify-between p-4 border-b border-border-subtle shrink-0\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <Building2 className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h2 id=\"modal-title\" className=\"text-lg font-semibold text-text-primary\">\n Create Billing Account\n </h2>\n <p className=\"text-sm text-text-secondary\">\n Set up a new billing account for your organization\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isSubmitting}\n className=\"p-2 rounded-button hover:bg-bg-sunken text-text-secondary hover:text-text-primary transition-colors disabled:opacity-50\"\n aria-label=\"Close modal\"\n >\n <X className=\"size-5\" />\n </button>\n </header>\n\n {/* Form - Scrollable content area */}\n <form onSubmit={handleSubmit} className=\"p-4 space-y-4 overflow-y-auto flex-1\">\n {/* Error Message */}\n {error && (\n <div className=\"flex items-center gap-2 p-3 rounded-lg bg-status-error-bg-subtle border border-status-error-border text-status-error-text\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <p className=\"text-sm\">{error}</p>\n </div>\n )}\n\n {/* Account Name */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"name\" className=\"block text-sm font-medium text-text-primary\">\n Account Name <span className=\"text-status-error-text\">*</span>\n </label>\n <div className=\"relative\">\n <Building2 className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n ref={firstInputRef}\n type=\"text\"\n id=\"name\"\n value={formData.name}\n onChange={(e) => handleChange('name', e.target.value)}\n className={`\n w-full pl-[3.25rem] pr-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.name ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"e.g., Acme Corporation\"\n disabled={isSubmitting}\n />\n </div>\n {validationErrors.name && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.name}</p>\n )}\n </div>\n\n {/* Email Row - 2 columns on desktop */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {/* Email */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"email\" className=\"block text-sm font-medium text-text-primary\">\n Email <span className=\"text-status-error-text\">*</span>\n </label>\n <div className=\"relative\">\n <Mail className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n type=\"email\"\n id=\"email\"\n value={formData.email}\n onChange={(e) => handleChange('email', e.target.value)}\n className={`\n w-full pl-[3.25rem] pr-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.email ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"contact@company.com\"\n disabled={isSubmitting}\n />\n </div>\n {validationErrors.email && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.email}</p>\n )}\n </div>\n\n {/* Billing Email */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"billingEmail\" className=\"block text-sm font-medium text-text-primary\">\n Billing Email <span className=\"text-text-secondary text-xs\">(optional)</span>\n </label>\n <div className=\"relative\">\n <Mail className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n type=\"email\"\n id=\"billingEmail\"\n value={formData.billingEmail || ''}\n onChange={(e) => handleChange('billingEmail', e.target.value)}\n className={`\n w-full pl-[3.25rem] pr-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.billingEmail ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"billing@company.com\"\n disabled={isSubmitting}\n />\n </div>\n {validationErrors.billingEmail && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.billingEmail}</p>\n )}\n </div>\n </div>\n\n {/* Billing Address Section */}\n <div className=\"pt-3 border-t border-border-subtle\">\n <h3 className=\"text-sm font-medium text-text-primary mb-3 flex items-center gap-2\">\n <MapPin className=\"size-4 text-text-secondary\" />\n Billing Address\n </h3>\n\n {/* Country + Address Line 1 - 2 columns on desktop */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3 mb-3\">\n {/* Country */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"country\" className=\"block text-sm font-medium text-text-primary\">\n Country <span className=\"text-status-error-text\">*</span>\n </label>\n <select\n id=\"country\"\n value={formData.country}\n onChange={(e) => handleChange('country', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.country ? 'border-status-error-border' : 'border-border-default'}\n `}\n disabled={isSubmitting}\n >\n <option value=\"\">\n {tr('billing.overview.selectCountry', 'Select a country')}\n </option>\n {COUNTRIES.map((c) => (\n <option key={c.code} value={c.code}>\n {c.name}\n </option>\n ))}\n </select>\n {validationErrors.country && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.country}</p>\n )}\n </div>\n\n {/* Address Line 1 */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"line1\" className=\"block text-sm font-medium text-text-primary\">\n Address Line 1 <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"line1\"\n value={formData.line1}\n onChange={(e) => handleChange('line1', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.line1 ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"Street address, P.O. box\"\n disabled={isSubmitting}\n />\n {validationErrors.line1 && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.line1}</p>\n )}\n </div>\n </div>\n\n {/* Address Line 2 */}\n <div className=\"space-y-1.5 mb-3\">\n <label htmlFor=\"line2\" className=\"block text-sm font-medium text-text-primary\">\n Address Line 2 <span className=\"text-text-secondary text-xs\">(optional)</span>\n </label>\n <input\n type=\"text\"\n id=\"line2\"\n value={formData.line2}\n onChange={(e) => handleChange('line2', e.target.value)}\n className=\"w-full px-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder=\"Apartment, suite, unit, building, floor\"\n disabled={isSubmitting}\n />\n </div>\n\n {/* City + State + Postal Code Row - 3 columns on desktop */}\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-3 mb-3\">\n {/* City */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"city\" className=\"block text-sm font-medium text-text-primary\">\n City <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"city\"\n value={formData.city}\n onChange={(e) => handleChange('city', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.city ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"City\"\n disabled={isSubmitting}\n />\n {validationErrors.city && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.city}</p>\n )}\n </div>\n\n {/* State - Dropdown for India, text input for others */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"state\" className=\"block text-sm font-medium text-text-primary\">\n State{' '}\n {formData.country === 'IN' && <span className=\"text-status-error-text\">*</span>}\n </label>\n {formData.country === 'IN' ? (\n <select\n id=\"state\"\n value={formData.state}\n onChange={(e) => handleChange('state', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.state ? 'border-status-error-border' : 'border-border-default'}\n `}\n disabled={isSubmitting}\n >\n <option value=\"\">Select state</option>\n {INDIAN_STATES.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n id=\"state\"\n value={formData.state}\n onChange={(e) => handleChange('state', e.target.value)}\n className=\"w-full px-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder=\"State/Province\"\n disabled={isSubmitting}\n />\n )}\n {validationErrors.state && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.state}</p>\n )}\n </div>\n\n {/* Postal Code */}\n <div className=\"space-y-1.5 col-span-2 sm:col-span-1\">\n <label htmlFor=\"postalCode\" className=\"block text-sm font-medium text-text-primary\">\n Postal Code <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"postalCode\"\n value={formData.postalCode}\n onChange={(e) => handleChange('postalCode', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.postalCode ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder={formData.country === 'IN' ? '600001' : 'ZIP/Postal code'}\n disabled={isSubmitting}\n />\n {validationErrors.postalCode && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.postalCode}</p>\n )}\n </div>\n </div>\n </div>\n\n {/* Currency & Tax ID - 2 columns on desktop */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 pt-3 border-t border-border-subtle\">\n {/* Currency - Searchable Dropdown */}\n <div className=\"space-y-1.5\">\n <label className=\"block text-sm font-medium text-text-primary\">\n {tr('billing.overview.currency', 'Currency')}\n </label>\n <div className=\"relative\" ref={currencyDropdownRef}>\n {/* Dropdown trigger */}\n <button\n type=\"button\"\n onClick={() => !isSubmitting && setCurrencyDropdownOpen(!currencyDropdownOpen)}\n disabled={isSubmitting}\n className={`\n w-full flex items-center justify-between gap-2 px-3 py-2 rounded-lg border\n transition-all duration-200 text-left\n disabled:opacity-50 disabled:cursor-not-allowed\n ${\n currencyDropdownOpen\n ? 'border-border-strong ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-default hover:border-border-strong'\n }\n `}\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"text-base\">{getFlagEmoji(selectedCurrencyDetails.flag)}</span>\n <span className=\"font-medium text-text-primary\">\n {selectedCurrencyDetails.code}\n </span>\n <span className=\"text-sm text-text-secondary\">\n {selectedCurrencyDetails.symbol} · {selectedCurrencyDetails.name}\n </span>\n </div>\n <ChevronDown\n className={`size-4 text-text-secondary transition-transform ${currencyDropdownOpen ? 'rotate-180' : ''}`}\n />\n </button>\n\n {/* Dropdown menu - Opens UPWARD to avoid form overflow clipping */}\n {currencyDropdownOpen && (\n <div\n className=\"absolute z-50 w-full bottom-full mb-1 bg-bg-elevated border border-border-seam rounded-card shadow-elevation-3 overflow-hidden\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {/* Currency list - at top when opening upward */}\n <div className=\"max-h-48 overflow-y-auto\">\n {filteredCurrencies.length === 0 ? (\n <div className=\"px-3 py-4 text-sm text-text-secondary text-center\">\n No currencies found\n </div>\n ) : (\n filteredCurrencies.map((currency) => {\n const isSelected = currency.code === formData.currency;\n return (\n <button\n key={currency.code}\n type=\"button\"\n onClick={() => {\n handleChange('currency', currency.code);\n setCurrencyDropdownOpen(false);\n setCurrencySearch('');\n }}\n className={`\n w-full flex items-center gap-3 px-3 py-2 text-left\n transition-colors\n ${\n isSelected\n ? 'bg-[var(--color-accent-soft)] text-text-primary'\n : 'hover:bg-bg-sunken text-text-primary'\n }\n `}\n >\n <span className=\"text-base shrink-0\">\n {getFlagEmoji(currency.flag)}\n </span>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{currency.code}</span>\n <span className=\"text-xs text-text-secondary\">\n {currency.symbol}\n </span>\n </div>\n <p className=\"text-xs text-text-secondary truncate\">\n {currency.name}\n </p>\n </div>\n {isSelected && <Check className=\"size-4 text-text-link shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n\n {/* Search input - at bottom when opening upward */}\n <div className=\"p-2 border-t border-border-subtle\">\n <div className=\"relative\">\n <Search className=\"absolute left-2.5 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n ref={currencySearchInputRef}\n type=\"text\"\n placeholder=\"Search currency...\"\n value={currencySearch}\n onChange={(e) => setCurrencySearch(e.target.value)}\n onMouseDown={(e) => e.stopPropagation()}\n className=\"w-full pl-8 pr-3 py-2 text-sm bg-bg-surface border border-border-subtle rounded-button focus:outline-none focus:ring-1 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Tax ID */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"taxId\" className=\"block text-sm font-medium text-text-primary\">\n Tax ID / VAT Number <span className=\"text-text-secondary text-xs\">(optional)</span>\n </label>\n <div className=\"relative\">\n <FileText className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n type=\"text\"\n id=\"taxId\"\n value={formData.taxId || ''}\n onChange={(e) => handleChange('taxId', e.target.value)}\n className=\"w-full pl-[3.25rem] pr-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder={\n formData.country === 'IN' ? 'e.g., 22AAAAA0000A1Z5' : 'Tax ID / VAT Number'\n }\n disabled={isSubmitting}\n />\n </div>\n </div>\n </div>\n </form>\n\n {/* Footer - Fixed at bottom */}\n <footer className=\"flex items-center justify-end gap-3 p-4 border-t border-border-subtle bg-bg-sunken rounded-b-card shrink-0\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isSubmitting}\n className=\"px-4 py-2 text-sm font-medium text-text-primary border border-border-subtle rounded-button hover:bg-bg-sunken hover:border-border-strong transition-all duration-200 disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={isSubmitting}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-button hover:bg-action-primary-bgHover transition-colors duration-200 disabled:opacity-50\"\n >\n {isSubmitting ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Creating…\n </>\n ) : (\n 'Create Account'\n )}\n </button>\n </footer>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"CreateBillingAccountModal.js","names":[],"sources":["../../../../../src/billing/modules/dashboard/components/CreateBillingAccountModal.tsx"],"sourcesContent":["/**\n * Create Billing Account Modal Component\n * Modal for creating a new billing account\n */\n\nimport { type FC, useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport {\n X,\n Building2,\n Mail,\n FileText,\n Loader2,\n AlertCircle,\n ChevronDown,\n Search,\n Check,\n MapPin,\n} from 'lucide-react';\nimport type { CreateBillingAccountInput, SetBillingAddressInput } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface CreateBillingAccountModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (\n input: CreateBillingAccountInput,\n address?: Omit<SetBillingAddressInput, 'billingAccountId'>\n ) => Promise<void>;\n isSubmitting?: boolean;\n error?: string | null;\n}\n\n// Form data includes both account and address fields\ninterface FormData extends CreateBillingAccountInput {\n // Address fields\n country: string;\n line1: string;\n line2: string;\n city: string;\n state: string;\n postalCode: string;\n}\n\n// Common countries (sorted by usage)\nconst COUNTRIES = [\n { code: 'IN', name: 'India' },\n { code: 'US', name: 'United States' },\n { code: 'GB', name: 'United Kingdom' },\n { code: 'CA', name: 'Canada' },\n { code: 'AU', name: 'Australia' },\n { code: 'DE', name: 'Germany' },\n { code: 'FR', name: 'France' },\n { code: 'SG', name: 'Singapore' },\n { code: 'AE', name: 'United Arab Emirates' },\n { code: 'JP', name: 'Japan' },\n { code: 'NL', name: 'Netherlands' },\n { code: 'CH', name: 'Switzerland' },\n { code: 'SE', name: 'Sweden' },\n { code: 'NO', name: 'Norway' },\n { code: 'DK', name: 'Denmark' },\n { code: 'NZ', name: 'New Zealand' },\n { code: 'IE', name: 'Ireland' },\n { code: 'IT', name: 'Italy' },\n { code: 'ES', name: 'Spain' },\n { code: 'BR', name: 'Brazil' },\n { code: 'MX', name: 'Mexico' },\n { code: 'ZA', name: 'South Africa' },\n { code: 'KR', name: 'South Korea' },\n { code: 'HK', name: 'Hong Kong' },\n { code: 'MY', name: 'Malaysia' },\n { code: 'ID', name: 'Indonesia' },\n { code: 'PH', name: 'Philippines' },\n { code: 'TH', name: 'Thailand' },\n { code: 'VN', name: 'Vietnam' },\n { code: 'PK', name: 'Pakistan' },\n { code: 'BD', name: 'Bangladesh' },\n { code: 'LK', name: 'Sri Lanka' },\n];\n\n// Indian states and union territories (for GST IGST vs CGST+SGST determination)\nconst INDIAN_STATES = [\n 'Andaman and Nicobar Islands',\n 'Andhra Pradesh',\n 'Arunachal Pradesh',\n 'Assam',\n 'Bihar',\n 'Chandigarh',\n 'Chhattisgarh',\n 'Dadra and Nagar Haveli and Daman and Diu',\n 'Delhi',\n 'Goa',\n 'Gujarat',\n 'Haryana',\n 'Himachal Pradesh',\n 'Jammu and Kashmir',\n 'Jharkhand',\n 'Karnataka',\n 'Kerala',\n 'Ladakh',\n 'Lakshadweep',\n 'Madhya Pradesh',\n 'Maharashtra',\n 'Manipur',\n 'Meghalaya',\n 'Mizoram',\n 'Nagaland',\n 'Odisha',\n 'Puducherry',\n 'Punjab',\n 'Rajasthan',\n 'Sikkim',\n 'Tamil Nadu',\n 'Telangana',\n 'Tripura',\n 'Uttar Pradesh',\n 'Uttarakhand',\n 'West Bengal',\n];\n\ninterface CurrencyOption {\n code: string;\n name: string;\n symbol: string;\n flag: string;\n}\n\n// All major currencies supported (sorted by popularity/usage)\nconst CURRENCY_OPTIONS: CurrencyOption[] = [\n // Most common\n { code: 'USD', name: 'US Dollar', symbol: '$', flag: 'US' },\n { code: 'EUR', name: 'Euro', symbol: '€', flag: 'EU' },\n { code: 'GBP', name: 'British Pound', symbol: '£', flag: 'GB' },\n { code: 'INR', name: 'Indian Rupee', symbol: '₹', flag: 'IN' },\n { code: 'CAD', name: 'Canadian Dollar', symbol: 'C$', flag: 'CA' },\n { code: 'AUD', name: 'Australian Dollar', symbol: 'A$', flag: 'AU' },\n { code: 'JPY', name: 'Japanese Yen', symbol: '¥', flag: 'JP' },\n { code: 'CNY', name: 'Chinese Yuan', symbol: '¥', flag: 'CN' },\n { code: 'CHF', name: 'Swiss Franc', symbol: 'CHF', flag: 'CH' },\n { code: 'SGD', name: 'Singapore Dollar', symbol: 'S$', flag: 'SG' },\n { code: 'HKD', name: 'Hong Kong Dollar', symbol: 'HK$', flag: 'HK' },\n { code: 'NZD', name: 'New Zealand Dollar', symbol: 'NZ$', flag: 'NZ' },\n { code: 'SEK', name: 'Swedish Krona', symbol: 'kr', flag: 'SE' },\n { code: 'NOK', name: 'Norwegian Krone', symbol: 'kr', flag: 'NO' },\n { code: 'DKK', name: 'Danish Krone', symbol: 'kr', flag: 'DK' },\n { code: 'MXN', name: 'Mexican Peso', symbol: '$', flag: 'MX' },\n { code: 'BRL', name: 'Brazilian Real', symbol: 'R$', flag: 'BR' },\n { code: 'KRW', name: 'South Korean Won', symbol: '₩', flag: 'KR' },\n { code: 'ZAR', name: 'South African Rand', symbol: 'R', flag: 'ZA' },\n { code: 'AED', name: 'UAE Dirham', symbol: 'د.إ', flag: 'AE' },\n { code: 'SAR', name: 'Saudi Riyal', symbol: '﷼', flag: 'SA' },\n { code: 'PLN', name: 'Polish Złoty', symbol: 'zł', flag: 'PL' },\n { code: 'THB', name: 'Thai Baht', symbol: '฿', flag: 'TH' },\n { code: 'MYR', name: 'Malaysian Ringgit', symbol: 'RM', flag: 'MY' },\n { code: 'IDR', name: 'Indonesian Rupiah', symbol: 'Rp', flag: 'ID' },\n { code: 'PHP', name: 'Philippine Peso', symbol: '₱', flag: 'PH' },\n { code: 'TWD', name: 'Taiwan Dollar', symbol: 'NT$', flag: 'TW' },\n { code: 'CZK', name: 'Czech Koruna', symbol: 'Kč', flag: 'CZ' },\n { code: 'HUF', name: 'Hungarian Forint', symbol: 'Ft', flag: 'HU' },\n { code: 'ILS', name: 'Israeli Shekel', symbol: '₪', flag: 'IL' },\n { code: 'CLP', name: 'Chilean Peso', symbol: '$', flag: 'CL' },\n { code: 'COP', name: 'Colombian Peso', symbol: '$', flag: 'CO' },\n { code: 'PEN', name: 'Peruvian Sol', symbol: 'S/', flag: 'PE' },\n { code: 'ARS', name: 'Argentine Peso', symbol: '$', flag: 'AR' },\n { code: 'VND', name: 'Vietnamese Dong', symbol: '₫', flag: 'VN' },\n { code: 'EGP', name: 'Egyptian Pound', symbol: 'E£', flag: 'EG' },\n { code: 'NGN', name: 'Nigerian Naira', symbol: '₦', flag: 'NG' },\n { code: 'KES', name: 'Kenyan Shilling', symbol: 'KSh', flag: 'KE' },\n { code: 'PKR', name: 'Pakistani Rupee', symbol: '₨', flag: 'PK' },\n { code: 'BDT', name: 'Bangladeshi Taka', symbol: '৳', flag: 'BD' },\n { code: 'LKR', name: 'Sri Lankan Rupee', symbol: 'Rs', flag: 'LK' },\n { code: 'RON', name: 'Romanian Leu', symbol: 'lei', flag: 'RO' },\n { code: 'BGN', name: 'Bulgarian Lev', symbol: 'лв', flag: 'BG' },\n { code: 'HRK', name: 'Croatian Kuna', symbol: 'kn', flag: 'HR' },\n { code: 'UAH', name: 'Ukrainian Hryvnia', symbol: '₴', flag: 'UA' },\n { code: 'TRY', name: 'Turkish Lira', symbol: '₺', flag: 'TR' },\n { code: 'RUB', name: 'Russian Ruble', symbol: '₽', flag: 'RU' },\n { code: 'QAR', name: 'Qatari Riyal', symbol: 'ر.ق', flag: 'QA' },\n { code: 'KWD', name: 'Kuwaiti Dinar', symbol: 'د.ك', flag: 'KW' },\n { code: 'BHD', name: 'Bahraini Dinar', symbol: '.د.ب', flag: 'BH' },\n { code: 'OMR', name: 'Omani Rial', symbol: 'ر.ع.', flag: 'OM' },\n];\n\n/**\n * Convert country/region code to flag emoji\n */\nfunction getFlagEmoji(countryCode: string): string {\n if (countryCode === 'EU') return '🇪🇺';\n const codePoints = countryCode\n .toUpperCase()\n .split('')\n .map((char) => 127397 + char.charCodeAt(0));\n return String.fromCodePoint(...codePoints);\n}\n\nexport const CreateBillingAccountModal: FC<CreateBillingAccountModalProps> = ({\n isOpen,\n onClose,\n onSubmit,\n isSubmitting = false,\n error = null,\n}) => {\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 [formData, setFormData] = useState<FormData>({\n name: '',\n email: '',\n billingEmail: '',\n currency: 'USD',\n taxId: '',\n // Address fields\n country: '',\n line1: '',\n line2: '',\n city: '',\n state: '',\n postalCode: '',\n });\n const [validationErrors, setValidationErrors] = useState<Record<string, string>>({});\n const [currencyDropdownOpen, setCurrencyDropdownOpen] = useState(false);\n const [currencySearch, setCurrencySearch] = useState('');\n const modalRef = useRef<HTMLDivElement>(null);\n const firstInputRef = useRef<HTMLInputElement>(null);\n const currencyDropdownRef = useRef<HTMLDivElement>(null);\n const currencySearchInputRef = useRef<HTMLInputElement>(null);\n\n // Filter currencies by search query\n const filteredCurrencies = useMemo(() => {\n if (!currencySearch.trim()) return CURRENCY_OPTIONS;\n const query = currencySearch.toLowerCase();\n return CURRENCY_OPTIONS.filter(\n (c) =>\n c.code.toLowerCase().includes(query) ||\n c.name.toLowerCase().includes(query) ||\n c.symbol.includes(query)\n );\n }, [currencySearch]);\n\n // Get selected currency details\n const selectedCurrencyDetails = useMemo(() => {\n return CURRENCY_OPTIONS.find((c) => c.code === formData.currency) || CURRENCY_OPTIONS[0];\n }, [formData.currency]);\n\n // Reset form when modal opens\n useEffect(() => {\n if (isOpen) {\n setFormData({\n name: '',\n email: '',\n billingEmail: '',\n currency: 'USD',\n taxId: '',\n // Address fields\n country: '',\n line1: '',\n line2: '',\n city: '',\n state: '',\n postalCode: '',\n });\n setValidationErrors({});\n setCurrencyDropdownOpen(false);\n setCurrencySearch('');\n const focusTimer = setTimeout(() => firstInputRef.current?.focus(), 100);\n return () => clearTimeout(focusTimer);\n }\n return undefined;\n }, [isOpen]);\n\n // Close currency dropdown when clicking outside\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (\n currencyDropdownRef.current &&\n !currencyDropdownRef.current.contains(event.target as Node)\n ) {\n setCurrencyDropdownOpen(false);\n setCurrencySearch('');\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n // Focus search input when currency dropdown opens\n useEffect(() => {\n if (currencyDropdownOpen && currencySearchInputRef.current) {\n currencySearchInputRef.current.focus();\n }\n }, [currencyDropdownOpen]);\n\n // Handle escape key\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen && !isSubmitting) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isOpen, isSubmitting, onClose]);\n\n // Trap focus within modal\n useEffect(() => {\n if (!isOpen) return;\n\n const modal = modalRef.current;\n if (!modal) return;\n\n const focusableElements = modal.querySelectorAll(\n 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\n );\n const firstElement = focusableElements[0] as HTMLElement;\n const lastElement = focusableElements[focusableElements.length - 1] as HTMLElement;\n\n const handleTabKey = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n\n if (e.shiftKey) {\n if (document.activeElement === firstElement) {\n e.preventDefault();\n lastElement.focus();\n }\n } else {\n if (document.activeElement === lastElement) {\n e.preventDefault();\n firstElement.focus();\n }\n }\n };\n\n modal.addEventListener('keydown', handleTabKey);\n return () => modal.removeEventListener('keydown', handleTabKey);\n }, [isOpen]);\n\n const validateForm = useCallback(() => {\n const errors: Record<string, string> = {};\n\n if (!formData.name.trim()) {\n errors.name = 'Account name is required';\n }\n\n if (!formData.email.trim()) {\n errors.email = 'Email is required';\n } else if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.email)) {\n errors.email = 'Please enter a valid email address';\n }\n\n if (formData.billingEmail && !/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(formData.billingEmail)) {\n errors.billingEmail = 'Please enter a valid email address';\n }\n\n // Address validation (required for proper tax calculation)\n if (!formData.country) {\n errors.country = 'Country is required';\n }\n\n if (!formData.line1.trim()) {\n errors.line1 = 'Address line 1 is required';\n }\n\n if (!formData.city.trim()) {\n errors.city = 'City is required';\n }\n\n // State is required for India (for IGST vs CGST+SGST determination)\n if (formData.country === 'IN' && !formData.state) {\n errors.state = 'State is required for India';\n }\n\n if (!formData.postalCode.trim()) {\n errors.postalCode = 'Postal code is required';\n }\n\n setValidationErrors(errors);\n return Object.keys(errors).length === 0;\n }, [formData]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!validateForm()) return;\n\n const input: CreateBillingAccountInput = {\n name: formData.name.trim(),\n email: formData.email.trim(),\n currency: formData.currency,\n };\n\n if (formData.billingEmail?.trim()) {\n input.billingEmail = formData.billingEmail.trim();\n }\n if (formData.taxId?.trim()) {\n input.taxId = formData.taxId.trim();\n }\n\n // Build address data (without billingAccountId - will be added by parent)\n const address: Omit<SetBillingAddressInput, 'billingAccountId'> = {\n country: formData.country,\n line1: formData.line1.trim(),\n city: formData.city.trim(),\n postalCode: formData.postalCode.trim(),\n };\n\n if (formData.line2?.trim()) {\n address.line2 = formData.line2.trim();\n }\n if (formData.state) {\n address.state = formData.state;\n }\n\n await onSubmit(input, address);\n };\n\n const handleChange = (field: keyof FormData, value: string) => {\n setFormData((prev) => {\n const updated = { ...prev, [field]: value };\n // Auto-set currency to INR when India is selected\n if (field === 'country' && value === 'IN' && prev.currency !== 'INR') {\n updated.currency = 'INR';\n }\n // Clear state when country changes (to avoid invalid state for new country)\n if (field === 'country' && value !== prev.country) {\n updated.state = '';\n }\n return updated;\n });\n // Clear validation error when user types\n if (validationErrors[field]) {\n setValidationErrors((prev) => {\n const next = { ...prev };\n delete next[field];\n return next;\n });\n }\n };\n\n if (!isOpen) return null;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"modal-title\"\n >\n {/* Backdrop */}\n <div\n className=\"absolute inset-0 bg-bg-overlay backdrop-blur-sm\"\n onClick={!isSubmitting ? onClose : undefined}\n aria-hidden=\"true\"\n />\n\n {/* Modal */}\n <div\n ref={modalRef}\n className=\"relative w-full max-w-2xl mx-4 bg-bg-surface border border-border-seam rounded-card shadow-[var(--shadow-elevation-4)] max-h-[90vh] flex flex-col overflow-hidden\"\n >\n {/* Header */}\n <header className=\"flex items-center justify-between p-4 border-b border-border-subtle shrink-0\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 rounded-lg bg-[var(--color-accent-soft)] flex items-center justify-center\">\n <Building2 className=\"size-5 text-text-link\" />\n </div>\n <div>\n <h2 id=\"modal-title\" className=\"text-lg font-semibold text-text-primary\">\n Create Billing Account\n </h2>\n <p className=\"text-sm text-text-secondary\">\n Set up a new billing account for your organization\n </p>\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isSubmitting}\n className=\"p-2 rounded-button hover:bg-bg-sunken text-text-secondary hover:text-text-primary transition-colors disabled:opacity-50\"\n aria-label=\"Close modal\"\n >\n <X className=\"size-5\" />\n </button>\n </header>\n\n {/* Form - Scrollable content area */}\n <form onSubmit={handleSubmit} className=\"p-4 space-y-4 overflow-y-auto flex-1\">\n {/* Error Message */}\n {error && (\n <div className=\"flex items-center gap-2 p-3 rounded-lg bg-status-error-bg-subtle border border-status-error-border text-status-error-text\">\n <AlertCircle className=\"size-4 flex-shrink-0\" />\n <p className=\"text-sm\">{error}</p>\n </div>\n )}\n\n {/* Account Name */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"name\" className=\"block text-sm font-medium text-text-primary\">\n Account Name <span className=\"text-status-error-text\">*</span>\n </label>\n <div className=\"relative\">\n <Building2 className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n ref={firstInputRef}\n type=\"text\"\n id=\"name\"\n value={formData.name}\n onChange={(e) => handleChange('name', e.target.value)}\n className={`\n w-full pl-[3.25rem] pr-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.name ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"e.g., Acme Corporation\"\n disabled={isSubmitting}\n />\n </div>\n {validationErrors.name && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.name}</p>\n )}\n </div>\n\n {/* Email Row - 2 columns on desktop */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4\">\n {/* Email */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"email\" className=\"block text-sm font-medium text-text-primary\">\n Email <span className=\"text-status-error-text\">*</span>\n </label>\n <div className=\"relative\">\n <Mail className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n type=\"email\"\n id=\"email\"\n value={formData.email}\n onChange={(e) => handleChange('email', e.target.value)}\n className={`\n w-full pl-[3.25rem] pr-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.email ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"contact@company.com\"\n disabled={isSubmitting}\n />\n </div>\n {validationErrors.email && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.email}</p>\n )}\n </div>\n\n {/* Billing Email */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"billingEmail\" className=\"block text-sm font-medium text-text-primary\">\n Billing Email <span className=\"text-text-secondary text-xs\">(optional)</span>\n </label>\n <div className=\"relative\">\n <Mail className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n type=\"email\"\n id=\"billingEmail\"\n value={formData.billingEmail || ''}\n onChange={(e) => handleChange('billingEmail', e.target.value)}\n className={`\n w-full pl-[3.25rem] pr-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.billingEmail ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"billing@company.com\"\n disabled={isSubmitting}\n />\n </div>\n {validationErrors.billingEmail && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.billingEmail}</p>\n )}\n </div>\n </div>\n\n {/* Billing Address Section */}\n <div className=\"pt-3 border-t border-border-subtle\">\n <h3 className=\"text-sm font-medium text-text-primary mb-3 flex items-center gap-2\">\n <MapPin className=\"size-4 text-text-secondary\" />\n Billing Address\n </h3>\n\n {/* Country + Address Line 1 - 2 columns on desktop */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-3 mb-3\">\n {/* Country */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"country\" className=\"block text-sm font-medium text-text-primary\">\n Country <span className=\"text-status-error-text\">*</span>\n </label>\n <select\n id=\"country\"\n value={formData.country}\n onChange={(e) => handleChange('country', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.country ? 'border-status-error-border' : 'border-border-default'}\n `}\n disabled={isSubmitting}\n >\n <option value=\"\">\n {tr('billing.overview.selectCountry', 'Select a country')}\n </option>\n {COUNTRIES.map((c) => (\n <option key={c.code} value={c.code}>\n {c.name}\n </option>\n ))}\n </select>\n {validationErrors.country && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.country}</p>\n )}\n </div>\n\n {/* Address Line 1 */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"line1\" className=\"block text-sm font-medium text-text-primary\">\n Address Line 1 <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"line1\"\n value={formData.line1}\n onChange={(e) => handleChange('line1', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.line1 ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"Street address, P.O. box\"\n disabled={isSubmitting}\n />\n {validationErrors.line1 && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.line1}</p>\n )}\n </div>\n </div>\n\n {/* Address Line 2 */}\n <div className=\"space-y-1.5 mb-3\">\n <label htmlFor=\"line2\" className=\"block text-sm font-medium text-text-primary\">\n Address Line 2 <span className=\"text-text-secondary text-xs\">(optional)</span>\n </label>\n <input\n type=\"text\"\n id=\"line2\"\n value={formData.line2}\n onChange={(e) => handleChange('line2', e.target.value)}\n className=\"w-full px-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder=\"Apartment, suite, unit, building, floor\"\n disabled={isSubmitting}\n />\n </div>\n\n {/* City + State + Postal Code Row - 3 columns on desktop */}\n <div className=\"grid grid-cols-2 sm:grid-cols-3 gap-3 mb-3\">\n {/* City */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"city\" className=\"block text-sm font-medium text-text-primary\">\n City <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"city\"\n value={formData.city}\n onChange={(e) => handleChange('city', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.city ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder=\"City\"\n disabled={isSubmitting}\n />\n {validationErrors.city && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.city}</p>\n )}\n </div>\n\n {/* State - Dropdown for India, text input for others */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"state\" className=\"block text-sm font-medium text-text-primary\">\n State{' '}\n {formData.country === 'IN' && <span className=\"text-status-error-text\">*</span>}\n </label>\n {formData.country === 'IN' ? (\n <select\n id=\"state\"\n value={formData.state}\n onChange={(e) => handleChange('state', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.state ? 'border-status-error-border' : 'border-border-default'}\n `}\n disabled={isSubmitting}\n >\n <option value=\"\">Select state</option>\n {INDIAN_STATES.map((s) => (\n <option key={s} value={s}>\n {s}\n </option>\n ))}\n </select>\n ) : (\n <input\n type=\"text\"\n id=\"state\"\n value={formData.state}\n onChange={(e) => handleChange('state', e.target.value)}\n className=\"w-full px-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder=\"State/Province\"\n disabled={isSubmitting}\n />\n )}\n {validationErrors.state && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.state}</p>\n )}\n </div>\n\n {/* Postal Code */}\n <div className=\"space-y-1.5 col-span-2 sm:col-span-1\">\n <label htmlFor=\"postalCode\" className=\"block text-sm font-medium text-text-primary\">\n Postal Code <span className=\"text-status-error-text\">*</span>\n </label>\n <input\n type=\"text\"\n id=\"postalCode\"\n value={formData.postalCode}\n onChange={(e) => handleChange('postalCode', e.target.value)}\n className={`\n w-full px-3 py-2 border rounded-lg bg-bg-surface text-text-primary\n placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\n ${validationErrors.postalCode ? 'border-status-error-border' : 'border-border-default'}\n `}\n placeholder={formData.country === 'IN' ? '600001' : 'ZIP/Postal code'}\n disabled={isSubmitting}\n />\n {validationErrors.postalCode && (\n <p className=\"text-sm text-status-error-text\">{validationErrors.postalCode}</p>\n )}\n </div>\n </div>\n </div>\n\n {/* Currency & Tax ID - 2 columns on desktop */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-4 pt-3 border-t border-border-subtle\">\n {/* Currency - Searchable Dropdown */}\n <div className=\"space-y-1.5\">\n <label className=\"block text-sm font-medium text-text-primary\">\n {tr('billing.overview.currency', 'Currency')}\n </label>\n <div className=\"relative\" ref={currencyDropdownRef}>\n {/* Dropdown trigger */}\n <button\n type=\"button\"\n onClick={() => !isSubmitting && setCurrencyDropdownOpen(!currencyDropdownOpen)}\n disabled={isSubmitting}\n className={`\n w-full flex items-center justify-between gap-2 px-3 py-2 rounded-lg border\n transition-all duration-200 text-left\n disabled:opacity-50 disabled:cursor-not-allowed\n ${\n currencyDropdownOpen\n ? 'border-border-strong ring-1 ring-[var(--color-focus-ring)]'\n : 'border-border-default hover:border-border-strong'\n }\n `}\n >\n <div className=\"flex items-center gap-2\">\n <span className=\"text-base\">{getFlagEmoji(selectedCurrencyDetails.flag)}</span>\n <span className=\"font-medium text-text-primary\">\n {selectedCurrencyDetails.code}\n </span>\n <span className=\"text-sm text-text-secondary\">\n {selectedCurrencyDetails.symbol} · {selectedCurrencyDetails.name}\n </span>\n </div>\n <ChevronDown\n className={`size-4 text-text-secondary transition-transform ${currencyDropdownOpen ? 'rotate-180' : ''}`}\n />\n </button>\n\n {/* Dropdown menu - Opens UPWARD to avoid form overflow clipping */}\n {currencyDropdownOpen && (\n <div\n className=\"absolute z-50 w-full bottom-full mb-1 bg-bg-elevated border border-border-seam rounded-card shadow-elevation-3 overflow-hidden\"\n onMouseDown={(e) => e.stopPropagation()}\n >\n {/* Currency list - at top when opening upward */}\n <div className=\"max-h-48 overflow-y-auto\">\n {filteredCurrencies.length === 0 ? (\n <div className=\"px-3 py-4 text-sm text-text-secondary text-center\">\n No currencies found\n </div>\n ) : (\n filteredCurrencies.map((currency) => {\n const isSelected = currency.code === formData.currency;\n return (\n <button\n key={currency.code}\n type=\"button\"\n onClick={() => {\n handleChange('currency', currency.code);\n setCurrencyDropdownOpen(false);\n setCurrencySearch('');\n }}\n className={`\n w-full flex items-center gap-3 px-3 py-2 text-left\n transition-colors\n ${\n isSelected\n ? 'bg-[var(--color-accent-soft)] text-text-primary'\n : 'hover:bg-bg-sunken text-text-primary'\n }\n `}\n >\n <span className=\"text-base shrink-0\">\n {getFlagEmoji(currency.flag)}\n </span>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium\">{currency.code}</span>\n <span className=\"text-xs text-text-secondary\">\n {currency.symbol}\n </span>\n </div>\n <p className=\"text-xs text-text-secondary truncate\">\n {currency.name}\n </p>\n </div>\n {isSelected && <Check className=\"size-4 text-text-link shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n\n {/* Search input - at bottom when opening upward */}\n <div className=\"p-2 border-t border-border-subtle\">\n <div className=\"relative\">\n <Search className=\"absolute left-2.5 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n ref={currencySearchInputRef}\n type=\"text\"\n placeholder=\"Search currency...\"\n value={currencySearch}\n onChange={(e) => setCurrencySearch(e.target.value)}\n onMouseDown={(e) => e.stopPropagation()}\n className=\"w-full pl-8 pr-3 py-2 text-sm bg-bg-surface border border-border-subtle rounded-button focus:outline-none focus:ring-1 focus:ring-[var(--color-focus-ring)]\"\n />\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n\n {/* Tax ID */}\n <div className=\"space-y-1.5\">\n <label htmlFor=\"taxId\" className=\"block text-sm font-medium text-text-primary\">\n Tax ID / VAT Number <span className=\"text-text-secondary text-xs\">(optional)</span>\n </label>\n <div className=\"relative\">\n <FileText className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-text-secondary\" />\n <input\n type=\"text\"\n id=\"taxId\"\n value={formData.taxId || ''}\n onChange={(e) => handleChange('taxId', e.target.value)}\n className=\"w-full pl-[3.25rem] pr-3 py-2 border border-border-default rounded-input bg-bg-surface text-text-primary placeholder:text-text-placeholder focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] focus:border-border-strong\"\n placeholder={\n formData.country === 'IN' ? 'e.g., 22AAAAA0000A1Z5' : 'Tax ID / VAT Number'\n }\n disabled={isSubmitting}\n />\n </div>\n </div>\n </div>\n </form>\n\n {/* Footer - Fixed at bottom */}\n <footer className=\"flex items-center justify-end gap-3 p-4 border-t border-border-subtle bg-bg-sunken rounded-b-card shrink-0\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={isSubmitting}\n className=\"px-4 py-2 text-sm font-medium text-text-primary border border-border-subtle rounded-button hover:bg-bg-sunken hover:border-border-strong transition-all duration-200 disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={handleSubmit}\n disabled={isSubmitting}\n className=\"inline-flex items-center gap-2 px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-button hover:bg-action-primary-bgHover transition-colors duration-200 disabled:opacity-50\"\n >\n {isSubmitting ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n Creating…\n </>\n ) : (\n 'Create Account'\n )}\n </button>\n </footer>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}