feat(admin): 管理端 UI/UX 深度优化——错误/加载/空状态、表单快捷键、移动端适配与无障碍
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useCallback } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router';
|
||||
import { Button, Card, Form, Space, Spin, Tabs, Tag } from 'antd';
|
||||
import {Button, Card, Form, Space, Tabs, Tag, Skeleton} from 'antd';
|
||||
import { ArrowLeftOutlined } from '@ant-design/icons';
|
||||
import dayjs from 'dayjs';
|
||||
import api from '../../api';
|
||||
@@ -33,6 +33,8 @@ const ClassDetailPage: React.FC = () => {
|
||||
const [studentModalOpen, setStudentModalOpen] = useState(false);
|
||||
const [allStudents, setAllStudents] = useState<StudentItem[]>([]);
|
||||
const [selectedStudentIds, setSelectedStudentIds] = useState<number[]>([]);
|
||||
const [addingStudents, setAddingStudents] = useState(false);
|
||||
const [addingTeacher, setAddingTeacher] = useState(false);
|
||||
|
||||
// Teacher modal state
|
||||
const [teacherModalOpen, setTeacherModalOpen] = useState(false);
|
||||
@@ -151,6 +153,7 @@ const ClassDetailPage: React.FC = () => {
|
||||
|
||||
const handleAddStudents = async () => {
|
||||
if (!selectedStudentIds.length) return;
|
||||
setAddingStudents(true);
|
||||
try {
|
||||
await api.post(`/classes/${id}/students`, { studentIds: selectedStudentIds });
|
||||
setStudentModalOpen(false);
|
||||
@@ -159,11 +162,14 @@ const ClassDetailPage: React.FC = () => {
|
||||
message.success('已添加');
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e, '添加失败'));
|
||||
} finally {
|
||||
setAddingStudents(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleAddTeacher = async () => {
|
||||
if (!teacherUserId) return;
|
||||
setAddingTeacher(true);
|
||||
try {
|
||||
await api.post(`/classes/${id}/teachers`, {
|
||||
userId: teacherUserId,
|
||||
@@ -175,6 +181,8 @@ const ClassDetailPage: React.FC = () => {
|
||||
message.success('已添加');
|
||||
} catch (e: unknown) {
|
||||
message.error(getErrorMessage(e, '添加失败'));
|
||||
} finally {
|
||||
setAddingTeacher(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -219,8 +227,8 @@ const ClassDetailPage: React.FC = () => {
|
||||
if (!detail) {
|
||||
if (loading) {
|
||||
return (
|
||||
<div style={{ textAlign: 'center', padding: 80 }}>
|
||||
<Spin size="large" />
|
||||
<div style={{ padding: 24 }}>
|
||||
<Skeleton active paragraph={{ rows: 8 }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -296,6 +304,7 @@ const ClassDetailPage: React.FC = () => {
|
||||
onClose={() => setStudentModalOpen(false)}
|
||||
onRemove={handleRemoveStudent}
|
||||
onSelect={setSelectedStudentIds}
|
||||
adding={addingStudents}
|
||||
/>
|
||||
),
|
||||
},
|
||||
@@ -324,6 +333,7 @@ const ClassDetailPage: React.FC = () => {
|
||||
onSubjectChange={setTeacherSubject}
|
||||
onUserChange={setTeacherUserId}
|
||||
getTeacherName={getTeacherName}
|
||||
adding={addingTeacher}
|
||||
/>
|
||||
),
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user