صفحهٔ برند
پیشنمایش تمامصفحهصفحهٔ برند یا فروشنده: کاورِ عکس، نشانِ برند روی لبه با تیکِ تأیید، آمار (امتیاز، کالا، دنبالکننده)، دنبالکردن، معرفیِ کوتاه و کالاهای برند با مرتبسازیِ سگمنت.
۱. نصب کامپوننتها
این بلاک از ۷ آیتم دیگ استفاده میکند: add-to-cartbuttoncontrol-sizeiconspersianproduct-cardtoggle-group
پکیجمنیجر پیشفرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیجمنیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/add-to-cart.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/product-card.json https://docs.digdesign.ir/r/toggle-group.jsonpnpm dlx digdesign@latest add https://docs.digdesign.ir/r/add-to-cart.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/product-card.json https://docs.digdesign.ir/r/toggle-group.jsonyarn dlx digdesign@latest add https://docs.digdesign.ir/r/add-to-cart.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/product-card.json https://docs.digdesign.ir/r/toggle-group.jsonbunx --bun digdesign@latest add https://docs.digdesign.ir/r/add-to-cart.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/product-card.json https://docs.digdesign.ir/r/toggle-group.json۲. کد صفحه
کد را در app/<route>/page.tsx بگذارید و متنها، داده و هندلرها را با محصول خودتان عوض کنید.
brand-page.tsx
"use client"
import * as React from "react"
import { CheckIcon, StarIcon } from "@/components/icons"
import { AddToCart } from "@/components/ui/add-to-cart"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { ProductCard, ProductCardBody, ProductCardFooter, ProductCardMedia, ProductCardPrice, ProductCardTitle } from "@/components/ui/product-card"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { formatCurrency, toFaDigits } from "@/lib/persian"
import { stockImages, type StockImageName } from "@/lib/stock-images"
const PRODUCTS: { id: string; title: string; image: StockImageName; price: number; sold: number; isNew?: boolean }[] = [
{ id: "1", title: "گلدانِ سرامیکی دوقلو", image: "productVase", price: 1_290_000, sold: 412 },
{ id: "2", title: "ظرفِ سفالی لعابمات", image: "coverMinimalRoom", price: 890_000, sold: 238, isNew: true },
{ id: "3", title: "ست فنجانِ دستساز", image: "studioSunlit", price: 1_640_000, sold: 156 },
{ id: "4", title: "جاشمعی سنگی", image: "coverNotebook", price: 420_000, sold: 98, isNew: true },
]
const SORTS = [
{ value: "popular", label: "پرفروش" },
{ value: "new", label: "تازهها" },
{ value: "cheap", label: "ارزانترین" },
]
/**
* صفحهٔ برند در فروشگاه: کاورِ عکس، نشانِ برند روی لبه با تیکِ تأیید، آمار (امتیاز،
* کالا، دنبالکننده) و دنبالکردن؛ معرفی کوتاه و کالاهای برند با مرتبسازی سگمنت.
*/
export default function BrandPageBlock() {
const [following, setFollowing] = React.useState(false)
const [sort, setSort] = React.useState("popular")
const products = [...PRODUCTS].sort((a, b) => (sort === "cheap" ? a.price - b.price : sort === "new" ? Number(Boolean(b.isNew)) - Number(Boolean(a.isNew)) : b.sold - a.sold))
return (
<ControlSizeProvider size="xl" asChild>
<main className="mx-auto flex w-full max-w-6xl flex-col gap-12 px-4 py-8 sm:px-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-48 w-full object-cover sm:h-64" />
<div className="flex flex-col gap-6 px-6 pb-6 sm:px-8 sm:pb-8">
<div className="flex flex-wrap items-end justify-between gap-4">
<div className="flex items-start gap-4">
<span className="-mt-10 flex size-20 shrink-0 items-center justify-center rounded-xl bg-[var(--dig-orange-500)] text-3xl font-black text-[var(--dig-white)] ring-4 ring-card">س</span>
<div className="flex flex-col gap-0.5 pt-3">
<h1 className="flex items-center gap-2 text-2xl font-bold">
خانهٔ سفال
<span className="flex size-5 items-center justify-center rounded-full bg-[var(--dig-blue-500)] text-[var(--dig-white)] [&>svg]:size-3" aria-label="فروشندهٔ تأییدشده">
<CheckIcon />
</span>
</h1>
<span className="text-sm text-muted-foreground">سفالِ دستسازِ لالجین، از ۱۳۹۸</span>
</div>
</div>
<Button variant={following ? "outline" : "default"} aria-pressed={following} onClick={() => setFollowing((value) => !value)}>
{following ? "دنبال میکنی" : "دنبال کردن"}
</Button>
</div>
<dl className="grid grid-cols-3 gap-4 rounded-lg bg-subtle p-4 text-center">
<div className="flex flex-col gap-0.5">
<dd className="flex items-center justify-center gap-1 text-xl font-black tabular-nums">
۴٫۸
<StarIcon aria-hidden className="size-4 fill-[var(--dig-orange-400)] text-[var(--dig-orange-400)]" />
</dd>
<dt className="text-xs text-muted-foreground">از ۲٬۳۱۰ نظر</dt>
</div>
<div className="flex flex-col gap-0.5">
<dd className="text-xl font-black tabular-nums">{toFaDigits(128)}</dd>
<dt className="text-xs text-muted-foreground">کالا</dt>
</div>
<div className="flex flex-col gap-0.5">
<dd className="text-xl font-black tabular-nums">{toFaDigits(following ? "18.5K" : "18.4K").replace(".", "٫")}</dd>
<dt className="text-xs text-muted-foreground">دنبالکننده</dt>
</div>
</dl>
<p className="max-w-3xl leading-8 text-muted-foreground">کارگاهی خانوادگی در لالجینِ همدان؛ هر تکه با دست چرخ و لعاب میخورد و برای همین هیچ دو گلدانی دقیقاً یکی نیستند.</p>
</div>
</section>
<section aria-labelledby="brand-products" className="flex flex-col gap-8">
<div className="flex flex-wrap items-center justify-between gap-4">
<h2 id="brand-products" className="text-2xl font-black">
کالاهای خانهٔ سفال
</h2>
<ToggleGroup type="single" variant="segmented" value={sort} onValueChange={(value) => value && setSort(value as string)} aria-label="مرتبسازی">
{SORTS.map((item) => (
<ToggleGroupItem key={item.value} value={item.value}>
{item.label}
</ToggleGroupItem>
))}
</ToggleGroup>
</div>
<div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
{products.map((product) => (
<ProductCard key={product.id} className="w-full">
<ProductCardMedia>
{/* eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ */}
<img src={stockImages[product.image].src} alt={stockImages[product.image].alt} loading="lazy" />
</ProductCardMedia>
<ProductCardBody>
<ProductCardTitle>{product.title}</ProductCardTitle>
<span className="text-xs text-muted-foreground">{product.isNew ? "تازه رسیده" : `${toFaDigits(product.sold)} فروش`}</span>
<ProductCardPrice amount={formatCurrency(product.price)} />
</ProductCardBody>
<ProductCardFooter>
<AddToCart fullWidth label="افزودن" itemName={product.title} />
</ProductCardFooter>
</ProductCard>
))}
</div>
</section>
</main>
</ControlSizeProvider>
)
}