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

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

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

این بلاک از ۶ آیتم دیگ استفاده می‌کند: buttoncontrol-sizeiconspersiansteppertoast

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add 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/stepper.json https://docs.digdesign.ir/r/toast.json
pnpm dlx digdesign@latest add 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/stepper.json https://docs.digdesign.ir/r/toast.json
yarn dlx digdesign@latest add 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/stepper.json https://docs.digdesign.ir/r/toast.json
bunx --bun digdesign@latest add 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/stepper.json https://docs.digdesign.ir/r/toast.json

۲. کد صفحه

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

order-success.tsx
"use client"

import * as React from "react"

import { CheckIcon, CopyIcon, DownloadIcon, TruckIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Stepper, StepperDescription, StepperItem, StepperTitle } from "@/components/ui/stepper"
import { toast } from "@/components/ui/toast"
import { formatCurrency, formatJalali, toFaDigits } from "@/lib/persian"
import { stockImages } from "@/lib/stock-images"

const ITEMS = [
  { title: "گلدانِ سرامیکی دوقلو", variant: "کرم · ۲ عدد", price: 2_580_000, image: stockImages.productVase },
  { title: "لیوانِ کاغذی برند‌دار", variant: "بستهٔ ۵۰ عددی", price: 420_000, image: stockImages.projectCafeBrand },
]
const SHIPPING = 0
const ORDER_ID = "DG-140507-3921"

/**
 * رسیدِ پرداخت و ثبتِ سفارش: تیکِ موفقیت و شمارهٔ سفارش با کپی، مراحلِ ارسال،
 * اقلام با عکس، ریزِ مبلغ و نشانی تحویل، و دو کنشِ «پیگیری» و «ادامهٔ خرید».
 */
export default function OrderSuccessBlock() {
  const subtotal = ITEMS.reduce((sum, item) => sum + item.price, 0)
  const delivery = new Date()
  delivery.setDate(delivery.getDate() + 2)

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="mx-auto flex w-full max-w-2xl flex-col gap-10 px-4 py-16 sm:px-6">
        <header className="flex flex-col items-center gap-5 text-center" role="status">
          <span aria-hidden className="flex size-16 items-center justify-center rounded-full bg-success-subtle text-success ring-8 ring-[color-mix(in_oklab,var(--success)_8%,var(--background))] [&>svg]:size-8">
            <CheckIcon />
          </span>
          <div className="flex flex-col gap-2">
            <h1 className="text-3xl font-bold">سفارشت ثبت شد!</h1>
            <p className="text-muted-foreground">پرداخت موفق بود و رسیدش به ایمیلت رفت. ممنون که از ما خریدی.</p>
          </div>
          <div className="flex items-center gap-2 rounded-lg bg-muted px-4 py-2 text-sm">
            <span className="text-muted-foreground">شمارهٔ سفارش:</span>
            <bdi dir="ltr" className="font-semibold tabular-nums">
              {ORDER_ID}
            </bdi>
            <Button
              variant="ghost"
              size="icon"
              aria-label="کپی شمارهٔ سفارش"
              onClick={() => {
                void navigator.clipboard?.writeText(ORDER_ID)
                toast.success("شمارهٔ سفارش کپی شد.")
              }}
            >
              <CopyIcon />
            </Button>
          </div>
        </header>

        <section aria-label="وضعیتِ ارسال" className="flex flex-col gap-6 rounded-xl border border-border p-6">
          <div className="flex items-center gap-3">
            <span aria-hidden className="flex size-11 items-center justify-center rounded-xl bg-[color-mix(in_oklab,var(--brand-secondary)_12%,var(--card))] text-brand-secondary [&>svg]:size-5">
              <TruckIcon />
            </span>
            <div className="flex flex-col">
              <span className="font-semibold">تحویل تا {formatJalali(delivery, "long")}</span>
              <span className="text-sm text-muted-foreground">با پیکِ سریع؛ کدِ رهگیری پیامک می‌شود.</span>
            </div>
          </div>
          <Stepper value={1}>
            <StepperItem>
              <StepperTitle>ثبت</StepperTitle>
              <StepperDescription>انجام شد</StepperDescription>
            </StepperItem>
            <StepperItem>
              <StepperTitle>آماده‌سازی</StepperTitle>
              <StepperDescription>امروز</StepperDescription>
            </StepperItem>
            <StepperItem>
              <StepperTitle>ارسال</StepperTitle>
            </StepperItem>
            <StepperItem>
              <StepperTitle>تحویل</StepperTitle>
            </StepperItem>
          </Stepper>
        </section>

        <section aria-labelledby="order-items" className="flex flex-col gap-4">
          <h2 id="order-items" className="text-lg font-bold">
            اقلامِ سفارش
          </h2>
          <ul className="flex flex-col divide-y divide-border rounded-xl border border-border">
            {ITEMS.map((item) => (
              <li key={item.title} className="flex items-center gap-4 p-4">
                {/* eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ */}
                <img src={item.image.src} alt="" className="size-16 shrink-0 rounded-lg object-cover" />
                <div className="flex min-w-0 flex-1 flex-col gap-0.5">
                  <span className="truncate font-medium">{item.title}</span>
                  <span className="text-sm text-muted-foreground">{item.variant}</span>
                </div>
                <span className="font-semibold tabular-nums">{formatCurrency(item.price)}</span>
              </li>
            ))}
          </ul>
          <dl className="flex flex-col gap-3 rounded-xl bg-subtle p-5 text-sm">
            <div className="flex justify-between">
              <dt className="text-muted-foreground">جمعِ کالاها</dt>
              <dd className="tabular-nums">{formatCurrency(subtotal)}</dd>
            </div>
            <div className="flex justify-between">
              <dt className="text-muted-foreground">ارسال</dt>
              <dd className="text-success">{SHIPPING === 0 ? "رایگان" : formatCurrency(SHIPPING)}</dd>
            </div>
            <div className="mt-2 flex items-baseline justify-between border-t border-border pt-4">
              <dt className="font-semibold">پرداخت‌شده</dt>
              <dd className="text-xl font-bold tabular-nums">{formatCurrency(subtotal + SHIPPING)}</dd>
            </div>
          </dl>
          <p className="text-sm leading-7 text-muted-foreground">
            تحویل به: سارا محمدی · تهران، خیابان ولیعصر، کوچهٔ نسترن، پلاک ۱۲ · <bdi dir="ltr">{toFaDigits("0912 345 6789")}</bdi>
          </p>
        </section>

        <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
          <Button fullWidth>پیگیری سفارش</Button>
          <Button variant="outline" fullWidth>
            ادامهٔ خرید
          </Button>
        </div>
        <Button variant="ghost" className="self-center">
          <DownloadIcon />
          دانلودِ فاکتور
        </Button>
      </main>
    </ControlSizeProvider>
  )
}