@burdenoff/microfe-billing 2026.526.1 → 2026.528.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.
- package/dist/billing/BillingAdminRoutes.js +1 -1
- package/dist/billing/BillingAdminRoutes.js.map +1 -1
- package/dist/billing/BillingUserRoutes.js +1 -1
- package/dist/billing/BillingUserRoutes.js.map +1 -1
- package/dist/billing/modules/addons/components/FloatingCartDrawer.js +15 -8
- package/dist/billing/modules/addons/components/FloatingCartDrawer.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +13 -6
- package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonCreatePage.js +1 -1
- package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonDetailPage.js +8 -4
- package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonEditPage.js +3 -2
- package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +44 -23
- package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonsListPage.js +60 -31
- package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
- package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +9 -9
- package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
- package/dist/billing/modules/analytics/pages/AnalyticsPage.js +8 -8
- package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +16 -10
- package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoicesListPage.js +24 -16
- package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +5 -1
- package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/RefundsPage.js +46 -29
- package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/TransactionsPage.js +34 -22
- package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
- package/dist/billing/modules/checkout/components/BillingAccountSelector.js +10 -10
- package/dist/billing/modules/checkout/components/BillingAccountSelector.js.map +1 -1
- package/dist/billing/modules/checkout/components/CreditsAmountInput.js +3 -3
- package/dist/billing/modules/checkout/components/CreditsAmountInput.js.map +1 -1
- package/dist/billing/modules/checkout/components/NativeCheckoutView.js +7 -0
- package/dist/billing/modules/checkout/components/NativeCheckoutView.js.map +1 -1
- package/dist/billing/modules/checkout/components/OrderSummary.js +13 -13
- package/dist/billing/modules/checkout/components/OrderSummary.js.map +1 -1
- package/dist/billing/modules/checkout/components/PromoCodeInput.js +5 -5
- package/dist/billing/modules/checkout/components/PromoCodeInput.js.map +1 -1
- package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js +5 -5
- package/dist/billing/modules/checkout/components/RazorpayPaymentButton.js.map +1 -1
- package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js +4 -4
- package/dist/billing/modules/checkout/components/SimpleAutoPayToggle.js.map +1 -1
- package/dist/billing/modules/checkout/components/StripePaymentForm.js +11 -11
- package/dist/billing/modules/checkout/components/StripePaymentForm.js.map +1 -1
- package/dist/billing/modules/checkout/components/SubscriptionSelector.js +3 -3
- package/dist/billing/modules/checkout/components/SubscriptionSelector.js.map +1 -1
- package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js +8 -8
- package/dist/billing/modules/checkout/components/UnifiedPaymentMethodSelector.js.map +1 -1
- package/dist/billing/modules/checkout/pages/CheckoutPage.js +61 -52
- package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CouponDetailPage.js +22 -15
- package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CouponsListPage.js +30 -21
- package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CreateCouponPage.js +9 -8
- package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/EditCouponPage.js +11 -8
- package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/AdminCreditsPage.js +1 -1
- package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +22 -17
- package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +15 -8
- package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditsPage.js +17 -11
- package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
- package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js +15 -11
- package/dist/billing/modules/dashboard/components/ActiveSubscriptionCard.js.map +1 -1
- package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js +21 -17
- package/dist/billing/modules/dashboard/components/AddPaymentMethodModal.js.map +1 -1
- package/dist/billing/modules/dashboard/components/BillingAccountCard.js +14 -11
- package/dist/billing/modules/dashboard/components/BillingAccountCard.js.map +1 -1
- package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js +32 -26
- package/dist/billing/modules/dashboard/components/CreateBillingAccountModal.js.map +1 -1
- package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js +14 -10
- package/dist/billing/modules/dashboard/components/PaymentMethodsSection.js.map +1 -1
- package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js +18 -11
- package/dist/billing/modules/dashboard/components/RecommendedAddonsSection.js.map +1 -1
- package/dist/billing/modules/dashboard/pages/OverviewPage.js +44 -32
- package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
- package/dist/billing/modules/discounts/pages/DiscountsListPage.js +35 -26
- package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
- package/dist/billing/modules/earnings/pages/EarningsPage.js +15 -15
- package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
- package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +11 -11
- package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
- package/dist/billing/modules/earnings/pages/PayoutsPage.js +5 -5
- package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +9 -4
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanCreatePage.js +1 -1
- package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanDetailPage.js +13 -8
- package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanEditPage.js +3 -2
- package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansBrowsePage.js +14 -7
- package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansListPage.js +23 -9
- package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaPage.js +11 -7
- package/dist/billing/modules/quota/pages/QuotaPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +3 -3
- package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +6 -2
- package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +5 -4
- package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +26 -12
- package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
- package/dist/billing/modules/settings/pages/SettingsPage.js +356 -349
- package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
- package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +157 -123
- package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js +13 -8
- package/dist/billing/modules/subscriptions/components/ManageSeatsModal.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +15 -7
- package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +30 -20
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +25 -16
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
- package/dist/billing/modules/usage/pages/UsagePage.js +50 -34
- package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
- package/dist/billing/shared/components/AccessDenied.js +2 -2
- package/dist/billing/shared/components/AccessDenied.js.map +1 -1
- package/dist/billing/shared/components/ActorIdentity.js +67 -0
- package/dist/billing/shared/components/ActorIdentity.js.map +1 -0
- package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js +6 -2
- package/dist/billing/shared/components/CurrencyPriceOverridesEditor.js.map +1 -1
- package/dist/billing/shared/components/EmptyState.js +7 -21
- package/dist/billing/shared/components/EmptyState.js.map +1 -1
- package/dist/billing/shared/components/PageHeader.js +7 -19
- package/dist/billing/shared/components/PageHeader.js.map +1 -1
- package/dist/billing/shared/components/ServerError.js +5 -4
- package/dist/billing/shared/components/ServerError.js.map +1 -1
- package/dist/billing/shared/components/index.js +1 -0
- package/dist/billing/shared/hooks/index.js +1 -0
- package/dist/billing/shared/hooks/useActorProfiles.js +113 -0
- package/dist/billing/shared/hooks/useActorProfiles.js.map +1 -0
- package/package.json +2 -2
|
@@ -70,13 +70,14 @@ var T = () => {
|
|
|
70
70
|
title: T("billing.coupons.detailTitle", "Coupon Details"),
|
|
71
71
|
description: "Loading...",
|
|
72
72
|
actions: /* @__PURE__ */ x("button", {
|
|
73
|
+
type: "button",
|
|
73
74
|
onClick: () => E("/coupons"),
|
|
74
75
|
className: "px-4 py-2 rounded-lg border border-border text-foreground hover:bg-muted flex items-center gap-2",
|
|
75
|
-
children: [/* @__PURE__ */ b(l, { className: "
|
|
76
|
+
children: [/* @__PURE__ */ b(l, { className: "size-4" }), "Back"]
|
|
76
77
|
})
|
|
77
78
|
}), /* @__PURE__ */ b("div", {
|
|
78
79
|
className: "flex items-center justify-center h-64",
|
|
79
|
-
children: /* @__PURE__ */ b("div", { className: "
|
|
80
|
+
children: /* @__PURE__ */ b("div", { className: "size-8 animate-spin rounded-full border-4 border-primary border-t-transparent" })
|
|
80
81
|
})]
|
|
81
82
|
});
|
|
82
83
|
if (I || !P?.getCoupon) return /* @__PURE__ */ x("div", {
|
|
@@ -85,9 +86,10 @@ var T = () => {
|
|
|
85
86
|
title: "Coupon Details",
|
|
86
87
|
description: "Coupon not found",
|
|
87
88
|
actions: /* @__PURE__ */ x("button", {
|
|
89
|
+
type: "button",
|
|
88
90
|
onClick: () => E("/coupons"),
|
|
89
91
|
className: "px-4 py-2 rounded-lg border border-border text-foreground hover:bg-muted flex items-center gap-2",
|
|
90
|
-
children: [/* @__PURE__ */ b(l, { className: "
|
|
92
|
+
children: [/* @__PURE__ */ b(l, { className: "size-4" }), "Back"]
|
|
91
93
|
})
|
|
92
94
|
}), /* @__PURE__ */ b("div", {
|
|
93
95
|
className: "flex items-center justify-center h-64 text-destructive text-sm",
|
|
@@ -108,29 +110,32 @@ var T = () => {
|
|
|
108
110
|
actions: /* @__PURE__ */ x("div", {
|
|
109
111
|
className: "flex items-center gap-3",
|
|
110
112
|
children: [/* @__PURE__ */ x("button", {
|
|
113
|
+
type: "button",
|
|
111
114
|
onClick: () => E("/coupons"),
|
|
112
115
|
className: "px-4 py-2 rounded-lg border border-border text-foreground hover:bg-muted flex items-center gap-2",
|
|
113
|
-
children: [/* @__PURE__ */ b(l, { className: "
|
|
116
|
+
children: [/* @__PURE__ */ b(l, { className: "size-4" }), "Back"]
|
|
114
117
|
}), /* @__PURE__ */ x("button", {
|
|
118
|
+
type: "button",
|
|
115
119
|
onClick: () => E(`/coupons/${z.id}/edit`),
|
|
116
120
|
className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 flex items-center gap-2",
|
|
117
|
-
children: [/* @__PURE__ */ b(m, { className: "
|
|
121
|
+
children: [/* @__PURE__ */ b(m, { className: "size-4" }), "Edit"]
|
|
118
122
|
})]
|
|
119
123
|
})
|
|
120
124
|
}),
|
|
121
125
|
/* @__PURE__ */ b("div", {
|
|
122
126
|
className: "mt-6 border-b border-border flex gap-1",
|
|
123
127
|
children: ["details", "usage"].map((e) => /* @__PURE__ */ x("button", {
|
|
128
|
+
type: "button",
|
|
124
129
|
onClick: () => A(e),
|
|
125
130
|
className: `flex items-center gap-2 px-4 py-2.5 text-sm font-medium border-b-2 -mb-px transition-colors ${k === e ? "border-primary text-foreground" : "border-transparent text-muted-foreground hover:text-foreground"}`,
|
|
126
|
-
children: [b(e === "details" ? _ : h, { className: "
|
|
131
|
+
children: [b(e === "details" ? _ : h, { className: "size-4" }), e === "details" ? "Details" : `Usage History${L ? ` (${L.getCouponUsageHistory.total})` : ""}`]
|
|
127
132
|
}, e))
|
|
128
133
|
}),
|
|
129
134
|
k === "usage" && /* @__PURE__ */ b("div", {
|
|
130
135
|
className: "mt-6 bg-card border border-border rounded-lg overflow-hidden",
|
|
131
136
|
children: R ? /* @__PURE__ */ b("div", {
|
|
132
137
|
className: "flex items-center justify-center h-40",
|
|
133
|
-
children: /* @__PURE__ */ b("div", { className: "
|
|
138
|
+
children: /* @__PURE__ */ b("div", { className: "size-6 animate-spin rounded-full border-4 border-primary border-t-transparent" })
|
|
134
139
|
}) : L?.getCouponUsageHistory.usages.length ? /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ b("div", {
|
|
135
140
|
className: "overflow-x-auto",
|
|
136
141
|
children: /* @__PURE__ */ x("table", {
|
|
@@ -186,7 +191,7 @@ var T = () => {
|
|
|
186
191
|
]
|
|
187
192
|
}) : /* @__PURE__ */ b("span", {
|
|
188
193
|
className: "text-muted-foreground",
|
|
189
|
-
children: "
|
|
194
|
+
children: ", "
|
|
190
195
|
})
|
|
191
196
|
}),
|
|
192
197
|
/* @__PURE__ */ x("td", {
|
|
@@ -237,15 +242,17 @@ var T = () => {
|
|
|
237
242
|
}), /* @__PURE__ */ x("div", {
|
|
238
243
|
className: "flex items-center gap-2",
|
|
239
244
|
children: [/* @__PURE__ */ b("button", {
|
|
245
|
+
type: "button",
|
|
240
246
|
onClick: () => M((e) => Math.max(0, e - 1)),
|
|
241
247
|
disabled: j === 0,
|
|
242
248
|
className: "p-1.5 rounded border border-border hover:bg-muted disabled:opacity-40",
|
|
243
|
-
children: /* @__PURE__ */ b(f, { className: "
|
|
249
|
+
children: /* @__PURE__ */ b(f, { className: "size-4" })
|
|
244
250
|
}), /* @__PURE__ */ b("button", {
|
|
251
|
+
type: "button",
|
|
245
252
|
onClick: () => M((e) => e + 1),
|
|
246
253
|
disabled: !L.getCouponUsageHistory.hasMore,
|
|
247
254
|
className: "p-1.5 rounded border border-border hover:bg-muted disabled:opacity-40",
|
|
248
|
-
children: /* @__PURE__ */ b(p, { className: "
|
|
255
|
+
children: /* @__PURE__ */ b(p, { className: "size-4" })
|
|
249
256
|
})]
|
|
250
257
|
})]
|
|
251
258
|
})] }) : /* @__PURE__ */ b("div", {
|
|
@@ -263,7 +270,7 @@ var T = () => {
|
|
|
263
270
|
className: "bg-card border border-border rounded-lg p-4",
|
|
264
271
|
children: [/* @__PURE__ */ x("div", {
|
|
265
272
|
className: "flex items-center gap-2 text-muted-foreground mb-1",
|
|
266
|
-
children: [/* @__PURE__ */ b(_, { className: "
|
|
273
|
+
children: [/* @__PURE__ */ b(_, { className: "size-4" }), /* @__PURE__ */ b("span", {
|
|
267
274
|
className: "text-xs font-medium uppercase tracking-wide",
|
|
268
275
|
children: "Code"
|
|
269
276
|
})]
|
|
@@ -277,7 +284,7 @@ var T = () => {
|
|
|
277
284
|
children: [
|
|
278
285
|
/* @__PURE__ */ x("div", {
|
|
279
286
|
className: "flex items-center gap-2 text-muted-foreground mb-1",
|
|
280
|
-
children: [/* @__PURE__ */ b(u, { className: "
|
|
287
|
+
children: [/* @__PURE__ */ b(u, { className: "size-4" }), /* @__PURE__ */ b("span", {
|
|
281
288
|
className: "text-xs font-medium uppercase tracking-wide",
|
|
282
289
|
children: "Discount"
|
|
283
290
|
})]
|
|
@@ -297,7 +304,7 @@ var T = () => {
|
|
|
297
304
|
children: [
|
|
298
305
|
/* @__PURE__ */ x("div", {
|
|
299
306
|
className: "flex items-center gap-2 text-muted-foreground mb-1",
|
|
300
|
-
children: [/* @__PURE__ */ b(v, { className: "
|
|
307
|
+
children: [/* @__PURE__ */ b(v, { className: "size-4" }), /* @__PURE__ */ b("span", {
|
|
301
308
|
className: "text-xs font-medium uppercase tracking-wide",
|
|
302
309
|
children: "Usage"
|
|
303
310
|
})]
|
|
@@ -320,7 +327,7 @@ var T = () => {
|
|
|
320
327
|
children: [
|
|
321
328
|
/* @__PURE__ */ x("div", {
|
|
322
329
|
className: "flex items-center gap-2 text-muted-foreground mb-1",
|
|
323
|
-
children: [/* @__PURE__ */ b(d, { className: "
|
|
330
|
+
children: [/* @__PURE__ */ b(d, { className: "size-4" }), /* @__PURE__ */ b("span", {
|
|
324
331
|
className: "text-xs font-medium uppercase tracking-wide",
|
|
325
332
|
children: "Status"
|
|
326
333
|
})]
|
|
@@ -460,7 +467,7 @@ var T = () => {
|
|
|
460
467
|
children: [
|
|
461
468
|
/* @__PURE__ */ x("h3", {
|
|
462
469
|
className: "text-sm font-semibold text-foreground uppercase tracking-wide mb-2",
|
|
463
|
-
children: [/* @__PURE__ */ b(g, { className: "
|
|
470
|
+
children: [/* @__PURE__ */ b(g, { className: "size-4 inline mr-1" }), "Audit"]
|
|
464
471
|
}),
|
|
465
472
|
/* @__PURE__ */ b(w, {
|
|
466
473
|
label: "Created",
|
|
@@ -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 { 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';\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-muted text-muted-foreground border-border',\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-destructive/10 text-destructive border-destructive/20',\n },\n };\n const { label, className } = map[status] ?? {\n label: status,\n className: 'bg-muted text-muted-foreground',\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 last:border-0\">\n <span className=\"text-sm text-muted-foreground w-44 shrink-0\">{label}</span>\n <span className=\"text-sm text-foreground 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 onClick={() => navigateTo('/coupons')}\n className=\"px-4 py-2 rounded-lg border border-border text-foreground hover:bg-muted flex items-center gap-2\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n }\n />\n <div className=\"flex items-center justify-center h-64\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-4 border-primary 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 onClick={() => navigateTo('/coupons')}\n className=\"px-4 py-2 rounded-lg border border-border text-foreground hover:bg-muted flex items-center gap-2\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n }\n />\n <div className=\"flex items-center justify-center h-64 text-destructive 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 <div className=\"flex items-center gap-3\">\n <button\n onClick={() => navigateTo('/coupons')}\n className=\"px-4 py-2 rounded-lg border border-border text-foreground hover:bg-muted flex items-center gap-2\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n <button\n onClick={() => navigateTo(`/coupons/${coupon.id}/edit`)}\n className=\"px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 flex items-center gap-2\"\n >\n <Edit className=\"h-4 w-4\" />\n Edit\n </button>\n </div>\n }\n />\n\n {/* Tabs */}\n <div className=\"mt-6 border-b border-border flex gap-1\">\n {(['details', 'usage'] as const).map((tab) => (\n <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-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {tab === 'details' ? <Tag className=\"h-4 w-4\" /> : <History className=\"h-4 w-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-card border border-border rounded-lg overflow-hidden\">\n {usageLoading ? (\n <div className=\"flex items-center justify-center h-40\">\n <div className=\"h-6 w-6 animate-spin rounded-full border-4 border-primary border-t-transparent\" />\n </div>\n ) : !usageData?.getCouponUsageHistory.usages.length ? (\n <div className=\"p-8 text-center text-sm text-muted-foreground\">\n No usage recorded for this coupon yet.\n </div>\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead className=\"bg-muted/50 border-b border-border\">\n <tr>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n User ID\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Transaction\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Original\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Discount\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Final\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Used At\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {usageData.getCouponUsageHistory.usages.map((u: CouponUsage) => (\n <tr key={u.id} className=\"hover:bg-muted/30\">\n <td className=\"p-4 text-sm text-foreground font-mono\">\n {u.userId.slice(0, 12)}…\n </td>\n <td className=\"p-4 text-sm\">\n {u.transactionId ? (\n <span className=\"font-mono text-xs text-primary\">\n {u.transactionId.slice(0, 12)}…\n </span>\n ) : u.orderId ? (\n <span className=\"text-xs text-muted-foreground\">\n Order: {u.orderId.slice(0, 12)}…\n </span>\n ) : (\n <span className=\"text-muted-foreground\">—</span>\n )}\n </td>\n <td className=\"p-4 text-sm text-foreground\">\n {u.originalAmount.toFixed(2)} {u.currency}\n </td>\n <td className=\"p-4 text-sm text-status-success-text font-medium\">\n -{u.discountValue.toFixed(2)} {u.currency}\n </td>\n <td className=\"p-4 text-sm text-foreground font-medium\">\n {u.finalAmount.toFixed(2)} {u.currency}\n </td>\n <td className=\"p-4 text-sm text-muted-foreground\">\n {new Date(u.usedAt).toLocaleString()}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {(usageData.getCouponUsageHistory.total ?? 0) > USAGE_PAGE_SIZE && (\n <div className=\"flex items-center justify-between p-4 border-t border-border\">\n <p className=\"text-sm text-muted-foreground\">\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 onClick={() => setUsagePage((p) => Math.max(0, p - 1))}\n disabled={usagePage === 0}\n className=\"p-1.5 rounded border border-border hover:bg-muted disabled:opacity-40\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setUsagePage((p) => p + 1)}\n disabled={!usageData.getCouponUsageHistory.hasMore}\n className=\"p-1.5 rounded border border-border hover:bg-muted disabled:opacity-40\"\n >\n <ChevronRight className=\"h-4 w-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-card border border-border rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground mb-1\">\n <Tag className=\"h-4 w-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-foreground\">{coupon.code}</p>\n </div>\n\n <div className=\"bg-card border border-border rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground mb-1\">\n <BarChart2 className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Discount</span>\n </div>\n <p className=\"text-lg font-bold text-foreground\">{formatValue()}</p>\n <p className=\"text-xs text-muted-foreground capitalize\">\n {coupon.type.replace('_', ' ').toLowerCase()}\n </p>\n </div>\n\n <div className=\"bg-card border border-border rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground mb-1\">\n <Users className=\"h-4 w-4\" />\n <span className=\"text-xs font-medium uppercase tracking-wide\">Usage</span>\n </div>\n <p className=\"text-lg font-bold text-foreground\">\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-muted rounded-full overflow-hidden\">\n <div\n className=\"h-full bg-primary rounded-full\"\n style={{ width: `${Math.min(usagePercent, 100)}%` }}\n />\n </div>\n )}\n </div>\n\n <div className=\"bg-card border border-border rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground mb-1\">\n <Calendar className=\"h-4 w-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-muted-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground uppercase tracking-wide mb-2\">\n <Package className=\"h-4 w-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 { 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';\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-muted text-muted-foreground border-border',\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-destructive/10 text-destructive border-destructive/20',\n },\n };\n const { label, className } = map[status] ?? {\n label: status,\n className: 'bg-muted text-muted-foreground',\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 last:border-0\">\n <span className=\"text-sm text-muted-foreground w-44 shrink-0\">{label}</span>\n <span className=\"text-sm text-foreground 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 text-foreground hover:bg-muted 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-primary 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 text-foreground hover:bg-muted 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-destructive 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 <div className=\"flex items-center gap-3\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/coupons')}\n className=\"px-4 py-2 rounded-lg border border-border text-foreground hover:bg-muted flex items-center gap-2\"\n >\n <ArrowLeft className=\"size-4\" />\n Back\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/coupons/${coupon.id}/edit`)}\n className=\"px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 flex items-center gap-2\"\n >\n <Edit className=\"size-4\" />\n Edit\n </button>\n </div>\n }\n />\n\n {/* Tabs */}\n <div className=\"mt-6 border-b border-border 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-primary text-foreground'\n : 'border-transparent text-muted-foreground hover:text-foreground'\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-card border border-border 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-primary border-t-transparent\" />\n </div>\n ) : !usageData?.getCouponUsageHistory.usages.length ? (\n <div className=\"p-8 text-center text-sm text-muted-foreground\">\n No usage recorded for this coupon yet.\n </div>\n ) : (\n <>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead className=\"bg-muted/50 border-b border-border\">\n <tr>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n User ID\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Transaction\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Original\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Discount\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Final\n </th>\n <th className=\"text-left p-4 text-xs font-medium text-muted-foreground uppercase tracking-wide\">\n Used At\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {usageData.getCouponUsageHistory.usages.map((u: CouponUsage) => (\n <tr key={u.id} className=\"hover:bg-muted/30\">\n <td className=\"p-4 text-sm text-foreground font-mono\">\n {u.userId.slice(0, 12)}…\n </td>\n <td className=\"p-4 text-sm\">\n {u.transactionId ? (\n <span className=\"font-mono text-xs text-primary\">\n {u.transactionId.slice(0, 12)}…\n </span>\n ) : u.orderId ? (\n <span className=\"text-xs text-muted-foreground\">\n Order: {u.orderId.slice(0, 12)}…\n </span>\n ) : (\n <span className=\"text-muted-foreground\">, </span>\n )}\n </td>\n <td className=\"p-4 text-sm text-foreground\">\n {u.originalAmount.toFixed(2)} {u.currency}\n </td>\n <td className=\"p-4 text-sm text-status-success-text font-medium\">\n -{u.discountValue.toFixed(2)} {u.currency}\n </td>\n <td className=\"p-4 text-sm text-foreground font-medium\">\n {u.finalAmount.toFixed(2)} {u.currency}\n </td>\n <td className=\"p-4 text-sm text-muted-foreground\">\n {new Date(u.usedAt).toLocaleString()}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {(usageData.getCouponUsageHistory.total ?? 0) > USAGE_PAGE_SIZE && (\n <div className=\"flex items-center justify-between p-4 border-t border-border\">\n <p className=\"text-sm text-muted-foreground\">\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 hover:bg-muted 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 hover:bg-muted 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-card border border-border rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground 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-foreground\">{coupon.code}</p>\n </div>\n\n <div className=\"bg-card border border-border rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground 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-foreground\">{formatValue()}</p>\n <p className=\"text-xs text-muted-foreground capitalize\">\n {coupon.type.replace('_', ' ').toLowerCase()}\n </p>\n </div>\n\n <div className=\"bg-card border border-border rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground 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-foreground\">\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-muted rounded-full overflow-hidden\">\n <div\n className=\"h-full bg-primary rounded-full\"\n style={{ width: `${Math.min(usagePercent, 100)}%` }}\n />\n </div>\n )}\n </div>\n\n <div className=\"bg-card border border-border rounded-lg p-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground 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-muted-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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-card border border-border rounded-lg p-6\">\n <h3 className=\"text-sm font-semibold text-foreground 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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"}
|
|
@@ -55,10 +55,10 @@ var O = () => {
|
|
|
55
55
|
}
|
|
56
56
|
}, de = (e) => {
|
|
57
57
|
switch (e) {
|
|
58
|
-
case "PERCENTAGE": return /* @__PURE__ */ T(_, { className: "
|
|
59
|
-
case "FIXED_AMOUNT": return /* @__PURE__ */ T(p, { className: "
|
|
60
|
-
case "FREE_SHIPPING": return /* @__PURE__ */ T(g, { className: "
|
|
61
|
-
default: return /* @__PURE__ */ T(S, { className: "
|
|
58
|
+
case "PERCENTAGE": return /* @__PURE__ */ T(_, { className: "size-4" });
|
|
59
|
+
case "FIXED_AMOUNT": return /* @__PURE__ */ T(p, { className: "size-4" });
|
|
60
|
+
case "FREE_SHIPPING": return /* @__PURE__ */ T(g, { className: "size-4" });
|
|
61
|
+
default: return /* @__PURE__ */ T(S, { className: "size-4" });
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
64
|
return /* @__PURE__ */ E("div", {
|
|
@@ -69,11 +69,12 @@ var O = () => {
|
|
|
69
69
|
children: [/* @__PURE__ */ T(t, {
|
|
70
70
|
title: re("billing.coupons.title", "Coupons"),
|
|
71
71
|
description: "Manage discount codes and promotional offers",
|
|
72
|
-
icon: /* @__PURE__ */ T(S, { className: "
|
|
72
|
+
icon: /* @__PURE__ */ T(S, { className: "size-6" })
|
|
73
73
|
}), /* @__PURE__ */ E("button", {
|
|
74
|
+
type: "button",
|
|
74
75
|
onClick: () => k("/coupons/create"),
|
|
75
76
|
className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 flex items-center gap-2",
|
|
76
|
-
children: [/* @__PURE__ */ T(v, { className: "
|
|
77
|
+
children: [/* @__PURE__ */ T(v, { className: "size-4" }), "Create Coupon"]
|
|
77
78
|
})]
|
|
78
79
|
}),
|
|
79
80
|
/* @__PURE__ */ E("div", {
|
|
@@ -87,7 +88,7 @@ var O = () => {
|
|
|
87
88
|
children: [/* @__PURE__ */ T("span", {
|
|
88
89
|
className: "text-sm text-muted-foreground",
|
|
89
90
|
children: "Total Coupons"
|
|
90
|
-
}), /* @__PURE__ */ T(S, { className: "
|
|
91
|
+
}), /* @__PURE__ */ T(S, { className: "size-4 text-accent-blue" })]
|
|
91
92
|
}),
|
|
92
93
|
/* @__PURE__ */ T("p", {
|
|
93
94
|
className: "text-2xl font-bold text-foreground",
|
|
@@ -107,7 +108,7 @@ var O = () => {
|
|
|
107
108
|
children: [/* @__PURE__ */ T("span", {
|
|
108
109
|
className: "text-sm text-muted-foreground",
|
|
109
110
|
children: "Total Uses"
|
|
110
|
-
}), /* @__PURE__ */ T(w, { className: "
|
|
111
|
+
}), /* @__PURE__ */ T(w, { className: "size-4 text-status-success-text" })]
|
|
111
112
|
}),
|
|
112
113
|
/* @__PURE__ */ T("p", {
|
|
113
114
|
className: "text-2xl font-bold text-foreground",
|
|
@@ -127,7 +128,7 @@ var O = () => {
|
|
|
127
128
|
children: [/* @__PURE__ */ T("span", {
|
|
128
129
|
className: "text-sm text-muted-foreground",
|
|
129
130
|
children: "Total Discount"
|
|
130
|
-
}), /* @__PURE__ */ T(p, { className: "
|
|
131
|
+
}), /* @__PURE__ */ T(p, { className: "size-4 text-accent-purple" })]
|
|
131
132
|
}),
|
|
132
133
|
/* @__PURE__ */ T("p", {
|
|
133
134
|
className: "text-2xl font-bold text-foreground",
|
|
@@ -147,7 +148,7 @@ var O = () => {
|
|
|
147
148
|
children: [/* @__PURE__ */ T("span", {
|
|
148
149
|
className: "text-sm text-muted-foreground",
|
|
149
150
|
children: "Active Rate"
|
|
150
|
-
}), /* @__PURE__ */ T(d, { className: "
|
|
151
|
+
}), /* @__PURE__ */ T(d, { className: "size-4 text-status-success-text" })]
|
|
151
152
|
}),
|
|
152
153
|
/* @__PURE__ */ E("p", {
|
|
153
154
|
className: "text-2xl font-bold text-foreground",
|
|
@@ -165,7 +166,7 @@ var O = () => {
|
|
|
165
166
|
className: H.tone === "success" ? "flex items-start gap-3 rounded-lg border border-status-success-border bg-status-success-bg-subtle p-4 text-status-success-text" : "flex items-start gap-3 rounded-lg border border-status-error-border bg-status-error-bg-subtle p-4 text-status-error-text",
|
|
166
167
|
role: "status",
|
|
167
168
|
"aria-live": "polite",
|
|
168
|
-
children: [H.tone === "success" ? /* @__PURE__ */ T(d, { className: "mt-0.5
|
|
169
|
+
children: [H.tone === "success" ? /* @__PURE__ */ T(d, { className: "mt-0.5 size-4 shrink-0" }) : /* @__PURE__ */ T(u, { className: "mt-0.5 size-4 shrink-0" }), /* @__PURE__ */ T("p", {
|
|
169
170
|
className: "text-sm font-medium",
|
|
170
171
|
children: H.message
|
|
171
172
|
})]
|
|
@@ -213,7 +214,7 @@ var O = () => {
|
|
|
213
214
|
className: "md:col-span-2",
|
|
214
215
|
children: /* @__PURE__ */ E("div", {
|
|
215
216
|
className: "relative",
|
|
216
|
-
children: [/* @__PURE__ */ T(x, { className: "absolute left-3 top-1/2 -translate-y-1/2
|
|
217
|
+
children: [/* @__PURE__ */ T(x, { className: "absolute left-3 top-1/2 -translate-y-1/2 size-4 text-muted-foreground" }), /* @__PURE__ */ T("input", {
|
|
217
218
|
type: "text",
|
|
218
219
|
placeholder: "Search coupons...",
|
|
219
220
|
value: A,
|
|
@@ -318,7 +319,7 @@ var O = () => {
|
|
|
318
319
|
children: G ? /* @__PURE__ */ T("tr", { children: /* @__PURE__ */ T("td", {
|
|
319
320
|
colSpan: 7,
|
|
320
321
|
className: "p-8 text-center text-muted-foreground",
|
|
321
|
-
children: "Loading coupons
|
|
322
|
+
children: "Loading coupons…"
|
|
322
323
|
}) }) : X.length === 0 ? /* @__PURE__ */ T("tr", { children: /* @__PURE__ */ T("td", {
|
|
323
324
|
colSpan: 7,
|
|
324
325
|
className: "p-8 text-center text-muted-foreground",
|
|
@@ -392,34 +393,39 @@ var O = () => {
|
|
|
392
393
|
className: "flex items-center justify-end gap-2",
|
|
393
394
|
children: [
|
|
394
395
|
/* @__PURE__ */ T("button", {
|
|
396
|
+
type: "button",
|
|
395
397
|
onClick: () => k(`/coupons/${e.id}`),
|
|
396
398
|
className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground",
|
|
397
399
|
title: "View details",
|
|
398
|
-
children: /* @__PURE__ */ T(h, { className: "
|
|
400
|
+
children: /* @__PURE__ */ T(h, { className: "size-4" })
|
|
399
401
|
}),
|
|
400
402
|
/* @__PURE__ */ T("button", {
|
|
403
|
+
type: "button",
|
|
401
404
|
onClick: () => k(`/coupons/${e.id}/edit`),
|
|
402
405
|
className: "p-2 rounded-lg hover:bg-muted text-muted-foreground hover:text-foreground",
|
|
403
406
|
title: "Edit coupon",
|
|
404
|
-
children: /* @__PURE__ */ T(m, { className: "
|
|
407
|
+
children: /* @__PURE__ */ T(m, { className: "size-4" })
|
|
405
408
|
}),
|
|
406
409
|
e.status === "ACTIVE" ? /* @__PURE__ */ T("button", {
|
|
410
|
+
type: "button",
|
|
407
411
|
onClick: () => z(e),
|
|
408
412
|
disabled: Y || B === e.id,
|
|
409
413
|
className: "p-2 rounded-lg hover:bg-destructive/10 text-muted-foreground hover:text-destructive disabled:opacity-50 disabled:cursor-not-allowed",
|
|
410
414
|
title: "Deactivate coupon",
|
|
411
|
-
children: /* @__PURE__ */ T(b, { className: "
|
|
415
|
+
children: /* @__PURE__ */ T(b, { className: "size-4" })
|
|
412
416
|
}) : e.status === "INACTIVE" ? /* @__PURE__ */ T("button", {
|
|
417
|
+
type: "button",
|
|
413
418
|
onClick: () => pe(e.id, s.Active),
|
|
414
419
|
disabled: B === e.id,
|
|
415
420
|
className: "p-2 rounded-lg hover:bg-status-success-bg-subtle text-muted-foreground hover:text-status-success-text disabled:opacity-50 disabled:cursor-not-allowed",
|
|
416
421
|
title: "Activate coupon",
|
|
417
|
-
children: /* @__PURE__ */ T(y, { className: "
|
|
422
|
+
children: /* @__PURE__ */ T(y, { className: "size-4" })
|
|
418
423
|
}) : /* @__PURE__ */ T("button", {
|
|
424
|
+
type: "button",
|
|
419
425
|
disabled: !0,
|
|
420
426
|
className: "p-2 rounded-lg text-muted-foreground/40 cursor-not-allowed",
|
|
421
427
|
title: `Cannot change status (${e.status.toLowerCase()})`,
|
|
422
|
-
children: /* @__PURE__ */ T(C, { className: "
|
|
428
|
+
children: /* @__PURE__ */ T(C, { className: "size-4" })
|
|
423
429
|
})
|
|
424
430
|
]
|
|
425
431
|
})
|
|
@@ -448,10 +454,11 @@ var O = () => {
|
|
|
448
454
|
className: "flex items-center gap-2",
|
|
449
455
|
children: [
|
|
450
456
|
/* @__PURE__ */ T("button", {
|
|
457
|
+
type: "button",
|
|
451
458
|
onClick: () => L((e) => Math.max(0, e - 1)),
|
|
452
459
|
disabled: I === 0,
|
|
453
460
|
className: "p-2 rounded-lg border border-border hover:bg-muted disabled:opacity-40 disabled:cursor-not-allowed",
|
|
454
|
-
children: /* @__PURE__ */ T(f, { className: "
|
|
461
|
+
children: /* @__PURE__ */ T(f, { className: "size-4" })
|
|
455
462
|
}),
|
|
456
463
|
/* @__PURE__ */ E("span", {
|
|
457
464
|
className: "text-sm text-foreground font-medium",
|
|
@@ -462,10 +469,11 @@ var O = () => {
|
|
|
462
469
|
]
|
|
463
470
|
}),
|
|
464
471
|
/* @__PURE__ */ T("button", {
|
|
472
|
+
type: "button",
|
|
465
473
|
onClick: () => L((e) => e + 1),
|
|
466
474
|
disabled: !oe,
|
|
467
475
|
className: "p-2 rounded-lg border border-border hover:bg-muted disabled:opacity-40 disabled:cursor-not-allowed",
|
|
468
|
-
children: /* @__PURE__ */ T(te, { className: "
|
|
476
|
+
children: /* @__PURE__ */ T(te, { className: "size-4" })
|
|
469
477
|
})
|
|
470
478
|
]
|
|
471
479
|
})]
|
|
@@ -473,9 +481,10 @@ var O = () => {
|
|
|
473
481
|
/* @__PURE__ */ T("div", {
|
|
474
482
|
className: "flex justify-end",
|
|
475
483
|
children: /* @__PURE__ */ E("button", {
|
|
484
|
+
type: "button",
|
|
476
485
|
onClick: me,
|
|
477
486
|
className: "px-4 py-2 rounded-lg border border-border text-foreground hover:bg-muted flex items-center gap-2",
|
|
478
|
-
children: [/* @__PURE__ */ T(ne, { className: "
|
|
487
|
+
children: [/* @__PURE__ */ T(ne, { className: "size-4" }), "Export Coupons"]
|
|
479
488
|
})
|
|
480
489
|
})
|
|
481
490
|
]
|