feat: 全站 PageShell 设计系统与专业 UI 统一

- 新增 PageShell/PageTabs/ContentPanel/PageLoading/PageEmpty 页面骨架
- index.css 设计令牌文档化,布局令牌与纯色主按钮(去除渐变粉彩)
- 全站路由页接入 PageShell,云账单三 Tab 为标杆
- 主题体系:跟随系统 + 主流/开发者分组,新增 Dracula/Tokyo Night,One Dark 暖灰差异化
- 登录页/侧栏/顶栏去渐变光球,企业克制风
- 修复 AIAlertAnalyzer JSX 与构建依赖导入问题
This commit is contained in:
Logan committed 2026-07-01 12:45:38 +08:00
1 parent 1acb0c49af
commit e363ded445
213 files changed
+7148 -6818

No files matched your search

@@ -72,15 +72,15 @@ export function HostDetailDialog({
return (
<Dialog open={!!host} onOpenChange={(v) => { if (!v) onClose(); }}>
<DialogContent className="max-w-3xl bg-slate-900 border-slate-800 text-slate-100">
<DialogContent className="max-w-3xl dg-card text-[var(--dg-text-primary)]">
<DialogHeader>
<DialogTitle className="text-slate-100 flex items-center gap-2">
<Server className="h-5 w-5 text-blue-400" />
<DialogTitle className="text-[var(--dg-text-primary)] flex items-center gap-2">
<Server className="h-5 w-5 dg-text-blue" />
{host.hostname}
{online ? (
<Badge className="bg-emerald-500/15 text-emerald-400 border border-emerald-500/30">在线</Badge>
<Badge className="bg-emerald-500/15 dg-text-green border border-emerald-500/30">在线</Badge>
) : (
<Badge className="bg-red-500/15 text-red-400 border border-red-500/30">离线</Badge>
<Badge className="bg-red-500/15 dg-text-red border border-red-500/30">离线</Badge>
)}
</DialogTitle>
<DialogDescription className="sr-only">查看主机详情和指标趋势</DialogDescription>
@@ -98,28 +98,28 @@ export function HostDetailDialog({
{/* 趋势图 */}
<div>
<div className="flex items-center justify-between mb-2">
<span className="text-sm font-medium text-slate-200 flex items-center gap-1.5">
<Activity className="h-4 w-4 text-blue-400" />
<span className="text-sm font-medium text-[var(--dg-text-primary)] flex items-center gap-1.5">
<Activity className="h-4 w-4 dg-text-blue" />
指标趋势
</span>
<Select value={String(hours)} onValueChange={(v) => setHours(Number(v))}>
<SelectTrigger size="sm" className="h-7 w-28 bg-slate-800 border-slate-700 text-slate-300 text-xs">
<SelectTrigger size="sm" className="h-7 w-28 dg-input text-[var(--dg-text-secondary)] text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent className="bg-slate-800 border-slate-700 text-slate-200">
<SelectContent className="dg-input">
<SelectItem value="1">最近 1 小时</SelectItem>
<SelectItem value="6">最近 6 小时</SelectItem>
<SelectItem value="24">最近 24 小时</SelectItem>
</SelectContent>
</Select>
</div>
<div className="h-56 rounded-lg bg-slate-950 border border-slate-800 p-3">
<div className="h-56 rounded-lg bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] p-3">
{loading ? (
<div className="h-full flex items-center justify-center">
<Loader2 className="h-5 w-5 animate-spin text-slate-500" />
<Loader2 className="h-5 w-5 animate-spin dg-text-muted" />
</div>
) : chartData.length === 0 ? (
<div className="h-full flex items-center justify-center text-sm text-slate-500">暂无历史数据</div>
<div className="h-full flex items-center justify-center text-sm dg-text-muted">暂无历史数据</div>
) : (
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={chartData} margin={{ top: 5, right: 5, bottom: 0, left: -20 }}>
@@ -154,16 +154,16 @@ export function HostDetailDialog({
{/* 端口列表 */}
<div>
<span className="text-sm font-medium text-slate-200 flex items-center gap-1.5 mb-2">
<Network className="h-4 w-4 text-blue-400" />
<span className="text-sm font-medium text-[var(--dg-text-primary)] flex items-center gap-1.5 mb-2">
<Network className="h-4 w-4 dg-text-blue" />
端口发现 ({ports.length})
</span>
{ports.length === 0 ? (
<p className="text-xs text-slate-500">暂无端口数据</p>
<p className="text-xs dg-text-muted">暂无端口数据</p>
) : (
<div className="flex flex-wrap gap-1.5 max-h-32 overflow-y-auto">
{ports.map((p, idx) => (
<Badge key={idx} className="bg-slate-800 text-slate-300 border border-slate-700">
<Badge key={idx} className="bg-[var(--dg-bg-tertiary)] text-[var(--dg-text-secondary)] border border-[var(--dg-border)]">
<Network className="h-3 w-3 mr-1" />
{p.port ?? p}
</Badge>
@@ -181,7 +181,7 @@ export function HostDetailDialog({
<Terminal className="h-4 w-4 mr-1.5" />
远程命令
</Button>
<Button variant="outline" onClick={onClose} className="border-slate-700 text-slate-300">
<Button variant="outline" onClick={onClose} className="border-[var(--dg-border)] text-[var(--dg-text-secondary)]">
关闭
</Button>
</DialogFooter>
@@ -192,9 +192,9 @@ export function HostDetailDialog({
function InfoCell({ label, value }: { label: string; value: string }) {
return (
<div className="bg-slate-950 border border-slate-800 rounded-lg px-3 py-2">
<div className="text-xs text-slate-500">{label}</div>
<div className="text-sm text-slate-200 font-medium truncate">{value}</div>
<div className="bg-[var(--dg-bg-primary)] border border-[var(--dg-border)] rounded-lg px-3 py-2">
<div className="text-xs dg-text-muted">{label}</div>
<div className="text-sm text-[var(--dg-text-primary)] font-medium truncate">{value}</div>
</div>
);
}