feat: 后台管理 Admin 仪表盘

新增完整的后台管理系统 (/admin):
- Dashboard: 系统概览、最近采集状态、预测统计
- Collection: 数据采集触发(bzzoiro/understat/injuries)
- Predictions: 预测历史查看、触发新预测
- Backtest: 回测配置与结果查看
- Monitoring: 系统健康、错误日志、死色队列
- Config: API Key 与数据源配置

技术栈: React Router + Tailwind 暗色主题 + TypeScript
文件: 11 个新文件, +21KB JS / +5KB CSS
This commit is contained in:
shangfangjian
2026-09-17 02:00:14 +08:00
parent 1219b4fd18
commit d3284c48c3
19 changed files with 2671 additions and 81 deletions
+87
View File
@@ -0,0 +1,87 @@
/**
* Admin 后台 - 布局组件
*
* 提供管理界面的基本结构:顶栏 + 侧边栏 + 内容区
* 暗色主题,参考线性风格设计
*/
import { NavLink, Outlet } from 'react-router-dom'
const NAV_ITEMS = [
{ to: '/admin', label: '仪表盘', icon: '◇', end: true },
{ to: '/admin/collection', label: '数据采集', icon: '◈' },
{ to: '/admin/predictions', label: '预测管理', icon: '◆' },
{ to: '/admin/backtest', label: '回测管理', icon: '◉' },
{ to: '/admin/monitoring', label: '监控面板', icon: '◐' },
{ to: '/admin/config', label: '配置管理', icon: '◑' },
]
export default function AdminLayout() {
return (
<div className="flex h-screen bg-gray-950 text-gray-200 overflow-hidden">
{/* ── 侧边栏 ── */}
<aside className="flex w-56 flex-shrink-0 flex-col border-r border-gray-800 bg-gray-900">
<div className="border-b border-gray-800 px-5 py-4">
<h1 className="font-serif text-lg font-bold tracking-wider text-gray-100">
Profeto
<span className="ml-2 text-xs font-normal tracking-normal text-gray-500">Admin</span>
</h1>
</div>
<nav className="flex-1 overflow-y-auto px-3 py-4" aria-label="主导航">
<ul className="space-y-0.5">
{NAV_ITEMS.map(item => (
<li key={item.to}>
<NavLink
to={item.to}
end={item.end}
className={({ isActive }) =>
`flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors ${
isActive
? 'bg-gray-800 text-white font-medium'
: 'text-gray-400 hover:bg-gray-800/60 hover:text-gray-200'
}`
}
>
<span className="text-base leading-none opacity-60" aria-hidden="true">
{item.icon}
</span>
{item.label}
</NavLink>
</li>
))}
</ul>
</nav>
<div className="border-t border-gray-800 px-4 py-3">
<a
href="/"
className="flex items-center gap-2 text-xs text-gray-500 transition-colors hover:text-gray-300"
>
<span aria-hidden="true"></span>
</a>
</div>
</aside>
{/* ── 主内容区 ── */}
<div className="flex flex-1 flex-col overflow-hidden">
{/* 顶栏 */}
<header className="flex h-12 flex-shrink-0 items-center justify-between border-b border-gray-800 bg-gray-900 px-6">
<div className="flex items-center gap-2 text-xs text-gray-500">
<span className="inline-block h-2 w-2 rounded-full bg-emerald-500" aria-hidden="true" />
</div>
<div className="text-xs text-gray-500">
Profeto Admin v1.0
</div>
</header>
{/* 页面内容 */}
<main className="flex-1 overflow-y-auto p-6">
<Outlet />
</main>
</div>
</div>
)
}