لندینگِ معاملهٔ هوشمند
پیشنمایش تمامصفحهلندینگِ سفید و آبی برای پلتفرمِ معامله با عاملهای هوشمند: پیشنمایشِ گفتوگو و گردشکارِ گرهای، کادرِ امتحان با پیشنهادها، منابعِ داده، کارتهای پرسش با نمودار، سه اصلِ کنترل، پلنها و فراخوان.
۱. نصب کامپوننتها
این بلاک از ۸ آیتم دیگ استفاده میکند: badgebuttonchart-presetscontrol-sizeiconsprompt-inputrevealtoggle-group
پکیجمنیجر پیشفرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیجمنیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/chart-presets.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/prompt-input.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.jsonpnpm dlx digdesign@latest add https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/chart-presets.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/prompt-input.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.jsonyarn dlx digdesign@latest add https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/chart-presets.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/prompt-input.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.jsonbunx --bun digdesign@latest add https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/chart-presets.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/prompt-input.json https://docs.digdesign.ir/r/reveal.json https://docs.digdesign.ir/r/toggle-group.json۲. کد صفحه
کد را در app/<route>/page.tsx بگذارید و متنها، داده و هندلرها را با محصول خودتان عوض کنید.
landing-trading.tsx
"use client"
import * as React from "react"
import { ArrowUpIcon, BarChartIcon, CheckIcon, EyeOffIcon, FlashIcon, GlobeIcon, ShieldCheckIcon, SparklesIcon, TrendingUpIcon } from "@/components/icons"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { AreaChart } from "@/components/ui/chart-presets"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { PromptInput, PromptInputSubmitButton, PromptInputTextarea, PromptInputToolbar, PromptInputTools } from "@/components/ui/prompt-input"
import { Reveal } from "@/components/ui/reveal"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { cn } from "@/lib/utils"
const SUGGESTIONS = ["اگر طلا ٪۲ افت کرد، بخر", "هر روز گزارشِ سبد را بفرست", "سهامِ پربازدهترِ هفته", "هشدارِ نوسانِ دلار"]
const PRICE = [
{ t: "۹", v: 182 },
{ t: "۱۰", v: 186 },
{ t: "۱۱", v: 184 },
{ t: "۱۲", v: 191 },
{ t: "۱۳", v: 189 },
{ t: "۱۴", v: 196 },
{ t: "۱۵", v: 201 },
]
const SOURCES = ["بورسِ تهران", "فرابورس", "بورسِ کالا", "بازارِ طلا", "صرافیِ ملی", "صندوقها"]
const PLANS = [
{ name: "شروع", month: 290, text: "برای امتحانِ ایدهها روی معاملهٔ آزمایشی.", features: ["۳ عاملِ فعال", "دادهٔ تأخیری", "معاملهٔ آزمایشی"], featured: false },
{ name: "حرفهای", month: 790, text: "برای معاملهگرِ فعال با دادهٔ لحظهای.", features: ["۲۰ عاملِ فعال", "دادهٔ لحظهای", "اتصال به کارگزاری", "هشدارِ پیامکی"], featured: true },
{ name: "سبدگردان", month: 2390, text: "برای تیم و صندوق با سقفِ بالا.", features: ["عاملِ نامحدود", "چند حساب", "گزارشِ حسابرسی", "پشتیبانیِ اختصاصی"], featured: false },
]
/**
* لندینگِ پلتفرمِ معاملهٔ هوشمند، سفید و آبی: هیرو با پیشنمایشِ اپ (گفتوگو و گردشکارِ
* گرهای)، کادرِ «امتحان کن» با پیشنهادها، شبکهٔ منابعِ داده، کارتهای «بپرس، نمودار بگیر» با
* نمودارِ واقعی، سه اصلِ کنترل، پلنها با سوییچِ ماهانه/سالانه و فراخوانِ پایانی.
*/
export default function LandingTradingBlock() {
const [prompt, setPrompt] = React.useState("")
const [billing, setBilling] = React.useState("month")
return (
<ControlSizeProvider size="xl" asChild>
<main className="flex w-full flex-col">
<section className="mx-auto grid w-full max-w-6xl grid-cols-1 gap-6 px-4 pt-20 sm:px-6 lg:grid-cols-[1.2fr_1fr] lg:items-end">
<div className="flex flex-col items-start gap-5">
<Badge color="info" variant="soft">
تازه: عاملهای چندمرحلهای
</Badge>
<h1 className="text-4xl leading-tight font-black text-balance sm:text-6xl sm:leading-tight">پلتفرمِ معاملهٔ هوشمند</h1>
</div>
<div className="flex flex-col items-start gap-4">
<p className="leading-8 text-muted-foreground">ایدهات را به زبانِ ساده بگو؛ عاملها داده را میخوانند، استراتژی را آزمایش میکنند و با اجازهٔ تو معامله میکنند.</p>
<Button className="[--primary-foreground:var(--dig-white)] [--primary:var(--dig-blue-600)]">
شروعِ رایگان
<ArrowUpIcon aria-hidden className="-rotate-45" />
</Button>
</div>
</section>
<Reveal className="mx-auto mt-12 w-full max-w-6xl px-4 sm:px-6">
<div className="grid grid-cols-1 gap-3 rounded-xl border border-border bg-subtle p-3 shadow-xl md:grid-cols-[18rem_1fr]">
<div className="flex flex-col gap-3 rounded-lg bg-card p-4">
<span className="text-xs text-muted-foreground">گفتوگو</span>
<p className="rounded-lg bg-muted p-3 text-sm leading-6">اگر قیمتِ طلا زیرِ میانگینِ ۲۰ روزه رفت، با ٪۱۰ سبد بخر و حدِ ضرر ٪۳ بگذار.</p>
<p className="flex items-start gap-2 text-sm leading-6 text-muted-foreground">
<SparklesIcon aria-hidden className="mt-1 size-4 shrink-0 text-[var(--dig-blue-600)]" />
استراتژی ساخته شد. روی دادهٔ دو سالِ اخیر ٪۱۸ بازده داشت. اجرا کنم؟
</p>
<div className="mt-auto flex gap-2">
<Button size="sm" className="[--primary-foreground:var(--dig-white)] [--primary:var(--dig-blue-600)]">
اجرا
</Button>
<Button size="sm" variant="outline">
ویرایش
</Button>
</div>
</div>
<div aria-hidden className="relative min-h-72 overflow-hidden rounded-lg bg-card bg-[radial-gradient(var(--border)_1px,transparent_1px)] [background-size:16px_16px]">
{[
{ x: "8%", y: "18%", label: "دادهٔ طلا", icon: <BarChartIcon /> },
{ x: "40%", y: "42%", label: "میانگینِ ۲۰ روزه", icon: <TrendingUpIcon /> },
{ x: "70%", y: "16%", label: "شرطِ خرید", icon: <FlashIcon /> },
{ x: "66%", y: "70%", label: "سفارشِ خرید", icon: <CheckIcon /> },
].map((node, index) => (
<span
key={node.label}
className={cn(
"absolute flex items-center gap-2 rounded-lg border bg-card px-3 py-2 text-xs font-semibold shadow-sm [&>svg]:size-4",
index === 3 ? "border-[var(--dig-blue-500)] text-[var(--dig-blue-700)] dark:text-[var(--dig-blue-300)]" : "border-border"
)}
style={{ insetInlineStart: node.x, top: node.y }}
>
{node.icon}
{node.label}
</span>
))}
<svg className="absolute inset-0 size-full" viewBox="0 0 100 100" preserveAspectRatio="none">
<path d="M22 26 C 32 26 34 48 42 48 M58 48 C 66 48 66 24 72 24 M80 30 C 84 50 78 60 74 74" fill="none" strokeWidth="0.4" strokeDasharray="1.5 1" className="stroke-[var(--dig-blue-400)]" />
</svg>
</div>
</div>
</Reveal>
<section aria-labelledby="lt-try" className="mx-auto flex w-full max-w-3xl flex-col items-center gap-6 px-4 py-24 text-center sm:px-6">
<h2 id="lt-try" className="text-3xl font-black sm:text-4xl">
امتحانش کن، رایگان است
</h2>
<p className="text-muted-foreground">یک استراتژی بنویس؛ پیش از هر معامله، نتیجهاش روی گذشته را میبینی.</p>
<PromptInput value={prompt} onValueChange={setPrompt} className="w-full text-start">
<PromptInputTextarea placeholder="مثلاً: هر وقت دلار از ۹۰ هزار بالاتر رفت خبرم کن" />
<PromptInputToolbar>
<PromptInputTools />
<PromptInputSubmitButton />
</PromptInputToolbar>
</PromptInput>
<div className="flex flex-wrap justify-center gap-2">
{SUGGESTIONS.map((item) => (
<Button key={item} size="sm" variant="outline" radius="full" onClick={() => setPrompt(item)}>
{item}
</Button>
))}
</div>
</section>
<section aria-labelledby="lt-data" className="bg-subtle px-4 py-20 sm:px-6">
<div className="mx-auto flex w-full max-w-6xl flex-col gap-10">
<div className="flex max-w-xl flex-col gap-3">
<h2 id="lt-data" className="text-3xl font-black sm:text-4xl">
همهٔ دادهای که عاملها لازم دارند
</h2>
<p className="text-muted-foreground">قیمتِ لحظهای، صورتهای مالی و اخبار، از منابعِ رسمی و یکپارچه.</p>
</div>
<ul className="grid grid-cols-2 gap-px overflow-hidden rounded-xl border border-border bg-border md:grid-cols-3">
{SOURCES.map((source) => (
<li key={source} className="flex items-center gap-3 bg-card p-6 font-bold">
<span aria-hidden className="flex size-9 items-center justify-center rounded-lg bg-[var(--dig-blue-100)] text-[var(--dig-blue-700)] dark:bg-[var(--dig-blue-950)] dark:text-[var(--dig-blue-300)]">
<GlobeIcon className="size-4" />
</span>
{source}
</li>
))}
</ul>
</div>
</section>
<section aria-labelledby="lt-ask" className="mx-auto flex w-full max-w-6xl flex-col gap-10 px-4 py-24 sm:px-6">
<h2 id="lt-ask" className="max-w-xl text-3xl font-black sm:text-4xl">
بپرس، نمودار بگیر
</h2>
<div className="grid grid-cols-1 gap-4 md:grid-cols-2">
<div className="flex flex-col gap-4 rounded-xl border border-border bg-card p-5">
<span className="self-end rounded-full bg-[var(--dig-blue-600)] px-3 py-1.5 text-sm text-[var(--dig-white)]">طلا امروز چطور بود؟</span>
<div className="flex items-baseline gap-2">
<span className="text-2xl font-black tabular-nums">۲۰۱ میلیون</span>
<span className="text-sm font-semibold text-success-subtle-foreground">+٪۱٫۸</span>
</div>
<AreaChart className="h-40" data={PRICE} categoryKey="t" series={[{ key: "v", label: "قیمت", color: "var(--dig-blue-500)" }]} smooth showPoints={false} hideValueAxis showGrid={false} />
</div>
<div className="flex flex-col gap-4 rounded-xl border border-border bg-card p-5">
<span className="self-end rounded-full bg-[var(--dig-blue-600)] px-3 py-1.5 text-sm text-[var(--dig-white)]">سبدم کجا ریسک دارد؟</span>
<ul className="flex flex-col gap-3">
{[
["سهامِ پالایشی", 46, true],
["طلا", 28, false],
["صندوقِ درآمد ثابت", 18, false],
["نقد", 8, false],
].map(([label, value, risky]) => (
<li key={String(label)} className="flex flex-col gap-1.5">
<span className="flex justify-between text-sm">
<span className="flex items-center gap-2">
{label}
{risky && (
<Badge color="warning" variant="soft" size="sm">
تمرکزِ بالا
</Badge>
)}
</span>
<span className="tabular-nums">٪{String(value).replace(/\d/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[Number(d)])}</span>
</span>
<span aria-hidden className="h-2 overflow-hidden rounded-full bg-muted">
<span className={cn("block h-full rounded-full", risky ? "bg-[var(--dig-amber-500)]" : "bg-[var(--dig-blue-500)]")} style={{ width: `${value}%` }} />
</span>
</li>
))}
</ul>
</div>
</div>
</section>
<section aria-labelledby="lt-control" className="mx-auto grid w-full max-w-6xl grid-cols-1 gap-8 border-t border-border px-4 py-20 sm:px-6 md:grid-cols-3">
<h2 id="lt-control" className="sr-only">
کنترل دستِ شماست
</h2>
{[
{ icon: <ShieldCheckIcon />, title: "بدونِ دسترسی به پول", text: "عامل فقط سفارش ثبت میکند؛ برداشت و انتقال ممکن نیست." },
{ icon: <EyeOffIcon />, title: "خصوصی، بهطورِ پیشفرض", text: "استراتژیها رمزگذاری میشوند و برای آموزشِ مدل استفاده نمیشوند." },
{ icon: <CheckIcon />, title: "با اجازهٔ شما", text: "سقفِ مبلغ و تأییدِ پیامکی برای هر معاملهٔ بزرگ." },
].map((item) => (
<div key={item.title} className="flex flex-col gap-3">
<span aria-hidden className="flex size-10 items-center justify-center rounded-lg bg-muted [&>svg]:size-5">
{item.icon}
</span>
<h3 className="font-bold">{item.title}</h3>
<p className="text-sm leading-6 text-muted-foreground">{item.text}</p>
</div>
))}
</section>
<section aria-labelledby="lt-plans" className="mx-auto flex w-full max-w-6xl flex-col gap-10 px-4 py-20 sm:px-6">
<div className="flex flex-col justify-between gap-4 md:flex-row md:items-end">
<h2 id="lt-plans" className="text-3xl font-black sm:text-4xl">
پلنِ مناسبِ استراتژیات
</h2>
<ToggleGroup type="single" variant="segmented" value={billing} onValueChange={(value) => value && setBilling(value as string)} aria-label="دورهٔ پرداخت">
<ToggleGroupItem value="month">ماهانه</ToggleGroupItem>
<ToggleGroupItem value="year">سالانه، دو ماه رایگان</ToggleGroupItem>
</ToggleGroup>
</div>
<ul className="grid grid-cols-1 gap-4 md:grid-cols-3">
{PLANS.map((plan) => {
const price = billing === "year" ? Math.round((plan.month * 10) / 12) : plan.month
return (
<li
key={plan.name}
className={cn(
"flex flex-col gap-6 rounded-xl border p-6",
plan.featured ? "border-transparent bg-[var(--dig-blue-600)] text-[var(--dig-white)] [--muted-foreground:var(--dig-blue-50)]" : "border-border bg-card"
)}
>
<div className="flex flex-col gap-2">
<span className="flex items-center justify-between font-bold">
{plan.name}
{plan.featured && <span className="rounded-full bg-[var(--dig-white)] px-2.5 py-0.5 text-xs text-[var(--dig-blue-700)]">پرطرفدار</span>}
</span>
<span className="text-sm leading-6 text-muted-foreground">{plan.text}</span>
</div>
<span className="flex items-baseline gap-1.5">
<span className="text-4xl font-black tabular-nums">{price.toLocaleString("fa-IR")}</span>
<span className="text-sm text-muted-foreground">هزار تومان / ماه</span>
</span>
<Button fullWidth variant={plan.featured ? "default" : "outline"} className={cn(plan.featured && "[--primary-foreground:var(--dig-blue-700)] [--primary:var(--dig-white)]")}>
شروع
</Button>
<ul className="flex flex-col gap-2.5 text-sm">
{plan.features.map((feature) => (
<li key={feature} className="flex items-center gap-2">
<CheckIcon aria-hidden className="size-4" />
{feature}
</li>
))}
</ul>
</li>
)
})}
</ul>
</section>
<section className="mx-auto flex w-full max-w-6xl flex-col items-start justify-between gap-6 border-t border-border px-4 py-20 sm:px-6 md:flex-row md:items-end">
<h2 className="max-w-md text-3xl leading-snug font-black sm:text-4xl">اولین استراتژیات را بنویس و امروز اجرا کن</h2>
<div className="flex gap-3">
<Button variant="outline">تماس با فروش</Button>
<Button className="[--primary-foreground:var(--dig-white)] [--primary:var(--dig-blue-600)]">شروعِ رایگان</Button>
</div>
</section>
</main>
</ControlSizeProvider>
)
}