بلاک‌ها · فروشگاهی

استعلام با کد پیگیری و مراحل ارسال سفارش.

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

این بلاک از ۱۰ آیتم دیگ استفاده می‌کند: avatarbadgebuttoncardcontrol-sizeiconspersianprogresssteppertext-field

پکیج‌منیجر پیش‌فرض 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/card.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/progress.json https://docs.digdesign.ir/r/stepper.json https://docs.digdesign.ir/r/text-field.json
pnpm 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/card.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/progress.json https://docs.digdesign.ir/r/stepper.json https://docs.digdesign.ir/r/text-field.json
yarn 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/card.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/progress.json https://docs.digdesign.ir/r/stepper.json https://docs.digdesign.ir/r/text-field.json
bunx --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/card.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/progress.json https://docs.digdesign.ir/r/stepper.json https://docs.digdesign.ir/r/text-field.json

۲. کد صفحه

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

order-tracking.tsx
"use client"

import * as React from "react"

import { ClockIcon, PhoneIcon, TruckIcon } from "@/components/icons"
import { Avatar } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Progress } from "@/components/ui/progress"
import { Stepper, StepperDescription, StepperItem, StepperTitle } from "@/components/ui/stepper"
import { TextField } from "@/components/ui/text-field"
import { formatJalaliDateTime, toFaDigits } from "@/lib/persian"
import { stockImages } from "@/lib/stock-images"

const STEPS = [
  { title: "ثبت سفارش", date: "2026-10-04T10:12:00" },
  { title: "آماده‌سازی در انبار", date: "2026-10-04T16:40:00" },
  { title: "تحویل به پیک", date: "2026-10-05T09:05:00" },
  { title: "در مسیر", date: "2026-10-06T08:30:00" },
  { title: "تحویل", date: null },
]
const CURRENT = 3
const ITEMS = [stockImages.productVase, stockImages.projectCafeBrand]

/**
 * پیگیری سفارش: جست‌وجوی کدِ رهگیری، کارتِ وضعیت با زمانِ تحویلِ برجسته و نوارِ
 * پیشرفت، نقشه با پیک، کارتِ پیک با تماس، مراحلِ عمودی با زمان، و اقلام و نشانی.
 */
export default function OrderTrackingBlock() {
  const [code, setCode] = React.useState("8821042")
  const [shown, setShown] = React.useState(true)

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="mx-auto flex w-full max-w-5xl flex-col gap-8 p-4 sm:p-6">
        <header className="flex flex-wrap items-end justify-between gap-x-4 gap-y-8">
          <div className="flex flex-col gap-1">
            <h1 className="text-2xl font-bold">پیگیری سفارش</h1>
            <p className="text-muted-foreground">کدِ رهگیری را از پیامکِ ثبتِ سفارش بردارید.</p>
          </div>
          <form
            className="flex w-full items-end gap-2 sm:w-auto"
            onSubmit={(event) => {
              event.preventDefault()
              setShown(code.length > 0)
            }}
          >
            <TextField label="کدِ رهگیری" inputMode="numeric" dir="ltr" value={code} onValueChange={setCode} className="flex-1 sm:w-56" />
            <Button type="submit">پیگیری</Button>
          </form>
        </header>

        {shown && (
          <div className="grid grid-cols-1 items-start gap-6 lg:grid-cols-[minmax(0,1.3fr)_minmax(0,1fr)]">
            <div className="flex flex-col gap-6">
              {/* وضعیت: زمانِ تحویل بزرگ، مرحلهٔ فعلی و پیشرفت. */}
              <section aria-label="وضعیتِ سفارش" className="relative isolate flex flex-col gap-5 overflow-hidden rounded-xl bg-[linear-gradient(135deg,var(--dig-violet-700),var(--dig-indigo-800))] p-6 text-[var(--dig-white)] [--muted-foreground:var(--dig-violet-100)]">
                <span aria-hidden className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(circle_at_90%_0%,var(--dig-violet-400),transparent_45%)]" />
                <span aria-hidden className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(color-mix(in_oklab,var(--dig-white)_28%,transparent)_1.2px,transparent_1.3px)] [background-size:18px_18px] [mask-image:linear-gradient(to_left,black,transparent_60%)]" />
                <div className="flex items-center justify-between gap-3">
                  <span className="text-sm text-muted-foreground">سفارشِ {toFaDigits(code)}</span>
                  <Badge className="bg-[var(--dig-white)] text-[var(--dig-violet-700)]">{STEPS[CURRENT].title}</Badge>
                </div>
                <div className="flex items-center gap-3">
                  <span aria-hidden className="flex size-12 items-center justify-center rounded-xl bg-[color-mix(in_oklab,var(--dig-white)_16%,var(--dig-violet-800))] [&>svg]:size-6">
                    <TruckIcon />
                  </span>
                  <div className="flex flex-col">
                    <span className="text-sm text-muted-foreground">تحویل امروز تا</span>
                    <span className="text-3xl font-black tabular-nums">ساعت ۱۸</span>
                  </div>
                </div>
                <Progress value={78} aria-label="پیشرفتِ ارسال" className="bg-[color-mix(in_oklab,var(--dig-white)_25%,var(--dig-violet-800))] [--progress:var(--dig-white)]" />
              </section>

              {/* نقشه با جای پیک؛ نقشهٔ واقعی در محصول جایگزین می‌شود. */}
              <div className="relative overflow-hidden rounded-xl border border-border">
                {/* eslint-disable-next-line @next/next/no-img-element -- نقشهٔ تزئینی */}
                <img src="/blocks/contact-map.svg" alt="موقعیتِ پیک روی نقشه" className="aspect-[16/9] w-full object-cover dark:brightness-[0.8]" />
                <div className="absolute start-4 bottom-4 flex items-center gap-3 rounded-lg bg-card px-4 py-3 shadow-card">
                  <ClockIcon aria-hidden className="size-4 text-brand-secondary" />
                  <span className="text-sm font-medium">۲۵ دقیقه تا شما</span>
                </div>
              </div>

              <Card>
                <CardContent className="flex items-center gap-4">
                  <Avatar size="lg" alt="علی کاظمی" src={stockImages.personMan2.src} />
                  <div className="flex flex-1 flex-col">
                    <span className="font-semibold">علی کاظمی</span>
                    <span className="text-sm text-muted-foreground">پیکِ شما · موتور، پلاکِ ۲۲۴</span>
                  </div>
                  <Button variant="outline" size="icon" aria-label="تماس با پیک">
                    <PhoneIcon />
                  </Button>
                </CardContent>
              </Card>
            </div>

            <div className="flex flex-col gap-6">
              <Card>
                <CardHeader>
                  <CardTitle className="text-base">مراحل</CardTitle>
                </CardHeader>
                <CardContent>
                  <Stepper value={CURRENT} orientation="vertical">
                    {STEPS.map((step) => (
                      <StepperItem key={step.title}>
                        <StepperTitle>{step.title}</StepperTitle>
                        <StepperDescription>{step.date ? formatJalaliDateTime(step.date) : "به‌زودی"}</StepperDescription>
                      </StepperItem>
                    ))}
                  </Stepper>
                </CardContent>
              </Card>
              <Card>
                <CardHeader>
                  <CardTitle className="text-base">اقلام و نشانی</CardTitle>
                </CardHeader>
                <CardContent className="flex flex-col gap-4">
                  <div className="flex gap-2">
                    {ITEMS.map((image) => (
                      // eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ
                      <img key={image.src} src={image.src} alt={image.alt} className="size-16 rounded-lg object-cover" />
                    ))}
                  </div>
                  <p className="text-sm leading-7 text-muted-foreground">تهران، خیابان ولیعصر، کوچهٔ نسترن، پلاک ۱۲، واحد ۴</p>
                </CardContent>
              </Card>
            </div>
          </div>
        )}
      </main>
    </ControlSizeProvider>
  )
}