بلاک‌ها · پنل مدیریت

خطای سرور با همان تابلوی آویزانِ صفحهٔ ۴۰۴ که یک بندش پاره شده، دکمهٔ تلاشِ دوباره و پیوندِ وضعیت سرویس‌ها.

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

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

پکیج‌منیجر پیش‌فرض 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/link.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/icons.json https://docs.digdesign.ir/r/link.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/icons.json https://docs.digdesign.ir/r/link.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/icons.json https://docs.digdesign.ir/r/link.json

۲. کد صفحه

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

server-error.tsx
"use client"

import * as React from "react"
import NextLink from "next/link"

import { RefreshIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Link } from "@/components/ui/link"

/**
 * تصویرِ خطی تابلوی آویزان؛ فقط رنگِ متن و پس‌زمینهٔ تم، پس در حالتِ تیره هم درست است.
 */
function BrokenSign({ className }: { className?: string }) {
  return (
    <svg viewBox="-10 0 320 290" role="img" aria-label="تابلوی ۵۰۲ که یک بندش پاره شده" className={className}>
      {/* میخ؛ بندِ چپ پاره شده و تابلو از بندِ راست کج آویزان است */}
      <circle cx="150" cy="26" r="6" fill="var(--background)" stroke="currentColor" strokeWidth="2" />
      <path d="M150 20v-8" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
      <path d="M150 30l-26 40" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" />
      <path d="m124 70-5 6m5-6 1 8m-1-8-7 2" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
      <g transform="rotate(14 150 30)">
        <path d="M150 30l62 79" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" />
        <path d="m96 109-4-8m4 8 3-7" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
        {/* عمقِ تابلو: لایهٔ پشتی با فاصله، مثلِ برش‌های خطی نمونه */}
        <path d="M58 114h200v122H58z" transform="translate(8 7)" fill="var(--background)" stroke="currentColor" strokeWidth="2" strokeLinejoin="round" />
        <path d="M258 114l8 7v122l-8-7M58 236l8 7h200" fill="none" stroke="currentColor" strokeWidth="2" strokeLinejoin="round" />
        {/* بدنهٔ پنجره */}
        <rect x="50" y="108" width="208" height="126" fill="var(--background)" stroke="currentColor" strokeWidth="2" />
        <path d="M50 128h208" stroke="currentColor" strokeWidth="2" />
        {/* سربرگ: منو و دو دایره، و حلقه‌های بند */}
        <path d="M60 114h10M60 118h10M60 122h10" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" />
        <circle cx="236" cy="118" r="2.6" fill="none" stroke="currentColor" strokeWidth="1.6" />
        <circle cx="246" cy="118" r="2.6" fill="none" stroke="currentColor" strokeWidth="1.6" />
        <circle cx="96" cy="112" r="3.2" fill="var(--background)" stroke="currentColor" strokeWidth="1.75" />
        <circle cx="212" cy="112" r="3.2" fill="var(--background)" stroke="currentColor" strokeWidth="1.75" />
        <rect x="56" y="134" width="196" height="94" fill="currentColor" />
        <text x="154" y="198" textAnchor="middle" fontSize="54" fontWeight="800" fill="var(--background)">۵۰۲</text>
      </g>
    </svg>
  )
}

/** صفحهٔ ۵۰۲ (سرورِ میانی پاسخ نداد)؛ همان سبکِ صفحهٔ ۴۰۴ با دکمهٔ تلاشِ دوباره. */
export default function ServerErrorBlock() {
  const [retrying, setRetrying] = React.useState(false)

  return (
    <ControlSizeProvider size="xl" asChild>
    <main className="flex min-h-svh flex-col items-center justify-center gap-8 p-6 text-center">
      <BrokenSign className="w-64 max-w-full text-foreground sm:w-80" />
      <div className="flex max-w-md flex-col items-center gap-3">
        <h1 className="text-3xl leading-snug font-bold">اِ… سیمش در رفته!</h1>
        <p className="leading-7 text-muted-foreground">
          سرورمون الان جواب نمی‌ده. یه لحظه دیگه دوباره امتحان کن؛ اطلاعاتت سر جاشه، نگران نباش.
        </p>
      </div>
      <div className="flex flex-wrap justify-center gap-3">
        <Button
          loading={retrying}
          onClick={() => {
            setRetrying(true)
            window.setTimeout(() => window.location.reload(), 600)
          }}
        >
          <RefreshIcon />
          دوباره امتحان کن
        </Button>
        <Button asChild variant="outline">
          <NextLink href="/">برگردیم خونه</NextLink>
        </Button>
      </div>
      <p className="text-sm text-muted-foreground">
        اگه درست نشد، <Link href="/status">وضعیت سرویس‌ها</Link> رو ببین.
      </p>
    </main>
    </ControlSizeProvider>
  )
}