Files
reui-blocks/blocks/product-quick-view8.tsx
T

165 lines
4.7 KiB
TypeScript

"use client";
import { X } from "lucide-react";
import { Price } from "@/components/shadcnblocks/price";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { Button } from "@/components/ui/button";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogTitle,
} from "@/components/ui/dialog";
type Image = {
alt: string;
src: string;
};
interface ProductPrice {
regular: number;
sale?: number;
currency: string;
}
type Product = {
images: Image[];
price: ProductPrice;
name: string;
description: string;
};
type ProductQuickView8Props = Product;
interface ProductImagesProps {
images: Image[];
}
const formatCurrency = (
value: number,
currency: string = "ریال",
locale: string = "fa-IR",
) => {
return `${value.toLocaleString(locale)} ${currency}`;
};
const PRODUCT_DETAILS: Product = {
images: [
{
src: "/block-media/shadcnblocks/block/ecommerce/electronics/turntable/modern-audio-device.png",
alt: "دستگاه صوتی مدرن",
},
{
src: "/block-media/shadcnblocks/block/ecommerce/electronics/turntable/modern-audio-panel.png",
alt: "پنل صوتی مدرن",
},
{
src: "/block-media/shadcnblocks/block/ecommerce/electronics/turntable/elegant-turntable-scene.png",
alt: "صحنه گرامافون شیک",
},
],
price: {
regular: 1299000.0,
currency: "ریال",
},
name: "گرامافون دقیق پرو",
description:
"وینیل را همان‌گونه بشنوید که باید شنیده شود. موتور دایرکت‌درایو دقیق، بازوی صوتی قابل تنظیم و شاسی ضدلرزش برای بازتولید صدایی پاکیزه.",
};
const ProductQuickView8 = ({
images = PRODUCT_DETAILS.images,
price = PRODUCT_DETAILS.price,
name = PRODUCT_DETAILS.name,
description = PRODUCT_DETAILS.description,
}: ProductQuickView8Props) => {
const { regular, sale, currency } = price;
return (
<Dialog defaultOpen>
<DialogContent showCloseButton={false} className="p-4 sm:max-w-168">
<div className="absolute top-5 end-5 z-50">
<DialogClose asChild>
<Button className="rounded-full" size="icon-sm" variant="secondary">
<X />
</Button>
</DialogClose>
</div>
<div className="hide-scrollbar max-h-[calc(100dvh-8rem)] overflow-auto">
<ProductImages images={images} />
<div className="pt-4 pb-20">
<div className="space-y-6">
<div className="space-y-1">
<Price
onSale={sale != null}
className="items-end gap-x-1 text-base font-medium"
>
{sale != null && (
<span className="leading-tight text-foreground">
{formatCurrency(sale, currency)}
</span>
)}
<span
className={
sale != null
? "leading-tight text-muted-foreground line-through"
: "leading-tight text-foreground"
}
>
{formatCurrency(regular, currency)}
</span>
</Price>
<DialogTitle className="text-xl font-medium">
{name}
</DialogTitle>
</div>
<DialogDescription className="text-base leading-relaxed">
{description}
</DialogDescription>
</div>
<DialogFooter className="fixed inset-x-0 bottom-0">
<div className="w-full rounded-b-lg bg-background p-4">
<Button className="w-full">افزودن به سبد</Button>
</div>
</DialogFooter>
</div>
</div>
</DialogContent>
</Dialog>
);
};
const ProductImages = ({ images }: ProductImagesProps) => {
return (
<Carousel>
<CarouselContent>
{images.map((img) => (
<CarouselItem key={crypto.randomUUID()}>
<AspectRatio ratio={1.4} className="overflow-hidden rounded-sm">
<img
src={img.src}
alt={img.alt}
className="block size-full object-cover object-center"
/>
</AspectRatio>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="start-1" />
<CarouselNext className="end-1" />
</Carousel>
);
};
export { ProductQuickView8 };