@nextblock-cms/ecom 0.11.2 → 0.12.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/lib/invoice-server.cjs.js +3 -3
- package/lib/invoice-server.es.js +56 -48
- package/lib/pages/cms/products/actions.d.ts +1 -0
- package/lib/pages/cms/products/components/ProductForm.cjs.js +1 -1
- package/lib/pages/cms/products/components/ProductForm.es.js +170 -165
- package/lib/product-actions.cjs.js +4 -4
- package/lib/product-actions.d.ts +3 -0
- package/lib/product-actions.es.js +86 -73
- package/lib/product-schema.cjs.js +1 -1
- package/lib/product-schema.d.ts +1 -0
- package/lib/product-schema.es.js +1 -0
- package/package.json +4 -4
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs as s, jsx as e, Fragment as Me } from "react/jsx-runtime";
|
|
3
|
-
import
|
|
3
|
+
import U, { useState as A, useRef as Ve, useEffect as k, useCallback as X } from "react";
|
|
4
4
|
import { zodResolver as De } from "@hookform/resolvers/zod";
|
|
5
5
|
import { AlertCircle as Ae, CheckCircle2 as er, Info as rr } from "lucide-react";
|
|
6
|
-
import { Select as le, SelectTrigger as ne, SelectValue as ce, SelectContent as ue, SelectItem as F, Badge as
|
|
6
|
+
import { Select as le, SelectTrigger as ne, SelectValue as ce, SelectContent as ue, SelectItem as F, Badge as Y, Label as x, Input as y, Button as Te } from "@nextblock-cms/ui";
|
|
7
7
|
import { productSchema as tr } from "../../../../product-schema.es.js";
|
|
8
8
|
import { useForm as sr } from "react-hook-form";
|
|
9
9
|
import { ProductMediaManager as ar } from "./ProductMediaManager.es.js";
|
|
10
|
-
import { SyncFreemiusPricingButton as
|
|
11
|
-
import { VariationsEditor as
|
|
10
|
+
import { SyncFreemiusPricingButton as ir } from "./SyncFreemiusPricingButton.es.js";
|
|
11
|
+
import { VariationsEditor as dr } from "./VariationsEditor.es.js";
|
|
12
12
|
import { CurrencyPriceFields as Ie } from "./CurrencyPriceFields.es.js";
|
|
13
|
-
import { SaleScheduleFields as
|
|
13
|
+
import { SaleScheduleFields as Re } from "./SaleScheduleFields.es.js";
|
|
14
14
|
import { ProductCategorySelector as or } from "./ProductCategorySelector.es.js";
|
|
15
15
|
import { getStoreManagedPriceCurrencyCodes as lr, resolveEditorCurrencyPriceMaps as nr, sanitizeProductFormValuesForStoreManagedCurrencies as Be } from "../product-price-sync.es.js";
|
|
16
16
|
import { derivePaymentProviderFromProductType as cr } from "../../../../types.es.js";
|
|
17
|
-
import { convertMinorUnitAmount as
|
|
18
|
-
import { majorUnitAmountToMinor as Oe, minorUnitAmountToMajor as
|
|
19
|
-
function Q({ title: r, description: a, action:
|
|
17
|
+
import { convertMinorUnitAmount as je } from "../../../../currency.es.js";
|
|
18
|
+
import { majorUnitAmountToMinor as Oe, minorUnitAmountToMajor as Ue } from "@nextblock-cms/utils";
|
|
19
|
+
function Q({ title: r, description: a, action: b, children: h, hideHeader: C }) {
|
|
20
20
|
return /* @__PURE__ */ s("section", { className: "rounded-lg border bg-card p-3 shadow-sm space-y-3", children: [
|
|
21
21
|
!C && /* @__PURE__ */ s("div", { className: "flex items-start justify-between gap-4 flex-wrap border-b border-muted/50 pb-2 mb-1", children: [
|
|
22
22
|
/* @__PURE__ */ s("div", { className: "space-y-0.5", children: [
|
|
23
23
|
/* @__PURE__ */ e("h2", { className: "text-sm font-bold tracking-tight", children: r }),
|
|
24
24
|
a ? /* @__PURE__ */ e("p", { className: "text-[11px] text-muted-foreground leading-none", children: a }) : null
|
|
25
25
|
] }),
|
|
26
|
-
|
|
26
|
+
b
|
|
27
27
|
] }),
|
|
28
28
|
/* @__PURE__ */ e("div", { className: C ? "" : "pt-1", children: h })
|
|
29
29
|
] });
|
|
30
30
|
}
|
|
31
|
-
function ur(r, a,
|
|
31
|
+
function ur(r, a, b) {
|
|
32
32
|
const h = a ? Number.parseInt(a, 10) : void 0;
|
|
33
|
-
return r?.language_id || (Number.isFinite(h) ? h : void 0) ||
|
|
33
|
+
return r?.language_id || (Number.isFinite(h) ? h : void 0) || b.find((C) => C.is_default)?.id || b[0]?.id || 1;
|
|
34
34
|
}
|
|
35
|
-
function
|
|
36
|
-
const T = (h.find((
|
|
35
|
+
function qe(r, a, b, h, C) {
|
|
36
|
+
const T = (h.find((v) => v.is_default) ?? h[0])?.code || "USD", j = r?.prices && Object.keys(r.prices).length > 0 ? r.prices : {
|
|
37
37
|
[T]: typeof r?.price == "number" ? r.price / 100 : 0
|
|
38
|
-
},
|
|
38
|
+
}, q = r?.sale_prices && Object.keys(r.sale_prices).length > 0 ? r.sale_prices : typeof r?.sale_price == "number" ? {
|
|
39
39
|
[T]: r.sale_price / 100
|
|
40
|
-
} : {},
|
|
40
|
+
} : {}, z = r?.product_type || "", I = r?.payment_provider || (r?.product_type ? cr(r.product_type) : "stripe");
|
|
41
41
|
return {
|
|
42
42
|
...Be({
|
|
43
|
-
product_type:
|
|
43
|
+
product_type: z || "physical",
|
|
44
44
|
payment_provider: I,
|
|
45
45
|
title: r?.title || "",
|
|
46
46
|
slug: r?.slug || "",
|
|
@@ -48,12 +48,13 @@ function ze(r, a, x, h, C) {
|
|
|
48
48
|
upc: r?.upc || "",
|
|
49
49
|
is_taxable: r?.is_taxable ?? !0,
|
|
50
50
|
price: typeof r?.price == "number" ? r.price / 100 : 0,
|
|
51
|
-
prices:
|
|
51
|
+
prices: j,
|
|
52
52
|
sale_price: typeof r?.sale_price == "number" ? r.sale_price / 100 : null,
|
|
53
|
-
sale_prices:
|
|
53
|
+
sale_prices: q,
|
|
54
54
|
stock: r?.stock || 0,
|
|
55
55
|
meta_title: r?.meta_title || "",
|
|
56
56
|
meta_description: r?.meta_description || "",
|
|
57
|
+
custom_canonical: r?.custom_canonical || "",
|
|
57
58
|
short_description: r?.short_description || "",
|
|
58
59
|
description_json: r?.description_json || {
|
|
59
60
|
type: "doc",
|
|
@@ -67,32 +68,32 @@ function ze(r, a, x, h, C) {
|
|
|
67
68
|
language_id: ur(
|
|
68
69
|
r,
|
|
69
70
|
a,
|
|
70
|
-
|
|
71
|
+
b
|
|
71
72
|
),
|
|
72
73
|
translation_group_id: r?.translation_group_id || C || void 0,
|
|
73
|
-
product_media: r?.product_media?.map((
|
|
74
|
-
media_id:
|
|
74
|
+
product_media: r?.product_media?.map((v) => ({
|
|
75
|
+
media_id: v.media_id
|
|
75
76
|
})) || [],
|
|
76
77
|
category_ids: r?.category_ids || [],
|
|
77
78
|
variation_attributes: r?.variation_attributes || [],
|
|
78
|
-
variants: r?.variants?.map((
|
|
79
|
-
...
|
|
80
|
-
prices:
|
|
81
|
-
sale_prices:
|
|
79
|
+
variants: r?.variants?.map((v) => ({
|
|
80
|
+
...v,
|
|
81
|
+
prices: v.prices || {},
|
|
82
|
+
sale_prices: v.sale_prices || {}
|
|
82
83
|
})) || []
|
|
83
84
|
}, h),
|
|
84
|
-
product_type:
|
|
85
|
+
product_type: z,
|
|
85
86
|
payment_provider: I
|
|
86
87
|
};
|
|
87
88
|
}
|
|
88
|
-
function
|
|
89
|
+
function ze(r) {
|
|
89
90
|
return r ? r.map((a) => ({
|
|
90
91
|
id: a.id || a.media_id,
|
|
91
92
|
media_id: a.media_id,
|
|
92
93
|
file_path: a.media?.file_path || a.media?.object_key || "",
|
|
93
94
|
alt: a.media?.alt_text || "",
|
|
94
95
|
sort_order: a.sort_order ?? 0
|
|
95
|
-
})).sort((a,
|
|
96
|
+
})).sort((a, b) => a.sort_order - b.sort_order) : [];
|
|
96
97
|
}
|
|
97
98
|
function mr(r) {
|
|
98
99
|
return r.map((a) => ({ media_id: a.media_id }));
|
|
@@ -108,33 +109,33 @@ const hr = (r) => r.toString().toLowerCase().trim().replace(/\s+/g, "-").replace
|
|
|
108
109
|
function Tr({
|
|
109
110
|
initialData: r,
|
|
110
111
|
isEdit: a = !1,
|
|
111
|
-
mediaPickerNode:
|
|
112
|
+
mediaPickerNode: b,
|
|
112
113
|
availableLanguagesProp: h,
|
|
113
114
|
globalAttributesProp: C,
|
|
114
115
|
currenciesProp: W,
|
|
115
116
|
translationGroupId: T,
|
|
116
|
-
targetLanguageId:
|
|
117
|
-
freemiusDashboardNode:
|
|
118
|
-
enabledProviders:
|
|
117
|
+
targetLanguageId: j,
|
|
118
|
+
freemiusDashboardNode: q,
|
|
119
|
+
enabledProviders: z,
|
|
119
120
|
configStatus: I,
|
|
120
121
|
createAction: Z,
|
|
121
|
-
updateAction:
|
|
122
|
+
updateAction: v,
|
|
122
123
|
availableCategoriesProp: Ee = []
|
|
123
124
|
}) {
|
|
124
|
-
const [B, E] = A(!1), [G, D] = A(() => !!r?.variants?.length), c =
|
|
125
|
-
() => W.filter((t) => t.is_active !== !1).sort((t,
|
|
125
|
+
const [B, E] = A(!1), [G, D] = A(() => !!r?.variants?.length), c = U.useMemo(
|
|
126
|
+
() => W.filter((t) => t.is_active !== !1).sort((t, d) => t.is_default !== d.is_default ? t.is_default ? -1 : 1 : t.code.localeCompare(d.code)),
|
|
126
127
|
[W]
|
|
127
|
-
), l =
|
|
128
|
+
), l = U.useMemo(
|
|
128
129
|
() => c.find((t) => t.is_default) ?? c[0],
|
|
129
130
|
[c]
|
|
130
|
-
), K =
|
|
131
|
+
), K = U.useMemo(
|
|
131
132
|
() => lr(c),
|
|
132
133
|
[c]
|
|
133
134
|
), me = sr({
|
|
134
135
|
resolver: De(tr),
|
|
135
|
-
defaultValues:
|
|
136
|
+
defaultValues: qe(
|
|
136
137
|
r,
|
|
137
|
-
|
|
138
|
+
j,
|
|
138
139
|
h,
|
|
139
140
|
c,
|
|
140
141
|
T
|
|
@@ -142,7 +143,7 @@ function Tr({
|
|
|
142
143
|
}), {
|
|
143
144
|
register: n,
|
|
144
145
|
handleSubmit: ee,
|
|
145
|
-
setValue:
|
|
146
|
+
setValue: i,
|
|
146
147
|
reset: pe,
|
|
147
148
|
watch: o,
|
|
148
149
|
setError: $,
|
|
@@ -157,21 +158,21 @@ function Tr({
|
|
|
157
158
|
if (!xe) return;
|
|
158
159
|
const t = JSON.stringify(te);
|
|
159
160
|
if (t === re.current) return;
|
|
160
|
-
const
|
|
161
|
+
const d = setTimeout(() => {
|
|
161
162
|
B || (re.current = t, ee(Fe)());
|
|
162
163
|
}, 1e3);
|
|
163
|
-
return () => clearTimeout(
|
|
164
|
+
return () => clearTimeout(d);
|
|
164
165
|
}, [te, a, xe, B, ee]);
|
|
165
|
-
const ye = o("title"), O = o("product_type"), p = O === "digital" ? "freemius" : O === "physical" ? "stripe" : void 0,
|
|
166
|
+
const ye = o("title"), O = o("product_type"), p = O === "digital" ? "freemius" : O === "physical" ? "stripe" : void 0, N = O === "physical", be = O === "digital", se = p ? z[p] : !1, ae = p ? I[p].hasKeys : !1, He = !!o("freemius_product_id"), ve = Number(o("trial_period_days") || 0), Ne = !!o("trial_requires_payment_method"), Je = o("variants") || [], M = o("price"), R = o("sale_price"), P = o("prices") || {}, V = o("sale_prices") || {}, S = (Je?.length || 0) > 0, Le = o("language_id"), Xe = h.find((t) => t.id === Le)?.code || h.find((t) => t.is_default)?.code || h[0]?.code, L = U.useMemo(
|
|
166
167
|
() => nr({
|
|
167
168
|
currencies: c,
|
|
168
|
-
prices:
|
|
169
|
+
prices: P,
|
|
169
170
|
salePrices: V,
|
|
170
171
|
fallbackPrice: M,
|
|
171
|
-
fallbackSalePrice:
|
|
172
|
+
fallbackSalePrice: R
|
|
172
173
|
}),
|
|
173
|
-
[M,
|
|
174
|
-
),
|
|
174
|
+
[M, R, c, P, V]
|
|
175
|
+
), Ye = U.useMemo(
|
|
175
176
|
() => r?.variants?.map((t) => ({
|
|
176
177
|
...t,
|
|
177
178
|
prices: t.prices || {},
|
|
@@ -182,150 +183,150 @@ function Tr({
|
|
|
182
183
|
k(() => {
|
|
183
184
|
if (he.title && !a) {
|
|
184
185
|
const t = hr(ye);
|
|
185
|
-
|
|
186
|
+
i("slug", t, { shouldValidate: !0 });
|
|
186
187
|
}
|
|
187
|
-
}, [ye, he.title,
|
|
188
|
-
const [
|
|
189
|
-
() =>
|
|
190
|
-
), [
|
|
188
|
+
}, [ye, he.title, i, a]);
|
|
189
|
+
const [ie, Pe] = A(
|
|
190
|
+
() => ze(r?.product_media)
|
|
191
|
+
), [de, Se] = A(/* @__PURE__ */ new Set());
|
|
191
192
|
k(() => {
|
|
192
193
|
pe(
|
|
193
|
-
|
|
194
|
+
qe(
|
|
194
195
|
r,
|
|
195
|
-
|
|
196
|
+
j,
|
|
196
197
|
h,
|
|
197
198
|
c,
|
|
198
199
|
T
|
|
199
200
|
)
|
|
200
|
-
), Pe(
|
|
201
|
+
), Pe(ze(r?.product_media)), Se(/* @__PURE__ */ new Set()), D(!!r?.variants?.length);
|
|
201
202
|
}, [
|
|
202
203
|
h,
|
|
203
204
|
c,
|
|
204
205
|
r,
|
|
205
206
|
pe,
|
|
206
|
-
|
|
207
|
+
j,
|
|
207
208
|
T
|
|
208
209
|
]);
|
|
209
210
|
const Qe = (t) => {
|
|
210
|
-
const
|
|
211
|
+
const d = new Set(t.map((m) => m.id)), u = ie.filter((m) => !d.has(m.id)), g = new Set(de);
|
|
211
212
|
u.forEach((m) => {
|
|
212
213
|
m.media_id && g.add(m.media_id);
|
|
213
|
-
}), Se(g), Pe(t),
|
|
214
|
+
}), Se(g), Pe(t), i("product_media", mr(t), { shouldDirty: !0 }), i("explicitly_removed_media_ids", Array.from(g), {
|
|
214
215
|
shouldDirty: !0
|
|
215
216
|
});
|
|
216
217
|
};
|
|
217
218
|
k(() => {
|
|
218
|
-
|
|
219
|
-
}, [
|
|
219
|
+
i("explicitly_removed_media_ids", Array.from(de));
|
|
220
|
+
}, [de, i]), k(() => {
|
|
220
221
|
S && D(!0);
|
|
221
222
|
}, [S]), k(() => {
|
|
222
223
|
n("is_taxable"), n("price"), n("sale_price"), n("payment_provider"), n("trial_requires_payment_method");
|
|
223
224
|
}, [n]), k(() => {
|
|
224
225
|
if (!be) {
|
|
225
|
-
|
|
226
|
+
i("trial_period_days", 0, { shouldDirty: !1, shouldValidate: !0 }), i("trial_requires_payment_method", !1, {
|
|
226
227
|
shouldDirty: !1,
|
|
227
228
|
shouldValidate: !0
|
|
228
229
|
});
|
|
229
230
|
return;
|
|
230
231
|
}
|
|
231
|
-
ve <= 0 &&
|
|
232
|
+
ve <= 0 && i("trial_requires_payment_method", !1, {
|
|
232
233
|
shouldDirty: !1,
|
|
233
234
|
shouldValidate: !0
|
|
234
235
|
});
|
|
235
|
-
}, [be,
|
|
236
|
-
p &&
|
|
236
|
+
}, [be, i, ve]), k(() => {
|
|
237
|
+
p && i("payment_provider", p, {
|
|
237
238
|
shouldDirty: !1,
|
|
238
239
|
shouldValidate: !0
|
|
239
240
|
});
|
|
240
|
-
}, [p,
|
|
241
|
-
l &&
|
|
241
|
+
}, [p, i]), k(() => {
|
|
242
|
+
l && P[l.code] === void 0 && i(
|
|
242
243
|
"prices",
|
|
243
244
|
{
|
|
244
|
-
...
|
|
245
|
+
...P,
|
|
245
246
|
[l.code]: M || 0
|
|
246
247
|
},
|
|
247
248
|
{ shouldDirty: !1 }
|
|
248
249
|
);
|
|
249
|
-
}, [M, l,
|
|
250
|
-
const we =
|
|
251
|
-
(t,
|
|
250
|
+
}, [M, l, P, i]);
|
|
251
|
+
const we = X(
|
|
252
|
+
(t, d) => {
|
|
252
253
|
const u = {
|
|
253
|
-
...
|
|
254
|
-
[t]:
|
|
254
|
+
...P,
|
|
255
|
+
[t]: d
|
|
255
256
|
};
|
|
256
|
-
|
|
257
|
+
i("prices", u, { shouldDirty: !0, shouldValidate: !0 }), t === l?.code && i("price", d, { shouldDirty: !0, shouldValidate: !0 });
|
|
257
258
|
},
|
|
258
|
-
[l?.code,
|
|
259
|
-
), ke =
|
|
260
|
-
(t,
|
|
259
|
+
[l?.code, P, i]
|
|
260
|
+
), ke = X(
|
|
261
|
+
(t, d) => {
|
|
261
262
|
const u = {
|
|
262
263
|
...V,
|
|
263
|
-
[t]:
|
|
264
|
+
[t]: d
|
|
264
265
|
};
|
|
265
|
-
|
|
266
|
+
i("sale_prices", u, {
|
|
266
267
|
shouldDirty: !0,
|
|
267
268
|
shouldValidate: !0
|
|
268
|
-
}), t === l?.code &&
|
|
269
|
+
}), t === l?.code && i("sale_price", d, { shouldDirty: !0, shouldValidate: !0 });
|
|
269
270
|
},
|
|
270
|
-
[l?.code, V,
|
|
271
|
-
), Ce =
|
|
271
|
+
[l?.code, V, i]
|
|
272
|
+
), Ce = X(() => {
|
|
272
273
|
if (!l)
|
|
273
274
|
return;
|
|
274
|
-
const t = new Set(K),
|
|
275
|
+
const t = new Set(K), d = P[l.code] ?? M ?? 0, u = V[l.code] ?? R ?? null, g = c.reduce((w, _) => {
|
|
275
276
|
if (_.code !== l.code && t.has(_.code))
|
|
276
277
|
return w;
|
|
277
|
-
const oe =
|
|
278
|
-
amount: Oe(
|
|
278
|
+
const oe = je({
|
|
279
|
+
amount: Oe(d, l.code),
|
|
279
280
|
fromCurrencyCode: l.code,
|
|
280
281
|
toCurrencyCode: _.code,
|
|
281
282
|
currencies: c,
|
|
282
283
|
applyRounding: !0
|
|
283
284
|
});
|
|
284
|
-
return w[_.code] =
|
|
285
|
+
return w[_.code] = Ue(oe, _.code), w;
|
|
285
286
|
}, {}), m = c.reduce(
|
|
286
287
|
(w, _) => {
|
|
287
288
|
if (_.code !== l.code && t.has(_.code))
|
|
288
289
|
return w;
|
|
289
290
|
if (typeof u != "number")
|
|
290
291
|
return (_.code === l.code || !t.has(_.code)) && (w[_.code] = null), w;
|
|
291
|
-
const oe =
|
|
292
|
+
const oe = je({
|
|
292
293
|
amount: Oe(u, l.code),
|
|
293
294
|
fromCurrencyCode: l.code,
|
|
294
295
|
toCurrencyCode: _.code,
|
|
295
296
|
currencies: c,
|
|
296
297
|
applyRounding: !0
|
|
297
298
|
});
|
|
298
|
-
return w[_.code] =
|
|
299
|
+
return w[_.code] = Ue(oe, _.code), w;
|
|
299
300
|
},
|
|
300
301
|
{}
|
|
301
302
|
);
|
|
302
|
-
|
|
303
|
+
i("prices", g, { shouldDirty: !0, shouldValidate: !0 }), i("sale_prices", m, {
|
|
303
304
|
shouldDirty: !0,
|
|
304
305
|
shouldValidate: !0
|
|
305
|
-
}),
|
|
306
|
+
}), i("price", g[l.code] ?? d, {
|
|
306
307
|
shouldDirty: !0,
|
|
307
308
|
shouldValidate: !0
|
|
308
|
-
}),
|
|
309
|
+
}), i("sale_price", m[l.code] ?? null, {
|
|
309
310
|
shouldDirty: !0,
|
|
310
311
|
shouldValidate: !0
|
|
311
312
|
});
|
|
312
313
|
}, [
|
|
313
314
|
c,
|
|
314
315
|
l,
|
|
315
|
-
|
|
316
|
+
P,
|
|
316
317
|
V,
|
|
317
|
-
|
|
318
|
+
i,
|
|
318
319
|
K,
|
|
319
320
|
M,
|
|
320
|
-
|
|
321
|
-
]), We =
|
|
321
|
+
R
|
|
322
|
+
]), We = X(
|
|
322
323
|
({
|
|
323
324
|
variationAttributes: t,
|
|
324
|
-
variants:
|
|
325
|
+
variants: d
|
|
325
326
|
}) => {
|
|
326
|
-
|
|
327
|
+
i("variation_attributes", t, { shouldDirty: !0 }), i("variants", d, { shouldDirty: !0, shouldValidate: !0 });
|
|
327
328
|
},
|
|
328
|
-
[
|
|
329
|
+
[i]
|
|
329
330
|
), Fe = async (t) => {
|
|
330
331
|
E(!0), H(!0), J(null);
|
|
331
332
|
try {
|
|
@@ -345,34 +346,34 @@ function Tr({
|
|
|
345
346
|
}), a ? J(m) : alert(m), E(!1), H(!1);
|
|
346
347
|
return;
|
|
347
348
|
}
|
|
348
|
-
const
|
|
349
|
+
const d = N ? 0 : Math.max(0, Number(t.trial_period_days || 0)), u = {
|
|
349
350
|
...t,
|
|
350
351
|
product_type: t.product_type,
|
|
351
352
|
payment_provider: p,
|
|
352
|
-
freemius_product_id:
|
|
353
|
-
freemius_plan_id:
|
|
354
|
-
trial_period_days:
|
|
355
|
-
trial_requires_payment_method: !
|
|
356
|
-
upc:
|
|
357
|
-
is_taxable:
|
|
358
|
-
variation_attributes:
|
|
359
|
-
variants:
|
|
353
|
+
freemius_product_id: N ? "" : t.freemius_product_id,
|
|
354
|
+
freemius_plan_id: N ? "" : t.freemius_plan_id,
|
|
355
|
+
trial_period_days: d,
|
|
356
|
+
trial_requires_payment_method: !N && d > 0 ? t.trial_requires_payment_method : !1,
|
|
357
|
+
upc: N ? t.upc : null,
|
|
358
|
+
is_taxable: N ? t.is_taxable : !1,
|
|
359
|
+
variation_attributes: N ? t.variation_attributes : [],
|
|
360
|
+
variants: N ? t.variants : []
|
|
360
361
|
}, g = Be(
|
|
361
362
|
u,
|
|
362
363
|
c
|
|
363
364
|
);
|
|
364
|
-
if (a &&
|
|
365
|
-
await
|
|
365
|
+
if (a && v)
|
|
366
|
+
await v(g), $e(/* @__PURE__ */ new Date());
|
|
366
367
|
else if (Z)
|
|
367
368
|
await Z(g);
|
|
368
369
|
else
|
|
369
370
|
throw new Error("Product form action is not configured.");
|
|
370
|
-
} catch (
|
|
371
|
-
if (console.error(
|
|
371
|
+
} catch (d) {
|
|
372
|
+
if (console.error(d), d.message === "NEXT_REDIRECT")
|
|
372
373
|
return;
|
|
373
|
-
let u =
|
|
374
|
-
if (
|
|
375
|
-
const g =
|
|
374
|
+
let u = d.message || "An error occurred while saving.";
|
|
375
|
+
if (d.code === "23505") {
|
|
376
|
+
const g = d.message?.toLowerCase() || "";
|
|
376
377
|
g.includes("products_slug_key") || g.includes("slug") ? (u = "This slug is already in use. Please choose another one.", $("slug", {
|
|
377
378
|
type: "manual",
|
|
378
379
|
message: u
|
|
@@ -385,7 +386,7 @@ function Tr({
|
|
|
385
386
|
} finally {
|
|
386
387
|
E(!1), H(!1);
|
|
387
388
|
}
|
|
388
|
-
}, Ze = S ? "bg-muted/60 text-muted-foreground opacity-70" : "", Ge = pr(
|
|
389
|
+
}, Ze = S ? "bg-muted/60 text-muted-foreground opacity-70" : "", Ge = pr(ie);
|
|
389
390
|
return /* @__PURE__ */ s("form", { onSubmit: ee(Fe), className: "space-y-2.5 pb-4", children: [
|
|
390
391
|
/* @__PURE__ */ e("input", { type: "hidden", ...n("translation_group_id") }),
|
|
391
392
|
/* @__PURE__ */ e("input", { type: "hidden", ...n("payment_provider") }),
|
|
@@ -399,7 +400,7 @@ function Tr({
|
|
|
399
400
|
/* @__PURE__ */ e("div", { className: "flex h-9 items-center", children: /* @__PURE__ */ s(
|
|
400
401
|
le,
|
|
401
402
|
{
|
|
402
|
-
onValueChange: (t) =>
|
|
403
|
+
onValueChange: (t) => i("product_type", t, {
|
|
403
404
|
shouldDirty: !0,
|
|
404
405
|
shouldValidate: !0
|
|
405
406
|
}),
|
|
@@ -417,7 +418,7 @@ function Tr({
|
|
|
417
418
|
/* @__PURE__ */ s("div", { className: "flex items-center gap-6", children: [
|
|
418
419
|
/* @__PURE__ */ s("div", { className: "flex h-9 items-center gap-3", children: [
|
|
419
420
|
/* @__PURE__ */ e("span", { className: "text-[11px] font-semibold text-muted-foreground uppercase tracking-wider leading-none", children: "Payment Provider" }),
|
|
420
|
-
/* @__PURE__ */ e(
|
|
421
|
+
/* @__PURE__ */ e(Y, { variant: "outline", className: "text-xs py-1 font-bold bg-muted/30 leading-none", children: p ? p === "stripe" ? "Stripe" : "Freemius" : "—" })
|
|
421
422
|
] }),
|
|
422
423
|
p && /* @__PURE__ */ e("div", { className: "flex h-9 items-center gap-2", children: se && ae ? /* @__PURE__ */ s("span", { className: "flex items-center gap-1.5 text-emerald-600 text-[10px] font-bold bg-emerald-50 px-2 py-1 rounded-full border border-emerald-100 uppercase leading-none", children: [
|
|
423
424
|
/* @__PURE__ */ e(er, { className: "h-3 w-3" }),
|
|
@@ -457,37 +458,41 @@ function Tr({
|
|
|
457
458
|
] }),
|
|
458
459
|
/* @__PURE__ */ s("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-2.5", children: [
|
|
459
460
|
/* @__PURE__ */ s("div", { className: "col-span-2 space-y-1", children: [
|
|
460
|
-
/* @__PURE__ */ e(
|
|
461
|
-
/* @__PURE__ */ e(
|
|
461
|
+
/* @__PURE__ */ e(x, { htmlFor: "title", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Title" }),
|
|
462
|
+
/* @__PURE__ */ e(y, { id: "title", placeholder: "Product title", ...n("title"), className: "h-8 text-sm" }),
|
|
462
463
|
f.title && /* @__PURE__ */ e("p", { className: "text-destructive text-[11px] leading-none", children: f.title.message })
|
|
463
464
|
] }),
|
|
464
465
|
/* @__PURE__ */ s("div", { className: "col-span-2 space-y-1", children: [
|
|
465
|
-
/* @__PURE__ */ e(
|
|
466
|
-
/* @__PURE__ */ e(
|
|
466
|
+
/* @__PURE__ */ e(x, { htmlFor: "slug", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Slug" }),
|
|
467
|
+
/* @__PURE__ */ e(y, { id: "slug", placeholder: "product-slug", ...n("slug"), className: "h-8 text-sm" }),
|
|
467
468
|
f.slug && /* @__PURE__ */ e("p", { className: "text-destructive text-[11px] leading-none", children: f.slug.message })
|
|
468
469
|
] }),
|
|
469
470
|
/* @__PURE__ */ s("div", { className: "col-span-1 space-y-1", children: [
|
|
470
|
-
/* @__PURE__ */ e(
|
|
471
|
-
/* @__PURE__ */ e(
|
|
471
|
+
/* @__PURE__ */ e(x, { htmlFor: "sku", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "SKU" }),
|
|
472
|
+
/* @__PURE__ */ e(y, { id: "sku", placeholder: "SKU", ...n("sku"), className: "h-8 text-sm font-mono" }),
|
|
472
473
|
f.sku && /* @__PURE__ */ e("p", { className: "text-destructive text-[11px] leading-none", children: f.sku.message })
|
|
473
474
|
] }),
|
|
474
475
|
/* @__PURE__ */ s("div", { className: "col-span-1 space-y-1", children: [
|
|
475
|
-
/* @__PURE__ */ e(
|
|
476
|
-
/* @__PURE__ */ e(
|
|
476
|
+
/* @__PURE__ */ e(x, { htmlFor: "upc_ean", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "UPC / EAN" }),
|
|
477
|
+
/* @__PURE__ */ e(y, { id: "upc_ean", placeholder: "000000000", ...n("upc"), className: "h-8 text-sm font-mono", readOnly: S })
|
|
477
478
|
] })
|
|
478
479
|
] }),
|
|
479
|
-
/* @__PURE__ */ s("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-
|
|
480
|
-
/* @__PURE__ */ s("div", { className: "lg:col-span-
|
|
481
|
-
/* @__PURE__ */ e(
|
|
482
|
-
/* @__PURE__ */ e(
|
|
480
|
+
/* @__PURE__ */ s("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-12 gap-2.5 mt-2", children: [
|
|
481
|
+
/* @__PURE__ */ s("div", { className: `${a ? "lg:col-span-3" : "lg:col-span-4"} col-span-2 space-y-1`, children: [
|
|
482
|
+
/* @__PURE__ */ e(x, { htmlFor: "meta_title", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Meta Title" }),
|
|
483
|
+
/* @__PURE__ */ e(y, { id: "meta_title", ...n("meta_title"), placeholder: "SEO page title (50-60 chars)", className: "h-8 text-sm" })
|
|
484
|
+
] }),
|
|
485
|
+
/* @__PURE__ */ s("div", { className: "lg:col-span-4 col-span-2 space-y-1", children: [
|
|
486
|
+
/* @__PURE__ */ e(x, { htmlFor: "meta_description", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Meta Description" }),
|
|
487
|
+
/* @__PURE__ */ e(y, { id: "meta_description", ...n("meta_description"), placeholder: "SEO description (150-160 chars)", className: "h-8 text-sm" })
|
|
483
488
|
] }),
|
|
484
|
-
/* @__PURE__ */ s("div", { className:
|
|
485
|
-
/* @__PURE__ */ e(
|
|
486
|
-
/* @__PURE__ */ e(
|
|
489
|
+
/* @__PURE__ */ s("div", { className: `${a ? "lg:col-span-3" : "lg:col-span-4"} col-span-2 space-y-1`, children: [
|
|
490
|
+
/* @__PURE__ */ e(x, { htmlFor: "custom_canonical", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Canonical URL (optional)" }),
|
|
491
|
+
/* @__PURE__ */ e(y, { id: "custom_canonical", ...n("custom_canonical"), placeholder: "Blank = self-referencing. Absolute https://… URL or /relative path to override.", className: "h-8 text-sm" })
|
|
487
492
|
] }),
|
|
488
|
-
a && /* @__PURE__ */ s("div", { className: "lg:col-span-
|
|
489
|
-
/* @__PURE__ */ e(
|
|
490
|
-
/* @__PURE__ */ s(le, { onValueChange: (t) =>
|
|
493
|
+
a && /* @__PURE__ */ s("div", { className: "lg:col-span-2 col-span-2 space-y-1", children: [
|
|
494
|
+
/* @__PURE__ */ e(x, { htmlFor: "status", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Status" }),
|
|
495
|
+
/* @__PURE__ */ s(le, { onValueChange: (t) => i("status", t, { shouldDirty: !0 }), value: o("status"), children: [
|
|
491
496
|
/* @__PURE__ */ e(ne, { className: "h-8 text-xs", children: /* @__PURE__ */ e(ce, { placeholder: "Status" }) }),
|
|
492
497
|
/* @__PURE__ */ s(ue, { children: [
|
|
493
498
|
/* @__PURE__ */ e(F, { value: "draft", children: "Draft" }),
|
|
@@ -510,13 +515,13 @@ function Tr({
|
|
|
510
515
|
{
|
|
511
516
|
categories: Ee,
|
|
512
517
|
selectedIds: o("category_ids") || [],
|
|
513
|
-
onChange: (t) =>
|
|
518
|
+
onChange: (t) => i("category_ids", t, { shouldDirty: !0, shouldValidate: !0 })
|
|
514
519
|
}
|
|
515
520
|
)
|
|
516
521
|
}
|
|
517
522
|
),
|
|
518
523
|
/* @__PURE__ */ s("section", { className: "rounded-lg border bg-card p-3 shadow-sm space-y-3", children: [
|
|
519
|
-
|
|
524
|
+
N && /* @__PURE__ */ s("div", { className: "flex items-center justify-between gap-4 flex-wrap border-b border-muted/50 pb-2", children: [
|
|
520
525
|
/* @__PURE__ */ e("div", { className: "flex items-center gap-4", children: /* @__PURE__ */ s("div", { className: "space-y-0.5", children: [
|
|
521
526
|
/* @__PURE__ */ e("h2", { className: "text-sm font-bold tracking-tight", children: "Pricing & Inventory" }),
|
|
522
527
|
/* @__PURE__ */ e("p", { className: "text-[11px] text-muted-foreground leading-none", children: "Manage simple or variant pricing." })
|
|
@@ -525,7 +530,7 @@ function Tr({
|
|
|
525
530
|
/* @__PURE__ */ s("div", { className: "flex items-center gap-2 bg-muted/40 rounded-md px-2.5 py-1.5", children: [
|
|
526
531
|
/* @__PURE__ */ e("span", { className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Stock" }),
|
|
527
532
|
/* @__PURE__ */ e(
|
|
528
|
-
|
|
533
|
+
y,
|
|
529
534
|
{
|
|
530
535
|
id: "stock",
|
|
531
536
|
type: "number",
|
|
@@ -537,18 +542,18 @@ function Tr({
|
|
|
537
542
|
}
|
|
538
543
|
)
|
|
539
544
|
] }),
|
|
540
|
-
S ? /* @__PURE__ */ e(
|
|
545
|
+
S ? /* @__PURE__ */ e(Y, { variant: "secondary", className: "text-[11px] py-0 px-2 h-5", children: "Variant pricing" }) : null
|
|
541
546
|
] })
|
|
542
547
|
] }),
|
|
543
|
-
|
|
548
|
+
N ? /* @__PURE__ */ s("div", { className: "space-y-3", children: [
|
|
544
549
|
/* @__PURE__ */ s("div", { className: "w-full", children: [
|
|
545
550
|
/* @__PURE__ */ e(
|
|
546
551
|
Ie,
|
|
547
552
|
{
|
|
548
553
|
idPrefix: "product",
|
|
549
554
|
currencies: c,
|
|
550
|
-
prices:
|
|
551
|
-
salePrices:
|
|
555
|
+
prices: L.prices,
|
|
556
|
+
salePrices: L.salePrices,
|
|
552
557
|
managedCurrencyCodes: K,
|
|
553
558
|
onPriceChange: we,
|
|
554
559
|
onSalePriceChange: ke,
|
|
@@ -556,12 +561,12 @@ function Tr({
|
|
|
556
561
|
readOnly: S,
|
|
557
562
|
helperText: S ? "Parent prices stay as a fallback, but active variants define the live shopper price." : void 0,
|
|
558
563
|
trailing: /* @__PURE__ */ e(
|
|
559
|
-
|
|
564
|
+
Re,
|
|
560
565
|
{
|
|
561
566
|
idPrefix: "product",
|
|
562
567
|
startAt: o("sale_start_at"),
|
|
563
568
|
endAt: o("sale_end_at"),
|
|
564
|
-
onChange: (t,
|
|
569
|
+
onChange: (t, d) => i(t, d, { shouldDirty: !0, shouldValidate: !0 }),
|
|
565
570
|
error: f.sale_end_at?.message,
|
|
566
571
|
bare: !0
|
|
567
572
|
}
|
|
@@ -587,19 +592,19 @@ function Tr({
|
|
|
587
592
|
)
|
|
588
593
|
] }),
|
|
589
594
|
G && /* @__PURE__ */ e("div", { className: "border-t pt-3", children: /* @__PURE__ */ e(
|
|
590
|
-
|
|
595
|
+
dr,
|
|
591
596
|
{
|
|
592
597
|
globalAttributes: C,
|
|
593
|
-
currentLanguageCode:
|
|
598
|
+
currentLanguageCode: Xe,
|
|
594
599
|
baseSku: o("sku") || "",
|
|
595
600
|
basePrice: M || 0,
|
|
596
|
-
basePrices:
|
|
597
|
-
baseSalePrice: typeof
|
|
601
|
+
basePrices: P,
|
|
602
|
+
baseSalePrice: typeof R == "number" ? R : null,
|
|
598
603
|
baseSalePrices: V,
|
|
599
604
|
currencies: c,
|
|
600
605
|
availableVariantImages: Ge,
|
|
601
606
|
initialVariationAttributes: r?.variation_attributes,
|
|
602
|
-
initialVariants:
|
|
607
|
+
initialVariants: Ye,
|
|
603
608
|
onChange: We
|
|
604
609
|
}
|
|
605
610
|
) })
|
|
@@ -607,27 +612,27 @@ function Tr({
|
|
|
607
612
|
/* @__PURE__ */ s("div", { className: "space-y-4", children: [
|
|
608
613
|
/* @__PURE__ */ s("div", { className: "flex items-end gap-4 w-full", children: [
|
|
609
614
|
/* @__PURE__ */ s("div", { className: "flex-1", children: [
|
|
610
|
-
/* @__PURE__ */ e(
|
|
611
|
-
/* @__PURE__ */ e(
|
|
615
|
+
/* @__PURE__ */ e(x, { htmlFor: "freemius_product_id", className: "text-[11px] uppercase tracking-wider text-muted-foreground font-bold mb-1.5 block", children: "Freemius Product ID" }),
|
|
616
|
+
/* @__PURE__ */ e(y, { id: "freemius_product_id", ...n("freemius_product_id"), className: "h-9" })
|
|
612
617
|
] }),
|
|
613
618
|
/* @__PURE__ */ s("div", { className: "flex-1", children: [
|
|
614
|
-
/* @__PURE__ */ e(
|
|
615
|
-
/* @__PURE__ */ e(
|
|
619
|
+
/* @__PURE__ */ e(x, { htmlFor: "freemius_plan_id", className: "text-[11px] uppercase tracking-wider text-muted-foreground font-bold mb-1.5 block", children: "Freemius Plan ID" }),
|
|
620
|
+
/* @__PURE__ */ e(y, { id: "freemius_plan_id", ...n("freemius_plan_id"), className: "h-9" })
|
|
616
621
|
] }),
|
|
617
|
-
He ? /* @__PURE__ */ e(
|
|
622
|
+
He ? /* @__PURE__ */ e(ir, { productId: o("freemius_product_id") }) : null
|
|
618
623
|
] }),
|
|
619
624
|
/* @__PURE__ */ s("div", { className: "bg-muted/10 border rounded-md overflow-hidden", children: [
|
|
620
625
|
/* @__PURE__ */ s("div", { className: "flex flex-wrap items-center gap-6 bg-muted/20 border-b p-2.5 px-4", children: [
|
|
621
626
|
/* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
|
|
622
627
|
/* @__PURE__ */ e("span", { className: "text-[11px] font-bold uppercase tracking-wider text-muted-foreground", children: "Free Trial" }),
|
|
623
|
-
/* @__PURE__ */ s(
|
|
628
|
+
/* @__PURE__ */ s(Y, { variant: "outline", className: "font-mono text-xs shadow-sm bg-background", children: [
|
|
624
629
|
String(o("trial_period_days") || 0),
|
|
625
630
|
" Days"
|
|
626
631
|
] })
|
|
627
632
|
] }),
|
|
628
633
|
/* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
|
|
629
634
|
/* @__PURE__ */ e("span", { className: "text-[11px] font-bold uppercase tracking-wider text-muted-foreground", children: "Card Required" }),
|
|
630
|
-
/* @__PURE__ */ e(
|
|
635
|
+
/* @__PURE__ */ e(Y, { variant: Ne ? "default" : "secondary", className: "text-xs shadow-sm", children: Ne ? "Yes" : "No" })
|
|
631
636
|
] }),
|
|
632
637
|
/* @__PURE__ */ e("span", { className: "text-[10px] text-muted-foreground ml-auto", children: "Managed in Freemius dashboard" }),
|
|
633
638
|
/* @__PURE__ */ e("input", { type: "hidden", ...n("trial_period_days", { valueAsNumber: !0 }) })
|
|
@@ -638,20 +643,20 @@ function Tr({
|
|
|
638
643
|
{
|
|
639
644
|
idPrefix: "product",
|
|
640
645
|
currencies: c,
|
|
641
|
-
prices:
|
|
642
|
-
salePrices:
|
|
646
|
+
prices: L.prices,
|
|
647
|
+
salePrices: L.salePrices,
|
|
643
648
|
managedCurrencyCodes: K,
|
|
644
649
|
onPriceChange: we,
|
|
645
650
|
onSalePriceChange: ke,
|
|
646
651
|
onAutoFill: Ce,
|
|
647
652
|
readOnly: !0,
|
|
648
653
|
trailing: /* @__PURE__ */ e(
|
|
649
|
-
|
|
654
|
+
Re,
|
|
650
655
|
{
|
|
651
656
|
idPrefix: "product",
|
|
652
657
|
startAt: o("sale_start_at"),
|
|
653
658
|
endAt: o("sale_end_at"),
|
|
654
|
-
onChange: (t,
|
|
659
|
+
onChange: (t, d) => i(t, d, { shouldDirty: !0, shouldValidate: !0 }),
|
|
655
660
|
error: f.sale_end_at?.message,
|
|
656
661
|
bare: !0
|
|
657
662
|
}
|
|
@@ -662,20 +667,20 @@ function Tr({
|
|
|
662
667
|
] })
|
|
663
668
|
] })
|
|
664
669
|
] }),
|
|
665
|
-
|
|
670
|
+
q && /* @__PURE__ */ e("div", { className: "pt-2 border-t", children: q })
|
|
666
671
|
] })
|
|
667
672
|
] }),
|
|
668
673
|
/* @__PURE__ */ e(Q, { title: "Product Description", hideHeader: !0, children: /* @__PURE__ */ e("div", { className: "space-y-2", children: /* @__PURE__ */ s("div", { className: "space-y-1", children: [
|
|
669
|
-
/* @__PURE__ */ e(
|
|
670
|
-
/* @__PURE__ */ e(
|
|
674
|
+
/* @__PURE__ */ e(x, { htmlFor: "short_description", className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Short Description" }),
|
|
675
|
+
/* @__PURE__ */ e(y, { id: "short_description", ...n("short_description"), placeholder: "Brief summary for product cards...", className: "h-8 text-sm" })
|
|
671
676
|
] }) }) }),
|
|
672
677
|
/* @__PURE__ */ s(Q, { title: "Media Gallery", description: "Drag to reorder. First image is the hero.", children: [
|
|
673
678
|
/* @__PURE__ */ e(
|
|
674
679
|
ar,
|
|
675
680
|
{
|
|
676
|
-
initialMedia:
|
|
681
|
+
initialMedia: ie,
|
|
677
682
|
onUpdate: Qe,
|
|
678
|
-
mediaPickerNode:
|
|
683
|
+
mediaPickerNode: b
|
|
679
684
|
}
|
|
680
685
|
),
|
|
681
686
|
/* @__PURE__ */ e("input", { type: "hidden", ...n("product_media") })
|
|
@@ -683,7 +688,7 @@ function Tr({
|
|
|
683
688
|
!a && /* @__PURE__ */ s("div", { className: "rounded-lg border bg-card p-3 px-4 shadow-sm flex items-center justify-between gap-3 flex-wrap", children: [
|
|
684
689
|
/* @__PURE__ */ s("div", { className: "flex items-center gap-2", children: [
|
|
685
690
|
/* @__PURE__ */ e("span", { className: "text-xs uppercase font-bold text-muted-foreground tracking-wider leading-none", children: "Status" }),
|
|
686
|
-
/* @__PURE__ */ s(le, { onValueChange: (t) =>
|
|
691
|
+
/* @__PURE__ */ s(le, { onValueChange: (t) => i("status", t), value: o("status"), children: [
|
|
687
692
|
/* @__PURE__ */ e(ne, { className: "h-8 w-[110px] text-sm", children: /* @__PURE__ */ e(ce, { placeholder: "Status" }) }),
|
|
688
693
|
/* @__PURE__ */ s(ue, { children: [
|
|
689
694
|
/* @__PURE__ */ e(F, { value: "draft", children: "Draft" }),
|