WIP: Switch to React #6

Draft
biss wants to merge 21 commits from codex/react-migration into master
pull from: codex/react-migration
7 changed files with 269 additions and 5 deletions
Showing only changes of commit 850eb6b05c - Show all commits

No files matched your search

+1 -1
View File
@@ -5,7 +5,7 @@
| 路由 | 页面 | 角色/公开范围 | 关键合同 | 状态 |
| --- | --- | --- | --- | --- |
| `/login` | 登录 | 公开 | 验证码、密码、TOTP、SSO 设置、会话落盘 | building |
| `/dashboard` | 教务总览 | 已登录用户 | `GET /api/dashboard`、角色视图、待办和学期 | building |
| `/dashboard` | 角色化首页 | 已登录用户 | 管理总览;学生课表/消息/考试/预警;教师教学班/成绩登记进度 | verification |
| `/account` | 个人账户 | 已登录用户 | TOTP、恢复码、SSO 绑定;Passkey 浏览器仪式尚未开放 | verification |
| `/users` | 用户与权限 | SuperAdmin | 列表、筛选、分页、创建、启停、重置密码、角色范围、Excel | verification |
+7 -3
View File
@@ -23,17 +23,21 @@ export default function AppShell() {
const logout = useAuthStore((state) => state.logout)
const refreshUser = useAuthStore((state) => state.refreshUser)
const [collapsed, setCollapsed] = useState(false)
const roles = user?.roles ?? []
const isStudentHome = roles.includes('Student') && !roles.some((role) => ['SuperAdmin', 'AcademicAdmin', 'CollegeAdmin', 'Counselor'].includes(role))
const isTeacherHome = roles.includes('Teacher') && !roles.some((role) => ['SuperAdmin', 'AcademicAdmin', 'CollegeAdmin', 'Counselor', 'Student'].includes(role))
const legacyBase = (import.meta.env.VITE_LEGACY_APP_URL ?? 'http://localhost:5255').replace(/\/$/, '')
useEffect(() => { void refreshUser().catch(() => undefined) }, [refreshUser])
const items = useMemo(() => [
{ key: '/dashboard', icon: <AppstoreOutlined />, label: '教务总览' },
{ key: '/dashboard', icon: <AppstoreOutlined />, label: isStudentHome ? '学习首页' : isTeacherHome ? '教学工作台' : '教务总览' },
{ key: '/account', icon: <IdcardOutlined />, label: '个人账户' },
...(user?.roles.includes('SuperAdmin')
? [{ key: '/users', icon: <SafetyCertificateOutlined />, label: '用户与权限' }]
: []),
{ key: 'legacy', icon: <ExportOutlined />, label: '返回现有系统' },
], [user?.roles])
], [isStudentHome, isTeacherHome, user?.roles])
const pageTitle = items.find((item) => location.pathname.startsWith(item.key))?.label ?? '迁移预览'
@@ -83,7 +87,7 @@ export default function AppShell() {
<div className="shell-context"><span>当前工作区</span><strong>{pageTitle}</strong></div>
</div>
<div className="shell-user">
<Button type="text" aria-label="通知中心" icon={<BellOutlined />} />
<Button type="text" aria-label="通知中心" icon={<BellOutlined />} onClick={() => window.location.assign(`${legacyBase}/notifications`)} />
<Tag color="geekblue">预览</Tag>
<div className="shell-user__copy"><strong>{user?.displayName ?? '用户'}</strong><small>{user?.roles.join(' · ') || '正在读取权限'}</small></div>
<Avatar style={{ background: '#54cfbd', color: '#163f43' }}>{user?.displayName?.slice(0, 1) ?? '明'}</Avatar>
+17 -1
View File
@@ -2,6 +2,10 @@ import { Alert, Button, Progress, Skeleton } from 'antd'
import { ArrowRightOutlined, ReloadOutlined } from '@ant-design/icons'
import { useQuery } from '@tanstack/react-query'
import http from '../api/http'
import { useAuthStore } from '../stores/auth'
import StudentDashboardPage from './dashboard/StudentDashboardPage'
import TeacherDashboardPage from './dashboard/TeacherDashboardPage'
import './dashboard/role-dashboard.css'
interface DashboardData {
audience: {
@@ -49,7 +53,7 @@ function formatDate(value?: string) {
return new Intl.DateTimeFormat('zh-CN', { month: 'long', day: 'numeric' }).format(date)
}
export default function DashboardPage() {
function AdminDashboardPage() {
const query = useQuery({
queryKey: ['dashboard'],
queryFn: async () => (await http.get<DashboardData>('/dashboard')).data,
@@ -131,3 +135,15 @@ export default function DashboardPage() {
</main>
)
}
export default function DashboardPage() {
const roles = useAuthStore((state) => state.user?.roles ?? [])
const isStudent = roles.includes('Student') &&
!roles.some((role) => ['SuperAdmin', 'AcademicAdmin', 'CollegeAdmin', 'Counselor'].includes(role))
const isTeacher = roles.includes('Teacher') &&
!roles.some((role) => ['SuperAdmin', 'AcademicAdmin', 'CollegeAdmin', 'Counselor', 'Student'].includes(role))
if (isStudent) return <StudentDashboardPage />
if (isTeacher) return <TeacherDashboardPage />
return <AdminDashboardPage />
}
Loaded 3 of 7 files, more files were not shown because too many files have changed in this diff. Show more