storefront-layouts 1.0.7 → 1.0.10
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-filtered-products-fetch.d.ts.map +1 -1
- package/dist/hooks/use-filtered-products-fetch.js +3 -2
- 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 +83 -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 +6 -16
- 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 +6 -16
- 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 +6 -16
- 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 +6 -16
- 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 +6 -15
- 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 +6 -15
- package/dist/layouts/motivational-speaker/pages/ProductsPage.d.ts.map +1 -1
- package/dist/layouts/motivational-speaker/pages/ProductsPage.js +6 -16
- 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 +26 -0
- package/dist/lib/product-variation-utils.d.ts.map +1 -1
- package/dist/lib/product-variation-utils.js +259 -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 +26 -8
- package/dist/lib/store-types.d.ts +1 -0
- package/dist/lib/store-types.d.ts.map +1 -1
- 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/lib/utils/filtered-product-query.d.ts +13 -0
- package/dist/lib/utils/filtered-product-query.d.ts.map +1 -1
- package/dist/lib/utils/filtered-product-query.js +31 -0
- package/dist/styles/index.css +143 -45
- package/package.json +1 -1
|
@@ -21,9 +21,10 @@ import { getAllCategoryIds, flattenCategoryTree, buildCategoryTree } from '../..
|
|
|
21
21
|
import { getBannerImage, getLayoutText } from '../../../lib/utils/asset-helpers';
|
|
22
22
|
import { SafeRichHtml } from '../../../components/rich-text/SafeRichHtml';
|
|
23
23
|
import { shouldUseAPI } from '../../../lib/utils/demo-detection';
|
|
24
|
+
import { productCategoryFilterChipClass } from '../../shared/product-category-filter-chip';
|
|
24
25
|
import { useCatalogPriceRange } from '../../../hooks/use-catalog-price-range.js';
|
|
25
26
|
import { getApiPriceFilterActive, isWithinActivePriceRange } from '../../../lib/utils/catalog-price-bounds.js';
|
|
26
|
-
import { buildFilteredProductQuery, getFilteredProductQueryKey, } from '../../../lib/utils/filtered-product-query.js';
|
|
27
|
+
import { buildFilteredProductQuery, getFilteredProductQueryKey, productMatchesCategoryIds, productMatchesCategorySlug, } from '../../../lib/utils/filtered-product-query.js';
|
|
27
28
|
import { transformProductToStoreProduct } from '../../../lib/store-config-utils.js';
|
|
28
29
|
import { ProductPriceFilterSection } from '../../shared/components/ProductPriceFilterSection';
|
|
29
30
|
function ProductsPageContent({ storeConfig: initialConfig }) {
|
|
@@ -83,7 +84,6 @@ function ProductsPageContent({ storeConfig: initialConfig }) {
|
|
|
83
84
|
const [isFilterOpen, setIsFilterOpen] = useState(false);
|
|
84
85
|
const [sortBy, setSortBy] = useState('featured');
|
|
85
86
|
const [visibleProducts, setVisibleProducts] = useState(12);
|
|
86
|
-
const [isFiltering, setIsFiltering] = useState(false);
|
|
87
87
|
// Fallback brands from the loaded page; full catalog brands come from the brands API.
|
|
88
88
|
const fallbackBrands = useMemo(() => {
|
|
89
89
|
const brandSet = new Set();
|
|
@@ -98,12 +98,6 @@ function ProductsPageContent({ storeConfig: initialConfig }) {
|
|
|
98
98
|
return Array.from(brandSet).sort();
|
|
99
99
|
}, [products]);
|
|
100
100
|
const brands = useProductBrands(storeConfig.id, fallbackBrands);
|
|
101
|
-
// Track filter changes and show loading
|
|
102
|
-
useEffect(() => {
|
|
103
|
-
setIsFiltering(true);
|
|
104
|
-
const timer = setTimeout(() => setIsFiltering(false), 300);
|
|
105
|
-
return () => clearTimeout(timer);
|
|
106
|
-
}, [selectedBrands, selectedCategories, priceRange, selectedCategoryFilter, minRating, showInStockOnly, sortBy]);
|
|
107
101
|
// Build category tree for filtering
|
|
108
102
|
const categoryTree = useMemo(() => buildCategoryTree(categories), [categories]);
|
|
109
103
|
// Get all category IDs to filter (including children of selected parent categories)
|
|
@@ -136,7 +130,7 @@ function ProductsPageContent({ storeConfig: initialConfig }) {
|
|
|
136
130
|
}
|
|
137
131
|
// Category filter (Sidebar) - includes parent and child categories
|
|
138
132
|
if (effectiveCategoryIds.length > 0) {
|
|
139
|
-
if (!
|
|
133
|
+
if (!productMatchesCategoryIds(product, effectiveCategoryIds)) {
|
|
140
134
|
return false;
|
|
141
135
|
}
|
|
142
136
|
}
|
|
@@ -147,7 +141,7 @@ function ProductsPageContent({ storeConfig: initialConfig }) {
|
|
|
147
141
|
// Category Filter (Top Buttons)
|
|
148
142
|
if (selectedCategoryFilter) {
|
|
149
143
|
const category = categories.find(c => c.slug === selectedCategoryFilter);
|
|
150
|
-
if (
|
|
144
|
+
if (!productMatchesCategorySlug(product, category)) {
|
|
151
145
|
return false;
|
|
152
146
|
}
|
|
153
147
|
}
|
|
@@ -319,15 +313,11 @@ function ProductsPageContent({ storeConfig: initialConfig }) {
|
|
|
319
313
|
element?.scrollIntoView({ behavior: 'smooth' });
|
|
320
314
|
}, children: layoutConfig?.sections?.productsHeader?.primaryButtonText || primaryButtonText })), (layoutConfig?.sections?.productsHeader?.secondaryButtonText || secondaryButtonText) && (layoutConfig?.sections?.productsHeader?.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 ${(layoutConfig?.sections?.productsHeader?.image || 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: () => {
|
|
321
315
|
window.location.href = `/${storeConfig.slug}/categories`;
|
|
322
|
-
}, children: layoutConfig?.sections?.productsHeader?.secondaryButtonText || 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: `
|
|
323
|
-
? 'bg-gray-900 text-white hover:bg-blue-600'
|
|
324
|
-
: '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
|
|
325
|
-
? 'bg-gray-900 text-white hover:bg-blue-600'
|
|
326
|
-
: '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) => {
|
|
316
|
+
}, children: layoutConfig?.sections?.productsHeader?.secondaryButtonText || 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) => {
|
|
327
317
|
setSelectedCategories(prev => isSelected
|
|
328
318
|
? [...prev, categoryId]
|
|
329
319
|
: prev.filter(id => id !== categoryId));
|
|
330
|
-
}, mode: "checkbox" })] }), _jsx(ProductPriceFilterSection, { currency: storeCurrency, priceRange: priceRange, onPriceRangeChange: setPriceRange, bounds: catalogBounds, isFilterActive: hasActivePriceFilter, onReset: resetPriceRange }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wide mb-4", children: "Rating" }), _jsx("div", { className: "space-y-2", children: [4, 3, 2, 1].map((rating) => (_jsxs("label", { className: "flex items-center gap-3 cursor-pointer group p-2 -ml-2 rounded-lg hover:bg-blue-50 hover:text-blue-600 transition-colors", children: [_jsx("div", { className: `w-5 h-5 rounded-full border flex items-center justify-center transition-colors ${minRating === rating ? 'border-blue-600 bg-blue-600' : 'border-gray-300 group-hover:border-blue-400'}`, children: minRating === rating && _jsx("div", { className: "w-2.5 h-2.5 bg-white rounded-full" }) }), _jsx("input", { type: "radio", name: "rating", checked: minRating === rating, onChange: () => setMinRating(minRating === rating ? null : rating), className: "hidden" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("div", { className: "flex text-yellow-400", children: Array.from({ length: 5 }).map((_, i) => (_jsx(Star, { className: `h-3.5 w-3.5 ${i < rating ? 'fill-current' : 'text-gray-200 fill-gray-200'}` }, i))) }), _jsx("span", { className: "text-sm text-gray-600", children: "& Up" })] })] }, rating))) })] })] }), _jsxs("div", { className: "lg:col-span-3", children: [_jsxs("div", { className: "lg:hidden mb-6 flex items-center justify-between", children: [_jsxs(Button, { onClick: () => setIsFilterOpen(true), variant: "outline", className: "flex items-center gap-2", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), " Filters"] }), _jsxs("select", { value: sortBy, onChange: (e) => setSortBy(e.target.value), className: "bg-transparent text-sm font-medium text-gray-700 focus:outline-none", children: [_jsx("option", { value: "featured", children: "Sort by: Featured" }), _jsx("option", { value: "newest", children: "Sort by: Newest" }), _jsx("option", { value: "price-asc", children: "Sort by: Price Low-High" }), _jsx("option", { value: "price-desc", children: "Sort by: Price High-Low" })] })] }), _jsxs("div", { className: "hidden lg:flex items-center justify-between mb-6", children: [_jsxs("p", { className: "text-sm text-gray-600", children: ["Showing ", _jsx("span", { className: "font-semibold text-gray-900", children: filteredAndSortedProducts.length }), " products"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Sort by:" }), _jsxs("select", { value: sortBy, onChange: (e) => setSortBy(e.target.value), className: "bg-transparent text-sm font-medium text-gray-900 focus:outline-none cursor-pointer hover:text-blue-600 transition-colors", children: [_jsx("option", { value: "featured", children: "Featured" }), _jsx("option", { value: "newest", children: "Newest Arrivals" }), _jsx("option", { value: "price-asc", children: "Price: Low to High" }), _jsx("option", { value: "price-desc", children: "Price: High to Low" }), _jsx("option", { value: "rating", children: "Top Rated" })] })] })] }), isLoadingProducts
|
|
320
|
+
}, mode: "checkbox" })] }), _jsx(ProductPriceFilterSection, { currency: storeCurrency, priceRange: priceRange, onPriceRangeChange: setPriceRange, bounds: catalogBounds, isFilterActive: hasActivePriceFilter, onReset: resetPriceRange }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 uppercase tracking-wide mb-4", children: "Rating" }), _jsx("div", { className: "space-y-2", children: [4, 3, 2, 1].map((rating) => (_jsxs("label", { className: "flex items-center gap-3 cursor-pointer group p-2 -ml-2 rounded-lg hover:bg-blue-50 hover:text-blue-600 transition-colors", children: [_jsx("div", { className: `w-5 h-5 rounded-full border flex items-center justify-center transition-colors ${minRating === rating ? 'border-blue-600 bg-blue-600' : 'border-gray-300 group-hover:border-blue-400'}`, children: minRating === rating && _jsx("div", { className: "w-2.5 h-2.5 bg-white rounded-full" }) }), _jsx("input", { type: "radio", name: "rating", checked: minRating === rating, onChange: () => setMinRating(minRating === rating ? null : rating), className: "hidden" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("div", { className: "flex text-yellow-400", children: Array.from({ length: 5 }).map((_, i) => (_jsx(Star, { className: `h-3.5 w-3.5 ${i < rating ? 'fill-current' : 'text-gray-200 fill-gray-200'}` }, i))) }), _jsx("span", { className: "text-sm text-gray-600", children: "& Up" })] })] }, rating))) })] })] }), _jsxs("div", { className: "lg:col-span-3", children: [_jsxs("div", { className: "lg:hidden mb-6 flex items-center justify-between", children: [_jsxs(Button, { onClick: () => setIsFilterOpen(true), variant: "outline", className: "flex items-center gap-2", children: [_jsx(SlidersHorizontal, { className: "h-4 w-4" }), " Filters"] }), _jsxs("select", { value: sortBy, onChange: (e) => setSortBy(e.target.value), className: "bg-transparent text-sm font-medium text-gray-700 focus:outline-none", children: [_jsx("option", { value: "featured", children: "Sort by: Featured" }), _jsx("option", { value: "newest", children: "Sort by: Newest" }), _jsx("option", { value: "price-asc", children: "Sort by: Price Low-High" }), _jsx("option", { value: "price-desc", children: "Sort by: Price High-Low" })] })] }), _jsxs("div", { className: "hidden lg:flex items-center justify-between mb-6", children: [_jsxs("p", { className: "text-sm text-gray-600", children: ["Showing ", _jsx("span", { className: "font-semibold text-gray-900", children: filteredAndSortedProducts.length }), " products"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm text-gray-500", children: "Sort by:" }), _jsxs("select", { value: sortBy, onChange: (e) => setSortBy(e.target.value), className: "bg-transparent text-sm font-medium text-gray-900 focus:outline-none cursor-pointer hover:text-blue-600 transition-colors", children: [_jsx("option", { value: "featured", children: "Featured" }), _jsx("option", { value: "newest", children: "Newest Arrivals" }), _jsx("option", { value: "price-asc", children: "Price: Low to High" }), _jsx("option", { value: "price-desc", children: "Price: High to Low" }), _jsx("option", { value: "rating", children: "Top Rated" })] })] })] }), isLoadingProducts ? (_jsx(ProductGridSkeleton, { count: 12, columns: 3 })) : displayedProducts.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: displayedProducts.map((product) => (_jsx(ProductCard, { product: product, storeSlug: storeConfig.slug, onAddToCart: handleAddToCart, onQuickView: handleQuickView }, product.id))) }), hasMore && (_jsx("div", { className: "mt-12 text-center", children: _jsx(Button, { onClick: handleLoadMore, variant: "outline", className: "min-w-[200px]", children: "Load More" }) }))] })) : (_jsxs("div", { className: "flex flex-col items-center justify-center py-20 bg-white rounded-lg border border-dashed border-gray-200 text-center", children: [_jsx("div", { className: "w-12 h-12 bg-gray-50 rounded-full flex items-center justify-center mb-4 text-gray-400", children: _jsx(Search, { className: "h-6 w-6" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-1", children: "No products found" }), _jsx("p", { className: "text-sm text-gray-500 mb-6", children: "Try adjusting your filters or search criteria." }), _jsx(Button, { onClick: clearAllFilters, variant: "outline", children: "Clear All Filters" })] }))] })] })] }), _jsxs(Sheet, { isOpen: isFilterOpen, onClose: () => setIsFilterOpen(false), title: "Filters", side: "right", children: [_jsxs("div", { className: "flex flex-col h-full overflow-y-auto pb-20 space-y-8 p-1", children: [_jsxs("div", { className: "pb-6 border-b border-gray-100", children: [_jsx("h3", { className: "font-bold text-sm uppercase tracking-widest mb-4", children: "Availability" }), _jsxs("label", { className: "flex items-center gap-3", children: [_jsx("input", { type: "checkbox", checked: showInStockOnly, onChange: () => setShowInStockOnly(!showInStockOnly), className: "rounded border-gray-300 text-black focus:ring-black" }), _jsx("span", { className: "text-sm text-gray-700", children: "In Stock Only" })] })] }), _jsx(ProductPriceFilterSection, { currency: storeCurrency, priceRange: priceRange, onPriceRangeChange: setPriceRange, bounds: catalogBounds, isFilterActive: hasActivePriceFilter, onReset: resetPriceRange }), _jsxs("div", { children: [_jsx("h3", { className: "font-bold text-sm uppercase tracking-widest mb-4", children: "Categories" }), _jsx(CategoryTree, { categories: categories, selectedCategoryIds: selectedCategories, onCategoryToggle: (categoryId, isSelected) => {
|
|
331
321
|
setSelectedCategories(prev => isSelected
|
|
332
322
|
? [...prev, categoryId]
|
|
333
323
|
: prev.filter(id => id !== categoryId));
|
|
@@ -110,7 +110,7 @@ export function ElectronicsGridProductCard({ product, storeSlug, onAddToCart, in
|
|
|
110
110
|
if (!isOutOfStock) {
|
|
111
111
|
onAddToCart(product);
|
|
112
112
|
}
|
|
113
|
-
}, disabled: isOutOfStock, className: cn("w-full bg-gray-900 hover:bg-gray-800 text-white border-none rounded-none h-11 font-normal text-sm transition-colors", isOutOfStock && "opacity-50 cursor-not-allowed"), children: [_jsx(Plus, { className: "w-4 h-4 mr-2" }), "
|
|
113
|
+
}, disabled: isOutOfStock, className: cn("w-full bg-gray-900 hover:bg-gray-800 text-white border-none rounded-none h-11 font-normal text-sm transition-colors", isOutOfStock && "opacity-50 cursor-not-allowed"), children: [_jsx(Plus, { className: "w-4 h-4 mr-2" }), " Add to cart"] }) }), _jsx("button", { disabled: isOutOfStock, className: cn("lg:hidden absolute bottom-3 right-3 z-30 w-10 h-10 rounded-full bg-gray-900 text-white flex items-center justify-center hover:bg-gray-800 active:scale-95 transition-colors", isOutOfStock && "opacity-50 cursor-not-allowed"), onClick: (e) => {
|
|
114
114
|
e.preventDefault();
|
|
115
115
|
if (!isOutOfStock) {
|
|
116
116
|
onAddToCart(product);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ElectronicsStoreHeader.d.ts","sourceRoot":"","sources":["../../../../src/layouts/electronics/components/ElectronicsStoreHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ElectronicsStoreHeader.d.ts","sourceRoot":"","sources":["../../../../src/layouts/electronics/components/ElectronicsStoreHeader.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAahD,UAAU,2BAA2B;IACnC,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,sBAAsB,CAAC,EAAE,WAAW,EAAE,EAAE,2BAA2B,+BA4JlF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { Button } from '../../../components/ui/button.js';
|
|
4
4
|
import { ShoppingCart, Zap, Menu, X, Search, User } from 'lucide-react';
|
|
5
5
|
import Link from 'next/link';
|
|
@@ -10,9 +10,10 @@ import { useStore } from '../../../lib/store-context.js';
|
|
|
10
10
|
import { useAuth } from '../../../lib/auth-context.js';
|
|
11
11
|
import { StoreLogo } from '../../../components/ui/store-logos.js';
|
|
12
12
|
import { usePathname } from 'next/navigation';
|
|
13
|
+
import { StoreCartSheet } from '../../shared/components/StoreCartSheet';
|
|
13
14
|
export function ElectronicsStoreHeader({ storeConfig }) {
|
|
14
15
|
const [scrolled, setScrolled] = useState(false);
|
|
15
|
-
const { cartCount } = useStore();
|
|
16
|
+
const { cartCount, setIsCartOpen } = useStore();
|
|
16
17
|
const { isAuthenticated, openLogin } = useAuth();
|
|
17
18
|
const pathname = usePathname();
|
|
18
19
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
@@ -29,11 +30,11 @@ export function ElectronicsStoreHeader({ storeConfig }) {
|
|
|
29
30
|
window.addEventListener('scroll', handleScroll);
|
|
30
31
|
return () => window.removeEventListener('scroll', handleScroll);
|
|
31
32
|
}, []);
|
|
32
|
-
return (_jsxs("nav", { className: cn("fixed top-0 w-full z-50 transition-all duration-300", scrolled
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
return (_jsxs(_Fragment, { children: [_jsxs("nav", { className: cn("fixed top-0 w-full z-50 transition-all duration-300", scrolled
|
|
34
|
+
? "bg-white/80 backdrop-blur-xl border-b border-gray-100 py-3 shadow-sm"
|
|
35
|
+
: "bg-transparent py-5"), children: [_jsxs("div", { className: "container mx-auto px-6 flex items-center justify-between", children: [_jsxs(Link, { href: `/${storeConfig.slug}`, className: "group flex items-center gap-2.5 z-50", children: [getLogoUrl(storeConfig) ? (_jsx(StoreLogo, { storeConfig: storeConfig, className: "h-10 w-10 transition-all duration-300 group-hover:scale-105 group-hover:opacity-90", alt: storeDisplayName })) : (_jsx("div", { className: "w-10 h-10 bg-blue-600 rounded-xl flex items-center justify-center transition-transform group-hover:scale-105 duration-300 shadow-lg shadow-blue-600/20", children: _jsx(Zap, { className: "h-5 w-5 text-white fill-current" }) })), !getLogoUrl(storeConfig) && (_jsx("span", { className: "text-xl font-black tracking-tight text-gray-900 group-hover:text-blue-600 transition-colors", children: storeDisplayName }))] }), _jsx("div", { className: "hidden md:flex items-center gap-6", children: [
|
|
36
|
+
{ label: 'Products', href: `/${storeConfig.slug}/products` },
|
|
37
|
+
{ label: 'Collections', href: `/${storeConfig.slug}/categories` },
|
|
38
|
+
{ label: 'About', href: `/${storeConfig.slug}/about` }
|
|
39
|
+
].map((item) => (_jsx(Link, { href: item.href, className: "text-sm font-semibold text-gray-600 hover:text-gray-900 underline-offset-4 hover:underline transition-colors", children: item.label }, item.href))) }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Button, { variant: "ghost", size: "icon", className: "hidden sm:flex text-gray-900 hover:bg-blue-50 hover:text-blue-600 rounded-full transition-all", children: _jsx(Search, { className: "h-5 w-5" }) }), isAuthenticated ? (_jsx(Link, { href: `/${storeConfig.slug}/account`, children: _jsx(Button, { variant: "ghost", size: "icon", className: "hidden md:flex text-gray-900 hover:bg-blue-50 hover:text-blue-600 rounded-full transition-all", children: _jsx(User, { className: "h-5 w-5" }) }) })) : (_jsx(Button, { variant: "ghost", size: "icon", className: "hidden md:flex text-gray-900 hover:bg-blue-50 hover:text-blue-600 rounded-full transition-all", onClick: handleAccountClick, "aria-label": "Sign in", children: _jsx(User, { className: "h-5 w-5" }) })), _jsxs(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => setIsCartOpen(true), className: "relative text-gray-900 hover:bg-blue-50 hover:text-blue-600 rounded-full transition-all h-10 w-10 sm:h-9 sm:w-9", "aria-label": "Open shopping bag", children: [_jsx(ShoppingCart, { className: "h-5 w-5" }), cartCount > 0 && (_jsx("span", { className: "absolute top-0 right-0 bg-blue-600 text-white text-[10px] font-bold h-4 w-4 flex items-center justify-center rounded-full shadow-sm ring-2 ring-white", children: cartCount }))] }), _jsx(Button, { variant: "ghost", size: "icon", className: "md:hidden text-gray-900 hover:bg-gray-100 rounded-full h-10 w-10", onClick: () => setIsMobileMenuOpen(!isMobileMenuOpen), children: isMobileMenuOpen ? _jsx(X, { className: "h-6 w-6" }) : _jsx(Menu, { className: "h-6 w-6" }) })] })] }), _jsxs("div", { className: cn("fixed inset-0 bg-white z-40 pt-28 px-6 md:hidden transition-all duration-300 ease-in-out transform", isMobileMenuOpen ? "opacity-100 translate-y-0" : "opacity-0 -translate-y-full pointer-events-none"), children: [_jsxs("div", { className: "mb-8 relative", children: [_jsx("input", { type: "text", placeholder: "Search products...", className: "w-full h-12 pl-12 pr-4 rounded-xl bg-gray-100 border-none text-gray-900 focus:ring-2 focus:ring-blue-500/20" }), _jsx(Search, { className: "absolute left-4 top-1/2 -translate-y-1/2 h-5 w-5 text-gray-400" })] }), _jsxs("div", { className: "flex flex-col gap-6 text-3xl font-bold text-gray-900 tracking-tight", children: [_jsx(Link, { href: `/${storeConfig.slug}/products`, onClick: () => setIsMobileMenuOpen(false), className: "hover:text-blue-600 transition-colors", children: "Products" }), _jsx(Link, { href: `/${storeConfig.slug}/categories`, onClick: () => setIsMobileMenuOpen(false), className: "hover:text-blue-600 transition-colors", children: "Collections" }), _jsx(Link, { href: `/${storeConfig.slug}/about`, onClick: () => setIsMobileMenuOpen(false), className: "hover:text-blue-600 transition-colors", children: "About" }), _jsx(Link, { href: `/${storeConfig.slug}/account`, onClick: () => setIsMobileMenuOpen(false), className: "hover:text-blue-600 transition-colors", children: "Account" })] }), _jsxs("div", { className: "mt-12 pt-12 border-t border-gray-100 grid grid-cols-2 gap-4", children: [_jsxs("div", { className: "bg-gray-50 p-6 rounded-2xl", children: [_jsx("h4", { className: "font-bold text-gray-900 mb-2", children: "Support" }), _jsx("p", { className: "text-sm text-gray-500", children: "24/7 Customer Care" })] }), _jsxs("div", { className: "bg-blue-50 p-6 rounded-2xl", children: [_jsx("h4", { className: "font-bold text-blue-900 mb-2", children: getLayoutText(storeConfig, 'electronics.newArrivals', 'New Arrivals') }), _jsx("p", { className: "text-sm text-blue-600", children: "Check out latest tech" })] })] })] })] }), _jsx(StoreCartSheet, { storeConfig: storeConfig, title: `My Cart (${cartCount})` })] }));
|
|
39
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/electronics/pages/ProductDetailPage.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAA8C,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ProductDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/electronics/pages/ProductDetailPage.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAA8C,MAAM,mBAAmB,CAAC;AAiC5F,UAAU,sBAAsB;IAC9B,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAsHD,wBAAgB,iBAAiB,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,EAAE,sBAAsB,+BA+4BpG"}
|