import { useState, useCallback } from 'react'; import { Table, Button, Space, Form, Input, Tag, Drawer, Modal, Badge, Typography, message, Tooltip, } from 'antd'; import { PlusOutlined, CopyOutlined, TeamOutlined, UserOutlined, ReloadOutlined, } from '@ant-design/icons'; import { classApi } from '../../api/diary/classes'; import type { SchoolClass, ClassMember } from '../../api/diary/types'; import { PageContainer } from '../../components/PageContainer'; import { DrawerForm } from '../../components/DrawerForm'; import { useCrudDrawer } from '../../hooks/useCrudDrawer'; import { usePaginatedData } from '../../hooks/usePaginatedData'; import { useApiRequest } from '../../hooks/useApiRequest'; import { useThemeMode } from '../../hooks/useThemeMode'; const { Text } = Typography; export default function ClassList() { const isDark = useThemeMode(); const { execute } = useApiRequest(); const { data: classes, total, page, loading, refresh, } = usePaginatedData(async (p, pageSize) => { const result = await classApi.list({ page: p, page_size: pageSize }); return { data: result.data, total: result.total }; }, 20); // --- Create/Edit drawer --- const classDrawer = useCrudDrawer({ getId: (r) => r.id, onCreate: async (values) => { await classApi.create({ name: values.name as string, school_name: values.school_name as string | undefined }); }, onUpdate: async () => { // Class update API not yet available; refresh list silently }, onSuccess: refresh, }); // --- Member drawer --- const [memberDrawerOpen, setMemberDrawerOpen] = useState(false); const [memberClass, setMemberClass] = useState(null); const [members, setMembers] = useState([]); const [membersLoading, setMembersLoading] = useState(false); const openMemberDrawer = useCallback(async (cls: SchoolClass) => { setMemberClass(cls); setMemberDrawerOpen(true); setMembersLoading(true); try { const result = await classApi.listMembers(cls.id); setMembers(result); } catch { message.error('加载班级成员失败'); setMembers([]); } finally { setMembersLoading(false); } }, []); // --- Copy class code --- const handleCopyCode = useCallback((code: string) => { navigator.clipboard.writeText(code).then( () => message.success('班级码已复制'), () => message.error('复制失败,请手动复制'), ); }, []); // --- Table columns --- const columns = [ { title: '班级名称', dataIndex: 'name', key: 'name', render: (name: string, record: SchoolClass) => ( ), }, { title: '学校', dataIndex: 'school_name', key: 'school_name', render: (v?: string) => v || -, }, { title: '班级码', dataIndex: 'class_code', key: 'class_code', width: 180, render: (code: string) => ( {code} } > refresh(p), showTotal: (t) => `共 ${t} 条记录`, }} onRow={(record) => ({ onClick: () => openMemberDrawer(record), style: { cursor: 'pointer' }, })} /> {/* Create class drawer */} {/* Member drawer */} {memberClass ? `${memberClass.name} - 班级成员` : '班级成员'} {memberClass && ( {memberClass.is_active ? '活跃' : '已停用'} )} } open={memberDrawerOpen} onClose={() => { setMemberDrawerOpen(false); setMemberClass(null); setMembers([]); }} width={600} styles={{ body: { background: isDark ? '#141414' : undefined, padding: 0 }, }} extra={ memberClass ? ( 班级码: {memberClass.class_code} ) : null } >
); }