"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { GitCompareArrows, Heart, Minus, Plus, X } from "lucide-react"; import type { ControllerRenderProps } from "react-hook-form"; import { useForm } from "react-hook-form"; import { Controller } from "react-hook-form"; import z from "zod"; import { Price } from "@/components/shadcnblocks/price"; import { Rating } from "@/components/shadcnblocks/rating"; import { AspectRatio } from "@/components/ui/aspect-ratio"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Carousel, CarouselContent, CarouselItem, } from "@/components/ui/carousel"; import { Field, FieldLabel } from "@/components/ui/field"; import { Input } from "@/components/ui/input"; import { Separator } from "@/components/ui/separator"; import { Sheet, SheetClose, SheetContent, SheetDescription, SheetTitle, } from "@/components/ui/sheet"; import { useMediaQuery } from "@/hooks/useMediaQuery"; const STOCK_STATUS = { IN_STOCK: "IN_STOCK", OUT_OF_STOCK: "OUT_OF_STOCK", } as const; type StockStatusCode = keyof typeof STOCK_STATUS; type Image = { src: string; alt: string; }; interface Reviews { rate: number; totalReviewers: string; link: string; } interface ProductPrice { regular: number; sale?: number; currency: string; } type Product = { images: Image[]; name: string; reviews: Reviews; price: ProductPrice; stockStatusCode: StockStatusCode; description: string; hinges: Record; categories: { text: string; link: string; }[]; }; type ProductQuickView6Props = Product; interface ProductImagesProps { images: Image[]; } type ProductFormType = z.infer; type FieldName = keyof ProductFormType; interface QuantityProps { field: ControllerRenderProps; max?: number; min?: number; } 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/furniture/pexels-karolina-grabowska-7193566-3.jpg", alt: "صندلی ناهارخوری از نمای جلو", }, { src: "/block-media/shadcnblocks/block/ecommerce/furniture/pexels-karolina-grabowska-7193654-3.jpg", alt: "صندلی ناهارخوری از نمای جانبی", }, { src: "/block-media/shadcnblocks/block/ecommerce/furniture/pexels-karolina-grabowska-7193627-3.jpg", alt: "جزئیات بافت صندلی ناهارخوری", }, { src: "/block-media/shadcnblocks/block/ecommerce/furniture/pexels-karolina-grabowska-7193650-3.jpg", alt: "صندلی در فضای ناهارخوری", }, { src: "/block-media/shadcnblocks/block/ecommerce/furniture/pexels-karolina-grabowska-7193649-3.jpg", alt: "صندلی ناهارخوری در دکور داخلی", }, ], name: "صندلی ناهارخوری آلو", reviews: { rate: 4.5, totalReviewers: "۵٫۸ هزار نظر", link: "#", }, price: { regular: 499000.0, sale: 389000.0, currency: "ریال", }, stockStatusCode: "IN_STOCK", description: "طراحی مدرن و راحت برای میز ناهارخوری؛ ترکیبی از استحکام، زیبایی و راحتی در استفاده روزمره.", hinges: { quantity: { id: "quantity", name: "quantity", label: "تعداد", min: 1, max: 99, }, }, categories: [ { text: "مبلمان", link: "#", }, { text: "صندلی", link: "#", }, ], }; const ProductQuickView6 = ({ images = PRODUCT_DETAILS.images, name = PRODUCT_DETAILS.name, price = PRODUCT_DETAILS.price, reviews = PRODUCT_DETAILS.reviews, stockStatusCode = PRODUCT_DETAILS.stockStatusCode, description = PRODUCT_DETAILS.description, hinges = PRODUCT_DETAILS.hinges, categories = PRODUCT_DETAILS.categories, }: ProductQuickView6Props) => { const { regular, sale, currency } = price; return (
{name} {formatCurrency(regular, currency)} {sale != null && ( {formatCurrency(sale, currency)} )} {stockStatusCode === STOCK_STATUS.IN_STOCK ? "موجود" : "ناموجود"} {description}

دسته‌ها:{" "} {categories.map((item) => ( {item.text} ))}

); }; const ProductImages = ({ images }: ProductImagesProps) => { const isDesktop = useMediaQuery("(min-width: 768px)"); if (!images) return; return ( {images.map((img) => ( {img.alt} ))} ); }; interface Hinges { label: string; id: string; name: FieldName; min?: number; max?: number; } interface ProductFormProps { hinges: Record; selected?: ProductFormType; } const productForm = z.object({ quantity: z.number(), }); const ProductForm = ({ hinges, selected }: ProductFormProps) => { const form = useForm({ resolver: zodResolver(productForm), defaultValues: { quantity: selected?.quantity ?? 1, }, }); function onSubmit(values: ProductFormType) { console.log(values); } const quantityHinges = hinges?.quantity; return (
( {quantityHinges.label} )} />
); }; const Quantity = ({ field, max, min }: QuantityProps) => { return (
{ const raw = e.target.value; const parsed = parseInt(raw, 10); // Accept empty string for typing, but validate if not a number if (raw === "") { field.onChange(""); } else if (!isNaN(parsed)) { field.onChange(parsed); } }} type="number" min={min ? min : 1} max={max ? max : 99} className="w-full min-w-10 flex-1 [appearance:textfield] rounded-none border-0 !bg-background px-1 text-center shadow-none focus-visible:ring-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none" />
); }; export { ProductQuickView6 };