IntelliClass_FE/pages/course/index.vue
2025-04-03 22:57:36 +08:00

258 lines
8.1 KiB
Vue

<script lang="ts" setup>
import { toast } from "vue-sonner";
import { toTypedSchema } from "@vee-validate/zod";
import * as z from "zod";
import type { ICourse } from "~/types";
definePageMeta({
layout: "no-sidebar",
});
useHead({
title: "课程中心",
});
const courseList = ref<ICourse[]>([
{
id: "1",
title: "传感器应用技术",
description: "学习传感器的基本原理及其应用。",
thumbnail_url:
"https://static-xsh.oss-cn-chengdu.aliyuncs.com/file/2024-08-05/9a8b2ed8d66340d43a4b840f58597f13.png",
school_name: "电子科技大学",
teacher_name: "张三",
semester: "2023-2024-1",
is_published: true,
created_at: 1690000000,
updated_at: 1690000000,
},
{
id: "2",
title: "人工智能导论",
description: "探索人工智能的基本概念和应用。",
thumbnail_url:
"https://static-xsh.oss-cn-chengdu.aliyuncs.com/file/2024-08-05/9a8b2ed8d66340d43a4b840f58597f13.png",
school_name: "清华大学",
teacher_name: "李四",
semester: "2023-2024-2",
is_published: false,
created_at: 1691000000,
updated_at: 1691000000,
},
]);
/**
* 生成学期列表
* @param years - 后推年数
* @returns 学期列表
*/
const getSemesters = (years: number) => {
const currentYear = new Date().getFullYear() - 1;
const semesters = [];
for (let i = 0; i < years + 1; i++) {
const year = currentYear + i;
semesters.push(`${year}-${year + 1}-1`, `${year}-${year + 1}-2`);
}
return semesters;
};
const courseFormSchema = toTypedSchema(
z.object({
courseName: z.string().min(4).max(32),
schoolName: z.string().min(4).max(32),
teacherName: z.string().min(2).max(12),
semester: z.enum([...getSemesters(3)] as [string, ...string[]]),
})
);
const folderFormSchema = toTypedSchema(
z.object({
folderName: z.string().min(2).max(32),
})
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const onCourseSubmit = (values: any) => {
toast("submit data:", {
description: JSON.stringify(values, null, 2),
});
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const onFolderSubmit = (values: any) => {
toast("submit data:", {
description: JSON.stringify(values, null, 2),
});
};
</script>
<template>
<div class="container mx-auto flex flex-col gap-8">
<div class="flex justify-between items-center">
<div class="flex items-center gap-2">
<Form
v-slot="{ handleSubmit }"
as=""
keep-values
:validation-schema="courseFormSchema"
>
<Dialog>
<DialogTrigger as-child>
<Button variant="secondary" size="sm">
<Icon name="tabler:plus" size="16px" />
新建课程
</Button>
</DialogTrigger>
<DialogContent class="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>创建课程</DialogTitle>
<DialogDescription>
课程创建后,您可以在课程中添加章节等内容。
</DialogDescription>
</DialogHeader>
<form
id="createCourseForm"
autocomplete="off"
class="space-y-2"
@submit="handleSubmit($event, onCourseSubmit)"
>
<FormField v-slot="{ componentField }" name="courseName">
<FormItem>
<FormLabel>课程名称</FormLabel>
<FormControl>
<Input
type="text"
placeholder="请输入课程名称"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField v-slot="{ componentField }" name="schoolName">
<FormItem>
<FormLabel>学校名称</FormLabel>
<FormControl>
<Input
type="text"
placeholder="请输入院校名称"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField v-slot="{ componentField }" name="teacherName">
<FormItem>
<FormLabel>教师名称</FormLabel>
<FormControl>
<Input
type="text"
placeholder="请输入教师名称"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField v-slot="{ componentField }" name="semester">
<FormItem>
<FormLabel>学期</FormLabel>
<FormControl>
<Select v-bind="componentField">
<FormControl>
<SelectTrigger>
<SelectValue placeholder="请选择学期" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectGroup>
<SelectItem
v-for="semester in getSemesters(3)"
:key="semester"
:value="semester"
>
{{ semester }}
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
</form>
<DialogFooter>
<Button type="submit" form="createCourseForm">创建</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</Form>
<Form
v-slot="{ handleSubmit }"
as=""
keep-values
:validation-schema="folderFormSchema"
>
<Dialog>
<DialogTrigger as-child>
<Button variant="secondary" size="sm">
<Icon name="tabler:folder-plus" size="16px" />
新建文件夹
</Button>
</DialogTrigger>
<DialogContent class="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>创建文件夹</DialogTitle>
<DialogDescription>
可以将多门课程收纳在文件夹中
</DialogDescription>
</DialogHeader>
<form
id="createCourseForm"
autocomplete="off"
class="space-y-2"
@submit="handleSubmit($event, onFolderSubmit)"
>
<FormField v-slot="{ componentField }" name="folderName">
<FormItem>
<FormLabel>文件夹名称</FormLabel>
<FormControl>
<Input
type="text"
placeholder="请输入文件夹名称"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
</form>
<DialogFooter>
<Button type="submit" form="createCourseForm">创建</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</Form>
</div>
<div class="flex items-center gap-2">
<Button variant="secondary" size="sm">删除课程</Button>
</div>
</div>
<div class="grid grid-cols-5 gap-8">
<CourseCard
v-for="course in courseList"
:key="course.id"
:data="course"
/>
</div>
</div>
</template>
<style scoped></style>