Files
reui-blocks/blocks/product-list5.tsx
T

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 };