@burdenoff/microfe-billing 2026.828.2 → 2026.828.4
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/hooks/useProducts.js +14 -0
- package/dist/billing/hooks/useProducts.js.map +1 -0
- package/dist/billing/modules/addons/pages/AddonCreatePage.js +159 -151
- package/dist/billing/modules/addons/pages/AddonCreatePage.js.map +1 -1
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js +18 -3
- package/dist/billing/modules/plans/pages/PlanBrowseDetailPage.js.map +1 -1
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js +1 -1
- package/dist/billing/modules/subscriptions/pages/UpgradeSubscriptionPage.js.map +1 -1
- package/dist/billing/shared/types/graphql.js.map +1 -1
- package/dist/generated/global-operations.js +20 -1
- package/dist/generated/global-operations.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useListProductsForSelectorQuery as e } from "../../generated/global-operations.js";
|
|
2
|
+
//#region src/billing/hooks/useProducts.ts
|
|
3
|
+
function t() {
|
|
4
|
+
let { data: t, loading: n, error: r } = e({ fetchPolicy: "cache-and-network" });
|
|
5
|
+
return {
|
|
6
|
+
products: t?.platformProducts.items ?? [],
|
|
7
|
+
isLoading: n,
|
|
8
|
+
error: r
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { t as useProducts };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=useProducts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProducts.js","names":[],"sources":["../../../src/billing/hooks/useProducts.ts"],"sourcesContent":["/**\n * Shared hook for fetching the active platform products list — used to back\n * product selectors (e.g. the addon create form) so admins pick a product by\n * name instead of typing its ID by hand.\n */\nimport { useListProductsForSelectorQuery } from '../../generated/global-operations';\n\nexport interface ProductOption {\n id: string;\n name: string;\n}\n\ninterface UseProductsResult {\n products: ProductOption[];\n isLoading: boolean;\n error: Error | undefined;\n}\n\nexport function useProducts(): UseProductsResult {\n const { data, loading, error } = useListProductsForSelectorQuery({\n fetchPolicy: 'cache-and-network',\n });\n\n return {\n products: data?.platformProducts.items ?? [],\n isLoading: loading,\n error: error as Error | undefined,\n };\n}\n"],"mappings":";;AAkBA,SAAgB,IAAiC;CAC/C,IAAM,EAAE,SAAM,YAAS,aAAU,EAAgC,EAC/D,aAAa,oBACf,CAAC;CAED,OAAO;EACL,UAAU,GAAM,iBAAiB,SAAS,CAAC;EAC3C,WAAW;EACJ;CACT;AACF"}
|
|
@@ -9,20 +9,21 @@ import { useAddonMutations as o } from "../hooks/useAddons.js";
|
|
|
9
9
|
import "../hooks/index.js";
|
|
10
10
|
import { useQuotas as s } from "../../plans/hooks/useQuotas.js";
|
|
11
11
|
import "../../plans/hooks/index.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
12
|
+
import { useProducts as c } from "../../../hooks/useProducts.js";
|
|
13
|
+
import { useState as l } from "react";
|
|
14
|
+
import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
15
|
+
import { useI18n as p } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
16
|
+
import { PagePurpose as m } from "@burdenoff/fe-libs/ui";
|
|
16
17
|
//#region src/billing/modules/addons/pages/AddonCreatePage.tsx
|
|
17
|
-
var
|
|
18
|
-
let { t:
|
|
19
|
-
let n =
|
|
18
|
+
var h = () => {
|
|
19
|
+
let { t: h } = p(), g = (e, t) => {
|
|
20
|
+
let n = h(e);
|
|
20
21
|
return n === e ? t : n;
|
|
21
|
-
},
|
|
22
|
-
if (!
|
|
23
|
-
if (
|
|
22
|
+
}, _ = a(), v = i(), { quotas: y, isLoading: b } = s({ onlyActive: !0 }), { products: x, isLoading: S } = c(), { createAddon: C, isCreating: w } = o(), [T, E] = l(""), [D, O] = l(""), [k, A] = l("USD"), [j, M] = l(r.MONTHLY), [N, P] = l(""), [F, I] = l([]), [L, R] = l([]), [z, B] = l(null), [V, H] = l(!1);
|
|
23
|
+
if (!v.canManageAddons) return /* @__PURE__ */ d(e, { message: g("billing.addons.noCreatePermission", "You don't have permission to create addons.") });
|
|
24
|
+
if (b || S) return /* @__PURE__ */ f("div", {
|
|
24
25
|
className: "space-y-6 p-6",
|
|
25
|
-
children: [/* @__PURE__ */
|
|
26
|
+
children: [/* @__PURE__ */ d("div", { className: "h-8 w-48 bg-bg-sunken animate-pulse rounded" }), /* @__PURE__ */ d("div", {
|
|
26
27
|
className: "max-w-2xl space-y-4",
|
|
27
28
|
children: [
|
|
28
29
|
1,
|
|
@@ -30,261 +31,268 @@ var m = () => {
|
|
|
30
31
|
3,
|
|
31
32
|
4,
|
|
32
33
|
5
|
|
33
|
-
].map((e) => /* @__PURE__ */
|
|
34
|
+
].map((e) => /* @__PURE__ */ d("div", { className: "h-16 bg-bg-sunken animate-pulse rounded" }, e))
|
|
34
35
|
})]
|
|
35
36
|
});
|
|
36
|
-
let
|
|
37
|
-
|
|
37
|
+
let U = () => {
|
|
38
|
+
I([{
|
|
38
39
|
quotaId: "",
|
|
39
40
|
quantity: 1
|
|
40
|
-
}, ...
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
},
|
|
44
|
-
let r = [...
|
|
45
|
-
t === "quotaId" ? r[e].quotaId = n : r[e].quantity = Number(n),
|
|
41
|
+
}, ...F]);
|
|
42
|
+
}, W = (e) => {
|
|
43
|
+
I(F.filter((t, n) => n !== e));
|
|
44
|
+
}, G = (e, t, n) => {
|
|
45
|
+
let r = [...F];
|
|
46
|
+
t === "quotaId" ? r[e].quotaId = n : r[e].quantity = Number(n), I(r);
|
|
46
47
|
};
|
|
47
|
-
return /* @__PURE__ */
|
|
48
|
+
return /* @__PURE__ */ f("div", {
|
|
48
49
|
className: "space-y-6 p-6",
|
|
49
50
|
children: [
|
|
50
|
-
/* @__PURE__ */
|
|
51
|
-
title:
|
|
52
|
-
description:
|
|
51
|
+
/* @__PURE__ */ d(t, {
|
|
52
|
+
title: g("billing.addons.createNewAddon", "Create New Addon"),
|
|
53
|
+
description: g("billing.addons.createNewAddonDesc", "Set up a new addon with quotas")
|
|
53
54
|
}),
|
|
54
|
-
/* @__PURE__ */
|
|
55
|
-
/* @__PURE__ */
|
|
55
|
+
/* @__PURE__ */ d(m, { children: g("billing.addons.createPurpose", "Create an add-on that customers can buy on top of a subscription — extra seats, storage, usage credits and so on. Set its price (with optional per-currency overrides) and the quotas it grants, then make it available to purchase.") }),
|
|
56
|
+
/* @__PURE__ */ f("form", {
|
|
56
57
|
onSubmit: async (e) => {
|
|
57
|
-
if (e.preventDefault(),
|
|
58
|
-
|
|
58
|
+
if (e.preventDefault(), B(null), H(!1), !T.trim()) {
|
|
59
|
+
B("Addon name is required");
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
61
|
-
if (!
|
|
62
|
-
|
|
62
|
+
if (!D || isNaN(Number(D)) || Number(D) < 0) {
|
|
63
|
+
B("Valid price is required");
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
65
|
-
if (!
|
|
66
|
-
|
|
66
|
+
if (!N.trim()) {
|
|
67
|
+
B("Product ID is required");
|
|
67
68
|
return;
|
|
68
69
|
}
|
|
69
|
-
if (
|
|
70
|
-
|
|
70
|
+
if (F.length === 0) {
|
|
71
|
+
B("At least one quota is required");
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
|
-
if (
|
|
74
|
-
|
|
74
|
+
if (F.filter((e) => e.quotaId === "").length > 0) {
|
|
75
|
+
B("Please select a quota for all allocations");
|
|
75
76
|
return;
|
|
76
77
|
}
|
|
77
78
|
let t = {
|
|
78
|
-
name:
|
|
79
|
-
price: Number(
|
|
80
|
-
currency:
|
|
81
|
-
duration:
|
|
82
|
-
productId:
|
|
83
|
-
quotas:
|
|
79
|
+
name: T.trim(),
|
|
80
|
+
price: Number(D),
|
|
81
|
+
currency: k,
|
|
82
|
+
duration: j,
|
|
83
|
+
productId: N.trim(),
|
|
84
|
+
quotas: F.map((e) => ({
|
|
84
85
|
quotaId: e.quotaId,
|
|
85
86
|
quantity: e.quantity
|
|
86
87
|
})),
|
|
87
|
-
...
|
|
88
|
+
...L.length > 0 ? { currencyPriceOverrides: L } : {}
|
|
88
89
|
};
|
|
89
90
|
try {
|
|
90
|
-
await
|
|
91
|
+
await C(t), H(!0), setTimeout(() => _("/addons"), 1500);
|
|
91
92
|
} catch (e) {
|
|
92
|
-
|
|
93
|
+
B(e instanceof Error ? e.message : "Failed to create addon");
|
|
93
94
|
}
|
|
94
95
|
},
|
|
95
96
|
className: "space-y-6",
|
|
96
97
|
children: [
|
|
97
|
-
|
|
98
|
+
z && /* @__PURE__ */ d("div", {
|
|
98
99
|
className: "p-4 bg-status-error-bg-subtle border border-border-subtle rounded-lg",
|
|
99
|
-
children: /* @__PURE__ */
|
|
100
|
+
children: /* @__PURE__ */ d("p", {
|
|
100
101
|
className: "text-sm text-status-error-text",
|
|
101
|
-
children:
|
|
102
|
+
children: z
|
|
102
103
|
})
|
|
103
104
|
}),
|
|
104
|
-
|
|
105
|
+
V && /* @__PURE__ */ d("div", {
|
|
105
106
|
className: "p-4 bg-status-success-bg-subtle border border-border-subtle rounded-lg",
|
|
106
|
-
children: /* @__PURE__ */
|
|
107
|
+
children: /* @__PURE__ */ d("p", {
|
|
107
108
|
className: "text-sm text-status-success-text",
|
|
108
|
-
children:
|
|
109
|
+
children: g("billing.addons.createSuccess", "Addon created successfully! Redirecting...")
|
|
109
110
|
})
|
|
110
111
|
}),
|
|
111
|
-
/* @__PURE__ */
|
|
112
|
+
/* @__PURE__ */ f("div", {
|
|
112
113
|
className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
|
|
113
|
-
children: [/* @__PURE__ */
|
|
114
|
+
children: [/* @__PURE__ */ f("div", {
|
|
114
115
|
className: "border border-border-seam rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)] h-fit",
|
|
115
|
-
children: [/* @__PURE__ */
|
|
116
|
+
children: [/* @__PURE__ */ d("div", {
|
|
116
117
|
className: "p-4 border-b border-border-subtle bg-bg-sunken/30",
|
|
117
|
-
children: /* @__PURE__ */
|
|
118
|
+
children: /* @__PURE__ */ d("h2", {
|
|
118
119
|
className: "font-semibold text-text-primary",
|
|
119
|
-
children:
|
|
120
|
+
children: g("billing.addons.basicInfo", "Basic Information")
|
|
120
121
|
})
|
|
121
|
-
}), /* @__PURE__ */
|
|
122
|
+
}), /* @__PURE__ */ f("div", {
|
|
122
123
|
className: "p-4 space-y-4",
|
|
123
124
|
children: [
|
|
124
|
-
/* @__PURE__ */
|
|
125
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ f("label", {
|
|
125
126
|
htmlFor: "name",
|
|
126
127
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
127
|
-
children: [
|
|
128
|
-
}), /* @__PURE__ */
|
|
128
|
+
children: [g("billing.addons.addonNameLabel", "Addon Name"), " *"]
|
|
129
|
+
}), /* @__PURE__ */ d("input", {
|
|
129
130
|
id: "name",
|
|
130
131
|
type: "text",
|
|
131
|
-
value:
|
|
132
|
-
onChange: (e) =>
|
|
132
|
+
value: T,
|
|
133
|
+
onChange: (e) => E(e.target.value),
|
|
133
134
|
className: "w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
134
|
-
placeholder:
|
|
135
|
+
placeholder: g("billing.addons.addonNamePlaceholder", "e.g., Extra Storage"),
|
|
135
136
|
required: !0
|
|
136
137
|
})] }),
|
|
137
|
-
/* @__PURE__ */
|
|
138
|
-
/* @__PURE__ */
|
|
138
|
+
/* @__PURE__ */ f("div", { children: [
|
|
139
|
+
/* @__PURE__ */ f("label", {
|
|
139
140
|
htmlFor: "productId",
|
|
140
141
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
141
|
-
children: [
|
|
142
|
+
children: [g("billing.addons.product", "Product"), " *"]
|
|
142
143
|
}),
|
|
143
|
-
/* @__PURE__ */
|
|
144
|
+
/* @__PURE__ */ f("select", {
|
|
144
145
|
id: "productId",
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
className:
|
|
149
|
-
|
|
150
|
-
|
|
146
|
+
value: N,
|
|
147
|
+
onChange: (e) => P(e.target.value),
|
|
148
|
+
disabled: x.length === 0,
|
|
149
|
+
className: `w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] disabled:opacity-50 ${N === "" ? "text-text-muted" : "text-text-primary"}`,
|
|
150
|
+
required: !0,
|
|
151
|
+
children: [/* @__PURE__ */ d("option", {
|
|
152
|
+
value: "",
|
|
153
|
+
disabled: !0,
|
|
154
|
+
children: g("billing.addons.selectProduct", "Select a product...")
|
|
155
|
+
}), x.map((e) => /* @__PURE__ */ d("option", {
|
|
156
|
+
value: e.id,
|
|
157
|
+
children: e.name
|
|
158
|
+
}, e.id))]
|
|
151
159
|
}),
|
|
152
|
-
/* @__PURE__ */
|
|
160
|
+
/* @__PURE__ */ d("p", {
|
|
153
161
|
className: "text-xs text-text-muted mt-1",
|
|
154
|
-
children:
|
|
162
|
+
children: x.length === 0 ? g("billing.addons.noProductsAvailable", "No active products found.") : g("billing.addons.productIdDesc", "The product this addon belongs to")
|
|
155
163
|
})
|
|
156
164
|
] }),
|
|
157
|
-
/* @__PURE__ */
|
|
165
|
+
/* @__PURE__ */ f("div", {
|
|
158
166
|
className: "grid grid-cols-2 gap-4",
|
|
159
|
-
children: [/* @__PURE__ */
|
|
167
|
+
children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ f("label", {
|
|
160
168
|
htmlFor: "price",
|
|
161
169
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
162
|
-
children: [
|
|
163
|
-
}), /* @__PURE__ */
|
|
170
|
+
children: [g("billing.addons.priceLabel", "Price"), " *"]
|
|
171
|
+
}), /* @__PURE__ */ d("input", {
|
|
164
172
|
id: "price",
|
|
165
173
|
type: "number",
|
|
166
174
|
step: "0.01",
|
|
167
175
|
min: "0",
|
|
168
|
-
value:
|
|
169
|
-
onChange: (e) =>
|
|
176
|
+
value: D,
|
|
177
|
+
onChange: (e) => O(e.target.value),
|
|
170
178
|
className: "w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
171
179
|
placeholder: "9.99",
|
|
172
180
|
required: !0
|
|
173
|
-
})] }), /* @__PURE__ */
|
|
181
|
+
})] }), /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ f("label", {
|
|
174
182
|
htmlFor: "currency",
|
|
175
183
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
176
|
-
children: [
|
|
177
|
-
}), /* @__PURE__ */
|
|
184
|
+
children: [g("billing.addons.currencyLabel", "Currency"), " *"]
|
|
185
|
+
}), /* @__PURE__ */ f("select", {
|
|
178
186
|
id: "currency",
|
|
179
|
-
value:
|
|
180
|
-
onChange: (e) =>
|
|
187
|
+
value: k,
|
|
188
|
+
onChange: (e) => A(e.target.value),
|
|
181
189
|
className: "w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
182
190
|
children: [
|
|
183
|
-
/* @__PURE__ */
|
|
191
|
+
/* @__PURE__ */ d("option", {
|
|
184
192
|
value: "USD",
|
|
185
193
|
children: "USD ($)"
|
|
186
194
|
}),
|
|
187
|
-
/* @__PURE__ */
|
|
195
|
+
/* @__PURE__ */ d("option", {
|
|
188
196
|
value: "EUR",
|
|
189
197
|
children: "EUR"
|
|
190
198
|
}),
|
|
191
|
-
/* @__PURE__ */
|
|
199
|
+
/* @__PURE__ */ d("option", {
|
|
192
200
|
value: "GBP",
|
|
193
201
|
children: "GBP"
|
|
194
202
|
}),
|
|
195
|
-
/* @__PURE__ */
|
|
203
|
+
/* @__PURE__ */ d("option", {
|
|
196
204
|
value: "INR",
|
|
197
205
|
children: "INR"
|
|
198
206
|
}),
|
|
199
|
-
/* @__PURE__ */
|
|
207
|
+
/* @__PURE__ */ d("option", {
|
|
200
208
|
value: "AUD",
|
|
201
209
|
children: "AUD"
|
|
202
210
|
}),
|
|
203
|
-
/* @__PURE__ */
|
|
211
|
+
/* @__PURE__ */ d("option", {
|
|
204
212
|
value: "CAD",
|
|
205
213
|
children: "CAD"
|
|
206
214
|
}),
|
|
207
|
-
/* @__PURE__ */
|
|
215
|
+
/* @__PURE__ */ d("option", {
|
|
208
216
|
value: "JPY",
|
|
209
217
|
children: "JPY"
|
|
210
218
|
}),
|
|
211
|
-
/* @__PURE__ */
|
|
219
|
+
/* @__PURE__ */ d("option", {
|
|
212
220
|
value: "SGD",
|
|
213
221
|
children: "SGD"
|
|
214
222
|
})
|
|
215
223
|
]
|
|
216
224
|
})] })]
|
|
217
225
|
}),
|
|
218
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ f("label", {
|
|
219
227
|
htmlFor: "duration",
|
|
220
228
|
className: "block text-sm font-medium text-text-primary mb-1",
|
|
221
|
-
children: [
|
|
222
|
-
}), /* @__PURE__ */
|
|
229
|
+
children: [g("billing.addons.billingPeriodLabel", "Billing Period"), " *"]
|
|
230
|
+
}), /* @__PURE__ */ f("select", {
|
|
223
231
|
id: "duration",
|
|
224
|
-
value:
|
|
225
|
-
onChange: (e) =>
|
|
232
|
+
value: j,
|
|
233
|
+
onChange: (e) => M(e.target.value),
|
|
226
234
|
className: "w-full px-3 py-2 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
|
|
227
|
-
children: [/* @__PURE__ */
|
|
235
|
+
children: [/* @__PURE__ */ d("option", {
|
|
228
236
|
value: r.MONTHLY,
|
|
229
237
|
children: "Monthly"
|
|
230
|
-
}), /* @__PURE__ */
|
|
238
|
+
}), /* @__PURE__ */ d("option", {
|
|
231
239
|
value: r.YEARLY,
|
|
232
240
|
children: "Yearly"
|
|
233
241
|
})]
|
|
234
242
|
})] })
|
|
235
243
|
]
|
|
236
244
|
})]
|
|
237
|
-
}), /* @__PURE__ */
|
|
245
|
+
}), /* @__PURE__ */ f("div", {
|
|
238
246
|
className: "border border-border-seam rounded-card bg-bg-surface overflow-hidden shadow-[var(--shadow-elevation-1)] h-fit",
|
|
239
|
-
children: [/* @__PURE__ */
|
|
247
|
+
children: [/* @__PURE__ */ f("div", {
|
|
240
248
|
className: "p-4 border-b border-border-subtle bg-bg-sunken/30 flex items-center justify-between",
|
|
241
|
-
children: [/* @__PURE__ */
|
|
249
|
+
children: [/* @__PURE__ */ f("h2", {
|
|
242
250
|
className: "font-semibold text-text-primary",
|
|
243
|
-
children: [
|
|
244
|
-
}), /* @__PURE__ */
|
|
251
|
+
children: [g("billing.addons.quotaAllocations", "Quota Allocations"), " *"]
|
|
252
|
+
}), /* @__PURE__ */ d("button", {
|
|
245
253
|
type: "button",
|
|
246
|
-
onClick:
|
|
247
|
-
disabled:
|
|
254
|
+
onClick: U,
|
|
255
|
+
disabled: y.length === 0,
|
|
248
256
|
className: "px-3 py-1 text-sm font-medium text-text-link hover:bg-[var(--color-accent-soft)] rounded-md transition-colors disabled:opacity-50",
|
|
249
257
|
children: "+ Add Quota"
|
|
250
258
|
})]
|
|
251
|
-
}), /* @__PURE__ */
|
|
259
|
+
}), /* @__PURE__ */ d("div", {
|
|
252
260
|
className: "p-4 space-y-3",
|
|
253
|
-
children:
|
|
261
|
+
children: y.length === 0 ? /* @__PURE__ */ d("p", {
|
|
254
262
|
className: "text-sm text-text-muted",
|
|
255
|
-
children:
|
|
256
|
-
}) :
|
|
263
|
+
children: g("billing.addons.noQuotasAvailable", "No quotas available. Please create quotas first.")
|
|
264
|
+
}) : F.length === 0 ? /* @__PURE__ */ d("p", {
|
|
257
265
|
className: "text-sm text-text-muted",
|
|
258
|
-
children:
|
|
259
|
-
}) :
|
|
260
|
-
let n =
|
|
261
|
-
return /* @__PURE__ */
|
|
266
|
+
children: g("billing.addons.noQuotasAllocated", "No quotas allocated. Click \"Add Quota\" to add one.")
|
|
267
|
+
}) : F.map((e, t) => {
|
|
268
|
+
let n = y.find((t) => t.id === e.quotaId), r = n?.limits, i = r?.value ?? 0, a = r?.type ?? "unknown", o = i * e.quantity;
|
|
269
|
+
return /* @__PURE__ */ f("div", {
|
|
262
270
|
className: "p-3 border border-border-subtle rounded-lg bg-bg-sunken/20 space-y-3",
|
|
263
|
-
children: [/* @__PURE__ */
|
|
271
|
+
children: [/* @__PURE__ */ f("div", {
|
|
264
272
|
className: "flex items-center gap-3",
|
|
265
|
-
children: [/* @__PURE__ */
|
|
273
|
+
children: [/* @__PURE__ */ f("select", {
|
|
266
274
|
value: e.quotaId,
|
|
267
|
-
onChange: (e) =>
|
|
275
|
+
onChange: (e) => G(t, "quotaId", e.target.value),
|
|
268
276
|
className: `flex-1 px-3 py-2 border border-border-subtle rounded-input bg-bg-surface focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] ${e.quotaId === "" ? "text-text-muted" : "text-text-primary"}`,
|
|
269
|
-
children: [/* @__PURE__ */
|
|
277
|
+
children: [/* @__PURE__ */ d("option", {
|
|
270
278
|
value: "",
|
|
271
279
|
disabled: !0,
|
|
272
|
-
children:
|
|
273
|
-
}),
|
|
280
|
+
children: g("billing.addons.selectQuota", "Select a quota...")
|
|
281
|
+
}), y.map((e) => /* @__PURE__ */ d("option", {
|
|
274
282
|
value: e.id,
|
|
275
283
|
children: e.name
|
|
276
284
|
}, e.id))]
|
|
277
|
-
}), /* @__PURE__ */
|
|
285
|
+
}), /* @__PURE__ */ d("button", {
|
|
278
286
|
type: "button",
|
|
279
|
-
onClick: () =>
|
|
287
|
+
onClick: () => W(t),
|
|
280
288
|
className: "p-2 text-status-error-text hover:bg-status-error-bg-subtle rounded-md transition-colors",
|
|
281
289
|
title: "Remove quota",
|
|
282
|
-
children: /* @__PURE__ */
|
|
290
|
+
children: /* @__PURE__ */ d("svg", {
|
|
283
291
|
className: "size-5",
|
|
284
292
|
fill: "none",
|
|
285
293
|
viewBox: "0 0 24 24",
|
|
286
294
|
stroke: "currentColor",
|
|
287
|
-
children: /* @__PURE__ */
|
|
295
|
+
children: /* @__PURE__ */ d("path", {
|
|
288
296
|
strokeLinecap: "round",
|
|
289
297
|
strokeLinejoin: "round",
|
|
290
298
|
strokeWidth: 2,
|
|
@@ -292,49 +300,49 @@ var m = () => {
|
|
|
292
300
|
})
|
|
293
301
|
})
|
|
294
302
|
})]
|
|
295
|
-
}), n && /* @__PURE__ */
|
|
303
|
+
}), n && /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("div", {
|
|
296
304
|
className: "flex items-center justify-between text-sm",
|
|
297
|
-
children: /* @__PURE__ */
|
|
305
|
+
children: /* @__PURE__ */ f("div", {
|
|
298
306
|
className: "text-text-muted",
|
|
299
307
|
children: [
|
|
300
|
-
/* @__PURE__ */
|
|
308
|
+
/* @__PURE__ */ f("span", {
|
|
301
309
|
className: "capitalize",
|
|
302
310
|
children: ["Type: ", a]
|
|
303
311
|
}),
|
|
304
|
-
/* @__PURE__ */
|
|
312
|
+
/* @__PURE__ */ d("span", {
|
|
305
313
|
className: "mx-2",
|
|
306
314
|
children: "•"
|
|
307
315
|
}),
|
|
308
|
-
/* @__PURE__ */
|
|
316
|
+
/* @__PURE__ */ f("span", { children: [
|
|
309
317
|
"Value per unit:",
|
|
310
318
|
" ",
|
|
311
|
-
/* @__PURE__ */
|
|
319
|
+
/* @__PURE__ */ d("span", {
|
|
312
320
|
className: "font-medium text-text-primary",
|
|
313
321
|
children: i.toLocaleString()
|
|
314
322
|
})
|
|
315
323
|
] })
|
|
316
324
|
]
|
|
317
325
|
})
|
|
318
|
-
}), /* @__PURE__ */
|
|
326
|
+
}), /* @__PURE__ */ f("div", {
|
|
319
327
|
className: "flex items-center gap-4",
|
|
320
|
-
children: [/* @__PURE__ */
|
|
328
|
+
children: [/* @__PURE__ */ f("div", {
|
|
321
329
|
className: "flex items-center gap-2",
|
|
322
|
-
children: [/* @__PURE__ */
|
|
330
|
+
children: [/* @__PURE__ */ f("label", {
|
|
323
331
|
className: "text-sm text-text-muted",
|
|
324
|
-
children: [
|
|
325
|
-
}), /* @__PURE__ */
|
|
332
|
+
children: [g("billing.addons.quantity", "Quantity"), ":"]
|
|
333
|
+
}), /* @__PURE__ */ d("input", {
|
|
326
334
|
type: "number",
|
|
327
335
|
min: "1",
|
|
328
336
|
value: e.quantity,
|
|
329
|
-
onChange: (e) =>
|
|
337
|
+
onChange: (e) => G(t, "quantity", e.target.value),
|
|
330
338
|
className: "w-24 px-3 py-1.5 border border-border-subtle rounded-input bg-bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)] text-center"
|
|
331
339
|
})]
|
|
332
|
-
}), /* @__PURE__ */
|
|
340
|
+
}), /* @__PURE__ */ f("div", {
|
|
333
341
|
className: "flex items-center gap-2 text-sm",
|
|
334
|
-
children: [/* @__PURE__ */
|
|
342
|
+
children: [/* @__PURE__ */ d("span", {
|
|
335
343
|
className: "text-text-muted",
|
|
336
344
|
children: "="
|
|
337
|
-
}), /* @__PURE__ */
|
|
345
|
+
}), /* @__PURE__ */ f("span", {
|
|
338
346
|
className: "font-semibold text-status-success-text",
|
|
339
347
|
children: [o.toLocaleString(), " total"]
|
|
340
348
|
})]
|
|
@@ -345,20 +353,20 @@ var m = () => {
|
|
|
345
353
|
})]
|
|
346
354
|
})]
|
|
347
355
|
}),
|
|
348
|
-
/* @__PURE__ */
|
|
349
|
-
overrides:
|
|
350
|
-
onChange:
|
|
356
|
+
/* @__PURE__ */ d(n, {
|
|
357
|
+
overrides: L,
|
|
358
|
+
onChange: R
|
|
351
359
|
}),
|
|
352
|
-
/* @__PURE__ */
|
|
360
|
+
/* @__PURE__ */ f("div", {
|
|
353
361
|
className: "flex items-center gap-3 pt-4",
|
|
354
|
-
children: [/* @__PURE__ */
|
|
362
|
+
children: [/* @__PURE__ */ d("button", {
|
|
355
363
|
type: "submit",
|
|
356
|
-
disabled:
|
|
364
|
+
disabled: w || y.length === 0,
|
|
357
365
|
className: "px-6 py-2 text-sm font-medium bg-action-primary-bg text-action-primary-text rounded-button hover:bg-action-primary-bgHover transition-colors disabled:opacity-50",
|
|
358
|
-
children:
|
|
359
|
-
}), /* @__PURE__ */
|
|
366
|
+
children: w ? g("billing.addons.creating", "Creating...") : g("billing.addons.createAddonBtn", "Create Addon")
|
|
367
|
+
}), /* @__PURE__ */ d("button", {
|
|
360
368
|
type: "button",
|
|
361
|
-
onClick: () =>
|
|
369
|
+
onClick: () => _("/addons"),
|
|
362
370
|
className: "px-6 py-2 text-sm font-medium border border-border-subtle text-text-primary rounded-button hover:bg-bg-sunken transition-colors",
|
|
363
371
|
children: "Cancel"
|
|
364
372
|
})]
|
|
@@ -369,6 +377,6 @@ var m = () => {
|
|
|
369
377
|
});
|
|
370
378
|
};
|
|
371
379
|
//#endregion
|
|
372
|
-
export {
|
|
380
|
+
export { h as AddonCreatePage };
|
|
373
381
|
|
|
374
382
|
//# sourceMappingURL=AddonCreatePage.js.map
|