Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fb0402b239 | |||
| f1c667b415 |
@@ -111,53 +111,106 @@ const ProductCardItem = memo(({
|
||||
}
|
||||
}, [isFromApi, onBuyClick, product, quantity]);
|
||||
|
||||
const [isFlipped, setIsFlipped] = useState(false);
|
||||
|
||||
return (
|
||||
<article
|
||||
className={cls("card group relative h-full flex flex-col gap-4 cursor-pointer p-4 rounded-theme-capped", cardClassName)}
|
||||
className={cls("card group relative h-full cursor-pointer", cardClassName)}
|
||||
onClick={handleClick}
|
||||
role="article"
|
||||
aria-label={`${product.name} - ${product.price}`}
|
||||
onMouseEnter={() => setIsFlipped(true)}
|
||||
onMouseLeave={() => setIsFlipped(false)}
|
||||
style={{
|
||||
perspective: "1000px",
|
||||
}}
|
||||
>
|
||||
<ProductImage
|
||||
imageSrc={product.imageSrc}
|
||||
imageAlt={product.imageAlt || product.name}
|
||||
isFavorited={product.isFavorited}
|
||||
onFavoriteToggle={product.onFavorite}
|
||||
imageClassName={imageClassName}
|
||||
/>
|
||||
|
||||
<div className="relative z-1 flex flex-col gap-3">
|
||||
<h3 className={cls("text-xl font-medium leading-[1.15] truncate", shouldUseLightText ? "text-background" : "text-foreground", cardNameClassName)}>
|
||||
{product.name}
|
||||
</h3>
|
||||
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className={cls("flex items-center gap-2", quantityControlsClassName)}>
|
||||
<QuantityButton
|
||||
onClick={handleDecrement}
|
||||
ariaLabel="Decrease quantity"
|
||||
Icon={Minus}
|
||||
/>
|
||||
<span className={cls("text-base font-medium min-w-[2ch] text-center leading-[1]", shouldUseLightText ? "text-background" : "text-foreground")}>
|
||||
{quantity}
|
||||
</span>
|
||||
<QuantityButton
|
||||
onClick={handleIncrement}
|
||||
ariaLabel="Increase quantity"
|
||||
Icon={Plus}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
{...getButtonProps(
|
||||
{
|
||||
text: product.price,
|
||||
props: product.priceButtonProps,
|
||||
},
|
||||
0,
|
||||
theme.defaultButtonVariant
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
transition: "transform 0.6s",
|
||||
transformStyle: "preserve-3d",
|
||||
transform: isFlipped ? "rotateY(180deg)" : "rotateY(0deg)",
|
||||
}}
|
||||
>
|
||||
{/* Front of card */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backfaceVisibility: "hidden",
|
||||
}}
|
||||
className={cls("flex flex-col gap-4 p-4 rounded-theme-capped", cardClassName)}
|
||||
>
|
||||
<ProductImage
|
||||
imageSrc={product.imageSrc}
|
||||
imageAlt={product.imageAlt || product.name}
|
||||
isFavorited={product.isFavorited}
|
||||
onFavoriteToggle={product.onFavorite}
|
||||
imageClassName={imageClassName}
|
||||
/>
|
||||
|
||||
<div className="relative z-1 flex flex-col gap-3">
|
||||
<h3 className={cls("text-xl font-medium leading-[1.15] truncate", shouldUseLightText ? "text-background" : "text-foreground", cardNameClassName)}>
|
||||
{product.name}
|
||||
</h3>
|
||||
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className={cls("flex items-center gap-2", quantityControlsClassName)}>
|
||||
<QuantityButton
|
||||
onClick={handleDecrement}
|
||||
ariaLabel="Decrease quantity"
|
||||
Icon={Minus}
|
||||
/>
|
||||
<span className={cls("text-base font-medium min-w-[2ch] text-center leading-[1]", shouldUseLightText ? "text-background" : "text-foreground")}>
|
||||
{quantity}
|
||||
</span>
|
||||
<QuantityButton
|
||||
onClick={handleIncrement}
|
||||
ariaLabel="Increase quantity"
|
||||
Icon={Plus}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
{...getButtonProps(
|
||||
{
|
||||
text: product.price,
|
||||
props: product.priceButtonProps,
|
||||
},
|
||||
0,
|
||||
theme.defaultButtonVariant
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Back of card */}
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
backfaceVisibility: "hidden",
|
||||
transform: "rotateY(180deg)",
|
||||
}}
|
||||
className={cls("flex flex-col gap-4 p-4 rounded-theme-capped justify-center items-center", cardClassName)}
|
||||
>
|
||||
<div className="flex flex-col gap-3 text-center">
|
||||
<h3 className={cls("text-lg font-medium leading-[1.15]", shouldUseLightText ? "text-background" : "text-foreground")}>
|
||||
{product.name}
|
||||
</h3>
|
||||
<p className={cls("text-sm leading-relaxed", shouldUseLightText ? "text-background/80" : "text-foreground/80")}>
|
||||
{product.description || "Premium quality product"}
|
||||
</p>
|
||||
<div className={cls("text-2xl font-bold mt-2", shouldUseLightText ? "text-background" : "text-foreground")}>
|
||||
{product.price}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
Reference in New Issue
Block a user