@burdenoff/microfe-billing 2026.625.4 → 2026.626.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 (96) hide show
  1. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +192 -187
  2. package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
  3. package/dist/billing/modules/addons/pages/AddonCreatePage.js +322 -317
  4. package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
  5. package/dist/billing/modules/addons/pages/AddonDetailPage.js +190 -185
  6. package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
  7. package/dist/billing/modules/addons/pages/AddonEditPage.js +297 -292
  8. package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
  9. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +60 -75
  10. package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
  11. package/dist/billing/modules/addons/pages/AddonsListPage.js +86 -101
  12. package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
  13. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +124 -121
  14. package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
  15. package/dist/billing/modules/analytics/pages/AnalyticsPage.js +103 -111
  16. package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
  17. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +196 -160
  18. package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
  19. package/dist/billing/modules/billing/pages/InvoicesListPage.js +58 -73
  20. package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
  21. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +65 -75
  22. package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
  23. package/dist/billing/modules/billing/pages/RefundsPage.js +399 -399
  24. package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
  25. package/dist/billing/modules/billing/pages/TransactionsPage.js +49 -48
  26. package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
  27. package/dist/billing/modules/billing/pages/UserRefundsPage.js +144 -151
  28. package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
  29. package/dist/billing/modules/checkout/pages/CheckoutPage.js +430 -425
  30. package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
  31. package/dist/billing/modules/coupons/pages/CouponDetailPage.js +121 -93
  32. package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
  33. package/dist/billing/modules/coupons/pages/CouponsListPage.js +154 -152
  34. package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
  35. package/dist/billing/modules/coupons/pages/CreateCouponPage.js +467 -462
  36. package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
  37. package/dist/billing/modules/coupons/pages/EditCouponPage.js +294 -286
  38. package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
  39. package/dist/billing/modules/credits/pages/AdminCreditsPage.js +123 -117
  40. package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
  41. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +43 -42
  42. package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
  43. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +192 -207
  44. package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
  45. package/dist/billing/modules/credits/pages/CreditsPage.js +40 -56
  46. package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
  47. package/dist/billing/modules/dashboard/pages/OverviewPage.js +128 -121
  48. package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
  49. package/dist/billing/modules/discounts/pages/DiscountsListPage.js +165 -180
  50. package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
  51. package/dist/billing/modules/earnings/pages/EarningsPage.js +103 -100
  52. package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
  53. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +175 -175
  54. package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
  55. package/dist/billing/modules/earnings/pages/PayoutsPage.js +96 -96
  56. package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
  57. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +42 -40
  58. package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
  59. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +45 -38
  60. package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
  61. package/dist/billing/modules/plans/pages/PlanCreatePage.js +339 -334
  62. package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
  63. package/dist/billing/modules/plans/pages/PlanDetailPage.js +80 -74
  64. package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
  65. package/dist/billing/modules/plans/pages/PlanEditPage.js +342 -337
  66. package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
  67. package/dist/billing/modules/plans/pages/PlansBrowsePage.js +38 -53
  68. package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
  69. package/dist/billing/modules/plans/pages/PlansListPage.js +60 -75
  70. package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
  71. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +242 -237
  72. package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
  73. package/dist/billing/modules/promotions/pages/PromotionsListPage.js +29 -39
  74. package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
  75. package/dist/billing/modules/quota/pages/QuotaPage.js +1 -0
  76. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +299 -294
  77. package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
  78. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +191 -186
  79. package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
  80. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +308 -303
  81. package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
  82. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +57 -78
  83. package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
  84. package/dist/billing/modules/settings/pages/SettingsPage.js +79 -78
  85. package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
  86. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +15 -13
  87. package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
  88. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +338 -299
  89. package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
  90. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +82 -103
  91. package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
  92. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +59 -54
  93. package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
  94. package/dist/billing/modules/usage/pages/UsagePage.js +172 -215
  95. package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
  96. package/package.json +2 -2
@@ -9,9 +9,9 @@ import { useEffect as s, useState as c } from "react";
9
9
  import { ArrowLeft as l, BarChart2 as u, Calendar as d, ChevronLeft as f, ChevronRight as p, Edit as m, History as h, Package as g, Tag as _, Users as v } from "lucide-react";
10
10
  import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
11
11
  import { useI18n as S } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
- import { CTAOverflowMenu as C, ResponsiveTable as w } from "@burdenoff/fe-libs/ui";
12
+ import { CTAOverflowMenu as C, NextSteps as w, PagePurpose as T, ResponsiveTable as E } from "@burdenoff/fe-libs/ui";
13
13
  //#region src/billing/modules/coupons/pages/CouponDetailPage.tsx
14
- var T = [
14
+ var D = [
15
15
  {
16
16
  key: "userId",
17
17
  header: "User ID",
@@ -82,7 +82,7 @@ var T = [
82
82
  cell: (e) => new Date(e.usedAt).toLocaleString()
83
83
  }
84
84
  ];
85
- function E({ status: e }) {
85
+ function O({ status: e }) {
86
86
  let { label: t, className: n } = {
87
87
  [o.Active]: {
88
88
  label: "Active",
@@ -109,7 +109,7 @@ function E({ status: e }) {
109
109
  children: t
110
110
  });
111
111
  }
112
- function D({ label: e, value: t }) {
112
+ function k({ label: e, value: t }) {
113
113
  return /* @__PURE__ */ x("div", {
114
114
  className: "flex items-start gap-2 py-3 border-b border-border-subtle last:border-0",
115
115
  children: [/* @__PURE__ */ b("span", {
@@ -121,29 +121,29 @@ function D({ label: e, value: t }) {
121
121
  })]
122
122
  });
123
123
  }
124
- var O = () => {
125
- let { t: o } = S(), O = (e, t) => {
124
+ var A = () => {
125
+ let { t: o } = S(), A = (e, t) => {
126
126
  let n = o(e);
127
127
  return n === e ? t : n;
128
- }, k = a(), A = n(), j = window.location.pathname.split("/").filter(Boolean).slice(-1)[0], [M, N] = c("details"), [P, F] = c(0), [I, { data: L, loading: R, error: z }] = r(), { data: B, loading: V } = i({
128
+ }, j = a(), M = n(), N = window.location.pathname.split("/").filter(Boolean).slice(-1)[0], [P, F] = c("details"), [I, L] = c(0), [R, { data: z, loading: B, error: V }] = r(), { data: H, loading: U } = i({
129
129
  variables: {
130
- couponId: j,
130
+ couponId: N,
131
131
  limit: 20,
132
- offset: P * 20
132
+ offset: I * 20
133
133
  },
134
- skip: !j || M !== "usage"
134
+ skip: !N || P !== "usage"
135
135
  });
136
136
  if (s(() => {
137
- j && I({ variables: { id: j } });
138
- }, [j, I]), !A.canManageDiscounts) return /* @__PURE__ */ b(e, { message: "You don't have permission to view coupon details." });
139
- if (R) return /* @__PURE__ */ x("div", {
137
+ N && R({ variables: { id: N } });
138
+ }, [N, R]), !M.canManageDiscounts) return /* @__PURE__ */ b(e, { message: "You don't have permission to view coupon details." });
139
+ if (B) return /* @__PURE__ */ x("div", {
140
140
  className: "p-8",
141
141
  children: [/* @__PURE__ */ b(t, {
142
- title: O("billing.coupons.detailTitle", "Coupon Details"),
142
+ title: A("billing.coupons.detailTitle", "Coupon Details"),
143
143
  description: "Loading...",
144
144
  actions: /* @__PURE__ */ x("button", {
145
145
  type: "button",
146
- onClick: () => k("/coupons"),
146
+ onClick: () => j("/coupons"),
147
147
  className: "px-4 py-2 rounded-lg border border-border-subtle text-text-primary hover:bg-bg-sunken flex items-center gap-2",
148
148
  children: [/* @__PURE__ */ b(l, { className: "size-4" }), "Back"]
149
149
  })
@@ -152,88 +152,116 @@ var O = () => {
152
152
  children: /* @__PURE__ */ b("div", { className: "size-8 animate-spin rounded-full border-4 border-action-primary-bg border-t-transparent" })
153
153
  })]
154
154
  });
155
- if (z || !L?.getCoupon) return /* @__PURE__ */ x("div", {
155
+ if (V || !z?.getCoupon) return /* @__PURE__ */ x("div", {
156
156
  className: "p-8",
157
157
  children: [/* @__PURE__ */ b(t, {
158
158
  title: "Coupon Details",
159
159
  description: "Coupon not found",
160
160
  actions: /* @__PURE__ */ x("button", {
161
161
  type: "button",
162
- onClick: () => k("/coupons"),
162
+ onClick: () => j("/coupons"),
163
163
  className: "px-4 py-2 rounded-lg border border-border-subtle text-text-primary hover:bg-bg-sunken flex items-center gap-2",
164
164
  children: [/* @__PURE__ */ b(l, { className: "size-4" }), "Back"]
165
165
  })
166
166
  }), /* @__PURE__ */ b("div", {
167
167
  className: "flex items-center justify-center h-64 text-status-error-text text-sm",
168
- children: z ? `Error: ${z.message}` : "Coupon not found"
168
+ children: V ? `Error: ${V.message}` : "Coupon not found"
169
169
  })]
170
170
  });
171
- let H = L.getCoupon, U = H.maxTotalUses && H.maxTotalUses > 0 ? Math.round(H.currentUses / H.maxTotalUses * 100) : null, W = (e) => e ? new Date(e).toLocaleDateString(void 0, {
171
+ let W = z.getCoupon, G = W.maxTotalUses && W.maxTotalUses > 0 ? Math.round(W.currentUses / W.maxTotalUses * 100) : null, K = [
172
+ {
173
+ id: "edit",
174
+ label: "Edit this coupon",
175
+ description: "Adjust the discount, limits, expiry or applicable products.",
176
+ onClick: () => j(`/coupons/${W.id}/edit`)
177
+ },
178
+ {
179
+ id: "usage",
180
+ label: "Review who has redeemed it",
181
+ description: "Open the Usage History tab to see every redemption.",
182
+ onClick: () => F("usage")
183
+ },
184
+ {
185
+ id: "back",
186
+ label: "Manage all coupons",
187
+ description: "Return to the full list of discount codes.",
188
+ onClick: () => j("/coupons")
189
+ }
190
+ ], q = (e) => e ? new Date(e).toLocaleDateString(void 0, {
172
191
  year: "numeric",
173
192
  month: "short",
174
193
  day: "numeric"
175
- }) : null, G = () => H.type === "PERCENTAGE" ? `${H.value}%` : `${H.value}${H.currency ? ` ${H.currency}` : ""}`;
194
+ }) : null, J = () => W.type === "PERCENTAGE" ? `${W.value}%` : `${W.value}${W.currency ? ` ${W.currency}` : ""}`;
176
195
  return /* @__PURE__ */ x("div", {
177
196
  className: "p-8",
178
197
  children: [
179
198
  /* @__PURE__ */ b(t, {
180
- title: H.name || H.code,
181
- description: H.description || `Coupon code: ${H.code}`,
199
+ title: W.name || W.code,
200
+ description: W.description || `Coupon code: ${W.code}`,
182
201
  actions: /* @__PURE__ */ b(C, {
183
202
  primary: {
184
203
  label: "Edit",
185
- onSelect: () => k(`/coupons/${H.id}/edit`),
204
+ onSelect: () => j(`/coupons/${W.id}/edit`),
186
205
  icon: /* @__PURE__ */ b(m, { className: "size-4" })
187
206
  },
188
207
  actions: [{
189
208
  label: "Back to coupons",
190
- onSelect: () => k("/coupons"),
209
+ onSelect: () => j("/coupons"),
191
210
  icon: /* @__PURE__ */ b(l, { className: "size-4" })
192
211
  }]
193
212
  })
194
213
  }),
214
+ /* @__PURE__ */ b(T, {
215
+ className: "mt-2",
216
+ children: "Everything about this coupon — its discount, validity window, usage limits and the full redemption history. Use it to check how it is performing, edit its terms, or stop it being redeemed."
217
+ }),
218
+ /* @__PURE__ */ b(w, {
219
+ storageKey: "billing-coupon-detail",
220
+ steps: K,
221
+ className: "mt-4"
222
+ }),
195
223
  /* @__PURE__ */ b("div", {
196
224
  className: "mt-6 border-b border-border-subtle flex gap-1",
197
225
  children: ["details", "usage"].map((e) => /* @__PURE__ */ x("button", {
198
226
  type: "button",
199
- onClick: () => N(e),
200
- className: `flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${M === e ? "border-action-primary-bg text-text-primary" : "border-transparent text-text-muted hover:text-text-primary"}`,
201
- children: [b(e === "details" ? _ : h, { className: "size-4" }), e === "details" ? "Details" : `Usage History${B ? ` (${B.getCouponUsageHistory.total})` : ""}`]
227
+ onClick: () => F(e),
228
+ className: `flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${P === e ? "border-action-primary-bg text-text-primary" : "border-transparent text-text-muted hover:text-text-primary"}`,
229
+ children: [b(e === "details" ? _ : h, { className: "size-4" }), e === "details" ? "Details" : `Usage History${H ? ` (${H.getCouponUsageHistory.total})` : ""}`]
202
230
  }, e))
203
231
  }),
204
- M === "usage" && /* @__PURE__ */ b("div", {
232
+ P === "usage" && /* @__PURE__ */ b("div", {
205
233
  className: "mt-6 bg-bg-surface border border-border-subtle rounded-lg overflow-hidden",
206
- children: V ? /* @__PURE__ */ b("div", {
234
+ children: U ? /* @__PURE__ */ b("div", {
207
235
  className: "flex items-center justify-center h-40",
208
236
  children: /* @__PURE__ */ b("div", { className: "size-6 animate-spin rounded-full border-4 border-action-primary-bg border-t-transparent" })
209
- }) : B?.getCouponUsageHistory.usages.length ? /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ b(w, {
210
- data: B.getCouponUsageHistory.usages,
237
+ }) : H?.getCouponUsageHistory.usages.length ? /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ b(E, {
238
+ data: H.getCouponUsageHistory.usages,
211
239
  rowKey: (e) => e.id,
212
- columns: T
213
- }), (B.getCouponUsageHistory.total ?? 0) > 20 && /* @__PURE__ */ x("div", {
240
+ columns: D
241
+ }), (H.getCouponUsageHistory.total ?? 0) > 20 && /* @__PURE__ */ x("div", {
214
242
  className: "flex items-center justify-between p-4 border-t border-border-subtle",
215
243
  children: [/* @__PURE__ */ x("p", {
216
244
  className: "text-sm text-text-muted",
217
245
  children: [
218
- P * 20 + 1,
246
+ I * 20 + 1,
219
247
  "–",
220
- Math.min((P + 1) * 20, B.getCouponUsageHistory.total),
248
+ Math.min((I + 1) * 20, H.getCouponUsageHistory.total),
221
249
  " ",
222
250
  "of ",
223
- B.getCouponUsageHistory.total
251
+ H.getCouponUsageHistory.total
224
252
  ]
225
253
  }), /* @__PURE__ */ x("div", {
226
254
  className: "flex items-center gap-2",
227
255
  children: [/* @__PURE__ */ b("button", {
228
256
  type: "button",
229
- onClick: () => F((e) => Math.max(0, e - 1)),
230
- disabled: P === 0,
257
+ onClick: () => L((e) => Math.max(0, e - 1)),
258
+ disabled: I === 0,
231
259
  className: "p-1.5 rounded border border-border-subtle hover:bg-bg-sunken disabled:opacity-40",
232
260
  children: /* @__PURE__ */ b(f, { className: "size-4" })
233
261
  }), /* @__PURE__ */ b("button", {
234
262
  type: "button",
235
- onClick: () => F((e) => e + 1),
236
- disabled: !B.getCouponUsageHistory.hasMore,
263
+ onClick: () => L((e) => e + 1),
264
+ disabled: !H.getCouponUsageHistory.hasMore,
237
265
  className: "p-1.5 rounded border border-border-subtle hover:bg-bg-sunken disabled:opacity-40",
238
266
  children: /* @__PURE__ */ b(p, { className: "size-4" })
239
267
  })]
@@ -243,7 +271,7 @@ var O = () => {
243
271
  children: "No usage recorded for this coupon yet."
244
272
  })
245
273
  }),
246
- M === "details" && /* @__PURE__ */ x("div", {
274
+ P === "details" && /* @__PURE__ */ x("div", {
247
275
  className: "mt-8 grid grid-cols-1 lg:grid-cols-3 gap-6",
248
276
  children: [
249
277
  /* @__PURE__ */ x("div", {
@@ -259,7 +287,7 @@ var O = () => {
259
287
  })]
260
288
  }), /* @__PURE__ */ b("p", {
261
289
  className: "text-lg font-mono font-bold text-text-primary",
262
- children: H.code
290
+ children: W.code
263
291
  })]
264
292
  }),
265
293
  /* @__PURE__ */ x("div", {
@@ -274,11 +302,11 @@ var O = () => {
274
302
  }),
275
303
  /* @__PURE__ */ b("p", {
276
304
  className: "text-lg font-bold text-text-primary",
277
- children: G()
305
+ children: J()
278
306
  }),
279
307
  /* @__PURE__ */ b("p", {
280
308
  className: "text-xs text-text-muted capitalize",
281
- children: H.type.replace("_", " ").toLowerCase()
309
+ children: W.type.replace("_", " ").toLowerCase()
282
310
  })
283
311
  ]
284
312
  }),
@@ -294,13 +322,13 @@ var O = () => {
294
322
  }),
295
323
  /* @__PURE__ */ x("p", {
296
324
  className: "text-lg font-bold text-text-primary",
297
- children: [H.currentUses, H.maxTotalUses ? ` / ${H.maxTotalUses}` : ""]
325
+ children: [W.currentUses, W.maxTotalUses ? ` / ${W.maxTotalUses}` : ""]
298
326
  }),
299
- U !== null && /* @__PURE__ */ b("div", {
327
+ G !== null && /* @__PURE__ */ b("div", {
300
328
  className: "mt-1.5 h-1.5 w-full bg-bg-sunken rounded-full overflow-hidden",
301
329
  children: /* @__PURE__ */ b("div", {
302
330
  className: "h-full bg-action-primary-bg rounded-full",
303
- style: { width: `${Math.min(U, 100)}%` }
331
+ style: { width: `${Math.min(G, 100)}%` }
304
332
  })
305
333
  })
306
334
  ]
@@ -317,11 +345,11 @@ var O = () => {
317
345
  }),
318
346
  /* @__PURE__ */ b("div", {
319
347
  className: "mt-1",
320
- children: /* @__PURE__ */ b(E, { status: H.status })
348
+ children: /* @__PURE__ */ b(O, { status: W.status })
321
349
  }),
322
- H.validUntil && /* @__PURE__ */ x("p", {
350
+ W.validUntil && /* @__PURE__ */ x("p", {
323
351
  className: "text-xs text-text-muted mt-1",
324
- children: ["Expires ", W(H.validUntil)]
352
+ children: ["Expires ", q(W.validUntil)]
325
353
  })
326
354
  ]
327
355
  })
@@ -336,36 +364,36 @@ var O = () => {
336
364
  className: "text-sm font-semibold text-text-primary uppercase tracking-wide mb-2",
337
365
  children: "Coupon Details"
338
366
  }),
339
- /* @__PURE__ */ b(D, {
367
+ /* @__PURE__ */ b(k, {
340
368
  label: "Code",
341
369
  value: /* @__PURE__ */ b("span", {
342
370
  className: "font-mono",
343
- children: H.code
371
+ children: W.code
344
372
  })
345
373
  }),
346
- /* @__PURE__ */ b(D, {
374
+ /* @__PURE__ */ b(k, {
347
375
  label: "Name",
348
- value: H.name
376
+ value: W.name
349
377
  }),
350
- /* @__PURE__ */ b(D, {
378
+ /* @__PURE__ */ b(k, {
351
379
  label: "Description",
352
- value: H.description
380
+ value: W.description
353
381
  }),
354
- /* @__PURE__ */ b(D, {
382
+ /* @__PURE__ */ b(k, {
355
383
  label: "Type",
356
- value: H.type.replace("_", " ").toLowerCase()
384
+ value: W.type.replace("_", " ").toLowerCase()
357
385
  }),
358
- /* @__PURE__ */ b(D, {
386
+ /* @__PURE__ */ b(k, {
359
387
  label: "Value",
360
- value: G()
388
+ value: J()
361
389
  }),
362
- /* @__PURE__ */ b(D, {
390
+ /* @__PURE__ */ b(k, {
363
391
  label: "Scope",
364
- value: H.scope
392
+ value: W.scope
365
393
  }),
366
- /* @__PURE__ */ b(D, {
394
+ /* @__PURE__ */ b(k, {
367
395
  label: "Status",
368
- value: /* @__PURE__ */ b(E, { status: H.status })
396
+ value: /* @__PURE__ */ b(O, { status: W.status })
369
397
  })
370
398
  ]
371
399
  }), /* @__PURE__ */ x("div", {
@@ -375,32 +403,32 @@ var O = () => {
375
403
  className: "text-sm font-semibold text-text-primary uppercase tracking-wide mb-2",
376
404
  children: "Restrictions"
377
405
  }),
378
- /* @__PURE__ */ b(D, {
406
+ /* @__PURE__ */ b(k, {
379
407
  label: "Min Purchase Amount",
380
- value: H.minPurchaseAmount == null ? null : `${H.minPurchaseAmount}${H.currency ? ` ${H.currency}` : ""}`
408
+ value: W.minPurchaseAmount == null ? null : `${W.minPurchaseAmount}${W.currency ? ` ${W.currency}` : ""}`
381
409
  }),
382
- /* @__PURE__ */ b(D, {
410
+ /* @__PURE__ */ b(k, {
383
411
  label: "Max Discount Amount",
384
- value: H.maxDiscountAmount == null ? null : `${H.maxDiscountAmount}${H.currency ? ` ${H.currency}` : ""}`
412
+ value: W.maxDiscountAmount == null ? null : `${W.maxDiscountAmount}${W.currency ? ` ${W.currency}` : ""}`
385
413
  }),
386
- /* @__PURE__ */ b(D, {
414
+ /* @__PURE__ */ b(k, {
387
415
  label: "Max Uses Per User",
388
- value: H.maxUsesPerUser
416
+ value: W.maxUsesPerUser
389
417
  }),
390
- /* @__PURE__ */ b(D, {
418
+ /* @__PURE__ */ b(k, {
391
419
  label: "Restricted Users",
392
- value: H.restrictedToUserIds?.length ? /* @__PURE__ */ b("span", {
420
+ value: W.restrictedToUserIds?.length ? /* @__PURE__ */ b("span", {
393
421
  className: "font-mono text-xs break-all",
394
- children: H.restrictedToUserIds.join(", ")
422
+ children: W.restrictedToUserIds.join(", ")
395
423
  }) : "No restrictions"
396
424
  }),
397
- /* @__PURE__ */ b(D, {
425
+ /* @__PURE__ */ b(k, {
398
426
  label: "Applicable Products",
399
- value: H.applicableProducts?.length ? H.applicableProducts.join(", ") : "All products"
427
+ value: W.applicableProducts?.length ? W.applicableProducts.join(", ") : "All products"
400
428
  }),
401
- /* @__PURE__ */ b(D, {
429
+ /* @__PURE__ */ b(k, {
402
430
  label: "Excluded Products",
403
- value: H.excludedProducts?.length ? H.excludedProducts.join(", ") : "None"
431
+ value: W.excludedProducts?.length ? W.excludedProducts.join(", ") : "None"
404
432
  })
405
433
  ]
406
434
  })]
@@ -415,33 +443,33 @@ var O = () => {
415
443
  className: "text-sm font-semibold text-text-primary uppercase tracking-wide mb-2",
416
444
  children: "Validity"
417
445
  }),
418
- /* @__PURE__ */ b(D, {
446
+ /* @__PURE__ */ b(k, {
419
447
  label: "Valid From",
420
- value: W(H.validFrom)
448
+ value: q(W.validFrom)
421
449
  }),
422
- /* @__PURE__ */ b(D, {
450
+ /* @__PURE__ */ b(k, {
423
451
  label: "Valid Until",
424
- value: W(H.validUntil) ?? "No expiry"
452
+ value: q(W.validUntil) ?? "No expiry"
425
453
  })
426
454
  ]
427
455
  }),
428
- H.campaignId && /* @__PURE__ */ x("div", {
456
+ W.campaignId && /* @__PURE__ */ x("div", {
429
457
  className: "bg-bg-surface border border-border-subtle rounded-lg p-6",
430
458
  children: [
431
459
  /* @__PURE__ */ b("h3", {
432
460
  className: "text-sm font-semibold text-text-primary uppercase tracking-wide mb-2",
433
461
  children: "Campaign"
434
462
  }),
435
- /* @__PURE__ */ b(D, {
463
+ /* @__PURE__ */ b(k, {
436
464
  label: "Campaign ID",
437
465
  value: /* @__PURE__ */ b("span", {
438
466
  className: "font-mono text-xs",
439
- children: H.campaignId
467
+ children: W.campaignId
440
468
  })
441
469
  }),
442
- /* @__PURE__ */ b(D, {
470
+ /* @__PURE__ */ b(k, {
443
471
  label: "Campaign Name",
444
- value: H.campaignName
472
+ value: W.campaignName
445
473
  })
446
474
  ]
447
475
  }),
@@ -452,17 +480,17 @@ var O = () => {
452
480
  className: "text-sm font-semibold text-text-primary uppercase tracking-wide mb-2",
453
481
  children: [/* @__PURE__ */ b(g, { className: "size-4 inline mr-1" }), "Audit"]
454
482
  }),
455
- /* @__PURE__ */ b(D, {
483
+ /* @__PURE__ */ b(k, {
456
484
  label: "Created",
457
- value: W(H.createdAt)
485
+ value: q(W.createdAt)
458
486
  }),
459
- /* @__PURE__ */ b(D, {
487
+ /* @__PURE__ */ b(k, {
460
488
  label: "Last Updated",
461
- value: W(H.updatedAt)
489
+ value: q(W.updatedAt)
462
490
  }),
463
- /* @__PURE__ */ b(D, {
491
+ /* @__PURE__ */ b(k, {
464
492
  label: "Created By",
465
- value: H.createdBy ?? null
493
+ value: W.createdBy ?? null
466
494
  })
467
495
  ]
468
496
  })
@@ -474,6 +502,6 @@ var O = () => {
474
502
  });
475
503
  };
476
504
  //#endregion
477
- export { O as CouponDetailPage };
505
+ export { A as CouponDetailPage };
478
506
 
479
507
  //# sourceMappingURL=CouponDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CouponDetailPage.js","names":[],"sources":["../../../../../src/billing/modules/coupons/pages/CouponDetailPage.tsx"],"sourcesContent":["import { type FC, useEffect, useState } from 'react';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport {\n ArrowLeft,\n Edit,\n Tag,\n Calendar,\n Users,\n Package,\n BarChart2,\n History,\n ChevronLeft,\n ChevronRight,\n} from 'lucide-react';\nimport { CTAOverflowMenu } from '@burdenoff/fe-libs/ui';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { AccessDenied, PageHeader } from '../../../shared/components';\nimport {\n useGetCouponLazyQuery,\n useGetCouponUsageHistoryQuery,\n} from '../../../../generated/global-operations';\nimport { Coupon, CouponStatus, CouponUsage } from '../../../../generated/global-types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ResponsiveTable, type ResponsiveTableColumn } from '@burdenoff/fe-libs/ui';\n\nconst couponUsageColumns: ResponsiveTableColumn<CouponUsage>[] = [\n {\n key: 'userId',\n header: 'User ID',\n priority: 'primary',\n cell: (u) => <span className=\"font-mono\">{u.userId.slice(0, 12)}…</span>,\n },\n {\n key: 'transaction',\n header: 'Transaction',\n cell: (u) =>\n u.transactionId ? (\n <span className=\"font-mono text-xs text-text-link\">{u.transactionId.slice(0, 12)}…</span>\n ) : u.orderId ? (\n <span className=\"text-xs text-text-muted\">Order: {u.orderId.slice(0, 12)}…</span>\n ) : (\n <span className=\"text-text-muted\">, </span>\n ),\n },\n {\n key: 'original',\n header: 'Original',\n cell: (u) => (\n <span className=\"tabular-nums\">\n {u.originalAmount.toFixed(2)} {u.currency}\n </span>\n ),\n },\n {\n key: 'discount',\n header: 'Discount',\n cell: (u) => (\n <span className=\"tabular-nums text-status-success-text font-medium\">\n -{u.discountValue.toFixed(2)} {u.currency}\n </span>\n ),\n },\n {\n key: 'final',\n header: 'Final',\n cell: (u) => (\n <span className=\"tabular-nums font-medium\">\n {u.finalAmount.toFixed(2)} {u.currency}\n </span>\n ),\n },\n {\n key: 'usedAt',\n header: 'Used At',\n cell: (u) => new Date(u.usedAt).toLocaleString(),\n },\n];\n\nfunction StatusBadge({ status }: { status: CouponStatus }) {\n const map: Record<CouponStatus, { label: string; className: string }> = {\n [CouponStatus.Active]: {\n label: 'Active',\n className:\n 'bg-status-success-bg-subtle text-status-success-text border-status-success-bg-subtle',\n },\n [CouponStatus.Inactive]: {\n label: 'Inactive',\n className: 'bg-bg-sunken text-text-muted border-border-subtle',\n },\n [CouponStatus.Expired]: {\n label: 'Expired',\n className:\n 'bg-status-warning-bg-subtle text-status-warning-text border-status-warning-bg-subtle',\n },\n [CouponStatus.Depleted]: {\n label: 'Depleted',\n className: 'bg-status-error-bg-subtle text-status-error-text border-status-error-border',\n },\n };\n const { label, className } = map[status] ?? {\n label: status,\n className: 'bg-bg-sunken text-text-muted',\n };\n return (\n <span\n className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border ${className}`}\n >\n {label}\n </span>\n );\n}\n\nfunction DetailRow({ label, value }: { label: string; value: React.ReactNode }) {\n return (\n <div className=\"flex items-start gap-2 py-3 border-b border-border-subtle last:border-0\">\n <span className=\"text-sm text-text-muted w-44 shrink-0\">{label}</span>\n <span className=\"text-sm text-text-primary font-medium flex-1\">{value ?? '—'}</span>\n </div>\n );\n}\n\nexport const CouponDetailPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const navigateTo = useBillingNavigate();\n const permissions = useBillingPermissions();\n\n const couponId = window.location.pathname.split('/').filter(Boolean).slice(-1)[0];\n const [activeTab, setActiveTab] = useState<'details' | 'usage'>('details');\n const [usagePage, setUsagePage] = useState(0);\n const USAGE_PAGE_SIZE = 20;\n\n const [getCoupon, { data, loading, error }] = useGetCouponLazyQuery();\n\n const { data: usageData, loading: usageLoading } = useGetCouponUsageHistoryQuery({\n variables: { couponId, limit: USAGE_PAGE_SIZE, offset: usagePage * USAGE_PAGE_SIZE },\n skip: !couponId || activeTab !== 'usage',\n });\n\n useEffect(() => {\n if (couponId) {\n getCoupon({ variables: { id: couponId } });\n }\n }, [couponId, getCoupon]);\n\n if (!permissions.canManageDiscounts) {\n return <AccessDenied message=\"You don't have permission to view coupon details.\" />;\n }\n\n if (loading) {\n return (\n <div className=\"p-8\">\n <PageHeader\n title={tr('billing.coupons.detailTitle', 'Coupon Details')}\n description=\"Loading...\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/coupons')}\n className=\"px-4 py-2 rounded-lg border border-border-subtle text-text-primary hover:bg-bg-sunken flex items-center gap-2\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n }\n />\n <div className=\"flex items-center justify-center h-64\">\n <div className=\"size-8 animate-spin rounded-full border-4 border-action-primary-bg border-t-transparent\" />\n </div>\n </div>\n );\n }\n\n if (error || !data?.getCoupon) {\n return (\n <div className=\"p-8\">\n <PageHeader\n title=\"Coupon Details\"\n description=\"Coupon not found\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/coupons')}\n className=\"px-4 py-2 rounded-lg border border-border-subtle text-text-primary hover:bg-bg-sunken flex items-center gap-2\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n }\n />\n <div className=\"flex items-center justify-center h-64 text-status-error-text text-sm\">\n {error ? `Error: ${error.message}` : 'Coupon not found'}\n </div>\n </div>\n );\n }\n\n const coupon = data.getCoupon as Coupon;\n const usagePercent =\n coupon.maxTotalUses && coupon.maxTotalUses > 0\n ? Math.round((coupon.currentUses / coupon.maxTotalUses) * 100)\n : null;\n\n const formatDate = (d: string | null | undefined) =>\n d\n ? new Date(d).toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })\n : null;\n\n const formatValue = () =>\n coupon.type === 'PERCENTAGE'\n ? `${coupon.value}%`\n : `${coupon.value}${coupon.currency ? ` ${coupon.currency}` : ''}`;\n\n return (\n <div className=\"p-8\">\n <PageHeader\n title={coupon.name || coupon.code}\n description={coupon.description || `Coupon code: ${coupon.code}`}\n actions={\n <CTAOverflowMenu\n primary={{\n label: 'Edit',\n onSelect: () => navigateTo(`/coupons/${coupon.id}/edit`),\n icon: <Edit className=\"size-4\" />,\n }}\n actions={[\n {\n label: 'Back to coupons',\n onSelect: () => navigateTo('/coupons'),\n icon: <ArrowLeft className=\"size-4\" />,\n },\n ]}\n />\n }\n />\n\n {/* Tabs */}\n <div className=\"mt-6 border-b border-border-subtle flex gap-1\">\n {(['details', 'usage'] as const).map((tab) => (\n <button\n type=\"button\"\n key={tab}\n onClick={() => setActiveTab(tab)}\n className={`flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${\n activeTab === tab\n ? 'border-action-primary-bg text-text-primary'\n : 'border-transparent text-text-muted hover:text-text-primary'\n }`}\n >\n {tab === 'details' ? <Tag className=\"size-4\" /> : <History className=\"size-4\" />}\n {tab === 'details'\n ? 'Details'\n : `Usage History${usageData ? ` (${usageData.getCouponUsageHistory.total})` : ''}`}\n </button>\n ))}\n </div>\n\n {activeTab === 'usage' && (\n <div className=\"mt-6 bg-bg-surface border border-border-subtle rounded-lg overflow-hidden\">\n {usageLoading ? (\n <div className=\"flex items-center justify-center h-40\">\n <div className=\"size-6 animate-spin rounded-full border-4 border-action-primary-bg border-t-transparent\" />\n </div>\n ) : !usageData?.getCouponUsageHistory.usages.length ? (\n <div className=\"p-8 text-center text-sm text-text-muted\">\n No usage recorded for this coupon yet.\n </div>\n ) : (\n <>\n <ResponsiveTable\n data={usageData.getCouponUsageHistory.usages}\n rowKey={(u) => u.id}\n columns={couponUsageColumns}\n />\n {(usageData.getCouponUsageHistory.total ?? 0) > USAGE_PAGE_SIZE && (\n <div className=\"flex items-center justify-between p-4 border-t border-border-subtle\">\n <p className=\"text-sm text-text-muted\">\n {usagePage * USAGE_PAGE_SIZE + 1}–\n {Math.min(\n (usagePage + 1) * USAGE_PAGE_SIZE,\n usageData.getCouponUsageHistory.total\n )}{' '}\n of {usageData.getCouponUsageHistory.total}\n </p>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setUsagePage((p) => Math.max(0, p - 1))}\n disabled={usagePage === 0}\n className=\"p-1.5 rounded border border-border-subtle hover:bg-bg-sunken disabled:opacity-40\"\n >\n <ChevronLeft className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setUsagePage((p) => p + 1)}\n disabled={!usageData.getCouponUsageHistory.hasMore}\n className=\"p-1.5 rounded border border-border-subtle hover:bg-bg-sunken disabled:opacity-40\"\n >\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n )}\n\n {activeTab === 'details' && (\n <div className=\"mt-8 grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Summary cards */}\n <div className=\"lg:col-span-3 grid grid-cols-2 sm:grid-cols-4 gap-4\">\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-text-muted mb-1\">\n <Tag className=\"size-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Code</span>\n </div>\n <p className=\"text-lg font-mono font-bold text-text-primary\">{coupon.code}</p>\n </div>\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-text-muted mb-1\">\n <BarChart2 className=\"size-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Discount</span>\n </div>\n <p className=\"text-lg font-bold text-text-primary\">{formatValue()}</p>\n <p className=\"text-xs text-text-muted capitalize\">\n {coupon.type.replace('_', ' ').toLowerCase()}\n </p>\n </div>\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-text-muted mb-1\">\n <Users className=\"size-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Usage</span>\n </div>\n <p className=\"text-lg font-bold text-text-primary\">\n {coupon.currentUses}\n {coupon.maxTotalUses ? ` / ${coupon.maxTotalUses}` : ''}\n </p>\n {usagePercent !== null && (\n <div className=\"mt-1.5 h-1.5 w-full bg-bg-sunken rounded-full overflow-hidden\">\n <div\n className=\"h-full bg-action-primary-bg rounded-full\"\n style={{ width: `${Math.min(usagePercent, 100)}%` }}\n />\n </div>\n )}\n </div>\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-text-muted mb-1\">\n <Calendar className=\"size-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Status</span>\n </div>\n <div className=\"mt-1\">\n <StatusBadge status={coupon.status} />\n </div>\n {coupon.validUntil && (\n <p className=\"text-xs text-text-muted mt-1\">\n Expires {formatDate(coupon.validUntil)}\n </p>\n )}\n </div>\n </div>\n\n {/* Main details */}\n <div className=\"lg:col-span-2 space-y-4\">\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n Coupon Details\n </h3>\n <DetailRow label=\"Code\" value={<span className=\"font-mono\">{coupon.code}</span>} />\n <DetailRow label=\"Name\" value={coupon.name} />\n <DetailRow label=\"Description\" value={coupon.description} />\n <DetailRow label=\"Type\" value={coupon.type.replace('_', ' ').toLowerCase()} />\n <DetailRow label=\"Value\" value={formatValue()} />\n <DetailRow label=\"Scope\" value={coupon.scope} />\n <DetailRow label=\"Status\" value={<StatusBadge status={coupon.status} />} />\n </div>\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n Restrictions\n </h3>\n <DetailRow\n label=\"Min Purchase Amount\"\n value={\n coupon.minPurchaseAmount != null\n ? `${coupon.minPurchaseAmount}${coupon.currency ? ` ${coupon.currency}` : ''}`\n : null\n }\n />\n <DetailRow\n label=\"Max Discount Amount\"\n value={\n coupon.maxDiscountAmount != null\n ? `${coupon.maxDiscountAmount}${coupon.currency ? ` ${coupon.currency}` : ''}`\n : null\n }\n />\n <DetailRow label=\"Max Uses Per User\" value={coupon.maxUsesPerUser} />\n <DetailRow\n label=\"Restricted Users\"\n value={\n coupon.restrictedToUserIds?.length ? (\n <span className=\"font-mono text-xs break-all\">\n {(coupon.restrictedToUserIds as string[]).join(', ')}\n </span>\n ) : (\n 'No restrictions'\n )\n }\n />\n <DetailRow\n label=\"Applicable Products\"\n value={\n coupon.applicableProducts?.length\n ? (coupon.applicableProducts as string[]).join(', ')\n : 'All products'\n }\n />\n <DetailRow\n label=\"Excluded Products\"\n value={\n coupon.excludedProducts?.length\n ? (coupon.excludedProducts as string[]).join(', ')\n : 'None'\n }\n />\n </div>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-4\">\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n Validity\n </h3>\n <DetailRow label=\"Valid From\" value={formatDate(coupon.validFrom)} />\n <DetailRow label=\"Valid Until\" value={formatDate(coupon.validUntil) ?? 'No expiry'} />\n </div>\n\n {coupon.campaignId && (\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n Campaign\n </h3>\n <DetailRow\n label=\"Campaign ID\"\n value={<span className=\"font-mono text-xs\">{coupon.campaignId}</span>}\n />\n <DetailRow label=\"Campaign Name\" value={coupon.campaignName} />\n </div>\n )}\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n <Package className=\"size-4 inline mr-1\" />\n Audit\n </h3>\n <DetailRow label=\"Created\" value={formatDate(coupon.createdAt)} />\n <DetailRow label=\"Last Updated\" value={formatDate(coupon.updatedAt)} />\n <DetailRow label=\"Created By\" value={coupon.createdBy ?? null} />\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"CouponDetailPage.js","names":[],"sources":["../../../../../src/billing/modules/coupons/pages/CouponDetailPage.tsx"],"sourcesContent":["import { type FC, useEffect, useState } from 'react';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport {\n ArrowLeft,\n Edit,\n Tag,\n Calendar,\n Users,\n Package,\n BarChart2,\n History,\n ChevronLeft,\n ChevronRight,\n} from 'lucide-react';\nimport { CTAOverflowMenu } from '@burdenoff/fe-libs/ui';\nimport { useBillingPermissions } from '../../../hooks/useBillingPermissions';\nimport { AccessDenied, PageHeader } from '../../../shared/components';\nimport {\n useGetCouponLazyQuery,\n useGetCouponUsageHistoryQuery,\n} from '../../../../generated/global-operations';\nimport { Coupon, CouponStatus, CouponUsage } from '../../../../generated/global-types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n ResponsiveTable,\n type ResponsiveTableColumn,\n PagePurpose,\n NextSteps,\n type NextStep,\n} from '@burdenoff/fe-libs/ui';\n\nconst couponUsageColumns: ResponsiveTableColumn<CouponUsage>[] = [\n {\n key: 'userId',\n header: 'User ID',\n priority: 'primary',\n cell: (u) => <span className=\"font-mono\">{u.userId.slice(0, 12)}…</span>,\n },\n {\n key: 'transaction',\n header: 'Transaction',\n cell: (u) =>\n u.transactionId ? (\n <span className=\"font-mono text-xs text-text-link\">{u.transactionId.slice(0, 12)}…</span>\n ) : u.orderId ? (\n <span className=\"text-xs text-text-muted\">Order: {u.orderId.slice(0, 12)}…</span>\n ) : (\n <span className=\"text-text-muted\">, </span>\n ),\n },\n {\n key: 'original',\n header: 'Original',\n cell: (u) => (\n <span className=\"tabular-nums\">\n {u.originalAmount.toFixed(2)} {u.currency}\n </span>\n ),\n },\n {\n key: 'discount',\n header: 'Discount',\n cell: (u) => (\n <span className=\"tabular-nums text-status-success-text font-medium\">\n -{u.discountValue.toFixed(2)} {u.currency}\n </span>\n ),\n },\n {\n key: 'final',\n header: 'Final',\n cell: (u) => (\n <span className=\"tabular-nums font-medium\">\n {u.finalAmount.toFixed(2)} {u.currency}\n </span>\n ),\n },\n {\n key: 'usedAt',\n header: 'Used At',\n cell: (u) => new Date(u.usedAt).toLocaleString(),\n },\n];\n\nfunction StatusBadge({ status }: { status: CouponStatus }) {\n const map: Record<CouponStatus, { label: string; className: string }> = {\n [CouponStatus.Active]: {\n label: 'Active',\n className:\n 'bg-status-success-bg-subtle text-status-success-text border-status-success-bg-subtle',\n },\n [CouponStatus.Inactive]: {\n label: 'Inactive',\n className: 'bg-bg-sunken text-text-muted border-border-subtle',\n },\n [CouponStatus.Expired]: {\n label: 'Expired',\n className:\n 'bg-status-warning-bg-subtle text-status-warning-text border-status-warning-bg-subtle',\n },\n [CouponStatus.Depleted]: {\n label: 'Depleted',\n className: 'bg-status-error-bg-subtle text-status-error-text border-status-error-border',\n },\n };\n const { label, className } = map[status] ?? {\n label: status,\n className: 'bg-bg-sunken text-text-muted',\n };\n return (\n <span\n className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium border ${className}`}\n >\n {label}\n </span>\n );\n}\n\nfunction DetailRow({ label, value }: { label: string; value: React.ReactNode }) {\n return (\n <div className=\"flex items-start gap-2 py-3 border-b border-border-subtle last:border-0\">\n <span className=\"text-sm text-text-muted w-44 shrink-0\">{label}</span>\n <span className=\"text-sm text-text-primary font-medium flex-1\">{value ?? '—'}</span>\n </div>\n );\n}\n\nexport const CouponDetailPage: FC = () => {\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n const navigateTo = useBillingNavigate();\n const permissions = useBillingPermissions();\n\n const couponId = window.location.pathname.split('/').filter(Boolean).slice(-1)[0];\n const [activeTab, setActiveTab] = useState<'details' | 'usage'>('details');\n const [usagePage, setUsagePage] = useState(0);\n const USAGE_PAGE_SIZE = 20;\n\n const [getCoupon, { data, loading, error }] = useGetCouponLazyQuery();\n\n const { data: usageData, loading: usageLoading } = useGetCouponUsageHistoryQuery({\n variables: { couponId, limit: USAGE_PAGE_SIZE, offset: usagePage * USAGE_PAGE_SIZE },\n skip: !couponId || activeTab !== 'usage',\n });\n\n useEffect(() => {\n if (couponId) {\n getCoupon({ variables: { id: couponId } });\n }\n }, [couponId, getCoupon]);\n\n if (!permissions.canManageDiscounts) {\n return <AccessDenied message=\"You don't have permission to view coupon details.\" />;\n }\n\n if (loading) {\n return (\n <div className=\"p-8\">\n <PageHeader\n title={tr('billing.coupons.detailTitle', 'Coupon Details')}\n description=\"Loading...\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/coupons')}\n className=\"px-4 py-2 rounded-lg border border-border-subtle text-text-primary hover:bg-bg-sunken flex items-center gap-2\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n }\n />\n <div className=\"flex items-center justify-center h-64\">\n <div className=\"size-8 animate-spin rounded-full border-4 border-action-primary-bg border-t-transparent\" />\n </div>\n </div>\n );\n }\n\n if (error || !data?.getCoupon) {\n return (\n <div className=\"p-8\">\n <PageHeader\n title=\"Coupon Details\"\n description=\"Coupon not found\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/coupons')}\n className=\"px-4 py-2 rounded-lg border border-border-subtle text-text-primary hover:bg-bg-sunken flex items-center gap-2\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n }\n />\n <div className=\"flex items-center justify-center h-64 text-status-error-text text-sm\">\n {error ? `Error: ${error.message}` : 'Coupon not found'}\n </div>\n </div>\n );\n }\n\n const coupon = data.getCoupon as Coupon;\n const usagePercent =\n coupon.maxTotalUses && coupon.maxTotalUses > 0\n ? Math.round((coupon.currentUses / coupon.maxTotalUses) * 100)\n : null;\n\n const nextSteps: NextStep[] = [\n {\n id: 'edit',\n label: 'Edit this coupon',\n description: 'Adjust the discount, limits, expiry or applicable products.',\n onClick: () => navigateTo(`/coupons/${coupon.id}/edit`),\n },\n {\n id: 'usage',\n label: 'Review who has redeemed it',\n description: 'Open the Usage History tab to see every redemption.',\n onClick: () => setActiveTab('usage'),\n },\n {\n id: 'back',\n label: 'Manage all coupons',\n description: 'Return to the full list of discount codes.',\n onClick: () => navigateTo('/coupons'),\n },\n ];\n\n const formatDate = (d: string | null | undefined) =>\n d\n ? new Date(d).toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n })\n : null;\n\n const formatValue = () =>\n coupon.type === 'PERCENTAGE'\n ? `${coupon.value}%`\n : `${coupon.value}${coupon.currency ? ` ${coupon.currency}` : ''}`;\n\n return (\n <div className=\"p-8\">\n <PageHeader\n title={coupon.name || coupon.code}\n description={coupon.description || `Coupon code: ${coupon.code}`}\n actions={\n <CTAOverflowMenu\n primary={{\n label: 'Edit',\n onSelect: () => navigateTo(`/coupons/${coupon.id}/edit`),\n icon: <Edit className=\"size-4\" />,\n }}\n actions={[\n {\n label: 'Back to coupons',\n onSelect: () => navigateTo('/coupons'),\n icon: <ArrowLeft className=\"size-4\" />,\n },\n ]}\n />\n }\n />\n\n <PagePurpose className=\"mt-2\">\n Everything about this coupon — its discount, validity window, usage limits and the full\n redemption history. Use it to check how it is performing, edit its terms, or stop it being\n redeemed.\n </PagePurpose>\n\n <NextSteps storageKey=\"billing-coupon-detail\" steps={nextSteps} className=\"mt-4\" />\n\n {/* Tabs */}\n <div className=\"mt-6 border-b border-border-subtle flex gap-1\">\n {(['details', 'usage'] as const).map((tab) => (\n <button\n type=\"button\"\n key={tab}\n onClick={() => setActiveTab(tab)}\n className={`flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${\n activeTab === tab\n ? 'border-action-primary-bg text-text-primary'\n : 'border-transparent text-text-muted hover:text-text-primary'\n }`}\n >\n {tab === 'details' ? <Tag className=\"size-4\" /> : <History className=\"size-4\" />}\n {tab === 'details'\n ? 'Details'\n : `Usage History${usageData ? ` (${usageData.getCouponUsageHistory.total})` : ''}`}\n </button>\n ))}\n </div>\n\n {activeTab === 'usage' && (\n <div className=\"mt-6 bg-bg-surface border border-border-subtle rounded-lg overflow-hidden\">\n {usageLoading ? (\n <div className=\"flex items-center justify-center h-40\">\n <div className=\"size-6 animate-spin rounded-full border-4 border-action-primary-bg border-t-transparent\" />\n </div>\n ) : !usageData?.getCouponUsageHistory.usages.length ? (\n <div className=\"p-8 text-center text-sm text-text-muted\">\n No usage recorded for this coupon yet.\n </div>\n ) : (\n <>\n <ResponsiveTable\n data={usageData.getCouponUsageHistory.usages}\n rowKey={(u) => u.id}\n columns={couponUsageColumns}\n />\n {(usageData.getCouponUsageHistory.total ?? 0) > USAGE_PAGE_SIZE && (\n <div className=\"flex items-center justify-between p-4 border-t border-border-subtle\">\n <p className=\"text-sm text-text-muted\">\n {usagePage * USAGE_PAGE_SIZE + 1}–\n {Math.min(\n (usagePage + 1) * USAGE_PAGE_SIZE,\n usageData.getCouponUsageHistory.total\n )}{' '}\n of {usageData.getCouponUsageHistory.total}\n </p>\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setUsagePage((p) => Math.max(0, p - 1))}\n disabled={usagePage === 0}\n className=\"p-1.5 rounded border border-border-subtle hover:bg-bg-sunken disabled:opacity-40\"\n >\n <ChevronLeft className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => setUsagePage((p) => p + 1)}\n disabled={!usageData.getCouponUsageHistory.hasMore}\n className=\"p-1.5 rounded border border-border-subtle hover:bg-bg-sunken disabled:opacity-40\"\n >\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n </div>\n )}\n </>\n )}\n </div>\n )}\n\n {activeTab === 'details' && (\n <div className=\"mt-8 grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Summary cards */}\n <div className=\"lg:col-span-3 grid grid-cols-2 sm:grid-cols-4 gap-4\">\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-text-muted mb-1\">\n <Tag className=\"size-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Code</span>\n </div>\n <p className=\"text-lg font-mono font-bold text-text-primary\">{coupon.code}</p>\n </div>\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-text-muted mb-1\">\n <BarChart2 className=\"size-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Discount</span>\n </div>\n <p className=\"text-lg font-bold text-text-primary\">{formatValue()}</p>\n <p className=\"text-xs text-text-muted capitalize\">\n {coupon.type.replace('_', ' ').toLowerCase()}\n </p>\n </div>\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-text-muted mb-1\">\n <Users className=\"size-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Usage</span>\n </div>\n <p className=\"text-lg font-bold text-text-primary\">\n {coupon.currentUses}\n {coupon.maxTotalUses ? ` / ${coupon.maxTotalUses}` : ''}\n </p>\n {usagePercent !== null && (\n <div className=\"mt-1.5 h-1.5 w-full bg-bg-sunken rounded-full overflow-hidden\">\n <div\n className=\"h-full bg-action-primary-bg rounded-full\"\n style={{ width: `${Math.min(usagePercent, 100)}%` }}\n />\n </div>\n )}\n </div>\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-text-muted mb-1\">\n <Calendar className=\"size-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Status</span>\n </div>\n <div className=\"mt-1\">\n <StatusBadge status={coupon.status} />\n </div>\n {coupon.validUntil && (\n <p className=\"text-xs text-text-muted mt-1\">\n Expires {formatDate(coupon.validUntil)}\n </p>\n )}\n </div>\n </div>\n\n {/* Main details */}\n <div className=\"lg:col-span-2 space-y-4\">\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n Coupon Details\n </h3>\n <DetailRow label=\"Code\" value={<span className=\"font-mono\">{coupon.code}</span>} />\n <DetailRow label=\"Name\" value={coupon.name} />\n <DetailRow label=\"Description\" value={coupon.description} />\n <DetailRow label=\"Type\" value={coupon.type.replace('_', ' ').toLowerCase()} />\n <DetailRow label=\"Value\" value={formatValue()} />\n <DetailRow label=\"Scope\" value={coupon.scope} />\n <DetailRow label=\"Status\" value={<StatusBadge status={coupon.status} />} />\n </div>\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n Restrictions\n </h3>\n <DetailRow\n label=\"Min Purchase Amount\"\n value={\n coupon.minPurchaseAmount != null\n ? `${coupon.minPurchaseAmount}${coupon.currency ? ` ${coupon.currency}` : ''}`\n : null\n }\n />\n <DetailRow\n label=\"Max Discount Amount\"\n value={\n coupon.maxDiscountAmount != null\n ? `${coupon.maxDiscountAmount}${coupon.currency ? ` ${coupon.currency}` : ''}`\n : null\n }\n />\n <DetailRow label=\"Max Uses Per User\" value={coupon.maxUsesPerUser} />\n <DetailRow\n label=\"Restricted Users\"\n value={\n coupon.restrictedToUserIds?.length ? (\n <span className=\"font-mono text-xs break-all\">\n {(coupon.restrictedToUserIds as string[]).join(', ')}\n </span>\n ) : (\n 'No restrictions'\n )\n }\n />\n <DetailRow\n label=\"Applicable Products\"\n value={\n coupon.applicableProducts?.length\n ? (coupon.applicableProducts as string[]).join(', ')\n : 'All products'\n }\n />\n <DetailRow\n label=\"Excluded Products\"\n value={\n coupon.excludedProducts?.length\n ? (coupon.excludedProducts as string[]).join(', ')\n : 'None'\n }\n />\n </div>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-4\">\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n Validity\n </h3>\n <DetailRow label=\"Valid From\" value={formatDate(coupon.validFrom)} />\n <DetailRow label=\"Valid Until\" value={formatDate(coupon.validUntil) ?? 'No expiry'} />\n </div>\n\n {coupon.campaignId && (\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n Campaign\n </h3>\n <DetailRow\n label=\"Campaign ID\"\n value={<span className=\"font-mono text-xs\">{coupon.campaignId}</span>}\n />\n <DetailRow label=\"Campaign Name\" value={coupon.campaignName} />\n </div>\n )}\n\n <div className=\"bg-bg-surface border border-border-subtle rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-text-primary uppercase tracking-wide mb-2\">\n <Package className=\"size-4 inline mr-1\" />\n Audit\n </h3>\n <DetailRow label=\"Created\" value={formatDate(coupon.createdAt)} />\n <DetailRow label=\"Last Updated\" value={formatDate(coupon.updatedAt)} />\n <DetailRow label=\"Created By\" value={coupon.createdBy ?? null} />\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}