قالب صفحهٔ کمکی (UtilityPage)

صفحه‌ای که محتوای خودش را ندارد — پیدا نشد، دسترسی ندارید، خطا، خالیِ اول‌کار، به‌روزرسانی — با یک عنوان، یک توضیح و حداکثر یک اقدام در مرکز قاب

معرفی

UtilityPage قالب صفحه‌ای است که چیزی از خودش برای نشان دادن ندارد: یک آیکون، عنوان صفحه (تنها h1)، یک توضیح و حداکثر یک اقدام، در عرض باریک و در مرکز ناحیهٔ محتوای قاب. شش نوع دارد:

kindکیعنوان پیش‌فرض
404نشانی وجود ندارد«صفحه پیدا نشد»
403کاربر اجازهٔ دیدن این صفحه را ندارد«به این صفحه دسترسی ندارید»
500صفحه به‌خاطر خطا بارگذاری نشد«مشکلی پیش آمد»
emptyبخش تازه است و هنوز هیچ چیزی در آن ساخته نشدهندارد: title را بدهید
maintenanceبخش موقتاً در دسترس نیست«در حال به‌روزرسانی هستیم»
loadingانتظار تمام‌صفحه پیش از هر صفحه‌ای (ورود، هدایت)«لحظه‌ای صبر کنید»

چه زمانی استفاده کنیم:

  • app/not-found.tsx در Next.js (kind="404")، و صفحه‌ای که کاربر به آن دسترسی ندارد (kind="403").
  • صفحه‌ای از منو که هنوز هیچ چیزی در آن نیست (kind="empty")، مثل «گزارش‌ها» پیش از اولین گزارش.
  • انتظاری تمام‌صفحه پیش از آن‌که صفحه‌ای وجود داشته باشد، مثل ورود کاربر در مینی‌اپ (kind="loading" title="در حال ورود…"). صفحه مشغول (aria-busy) و متنش وضعیت (role="status") اعلام می‌شود.

چه زمانی استفاده نکنیم:

  • فهرستی که با فیلتر خالی شده یا هنوز موردی ندارد ولی ابزارهای فهرست (جست‌وجو، فیلتر) را لازم دارد: حالت empty در ListPage.
  • خطای بارگذاری یک بلوک که با تلاش دوباره حل می‌شود: حالت error همان صفحه.
  • صفحه‌ای که محتوایش در حال بارگذاری است: حالت loading قالب همان صفحه، نه UtilityPage kind="loading".
  • اقدامی که کاربر اجازه‌اش را ندارد در صفحه‌ای که می‌بیند: همان اقدام، غیرفعال با دلیلش (GatedAction)، نه صفحهٔ 403.

استفاده

// app/not-found.tsx — با قاب در app/(app)/layout.tsx، بازگشتی را در <Frame> بپیچید.
import Link from 'next/link'
import { Button } from '@partodata/ui'
import { UtilityPage } from '@partodata/ui/templates'

export default function NotFound() {
  return (
    <UtilityPage
      kind="404"
      action={
        <Button asChild>
          <Link href="/">بازگشت به صفحهٔ اصلی</Link>
        </Button>
      }
    />
  )
}
// app/reports/page.tsx — هنوز چیزی در محصول گزارش نمی‌سازد: بی اقدام
import { UtilityPage } from '@partodata/ui/templates'

export default function ReportsPage() {
  return (
    <UtilityPage
      kind="empty"
      title="هنوز گزارشی ساخته نشده است"
      description="گزارش‌ها خلاصهٔ دوره‌ای منشن‌ها و روند گفت‌وگوها هستند و پس از راه‌اندازی این بخش، این‌جا فهرست می‌شوند."
    />
  )
}
// app/reports/page.tsx — وقتی صفحهٔ دیگری اولین گزارش را می‌سازد: اقدام، پیوند به آن‌جاست
import Link from 'next/link'
import { Button } from '@partodata/ui'
import { UtilityPage } from '@partodata/ui/templates'

export default function ReportsPage() {
  return (
    <UtilityPage
      kind="empty"
      title="هنوز گزارشی ساخته نشده است"
      description="گزارش‌ها از منشن‌های فیلترشده ساخته می‌شوند. از صفحهٔ منشن‌ها شروع کنید."
      action={
        <Button asChild>
          <Link href="/mentions">رفتن به منشن‌ها</Link>
        </Button>
      }
    />
  )
}

حالت‌ها و انواع

صفحهٔ پیدانشده

متن‌ها

برای 404، 403، 500، maintenance و loading عنوان و توضیح پیش‌فرض دارند و می‌توانید عوضشان کنید. empty متن پیش‌فرض ندارد و title و description در نوعش الزامی‌اند (بی آن‌ها کد کامپایل نمی‌شود): عنوان وضعیت را می‌گوید، نه نام صفحه («هنوز گزارشی ساخته نشده است»، نه «گزارش‌ها» — منو نام صفحه را دارد)، و توضیح می‌گوید این بخش چیست و چه انتظاری باید داشت.

اقدام

action یک Button بدون variant است — تنها اقدام اصلی صفحه — و فقط وقتی کار می‌کند: پیوندی (<Button asChild><Link href>…</Link></Button>) به جایی که اولین مورد ساخته می‌شود یا به داشبورد، یا onClickای که اولین مورد را می‌سازد. وقتی هنوز چیزی در محصول آن مورد را نمی‌سازد، action را ندهید؛ هرگز دکمه‌ای بی onClick و بی پیوند (قاعدهٔ ESLint parto/page-primary-action آن را می‌گیرد).

راهنمای استفاده

بکنید

  • صفحهٔ 404 محصول را در app/not-found.tsx با UtilityPage kind="404" بسازید. اگر قاب در app/(app)/layout.tsx است (محصولی با صفحهٔ ورود)، app/not-found.tsx بیرون از هر گروه است و خودش قاب را رندر می‌کند: <Frame><UtilityPage kind="404" …/></Frame>.
  • برای empty عنوان و توضیحی بنویسید که بگوید بخش چیست و گام بعدی چیست.

نکنید

  • صفحهٔ کمکی را بیرون از قاب محصول (بدون منو) نسازید.
  • Empty را با عنوان صفحهٔ جداگانه بالای آن نگذارید؛ عنوان صفحهٔ کمکی همان عنوان وضعیت است.
  • بیش از یک اقدام ندهید، و دکمه‌ای که کاری نمی‌کند اقدام نکنید.
  • عنوان empty را نام صفحه («گزارش‌ها») نگذارید.

Props

UtilityPage

Prop

Type

دسترسی‌پذیری

  • عنوان صفحه تنها h1 صفحه است؛ آیکون تزئینی است و از فناوری کمکی پنهان است.
  • اقدام، اگر باشد، تنها کنترل صفحه است و اولین توقف Tab بعد از قاب.

کامپوننت‌های مرتبط

  • ListPage — فهرستی که خالی است ولی ابزارهای فهرست را لازم دارد.
  • PageState — حالت خطا یا خالیِ یک بلوک در صفحه‌ای که بقیه‌اش سر جایش است.
  • Empty — جزء حالت خالی درون یک بلوک.