import type { Site, SiteAccount } from "@umt/contracts"; import { ArrowRight, Camera, Globe, RefreshCw } from "lucide-react"; import { Link } from "react-router"; import { toast } from "sonner"; import { snapshotStale, useSiteAccounts, useSites, useSnapshotSite, useToggleSite } from "~/api/sites.ts"; import { EmptyState, ErrorState, LoadingState } from "~/components/console/empty-state.tsx"; import { PageHeader } from "~/components/console/page-header.tsx"; import { StatusBadge } from "~/components/console/status-badge.tsx"; import { Button } from "~/components/ui/button.tsx"; import { Switch } from "~/components/ui/switch.tsx"; import { accountSummary, circuitLabel, relTime, SITE_HEALTH } from "~/components/workbench/release-fields.ts"; import { errorMessage } from "~/lib/api.ts"; const ADAPTER_LABEL: Record = { nexusphp: "NexusPHP", mteam_api: "M-Team API", api: "站点 API", generic_rss: "通用 RSS", }; function SiteCard({ site, accounts }: { site: Site; accounts: SiteAccount[] }) { const toggle = useToggleSite(); const snap = useSnapshotSite(); const health = SITE_HEALTH[site.healthStatus]; const account = accountSummary(accounts); const stale = site.snapshotEnabled && snapshotStale(site); const circuit = circuitLabel(site); return (
{site.name}

{site.key} · {ADAPTER_LABEL[site.adapter]}

toggle.mutate( { id: site.id, enabled: v }, { onSuccess: () => toast.success(v ? `已启用 ${site.name}` : `已停用 ${site.name}`), onError: (e) => toast.error(errorMessage(e)), }, ) } />
{health.label} 账号:{account.label} {circuit ? {circuit} : null}
最近快照
{site.snapshotEnabled ? relTime(site.lastSnapshotAt) : "未开启快照"} {stale ? 已过期 : null}
快照周期
{site.snapshotIntervalSec ? `${Math.round(site.snapshotIntervalSec / 60)} 分钟` : "默认"}
); } export default function SitesPage() { const sites = useSites(); const accounts = useSiteAccounts(); const bySite = new Map(); for (const a of accounts.data?.items ?? []) bySite.set(a.siteId, [...(bySite.get(a.siteId) ?? []), a]); return ( <> void sites.refetch()} disabled={sites.isFetching}> 刷新 } /> {sites.isPending ? (
) : sites.error && !sites.data ? ( void sites.refetch()} /> ) : !sites.data?.items.length ? ( 去来源页 } /> ) : (
{sites.data.items.map((s) => ( ))}
)} ); }