تماس با نقشه
پیشنمایش تمامصفحهتماس با نقشهٔ بزرگ و کارتِ نشانی، تلفن، ایمیل و ساعتِ کار روی آن، و فرمِ کوتاه با پیامِ موفقیتِ درجا.
۱. نصب کامپوننتها
این بلاک از ۷ آیتم دیگ استفاده میکند: 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.jsonpnpm 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.jsonyarn 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.jsonbunx --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>
)
}