Initial WhaleTown V2 backend

This commit is contained in:
2026-07-20 02:00:52 +08:00
commit c995891c1f
265 changed files with 75689 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
import { Layout, Menu, Typography } from 'antd';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import { clearAuth } from '../lib/adminAuth';
const { Header, Content, Sider } = Layout;
export function AdminLayout() {
const navigate = useNavigate();
const location = useLocation();
const selectedKey = location.pathname.startsWith('/logs')
? 'logs'
: location.pathname.startsWith('/users')
? 'users'
: 'users';
return (
<Layout style={{ minHeight: '100vh' }}>
<Sider width={220}>
<div style={{ padding: 16 }}>
<Typography.Title level={5} style={{ color: 'white', margin: 0 }}>
Whale Town Admin
</Typography.Title>
</div>
<Menu
theme="dark"
mode="inline"
selectedKeys={[selectedKey]}
items={[
{
key: 'users',
label: '用户管理',
onClick: () => navigate('/users'),
},
{
key: 'logs',
label: '运行日志',
onClick: () => navigate('/logs'),
},
{
key: 'logout',
label: '退出登录',
onClick: () => {
clearAuth();
navigate('/login');
},
},
]}
/>
</Sider>
<Layout>
<Header style={{ background: 'white', display: 'flex', alignItems: 'center' }}>
<Typography.Text></Typography.Text>
</Header>
<Content style={{ padding: 16 }}>
<Outlet />
</Content>
</Layout>
</Layout>
);
}

28
client/src/app/App.tsx Normal file
View File

@@ -0,0 +1,28 @@
import { ConfigProvider } from 'antd';
import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom';
import { AdminLayout } from './AdminLayout';
import { LoginPage } from '../pages/LoginPage';
import { UsersPage } from '../pages/UsersPage';
import { LogsPage } from '../pages/LogsPage';
import { isAuthed } from '../lib/adminAuth';
export function App() {
return (
<ConfigProvider>
<BrowserRouter>
<Routes>
<Route path="/login" element={<LoginPage />} />
<Route
path="/"
element={isAuthed() ? <AdminLayout /> : <Navigate to="/login" replace />}
>
<Route index element={<Navigate to="/users" replace />} />
<Route path="users" element={<UsersPage />} />
<Route path="logs" element={<LogsPage />} />
</Route>
<Route path="*" element={<Navigate to={isAuthed() ? '/users' : '/login'} replace />} />
</Routes>
</BrowserRouter>
</ConfigProvider>
);
}