"use client"; import { BadgeCheck, ChevronDown } from "lucide-react"; import { useState } from "react"; import { Rating } from "@/components/shadcnblocks/rating"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Progress } from "@/components/ui/progress"; import { Separator } from "@/components/ui/separator"; import { cn } from "@/lib/utils"; interface Review { id: string; rating: number; title: string; content: string; author: { name: string; avatar?: string; }; date: string; /** برای مرتب‌سازی جدیدترین؛ تاریخ نمایشی ممکن است شمسی باشد */ postedAt?: number; verified?: boolean; helpful?: number; } const DEFAULT_REVIEWS: Review[] = [ { id: "1", rating: 5, title: "فراتر از انتظارم بود", content: "اول کمی تردید داشتم، ولی این محصول واقعاً جواب داد. کیفیت ساخت عالی است و زودتر از موعد به دستم رسید.", author: { name: "سارا احمدی", avatar: "/block-media/shadcnblocks/block/avatar-1.webp", }, date: "۲۰ آذر ۱۴۰۳", postedAt: 6, verified: true, helpful: 42, }, { id: "2", rating: 5, title: "بهترین خرید امسالم", content: "واقعاً عاشقش شدم! به جزئیات با دقت زیادی توجه شده. وقتی سوال داشتم، پشتیبانی هم بسیار مفید بود.", author: { name: "مازیار رضایی", avatar: "/block-media/shadcnblocks/block/avatar-2.webp", }, date: "۱۸ آذر ۱۴۰۳", postedAt: 5, verified: true, helpful: 38, }, { id: "3", rating: 4, title: "ارزش خرید بالا", content: "به‌طور کلی محصول خوبی است و دقیقاً همان کاری را می‌کند که باید. پیشنهاد می‌کنم.", author: { name: "نیلوفر حسینی", avatar: "/block-media/shadcnblocks/block/avatar-3.webp", }, date: "۱۵ آذر ۱۴۰۳", postedAt: 4, verified: true, helpful: 24, }, { id: "4", rating: 5, title: "عالی برای استفاده روزمره", content: "یک ماه است هر روز از آن استفاده می‌کنم و هنوز مثل روز اول به نظر می‌رسد و درست کار می‌کند. کیفیت ساخت قابل تحسین است.", author: { name: "امیر محمدی" }, date: "۱۲ آذر ۱۴۰۳", postedAt: 3, verified: false, helpful: 19, }, { id: "5", rating: 4, title: "خوب، ولی جای بهبود دارد", content: "محصول خوبی است. رنگ کمی با عکس‌ها فرق داشت، ولی در مجموع از خریدم راضی‌ام.", author: { name: "رؤیا کاظمی", avatar: "/block-media/shadcnblocks/block/avatar-1.webp", }, date: "۸ آذر ۱۴۰۳", postedAt: 2, verified: true, helpful: 12, }, { id: "6", rating: 3, title: "قابل قبول، ولی انتظار بیشتری داشتم", content: "با توجه به قیمت، محصول معمولی است؛ چیز خاصی نیست ولی کارش را انجام می‌دهد. ارسال سریع بود.", author: { name: "پارسا موسوی" }, date: "۵ آذر ۱۴۰۳", postedAt: 1, verified: true, helpful: 8, }, ]; type SortOption = "helpful" | "newest" | "highest" | "lowest"; interface Reviews5Props { reviews?: Review[]; title?: string; className?: string; } const sortLabels: Record = { helpful: "مفیدترین", newest: "جدیدترین", highest: "بیشترین امتیاز", lowest: "کمترین امتیاز", }; const Reviews5 = ({ reviews = DEFAULT_REVIEWS, title = "نظرات مشتریان", className, }: Reviews5Props) => { const [sortBy, setSortBy] = useState("helpful"); const totalReviews = reviews.length; const averageRating = reviews.reduce((sum, r) => sum + r.rating, 0) / totalReviews; const formattedAverage = averageRating.toLocaleString("fa-IR", { minimumFractionDigits: 1, maximumFractionDigits: 1, }); const ratingCounts = [5, 4, 3, 2, 1].map((star) => ({ star, count: reviews.filter((r) => r.rating === star).length, percentage: (reviews.filter((r) => r.rating === star).length / totalReviews) * 100, })); const sortedReviews = [...reviews].sort((a, b) => { switch (sortBy) { case "helpful": return (b.helpful || 0) - (a.helpful || 0); case "newest": return (b.postedAt ?? 0) - (a.postedAt ?? 0); case "highest": return b.rating - a.rating; case "lowest": return a.rating - b.rating; default: return 0; } }); const formatHelpfulCount = (count: number) => `${count.toLocaleString("fa-IR")} نفر این نظر را مفید دانستند`; return (

{title}

{formattedAverage} از ۵
({totalReviews.toLocaleString("fa-IR")})
{[5, 4, 3, 2, 1].map((n) => ( {n.toLocaleString("fa-IR")} ))}
{ratingCounts.map(({ star, percentage }) => ( ))}
{totalReviews.toLocaleString("fa-IR")} نظر {(Object.keys(sortLabels) as SortOption[]).map((option) => ( setSortBy(option)} className={cn(sortBy === option && "font-medium")} > {sortLabels[option]} ))}
{sortedReviews.map((review, index) => (
{index > 0 && }
{review.author.name .split(/\s+/) .slice(0, 2) .map((part) => part[0]) .join("")} {review.author.name} {review.verified && ( )}
{review.date}
{review.title}

{review.content}

{review.helpful !== undefined && review.helpful > 0 && (

{formatHelpfulCount(review.helpful)}

)}
))}
); }; export { Reviews5 };