لندینگ اپ موبایل
پیشنمایش تمامصفحهمعرفیِ اپ: هیروی تیره با پترنِ نقطهای و گوشیِ واقعینما، دکمههای دانلود و کاربرانِ واقعی، ویژگیها با آیکونِ رنگی، سه قدمِ شروع، آمارِ شمارنده با نظرِ کاربر، پرسشها و دعوتِ پایانی.
۱. نصب کامپوننتها
این بلاک از ۱۱ آیتم دیگ استفاده میکند: accordionavatarbackground-patternbadgebuttoncontrol-sizecount-upfootericonspersianreveal
پکیجمنیجر پیشفرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیجمنیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/accordion.json https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/background-pattern.json https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/count-up.json https://docs.digdesign.ir/r/footer.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.jsonpnpm dlx digdesign@latest add https://docs.digdesign.ir/r/accordion.json https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/background-pattern.json https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/count-up.json https://docs.digdesign.ir/r/footer.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.jsonyarn dlx digdesign@latest add https://docs.digdesign.ir/r/accordion.json https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/background-pattern.json https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/count-up.json https://docs.digdesign.ir/r/footer.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.jsonbunx --bun digdesign@latest add https://docs.digdesign.ir/r/accordion.json https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/background-pattern.json https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/count-up.json https://docs.digdesign.ir/r/footer.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/reveal.json۲. کد صفحه
کد را در app/<route>/page.tsx بگذارید و متنها، داده و هندلرها را با محصول خودتان عوض کنید.
app-landing.tsx
"use client"
import * as React from "react"
import {
ArrowUpIcon,
BellIcon,
CheckIcon,
CreditCardIcon,
DownloadIcon,
ShieldCheckIcon,
StarIcon,
WalletIcon,
} from "@/components/icons"
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"
import { Avatar, AvatarGroup } from "@/components/ui/avatar"
import { DotPattern } from "@/components/ui/background-pattern"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { CountUp } from "@/components/ui/count-up"
import {
Footer,
FooterBottom,
FooterBrand,
FooterColumn,
FooterColumns,
FooterColumnTitle,
FooterContent,
FooterLink,
FooterLinkList,
} from "@/components/ui/footer"
import { Reveal } from "@/components/ui/reveal"
import { formatCurrency, toFaDigits } from "@/lib/persian"
import { stockImages } from "@/lib/stock-images"
const FEATURES = [
{ icon: <WalletIcon />, tone: "violet", title: "کیف پولِ یکپارچه", text: "موجودی همهٔ کارتها در یک صفحه، با دستهبندی خودکارِ هزینهها." },
{ icon: <CreditCardIcon />, tone: "blue", title: "کارتبهکارتِ بیکارمزد", text: "تا ۳ انتقال در روز بدونِ کارمزد، به همهٔ بانکها." },
{ icon: <BellIcon />, tone: "amber", title: "یادآورِ قسط و قبض", text: "یک روز قبل از سررسید خبرت میکنیم؛ دیگر جریمه نمیدهی." },
{ icon: <ShieldCheckIcon />, tone: "green", title: "امنیتِ بانکی", text: "ورودِ دومرحلهای، اثرِ انگشت و قفلِ آنی کارت از داخلِ اپ." },
]
const STEPS = [
{ title: "اپ را نصب کن", text: "از کافهبازار، مایکت یا مستقیم." },
{ title: "با کد ملی ثبتنام کن", text: "احرازِ هویت کمتر از دو دقیقه." },
{ title: "کارتهایت را وصل کن", text: "همهٔ حسابها در یک نگاه." },
]
const FAQ = [
{ q: "اپ رایگان است؟", a: "بله؛ نصب و استفاده رایگان است و فقط برای بعضی خدماتِ ویژه کارمزد میگیریم." },
{ q: "اطلاعاتِ کارتم امن است؟", a: "رمزها هرگز ذخیره نمیشوند و همهٔ ارتباطها رمزنگاریشدهاند." },
{ q: "روی آیفون هم نصب میشود؟", a: "بله؛ نسخهٔ وباپ روی آیفون و نسخهٔ کامل روی اندروید." },
]
/** پیشنمایشِ گوشی با صفحهٔ اصلی اپ (تزئینی)؛ توکنهای روشن را دوباره تعریف میکند چون داخلِ هیروی تیره است. */
function PhoneMock() {
return (
<div aria-hidden className="relative mx-auto w-64 rounded-[2.5rem] border-[10px] border-[var(--dig-graphite-950)] bg-[var(--dig-white)] text-[var(--dig-graphite-900)] shadow-overlay sm:w-72 [--border:var(--dig-neutral-200)] [--card:var(--dig-white)] [--foreground:var(--dig-graphite-900)] [--muted-foreground:var(--dig-neutral-500)] [--muted:var(--dig-neutral-100)]">
<div className="mx-auto mt-2 h-5 w-24 rounded-full bg-inverse" />
<div className="flex flex-col gap-4 p-4">
<div className="flex items-center justify-between">
<span className="text-sm font-semibold">سلام، سارا</span>
<Avatar size="sm" alt="" src={stockImages.personWoman3.src} />
</div>
<div className="flex flex-col gap-1 rounded-xl bg-[var(--dig-violet-700)] p-4 text-[var(--dig-white)]">
<span className="text-xs text-[var(--dig-violet-200)]">موجودی کل</span>
<span className="text-xl font-bold tabular-nums">{formatCurrency(48_250_000)}</span>
<span className="mt-2 flex items-center gap-1 text-xs text-[var(--dig-green-300)]">
<ArrowUpIcon className="size-3" />
۱۲٪ نسبت به ماهِ قبل
</span>
</div>
<div className="grid grid-cols-3 gap-2 text-center text-xs">
{["انتقال", "قبض", "شارژ"].map((label) => (
<span key={label} className="flex flex-col items-center gap-1.5 rounded-lg bg-muted py-3">
<span className="size-6 rounded-full bg-[color-mix(in_oklab,var(--dig-violet-500)_18%,var(--card))]" />
{label}
</span>
))}
</div>
<div className="flex flex-col gap-2">
{[
{ title: "کافه رست", amount: -185_000 },
{ title: "واریزِ حقوق", amount: 32_000_000 },
{ title: "اسنپ", amount: -96_000 },
].map((row) => (
<span key={row.title} className="flex items-center justify-between rounded-lg border border-border px-3 py-2 text-xs">
<span className="font-medium">{row.title}</span>
<span className={row.amount > 0 ? "font-semibold text-success tabular-nums" : "font-semibold tabular-nums"}>
{row.amount > 0 ? "+" : "−"}
{formatCurrency(Math.abs(row.amount))}
</span>
</span>
))}
</div>
</div>
</div>
)
}
/**
* لندینگِ اپِ موبایل: هیروی تیره با گوشی واقعینما و دکمههای دانلود، ویژگیها با
* آیکونِ رنگی، سه قدمِ شروع، آمارِ شمارنده، نظرِ کاربران، پرسشها و دعوتِ پایانی.
*/
export default function AppLandingBlock() {
return (
<ControlSizeProvider size="xl" asChild>
<div className="flex min-h-svh flex-col bg-background">
{/* قهرمانِ تیره با پترنِ نقطهای؛ متن در شروع و گوشی در پایان. */}
<section className="relative overflow-hidden bg-inverse text-[var(--dig-white)] [--background:var(--inverse)] [--border:var(--inverse-border)] [--foreground:var(--dig-white)] [--muted-foreground:var(--dig-neutral-400)] [--primary-foreground:var(--dig-graphite-950)] [--primary:var(--dig-white)]">
<DotPattern size={22} />
<span aria-hidden className="absolute -end-32 top-24 size-[28rem] rounded-full bg-[var(--dig-violet-800)] blur-3xl" />
<header className="relative mx-auto flex h-16 w-full max-w-6xl items-center justify-between px-4 sm:px-6">
<span className="flex items-center gap-2 text-lg font-black">
<span aria-hidden className="size-7 rounded-lg bg-[var(--dig-violet-500)]" />
سکه
</span>
<nav aria-label="ناوبری اصلی" className="hidden gap-6 text-sm text-muted-foreground md:flex">
{["امکانات", "امنیت", "پرسشها"].map((item) => (
<a key={item} href="#" className="transition-colors hover:text-foreground">
{item}
</a>
))}
</nav>
</header>
<div className="relative mx-auto grid grid-cols-1 w-full max-w-6xl items-center gap-12 px-4 pt-12 pb-20 sm:px-6 lg:grid-cols-2 lg:pt-16 lg:pb-28">
<div className="flex flex-col gap-6">
<Badge variant="outline" className="self-start border-inverse-border bg-inverse-raised text-[var(--dig-white)]">
<StarIcon className="size-3.5 fill-current text-[var(--dig-amber-400)]" />
امتیازِ ۴٫۸ در کافهبازار
</Badge>
<h1 className="text-4xl leading-snug font-black sm:text-6xl sm:leading-snug">همهٔ پولت، در یک اپ.</h1>
<p className="max-w-lg text-lg leading-8 text-muted-foreground">
موجودی، انتقال، قبض و قسط؛ ساده، سریع و امن. بیش از نیم میلیون نفر هر روز با سکه حسابوکتاب میکنند.
</p>
<div className="mt-2 flex flex-wrap gap-3">
<Button>
<DownloadIcon />
دانلود از کافهبازار
</Button>
<Button variant="outline" className="border-inverse-border bg-inverse-raised text-[var(--dig-white)] hover:bg-inverse-border hover:text-[var(--dig-white)]">
نسخهٔ آیفون
</Button>
</div>
<div className="mt-2 flex items-center gap-3 text-sm text-muted-foreground">
<AvatarGroup>
{[stockImages.personMan1, stockImages.personWoman1, stockImages.personMan2].map((photo) => (
<Avatar key={photo.src} size="sm" alt="" src={photo.src} className="ring-2 ring-inverse" />
))}
</AvatarGroup>
بیش از ۵۰۰ هزار کاربرِ فعال
</div>
</div>
<PhoneMock />
</div>
</section>
<main className="flex flex-col">
{/* ویژگیها: چهار کارت با کاشی آیکونِ رنگی. */}
<section aria-labelledby="app-features" className="mx-auto flex w-full max-w-6xl flex-col gap-12 px-4 py-24 sm:px-6">
<div className="flex max-w-2xl flex-col gap-3">
<h2 id="app-features" className="text-3xl font-black sm:text-4xl">
چیزهایی که هر روز لازم داری
</h2>
<p className="text-lg leading-8 text-muted-foreground">بدونِ رفتن به شعبه و بدونِ اپهای جداجدا.</p>
</div>
<ul className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
{FEATURES.map((feature, index) => (
<Reveal asChild key={feature.title} delay={index * 100}>
<li className="flex flex-col gap-4 rounded-xl border border-border bg-card p-6 transition-[opacity,translate,box-shadow] hover:shadow-card">
<span
aria-hidden
className="flex size-11 items-center justify-center rounded-xl [&>svg]:size-5"
style={{ background: `color-mix(in oklab, var(--dig-${feature.tone}-500) 12%, var(--card))`, color: `var(--dig-${feature.tone}-600)` }}
>
{feature.icon}
</span>
<span className="font-bold">{feature.title}</span>
<span className="text-sm leading-7 text-muted-foreground">{feature.text}</span>
</li>
</Reveal>
))}
</ul>
</section>
{/* سه قدم با شمارههای بزرگ و خطِ اتصال. */}
<section aria-labelledby="app-steps" className="bg-muted py-24">
<div className="mx-auto flex w-full max-w-6xl flex-col gap-12 px-4 sm:px-6">
<div className="flex max-w-2xl flex-col gap-3">
<h2 id="app-steps" className="text-3xl font-black sm:text-4xl">
در سه قدم شروع کن
</h2>
<p className="text-lg leading-8 text-muted-foreground">کمتر از پنج دقیقه از نصب تا اولین انتقال.</p>
</div>
<ol className="grid grid-cols-1 gap-8 md:grid-cols-3">
{STEPS.map((step, index) => (
<Reveal asChild key={step.title} delay={index * 100}>
<li className="flex flex-col gap-3 border-t-2 border-[var(--dig-violet-500)] pt-6">
<span className="text-4xl font-black text-[var(--dig-violet-600)] tabular-nums">{toFaDigits(index + 1)}</span>
<span className="text-lg font-bold">{step.title}</span>
<span className="text-muted-foreground">{step.text}</span>
</li>
</Reveal>
))}
</ol>
</div>
</section>
{/* آمار با شمارنده و نظرِ یک کاربر کنارش. */}
<section className="mx-auto grid grid-cols-1 w-full max-w-6xl gap-6 px-4 py-24 sm:px-6 lg:grid-cols-[1fr_1.2fr]">
<dl className="grid grid-cols-2 gap-4">
{[
{ value: 500, suffix: "+ هزار", label: "کاربرِ فعال" },
{ value: 4.8, decimals: 1, label: "امتیاز در استورها" },
{ value: 12, suffix: "+ میلیون", label: "تراکنشِ ماهانه" },
{ value: 99.9, decimals: 1, suffix: "٪", label: "دسترسپذیری" },
].map((stat) => (
<div key={stat.label} className="flex flex-col gap-1 rounded-xl border border-border p-6">
<dt className="order-2 text-sm text-muted-foreground">{stat.label}</dt>
<dd className="text-3xl font-black">
<CountUp value={stat.value} decimals={stat.decimals ?? 0} suffix={stat.suffix} />
</dd>
</div>
))}
</dl>
<figure className="flex flex-col justify-between gap-8 rounded-xl bg-[var(--dig-violet-800)] p-8 text-[var(--dig-white)] [--muted-foreground:var(--dig-violet-200)]">
<span className="flex gap-0.5 text-[var(--dig-amber-400)]" role="img" aria-label="امتیاز ۵ از ۵">
{[0, 1, 2, 3, 4].map((star) => (
<StarIcon key={star} className="size-5 fill-current" aria-hidden />
))}
</span>
<blockquote className="text-xl leading-9 font-bold">
«اولین اپی که واقعاً میفهمم پولم کجا میرود. یادآورِ قسط هم چند بار نجاتم داده.»
</blockquote>
<figcaption className="flex items-center gap-3">
<Avatar alt="لیلا احمدی" src={stockImages.personWoman2.src} />
<span className="flex flex-col">
<span className="font-semibold">لیلا احمدی</span>
<span className="text-sm text-muted-foreground">کاربرِ سکه از ۱۴۰۲</span>
</span>
</figcaption>
</figure>
</section>
<section aria-labelledby="app-faq" className="mx-auto grid grid-cols-1 w-full max-w-6xl gap-12 px-4 pb-24 sm:px-6 lg:grid-cols-[1fr_1.4fr]">
<div className="flex flex-col gap-3">
<h2 id="app-faq" className="text-3xl font-black sm:text-4xl">
پرسشهای رایج
</h2>
<p className="text-lg leading-8 text-muted-foreground">جوابت اینجا نیست؟ داخلِ اپ با پشتیبانی گفتوگو کن.</p>
</div>
<Accordion type="single" collapsible variant="soft" indicator="plus" defaultValue={FAQ[0].q}>
{FAQ.map((item) => (
<AccordionItem key={item.q} value={item.q}>
<AccordionTrigger className="text-base font-semibold">{item.q}</AccordionTrigger>
<AccordionContent className="leading-8 text-muted-foreground">{item.a}</AccordionContent>
</AccordionItem>
))}
</Accordion>
</section>
{/* دعوتِ پایانی روی کارتِ بنفش. */}
<section className="mx-auto w-full max-w-6xl px-4 pb-24 sm:px-6">
<div className="flex flex-col items-start gap-6 rounded-xl bg-[var(--dig-violet-700)] p-8 text-[var(--dig-white)] sm:flex-row sm:items-center sm:justify-between sm:p-12 [--muted-foreground:var(--dig-violet-100)] [--primary-foreground:var(--dig-violet-800)] [--primary:var(--dig-white)]">
<div className="flex flex-col gap-2">
<h2 className="text-3xl font-black">همین امروز نصبش کن</h2>
<p className="flex items-center gap-2 text-muted-foreground">
<CheckIcon className="size-4" aria-hidden />
رایگان، بدونِ مراجعهٔ حضوری
</p>
</div>
<Button>
<DownloadIcon />
دانلود اپ
</Button>
</div>
</section>
</main>
<Footer>
<FooterContent>
<FooterBrand>
<span className="text-lg font-black">سکه</span>
<p className="text-sm text-muted-foreground">اپِ مدیریتِ مالی شخصی.</p>
</FooterBrand>
<FooterColumns>
<FooterColumn>
<FooterColumnTitle>اپ</FooterColumnTitle>
<FooterLinkList>
<FooterLink href="#">امکانات</FooterLink>
<FooterLink href="#">امنیت</FooterLink>
</FooterLinkList>
</FooterColumn>
<FooterColumn>
<FooterColumnTitle>پشتیبانی</FooterColumnTitle>
<FooterLinkList>
<FooterLink href="#">پرسشها</FooterLink>
<FooterLink href="#">تماس</FooterLink>
</FooterLinkList>
</FooterColumn>
</FooterColumns>
</FooterContent>
<FooterBottom>
<span>© {toFaDigits(1405)} سکه</span>
</FooterBottom>
</Footer>
</div>
</ControlSizeProvider>
)
}