تیم در گریدِ پرتره
پیشنمایش تمامصفحهبخشِ تیم: پرترههای سیاهوسفید که با هاور رنگی میشوند، اسم، نقش و دو دکمهٔ تماس، و کارتِ تیرهٔ دعوت به همکاری در انتهای گرید.
۱. نصب کامپوننتها
این بلاک از ۵ آیتم دیگ استفاده میکند: 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.jsonpnpm 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.jsonyarn 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.jsonbunx --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>
)
}