150 lines
4.3 KiB
TypeScript
150 lines
4.3 KiB
TypeScript
import { AspectRatio } from "@/components/ui/aspect-ratio";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type ProductCategory = {
|
|
title: string;
|
|
image: {
|
|
src: string;
|
|
alt: string;
|
|
};
|
|
summary: string;
|
|
link: string;
|
|
};
|
|
|
|
type ProductCategories2Props = {
|
|
title: string;
|
|
productCategories: ProductCategory[];
|
|
className?: string;
|
|
};
|
|
|
|
const PRODUCT_CATEGORIES = {
|
|
title: "دستهبندی محصولات",
|
|
productCategories: [
|
|
{
|
|
title: "عینک آفتابی",
|
|
summary: "عینکهای مدرن با ترکیب استایل و محافظت در برابر آفتاب",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Checkered-Sunglasses-on-Stone-Pedestal-2.png",
|
|
alt: "عینک آفتابی",
|
|
},
|
|
link: "#",
|
|
},
|
|
{
|
|
title: "جواهرات",
|
|
summary: "قطعات ظریف برای ارتقای هر استایل",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Gold-Hoop-Earrings-on-Ceramic-Dish-2.png",
|
|
alt: "جواهرات",
|
|
},
|
|
link: "#",
|
|
},
|
|
{
|
|
title: "کاپشن و ژاکت",
|
|
summary: "لایهبندی با استایلهای کلاسیک بیرونی",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/clothes/Minimalist-Fashion-Portrait-2.png",
|
|
alt: "کاپشن و ژاکت",
|
|
},
|
|
link: "#",
|
|
},
|
|
{
|
|
title: "کیف",
|
|
summary: "طراحیهای کاربردی برای استفاده روزمره",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/clothes/Woman-with-Tote-Bag-2.png",
|
|
alt: "کیف",
|
|
},
|
|
link: "#",
|
|
},
|
|
{
|
|
title: "کفش",
|
|
summary: "قدم بردارید با راحتی و استایل",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/clothes/Minimalist-Beige-Sneakers-2.png",
|
|
alt: "کفش",
|
|
},
|
|
link: "#",
|
|
},
|
|
{
|
|
title: "لباس",
|
|
summary: "برشهای آسان برای هر مناسبت",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/clothes/pexels-429124762-15555033-2.jpg",
|
|
alt: "لباس",
|
|
},
|
|
link: "#",
|
|
},
|
|
],
|
|
};
|
|
|
|
const ProductCategories2 = ({
|
|
title = PRODUCT_CATEGORIES.title,
|
|
productCategories = PRODUCT_CATEGORIES.productCategories,
|
|
className,
|
|
}: ProductCategories2Props) => {
|
|
return (
|
|
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
|
|
<div className="container">
|
|
<div className="flex flex-col gap-10">
|
|
<h2 className="animate-in text-center text-xl leading-snug font-medium duration-600 fade-in slide-in-from-bottom-6">
|
|
{title}
|
|
</h2>
|
|
<div className="gap grid grid-cols-2 gap-x-2.5 gap-y-10 lg:grid-cols-3">
|
|
{productCategories?.map((item, index) => (
|
|
<div
|
|
key={item.title}
|
|
style={{
|
|
animationDelay: `${100 * index}ms`,
|
|
}}
|
|
className="animate-out opacity-0 duration-700 fade-in-100 fill-mode-forwards"
|
|
>
|
|
<ProductCategoryCard {...item} />
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
const ProductCategoryCard = ({
|
|
title,
|
|
image,
|
|
summary,
|
|
link,
|
|
}: ProductCategory) => {
|
|
return (
|
|
<Card className="rounded-none border-none bg-background p-0 shadow-none">
|
|
<CardContent className="p-0">
|
|
<a href={link} className="flex flex-col gap-4">
|
|
<AspectRatio
|
|
ratio={1.363277259}
|
|
className="overflow-hidden rounded-xl"
|
|
>
|
|
<img
|
|
src={image.src}
|
|
alt={image.alt}
|
|
className="size-full origin-center object-cover object-center transition-transform duration-400 hover:scale-115"
|
|
/>
|
|
</AspectRatio>
|
|
<div className="space-y-1">
|
|
<CardTitle className="text-center text-lg leading-tight font-medium sm:text-xl md:text-xl">
|
|
{title}
|
|
</CardTitle>
|
|
<CardDescription className="text-center">{summary}</CardDescription>
|
|
</div>
|
|
</a>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export { ProductCategories2 };
|