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

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

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

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

پکیج‌منیجر پیش‌فرض 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
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
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
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

۲. کد صفحه

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

offline.tsx
"use client"

import * as React from "react"

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

/** تصویرِ خطی ابر با سیمِ قطع‌شده؛ هم‌سبکِ تابلوهای ۴۰۴ و ۵۰۲، با رنگِ تم. */
function DisconnectedCloud({ className }: { className?: string }) {
  return (
    <svg viewBox="0 0 320 220" role="img" aria-label="ابری با سیمِ قطع‌شده" className={className}>
      <path
        d="M92 150h138a42 42 0 0 0 4-84 62 62 0 0 0-118-12 46 46 0 0 0-24 96z"
        fill="var(--background)"
        stroke="currentColor"
        strokeWidth="2.5"
        strokeLinejoin="round"
      />
      <path d="M100 158h138a42 42 0 0 0 10-82" transform="translate(6 6)" fill="none" stroke="currentColor" strokeWidth="2" strokeLinejoin="round" />
      <path d="M150 150v22m0 0-10 10m10-10 10 10" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" />
      <path d="M170 198v-10m0 0 10-10m-10 10-10-10" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" transform="translate(-20 14)" />
      <path d="M118 188l-8 6M196 188l8 6M158 206v8" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
      <path d="M128 100h0M192 100h0" stroke="currentColor" strokeWidth="6" strokeLinecap="round" />
      <path d="M140 124c12-8 28-8 40 0" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" />
    </svg>
  )
}

/**
 * صفحهٔ آفلاین: هم‌سبکِ صفحه‌های خطا، با وضعیتِ زندهٔ اتصال؛ وقتی اینترنت برگشت،
 * پیام و دکمه خودشان عوض می‌شوند. کارهای ذخیره‌شده دست نمی‌خورند.
 */
export default function OfflineBlock() {
  const [online, setOnline] = React.useState(false)
  const [checking, setChecking] = React.useState(false)

  React.useEffect(() => {
    const on = () => setOnline(true)
    const off = () => setOnline(false)
    window.addEventListener("online", on)
    window.addEventListener("offline", off)
    return () => {
      window.removeEventListener("online", on)
      window.removeEventListener("offline", off)
    }
  }, [])

  return (
    <ControlSizeProvider size="xl" asChild>
      <main className="flex min-h-svh flex-col items-center justify-center gap-8 p-6 text-center">
        <DisconnectedCloud className="w-64 max-w-full text-foreground sm:w-80" />
        <div className="flex max-w-md flex-col items-center gap-3" aria-live="polite">
          <h1 className="text-3xl leading-snug font-bold">{online ? "برگشتیم!" : "اینترنت قطعه"}</h1>
          <p className="leading-7 text-muted-foreground">
            {online ? "اتصال برقرار شد؛ صفحه را تازه کن و ادامه بده." : "نگران نباش، چیزی پاک نشده. وقتی وصل شدی همه‌چیز همان‌جاست که گذاشته بودی."}
          </p>
        </div>
        <Button
          loading={checking}
          onClick={() => {
            setChecking(true)
            window.setTimeout(() => {
              setChecking(false)
              setOnline(navigator.onLine)
            }, 900)
          }}
        >
          <RefreshIcon />
          {online ? "تازه کردنِ صفحه" : "دوباره امتحان کن"}
        </Button>
        <ul className="flex flex-col gap-1 text-sm text-muted-foreground">
          <li>وای‌فای یا دادهٔ همراه روشن است؟</li>
          <li>حالتِ هواپیما خاموش است؟</li>
        </ul>
      </main>
    </ControlSizeProvider>
  )
}