179 lines
4.6 KiB
TypeScript
179 lines
4.6 KiB
TypeScript
import { AspectRatio } from "@/components/ui/aspect-ratio";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
interface Product {
|
|
name: string;
|
|
image: {
|
|
src: string;
|
|
alt: string;
|
|
};
|
|
link: string;
|
|
price: ProductPrice;
|
|
collection: string;
|
|
}
|
|
|
|
type ProductCardProps = Product;
|
|
|
|
interface ProductPrice {
|
|
regular: number;
|
|
sale?: number;
|
|
currency: string;
|
|
}
|
|
|
|
type ProductList = Array<Product>;
|
|
|
|
const PRODUCTS_LIST: ProductList = [
|
|
{
|
|
collection: "ساعت طلایی",
|
|
name: "گوشواره بلوم و گلیم",
|
|
link: "#",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Elegant-Floral-Earrings-1.png",
|
|
alt: "گوشواره گلدار ظریف",
|
|
},
|
|
price: {
|
|
regular: 4000000.0,
|
|
currency: "ریال",
|
|
},
|
|
},
|
|
{
|
|
collection: "ساعت طلایی",
|
|
name: "گوشواره درخشش عاشقانه",
|
|
link: "#",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Gold-Heart-Earrings-1.png",
|
|
alt: "گوشواره طلایی قلبی",
|
|
},
|
|
price: {
|
|
regular: 8000000.0,
|
|
sale: 7599000.0,
|
|
currency: "ریال",
|
|
},
|
|
},
|
|
{
|
|
collection: "ساعت طلایی",
|
|
name: "گوشواره زمزمه طلایی",
|
|
link: "#",
|
|
image: {
|
|
src: "/block-media/shadcnblocks/block/ecommerce/accessories/Gold-Hoop-Earrings-on-Ceramic-Dish-1.png",
|
|
alt: "گوشواره حلقهای طلایی",
|
|
},
|
|
price: {
|
|
regular: 6000000.0,
|
|
currency: "ریال",
|
|
},
|
|
},
|
|
];
|
|
|
|
interface ProductList5Props {
|
|
className?: string;
|
|
}
|
|
|
|
const ProductList5 = ({ className }: ProductList5Props) => {
|
|
return (
|
|
<section className={cn("py-32", className)}>
|
|
<div className="container">
|
|
<div className="mb-12 flex flex-col gap-12 md:flex-row md:justify-between">
|
|
<div className="flex flex-col gap-4">
|
|
<p className="text-center leading-tight font-medium text-primary md:text-start">
|
|
جایی که ظرافت، همراه هر روز است.
|
|
</p>
|
|
<h1 className="text-center text-xl font-semibold md:text-start">
|
|
محبوبترینهای مشتریان
|
|
</h1>
|
|
</div>
|
|
<div className="self-end">
|
|
<Button variant="secondary">مشاهده کالکشن</Button>
|
|
</div>
|
|
</div>
|
|
<div className="grid gap-6 sm:grid-cols-2 md:grid-cols-3">
|
|
{PRODUCTS_LIST.map((item, index) => (
|
|
<ProductCard key={`product-list-5-card-${index}`} {...item} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
};
|
|
|
|
const ProductCard = ({
|
|
name,
|
|
link,
|
|
image,
|
|
price,
|
|
collection,
|
|
}: ProductCardProps) => {
|
|
const { regular, sale, currency } = price;
|
|
|
|
return (
|
|
<a href={link} className="block h-full w-full min-w-47.5">
|
|
<Card className="group h-full gap-3.5 rounded-none border-none bg-background p-0 shadow-none">
|
|
<CardHeader className="block p-0">
|
|
<AspectRatio ratio={1} className="w-full overflow-hidden rounded-2xl">
|
|
<img
|
|
src={image.src}
|
|
alt={image.alt}
|
|
className="block size-full object-cover object-center"
|
|
/>
|
|
</AspectRatio>
|
|
</CardHeader>
|
|
<CardContent className="flex h-full flex-col gap-2 p-0">
|
|
<p className="text-xs text-muted-foreground uppercase">
|
|
{collection}
|
|
</p>
|
|
<CardTitle className="leading-tight font-medium">{name}</CardTitle>
|
|
<ProductCardPrice
|
|
regular={regular}
|
|
sale={sale}
|
|
currency={currency}
|
|
/>
|
|
</CardContent>
|
|
</Card>
|
|
</a>
|
|
);
|
|
};
|
|
|
|
const formatCurrency = (
|
|
value: number,
|
|
currency: string = "ریال",
|
|
locale: string = "fa-IR",
|
|
) => {
|
|
return `${value.toLocaleString(locale)} ${currency}`;
|
|
};
|
|
|
|
const ProductCardPrice = ({
|
|
regular,
|
|
sale,
|
|
currency,
|
|
}: {
|
|
regular: number;
|
|
sale?: number;
|
|
currency: string;
|
|
}) => {
|
|
const onSale = sale != null;
|
|
|
|
return (
|
|
<div className="flex flex-wrap items-center gap-x-2 text-lg font-semibold">
|
|
<span
|
|
className={cn(
|
|
"leading-tight",
|
|
onSale
|
|
? "text-muted-foreground line-through"
|
|
: "text-foreground",
|
|
)}
|
|
>
|
|
{formatCurrency(regular, currency)}
|
|
</span>
|
|
{onSale ? (
|
|
<span className="leading-tight text-foreground">
|
|
{formatCurrency(sale, currency)}
|
|
</span>
|
|
) : null}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export { ProductList5 };
|