storefront-layouts 1.0.9 → 1.0.13
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/components/shipping/ProductDeliveryInfoSection.d.ts.map +1 -1
- package/dist/components/shipping/ProductDeliveryInfoSection.js +10 -3
- package/dist/components/ui/address-selector.d.ts.map +1 -1
- package/dist/components/ui/address-selector.js +4 -3
- package/dist/components/ui/button.js +1 -1
- package/dist/components/ui/checkout-button.d.ts.map +1 -1
- package/dist/components/ui/checkout-button.js +2 -1
- package/dist/components/ui/product-card.d.ts.map +1 -1
- package/dist/components/ui/product-card.js +15 -4
- package/dist/components/ui/route-skeleton-loader.d.ts.map +1 -1
- package/dist/components/ui/route-skeleton-loader.js +6 -2
- package/dist/components/ui/sheet.d.ts.map +1 -1
- package/dist/components/ui/sheet.js +2 -2
- package/dist/components/ui/skeletons/checkout-skeleton.js +1 -1
- package/dist/editor/blocks/defaults/clothing-minimal-home.js +1 -1
- package/dist/editor/blocks/migrate-clothing-minimal.js +1 -1
- package/dist/hooks/use-pdp-variation.d.ts +57 -0
- package/dist/hooks/use-pdp-variation.d.ts.map +1 -0
- package/dist/hooks/use-pdp-variation.js +69 -0
- package/dist/hooks/use-product-by-slug.d.ts.map +1 -1
- package/dist/hooks/use-product-by-slug.js +0 -5
- package/dist/hooks/use-product-variation-selection.js +1 -1
- package/dist/hooks/use-shipping-quote.d.ts +1 -0
- package/dist/hooks/use-shipping-quote.d.ts.map +1 -1
- package/dist/hooks/use-shipping-quote.js +3 -0
- package/dist/layouts/booking/pages/ProductDetailPage.d.ts.map +1 -1
- package/dist/layouts/booking/pages/ProductDetailPage.js +130 -223
- package/dist/layouts/booking-agenda/pages/ProductDetailPage.d.ts.map +1 -1
- package/dist/layouts/booking-agenda/pages/ProductDetailPage.js +130 -223
- package/dist/layouts/clothing/components/ClothingHomePage.d.ts.map +1 -1
- package/dist/layouts/clothing/components/ClothingHomePage.js +40 -2
- package/dist/layouts/clothing/pages/ProductDetailPage.d.ts.map +1 -1
- package/dist/layouts/clothing/pages/ProductDetailPage.js +127 -209
- package/dist/layouts/clothing/pages/ProductsPage.d.ts.map +1 -1
- package/dist/layouts/clothing/pages/ProductsPage.js +2 -5
- package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.d.ts.map +1 -1
- package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.js +5 -3
- package/dist/layouts/clothing-minimal/components/clothing-minimal-block-render.d.ts.map +1 -1
- package/dist/layouts/clothing-minimal/components/clothing-minimal-block-render.js +13 -4
- package/dist/layouts/clothing-minimal/pages/ProductDetailPage.d.ts.map +1 -1
- package/dist/layouts/clothing-minimal/pages/ProductDetailPage.js +130 -223
- package/dist/layouts/clothing-minimal/pages/ProductsPage.d.ts.map +1 -1
- package/dist/layouts/clothing-minimal/pages/ProductsPage.js +2 -5
- package/dist/layouts/electronics/components/ElectronicsGridProductCard.js +1 -1
- package/dist/layouts/electronics/components/ElectronicsStoreHeader.d.ts.map +1 -1
- package/dist/layouts/electronics/components/ElectronicsStoreHeader.js +10 -9
- package/dist/layouts/electronics/pages/ProductDetailPage.d.ts.map +1 -1
- package/dist/layouts/electronics/pages/ProductDetailPage.js +130 -223
- package/dist/layouts/electronics/pages/ProductsPage.d.ts.map +1 -1
- package/dist/layouts/electronics/pages/ProductsPage.js +2 -5
- package/dist/layouts/electronics-grid/components/ElectronicsGridProductCard.js +1 -1
- package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.d.ts.map +1 -1
- package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.js +4 -5
- package/dist/layouts/electronics-grid/pages/ProductDetailPage.d.ts.map +1 -1
- package/dist/layouts/electronics-grid/pages/ProductDetailPage.js +130 -223
- package/dist/layouts/electronics-grid/pages/ProductsPage.d.ts.map +1 -1
- package/dist/layouts/electronics-grid/pages/ProductsPage.js +2 -5
- package/dist/layouts/food/pages/MenuPage.js +1 -1
- package/dist/layouts/food/pages/ProductDetailPage.d.ts.map +1 -1
- package/dist/layouts/food/pages/ProductDetailPage.js +37 -140
- package/dist/layouts/food/pages/ProductsPage.d.ts.map +1 -1
- package/dist/layouts/food/pages/ProductsPage.js +2 -5
- package/dist/layouts/food-modern/pages/MenuPage.js +1 -1
- package/dist/layouts/food-modern/pages/ProductDetailPage.d.ts.map +1 -1
- package/dist/layouts/food-modern/pages/ProductDetailPage.js +130 -223
- package/dist/layouts/food-modern/pages/ProductsPage.d.ts.map +1 -1
- package/dist/layouts/food-modern/pages/ProductsPage.js +2 -5
- package/dist/layouts/motivational-speaker/pages/ProductsPage.d.ts.map +1 -1
- package/dist/layouts/motivational-speaker/pages/ProductsPage.js +2 -5
- package/dist/layouts/shared/components/PdpColorSwatch.d.ts +11 -0
- package/dist/layouts/shared/components/PdpColorSwatch.d.ts.map +1 -0
- package/dist/layouts/shared/components/PdpColorSwatch.js +29 -0
- package/dist/layouts/shared/components/PdpVariationSelectors.d.ts +13 -0
- package/dist/layouts/shared/components/PdpVariationSelectors.d.ts.map +1 -0
- package/dist/layouts/shared/components/PdpVariationSelectors.js +65 -0
- package/dist/layouts/shared/components/StoreCartSheet.d.ts +8 -0
- package/dist/layouts/shared/components/StoreCartSheet.d.ts.map +1 -0
- package/dist/layouts/shared/components/StoreCartSheet.js +16 -0
- package/dist/layouts/shared/components/StoreHeader.d.ts.map +1 -1
- package/dist/layouts/shared/components/StoreHeader.js +13 -12
- package/dist/layouts/shared/components/headers/ClothingMinimalHeader.d.ts.map +1 -1
- package/dist/layouts/shared/components/headers/ClothingMinimalHeader.js +5 -7
- package/dist/layouts/shared/pages/CartPage.d.ts.map +1 -1
- package/dist/layouts/shared/pages/CartPage.js +6 -5
- package/dist/layouts/shared/pages/CheckoutPage.d.ts.map +1 -1
- package/dist/layouts/shared/pages/CheckoutPage.js +209 -107
- package/dist/layouts/shared/product-category-filter-chip.d.ts +2 -0
- package/dist/layouts/shared/product-category-filter-chip.d.ts.map +1 -0
- package/dist/layouts/shared/product-category-filter-chip.js +6 -0
- package/dist/lib/pdp-cart-actions.d.ts +5 -0
- package/dist/lib/pdp-cart-actions.d.ts.map +1 -0
- package/dist/lib/pdp-cart-actions.js +19 -0
- package/dist/lib/product-variation-utils.d.ts +17 -0
- package/dist/lib/product-variation-utils.d.ts.map +1 -1
- package/dist/lib/product-variation-utils.js +193 -14
- package/dist/lib/services/checkout.service.d.ts +11 -0
- package/dist/lib/services/checkout.service.d.ts.map +1 -1
- package/dist/lib/services/shipping.service.d.ts +3 -0
- package/dist/lib/services/shipping.service.d.ts.map +1 -1
- package/dist/lib/store-config-utils.d.ts.map +1 -1
- package/dist/lib/store-config-utils.js +104 -11
- package/dist/lib/store-context.d.ts.map +1 -1
- package/dist/lib/store-context.js +23 -8
- package/dist/lib/utils/asset-helpers.d.ts +2 -0
- package/dist/lib/utils/asset-helpers.d.ts.map +1 -1
- package/dist/lib/utils/asset-helpers.js +24 -0
- package/dist/styles/index.css +143 -45
- package/package.json +8 -2
|
@@ -20,6 +20,7 @@ import { filterActiveProducts } from '../../../lib/utils/index.js';
|
|
|
20
20
|
import { getAllCategoryIds, flattenCategoryTree, buildCategoryTree } from '../../../lib/utils/category-tree.js';
|
|
21
21
|
import { getBannerImage, getLayoutText } from '../../../lib/utils/asset-helpers.js';
|
|
22
22
|
import { shouldUseAPI } from '../../../lib/utils/demo-detection.js';
|
|
23
|
+
import { productCategoryFilterChipClass } from '../../shared/product-category-filter-chip';
|
|
23
24
|
import { useCatalogPriceRange } from '../../../hooks/use-catalog-price-range.js';
|
|
24
25
|
import { getApiPriceFilterActive, isWithinActivePriceRange } from '../../../lib/utils/catalog-price-bounds.js';
|
|
25
26
|
import { buildFilteredProductQuery, getFilteredProductQueryKey, productMatchesCategoryIds, productMatchesCategorySlug, } from '../../../lib/utils/filtered-product-query.js';
|
|
@@ -309,11 +310,7 @@ function ProductsPageContent({ storeConfig }) {
|
|
|
309
310
|
element?.scrollIntoView({ behavior: 'smooth' });
|
|
310
311
|
}, children: primaryButtonText })), secondaryButtonText && secondaryButtonText.trim() !== '' && (_jsx(Button, { className: `h-12 px-8 rounded-full text-base font-medium shadow-lg hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1 ${categoryHeaderImage ? 'bg-white/10 backdrop-blur-md text-white border border-white/30 hover:bg-white/20' : 'bg-gray-100 text-gray-900 hover:bg-gray-200 border border-gray-200'}`, onClick: () => {
|
|
311
312
|
window.location.href = `/${storeConfig.slug}/categories`;
|
|
312
|
-
}, children: secondaryButtonText }))] })] }) }) })] }), _jsxs("div", { "data-content-ready": true, className: "container mx-auto px-4 sm:px-6 lg:px-8 py-8", children: [_jsxs("div", { className: "flex gap-3 mb-8 overflow-x-auto pb-2 scrollbar-hide", children: [_jsx("button", { onClick: () => setSelectedCategoryFilter(null), className: `
|
|
313
|
-
? 'bg-gray-900 text-white hover:bg-blue-600'
|
|
314
|
-
: 'bg-gray-100 text-gray-700 hover:bg-blue-50 hover:text-blue-600'}`, children: "All" }), categories.map((category) => (_jsx("button", { onClick: () => setSelectedCategoryFilter(selectedCategoryFilter === category.slug ? null : category.slug), className: `px-6 py-2.5 rounded-lg text-sm font-semibold whitespace-nowrap transition-all ${selectedCategoryFilter === category.slug
|
|
315
|
-
? 'bg-gray-900 text-white hover:bg-blue-600'
|
|
316
|
-
: 'bg-gray-100 text-gray-700 hover:bg-blue-50 hover:text-blue-600'}`, children: category.name }, category.id)))] }), _jsxs("div", { id: "product-grid", className: "grid grid-cols-1 lg:grid-cols-4 gap-8", children: [_jsxs("aside", { className: "hidden lg:block col-span-1 space-y-8 sticky top-24 h-fit max-h-[calc(100vh-8rem)] overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-gray-200 scrollbar-track-transparent", children: [_jsxs("div", { className: "flex items-center justify-between pb-4 border-b border-gray-100", children: [_jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Filters" }), hasActiveFilters && (_jsxs("button", { onClick: clearAllFilters, className: "text-xs font-medium text-red-500 hover:text-red-700 flex items-center gap-1", children: [_jsx(RotateCcw, { className: "h-3 w-3" }), " Reset"] }))] }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wide mb-4", children: "Availability" }), _jsxs("label", { className: "flex items-center gap-3 cursor-pointer group p-2 -ml-2 rounded-lg hover:bg-gray-50 transition-colors", children: [_jsx("div", { className: `w-5 h-5 rounded border flex items-center justify-center transition-colors ${showInStockOnly ? 'bg-black border-black' : 'border-gray-300 group-hover:border-black'}`, children: showInStockOnly && _jsx(Check, { className: "h-3 w-3 text-white" }) }), _jsx("input", { type: "checkbox", className: "hidden", checked: showInStockOnly, onChange: () => setShowInStockOnly(!showInStockOnly) }), _jsx("span", { className: "text-sm text-gray-700 font-medium", children: "In Stock Only" })] })] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wide", children: "Brand" }), selectedBrands.length > 0 && (_jsx("button", { onClick: () => setSelectedBrands([]), className: "text-xs text-gray-600 hover:text-blue-600 font-medium transition-colors", children: "Clear" }))] }), brands.length > 0 ? (_jsxs("div", { className: "space-y-2", children: [(showMoreBrands ? brands : brands.slice(0, 6)).map((brand) => (_jsx("label", { className: "flex items-center justify-between cursor-pointer group hover:bg-blue-50 hover:text-blue-600 p-2 rounded-lg -ml-2 -mr-2 transition-colors", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("input", { type: "checkbox", checked: selectedBrands.includes(brand), onChange: () => setSelectedBrands(prev => prev.includes(brand) ? prev.filter(b => b !== brand) : [...prev, brand]), className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" }), _jsx("span", { className: "text-sm text-gray-700 font-medium group-hover:text-blue-600", children: brand })] }) }, brand))), brands.length > 6 && (_jsx("button", { onClick: () => setShowMoreBrands(!showMoreBrands), className: "text-sm text-gray-600 hover:text-blue-600 font-medium mt-2 flex items-center gap-1 transition-colors", children: showMoreBrands ? _jsxs(_Fragment, { children: ["Show less ", _jsx(ChevronUp, { className: "h-4 w-4" })] }) : _jsxs(_Fragment, { children: ["Show more ", _jsx(ChevronDown, { className: "h-4 w-4" })] }) }))] })) : (_jsx("p", { className: "text-xs text-gray-500 italic", children: "No brands available" }))] }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wide mb-4", children: "Category" }), _jsx(CategoryTree, { categories: categories, selectedCategoryIds: selectedCategories, onCategoryToggle: (categoryId, isSelected) => {
|
|
313
|
+
}, children: secondaryButtonText }))] })] }) }) })] }), _jsxs("div", { "data-content-ready": true, className: "container mx-auto px-4 sm:px-6 lg:px-8 py-8", children: [_jsxs("div", { className: "flex gap-3 mb-8 overflow-x-auto pb-2 scrollbar-hide", children: [_jsx("button", { onClick: () => setSelectedCategoryFilter(null), className: productCategoryFilterChipClass(!selectedCategoryFilter), children: "All" }), categories.map((category) => (_jsx("button", { onClick: () => setSelectedCategoryFilter(selectedCategoryFilter === category.slug ? null : category.slug), className: productCategoryFilterChipClass(selectedCategoryFilter === category.slug), children: category.name }, category.id)))] }), _jsxs("div", { id: "product-grid", className: "grid grid-cols-1 lg:grid-cols-4 gap-8", children: [_jsxs("aside", { className: "hidden lg:block col-span-1 space-y-8 sticky top-24 h-fit max-h-[calc(100vh-8rem)] overflow-y-auto pr-2 scrollbar-thin scrollbar-thumb-gray-200 scrollbar-track-transparent", children: [_jsxs("div", { className: "flex items-center justify-between pb-4 border-b border-gray-100", children: [_jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Filters" }), hasActiveFilters && (_jsxs("button", { onClick: clearAllFilters, className: "text-xs font-medium text-red-500 hover:text-red-700 flex items-center gap-1", children: [_jsx(RotateCcw, { className: "h-3 w-3" }), " Reset"] }))] }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wide mb-4", children: "Availability" }), _jsxs("label", { className: "flex items-center gap-3 cursor-pointer group p-2 -ml-2 rounded-lg hover:bg-gray-50 transition-colors", children: [_jsx("div", { className: `w-5 h-5 rounded border flex items-center justify-center transition-colors ${showInStockOnly ? 'bg-black border-black' : 'border-gray-300 group-hover:border-black'}`, children: showInStockOnly && _jsx(Check, { className: "h-3 w-3 text-white" }) }), _jsx("input", { type: "checkbox", className: "hidden", checked: showInStockOnly, onChange: () => setShowInStockOnly(!showInStockOnly) }), _jsx("span", { className: "text-sm text-gray-700 font-medium", children: "In Stock Only" })] })] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wide", children: "Brand" }), selectedBrands.length > 0 && (_jsx("button", { onClick: () => setSelectedBrands([]), className: "text-xs text-gray-600 hover:text-blue-600 font-medium transition-colors", children: "Clear" }))] }), brands.length > 0 ? (_jsxs("div", { className: "space-y-2", children: [(showMoreBrands ? brands : brands.slice(0, 6)).map((brand) => (_jsx("label", { className: "flex items-center justify-between cursor-pointer group hover:bg-blue-50 hover:text-blue-600 p-2 rounded-lg -ml-2 -mr-2 transition-colors", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("input", { type: "checkbox", checked: selectedBrands.includes(brand), onChange: () => setSelectedBrands(prev => prev.includes(brand) ? prev.filter(b => b !== brand) : [...prev, brand]), className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" }), _jsx("span", { className: "text-sm text-gray-700 font-medium group-hover:text-blue-600", children: brand })] }) }, brand))), brands.length > 6 && (_jsx("button", { onClick: () => setShowMoreBrands(!showMoreBrands), className: "text-sm text-gray-600 hover:text-blue-600 font-medium mt-2 flex items-center gap-1 transition-colors", children: showMoreBrands ? _jsxs(_Fragment, { children: ["Show less ", _jsx(ChevronUp, { className: "h-4 w-4" })] }) : _jsxs(_Fragment, { children: ["Show more ", _jsx(ChevronDown, { className: "h-4 w-4" })] }) }))] })) : (_jsx("p", { className: "text-xs text-gray-500 italic", children: "No brands available" }))] }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wide mb-4", children: "Category" }), _jsx(CategoryTree, { categories: categories, selectedCategoryIds: selectedCategories, onCategoryToggle: (categoryId, isSelected) => {
|
|
317
314
|
setSelectedCategories(prev => isSelected
|
|
318
315
|
? [...prev, categoryId]
|
|
319
316
|
: prev.filter(id => id !== categoryId));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type PdpColorSwatchProps = {
|
|
2
|
+
colorValue: string;
|
|
3
|
+
isSelected: boolean;
|
|
4
|
+
isAvailable?: boolean;
|
|
5
|
+
swatchColor: string;
|
|
6
|
+
optionImage?: string | null;
|
|
7
|
+
onSelect: () => void;
|
|
8
|
+
onClear: () => void;
|
|
9
|
+
};
|
|
10
|
+
export declare function PdpColorSwatch({ colorValue, isSelected, isAvailable, swatchColor, optionImage, onSelect, onClear, }: PdpColorSwatchProps): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=PdpColorSwatch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PdpColorSwatch.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/PdpColorSwatch.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,UAAU,EACV,WAAkB,EAClB,WAAW,EACX,WAAW,EACX,QAAQ,EACR,OAAO,GACR,EAAE,mBAAmB,+BA0ErB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export function PdpColorSwatch({ colorValue, isSelected, isAvailable = true, swatchColor, optionImage, onSelect, onClear, }) {
|
|
4
|
+
const fillStyle = optionImage
|
|
5
|
+
? {
|
|
6
|
+
backgroundImage: `url(${optionImage})`,
|
|
7
|
+
backgroundSize: 'cover',
|
|
8
|
+
backgroundPosition: 'center',
|
|
9
|
+
}
|
|
10
|
+
: {
|
|
11
|
+
backgroundColor: swatchColor,
|
|
12
|
+
boxShadow: 'inset 0px -2px 6px rgba(255, 255, 255, 0.24), inset 0px 2px 6px rgba(0, 0, 0, 0.12)',
|
|
13
|
+
};
|
|
14
|
+
return (_jsxs("span", { className: "relative inline-flex h-11 w-11 shrink-0", children: [_jsx("button", { type: "button", onClick: () => {
|
|
15
|
+
if (!isAvailable || isSelected)
|
|
16
|
+
return;
|
|
17
|
+
onSelect();
|
|
18
|
+
}, disabled: !isAvailable, title: !isAvailable
|
|
19
|
+
? `${colorValue} is unavailable with your other choices`
|
|
20
|
+
: colorValue, "aria-pressed": isSelected, "aria-disabled": !isAvailable, "aria-label": `Color: ${colorValue}`, className: `box-border flex h-11 w-11 items-center justify-center overflow-hidden rounded-full bg-white p-1.5 transition-colors ${!isAvailable
|
|
21
|
+
? 'cursor-not-allowed border-2 border-transparent opacity-35'
|
|
22
|
+
: isSelected
|
|
23
|
+
? 'border-2 border-[#FA8232]'
|
|
24
|
+
: 'border-2 border-transparent hover:border-[#E4E7E9]'}`, children: _jsx("span", { className: "block h-8 w-8 shrink-0 overflow-hidden rounded-full bg-cover bg-center", style: fillStyle }) }), isSelected ? (_jsx("button", { type: "button", onClick: (e) => {
|
|
25
|
+
e.preventDefault();
|
|
26
|
+
e.stopPropagation();
|
|
27
|
+
onClear();
|
|
28
|
+
}, title: "Clear selection", "aria-label": `Clear ${colorValue} selection`, className: "absolute -right-1 -top-1 z-10 flex h-4 w-4 items-center justify-center rounded-full bg-[#141414] text-white shadow-sm hover:bg-[#333333]", children: _jsx("svg", { width: "8", height: "8", viewBox: "0 0 8 8", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M1.5 1.5l5 5M6.5 1.5l-5 5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })) : null] }));
|
|
29
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type PdpVariationSelectorsProps = {
|
|
2
|
+
optionGroups: Record<string, string[]>;
|
|
3
|
+
selectedAttributes: Record<string, string>;
|
|
4
|
+
setAttribute: (key: string, value: string) => void;
|
|
5
|
+
isOptionAvailable?: (key: string, value: string) => boolean;
|
|
6
|
+
getOptionImage: (attributeKey: string, value: string) => string | undefined;
|
|
7
|
+
onAfterClearAttribute?: () => void;
|
|
8
|
+
storeSlug?: string;
|
|
9
|
+
showSizeGuide?: boolean;
|
|
10
|
+
colorSwatches?: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
export declare function PdpVariationSelectors({ optionGroups, selectedAttributes, setAttribute, isOptionAvailable, getOptionImage, onAfterClearAttribute, colorSwatches, }: PdpVariationSelectorsProps): import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=PdpVariationSelectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PdpVariationSelectors.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/PdpVariationSelectors.tsx"],"names":[],"mappings":"AAqCA,MAAM,MAAM,0BAA0B,GAAG;IACvC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,iBAAiB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;IAC5D,cAAc,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IAC5E,qBAAqB,CAAC,EAAE,MAAM,IAAI,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC,CAAC;AAsHF,wBAAgB,qBAAqB,CAAC,EACpC,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,iBAA8B,EAC9B,cAAc,EACd,qBAAqB,EACrB,aAAsC,GACvC,EAAE,0BAA0B,+BA4C5B"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { getSortedVariationOptionKeys, getVariationAttributeLabel, } from '../../../lib/product-variation-utils';
|
|
4
|
+
import { PdpColorSwatch } from './PdpColorSwatch';
|
|
5
|
+
const DEFAULT_COLOR_SWATCHES = {
|
|
6
|
+
White: '#FFFFFF',
|
|
7
|
+
white: '#FFFFFF',
|
|
8
|
+
Black: '#11171D',
|
|
9
|
+
black: '#11171D',
|
|
10
|
+
Gray: '#B1B5B8',
|
|
11
|
+
gray: '#B1B5B8',
|
|
12
|
+
Grey: '#B1B5B8',
|
|
13
|
+
grey: '#B1B5B8',
|
|
14
|
+
Silver: '#E0E1E1',
|
|
15
|
+
silver: '#E0E1E1',
|
|
16
|
+
Blue: '#3A6A90',
|
|
17
|
+
blue: '#3A6A90',
|
|
18
|
+
Red: '#EF4444',
|
|
19
|
+
red: '#EF4444',
|
|
20
|
+
Green: '#10B981',
|
|
21
|
+
green: '#10B981',
|
|
22
|
+
Yellow: '#FBBF24',
|
|
23
|
+
yellow: '#FBBF24',
|
|
24
|
+
Brown: '#534029',
|
|
25
|
+
brown: '#534029',
|
|
26
|
+
'Royal Brown': '#534029',
|
|
27
|
+
Navy: '#1E3A8A',
|
|
28
|
+
navy: '#1E3A8A',
|
|
29
|
+
Beige: '#E0E1E1',
|
|
30
|
+
beige: '#E0E1E1',
|
|
31
|
+
};
|
|
32
|
+
function resolveSwatchColor(value, colorSwatches) {
|
|
33
|
+
return (colorSwatches[value] ||
|
|
34
|
+
DEFAULT_COLOR_SWATCHES[value] ||
|
|
35
|
+
DEFAULT_COLOR_SWATCHES[value.toLowerCase()] ||
|
|
36
|
+
'#B1B5B8');
|
|
37
|
+
}
|
|
38
|
+
function AttributeField({ label, children, }) {
|
|
39
|
+
return (_jsxs("div", { className: "flex w-full min-w-0 flex-col items-stretch gap-2", children: [_jsx("p", { className: "m-0 text-sm font-normal leading-5 text-[#191C1F]", children: label }), children] }));
|
|
40
|
+
}
|
|
41
|
+
function VariationDropdown({ attributeKey, label, values, selectedValue, isOptionAvailable, onChange, }) {
|
|
42
|
+
const placeholder = `Select ${label.toLowerCase()}`;
|
|
43
|
+
return (_jsx(AttributeField, { label: label, children: _jsxs("div", { className: "relative h-11 w-full", children: [_jsxs("select", { id: `pdp-variation-${attributeKey}`, value: selectedValue || '', onChange: (e) => onChange(e.target.value), className: "box-border h-11 w-full appearance-none rounded-[2px] border border-[#E4E7E9] bg-white py-0 pl-4 pr-10 text-sm font-normal leading-5 text-[#475156] outline-none transition-colors focus:border-[#FA8232]", "aria-label": label, children: [_jsx("option", { value: "", children: placeholder }), values.map((value) => {
|
|
44
|
+
const available = isOptionAvailable(attributeKey, value);
|
|
45
|
+
return (_jsx("option", { value: value, disabled: !available, children: available ? value : `${value} (unavailable)` }, value));
|
|
46
|
+
})] }), _jsx("span", { "aria-hidden": true, className: "pointer-events-none absolute right-4 top-1/2 h-0 w-0 -translate-y-1/2 border-x-[5px] border-t-[6px] border-x-transparent border-t-[#ADB7BC]" })] }) }));
|
|
47
|
+
}
|
|
48
|
+
function ColorSwatchRow({ attributeKey, label, values, selectedValue, getOptionImage, colorSwatches, isOptionAvailable, setAttribute, onAfterClearAttribute, }) {
|
|
49
|
+
return (_jsx(AttributeField, { label: label, children: _jsx("div", { className: "flex min-h-11 w-full flex-wrap items-center gap-3", children: values.map((value) => (_jsx(PdpColorSwatch, { colorValue: value, isSelected: selectedValue === value, isAvailable: isOptionAvailable(attributeKey, value), swatchColor: resolveSwatchColor(value, colorSwatches), optionImage: getOptionImage(attributeKey, value), onSelect: () => setAttribute(attributeKey, value), onClear: () => {
|
|
50
|
+
setAttribute(attributeKey, '');
|
|
51
|
+
onAfterClearAttribute?.();
|
|
52
|
+
} }, value))) }) }));
|
|
53
|
+
}
|
|
54
|
+
export function PdpVariationSelectors({ optionGroups, selectedAttributes, setAttribute, isOptionAvailable = () => true, getOptionImage, onAfterClearAttribute, colorSwatches = DEFAULT_COLOR_SWATCHES, }) {
|
|
55
|
+
const keys = getSortedVariationOptionKeys(optionGroups);
|
|
56
|
+
if (keys.length === 0)
|
|
57
|
+
return null;
|
|
58
|
+
const colorKeys = keys.filter((key) => key === 'color');
|
|
59
|
+
const dropdownKeys = keys.filter((key) => key !== 'color');
|
|
60
|
+
return (_jsxs("div", { className: "mb-8 flex w-full flex-col items-stretch gap-4", children: [colorKeys.map((attributeKey) => (_jsx(ColorSwatchRow, { attributeKey: attributeKey, label: getVariationAttributeLabel(attributeKey), values: optionGroups[attributeKey] ?? [], selectedValue: selectedAttributes[attributeKey], getOptionImage: getOptionImage, colorSwatches: colorSwatches, isOptionAvailable: isOptionAvailable, setAttribute: setAttribute, onAfterClearAttribute: onAfterClearAttribute }, attributeKey))), dropdownKeys.length > 0 ? (_jsx("div", { className: "grid w-full grid-cols-1 gap-x-6 gap-y-4 sm:grid-cols-2", children: dropdownKeys.map((attributeKey) => (_jsx(VariationDropdown, { attributeKey: attributeKey, label: getVariationAttributeLabel(attributeKey), values: optionGroups[attributeKey] ?? [], selectedValue: selectedAttributes[attributeKey], isOptionAvailable: isOptionAvailable, onChange: (value) => {
|
|
61
|
+
setAttribute(attributeKey, value);
|
|
62
|
+
if (!value)
|
|
63
|
+
onAfterClearAttribute?.();
|
|
64
|
+
} }, attributeKey))) })) : null] }));
|
|
65
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { StoreConfig } from '../../../lib/store-types';
|
|
2
|
+
interface StoreCartSheetProps {
|
|
3
|
+
storeConfig: StoreConfig;
|
|
4
|
+
title: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function StoreCartSheet({ storeConfig, title }: StoreCartSheetProps): import("react").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=StoreCartSheet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StoreCartSheet.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/StoreCartSheet.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAKvD,UAAU,mBAAmB;IAC3B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,cAAc,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,mBAAmB,+BA+GzE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ShoppingBag, Minus, Plus, Trash2 } from 'lucide-react';
|
|
4
|
+
import { Sheet } from '../../../components/ui/sheet';
|
|
5
|
+
import { Button } from '../../../components/ui/button';
|
|
6
|
+
import { CheckoutButton } from '../../../components/ui/checkout-button';
|
|
7
|
+
import { ImageWithFallback } from '../../../components/ui/image-with-fallback';
|
|
8
|
+
import { useStore } from '../../../lib/store-context';
|
|
9
|
+
import { formatCurrency } from '../../../lib/utils';
|
|
10
|
+
import { getCartLineImage } from '../../../lib/product-variation-utils';
|
|
11
|
+
import { getLayoutText } from '../../../lib/utils/asset-helpers';
|
|
12
|
+
export function StoreCartSheet({ storeConfig, title }) {
|
|
13
|
+
const { cart, removeFromCart, updateCartQuantity, isCartOpen, setIsCartOpen, cartTotal, } = useStore();
|
|
14
|
+
const currency = storeConfig.settings?.currency || 'USD';
|
|
15
|
+
return (_jsx(Sheet, { isOpen: isCartOpen, onClose: () => setIsCartOpen(false), title: title, side: "right", portal: true, className: "w-full max-w-[min(28rem,100dvw)] box-border border-l border-gray-100", contentClassName: "flex flex-col min-h-0 h-full !px-0 !pb-0", children: cart.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center flex-1 px-6 pb-8 text-center space-y-4", children: [_jsx(ShoppingBag, { className: "h-12 w-12 text-gray-300" }), _jsx("p", { className: "text-gray-500", children: getLayoutText(storeConfig, 'header.cartEmpty', 'Your bag is empty.') }), _jsx(Button, { onClick: () => setIsCartOpen(false), variant: "outline", className: "mt-2", children: getLayoutText(storeConfig, 'common.continueShopping', 'Continue Shopping') })] })) : (_jsxs("div", { className: "flex flex-col flex-1 min-h-0", children: [_jsx("div", { className: "flex-1 min-h-0 overflow-y-auto overflow-x-hidden px-5 sm:px-6 py-4 space-y-6", children: cart.map((item) => (_jsxs("div", { className: "flex gap-3 sm:gap-4 min-w-0", children: [_jsx("div", { className: "w-[4.5rem] sm:w-20 h-24 bg-gray-100 shrink-0 overflow-hidden relative", children: _jsx(ImageWithFallback, { src: getCartLineImage(item) || item.product.images[0], alt: item.product.name, className: "w-full h-full object-cover" }) }), _jsxs("div", { className: "flex-1 min-w-0 flex flex-col justify-between gap-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("h4", { className: "font-medium text-sm line-clamp-2 text-gray-900", children: item.product.name }), item.variantName ? (_jsx("p", { className: "text-gray-500 text-xs mt-1 truncate", children: item.variantName })) : null] }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-2 gap-y-2", children: [_jsxs("div", { className: "flex items-center border border-gray-200 rounded-full shrink-0", children: [_jsx("button", { type: "button", onClick: () => updateCartQuantity(item.id, item.quantity - 1), className: "p-1 hover:bg-gray-100 rounded-full", "aria-label": "Decrease quantity", children: _jsx(Minus, { className: "h-3 w-3" }) }), _jsx("span", { className: "text-xs font-medium px-2 tabular-nums", children: item.quantity }), _jsx("button", { type: "button", onClick: () => updateCartQuantity(item.id, item.quantity + 1), className: "p-1 hover:bg-gray-100 rounded-full", "aria-label": "Increase quantity", children: _jsx(Plus, { className: "h-3 w-3" }) })] }), _jsxs("div", { className: "flex items-center gap-2 shrink-0 ml-auto", children: [_jsx("span", { className: "font-medium text-sm tabular-nums whitespace-nowrap text-gray-900", children: formatCurrency(item.price * item.quantity, item.product?.currency || currency) }), _jsx("button", { type: "button", onClick: () => removeFromCart(item.id), className: "text-gray-400 hover:text-red-500 p-1", "aria-label": "Remove item", children: _jsx(Trash2, { className: "h-4 w-4" }) })] })] })] })] }, item.id))) }), _jsxs("div", { className: "shrink-0 border-t border-gray-100 px-5 sm:px-6 pt-4 pb-6 pb-[max(1.5rem,env(safe-area-inset-bottom))] space-y-4 bg-white", children: [_jsxs("div", { className: "flex justify-between items-center gap-3 font-medium text-lg min-w-0", children: [_jsx("span", { className: "text-gray-900", children: "Subtotal" }), _jsx("span", { className: "tabular-nums whitespace-nowrap text-gray-900", children: formatCurrency(cartTotal, currency) })] }), _jsx("p", { className: "text-xs text-gray-500 text-center", children: "Shipping and taxes calculated at checkout." }), _jsx(CheckoutButton, { storeConfig: storeConfig, className: "w-full h-12 bg-black text-white hover:bg-gray-800 rounded-full font-bold" })] })] })) }));
|
|
16
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StoreHeader.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/StoreHeader.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"StoreHeader.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/components/StoreHeader.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AA8BvD,UAAU,gBAAgB;IACxB,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAWD,wBAAgB,WAAW,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,aAAiB,EAAE,EAAE,gBAAgB,+BA8d9F"}
|
|
@@ -37,10 +37,17 @@ import { useStore } from '../../../lib/store-context';
|
|
|
37
37
|
import { getLogoUrl } from '../../../lib/utils/asset-helpers';
|
|
38
38
|
import { AvatarImage } from '../../../components/ui/avatar-image';
|
|
39
39
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
40
|
+
import { StoreCartSheet } from './StoreCartSheet';
|
|
41
|
+
function headerNavLinkClass(isDarkTheme) {
|
|
42
|
+
return cn('px-2 py-2.5 text-[11px] font-bold uppercase tracking-[0.12em] transition-colors underline-offset-4 decoration-2 inline-flex items-center gap-2 whitespace-nowrap', isDarkTheme
|
|
43
|
+
? 'text-gray-400 hover:text-white hover:underline'
|
|
44
|
+
: 'text-gray-600 hover:text-black hover:underline');
|
|
45
|
+
}
|
|
40
46
|
export function StoreHeader({ storeConfig: initialConfig, cartItemCount = 0 }) {
|
|
41
|
-
const { store, wishlist } = useStore();
|
|
47
|
+
const { store, wishlist, setIsCartOpen, cartCount: storeCartCount } = useStore();
|
|
42
48
|
const storeConfig = store || initialConfig;
|
|
43
49
|
const wishlistCount = wishlist.length;
|
|
50
|
+
const displayCartCount = storeCartCount > 0 ? storeCartCount : cartItemCount;
|
|
44
51
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
|
45
52
|
const [searchOpen, setSearchOpen] = useState(false);
|
|
46
53
|
const [searchQuery, setSearchQuery] = useState('');
|
|
@@ -88,24 +95,18 @@ export function StoreHeader({ storeConfig: initialConfig, cartItemCount = 0 }) {
|
|
|
88
95
|
const categoriesToDisplay = categories.slice(0, categoriesToShowCount);
|
|
89
96
|
const overflowCategories = categories.slice(categoriesToShowCount);
|
|
90
97
|
return (_jsxs(_Fragment, { children: [menuItems.map((item, index) => {
|
|
91
|
-
return (_jsx(Link, { href: `/${storeConfig.slug}${item.href}`, className:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}), categoriesToDisplay.map((cat) => (_jsx(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: cn("px-4 py-2.5 text-[11px] font-bold uppercase tracking-[0.12em] transition-all rounded-full flex items-center gap-2 group/nav whitespace-nowrap", isDarkTheme
|
|
95
|
-
? "text-gray-400 hover:text-white hover:bg-white/10"
|
|
96
|
-
: "text-gray-600 hover:text-black hover:bg-gray-100"), children: cat.name }, `cat-direct-${cat.id}`))), overflowCategories.length > 0 && (_jsxs("div", { className: "relative group", onMouseEnter: () => setIsCatalogueOpen(true), onMouseLeave: () => setIsCatalogueOpen(false), children: [_jsxs("button", { className: cn("px-4 py-2.5 text-[11px] font-bold uppercase tracking-[0.12em] transition-all rounded-full flex items-center gap-2 group/nav whitespace-nowrap", isDarkTheme
|
|
97
|
-
? "text-gray-400 hover:text-white hover:bg-white/10"
|
|
98
|
-
: "text-gray-600 hover:text-black hover:bg-gray-100"), children: [categoriesToDisplay.length > 0 ? "More" : "Catalogue", _jsx(ChevronDown, { className: cn("w-3.5 h-3.5 transition-transform duration-300", isCatalogueOpen && "rotate-180") })] }), _jsx(AnimatePresence, { children: isCatalogueOpen && (_jsx(motion.div, { initial: { opacity: 0, y: 10, scale: 0.95 }, animate: { opacity: 1, y: 0, scale: 1 }, exit: { opacity: 0, y: 10, scale: 0.95 }, transition: { duration: 0.2 }, className: cn("absolute top-full left-1/2 -translate-x-1/2 mt-2 w-64 p-3 rounded-2xl shadow-2xl border backdrop-blur-2xl z-50", isDarkTheme ? "bg-black/90 border-white/10" : "bg-white/95 border-gray-100"), children: _jsx("div", { className: "grid gap-1 overflow-y-auto max-h-[70vh]", children: overflowCategories.map((cat) => (_jsxs(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: cn("flex items-center justify-between px-4 py-3 rounded-xl transition-all group/item", isDarkTheme ? "hover:bg-white/5" : "hover:bg-gray-50"), onClick: () => setIsCatalogueOpen(false), children: [_jsx("span", { className: cn("text-sm font-medium", isDarkTheme ? "text-gray-300 group-hover/item:text-white" : "text-gray-600 group-hover/item:text-black"), children: cat.name }), _jsx(ChevronRight, { className: "w-4 h-4 opacity-0 -translate-x-2 group-hover/item:opacity-100 group-hover/item:translate-x-0 transition-all text-gray-400" })] }, `cat-overflow-${cat.id}`))) }) })) })] }))] }));
|
|
99
|
-
})() }), _jsxs("div", { className: "flex items-center gap-0.5 sm:gap-1 lg:gap-2 flex-shrink-0 z-20 ml-auto lg:ml-0 lg:pl-1", children: [_jsx(Button, { variant: "ghost", size: "icon", className: cn("h-9 w-9 sm:h-10 sm:w-10 rounded-full transition-all relative", isDarkTheme ? "hover:bg-white/10 text-gray-300" : "hover:bg-gray-100 text-gray-600", searchOpen && "bg-transparent shadow-none"), onClick: () => setSearchOpen(true), children: _jsx(Search, { className: "h-5 w-5" }) }), storeConfig.features.wishlist && (_jsx(Link, { href: `/${storeConfig.slug}/wishlist`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: "h-9 w-9 sm:h-10 sm:w-10 relative rounded-full group hover:bg-red-50 dark:hover:bg-red-900/10", children: [_jsx(Heart, { className: cn("h-5 w-5 transition-all group-hover:scale-110", wishlistCount > 0 && "fill-red-500 text-red-500") }), wishlistCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 h-4 w-4 text-[9px] font-bold text-white rounded-full flex items-center justify-center shadow-lg", style: { backgroundColor: primaryColor }, children: wishlistCount }))] }) })), storeConfig.layout === 'motivational-speaker' && isAuthenticated && (_jsx(Link, { href: `/${storeConfig.slug}/account?tab=learning`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: cn("h-9 w-9 sm:h-10 sm:w-10 relative rounded-full group transition-all", isDarkTheme ? "hover:bg-blue-900/20 text-blue-400" : "hover:bg-blue-50 text-blue-600"), children: [_jsx(BookOpen, { className: "h-5 w-5 transition-all group-hover:scale-110" }), _jsx("span", { className: "sr-only", children: "My Learning" })] }) })), storeConfig.features.cart && (_jsx(Link, { href: `/${storeConfig.slug}/cart`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: "h-9 w-9 sm:h-10 sm:w-10 relative rounded-full group hover:bg-gray-100 dark:hover:bg-white/10", children: [_jsx(ShoppingCart, { className: "h-5 w-5 group-hover:scale-110 transition-all" }), cartItemCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 h-4 w-4 text-[9px] font-bold text-white rounded-full flex items-center justify-center shadow-lg", style: { backgroundColor: primaryColor }, children: cartItemCount }))] }) })), isAuthenticated ? (_jsx(Link, { href: `/${storeConfig.slug}/account`, children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-9 w-9 sm:h-10 sm:w-10 rounded-full overflow-hidden border-2 border-transparent hover:border-gray-200 transition-all", children: _jsx(AvatarImage, { src: user?.avatar, alt: "User", size: 32 }) }) })) : (_jsx(Button, { className: "ml-1 hidden sm:block h-10 px-6 rounded-full font-bold text-xs uppercase tracking-widest transition-all shadow-md hover:shadow-lg active:scale-95", style: { backgroundColor: primaryColor, color: 'white' }, onClick: () => openLogin({
|
|
98
|
+
return (_jsx(Link, { href: `/${storeConfig.slug}${item.href}`, className: headerNavLinkClass(isDarkTheme), children: item.label }, `nav-${index}-${item.href}`));
|
|
99
|
+
}), categoriesToDisplay.map((cat) => (_jsx(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: headerNavLinkClass(isDarkTheme), children: cat.name }, `cat-direct-${cat.id}`))), overflowCategories.length > 0 && (_jsxs("div", { className: "relative group", onMouseEnter: () => setIsCatalogueOpen(true), onMouseLeave: () => setIsCatalogueOpen(false), children: [_jsxs("button", { className: headerNavLinkClass(isDarkTheme), children: [categoriesToDisplay.length > 0 ? "More" : "Catalogue", _jsx(ChevronDown, { className: cn("w-3.5 h-3.5 transition-transform duration-300", isCatalogueOpen && "rotate-180") })] }), _jsx(AnimatePresence, { children: isCatalogueOpen && (_jsx(motion.div, { initial: { opacity: 0, y: 10, scale: 0.95 }, animate: { opacity: 1, y: 0, scale: 1 }, exit: { opacity: 0, y: 10, scale: 0.95 }, transition: { duration: 0.2 }, className: cn("absolute top-full left-1/2 -translate-x-1/2 mt-2 w-64 p-3 rounded-2xl shadow-2xl border backdrop-blur-2xl z-50", isDarkTheme ? "bg-black/90 border-white/10" : "bg-white/95 border-gray-100"), children: _jsx("div", { className: "grid gap-1 overflow-y-auto max-h-[70vh]", children: overflowCategories.map((cat) => (_jsxs(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: cn("flex items-center justify-between px-4 py-3 rounded-xl transition-all group/item", isDarkTheme ? "hover:bg-white/5" : "hover:bg-gray-50"), onClick: () => setIsCatalogueOpen(false), children: [_jsx("span", { className: cn("text-sm font-medium", isDarkTheme ? "text-gray-300 group-hover/item:text-white" : "text-gray-600 group-hover/item:text-black"), children: cat.name }), _jsx(ChevronRight, { className: "w-4 h-4 opacity-0 -translate-x-2 group-hover/item:opacity-100 group-hover/item:translate-x-0 transition-all text-gray-400" })] }, `cat-overflow-${cat.id}`))) }) })) })] }))] }));
|
|
100
|
+
})() }), _jsxs("div", { className: "flex items-center gap-0.5 sm:gap-1 lg:gap-2 flex-shrink-0 z-20 ml-auto lg:ml-0 lg:pl-1", children: [_jsx(Button, { variant: "ghost", size: "icon", className: cn("h-9 w-9 sm:h-10 sm:w-10 rounded-full transition-all relative", isDarkTheme ? "hover:bg-white/10 text-gray-300" : "hover:bg-gray-100 text-gray-600", searchOpen && "bg-transparent shadow-none"), onClick: () => setSearchOpen(true), children: _jsx(Search, { className: "h-5 w-5" }) }), storeConfig.features.wishlist && (_jsx(Link, { href: `/${storeConfig.slug}/wishlist`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: "h-9 w-9 sm:h-10 sm:w-10 relative rounded-full group hover:bg-red-50 dark:hover:bg-red-900/10", children: [_jsx(Heart, { className: cn("h-5 w-5 transition-all group-hover:scale-110", wishlistCount > 0 && "fill-red-500 text-red-500") }), wishlistCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 h-4 w-4 text-[9px] font-bold text-white rounded-full flex items-center justify-center shadow-lg", style: { backgroundColor: primaryColor }, children: wishlistCount }))] }) })), storeConfig.layout === 'motivational-speaker' && isAuthenticated && (_jsx(Link, { href: `/${storeConfig.slug}/account?tab=learning`, children: _jsxs(Button, { variant: "ghost", size: "icon", className: cn("h-9 w-9 sm:h-10 sm:w-10 relative rounded-full group transition-all", isDarkTheme ? "hover:bg-blue-900/20 text-blue-400" : "hover:bg-blue-50 text-blue-600"), children: [_jsx(BookOpen, { className: "h-5 w-5 transition-all group-hover:scale-110" }), _jsx("span", { className: "sr-only", children: "My Learning" })] }) })), storeConfig.features.cart && (_jsxs(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => setIsCartOpen(true), className: "h-9 w-9 sm:h-10 sm:w-10 relative rounded-full group hover:bg-gray-100 dark:hover:bg-white/10", "aria-label": "Open shopping bag", children: [_jsx(ShoppingCart, { className: "h-5 w-5 group-hover:scale-110 transition-all" }), displayCartCount > 0 && (_jsx("span", { className: "absolute -top-1 -right-1 h-4 w-4 text-[9px] font-bold text-white rounded-full flex items-center justify-center shadow-lg", style: { backgroundColor: primaryColor }, children: displayCartCount }))] })), isAuthenticated ? (_jsx(Link, { href: `/${storeConfig.slug}/account`, children: _jsx(Button, { variant: "ghost", size: "icon", className: "h-9 w-9 sm:h-10 sm:w-10 rounded-full overflow-hidden border-2 border-transparent hover:border-gray-200 transition-all", children: _jsx(AvatarImage, { src: user?.avatar, alt: "User", size: 32 }) }) })) : (_jsx(Button, { className: "ml-1 hidden sm:block h-10 px-6 rounded-full font-bold text-xs uppercase tracking-widest transition-all shadow-md hover:shadow-lg active:scale-95", style: { backgroundColor: primaryColor, color: 'white' }, onClick: () => openLogin({
|
|
100
101
|
callbackUrl: pathname || `/${storeConfig.slug}`,
|
|
101
102
|
}), children: storeConfig.headerConfig?.loginButtonText || 'Log In' })), _jsx(Button, { variant: "ghost", size: "icon", className: "lg:hidden h-9 w-9 sm:h-10 sm:w-10 rounded-full", onClick: () => setMobileMenuOpen(true), children: _jsx(Menu, { className: "h-6 w-6" }) })] })] }) }) }), _jsx(AnimatePresence, { children: searchOpen && (_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, className: "fixed inset-0 z-[100] flex flex-col items-center justify-start pt-24 px-4 bg-white/80 dark:bg-black/80 backdrop-blur-2xl", children: _jsxs(motion.div, { initial: { y: -20, opacity: 0 }, animate: { y: 0, opacity: 1 }, exit: { y: -20, opacity: 0 }, className: "w-full max-w-3xl relative", children: [_jsxs("div", { className: "relative flex items-center group", children: [_jsx(Search, { className: "absolute left-6 h-6 w-6 text-gray-400 group-focus-within:text-black dark:group-focus-within:text-white transition-colors" }), _jsx("input", { ref: searchInputRef, type: "text", placeholder: storeConfig.headerConfig?.searchPlaceholder || "Search products, categories, guides...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: cn("w-full pl-16 pr-24 py-6 text-2xl md:text-3xl font-light bg-transparent border-b-2 border-gray-200 dark:border-white/10 focus:outline-none focus:border-black dark:focus:border-white transition-all", isDarkTheme ? "text-white placeholder-gray-600" : "text-black placeholder-gray-300"), onKeyDown: (e) => e.key === 'Escape' && setSearchOpen(false) }), _jsxs("div", { className: "absolute right-0 flex items-center gap-2", children: [searchQuery && (_jsx(Button, { variant: "ghost", size: "icon", onClick: () => setSearchQuery(''), className: "h-10 w-10 rounded-full", children: _jsx(X, { className: "h-5 w-5 text-gray-400" }) })), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setSearchOpen(false), className: "text-xs font-bold uppercase tracking-widest text-gray-400 hover:text-black dark:hover:text-white", children: "Esc" })] })] }), _jsxs("div", { className: "mt-12 grid grid-cols-1 md:grid-cols-2 gap-12", children: [_jsxs("div", { className: "space-y-6", children: [_jsx("h4", { className: "text-[10px] font-black uppercase tracking-[0.3em] text-gray-400", children: "Quick Links" }), _jsx("div", { className: "flex flex-wrap gap-2", children: ['Courses', 'Mentorship', 'Free Guides', 'Memberships', 'Contact'].map((tag) => (_jsx("button", { className: cn("px-4 py-2 rounded-full text-sm border transition-all", isDarkTheme
|
|
102
103
|
? "border-white/10 hover:border-white text-gray-400 hover:text-white"
|
|
103
104
|
: "border-gray-200 hover:border-black text-gray-600 hover:text-black"), children: tag }, tag))) })] }), _jsxs("div", { className: "space-y-6", children: [_jsx("h4", { className: "text-[10px] font-black uppercase tracking-[0.3em] text-gray-400", children: "Popular Categories" }), _jsx("div", { className: "grid gap-3", children: parentCategories.map((cat) => (_jsxs(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: "flex items-center gap-3 group", onClick: () => setSearchOpen(false), children: [_jsx("div", { className: "w-10 h-10 rounded-lg bg-gray-100 dark:bg-white/5 flex items-center justify-center group-hover:scale-110 transition-transform", children: _jsx(ChevronRight, { className: "w-4 h-4 text-gray-400" }) }), _jsx("span", { className: "text-lg font-medium text-gray-500 group-hover:text-black dark:group-hover:text-white transition-colors", children: cat.name })] }, cat.id))) })] })] })] }) })) }), _jsx(AnimatePresence, { children: mobileMenuOpen && (_jsxs("div", { className: "fixed inset-0 z-[100] lg:hidden", children: [_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, className: "absolute inset-0 bg-black/60 backdrop-blur-md", onClick: () => setMobileMenuOpen(false) }), _jsxs(motion.nav, { initial: { x: '100%' }, animate: { x: 0 }, exit: { x: '100%' }, transition: { type: "spring", damping: 25, stiffness: 200 }, className: cn("absolute right-0 top-0 bottom-0 w-[300px] shadow-2xl p-8 flex flex-col", isDarkTheme ? "bg-black text-white" : "bg-white text-black"), children: [_jsxs("div", { className: "flex items-center justify-between mb-12", children: [_jsx(StoreLogo, { storeConfig: storeConfig, className: "h-8 w-8" }), _jsx(Button, { variant: "ghost", size: "icon", onClick: () => setMobileMenuOpen(false), children: _jsx(X, { className: "h-6 w-6" }) })] }), _jsxs("div", { className: "flex flex-col gap-8", children: [(storeConfig.navigation?.main ?? []).map((item, i) => {
|
|
104
105
|
return (_jsx(Link, { href: `/${storeConfig.slug}${item.href}`, className: "text-3xl font-bold tracking-tight hover:opacity-50 transition-opacity flex items-center gap-4", onClick: () => setMobileMenuOpen(false), children: item.label }, i));
|
|
105
|
-
}), _jsxs("div", { className: "pt-8 space-y-4 border-t border-gray-100 dark:border-white/10", children: [_jsx("h4", { className: "text-[10px] font-black uppercase tracking-[0.3em] text-gray-400", children: "Catalogue" }), _jsx("div", { className: "grid gap-4", children: parentCategories.map((cat) => (_jsx(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: "text-lg font-medium text-gray-500 hover:text-black dark:hover:text-white transition-colors", onClick: () => setMobileMenuOpen(false), children: cat.name }, cat.id))) })] })] }), _jsxs("div", { className: "mt-auto pt-8 border-t border-gray-100 dark:border-white/10 flex flex-col gap-6", children: [!isAuthenticated ? (_jsx(Button, { className: "w-full h-14 rounded-full font-bold text-sm uppercase tracking-widest shadow-xl", style: { backgroundColor: primaryColor, color: 'white' }, onClick: () => {
|
|
106
|
+
}), _jsxs("div", { className: "pt-8 space-y-4 border-t border-gray-100 dark:border-white/10", children: [_jsx("h4", { className: "text-[10px] font-black uppercase tracking-[0.3em] text-gray-400", children: "Catalogue" }), _jsx("div", { className: "grid gap-4", children: parentCategories.map((cat) => (_jsx(Link, { href: `/${storeConfig.slug}/categories/${cat.slug}`, className: "text-lg font-medium text-gray-500 hover:text-black dark:hover:text-white hover:underline underline-offset-4 transition-colors", onClick: () => setMobileMenuOpen(false), children: cat.name }, cat.id))) })] })] }), _jsxs("div", { className: "mt-auto pt-8 border-t border-gray-100 dark:border-white/10 flex flex-col gap-6", children: [!isAuthenticated ? (_jsx(Button, { className: "w-full h-14 rounded-full font-bold text-sm uppercase tracking-widest shadow-xl", style: { backgroundColor: primaryColor, color: 'white' }, onClick: () => {
|
|
106
107
|
setMobileMenuOpen(false);
|
|
107
108
|
openLogin({
|
|
108
109
|
callbackUrl: pathname || `/${storeConfig.slug}`,
|
|
109
110
|
});
|
|
110
|
-
}, children: "Sign In" })) : (_jsx(Link, { href: `/${storeConfig.slug}/account`, children: _jsx(Button, { variant: "outline", className: "w-full h-14 rounded-full font-bold text-sm uppercase tracking-widest", children: "My Account" }) })), _jsxs("div", { className: "flex justify-center gap-6 text-gray-400", children: [_jsx(Instagram, { className: "w-5 h-5" }), _jsx(Twitter, { className: "w-5 h-5" }), _jsx(Youtube, { className: "w-5 h-5" })] })] })] })] })) })] }));
|
|
111
|
+
}, children: "Sign In" })) : (_jsx(Link, { href: `/${storeConfig.slug}/account`, children: _jsx(Button, { variant: "outline", className: "w-full h-14 rounded-full font-bold text-sm uppercase tracking-widest", children: "My Account" }) })), _jsxs("div", { className: "flex justify-center gap-6 text-gray-400", children: [_jsx(Instagram, { className: "w-5 h-5" }), _jsx(Twitter, { className: "w-5 h-5" }), _jsx(Youtube, { className: "w-5 h-5" })] })] })] })] })) }), storeConfig.features.cart && (_jsx(StoreCartSheet, { storeConfig: storeConfig, title: `Shopping Bag (${displayCartCount})` }))] }));
|
|
111
112
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClothingMinimalHeader.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/shared/components/headers/ClothingMinimalHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"ClothingMinimalHeader.d.ts","sourceRoot":"","sources":["../../../../../src/layouts/shared/components/headers/ClothingMinimalHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAgB1D,UAAU,0BAA0B;IAClC,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,qBAAqB,CAAC,EAAE,WAAW,EAAE,EAAE,0BAA0B,+BA6JhF"}
|
|
@@ -2,22 +2,20 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { Button } from '../../../../components/ui/button';
|
|
4
4
|
import { Sheet } from '../../../../components/ui/sheet';
|
|
5
|
-
import {
|
|
5
|
+
import { StoreCartSheet } from '../StoreCartSheet';
|
|
6
6
|
import { useStore } from '../../../../lib/store-context';
|
|
7
|
-
import {
|
|
8
|
-
import { ShoppingBag, Menu, Search, Trash2, Plus, Minus } from 'lucide-react';
|
|
7
|
+
import { ShoppingBag, Menu, Search } from 'lucide-react';
|
|
9
8
|
import Link from 'next/link';
|
|
10
9
|
import { useState, useEffect } from 'react';
|
|
11
10
|
import { usePathname } from 'next/navigation';
|
|
12
|
-
import {
|
|
13
|
-
import { getCartLineImage } from '../../../../lib/product-variation-utils';
|
|
11
|
+
import { formatStoreDisplayName } from '../../../../lib/utils';
|
|
14
12
|
import { getLayoutText, getLogoUrl } from '../../../../lib/utils/asset-helpers';
|
|
15
13
|
import { StoreLogo } from '../../../../components/ui/store-logos';
|
|
16
14
|
import { useAuth } from '../../../../lib/auth-context';
|
|
17
15
|
import { AvatarImage } from '../../../../components/ui/avatar-image';
|
|
18
16
|
import { User } from 'lucide-react';
|
|
19
17
|
export function ClothingMinimalHeader({ storeConfig }) {
|
|
20
|
-
const {
|
|
18
|
+
const { isCartOpen, setIsCartOpen, cartCount } = useStore();
|
|
21
19
|
const pathname = usePathname();
|
|
22
20
|
const { isAuthenticated, user, openLogin } = useAuth();
|
|
23
21
|
const layoutConfig = storeConfig.layoutConfig;
|
|
@@ -30,7 +28,7 @@ export function ClothingMinimalHeader({ storeConfig }) {
|
|
|
30
28
|
}, []);
|
|
31
29
|
return (_jsxs(_Fragment, { children: [layoutConfig?.sections?.header?.show !== false && (_jsx("header", { className: "fixed top-0 w-full z-40 bg-white/90 backdrop-blur-sm transition-all duration-300 border-b border-transparent hover:border-gray-100", children: _jsxs("div", { className: "container mx-auto px-4 md:px-8 h-20 flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-6", children: [_jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsMenuOpen(true), className: "hover:bg-gray-100 rounded-full", children: _jsx(Menu, { className: "h-5 w-5" }) }), storeConfig.features.search && (_jsx(Button, { variant: "ghost", size: "icon", onClick: () => setIsSearchOpen(!isSearchOpen), className: "hidden md:flex hover:bg-gray-100 rounded-full", children: _jsx(Search, { className: "h-5 w-5" }) }))] }), !getLogoUrl(storeConfig) && (_jsx(Link, { href: `/${storeConfig.slug}`, className: "text-xl md:text-2xl font-bold tracking-tight absolute left-1/2 -translate-x-1/2 whitespace-nowrap", children: storeDisplayName })), getLogoUrl(storeConfig) && (_jsx(Link, { href: `/${storeConfig.slug}`, className: "absolute left-1/2 -translate-x-1/2", children: _jsx(StoreLogo, { storeConfig: storeConfig, className: "h-10 w-10 transition-all duration-300 hover:opacity-90", alt: storeDisplayName }) })), _jsxs("div", { className: "flex items-center gap-6", children: [isAuthenticated && user ? (_jsx(Link, { href: `/${storeConfig.slug}/account`, className: "hidden md:flex items-center gap-2 text-sm font-medium hover:text-gray-600", children: user.avatar ? (_jsx("div", { className: "h-6 w-6 rounded-full overflow-hidden", children: _jsx(AvatarImage, { src: user.avatar, alt: `${user.firstName} ${user.lastName}` || 'User' }) })) : (_jsx(User, { className: "h-5 w-5" })) })) : (_jsx("button", { type: "button", className: "hidden md:block text-sm font-medium hover:text-gray-600", onClick: () => openLogin({
|
|
32
30
|
callbackUrl: pathname || `/${storeConfig.slug}`,
|
|
33
|
-
}), children: storeConfig.headerConfig?.loginButtonText || 'Log In' })), _jsxs(Button, { variant: "ghost", size: "icon", onClick: () => setIsCartOpen(true), className: "relative hover:bg-gray-100 rounded-full", children: [_jsx(ShoppingBag, { className: "h-5 w-5" }), isClient && cartCount > 0 && (_jsx("span", { className: "absolute top-2 right-2 h-2 w-2 bg-black rounded-full animate-pulse" }))] })] })] }) })), isSearchOpen && storeConfig.features.search && (_jsx("div", { className: "fixed inset-0 z-50 bg-white/95 backdrop-blur-md pt-20", children: _jsx("div", { className: "container mx-auto px-4 md:px-8", children: _jsxs("div", { className: "relative max-w-2xl mx-auto", children: [_jsx(Search, { className: "absolute left-4 top-1/2 -translate-y-1/2 h-5 w-5 text-gray-400" }), _jsx("input", { type: "text", placeholder: getLayoutText(storeConfig, 'header.searchPlaceholder', 'Search products...'), autoFocus: true, className: "w-full pl-12 pr-4 py-4 text-lg border-b-2 border-black focus:outline-none", onBlur: () => setIsSearchOpen(false) })] }) }) })), _jsx(
|
|
31
|
+
}), children: storeConfig.headerConfig?.loginButtonText || 'Log In' })), _jsxs(Button, { variant: "ghost", size: "icon", onClick: () => setIsCartOpen(true), className: "relative hover:bg-gray-100 rounded-full", children: [_jsx(ShoppingBag, { className: "h-5 w-5" }), isClient && cartCount > 0 && (_jsx("span", { className: "absolute top-2 right-2 h-2 w-2 bg-black rounded-full animate-pulse" }))] })] })] }) })), isSearchOpen && storeConfig.features.search && (_jsx("div", { className: "fixed inset-0 z-50 bg-white/95 backdrop-blur-md pt-20", children: _jsx("div", { className: "container mx-auto px-4 md:px-8", children: _jsxs("div", { className: "relative max-w-2xl mx-auto", children: [_jsx(Search, { className: "absolute left-4 top-1/2 -translate-y-1/2 h-5 w-5 text-gray-400" }), _jsx("input", { type: "text", placeholder: getLayoutText(storeConfig, 'header.searchPlaceholder', 'Search products...'), autoFocus: true, className: "w-full pl-12 pr-4 py-4 text-lg border-b-2 border-black focus:outline-none", onBlur: () => setIsSearchOpen(false) })] }) }) })), _jsx(StoreCartSheet, { storeConfig: storeConfig, title: `Shopping Bag (${cartCount})` }), _jsxs(Sheet, { isOpen: isMenuOpen, onClose: () => setIsMenuOpen(false), title: "Menu", side: "left", children: [_jsx("div", { className: "pt-4 pb-6", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search...", className: "w-full pl-10 pr-4 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:border-black transition-colors" })] }) }), _jsxs("nav", { className: "flex flex-col space-y-6 text-lg font-medium", children: [_jsx(Link, { href: `/${storeConfig.slug}/products`, onClick: () => setIsMenuOpen(false), className: "hover:text-gray-500", children: "Shop All" }), _jsx(Link, { href: `/${storeConfig.slug}/categories`, onClick: () => setIsMenuOpen(false), className: "hover:text-gray-500", children: "Categories" }), _jsx("div", { className: "h-px bg-gray-100 my-2" }), _jsx(Link, { href: `/${storeConfig.slug}/about`, onClick: () => setIsMenuOpen(false), className: "hover:text-gray-500 text-base font-normal", children: "Our Story" }), _jsx(Link, { href: `/${storeConfig.slug}/contact`, onClick: () => setIsMenuOpen(false), className: "hover:text-gray-500 text-base font-normal", children: "Contact" }), _jsx("div", { className: "mt-auto pt-12 text-sm font-normal text-gray-500 flex flex-col gap-3", children: isAuthenticated ? (_jsxs(_Fragment, { children: [_jsx(Link, { href: `/${storeConfig.slug}/account`, className: "hover:text-black transition-colors", children: "My Account" }), _jsx(Link, { href: `/auth/logout?callbackUrl=/${storeConfig.slug}`, className: "hover:text-black transition-colors", children: "Sign Out" })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: "hover:text-black transition-colors text-left", onClick: () => {
|
|
34
32
|
setIsMenuOpen(false);
|
|
35
33
|
openLogin({
|
|
36
34
|
callbackUrl: pathname || `/${storeConfig.slug}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/pages/CartPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"CartPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/pages/CartPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAWhD,UAAU,aAAa;IACrB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,EAAE,WAAW,EAAE,EAAE,aAAa,+BAiRtD"}
|
|
@@ -7,6 +7,7 @@ import Image from 'next/image';
|
|
|
7
7
|
import { useEffect, useState } from 'react';
|
|
8
8
|
import { useStore } from '../../../lib/store-context.js';
|
|
9
9
|
import { formatCurrency } from '../../../lib/utils/index.js';
|
|
10
|
+
import { getCartLineImage } from '../../../lib/product-variation-utils.js';
|
|
10
11
|
import { calculateVAT, calculateServiceCharge, getVATLabel, getServiceChargeLabel } from '../../../lib/utils/fee-calculations.js';
|
|
11
12
|
export function CartPage({ storeConfig }) {
|
|
12
13
|
const primaryColor = storeConfig.branding.primaryColor;
|
|
@@ -54,9 +55,9 @@ export function CartPage({ storeConfig }) {
|
|
|
54
55
|
if (!isClient)
|
|
55
56
|
return null; // Avoid hydration mismatch
|
|
56
57
|
if (cart.length === 0) {
|
|
57
|
-
return (_jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col items-center justify-center p-4", children: [_jsx("div", { className: "w-24 h-24 bg-white rounded-full shadow-lg flex items-center justify-center mb-6 animate-fade-in-up", children: _jsx(ShoppingBag, { className: "w-10 h-10 text-gray-300" }) }), _jsx("h1", { className: "text-3xl font-bold text-gray-900 mb-3 animate-fade-in-up", style: { animationDelay: '100ms' }, children: "Your cart is empty" }), _jsx("p", { className: "text-gray-500 mb-8 max-w-md text-center animate-fade-in-up", style: { animationDelay: '200ms' }, children: "Looks like you haven't added anything to your cart yet. Browse our products to find something you love." }), _jsx(Link, { href: `/${storeConfig.slug}`, className: "animate-fade-in-up", style: { animationDelay: '300ms' }, children: _jsx(Button, { size: "lg", className: "rounded-
|
|
58
|
+
return (_jsxs("div", { className: "min-h-screen bg-gray-50 flex flex-col items-center justify-center p-4", children: [_jsx("div", { className: "w-24 h-24 bg-white rounded-full shadow-lg flex items-center justify-center mb-6 animate-fade-in-up", children: _jsx(ShoppingBag, { className: "w-10 h-10 text-gray-300" }) }), _jsx("h1", { className: "text-3xl font-bold text-gray-900 mb-3 animate-fade-in-up", style: { animationDelay: '100ms' }, children: "Your cart is empty" }), _jsx("p", { className: "text-gray-500 mb-8 max-w-md text-center animate-fade-in-up", style: { animationDelay: '200ms' }, children: "Looks like you haven't added anything to your cart yet. Browse our products to find something you love." }), _jsx(Link, { href: `/${storeConfig.slug}`, className: "animate-fade-in-up", style: { animationDelay: '300ms' }, children: _jsx(Button, { size: "lg", className: "rounded-sm px-8 h-12 text-base font-bold shadow-sm transition-transform hover:scale-[1.02]", style: { backgroundColor: primaryColor }, children: "Start Shopping" }) })] }));
|
|
58
59
|
}
|
|
59
|
-
return (_jsx("div", { className: "min-h-screen bg-gray-50/50 py-12 px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "container mx-auto max-w-6xl", children: [_jsxs("div", { className: "mb-10 flex flex-col md:flex-row md:items-center justify-between gap-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Link, { href: `/${storeConfig.slug}`, className: "p-2 -ml-2 hover:bg-white rounded-full transition-colors text-gray-500 hover:text-black", children: _jsx(ArrowLeft, { className: "w-5 h-5" }) }), _jsxs("div", { children: [_jsx("h1", { className: "text-3xl font-black text-gray-900 tracking-tight", children: "Shopping Cart" }), _jsxs("p", { className: "text-gray-500 text-sm mt-1", children: [cart.length, " items in your cart"] })] })] }), _jsxs("div", { className: "flex items-center gap-2 text-sm font-medium bg-white px-4 py-2 rounded-
|
|
60
|
+
return (_jsx("div", { className: "min-h-screen bg-gray-50/50 py-12 px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "container mx-auto max-w-6xl", children: [_jsxs("div", { className: "mb-10 flex flex-col md:flex-row md:items-center justify-between gap-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Link, { href: `/${storeConfig.slug}`, className: "p-2 -ml-2 hover:bg-white rounded-full transition-colors text-gray-500 hover:text-black", children: _jsx(ArrowLeft, { className: "w-5 h-5" }) }), _jsxs("div", { children: [_jsx("h1", { className: "text-3xl font-black text-gray-900 tracking-tight", children: "Shopping Cart" }), _jsxs("p", { className: "text-gray-500 text-sm mt-1", children: [cart.length, " items in your cart"] })] })] }), _jsxs("div", { className: "flex items-center gap-2 text-sm font-medium bg-white px-4 py-2 rounded-sm shadow-sm border border-gray-100", children: [_jsx("span", { className: "text-black", children: "Cart" }), _jsx("span", { className: "text-gray-300 mx-1", children: "/" }), _jsx("span", { className: "text-gray-400", children: "Checkout" }), _jsx("span", { className: "text-gray-300 mx-1", children: "/" }), _jsx("span", { className: "text-gray-400", children: "Payment" })] })] }), _jsxs("div", { className: "flex flex-col lg:flex-row gap-8 lg:gap-12", children: [_jsx("div", { className: "flex-1 space-y-6", children: cart.map((item) => (_jsxs("div", { className: "bg-white rounded-sm p-4 sm:p-6 border border-gray-200/90 shadow-sm flex flex-row gap-4 sm:gap-6 group transition-all hover:shadow-md hover:border-gray-200", children: [_jsx("div", { className: "w-24 h-24 sm:w-32 sm:h-32 aspect-square bg-gray-100 rounded-sm overflow-hidden flex-shrink-0 relative", children: _jsx(Image, { src: getCartLineImage(item) || item.product.images[0], alt: item.product.name, fill: true, className: "object-cover group-hover:scale-105 transition-transform duration-500", unoptimized: true }) }), _jsxs("div", { className: "flex-1 flex flex-col justify-between", children: [_jsxs("div", { children: [_jsxs("div", { className: "flex justify-between items-start gap-4", children: [_jsx("h3", { className: "font-bold text-gray-900 text-lg leading-tight", children: item.product.name }), _jsx("p", { className: "font-black text-lg text-gray-900", children: formatCurrency(item.price * item.quantity, cartCurrency) })] }), _jsx("div", { className: "flex flex-wrap gap-2 mt-2", children: item.variantName && (_jsx("span", { className: "text-xs font-bold px-2 py-1 bg-gray-50 border border-gray-100 rounded-sm text-gray-600", children: item.variantName })) })] }), _jsxs("div", { className: "flex justify-between items-end mt-6", children: [item.product.categoryId === 'subscriptions' || item.product.contentType ? (_jsx("div", { className: "text-xs font-bold text-gray-400 uppercase tracking-widest bg-gray-50 px-3 py-1.5 rounded-sm border border-gray-100", children: "Digital Content" })) : (_jsxs("div", { className: "flex items-center gap-1 bg-gray-50 rounded-sm p-1 border border-gray-200", children: [_jsx("button", { onClick: async () => {
|
|
60
61
|
setUpdatingItemId(item.id);
|
|
61
62
|
try {
|
|
62
63
|
await updateCartQuantity(item.id, item.quantity - 1);
|
|
@@ -64,7 +65,7 @@ export function CartPage({ storeConfig }) {
|
|
|
64
65
|
finally {
|
|
65
66
|
setUpdatingItemId(null);
|
|
66
67
|
}
|
|
67
|
-
}, className: "w-8 h-8 flex items-center justify-center rounded-
|
|
68
|
+
}, className: "w-8 h-8 flex items-center justify-center rounded-sm bg-white shadow-sm hover:bg-gray-50 transition-colors disabled:opacity-50 text-gray-600", disabled: item.quantity <= 1 || updatingItemId === item.id || isCartLoading, children: updatingItemId === item.id ? (_jsx("div", { className: "w-3.5 h-3.5 border-2 border-gray-400 border-t-transparent rounded-full animate-spin" })) : (_jsx(Minus, { className: "w-3.5 h-3.5" })) }), _jsx("span", { className: "text-sm font-bold w-8 text-center text-gray-900", children: updatingItemId === item.id ? (_jsx("div", { className: "w-4 h-4 border-2 border-gray-400 border-t-transparent rounded-full animate-spin mx-auto" })) : (item.quantity) }), _jsx("button", { onClick: async () => {
|
|
68
69
|
setUpdatingItemId(item.id);
|
|
69
70
|
try {
|
|
70
71
|
await updateCartQuantity(item.id, item.quantity + 1);
|
|
@@ -72,7 +73,7 @@ export function CartPage({ storeConfig }) {
|
|
|
72
73
|
finally {
|
|
73
74
|
setUpdatingItemId(null);
|
|
74
75
|
}
|
|
75
|
-
}, className: "w-8 h-8 flex items-center justify-center rounded-
|
|
76
|
+
}, className: "w-8 h-8 flex items-center justify-center rounded-sm bg-white shadow-sm hover:bg-gray-50 transition-colors disabled:opacity-50 text-gray-900", disabled: updatingItemId === item.id || isCartLoading, children: updatingItemId === item.id ? (_jsx("div", { className: "w-3.5 h-3.5 border-2 border-gray-400 border-t-transparent rounded-full animate-spin" })) : (_jsx(Plus, { className: "w-3.5 h-3.5" })) })] })), _jsx("button", { onClick: async () => {
|
|
76
77
|
setRemovingItemId(item.id);
|
|
77
78
|
try {
|
|
78
79
|
await removeFromCart(item.id);
|
|
@@ -80,5 +81,5 @@ export function CartPage({ storeConfig }) {
|
|
|
80
81
|
finally {
|
|
81
82
|
setRemovingItemId(null);
|
|
82
83
|
}
|
|
83
|
-
}, className: "text-gray-400 hover:text-red-500 transition-colors p-2 hover:bg-red-50 rounded-
|
|
84
|
+
}, className: "text-gray-400 hover:text-red-500 transition-colors p-2 hover:bg-red-50 rounded-sm disabled:opacity-50", "aria-label": "Remove item", disabled: removingItemId === item.id || isCartLoading, children: removingItemId === item.id ? (_jsx("div", { className: "w-5 h-5 border-2 border-red-400 border-t-transparent rounded-full animate-spin" })) : (_jsx(Trash2, { className: "w-5 h-5" })) })] })] })] }, item.id))) }), _jsx("div", { className: "w-full lg:w-96 flex-shrink-0", children: _jsxs("div", { className: "bg-white rounded-sm border border-gray-200/90 shadow-sm px-8 pt-8 pb-10 sticky top-24", children: [_jsx("h2", { className: "text-2xl font-black text-gray-900 mb-8", children: "Summary" }), _jsxs("div", { className: "space-y-4 mb-8", children: [_jsxs("div", { className: "flex justify-between text-gray-600 font-medium", children: [_jsx("span", { children: "Subtotal" }), _jsx("span", { className: "text-gray-900", children: formatCurrency(subtotal, cartCurrency) })] }), vatAmount > 0 && (_jsxs("div", { className: "flex justify-between text-gray-600 font-medium", children: [_jsx("span", { children: vatLabel }), _jsx("span", { className: "text-gray-900", children: formatCurrency(vatAmount, cartCurrency) })] })), serviceChargeAmount > 0 && (_jsxs("div", { className: "flex justify-between text-gray-600 font-medium", children: [_jsx("span", { children: serviceChargeLabel }), _jsx("span", { className: "text-gray-900", children: formatCurrency(serviceChargeAmount, cartCurrency) })] })), _jsxs("div", { className: "pt-6 border-t-2 border-gray-100 flex justify-between items-end mt-4", children: [_jsx("span", { className: "text-lg font-bold text-gray-900", children: "Total" }), _jsx("span", { className: "text-4xl font-black text-gray-900 tracking-tight", children: formatCurrency(total, cartCurrency) })] })] }), _jsxs("div", { className: "space-y-5", children: [_jsx(Link, { href: `/${storeConfig.slug}/checkout`, className: "block", children: _jsxs(Button, { className: "w-full h-14 rounded-sm text-lg font-bold shadow-sm transition-all hover:opacity-95 active:scale-[0.99]", style: { backgroundColor: primaryColor, color: 'white' }, children: ["Checkout ", _jsx(ArrowRight, { className: "ml-2 w-5 h-5" })] }) }), _jsxs("div", { className: "flex items-center justify-center gap-2 pt-1 text-xs font-medium text-gray-400", children: [_jsx(Lock, { className: "w-3 h-3" }), "Secure Encrypted Checkout"] })] })] }) })] })] }) }));
|
|
84
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckoutPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/pages/CheckoutPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"CheckoutPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/pages/CheckoutPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAkChD,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAkID,wBAAgB,YAAY,CAAC,EAAE,WAAW,EAAE,EAAE,iBAAiB,+BA69C9D"}
|