From d28296e0abb7f848685e3aec1476294f2e904863 Mon Sep 17 00:00:00 2001 From: bender Date: Tue, 3 Mar 2026 05:00:30 +0000 Subject: [PATCH] Update src/components/sections/product/ProductCardFour.tsx --- .../sections/product/ProductCardFour.tsx | 303 +++++------------- 1 file changed, 84 insertions(+), 219 deletions(-) diff --git a/src/components/sections/product/ProductCardFour.tsx b/src/components/sections/product/ProductCardFour.tsx index 303ff14..52b45ab 100644 --- a/src/components/sections/product/ProductCardFour.tsx +++ b/src/components/sections/product/ProductCardFour.tsx @@ -1,238 +1,103 @@ "use client"; -import { memo, useCallback } from "react"; -import { useRouter } from "next/navigation"; -import CardStack from "@/components/cardStack/CardStack"; -import ProductImage from "@/components/shared/ProductImage"; -import { cls, shouldUseInvertedText } from "@/lib/utils"; -import { useTheme } from "@/providers/themeProvider/ThemeProvider"; -import { useProducts } from "@/hooks/useProducts"; -import type { Product } from "@/lib/api/product"; -import type { LucideIcon } from "lucide-react"; -import type { ButtonConfig, GridVariant, CardAnimationType, TitleSegment, ButtonAnimationType } from "@/components/cardStack/types"; -import type { TextboxLayout, InvertedBackground } from "@/providers/themeProvider/config/constants"; +import React from "react"; +import { Heart } from "lucide-react"; -type ProductCardFourGridVariant = Exclude; +export interface ProductCard { + id: string; + name: string; + price: string; + imageSrc: string; + imageAlt?: string; + category?: string; + rating?: number; + reviewCount?: string; + isFavorited?: boolean; +} -type ProductCard = Product & { - variant: string; -}; - -interface ProductCardFourProps { - products?: ProductCard[]; - carouselMode?: "auto" | "buttons"; - gridVariant: ProductCardFourGridVariant; - uniformGridCustomHeightClasses?: string; - animationType: CardAnimationType; - title: string; - titleSegments?: TitleSegment[]; - description: string; - tag?: string; - tagIcon?: LucideIcon; - tagAnimation?: ButtonAnimationType; - buttons?: ButtonConfig[]; - buttonAnimation?: ButtonAnimationType; - textboxLayout: TextboxLayout; - useInvertedBackground: InvertedBackground; - ariaLabel?: string; +export interface ProductCardFourProps { + products: ProductCard[]; + title?: string; + description?: string; + onFavorite?: (productId: string) => void; className?: string; - containerClassName?: string; - cardClassName?: string; - imageClassName?: string; - textBoxTitleClassName?: string; - textBoxTitleImageWrapperClassName?: string; - textBoxTitleImageClassName?: string; - textBoxDescriptionClassName?: string; - cardNameClassName?: string; - cardPriceClassName?: string; - cardVariantClassName?: string; - actionButtonClassName?: string; gridClassName?: string; - carouselClassName?: string; - controlsClassName?: string; - textBoxClassName?: string; - textBoxTagClassName?: string; - textBoxButtonContainerClassName?: string; - textBoxButtonClassName?: string; - textBoxButtonTextClassName?: string; -} - -interface ProductCardItemProps { - product: ProductCard; - shouldUseLightText: boolean; cardClassName?: string; - imageClassName?: string; - cardNameClassName?: string; - cardPriceClassName?: string; - cardVariantClassName?: string; - actionButtonClassName?: string; } -const ProductCardItem = memo(({ - product, - shouldUseLightText, - cardClassName = "", - imageClassName = "", - cardNameClassName = "", - cardPriceClassName = "", - cardVariantClassName = "", - actionButtonClassName = "", -}: ProductCardItemProps) => { +const ProductCardFour = React.forwardRef< + HTMLDivElement, + ProductCardFourProps +>(( + { + products, + title, + description, + onFavorite, + className = "", gridClassName = "", cardClassName = ""}, + ref +) => { return ( -
- +
+ {title &&

{title}

} + {description && ( +

{description}

+ )} +
+ {products.map((product) => ( +
+ {/* Image Container */} +
+ {product.imageSrc && ( + {product.imageAlt + )} + {/* Favorite Button */} + +
-
-
-
-

- {product.name} -

-

- {product.variant} -

+ {/* Product Info */} +
+ {product.category && ( +

+ {product.category} +

+ )} +

{product.name}

+ {product.rating !== undefined && ( +
+ ★ {product.rating} + {product.reviewCount && ( + + ({product.reviewCount}) + + )} +
+ )} +

{product.price}

+
-

- {product.price} -

-
+ ))}
-
+ ); }); -ProductCardItem.displayName = "ProductCardItem"; - -const ProductCardFour = ({ - products: productsProp, - carouselMode = "buttons", - gridVariant, - uniformGridCustomHeightClasses = "min-h-95 2xl:min-h-105", - animationType, - title, - titleSegments, - description, - tag, - tagIcon, - tagAnimation, - buttons, - buttonAnimation, - textboxLayout, - useInvertedBackground, - ariaLabel = "Product section", - className = "", - containerClassName = "", - cardClassName = "", - imageClassName = "", - textBoxTitleClassName = "", - textBoxTitleImageWrapperClassName = "", - textBoxTitleImageClassName = "", - textBoxDescriptionClassName = "", - cardNameClassName = "", - cardPriceClassName = "", - cardVariantClassName = "", - actionButtonClassName = "", - gridClassName = "", - carouselClassName = "", - controlsClassName = "", - textBoxClassName = "", - textBoxTagClassName = "", - textBoxButtonContainerClassName = "", - textBoxButtonClassName = "", - textBoxButtonTextClassName = "", -}: ProductCardFourProps) => { - const theme = useTheme(); - const router = useRouter(); - const { products: fetchedProducts, isLoading } = useProducts(); - const isFromApi = fetchedProducts.length > 0; - const products = (isFromApi ? fetchedProducts : productsProp) as ProductCard[]; - const shouldUseLightText = shouldUseInvertedText(useInvertedBackground, theme.cardStyle); - - const handleProductClick = useCallback((product: ProductCard) => { - if (isFromApi) { - router.push(`/shop/${product.id}`); - } else { - product.onProductClick?.(); - } - }, [isFromApi, router]); - - - if (isLoading && !productsProp) { - return ( -
-

Loading products...

-
- ); - } - - if (!products || products.length === 0) { - return null; - } - - return ( - - {products?.map((product, index) => ( - handleProductClick(product) }} - shouldUseLightText={shouldUseLightText} - cardClassName={cardClassName} - imageClassName={imageClassName} - cardNameClassName={cardNameClassName} - cardPriceClassName={cardPriceClassName} - cardVariantClassName={cardVariantClassName} - actionButtonClassName={actionButtonClassName} - /> - ))} - - ); -}; - ProductCardFour.displayName = "ProductCardFour"; export default ProductCardFour;