@carlonicora/nextjs-jsonapi 2.2.3 → 2.4.0
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/{BlockNoteEditor-QTIDATPF.js → BlockNoteEditor-7WGCH2KB.js} +27 -26
- package/dist/BlockNoteEditor-7WGCH2KB.js.map +1 -0
- package/dist/{BlockNoteEditor-ADT6II2V.mjs → BlockNoteEditor-GWAV5ESO.mjs} +12 -11
- package/dist/BlockNoteEditor-GWAV5ESO.mjs.map +1 -0
- package/dist/billing/index.d.mts +40 -1
- package/dist/billing/index.d.ts +40 -1
- package/dist/billing/index.js +519 -462
- package/dist/billing/index.js.map +1 -1
- package/dist/billing/index.mjs +298 -241
- package/dist/billing/index.mjs.map +1 -1
- package/dist/{chunk-7DJOQTNN.mjs → chunk-3LVSA7IM.mjs} +2 -2
- package/dist/{chunk-F3BPNQDB.js → chunk-GYGMEDVS.js} +1135 -952
- package/dist/chunk-GYGMEDVS.js.map +1 -0
- package/dist/{chunk-DLTMYGLR.mjs → chunk-LCCRUWWY.mjs} +13 -1
- package/dist/chunk-LCCRUWWY.mjs.map +1 -0
- package/dist/{chunk-YEPE2HT6.mjs → chunk-M2EGUO2F.mjs} +2538 -2355
- package/dist/chunk-M2EGUO2F.mjs.map +1 -0
- package/dist/{chunk-LANOKEFZ.js → chunk-TOKHHZSP.js} +7 -7
- package/dist/{chunk-LANOKEFZ.js.map → chunk-TOKHHZSP.js.map} +1 -1
- package/dist/{chunk-KSU6CCW6.js → chunk-V66AZWPG.js} +14 -2
- package/dist/chunk-V66AZWPG.js.map +1 -0
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +4 -4
- package/dist/client/index.mjs +3 -3
- package/dist/components/index.d.mts +129 -4
- package/dist/components/index.d.ts +129 -4
- package/dist/components/index.js +16 -4
- package/dist/components/index.js.map +1 -1
- package/dist/components/index.mjs +15 -3
- package/dist/{content.fields-xH3TGvVk.d.mts → content.fields-1AlHDtDb.d.mts} +1 -0
- package/dist/{content.fields-xH3TGvVk.d.ts → content.fields-1AlHDtDb.d.ts} +1 -0
- package/dist/contexts/index.d.mts +22 -1
- package/dist/contexts/index.d.ts +22 -1
- package/dist/contexts/index.js +8 -4
- package/dist/contexts/index.js.map +1 -1
- package/dist/contexts/index.mjs +7 -3
- package/dist/core/index.d.mts +12 -2
- package/dist/core/index.d.ts +12 -2
- package/dist/core/index.js +4 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +3 -1
- package/dist/features/help/index.js +37 -37
- package/dist/features/help/index.mjs +3 -3
- package/dist/features/tokenusage/index.js +71 -71
- package/dist/features/tokenusage/index.mjs +3 -3
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4 -2
- package/dist/server/index.js +3 -3
- package/dist/server/index.mjs +1 -1
- package/package.json +1 -1
- package/src/billing/index.ts +1 -0
- package/src/components/editors/BlockNoteEditor.tsx +12 -6
- package/src/components/index.ts +1 -0
- package/src/contexts/index.ts +1 -0
- package/src/features/administration/components/AdminIndexContainer.tsx +150 -0
- package/src/features/administration/components/__tests__/AdminIndexContainer.spec.tsx +96 -0
- package/src/features/administration/components/index.ts +1 -0
- package/src/features/administration/contexts/AdministrationContext.tsx +47 -0
- package/src/features/administration/contexts/index.ts +1 -0
- package/src/features/administration/data/admin-section.types.ts +30 -0
- package/src/features/administration/i18n-keys.ts +26 -0
- package/src/features/administration/index.ts +3 -0
- package/src/features/assistant/components/containers/AssistantPageContainer.tsx +8 -1
- package/src/features/billing/contexts/BillingContext.tsx +95 -0
- package/src/features/billing/contexts/index.ts +1 -0
- package/src/features/billing/index.ts +1 -0
- package/src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx +39 -27
- package/src/features/billing/stripe-product/components/containers/ProductsAdminPageContainer.tsx +27 -0
- package/src/features/billing/stripe-product/components/containers/index.ts +1 -0
- package/src/features/company/components/containers/CompaniesListContainer.tsx +25 -0
- package/src/features/company/components/containers/index.ts +1 -0
- package/src/features/company/components/lists/CompaniesList.tsx +12 -1
- package/src/features/company/contexts/CompanyContext.tsx +13 -1
- package/src/features/company/data/entity-ai-status.ts +13 -0
- package/src/features/company/data/index.ts +1 -0
- package/src/features/user/components/containers/PlatformUsersContainer.tsx +23 -0
- package/src/features/user/components/containers/index.ts +1 -0
- package/src/features/user/components/lists/PlatformUsersList.tsx +45 -0
- package/src/features/user/components/lists/index.ts +1 -0
- package/src/features/user/data/user.fields.ts +1 -0
- package/src/features/user/hooks/useUserTableStructure.tsx +17 -0
- package/dist/BlockNoteEditor-ADT6II2V.mjs.map +0 -1
- package/dist/BlockNoteEditor-QTIDATPF.js.map +0 -1
- package/dist/chunk-DLTMYGLR.mjs.map +0 -1
- package/dist/chunk-F3BPNQDB.js.map +0 -1
- package/dist/chunk-KSU6CCW6.js.map +0 -1
- package/dist/chunk-YEPE2HT6.mjs.map +0 -1
- /package/dist/{chunk-7DJOQTNN.mjs.map → chunk-3LVSA7IM.mjs.map} +0 -0
package/dist/billing/index.mjs
CHANGED
|
@@ -36,7 +36,9 @@ import {
|
|
|
36
36
|
FormTextarea,
|
|
37
37
|
Input,
|
|
38
38
|
Label,
|
|
39
|
+
RoundPageContainer,
|
|
39
40
|
SectionHeader,
|
|
41
|
+
SharedProvider,
|
|
40
42
|
Skeleton,
|
|
41
43
|
Table,
|
|
42
44
|
TableBody,
|
|
@@ -48,13 +50,14 @@ import {
|
|
|
48
50
|
TabsList,
|
|
49
51
|
TabsTrigger,
|
|
50
52
|
useCurrentUserContext
|
|
51
|
-
} from "../chunk-
|
|
53
|
+
} from "../chunk-M2EGUO2F.mjs";
|
|
52
54
|
import {
|
|
53
55
|
getRoleId,
|
|
54
56
|
getStripePublishableKey
|
|
55
|
-
} from "../chunk-
|
|
57
|
+
} from "../chunk-3LVSA7IM.mjs";
|
|
56
58
|
import {
|
|
57
59
|
FeatureService,
|
|
60
|
+
Modules,
|
|
58
61
|
StripeCustomerService,
|
|
59
62
|
StripeInvoiceService,
|
|
60
63
|
StripePriceService,
|
|
@@ -63,7 +66,7 @@ import {
|
|
|
63
66
|
StripeSubscriptionService,
|
|
64
67
|
StripeUsageService,
|
|
65
68
|
cn
|
|
66
|
-
} from "../chunk-
|
|
69
|
+
} from "../chunk-LCCRUWWY.mjs";
|
|
67
70
|
import "../chunk-AUXK7QSA.mjs";
|
|
68
71
|
import "../chunk-C7C7VY4F.mjs";
|
|
69
72
|
import "../chunk-E5YA5Z5X.mjs";
|
|
@@ -3100,17 +3103,135 @@ function isStripeConfigured() {
|
|
|
3100
3103
|
}
|
|
3101
3104
|
__name(isStripeConfigured, "isStripeConfigured");
|
|
3102
3105
|
|
|
3103
|
-
// src/features/billing/
|
|
3106
|
+
// src/features/billing/contexts/BillingContext.tsx
|
|
3107
|
+
import { useTranslations } from "next-intl";
|
|
3108
|
+
import { createContext, useCallback as useCallback5, useContext, useState as useState16 } from "react";
|
|
3109
|
+
|
|
3110
|
+
// src/features/billing/stripe-product/components/forms/ProductEditor.tsx
|
|
3104
3111
|
import { zodResolver as zodResolver2 } from "@hookform/resolvers/zod";
|
|
3105
|
-
import {
|
|
3106
|
-
import { useEffect as useEffect10, useState as useState15 } from "react";
|
|
3112
|
+
import { useState as useState15 } from "react";
|
|
3107
3113
|
import { useForm as useForm2 } from "react-hook-form";
|
|
3108
3114
|
import { v4 as v42 } from "uuid";
|
|
3109
3115
|
import { z as z2 } from "zod";
|
|
3110
3116
|
import { jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3111
|
-
function
|
|
3117
|
+
function ProductEditor({ product, open, onOpenChange, onSuccess }) {
|
|
3112
3118
|
const [isSubmitting, setIsSubmitting] = useState15(false);
|
|
3113
|
-
const
|
|
3119
|
+
const formSchema2 = z2.object({
|
|
3120
|
+
name: z2.string().min(1, { message: "Product name is required" }),
|
|
3121
|
+
description: z2.string().min(1, { message: "Description is required" }),
|
|
3122
|
+
active: z2.boolean()
|
|
3123
|
+
});
|
|
3124
|
+
const form = useForm2({
|
|
3125
|
+
resolver: zodResolver2(formSchema2),
|
|
3126
|
+
defaultValues: {
|
|
3127
|
+
name: product?.name || "",
|
|
3128
|
+
description: product?.description || "",
|
|
3129
|
+
active: product?.active ?? true
|
|
3130
|
+
}
|
|
3131
|
+
});
|
|
3132
|
+
const onSubmit = /* @__PURE__ */ __name(async (values) => {
|
|
3133
|
+
setIsSubmitting(true);
|
|
3134
|
+
try {
|
|
3135
|
+
if (product) {
|
|
3136
|
+
await StripeProductService.updateProduct({
|
|
3137
|
+
id: product.id,
|
|
3138
|
+
name: values.name,
|
|
3139
|
+
description: values.description,
|
|
3140
|
+
active: values.active
|
|
3141
|
+
});
|
|
3142
|
+
} else {
|
|
3143
|
+
await StripeProductService.createProduct({
|
|
3144
|
+
id: v42(),
|
|
3145
|
+
name: values.name,
|
|
3146
|
+
description: values.description,
|
|
3147
|
+
active: values.active
|
|
3148
|
+
});
|
|
3149
|
+
}
|
|
3150
|
+
onSuccess();
|
|
3151
|
+
onOpenChange(false);
|
|
3152
|
+
} catch (error) {
|
|
3153
|
+
console.error("[ProductEditor] Failed to save product:", error);
|
|
3154
|
+
} finally {
|
|
3155
|
+
setIsSubmitting(false);
|
|
3156
|
+
}
|
|
3157
|
+
}, "onSubmit");
|
|
3158
|
+
return /* @__PURE__ */ jsx40(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs35(DialogContent, { className: "max-w-2xl", children: [
|
|
3159
|
+
/* @__PURE__ */ jsxs35(DialogHeader, { children: [
|
|
3160
|
+
/* @__PURE__ */ jsx40(DialogTitle, { children: product ? "Edit Product" : "Create Product" }),
|
|
3161
|
+
/* @__PURE__ */ jsx40(DialogDescription, { children: product ? `Update the details for ${product.name}` : "Create a new product to offer to your customers" })
|
|
3162
|
+
] }),
|
|
3163
|
+
/* @__PURE__ */ jsx40(Form, { ...form, children: /* @__PURE__ */ jsxs35("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
|
|
3164
|
+
/* @__PURE__ */ jsx40(FormInput, { form, id: "name", name: "Product Name", placeholder: "Enter product name", isRequired: true }),
|
|
3165
|
+
/* @__PURE__ */ jsx40(
|
|
3166
|
+
FormTextarea,
|
|
3167
|
+
{
|
|
3168
|
+
form,
|
|
3169
|
+
id: "description",
|
|
3170
|
+
name: "Description",
|
|
3171
|
+
placeholder: "Enter product description",
|
|
3172
|
+
className: "min-h-32"
|
|
3173
|
+
}
|
|
3174
|
+
),
|
|
3175
|
+
/* @__PURE__ */ jsx40(FormCheckbox, { form, id: "active", name: "Active" }),
|
|
3176
|
+
/* @__PURE__ */ jsx40(CommonEditorButtons, { isEdit: !!product, form, disabled: isSubmitting, setOpen: onOpenChange })
|
|
3177
|
+
] }) })
|
|
3178
|
+
] }) });
|
|
3179
|
+
}
|
|
3180
|
+
__name(ProductEditor, "ProductEditor");
|
|
3181
|
+
|
|
3182
|
+
// src/features/billing/contexts/BillingContext.tsx
|
|
3183
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
3184
|
+
var BillingContext = createContext(void 0);
|
|
3185
|
+
var BillingProvider = /* @__PURE__ */ __name(({ children }) => {
|
|
3186
|
+
const t = useTranslations();
|
|
3187
|
+
const { hasRole } = useCurrentUserContext();
|
|
3188
|
+
const [showCreateProduct, setShowCreateProduct] = useState16(false);
|
|
3189
|
+
const [refreshToken, setRefreshToken] = useState16(0);
|
|
3190
|
+
const refresh = useCallback5(() => setRefreshToken((value) => value + 1), []);
|
|
3191
|
+
const breadcrumbs = [{ name: t(`billing.admin.products.title`) }];
|
|
3192
|
+
const title = /* @__PURE__ */ __name(() => {
|
|
3193
|
+
const response = { type: t(`billing.admin.products.title`) };
|
|
3194
|
+
if (hasRole(getRoleId().Administrator)) {
|
|
3195
|
+
response.functions = [
|
|
3196
|
+
/* @__PURE__ */ jsx41(Button, { onClick: () => setShowCreateProduct(true), children: t(`billing.admin.products.create`) }, "productEditorTrigger"),
|
|
3197
|
+
showCreateProduct ? /* @__PURE__ */ jsx41(
|
|
3198
|
+
ProductEditor,
|
|
3199
|
+
{
|
|
3200
|
+
open: showCreateProduct,
|
|
3201
|
+
onOpenChange: setShowCreateProduct,
|
|
3202
|
+
onSuccess: () => {
|
|
3203
|
+
setShowCreateProduct(false);
|
|
3204
|
+
refresh();
|
|
3205
|
+
}
|
|
3206
|
+
},
|
|
3207
|
+
"productEditor"
|
|
3208
|
+
) : null
|
|
3209
|
+
];
|
|
3210
|
+
}
|
|
3211
|
+
return response;
|
|
3212
|
+
}, "title");
|
|
3213
|
+
return /* @__PURE__ */ jsx41(SharedProvider, { value: { breadcrumbs, title: title() }, children: /* @__PURE__ */ jsx41(BillingContext.Provider, { value: { refreshToken, refresh }, children }) });
|
|
3214
|
+
}, "BillingProvider");
|
|
3215
|
+
var useBillingContext = /* @__PURE__ */ __name(() => {
|
|
3216
|
+
const context = useContext(BillingContext);
|
|
3217
|
+
if (context === void 0) {
|
|
3218
|
+
throw new Error("useBillingContext must be used within a BillingProvider");
|
|
3219
|
+
}
|
|
3220
|
+
return context;
|
|
3221
|
+
}, "useBillingContext");
|
|
3222
|
+
var useOptionalBillingContext = /* @__PURE__ */ __name(() => useContext(BillingContext), "useOptionalBillingContext");
|
|
3223
|
+
|
|
3224
|
+
// src/features/billing/stripe-price/components/forms/PriceEditor.tsx
|
|
3225
|
+
import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
|
|
3226
|
+
import { AlertCircle as AlertCircle3, PlusIcon, XIcon } from "lucide-react";
|
|
3227
|
+
import { useEffect as useEffect10, useState as useState17 } from "react";
|
|
3228
|
+
import { useForm as useForm3 } from "react-hook-form";
|
|
3229
|
+
import { v4 as v43 } from "uuid";
|
|
3230
|
+
import { z as z3 } from "zod";
|
|
3231
|
+
import { jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3232
|
+
function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
3233
|
+
const [isSubmitting, setIsSubmitting] = useState17(false);
|
|
3234
|
+
const [allFeatures, setAllFeatures] = useState17([]);
|
|
3114
3235
|
useEffect10(() => {
|
|
3115
3236
|
const fetchFeatures = /* @__PURE__ */ __name(async () => {
|
|
3116
3237
|
try {
|
|
@@ -3122,32 +3243,32 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3122
3243
|
}, "fetchFeatures");
|
|
3123
3244
|
fetchFeatures();
|
|
3124
3245
|
}, []);
|
|
3125
|
-
const formSchema2 =
|
|
3126
|
-
unitAmount:
|
|
3246
|
+
const formSchema2 = z3.object({
|
|
3247
|
+
unitAmount: z3.preprocess(
|
|
3127
3248
|
(val) => typeof val === "string" ? parseFloat(val) : val,
|
|
3128
|
-
|
|
3249
|
+
z3.number().min(0, { message: "Amount must be 0 or greater" })
|
|
3129
3250
|
),
|
|
3130
|
-
currency:
|
|
3131
|
-
interval:
|
|
3132
|
-
intervalCount:
|
|
3251
|
+
currency: z3.string().min(1, { message: "Currency is required" }),
|
|
3252
|
+
interval: z3.enum(["one_time", "day", "week", "month", "year"]),
|
|
3253
|
+
intervalCount: z3.preprocess(
|
|
3133
3254
|
(val) => val === "" || val === void 0 ? void 0 : typeof val === "string" ? parseInt(val, 10) : val,
|
|
3134
|
-
|
|
3255
|
+
z3.number().min(1).optional()
|
|
3135
3256
|
),
|
|
3136
|
-
usageType:
|
|
3137
|
-
nickname:
|
|
3138
|
-
active:
|
|
3139
|
-
isTrial:
|
|
3140
|
-
description:
|
|
3141
|
-
features:
|
|
3142
|
-
token:
|
|
3143
|
-
featureIds:
|
|
3257
|
+
usageType: z3.enum(["licensed", "metered"]).optional(),
|
|
3258
|
+
nickname: z3.string().optional(),
|
|
3259
|
+
active: z3.boolean(),
|
|
3260
|
+
isTrial: z3.boolean(),
|
|
3261
|
+
description: z3.string().optional(),
|
|
3262
|
+
features: z3.array(z3.string()),
|
|
3263
|
+
token: z3.string(),
|
|
3264
|
+
featureIds: z3.array(z3.string())
|
|
3144
3265
|
});
|
|
3145
3266
|
const isEditMode = !!price;
|
|
3146
3267
|
const defaultUnitAmount = price?.unitAmount ? price.unitAmount / 100 : 0;
|
|
3147
3268
|
const coreFeatureIds = allFeatures.filter((f) => f.isCore).map((f) => f.id);
|
|
3148
3269
|
const defaultFeatureIds = [.../* @__PURE__ */ new Set([...price?.priceFeatures?.map((f) => f.id) ?? [], ...coreFeatureIds])];
|
|
3149
|
-
const form =
|
|
3150
|
-
resolver:
|
|
3270
|
+
const form = useForm3({
|
|
3271
|
+
resolver: zodResolver3(formSchema2),
|
|
3151
3272
|
defaultValues: {
|
|
3152
3273
|
unitAmount: defaultUnitAmount,
|
|
3153
3274
|
currency: price?.currency || "usd",
|
|
@@ -3203,7 +3324,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3203
3324
|
});
|
|
3204
3325
|
} else {
|
|
3205
3326
|
const createInput = {
|
|
3206
|
-
id:
|
|
3327
|
+
id: v43(),
|
|
3207
3328
|
productId,
|
|
3208
3329
|
currency: values.currency,
|
|
3209
3330
|
unitAmount: unitAmountInCents
|
|
@@ -3260,21 +3381,21 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3260
3381
|
{ id: "licensed", text: "Licensed (per unit)" },
|
|
3261
3382
|
{ id: "metered", text: "Metered (usage-based)" }
|
|
3262
3383
|
];
|
|
3263
|
-
return /* @__PURE__ */
|
|
3264
|
-
/* @__PURE__ */
|
|
3265
|
-
/* @__PURE__ */
|
|
3266
|
-
/* @__PURE__ */
|
|
3384
|
+
return /* @__PURE__ */ jsx42(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs36(DialogContent, { className: "max-w-2xl", children: [
|
|
3385
|
+
/* @__PURE__ */ jsxs36(DialogHeader, { children: [
|
|
3386
|
+
/* @__PURE__ */ jsx42(DialogTitle, { children: isEditMode ? "Edit Price" : "Create Price" }),
|
|
3387
|
+
/* @__PURE__ */ jsx42(DialogDescription, { children: isEditMode ? "Update the price details. Note: Only nickname and active status can be changed." : "Create a new price for this product" })
|
|
3267
3388
|
] }),
|
|
3268
|
-
isEditMode && /* @__PURE__ */
|
|
3269
|
-
/* @__PURE__ */
|
|
3270
|
-
/* @__PURE__ */
|
|
3271
|
-
/* @__PURE__ */
|
|
3272
|
-
/* @__PURE__ */
|
|
3389
|
+
isEditMode && /* @__PURE__ */ jsxs36("div", { className: "bg-primary/10 border-primary/30 flex gap-x-3 rounded-lg border p-4", children: [
|
|
3390
|
+
/* @__PURE__ */ jsx42(AlertCircle3, { className: "text-primary mt-0.5 h-5 w-5 flex-shrink-0" }),
|
|
3391
|
+
/* @__PURE__ */ jsxs36("div", { className: "text-foreground text-sm", children: [
|
|
3392
|
+
/* @__PURE__ */ jsx42("p", { className: "font-semibold mb-1", children: "Stripe Price Immutability" }),
|
|
3393
|
+
/* @__PURE__ */ jsx42("p", { children: "Due to Stripe's architecture, only the nickname and active status can be modified after creation. To change amount, currency, or billing interval, create a new price." })
|
|
3273
3394
|
] })
|
|
3274
3395
|
] }),
|
|
3275
|
-
/* @__PURE__ */
|
|
3276
|
-
/* @__PURE__ */
|
|
3277
|
-
/* @__PURE__ */
|
|
3396
|
+
/* @__PURE__ */ jsx42(Form, { ...form, children: /* @__PURE__ */ jsxs36("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
|
|
3397
|
+
/* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-2 gap-x-4", children: [
|
|
3398
|
+
/* @__PURE__ */ jsx42(
|
|
3278
3399
|
FormInput,
|
|
3279
3400
|
{
|
|
3280
3401
|
form,
|
|
@@ -3285,9 +3406,9 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3285
3406
|
isRequired: true
|
|
3286
3407
|
}
|
|
3287
3408
|
),
|
|
3288
|
-
/* @__PURE__ */
|
|
3409
|
+
/* @__PURE__ */ jsx42(FormSelect, { form, id: "currency", name: "Currency", values: currencyOptions, disabled: isEditMode })
|
|
3289
3410
|
] }),
|
|
3290
|
-
/* @__PURE__ */
|
|
3411
|
+
/* @__PURE__ */ jsx42(
|
|
3291
3412
|
FormSelect,
|
|
3292
3413
|
{
|
|
3293
3414
|
form,
|
|
@@ -3297,8 +3418,8 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3297
3418
|
disabled: isEditMode
|
|
3298
3419
|
}
|
|
3299
3420
|
),
|
|
3300
|
-
isRecurring && /* @__PURE__ */
|
|
3301
|
-
/* @__PURE__ */
|
|
3421
|
+
isRecurring && /* @__PURE__ */ jsxs36("div", { className: "grid grid-cols-2 gap-x-4", children: [
|
|
3422
|
+
/* @__PURE__ */ jsx42(
|
|
3302
3423
|
FormInput,
|
|
3303
3424
|
{
|
|
3304
3425
|
form,
|
|
@@ -3309,7 +3430,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3309
3430
|
disabled: isEditMode
|
|
3310
3431
|
}
|
|
3311
3432
|
),
|
|
3312
|
-
/* @__PURE__ */
|
|
3433
|
+
/* @__PURE__ */ jsx42(
|
|
3313
3434
|
FormSelect,
|
|
3314
3435
|
{
|
|
3315
3436
|
form,
|
|
@@ -3320,7 +3441,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3320
3441
|
}
|
|
3321
3442
|
)
|
|
3322
3443
|
] }),
|
|
3323
|
-
/* @__PURE__ */
|
|
3444
|
+
/* @__PURE__ */ jsx42(
|
|
3324
3445
|
FormInput,
|
|
3325
3446
|
{
|
|
3326
3447
|
form,
|
|
@@ -3329,7 +3450,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3329
3450
|
placeholder: "e.g., Standard Plan, Pro Tier"
|
|
3330
3451
|
}
|
|
3331
3452
|
),
|
|
3332
|
-
/* @__PURE__ */
|
|
3453
|
+
/* @__PURE__ */ jsx42(
|
|
3333
3454
|
FormTextarea,
|
|
3334
3455
|
{
|
|
3335
3456
|
form,
|
|
@@ -3339,12 +3460,12 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3339
3460
|
className: "min-h-24"
|
|
3340
3461
|
}
|
|
3341
3462
|
),
|
|
3342
|
-
/* @__PURE__ */
|
|
3343
|
-
/* @__PURE__ */
|
|
3344
|
-
/* @__PURE__ */
|
|
3345
|
-
/* @__PURE__ */
|
|
3346
|
-
form.watch("features").map((_, index) => /* @__PURE__ */
|
|
3347
|
-
/* @__PURE__ */
|
|
3463
|
+
/* @__PURE__ */ jsx42(FormInput, { form, id: "token", name: "Token (optional)", placeholder: "Enter token value" }),
|
|
3464
|
+
/* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
|
|
3465
|
+
/* @__PURE__ */ jsx42(Label, { children: "Features (optional)" }),
|
|
3466
|
+
/* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
|
|
3467
|
+
form.watch("features").map((_, index) => /* @__PURE__ */ jsxs36("div", { className: "flex gap-2", children: [
|
|
3468
|
+
/* @__PURE__ */ jsx42(
|
|
3348
3469
|
Input,
|
|
3349
3470
|
{
|
|
3350
3471
|
...form.register(`features.${index}`),
|
|
@@ -3352,7 +3473,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3352
3473
|
className: "flex-1"
|
|
3353
3474
|
}
|
|
3354
3475
|
),
|
|
3355
|
-
/* @__PURE__ */
|
|
3476
|
+
/* @__PURE__ */ jsx42(
|
|
3356
3477
|
Button,
|
|
3357
3478
|
{
|
|
3358
3479
|
type: "button",
|
|
@@ -3365,11 +3486,11 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3365
3486
|
currentFeatures.filter((_2, i) => i !== index)
|
|
3366
3487
|
);
|
|
3367
3488
|
},
|
|
3368
|
-
children: /* @__PURE__ */
|
|
3489
|
+
children: /* @__PURE__ */ jsx42(XIcon, { className: "h-4 w-4" })
|
|
3369
3490
|
}
|
|
3370
3491
|
)
|
|
3371
3492
|
] }, index)),
|
|
3372
|
-
/* @__PURE__ */
|
|
3493
|
+
/* @__PURE__ */ jsxs36(
|
|
3373
3494
|
Button,
|
|
3374
3495
|
{
|
|
3375
3496
|
type: "button",
|
|
@@ -3381,20 +3502,20 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3381
3502
|
},
|
|
3382
3503
|
className: "mt-2",
|
|
3383
3504
|
children: [
|
|
3384
|
-
/* @__PURE__ */
|
|
3505
|
+
/* @__PURE__ */ jsx42(PlusIcon, { className: "h-4 w-4 mr-2" }),
|
|
3385
3506
|
"Add Feature"
|
|
3386
3507
|
]
|
|
3387
3508
|
}
|
|
3388
3509
|
)
|
|
3389
3510
|
] })
|
|
3390
3511
|
] }),
|
|
3391
|
-
isRecurring && allFeatures.length > 0 && /* @__PURE__ */
|
|
3392
|
-
/* @__PURE__ */
|
|
3393
|
-
/* @__PURE__ */
|
|
3512
|
+
isRecurring && allFeatures.length > 0 && /* @__PURE__ */ jsxs36("div", { className: "space-y-2", children: [
|
|
3513
|
+
/* @__PURE__ */ jsx42(Label, { children: "Platform Features" }),
|
|
3514
|
+
/* @__PURE__ */ jsx42("div", { className: "border rounded-md p-4 space-y-2 max-h-48 overflow-y-auto", children: allFeatures.map((feature) => {
|
|
3394
3515
|
const isCore = feature.isCore;
|
|
3395
3516
|
const isChecked = form.watch("featureIds").includes(feature.id);
|
|
3396
|
-
return /* @__PURE__ */
|
|
3397
|
-
/* @__PURE__ */
|
|
3517
|
+
return /* @__PURE__ */ jsxs36("div", { className: "flex items-center space-x-2", children: [
|
|
3518
|
+
/* @__PURE__ */ jsx42(
|
|
3398
3519
|
"input",
|
|
3399
3520
|
{
|
|
3400
3521
|
type: "checkbox",
|
|
@@ -3417,22 +3538,22 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3417
3538
|
className: "h-4 w-4 rounded border-gray-300 text-primary focus:ring-primary disabled:opacity-50"
|
|
3418
3539
|
}
|
|
3419
3540
|
),
|
|
3420
|
-
/* @__PURE__ */
|
|
3541
|
+
/* @__PURE__ */ jsxs36(
|
|
3421
3542
|
"label",
|
|
3422
3543
|
{
|
|
3423
3544
|
htmlFor: `feature-${feature.id}`,
|
|
3424
3545
|
className: `text-sm ${isCore ? "text-muted-foreground" : ""}`,
|
|
3425
3546
|
children: [
|
|
3426
3547
|
feature.name,
|
|
3427
|
-
isCore && /* @__PURE__ */
|
|
3548
|
+
isCore && /* @__PURE__ */ jsx42("span", { className: "ml-2 text-xs text-muted-foreground", children: "(Core - Required)" })
|
|
3428
3549
|
]
|
|
3429
3550
|
}
|
|
3430
3551
|
)
|
|
3431
3552
|
] }, feature.id);
|
|
3432
3553
|
}) })
|
|
3433
3554
|
] }),
|
|
3434
|
-
/* @__PURE__ */
|
|
3435
|
-
isRecurring && /* @__PURE__ */
|
|
3555
|
+
/* @__PURE__ */ jsx42(FormCheckbox, { form, id: "active", name: "Active" }),
|
|
3556
|
+
isRecurring && /* @__PURE__ */ jsx42(
|
|
3436
3557
|
FormCheckbox,
|
|
3437
3558
|
{
|
|
3438
3559
|
form,
|
|
@@ -3441,7 +3562,7 @@ function PriceEditor({ productId, price, open, onOpenChange, onSuccess }) {
|
|
|
3441
3562
|
description: "Mark this as the trial subscription plan (only one price should be marked as trial)"
|
|
3442
3563
|
}
|
|
3443
3564
|
),
|
|
3444
|
-
/* @__PURE__ */
|
|
3565
|
+
/* @__PURE__ */ jsx42(CommonEditorButtons, { isEdit: isEditMode, form, disabled: isSubmitting, setOpen: onOpenChange })
|
|
3445
3566
|
] }) })
|
|
3446
3567
|
] }) });
|
|
3447
3568
|
}
|
|
@@ -3449,17 +3570,17 @@ __name(PriceEditor, "PriceEditor");
|
|
|
3449
3570
|
|
|
3450
3571
|
// src/features/billing/stripe-price/components/lists/PricesList.tsx
|
|
3451
3572
|
import { Archive, DollarSign, Edit, RotateCcw } from "lucide-react";
|
|
3452
|
-
import { useEffect as useEffect11, useState as
|
|
3453
|
-
import { jsx as
|
|
3573
|
+
import { useEffect as useEffect11, useState as useState18 } from "react";
|
|
3574
|
+
import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3454
3575
|
function PricesList({ productId, onPricesChange }) {
|
|
3455
|
-
const [prices, setPrices] =
|
|
3456
|
-
const [loading, setLoading] =
|
|
3457
|
-
const [showCreatePrice, setShowCreatePrice] =
|
|
3458
|
-
const [editingPrice, setEditingPrice] =
|
|
3459
|
-
const [priceToArchive, setPriceToArchive] =
|
|
3460
|
-
const [priceToReactivate, setPriceToReactivate] =
|
|
3461
|
-
const [archivingPriceId, setArchivingPriceId] =
|
|
3462
|
-
const [reactivatingPriceId, setReactivatingPriceId] =
|
|
3576
|
+
const [prices, setPrices] = useState18([]);
|
|
3577
|
+
const [loading, setLoading] = useState18(true);
|
|
3578
|
+
const [showCreatePrice, setShowCreatePrice] = useState18(false);
|
|
3579
|
+
const [editingPrice, setEditingPrice] = useState18(null);
|
|
3580
|
+
const [priceToArchive, setPriceToArchive] = useState18(null);
|
|
3581
|
+
const [priceToReactivate, setPriceToReactivate] = useState18(null);
|
|
3582
|
+
const [archivingPriceId, setArchivingPriceId] = useState18(null);
|
|
3583
|
+
const [reactivatingPriceId, setReactivatingPriceId] = useState18(null);
|
|
3463
3584
|
const loadPrices = /* @__PURE__ */ __name(async () => {
|
|
3464
3585
|
setLoading(true);
|
|
3465
3586
|
try {
|
|
@@ -3522,27 +3643,27 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3522
3643
|
return "";
|
|
3523
3644
|
}, "formatInterval");
|
|
3524
3645
|
if (loading) {
|
|
3525
|
-
return /* @__PURE__ */
|
|
3646
|
+
return /* @__PURE__ */ jsx43("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsx43("p", { className: "text-muted-foreground", children: "Loading prices..." }) });
|
|
3526
3647
|
}
|
|
3527
|
-
return /* @__PURE__ */
|
|
3528
|
-
/* @__PURE__ */
|
|
3529
|
-
/* @__PURE__ */
|
|
3530
|
-
/* @__PURE__ */
|
|
3648
|
+
return /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-y-4", children: [
|
|
3649
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex items-center justify-between mb-4", children: [
|
|
3650
|
+
/* @__PURE__ */ jsx43("h4", { className: "text-lg font-semibold", children: "Prices" }),
|
|
3651
|
+
/* @__PURE__ */ jsx43(Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
|
|
3531
3652
|
] }),
|
|
3532
|
-
prices.length === 0 && /* @__PURE__ */
|
|
3533
|
-
/* @__PURE__ */
|
|
3534
|
-
/* @__PURE__ */
|
|
3535
|
-
/* @__PURE__ */
|
|
3653
|
+
prices.length === 0 && /* @__PURE__ */ jsxs37("div", { className: "bg-background flex flex-col items-center justify-center gap-y-3 rounded-lg border border-dashed p-8", children: [
|
|
3654
|
+
/* @__PURE__ */ jsx43(DollarSign, { className: "text-muted-foreground h-12 w-12" }),
|
|
3655
|
+
/* @__PURE__ */ jsx43("p", { className: "text-muted-foreground text-sm", children: "No prices yet. Add a price to enable subscriptions." }),
|
|
3656
|
+
/* @__PURE__ */ jsx43(Button, { size: "sm", onClick: () => setShowCreatePrice(true), children: "Add Price" })
|
|
3536
3657
|
] }),
|
|
3537
|
-
prices.length > 0 && /* @__PURE__ */
|
|
3658
|
+
prices.length > 0 && /* @__PURE__ */ jsx43("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4", children: prices.map((price) => {
|
|
3538
3659
|
const isArchiving = archivingPriceId === price.id;
|
|
3539
3660
|
const isReactivating = reactivatingPriceId === price.id;
|
|
3540
|
-
return /* @__PURE__ */
|
|
3541
|
-
/* @__PURE__ */
|
|
3542
|
-
/* @__PURE__ */
|
|
3543
|
-
/* @__PURE__ */
|
|
3544
|
-
/* @__PURE__ */
|
|
3545
|
-
price.active ? /* @__PURE__ */
|
|
3661
|
+
return /* @__PURE__ */ jsxs37("div", { className: "border rounded-lg bg-white p-4 hover:shadow-sm transition-shadow", children: [
|
|
3662
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex items-start justify-between mb-3", children: [
|
|
3663
|
+
/* @__PURE__ */ jsx43(DollarSign, { className: "h-5 w-5 text-primary" }),
|
|
3664
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex gap-1", children: [
|
|
3665
|
+
/* @__PURE__ */ jsx43(Button, { variant: "ghost", size: "sm", onClick: () => setEditingPrice(price), className: "h-8 w-8 p-0", children: /* @__PURE__ */ jsx43(Edit, { className: "h-4 w-4" }) }),
|
|
3666
|
+
price.active ? /* @__PURE__ */ jsx43(
|
|
3546
3667
|
Button,
|
|
3547
3668
|
{
|
|
3548
3669
|
variant: "ghost",
|
|
@@ -3550,9 +3671,9 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3550
3671
|
onClick: () => setPriceToArchive(price),
|
|
3551
3672
|
className: "h-8 w-8 p-0",
|
|
3552
3673
|
disabled: isArchiving,
|
|
3553
|
-
children: /* @__PURE__ */
|
|
3674
|
+
children: /* @__PURE__ */ jsx43(Archive, { className: "h-4 w-4" })
|
|
3554
3675
|
}
|
|
3555
|
-
) : /* @__PURE__ */
|
|
3676
|
+
) : /* @__PURE__ */ jsx43(
|
|
3556
3677
|
Button,
|
|
3557
3678
|
{
|
|
3558
3679
|
variant: "ghost",
|
|
@@ -3560,25 +3681,25 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3560
3681
|
onClick: () => setPriceToReactivate(price),
|
|
3561
3682
|
className: "h-8 w-8 p-0",
|
|
3562
3683
|
disabled: isReactivating,
|
|
3563
|
-
children: /* @__PURE__ */
|
|
3684
|
+
children: /* @__PURE__ */ jsx43(RotateCcw, { className: "h-4 w-4" })
|
|
3564
3685
|
}
|
|
3565
3686
|
)
|
|
3566
3687
|
] })
|
|
3567
3688
|
] }),
|
|
3568
|
-
/* @__PURE__ */
|
|
3689
|
+
/* @__PURE__ */ jsx43("div", { className: "mb-2", children: /* @__PURE__ */ jsxs37("div", { className: "text-2xl font-bold", children: [
|
|
3569
3690
|
formatCurrency(price.unitAmount, price.currency),
|
|
3570
3691
|
" ",
|
|
3571
|
-
/* @__PURE__ */
|
|
3692
|
+
/* @__PURE__ */ jsx43("span", { className: "text-muted-foreground text-sm font-normal", children: formatInterval2(price) })
|
|
3572
3693
|
] }) }),
|
|
3573
|
-
price.metadata?.nickname && /* @__PURE__ */
|
|
3574
|
-
/* @__PURE__ */
|
|
3575
|
-
price.active ? /* @__PURE__ */
|
|
3576
|
-
price.recurring?.usageType === "metered" && /* @__PURE__ */
|
|
3577
|
-
/* @__PURE__ */
|
|
3694
|
+
price.metadata?.nickname && /* @__PURE__ */ jsx43("p", { className: "text-sm font-medium mb-2", children: price.metadata.nickname }),
|
|
3695
|
+
/* @__PURE__ */ jsxs37("div", { className: "flex flex-wrap gap-2", children: [
|
|
3696
|
+
price.active ? /* @__PURE__ */ jsx43(Badge, { variant: "softGreen", children: "Active" }) : /* @__PURE__ */ jsx43(Badge, { variant: "softGray", children: "Inactive" }),
|
|
3697
|
+
price.recurring?.usageType === "metered" && /* @__PURE__ */ jsx43(Badge, { variant: "softBlue", children: "Metered" }),
|
|
3698
|
+
/* @__PURE__ */ jsx43(Badge, { variant: "softGray", className: "uppercase", children: price.currency })
|
|
3578
3699
|
] })
|
|
3579
3700
|
] }, price.id);
|
|
3580
3701
|
}) }),
|
|
3581
|
-
showCreatePrice && /* @__PURE__ */
|
|
3702
|
+
showCreatePrice && /* @__PURE__ */ jsx43(
|
|
3582
3703
|
PriceEditor,
|
|
3583
3704
|
{
|
|
3584
3705
|
productId,
|
|
@@ -3590,7 +3711,7 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3590
3711
|
}
|
|
3591
3712
|
}
|
|
3592
3713
|
),
|
|
3593
|
-
editingPrice && /* @__PURE__ */
|
|
3714
|
+
editingPrice && /* @__PURE__ */ jsx43(
|
|
3594
3715
|
PriceEditor,
|
|
3595
3716
|
{
|
|
3596
3717
|
productId,
|
|
@@ -3604,19 +3725,19 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3604
3725
|
}
|
|
3605
3726
|
}
|
|
3606
3727
|
),
|
|
3607
|
-
/* @__PURE__ */
|
|
3608
|
-
/* @__PURE__ */
|
|
3609
|
-
/* @__PURE__ */
|
|
3610
|
-
/* @__PURE__ */
|
|
3728
|
+
/* @__PURE__ */ jsx43(AlertDialog, { open: !!priceToArchive, onOpenChange: (open) => !open && setPriceToArchive(null), children: /* @__PURE__ */ jsxs37(AlertDialogContent, { children: [
|
|
3729
|
+
/* @__PURE__ */ jsxs37(AlertDialogHeader, { children: [
|
|
3730
|
+
/* @__PURE__ */ jsx43(AlertDialogTitle, { children: "Archive Price" }),
|
|
3731
|
+
/* @__PURE__ */ jsxs37(AlertDialogDescription, { children: [
|
|
3611
3732
|
"Are you sure you want to archive the price for",
|
|
3612
3733
|
" ",
|
|
3613
3734
|
priceToArchive && `${formatCurrency(priceToArchive.unitAmount, priceToArchive.currency)} ${formatInterval2(priceToArchive)}`,
|
|
3614
3735
|
"? This will prevent new subscriptions but existing ones will continue."
|
|
3615
3736
|
] })
|
|
3616
3737
|
] }),
|
|
3617
|
-
/* @__PURE__ */
|
|
3618
|
-
/* @__PURE__ */
|
|
3619
|
-
/* @__PURE__ */
|
|
3738
|
+
/* @__PURE__ */ jsxs37(AlertDialogFooter, { children: [
|
|
3739
|
+
/* @__PURE__ */ jsx43(AlertDialogCancel, { disabled: !!archivingPriceId, children: "Cancel" }),
|
|
3740
|
+
/* @__PURE__ */ jsx43(
|
|
3620
3741
|
AlertDialogAction,
|
|
3621
3742
|
{
|
|
3622
3743
|
onClick: handleArchive,
|
|
@@ -3627,19 +3748,19 @@ function PricesList({ productId, onPricesChange }) {
|
|
|
3627
3748
|
)
|
|
3628
3749
|
] })
|
|
3629
3750
|
] }) }),
|
|
3630
|
-
/* @__PURE__ */
|
|
3631
|
-
/* @__PURE__ */
|
|
3632
|
-
/* @__PURE__ */
|
|
3633
|
-
/* @__PURE__ */
|
|
3751
|
+
/* @__PURE__ */ jsx43(AlertDialog, { open: !!priceToReactivate, onOpenChange: (open) => !open && setPriceToReactivate(null), children: /* @__PURE__ */ jsxs37(AlertDialogContent, { children: [
|
|
3752
|
+
/* @__PURE__ */ jsxs37(AlertDialogHeader, { children: [
|
|
3753
|
+
/* @__PURE__ */ jsx43(AlertDialogTitle, { children: "Reactivate Price" }),
|
|
3754
|
+
/* @__PURE__ */ jsxs37(AlertDialogDescription, { children: [
|
|
3634
3755
|
"Are you sure you want to reactivate the price for",
|
|
3635
3756
|
" ",
|
|
3636
3757
|
priceToReactivate && `${formatCurrency(priceToReactivate.unitAmount, priceToReactivate.currency)} ${formatInterval2(priceToReactivate)}`,
|
|
3637
3758
|
"? This will allow new subscriptions again."
|
|
3638
3759
|
] })
|
|
3639
3760
|
] }),
|
|
3640
|
-
/* @__PURE__ */
|
|
3641
|
-
/* @__PURE__ */
|
|
3642
|
-
/* @__PURE__ */
|
|
3761
|
+
/* @__PURE__ */ jsxs37(AlertDialogFooter, { children: [
|
|
3762
|
+
/* @__PURE__ */ jsx43(AlertDialogCancel, { disabled: !!reactivatingPriceId, children: "Cancel" }),
|
|
3763
|
+
/* @__PURE__ */ jsx43(
|
|
3643
3764
|
AlertDialogAction,
|
|
3644
3765
|
{
|
|
3645
3766
|
onClick: handleReactivate,
|
|
@@ -3656,91 +3777,19 @@ __name(PricesList, "PricesList");
|
|
|
3656
3777
|
|
|
3657
3778
|
// src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx
|
|
3658
3779
|
import { Package as Package2 } from "lucide-react";
|
|
3659
|
-
import { useEffect as useEffect12, useState as
|
|
3660
|
-
|
|
3661
|
-
// src/features/billing/stripe-product/components/forms/ProductEditor.tsx
|
|
3662
|
-
import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
|
|
3663
|
-
import { useState as useState17 } from "react";
|
|
3664
|
-
import { useForm as useForm3 } from "react-hook-form";
|
|
3665
|
-
import { v4 as v43 } from "uuid";
|
|
3666
|
-
import { z as z3 } from "zod";
|
|
3667
|
-
import { jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3668
|
-
function ProductEditor({ product, open, onOpenChange, onSuccess }) {
|
|
3669
|
-
const [isSubmitting, setIsSubmitting] = useState17(false);
|
|
3670
|
-
const formSchema2 = z3.object({
|
|
3671
|
-
name: z3.string().min(1, { message: "Product name is required" }),
|
|
3672
|
-
description: z3.string().min(1, { message: "Description is required" }),
|
|
3673
|
-
active: z3.boolean()
|
|
3674
|
-
});
|
|
3675
|
-
const form = useForm3({
|
|
3676
|
-
resolver: zodResolver3(formSchema2),
|
|
3677
|
-
defaultValues: {
|
|
3678
|
-
name: product?.name || "",
|
|
3679
|
-
description: product?.description || "",
|
|
3680
|
-
active: product?.active ?? true
|
|
3681
|
-
}
|
|
3682
|
-
});
|
|
3683
|
-
const onSubmit = /* @__PURE__ */ __name(async (values) => {
|
|
3684
|
-
setIsSubmitting(true);
|
|
3685
|
-
try {
|
|
3686
|
-
if (product) {
|
|
3687
|
-
await StripeProductService.updateProduct({
|
|
3688
|
-
id: product.id,
|
|
3689
|
-
name: values.name,
|
|
3690
|
-
description: values.description,
|
|
3691
|
-
active: values.active
|
|
3692
|
-
});
|
|
3693
|
-
} else {
|
|
3694
|
-
await StripeProductService.createProduct({
|
|
3695
|
-
id: v43(),
|
|
3696
|
-
name: values.name,
|
|
3697
|
-
description: values.description,
|
|
3698
|
-
active: values.active
|
|
3699
|
-
});
|
|
3700
|
-
}
|
|
3701
|
-
onSuccess();
|
|
3702
|
-
onOpenChange(false);
|
|
3703
|
-
} catch (error) {
|
|
3704
|
-
console.error("[ProductEditor] Failed to save product:", error);
|
|
3705
|
-
} finally {
|
|
3706
|
-
setIsSubmitting(false);
|
|
3707
|
-
}
|
|
3708
|
-
}, "onSubmit");
|
|
3709
|
-
return /* @__PURE__ */ jsx42(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs37(DialogContent, { className: "max-w-2xl", children: [
|
|
3710
|
-
/* @__PURE__ */ jsxs37(DialogHeader, { children: [
|
|
3711
|
-
/* @__PURE__ */ jsx42(DialogTitle, { children: product ? "Edit Product" : "Create Product" }),
|
|
3712
|
-
/* @__PURE__ */ jsx42(DialogDescription, { children: product ? `Update the details for ${product.name}` : "Create a new product to offer to your customers" })
|
|
3713
|
-
] }),
|
|
3714
|
-
/* @__PURE__ */ jsx42(Form, { ...form, children: /* @__PURE__ */ jsxs37("form", { onSubmit: form.handleSubmit(onSubmit), className: "flex flex-col gap-y-4", children: [
|
|
3715
|
-
/* @__PURE__ */ jsx42(FormInput, { form, id: "name", name: "Product Name", placeholder: "Enter product name", isRequired: true }),
|
|
3716
|
-
/* @__PURE__ */ jsx42(
|
|
3717
|
-
FormTextarea,
|
|
3718
|
-
{
|
|
3719
|
-
form,
|
|
3720
|
-
id: "description",
|
|
3721
|
-
name: "Description",
|
|
3722
|
-
placeholder: "Enter product description",
|
|
3723
|
-
className: "min-h-32"
|
|
3724
|
-
}
|
|
3725
|
-
),
|
|
3726
|
-
/* @__PURE__ */ jsx42(FormCheckbox, { form, id: "active", name: "Active" }),
|
|
3727
|
-
/* @__PURE__ */ jsx42(CommonEditorButtons, { isEdit: !!product, form, disabled: isSubmitting, setOpen: onOpenChange })
|
|
3728
|
-
] }) })
|
|
3729
|
-
] }) });
|
|
3730
|
-
}
|
|
3731
|
-
__name(ProductEditor, "ProductEditor");
|
|
3780
|
+
import { useEffect as useEffect12, useState as useState20 } from "react";
|
|
3732
3781
|
|
|
3733
3782
|
// src/features/billing/stripe-product/components/lists/ProductsList.tsx
|
|
3734
3783
|
import { Archive as Archive2, ChevronDown, ChevronUp, Edit as Edit2, Package, RefreshCw as RefreshCw2 } from "lucide-react";
|
|
3735
|
-
import { useState as
|
|
3736
|
-
import { jsx as
|
|
3784
|
+
import { useState as useState19 } from "react";
|
|
3785
|
+
import { jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3737
3786
|
function ProductsList({ products, onProductsChange }) {
|
|
3738
|
-
const [expandedProductId, setExpandedProductId] =
|
|
3739
|
-
const [editingProduct, setEditingProduct] =
|
|
3740
|
-
const [archivingProductId, setArchivingProductId] =
|
|
3741
|
-
const [reactivatingProductId, setReactivatingProductId] =
|
|
3742
|
-
const [productToArchive, setProductToArchive] =
|
|
3743
|
-
const [productToReactivate, setProductToReactivate] =
|
|
3787
|
+
const [expandedProductId, setExpandedProductId] = useState19(null);
|
|
3788
|
+
const [editingProduct, setEditingProduct] = useState19(null);
|
|
3789
|
+
const [archivingProductId, setArchivingProductId] = useState19(null);
|
|
3790
|
+
const [reactivatingProductId, setReactivatingProductId] = useState19(null);
|
|
3791
|
+
const [productToArchive, setProductToArchive] = useState19(null);
|
|
3792
|
+
const [productToReactivate, setProductToReactivate] = useState19(null);
|
|
3744
3793
|
const handleArchive = /* @__PURE__ */ __name(async () => {
|
|
3745
3794
|
if (!productToArchive) {
|
|
3746
3795
|
return;
|
|
@@ -3781,18 +3830,18 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3781
3830
|
return /* @__PURE__ */ jsxs38("div", { className: "border rounded-lg bg-white shadow-sm hover:shadow-md transition-shadow", children: [
|
|
3782
3831
|
/* @__PURE__ */ jsxs38("div", { className: "flex items-center justify-between p-6", children: [
|
|
3783
3832
|
/* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-x-4 flex-1", children: [
|
|
3784
|
-
/* @__PURE__ */
|
|
3833
|
+
/* @__PURE__ */ jsx44(Package, { className: "h-6 w-6 text-primary" }),
|
|
3785
3834
|
/* @__PURE__ */ jsxs38("div", { className: "flex-1", children: [
|
|
3786
3835
|
/* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-x-3", children: [
|
|
3787
|
-
/* @__PURE__ */
|
|
3788
|
-
product.active ? /* @__PURE__ */
|
|
3836
|
+
/* @__PURE__ */ jsx44("h3", { className: "text-sm font-medium", children: product.name }),
|
|
3837
|
+
product.active ? /* @__PURE__ */ jsx44(Badge, { variant: "softGreen", children: "Active" }) : /* @__PURE__ */ jsx44(Badge, { variant: "softGray", children: "Inactive" })
|
|
3789
3838
|
] }),
|
|
3790
|
-
product.description && /* @__PURE__ */
|
|
3839
|
+
product.description && /* @__PURE__ */ jsx44("p", { className: "text-muted-foreground text-sm mt-1", children: product.description })
|
|
3791
3840
|
] })
|
|
3792
3841
|
] }),
|
|
3793
3842
|
/* @__PURE__ */ jsxs38("div", { className: "flex items-center gap-x-2", children: [
|
|
3794
3843
|
/* @__PURE__ */ jsxs38(Button, { variant: "outline", size: "sm", onClick: () => setEditingProduct(product), children: [
|
|
3795
|
-
/* @__PURE__ */
|
|
3844
|
+
/* @__PURE__ */ jsx44(Edit2, { className: "h-4 w-4 mr-1" }),
|
|
3796
3845
|
"Edit"
|
|
3797
3846
|
] }),
|
|
3798
3847
|
product.active ? /* @__PURE__ */ jsxs38(
|
|
@@ -3803,7 +3852,7 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3803
3852
|
onClick: () => setProductToArchive(product),
|
|
3804
3853
|
disabled: isArchiving,
|
|
3805
3854
|
children: [
|
|
3806
|
-
/* @__PURE__ */
|
|
3855
|
+
/* @__PURE__ */ jsx44(Archive2, { className: "h-4 w-4 mr-1" }),
|
|
3807
3856
|
isArchiving ? "Archiving..." : "Archive"
|
|
3808
3857
|
]
|
|
3809
3858
|
}
|
|
@@ -3815,18 +3864,18 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3815
3864
|
onClick: () => setProductToReactivate(product),
|
|
3816
3865
|
disabled: isReactivating,
|
|
3817
3866
|
children: [
|
|
3818
|
-
/* @__PURE__ */
|
|
3867
|
+
/* @__PURE__ */ jsx44(RefreshCw2, { className: "h-4 w-4 mr-1" }),
|
|
3819
3868
|
isReactivating ? "Reactivating..." : "Reactivate"
|
|
3820
3869
|
]
|
|
3821
3870
|
}
|
|
3822
3871
|
),
|
|
3823
|
-
/* @__PURE__ */
|
|
3872
|
+
/* @__PURE__ */ jsx44(Button, { variant: "ghost", size: "sm", onClick: () => toggleExpand(product.id), children: isExpanded ? /* @__PURE__ */ jsx44(ChevronUp, { className: "h-5 w-5" }) : /* @__PURE__ */ jsx44(ChevronDown, { className: "h-5 w-5" }) })
|
|
3824
3873
|
] })
|
|
3825
3874
|
] }),
|
|
3826
|
-
isExpanded && /* @__PURE__ */
|
|
3875
|
+
isExpanded && /* @__PURE__ */ jsx44("div", { className: "border-t bg-muted/30 p-6", children: /* @__PURE__ */ jsx44(PricesList, { productId: product.id, onPricesChange: onProductsChange }) })
|
|
3827
3876
|
] }, product.id);
|
|
3828
3877
|
}),
|
|
3829
|
-
editingProduct && /* @__PURE__ */
|
|
3878
|
+
editingProduct && /* @__PURE__ */ jsx44(
|
|
3830
3879
|
ProductEditor,
|
|
3831
3880
|
{
|
|
3832
3881
|
product: editingProduct,
|
|
@@ -3838,9 +3887,9 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3838
3887
|
}
|
|
3839
3888
|
}
|
|
3840
3889
|
),
|
|
3841
|
-
/* @__PURE__ */
|
|
3890
|
+
/* @__PURE__ */ jsx44(AlertDialog, { open: !!productToArchive, onOpenChange: (open) => !open && setProductToArchive(null), children: /* @__PURE__ */ jsxs38(AlertDialogContent, { children: [
|
|
3842
3891
|
/* @__PURE__ */ jsxs38(AlertDialogHeader, { children: [
|
|
3843
|
-
/* @__PURE__ */
|
|
3892
|
+
/* @__PURE__ */ jsx44(AlertDialogTitle, { children: "Archive Product" }),
|
|
3844
3893
|
/* @__PURE__ */ jsxs38(AlertDialogDescription, { children: [
|
|
3845
3894
|
'Are you sure you want to archive "',
|
|
3846
3895
|
productToArchive?.name,
|
|
@@ -3848,8 +3897,8 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3848
3897
|
] })
|
|
3849
3898
|
] }),
|
|
3850
3899
|
/* @__PURE__ */ jsxs38(AlertDialogFooter, { children: [
|
|
3851
|
-
/* @__PURE__ */
|
|
3852
|
-
/* @__PURE__ */
|
|
3900
|
+
/* @__PURE__ */ jsx44(AlertDialogCancel, { disabled: !!archivingProductId, children: "Cancel" }),
|
|
3901
|
+
/* @__PURE__ */ jsx44(
|
|
3853
3902
|
AlertDialogAction,
|
|
3854
3903
|
{
|
|
3855
3904
|
onClick: handleArchive,
|
|
@@ -3860,9 +3909,9 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3860
3909
|
)
|
|
3861
3910
|
] })
|
|
3862
3911
|
] }) }),
|
|
3863
|
-
/* @__PURE__ */
|
|
3912
|
+
/* @__PURE__ */ jsx44(AlertDialog, { open: !!productToReactivate, onOpenChange: (open) => !open && setProductToReactivate(null), children: /* @__PURE__ */ jsxs38(AlertDialogContent, { children: [
|
|
3864
3913
|
/* @__PURE__ */ jsxs38(AlertDialogHeader, { children: [
|
|
3865
|
-
/* @__PURE__ */
|
|
3914
|
+
/* @__PURE__ */ jsx44(AlertDialogTitle, { children: "Reactivate Product" }),
|
|
3866
3915
|
/* @__PURE__ */ jsxs38(AlertDialogDescription, { children: [
|
|
3867
3916
|
'Are you sure you want to reactivate "',
|
|
3868
3917
|
productToReactivate?.name,
|
|
@@ -3870,8 +3919,8 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3870
3919
|
] })
|
|
3871
3920
|
] }),
|
|
3872
3921
|
/* @__PURE__ */ jsxs38(AlertDialogFooter, { children: [
|
|
3873
|
-
/* @__PURE__ */
|
|
3874
|
-
/* @__PURE__ */
|
|
3922
|
+
/* @__PURE__ */ jsx44(AlertDialogCancel, { disabled: !!reactivatingProductId, children: "Cancel" }),
|
|
3923
|
+
/* @__PURE__ */ jsx44(
|
|
3875
3924
|
AlertDialogAction,
|
|
3876
3925
|
{
|
|
3877
3926
|
onClick: handleReactivate,
|
|
@@ -3887,14 +3936,15 @@ function ProductsList({ products, onProductsChange }) {
|
|
|
3887
3936
|
__name(ProductsList, "ProductsList");
|
|
3888
3937
|
|
|
3889
3938
|
// src/features/billing/stripe-product/components/containers/ProductsAdminContainer.tsx
|
|
3890
|
-
import { jsx as
|
|
3939
|
+
import { jsx as jsx45, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3891
3940
|
function ProductsAdminContainer() {
|
|
3892
3941
|
const { hasRole } = useCurrentUserContext();
|
|
3893
|
-
const
|
|
3894
|
-
const [
|
|
3895
|
-
const [
|
|
3942
|
+
const billing = useOptionalBillingContext();
|
|
3943
|
+
const [products, setProducts] = useState20([]);
|
|
3944
|
+
const [loading, setLoading] = useState20(true);
|
|
3945
|
+
const [showCreateProduct, setShowCreateProduct] = useState20(false);
|
|
3896
3946
|
if (!hasRole(getRoleId().Administrator)) {
|
|
3897
|
-
return /* @__PURE__ */
|
|
3947
|
+
return /* @__PURE__ */ jsx45("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx45("p", { className: "text-destructive text-xs/relaxed", children: "Permission denied. Administrator access required." }) });
|
|
3898
3948
|
}
|
|
3899
3949
|
const loadProducts = /* @__PURE__ */ __name(async () => {
|
|
3900
3950
|
setLoading(true);
|
|
@@ -3909,35 +3959,39 @@ function ProductsAdminContainer() {
|
|
|
3909
3959
|
}, "loadProducts");
|
|
3910
3960
|
useEffect12(() => {
|
|
3911
3961
|
loadProducts();
|
|
3912
|
-
}, []);
|
|
3962
|
+
}, [billing?.refreshToken]);
|
|
3913
3963
|
if (loading) {
|
|
3914
|
-
return /* @__PURE__ */
|
|
3964
|
+
return /* @__PURE__ */ jsx45("div", { className: "flex h-64 items-center justify-center", children: /* @__PURE__ */ jsx45("p", { className: "text-muted-foreground", children: "Loading products..." }) });
|
|
3915
3965
|
}
|
|
3916
|
-
return /* @__PURE__ */ jsxs39("div", { className: "flex w-full flex-col
|
|
3917
|
-
/* @__PURE__ */
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
/* @__PURE__ */
|
|
3966
|
+
return /* @__PURE__ */ jsxs39("div", { className: "flex w-full flex-col", children: [
|
|
3967
|
+
!billing && /* @__PURE__ */ jsx45("div", { className: "flex w-full items-center justify-end px-4 pt-4", children: /* @__PURE__ */ jsx45(Button, { onClick: () => setShowCreateProduct(true), children: "Create Product" }) }),
|
|
3968
|
+
/* @__PURE__ */ jsxs39("div", { className: "flex w-full flex-col gap-y-6 px-4 pb-4", children: [
|
|
3969
|
+
products.length === 0 && /* @__PURE__ */ jsxs39("div", { className: "bg-muted/50 flex flex-col items-center justify-center gap-y-4 rounded-lg border-2 border-dashed p-12", children: [
|
|
3970
|
+
/* @__PURE__ */ jsx45(Package2, { className: "text-muted-foreground h-16 w-16" }),
|
|
3971
|
+
/* @__PURE__ */ jsxs39("div", { className: "text-center", children: [
|
|
3972
|
+
/* @__PURE__ */ jsx45("h3", { className: "mb-2 text-sm font-medium", children: "No products yet" }),
|
|
3973
|
+
/* @__PURE__ */ jsx45("p", { className: "text-muted-foreground mb-4", children: "Create your first product to start offering subscriptions to your customers." }),
|
|
3974
|
+
/* @__PURE__ */ jsx45(Button, { onClick: () => setShowCreateProduct(true), children: "Create Your First Product" })
|
|
3975
|
+
] })
|
|
3921
3976
|
] }),
|
|
3922
|
-
/* @__PURE__ */
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
/* @__PURE__ */ jsx44(Package2, { className: "text-muted-foreground h-16 w-16" }),
|
|
3926
|
-
/* @__PURE__ */ jsxs39("div", { className: "text-center", children: [
|
|
3927
|
-
/* @__PURE__ */ jsx44("h3", { className: "mb-2 text-sm font-medium", children: "No products yet" }),
|
|
3928
|
-
/* @__PURE__ */ jsx44("p", { className: "text-muted-foreground mb-4", children: "Create your first product to start offering subscriptions to your customers." }),
|
|
3929
|
-
/* @__PURE__ */ jsx44(Button, { onClick: () => setShowCreateProduct(true), children: "Create Your First Product" })
|
|
3930
|
-
] })
|
|
3931
|
-
] }),
|
|
3932
|
-
products.length > 0 && /* @__PURE__ */ jsx44(ProductsList, { products, onProductsChange: loadProducts }),
|
|
3933
|
-
showCreateProduct && /* @__PURE__ */ jsx44(ProductEditor, { open: showCreateProduct, onOpenChange: setShowCreateProduct, onSuccess: loadProducts })
|
|
3977
|
+
products.length > 0 && /* @__PURE__ */ jsx45(ProductsList, { products, onProductsChange: loadProducts }),
|
|
3978
|
+
showCreateProduct && /* @__PURE__ */ jsx45(ProductEditor, { open: showCreateProduct, onOpenChange: setShowCreateProduct, onSuccess: loadProducts })
|
|
3979
|
+
] })
|
|
3934
3980
|
] });
|
|
3935
3981
|
}
|
|
3936
3982
|
__name(ProductsAdminContainer, "ProductsAdminContainer");
|
|
3983
|
+
|
|
3984
|
+
// src/features/billing/stripe-product/components/containers/ProductsAdminPageContainer.tsx
|
|
3985
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
3986
|
+
function ProductsAdminPageContainer() {
|
|
3987
|
+
return /* @__PURE__ */ jsx46(BillingProvider, { children: /* @__PURE__ */ jsx46(RoundPageContainer, { module: Modules.StripeProduct, fullWidth: true, forceHeader: true, children: /* @__PURE__ */ jsx46(ProductsAdminContainer, {}) }) });
|
|
3988
|
+
}
|
|
3989
|
+
__name(ProductsAdminPageContainer, "ProductsAdminPageContainer");
|
|
3937
3990
|
export {
|
|
3938
3991
|
BillingAlertBanner,
|
|
3939
3992
|
BillingDashboardContainer,
|
|
3940
3993
|
BillingDetailModal,
|
|
3994
|
+
BillingProvider,
|
|
3941
3995
|
BillingUsageSummaryCard,
|
|
3942
3996
|
CancelSubscriptionDialog,
|
|
3943
3997
|
CustomerInfoCard,
|
|
@@ -3960,6 +4014,7 @@ export {
|
|
|
3960
4014
|
ProductPricingList,
|
|
3961
4015
|
ProductPricingRow,
|
|
3962
4016
|
ProductsAdminContainer,
|
|
4017
|
+
ProductsAdminPageContainer,
|
|
3963
4018
|
ProductsList,
|
|
3964
4019
|
PromoCodeInput,
|
|
3965
4020
|
ProrationPreview,
|
|
@@ -3977,6 +4032,8 @@ export {
|
|
|
3977
4032
|
formatCurrency,
|
|
3978
4033
|
formatDate3 as formatDate,
|
|
3979
4034
|
formatInterval,
|
|
3980
|
-
isStripeConfigured
|
|
4035
|
+
isStripeConfigured,
|
|
4036
|
+
useBillingContext,
|
|
4037
|
+
useOptionalBillingContext
|
|
3981
4038
|
};
|
|
3982
4039
|
//# sourceMappingURL=index.mjs.map
|