@nextblock-cms/ecom 0.8.1 → 0.8.6
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/AddToCartButton-DsSEH9yp.cjs +1 -0
- package/AddToCartButton-ffE0DhHu.js +59 -0
- package/CouponForm-BI_5SBHQ.js +152 -0
- package/CouponForm-D_uu2bLP.cjs +1 -0
- package/CurrencyProvider-Cg-Q6ucj.cjs +1 -0
- package/CurrencyProvider-OzlRN96V.js +120 -0
- package/CurrencyProvider.cjs.js +1 -0
- package/CurrencyProvider.es.js +10 -0
- package/ProductDetailsLayout-BxJH_BxR.cjs +1 -0
- package/ProductDetailsLayout-Dg8dRTYp.js +530 -0
- package/ProductGrid-BdL7iglO.cjs +1 -0
- package/ProductGrid-D3AWM8sr.js +130 -0
- package/actions-AHmBrS5e.cjs +48 -0
- package/actions-j5fuSZX-.js +820 -0
- package/cart-store.cjs.js +1 -0
- package/cart-store.es.js +116 -0
- package/components/Cart.cjs.js +1 -0
- package/components/Cart.es.js +259 -0
- package/components/CartDrawer.cjs.js +1 -0
- package/components/CartDrawer.es.js +118 -0
- package/components/CartIcon.cjs.js +1 -0
- package/components/CartIcon.es.js +33 -0
- package/components/Checkout.cjs.js +1 -0
- package/components/Checkout.es.js +1020 -0
- package/components/CurrencySwitcher.cjs.js +1 -0
- package/components/CurrencySwitcher.es.js +17 -0
- package/components/FeaturedProduct.cjs.js +1 -0
- package/components/FeaturedProduct.es.js +71 -0
- package/components/ProductDetailsLayout.cjs.js +1 -0
- package/components/ProductDetailsLayout.es.js +19 -0
- package/components/ProductGrid.cjs.js +1 -0
- package/components/ProductGrid.es.js +6 -0
- package/components/SimpleTiptapRenderer.cjs.js +1 -0
- package/components/SimpleTiptapRenderer.es.js +187 -0
- package/coupon-server-C9ySm3I5.cjs +1 -0
- package/coupon-server-DUKVtyYs.js +248 -0
- package/currency-constants.cjs.js +1 -0
- package/currency-constants.es.js +4 -0
- package/currency.cjs.js +1 -0
- package/currency.es.js +312 -0
- package/customer-C-UPvrYN.cjs +1 -0
- package/customer-C3xccjUg.js +57 -0
- package/index.cjs.js +1 -1
- package/index.es.js +414 -3105
- package/invoice-ui-CAnJPu6n.cjs +29 -0
- package/invoice-ui-DtpbTJE1.js +2886 -0
- package/package.json +10 -5
- package/product-actions-CONBF8i6.cjs +251 -0
- package/product-actions-DjlIWCMH.js +691 -0
- package/resolver-Fz_FKsfX.cjs +7 -0
- package/resolver-cfrCaHpE.js +128 -0
- package/server-actions/product-actions.cjs.js +1 -0
- package/server-actions/product-actions.es.js +15 -0
- package/server.cjs.js +27 -27
- package/server.es.js +478 -463
- package/shipping-actions-BnHjlo2q.js +25 -0
- package/shipping-actions-D6zt20gg.cjs +1 -0
- package/states-CWYRxV4B.cjs +1 -0
- package/states-DlHJezQ1.js +200 -0
- package/tax-calculation-Dab89aHd.js +181 -0
- package/tax-calculation-MkDKOEkL.cjs +1 -0
- package/trials-DvZaOtNy.cjs +1 -0
- package/trials-RDcRAZKx.js +29 -0
- package/types.cjs.js +1 -0
- package/types.es.js +33 -0
- package/use-cart.cjs.js +1 -0
- package/use-cart.es.js +43 -0
- package/variation-utils.cjs.js +1 -0
- package/variation-utils.es.js +246 -0
- package/invoice-ui-BJZfedDd.cjs +0 -332
- package/invoice-ui-GJ1ADAjn.js +0 -5759
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const i=require("react/jsx-runtime"),a=require("@nextblock-cms/ui/button"),_=require("lucide-react"),o=require("sonner"),v=require("next/link"),y=require("./use-cart.cjs.js"),q=require("@nextblock-cms/utils"),l=require("./types.cjs.js"),C=require("./CurrencyProvider-Cg-Q6ucj.cjs"),f=({product:e,className:t,quantity:c})=>{const n=y.useCart(s=>s),{t:r}=q.useTranslations(),{activeCurrencyCode:d}=C.useCurrency();if(!!e.has_variants&&!e.variant_id&&!l.isDigitalProduct(e))return i.jsx(a.Button,{asChild:!0,className:t,children:i.jsx(v,{href:`/product/${e.slug}`,children:"Select Options"})});if(!n)return i.jsxs(a.Button,{disabled:!0,className:t,children:[i.jsx(_.ShoppingCart,{className:"mr-2 h-4 w-4"}),r("ecommerce.add_to_cart")]});const{addItem:u}=n,m=()=>{const s=l.getProductPaymentProvider(e)??"stripe",{success:h,error:g}=u({id:e.variant_id||e.id,product_id:e.id,title:e.title,price:e.price,prices:e.prices,sale_price:e.sale_price,sale_prices:e.sale_prices,is_taxable:e.is_taxable,image_url:e.image_url,slug:e.slug,sku:e.sku,stock:e.stock,language_id:e.language_id,translation_group_id:e.translation_group_id,product_type:e.product_type,payment_provider:e.payment_provider??s,provider:s,freemius_product_id:e.freemius_product_id,freemius_plan_id:e.freemius_plan_id,trial_period_days:e.trial_period_days??0,trial_requires_payment_method:e.trial_requires_payment_method??!1,has_variants:e.has_variants,variant_id:e.variant_id,variant_label:e.variant_label,selected_options:e.selected_options,currency_code:d,quantity:c});h?o.toast.success(r("ecommerce.added_to_cart_success",{item:e.title})):o.toast.error(g||r("ecommerce.added_to_cart_error"))};return i.jsxs(a.Button,{onClick:m,className:t,children:[i.jsx(_.ShoppingCart,{className:"mr-2 h-4 w-4"}),r("ecommerce.add_to_cart")]})};exports.AddToCartButton=f;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as a, jsxs as n } from "react/jsx-runtime";
|
|
2
|
+
import { Button as t } from "@nextblock-cms/ui/button";
|
|
3
|
+
import { ShoppingCart as o } from "lucide-react";
|
|
4
|
+
import { toast as l } from "sonner";
|
|
5
|
+
import p from "next/link";
|
|
6
|
+
import { useCart as g } from "./use-cart.es.js";
|
|
7
|
+
import { useTranslations as u } from "@nextblock-cms/utils";
|
|
8
|
+
import { isDigitalProduct as v, getProductPaymentProvider as y } from "./types.es.js";
|
|
9
|
+
import { u as C } from "./CurrencyProvider-OzlRN96V.js";
|
|
10
|
+
const V = ({ product: e, className: s, quantity: m }) => {
|
|
11
|
+
const _ = g((r) => r), { t: i } = u(), { activeCurrencyCode: d } = C();
|
|
12
|
+
if (!!e.has_variants && !e.variant_id && !v(e))
|
|
13
|
+
return /* @__PURE__ */ a(t, { asChild: !0, className: s, children: /* @__PURE__ */ a(p, { href: `/product/${e.slug}`, children: "Select Options" }) });
|
|
14
|
+
if (!_)
|
|
15
|
+
return /* @__PURE__ */ n(t, { disabled: !0, className: s, children: [
|
|
16
|
+
/* @__PURE__ */ a(o, { className: "mr-2 h-4 w-4" }),
|
|
17
|
+
i("ecommerce.add_to_cart")
|
|
18
|
+
] });
|
|
19
|
+
const { addItem: c } = _;
|
|
20
|
+
return /* @__PURE__ */ n(t, { onClick: () => {
|
|
21
|
+
const r = y(e) ?? "stripe", { success: f, error: h } = c({
|
|
22
|
+
id: e.variant_id || e.id,
|
|
23
|
+
product_id: e.id,
|
|
24
|
+
title: e.title,
|
|
25
|
+
price: e.price,
|
|
26
|
+
prices: e.prices,
|
|
27
|
+
sale_price: e.sale_price,
|
|
28
|
+
sale_prices: e.sale_prices,
|
|
29
|
+
is_taxable: e.is_taxable,
|
|
30
|
+
image_url: e.image_url,
|
|
31
|
+
slug: e.slug,
|
|
32
|
+
sku: e.sku,
|
|
33
|
+
stock: e.stock,
|
|
34
|
+
language_id: e.language_id,
|
|
35
|
+
translation_group_id: e.translation_group_id,
|
|
36
|
+
product_type: e.product_type,
|
|
37
|
+
payment_provider: e.payment_provider ?? r,
|
|
38
|
+
provider: r,
|
|
39
|
+
freemius_product_id: e.freemius_product_id,
|
|
40
|
+
// include just in case it wasn't intercepted
|
|
41
|
+
freemius_plan_id: e.freemius_plan_id,
|
|
42
|
+
trial_period_days: e.trial_period_days ?? 0,
|
|
43
|
+
trial_requires_payment_method: e.trial_requires_payment_method ?? !1,
|
|
44
|
+
has_variants: e.has_variants,
|
|
45
|
+
variant_id: e.variant_id,
|
|
46
|
+
variant_label: e.variant_label,
|
|
47
|
+
selected_options: e.selected_options,
|
|
48
|
+
currency_code: d,
|
|
49
|
+
quantity: m
|
|
50
|
+
});
|
|
51
|
+
f ? l.success(i("ecommerce.added_to_cart_success", { item: e.title })) : l.error(h || i("ecommerce.added_to_cart_error"));
|
|
52
|
+
}, className: s, children: [
|
|
53
|
+
/* @__PURE__ */ a(o, { className: "mr-2 h-4 w-4" }),
|
|
54
|
+
i("ecommerce.add_to_cart")
|
|
55
|
+
] });
|
|
56
|
+
};
|
|
57
|
+
export {
|
|
58
|
+
V as A
|
|
59
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { jsxs as l, jsx as c } from "react/jsx-runtime";
|
|
2
|
+
import { useState as h, useRef as E, useMemo as k, useCallback as N, useEffect as R } from "react";
|
|
3
|
+
import { Badge as S } from "@nextblock-cms/ui/badge";
|
|
4
|
+
import { Button as T } from "@nextblock-cms/ui/button";
|
|
5
|
+
import { Input as z } from "@nextblock-cms/ui/input";
|
|
6
|
+
import { Label as B } from "@nextblock-cms/ui/label";
|
|
7
|
+
import { Tag as D, X as V } from "lucide-react";
|
|
8
|
+
import { useTranslations as L, formatPrice as M } from "@nextblock-cms/utils";
|
|
9
|
+
import { a as O, n as I } from "./coupon-server-DUKVtyYs.js";
|
|
10
|
+
import { useCart as A } from "./use-cart.es.js";
|
|
11
|
+
import { getServiceRoleSupabaseClient as P } from "@nextblock-cms/db/server";
|
|
12
|
+
async function U(o) {
|
|
13
|
+
try {
|
|
14
|
+
const r = P();
|
|
15
|
+
return await O({
|
|
16
|
+
client: r,
|
|
17
|
+
code: o.code,
|
|
18
|
+
items: Array.isArray(o.items) ? o.items : [],
|
|
19
|
+
currencyCode: o.currencyCode
|
|
20
|
+
});
|
|
21
|
+
} catch (r) {
|
|
22
|
+
return console.error("Failed to validate coupon:", r), {
|
|
23
|
+
success: !1,
|
|
24
|
+
error: r.message || "Failed to validate coupon.",
|
|
25
|
+
errorKey: "ecommerce.coupon_validation_failed"
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function re({
|
|
30
|
+
items: o,
|
|
31
|
+
currencyCode: r,
|
|
32
|
+
onQuoteChange: a,
|
|
33
|
+
compact: b = !1
|
|
34
|
+
}) {
|
|
35
|
+
const f = A((e) => e.appliedCoupon), p = A((e) => e.setAppliedCoupon), s = A((e) => e.removeCoupon), { t: _ } = L(), [x, q] = h(""), [i, d] = h(null), [w, u] = h(""), [F, K] = h(!1), y = E(null), $ = k(
|
|
36
|
+
() => o.map((e) => `${e.product_id}:${e.variant_id || "base"}:${e.quantity}`).sort().join("|"),
|
|
37
|
+
[o]
|
|
38
|
+
), n = N((e, C) => {
|
|
39
|
+
const m = _(e);
|
|
40
|
+
return m === e ? C : m;
|
|
41
|
+
}, [_]), v = N(
|
|
42
|
+
(e) => `${I(e)}:${r}:${$}`,
|
|
43
|
+
[$, r]
|
|
44
|
+
), g = N(async (e, C) => {
|
|
45
|
+
const m = I(e);
|
|
46
|
+
if (!m) {
|
|
47
|
+
u(n("ecommerce.coupon_code_required", "Enter a coupon code."));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
K(!0), u("");
|
|
51
|
+
try {
|
|
52
|
+
const t = await U({
|
|
53
|
+
code: m,
|
|
54
|
+
items: o,
|
|
55
|
+
currencyCode: r
|
|
56
|
+
});
|
|
57
|
+
if (!t.success) {
|
|
58
|
+
d(null), a?.(null), s?.(), u(t.errorKey ? n(t.errorKey, t.error) : t.error);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
y.current = v(t.quote.code), d(t.quote), a?.(t.quote), C?.silent || (p?.({
|
|
62
|
+
code: t.quote.code,
|
|
63
|
+
couponId: t.quote.couponId
|
|
64
|
+
}), q("")), C?.silent || u("");
|
|
65
|
+
} catch (t) {
|
|
66
|
+
console.error("Failed to validate coupon:", t), d(null), a?.(null), u(
|
|
67
|
+
n("ecommerce.coupon_validation_failed", "Failed to validate coupon.")
|
|
68
|
+
);
|
|
69
|
+
} finally {
|
|
70
|
+
K(!1);
|
|
71
|
+
}
|
|
72
|
+
}, [
|
|
73
|
+
s,
|
|
74
|
+
r,
|
|
75
|
+
v,
|
|
76
|
+
o,
|
|
77
|
+
a,
|
|
78
|
+
p,
|
|
79
|
+
n
|
|
80
|
+
]);
|
|
81
|
+
if (R(() => {
|
|
82
|
+
if (!p || !s)
|
|
83
|
+
return;
|
|
84
|
+
if (!f || o.length === 0) {
|
|
85
|
+
y.current = null, d(null), a?.(null);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const e = v(f.code);
|
|
89
|
+
y.current !== e && (y.current = e, g(f.code, { silent: !0 }));
|
|
90
|
+
}, [
|
|
91
|
+
f?.code,
|
|
92
|
+
g,
|
|
93
|
+
s,
|
|
94
|
+
v,
|
|
95
|
+
o.length,
|
|
96
|
+
a,
|
|
97
|
+
p
|
|
98
|
+
]), !p || !s)
|
|
99
|
+
return null;
|
|
100
|
+
const j = () => {
|
|
101
|
+
s(), d(null), a?.(null), u("");
|
|
102
|
+
};
|
|
103
|
+
return /* @__PURE__ */ l("div", { className: b ? "space-y-2" : "rounded-lg border bg-muted/10 p-4 space-y-3", children: [
|
|
104
|
+
/* @__PURE__ */ l("div", { className: "flex items-center justify-between gap-3", children: [
|
|
105
|
+
/* @__PURE__ */ l(B, { htmlFor: b ? "coupon-code-compact" : "coupon-code", className: "flex items-center gap-2 text-sm font-medium", children: [
|
|
106
|
+
/* @__PURE__ */ c(D, { className: "h-4 w-4" }),
|
|
107
|
+
n("ecommerce.coupon", "Coupon")
|
|
108
|
+
] }),
|
|
109
|
+
i ? /* @__PURE__ */ l(S, { variant: "secondary", className: "gap-1", children: [
|
|
110
|
+
i.code,
|
|
111
|
+
/* @__PURE__ */ c("button", { type: "button", onClick: j, "aria-label": `Remove coupon ${i.code}`, children: /* @__PURE__ */ c(V, { className: "h-3 w-3" }) })
|
|
112
|
+
] }) : null
|
|
113
|
+
] }),
|
|
114
|
+
i ? /* @__PURE__ */ l("div", { className: "flex items-center justify-between text-sm", children: [
|
|
115
|
+
/* @__PURE__ */ c("span", { className: "text-muted-foreground", children: i.name }),
|
|
116
|
+
/* @__PURE__ */ l("span", { className: "font-medium text-emerald-600", children: [
|
|
117
|
+
"-",
|
|
118
|
+
M(i.discountTotal, r)
|
|
119
|
+
] })
|
|
120
|
+
] }) : /* @__PURE__ */ l("div", { className: "flex gap-2", children: [
|
|
121
|
+
/* @__PURE__ */ c(
|
|
122
|
+
z,
|
|
123
|
+
{
|
|
124
|
+
id: b ? "coupon-code-compact" : "coupon-code",
|
|
125
|
+
value: x,
|
|
126
|
+
onChange: (e) => q(e.target.value.toUpperCase()),
|
|
127
|
+
placeholder: n("ecommerce.coupon_placeholder", "Code"),
|
|
128
|
+
className: "uppercase",
|
|
129
|
+
onKeyDown: (e) => {
|
|
130
|
+
e.key === "Enter" && (e.preventDefault(), g(x));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
/* @__PURE__ */ c(
|
|
135
|
+
T,
|
|
136
|
+
{
|
|
137
|
+
type: "button",
|
|
138
|
+
variant: "outline",
|
|
139
|
+
disabled: F || o.length === 0,
|
|
140
|
+
onClick: () => {
|
|
141
|
+
g(x);
|
|
142
|
+
},
|
|
143
|
+
children: F ? n("ecommerce.applying", "Applying...") : n("ecommerce.apply", "Apply")
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
] }),
|
|
147
|
+
w ? /* @__PURE__ */ c("p", { className: "text-xs text-destructive", children: w }) : null
|
|
148
|
+
] });
|
|
149
|
+
}
|
|
150
|
+
export {
|
|
151
|
+
re as C
|
|
152
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const o=require("react/jsx-runtime"),s=require("react"),$=require("@nextblock-cms/ui/badge"),k=require("@nextblock-cms/ui/button"),I=require("@nextblock-cms/ui/input"),E=require("@nextblock-cms/ui/label"),w=require("lucide-react"),K=require("@nextblock-cms/utils"),j=require("./coupon-server-C9ySm3I5.cjs"),q=require("./use-cart.cjs.js"),z=require("@nextblock-cms/db/server");async function T(t){try{const n=z.getServiceRoleSupabaseClient();return await j.getCouponQuote({client:n,code:t.code,items:Array.isArray(t.items)?t.items:[],currencyCode:t.currencyCode})}catch(n){return console.error("Failed to validate coupon:",n),{success:!1,error:n.message||"Failed to validate coupon.",errorKey:"ecommerce.coupon_validation_failed"}}}function B({items:t,currencyCode:n,onQuoteChange:a,compact:b=!1}){const f=q.useCart(e=>e.appliedCoupon),d=q.useCart(e=>e.setAppliedCoupon),l=q.useCart(e=>e.removeCoupon),{t:h}=K.useTranslations(),[g,N]=s.useState(""),[u,p]=s.useState(null),[A,i]=s.useState(""),[_,F]=s.useState(!1),v=s.useRef(null),S=s.useMemo(()=>t.map(e=>`${e.product_id}:${e.variant_id||"base"}:${e.quantity}`).sort().join("|"),[t]),c=s.useCallback((e,C)=>{const m=h(e);return m===e?C:m},[h]),y=s.useCallback(e=>`${j.normalizeCouponCode(e)}:${n}:${S}`,[S,n]),x=s.useCallback(async(e,C)=>{const m=j.normalizeCouponCode(e);if(!m){i(c("ecommerce.coupon_code_required","Enter a coupon code."));return}F(!0),i("");try{const r=await T({code:m,items:t,currencyCode:n});if(!r.success){p(null),a?.(null),l?.(),i(r.errorKey?c(r.errorKey,r.error):r.error);return}v.current=y(r.quote.code),p(r.quote),a?.(r.quote),C?.silent||(d?.({code:r.quote.code,couponId:r.quote.couponId}),N("")),C?.silent||i("")}catch(r){console.error("Failed to validate coupon:",r),p(null),a?.(null),i(c("ecommerce.coupon_validation_failed","Failed to validate coupon."))}finally{F(!1)}},[l,n,y,t,a,d,c]);if(s.useEffect(()=>{if(!d||!l)return;if(!f||t.length===0){v.current=null,p(null),a?.(null);return}const e=y(f.code);v.current!==e&&(v.current=e,x(f.code,{silent:!0}))},[f?.code,x,l,y,t.length,a,d]),!d||!l)return null;const R=()=>{l(),p(null),a?.(null),i("")};return o.jsxs("div",{className:b?"space-y-2":"rounded-lg border bg-muted/10 p-4 space-y-3",children:[o.jsxs("div",{className:"flex items-center justify-between gap-3",children:[o.jsxs(E.Label,{htmlFor:b?"coupon-code-compact":"coupon-code",className:"flex items-center gap-2 text-sm font-medium",children:[o.jsx(w.Tag,{className:"h-4 w-4"}),c("ecommerce.coupon","Coupon")]}),u?o.jsxs($.Badge,{variant:"secondary",className:"gap-1",children:[u.code,o.jsx("button",{type:"button",onClick:R,"aria-label":`Remove coupon ${u.code}`,children:o.jsx(w.X,{className:"h-3 w-3"})})]}):null]}),u?o.jsxs("div",{className:"flex items-center justify-between text-sm",children:[o.jsx("span",{className:"text-muted-foreground",children:u.name}),o.jsxs("span",{className:"font-medium text-emerald-600",children:["-",K.formatPrice(u.discountTotal,n)]})]}):o.jsxs("div",{className:"flex gap-2",children:[o.jsx(I.Input,{id:b?"coupon-code-compact":"coupon-code",value:g,onChange:e=>N(e.target.value.toUpperCase()),placeholder:c("ecommerce.coupon_placeholder","Code"),className:"uppercase",onKeyDown:e=>{e.key==="Enter"&&(e.preventDefault(),x(g))}}),o.jsx(k.Button,{type:"button",variant:"outline",disabled:_||t.length===0,onClick:()=>{x(g)},children:_?c("ecommerce.applying","Applying..."):c("ecommerce.apply","Apply")})]}),A?o.jsx("p",{className:"text-xs text-destructive",children:A}):null]})}exports.CouponForm=B;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const E=require("react/jsx-runtime"),c=require("react"),f=require("@nextblock-cms/utils"),l=require("./currency.cjs.js"),P=require("zustand"),z=require("zustand/middleware"),q=require("./currency-constants.cjs.js"),y=P.create()(z.persist(r=>({activeCurrencyCode:null,hasHydrated:!1,setActiveCurrencyCode:e=>r({activeCurrencyCode:f.normalizeCurrencyCode(e)}),setHasHydrated:e=>r({hasHydrated:e})}),{name:"currency-preference-storage",storage:z.createJSONStorage(()=>localStorage),skipHydration:!0,partialize:r=>({activeCurrencyCode:r.activeCurrencyCode}),onRehydrateStorage:()=>r=>{r?.setHasHydrated(!0)}})),H=c.createContext(null);function x(r){return l.sortCurrencies(r.filter(e=>e.is_active!==!1))}function A(r){const{currencies:e,storedCurrencyCode:i,hasHydrated:m,initialCurrencyCode:n,locale:v}=r,u=new Set(e.map(C=>f.normalizeCurrencyCode(C.code))),a=l.getDefaultCurrency(e),s=n?f.normalizeCurrencyCode(n):null,t=i?f.normalizeCurrencyCode(i):null;if(m&&t&&u.has(t))return t;if(s&&u.has(s))return s;const d=l.inferCurrencyCodeFromLocale(v,e);return u.has(d)?d:a.code}function R({children:r,initialCurrencies:e,initialCurrencyCode:i,locale:m}){const[n,v]=c.useState(()=>x(e)),u=y(o=>o.activeCurrencyCode),a=y(o=>o.hasHydrated),s=y(o=>o.setActiveCurrencyCode);c.useEffect(()=>{y.persist.rehydrate()},[]),c.useEffect(()=>{e.length>0&&v(x(e))},[e]),c.useEffect(()=>{if(e.length>0)return;async function o(){const{fetchActiveCurrenciesFromRest:h}=await Promise.resolve().then(()=>require("./currency-rest-client-uolJxUkL.cjs")),g=await h();g.length>0&&v(x(g.map(S=>l.normalizeCurrencyRecord(S))))}o()},[e.length]);const t=c.useMemo(()=>A({currencies:n,storedCurrencyCode:u,hasHydrated:a,initialCurrencyCode:i,locale:m}),[n,u,a,i,m]);c.useEffect(()=>{t&&u!==t&&s(t)},[t,s,u]),c.useEffect(()=>{!t||typeof document>"u"||(document.cookie=`${q.CURRENCY_COOKIE_NAME}=${t}; Path=/; Max-Age=31536000; SameSite=Lax`)},[t]);const d=c.useMemo(()=>l.getDefaultCurrency(n),[n]),C=c.useMemo(()=>n.find(o=>o.code===t)??d,[n,d,t]),p=c.useMemo(()=>({currencies:n,defaultCurrency:d,activeCurrency:C,activeCurrencyCode:C.code,isHydrated:a,setActiveCurrencyCode:o=>{const h=f.normalizeCurrencyCode(o);n.some(S=>S.code===h)&&s(h)}}),[C,n,d,a,s]);return E.jsx(H.Provider,{value:p,children:r})}function w(){const r=c.useContext(H);if(!r)throw new Error("useCurrency must be used inside a CurrencyProvider");return r}exports.CurrencyProvider=R;exports.useCurrency=w;exports.useCurrencyPreferenceStore=y;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { jsx as P } from "react/jsx-runtime";
|
|
2
|
+
import { createContext as w, useState as z, useEffect as C, useMemo as v, useContext as E } from "react";
|
|
3
|
+
import { normalizeCurrencyCode as f } from "@nextblock-cms/utils";
|
|
4
|
+
import { getDefaultCurrency as S, sortCurrencies as R, normalizeCurrencyRecord as M, inferCurrencyCodeFromLocale as N } from "./currency.es.js";
|
|
5
|
+
import { create as O } from "zustand";
|
|
6
|
+
import { persist as _, createJSONStorage as k } from "zustand/middleware";
|
|
7
|
+
import { CURRENCY_COOKIE_NAME as F } from "./currency-constants.es.js";
|
|
8
|
+
const p = O()(
|
|
9
|
+
_(
|
|
10
|
+
(r) => ({
|
|
11
|
+
activeCurrencyCode: null,
|
|
12
|
+
hasHydrated: !1,
|
|
13
|
+
setActiveCurrencyCode: (e) => r({ activeCurrencyCode: f(e) }),
|
|
14
|
+
setHasHydrated: (e) => r({ hasHydrated: e })
|
|
15
|
+
}),
|
|
16
|
+
{
|
|
17
|
+
name: "currency-preference-storage",
|
|
18
|
+
storage: k(() => localStorage),
|
|
19
|
+
skipHydration: !0,
|
|
20
|
+
partialize: (r) => ({
|
|
21
|
+
activeCurrencyCode: r.activeCurrencyCode
|
|
22
|
+
}),
|
|
23
|
+
onRehydrateStorage: () => (r) => {
|
|
24
|
+
r?.setHasHydrated(!0);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
), H = w(null);
|
|
29
|
+
function x(r) {
|
|
30
|
+
return R(
|
|
31
|
+
r.filter((e) => e.is_active !== !1)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
function L(r) {
|
|
35
|
+
const { currencies: e, storedCurrencyCode: a, hasHydrated: y, initialCurrencyCode: o, locale: m } = r, c = new Set(
|
|
36
|
+
e.map((i) => f(i.code))
|
|
37
|
+
), d = S(e), s = o ? f(o) : null, t = a ? f(a) : null;
|
|
38
|
+
if (y && t && c.has(t))
|
|
39
|
+
return t;
|
|
40
|
+
if (s && c.has(s))
|
|
41
|
+
return s;
|
|
42
|
+
const u = N(m, e);
|
|
43
|
+
return c.has(u) ? u : d.code;
|
|
44
|
+
}
|
|
45
|
+
function U({
|
|
46
|
+
children: r,
|
|
47
|
+
initialCurrencies: e,
|
|
48
|
+
initialCurrencyCode: a,
|
|
49
|
+
locale: y
|
|
50
|
+
}) {
|
|
51
|
+
const [o, m] = z(
|
|
52
|
+
() => x(e)
|
|
53
|
+
), c = p(
|
|
54
|
+
(n) => n.activeCurrencyCode
|
|
55
|
+
), d = p((n) => n.hasHydrated), s = p(
|
|
56
|
+
(n) => n.setActiveCurrencyCode
|
|
57
|
+
);
|
|
58
|
+
C(() => {
|
|
59
|
+
p.persist.rehydrate();
|
|
60
|
+
}, []), C(() => {
|
|
61
|
+
e.length > 0 && m(x(e));
|
|
62
|
+
}, [e]), C(() => {
|
|
63
|
+
if (e.length > 0)
|
|
64
|
+
return;
|
|
65
|
+
async function n() {
|
|
66
|
+
const { fetchActiveCurrenciesFromRest: l } = await import("./currency-rest-client-CwoqdgAP.js"), h = await l();
|
|
67
|
+
h.length > 0 && m(
|
|
68
|
+
x(h.map((g) => M(g)))
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
n();
|
|
72
|
+
}, [e.length]);
|
|
73
|
+
const t = v(
|
|
74
|
+
() => L({
|
|
75
|
+
currencies: o,
|
|
76
|
+
storedCurrencyCode: c,
|
|
77
|
+
hasHydrated: d,
|
|
78
|
+
initialCurrencyCode: a,
|
|
79
|
+
locale: y
|
|
80
|
+
}),
|
|
81
|
+
[o, c, d, a, y]
|
|
82
|
+
);
|
|
83
|
+
C(() => {
|
|
84
|
+
t && c !== t && s(t);
|
|
85
|
+
}, [t, s, c]), C(() => {
|
|
86
|
+
!t || typeof document > "u" || (document.cookie = `${F}=${t}; Path=/; Max-Age=31536000; SameSite=Lax`);
|
|
87
|
+
}, [t]);
|
|
88
|
+
const u = v(
|
|
89
|
+
() => S(o),
|
|
90
|
+
[o]
|
|
91
|
+
), i = v(
|
|
92
|
+
() => o.find((n) => n.code === t) ?? u,
|
|
93
|
+
[o, u, t]
|
|
94
|
+
), A = v(
|
|
95
|
+
() => ({
|
|
96
|
+
currencies: o,
|
|
97
|
+
defaultCurrency: u,
|
|
98
|
+
activeCurrency: i,
|
|
99
|
+
activeCurrencyCode: i.code,
|
|
100
|
+
isHydrated: d,
|
|
101
|
+
setActiveCurrencyCode: (n) => {
|
|
102
|
+
const l = f(n);
|
|
103
|
+
o.some((g) => g.code === l) && s(l);
|
|
104
|
+
}
|
|
105
|
+
}),
|
|
106
|
+
[i, o, u, d, s]
|
|
107
|
+
);
|
|
108
|
+
return /* @__PURE__ */ P(H.Provider, { value: A, children: r });
|
|
109
|
+
}
|
|
110
|
+
function V() {
|
|
111
|
+
const r = E(H);
|
|
112
|
+
if (!r)
|
|
113
|
+
throw new Error("useCurrency must be used inside a CurrencyProvider");
|
|
114
|
+
return r;
|
|
115
|
+
}
|
|
116
|
+
export {
|
|
117
|
+
U as C,
|
|
118
|
+
p as a,
|
|
119
|
+
V as u
|
|
120
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require("react/jsx-runtime");require("react");require("@nextblock-cms/utils");require("./currency.cjs.js");const r=require("./CurrencyProvider-Cg-Q6ucj.cjs");require("./currency-constants.cjs.js");exports.CurrencyProvider=r.CurrencyProvider;exports.useCurrency=r.useCurrency;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "react/jsx-runtime";
|
|
2
|
+
import "react";
|
|
3
|
+
import "@nextblock-cms/utils";
|
|
4
|
+
import "./currency.es.js";
|
|
5
|
+
import { C as u, u as s } from "./CurrencyProvider-OzlRN96V.js";
|
|
6
|
+
import "./currency-constants.es.js";
|
|
7
|
+
export {
|
|
8
|
+
u as CurrencyProvider,
|
|
9
|
+
s as useCurrency
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const e=require("react/jsx-runtime"),d=require("react"),M=require("lucide-react"),V=require("@nextblock-cms/ui/badge"),J=require("@nextblock-cms/ui/button"),se=require("@nextblock-cms/ui/label"),ne=require("@nextblock-cms/ui/separator"),p=require("@nextblock-cms/utils"),ie=require("./AddToCartButton-DsSEH9yp.cjs"),D=require("@nextblock-cms/ui/Skeleton"),ae=require("./use-cart.cjs.js"),F=require("sonner"),le=require("./actions-AHmBrS5e.cjs"),G=require("./CurrencyProvider-Cg-Q6ucj.cjs"),A=require("./currency.cjs.js"),K=require("./trials-DvZaOtNy.cjs"),ce=require("./components/SimpleTiptapRenderer.cjs.js"),S=require("./variation-utils.cjs.js"),oe=require("./types.cjs.js"),X=({images:r=[],className:m})=>{const[t,c]=d.useState(0);return d.useEffect(()=>{c(0)},[r]),r.length?e.jsxs("div",{className:p.cn("flex flex-col gap-4",m),children:[e.jsx("div",{className:"relative aspect-square w-full overflow-hidden rounded-lg border bg-white",children:e.jsx("img",{src:r[t].url,alt:r[t].alt,className:"h-full w-full object-cover object-center"})}),r.length>1&&e.jsx("div",{className:"flex gap-4 overflow-x-auto pb-2",children:r.map((f,l)=>e.jsx("button",{onClick:()=>c(l),className:p.cn("relative aspect-square w-20 flex-shrink-0 overflow-hidden rounded-md border",t===l?"ring-2 ring-primary":"ring-1 ring-transparent hover:ring-primary/50"),children:e.jsx("img",{src:f.url,alt:f.alt,className:"h-full w-full object-cover object-center"})},l))})]}):e.jsx("div",{className:p.cn("relative aspect-square w-full overflow-hidden rounded-lg bg-secondary",m),children:e.jsx("div",{className:"flex h-full items-center justify-center text-muted-foreground",children:"No Image"})})},z=({product:r})=>{const m=ae.useCart(o=>o),{t}=p.useTranslations(),{activeCurrencyCode:c,currencies:f,defaultCurrency:l}=G.useCurrency(),[L,_]=d.useState([]),[T,E]=d.useState(!0),[a,v]=d.useState("annual");if(d.useEffect(()=>{async function o(){try{if(!r.id)return;const s=await le.getPublicFreemiusPricing(r.id);_(s)}catch(s){console.error("Failed to load pricing:",s)}finally{E(!1)}}o()},[r.id]),!m)return e.jsx(D.Skeleton,{className:"h-14 w-full"});const{addItem:y}=m,N=L[0],n=N?.pricing?.[0],b=()=>{let o=r.price,s=r.freemius_plan_id;n&&(a==="monthly"&&n.monthly_price!=null&&(o=p.majorUnitAmountToMinor(n.monthly_price,l.code)),a==="annual"&&n.annual_price!=null&&(o=p.majorUnitAmountToMinor(n.annual_price,l.code)),a==="lifetime"&&n.lifetime_price!=null&&(o=p.majorUnitAmountToMinor(n.lifetime_price,l.code)));const q=f.reduce((u,U)=>(u[U.code]=A.convertMinorUnitAmount({amount:o,fromCurrencyCode:l.code,toCurrencyCode:U.code,currencies:f,applyRounding:!0}),u),{}),I=q[c]??o;N&&N.id&&(s=N.id);const{success:P,error:k}=y({id:r.id,product_id:r.id,title:r.title,price:I,prices:q,image_url:r.image_url,slug:r.slug,sku:r.sku,language_id:r.language_id,translation_group_id:r.translation_group_id,product_type:"digital",payment_provider:"freemius",provider:"freemius",billing_cycle:a,freemius_product_id:r.freemius_product_id,freemius_plan_id:s,trial_period_days:r.trial_period_days??0,trial_requires_payment_method:r.trial_requires_payment_method??!1,is_taxable:r.is_taxable,currency_code:c});P?F.toast.success(t("ecommerce.added_to_cart_success",{item:r.title})):F.toast.error(k||t("ecommerce.added_to_cart_error"))};if(T)return e.jsx(D.Skeleton,{className:"h-32 w-full"});if(!N||!n)return e.jsx("div",{className:"p-4 border border-dashed rounded-lg text-center text-muted-foreground",children:t("ecommerce.pricing_unavailable")});const g=n.monthly_price!=null,w=n.annual_price!=null,R=n.lifetime_price!=null;a==="annual"&&!w&&(g?v("monthly"):R&&v("lifetime"));const h=K.getTrialSummary(r);let C=r.price;return a==="monthly"&&n.monthly_price!=null&&(C=A.convertMinorUnitAmount({amount:p.majorUnitAmountToMinor(n.monthly_price,l.code),fromCurrencyCode:l.code,toCurrencyCode:c,currencies:f,applyRounding:!0})),a==="annual"&&n.annual_price!=null&&(C=A.convertMinorUnitAmount({amount:p.majorUnitAmountToMinor(n.annual_price,l.code),fromCurrencyCode:l.code,toCurrencyCode:c,currencies:f,applyRounding:!0})),a==="lifetime"&&n.lifetime_price!=null&&(C=A.convertMinorUnitAmount({amount:p.majorUnitAmountToMinor(n.lifetime_price,l.code),fromCurrencyCode:l.code,toCurrencyCode:c,currencies:f,applyRounding:!0})),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"flex bg-secondary/35 p-1 rounded-lg w-full max-w-sm mx-auto shadow-inner",children:[g&&e.jsx("button",{onClick:()=>v("monthly"),className:`flex-1 py-1.5 text-xs font-semibold rounded-md transition-all ${a==="monthly"?"bg-background shadow-sm text-foreground":"text-muted-foreground hover:text-foreground"}`,children:t("ecommerce.monthly")}),w&&e.jsx("button",{onClick:()=>v("annual"),className:`flex-1 py-1.5 text-xs font-semibold rounded-md transition-all ${a==="annual"?"bg-background shadow-sm text-foreground":"text-muted-foreground hover:text-foreground"}`,children:t("ecommerce.annual")}),R&&e.jsx("button",{onClick:()=>v("lifetime"),className:`flex-1 py-1.5 text-xs font-semibold rounded-md transition-all ${a==="lifetime"?"bg-background shadow-sm text-foreground":"text-muted-foreground hover:text-foreground"}`,children:t("ecommerce.lifetime")})]}),e.jsxs("div",{className:"text-center",children:[e.jsx("span",{className:"text-3xl font-extrabold text-foreground",children:p.formatPrice(C,c)}),a!=="lifetime"&&e.jsxs("span",{className:"text-muted-foreground text-sm ml-1.5",children:["/ ",t(a==="annual"?"ecommerce.year":"ecommerce.month")]}),h&&e.jsxs("div",{className:"mt-1 text-xs font-medium text-emerald-600 dark:text-emerald-400",children:[h.label,e.jsx("span",{className:"mx-2 text-muted-foreground/50",children:"|"}),e.jsx("span",{className:"text-muted-foreground",children:h.paymentRequirementLabel})]})]}),e.jsxs(J.Button,{onClick:b,className:"w-full h-12 text-md font-bold shadow-md transition-all hover:shadow-lg active:scale-[0.98]",children:[e.jsx(M.ShoppingCart,{className:"mr-2 h-4 w-4"}),h?.label?`Start ${h.label}`:t("ecommerce.get_license")]})]})},W=d.createContext(void 0),de=({product:r,children:m})=>e.jsx(W.Provider,{value:{product:r},children:m}),H=()=>{const r=d.useContext(W);if(!r)throw new Error("useProduct must be used within a ProductProvider. Ensure the component is wrapped in a ProductProvider.");return r.product};function O(r,m,t,c){const f={kind:"product-field",field:m,input:t,label:c},l=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 _=(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{(_.startsWith("http://")||_.startsWith("https://"))&&(_=new URL(_).hostname)}catch{}const T=process.env.NEXTBLOCK_VERCEL_PROJECT_ID||process.env.VERCEL_PROJECT_ID,E=process.env.NEXTBLOCK_VERCEL_WORKSPACE_ID||process.env.VERCEL_ORG_ID,a={origin:_,editUrl:`${l}/cms/products/${r.id}/edit`,data:{parentType:"product",parentId:r.id,slug:r.slug,languageId:r.language_id,draftId:null,target:f}};return T&&(a.projectId=T),E&&(a.workspaceId=E),{"data-vercel-edit-info":JSON.stringify(a),"data-vercel-edit-target":JSON.stringify(f),"data-nextblock-visual-edit":`product:${m}`}}const ue=({visualEditingEnabled:r=!1,descriptionNode:m})=>{const t=H(),{t:c,lang:f}=p.useTranslations(),{activeCurrencyCode:l,currencies:L}=G.useCurrency(),_=r?O(t,"title","plain-text","Product title"):void 0,T=r?O(t,"short_description","plain-text","Short description"):void 0,E=r?O(t,"description_json","tiptap","Product description"):void 0,a=(i,j,x)=>{const B=c(i,x);return B===i?j:B},v=t.images&&t.images.length>0?t.images:t.image_url?[{url:t.image_url,alt:t.title}]:[],y=t.custom_props?.provider==="freemius"||oe.isDigitalProduct(t),N=K.getTrialSummary(t),n=!y&&!!(t.has_variants&&t.attributes?.length&&t.variants?.length),b=t.attributes||[],g=t.variants||[],[w,R]=d.useState(()=>S.chooseInitialVariantSelections(b,g)),[h,C]=d.useState(1);d.useEffect(()=>{C(1)},[t.id]),d.useEffect(()=>{n&&R(S.chooseInitialVariantSelections(b,g))},[b,n,t.id,g]);const o=d.useMemo(()=>n?S.normalizeSelectionsToAvailableVariants(b,g,w):w,[b,n,w,g]);d.useEffect(()=>{JSON.stringify(o)!==JSON.stringify(w)&&R(o)},[o,w]);const s=d.useMemo(()=>n?S.findMatchingVariant(g,o):null,[n,o,g]),q=A.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:l,currencies:L}),I=n&&s?A.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:L}):null,P=I?.price??q.price,k=I?.sale_price??q.sale_price,u=n?s?.stock_quantity??0:t.stock??0,U=d.useMemo(()=>{if(!s?.image_url)return v;const i={url:s.image_url,alt:`${t.title} ${s.label}`},j=v.filter(x=>x.url!==s.image_url);return[i,...j]},[v,t.title,s]),Q=typeof k=="number"&&P>0?Math.round((P-k)/P*100):0,Y=n&&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:l}:{...t,currency_code:l},Z=(i,j)=>{R(x=>S.normalizeSelectionsToAvailableVariants(b,g,{...x,[i]:j}))},ee=a("ecommerce.in_stock",`${u} in stock`,{count:String(u)}),$=a("ecommerce.out_of_stock","Out of stock"),te=a("ecommerce.select_options","Select Options"),re=a("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(X,{images:U,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",..._,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((i,j)=>{const x=S.resolveTranslatedText(i.name,i.name_translations,f);return e.jsxs(d.Fragment,{children:[j>0&&e.jsx("span",{className:"text-muted-foreground/30",children:"•"}),e.jsx("span",{children:x})]},i.id)})}),e.jsx("div",{className:"prose prose-neutral dark:prose-invert max-w-none text-muted-foreground leading-relaxed text-left",...T,children:t.short_description?e.jsx("div",{className:"text-lg mb-4 leading-relaxed",dangerouslySetInnerHTML:{__html:t.short_description}}):r?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 k=="number"&&e.jsx(V.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(Q)})}),!y&&u>0&&u<10&&e.jsx(V.Badge,{variant:"outline",className:"text-amber-600 border-amber-200 bg-amber-50",children:c("ecommerce.low_stock",{count:String(u)})}),N&&e.jsx(V.Badge,{variant:"secondary",className:"border border-emerald-200 bg-emerald-50 text-emerald-800",children:N.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:[y?e.jsx(z,{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:a("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:p.formatPrice(k??P,l)}),typeof k=="number"&&e.jsx("span",{className:"text-lg text-muted-foreground line-through decoration-destructive/20 decoration-1",children:p.formatPrice(P,l)})]})]}),!y&&(s||!n)&&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:[!n&&t.sku&&e.jsxs("span",{className:"mr-2 font-normal lowercase normal-case text-muted-foreground/70",children:["SKU: ",t.sku]}),a("ecommerce.status","Status")]}),e.jsx("div",{className:(u??0)>0?"text-emerald-600 dark:text-emerald-400 font-semibold text-sm":"text-destructive font-semibold text-sm",children:(u??0)>0?ee:$})]})]}),n&&e.jsx("div",{className:"space-y-3",children:e.jsx("div",{className:"grid gap-3 sm:grid-cols-2",children:b.map(i=>{const j=S.getAvailableTermIdsForAttribute(g,i.id,o);return e.jsxs("div",{className:"space-y-1",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(se.Label,{htmlFor:`attribute-${i.id}`,className:"text-[11px] font-semibold text-muted-foreground uppercase tracking-wider",children:i.name}),s?.sku&&e.jsx("span",{className:"text-[10px] text-muted-foreground font-mono",children:s.sku})]}),e.jsx("select",{id:`attribute-${i.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:o[i.id]||"",onChange:x=>Z(i.id,x.target.value),children:i.terms.map(x=>e.jsx("option",{value:x.id,disabled:!j.has(x.id),children:x.value},x.id))})]},i.id)})})}),n&&!s&&e.jsx("p",{className:"text-xs text-muted-foreground italic pt-1",children:re}),e.jsxs("div",{className:"flex items-center gap-3 pt-1",children:[!y&&(u??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:()=>C(i=>Math.max(1,i-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:h<=1,children:"-"}),e.jsx("span",{className:"w-8 text-center text-sm font-semibold",children:h}),e.jsx("button",{type:"button",onClick:()=>C(i=>u!==null&&i>=u?i:i+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:u!==null&&h>=u,children:"+"})]}),n&&(!s||(u??0)<=0)?e.jsx(J.Button,{disabled:!0,className:"flex-1 h-12 text-md font-bold shadow-md",children:s?$:te}):e.jsx(ie.AddToCartButton,{product:Y,quantity:h,className:"flex-1 h-12 text-md font-bold shadow-md transition-all hover:shadow-lg active:scale-[0.98]"})]})]}),e.jsx(ne.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:y?e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx(M.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(M.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(M.ShieldCheck,{className:"h-3.5 w-3.5"}),c("ecommerce.secure_checkout")]})})]})]})]})]})}),e.jsx("div",{className:"min-w-0 w-full",...m?void 0:E,children:m||(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(ce.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")})}))})]})};exports.ProductDetailsLayout=ue;exports.ProductGallery=X;exports.ProductProvider=de;exports.SubscriptionSelector=z;exports.useProduct=H;
|