بلاک‌ها · پشتیبانی و محتوا

تماس با نقشهٔ بزرگ و کارتِ نشانی، تلفن، ایمیل و ساعتِ کار روی آن، و فرمِ کوتاه با پیامِ موفقیتِ درجا.

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

این بلاک از ۷ آیتم دیگ استفاده می‌کند: buttoncontrol-sizeiconslabelpersiantext-fieldtextarea

پکیج‌منیجر پیش‌فرض 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/label.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/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/label.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/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/label.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/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/label.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 بگذارید و متن‌ها، داده و هندلرها را با محصول خودتان عوض کنید.

contact-map.tsx
"use client"

import * as React from "react"

import { ClockIcon, EnvelopeIcon, PhoneIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { TextField } from "@/components/ui/text-field"
import { Textarea } from "@/components/ui/textarea"
import { Label } from "@/components/ui/label"
import { isValidEmail, toFaDigits } from "@/lib/persian"

/**
 * تماس با نقشه: نقشهٔ بزرگ با کارتِ نشانی روی آن در یک ستون و فرمِ کوتاه در ستونِ دیگر؛
 * برای کسب‌وکاری که مراجعهٔ حضوری مهم است. پیامِ موفقیت در جای فرم.
 */
export default function ContactMapBlock() {
  const [sent, setSent] = React.useState(false)

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="mx-auto grid w-full max-w-6xl grid-cols-1 gap-8 px-4 py-16 sm:px-6 lg:grid-cols-2">
        <div className="relative min-h-80 overflow-hidden rounded-xl border border-border">
          {/* eslint-disable-next-line @next/next/no-img-element -- نقشهٔ تزئینی؛ در محصول نقشهٔ واقعی می‌آید */}
          <img src="/blocks/contact-map.svg" alt="موقعیتِ دفتر روی نقشه" className="absolute inset-0 size-full object-cover" />
          <div className="absolute inset-x-4 bottom-4 flex flex-col gap-3 rounded-xl bg-card p-5 shadow-card">
            <span className="font-bold">دفترِ مرکزی</span>
            <span className="text-sm leading-6 text-muted-foreground">تهران، خیابان ولیعصر، بالاتر از پارک ساعی، پلاک ۱۲</span>
            <div className="flex flex-wrap gap-x-5 gap-y-2 text-sm">
              <a href="tel:02191001234" className="flex items-center gap-1.5 hover:underline">
                <PhoneIcon aria-hidden className="size-4 text-muted-foreground" />
                <bdi dir="ltr">{toFaDigits("021-91001234")}</bdi>
              </a>
              <a href="mailto:hello@avand.example" className="flex items-center gap-1.5 hover:underline">
                <EnvelopeIcon aria-hidden className="size-4 text-muted-foreground" />
                <bdi dir="ltr">hello@avand.example</bdi>
              </a>
              <span className="flex items-center gap-1.5 text-muted-foreground">
                <ClockIcon aria-hidden className="size-4" />
                ۹ تا ۱۸
              </span>
            </div>
          </div>
        </div>

        <section className="flex flex-col gap-8 rounded-xl border border-border bg-card p-6 sm:p-10">
          <div className="flex flex-col gap-2">
            <h1 className="text-3xl font-black">سر بزن یا بنویس</h1>
            <p className="text-muted-foreground">تا پایانِ همان روزِ کاری جواب می‌دهیم.</p>
          </div>
          {sent ? (
            <p role="status" className="rounded-lg bg-success-subtle p-5 font-medium text-success-subtle-foreground">
              پیامت رسید؛ به‌زودی خبرت می‌کنیم.
            </p>
          ) : (
            <form
              className="flex flex-col gap-5"
              onSubmit={(event) => {
                event.preventDefault()
                setSent(true)
              }}
            >
              <div className="grid grid-cols-1 gap-5 sm:grid-cols-2">
                <TextField label="نام" name="name" autoComplete="name" required />
                <TextField label="ایمیل" name="email" type="email" dir="ltr" required validate={(value) => (isValidEmail(value) ? undefined : "ایمیل معتبر نیست.")} />
              </div>
              <div className="flex flex-col gap-2">
                <Label htmlFor="cm-message">پیام</Label>
                <Textarea id="cm-message" name="message" rows={5} required />
              </div>
              <Button type="submit" className="mt-4 self-start">
                ارسالِ پیام
              </Button>
            </form>
          )}
        </section>
      </main>
    </ControlSizeProvider>
  )
}