Files
reui-blocks/blocks/testimonial23.tsx
T

246 lines
8.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import {
BadgeCheck,
ChevronRight,
Clock,
MessageSquareCode,
} from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import { Avatar, AvatarImage } from "@/components/ui/avatar";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { cn } from "@/lib/utils";
interface DataItem {
id: string;
name: string;
username: string;
date: string;
avatar: string;
content: string;
}
const DATA: DataItem[] = [
{
id: "1",
name: "امیر محمدی",
username: "amir_mohammadi",
date: "۵ مهر ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-4.webp",
content:
"این پلتفرم کاملاً نحوه مدیریت پروژه‌هایم را تغییر داد. ابزارها هم شهودی‌اند هم قدرتمند و گردش کارم را بی‌سابقه ساده کرده‌اند. برای بهره‌وری تحول‌آفرین است!",
},
{
id: "2",
name: "نیلوفر حسینی",
username: "niloofar_h",
date: "۳۰ شهریور ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-1.webp",
content:
"قابلیت‌های همکاری واقعاً برجسته است و به تیم من اجازه می‌دهد هر جا که هستیم بی‌نقص با هم کار کنیم؛ دورکاری را به‌طور محسوسی آسان‌تر کرده. ویرایش بلادرنگ و اشتراک‌گذاری شهودی نحوه کار ما را عوض کرده و دردسر نسخه‌ها و ایمیل‌های بی‌پایان را حذف کرده.",
},
{
id: "3",
name: "سارا احمدی",
username: "sara_ahmadi",
date: "۲۵ شهریور ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-3.webp",
content: "تحلیل‌ها تحول‌آفرین‌اند!",
},
{
id: "4",
name: "پارسا موسوی",
username: "parsa_mousavi",
date: "۲۰ شهریور ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-4.webp",
content:
"دوست دارم چقدر ادغام این پلتفرم با ابزارهای موجود آسان است. گردش کارم را به‌طور چشمگیری ساده کرده و هر هفته ساعت‌ها برایم ذخیره می‌کند.",
},
{
id: "5",
name: "رؤیا کاظمی",
username: "roya_kazemi",
date: "۱۵ شهریور ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-3.webp",
content:
"قالب‌های طراحی فوق‌العاده‌اند. کمک کردند پروژه‌ها را سریع‌تر تحویل دهم بدون اینکه کیفیت پایین بیاید. شدیداً توصیه می‌کنم!",
},
{
id: "6",
name: "مهسا نوری",
username: "mahsa_nouri",
date: "۱۰ شهریور ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-7.webp",
content:
"این پلتفرم مدیریت پروژه را بسیار آسان کرده. شهودی، کارآمد و همه را روی اهداف مشترک نگه می‌دارد.",
},
{
id: "7",
name: "فاطمه رستمی",
username: "fateme_rastemi",
date: "۵ شهریور ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-7.webp",
content:
"ابزارهای برندسازی شگفت‌انگیزند. به ما کمک کردند در همه کمپین‌ها یکنواختی حفظ کنیم؛ برد بزرگی برای تیم بود.",
},
{
id: "8",
name: "مهتاب شریفی",
username: "mahtab_sharifi",
date: "۳۰ مرداد ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-1.webp",
content:
"ابزارهای ویرایش وکتور عالی‌اند. فرایند خلاقانه من را بسیار روان‌تر و لذت‌بخش‌تر کرده‌اند.",
},
{
id: "9",
name: "کاوه مرادی",
username: "kaveh_moradi",
date: "۲۵ مرداد ۱۴۲",
avatar:
"/block-media/shadcnblocks/block/avatar-4.webp",
content:
"قابلیت‌های انیمیشن باورنکردنی‌اند. پروژه‌هایم را به سطح بالاتری برده‌اند و از نتیجه بسیار راضی‌ام.",
},
];
const TestimonialCard = ({ testimonial }: { testimonial: DataItem }) => (
<Card className="relative mb-5 break-inside-avoid rounded-xl p-5 shadow-sm">
<div className="flex items-center gap-4">
<Avatar className="h-10 w-10 rounded-full ring-1 ring-muted">
<AvatarImage src={testimonial.avatar} alt={testimonial.name} />
</Avatar>
<div>
<div className="flex items-center gap-2">
<p className="text-sm font-medium">{testimonial.name}</p>
<BadgeCheck className="h-4 w-4 fill-cyan-400 stroke-white" />
</div>
<p className="mt-2 text-xs text-muted-foreground">
@{testimonial.username}
</p>
</div>
<div className="ms-auto hover:cursor-pointer">
<img
src="/block-media/shadcnblocks/block/logos/x.svg"
alt="لوگوی X"
className="h-4 w-4"
/>
</div>
</div>
<div className="my-4 border-t border-dashed border-border" />
<div className="text-sm text-foreground">
<q>{testimonial.content}</q>
</div>
<div className="mt-4 flex items-center gap-2 text-xs text-muted-foreground">
<Clock className="h-4 w-4" />
<span>{testimonial.date}</span>
</div>
</Card>
);
interface Testimonial23Props {
className?: string;
}
const Testimonial23 = ({ className }: Testimonial23Props) => {
const [columnCount, setColumnCount] = useState(3);
useEffect(() => {
const getColumnCount = () => {
if (typeof window === "undefined") return 3;
const width = window.innerWidth;
if (width < 768) return 1;
if (width < 1024) return 2;
return 3;
};
const updateColumnCount = () => {
setColumnCount(getColumnCount());
};
updateColumnCount();
window.addEventListener("resize", updateColumnCount);
return () => window.removeEventListener("resize", updateColumnCount);
}, []);
const reorderForColumns = (items: DataItem[], columns: number) => {
const itemsPerColumn = Math.ceil(items.length / columns);
const reordered: DataItem[] = [];
for (let col = 0; col < columns; col++) {
for (let row = 0; row < itemsPerColumn; row++) {
const originalIndex = row * columns + col;
if (originalIndex < items.length) {
reordered.push(items[originalIndex]);
}
}
}
return reordered;
};
const reorderedData = useMemo(() => {
return reorderForColumns(DATA, columnCount);
}, [columnCount]);
return (
<section dir="rtl" lang="fa" className={cn("py-32", className)}>
<div className="container">
<div className="my-4 flex justify-center">
<Badge variant="outline" className="rounded-sm py-2 shadow-md">
<MessageSquareCode className="me-2 size-4 text-muted-foreground" />
<span>بازخورد مشتریان</span>
</Badge>
</div>
<div className="flex flex-col items-center gap-6 px-4 sm:px-8">
<h2 className="mb-2 text-center text-3xl font-semibold lg:text-2xll">
بشنویید مشتریان ما <br /> چه می‌گویند
</h2>
<div className="mt-4 flex flex-col items-center gap-4 sm:flex-row">
<span>
ببینید <b>ری یو آی</b> چگونه گردش کار در صنایع مختلف را متحول
می‌کند.
</span>
</div>
</div>
<div className="relative mt-14 w-full px-4 after:absolute after:inset-x-0 after:-bottom-2 after:h-96 after:bg-linear-to-t after:from-background sm:px-8 md:px-16 lg:px-32">
<div className="columns-1 gap-5 md:columns-2 lg:columns-3">
{reorderedData.map((testimonial) => (
<TestimonialCard key={testimonial.id} testimonial={testimonial} />
))}
</div>
</div>
<div className="flex justify-center">
<Button className="mt-4 gap-2 rounded-lg px-5 py-3 text-sm shadow-sm transition-colors hover:bg-primary/90 focus:outline-none disabled:pointer-events-none disabled:opacity-50">
<span className="flex items-center gap-1">
<span>بیشتر ببینید</span>
<span className="text-muted/80">-</span>
<span className="text-muted/80">نظرات</span>
</span>
<ChevronRight className="h-4 w-4 text-muted-foreground/80" />
</Button>
</div>
</div>
</section>
);
};
export { Testimonial23 };