storefront-layouts 1.0.6 → 1.0.7

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.
Files changed (160) hide show
  1. package/dist/components/ui/route-skeleton-loader.d.ts.map +1 -1
  2. package/dist/components/ui/route-skeleton-loader.js +6 -1
  3. package/dist/editor/alignment-schemas/booking-footer-section.d.ts.map +1 -1
  4. package/dist/editor/alignment-schemas/booking-footer-section.js +0 -1
  5. package/dist/editor/alignment-schemas/clothing.d.ts.map +1 -1
  6. package/dist/editor/alignment-schemas/clothing.js +0 -1
  7. package/dist/editor/alignment-schemas/food.d.ts.map +1 -1
  8. package/dist/editor/alignment-schemas/food.js +0 -1
  9. package/dist/hooks/use-category-products.d.ts +5 -1
  10. package/dist/hooks/use-category-products.d.ts.map +1 -1
  11. package/dist/hooks/use-category-products.js +8 -5
  12. package/dist/hooks/use-filtered-products-fetch.d.ts +12 -0
  13. package/dist/hooks/use-filtered-products-fetch.d.ts.map +1 -0
  14. package/dist/hooks/use-filtered-products-fetch.js +58 -0
  15. package/dist/index.d.ts +5 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +5 -0
  18. package/dist/layouts/booking/components/BookingHomePage.d.ts.map +1 -1
  19. package/dist/layouts/booking/components/BookingHomePage.js +3 -1
  20. package/dist/layouts/booking/pages/AboutPage.d.ts.map +1 -1
  21. package/dist/layouts/booking/pages/AboutPage.js +3 -1
  22. package/dist/layouts/booking/pages/CategoryPage.d.ts.map +1 -1
  23. package/dist/layouts/booking/pages/CategoryPage.js +3 -1
  24. package/dist/layouts/booking/pages/ProductDetailPage.d.ts.map +1 -1
  25. package/dist/layouts/booking/pages/ProductDetailPage.js +2 -1
  26. package/dist/layouts/booking/pages/ServicesPage.d.ts.map +1 -1
  27. package/dist/layouts/booking/pages/ServicesPage.js +4 -2
  28. package/dist/layouts/booking-agenda/pages/AboutPage.d.ts.map +1 -1
  29. package/dist/layouts/booking-agenda/pages/AboutPage.js +3 -1
  30. package/dist/layouts/booking-agenda/pages/CategoryPage.d.ts.map +1 -1
  31. package/dist/layouts/booking-agenda/pages/CategoryPage.js +3 -1
  32. package/dist/layouts/booking-agenda/pages/ProductDetailPage.d.ts.map +1 -1
  33. package/dist/layouts/booking-agenda/pages/ProductDetailPage.js +2 -1
  34. package/dist/layouts/booking-agenda/pages/ServicesPage.d.ts.map +1 -1
  35. package/dist/layouts/booking-agenda/pages/ServicesPage.js +4 -2
  36. package/dist/layouts/clothing/components/ClothingHomePage.d.ts.map +1 -1
  37. package/dist/layouts/clothing/components/ClothingHomePage.js +5 -4
  38. package/dist/layouts/clothing/pages/AboutPage.d.ts.map +1 -1
  39. package/dist/layouts/clothing/pages/AboutPage.js +2 -1
  40. package/dist/layouts/clothing/pages/CategoriesPage.d.ts.map +1 -1
  41. package/dist/layouts/clothing/pages/CategoriesPage.js +3 -2
  42. package/dist/layouts/clothing/pages/CategoryPage.d.ts +3 -1
  43. package/dist/layouts/clothing/pages/CategoryPage.d.ts.map +1 -1
  44. package/dist/layouts/clothing/pages/CategoryPage.js +4 -3
  45. package/dist/layouts/clothing/pages/ProductDetailPage.d.ts.map +1 -1
  46. package/dist/layouts/clothing/pages/ProductDetailPage.js +3 -2
  47. package/dist/layouts/clothing/pages/ProductsPage.d.ts.map +1 -1
  48. package/dist/layouts/clothing/pages/ProductsPage.js +53 -60
  49. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.d.ts.map +1 -1
  50. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.js +4 -3
  51. package/dist/layouts/clothing-minimal/pages/AboutPage.d.ts.map +1 -1
  52. package/dist/layouts/clothing-minimal/pages/AboutPage.js +2 -1
  53. package/dist/layouts/clothing-minimal/pages/CategoriesPage.d.ts.map +1 -1
  54. package/dist/layouts/clothing-minimal/pages/CategoriesPage.js +3 -2
  55. package/dist/layouts/clothing-minimal/pages/CategoryPage.d.ts +3 -1
  56. package/dist/layouts/clothing-minimal/pages/CategoryPage.d.ts.map +1 -1
  57. package/dist/layouts/clothing-minimal/pages/CategoryPage.js +4 -3
  58. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.d.ts.map +1 -1
  59. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.js +2 -1
  60. package/dist/layouts/clothing-minimal/pages/ProductsPage.d.ts.map +1 -1
  61. package/dist/layouts/clothing-minimal/pages/ProductsPage.js +53 -60
  62. package/dist/layouts/electronics/components/ElectronicsHomePage.d.ts.map +1 -1
  63. package/dist/layouts/electronics/components/ElectronicsHomePage.js +2 -1
  64. package/dist/layouts/electronics/components/ElectronicsProductsPage.d.ts.map +1 -1
  65. package/dist/layouts/electronics/components/ElectronicsProductsPage.js +45 -36
  66. package/dist/layouts/electronics/components/ElectronicsStoreFooter.d.ts.map +1 -1
  67. package/dist/layouts/electronics/components/ElectronicsStoreFooter.js +2 -1
  68. package/dist/layouts/electronics/pages/AboutPage.d.ts.map +1 -1
  69. package/dist/layouts/electronics/pages/AboutPage.js +3 -1
  70. package/dist/layouts/electronics/pages/CategoryPage.d.ts +3 -1
  71. package/dist/layouts/electronics/pages/CategoryPage.d.ts.map +1 -1
  72. package/dist/layouts/electronics/pages/CategoryPage.js +4 -3
  73. package/dist/layouts/electronics/pages/ProductDetailPage.d.ts.map +1 -1
  74. package/dist/layouts/electronics/pages/ProductDetailPage.js +2 -1
  75. package/dist/layouts/electronics/pages/ProductsPage.d.ts.map +1 -1
  76. package/dist/layouts/electronics/pages/ProductsPage.js +53 -60
  77. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.d.ts.map +1 -1
  78. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.js +2 -1
  79. package/dist/layouts/electronics-grid/pages/AboutPage.d.ts.map +1 -1
  80. package/dist/layouts/electronics-grid/pages/AboutPage.js +3 -1
  81. package/dist/layouts/electronics-grid/pages/CategoryPage.d.ts +3 -1
  82. package/dist/layouts/electronics-grid/pages/CategoryPage.d.ts.map +1 -1
  83. package/dist/layouts/electronics-grid/pages/CategoryPage.js +4 -3
  84. package/dist/layouts/electronics-grid/pages/ProductDetailPage.d.ts.map +1 -1
  85. package/dist/layouts/electronics-grid/pages/ProductDetailPage.js +2 -1
  86. package/dist/layouts/electronics-grid/pages/ProductsPage.d.ts.map +1 -1
  87. package/dist/layouts/electronics-grid/pages/ProductsPage.js +53 -60
  88. package/dist/layouts/food/components/FoodHomePage.d.ts.map +1 -1
  89. package/dist/layouts/food/components/FoodHomePage.js +6 -4
  90. package/dist/layouts/food/pages/AboutPage.d.ts.map +1 -1
  91. package/dist/layouts/food/pages/AboutPage.js +2 -1
  92. package/dist/layouts/food/pages/CategoryPage.d.ts +3 -1
  93. package/dist/layouts/food/pages/CategoryPage.d.ts.map +1 -1
  94. package/dist/layouts/food/pages/CategoryPage.js +5 -3
  95. package/dist/layouts/food/pages/MenuPage.js +1 -1
  96. package/dist/layouts/food/pages/ProductDetailPage.d.ts.map +1 -1
  97. package/dist/layouts/food/pages/ProductDetailPage.js +2 -1
  98. package/dist/layouts/food/pages/ProductsPage.d.ts.map +1 -1
  99. package/dist/layouts/food/pages/ProductsPage.js +51 -54
  100. package/dist/layouts/food-modern/components/FoodHomePageModern.d.ts.map +1 -1
  101. package/dist/layouts/food-modern/components/FoodHomePageModern.js +4 -2
  102. package/dist/layouts/food-modern/pages/AboutPage.d.ts.map +1 -1
  103. package/dist/layouts/food-modern/pages/AboutPage.js +3 -1
  104. package/dist/layouts/food-modern/pages/CategoryPage.d.ts +3 -1
  105. package/dist/layouts/food-modern/pages/CategoryPage.d.ts.map +1 -1
  106. package/dist/layouts/food-modern/pages/CategoryPage.js +5 -3
  107. package/dist/layouts/food-modern/pages/MenuPage.js +1 -1
  108. package/dist/layouts/food-modern/pages/ProductDetailPage.d.ts.map +1 -1
  109. package/dist/layouts/food-modern/pages/ProductDetailPage.js +2 -1
  110. package/dist/layouts/food-modern/pages/ProductsPage.d.ts.map +1 -1
  111. package/dist/layouts/food-modern/pages/ProductsPage.js +51 -54
  112. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.d.ts.map +1 -1
  113. package/dist/layouts/motivational-speaker/components/MotivationalHomePage.js +4 -2
  114. package/dist/layouts/motivational-speaker/pages/AboutPage.d.ts.map +1 -1
  115. package/dist/layouts/motivational-speaker/pages/AboutPage.js +3 -1
  116. package/dist/layouts/motivational-speaker/pages/CategoryPage.d.ts +3 -1
  117. package/dist/layouts/motivational-speaker/pages/CategoryPage.d.ts.map +1 -1
  118. package/dist/layouts/motivational-speaker/pages/CategoryPage.js +6 -4
  119. package/dist/layouts/motivational-speaker/pages/ProductsPage.d.ts.map +1 -1
  120. package/dist/layouts/motivational-speaker/pages/ProductsPage.js +53 -60
  121. package/dist/layouts/motivational-speaker/pages/ServiceDetailPage.d.ts.map +1 -1
  122. package/dist/layouts/motivational-speaker/pages/ServiceDetailPage.js +2 -1
  123. package/dist/layouts/motivational-speaker/pages/ServicesPage.d.ts.map +1 -1
  124. package/dist/layouts/motivational-speaker/pages/ServicesPage.js +4 -2
  125. package/dist/layouts/motivational-speaker/pages/SubscriptionPage.d.ts.map +1 -1
  126. package/dist/layouts/motivational-speaker/pages/SubscriptionPage.js +3 -2
  127. package/dist/layouts/shared/components/StoreFooter.d.ts.map +1 -1
  128. package/dist/layouts/shared/components/StoreFooter.js +3 -13
  129. package/dist/layouts/shared/pages/PortfolioPage.d.ts.map +1 -1
  130. package/dist/layouts/shared/pages/PortfolioPage.js +2 -1
  131. package/dist/layouts/shared/pages/StoreMaintenanceScreen.d.ts +9 -0
  132. package/dist/layouts/shared/pages/StoreMaintenanceScreen.d.ts.map +1 -0
  133. package/dist/layouts/shared/pages/StoreMaintenanceScreen.js +10 -0
  134. package/dist/layouts/shared/pages/StoreOfflinePage.d.ts +19 -0
  135. package/dist/layouts/shared/pages/StoreOfflinePage.d.ts.map +1 -0
  136. package/dist/layouts/shared/pages/StoreOfflinePage.js +113 -0
  137. package/dist/layouts/shared/pages/WishlistPage.d.ts.map +1 -1
  138. package/dist/layouts/shared/pages/WishlistPage.js +11 -14
  139. package/dist/lib/content-selectors.js +3 -3
  140. package/dist/lib/layout-route-utils.d.ts +1 -0
  141. package/dist/lib/layout-route-utils.d.ts.map +1 -1
  142. package/dist/lib/layout-route-utils.js +1 -1
  143. package/dist/lib/services/product.service.d.ts +1 -0
  144. package/dist/lib/services/product.service.d.ts.map +1 -1
  145. package/dist/lib/store-context.d.ts +1 -0
  146. package/dist/lib/store-context.d.ts.map +1 -1
  147. package/dist/lib/store-context.js +1 -0
  148. package/dist/lib/utils/catalog-price-bounds.d.ts +2 -0
  149. package/dist/lib/utils/catalog-price-bounds.d.ts.map +1 -1
  150. package/dist/lib/utils/catalog-price-bounds.js +21 -0
  151. package/dist/lib/utils/filtered-product-query.d.ts +22 -0
  152. package/dist/lib/utils/filtered-product-query.d.ts.map +1 -0
  153. package/dist/lib/utils/filtered-product-query.js +57 -0
  154. package/dist/lib/utils/filtered-products-inflight.d.ts +3 -0
  155. package/dist/lib/utils/filtered-products-inflight.d.ts.map +1 -0
  156. package/dist/lib/utils/filtered-products-inflight.js +15 -0
  157. package/dist/lib/utils/url-helpers.d.ts.map +1 -1
  158. package/dist/lib/utils/url-helpers.js +2 -11
  159. package/dist/styles/index.css +33 -6
  160. package/package.json +2 -2
@@ -13,14 +13,17 @@ import { useLoading } from '../../../lib/loading-context.js';
13
13
  import { useAnalytics } from '../../../hooks/use-analytics.js';
14
14
  import { ChevronDown, ChevronUp, Star, Check, Search, RotateCcw, SlidersHorizontal } from 'lucide-react';
15
15
  import { useSearchParams } from 'next/navigation';
16
- import { useState, useMemo, useEffect, useRef, Suspense } from 'react';
16
+ import { useState, useMemo, useEffect, Suspense } from 'react';
17
17
  import { useProductBrands } from '../../../hooks/use-product-brands.js';
18
+ import { useFilteredProductsFetch } from '../../../hooks/use-filtered-products-fetch.js';
18
19
  import { filterActiveProducts } from '../../../lib/utils/index.js';
19
20
  import { getAllCategoryIds, flattenCategoryTree, buildCategoryTree } from '../../../lib/utils/category-tree.js';
20
21
  import { getBannerImage, getLayoutText } from '../../../lib/utils/asset-helpers.js';
21
22
  import { shouldUseAPI } from '../../../lib/utils/demo-detection.js';
22
23
  import { useCatalogPriceRange } from '../../../hooks/use-catalog-price-range.js';
23
- import { isWithinActivePriceRange } from '../../../lib/utils/catalog-price-bounds.js';
24
+ import { getApiPriceFilterActive, isWithinActivePriceRange } from '../../../lib/utils/catalog-price-bounds.js';
25
+ import { buildFilteredProductQuery, getFilteredProductQueryKey, } from '../../../lib/utils/filtered-product-query.js';
26
+ import { transformProductToStoreProduct } from '../../../lib/store-config-utils.js';
24
27
  import { ProductPriceFilterSection } from '../../shared/components/ProductPriceFilterSection';
25
28
  function ProductsPageContent({ storeConfig }) {
26
29
  const searchParams = useSearchParams();
@@ -62,7 +65,9 @@ function ProductsPageContent({ storeConfig }) {
62
65
  const [selectedBrands, setSelectedBrands] = useState([]);
63
66
  const [selectedCategories, setSelectedCategories] = useState([]);
64
67
  const storeCurrency = storeConfig.settings?.currency || 'NGN';
65
- const { priceRange, setPriceRange, catalogBounds, resetPriceRange, hasActivePriceFilter, } = useCatalogPriceRange(products);
68
+ const bootstrapProducts = useMemo(() => filterActiveProducts(storeConfig.products || []), [storeConfig.products]);
69
+ const priceCatalogItems = bootstrapProducts.length > 0 ? bootstrapProducts : products;
70
+ const { priceRange, setPriceRange, catalogBounds, resetPriceRange, hasActivePriceFilter, } = useCatalogPriceRange(priceCatalogItems);
66
71
  const [selectedCategoryFilter, setSelectedCategoryFilter] = useState(null);
67
72
  // Initialize filters from URL
68
73
  useEffect(() => {
@@ -180,64 +185,52 @@ function ProductsPageContent({ storeConfig }) {
180
185
  }
181
186
  return result;
182
187
  }, [products, selectedBrands, effectiveCategoryIds, priceRange, selectedCategoryFilter, minRating, showInStockOnly, sortBy, categories]);
183
- const productQuery = useMemo(() => {
184
- const categoryIds = new Set(effectiveCategoryIds);
185
- const selectedCategory = categories.find((category) => category.slug === selectedCategoryFilter);
186
- if (selectedCategory)
187
- getAllCategoryIds(selectedCategory).forEach((id) => categoryIds.add(id));
188
- return {
188
+ const hasApiPriceFilter = getApiPriceFilterActive(priceRange, bootstrapProducts);
189
+ const priceQueryMin = hasApiPriceFilter ? priceRange[0] : undefined;
190
+ const priceQueryMax = hasApiPriceFilter ? priceRange[1] : undefined;
191
+ const { productQueryParams, productQueryKey } = useMemo(() => {
192
+ const params = buildFilteredProductQuery({
189
193
  storeId: storeConfig.id,
190
- categoryIds: categoryIds.size ? Array.from(categoryIds).join(',') : undefined,
191
- brands: selectedBrands.length ? selectedBrands.join(',') : undefined,
192
- minPrice: priceRange[0] || undefined,
193
- maxPrice: priceRange[1] < catalogBounds.max ? priceRange[1] : undefined,
194
- rating: minRating || undefined,
195
- inStock: showInStockOnly || undefined,
194
+ categories,
195
+ effectiveCategoryIds,
196
+ selectedCategoryFilter,
197
+ selectedBrands,
198
+ priceRange,
199
+ hasActivePriceFilter: hasApiPriceFilter,
200
+ minRating,
201
+ showInStockOnly,
196
202
  sortBy,
203
+ });
204
+ return {
205
+ productQueryParams: params,
206
+ productQueryKey: getFilteredProductQueryKey(params),
197
207
  };
198
- }, [catalogBounds.max, categories, effectiveCategoryIds, minRating, priceRange, selectedBrands, selectedCategoryFilter, showInStockOnly, sortBy, storeConfig.id]);
199
- const skipBootstrapRefetch = useRef(true);
200
- useEffect(() => {
201
- let cancelled = false;
202
- const isDefaultQuery = !productQuery.categoryIds &&
203
- !productQuery.brands &&
204
- !productQuery.minPrice &&
205
- productQuery.maxPrice === undefined &&
206
- !productQuery.rating &&
207
- !productQuery.inStock &&
208
- productQuery.sortBy === 'featured';
209
- const fetchFilteredProducts = async () => {
210
- // Keep SSR bootstrap first paint; only refetch when filters/sort change.
211
- if (skipBootstrapRefetch.current && isDefaultQuery && products.length > 0) {
212
- skipBootstrapRefetch.current = false;
213
- setTotalProducts(storeConfig.productsTotal || products.length);
214
- return;
215
- }
216
- skipBootstrapRefetch.current = false;
217
- setIsLoadingProducts(true);
218
- try {
219
- const { productService } = await import('../../../lib/services/product.service.js');
220
- const { transformProductToStoreProduct } = await import('../../../lib/store-config-utils.js');
221
- const response = await productService.getProducts({ ...productQuery, page: 1, limit: 12 });
222
- if (cancelled)
223
- return;
224
- setProducts(response.data.map(transformProductToStoreProduct));
225
- setCurrentPage(1);
226
- setTotalProducts(response.meta.total);
227
- setVisibleProducts(12);
228
- }
229
- catch (error) {
230
- if (!cancelled)
231
- console.error('Failed to fetch products:', error);
232
- }
233
- finally {
234
- if (!cancelled)
235
- setIsLoadingProducts(false);
236
- }
237
- };
238
- fetchFilteredProducts();
239
- return () => { cancelled = true; };
240
- }, [productQuery]);
208
+ }, [
209
+ storeConfig.id,
210
+ categories,
211
+ effectiveCategoryIds,
212
+ selectedCategoryFilter,
213
+ selectedBrands,
214
+ hasApiPriceFilter,
215
+ priceQueryMin,
216
+ priceQueryMax,
217
+ minRating,
218
+ showInStockOnly,
219
+ sortBy,
220
+ ]);
221
+ useFilteredProductsFetch(productQueryParams, productQueryKey, {
222
+ bootstrapItemCount: bootstrapProducts.length,
223
+ bootstrapTotal: storeConfig.productsTotal,
224
+ mapResponse: (data) => data.map(transformProductToStoreProduct),
225
+ applyResults: (items, total) => {
226
+ setProducts(items);
227
+ setCurrentPage(1);
228
+ setTotalProducts(total);
229
+ setVisibleProducts(12);
230
+ },
231
+ setTotalProducts,
232
+ setLoading: setIsLoadingProducts,
233
+ });
241
234
  const displayedProducts = filteredAndSortedProducts.slice(0, visibleProducts);
242
235
  const hasMore = currentPage * 12 < totalProducts;
243
236
  const handleLoadMore = async () => {
@@ -248,7 +241,7 @@ function ProductsPageContent({ storeConfig }) {
248
241
  const { productService } = await import('../../../lib/services/product.service.js');
249
242
  const { transformProductToStoreProduct } = await import('../../../lib/store-config-utils.js');
250
243
  const nextPage = currentPage + 1;
251
- const response = await productService.getProducts({ ...productQuery, page: nextPage, limit: 12 });
244
+ const response = await productService.getProducts({ ...productQueryParams, page: nextPage, limit: 12 });
252
245
  setProducts((current) => [...current, ...response.data.map(transformProductToStoreProduct)]);
253
246
  setCurrentPage(nextPage);
254
247
  setTotalProducts(response.meta.total);
@@ -318,7 +311,7 @@ function ProductsPageContent({ storeConfig }) {
318
311
  const secondaryButtonText = hasSecondaryButtonFromConfig
319
312
  ? (categoryHeaderSecondaryButton && categoryHeaderSecondaryButton.trim() !== '' ? categoryHeaderSecondaryButton.trim() : null)
320
313
  : getLayoutText(storeConfig, 'sections.categories.viewAll', 'View Categories');
321
- return (_jsxs("div", { className: "min-h-screen bg-white font-sans text-slate-900", children: [_jsxs("div", { className: "relative overflow-hidden bg-white", children: [categoryHeaderImage && (_jsxs("div", { className: "absolute inset-0 z-0", children: [_jsx(ImageWithFallback, { src: categoryHeaderImage, alt: categoryHeaderTitle || storeConfig.name, className: "w-full h-full object-cover", skeletonAspectRatio: "16/9" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-r from-black/60 via-black/40 to-black/60" })] })), !categoryHeaderImage && (_jsxs("div", { className: "absolute top-0 left-0 w-full h-full overflow-hidden z-0 pointer-events-none", children: [_jsx("div", { className: "absolute top-[-10%] right-[-5%] w-[500px] h-[500px] bg-gray-100 rounded-full mix-blend-multiply filter blur-3xl opacity-70 animate-pulse-slow" }), _jsx("div", { className: "absolute bottom-[-10%] left-[-10%] w-[400px] h-[400px] bg-gray-50 rounded-full mix-blend-multiply filter blur-3xl opacity-70 animate-pulse-slow", style: { animationDelay: '2s' } })] })), _jsx("div", { className: `container mx-auto px-4 sm:px-6 lg:px-8 relative z-10 pt-12 pb-16 lg:pt-20 lg:pb-24 ${categoryHeaderImage ? 'min-h-[500px] flex items-center' : ''}`, children: _jsx("div", { className: "flex flex-col items-center w-full max-w-4xl mx-auto", children: _jsxs("div", { className: `w-full text-center lg:text-left animate-fade-in-up ${categoryHeaderImage ? 'text-white' : ''}`, children: [_jsx("div", { className: "flex justify-center lg:justify-start mb-6", children: _jsx("div", { className: categoryHeaderImage ? 'bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20' : '', children: _jsx(Breadcrumbs, { items: breadcrumbItems, variant: categoryHeaderImage ? 'light' : 'default' }) }) }), _jsxs("div", { className: `inline-flex items-center gap-2 px-3 py-1 rounded-full text-xs font-bold tracking-wider uppercase mb-6 ${categoryHeaderImage ? 'bg-white/20 backdrop-blur-md text-white border border-white/30' : 'bg-black/5 text-gray-900'}`, children: [_jsx("span", { className: `w-2 h-2 rounded-full animate-pulse ${categoryHeaderImage ? 'bg-white' : 'bg-black'}` }), getLayoutText(storeConfig, 'common.newArrivals', 'New Arrivals 2024')] }), _jsx("h1", { className: `text-4xl sm:text-5xl lg:text-6xl font-bold tracking-tight mb-6 leading-[1.1] ${categoryHeaderImage ? 'text-white' : 'text-gray-900'}`, children: categoryHeaderTitle || (_jsxs(_Fragment, { children: ["Explore The Collections of ", _jsx("br", {}), _jsx("span", { className: "text-transparent bg-clip-text bg-gradient-to-r from-gray-900 via-gray-700 to-gray-900", children: storeConfig.name })] })) }), _jsx("p", { className: `text-lg mb-8 leading-relaxed max-w-lg mx-auto lg:mx-0 ${categoryHeaderImage ? 'text-white/90' : 'text-gray-600'}`, children: getLayoutText(storeConfig, 'category_header:description', "Don't miss out on shopping our latest collection! curated for quality and style. Experience the perfect blend of modern aesthetics and premium craftsmanship.") }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-4 justify-center lg:justify-start", children: [primaryButtonText && primaryButtonText.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 text-gray-900 hover:bg-gray-100' : ''}`, onClick: () => {
314
+ return (_jsxs("div", { className: "min-h-screen bg-white font-sans text-slate-900", children: [_jsxs("div", { className: "relative overflow-hidden bg-white", children: [categoryHeaderImage && (_jsxs("div", { className: "absolute inset-0 z-0", children: [_jsx(ImageWithFallback, { src: categoryHeaderImage, alt: categoryHeaderTitle || storeConfig.name, className: "w-full h-full object-cover", skeletonAspectRatio: "16/9" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-r from-black/60 via-black/40 to-black/60" })] })), !categoryHeaderImage && (_jsxs("div", { className: "absolute top-0 left-0 w-full h-full overflow-hidden z-0 pointer-events-none", children: [_jsx("div", { className: "absolute top-[-10%] right-[-5%] w-[500px] h-[500px] bg-gray-100 rounded-full mix-blend-multiply filter blur-3xl opacity-70 animate-pulse-slow" }), _jsx("div", { className: "absolute bottom-[-10%] left-[-10%] w-[400px] h-[400px] bg-gray-50 rounded-full mix-blend-multiply filter blur-3xl opacity-70 animate-pulse-slow", style: { animationDelay: '2s' } })] })), _jsx("div", { className: `container mx-auto px-4 sm:px-6 lg:px-8 relative z-10 pt-12 pb-16 lg:pt-20 lg:pb-24 ${categoryHeaderImage ? 'min-h-[500px] flex items-center' : ''}`, children: _jsx("div", { className: "flex flex-col items-center w-full max-w-4xl mx-auto", children: _jsxs("div", { className: `w-full text-center lg:text-left animate-fade-in-up ${categoryHeaderImage ? 'text-white' : ''}`, children: [_jsx("div", { className: "flex justify-center lg:justify-start mb-6", children: _jsx("div", { className: categoryHeaderImage ? 'bg-white/10 backdrop-blur-md px-4 py-2 rounded-full border border-white/20' : '', children: _jsx(Breadcrumbs, { items: breadcrumbItems, variant: categoryHeaderImage ? 'light' : 'default' }) }) }), _jsx("h1", { className: `text-4xl sm:text-5xl lg:text-6xl font-bold tracking-tight mb-6 leading-[1.1] ${categoryHeaderImage ? 'text-white' : 'text-gray-900'}`, children: categoryHeaderTitle || (_jsxs(_Fragment, { children: ["Explore The Collections of ", _jsx("br", {}), _jsx("span", { className: "text-transparent bg-clip-text bg-gradient-to-r from-gray-900 via-gray-700 to-gray-900", children: storeConfig.name })] })) }), _jsx("p", { className: `text-lg mb-8 leading-relaxed max-w-lg mx-auto lg:mx-0 ${categoryHeaderImage ? 'text-white/90' : 'text-gray-600'}`, children: getLayoutText(storeConfig, 'category_header:description', "Don't miss out on shopping our latest collection! curated for quality and style. Experience the perfect blend of modern aesthetics and premium craftsmanship.") }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-4 justify-center lg:justify-start", children: [primaryButtonText && primaryButtonText.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 text-gray-900 hover:bg-gray-100' : ''}`, onClick: () => {
322
315
  const element = document.getElementById('product-grid');
323
316
  element?.scrollIntoView({ behavior: 'smooth' });
324
317
  }, 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: () => {
@@ -1 +1 @@
1
- {"version":3,"file":"FoodHomePage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/components/FoodHomePage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAe/D,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,iBAAiB,+BA2jC7E"}
1
+ {"version":3,"file":"FoodHomePage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/components/FoodHomePage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAiB,MAAM,mBAAmB,CAAC;AAiB/D,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,iBAAiB,+BAikC7E"}
@@ -12,6 +12,8 @@ import { getLayoutText, getBannerImage, getTextContent, normalizeStoreImageUrl }
12
12
  import { toStoreHref } from '../../../lib/utils/url-helpers.js';
13
13
  import { shouldUseAPI } from '../../../lib/utils/demo-detection.js';
14
14
  import { TestimonialCard } from '../../shared/components/TestimonialCard';
15
+ import { SafeRichHtml } from '../../../components/rich-text/SafeRichHtml.js';
16
+ import { RichTextExcerpt } from '../../../components/rich-text/RichTextExcerpt.js';
15
17
  export function FoodHomePage({ storeConfig: initialConfig }) {
16
18
  const { store, addToCart } = useStore();
17
19
  const storeConfig = store || initialConfig;
@@ -310,7 +312,7 @@ export function FoodHomePage({ storeConfig: initialConfig }) {
310
312
  const handleInputChange = (field, value) => {
311
313
  setReservationData(prev => ({ ...prev, [field]: value }));
312
314
  };
313
- return (_jsxs("div", { className: "min-h-screen bg-[#FAFAFA]", children: [(layoutConfig?.sections?.hero?.show !== false || layoutConfig?.hero?.show !== false) && heroSlides.length > 0 && (_jsxs("section", { "data-section": "hero", className: "relative h-[90vh] w-full overflow-hidden bg-black", onMouseEnter: () => setIsAutoPlaying(false), onMouseLeave: () => setIsAutoPlaying(true), children: [heroSlides.map((slide, index) => (_jsxs("div", { className: `absolute inset-0 transition-opacity duration-1000 ease-in-out ${index === currentSlide ? 'opacity-100 z-10' : 'opacity-0 z-0'}`, children: [_jsxs("div", { className: "absolute inset-0", children: [_jsx(Image, { src: slide.image, alt: slide.title, fill: true, className: `object-cover transition-transform duration-[10000ms] ease-linear ${index === currentSlide ? 'scale-110' : 'scale-100'}`, unoptimized: true }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-r from-black/80 via-black/40 to-transparent" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent" })] }), _jsx("div", { className: "absolute inset-0 flex items-center", children: _jsx("div", { className: "container mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: `max-w-3xl space-y-8 transition-all duration-1000 transform ${index === currentSlide ? 'translate-y-0 opacity-100' : 'translate-y-10 opacity-0'}`, children: [_jsxs("div", { className: "inline-flex items-center gap-3 px-5 py-2.5 bg-orange-500 text-white rounded-full text-sm font-bold shadow-[0_0_20px_rgba(249,115,22,0.4)] backdrop-blur-md border border-orange-400/50 w-fit", children: [_jsx(Flame, { className: "h-4 w-4 fill-white animate-bounce" }), " ", slide.badge] }), _jsxs("h1", { className: "text-5xl sm:text-6xl lg:text-8xl font-black text-white tracking-tighter leading-[1.1] drop-shadow-2xl", children: [slide.title, " ", _jsx("br", {}), _jsx("span", { className: "text-transparent bg-clip-text bg-gradient-to-r from-orange-400 via-yellow-400 to-orange-500", children: slide.highlight })] }), _jsx("p", { className: "text-xl sm:text-2xl text-gray-200 max-w-xl font-medium leading-relaxed drop-shadow-lg", children: slide.description }), _jsxs("div", { className: "flex flex-wrap gap-5 pt-4", children: [(layoutConfig?.sections?.hero?.showCTA !== false || layoutConfig?.hero?.showCTA !== false) &&
315
+ return (_jsxs("div", { className: "min-h-screen bg-[#FAFAFA]", children: [(layoutConfig?.sections?.hero?.show !== false || layoutConfig?.hero?.show !== false) && heroSlides.length > 0 && (_jsxs("section", { "data-section": "hero", className: "relative h-[90vh] w-full overflow-hidden bg-black", onMouseEnter: () => setIsAutoPlaying(false), onMouseLeave: () => setIsAutoPlaying(true), children: [heroSlides.map((slide, index) => (_jsxs("div", { className: `absolute inset-0 transition-opacity duration-1000 ease-in-out ${index === currentSlide ? 'opacity-100 z-10' : 'opacity-0 z-0'}`, children: [_jsxs("div", { className: "absolute inset-0", children: [_jsx(Image, { src: slide.image, alt: slide.title, fill: true, className: `object-cover transition-transform duration-[10000ms] ease-linear ${index === currentSlide ? 'scale-110' : 'scale-100'}`, unoptimized: true }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-r from-black/80 via-black/40 to-transparent" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent" })] }), _jsx("div", { className: "absolute inset-0 flex items-center", children: _jsx("div", { className: "container mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: `max-w-3xl space-y-8 transition-all duration-1000 transform ${index === currentSlide ? 'translate-y-0 opacity-100' : 'translate-y-10 opacity-0'}`, children: [_jsxs("div", { className: "inline-flex items-center gap-3 px-5 py-2.5 bg-orange-500 text-white rounded-full text-sm font-bold shadow-[0_0_20px_rgba(249,115,22,0.4)] backdrop-blur-md border border-orange-400/50 w-fit", children: [_jsx(Flame, { className: "h-4 w-4 fill-white animate-bounce" }), " ", slide.badge] }), _jsxs("h1", { className: "text-5xl sm:text-6xl lg:text-8xl font-black text-white tracking-tighter leading-[1.1] drop-shadow-2xl", children: [slide.title, " ", _jsx("br", {}), _jsx("span", { className: "text-transparent bg-clip-text bg-gradient-to-r from-orange-400 via-yellow-400 to-orange-500", children: slide.highlight })] }), _jsx(SafeRichHtml, { value: slide.description, as: "div", className: "text-xl sm:text-2xl text-gray-200 max-w-xl font-medium leading-relaxed drop-shadow-lg [&_p]:mb-0" }), _jsxs("div", { className: "flex flex-wrap gap-5 pt-4", children: [(layoutConfig?.sections?.hero?.showCTA !== false || layoutConfig?.hero?.showCTA !== false) &&
314
316
  slide.primaryBtn &&
315
317
  slide.primaryBtn.trim() !== '' && (_jsx(Link, { href: slide.primaryBtnLink || `/${storeConfig.slug}/menu`, children: _jsx(Button, { size: "lg", className: "h-16 px-10 text-lg font-bold rounded-full bg-gradient-to-r from-orange-600 to-orange-500 hover:from-orange-700 hover:to-orange-600 text-white shadow-[0_10px_30px_rgba(249,115,22,0.4)] transition-all hover:scale-105 hover:-translate-y-1", children: slide.primaryBtn }) })), (layoutConfig?.sections?.hero?.showSecondaryCTA !== false || layoutConfig?.hero?.showSecondaryCTA !== false) &&
316
318
  slide.secondaryBtn &&
@@ -330,9 +332,9 @@ export function FoodHomePage({ storeConfig: initialConfig }) {
330
332
  const iconMap = { Smartphone, ChefHat, Truck };
331
333
  return steps.map((step, idx) => {
332
334
  const IconComponent = iconMap[step.icon] || Utensils;
333
- return (_jsxs("div", { className: "flex flex-col items-center text-center group", children: [_jsxs("div", { className: "w-32 h-32 rounded-[2rem] bg-white flex items-center justify-center mb-8 shadow-[0_20px_50px_rgba(0,0,0,0.05)] group-hover:shadow-[0_20px_50px_rgba(249,115,22,0.15)] group-hover:-translate-y-2 transition-all duration-500 relative z-10 border border-gray-100", children: [_jsx("div", { className: "p-4 bg-orange-50 rounded-2xl group-hover:bg-orange-100 transition-colors duration-500", children: _jsx(IconComponent, { className: "h-10 w-10 text-orange-500 group-hover:scale-110 transition-transform duration-500" }) }), _jsx("div", { className: "absolute -top-3 -right-3 w-8 h-8 bg-orange-500 rounded-full flex items-center justify-center text-white font-bold text-sm shadow-lg", children: idx + 1 })] }), _jsx("h3", { className: "text-2xl font-bold text-gray-900 mb-4", children: step.title }), _jsx("p", { className: "text-gray-500 leading-relaxed max-w-xs font-medium", children: step.description })] }, idx));
335
+ return (_jsxs("div", { className: "flex flex-col items-center text-center group", children: [_jsxs("div", { className: "w-32 h-32 rounded-[2rem] bg-white flex items-center justify-center mb-8 shadow-[0_20px_50px_rgba(0,0,0,0.05)] group-hover:shadow-[0_20px_50px_rgba(249,115,22,0.15)] group-hover:-translate-y-2 transition-all duration-500 relative z-10 border border-gray-100", children: [_jsx("div", { className: "p-4 bg-orange-50 rounded-2xl group-hover:bg-orange-100 transition-colors duration-500", children: _jsx(IconComponent, { className: "h-10 w-10 text-orange-500 group-hover:scale-110 transition-transform duration-500" }) }), _jsx("div", { className: "absolute -top-3 -right-3 w-8 h-8 bg-orange-500 rounded-full flex items-center justify-center text-white font-bold text-sm shadow-lg", children: idx + 1 })] }), _jsx("h3", { className: "text-2xl font-bold text-gray-900 mb-4", children: step.title }), _jsx(RichTextExcerpt, { value: step.description, as: "p", className: "text-gray-500 leading-relaxed max-w-xs font-medium" })] }, idx));
334
336
  });
335
- })()] })] }) })), layoutConfig?.sections?.featuredProducts?.show !== false && (_jsx("section", { "data-section": "featuredProducts", className: "py-16 md:py-20 px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "container mx-auto max-w-7xl", children: [_jsxs("div", { className: "flex flex-col md:flex-row items-end justify-between mb-8 md:mb-12 gap-4", children: [_jsxs("div", { children: [_jsx("span", { className: "text-orange-500 font-bold tracking-widest uppercase text-xs mb-3 block", children: layoutConfig?.sections?.featuredProducts?.subtitle || "Our Menu" }), _jsx("h2", { className: "text-3xl md:text-4xl font-black text-gray-900 tracking-tight", children: layoutConfig?.sections?.featuredProducts?.title || getLayoutText(storeConfig, 'food.chefRecommendations', 'Chef\'s Recommendations') })] }), _jsxs(Link, { href: `/${storeConfig.slug}/menu`, className: "group flex items-center gap-2 text-gray-600 hover:text-orange-600 font-bold transition-colors", children: [layoutConfig?.sections?.featuredProducts?.viewAllLabel || getLayoutText(storeConfig, 'food.viewMenu', 'View Full Menu'), " ", _jsx(ArrowRight, { className: "h-5 w-5 transition-transform group-hover:translate-x-1" })] })] }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8", children: menuItems.slice(0, 3).map((item) => (_jsxs("div", { className: "group bg-white rounded-[2rem] border border-gray-100 shadow-sm hover:shadow-[0_20px_50px_rgba(0,0,0,0.08)] transition-all duration-500 overflow-hidden flex flex-col h-full hover:-translate-y-2", children: [_jsxs("div", { className: "relative aspect-[4/3] overflow-hidden m-3 rounded-[1.5rem]", children: [item.image ? (_jsx("div", { className: "w-full h-full relative", children: _jsx(Image, { src: item.image, alt: item.name, fill: true, className: "object-cover transition-transform duration-700 group-hover:scale-110", unoptimized: true }) })) : (_jsx("div", { className: "w-full h-full bg-gray-100 flex items-center justify-center", children: _jsx(Utensils, { className: "h-12 w-12 text-gray-300" }) })), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" }), _jsx("div", { className: "absolute top-4 right-4 bg-white/95 backdrop-blur-md px-4 py-2 rounded-full font-black text-gray-900 shadow-lg border border-white/50", children: formatCurrency(item.price, storeConfig.settings?.currency || 'USD') }), _jsx("div", { className: "hidden lg:block absolute bottom-4 left-4 right-4 translate-y-20 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-500 delay-100", children: _jsx(Button, { onClick: () => handleAddToCart(item), className: "w-full h-12 rounded-xl bg-white hover:bg-orange-600 text-gray-900 hover:text-white font-bold shadow-xl border-0 transition-colors", children: "Add to Order" }) }), _jsx("button", { onClick: () => handleAddToCart(item), className: "lg:hidden absolute bottom-3 right-3 bg-white text-orange-600 w-10 h-10 rounded-full shadow-lg flex items-center justify-center font-bold z-10 active:scale-95 transition-transform", children: _jsx(Plus, { className: "h-5 w-5" }) })] }), _jsxs("div", { className: "p-6 pt-2 flex flex-col flex-1", children: [_jsx("div", { className: "flex justify-between items-start mb-2", children: _jsx("h3", { className: "font-bold text-xl text-gray-900 group-hover:text-orange-600 transition-colors line-clamp-1", children: item.name }) }), _jsx("p", { className: "text-gray-500 text-sm mb-6 line-clamp-2 flex-1 leading-relaxed font-medium", children: item.description }), item.dietaryInfo && item.dietaryInfo.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mt-auto pt-4 border-t border-gray-50", children: item.dietaryInfo.map((info) => (_jsx("span", { className: "text-[10px] font-bold uppercase tracking-wider px-3 py-1.5 bg-gray-50 text-gray-600 rounded-lg group-hover:bg-orange-50 group-hover:text-orange-700 transition-colors", children: info }, info))) }))] })] }, item.id))) })] }) })), layoutConfig?.sections?.about?.show !== false && (_jsx("section", { "data-section": "about", className: "py-16 md:py-20 px-4 sm:px-6 lg:px-8 bg-white overflow-hidden", children: _jsx("div", { className: "container mx-auto max-w-7xl", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-10 md:gap-12 lg:gap-20 items-center", children: [_jsx("div", { className: "order-2 lg:order-1", children: _jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute -top-10 -left-10 w-64 h-64 bg-orange-100 rounded-full blur-3xl opacity-50" }), _jsx("div", { className: "relative aspect-square rounded-3xl overflow-hidden shadow-2xl rotate-3 hover:rotate-0 transition-transform duration-700", children: _jsx(Image, { src: layoutConfig?.sections?.about?.image || getBannerImage(storeConfig, 'chef_image', "https://images.unsplash.com/photo-1583394293214-28ded15ee548?q=80&w=2000&auto=format&fit=crop"), alt: "Chef Cooking", fill: true, className: "object-cover", unoptimized: true }) }), _jsx("div", { className: "absolute -bottom-8 -right-8 bg-white p-6 rounded-2xl shadow-xl animate-fade-in-up hidden md:block", children: _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("div", { className: "p-3 bg-orange-100 rounded-full text-orange-600", children: _jsx(ChefHat, { className: "h-8 w-8" }) }), _jsxs("div", { children: [_jsx("p", { className: "font-bold text-gray-900 text-lg", children: "Master Chef" }), _jsx("p", { className: "text-sm text-gray-500", children: "15+ Years Experience" })] })] }) })] }) }), _jsxs("div", { className: "order-1 lg:order-2 space-y-6", children: [_jsx("span", { className: "text-orange-600 font-bold tracking-wider uppercase text-sm", children: layoutConfig?.sections?.about?.section_title || getLayoutText(storeConfig, 'chef_image:section_title', 'Our Story') }), _jsx("h2", { className: "text-4xl md:text-5xl font-black text-gray-900 leading-tight", children: layoutConfig?.sections?.about?.chef_name || getLayoutText(storeConfig, 'chef_image:chef_name', 'Crafted with Love, Served with Passion') }), _jsx("p", { className: "text-lg text-gray-600 leading-relaxed", children: layoutConfig?.sections?.about?.chef_bio || getLayoutText(storeConfig, 'chef_image:chef_bio', 'We believe that great food brings people together. Our chefs use only the freshest, locally-sourced ingredients to create dishes that not only taste amazing but also tell a story of tradition and innovation.') }), _jsx("div", { className: "grid grid-cols-2 gap-6 pt-4", children: (layoutConfig?.sections?.about?.showStats !== false) && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "space-y-2", children: [_jsx("h4", { className: "text-3xl font-black text-gray-900", children: layoutConfig?.sections?.about?.stat1Value || "15k+" }), _jsx("p", { className: "text-gray-500 font-medium", children: layoutConfig?.sections?.about?.stat1Label || "Happy Customers" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("h4", { className: "text-3xl font-black text-gray-900", children: layoutConfig?.sections?.about?.stat2Value || "100%" }), _jsx("p", { className: "text-gray-500 font-medium", children: layoutConfig?.sections?.about?.stat2Label || "Fresh Ingredients" })] })] })) }), _jsx("div", { className: "pt-6", children: _jsx(Link, { href: toStoreHref(storeConfig.slug, layoutConfig?.sections?.about?.buttonLink, '/about'), children: _jsx(Button, { variant: "outline", className: "rounded-full px-8 py-6 border-gray-200 hover:border-orange-600 hover:text-orange-600 text-base font-bold", children: layoutConfig?.sections?.about?.buttonText || "Read More About Us" }) }) })] })] }) }) })), layoutConfig?.sections?.testimonials?.show !== false && (_jsx("section", { "data-section": "testimonials", className: "py-16 md:py-24 px-4 sm:px-6 lg:px-8 bg-gradient-to-b from-white via-orange-50/30 to-white", children: _jsxs("div", { className: "container mx-auto max-w-7xl", children: [_jsxs("div", { className: "text-center mb-12 md:mb-20", children: [_jsx("span", { className: "text-orange-500 font-bold tracking-widest uppercase text-xs mb-3 block", children: "Testimonials" }), _jsx("h2", { className: "text-4xl md:text-5xl font-black text-gray-900 tracking-tight", children: layoutConfig?.sections?.testimonials?.title || getLayoutText(storeConfig, 'sections.testimonials.title', 'What Our Customers Say') }), _jsx("p", { className: "text-gray-500 text-lg mt-4 max-w-2xl mx-auto", children: layoutConfig?.sections?.testimonials?.subtitle || getLayoutText(storeConfig, 'sections.testimonials.subtitle', 'Real experiences from food lovers who trust us') })] }), _jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-8", children: (() => {
337
+ })()] })] }) })), layoutConfig?.sections?.featuredProducts?.show !== false && (_jsx("section", { "data-section": "featuredProducts", className: "py-16 md:py-20 px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "container mx-auto max-w-7xl", children: [_jsxs("div", { className: "flex flex-col md:flex-row items-end justify-between mb-8 md:mb-12 gap-4", children: [_jsxs("div", { children: [_jsx("span", { className: "text-orange-500 font-bold tracking-widest uppercase text-xs mb-3 block", children: layoutConfig?.sections?.featuredProducts?.subtitle || "Our Menu" }), _jsx("h2", { className: "text-3xl md:text-4xl font-black text-gray-900 tracking-tight", children: layoutConfig?.sections?.featuredProducts?.title || getLayoutText(storeConfig, 'food.chefRecommendations', 'Chef\'s Recommendations') })] }), _jsxs(Link, { href: `/${storeConfig.slug}/menu`, className: "group flex items-center gap-2 text-gray-600 hover:text-orange-600 font-bold transition-colors", children: [layoutConfig?.sections?.featuredProducts?.viewAllLabel || getLayoutText(storeConfig, 'food.viewMenu', 'View Full Menu'), " ", _jsx(ArrowRight, { className: "h-5 w-5 transition-transform group-hover:translate-x-1" })] })] }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8", children: menuItems.slice(0, 3).map((item) => (_jsxs("div", { className: "group bg-white rounded-[2rem] border border-gray-100 shadow-sm hover:shadow-[0_20px_50px_rgba(0,0,0,0.08)] transition-all duration-500 overflow-hidden flex flex-col h-full hover:-translate-y-2", children: [_jsxs("div", { className: "relative aspect-[4/3] overflow-hidden m-3 rounded-[1.5rem]", children: [item.image ? (_jsx("div", { className: "w-full h-full relative", children: _jsx(Image, { src: item.image, alt: item.name, fill: true, className: "object-cover transition-transform duration-700 group-hover:scale-110", unoptimized: true }) })) : (_jsx("div", { className: "w-full h-full bg-gray-100 flex items-center justify-center", children: _jsx(Utensils, { className: "h-12 w-12 text-gray-300" }) })), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" }), _jsx("div", { className: "absolute top-4 right-4 bg-white/95 backdrop-blur-md px-4 py-2 rounded-full font-black text-gray-900 shadow-lg border border-white/50", children: formatCurrency(item.price, storeConfig.settings?.currency || 'USD') }), _jsx("div", { className: "hidden lg:block absolute bottom-4 left-4 right-4 translate-y-20 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-500 delay-100", children: _jsx(Button, { onClick: () => handleAddToCart(item), className: "w-full h-12 rounded-xl bg-white hover:bg-orange-600 text-gray-900 hover:text-white font-bold shadow-xl border-0 transition-colors", children: "Add to Order" }) }), _jsx("button", { onClick: () => handleAddToCart(item), className: "lg:hidden absolute bottom-3 right-3 bg-white text-orange-600 w-10 h-10 rounded-full shadow-lg flex items-center justify-center font-bold z-10 active:scale-95 transition-transform", children: _jsx(Plus, { className: "h-5 w-5" }) })] }), _jsxs("div", { className: "p-6 pt-2 flex flex-col flex-1", children: [_jsx("div", { className: "flex justify-between items-start mb-2", children: _jsx("h3", { className: "font-bold text-xl text-gray-900 group-hover:text-orange-600 transition-colors line-clamp-1", children: item.name }) }), _jsx(RichTextExcerpt, { value: item.description, as: "p", className: "text-gray-500 text-sm mb-6 line-clamp-2 flex-1 leading-relaxed font-medium" }), item.dietaryInfo && item.dietaryInfo.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mt-auto pt-4 border-t border-gray-50", children: item.dietaryInfo.map((info) => (_jsx("span", { className: "text-[10px] font-bold uppercase tracking-wider px-3 py-1.5 bg-gray-50 text-gray-600 rounded-lg group-hover:bg-orange-50 group-hover:text-orange-700 transition-colors", children: info }, info))) }))] })] }, item.id))) })] }) })), layoutConfig?.sections?.about?.show !== false && (_jsx("section", { "data-section": "about", className: "py-16 md:py-20 px-4 sm:px-6 lg:px-8 bg-white overflow-hidden", children: _jsx("div", { className: "container mx-auto max-w-7xl", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-10 md:gap-12 lg:gap-20 items-center", children: [_jsx("div", { className: "order-2 lg:order-1", children: _jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute -top-10 -left-10 w-64 h-64 bg-orange-100 rounded-full blur-3xl opacity-50" }), _jsx("div", { className: "relative aspect-square rounded-3xl overflow-hidden shadow-2xl rotate-3 hover:rotate-0 transition-transform duration-700", children: _jsx(Image, { src: layoutConfig?.sections?.about?.image || getBannerImage(storeConfig, 'chef_image', "https://images.unsplash.com/photo-1583394293214-28ded15ee548?q=80&w=2000&auto=format&fit=crop"), alt: "Chef Cooking", fill: true, className: "object-cover", unoptimized: true }) }), _jsx("div", { className: "absolute -bottom-8 -right-8 bg-white p-6 rounded-2xl shadow-xl animate-fade-in-up hidden md:block", children: _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("div", { className: "p-3 bg-orange-100 rounded-full text-orange-600", children: _jsx(ChefHat, { className: "h-8 w-8" }) }), _jsxs("div", { children: [_jsx("p", { className: "font-bold text-gray-900 text-lg", children: "Master Chef" }), _jsx("p", { className: "text-sm text-gray-500", children: "15+ Years Experience" })] })] }) })] }) }), _jsxs("div", { className: "order-1 lg:order-2 space-y-6", children: [_jsx("span", { className: "text-orange-600 font-bold tracking-wider uppercase text-sm", children: layoutConfig?.sections?.about?.section_title || getLayoutText(storeConfig, 'chef_image:section_title', 'Our Story') }), _jsx("h2", { className: "text-4xl md:text-5xl font-black text-gray-900 leading-tight", children: layoutConfig?.sections?.about?.chef_name || getLayoutText(storeConfig, 'chef_image:chef_name', 'Crafted with Love, Served with Passion') }), _jsx("p", { className: "text-lg text-gray-600 leading-relaxed", children: layoutConfig?.sections?.about?.chef_bio || getLayoutText(storeConfig, 'chef_image:chef_bio', 'We believe that great food brings people together. Our chefs use only the freshest, locally-sourced ingredients to create dishes that not only taste amazing but also tell a story of tradition and innovation.') }), _jsx("div", { className: "grid grid-cols-2 gap-6 pt-4", children: (layoutConfig?.sections?.about?.showStats !== false) && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "space-y-2", children: [_jsx("h4", { className: "text-3xl font-black text-gray-900", children: layoutConfig?.sections?.about?.stat1Value || "15k+" }), _jsx("p", { className: "text-gray-500 font-medium", children: layoutConfig?.sections?.about?.stat1Label || "Happy Customers" })] }), _jsxs("div", { className: "space-y-2", children: [_jsx("h4", { className: "text-3xl font-black text-gray-900", children: layoutConfig?.sections?.about?.stat2Value || "100%" }), _jsx("p", { className: "text-gray-500 font-medium", children: layoutConfig?.sections?.about?.stat2Label || "Fresh Ingredients" })] })] })) }), _jsx("div", { className: "pt-6", children: _jsx(Link, { href: toStoreHref(storeConfig.slug, layoutConfig?.sections?.about?.buttonLink, '/about'), children: _jsx(Button, { variant: "outline", className: "rounded-full px-8 py-6 border-gray-200 hover:border-orange-600 hover:text-orange-600 text-base font-bold", children: layoutConfig?.sections?.about?.buttonText || "Read More About Us" }) }) })] })] }) }) })), layoutConfig?.sections?.testimonials?.show !== false && (_jsx("section", { "data-section": "testimonials", className: "py-16 md:py-24 px-4 sm:px-6 lg:px-8 bg-gradient-to-b from-white via-orange-50/30 to-white", children: _jsxs("div", { className: "container mx-auto max-w-7xl", children: [_jsxs("div", { className: "text-center mb-12 md:mb-20", children: [_jsx("span", { className: "text-orange-500 font-bold tracking-widest uppercase text-xs mb-3 block", children: "Testimonials" }), _jsx("h2", { className: "text-4xl md:text-5xl font-black text-gray-900 tracking-tight", children: layoutConfig?.sections?.testimonials?.title || getLayoutText(storeConfig, 'sections.testimonials.title', 'What Our Customers Say') }), _jsx("p", { className: "text-gray-500 text-lg mt-4 max-w-2xl mx-auto", children: layoutConfig?.sections?.testimonials?.subtitle || getLayoutText(storeConfig, 'sections.testimonials.subtitle', 'Real experiences from food lovers who trust us') })] }), _jsx("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-8", children: (() => {
336
338
  // Use backend testimonials if available
337
339
  const backendTestimonials = layoutConfig?.sections?.testimonials?.items || [];
338
340
  const fallbackTestimonials = [
@@ -382,7 +384,7 @@ export function FoodHomePage({ storeConfig: initialConfig }) {
382
384
  return null;
383
385
  return features.map((feature, idx) => {
384
386
  const IconComponent = iconMap[feature.icon] || Star;
385
- return (_jsxs("div", { className: "group flex items-start gap-4 p-5 bg-white rounded-2xl shadow-sm hover:shadow-lg border border-gray-100 hover:border-orange-200 transition-all duration-300", children: [_jsx("div", { className: "p-3 bg-orange-50 rounded-xl group-hover:bg-orange-100 transition-colors", children: _jsx(IconComponent, { className: "h-6 w-6 text-orange-500" }) }), _jsxs("div", { children: [_jsx("h3", { className: "font-bold text-gray-900 mb-1.5", children: feature.title }), _jsx("p", { className: "text-sm text-gray-600 font-medium", children: feature.description })] })] }, idx));
387
+ return (_jsxs("div", { className: "group flex items-start gap-4 p-5 bg-white rounded-2xl shadow-sm hover:shadow-lg border border-gray-100 hover:border-orange-200 transition-all duration-300", children: [_jsx("div", { className: "p-3 bg-orange-50 rounded-xl group-hover:bg-orange-100 transition-colors", children: _jsx(IconComponent, { className: "h-6 w-6 text-orange-500" }) }), _jsxs("div", { children: [_jsx("h3", { className: "font-bold text-gray-900 mb-1.5", children: feature.title }), _jsx(RichTextExcerpt, { value: feature.description, as: "p", className: "text-sm text-gray-600 font-medium" })] })] }, idx));
386
388
  });
387
389
  })() }), _jsx("div", { className: "pt-6", children: _jsxs("div", { className: "flex items-center gap-4 p-5 bg-white rounded-2xl shadow-sm border border-gray-100", children: [_jsx("div", { className: "p-3 bg-orange-50 rounded-xl", children: _jsx(Phone, { className: "h-5 w-5 text-orange-500" }) }), _jsxs("div", { children: [_jsx("p", { className: "text-sm text-gray-500 font-medium mb-1", children: "Prefer to call?" }), _jsx("span", { className: "text-lg font-bold text-gray-900", children: layoutConfig?.sections?.reservation?.phone || "(555) 123-4567" })] })] }) })] }), _jsxs("div", { className: "bg-white rounded-[2.5rem] shadow-[0_20px_60px_rgba(0,0,0,0.1)] p-8 md:p-10 border border-gray-100 relative overflow-hidden", children: [_jsx("div", { className: "absolute top-0 right-0 w-64 h-64 bg-orange-50 rounded-full blur-3xl opacity-50 -z-10" }), submitSuccess ? (_jsxs("div", { className: "text-center py-12", children: [_jsx("div", { className: "w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-6", children: _jsx(CheckCircle, { className: "h-10 w-10 text-green-600" }) }), _jsx("h3", { className: "text-2xl font-bold text-gray-900 mb-2", children: "Reservation Confirmed!" }), _jsxs("p", { className: "text-gray-600", children: ["We've sent a confirmation email to ", reservationData.email] })] })) : (_jsxs("form", { onSubmit: handleReservationSubmit, className: "space-y-6", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { children: [_jsxs("label", { className: "block text-sm font-bold text-gray-900 mb-3", children: [_jsx(Calendar, { className: "h-4 w-4 inline mr-2 text-orange-500" }), "Date"] }), _jsx("input", { type: "date", required: true, min: minDate, max: maxDateString, value: reservationData.date, onChange: (e) => handleInputChange('date', e.target.value), className: "w-full px-5 py-4 rounded-2xl border-2 border-gray-200 focus:border-orange-500 focus:ring-4 focus:ring-orange-500/10 outline-none transition-all font-medium text-gray-900" })] }), _jsxs("div", { children: [_jsxs("label", { className: "block text-sm font-bold text-gray-900 mb-3", children: [_jsx(Clock, { className: "h-4 w-4 inline mr-2 text-orange-500" }), "Time"] }), _jsxs("select", { required: true, value: reservationData.time, onChange: (e) => handleInputChange('time', e.target.value), className: "w-full px-5 py-4 rounded-2xl border-2 border-gray-200 focus:border-orange-500 focus:ring-4 focus:ring-orange-500/10 outline-none transition-all font-medium text-gray-900", children: [_jsx("option", { value: "", children: "Select time" }), timeSlots.map((time) => (_jsx("option", { value: time, children: time }, time)))] })] })] }), _jsxs("div", { children: [_jsxs("label", { className: "block text-sm font-bold text-gray-900 mb-3", children: [_jsx(Users, { className: "h-4 w-4 inline mr-2 text-orange-500" }), getLayoutText(storeConfig, 'booking.selectDate', 'Number of Guests')] }), _jsxs("select", { required: true, value: reservationData.guests, onChange: (e) => handleInputChange('guests', e.target.value), className: "w-full px-5 py-4 rounded-2xl border-2 border-gray-200 focus:border-orange-500 focus:ring-4 focus:ring-orange-500/10 outline-none transition-all font-medium text-gray-900", children: [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].map((num) => (_jsxs("option", { value: num.toString(), children: [num, " ", num === 1 ? 'Guest' : 'Guests'] }, num))), _jsx("option", { value: "13+", children: "13+ Guests (Large Party)" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-sm font-bold text-gray-900 mb-3", children: getLayoutText(storeConfig, 'common.account', 'Full Name') }), _jsx("input", { type: "text", required: true, value: reservationData.name, onChange: (e) => handleInputChange('name', e.target.value), placeholder: "John Doe", className: "w-full px-5 py-4 rounded-2xl border-2 border-gray-200 focus:border-orange-500 focus:ring-4 focus:ring-orange-500/10 outline-none transition-all font-medium text-gray-900 placeholder:text-gray-400" })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsxs("div", { children: [_jsxs("label", { className: "block text-sm font-bold text-gray-900 mb-3", children: [_jsx(Mail, { className: "h-4 w-4 inline mr-2 text-orange-500" }), getLayoutText(storeConfig, 'common.account', 'Email')] }), _jsx("input", { type: "email", required: true, value: reservationData.email, onChange: (e) => handleInputChange('email', e.target.value), placeholder: "john@example.com", className: "w-full px-5 py-4 rounded-2xl border-2 border-gray-200 focus:border-orange-500 focus:ring-4 focus:ring-orange-500/10 outline-none transition-all font-medium text-gray-900 placeholder:text-gray-400" })] }), _jsxs("div", { children: [_jsxs("label", { className: "block text-sm font-bold text-gray-900 mb-3", children: [_jsx(Phone, { className: "h-4 w-4 inline mr-2 text-orange-500" }), getLayoutText(storeConfig, 'common.account', 'Phone')] }), _jsx("input", { type: "tel", required: true, value: reservationData.phone, onChange: (e) => handleInputChange('phone', e.target.value), placeholder: "(555) 123-4567", className: "w-full px-5 py-4 rounded-2xl border-2 border-gray-200 focus:border-orange-500 focus:ring-4 focus:ring-orange-500/10 outline-none transition-all font-medium text-gray-900 placeholder:text-gray-400" })] })] }), _jsxs("div", { children: [_jsxs("label", { className: "block text-sm font-bold text-gray-900 mb-3", children: [_jsx(MessageSquare, { className: "h-4 w-4 inline mr-2 text-orange-500" }), getLayoutText(storeConfig, 'common.account', 'Special Requests (Optional)')] }), _jsx("textarea", { value: reservationData.specialRequests, onChange: (e) => handleInputChange('specialRequests', e.target.value), placeholder: "Dietary restrictions, celebration details, seating preferences...", rows: 4, className: "w-full px-5 py-4 rounded-2xl border-2 border-gray-200 focus:border-orange-500 focus:ring-4 focus:ring-orange-500/10 outline-none transition-all resize-none font-medium text-gray-900 placeholder:text-gray-400" })] }), _jsx(Button, { type: "submit", disabled: isSubmitting, className: "w-full h-16 rounded-2xl bg-gradient-to-r from-orange-600 to-orange-500 hover:from-orange-700 hover:to-orange-600 text-white font-bold text-lg shadow-[0_10px_30px_rgba(249,115,22,0.3)] transition-all hover:scale-[1.02] hover:-translate-y-1 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 disabled:hover:translate-y-0", children: isSubmitting ? (_jsxs(_Fragment, { children: [_jsx(Clock, { className: "h-5 w-5 mr-2 animate-spin" }), getLayoutText(storeConfig, 'common.account', 'Processing...')] })) : (_jsxs(_Fragment, { children: [_jsx(Calendar, { className: "h-5 w-5 mr-2" }), getLayoutText(storeConfig, 'food.reserveTable', 'Reserve Table')] })) }), _jsx("p", { className: "text-xs text-center text-gray-500 font-medium", children: "By submitting, you agree to our reservation policy. Cancellations must be made 24 hours in advance." })] }))] })] }) })] })), layoutConfig?.sections?.marketing?.show !== false && (_jsx("section", { "data-section": "marketing", className: "py-16 md:py-24 px-4 sm:px-6 lg:px-8", children: _jsx("div", { className: "container mx-auto max-w-7xl", children: _jsxs("div", { className: "relative rounded-[2.5rem] overflow-hidden bg-gray-900 text-white isolate", children: [_jsx("div", { className: "absolute inset-0 opacity-20", children: _jsx(Image, { src: layoutConfig?.sections?.marketing?.backgroundImage || getBannerImage(storeConfig, 'newsletter_bg', "https://images.unsplash.com/photo-1555939594-58d7cb561ad1?q=80&w=2070&auto=format&fit=crop"), alt: "Pattern", fill: true, className: "object-cover", unoptimized: true }) }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-r from-gray-900 via-gray-900/80 to-transparent" }), _jsxs("div", { className: "relative z-10 flex flex-col lg:flex-row items-center justify-between p-12 lg:p-20 gap-12", children: [_jsxs("div", { className: "max-w-xl space-y-6", children: [_jsx("span", { className: "inline-block px-4 py-1.5 bg-orange-500 text-white rounded-full text-sm font-bold uppercase tracking-widest shadow-lg shadow-orange-500/30", children: layoutConfig?.sections?.marketing?.badge || "Limited Time" }), _jsx("h2", { className: "text-4xl md:text-5xl font-black leading-tight", children: layoutConfig?.sections?.marketing?.title || "Get 20% Off Your <br /> First Order" }), _jsx("p", { className: "text-gray-300 text-lg leading-relaxed", children: layoutConfig?.sections?.marketing?.subtitle || "Join our food lover's community and get exclusive access to new menu items and special offers." }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-4 pt-4", children: [_jsx("input", { type: "email", placeholder: layoutConfig?.sections?.marketing?.newsletterPlaceholder || "Enter your email address", value: newsletterEmail, onChange: (e) => setNewsletterEmail(e.target.value), className: "px-6 py-4 rounded-full bg-white/10 border border-white/20 text-white placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-orange-500 flex-1 min-w-[300px]" }), _jsx(Button, { onClick: handleSubscribe, size: "lg", className: "rounded-full px-8 py-6 bg-orange-600 hover:bg-orange-700 font-bold text-lg shadow-lg shadow-orange-600/30", children: layoutConfig?.sections?.marketing?.newsletterButton || "Subscribe" })] })] }), _jsx("div", { className: "hidden lg:block relative", children: _jsx("div", { className: "w-80 h-80 rounded-full bg-gradient-to-tr from-orange-500 to-yellow-500 p-1 animate-spin-slow", children: _jsx("div", { className: "w-full h-full rounded-full bg-gray-900 flex items-center justify-center p-8 text-center", children: _jsxs("div", { children: [_jsx("span", { className: "block text-8xl font-black text-transparent bg-clip-text bg-gradient-to-r from-orange-400 to-yellow-400", children: layoutConfig?.sections?.marketing?.promoDiscount || "20%" }), _jsx("span", { className: "text-2xl font-bold text-white tracking-widest uppercase", children: "OFF" })] }) }) }) })] })] }) }) }))] }));
388
390
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AboutPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/pages/AboutPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOhD,UAAU,cAAc;IACtB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,cAAc,+BAkQvE"}
1
+ {"version":3,"file":"AboutPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/pages/AboutPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAShD,UAAU,cAAc;IACtB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,EAAE,cAAc,+BAkQvE"}
@@ -5,6 +5,7 @@ import { Button } from '../../../components/ui/button.js';
5
5
  import { DotPattern } from '../../../components/ui/background-patterns.js';
6
6
  import { useStore } from '../../../lib/store-context.js';
7
7
  import Image from 'next/image';
8
+ import { RichTextExcerpt } from '../../../components/rich-text/RichTextExcerpt.js';
8
9
  export function AboutPage({ storeConfig: initialConfig }) {
9
10
  const { store } = useStore();
10
11
  const storeConfig = store || initialConfig;
@@ -57,7 +58,7 @@ export function AboutPage({ storeConfig: initialConfig }) {
57
58
  description: "Committed to eco-friendly packaging and responsible sourcing."
58
59
  }
59
60
  ];
60
- return (_jsxs("div", { className: "min-h-screen bg-white pb-20 overflow-hidden", children: [_jsxs("section", { "data-section": "hero", className: "relative h-[60vh] min-h-[500px] w-full overflow-hidden", children: [_jsxs("div", { className: "absolute inset-0", children: [_jsx(Image, { src: heroImage, alt: "About Us", fill: true, className: "w-full h-full object-cover transform scale-105 animate-pulse-slow" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-r from-black/80 via-black/50 to-transparent" })] }), _jsx("div", { className: "absolute inset-0 flex items-center", children: _jsx("div", { className: "container mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "max-w-3xl animate-fade-in-up", children: [showBadge && (_jsxs("div", { className: "inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-white/10 backdrop-blur-md border border-white/20 text-white text-sm font-medium mb-6", children: [_jsx("span", { className: "w-2 h-2 rounded-full bg-white animate-pulse" }), badgeText] })), _jsx("h1", { className: "text-5xl md:text-7xl font-bold text-white mb-6 tracking-tight leading-tight", children: pageTitle }), _jsx("p", { className: "text-xl md:text-2xl text-gray-200 max-w-2xl leading-relaxed font-light", children: missionStatement })] }) }) })] }), content?.show !== false && (_jsxs("section", { "data-section": "story", className: "py-24 px-4 sm:px-6 lg:px-8 relative", children: [_jsx("div", { className: "absolute top-0 right-0 -mt-24 -mr-24 w-96 h-96 bg-gray-50 rounded-full blur-3xl -z-10" }), _jsx("div", { className: "container mx-auto max-w-7xl", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-16 items-center", children: [_jsxs("div", { className: "relative", children: [showGallery && galleryImages && galleryImages.length > 0 ? (_jsx("div", { className: "grid grid-cols-2 gap-4", children: galleryImages.slice(0, 4).map((img, i) => (_jsx("div", { className: `relative overflow-hidden rounded-2xl shadow-lg ${i === 0 ? 'col-span-2 aspect-[16/9]' : 'aspect-square'}`, children: _jsx(Image, { src: img.image, alt: img.caption || "Gallery Image", fill: true, className: "w-full h-full object-cover hover:scale-110 transition-transform duration-500" }) }, i))) })) : (_jsxs("div", { className: "relative aspect-[4/5] rounded-[2rem] overflow-hidden shadow-2xl", children: [_jsx(Image, { src: "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?q=80&w=2071&auto=format&fit=crop", alt: "Our Team", fill: true, className: "w-full h-full object-cover" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-60" }), _jsxs("div", { className: "absolute bottom-8 left-8 text-white", children: [_jsx("p", { className: "font-bold text-lg", children: "The Dream Team" }), _jsx("p", { className: "text-white/80 text-sm", children: "Working together to serve you better" })] })] })), _jsx("div", { className: "absolute -bottom-6 -right-6 w-24 h-24 bg-white rounded-2xl shadow-xl flex items-center justify-center p-4 animate-bounce duration-[3000ms]", children: _jsx(Heart, { className: "w-10 h-10", style: { color: primaryColor, fill: primaryColor } }) })] }), _jsxs("div", { className: "space-y-10", children: [_jsxs("div", { children: [_jsx("span", { className: "text-sm font-bold uppercase tracking-widest mb-3 block", style: { color: primaryColor }, children: sectionLabel }), _jsx("h2", { className: "text-4xl md:text-5xl font-black text-gray-900 mb-6 tracking-tight", children: sectionTitle }), _jsxs("div", { className: "prose prose-lg text-gray-600 leading-relaxed space-y-6", children: [pageContent?.split('\n').map((paragraph, idx) => (_jsx("p", { children: paragraph }, idx))), !pageContent && (_jsxs(_Fragment, { children: [_jsxs("p", { children: ["Founded with a bold vision to redefine excellence in the ", _jsx("span", { className: "font-semibold text-gray-900", children: storeConfig.type }), " industry, ", storeConfig.name, " has grown from a small passion project into a beloved brand. We believe in the power of quality, innovation, and community."] }), _jsx("p", { children: "Every day, we strive to bring you the best products, curated with care and delivered with a smile. Our team is dedicated to ensuring that your experience with us is nothing short of exceptional." })] }))] })] }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-8", children: values.map((item, idx) => (_jsxs("div", { className: "flex gap-4 group", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "w-14 h-14 rounded-2xl flex items-center justify-center transition-colors group-hover:bg-gray-100", style: { backgroundColor: `${primaryColor}10` }, children: _jsx(item.icon, { className: "h-7 w-7 transition-transform group-hover:scale-110", style: { color: primaryColor } }) }) }), _jsxs("div", { children: [_jsx("h4", { className: "font-bold text-gray-900 mb-2 text-lg", children: item.title }), _jsx("p", { className: "text-gray-600 text-sm leading-relaxed", children: item.description })] })] }, idx))) })] })] }) })] })), _jsxs("section", { "data-section": "stats", className: "py-20 relative overflow-hidden", children: [_jsx("div", { className: "absolute inset-0 opacity-10", children: _jsx(DotPattern, { color: primaryColor, cx: 2, cy: 2, cr: 2, width: 30, height: 30 }) }), _jsx("div", { className: "absolute inset-0", style: { backgroundColor: `${secondaryColor}15` } }), _jsx("div", { className: "container mx-auto px-4 relative z-10", children: _jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12", children: [
61
+ return (_jsxs("div", { className: "min-h-screen bg-white pb-20 overflow-hidden", children: [_jsxs("section", { "data-section": "hero", className: "relative h-[60vh] min-h-[500px] w-full overflow-hidden", children: [_jsxs("div", { className: "absolute inset-0", children: [_jsx(Image, { src: heroImage, alt: "About Us", fill: true, className: "w-full h-full object-cover transform scale-105 animate-pulse-slow" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-r from-black/80 via-black/50 to-transparent" })] }), _jsx("div", { className: "absolute inset-0 flex items-center", children: _jsx("div", { className: "container mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "max-w-3xl animate-fade-in-up", children: [showBadge && (_jsxs("div", { className: "inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-white/10 backdrop-blur-md border border-white/20 text-white text-sm font-medium mb-6", children: [_jsx("span", { className: "w-2 h-2 rounded-full bg-white animate-pulse" }), badgeText] })), _jsx("h1", { className: "text-5xl md:text-7xl font-bold text-white mb-6 tracking-tight leading-tight", children: pageTitle }), _jsx("p", { className: "text-xl md:text-2xl text-gray-200 max-w-2xl leading-relaxed font-light", children: missionStatement })] }) }) })] }), content?.show !== false && (_jsxs("section", { "data-section": "story", className: "py-24 px-4 sm:px-6 lg:px-8 relative", children: [_jsx("div", { className: "absolute top-0 right-0 -mt-24 -mr-24 w-96 h-96 bg-gray-50 rounded-full blur-3xl -z-10" }), _jsx("div", { className: "container mx-auto max-w-7xl", children: _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-16 items-center", children: [_jsxs("div", { className: "relative", children: [showGallery && galleryImages && galleryImages.length > 0 ? (_jsx("div", { className: "grid grid-cols-2 gap-4", children: galleryImages.slice(0, 4).map((img, i) => (_jsx("div", { className: `relative overflow-hidden rounded-2xl shadow-lg ${i === 0 ? 'col-span-2 aspect-[16/9]' : 'aspect-square'}`, children: _jsx(Image, { src: img.image, alt: img.caption || "Gallery Image", fill: true, className: "w-full h-full object-cover hover:scale-110 transition-transform duration-500" }) }, i))) })) : (_jsxs("div", { className: "relative aspect-[4/5] rounded-[2rem] overflow-hidden shadow-2xl", children: [_jsx(Image, { src: "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?q=80&w=2071&auto=format&fit=crop", alt: "Our Team", fill: true, className: "w-full h-full object-cover" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-transparent opacity-60" }), _jsxs("div", { className: "absolute bottom-8 left-8 text-white", children: [_jsx("p", { className: "font-bold text-lg", children: "The Dream Team" }), _jsx("p", { className: "text-white/80 text-sm", children: "Working together to serve you better" })] })] })), _jsx("div", { className: "absolute -bottom-6 -right-6 w-24 h-24 bg-white rounded-2xl shadow-xl flex items-center justify-center p-4 animate-bounce duration-[3000ms]", children: _jsx(Heart, { className: "w-10 h-10", style: { color: primaryColor, fill: primaryColor } }) })] }), _jsxs("div", { className: "space-y-10", children: [_jsxs("div", { children: [_jsx("span", { className: "text-sm font-bold uppercase tracking-widest mb-3 block", style: { color: primaryColor }, children: sectionLabel }), _jsx("h2", { className: "text-4xl md:text-5xl font-black text-gray-900 mb-6 tracking-tight", children: sectionTitle }), _jsxs("div", { className: "prose prose-lg text-gray-600 leading-relaxed space-y-6", children: [pageContent?.split('\n').map((paragraph, idx) => (_jsx("p", { children: paragraph }, idx))), !pageContent && (_jsxs(_Fragment, { children: [_jsxs("p", { children: ["Founded with a bold vision to redefine excellence in the ", _jsx("span", { className: "font-semibold text-gray-900", children: storeConfig.type }), " industry, ", storeConfig.name, " has grown from a small passion project into a beloved brand. We believe in the power of quality, innovation, and community."] }), _jsx("p", { children: "Every day, we strive to bring you the best products, curated with care and delivered with a smile. Our team is dedicated to ensuring that your experience with us is nothing short of exceptional." })] }))] })] }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-8", children: values.map((item, idx) => (_jsxs("div", { className: "flex gap-4 group", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "w-14 h-14 rounded-2xl flex items-center justify-center transition-colors group-hover:bg-gray-100", style: { backgroundColor: `${primaryColor}10` }, children: _jsx(item.icon, { className: "h-7 w-7 transition-transform group-hover:scale-110", style: { color: primaryColor } }) }) }), _jsxs("div", { children: [_jsx("h4", { className: "font-bold text-gray-900 mb-2 text-lg", children: item.title }), _jsx(RichTextExcerpt, { value: item.description, as: "p", className: "text-gray-600 text-sm leading-relaxed" })] })] }, idx))) })] })] }) })] })), _jsxs("section", { "data-section": "stats", className: "py-20 relative overflow-hidden", children: [_jsx("div", { className: "absolute inset-0 opacity-10", children: _jsx(DotPattern, { color: primaryColor, cx: 2, cy: 2, cr: 2, width: 30, height: 30 }) }), _jsx("div", { className: "absolute inset-0", style: { backgroundColor: `${secondaryColor}15` } }), _jsx("div", { className: "container mx-auto px-4 relative z-10", children: _jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12", children: [
61
62
  { label: "Happy Foodies", value: "15k+" },
62
63
  { label: "Menu Items", value: menuItems?.length ? `${menuItems.length}+` : "40+" },
63
64
  { label: "Years of Cooking", value: "8+" },
@@ -1,8 +1,10 @@
1
+ import { type CategoryProductsSeed } from '../../../hooks/use-category-products.js';
1
2
  import { StoreConfig } from '../../../lib/store-types.js';
2
3
  interface CategoryPageProps {
3
4
  storeConfig: StoreConfig;
4
5
  categorySlug: string;
6
+ categoryProductsSeed?: CategoryProductsSeed;
5
7
  }
6
- export declare function CategoryPage({ storeConfig: initialConfig, categorySlug }: CategoryPageProps): import("react").JSX.Element;
8
+ export declare function CategoryPage({ storeConfig: initialConfig, categorySlug, categoryProductsSeed }: CategoryPageProps): import("react").JSX.Element;
7
9
  export {};
8
10
  //# sourceMappingURL=CategoryPage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CategoryPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/pages/CategoryPage.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAA8B,MAAM,mBAAmB,CAAC;AAc5E,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,YAAY,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,EAAE,iBAAiB,+BAuK3F"}
1
+ {"version":3,"file":"CategoryPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/pages/CategoryPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAE/F,OAAO,EAAE,WAAW,EAA8B,MAAM,mBAAmB,CAAC;AAgB5E,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;CAC7C;AAED,wBAAgB,YAAY,CAAC,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,oBAAoB,EAAE,EAAE,iBAAiB,+BA2KjH"}
@@ -10,12 +10,14 @@ import { useToast } from '../../../components/ui/toast.js';
10
10
  import { useAnalytics } from '../../../hooks/use-analytics.js';
11
11
  import { useEffect } from 'react';
12
12
  import { formatCurrency } from '../../../lib/utils/index.js';
13
- export function CategoryPage({ storeConfig: initialConfig, categorySlug }) {
13
+ import { CategoryDescription } from '../../../components/rich-text/CategoryDescription';
14
+ import { RichTextExcerpt } from '../../../components/rich-text/RichTextExcerpt';
15
+ export function CategoryPage({ storeConfig: initialConfig, categorySlug, categoryProductsSeed }) {
14
16
  const { store, addToCart } = useStore();
15
17
  const storeConfig = store || initialConfig;
16
18
  const categories = storeConfig.categories || [];
17
19
  const category = categories.find(c => c.slug === categorySlug);
18
- const { products, isLoading, hasMore, loadMore } = useCategoryProducts(storeConfig.id, category?.id);
20
+ const { products, isLoading, hasMore, loadMore } = useCategoryProducts(storeConfig.id, category?.id, categoryProductsSeed);
19
21
  const menuItems = products.map((product) => ({
20
22
  id: product.id,
21
23
  name: product.name,
@@ -63,5 +65,5 @@ export function CategoryPage({ storeConfig: initialConfig, categorySlug }) {
63
65
  const isDarkTheme = storeConfig.type === 'food-modern' || storeConfig.branding.theme === 'dark';
64
66
  const bgColor = isDarkTheme ? 'bg-[#0F0F0F]' : 'bg-gray-50';
65
67
  const textColor = isDarkTheme ? 'text-white' : 'text-gray-900';
66
- return (_jsxs("div", { className: `min-h-screen ${bgColor} ${textColor} transition-colors duration-300`, children: [_jsxs("div", { className: "relative h-[40vh] overflow-hidden", children: [_jsx(ImageWithFallback, { src: category.image, alt: category.name, className: "w-full h-full object-cover", skeletonAspectRatio: "16/9" }), _jsx("div", { className: `absolute inset-0 ${isDarkTheme ? 'bg-black/60' : 'bg-black/40'} backdrop-blur-[2px]` }), _jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-center p-6 text-white", children: [_jsx("h1", { className: "text-5xl md:text-7xl font-bold tracking-tight mb-4", children: category.name }), category.description && (_jsx("p", { className: "text-lg md:text-xl max-w-2xl opacity-90 font-light", children: category.description }))] })] }), _jsxs("div", { className: "container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-12", children: [_jsxs("div", { className: "flex flex-col md:flex-row justify-between items-center mb-10 gap-4", children: [_jsxs(Link, { href: `/${storeConfig.slug}/categories`, className: `inline-flex items-center text-sm font-medium ${isDarkTheme ? 'text-gray-400 hover:text-white' : 'text-gray-600 hover:text-gray-900'}`, children: [_jsx(ArrowLeft, { className: "h-4 w-4 mr-2" }), "Back to All Categories"] }), _jsx("div", { className: "flex items-center gap-4", children: _jsxs(Button, { variant: "outline", className: `${isDarkTheme ? 'border-white/20 text-white hover:bg-white/10' : 'bg-white'}`, children: [_jsx(Filter, { className: "h-4 w-4 mr-2" }), " Filter"] }) })] }), !hasItems && !isLoading ? (_jsxs("div", { className: "text-center py-20 border border-dashed border-gray-300 rounded-3xl", children: [_jsx("p", { className: "text-gray-500 text-lg", children: "No items found in this category." }), _jsx(Button, { className: "mt-4", onClick: () => window.history.back(), children: "Go Back" })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "space-y-12", children: _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8", children: menuItems.map((item) => (_jsxs("div", { className: `group bg-white rounded-3xl overflow-hidden shadow-sm hover:shadow-xl transition-all duration-500 flex flex-col h-full border ${isDarkTheme ? 'border-white/10' : 'border-gray-100'}`, children: [_jsxs("div", { className: "relative aspect-square overflow-hidden", children: [_jsx(ImageWithFallback, { src: item.image, alt: item.name, className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-110", skeletonAspectRatio: "square" }), _jsx("div", { className: "absolute inset-0 bg-black/20 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center", children: _jsx(Button, { className: "rounded-full bg-white text-black hover:bg-gray-100 transform translate-y-4 group-hover:translate-y-0 transition-all duration-300 shadow-lg font-bold px-8", onClick: () => handleAddToCart(item), children: "Add to Order" }) })] }), _jsxs("div", { className: "p-6 flex flex-col flex-1", children: [_jsxs("div", { className: "flex justify-between items-start mb-2", children: [_jsx("h3", { className: "font-bold text-lg text-gray-900 leading-tight group-hover:text-orange-600 transition-colors", children: item.name }), _jsx("span", { className: "font-black text-lg text-gray-900 whitespace-nowrap ml-2", children: formatCurrency(item.price, storeConfig.settings?.currency || 'USD') })] }), _jsx("p", { className: "text-gray-500 text-sm mb-4 line-clamp-2 leading-relaxed flex-1", children: item.description })] })] }, item.id))) }) }), hasMore && (_jsx("div", { className: "mt-10 flex justify-center", children: _jsx(Button, { onClick: loadMore, disabled: isLoading, children: "Load more" }) }))] }))] })] }));
68
+ return (_jsxs("div", { className: `min-h-screen ${bgColor} ${textColor} transition-colors duration-300`, children: [_jsxs("div", { className: "relative h-[40vh] overflow-hidden", children: [_jsx(ImageWithFallback, { src: category.image, alt: category.name, className: "w-full h-full object-cover", skeletonAspectRatio: "16/9" }), _jsx("div", { className: `absolute inset-0 ${isDarkTheme ? 'bg-black/60' : 'bg-black/40'} backdrop-blur-[2px]` }), _jsxs("div", { className: "absolute inset-0 flex flex-col items-center justify-center text-center p-6 text-white", children: [_jsx("h1", { className: "text-5xl md:text-7xl font-bold tracking-tight mb-4", children: category.name }), _jsx(CategoryDescription, { description: category.description })] })] }), _jsxs("div", { className: "container mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-12", children: [_jsxs("div", { className: "flex flex-col md:flex-row justify-between items-center mb-10 gap-4", children: [_jsxs(Link, { href: `/${storeConfig.slug}/categories`, className: `inline-flex items-center text-sm font-medium ${isDarkTheme ? 'text-gray-400 hover:text-white' : 'text-gray-600 hover:text-gray-900'}`, children: [_jsx(ArrowLeft, { className: "h-4 w-4 mr-2" }), "Back to All Categories"] }), _jsx("div", { className: "flex items-center gap-4", children: _jsxs(Button, { variant: "outline", className: `${isDarkTheme ? 'border-white/20 text-white hover:bg-white/10' : 'bg-white'}`, children: [_jsx(Filter, { className: "h-4 w-4 mr-2" }), " Filter"] }) })] }), !hasItems && !isLoading ? (_jsxs("div", { className: "text-center py-20 border border-dashed border-gray-300 rounded-3xl", children: [_jsx("p", { className: "text-gray-500 text-lg", children: "No items found in this category." }), _jsx(Button, { className: "mt-4", onClick: () => window.history.back(), children: "Go Back" })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "space-y-12", children: _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8", children: menuItems.map((item) => (_jsxs("div", { className: `group bg-white rounded-3xl overflow-hidden shadow-sm hover:shadow-xl transition-all duration-500 flex flex-col h-full border ${isDarkTheme ? 'border-white/10' : 'border-gray-100'}`, children: [_jsxs("div", { className: "relative aspect-square overflow-hidden", children: [_jsx(ImageWithFallback, { src: item.image, alt: item.name, className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-110", skeletonAspectRatio: "square" }), _jsx("div", { className: "absolute inset-0 bg-black/20 opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-center justify-center", children: _jsx(Button, { className: "rounded-full bg-white text-black hover:bg-gray-100 transform translate-y-4 group-hover:translate-y-0 transition-all duration-300 shadow-lg font-bold px-8", onClick: () => handleAddToCart(item), children: "Add to Order" }) })] }), _jsxs("div", { className: "p-6 flex flex-col flex-1", children: [_jsxs("div", { className: "flex justify-between items-start mb-2", children: [_jsx("h3", { className: "font-bold text-lg text-gray-900 leading-tight group-hover:text-orange-600 transition-colors", children: item.name }), _jsx("span", { className: "font-black text-lg text-gray-900 whitespace-nowrap ml-2", children: formatCurrency(item.price, storeConfig.settings?.currency || 'USD') })] }), _jsx(RichTextExcerpt, { value: item.description, as: "p", className: "text-gray-500 text-sm mb-4 line-clamp-2 leading-relaxed flex-1" })] })] }, item.id))) }) }), hasMore && (_jsx("div", { className: "mt-10 flex justify-center", children: _jsx(Button, { onClick: loadMore, disabled: isLoading, children: "Load more" }) }))] }))] })] }));
67
69
  }
@@ -133,7 +133,7 @@ export function MenuPage({ storeConfig: initialConfig, categorySlug }) {
133
133
  ? "text-white border-transparent shadow-md transform scale-105"
134
134
  : "bg-white text-gray-600 border-gray-200 hover:bg-gray-100 hover:border-gray-300"), style: !selectedCategory ? { backgroundColor: primaryColor } : {}, children: "All Items" }), categories.map((category) => (_jsx("button", { onClick: () => setSelectedCategory(category.slug), className: cn("px-4 py-2 rounded-full text-sm font-bold whitespace-nowrap transition-all border flex-shrink-0 select-none", selectedCategory === category.slug
135
135
  ? "text-white border-transparent shadow-md transform scale-105"
136
- : "bg-white text-gray-600 border-gray-200 hover:bg-gray-100 hover:border-gray-300"), style: selectedCategory === category.slug ? { backgroundColor: primaryColor } : {}, children: category.name }, category.id)))] })] })] }) }) }), _jsxs("div", { className: "container mx-auto px-4 sm:px-6 lg:px-8 py-12", children: [selectedCategory && (_jsx("div", { className: "mb-8 animate-fade-in", children: _jsxs("h2", { className: "text-2xl font-bold text-gray-900 capitalize flex items-center gap-3", children: [categories.find(c => c.slug === selectedCategory)?.name || 'Category', _jsxs("span", { className: "text-sm font-normal text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full", children: [filteredItems.length, " items"] })] }) })), _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8", children: filteredItems.map((item, index) => (_jsxs(Card, { className: "group overflow-hidden hover:shadow-xl transition-all duration-300 border-gray-100 flex flex-col h-full bg-white rounded-2xl", children: [_jsxs("div", { className: "relative aspect-[4/3] overflow-hidden", children: [_jsx(ImageWithFallback, { src: item.image, alt: item.name, className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-110", skeletonAspectRatio: "4/3" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-end justify-center pb-6", children: _jsx(Button, { className: "rounded-full font-bold shadow-lg transform translate-y-4 group-hover:translate-y-0 transition-transform duration-300", style: { backgroundColor: primaryColor, color: 'white' }, children: "Quick Add" }) }), index % 3 === 0 && (_jsxs("div", { className: "absolute top-3 right-3 bg-white/90 backdrop-blur text-gray-900 text-[10px] font-bold px-2 py-1 rounded-full shadow-sm flex items-center gap-1", children: [_jsx(Star, { className: "w-3 h-3 fill-yellow-400 text-yellow-400" }), " Popular"] }))] }), _jsxs(CardContent, { className: "p-6 flex-1 flex flex-col", children: [_jsxs("div", { className: "flex justify-between items-start mb-2", children: [_jsx("h3", { className: "font-bold text-lg text-gray-900 leading-tight", children: item.name }), _jsx("span", { className: "font-black text-lg text-gray-900 whitespace-nowrap ml-2", children: formatCurrency(item.price, item.currency || storeConfig.settings?.currency || 'USD') })] }), _jsx("p", { className: "text-gray-500 text-sm mb-4 line-clamp-2 leading-relaxed flex-1", children: item.description }), item.dietaryInfo && item.dietaryInfo.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mb-6", children: item.dietaryInfo.map((info) => {
136
+ : "bg-white text-gray-600 border-gray-200 hover:bg-gray-100 hover:border-gray-300"), style: selectedCategory === category.slug ? { backgroundColor: primaryColor } : {}, children: category.name }, category.id)))] })] })] }) }) }), _jsxs("div", { className: "container mx-auto px-4 sm:px-6 lg:px-8 py-12", children: [selectedCategory && (_jsx("div", { className: "mb-8 animate-fade-in", children: _jsxs("h2", { className: "text-2xl font-bold text-gray-900 capitalize flex items-center gap-3", children: [categories.find(c => c.slug === selectedCategory)?.name || 'Category', _jsxs("span", { className: "text-sm font-normal text-gray-500 bg-gray-100 px-2 py-0.5 rounded-full", children: [filteredItems.length, " items"] })] }) })), _jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-8", children: filteredItems.map((item, index) => (_jsxs(Card, { className: "group overflow-hidden hover:shadow-xl transition-all duration-300 border-gray-100 flex flex-col h-full bg-white rounded-2xl", children: [_jsxs("div", { className: "relative aspect-[4/3] overflow-hidden", children: [_jsx(ImageWithFallback, { src: item.image, alt: item.name, className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-110", skeletonAspectRatio: "4/3" }), _jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-300 flex items-end justify-center pb-6", children: _jsx(Button, { className: "rounded-full font-bold shadow-lg transform translate-y-4 group-hover:translate-y-0 transition-transform duration-300", style: { backgroundColor: primaryColor, color: 'white' }, children: "Quick Add" }) }), index % 3 === 0 && (_jsxs("div", { className: "absolute top-3 right-3 bg-white/90 backdrop-blur text-gray-900 text-[10px] font-bold px-2 py-1 rounded-full shadow-sm flex items-center gap-1", children: [_jsx(Star, { className: "w-3 h-3 fill-yellow-400 text-yellow-400" }), " Popular"] }))] }), _jsxs(CardContent, { className: "p-6 flex-1 flex flex-col", children: [_jsxs("div", { className: "flex justify-between items-start mb-2", children: [_jsx("h3", { className: "font-bold text-lg text-gray-900 leading-tight", children: item.name }), _jsx("span", { className: "font-black text-lg text-gray-900 whitespace-nowrap ml-2", children: formatCurrency(item.price, item.currency || storeConfig.settings?.currency || 'USD') })] }), _jsx(RichTextExcerpt, { value: item.description, as: "p", className: "text-gray-500 text-sm mb-4 line-clamp-2 leading-relaxed flex-1" }), item.dietaryInfo && item.dietaryInfo.length > 0 && (_jsx("div", { className: "flex flex-wrap gap-2 mb-6", children: item.dietaryInfo.map((info) => {
137
137
  const Icon = dietaryIcons[info.toLowerCase()] || Info;
138
138
  return (_jsxs("span", { className: "inline-flex items-center gap-1 text-[10px] uppercase font-bold px-2 py-1 rounded bg-gray-50 text-gray-500 border border-gray-100", children: [_jsx(Icon, { className: "w-3 h-3" }), info] }, info));
139
139
  }) })), _jsxs(Button, { className: "w-full rounded-xl font-bold h-11 shadow-sm hover:shadow-md transition-all active:scale-[0.98]", style: {
@@ -1 +1 @@
1
- {"version":3,"file":"ProductDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/pages/ProductDetailPage.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAA8C,MAAM,mBAAmB,CAAC;AA6B5F,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,+BAqkCpG"}
1
+ {"version":3,"file":"ProductDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/pages/ProductDetailPage.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAA8C,MAAM,mBAAmB,CAAC;AA8B5F,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,+BAqkCpG"}
@@ -18,6 +18,7 @@ import { getGuestUserInfo, saveGuestUserInfo } from '../../../lib/guest-user.js'
18
18
  import { ProductCard } from '../../../components/ui/product-card.js';
19
19
  import Image from 'next/image';
20
20
  import { ImageWithFallback } from '../../../components/ui/image-with-fallback.js';
21
+ import { SafeRichHtml } from '../../../components/rich-text/SafeRichHtml.js';
21
22
  import { ButtonLoader } from '../../../components/ui/page-loader.js';
22
23
  import { extractImageUrls } from '../../../lib/store-config-utils.js';
23
24
  import { OutOfStockOverlay } from '../../../components/ui/out-of-stock-overlay.js';
@@ -541,5 +542,5 @@ export function ProductDetailPage({ storeConfig: initialConfig, productSlug }) {
541
542
  : 'bg-white text-gray-700 border-gray-200 hover:border-gray-300 hover:bg-gray-50'}`, children: variant.value }, variant.id));
542
543
  }) })] })), _jsxs("div", { className: "flex flex-col gap-4 mb-8", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: "Quantity" }), _jsxs("div", { className: "flex items-center border border-gray-300 rounded-lg", children: [_jsx("button", { className: "p-3 text-gray-600 hover:bg-gray-100 rounded-l-lg disabled:opacity-50", onClick: () => setQuantity(Math.max(1, quantity - 1)), disabled: quantity <= 1, children: _jsx(Minus, { className: "h-4 w-4" }) }), _jsx("span", { className: "w-12 text-center font-semibold text-gray-900", children: quantity }), _jsx("button", { className: "p-3 text-gray-600 hover:bg-gray-100 rounded-r-lg", onClick: () => setQuantity(quantity + 1), children: _jsx(Plus, { className: "h-4 w-4" }) })] })] }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-3 mt-2", children: [_jsx(Button, { "data-add-to-cart": true, size: "lg", onClick: handleAddToCart, disabled: isCartLoading || isOutOfStock, className: "flex-1 bg-white border-2 border-gray-900 text-gray-900 hover:bg-gray-50 rounded-full h-14 text-base font-bold shadow-sm transition-all disabled:opacity-50 disabled:cursor-not-allowed", children: isCartLoading ? (_jsxs(_Fragment, { children: [_jsx(ButtonLoader, { className: "mr-2" }), "Adding..."] })) : (_jsxs(_Fragment, { children: [_jsx(ShoppingCart, { className: "h-5 w-5 mr-2" }), "Add to Cart"] })) }), _jsx(Button, { size: "lg", onClick: handleBuyNow, disabled: isOutOfStock || isBuyNowLoading || isCartLoading, className: "flex-1 bg-gray-900 hover:bg-gray-800 text-white rounded-full h-14 text-base font-bold shadow-lg hover:shadow-xl transition-all disabled:opacity-50 disabled:cursor-not-allowed", children: isBuyNowLoading || isCartLoading ? (_jsxs(_Fragment, { children: [_jsx(ButtonLoader, { className: "mr-2" }), "Adding..."] })) : ('Buy Now') }), storeConfig.features.wishlist && (_jsx(Button, { variant: "outline", size: "lg", onClick: handleWishlistClick, disabled: isWishlistLoading || !product, className: cn("h-14 w-14 rounded-full border-2 transition-all disabled:opacity-50 disabled:cursor-not-allowed", product && isInWishlist(product.id)
543
544
  ? "border-red-500 bg-red-50 text-red-500 hover:bg-red-100"
544
- : "border-gray-200 hover:border-gray-300 hover:bg-gray-50"), children: isWishlistLoading ? (_jsx(ButtonLoader, { className: "h-5 w-5" })) : (_jsx(Heart, { className: cn("h-5 w-5", product && isInWishlist(product.id) && "fill-current") })) }))] })] }), _jsx(ProductDeliveryInfoSection, { storeConfig: storeConfig, currency: storeConfig.settings?.currency || 'USD', productCurrency: product.currency, productPrice: product.price, quantity: quantity, shippingAddress: shippingAddress, updateShippingAddress: (patch) => setShippingAddress((prev) => ({ ...prev, ...patch })), shippingMethods: shippingMethods, isCalculatingShipping: isCalculatingShipping, shippingError: shippingError, freeShippingEligible: freeShippingEligible, freeShippingThreshold: freeShippingThreshold, onToast: addToast }), product.description && (_jsxs("div", { className: "mb-8", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-3", children: "Description" }), _jsxs("div", { className: "prose prose-sm max-w-none text-gray-600 leading-relaxed", children: [_jsx("p", { children: product.description }), _jsxs("ul", { className: "list-disc pl-5 space-y-1 mt-2", children: [_jsx("li", { children: "Premium quality material" }), _jsx("li", { children: "Comfortable fit for all-day wear" }), _jsx("li", { children: "Durable stitching and finish" })] })] })] })), product.specifications && Object.keys(product.specifications).length > 0 && (_jsxs("div", { className: "mb-8", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-4", children: "Specifications" }), _jsx("dl", { className: "grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-4", children: Object.entries(product.specifications).map(([key, value]) => (_jsxs("div", { className: "flex flex-col p-3 bg-gray-50 rounded-lg", children: [_jsx("dt", { className: "text-xs text-gray-500 font-medium uppercase tracking-wider mb-1", children: key }), _jsx("dd", { className: "text-sm font-bold text-gray-900", children: value })] }, key))) })] }))] })] }), _jsx("div", { className: "mt-20 pt-16 border-t border-gray-200", children: _jsxs("div", { className: "max-w-4xl", children: [_jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-6 mb-10", children: [_jsxs("div", { className: "flex-1", children: [_jsx("h2", { className: "text-2xl lg:text-3xl font-bold text-gray-900 mb-4", children: "Customer Reviews" }), product.reviewCount && product.reviewCount > 0 && product.rating && product.rating > 0 ? (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StarRating, { rating: typeof product.rating === 'number' ? product.rating : Number(product.rating) || 0, size: "lg" }), _jsx("span", { className: "text-2xl font-bold text-gray-900", children: Number(product.rating).toFixed(1) }), _jsx("span", { className: "text-lg text-gray-500", children: "out of 5" })] }), _jsx("span", { className: "text-gray-300", children: "|" }), _jsxs("span", { className: "text-lg text-gray-600", children: [product.reviewCount, " ", product.reviewCount === 1 ? 'review' : 'reviews'] })] })) : (_jsx("div", { className: "text-gray-500", children: _jsx("p", { className: "text-base", children: "Be the first to review this product" }) }))] }), _jsx(Button, { onClick: () => setIsReviewModalOpen(true), className: "rounded-full shrink-0 bg-gray-900 hover:bg-gray-800 text-white", children: product.reviewCount && product.reviewCount > 0 ? 'Write a Review' : 'Be the First to Review' })] }), ratingDistribution.some(r => r.count > 0) && (_jsxs("div", { className: "mb-10 p-6 bg-gray-50 rounded-xl border border-gray-100", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-5", children: "Rating Breakdown" }), _jsx("div", { className: "space-y-3", children: ratingDistribution.map(({ rating, count, percentage }) => (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-1.5 w-20", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: rating }), _jsx(Star, { className: "h-4 w-4 fill-gray-900 text-gray-900" })] }), _jsx("div", { className: "flex-1 h-2.5 bg-gray-200 rounded-full overflow-hidden", children: _jsx("div", { className: "h-full bg-gradient-to-r from-gray-700 to-gray-900 rounded-full transition-all duration-500", style: { width: `${percentage}%` } }) }), _jsx("span", { className: "text-sm font-medium text-gray-700 w-12 text-right", children: count })] }, rating))) })] })), reviews.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "space-y-6", children: displayedReviews.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) }), hasMoreReviews && !showAllReviews && (_jsx("div", { className: "mt-8 text-center", children: _jsxs(Button, { variant: "outline", onClick: () => setShowAllReviews(true), className: "px-8 rounded-full h-12 border-gray-300", children: ["Show All ", reviews.length, " Reviews"] }) }))] })) : (_jsxs("div", { className: "text-center py-12 bg-gray-50 rounded-xl border border-dashed border-gray-300", children: [_jsx("div", { className: "inline-flex items-center justify-center w-12 h-12 rounded-full bg-white shadow-sm mb-4", children: _jsx(Star, { className: "h-6 w-6 text-gray-400" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "No Reviews Yet" }), _jsx("p", { className: "text-gray-500 max-w-sm mx-auto mb-6", children: "Be the first to review this product and help other customers make informed decisions." }), _jsx(Button, { onClick: () => setIsReviewModalOpen(true), className: "bg-gray-900 hover:bg-gray-800 text-white", children: "Write the First Review" })] }))] }) }), relatedProducts.length > 0 && (_jsxs("div", { className: "mt-20 pt-16 border-t border-gray-200", children: [_jsx("h2", { className: "text-2xl lg:text-3xl font-bold text-gray-900 mb-8", children: "You Might Also Like" }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6", children: relatedProducts.map((relatedProduct) => (_jsx("div", { className: "h-[400px]", children: _jsx(ProductCard, { product: relatedProduct, storeSlug: storeConfig.slug, onAddToCart: (p) => addToCart(p, 1), onQuickView: handleQuickView, className: "h-full" }) }, relatedProduct.id))) })] }))] }) }), _jsx(Modal, { isOpen: isReviewModalOpen, onClose: () => setIsReviewModalOpen(false), title: "Write a Review", children: _jsxs("form", { onSubmit: handleSubmitReview, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Rating" }), _jsxs("div", { className: "flex items-center gap-1", children: [[1, 2, 3, 4, 5].map((star) => (_jsxs("div", { className: "relative group", children: [_jsx("button", { type: "button", onClick: () => setNewReview({ ...newReview, rating: star - 0.5 }), className: "absolute top-0 left-0 w-1/2 h-full z-20 focus:outline-none", title: `${star - 0.5} stars` }), _jsx("button", { type: "button", onClick: () => setNewReview({ ...newReview, rating: star }), className: "absolute top-0 right-0 w-1/2 h-full z-20 focus:outline-none", title: `${star} stars` }), _jsxs("div", { className: "relative pointer-events-none transition-transform group-hover:scale-110", children: [_jsx(Star, { className: "h-8 w-8 text-gray-200 fill-gray-200" }), newReview.rating >= star - 0.5 && (_jsx("div", { className: "absolute inset-0 overflow-hidden", style: { width: newReview.rating === star - 0.5 ? '50%' : '100%' }, children: _jsx(Star, { className: "h-8 w-8 text-gray-900 fill-gray-900" }) }))] })] }, star))), _jsx("span", { className: "ml-3 text-lg font-medium text-gray-900 w-12", children: newReview.rating })] })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "title", className: "block text-sm font-medium text-gray-700 mb-1", children: "Review Title" }), _jsx("input", { type: "text", id: "title", required: true, className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-black", placeholder: "Summarize your thoughts", value: newReview.title, onChange: (e) => setNewReview({ ...newReview, title: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "comment", className: "block text-sm font-medium text-gray-700 mb-1", children: "Review" }), _jsx("textarea", { id: "comment", required: true, rows: 4, className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-black", placeholder: "What did you like or dislike?", value: newReview.comment, onChange: (e) => setNewReview({ ...newReview, comment: e.target.value }) })] }), _jsxs("div", { className: "pt-4 flex justify-end gap-3", children: [_jsx(Button, { type: "button", variant: "outline", onClick: () => setIsReviewModalOpen(false), children: "Cancel" }), _jsx(Button, { type: "submit", className: "bg-black text-white hover:bg-gray-800", children: "Submit Review" })] })] }) }), _jsx(GuestCheckoutModal, { isOpen: showGuestModal, onClose: () => setShowGuestModal(false), onSubmit: handleGuestInfoSubmit, initialData: getGuestUserInfo() || undefined })] }));
545
+ : "border-gray-200 hover:border-gray-300 hover:bg-gray-50"), children: isWishlistLoading ? (_jsx(ButtonLoader, { className: "h-5 w-5" })) : (_jsx(Heart, { className: cn("h-5 w-5", product && isInWishlist(product.id) && "fill-current") })) }))] })] }), _jsx(ProductDeliveryInfoSection, { storeConfig: storeConfig, currency: storeConfig.settings?.currency || 'USD', productCurrency: product.currency, productPrice: product.price, quantity: quantity, shippingAddress: shippingAddress, updateShippingAddress: (patch) => setShippingAddress((prev) => ({ ...prev, ...patch })), shippingMethods: shippingMethods, isCalculatingShipping: isCalculatingShipping, shippingError: shippingError, freeShippingEligible: freeShippingEligible, freeShippingThreshold: freeShippingThreshold, onToast: addToast }), product.description && (_jsxs("div", { className: "mb-8", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-3", children: "Description" }), _jsxs("div", { className: "prose prose-sm max-w-none text-gray-600 leading-relaxed", children: [_jsx(SafeRichHtml, { value: product.description, fallbackPlain: "", as: "div" }), _jsxs("ul", { className: "list-disc pl-5 space-y-1 mt-2", children: [_jsx("li", { children: "Premium quality material" }), _jsx("li", { children: "Comfortable fit for all-day wear" }), _jsx("li", { children: "Durable stitching and finish" })] })] })] })), product.specifications && Object.keys(product.specifications).length > 0 && (_jsxs("div", { className: "mb-8", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900 mb-4", children: "Specifications" }), _jsx("dl", { className: "grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-4", children: Object.entries(product.specifications).map(([key, value]) => (_jsxs("div", { className: "flex flex-col p-3 bg-gray-50 rounded-lg", children: [_jsx("dt", { className: "text-xs text-gray-500 font-medium uppercase tracking-wider mb-1", children: key }), _jsx("dd", { className: "text-sm font-bold text-gray-900", children: value })] }, key))) })] }))] })] }), _jsx("div", { className: "mt-20 pt-16 border-t border-gray-200", children: _jsxs("div", { className: "max-w-4xl", children: [_jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-6 mb-10", children: [_jsxs("div", { className: "flex-1", children: [_jsx("h2", { className: "text-2xl lg:text-3xl font-bold text-gray-900 mb-4", children: "Customer Reviews" }), product.reviewCount && product.reviewCount > 0 && product.rating && product.rating > 0 ? (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(StarRating, { rating: typeof product.rating === 'number' ? product.rating : Number(product.rating) || 0, size: "lg" }), _jsx("span", { className: "text-2xl font-bold text-gray-900", children: Number(product.rating).toFixed(1) }), _jsx("span", { className: "text-lg text-gray-500", children: "out of 5" })] }), _jsx("span", { className: "text-gray-300", children: "|" }), _jsxs("span", { className: "text-lg text-gray-600", children: [product.reviewCount, " ", product.reviewCount === 1 ? 'review' : 'reviews'] })] })) : (_jsx("div", { className: "text-gray-500", children: _jsx("p", { className: "text-base", children: "Be the first to review this product" }) }))] }), _jsx(Button, { onClick: () => setIsReviewModalOpen(true), className: "rounded-full shrink-0 bg-gray-900 hover:bg-gray-800 text-white", children: product.reviewCount && product.reviewCount > 0 ? 'Write a Review' : 'Be the First to Review' })] }), ratingDistribution.some(r => r.count > 0) && (_jsxs("div", { className: "mb-10 p-6 bg-gray-50 rounded-xl border border-gray-100", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 mb-5", children: "Rating Breakdown" }), _jsx("div", { className: "space-y-3", children: ratingDistribution.map(({ rating, count, percentage }) => (_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "flex items-center gap-1.5 w-20", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: rating }), _jsx(Star, { className: "h-4 w-4 fill-gray-900 text-gray-900" })] }), _jsx("div", { className: "flex-1 h-2.5 bg-gray-200 rounded-full overflow-hidden", children: _jsx("div", { className: "h-full bg-gradient-to-r from-gray-700 to-gray-900 rounded-full transition-all duration-500", style: { width: `${percentage}%` } }) }), _jsx("span", { className: "text-sm font-medium text-gray-700 w-12 text-right", children: count })] }, rating))) })] })), reviews.length > 0 ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "space-y-6", children: displayedReviews.map((review) => (_jsx(ReviewCard, { review: review }, review.id))) }), hasMoreReviews && !showAllReviews && (_jsx("div", { className: "mt-8 text-center", children: _jsxs(Button, { variant: "outline", onClick: () => setShowAllReviews(true), className: "px-8 rounded-full h-12 border-gray-300", children: ["Show All ", reviews.length, " Reviews"] }) }))] })) : (_jsxs("div", { className: "text-center py-12 bg-gray-50 rounded-xl border border-dashed border-gray-300", children: [_jsx("div", { className: "inline-flex items-center justify-center w-12 h-12 rounded-full bg-white shadow-sm mb-4", children: _jsx(Star, { className: "h-6 w-6 text-gray-400" }) }), _jsx("h3", { className: "text-lg font-semibold text-gray-900 mb-2", children: "No Reviews Yet" }), _jsx("p", { className: "text-gray-500 max-w-sm mx-auto mb-6", children: "Be the first to review this product and help other customers make informed decisions." }), _jsx(Button, { onClick: () => setIsReviewModalOpen(true), className: "bg-gray-900 hover:bg-gray-800 text-white", children: "Write the First Review" })] }))] }) }), relatedProducts.length > 0 && (_jsxs("div", { className: "mt-20 pt-16 border-t border-gray-200", children: [_jsx("h2", { className: "text-2xl lg:text-3xl font-bold text-gray-900 mb-8", children: "You Might Also Like" }), _jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6", children: relatedProducts.map((relatedProduct) => (_jsx("div", { className: "h-[400px]", children: _jsx(ProductCard, { product: relatedProduct, storeSlug: storeConfig.slug, onAddToCart: (p) => addToCart(p, 1), onQuickView: handleQuickView, className: "h-full" }) }, relatedProduct.id))) })] }))] }) }), _jsx(Modal, { isOpen: isReviewModalOpen, onClose: () => setIsReviewModalOpen(false), title: "Write a Review", children: _jsxs("form", { onSubmit: handleSubmitReview, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Rating" }), _jsxs("div", { className: "flex items-center gap-1", children: [[1, 2, 3, 4, 5].map((star) => (_jsxs("div", { className: "relative group", children: [_jsx("button", { type: "button", onClick: () => setNewReview({ ...newReview, rating: star - 0.5 }), className: "absolute top-0 left-0 w-1/2 h-full z-20 focus:outline-none", title: `${star - 0.5} stars` }), _jsx("button", { type: "button", onClick: () => setNewReview({ ...newReview, rating: star }), className: "absolute top-0 right-0 w-1/2 h-full z-20 focus:outline-none", title: `${star} stars` }), _jsxs("div", { className: "relative pointer-events-none transition-transform group-hover:scale-110", children: [_jsx(Star, { className: "h-8 w-8 text-gray-200 fill-gray-200" }), newReview.rating >= star - 0.5 && (_jsx("div", { className: "absolute inset-0 overflow-hidden", style: { width: newReview.rating === star - 0.5 ? '50%' : '100%' }, children: _jsx(Star, { className: "h-8 w-8 text-gray-900 fill-gray-900" }) }))] })] }, star))), _jsx("span", { className: "ml-3 text-lg font-medium text-gray-900 w-12", children: newReview.rating })] })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "title", className: "block text-sm font-medium text-gray-700 mb-1", children: "Review Title" }), _jsx("input", { type: "text", id: "title", required: true, className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-black", placeholder: "Summarize your thoughts", value: newReview.title, onChange: (e) => setNewReview({ ...newReview, title: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "comment", className: "block text-sm font-medium text-gray-700 mb-1", children: "Review" }), _jsx("textarea", { id: "comment", required: true, rows: 4, className: "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-black", placeholder: "What did you like or dislike?", value: newReview.comment, onChange: (e) => setNewReview({ ...newReview, comment: e.target.value }) })] }), _jsxs("div", { className: "pt-4 flex justify-end gap-3", children: [_jsx(Button, { type: "button", variant: "outline", onClick: () => setIsReviewModalOpen(false), children: "Cancel" }), _jsx(Button, { type: "submit", className: "bg-black text-white hover:bg-gray-800", children: "Submit Review" })] })] }) }), _jsx(GuestCheckoutModal, { isOpen: showGuestModal, onClose: () => setShowGuestModal(false), onSubmit: handleGuestInfoSubmit, initialData: getGuestUserInfo() || undefined })] }));
545
546
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/pages/ProductsPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAgB,MAAM,mBAAmB,CAAC;AA0B9D,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;CAC1B;AAomBD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BAMpD"}
1
+ {"version":3,"file":"ProductsPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/food/pages/ProductsPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAgB,MAAM,mBAAmB,CAAC;AAgC9D,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;CAC1B;AA4lBD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BAMpD"}