@burdenoff/microfe-billing 2026.915.3 → 2026.916.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.
@@ -2,21 +2,21 @@ import { useBilling as e } from "../../../providers/BillingProvider.js";
2
2
  import { AccessDenied as t } from "../../../shared/components/AccessDenied.js";
3
3
  import { PageHeader as n } from "../../../shared/components/PageHeader.js";
4
4
  import { StatCard as r } from "../../../shared/components/StatCard.js";
5
- import { ServerError as i } from "../../../shared/components/ServerError.js";
5
+ import { ServerError as ee } from "../../../shared/components/ServerError.js";
6
6
  import "../../../shared/components/index.js";
7
- import { formatCurrency as a, formatDateTime as o } from "../../../shared/utils/format.js";
8
- import { isServerError as s } from "../../../shared/utils/error.js";
7
+ import { formatCurrency as i, formatDateTime as a } from "../../../shared/utils/format.js";
8
+ import { isServerError as o } from "../../../shared/utils/error.js";
9
9
  import "../../../shared/utils/index.js";
10
- import { useBillingPermissions as c } from "../../../hooks/useBillingPermissions.js";
11
- import { useGetDefaultBillingAccountSettingsQuery as l } from "../../../../generated/global-operations.js";
12
- import { fetchDeveloperPortalRevenueDashboard as u, fetchEarningsEntries as d, fetchEarningsSummary as f } from "../api.js";
13
- import { useCallback as p, useEffect as m, useMemo as h, useState as g } from "react";
14
- import { Coins as _, HandCoins as v, RefreshCw as y, Wallet as b } from "lucide-react";
15
- import { useSearchParams as x } from "react-router";
16
- import { jsx as S, jsxs as C } from "react/jsx-runtime";
17
- import { EmphasisPanel as w, IllustratedEmptyState as T, PagePurpose as E, ResponsiveTable as D } from "@burdenoff/fe-libs/ui";
10
+ import { useBillingPermissions as s } from "../../../hooks/useBillingPermissions.js";
11
+ import { useGetDefaultBillingAccountSettingsQuery as te } from "../../../../generated/global-operations.js";
12
+ import { fetchDeveloperPortalRevenueDashboard as c, fetchEarningsEntries as l, fetchEarningsSummary as u } from "../api.js";
13
+ import { useCallback as d, useEffect as f, useMemo as ne, useState as p } from "react";
14
+ import { ArrowLeft as m, Coins as h, HandCoins as g, RefreshCw as _, Wallet as v } from "lucide-react";
15
+ import { useSearchParams as re } from "react-router";
16
+ import { jsx as y, jsxs as b } from "react/jsx-runtime";
17
+ import { EmphasisPanel as x, IllustratedEmptyState as S, PagePurpose as C, ResponsiveTable as w } from "@burdenoff/fe-libs/ui";
18
18
  //#region src/billing/modules/earnings/pages/EarningsPage.tsx
19
- var ee = [
19
+ var T = [
20
20
  {
21
21
  key: "application",
22
22
  header: "Application",
@@ -31,17 +31,17 @@ var ee = [
31
31
  {
32
32
  key: "gross",
33
33
  header: "Gross",
34
- cell: (e) => /* @__PURE__ */ S("span", {
34
+ cell: (e) => /* @__PURE__ */ y("span", {
35
35
  className: "tabular-nums",
36
- children: a(e.grossAmount, e.currency || "USD")
36
+ children: i(e.grossAmount, e.currency || "USD")
37
37
  })
38
38
  },
39
39
  {
40
40
  key: "net",
41
41
  header: "Net",
42
- cell: (e) => /* @__PURE__ */ S("span", {
42
+ cell: (e) => /* @__PURE__ */ y("span", {
43
43
  className: "tabular-nums",
44
- children: a(e.netAmount, e.currency || "USD")
44
+ children: i(e.netAmount, e.currency || "USD")
45
45
  })
46
46
  },
47
47
  {
@@ -52,9 +52,9 @@ var ee = [
52
52
  {
53
53
  key: "purchased",
54
54
  header: "Purchased",
55
- cell: (e) => o(e.purchasedAt)
55
+ cell: (e) => a(e.purchasedAt)
56
56
  }
57
- ], O = [
57
+ ], ie = [
58
58
  {
59
59
  key: "period",
60
60
  header: "Period",
@@ -64,9 +64,9 @@ var ee = [
64
64
  {
65
65
  key: "amount",
66
66
  header: "Amount",
67
- cell: (e) => /* @__PURE__ */ S("span", {
67
+ cell: (e) => /* @__PURE__ */ y("span", {
68
68
  className: "tabular-nums",
69
- children: a(e.netAmount, e.currency || "USD")
69
+ children: i(e.netAmount, e.currency || "USD")
70
70
  })
71
71
  },
72
72
  {
@@ -77,14 +77,14 @@ var ee = [
77
77
  {
78
78
  key: "scheduled",
79
79
  header: "Scheduled",
80
- cell: (e) => e.scheduledAt ? o(e.scheduledAt) : "-"
80
+ cell: (e) => e.scheduledAt ? a(e.scheduledAt) : "-"
81
81
  },
82
82
  {
83
83
  key: "completed",
84
84
  header: "Completed",
85
- cell: (e) => e.completedAt ? o(e.completedAt) : "-"
85
+ cell: (e) => e.completedAt ? a(e.completedAt) : "-"
86
86
  }
87
- ], k = [
87
+ ], ae = [
88
88
  {
89
89
  key: "category",
90
90
  header: "Category",
@@ -104,9 +104,9 @@ var ee = [
104
104
  {
105
105
  key: "amount",
106
106
  header: "Amount",
107
- cell: (e) => /* @__PURE__ */ S("span", {
107
+ cell: (e) => /* @__PURE__ */ y("span", {
108
108
  className: "tabular-nums",
109
- children: e.unitType === "CREDITS" ? `${e.amount.toLocaleString()} credits` : a(e.amount, e.currency || "USD")
109
+ children: e.unitType === "CREDITS" ? `${e.amount.toLocaleString()} credits` : i(e.amount, e.currency || "USD")
110
110
  })
111
111
  },
112
112
  {
@@ -117,29 +117,29 @@ var ee = [
117
117
  {
118
118
  key: "created",
119
119
  header: "Created",
120
- cell: (e) => o(e.createdAt)
120
+ cell: (e) => a(e.createdAt)
121
121
  }
122
- ], A = () => {
123
- let [o] = x(), A = c(), { apiGatewayUrl: j, authToken: M, orgId: N } = e(), P = o.get("developerOrgId"), F = o.get("developerOrgName"), { data: te, loading: ne } = l({}), I = te?.getDefaultBillingAccount?.id, [L, R] = g(null), [z, B] = g([]), [V, H] = g(null), [U, W] = g("ALL"), [G, K] = g(!0), [q, J] = g(null), Y = h(() => ({
124
- apiGatewayUrl: j,
125
- authToken: M,
126
- orgId: N
122
+ ], E = () => {
123
+ let [a] = re(), E = s(), { apiGatewayUrl: D, authToken: O, orgId: k, navigate: A } = e(), j = a.get("developerOrgId"), M = a.get("developerOrgName"), N = a.get("returnTo"), { data: P, loading: F } = te({}), I = P?.getDefaultBillingAccount?.id, [L, R] = p(null), [z, B] = p([]), [V, H] = p(null), [U, W] = p("ALL"), [G, K] = p(!0), [q, J] = p(null), Y = ne(() => ({
124
+ apiGatewayUrl: D,
125
+ authToken: O,
126
+ orgId: k
127
127
  }), [
128
- j,
129
- M,
130
- N
131
- ]), X = p(async () => {
128
+ D,
129
+ O,
130
+ k
131
+ ]), X = d(async () => {
132
132
  K(!0), J(null);
133
133
  try {
134
- if (P) {
135
- H(await u(P, Y)), R(null), B([]);
134
+ if (j) {
135
+ H(await c(j, Y)), R(null), B([]);
136
136
  return;
137
137
  }
138
138
  if (!I) {
139
139
  R(null), B([]), H(null);
140
140
  return;
141
141
  }
142
- let [e, t] = await Promise.all([f(I, Y), d(I, Y)]);
142
+ let [e, t] = await Promise.all([u(I, Y), l(I, Y)]);
143
143
  R(e), B(t), H(null);
144
144
  } catch (e) {
145
145
  J(e instanceof Error ? e : /* @__PURE__ */ Error("Failed to load earnings"));
@@ -148,166 +148,172 @@ var ee = [
148
148
  }
149
149
  }, [
150
150
  I,
151
- P,
151
+ j,
152
152
  Y
153
153
  ]);
154
- if (m(() => {
154
+ if (f(() => {
155
155
  X();
156
- }, [X]), !A.canViewBillingAccount) return /* @__PURE__ */ S(t, { message: "You don't have permission to view earnings." });
157
- if (!P && !I && !ne) return /* @__PURE__ */ S(T, {
156
+ }, [X]), !E.canViewBillingAccount) return /* @__PURE__ */ y(t, { message: "You don't have permission to view earnings." });
157
+ if (!j && !I && !F) return /* @__PURE__ */ y(S, {
158
158
  illustration: "empty-generic",
159
159
  title: "No billing account found",
160
160
  description: "Create a billing account first to view earnings."
161
161
  });
162
- if (q && s(q)) return /* @__PURE__ */ S(i, {
162
+ if (q && o(q)) return /* @__PURE__ */ y(ee, {
163
163
  title: "Earnings unavailable",
164
164
  message: q.message,
165
165
  onRetry: () => void X(),
166
166
  showRetry: !0
167
167
  });
168
- let re = L ? [
168
+ let oe = L ? [
169
169
  {
170
170
  title: "Available",
171
- value: a(L.availableAmount, "USD"),
172
- icon: /* @__PURE__ */ S(v, { className: "size-5" })
171
+ value: i(L.availableAmount, "USD"),
172
+ icon: /* @__PURE__ */ y(g, { className: "size-5" })
173
173
  },
174
174
  {
175
175
  title: "Reserved",
176
- value: a(L.reservedAmount, "USD"),
177
- icon: /* @__PURE__ */ S(_, { className: "size-5" })
176
+ value: i(L.reservedAmount, "USD"),
177
+ icon: /* @__PURE__ */ y(h, { className: "size-5" })
178
178
  },
179
179
  {
180
180
  title: "Paid out",
181
- value: a(L.paidAmount, "USD"),
182
- icon: /* @__PURE__ */ S(b, { className: "size-5" })
181
+ value: i(L.paidAmount, "USD"),
182
+ icon: /* @__PURE__ */ y(v, { className: "size-5" })
183
183
  },
184
184
  {
185
185
  title: "Lifetime",
186
- value: a(L.totalLifetimeAmount, "USD"),
187
- icon: /* @__PURE__ */ S(y, { className: "size-5" })
186
+ value: i(L.totalLifetimeAmount, "USD"),
187
+ icon: /* @__PURE__ */ y(_, { className: "size-5" })
188
188
  }
189
189
  ] : [], Z = U === "ALL" ? z : z.filter((e) => e.sourceCategory === U), Q = L?.categoryBreakdown?.map((e) => ({
190
190
  title: `${e.category} earnings`,
191
- value: a(e.amount, "USD"),
191
+ value: i(e.amount, "USD"),
192
192
  helperText: `${e.count} entries`
193
- })) ?? [], ie = V?.summary ? [
193
+ })) ?? [], se = V?.summary ? [
194
194
  {
195
195
  title: "Gross revenue",
196
- value: a(V.summary.totalGrossRevenue, V.summary.currency),
197
- icon: /* @__PURE__ */ S(v, { className: "size-5" })
196
+ value: i(V.summary.totalGrossRevenue, V.summary.currency),
197
+ icon: /* @__PURE__ */ y(g, { className: "size-5" })
198
198
  },
199
199
  {
200
200
  title: "Net revenue",
201
- value: a(V.summary.totalNetRevenue, V.summary.currency),
202
- icon: /* @__PURE__ */ S(b, { className: "size-5" })
201
+ value: i(V.summary.totalNetRevenue, V.summary.currency),
202
+ icon: /* @__PURE__ */ y(v, { className: "size-5" })
203
203
  },
204
204
  {
205
205
  title: "Pending balance",
206
- value: a(V.summary.pendingBalance, V.summary.currency),
207
- icon: /* @__PURE__ */ S(_, { className: "size-5" })
206
+ value: i(V.summary.pendingBalance, V.summary.currency),
207
+ icon: /* @__PURE__ */ y(h, { className: "size-5" })
208
208
  },
209
209
  {
210
210
  title: "Platform fees",
211
- value: a(V.summary.totalPlatformFees, V.summary.currency),
212
- icon: /* @__PURE__ */ S(y, { className: "size-5" })
211
+ value: i(V.summary.totalPlatformFees, V.summary.currency),
212
+ icon: /* @__PURE__ */ y(_, { className: "size-5" })
213
213
  }
214
- ] : [], $ = !!P;
215
- return /* @__PURE__ */ C("div", {
214
+ ] : [], $ = !!j;
215
+ return /* @__PURE__ */ b("div", {
216
216
  className: "space-y-6 p-6",
217
217
  children: [
218
- /* @__PURE__ */ S(n, {
218
+ /* @__PURE__ */ y(n, {
219
219
  title: $ ? "Marketplace earnings" : "Earnings",
220
- description: $ ? `Developer portal revenue, sales, and payouts${F ? ` for ${F}` : ""}.` : "Track affiliate, store, and other earning sources in one ledger."
220
+ description: $ ? `Developer portal revenue, sales, and payouts${M ? ` for ${M}` : ""}.` : "Track affiliate, store, and other earning sources in one ledger.",
221
+ actions: N ? /* @__PURE__ */ b("button", {
222
+ type: "button",
223
+ onClick: () => A?.(N),
224
+ className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary",
225
+ children: [/* @__PURE__ */ y(m, { className: "size-4" }), "Back"]
226
+ }) : void 0
221
227
  }),
222
- /* @__PURE__ */ S(E, { children: "See everything you have earned — from affiliate rewards, store sales and marketplace revenue — in one ledger, along with how much has been paid out and what is still pending. Filter by source to reconcile a specific stream." }),
223
- G ? /* @__PURE__ */ S("div", {
228
+ /* @__PURE__ */ y(C, { children: "See everything you have earned — from affiliate rewards, store sales and marketplace revenue — in one ledger, along with how much has been paid out and what is still pending. Filter by source to reconcile a specific stream." }),
229
+ G ? /* @__PURE__ */ y("div", {
224
230
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4",
225
231
  children: [
226
232
  1,
227
233
  2,
228
234
  3,
229
235
  4
230
- ].map((e) => /* @__PURE__ */ S("div", { className: "h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface" }, e))
231
- }) : $ ? V?.summary ? /* @__PURE__ */ C("div", {
236
+ ].map((e) => /* @__PURE__ */ y("div", { className: "h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface" }, e))
237
+ }) : $ ? V?.summary ? /* @__PURE__ */ b("div", {
232
238
  className: "space-y-6",
233
239
  children: [
234
- /* @__PURE__ */ S("div", {
240
+ /* @__PURE__ */ y("div", {
235
241
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4",
236
- children: ie.map((e) => /* @__PURE__ */ S(r, {
242
+ children: se.map((e) => /* @__PURE__ */ y(r, {
237
243
  label: e.title,
238
244
  value: e.value,
239
245
  icon: e.icon
240
246
  }, e.title))
241
247
  }),
242
- /* @__PURE__ */ C("section", {
248
+ /* @__PURE__ */ b("section", {
243
249
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
244
- children: [/* @__PURE__ */ C("div", {
250
+ children: [/* @__PURE__ */ b("div", {
245
251
  className: "mb-4 flex items-center justify-between",
246
- children: [/* @__PURE__ */ S("h2", {
252
+ children: [/* @__PURE__ */ y("h2", {
247
253
  className: "text-lg font-semibold text-text-primary",
248
254
  children: "Recent sales"
249
- }), /* @__PURE__ */ C("button", {
255
+ }), /* @__PURE__ */ b("button", {
250
256
  type: "button",
251
257
  onClick: () => void X(),
252
258
  className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary",
253
- children: [/* @__PURE__ */ S(y, { className: "size-4" }), "Refresh"]
259
+ children: [/* @__PURE__ */ y(_, { className: "size-4" }), "Refresh"]
254
260
  })]
255
- }), V.sales.length === 0 ? /* @__PURE__ */ S(T, {
261
+ }), V.sales.length === 0 ? /* @__PURE__ */ y(S, {
256
262
  illustration: "empty-data",
257
263
  title: "No sales yet",
258
264
  description: "Sales will appear here when customers start purchasing your apps."
259
- }) : /* @__PURE__ */ S(D, {
265
+ }) : /* @__PURE__ */ y(w, {
260
266
  data: V.sales,
261
267
  rowKey: (e) => e.id,
262
- columns: ee
268
+ columns: T
263
269
  })]
264
270
  }),
265
- /* @__PURE__ */ C("section", {
271
+ /* @__PURE__ */ b("section", {
266
272
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
267
- children: [/* @__PURE__ */ S("h2", {
273
+ children: [/* @__PURE__ */ y("h2", {
268
274
  className: "mb-4 text-lg font-semibold text-text-primary",
269
275
  children: "Payouts"
270
- }), V.payouts.length === 0 ? /* @__PURE__ */ S(T, {
276
+ }), V.payouts.length === 0 ? /* @__PURE__ */ y(S, {
271
277
  illustration: "empty-data",
272
278
  title: "No payouts yet",
273
279
  description: "Scheduled and completed payouts will appear here."
274
- }) : /* @__PURE__ */ S(D, {
280
+ }) : /* @__PURE__ */ y(w, {
275
281
  data: V.payouts,
276
282
  rowKey: (e) => e.id,
277
- columns: O
283
+ columns: ie
278
284
  })]
279
285
  })
280
286
  ]
281
- }) : /* @__PURE__ */ S(T, {
287
+ }) : /* @__PURE__ */ y(S, {
282
288
  illustration: "empty-data",
283
289
  title: "No developer portal revenue yet",
284
290
  description: "Marketplace revenue will appear here once your developer organization records sales."
285
- }) : L ? /* @__PURE__ */ C("div", {
291
+ }) : L ? /* @__PURE__ */ b("div", {
286
292
  className: "space-y-4",
287
- children: [/* @__PURE__ */ S(w, {
293
+ children: [/* @__PURE__ */ y(x, {
288
294
  className: "p-4 sm:p-5",
289
- children: /* @__PURE__ */ S("div", {
295
+ children: /* @__PURE__ */ y("div", {
290
296
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-4",
291
- children: re.map((e) => /* @__PURE__ */ S(r, {
297
+ children: oe.map((e) => /* @__PURE__ */ y(r, {
292
298
  label: e.title,
293
299
  value: e.value,
294
300
  icon: e.icon
295
301
  }, e.title))
296
302
  })
297
- }), Q.length > 0 ? /* @__PURE__ */ S("div", {
303
+ }), Q.length > 0 ? /* @__PURE__ */ y("div", {
298
304
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-3",
299
- children: Q.map((e) => /* @__PURE__ */ C("div", {
305
+ children: Q.map((e) => /* @__PURE__ */ b("div", {
300
306
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
301
307
  children: [
302
- /* @__PURE__ */ S("p", {
308
+ /* @__PURE__ */ y("p", {
303
309
  className: "text-sm text-text-secondary",
304
310
  children: e.title
305
311
  }),
306
- /* @__PURE__ */ S("p", {
312
+ /* @__PURE__ */ y("p", {
307
313
  className: "mt-2 text-xl font-semibold text-text-primary",
308
314
  children: e.value
309
315
  }),
310
- /* @__PURE__ */ S("p", {
316
+ /* @__PURE__ */ y("p", {
311
317
  className: "mt-1 text-xs text-text-secondary",
312
318
  children: e.helperText
313
319
  })
@@ -315,62 +321,62 @@ var ee = [
315
321
  }, e.title))
316
322
  }) : null]
317
323
  }) : null,
318
- q && !s(q) ? /* @__PURE__ */ S("div", {
324
+ q && !o(q) ? /* @__PURE__ */ y("div", {
319
325
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text",
320
326
  children: q.message
321
327
  }) : null,
322
- /* @__PURE__ */ C("section", {
328
+ /* @__PURE__ */ b("section", {
323
329
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
324
- children: [/* @__PURE__ */ C("div", {
330
+ children: [/* @__PURE__ */ b("div", {
325
331
  className: "mb-4 flex items-center justify-between",
326
- children: [/* @__PURE__ */ S("h2", {
332
+ children: [/* @__PURE__ */ y("h2", {
327
333
  className: "text-lg font-semibold text-text-primary",
328
334
  children: "Ledger"
329
- }), /* @__PURE__ */ C("div", {
335
+ }), /* @__PURE__ */ b("div", {
330
336
  className: "flex items-center gap-3",
331
- children: [/* @__PURE__ */ C("select", {
337
+ children: [/* @__PURE__ */ b("select", {
332
338
  value: U,
333
339
  onChange: (e) => W(e.target.value),
334
340
  className: "rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary",
335
341
  children: [
336
- /* @__PURE__ */ S("option", {
342
+ /* @__PURE__ */ y("option", {
337
343
  value: "ALL",
338
344
  children: "All sources"
339
345
  }),
340
- /* @__PURE__ */ S("option", {
346
+ /* @__PURE__ */ y("option", {
341
347
  value: "AFFILIATE",
342
348
  children: "Affiliate"
343
349
  }),
344
- /* @__PURE__ */ S("option", {
350
+ /* @__PURE__ */ y("option", {
345
351
  value: "STORE",
346
352
  children: "Store"
347
353
  }),
348
- /* @__PURE__ */ S("option", {
354
+ /* @__PURE__ */ y("option", {
349
355
  value: "OTHER",
350
356
  children: "Other"
351
357
  })
352
358
  ]
353
- }), /* @__PURE__ */ C("button", {
359
+ }), /* @__PURE__ */ b("button", {
354
360
  type: "button",
355
361
  onClick: () => void X(),
356
362
  className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary",
357
- children: [/* @__PURE__ */ S(y, { className: "size-4" }), "Refresh"]
363
+ children: [/* @__PURE__ */ y(_, { className: "size-4" }), "Refresh"]
358
364
  })]
359
365
  })]
360
- }), Z.length === 0 && !G ? /* @__PURE__ */ S(T, {
366
+ }), Z.length === 0 && !G ? /* @__PURE__ */ y(S, {
361
367
  illustration: "empty-data",
362
368
  title: "No earnings yet",
363
369
  description: "Eligible affiliate rewards and other earnings will appear here."
364
- }) : /* @__PURE__ */ S(D, {
370
+ }) : /* @__PURE__ */ y(w, {
365
371
  data: Z,
366
372
  rowKey: (e) => e.id,
367
- columns: k
373
+ columns: ae
368
374
  })]
369
375
  })
370
376
  ]
371
377
  });
372
378
  };
373
379
  //#endregion
374
- export { A as EarningsPage };
380
+ export { E as EarningsPage };
375
381
 
376
382
  //# sourceMappingURL=EarningsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EarningsPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/EarningsPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState, type FC } from 'react';\nimport { useSearchParams } from 'react-router';\nimport { Coins, HandCoins, RefreshCw, Wallet } from 'lucide-react';\nimport {\n ResponsiveTable,\n type ResponsiveTableColumn,\n PagePurpose,\n EmphasisPanel,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\n\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { AccessDenied, PageHeader, ServerError, StatCard } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport { useGetDefaultBillingAccountSettingsQuery } from '../../../../generated/global-operations';\nimport {\n fetchEarningsEntries,\n fetchEarningsSummary,\n fetchDeveloperPortalRevenueDashboard,\n type DeveloperPortalRevenueDashboard,\n type DeveloperPortalRevenueSale,\n type DeveloperPortalRevenuePayout,\n type EarningsEntry,\n type EarningsSummary,\n} from '../api';\n\ntype EarningsSourceFilter = 'ALL' | 'AFFILIATE' | 'STORE' | 'OTHER';\n\nconst salesColumns: ResponsiveTableColumn<DeveloperPortalRevenueSale>[] = [\n {\n key: 'application',\n header: 'Application',\n priority: 'primary',\n cell: (sale) => sale.application?.name || sale.application?.slug || 'Unknown app',\n },\n { key: 'pricing', header: 'Pricing', cell: (sale) => sale.pricingModel },\n {\n key: 'gross',\n header: 'Gross',\n cell: (sale) => (\n <span className=\"tabular-nums\">\n {formatCurrency(sale.grossAmount, sale.currency || 'USD')}\n </span>\n ),\n },\n {\n key: 'net',\n header: 'Net',\n cell: (sale) => (\n <span className=\"tabular-nums\">{formatCurrency(sale.netAmount, sale.currency || 'USD')}</span>\n ),\n },\n { key: 'status', header: 'Status', cell: (sale) => sale.status },\n {\n key: 'purchased',\n header: 'Purchased',\n cell: (sale) => formatDateTime(sale.purchasedAt),\n },\n];\n\nconst payoutColumns: ResponsiveTableColumn<DeveloperPortalRevenuePayout>[] = [\n {\n key: 'period',\n header: 'Period',\n priority: 'primary',\n cell: (payout) => payout.periodLabel || '-',\n },\n {\n key: 'amount',\n header: 'Amount',\n cell: (payout) => (\n <span className=\"tabular-nums\">\n {formatCurrency(payout.netAmount, payout.currency || 'USD')}\n </span>\n ),\n },\n { key: 'status', header: 'Status', cell: (payout) => payout.status },\n {\n key: 'scheduled',\n header: 'Scheduled',\n cell: (payout) => (payout.scheduledAt ? formatDateTime(payout.scheduledAt) : '-'),\n },\n {\n key: 'completed',\n header: 'Completed',\n cell: (payout) => (payout.completedAt ? formatDateTime(payout.completedAt) : '-'),\n },\n];\n\nconst ledgerColumns: ResponsiveTableColumn<EarningsEntry>[] = [\n {\n key: 'category',\n header: 'Category',\n priority: 'primary',\n cell: (entry) => entry.sourceCategory,\n },\n {\n key: 'description',\n header: 'Description',\n cell: (entry) => entry.description || entry.sourceSubcategory || '-',\n },\n { key: 'unit', header: 'Unit', cell: (entry) => entry.unitType },\n {\n key: 'amount',\n header: 'Amount',\n cell: (entry) => (\n <span className=\"tabular-nums\">\n {entry.unitType === 'CREDITS'\n ? `${entry.amount.toLocaleString()} credits`\n : formatCurrency(entry.amount, entry.currency || 'USD')}\n </span>\n ),\n },\n { key: 'status', header: 'Status', cell: (entry) => entry.status },\n {\n key: 'created',\n header: 'Created',\n cell: (entry) => formatDateTime(entry.createdAt),\n },\n];\n\nexport const EarningsPage: FC = () => {\n const [searchParams] = useSearchParams();\n const permissions = useBillingPermissions();\n const { apiGatewayUrl, authToken, orgId } = useBilling();\n const developerOrgId = searchParams.get('developerOrgId');\n const developerOrgName = searchParams.get('developerOrgName');\n const { data: billingAccountData, loading: billingAccountLoading } =\n useGetDefaultBillingAccountSettingsQuery({});\n\n const billingAccountId = billingAccountData?.getDefaultBillingAccount?.id;\n const [summary, setSummary] = useState<EarningsSummary | null>(null);\n const [entries, setEntries] = useState<EarningsEntry[]>([]);\n const [developerPortalRevenue, setDeveloperPortalRevenue] =\n useState<DeveloperPortalRevenueDashboard | null>(null);\n const [sourceFilter, setSourceFilter] = useState<EarningsSourceFilter>('ALL');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const requestContext = useMemo(\n () => ({\n apiGatewayUrl,\n authToken,\n orgId,\n }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n if (developerOrgId) {\n const loadedRevenue = await fetchDeveloperPortalRevenueDashboard(\n developerOrgId,\n requestContext\n );\n setDeveloperPortalRevenue(loadedRevenue);\n setSummary(null);\n setEntries([]);\n return;\n }\n\n if (!billingAccountId) {\n setSummary(null);\n setEntries([]);\n setDeveloperPortalRevenue(null);\n return;\n }\n\n const [loadedSummary, loadedEntries] = await Promise.all([\n fetchEarningsSummary(billingAccountId, requestContext),\n fetchEarningsEntries(billingAccountId, requestContext),\n ]);\n setSummary(loadedSummary);\n setEntries(loadedEntries);\n setDeveloperPortalRevenue(null);\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load earnings'));\n } finally {\n setLoading(false);\n }\n }, [billingAccountId, developerOrgId, requestContext]);\n\n useEffect(() => {\n void loadData();\n }, [loadData]);\n\n if (!permissions.canViewBillingAccount) {\n return <AccessDenied message=\"You don't have permission to view earnings.\" />;\n }\n\n if (!developerOrgId && !billingAccountId && !billingAccountLoading) {\n return (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No billing account found\"\n description=\"Create a billing account first to view earnings.\"\n />\n );\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Earnings unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const cards = summary\n ? [\n {\n title: 'Available',\n value: formatCurrency(summary.availableAmount, 'USD'),\n icon: <HandCoins className=\"size-5\" />,\n },\n {\n title: 'Reserved',\n value: formatCurrency(summary.reservedAmount, 'USD'),\n icon: <Coins className=\"size-5\" />,\n },\n {\n title: 'Paid out',\n value: formatCurrency(summary.paidAmount, 'USD'),\n icon: <Wallet className=\"size-5\" />,\n },\n {\n title: 'Lifetime',\n value: formatCurrency(summary.totalLifetimeAmount, 'USD'),\n icon: <RefreshCw className=\"size-5\" />,\n },\n ]\n : [];\n\n const filteredEntries =\n sourceFilter === 'ALL'\n ? entries\n : entries.filter((entry) => entry.sourceCategory === sourceFilter);\n\n const categoryCards =\n summary?.categoryBreakdown?.map((item) => ({\n title: `${item.category} earnings`,\n value: formatCurrency(item.amount, 'USD'),\n helperText: `${item.count} entries`,\n })) ?? [];\n\n const developerPortalCards = developerPortalRevenue?.summary\n ? [\n {\n title: 'Gross revenue',\n value: formatCurrency(\n developerPortalRevenue.summary.totalGrossRevenue,\n developerPortalRevenue.summary.currency\n ),\n icon: <HandCoins className=\"size-5\" />,\n },\n {\n title: 'Net revenue',\n value: formatCurrency(\n developerPortalRevenue.summary.totalNetRevenue,\n developerPortalRevenue.summary.currency\n ),\n icon: <Wallet className=\"size-5\" />,\n },\n {\n title: 'Pending balance',\n value: formatCurrency(\n developerPortalRevenue.summary.pendingBalance,\n developerPortalRevenue.summary.currency\n ),\n icon: <Coins className=\"size-5\" />,\n },\n {\n title: 'Platform fees',\n value: formatCurrency(\n developerPortalRevenue.summary.totalPlatformFees,\n developerPortalRevenue.summary.currency\n ),\n icon: <RefreshCw className=\"size-5\" />,\n },\n ]\n : [];\n\n const isDeveloperPortalMode = !!developerOrgId;\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={isDeveloperPortalMode ? 'Marketplace earnings' : 'Earnings'}\n description={\n isDeveloperPortalMode\n ? `Developer portal revenue, sales, and payouts${developerOrgName ? ` for ${developerOrgName}` : ''}.`\n : 'Track affiliate, store, and other earning sources in one ledger.'\n }\n />\n\n <PagePurpose>\n See everything you have earned — from affiliate rewards, store sales and marketplace revenue\n — in one ledger, along with how much has been paid out and what is still pending. Filter by\n source to reconcile a specific stream.\n </PagePurpose>\n\n {loading ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {[1, 2, 3, 4].map((item) => (\n <div\n key={item}\n className=\"h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface\"\n />\n ))}\n </div>\n ) : isDeveloperPortalMode ? (\n developerPortalRevenue?.summary ? (\n <div className=\"space-y-6\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {developerPortalCards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent sales</h2>\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n </div>\n\n {developerPortalRevenue.sales.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No sales yet\"\n description=\"Sales will appear here when customers start purchasing your apps.\"\n />\n ) : (\n <ResponsiveTable\n data={developerPortalRevenue.sales}\n rowKey={(sale) => sale.id}\n columns={salesColumns}\n />\n )}\n </section>\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Payouts</h2>\n\n {developerPortalRevenue.payouts.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No payouts yet\"\n description=\"Scheduled and completed payouts will appear here.\"\n />\n ) : (\n <ResponsiveTable\n data={developerPortalRevenue.payouts}\n rowKey={(payout) => payout.id}\n columns={payoutColumns}\n />\n )}\n </section>\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No developer portal revenue yet\"\n description=\"Marketplace revenue will appear here once your developer organization records sales.\"\n />\n )\n ) : summary ? (\n <div className=\"space-y-4\">\n <EmphasisPanel className=\"p-4 sm:p-5\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {cards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n </EmphasisPanel>\n {categoryCards.length > 0 ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {categoryCards.map((card) => (\n <div\n key={card.title}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <p className=\"text-sm text-text-secondary\">{card.title}</p>\n <p className=\"mt-2 text-xl font-semibold text-text-primary\">{card.value}</p>\n <p className=\"mt-1 text-xs text-text-secondary\">{card.helperText}</p>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n {error && !isServerError(error) ? (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text\">\n {error.message}\n </div>\n ) : null}\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Ledger</h2>\n <div className=\"flex items-center gap-3\">\n <select\n value={sourceFilter}\n onChange={(event) => setSourceFilter(event.target.value as EarningsSourceFilter)}\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"ALL\">All sources</option>\n <option value=\"AFFILIATE\">Affiliate</option>\n <option value=\"STORE\">Store</option>\n <option value=\"OTHER\">Other</option>\n </select>\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n </div>\n </div>\n\n {filteredEntries.length === 0 && !loading ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No earnings yet\"\n description=\"Eligible affiliate rewards and other earnings will appear here.\"\n />\n ) : (\n <ResponsiveTable\n data={filteredEntries}\n rowKey={(entry) => entry.id}\n columns={ledgerColumns}\n />\n )}\n </section>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"EarningsPage.js","names":[],"sources":["../../../../../src/billing/modules/earnings/pages/EarningsPage.tsx"],"sourcesContent":["import { useCallback, useEffect, useMemo, useState, type FC } from 'react';\nimport { useSearchParams } from 'react-router';\nimport { ArrowLeft, Coins, HandCoins, RefreshCw, Wallet } from 'lucide-react';\nimport {\n ResponsiveTable,\n type ResponsiveTableColumn,\n PagePurpose,\n EmphasisPanel,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\n\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { useBilling } from '../../../providers/BillingProvider';\nimport { AccessDenied, PageHeader, ServerError, StatCard } from '../../../shared/components';\nimport { formatCurrency, formatDateTime, isServerError } from '../../../shared/utils';\nimport { useGetDefaultBillingAccountSettingsQuery } from '../../../../generated/global-operations';\nimport {\n fetchEarningsEntries,\n fetchEarningsSummary,\n fetchDeveloperPortalRevenueDashboard,\n type DeveloperPortalRevenueDashboard,\n type DeveloperPortalRevenueSale,\n type DeveloperPortalRevenuePayout,\n type EarningsEntry,\n type EarningsSummary,\n} from '../api';\n\ntype EarningsSourceFilter = 'ALL' | 'AFFILIATE' | 'STORE' | 'OTHER';\n\nconst salesColumns: ResponsiveTableColumn<DeveloperPortalRevenueSale>[] = [\n {\n key: 'application',\n header: 'Application',\n priority: 'primary',\n cell: (sale) => sale.application?.name || sale.application?.slug || 'Unknown app',\n },\n { key: 'pricing', header: 'Pricing', cell: (sale) => sale.pricingModel },\n {\n key: 'gross',\n header: 'Gross',\n cell: (sale) => (\n <span className=\"tabular-nums\">\n {formatCurrency(sale.grossAmount, sale.currency || 'USD')}\n </span>\n ),\n },\n {\n key: 'net',\n header: 'Net',\n cell: (sale) => (\n <span className=\"tabular-nums\">{formatCurrency(sale.netAmount, sale.currency || 'USD')}</span>\n ),\n },\n { key: 'status', header: 'Status', cell: (sale) => sale.status },\n {\n key: 'purchased',\n header: 'Purchased',\n cell: (sale) => formatDateTime(sale.purchasedAt),\n },\n];\n\nconst payoutColumns: ResponsiveTableColumn<DeveloperPortalRevenuePayout>[] = [\n {\n key: 'period',\n header: 'Period',\n priority: 'primary',\n cell: (payout) => payout.periodLabel || '-',\n },\n {\n key: 'amount',\n header: 'Amount',\n cell: (payout) => (\n <span className=\"tabular-nums\">\n {formatCurrency(payout.netAmount, payout.currency || 'USD')}\n </span>\n ),\n },\n { key: 'status', header: 'Status', cell: (payout) => payout.status },\n {\n key: 'scheduled',\n header: 'Scheduled',\n cell: (payout) => (payout.scheduledAt ? formatDateTime(payout.scheduledAt) : '-'),\n },\n {\n key: 'completed',\n header: 'Completed',\n cell: (payout) => (payout.completedAt ? formatDateTime(payout.completedAt) : '-'),\n },\n];\n\nconst ledgerColumns: ResponsiveTableColumn<EarningsEntry>[] = [\n {\n key: 'category',\n header: 'Category',\n priority: 'primary',\n cell: (entry) => entry.sourceCategory,\n },\n {\n key: 'description',\n header: 'Description',\n cell: (entry) => entry.description || entry.sourceSubcategory || '-',\n },\n { key: 'unit', header: 'Unit', cell: (entry) => entry.unitType },\n {\n key: 'amount',\n header: 'Amount',\n cell: (entry) => (\n <span className=\"tabular-nums\">\n {entry.unitType === 'CREDITS'\n ? `${entry.amount.toLocaleString()} credits`\n : formatCurrency(entry.amount, entry.currency || 'USD')}\n </span>\n ),\n },\n { key: 'status', header: 'Status', cell: (entry) => entry.status },\n {\n key: 'created',\n header: 'Created',\n cell: (entry) => formatDateTime(entry.createdAt),\n },\n];\n\nexport const EarningsPage: FC = () => {\n const [searchParams] = useSearchParams();\n const permissions = useBillingPermissions();\n const { apiGatewayUrl, authToken, orgId, navigate } = useBilling();\n const developerOrgId = searchParams.get('developerOrgId');\n const developerOrgName = searchParams.get('developerOrgName');\n // Set by devportal's OrganizationDetailPage when it links here — lets this\n // page offer a way back without needing to know whether the org is\n // PHYSICAL or DIGITAL (that split isn't in scope on this side).\n const returnTo = searchParams.get('returnTo');\n const { data: billingAccountData, loading: billingAccountLoading } =\n useGetDefaultBillingAccountSettingsQuery({});\n\n const billingAccountId = billingAccountData?.getDefaultBillingAccount?.id;\n const [summary, setSummary] = useState<EarningsSummary | null>(null);\n const [entries, setEntries] = useState<EarningsEntry[]>([]);\n const [developerPortalRevenue, setDeveloperPortalRevenue] =\n useState<DeveloperPortalRevenueDashboard | null>(null);\n const [sourceFilter, setSourceFilter] = useState<EarningsSourceFilter>('ALL');\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const requestContext = useMemo(\n () => ({\n apiGatewayUrl,\n authToken,\n orgId,\n }),\n [apiGatewayUrl, authToken, orgId]\n );\n\n const loadData = useCallback(async () => {\n setLoading(true);\n setError(null);\n try {\n if (developerOrgId) {\n const loadedRevenue = await fetchDeveloperPortalRevenueDashboard(\n developerOrgId,\n requestContext\n );\n setDeveloperPortalRevenue(loadedRevenue);\n setSummary(null);\n setEntries([]);\n return;\n }\n\n if (!billingAccountId) {\n setSummary(null);\n setEntries([]);\n setDeveloperPortalRevenue(null);\n return;\n }\n\n const [loadedSummary, loadedEntries] = await Promise.all([\n fetchEarningsSummary(billingAccountId, requestContext),\n fetchEarningsEntries(billingAccountId, requestContext),\n ]);\n setSummary(loadedSummary);\n setEntries(loadedEntries);\n setDeveloperPortalRevenue(null);\n } catch (loadError) {\n setError(loadError instanceof Error ? loadError : new Error('Failed to load earnings'));\n } finally {\n setLoading(false);\n }\n }, [billingAccountId, developerOrgId, requestContext]);\n\n useEffect(() => {\n void loadData();\n }, [loadData]);\n\n if (!permissions.canViewBillingAccount) {\n return <AccessDenied message=\"You don't have permission to view earnings.\" />;\n }\n\n if (!developerOrgId && !billingAccountId && !billingAccountLoading) {\n return (\n <IllustratedEmptyState\n illustration=\"empty-generic\"\n title=\"No billing account found\"\n description=\"Create a billing account first to view earnings.\"\n />\n );\n }\n\n if (error && isServerError(error)) {\n return (\n <ServerError\n title=\"Earnings unavailable\"\n message={error.message}\n onRetry={() => void loadData()}\n showRetry\n />\n );\n }\n\n const cards = summary\n ? [\n {\n title: 'Available',\n value: formatCurrency(summary.availableAmount, 'USD'),\n icon: <HandCoins className=\"size-5\" />,\n },\n {\n title: 'Reserved',\n value: formatCurrency(summary.reservedAmount, 'USD'),\n icon: <Coins className=\"size-5\" />,\n },\n {\n title: 'Paid out',\n value: formatCurrency(summary.paidAmount, 'USD'),\n icon: <Wallet className=\"size-5\" />,\n },\n {\n title: 'Lifetime',\n value: formatCurrency(summary.totalLifetimeAmount, 'USD'),\n icon: <RefreshCw className=\"size-5\" />,\n },\n ]\n : [];\n\n const filteredEntries =\n sourceFilter === 'ALL'\n ? entries\n : entries.filter((entry) => entry.sourceCategory === sourceFilter);\n\n const categoryCards =\n summary?.categoryBreakdown?.map((item) => ({\n title: `${item.category} earnings`,\n value: formatCurrency(item.amount, 'USD'),\n helperText: `${item.count} entries`,\n })) ?? [];\n\n const developerPortalCards = developerPortalRevenue?.summary\n ? [\n {\n title: 'Gross revenue',\n value: formatCurrency(\n developerPortalRevenue.summary.totalGrossRevenue,\n developerPortalRevenue.summary.currency\n ),\n icon: <HandCoins className=\"size-5\" />,\n },\n {\n title: 'Net revenue',\n value: formatCurrency(\n developerPortalRevenue.summary.totalNetRevenue,\n developerPortalRevenue.summary.currency\n ),\n icon: <Wallet className=\"size-5\" />,\n },\n {\n title: 'Pending balance',\n value: formatCurrency(\n developerPortalRevenue.summary.pendingBalance,\n developerPortalRevenue.summary.currency\n ),\n icon: <Coins className=\"size-5\" />,\n },\n {\n title: 'Platform fees',\n value: formatCurrency(\n developerPortalRevenue.summary.totalPlatformFees,\n developerPortalRevenue.summary.currency\n ),\n icon: <RefreshCw className=\"size-5\" />,\n },\n ]\n : [];\n\n const isDeveloperPortalMode = !!developerOrgId;\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={isDeveloperPortalMode ? 'Marketplace earnings' : 'Earnings'}\n description={\n isDeveloperPortalMode\n ? `Developer portal revenue, sales, and payouts${developerOrgName ? ` for ${developerOrgName}` : ''}.`\n : 'Track affiliate, store, and other earning sources in one ledger.'\n }\n actions={\n returnTo ? (\n <button\n type=\"button\"\n onClick={() => navigate?.(returnTo)}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n ) : undefined\n }\n />\n\n <PagePurpose>\n See everything you have earned — from affiliate rewards, store sales and marketplace revenue\n — in one ledger, along with how much has been paid out and what is still pending. Filter by\n source to reconcile a specific stream.\n </PagePurpose>\n\n {loading ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {[1, 2, 3, 4].map((item) => (\n <div\n key={item}\n className=\"h-28 animate-pulse rounded-lg border border-border-subtle bg-bg-surface\"\n />\n ))}\n </div>\n ) : isDeveloperPortalMode ? (\n developerPortalRevenue?.summary ? (\n <div className=\"space-y-6\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {developerPortalCards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent sales</h2>\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n </div>\n\n {developerPortalRevenue.sales.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No sales yet\"\n description=\"Sales will appear here when customers start purchasing your apps.\"\n />\n ) : (\n <ResponsiveTable\n data={developerPortalRevenue.sales}\n rowKey={(sale) => sale.id}\n columns={salesColumns}\n />\n )}\n </section>\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Payouts</h2>\n\n {developerPortalRevenue.payouts.length === 0 ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No payouts yet\"\n description=\"Scheduled and completed payouts will appear here.\"\n />\n ) : (\n <ResponsiveTable\n data={developerPortalRevenue.payouts}\n rowKey={(payout) => payout.id}\n columns={payoutColumns}\n />\n )}\n </section>\n </div>\n ) : (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No developer portal revenue yet\"\n description=\"Marketplace revenue will appear here once your developer organization records sales.\"\n />\n )\n ) : summary ? (\n <div className=\"space-y-4\">\n <EmphasisPanel className=\"p-4 sm:p-5\">\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {cards.map((card) => (\n <StatCard key={card.title} label={card.title} value={card.value} icon={card.icon} />\n ))}\n </div>\n </EmphasisPanel>\n {categoryCards.length > 0 ? (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {categoryCards.map((card) => (\n <div\n key={card.title}\n className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\"\n >\n <p className=\"text-sm text-text-secondary\">{card.title}</p>\n <p className=\"mt-2 text-xl font-semibold text-text-primary\">{card.value}</p>\n <p className=\"mt-1 text-xs text-text-secondary\">{card.helperText}</p>\n </div>\n ))}\n </div>\n ) : null}\n </div>\n ) : null}\n\n {error && !isServerError(error) ? (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4 text-sm text-status-error-text\">\n {error.message}\n </div>\n ) : null}\n\n <section className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Ledger</h2>\n <div className=\"flex items-center gap-3\">\n <select\n value={sourceFilter}\n onChange={(event) => setSourceFilter(event.target.value as EarningsSourceFilter)}\n className=\"rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n <option value=\"ALL\">All sources</option>\n <option value=\"AFFILIATE\">Affiliate</option>\n <option value=\"STORE\">Store</option>\n <option value=\"OTHER\">Other</option>\n </select>\n <button\n type=\"button\"\n onClick={() => void loadData()}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary\"\n >\n <RefreshCw className=\"size-4\" />\n Refresh\n </button>\n </div>\n </div>\n\n {filteredEntries.length === 0 && !loading ? (\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title=\"No earnings yet\"\n description=\"Eligible affiliate rewards and other earnings will appear here.\"\n />\n ) : (\n <ResponsiveTable\n data={filteredEntries}\n rowKey={(entry) => entry.id}\n columns={ledgerColumns}\n />\n )}\n </section>\n </div>\n );\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-billing",
3
- "version": "2026.915.3",
3
+ "version": "2026.916.1",
4
4
  "description": "Billing microfrontend for Burdenoff products",
5
5
  "type": "module",
6
6
  "files": [