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

صفحهٔ تعمیرات، هم‌سبکِ ۴۰۴ و ۵۰۲: تابلوی خطی با آچار، متنِ صمیمی، پیشرفتِ کار با شمارنده و زمانِ تقریبیِ برگشت، و «خبرم کن».

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

این بلاک از ۶ آیتم دیگ استفاده می‌کند: buttoncontrol-sizecount-upiconsprogresstoast

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

۲. کد صفحه

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

maintenance.tsx
"use client"

import * as React from "react"

import { BellIcon } from "@/components/icons"
import { Button } from "@/components/ui/button"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { CountUp } from "@/components/ui/count-up"
import { Progress } from "@/components/ui/progress"
import { toast } from "@/components/ui/toast"

/**
 * تصویرِ خطی تابلوی آویزان، هم‌خانوادهٔ صفحه‌های ۴۰۴ و ۵۰۲؛ فقط رنگِ متن و
 * پس‌زمینهٔ تم، پس در حالتِ تیره هم درست است. محتوای وسطِ تابلو را children می‌دهد.
 */
function HangingSign({ label, className, children }: { label: string; className?: string; children: React.ReactNode }) {
  return (
    <svg viewBox="-10 0 320 290" role="img" aria-label={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 30 96 108M150 30l58 78" fill="none" stroke="currentColor" strokeWidth="1.75" 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="208" cy="112" r="3.2" fill="var(--background)" stroke="currentColor" strokeWidth="1.75" />
      <rect x="56" y="134" width="196" height="94" fill="currentColor" />
      {children}
    </svg>
  )
}

/** صفحهٔ تعمیرات؛ هم‌سبکِ ۴۰۴ و ۵۰۲، با زمانِ تقریبی برگشت و «خبرم کن». */
export default function MaintenanceBlock() {
  const [notify, setNotify] = 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">
        <HangingSign label="تابلوی در حالِ تعمیر با آچار" className="w-64 max-w-full text-foreground sm:w-80">
          {/* آچار و پیچ‌گوشتی ضربدری */}
          <g fill="none" stroke="var(--background)" strokeWidth="5" strokeLinecap="round">
            <path d="m134 206 36-36" />
            <path d="M166 160a10 10 0 1 0 14 14l-6-2-4-4z" strokeWidth="4" strokeLinejoin="round" />
            <path d="m174 206-36-36" />
            <path d="m132 166 8-8" strokeWidth="6" />
          </g>
        </HangingSign>
        <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 w-full max-w-xs flex-col gap-2 text-sm">
          <div className="flex justify-between text-muted-foreground">
            <span>پیشرفتِ کار</span>
            <CountUp value={72} suffix="٪" className="font-semibold text-foreground" />
          </div>
          <Progress value={72} aria-label="پیشرفتِ تعمیرات" />
          <span className="text-muted-foreground">برگشتِ تقریبی: حدودِ ۱۵ دقیقهٔ دیگه</span>
        </div>
        <Button
          variant={notify ? "outline" : "default"}
          onClick={() => {
            setNotify(true)
            toast.success("برگشتیم، پیامک می‌زنیم.")
          }}
          disabled={notify}
        >
          <BellIcon />
          {notify ? "خبرت می‌کنیم" : "وقتی برگشتید خبرم کن"}
        </Button>
      </main>
    </ControlSizeProvider>
  )
}