72 lines
2.8 KiB
TypeScript
72 lines
2.8 KiB
TypeScript
import { Link } from 'react-router-dom'
|
|
import type { Product } from '../types'
|
|
import { getCategoryImage, formatPrice } from '../types'
|
|
import { Heart } from 'lucide-react'
|
|
import { useWishlistStore } from '../store/wishlistStore'
|
|
|
|
interface ProductCardProps {
|
|
product: Product
|
|
}
|
|
|
|
export default function ProductCard({ product }: ProductCardProps) {
|
|
const { addItem, removeItem, isInWishlist } = useWishlistStore()
|
|
const isWished = isInWishlist(product.id)
|
|
|
|
const handleWishlistClick = (e: React.MouseEvent) => {
|
|
e.preventDefault() // prevent navigating to product detail
|
|
if (isWished) {
|
|
removeItem(product.id)
|
|
} else {
|
|
addItem(product)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Link
|
|
to={`/products/${product.id}`}
|
|
className="bg-white shadow-sm border border-spa-stone/10 rounded-2xl overflow-hidden flex flex-col group p-2 transition-all duration-300 hover:shadow-lg hover:border-spa-forest/30"
|
|
>
|
|
<div className="h-48 md:h-64 overflow-hidden rounded-xl relative bg-spa-sage/20">
|
|
<img
|
|
src={product.images?.[0]?.url || getCategoryImage(product.category.name)}
|
|
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-700"
|
|
alt={product.scent.name}
|
|
/>
|
|
{/* Category badge */}
|
|
<div className="absolute top-3 left-3 bg-white/90 backdrop-blur-sm px-2.5 py-1 rounded-md text-[10px] font-bold uppercase tracking-widest text-spa-forest shadow-sm">
|
|
{product.category.name}
|
|
</div>
|
|
{/* Wishlist Button */}
|
|
<button
|
|
onClick={handleWishlistClick}
|
|
className="absolute top-3 right-3 p-2 bg-white/90 backdrop-blur-sm rounded-full shadow-sm hover:scale-110 transition-transform z-10"
|
|
>
|
|
<Heart
|
|
className={`w-4 h-4 transition-colors ${isWished ? 'fill-rose-500 text-rose-500' : 'text-spa-stone/60 hover:text-rose-500'}`}
|
|
/>
|
|
</button>
|
|
</div>
|
|
|
|
<div className="p-4 flex flex-col flex-1">
|
|
<div className="mb-4">
|
|
<h3 className="text-base md:text-lg font-bold text-pop-black leading-tight line-clamp-1 group-hover:text-spa-forest transition-colors">
|
|
{product.scent.name}
|
|
</h3>
|
|
<p className="text-[10px] md:text-xs text-spa-stone/60 mt-1 uppercase tracking-widest line-clamp-1 font-semibold">
|
|
{product.category.name}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="mt-auto flex items-center justify-between">
|
|
<span className="text-rose-500 font-black text-sm md:text-lg">
|
|
{formatPrice(product.variants[0]?.price)}
|
|
</span>
|
|
<span className="text-[10px] md:text-xs font-bold text-spa-forest uppercase tracking-widest flex items-center gap-1 group-hover:translate-x-1 transition-transform">
|
|
View Details →
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
)
|
|
}
|