@rovela-ai/sdk 0.10.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/api/settings.d.ts.map +1 -1
- package/dist/admin/api/settings.js +15 -0
- package/dist/admin/api/settings.js.map +1 -1
- package/dist/admin/components/StoreSettings.d.ts.map +1 -1
- package/dist/admin/components/StoreSettings.js +28 -1
- package/dist/admin/components/StoreSettings.js.map +1 -1
- package/dist/admin/types.d.ts +2 -0
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/cart/components/AddToCartButton.d.ts +1 -1
- package/dist/cart/components/AddToCartButton.d.ts.map +1 -1
- package/dist/cart/components/AddToCartButton.js +4 -2
- package/dist/cart/components/AddToCartButton.js.map +1 -1
- package/dist/cart/components/CartDrawer.d.ts.map +1 -1
- package/dist/cart/components/CartDrawer.js +4 -2
- package/dist/cart/components/CartDrawer.js.map +1 -1
- package/dist/cart/components/CartIcon.d.ts.map +1 -1
- package/dist/cart/components/CartIcon.js +4 -2
- package/dist/cart/components/CartIcon.js.map +1 -1
- package/dist/cart/components/CartItem.d.ts.map +1 -1
- package/dist/cart/components/CartItem.js +3 -1
- package/dist/cart/components/CartItem.js.map +1 -1
- package/dist/cart/components/CartSummary.d.ts.map +1 -1
- package/dist/cart/components/CartSummary.js +6 -4
- package/dist/cart/components/CartSummary.js.map +1 -1
- package/dist/cart/components/QuantitySelector.d.ts.map +1 -1
- package/dist/cart/components/QuantitySelector.js +4 -2
- package/dist/cart/components/QuantitySelector.js.map +1 -1
- package/dist/checkout/components/CheckoutButton.d.ts.map +1 -1
- package/dist/checkout/components/CheckoutButton.js +4 -2
- package/dist/checkout/components/CheckoutButton.js.map +1 -1
- package/dist/checkout/components/CheckoutFlow.d.ts.map +1 -1
- package/dist/checkout/components/CheckoutFlow.js +42 -38
- package/dist/checkout/components/CheckoutFlow.js.map +1 -1
- package/dist/checkout/components/OrderSummary.d.ts.map +1 -1
- package/dist/checkout/components/OrderSummary.js +5 -2
- package/dist/checkout/components/OrderSummary.js.map +1 -1
- package/dist/checkout/components/ShippingForm.d.ts.map +1 -1
- package/dist/checkout/components/ShippingForm.js +28 -25
- package/dist/checkout/components/ShippingForm.js.map +1 -1
- package/dist/checkout/components/ShippingOptions.d.ts.map +1 -1
- package/dist/checkout/components/ShippingOptions.js +8 -5
- package/dist/checkout/components/ShippingOptions.js.map +1 -1
- package/dist/core/StoreSettingsProvider.d.ts +2 -0
- package/dist/core/StoreSettingsProvider.d.ts.map +1 -1
- package/dist/core/StoreSettingsProvider.js +4 -0
- package/dist/core/StoreSettingsProvider.js.map +1 -1
- package/dist/core/api/settings.d.ts +2 -0
- package/dist/core/api/settings.d.ts.map +1 -1
- package/dist/core/api/settings.js +4 -0
- package/dist/core/api/settings.js.map +1 -1
- package/dist/core/db/queries.d.ts +31 -27
- package/dist/core/db/queries.d.ts.map +1 -1
- package/dist/core/db/queries.js +12 -0
- package/dist/core/db/queries.js.map +1 -1
- package/dist/core/db/schema.d.ts +39 -1
- package/dist/core/db/schema.d.ts.map +1 -1
- package/dist/core/db/schema.js +8 -0
- package/dist/core/db/schema.js.map +1 -1
- package/dist/core/i18n/LanguageSwitcher.d.ts +7 -0
- package/dist/core/i18n/LanguageSwitcher.d.ts.map +1 -0
- package/dist/core/i18n/LanguageSwitcher.js +44 -0
- package/dist/core/i18n/LanguageSwitcher.js.map +1 -0
- package/dist/core/i18n/context.d.ts +27 -0
- package/dist/core/i18n/context.d.ts.map +1 -0
- package/dist/core/i18n/context.js +47 -0
- package/dist/core/i18n/context.js.map +1 -0
- package/dist/core/i18n/index.d.ts +19 -0
- package/dist/core/i18n/index.d.ts.map +1 -0
- package/dist/core/i18n/index.js +14 -0
- package/dist/core/i18n/index.js.map +1 -0
- package/dist/core/i18n/messages/en.d.ts +9 -0
- package/dist/core/i18n/messages/en.d.ts.map +1 -0
- package/dist/core/i18n/messages/en.js +135 -0
- package/dist/core/i18n/messages/en.js.map +1 -0
- package/dist/core/i18n/messages/fr.d.ts +10 -0
- package/dist/core/i18n/messages/fr.d.ts.map +1 -0
- package/dist/core/i18n/messages/fr.js +136 -0
- package/dist/core/i18n/messages/fr.js.map +1 -0
- package/dist/core/i18n/resolve.d.ts +64 -0
- package/dist/core/i18n/resolve.d.ts.map +1 -0
- package/dist/core/i18n/resolve.js +95 -0
- package/dist/core/i18n/resolve.js.map +1 -0
- package/dist/core/i18n/translate.d.ts +26 -0
- package/dist/core/i18n/translate.d.ts.map +1 -0
- package/dist/core/i18n/translate.js +46 -0
- package/dist/core/i18n/translate.js.map +1 -0
- package/dist/core/i18n/types.d.ts +46 -0
- package/dist/core/i18n/types.d.ts.map +1 -0
- package/dist/core/i18n/types.js +50 -0
- package/dist/core/i18n/types.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import Image from 'next/image';
|
|
|
4
4
|
import Link from 'next/link';
|
|
5
5
|
import { ImageIcon } from 'lucide-react';
|
|
6
6
|
import { cn, formatPrice } from '../../core/utils';
|
|
7
|
+
import { useT } from '../../core/i18n';
|
|
7
8
|
import { useStoreSettingsOptional } from '../../core/StoreSettingsProvider';
|
|
8
9
|
import { QuantitySelector } from './QuantitySelector';
|
|
9
10
|
/** Links to the product when an href is known, else renders a non-clickable
|
|
@@ -43,6 +44,7 @@ function ProductLink({ href, className, children, }) {
|
|
|
43
44
|
* ```
|
|
44
45
|
*/
|
|
45
46
|
export function CartItem({ item, onUpdateQuantity, onRemove, currency, locale, showRemove = true, showQuantity = true, maxQuantity = 99, productHref, className, compact = false, }) {
|
|
47
|
+
const t = useT();
|
|
46
48
|
// Get currency from context if not provided via props
|
|
47
49
|
const storeSettings = useStoreSettingsOptional();
|
|
48
50
|
const resolvedCurrency = currency ?? storeSettings?.currency ?? 'USD';
|
|
@@ -56,6 +58,6 @@ export function CartItem({ item, onUpdateQuantity, onRemove, currency, locale, s
|
|
|
56
58
|
const attributeText = item.attributes
|
|
57
59
|
? Object.values(item.attributes).join(' / ')
|
|
58
60
|
: null;
|
|
59
|
-
return (_jsxs("div", { className: cn('flex gap-4', compact ? 'py-3' : 'py-4', className), children: [_jsx(ProductLink, { href: href, className: cn('relative flex-shrink-0 overflow-hidden rounded-md bg-muted', compact ? 'h-16 w-16' : 'h-20 w-20'), children: item.image ? (_jsx(Image, { src: item.image, alt: item.name, fill: true, sizes: compact ? '64px' : '80px', className: "object-cover" })) : (_jsx("div", { className: "flex h-full w-full items-center justify-center text-muted-foreground", children: _jsx(ImageIcon, { className: cn(compact ? 'h-6 w-6' : 'h-8 w-8'), strokeWidth: 1 }) })) }), _jsxs("div", { className: "flex flex-1 flex-col justify-between", children: [_jsxs("div", { children: [_jsx(ProductLink, { href: href, className: cn('font-medium text-foreground transition-colors', href && 'hover:text-primary', compact ? 'text-sm line-clamp-1' : 'text-sm line-clamp-2'), children: item.name }), attributeText && (_jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: attributeText })), _jsxs("p", { className: cn('text-muted-foreground', compact ? 'mt-0.5 text-xs' : 'mt-1 text-sm'), children: [formatPrice(item.price, { currency: resolvedCurrency, locale: resolvedLocale }), item.quantity > 1 && ' each'] })] }), _jsxs("div", { className: cn('flex items-center justify-between', compact ? 'mt-2' : 'mt-3'), children: [showQuantity && onUpdateQuantity ? (_jsx(QuantitySelector, { value: item.quantity, onChange: onUpdateQuantity, min: 1, max: maxQuantity, size: compact ? 'sm' : 'md' })) : (_jsxs("span", { className: "text-sm text-muted-foreground", children: ["Qty: ", item.quantity] })), showRemove && onRemove && (_jsx("button", { type: "button", onClick: onRemove, className: cn('text-muted-foreground hover:text-destructive transition-colors', compact ? 'text-xs' : 'text-sm'), "aria-label":
|
|
61
|
+
return (_jsxs("div", { className: cn('flex gap-4', compact ? 'py-3' : 'py-4', className), children: [_jsx(ProductLink, { href: href, className: cn('relative flex-shrink-0 overflow-hidden rounded-md bg-muted', compact ? 'h-16 w-16' : 'h-20 w-20'), children: item.image ? (_jsx(Image, { src: item.image, alt: item.name, fill: true, sizes: compact ? '64px' : '80px', className: "object-cover" })) : (_jsx("div", { className: "flex h-full w-full items-center justify-center text-muted-foreground", children: _jsx(ImageIcon, { className: cn(compact ? 'h-6 w-6' : 'h-8 w-8'), strokeWidth: 1 }) })) }), _jsxs("div", { className: "flex flex-1 flex-col justify-between", children: [_jsxs("div", { children: [_jsx(ProductLink, { href: href, className: cn('font-medium text-foreground transition-colors', href && 'hover:text-primary', compact ? 'text-sm line-clamp-1' : 'text-sm line-clamp-2'), children: item.name }), attributeText && (_jsx("p", { className: "mt-0.5 text-xs text-muted-foreground", children: attributeText })), _jsxs("p", { className: cn('text-muted-foreground', compact ? 'mt-0.5 text-xs' : 'mt-1 text-sm'), children: [formatPrice(item.price, { currency: resolvedCurrency, locale: resolvedLocale }), item.quantity > 1 && ' each'] })] }), _jsxs("div", { className: cn('flex items-center justify-between', compact ? 'mt-2' : 'mt-3'), children: [showQuantity && onUpdateQuantity ? (_jsx(QuantitySelector, { value: item.quantity, onChange: onUpdateQuantity, min: 1, max: maxQuantity, size: compact ? 'sm' : 'md' })) : (_jsxs("span", { className: "text-sm text-muted-foreground", children: ["Qty: ", item.quantity] })), showRemove && onRemove && (_jsx("button", { type: "button", onClick: onRemove, className: cn('text-muted-foreground hover:text-destructive transition-colors', compact ? 'text-xs' : 'text-sm'), "aria-label": t('cart.removeItem', { name: item.name }), children: "Remove" }))] })] }), _jsx("div", { className: cn('flex-shrink-0 text-right', compact ? 'w-16' : 'w-20'), children: _jsx("span", { className: cn('font-medium text-foreground', compact ? 'text-sm' : 'text-base'), children: formatPrice(lineTotal, { currency: resolvedCurrency, locale: resolvedLocale }) }) })] }));
|
|
60
62
|
}
|
|
61
63
|
//# sourceMappingURL=CartItem.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartItem.js","sourceRoot":"","sources":["../../../src/cart/components/CartItem.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"CartItem.js","sourceRoot":"","sources":["../../../src/cart/components/CartItem.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartSummary.d.ts","sourceRoot":"","sources":["../../../src/cart/components/CartSummary.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CartSummary.d.ts","sourceRoot":"","sources":["../../../src/cart/components/CartSummary.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mBAAmB;IACnB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,YAAmB,EACnB,YAAmB,EACnB,OAAe,EACf,SAAgB,EAChB,SAAgB,EAChB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,OAAe,GAChB,EAAE,gBAAgB,2CA6GlB"}
|
|
@@ -6,6 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
6
6
|
* Cart summary component showing subtotal and optional estimates.
|
|
7
7
|
*/
|
|
8
8
|
import { cn, formatPrice } from '../../core/utils';
|
|
9
|
+
import { useT } from '../../core/i18n';
|
|
9
10
|
import { useStoreSettingsOptional } from '../../core/StoreSettingsProvider';
|
|
10
11
|
import { useCart } from '../store';
|
|
11
12
|
// =============================================================================
|
|
@@ -33,6 +34,7 @@ import { useCart } from '../store';
|
|
|
33
34
|
* ```
|
|
34
35
|
*/
|
|
35
36
|
export function CartSummary({ showShipping = true, shippingCost = null, showTax = false, taxAmount = null, showTotal = true, currency, locale, className, compact = false, }) {
|
|
37
|
+
const t = useT();
|
|
36
38
|
// Get currency from context if not provided via props
|
|
37
39
|
const storeSettings = useStoreSettingsOptional();
|
|
38
40
|
const resolvedCurrency = currency ?? storeSettings?.currency ?? 'USD';
|
|
@@ -47,13 +49,13 @@ export function CartSummary({ showShipping = true, shippingCost = null, showTax
|
|
|
47
49
|
? subtotal + (shippingCost || 0) + (taxAmount || 0)
|
|
48
50
|
: null;
|
|
49
51
|
const formatOptions = { currency: resolvedCurrency, locale: resolvedLocale };
|
|
50
|
-
return (_jsxs("div", { className: cn('space-y-2', className), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: cn('text-muted-foreground', compact ? 'text-sm' : 'text-base'), children:
|
|
52
|
+
return (_jsxs("div", { className: cn('space-y-2', className), children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: cn('text-muted-foreground', compact ? 'text-sm' : 'text-base'), children: t('common.subtotal') }), _jsx("span", { className: cn('font-medium text-foreground', compact ? 'text-sm' : 'text-base'), children: formatPrice(subtotal, formatOptions) })] }), showShipping && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: cn('text-muted-foreground', compact ? 'text-sm' : 'text-base'), children: "Shipping" }), _jsx("span", { className: cn('text-muted-foreground', compact ? 'text-sm' : 'text-base'), children: shippingCost !== null
|
|
51
53
|
? shippingCost === 0
|
|
52
|
-
? '
|
|
54
|
+
? t('common.free')
|
|
53
55
|
: formatPrice(shippingCost, formatOptions)
|
|
54
|
-
: '
|
|
56
|
+
: t('cart.calculatedAtCheckout') })] })), showTax && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: cn('text-muted-foreground', compact ? 'text-sm' : 'text-base'), children: "Tax" }), _jsx("span", { className: cn('text-muted-foreground', compact ? 'text-sm' : 'text-base'), children: taxAmount !== null
|
|
55
57
|
? formatPrice(taxAmount, formatOptions)
|
|
56
|
-
: '
|
|
58
|
+
: t('cart.calculatedAtCheckout') })] })), showTotal && (_jsxs(_Fragment, { children: [_jsx("div", { className: "my-3 border-t border-border" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: cn('font-medium text-foreground', compact ? 'text-base' : 'text-lg'), children: hasAllValues ? t('common.total') : t('cart.estimatedTotal') }), _jsx("span", { className: cn('font-semibold text-foreground', compact ? 'text-base' : 'text-lg'), children: total !== null
|
|
57
59
|
? formatPrice(total, formatOptions)
|
|
58
60
|
: formatPrice(subtotal, formatOptions) })] }), !hasAllValues && (_jsx("p", { className: "text-xs text-muted-foreground text-right", children: "Shipping and taxes calculated at checkout" }))] }))] }));
|
|
59
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartSummary.js","sourceRoot":"","sources":["../../../src/cart/components/CartSummary.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;GAIG;AAEH,OAAO,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAA;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AA2BlC,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,YAAY,GAAG,IAAI,EACnB,YAAY,GAAG,IAAI,EACnB,OAAO,GAAG,KAAK,EACf,SAAS,GAAG,IAAI,EAChB,SAAS,GAAG,IAAI,EAChB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,OAAO,GAAG,KAAK,GACE;IACjB,sDAAsD;IACtD,MAAM,aAAa,GAAG,wBAAwB,EAAE,CAAA;IAChD,MAAM,gBAAgB,GAAG,QAAQ,IAAI,aAAa,EAAE,QAAQ,IAAI,KAAK,CAAA;IACrE,MAAM,cAAc,GAAG,MAAM,IAAI,aAAa,EAAE,MAAM,IAAI,OAAO,CAAA;IAEjE,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACjC,gCAAgC;QAChC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAC/E,CAAC,CAAC,CAAA;IAEF,0CAA0C;IAC1C,MAAM,YAAY,GAAG,YAAY,KAAK,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;IAC9E,MAAM,KAAK,GAAG,YAAY;QACxB,CAAC,CAAC,QAAQ,GAAG,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC;QACnD,CAAC,CAAC,IAAI,CAAA;IAER,MAAM,aAAa,GAAG,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAE5E,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,aAExC,eAAK,SAAS,EAAC,mCAAmC,aAChD,eAAM,SAAS,EAAE,EAAE,CACjB,uBAAuB,EACvB,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAClC,
|
|
1
|
+
{"version":3,"file":"CartSummary.js","sourceRoot":"","sources":["../../../src/cart/components/CartSummary.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuantitySelector.d.ts","sourceRoot":"","sources":["../../../src/cart/components/QuantitySelector.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QuantitySelector.d.ts","sourceRoot":"","sources":["../../../src/cart/components/QuantitySelector.tsx"],"names":[],"mappings":"AAiBA,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,qCAAqC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mBAAmB;IACnB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACzB,uBAAuB;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,mCAAmC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,EACR,GAAO,EACP,GAAQ,EACR,QAAgB,EAChB,IAAW,EACX,SAAS,EACT,SAAS,GACV,EAAE,qBAAqB,2CAgIvB"}
|
|
@@ -8,6 +8,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
import { useCallback } from 'react';
|
|
9
9
|
import { Minus, Plus } from 'lucide-react';
|
|
10
10
|
import { cn } from '../../core/utils';
|
|
11
|
+
import { useT } from '../../core/i18n';
|
|
11
12
|
// =============================================================================
|
|
12
13
|
// Component
|
|
13
14
|
// =============================================================================
|
|
@@ -30,7 +31,8 @@ import { cn } from '../../core/utils';
|
|
|
30
31
|
* }
|
|
31
32
|
* ```
|
|
32
33
|
*/
|
|
33
|
-
export function QuantitySelector({ value, onChange, min = 1, max = 99, disabled = false, size = 'md', className, ariaLabel
|
|
34
|
+
export function QuantitySelector({ value, onChange, min = 1, max = 99, disabled = false, size = 'md', className, ariaLabel, }) {
|
|
35
|
+
const t = useT();
|
|
34
36
|
const handleDecrement = useCallback(() => {
|
|
35
37
|
if (value > min && !disabled) {
|
|
36
38
|
onChange(value - 1);
|
|
@@ -80,6 +82,6 @@ export function QuantitySelector({ value, onChange, min = 1, max = 99, disabled
|
|
|
80
82
|
const classes = sizeClasses[size];
|
|
81
83
|
const isAtMin = value <= min;
|
|
82
84
|
const isAtMax = value >= max;
|
|
83
|
-
return (_jsxs("div", { className: cn('inline-flex items-center rounded-md border border-border', disabled && 'opacity-50', className), role: "group", "aria-label": ariaLabel, children: [_jsx("button", { type: "button", onClick: handleDecrement, disabled: disabled || isAtMin, className: cn('flex items-center justify-center text-muted-foreground transition-colors', 'hover:text-foreground hover:bg-muted', 'disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset', 'rounded-l-md', classes.button), "aria-label": "Decrease quantity", children: _jsx(Minus, { className: classes.icon }) }), _jsx("input", { type: "number", value: value, onChange: handleInputChange, onKeyDown: handleKeyDown, disabled: disabled, min: min, max: max, className: cn('border-x border-border bg-transparent text-center focus:outline-none', 'disabled:cursor-not-allowed', '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none', classes.container, classes.input), "aria-label": ariaLabel }), _jsx("button", { type: "button", onClick: handleIncrement, disabled: disabled || isAtMax, className: cn('flex items-center justify-center text-muted-foreground transition-colors', 'hover:text-foreground hover:bg-muted', 'disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset', 'rounded-r-md', classes.button), "aria-label": "Increase quantity", children: _jsx(Plus, { className: classes.icon }) })] }));
|
|
85
|
+
return (_jsxs("div", { className: cn('inline-flex items-center rounded-md border border-border', disabled && 'opacity-50', className), role: "group", "aria-label": ariaLabel ?? t('cart.quantity'), children: [_jsx("button", { type: "button", onClick: handleDecrement, disabled: disabled || isAtMin, className: cn('flex items-center justify-center text-muted-foreground transition-colors', 'hover:text-foreground hover:bg-muted', 'disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset', 'rounded-l-md', classes.button), "aria-label": "Decrease quantity", children: _jsx(Minus, { className: classes.icon }) }), _jsx("input", { type: "number", value: value, onChange: handleInputChange, onKeyDown: handleKeyDown, disabled: disabled, min: min, max: max, className: cn('border-x border-border bg-transparent text-center focus:outline-none', 'disabled:cursor-not-allowed', '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none', classes.container, classes.input), "aria-label": ariaLabel ?? t('cart.quantity') }), _jsx("button", { type: "button", onClick: handleIncrement, disabled: disabled || isAtMax, className: cn('flex items-center justify-center text-muted-foreground transition-colors', 'hover:text-foreground hover:bg-muted', 'disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-inset', 'rounded-r-md', classes.button), "aria-label": "Increase quantity", children: _jsx(Plus, { className: classes.icon }) })] }));
|
|
84
86
|
}
|
|
85
87
|
//# sourceMappingURL=QuantitySelector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuantitySelector.js","sourceRoot":"","sources":["../../../src/cart/components/QuantitySelector.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAA;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"QuantitySelector.js","sourceRoot":"","sources":["../../../src/cart/components/QuantitySelector.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckoutButton.d.ts","sourceRoot":"","sources":["../../../src/checkout/components/CheckoutButton.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"CheckoutButton.d.ts","sourceRoot":"","sources":["../../../src/checkout/components/CheckoutButton.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAMnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,cAAc,CAAC,EAC7B,QAAQ,EACR,QAAgB,EAChB,SAAS,EACT,gBAAgB,EAChB,OAAO,EACP,IAAW,EACX,SAAiB,EACjB,gBAAwB,GACzB,EAAE,mBAAmB,2CAgIrB"}
|
|
@@ -10,6 +10,7 @@ import { Loader2, AlertCircle } from 'lucide-react';
|
|
|
10
10
|
import { useCheckout } from '../hooks/useCheckout';
|
|
11
11
|
import { usePaymentStatus } from '../hooks/usePaymentStatus';
|
|
12
12
|
import { cn } from '../../core/utils';
|
|
13
|
+
import { useT } from '../../core/i18n';
|
|
13
14
|
// =============================================================================
|
|
14
15
|
// Component
|
|
15
16
|
// =============================================================================
|
|
@@ -59,7 +60,8 @@ import { cn } from '../../core/utils';
|
|
|
59
60
|
* <CheckoutButton skipPaymentCheck />
|
|
60
61
|
* ```
|
|
61
62
|
*/
|
|
62
|
-
export function CheckoutButton({ children
|
|
63
|
+
export function CheckoutButton({ children, disabled = false, className, onBeforeCheckout, onError, size = 'md', fullWidth = false, skipPaymentCheck = false, }) {
|
|
64
|
+
const t = useT();
|
|
63
65
|
const paymentStatus = usePaymentStatus();
|
|
64
66
|
const { checkout, isLoading } = useCheckout({
|
|
65
67
|
onError: (err) => {
|
|
@@ -127,6 +129,6 @@ export function CheckoutButton({ children = 'Checkout', disabled = false, classN
|
|
|
127
129
|
// Size
|
|
128
130
|
sizeClasses[size],
|
|
129
131
|
// Width
|
|
130
|
-
fullWidth && 'w-full', className), children: isLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin mr-2" }),
|
|
132
|
+
fullWidth && 'w-full', className), children: isLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin mr-2" }), t('checkout.redirecting')] })) : (children ?? t('cart.checkout')) }));
|
|
131
133
|
}
|
|
132
134
|
//# sourceMappingURL=CheckoutButton.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckoutButton.js","sourceRoot":"","sources":["../../../src/checkout/components/CheckoutButton.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,CAAA;;AAEZ,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC5D,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"CheckoutButton.js","sourceRoot":"","sources":["../../../src/checkout/components/CheckoutButton.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckoutFlow.d.ts","sourceRoot":"","sources":["../../../src/checkout/components/CheckoutFlow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoBH,OAAO,KAAK,EACV,iBAAiB,EAMlB,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"CheckoutFlow.d.ts","sourceRoot":"","sources":["../../../src/checkout/components/CheckoutFlow.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAoBH,OAAO,KAAK,EACV,iBAAiB,EAMlB,MAAM,UAAU,CAAA;AA8TjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,aAAa,EACb,UAAU,EACV,UAAU,EACV,SAAS,EACT,SAAS,EACT,gBAAuB,EACvB,QAAgB,EAChB,QAAQ,GACT,EAAE,iBAAiB,2CAulCnB"}
|
|
@@ -17,7 +17,7 @@ import { ArrowLeft, Loader2, Check, MapPin, Truck, CreditCard, Store, Clock } fr
|
|
|
17
17
|
import { cn } from '../../core/utils';
|
|
18
18
|
import { formatPrice } from '../../core/utils';
|
|
19
19
|
import { useCart } from '../../cart/store';
|
|
20
|
-
import { useStoreSettings } from '../../core';
|
|
20
|
+
import { useStoreSettings, useT, translateDynamic } from '../../core';
|
|
21
21
|
import { useCheckout } from '../hooks/useCheckout';
|
|
22
22
|
import { emitEvent } from '../../analytics/client/tracker';
|
|
23
23
|
import { useAddresses } from '../../auth/hooks/useAddresses';
|
|
@@ -27,15 +27,15 @@ import { ShippingForm } from './ShippingForm';
|
|
|
27
27
|
import { ShippingOptions } from './ShippingOptions';
|
|
28
28
|
import { OrderSummary } from './OrderSummary';
|
|
29
29
|
/** "Open today 09:00–18:00" line for a pickup-location card (Mon = day 0). */
|
|
30
|
-
function formatTodayHours(location) {
|
|
30
|
+
function formatTodayHours(location, t) {
|
|
31
31
|
const day = (new Date().getDay() + 6) % 7;
|
|
32
32
|
const h = location.openingHours?.find((x) => x.day === day);
|
|
33
33
|
if (!h)
|
|
34
34
|
return null;
|
|
35
35
|
if (h.closed)
|
|
36
|
-
return '
|
|
36
|
+
return t('checkout.closedToday');
|
|
37
37
|
if (h.open && h.close)
|
|
38
|
-
return
|
|
38
|
+
return t('checkout.openToday', { open: h.open, close: h.close });
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
41
|
/** One-line address for a pickup-location card. */
|
|
@@ -71,10 +71,11 @@ function addressSummary(a) {
|
|
|
71
71
|
.join(', ');
|
|
72
72
|
}
|
|
73
73
|
function StepIndicator({ currentStep, pickup = false }) {
|
|
74
|
+
const t = useT();
|
|
74
75
|
const steps = [
|
|
75
|
-
{ key: 'address', label: pickup ? '
|
|
76
|
-
...(pickup ? [] : [{ key: 'shipping', label: '
|
|
77
|
-
{ key: 'review', label: '
|
|
76
|
+
{ key: 'address', label: pickup ? t('checkout.stepPickup') : t('checkout.stepAddress'), icon: pickup ? Store : MapPin },
|
|
77
|
+
...(pickup ? [] : [{ key: 'shipping', label: t('checkout.stepShipping'), icon: Truck }]),
|
|
78
|
+
{ key: 'review', label: t('checkout.stepReview'), icon: CreditCard },
|
|
78
79
|
];
|
|
79
80
|
const currentIndex = steps.findIndex((s) => s.key === currentStep);
|
|
80
81
|
return (_jsx("div", { className: "flex items-center justify-center gap-2 mb-8", children: steps.map((step, index) => {
|
|
@@ -85,8 +86,9 @@ function StepIndicator({ currentStep, pickup = false }) {
|
|
|
85
86
|
}) }));
|
|
86
87
|
}
|
|
87
88
|
function ReviewSection({ shippingAddress, billingAddress, selectedShipping, email, currency, onEditAddress, onEditShipping, }) {
|
|
88
|
-
|
|
89
|
-
|
|
89
|
+
const t = useT();
|
|
90
|
+
return (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "p-4 border rounded-lg", children: [_jsx("div", { className: "flex items-center justify-between mb-2", children: _jsx("h4", { className: "font-medium", children: t('common.contact') }) }), _jsx("p", { className: "text-sm text-muted-foreground", children: email })] }), _jsxs("div", { className: "p-4 border rounded-lg", children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("h4", { className: "font-medium", children: t('checkout.shipTo') }), _jsx("button", { type: "button", onClick: onEditAddress, className: "text-sm text-primary hover:underline", children: t('common.change') })] }), _jsxs("p", { className: "text-sm text-muted-foreground", children: [shippingAddress.firstName, " ", shippingAddress.lastName, _jsx("br", {}), shippingAddress.line1, shippingAddress.line2 && (_jsxs(_Fragment, { children: [_jsx("br", {}), shippingAddress.line2] })), _jsx("br", {}), shippingAddress.city, ", ", shippingAddress.state, " ", shippingAddress.postalCode, _jsx("br", {}), shippingAddress.country] })] }), _jsxs("div", { className: "p-4 border rounded-lg", children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("h4", { className: "font-medium", children: t('checkout.billTo') }), _jsx("button", { type: "button", onClick: onEditAddress, className: "text-sm text-primary hover:underline", children: t('common.change') })] }), billingAddress ? (_jsxs("p", { className: "text-sm text-muted-foreground", children: [billingAddress.firstName, " ", billingAddress.lastName, _jsx("br", {}), billingAddress.line1, billingAddress.line2 && (_jsxs(_Fragment, { children: [_jsx("br", {}), billingAddress.line2] })), _jsx("br", {}), billingAddress.city, ", ", billingAddress.state, " ", billingAddress.postalCode, _jsx("br", {}), billingAddress.country] })) : (_jsx("p", { className: "text-sm text-muted-foreground", children: t('checkout.sameAsShipping') }))] }), _jsxs("div", { className: "p-4 border rounded-lg", children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsx("h4", { className: "font-medium", children: t('checkout.shippingMethod') }), _jsx("button", { type: "button", onClick: onEditShipping, className: "text-sm text-primary hover:underline", children: t('common.change') })] }), _jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsxs("div", { children: [_jsxs("p", { className: "text-muted-foreground", children: [selectedShipping.carrierName && `${selectedShipping.carrierName} - `, selectedShipping.name] }), selectedShipping.description && (_jsx("p", { className: "text-xs text-muted-foreground/80", children: selectedShipping.description }))] }), _jsx("p", { className: cn('font-medium', selectedShipping.price === 0 && 'text-green-600'), children: selectedShipping.price === 0
|
|
91
|
+
? t('common.freeUpper')
|
|
90
92
|
: formatPrice(selectedShipping.price / 100, { currency }) })] })] })] }));
|
|
91
93
|
}
|
|
92
94
|
/**
|
|
@@ -96,11 +98,12 @@ function ReviewSection({ shippingAddress, billingAddress, selectedShipping, emai
|
|
|
96
98
|
* so we gate on the real session, never an optimistic flag.
|
|
97
99
|
*/
|
|
98
100
|
function AuthGate({ tab, onTab, onSignedUp }) {
|
|
99
|
-
|
|
101
|
+
const t = useT();
|
|
102
|
+
return (_jsxs("div", { className: "mx-auto max-w-md space-y-6", children: [_jsxs("div", { className: "space-y-2 text-center", children: [_jsx("h2", { className: "text-xl font-semibold", children: t('checkout.signInToCheckOut') }), _jsx("p", { className: "text-sm text-muted-foreground", children: t('checkout.accountRequired') })] }), _jsxs("div", { className: "flex rounded-lg border p-1 text-sm", children: [_jsx("button", { type: "button", onClick: () => onTab('signin'), className: cn('flex-1 rounded-md px-3 py-1.5 font-medium transition-colors', tab === 'signin'
|
|
100
103
|
? 'bg-primary text-primary-foreground'
|
|
101
|
-
: 'text-muted-foreground hover:text-foreground'), children:
|
|
104
|
+
: 'text-muted-foreground hover:text-foreground'), children: t('checkout.signIn') }), _jsx("button", { type: "button", onClick: () => onTab('signup'), className: cn('flex-1 rounded-md px-3 py-1.5 font-medium transition-colors', tab === 'signup'
|
|
102
105
|
? 'bg-primary text-primary-foreground'
|
|
103
|
-
: 'text-muted-foreground hover:text-foreground'), children:
|
|
106
|
+
: 'text-muted-foreground hover:text-foreground'), children: t('checkout.createAccount') })] }), tab === 'signin' ? (
|
|
104
107
|
// No redirect — a successful sign-in updates the session in place and
|
|
105
108
|
// the gate closes once `customerId` propagates from the parent.
|
|
106
109
|
_jsx(SignInForm, {})) : (
|
|
@@ -151,6 +154,7 @@ function AuthGate({ tab, onTab, onSignedUp }) {
|
|
|
151
154
|
* ```
|
|
152
155
|
*/
|
|
153
156
|
export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId, successUrl, cancelUrl, className, showOrderSummary = true, currency = 'USD', metadata, }) {
|
|
157
|
+
const t = useT();
|
|
154
158
|
// Cart state - use selectors for proper reactivity (getters may return stale values)
|
|
155
159
|
const items = useCart((state) => state.items);
|
|
156
160
|
const subtotal = useCart((state) => state.items.reduce((sum, item) => sum + item.price * item.quantity, 0));
|
|
@@ -277,11 +281,11 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
277
281
|
});
|
|
278
282
|
const data = await response.json();
|
|
279
283
|
if (!response.ok || !data?.success) {
|
|
280
|
-
setDiscountError(data?.error || '
|
|
284
|
+
setDiscountError(data?.error || t('checkout.codeCheckFailed'));
|
|
281
285
|
return;
|
|
282
286
|
}
|
|
283
287
|
if (code && !data.valid) {
|
|
284
|
-
setDiscountError(data.error ||
|
|
288
|
+
setDiscountError(data.error || t('checkout.codeInvalid'));
|
|
285
289
|
// Keep whatever automatic promotions still apply.
|
|
286
290
|
setDiscountEval({
|
|
287
291
|
code: null,
|
|
@@ -303,12 +307,12 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
303
307
|
setDiscountInput('');
|
|
304
308
|
}
|
|
305
309
|
catch {
|
|
306
|
-
setDiscountError('
|
|
310
|
+
setDiscountError(t('checkout.codeCheckFailed'));
|
|
307
311
|
}
|
|
308
312
|
finally {
|
|
309
313
|
setIsApplyingDiscount(false);
|
|
310
314
|
}
|
|
311
|
-
}, [items, state.email]);
|
|
315
|
+
}, [items, state.email, t]);
|
|
312
316
|
// Evaluate automatic promotions on mount so the recap column surfaces them
|
|
313
317
|
// from the first step (once — re-evaluations happen through apply/remove).
|
|
314
318
|
useEffect(() => {
|
|
@@ -375,7 +379,7 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
375
379
|
setState((prev) => ({
|
|
376
380
|
...prev,
|
|
377
381
|
isLoadingShipping: false,
|
|
378
|
-
shippingError: data.error || '
|
|
382
|
+
shippingError: data.error || t('checkout.shippingCalcFailed'),
|
|
379
383
|
}));
|
|
380
384
|
return;
|
|
381
385
|
}
|
|
@@ -398,10 +402,10 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
398
402
|
setState((prev) => ({
|
|
399
403
|
...prev,
|
|
400
404
|
isLoadingShipping: false,
|
|
401
|
-
shippingError: '
|
|
405
|
+
shippingError: t('checkout.shippingCalcFailedRetry'),
|
|
402
406
|
}));
|
|
403
407
|
}
|
|
404
|
-
}, [items]);
|
|
408
|
+
}, [items, t]);
|
|
405
409
|
// Handle address submission
|
|
406
410
|
const handleAddressSubmit = useCallback(async (address) => {
|
|
407
411
|
setState((prev) => ({
|
|
@@ -465,18 +469,18 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
465
469
|
const firstName = pickupContact.firstName.trim();
|
|
466
470
|
const lastName = pickupContact.lastName.trim();
|
|
467
471
|
if (!firstName || !lastName) {
|
|
468
|
-
setState((prev) => ({ ...prev, error: '
|
|
472
|
+
setState((prev) => ({ ...prev, error: t('checkout.enterFirstLastName') }));
|
|
469
473
|
return;
|
|
470
474
|
}
|
|
471
475
|
if (!state.email) {
|
|
472
|
-
setState((prev) => ({ ...prev, error: '
|
|
476
|
+
setState((prev) => ({ ...prev, error: t('checkout.enterEmail') }));
|
|
473
477
|
return;
|
|
474
478
|
}
|
|
475
479
|
const pickupOption = {
|
|
476
480
|
id: location.id,
|
|
477
481
|
name: location.name,
|
|
478
482
|
description: location.preparationTime
|
|
479
|
-
?
|
|
483
|
+
? t('checkout.usuallyReadyIn', { time: translateDynamic(t, 'prep', location.preparationTime) })
|
|
480
484
|
: undefined,
|
|
481
485
|
price: 0,
|
|
482
486
|
source: 'pickup',
|
|
@@ -535,7 +539,7 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
535
539
|
currency: resolvedCurrency,
|
|
536
540
|
path: typeof window !== 'undefined' ? window.location.pathname : '/checkout',
|
|
537
541
|
});
|
|
538
|
-
}, [state.selectedPickupLocation, state.email, pickupContact, items, subtotal, resolvedCurrency]);
|
|
542
|
+
}, [state.selectedPickupLocation, state.email, pickupContact, items, subtotal, resolvedCurrency, t]);
|
|
539
543
|
// Handle checkout
|
|
540
544
|
const handleCheckout = useCallback(async () => {
|
|
541
545
|
setState((prev) => ({ ...prev, isProcessing: true, error: null }));
|
|
@@ -574,7 +578,7 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
574
578
|
}, []);
|
|
575
579
|
// Early return if cart is empty
|
|
576
580
|
if (items.length === 0) {
|
|
577
|
-
return (_jsxs("div", { className: cn('text-center py-12', className), children: [_jsx("p", { className: "text-muted-foreground", children:
|
|
581
|
+
return (_jsxs("div", { className: cn('text-center py-12', className), children: [_jsx("p", { className: "text-muted-foreground", children: t('checkout.cartEmpty') }), onCancel && (_jsx("button", { onClick: onCancel, className: "mt-4 text-primary hover:underline", children: t('checkout.continueShopping') }))] }));
|
|
578
582
|
}
|
|
579
583
|
// Calculate totals (mirrors the pricing core's canonical formula:
|
|
580
584
|
// taxable base = subtotal − discount + shipping)
|
|
@@ -602,7 +606,7 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
602
606
|
// Discount code entry (native discounts engine). Rendered in the sticky
|
|
603
607
|
// recap column (Shopify placement); falls back into the review step when
|
|
604
608
|
// the order summary is hidden. All state lives in this component either way.
|
|
605
|
-
const discountBlock = (_jsxs("div", { className: "p-4 border rounded-lg bg-card", children: [_jsx("h4", { className: "font-medium mb-3", children:
|
|
609
|
+
const discountBlock = (_jsxs("div", { className: "p-4 border rounded-lg bg-card", children: [_jsx("h4", { className: "font-medium mb-3", children: t('checkout.discountCode') }), discountEval?.code ? (_jsxs("div", { className: "flex items-center justify-between gap-3 rounded-md border border-emerald-200 bg-emerald-50 px-3 py-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("span", { className: "block text-sm font-medium text-emerald-700", children: discountEval.code }), discountEval.title && (_jsx("span", { className: "block text-xs text-emerald-600 truncate", children: discountEval.title }))] }), _jsx("button", { type: "button", onClick: () => void fetchDiscountEvaluation(''), disabled: isApplyingDiscount, className: "text-xs text-muted-foreground hover:text-foreground underline shrink-0", children: t('common.remove') })] })) : (_jsxs("div", { className: "flex gap-2", children: [_jsx("input", { type: "text", value: discountInput, onChange: (e) => {
|
|
606
610
|
setDiscountInput(e.target.value);
|
|
607
611
|
if (discountError)
|
|
608
612
|
setDiscountError(null);
|
|
@@ -613,34 +617,34 @@ export function CheckoutFlow({ onComplete, onCancel, customerEmail, customerId,
|
|
|
613
617
|
void fetchDiscountEvaluation(discountInput.trim());
|
|
614
618
|
}
|
|
615
619
|
}
|
|
616
|
-
}, placeholder:
|
|
620
|
+
}, placeholder: t('checkout.enterCode'), autoComplete: "off", className: cn('min-w-0 flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm uppercase', 'placeholder:normal-case placeholder:text-muted-foreground', 'focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary') }), _jsx("button", { type: "button", onClick: () => void fetchDiscountEvaluation(discountInput.trim()), disabled: !discountInput.trim() || isApplyingDiscount, className: cn('shrink-0 px-4 py-2 rounded-md text-sm font-medium', 'border border-input bg-background', 'hover:bg-accent hover:text-accent-foreground transition-colors', 'disabled:opacity-50 disabled:cursor-not-allowed'), children: isApplyingDiscount ? _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : t('checkout.apply') })] })), discountError && _jsx("p", { className: "mt-2 text-xs text-destructive", children: discountError }), (discountEval?.applied ?? [])
|
|
617
621
|
.filter((a) => a.method === 'automatic')
|
|
618
622
|
.map((a) => (_jsx("p", { className: "mt-2 text-xs text-emerald-600", children: a.freeShipping && a.amountCents === 0
|
|
619
|
-
?
|
|
620
|
-
:
|
|
621
|
-
return (_jsx("div", { className: cn('max-w-6xl mx-auto', className), children: _jsxs("div", { className: cn('grid gap-8', showOrderSummary ? 'lg:grid-cols-3' : ''), children: [_jsx("div", { className: cn(showOrderSummary ? 'lg:col-span-2' : ''), children: showAuthGate ? (_jsx(AuthGate, { tab: authTab, onTab: setAuthTab, onSignedUp: () => setAuthTab('signin') })) : (_jsxs(_Fragment, { children: [_jsx(StepIndicator, { currentStep: state.step, pickup: isPickup }), state.step !== 'address' && (_jsxs("button", { type: "button", onClick: goBack, className: "flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground mb-6", children: [_jsx(ArrowLeft, { className: "h-4 w-4" }),
|
|
623
|
+
? t('checkout.promotionAppliedFreeShipping', { title: a.title })
|
|
624
|
+
: t('checkout.promotionApplied', { title: a.title }) }, `${a.title}-${a.amountCents}`)))] }));
|
|
625
|
+
return (_jsx("div", { className: cn('max-w-6xl mx-auto', className), children: _jsxs("div", { className: cn('grid gap-8', showOrderSummary ? 'lg:grid-cols-3' : ''), children: [_jsx("div", { className: cn(showOrderSummary ? 'lg:col-span-2' : ''), children: showAuthGate ? (_jsx(AuthGate, { tab: authTab, onTab: setAuthTab, onSignedUp: () => setAuthTab('signin') })) : (_jsxs(_Fragment, { children: [_jsx(StepIndicator, { currentStep: state.step, pickup: isPickup }), state.step !== 'address' && (_jsxs("button", { type: "button", onClick: goBack, className: "flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground mb-6", children: [_jsx(ArrowLeft, { className: "h-4 w-4" }), t('common.back')] })), (state.error || checkoutError) && (_jsx("div", { className: "mb-6 p-4 border border-destructive/50 bg-destructive/10 rounded-lg", children: _jsx("p", { className: "text-sm text-destructive", children: state.error || checkoutError?.error }) })), state.step === 'address' && (_jsxs("div", { className: "space-y-6", children: [state.pickupLocations.length > 0 && (_jsxs("div", { className: "grid grid-cols-2 gap-2 rounded-lg border p-1", children: [_jsxs("button", { type: "button", onClick: () => handleFulfillmentChange('shipping'), className: cn('flex items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors', !isPickup
|
|
622
626
|
? 'bg-primary text-primary-foreground'
|
|
623
|
-
: 'text-muted-foreground hover:text-foreground'), children: [_jsx(Truck, { className: "h-4 w-4" }),
|
|
627
|
+
: 'text-muted-foreground hover:text-foreground'), children: [_jsx(Truck, { className: "h-4 w-4" }), t('checkout.delivery')] }), _jsxs("button", { type: "button", onClick: () => handleFulfillmentChange('pickup'), className: cn('flex items-center justify-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors', isPickup
|
|
624
628
|
? 'bg-primary text-primary-foreground'
|
|
625
|
-
: 'text-muted-foreground hover:text-foreground'), children: [_jsx(Store, { className: "h-4 w-4" }),
|
|
629
|
+
: 'text-muted-foreground hover:text-foreground'), children: [_jsx(Store, { className: "h-4 w-4" }), t('checkout.pickupInStore')] })] })), _jsx("h2", { className: "text-xl font-semibold", children: isPickup ? t('checkout.pickupInStore') : t('checkout.shippingAddress') }), !customerEmail && (_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "block text-sm font-medium", children: [t('checkout.email'), " ", _jsx("span", { className: "text-destructive", children: "*" })] }), _jsx("input", { type: "email", value: state.email || '', onChange: (e) => setState((prev) => ({ ...prev, email: e.target.value })), placeholder: t('checkout.emailPlaceholder'), className: cn('w-full px-3 py-2 rounded-md border', 'bg-background text-foreground', 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary', 'border-input') })] })), isPickup ? (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [_jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "block text-sm font-medium", children: [t('checkout.firstName'), " ", _jsx("span", { className: "text-destructive", children: "*" })] }), _jsx("input", { type: "text", value: pickupContact.firstName, onChange: (e) => setPickupContact((prev) => ({ ...prev, firstName: e.target.value })), className: "w-full px-3 py-2 rounded-md border bg-background text-foreground border-input focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary" })] }), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: "block text-sm font-medium", children: [t('checkout.lastName'), " ", _jsx("span", { className: "text-destructive", children: "*" })] }), _jsx("input", { type: "text", value: pickupContact.lastName, onChange: (e) => setPickupContact((prev) => ({ ...prev, lastName: e.target.value })), className: "w-full px-3 py-2 rounded-md border bg-background text-foreground border-input focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary" })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("p", { className: "text-sm font-medium", children: t('checkout.pickupStore') }), (showAllLocations
|
|
626
630
|
? state.pickupLocations
|
|
627
631
|
: state.pickupLocations.slice(0, 1).map((first) => state.selectedPickupLocation &&
|
|
628
632
|
state.selectedPickupLocation.id !== first.id
|
|
629
633
|
? state.selectedPickupLocation
|
|
630
634
|
: first)).map((location) => {
|
|
631
635
|
const selected = state.selectedPickupLocation?.id === location.id;
|
|
632
|
-
const hours = formatTodayHours(location);
|
|
633
|
-
return (_jsxs("label", { className: cn('flex items-start gap-3 rounded-lg border p-4 cursor-pointer transition-colors', selected && 'border-primary bg-primary/5'), children: [_jsx("input", { type: "radio", name: "pickup-location", checked: selected, onChange: () => handlePickupLocationSelect(location), className: "mt-1" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-sm font-medium", children: location.name }), _jsx("span", { className: "block text-xs text-muted-foreground", children: pickupAddressLine(location) }), hours && (_jsxs("span", { className: "mt-1 flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(Clock, { className: "h-3 w-3" }), hours] })), location.preparationTime && (
|
|
634
|
-
}), state.pickupLocations.length > 1 && !showAllLocations && (
|
|
636
|
+
const hours = formatTodayHours(location, t);
|
|
637
|
+
return (_jsxs("label", { className: cn('flex items-start gap-3 rounded-lg border p-4 cursor-pointer transition-colors', selected && 'border-primary bg-primary/5'), children: [_jsx("input", { type: "radio", name: "pickup-location", checked: selected, onChange: () => handlePickupLocationSelect(location), className: "mt-1" }), _jsxs("span", { className: "min-w-0 flex-1", children: [_jsx("span", { className: "block text-sm font-medium", children: location.name }), _jsx("span", { className: "block text-xs text-muted-foreground", children: pickupAddressLine(location) }), hours && (_jsxs("span", { className: "mt-1 flex items-center gap-1 text-xs text-muted-foreground", children: [_jsx(Clock, { className: "h-3 w-3" }), hours] })), location.preparationTime && (_jsx("span", { className: "block text-xs text-emerald-600 mt-1", children: t('checkout.usuallyReadyIn', { time: translateDynamic(t, 'prep', location.preparationTime) }) }))] }), _jsx("span", { className: "shrink-0 text-sm font-medium", children: t('common.free') })] }, location.id));
|
|
638
|
+
}), state.pickupLocations.length > 1 && !showAllLocations && (_jsx("button", { type: "button", onClick: () => setShowAllLocations(true), className: "text-sm text-primary hover:underline", children: t('checkout.chooseAnotherStore', { count: state.pickupLocations.length - 1 }) }))] }), _jsxs("button", { type: "button", onClick: handlePickupContinue, disabled: !state.selectedPickupLocation ||
|
|
635
639
|
!pickupContact.firstName.trim() ||
|
|
636
640
|
!pickupContact.lastName.trim() ||
|
|
637
641
|
!state.email ||
|
|
638
|
-
state.isLoadingShipping, className: cn('w-full px-4 py-3 rounded-md font-medium', 'bg-primary text-primary-foreground hover:bg-primary/90 transition-colors', 'disabled:opacity-50 disabled:cursor-not-allowed', 'flex items-center justify-center gap-2'), children: [state.isLoadingShipping && _jsx(Loader2, { className: "h-4 w-4 animate-spin" }),
|
|
642
|
+
state.isLoadingShipping, className: cn('w-full px-4 py-3 rounded-md font-medium', 'bg-primary text-primary-foreground hover:bg-primary/90 transition-colors', 'disabled:opacity-50 disabled:cursor-not-allowed', 'flex items-center justify-center gap-2'), children: [state.isLoadingShipping && _jsx(Loader2, { className: "h-4 w-4 animate-spin" }), t('checkout.continueToReview')] })] })) : hasSavedAddresses && !useNewAddress ? (_jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-sm font-medium", children: t('checkout.chooseDeliveryAddress') }), savedAddresses.map((a) => (_jsxs("div", { className: "flex items-start justify-between gap-4 rounded-lg border p-4", children: [_jsxs("div", { className: "text-sm", children: [_jsxs("p", { className: "font-medium", children: [a.firstName, " ", a.lastName, a.label ? _jsxs("span", { className: "text-muted-foreground", children: [" \u00B7 ", a.label] }) : null] }), _jsx("p", { className: "text-muted-foreground", children: addressSummary(a) }), a.phone && _jsx("p", { className: "text-muted-foreground", children: a.phone })] }), _jsx("button", { type: "button", onClick: () => handleAddressSubmit(dtoToAddress(a, state.email)), className: "shrink-0 rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90", children: t('checkout.deliverHere') })] }, a.id))), _jsx("button", { type: "button", onClick: () => {
|
|
639
643
|
setUseNewAddress(true);
|
|
640
644
|
setFormKey((k) => k + 1);
|
|
641
|
-
}, className: "text-sm text-primary hover:underline", children:
|
|
642
|
-
? '
|
|
643
|
-
:
|
|
645
|
+
}, className: "text-sm text-primary hover:underline", children: t('checkout.useNewAddress') })] })) : (_jsxs(_Fragment, { children: [hasSavedAddresses && (_jsxs("button", { type: "button", onClick: () => setUseNewAddress(false), className: "flex items-center gap-1 text-sm text-primary hover:underline", children: [_jsx(ArrowLeft, { className: "h-3 w-3" }), t('checkout.useSavedAddress')] })), _jsx(ShippingForm, { defaultValues: state.shippingAddress || undefined, onSubmit: handleAddressSubmit, onCancel: onCancel, showBillingAddress: true, onBillingAddressChange: (addr) => setState((prev) => ({ ...prev, billingAddress: addr })), allowedCountries: allowedCountries.length > 0 ? allowedCountries : undefined }, formKey)] }))] })), state.step === 'shipping' && (_jsxs("div", { className: "space-y-6", children: [_jsx("h2", { className: "text-xl font-semibold", children: t('checkout.shippingMethodTitle') }), _jsx(ShippingOptions, { options: state.availableShipping, selectedOption: state.selectedShipping, onSelect: handleShippingSelect, isLoading: state.isLoadingShipping, error: state.shippingError, currency: resolvedCurrency }), _jsxs("div", { className: "flex gap-4 pt-4", children: [_jsx("button", { type: "button", onClick: goBack, className: cn('flex-1 px-4 py-3 rounded-md font-medium', 'border border-input bg-background', 'hover:bg-accent hover:text-accent-foreground', 'transition-colors'), children: t('common.back') }), _jsx("button", { type: "button", onClick: handleShippingContinue, disabled: !state.selectedShipping || state.isLoadingShipping, className: cn('flex-1 px-4 py-3 rounded-md font-medium', 'bg-primary text-primary-foreground', 'hover:bg-primary/90', 'transition-colors', 'disabled:opacity-50 disabled:cursor-not-allowed'), children: t('checkout.continueToReview') })] })] })), state.step === 'review' && state.shippingAddress && state.selectedShipping && (_jsxs("div", { className: "space-y-6", children: [_jsx("h2", { className: "text-xl font-semibold", children: t('checkout.reviewYourOrder') }), isPickup && state.selectedPickupLocation ? (_jsx("div", { className: "space-y-4", children: _jsxs("div", { className: "p-4 border rounded-lg space-y-3", children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("h4", { className: "flex items-center gap-2 font-medium", children: [_jsx(Store, { className: "h-4 w-4" }), t('checkout.pickupInStore')] }), _jsx("button", { type: "button", onClick: () => setState((prev) => ({ ...prev, step: 'address' })), className: "text-sm text-primary hover:underline shrink-0", children: t('common.edit') })] }), _jsxs("div", { className: "text-sm", children: [_jsx("p", { className: "font-medium", children: state.selectedPickupLocation.name }), _jsx("p", { className: "text-muted-foreground", children: pickupAddressLine(state.selectedPickupLocation) }), formatTodayHours(state.selectedPickupLocation, t) && (_jsxs("p", { className: "text-muted-foreground flex items-center gap-1 mt-1", children: [_jsx(Clock, { className: "h-3 w-3" }), formatTodayHours(state.selectedPickupLocation, t)] })), state.selectedPickupLocation.preparationTime && (_jsx("p", { className: "text-emerald-600 mt-1", children: t('checkout.usuallyReadyIn', { time: translateDynamic(t, 'prep', state.selectedPickupLocation.preparationTime) }) }))] }), _jsxs("div", { className: "border-t pt-3 text-sm", children: [_jsxs("p", { className: "font-medium", children: [pickupContact.firstName, " ", pickupContact.lastName] }), _jsx("p", { className: "text-muted-foreground", children: state.email || customerEmail || '' })] })] }) })) : (_jsx(ReviewSection, { shippingAddress: state.shippingAddress, billingAddress: state.billingAddress, selectedShipping: state.selectedShipping, email: state.email || customerEmail || '', currency: resolvedCurrency, onEditAddress: () => setState((prev) => ({ ...prev, step: 'address' })), onEditShipping: () => setState((prev) => ({ ...prev, step: 'shipping' })) })), !showOrderSummary && discountBlock, paymentMethods.length > 0 && (_jsxs("div", { className: "p-4 border rounded-lg", children: [_jsx("h4", { className: "font-medium mb-3", children: t('checkout.paymentMethod') }), _jsxs("div", { className: "space-y-2", children: [_jsxs("label", { className: cn('flex items-start gap-3 rounded-md border p-3 cursor-pointer transition-colors', selectedPaymentMethodId === '' && 'border-primary bg-primary/5'), children: [_jsx("input", { type: "radio", name: "payment-method", checked: selectedPaymentMethodId === '', onChange: () => setSelectedPaymentMethodId(''), className: "mt-1" }), _jsxs("span", { children: [_jsx("span", { className: "block text-sm font-medium", children: t('checkout.card') }), _jsx("span", { className: "block text-xs text-muted-foreground", children: t('checkout.secureViaStripe') })] })] }), paymentMethods.map((m) => (_jsxs("label", { className: cn('flex items-start gap-3 rounded-md border p-3 cursor-pointer transition-colors', selectedPaymentMethodId === m.id && 'border-primary bg-primary/5'), children: [_jsx("input", { type: "radio", name: "payment-method", checked: selectedPaymentMethodId === m.id, onChange: () => setSelectedPaymentMethodId(m.id), className: "mt-1" }), _jsxs("span", { children: [_jsx("span", { className: "block text-sm font-medium", children: m.name }), m.instructions && (_jsx("span", { className: "block text-xs text-muted-foreground line-clamp-2", children: m.instructions }))] })] }, m.id)))] })] })), _jsx("button", { type: "button", onClick: handleCheckout, disabled: state.isProcessing || isCheckoutLoading, className: cn('w-full px-4 py-4 rounded-md font-medium text-lg', 'bg-primary text-primary-foreground', 'hover:bg-primary/90', 'transition-colors', 'disabled:opacity-50 disabled:cursor-not-allowed', 'flex items-center justify-center gap-2'), children: (state.isProcessing || isCheckoutLoading) ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-5 w-5 animate-spin" }), t('common.processing')] })) : (_jsxs(_Fragment, { children: [_jsx(CreditCard, { className: "h-5 w-5" }), selectedPaymentMethodId ? t('checkout.placeOrder') : t('checkout.proceedToPayment')] })) }), _jsx("p", { className: "text-xs text-center text-muted-foreground", children: selectedPaymentMethodId
|
|
646
|
+
? t('checkout.manualConfirmNote')
|
|
647
|
+
: t('checkout.stripeRedirectNote') })] }))] })) }), showOrderSummary && (_jsx("div", { className: "lg:col-span-1", children: _jsxs("div", { className: "sticky top-4 space-y-3", children: [_jsx(OrderSummary, { items: items.map((item) => ({
|
|
644
648
|
productId: item.productId,
|
|
645
649
|
variantId: item.variantId,
|
|
646
650
|
name: item.name,
|