@burdenoff/microfe-devportal 2026.707.2 → 2026.711.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/devportal/AdminDevportalRoot.js +33 -27
  2. package/dist/devportal/AdminDevportalRoot.js.map +1 -1
  3. package/dist/devportal/AdminDevportalRoutes.js +9 -5
  4. package/dist/devportal/AdminDevportalRoutes.js.map +1 -1
  5. package/dist/devportal/DevportalRoutes.js +125 -105
  6. package/dist/devportal/DevportalRoutes.js.map +1 -1
  7. package/dist/devportal/pages/AdminOrganizationVerificationPage.js +169 -0
  8. package/dist/devportal/pages/AdminOrganizationVerificationPage.js.map +1 -0
  9. package/dist/devportal/pages/CreatePhysicalItemPage.js +494 -0
  10. package/dist/devportal/pages/CreatePhysicalItemPage.js.map +1 -0
  11. package/dist/devportal/pages/EditPhysicalItemPage.js +419 -0
  12. package/dist/devportal/pages/EditPhysicalItemPage.js.map +1 -0
  13. package/dist/devportal/pages/OrganizationDetailPage.js +441 -295
  14. package/dist/devportal/pages/OrganizationDetailPage.js.map +1 -1
  15. package/dist/devportal/pages/RevenueDashboardPage.js +72 -54
  16. package/dist/devportal/pages/RevenueDashboardPage.js.map +1 -1
  17. package/dist/devportal/pages/SellerDashboardPage.js +364 -0
  18. package/dist/devportal/pages/SellerDashboardPage.js.map +1 -0
  19. package/dist/devportal/pages/SellerItemsPage.js +533 -0
  20. package/dist/devportal/pages/SellerItemsPage.js.map +1 -0
  21. package/dist/devportal/pages/SellerOrdersPage.js +411 -0
  22. package/dist/devportal/pages/SellerOrdersPage.js.map +1 -0
  23. package/dist/devportal/types/index.js.map +1 -1
  24. package/dist/generated/global-operations.js +48 -55
  25. package/dist/generated/global-operations.js.map +1 -1
  26. package/package.json +1 -1
@@ -1,26 +1,26 @@
1
1
  import { useDevportal as e } from "../providers/DevportalProvider.js";
2
2
  import { cn as t } from "../utils/cn.js";
3
3
  import { EmptyState as n } from "../components/EmptyState.js";
4
- import { useGetBillingAccountsByOrgQuery as ee, useGetMyOrganizationsQuery as r, useGetRevenueDashboardDataQuery as te, useLinkDevOrgBillingAccountMutation as ne } from "../../generated/global-operations.js";
5
- import { getErrorMessage as i } from "../hooks/useGraphQL.js";
6
- import { PageLayout as a, PageSection as o } from "../components/PageLayout.js";
7
- import { StatusBadge as s } from "../components/StatusBadge.js";
8
- import { StatCard as c, StatCardGrid as re } from "../components/StatCard.js";
9
- import { DataTable as l } from "../components/DataTable.js";
4
+ import { useGetBillingAccountsByOrgQuery as ee, useGetMyOrganizationsQuery as te, useGetRevenueDashboardDataQuery as ne, useLinkDevOrgBillingAccountMutation as re } from "../../generated/global-operations.js";
5
+ import { getErrorMessage as r } from "../hooks/useGraphQL.js";
6
+ import { PageLayout as i, PageSection as a } from "../components/PageLayout.js";
7
+ import { StatusBadge as o } from "../components/StatusBadge.js";
8
+ import { StatCard as s, StatCardGrid as ie } from "../components/StatCard.js";
9
+ import { DataTable as c } from "../components/DataTable.js";
10
10
  import "../hooks/index.js";
11
- import { Tooltip as u } from "../../node_modules/recharts/es6/component/Tooltip.js";
12
- import { ResponsiveContainer as d } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
13
- import { Bar as ie } from "../../node_modules/recharts/es6/cartesian/Bar.js";
14
- import { CartesianGrid as f } from "../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
15
- import { Line as p } from "../../node_modules/recharts/es6/cartesian/Line.js";
16
- import { XAxis as m } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
17
- import { YAxis as h } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
18
- import { LineChart as ae } from "../../node_modules/recharts/es6/chart/LineChart.js";
11
+ import { Tooltip as l } from "../../node_modules/recharts/es6/component/Tooltip.js";
12
+ import { ResponsiveContainer as u } from "../../node_modules/recharts/es6/component/ResponsiveContainer.js";
13
+ import { Bar as ae } from "../../node_modules/recharts/es6/cartesian/Bar.js";
14
+ import { CartesianGrid as d } from "../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
15
+ import { Line as f } from "../../node_modules/recharts/es6/cartesian/Line.js";
16
+ import { XAxis as p } from "../../node_modules/recharts/es6/cartesian/XAxis.js";
17
+ import { YAxis as m } from "../../node_modules/recharts/es6/cartesian/YAxis.js";
18
+ import { LineChart as h } from "../../node_modules/recharts/es6/chart/LineChart.js";
19
19
  import { BarChart as oe } from "../../node_modules/recharts/es6/chart/BarChart.js";
20
20
  import { useTr as se } from "../utils/i18n.js";
21
21
  import { useMemo as g, useState as _ } from "react";
22
- import { AlertCircle as v, ArrowDownToLine as ce, Building2 as y, Check as b, CreditCard as x, DollarSign as S, Link2 as C, Loader2 as w, Wallet as T } from "lucide-react";
23
- import { useSearchParams as le } from "react-router-dom";
22
+ import { AlertCircle as v, ArrowDownToLine as ce, Building2 as y, Check as b, CreditCard as x, DollarSign as S, Link2 as C, Loader2 as w, Wallet as le } from "lucide-react";
23
+ import { useSearchParams as T } from "react-router-dom";
24
24
  import { Fragment as ue, jsx as E, jsxs as D } from "react/jsx-runtime";
25
25
  import { EmphasisPanel as de, GlassCard as O } from "@burdenoff/fe-libs/ui";
26
26
  //#region src/devportal/pages/RevenueDashboardPage.tsx
@@ -33,13 +33,13 @@ var k = {
33
33
  "90d": 90,
34
34
  "12m": 365
35
35
  }, A = () => {
36
- let A = se(), { activeOrgId: j, tenantId: pe } = e(), [M, me] = _("90d"), [N, P] = _(!1), [F, I] = _(null), [he] = ne(), [L, R] = _(!1), [z, B] = _(null), [ge] = le(), V = g(() => /* @__PURE__ */ new Date(), []), { data: _e, loading: H } = ee({
36
+ let A = se(), { activeOrgId: j, tenantId: pe } = e(), [M, me] = _("90d"), [N, P] = _(!1), [F, I] = _(null), [he] = re(), [L, R] = _(!1), [z, B] = _(null), [ge] = T(), V = g(() => /* @__PURE__ */ new Date(), []), { data: _e, loading: H } = ee({
37
37
  fetchPolicy: "cache-and-network",
38
38
  context: { headers: { "x-org-id": pe ?? "" } }
39
39
  }), ve = g(() => {
40
40
  let e = new Date(V);
41
41
  return e.setDate(e.getDate() - fe[M]), e.toISOString();
42
- }, [V, M]), { data: U, loading: ye, error: W } = r({ fetchPolicy: "cache-and-network" }), { data: G, loading: be, error: K } = te({
42
+ }, [V, M]), { data: U, loading: ye, error: W } = te({ fetchPolicy: "cache-and-network" }), { data: G, loading: be, error: K } = ne({
43
43
  variables: {
44
44
  organizationId: j ?? "",
45
45
  period: "monthly",
@@ -82,14 +82,14 @@ var k = {
82
82
  refunds: e.refunds,
83
83
  salesCount: e.salesCount
84
84
  }));
85
- return ye && !U ? /* @__PURE__ */ E(a, {
85
+ return ye && !U ? /* @__PURE__ */ E(i, {
86
86
  title: A("devportal.revenue.title", "Revenue"),
87
87
  description: A("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
88
88
  children: /* @__PURE__ */ E("div", {
89
89
  className: "flex items-center justify-center py-16 text-text-secondary",
90
90
  children: /* @__PURE__ */ E(w, { className: "h-8 w-8 animate-spin" })
91
91
  })
92
- }) : W ? /* @__PURE__ */ E(a, {
92
+ }) : W ? /* @__PURE__ */ E(i, {
93
93
  title: A("devportal.revenue.title", "Revenue"),
94
94
  description: A("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
95
95
  children: /* @__PURE__ */ E(n, {
@@ -98,9 +98,9 @@ var k = {
98
98
  className: "text-status-error-text"
99
99
  }),
100
100
  title: A("devportal.revenue.errorLoadOrgs", "Unable to load organizations"),
101
- description: i(W)
101
+ description: r(W)
102
102
  })
103
- }) : j ? K ? /* @__PURE__ */ E(a, {
103
+ }) : j ? K ? /* @__PURE__ */ E(i, {
104
104
  title: A("devportal.revenue.title", "Revenue"),
105
105
  description: A("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
106
106
  children: /* @__PURE__ */ E(n, {
@@ -109,9 +109,9 @@ var k = {
109
109
  className: "text-status-error-text"
110
110
  }),
111
111
  title: A("devportal.revenue.errorLoadData", "Unable to load revenue data"),
112
- description: i(K)
112
+ description: r(K)
113
113
  })
114
- }) : /* @__PURE__ */ D(a, {
114
+ }) : /* @__PURE__ */ D(i, {
115
115
  title: A("devportal.revenue.title", "Revenue"),
116
116
  description: q ? `${A("devportal.revenue.financialPerformanceFor", "Financial performance for")} ${q.name}` : A("devportal.revenue.shortDescription", "Track revenue, sales, and payouts"),
117
117
  purpose: A("devportal.revenue.purpose", "Revenue tracks the money your paid apps earn — gross sales, platform fees, and what gets paid out to your organization. Link a billing account, then use this to reconcile payouts and watch growth across time ranges."),
@@ -322,26 +322,26 @@ var k = {
322
322
  }) : Q ? /* @__PURE__ */ D(ue, { children: [
323
323
  /* @__PURE__ */ E(de, {
324
324
  className: "mb-6",
325
- children: /* @__PURE__ */ D(re, {
325
+ children: /* @__PURE__ */ D(ie, {
326
326
  columns: 4,
327
327
  children: [
328
- /* @__PURE__ */ E(c, {
328
+ /* @__PURE__ */ E(s, {
329
329
  title: A("devportal.revenue.grossRevenue", "Gross Revenue"),
330
330
  value: `$${Q.totalGrossRevenue.toLocaleString()}`,
331
331
  icon: /* @__PURE__ */ E(S, { size: 20 })
332
332
  }),
333
- /* @__PURE__ */ E(c, {
333
+ /* @__PURE__ */ E(s, {
334
334
  title: A("devportal.revenue.netRevenue", "Net Revenue"),
335
335
  value: `$${Q.totalNetRevenue.toLocaleString()}`,
336
- icon: /* @__PURE__ */ E(T, { size: 20 })
336
+ icon: /* @__PURE__ */ E(le, { size: 20 })
337
337
  }),
338
- /* @__PURE__ */ E(c, {
338
+ /* @__PURE__ */ E(s, {
339
339
  title: A("devportal.revenue.pendingBalance", "Pending Balance"),
340
340
  value: `$${Q.pendingBalance.toLocaleString()}`,
341
341
  icon: /* @__PURE__ */ E(x, { size: 20 }),
342
342
  description: Q.nextPayoutDate ? `${A("devportal.revenue.nextPayout", "Next payout")} ${new Date(Q.nextPayoutDate).toLocaleDateString()}` : A("devportal.revenue.noPayoutScheduled", "No payout scheduled")
343
343
  }),
344
- /* @__PURE__ */ E(c, {
344
+ /* @__PURE__ */ E(s, {
345
345
  title: A("devportal.revenue.platformFees", "Platform Fees"),
346
346
  value: `$${Q.totalPlatformFees.toLocaleString()}`,
347
347
  icon: /* @__PURE__ */ E(ce, { size: 20 }),
@@ -352,43 +352,43 @@ var k = {
352
352
  }),
353
353
  /* @__PURE__ */ D("div", {
354
354
  className: "grid gap-6 xl:grid-cols-2",
355
- children: [/* @__PURE__ */ E(o, {
355
+ children: [/* @__PURE__ */ E(a, {
356
356
  title: A("devportal.revenue.revenueTrend", "Revenue trend"),
357
357
  children: /* @__PURE__ */ E(O, {
358
358
  treatment: "insight",
359
359
  className: "p-4",
360
- children: /* @__PURE__ */ E(d, {
360
+ children: $.length > 0 ? /* @__PURE__ */ E(u, {
361
361
  width: "100%",
362
362
  height: 300,
363
- children: /* @__PURE__ */ D(ae, {
363
+ children: /* @__PURE__ */ D(h, {
364
364
  data: $,
365
365
  children: [
366
- /* @__PURE__ */ E(f, {
366
+ /* @__PURE__ */ E(d, {
367
367
  strokeDasharray: "3 3",
368
368
  stroke: "var(--color-chart-grid)"
369
369
  }),
370
- /* @__PURE__ */ E(m, {
370
+ /* @__PURE__ */ E(p, {
371
371
  dataKey: "date",
372
372
  stroke: "var(--color-chart-axis)",
373
373
  fontSize: 12
374
374
  }),
375
- /* @__PURE__ */ E(h, {
375
+ /* @__PURE__ */ E(m, {
376
376
  stroke: "var(--color-chart-axis)",
377
377
  fontSize: 12
378
378
  }),
379
- /* @__PURE__ */ E(u, { contentStyle: {
379
+ /* @__PURE__ */ E(l, { contentStyle: {
380
380
  backgroundColor: "var(--color-card)",
381
381
  border: "1px solid var(--color-border-default)",
382
382
  borderRadius: 12
383
383
  } }),
384
- /* @__PURE__ */ E(p, {
384
+ /* @__PURE__ */ E(f, {
385
385
  type: "monotone",
386
386
  dataKey: "grossRevenue",
387
387
  stroke: k.primary,
388
388
  strokeWidth: 2,
389
389
  dot: !1
390
390
  }),
391
- /* @__PURE__ */ E(p, {
391
+ /* @__PURE__ */ E(f, {
392
392
  type: "monotone",
393
393
  dataKey: "netRevenue",
394
394
  stroke: k.secondary,
@@ -397,9 +397,18 @@ var k = {
397
397
  })
398
398
  ]
399
399
  })
400
+ }) : /* @__PURE__ */ D("div", {
401
+ className: "flex h-[300px] flex-col items-center justify-center gap-2 text-text-secondary",
402
+ children: [/* @__PURE__ */ E("p", {
403
+ className: "text-sm font-medium",
404
+ children: A("devportal.revenue.noTrendData", "No trend data yet")
405
+ }), /* @__PURE__ */ E("p", {
406
+ className: "text-xs text-text-tertiary",
407
+ children: A("devportal.revenue.noTrendDataHint", "Revenue trend appears once daily analytics have been aggregated.")
408
+ })]
400
409
  })
401
410
  })
402
- }), /* @__PURE__ */ E(o, {
411
+ }), /* @__PURE__ */ E(a, {
403
412
  title: A("devportal.revenue.topApps", "Top applications by revenue"),
404
413
  children: Q.topApps.length > 0 ? /* @__PURE__ */ E("div", {
405
414
  className: "space-y-2",
@@ -442,36 +451,36 @@ var k = {
442
451
  })
443
452
  })]
444
453
  }),
445
- /* @__PURE__ */ E(o, {
454
+ /* @__PURE__ */ E(a, {
446
455
  title: A("devportal.revenue.salesVolume", "Sales volume"),
447
456
  children: /* @__PURE__ */ E(O, {
448
457
  treatment: "insight",
449
458
  className: "p-4",
450
- children: /* @__PURE__ */ E(d, {
459
+ children: $.length > 0 ? /* @__PURE__ */ E(u, {
451
460
  width: "100%",
452
461
  height: 280,
453
462
  children: /* @__PURE__ */ D(oe, {
454
463
  data: $,
455
464
  children: [
456
- /* @__PURE__ */ E(f, {
465
+ /* @__PURE__ */ E(d, {
457
466
  strokeDasharray: "3 3",
458
467
  stroke: "var(--color-chart-grid)"
459
468
  }),
460
- /* @__PURE__ */ E(m, {
469
+ /* @__PURE__ */ E(p, {
461
470
  dataKey: "date",
462
471
  stroke: "var(--color-chart-axis)",
463
472
  fontSize: 12
464
473
  }),
465
- /* @__PURE__ */ E(h, {
474
+ /* @__PURE__ */ E(m, {
466
475
  stroke: "var(--color-chart-axis)",
467
476
  fontSize: 12
468
477
  }),
469
- /* @__PURE__ */ E(u, { contentStyle: {
478
+ /* @__PURE__ */ E(l, { contentStyle: {
470
479
  backgroundColor: "var(--color-card)",
471
480
  border: "1px solid var(--color-border-default)",
472
481
  borderRadius: 12
473
482
  } }),
474
- /* @__PURE__ */ E(ie, {
483
+ /* @__PURE__ */ E(ae, {
475
484
  dataKey: "salesCount",
476
485
  fill: k.tertiary,
477
486
  radius: [
@@ -483,14 +492,23 @@ var k = {
483
492
  })
484
493
  ]
485
494
  })
495
+ }) : /* @__PURE__ */ D("div", {
496
+ className: "flex h-[280px] flex-col items-center justify-center gap-2 text-text-secondary",
497
+ children: [/* @__PURE__ */ E("p", {
498
+ className: "text-sm font-medium",
499
+ children: A("devportal.revenue.noVolumeData", "No sales volume data yet")
500
+ }), /* @__PURE__ */ E("p", {
501
+ className: "text-xs text-text-tertiary",
502
+ children: A("devportal.revenue.noVolumeDataHint", "Sales volume by period appears once analytics have been aggregated.")
503
+ })]
486
504
  })
487
505
  })
488
506
  }),
489
507
  /* @__PURE__ */ D("div", {
490
508
  className: "grid gap-6 xl:grid-cols-2",
491
- children: [/* @__PURE__ */ E(o, {
509
+ children: [/* @__PURE__ */ E(a, {
492
510
  title: A("devportal.revenue.recentSales", "Recent sales"),
493
- children: /* @__PURE__ */ E(l, {
511
+ children: /* @__PURE__ */ E(c, {
494
512
  data: Se,
495
513
  keyField: "id",
496
514
  columns: [
@@ -512,16 +530,16 @@ var k = {
512
530
  {
513
531
  key: "status",
514
532
  header: A("devportal.revenue.status", "Status"),
515
- render: (e) => /* @__PURE__ */ E(s, {
533
+ render: (e) => /* @__PURE__ */ E(o, {
516
534
  status: e.status,
517
535
  type: "app"
518
536
  })
519
537
  }
520
538
  ]
521
539
  })
522
- }), /* @__PURE__ */ E(o, {
540
+ }), /* @__PURE__ */ E(a, {
523
541
  title: A("devportal.revenue.payoutHistory", "Payout history"),
524
- children: /* @__PURE__ */ E(l, {
542
+ children: /* @__PURE__ */ E(c, {
525
543
  data: Ce,
526
544
  keyField: "id",
527
545
  columns: [
@@ -538,7 +556,7 @@ var k = {
538
556
  {
539
557
  key: "status",
540
558
  header: A("devportal.revenue.status", "Status"),
541
- render: (e) => /* @__PURE__ */ E(s, {
559
+ render: (e) => /* @__PURE__ */ E(o, {
542
560
  status: e.status,
543
561
  type: "app"
544
562
  })
@@ -554,7 +572,7 @@ var k = {
554
572
  description: A("devportal.revenue.noDataDescription", "Revenue metrics will appear after this organization starts recording marketplace sales.")
555
573
  })
556
574
  ]
557
- }) : /* @__PURE__ */ E(a, {
575
+ }) : /* @__PURE__ */ E(i, {
558
576
  title: A("devportal.revenue.title", "Revenue"),
559
577
  description: A("devportal.revenue.description", "Track real revenue, sales, and payout activity for your developer organizations"),
560
578
  children: /* @__PURE__ */ E(n, {
@@ -1 +1 @@
1
- {"version":3,"file":"RevenueDashboardPage.js","names":[],"sources":["../../../src/devportal/pages/RevenueDashboardPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { 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 Check,\n CreditCard,\n DollarSign,\n Link2,\n Loader2,\n Wallet,\n} from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\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 useGetBillingAccountsByOrgQuery,\n useGetMyOrganizationsQuery,\n useGetRevenueDashboardDataQuery,\n useLinkDevOrgBillingAccountMutation,\n} from \"../hooks\";\nimport { cn } from \"../utils/cn\";\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 { activeOrgId, tenantId } = useDevportal();\n const [timeRange, setTimeRange] = useState<TimeRange>(\"90d\");\n const [linkingBilling, setLinkingBilling] = useState(false);\n const [linkBillingError, setLinkBillingError] = useState<string | null>(null);\n\n const [linkBillingAccount] = useLinkDevOrgBillingAccountMutation();\n const [showBillingPicker, setShowBillingPicker] = useState(false);\n const [selectedBillingAccountId, setSelectedBillingAccountId] = useState<\n string | null\n >(null);\n const [searchParams] = useSearchParams();\n const now = useMemo(() => new Date(), []);\n\n const { data: billingAccountsData, loading: billingAccountsLoading } =\n useGetBillingAccountsByOrgQuery({\n fetchPolicy: \"cache-and-network\",\n context: { headers: { \"x-org-id\": tenantId ?? \"\" } },\n });\n // searchParams kept for deep-link compatibility (URL ?org= still works via OrgSwitcher auto-select)\n void searchParams;\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: activeOrgId ?? \"\",\n period: \"monthly\",\n startDate,\n endDate: now.toISOString(),\n salesLimit: 10,\n salesOffset: 0,\n payoutsLimit: 10,\n payoutsOffset: 0,\n },\n skip: !activeOrgId,\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 const selectedOrganization = organizations.find(\n (organization) => organization.id === activeOrgId,\n );\n\n type BillingAccount = NonNullable<\n typeof billingAccountsData\n >[\"getBillingAccountsByOrg\"][number];\n const existingBillingAccounts: BillingAccount[] =\n billingAccountsData?.getBillingAccountsByOrg ?? [];\n\n const linkedBillingAccount =\n existingBillingAccounts.find(\n (a) => a.id === selectedOrganization?.billingAccountId,\n ) ?? null;\n\n const handleOpenBillingPicker = () => {\n // Pre-select the currently linked account; fall back to default or first\n setSelectedBillingAccountId(\n selectedOrganization?.billingAccountId ??\n existingBillingAccounts.find((a) => a.isDefault)?.id ??\n existingBillingAccounts[0]?.id ??\n null,\n );\n setShowBillingPicker(true);\n };\n\n const handleLinkExisting = async () => {\n if (!activeOrgId || !selectedBillingAccountId) return;\n setLinkingBilling(true);\n setLinkBillingError(null);\n try {\n await linkBillingAccount({\n variables: {\n organizationId: activeOrgId,\n billingAccountId: selectedBillingAccountId,\n },\n refetchQueries: [\"GetMyOrganizations\"],\n });\n setShowBillingPicker(false);\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-text-secondary\">\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 (!activeOrgId) {\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 illustration=\"empty-people\"\n icon={<Building2 size={32} className=\"text-text-secondary\" />}\n title={tr(\n \"devportal.revenue.selectOrgTitle\",\n \"Select an organization\",\n )}\n description={tr(\n \"devportal.revenue.selectOrgHint\",\n \"Use the organization switcher in the nav bar above to choose which organization's revenue to view.\",\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 purpose={tr(\n \"devportal.revenue.purpose\",\n \"Revenue tracks the money your paid apps earn — gross sales, platform fees, and what gets paid out to your organization. Link a billing account, then use this to reconcile payouts and watch growth across time ranges.\",\n )}\n actions={\n <div className=\"flex flex-wrap gap-2\">\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-bg-surface 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-card border border-border-seam bg-status-info-bg-subtle p-4 flex flex-col gap-3\">\n <div className=\"flex items-start gap-3\">\n <Link2\n size={20}\n className=\"text-accent-blue flex-shrink-0 mt-0.5\"\n />\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={handleOpenBillingPicker}\n disabled={linkingBilling || billingAccountsLoading}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50 flex-shrink-0\"\n >\n {linkingBilling || billingAccountsLoading ? (\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 {/* No billing accounts message */}\n {showBillingPicker && existingBillingAccounts.length === 0 && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 ml-8 text-sm text-text-secondary\">\n {tr(\n \"devportal.revenue.noBillingAccounts\",\n \"You don't have any billing accounts yet. Create one from your account billing settings first.\",\n )}\n </div>\n )}\n\n {/* Billing account picker — shown when user has existing accounts */}\n {showBillingPicker && existingBillingAccounts.length > 0 && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 ml-8 space-y-3\">\n <p className=\"text-sm font-medium\">\n {tr(\n \"devportal.revenue.chooseBillingAccount\",\n \"Choose a billing account to link\",\n )}\n </p>\n <div className=\"space-y-2\">\n {existingBillingAccounts.map((account) => (\n <button\n key={account.id}\n type=\"button\"\n onClick={() =>\n setSelectedBillingAccountId(account.id ?? null)\n }\n className={cn(\n \"flex w-full items-center gap-3 rounded-md border px-3 py-2.5 text-sm text-left transition-colors\",\n selectedBillingAccountId === account.id\n ? \"border-primary bg-action-primary-bg/5 text-text-primary\"\n : \"border-border-subtle hover:bg-accent text-text-primary\",\n )}\n >\n <Check\n size={14}\n className={cn(\n \"flex-shrink-0\",\n selectedBillingAccountId === account.id\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium truncate\">{account.name}</p>\n {account.isDefault && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.revenue.defaultAccount\", \"Default\")}\n </p>\n )}\n </div>\n </button>\n ))}\n </div>\n <div className=\"flex items-center justify-end gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={() => {\n setShowBillingPicker(false);\n setLinkBillingError(null);\n }}\n className=\"rounded-md px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-accent transition-colors\"\n >\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n disabled={linkingBilling || !selectedBillingAccountId}\n onClick={() => void handleLinkExisting()}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50\"\n >\n {linkingBilling ? (\n <Loader2 size={13} className=\"animate-spin\" />\n ) : (\n <Link2 size={13} />\n )}\n {tr(\"devportal.revenue.confirm\", \"Confirm\")}\n </button>\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Linked billing account info — shown when billing is already linked */}\n {selectedOrganization?.billingAccountId && (\n <div className=\"mb-6 rounded-lg border border-border-subtle bg-bg-surface p-3 flex flex-col gap-3\">\n <div className=\"flex items-center gap-3\">\n <CreditCard\n size={16}\n className=\"text-text-secondary flex-shrink-0\"\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">\n {linkedBillingAccount?.name ??\n tr(\"devportal.revenue.billingAccount\", \"Billing account\")}\n </p>\n <p className=\"text-xs text-text-secondary truncate\">\n {linkedBillingAccount\n ? `${linkedBillingAccount.currency}${linkedBillingAccount.email ? ` · ${linkedBillingAccount.email}` : \"\"}`\n : selectedOrganization.billingAccountId}\n </p>\n </div>\n {!showBillingPicker && (\n <button\n type=\"button\"\n onClick={handleOpenBillingPicker}\n disabled={billingAccountsLoading}\n className=\"text-xs text-text-secondary hover:text-text-primary transition-colors flex-shrink-0 disabled:opacity-50\"\n >\n {tr(\"devportal.revenue.changeBillingAccount\", \"Change\")}\n </button>\n )}\n </div>\n {/* Picker for changing the linked account */}\n {showBillingPicker && existingBillingAccounts.length > 0 && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 space-y-3\">\n <p className=\"text-sm font-medium\">\n {tr(\n \"devportal.revenue.chooseBillingAccount\",\n \"Choose a billing account to link\",\n )}\n </p>\n <div className=\"space-y-2\">\n {existingBillingAccounts.map((account) => (\n <button\n key={account.id}\n type=\"button\"\n onClick={() =>\n setSelectedBillingAccountId(account.id ?? null)\n }\n className={cn(\n \"flex w-full items-center gap-3 rounded-md border px-3 py-2.5 text-sm text-left transition-colors\",\n selectedBillingAccountId === account.id\n ? \"border-primary bg-action-primary-bg/5 text-text-primary\"\n : \"border-border-subtle hover:bg-accent text-text-primary\",\n )}\n >\n <Check\n size={14}\n className={cn(\n \"flex-shrink-0\",\n selectedBillingAccountId === account.id\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium truncate\">{account.name}</p>\n {account.isDefault && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.revenue.defaultAccount\", \"Default\")}\n </p>\n )}\n </div>\n </button>\n ))}\n </div>\n <div className=\"flex items-center justify-end gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={() => {\n setShowBillingPicker(false);\n setLinkBillingError(null);\n }}\n className=\"rounded-md px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-accent transition-colors\"\n >\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n disabled={linkingBilling || !selectedBillingAccountId}\n onClick={() => void handleLinkExisting()}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50\"\n >\n {linkingBilling ? (\n <Loader2 size={13} className=\"animate-spin\" />\n ) : (\n <Link2 size={13} />\n )}\n {tr(\"devportal.revenue.confirm\", \"Confirm\")}\n </button>\n </div>\n {linkBillingError && (\n <p className=\"text-xs text-status-error-text\">\n {linkBillingError}\n </p>\n )}\n </div>\n )}\n </div>\n )}\n\n {loading && !summary ? (\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n ) : summary ? (\n <>\n <EmphasisPanel className=\"mb-6\">\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(\n \"devportal.revenue.pendingBalance\",\n \"Pending Balance\",\n )}\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 </EmphasisPanel>\n\n <div className=\"grid gap-6 xl:grid-cols-2\">\n <PageSection\n title={tr(\"devportal.revenue.revenueTrend\", \"Revenue trend\")}\n >\n <GlassCard treatment=\"insight\" className=\"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 </GlassCard>\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 <GlassCard\n key={application.applicationId}\n treatment=\"insight\"\n className=\"border-border-seam 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-text-secondary\">\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-text-secondary\">\n {tr(\"devportal.revenue.net\", \"Net\")} $\n {application.netRevenue.toLocaleString()}\n </p>\n </div>\n </div>\n </GlassCard>\n ),\n )}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\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 <GlassCard treatment=\"insight\" className=\"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 </GlassCard>\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 illustration=\"empty-data\"\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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"}
1
+ {"version":3,"file":"RevenueDashboardPage.js","names":[],"sources":["../../../src/devportal/pages/RevenueDashboardPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { 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 Check,\n CreditCard,\n DollarSign,\n Link2,\n Loader2,\n Wallet,\n} from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\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 useGetBillingAccountsByOrgQuery,\n useGetMyOrganizationsQuery,\n useGetRevenueDashboardDataQuery,\n useLinkDevOrgBillingAccountMutation,\n} from \"../hooks\";\nimport { cn } from \"../utils/cn\";\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 { activeOrgId, tenantId } = useDevportal();\n const [timeRange, setTimeRange] = useState<TimeRange>(\"90d\");\n const [linkingBilling, setLinkingBilling] = useState(false);\n const [linkBillingError, setLinkBillingError] = useState<string | null>(null);\n\n const [linkBillingAccount] = useLinkDevOrgBillingAccountMutation();\n const [showBillingPicker, setShowBillingPicker] = useState(false);\n const [selectedBillingAccountId, setSelectedBillingAccountId] = useState<\n string | null\n >(null);\n const [searchParams] = useSearchParams();\n const now = useMemo(() => new Date(), []);\n\n const { data: billingAccountsData, loading: billingAccountsLoading } =\n useGetBillingAccountsByOrgQuery({\n fetchPolicy: \"cache-and-network\",\n context: { headers: { \"x-org-id\": tenantId ?? \"\" } },\n });\n // searchParams kept for deep-link compatibility (URL ?org= still works via OrgSwitcher auto-select)\n void searchParams;\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: activeOrgId ?? \"\",\n period: \"monthly\",\n startDate,\n endDate: now.toISOString(),\n salesLimit: 10,\n salesOffset: 0,\n payoutsLimit: 10,\n payoutsOffset: 0,\n },\n skip: !activeOrgId,\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 const selectedOrganization = organizations.find(\n (organization) => organization.id === activeOrgId,\n );\n\n type BillingAccount = NonNullable<\n typeof billingAccountsData\n >[\"getBillingAccountsByOrg\"][number];\n const existingBillingAccounts: BillingAccount[] =\n billingAccountsData?.getBillingAccountsByOrg ?? [];\n\n const linkedBillingAccount =\n existingBillingAccounts.find(\n (a) => a.id === selectedOrganization?.billingAccountId,\n ) ?? null;\n\n const handleOpenBillingPicker = () => {\n // Pre-select the currently linked account; fall back to default or first\n setSelectedBillingAccountId(\n selectedOrganization?.billingAccountId ??\n existingBillingAccounts.find((a) => a.isDefault)?.id ??\n existingBillingAccounts[0]?.id ??\n null,\n );\n setShowBillingPicker(true);\n };\n\n const handleLinkExisting = async () => {\n if (!activeOrgId || !selectedBillingAccountId) return;\n setLinkingBilling(true);\n setLinkBillingError(null);\n try {\n await linkBillingAccount({\n variables: {\n organizationId: activeOrgId,\n billingAccountId: selectedBillingAccountId,\n },\n refetchQueries: [\"GetMyOrganizations\"],\n });\n setShowBillingPicker(false);\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-text-secondary\">\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 (!activeOrgId) {\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 illustration=\"empty-people\"\n icon={<Building2 size={32} className=\"text-text-secondary\" />}\n title={tr(\n \"devportal.revenue.selectOrgTitle\",\n \"Select an organization\",\n )}\n description={tr(\n \"devportal.revenue.selectOrgHint\",\n \"Use the organization switcher in the nav bar above to choose which organization's revenue to view.\",\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 purpose={tr(\n \"devportal.revenue.purpose\",\n \"Revenue tracks the money your paid apps earn — gross sales, platform fees, and what gets paid out to your organization. Link a billing account, then use this to reconcile payouts and watch growth across time ranges.\",\n )}\n actions={\n <div className=\"flex flex-wrap gap-2\">\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-bg-surface 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-card border border-border-seam bg-status-info-bg-subtle p-4 flex flex-col gap-3\">\n <div className=\"flex items-start gap-3\">\n <Link2\n size={20}\n className=\"text-accent-blue flex-shrink-0 mt-0.5\"\n />\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={handleOpenBillingPicker}\n disabled={linkingBilling || billingAccountsLoading}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50 flex-shrink-0\"\n >\n {linkingBilling || billingAccountsLoading ? (\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 {/* No billing accounts message */}\n {showBillingPicker && existingBillingAccounts.length === 0 && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 ml-8 text-sm text-text-secondary\">\n {tr(\n \"devportal.revenue.noBillingAccounts\",\n \"You don't have any billing accounts yet. Create one from your account billing settings first.\",\n )}\n </div>\n )}\n\n {/* Billing account picker — shown when user has existing accounts */}\n {showBillingPicker && existingBillingAccounts.length > 0 && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 ml-8 space-y-3\">\n <p className=\"text-sm font-medium\">\n {tr(\n \"devportal.revenue.chooseBillingAccount\",\n \"Choose a billing account to link\",\n )}\n </p>\n <div className=\"space-y-2\">\n {existingBillingAccounts.map((account) => (\n <button\n key={account.id}\n type=\"button\"\n onClick={() =>\n setSelectedBillingAccountId(account.id ?? null)\n }\n className={cn(\n \"flex w-full items-center gap-3 rounded-md border px-3 py-2.5 text-sm text-left transition-colors\",\n selectedBillingAccountId === account.id\n ? \"border-primary bg-action-primary-bg/5 text-text-primary\"\n : \"border-border-subtle hover:bg-accent text-text-primary\",\n )}\n >\n <Check\n size={14}\n className={cn(\n \"flex-shrink-0\",\n selectedBillingAccountId === account.id\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium truncate\">{account.name}</p>\n {account.isDefault && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.revenue.defaultAccount\", \"Default\")}\n </p>\n )}\n </div>\n </button>\n ))}\n </div>\n <div className=\"flex items-center justify-end gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={() => {\n setShowBillingPicker(false);\n setLinkBillingError(null);\n }}\n className=\"rounded-md px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-accent transition-colors\"\n >\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n disabled={linkingBilling || !selectedBillingAccountId}\n onClick={() => void handleLinkExisting()}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50\"\n >\n {linkingBilling ? (\n <Loader2 size={13} className=\"animate-spin\" />\n ) : (\n <Link2 size={13} />\n )}\n {tr(\"devportal.revenue.confirm\", \"Confirm\")}\n </button>\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Linked billing account info — shown when billing is already linked */}\n {selectedOrganization?.billingAccountId && (\n <div className=\"mb-6 rounded-lg border border-border-subtle bg-bg-surface p-3 flex flex-col gap-3\">\n <div className=\"flex items-center gap-3\">\n <CreditCard\n size={16}\n className=\"text-text-secondary flex-shrink-0\"\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">\n {linkedBillingAccount?.name ??\n tr(\"devportal.revenue.billingAccount\", \"Billing account\")}\n </p>\n <p className=\"text-xs text-text-secondary truncate\">\n {linkedBillingAccount\n ? `${linkedBillingAccount.currency}${linkedBillingAccount.email ? ` · ${linkedBillingAccount.email}` : \"\"}`\n : selectedOrganization.billingAccountId}\n </p>\n </div>\n {!showBillingPicker && (\n <button\n type=\"button\"\n onClick={handleOpenBillingPicker}\n disabled={billingAccountsLoading}\n className=\"text-xs text-text-secondary hover:text-text-primary transition-colors flex-shrink-0 disabled:opacity-50\"\n >\n {tr(\"devportal.revenue.changeBillingAccount\", \"Change\")}\n </button>\n )}\n </div>\n {/* Picker for changing the linked account */}\n {showBillingPicker && existingBillingAccounts.length > 0 && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 space-y-3\">\n <p className=\"text-sm font-medium\">\n {tr(\n \"devportal.revenue.chooseBillingAccount\",\n \"Choose a billing account to link\",\n )}\n </p>\n <div className=\"space-y-2\">\n {existingBillingAccounts.map((account) => (\n <button\n key={account.id}\n type=\"button\"\n onClick={() =>\n setSelectedBillingAccountId(account.id ?? null)\n }\n className={cn(\n \"flex w-full items-center gap-3 rounded-md border px-3 py-2.5 text-sm text-left transition-colors\",\n selectedBillingAccountId === account.id\n ? \"border-primary bg-action-primary-bg/5 text-text-primary\"\n : \"border-border-subtle hover:bg-accent text-text-primary\",\n )}\n >\n <Check\n size={14}\n className={cn(\n \"flex-shrink-0\",\n selectedBillingAccountId === account.id\n ? \"opacity-100 text-primary\"\n : \"opacity-0\",\n )}\n />\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium truncate\">{account.name}</p>\n {account.isDefault && (\n <p className=\"text-xs text-text-secondary\">\n {tr(\"devportal.revenue.defaultAccount\", \"Default\")}\n </p>\n )}\n </div>\n </button>\n ))}\n </div>\n <div className=\"flex items-center justify-end gap-2 pt-1\">\n <button\n type=\"button\"\n onClick={() => {\n setShowBillingPicker(false);\n setLinkBillingError(null);\n }}\n className=\"rounded-md px-3 py-1.5 text-xs font-medium text-text-secondary hover:bg-accent transition-colors\"\n >\n {tr(\"devportal.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n disabled={linkingBilling || !selectedBillingAccountId}\n onClick={() => void handleLinkExisting()}\n className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors disabled:opacity-50\"\n >\n {linkingBilling ? (\n <Loader2 size={13} className=\"animate-spin\" />\n ) : (\n <Link2 size={13} />\n )}\n {tr(\"devportal.revenue.confirm\", \"Confirm\")}\n </button>\n </div>\n {linkBillingError && (\n <p className=\"text-xs text-status-error-text\">\n {linkBillingError}\n </p>\n )}\n </div>\n )}\n </div>\n )}\n\n {loading && !summary ? (\n <div className=\"flex items-center justify-center py-16 text-text-secondary\">\n <Loader2 className=\"h-8 w-8 animate-spin\" />\n </div>\n ) : summary ? (\n <>\n <EmphasisPanel className=\"mb-6\">\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(\n \"devportal.revenue.pendingBalance\",\n \"Pending Balance\",\n )}\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 </EmphasisPanel>\n\n <div className=\"grid gap-6 xl:grid-cols-2\">\n <PageSection\n title={tr(\"devportal.revenue.revenueTrend\", \"Revenue trend\")}\n >\n <GlassCard treatment=\"insight\" className=\"p-4\">\n {chartData.length > 0 ? (\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 ) : (\n <div className=\"flex h-[300px] flex-col items-center justify-center gap-2 text-text-secondary\">\n <p className=\"text-sm font-medium\">\n {tr(\"devportal.revenue.noTrendData\", \"No trend data yet\")}\n </p>\n <p className=\"text-xs text-text-tertiary\">\n {tr(\n \"devportal.revenue.noTrendDataHint\",\n \"Revenue trend appears once daily analytics have been aggregated.\",\n )}\n </p>\n </div>\n )}\n </GlassCard>\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 <GlassCard\n key={application.applicationId}\n treatment=\"insight\"\n className=\"border-border-seam 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-text-secondary\">\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-text-secondary\">\n {tr(\"devportal.revenue.net\", \"Net\")} $\n {application.netRevenue.toLocaleString()}\n </p>\n </div>\n </div>\n </GlassCard>\n ),\n )}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-data\"\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 <GlassCard treatment=\"insight\" className=\"p-4\">\n {chartData.length > 0 ? (\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 ) : (\n <div className=\"flex h-[280px] flex-col items-center justify-center gap-2 text-text-secondary\">\n <p className=\"text-sm font-medium\">\n {tr(\n \"devportal.revenue.noVolumeData\",\n \"No sales volume data yet\",\n )}\n </p>\n <p className=\"text-xs text-text-tertiary\">\n {tr(\n \"devportal.revenue.noVolumeDataHint\",\n \"Sales volume by period appears once analytics have been aggregated.\",\n )}\n </p>\n </div>\n )}\n </GlassCard>\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 illustration=\"empty-data\"\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":";;;;;;;;;;;;;;;;;;;;;;;;;;AA+CA,IAAM,IAAc;CAClB,SAAS;CACT,WAAW;CACX,UAAU;CACX,EAOK,KAAyC;CAC7C,OAAO;CACP,OAAO;CACP,OAAO;CACR,EAEY,UAAiC;CAC5C,IAAM,IAAK,IAAO,EACZ,EAAE,gBAAa,iBAAa,GAAc,EAC1C,CAAC,GAAW,MAAgB,EAAoB,MAAM,EACtD,CAAC,GAAgB,KAAqB,EAAS,GAAM,EACrD,CAAC,GAAkB,KAAuB,EAAwB,KAAK,EAEvE,CAAC,MAAsB,IAAqC,EAC5D,CAAC,GAAmB,KAAwB,EAAS,GAAM,EAC3D,CAAC,GAA0B,KAA+B,EAE9D,KAAK,EACD,CAAC,MAAgB,GAAiB,EAClC,IAAM,wBAAc,IAAI,MAAM,EAAE,EAAE,CAAC,EAEnC,EAAE,MAAM,IAAqB,SAAS,MAC1C,GAAgC;EAC9B,aAAa;EACb,SAAS,EAAE,SAAS,EAAE,YAAY,MAAY,IAAI,EAAE;EACrD,CAAC,EAGE,KAAY,QAAc;EAC9B,IAAM,IAAW,IAAI,KAAK,EAAI;AAE9B,SADA,EAAS,QAAQ,EAAS,SAAS,GAAG,GAAY,GAAW,EACtD,EAAS,aAAa;IAC5B,CAAC,GAAK,EAAU,CAAC,EAEd,EACJ,MAAM,GACN,SAAS,IACT,OAAO,MACL,GAA2B,EAC7B,aAAa,qBACd,CAAC,EACI,EAAE,SAAM,aAAS,aAAU,GAAgC;EAC/D,WAAW;GACT,gBAAgB,KAAe;GAC/B,QAAQ;GACR;GACA,SAAS,EAAI,aAAa;GAC1B,YAAY;GACZ,aAAa;GACb,cAAc;GACd,eAAe;GAChB;EACD,MAAM,CAAC;EACP,aAAa;EACd,CAAC,EAYI,IAVyC,QAE3C,GAAmB,0BAA0B,KAEzC,MACG,EACN,IAAI,EAAE,EACT,CAAC,GAAmB,yBAAyB,CAC9C,CAE0C,MACxC,MAAiB,EAAa,OAAO,EACvC,EAKK,IACJ,IAAqB,2BAA2B,EAAE,EAE9C,IACJ,EAAwB,MACrB,MAAM,EAAE,OAAO,GAAsB,iBACvC,IAAI,MAED,UAAgC;AAQpC,EANA,EACE,GAAsB,oBACpB,EAAwB,MAAM,MAAM,EAAE,UAAU,EAAE,MAClD,EAAwB,IAAI,MAC5B,KACH,EACD,EAAqB,GAAK;IAGtB,IAAqB,YAAY;AACjC,SAAC,KAAe,CAAC,IAErB;GADA,EAAkB,GAAK,EACvB,EAAoB,KAAK;AACzB,OAAI;AAQF,IAPA,MAAM,GAAmB;KACvB,WAAW;MACT,gBAAgB;MAChB,kBAAkB;MACnB;KACD,gBAAgB,CAAC,qBAAqB;KACvC,CAAC,EACF,EAAqB,GAAM;YACpB,GAAK;AACZ,MACE,aAAe,QAAQ,EAAI,UAAU,iCACtC;aACO;AACR,MAAkB,GAAM;;;IAItB,IAAU,GAAM,4BAChB,KAAY,CAAC,GAAI,GAAM,gCAAgC,EAAE,CAAE,CAAC,MAC/D,GAAM,MACL,IAAI,KAAK,EAAK,KAAK,CAAC,SAAS,GAAG,IAAI,KAAK,EAAM,KAAK,CAAC,SAAS,CACjE,EACK,KACJ,GAAM,mBAAmB,OAAO,KAE5B,MACG,EAAK,KACX,IAAI,EAAE,EACH,KACJ,GAAM,qBAAqB,OAAO,KAE9B,MACG,EAAK,KACX,IAAI,EAAE,EAEH,IAAY,GAAU,KAAK,OAAW;EAC1C,MAAM,IAAI,KAAK,EAAM,KAAK,CAAC,mBAAmB,KAAA,GAAW;GACvD,OAAO;GACP,KAAK;GACN,CAAC;EACF,cAAc,EAAM;EACpB,YAAY,EAAM;EAClB,cAAc,EAAM;EACpB,SAAS,EAAM;EACf,YAAY,EAAM;EACnB,EAAE;AAqFH,QAnFI,MAAwB,CAAC,IAEzB,kBAAC,GAAD;EACE,OAAO,EAAG,2BAA2B,UAAU;EAC/C,aAAa,EACX,iCACA,kFACD;YAED,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA;GACxC,CAAA;EACK,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAO,EAAG,2BAA2B,UAAU;EAC/C,aAAa,EACX,iCACA,kFACD;YAED,kBAAC,GAAD;GACE,MAAM,kBAAC,GAAD;IAAa,MAAM;IAAI,WAAU;IAA2B,CAAA;GAClE,OAAO,EACL,mCACA,+BACD;GACD,aAAa,EAAgB,EAAmB;GAChD,CAAA;EACS,CAAA,GAIZ,IAyBD,IAEA,kBAAC,GAAD;EACE,OAAO,EAAG,2BAA2B,UAAU;EAC/C,aAAa,EACX,iCACA,kFACD;YAED,kBAAC,GAAD;GACE,MAAM,kBAAC,GAAD;IAAa,MAAM;IAAI,WAAU;IAA2B,CAAA;GAClE,OAAO,EACL,mCACA,8BACD;GACD,aAAa,EAAgB,EAAM;GACnC,CAAA;EACS,CAAA,GAKf,kBAAC,GAAD;EACE,OAAO,EAAG,2BAA2B,UAAU;EAC/C,aACE,IACI,GAAG,EAAG,6CAA6C,4BAA4B,CAAC,GAAG,EAAqB,SACxG,EACE,sCACA,oCACD;EAEP,SAAS,EACP,6BACA,0NACD;EACD,SACE,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,UAAD;IACE,OAAO;IACP,WAAW,MAAU,GAAa,EAAM,OAAO,MAAmB;IAClE,cAAY,EACV,qCACA,oBACD;IACD,WAAU;cAPZ;KASE,kBAAC,UAAD;MAAQ,OAAM;gBACX,EAAG,+BAA+B,eAAe;MAC3C,CAAA;KACT,kBAAC,UAAD;MAAQ,OAAM;gBACX,EAAG,+BAA+B,eAAe;MAC3C,CAAA;KACT,kBAAC,UAAD;MAAQ,OAAM;gBACX,EAAG,+BAA+B,iBAAiB;MAC7C,CAAA;KACF;;GACL,CAAA;YAnCV;GAuCG,KAAwB,CAAC,EAAqB,oBAC7C,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QACE,MAAM;QACN,WAAU;QACV,CAAA;OACF,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,KAAD;UAAG,WAAU;oBACV,EACC,2CACA,kDACD;UACC,CAAA;SACJ,kBAAC,KAAD;UAAG,WAAU;oBACV,EACC,0CACA,mJACD;UACC,CAAA;SACH,KACC,kBAAC,KAAD;UAAG,WAAU;oBACV;UACC,CAAA;SAEF;;OACN,kBAAC,UAAD;QACE,MAAK;QACL,SAAS;QACT,UAAU,KAAkB;QAC5B,WAAU;kBAJZ,CAMG,KAAkB,IACjB,kBAAC,GAAD;SAAS,MAAM;SAAI,WAAU;SAAiB,CAAA,GAE9C,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAEpB,IACG,EAAG,6BAA6B,aAAa,GAC7C,EACE,wCACA,uBACD,CACE;;OACL;;KAGL,KAAqB,EAAwB,WAAW,KACvD,kBAAC,OAAD;MAAK,WAAU;gBACZ,EACC,uCACA,gGACD;MACG,CAAA;KAIP,KAAqB,EAAwB,SAAS,KACrD,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EACC,0CACA,mCACD;QACC,CAAA;OACJ,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAwB,KAAK,MAC5B,kBAAC,UAAD;SAEE,MAAK;SACL,eACE,EAA4B,EAAQ,MAAM,KAAK;SAEjD,WAAW,EACT,oGACA,MAA6B,EAAQ,KACjC,4DACA,yDACL;mBAXH,CAaE,kBAAC,GAAD;UACE,MAAM;UACN,WAAW,EACT,iBACA,MAA6B,EAAQ,KACjC,6BACA,YACL;UACD,CAAA,EACF,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,KAAD;WAAG,WAAU;qBAAwB,EAAQ;WAAS,CAAA,EACrD,EAAQ,aACP,kBAAC,KAAD;WAAG,WAAU;qBACV,EAAG,oCAAoC,UAAU;WAChD,CAAA,CAEF;YACC;WA7BF,EAAQ,GA6BN,CACT;QACE,CAAA;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,MAAK;SACL,eAAe;AAEb,UADA,EAAqB,GAAM,EAC3B,EAAoB,KAAK;;SAE3B,WAAU;mBAET,EAAG,oBAAoB,SAAS;SAC1B,CAAA,EACT,kBAAC,UAAD;SACE,MAAK;SACL,UAAU,KAAkB,CAAC;SAC7B,eAAe,KAAK,GAAoB;SACxC,WAAU;mBAJZ,CAMG,IACC,kBAAC,GAAD;UAAS,MAAM;UAAI,WAAU;UAAiB,CAAA,GAE9C,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAEpB,EAAG,6BAA6B,UAAU,CACpC;WACL;;OACF;;KAEJ;;GAIP,GAAsB,oBACrB,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OACE,MAAM;OACN,WAAU;OACV,CAAA;MACF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,GAAsB,QACrB,EAAG,oCAAoC,kBAAkB;QACzD,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,IACG,GAAG,EAAqB,WAAW,EAAqB,QAAQ,MAAM,EAAqB,UAAU,OACrG,EAAqB;QACvB,CAAA,CACA;;MACL,CAAC,KACA,kBAAC,UAAD;OACE,MAAK;OACL,SAAS;OACT,UAAU;OACV,WAAU;iBAET,EAAG,0CAA0C,SAAS;OAChD,CAAA;MAEP;QAEL,KAAqB,EAAwB,SAAS,KACrD,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EACC,0CACA,mCACD;OACC,CAAA;MACJ,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAwB,KAAK,MAC5B,kBAAC,UAAD;QAEE,MAAK;QACL,eACE,EAA4B,EAAQ,MAAM,KAAK;QAEjD,WAAW,EACT,oGACA,MAA6B,EAAQ,KACjC,4DACA,yDACL;kBAXH,CAaE,kBAAC,GAAD;SACE,MAAM;SACN,WAAW,EACT,iBACA,MAA6B,EAAQ,KACjC,6BACA,YACL;SACD,CAAA,EACF,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,KAAD;UAAG,WAAU;oBAAwB,EAAQ;UAAS,CAAA,EACrD,EAAQ,aACP,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAG,oCAAoC,UAAU;UAChD,CAAA,CAEF;WACC;UA7BF,EAAQ,GA6BN,CACT;OACE,CAAA;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,UAAD;QACE,MAAK;QACL,eAAe;AAEb,SADA,EAAqB,GAAM,EAC3B,EAAoB,KAAK;;QAE3B,WAAU;kBAET,EAAG,oBAAoB,SAAS;QAC1B,CAAA,EACT,kBAAC,UAAD;QACE,MAAK;QACL,UAAU,KAAkB,CAAC;QAC7B,eAAe,KAAK,GAAoB;QACxC,WAAU;kBAJZ,CAMG,IACC,kBAAC,GAAD;SAAS,MAAM;SAAI,WAAU;SAAiB,CAAA,GAE9C,kBAAC,GAAD,EAAO,MAAM,IAAM,CAAA,EAEpB,EAAG,6BAA6B,UAAU,CACpC;UACL;;MACL,KACC,kBAAC,KAAD;OAAG,WAAU;iBACV;OACC,CAAA;MAEF;OAEJ;;GAGP,MAAW,CAAC,IACX,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA;IACxC,CAAA,GACJ,IACF,kBAAA,IAAA,EAAA,UAAA;IACE,kBAAC,IAAD;KAAe,WAAU;eACvB,kBAAC,IAAD;MAAc,SAAS;gBAAvB;OACE,kBAAC,GAAD;QACE,OAAO,EAAG,kCAAkC,gBAAgB;QAC5D,OAAO,IAAI,EAAQ,kBAAkB,gBAAgB;QACrD,MAAM,kBAAC,GAAD,EAAY,MAAM,IAAM,CAAA;QAC9B,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAG,gCAAgC,cAAc;QACxD,OAAO,IAAI,EAAQ,gBAAgB,gBAAgB;QACnD,MAAM,kBAAC,IAAD,EAAQ,MAAM,IAAM,CAAA;QAC1B,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EACL,oCACA,kBACD;QACD,OAAO,IAAI,EAAQ,eAAe,gBAAgB;QAClD,MAAM,kBAAC,GAAD,EAAY,MAAM,IAAM,CAAA;QAC9B,aACE,EAAQ,iBACJ,GAAG,EAAG,gCAAgC,cAAc,CAAC,GAAG,IAAI,KAAK,EAAQ,eAAe,CAAC,oBAAoB,KAC7G,EACE,uCACA,sBACD;QAEP,CAAA;OACF,kBAAC,GAAD;QACE,OAAO,EAAG,kCAAkC,gBAAgB;QAC5D,OAAO,IAAI,EAAQ,kBAAkB,gBAAgB;QACrD,MAAM,kBAAC,IAAD,EAAiB,MAAM,IAAM,CAAA;QACnC,aAAa,GAAG,EAAQ,kBAAkB,GAAG,EAAG,6BAA6B,UAAU;QACvF,CAAA;OACW;;KACD,CAAA;IAEhB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,OAAO,EAAG,kCAAkC,gBAAgB;gBAE5D,kBAAC,GAAD;OAAW,WAAU;OAAU,WAAU;iBACtC,EAAU,SAAS,IAClB,kBAAC,GAAD;QAAqB,OAAM;QAAO,QAAQ;kBACxC,kBAAC,GAAD;SAAW,MAAM;mBAAjB;UACE,kBAAC,GAAD;WACE,iBAAgB;WAChB,QAAO;WACP,CAAA;UACF,kBAAC,GAAD;WACE,SAAQ;WACR,QAAO;WACP,UAAU;WACV,CAAA;UACF,kBAAC,GAAD;WAAO,QAAO;WAA0B,UAAU;WAAM,CAAA;UACxD,kBAAC,GAAD,EACE,cAAc;WACZ,iBAAiB;WACjB,QAAQ;WACR,cAAc;WACf,EACD,CAAA;UACF,kBAAC,GAAD;WACE,MAAK;WACL,SAAQ;WACR,QAAQ,EAAY;WACpB,aAAa;WACb,KAAK;WACL,CAAA;UACF,kBAAC,GAAD;WACE,MAAK;WACL,SAAQ;WACR,QAAQ,EAAY;WACpB,aAAa;WACb,KAAK;WACL,CAAA;UACQ;;QACQ,CAAA,GAEtB,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,iCAAiC,oBAAoB;SACvD,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,EACC,qCACA,mEACD;SACC,CAAA,CACA;;OAEE,CAAA;MACA,CAAA,EAEd,kBAAC,GAAD;MACE,OAAO,EACL,6BACA,8BACD;gBAEA,EAAQ,QAAQ,SAAS,IACxB,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAQ,QAAQ,KAEb,MAEA,kBAAC,GAAD;QAEE,WAAU;QACV,WAAU;kBAEV,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;UAAG,WAAU;oBACV,EAAY;UACX,CAAA,EACJ,kBAAC,KAAD;UAAG,WAAU;oBAAb;WACG,EAAY;WAAY;WACxB,EAAG,2BAA2B,QAAQ;WACrC;YACA,EAAA,CAAA,EACN,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,KAAD;WAAG,WAAU;qBAAb,CAA6B,KACzB,EAAY,aAAa,gBAAgB,CACzC;cACJ,kBAAC,KAAD;WAAG,WAAU;qBAAb;YACG,EAAG,yBAAyB,MAAM;YAAC;YACnC,EAAY,WAAW,gBAAgB;YACtC;aACA;YACF;;QACI,EAxBL,EAAY,cAwBP,CAEf;OACG,CAAA,GAEN,kBAAC,GAAD;OACE,cAAa;OACb,MAAM,kBAAC,GAAD,EAAW,MAAM,IAAM,CAAA;OAC7B,OAAO,EACL,oCACA,yBACD;OACD,aAAa,EACX,0CACA,yEACD;OACD,CAAA;MAEQ,CAAA,CACV;;IAEN,kBAAC,GAAD;KACE,OAAO,EAAG,iCAAiC,eAAe;eAE1D,kBAAC,GAAD;MAAW,WAAU;MAAU,WAAU;gBACtC,EAAU,SAAS,IAClB,kBAAC,GAAD;OAAqB,OAAM;OAAO,QAAQ;iBACxC,kBAAC,IAAD;QAAU,MAAM;kBAAhB;SACE,kBAAC,GAAD;UACE,iBAAgB;UAChB,QAAO;UACP,CAAA;SACF,kBAAC,GAAD;UACE,SAAQ;UACR,QAAO;UACP,UAAU;UACV,CAAA;SACF,kBAAC,GAAD;UAAO,QAAO;UAA0B,UAAU;UAAM,CAAA;SACxD,kBAAC,GAAD,EACE,cAAc;UACZ,iBAAiB;UACjB,QAAQ;UACR,cAAc;UACf,EACD,CAAA;SACF,kBAAC,IAAD;UACE,SAAQ;UACR,MAAM,EAAY;UAClB,QAAQ;WAAC;WAAG;WAAG;WAAG;WAAE;UACpB,CAAA;SACO;;OACS,CAAA,GAEtB,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EACC,kCACA,2BACD;QACC,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,EACC,sCACA,sEACD;QACC,CAAA,CACA;;MAEE,CAAA;KACA,CAAA;IAEd,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,OAAO,EAAG,iCAAiC,eAAe;gBAE1D,kBAAC,GAAD;OACE,MAAM;OACN,UAAS;OACT,SAAS;QACP;SACE,KAAK;SACL,QAAQ,EAAG,iCAAiC,cAAc;SAC1D,SAAS,MACP,EAAK,aAAa,QAClB,EAAK,YACL,EAAG,4BAA4B,UAAU;SAC5C;QACD;SACE,KAAK;SACL,QAAQ,EAAG,2BAA2B,QAAQ;SAC9C,SAAS,MAAS,IAAI,EAAK,YAAY,gBAAgB;SACxD;QACD;SACE,KAAK;SACL,QAAQ,EAAG,yBAAyB,MAAM;SAC1C,SAAS,MAAS,IAAI,EAAK,UAAU,gBAAgB;SACtD;QACD;SACE,KAAK;SACL,QAAQ,EAAG,4BAA4B,SAAS;SAChD,SAAS,MACP,kBAAC,GAAD;UAAa,QAAQ,EAAK;UAAQ,MAAK;UAAQ,CAAA;SAElD;QACF;OACD,CAAA;MACU,CAAA,EAEd,kBAAC,GAAD;MACE,OAAO,EAAG,mCAAmC,iBAAiB;gBAE9D,kBAAC,GAAD;OACE,MAAM;OACN,UAAS;OACT,SAAS;QACP;SACE,KAAK;SACL,QAAQ,EAAG,4BAA4B,SAAS;SAChD,SAAS,MAAW,EAAO;SAC5B;QACD;SACE,KAAK;SACL,QAAQ,EAAG,+BAA+B,aAAa;SACvD,SAAS,MAAW,IAAI,EAAO,UAAU,gBAAgB;SAC1D;QACD;SACE,KAAK;SACL,QAAQ,EAAG,4BAA4B,SAAS;SAChD,SAAS,MACP,kBAAC,GAAD;UAAa,QAAQ,EAAO;UAAQ,MAAK;UAAQ,CAAA;SAEpD;QACF;OACD,CAAA;MACU,CAAA,CACV;;IACL,EAAA,CAAA,GAEH,kBAAC,GAAD;IACE,cAAa;IACb,MAAM,kBAAC,GAAD,EAAY,MAAM,IAAM,CAAA;IAC9B,OAAO,EAAG,iCAAiC,sBAAsB;IACjE,aAAa,EACX,uCACA,0FACD;IACD,CAAA;GAEO;MAhmBX,kBAAC,GAAD;EACE,OAAO,EAAG,2BAA2B,UAAU;EAC/C,aAAa,EACX,iCACA,kFACD;YAED,kBAAC,GAAD;GACE,cAAa;GACb,MAAM,kBAAC,GAAD;IAAW,MAAM;IAAI,WAAU;IAAwB,CAAA;GAC7D,OAAO,EACL,oCACA,yBACD;GACD,aAAa,EACX,mCACA,qGACD;GACD,CAAA;EACS,CAAA"}