mirror of
https://github.com/cfngc4594/monaco-editor-lsp-next.git
synced 2025-07-04 09:20:53 +00:00
refactor(user-management): 优化用户管理功能和界面
- 为 toast 消息添加 1500ms 持续时间 - 修复管理员、学生和教师表单的字段和验证规则 - 优化问题表格的列配置 - 调整用户表格的样式和布局
This commit is contained in:
parent
42e576876e
commit
db8051d1d8
@ -293,11 +293,11 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
if (isProblem) {
|
||||
problemApi.getProblems()
|
||||
.then(setData)
|
||||
.catch(() => toast.error('获取数据失败'))
|
||||
.catch(() => toast.error('获取数据失败', { duration: 1500 }))
|
||||
} else {
|
||||
userApi.getUsers(config.userType)
|
||||
.then(setData)
|
||||
.catch(() => toast.error('获取数据失败'))
|
||||
.catch(() => toast.error('获取数据失败', { duration: 1500 }))
|
||||
}
|
||||
}, [config.userType])
|
||||
|
||||
@ -335,9 +335,9 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
await userApi.createUser(config.userType, submitData)
|
||||
userApi.getUsers(config.userType).then(setData)
|
||||
onOpenChange(false)
|
||||
toast.success('添加成功')
|
||||
toast.success('添加成功', { duration: 1500 })
|
||||
} catch {
|
||||
toast.error("添加失败")
|
||||
toast.error('添加失败', { duration: 1500 })
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
@ -410,9 +410,9 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
await problemApi.createProblem(submitData)
|
||||
problemApi.getProblems().then(setData)
|
||||
onOpenChange(false)
|
||||
toast.success('添加成功')
|
||||
toast.success('添加成功', { duration: 1500 })
|
||||
} catch {
|
||||
toast.error("添加失败")
|
||||
toast.error('添加失败', { duration: 1500 })
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
@ -485,9 +485,9 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
await userApi.updateUser(config.userType, submitData)
|
||||
userApi.getUsers(config.userType).then(setData)
|
||||
onOpenChange(false)
|
||||
toast.success('修改成功')
|
||||
toast.success('修改成功', { duration: 1500 })
|
||||
} catch {
|
||||
toast.error("修改失败")
|
||||
toast.error('修改失败', { duration: 1500 })
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
@ -558,9 +558,9 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
await problemApi.updateProblem(submitData)
|
||||
problemApi.getProblems().then(setData)
|
||||
onOpenChange(false)
|
||||
toast.success('修改成功')
|
||||
toast.success('修改成功', { duration: 1500 })
|
||||
} catch {
|
||||
toast.error("修改失败")
|
||||
toast.error('修改失败', { duration: 1500 })
|
||||
} finally {
|
||||
setIsLoading(false)
|
||||
}
|
||||
@ -577,26 +577,21 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
</DialogHeader>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
||||
<div className="grid gap-4 py-4">
|
||||
{config.formFields.map((field) => (
|
||||
<div key={field.key} className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor={field.key} className="text-right">
|
||||
{field.label}
|
||||
</Label>
|
||||
<div className="grid grid-cols-4 items-center gap-4">
|
||||
<Label htmlFor="displayId" className="text-right">题目编号</Label>
|
||||
<Input
|
||||
id={field.key}
|
||||
type={field.type}
|
||||
{...form.register(field.key as 'displayId' | 'difficulty', field.key === 'displayId' ? { valueAsNumber: true } : {})}
|
||||
id="displayId"
|
||||
type="number"
|
||||
{...form.register('displayId', { valueAsNumber: true })}
|
||||
className="col-span-3"
|
||||
placeholder={field.placeholder}
|
||||
disabled={field.key === 'id'}
|
||||
placeholder="请输入题目编号"
|
||||
/>
|
||||
{form.formState.errors[field.key as keyof typeof form.formState.errors]?.message && (
|
||||
{form.formState.errors.displayId?.message && (
|
||||
<p className="col-span-3 col-start-2 text-sm text-red-500">
|
||||
{form.formState.errors[field.key as keyof typeof form.formState.errors]?.message as string}
|
||||
{form.formState.errors.displayId?.message as string}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button type="submit" disabled={isLoading}>
|
||||
@ -644,6 +639,8 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
password: "密码",
|
||||
createdAt: "创建时间",
|
||||
actions: "操作",
|
||||
displayId: "题目编号",
|
||||
difficulty: "难度",
|
||||
}
|
||||
return (
|
||||
<DropdownMenuCheckboxItem
|
||||
@ -660,6 +657,7 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
{config.actions.add && (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
@ -669,6 +667,7 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
<PlusIcon className="h-4 w-4" />
|
||||
{config.actions.add.label}
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
@ -830,11 +829,11 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
</div>
|
||||
|
||||
{/* 添加用户对话框 */}
|
||||
{isProblem ? (
|
||||
{isProblem && config.actions.add ? (
|
||||
<AddUserDialogProblem open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen} />
|
||||
) : (
|
||||
) : !isProblem && config.actions.add ? (
|
||||
<AddUserDialogUser open={isAddDialogOpen} onOpenChange={setIsAddDialogOpen} />
|
||||
)}
|
||||
) : null}
|
||||
|
||||
{/* 编辑用户对话框 */}
|
||||
{isProblem && editingUser ? (
|
||||
@ -874,7 +873,7 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
userApi.getUsers(config.userType).then(setData)
|
||||
}
|
||||
}
|
||||
toast.success(`成功删除 ${selectedRows.length} 条记录`)
|
||||
toast.success(`成功删除 ${selectedRows.length} 条记录`, { duration: 1500 })
|
||||
} else if (deleteTargetId) {
|
||||
if (isProblem) {
|
||||
await problemApi.deleteProblem(deleteTargetId)
|
||||
@ -883,11 +882,11 @@ export function UserTable({ config, data: initialData }: UserTableProps) {
|
||||
await userApi.deleteUser(config.userType, deleteTargetId)
|
||||
userApi.getUsers(config.userType).then(setData)
|
||||
}
|
||||
toast.success('删除成功')
|
||||
toast.success('删除成功', { duration: 1500 })
|
||||
}
|
||||
setDeleteDialogOpen(false)
|
||||
} catch {
|
||||
toast.error("删除失败")
|
||||
toast.error('删除失败', { duration: 1500 })
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
@ -15,18 +15,18 @@ export type Admin = z.infer<typeof adminSchema>
|
||||
|
||||
// 添加管理员表单校验 schema
|
||||
export const addAdminSchema = z.object({
|
||||
name: z.string().optional(),
|
||||
name: z.string().min(1, "姓名为必填项"),
|
||||
email: z.string().email("请输入有效的邮箱地址"),
|
||||
password: z.string().optional(),
|
||||
password: z.string().min(8, "密码长度8-32位").max(32, "密码长度8-32位"),
|
||||
createdAt: z.string(),
|
||||
})
|
||||
|
||||
// 编辑管理员表单校验 schema
|
||||
export const editAdminSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string().optional(),
|
||||
name: z.string().min(1, "姓名为必填项"),
|
||||
email: z.string().email("请输入有效的邮箱地址"),
|
||||
password: z.string().optional(),
|
||||
password: z.string().min(8, "密码长度8-32位").max(32, "密码长度8-32位"),
|
||||
createdAt: z.string(),
|
||||
})
|
||||
|
||||
@ -77,8 +77,8 @@ export const adminConfig = {
|
||||
key: "name",
|
||||
label: "姓名",
|
||||
type: "text",
|
||||
placeholder: "请输入管理员姓名(选填)",
|
||||
required: false,
|
||||
placeholder: "请输入管理员姓名",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: "email",
|
||||
@ -91,8 +91,8 @@ export const adminConfig = {
|
||||
key: "password",
|
||||
label: "密码",
|
||||
type: "password",
|
||||
placeholder: "请输入密码(选填)",
|
||||
required: false,
|
||||
placeholder: "请输入8-32位密码",
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
key: "createdAt",
|
||||
|
@ -26,14 +26,12 @@ export const problemConfig = {
|
||||
{ key: "id", label: "ID", sortable: true },
|
||||
{ key: "displayId", label: "题目编号", sortable: true, searchable: true, placeholder: "搜索编号" },
|
||||
{ key: "difficulty", label: "难度", sortable: true, searchable: true, placeholder: "搜索难度" },
|
||||
{ key: "createdAt", label: "创建时间", sortable: true },
|
||||
],
|
||||
formFields: [
|
||||
{ key: "displayId", label: "题目编号", type: "number", required: true },
|
||||
{ key: "difficulty", label: "难度", type: "text", required: true },
|
||||
],
|
||||
actions: {
|
||||
add: { label: "添加题目", icon: "PlusIcon" },
|
||||
edit: { label: "编辑", icon: "PencilIcon" },
|
||||
delete: { label: "删除", icon: "TrashIcon" },
|
||||
batchDelete: { label: "批量删除", icon: "TrashIcon" },
|
||||
|
@ -11,17 +11,17 @@ export const studentSchema = z.object({
|
||||
});
|
||||
|
||||
export const addStudentSchema = z.object({
|
||||
name: z.string().optional(),
|
||||
name: z.string().min(1, "姓名为必填项"),
|
||||
email: z.string().email("请输入有效的邮箱地址"),
|
||||
password: z.string().optional(),
|
||||
password: z.string().min(8, "密码长度8-32位").max(32, "密码长度8-32位"),
|
||||
createdAt: z.string(),
|
||||
});
|
||||
|
||||
export const editStudentSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string().optional(),
|
||||
name: z.string().min(1, "姓名为必填项"),
|
||||
email: z.string().email("请输入有效的邮箱地址"),
|
||||
password: z.string().optional(),
|
||||
password: z.string().min(8, "密码长度8-32位").max(32, "密码长度8-32位"),
|
||||
createdAt: z.string(),
|
||||
});
|
||||
|
||||
@ -37,9 +37,9 @@ export const studentConfig = {
|
||||
{ key: "createdAt", label: "创建时间", sortable: true },
|
||||
],
|
||||
formFields: [
|
||||
{ key: "name", label: "姓名", type: "text", placeholder: "请输入学生姓名(选填)", required: false },
|
||||
{ key: "name", label: "姓名", type: "text", placeholder: "请输入学生姓名", required: true },
|
||||
{ key: "email", label: "邮箱", type: "email", placeholder: "请输入学生邮箱", required: true },
|
||||
{ key: "password", label: "密码", type: "password", placeholder: "请输入密码(选填)", required: false },
|
||||
{ key: "password", label: "密码", type: "password", placeholder: "请输入8-32位密码", required: true },
|
||||
{ key: "createdAt", label: "创建时间", type: "datetime-local", required: true },
|
||||
],
|
||||
actions: {
|
||||
|
@ -11,17 +11,17 @@ export const teacherSchema = z.object({
|
||||
});
|
||||
|
||||
export const addTeacherSchema = z.object({
|
||||
name: z.string().optional(),
|
||||
name: z.string().min(1, "姓名为必填项"),
|
||||
email: z.string().email("请输入有效的邮箱地址"),
|
||||
password: z.string().optional(),
|
||||
password: z.string().min(8, "密码长度8-32位").max(32, "密码长度8-32位"),
|
||||
createdAt: z.string(),
|
||||
});
|
||||
|
||||
export const editTeacherSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string().optional(),
|
||||
name: z.string().min(1, "姓名为必填项"),
|
||||
email: z.string().email("请输入有效的邮箱地址"),
|
||||
password: z.string().optional(),
|
||||
password: z.string().min(8, "密码长度8-32位").max(32, "密码长度8-32位"),
|
||||
createdAt: z.string(),
|
||||
});
|
||||
|
||||
@ -37,9 +37,9 @@ export const teacherConfig = {
|
||||
{ key: "createdAt", label: "创建时间", sortable: true },
|
||||
],
|
||||
formFields: [
|
||||
{ key: "name", label: "姓名", type: "text", placeholder: "请输入教师姓名(选填)", required: false },
|
||||
{ key: "name", label: "姓名", type: "text", placeholder: "请输入教师姓名", required: true },
|
||||
{ key: "email", label: "邮箱", type: "email", placeholder: "请输入教师邮箱", required: true },
|
||||
{ key: "password", label: "密码", type: "password", placeholder: "请输入密码(选填)", required: false },
|
||||
{ key: "password", label: "密码", type: "password", placeholder: "请输入8-32位密码", required: true },
|
||||
{ key: "createdAt", label: "创建时间", type: "datetime-local", required: true },
|
||||
],
|
||||
actions: {
|
||||
|
Loading…
Reference in New Issue
Block a user