@burdenoff/microfe-billing 2026.526.1 → 2026.528.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/billing/BillingAdminRoutes.js +1 -1
  2. package/dist/billing/BillingAdminRoutes.js.map +1 -1
  3. package/dist/billing/BillingUserRoutes.js +1 -1
  4. package/dist/billing/BillingUserRoutes.js.map +1 -1
  5. package/dist/billing/modules/addons/components/FloatingCartDrawer.js +15 -8
  6. package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
  7. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +13 -6
  8. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  9. package/dist/billing/modules/addons/pages/AddonCreatePage.js +1 -1
  10. package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
  11. package/dist/billing/modules/addons/pages/AddonDetailPage.js +8 -4
  12. package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
  13. package/dist/billing/modules/addons/pages/AddonEditPage.js +3 -2
  14. package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
  15. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +44 -23
  16. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  17. package/dist/billing/modules/addons/pages/AddonsListPage.js +60 -31
  18. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  19. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +9 -9
  20. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  21. package/dist/billing/modules/analytics/pages/AnalyticsPage.js +8 -8
  22. package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
  23. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +16 -10
  24. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  25. package/dist/billing/modules/billing/pages/InvoicesListPage.js +24 -16
  26. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  27. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +5 -1
  28. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  29. package/dist/billing/modules/billing/pages/RefundsPage.js +46 -29
  30. package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
  31. package/dist/billing/modules/billing/pages/TransactionsPage.js +34 -22
  32. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  33. package/dist/billing/modules/checkout/components/BillingAccountSelector.js +10 -10
  34. package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
  35. package/dist/billing/modules/checkout/components/CreditsAmountInput.js +3 -3
  36. package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
  37. package/dist/billing/modules/checkout/components/NativeCheckoutView.js +7 -0
  38. package/dist/billing/modules/checkout/components/NativeCheckoutView.js.map +1 -1
  39. package/dist/billing/modules/checkout/components/OrderSummary.js +13 -13
  40. package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
  41. package/dist/billing/modules/checkout/components/PromoCodeInput.js +5 -5
  42. package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
  43. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js +5 -5
  44. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
  45. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js +4 -4
  46. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
  47. package/dist/billing/modules/checkout/components/StripePaymentForm.js +11 -11
  48. package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
  49. package/dist/billing/modules/checkout/components/SubscriptionSelector.js +3 -3
  50. package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
  51. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js +8 -8
  52. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
  53. package/dist/billing/modules/checkout/pages/CheckoutPage.js +61 -52
  54. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  55. package/dist/billing/modules/coupons/pages/CouponDetailPage.js +22 -15
  56. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  57. package/dist/billing/modules/coupons/pages/CouponsListPage.js +30 -21
  58. package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
  59. package/dist/billing/modules/coupons/pages/CreateCouponPage.js +9 -8
  60. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  61. package/dist/billing/modules/coupons/pages/EditCouponPage.js +11 -8
  62. package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
  63. package/dist/billing/modules/credits/pages/AdminCreditsPage.js +1 -1
  64. package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
  65. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +22 -17
  66. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
  67. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +15 -8
  68. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  69. package/dist/billing/modules/credits/pages/CreditsPage.js +17 -11
  70. package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
  71. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js +15 -11
  72. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
  73. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js +21 -17
  74. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
  75. package/dist/billing/modules/dashboard/components/BillingAccountCard.js +14 -11
  76. package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
  77. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js +32 -26
  78. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
  79. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js +14 -10
  80. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
  81. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js +18 -11
  82. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
  83. package/dist/billing/modules/dashboard/pages/OverviewPage.js +44 -32
  84. package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
  85. package/dist/billing/modules/discounts/pages/DiscountsListPage.js +35 -26
  86. package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
  87. package/dist/billing/modules/earnings/pages/EarningsPage.js +15 -15
  88. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  89. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +11 -11
  90. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  91. package/dist/billing/modules/earnings/pages/PayoutsPage.js +5 -5
  92. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  93. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +9 -4
  94. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
  95. package/dist/billing/modules/plans/pages/PlanCreatePage.js +1 -1
  96. package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
  97. package/dist/billing/modules/plans/pages/PlanDetailPage.js +13 -8
  98. package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
  99. package/dist/billing/modules/plans/pages/PlanEditPage.js +3 -2
  100. package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
  101. package/dist/billing/modules/plans/pages/PlansBrowsePage.js +14 -7
  102. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  103. package/dist/billing/modules/plans/pages/PlansListPage.js +23 -9
  104. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  105. package/dist/billing/modules/quota/pages/QuotaPage.js +11 -7
  106. package/dist/billing/modules/quota/pages/QuotaPage.js.map +1 -1
  107. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +3 -3
  108. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
  109. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +6 -2
  110. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
  111. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +5 -4
  112. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
  113. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +26 -12
  114. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  115. package/dist/billing/modules/settings/pages/SettingsPage.js +356 -349
  116. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  117. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +157 -123
  118. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  119. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js +13 -8
  120. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
  121. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +15 -7
  122. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  123. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +30 -20
  124. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  125. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +25 -16
  126. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  127. package/dist/billing/modules/usage/pages/UsagePage.js +50 -34
  128. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  129. package/dist/billing/shared/components/AccessDenied.js +2 -2
  130. package/dist/billing/shared/components/AccessDenied.js.map +1 -1
  131. package/dist/billing/shared/components/ActorIdentity.js +67 -0
  132. package/dist/billing/shared/components/ActorIdentity.js.map +1 -0
  133. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js +6 -2
  134. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
  135. package/dist/billing/shared/components/EmptyState.js +7 -21
  136. package/dist/billing/shared/components/EmptyState.js.map +1 -1
  137. package/dist/billing/shared/components/PageHeader.js +7 -19
  138. package/dist/billing/shared/components/PageHeader.js.map +1 -1
  139. package/dist/billing/shared/components/ServerError.js +5 -4
  140. package/dist/billing/shared/components/ServerError.js.map +1 -1
  141. package/dist/billing/shared/components/index.js +1 -0
  142. package/dist/billing/shared/hooks/index.js +1 -0
  143. package/dist/billing/shared/hooks/useActorProfiles.js +113 -0
  144. package/dist/billing/shared/hooks/useActorProfiles.js.map +1 -0
  145. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"RefundsPage.js","names":[],"sources":["../../../../../src/billing/modules/billing/pages/RefundsPage.tsx"],"sourcesContent":["/**\n * Billing Module - Refunds Page\n * Admin page for managing refund records\n */\n\nimport { useState, useRef, useEffect, useMemo, useCallback, type FC } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport {\n RefreshCw,\n Plus,\n MoreHorizontal,\n Eye,\n Play,\n SkipForward,\n RotateCcw,\n ChevronLeft,\n ChevronRight,\n X,\n Search,\n Filter,\n AlertTriangle,\n CheckCircle,\n Clock,\n XCircle,\n Loader2,\n Ban,\n Download,\n // Calendar - available but not currently used\n} from 'lucide-react';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport {\n useRefunds,\n type RefundRecord,\n type RefundRecordStatus,\n type RefundSource,\n type RefundRecordFilters,\n} from '../hooks';\nimport {\n GetTransactionDocument,\n type GetTransactionQuery,\n} from '../../../../generated/global-operations';\nimport { AccessDenied, PageHeader, EmptyState, ServerError } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst STATUS_CONFIG: Record<\n RefundRecordStatus,\n { label: string; color: string; icon: FC<{ className?: string }> }\n> = {\n PENDING: { label: 'Pending', color: 'yellow', icon: Clock },\n PROCESSING: { label: 'Processing', color: 'blue', icon: Loader2 },\n COMPLETED: { label: 'Completed', color: 'green', icon: CheckCircle },\n FAILED: { label: 'Failed', color: 'red', icon: XCircle },\n SKIPPED: { label: 'Skipped', color: 'gray', icon: Ban },\n};\n\nconst SOURCE_LABELS: Record<RefundSource, string> = {\n MANUAL: 'Manual',\n WEBHOOK_RECOVERY: 'Webhook Recovery',\n SUBSCRIPTION_CANCEL: 'Subscription Cancel',\n DUPLICATE_PAYMENT: 'Duplicate Payment',\n};\n\nconst PROVIDER_OPTIONS = ['stripe', 'razorpay'];\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\nconst getStatusBadgeClasses = (color: string): string => {\n const classes: Record<string, string> = {\n yellow: `${statusTokens.warning.bg} ${statusTokens.warning.text}`,\n blue: `${statusTokens.info.bg} ${statusTokens.info.text}`,\n green: `${statusTokens.success.bg} ${statusTokens.success.text}`,\n red: `${statusTokens.error.bg} ${statusTokens.error.text}`,\n gray: `${statusTokens.neutral.bg} ${statusTokens.neutral.text}`,\n };\n return classes[color] || classes.gray;\n};\n\n// Actions Dropdown\ninterface RefundActionsDropdownProps {\n record: RefundRecord;\n onViewDetails: () => void;\n onProcess: () => void;\n onSkip: () => void;\n onRetry: () => void;\n isProcessing: boolean;\n}\n\nconst RefundActionsDropdown: FC<RefundActionsDropdownProps> = ({\n record,\n onViewDetails,\n onProcess,\n onSkip,\n onRetry,\n isProcessing,\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n const canProcess = record.status === 'PENDING';\n const canSkip = record.status === 'PENDING';\n const canRetry = record.status === 'FAILED';\n\n return (\n <div className=\"relative\" ref={dropdownRef}>\n <button\n onClick={() => setIsOpen(!isOpen)}\n disabled={isProcessing}\n className=\"p-1.5 rounded-md hover:bg-muted/50 transition-colors disabled:opacity-50\"\n aria-label=\"Refund actions\"\n >\n {isProcessing ? (\n <Loader2 className=\"w-4 h-4 animate-spin text-muted-foreground\" />\n ) : (\n <MoreHorizontal className=\"w-4 h-4 text-muted-foreground\" />\n )}\n </button>\n\n {isOpen && (\n <div className=\"absolute right-0 top-full mt-1 z-50 min-w-[160px] bg-popover border border-border rounded-md shadow-lg py-1\">\n <button\n onClick={() => {\n onViewDetails();\n setIsOpen(false);\n }}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-muted/50 transition-colors\"\n >\n <Eye className=\"w-4 h-4\" />\n View Details\n </button>\n\n {canProcess && (\n <button\n onClick={() => {\n onProcess();\n setIsOpen(false);\n }}\n className={`w-full flex items-center gap-2 px-3 py-2 text-sm ${statusTokens.success.text} hover:bg-muted/50 transition-colors`}\n >\n <Play className=\"w-4 h-4\" />\n Process Refund\n </button>\n )}\n\n {canSkip && (\n <button\n onClick={() => {\n onSkip();\n setIsOpen(false);\n }}\n className={`w-full flex items-center gap-2 px-3 py-2 text-sm ${statusTokens.warning.text} hover:bg-muted/50 transition-colors`}\n >\n <SkipForward className=\"w-4 h-4\" />\n Skip Refund\n </button>\n )}\n\n {canRetry && (\n <button\n onClick={() => {\n onRetry();\n setIsOpen(false);\n }}\n className={`w-full flex items-center gap-2 px-3 py-2 text-sm ${statusTokens.info.text} hover:bg-muted/50 transition-colors`}\n >\n <RotateCcw className=\"w-4 h-4\" />\n Retry Refund\n </button>\n )}\n </div>\n )}\n </div>\n );\n};\n\n// Create Refund Modal\ninterface CreateRefundModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (data: CreateRefundFormData) => Promise<void>;\n isSubmitting: boolean;\n}\n\ninterface CreateRefundFormData {\n billingAccountId?: string;\n provider: string;\n gatewayPaymentId: string;\n gatewayOrderId?: string;\n amount: number;\n currency: string;\n purchaseType?: string;\n purchaseDetail?: string;\n reason?: string;\n notes?: string;\n transactionId?: string;\n}\n\ninterface LookedUpTransaction {\n id: string;\n billingAccountId: string;\n amount: number;\n totalAmount: number; // amount + tax (what was actually charged)\n currency: string;\n description: string | null;\n razorpayPaymentId: string | null;\n stripePaymentId: string | null;\n metadata: Record<string, unknown> | null;\n}\n\nconst EMPTY_FORM: CreateRefundFormData = {\n provider: 'stripe',\n gatewayPaymentId: '',\n amount: 0,\n currency: 'USD',\n};\n\nconst CreateRefundModal: FC<CreateRefundModalProps> = ({\n isOpen,\n onClose,\n onSubmit,\n isSubmitting,\n}) => {\n const client = useApolloClient();\n const [transactionId, setTransactionId] = useState('');\n const [lookedUp, setLookedUp] = useState<LookedUpTransaction | null>(null);\n const [lookupError, setLookupError] = useState<string | null>(null);\n const [isLookingUp, setIsLookingUp] = useState(false);\n const [formData, setFormData] = useState<CreateRefundFormData>(EMPTY_FORM);\n\n const reset = () => {\n setTransactionId('');\n setLookedUp(null);\n setLookupError(null);\n setFormData(EMPTY_FORM);\n };\n\n const handleClose = () => {\n reset();\n onClose();\n };\n\n const lookupTransaction = useCallback(\n async (id: string) => {\n const trimmed = id.trim();\n if (!trimmed) return;\n setIsLookingUp(true);\n setLookupError(null);\n setLookedUp(null);\n try {\n const { data } = await client.query<GetTransactionQuery>({\n query: GetTransactionDocument,\n variables: { id: trimmed },\n fetchPolicy: 'network-only',\n });\n const txn = data?.getTransaction ?? null;\n if (!txn) {\n setLookupError('Transaction not found. Check the ID and try again.');\n setFormData(EMPTY_FORM);\n return;\n }\n const meta = txn.metadata as Record<string, unknown> | null;\n const totalAmount = typeof meta?.total === 'number' ? meta.total : txn.amount;\n const lookedUpWithTotal: LookedUpTransaction = {\n id: txn.id,\n billingAccountId: txn.billingAccountId,\n amount: txn.amount,\n totalAmount,\n currency: txn.currency,\n description: txn.description ?? null,\n razorpayPaymentId: txn.razorpayPaymentId ?? null,\n stripePaymentId: txn.stripePaymentId ?? null,\n metadata: txn.metadata ?? null,\n };\n setLookedUp(lookedUpWithTotal);\n const provider = txn.razorpayPaymentId ? 'razorpay' : 'stripe';\n const gatewayPaymentId = txn.razorpayPaymentId ?? txn.stripePaymentId ?? '';\n const purchaseType = (meta?.purchaseType as string) ?? '';\n const purchaseDetail = txn.description ?? '';\n setFormData({\n transactionId: txn.id,\n billingAccountId: txn.billingAccountId,\n provider,\n gatewayPaymentId,\n currency: txn.currency,\n amount: totalAmount,\n purchaseType,\n purchaseDetail,\n reason: '',\n notes: '',\n });\n } catch {\n setLookupError('Failed to look up transaction. Ensure the ID is correct.');\n setFormData(EMPTY_FORM);\n } finally {\n setIsLookingUp(false);\n }\n },\n [client]\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n await onSubmit(formData);\n reset();\n };\n\n if (!isOpen) return null;\n\n const maxAmount = lookedUp?.totalAmount ?? undefined;\n const isAmountExceedingMax = maxAmount !== undefined && formData.amount > maxAmount + 0.01;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-overlay-scrim\" onClick={handleClose} />\n <div className=\"relative bg-background border border-border rounded-lg shadow-xl max-w-lg w-full mx-4 max-h-[90vh] overflow-auto\">\n <div className=\"flex items-center justify-between p-4 border-b border-border\">\n <h2 className=\"text-lg font-semibold\">Create Manual Refund</h2>\n <button\n onClick={handleClose}\n className=\"p-1 rounded-md hover:bg-muted/50 transition-colors\"\n >\n <X className=\"w-5 h-5\" />\n </button>\n </div>\n\n <form onSubmit={handleSubmit} className=\"p-4 space-y-4\">\n {/* Step 1: Transaction ID lookup */}\n <div>\n <label className=\"block text-sm font-medium mb-1\">Transaction ID *</label>\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={transactionId}\n onChange={(e) => {\n setTransactionId(e.target.value);\n setLookedUp(null);\n setLookupError(null);\n }}\n onBlur={() => lookupTransaction(transactionId)}\n className=\"flex-1 px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary\"\n placeholder=\"Paste transaction UUID...\"\n required\n />\n <button\n type=\"button\"\n onClick={() => lookupTransaction(transactionId)}\n disabled={!transactionId.trim() || isLookingUp}\n className=\"px-3 py-2 border border-border rounded-md hover:bg-muted/50 transition-colors disabled:opacity-50 flex items-center gap-1 text-sm\"\n >\n {isLookingUp ? (\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n ) : (\n <Search className=\"w-4 h-4\" />\n )}\n </button>\n </div>\n {lookupError && <p className=\"text-xs text-status-error-text mt-1\">{lookupError}</p>}\n {isLookingUp && (\n <p className=\"text-xs text-muted-foreground mt-1\">Looking up transaction...</p>\n )}\n </div>\n\n {/* Auto-filled fields — shown once transaction is found */}\n {lookedUp && (\n <>\n {/* Transaction summary banner */}\n <div className=\"p-3 bg-status-success-bg-subtle border border-border-subtle rounded-md text-sm space-y-1\">\n <div className=\"flex items-center gap-2 text-status-success-text font-medium\">\n <CheckCircle className=\"w-4 h-4\" />\n Transaction found\n </div>\n <div className=\"text-muted-foreground grid grid-cols-2 gap-x-4 gap-y-0.5 mt-1\">\n <span>\n Account:{' '}\n <span className=\"text-foreground font-mono text-xs\">\n {lookedUp.billingAccountId.slice(0, 16)}…\n </span>\n </span>\n <span>\n Paid:{' '}\n <span className=\"text-foreground\">\n {formatCurrency(lookedUp.totalAmount, lookedUp.currency)}\n </span>\n </span>\n <span>\n Provider:{' '}\n <span className=\"text-foreground capitalize\">{formData.provider}</span>\n </span>\n <span>\n Currency: <span className=\"text-foreground\">{lookedUp.currency}</span>\n </span>\n </div>\n </div>\n\n {/* Read-only auto-filled fields */}\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Provider\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm capitalize\">\n {formData.provider}\n </div>\n </div>\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Currency\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm\">\n {formData.currency}\n </div>\n </div>\n </div>\n\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Gateway Payment ID\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm font-mono truncate\">\n {formData.gatewayPaymentId}\n </div>\n </div>\n\n {formData.purchaseType && (\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Purchase Type\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm\">\n {formData.purchaseType}\n </div>\n </div>\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Purchase Detail\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm truncate\">\n {formData.purchaseDetail || '—'}\n </div>\n </div>\n </div>\n )}\n\n {/* Editable: Amount (capped at transaction amount) */}\n <div>\n <label className=\"block text-sm font-medium mb-1\">\n Refund Amount *\n <span className=\"text-xs text-muted-foreground ml-1\">\n (max {formatCurrency(maxAmount!, formData.currency)})\n </span>\n </label>\n <input\n type=\"number\"\n step=\"0.01\"\n min=\"0.01\"\n max={maxAmount}\n value={formData.amount}\n onChange={(e) =>\n setFormData({ ...formData, amount: parseFloat(e.target.value) || 0 })\n }\n className={`w-full px-3 py-2 border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary ${\n isAmountExceedingMax ? 'border-status-error-text' : 'border-border'\n }`}\n required\n />\n {isAmountExceedingMax && (\n <p className=\"text-xs text-status-error-text mt-1\">\n Amount cannot exceed the original payment of{' '}\n {formatCurrency(maxAmount!, formData.currency)}\n </p>\n )}\n </div>\n\n {/* Editable: Reason & Notes */}\n <div>\n <label className=\"block text-sm font-medium mb-1\">Reason</label>\n <input\n type=\"text\"\n value={formData.reason || ''}\n onChange={(e) => setFormData({ ...formData, reason: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary\"\n placeholder=\"Reason for refund\"\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-1\">Notes</label>\n <textarea\n value={formData.notes || ''}\n onChange={(e) => setFormData({ ...formData, notes: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary resize-none\"\n rows={2}\n placeholder=\"Internal notes\"\n />\n </div>\n </>\n )}\n\n <div className=\"flex gap-2 pt-2\">\n <button\n type=\"button\"\n onClick={handleClose}\n className=\"flex-1 py-2 px-4 border border-border rounded-md hover:bg-muted/50 transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={\n isSubmitting ||\n !lookedUp ||\n !formData.gatewayPaymentId ||\n formData.amount <= 0 ||\n isAmountExceedingMax\n }\n className=\"flex-1 py-2 px-4 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2\"\n >\n {isSubmitting && <Loader2 className=\"w-4 h-4 animate-spin\" />}\n Create Refund\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n};\n\n// Skip Refund Modal\ninterface SkipRefundModalProps {\n isOpen: boolean;\n record: RefundRecord | null;\n onClose: () => void;\n onSubmit: (reason: string) => Promise<void>;\n isSubmitting: boolean;\n}\n\nconst SkipRefundModal: FC<SkipRefundModalProps> = ({\n isOpen,\n record,\n onClose,\n onSubmit,\n isSubmitting,\n}) => {\n const [reason, setReason] = useState('');\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n await onSubmit(reason);\n setReason('');\n };\n\n if (!isOpen || !record) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-overlay-scrim\" onClick={onClose} />\n <div className=\"relative bg-background border border-border rounded-lg shadow-xl max-w-md w-full mx-4\">\n <div className=\"flex items-center justify-between p-4 border-b border-border\">\n <h2 className=\"text-lg font-semibold\">Skip Refund</h2>\n <button onClick={onClose} className=\"p-1 rounded-md hover:bg-muted/50 transition-colors\">\n <X className=\"w-5 h-5\" />\n </button>\n </div>\n\n <form onSubmit={handleSubmit} className=\"p-4 space-y-4\">\n <div\n className={`p-3 ${statusTokens.warning.bg} border ${statusTokens.warning.border} rounded-md`}\n >\n <div className=\"flex items-start gap-2\">\n <AlertTriangle className={`w-5 h-5 ${statusTokens.warning.icon} mt-0.5`} />\n <div>\n <p className={`text-sm font-medium ${statusTokens.warning.text}`}>\n You are about to skip this refund\n </p>\n <p className={`text-sm ${statusTokens.warning.text} mt-1`}>\n Amount: {formatCurrency(record.amount, record.currency)}\n </p>\n </div>\n </div>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-1\">Reason for skipping *</label>\n <textarea\n value={reason}\n onChange={(e) => setReason(e.target.value)}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background resize-none\"\n rows={3}\n placeholder=\"Explain why this refund is being skipped...\"\n required\n />\n </div>\n\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"flex-1 py-2 px-4 border border-border rounded-md hover:bg-muted/50 transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={isSubmitting || !reason.trim()}\n className={`flex-1 py-2 px-4 ${statusTokens.warning.dot} text-primary-foreground rounded-md hover:opacity-90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2`}\n >\n {isSubmitting && <Loader2 className=\"w-4 h-4 animate-spin\" />}\n Skip Refund\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n};\n\n// Refund Details Modal\ninterface RefundDetailsModalProps {\n record: RefundRecord | null;\n onClose: () => void;\n}\n\nconst RefundDetailsModal: FC<RefundDetailsModalProps> = ({ record, onClose }) => {\n if (!record) return null;\n\n const StatusIcon = STATUS_CONFIG[record.status].icon;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-overlay-scrim\" onClick={onClose} />\n <div className=\"relative bg-background border border-border rounded-lg shadow-xl max-w-lg w-full mx-4 max-h-[90vh] overflow-auto\">\n <div className=\"flex items-center justify-between p-4 border-b border-border\">\n <h2 className=\"text-lg font-semibold\">Refund Details</h2>\n <button onClick={onClose} className=\"p-1 rounded-md hover:bg-muted/50 transition-colors\">\n <X className=\"w-5 h-5\" />\n </button>\n </div>\n\n <div className=\"p-4 space-y-4\">\n {/* Status Banner */}\n <div\n className={`flex items-center gap-2 p-3 rounded-md ${getStatusBadgeClasses(STATUS_CONFIG[record.status].color)}`}\n >\n <StatusIcon className=\"w-5 h-5\" />\n <span className=\"font-medium\">{STATUS_CONFIG[record.status].label}</span>\n </div>\n\n {/* Basic Info */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Refund ID</p>\n <p className=\"text-sm font-mono break-all\">{record.id}</p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Source</p>\n <p className=\"text-sm\">{SOURCE_LABELS[record.source]}</p>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Amount</p>\n <p className=\"text-lg font-semibold\">\n {formatCurrency(record.amount, record.currency)}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Provider</p>\n <p className=\"text-sm capitalize\">{record.provider}</p>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Gateway Payment ID</p>\n <p className=\"text-sm font-mono break-all\">{record.gatewayPaymentId}</p>\n </div>\n {record.gatewayOrderId && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Gateway Order ID</p>\n <p className=\"text-sm font-mono break-all\">{record.gatewayOrderId}</p>\n </div>\n )}\n </div>\n\n {record.gatewayRefundId && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Gateway Refund ID</p>\n <p className=\"text-sm font-mono break-all\">{record.gatewayRefundId}</p>\n </div>\n )}\n\n {(record.purchaseType || record.purchaseDetail) && (\n <div className=\"grid grid-cols-2 gap-4\">\n {record.purchaseType && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Purchase Type</p>\n <p className=\"text-sm\">{record.purchaseType}</p>\n </div>\n )}\n {record.purchaseDetail && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Purchase Detail</p>\n <p className=\"text-sm\">{record.purchaseDetail}</p>\n </div>\n )}\n </div>\n )}\n\n {record.reason && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Reason</p>\n <p className=\"text-sm\">{record.reason}</p>\n </div>\n )}\n\n {record.notes && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Notes</p>\n <p className=\"text-sm\">{record.notes}</p>\n </div>\n )}\n\n {record.errorMessage && (\n <div\n className={`p-3 ${statusTokens.error.bg} border ${statusTokens.error.border} rounded-md`}\n >\n <p className={`text-xs ${statusTokens.error.text} mb-1`}>Error Message</p>\n <p className={`text-sm ${statusTokens.error.text}`}>{record.errorMessage}</p>\n </div>\n )}\n\n <div className=\"grid grid-cols-2 gap-4 pt-2 border-t border-border\">\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Created At</p>\n <p className=\"text-sm\">{formatDateTime(record.createdAt)}</p>\n </div>\n {record.processedAt && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Processed At</p>\n <p className=\"text-sm\">{formatDateTime(record.processedAt)}</p>\n </div>\n )}\n </div>\n\n {record.retryCount > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Retry Count</p>\n <p className=\"text-sm\">{record.retryCount}</p>\n </div>\n )}\n </div>\n\n <div className=\"p-4 border-t border-border\">\n <button\n onClick={onClose}\n className=\"w-full py-2 px-4 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors\"\n >\n Close\n </button>\n </div>\n </div>\n </div>\n );\n};\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\ntype TabStatus = 'PENDING' | 'COMPLETED' | 'FAILED' | 'ALL';\n\nconst TAB_CONFIG: Record<TabStatus, { label: string; status?: RefundRecordStatus }> = {\n PENDING: { label: 'Pending', status: 'PENDING' },\n COMPLETED: { label: 'Completed', status: 'COMPLETED' },\n FAILED: { label: 'Failed', status: 'FAILED' },\n ALL: { label: 'All', status: undefined },\n};\n\nexport const RefundsPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const permissions = useBillingPermissions();\n\n // State\n const [activeTab, setActiveTab] = useState<TabStatus>('PENDING');\n const [searchQuery, setSearchQuery] = useState('');\n const [filters, setFilters] = useState<RefundRecordFilters>({});\n const [showFilters, setShowFilters] = useState(false);\n const [selectedRecord, setSelectedRecord] = useState<RefundRecord | null>(null);\n const [showCreateModal, setShowCreateModal] = useState(false);\n const [showSkipModal, setShowSkipModal] = useState(false);\n const [recordToSkip, setRecordToSkip] = useState<RefundRecord | null>(null);\n const [actionLoadingId, setActionLoadingId] = useState<string | null>(null);\n\n // Build filters based on active tab - memoized to prevent infinite re-render loop\n // (useRefundRecords has a useEffect on options.filters, so a new object every render would cause\n // infinite updates if tabFilters were not stable)\n const tabFilters = useMemo<RefundRecordFilters>(\n () => ({\n ...filters,\n status: TAB_CONFIG[activeTab].status,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- filters is an object; spread ensures correct deps\n [\n activeTab,\n filters.source,\n filters.provider,\n filters.billingAccountId,\n filters.fromDate,\n filters.toDate,\n ]\n );\n\n // Data hooks - filters automatically applied based on active tab\n const {\n records,\n stats,\n pagination,\n isLoading,\n recordsError,\n unprocessedWebhooks,\n refetch,\n goToNextPage,\n goToPreviousPage,\n setFilters: updateFilters,\n createRefundRecord,\n processRefund,\n skipRefund,\n retryRefund,\n createRefundRecordsFromFailedWebhooks,\n isCreating,\n isProcessing,\n isCreatingFromWebhooks,\n } = useRefunds({ filters: tabFilters });\n\n // Permission check\n if (!permissions.canViewPayments) {\n return <AccessDenied message=\"You don't have permission to view refunds.\" />;\n }\n\n // Error handling\n if (recordsError && isServerError(recordsError)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title=\"Server Unavailable\"\n message=\"Unable to load refunds. The server might be down or experiencing issues.\"\n onRetry={() => refetch()}\n showRetry\n />\n </div>\n );\n }\n\n // Handlers\n const handleTabChange = (tab: TabStatus) => {\n setActiveTab(tab);\n // Reset filters when changing tabs\n setFilters({});\n setSearchQuery('');\n };\n\n const handleFilterChange = (key: keyof RefundRecordFilters, value: string | undefined) => {\n // Don't allow status filter changes as tabs control status\n if (key === 'status') return;\n\n const newFilters = { ...filters, [key]: value || undefined };\n setFilters(newFilters);\n updateFilters({ ...newFilters, status: TAB_CONFIG[activeTab].status });\n };\n\n const handleCreateRefund = async (data: CreateRefundFormData) => {\n try {\n await createRefundRecord(data);\n setShowCreateModal(false);\n } catch (error) {\n console.error('Failed to create refund:', error);\n }\n };\n\n const handleProcess = async (record: RefundRecord) => {\n setActionLoadingId(record.id);\n try {\n const result = await processRefund(record.id);\n if (!result.success && result.error) {\n console.error('Refund processing failed:', result.error);\n }\n } catch (error) {\n console.error('Failed to process refund:', error);\n } finally {\n setActionLoadingId(null);\n }\n };\n\n const handleSkip = async (reason: string) => {\n if (!recordToSkip) return;\n try {\n await skipRefund(recordToSkip.id, reason);\n setShowSkipModal(false);\n setRecordToSkip(null);\n } catch (error) {\n console.error('Failed to skip refund:', error);\n }\n };\n\n const handleRetry = async (record: RefundRecord) => {\n setActionLoadingId(record.id);\n try {\n const result = await retryRefund(record.id);\n if (!result.success && result.error) {\n console.error('Refund retry failed:', result.error);\n }\n } catch (error) {\n console.error('Failed to retry refund:', error);\n } finally {\n setActionLoadingId(null);\n }\n };\n\n const handleCreateFromWebhooks = async () => {\n try {\n await createRefundRecordsFromFailedWebhooks();\n } catch (error) {\n console.error('Failed to create refunds from webhooks:', error);\n }\n };\n\n // Filter records by search query (client-side)\n const filteredRecords = searchQuery\n ? records.filter(\n (r) =>\n r.gatewayPaymentId.toLowerCase().includes(searchQuery.toLowerCase()) ||\n r.gatewayOrderId?.toLowerCase().includes(searchQuery.toLowerCase()) ||\n r.reason?.toLowerCase().includes(searchQuery.toLowerCase())\n )\n : records;\n\n if (isLoading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"h-8 w-48 bg-muted animate-pulse rounded\" />\n <div className=\"grid grid-cols-5 gap-4\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"h-24 bg-muted animate-pulse rounded-lg\" />\n ))}\n </div>\n <div className=\"space-y-2\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"h-16 bg-muted animate-pulse rounded\" />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={tr('billing.refunds.title', 'Refund Management')}\n description=\"View and manage refund records\"\n actions={\n <div className=\"flex items-center gap-2\">\n {unprocessedWebhooks.length > 0 && (\n <button\n onClick={handleCreateFromWebhooks}\n disabled={isCreatingFromWebhooks}\n className={`inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md border ${statusTokens.warning.border} ${statusTokens.warning.bg} ${statusTokens.warning.text} hover:opacity-90 transition-colors disabled:opacity-50`}\n >\n {isCreatingFromWebhooks ? (\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n ) : (\n <Download className=\"w-4 h-4\" />\n )}\n Import {unprocessedWebhooks.length} Failed Webhooks\n </button>\n )}\n <button\n onClick={() => refetch()}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md border border-border bg-background hover:bg-muted/50 transition-colors\"\n >\n <RefreshCw className=\"w-4 h-4\" />\n Refresh\n </button>\n <button\n onClick={() => setShowCreateModal(true)}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <Plus className=\"w-4 h-4\" />\n Create Manual Refund\n </button>\n </div>\n }\n />\n\n {/* Tabs Navigation */}\n <div className=\"border-b border-border\">\n <div className=\"flex flex-wrap gap-2 sm:gap-0\">\n {(Object.keys(TAB_CONFIG) as TabStatus[]).map((tab) => {\n const isActive = activeTab === tab;\n const count = stats\n ? tab === 'PENDING'\n ? stats.pending\n : tab === 'COMPLETED'\n ? stats.completed\n : tab === 'FAILED'\n ? stats.failed\n : stats.pending +\n stats.processing +\n stats.completed +\n stats.failed +\n stats.skipped\n : 0;\n\n return (\n <button\n key={tab}\n onClick={() => handleTabChange(tab)}\n className={`flex items-center gap-2 px-4 py-3 text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${\n isActive\n ? 'border-primary text-primary'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:border-border'\n }`}\n >\n {TAB_CONFIG[tab].label}\n {stats && (\n <span\n className={`px-2 py-0.5 text-xs rounded-full ${\n isActive ? 'bg-primary/10 text-primary' : 'bg-muted text-muted-foreground'\n }`}\n >\n {count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col sm:flex-row gap-4\">\n {/* Search */}\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-muted-foreground\" />\n <input\n type=\"text\"\n placeholder=\"Search by payment ID, order ID, or reason...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full pl-[3.25rem] pr-4 py-2 border border-border rounded-md bg-background\"\n />\n </div>\n\n {/* Filter Toggle */}\n <button\n onClick={() => setShowFilters(!showFilters)}\n className={`inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md border transition-colors ${\n showFilters\n ? 'border-primary bg-primary/10 text-primary'\n : 'border-border bg-background hover:bg-muted/50'\n }`}\n >\n <Filter className=\"w-4 h-4\" />\n Filters\n {Object.values(filters).filter(Boolean).length > 0 && (\n <span className=\"px-1.5 py-0.5 text-xs rounded-full bg-primary text-primary-foreground\">\n {Object.values(filters).filter(Boolean).length}\n </span>\n )}\n </button>\n\n {/* Clear Filters */}\n {Object.values(filters).filter(Boolean).length > 0 && (\n <button\n onClick={() => {\n setFilters({});\n updateFilters({});\n }}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md text-muted-foreground hover:text-foreground transition-colors\"\n >\n <X className=\"w-4 h-4\" />\n Clear\n </button>\n )}\n </div>\n\n {/* Expanded Filters */}\n {showFilters && (\n <div className=\"p-4 border border-border rounded-lg bg-muted/30 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n <div>\n <label className=\"block text-sm font-medium mb-1\">Source</label>\n <select\n value={filters.source || ''}\n onChange={(e) => handleFilterChange('source', e.target.value)}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background\"\n >\n <option value=\"\">All Sources</option>\n {Object.entries(SOURCE_LABELS).map(([key, label]) => (\n <option key={key} value={key}>\n {label}\n </option>\n ))}\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-1\">Provider</label>\n <select\n value={filters.provider || ''}\n onChange={(e) => handleFilterChange('provider', e.target.value)}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background\"\n >\n <option value=\"\">All Providers</option>\n {PROVIDER_OPTIONS.map((p) => (\n <option key={p} value={p}>\n {p.charAt(0).toUpperCase() + p.slice(1)}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"sm:col-span-2 lg:col-span-1\">\n <label className=\"block text-sm font-medium mb-1\">Date Range</label>\n <div className=\"flex flex-col sm:flex-row items-start sm:items-center gap-2\">\n <input\n type=\"date\"\n value={filters.fromDate ? filters.fromDate.split('T')[0] : ''}\n onChange={(e) =>\n handleFilterChange(\n 'fromDate',\n e.target.value ? new Date(e.target.value).toISOString() : undefined\n )\n }\n className=\"w-full sm:flex-1 px-2 py-2 border border-border rounded-md bg-background text-sm\"\n />\n <span className=\"text-muted-foreground hidden sm:inline\">-</span>\n <input\n type=\"date\"\n value={filters.toDate ? filters.toDate.split('T')[0] : ''}\n onChange={(e) =>\n handleFilterChange(\n 'toDate',\n e.target.value ? new Date(e.target.value).toISOString() : undefined\n )\n }\n className=\"w-full sm:flex-1 px-2 py-2 border border-border rounded-md bg-background text-sm\"\n />\n </div>\n </div>\n </div>\n )}\n\n {/* Table */}\n {filteredRecords.length === 0 ? (\n <EmptyState\n icon={<RefreshCw className=\"w-6 h-6 text-muted-foreground\" />}\n title=\"No refund records found\"\n description={\n Object.values(filters).filter(Boolean).length > 0\n ? 'Try adjusting your filters.'\n : activeTab === 'PENDING'\n ? 'No pending refunds to process.'\n : 'Refund records will appear here when created.'\n }\n />\n ) : (\n <div className=\"border border-border rounded-lg overflow-hidden\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[400px]\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap\">\n Date\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap\">\n Status\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap hidden sm:table-cell\">\n Source\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap hidden md:table-cell\">\n Provider\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap\">\n Payment ID\n </th>\n <th className=\"text-right text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap\">\n Amount\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap hidden lg:table-cell\">\n Reason\n </th>\n <th className=\"px-2 py-2 w-10\"></th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {filteredRecords.map((record) => {\n const StatusIcon = STATUS_CONFIG[record.status].icon;\n return (\n <tr key={record.id} className=\"hover:bg-muted/30 transition-colors\">\n <td className=\"px-3 py-2 text-sm text-foreground whitespace-nowrap\">\n <div className=\"flex flex-col\">\n <span>{formatDateTime(record.createdAt).split(' ')[0]}</span>\n <span className=\"text-xs text-muted-foreground\">\n {formatDateTime(record.createdAt).split(' ')[1]}\n </span>\n </div>\n </td>\n <td className=\"px-3 py-2 whitespace-nowrap\">\n <span\n className={`inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded ${getStatusBadgeClasses(\n STATUS_CONFIG[record.status].color\n )}`}\n >\n <StatusIcon className=\"w-3 h-3\" />\n <span className=\"hidden sm:inline\">\n {STATUS_CONFIG[record.status].label}\n </span>\n </span>\n </td>\n <td className=\"px-3 py-2 text-sm text-muted-foreground whitespace-nowrap hidden sm:table-cell\">\n {SOURCE_LABELS[record.source]}\n </td>\n <td className=\"px-3 py-2 text-sm text-foreground capitalize whitespace-nowrap hidden md:table-cell\">\n {record.provider}\n </td>\n <td className=\"px-3 py-2 text-sm font-mono text-muted-foreground whitespace-nowrap max-w-[120px] sm:max-w-[200px] truncate\">\n {record.gatewayPaymentId}\n </td>\n <td className=\"px-3 py-2 text-sm text-right font-medium whitespace-nowrap\">\n {formatCurrency(record.amount, record.currency)}\n </td>\n <td className=\"px-3 py-2 text-sm text-muted-foreground max-w-[200px] truncate hidden lg:table-cell\">\n {record.reason || '-'}\n </td>\n <td className=\"px-2 py-2 text-center\">\n <RefundActionsDropdown\n record={record}\n onViewDetails={() => setSelectedRecord(record)}\n onProcess={() => handleProcess(record)}\n onSkip={() => {\n setRecordToSkip(record);\n setShowSkipModal(true);\n }}\n onRetry={() => handleRetry(record)}\n isProcessing={actionLoadingId === record.id}\n />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </div>\n )}\n\n {/* Pagination */}\n {pagination.totalCount > 0 && (\n <div className=\"flex flex-col sm:flex-row items-center justify-between gap-4 border-t border-border pt-4\">\n <p className=\"text-sm text-muted-foreground text-center sm:text-left\">\n Showing {pagination.page * pagination.pageSize + 1} to{' '}\n {Math.min((pagination.page + 1) * pagination.pageSize, pagination.totalCount)} of{' '}\n {pagination.totalCount} refunds\n </p>\n <div className=\"flex items-center gap-2\">\n <button\n onClick={goToPreviousPage}\n disabled={!pagination.hasPrevious}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-md border border-border bg-background hover:bg-muted/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n <ChevronLeft className=\"w-4 h-4\" />\n <span className=\"hidden sm:inline\">Previous</span>\n </button>\n <span className=\"text-sm text-muted-foreground px-2\">\n <span className=\"hidden sm:inline\">Page </span>\n {pagination.page + 1} <span className=\"hidden sm:inline\">of</span>\n <span className=\"sm:hidden\">/</span>{' '}\n {Math.ceil(pagination.totalCount / pagination.pageSize)}\n </span>\n <button\n onClick={goToNextPage}\n disabled={!pagination.hasMore}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-md border border-border bg-background hover:bg-muted/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n <span className=\"hidden sm:inline\">Next</span>\n <ChevronRight className=\"w-4 h-4\" />\n </button>\n </div>\n </div>\n )}\n\n {/* Modals */}\n <CreateRefundModal\n isOpen={showCreateModal}\n onClose={() => setShowCreateModal(false)}\n onSubmit={handleCreateRefund}\n isSubmitting={isCreating}\n />\n\n <SkipRefundModal\n isOpen={showSkipModal}\n record={recordToSkip}\n onClose={() => {\n setShowSkipModal(false);\n setRecordToSkip(null);\n }}\n onSubmit={handleSkip}\n isSubmitting={isProcessing}\n />\n\n <RefundDetailsModal record={selectedRecord} onClose={() => setSelectedRecord(null)} />\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAkDA,IAAM,IAGF;CACF,SAAS;EAAE,OAAO;EAAW,OAAO;EAAU,MAAM;EAAO;CAC3D,YAAY;EAAE,OAAO;EAAc,OAAO;EAAQ,MAAM;EAAS;CACjE,WAAW;EAAE,OAAO;EAAa,OAAO;EAAS,MAAM;EAAa;CACpE,QAAQ;EAAE,OAAO;EAAU,OAAO;EAAO,MAAM;EAAS;CACxD,SAAS;EAAE,OAAO;EAAW,OAAO;EAAQ,MAAM;EAAK;CACxD,EAEK,IAA8C;CAClD,QAAQ;CACR,kBAAkB;CAClB,qBAAqB;CACrB,mBAAmB;CACpB,EAEK,KAAmB,CAAC,UAAU,WAAW,EAMzC,KAAyB,MAA0B;CACvD,IAAM,IAAkC;EACtC,QAAQ,GAAG,EAAa,QAAQ,GAAG,GAAG,EAAa,QAAQ;EAC3D,MAAM,GAAG,EAAa,KAAK,GAAG,GAAG,EAAa,KAAK;EACnD,OAAO,GAAG,EAAa,QAAQ,GAAG,GAAG,EAAa,QAAQ;EAC1D,KAAK,GAAG,EAAa,MAAM,GAAG,GAAG,EAAa,MAAM;EACpD,MAAM,GAAG,EAAa,QAAQ,GAAG,GAAG,EAAa,QAAQ;EAC1D;AACD,QAAO,EAAQ,MAAU,EAAQ;GAa7B,MAAyD,EAC7D,WACA,kBACA,cACA,WACA,YACA,sBACI;CACJ,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAM,EACrC,IAAc,EAAuB,KAAK;AAEhD,SAAgB;EACd,IAAM,KAAsB,MAAsB;AAChD,GAAI,EAAY,WAAW,CAAC,EAAY,QAAQ,SAAS,EAAM,OAAe,IAC5E,EAAU,GAAM;;AAIpB,SADA,SAAS,iBAAiB,aAAa,EAAmB,QAC7C,SAAS,oBAAoB,aAAa,EAAmB;IACzE,EAAE,CAAC;CAEN,IAAM,IAAa,EAAO,WAAW,WAC/B,IAAU,EAAO,WAAW,WAC5B,IAAW,EAAO,WAAW;AAEnC,QACE,kBAAC,OAAD;EAAK,WAAU;EAAW,KAAK;YAA/B,CACE,kBAAC,UAAD;GACE,eAAe,EAAU,CAAC,EAAO;GACjC,UAAU;GACV,WAAU;GACV,cAAW;aAEV,IACC,kBAAC,GAAD,EAAS,WAAU,8CAA+C,CAAA,GAElE,kBAAC,GAAD,EAAgB,WAAU,iCAAkC,CAAA;GAEvD,CAAA,EAER,KACC,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,UAAD;KACE,eAAe;AAEb,MADA,GAAe,EACf,EAAU,GAAM;;KAElB,WAAU;eALZ,CAOE,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA,EAAA,eAEpB;;IAER,KACC,kBAAC,UAAD;KACE,eAAe;AAEb,MADA,GAAW,EACX,EAAU,GAAM;;KAElB,WAAW,oDAAoD,EAAa,QAAQ,KAAK;eAL3F,CAOE,kBAAC,IAAD,EAAM,WAAU,WAAY,CAAA,EAAA,iBAErB;;IAGV,KACC,kBAAC,UAAD;KACE,eAAe;AAEb,MADA,GAAQ,EACR,EAAU,GAAM;;KAElB,WAAW,oDAAoD,EAAa,QAAQ,KAAK;eAL3F,CAOE,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA,EAAA,cAE5B;;IAGV,KACC,kBAAC,UAAD;KACE,eAAe;AAEb,MADA,GAAS,EACT,EAAU,GAAM;;KAElB,WAAW,oDAAoD,EAAa,KAAK,KAAK;eALxF,CAOE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,eAE1B;;IAEP;KAEJ;;GAsCJ,IAAmC;CACvC,UAAU;CACV,kBAAkB;CAClB,QAAQ;CACR,UAAU;CACX,EAEK,MAAiD,EACrD,WACA,YACA,aACA,sBACI;CACJ,IAAM,IAAS,GAAiB,EAC1B,CAAC,GAAe,KAAoB,EAAS,GAAG,EAChD,CAAC,GAAU,KAAe,EAAqC,KAAK,EACpE,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,GAAa,KAAkB,EAAS,GAAM,EAC/C,CAAC,GAAU,KAAe,EAA+B,EAAW,EAEpE,UAAc;AAIlB,EAHA,EAAiB,GAAG,EACpB,EAAY,KAAK,EACjB,EAAe,KAAK,EACpB,EAAY,EAAW;IAGnB,UAAoB;AAExB,EADA,GAAO,EACP,GAAS;IAGL,IAAoB,EACxB,OAAO,MAAe;EACpB,IAAM,IAAU,EAAG,MAAM;AACpB,SAGL;GAFA,EAAe,GAAK,EACpB,EAAe,KAAK,EACpB,EAAY,KAAK;AACjB,OAAI;IACF,IAAM,EAAE,YAAS,MAAM,EAAO,MAA2B;KACvD,OAAO;KACP,WAAW,EAAE,IAAI,GAAS;KAC1B,aAAa;KACd,CAAC,EACI,IAAM,GAAM,kBAAkB;AACpC,QAAI,CAAC,GAAK;AAER,KADA,EAAe,qDAAqD,EACpE,EAAY,EAAW;AACvB;;IAEF,IAAM,IAAO,EAAI,UACX,IAAc,OAAO,GAAM,SAAU,WAAW,EAAK,QAAQ,EAAI;AAYvE,MAX+C;KAC7C,IAAI,EAAI;KACR,kBAAkB,EAAI;KACtB,QAAQ,EAAI;KACZ;KACA,UAAU,EAAI;KACd,aAAa,EAAI,eAAe;KAChC,mBAAmB,EAAI,qBAAqB;KAC5C,iBAAiB,EAAI,mBAAmB;KACxC,UAAU,EAAI,YAAY;KAC3B,CAC6B;IAC9B,IAAM,IAAW,EAAI,oBAAoB,aAAa,UAChD,IAAmB,EAAI,qBAAqB,EAAI,mBAAmB,IACnE,IAAgB,GAAM,gBAA2B,IACjD,IAAiB,EAAI,eAAe;AAC1C,MAAY;KACV,eAAe,EAAI;KACnB,kBAAkB,EAAI;KACtB;KACA;KACA,UAAU,EAAI;KACd,QAAQ;KACR;KACA;KACA,QAAQ;KACR,OAAO;KACR,CAAC;WACI;AAEN,IADA,EAAe,2DAA2D,EAC1E,EAAY,EAAW;aACf;AACR,MAAe,GAAM;;;IAGzB,CAAC,EAAO,CACT,EAEK,IAAe,OAAO,MAAuB;AAGjD,EAFA,EAAE,gBAAgB,EAClB,MAAM,EAAS,EAAS,EACxB,GAAO;;AAGT,KAAI,CAAC,EAAQ,QAAO;CAEpB,IAAM,IAAY,GAAU,eAAe,KAAA,GACrC,IAAuB,MAAc,KAAA,KAAa,EAAS,SAAS,IAAY;AAEtF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;GAAoC,SAAS;GAAe,CAAA,EAC3E,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAwB;KAAyB,CAAA,EAC/D,kBAAC,UAAD;KACE,SAAS;KACT,WAAU;eAEV,kBAAC,GAAD,EAAG,WAAU,WAAY,CAAA;KAClB,CAAA,CACL;OAEN,kBAAC,QAAD;IAAM,UAAU;IAAc,WAAU;cAAxC;KAEE,kBAAC,OAAD,EAAA,UAAA;MACE,kBAAC,SAAD;OAAO,WAAU;iBAAiC;OAAwB,CAAA;MAC1E,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,SAAD;QACE,MAAK;QACL,OAAO;QACP,WAAW,MAAM;AAGf,SAFA,EAAiB,EAAE,OAAO,MAAM,EAChC,EAAY,KAAK,EACjB,EAAe,KAAK;;QAEtB,cAAc,EAAkB,EAAc;QAC9C,WAAU;QACV,aAAY;QACZ,UAAA;QACA,CAAA,EACF,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,EAAkB,EAAc;QAC/C,UAAU,CAAC,EAAc,MAAM,IAAI;QACnC,WAAU;kBAET,IACC,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAE5C,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;QAEzB,CAAA,CACL;;MACL,KAAe,kBAAC,KAAD;OAAG,WAAU;iBAAuC;OAAgB,CAAA;MACnF,KACC,kBAAC,KAAD;OAAG,WAAU;iBAAqC;OAA6B,CAAA;MAE7E,EAAA,CAAA;KAGL,KACC,kBAAA,GAAA,EAAA,UAAA;MAEE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA,EAAA,oBAE/B;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,QAAD,EAAA,UAAA;UAAM;UACK;UACT,kBAAC,QAAD;WAAM,WAAU;qBAAhB,CACG,EAAS,iBAAiB,MAAM,GAAG,GAAG,EAAC,IACnC;;UACF,EAAA,CAAA;SACP,kBAAC,QAAD,EAAA,UAAA;UAAM;UACE;UACN,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAe,EAAS,aAAa,EAAS,SAAS;WACnD,CAAA;UACF,EAAA,CAAA;SACP,kBAAC,QAAD,EAAA,UAAA;UAAM;UACM;UACV,kBAAC,QAAD;WAAM,WAAU;qBAA8B,EAAS;WAAgB,CAAA;UAClE,EAAA,CAAA;SACP,kBAAC,QAAD,EAAA,UAAA,CAAM,cACM,kBAAC,QAAD;UAAM,WAAU;oBAAmB,EAAS;UAAgB,CAAA,CACjE,EAAA,CAAA;SACH;UACF;;MAGN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAuD;QAEhE,CAAA,EACR,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAS;QACN,CAAA,CACF,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAuD;QAEhE,CAAA,EACR,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAS;QACN,CAAA,CACF,EAAA,CAAA,CACF;;MAEN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAAuD;OAEhE,CAAA,EACR,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAS;OACN,CAAA,CACF,EAAA,CAAA;MAEL,EAAS,gBACR,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAuD;QAEhE,CAAA,EACR,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAS;QACN,CAAA,CACF,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;QAAO,WAAU;kBAAuD;QAEhE,CAAA,EACR,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAS,kBAAkB;QACxB,CAAA,CACF,EAAA,CAAA,CACF;;MAIR,kBAAC,OAAD,EAAA,UAAA;OACE,kBAAC,SAAD;QAAO,WAAU;kBAAjB,CAAkD,mBAEhD,kBAAC,QAAD;SAAM,WAAU;mBAAhB;UAAqD;UAC7C,EAAe,GAAY,EAAS,SAAS;UAAC;UAC/C;WACD;;OACR,kBAAC,SAAD;QACE,MAAK;QACL,MAAK;QACL,KAAI;QACJ,KAAK;QACL,OAAO,EAAS;QAChB,WAAW,MACT,EAAY;SAAE,GAAG;SAAU,QAAQ,WAAW,EAAE,OAAO,MAAM,IAAI;SAAG,CAAC;QAEvE,WAAW,uHACT,IAAuB,6BAA6B;QAEtD,UAAA;QACA,CAAA;OACD,KACC,kBAAC,KAAD;QAAG,WAAU;kBAAb;SAAmD;SACJ;SAC5C,EAAe,GAAY,EAAS,SAAS;SAC5C;;OAEF,EAAA,CAAA;MAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAAiC;OAAc,CAAA,EAChE,kBAAC,SAAD;OACE,MAAK;OACL,OAAO,EAAS,UAAU;OAC1B,WAAW,MAAM,EAAY;QAAE,GAAG;QAAU,QAAQ,EAAE,OAAO;QAAO,CAAC;OACrE,WAAU;OACV,aAAY;OACZ,CAAA,CACE,EAAA,CAAA;MAEN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAAiC;OAAa,CAAA,EAC/D,kBAAC,YAAD;OACE,OAAO,EAAS,SAAS;OACzB,WAAW,MAAM,EAAY;QAAE,GAAG;QAAU,OAAO,EAAE,OAAO;QAAO,CAAC;OACpE,WAAU;OACV,MAAM;OACN,aAAY;OACZ,CAAA,CACE,EAAA,CAAA;MACL,EAAA,CAAA;KAGL,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,WAAU;iBACX;OAEQ,CAAA,EACT,kBAAC,UAAD;OACE,MAAK;OACL,UACE,KACA,CAAC,KACD,CAAC,EAAS,oBACV,EAAS,UAAU,KACnB;OAEF,WAAU;iBATZ,CAWG,KAAgB,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,EAAC,gBAEvD;SACL;;KACD;MACH;KACF;;GAaJ,MAA6C,EACjD,WACA,WACA,YACA,aACA,sBACI;CACJ,IAAM,CAAC,GAAQ,KAAa,EAAS,GAAG;AAUxC,QAFI,CAAC,KAAU,CAAC,IAAe,OAG7B,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;GAAoC,SAAS;GAAW,CAAA,EACvE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAwB;KAAgB,CAAA,EACtD,kBAAC,UAAD;KAAQ,SAAS;KAAS,WAAU;eAClC,kBAAC,GAAD,EAAG,WAAU,WAAY,CAAA;KAClB,CAAA,CACL;OAEN,kBAAC,QAAD;IAAM,UAnBS,OAAO,MAAuB;AAGjD,KAFA,EAAE,gBAAgB,EAClB,MAAM,EAAS,EAAO,EACtB,EAAU,GAAG;;IAgBqB,WAAU;cAAxC;KACE,kBAAC,OAAD;MACE,WAAW,OAAO,EAAa,QAAQ,GAAG,UAAU,EAAa,QAAQ,OAAO;gBAEhF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAe,WAAW,WAAW,EAAa,QAAQ,KAAK,UAAY,CAAA,EAC3E,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAW,uBAAuB,EAAa,QAAQ;kBAAQ;QAE9D,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAW,WAAW,EAAa,QAAQ,KAAK;kBAAnD,CAA2D,YAChD,EAAe,EAAO,QAAQ,EAAO,SAAS,CACrD;UACA,EAAA,CAAA,CACF;;MACF,CAAA;KAEN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAiC;MAA6B,CAAA,EAC/E,kBAAC,YAAD;MACE,OAAO;MACP,WAAW,MAAM,EAAU,EAAE,OAAO,MAAM;MAC1C,WAAU;MACV,MAAM;MACN,aAAY;MACZ,UAAA;MACA,CAAA,CACE,EAAA,CAAA;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,WAAU;iBACX;OAEQ,CAAA,EACT,kBAAC,UAAD;OACE,MAAK;OACL,UAAU,KAAgB,CAAC,EAAO,MAAM;OACxC,WAAW,oBAAoB,EAAa,QAAQ,IAAI;iBAH1D,CAKG,KAAgB,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,EAAC,cAEvD;SACL;;KACD;MACH;KACF;;GAUJ,MAAmD,EAAE,WAAQ,iBAAc;AAC/E,KAAI,CAAC,EAAQ,QAAO;CAEpB,IAAM,IAAa,EAAc,EAAO,QAAQ;AAEhD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;GAAoC,SAAS;GAAW,CAAA,EACvE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAwB;MAAmB,CAAA,EACzD,kBAAC,UAAD;MAAQ,SAAS;MAAS,WAAU;gBAClC,kBAAC,GAAD,EAAG,WAAU,WAAY,CAAA;MAClB,CAAA,CACL;;IAEN,kBAAC,OAAD;KAAK,WAAU;eAAf;MAEE,kBAAC,OAAD;OACE,WAAW,0CAA0C,EAAsB,EAAc,EAAO,QAAQ,MAAM;iBADhH,CAGE,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA,EAClC,kBAAC,QAAD;QAAM,WAAU;kBAAe,EAAc,EAAO,QAAQ;QAAa,CAAA,CACrE;;MAGN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAa,CAAA,EAC/D,kBAAC,KAAD;QAAG,WAAU;kBAA+B,EAAO;QAAO,CAAA,CACtD,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAU,CAAA,EAC5D,kBAAC,KAAD;QAAG,WAAU;kBAAW,EAAc,EAAO;QAAY,CAAA,CACrD,EAAA,CAAA,CACF;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAU,CAAA,EAC5D,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAe,EAAO,QAAQ,EAAO,SAAS;QAC7C,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAY,CAAA,EAC9D,kBAAC,KAAD;QAAG,WAAU;kBAAsB,EAAO;QAAa,CAAA,CACnD,EAAA,CAAA,CACF;;MAEN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAsB,CAAA,EACxE,kBAAC,KAAD;QAAG,WAAU;kBAA+B,EAAO;QAAqB,CAAA,CACpE,EAAA,CAAA,EACL,EAAO,kBACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAoB,CAAA,EACtE,kBAAC,KAAD;QAAG,WAAU;kBAA+B,EAAO;QAAmB,CAAA,CAClE,EAAA,CAAA,CAEJ;;MAEL,EAAO,mBACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAqC;OAAqB,CAAA,EACvE,kBAAC,KAAD;OAAG,WAAU;iBAA+B,EAAO;OAAoB,CAAA,CACnE,EAAA,CAAA;OAGN,EAAO,gBAAgB,EAAO,mBAC9B,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACG,EAAO,gBACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAiB,CAAA,EACnE,kBAAC,KAAD;QAAG,WAAU;kBAAW,EAAO;QAAiB,CAAA,CAC5C,EAAA,CAAA,EAEP,EAAO,kBACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAmB,CAAA,EACrE,kBAAC,KAAD;QAAG,WAAU;kBAAW,EAAO;QAAmB,CAAA,CAC9C,EAAA,CAAA,CAEJ;;MAGP,EAAO,UACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAqC;OAAU,CAAA,EAC5D,kBAAC,KAAD;OAAG,WAAU;iBAAW,EAAO;OAAW,CAAA,CACtC,EAAA,CAAA;MAGP,EAAO,SACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAqC;OAAS,CAAA,EAC3D,kBAAC,KAAD;OAAG,WAAU;iBAAW,EAAO;OAAU,CAAA,CACrC,EAAA,CAAA;MAGP,EAAO,gBACN,kBAAC,OAAD;OACE,WAAW,OAAO,EAAa,MAAM,GAAG,UAAU,EAAa,MAAM,OAAO;iBAD9E,CAGE,kBAAC,KAAD;QAAG,WAAW,WAAW,EAAa,MAAM,KAAK;kBAAQ;QAAiB,CAAA,EAC1E,kBAAC,KAAD;QAAG,WAAW,WAAW,EAAa,MAAM;kBAAS,EAAO;QAAiB,CAAA,CACzE;;MAGR,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAc,CAAA,EAChE,kBAAC,KAAD;QAAG,WAAU;kBAAW,EAAe,EAAO,UAAU;QAAK,CAAA,CACzD,EAAA,CAAA,EACL,EAAO,eACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAqC;QAAgB,CAAA,EAClE,kBAAC,KAAD;QAAG,WAAU;kBAAW,EAAe,EAAO,YAAY;QAAK,CAAA,CAC3D,EAAA,CAAA,CAEJ;;MAEL,EAAO,aAAa,KACnB,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAqC;OAAe,CAAA,EACjE,kBAAC,KAAD;OAAG,WAAU;iBAAW,EAAO;OAAe,CAAA,CAC1C,EAAA,CAAA;MAEJ;;IAEN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,UAAD;MACE,SAAS;MACT,WAAU;gBACX;MAEQ,CAAA;KACL,CAAA;IACF;KACF;;GAUJ,IAAgF;CACpF,SAAS;EAAE,OAAO;EAAW,QAAQ;EAAW;CAChD,WAAW;EAAE,OAAO;EAAa,QAAQ;EAAa;CACtD,QAAQ;EAAE,OAAO;EAAU,QAAQ;EAAU;CAC7C,KAAK;EAAE,OAAO;EAAO,QAAQ,KAAA;EAAW;CACzC,EAEY,UAAwB;CACnC,IAAM,EAAE,SAAM,IAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAa,EAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAEnC,IAAc,GAAuB,EAGrC,CAAC,GAAW,KAAgB,EAAoB,UAAU,EAC1D,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAS,KAAc,EAA8B,EAAE,CAAC,EACzD,CAAC,GAAa,MAAkB,EAAS,GAAM,EAC/C,CAAC,GAAgB,KAAqB,EAA8B,KAAK,EACzE,CAAC,GAAiB,KAAsB,EAAS,GAAM,EACvD,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAc,KAAmB,EAA8B,KAAK,EACrE,CAAC,IAAiB,KAAsB,EAAwB,KAAK,EAsBrE,EACJ,YACA,UACA,eACA,eACA,iBACA,wBACA,YACA,kBACA,sBACA,YAAY,GACZ,wBACA,mBACA,gBACA,iBACA,2CACA,gBACA,kBACA,8BACE,EAAW,EAAE,SApCE,SACV;EACL,GAAG;EACH,QAAQ,EAAW,GAAW;EAC/B,GAED;EACE;EACA,EAAQ;EACR,EAAQ;EACR,EAAQ;EACR,EAAQ;EACR,EAAQ;EACT,CACF,EAsBqC,CAAC;AAGvC,KAAI,CAAC,EAAY,gBACf,QAAO,kBAAC,GAAD,EAAc,SAAQ,8CAA+C,CAAA;AAI9E,KAAI,KAAgB,EAAc,EAAa,CAC7C,QACE,kBAAC,OAAD;EAAK,WAAU;YACb,kBAAC,GAAD;GACE,OAAM;GACN,SAAQ;GACR,eAAe,GAAS;GACxB,WAAA;GACA,CAAA;EACE,CAAA;CAKV,IAAM,MAAmB,MAAmB;AAI1C,EAHA,EAAa,EAAI,EAEjB,EAAW,EAAE,CAAC,EACd,EAAe,GAAG;IAGd,KAAsB,GAAgC,MAA8B;AAExF,MAAI,MAAQ,SAAU;EAEtB,IAAM,IAAa;GAAE,GAAG;IAAU,IAAM,KAAS,KAAA;GAAW;AAE5D,EADA,EAAW,EAAW,EACtB,EAAc;GAAE,GAAG;GAAY,QAAQ,EAAW,GAAW;GAAQ,CAAC;IAGlE,KAAqB,OAAO,MAA+B;AAC/D,MAAI;AAEF,GADA,MAAM,GAAmB,EAAK,EAC9B,EAAmB,GAAM;WAClB,GAAO;AACd,WAAQ,MAAM,4BAA4B,EAAM;;IAI9C,KAAgB,OAAO,MAAyB;AACpD,IAAmB,EAAO,GAAG;AAC7B,MAAI;GACF,IAAM,IAAS,MAAM,GAAc,EAAO,GAAG;AAC7C,GAAI,CAAC,EAAO,WAAW,EAAO,SAC5B,QAAQ,MAAM,6BAA6B,EAAO,MAAM;WAEnD,GAAO;AACd,WAAQ,MAAM,6BAA6B,EAAM;YACzC;AACR,KAAmB,KAAK;;IAItB,KAAa,OAAO,MAAmB;AACtC,QACL,KAAI;AAGF,GAFA,MAAM,GAAW,EAAa,IAAI,EAAO,EACzC,EAAiB,GAAM,EACvB,EAAgB,KAAK;WACd,GAAO;AACd,WAAQ,MAAM,0BAA0B,EAAM;;IAI5C,KAAc,OAAO,MAAyB;AAClD,IAAmB,EAAO,GAAG;AAC7B,MAAI;GACF,IAAM,IAAS,MAAM,GAAY,EAAO,GAAG;AAC3C,GAAI,CAAC,EAAO,WAAW,EAAO,SAC5B,QAAQ,MAAM,wBAAwB,EAAO,MAAM;WAE9C,GAAO;AACd,WAAQ,MAAM,2BAA2B,EAAM;YACvC;AACR,KAAmB,KAAK;;IAItB,KAA2B,YAAY;AAC3C,MAAI;AACF,SAAM,IAAuC;WACtC,GAAO;AACd,WAAQ,MAAM,2CAA2C,EAAM;;IAK7D,KAAkB,IACpB,EAAQ,QACL,MACC,EAAE,iBAAiB,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,IACpE,EAAE,gBAAgB,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,IACnE,EAAE,QAAQ,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,CAC9D,GACD;AAoBJ,QAlBI,KAEA,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD,EAAK,WAAU,2CAA4C,CAAA;GAC3D,kBAAC,OAAD;IAAK,WAAU;cACZ;KAAC;KAAG;KAAG;KAAG;KAAG;KAAE,CAAC,KAAK,MACpB,kBAAC,OAAD,EAAa,WAAU,0CAA2C,EAAxD,EAAwD,CAClE;IACE,CAAA;GACN,kBAAC,OAAD;IAAK,WAAU;cACZ;KAAC;KAAG;KAAG;KAAG;KAAG;KAAE,CAAC,KAAK,MACpB,kBAAC,OAAD,EAAa,WAAU,uCAAwC,EAArD,EAAqD,CAC/D;IACE,CAAA;GACF;MAKR,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,GAAD;IACE,OAAO,EAAG,yBAAyB,oBAAoB;IACvD,aAAY;IACZ,SACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACG,EAAoB,SAAS,KAC5B,kBAAC,UAAD;OACE,SAAS;OACT,UAAU;OACV,WAAW,kFAAkF,EAAa,QAAQ,OAAO,GAAG,EAAa,QAAQ,GAAG,GAAG,EAAa,QAAQ,KAAK;iBAHnL;QAKG,IACC,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAE5C,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;QAChC;QACM,EAAoB;QAAO;QAC5B;;MAEX,kBAAC,UAAD;OACE,eAAe,GAAS;OACxB,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,UAE1B;;MACT,kBAAC,UAAD;OACE,eAAe,EAAmB,GAAK;OACvC,WAAU;iBAFZ,CAIE,kBAAC,IAAD,EAAM,WAAU,WAAY,CAAA,EAAA,uBAErB;;MACL;;IAER,CAAA;GAGF,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eACX,OAAO,KAAK,EAAW,CAAiB,KAAK,MAAQ;MACrD,IAAM,IAAW,MAAc,GACzB,IAAQ,IACV,MAAQ,YACN,EAAM,UACN,MAAQ,cACN,EAAM,YACN,MAAQ,WACN,EAAM,SACN,EAAM,UACN,EAAM,aACN,EAAM,YACN,EAAM,SACN,EAAM,UACZ;AAEJ,aACE,kBAAC,UAAD;OAEE,eAAe,GAAgB,EAAI;OACnC,WAAW,wGACT,IACI,gCACA;iBANR,CASG,EAAW,GAAK,OAChB,KACC,kBAAC,QAAD;QACE,WAAW,oCACT,IAAW,+BAA+B;kBAG3C;QACI,CAAA,CAEF;SAlBF,EAkBE;OAEX;KACE,CAAA;IACF,CAAA;GAGN,kBAAC,OAAD;IAAK,WAAU;cAAf;KAEE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,0EAA2E,CAAA,EAC7F,kBAAC,SAAD;OACE,MAAK;OACL,aAAY;OACZ,OAAO;OACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;OAC/C,WAAU;OACV,CAAA,CACE;;KAGN,kBAAC,UAAD;MACE,eAAe,GAAe,CAAC,EAAY;MAC3C,WAAW,oGACT,IACI,8CACA;gBALR;OAQE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;;OAE7B,OAAO,OAAO,EAAQ,CAAC,OAAO,QAAQ,CAAC,SAAS,KAC/C,kBAAC,QAAD;QAAM,WAAU;kBACb,OAAO,OAAO,EAAQ,CAAC,OAAO,QAAQ,CAAC;QACnC,CAAA;OAEF;;KAGR,OAAO,OAAO,EAAQ,CAAC,OAAO,QAAQ,CAAC,SAAS,KAC/C,kBAAC,UAAD;MACE,eAAe;AAEb,OADA,EAAW,EAAE,CAAC,EACd,EAAc,EAAE,CAAC;;MAEnB,WAAU;gBALZ,CAOE,kBAAC,GAAD,EAAG,WAAU,WAAY,CAAA,EAAA,QAElB;;KAEP;;GAGL,KACC,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAiC;MAAc,CAAA,EAChE,kBAAC,UAAD;MACE,OAAO,EAAQ,UAAU;MACzB,WAAW,MAAM,EAAmB,UAAU,EAAE,OAAO,MAAM;MAC7D,WAAU;gBAHZ,CAKE,kBAAC,UAAD;OAAQ,OAAM;iBAAG;OAAoB,CAAA,EACpC,OAAO,QAAQ,EAAc,CAAC,KAAK,CAAC,GAAK,OACxC,kBAAC,UAAD;OAAkB,OAAO;iBACtB;OACM,EAFI,EAEJ,CACT,CACK;QACL,EAAA,CAAA;KAEN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAAiC;MAAgB,CAAA,EAClE,kBAAC,UAAD;MACE,OAAO,EAAQ,YAAY;MAC3B,WAAW,MAAM,EAAmB,YAAY,EAAE,OAAO,MAAM;MAC/D,WAAU;gBAHZ,CAKE,kBAAC,UAAD;OAAQ,OAAM;iBAAG;OAAsB,CAAA,EACtC,GAAiB,KAAK,MACrB,kBAAC,UAAD;OAAgB,OAAO;iBACpB,EAAE,OAAO,EAAE,CAAC,aAAa,GAAG,EAAE,MAAM,EAAE;OAChC,EAFI,EAEJ,CACT,CACK;QACL,EAAA,CAAA;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,SAAD;OAAO,WAAU;iBAAiC;OAAkB,CAAA,EACpE,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,SAAD;SACE,MAAK;SACL,OAAO,EAAQ,WAAW,EAAQ,SAAS,MAAM,IAAI,CAAC,KAAK;SAC3D,WAAW,MACT,EACE,YACA,EAAE,OAAO,QAAQ,IAAI,KAAK,EAAE,OAAO,MAAM,CAAC,aAAa,GAAG,KAAA,EAC3D;SAEH,WAAU;SACV,CAAA;QACF,kBAAC,QAAD;SAAM,WAAU;mBAAyC;SAAQ,CAAA;QACjE,kBAAC,SAAD;SACE,MAAK;SACL,OAAO,EAAQ,SAAS,EAAQ,OAAO,MAAM,IAAI,CAAC,KAAK;SACvD,WAAW,MACT,EACE,UACA,EAAE,OAAO,QAAQ,IAAI,KAAK,EAAE,OAAO,MAAM,CAAC,aAAa,GAAG,KAAA,EAC3D;SAEH,WAAU;SACV,CAAA;QACE;SACF;;KACF;;GAIP,GAAgB,WAAW,IAC1B,kBAAC,GAAD;IACE,MAAM,kBAAC,GAAD,EAAW,WAAU,iCAAkC,CAAA;IAC7D,OAAM;IACN,aACE,OAAO,OAAO,EAAQ,CAAC,OAAO,QAAQ,CAAC,SAAS,IAC5C,gCACA,MAAc,YACZ,mCACA;IAER,CAAA,GAEF,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,SAAD;OAAO,WAAU;iBACf,kBAAC,MAAD,EAAA,UAAA;QACE,kBAAC,MAAD;SAAI,WAAU;mBAAkF;SAE3F,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAkF;SAE3F,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAuG;SAEhH,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAuG;SAEhH,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAkF;SAE3F,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAmF;SAE5F,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAuG;SAEhH,CAAA;QACL,kBAAC,MAAD,EAAI,WAAU,kBAAsB,CAAA;QACjC,EAAA,CAAA;OACC,CAAA,EACR,kBAAC,SAAD;OAAO,WAAU;iBACd,GAAgB,KAAK,MAAW;QAC/B,IAAM,IAAa,EAAc,EAAO,QAAQ;AAChD,eACE,kBAAC,MAAD;SAAoB,WAAU;mBAA9B;UACE,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,QAAD,EAAA,UAAO,EAAe,EAAO,UAAU,CAAC,MAAM,IAAI,CAAC,IAAU,CAAA,EAC7D,kBAAC,QAAD;aAAM,WAAU;uBACb,EAAe,EAAO,UAAU,CAAC,MAAM,IAAI,CAAC;aACxC,CAAA,CACH;;WACH,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,QAAD;YACE,WAAW,0EAA0E,EACnF,EAAc,EAAO,QAAQ,MAC9B;sBAHH,CAKE,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA,EAClC,kBAAC,QAAD;aAAM,WAAU;uBACb,EAAc,EAAO,QAAQ;aACzB,CAAA,CACF;;WACJ,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAc,EAAO;WACnB,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAO;WACL,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAO;WACL,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAe,EAAO,QAAQ,EAAO,SAAS;WAC5C,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACX,EAAO,UAAU;WACf,CAAA;UACL,kBAAC,MAAD;WAAI,WAAU;qBACZ,kBAAC,IAAD;YACU;YACR,qBAAqB,EAAkB,EAAO;YAC9C,iBAAiB,GAAc,EAAO;YACtC,cAAc;AAEZ,aADA,EAAgB,EAAO,EACvB,EAAiB,GAAK;;YAExB,eAAe,GAAY,EAAO;YAClC,cAAc,OAAoB,EAAO;YACzC,CAAA;WACC,CAAA;UACF;WAjDI,EAAO,GAiDX;SAEP;OACI,CAAA,CACF;;KACJ,CAAA;IACF,CAAA;GAIP,EAAW,aAAa,KACvB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eAAb;MAAsE;MAC3D,EAAW,OAAO,EAAW,WAAW;MAAE;MAAI;MACtD,KAAK,KAAK,EAAW,OAAO,KAAK,EAAW,UAAU,EAAW,WAAW;MAAC;MAAI;MACjF,EAAW;MAAW;MACrB;QACJ,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,UAAD;OACE,SAAS;OACT,UAAU,CAAC,EAAW;OACtB,WAAU;iBAHZ,CAKE,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA,EACnC,kBAAC,QAAD;QAAM,WAAU;kBAAmB;QAAe,CAAA,CAC3C;;MACT,kBAAC,QAAD;OAAM,WAAU;iBAAhB;QACE,kBAAC,QAAD;SAAM,WAAU;mBAAmB;SAAY,CAAA;QAC9C,EAAW,OAAO;QAAE;QAAC,kBAAC,QAAD;SAAM,WAAU;mBAAmB;SAAS,CAAA;QAClE,kBAAC,QAAD;SAAM,WAAU;mBAAY;SAAQ,CAAA;QAAC;QACpC,KAAK,KAAK,EAAW,aAAa,EAAW,SAAS;QAClD;;MACP,kBAAC,UAAD;OACE,SAAS;OACT,UAAU,CAAC,EAAW;OACtB,WAAU;iBAHZ,CAKE,kBAAC,QAAD;QAAM,WAAU;kBAAmB;QAAW,CAAA,EAC9C,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA,CAC7B;;MACL;OACF;;GAIR,kBAAC,IAAD;IACE,QAAQ;IACR,eAAe,EAAmB,GAAM;IACxC,UAAU;IACV,cAAc;IACd,CAAA;GAEF,kBAAC,IAAD;IACE,QAAQ;IACR,QAAQ;IACR,eAAe;AAEb,KADA,EAAiB,GAAM,EACvB,EAAgB,KAAK;;IAEvB,UAAU;IACV,cAAc;IACd,CAAA;GAEF,kBAAC,IAAD;IAAoB,QAAQ;IAAgB,eAAe,EAAkB,KAAK;IAAI,CAAA;GAClF"}
1
+ {"version":3,"file":"RefundsPage.js","names":[],"sources":["../../../../../src/billing/modules/billing/pages/RefundsPage.tsx"],"sourcesContent":["/**\n * Billing Module - Refunds Page\n * Admin page for managing refund records\n */\n\nimport { useState, useRef, useEffect, useMemo, useCallback, type FC } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport {\n RefreshCw,\n Plus,\n MoreHorizontal,\n Eye,\n Play,\n SkipForward,\n RotateCcw,\n ChevronLeft,\n ChevronRight,\n X,\n Search,\n Filter,\n AlertTriangle,\n CheckCircle,\n Clock,\n XCircle,\n Loader2,\n Ban,\n Download,\n // Calendar - available but not currently used\n} from 'lucide-react';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport {\n useRefunds,\n type RefundRecord,\n type RefundRecordStatus,\n type RefundSource,\n type RefundRecordFilters,\n} from '../hooks';\nimport {\n GetTransactionDocument,\n type GetTransactionQuery,\n} from '../../../../generated/global-operations';\nimport { AccessDenied, PageHeader, EmptyState, ServerError } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport { statusTokens } from '../../../shared/utils/tokens';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst STATUS_CONFIG: Record<\n RefundRecordStatus,\n { label: string; color: string; icon: FC<{ className?: string }> }\n> = {\n PENDING: { label: 'Pending', color: 'yellow', icon: Clock },\n PROCESSING: { label: 'Processing', color: 'blue', icon: Loader2 },\n COMPLETED: { label: 'Completed', color: 'green', icon: CheckCircle },\n FAILED: { label: 'Failed', color: 'red', icon: XCircle },\n SKIPPED: { label: 'Skipped', color: 'gray', icon: Ban },\n};\n\nconst SOURCE_LABELS: Record<RefundSource, string> = {\n MANUAL: 'Manual',\n WEBHOOK_RECOVERY: 'Webhook Recovery',\n SUBSCRIPTION_CANCEL: 'Subscription Cancel',\n DUPLICATE_PAYMENT: 'Duplicate Payment',\n};\n\nconst PROVIDER_OPTIONS = ['stripe', 'razorpay'];\n\n// ============================================================================\n// Helper Components\n// ============================================================================\n\nconst getStatusBadgeClasses = (color: string): string => {\n const classes: Record<string, string> = {\n yellow: `${statusTokens.warning.bg} ${statusTokens.warning.text}`,\n blue: `${statusTokens.info.bg} ${statusTokens.info.text}`,\n green: `${statusTokens.success.bg} ${statusTokens.success.text}`,\n red: `${statusTokens.error.bg} ${statusTokens.error.text}`,\n gray: `${statusTokens.neutral.bg} ${statusTokens.neutral.text}`,\n };\n return classes[color] || classes.gray;\n};\n\n// Actions Dropdown\ninterface RefundActionsDropdownProps {\n record: RefundRecord;\n onViewDetails: () => void;\n onProcess: () => void;\n onSkip: () => void;\n onRetry: () => void;\n isProcessing: boolean;\n}\n\nconst RefundActionsDropdown: FC<RefundActionsDropdownProps> = ({\n record,\n onViewDetails,\n onProcess,\n onSkip,\n onRetry,\n isProcessing,\n}) => {\n const [isOpen, setIsOpen] = useState(false);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handleClickOutside);\n return () => document.removeEventListener('mousedown', handleClickOutside);\n }, []);\n\n const canProcess = record.status === 'PENDING';\n const canSkip = record.status === 'PENDING';\n const canRetry = record.status === 'FAILED';\n\n return (\n <div className=\"relative\" ref={dropdownRef}>\n <button\n type=\"button\"\n onClick={() => setIsOpen(!isOpen)}\n disabled={isProcessing}\n className=\"p-1.5 rounded-md hover:bg-muted/50 transition-colors disabled:opacity-50\"\n aria-label=\"Refund actions\"\n >\n {isProcessing ? (\n <Loader2 className=\"size-4 animate-spin text-muted-foreground\" />\n ) : (\n <MoreHorizontal className=\"size-4 text-muted-foreground\" />\n )}\n </button>\n\n {isOpen && (\n <div className=\"absolute right-0 top-full mt-1 z-50 min-w-[160px] bg-popover border border-border rounded-md shadow-lg py-1\">\n <button\n type=\"button\"\n onClick={() => {\n onViewDetails();\n setIsOpen(false);\n }}\n className=\"w-full flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-muted/50 transition-colors\"\n >\n <Eye className=\"size-4\" />\n View Details\n </button>\n\n {canProcess && (\n <button\n type=\"button\"\n onClick={() => {\n onProcess();\n setIsOpen(false);\n }}\n className={`w-full flex items-center gap-2 px-3 py-2 text-sm ${statusTokens.success.text} hover:bg-muted/50 transition-colors`}\n >\n <Play className=\"size-4\" />\n Process Refund\n </button>\n )}\n\n {canSkip && (\n <button\n type=\"button\"\n onClick={() => {\n onSkip();\n setIsOpen(false);\n }}\n className={`w-full flex items-center gap-2 px-3 py-2 text-sm ${statusTokens.warning.text} hover:bg-muted/50 transition-colors`}\n >\n <SkipForward className=\"size-4\" />\n Skip Refund\n </button>\n )}\n\n {canRetry && (\n <button\n type=\"button\"\n onClick={() => {\n onRetry();\n setIsOpen(false);\n }}\n className={`w-full flex items-center gap-2 px-3 py-2 text-sm ${statusTokens.info.text} hover:bg-muted/50 transition-colors`}\n >\n <RotateCcw className=\"size-4\" />\n Retry Refund\n </button>\n )}\n </div>\n )}\n </div>\n );\n};\n\n// Create Refund Modal\ninterface CreateRefundModalProps {\n isOpen: boolean;\n onClose: () => void;\n onSubmit: (data: CreateRefundFormData) => Promise<void>;\n isSubmitting: boolean;\n}\n\ninterface CreateRefundFormData {\n billingAccountId?: string;\n provider: string;\n gatewayPaymentId: string;\n gatewayOrderId?: string;\n amount: number;\n currency: string;\n purchaseType?: string;\n purchaseDetail?: string;\n reason?: string;\n notes?: string;\n transactionId?: string;\n}\n\ninterface LookedUpTransaction {\n id: string;\n billingAccountId: string;\n amount: number;\n totalAmount: number; // amount + tax (what was actually charged)\n currency: string;\n description: string | null;\n razorpayPaymentId: string | null;\n stripePaymentId: string | null;\n metadata: Record<string, unknown> | null;\n}\n\nconst EMPTY_FORM: CreateRefundFormData = {\n provider: 'stripe',\n gatewayPaymentId: '',\n amount: 0,\n currency: 'USD',\n};\n\nconst CreateRefundModal: FC<CreateRefundModalProps> = ({\n isOpen,\n onClose,\n onSubmit,\n isSubmitting,\n}) => {\n const client = useApolloClient();\n const [transactionId, setTransactionId] = useState('');\n const [lookedUp, setLookedUp] = useState<LookedUpTransaction | null>(null);\n const [lookupError, setLookupError] = useState<string | null>(null);\n const [isLookingUp, setIsLookingUp] = useState(false);\n const [formData, setFormData] = useState<CreateRefundFormData>(EMPTY_FORM);\n\n const reset = () => {\n setTransactionId('');\n setLookedUp(null);\n setLookupError(null);\n setFormData(EMPTY_FORM);\n };\n\n const handleClose = () => {\n reset();\n onClose();\n };\n\n const lookupTransaction = useCallback(\n async (id: string) => {\n const trimmed = id.trim();\n if (!trimmed) return;\n setIsLookingUp(true);\n setLookupError(null);\n setLookedUp(null);\n try {\n const { data } = await client.query<GetTransactionQuery>({\n query: GetTransactionDocument,\n variables: { id: trimmed },\n fetchPolicy: 'network-only',\n });\n const txn = data?.getTransaction ?? null;\n if (!txn) {\n setLookupError('Transaction not found. Check the ID and try again.');\n setFormData(EMPTY_FORM);\n return;\n }\n const meta = txn.metadata as Record<string, unknown> | null;\n const totalAmount = typeof meta?.total === 'number' ? meta.total : txn.amount;\n const lookedUpWithTotal: LookedUpTransaction = {\n id: txn.id,\n billingAccountId: txn.billingAccountId,\n amount: txn.amount,\n totalAmount,\n currency: txn.currency,\n description: txn.description ?? null,\n razorpayPaymentId: txn.razorpayPaymentId ?? null,\n stripePaymentId: txn.stripePaymentId ?? null,\n metadata: txn.metadata ?? null,\n };\n setLookedUp(lookedUpWithTotal);\n const provider = txn.razorpayPaymentId ? 'razorpay' : 'stripe';\n const gatewayPaymentId = txn.razorpayPaymentId ?? txn.stripePaymentId ?? '';\n const purchaseType = (meta?.purchaseType as string) ?? '';\n const purchaseDetail = txn.description ?? '';\n setFormData({\n transactionId: txn.id,\n billingAccountId: txn.billingAccountId,\n provider,\n gatewayPaymentId,\n currency: txn.currency,\n amount: totalAmount,\n purchaseType,\n purchaseDetail,\n reason: '',\n notes: '',\n });\n } catch {\n setLookupError('Failed to look up transaction. Ensure the ID is correct.');\n setFormData(EMPTY_FORM);\n } finally {\n setIsLookingUp(false);\n }\n },\n [client]\n );\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n await onSubmit(formData);\n reset();\n };\n\n if (!isOpen) return null;\n\n const maxAmount = lookedUp?.totalAmount ?? undefined;\n const isAmountExceedingMax = maxAmount !== undefined && formData.amount > maxAmount + 0.01;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-overlay-scrim\" onClick={handleClose} />\n <div className=\"relative bg-background border border-border rounded-lg shadow-xl max-w-lg w-full mx-4 max-h-[90vh] overflow-auto\">\n <div className=\"flex items-center justify-between p-4 border-b border-border\">\n <h2 className=\"text-lg font-semibold\">Create Manual Refund</h2>\n <button\n type=\"button\"\n onClick={handleClose}\n className=\"p-1 rounded-md hover:bg-muted/50 transition-colors\"\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n <form onSubmit={handleSubmit} className=\"p-4 space-y-4\">\n {/* Step 1: Transaction ID lookup */}\n <div>\n <label className=\"block text-sm font-medium mb-1\">Transaction ID *</label>\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={transactionId}\n onChange={(e) => {\n setTransactionId(e.target.value);\n setLookedUp(null);\n setLookupError(null);\n }}\n onBlur={() => lookupTransaction(transactionId)}\n className=\"flex-1 px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary\"\n placeholder=\"Paste transaction UUID...\"\n required\n />\n <button\n type=\"button\"\n onClick={() => lookupTransaction(transactionId)}\n disabled={!transactionId.trim() || isLookingUp}\n className=\"px-3 py-2 border border-border rounded-md hover:bg-muted/50 transition-colors disabled:opacity-50 flex items-center gap-1 text-sm\"\n >\n {isLookingUp ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Search className=\"size-4\" />\n )}\n </button>\n </div>\n {lookupError && <p className=\"text-xs text-status-error-text mt-1\">{lookupError}</p>}\n {isLookingUp && (\n <p className=\"text-xs text-muted-foreground mt-1\">Looking up transaction…</p>\n )}\n </div>\n\n {/* Auto-filled fields — shown once transaction is found */}\n {lookedUp && (\n <>\n {/* Transaction summary banner */}\n <div className=\"p-3 bg-status-success-bg-subtle border border-border-subtle rounded-md text-sm space-y-1\">\n <div className=\"flex items-center gap-2 text-status-success-text font-medium\">\n <CheckCircle className=\"size-4\" />\n Transaction found\n </div>\n <div className=\"text-muted-foreground grid grid-cols-2 gap-x-4 gap-y-0.5 mt-1\">\n <span>\n Account:{' '}\n <span className=\"text-foreground font-mono text-xs\">\n {lookedUp.billingAccountId.slice(0, 16)}…\n </span>\n </span>\n <span>\n Paid:{' '}\n <span className=\"text-foreground\">\n {formatCurrency(lookedUp.totalAmount, lookedUp.currency)}\n </span>\n </span>\n <span>\n Provider:{' '}\n <span className=\"text-foreground capitalize\">{formData.provider}</span>\n </span>\n <span>\n Currency: <span className=\"text-foreground\">{lookedUp.currency}</span>\n </span>\n </div>\n </div>\n\n {/* Read-only auto-filled fields */}\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Provider\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm capitalize\">\n {formData.provider}\n </div>\n </div>\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Currency\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm\">\n {formData.currency}\n </div>\n </div>\n </div>\n\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Gateway Payment ID\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm font-mono truncate\">\n {formData.gatewayPaymentId}\n </div>\n </div>\n\n {formData.purchaseType && (\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Purchase Type\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm\">\n {formData.purchaseType}\n </div>\n </div>\n <div>\n <label className=\"block text-xs font-medium text-muted-foreground mb-1\">\n Purchase Detail\n </label>\n <div className=\"px-3 py-2 border border-border rounded-md bg-muted/30 text-sm truncate\">\n {formData.purchaseDetail || '—'}\n </div>\n </div>\n </div>\n )}\n\n {/* Editable: Amount (capped at transaction amount) */}\n <div>\n <label className=\"block text-sm font-medium mb-1\">\n Refund Amount *\n <span className=\"text-xs text-muted-foreground ml-1\">\n (max {formatCurrency(maxAmount!, formData.currency)})\n </span>\n </label>\n <input\n type=\"number\"\n step=\"0.01\"\n min=\"0.01\"\n max={maxAmount}\n value={formData.amount}\n onChange={(e) =>\n setFormData({ ...formData, amount: parseFloat(e.target.value) || 0 })\n }\n className={`w-full px-3 py-2 border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary ${\n isAmountExceedingMax ? 'border-status-error-text' : 'border-border'\n }`}\n required\n />\n {isAmountExceedingMax && (\n <p className=\"text-xs text-status-error-text mt-1\">\n Amount cannot exceed the original payment of{' '}\n {formatCurrency(maxAmount!, formData.currency)}\n </p>\n )}\n </div>\n\n {/* Editable: Reason & Notes */}\n <div>\n <label className=\"block text-sm font-medium mb-1\">Reason</label>\n <input\n type=\"text\"\n value={formData.reason || ''}\n onChange={(e) => setFormData({ ...formData, reason: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary\"\n placeholder=\"Reason for refund\"\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-1\">Notes</label>\n <textarea\n value={formData.notes || ''}\n onChange={(e) => setFormData({ ...formData, notes: e.target.value })}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-primary resize-none\"\n rows={2}\n placeholder=\"Internal notes\"\n />\n </div>\n </>\n )}\n\n <div className=\"flex gap-2 pt-2\">\n <button\n type=\"button\"\n onClick={handleClose}\n className=\"flex-1 py-2 px-4 border border-border rounded-md hover:bg-muted/50 transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={\n isSubmitting ||\n !lookedUp ||\n !formData.gatewayPaymentId ||\n formData.amount <= 0 ||\n isAmountExceedingMax\n }\n className=\"flex-1 py-2 px-4 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2\"\n >\n {isSubmitting && <Loader2 className=\"size-4 animate-spin\" />}\n Create Refund\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n};\n\n// Skip Refund Modal\ninterface SkipRefundModalProps {\n isOpen: boolean;\n record: RefundRecord | null;\n onClose: () => void;\n onSubmit: (reason: string) => Promise<void>;\n isSubmitting: boolean;\n}\n\nconst SkipRefundModal: FC<SkipRefundModalProps> = ({\n isOpen,\n record,\n onClose,\n onSubmit,\n isSubmitting,\n}) => {\n const [reason, setReason] = useState('');\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n await onSubmit(reason);\n setReason('');\n };\n\n if (!isOpen || !record) return null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-overlay-scrim\" onClick={onClose} />\n <div className=\"relative bg-background border border-border rounded-lg shadow-xl max-w-md w-full mx-4\">\n <div className=\"flex items-center justify-between p-4 border-b border-border\">\n <h2 className=\"text-lg font-semibold\">Skip Refund</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 rounded-md hover:bg-muted/50 transition-colors\"\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n <form onSubmit={handleSubmit} className=\"p-4 space-y-4\">\n <div\n className={`p-3 ${statusTokens.warning.bg} border ${statusTokens.warning.border} rounded-md`}\n >\n <div className=\"flex items-start gap-2\">\n <AlertTriangle className={`size-5 ${statusTokens.warning.icon} mt-0.5`} />\n <div>\n <p className={`text-sm font-medium ${statusTokens.warning.text}`}>\n You are about to skip this refund\n </p>\n <p className={`text-sm ${statusTokens.warning.text} mt-1`}>\n Amount: {formatCurrency(record.amount, record.currency)}\n </p>\n </div>\n </div>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-1\">Reason for skipping *</label>\n <textarea\n value={reason}\n onChange={(e) => setReason(e.target.value)}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background resize-none\"\n rows={3}\n placeholder=\"Explain why this refund is being skipped...\"\n required\n />\n </div>\n\n <div className=\"flex gap-2\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"flex-1 py-2 px-4 border border-border rounded-md hover:bg-muted/50 transition-colors\"\n >\n Cancel\n </button>\n <button\n type=\"submit\"\n disabled={isSubmitting || !reason.trim()}\n className={`flex-1 py-2 px-4 ${statusTokens.warning.dot} text-primary-foreground rounded-md hover:opacity-90 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2`}\n >\n {isSubmitting && <Loader2 className=\"size-4 animate-spin\" />}\n Skip Refund\n </button>\n </div>\n </form>\n </div>\n </div>\n );\n};\n\n// Refund Details Modal\ninterface RefundDetailsModalProps {\n record: RefundRecord | null;\n onClose: () => void;\n}\n\nconst RefundDetailsModal: FC<RefundDetailsModalProps> = ({ record, onClose }) => {\n if (!record) return null;\n\n const StatusIcon = STATUS_CONFIG[record.status].icon;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n <div className=\"absolute inset-0 bg-overlay-scrim\" onClick={onClose} />\n <div className=\"relative bg-background border border-border rounded-lg shadow-xl max-w-lg w-full mx-4 max-h-[90vh] overflow-auto\">\n <div className=\"flex items-center justify-between p-4 border-b border-border\">\n <h2 className=\"text-lg font-semibold\">Refund Details</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"p-1 rounded-md hover:bg-muted/50 transition-colors\"\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n <div className=\"p-4 space-y-4\">\n {/* Status Banner */}\n <div\n className={`flex items-center gap-2 p-3 rounded-md ${getStatusBadgeClasses(STATUS_CONFIG[record.status].color)}`}\n >\n <StatusIcon className=\"size-5\" />\n <span className=\"font-medium\">{STATUS_CONFIG[record.status].label}</span>\n </div>\n\n {/* Basic Info */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Refund ID</p>\n <p className=\"text-sm font-mono break-all\">{record.id}</p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Source</p>\n <p className=\"text-sm\">{SOURCE_LABELS[record.source]}</p>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Amount</p>\n <p className=\"text-lg font-semibold\">\n {formatCurrency(record.amount, record.currency)}\n </p>\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Provider</p>\n <p className=\"text-sm capitalize\">{record.provider}</p>\n </div>\n </div>\n\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Gateway Payment ID</p>\n <p className=\"text-sm font-mono break-all\">{record.gatewayPaymentId}</p>\n </div>\n {record.gatewayOrderId && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Gateway Order ID</p>\n <p className=\"text-sm font-mono break-all\">{record.gatewayOrderId}</p>\n </div>\n )}\n </div>\n\n {record.gatewayRefundId && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Gateway Refund ID</p>\n <p className=\"text-sm font-mono break-all\">{record.gatewayRefundId}</p>\n </div>\n )}\n\n {(record.purchaseType || record.purchaseDetail) && (\n <div className=\"grid grid-cols-2 gap-4\">\n {record.purchaseType && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Purchase Type</p>\n <p className=\"text-sm\">{record.purchaseType}</p>\n </div>\n )}\n {record.purchaseDetail && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Purchase Detail</p>\n <p className=\"text-sm\">{record.purchaseDetail}</p>\n </div>\n )}\n </div>\n )}\n\n {record.reason && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Reason</p>\n <p className=\"text-sm\">{record.reason}</p>\n </div>\n )}\n\n {record.notes && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Notes</p>\n <p className=\"text-sm\">{record.notes}</p>\n </div>\n )}\n\n {record.errorMessage && (\n <div\n className={`p-3 ${statusTokens.error.bg} border ${statusTokens.error.border} rounded-md`}\n >\n <p className={`text-xs ${statusTokens.error.text} mb-1`}>Error Message</p>\n <p className={`text-sm ${statusTokens.error.text}`}>{record.errorMessage}</p>\n </div>\n )}\n\n <div className=\"grid grid-cols-2 gap-4 pt-2 border-t border-border\">\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Created At</p>\n <p className=\"text-sm\">{formatDateTime(record.createdAt)}</p>\n </div>\n {record.processedAt && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Processed At</p>\n <p className=\"text-sm\">{formatDateTime(record.processedAt)}</p>\n </div>\n )}\n </div>\n\n {record.retryCount > 0 && (\n <div>\n <p className=\"text-xs text-muted-foreground mb-1\">Retry Count</p>\n <p className=\"text-sm\">{record.retryCount}</p>\n </div>\n )}\n </div>\n\n <div className=\"p-4 border-t border-border\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"w-full py-2 px-4 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors\"\n >\n Close\n </button>\n </div>\n </div>\n </div>\n );\n};\n\n// ============================================================================\n// Main Component\n// ============================================================================\n\ntype TabStatus = 'PENDING' | 'COMPLETED' | 'FAILED' | 'ALL';\n\nconst TAB_CONFIG: Record<TabStatus, { label: string; status?: RefundRecordStatus }> = {\n PENDING: { label: 'Pending', status: 'PENDING' },\n COMPLETED: { label: 'Completed', status: 'COMPLETED' },\n FAILED: { label: 'Failed', status: 'FAILED' },\n ALL: { label: 'All', status: undefined },\n};\n\nexport const RefundsPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const permissions = useBillingPermissions();\n\n // State\n const [activeTab, setActiveTab] = useState<TabStatus>('PENDING');\n const [searchQuery, setSearchQuery] = useState('');\n const [filters, setFilters] = useState<RefundRecordFilters>({});\n const [showFilters, setShowFilters] = useState(false);\n const [selectedRecord, setSelectedRecord] = useState<RefundRecord | null>(null);\n const [showCreateModal, setShowCreateModal] = useState(false);\n const [showSkipModal, setShowSkipModal] = useState(false);\n const [recordToSkip, setRecordToSkip] = useState<RefundRecord | null>(null);\n const [actionLoadingId, setActionLoadingId] = useState<string | null>(null);\n\n // Build filters based on active tab - memoized to prevent infinite re-render loop\n // (useRefundRecords has a useEffect on options.filters, so a new object every render would cause\n // infinite updates if tabFilters were not stable)\n const tabFilters = useMemo<RefundRecordFilters>(\n () => ({\n ...filters,\n status: TAB_CONFIG[activeTab].status,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- filters is an object; spread ensures correct deps\n [\n activeTab,\n filters.source,\n filters.provider,\n filters.billingAccountId,\n filters.fromDate,\n filters.toDate,\n ]\n );\n\n // Data hooks - filters automatically applied based on active tab\n const {\n records,\n stats,\n pagination,\n isLoading,\n recordsError,\n unprocessedWebhooks,\n refetch,\n goToNextPage,\n goToPreviousPage,\n setFilters: updateFilters,\n createRefundRecord,\n processRefund,\n skipRefund,\n retryRefund,\n createRefundRecordsFromFailedWebhooks,\n isCreating,\n isProcessing,\n isCreatingFromWebhooks,\n } = useRefunds({ filters: tabFilters });\n\n // Permission check\n if (!permissions.canViewPayments) {\n return <AccessDenied message=\"You don't have permission to view refunds.\" />;\n }\n\n // Error handling\n if (recordsError && isServerError(recordsError)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title=\"Server Unavailable\"\n message=\"Unable to load refunds. The server might be down or experiencing issues.\"\n onRetry={() => refetch()}\n showRetry\n />\n </div>\n );\n }\n\n // Handlers\n const handleTabChange = (tab: TabStatus) => {\n setActiveTab(tab);\n // Reset filters when changing tabs\n setFilters({});\n setSearchQuery('');\n };\n\n const handleFilterChange = (key: keyof RefundRecordFilters, value: string | undefined) => {\n // Don't allow status filter changes as tabs control status\n if (key === 'status') return;\n\n const newFilters = { ...filters, [key]: value || undefined };\n setFilters(newFilters);\n updateFilters({ ...newFilters, status: TAB_CONFIG[activeTab].status });\n };\n\n const handleCreateRefund = async (data: CreateRefundFormData) => {\n try {\n await createRefundRecord(data);\n setShowCreateModal(false);\n } catch (error) {\n console.error('Failed to create refund:', error);\n }\n };\n\n const handleProcess = async (record: RefundRecord) => {\n setActionLoadingId(record.id);\n try {\n const result = await processRefund(record.id);\n if (!result.success && result.error) {\n console.error('Refund processing failed:', result.error);\n }\n } catch (error) {\n console.error('Failed to process refund:', error);\n } finally {\n setActionLoadingId(null);\n }\n };\n\n const handleSkip = async (reason: string) => {\n if (!recordToSkip) return;\n try {\n await skipRefund(recordToSkip.id, reason);\n setShowSkipModal(false);\n setRecordToSkip(null);\n } catch (error) {\n console.error('Failed to skip refund:', error);\n }\n };\n\n const handleRetry = async (record: RefundRecord) => {\n setActionLoadingId(record.id);\n try {\n const result = await retryRefund(record.id);\n if (!result.success && result.error) {\n console.error('Refund retry failed:', result.error);\n }\n } catch (error) {\n console.error('Failed to retry refund:', error);\n } finally {\n setActionLoadingId(null);\n }\n };\n\n const handleCreateFromWebhooks = async () => {\n try {\n await createRefundRecordsFromFailedWebhooks();\n } catch (error) {\n console.error('Failed to create refunds from webhooks:', error);\n }\n };\n\n // Filter records by search query (client-side)\n const filteredRecords = searchQuery\n ? records.filter(\n (r) =>\n r.gatewayPaymentId.toLowerCase().includes(searchQuery.toLowerCase()) ||\n r.gatewayOrderId?.toLowerCase().includes(searchQuery.toLowerCase()) ||\n r.reason?.toLowerCase().includes(searchQuery.toLowerCase())\n )\n : records;\n\n if (isLoading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"h-8 w-48 bg-muted animate-pulse rounded\" />\n <div className=\"grid grid-cols-5 gap-4\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"h-24 bg-muted animate-pulse rounded-lg\" />\n ))}\n </div>\n <div className=\"space-y-2\">\n {[1, 2, 3, 4, 5].map((i) => (\n <div key={i} className=\"h-16 bg-muted animate-pulse rounded\" />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={tr('billing.refunds.title', 'Refund Management')}\n description=\"View and manage refund records\"\n actions={\n <div className=\"flex items-center gap-2\">\n {unprocessedWebhooks.length > 0 && (\n <button\n type=\"button\"\n onClick={handleCreateFromWebhooks}\n disabled={isCreatingFromWebhooks}\n className={`inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md border ${statusTokens.warning.border} ${statusTokens.warning.bg} ${statusTokens.warning.text} hover:opacity-90 transition-colors disabled:opacity-50`}\n >\n {isCreatingFromWebhooks ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <Download className=\"size-4\" />\n )}\n Import {unprocessedWebhooks.length} Failed Webhooks\n </button>\n )}\n <button\n type=\"button\"\n onClick={() => refetch()}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md border border-border bg-background hover:bg-muted/50 transition-colors\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n <button\n type=\"button\"\n onClick={() => setShowCreateModal(true)}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md bg-primary text-primary-foreground hover:bg-primary/90 transition-colors\"\n >\n <Plus className=\"size-4\" />\n Create Manual Refund\n </button>\n </div>\n }\n />\n\n {/* Tabs Navigation */}\n <div className=\"border-b border-border\">\n <div className=\"flex flex-wrap gap-2 sm:gap-0\">\n {(Object.keys(TAB_CONFIG) as TabStatus[]).map((tab) => {\n const isActive = activeTab === tab;\n const count = stats\n ? tab === 'PENDING'\n ? stats.pending\n : tab === 'COMPLETED'\n ? stats.completed\n : tab === 'FAILED'\n ? stats.failed\n : stats.pending +\n stats.processing +\n stats.completed +\n stats.failed +\n stats.skipped\n : 0;\n\n return (\n <button\n type=\"button\"\n key={tab}\n onClick={() => handleTabChange(tab)}\n className={`flex items-center gap-2 px-4 py-3 text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${\n isActive\n ? 'border-primary text-primary'\n : 'border-transparent text-muted-foreground hover:text-foreground hover:border-border'\n }`}\n >\n {TAB_CONFIG[tab].label}\n {stats && (\n <span\n className={`px-2 py-0.5 text-xs rounded-full ${\n isActive ? 'bg-primary/10 text-primary' : 'bg-muted text-muted-foreground'\n }`}\n >\n {count}\n </span>\n )}\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col sm:flex-row gap-4\">\n {/* Search */}\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground\" />\n <input\n type=\"text\"\n placeholder=\"Search by payment ID, order ID, or reason...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full pl-[3.25rem] pr-4 py-2 border border-border rounded-md bg-background\"\n />\n </div>\n\n {/* Filter Toggle */}\n <button\n type=\"button\"\n onClick={() => setShowFilters(!showFilters)}\n className={`inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md border transition-colors ${\n showFilters\n ? 'border-primary bg-primary/10 text-primary'\n : 'border-border bg-background hover:bg-muted/50'\n }`}\n >\n <Filter className=\"size-4\" />\n Filters\n {Object.values(filters).filter(Boolean).length > 0 && (\n <span className=\"px-1.5 py-0.5 text-xs rounded-full bg-primary text-primary-foreground\">\n {Object.values(filters).filter(Boolean).length}\n </span>\n )}\n </button>\n\n {/* Clear Filters */}\n {Object.values(filters).filter(Boolean).length > 0 && (\n <button\n type=\"button\"\n onClick={() => {\n setFilters({});\n updateFilters({});\n }}\n className=\"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium rounded-md text-muted-foreground hover:text-foreground transition-colors\"\n >\n <X className=\"size-4\" />\n Clear\n </button>\n )}\n </div>\n\n {/* Expanded Filters */}\n {showFilters && (\n <div className=\"p-4 border border-border rounded-lg bg-muted/30 grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4\">\n <div>\n <label className=\"block text-sm font-medium mb-1\">Source</label>\n <select\n value={filters.source || ''}\n onChange={(e) => handleFilterChange('source', e.target.value)}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background\"\n >\n <option value=\"\">All Sources</option>\n {Object.entries(SOURCE_LABELS).map(([key, label]) => (\n <option key={key} value={key}>\n {label}\n </option>\n ))}\n </select>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium mb-1\">Provider</label>\n <select\n value={filters.provider || ''}\n onChange={(e) => handleFilterChange('provider', e.target.value)}\n className=\"w-full px-3 py-2 border border-border rounded-md bg-background\"\n >\n <option value=\"\">All Providers</option>\n {PROVIDER_OPTIONS.map((p) => (\n <option key={p} value={p}>\n {p.charAt(0).toUpperCase() + p.slice(1)}\n </option>\n ))}\n </select>\n </div>\n\n <div className=\"sm:col-span-2 lg:col-span-1\">\n <label className=\"block text-sm font-medium mb-1\">Date Range</label>\n <div className=\"flex flex-col sm:flex-row items-start sm:items-center gap-2\">\n <input\n type=\"date\"\n value={filters.fromDate ? filters.fromDate.split('T')[0] : ''}\n onChange={(e) =>\n handleFilterChange(\n 'fromDate',\n e.target.value ? new Date(e.target.value).toISOString() : undefined\n )\n }\n className=\"w-full sm:flex-1 p-2 border border-border rounded-md bg-background text-sm\"\n />\n <span className=\"text-muted-foreground hidden sm:inline\">-</span>\n <input\n type=\"date\"\n value={filters.toDate ? filters.toDate.split('T')[0] : ''}\n onChange={(e) =>\n handleFilterChange(\n 'toDate',\n e.target.value ? new Date(e.target.value).toISOString() : undefined\n )\n }\n className=\"w-full sm:flex-1 p-2 border border-border rounded-md bg-background text-sm\"\n />\n </div>\n </div>\n </div>\n )}\n\n {/* Table */}\n {filteredRecords.length === 0 ? (\n <EmptyState\n icon={<RefreshCw className=\"size-6 text-muted-foreground\" />}\n title=\"No refund records found\"\n description={\n Object.values(filters).filter(Boolean).length > 0\n ? 'Try adjusting your filters.'\n : activeTab === 'PENDING'\n ? 'No pending refunds to process.'\n : 'Refund records will appear here when created.'\n }\n />\n ) : (\n <div className=\"border border-border rounded-lg overflow-hidden\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[400px]\">\n <thead className=\"bg-muted/50\">\n <tr>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap\">\n Date\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap\">\n Status\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap hidden sm:table-cell\">\n Source\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap hidden md:table-cell\">\n Provider\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap\">\n Payment ID\n </th>\n <th className=\"text-right text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap\">\n Amount\n </th>\n <th className=\"text-left text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap hidden lg:table-cell\">\n Reason\n </th>\n <th className=\"p-2 w-10\"></th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {filteredRecords.map((record) => {\n const StatusIcon = STATUS_CONFIG[record.status].icon;\n return (\n <tr key={record.id} className=\"hover:bg-muted/30 transition-colors\">\n <td className=\"px-3 py-2 text-sm text-foreground whitespace-nowrap\">\n <div className=\"flex flex-col\">\n <span>{formatDateTime(record.createdAt).split(' ')[0]}</span>\n <span className=\"text-xs text-muted-foreground\">\n {formatDateTime(record.createdAt).split(' ')[1]}\n </span>\n </div>\n </td>\n <td className=\"px-3 py-2 whitespace-nowrap\">\n <span\n className={`inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded ${getStatusBadgeClasses(\n STATUS_CONFIG[record.status].color\n )}`}\n >\n <StatusIcon className=\"size-3\" />\n <span className=\"hidden sm:inline\">\n {STATUS_CONFIG[record.status].label}\n </span>\n </span>\n </td>\n <td className=\"px-3 py-2 text-sm text-muted-foreground whitespace-nowrap hidden sm:table-cell\">\n {SOURCE_LABELS[record.source]}\n </td>\n <td className=\"px-3 py-2 text-sm text-foreground capitalize whitespace-nowrap hidden md:table-cell\">\n {record.provider}\n </td>\n <td className=\"px-3 py-2 text-sm font-mono text-muted-foreground whitespace-nowrap max-w-[120px] sm:max-w-[200px] truncate\">\n {record.gatewayPaymentId}\n </td>\n <td className=\"px-3 py-2 text-sm text-right font-medium whitespace-nowrap\">\n {formatCurrency(record.amount, record.currency)}\n </td>\n <td className=\"px-3 py-2 text-sm text-muted-foreground max-w-[200px] truncate hidden lg:table-cell\">\n {record.reason || '-'}\n </td>\n <td className=\"p-2 text-center\">\n <RefundActionsDropdown\n record={record}\n onViewDetails={() => setSelectedRecord(record)}\n onProcess={() => handleProcess(record)}\n onSkip={() => {\n setRecordToSkip(record);\n setShowSkipModal(true);\n }}\n onRetry={() => handleRetry(record)}\n isProcessing={actionLoadingId === record.id}\n />\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n </div>\n )}\n\n {/* Pagination */}\n {pagination.totalCount > 0 && (\n <div className=\"flex flex-col sm:flex-row items-center justify-between gap-4 border-t border-border pt-4\">\n <p className=\"text-sm text-muted-foreground text-center sm:text-left\">\n Showing {pagination.page * pagination.pageSize + 1} to{' '}\n {Math.min((pagination.page + 1) * pagination.pageSize, pagination.totalCount)} of{' '}\n {pagination.totalCount} refunds\n </p>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={goToPreviousPage}\n disabled={!pagination.hasPrevious}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-md border border-border bg-background hover:bg-muted/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n <ChevronLeft className=\"size-4\" />\n <span className=\"hidden sm:inline\">Previous</span>\n </button>\n <span className=\"text-sm text-muted-foreground px-2\">\n <span className=\"hidden sm:inline\">Page </span>\n {pagination.page + 1} <span className=\"hidden sm:inline\">of</span>\n <span className=\"sm:hidden\">/</span>{' '}\n {Math.ceil(pagination.totalCount / pagination.pageSize)}\n </span>\n <button\n type=\"button\"\n onClick={goToNextPage}\n disabled={!pagination.hasMore}\n className=\"inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-md border border-border bg-background hover:bg-muted/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors\"\n >\n <span className=\"hidden sm:inline\">Next</span>\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n </div>\n )}\n\n {/* Modals */}\n <CreateRefundModal\n isOpen={showCreateModal}\n onClose={() => setShowCreateModal(false)}\n onSubmit={handleCreateRefund}\n isSubmitting={isCreating}\n />\n\n <SkipRefundModal\n isOpen={showSkipModal}\n record={recordToSkip}\n onClose={() => {\n setShowSkipModal(false);\n setRecordToSkip(null);\n }}\n onSubmit={handleSkip}\n isSubmitting={isProcessing}\n />\n\n <RefundDetailsModal record={selectedRecord} onClose={() => setSelectedRecord(null)} />\n </div>\n );\n};\n"],"mappings":"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"}
@@ -33,24 +33,27 @@ var F = {
33
33
  className: "relative overflow-visible",
34
34
  ref: o,
35
35
  children: [/* @__PURE__ */ M("button", {
36
+ type: "button",
36
37
  onClick: () => a(!i),
37
38
  className: "p-1.5 rounded-md hover:bg-muted/50 transition-colors",
38
39
  "aria-label": "Transaction actions",
39
- children: /* @__PURE__ */ M(E, { className: "w-4 h-4 text-muted-foreground" })
40
+ children: /* @__PURE__ */ M(E, { className: "size-4 text-muted-foreground" })
40
41
  }), i && /* @__PURE__ */ N("div", {
41
42
  className: "absolute right-0 top-full mt-1 z-50 min-w-[160px] bg-popover border border-border rounded-md shadow-lg py-1",
42
43
  children: [/* @__PURE__ */ N("button", {
44
+ type: "button",
43
45
  onClick: () => {
44
46
  t(), a(!1);
45
47
  },
46
48
  className: "w-full flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-muted/50 transition-colors whitespace-nowrap",
47
- children: [/* @__PURE__ */ M(C, { className: "w-4 h-4" }), "View Details"]
49
+ children: [/* @__PURE__ */ M(C, { className: "size-4" }), "View Details"]
48
50
  }), e.type === "payment" && r && /* @__PURE__ */ N("button", {
51
+ type: "button",
49
52
  onClick: () => {
50
53
  n(), a(!1);
51
54
  },
52
55
  className: "w-full flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-muted/50 transition-colors whitespace-nowrap",
53
- children: [/* @__PURE__ */ M(w, { className: "w-4 h-4" }), "View Invoice"]
56
+ children: [/* @__PURE__ */ M(w, { className: "size-4" }), "View Invoice"]
54
57
  })]
55
58
  })]
56
59
  });
@@ -75,10 +78,11 @@ var F = {
75
78
  className: "text-lg font-semibold",
76
79
  children: "Transaction Details"
77
80
  }), /* @__PURE__ */ M("button", {
81
+ type: "button",
78
82
  onClick: t,
79
83
  className: "p-1 rounded-md hover:bg-muted/50 transition-colors",
80
84
  "aria-label": "Close transaction details",
81
- children: /* @__PURE__ */ M(O, { className: "w-5 h-5" })
85
+ children: /* @__PURE__ */ M(O, { className: "size-5" })
82
86
  })]
83
87
  }),
84
88
  /* @__PURE__ */ N("div", {
@@ -187,19 +191,21 @@ var F = {
187
191
  children: ["Provider: ", c]
188
192
  }),
189
193
  r && n && /* @__PURE__ */ N("button", {
194
+ type: "button",
190
195
  onClick: () => n(e),
191
196
  className: "flex items-center gap-2 text-sm text-primary hover:underline",
192
- children: [/* @__PURE__ */ M(w, { className: "w-4 h-4" }), "View Invoice"]
197
+ children: [/* @__PURE__ */ M(w, { className: "size-4" }), "View Invoice"]
193
198
  })
194
199
  ]
195
200
  }),
196
201
  !_ && r && n && /* @__PURE__ */ M("div", {
197
202
  className: "p-3 bg-muted/50 rounded-lg",
198
203
  children: /* @__PURE__ */ N("button", {
204
+ type: "button",
199
205
  onClick: () => n(e),
200
206
  className: "flex items-center gap-2 text-sm text-primary hover:underline",
201
207
  children: [
202
- /* @__PURE__ */ M(w, { className: "w-4 h-4" }),
208
+ /* @__PURE__ */ M(w, { className: "size-4" }),
203
209
  "View Invoice ",
204
210
  c && `(${c})`
205
211
  ]
@@ -210,7 +216,7 @@ var F = {
210
216
  children: [
211
217
  /* @__PURE__ */ N("div", {
212
218
  className: "flex items-center gap-2",
213
- children: [/* @__PURE__ */ M("div", { className: "w-1.5 h-1.5 rounded-full bg-status-error-bg" }), /* @__PURE__ */ M("p", {
219
+ children: [/* @__PURE__ */ M("div", { className: "size-1.5 rounded-full bg-status-error-bg" }), /* @__PURE__ */ M("p", {
214
220
  className: "text-sm font-semibold text-status-error-text",
215
221
  children: "Refund Information"
216
222
  })]
@@ -224,11 +230,12 @@ var F = {
224
230
  className: "text-sm font-mono text-status-error-text",
225
231
  children: C
226
232
  })] }), T && /* @__PURE__ */ N("button", {
233
+ type: "button",
227
234
  onClick: () => {
228
235
  u("light"), d(T);
229
236
  },
230
237
  className: "flex items-center gap-2 text-sm text-status-error-text hover:underline",
231
- children: [/* @__PURE__ */ M(w, { className: "w-4 h-4" }), "Download Credit Note PDF"]
238
+ children: [/* @__PURE__ */ M(w, { className: "size-4" }), "Download Credit Note PDF"]
232
239
  })]
233
240
  }),
234
241
  D && /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
@@ -280,6 +287,7 @@ var F = {
280
287
  /* @__PURE__ */ M("div", {
281
288
  className: "p-4 border-t border-border",
282
289
  children: /* @__PURE__ */ M("button", {
290
+ type: "button",
283
291
  onClick: t,
284
292
  className: "w-full py-2 px-4 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors",
285
293
  children: "Close"
@@ -310,7 +318,7 @@ var F = {
310
318
  className: "p-6",
311
319
  children: /* @__PURE__ */ M(n, {
312
320
  icon: /* @__PURE__ */ M("svg", {
313
- className: "w-6 h-6 text-muted-foreground",
321
+ className: "size-6 text-muted-foreground",
314
322
  fill: "none",
315
323
  viewBox: "0 0 24 24",
316
324
  stroke: "currentColor",
@@ -351,9 +359,10 @@ var F = {
351
359
  className: "space-y-6 p-6",
352
360
  children: [
353
361
  /* @__PURE__ */ N("button", {
362
+ type: "button",
354
363
  onClick: () => O("/overview"),
355
364
  className: "inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors",
356
- children: [/* @__PURE__ */ M(_, { className: "w-4 h-4" }), "Back to Overview"]
365
+ children: [/* @__PURE__ */ M(_, { className: "size-4" }), "Back to Overview"]
357
366
  }),
358
367
  /* @__PURE__ */ M(t, {
359
368
  title: h("billing.transactions.title", "Transaction History"),
@@ -366,7 +375,7 @@ var F = {
366
375
  children: [
367
376
  /* @__PURE__ */ N("div", {
368
377
  className: "flex items-start gap-2",
369
- children: [/* @__PURE__ */ M(S, { className: "w-4 h-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [
378
+ children: [/* @__PURE__ */ M(S, { className: "size-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [
370
379
  /* @__PURE__ */ M("p", {
371
380
  className: "text-xs text-muted-foreground mb-0.5",
372
381
  children: "Account"
@@ -377,16 +386,16 @@ var F = {
377
386
  }),
378
387
  j.isActive ? /* @__PURE__ */ N("span", {
379
388
  className: "inline-flex items-center gap-1 mt-1 px-1.5 py-0.5 text-xs font-medium rounded bg-status-success-bg-subtle text-status-success-text",
380
- children: [/* @__PURE__ */ M(y, { className: "w-3 h-3" }), "Active"]
389
+ children: [/* @__PURE__ */ M(y, { className: "size-3" }), "Active"]
381
390
  }) : /* @__PURE__ */ N("span", {
382
391
  className: "inline-flex items-center gap-1 mt-1 px-1.5 py-0.5 text-xs font-medium rounded bg-status-error-bg-subtle text-status-error-text",
383
- children: [/* @__PURE__ */ M(k, { className: "w-3 h-3" }), "Inactive"]
392
+ children: [/* @__PURE__ */ M(k, { className: "size-3" }), "Inactive"]
384
393
  })
385
394
  ] })]
386
395
  }),
387
396
  /* @__PURE__ */ N("div", {
388
397
  className: "flex items-start gap-2",
389
- children: [/* @__PURE__ */ M(T, { className: "w-4 h-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
398
+ children: [/* @__PURE__ */ M(T, { className: "size-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
390
399
  className: "text-xs text-muted-foreground mb-0.5",
391
400
  children: "Email"
392
401
  }), /* @__PURE__ */ M("p", {
@@ -396,7 +405,7 @@ var F = {
396
405
  }),
397
406
  /* @__PURE__ */ N("div", {
398
407
  className: "flex items-start gap-2",
399
- children: [/* @__PURE__ */ M(D, { className: "w-4 h-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
408
+ children: [/* @__PURE__ */ M(D, { className: "size-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
400
409
  className: "text-xs text-muted-foreground mb-0.5",
401
410
  children: "Credits Balance"
402
411
  }), /* @__PURE__ */ N("p", {
@@ -406,7 +415,7 @@ var F = {
406
415
  }),
407
416
  /* @__PURE__ */ N("div", {
408
417
  className: "flex items-start gap-2",
409
- children: [/* @__PURE__ */ M(w, { className: "w-4 h-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
418
+ children: [/* @__PURE__ */ M(w, { className: "size-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
410
419
  className: "text-xs text-muted-foreground mb-0.5",
411
420
  children: "Tax ID"
412
421
  }), /* @__PURE__ */ M("p", {
@@ -416,7 +425,7 @@ var F = {
416
425
  }),
417
426
  /* @__PURE__ */ N("div", {
418
427
  className: "flex items-start gap-2",
419
- children: [/* @__PURE__ */ M(v, { className: "w-4 h-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
428
+ children: [/* @__PURE__ */ M(v, { className: "size-4 text-muted-foreground mt-0.5" }), /* @__PURE__ */ N("div", { children: [/* @__PURE__ */ M("p", {
420
429
  className: "text-xs text-muted-foreground mb-0.5",
421
430
  children: "Member Since"
422
431
  }), /* @__PURE__ */ M("p", {
@@ -437,6 +446,7 @@ var F = {
437
446
  "refund",
438
447
  "adjustment"
439
448
  ].map((e) => /* @__PURE__ */ M("button", {
449
+ type: "button",
440
450
  onClick: () => q(e),
441
451
  className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${K === e ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
442
452
  children: e === "all" ? "All" : F[e]
@@ -445,7 +455,7 @@ var F = {
445
455
  }),
446
456
  $.length === 0 ? /* @__PURE__ */ M(n, {
447
457
  icon: /* @__PURE__ */ M("svg", {
448
- className: "w-6 h-6 text-muted-foreground",
458
+ className: "size-6 text-muted-foreground",
449
459
  fill: "none",
450
460
  viewBox: "0 0 24 24",
451
461
  stroke: "currentColor",
@@ -485,7 +495,7 @@ var F = {
485
495
  className: "text-center text-sm font-medium text-muted-foreground px-3 py-2 whitespace-nowrap",
486
496
  children: "Status"
487
497
  }),
488
- /* @__PURE__ */ M("th", { className: "px-2 py-2 w-10" })
498
+ /* @__PURE__ */ M("th", { className: "p-2 w-10" })
489
499
  ] })
490
500
  }), /* @__PURE__ */ M("tbody", {
491
501
  className: "divide-y divide-border",
@@ -516,7 +526,7 @@ var F = {
516
526
  })
517
527
  }),
518
528
  /* @__PURE__ */ M("td", {
519
- className: "px-2 py-2 text-center",
529
+ className: "p-2 text-center",
520
530
  children: /* @__PURE__ */ M(L, {
521
531
  transaction: e,
522
532
  onViewDetails: () => Y(e),
@@ -548,10 +558,11 @@ var F = {
548
558
  className: "flex items-center gap-2",
549
559
  children: [
550
560
  /* @__PURE__ */ N("button", {
561
+ type: "button",
551
562
  onClick: G,
552
563
  disabled: !B.hasPrevious,
553
564
  className: "inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-md border border-border bg-background hover:bg-muted/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
554
- children: [/* @__PURE__ */ M(b, { className: "w-4 h-4" }), "Previous"]
565
+ children: [/* @__PURE__ */ M(b, { className: "size-4" }), "Previous"]
555
566
  }),
556
567
  /* @__PURE__ */ N("span", {
557
568
  className: "text-sm text-muted-foreground px-2",
@@ -563,10 +574,11 @@ var F = {
563
574
  ]
564
575
  }),
565
576
  /* @__PURE__ */ N("button", {
577
+ type: "button",
566
578
  onClick: W,
567
579
  disabled: !B.hasMore,
568
580
  className: "inline-flex items-center gap-1 px-3 py-1.5 text-sm font-medium rounded-md border border-border bg-background hover:bg-muted/50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors",
569
- children: ["Next", /* @__PURE__ */ M(x, { className: "w-4 h-4" })]
581
+ children: ["Next", /* @__PURE__ */ M(x, { className: "size-4" })]
570
582
  })
571
583
  ]
572
584
  })]