import type { Metadata } from "next" import { getTranslations, getMessages, setRequestLocale } from "next-intl/server" import { Link } from "@/i18n/navigation" import Image from "next/image" import { DocHeader } from "@/components/ui/doc-header" import { Callout } from "@/components/ui/callout" import CopyableCode from "@/components/CopyableCode" export async function generateMetadata({ params, }: { params: Promise<{ locale: string }> }): Promise { const { locale } = await params const t = await getTranslations({ locale, namespace: "docs.diskManager.smartDiskTest.meta" }) return { title: t("title"), description: t("description"), openGraph: { title: t("ogTitle"), description: t("ogDescription"), type: "article", url: "https://macrimi.github.io/ProxMenux/docs/disk-manager/smart-disk-test", }, } } type ActionRow = { action: string; what?: string; whatRich?: string; dur: string } type StepData = { title: string; body?: string; bodyRich?: string; img?: string; alt?: string; caption?: string } type RelatedItem = { href: string; label: string; tail?: string } export default async function SmartDiskTestPage({ params, }: { params: Promise<{ locale: string }> }) { const { locale } = await params setRequestLocale(locale) const t = await getTranslations({ locale, namespace: "docs.diskManager.smartDiskTest" }) const messages = (await getMessages({ locale })) as unknown as { docs: { diskManager: { smartDiskTest: { actions: { rows: ActionRow[] } steps: { list: StepData[] } related: { items: RelatedItem[] } } } } } const actionRows = messages.docs.diskManager.smartDiskTest.actions.rows const stepList = messages.docs.diskManager.smartDiskTest.steps.list const relatedItems = messages.docs.diskManager.smartDiskTest.related.items const code = (chunks: React.ReactNode) => {chunks} const strong = (chunks: React.ReactNode) => {chunks} const em = (chunks: React.ReactNode) => {chunks} const br = () =>
return (
{t.rich("intro.body", { code })}

{t("howRuns.heading")}

{t("howRuns.body")}

{`        Detect dependencies (first run)
        ├─ smartctl  present? (smartmontools)
        └─ nvme      present? (nvme-cli)
        Any missing → apt-get install silently
                           │
                           ▼
        Enumerate disks on host (lsblk)
        (no safety filter — read-only tool,
         root / system disks are shown too)
                           │
                           ▼
        User picks a disk
                           │
                           ▼
        Detect disk class from path / TRAN
        ├─ /dev/nvme*      → NVMe
        └─ anything else   → SATA / SAS / SCSI
                           │
                           ▼
        Action menu (loop — stays open after
        each action so you can chain queries)
                           │
  ┌────────────────┬────────────────┬────────────────┬───────────────┐
  ▼                ▼                ▼                ▼               ▼
 Quick         Full             Short            Long             Check
 status        report           test             test             progress
 (instant)     (instant)        (~2 min)         (hours)          (instant)
  │             │                │                │                │
  │             │                │                │                │
  │             │                │ Long test only:                  │
  │             │                │ confirm "runs in background,     │
  │             │                │ result saved to JSON"            │
  │             │                │                │                │
  │             │                └───────┬────────┘                │
  │             │                        │                         │
  │             │               Queued on drive firmware:           │
  │             │               ├─ SATA/SAS: smartctl -t short|long │
  │             │               └─ NVMe:     nvme device-self-test  │
  │             │               Returns to menu while running       │
  │             │                                                  │
  ▼             ▼                                                  ▼
 Read:         Read:                                         Read status:
 SATA/SAS →    SATA/SAS →                                   SATA/SAS →
  smartctl -H   smartctl -x                                  smartctl -c
  smartctl -A                                                NVMe →
                                                             nvme self-test-log
 NVMe →        NVMe →
  nvme smart-   nvme smart-log
  log           + nvme id-ctrl
  │             │                                                  │
  └──────┬──────┴──────────────────────────────────────────────────┘
         │
         ▼
   Output to terminal (color-coded when applicable)
         +
   JSON export to:
   /usr/local/share/proxmenux/smart//
       _.json
         │
         ▼
   Retention policy: oldest beyond the limit
   are trimmed automatically
         │
         ▼
   ProxMenux Monitor reads these files to
   render health trends per disk over time`}
      

{t("deps.heading")}

{t.rich("deps.body", { code })}

{t("actions.heading")}

{actionRows.map((row, idx) => ( ))}
{t("actions.headerAction")} {t("actions.headerWhat")} {t("actions.headerDur")}
{row.action} {row.whatRich ? t.rich(`actions.rows.${idx}.whatRich`, { code, br }) : row.what} {row.dur}
{t.rich("actions.tipBody", { em, strong })}

{t("json.heading")}

{t.rich("json.intro", { code })}

        {`/usr/local/share/proxmenux/smart/
├── sda/
│   ├── 2026-04-23_145312_status.json
│   ├── 2026-04-23_180041_short.json
│   └── 2026-04-24_020015_long.json
└── nvme0n1/
    ├── 2026-04-23_145318_status.json
    └── 2026-04-24_021407_long.json`}
      

{t("json.outro")}

{t("steps.heading")}

{stepList.map((step, idx) => (
{t("steps.stepLabel")} {idx + 1}

{step.title}

{step.bodyRich ? (

{t.rich(`steps.list.${idx}.bodyRich`, { strong })}

) : step.body &&

{step.body}

}
{step.img && (
{step.alt
{step.caption && {step.caption}}
)}
))}

{t("manual.heading")}

{t.rich("manual.nvmeWarnBody", { code })}

{t("troubleshoot.heading")}

{t.rich("troubleshoot.noSmartBody", { code })} {t.rich("troubleshoot.longBody", { code })}

{t("related.heading")}

    {relatedItems.map((item) => (
  • {item.label} {item.tail}
  • ))}
) }