feat(web): add login page, auth store, API client, and route guard
- API client with axios interceptors: JWT attach + 401 auto-refresh - Auth store (Zustand): login/logout/loadFromStorage with localStorage - Login page: gradient background, Ant Design form, error handling - Home page: dashboard with statistics cards - App.tsx: PrivateRoute guard, /login route, auth state restoration - MainLayout: dynamic user display, logout dropdown, menu navigation - Users API service: CRUD with pagination support
This commit is contained in:
@@ -1,29 +1,53 @@
|
||||
import { HashRouter, Routes, Route } from 'react-router-dom';
|
||||
import { useEffect } from 'react';
|
||||
import { HashRouter, Routes, Route, Navigate } from 'react-router-dom';
|
||||
import { ConfigProvider, theme as antdTheme } from 'antd';
|
||||
import zhCN from 'antd/locale/zh_CN';
|
||||
import MainLayout from './layouts/MainLayout';
|
||||
import Login from './pages/Login';
|
||||
import Home from './pages/Home';
|
||||
import { useAuthStore } from './stores/auth';
|
||||
import { useAppStore } from './stores/app';
|
||||
|
||||
function HomePage() {
|
||||
return <div>欢迎来到 ERP 平台</div>;
|
||||
function PrivateRoute({ children }: { children: React.ReactNode }) {
|
||||
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
|
||||
return isAuthenticated ? <>{children}</> : <Navigate to="/login" replace />;
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const { theme: appTheme } = useAppStore();
|
||||
const loadFromStorage = useAuthStore((s) => s.loadFromStorage);
|
||||
const theme = useAppStore((s) => s.theme);
|
||||
|
||||
// Restore auth state from localStorage on app load
|
||||
useEffect(() => {
|
||||
loadFromStorage();
|
||||
}, [loadFromStorage]);
|
||||
|
||||
return (
|
||||
<ConfigProvider
|
||||
locale={zhCN}
|
||||
theme={{
|
||||
algorithm: appTheme === 'dark' ? antdTheme.darkAlgorithm : antdTheme.defaultAlgorithm,
|
||||
algorithm: theme === 'dark' ? antdTheme.darkAlgorithm : antdTheme.defaultAlgorithm,
|
||||
}}
|
||||
>
|
||||
<HashRouter>
|
||||
<MainLayout>
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
</Routes>
|
||||
</MainLayout>
|
||||
<Routes>
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<PrivateRoute>
|
||||
<MainLayout>
|
||||
<Routes>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="/users" element={<div>用户管理(开发中)</div>} />
|
||||
<Route path="/roles" element={<div>权限管理(开发中)</div>} />
|
||||
<Route path="/settings" element={<div>系统设置(开发中)</div>} />
|
||||
</Routes>
|
||||
</MainLayout>
|
||||
</PrivateRoute>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</HashRouter>
|
||||
</ConfigProvider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user