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

تیم در گریدِ پرتره

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

بخشِ تیم: پرتره‌های سیاه‌وسفید که با هاور رنگی می‌شوند، اسم، نقش و دو دکمهٔ تماس، و کارتِ تیرهٔ دعوت به همکاری در انتهای گرید.

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

این بلاک از ۵ آیتم دیگ استفاده می‌کند: avatarbuttoncontrol-sizeiconsreveal

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

۲. کد صفحه

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

team-grid.tsx
"use client"

import { EnvelopeIcon, LinkIcon } from "@/components/icons"
import { Avatar } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Reveal } from "@/components/ui/reveal"
import { stockImages, type StockImageName } from "@/lib/stock-images"

const PEOPLE: { name: string; role: string; photo?: StockImageName; initials?: string }[] = [
  { name: "سارا نیک‌پور", role: "مدیرعامل و هم‌بنیان‌گذار", photo: "personWoman1" },
  { name: "مهدی افشار", role: "مدیرِ فنی", photo: "personMan1" },
  { name: "نگار رحیمی", role: "سرپرستِ طراحی", photo: "personWoman3" },
  { name: "آرش کریمی", role: "مدیرِ رشد", photo: "personMan2" },
  { name: "مریم صالحی", role: "مدیرِ مالی", photo: "personWoman2" },
  { name: "کیوان رستمی", role: "سرپرستِ پشتیبانی", initials: "ک ر" },
]

/**
 * تیم در گریدِ پرتره: عکسِ سیاه‌وسفید که با هاور رنگی می‌شود، اسم و نقش، و دو دکمهٔ تماس
 * گوشهٔ عکس؛ کارتِ پایانی دعوت به همکاری است تا گرید خالی نماند.
 */
export default function TeamGridBlock() {
  return (
    <ControlSizeProvider size="xl" asChild>
      <section aria-labelledby="tg-title" className="mx-auto flex w-full max-w-6xl flex-col gap-12 px-4 py-24 sm:px-6">
        <div className="flex flex-col items-start justify-between gap-6 md:flex-row md:items-end">
          <div className="flex max-w-xl flex-col gap-3">
            <span className="text-sm font-semibold text-brand-secondary">تیم</span>
            <h2 id="tg-title" className="text-3xl leading-snug font-black text-balance sm:text-4xl">
              کوچک، باتجربه، همیشه در دسترس
            </h2>
          </div>
          <p className="max-w-sm leading-7 text-muted-foreground">بیست و چهار نفر در سه شهر؛ هر کدام دست‌کم یک روز در ماه پشتیبانی جواب می‌دهند.</p>
        </div>
        <ul className="grid grid-cols-2 gap-x-4 gap-y-8 md:grid-cols-3 lg:grid-cols-4">
          {PEOPLE.map((person, index) => (
            <Reveal asChild key={person.name} delay={(index % 4) * 80}>
              <li className="group flex flex-col gap-3">
                <div className="relative overflow-hidden rounded-xl bg-muted">
                  {person.photo ? (
                    // eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ
                    <img src={stockImages[person.photo].src} alt="" className="aspect-[4/5] w-full object-cover grayscale transition-[filter,scale] duration-500 group-hover:scale-105 group-hover:grayscale-0" />
                  ) : (
                    <div className="flex aspect-[4/5] items-center justify-center bg-[linear-gradient(160deg,var(--dig-violet-100),var(--dig-blue-100))] dark:bg-[linear-gradient(160deg,var(--dig-violet-900),var(--dig-blue-900))]">
                      <Avatar name={person.initials} size="lg" className="size-20 text-2xl" />
                    </div>
                  )}
                  <div className="absolute end-3 bottom-3 flex gap-2">
                    <Button size="icon" variant="secondary" radius="full" aria-label={`ایمیل به ${person.name}`}>
                      <EnvelopeIcon />
                    </Button>
                    <Button size="icon" variant="secondary" radius="full" aria-label={`صفحهٔ ${person.name}`}>
                      <LinkIcon />
                    </Button>
                  </div>
                </div>
                <div className="flex flex-col gap-0.5">
                  <h3 className="font-bold">{person.name}</h3>
                  <span className="text-sm text-muted-foreground">{person.role}</span>
                </div>
              </li>
            </Reveal>
          ))}
          <Reveal asChild delay={160}>
            <li className="col-span-2 flex flex-col items-start justify-end gap-4 rounded-xl bg-inverse p-6 text-[var(--dig-white)] [--primary-foreground:var(--dig-graphite-950)] [--primary:var(--dig-white)] md:col-span-1 lg:col-span-2">
              <h3 className="text-2xl font-black">جای شما خالی است</h3>
              <p className="leading-7 text-[var(--dig-neutral-400)]">شش موقعیتِ باز در طراحی، مهندسی و فروش.</p>
              <Button>موقعیت‌های شغلی</Button>
            </li>
          </Reveal>
        </ul>
      </section>
    </ControlSizeProvider>
  )
}