Browse Source

重构:更新认证和仪表板页面结构,优化路由配置

refactor/repository-structure
hyh 7 months ago
parent
commit
4dcb222883
  1. 25
      src/CellularManagement.WebUI/package-lock.json
  2. 1
      src/CellularManagement.WebUI/package.json
  3. 57
      src/CellularManagement.WebUI/src/components/auth/LoginForm.tsx
  4. 5
      src/CellularManagement.WebUI/src/constants/auth.ts
  5. 79
      src/CellularManagement.WebUI/src/pages/LoginPage.tsx
  6. 30
      src/CellularManagement.WebUI/src/pages/auth/LoginPage.tsx
  7. 0
      src/CellularManagement.WebUI/src/pages/dashboard/DashboardHome.tsx
  8. 33
      src/CellularManagement.WebUI/src/routes/AppRouter.tsx

25
src/CellularManagement.WebUI/package-lock.json

@ -19,6 +19,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.0",
"recoil": "^0.7.7",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
"zustand": "^4.5.0"
@ -3206,6 +3207,11 @@
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
"dev": true
},
"node_modules/hamt_plus": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/hamt_plus/-/hamt_plus-1.0.2.tgz",
"integrity": "sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA=="
},
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
@ -4125,6 +4131,25 @@
"node": ">=8.10.0"
}
},
"node_modules/recoil": {
"version": "0.7.7",
"resolved": "https://registry.npmmirror.com/recoil/-/recoil-0.7.7.tgz",
"integrity": "sha512-8Og5KPQW9LwC577Vc7Ug2P0vQshkv1y3zG3tSSkWMqkWSwHmE+by06L8JtnGocjW6gcCvfwB3YtrJG6/tWivNQ==",
"dependencies": {
"hamt_plus": "1.0.2"
},
"peerDependencies": {
"react": ">=16.13.1"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/resolve": {
"version": "1.22.10",
"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.10.tgz",

1
src/CellularManagement.WebUI/package.json

@ -21,6 +21,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.0",
"recoil": "^0.7.7",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7",
"zustand": "^4.5.0"

57
src/CellularManagement.WebUI/src/components/auth/LoginForm.tsx

@ -0,0 +1,57 @@
import { useState } from 'react';
import { DEFAULT_CREDENTIALS } from '../../constants/auth';
interface LoginFormProps {
onSubmit: (username: string, password: string) => void;
}
export function LoginForm({ onSubmit }: LoginFormProps) {
const [username, setUsername] = useState(DEFAULT_CREDENTIALS.username);
const [password, setPassword] = useState(DEFAULT_CREDENTIALS.password);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
onSubmit(username, password);
};
return (
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
<div className="space-y-4">
<div>
<label htmlFor="username" className="block text-sm font-medium">
/
</label>
<input
id="username"
type="text"
required
value={username}
onChange={(e) => setUsername(e.target.value)}
className="mt-1 block w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
placeholder="请输入用户名或邮箱"
/>
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium">
</label>
<input
id="password"
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
className="mt-1 block w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
placeholder="请输入密码"
/>
</div>
</div>
<button
type="submit"
className="w-full rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
</button>
</form>
);
}

5
src/CellularManagement.WebUI/src/constants/auth.ts

@ -0,0 +1,5 @@
export const DEFAULT_CREDENTIALS = {
username: 'admin',
email: 'admin@example.com',
password: 'admin123'
};

79
src/CellularManagement.WebUI/src/pages/LoginPage.tsx

@ -1,79 +0,0 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
export function LoginPage() {
const navigate = useNavigate();
// 默认账号密码
const defaultCredentials = {
username: 'admin',
email: 'admin@example.com',
password: 'admin123'
};
// 初始化时使用默认值
const [username, setUsername] = useState(defaultCredentials.username);
const [password, setPassword] = useState(defaultCredentials.password);
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// 验证登录
const isValidLogin =
(username === defaultCredentials.username || username === defaultCredentials.email) &&
password === defaultCredentials.password;
if (isValidLogin) {
navigate('/dashboard');
} else {
alert('用户名/邮箱或密码错误');
}
};
return (
<div className="flex min-h-screen items-center justify-center bg-background">
<div className="w-full max-w-md space-y-8 rounded-lg border bg-card p-8 shadow-lg">
<div className="text-center">
<h2 className="text-2xl font-bold"></h2>
</div>
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
<div className="space-y-4">
<div>
<label htmlFor="username" className="block text-sm font-medium">
/
</label>
<input
id="username"
type="text"
required
value={username}
onChange={(e) => setUsername(e.target.value)}
className="mt-1 block w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
placeholder="请输入用户名或邮箱"
/>
</div>
<div>
<label htmlFor="password" className="block text-sm font-medium">
</label>
<input
id="password"
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
className="mt-1 block w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
placeholder="请输入密码"
/>
</div>
</div>
<button
type="submit"
className="w-full rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
</button>
</form>
</div>
</div>
);
}

30
src/CellularManagement.WebUI/src/pages/auth/LoginPage.tsx

@ -0,0 +1,30 @@
import { useNavigate } from 'react-router-dom';
import { LoginForm } from '../../components/auth/LoginForm';
import { DEFAULT_CREDENTIALS } from '../../constants/auth';
export function LoginPage() {
const navigate = useNavigate();
const handleLogin = (username: string, password: string) => {
const isValidLogin =
(username === DEFAULT_CREDENTIALS.username || username === DEFAULT_CREDENTIALS.email) &&
password === DEFAULT_CREDENTIALS.password;
if (isValidLogin) {
navigate('/dashboard');
} else {
alert('用户名/邮箱或密码错误');
}
};
return (
<div className="flex min-h-screen items-center justify-center bg-background">
<div className="w-full max-w-md space-y-8 rounded-lg border bg-card p-8 shadow-lg">
<div className="text-center">
<h2 className="text-2xl font-bold"></h2>
</div>
<LoginForm onSubmit={handleLogin} />
</div>
</div>
);
}

0
src/CellularManagement.WebUI/src/pages/DashboardHome.tsx → src/CellularManagement.WebUI/src/pages/dashboard/DashboardHome.tsx

33
src/CellularManagement.WebUI/src/routes/AppRouter.tsx

@ -1,21 +1,40 @@
import { Routes, Route, Navigate } from 'react-router-dom';
import { Suspense, lazy } from 'react';
import { DashboardLayout } from '../components/layout/DashboardLayout';
import { LoginPage } from '../pages/LoginPage';
import { DashboardHome } from '../pages/DashboardHome';
// 使用 lazy 加载组件
const LoginPage = lazy(() => import('../pages/auth/LoginPage').then(module => ({ default: module.LoginPage })));
const DashboardHome = lazy(() => import('../pages/dashboard/DashboardHome').then(module => ({ default: module.DashboardHome })));
// 加载中的占位组件
const LoadingFallback = () => (
<div className="flex items-center justify-center min-h-screen">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div>
</div>
);
export function AppRouter() {
return (
<Routes>
<Route path="/" element={<Navigate to="/login" replace />} />
<Route path="/login" element={<LoginPage />} />
<Route
path="/login"
element={
<Suspense fallback={<LoadingFallback />}>
<LoginPage />
</Suspense>
}
/>
<Route
path="/dashboard/*"
element={
<DashboardLayout>
<Routes>
<Route index element={<DashboardHome />} />
{/* 添加更多路由 */}
</Routes>
<Suspense fallback={<LoadingFallback />}>
<Routes>
<Route index element={<DashboardHome />} />
{/* 添加更多路由 */}
</Routes>
</Suspense>
</DashboardLayout>
}
/>

Loading…
Cancel
Save