fix: update home page background image and remove unnecessary redirect code chore: update pnpm lock file with new dependencies for auto-animate and svg spinners delete: remove unused images from public directory refactor: modify course and user types for better clarity and structure feat: implement course API with CRUD operations and teacher team management feat: create user authentication page with login functionality and validation feat: add login state management with Pinia for user session handling style: create reusable UI components for cards and tabs chore: implement HTTP utility for API requests with error handling
76 lines
2.3 KiB
Vue
76 lines
2.3 KiB
Vue
<script lang="ts" setup>
|
||
import type { ICourse } from "~/types";
|
||
|
||
defineProps<{
|
||
data: ICourse;
|
||
deleteMode?: boolean;
|
||
}>();
|
||
|
||
const emit = defineEmits<{
|
||
"delete-course": [courseId: number];
|
||
}>();
|
||
|
||
const openCourse = (id: number) => {
|
||
window.open(`/course/${id}`, "_blank", "noopener,noreferrer");
|
||
};
|
||
</script>
|
||
|
||
<template>
|
||
<div class="flex flex-col gap-2 relative">
|
||
<div class="absolute top-0 right-0">
|
||
<Button
|
||
v-if="deleteMode"
|
||
size="icon"
|
||
variant="link"
|
||
@click="emit('delete-course', data.id)"
|
||
>
|
||
<Icon name="tabler:trash" size="16px" class="text-red-500 text-lg" />
|
||
</Button>
|
||
</div>
|
||
<NuxtImg
|
||
:src="data.previewUrl || '/images/bg_home.jpg'"
|
||
alt="课程封面"
|
||
class="w-full aspect-video rounded-md shadow-md cursor-pointer hover:shadow-lg transition duration-300 ease-in-out hover:ring-4 hover:ring-primary-background"
|
||
@click="openCourse(data.id)"
|
||
/>
|
||
<div class="px-1.5 flex flex-col gap-1">
|
||
<div class="flex justify-between items-center gap-2">
|
||
<h1 class="flex-1 text-base font-medium text-ellipsis line-clamp-1">
|
||
{{ data.courseName || "未知课程" }}
|
||
</h1>
|
||
<p
|
||
class="text-xs text-muted-foreground font-medium flex items-center gap-0.5"
|
||
>
|
||
<Icon name="tabler:user" size="14px" />
|
||
<span>{{ data.teacherName || "未知教师" }}</span>
|
||
</p>
|
||
</div>
|
||
<div class="flex justify-between gap-1 text-xs text-muted-foreground/80">
|
||
<div class="flex-1 flex flex-col">
|
||
<p>
|
||
学期:<span>{{ data.semester || "未知" }}</span>
|
||
</p>
|
||
<p>
|
||
课程ID:<span>{{ data.id }}</span>
|
||
</p>
|
||
</div>
|
||
<div class="flex flex-col items-end">
|
||
<p>{{ data.schoolName }}</p>
|
||
<div class="flex items-center gap-1">
|
||
<div
|
||
v-if="data.status === 0"
|
||
class="w-2 h-2 rounded-full bg-emerald-400"
|
||
/>
|
||
<div v-else class="w-2 h-2 rounded-full bg-gray-400" />
|
||
<p class="text-xs text-muted-foreground/80">
|
||
{{ data.status === 0 ? "开课" : "关课" }}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped></style>
|