@burdenoff/microfe-billing 2026.706.1 → 2026.708.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,438 @@
1
+ import { useBilling as e } from "../../../providers/BillingProvider.js";
2
+ import { AccessDenied as t } from "../../../shared/components/AccessDenied.js";
3
+ import { PageHeader as n } from "../../../shared/components/PageHeader.js";
4
+ import { ServerError as r } from "../../../shared/components/ServerError.js";
5
+ import "../../../shared/components/index.js";
6
+ import { formatCurrency as i, formatDateTime as a } from "../../../shared/utils/format.js";
7
+ import { isServerError as o } from "../../../shared/utils/error.js";
8
+ import "../../../shared/utils/index.js";
9
+ import { useBillingPermissions as s } from "../../../hooks/useBillingPermissions.js";
10
+ import { fetchAdminDeveloperRevenueOrgDetail as c, fetchAdminDeveloperRevenueOrgs as l, retrySaleCreditSync as u } from "../api.js";
11
+ import { useEffect as d, useMemo as f, useState as p } from "react";
12
+ import { Building2 as m, CreditCard as h, DollarSign as g, Loader2 as _, Receipt as v, Wallet as y } from "lucide-react";
13
+ import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
14
+ import { PagePurpose as C, ResponsiveDialog as w, ResponsiveDialogContent as T, ResponsiveDialogDescription as E, ResponsiveDialogFooter as D, ResponsiveDialogHeader as O, ResponsiveDialogTitle as k } from "@burdenoff/fe-libs/ui";
15
+ //#region src/billing/modules/earnings/pages/DeveloperRevenueAdminPage.tsx
16
+ function A({ orgs: e }) {
17
+ let t = f(() => e.reduce((e, t) => ({
18
+ totalRevenue: e.totalRevenue + t.totalRevenue,
19
+ totalPlatformFees: e.totalPlatformFees + t.totalPlatformFees,
20
+ pendingBalance: e.pendingBalance + t.pendingBalance,
21
+ totalPayouts: e.totalPayouts + t.totalPayouts
22
+ }), {
23
+ totalRevenue: 0,
24
+ totalPlatformFees: 0,
25
+ pendingBalance: 0,
26
+ totalPayouts: 0
27
+ }), [e]);
28
+ return /* @__PURE__ */ S("div", {
29
+ className: "grid gap-3 md:grid-cols-2 xl:grid-cols-4",
30
+ children: [
31
+ /* @__PURE__ */ S("div", {
32
+ className: "rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]",
33
+ children: [/* @__PURE__ */ x("div", {
34
+ className: "text-xs uppercase tracking-wide text-text-muted",
35
+ children: "Gross revenue"
36
+ }), /* @__PURE__ */ S("div", {
37
+ className: "mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary",
38
+ children: [/* @__PURE__ */ x(g, { className: "size-4 text-text-muted" }), i(t.totalRevenue, "USD")]
39
+ })]
40
+ }),
41
+ /* @__PURE__ */ S("div", {
42
+ className: "rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]",
43
+ children: [/* @__PURE__ */ x("div", {
44
+ className: "text-xs uppercase tracking-wide text-text-muted",
45
+ children: "Platform fees"
46
+ }), /* @__PURE__ */ S("div", {
47
+ className: "mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary",
48
+ children: [/* @__PURE__ */ x(v, { className: "size-4 text-text-muted" }), i(t.totalPlatformFees, "USD")]
49
+ })]
50
+ }),
51
+ /* @__PURE__ */ S("div", {
52
+ className: "rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]",
53
+ children: [/* @__PURE__ */ x("div", {
54
+ className: "text-xs uppercase tracking-wide text-text-muted",
55
+ children: "Pending earned credits"
56
+ }), /* @__PURE__ */ S("div", {
57
+ className: "mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary",
58
+ children: [/* @__PURE__ */ x(y, { className: "size-4 text-text-muted" }), i(t.pendingBalance, "USD")]
59
+ })]
60
+ }),
61
+ /* @__PURE__ */ S("div", {
62
+ className: "rounded-card border border-border-seam bg-bg-surface p-4 shadow-[var(--shadow-elevation-1)]",
63
+ children: [/* @__PURE__ */ x("div", {
64
+ className: "text-xs uppercase tracking-wide text-text-muted",
65
+ children: "Already withdrawn"
66
+ }), /* @__PURE__ */ S("div", {
67
+ className: "mt-1 flex items-center gap-2 text-lg font-semibold text-text-primary",
68
+ children: [/* @__PURE__ */ x(m, { className: "size-4 text-text-muted" }), i(t.totalPayouts, "USD")]
69
+ })]
70
+ })
71
+ ]
72
+ });
73
+ }
74
+ function j({ org: e, detail: t, loading: n, error: r, retryingSaleId: o, onRetrySale: s, onClose: c }) {
75
+ return /* @__PURE__ */ x(w, {
76
+ open: e !== null,
77
+ onOpenChange: (e) => !e && c(),
78
+ children: /* @__PURE__ */ S(T, {
79
+ className: "sm:max-w-4xl",
80
+ children: [
81
+ /* @__PURE__ */ S(O, { children: [/* @__PURE__ */ x(k, { children: e ? `${e.name} revenue details` : "Revenue details" }), /* @__PURE__ */ x(E, { children: "Store revenue is credited into the linked billing account as earned credits. Developers withdraw those credits later through the billing withdrawal flow." })] }),
82
+ n ? /* @__PURE__ */ x("div", {
83
+ className: "flex items-center justify-center py-14 text-text-secondary",
84
+ children: /* @__PURE__ */ x(_, { className: "size-7 animate-spin" })
85
+ }) : r ? /* @__PURE__ */ x("div", {
86
+ className: "rounded-lg border border-status-error-border bg-status-error-bg-subtle p-4 text-sm text-status-error-text",
87
+ children: r.message
88
+ }) : t && e ? /* @__PURE__ */ S("div", {
89
+ className: "space-y-5",
90
+ children: [
91
+ /* @__PURE__ */ S("div", {
92
+ className: "grid gap-3 md:grid-cols-4",
93
+ children: [
94
+ /* @__PURE__ */ S("div", {
95
+ className: "rounded-card border border-border-seam bg-bg-surface p-4",
96
+ children: [
97
+ /* @__PURE__ */ x("div", {
98
+ className: "text-xs uppercase tracking-wide text-text-muted",
99
+ children: "Linked billing account"
100
+ }),
101
+ /* @__PURE__ */ x("div", {
102
+ className: "mt-1 text-sm font-semibold text-text-primary",
103
+ children: e.billingAccountId ? "Connected" : "Not linked"
104
+ }),
105
+ /* @__PURE__ */ x("div", {
106
+ className: "mt-1 break-all text-xs text-text-muted",
107
+ children: e.billingAccountId ?? "Revenue cannot be credited until a billing account is linked."
108
+ })
109
+ ]
110
+ }),
111
+ /* @__PURE__ */ S("div", {
112
+ className: "rounded-card border border-border-seam bg-bg-surface p-4",
113
+ children: [/* @__PURE__ */ x("div", {
114
+ className: "text-xs uppercase tracking-wide text-text-muted",
115
+ children: "Earned credits awaiting withdrawal"
116
+ }), /* @__PURE__ */ x("div", {
117
+ className: "mt-1 text-lg font-semibold text-text-primary",
118
+ children: i(t.summary?.pendingBalance ?? e.pendingBalance, "USD")
119
+ })]
120
+ }),
121
+ /* @__PURE__ */ S("div", {
122
+ className: "rounded-card border border-border-seam bg-bg-surface p-4",
123
+ children: [/* @__PURE__ */ x("div", {
124
+ className: "text-xs uppercase tracking-wide text-text-muted",
125
+ children: "Unpaid sales"
126
+ }), /* @__PURE__ */ x("div", {
127
+ className: "mt-1 text-lg font-semibold text-text-primary",
128
+ children: t.unpaidSales.totalCount
129
+ })]
130
+ }),
131
+ /* @__PURE__ */ S("div", {
132
+ className: "rounded-card border border-border-seam bg-bg-surface p-4",
133
+ children: [/* @__PURE__ */ x("div", {
134
+ className: "text-xs uppercase tracking-wide text-text-muted",
135
+ children: "Total sales"
136
+ }), /* @__PURE__ */ x("div", {
137
+ className: "mt-1 text-lg font-semibold text-text-primary",
138
+ children: t.summary?.totalSales ?? 0
139
+ })]
140
+ })
141
+ ]
142
+ }),
143
+ /* @__PURE__ */ x("div", {
144
+ className: "rounded-card border border-border-seam bg-bg-surface p-4",
145
+ children: /* @__PURE__ */ S("div", {
146
+ className: "flex items-start gap-3",
147
+ children: [/* @__PURE__ */ x(h, { className: "mt-0.5 size-5 text-text-muted" }), /* @__PURE__ */ S("div", {
148
+ className: "space-y-1 text-sm",
149
+ children: [
150
+ /* @__PURE__ */ x("p", {
151
+ className: "font-medium text-text-primary",
152
+ children: "Correct payout model"
153
+ }),
154
+ /* @__PURE__ */ S("p", {
155
+ className: "text-text-muted",
156
+ children: [
157
+ "Revenue from Store sales is posted into the developer organization's linked billing account as ",
158
+ /* @__PURE__ */ x("strong", { children: "earned credits" }),
159
+ ". We do not directly send cash to developer-org payment methods from this page."
160
+ ]
161
+ }),
162
+ /* @__PURE__ */ x("p", {
163
+ className: "text-text-muted",
164
+ children: "If the developer wants to cash out, they use the billing withdrawal flow from their own billing account and payout methods."
165
+ })
166
+ ]
167
+ })]
168
+ })
169
+ }),
170
+ /* @__PURE__ */ S("section", {
171
+ className: "rounded-card border border-border-seam bg-bg-surface p-4",
172
+ children: [
173
+ /* @__PURE__ */ x("h3", {
174
+ className: "text-sm font-semibold text-text-primary",
175
+ children: "Sales currently contributing to earned credits"
176
+ }),
177
+ /* @__PURE__ */ x("p", {
178
+ className: "mt-1 text-xs text-text-muted",
179
+ children: "These sales represent revenue that should exist as earned credits in the linked billing account until the developer withdraws them."
180
+ }),
181
+ /* @__PURE__ */ x("div", {
182
+ className: "mt-4 overflow-x-auto",
183
+ children: /* @__PURE__ */ S("table", {
184
+ className: "min-w-full text-sm",
185
+ children: [/* @__PURE__ */ x("thead", {
186
+ className: "bg-bg-sunken/60 text-left text-xs uppercase tracking-wide text-text-muted",
187
+ children: /* @__PURE__ */ S("tr", { children: [
188
+ /* @__PURE__ */ x("th", {
189
+ className: "px-3 py-2",
190
+ children: "Application"
191
+ }),
192
+ /* @__PURE__ */ x("th", {
193
+ className: "px-3 py-2",
194
+ children: "Purchased"
195
+ }),
196
+ /* @__PURE__ */ x("th", {
197
+ className: "px-3 py-2",
198
+ children: "Net revenue"
199
+ }),
200
+ /* @__PURE__ */ x("th", {
201
+ className: "px-3 py-2",
202
+ children: "Credit sync"
203
+ }),
204
+ /* @__PURE__ */ x("th", {
205
+ className: "px-3 py-2",
206
+ children: "Status"
207
+ })
208
+ ] })
209
+ }), /* @__PURE__ */ x("tbody", { children: t.unpaidSales.items.length === 0 ? /* @__PURE__ */ x("tr", { children: /* @__PURE__ */ x("td", {
210
+ colSpan: 5,
211
+ className: "px-3 py-5 text-center text-sm text-text-muted",
212
+ children: "No outstanding unpaid sales. Revenue has either not started yet or has already been withdrawn through billing."
213
+ }) }) : t.unpaidSales.items.map((t) => /* @__PURE__ */ S("tr", {
214
+ className: "border-t border-border-seam",
215
+ children: [
216
+ /* @__PURE__ */ S("td", {
217
+ className: "px-3 py-2",
218
+ children: [/* @__PURE__ */ x("div", {
219
+ className: "font-medium text-text-primary",
220
+ children: t.application?.name ?? "Unknown app"
221
+ }), /* @__PURE__ */ S("div", {
222
+ className: "text-xs text-text-muted",
223
+ children: ["/", t.application?.slug ?? "unknown"]
224
+ })]
225
+ }),
226
+ /* @__PURE__ */ x("td", {
227
+ className: "px-3 py-2 text-text-secondary",
228
+ children: a(t.purchasedAt)
229
+ }),
230
+ /* @__PURE__ */ x("td", {
231
+ className: "px-3 py-2 text-text-primary",
232
+ children: i(t.netAmount, t.currency)
233
+ }),
234
+ /* @__PURE__ */ S("td", {
235
+ className: "px-3 py-2 text-text-secondary",
236
+ children: [
237
+ /* @__PURE__ */ x("div", { children: t.billingCreditSyncStatus ?? "UNKNOWN" }),
238
+ t.billingCreditSyncError && /* @__PURE__ */ x("div", {
239
+ className: "mt-1 text-xs text-status-error-text",
240
+ children: t.billingCreditSyncError
241
+ }),
242
+ t.billingCreditSyncStatus !== "SYNCED" && e.billingAccountId && /* @__PURE__ */ x("button", {
243
+ type: "button",
244
+ onClick: () => s(t.id),
245
+ disabled: o === t.id,
246
+ className: "mt-2 rounded-md border border-border-subtle px-2 py-1 text-xs font-medium text-text-primary disabled:opacity-50",
247
+ children: o === t.id ? "Retrying…" : "Retry sync"
248
+ })
249
+ ]
250
+ }),
251
+ /* @__PURE__ */ x("td", {
252
+ className: "px-3 py-2 text-text-secondary",
253
+ children: t.status
254
+ })
255
+ ]
256
+ }, t.id)) })]
257
+ })
258
+ })
259
+ ]
260
+ })
261
+ ]
262
+ }) : null,
263
+ /* @__PURE__ */ x(D, { children: /* @__PURE__ */ x("button", {
264
+ type: "button",
265
+ onClick: c,
266
+ className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary",
267
+ children: "Close"
268
+ }) })
269
+ ]
270
+ })
271
+ });
272
+ }
273
+ var M = () => {
274
+ let a = s(), { apiGatewayUrl: m, authToken: h, orgId: g, navigate: v, basePath: y } = e(), [w, T] = p([]), [E, D] = p(!0), [O, k] = p(null), [M, N] = p(null), [P, F] = p(null), [I, L] = p(!1), [R, z] = p(null), [B, V] = p(null), H = f(() => ({
275
+ apiGatewayUrl: m,
276
+ authToken: h,
277
+ orgId: g
278
+ }), [
279
+ m,
280
+ h,
281
+ g
282
+ ]), U = async () => {
283
+ D(!0), k(null);
284
+ try {
285
+ T((await l(H)).filter((e) => e.totalRevenue > 0 || e.pendingBalance > 0 || e.totalPayouts > 0));
286
+ } catch (e) {
287
+ k(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load developer revenue"));
288
+ } finally {
289
+ D(!1);
290
+ }
291
+ }, W = async (e) => {
292
+ N(e), L(!0), z(null);
293
+ try {
294
+ F(await c(e.id, H));
295
+ } catch (e) {
296
+ F(null), z(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load revenue detail"));
297
+ } finally {
298
+ L(!1);
299
+ }
300
+ };
301
+ return d(() => {
302
+ a.isBillingAdmin && U();
303
+ }, [a.isBillingAdmin, H]), a.isBillingAdmin ? O && o(O) ? /* @__PURE__ */ x(r, {
304
+ title: "Developer revenue unavailable",
305
+ message: O.message,
306
+ showRetry: !0,
307
+ onRetry: () => void U()
308
+ }) : /* @__PURE__ */ S("div", {
309
+ className: "space-y-6 p-6",
310
+ children: [
311
+ /* @__PURE__ */ x(n, {
312
+ title: "Developer revenue",
313
+ description: "See store-generated revenue across developer organizations and confirm that the earnings are flowing into linked billing accounts as earned credits.",
314
+ actions: /* @__PURE__ */ x("button", {
315
+ type: "button",
316
+ onClick: () => v?.(`${y}/payouts`),
317
+ 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",
318
+ children: "Open billing withdrawal queue"
319
+ })
320
+ }),
321
+ /* @__PURE__ */ x(C, { children: "Developer portal revenue does not pay out directly from this page. Each Store sale is credited into the developer organization's linked billing account as earned credits. Developers then withdraw those credits later using the billing withdrawal flow and their own payout methods." }),
322
+ E ? /* @__PURE__ */ x("div", {
323
+ className: "flex items-center justify-center py-16 text-text-secondary",
324
+ children: /* @__PURE__ */ x(_, { className: "size-8 animate-spin" })
325
+ }) : /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x(A, { orgs: w }), /* @__PURE__ */ S("div", {
326
+ className: "overflow-hidden rounded-card border border-border-seam bg-bg-surface shadow-[var(--shadow-elevation-1)]",
327
+ children: [/* @__PURE__ */ S("div", {
328
+ className: "border-b border-border-seam px-5 py-4",
329
+ children: [/* @__PURE__ */ x("h2", {
330
+ className: "text-base font-semibold text-text-primary",
331
+ children: "Organizations"
332
+ }), /* @__PURE__ */ x("p", {
333
+ className: "mt-1 text-sm text-text-muted",
334
+ children: "Click a row to inspect billing linkage and the unpaid sales behind the current earned-credit balance."
335
+ })]
336
+ }), w.length === 0 ? /* @__PURE__ */ x("div", {
337
+ className: "px-5 py-12 text-center text-sm text-text-muted",
338
+ children: "No developer revenue has been recorded yet."
339
+ }) : /* @__PURE__ */ x("div", {
340
+ className: "overflow-x-auto",
341
+ children: /* @__PURE__ */ S("table", {
342
+ className: "min-w-full text-sm",
343
+ children: [/* @__PURE__ */ x("thead", {
344
+ className: "bg-bg-sunken/60 text-left text-xs uppercase tracking-wide text-text-muted",
345
+ children: /* @__PURE__ */ S("tr", { children: [
346
+ /* @__PURE__ */ x("th", {
347
+ className: "px-4 py-3",
348
+ children: "Organization"
349
+ }),
350
+ /* @__PURE__ */ x("th", {
351
+ className: "px-4 py-3",
352
+ children: "Billing linked"
353
+ }),
354
+ /* @__PURE__ */ x("th", {
355
+ className: "px-4 py-3",
356
+ children: "Revenue"
357
+ }),
358
+ /* @__PURE__ */ x("th", {
359
+ className: "px-4 py-3",
360
+ children: "Platform fee"
361
+ }),
362
+ /* @__PURE__ */ x("th", {
363
+ className: "px-4 py-3",
364
+ children: "Earned credits pending withdrawal"
365
+ }),
366
+ /* @__PURE__ */ x("th", {
367
+ className: "px-4 py-3",
368
+ children: "Already withdrawn"
369
+ })
370
+ ] })
371
+ }), /* @__PURE__ */ x("tbody", { children: [...w].sort((e, t) => t.pendingBalance - e.pendingBalance).map((e) => /* @__PURE__ */ S("tr", {
372
+ className: "cursor-pointer border-t border-border-seam transition-colors hover:bg-bg-sunken/30",
373
+ onClick: () => void W(e),
374
+ children: [
375
+ /* @__PURE__ */ S("td", {
376
+ className: "px-4 py-3",
377
+ children: [/* @__PURE__ */ x("div", {
378
+ className: "font-medium text-text-primary",
379
+ children: e.name
380
+ }), /* @__PURE__ */ S("div", {
381
+ className: "text-xs text-text-muted",
382
+ children: ["/", e.slug]
383
+ })]
384
+ }),
385
+ /* @__PURE__ */ x("td", {
386
+ className: "px-4 py-3 text-text-secondary",
387
+ children: e.billingAccountId ? "Yes" : "No"
388
+ }),
389
+ /* @__PURE__ */ x("td", {
390
+ className: "px-4 py-3 text-text-primary",
391
+ children: i(e.totalRevenue, "USD")
392
+ }),
393
+ /* @__PURE__ */ x("td", {
394
+ className: "px-4 py-3 text-text-secondary",
395
+ children: i(e.totalPlatformFees, "USD")
396
+ }),
397
+ /* @__PURE__ */ x("td", {
398
+ className: "px-4 py-3 font-medium text-status-warning-text",
399
+ children: i(e.pendingBalance, "USD")
400
+ }),
401
+ /* @__PURE__ */ x("td", {
402
+ className: "px-4 py-3 text-text-secondary",
403
+ children: i(e.totalPayouts, "USD")
404
+ })
405
+ ]
406
+ }, e.id)) })]
407
+ })
408
+ })]
409
+ })] }),
410
+ /* @__PURE__ */ x(j, {
411
+ org: M,
412
+ detail: P,
413
+ loading: I,
414
+ error: R,
415
+ retryingSaleId: B,
416
+ onRetrySale: (e) => {
417
+ M && (async () => {
418
+ V(e), z(null);
419
+ try {
420
+ await u(e, H), await W(M);
421
+ } catch (e) {
422
+ z(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to retry credit sync"));
423
+ } finally {
424
+ V(null);
425
+ }
426
+ })();
427
+ },
428
+ onClose: () => {
429
+ N(null), F(null), z(null);
430
+ }
431
+ })
432
+ ]
433
+ }) : /* @__PURE__ */ x(t, { message: "You don't have permission to view developer revenue." });
434
+ };
435
+ //#endregion
436
+ export { M as DeveloperRevenueAdminPage };
437
+
438
+ //# sourceMappingURL=DeveloperRevenueAdminPage.js.map
@@ -0,0 +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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"}