بلاک‌ها · معرفی محصول

قیمت به ازای کاربر

پیش‌نمایش تمام‌صفحه

قیمت‌گذاریِ وابسته به تعداد: اسلایدرِ تعدادِ کاربر، سگمنتِ ماهانه/سالانه و کارتِ تیرهٔ قیمتِ زنده با صرفه‌جوییِ سالانه.

۱. نصب کامپوننت‌ها

این بلاک از ۷ آیتم دیگ استفاده می‌کند: badgebuttoncontrol-sizeiconspersianslidertoggle-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/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/slider.json https://docs.digdesign.ir/r/toggle-group.json
pnpm 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/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/slider.json https://docs.digdesign.ir/r/toggle-group.json
yarn 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/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/slider.json https://docs.digdesign.ir/r/toggle-group.json
bunx --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/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/slider.json https://docs.digdesign.ir/r/toggle-group.json

۲. کد صفحه

کد را در app/<route>/page.tsx بگذارید و متن‌ها، داده و هندلرها را با محصول خودتان عوض کنید.

pricing-calculator.tsx
"use client"

import * as React from "react"

import { CheckIcon } from "@/components/icons"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Slider } from "@/components/ui/slider"
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"
import { formatCurrency, toFaDigits } from "@/lib/persian"

const PER_SEAT = 95_000
const INCLUDED = ["فاکتور و گزارشِ نامحدود", "اتصال به همهٔ بانک‌ها", "پشتیبانی آنلاین", "نسخهٔ پشتیبانِ روزانه"]

/**
 * قیمت‌گذاری وابسته به تعداد: اسلایدرِ تعدادِ کاربر و سگمنتِ ماهانه/سالانه، و کارتِ
 * تیره که قیمتِ هر ماه، تخفیفِ سالانه و جمعِ پرداخت را زنده نشان می‌دهد.
 */
export default function PricingCalculatorBlock() {
  const [seats, setSeats] = React.useState([8])
  const [period, setPeriod] = React.useState("yearly")
  const yearly = period === "yearly"
  const monthly = seats[0] * PER_SEAT * (yearly ? 0.8 : 1)

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="mx-auto flex w-full max-w-5xl flex-col gap-12 px-4 py-20 sm:px-6">
        <header className="mx-auto flex max-w-2xl flex-col items-center gap-3 text-center">
          <h1 className="text-4xl font-black text-balance">فقط به اندازهٔ تیمت پول بده</h1>
          <p className="text-lg leading-8 text-muted-foreground">هر کاربر {formatCurrency(PER_SEAT)} در ماه؛ همهٔ امکانات برای همه.</p>
        </header>
        <div className="grid grid-cols-1 items-stretch gap-6 md:grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)]">
          <section className="flex flex-col gap-10 rounded-xl border border-border bg-card p-6 sm:p-8">
            <div className="flex flex-col gap-5">
              <div className="flex items-baseline justify-between gap-2">
                <span id="pc-seats" className="font-medium">
                  تعدادِ کاربر
                </span>
                <span className="text-3xl font-black tabular-nums">{toFaDigits(seats[0])}</span>
              </div>
              <Slider aria-labelledby="pc-seats" value={seats} onValueChange={setSeats} min={1} max={50} />
              <div className="flex justify-between text-xs text-muted-foreground">
                <span>{toFaDigits(1)}</span>
                <span>{toFaDigits(50)}</span>
              </div>
            </div>
            <div className="flex flex-col gap-3">
              <span id="pc-period" className="font-medium">
                دورهٔ پرداخت
              </span>
              <ToggleGroup type="single" variant="segmented" value={period} onValueChange={(value) => value && setPeriod(value as string)} aria-labelledby="pc-period" className="w-full">
                <ToggleGroupItem value="monthly" className="flex-1">
                  ماهانه
                </ToggleGroupItem>
                <ToggleGroupItem value="yearly" className="flex-1 gap-2">
                  سالانه
                  <Badge variant="soft" color="success">
                    ٪۲۰ کمتر
                  </Badge>
                </ToggleGroupItem>
              </ToggleGroup>
            </div>
            <ul className="mt-auto flex flex-col gap-3 border-t border-border pt-6 text-sm">
              {INCLUDED.map((item) => (
                <li key={item} className="flex items-center gap-2">
                  <CheckIcon aria-hidden className="size-4 text-success" />
                  {item}
                </li>
              ))}
            </ul>
          </section>
          <section aria-live="polite" className="flex flex-col gap-6 rounded-xl bg-inverse p-6 text-[var(--dig-white)] [--border:var(--inverse-border)] [--muted-foreground:var(--dig-neutral-400)] [--primary-foreground:var(--dig-graphite-950)] [--primary:var(--dig-white)] sm:p-8">
            <span className="text-sm text-muted-foreground">هزینهٔ تو</span>
            <div className="flex items-baseline gap-2">
              <span className="text-4xl font-black tabular-nums">{formatCurrency(Math.round(monthly))}</span>
              <span className="text-muted-foreground">در ماه</span>
            </div>
            <dl className="flex flex-col gap-3 border-t border-border pt-6 text-sm">
              <div className="flex justify-between gap-2">
                <dt className="text-muted-foreground">پرداختِ {yearly ? "سالانه" : "ماهانه"}</dt>
                <dd className="tabular-nums">{formatCurrency(Math.round(yearly ? monthly * 12 : monthly))}</dd>
              </div>
              {yearly && (
                <div className="flex justify-between gap-2">
                  <dt className="text-muted-foreground">صرفه‌جویی</dt>
                  <dd className="text-[var(--dig-green-400)] tabular-nums">{formatCurrency(Math.round(seats[0] * PER_SEAT * 12 * 0.2))}</dd>
                </div>
              )}
            </dl>
            <Button fullWidth className="mt-auto">
              شروعِ ۱۴ روز رایگان
            </Button>
          </section>
        </div>
      </main>
    </ControlSizeProvider>
  )
}