@burdenoff/microfe-billing 2026.515.4 → 2026.515.6

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.
@@ -1 +1 @@
1
- {"version":3,"file":"PayoutAdminPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/PayoutAdminPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type FC } from 'react';\nimport { AlertTriangle, CheckCircle2, PlayCircle, RefreshCw, XCircle } from 'lucide-react';\n\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport {\n AccessDenied,\n EmptyState,\n PageHeader,\n ServerError,\n StatCard,\n} from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport {\n approvePayoutRequest,\n fetchAdminPayoutRequests,\n fetchAdminPayoutSummary,\n processPayoutRequest,\n rejectPayoutRequest,\n type PayoutAdminSummary,\n type PayoutRequest,\n} from '../api';\n\nexport const PayoutAdminPage: FC = () => {\n const permissions = useBillingPermissions();\n const { emit } = useBillingEventEmitter();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n\n const [summary, setSummary] = useState<PayoutAdminSummary | null>(null);\n const [requests, setRequests] = useState<PayoutRequest[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const requestContext = useMemo(\n () => ({\n apiGatewayUrl,\n authToken,\n orgId,\n }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadData = async () => {\n setLoading(true);\n setError(null);\n try {\n const [loadedSummary, loadedRequests] = await Promise.all([\n fetchAdminPayoutSummary(requestContext),\n fetchAdminPayoutRequests(requestContext),\n ]);\n setSummary(loadedSummary);\n setRequests(loadedRequests);\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load payout queue'));\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n void loadData();\n }, [requestContext]);\n\n if (!permissions.isBillingAdmin) {\n return <AccessDenied message=\"You don't have permission to manage payouts.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Payout queue unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const cards = summary\n ? [\n {\n title: 'Requested',\n value: formatCurrency(summary.totalRequestedAmount, 'USD'),\n icon: <AlertTriangle className=\"h-5 w-5\" />,\n },\n {\n title: 'Processing',\n value: formatCurrency(summary.totalProcessingAmount, 'USD'),\n icon: <PlayCircle className=\"h-5 w-5\" />,\n },\n {\n title: 'Paid',\n value: formatCurrency(summary.totalPaidAmount, 'USD'),\n icon: <CheckCircle2 className=\"h-5 w-5\" />,\n },\n { title: 'Failed', value: summary.failedCount, icon: <XCircle className=\"h-5 w-5\" /> },\n ]\n : [];\n\n const handleApprove = async (requestId: string) => {\n const notes = window.prompt('Approval notes (optional)') ?? null;\n await approvePayoutRequest(requestId, notes, requestContext);\n emit('billing.payout.approved', {\n route: '/billing/payouts',\n entityId: requestId,\n source: 'payout-admin',\n });\n await loadData();\n };\n\n const handleReject = async (requestId: string) => {\n const reason = window.prompt('Reason for rejection');\n if (!reason) return;\n await rejectPayoutRequest(requestId, reason, requestContext);\n emit('billing.payout.rejected', {\n route: '/billing/payouts',\n entityId: requestId,\n source: 'payout-admin',\n reason,\n });\n await loadData();\n };\n\n const handleProcess = async (requestId: string) => {\n await processPayoutRequest(requestId, requestContext);\n emit('billing.payout.processed', {\n route: '/billing/payouts',\n entityId: requestId,\n source: 'payout-admin',\n });\n await loadData();\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Payout queue\"\n description=\"Approve, reject, and process payout requests across all earnings sources.\"\n actions={\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground\"\n >\n <RefreshCw className=\"h-4 w-4\" />\n Refresh\n </button>\n }\n />\n\n {loading ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {[1, 2, 3, 4].map((item) => (\n <div\n key={item}\n className=\"h-28 animate-pulse rounded-lg border border-border bg-card\"\n />\n ))}\n </div>\n ) : summary ? (\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {cards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n <div className=\"grid gap-4 xl:grid-cols-2\">\n <div className=\"rounded-lg border border-border bg-card p-4\">\n <h3 className=\"mb-3 text-sm font-semibold text-foreground\">Status breakdown</h3>\n <div className=\"space-y-2 text-sm\">\n {(summary.statusBreakdown || []).map((item) => (\n <div key={item.status} className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground\">{item.status}</span>\n <span className=\"font-medium text-foreground\">\n {item.count} · {formatCurrency(item.totalAmount, 'USD')}\n </span>\n </div>\n ))}\n </div>\n </div>\n <div className=\"rounded-lg border border-border bg-card p-4\">\n <h3 className=\"mb-3 text-sm font-semibold text-foreground\">Provider breakdown</h3>\n <div className=\"space-y-2 text-sm\">\n {(summary.providerBreakdown || []).map((item) => (\n <div key={item.provider} className=\"flex items-center justify-between\">\n <span className=\"text-muted-foreground\">{item.provider}</span>\n <span className=\"font-medium text-foreground\">\n {item.count} · {formatCurrency(item.totalAmount, 'USD')}\n </span>\n </div>\n ))}\n </div>\n </div>\n </div>\n </div>\n ) : null}\n\n {error && !isServerError(error) ? (\n <div className=\"rounded-lg border border-border bg-card p-4 text-sm text-destructive\">\n {error.message}\n </div>\n ) : null}\n\n <section className=\"rounded-lg border border-border bg-card p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-foreground\">Requests</h2>\n {requests.length === 0 && !loading ? (\n <EmptyState\n icon={<PlayCircle className=\"h-8 w-8\" />}\n title=\"No payout requests\"\n description=\"New payout requests will appear in this queue.\"\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border text-left text-muted-foreground\">\n <th className=\"px-3 py-2\">Amount</th>\n <th className=\"px-3 py-2\">Provider</th>\n <th className=\"px-3 py-2\">Status</th>\n <th className=\"px-3 py-2\">Account</th>\n <th className=\"px-3 py-2\">Created</th>\n <th className=\"px-3 py-2\">Actions</th>\n </tr>\n </thead>\n <tbody>\n {requests.map((request) => (\n <tr key={request.id} className=\"border-b border-border/70 text-foreground\">\n <td className=\"px-3 py-2 font-medium\">\n {formatCurrency(request.requestedAmount, request.currency)}\n </td>\n <td className=\"px-3 py-2\">{request.provider}</td>\n <td className=\"px-3 py-2\">{request.status}</td>\n <td className=\"px-3 py-2\">{request.payoutAccount?.label || '-'}</td>\n <td className=\"px-3 py-2\">{formatDateTime(request.createdAt)}</td>\n <td className=\"px-3 py-2\">\n <div className=\"flex flex-wrap gap-2\">\n {request.status === 'REQUESTED' || request.status === 'REJECTED' ? (\n <button\n type=\"button\"\n onClick={() => void handleApprove(request.id)}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-foreground\"\n >\n Approve\n </button>\n ) : null}\n {request.status === 'REQUESTED' || request.status === 'APPROVED' ? (\n <button\n type=\"button\"\n onClick={() => void handleReject(request.id)}\n className=\"rounded-md border border-border px-3 py-1.5 text-xs font-medium text-destructive\"\n >\n Reject\n </button>\n ) : null}\n {request.status === 'APPROVED' ? (\n <button\n type=\"button\"\n onClick={() => void handleProcess(request.id)}\n className=\"rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground\"\n >\n Process\n </button>\n ) : null}\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PayoutAdminPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/PayoutAdminPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type FC } from 'react';\nimport {\n AlertTriangle,\n Banknote,\n CheckCircle2,\n ChevronDown,\n ChevronUp,\n Clock,\n CreditCard,\n RefreshCw,\n ReceiptText,\n XCircle,\n} from 'lucide-react';\n\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useBillingEventEmitter } from '../../../hooks/useBillingEventEmitter';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { AccessDenied, EmptyState, PageHeader, ServerError } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport {\n approvePayoutRequest,\n fetchAdminPayoutRequests,\n fetchAdminPayoutSummary,\n markPayoutPaid,\n rejectPayoutRequest,\n type PayoutAdminSummary,\n type PayoutRequest,\n} from '../api';\n\ntype Tab = 'pending' | 'approved' | 'history';\n\ninterface ActionDialogState {\n type: 'approve' | 'reject' | 'mark_paid';\n requestId: string;\n amount: number;\n currency: string;\n accountLabel: string;\n}\n\nconst STATUS_LABEL: Record<string, string> = {\n REQUESTED: 'Requested',\n APPROVED: 'Approved',\n REJECTED: 'Rejected',\n PROCESSING: 'Processing',\n PAID: 'Paid',\n FAILED: 'Failed',\n CANCELED: 'Canceled',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n REQUESTED: 'bg-warning-surface text-warning-foreground',\n APPROVED: 'bg-info-surface text-info-foreground',\n REJECTED: 'bg-destructive/10 text-destructive',\n PROCESSING: 'bg-info-surface text-info-foreground',\n PAID: 'bg-success-surface text-success-foreground',\n FAILED: 'bg-destructive/10 text-destructive',\n CANCELED: 'bg-muted text-muted-foreground',\n};\n\nfunction StatusBadge({ status }: { status: string }) {\n return (\n <span\n className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${STATUS_COLORS[status] ?? 'bg-muted text-muted-foreground'}`}\n >\n {STATUS_LABEL[status] ?? status}\n </span>\n );\n}\n\nfunction AccountDetails({ account }: { account: NonNullable<PayoutRequest['payoutAccount']> }) {\n const [expanded, setExpanded] = useState(false);\n const details = account.accountDetails as Record<string, string | null> | null;\n\n return (\n <div className=\"rounded-md border border-border bg-muted/40 p-3 text-sm\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2 text-foreground font-medium\">\n <CreditCard className=\"h-4 w-4 text-muted-foreground\" />\n {account.displayName ?? account.label}\n <span className=\"text-xs text-muted-foreground font-normal\">\n ({account.type === 'UPI' ? 'UPI' : 'Bank'} · {account.country ?? 'Unknown'} ·{' '}\n {account.currency})\n </span>\n </div>\n {details && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"text-muted-foreground hover:text-foreground\"\n >\n {expanded ? <ChevronUp className=\"h-4 w-4\" /> : <ChevronDown className=\"h-4 w-4\" />}\n </button>\n )}\n </div>\n {expanded && details && (\n <div className=\"mt-2 grid gap-1 text-xs\">\n {details.accountHolderName && (\n <div className=\"flex gap-2\">\n <span className=\"text-muted-foreground w-32 shrink-0\">Account holder</span>\n <span className=\"text-foreground\">{details.accountHolderName}</span>\n </div>\n )}\n {details.bankName && (\n <div className=\"flex gap-2\">\n <span className=\"text-muted-foreground w-32 shrink-0\">Bank</span>\n <span className=\"text-foreground\">{details.bankName}</span>\n </div>\n )}\n {account.accountLast4 && (\n <div className=\"flex gap-2\">\n <span className=\"text-muted-foreground w-32 shrink-0\">Account (last 4)</span>\n <span className=\"text-foreground font-mono\">••••{account.accountLast4}</span>\n </div>\n )}\n {details.ifsc && (\n <div className=\"flex gap-2\">\n <span className=\"text-muted-foreground w-32 shrink-0\">IFSC</span>\n <span className=\"text-foreground font-mono\">{details.ifsc}</span>\n </div>\n )}\n {details.routingNumberLast4 && (\n <div className=\"flex gap-2\">\n <span className=\"text-muted-foreground w-32 shrink-0\">Routing (last 4)</span>\n <span className=\"text-foreground font-mono\">••••{details.routingNumberLast4}</span>\n </div>\n )}\n {details.upiIdMasked && (\n <div className=\"flex gap-2\">\n <span className=\"text-muted-foreground w-32 shrink-0\">UPI ID</span>\n <span className=\"text-foreground font-mono\">{details.upiIdMasked}</span>\n </div>\n )}\n {details.swift && (\n <div className=\"flex gap-2\">\n <span className=\"text-muted-foreground w-32 shrink-0\">SWIFT</span>\n <span className=\"text-foreground font-mono\">{details.swift}</span>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction RequestCard({\n request,\n onApprove,\n onReject,\n onMarkPaid,\n}: {\n request: PayoutRequest;\n onApprove: (r: PayoutRequest) => void;\n onReject: (r: PayoutRequest) => void;\n onMarkPaid: (r: PayoutRequest) => void;\n}) {\n const canApprove = request.status === 'REQUESTED' || request.status === 'REJECTED';\n const canReject = request.status === 'REQUESTED' || request.status === 'APPROVED';\n const canMarkPaid = request.status === 'APPROVED' || request.status === 'PROCESSING';\n\n return (\n <div className=\"rounded-lg border border-border bg-card p-5 space-y-4\">\n {/* Header row */}\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xl font-semibold text-foreground\">\n {formatCurrency(request.requestedAmount, request.currency)}\n </span>\n <StatusBadge status={request.status} />\n </div>\n <div className=\"text-xs text-muted-foreground space-x-2\">\n <span>Requested {formatDateTime(request.createdAt)}</span>\n {request.requesterUserId && (\n <>\n <span>·</span>\n <span>by {request.requesterUserId}</span>\n </>\n )}\n <span>·</span>\n <span className=\"font-mono text-xs\">{request.id.slice(0, 8)}…</span>\n </div>\n </div>\n <div className=\"flex flex-wrap gap-2\">\n {canApprove && (\n <button\n type=\"button\"\n onClick={() => onApprove(request)}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground\"\n >\n <CheckCircle2 className=\"h-3.5 w-3.5\" />\n Approve\n </button>\n )}\n {canMarkPaid && (\n <button\n type=\"button\"\n onClick={() => onMarkPaid(request)}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-success-surface border border-success-border px-3 py-1.5 text-xs font-medium text-success-foreground\"\n >\n <Banknote className=\"h-3.5 w-3.5\" />\n Mark as Paid\n </button>\n )}\n {canReject && (\n <button\n type=\"button\"\n onClick={() => onReject(request)}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-1.5 text-xs font-medium text-destructive\"\n >\n <XCircle className=\"h-3.5 w-3.5\" />\n Reject\n </button>\n )}\n </div>\n </div>\n\n {/* Payout account */}\n {request.payoutAccount && <AccountDetails account={request.payoutAccount} />}\n\n {/* User notes */}\n {request.userNotes && (\n <div className=\"rounded-md bg-muted/40 border border-border px-3 py-2 text-sm\">\n <span className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n User note\n </span>\n <p className=\"mt-1 text-foreground\">{request.userNotes}</p>\n </div>\n )}\n\n {/* Internal notes / failure / ref */}\n {(request.internalNotes ?? request.failureReason ?? request.externalReference) && (\n <div className=\"grid gap-1 text-xs text-muted-foreground\">\n {request.externalReference && (\n <div className=\"flex gap-2\">\n <ReceiptText className=\"h-3.5 w-3.5 mt-px shrink-0\" />\n <span>\n Ref: <span className=\"font-mono text-foreground\">{request.externalReference}</span>\n </span>\n </div>\n )}\n {request.internalNotes && (\n <div className=\"flex gap-2\">\n <span className=\"shrink-0\">Internal note:</span>\n <span className=\"text-foreground\">{request.internalNotes}</span>\n </div>\n )}\n {request.failureReason && (\n <div className=\"flex gap-2 text-destructive\">\n <AlertTriangle className=\"h-3.5 w-3.5 mt-px shrink-0\" />\n <span>{request.failureReason}</span>\n </div>\n )}\n </div>\n )}\n\n {/* Timestamps */}\n {(request.paidAt ?? request.processedAt) && (\n <div className=\"flex flex-wrap gap-4 text-xs text-muted-foreground\">\n {request.processedAt && (\n <span className=\"flex items-center gap-1\">\n <Clock className=\"h-3 w-3\" />\n Processed {formatDateTime(request.processedAt)}\n </span>\n )}\n {request.paidAt && (\n <span className=\"flex items-center gap-1\">\n <CheckCircle2 className=\"h-3 w-3\" />\n Paid {formatDateTime(request.paidAt)}\n </span>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction SummaryBar({ summary }: { summary: PayoutAdminSummary }) {\n return (\n <div className=\"grid gap-3 sm:grid-cols-3\">\n <div className=\"rounded-lg border border-border bg-card p-4\">\n <div className=\"text-xs text-muted-foreground uppercase tracking-wide\">Pending payout</div>\n <div className=\"mt-1 text-lg font-semibold text-foreground\">\n {formatCurrency(summary.totalRequestedAmount, 'USD')}\n </div>\n <div className=\"text-xs text-muted-foreground mt-0.5\">{summary.pendingCount} requests</div>\n </div>\n <div className=\"rounded-lg border border-border bg-card p-4\">\n <div className=\"text-xs text-muted-foreground uppercase tracking-wide\">Processing</div>\n <div className=\"mt-1 text-lg font-semibold text-foreground\">\n {formatCurrency(summary.totalProcessingAmount, 'USD')}\n </div>\n </div>\n <div className=\"rounded-lg border border-border bg-card p-4\">\n <div className=\"text-xs text-muted-foreground uppercase tracking-wide\">Total paid</div>\n <div className=\"mt-1 text-lg font-semibold text-foreground\">\n {formatCurrency(summary.totalPaidAmount, 'USD')}\n </div>\n {summary.failedCount > 0 && (\n <div className=\"text-xs text-destructive mt-0.5\">{summary.failedCount} failed</div>\n )}\n </div>\n </div>\n );\n}\n\nfunction ActionDialog({\n dialog,\n onClose,\n onConfirm,\n}: {\n dialog: ActionDialogState;\n onClose: () => void;\n onConfirm: (data: {\n notes?: string;\n reason?: string;\n externalReference?: string;\n }) => Promise<void>;\n}) {\n const [notes, setNotes] = useState('');\n const [reason, setReason] = useState('');\n const [txnRef, setTxnRef] = useState('');\n const [submitting, setSubmitting] = useState(false);\n\n const handleSubmit = async () => {\n if (dialog.type === 'reject' && !reason.trim()) return;\n setSubmitting(true);\n await onConfirm({\n notes: notes.trim() || undefined,\n reason: reason.trim() || undefined,\n externalReference: txnRef.trim() || undefined,\n });\n setSubmitting(false);\n };\n\n const titles = {\n approve: 'Approve withdrawal request',\n reject: 'Reject withdrawal request',\n mark_paid: 'Mark as paid',\n };\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4\">\n <div className=\"w-full max-w-md rounded-lg border border-border bg-card p-6 shadow-lg space-y-4\">\n <div>\n <h3 className=\"text-base font-semibold text-foreground\">{titles[dialog.type]}</h3>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {formatCurrency(dialog.amount, dialog.currency)} · {dialog.accountLabel}\n </p>\n </div>\n\n {dialog.type === 'mark_paid' && (\n <div className=\"space-y-3\">\n <div>\n <label className=\"text-xs font-medium text-foreground block mb-1\">\n Transaction reference / UTR number\n </label>\n <input\n type=\"text\"\n value={txnRef}\n onChange={(e) => setTxnRef(e.target.value)}\n placeholder=\"e.g. UTR123456789012, TXN_abc123\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n <p className=\"text-xs text-muted-foreground mt-1\">\n Enter the bank reference number so the user can verify the transfer.\n </p>\n </div>\n <div>\n <label className=\"text-xs font-medium text-foreground block mb-1\">\n Internal notes (optional)\n </label>\n <textarea\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n rows={2}\n placeholder=\"Any internal notes about this payment…\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring resize-none\"\n />\n </div>\n </div>\n )}\n\n {dialog.type === 'approve' && (\n <div>\n <label className=\"text-xs font-medium text-foreground block mb-1\">\n Internal notes (optional)\n </label>\n <textarea\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n rows={3}\n placeholder=\"e.g. Verified bank details, approved for transfer…\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring resize-none\"\n />\n </div>\n )}\n\n {dialog.type === 'reject' && (\n <div>\n <label className=\"text-xs font-medium text-foreground block mb-1\">\n Reason for rejection <span className=\"text-destructive\">*</span>\n </label>\n <textarea\n value={reason}\n onChange={(e) => setReason(e.target.value)}\n rows={3}\n placeholder=\"e.g. Invalid bank details provided, please re-submit with correct IFSC…\"\n className=\"w-full rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring resize-none\"\n />\n </div>\n )}\n\n <div className=\"flex justify-end gap-2 pt-2\">\n <button\n type=\"button\"\n onClick={onClose}\n disabled={submitting}\n className=\"rounded-md border border-border px-4 py-2 text-sm font-medium text-foreground disabled:opacity-50\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={() => void handleSubmit()}\n disabled={submitting || (dialog.type === 'reject' && !reason.trim())}\n className={`rounded-md px-4 py-2 text-sm font-medium disabled:opacity-50 ${\n dialog.type === 'reject'\n ? 'bg-destructive text-destructive-foreground'\n : 'bg-primary text-primary-foreground'\n }`}\n >\n {submitting\n ? 'Saving…'\n : dialog.type === 'approve'\n ? 'Approve'\n : dialog.type === 'reject'\n ? 'Reject'\n : 'Confirm Payment'}\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nexport const PayoutAdminPage: FC = () => {\n const permissions = useBillingPermissions();\n const { emit } = useBillingEventEmitter();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n\n const [summary, setSummary] = useState<PayoutAdminSummary | null>(null);\n const [requests, setRequests] = useState<PayoutRequest[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [activeTab, setActiveTab] = useState<Tab>('pending');\n const [dialog, setDialog] = useState<ActionDialogState | null>(null);\n\n const requestContext = useMemo(\n () => ({ apiGatewayUrl, authToken, orgId }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadData = async () => {\n setLoading(true);\n setError(null);\n try {\n const [loadedSummary, loadedRequests] = await Promise.all([\n fetchAdminPayoutSummary(requestContext),\n fetchAdminPayoutRequests(requestContext),\n ]);\n setSummary(loadedSummary);\n setRequests(loadedRequests);\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load payout queue'));\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n void loadData();\n }, [requestContext]);\n\n if (!permissions.isBillingAdmin) {\n return <AccessDenied message=\"You don't have permission to manage payouts.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Payout queue unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const pending = requests.filter((r) => r.status === 'REQUESTED');\n const approved = requests.filter((r) => r.status === 'APPROVED' || r.status === 'PROCESSING');\n const history = requests.filter((r) =>\n ['PAID', 'REJECTED', 'FAILED', 'CANCELED'].includes(r.status)\n );\n\n const tabItems: { id: Tab; label: string; count: number }[] = [\n { id: 'pending', label: 'Pending', count: pending.length },\n { id: 'approved', label: 'Approved', count: approved.length },\n { id: 'history', label: 'History', count: history.length },\n ];\n\n const visibleRequests =\n activeTab === 'pending' ? pending : activeTab === 'approved' ? approved : history;\n\n const openDialog = (type: ActionDialogState['type'], request: PayoutRequest) => {\n setDialog({\n type,\n requestId: request.id,\n amount: request.requestedAmount,\n currency: request.currency,\n accountLabel:\n request.payoutAccount?.displayName ?? request.payoutAccount?.label ?? 'Unknown account',\n });\n };\n\n const handleConfirm = async (data: {\n notes?: string;\n reason?: string;\n externalReference?: string;\n }) => {\n if (!dialog) return;\n\n try {\n if (dialog.type === 'approve') {\n await approvePayoutRequest(dialog.requestId, data.notes ?? null, requestContext);\n emit('billing.payout.approved', {\n route: '/billing/payouts',\n entityId: dialog.requestId,\n source: 'payout-admin',\n });\n } else if (dialog.type === 'reject') {\n await rejectPayoutRequest(dialog.requestId, data.reason ?? '', requestContext);\n emit('billing.payout.rejected', {\n route: '/billing/payouts',\n entityId: dialog.requestId,\n source: 'payout-admin',\n reason: data.reason,\n });\n } else if (dialog.type === 'mark_paid') {\n await markPayoutPaid(\n dialog.requestId,\n data.externalReference ?? null,\n data.notes ?? null,\n requestContext\n );\n emit('billing.payout.processed', {\n route: '/billing/payouts',\n entityId: dialog.requestId,\n source: 'payout-admin',\n });\n }\n setDialog(null);\n await loadData();\n } catch (err) {\n setError(err instanceof Error ? err : new Error('Action failed'));\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Payout queue\"\n description=\"Review withdrawal requests, verify bank details, and mark payments as paid once transferred.\"\n actions={\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground\"\n >\n <RefreshCw className={`h-4 w-4 ${loading ? 'animate-spin' : ''}`} />\n Refresh\n </button>\n }\n />\n\n {summary && !loading && <SummaryBar summary={summary} />}\n\n {loading && (\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"h-20 animate-pulse rounded-lg border border-border bg-card\" />\n ))}\n </div>\n )}\n\n {error && !isServerError(error) && (\n <div className=\"rounded-lg border border-destructive/30 bg-destructive/10 p-4 text-sm text-destructive\">\n {error.message}\n </div>\n )}\n\n {/* Tabs */}\n <div className=\"border-b border-border\">\n <div className=\"flex gap-0\">\n {tabItems.map((tab) => (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={`flex items-center gap-2 border-b-2 px-4 py-2.5 text-sm font-medium transition-colors ${\n activeTab === tab.id\n ? 'border-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {tab.label}\n {tab.count > 0 && (\n <span\n className={`rounded-full px-1.5 py-0.5 text-xs ${\n activeTab === tab.id\n ? 'bg-primary text-primary-foreground'\n : 'bg-muted text-muted-foreground'\n }`}\n >\n {tab.count}\n </span>\n )}\n </button>\n ))}\n </div>\n </div>\n\n {/* How to pay — shown only on the Approved tab */}\n {activeTab === 'approved' && approved.length > 0 && (\n <div className=\"rounded-lg border border-info-border bg-info-surface px-4 py-3 text-sm text-info-foreground\">\n <strong>How to pay:</strong> Click the account row to expand bank/UPI details → transfer\n the exact amount via your bank → click <strong>Mark as Paid</strong> and enter the UTR /\n transaction reference number.\n </div>\n )}\n\n {/* Request cards */}\n {loading ? (\n <div className=\"space-y-4\">\n {[1, 2].map((i) => (\n <div key={i} className=\"h-40 animate-pulse rounded-lg border border-border bg-card\" />\n ))}\n </div>\n ) : visibleRequests.length === 0 ? (\n <EmptyState\n icon={<CheckCircle2 className=\"h-8 w-8\" />}\n title={\n activeTab === 'pending'\n ? 'No pending requests'\n : activeTab === 'approved'\n ? 'No approved requests awaiting payment'\n : 'No history yet'\n }\n description={\n activeTab === 'pending'\n ? 'New withdrawal requests will appear here.'\n : activeTab === 'approved'\n ? 'Approve pending requests first, then send payment and mark as paid.'\n : 'Completed and rejected requests will appear here.'\n }\n />\n ) : (\n <div className=\"space-y-4\">\n {visibleRequests.map((request) => (\n <RequestCard\n key={request.id}\n request={request}\n onApprove={(r) => openDialog('approve', r)}\n onReject={(r) => openDialog('reject', r)}\n onMarkPaid={(r) => openDialog('mark_paid', r)}\n />\n ))}\n </div>\n )}\n\n {dialog && (\n <ActionDialog dialog={dialog} onClose={() => setDialog(null)} onConfirm={handleConfirm} />\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -3349,6 +3349,22 @@ export type ArchivePayoutAccountMutation = {
3349
3349
  __typename?: 'Mutation';
3350
3350
  archivePayoutAccount: boolean;
3351
3351
  };
3352
+ export type MarkPayoutPaidMutationVariables = Types.Exact<{
3353
+ id: Types.Scalars['ID']['input'];
3354
+ externalReference?: Types.InputMaybe<Types.Scalars['String']['input']>;
3355
+ notes?: Types.InputMaybe<Types.Scalars['String']['input']>;
3356
+ }>;
3357
+ export type MarkPayoutPaidMutation = {
3358
+ __typename?: 'Mutation';
3359
+ markPayoutPaid: {
3360
+ __typename?: 'PayoutRequest';
3361
+ id: string;
3362
+ status: Types.PayoutRequestStatus;
3363
+ externalReference?: string | null;
3364
+ internalNotes?: string | null;
3365
+ paidAt?: string | null;
3366
+ };
3367
+ };
3352
3368
  export type ProcessPayoutRequestMutationVariables = Types.Exact<{
3353
3369
  id: Types.Scalars['ID']['input'];
3354
3370
  }>;
@@ -3403,6 +3419,8 @@ export type AdminPayoutRequestsQuery = {
3403
3419
  items: Array<{
3404
3420
  __typename?: 'PayoutRequest';
3405
3421
  id: string;
3422
+ billingAccountId: string;
3423
+ requesterUserId?: string | null;
3406
3424
  requestedAmount: number;
3407
3425
  approvedAmount?: number | null;
3408
3426
  currency: string;
@@ -3427,6 +3445,7 @@ export type AdminPayoutRequestsQuery = {
3427
3445
  country?: string | null;
3428
3446
  currency: string;
3429
3447
  isDefault: boolean;
3448
+ accountDetails?: Record<string, unknown> | null;
3430
3449
  } | null;
3431
3450
  }>;
3432
3451
  };
@@ -7859,6 +7878,31 @@ export declare function useArchivePayoutAccountMutation(baseOptions?: ApolloReac
7859
7878
  export type ArchivePayoutAccountMutationHookResult = ReturnType<typeof useArchivePayoutAccountMutation>;
7860
7879
  export type ArchivePayoutAccountMutationResult = Apollo.MutationResult<Types.ArchivePayoutAccountMutation>;
7861
7880
  export type ArchivePayoutAccountMutationOptions = Apollo.BaseMutationOptions<Types.ArchivePayoutAccountMutation, Types.ArchivePayoutAccountMutationVariables>;
7881
+ export declare const MarkPayoutPaidDocument: Apollo.DocumentNode;
7882
+ export type MarkPayoutPaidMutationFn = Apollo.MutationFunction<Types.MarkPayoutPaidMutation, Types.MarkPayoutPaidMutationVariables>;
7883
+ /**
7884
+ * __useMarkPayoutPaidMutation__
7885
+ *
7886
+ * To run a mutation, you first call `useMarkPayoutPaidMutation` within a React component and pass it any options that fit your needs.
7887
+ * When your component renders, `useMarkPayoutPaidMutation` returns a tuple that includes:
7888
+ * - A mutate function that you can call at any time to execute the mutation
7889
+ * - An object with fields that represent the current status of the mutation's execution
7890
+ *
7891
+ * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
7892
+ *
7893
+ * @example
7894
+ * const [markPayoutPaidMutation, { data, loading, error }] = useMarkPayoutPaidMutation({
7895
+ * variables: {
7896
+ * id: // value for 'id'
7897
+ * externalReference: // value for 'externalReference'
7898
+ * notes: // value for 'notes'
7899
+ * },
7900
+ * });
7901
+ */
7902
+ export declare function useMarkPayoutPaidMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<Types.MarkPayoutPaidMutation, Types.MarkPayoutPaidMutationVariables>): ApolloReactHooks.useMutation.ResultTuple<Types.MarkPayoutPaidMutation, any, Apollo.ApolloCache>;
7903
+ export type MarkPayoutPaidMutationHookResult = ReturnType<typeof useMarkPayoutPaidMutation>;
7904
+ export type MarkPayoutPaidMutationResult = Apollo.MutationResult<Types.MarkPayoutPaidMutation>;
7905
+ export type MarkPayoutPaidMutationOptions = Apollo.BaseMutationOptions<Types.MarkPayoutPaidMutation, Types.MarkPayoutPaidMutationVariables>;
7862
7906
  export declare const ProcessPayoutRequestDocument: Apollo.DocumentNode;
7863
7907
  export type ProcessPayoutRequestMutationFn = Apollo.MutationFunction<Types.ProcessPayoutRequestMutation, Types.ProcessPayoutRequestMutationVariables>;
7864
7908
  /**