import { useQuery } from "@tanstack/react-query"; import { type Dashboard, DownloadBoard, type HealthLevel } from "@umt/contracts"; import { ArrowRight, Download, HardDrive, type LucideIcon } from "lucide-react"; import type { ReactNode } from "react"; import { Link } from "react-router"; import { apiParsed } from "~/api/parse.ts"; import { useSystemHealth } from "~/api/system.ts"; import { EmptyState, ErrorState, LoadingState } from "~/components/console/empty-state.tsx"; import { consolePath } from "~/components/console/nav.ts"; import { StatusBadge, type StatusTone } from "~/components/console/status-badge.tsx"; import { formatRelative } from "~/lib/labels.ts"; import { cn, formatBytes } from "~/lib/utils.ts"; const LEVEL: Record = { ok: { label: "正常", tone: "success" }, warn: { label: "需要关注", tone: "warning" }, critical: { label: "需要处理", tone: "destructive" }, unknown: { label: "用量未知", tone: "neutral" }, }; const SCOPE = { data_dir: "系统数据", library_root: "媒体库", download_dir: "下载目录" }; function OverviewCard({ title, icon: Icon, to, children, }: { title: string; icon: LucideIcon; to: string; children: ReactNode; }) { return (

{title}

详情
{children}
); } function StorageOverview() { const q = useSystemHealth(60_000); const mediaDisks = q.data?.disks.filter((d) => d.scope !== "data_dir") ?? []; const disks = mediaDisks.length ? mediaDisks : (q.data?.disks ?? []); return ( {q.isPending ? ( ) : q.isError ? ( q.refetch()} className="py-6" /> ) : !disks.length ? ( ) : (
    {disks.map((d) => { const pct = d.usedRatio === null ? null : d.usedRatio * 100; const state = LEVEL[d.level]; return (
  • {d.name !== SCOPE[d.scope] ? ( {SCOPE[d.scope]} ) : null} {d.name}

    {state.label} {pct === null ? "" : ` · ${Math.round(pct)}%`}
    {pct !== null ? (
    ) : null}

    剩余{" "} {d.availableBytes === null ? "未知" : formatBytes(d.availableBytes, 1)} 已用 {d.usedBytes === null ? "未知" : formatBytes(d.usedBytes, 1)} 总量 {d.totalBytes === null ? "未知" : formatBytes(d.totalBytes, 1)}

    {d.path}

    {d.error ?

    无法读取磁盘用量

    : null}
  • ); })}
)} {q.data && !q.isError ? (

所在磁盘用量 · 检查于 {formatRelative(q.data.checkedAt)}

) : null}
); } function DownloaderOverview({ downloaders }: { downloaders?: Dashboard["sources"]["downloaders"] }) { // 首页仅取一条面板记录,速度和计数仍是完整汇总;无需拉取下载任务列表。 const q = useQuery({ queryKey: ["downloads", "home-overview"], queryFn: ({ signal }) => apiParsed(DownloadBoard, "/api/v1/download-tasks/board", { params: { state: "active", limit: 1 }, signal }), refetchInterval: 15_000, refetchIntervalInBackground: false, }); const board = q.data; const instances = board?.transfer.instances ?? []; const sources = downloaders ?? instances.map((d) => ({ id: d.instanceId, name: d.name, enabled: true, health: "unknown", lastSeenAt: null })); return ( {q.isPending ? ( ) : q.isError ? ( q.refetch()} className="py-6" /> ) : !sources.length ? ( ) : ( <>

{board?.counts.active} 项进行中

    {sources.map((d) => { const live = instances.find((i) => i.instanceId === d.id); const state = !d.enabled ? { label: "已停用", tone: "neutral" as const } : !live ? { label: "状态未知", tone: "neutral" as const } : live.reachable ? { label: "在线", tone: "success" as const } : { label: "连接失败", tone: "warning" as const }; const readable = d.enabled && live?.reachable; return (
  • {d.name} {state.label}
    {d.enabled ? (

    下载{" "} {readable ? `${formatBytes(live.dlSpeed, 1)}/s` : "未知"} 上传{" "} {readable ? `${formatBytes(live.upSpeed, 1)}/s` : "未知"}

    ) : null}
  • ); })}

进行中含等待计划、暂停和异常任务 · 速度含下载器全部任务

{board?.liveAt ? (

速度采样于 {formatRelative(board.liveAt)}

) : null} )}
); } export function HomeRuntime({ downloaders }: { downloaders?: Dashboard["sources"]["downloaders"] }) { return (
); }