@nextblock-cms/ecom 0.10.9 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/ProductCard.cjs.js +1 -1
- package/lib/components/ProductCard.es.js +74 -50
- package/lib/components/ProductDetailsLayout.cjs.js +1 -1
- package/lib/components/ProductDetailsLayout.d.ts +1 -0
- package/lib/components/ProductDetailsLayout.es.js +160 -128
- package/lib/pages/cms/products/actions.d.ts +4 -0
- package/lib/product-actions.cjs.js +3 -3
- package/lib/product-actions.d.ts +9 -1
- package/lib/product-actions.es.js +7 -7
- package/lib/shared-inventory.d.ts +1 -1
- package/lib/types.d.ts +2 -0
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),k=require("./AddToCartButton.cjs.js"),a=require("@nextblock-cms/utils"),b=require("next/link"),A=require("../CurrencyProvider.cjs.js"),c=require("../currency.cjs.js"),q=require("../trials.cjs.js"),R=require("../variation-utils.cjs.js"),T=({product:e,className:j})=>{const{activeCurrencyCode:l,currencies:i}=A.useCurrency(),t=c.resolvePriceRangeForCurrency({entries:e.variants?.length?e.variants:e.product_variants?.length?e.product_variants:[],currencyCode:l,currencies:i}),u=!!(e.has_variants&&t),n=c.resolveEffectivePriceForCurrency({prices:e.prices,salePrices:e.sale_prices,fallbackPrice:e.price,fallbackSalePrice:e.sale_price,saleStartAt:e.sale_start_at,saleEndAt:e.sale_end_at,scheduledPrice:e.scheduled_price,scheduledPrices:e.scheduled_prices,scheduledPriceAt:e.scheduled_price_at,currencyCode:l,currencies:i}),P=u&&t?t.min===t.max?a.formatPrice(t.min,l):`${a.formatPrice(t.min,l)} - ${a.formatPrice(t.max,l)}`:a.formatPrice(n.sale_price??n.price,l),y=e.variants?.length?e.variants:e.product_variants?.length?e.product_variants:[],N=u?y.some(s=>c.resolveEffectivePriceForCurrency({prices:s.prices,salePrices:s.sale_prices,fallbackPrice:s.price,fallbackSalePrice:s.sale_price,saleStartAt:s.sale_start_at,saleEndAt:s.sale_end_at,scheduledPrice:s.scheduled_price,scheduledPrices:s.scheduled_prices,scheduledPriceAt:s.scheduled_price_at,currencyCode:l,currencies:i}).sale_price!=null):n.sale_price!=null,{t:o,lang:C}=a.useTranslations(),g=o("ecommerce.on_sale"),w=g==="ecommerce.on_sale"?"On Sale":g,h=q.getTrialSummary(e),m=e.freemius_plans?.[0]?.freemius_pricing?.[0],d=i.find(s=>s.is_default)?.code||"USD",_=m?.override_monthly_price??m?.api_monthly_price,p=m?.override_annual_price??m?.api_annual_price,x=typeof _=="number"?c.resolvePriceForCurrency({prices:{[d]:a.majorUnitAmountToMinor(_,d)},currencyCode:l,currencies:i}):null,f=typeof p=="number"?c.resolvePriceForCurrency({prices:{[d]:a.majorUnitAmountToMinor(p,d)},currencyCode:l,currencies:i}):null;return r.jsxs("div",{className:a.cn("group relative flex flex-col overflow-hidden rounded-lg border bg-card text-card-foreground shadow-sm transition-all hover:shadow-md",j),children:[r.jsxs(b,{href:`/product/${e.slug}`,className:"relative aspect-square overflow-hidden bg-muted",children:[N&&r.jsx("span",{className:"absolute left-3 top-3 z-10 rounded-full bg-destructive px-2.5 py-1 text-[10px] font-bold uppercase tracking-wider text-destructive-foreground shadow-sm",children:w}),e.image_url?r.jsx("img",{src:e.image_url,alt:e.title,className:"h-full w-full object-cover object-center transition-transform duration-300 group-hover:scale-105"}):r.jsx("div",{className:"flex h-full items-center justify-center text-muted-foreground",children:"No Image"})]}),r.jsxs("div",{className:"flex flex-1 flex-col p-4",children:[e.categories&&e.categories.length>0&&r.jsx("div",{className:"text-[10px] font-bold uppercase tracking-widest text-amber-600 dark:text-amber-400 mb-1",children:e.categories.map(s=>R.resolveTranslatedText(s.name,s.name_translations,C)).join(" • ")}),r.jsx(b,{href:`/product/${e.slug}`,className:"mb-2",children:r.jsx("h3",{className:"line-clamp-1 text-lg font-medium text-foreground group-hover:underline",children:e.title})}),r.jsx("div",{className:"flex items-center gap-1 mb-2 mt-0.5 text-xs text-muted-foreground min-h-[1.25rem] select-none","aria-label":`Rating: ${e.average_rating??0} out of 5 stars`,children:e.total_reviews&&e.total_reviews>0?r.jsxs(r.Fragment,{children:[r.jsx("div",{className:"flex items-center text-amber-500 mr-1",children:Array.from({length:5}).map((s,v)=>{const S=e.average_rating??0;return r.jsx("svg",{className:a.cn("h-3.5 w-3.5 fill-current",v<Math.round(S)?"text-amber-500":"text-slate-200 dark:text-slate-800"),viewBox:"0 0 20 20",fill:"currentColor",children:r.jsx("path",{d:"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"})},v)})}),r.jsx("span",{className:"font-semibold text-slate-700 dark:text-slate-300",children:Number(e.average_rating).toFixed(1)}),r.jsxs("span",{className:"ml-0.5",children:["(",e.total_reviews,")"]})]}):r.jsx("span",{className:"text-slate-400 dark:text-slate-600",children:o("reviews.no_reviews")})}),r.jsx("div",{className:"mb-4",children:e.product_type==="digital"&&(x||f)?r.jsxs("div",{className:"flex flex-wrap items-baseline gap-x-3 gap-y-1",children:[x&&r.jsxs("div",{className:"flex items-baseline gap-0.5",children:[r.jsx("span",{className:"text-xl font-bold text-primary",children:a.formatPrice(x.price,l)}),r.jsxs("span",{className:"text-xs font-medium text-muted-foreground lowercase",children:["/ ",o("ecommerce.month")]})]}),f&&r.jsxs("div",{className:"flex items-baseline gap-0.5",children:[r.jsx("span",{className:a.cn("font-bold text-primary",x?"text-lg":"text-xl"),children:a.formatPrice(f.price,l)}),r.jsxs("span",{className:"text-xs font-medium text-muted-foreground lowercase",children:["/ ",o("ecommerce.year")]})]})]}):r.jsxs("div",{className:"flex items-baseline gap-2",children:[r.jsx("span",{className:"text-xl font-bold text-primary",children:P}),!u&&n.sale_price&&r.jsx("span",{className:"text-sm text-muted-foreground line-through",children:a.formatPrice(n.price,l)})]})}),h&&r.jsxs("div",{className:"mb-4 rounded-md border border-emerald-200 bg-emerald-50 px-3 py-2 text-xs text-emerald-900",children:[r.jsx("div",{className:"font-semibold",children:h.label}),r.jsx("div",{className:"text-emerald-700",children:h.paymentRequirementLabel})]}),r.jsx("div",{className:"mt-auto",children:r.jsx(k.AddToCartButton,{product:{...e,price:e.price,prices:e.prices,sale_price:e.sale_price,sale_prices:e.sale_prices},className:"w-full"})})]})]})};exports.ProductCard=T;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsxs as s, jsx as
|
|
3
|
-
import { AddToCartButton as
|
|
4
|
-
import { formatPrice as
|
|
2
|
+
import { jsxs as s, jsx as a, Fragment as T } from "react/jsx-runtime";
|
|
3
|
+
import { AddToCartButton as F } from "./AddToCartButton.es.js";
|
|
4
|
+
import { formatPrice as i, useTranslations as M, majorUnitAmountToMinor as N, cn as p } from "@nextblock-cms/utils";
|
|
5
5
|
import y from "next/link";
|
|
6
|
-
import { useCurrency as
|
|
7
|
-
import { resolvePriceRangeForCurrency as E, resolveEffectivePriceForCurrency as
|
|
8
|
-
import { getTrialSummary as
|
|
9
|
-
import { resolveTranslatedText as
|
|
10
|
-
const
|
|
11
|
-
const { activeCurrencyCode: l, currencies: n } =
|
|
6
|
+
import { useCurrency as $ } from "../CurrencyProvider.es.js";
|
|
7
|
+
import { resolvePriceRangeForCurrency as E, resolveEffectivePriceForCurrency as P, resolvePriceForCurrency as w } from "../currency.es.js";
|
|
8
|
+
import { getTrialSummary as B } from "../trials.es.js";
|
|
9
|
+
import { resolveTranslatedText as q } from "../variation-utils.es.js";
|
|
10
|
+
const K = ({ product: e, className: C }) => {
|
|
11
|
+
const { activeCurrencyCode: l, currencies: n } = $(), t = E({
|
|
12
12
|
entries: e.variants?.length ? e.variants : e.product_variants?.length ? e.product_variants : [],
|
|
13
13
|
currencyCode: l,
|
|
14
14
|
currencies: n
|
|
15
|
-
}), f = !!(e.has_variants &&
|
|
15
|
+
}), f = !!(e.has_variants && t), c = P({
|
|
16
16
|
prices: e.prices,
|
|
17
17
|
salePrices: e.sale_prices,
|
|
18
18
|
fallbackPrice: e.price,
|
|
@@ -24,82 +24,106 @@ const G = ({ product: e, className: C }) => {
|
|
|
24
24
|
scheduledPriceAt: e.scheduled_price_at,
|
|
25
25
|
currencyCode: l,
|
|
26
26
|
currencies: n
|
|
27
|
-
}),
|
|
28
|
-
|
|
27
|
+
}), S = f && t ? t.min === t.max ? i(t.min, l) : `${i(t.min, l)} - ${i(
|
|
28
|
+
t.max,
|
|
29
29
|
l
|
|
30
|
-
)}` : c
|
|
31
|
-
(
|
|
32
|
-
prices:
|
|
33
|
-
salePrices:
|
|
34
|
-
fallbackPrice:
|
|
35
|
-
fallbackSalePrice:
|
|
36
|
-
saleStartAt:
|
|
37
|
-
saleEndAt:
|
|
38
|
-
scheduledPrice:
|
|
39
|
-
scheduledPrices:
|
|
40
|
-
scheduledPriceAt:
|
|
30
|
+
)}` : i(c.sale_price ?? c.price, l), k = e.variants?.length ? e.variants : e.product_variants?.length ? e.product_variants : [], j = f ? k.some(
|
|
31
|
+
(r) => P({
|
|
32
|
+
prices: r.prices,
|
|
33
|
+
salePrices: r.sale_prices,
|
|
34
|
+
fallbackPrice: r.price,
|
|
35
|
+
fallbackSalePrice: r.sale_price,
|
|
36
|
+
saleStartAt: r.sale_start_at,
|
|
37
|
+
saleEndAt: r.sale_end_at,
|
|
38
|
+
scheduledPrice: r.scheduled_price,
|
|
39
|
+
scheduledPrices: r.scheduled_prices,
|
|
40
|
+
scheduledPriceAt: r.scheduled_price_at,
|
|
41
41
|
currencyCode: l,
|
|
42
42
|
currencies: n
|
|
43
43
|
}).sale_price != null
|
|
44
|
-
) :
|
|
44
|
+
) : c.sale_price != null, { t: o, lang: A } = M(), g = o("ecommerce.on_sale"), R = g === "ecommerce.on_sale" ? "On Sale" : g, x = B(e), m = e.freemius_plans?.[0]?.freemius_pricing?.[0], d = n.find((r) => r.is_default)?.code || "USD", _ = m?.override_monthly_price ?? m?.api_monthly_price, v = m?.override_annual_price ?? m?.api_annual_price, h = typeof _ == "number" ? w({
|
|
45
45
|
prices: {
|
|
46
|
-
[
|
|
46
|
+
[d]: N(
|
|
47
47
|
_,
|
|
48
|
-
|
|
48
|
+
d
|
|
49
49
|
)
|
|
50
50
|
},
|
|
51
51
|
currencyCode: l,
|
|
52
52
|
currencies: n
|
|
53
|
-
}) : null, u = typeof
|
|
53
|
+
}) : null, u = typeof v == "number" ? w({
|
|
54
54
|
prices: {
|
|
55
|
-
[
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
[d]: N(
|
|
56
|
+
v,
|
|
57
|
+
d
|
|
58
58
|
)
|
|
59
59
|
},
|
|
60
60
|
currencyCode: l,
|
|
61
61
|
currencies: n
|
|
62
62
|
}) : null;
|
|
63
|
-
return /* @__PURE__ */ s("div", { className:
|
|
63
|
+
return /* @__PURE__ */ s("div", { className: p("group relative flex flex-col overflow-hidden rounded-lg border bg-card text-card-foreground shadow-sm transition-all hover:shadow-md", C), children: [
|
|
64
64
|
/* @__PURE__ */ s(y, { href: `/product/${e.slug}`, className: "relative aspect-square overflow-hidden bg-muted", children: [
|
|
65
|
-
j && /* @__PURE__ */
|
|
66
|
-
e.image_url ? /* @__PURE__ */
|
|
65
|
+
j && /* @__PURE__ */ a("span", { className: "absolute left-3 top-3 z-10 rounded-full bg-destructive px-2.5 py-1 text-[10px] font-bold uppercase tracking-wider text-destructive-foreground shadow-sm", children: R }),
|
|
66
|
+
e.image_url ? /* @__PURE__ */ a(
|
|
67
67
|
"img",
|
|
68
68
|
{
|
|
69
69
|
src: e.image_url,
|
|
70
70
|
alt: e.title,
|
|
71
71
|
className: "h-full w-full object-cover object-center transition-transform duration-300 group-hover:scale-105"
|
|
72
72
|
}
|
|
73
|
-
) : /* @__PURE__ */
|
|
73
|
+
) : /* @__PURE__ */ a("div", { className: "flex h-full items-center justify-center text-muted-foreground", children: "No Image" })
|
|
74
74
|
] }),
|
|
75
75
|
/* @__PURE__ */ s("div", { className: "flex flex-1 flex-col p-4", children: [
|
|
76
|
-
e.categories && e.categories.length > 0 && /* @__PURE__ */
|
|
77
|
-
/* @__PURE__ */
|
|
78
|
-
/* @__PURE__ */
|
|
79
|
-
|
|
80
|
-
|
|
76
|
+
e.categories && e.categories.length > 0 && /* @__PURE__ */ a("div", { className: "text-[10px] font-bold uppercase tracking-widest text-amber-600 dark:text-amber-400 mb-1", children: e.categories.map((r) => q(r.name, r.name_translations, A)).join(" • ") }),
|
|
77
|
+
/* @__PURE__ */ a(y, { href: `/product/${e.slug}`, className: "mb-2", children: /* @__PURE__ */ a("h3", { className: "line-clamp-1 text-lg font-medium text-foreground group-hover:underline", children: e.title }) }),
|
|
78
|
+
/* @__PURE__ */ a("div", { className: "flex items-center gap-1 mb-2 mt-0.5 text-xs text-muted-foreground min-h-[1.25rem] select-none", "aria-label": `Rating: ${e.average_rating ?? 0} out of 5 stars`, children: e.total_reviews && e.total_reviews > 0 ? /* @__PURE__ */ s(T, { children: [
|
|
79
|
+
/* @__PURE__ */ a("div", { className: "flex items-center text-amber-500 mr-1", children: Array.from({ length: 5 }).map((r, b) => {
|
|
80
|
+
const L = e.average_rating ?? 0;
|
|
81
|
+
return /* @__PURE__ */ a(
|
|
82
|
+
"svg",
|
|
83
|
+
{
|
|
84
|
+
className: p(
|
|
85
|
+
"h-3.5 w-3.5 fill-current",
|
|
86
|
+
b < Math.round(L) ? "text-amber-500" : "text-slate-200 dark:text-slate-800"
|
|
87
|
+
),
|
|
88
|
+
viewBox: "0 0 20 20",
|
|
89
|
+
fill: "currentColor",
|
|
90
|
+
children: /* @__PURE__ */ a("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" })
|
|
91
|
+
},
|
|
92
|
+
b
|
|
93
|
+
);
|
|
94
|
+
}) }),
|
|
95
|
+
/* @__PURE__ */ a("span", { className: "font-semibold text-slate-700 dark:text-slate-300", children: Number(e.average_rating).toFixed(1) }),
|
|
96
|
+
/* @__PURE__ */ s("span", { className: "ml-0.5", children: [
|
|
97
|
+
"(",
|
|
98
|
+
e.total_reviews,
|
|
99
|
+
")"
|
|
100
|
+
] })
|
|
101
|
+
] }) : /* @__PURE__ */ a("span", { className: "text-slate-400 dark:text-slate-600", children: o("reviews.no_reviews") }) }),
|
|
102
|
+
/* @__PURE__ */ a("div", { className: "mb-4", children: e.product_type === "digital" && (h || u) ? /* @__PURE__ */ s("div", { className: "flex flex-wrap items-baseline gap-x-3 gap-y-1", children: [
|
|
103
|
+
h && /* @__PURE__ */ s("div", { className: "flex items-baseline gap-0.5", children: [
|
|
104
|
+
/* @__PURE__ */ a("span", { className: "text-xl font-bold text-primary", children: i(h.price, l) }),
|
|
81
105
|
/* @__PURE__ */ s("span", { className: "text-xs font-medium text-muted-foreground lowercase", children: [
|
|
82
106
|
"/ ",
|
|
83
|
-
|
|
107
|
+
o("ecommerce.month")
|
|
84
108
|
] })
|
|
85
109
|
] }),
|
|
86
110
|
u && /* @__PURE__ */ s("div", { className: "flex items-baseline gap-0.5", children: [
|
|
87
|
-
/* @__PURE__ */
|
|
111
|
+
/* @__PURE__ */ a("span", { className: p("font-bold text-primary", h ? "text-lg" : "text-xl"), children: i(u.price, l) }),
|
|
88
112
|
/* @__PURE__ */ s("span", { className: "text-xs font-medium text-muted-foreground lowercase", children: [
|
|
89
113
|
"/ ",
|
|
90
|
-
|
|
114
|
+
o("ecommerce.year")
|
|
91
115
|
] })
|
|
92
116
|
] })
|
|
93
117
|
] }) : /* @__PURE__ */ s("div", { className: "flex items-baseline gap-2", children: [
|
|
94
|
-
/* @__PURE__ */
|
|
95
|
-
!f &&
|
|
118
|
+
/* @__PURE__ */ a("span", { className: "text-xl font-bold text-primary", children: S }),
|
|
119
|
+
!f && c.sale_price && /* @__PURE__ */ a("span", { className: "text-sm text-muted-foreground line-through", children: i(c.price, l) })
|
|
96
120
|
] }) }),
|
|
97
|
-
|
|
98
|
-
/* @__PURE__ */
|
|
99
|
-
/* @__PURE__ */
|
|
121
|
+
x && /* @__PURE__ */ s("div", { className: "mb-4 rounded-md border border-emerald-200 bg-emerald-50 px-3 py-2 text-xs text-emerald-900", children: [
|
|
122
|
+
/* @__PURE__ */ a("div", { className: "font-semibold", children: x.label }),
|
|
123
|
+
/* @__PURE__ */ a("div", { className: "text-emerald-700", children: x.paymentRequirementLabel })
|
|
100
124
|
] }),
|
|
101
|
-
/* @__PURE__ */
|
|
102
|
-
|
|
125
|
+
/* @__PURE__ */ a("div", { className: "mt-auto", children: /* @__PURE__ */ a(
|
|
126
|
+
F,
|
|
103
127
|
{
|
|
104
128
|
product: {
|
|
105
129
|
...e,
|
|
@@ -115,5 +139,5 @@ const G = ({ product: e, className: C }) => {
|
|
|
115
139
|
] });
|
|
116
140
|
};
|
|
117
141
|
export {
|
|
118
|
-
|
|
142
|
+
K as ProductCard
|
|
119
143
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),m=require("react"),R=require("lucide-react"),T=require("@nextblock-cms/ui/badge"),z=require("@nextblock-cms/ui/button"),W=require("@nextblock-cms/ui/label"),H=require("@nextblock-cms/ui/separator"),q=require("@nextblock-cms/utils"),Q=require("../product-context.cjs.js"),Y=require("./ProductGallery.cjs.js"),Z=require("./AddToCartButton.cjs.js"),ee=require("./SubscriptionSelector.cjs.js"),te=require("./SimpleTiptapRenderer.cjs.js"),h=require("../variation-utils.cjs.js"),se=require("../CurrencyProvider.cjs.js"),$=require("../currency.cjs.js"),re=require("../types.cjs.js"),ae=require("../trials.cjs.js");function I(l,v,t,o){const y={kind:"product-field",field:v,input:t,label:o},p=typeof window<"u"?window.location.origin:process.env.NEXT_PUBLIC_URL||process.env.TARGET_URL||(process.env.VERCEL_URL?`https://${process.env.VERCEL_URL}`:"")||"http://localhost:3000";let x=(typeof window<"u"?window.location.origin:process.env.NEXT_PUBLIC_URL||process.env.TARGET_URL||(process.env.VERCEL_URL?`https://${process.env.VERCEL_URL}`:"")||"http://localhost:3000").replace(/\/+$/,"");try{(x.startsWith("http://")||x.startsWith("https://"))&&(x=new URL(x).hostname)}catch{}const k=process.env.NEXTBLOCK_VERCEL_PROJECT_ID||process.env.VERCEL_PROJECT_ID,w=process.env.NEXTBLOCK_VERCEL_WORKSPACE_ID||process.env.VERCEL_ORG_ID,n={origin:x,editUrl:`${p}/cms/products/${l.id}/edit`,data:{parentType:"product",parentId:l.id,slug:l.slug,languageId:l.language_id,draftId:null,target:y}};return k&&(n.projectId=k),w&&(n.workspaceId=w),{"data-vercel-edit-info":JSON.stringify(n),"data-vercel-edit-target":JSON.stringify(y),"data-nextblock-visual-edit":`product:${v}`}}const ie=({visualEditingEnabled:l=!1,descriptionNode:v})=>{const t=Q.useProduct(),{t:o,lang:y}=q.useTranslations(),{activeCurrencyCode:p,currencies:P}=se.useCurrency(),x=l?I(t,"title","plain-text","Product title"):void 0,k=l?I(t,"short_description","plain-text","Short description"):void 0,w=l?I(t,"description_json","tiptap","Product description"):void 0,n=(r,u,i)=>{const B=o(r,i);return B===r?u:B},C=t.images&&t.images.length>0?t.images:t.image_url?[{url:t.image_url,alt:t.title}]:[],b=t.custom_props?.provider==="freemius"||re.isDigitalProduct(t),A=ae.getTrialSummary(t),a=!b&&!!(t.has_variants&&t.attributes?.length&&t.variants?.length),g=t.attributes||[],d=t.variants||[],[_,E]=m.useState(()=>h.chooseInitialVariantSelections(g,d)),[S,L]=m.useState(1);m.useEffect(()=>{L(1)},[t.id]),m.useEffect(()=>{a&&E(h.chooseInitialVariantSelections(g,d))},[g,a,t.id,d]);const f=m.useMemo(()=>a?h.normalizeSelectionsToAvailableVariants(g,d,_):_,[g,a,_,d]);m.useEffect(()=>{JSON.stringify(f)!==JSON.stringify(_)&&E(f)},[f,_]);const s=m.useMemo(()=>a?h.findMatchingVariant(d,f):null,[a,f,d]),V=$.resolveEffectivePriceForCurrency({prices:t.prices,salePrices:t.sale_prices,fallbackPrice:t.price,fallbackSalePrice:t.sale_price,saleStartAt:t.sale_start_at,saleEndAt:t.sale_end_at,scheduledPrice:t.scheduled_price,scheduledPrices:t.scheduled_prices,scheduledPriceAt:t.scheduled_price_at,currencyCode:p,currencies:P}),O=a&&s?$.resolveEffectivePriceForCurrency({prices:s.prices,salePrices:s.sale_prices,fallbackPrice:s.price,fallbackSalePrice:s.sale_price,saleStartAt:s.sale_start_at,saleEndAt:s.sale_end_at,scheduledPrice:s.scheduled_price,scheduledPrices:s.scheduled_prices,scheduledPriceAt:s.scheduled_price_at,currencyCode:p,currencies:P}):null,j=O?.price??V.price,N=O?.sale_price??V.sale_price,c=a?s?.stock_quantity??0:t.stock??0,D=m.useMemo(()=>{if(!s?.image_url)return C;const r={url:s.image_url,alt:`${t.title} ${s.label}`},u=C.filter(i=>i.url!==s.image_url);return[r,...u]},[C,t.title,s]),M=typeof N=="number"&&j>0?Math.round((j-N)/j*100):0,F=a&&s?{...t,sku:s.sku,price:s.price,prices:s.prices,sale_price:typeof s.sale_price=="number"?s.sale_price:null,sale_prices:s.sale_prices,image_url:s.image_url||t.image_url,stock:s.stock_quantity,variant_id:s.id,variant_label:s.label,selected_options:s.selected_options,currency_code:p}:{...t,currency_code:p},J=(r,u)=>{E(i=>h.normalizeSelectionsToAvailableVariants(g,d,{...i,[r]:u}))},G=n("ecommerce.in_stock",`${c} in stock`,{count:String(c)}),U=n("ecommerce.out_of_stock","Out of stock"),K=n("ecommerce.select_options","Select Options"),X=n("ecommerce.variant_selection_required","Select one term from every dropdown to resolve a variation.");return e.jsxs("div",{className:"w-full animate-in fade-in slide-in-from-bottom-4 duration-700 ease-out",children:[e.jsx("div",{className:"container mx-auto px-4 md:px-6 py-12",children:e.jsxs("div",{className:"grid gap-12 lg:grid-cols-[2fr_3fr] items-start",children:[e.jsx("div",{className:"w-full max-w-2xl mx-auto lg:max-w-none",children:e.jsx(Y.ProductGallery,{images:D,className:"w-full"})}),e.jsxs("div",{className:"flex flex-col gap-4 pb-2 max-w-xl mx-auto lg:mx-0 lg:max-w-none",children:[e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("h1",{className:"text-3xl sm:text-4xl lg:text-5xl font-extrabold tracking-tight text-foreground leading-[1.1] lg:mt-0",...x,children:t.title}),t.categories&&t.categories.length>0&&e.jsx("div",{className:"flex flex-wrap items-center gap-1.5 text-xs font-bold uppercase tracking-widest text-amber-600 dark:text-amber-400",children:t.categories.map((r,u)=>{const i=h.resolveTranslatedText(r.name,r.name_translations,y);return e.jsxs(m.Fragment,{children:[u>0&&e.jsx("span",{className:"text-muted-foreground/30",children:"•"}),e.jsx("span",{children:i})]},r.id)})}),e.jsx("div",{className:"prose prose-neutral dark:prose-invert max-w-none text-muted-foreground leading-relaxed text-left",...k,children:t.short_description?e.jsx("div",{className:"text-lg mb-4 leading-relaxed",dangerouslySetInnerHTML:{__html:t.short_description}}):l?e.jsx("p",{className:"text-lg mb-4 italic text-muted-foreground",children:"Add a short product description."}):null}),e.jsxs("div",{className:"flex items-center gap-3",children:[typeof N=="number"&&e.jsx(T.Badge,{variant:"destructive",className:"px-2.5 py-1 text-xs font-bold uppercase tracking-wide animate-pulse shadow-sm",children:o("ecommerce.sale_badge",{percent:String(M)})}),!b&&c>0&&c<10&&e.jsx(T.Badge,{variant:"outline",className:"text-amber-600 border-amber-200 bg-amber-50",children:o("ecommerce.low_stock",{count:String(c)})}),A&&e.jsx(T.Badge,{variant:"secondary",className:"border border-emerald-200 bg-emerald-50 text-emerald-800",children:A.label})]})]})}),e.jsxs("div",{className:"p-5 rounded-2xl bg-card/60 border border-border/80 shadow-md backdrop-blur-md space-y-4",children:[b?e.jsx(ee.SubscriptionSelector,{product:t}):e.jsxs("div",{className:"space-y-3.5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("span",{className:"text-[10px] font-bold text-muted-foreground uppercase tracking-widest",children:n("ecommerce.price","Price")}),e.jsxs("div",{className:"flex items-baseline gap-2.5",children:[e.jsx("span",{className:"text-3xl font-extrabold text-foreground",children:q.formatPrice(N??j,p)}),typeof N=="number"&&e.jsx("span",{className:"text-lg text-muted-foreground line-through decoration-destructive/20 decoration-1",children:q.formatPrice(j,p)})]})]}),!b&&(s||!a)&&e.jsxs("div",{className:"text-right space-y-1",children:[e.jsxs("span",{className:"text-[10px] font-bold text-muted-foreground uppercase tracking-widest block",children:[!a&&t.sku&&e.jsxs("span",{className:"mr-2 font-normal lowercase normal-case text-muted-foreground/70",children:["SKU: ",t.sku]}),n("ecommerce.status","Status")]}),e.jsx("div",{className:(c??0)>0?"text-emerald-600 dark:text-emerald-400 font-semibold text-sm":"text-destructive font-semibold text-sm",children:(c??0)>0?G:U})]})]}),a&&e.jsx("div",{className:"space-y-3",children:e.jsx("div",{className:"grid gap-3 sm:grid-cols-2",children:g.map(r=>{const u=h.getAvailableTermIdsForAttribute(d,r.id,f);return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(W.Label,{htmlFor:`attribute-${r.id}`,className:"text-[11px] font-semibold text-muted-foreground uppercase tracking-wider",children:r.name}),s?.sku&&e.jsx("span",{className:"text-[10px] text-muted-foreground font-mono",children:s.sku})]}),e.jsx("select",{id:`attribute-${r.id}`,className:"flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",value:f[r.id]||"",onChange:i=>J(r.id,i.target.value),children:r.terms.map(i=>e.jsx("option",{value:i.id,disabled:!u.has(i.id),children:i.value},i.id))})]},r.id)})})}),a&&!s&&e.jsx("p",{className:"text-xs text-muted-foreground italic pt-1",children:X}),e.jsxs("div",{className:"flex items-center gap-3 pt-1",children:[!b&&(c??0)>0&&e.jsxs("div",{className:"flex items-center border rounded-lg h-12 bg-background border-input select-none",children:[e.jsx("button",{type:"button",onClick:()=>L(r=>Math.max(1,r-1)),className:"px-3 h-full flex items-center justify-center text-muted-foreground hover:text-foreground active:scale-95 transition-all text-lg font-medium",disabled:S<=1,children:"-"}),e.jsx("span",{className:"w-8 text-center text-sm font-semibold",children:S}),e.jsx("button",{type:"button",onClick:()=>L(r=>c!==null&&r>=c?r:r+1),className:"px-3 h-full flex items-center justify-center text-muted-foreground hover:text-foreground active:scale-95 transition-all text-lg font-medium",disabled:c!==null&&S>=c,children:"+"})]}),a&&(!s||(c??0)<=0)?e.jsx(z.Button,{disabled:!0,className:"flex-1 h-12 text-md font-bold shadow-md",children:s?U:K}):e.jsx(Z.AddToCartButton,{product:F,quantity:S,className:"flex-1 h-12 text-md font-bold shadow-md transition-all hover:shadow-lg active:scale-[0.98]"})]})]}),e.jsx(H.Separator,{className:"opacity-60 my-0.5"}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center text-[11px] font-medium text-muted-foreground pt-1",children:[e.jsx("div",{className:"flex items-center justify-center gap-2",children:b?e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(R.Download,{className:"h-3.5 w-3.5"}),o("ecommerce.instant_digital_delivery")]}):e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(R.Package,{className:"h-3.5 w-3.5"}),o("ecommerce.free_shipping")]})}),e.jsx("div",{className:"flex items-center justify-center gap-2",children:e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(R.ShieldCheck,{className:"h-3.5 w-3.5"}),o("ecommerce.secure_checkout")]})})]})]})]})]})}),e.jsx("div",{className:"min-w-0 w-full",...v?void 0:w,children:v||(t.description_json?e.jsx("div",{className:"container mx-auto px-4 md:px-6 pb-12 prose prose-neutral dark:prose-invert max-w-none leading-relaxed",children:e.jsx(te.SimpleTiptapRenderer,{content:t.description_json})}):e.jsx("div",{className:"container mx-auto px-4 md:px-6 pb-12",children:e.jsx("p",{className:"italic text-sm text-muted-foreground",children:o("ecommerce.no_description")})}))})]})};exports.ProductDetailsLayout=ie;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),u=require("react"),q=require("lucide-react"),A=require("@nextblock-cms/ui/badge"),W=require("@nextblock-cms/ui/button"),H=require("@nextblock-cms/ui/label"),Q=require("@nextblock-cms/ui/separator"),C=require("@nextblock-cms/utils"),Y=require("../product-context.cjs.js"),Z=require("./ProductGallery.cjs.js"),ee=require("./AddToCartButton.cjs.js"),te=require("./SubscriptionSelector.cjs.js"),se=require("./SimpleTiptapRenderer.cjs.js"),h=require("../variation-utils.cjs.js"),re=require("../CurrencyProvider.cjs.js"),M=require("../currency.cjs.js"),ae=require("../types.cjs.js"),ie=require("../trials.cjs.js");function I(o,f,w,t){const c={kind:"product-field",field:f,input:w,label:t},E=typeof window<"u"?window.location.origin:process.env.NEXT_PUBLIC_URL||process.env.TARGET_URL||(process.env.VERCEL_URL?`https://${process.env.VERCEL_URL}`:"")||"http://localhost:3000";let m=(typeof window<"u"?window.location.origin:process.env.NEXT_PUBLIC_URL||process.env.TARGET_URL||(process.env.VERCEL_URL?`https://${process.env.VERCEL_URL}`:"")||"http://localhost:3000").replace(/\/+$/,"");try{(m.startsWith("http://")||m.startsWith("https://"))&&(m=new URL(m).hostname)}catch{}const k=process.env.NEXTBLOCK_VERCEL_PROJECT_ID||process.env.VERCEL_PROJECT_ID,S=process.env.NEXTBLOCK_VERCEL_WORKSPACE_ID||process.env.VERCEL_ORG_ID,b={origin:m,editUrl:`${E}/cms/products/${o.id}/edit`,data:{parentType:"product",parentId:o.id,slug:o.slug,languageId:o.language_id,draftId:null,target:c}};return k&&(b.projectId=k),S&&(b.workspaceId=S),{"data-vercel-edit-info":JSON.stringify(b),"data-vercel-edit-target":JSON.stringify(c),"data-nextblock-visual-edit":`product:${f}`}}const ce=({visualEditingEnabled:o=!1,descriptionNode:f,reviewsNode:w})=>{const t=Y.useProduct(),{t:c,lang:E}=C.useTranslations(),{activeCurrencyCode:p,currencies:m}=re.useCurrency(),k=o?I(t,"title","plain-text","Product title"):void 0,S=o?I(t,"short_description","plain-text","Short description"):void 0,b=o?I(t,"description_json","tiptap","Product description"):void 0,v=(r,l,i)=>{const $=c(r,i);return $===r?l:$},L=t.images&&t.images.length>0?t.images:t.image_url?[{url:t.image_url,alt:t.title}]:[],_=t.custom_props?.provider==="freemius"||ae.isDigitalProduct(t),V=ie.getTrialSummary(t),a=!_&&!!(t.has_variants&&t.attributes?.length&&t.variants?.length),x=t.attributes||[],d=t.variants||[],[j,R]=u.useState(()=>h.chooseInitialVariantSelections(x,d)),[P,T]=u.useState(1);u.useEffect(()=>{T(1)},[t.id]),u.useEffect(()=>{a&&R(h.chooseInitialVariantSelections(x,d))},[x,a,t.id,d]);const g=u.useMemo(()=>a?h.normalizeSelectionsToAvailableVariants(x,d,j):j,[x,a,j,d]);u.useEffect(()=>{JSON.stringify(g)!==JSON.stringify(j)&&R(g)},[g,j]);const s=u.useMemo(()=>a?h.findMatchingVariant(d,g):null,[a,g,d]),O=M.resolveEffectivePriceForCurrency({prices:t.prices,salePrices:t.sale_prices,fallbackPrice:t.price,fallbackSalePrice:t.sale_price,saleStartAt:t.sale_start_at,saleEndAt:t.sale_end_at,scheduledPrice:t.scheduled_price,scheduledPrices:t.scheduled_prices,scheduledPriceAt:t.scheduled_price_at,currencyCode:p,currencies:m}),U=a&&s?M.resolveEffectivePriceForCurrency({prices:s.prices,salePrices:s.sale_prices,fallbackPrice:s.price,fallbackSalePrice:s.sale_price,saleStartAt:s.sale_start_at,saleEndAt:s.sale_end_at,scheduledPrice:s.scheduled_price,scheduledPrices:s.scheduled_prices,scheduledPriceAt:s.scheduled_price_at,currencyCode:p,currencies:m}):null,N=U?.price??O.price,y=U?.sale_price??O.sale_price,n=a?s?.stock_quantity??0:t.stock??0,D=u.useMemo(()=>{if(!s?.image_url)return L;const r={url:s.image_url,alt:`${t.title} ${s.label}`},l=L.filter(i=>i.url!==s.image_url);return[r,...l]},[L,t.title,s]),F=typeof y=="number"&&N>0?Math.round((N-y)/N*100):0,J=a&&s?{...t,sku:s.sku,price:s.price,prices:s.prices,sale_price:typeof s.sale_price=="number"?s.sale_price:null,sale_prices:s.sale_prices,image_url:s.image_url||t.image_url,stock:s.stock_quantity,variant_id:s.id,variant_label:s.label,selected_options:s.selected_options,currency_code:p}:{...t,currency_code:p},G=(r,l)=>{R(i=>h.normalizeSelectionsToAvailableVariants(x,d,{...i,[r]:l}))},z=v("ecommerce.in_stock",`${n} in stock`,{count:String(n)}),B=v("ecommerce.out_of_stock","Out of stock"),K=v("ecommerce.select_options","Select Options"),X=v("ecommerce.variant_selection_required","Select one term from every dropdown to resolve a variation.");return e.jsxs("div",{className:"w-full animate-in fade-in slide-in-from-bottom-4 duration-700 ease-out",children:[e.jsx("div",{className:"container mx-auto px-4 md:px-6 py-12",children:e.jsxs("div",{className:"grid gap-12 lg:grid-cols-[2fr_3fr] items-start",children:[e.jsx("div",{className:"w-full max-w-2xl mx-auto lg:max-w-none",children:e.jsx(Z.ProductGallery,{images:D,className:"w-full"})}),e.jsxs("div",{className:"flex flex-col gap-4 pb-2 max-w-xl mx-auto lg:mx-0 lg:max-w-none",children:[e.jsx("div",{className:"space-y-6",children:e.jsxs("div",{className:"space-y-4",children:[e.jsx("h1",{className:"text-3xl sm:text-4xl lg:text-5xl font-extrabold tracking-tight text-foreground leading-[1.1] lg:mt-0",...k,children:t.title}),e.jsx("div",{className:"flex items-center gap-2 mt-2",children:e.jsxs("a",{href:"#reviews-section",className:"flex items-center gap-1.5 group hover:opacity-85 transition-opacity",children:[e.jsx("div",{className:"flex items-center text-amber-500",children:Array.from({length:5}).map((r,l)=>e.jsx("svg",{className:C.cn("h-4 w-4 fill-current",l<Math.round(t.average_rating||0)?"text-amber-500":"text-slate-300 dark:text-slate-700"),viewBox:"0 0 20 20",fill:"currentColor",children:e.jsx("path",{d:"M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"})},l))}),t.total_reviews&&t.total_reviews>0?e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"text-sm font-semibold text-slate-700 dark:text-slate-300",children:t.average_rating?.toFixed(1)}),e.jsxs("span",{className:"text-sm text-muted-foreground underline decoration-dotted group-hover:text-primary",children:["(",t.total_reviews===1?c("reviews.review_count_one",{count:t.total_reviews}):c("reviews.review_count_other",{count:t.total_reviews}),")"]})]}):e.jsx("span",{className:"text-xs text-muted-foreground group-hover:text-primary underline decoration-dotted",children:c("reviews.be_the_first")})]})}),t.categories&&t.categories.length>0&&e.jsx("div",{className:"flex flex-wrap items-center gap-1.5 text-xs font-bold uppercase tracking-widest text-amber-600 dark:text-amber-400",children:t.categories.map((r,l)=>{const i=h.resolveTranslatedText(r.name,r.name_translations,E);return e.jsxs(u.Fragment,{children:[l>0&&e.jsx("span",{className:"text-muted-foreground/30",children:"•"}),e.jsx("span",{children:i})]},r.id)})}),e.jsx("div",{className:"prose prose-neutral dark:prose-invert max-w-none text-muted-foreground leading-relaxed text-left",...S,children:t.short_description?e.jsx("div",{className:"text-lg mb-4 leading-relaxed",dangerouslySetInnerHTML:{__html:t.short_description}}):o?e.jsx("p",{className:"text-lg mb-4 italic text-muted-foreground",children:"Add a short product description."}):null}),e.jsxs("div",{className:"flex items-center gap-3",children:[typeof y=="number"&&e.jsx(A.Badge,{variant:"destructive",className:"px-2.5 py-1 text-xs font-bold uppercase tracking-wide animate-pulse shadow-sm",children:c("ecommerce.sale_badge",{percent:String(F)})}),!_&&n>0&&n<10&&e.jsx(A.Badge,{variant:"outline",className:"text-amber-600 border-amber-200 bg-amber-50",children:c("ecommerce.low_stock",{count:String(n)})}),V&&e.jsx(A.Badge,{variant:"secondary",className:"border border-emerald-200 bg-emerald-50 text-emerald-800",children:V.label})]})]})}),e.jsxs("div",{className:"p-5 rounded-2xl bg-card/60 border border-border/80 shadow-md backdrop-blur-md space-y-4",children:[_?e.jsx(te.SubscriptionSelector,{product:t}):e.jsxs("div",{className:"space-y-3.5",children:[e.jsxs("div",{className:"flex items-center justify-between gap-4",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsx("span",{className:"text-[10px] font-bold text-muted-foreground uppercase tracking-widest",children:v("ecommerce.price","Price")}),e.jsxs("div",{className:"flex items-baseline gap-2.5",children:[e.jsx("span",{className:"text-3xl font-extrabold text-foreground",children:C.formatPrice(y??N,p)}),typeof y=="number"&&e.jsx("span",{className:"text-lg text-muted-foreground line-through decoration-destructive/20 decoration-1",children:C.formatPrice(N,p)})]})]}),!_&&(s||!a)&&e.jsxs("div",{className:"text-right space-y-1",children:[e.jsxs("span",{className:"text-[10px] font-bold text-muted-foreground uppercase tracking-widest block",children:[!a&&t.sku&&e.jsxs("span",{className:"mr-2 font-normal lowercase normal-case text-muted-foreground/70",children:["SKU: ",t.sku]}),v("ecommerce.status","Status")]}),e.jsx("div",{className:(n??0)>0?"text-emerald-600 dark:text-emerald-400 font-semibold text-sm":"text-destructive font-semibold text-sm",children:(n??0)>0?z:B})]})]}),a&&e.jsx("div",{className:"space-y-3",children:e.jsx("div",{className:"grid gap-3 sm:grid-cols-2",children:x.map(r=>{const l=h.getAvailableTermIdsForAttribute(d,r.id,g);return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(H.Label,{htmlFor:`attribute-${r.id}`,className:"text-[11px] font-semibold text-muted-foreground uppercase tracking-wider",children:r.name}),s?.sku&&e.jsx("span",{className:"text-[10px] text-muted-foreground font-mono",children:s.sku})]}),e.jsx("select",{id:`attribute-${r.id}`,className:"flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",value:g[r.id]||"",onChange:i=>G(r.id,i.target.value),children:r.terms.map(i=>e.jsx("option",{value:i.id,disabled:!l.has(i.id),children:i.value},i.id))})]},r.id)})})}),a&&!s&&e.jsx("p",{className:"text-xs text-muted-foreground italic pt-1",children:X}),e.jsxs("div",{className:"flex items-center gap-3 pt-1",children:[!_&&(n??0)>0&&e.jsxs("div",{className:"flex items-center border rounded-lg h-12 bg-background border-input select-none",children:[e.jsx("button",{type:"button",onClick:()=>T(r=>Math.max(1,r-1)),className:"px-3 h-full flex items-center justify-center text-muted-foreground hover:text-foreground active:scale-95 transition-all text-lg font-medium",disabled:P<=1,children:"-"}),e.jsx("span",{className:"w-8 text-center text-sm font-semibold",children:P}),e.jsx("button",{type:"button",onClick:()=>T(r=>n!==null&&r>=n?r:r+1),className:"px-3 h-full flex items-center justify-center text-muted-foreground hover:text-foreground active:scale-95 transition-all text-lg font-medium",disabled:n!==null&&P>=n,children:"+"})]}),a&&(!s||(n??0)<=0)?e.jsx(W.Button,{disabled:!0,className:"flex-1 h-12 text-md font-bold shadow-md",children:s?B:K}):e.jsx(ee.AddToCartButton,{product:J,quantity:P,className:"flex-1 h-12 text-md font-bold shadow-md transition-all hover:shadow-lg active:scale-[0.98]"})]})]}),e.jsx(Q.Separator,{className:"opacity-60 my-0.5"}),e.jsxs("div",{className:"grid grid-cols-2 gap-4 text-center text-[11px] font-medium text-muted-foreground pt-1",children:[e.jsx("div",{className:"flex items-center justify-center gap-2",children:_?e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(q.Download,{className:"h-3.5 w-3.5"}),c("ecommerce.instant_digital_delivery")]}):e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(q.Package,{className:"h-3.5 w-3.5"}),c("ecommerce.free_shipping")]})}),e.jsx("div",{className:"flex items-center justify-center gap-2",children:e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(q.ShieldCheck,{className:"h-3.5 w-3.5"}),c("ecommerce.secure_checkout")]})})]})]})]})]})}),e.jsx("div",{className:"min-w-0 w-full",...f?void 0:b,children:f||(t.description_json?e.jsx("div",{className:"container mx-auto px-4 md:px-6 pb-12 prose prose-neutral dark:prose-invert max-w-none leading-relaxed",children:e.jsx(se.SimpleTiptapRenderer,{content:t.description_json})}):e.jsx("div",{className:"container mx-auto px-4 md:px-6 pb-12",children:e.jsx("p",{className:"italic text-sm text-muted-foreground",children:c("ecommerce.no_description")})}))}),w&&e.jsx("div",{id:"reviews-section",className:"border-t border-border mt-12 pt-12",children:w})]})};exports.ProductDetailsLayout=ce;
|
|
@@ -2,6 +2,7 @@ import { default as React } from 'react';
|
|
|
2
2
|
interface ProductDetailsLayoutProps {
|
|
3
3
|
visualEditingEnabled?: boolean;
|
|
4
4
|
descriptionNode?: React.ReactNode;
|
|
5
|
+
reviewsNode?: React.ReactNode;
|
|
5
6
|
}
|
|
6
7
|
export declare const ProductDetailsLayout: React.FC<ProductDetailsLayoutProps>;
|
|
7
8
|
export {};
|
|
@@ -1,89 +1,90 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsxs as a, jsx as t } from "react/jsx-runtime";
|
|
3
|
-
import
|
|
4
|
-
import { Download as
|
|
5
|
-
import { Badge as
|
|
6
|
-
import { Button as
|
|
7
|
-
import { Label as
|
|
8
|
-
import { Separator as
|
|
9
|
-
import { useTranslations as
|
|
10
|
-
import { useProduct as
|
|
11
|
-
import { ProductGallery as
|
|
12
|
-
import { AddToCartButton as
|
|
13
|
-
import { SubscriptionSelector as
|
|
14
|
-
import { SimpleTiptapRenderer as
|
|
15
|
-
import { chooseInitialVariantSelections as
|
|
16
|
-
import { useCurrency as
|
|
17
|
-
import { resolveEffectivePriceForCurrency as
|
|
18
|
-
import { isDigitalProduct as
|
|
19
|
-
import { getTrialSummary as
|
|
20
|
-
function
|
|
21
|
-
const
|
|
2
|
+
import { jsxs as a, jsx as t, Fragment as Y } from "react/jsx-runtime";
|
|
3
|
+
import Z, { useState as D, useEffect as T, useMemo as I } from "react";
|
|
4
|
+
import { Download as ee, Package as te, ShieldCheck as re } from "lucide-react";
|
|
5
|
+
import { Badge as A } from "@nextblock-cms/ui/badge";
|
|
6
|
+
import { Button as se } from "@nextblock-cms/ui/button";
|
|
7
|
+
import { Label as ae } from "@nextblock-cms/ui/label";
|
|
8
|
+
import { Separator as ie } from "@nextblock-cms/ui/separator";
|
|
9
|
+
import { useTranslations as ce, cn as le, formatPrice as F } from "@nextblock-cms/utils";
|
|
10
|
+
import { useProduct as ne } from "../product-context.es.js";
|
|
11
|
+
import { ProductGallery as oe } from "./ProductGallery.es.js";
|
|
12
|
+
import { AddToCartButton as de } from "./AddToCartButton.es.js";
|
|
13
|
+
import { SubscriptionSelector as me } from "./SubscriptionSelector.es.js";
|
|
14
|
+
import { SimpleTiptapRenderer as pe } from "./SimpleTiptapRenderer.es.js";
|
|
15
|
+
import { chooseInitialVariantSelections as M, normalizeSelectionsToAvailableVariants as J, findMatchingVariant as ue, resolveTranslatedText as fe, getAvailableTermIdsForAttribute as he } from "../variation-utils.es.js";
|
|
16
|
+
import { useCurrency as ge } from "../CurrencyProvider.es.js";
|
|
17
|
+
import { resolveEffectivePriceForCurrency as G } from "../currency.es.js";
|
|
18
|
+
import { isDigitalProduct as xe } from "../types.es.js";
|
|
19
|
+
import { getTrialSummary as ve } from "../trials.es.js";
|
|
20
|
+
function V(d, g, w, e) {
|
|
21
|
+
const l = {
|
|
22
22
|
kind: "product-field",
|
|
23
|
-
field:
|
|
24
|
-
input:
|
|
25
|
-
label:
|
|
26
|
-
},
|
|
27
|
-
let
|
|
23
|
+
field: g,
|
|
24
|
+
input: w,
|
|
25
|
+
label: e
|
|
26
|
+
}, C = typeof window < "u" ? window.location.origin : process.env.NEXT_PUBLIC_URL || process.env.TARGET_URL || (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "") || "http://localhost:3000";
|
|
27
|
+
let p = (typeof window < "u" ? window.location.origin : process.env.NEXT_PUBLIC_URL || process.env.TARGET_URL || (process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : "") || "http://localhost:3000").replace(/\/+$/, "");
|
|
28
28
|
try {
|
|
29
|
-
(
|
|
29
|
+
(p.startsWith("http://") || p.startsWith("https://")) && (p = new URL(p).hostname);
|
|
30
30
|
} catch {
|
|
31
31
|
}
|
|
32
|
-
const k = process.env.NEXTBLOCK_VERCEL_PROJECT_ID || process.env.VERCEL_PROJECT_ID,
|
|
33
|
-
origin:
|
|
34
|
-
editUrl: `${
|
|
32
|
+
const k = process.env.NEXTBLOCK_VERCEL_PROJECT_ID || process.env.VERCEL_PROJECT_ID, S = process.env.NEXTBLOCK_VERCEL_WORKSPACE_ID || process.env.VERCEL_ORG_ID, _ = {
|
|
33
|
+
origin: p,
|
|
34
|
+
editUrl: `${C}/cms/products/${d.id}/edit`,
|
|
35
35
|
data: {
|
|
36
36
|
parentType: "product",
|
|
37
|
-
parentId:
|
|
38
|
-
slug:
|
|
39
|
-
languageId:
|
|
37
|
+
parentId: d.id,
|
|
38
|
+
slug: d.slug,
|
|
39
|
+
languageId: d.language_id,
|
|
40
40
|
draftId: null,
|
|
41
|
-
target:
|
|
41
|
+
target: l
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
|
-
return k && (
|
|
45
|
-
"data-vercel-edit-info": JSON.stringify(
|
|
46
|
-
"data-vercel-edit-target": JSON.stringify(
|
|
47
|
-
"data-nextblock-visual-edit": `product:${
|
|
44
|
+
return k && (_.projectId = k), S && (_.workspaceId = S), {
|
|
45
|
+
"data-vercel-edit-info": JSON.stringify(_),
|
|
46
|
+
"data-vercel-edit-target": JSON.stringify(l),
|
|
47
|
+
"data-nextblock-visual-edit": `product:${g}`
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
-
const
|
|
51
|
-
visualEditingEnabled:
|
|
52
|
-
descriptionNode:
|
|
50
|
+
const je = ({
|
|
51
|
+
visualEditingEnabled: d = !1,
|
|
52
|
+
descriptionNode: g,
|
|
53
|
+
reviewsNode: w
|
|
53
54
|
}) => {
|
|
54
|
-
const e =
|
|
55
|
+
const e = ne(), { t: l, lang: C } = ce(), { activeCurrencyCode: u, currencies: p } = ge(), k = d ? V(
|
|
55
56
|
e,
|
|
56
57
|
"title",
|
|
57
58
|
"plain-text",
|
|
58
59
|
"Product title"
|
|
59
|
-
) : void 0,
|
|
60
|
+
) : void 0, S = d ? V(
|
|
60
61
|
e,
|
|
61
62
|
"short_description",
|
|
62
63
|
"plain-text",
|
|
63
64
|
"Short description"
|
|
64
|
-
) : void 0,
|
|
65
|
+
) : void 0, _ = d ? V(
|
|
65
66
|
e,
|
|
66
67
|
"description_json",
|
|
67
68
|
"tiptap",
|
|
68
69
|
"Product description"
|
|
69
|
-
) : void 0,
|
|
70
|
-
const
|
|
71
|
-
return
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}, [e.id]),
|
|
76
|
-
i &&
|
|
77
|
-
}, [
|
|
78
|
-
const h =
|
|
79
|
-
|
|
70
|
+
) : void 0, x = (s, o, c) => {
|
|
71
|
+
const B = l(s, c);
|
|
72
|
+
return B === s ? o : B;
|
|
73
|
+
}, L = e.images && e.images.length > 0 ? e.images : e.image_url ? [{ url: e.image_url, alt: e.title }] : [], v = e.custom_props?.provider === "freemius" || xe(e), O = ve(e), i = !v && !!(e.has_variants && e.attributes?.length && e.variants?.length), f = e.attributes || [], m = e.variants || [], [b, E] = D(() => M(f, m)), [P, R] = D(1);
|
|
74
|
+
T(() => {
|
|
75
|
+
R(1);
|
|
76
|
+
}, [e.id]), T(() => {
|
|
77
|
+
i && E(M(f, m));
|
|
78
|
+
}, [f, i, e.id, m]);
|
|
79
|
+
const h = I(() => i ? J(
|
|
80
|
+
f,
|
|
80
81
|
m,
|
|
81
|
-
|
|
82
|
-
) :
|
|
83
|
-
|
|
84
|
-
JSON.stringify(h) !== JSON.stringify(
|
|
85
|
-
}, [h,
|
|
86
|
-
const r =
|
|
82
|
+
b
|
|
83
|
+
) : b, [f, i, b, m]);
|
|
84
|
+
T(() => {
|
|
85
|
+
JSON.stringify(h) !== JSON.stringify(b) && E(h);
|
|
86
|
+
}, [h, b]);
|
|
87
|
+
const r = I(() => i ? ue(m, h) : null, [i, h, m]), U = G({
|
|
87
88
|
prices: e.prices,
|
|
88
89
|
salePrices: e.sale_prices,
|
|
89
90
|
fallbackPrice: e.price,
|
|
@@ -94,8 +95,8 @@ const Ve = ({
|
|
|
94
95
|
scheduledPrices: e.scheduled_prices,
|
|
95
96
|
scheduledPriceAt: e.scheduled_price_at,
|
|
96
97
|
currencyCode: u,
|
|
97
|
-
currencies:
|
|
98
|
-
}),
|
|
98
|
+
currencies: p
|
|
99
|
+
}), j = i && r ? G({
|
|
99
100
|
prices: r.prices,
|
|
100
101
|
salePrices: r.sale_prices,
|
|
101
102
|
fallbackPrice: r.price,
|
|
@@ -106,20 +107,20 @@ const Ve = ({
|
|
|
106
107
|
scheduledPrices: r.scheduled_prices,
|
|
107
108
|
scheduledPriceAt: r.scheduled_price_at,
|
|
108
109
|
currencyCode: u,
|
|
109
|
-
currencies:
|
|
110
|
-
}) : null,
|
|
110
|
+
currencies: p
|
|
111
|
+
}) : null, N = j?.price ?? U.price, y = j?.sale_price ?? U.sale_price, n = i ? r?.stock_quantity ?? 0 : e.stock ?? 0, K = I(() => {
|
|
111
112
|
if (!r?.image_url)
|
|
112
|
-
return
|
|
113
|
+
return L;
|
|
113
114
|
const s = {
|
|
114
115
|
url: r.image_url,
|
|
115
116
|
alt: `${e.title} ${r.label}`
|
|
116
|
-
},
|
|
117
|
+
}, o = L.filter(
|
|
117
118
|
(c) => c.url !== r.image_url
|
|
118
119
|
);
|
|
119
|
-
return [s, ...
|
|
120
|
-
}, [
|
|
121
|
-
(
|
|
122
|
-
) : 0,
|
|
120
|
+
return [s, ...o];
|
|
121
|
+
}, [L, e.title, r]), X = typeof y == "number" && N > 0 ? Math.round(
|
|
122
|
+
(N - y) / N * 100
|
|
123
|
+
) : 0, q = i && r ? {
|
|
123
124
|
...e,
|
|
124
125
|
sku: r.sku,
|
|
125
126
|
price: r.price,
|
|
@@ -135,48 +136,78 @@ const Ve = ({
|
|
|
135
136
|
} : {
|
|
136
137
|
...e,
|
|
137
138
|
currency_code: u
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
(c) => J(
|
|
139
|
+
}, z = (s, o) => {
|
|
140
|
+
E(
|
|
141
|
+
(c) => J(f, m, {
|
|
141
142
|
...c,
|
|
142
|
-
[s]:
|
|
143
|
+
[s]: o
|
|
143
144
|
})
|
|
144
145
|
);
|
|
145
|
-
}, W =
|
|
146
|
+
}, W = x(
|
|
146
147
|
"ecommerce.in_stock",
|
|
147
148
|
`${n} in stock`,
|
|
148
149
|
{ count: String(n) }
|
|
149
|
-
),
|
|
150
|
+
), $ = x(
|
|
150
151
|
"ecommerce.out_of_stock",
|
|
151
152
|
"Out of stock"
|
|
152
|
-
),
|
|
153
|
+
), H = x(
|
|
153
154
|
"ecommerce.select_options",
|
|
154
155
|
"Select Options"
|
|
155
|
-
),
|
|
156
|
+
), Q = x(
|
|
156
157
|
"ecommerce.variant_selection_required",
|
|
157
158
|
"Select one term from every dropdown to resolve a variation."
|
|
158
159
|
);
|
|
159
160
|
return /* @__PURE__ */ a("div", { className: "w-full animate-in fade-in slide-in-from-bottom-4 duration-700 ease-out", children: [
|
|
160
161
|
/* @__PURE__ */ t("div", { className: "container mx-auto px-4 md:px-6 py-12", children: /* @__PURE__ */ a("div", { className: "grid gap-12 lg:grid-cols-[2fr_3fr] items-start", children: [
|
|
161
|
-
/* @__PURE__ */ t("div", { className: "w-full max-w-2xl mx-auto lg:max-w-none", children: /* @__PURE__ */ t(
|
|
162
|
+
/* @__PURE__ */ t("div", { className: "w-full max-w-2xl mx-auto lg:max-w-none", children: /* @__PURE__ */ t(oe, { images: K, className: "w-full" }) }),
|
|
162
163
|
/* @__PURE__ */ a("div", { className: "flex flex-col gap-4 pb-2 max-w-xl mx-auto lg:mx-0 lg:max-w-none", children: [
|
|
163
164
|
/* @__PURE__ */ t("div", { className: "space-y-6", children: /* @__PURE__ */ a("div", { className: "space-y-4", children: [
|
|
164
165
|
/* @__PURE__ */ t(
|
|
165
166
|
"h1",
|
|
166
167
|
{
|
|
167
168
|
className: "text-3xl sm:text-4xl lg:text-5xl font-extrabold tracking-tight text-foreground leading-[1.1] lg:mt-0",
|
|
168
|
-
...
|
|
169
|
+
...k,
|
|
169
170
|
children: e.title
|
|
170
171
|
}
|
|
171
172
|
),
|
|
172
|
-
|
|
173
|
-
|
|
173
|
+
/* @__PURE__ */ t("div", { className: "flex items-center gap-2 mt-2", children: /* @__PURE__ */ a(
|
|
174
|
+
"a",
|
|
175
|
+
{
|
|
176
|
+
href: "#reviews-section",
|
|
177
|
+
className: "flex items-center gap-1.5 group hover:opacity-85 transition-opacity",
|
|
178
|
+
children: [
|
|
179
|
+
/* @__PURE__ */ t("div", { className: "flex items-center text-amber-500", children: Array.from({ length: 5 }).map((s, o) => /* @__PURE__ */ t(
|
|
180
|
+
"svg",
|
|
181
|
+
{
|
|
182
|
+
className: le(
|
|
183
|
+
"h-4 w-4 fill-current",
|
|
184
|
+
o < Math.round(e.average_rating || 0) ? "text-amber-500" : "text-slate-300 dark:text-slate-700"
|
|
185
|
+
),
|
|
186
|
+
viewBox: "0 0 20 20",
|
|
187
|
+
fill: "currentColor",
|
|
188
|
+
children: /* @__PURE__ */ t("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" })
|
|
189
|
+
},
|
|
190
|
+
o
|
|
191
|
+
)) }),
|
|
192
|
+
e.total_reviews && e.total_reviews > 0 ? /* @__PURE__ */ a(Y, { children: [
|
|
193
|
+
/* @__PURE__ */ t("span", { className: "text-sm font-semibold text-slate-700 dark:text-slate-300", children: e.average_rating?.toFixed(1) }),
|
|
194
|
+
/* @__PURE__ */ a("span", { className: "text-sm text-muted-foreground underline decoration-dotted group-hover:text-primary", children: [
|
|
195
|
+
"(",
|
|
196
|
+
e.total_reviews === 1 ? l("reviews.review_count_one", { count: e.total_reviews }) : l("reviews.review_count_other", { count: e.total_reviews }),
|
|
197
|
+
")"
|
|
198
|
+
] })
|
|
199
|
+
] }) : /* @__PURE__ */ t("span", { className: "text-xs text-muted-foreground group-hover:text-primary underline decoration-dotted", children: l("reviews.be_the_first") })
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
) }),
|
|
203
|
+
e.categories && e.categories.length > 0 && /* @__PURE__ */ t("div", { className: "flex flex-wrap items-center gap-1.5 text-xs font-bold uppercase tracking-widest text-amber-600 dark:text-amber-400", children: e.categories.map((s, o) => {
|
|
204
|
+
const c = fe(
|
|
174
205
|
s.name,
|
|
175
206
|
s.name_translations,
|
|
176
|
-
|
|
207
|
+
C
|
|
177
208
|
);
|
|
178
|
-
return /* @__PURE__ */ a(
|
|
179
|
-
|
|
209
|
+
return /* @__PURE__ */ a(Z.Fragment, { children: [
|
|
210
|
+
o > 0 && /* @__PURE__ */ t("span", { className: "text-muted-foreground/30", children: "•" }),
|
|
180
211
|
/* @__PURE__ */ t("span", { children: c })
|
|
181
212
|
] }, s.id);
|
|
182
213
|
}) }),
|
|
@@ -184,7 +215,7 @@ const Ve = ({
|
|
|
184
215
|
"div",
|
|
185
216
|
{
|
|
186
217
|
className: "prose prose-neutral dark:prose-invert max-w-none text-muted-foreground leading-relaxed text-left",
|
|
187
|
-
...
|
|
218
|
+
...S,
|
|
188
219
|
children: e.short_description ? /* @__PURE__ */ t(
|
|
189
220
|
"div",
|
|
190
221
|
{
|
|
@@ -193,51 +224,51 @@ const Ve = ({
|
|
|
193
224
|
__html: e.short_description
|
|
194
225
|
}
|
|
195
226
|
}
|
|
196
|
-
) :
|
|
227
|
+
) : d ? /* @__PURE__ */ t("p", { className: "text-lg mb-4 italic text-muted-foreground", children: "Add a short product description." }) : null
|
|
197
228
|
}
|
|
198
229
|
),
|
|
199
230
|
/* @__PURE__ */ a("div", { className: "flex items-center gap-3", children: [
|
|
200
|
-
typeof
|
|
201
|
-
|
|
231
|
+
typeof y == "number" && /* @__PURE__ */ t(
|
|
232
|
+
A,
|
|
202
233
|
{
|
|
203
234
|
variant: "destructive",
|
|
204
235
|
className: "px-2.5 py-1 text-xs font-bold uppercase tracking-wide animate-pulse shadow-sm",
|
|
205
|
-
children:
|
|
206
|
-
percent: String(
|
|
236
|
+
children: l("ecommerce.sale_badge", {
|
|
237
|
+
percent: String(X)
|
|
207
238
|
})
|
|
208
239
|
}
|
|
209
240
|
),
|
|
210
241
|
!v && n > 0 && n < 10 && /* @__PURE__ */ t(
|
|
211
|
-
|
|
242
|
+
A,
|
|
212
243
|
{
|
|
213
244
|
variant: "outline",
|
|
214
245
|
className: "text-amber-600 border-amber-200 bg-amber-50",
|
|
215
|
-
children:
|
|
246
|
+
children: l("ecommerce.low_stock", {
|
|
216
247
|
count: String(n)
|
|
217
248
|
})
|
|
218
249
|
}
|
|
219
250
|
),
|
|
220
|
-
|
|
221
|
-
|
|
251
|
+
O && /* @__PURE__ */ t(
|
|
252
|
+
A,
|
|
222
253
|
{
|
|
223
254
|
variant: "secondary",
|
|
224
255
|
className: "border border-emerald-200 bg-emerald-50 text-emerald-800",
|
|
225
|
-
children:
|
|
256
|
+
children: O.label
|
|
226
257
|
}
|
|
227
258
|
)
|
|
228
259
|
] })
|
|
229
260
|
] }) }),
|
|
230
261
|
/* @__PURE__ */ a("div", { className: "p-5 rounded-2xl bg-card/60 border border-border/80 shadow-md backdrop-blur-md space-y-4", children: [
|
|
231
|
-
v ? /* @__PURE__ */ t(
|
|
262
|
+
v ? /* @__PURE__ */ t(me, { product: e }) : /* @__PURE__ */ a("div", { className: "space-y-3.5", children: [
|
|
232
263
|
/* @__PURE__ */ a("div", { className: "flex items-center justify-between gap-4", children: [
|
|
233
264
|
/* @__PURE__ */ a("div", { className: "space-y-1", children: [
|
|
234
|
-
/* @__PURE__ */ t("span", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-widest", children:
|
|
265
|
+
/* @__PURE__ */ t("span", { className: "text-[10px] font-bold text-muted-foreground uppercase tracking-widest", children: x("ecommerce.price", "Price") }),
|
|
235
266
|
/* @__PURE__ */ a("div", { className: "flex items-baseline gap-2.5", children: [
|
|
236
|
-
/* @__PURE__ */ t("span", { className: "text-3xl font-extrabold text-foreground", children:
|
|
237
|
-
|
|
267
|
+
/* @__PURE__ */ t("span", { className: "text-3xl font-extrabold text-foreground", children: F(
|
|
268
|
+
y ?? N,
|
|
238
269
|
u
|
|
239
270
|
) }),
|
|
240
|
-
typeof
|
|
271
|
+
typeof y == "number" && /* @__PURE__ */ t("span", { className: "text-lg text-muted-foreground line-through decoration-destructive/20 decoration-1", children: F(N, u) })
|
|
241
272
|
] })
|
|
242
273
|
] }),
|
|
243
274
|
!v && (r || !i) && /* @__PURE__ */ a("div", { className: "text-right space-y-1", children: [
|
|
@@ -246,13 +277,13 @@ const Ve = ({
|
|
|
246
277
|
"SKU: ",
|
|
247
278
|
e.sku
|
|
248
279
|
] }),
|
|
249
|
-
|
|
280
|
+
x("ecommerce.status", "Status")
|
|
250
281
|
] }),
|
|
251
|
-
/* @__PURE__ */ t("div", { className: (n ?? 0) > 0 ? "text-emerald-600 dark:text-emerald-400 font-semibold text-sm" : "text-destructive font-semibold text-sm", children: (n ?? 0) > 0 ? W :
|
|
282
|
+
/* @__PURE__ */ t("div", { className: (n ?? 0) > 0 ? "text-emerald-600 dark:text-emerald-400 font-semibold text-sm" : "text-destructive font-semibold text-sm", children: (n ?? 0) > 0 ? W : $ })
|
|
252
283
|
] })
|
|
253
284
|
] }),
|
|
254
|
-
i && /* @__PURE__ */ t("div", { className: "space-y-3", children: /* @__PURE__ */ t("div", { className: "grid gap-3 sm:grid-cols-2", children:
|
|
255
|
-
const
|
|
285
|
+
i && /* @__PURE__ */ t("div", { className: "space-y-3", children: /* @__PURE__ */ t("div", { className: "grid gap-3 sm:grid-cols-2", children: f.map((s) => {
|
|
286
|
+
const o = he(
|
|
256
287
|
m,
|
|
257
288
|
s.id,
|
|
258
289
|
h
|
|
@@ -260,7 +291,7 @@ const Ve = ({
|
|
|
260
291
|
return /* @__PURE__ */ a("div", { className: "space-y-1", children: [
|
|
261
292
|
/* @__PURE__ */ a("div", { className: "flex items-center justify-between", children: [
|
|
262
293
|
/* @__PURE__ */ t(
|
|
263
|
-
|
|
294
|
+
ae,
|
|
264
295
|
{
|
|
265
296
|
htmlFor: `attribute-${s.id}`,
|
|
266
297
|
className: "text-[11px] font-semibold text-muted-foreground uppercase tracking-wider",
|
|
@@ -275,7 +306,7 @@ const Ve = ({
|
|
|
275
306
|
id: `attribute-${s.id}`,
|
|
276
307
|
className: "flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
277
308
|
value: h[s.id] || "",
|
|
278
|
-
onChange: (c) =>
|
|
309
|
+
onChange: (c) => z(
|
|
279
310
|
s.id,
|
|
280
311
|
c.target.value
|
|
281
312
|
),
|
|
@@ -283,7 +314,7 @@ const Ve = ({
|
|
|
283
314
|
"option",
|
|
284
315
|
{
|
|
285
316
|
value: c.id,
|
|
286
|
-
disabled: !
|
|
317
|
+
disabled: !o.has(c.id),
|
|
287
318
|
children: c.value
|
|
288
319
|
},
|
|
289
320
|
c.id
|
|
@@ -292,70 +323,71 @@ const Ve = ({
|
|
|
292
323
|
)
|
|
293
324
|
] }, s.id);
|
|
294
325
|
}) }) }),
|
|
295
|
-
i && !r && /* @__PURE__ */ t("p", { className: "text-xs text-muted-foreground italic pt-1", children:
|
|
326
|
+
i && !r && /* @__PURE__ */ t("p", { className: "text-xs text-muted-foreground italic pt-1", children: Q }),
|
|
296
327
|
/* @__PURE__ */ a("div", { className: "flex items-center gap-3 pt-1", children: [
|
|
297
328
|
!v && (n ?? 0) > 0 && /* @__PURE__ */ a("div", { className: "flex items-center border rounded-lg h-12 bg-background border-input select-none", children: [
|
|
298
329
|
/* @__PURE__ */ t(
|
|
299
330
|
"button",
|
|
300
331
|
{
|
|
301
332
|
type: "button",
|
|
302
|
-
onClick: () =>
|
|
333
|
+
onClick: () => R((s) => Math.max(1, s - 1)),
|
|
303
334
|
className: "px-3 h-full flex items-center justify-center text-muted-foreground hover:text-foreground active:scale-95 transition-all text-lg font-medium",
|
|
304
|
-
disabled:
|
|
335
|
+
disabled: P <= 1,
|
|
305
336
|
children: "-"
|
|
306
337
|
}
|
|
307
338
|
),
|
|
308
|
-
/* @__PURE__ */ t("span", { className: "w-8 text-center text-sm font-semibold", children:
|
|
339
|
+
/* @__PURE__ */ t("span", { className: "w-8 text-center text-sm font-semibold", children: P }),
|
|
309
340
|
/* @__PURE__ */ t(
|
|
310
341
|
"button",
|
|
311
342
|
{
|
|
312
343
|
type: "button",
|
|
313
|
-
onClick: () =>
|
|
344
|
+
onClick: () => R(
|
|
314
345
|
(s) => n !== null && s >= n ? s : s + 1
|
|
315
346
|
),
|
|
316
347
|
className: "px-3 h-full flex items-center justify-center text-muted-foreground hover:text-foreground active:scale-95 transition-all text-lg font-medium",
|
|
317
|
-
disabled: n !== null &&
|
|
348
|
+
disabled: n !== null && P >= n,
|
|
318
349
|
children: "+"
|
|
319
350
|
}
|
|
320
351
|
)
|
|
321
352
|
] }),
|
|
322
353
|
i && (!r || (n ?? 0) <= 0) ? /* @__PURE__ */ t(
|
|
323
|
-
|
|
354
|
+
se,
|
|
324
355
|
{
|
|
325
356
|
disabled: !0,
|
|
326
357
|
className: "flex-1 h-12 text-md font-bold shadow-md",
|
|
327
|
-
children: r ?
|
|
358
|
+
children: r ? $ : H
|
|
328
359
|
}
|
|
329
360
|
) : /* @__PURE__ */ t(
|
|
330
|
-
|
|
361
|
+
de,
|
|
331
362
|
{
|
|
332
|
-
product:
|
|
333
|
-
quantity:
|
|
363
|
+
product: q,
|
|
364
|
+
quantity: P,
|
|
334
365
|
className: "flex-1 h-12 text-md font-bold shadow-md transition-all hover:shadow-lg active:scale-[0.98]"
|
|
335
366
|
}
|
|
336
367
|
)
|
|
337
368
|
] })
|
|
338
369
|
] }),
|
|
339
|
-
/* @__PURE__ */ t(
|
|
370
|
+
/* @__PURE__ */ t(ie, { className: "opacity-60 my-0.5" }),
|
|
340
371
|
/* @__PURE__ */ a("div", { className: "grid grid-cols-2 gap-4 text-center text-[11px] font-medium text-muted-foreground pt-1", children: [
|
|
341
372
|
/* @__PURE__ */ t("div", { className: "flex items-center justify-center gap-2", children: v ? /* @__PURE__ */ a("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
342
|
-
/* @__PURE__ */ t(
|
|
343
|
-
|
|
373
|
+
/* @__PURE__ */ t(ee, { className: "h-3.5 w-3.5" }),
|
|
374
|
+
l("ecommerce.instant_digital_delivery")
|
|
344
375
|
] }) : /* @__PURE__ */ a("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
345
|
-
/* @__PURE__ */ t(
|
|
346
|
-
|
|
376
|
+
/* @__PURE__ */ t(te, { className: "h-3.5 w-3.5" }),
|
|
377
|
+
l("ecommerce.free_shipping")
|
|
347
378
|
] }) }),
|
|
348
379
|
/* @__PURE__ */ t("div", { className: "flex items-center justify-center gap-2", children: /* @__PURE__ */ a("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
349
|
-
/* @__PURE__ */ t(
|
|
350
|
-
|
|
380
|
+
/* @__PURE__ */ t(re, { className: "h-3.5 w-3.5" }),
|
|
381
|
+
l("ecommerce.secure_checkout")
|
|
351
382
|
] }) })
|
|
352
383
|
] })
|
|
353
384
|
] })
|
|
354
385
|
] })
|
|
355
386
|
] }) }),
|
|
356
|
-
/* @__PURE__ */ t("div", { className: "min-w-0 w-full", ...
|
|
387
|
+
/* @__PURE__ */ t("div", { className: "min-w-0 w-full", ...g ? void 0 : _, children: g || (e.description_json ? /* @__PURE__ */ t("div", { className: "container mx-auto px-4 md:px-6 pb-12 prose prose-neutral dark:prose-invert max-w-none leading-relaxed", children: /* @__PURE__ */ t(pe, { content: e.description_json }) }) : /* @__PURE__ */ t("div", { className: "container mx-auto px-4 md:px-6 pb-12", children: /* @__PURE__ */ t("p", { className: "italic text-sm text-muted-foreground", children: l("ecommerce.no_description") }) })) }),
|
|
388
|
+
w && /* @__PURE__ */ t("div", { id: "reviews-section", className: "border-t border-border mt-12 pt-12", children: w })
|
|
357
389
|
] });
|
|
358
390
|
};
|
|
359
391
|
export {
|
|
360
|
-
|
|
392
|
+
je as ProductDetailsLayout
|
|
361
393
|
};
|
|
@@ -7,6 +7,8 @@ export declare function getProducts(options?: {
|
|
|
7
7
|
data: never[] | {
|
|
8
8
|
id: string;
|
|
9
9
|
title: string;
|
|
10
|
+
average_rating: number;
|
|
11
|
+
total_reviews: number;
|
|
10
12
|
sku: string;
|
|
11
13
|
upc: string | null;
|
|
12
14
|
price: number;
|
|
@@ -79,6 +81,7 @@ export declare function getProducts(options?: {
|
|
|
79
81
|
count: number | null;
|
|
80
82
|
}>;
|
|
81
83
|
export declare function getProduct(id: string): Promise<{
|
|
84
|
+
average_rating: number;
|
|
82
85
|
created_at: string | null;
|
|
83
86
|
description_json: import('../../../../../../db/src/index.ts').Json | null;
|
|
84
87
|
freemius_plan_id: string | null;
|
|
@@ -106,6 +109,7 @@ export declare function getProduct(id: string): Promise<{
|
|
|
106
109
|
status: string;
|
|
107
110
|
stock: number | null;
|
|
108
111
|
title: string;
|
|
112
|
+
total_reviews: number;
|
|
109
113
|
translation_group_id: string;
|
|
110
114
|
trial_period_days: number;
|
|
111
115
|
trial_requires_payment_method: boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const F=require("@nextblock-cms/utils/server"),P=require("./shared-inventory.cjs.js"),b=require("@nextblock-cms/utils"),g=e=>Math.round(e*100);function y(e){return Object.entries(e||{}).reduce((t,[r,i])=>(typeof i=="number"&&Number.isFinite(i)&&i>=0&&(t[b.normalizeCurrencyCode(r)]=g(i)),t),{})}function E(e){return(e||[]).map(t=>({id:t.id,sku:t.sku,upc:t.upc??null,price:g(t.price),sale_price:typeof t.sale_price=="number"&&!isNaN(t.sale_price)?g(t.sale_price):null,prices:y(t.prices),sale_prices:y(t.sale_prices),sale_start_at:t.sale_start_at??null,sale_end_at:t.sale_end_at??null,stock_quantity:t.stock_quantity,main_media_id:t.main_media_id??null,attribute_term_ids:t.attribute_term_ids}))}function j(e,t){const i=e.product_type==="digital"&&e.payment_provider==="freemius"?Math.max(0,Number(e.trial_period_days??0)):0;return{id:t,product_type:e.product_type,payment_provider:e.payment_provider,title:e.title,slug:e.slug,sku:e.sku,upc:e.upc??null,stock:e.stock,status:e.status,short_description:e.short_description??null,description_json:e.description_json??null,metadata:{},price:g(e.price),sale_price:typeof e.sale_price=="number"&&!isNaN(e.sale_price)?g(e.sale_price):null,prices:y(e.prices),sale_prices:y(e.sale_prices),sale_start_at:e.sale_start_at??null,sale_end_at:e.sale_end_at??null,freemius_plan_id:e.freemius_plan_id??null,freemius_product_id:e.freemius_product_id??null,trial_period_days:i,trial_requires_payment_method:i>0?e.trial_requires_payment_method??!1:!1,is_taxable:e.is_taxable,language_id:e.language_id,translation_group_id:e.translation_group_id||void 0,variants:E(e.variants)}}async function S(e,t,r){const{error:i}=await e.from("products").update({is_taxable:r,updated_at:new Date().toISOString()}).eq("id",t);if(i)throw i}async function x(e,t,r){const i=new Date().toISOString(),{data:c}=await e.from("products").select("sku, sale_price, sale_prices").eq("id",t).maybeSingle(),s=c?.sku??r.sku,{data:a}=await e.from("products").select("id").eq("sku",s),d=(a??[]).map(o=>o.id);d.length===0&&d.push(t);const{error:n}=await e.from("products").update({sale_price:c?.sale_price??null,sale_prices:c?.sale_prices??null,sale_start_at:r.sale_start_at??null,sale_end_at:r.sale_end_at??null,updated_at:i}).in("id",d);if(n)throw n;const _=r.variants??[];if(_.length===0)return;const{data:l}=await e.from("product_variants").select("sku, sale_price, sale_prices").eq("product_id",t),u=new Map((l??[]).map(o=>[o.sku,o]));for(const o of _){const p=u.get(o.sku);if(!p)continue;const{error:m}=await e.from("product_variants").update({sale_price:p.sale_price??null,sale_prices:p.sale_prices??null,sale_start_at:o.sale_start_at??null,sale_end_at:o.sale_end_at??null,updated_at:i}).eq("sku",o.sku).in("product_id",d);if(m)throw m}}async function C(e,{page:t=1,limit:r=10,search:i="",languageId:c,categoryId:s}={}){const a=(t-1)*r,d=a+r-1;let n=e.from("products").select("id, title, sku, upc, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at, is_taxable, product_type, payment_provider, short_description, stock, status, slug, language_id, translation_group_id, freemius_product_id, freemius_plan_id, trial_period_days, trial_requires_payment_method, product_media(media(file_path, object_key)), product_variants(id, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at), freemius_plans(id, name, title, freemius_pricing(id, license_quota, api_monthly_price, api_annual_price, api_lifetime_price, override_monthly_price, override_annual_price, override_lifetime_price, is_active)), product_categories(category:categories(id, name, slug, description, name_translations, description_translations))",{count:"exact"}).range(a,d).order("created_at",{ascending:!1});if(c&&(n=n.eq("language_id",c)),s){const{data:_,error:l}=await e.from("product_categories").select("product_id").eq("category_id",s);if(l)return{data:[],error:l,count:0};const u=(_||[]).map(o=>o.product_id).filter(Boolean);if(u.length===0)return{data:[],error:null,count:0};n=n.in("id",u)}return i&&(n=n.or(`title.ilike.%${i}%,sku.ilike.%${i}%`)),n}async function M(e,t){return e.from("products").select(`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const F=require("@nextblock-cms/utils/server"),P=require("./shared-inventory.cjs.js"),b=require("@nextblock-cms/utils/utils"),g=e=>Math.round(e*100);function y(e){return Object.entries(e||{}).reduce((t,[r,i])=>(typeof i=="number"&&Number.isFinite(i)&&i>=0&&(t[b.normalizeCurrencyCode(r)]=g(i)),t),{})}function E(e){return(e||[]).map(t=>({id:t.id,sku:t.sku,upc:t.upc??null,price:g(t.price),sale_price:typeof t.sale_price=="number"&&!isNaN(t.sale_price)?g(t.sale_price):null,prices:y(t.prices),sale_prices:y(t.sale_prices),sale_start_at:t.sale_start_at??null,sale_end_at:t.sale_end_at??null,stock_quantity:t.stock_quantity,main_media_id:t.main_media_id??null,attribute_term_ids:t.attribute_term_ids}))}function j(e,t){const i=e.product_type==="digital"&&e.payment_provider==="freemius"?Math.max(0,Number(e.trial_period_days??0)):0;return{id:t,product_type:e.product_type,payment_provider:e.payment_provider,title:e.title,slug:e.slug,sku:e.sku,upc:e.upc??null,stock:e.stock,status:e.status,short_description:e.short_description??null,description_json:e.description_json??null,metadata:{},price:g(e.price),sale_price:typeof e.sale_price=="number"&&!isNaN(e.sale_price)?g(e.sale_price):null,prices:y(e.prices),sale_prices:y(e.sale_prices),sale_start_at:e.sale_start_at??null,sale_end_at:e.sale_end_at??null,freemius_plan_id:e.freemius_plan_id??null,freemius_product_id:e.freemius_product_id??null,trial_period_days:i,trial_requires_payment_method:i>0?e.trial_requires_payment_method??!1:!1,is_taxable:e.is_taxable,language_id:e.language_id,translation_group_id:e.translation_group_id||void 0,variants:E(e.variants)}}async function S(e,t,r){const{error:i}=await e.from("products").update({is_taxable:r,updated_at:new Date().toISOString()}).eq("id",t);if(i)throw i}async function x(e,t,r){const i=new Date().toISOString(),{data:c}=await e.from("products").select("sku, sale_price, sale_prices").eq("id",t).maybeSingle(),s=c?.sku??r.sku,{data:a}=await e.from("products").select("id").eq("sku",s),d=(a??[]).map(o=>o.id);d.length===0&&d.push(t);const{error:n}=await e.from("products").update({sale_price:c?.sale_price??null,sale_prices:c?.sale_prices??null,sale_start_at:r.sale_start_at??null,sale_end_at:r.sale_end_at??null,updated_at:i}).in("id",d);if(n)throw n;const _=r.variants??[];if(_.length===0)return;const{data:l}=await e.from("product_variants").select("sku, sale_price, sale_prices").eq("product_id",t),u=new Map((l??[]).map(o=>[o.sku,o]));for(const o of _){const p=u.get(o.sku);if(!p)continue;const{error:m}=await e.from("product_variants").update({sale_price:p.sale_price??null,sale_prices:p.sale_prices??null,sale_start_at:o.sale_start_at??null,sale_end_at:o.sale_end_at??null,updated_at:i}).eq("sku",o.sku).in("product_id",d);if(m)throw m}}async function C(e,{page:t=1,limit:r=10,search:i="",languageId:c,categoryId:s}={}){const a=(t-1)*r,d=a+r-1;let n=e.from("products").select("id, title, average_rating, total_reviews, sku, upc, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at, is_taxable, product_type, payment_provider, short_description, stock, status, slug, language_id, translation_group_id, freemius_product_id, freemius_plan_id, trial_period_days, trial_requires_payment_method, product_media(media(file_path, object_key)), product_variants(id, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at), freemius_plans(id, name, title, freemius_pricing(id, license_quota, api_monthly_price, api_annual_price, api_lifetime_price, override_monthly_price, override_annual_price, override_lifetime_price, is_active)), product_categories(category:categories(id, name, slug, description, name_translations, description_translations))",{count:"exact"}).range(a,d).order("created_at",{ascending:!1});if(c&&(n=n.eq("language_id",c)),s){const{data:_,error:l}=await e.from("product_categories").select("product_id").eq("category_id",s);if(l)return{data:[],error:l,count:0};const u=(_||[]).map(o=>o.product_id).filter(Boolean);if(u.length===0)return{data:[],error:null,count:0};n=n.in("id",u)}return i&&(n=n.or(`title.ilike.%${i}%,sku.ilike.%${i}%`)),n}async function M(e,t){return e.from("products").select(`
|
|
2
2
|
*,
|
|
3
3
|
languages (
|
|
4
4
|
code
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
description_translations
|
|
167
167
|
)
|
|
168
168
|
)
|
|
169
|
-
`).eq("slug",t);if(c)return{data:null,error:c};if(!i||i.length===0)return{data:null,error:{message:"Product not found",code:"PGRST116"}};let s=null;return r&&(s=i.find(a=>(Array.isArray(a.languages)?a.languages[0]:a.languages)?.code===r)),s||(s=i.find(a=>(Array.isArray(a.languages)?a.languages[0]:a.languages)?.is_default)),s||(s=i.find(a=>(Array.isArray(a.languages)?a.languages[0]:a.languages)?.code==="en")),s||(s=i[0]),{data:s,error:null}}async function A(e,t){const{data:r,error:i}=await e.rpc("upsert_product_with_variants",{product_payload:j(t)});if(i||!r)throw i||new Error("Failed to create product");if(t.product_media&&t.product_media.length>0){const s=t.product_media.map((a,d)=>({product_id:r,media_id:a.media_id,sort_order:d}));await e.from("product_media").insert(s)}else t.media_id&&await e.from("product_media").insert({product_id:r,media_id:t.media_id,sort_order:0});await S(e,r,t.is_taxable),await x(e,r,t),await P.syncSharedInventoryForSavedProduct(r,t),t.category_ids!==void 0&&await
|
|
169
|
+
`).eq("slug",t);if(c)return{data:null,error:c};if(!i||i.length===0)return{data:null,error:{message:"Product not found",code:"PGRST116"}};let s=null;return r&&(s=i.find(a=>(Array.isArray(a.languages)?a.languages[0]:a.languages)?.code===r)),s||(s=i.find(a=>(Array.isArray(a.languages)?a.languages[0]:a.languages)?.is_default)),s||(s=i.find(a=>(Array.isArray(a.languages)?a.languages[0]:a.languages)?.code==="en")),s||(s=i[0]),{data:s,error:null}}async function A(e,t){const{data:r,error:i}=await e.rpc("upsert_product_with_variants",{product_payload:j(t)});if(i||!r)throw i||new Error("Failed to create product");if(t.product_media&&t.product_media.length>0){const s=t.product_media.map((a,d)=>({product_id:r,media_id:a.media_id,sort_order:d}));await e.from("product_media").insert(s)}else t.media_id&&await e.from("product_media").insert({product_id:r,media_id:t.media_id,sort_order:0});await S(e,r,t.is_taxable),await x(e,r,t),await P.syncSharedInventoryForSavedProduct(r,t),t.category_ids!==void 0&&await v(e,r,t.category_ids);const{data:c}=await e.from("products").select("*").eq("id",r).single();return c}async function R(e,t,r){const{data:i}=await e.from("product_media").select("media_id").eq("product_id",t),c=i?.map(o=>o.media_id)||[],{data:s,error:a}=await e.rpc("upsert_product_with_variants",{product_payload:j(r,t)});if(a||!s)throw a||new Error("Failed to update product");if(r.product_media){if(await e.from("product_media").delete().eq("product_id",t),r.product_media.length>0){const o=r.product_media.map((p,m)=>({product_id:t,media_id:p.media_id,sort_order:m}));await e.from("product_media").insert(o)}}else r.media_id&&(await e.from("product_media").delete().eq("product_id",t),await e.from("product_media").insert({product_id:t,media_id:r.media_id,sort_order:0}));await S(e,s,r.is_taxable),await x(e,s,r);const d=r.product_media?r.product_media.map(o=>o.media_id):r.media_id?[r.media_id]:[],n=r.explicitly_removed_media_ids||[],_=c.filter(o=>!d.includes(o)),l=Array.from(new Set([..._,...n]));if(l.length>0)for(const o of l){const{count:p}=await e.from("product_media").select("*",{count:"exact",head:!0}).eq("media_id",o);if(p&&p>0)continue;const{count:m}=await e.from("posts").select("*",{count:"exact",head:!0}).eq("feature_image_id",o);if(m&&m>0)continue;const{count:h}=await e.from("logos").select("*",{count:"exact",head:!0}).eq("media_id",o);if(h&&h>0)continue;const{count:w}=await e.from("product_variants").select("*",{count:"exact",head:!0}).eq("main_media_id",o);if(w&&w>0)continue;const{data:f}=await e.from("media").select("object_key, variants").eq("id",o).single();if(f){const q=[f.object_key];f.variants&&Array.isArray(f.variants)&&f.variants.forEach(k=>{k.objectKey&&q.push(k.objectKey)}),await F.deleteMediaFiles(q),await e.from("media").delete().eq("id",o)}}await P.syncSharedInventoryForSavedProduct(s,r),r.category_ids!==void 0&&await v(e,t,r.category_ids);const{data:u}=await e.from("products").select("*").eq("id",s).single();return u}async function I(e,t){const{error:r}=await e.from("products").delete().eq("id",t);if(r)throw r;return!0}async function N(e,t,r){const{data:i,error:c}=await e.from("products").select("*").eq("id",r).single();if(c||!i)throw new Error(c?.message||"Source product not found");const{data:s,error:a}=await e.from("products").select("language_id").eq("id",t).single();if(a||!s)throw new Error(a?.message||"Target product not found");const{error:d}=await e.from("products").update({title:i.title,short_description:i.short_description,description_json:i.description_json}).eq("id",t);if(d)throw d;const{data:n,error:_}=await e.from("blocks").select("*").eq("product_id",r).order("order",{ascending:!0});if(_)throw _;if(await e.from("blocks").delete().eq("product_id",t),n&&n.length>0){const u=n.map(p=>{const{id:m,created_at:h,updated_at:w,...f}=p;return{...f,product_id:t,language_id:s.language_id}}),{error:o}=await e.from("blocks").insert(u);if(o)throw o}await e.from("product_drafts").delete().eq("product_id",t),await e.from("product_media").delete().eq("product_id",t);const{data:l}=await e.from("product_media").select("media_id, sort_order").eq("product_id",r);if(l&&l.length>0){const u=l.map(o=>({product_id:t,media_id:o.media_id,sort_order:o.sort_order}));await e.from("product_media").insert(u)}return{success:!0}}async function $(e,t,r,i=[],c=[]){const{data:s}=await e.from("languages").select("id").eq("code",r).single();if(!s)return{data:[],error:"Language not found"};const a=[];t.length>0&&a.push(`translation_group_id.in.(${t.join(",")})`),i.length>0&&a.push(`sku.in.(${i.map(_=>`"${_}"`).join(",")})`),c.length>0&&a.push(`id.in.(${c.join(",")})`);let d=e.from("products").select(`
|
|
170
170
|
id,
|
|
171
171
|
title,
|
|
172
172
|
sku,
|
|
@@ -234,4 +234,4 @@
|
|
|
234
234
|
)
|
|
235
235
|
),
|
|
236
236
|
translation_group_id
|
|
237
|
-
`).eq("language_id",s.id).eq("status","active");return a.length>0&&(d=d.or(a.join(","))),await d.order("id")}async function
|
|
237
|
+
`).eq("language_id",s.id).eq("status","active");return a.length>0&&(d=d.or(a.join(","))),await d.order("id")}async function v(e,t,r){const{data:i}=await e.from("products").select("translation_group_id").eq("id",t).single();if(!i||!i.translation_group_id){if(await e.from("product_categories").delete().eq("product_id",t),r.length>0){const a=r.map(d=>({product_id:t,category_id:d}));await e.from("product_categories").insert(a)}return}const{data:c}=await e.from("products").select("id").eq("translation_group_id",i.translation_group_id),s=c&&c.length>0?c.map(a=>a.id):[t];if(await e.from("product_categories").delete().in("product_id",s),r.length>0){const a=[];for(const d of s)for(const n of r)a.push({product_id:d,category_id:n});await e.from("product_categories").insert(a)}}exports.copyProductFromLanguage=N;exports.createProduct=A;exports.deleteProduct=I;exports.fetchTranslatedProductsForCartInternal=$;exports.getProduct=M;exports.getProductBySlug=T;exports.getProducts=C;exports.syncCategoriesForTranslationGroup=v;exports.updateProduct=R;
|
package/lib/product-actions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
import { Database } from '../../../db/src/
|
|
2
|
+
import { Database } from '../../../db/src/lib/supabase/types.ts';
|
|
3
3
|
import { ProductFormValues } from './product-schema';
|
|
4
4
|
export declare function getProducts(supabase: SupabaseClient<Database>, { page, limit, search, languageId, categoryId, }?: {
|
|
5
5
|
page?: number;
|
|
@@ -10,6 +10,8 @@ export declare function getProducts(supabase: SupabaseClient<Database>, { page,
|
|
|
10
10
|
}): Promise<import('@supabase/postgrest-js').PostgrestResponseFailure | import('@supabase/postgrest-js').PostgrestResponseSuccess<{
|
|
11
11
|
id: string;
|
|
12
12
|
title: string;
|
|
13
|
+
average_rating: number;
|
|
14
|
+
total_reviews: number;
|
|
13
15
|
sku: string;
|
|
14
16
|
upc: string | null;
|
|
15
17
|
price: number;
|
|
@@ -88,6 +90,7 @@ export declare function getProducts(supabase: SupabaseClient<Database>, { page,
|
|
|
88
90
|
count: number;
|
|
89
91
|
}>;
|
|
90
92
|
export declare function getProduct(supabase: SupabaseClient<Database>, id: string): Promise<import('@supabase/postgrest-js').PostgrestSingleResponse<{
|
|
93
|
+
average_rating: number;
|
|
91
94
|
created_at: string | null;
|
|
92
95
|
description_json: import('../../../db/src/index.ts').Json | null;
|
|
93
96
|
freemius_plan_id: string | null;
|
|
@@ -115,6 +118,7 @@ export declare function getProduct(supabase: SupabaseClient<Database>, id: strin
|
|
|
115
118
|
status: string;
|
|
116
119
|
stock: number | null;
|
|
117
120
|
title: string;
|
|
121
|
+
total_reviews: number;
|
|
118
122
|
translation_group_id: string;
|
|
119
123
|
trial_period_days: number;
|
|
120
124
|
trial_requires_payment_method: boolean;
|
|
@@ -210,6 +214,7 @@ export declare function getProductBySlug(supabase: SupabaseClient<Database>, slu
|
|
|
210
214
|
error: null;
|
|
211
215
|
}>;
|
|
212
216
|
export declare function createProduct(supabase: SupabaseClient<Database>, data: ProductFormValues): Promise<{
|
|
217
|
+
average_rating: number;
|
|
213
218
|
created_at: string | null;
|
|
214
219
|
description_json: import('../../../db/src/index.ts').Json | null;
|
|
215
220
|
freemius_plan_id: string | null;
|
|
@@ -237,6 +242,7 @@ export declare function createProduct(supabase: SupabaseClient<Database>, data:
|
|
|
237
242
|
status: string;
|
|
238
243
|
stock: number | null;
|
|
239
244
|
title: string;
|
|
245
|
+
total_reviews: number;
|
|
240
246
|
translation_group_id: string;
|
|
241
247
|
trial_period_days: number;
|
|
242
248
|
trial_requires_payment_method: boolean;
|
|
@@ -244,6 +250,7 @@ export declare function createProduct(supabase: SupabaseClient<Database>, data:
|
|
|
244
250
|
updated_at: string | null;
|
|
245
251
|
} | null>;
|
|
246
252
|
export declare function updateProduct(supabase: SupabaseClient<Database>, id: string, data: ProductFormValues): Promise<{
|
|
253
|
+
average_rating: number;
|
|
247
254
|
created_at: string | null;
|
|
248
255
|
description_json: import('../../../db/src/index.ts').Json | null;
|
|
249
256
|
freemius_plan_id: string | null;
|
|
@@ -271,6 +278,7 @@ export declare function updateProduct(supabase: SupabaseClient<Database>, id: st
|
|
|
271
278
|
status: string;
|
|
272
279
|
stock: number | null;
|
|
273
280
|
title: string;
|
|
281
|
+
total_reviews: number;
|
|
274
282
|
translation_group_id: string;
|
|
275
283
|
trial_period_days: number;
|
|
276
284
|
trial_requires_payment_method: boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { deleteMediaFiles as b } from "@nextblock-cms/utils/server";
|
|
2
|
-
import { syncSharedInventoryForSavedProduct as
|
|
3
|
-
import { normalizeCurrencyCode as E } from "@nextblock-cms/utils";
|
|
2
|
+
import { syncSharedInventoryForSavedProduct as k } from "./shared-inventory.es.js";
|
|
3
|
+
import { normalizeCurrencyCode as E } from "@nextblock-cms/utils/utils";
|
|
4
4
|
const g = (e) => Math.round(e * 100);
|
|
5
5
|
function h(e) {
|
|
6
6
|
return Object.entries(e || {}).reduce(
|
|
@@ -105,7 +105,7 @@ async function R(e, {
|
|
|
105
105
|
} = {}) {
|
|
106
106
|
const a = (t - 1) * i, d = a + i - 1;
|
|
107
107
|
let n = e.from("products").select(
|
|
108
|
-
"id, title, sku, upc, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at, is_taxable, product_type, payment_provider, short_description, stock, status, slug, language_id, translation_group_id, freemius_product_id, freemius_plan_id, trial_period_days, trial_requires_payment_method, product_media(media(file_path, object_key)), product_variants(id, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at), freemius_plans(id, name, title, freemius_pricing(id, license_quota, api_monthly_price, api_annual_price, api_lifetime_price, override_monthly_price, override_annual_price, override_lifetime_price, is_active)), product_categories(category:categories(id, name, slug, description, name_translations, description_translations))",
|
|
108
|
+
"id, title, average_rating, total_reviews, sku, upc, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at, is_taxable, product_type, payment_provider, short_description, stock, status, slug, language_id, translation_group_id, freemius_product_id, freemius_plan_id, trial_period_days, trial_requires_payment_method, product_media(media(file_path, object_key)), product_variants(id, price, prices, sale_price, sale_prices, sale_start_at, sale_end_at, scheduled_price, scheduled_prices, scheduled_price_at), freemius_plans(id, name, title, freemius_pricing(id, license_quota, api_monthly_price, api_annual_price, api_lifetime_price, override_monthly_price, override_annual_price, override_lifetime_price, is_active)), product_categories(category:categories(id, name, slug, description, name_translations, description_translations))",
|
|
109
109
|
{ count: "exact" }
|
|
110
110
|
).range(a, d).order("created_at", { ascending: !1 });
|
|
111
111
|
if (c && (n = n.eq("language_id", c)), s) {
|
|
@@ -320,7 +320,7 @@ async function $(e, t) {
|
|
|
320
320
|
media_id: t.media_id,
|
|
321
321
|
sort_order: 0
|
|
322
322
|
});
|
|
323
|
-
await x(e, i, t.is_taxable), await P(e, i, t), await
|
|
323
|
+
await x(e, i, t.is_taxable), await P(e, i, t), await k(i, t), t.category_ids !== void 0 && await S(e, i, t.category_ids);
|
|
324
324
|
const { data: c } = await e.from("products").select("*").eq("id", i).single();
|
|
325
325
|
return c;
|
|
326
326
|
}
|
|
@@ -358,12 +358,12 @@ async function D(e, t, i) {
|
|
|
358
358
|
const { data: f } = await e.from("media").select("object_key, variants").eq("id", o).single();
|
|
359
359
|
if (f) {
|
|
360
360
|
const q = [f.object_key];
|
|
361
|
-
f.variants && Array.isArray(f.variants) && f.variants.forEach((
|
|
362
|
-
|
|
361
|
+
f.variants && Array.isArray(f.variants) && f.variants.forEach((v) => {
|
|
362
|
+
v.objectKey && q.push(v.objectKey);
|
|
363
363
|
}), await b(q), await e.from("media").delete().eq("id", o);
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
|
-
await
|
|
366
|
+
await k(s, i), i.category_ids !== void 0 && await S(e, t, i.category_ids);
|
|
367
367
|
const { data: u } = await e.from("products").select("*").eq("id", s).single();
|
|
368
368
|
return u;
|
|
369
369
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SupabaseClient } from '@supabase/supabase-js';
|
|
2
|
-
import { Database } from '../../../db/src/
|
|
2
|
+
import { Database } from '../../../db/src/lib/supabase/types.ts';
|
|
3
3
|
import { ProductFormValues } from './product-schema';
|
|
4
4
|
export type InventoryUsageType = 'product' | 'variant' | 'mixed';
|
|
5
5
|
export interface InventoryItem {
|
package/lib/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextblock-cms/ecom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@nextblock-cms/db": "^0.
|
|
14
|
-
"@nextblock-cms/ui": "^0.
|
|
15
|
-
"@nextblock-cms/utils": "^0.
|
|
13
|
+
"@nextblock-cms/db": "^0.11.2",
|
|
14
|
+
"@nextblock-cms/ui": "^0.11.2",
|
|
15
|
+
"@nextblock-cms/utils": "^0.11.2",
|
|
16
16
|
"@freemius/checkout": "^1.4.1",
|
|
17
17
|
"@freemius/sdk": "^0.3.0",
|
|
18
18
|
"@hookform/resolvers": "^5.2.2",
|