@burdenoff/microfe-devportal 2026.609.4 → 2026.611.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 (58) hide show
  1. package/dist/devportal/DevportalRoot.js +6 -1
  2. package/dist/devportal/DevportalRoot.js.map +1 -1
  3. package/dist/devportal/DevportalRoutes.js +169 -158
  4. package/dist/devportal/DevportalRoutes.js.map +1 -1
  5. package/dist/devportal/hooks/usePackageUpload.js +120 -0
  6. package/dist/devportal/hooks/usePackageUpload.js.map +1 -0
  7. package/dist/devportal/pages/AnalyticsDashboardPage.js +73 -62
  8. package/dist/devportal/pages/AnalyticsDashboardPage.js.map +1 -1
  9. package/dist/devportal/pages/AppLogsPage.js +89 -82
  10. package/dist/devportal/pages/AppLogsPage.js.map +1 -1
  11. package/dist/devportal/pages/ApplicationDetailPage.js +948 -367
  12. package/dist/devportal/pages/ApplicationDetailPage.js.map +1 -1
  13. package/dist/devportal/pages/ApplicationVersionsPage.js +56 -45
  14. package/dist/devportal/pages/ApplicationVersionsPage.js.map +1 -1
  15. package/dist/devportal/pages/CreateApiKeyPage.js +30 -32
  16. package/dist/devportal/pages/CreateApiKeyPage.js.map +1 -1
  17. package/dist/devportal/pages/CreateApplicationPage.js +8 -3
  18. package/dist/devportal/pages/CreateApplicationPage.js.map +1 -1
  19. package/dist/devportal/pages/CreateOAuthClientPage.js +4 -4
  20. package/dist/devportal/pages/CreateOAuthClientPage.js.map +1 -1
  21. package/dist/devportal/pages/CreateOrganizationPage.js +238 -229
  22. package/dist/devportal/pages/CreateOrganizationPage.js.map +1 -1
  23. package/dist/devportal/pages/CreateWebhookPage.js +159 -148
  24. package/dist/devportal/pages/CreateWebhookPage.js.map +1 -1
  25. package/dist/devportal/pages/DelegationsPage.js +1 -1
  26. package/dist/devportal/pages/DelegationsPage.js.map +1 -1
  27. package/dist/devportal/pages/EditApplicationPage.js +25 -17
  28. package/dist/devportal/pages/EditApplicationPage.js.map +1 -1
  29. package/dist/devportal/pages/ListingPreviewPage.js +159 -153
  30. package/dist/devportal/pages/ListingPreviewPage.js.map +1 -1
  31. package/dist/devportal/pages/OAuthClientDetailPage.js.map +1 -1
  32. package/dist/devportal/pages/OAuthClientsPage.js +2 -2
  33. package/dist/devportal/pages/OAuthClientsPage.js.map +1 -1
  34. package/dist/devportal/pages/OrganizationDetailPage.js +158 -153
  35. package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
  36. package/dist/devportal/pages/OrganizationMembersPage.js +223 -212
  37. package/dist/devportal/pages/OrganizationMembersPage.js.map +1 -1
  38. package/dist/devportal/pages/PublishPage.js +172 -165
  39. package/dist/devportal/pages/PublishPage.js.map +1 -1
  40. package/dist/devportal/pages/ResourcesPage.js.map +1 -1
  41. package/dist/devportal/pages/RevenueDashboardPage.js +461 -0
  42. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -0
  43. package/dist/devportal/pages/SetupPage.js +186 -181
  44. package/dist/devportal/pages/SetupPage.js.map +1 -1
  45. package/dist/devportal/pages/StoreSubmissionPage.js +76 -97
  46. package/dist/devportal/pages/StoreSubmissionPage.js.map +1 -1
  47. package/dist/devportal/pages/WebhookDetailPage.js +172 -154
  48. package/dist/devportal/pages/WebhookDetailPage.js.map +1 -1
  49. package/dist/devportal/pages/WebhooksPage.js +218 -200
  50. package/dist/devportal/pages/WebhooksPage.js.map +1 -1
  51. package/dist/devportal/providers/DevportalProvider.js +16 -13
  52. package/dist/devportal/providers/DevportalProvider.js.map +1 -1
  53. package/dist/devportal/types/index.js.map +1 -1
  54. package/dist/generated/global-operations.js +334 -223
  55. package/dist/generated/global-operations.js.map +1 -1
  56. package/package.json +1 -1
  57. package/dist/devportal/pages/RevenueRedirectPage.js +0 -14
  58. package/dist/devportal/pages/RevenueRedirectPage.js.map +0 -1
@@ -0,0 +1,461 @@
1
+ import { EmptyState as e } from "../components/EmptyState.js";
2
+ import { PageLayout as t, PageSection as n } from "../components/PageLayout.js";
3
+ import { StatCard as r, StatCardGrid as ee } from "../components/StatCard.js";
4
+ import { StatusBadge as i } from "../components/StatusBadge.js";
5
+ import { DataTable as a } from "../components/DataTable.js";
6
+ import { useCreateBillingAccountMutation as te, useGetMyOrganizationsQuery as ne, useGetRevenueDashboardDataQuery as o, useLinkDevOrgBillingAccountMutation as s } from "../../generated/global-operations.js";
7
+ import { getErrorMessage as c } from "../hooks/useGraphQL.js";
8
+ import "../hooks/index.js";
9
+ import { Tooltip as l } from "../../node_modules/recharts/es6/component/Tooltip.js";
10
+ import { ResponsiveContainer as u } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
11
+ import { Bar as d } from "../../node_modules/recharts/es6/cartesian/Bar.js";
12
+ import { CartesianGrid as f } from "../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
13
+ import { Line as p } from "../../node_modules/recharts/es6/cartesian/Line.js";
14
+ import { XAxis as m } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
15
+ import { YAxis as h } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
16
+ import { LineChart as g } from "../../node_modules/recharts/es6/chart/LineChart.js";
17
+ import { BarChart as re } from "../../node_modules/recharts/es6/chart/BarChart.js";
18
+ import { useTr as ie } from "../utils/i18n.js";
19
+ import { useEffect as _, useMemo as v, useState as y } from "react";
20
+ import { AlertCircle as b, ArrowDownToLine as ae, Building2 as x, CreditCard as oe, DollarSign as S, Link2 as C, Loader2 as w, Wallet as T } from "lucide-react";
21
+ import { useSearchParams as E } from "react-router-dom";
22
+ import { Fragment as D, jsx as O, jsxs as k } from "react/jsx-runtime";
23
+ //#region src/devportal/pages/RevenueDashboardPage.tsx
24
+ var A = {
25
+ primary: "var(--color-chart-1)",
26
+ secondary: "var(--color-chart-2)",
27
+ tertiary: "var(--color-chart-4)"
28
+ }, se = {
29
+ "30d": 30,
30
+ "90d": 90,
31
+ "12m": 365
32
+ }, j = () => {
33
+ let j = ie(), [M, ce] = y("90d"), [N, P] = y(""), [F, I] = y(!1), [L, R] = y(null), [z] = te(), [B] = s(), [V] = E(), H = v(() => /* @__PURE__ */ new Date(), []), U = V.get("org"), W = v(() => {
34
+ let e = new Date(H);
35
+ return e.setDate(e.getDate() - se[M]), e.toISOString();
36
+ }, [H, M]), { data: G, loading: le, error: K } = ne({ fetchPolicy: "cache-and-network" }), { data: q, loading: J, error: Y } = o({
37
+ variables: {
38
+ organizationId: N,
39
+ period: "monthly",
40
+ startDate: W,
41
+ endDate: H.toISOString(),
42
+ salesLimit: 10,
43
+ salesOffset: 0,
44
+ payoutsLimit: 10,
45
+ payoutsOffset: 0
46
+ },
47
+ skip: !N,
48
+ fetchPolicy: "cache-and-network"
49
+ }), X = v(() => G?.myDeveloperOrganizations?.map((e) => e) ?? [], [G?.myDeveloperOrganizations]);
50
+ _(() => {
51
+ if (!N) {
52
+ if (U && X.some((e) => e.id === U)) {
53
+ P(U);
54
+ return;
55
+ }
56
+ X.length === 1 && P(X[0]?.id ?? "");
57
+ }
58
+ }, [
59
+ X,
60
+ U,
61
+ N
62
+ ]);
63
+ let Z = X.find((e) => e.id === N), ue = async () => {
64
+ if (N) {
65
+ I(!0), R(null);
66
+ try {
67
+ let e = (await z({ variables: { input: {
68
+ name: Z?.name ?? N,
69
+ email: ""
70
+ } } })).data?.createBillingAccount?.id;
71
+ e && await B({
72
+ variables: {
73
+ organizationId: N,
74
+ billingAccountId: e
75
+ },
76
+ refetchQueries: ["GetMyOrganizations"]
77
+ });
78
+ } catch (e) {
79
+ R(e instanceof Error ? e.message : "Failed to link billing account");
80
+ } finally {
81
+ I(!1);
82
+ }
83
+ }
84
+ }, Q = q?.developerOrgRevenueSummary, de = [...q?.developerOrgRevenueAnalytics ?? []].sort((e, t) => new Date(e.date).getTime() - new Date(t.date).getTime()), fe = q?.developerOrgSales?.edges?.map((e) => e.node) ?? [], pe = q?.developerOrgPayouts?.edges?.map((e) => e.node) ?? [], $ = de.map((e) => ({
85
+ date: new Date(e.date).toLocaleDateString(void 0, {
86
+ month: "short",
87
+ day: "numeric"
88
+ }),
89
+ grossRevenue: e.grossRevenue,
90
+ netRevenue: e.netRevenue,
91
+ platformFees: e.platformFees,
92
+ refunds: e.refunds,
93
+ salesCount: e.salesCount
94
+ }));
95
+ return le && !G ? /* @__PURE__ */ O(t, {
96
+ title: j("devportal.revenue.title", "Revenue"),
97
+ description: j("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
98
+ children: /* @__PURE__ */ O("div", {
99
+ className: "flex items-center justify-center py-16 text-muted-foreground",
100
+ children: /* @__PURE__ */ O(w, { className: "h-8 w-8 animate-spin" })
101
+ })
102
+ }) : K ? /* @__PURE__ */ O(t, {
103
+ title: j("devportal.revenue.title", "Revenue"),
104
+ description: j("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
105
+ children: /* @__PURE__ */ O(e, {
106
+ icon: /* @__PURE__ */ O(b, {
107
+ size: 32,
108
+ className: "text-status-error-text"
109
+ }),
110
+ title: j("devportal.revenue.errorLoadOrgs", "Unable to load organizations"),
111
+ description: c(K)
112
+ })
113
+ }) : N ? Y ? /* @__PURE__ */ O(t, {
114
+ title: j("devportal.revenue.title", "Revenue"),
115
+ description: j("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
116
+ children: /* @__PURE__ */ O(e, {
117
+ icon: /* @__PURE__ */ O(b, {
118
+ size: 32,
119
+ className: "text-status-error-text"
120
+ }),
121
+ title: j("devportal.revenue.errorLoadData", "Unable to load revenue data"),
122
+ description: c(Y)
123
+ })
124
+ }) : /* @__PURE__ */ k(t, {
125
+ title: j("devportal.revenue.title", "Revenue"),
126
+ description: Z ? `${j("devportal.revenue.financialPerformanceFor", "Financial performance for")} ${Z.name}` : j("devportal.revenue.shortDescription", "Track revenue, sales, and payouts"),
127
+ actions: /* @__PURE__ */ k("div", {
128
+ className: "flex flex-wrap gap-2",
129
+ children: [/* @__PURE__ */ O("select", {
130
+ value: N,
131
+ onChange: (e) => P(e.target.value),
132
+ "aria-label": j("devportal.revenue.selectOrgAria", "Select organization"),
133
+ className: "rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary",
134
+ children: X.map((e) => /* @__PURE__ */ O("option", {
135
+ value: e.id,
136
+ children: e.name
137
+ }, e.id))
138
+ }), /* @__PURE__ */ k("select", {
139
+ value: M,
140
+ onChange: (e) => ce(e.target.value),
141
+ "aria-label": j("devportal.revenue.selectRangeAria", "Select time range"),
142
+ className: "rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary",
143
+ children: [
144
+ /* @__PURE__ */ O("option", {
145
+ value: "30d",
146
+ children: j("devportal.revenue.range.30d", "Last 30 days")
147
+ }),
148
+ /* @__PURE__ */ O("option", {
149
+ value: "90d",
150
+ children: j("devportal.revenue.range.90d", "Last 90 days")
151
+ }),
152
+ /* @__PURE__ */ O("option", {
153
+ value: "12m",
154
+ children: j("devportal.revenue.range.12m", "Last 12 months")
155
+ })
156
+ ]
157
+ })]
158
+ }),
159
+ children: [Z && !Z.billingAccountId && /* @__PURE__ */ k("div", {
160
+ className: "mb-6 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 flex items-start gap-3",
161
+ children: [
162
+ /* @__PURE__ */ O(C, {
163
+ size: 20,
164
+ className: "text-accent-blue flex-shrink-0 mt-0.5"
165
+ }),
166
+ /* @__PURE__ */ k("div", {
167
+ className: "flex-1 min-w-0",
168
+ children: [
169
+ /* @__PURE__ */ O("p", {
170
+ className: "text-sm font-medium text-status-info-text",
171
+ children: j("devportal.revenue.billingNotLinkedTitle", "Link a billing account to receive store revenue")
172
+ }),
173
+ /* @__PURE__ */ O("p", {
174
+ className: "mt-1 text-sm text-status-info-text",
175
+ children: j("devportal.revenue.billingNotLinkedDesc", "Once linked, net earnings from app sales will appear in your billing credits — you can spend them on platform services or withdraw to your bank.")
176
+ }),
177
+ L && /* @__PURE__ */ O("p", {
178
+ className: "mt-2 text-sm text-status-error-text",
179
+ children: L
180
+ })
181
+ ]
182
+ }),
183
+ /* @__PURE__ */ k("button", {
184
+ type: "button",
185
+ onClick: ue,
186
+ disabled: F,
187
+ className: "inline-flex items-center gap-2 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50 flex-shrink-0",
188
+ children: [F ? /* @__PURE__ */ O(w, {
189
+ size: 14,
190
+ className: "animate-spin"
191
+ }) : /* @__PURE__ */ O(C, { size: 14 }), F ? j("devportal.revenue.linking", "Linking...") : j("devportal.revenue.linkBillingAccount", "Link Billing Account")]
192
+ })
193
+ ]
194
+ }), J && !Q ? /* @__PURE__ */ O("div", {
195
+ className: "flex items-center justify-center py-16 text-muted-foreground",
196
+ children: /* @__PURE__ */ O(w, { className: "h-8 w-8 animate-spin" })
197
+ }) : Q ? /* @__PURE__ */ k(D, { children: [
198
+ /* @__PURE__ */ k(ee, {
199
+ columns: 4,
200
+ children: [
201
+ /* @__PURE__ */ O(r, {
202
+ title: j("devportal.revenue.grossRevenue", "Gross Revenue"),
203
+ value: `$${Q.totalGrossRevenue.toLocaleString()}`,
204
+ icon: /* @__PURE__ */ O(S, { size: 20 })
205
+ }),
206
+ /* @__PURE__ */ O(r, {
207
+ title: j("devportal.revenue.netRevenue", "Net Revenue"),
208
+ value: `$${Q.totalNetRevenue.toLocaleString()}`,
209
+ icon: /* @__PURE__ */ O(T, { size: 20 })
210
+ }),
211
+ /* @__PURE__ */ O(r, {
212
+ title: j("devportal.revenue.pendingBalance", "Pending Balance"),
213
+ value: `$${Q.pendingBalance.toLocaleString()}`,
214
+ icon: /* @__PURE__ */ O(oe, { size: 20 }),
215
+ description: Q.nextPayoutDate ? `${j("devportal.revenue.nextPayout", "Next payout")} ${new Date(Q.nextPayoutDate).toLocaleDateString()}` : j("devportal.revenue.noPayoutScheduled", "No payout scheduled")
216
+ }),
217
+ /* @__PURE__ */ O(r, {
218
+ title: j("devportal.revenue.platformFees", "Platform Fees"),
219
+ value: `$${Q.totalPlatformFees.toLocaleString()}`,
220
+ icon: /* @__PURE__ */ O(ae, { size: 20 }),
221
+ description: `${Q.totalRefundsCount} ${j("devportal.revenue.refunds", "refunds")}`
222
+ })
223
+ ]
224
+ }),
225
+ /* @__PURE__ */ k("div", {
226
+ className: "grid gap-6 xl:grid-cols-2",
227
+ children: [/* @__PURE__ */ O(n, {
228
+ title: j("devportal.revenue.revenueTrend", "Revenue trend"),
229
+ children: /* @__PURE__ */ O("div", {
230
+ className: "rounded-lg border bg-card p-4",
231
+ children: /* @__PURE__ */ O(u, {
232
+ width: "100%",
233
+ height: 300,
234
+ children: /* @__PURE__ */ k(g, {
235
+ data: $,
236
+ children: [
237
+ /* @__PURE__ */ O(f, {
238
+ strokeDasharray: "3 3",
239
+ stroke: "var(--color-chart-grid)"
240
+ }),
241
+ /* @__PURE__ */ O(m, {
242
+ dataKey: "date",
243
+ stroke: "var(--color-chart-axis)",
244
+ fontSize: 12
245
+ }),
246
+ /* @__PURE__ */ O(h, {
247
+ stroke: "var(--color-chart-axis)",
248
+ fontSize: 12
249
+ }),
250
+ /* @__PURE__ */ O(l, { contentStyle: {
251
+ backgroundColor: "var(--color-card)",
252
+ border: "1px solid var(--color-border-default)",
253
+ borderRadius: 12
254
+ } }),
255
+ /* @__PURE__ */ O(p, {
256
+ type: "monotone",
257
+ dataKey: "grossRevenue",
258
+ stroke: A.primary,
259
+ strokeWidth: 2,
260
+ dot: !1
261
+ }),
262
+ /* @__PURE__ */ O(p, {
263
+ type: "monotone",
264
+ dataKey: "netRevenue",
265
+ stroke: A.secondary,
266
+ strokeWidth: 2,
267
+ dot: !1
268
+ })
269
+ ]
270
+ })
271
+ })
272
+ })
273
+ }), /* @__PURE__ */ O(n, {
274
+ title: j("devportal.revenue.topApps", "Top applications by revenue"),
275
+ children: Q.topApps.length > 0 ? /* @__PURE__ */ O("div", {
276
+ className: "space-y-2",
277
+ children: Q.topApps.map((e) => /* @__PURE__ */ O("div", {
278
+ className: "rounded-lg border bg-card p-4",
279
+ children: /* @__PURE__ */ k("div", {
280
+ className: "flex items-start justify-between gap-3",
281
+ children: [/* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("p", {
282
+ className: "font-medium",
283
+ children: e.applicationName
284
+ }), /* @__PURE__ */ k("p", {
285
+ className: "text-sm text-muted-foreground",
286
+ children: [
287
+ e.salesCount,
288
+ " ",
289
+ j("devportal.revenue.sales", "sales")
290
+ ]
291
+ })] }), /* @__PURE__ */ k("div", {
292
+ className: "text-right",
293
+ children: [/* @__PURE__ */ k("p", {
294
+ className: "font-semibold",
295
+ children: ["$", e.grossRevenue.toLocaleString()]
296
+ }), /* @__PURE__ */ k("p", {
297
+ className: "text-sm text-muted-foreground",
298
+ children: [
299
+ j("devportal.revenue.net", "Net"),
300
+ " $",
301
+ e.netRevenue.toLocaleString()
302
+ ]
303
+ })]
304
+ })]
305
+ })
306
+ }, e.applicationId))
307
+ }) : /* @__PURE__ */ O(e, {
308
+ icon: /* @__PURE__ */ O(x, { size: 24 }),
309
+ title: j("devportal.revenue.noLeadersTitle", "No revenue leaders yet"),
310
+ description: j("devportal.revenue.noLeadersDescription", "Top-performing applications will appear here once revenue is recorded.")
311
+ })
312
+ })]
313
+ }),
314
+ /* @__PURE__ */ O(n, {
315
+ title: j("devportal.revenue.salesVolume", "Sales volume"),
316
+ children: /* @__PURE__ */ O("div", {
317
+ className: "rounded-lg border bg-card p-4",
318
+ children: /* @__PURE__ */ O(u, {
319
+ width: "100%",
320
+ height: 280,
321
+ children: /* @__PURE__ */ k(re, {
322
+ data: $,
323
+ children: [
324
+ /* @__PURE__ */ O(f, {
325
+ strokeDasharray: "3 3",
326
+ stroke: "var(--color-chart-grid)"
327
+ }),
328
+ /* @__PURE__ */ O(m, {
329
+ dataKey: "date",
330
+ stroke: "var(--color-chart-axis)",
331
+ fontSize: 12
332
+ }),
333
+ /* @__PURE__ */ O(h, {
334
+ stroke: "var(--color-chart-axis)",
335
+ fontSize: 12
336
+ }),
337
+ /* @__PURE__ */ O(l, { contentStyle: {
338
+ backgroundColor: "var(--color-card)",
339
+ border: "1px solid var(--color-border-default)",
340
+ borderRadius: 12
341
+ } }),
342
+ /* @__PURE__ */ O(d, {
343
+ dataKey: "salesCount",
344
+ fill: A.tertiary,
345
+ radius: [
346
+ 6,
347
+ 6,
348
+ 0,
349
+ 0
350
+ ]
351
+ })
352
+ ]
353
+ })
354
+ })
355
+ })
356
+ }),
357
+ /* @__PURE__ */ k("div", {
358
+ className: "grid gap-6 xl:grid-cols-2",
359
+ children: [/* @__PURE__ */ O(n, {
360
+ title: j("devportal.revenue.recentSales", "Recent sales"),
361
+ children: /* @__PURE__ */ O(a, {
362
+ data: fe,
363
+ keyField: "id",
364
+ columns: [
365
+ {
366
+ key: "application",
367
+ header: j("devportal.revenue.application", "Application"),
368
+ render: (e) => e.application?.name || e.planName || j("devportal.common.unknown", "Unknown")
369
+ },
370
+ {
371
+ key: "grossAmount",
372
+ header: j("devportal.revenue.gross", "Gross"),
373
+ render: (e) => `$${e.grossAmount.toLocaleString()}`
374
+ },
375
+ {
376
+ key: "netAmount",
377
+ header: j("devportal.revenue.net", "Net"),
378
+ render: (e) => `$${e.netAmount.toLocaleString()}`
379
+ },
380
+ {
381
+ key: "status",
382
+ header: j("devportal.revenue.status", "Status"),
383
+ render: (e) => /* @__PURE__ */ O(i, {
384
+ status: e.status,
385
+ type: "app"
386
+ })
387
+ }
388
+ ]
389
+ })
390
+ }), /* @__PURE__ */ O(n, {
391
+ title: j("devportal.revenue.payoutHistory", "Payout history"),
392
+ children: /* @__PURE__ */ O(a, {
393
+ data: pe,
394
+ keyField: "id",
395
+ columns: [
396
+ {
397
+ key: "periodLabel",
398
+ header: j("devportal.revenue.period", "Period"),
399
+ render: (e) => e.periodLabel
400
+ },
401
+ {
402
+ key: "netAmount",
403
+ header: j("devportal.revenue.netPayout", "Net payout"),
404
+ render: (e) => `$${e.netAmount.toLocaleString()}`
405
+ },
406
+ {
407
+ key: "status",
408
+ header: j("devportal.revenue.status", "Status"),
409
+ render: (e) => /* @__PURE__ */ O(i, {
410
+ status: e.status,
411
+ type: "app"
412
+ })
413
+ }
414
+ ]
415
+ })
416
+ })]
417
+ })
418
+ ] }) : /* @__PURE__ */ O(e, {
419
+ icon: /* @__PURE__ */ O(S, { size: 32 }),
420
+ title: j("devportal.revenue.noDataTitle", "No revenue data yet"),
421
+ description: j("devportal.revenue.noDataDescription", "Revenue metrics will appear after this organization starts recording marketplace sales.")
422
+ })]
423
+ }) : /* @__PURE__ */ O(t, {
424
+ title: j("devportal.revenue.title", "Revenue"),
425
+ description: j("devportal.revenue.selectOrgDescription", "Select an organization to review real sales and payout data through the public gateway"),
426
+ children: X.length > 0 ? /* @__PURE__ */ O("div", {
427
+ className: "space-y-2",
428
+ children: X.map((e) => /* @__PURE__ */ O("button", {
429
+ type: "button",
430
+ onClick: () => P(e.id),
431
+ className: "flex w-full items-start justify-between rounded-lg border bg-card p-4 text-left transition-colors hover:bg-accent",
432
+ children: /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ k("div", {
433
+ className: "flex items-center gap-2",
434
+ children: [/* @__PURE__ */ O(x, { className: "h-4 w-4 text-primary" }), /* @__PURE__ */ O("span", {
435
+ className: "font-medium",
436
+ children: e.name
437
+ })]
438
+ }), /* @__PURE__ */ k("p", {
439
+ className: "mt-1 text-sm text-muted-foreground",
440
+ children: [
441
+ e.totalApps ?? 0,
442
+ " ",
443
+ j("devportal.revenue.apps", "apps"),
444
+ " · $",
445
+ e.totalRevenue?.toLocaleString() ?? 0,
446
+ " ",
447
+ j("devportal.revenue.revenue", "revenue")
448
+ ]
449
+ })] })
450
+ }, e.id))
451
+ }) : /* @__PURE__ */ O(e, {
452
+ icon: /* @__PURE__ */ O(S, { size: 32 }),
453
+ title: j("devportal.revenue.noOrgsTitle", "No organizations available"),
454
+ description: j("devportal.revenue.noOrgsDescription", "Create a developer organization before reviewing revenue data.")
455
+ })
456
+ });
457
+ };
458
+ //#endregion
459
+ export { j as RevenueDashboardPage };
460
+
461
+ //# sourceMappingURL=RevenueDashboardPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RevenueDashboardPage.js","names":[],"sources":["../../../src/devportal/pages/RevenueDashboardPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Line,\n LineChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport {\n AlertCircle,\n ArrowDownToLine,\n Building2,\n CreditCard,\n DollarSign,\n Link2,\n Loader2,\n Wallet,\n} from \"lucide-react\";\nimport { PageLayout, PageSection } from \"../components/PageLayout\";\nimport { DataTable } from \"../components/DataTable\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { StatCard, StatCardGrid } from \"../components/StatCard\";\nimport { StatusBadge } from \"../components/StatusBadge\";\nimport type { DeveloperOrganization } from \"../types\";\nimport {\n type GetMyOrganizationsQuery,\n type GetRevenueDashboardDataQuery,\n getErrorMessage,\n useCreateBillingAccountMutation,\n useGetMyOrganizationsQuery,\n useGetRevenueDashboardDataQuery,\n useLinkDevOrgBillingAccountMutation,\n} from \"../hooks\";\nimport { useTr } from \"../utils/i18n\";\n\ntype TimeRange = \"30d\" | \"90d\" | \"12m\";\n\nconst chartColors = {\n primary: \"var(--color-chart-1)\",\n secondary: \"var(--color-chart-2)\",\n tertiary: \"var(--color-chart-4)\",\n};\n\ntype RevenueSale =\n GetRevenueDashboardDataQuery[\"developerOrgSales\"][\"edges\"][number][\"node\"];\ntype RevenuePayout =\n GetRevenueDashboardDataQuery[\"developerOrgPayouts\"][\"edges\"][number][\"node\"];\n\nconst daysByRange: Record<TimeRange, number> = {\n \"30d\": 30,\n \"90d\": 90,\n \"12m\": 365,\n};\n\nexport const RevenueDashboardPage: FC = () => {\n const tr = useTr();\n const [timeRange, setTimeRange] = useState<TimeRange>(\"90d\");\n const [selectedOrganizationId, setSelectedOrganizationId] = useState(\"\");\n const [linkingBilling, setLinkingBilling] = useState(false);\n const [linkBillingError, setLinkBillingError] = useState<string | null>(null);\n\n const [createBillingAccount] = useCreateBillingAccountMutation();\n const [linkBillingAccount] = useLinkDevOrgBillingAccountMutation();\n const [searchParams] = useSearchParams();\n const now = useMemo(() => new Date(), []);\n const requestedOrganizationId = searchParams.get(\"org\");\n const startDate = useMemo(() => {\n const nextDate = new Date(now);\n nextDate.setDate(nextDate.getDate() - daysByRange[timeRange]);\n return nextDate.toISOString();\n }, [now, timeRange]);\n\n const {\n data: organizationsData,\n loading: organizationsLoading,\n error: organizationsError,\n } = useGetMyOrganizationsQuery({\n fetchPolicy: \"cache-and-network\",\n });\n const { data, loading, error } = useGetRevenueDashboardDataQuery({\n variables: {\n organizationId: selectedOrganizationId,\n period: \"monthly\",\n startDate,\n endDate: now.toISOString(),\n salesLimit: 10,\n salesOffset: 0,\n payoutsLimit: 10,\n payoutsOffset: 0,\n },\n skip: !selectedOrganizationId,\n fetchPolicy: \"cache-and-network\",\n });\n\n const organizations: DeveloperOrganization[] = useMemo(\n () =>\n organizationsData?.myDeveloperOrganizations?.map(\n (\n organization: GetMyOrganizationsQuery[\"myDeveloperOrganizations\"][number],\n ) => organization as unknown as DeveloperOrganization,\n ) ?? [],\n [organizationsData?.myDeveloperOrganizations],\n );\n\n useEffect(() => {\n if (selectedOrganizationId) {\n return;\n }\n\n if (\n requestedOrganizationId &&\n organizations.some(\n (organization) => organization.id === requestedOrganizationId,\n )\n ) {\n setSelectedOrganizationId(requestedOrganizationId);\n return;\n }\n\n if (organizations.length === 1) {\n setSelectedOrganizationId(organizations[0]?.id ?? \"\");\n }\n }, [organizations, requestedOrganizationId, selectedOrganizationId]);\n\n const selectedOrganization = organizations.find(\n (organization) => organization.id === selectedOrganizationId,\n );\n\n const handleLinkBillingAccount = async () => {\n if (!selectedOrganizationId) return;\n setLinkingBilling(true);\n setLinkBillingError(null);\n try {\n const billingResult = await createBillingAccount({\n variables: {\n input: {\n name: selectedOrganization?.name ?? selectedOrganizationId,\n email: \"\",\n },\n },\n });\n const billingAccountId = billingResult.data?.createBillingAccount?.id;\n if (billingAccountId) {\n await linkBillingAccount({\n variables: {\n organizationId: selectedOrganizationId,\n billingAccountId,\n },\n refetchQueries: [\"GetMyOrganizations\"],\n });\n }\n } catch (err) {\n setLinkBillingError(\n err instanceof Error ? err.message : \"Failed to link billing account\",\n );\n } finally {\n setLinkingBilling(false);\n }\n };\n\n const summary = data?.developerOrgRevenueSummary;\n const analytics = [...(data?.developerOrgRevenueAnalytics ?? [])].sort(\n (left, right) =>\n new Date(left.date).getTime() - new Date(right.date).getTime(),\n );\n const sales: RevenueSale[] =\n data?.developerOrgSales?.edges?.map(\n (\n edge: GetRevenueDashboardDataQuery[\"developerOrgSales\"][\"edges\"][number],\n ) => edge.node,\n ) ?? [];\n const payouts: RevenuePayout[] =\n data?.developerOrgPayouts?.edges?.map(\n (\n edge: GetRevenueDashboardDataQuery[\"developerOrgPayouts\"][\"edges\"][number],\n ) => edge.node,\n ) ?? [];\n\n const chartData = analytics.map((entry) => ({\n date: new Date(entry.date).toLocaleDateString(undefined, {\n month: \"short\",\n day: \"numeric\",\n }),\n grossRevenue: entry.grossRevenue,\n netRevenue: entry.netRevenue,\n platformFees: entry.platformFees,\n refunds: entry.refunds,\n salesCount: entry.salesCount,\n }));\n\n if (organizationsLoading && !organizationsData) {\n return (\n <PageLayout\n title={tr(\"devportal.revenue.title\", \"Revenue\")}\n description={tr(\n \"devportal.revenue.description\",\n \"Track real revenue, sales, and payout activity for your developer organizations\",\n )}\n >\n <div className=\"flex items-center justify-center py-16 text-muted-foreground\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n </PageLayout>\n );\n }\n\n if (organizationsError) {\n return (\n <PageLayout\n title={tr(\"devportal.revenue.title\", \"Revenue\")}\n description={tr(\n \"devportal.revenue.description\",\n \"Track real revenue, sales, and payout activity for your developer organizations\",\n )}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.revenue.errorLoadOrgs\",\n \"Unable to load organizations\",\n )}\n description={getErrorMessage(organizationsError)}\n />\n </PageLayout>\n );\n }\n\n if (!selectedOrganizationId) {\n return (\n <PageLayout\n title={tr(\"devportal.revenue.title\", \"Revenue\")}\n description={tr(\n \"devportal.revenue.selectOrgDescription\",\n \"Select an organization to review real sales and payout data through the public gateway\",\n )}\n >\n {organizations.length > 0 ? (\n <div className=\"space-y-2\">\n {organizations.map((organization) => (\n <button\n key={organization.id}\n type=\"button\"\n onClick={() => setSelectedOrganizationId(organization.id)}\n className=\"flex w-full items-start justify-between rounded-lg border bg-card p-4 text-left transition-colors hover:bg-accent\"\n >\n <div>\n <div className=\"flex items-center gap-2\">\n <Building2 className=\"h-4 w-4 text-primary\" />\n <span className=\"font-medium\">{organization.name}</span>\n </div>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {organization.totalApps ?? 0}{\" \"}\n {tr(\"devportal.revenue.apps\", \"apps\")} · $\n {organization.totalRevenue?.toLocaleString() ?? 0}{\" \"}\n {tr(\"devportal.revenue.revenue\", \"revenue\")}\n </p>\n </div>\n </button>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<DollarSign size={32} />}\n title={tr(\n \"devportal.revenue.noOrgsTitle\",\n \"No organizations available\",\n )}\n description={tr(\n \"devportal.revenue.noOrgsDescription\",\n \"Create a developer organization before reviewing revenue data.\",\n )}\n />\n )}\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title={tr(\"devportal.revenue.title\", \"Revenue\")}\n description={tr(\n \"devportal.revenue.description\",\n \"Track real revenue, sales, and payout activity for your developer organizations\",\n )}\n >\n <EmptyState\n icon={<AlertCircle size={32} className=\"text-status-error-text\" />}\n title={tr(\n \"devportal.revenue.errorLoadData\",\n \"Unable to load revenue data\",\n )}\n description={getErrorMessage(error)}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={tr(\"devportal.revenue.title\", \"Revenue\")}\n description={\n selectedOrganization\n ? `${tr(\"devportal.revenue.financialPerformanceFor\", \"Financial performance for\")} ${selectedOrganization.name}`\n : tr(\n \"devportal.revenue.shortDescription\",\n \"Track revenue, sales, and payouts\",\n )\n }\n actions={\n <div className=\"flex flex-wrap gap-2\">\n <select\n value={selectedOrganizationId}\n onChange={(event) => setSelectedOrganizationId(event.target.value)}\n aria-label={tr(\n \"devportal.revenue.selectOrgAria\",\n \"Select organization\",\n )}\n className=\"rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n {organizations.map((organization) => (\n <option key={organization.id} value={organization.id}>\n {organization.name}\n </option>\n ))}\n </select>\n <select\n value={timeRange}\n onChange={(event) => setTimeRange(event.target.value as TimeRange)}\n aria-label={tr(\n \"devportal.revenue.selectRangeAria\",\n \"Select time range\",\n )}\n className=\"rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary\"\n >\n <option value=\"30d\">\n {tr(\"devportal.revenue.range.30d\", \"Last 30 days\")}\n </option>\n <option value=\"90d\">\n {tr(\"devportal.revenue.range.90d\", \"Last 90 days\")}\n </option>\n <option value=\"12m\">\n {tr(\"devportal.revenue.range.12m\", \"Last 12 months\")}\n </option>\n </select>\n </div>\n }\n >\n {/* Billing account link banner for orgs not yet linked */}\n {selectedOrganization && !selectedOrganization.billingAccountId && (\n <div className=\"mb-6 rounded-lg border border-border-subtle bg-status-info-bg-subtle p-4 flex items-start gap-3\">\n <Link2 size={20} className=\"text-accent-blue flex-shrink-0 mt-0.5\" />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-status-info-text\">\n {tr(\n \"devportal.revenue.billingNotLinkedTitle\",\n \"Link a billing account to receive store revenue\",\n )}\n </p>\n <p className=\"mt-1 text-sm text-status-info-text\">\n {tr(\n \"devportal.revenue.billingNotLinkedDesc\",\n \"Once linked, net earnings from app sales will appear in your billing credits — you can spend them on platform services or withdraw to your bank.\",\n )}\n </p>\n {linkBillingError && (\n <p className=\"mt-2 text-sm text-status-error-text\">\n {linkBillingError}\n </p>\n )}\n </div>\n <button\n type=\"button\"\n onClick={handleLinkBillingAccount}\n disabled={linkingBilling}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50 flex-shrink-0\"\n >\n {linkingBilling ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : (\n <Link2 size={14} />\n )}\n {linkingBilling\n ? tr(\"devportal.revenue.linking\", \"Linking...\")\n : tr(\n \"devportal.revenue.linkBillingAccount\",\n \"Link Billing Account\",\n )}\n </button>\n </div>\n )}\n\n {loading && !summary ? (\n <div className=\"flex items-center justify-center py-16 text-muted-foreground\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n ) : summary ? (\n <>\n <StatCardGrid columns={4}>\n <StatCard\n title={tr(\"devportal.revenue.grossRevenue\", \"Gross Revenue\")}\n value={`$${summary.totalGrossRevenue.toLocaleString()}`}\n icon={<DollarSign size={20} />}\n />\n <StatCard\n title={tr(\"devportal.revenue.netRevenue\", \"Net Revenue\")}\n value={`$${summary.totalNetRevenue.toLocaleString()}`}\n icon={<Wallet size={20} />}\n />\n <StatCard\n title={tr(\"devportal.revenue.pendingBalance\", \"Pending Balance\")}\n value={`$${summary.pendingBalance.toLocaleString()}`}\n icon={<CreditCard size={20} />}\n description={\n summary.nextPayoutDate\n ? `${tr(\"devportal.revenue.nextPayout\", \"Next payout\")} ${new Date(summary.nextPayoutDate).toLocaleDateString()}`\n : tr(\n \"devportal.revenue.noPayoutScheduled\",\n \"No payout scheduled\",\n )\n }\n />\n <StatCard\n title={tr(\"devportal.revenue.platformFees\", \"Platform Fees\")}\n value={`$${summary.totalPlatformFees.toLocaleString()}`}\n icon={<ArrowDownToLine size={20} />}\n description={`${summary.totalRefundsCount} ${tr(\"devportal.revenue.refunds\", \"refunds\")}`}\n />\n </StatCardGrid>\n\n <div className=\"grid gap-6 xl:grid-cols-2\">\n <PageSection\n title={tr(\"devportal.revenue.revenueTrend\", \"Revenue trend\")}\n >\n <div className=\"rounded-lg border bg-card p-4\">\n <ResponsiveContainer width=\"100%\" height={300}>\n <LineChart data={chartData}>\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"var(--color-chart-grid)\"\n />\n <XAxis\n dataKey=\"date\"\n stroke=\"var(--color-chart-axis)\"\n fontSize={12}\n />\n <YAxis stroke=\"var(--color-chart-axis)\" fontSize={12} />\n <Tooltip\n contentStyle={{\n backgroundColor: \"var(--color-card)\",\n border: \"1px solid var(--color-border-default)\",\n borderRadius: 12,\n }}\n />\n <Line\n type=\"monotone\"\n dataKey=\"grossRevenue\"\n stroke={chartColors.primary}\n strokeWidth={2}\n dot={false}\n />\n <Line\n type=\"monotone\"\n dataKey=\"netRevenue\"\n stroke={chartColors.secondary}\n strokeWidth={2}\n dot={false}\n />\n </LineChart>\n </ResponsiveContainer>\n </div>\n </PageSection>\n\n <PageSection\n title={tr(\n \"devportal.revenue.topApps\",\n \"Top applications by revenue\",\n )}\n >\n {summary.topApps.length > 0 ? (\n <div className=\"space-y-2\">\n {summary.topApps.map(\n (\n application: GetRevenueDashboardDataQuery[\"developerOrgRevenueSummary\"][\"topApps\"][number],\n ) => (\n <div\n key={application.applicationId}\n className=\"rounded-lg border bg-card p-4\"\n >\n <div className=\"flex items-start justify-between gap-3\">\n <div>\n <p className=\"font-medium\">\n {application.applicationName}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {application.salesCount}{\" \"}\n {tr(\"devportal.revenue.sales\", \"sales\")}\n </p>\n </div>\n <div className=\"text-right\">\n <p className=\"font-semibold\">\n ${application.grossRevenue.toLocaleString()}\n </p>\n <p className=\"text-sm text-muted-foreground\">\n {tr(\"devportal.revenue.net\", \"Net\")} $\n {application.netRevenue.toLocaleString()}\n </p>\n </div>\n </div>\n </div>\n ),\n )}\n </div>\n ) : (\n <EmptyState\n icon={<Building2 size={24} />}\n title={tr(\n \"devportal.revenue.noLeadersTitle\",\n \"No revenue leaders yet\",\n )}\n description={tr(\n \"devportal.revenue.noLeadersDescription\",\n \"Top-performing applications will appear here once revenue is recorded.\",\n )}\n />\n )}\n </PageSection>\n </div>\n\n <PageSection\n title={tr(\"devportal.revenue.salesVolume\", \"Sales volume\")}\n >\n <div className=\"rounded-lg border bg-card p-4\">\n <ResponsiveContainer width=\"100%\" height={280}>\n <BarChart data={chartData}>\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"var(--color-chart-grid)\"\n />\n <XAxis\n dataKey=\"date\"\n stroke=\"var(--color-chart-axis)\"\n fontSize={12}\n />\n <YAxis stroke=\"var(--color-chart-axis)\" fontSize={12} />\n <Tooltip\n contentStyle={{\n backgroundColor: \"var(--color-card)\",\n border: \"1px solid var(--color-border-default)\",\n borderRadius: 12,\n }}\n />\n <Bar\n dataKey=\"salesCount\"\n fill={chartColors.tertiary}\n radius={[6, 6, 0, 0]}\n />\n </BarChart>\n </ResponsiveContainer>\n </div>\n </PageSection>\n\n <div className=\"grid gap-6 xl:grid-cols-2\">\n <PageSection\n title={tr(\"devportal.revenue.recentSales\", \"Recent sales\")}\n >\n <DataTable\n data={sales}\n keyField=\"id\"\n columns={[\n {\n key: \"application\",\n header: tr(\"devportal.revenue.application\", \"Application\"),\n render: (sale) =>\n sale.application?.name ||\n sale.planName ||\n tr(\"devportal.common.unknown\", \"Unknown\"),\n },\n {\n key: \"grossAmount\",\n header: tr(\"devportal.revenue.gross\", \"Gross\"),\n render: (sale) => `$${sale.grossAmount.toLocaleString()}`,\n },\n {\n key: \"netAmount\",\n header: tr(\"devportal.revenue.net\", \"Net\"),\n render: (sale) => `$${sale.netAmount.toLocaleString()}`,\n },\n {\n key: \"status\",\n header: tr(\"devportal.revenue.status\", \"Status\"),\n render: (sale) => (\n <StatusBadge status={sale.status} type=\"app\" />\n ),\n },\n ]}\n />\n </PageSection>\n\n <PageSection\n title={tr(\"devportal.revenue.payoutHistory\", \"Payout history\")}\n >\n <DataTable\n data={payouts}\n keyField=\"id\"\n columns={[\n {\n key: \"periodLabel\",\n header: tr(\"devportal.revenue.period\", \"Period\"),\n render: (payout) => payout.periodLabel,\n },\n {\n key: \"netAmount\",\n header: tr(\"devportal.revenue.netPayout\", \"Net payout\"),\n render: (payout) => `$${payout.netAmount.toLocaleString()}`,\n },\n {\n key: \"status\",\n header: tr(\"devportal.revenue.status\", \"Status\"),\n render: (payout) => (\n <StatusBadge status={payout.status} type=\"app\" />\n ),\n },\n ]}\n />\n </PageSection>\n </div>\n </>\n ) : (\n <EmptyState\n icon={<DollarSign size={32} />}\n title={tr(\"devportal.revenue.noDataTitle\", \"No revenue data yet\")}\n description={tr(\n \"devportal.revenue.noDataDescription\",\n \"Revenue metrics will appear after this organization starts recording marketplace sales.\",\n )}\n />\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}