پروفایلِ عمومی
پیشنمایش تمامصفحهپروفایلی که دیگران میبینند: کاور، عکس روی لبه، نام و نقش، شهر و لینک، آمار، دنبالکردن و پیام، و کارها یا مهارتها در سگمنت.
۱. نصب کامپوننتها
این بلاک از ۷ آیتم دیگ استفاده میکند: avatarbadgebuttoncontrol-sizeiconspersiantoggle-group
پکیجمنیجر پیشفرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیجمنیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/badge.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/persian.json https://docs.digdesign.ir/r/toggle-group.jsonpnpm dlx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/badge.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/persian.json https://docs.digdesign.ir/r/toggle-group.jsonyarn dlx digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/badge.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/persian.json https://docs.digdesign.ir/r/toggle-group.jsonbunx --bun digdesign@latest add https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/badge.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/persian.json https://docs.digdesign.ir/r/toggle-group.json۲. کد صفحه
کد را در app/<route>/page.tsx بگذارید و متنها، داده و هندلرها را با محصول خودتان عوض کنید.
profile-public.tsx
"use client"
import * as React from "react"
import { GlobeIcon, LinkIcon } from "@/components/icons"
import { Avatar } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { toFaDigits } from "@/lib/persian"
import { stockImages, type StockImageName } from "@/lib/stock-images"
const WORKS: { title: string; image: StockImageName }[] = [
{ title: "اپِ بانکی نو", image: "projectMobileApp" },
{ title: "داشبوردِ فروش", image: "projectDashboard" },
{ title: "هویتِ بصری کافه", image: "projectCafeBrand" },
]
const SKILLS = ["طراحی محصول", "تحقیقِ کاربر", "سیستمِ طراحی", "پروتوتایپ"]
/**
* پروفایلِ عمومی (آنچه دیگران میبینند): کاور، عکسِ روی لبه، نام و نقش، شهر و لینک، آمار،
* دنبالکردن و پیام؛ مهارتها و کارها در زبانههای سگمنت.
*/
export default function ProfilePublicBlock() {
const [following, setFollowing] = React.useState(false)
const [tab, setTab] = React.useState("works")
return (
<ControlSizeProvider size="xl" asChild>
<main className="mx-auto flex w-full max-w-4xl flex-col gap-8 p-4 sm:p-6">
<section className="overflow-hidden rounded-xl border border-border bg-card">
{/* eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ */}
<img src={stockImages.studioSunlit.src} alt="" className="h-40 w-full object-cover sm:h-52" />
<div className="flex flex-col gap-6 px-6 pb-6">
<div className="flex flex-wrap items-start justify-between gap-4">
<div className="flex items-start gap-4">
<Avatar alt="" src={stockImages.personWoman2.src} className="-mt-12 size-24 shrink-0 ring-4 ring-card" />
<div className="flex flex-col gap-0.5 pt-3">
<h1 className="text-2xl font-bold">سارا محمدی</h1>
<span className="text-muted-foreground">طراحِ محصول در آوند</span>
</div>
</div>
<div className="flex gap-2 pt-3">
<Button variant="outline">پیام</Button>
<Button variant={following ? "outline" : "default"} aria-pressed={following} onClick={() => setFollowing((value) => !value)}>
{following ? "دنبال میکنی" : "دنبال کردن"}
</Button>
</div>
</div>
<p className="max-w-2xl leading-8 text-muted-foreground">هشت سال طراحی محصولاتِ مالی؛ عاشقِ سادهکردنِ چیزهایی که پیچیده به نظر میرسند.</p>
<div className="flex flex-wrap items-center gap-x-6 gap-y-2 text-sm text-muted-foreground">
<span className="flex items-center gap-1.5">
<GlobeIcon aria-hidden className="size-4" />
تهران
</span>
<a href="#" className="flex items-center gap-1.5 hover:text-foreground">
<LinkIcon aria-hidden className="size-4" />
<bdi dir="ltr">sara.design</bdi>
</a>
<span>
<span className="font-semibold text-foreground">{toFaDigits(following ? 1241 : 1240)}</span> دنبالکننده
</span>
<span>
<span className="font-semibold text-foreground">{toFaDigits(186)}</span> دنبالشده
</span>
</div>
</div>
</section>
<ToggleGroup type="single" variant="segmented" value={tab} onValueChange={(value) => value && setTab(value as string)} aria-label="بخش" className="self-start">
<ToggleGroupItem value="works">کارها</ToggleGroupItem>
<ToggleGroupItem value="skills">مهارتها</ToggleGroupItem>
</ToggleGroup>
{tab === "works" ? (
<ul className="grid grid-cols-2 gap-3 sm:grid-cols-3 sm:gap-4">
{WORKS.map((work) => (
<li key={work.title} className="flex flex-col gap-3">
{/* eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ */}
<img src={stockImages[work.image].src} alt="" loading="lazy" className="aspect-[4/3] w-full rounded-xl object-cover" />
<span className="font-semibold">{work.title}</span>
</li>
))}
</ul>
) : (
<ul className="flex flex-wrap gap-2">
{SKILLS.map((skill) => (
<li key={skill}>
<Badge variant="soft" className="px-3 py-1 text-sm">
{skill}
</Badge>
</li>
))}
</ul>
)}
</main>
</ControlSizeProvider>
)
}