@burdenoff/microfe-billing 2026.821.1 → 2026.825.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/billing/BillingAdminRoutes.js.map +1 -1
  2. package/dist/billing/BillingRoot.js.map +1 -1
  3. package/dist/billing/BillingUserRoutes.js.map +1 -1
  4. package/dist/billing/hooks/useBillingAccountSelection.js.map +1 -1
  5. package/dist/billing/hooks/useBillingEventEmitter.js.map +1 -1
  6. package/dist/billing/hooks/useBillingNavigate.js.map +1 -1
  7. package/dist/billing/hooks/useBillingPermissions.js.map +1 -1
  8. package/dist/billing/hooks/useDefaultBillingCurrency.js.map +1 -1
  9. package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
  10. package/dist/billing/modules/addons/hooks/useAddons.js.map +1 -1
  11. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  12. package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
  13. package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
  14. package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
  15. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  16. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  17. package/dist/billing/modules/addons/store/addonCartStore.js.map +1 -1
  18. package/dist/billing/modules/affiliate/api.js.map +1 -1
  19. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +107 -107
  20. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  21. package/dist/billing/modules/analytics/pages/AnalyticsPage.js +80 -81
  22. package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
  23. package/dist/billing/modules/billing/hooks/useInvoices.js.map +1 -1
  24. package/dist/billing/modules/billing/hooks/useRefunds.js.map +1 -1
  25. package/dist/billing/modules/billing/hooks/useTransactions.js.map +1 -1
  26. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  27. package/dist/billing/modules/billing/pages/InvoicesListPage.js +1 -1
  28. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  29. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  30. package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
  31. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  32. package/dist/billing/modules/billing/pages/UserRefundsPage.js +127 -127
  33. package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
  34. package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
  35. package/dist/billing/modules/checkout/components/CompleteBillingAccountModal.js.map +1 -1
  36. package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
  37. package/dist/billing/modules/checkout/components/NativeCheckoutView.js.map +1 -1
  38. package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
  39. package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
  40. package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
  41. package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
  42. package/dist/billing/modules/checkout/components/StoreShippingSection.js.map +1 -1
  43. package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
  44. package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
  45. package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
  46. package/dist/billing/modules/checkout/components/WorkspaceQuotaAssignmentModal.js.map +1 -1
  47. package/dist/billing/modules/checkout/hooks/useCheckout.js +0 -1
  48. package/dist/billing/modules/checkout/hooks/useCheckout.js.map +1 -1
  49. package/dist/billing/modules/checkout/hooks/useNativeCheckout.js.map +1 -1
  50. package/dist/billing/modules/checkout/hooks/usePaymentProviders.js.map +1 -1
  51. package/dist/billing/modules/checkout/hooks/usePaymentStatusPolling.js.map +1 -1
  52. package/dist/billing/modules/checkout/hooks/useStoreShipping.js.map +1 -1
  53. package/dist/billing/modules/checkout/pages/CheckoutPage.js +412 -395
  54. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  55. package/dist/billing/modules/checkout/utils/storeOrder.js.map +1 -1
  56. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  57. package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
  58. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  59. package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
  60. package/dist/billing/modules/credits/hooks/useCredits.js.map +1 -1
  61. package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
  62. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
  63. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  64. package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
  65. package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
  66. package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
  67. package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
  68. package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
  69. package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
  70. package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
  71. package/dist/billing/modules/dashboard/hooks/useBillingOverviewData.js.map +1 -1
  72. package/dist/billing/modules/dashboard/hooks/useDashboard.js.map +1 -1
  73. package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
  74. package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
  75. package/dist/billing/modules/earnings/api.js.map +1 -1
  76. package/dist/billing/modules/earnings/pages/DeveloperRevenueAdminPage.js +145 -145
  77. package/dist/billing/modules/earnings/pages/DeveloperRevenueAdminPage.js.map +1 -1
  78. package/dist/billing/modules/earnings/pages/EarningsPage.js +133 -133
  79. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  80. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +7 -9
  81. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  82. package/dist/billing/modules/earnings/pages/PayoutsPage.js +95 -95
  83. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  84. package/dist/billing/modules/plans/constants/featuredQuotas.js.map +1 -1
  85. package/dist/billing/modules/plans/hooks/usePlans.js.map +1 -1
  86. package/dist/billing/modules/plans/hooks/useQuotas.js.map +1 -1
  87. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  88. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
  89. package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
  90. package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
  91. package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
  92. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  93. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  94. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  95. package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
  96. package/dist/billing/modules/quota/hooks/useQuotaTemplates.js.map +1 -1
  97. package/dist/billing/modules/quota/pages/QuotaAssignFreePage.js.map +1 -1
  98. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
  99. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
  100. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
  101. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  102. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  103. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  104. package/dist/billing/modules/store/pages/StoreCheckoutPage.js +5 -6
  105. package/dist/billing/modules/store/pages/StoreCheckoutPage.js.map +1 -1
  106. package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
  107. package/dist/billing/modules/subscriptions/hooks/useSubscriptions.js.map +1 -1
  108. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  109. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  110. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  111. package/dist/billing/modules/usage/hooks/useUsage.js +14 -9
  112. package/dist/billing/modules/usage/hooks/useUsage.js.map +1 -1
  113. package/dist/billing/modules/usage/pages/UsagePage.js +481 -453
  114. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  115. package/dist/billing/providers/BillingProvider.js.map +1 -1
  116. package/dist/billing/shared/components/AccessDenied.js.map +1 -1
  117. package/dist/billing/shared/components/ActorIdentity.js.map +1 -1
  118. package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
  119. package/dist/billing/shared/components/EmptyState.js.map +1 -1
  120. package/dist/billing/shared/components/PageHeader.js.map +1 -1
  121. package/dist/billing/shared/components/ServerError.js.map +1 -1
  122. package/dist/billing/shared/components/StatCard.js.map +1 -1
  123. package/dist/billing/shared/hooks/useActorProfiles.js.map +1 -1
  124. package/dist/billing/shared/types/graphql.js.map +1 -1
  125. package/dist/billing/shared/ui/Card.js.map +1 -1
  126. package/dist/billing/shared/ui/MetricCard.js.map +1 -1
  127. package/dist/billing/shared/ui/ProgressBar.js.map +1 -1
  128. package/dist/billing/shared/ui/StatusPill.js.map +1 -1
  129. package/dist/billing/shared/utils/directBillingGraphql.js.map +1 -1
  130. package/dist/billing/shared/utils/error.js.map +1 -1
  131. package/dist/billing/shared/utils/format.js.map +1 -1
  132. package/dist/billing/shared/utils/gatewayGraphql.js.map +1 -1
  133. package/dist/billing/shared/utils/navigation.js.map +1 -1
  134. package/dist/billing/shared/utils/paymentTheme.js.map +1 -1
  135. package/dist/billing/shared/utils/planFeatureQuantity.js.map +1 -1
  136. package/dist/billing/shared/utils/status.js.map +1 -1
  137. package/dist/billing/shared/utils/tokens.js.map +1 -1
  138. package/dist/generated/global-operations.js +5 -1
  139. package/dist/generated/global-operations.js.map +1 -1
  140. package/dist/generated/global-types.js.map +1 -1
  141. package/dist/generated/wspace-operations.js +1 -1
  142. package/dist/generated/wspace-operations.js.map +1 -1
  143. package/dist/node_modules/@capacitor/core/dist/index.js +1 -1
  144. package/dist/node_modules/@capacitor/core/dist/index.js.map +1 -1
  145. package/package.json +13 -10
@@ -1 +1 @@
1
- {"version":3,"file":"DeveloperRevenueAdminPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/DeveloperRevenueAdminPage.tsx"],"sourcesContent":["import { useEffect, useMemo, useState, type FC } from 'react';\nimport { Building2, CreditCard, DollarSign, Loader2, Receipt, Wallet } from 'lucide-react';\n\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { AccessDenied, PageHeader, ServerError } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport {\n PagePurpose,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport {\n fetchAdminDeveloperRevenueOrgDetail,\n fetchAdminDeveloperRevenueOrgs,\n retrySaleCreditSync,\n type AdminDeveloperRevenueOrg,\n type AdminDeveloperRevenueOrgDetail,\n} from '../api';\n\nfunction SummaryCards({ orgs }: { orgs: AdminDeveloperRevenueOrg[] }) {\n const totals = useMemo(\n () =>\n orgs.reduce(\n (acc, org) => ({\n totalRevenue: acc.totalRevenue + org.totalRevenue,\n totalPlatformFees: acc.totalPlatformFees + org.totalPlatformFees,\n pendingBalance: acc.pendingBalance + org.pendingBalance,\n totalPayouts: acc.totalPayouts + org.totalPayouts,\n }),\n { totalRevenue: 0, totalPlatformFees: 0, pendingBalance: 0, totalPayouts: 0 }\n ),\n [orgs]\n );\n\n return (\n <div className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-4\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Gross revenue</div>\n <div className=\"mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <DollarSign className=\"size-4 text-text-muted\" />\n {formatCurrency(totals.totalRevenue, 'USD')}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Platform fees</div>\n <div className=\"mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <Receipt className=\"size-4 text-text-muted\" />\n {formatCurrency(totals.totalPlatformFees, 'USD')}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Pending earned credits</div>\n <div className=\"mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <Wallet className=\"size-4 text-text-muted\" />\n {formatCurrency(totals.pendingBalance, 'USD')}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Already withdrawn</div>\n <div className=\"mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <Building2 className=\"size-4 text-text-muted\" />\n {formatCurrency(totals.totalPayouts, 'USD')}\n </div>\n </div>\n </div>\n );\n}\n\nfunction RevenueDetailDialog({\n org,\n detail,\n loading,\n error,\n retryingSaleId,\n onRetrySale,\n onClose,\n}: {\n org: AdminDeveloperRevenueOrg | null;\n detail: AdminDeveloperRevenueOrgDetail | null;\n loading: boolean;\n error: Error | null;\n retryingSaleId: string | null;\n onRetrySale: (saleId: string) => void;\n onClose: () => void;\n}) {\n return (\n <ResponsiveDialog open={org !== null} onOpenChange={(open) => !open && onClose()}>\n <ResponsiveDialogContent className=\"sm:max-w-4xl\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>{org ? `${org.name} revenue details` : 'Revenue details'}</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Store revenue is credited into the linked billing account as earned credits. Developers withdraw those credits later through the billing withdrawal flow.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n {loading ? (\n <div className=\"flex items-center justify-center py-14 text-text-secondary\">\n <Loader2 className=\"size-7 animate-spin\" />\n </div>\n ) : error ? (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle p-4 text-sm text-status-error-text\">\n {error.message}\n </div>\n ) : detail && org ? (\n <div className=\"space-y-5\">\n <div className=\"grid gap-3 md:grid-cols-4\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Linked billing account</div>\n <div className=\"mt-1 text-sm font-semibold text-text-primary\">\n {org.billingAccountId ? 'Connected' : 'Not linked'}\n </div>\n <div className=\"mt-1 break-all text-xs text-text-muted\">\n {org.billingAccountId ?? 'Revenue cannot be credited until a billing account is linked.'}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Earned credits awaiting withdrawal</div>\n <div className=\"mt-1 text-lg font-semibold text-text-primary\">\n {formatCurrency(detail.summary?.pendingBalance ?? org.pendingBalance, 'USD')}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Unpaid sales</div>\n <div className=\"mt-1 text-lg font-semibold text-text-primary\">{detail.unpaidSales.totalCount}</div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Total sales</div>\n <div className=\"mt-1 text-lg font-semibold text-text-primary\">{detail.summary?.totalSales ?? 0}</div>\n </div>\n </div>\n\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <CreditCard className=\"mt-0.5 size-5 text-text-muted\" />\n <div className=\"space-y-1 text-sm\">\n <p className=\"font-medium text-text-primary\">Correct payout model</p>\n <p className=\"text-text-muted\">\n Revenue from Store sales is posted into the developer organization&apos;s linked billing account as <strong>earned credits</strong>. We do not directly send cash to developer-org payment methods from this page.\n </p>\n <p className=\"text-text-muted\">\n If the developer wants to cash out, they use the billing withdrawal flow from their own billing account and payout methods.\n </p>\n </div>\n </div>\n </div>\n\n <section className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Sales currently contributing to earned credits</h3>\n <p className=\"mt-1 text-xs text-text-muted\">\n These sales represent revenue that should exist as earned credits in the linked billing account until the developer withdraws them.\n </p>\n <div className=\"mt-4 overflow-x-auto\">\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-bg-sunken/60 text-left text-xs uppercase tracking-wide text-text-muted\">\n <tr>\n <th className=\"px-3 py-2\">Application</th>\n <th className=\"px-3 py-2\">Purchased</th>\n <th className=\"px-3 py-2\">Net revenue</th>\n <th className=\"px-3 py-2\">Credit sync</th>\n <th className=\"px-3 py-2\">Status</th>\n </tr>\n </thead>\n <tbody>\n {detail.unpaidSales.items.length === 0 ? (\n <tr>\n <td colSpan={5} className=\"px-3 py-5 text-center text-sm text-text-muted\">\n No outstanding unpaid sales. Revenue has either not started yet or has already been withdrawn through billing.\n </td>\n </tr>\n ) : (\n detail.unpaidSales.items.map((sale) => (\n <tr key={sale.id} className=\"border-t border-border-seam\">\n <td className=\"px-3 py-2\">\n <div className=\"font-medium text-text-primary\">{sale.application?.name ?? 'Unknown app'}</div>\n <div className=\"text-xs text-text-muted\">/{sale.application?.slug ?? 'unknown'}</div>\n </td>\n <td className=\"px-3 py-2 text-text-secondary\">{formatDateTime(sale.purchasedAt)}</td>\n <td className=\"px-3 py-2 text-text-primary\">{formatCurrency(sale.netAmount, sale.currency)}</td>\n <td className=\"px-3 py-2 text-text-secondary\">\n <div>{sale.billingCreditSyncStatus ?? 'UNKNOWN'}</div>\n {sale.billingCreditSyncError && (\n <div className=\"mt-1 text-xs text-status-error-text\">{sale.billingCreditSyncError}</div>\n )}\n {sale.billingCreditSyncStatus !== 'SYNCED' && org.billingAccountId && (\n <button\n type=\"button\"\n onClick={() => onRetrySale(sale.id)}\n disabled={retryingSaleId === sale.id}\n className=\"mt-2 rounded-md border border-border-subtle px-2 py-1 text-xs font-medium text-text-primary disabled:opacity-50\"\n >\n {retryingSaleId === sale.id ? 'Retrying…' : 'Retry sync'}\n </button>\n )}\n </td>\n <td className=\"px-3 py-2 text-text-secondary\">{sale.status}</td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </section>\n </div>\n ) : null}\n\n <ResponsiveDialogFooter>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary\"\n >\n Close\n </button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\nexport const DeveloperRevenueAdminPage: FC = () => {\n const permissions = useBillingPermissions();\n const { apiGatewayUrl, authToken, orgId, navigate, basePath } = useBilling();\n const [orgs, setOrgs] = useState<AdminDeveloperRevenueOrg[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [selectedOrg, setSelectedOrg] = useState<AdminDeveloperRevenueOrg | null>(null);\n const [detail, setDetail] = useState<AdminDeveloperRevenueOrgDetail | null>(null);\n const [detailLoading, setDetailLoading] = useState(false);\n const [detailError, setDetailError] = useState<Error | null>(null);\n const [retryingSaleId, setRetryingSaleId] = useState<string | null>(null);\n\n const requestContext = useMemo(() => ({ apiGatewayUrl, authToken, orgId }), [apiGatewayUrl, authToken, orgId]);\n\n const loadOrgs = async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await fetchAdminDeveloperRevenueOrgs(requestContext);\n setOrgs(result.filter((org) => org.totalRevenue > 0 || org.pendingBalance > 0 || org.totalPayouts > 0));\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load developer revenue'));\n } finally {\n setLoading(false);\n }\n };\n\n const loadDetail = async (org: AdminDeveloperRevenueOrg) => {\n setSelectedOrg(org);\n setDetailLoading(true);\n setDetailError(null);\n try {\n setDetail(await fetchAdminDeveloperRevenueOrgDetail(org.id, requestContext));\n } catch (loadError) {\n setDetail(null);\n setDetailError(loadError instanceof Error ? loadError : new Error('Failed to load revenue detail'));\n } finally {\n setDetailLoading(false);\n }\n };\n\n useEffect(() => {\n if (!permissions.isBillingAdmin) return;\n void loadOrgs();\n }, [permissions.isBillingAdmin, requestContext]);\n\n if (!permissions.isBillingAdmin) {\n return <AccessDenied message=\"You don't have permission to view developer revenue.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Developer revenue unavailable\"\n message={error.message}\n showRetry\n onRetry={() => void loadOrgs()}\n />\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Developer revenue\"\n description=\"See store-generated revenue across developer organizations and confirm that the earnings are flowing into linked billing accounts as earned credits.\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigate?.(`${basePath}/payouts`)}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n Open billing withdrawal queue\n </button>\n }\n />\n\n <PagePurpose>\n Developer portal revenue does not pay out directly from this page. Each Store sale is credited into the developer organization&apos;s linked billing account as earned credits. Developers then withdraw those credits later using the billing withdrawal flow and their own payout methods.\n </PagePurpose>\n\n {loading ? (\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"size-8 animate-spin\" />\n </div>\n ) : (\n <>\n <SummaryCards orgs={orgs} />\n\n <div className=\"overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-[var(--shadow-elevation-1)]\">\n <div className=\"border-b border-border-seam px-5 py-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">Organizations</h2>\n <p className=\"mt-1 text-sm text-text-muted\">Click a row to inspect billing linkage and the unpaid sales behind the current earned-credit balance.</p>\n </div>\n\n {orgs.length === 0 ? (\n <div className=\"px-5 py-12 text-center text-sm text-text-muted\">No developer revenue has been recorded yet.</div>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-bg-sunken/60 text-left text-xs uppercase tracking-wide text-text-muted\">\n <tr>\n <th className=\"px-4 py-3\">Organization</th>\n <th className=\"px-4 py-3\">Billing linked</th>\n <th className=\"px-4 py-3\">Revenue</th>\n <th className=\"px-4 py-3\">Platform fee</th>\n <th className=\"px-4 py-3\">Earned credits pending withdrawal</th>\n <th className=\"px-4 py-3\">Already withdrawn</th>\n </tr>\n </thead>\n <tbody>\n {[...orgs].sort((a, b) => b.pendingBalance - a.pendingBalance).map((org) => (\n <tr\n key={org.id}\n className=\"cursor-pointer border-t border-border-seam transition-colors hover:bg-bg-sunken/30\"\n onClick={() => void loadDetail(org)}\n >\n <td className=\"px-4 py-3\">\n <div className=\"font-medium text-text-primary\">{org.name}</div>\n <div className=\"text-xs text-text-muted\">/{org.slug}</div>\n </td>\n <td className=\"px-4 py-3 text-text-secondary\">{org.billingAccountId ? 'Yes' : 'No'}</td>\n <td className=\"px-4 py-3 text-text-primary\">{formatCurrency(org.totalRevenue, 'USD')}</td>\n <td className=\"px-4 py-3 text-text-secondary\">{formatCurrency(org.totalPlatformFees, 'USD')}</td>\n <td className=\"px-4 py-3 font-medium text-status-warning-text\">{formatCurrency(org.pendingBalance, 'USD')}</td>\n <td className=\"px-4 py-3 text-text-secondary\">{formatCurrency(org.totalPayouts, 'USD')}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </>\n )}\n\n <RevenueDetailDialog\n org={selectedOrg}\n detail={detail}\n loading={detailLoading}\n error={detailError}\n retryingSaleId={retryingSaleId}\n onRetrySale={(saleId) => {\n if (!selectedOrg) return;\n void (async () => {\n setRetryingSaleId(saleId);\n setDetailError(null);\n try {\n await retrySaleCreditSync(saleId, requestContext);\n await loadDetail(selectedOrg);\n } catch (retryError) {\n setDetailError(retryError instanceof Error ? retryError : new Error('Failed to retry credit sync'));\n } finally {\n setRetryingSaleId(null);\n }\n })();\n }}\n onClose={() => {\n setSelectedOrg(null);\n setDetail(null);\n setDetailError(null);\n }}\n />\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"DeveloperRevenueAdminPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/DeveloperRevenueAdminPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState, type FC } from 'react';\nimport { Building2, CreditCard, DollarSign, Loader2, Receipt, Wallet } from 'lucide-react';\n\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { AccessDenied, PageHeader, ServerError } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport {\n PagePurpose,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n} from '@burdenoff/fe-libs/ui';\nimport {\n fetchAdminDeveloperRevenueOrgDetail,\n fetchAdminDeveloperRevenueOrgs,\n retrySaleCreditSync,\n type AdminDeveloperRevenueOrg,\n type AdminDeveloperRevenueOrgDetail,\n} from '../api';\n\nfunction SummaryCards({ orgs }: { orgs: AdminDeveloperRevenueOrg[] }) {\n const totals = useMemo(\n () =>\n orgs.reduce(\n (acc, org) => ({\n totalRevenue: acc.totalRevenue + org.totalRevenue,\n totalPlatformFees: acc.totalPlatformFees + org.totalPlatformFees,\n pendingBalance: acc.pendingBalance + org.pendingBalance,\n totalPayouts: acc.totalPayouts + org.totalPayouts,\n }),\n { totalRevenue: 0, totalPlatformFees: 0, pendingBalance: 0, totalPayouts: 0 }\n ),\n [orgs]\n );\n\n return (\n <div className=\"grid gap-3 md:grid-cols-2 xl:grid-cols-4\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Gross revenue</div>\n <div className=\"mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <DollarSign className=\"size-4 text-text-muted\" />\n {formatCurrency(totals.totalRevenue, 'USD')}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Platform fees</div>\n <div className=\"mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <Receipt className=\"size-4 text-text-muted\" />\n {formatCurrency(totals.totalPlatformFees, 'USD')}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">\n Pending earned credits\n </div>\n <div className=\"mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <Wallet className=\"size-4 text-text-muted\" />\n {formatCurrency(totals.pendingBalance, 'USD')}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Already withdrawn</div>\n <div className=\"mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <Building2 className=\"size-4 text-text-muted\" />\n {formatCurrency(totals.totalPayouts, 'USD')}\n </div>\n </div>\n </div>\n );\n}\n\nfunction RevenueDetailDialog({\n org,\n detail,\n loading,\n error,\n retryingSaleId,\n onRetrySale,\n onClose,\n}: {\n org: AdminDeveloperRevenueOrg | null;\n detail: AdminDeveloperRevenueOrgDetail | null;\n loading: boolean;\n error: Error | null;\n retryingSaleId: string | null;\n onRetrySale: (saleId: string) => void;\n onClose: () => void;\n}) {\n return (\n <ResponsiveDialog open={org !== null} onOpenChange={(open) => !open && onClose()}>\n <ResponsiveDialogContent className=\"sm:max-w-4xl\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {org ? `${org.name} revenue details` : 'Revenue details'}\n </ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Store revenue is credited into the linked billing account as earned credits. Developers\n withdraw those credits later through the billing withdrawal flow.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n {loading ? (\n <div className=\"flex items-center justify-center py-14 text-text-secondary\">\n <Loader2 className=\"size-7 animate-spin\" />\n </div>\n ) : error ? (\n <div className=\"rounded-lg border border-status-error-border bg-status-error-bg-subtle p-4 text-sm text-status-error-text\">\n {error.message}\n </div>\n ) : detail && org ? (\n <div className=\"space-y-5\">\n <div className=\"grid gap-3 md:grid-cols-4\">\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">\n Linked billing account\n </div>\n <div className=\"mt-1 text-sm font-semibold text-text-primary\">\n {org.billingAccountId ? 'Connected' : 'Not linked'}\n </div>\n <div className=\"mt-1 break-all text-xs text-text-muted\">\n {org.billingAccountId ??\n 'Revenue cannot be credited until a billing account is linked.'}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">\n Earned credits awaiting withdrawal\n </div>\n <div className=\"mt-1 text-lg font-semibold text-text-primary\">\n {formatCurrency(detail.summary?.pendingBalance ?? org.pendingBalance, 'USD')}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Unpaid sales</div>\n <div className=\"mt-1 text-lg font-semibold text-text-primary\">\n {detail.unpaidSales.totalCount}\n </div>\n </div>\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"text-xs uppercase tracking-wide text-text-muted\">Total sales</div>\n <div className=\"mt-1 text-lg font-semibold text-text-primary\">\n {detail.summary?.totalSales ?? 0}\n </div>\n </div>\n </div>\n\n <div className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <div className=\"flex items-start gap-3\">\n <CreditCard className=\"mt-0.5 size-5 text-text-muted\" />\n <div className=\"space-y-1 text-sm\">\n <p className=\"font-medium text-text-primary\">Correct payout model</p>\n <p className=\"text-text-muted\">\n Revenue from Store sales is posted into the developer organization&apos;s linked\n billing account as <strong>earned credits</strong>. We do not directly send cash\n to developer-org payment methods from this page.\n </p>\n <p className=\"text-text-muted\">\n If the developer wants to cash out, they use the billing withdrawal flow from\n their own billing account and payout methods.\n </p>\n </div>\n </div>\n </div>\n\n <section className=\"rounded-card border border-border-seam bg-bg-surface p-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Sales currently contributing to earned credits\n </h3>\n <p className=\"mt-1 text-xs text-text-muted\">\n These sales represent revenue that should exist as earned credits in the linked\n billing account until the developer withdraws them.\n </p>\n <div className=\"mt-4 overflow-x-auto\">\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-bg-sunken/60 text-left text-xs uppercase tracking-wide text-text-muted\">\n <tr>\n <th className=\"px-3 py-2\">Application</th>\n <th className=\"px-3 py-2\">Purchased</th>\n <th className=\"px-3 py-2\">Net revenue</th>\n <th className=\"px-3 py-2\">Credit sync</th>\n <th className=\"px-3 py-2\">Status</th>\n </tr>\n </thead>\n <tbody>\n {detail.unpaidSales.items.length === 0 ? (\n <tr>\n <td colSpan={5} className=\"px-3 py-5 text-center text-sm text-text-muted\">\n No outstanding unpaid sales. Revenue has either not started yet or has\n already been withdrawn through billing.\n </td>\n </tr>\n ) : (\n detail.unpaidSales.items.map((sale) => (\n <tr key={sale.id} className=\"border-t border-border-seam\">\n <td className=\"px-3 py-2\">\n <div className=\"font-medium text-text-primary\">\n {sale.application?.name ?? 'Unknown app'}\n </div>\n <div className=\"text-xs text-text-muted\">\n /{sale.application?.slug ?? 'unknown'}\n </div>\n </td>\n <td className=\"px-3 py-2 text-text-secondary\">\n {formatDateTime(sale.purchasedAt)}\n </td>\n <td className=\"px-3 py-2 text-text-primary\">\n {formatCurrency(sale.netAmount, sale.currency)}\n </td>\n <td className=\"px-3 py-2 text-text-secondary\">\n <div>{sale.billingCreditSyncStatus ?? 'UNKNOWN'}</div>\n {sale.billingCreditSyncError && (\n <div className=\"mt-1 text-xs text-status-error-text\">\n {sale.billingCreditSyncError}\n </div>\n )}\n {sale.billingCreditSyncStatus !== 'SYNCED' && org.billingAccountId && (\n <button\n type=\"button\"\n onClick={() => onRetrySale(sale.id)}\n disabled={retryingSaleId === sale.id}\n className=\"mt-2 rounded-md border border-border-subtle px-2 py-1 text-xs font-medium text-text-primary disabled:opacity-50\"\n >\n {retryingSaleId === sale.id ? 'Retrying…' : 'Retry sync'}\n </button>\n )}\n </td>\n <td className=\"px-3 py-2 text-text-secondary\">{sale.status}</td>\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </section>\n </div>\n ) : null}\n\n <ResponsiveDialogFooter>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary\"\n >\n Close\n </button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n\nexport const DeveloperRevenueAdminPage: FC = () => {\n const permissions = useBillingPermissions();\n const { apiGatewayUrl, authToken, orgId, navigate, basePath } = useBilling();\n const [orgs, setOrgs] = useState<AdminDeveloperRevenueOrg[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const [selectedOrg, setSelectedOrg] = useState<AdminDeveloperRevenueOrg | null>(null);\n const [detail, setDetail] = useState<AdminDeveloperRevenueOrgDetail | null>(null);\n const [detailLoading, setDetailLoading] = useState(false);\n const [detailError, setDetailError] = useState<Error | null>(null);\n const [retryingSaleId, setRetryingSaleId] = useState<string | null>(null);\n\n const requestContext = useMemo(\n () => ({ apiGatewayUrl, authToken, orgId }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadOrgs = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n const result = await fetchAdminDeveloperRevenueOrgs(requestContext);\n setOrgs(\n result.filter(\n (org) => org.totalRevenue > 0 || org.pendingBalance > 0 || org.totalPayouts > 0\n )\n );\n } catch (loadError) {\n setError(\n loadError instanceof Error ? loadError : new Error('Failed to load developer revenue')\n );\n } finally {\n setLoading(false);\n }\n }, [requestContext]);\n\n const loadDetail = async (org: AdminDeveloperRevenueOrg) => {\n setSelectedOrg(org);\n setDetailLoading(true);\n setDetailError(null);\n try {\n setDetail(await fetchAdminDeveloperRevenueOrgDetail(org.id, requestContext));\n } catch (loadError) {\n setDetail(null);\n setDetailError(\n loadError instanceof Error ? loadError : new Error('Failed to load revenue detail')\n );\n } finally {\n setDetailLoading(false);\n }\n };\n\n useEffect(() => {\n if (!permissions.isBillingAdmin) return;\n void loadOrgs();\n }, [loadOrgs, permissions.isBillingAdmin]);\n\n if (!permissions.isBillingAdmin) {\n return <AccessDenied message=\"You don't have permission to view developer revenue.\" />;\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Developer revenue unavailable\"\n message={error.message}\n showRetry\n onRetry={() => void loadOrgs()}\n />\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title=\"Developer revenue\"\n description=\"See store-generated revenue across developer organizations and confirm that the earnings are flowing into linked billing accounts as earned credits.\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigate?.(`${basePath}/payouts`)}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n Open billing withdrawal queue\n </button>\n }\n />\n\n <PagePurpose>\n Developer portal revenue does not pay out directly from this page. Each Store sale is\n credited into the developer organization&apos;s linked billing account as earned credits.\n Developers then withdraw those credits later using the billing withdrawal flow and their own\n payout methods.\n </PagePurpose>\n\n {loading ? (\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"size-8 animate-spin\" />\n </div>\n ) : (\n <>\n <SummaryCards orgs={orgs} />\n\n <div className=\"overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-[var(--shadow-elevation-1)]\">\n <div className=\"border-b border-border-seam px-5 py-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">Organizations</h2>\n <p className=\"mt-1 text-sm text-text-muted\">\n Click a row to inspect billing linkage and the unpaid sales behind the current\n earned-credit balance.\n </p>\n </div>\n\n {orgs.length === 0 ? (\n <div className=\"px-5 py-12 text-center text-sm text-text-muted\">\n No developer revenue has been recorded yet.\n </div>\n ) : (\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-bg-sunken/60 text-left text-xs uppercase tracking-wide text-text-muted\">\n <tr>\n <th className=\"px-4 py-3\">Organization</th>\n <th className=\"px-4 py-3\">Billing linked</th>\n <th className=\"px-4 py-3\">Revenue</th>\n <th className=\"px-4 py-3\">Platform fee</th>\n <th className=\"px-4 py-3\">Earned credits pending withdrawal</th>\n <th className=\"px-4 py-3\">Already withdrawn</th>\n </tr>\n </thead>\n <tbody>\n {[...orgs]\n .sort((a, b) => b.pendingBalance - a.pendingBalance)\n .map((org) => (\n <tr\n key={org.id}\n className=\"cursor-pointer border-t border-border-seam transition-colors hover:bg-bg-sunken/30\"\n onClick={() => void loadDetail(org)}\n >\n <td className=\"px-4 py-3\">\n <div className=\"font-medium text-text-primary\">{org.name}</div>\n <div className=\"text-xs text-text-muted\">/{org.slug}</div>\n </td>\n <td className=\"px-4 py-3 text-text-secondary\">\n {org.billingAccountId ? 'Yes' : 'No'}\n </td>\n <td className=\"px-4 py-3 text-text-primary\">\n {formatCurrency(org.totalRevenue, 'USD')}\n </td>\n <td className=\"px-4 py-3 text-text-secondary\">\n {formatCurrency(org.totalPlatformFees, 'USD')}\n </td>\n <td className=\"px-4 py-3 font-medium text-status-warning-text\">\n {formatCurrency(org.pendingBalance, 'USD')}\n </td>\n <td className=\"px-4 py-3 text-text-secondary\">\n {formatCurrency(org.totalPayouts, 'USD')}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </>\n )}\n\n <RevenueDetailDialog\n org={selectedOrg}\n detail={detail}\n loading={detailLoading}\n error={detailError}\n retryingSaleId={retryingSaleId}\n onRetrySale={(saleId) => {\n if (!selectedOrg) return;\n void (async () => {\n setRetryingSaleId(saleId);\n setDetailError(null);\n try {\n await retrySaleCreditSync(saleId, requestContext);\n await loadDetail(selectedOrg);\n } catch (retryError) {\n setDetailError(\n retryError instanceof Error ? retryError : new Error('Failed to retry credit sync')\n );\n } finally {\n setRetryingSaleId(null);\n }\n })();\n }}\n onClose={() => {\n setSelectedOrg(null);\n setDetail(null);\n setDetailError(null);\n }}\n />\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1,22 +1,22 @@
1
1
  import { useBilling as e } from "../../../providers/BillingProvider.js";
2
2
  import { AccessDenied as t } from "../../../shared/components/AccessDenied.js";
3
- import { PageHeader as ee } from "../../../shared/components/PageHeader.js";
4
- import { StatCard as n } from "../../../shared/components/StatCard.js";
5
- import { ServerError as te } from "../../../shared/components/ServerError.js";
3
+ import { PageHeader as n } from "../../../shared/components/PageHeader.js";
4
+ import { StatCard as r } from "../../../shared/components/StatCard.js";
5
+ import { ServerError as i } from "../../../shared/components/ServerError.js";
6
6
  import "../../../shared/components/index.js";
7
- import { formatCurrency as r, formatDateTime as i } from "../../../shared/utils/format.js";
8
- import { isServerError as a } from "../../../shared/utils/error.js";
7
+ import { formatCurrency as a, formatDateTime as o } from "../../../shared/utils/format.js";
8
+ import { isServerError as s } from "../../../shared/utils/error.js";
9
9
  import "../../../shared/utils/index.js";
10
- import { useBillingPermissions as ne } from "../../../hooks/useBillingPermissions.js";
11
- import { useGetDefaultBillingAccountSettingsQuery as o } from "../../../../generated/global-operations.js";
12
- import { fetchDeveloperPortalRevenueDashboard as s, fetchEarningsEntries as c, fetchEarningsSummary as l } from "../api.js";
13
- import { useEffect as u, useMemo as d, useState as f } from "react";
14
- import { Coins as p, HandCoins as m, RefreshCw as h, Wallet as g } from "lucide-react";
15
- import { useSearchParams as _ } from "react-router";
16
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
17
- import { EmphasisPanel as b, IllustratedEmptyState as x, PagePurpose as S, ResponsiveTable as C } from "@burdenoff/fe-libs/ui";
10
+ import { useBillingPermissions as c } from "../../../hooks/useBillingPermissions.js";
11
+ import { useGetDefaultBillingAccountSettingsQuery as l } from "../../../../generated/global-operations.js";
12
+ import { fetchDeveloperPortalRevenueDashboard as u, fetchEarningsEntries as d, fetchEarningsSummary as f } from "../api.js";
13
+ import { useCallback as p, useEffect as m, useMemo as h, useState as g } from "react";
14
+ import { Coins as _, HandCoins as v, RefreshCw as y, Wallet as b } from "lucide-react";
15
+ import { useSearchParams as x } from "react-router";
16
+ import { jsx as S, jsxs as C } from "react/jsx-runtime";
17
+ import { EmphasisPanel as w, IllustratedEmptyState as T, PagePurpose as E, ResponsiveTable as D } from "@burdenoff/fe-libs/ui";
18
18
  //#region src/billing/modules/earnings/pages/EarningsPage.tsx
19
- var w = [
19
+ var ee = [
20
20
  {
21
21
  key: "application",
22
22
  header: "Application",
@@ -31,17 +31,17 @@ var w = [
31
31
  {
32
32
  key: "gross",
33
33
  header: "Gross",
34
- cell: (e) => /* @__PURE__ */ v("span", {
34
+ cell: (e) => /* @__PURE__ */ S("span", {
35
35
  className: "tabular-nums",
36
- children: r(e.grossAmount, e.currency || "USD")
36
+ children: a(e.grossAmount, e.currency || "USD")
37
37
  })
38
38
  },
39
39
  {
40
40
  key: "net",
41
41
  header: "Net",
42
- cell: (e) => /* @__PURE__ */ v("span", {
42
+ cell: (e) => /* @__PURE__ */ S("span", {
43
43
  className: "tabular-nums",
44
- children: r(e.netAmount, e.currency || "USD")
44
+ children: a(e.netAmount, e.currency || "USD")
45
45
  })
46
46
  },
47
47
  {
@@ -52,9 +52,9 @@ var w = [
52
52
  {
53
53
  key: "purchased",
54
54
  header: "Purchased",
55
- cell: (e) => i(e.purchasedAt)
55
+ cell: (e) => o(e.purchasedAt)
56
56
  }
57
- ], T = [
57
+ ], O = [
58
58
  {
59
59
  key: "period",
60
60
  header: "Period",
@@ -64,9 +64,9 @@ var w = [
64
64
  {
65
65
  key: "amount",
66
66
  header: "Amount",
67
- cell: (e) => /* @__PURE__ */ v("span", {
67
+ cell: (e) => /* @__PURE__ */ S("span", {
68
68
  className: "tabular-nums",
69
- children: r(e.netAmount, e.currency || "USD")
69
+ children: a(e.netAmount, e.currency || "USD")
70
70
  })
71
71
  },
72
72
  {
@@ -77,14 +77,14 @@ var w = [
77
77
  {
78
78
  key: "scheduled",
79
79
  header: "Scheduled",
80
- cell: (e) => e.scheduledAt ? i(e.scheduledAt) : "-"
80
+ cell: (e) => e.scheduledAt ? o(e.scheduledAt) : "-"
81
81
  },
82
82
  {
83
83
  key: "completed",
84
84
  header: "Completed",
85
- cell: (e) => e.completedAt ? i(e.completedAt) : "-"
85
+ cell: (e) => e.completedAt ? o(e.completedAt) : "-"
86
86
  }
87
- ], E = [
87
+ ], k = [
88
88
  {
89
89
  key: "category",
90
90
  header: "Category",
@@ -104,9 +104,9 @@ var w = [
104
104
  {
105
105
  key: "amount",
106
106
  header: "Amount",
107
- cell: (e) => /* @__PURE__ */ v("span", {
107
+ cell: (e) => /* @__PURE__ */ S("span", {
108
108
  className: "tabular-nums",
109
- children: e.unitType === "CREDITS" ? `${e.amount.toLocaleString()} credits` : r(e.amount, e.currency || "USD")
109
+ children: e.unitType === "CREDITS" ? `${e.amount.toLocaleString()} credits` : a(e.amount, e.currency || "USD")
110
110
  })
111
111
  },
112
112
  {
@@ -117,197 +117,197 @@ var w = [
117
117
  {
118
118
  key: "created",
119
119
  header: "Created",
120
- cell: (e) => i(e.createdAt)
120
+ cell: (e) => o(e.createdAt)
121
121
  }
122
- ], D = () => {
123
- let [i] = _(), D = ne(), { apiGatewayUrl: O, authToken: k, orgId: A } = e(), j = i.get("developerOrgId"), M = i.get("developerOrgName"), { data: N, loading: P } = o({}), F = N?.getDefaultBillingAccount?.id, [I, L] = f(null), [R, z] = f([]), [B, V] = f(null), [H, U] = f("ALL"), [W, G] = f(!0), [K, q] = f(null), J = d(() => ({
124
- apiGatewayUrl: O,
125
- authToken: k,
126
- orgId: A
122
+ ], A = () => {
123
+ let [o] = x(), A = c(), { apiGatewayUrl: j, authToken: M, orgId: N } = e(), P = o.get("developerOrgId"), F = o.get("developerOrgName"), { data: te, loading: ne } = l({}), I = te?.getDefaultBillingAccount?.id, [L, R] = g(null), [z, B] = g([]), [V, H] = g(null), [U, W] = g("ALL"), [G, K] = g(!0), [q, J] = g(null), Y = h(() => ({
124
+ apiGatewayUrl: j,
125
+ authToken: M,
126
+ orgId: N
127
127
  }), [
128
- O,
129
- k,
130
- A
131
- ]), Y = async () => {
132
- G(!0), q(null);
128
+ j,
129
+ M,
130
+ N
131
+ ]), X = p(async () => {
132
+ K(!0), J(null);
133
133
  try {
134
- if (j) {
135
- V(await s(j, J)), L(null), z([]);
134
+ if (P) {
135
+ H(await u(P, Y)), R(null), B([]);
136
136
  return;
137
137
  }
138
- if (!F) {
139
- L(null), z([]), V(null);
138
+ if (!I) {
139
+ R(null), B([]), H(null);
140
140
  return;
141
141
  }
142
- let [e, t] = await Promise.all([l(F, J), c(F, J)]);
143
- L(e), z(t), V(null);
142
+ let [e, t] = await Promise.all([f(I, Y), d(I, Y)]);
143
+ R(e), B(t), H(null);
144
144
  } catch (e) {
145
- q(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load earnings"));
145
+ J(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load earnings"));
146
146
  } finally {
147
- G(!1);
147
+ K(!1);
148
148
  }
149
- };
150
- if (u(() => {
151
- Y();
152
149
  }, [
153
- F,
154
- j,
155
- J
156
- ]), !D.canViewBillingAccount) return /* @__PURE__ */ v(t, { message: "You don't have permission to view earnings." });
157
- if (!j && !F && !P) return /* @__PURE__ */ v(x, {
150
+ I,
151
+ P,
152
+ Y
153
+ ]);
154
+ if (m(() => {
155
+ X();
156
+ }, [X]), !A.canViewBillingAccount) return /* @__PURE__ */ S(t, { message: "You don't have permission to view earnings." });
157
+ if (!P && !I && !ne) return /* @__PURE__ */ S(T, {
158
158
  illustration: "empty-generic",
159
159
  title: "No billing account found",
160
160
  description: "Create a billing account first to view earnings."
161
161
  });
162
- if (K && a(K)) return /* @__PURE__ */ v(te, {
162
+ if (q && s(q)) return /* @__PURE__ */ S(i, {
163
163
  title: "Earnings unavailable",
164
- message: K.message,
165
- onRetry: () => void Y(),
164
+ message: q.message,
165
+ onRetry: () => void X(),
166
166
  showRetry: !0
167
167
  });
168
- let X = I ? [
168
+ let re = L ? [
169
169
  {
170
170
  title: "Available",
171
- value: r(I.availableAmount, "USD"),
172
- icon: /* @__PURE__ */ v(m, { className: "size-5" })
171
+ value: a(L.availableAmount, "USD"),
172
+ icon: /* @__PURE__ */ S(v, { className: "size-5" })
173
173
  },
174
174
  {
175
175
  title: "Reserved",
176
- value: r(I.reservedAmount, "USD"),
177
- icon: /* @__PURE__ */ v(p, { className: "size-5" })
176
+ value: a(L.reservedAmount, "USD"),
177
+ icon: /* @__PURE__ */ S(_, { className: "size-5" })
178
178
  },
179
179
  {
180
180
  title: "Paid out",
181
- value: r(I.paidAmount, "USD"),
182
- icon: /* @__PURE__ */ v(g, { className: "size-5" })
181
+ value: a(L.paidAmount, "USD"),
182
+ icon: /* @__PURE__ */ S(b, { className: "size-5" })
183
183
  },
184
184
  {
185
185
  title: "Lifetime",
186
- value: r(I.totalLifetimeAmount, "USD"),
187
- icon: /* @__PURE__ */ v(h, { className: "size-5" })
186
+ value: a(L.totalLifetimeAmount, "USD"),
187
+ icon: /* @__PURE__ */ S(y, { className: "size-5" })
188
188
  }
189
- ] : [], Z = H === "ALL" ? R : R.filter((e) => e.sourceCategory === H), Q = I?.categoryBreakdown?.map((e) => ({
189
+ ] : [], Z = U === "ALL" ? z : z.filter((e) => e.sourceCategory === U), Q = L?.categoryBreakdown?.map((e) => ({
190
190
  title: `${e.category} earnings`,
191
- value: r(e.amount, "USD"),
191
+ value: a(e.amount, "USD"),
192
192
  helperText: `${e.count} entries`
193
- })) ?? [], re = B?.summary ? [
193
+ })) ?? [], ie = V?.summary ? [
194
194
  {
195
195
  title: "Gross revenue",
196
- value: r(B.summary.totalGrossRevenue, "USD"),
197
- icon: /* @__PURE__ */ v(m, { className: "size-5" })
196
+ value: a(V.summary.totalGrossRevenue, "USD"),
197
+ icon: /* @__PURE__ */ S(v, { className: "size-5" })
198
198
  },
199
199
  {
200
200
  title: "Net revenue",
201
- value: r(B.summary.totalNetRevenue, "USD"),
202
- icon: /* @__PURE__ */ v(g, { className: "size-5" })
201
+ value: a(V.summary.totalNetRevenue, "USD"),
202
+ icon: /* @__PURE__ */ S(b, { className: "size-5" })
203
203
  },
204
204
  {
205
205
  title: "Pending balance",
206
- value: r(B.summary.pendingBalance, "USD"),
207
- icon: /* @__PURE__ */ v(p, { className: "size-5" })
206
+ value: a(V.summary.pendingBalance, "USD"),
207
+ icon: /* @__PURE__ */ S(_, { className: "size-5" })
208
208
  },
209
209
  {
210
210
  title: "Platform fees",
211
- value: r(B.summary.totalPlatformFees, "USD"),
212
- icon: /* @__PURE__ */ v(h, { className: "size-5" })
211
+ value: a(V.summary.totalPlatformFees, "USD"),
212
+ icon: /* @__PURE__ */ S(y, { className: "size-5" })
213
213
  }
214
- ] : [], $ = !!j;
215
- return /* @__PURE__ */ y("div", {
214
+ ] : [], $ = !!P;
215
+ return /* @__PURE__ */ C("div", {
216
216
  className: "space-y-6 p-6",
217
217
  children: [
218
- /* @__PURE__ */ v(ee, {
218
+ /* @__PURE__ */ S(n, {
219
219
  title: $ ? "Marketplace earnings" : "Earnings",
220
- description: $ ? `Developer portal revenue, sales, and payouts${M ? ` for ${M}` : ""}.` : "Track affiliate, store, and other earning sources in one ledger."
220
+ description: $ ? `Developer portal revenue, sales, and payouts${F ? ` for ${F}` : ""}.` : "Track affiliate, store, and other earning sources in one ledger."
221
221
  }),
222
- /* @__PURE__ */ v(S, { children: "See everything you have earned — from affiliate rewards, store sales and marketplace revenue — in one ledger, along with how much has been paid out and what is still pending. Filter by source to reconcile a specific stream." }),
223
- W ? /* @__PURE__ */ v("div", {
222
+ /* @__PURE__ */ S(E, { children: "See everything you have earned — from affiliate rewards, store sales and marketplace revenue — in one ledger, along with how much has been paid out and what is still pending. Filter by source to reconcile a specific stream." }),
223
+ G ? /* @__PURE__ */ S("div", {
224
224
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4",
225
225
  children: [
226
226
  1,
227
227
  2,
228
228
  3,
229
229
  4
230
- ].map((e) => /* @__PURE__ */ v("div", { className: "h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface" }, e))
231
- }) : $ ? B?.summary ? /* @__PURE__ */ y("div", {
230
+ ].map((e) => /* @__PURE__ */ S("div", { className: "h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface" }, e))
231
+ }) : $ ? V?.summary ? /* @__PURE__ */ C("div", {
232
232
  className: "space-y-6",
233
233
  children: [
234
- /* @__PURE__ */ v("div", {
234
+ /* @__PURE__ */ S("div", {
235
235
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4",
236
- children: re.map((e) => /* @__PURE__ */ v(n, {
236
+ children: ie.map((e) => /* @__PURE__ */ S(r, {
237
237
  label: e.title,
238
238
  value: e.value,
239
239
  icon: e.icon
240
240
  }, e.title))
241
241
  }),
242
- /* @__PURE__ */ y("section", {
242
+ /* @__PURE__ */ C("section", {
243
243
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
244
- children: [/* @__PURE__ */ y("div", {
244
+ children: [/* @__PURE__ */ C("div", {
245
245
  className: "mb-4 flex items-center justify-between",
246
- children: [/* @__PURE__ */ v("h2", {
246
+ children: [/* @__PURE__ */ S("h2", {
247
247
  className: "text-lg font-semibold text-text-primary",
248
248
  children: "Recent sales"
249
- }), /* @__PURE__ */ y("button", {
249
+ }), /* @__PURE__ */ C("button", {
250
250
  type: "button",
251
- onClick: () => void Y(),
251
+ onClick: () => void X(),
252
252
  className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary",
253
- children: [/* @__PURE__ */ v(h, { className: "size-4" }), "Refresh"]
253
+ children: [/* @__PURE__ */ S(y, { className: "size-4" }), "Refresh"]
254
254
  })]
255
- }), B.sales.length === 0 ? /* @__PURE__ */ v(x, {
255
+ }), V.sales.length === 0 ? /* @__PURE__ */ S(T, {
256
256
  illustration: "empty-data",
257
257
  title: "No sales yet",
258
258
  description: "Sales will appear here when customers start purchasing your apps."
259
- }) : /* @__PURE__ */ v(C, {
260
- data: B.sales,
259
+ }) : /* @__PURE__ */ S(D, {
260
+ data: V.sales,
261
261
  rowKey: (e) => e.id,
262
- columns: w
262
+ columns: ee
263
263
  })]
264
264
  }),
265
- /* @__PURE__ */ y("section", {
265
+ /* @__PURE__ */ C("section", {
266
266
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
267
- children: [/* @__PURE__ */ v("h2", {
267
+ children: [/* @__PURE__ */ S("h2", {
268
268
  className: "mb-4 text-lg font-semibold text-text-primary",
269
269
  children: "Payouts"
270
- }), B.payouts.length === 0 ? /* @__PURE__ */ v(x, {
270
+ }), V.payouts.length === 0 ? /* @__PURE__ */ S(T, {
271
271
  illustration: "empty-data",
272
272
  title: "No payouts yet",
273
273
  description: "Scheduled and completed payouts will appear here."
274
- }) : /* @__PURE__ */ v(C, {
275
- data: B.payouts,
274
+ }) : /* @__PURE__ */ S(D, {
275
+ data: V.payouts,
276
276
  rowKey: (e) => e.id,
277
- columns: T
277
+ columns: O
278
278
  })]
279
279
  })
280
280
  ]
281
- }) : /* @__PURE__ */ v(x, {
281
+ }) : /* @__PURE__ */ S(T, {
282
282
  illustration: "empty-data",
283
283
  title: "No developer portal revenue yet",
284
284
  description: "Marketplace revenue will appear here once your developer organization records sales."
285
- }) : I ? /* @__PURE__ */ y("div", {
285
+ }) : L ? /* @__PURE__ */ C("div", {
286
286
  className: "space-y-4",
287
- children: [/* @__PURE__ */ v(b, {
287
+ children: [/* @__PURE__ */ S(w, {
288
288
  className: "p-4 sm:p-5",
289
- children: /* @__PURE__ */ v("div", {
289
+ children: /* @__PURE__ */ S("div", {
290
290
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4",
291
- children: X.map((e) => /* @__PURE__ */ v(n, {
291
+ children: re.map((e) => /* @__PURE__ */ S(r, {
292
292
  label: e.title,
293
293
  value: e.value,
294
294
  icon: e.icon
295
295
  }, e.title))
296
296
  })
297
- }), Q.length > 0 ? /* @__PURE__ */ v("div", {
297
+ }), Q.length > 0 ? /* @__PURE__ */ S("div", {
298
298
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-3",
299
- children: Q.map((e) => /* @__PURE__ */ y("div", {
299
+ children: Q.map((e) => /* @__PURE__ */ C("div", {
300
300
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
301
301
  children: [
302
- /* @__PURE__ */ v("p", {
302
+ /* @__PURE__ */ S("p", {
303
303
  className: "text-sm text-text-secondary",
304
304
  children: e.title
305
305
  }),
306
- /* @__PURE__ */ v("p", {
306
+ /* @__PURE__ */ S("p", {
307
307
  className: "mt-2 text-xl font-semibold text-text-primary",
308
308
  children: e.value
309
309
  }),
310
- /* @__PURE__ */ v("p", {
310
+ /* @__PURE__ */ S("p", {
311
311
  className: "mt-1 text-xs text-text-secondary",
312
312
  children: e.helperText
313
313
  })
@@ -315,62 +315,62 @@ var w = [
315
315
  }, e.title))
316
316
  }) : null]
317
317
  }) : null,
318
- K && !a(K) ? /* @__PURE__ */ v("div", {
318
+ q && !s(q) ? /* @__PURE__ */ S("div", {
319
319
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text",
320
- children: K.message
320
+ children: q.message
321
321
  }) : null,
322
- /* @__PURE__ */ y("section", {
322
+ /* @__PURE__ */ C("section", {
323
323
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
324
- children: [/* @__PURE__ */ y("div", {
324
+ children: [/* @__PURE__ */ C("div", {
325
325
  className: "mb-4 flex items-center justify-between",
326
- children: [/* @__PURE__ */ v("h2", {
326
+ children: [/* @__PURE__ */ S("h2", {
327
327
  className: "text-lg font-semibold text-text-primary",
328
328
  children: "Ledger"
329
- }), /* @__PURE__ */ y("div", {
329
+ }), /* @__PURE__ */ C("div", {
330
330
  className: "flex items-center gap-3",
331
- children: [/* @__PURE__ */ y("select", {
332
- value: H,
333
- onChange: (e) => U(e.target.value),
331
+ children: [/* @__PURE__ */ C("select", {
332
+ value: U,
333
+ onChange: (e) => W(e.target.value),
334
334
  className: "rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary",
335
335
  children: [
336
- /* @__PURE__ */ v("option", {
336
+ /* @__PURE__ */ S("option", {
337
337
  value: "ALL",
338
338
  children: "All sources"
339
339
  }),
340
- /* @__PURE__ */ v("option", {
340
+ /* @__PURE__ */ S("option", {
341
341
  value: "AFFILIATE",
342
342
  children: "Affiliate"
343
343
  }),
344
- /* @__PURE__ */ v("option", {
344
+ /* @__PURE__ */ S("option", {
345
345
  value: "STORE",
346
346
  children: "Store"
347
347
  }),
348
- /* @__PURE__ */ v("option", {
348
+ /* @__PURE__ */ S("option", {
349
349
  value: "OTHER",
350
350
  children: "Other"
351
351
  })
352
352
  ]
353
- }), /* @__PURE__ */ y("button", {
353
+ }), /* @__PURE__ */ C("button", {
354
354
  type: "button",
355
- onClick: () => void Y(),
355
+ onClick: () => void X(),
356
356
  className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary",
357
- children: [/* @__PURE__ */ v(h, { className: "size-4" }), "Refresh"]
357
+ children: [/* @__PURE__ */ S(y, { className: "size-4" }), "Refresh"]
358
358
  })]
359
359
  })]
360
- }), Z.length === 0 && !W ? /* @__PURE__ */ v(x, {
360
+ }), Z.length === 0 && !G ? /* @__PURE__ */ S(T, {
361
361
  illustration: "empty-data",
362
362
  title: "No earnings yet",
363
363
  description: "Eligible affiliate rewards and other earnings will appear here."
364
- }) : /* @__PURE__ */ v(C, {
364
+ }) : /* @__PURE__ */ S(D, {
365
365
  data: Z,
366
366
  rowKey: (e) => e.id,
367
- columns: E
367
+ columns: k
368
368
  })]
369
369
  })
370
370
  ]
371
371
  });
372
372
  };
373
373
  //#endregion
374
- export { D as EarningsPage };
374
+ export { A as EarningsPage };
375
375
 
376
376
  //# sourceMappingURL=EarningsPage.js.map