کیف پولِ ساده
پیشنمایش تمامصفحهکارتِ وسطچین با موجودیِ درشت (نمایش/پنهان)، سه اقدامِ اصلی و سه تراکنشِ آخر؛ برای اپهایی که کیف پول جانبی است.
۱. نصب کامپوننتها
این بلاک از ۴ آیتم دیگ استفاده میکند: buttoncontrol-sizeiconspersian
پکیجمنیجر پیشفرض 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/persian.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/persian.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/persian.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/persian.json۲. کد صفحه
کد را در app/<route>/page.tsx بگذارید و متنها، داده و هندلرها را با محصول خودتان عوض کنید.
wallet-simple.tsx
"use client"
import * as React from "react"
import { ArrowUpIcon, EyeIcon, EyeOffIcon, PlusIcon, ReceiptIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { formatCurrency, formatNumber } from "@/lib/persian"
const RECENT = [
{ title: "خرید از کافه رست", time: "امروز ۱۰:۲۴", amount: -185_000 },
{ title: "افزایشِ موجودی", time: "دیروز", amount: 2_000_000 },
{ title: "قبضِ برق", time: "۱۲ مهر", amount: -412_000 },
]
/**
* کیف پولِ ساده: یک کارتِ وسطچین با موجودی درشت (نمایش/پنهان)، سه اقدامِ اصلی
* (افزایش، انتقال، پرداختِ قبض) و سه تراکنشِ آخر با «همه»؛ برای اپهایی که کیف پول جانبی است.
*/
export default function WalletSimpleBlock() {
const [hidden, setHidden] = React.useState(false)
return (
<ControlSizeProvider size="xl" asChild>
<main className="mx-auto flex w-full max-w-md flex-col gap-8 p-4 py-10 sm:p-6">
<h1 className="sr-only">کیف پول</h1>
<section aria-label="موجودی" className="flex flex-col items-center gap-2 text-center">
<span className="text-sm text-muted-foreground">موجودی کیف پول</span>
<div className="flex items-center gap-2">
<span className="text-4xl font-black tabular-nums">{hidden ? "••••••" : formatCurrency(1_345_000)}</span>
<Button variant="ghost" size="icon" aria-label={hidden ? "نمایشِ موجودی" : "پنهانکردنِ موجودی"} aria-pressed={hidden} onClick={() => setHidden((value) => !value)}>
{hidden ? <EyeIcon /> : <EyeOffIcon />}
</Button>
</div>
</section>
<div className="grid grid-cols-3 gap-3">
{[
{ label: "افزایش", icon: <PlusIcon />, primary: true },
{ label: "انتقال", icon: <ArrowUpIcon className="rotate-45" /> },
{ label: "قبض", icon: <ReceiptIcon /> },
].map((action) => (
<Button key={action.label} variant={action.primary ? "default" : "outline"} className="h-auto flex-col gap-2 py-4">
{action.icon}
{action.label}
</Button>
))}
</div>
<section aria-labelledby="ws-recent" className="flex flex-col gap-2">
<div className="flex items-center justify-between">
<h2 id="ws-recent" className="font-bold">
آخرین تراکنشها
</h2>
<Button variant="ghost">همه</Button>
</div>
<ul className="flex flex-col divide-y divide-border rounded-xl border border-border bg-card">
{RECENT.map((item) => (
<li key={item.title} className="flex min-h-16 items-center justify-between gap-3 px-4">
<span className="flex flex-col">
<span className="font-medium">{item.title}</span>
<span className="text-xs text-muted-foreground">{item.time}</span>
</span>
<span className={`font-bold tabular-nums ${item.amount > 0 ? "text-success" : ""}`}>
<bdi dir="ltr">
{item.amount > 0 ? "+" : "−"}
{formatNumber(Math.abs(item.amount))}
</bdi>
</span>
</li>
))}
</ul>
</section>
</main>
</ControlSizeProvider>
)
}