@burdenoff/microfe-billing 2026.830.1 → 2026.830.2
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/BillingRoot.js +56 -59
- package/dist/billing/BillingRoot.js.map +1 -1
- package/dist/billing/modules/billing/pages/InvoicesListPage.js +163 -168
- package/dist/billing/modules/billing/pages/InvoicesListPage.js.map +1 -1
- package/dist/billing/modules/dashboard/pages/OverviewPage.js +251 -254
- package/dist/billing/modules/dashboard/pages/OverviewPage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlansListPage.js +179 -185
- package/dist/billing/modules/plans/pages/PlansListPage.js.map +1 -1
- package/dist/billing/modules/settings/pages/SettingsPage.js +285 -289
- package/dist/billing/modules/settings/pages/SettingsPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js +191 -198
- package/dist/billing/modules/subscriptions/pages/SubscriptionsListPage.js.map +1 -1
- package/dist/billing/shared/components/AccessDenied.js +12 -15
- package/dist/billing/shared/components/AccessDenied.js.map +1 -1
- package/dist/billing/shared/components/ActorIdentity.js +34 -33
- package/dist/billing/shared/components/ActorIdentity.js.map +1 -1
- package/dist/billing/shared/components/ServerError.js +27 -30
- package/dist/billing/shared/components/ServerError.js.map +1 -1
- package/dist/billing/shared/hooks/index.js +1 -0
- package/dist/billing/shared/hooks/useTr.js +14 -0
- package/dist/billing/shared/hooks/useTr.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useTr as e } from "../../../shared/hooks/useTr.js";
|
|
2
|
+
import { AccessDenied as t } from "../../../shared/components/AccessDenied.js";
|
|
3
|
+
import { ServerError as n } from "../../../shared/components/ServerError.js";
|
|
3
4
|
import "../../../shared/components/index.js";
|
|
4
|
-
import { PricingModel as
|
|
5
|
-
import { formatCurrency as
|
|
6
|
-
import { isServerError as
|
|
7
|
-
import { getPlanFeatureQuantity as
|
|
5
|
+
import { PricingModel as r } from "../../../shared/types/graphql.js";
|
|
6
|
+
import { formatCurrency as i, formatPlanDuration as a, formatPlanDurationLabel as o } from "../../../shared/utils/format.js";
|
|
7
|
+
import { isServerError as s } from "../../../shared/utils/error.js";
|
|
8
|
+
import { getPlanFeatureQuantity as c } from "../../../shared/utils/planFeatureQuantity.js";
|
|
8
9
|
import "../../../shared/utils/index.js";
|
|
9
|
-
import { useBillingPermissions as
|
|
10
|
-
import { useBillingNavigate as
|
|
11
|
-
import { getDisplayPrice as
|
|
12
|
-
import { usePlanMutations as
|
|
10
|
+
import { useBillingPermissions as l } from "../../../hooks/useBillingPermissions.js";
|
|
11
|
+
import { useBillingNavigate as u } from "../../../hooks/useBillingNavigate.js";
|
|
12
|
+
import { getDisplayPrice as d, useDefaultBillingCurrency as f } from "../../../hooks/useDefaultBillingCurrency.js";
|
|
13
|
+
import { usePlanMutations as p, usePlans as m } from "../hooks/usePlans.js";
|
|
13
14
|
import "../hooks/index.js";
|
|
14
|
-
import { useMemo as
|
|
15
|
-
import { jsx as
|
|
16
|
-
import { useI18n as v } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
15
|
+
import { useMemo as h, useState as g } from "react";
|
|
16
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
17
17
|
import { IllustratedEmptyState as y, PagePurpose as b } from "@burdenoff/fe-libs/ui";
|
|
18
18
|
//#region src/billing/modules/plans/pages/PlansListPage.tsx
|
|
19
19
|
function x(e) {
|
|
20
20
|
let t = /* @__PURE__ */ new Map();
|
|
21
21
|
for (let n of e) {
|
|
22
22
|
if (!n.quota) continue;
|
|
23
|
-
let e = n.quota.id, r =
|
|
23
|
+
let e = n.quota.id, r = c(n), i = t.get(e);
|
|
24
24
|
i ? i.totalValue += r : t.set(e, {
|
|
25
25
|
quotaId: e,
|
|
26
26
|
name: n.quota.name ?? "Unknown Quota",
|
|
@@ -30,68 +30,65 @@ function x(e) {
|
|
|
30
30
|
return Array.from(t.values());
|
|
31
31
|
}
|
|
32
32
|
var S = () => {
|
|
33
|
-
let {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}, i = l(), a = c(), { plans: s, isLoading: u, error: d, refetch: m } = p(), { togglePlan: x, isToggling: S } = f(), [T, E] = h("grid"), [D, O] = h(!1), [k, A] = h("all");
|
|
37
|
-
if (!a.canViewPlans) return /* @__PURE__ */ g(e, { message: r("billing.plans.noViewPermission", "You don't have permission to view pricing plans.") });
|
|
38
|
-
let j = s.filter((e) => !(!D && !e.isActive || k !== "all" && e.duration !== k)), M = async (e) => {
|
|
33
|
+
let r = e(), i = u(), a = l(), { plans: o, isLoading: c, error: d, refetch: f } = m(), { togglePlan: h, isToggling: x } = p(), [S, T] = g("grid"), [E, D] = g(!1), [O, k] = g("all");
|
|
34
|
+
if (!a.canViewPlans) return /* @__PURE__ */ _(t, { message: r("billing.plans.noViewPermission", "You don't have permission to view pricing plans.") });
|
|
35
|
+
let A = o.filter((e) => !(!E && !e.isActive || O !== "all" && e.duration !== O)), j = async (e) => {
|
|
39
36
|
if (a.canManagePlans) try {
|
|
40
|
-
await
|
|
37
|
+
await h(e.id, !e.isActive), await f();
|
|
41
38
|
} catch (e) {
|
|
42
39
|
console.error("Failed to toggle plan:", e);
|
|
43
40
|
}
|
|
44
|
-
},
|
|
41
|
+
}, M = (e) => {
|
|
45
42
|
i(`/checkout/${e.id}`);
|
|
46
|
-
},
|
|
43
|
+
}, N = (e) => {
|
|
47
44
|
i(`/plans/${e.id}`);
|
|
48
45
|
};
|
|
49
|
-
return
|
|
46
|
+
return c && o.length === 0 ? /* @__PURE__ */ v("div", {
|
|
50
47
|
className: "space-y-6 p-6",
|
|
51
|
-
children: [/* @__PURE__ */
|
|
48
|
+
children: [/* @__PURE__ */ _("div", { className: "h-8 w-48 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ _("div", {
|
|
52
49
|
className: "grid grid-cols-1 md:grid-cols-3 gap-6",
|
|
53
50
|
children: [
|
|
54
51
|
1,
|
|
55
52
|
2,
|
|
56
53
|
3
|
|
57
|
-
].map((e) => /* @__PURE__ */
|
|
54
|
+
].map((e) => /* @__PURE__ */ v("div", {
|
|
58
55
|
className: "border border-border-subtle rounded-lg p-6 space-y-4",
|
|
59
56
|
children: [
|
|
60
|
-
/* @__PURE__ */
|
|
61
|
-
/* @__PURE__ */
|
|
62
|
-
/* @__PURE__ */
|
|
57
|
+
/* @__PURE__ */ _("div", { className: "h-6 w-24 bg-bg-sunken animate-pulse rounded" }),
|
|
58
|
+
/* @__PURE__ */ _("div", { className: "h-8 w-32 bg-bg-sunken animate-pulse rounded" }),
|
|
59
|
+
/* @__PURE__ */ _("div", {
|
|
63
60
|
className: "space-y-2",
|
|
64
61
|
children: [
|
|
65
62
|
1,
|
|
66
63
|
2,
|
|
67
64
|
3,
|
|
68
65
|
4
|
|
69
|
-
].map((e) => /* @__PURE__ */
|
|
66
|
+
].map((e) => /* @__PURE__ */ _("div", { className: "h-4 w-full bg-bg-sunken animate-pulse rounded" }, e))
|
|
70
67
|
})
|
|
71
68
|
]
|
|
72
69
|
}, e))
|
|
73
70
|
})]
|
|
74
|
-
}) : d ?
|
|
71
|
+
}) : d ? s(d) ? /* @__PURE__ */ _("div", {
|
|
75
72
|
className: "p-6",
|
|
76
|
-
children: /* @__PURE__ */
|
|
73
|
+
children: /* @__PURE__ */ _(n, {
|
|
77
74
|
title: r("billing.plans.serverUnavailable", "Server Unavailable"),
|
|
78
75
|
message: r("billing.plans.serverUnavailableMessage", "Unable to load pricing plans. The server might be down or experiencing issues."),
|
|
79
|
-
onRetry: () =>
|
|
76
|
+
onRetry: () => f(),
|
|
80
77
|
showRetry: !0
|
|
81
78
|
})
|
|
82
|
-
}) : /* @__PURE__ */
|
|
79
|
+
}) : /* @__PURE__ */ _("div", {
|
|
83
80
|
className: "flex items-center justify-center h-full min-h-[400px]",
|
|
84
|
-
children: /* @__PURE__ */
|
|
81
|
+
children: /* @__PURE__ */ v("div", {
|
|
85
82
|
className: "text-center space-y-4",
|
|
86
83
|
children: [
|
|
87
|
-
/* @__PURE__ */
|
|
84
|
+
/* @__PURE__ */ _("div", {
|
|
88
85
|
className: "size-12 mx-auto rounded-full bg-status-error-bg-subtle flex items-center justify-center",
|
|
89
|
-
children: /* @__PURE__ */
|
|
86
|
+
children: /* @__PURE__ */ _("svg", {
|
|
90
87
|
className: "size-6 text-status-error-text",
|
|
91
88
|
fill: "none",
|
|
92
89
|
viewBox: "0 0 24 24",
|
|
93
90
|
stroke: "currentColor",
|
|
94
|
-
children: /* @__PURE__ */
|
|
91
|
+
children: /* @__PURE__ */ _("path", {
|
|
95
92
|
strokeLinecap: "round",
|
|
96
93
|
strokeLinejoin: "round",
|
|
97
94
|
strokeWidth: 2,
|
|
@@ -99,126 +96,126 @@ var S = () => {
|
|
|
99
96
|
})
|
|
100
97
|
})
|
|
101
98
|
}),
|
|
102
|
-
/* @__PURE__ */
|
|
99
|
+
/* @__PURE__ */ _("h2", {
|
|
103
100
|
className: "text-lg font-semibold text-text-primary",
|
|
104
101
|
children: r("billing.plans.failedToLoad", "Failed to load plans")
|
|
105
102
|
}),
|
|
106
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ _("p", {
|
|
107
104
|
className: "text-sm text-text-muted",
|
|
108
105
|
children: d.message
|
|
109
106
|
}),
|
|
110
|
-
/* @__PURE__ */
|
|
107
|
+
/* @__PURE__ */ _("button", {
|
|
111
108
|
type: "button",
|
|
112
|
-
onClick: () =>
|
|
109
|
+
onClick: () => f(),
|
|
113
110
|
className: "px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors",
|
|
114
|
-
children: "Try Again"
|
|
111
|
+
children: r("billing.common.tryAgain", "Try Again")
|
|
115
112
|
})
|
|
116
113
|
]
|
|
117
114
|
})
|
|
118
|
-
}) : /* @__PURE__ */
|
|
115
|
+
}) : /* @__PURE__ */ v("div", {
|
|
119
116
|
className: "space-y-6 p-6",
|
|
120
117
|
children: [
|
|
121
|
-
/* @__PURE__ */
|
|
118
|
+
/* @__PURE__ */ v("div", {
|
|
122
119
|
className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
|
|
123
|
-
children: [/* @__PURE__ */
|
|
124
|
-
/* @__PURE__ */
|
|
120
|
+
children: [/* @__PURE__ */ v("div", { children: [
|
|
121
|
+
/* @__PURE__ */ _("h1", {
|
|
125
122
|
className: "text-2xl md:text-3xl font-semibold tracking-tight text-text-primary",
|
|
126
123
|
children: r("billing.plans.title", "Pricing Plans")
|
|
127
124
|
}),
|
|
128
|
-
/* @__PURE__ */
|
|
125
|
+
/* @__PURE__ */ _("p", {
|
|
129
126
|
className: "text-sm text-text-muted mt-1",
|
|
130
127
|
children: r("billing.plans.subtitle", "Choose the plan that best fits your needs")
|
|
131
128
|
}),
|
|
132
|
-
/* @__PURE__ */
|
|
129
|
+
/* @__PURE__ */ _(b, {
|
|
133
130
|
className: "mt-3",
|
|
134
131
|
children: r("billing.plans.listPurpose", "Manage the full catalog of pricing plans for this product — including inactive ones. Create new tiers, edit the quotas and price each plan grants, and activate or deactivate plans to control what customers can subscribe to.")
|
|
135
132
|
})
|
|
136
|
-
] }), a.canManagePlans && /* @__PURE__ */
|
|
133
|
+
] }), a.canManagePlans && /* @__PURE__ */ v("button", {
|
|
137
134
|
type: "button",
|
|
138
135
|
onClick: () => i("/plans/new"),
|
|
139
136
|
className: "inline-flex items-center gap-2 px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors",
|
|
140
|
-
children: [/* @__PURE__ */
|
|
137
|
+
children: [/* @__PURE__ */ _("svg", {
|
|
141
138
|
className: "size-4",
|
|
142
139
|
fill: "none",
|
|
143
140
|
viewBox: "0 0 24 24",
|
|
144
141
|
stroke: "currentColor",
|
|
145
|
-
children: /* @__PURE__ */
|
|
142
|
+
children: /* @__PURE__ */ _("path", {
|
|
146
143
|
strokeLinecap: "round",
|
|
147
144
|
strokeLinejoin: "round",
|
|
148
145
|
strokeWidth: 2,
|
|
149
146
|
d: "M12 4v16m8-8H4"
|
|
150
147
|
})
|
|
151
|
-
}), "Create Plan"]
|
|
148
|
+
}), r("billing.plans.createPlan", "Create Plan")]
|
|
152
149
|
})]
|
|
153
150
|
}),
|
|
154
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ v("div", {
|
|
155
152
|
className: "flex flex-wrap items-center gap-4 pb-4 border-b border-border-subtle",
|
|
156
153
|
children: [
|
|
157
|
-
/* @__PURE__ */
|
|
154
|
+
/* @__PURE__ */ v("div", {
|
|
158
155
|
className: "inline-flex rounded-lg border border-border-subtle p-1 bg-bg-sunken/50",
|
|
159
156
|
children: [
|
|
160
|
-
/* @__PURE__ */
|
|
157
|
+
/* @__PURE__ */ _("button", {
|
|
161
158
|
type: "button",
|
|
162
|
-
onClick: () =>
|
|
163
|
-
className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${
|
|
164
|
-
children: "All"
|
|
159
|
+
onClick: () => k("all"),
|
|
160
|
+
className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${O === "all" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-primary"}`,
|
|
161
|
+
children: r("billing.plans.all", "All")
|
|
165
162
|
}),
|
|
166
|
-
/* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ _("button", {
|
|
167
164
|
type: "button",
|
|
168
|
-
onClick: () =>
|
|
169
|
-
className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${
|
|
170
|
-
children: "Monthly"
|
|
165
|
+
onClick: () => k("monthly"),
|
|
166
|
+
className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${O === "monthly" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-primary"}`,
|
|
167
|
+
children: r("billing.plans.monthly", "Monthly")
|
|
171
168
|
}),
|
|
172
|
-
/* @__PURE__ */
|
|
169
|
+
/* @__PURE__ */ _("button", {
|
|
173
170
|
type: "button",
|
|
174
|
-
onClick: () =>
|
|
175
|
-
className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${
|
|
176
|
-
children: "Yearly"
|
|
171
|
+
onClick: () => k("yearly"),
|
|
172
|
+
className: `px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${O === "yearly" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-primary"}`,
|
|
173
|
+
children: r("billing.plans.yearly", "Yearly")
|
|
177
174
|
})
|
|
178
175
|
]
|
|
179
176
|
}),
|
|
180
|
-
a.canManagePlans && /* @__PURE__ */
|
|
177
|
+
a.canManagePlans && /* @__PURE__ */ v("label", {
|
|
181
178
|
className: "flex items-center gap-2 text-sm cursor-pointer",
|
|
182
|
-
children: [/* @__PURE__ */
|
|
179
|
+
children: [/* @__PURE__ */ _("input", {
|
|
183
180
|
type: "checkbox",
|
|
184
|
-
checked:
|
|
185
|
-
onChange: (e) =>
|
|
181
|
+
checked: E,
|
|
182
|
+
onChange: (e) => D(e.target.checked),
|
|
186
183
|
className: "size-4 rounded border-border-subtle text-text-link focus:ring-[var(--color-focus-ring)]"
|
|
187
|
-
}), /* @__PURE__ */
|
|
184
|
+
}), /* @__PURE__ */ _("span", {
|
|
188
185
|
className: "text-text-muted",
|
|
189
186
|
children: r("billing.plans.showInactive", "Show inactive plans")
|
|
190
187
|
})]
|
|
191
188
|
}),
|
|
192
|
-
/* @__PURE__ */
|
|
189
|
+
/* @__PURE__ */ v("div", {
|
|
193
190
|
className: "ml-auto inline-flex rounded-lg border border-border-subtle p-1 bg-bg-sunken/50",
|
|
194
|
-
children: [/* @__PURE__ */
|
|
191
|
+
children: [/* @__PURE__ */ _("button", {
|
|
195
192
|
type: "button",
|
|
196
|
-
onClick: () =>
|
|
197
|
-
className: `p-1.5 rounded-md transition-colors ${
|
|
198
|
-
title: "Grid view",
|
|
199
|
-
children: /* @__PURE__ */
|
|
193
|
+
onClick: () => T("grid"),
|
|
194
|
+
className: `p-1.5 rounded-md transition-colors ${S === "grid" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-primary"}`,
|
|
195
|
+
title: r("billing.plans.gridView", "Grid view"),
|
|
196
|
+
children: /* @__PURE__ */ _("svg", {
|
|
200
197
|
className: "size-4",
|
|
201
198
|
fill: "none",
|
|
202
199
|
viewBox: "0 0 24 24",
|
|
203
200
|
stroke: "currentColor",
|
|
204
|
-
children: /* @__PURE__ */
|
|
201
|
+
children: /* @__PURE__ */ _("path", {
|
|
205
202
|
strokeLinecap: "round",
|
|
206
203
|
strokeLinejoin: "round",
|
|
207
204
|
strokeWidth: 2,
|
|
208
205
|
d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"
|
|
209
206
|
})
|
|
210
207
|
})
|
|
211
|
-
}), /* @__PURE__ */
|
|
208
|
+
}), /* @__PURE__ */ _("button", {
|
|
212
209
|
type: "button",
|
|
213
|
-
onClick: () =>
|
|
214
|
-
className: `p-1.5 rounded-md transition-colors ${
|
|
215
|
-
title: "List view",
|
|
216
|
-
children: /* @__PURE__ */
|
|
210
|
+
onClick: () => T("list"),
|
|
211
|
+
className: `p-1.5 rounded-md transition-colors ${S === "list" ? "bg-bg-surface text-text-primary shadow-sm" : "text-text-muted hover:text-text-primary"}`,
|
|
212
|
+
title: r("billing.plans.listView", "List view"),
|
|
213
|
+
children: /* @__PURE__ */ _("svg", {
|
|
217
214
|
className: "size-4",
|
|
218
215
|
fill: "none",
|
|
219
216
|
viewBox: "0 0 24 24",
|
|
220
217
|
stroke: "currentColor",
|
|
221
|
-
children: /* @__PURE__ */
|
|
218
|
+
children: /* @__PURE__ */ _("path", {
|
|
222
219
|
strokeLinecap: "round",
|
|
223
220
|
strokeLinejoin: "round",
|
|
224
221
|
strokeWidth: 2,
|
|
@@ -229,203 +226,200 @@ var S = () => {
|
|
|
229
226
|
})
|
|
230
227
|
]
|
|
231
228
|
}),
|
|
232
|
-
|
|
229
|
+
A.length === 0 ? /* @__PURE__ */ _(y, {
|
|
233
230
|
illustration: "empty-data",
|
|
234
231
|
title: r("billing.plans.noPlansFound", "No plans found"),
|
|
235
|
-
description:
|
|
236
|
-
action: a.canManagePlans ? /* @__PURE__ */
|
|
232
|
+
description: E ? r("billing.plans.noPlansFiltered", "No plans match your current filters.") : r("billing.plans.noActivePlans", "There are no active plans available."),
|
|
233
|
+
action: a.canManagePlans ? /* @__PURE__ */ _("button", {
|
|
237
234
|
type: "button",
|
|
238
235
|
onClick: () => i("/plans/new"),
|
|
239
236
|
className: "px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors",
|
|
240
237
|
children: r("billing.plans.createFirstPlan", "Create your first plan")
|
|
241
238
|
}) : void 0
|
|
242
|
-
}) :
|
|
239
|
+
}) : S === "grid" ? /* @__PURE__ */ _("div", {
|
|
243
240
|
className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6",
|
|
244
|
-
children:
|
|
241
|
+
children: A.map((e) => /* @__PURE__ */ _(C, {
|
|
245
242
|
plan: e,
|
|
246
|
-
onSelect:
|
|
247
|
-
onView:
|
|
248
|
-
onToggle:
|
|
243
|
+
onSelect: M,
|
|
244
|
+
onView: N,
|
|
245
|
+
onToggle: j,
|
|
249
246
|
canSelect: a.canCreateSubscription,
|
|
250
247
|
canManage: a.canManagePlans,
|
|
251
|
-
isToggling:
|
|
248
|
+
isToggling: x
|
|
252
249
|
}, e.id))
|
|
253
|
-
}) : /* @__PURE__ */
|
|
250
|
+
}) : /* @__PURE__ */ _("div", {
|
|
254
251
|
className: "space-y-3",
|
|
255
|
-
children:
|
|
252
|
+
children: A.map((e) => /* @__PURE__ */ _(w, {
|
|
256
253
|
plan: e,
|
|
257
|
-
onSelect:
|
|
258
|
-
onView:
|
|
259
|
-
onToggle:
|
|
254
|
+
onSelect: M,
|
|
255
|
+
onView: N,
|
|
256
|
+
onToggle: j,
|
|
260
257
|
canSelect: a.canCreateSubscription,
|
|
261
258
|
canManage: a.canManagePlans,
|
|
262
|
-
isToggling:
|
|
259
|
+
isToggling: x
|
|
263
260
|
}, e.id))
|
|
264
261
|
})
|
|
265
262
|
]
|
|
266
263
|
});
|
|
267
|
-
}, C = ({ plan:
|
|
268
|
-
let
|
|
269
|
-
return /* @__PURE__ */
|
|
270
|
-
className: `relative border rounded-card p-6 flex flex-col h-full transition-[box-shadow,transform] duration-200 ease-[var(--motion-easing-out)] ${
|
|
264
|
+
}, C = ({ plan: t, onSelect: n, onView: s, onToggle: c, canSelect: l, canManage: u, isToggling: p }) => {
|
|
265
|
+
let m = e(), g = f(), y = h(() => x(t.features || []), [t.features]);
|
|
266
|
+
return /* @__PURE__ */ v("div", {
|
|
267
|
+
className: `relative border rounded-card p-6 flex flex-col h-full transition-[box-shadow,transform] duration-200 ease-[var(--motion-easing-out)] ${t.isActive ? "border-border-seam bg-bg-surface shadow-[var(--shadow-pop)] hover:shadow-[var(--shadow-elevation-2)] [@media(hover:none)]:" : "border-dashed border-text-muted/30 bg-bg-sunken/30 shadow-elevation-1"}`,
|
|
271
268
|
children: [
|
|
272
|
-
!
|
|
269
|
+
!t.isActive && /* @__PURE__ */ _("span", {
|
|
273
270
|
className: "absolute top-4 right-4 px-2 py-1 text-xs font-medium bg-bg-sunken text-text-muted rounded",
|
|
274
|
-
children: "Inactive"
|
|
271
|
+
children: m("billing.common.inactive", "Inactive")
|
|
275
272
|
}),
|
|
276
|
-
/* @__PURE__ */
|
|
273
|
+
/* @__PURE__ */ v("div", {
|
|
277
274
|
className: "mb-4",
|
|
278
|
-
children: [/* @__PURE__ */
|
|
275
|
+
children: [/* @__PURE__ */ _("h3", {
|
|
279
276
|
className: "text-xl font-bold text-text-primary",
|
|
280
|
-
children:
|
|
281
|
-
}), /* @__PURE__ */
|
|
277
|
+
children: t.name
|
|
278
|
+
}), /* @__PURE__ */ _("span", {
|
|
282
279
|
className: "text-sm text-text-muted",
|
|
283
|
-
children:
|
|
280
|
+
children: o(t.duration)
|
|
284
281
|
})]
|
|
285
282
|
}),
|
|
286
|
-
/* @__PURE__ */
|
|
283
|
+
/* @__PURE__ */ v("div", {
|
|
287
284
|
className: "flex items-baseline gap-1 mb-1",
|
|
288
|
-
children: [/* @__PURE__ */
|
|
285
|
+
children: [/* @__PURE__ */ _("span", {
|
|
289
286
|
className: "text-3xl font-bold text-text-primary",
|
|
290
287
|
children: (() => {
|
|
291
|
-
let
|
|
292
|
-
price:
|
|
293
|
-
currency:
|
|
288
|
+
let e = t.pricingModel === r.PER_SEAT && t.pricePerSeat ? {
|
|
289
|
+
price: t.pricePerSeat,
|
|
290
|
+
currency: t.currency
|
|
294
291
|
} : {
|
|
295
|
-
price:
|
|
296
|
-
currency:
|
|
297
|
-
}, { price:
|
|
298
|
-
return
|
|
292
|
+
price: t.price,
|
|
293
|
+
currency: t.currency
|
|
294
|
+
}, { price: n, currency: a } = d(e.price, e.currency, t.currencyPrices, g);
|
|
295
|
+
return i(n, a);
|
|
299
296
|
})()
|
|
300
|
-
}), /* @__PURE__ */
|
|
297
|
+
}), /* @__PURE__ */ v("span", {
|
|
301
298
|
className: "text-text-muted",
|
|
302
|
-
children: ["/ ",
|
|
299
|
+
children: ["/ ", a(t.duration)]
|
|
303
300
|
})]
|
|
304
301
|
}),
|
|
305
|
-
|
|
302
|
+
t.pricingModel === r.PER_SEAT && /* @__PURE__ */ v("p", {
|
|
306
303
|
className: "text-xs text-text-muted mb-4",
|
|
307
|
-
children: ["per seat",
|
|
304
|
+
children: [m("billing.plans.perSeat", "per seat"), t.minSeats ? ` · ${m("billing.plans.minSeats", "min {{count}} seat{{plural}}", {
|
|
305
|
+
count: t.minSeats,
|
|
306
|
+
plural: t.minSeats === 1 ? "" : "s"
|
|
307
|
+
})}` : ""]
|
|
308
308
|
}),
|
|
309
|
-
|
|
310
|
-
|
|
309
|
+
t.pricingModel !== r.PER_SEAT && /* @__PURE__ */ _("div", { className: "mb-6" }),
|
|
310
|
+
y.length > 0 && /* @__PURE__ */ v("ul", {
|
|
311
311
|
className: "space-y-2 mb-6",
|
|
312
|
-
children: [
|
|
312
|
+
children: [y.slice(0, 5).map((e) => /* @__PURE__ */ v("li", {
|
|
313
313
|
className: "flex items-center justify-between text-sm",
|
|
314
|
-
children: [/* @__PURE__ */
|
|
314
|
+
children: [/* @__PURE__ */ v("div", {
|
|
315
315
|
className: "flex items-center gap-2",
|
|
316
|
-
children: [/* @__PURE__ */
|
|
316
|
+
children: [/* @__PURE__ */ _("svg", {
|
|
317
317
|
className: "size-5 text-status-success-text shrink-0",
|
|
318
318
|
fill: "none",
|
|
319
319
|
viewBox: "0 0 24 24",
|
|
320
320
|
stroke: "currentColor",
|
|
321
|
-
children: /* @__PURE__ */
|
|
321
|
+
children: /* @__PURE__ */ _("path", {
|
|
322
322
|
strokeLinecap: "round",
|
|
323
323
|
strokeLinejoin: "round",
|
|
324
324
|
strokeWidth: 2,
|
|
325
325
|
d: "M5 13l4 4L19 7"
|
|
326
326
|
})
|
|
327
|
-
}), /* @__PURE__ */
|
|
327
|
+
}), /* @__PURE__ */ _("span", {
|
|
328
328
|
className: "text-text-primary",
|
|
329
329
|
children: e.name
|
|
330
330
|
})]
|
|
331
|
-
}), /* @__PURE__ */
|
|
331
|
+
}), /* @__PURE__ */ _("span", {
|
|
332
332
|
className: "font-medium text-text-primary",
|
|
333
333
|
children: e.totalValue.toLocaleString()
|
|
334
334
|
})]
|
|
335
|
-
}, e.quotaId)),
|
|
335
|
+
}, e.quotaId)), y.length > 5 && /* @__PURE__ */ _("li", {
|
|
336
336
|
className: "text-sm text-text-muted pl-7",
|
|
337
|
-
children:
|
|
338
|
-
"+",
|
|
339
|
-
h.length - 5,
|
|
340
|
-
" more quotas"
|
|
341
|
-
]
|
|
337
|
+
children: m("billing.plans.moreQuotas", "+{{count}} more quotas", { count: y.length - 5 })
|
|
342
338
|
})]
|
|
343
339
|
}),
|
|
344
|
-
/* @__PURE__ */
|
|
340
|
+
/* @__PURE__ */ v("div", {
|
|
345
341
|
className: "space-y-2 pt-4 border-t border-border-subtle mt-auto",
|
|
346
|
-
children: [
|
|
342
|
+
children: [l && t.isActive && /* @__PURE__ */ _("button", {
|
|
347
343
|
type: "button",
|
|
348
|
-
onClick: () => t
|
|
344
|
+
onClick: () => n(t),
|
|
349
345
|
className: "w-full px-4 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors",
|
|
350
|
-
children: "Select Plan"
|
|
351
|
-
}), /* @__PURE__ */
|
|
346
|
+
children: m("billing.plans.selectPlan", "Select Plan")
|
|
347
|
+
}), /* @__PURE__ */ v("div", {
|
|
352
348
|
className: "flex gap-2",
|
|
353
|
-
children: [/* @__PURE__ */
|
|
349
|
+
children: [/* @__PURE__ */ _("button", {
|
|
354
350
|
type: "button",
|
|
355
|
-
onClick: () =>
|
|
351
|
+
onClick: () => s(t),
|
|
356
352
|
className: "flex-1 px-4 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors",
|
|
357
|
-
children: "View Details"
|
|
358
|
-
}),
|
|
353
|
+
children: m("billing.plans.viewDetails", "View Details")
|
|
354
|
+
}), u && /* @__PURE__ */ _("button", {
|
|
359
355
|
type: "button",
|
|
360
|
-
onClick: () =>
|
|
361
|
-
disabled:
|
|
362
|
-
className: `px-4 py-2 text-sm font-medium border border-border-subtle rounded-md transition-colors ${
|
|
363
|
-
children:
|
|
356
|
+
onClick: () => c(t),
|
|
357
|
+
disabled: p,
|
|
358
|
+
className: `px-4 py-2 text-sm font-medium border border-border-subtle rounded-md transition-colors ${t.isActive ? "text-status-error-text hover:bg-status-error-bg-subtle" : "text-status-success-text hover:bg-status-success-bg-subtle"}`,
|
|
359
|
+
children: t.isActive ? m("billing.plans.deactivate", "Deactivate") : m("billing.plans.activate", "Activate")
|
|
364
360
|
})]
|
|
365
361
|
})]
|
|
366
362
|
})
|
|
367
363
|
]
|
|
368
364
|
});
|
|
369
|
-
}, w = ({ plan:
|
|
370
|
-
let
|
|
371
|
-
return /* @__PURE__ */
|
|
372
|
-
className: `flex items-center gap-4 p-4 border rounded-card shadow-[var(--shadow-elevation-1)] transition-all duration-200 hover:border-border-strong hover:shadow-[var(--shadow-elevation-2)] ${
|
|
365
|
+
}, w = ({ plan: t, onSelect: n, onView: r, onToggle: o, canSelect: s, canManage: c, isToggling: l }) => {
|
|
366
|
+
let u = e(), p = f(), m = h(() => x(t.features || []), [t.features]);
|
|
367
|
+
return /* @__PURE__ */ v("div", {
|
|
368
|
+
className: `flex items-center gap-4 p-4 border rounded-card shadow-[var(--shadow-elevation-1)] transition-all duration-200 hover:border-border-strong hover:shadow-[var(--shadow-elevation-2)] ${t.isActive ? "border-border-subtle bg-bg-surface" : "border-dashed border-text-muted/30 bg-bg-sunken/30"}`,
|
|
373
369
|
children: [
|
|
374
|
-
/* @__PURE__ */
|
|
370
|
+
/* @__PURE__ */ v("div", {
|
|
375
371
|
className: "flex-1 min-w-0",
|
|
376
|
-
children: [/* @__PURE__ */
|
|
372
|
+
children: [/* @__PURE__ */ v("div", {
|
|
377
373
|
className: "flex items-center gap-2",
|
|
378
|
-
children: [/* @__PURE__ */
|
|
374
|
+
children: [/* @__PURE__ */ _("h3", {
|
|
379
375
|
className: "font-semibold text-text-primary truncate",
|
|
380
|
-
children:
|
|
381
|
-
}), !
|
|
376
|
+
children: t.name
|
|
377
|
+
}), !t.isActive && /* @__PURE__ */ _("span", {
|
|
382
378
|
className: "px-2 py-0.5 text-xs font-medium bg-bg-sunken text-text-muted rounded",
|
|
383
|
-
children: "Inactive"
|
|
379
|
+
children: u("billing.common.inactive", "Inactive")
|
|
384
380
|
})]
|
|
385
381
|
}), /* @__PURE__ */ _("p", {
|
|
386
382
|
className: "text-sm text-text-muted",
|
|
387
|
-
children:
|
|
388
|
-
|
|
389
|
-
"
|
|
390
|
-
|
|
391
|
-
" included"
|
|
392
|
-
]
|
|
383
|
+
children: u("billing.plans.quotasIncludedCount", "{{count}} quota{{plural}} included", {
|
|
384
|
+
count: m.length,
|
|
385
|
+
plural: m.length === 1 ? "" : "s"
|
|
386
|
+
})
|
|
393
387
|
})]
|
|
394
388
|
}),
|
|
395
|
-
/* @__PURE__ */
|
|
389
|
+
/* @__PURE__ */ v("div", {
|
|
396
390
|
className: "text-right",
|
|
397
|
-
children: [/* @__PURE__ */
|
|
391
|
+
children: [/* @__PURE__ */ _("div", {
|
|
398
392
|
className: "font-semibold text-text-primary",
|
|
399
393
|
children: (() => {
|
|
400
|
-
let { price:
|
|
401
|
-
return
|
|
394
|
+
let { price: e, currency: n } = d(t.price, t.currency, t.currencyPrices, p);
|
|
395
|
+
return i(e, n);
|
|
402
396
|
})()
|
|
403
|
-
}), /* @__PURE__ */
|
|
397
|
+
}), /* @__PURE__ */ v("div", {
|
|
404
398
|
className: "text-sm text-text-muted",
|
|
405
|
-
children: ["per ",
|
|
399
|
+
children: ["per ", a(t.duration)]
|
|
406
400
|
})]
|
|
407
401
|
}),
|
|
408
|
-
/* @__PURE__ */
|
|
402
|
+
/* @__PURE__ */ v("div", {
|
|
409
403
|
className: "flex items-center gap-2",
|
|
410
404
|
children: [
|
|
411
|
-
|
|
405
|
+
s && t.isActive && /* @__PURE__ */ _("button", {
|
|
412
406
|
type: "button",
|
|
413
|
-
onClick: () => t
|
|
407
|
+
onClick: () => n(t),
|
|
414
408
|
className: "px-3 py-1.5 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors",
|
|
415
|
-
children: "Select"
|
|
409
|
+
children: u("billing.common.select", "Select")
|
|
416
410
|
}),
|
|
417
|
-
/* @__PURE__ */
|
|
411
|
+
/* @__PURE__ */ _("button", {
|
|
418
412
|
type: "button",
|
|
419
|
-
onClick: () =>
|
|
413
|
+
onClick: () => r(t),
|
|
420
414
|
className: "px-3 py-1.5 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors",
|
|
421
|
-
children: "View"
|
|
415
|
+
children: u("billing.common.view", "View")
|
|
422
416
|
}),
|
|
423
|
-
|
|
417
|
+
c && /* @__PURE__ */ _("button", {
|
|
424
418
|
type: "button",
|
|
425
|
-
onClick: () =>
|
|
426
|
-
disabled:
|
|
427
|
-
className: `px-3 py-1.5 text-sm font-medium border border-border-subtle rounded-md transition-colors ${
|
|
428
|
-
children:
|
|
419
|
+
onClick: () => o(t),
|
|
420
|
+
disabled: l,
|
|
421
|
+
className: `px-3 py-1.5 text-sm font-medium border border-border-subtle rounded-md transition-colors ${t.isActive ? "text-status-error-text hover:bg-status-error-bg-subtle" : "text-status-success-text hover:bg-status-success-bg-subtle"}`,
|
|
422
|
+
children: t.isActive ? u("billing.plans.deactivate", "Deactivate") : u("billing.plans.activate", "Activate")
|
|
429
423
|
})
|
|
430
424
|
]
|
|
431
425
|
})
|