<script lang="ts" setup> import { toTypedSchema } from "@vee-validate/zod"; import { useForm } from "vee-validate"; import { toast } from "vue-sonner"; import { z } from "zod"; import { createClass, getClassListByCourse, getCourseDetail, } from "~/api/course"; definePageMeta({ requiresAuth: true, }); const { params: { id: courseId }, } = useRoute(); // const loginState = useLoginState(); const course = await getCourseDetail(courseId as string); const { data: classes, refresh: refreshClasses } = useAsyncData(() => getClassListByCourse(parseInt(courseId as string)) ); const createClassDialogOpen = ref(false); const createClassSchema = toTypedSchema( z.object({ className: z .string() .min(2, "班级名称至少2个字符") .max(32, "最大长度32个字符"), notes: z.string().max(200, "班级介绍最大长度200个字符"), courseId: z.number().min(1, "课程ID不能为空"), }) ); const createClassForm = useForm({ validationSchema: createClassSchema, initialValues: { className: "", notes: "", courseId: Number(courseId), }, }); const onCreateClassSubmit = createClassForm.handleSubmit((values) => { toast.promise(createClass(values), { loading: "正在创建班级...", success: () => { createClassForm.resetForm(); createClassDialogOpen.value = false; return "创建班级成功"; }, error: () => { return "创建班级失败"; }, finally: () => { refreshClasses(); }, }); }); // const onDeleteClass = (classId: number) => { // toast.promise(deleteCourseClass(classId), { // loading: "正在删除班级...", // success: () => { // refreshClasses(); // return "删除班级成功"; // }, // error: () => { // return "删除班级失败"; // }, // }); // }; </script> <template> <div class="flex flex-col gap-4 px-4 py-2"> <div class="flex justify-between items-start"> <h1 class="text-xl font-medium"> 课程班级管理 <span class="block text-sm text-muted-foreground"> 课程负责人:{{ course.data.teacherName || "未知" }} </span> </h1> <div class="flex items-center gap-4"> <Dialog v-model:open="createClassDialogOpen"> <DialogTrigger as-child> <Button variant="secondary" size="sm" class="flex items-center gap-1" > <Icon name="tabler:plus" size="16px" /> <span>创建班级</span> </Button> </DialogTrigger> <DialogContent class="sm:max-w-[425px]"> <DialogHeader> <DialogTitle>创建班级</DialogTitle> </DialogHeader> <form id="create-class-form" autocomplete="off" class="space-y-2" @submit="onCreateClassSubmit" > <FormField v-slot="{ componentField }" name="className"> <FormItem v-auto-animate> <FormLabel>班级名称</FormLabel> <FormControl> <Input type="text" placeholder="请输入班级名称" v-bind="componentField" /> </FormControl> <FormMessage /> </FormItem> </FormField> <FormField v-slot="{ componentField }" name="notes"> <FormItem v-auto-animate> <FormLabel>班级介绍</FormLabel> <FormControl> <Textarea placeholder="请输入班级介绍" v-bind="componentField" /> </FormControl> <FormMessage /> </FormItem> </FormField> <input type="hidden" name="courseId" /> </form> <DialogFooter> <Button type="submit" form="create-class-form">创建</Button> </DialogFooter> </DialogContent> </Dialog> </div> </div> <div v-if="classes?.data && classes.data.length > 0" class="grid gap-6 grid-cols-1 sm:grid-cols-2 2xl:grid-cols-4" > <CourseClassCard v-for="classItem in classes.data" :key="classItem.classId" :class-item="classItem" /> </div> <EmptyScreen v-else title="暂无班级" description="课程下没有班级,请创建新的班级" icon="fluent-color:people-list-24" /> </div> </template> <style scoped></style>