@burdenoff/microfe-billing 2026.623.3 → 2026.624.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/billing/BillingUserRoutes.js +3 -3
  2. package/dist/billing/BillingUserRoutes.js.map +1 -1
  3. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +34 -34
  4. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  5. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +94 -94
  6. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  7. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +162 -187
  8. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  9. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +146 -153
  10. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  11. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +10 -10
  12. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  13. package/dist/billing/modules/billing/pages/TransactionsPage.js +62 -62
  14. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  15. package/dist/billing/modules/coupons/pages/CouponDetailPage.js +164 -179
  16. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  17. package/dist/billing/modules/coupons/pages/CreateCouponPage.js +8 -8
  18. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  19. package/dist/billing/modules/earnings/pages/EarningsPage.js +243 -305
  20. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  21. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +73 -78
  22. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  23. package/dist/billing/modules/earnings/pages/PayoutsPage.js +173 -179
  24. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  25. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +4 -4
  26. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  27. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +4 -4
  28. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  29. package/dist/billing/modules/settings/pages/SettingsPage.js +181 -173
  30. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  31. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +111 -99
  32. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  33. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js +68 -83
  34. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
  35. package/dist/billing/shared/components/AccessDenied.js +4 -4
  36. package/dist/billing/shared/components/AccessDenied.js.map +1 -1
  37. package/dist/billing/shared/components/ActorIdentity.js +8 -8
  38. package/dist/billing/shared/components/ActorIdentity.js.map +1 -1
  39. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js +11 -11
  40. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
  41. package/dist/billing/shared/ui/MetricCard.js +1 -1
  42. package/dist/billing/shared/ui/MetricCard.js.map +1 -1
  43. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"EarningsPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/EarningsPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type FC } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Coins, HandCoins, RefreshCw, Wallet } from 'lucide-react';\n\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\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 { useGetDefaultBillingAccountSettingsQuery } from '../../../../generated/global-operations';\nimport {\n fetchEarningsEntries,\n fetchEarningsSummary,\n fetchDeveloperPortalRevenueDashboard,\n type DeveloperPortalRevenueDashboard,\n type EarningsEntry,\n type EarningsSummary,\n} from '../api';\n\ntype EarningsSourceFilter = 'ALL' | 'AFFILIATE' | 'STORE' | 'OTHER';\n\nexport const EarningsPage: FC = () => {\n const [searchParams] = useSearchParams();\n const permissions = useBillingPermissions();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n const developerOrgId = searchParams.get('developerOrgId');\n const developerOrgName = searchParams.get('developerOrgName');\n const { data: billingAccountData, loading: billingAccountLoading } =\n useGetDefaultBillingAccountSettingsQuery({});\n\n const billingAccountId = billingAccountData?.getDefaultBillingAccount?.id;\n const [summary, setSummary] = useState<EarningsSummary | null>(null);\n const [entries, setEntries] = useState<EarningsEntry[]>([]);\n const [developerPortalRevenue, setDeveloperPortalRevenue] =\n useState<DeveloperPortalRevenueDashboard | null>(null);\n const [sourceFilter, setSourceFilter] = useState<EarningsSourceFilter>('ALL');\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 if (developerOrgId) {\n const loadedRevenue = await fetchDeveloperPortalRevenueDashboard(\n developerOrgId,\n requestContext\n );\n setDeveloperPortalRevenue(loadedRevenue);\n setSummary(null);\n setEntries([]);\n return;\n }\n\n if (!billingAccountId) {\n setSummary(null);\n setEntries([]);\n setDeveloperPortalRevenue(null);\n return;\n }\n\n const [loadedSummary, loadedEntries] = await Promise.all([\n fetchEarningsSummary(billingAccountId, requestContext),\n fetchEarningsEntries(billingAccountId, requestContext),\n ]);\n setSummary(loadedSummary);\n setEntries(loadedEntries);\n setDeveloperPortalRevenue(null);\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load earnings'));\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n void loadData();\n }, [billingAccountId, developerOrgId, requestContext]);\n\n if (!permissions.canViewBillingAccount) {\n return <AccessDenied message=\"You don't have permission to view earnings.\" />;\n }\n\n if (!developerOrgId && !billingAccountId && !billingAccountLoading) {\n return (\n <EmptyState\n icon={<Wallet className=\"size-8\" />}\n title=\"No billing account found\"\n description=\"Create a billing account first to view earnings.\"\n />\n );\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Earnings unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const cards = summary\n ? [\n {\n title: 'Available',\n value: formatCurrency(summary.availableAmount, 'USD'),\n icon: <HandCoins className=\"size-5\" />,\n },\n {\n title: 'Reserved',\n value: formatCurrency(summary.reservedAmount, 'USD'),\n icon: <Coins className=\"size-5\" />,\n },\n {\n title: 'Paid out',\n value: formatCurrency(summary.paidAmount, 'USD'),\n icon: <Wallet className=\"size-5\" />,\n },\n {\n title: 'Lifetime',\n value: formatCurrency(summary.totalLifetimeAmount, 'USD'),\n icon: <RefreshCw className=\"size-5\" />,\n },\n ]\n : [];\n\n const filteredEntries =\n sourceFilter === 'ALL'\n ? entries\n : entries.filter((entry) => entry.sourceCategory === sourceFilter);\n\n const categoryCards =\n summary?.categoryBreakdown?.map((item) => ({\n title: `${item.category} earnings`,\n value: formatCurrency(item.amount, 'USD'),\n helperText: `${item.count} entries`,\n })) ?? [];\n\n const developerPortalCards = developerPortalRevenue?.summary\n ? [\n {\n title: 'Gross revenue',\n value: formatCurrency(developerPortalRevenue.summary.totalGrossRevenue, 'USD'),\n icon: <HandCoins className=\"size-5\" />,\n },\n {\n title: 'Net revenue',\n value: formatCurrency(developerPortalRevenue.summary.totalNetRevenue, 'USD'),\n icon: <Wallet className=\"size-5\" />,\n },\n {\n title: 'Pending balance',\n value: formatCurrency(developerPortalRevenue.summary.pendingBalance, 'USD'),\n icon: <Coins className=\"size-5\" />,\n },\n {\n title: 'Platform fees',\n value: formatCurrency(developerPortalRevenue.summary.totalPlatformFees, 'USD'),\n icon: <RefreshCw className=\"size-5\" />,\n },\n ]\n : [];\n\n const isDeveloperPortalMode = !!developerOrgId;\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={isDeveloperPortalMode ? 'Marketplace earnings' : 'Earnings'}\n description={\n isDeveloperPortalMode\n ? `Developer portal revenue, sales, and payouts${developerOrgName ? ` for ${developerOrgName}` : ''}.`\n : 'Track affiliate, store, and other earning sources in one ledger.'\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 ) : isDeveloperPortalMode ? (\n developerPortalRevenue?.summary ? (\n <div className=\"space-y-6\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {developerPortalCards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n\n <section className=\"rounded-lg border border-border bg-card p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-foreground\">Recent sales</h2>\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=\"size-4\" />\n Refresh\n </button>\n </div>\n\n {developerPortalRevenue.sales.length === 0 ? (\n <EmptyState\n icon={<Coins className=\"size-8\" />}\n title=\"No sales yet\"\n description=\"Sales will appear here when customers start purchasing your apps.\"\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\">Application</th>\n <th className=\"px-3 py-2\">Pricing</th>\n <th className=\"px-3 py-2\">Gross</th>\n <th className=\"px-3 py-2\">Net</th>\n <th className=\"px-3 py-2\">Status</th>\n <th className=\"px-3 py-2\">Purchased</th>\n </tr>\n </thead>\n <tbody>\n {developerPortalRevenue.sales.map((sale) => (\n <tr key={sale.id} className=\"border-b border-border/70 text-foreground\">\n <td className=\"px-3 py-2 font-medium\">\n {sale.application?.name || sale.application?.slug || 'Unknown app'}\n </td>\n <td className=\"px-3 py-2\">{sale.pricingModel}</td>\n <td className=\"px-3 py-2\">\n {formatCurrency(sale.grossAmount, sale.currency || 'USD')}\n </td>\n <td className=\"px-3 py-2\">\n {formatCurrency(sale.netAmount, sale.currency || 'USD')}\n </td>\n <td className=\"px-3 py-2\">{sale.status}</td>\n <td className=\"px-3 py-2\">{formatDateTime(sale.purchasedAt)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n\n <section className=\"rounded-lg border border-border bg-card p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-foreground\">Payouts</h2>\n\n {developerPortalRevenue.payouts.length === 0 ? (\n <EmptyState\n icon={<Wallet className=\"size-8\" />}\n title=\"No payouts yet\"\n description=\"Scheduled and completed payouts will appear here.\"\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\">Period</th>\n <th className=\"px-3 py-2\">Amount</th>\n <th className=\"px-3 py-2\">Status</th>\n <th className=\"px-3 py-2\">Scheduled</th>\n <th className=\"px-3 py-2\">Completed</th>\n </tr>\n </thead>\n <tbody>\n {developerPortalRevenue.payouts.map((payout) => (\n <tr key={payout.id} className=\"border-b border-border/70 text-foreground\">\n <td className=\"px-3 py-2 font-medium\">{payout.periodLabel || '-'}</td>\n <td className=\"px-3 py-2\">\n {formatCurrency(payout.netAmount, payout.currency || 'USD')}\n </td>\n <td className=\"px-3 py-2\">{payout.status}</td>\n <td className=\"px-3 py-2\">\n {payout.scheduledAt ? formatDateTime(payout.scheduledAt) : '-'}\n </td>\n <td className=\"px-3 py-2\">\n {payout.completedAt ? formatDateTime(payout.completedAt) : '-'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n </div>\n ) : (\n <EmptyState\n icon={<Coins className=\"size-8\" />}\n title=\"No developer portal revenue yet\"\n description=\"Marketplace revenue will appear here once your developer organization records sales.\"\n />\n )\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 {categoryCards.length > 0 ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {categoryCards.map((card) => (\n <div key={card.title} className=\"rounded-lg border border-border bg-card p-4\">\n <p className=\"text-sm text-muted-foreground\">{card.title}</p>\n <p className=\"mt-2 text-xl font-semibold text-foreground\">{card.value}</p>\n <p className=\"mt-1 text-xs text-muted-foreground\">{card.helperText}</p>\n </div>\n ))}\n </div>\n ) : null}\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 <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-foreground\">Ledger</h2>\n <div className=\"flex items-center gap-3\">\n <select\n value={sourceFilter}\n onChange={(event) => setSourceFilter(event.target.value as EarningsSourceFilter)}\n className=\"rounded-md border border-border bg-background px-3 py-2 text-sm text-foreground\"\n >\n <option value=\"ALL\">All sources</option>\n <option value=\"AFFILIATE\">Affiliate</option>\n <option value=\"STORE\">Store</option>\n <option value=\"OTHER\">Other</option>\n </select>\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=\"size-4\" />\n Refresh\n </button>\n </div>\n </div>\n\n {filteredEntries.length === 0 && !loading ? (\n <EmptyState\n icon={<Coins className=\"size-8\" />}\n title=\"No earnings yet\"\n description=\"Eligible affiliate rewards and other earnings will appear here.\"\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\">Category</th>\n <th className=\"px-3 py-2\">Description</th>\n <th className=\"px-3 py-2\">Unit</th>\n <th className=\"px-3 py-2\">Amount</th>\n <th className=\"px-3 py-2\">Status</th>\n <th className=\"px-3 py-2\">Created</th>\n </tr>\n </thead>\n <tbody>\n {filteredEntries.map((entry) => (\n <tr key={entry.id} className=\"border-b border-border/70 text-foreground\">\n <td className=\"px-3 py-2 font-medium\">{entry.sourceCategory}</td>\n <td className=\"px-3 py-2\">\n {entry.description || entry.sourceSubcategory || '-'}\n </td>\n <td className=\"px-3 py-2\">{entry.unitType}</td>\n <td className=\"px-3 py-2\">\n {entry.unitType === 'CREDITS'\n ? `${entry.amount.toLocaleString()} credits`\n : formatCurrency(entry.amount, entry.currency || 'USD')}\n </td>\n <td className=\"px-3 py-2\">{entry.status}</td>\n <td className=\"px-3 py-2\">{formatDateTime(entry.createdAt)}</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":"EarningsPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/EarningsPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type FC } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Coins, HandCoins, RefreshCw, Wallet } from 'lucide-react';\nimport { ResponsiveTable, type ResponsiveTableColumn } from '@burdenoff/fe-libs/ui';\n\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\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 { useGetDefaultBillingAccountSettingsQuery } from '../../../../generated/global-operations';\nimport {\n fetchEarningsEntries,\n fetchEarningsSummary,\n fetchDeveloperPortalRevenueDashboard,\n type DeveloperPortalRevenueDashboard,\n type DeveloperPortalRevenueSale,\n type DeveloperPortalRevenuePayout,\n type EarningsEntry,\n type EarningsSummary,\n} from '../api';\n\ntype EarningsSourceFilter = 'ALL' | 'AFFILIATE' | 'STORE' | 'OTHER';\n\nconst salesColumns: ResponsiveTableColumn<DeveloperPortalRevenueSale>[] = [\n {\n key: 'application',\n header: 'Application',\n priority: 'primary',\n cell: (sale) => sale.application?.name || sale.application?.slug || 'Unknown app',\n },\n { key: 'pricing', header: 'Pricing', cell: (sale) => sale.pricingModel },\n {\n key: 'gross',\n header: 'Gross',\n cell: (sale) => (\n <span className=\"tabular-nums\">\n {formatCurrency(sale.grossAmount, sale.currency || 'USD')}\n </span>\n ),\n },\n {\n key: 'net',\n header: 'Net',\n cell: (sale) => (\n <span className=\"tabular-nums\">\n {formatCurrency(sale.netAmount, sale.currency || 'USD')}\n </span>\n ),\n },\n { key: 'status', header: 'Status', cell: (sale) => sale.status },\n {\n key: 'purchased',\n header: 'Purchased',\n cell: (sale) => formatDateTime(sale.purchasedAt),\n },\n];\n\nconst payoutColumns: ResponsiveTableColumn<DeveloperPortalRevenuePayout>[] = [\n {\n key: 'period',\n header: 'Period',\n priority: 'primary',\n cell: (payout) => payout.periodLabel || '-',\n },\n {\n key: 'amount',\n header: 'Amount',\n cell: (payout) => (\n <span className=\"tabular-nums\">\n {formatCurrency(payout.netAmount, payout.currency || 'USD')}\n </span>\n ),\n },\n { key: 'status', header: 'Status', cell: (payout) => payout.status },\n {\n key: 'scheduled',\n header: 'Scheduled',\n cell: (payout) => (payout.scheduledAt ? formatDateTime(payout.scheduledAt) : '-'),\n },\n {\n key: 'completed',\n header: 'Completed',\n cell: (payout) => (payout.completedAt ? formatDateTime(payout.completedAt) : '-'),\n },\n];\n\nconst ledgerColumns: ResponsiveTableColumn<EarningsEntry>[] = [\n {\n key: 'category',\n header: 'Category',\n priority: 'primary',\n cell: (entry) => entry.sourceCategory,\n },\n {\n key: 'description',\n header: 'Description',\n cell: (entry) => entry.description || entry.sourceSubcategory || '-',\n },\n { key: 'unit', header: 'Unit', cell: (entry) => entry.unitType },\n {\n key: 'amount',\n header: 'Amount',\n cell: (entry) => (\n <span className=\"tabular-nums\">\n {entry.unitType === 'CREDITS'\n ? `${entry.amount.toLocaleString()} credits`\n : formatCurrency(entry.amount, entry.currency || 'USD')}\n </span>\n ),\n },\n { key: 'status', header: 'Status', cell: (entry) => entry.status },\n {\n key: 'created',\n header: 'Created',\n cell: (entry) => formatDateTime(entry.createdAt),\n },\n];\n\nexport const EarningsPage: FC = () => {\n const [searchParams] = useSearchParams();\n const permissions = useBillingPermissions();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n const developerOrgId = searchParams.get('developerOrgId');\n const developerOrgName = searchParams.get('developerOrgName');\n const { data: billingAccountData, loading: billingAccountLoading } =\n useGetDefaultBillingAccountSettingsQuery({});\n\n const billingAccountId = billingAccountData?.getDefaultBillingAccount?.id;\n const [summary, setSummary] = useState<EarningsSummary | null>(null);\n const [entries, setEntries] = useState<EarningsEntry[]>([]);\n const [developerPortalRevenue, setDeveloperPortalRevenue] =\n useState<DeveloperPortalRevenueDashboard | null>(null);\n const [sourceFilter, setSourceFilter] = useState<EarningsSourceFilter>('ALL');\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 if (developerOrgId) {\n const loadedRevenue = await fetchDeveloperPortalRevenueDashboard(\n developerOrgId,\n requestContext\n );\n setDeveloperPortalRevenue(loadedRevenue);\n setSummary(null);\n setEntries([]);\n return;\n }\n\n if (!billingAccountId) {\n setSummary(null);\n setEntries([]);\n setDeveloperPortalRevenue(null);\n return;\n }\n\n const [loadedSummary, loadedEntries] = await Promise.all([\n fetchEarningsSummary(billingAccountId, requestContext),\n fetchEarningsEntries(billingAccountId, requestContext),\n ]);\n setSummary(loadedSummary);\n setEntries(loadedEntries);\n setDeveloperPortalRevenue(null);\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load earnings'));\n } finally {\n setLoading(false);\n }\n };\n\n useEffect(() => {\n void loadData();\n }, [billingAccountId, developerOrgId, requestContext]);\n\n if (!permissions.canViewBillingAccount) {\n return <AccessDenied message=\"You don't have permission to view earnings.\" />;\n }\n\n if (!developerOrgId && !billingAccountId && !billingAccountLoading) {\n return (\n <EmptyState\n icon={<Wallet className=\"size-8\" />}\n title=\"No billing account found\"\n description=\"Create a billing account first to view earnings.\"\n />\n );\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Earnings unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const cards = summary\n ? [\n {\n title: 'Available',\n value: formatCurrency(summary.availableAmount, 'USD'),\n icon: <HandCoins className=\"size-5\" />,\n },\n {\n title: 'Reserved',\n value: formatCurrency(summary.reservedAmount, 'USD'),\n icon: <Coins className=\"size-5\" />,\n },\n {\n title: 'Paid out',\n value: formatCurrency(summary.paidAmount, 'USD'),\n icon: <Wallet className=\"size-5\" />,\n },\n {\n title: 'Lifetime',\n value: formatCurrency(summary.totalLifetimeAmount, 'USD'),\n icon: <RefreshCw className=\"size-5\" />,\n },\n ]\n : [];\n\n const filteredEntries =\n sourceFilter === 'ALL'\n ? entries\n : entries.filter((entry) => entry.sourceCategory === sourceFilter);\n\n const categoryCards =\n summary?.categoryBreakdown?.map((item) => ({\n title: `${item.category} earnings`,\n value: formatCurrency(item.amount, 'USD'),\n helperText: `${item.count} entries`,\n })) ?? [];\n\n const developerPortalCards = developerPortalRevenue?.summary\n ? [\n {\n title: 'Gross revenue',\n value: formatCurrency(developerPortalRevenue.summary.totalGrossRevenue, 'USD'),\n icon: <HandCoins className=\"size-5\" />,\n },\n {\n title: 'Net revenue',\n value: formatCurrency(developerPortalRevenue.summary.totalNetRevenue, 'USD'),\n icon: <Wallet className=\"size-5\" />,\n },\n {\n title: 'Pending balance',\n value: formatCurrency(developerPortalRevenue.summary.pendingBalance, 'USD'),\n icon: <Coins className=\"size-5\" />,\n },\n {\n title: 'Platform fees',\n value: formatCurrency(developerPortalRevenue.summary.totalPlatformFees, 'USD'),\n icon: <RefreshCw className=\"size-5\" />,\n },\n ]\n : [];\n\n const isDeveloperPortalMode = !!developerOrgId;\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={isDeveloperPortalMode ? 'Marketplace earnings' : 'Earnings'}\n description={\n isDeveloperPortalMode\n ? `Developer portal revenue, sales, and payouts${developerOrgName ? ` for ${developerOrgName}` : ''}.`\n : 'Track affiliate, store, and other earning sources in one ledger.'\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-subtle bg-bg-surface\"\n />\n ))}\n </div>\n ) : isDeveloperPortalMode ? (\n developerPortalRevenue?.summary ? (\n <div className=\"space-y-6\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {developerPortalCards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent sales</h2>\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n </div>\n\n {developerPortalRevenue.sales.length === 0 ? (\n <EmptyState\n icon={<Coins className=\"size-8\" />}\n title=\"No sales yet\"\n description=\"Sales will appear here when customers start purchasing your apps.\"\n />\n ) : (\n <ResponsiveTable\n data={developerPortalRevenue.sales}\n rowKey={(sale) => sale.id}\n columns={salesColumns}\n />\n )}\n </section>\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Payouts</h2>\n\n {developerPortalRevenue.payouts.length === 0 ? (\n <EmptyState\n icon={<Wallet className=\"size-8\" />}\n title=\"No payouts yet\"\n description=\"Scheduled and completed payouts will appear here.\"\n />\n ) : (\n <ResponsiveTable\n data={developerPortalRevenue.payouts}\n rowKey={(payout) => payout.id}\n columns={payoutColumns}\n />\n )}\n </section>\n </div>\n ) : (\n <EmptyState\n icon={<Coins className=\"size-8\" />}\n title=\"No developer portal revenue yet\"\n description=\"Marketplace revenue will appear here once your developer organization records sales.\"\n />\n )\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 {categoryCards.length > 0 ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {categoryCards.map((card) => (\n <div key={card.title} className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-sm text-text-secondary\">{card.title}</p>\n <p className=\"mt-2 text-xl font-semibold text-text-primary\">{card.value}</p>\n <p className=\"mt-1 text-xs text-text-secondary\">{card.helperText}</p>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n {error && !isServerError(error) ? (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text\">\n {error.message}\n </div>\n ) : null}\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Ledger</h2>\n <div className=\"flex items-center gap-3\">\n <select\n value={sourceFilter}\n onChange={(event) => setSourceFilter(event.target.value as EarningsSourceFilter)}\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"ALL\">All sources</option>\n <option value=\"AFFILIATE\">Affiliate</option>\n <option value=\"STORE\">Store</option>\n <option value=\"OTHER\">Other</option>\n </select>\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n </div>\n </div>\n\n {filteredEntries.length === 0 && !loading ? (\n <EmptyState\n icon={<Coins className=\"size-8\" />}\n title=\"No earnings yet\"\n description=\"Eligible affiliate rewards and other earnings will appear here.\"\n />\n ) : (\n <ResponsiveTable\n data={filteredEntries}\n rowKey={(entry) => entry.id}\n columns={ledgerColumns}\n />\n )}\n </section>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -13,8 +13,9 @@ import { approvePayoutRequest as u, fetchAdminPayoutRequests as d, fetchAdminPay
13
13
  import { useEffect as h, useMemo as g, useState as _ } from "react";
14
14
  import { AlertTriangle as v, Banknote as y, CheckCircle2 as b, ChevronDown as x, ChevronUp as S, Clock as C, CreditCard as w, ReceiptText as T, RefreshCw as E, XCircle as D } from "lucide-react";
15
15
  import { Fragment as O, jsx as k, jsxs as A } from "react/jsx-runtime";
16
+ import { ResponsiveDialog as j, ResponsiveDialogContent as M, ResponsiveDialogDescription as N, ResponsiveDialogFooter as P, ResponsiveDialogHeader as F, ResponsiveDialogTitle as I } from "@burdenoff/fe-libs/ui";
16
17
  //#region src/billing/modules/earnings/pages/PayoutAdminPage.tsx
17
- var j = {
18
+ var L = {
18
19
  REQUESTED: "Requested",
19
20
  APPROVED: "Approved",
20
21
  REJECTED: "Rejected",
@@ -22,7 +23,7 @@ var j = {
22
23
  PAID: "Paid",
23
24
  FAILED: "Failed",
24
25
  CANCELED: "Canceled"
25
- }, M = {
26
+ }, R = {
26
27
  REQUESTED: "bg-status-warning-bg-subtle text-status-warning-text",
27
28
  APPROVED: "bg-status-info-bg-subtle text-status-info-text",
28
29
  REJECTED: "bg-status-error-bg-subtle text-status-error-text",
@@ -31,13 +32,13 @@ var j = {
31
32
  FAILED: "bg-status-error-bg-subtle text-status-error-text",
32
33
  CANCELED: "bg-bg-sunken text-text-muted"
33
34
  };
34
- function N({ status: e }) {
35
+ function z({ status: e }) {
35
36
  return /* @__PURE__ */ k("span", {
36
- className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${M[e] ?? "bg-bg-sunken text-text-muted"}`,
37
- children: j[e] ?? e
37
+ className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${R[e] ?? "bg-bg-sunken text-text-muted"}`,
38
+ children: L[e] ?? e
38
39
  });
39
40
  }
40
- function P({ account: e }) {
41
+ function B({ account: e }) {
41
42
  let [t, n] = _(!1), r = e.accountDetails;
42
43
  return /* @__PURE__ */ A("div", {
43
44
  className: "rounded-md border border-border-subtle bg-bg-sunken/40 p-3 text-sm",
@@ -145,7 +146,7 @@ function P({ account: e }) {
145
146
  })]
146
147
  });
147
148
  }
148
- function F({ request: e, onApprove: t, onReject: n, onMarkPaid: r }) {
149
+ function V({ request: e, onApprove: t, onReject: n, onMarkPaid: r }) {
149
150
  let i = e.status === "REQUESTED" || e.status === "REJECTED", a = e.status === "REQUESTED" || e.status === "APPROVED", c = e.status === "APPROVED" || e.status === "PROCESSING";
150
151
  return /* @__PURE__ */ A("div", {
151
152
  className: "rounded-card border border-border-subtle bg-bg-surface p-5 space-y-4 shadow-[var(--shadow-elevation-1)] transition-all duration-200 hover:shadow-[var(--shadow-elevation-2)]",
@@ -159,7 +160,7 @@ function F({ request: e, onApprove: t, onReject: n, onMarkPaid: r }) {
159
160
  children: [/* @__PURE__ */ k("span", {
160
161
  className: "text-xl font-semibold text-text-primary",
161
162
  children: o(e.requestedAmount, e.currency)
162
- }), /* @__PURE__ */ k(N, { status: e.status })]
163
+ }), /* @__PURE__ */ k(z, { status: e.status })]
163
164
  }), /* @__PURE__ */ A("div", {
164
165
  className: "text-xs text-text-muted space-x-2",
165
166
  children: [
@@ -196,7 +197,7 @@ function F({ request: e, onApprove: t, onReject: n, onMarkPaid: r }) {
196
197
  ]
197
198
  })]
198
199
  }),
199
- e.payoutAccount && /* @__PURE__ */ k(P, { account: e.payoutAccount }),
200
+ e.payoutAccount && /* @__PURE__ */ k(B, { account: e.payoutAccount }),
200
201
  e.userNotes && /* @__PURE__ */ A("div", {
201
202
  className: "rounded-md bg-bg-sunken/40 border border-border-subtle px-3 py-2 text-sm",
202
203
  children: [/* @__PURE__ */ k("span", {
@@ -258,7 +259,7 @@ function F({ request: e, onApprove: t, onReject: n, onMarkPaid: r }) {
258
259
  ]
259
260
  });
260
261
  }
261
- function I({ summary: e }) {
262
+ function H({ summary: e }) {
262
263
  return /* @__PURE__ */ A("div", {
263
264
  className: "grid gap-3 sm:grid-cols-3",
264
265
  children: [
@@ -309,7 +310,7 @@ function I({ summary: e }) {
309
310
  ]
310
311
  });
311
312
  }
312
- function L({ dialog: e, onClose: t, onConfirm: n }) {
313
+ function U({ dialog: e, onClose: t, onConfirm: n }) {
313
314
  let [r, i] = _(""), [a, s] = _(""), [c, l] = _(""), [u, d] = _(!1), f = async () => {
314
315
  e.type === "reject" && !a.trim() || (d(!0), await n({
315
316
  notes: r.trim() || void 0,
@@ -317,26 +318,23 @@ function L({ dialog: e, onClose: t, onConfirm: n }) {
317
318
  externalReference: c.trim() || void 0
318
319
  }), d(!1));
319
320
  };
320
- return /* @__PURE__ */ k("div", {
321
- className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-overlay p-4",
322
- children: /* @__PURE__ */ A("div", {
323
- className: "w-full max-w-md rounded-card border border-border-subtle bg-bg-elevated p-6 shadow-[var(--shadow-elevation-4)] space-y-4",
321
+ return /* @__PURE__ */ k(j, {
322
+ open: !0,
323
+ onOpenChange: (e) => {
324
+ !e && !u && t();
325
+ },
326
+ children: /* @__PURE__ */ A(M, {
327
+ className: "sm:max-w-md",
324
328
  children: [
325
- /* @__PURE__ */ A("div", { children: [/* @__PURE__ */ k("h3", {
326
- className: "text-base font-semibold text-text-primary",
327
- children: {
328
- approve: "Approve withdrawal request",
329
- reject: "Reject withdrawal request",
330
- mark_paid: "Mark as paid"
331
- }[e.type]
332
- }), /* @__PURE__ */ A("p", {
333
- className: "text-sm text-text-muted mt-1",
334
- children: [
335
- o(e.amount, e.currency),
336
- " · ",
337
- e.accountLabel
338
- ]
339
- })] }),
329
+ /* @__PURE__ */ A(F, { children: [/* @__PURE__ */ k(I, { children: {
330
+ approve: "Approve withdrawal request",
331
+ reject: "Reject withdrawal request",
332
+ mark_paid: "Mark as paid"
333
+ }[e.type] }), /* @__PURE__ */ A(N, { children: [
334
+ o(e.amount, e.currency),
335
+ " · ",
336
+ e.accountLabel
337
+ ] })] }),
340
338
  e.type === "mark_paid" && /* @__PURE__ */ A("div", {
341
339
  className: "space-y-3",
342
340
  children: [/* @__PURE__ */ A("div", { children: [
@@ -349,7 +347,7 @@ function L({ dialog: e, onClose: t, onConfirm: n }) {
349
347
  value: c,
350
348
  onChange: (e) => l(e.target.value),
351
349
  placeholder: "e.g. UTR123456789012, TXN_abc123",
352
- className: "w-full rounded-input border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-ring"
350
+ className: "w-full rounded-input border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
353
351
  }),
354
352
  /* @__PURE__ */ k("p", {
355
353
  className: "text-xs text-text-muted mt-1",
@@ -363,7 +361,7 @@ function L({ dialog: e, onClose: t, onConfirm: n }) {
363
361
  onChange: (e) => i(e.target.value),
364
362
  rows: 2,
365
363
  placeholder: "Any internal notes about this payment…",
366
- className: "w-full rounded-input border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-ring resize-none"
364
+ className: "w-full rounded-input border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none"
367
365
  })] })]
368
366
  }),
369
367
  e.type === "approve" && /* @__PURE__ */ A("div", { children: [/* @__PURE__ */ k("label", {
@@ -374,7 +372,7 @@ function L({ dialog: e, onClose: t, onConfirm: n }) {
374
372
  onChange: (e) => i(e.target.value),
375
373
  rows: 3,
376
374
  placeholder: "e.g. Verified bank details, approved for transfer…",
377
- className: "w-full rounded-input border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-ring resize-none"
375
+ className: "w-full rounded-input border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none"
378
376
  })] }),
379
377
  e.type === "reject" && /* @__PURE__ */ A("div", { children: [/* @__PURE__ */ A("label", {
380
378
  className: "text-xs font-medium text-text-primary block mb-1",
@@ -387,30 +385,27 @@ function L({ dialog: e, onClose: t, onConfirm: n }) {
387
385
  onChange: (e) => s(e.target.value),
388
386
  rows: 3,
389
387
  placeholder: "e.g. Invalid bank details provided, please re-submit with correct IFSC…",
390
- className: "w-full rounded-input border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-ring resize-none"
388
+ className: "w-full rounded-input border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] resize-none"
391
389
  })] }),
392
- /* @__PURE__ */ A("div", {
393
- className: "flex justify-end gap-2 pt-2",
394
- children: [/* @__PURE__ */ k("button", {
395
- type: "button",
396
- onClick: t,
397
- disabled: u,
398
- className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary disabled:opacity-50",
399
- children: "Cancel"
400
- }), /* @__PURE__ */ k("button", {
401
- type: "button",
402
- onClick: () => void f(),
403
- disabled: u || e.type === "reject" && !a.trim(),
404
- className: `rounded-md px-4 py-2 text-sm font-medium disabled:opacity-50 ${e.type === "reject" ? "bg-action-danger-bg text-action-danger-text" : "bg-action-primary-bg text-action-primary-text"}`,
405
- children: u ? "Saving…" : e.type === "approve" ? "Approve" : e.type === "reject" ? "Reject" : "Confirm Payment"
406
- })]
407
- })
390
+ /* @__PURE__ */ A(P, { children: [/* @__PURE__ */ k("button", {
391
+ type: "button",
392
+ onClick: t,
393
+ disabled: u,
394
+ className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary disabled:opacity-50",
395
+ children: "Cancel"
396
+ }), /* @__PURE__ */ k("button", {
397
+ type: "button",
398
+ onClick: () => void f(),
399
+ disabled: u || e.type === "reject" && !a.trim(),
400
+ className: `rounded-md px-4 py-2 text-sm font-medium disabled:opacity-50 ${e.type === "reject" ? "bg-action-danger-bg text-action-danger-text" : "bg-action-primary-bg text-action-primary-text"}`,
401
+ children: u ? "Saving…" : e.type === "approve" ? "Approve" : e.type === "reject" ? "Reject" : "Confirm Payment"
402
+ })] })
408
403
  ]
409
404
  })
410
405
  });
411
406
  }
412
- var R = () => {
413
- let o = l(), { emit: s } = a(), { apiGatewayUrl: v, authToken: y, orgId: x } = e(), [S, C] = _(null), [w, T] = _([]), [D, O] = _(!0), [j, M] = _(null), [N, P] = _("pending"), [R, z] = _(null), B = g(() => ({
407
+ var W = () => {
408
+ let o = l(), { emit: s } = a(), { apiGatewayUrl: v, authToken: y, orgId: x } = e(), [S, C] = _(null), [w, T] = _([]), [D, O] = _(!0), [j, M] = _(null), [N, P] = _("pending"), [F, I] = _(null), L = g(() => ({
414
409
  apiGatewayUrl: v,
415
410
  authToken: y,
416
411
  orgId: x
@@ -418,10 +413,10 @@ var R = () => {
418
413
  v,
419
414
  y,
420
415
  x
421
- ]), V = async () => {
416
+ ]), R = async () => {
422
417
  O(!0), M(null);
423
418
  try {
424
- let [e, t] = await Promise.all([f(B), d(B)]);
419
+ let [e, t] = await Promise.all([f(L), d(L)]);
425
420
  C(e), T(t);
426
421
  } catch (e) {
427
422
  M(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load payout queue"));
@@ -430,15 +425,15 @@ var R = () => {
430
425
  }
431
426
  };
432
427
  if (h(() => {
433
- V();
434
- }, [B]), !o.isBillingAdmin) return /* @__PURE__ */ k(t, { message: "You don't have permission to manage payouts." });
428
+ R();
429
+ }, [L]), !o.isBillingAdmin) return /* @__PURE__ */ k(t, { message: "You don't have permission to manage payouts." });
435
430
  if (j && c(j)) return /* @__PURE__ */ k(i, {
436
431
  title: "Payout queue unavailable",
437
432
  message: j.message,
438
- onRetry: () => void V(),
433
+ onRetry: () => void R(),
439
434
  showRetry: !0
440
435
  });
441
- let H = w.filter((e) => e.status === "REQUESTED"), U = w.filter((e) => e.status === "APPROVED" || e.status === "PROCESSING"), W = w.filter((e) => [
436
+ let z = w.filter((e) => e.status === "REQUESTED"), B = w.filter((e) => e.status === "APPROVED" || e.status === "PROCESSING"), W = w.filter((e) => [
442
437
  "PAID",
443
438
  "REJECTED",
444
439
  "FAILED",
@@ -447,20 +442,20 @@ var R = () => {
447
442
  {
448
443
  id: "pending",
449
444
  label: "Pending",
450
- count: H.length
445
+ count: z.length
451
446
  },
452
447
  {
453
448
  id: "approved",
454
449
  label: "Approved",
455
- count: U.length
450
+ count: B.length
456
451
  },
457
452
  {
458
453
  id: "history",
459
454
  label: "History",
460
455
  count: W.length
461
456
  }
462
- ], K = N === "pending" ? H : N === "approved" ? U : W, q = (e, t) => {
463
- z({
457
+ ], K = N === "pending" ? z : N === "approved" ? B : W, q = (e, t) => {
458
+ I({
464
459
  type: e,
465
460
  requestId: t.id,
466
461
  amount: t.requestedAmount,
@@ -476,12 +471,12 @@ var R = () => {
476
471
  description: "Review withdrawal requests, verify bank details, and mark payments as paid once transferred.",
477
472
  actions: /* @__PURE__ */ A("button", {
478
473
  type: "button",
479
- onClick: () => void V(),
474
+ onClick: () => void R(),
480
475
  className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary",
481
476
  children: [/* @__PURE__ */ k(E, { className: `size-4 ${D ? "animate-spin" : ""}` }), "Refresh"]
482
477
  })
483
478
  }),
484
- S && !D && /* @__PURE__ */ k(I, { summary: S }),
479
+ S && !D && /* @__PURE__ */ k(H, { summary: S }),
485
480
  D && /* @__PURE__ */ k("div", {
486
481
  className: "grid gap-3 sm:grid-cols-3",
487
482
  children: [
@@ -509,7 +504,7 @@ var R = () => {
509
504
  }, e.id))
510
505
  })
511
506
  }),
512
- N === "approved" && U.length > 0 && /* @__PURE__ */ A("div", {
507
+ N === "approved" && B.length > 0 && /* @__PURE__ */ A("div", {
513
508
  className: "rounded-card border border-status-info-border bg-status-info-bg-subtle px-4 py-3 text-sm text-status-info-text",
514
509
  children: [
515
510
  /* @__PURE__ */ k("strong", { children: "How to pay:" }),
@@ -527,32 +522,32 @@ var R = () => {
527
522
  description: N === "pending" ? "New withdrawal requests will appear here." : N === "approved" ? "Approve pending requests first, then send payment and mark as paid." : "Completed and rejected requests will appear here."
528
523
  }) : /* @__PURE__ */ k("div", {
529
524
  className: "space-y-4",
530
- children: K.map((e) => /* @__PURE__ */ k(F, {
525
+ children: K.map((e) => /* @__PURE__ */ k(V, {
531
526
  request: e,
532
527
  onApprove: (e) => q("approve", e),
533
528
  onReject: (e) => q("reject", e),
534
529
  onMarkPaid: (e) => q("mark_paid", e)
535
530
  }, e.id))
536
531
  }),
537
- R && /* @__PURE__ */ k(L, {
538
- dialog: R,
539
- onClose: () => z(null),
532
+ F && /* @__PURE__ */ k(U, {
533
+ dialog: F,
534
+ onClose: () => I(null),
540
535
  onConfirm: async (e) => {
541
- if (R) try {
542
- R.type === "approve" ? (await u(R.requestId, e.notes ?? null, B), s("billing.payout.approved", {
536
+ if (F) try {
537
+ F.type === "approve" ? (await u(F.requestId, e.notes ?? null, L), s("billing.payout.approved", {
543
538
  route: "/billing/payouts",
544
- entityId: R.requestId,
539
+ entityId: F.requestId,
545
540
  source: "payout-admin"
546
- })) : R.type === "reject" ? (await m(R.requestId, e.reason ?? "", B), s("billing.payout.rejected", {
541
+ })) : F.type === "reject" ? (await m(F.requestId, e.reason ?? "", L), s("billing.payout.rejected", {
547
542
  route: "/billing/payouts",
548
- entityId: R.requestId,
543
+ entityId: F.requestId,
549
544
  source: "payout-admin",
550
545
  reason: e.reason
551
- })) : R.type === "mark_paid" && (await p(R.requestId, e.externalReference ?? null, e.notes ?? null, B), s("billing.payout.processed", {
546
+ })) : F.type === "mark_paid" && (await p(F.requestId, e.externalReference ?? null, e.notes ?? null, L), s("billing.payout.processed", {
552
547
  route: "/billing/payouts",
553
- entityId: R.requestId,
548
+ entityId: F.requestId,
554
549
  source: "payout-admin"
555
- })), z(null), await V();
550
+ })), I(null), await R();
556
551
  } catch (e) {
557
552
  M(e instanceof Error ? e : /* @__PURE__ */ Error("Action failed"));
558
553
  }
@@ -562,6 +557,6 @@ var R = () => {
562
557
  });
563
558
  };
564
559
  //#endregion
565
- export { R as PayoutAdminPage };
560
+ export { W as PayoutAdminPage };
566
561
 
567
562
  //# sourceMappingURL=PayoutAdminPage.js.map