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

خرید بدونِ ثبت‌نام

پیش‌نمایش تمام‌صفحه

فرمِ کوتاهِ گیرنده و نشانی، «وارد شو» برای مشتریِ قبلی و ساختِ حسابِ تیک‌خوردنی در پایان؛ خلاصهٔ سفارش با عکس.

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

این بلاک از ۸ آیتم دیگ استفاده می‌کند: buttoncheckboxcontrol-sizelabellinkpersiantext-fieldtextarea

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/checkbox.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/label.json https://docs.digdesign.ir/r/link.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/text-field.json https://docs.digdesign.ir/r/textarea.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/checkbox.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/label.json https://docs.digdesign.ir/r/link.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/text-field.json https://docs.digdesign.ir/r/textarea.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/checkbox.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/label.json https://docs.digdesign.ir/r/link.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/text-field.json https://docs.digdesign.ir/r/textarea.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/checkbox.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/label.json https://docs.digdesign.ir/r/link.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/text-field.json https://docs.digdesign.ir/r/textarea.json

۲. کد صفحه

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

checkout-guest.tsx
"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Label } from "@/components/ui/label"
import { Link } from "@/components/ui/link"
import { TextField } from "@/components/ui/text-field"
import { Textarea } from "@/components/ui/textarea"
import { formatCurrency, isValidMobile, toFaDigits } from "@/lib/persian"
import { stockImages, type StockImageName } from "@/lib/stock-images"

const ITEMS: { title: string; image: StockImageName; price: number; quantity: number }[] = [
  { title: "گلدانِ سرامیکی دوقلو", image: "productVase", price: 1_290_000, quantity: 1 },
  { title: "دفترِ یادداشتِ جلدسخت", image: "coverNotebook", price: 180_000, quantity: 2 },
]

/**
 * خرید بدونِ ثبت‌نام: یک فرمِ کوتاه (گیرنده، موبایل، نشانی) و ساختِ حسابِ
 * دلخواه با تیک در پایان؛ «ورود» برای مشتری قبلی بالای فرم. خلاصهٔ سفارش با عکس کنارِ فرم.
 */
export default function CheckoutGuestBlock() {
  const [account, setAccount] = React.useState(true)
  const subtotal = ITEMS.reduce((sum, item) => sum + item.price * item.quantity, 0)

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="mx-auto grid w-full max-w-5xl grid-cols-1 items-start gap-8 p-4 sm:p-6 lg:grid-cols-[minmax(0,1fr)_20rem]">
        <form className="flex flex-col gap-8 rounded-xl border border-border bg-card p-6 sm:p-8" onSubmit={(event) => event.preventDefault()}>
          <div className="flex flex-wrap items-end justify-between gap-x-4 gap-y-3">
            <h1 className="text-2xl font-bold">تکمیلِ خرید</h1>
            <span className="text-sm text-muted-foreground">
              قبلاً خرید کرده‌ای؟ <Link href="#">وارد شو</Link>
            </span>
          </div>
          <div className="grid grid-cols-1 gap-5 sm:grid-cols-2">
            <TextField label="نامِ گیرنده" autoComplete="name" required />
            <TextField label="شماره موبایل" type="tel" dir="ltr" maxLength={11} autoComplete="tel" required validate={(value) => (isValidMobile(value) ? undefined : "شماره موبایل باید با ۰۹ شروع شود و ۱۱ رقم باشد.")} />
            <div className="flex flex-col gap-2 sm:col-span-2">
              <Label htmlFor="cg-address">نشانی</Label>
              <Textarea id="cg-address" rows={3} autoComplete="street-address" placeholder="شهر، خیابان، کوچه، پلاک، واحد" required />
            </div>
            <TextField label="کد پستی" dir="ltr" maxLength={10} inputMode="numeric" required />
          </div>
          <div className="flex items-start gap-3 rounded-lg bg-subtle p-4">
            <Checkbox id="cg-account" checked={account} onCheckedChange={(checked) => setAccount(checked === true)} className="mt-0.5" />
            <Label htmlFor="cg-account" className="flex flex-col items-start gap-1 font-normal">
              <span className="font-medium">با همین اطلاعات حساب بساز</span>
              <span className="text-sm text-muted-foreground">پیگیری سفارش و خریدِ بعدی سریع‌تر می‌شود؛ رمز لازم نیست، با کدِ پیامکی وارد می‌شوی.</span>
            </Label>
          </div>
          <Button type="submit" className="mt-2">
            ادامه و پرداخت
          </Button>
        </form>
        <aside className="flex flex-col gap-4 rounded-xl bg-subtle p-6 lg:sticky lg:top-6">
          <h2 className="font-bold">سفارشِ تو</h2>
          <ul className="flex flex-col gap-3">
            {ITEMS.map((item) => (
              <li key={item.title} className="flex items-center gap-3 text-sm">
                {/* eslint-disable-next-line @next/next/no-img-element -- عکس از کتابخانهٔ تصویرِ دیگ */}
                <img src={stockImages[item.image].src} alt="" className="size-12 rounded-lg object-cover" />
                <span className="flex flex-1 flex-col">
                  <span className="font-medium">{item.title}</span>
                  <span className="text-muted-foreground">{toFaDigits(item.quantity)} عدد</span>
                </span>
                <span className="tabular-nums">{formatCurrency(item.price * item.quantity)}</span>
              </li>
            ))}
          </ul>
          <div className="flex items-baseline justify-between border-t border-border pt-4">
            <span className="font-semibold">جمع</span>
            <span className="text-xl font-black tabular-nums">{formatCurrency(subtotal)}</span>
          </div>
        </aside>
      </main>
    </ControlSizeProvider>
  )
}