نرخنامهٔ خدمات
پیشنمایش تمامصفحهبخشِ نرخنامه: سگمنتِ ساعتی/روزانه/ماهانه همهٔ نرخها را با تخفیفِ حجمی عوض میکند؛ هر ردیف تیتر، توضیح و نرخ، با برچسبِ پرطرفدار و پانویسِ شرایط.
۱. نصب کامپوننتها
این بلاک از ۵ آیتم دیگ استفاده میکند: badgebuttoncontrol-sizepersiantoggle-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/control-size.json https://docs.digdesign.ir/r/persian.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/control-size.json https://docs.digdesign.ir/r/persian.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/control-size.json https://docs.digdesign.ir/r/persian.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/control-size.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/toggle-group.json۲. کد صفحه
کد را در app/<route>/page.tsx بگذارید و متنها، داده و هندلرها را با محصول خودتان عوض کنید.
services-rate-card.tsx
"use client"
import * as React from "react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { formatCurrency } from "@/lib/persian"
const RATES = [
{ title: "مشاورهٔ فنی", text: "بازبینیِ معماری، کد یا زیرساخت", hour: 2_400_000, popular: false },
{ title: "طراحیِ محصول", text: "پژوهش، نقشهٔ صفحه و طراحیِ نهایی", hour: 1_800_000, popular: true },
{ title: "توسعهٔ فرانتاند", text: "پیادهسازی با کامپوننتهای دیگ", hour: 1_600_000, popular: false },
{ title: "نوشتنِ محتوا", text: "متنِ رابط، راهنما و صفحهٔ فرود", hour: 900_000, popular: false },
]
const UNITS = { hour: { label: "ساعتی", factor: 1, per: "هر ساعت" }, day: { label: "روزانه", factor: 7, per: "هر روز" }, month: { label: "ماهانه", factor: 140, per: "هر ماه" } }
/**
* جدولِ نرخِ خدمات: سگمنتِ ساعتی/روزانه/ماهانه همهٔ نرخها را با هم عوض میکند (روزانه و ماهانه
* با تخفیفِ حجمی)، هر ردیف تیتر، توضیح و نرخ دارد و پرطرفدار برچسب میخورد؛ پانویسِ شرایط و
* دکمهٔ رزروِ جلسه.
*/
export default function ServicesRateCardBlock() {
const [unit, setUnit] = React.useState<keyof typeof UNITS>("hour")
const current = UNITS[unit]
return (
<ControlSizeProvider size="xl" asChild>
<section aria-labelledby="rc-title" className="mx-auto flex w-full max-w-3xl flex-col gap-10 px-4 py-24 sm:px-6">
<div className="flex flex-col items-center gap-4 text-center">
<span className="text-sm font-semibold text-brand-secondary">نرخنامه</span>
<h2 id="rc-title" className="text-3xl font-black sm:text-4xl">
هزینهٔ همکاری
</h2>
<ToggleGroup type="single" variant="segmented" value={unit} onValueChange={(value) => value && setUnit(value as keyof typeof UNITS)} aria-label="واحدِ نرخ">
{Object.entries(UNITS).map(([key, item]) => (
<ToggleGroupItem key={key} value={key}>
{item.label}
</ToggleGroupItem>
))}
</ToggleGroup>
</div>
<div className="overflow-hidden rounded-xl border border-border bg-card">
<ul aria-live="polite" className="divide-y divide-border">
{RATES.map((rate) => {
const price = Math.round((rate.hour * current.factor * (unit === "hour" ? 1 : unit === "day" ? 0.92 : 0.85)) / 10_000) * 10_000
return (
<li key={rate.title} className="flex flex-wrap items-center justify-between gap-x-6 gap-y-2 p-5 sm:p-6">
<span className="flex flex-col gap-1">
<span className="flex items-center gap-2 font-bold">
{rate.title}
{rate.popular && (
<Badge color="violet" variant="soft" size="sm">
پرطرفدار
</Badge>
)}
</span>
<span className="text-sm text-muted-foreground">{rate.text}</span>
</span>
<span className="flex items-baseline gap-1.5">
<span className="text-xl font-black tabular-nums">{formatCurrency(price)}</span>
<span className="text-sm text-muted-foreground">{current.per}</span>
</span>
</li>
)
})}
</ul>
<div className="flex flex-col items-start justify-between gap-4 bg-subtle p-5 sm:flex-row sm:items-center sm:p-6">
<p className="text-sm leading-6 text-muted-foreground">نرخِ روزانه ۸٪ و ماهانه ۱۵٪ تخفیف دارد. پیشپرداخت ۳۰٪، بقیه پس از تحویل.</p>
<Button className="shrink-0">رزروِ جلسهٔ آشنایی</Button>
</div>
</div>
</section>
</ControlSizeProvider>
)
}