@burdenoff/microfe-billing 2026.515.6 → 2026.517.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 (36) hide show
  1. package/dist/billing/BillingUserRoutes.js +1 -1
  2. package/dist/billing/BillingUserRoutes.js.map +1 -1
  3. package/dist/billing/modules/billing/hooks/useInvoices.d.ts +0 -1
  4. package/dist/billing/modules/billing/hooks/useInvoices.d.ts.map +1 -1
  5. package/dist/billing/modules/billing/hooks/useInvoices.js +20 -26
  6. package/dist/billing/modules/billing/hooks/useInvoices.js.map +1 -1
  7. package/dist/billing/modules/billing/pages/InvoicesListPage.d.ts.map +1 -1
  8. package/dist/billing/modules/billing/pages/InvoicesListPage.js +175 -169
  9. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  10. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.d.ts.map +1 -1
  11. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +178 -209
  12. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  13. package/dist/billing/modules/earnings/api.d.ts +0 -4
  14. package/dist/billing/modules/earnings/api.d.ts.map +1 -1
  15. package/dist/billing/modules/earnings/api.js +10 -14
  16. package/dist/billing/modules/earnings/api.js.map +1 -1
  17. package/dist/billing/modules/earnings/pages/PayoutAdminPage.d.ts.map +1 -1
  18. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +233 -523
  19. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  20. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.d.ts +1 -1
  21. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.d.ts.map +1 -1
  22. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.js +15 -16
  23. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.js.map +1 -1
  24. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.d.ts.map +1 -1
  25. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +162 -155
  26. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  27. package/dist/billing/modules/usage/pages/UsagePage.d.ts.map +1 -1
  28. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  29. package/dist/generated/global-operations.d.ts +0 -48
  30. package/dist/generated/global-operations.d.ts.map +1 -1
  31. package/dist/generated/global-operations.js +293 -310
  32. package/dist/generated/global-operations.js.map +1 -1
  33. package/dist/generated/global-types.d.ts +0 -9
  34. package/dist/generated/global-types.d.ts.map +1 -1
  35. package/dist/generated/global-types.js.map +1 -1
  36. package/package.json +1 -1
@@ -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 {\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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"}
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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"}
@@ -77,7 +77,7 @@ export declare function useBillingAccounts(): {
77
77
  /**
78
78
  * Hook for fetching paginated subscriptions for a billing account
79
79
  */
80
- export declare function usePaginatedSubscriptions(billingAccountId: string | undefined, page?: number, pageSize?: number, search?: string): {
80
+ export declare function usePaginatedSubscriptions(billingAccountId: string | undefined, page?: number, pageSize?: number): {
81
81
  subscriptions: BillingSubscription[];
82
82
  activeSubscriptions: BillingSubscription[];
83
83
  totalCount: any;
@@ -1 +1 @@
1
- {"version":3,"file":"useSubscriptions.d.ts","sourceRoot":"","sources":["../../../../../src/billing/modules/subscriptions/hooks/useSubscriptions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useSubscriptions.d.ts","sourceRoot":"","sources":["../../../../../src/billing/modules/subscriptions/hooks/useSubscriptions.ts"],"names":[],"mappings":"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"}
@@ -106,29 +106,28 @@ function y() {
106
106
  refetch: i
107
107
  };
108
108
  }
109
- function b(e, t = 1, n = 10, r) {
110
- let { data: i, loading: a, error: o, refetch: c } = s({
109
+ function b(e, t = 1, n = 10) {
110
+ let { data: r, loading: i, error: a, refetch: o } = s({
111
111
  variables: {
112
112
  billingAccountId: e,
113
113
  page: t,
114
- pageSize: n,
115
- search: r || void 0
114
+ pageSize: n
116
115
  },
117
116
  skip: !e,
118
117
  fetchPolicy: "cache-and-network"
119
- }), l = p(async () => {
120
- await c();
121
- }, [c]), u = i?.getPaginatedSubscriptions, d = m(() => u?.subscriptions || [], [u?.subscriptions]);
118
+ }), c = p(async () => {
119
+ await o();
120
+ }, [o]), l = r?.getPaginatedSubscriptions, u = m(() => l?.subscriptions || [], [l?.subscriptions]);
122
121
  return {
123
- subscriptions: d,
124
- activeSubscriptions: m(() => d.filter((e) => e.status === "active"), [d]),
125
- totalCount: u?.totalCount || 0,
126
- page: u?.page || t,
127
- pageSize: u?.pageSize || n,
128
- totalPages: u?.totalPages || 0,
129
- isLoading: a,
130
- error: o,
131
- refetch: l
122
+ subscriptions: u,
123
+ activeSubscriptions: m(() => u.filter((e) => e.status === "active"), [u]),
124
+ totalCount: l?.totalCount || 0,
125
+ page: l?.page || t,
126
+ pageSize: l?.pageSize || n,
127
+ totalPages: l?.totalPages || 0,
128
+ isLoading: i,
129
+ error: a,
130
+ refetch: c
132
131
  };
133
132
  }
134
133
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"useSubscriptions.js","names":[],"sources":["../../../../../src/billing/modules/subscriptions/hooks/useSubscriptions.ts"],"sourcesContent":["/**\n * Subscriptions Module - useSubscriptions Hook\n * Provides access to subscription data and mutations\n */\n\nimport { useApolloClient } from '@apollo/client/react';\nimport { useCallback, useMemo } from 'react';\nimport {\n useGetSubscriptionQuery,\n useGetBillingAccountQuery,\n useGetDefaultBillingAccountQuery,\n useGetSubscriptionUsageOverviewQuery,\n useGetBillingAccountsForSubscriptionsQuery,\n useGetPaginatedSubscriptionsQuery,\n useCreateBillingAccountSubscriptionsMutation,\n useUpdateBillingAccountSubscriptionsMutation,\n useInitiatePaymentSubscriptionsMutation,\n useSpendCreditsSubscriptionsMutation,\n useCancelSubscriptionMutation,\n useUpdateSubscriptionSeatsMutation,\n GetSubscriptionDocument,\n GetBillingAccountDocument,\n GetDefaultBillingAccountDocument,\n} from '../../../../generated/global-operations';\nimport type {\n BillingSubscription,\n BillingAccount,\n SubscriptionStatus,\n CreateBillingAccountInput,\n UpdateBillingAccountInput,\n InitiatePaymentInput,\n InitiatePaymentResponse,\n SpendCreditsInput,\n CancelSubscriptionInput,\n UpdateSubscriptionSeatsInput,\n} from '../../../shared/types';\n\ninterface UseSubscriptionResult {\n subscription: BillingSubscription | null;\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => Promise<void>;\n}\n\ninterface UseBillingAccountResult {\n billingAccount: BillingAccount | null;\n subscriptions: BillingSubscription[];\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => Promise<void>;\n}\n\ninterface UseSubscriptionsListResult {\n subscriptions: BillingSubscription[];\n activeSubscriptions: BillingSubscription[];\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => Promise<void>;\n}\n\ninterface UseSubscriptionMutationsResult {\n createBillingAccount: (input: CreateBillingAccountInput) => Promise<BillingAccount>;\n updateBillingAccount: (input: UpdateBillingAccountInput) => Promise<BillingAccount>;\n initiatePayment: (input: InitiatePaymentInput) => Promise<InitiatePaymentResponse>;\n spendCredits: (input: SpendCreditsInput) => Promise<{ creditTransactionID: string }>;\n cancelSubscription: (input: CancelSubscriptionInput) => Promise<BillingSubscription>;\n updateSubscriptionSeats: (input: UpdateSubscriptionSeatsInput) => Promise<BillingSubscription>;\n isCreating: boolean;\n isUpdating: boolean;\n isInitiatingPayment: boolean;\n isSpendingCredits: boolean;\n isCanceling: boolean;\n isUpdatingSeats: boolean;\n}\n\n/**\n * Hook for fetching a single subscription by ID\n */\nexport function useSubscription(\n id: string | undefined,\n billingAccountId: string | undefined\n): UseSubscriptionResult {\n const { data, loading, error, refetch } = useGetSubscriptionQuery({\n variables: { id: id!, billingAccountId: billingAccountId! },\n skip: !id || !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n return {\n subscription: data?.getSubscription || null,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for fetching billing account by ID\n */\nexport function useBillingAccount(id: string | undefined): UseBillingAccountResult {\n const { data, loading, error, refetch } = useGetBillingAccountQuery({\n variables: { id: id! },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n const billingAccount = data?.getBillingAccount || null;\n const subscriptions = (billingAccount?.subscriptions || []).filter(\n Boolean\n ) as BillingSubscription[];\n\n return {\n billingAccount,\n subscriptions,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for fetching default billing account for an org\n */\nexport function useDefaultBillingAccount(): UseBillingAccountResult {\n const { data, loading, error, refetch } = useGetDefaultBillingAccountQuery({\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n const billingAccount = data?.getDefaultBillingAccount || null;\n const subscriptions = (billingAccount?.subscriptions || []).filter(\n Boolean\n ) as BillingSubscription[];\n\n return {\n billingAccount,\n subscriptions,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for listing subscriptions from a billing account\n */\nexport function useSubscriptionsList(\n billingAccountId: string | undefined\n): UseSubscriptionsListResult {\n const { subscriptions, isLoading, error, refetch } = useBillingAccount(billingAccountId);\n\n const activeSubscriptions = useMemo(() => {\n return subscriptions.filter((s) => s.status === ('active' as SubscriptionStatus));\n }, [subscriptions]);\n\n return {\n subscriptions,\n activeSubscriptions,\n isLoading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook for subscription usage overview\n */\nexport function useSubscriptionUsageOverview(\n billingAccountId: string | undefined,\n page = 1,\n pageSize = 10\n) {\n const { data, loading, error, refetch } = useGetSubscriptionUsageOverviewQuery({\n variables: { billingAccountId: billingAccountId!, page, pageSize },\n skip: !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n return {\n subscriptionsWithQuotas: data?.getSubscriptionUsageOverview || [],\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for subscription mutations\n */\nexport function useSubscriptionMutations(): UseSubscriptionMutationsResult {\n const client = useApolloClient();\n\n const [createBillingAccountMutation, { loading: isCreating }] =\n useCreateBillingAccountSubscriptionsMutation();\n const [updateBillingAccountMutation, { loading: isUpdating }] =\n useUpdateBillingAccountSubscriptionsMutation();\n const [initiatePaymentMutation, { loading: isInitiatingPayment }] =\n useInitiatePaymentSubscriptionsMutation();\n const [spendCreditsMutation, { loading: isSpendingCredits }] =\n useSpendCreditsSubscriptionsMutation();\n const [cancelSubscriptionMutation, { loading: isCanceling }] = useCancelSubscriptionMutation();\n const [updateSeatsMutation, { loading: isUpdatingSeats }] = useUpdateSubscriptionSeatsMutation();\n\n const createBillingAccount = useCallback(\n async (input: CreateBillingAccountInput): Promise<BillingAccount> => {\n try {\n const { data } = await createBillingAccountMutation({\n variables: { input },\n });\n return data.createBillingAccount;\n } catch (error) {\n console.error('Failed to create billing account:', error);\n throw error;\n }\n },\n [createBillingAccountMutation]\n );\n\n const updateBillingAccount = useCallback(\n async (input: UpdateBillingAccountInput): Promise<BillingAccount> => {\n try {\n const { data } = await updateBillingAccountMutation({\n variables: { input },\n });\n // Refetch billing account after update\n await client.refetchQueries({ include: [GetBillingAccountDocument] });\n return data.updateBillingAccount;\n } catch (error) {\n console.error('Failed to update billing account:', error);\n throw error;\n }\n },\n [updateBillingAccountMutation, client]\n );\n\n const initiatePayment = useCallback(\n async (input: InitiatePaymentInput): Promise<InitiatePaymentResponse> => {\n try {\n const { data } = await initiatePaymentMutation({\n variables: { input },\n });\n return data.initiatePayment;\n } catch (error) {\n console.error('Failed to initiate payment:', error);\n throw error;\n }\n },\n [initiatePaymentMutation]\n );\n\n const spendCredits = useCallback(\n async (input: SpendCreditsInput): Promise<{ creditTransactionID: string }> => {\n try {\n const { data } = await spendCreditsMutation({\n variables: { input },\n });\n // Refetch billing account after spending credits\n await client.refetchQueries({\n include: [GetBillingAccountDocument, GetDefaultBillingAccountDocument],\n });\n return data.spendCredits;\n } catch (error) {\n console.error('Failed to spend credits:', error);\n throw error;\n }\n },\n [spendCreditsMutation, client]\n );\n\n const cancelSubscription = useCallback(\n async (input: CancelSubscriptionInput): Promise<BillingSubscription> => {\n try {\n const { data } = await cancelSubscriptionMutation({\n variables: { input },\n });\n // Refetch subscription and billing account after cancellation\n await client.refetchQueries({\n include: [\n GetSubscriptionDocument,\n GetBillingAccountDocument,\n GetDefaultBillingAccountDocument,\n ],\n });\n return data.cancelSubscription;\n } catch (error) {\n console.error('Failed to cancel subscription:', error);\n throw error;\n }\n },\n [cancelSubscriptionMutation, client]\n );\n\n const updateSubscriptionSeats = useCallback(\n async (input: UpdateSubscriptionSeatsInput): Promise<BillingSubscription> => {\n try {\n const { data } = await updateSeatsMutation({ variables: { input } });\n await client.refetchQueries({ include: [GetSubscriptionDocument] });\n return data.updateSubscriptionSeats;\n } catch (error) {\n console.error('Failed to update subscription seats:', error);\n throw error;\n }\n },\n [updateSeatsMutation, client]\n );\n\n return {\n createBillingAccount,\n updateBillingAccount,\n initiatePayment,\n spendCredits,\n cancelSubscription,\n updateSubscriptionSeats,\n isCreating,\n isUpdating,\n isInitiatingPayment,\n isSpendingCredits,\n isCanceling,\n isUpdatingSeats,\n };\n}\n\n/**\n * Hook for fetching all billing accounts for an org\n */\nexport function useBillingAccounts() {\n const { data, loading, error, refetch } = useGetBillingAccountsForSubscriptionsQuery({\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n const billingAccounts: BillingAccount[] = data?.getBillingAccountsByOrg || [];\n\n return {\n billingAccounts,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for fetching paginated subscriptions for a billing account\n */\nexport function usePaginatedSubscriptions(\n billingAccountId: string | undefined,\n page: number = 1,\n pageSize: number = 10,\n search?: string\n) {\n const { data, loading, error, refetch } = useGetPaginatedSubscriptionsQuery({\n variables: { billingAccountId: billingAccountId!, page, pageSize, search: search || undefined },\n skip: !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n const result = data?.getPaginatedSubscriptions;\n const subscriptions = useMemo<BillingSubscription[]>(\n () => result?.subscriptions || [],\n [result?.subscriptions]\n );\n const activeSubscriptions = useMemo(() => {\n return subscriptions.filter((s) => s.status === ('active' as SubscriptionStatus));\n }, [subscriptions]);\n\n return {\n subscriptions,\n activeSubscriptions,\n totalCount: result?.totalCount || 0,\n page: result?.page || page,\n pageSize: result?.pageSize || pageSize,\n totalPages: result?.totalPages || 0,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"useSubscriptions.js","names":[],"sources":["../../../../../src/billing/modules/subscriptions/hooks/useSubscriptions.ts"],"sourcesContent":["/**\n * Subscriptions Module - useSubscriptions Hook\n * Provides access to subscription data and mutations\n */\n\nimport { useApolloClient } from '@apollo/client/react';\nimport { useCallback, useMemo } from 'react';\nimport {\n useGetSubscriptionQuery,\n useGetBillingAccountQuery,\n useGetDefaultBillingAccountQuery,\n useGetSubscriptionUsageOverviewQuery,\n useGetBillingAccountsForSubscriptionsQuery,\n useGetPaginatedSubscriptionsQuery,\n useCreateBillingAccountSubscriptionsMutation,\n useUpdateBillingAccountSubscriptionsMutation,\n useInitiatePaymentSubscriptionsMutation,\n useSpendCreditsSubscriptionsMutation,\n useCancelSubscriptionMutation,\n useUpdateSubscriptionSeatsMutation,\n GetSubscriptionDocument,\n GetBillingAccountDocument,\n GetDefaultBillingAccountDocument,\n} from '../../../../generated/global-operations';\nimport type {\n BillingSubscription,\n BillingAccount,\n SubscriptionStatus,\n CreateBillingAccountInput,\n UpdateBillingAccountInput,\n InitiatePaymentInput,\n InitiatePaymentResponse,\n SpendCreditsInput,\n CancelSubscriptionInput,\n UpdateSubscriptionSeatsInput,\n} from '../../../shared/types';\n\ninterface UseSubscriptionResult {\n subscription: BillingSubscription | null;\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => Promise<void>;\n}\n\ninterface UseBillingAccountResult {\n billingAccount: BillingAccount | null;\n subscriptions: BillingSubscription[];\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => Promise<void>;\n}\n\ninterface UseSubscriptionsListResult {\n subscriptions: BillingSubscription[];\n activeSubscriptions: BillingSubscription[];\n isLoading: boolean;\n error: Error | undefined;\n refetch: () => Promise<void>;\n}\n\ninterface UseSubscriptionMutationsResult {\n createBillingAccount: (input: CreateBillingAccountInput) => Promise<BillingAccount>;\n updateBillingAccount: (input: UpdateBillingAccountInput) => Promise<BillingAccount>;\n initiatePayment: (input: InitiatePaymentInput) => Promise<InitiatePaymentResponse>;\n spendCredits: (input: SpendCreditsInput) => Promise<{ creditTransactionID: string }>;\n cancelSubscription: (input: CancelSubscriptionInput) => Promise<BillingSubscription>;\n updateSubscriptionSeats: (input: UpdateSubscriptionSeatsInput) => Promise<BillingSubscription>;\n isCreating: boolean;\n isUpdating: boolean;\n isInitiatingPayment: boolean;\n isSpendingCredits: boolean;\n isCanceling: boolean;\n isUpdatingSeats: boolean;\n}\n\n/**\n * Hook for fetching a single subscription by ID\n */\nexport function useSubscription(\n id: string | undefined,\n billingAccountId: string | undefined\n): UseSubscriptionResult {\n const { data, loading, error, refetch } = useGetSubscriptionQuery({\n variables: { id: id!, billingAccountId: billingAccountId! },\n skip: !id || !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n return {\n subscription: data?.getSubscription || null,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for fetching billing account by ID\n */\nexport function useBillingAccount(id: string | undefined): UseBillingAccountResult {\n const { data, loading, error, refetch } = useGetBillingAccountQuery({\n variables: { id: id! },\n skip: !id,\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n const billingAccount = data?.getBillingAccount || null;\n const subscriptions = (billingAccount?.subscriptions || []).filter(\n Boolean\n ) as BillingSubscription[];\n\n return {\n billingAccount,\n subscriptions,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for fetching default billing account for an org\n */\nexport function useDefaultBillingAccount(): UseBillingAccountResult {\n const { data, loading, error, refetch } = useGetDefaultBillingAccountQuery({\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n const billingAccount = data?.getDefaultBillingAccount || null;\n const subscriptions = (billingAccount?.subscriptions || []).filter(\n Boolean\n ) as BillingSubscription[];\n\n return {\n billingAccount,\n subscriptions,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for listing subscriptions from a billing account\n */\nexport function useSubscriptionsList(\n billingAccountId: string | undefined\n): UseSubscriptionsListResult {\n const { subscriptions, isLoading, error, refetch } = useBillingAccount(billingAccountId);\n\n const activeSubscriptions = useMemo(() => {\n return subscriptions.filter((s) => s.status === ('active' as SubscriptionStatus));\n }, [subscriptions]);\n\n return {\n subscriptions,\n activeSubscriptions,\n isLoading,\n error,\n refetch,\n };\n}\n\n/**\n * Hook for subscription usage overview\n */\nexport function useSubscriptionUsageOverview(\n billingAccountId: string | undefined,\n page = 1,\n pageSize = 10\n) {\n const { data, loading, error, refetch } = useGetSubscriptionUsageOverviewQuery({\n variables: { billingAccountId: billingAccountId!, page, pageSize },\n skip: !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n return {\n subscriptionsWithQuotas: data?.getSubscriptionUsageOverview || [],\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for subscription mutations\n */\nexport function useSubscriptionMutations(): UseSubscriptionMutationsResult {\n const client = useApolloClient();\n\n const [createBillingAccountMutation, { loading: isCreating }] =\n useCreateBillingAccountSubscriptionsMutation();\n const [updateBillingAccountMutation, { loading: isUpdating }] =\n useUpdateBillingAccountSubscriptionsMutation();\n const [initiatePaymentMutation, { loading: isInitiatingPayment }] =\n useInitiatePaymentSubscriptionsMutation();\n const [spendCreditsMutation, { loading: isSpendingCredits }] =\n useSpendCreditsSubscriptionsMutation();\n const [cancelSubscriptionMutation, { loading: isCanceling }] = useCancelSubscriptionMutation();\n const [updateSeatsMutation, { loading: isUpdatingSeats }] = useUpdateSubscriptionSeatsMutation();\n\n const createBillingAccount = useCallback(\n async (input: CreateBillingAccountInput): Promise<BillingAccount> => {\n try {\n const { data } = await createBillingAccountMutation({\n variables: { input },\n });\n return data.createBillingAccount;\n } catch (error) {\n console.error('Failed to create billing account:', error);\n throw error;\n }\n },\n [createBillingAccountMutation]\n );\n\n const updateBillingAccount = useCallback(\n async (input: UpdateBillingAccountInput): Promise<BillingAccount> => {\n try {\n const { data } = await updateBillingAccountMutation({\n variables: { input },\n });\n // Refetch billing account after update\n await client.refetchQueries({ include: [GetBillingAccountDocument] });\n return data.updateBillingAccount;\n } catch (error) {\n console.error('Failed to update billing account:', error);\n throw error;\n }\n },\n [updateBillingAccountMutation, client]\n );\n\n const initiatePayment = useCallback(\n async (input: InitiatePaymentInput): Promise<InitiatePaymentResponse> => {\n try {\n const { data } = await initiatePaymentMutation({\n variables: { input },\n });\n return data.initiatePayment;\n } catch (error) {\n console.error('Failed to initiate payment:', error);\n throw error;\n }\n },\n [initiatePaymentMutation]\n );\n\n const spendCredits = useCallback(\n async (input: SpendCreditsInput): Promise<{ creditTransactionID: string }> => {\n try {\n const { data } = await spendCreditsMutation({\n variables: { input },\n });\n // Refetch billing account after spending credits\n await client.refetchQueries({\n include: [GetBillingAccountDocument, GetDefaultBillingAccountDocument],\n });\n return data.spendCredits;\n } catch (error) {\n console.error('Failed to spend credits:', error);\n throw error;\n }\n },\n [spendCreditsMutation, client]\n );\n\n const cancelSubscription = useCallback(\n async (input: CancelSubscriptionInput): Promise<BillingSubscription> => {\n try {\n const { data } = await cancelSubscriptionMutation({\n variables: { input },\n });\n // Refetch subscription and billing account after cancellation\n await client.refetchQueries({\n include: [\n GetSubscriptionDocument,\n GetBillingAccountDocument,\n GetDefaultBillingAccountDocument,\n ],\n });\n return data.cancelSubscription;\n } catch (error) {\n console.error('Failed to cancel subscription:', error);\n throw error;\n }\n },\n [cancelSubscriptionMutation, client]\n );\n\n const updateSubscriptionSeats = useCallback(\n async (input: UpdateSubscriptionSeatsInput): Promise<BillingSubscription> => {\n try {\n const { data } = await updateSeatsMutation({ variables: { input } });\n await client.refetchQueries({ include: [GetSubscriptionDocument] });\n return data.updateSubscriptionSeats;\n } catch (error) {\n console.error('Failed to update subscription seats:', error);\n throw error;\n }\n },\n [updateSeatsMutation, client]\n );\n\n return {\n createBillingAccount,\n updateBillingAccount,\n initiatePayment,\n spendCredits,\n cancelSubscription,\n updateSubscriptionSeats,\n isCreating,\n isUpdating,\n isInitiatingPayment,\n isSpendingCredits,\n isCanceling,\n isUpdatingSeats,\n };\n}\n\n/**\n * Hook for fetching all billing accounts for an org\n */\nexport function useBillingAccounts() {\n const { data, loading, error, refetch } = useGetBillingAccountsForSubscriptionsQuery({\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n const billingAccounts: BillingAccount[] = data?.getBillingAccountsByOrg || [];\n\n return {\n billingAccounts,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n\n/**\n * Hook for fetching paginated subscriptions for a billing account\n */\nexport function usePaginatedSubscriptions(\n billingAccountId: string | undefined,\n page: number = 1,\n pageSize: number = 10\n) {\n const { data, loading, error, refetch } = useGetPaginatedSubscriptionsQuery({\n variables: { billingAccountId: billingAccountId!, page, pageSize },\n skip: !billingAccountId,\n fetchPolicy: 'cache-and-network',\n });\n\n const handleRefetch = useCallback(async () => {\n await refetch();\n }, [refetch]);\n\n const result = data?.getPaginatedSubscriptions;\n const subscriptions = useMemo<BillingSubscription[]>(\n () => result?.subscriptions || [],\n [result?.subscriptions]\n );\n const activeSubscriptions = useMemo(() => {\n return subscriptions.filter((s) => s.status === ('active' as SubscriptionStatus));\n }, [subscriptions]);\n\n return {\n subscriptions,\n activeSubscriptions,\n totalCount: result?.totalCount || 0,\n page: result?.page || page,\n pageSize: result?.pageSize || pageSize,\n totalPages: result?.totalPages || 0,\n isLoading: loading,\n error: error as Error | undefined,\n refetch: handleRefetch,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SubscriptionsListPage.d.ts","sourceRoot":"","sources":["../../../../../src/billing/modules/subscriptions/pages/SubscriptionsListPage.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAA+B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAwB7D,eAAO,MAAM,qBAAqB,EAAE,EA6enC,CAAC"}
1
+ {"version":3,"file":"SubscriptionsListPage.d.ts","sourceRoot":"","sources":["../../../../../src/billing/modules/subscriptions/pages/SubscriptionsListPage.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAwB1C,eAAO,MAAM,qBAAqB,EAAE,EA6enC,CAAC"}