134 lines
5.0 KiB
TypeScript
134 lines
5.0 KiB
TypeScript
"use client";
|
|
|
|
import Image from "next/image";
|
|
import Link from "next/link";
|
|
import type { Product } from "@/data/home";
|
|
import { productPath } from "@/lib/product-path";
|
|
|
|
const FALLBACK_DESC =
|
|
"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است.";
|
|
|
|
type ProductCardProps = {
|
|
product: Product;
|
|
className?: string;
|
|
};
|
|
|
|
export default function ProductCard({ product, className = "" }: ProductCardProps) {
|
|
const href = product.href ?? productPath(product);
|
|
const hoverSrc = product.imageHover;
|
|
const colors = product.colors ?? [];
|
|
const sizes = product.sizes ?? [];
|
|
const hasVars = colors.length > 0 || sizes.length > 0;
|
|
const description = product.description?.trim() || FALLBACK_DESC;
|
|
|
|
return (
|
|
<article
|
|
dir="rtl"
|
|
className={`group relative flex h-[491px] w-full flex-col rounded-[5px] border border-[#8e8e8e]/30 bg-white transition-colors duration-300 ease-out hover:border-ink ${className}`}
|
|
>
|
|
<Link href={href} className="flex min-h-0 flex-1 flex-col">
|
|
{/* Clip media only — keep border on the outer box so it never gets cut off */}
|
|
<span className="relative block min-h-0 flex-1 overflow-hidden rounded-t-[4px] p-2.5">
|
|
<span className="relative block h-full w-full overflow-hidden rounded-[5px]">
|
|
<Image
|
|
src={product.image}
|
|
alt={product.nameFa}
|
|
fill
|
|
sizes="(max-width: 768px) 50vw, 324px"
|
|
className={`object-cover object-top transition-transform duration-500 ease-out ${
|
|
hoverSrc ? "group-hover:translate-x-full" : "group-hover:scale-[1.04]"
|
|
}`}
|
|
/>
|
|
{hoverSrc ? (
|
|
<Image
|
|
src={hoverSrc}
|
|
alt=""
|
|
fill
|
|
sizes="(max-width: 768px) 50vw, 324px"
|
|
className="object-cover object-top -translate-x-full transition-transform duration-500 ease-out group-hover:translate-x-0"
|
|
aria-hidden
|
|
/>
|
|
) : null}
|
|
</span>
|
|
</span>
|
|
|
|
<span className="flex shrink-0 flex-col gap-1.5 px-3.5 pb-3.5 pt-1">
|
|
<span className="w-full text-right">
|
|
<span className="line-clamp-1 block text-[15px] font-medium text-ink">
|
|
{product.nameFa}
|
|
</span>
|
|
<span
|
|
dir="ltr"
|
|
className="mt-0.5 line-clamp-1 block w-full text-right font-montserrat text-[9px] font-light uppercase tracking-[0.2em] text-[#afafaf]"
|
|
>
|
|
{product.nameEn}
|
|
</span>
|
|
</span>
|
|
|
|
{hasVars ? (
|
|
<span className="flex flex-wrap items-center justify-start gap-2">
|
|
{sizes.length > 0 ? (
|
|
<span className="flex items-center gap-1" aria-label="سایزها" dir="ltr">
|
|
{sizes.slice(0, 5).map((size) => (
|
|
<span
|
|
key={size.id}
|
|
title={size.labelFa}
|
|
className="inline-flex h-5 min-w-5 items-center justify-center rounded-[3px] border border-ink/20 px-1 font-montserrat text-[9px] font-medium uppercase leading-none text-ink"
|
|
>
|
|
{size.labelFa}
|
|
</span>
|
|
))}
|
|
</span>
|
|
) : null}
|
|
{colors.length > 0 ? (
|
|
<span className="flex items-center gap-1" aria-label="رنگهای موجود">
|
|
{colors.slice(0, 6).map((color) => (
|
|
<span
|
|
key={color.id}
|
|
title={color.labelFa}
|
|
className="inline-block size-3.5 shrink-0 rounded-full border border-black/10"
|
|
style={{ background: color.swatch || "#ccc" }}
|
|
/>
|
|
))}
|
|
</span>
|
|
) : null}
|
|
</span>
|
|
) : null}
|
|
|
|
<span
|
|
aria-hidden
|
|
className="mt-0.5 block h-px w-full bg-ink/10 transition-colors duration-300 ease-out group-hover:bg-ink/35"
|
|
/>
|
|
|
|
{/* Vars occupy ~1 line — clamp desc to 1 so the image height stays even */}
|
|
<span
|
|
className={`${
|
|
hasVars ? "line-clamp-1" : "line-clamp-2"
|
|
} text-right text-[11px] font-light leading-relaxed text-[#6e6e6e]`}
|
|
>
|
|
{description}
|
|
</span>
|
|
</span>
|
|
</Link>
|
|
|
|
<button
|
|
type="button"
|
|
aria-label="افزودن به علاقهمندی"
|
|
className="absolute end-3 top-4 z-10 transition-opacity hover:opacity-70"
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}}
|
|
>
|
|
<Image
|
|
src="/images/home/icons/bookmark.svg"
|
|
alt=""
|
|
width={24}
|
|
height={24}
|
|
unoptimized
|
|
/>
|
|
</button>
|
|
</article>
|
|
);
|
|
}
|