بلاک‌ها · حساب کاربری

حالت‌های خالی

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

چهار حالتِ خالی با دلیل و قدمِ بعدیِ روشن: اولین بار (ساختن)، جست‌وجوی بی‌نتیجه (پاک‌کردنِ فیلتر)، خطای بارگذاری (تلاشِ دوباره) و نبودِ دسترسی (درخواست از مدیر).

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

این بلاک از ۴ آیتم دیگ استفاده می‌کند: buttoncontrol-sizeempty-stateicons

پکیج‌منیجر پیش‌فرض 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/empty-state.json https://docs.digdesign.ir/r/icons.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/empty-state.json https://docs.digdesign.ir/r/icons.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/empty-state.json https://docs.digdesign.ir/r/icons.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/empty-state.json https://docs.digdesign.ir/r/icons.json

۲. کد صفحه

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

empty-states.tsx
"use client"

import * as React from "react"

import { AlertTriangleIcon, EnvelopeIcon, PlusIcon, RefreshIcon, SearchIcon, ShieldCheckIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { EmptyState, EmptyStateActions, EmptyStateDescription, EmptyStateIcon, EmptyStateTitle } from "@/components/ui/empty-state"

const KINDS = [
  { value: "first", label: "اولین بار" },
  { value: "search", label: "بی‌نتیجه" },
  { value: "error", label: "خطا" },
  { value: "denied", label: "بی‌دسترسی" },
] as const

/**
 * حالت‌های خالی در یک جا: هر کدام دلیل را می‌گوید و یک قدمِ بعدی روشن پیشنهاد می‌دهد.
 * اولین بار (دعوت به ساختن)، جست‌وجوی بی‌نتیجه (پاک‌کردنِ فیلتر)، خطای بارگذاری (تلاشِ
 * دوباره) و نبودِ دسترسی (درخواست از مدیر). آیکون در کاشی رنگی ملایم.
 */
export default function EmptyStatesBlock() {
  const [retrying, setRetrying] = React.useState(false)

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="mx-auto flex w-full max-w-5xl flex-col gap-8 p-4 sm:p-6">
        <header className="flex flex-col gap-1">
          <h1 className="text-2xl font-bold">حالت‌های خالی</h1>
          <p className="text-muted-foreground">برای هر فهرست، جدول یا صفحه‌ای که ممکن است چیزی نشان ندهد.</p>
        </header>
        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
          <EmptyState variant="bordered" className="rounded-xl bg-card py-12" aria-label={KINDS[0].label}>
            <EmptyStateIcon className="bg-[color-mix(in_oklab,var(--dig-violet-500)_12%,var(--card))] text-[var(--dig-violet-600)]">
              <EnvelopeIcon />
            </EmptyStateIcon>
            <EmptyStateTitle>هنوز فاکتوری نساخته‌ای</EmptyStateTitle>
            <EmptyStateDescription>اولین فاکتور را بساز؛ کمتر از یک دقیقه وقت می‌گیرد و قالبش آماده است.</EmptyStateDescription>
            <EmptyStateActions>
              <Button>
                <PlusIcon />
                ساختِ فاکتور
              </Button>
            </EmptyStateActions>
          </EmptyState>

          <EmptyState variant="bordered" className="rounded-xl bg-card py-12" aria-label={KINDS[1].label}>
            <EmptyStateIcon className="bg-subtle text-muted-foreground">
              <SearchIcon />
            </EmptyStateIcon>
            <EmptyStateTitle>برای «فاکتورِ مهر» چیزی پیدا نشد</EmptyStateTitle>
            <EmptyStateDescription>املای کلمه را بررسی کن یا فیلترِ «فقط پرداخت‌نشده» را بردار.</EmptyStateDescription>
            <EmptyStateActions>
              <Button variant="outline">پاک‌کردنِ فیلترها</Button>
            </EmptyStateActions>
          </EmptyState>

          <EmptyState variant="bordered" className="rounded-xl bg-card py-12" aria-label={KINDS[2].label}>
            <EmptyStateIcon className="bg-[color-mix(in_oklab,var(--dig-red-500)_12%,var(--card))] text-destructive">
              <AlertTriangleIcon />
            </EmptyStateIcon>
            <EmptyStateTitle>فهرست بارگذاری نشد</EmptyStateTitle>
            <EmptyStateDescription>ارتباط با سرور قطع شد. داده‌هایت سالم است؛ دوباره امتحان کن.</EmptyStateDescription>
            <EmptyStateActions>
              <Button
                variant="outline"
                loading={retrying}
                onClick={() => {
                  setRetrying(true)
                  window.setTimeout(() => setRetrying(false), 900)
                }}
              >
                <RefreshIcon />
                تلاشِ دوباره
              </Button>
            </EmptyStateActions>
          </EmptyState>

          <EmptyState variant="bordered" className="rounded-xl bg-card py-12" aria-label={KINDS[3].label}>
            <EmptyStateIcon className="bg-[color-mix(in_oklab,var(--dig-orange-500)_12%,var(--card))] text-[var(--dig-orange-600)]">
              <ShieldCheckIcon />
            </EmptyStateIcon>
            <EmptyStateTitle>به گزارش‌های مالی دسترسی نداری</EmptyStateTitle>
            <EmptyStateDescription>این بخش فقط برای مدیر و حسابدار باز است. می‌توانی از مدیرِ تیم دسترسی بخواهی.</EmptyStateDescription>
            <EmptyStateActions>
              <Button variant="outline">درخواستِ دسترسی</Button>
            </EmptyStateActions>
          </EmptyState>
        </div>
      </main>
    </ControlSizeProvider>
  )
}