import type { SiteListItem } from "@umt/contracts"; import { accessSummary, useSiteRequestStats, useSiteUserData } from "~/api/sites.ts"; import { DetailSection } from "~/components/console/detail-sheet.tsx"; import { ErrorState, LoadingState } from "~/components/console/empty-state.tsx"; import { KvList } from "~/components/console/kv-list.tsx"; import { StatTile } from "~/components/console/stat-tile.tsx"; import { StatusBadge } from "~/components/console/status-badge.tsx"; import { relTime } from "~/components/workbench/release-fields.ts"; import { ACCOUNT_OVERALL, AUTH_KIND_LABEL, bytes, dataAccount, healthLine, healthMessage, overallStatus, primaryAccount, rateLimitText, ratioText, } from "./site-fields.ts"; import { UserDataChart } from "./user-data-chart.tsx"; /** 站点详情"概览":账号数据磁贴 + 30 天趋势 + 状态 */ export function SiteOverview({ site }: { site: SiteListItem }) { const dAcc = dataAccount(site.accounts); const acc = primaryAccount(site.accounts); const u = dAcc?.userData ?? null; const history = useSiteUserData(site.id, dAcc?.id, 30); const stats = useSiteRequestStats(site.id); const st = ACCOUNT_OVERALL[overallStatus(site)]; const h = healthLine(site.lastHealth, site.lastHealthAt); return (

近 30 天

{dAcc ? `账号 ${dAcc.label} · 数据 ${relTime(dAcc.userDataAt)}` : "没有账号数据"}
{history.isPending && dAcc ? ( ) : history.error ? ( void history.refetch()} /> ) : ( )}
{st.label} }, { label: "凭证", value: acc ? AUTH_KIND_LABEL[acc.authKind] : "未配置" }, { label: "用户名", value: u?.username ?? acc?.loginName }, { label: "上次登录", value: relTime(acc?.lastLoginAt) }, ...(acc?.lastError && acc.status !== "active" ? [{ label: "最近错误", value: {acc.lastError.message} }] : []), ]} /> {h.text} {healthMessage(site.lastHealth) ? ( {healthMessage(site.lastHealth)} ) : null} ), }, { label: "快照", value: site.snapshotEnabled ? `${site.lastSnapshotAt ? relTime(site.lastSnapshotAt) : "还没有快照"} · ${site.snapshotIntervalSec ? `每 ${Math.round(site.snapshotIntervalSec / 60)} 分钟` : "默认周期"}` : "未开启", }, { label: "限流", value: rateLimitText(site.rateLimit) }, { label: "近 24 小时请求", value: stats.data ? ( {stats.data.last24h} 次 {accessSummary(stats.data)} ) : ( "—" ), }, { label: "代理", value: site.proxy ? "使用" : "不使用" }, ]} />
); }