diff --git a/src/components/ecommerce/productCatalog/ProductCatalog.tsx b/src/components/ecommerce/productCatalog/ProductCatalog.tsx index fc04961..3e4b87a 100644 --- a/src/components/ecommerce/productCatalog/ProductCatalog.tsx +++ b/src/components/ecommerce/productCatalog/ProductCatalog.tsx @@ -1,156 +1,79 @@ "use client"; -import { memo, useMemo, useCallback } from "react"; -import { useRouter } from "next/navigation"; -import Input from "@/components/form/Input"; -import ProductDetailVariantSelect from "@/components/ecommerce/productDetail/ProductDetailVariantSelect"; -import type { ProductVariant } from "@/components/ecommerce/productDetail/ProductDetailCard"; -import { cls } from "@/lib/utils"; -import { useProducts } from "@/hooks/useProducts"; +import React from "react"; import ProductCatalogItem from "./ProductCatalogItem"; -import type { CatalogProduct } from "./ProductCatalogItem"; -interface ProductCatalogProps { - layout: "page" | "section"; - products?: CatalogProduct[]; - searchValue?: string; - onSearchChange?: (value: string) => void; - searchPlaceholder?: string; - filters?: ProductVariant[]; - emptyMessage?: string; - className?: string; - gridClassName?: string; - cardClassName?: string; - imageClassName?: string; - searchClassName?: string; - filterClassName?: string; - toolbarClassName?: string; +export interface CatalogProduct { + id: string; + name: string; + price: string; + imageSrc: string; + imageAlt?: string; + category?: string; + rating?: number; + reviewCount?: string; + onProductClick?: () => void; + onFavorite?: () => void; + isFavorited?: boolean; } -const ProductCatalog = ({ - layout, - products: productsProp, - searchValue = "", - onSearchChange, - searchPlaceholder = "Search products...", - filters, - emptyMessage = "No products found", - className = "", - gridClassName = "", - cardClassName = "", - imageClassName = "", - searchClassName = "", - filterClassName = "", - toolbarClassName = "", -}: ProductCatalogProps) => { - const router = useRouter(); - const { products: fetchedProducts, isLoading } = useProducts(); +export interface ProductCatalogProps { + products: CatalogProduct[]; + title?: string; + description?: string; + className?: string; + containerClassName?: string; + gridClassName?: string; + cardClassName?: string; + onProductClick?: (product: CatalogProduct) => void; + ariaLabel?: string; +} - const handleProductClick = useCallback((productId: string) => { - router.push(`/shop/${productId}`); - }, [router]); - - const products: CatalogProduct[] = useMemo(() => { - if (productsProp && productsProp.length > 0) { - return productsProp; - } - - if (fetchedProducts.length === 0) { - return []; - } - - return fetchedProducts.map((product) => ({ - id: product.id, - name: product.name, - price: product.price, - imageSrc: product.imageSrc, - imageAlt: product.imageAlt || product.name, - rating: product.rating || 0, - reviewCount: product.reviewCount, - category: product.brand, - onProductClick: () => handleProductClick(product.id), - })); - }, [productsProp, fetchedProducts, handleProductClick]); - - if (isLoading && (!productsProp || productsProp.length === 0)) { - return ( - - - Loading products... - - - ); - } +const ProductCatalog = React.forwardRef( + ( + { + products, + title, + description, + className = "", containerClassName = "", gridClassName = "", cardClassName = "", onProductClick, + ariaLabel = "Product catalog"}, + ref + ) => { + const normalizedProducts = Array.isArray(products) + ? products.map((p) => ({ + ...p, + price: typeof p.price === "number" ? p.price.toString() : p.price, + })) + : []; return ( - - {(onSearchChange || (filters && filters.length > 0)) && ( - - {onSearchChange && ( - - )} - {filters && filters.length > 0 && ( - - {filters.map((filter) => ( - - ))} - - )} - - )} - - {products.length === 0 ? ( - - {emptyMessage} - - ) : ( - - {products.map((product) => ( - - ))} - - )} - + + {title && {title}} + {description && ( + {description} + )} + + {normalizedProducts.map((product) => ( + { + product.onProductClick?.(); + onProductClick?.(product); + }} + /> + ))} + + ); -}; + } +); ProductCatalog.displayName = "ProductCatalog"; -export default memo(ProductCatalog); \ No newline at end of file +export default ProductCatalog;
- Loading products... -
- {emptyMessage} -
{description}