بلاک‌ها · بخش‌های صفحه

نظرِ مشتری‌ها در گریدِ آجری

پیش‌نمایش تمام‌صفحه

بخشِ نظرِ مشتری: کارت‌ها در ستون‌های آجری با طولِ متنِ متفاوت، هر کدام امتیاز، نقل‌قول و عکسِ واقعیِ گوینده با نقشش؛ روی سطحِ subtle.

۱. نصب کامپوننت‌ها

این بلاک از ۴ آیتم دیگ استفاده می‌کند: avatarcontrol-sizerevealtestimonial

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/testimonial.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/testimonial.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/testimonial.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/testimonial.json

۲. کد صفحه

کد را در app/<route>/page.tsx بگذارید و متن‌ها، داده و هندلرها را با محصول خودتان عوض کنید.

testimonials-grid.tsx
"use client"

import { Avatar } from "@/components/ui/avatar"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Reveal } from "@/components/ui/reveal"
import {
  Testimonial,
  TestimonialAuthor,
  TestimonialAuthorAvatar,
  TestimonialAuthorName,
  TestimonialAuthorRole,
  TestimonialQuote,
  TestimonialRating,
} from "@/components/ui/testimonial"
import { stockImages, type StockImageName } from "@/lib/stock-images"

const QUOTES: { text: string; name: string; role: string; photo: StockImageName; rating: number }[] = [
  { text: "قبلاً آخرِ هر ماه دو روز درگیرِ فاکتورها بودم؛ حالا نیم ساعت.", name: "سارا محمدی", role: "مدیرِ کافه رست", photo: "personWoman2", rating: 5 },
  { text: "گزارشِ سود و زیان را برای اولین بار بدونِ حسابدار فهمیدم. نمودارها واقعاً روشن‌اند و هر هفته نگاهشان می‌کنم.", name: "امیر رضایی", role: "بنیان‌گذارِ فروشگاهِ بوم", photo: "personMan1", rating: 5 },
  { text: "پشتیبانی سرِ پنج دقیقه جواب داد.", name: "نگار احمدی", role: "حسابدارِ آزاد", photo: "personWoman3", rating: 4 },
  { text: "حقوقِ دوازده نفر را با یک کلیک می‌دهیم و فیش‌ها خودشان پیامک می‌شوند. همین یک قابلیت ارزشِ اشتراک را داشت.", name: "علی کاظمی", role: "مدیرِ منابعِ انسانی", photo: "personMan2", rating: 5 },
  { text: "اتصال به بانک یعنی دیگر هیچ تراکنشی را دستی وارد نمی‌کنم.", name: "مهسا کریمی", role: "طراحِ مستقل", photo: "personWoman1", rating: 5 },
  { text: "تیمِ فروش و مالی بالاخره یک عدد را می‌بینند.", name: "کیان مرادی", role: "مدیرِ عامل، استودیو نقش", photo: "personMan1", rating: 4 },
]

/**
 * نظرِ مشتری‌ها در گریدِ آجری: ستون‌ها با طولِ متنِ متفاوت پر می‌شوند تا یکنواخت و
 * خسته‌کننده نباشد؛ هر کارت امتیاز، نقل‌قول و عکسِ واقعی گوینده با نقشش را دارد.
 */
export default function TestimonialsGridBlock() {
  return (
    <ControlSizeProvider size="xl" asChild>
      <section aria-labelledby="quotes-title" className="bg-subtle py-24">
        <div className="mx-auto flex w-full max-w-6xl flex-col gap-12 px-4 sm:px-6">
          <div className="mx-auto flex max-w-2xl flex-col items-center gap-3 text-center">
            <span className="text-sm font-semibold text-brand-secondary">نظرِ مشتری‌ها</span>
            <h2 id="quotes-title" className="text-3xl leading-snug font-black text-balance sm:text-4xl">
              بیش از ۱۲ هزار کسب‌وکار به ما اعتماد کرده‌اند
            </h2>
          </div>
          <div className="columns-1 gap-4 sm:columns-2 lg:columns-3 [&>*]:mb-4">
            {QUOTES.map((quote, index) => (
              <Reveal key={quote.name + index} delay={(index % 3) * 100} className="break-inside-avoid">
                <Testimonial className="gap-5">
                  <TestimonialRating rating={quote.rating} />
                  <TestimonialQuote className="text-base leading-8">{quote.text}</TestimonialQuote>
                  <TestimonialAuthor>
                    <TestimonialAuthorAvatar>
                      <Avatar alt={quote.name} src={stockImages[quote.photo].src} />
                    </TestimonialAuthorAvatar>
                    <div className="flex flex-col">
                      <TestimonialAuthorName>{quote.name}</TestimonialAuthorName>
                      <TestimonialAuthorRole>{quote.role}</TestimonialAuthorRole>
                    </div>
                  </TestimonialAuthor>
                </Testimonial>
              </Reveal>
            ))}
          </div>
        </div>
      </section>
    </ControlSizeProvider>
  )
}