@burdenoff/microfe-billing 2026.625.3 → 2026.625.5
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/lib/native-purchases.js +2 -44
- package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js +192 -187
- package/dist/billing/modules/addons/pages/AddonBrowseDetailPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonCreatePage.js +322 -317
- package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonDetailPage.js +190 -185
- package/dist/billing/modules/addons/pages/AddonDetailPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonEditPage.js +297 -292
- package/dist/billing/modules/addons/pages/AddonEditPage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonsBrowsePage.js +60 -75
- package/dist/billing/modules/addons/pages/AddonsBrowsePage.js.map +1 -1
- package/dist/billing/modules/addons/pages/AddonsListPage.js +86 -101
- package/dist/billing/modules/addons/pages/AddonsListPage.js.map +1 -1
- package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js +124 -121
- package/dist/billing/modules/affiliate/pages/AffiliateDashboardPage.js.map +1 -1
- package/dist/billing/modules/analytics/pages/AnalyticsPage.js +103 -111
- package/dist/billing/modules/analytics/pages/AnalyticsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoiceDetailPage.js +196 -160
- package/dist/billing/modules/billing/pages/InvoiceDetailPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoicesListPage.js +58 -73
- package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/PaymentMethodsPage.js +65 -75
- package/dist/billing/modules/billing/pages/PaymentMethodsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/RefundsPage.js +399 -399
- package/dist/billing/modules/billing/pages/RefundsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/TransactionsPage.js +49 -48
- package/dist/billing/modules/billing/pages/TransactionsPage.js.map +1 -1
- package/dist/billing/modules/billing/pages/UserRefundsPage.js +144 -151
- package/dist/billing/modules/billing/pages/UserRefundsPage.js.map +1 -1
- package/dist/billing/modules/checkout/pages/CheckoutPage.js +430 -425
- package/dist/billing/modules/checkout/pages/CheckoutPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CouponDetailPage.js +121 -93
- package/dist/billing/modules/coupons/pages/CouponDetailPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CouponsListPage.js +154 -152
- package/dist/billing/modules/coupons/pages/CouponsListPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/CreateCouponPage.js +467 -462
- package/dist/billing/modules/coupons/pages/CreateCouponPage.js.map +1 -1
- package/dist/billing/modules/coupons/pages/EditCouponPage.js +294 -286
- package/dist/billing/modules/coupons/pages/EditCouponPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/AdminCreditsPage.js +123 -117
- package/dist/billing/modules/credits/pages/AdminCreditsPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditTransactionsPage.js +43 -42
- package/dist/billing/modules/credits/pages/CreditTransactionsPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js +192 -207
- package/dist/billing/modules/credits/pages/CreditWithdrawalPage.js.map +1 -1
- package/dist/billing/modules/credits/pages/CreditsPage.js +40 -56
- package/dist/billing/modules/credits/pages/CreditsPage.js.map +1 -1
- package/dist/billing/modules/dashboard/pages/OverviewPage.js +128 -121
- package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
- package/dist/billing/modules/discounts/pages/DiscountsListPage.js +165 -180
- package/dist/billing/modules/discounts/pages/DiscountsListPage.js.map +1 -1
- package/dist/billing/modules/earnings/pages/EarningsPage.js +103 -100
- package/dist/billing/modules/earnings/pages/EarningsPage.js.map +1 -1
- package/dist/billing/modules/earnings/pages/PayoutAdminPage.js +175 -175
- package/dist/billing/modules/earnings/pages/PayoutAdminPage.js.map +1 -1
- package/dist/billing/modules/earnings/pages/PayoutsPage.js +96 -96
- package/dist/billing/modules/earnings/pages/PayoutsPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanAssignFreePage.js +42 -40
- package/dist/billing/modules/plans/pages/PlanAssignFreePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +45 -38
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanCreatePage.js +339 -334
- package/dist/billing/modules/plans/pages/PlanCreatePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanDetailPage.js +80 -74
- package/dist/billing/modules/plans/pages/PlanDetailPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanEditPage.js +342 -337
- package/dist/billing/modules/plans/pages/PlanEditPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansBrowsePage.js +38 -53
- package/dist/billing/modules/plans/pages/PlansBrowsePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansListPage.js +60 -75
- package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
- package/dist/billing/modules/promotions/pages/CreatePromotionPage.js +242 -237
- package/dist/billing/modules/promotions/pages/CreatePromotionPage.js.map +1 -1
- package/dist/billing/modules/promotions/pages/PromotionsListPage.js +29 -39
- package/dist/billing/modules/promotions/pages/PromotionsListPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaPage.js +1 -0
- package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js +299 -294
- package/dist/billing/modules/quota/pages/QuotaTemplateCreatePage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js +191 -186
- package/dist/billing/modules/quota/pages/QuotaTemplateDetailPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js +308 -303
- package/dist/billing/modules/quota/pages/QuotaTemplateEditPage.js.map +1 -1
- package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js +57 -78
- package/dist/billing/modules/quota/pages/QuotaTemplatesListPage.js.map +1 -1
- package/dist/billing/modules/settings/pages/SettingsPage.js +79 -78
- package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
- package/dist/billing/modules/settings/pages/TeamPermissionsPage.js +15 -13
- package/dist/billing/modules/settings/pages/TeamPermissionsPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js +338 -299
- package/dist/billing/modules/subscriptions/pages/SubscriptionDetailPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +82 -103
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +59 -54
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
- package/dist/billing/modules/usage/pages/UsagePage.js +172 -215
- package/dist/billing/modules/usage/pages/UsagePage.js.map +1 -1
- package/package.json +2 -2
- package/dist/billing/lib/native-purchases.js.map +0 -1
|
@@ -1,44 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
function t() {
|
|
4
|
-
return e.isNativePlatform();
|
|
5
|
-
}
|
|
6
|
-
async function n() {
|
|
7
|
-
if (!e.isNativePlatform()) return null;
|
|
8
|
-
try {
|
|
9
|
-
let e = await import(
|
|
10
|
-
/* @vite-ignore */
|
|
11
|
-
"@capgo/native-purchases"
|
|
12
|
-
);
|
|
13
|
-
return e.NativePurchases ?? e.default ?? null;
|
|
14
|
-
} catch {
|
|
15
|
-
return null;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
async function r(e, t) {
|
|
19
|
-
let r = await n();
|
|
20
|
-
return !r || e.length === 0 ? [] : (await r.getProducts({
|
|
21
|
-
productIdentifiers: e,
|
|
22
|
-
productType: t
|
|
23
|
-
})).products ?? [];
|
|
24
|
-
}
|
|
25
|
-
async function i(e, t) {
|
|
26
|
-
let r = await n();
|
|
27
|
-
if (!r) throw Error("Native purchases not available on this platform");
|
|
28
|
-
return r.purchaseProduct({
|
|
29
|
-
productIdentifier: e,
|
|
30
|
-
...t
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
async function a(e) {
|
|
34
|
-
let t = await n();
|
|
35
|
-
t && await t.acknowledgePurchase({ purchaseToken: e });
|
|
36
|
-
}
|
|
37
|
-
async function o() {
|
|
38
|
-
let e = await n();
|
|
39
|
-
e && await e.restorePurchases();
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
42
|
-
export { a as acknowledgeNativePurchase, r as getNativeProducts, t as isNativeIAPAvailable, i as purchaseNativeProduct, o as restoreNativePurchases };
|
|
43
|
-
|
|
44
|
-
//# sourceMappingURL=native-purchases.js.map
|
|
1
|
+
import { acknowledgeNativePurchase as e, getNativeProducts as t, isNativeIAPAvailable as n, purchaseNativeProduct as r, restoreNativePurchases as i } from "@burdenoff/fe-libs/shared/native/purchases";
|
|
2
|
+
export { e as acknowledgeNativePurchase, t as getNativeProducts, n as isNativeIAPAvailable, r as purchaseNativeProduct, i as restoreNativePurchases };
|
|
@@ -13,8 +13,9 @@ import { Minus as u, Plus as d, ShoppingCart as f, Trash2 as p } from "lucide-re
|
|
|
13
13
|
import { useParams as m } from "react-router-dom";
|
|
14
14
|
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
15
15
|
import { useI18n as _ } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
16
|
+
import { EmphasisPanel as v, PagePurpose as y } from "@burdenoff/fe-libs/ui";
|
|
16
17
|
//#region src/billing/modules/addons/pages/AddonBrowseDetailPage.tsx
|
|
17
|
-
function
|
|
18
|
+
function b(e) {
|
|
18
19
|
let t = /* @__PURE__ */ new Map();
|
|
19
20
|
for (let n of e) {
|
|
20
21
|
if (!n.quota) continue;
|
|
@@ -28,12 +29,12 @@ function v(e) {
|
|
|
28
29
|
}
|
|
29
30
|
return Array.from(t.values());
|
|
30
31
|
}
|
|
31
|
-
var
|
|
32
|
-
let { t:
|
|
33
|
-
let n =
|
|
32
|
+
var x = () => {
|
|
33
|
+
let { t: x } = _(), S = (e, t) => {
|
|
34
|
+
let n = x(e);
|
|
34
35
|
return n === e ? t : n;
|
|
35
|
-
}, { addonId:
|
|
36
|
-
return
|
|
36
|
+
}, { addonId: C } = m(), w = s(), { addon: T, isLoading: E, error: D, refetch: O } = c(C), { addToCart: k, removeFromCart: A, updateQuantity: j, isInCart: M, getCartItem: N } = o(), P = l(() => b(T?.features || []), [T?.features]), F = T ? M(T.id) : !1, I = (T ? N(T.id) : void 0)?.quantity || 0;
|
|
37
|
+
return E ? /* @__PURE__ */ g("div", {
|
|
37
38
|
className: "space-y-6 p-6",
|
|
38
39
|
children: [/* @__PURE__ */ h("div", { className: "h-8 w-48 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ g("div", {
|
|
39
40
|
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
@@ -46,204 +47,208 @@ var y = () => {
|
|
|
46
47
|
].map((e) => /* @__PURE__ */ h("div", { className: "h-24 bg-bg-sunken animate-pulse rounded" }, e))
|
|
47
48
|
}), /* @__PURE__ */ h("div", { className: "h-64 bg-bg-sunken animate-pulse rounded" })]
|
|
48
49
|
})]
|
|
49
|
-
}) :
|
|
50
|
+
}) : D && a(D) ? /* @__PURE__ */ h("div", {
|
|
50
51
|
className: "p-6",
|
|
51
52
|
children: /* @__PURE__ */ h(t, {
|
|
52
|
-
title:
|
|
53
|
-
message:
|
|
54
|
-
onRetry: () =>
|
|
53
|
+
title: S("billing.addons.serverUnavailable", "Server Unavailable"),
|
|
54
|
+
message: S("billing.addons.unableToLoadAddonDetails", "Unable to load addon details."),
|
|
55
|
+
onRetry: () => O(),
|
|
55
56
|
showRetry: !0
|
|
56
57
|
})
|
|
57
|
-
}) :
|
|
58
|
+
}) : T ? /* @__PURE__ */ g("div", {
|
|
58
59
|
className: "space-y-6 p-6",
|
|
59
|
-
children: [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
children: [
|
|
61
|
+
/* @__PURE__ */ h(e, {
|
|
62
|
+
title: T.name,
|
|
63
|
+
description: `${i(T.duration)} addon`
|
|
64
|
+
}),
|
|
65
|
+
/* @__PURE__ */ h(y, { children: S("billing.addons.browseDetailPurpose", "See exactly what this add-on costs and the extra capacity it gives you on top of your plan before you buy it. Add it to your cart from here when it fits your needs.") }),
|
|
66
|
+
/* @__PURE__ */ g("div", {
|
|
67
|
+
className: "grid grid-cols-1 lg:grid-cols-3 gap-6",
|
|
66
68
|
children: [/* @__PURE__ */ g("div", {
|
|
67
|
-
className: "
|
|
68
|
-
children: [/* @__PURE__ */
|
|
69
|
-
className: "
|
|
70
|
-
children: /* @__PURE__ */ h("
|
|
71
|
-
className: "
|
|
72
|
-
children:
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
className: "
|
|
78
|
-
children: [/* @__PURE__ */
|
|
79
|
-
className: "
|
|
80
|
-
children:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
69
|
+
className: "lg:col-span-2 space-y-6",
|
|
70
|
+
children: [/* @__PURE__ */ g(v, {
|
|
71
|
+
className: "overflow-hidden p-0",
|
|
72
|
+
children: [/* @__PURE__ */ h("div", {
|
|
73
|
+
className: "p-4 border-b border-border-subtle",
|
|
74
|
+
children: /* @__PURE__ */ h("h2", {
|
|
75
|
+
className: "font-semibold text-text-primary",
|
|
76
|
+
children: S("billing.addons.pricing", "Pricing")
|
|
77
|
+
})
|
|
78
|
+
}), /* @__PURE__ */ g("div", {
|
|
79
|
+
className: "p-6",
|
|
80
|
+
children: [/* @__PURE__ */ g("div", {
|
|
81
|
+
className: "flex items-baseline gap-2",
|
|
82
|
+
children: [/* @__PURE__ */ h("span", {
|
|
83
|
+
className: "text-4xl font-bold text-text-primary",
|
|
84
|
+
children: n(T.price, T.currency)
|
|
85
|
+
}), /* @__PURE__ */ g("span", {
|
|
86
|
+
className: "text-lg text-text-secondary",
|
|
87
|
+
children: ["/ ", r(T.duration)]
|
|
88
|
+
})]
|
|
89
|
+
}), /* @__PURE__ */ g("p", {
|
|
90
|
+
className: "text-sm text-text-secondary mt-2",
|
|
91
|
+
children: [
|
|
92
|
+
S("billing.addons.billed", "Billed"),
|
|
93
|
+
" ",
|
|
94
|
+
T.duration === "monthly" ? S("billing.addons.everyMonth", "every month") : S("billing.addons.annually", "annually")
|
|
95
|
+
]
|
|
84
96
|
})]
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
97
|
+
})]
|
|
98
|
+
}), /* @__PURE__ */ g("div", {
|
|
99
|
+
className: "border border-border-subtle rounded-lg bg-bg-surface overflow-hidden",
|
|
100
|
+
children: [/* @__PURE__ */ h("div", {
|
|
101
|
+
className: "p-4 border-b border-border-subtle bg-bg-sunken/30",
|
|
102
|
+
children: /* @__PURE__ */ g("h2", {
|
|
103
|
+
className: "font-semibold text-text-primary",
|
|
104
|
+
children: [
|
|
105
|
+
S("billing.addons.includedQuotas", "Included Quotas"),
|
|
106
|
+
" (",
|
|
107
|
+
P.length,
|
|
108
|
+
")"
|
|
109
|
+
]
|
|
110
|
+
})
|
|
111
|
+
}), /* @__PURE__ */ h("div", {
|
|
112
|
+
className: "p-4",
|
|
113
|
+
children: P.length === 0 ? /* @__PURE__ */ h("p", {
|
|
114
|
+
className: "text-sm text-text-secondary py-4 text-center",
|
|
115
|
+
children: S("billing.addons.noQuotas", "No quotas associated with this addon.")
|
|
116
|
+
}) : /* @__PURE__ */ h("div", {
|
|
117
|
+
className: "space-y-3",
|
|
118
|
+
children: P.map((e) => /* @__PURE__ */ g("div", {
|
|
119
|
+
className: "flex items-center justify-between p-3 border border-border-subtle rounded-lg bg-bg-sunken/20",
|
|
120
|
+
children: [/* @__PURE__ */ g("div", {
|
|
121
|
+
className: "flex items-center gap-3",
|
|
122
|
+
children: [/* @__PURE__ */ h("div", {
|
|
123
|
+
className: "size-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center",
|
|
124
|
+
children: /* @__PURE__ */ h("svg", {
|
|
125
|
+
className: "size-4 text-primary",
|
|
126
|
+
fill: "none",
|
|
127
|
+
viewBox: "0 0 24 24",
|
|
128
|
+
stroke: "currentColor",
|
|
129
|
+
children: /* @__PURE__ */ h("path", {
|
|
130
|
+
strokeLinecap: "round",
|
|
131
|
+
strokeLinejoin: "round",
|
|
132
|
+
strokeWidth: 2,
|
|
133
|
+
d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
}), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("p", {
|
|
137
|
+
className: "font-medium text-text-primary",
|
|
138
|
+
children: e.name
|
|
139
|
+
}), /* @__PURE__ */ g("p", {
|
|
140
|
+
className: "text-xs text-text-secondary capitalize",
|
|
141
|
+
children: ["Type: ", e.type]
|
|
142
|
+
})] })]
|
|
143
|
+
}), /* @__PURE__ */ g("div", {
|
|
144
|
+
className: "text-right",
|
|
145
|
+
children: [/* @__PURE__ */ h("span", {
|
|
146
|
+
className: "text-lg font-semibold text-status-success-text",
|
|
147
|
+
children: e.totalValue.toLocaleString()
|
|
148
|
+
}), /* @__PURE__ */ h("p", {
|
|
149
|
+
className: "text-xs text-text-secondary",
|
|
150
|
+
children: "total"
|
|
151
|
+
})]
|
|
152
|
+
})]
|
|
153
|
+
}, e.quotaId))
|
|
154
|
+
})
|
|
92
155
|
})]
|
|
93
156
|
})]
|
|
94
157
|
}), /* @__PURE__ */ g("div", {
|
|
95
|
-
className: "
|
|
96
|
-
children: [/* @__PURE__ */
|
|
97
|
-
className: "
|
|
98
|
-
children: /* @__PURE__ */
|
|
99
|
-
className: "
|
|
158
|
+
className: "space-y-6",
|
|
159
|
+
children: [/* @__PURE__ */ g("div", {
|
|
160
|
+
className: "border border-border-subtle rounded-lg bg-bg-surface overflow-hidden",
|
|
161
|
+
children: [/* @__PURE__ */ h("div", {
|
|
162
|
+
className: "p-4 border-b border-border-subtle bg-bg-sunken/30",
|
|
163
|
+
children: /* @__PURE__ */ h("h2", {
|
|
164
|
+
className: "font-semibold text-text-primary",
|
|
165
|
+
children: S("billing.addons.purchase", "Purchase")
|
|
166
|
+
})
|
|
167
|
+
}), /* @__PURE__ */ g("div", {
|
|
168
|
+
className: "p-4 space-y-4",
|
|
100
169
|
children: [
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
M.length,
|
|
104
|
-
")"
|
|
105
|
-
]
|
|
106
|
-
})
|
|
107
|
-
}), /* @__PURE__ */ h("div", {
|
|
108
|
-
className: "p-4",
|
|
109
|
-
children: M.length === 0 ? /* @__PURE__ */ h("p", {
|
|
110
|
-
className: "text-sm text-text-secondary py-4 text-center",
|
|
111
|
-
children: b("billing.addons.noQuotas", "No quotas associated with this addon.")
|
|
112
|
-
}) : /* @__PURE__ */ h("div", {
|
|
113
|
-
className: "space-y-3",
|
|
114
|
-
children: M.map((e) => /* @__PURE__ */ g("div", {
|
|
115
|
-
className: "flex items-center justify-between p-3 border border-border-subtle rounded-lg bg-bg-sunken/20",
|
|
116
|
-
children: [/* @__PURE__ */ g("div", {
|
|
117
|
-
className: "flex items-center gap-3",
|
|
118
|
-
children: [/* @__PURE__ */ h("div", {
|
|
119
|
-
className: "size-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center",
|
|
120
|
-
children: /* @__PURE__ */ h("svg", {
|
|
121
|
-
className: "size-4 text-primary",
|
|
122
|
-
fill: "none",
|
|
123
|
-
viewBox: "0 0 24 24",
|
|
124
|
-
stroke: "currentColor",
|
|
125
|
-
children: /* @__PURE__ */ h("path", {
|
|
126
|
-
strokeLinecap: "round",
|
|
127
|
-
strokeLinejoin: "round",
|
|
128
|
-
strokeWidth: 2,
|
|
129
|
-
d: "M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
|
130
|
-
})
|
|
131
|
-
})
|
|
132
|
-
}), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("p", {
|
|
133
|
-
className: "font-medium text-text-primary",
|
|
134
|
-
children: e.name
|
|
135
|
-
}), /* @__PURE__ */ g("p", {
|
|
136
|
-
className: "text-xs text-text-secondary capitalize",
|
|
137
|
-
children: ["Type: ", e.type]
|
|
138
|
-
})] })]
|
|
139
|
-
}), /* @__PURE__ */ g("div", {
|
|
140
|
-
className: "text-right",
|
|
170
|
+
/* @__PURE__ */ g("div", {
|
|
171
|
+
className: "flex items-center justify-between",
|
|
141
172
|
children: [/* @__PURE__ */ h("span", {
|
|
142
|
-
className: "text-
|
|
143
|
-
children:
|
|
144
|
-
}), /* @__PURE__ */
|
|
145
|
-
className: "text-
|
|
146
|
-
children:
|
|
173
|
+
className: "text-sm text-text-secondary",
|
|
174
|
+
children: S("billing.addons.price", "Price")
|
|
175
|
+
}), /* @__PURE__ */ g("span", {
|
|
176
|
+
className: "text-sm font-medium text-text-primary",
|
|
177
|
+
children: [
|
|
178
|
+
n(T.price, T.currency),
|
|
179
|
+
" /",
|
|
180
|
+
" ",
|
|
181
|
+
r(T.duration)
|
|
182
|
+
]
|
|
147
183
|
})]
|
|
148
|
-
})
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}), /* @__PURE__ */ g("div", {
|
|
164
|
-
className: "p-4 space-y-4",
|
|
165
|
-
children: [
|
|
166
|
-
/* @__PURE__ */ g("div", {
|
|
167
|
-
className: "flex items-center justify-between",
|
|
168
|
-
children: [/* @__PURE__ */ h("span", {
|
|
169
|
-
className: "text-sm text-text-secondary",
|
|
170
|
-
children: b("billing.addons.price", "Price")
|
|
171
|
-
}), /* @__PURE__ */ g("span", {
|
|
172
|
-
className: "text-sm font-medium text-text-primary",
|
|
173
|
-
children: [
|
|
174
|
-
n(C.price, C.currency),
|
|
175
|
-
" /",
|
|
176
|
-
" ",
|
|
177
|
-
r(C.duration)
|
|
178
|
-
]
|
|
179
|
-
})]
|
|
180
|
-
}),
|
|
181
|
-
/* @__PURE__ */ g("div", {
|
|
182
|
-
className: "flex items-center justify-between",
|
|
183
|
-
children: [/* @__PURE__ */ h("span", {
|
|
184
|
-
className: "text-sm text-text-secondary",
|
|
185
|
-
children: b("billing.addons.billingLabel", "Billing")
|
|
186
|
-
}), /* @__PURE__ */ h("span", {
|
|
187
|
-
className: "text-sm font-medium text-text-primary capitalize",
|
|
188
|
-
children: C.duration
|
|
189
|
-
})]
|
|
190
|
-
}),
|
|
191
|
-
/* @__PURE__ */ h("div", {
|
|
192
|
-
className: "pt-2 space-y-2",
|
|
193
|
-
children: N ? /* @__PURE__ */ g("div", {
|
|
194
|
-
className: "space-y-2",
|
|
195
|
-
children: [/* @__PURE__ */ g("div", {
|
|
196
|
-
className: "flex items-center justify-between gap-2",
|
|
184
|
+
}),
|
|
185
|
+
/* @__PURE__ */ g("div", {
|
|
186
|
+
className: "flex items-center justify-between",
|
|
187
|
+
children: [/* @__PURE__ */ h("span", {
|
|
188
|
+
className: "text-sm text-text-secondary",
|
|
189
|
+
children: S("billing.addons.billingLabel", "Billing")
|
|
190
|
+
}), /* @__PURE__ */ h("span", {
|
|
191
|
+
className: "text-sm font-medium text-text-primary capitalize",
|
|
192
|
+
children: T.duration
|
|
193
|
+
})]
|
|
194
|
+
}),
|
|
195
|
+
/* @__PURE__ */ h("div", {
|
|
196
|
+
className: "pt-2 space-y-2",
|
|
197
|
+
children: F ? /* @__PURE__ */ g("div", {
|
|
198
|
+
className: "space-y-2",
|
|
197
199
|
children: [/* @__PURE__ */ g("div", {
|
|
198
|
-
className: "flex items-center gap-
|
|
199
|
-
children: [
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
200
|
+
className: "flex items-center justify-between gap-2",
|
|
201
|
+
children: [/* @__PURE__ */ g("div", {
|
|
202
|
+
className: "flex items-center gap-1",
|
|
203
|
+
children: [
|
|
204
|
+
/* @__PURE__ */ h("button", {
|
|
205
|
+
type: "button",
|
|
206
|
+
onClick: () => j(T.id, I - 1),
|
|
207
|
+
className: "p-1.5 rounded border border-border-subtle hover:bg-bg-sunken transition-colors",
|
|
208
|
+
children: /* @__PURE__ */ h(u, { className: "size-4" })
|
|
209
|
+
}),
|
|
210
|
+
/* @__PURE__ */ h("span", {
|
|
211
|
+
className: "w-10 text-center font-medium",
|
|
212
|
+
children: I
|
|
213
|
+
}),
|
|
214
|
+
/* @__PURE__ */ h("button", {
|
|
215
|
+
type: "button",
|
|
216
|
+
onClick: () => j(T.id, I + 1),
|
|
217
|
+
className: "p-1.5 rounded border border-border-subtle hover:bg-bg-sunken transition-colors",
|
|
218
|
+
children: /* @__PURE__ */ h(d, { className: "size-4" })
|
|
219
|
+
})
|
|
220
|
+
]
|
|
221
|
+
}), /* @__PURE__ */ h("button", {
|
|
222
|
+
type: "button",
|
|
223
|
+
onClick: () => A(T.id),
|
|
224
|
+
className: "p-1.5 rounded text-status-error-text hover:bg-status-error-bg/10 transition-colors",
|
|
225
|
+
title: "Remove from cart",
|
|
226
|
+
children: /* @__PURE__ */ h(p, { className: "size-4" })
|
|
227
|
+
})]
|
|
217
228
|
}), /* @__PURE__ */ h("button", {
|
|
218
229
|
type: "button",
|
|
219
|
-
onClick: () =>
|
|
220
|
-
className: "
|
|
221
|
-
|
|
222
|
-
children: /* @__PURE__ */ h(p, { className: "size-4" })
|
|
230
|
+
onClick: () => w("/checkout/addons"),
|
|
231
|
+
className: "w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors",
|
|
232
|
+
children: "Proceed to Checkout"
|
|
223
233
|
})]
|
|
224
|
-
})
|
|
234
|
+
}) : /* @__PURE__ */ g("button", {
|
|
225
235
|
type: "button",
|
|
226
|
-
onClick: () =>
|
|
227
|
-
className: "w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors",
|
|
228
|
-
children: "
|
|
229
|
-
})
|
|
230
|
-
}) : /* @__PURE__ */ g("button", {
|
|
231
|
-
type: "button",
|
|
232
|
-
onClick: () => D(C),
|
|
233
|
-
className: "w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors flex items-center justify-center gap-2",
|
|
234
|
-
children: [/* @__PURE__ */ h(f, { className: "size-4" }), "Add to Cart"]
|
|
236
|
+
onClick: () => k(T),
|
|
237
|
+
className: "w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors flex items-center justify-center gap-2",
|
|
238
|
+
children: [/* @__PURE__ */ h(f, { className: "size-4" }), "Add to Cart"]
|
|
239
|
+
})
|
|
235
240
|
})
|
|
236
|
-
|
|
237
|
-
]
|
|
241
|
+
]
|
|
242
|
+
})]
|
|
243
|
+
}), /* @__PURE__ */ h("button", {
|
|
244
|
+
type: "button",
|
|
245
|
+
onClick: () => w("/addons"),
|
|
246
|
+
className: "w-full px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-md hover:bg-bg-sunken transition-colors",
|
|
247
|
+
children: "Back to Addons"
|
|
238
248
|
})]
|
|
239
|
-
}), /* @__PURE__ */ h("button", {
|
|
240
|
-
type: "button",
|
|
241
|
-
onClick: () => S("/addons"),
|
|
242
|
-
className: "w-full px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-md hover:bg-bg-sunken transition-colors",
|
|
243
|
-
children: "Back to Addons"
|
|
244
249
|
})]
|
|
245
|
-
})
|
|
246
|
-
|
|
250
|
+
})
|
|
251
|
+
]
|
|
247
252
|
}) : /* @__PURE__ */ h("div", {
|
|
248
253
|
className: "flex items-center justify-center h-full min-h-[400px]",
|
|
249
254
|
children: /* @__PURE__ */ g("div", {
|
|
@@ -251,15 +256,15 @@ var y = () => {
|
|
|
251
256
|
children: [
|
|
252
257
|
/* @__PURE__ */ h("h2", {
|
|
253
258
|
className: "text-lg font-semibold text-text-primary",
|
|
254
|
-
children:
|
|
259
|
+
children: S("billing.addons.addonNotFound", "Addon not found")
|
|
255
260
|
}),
|
|
256
261
|
/* @__PURE__ */ h("p", {
|
|
257
262
|
className: "text-sm text-text-secondary",
|
|
258
|
-
children:
|
|
263
|
+
children: S("billing.addons.addonNotFoundMessage", "The addon you're looking for doesn't exist or has been removed.")
|
|
259
264
|
}),
|
|
260
265
|
/* @__PURE__ */ h("button", {
|
|
261
266
|
type: "button",
|
|
262
|
-
onClick: () =>
|
|
267
|
+
onClick: () => w("/addons"),
|
|
263
268
|
className: "px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors",
|
|
264
269
|
children: "Back to Addons"
|
|
265
270
|
})
|
|
@@ -268,6 +273,6 @@ var y = () => {
|
|
|
268
273
|
});
|
|
269
274
|
};
|
|
270
275
|
//#endregion
|
|
271
|
-
export {
|
|
276
|
+
export { x as AddonBrowseDetailPage };
|
|
272
277
|
|
|
273
278
|
//# sourceMappingURL=AddonBrowseDetailPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AddonBrowseDetailPage.js","names":[],"sources":["../../../../../src/billing/modules/addons/pages/AddonBrowseDetailPage.tsx"],"sourcesContent":["/**\n * Addons Module - Addon Browse Detail Page (User-facing)\n * View addon details and add to cart. No edit/toggle actions.\n */\n\nimport { useMemo, type FC } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ShoppingCart, Plus, Minus, Trash2 } from 'lucide-react';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { useAddon } from '../hooks';\nimport { useAddonCartStore } from '../store/addonCartStore';\nimport { PageHeader, ServerError } from '../../../shared/components';\nimport {\n formatCurrency,\n formatPlanDuration,\n formatPlanDurationLabel,\n isServerError,\n} from '../../../shared/utils';\nimport type { SubscriptionFeatures } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface CombinedQuota {\n quotaId: string;\n name: string;\n totalValue: number;\n type: string;\n}\n\nfunction combineQuotas(features: SubscriptionFeatures[]): CombinedQuota[] {\n const quotaMap = new Map<string, CombinedQuota>();\n for (const feature of features) {\n if (!feature.quota) continue;\n const quotaId = feature.quota.id;\n const limits = feature.quota.limits as { value?: number; type?: string } | null;\n const limitValue = limits?.value ?? 0;\n const limitType = limits?.type ?? 'unknown';\n const existing = quotaMap.get(quotaId);\n if (existing) {\n existing.totalValue += limitValue;\n } else {\n quotaMap.set(quotaId, {\n quotaId,\n name: feature.quota.name ?? 'Unknown Quota',\n totalValue: limitValue,\n type: limitType,\n });\n }\n }\n return Array.from(quotaMap.values());\n}\n\nexport const AddonBrowseDetailPage: 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 { addonId } = useParams<{ addonId: string }>();\n const navigateTo = useBillingNavigate();\n const { addon, isLoading, error, refetch } = useAddon(addonId);\n const { addToCart, removeFromCart, updateQuantity, isInCart, getCartItem } = useAddonCartStore();\n\n const combinedQuotas = useMemo(() => combineQuotas(addon?.features || []), [addon?.features]);\n const inCart = addon ? isInCart(addon.id) : false;\n const cartItem = addon ? getCartItem(addon.id) : undefined;\n const cartQuantity = cartItem?.quantity || 0;\n\n if (isLoading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"h-8 w-48 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"h-24 bg-bg-sunken animate-pulse rounded\" />\n ))}\n </div>\n <div className=\"h-64 bg-bg-sunken animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n if (error && isServerError(error)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title={tr('billing.addons.serverUnavailable', 'Server Unavailable')}\n message={tr('billing.addons.unableToLoadAddonDetails', 'Unable to load addon details.')}\n onRetry={() => refetch()}\n showRetry\n />\n </div>\n );\n }\n\n if (!addon) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.addons.addonNotFound', 'Addon not found')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'billing.addons.addonNotFoundMessage',\n \"The addon you're looking for doesn't exist or has been removed.\"\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => navigateTo('/addons')}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors\"\n >\n Back to Addons\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={addon.name}\n description={`${formatPlanDurationLabel(addon.duration)} addon`}\n />\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Main Content */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Pricing Card */}\n <div className=\"border border-border-subtle rounded-lg bg-bg-surface overflow-hidden\">\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30\">\n <h2 className=\"font-semibold text-text-primary\">\n {tr('billing.addons.pricing', 'Pricing')}\n </h2>\n </div>\n <div className=\"p-6\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-4xl font-bold text-text-primary\">\n {formatCurrency(addon.price, addon.currency)}\n </span>\n <span className=\"text-lg text-text-secondary\">\n / {formatPlanDuration(addon.duration)}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary mt-2\">\n {tr('billing.addons.billed', 'Billed')}{' '}\n {addon.duration === 'monthly'\n ? tr('billing.addons.everyMonth', 'every month')\n : tr('billing.addons.annually', 'annually')}\n </p>\n </div>\n </div>\n\n {/* Quotas Card */}\n <div className=\"border border-border-subtle rounded-lg bg-bg-surface overflow-hidden\">\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30\">\n <h2 className=\"font-semibold text-text-primary\">\n {tr('billing.addons.includedQuotas', 'Included Quotas')} ({combinedQuotas.length})\n </h2>\n </div>\n <div className=\"p-4\">\n {combinedQuotas.length === 0 ? (\n <p className=\"text-sm text-text-secondary py-4 text-center\">\n {tr('billing.addons.noQuotas', 'No quotas associated with this addon.')}\n </p>\n ) : (\n <div className=\"space-y-3\">\n {combinedQuotas.map((quota) => (\n <div\n key={quota.quotaId}\n className=\"flex items-center justify-between p-3 border border-border-subtle rounded-lg bg-bg-sunken/20\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center\">\n <svg\n className=\"size-4 text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">{quota.name}</p>\n <p className=\"text-xs text-text-secondary capitalize\">\n Type: {quota.type}\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <span className=\"text-lg font-semibold text-status-success-text\">\n {quota.totalValue.toLocaleString()}\n </span>\n <p className=\"text-xs text-text-secondary\">total</p>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Purchase Card */}\n <div className=\"border border-border-subtle rounded-lg bg-bg-surface overflow-hidden\">\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30\">\n <h2 className=\"font-semibold text-text-primary\">\n {tr('billing.addons.purchase', 'Purchase')}\n </h2>\n </div>\n <div className=\"p-4 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr('billing.addons.price', 'Price')}\n </span>\n <span className=\"text-sm font-medium text-text-primary\">\n {formatCurrency(addon.price, addon.currency)} /{' '}\n {formatPlanDuration(addon.duration)}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr('billing.addons.billingLabel', 'Billing')}\n </span>\n <span className=\"text-sm font-medium text-text-primary capitalize\">\n {addon.duration}\n </span>\n </div>\n\n <div className=\"pt-2 space-y-2\">\n {inCart ? (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => updateQuantity(addon.id, cartQuantity - 1)}\n className=\"p-1.5 rounded border border-border-subtle hover:bg-bg-sunken transition-colors\"\n >\n <Minus className=\"size-4\" />\n </button>\n <span className=\"w-10 text-center font-medium\">{cartQuantity}</span>\n <button\n type=\"button\"\n onClick={() => updateQuantity(addon.id, cartQuantity + 1)}\n className=\"p-1.5 rounded border border-border-subtle hover:bg-bg-sunken transition-colors\"\n >\n <Plus className=\"size-4\" />\n </button>\n </div>\n <button\n type=\"button\"\n onClick={() => removeFromCart(addon.id)}\n className=\"p-1.5 rounded text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n title=\"Remove from cart\"\n >\n <Trash2 className=\"size-4\" />\n </button>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo('/checkout/addons')}\n className=\"w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors\"\n >\n Proceed to Checkout\n </button>\n </div>\n ) : (\n <button\n type=\"button\"\n onClick={() => addToCart(addon)}\n className=\"w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors flex items-center justify-center gap-2\"\n >\n <ShoppingCart className=\"size-4\" />\n Add to Cart\n </button>\n )}\n </div>\n </div>\n </div>\n\n {/* Back Button */}\n <button\n type=\"button\"\n onClick={() => navigateTo('/addons')}\n className=\"w-full px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-md hover:bg-bg-sunken transition-colors\"\n >\n Back to Addons\n </button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AddonBrowseDetailPage.js","names":[],"sources":["../../../../../src/billing/modules/addons/pages/AddonBrowseDetailPage.tsx"],"sourcesContent":["/**\n * Addons Module - Addon Browse Detail Page (User-facing)\n * View addon details and add to cart. No edit/toggle actions.\n */\n\nimport { useMemo, type FC } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ShoppingCart, Plus, Minus, Trash2 } from 'lucide-react';\nimport { useBillingNavigate } from '../../../hooks/useBillingNavigate';\nimport { useAddon } from '../hooks';\nimport { useAddonCartStore } from '../store/addonCartStore';\nimport { PageHeader, ServerError } from '../../../shared/components';\nimport { PagePurpose, EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport {\n formatCurrency,\n formatPlanDuration,\n formatPlanDurationLabel,\n isServerError,\n} from '../../../shared/utils';\nimport type { SubscriptionFeatures } from '../../../shared/types';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\ninterface CombinedQuota {\n quotaId: string;\n name: string;\n totalValue: number;\n type: string;\n}\n\nfunction combineQuotas(features: SubscriptionFeatures[]): CombinedQuota[] {\n const quotaMap = new Map<string, CombinedQuota>();\n for (const feature of features) {\n if (!feature.quota) continue;\n const quotaId = feature.quota.id;\n const limits = feature.quota.limits as { value?: number; type?: string } | null;\n const limitValue = limits?.value ?? 0;\n const limitType = limits?.type ?? 'unknown';\n const existing = quotaMap.get(quotaId);\n if (existing) {\n existing.totalValue += limitValue;\n } else {\n quotaMap.set(quotaId, {\n quotaId,\n name: feature.quota.name ?? 'Unknown Quota',\n totalValue: limitValue,\n type: limitType,\n });\n }\n }\n return Array.from(quotaMap.values());\n}\n\nexport const AddonBrowseDetailPage: 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 { addonId } = useParams<{ addonId: string }>();\n const navigateTo = useBillingNavigate();\n const { addon, isLoading, error, refetch } = useAddon(addonId);\n const { addToCart, removeFromCart, updateQuantity, isInCart, getCartItem } = useAddonCartStore();\n\n const combinedQuotas = useMemo(() => combineQuotas(addon?.features || []), [addon?.features]);\n const inCart = addon ? isInCart(addon.id) : false;\n const cartItem = addon ? getCartItem(addon.id) : undefined;\n const cartQuantity = cartItem?.quantity || 0;\n\n if (isLoading) {\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"h-8 w-48 bg-bg-sunken animate-pulse rounded\" />\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n <div className=\"lg:col-span-2 space-y-4\">\n {[1, 2, 3].map((i) => (\n <div key={i} className=\"h-24 bg-bg-sunken animate-pulse rounded\" />\n ))}\n </div>\n <div className=\"h-64 bg-bg-sunken animate-pulse rounded\" />\n </div>\n </div>\n );\n }\n\n if (error && isServerError(error)) {\n return (\n <div className=\"p-6\">\n <ServerError\n title={tr('billing.addons.serverUnavailable', 'Server Unavailable')}\n message={tr('billing.addons.unableToLoadAddonDetails', 'Unable to load addon details.')}\n onRetry={() => refetch()}\n showRetry\n />\n </div>\n );\n }\n\n if (!addon) {\n return (\n <div className=\"flex items-center justify-center h-full min-h-[400px]\">\n <div className=\"text-center space-y-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('billing.addons.addonNotFound', 'Addon not found')}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'billing.addons.addonNotFoundMessage',\n \"The addon you're looking for doesn't exist or has been removed.\"\n )}\n </p>\n <button\n type=\"button\"\n onClick={() => navigateTo('/addons')}\n className=\"px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors\"\n >\n Back to Addons\n </button>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <PageHeader\n title={addon.name}\n description={`${formatPlanDurationLabel(addon.duration)} addon`}\n />\n\n <PagePurpose>\n {tr(\n 'billing.addons.browseDetailPurpose',\n 'See exactly what this add-on costs and the extra capacity it gives you on top of your plan before you buy it. Add it to your cart from here when it fits your needs.'\n )}\n </PagePurpose>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-6\">\n {/* Main Content */}\n <div className=\"lg:col-span-2 space-y-6\">\n {/* Pricing Card — primary emphasis zone */}\n <EmphasisPanel className=\"overflow-hidden p-0\">\n <div className=\"p-4 border-b border-border-subtle\">\n <h2 className=\"font-semibold text-text-primary\">\n {tr('billing.addons.pricing', 'Pricing')}\n </h2>\n </div>\n <div className=\"p-6\">\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-4xl font-bold text-text-primary\">\n {formatCurrency(addon.price, addon.currency)}\n </span>\n <span className=\"text-lg text-text-secondary\">\n / {formatPlanDuration(addon.duration)}\n </span>\n </div>\n <p className=\"text-sm text-text-secondary mt-2\">\n {tr('billing.addons.billed', 'Billed')}{' '}\n {addon.duration === 'monthly'\n ? tr('billing.addons.everyMonth', 'every month')\n : tr('billing.addons.annually', 'annually')}\n </p>\n </div>\n </EmphasisPanel>\n\n {/* Quotas Card */}\n <div className=\"border border-border-subtle rounded-lg bg-bg-surface overflow-hidden\">\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30\">\n <h2 className=\"font-semibold text-text-primary\">\n {tr('billing.addons.includedQuotas', 'Included Quotas')} ({combinedQuotas.length})\n </h2>\n </div>\n <div className=\"p-4\">\n {combinedQuotas.length === 0 ? (\n <p className=\"text-sm text-text-secondary py-4 text-center\">\n {tr('billing.addons.noQuotas', 'No quotas associated with this addon.')}\n </p>\n ) : (\n <div className=\"space-y-3\">\n {combinedQuotas.map((quota) => (\n <div\n key={quota.quotaId}\n className=\"flex items-center justify-between p-3 border border-border-subtle rounded-lg bg-bg-sunken/20\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"size-8 rounded-full bg-action-primary-bg/10 flex items-center justify-center\">\n <svg\n className=\"size-4 text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">{quota.name}</p>\n <p className=\"text-xs text-text-secondary capitalize\">\n Type: {quota.type}\n </p>\n </div>\n </div>\n <div className=\"text-right\">\n <span className=\"text-lg font-semibold text-status-success-text\">\n {quota.totalValue.toLocaleString()}\n </span>\n <p className=\"text-xs text-text-secondary\">total</p>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* Sidebar */}\n <div className=\"space-y-6\">\n {/* Purchase Card */}\n <div className=\"border border-border-subtle rounded-lg bg-bg-surface overflow-hidden\">\n <div className=\"p-4 border-b border-border-subtle bg-bg-sunken/30\">\n <h2 className=\"font-semibold text-text-primary\">\n {tr('billing.addons.purchase', 'Purchase')}\n </h2>\n </div>\n <div className=\"p-4 space-y-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr('billing.addons.price', 'Price')}\n </span>\n <span className=\"text-sm font-medium text-text-primary\">\n {formatCurrency(addon.price, addon.currency)} /{' '}\n {formatPlanDuration(addon.duration)}\n </span>\n </div>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr('billing.addons.billingLabel', 'Billing')}\n </span>\n <span className=\"text-sm font-medium text-text-primary capitalize\">\n {addon.duration}\n </span>\n </div>\n\n <div className=\"pt-2 space-y-2\">\n {inCart ? (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n onClick={() => updateQuantity(addon.id, cartQuantity - 1)}\n className=\"p-1.5 rounded border border-border-subtle hover:bg-bg-sunken transition-colors\"\n >\n <Minus className=\"size-4\" />\n </button>\n <span className=\"w-10 text-center font-medium\">{cartQuantity}</span>\n <button\n type=\"button\"\n onClick={() => updateQuantity(addon.id, cartQuantity + 1)}\n className=\"p-1.5 rounded border border-border-subtle hover:bg-bg-sunken transition-colors\"\n >\n <Plus className=\"size-4\" />\n </button>\n </div>\n <button\n type=\"button\"\n onClick={() => removeFromCart(addon.id)}\n className=\"p-1.5 rounded text-status-error-text hover:bg-status-error-bg/10 transition-colors\"\n title=\"Remove from cart\"\n >\n <Trash2 className=\"size-4\" />\n </button>\n </div>\n <button\n type=\"button\"\n onClick={() => navigateTo('/checkout/addons')}\n className=\"w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors\"\n >\n Proceed to Checkout\n </button>\n </div>\n ) : (\n <button\n type=\"button\"\n onClick={() => addToCart(addon)}\n className=\"w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-md hover:bg-action-primary-bg/90 transition-colors flex items-center justify-center gap-2\"\n >\n <ShoppingCart className=\"size-4\" />\n Add to Cart\n </button>\n )}\n </div>\n </div>\n </div>\n\n {/* Back Button */}\n <button\n type=\"button\"\n onClick={() => navigateTo('/addons')}\n className=\"w-full px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-md hover:bg-bg-sunken transition-colors\"\n >\n Back to Addons\n </button>\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
|