فوتر روی منظره
پیشنمایش تمامصفحهبخشِ فوتر: کارتِ سفیدِ شناور با برند، سه ستونِ لینک و شبکههای اجتماعی روی منظرهٔ کویر و جادهٔ پیچان (SVG با توکنها، غروب در حالتِ تیره).
۱. نصب کامپوننتها
این بلاک از ۳ آیتم دیگ استفاده میکند: buttoncontrol-sizeicons
پکیجمنیجر پیشفرض 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.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.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.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۲. کد صفحه
کد را در app/<route>/page.tsx بگذارید و متنها، داده و هندلرها را با محصول خودتان عوض کنید.
footer-scene.tsx
"use client"
import { InstagramLogo, LinkedInLogo, TelegramLogo, TruckIcon, TwitterLogo } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
const COLUMNS = [
{ title: "شرکت", links: ["داستانِ ما", "چطور کار میکند", "رانندهٔ ما شوید"] },
{ title: "دریافتِ اپ", links: ["کافهبازار", "مایکت", "دانلودِ مستقیم"] },
{ title: "قوانین", links: ["حریمِ خصوصی", "شرایطِ استفاده"] },
]
const SOCIALS = [
{ icon: <InstagramLogo />, label: "اینستاگرام" },
{ icon: <TelegramLogo />, label: "تلگرام" },
{ icon: <LinkedInLogo />, label: "لینکدین" },
{ icon: <TwitterLogo />, label: "ایکس" },
]
/**
* فوترِ کارتِ شناور روی منظره: تپههای شنیِ کویر و جادهای پیچان با یک کامیونِ کوچک (کشیده با
* SVG و توکنهای نارنجی)، و کارتِ سفیدِ فوتر با برند، سه ستونِ لینک، کپیرایت و شبکههای
* اجتماعی بالای آن. منظره با تم هماهنگ است و در حالتِ تیره غروب میشود.
*/
export default function FooterSceneBlock() {
return (
<ControlSizeProvider size="xl" asChild>
<footer className="relative isolate w-full overflow-hidden bg-[var(--dig-orange-200)] px-4 pt-16 pb-72 sm:px-6 sm:pb-96 dark:bg-[var(--dig-orange-950)]">
<svg aria-hidden viewBox="0 0 1440 700" preserveAspectRatio="xMidYMax slice" className="absolute inset-0 -z-10 size-full">
<path d="M0 260 C 200 200 360 240 520 190 S 880 150 1040 210 S 1300 190 1440 230 V700 H0Z" className="fill-[var(--dig-orange-300)] dark:fill-[var(--dig-orange-900)]" />
<path d="M0 360 C 240 300 420 360 640 300 S 1020 260 1200 330 S 1380 320 1440 340 V700 H0Z" className="fill-[var(--dig-orange-400)] dark:fill-[var(--dig-orange-800)]" />
<path d="M520 420 C 600 360 700 350 780 300 C 860 350 980 360 1060 430 Z" className="fill-[var(--dig-orange-300)] dark:fill-[var(--dig-orange-700)]" />
<path d="M0 470 C 260 420 480 470 700 430 S 1160 400 1440 450 V700 H0Z" className="fill-[var(--dig-orange-500)] dark:fill-[var(--dig-orange-800)]" />
<path d="M0 560 C 300 520 560 560 820 530 S 1240 510 1440 540 V700 H0Z" className="fill-[var(--dig-orange-600)] dark:fill-[var(--dig-orange-900)]" />
<path
d="M760 700 C 760 640 620 620 660 580 S 860 540 820 500 S 700 470 760 440"
fill="none"
strokeWidth="16"
strokeLinecap="round"
className="stroke-[var(--dig-orange-200)] dark:stroke-[var(--dig-orange-700)]"
/>
{[300, 900, 1200].map((x, index) => (
<path key={x} d={`M${x} ${500 + index * 20} q 60 -30 140 -8`} fill="none" strokeWidth="2" className="stroke-[var(--dig-orange-400)] dark:stroke-[var(--dig-orange-700)]" />
))}
<g transform="translate(728 404) rotate(-8)">
<rect x="0" y="0" width="40" height="26" rx="3" className="fill-[var(--dig-orange-50)] dark:fill-[var(--dig-orange-200)]" />
<rect x="40" y="8" width="16" height="18" rx="3" className="fill-[var(--dig-orange-800)]" />
<rect x="44" y="11" width="9" height="7" rx="1.5" className="fill-[var(--dig-orange-100)]" />
<circle cx="10" cy="28" r="5" className="fill-[var(--dig-graphite-900)]" />
<circle cx="46" cy="28" r="5" className="fill-[var(--dig-graphite-900)]" />
</g>
</svg>
<div className="mx-auto flex w-full max-w-5xl flex-col gap-8 rounded-xl bg-card p-6 shadow-2xl sm:p-8">
<div className="grid grid-cols-2 gap-8 md:grid-cols-[1.4fr_1fr_1fr_1fr]">
<span className="col-span-2 flex items-start gap-2 text-xl font-black md:col-span-1">
<span aria-hidden className="flex size-8 items-center justify-center rounded-lg bg-[var(--dig-orange-500)] text-[var(--dig-white)]">
<TruckIcon className="size-4" />
</span>
باربَر
</span>
{COLUMNS.map((column) => (
<nav key={column.title} aria-label={column.title} className="flex flex-col gap-2.5 text-sm">
<span className="font-bold">{column.title}</span>
{column.links.map((link) => (
<a key={link} href="#" className="text-muted-foreground hover:text-foreground">
{link}
</a>
))}
</nav>
))}
</div>
<div className="flex flex-wrap items-center justify-between gap-4 border-t border-border pt-6">
<span className="text-sm text-muted-foreground">© ۱۴۰۵ باربَر. همهٔ حقوق محفوظ است.</span>
<div className="flex gap-1">
{SOCIALS.map((social) => (
<Button key={social.label} variant="ghost" size="icon" radius="full" aria-label={social.label} asChild>
<a href="#">{social.icon}</a>
</Button>
))}
</div>
</div>
</div>
</footer>
</ControlSizeProvider>
)
}