IntelliClass_FE/components/CourseCard.vue
Timothy Yin b05f954923
feat: add authentication requirements to course preparation and resources pages
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
2025-04-06 00:25:20 +08:00

76 lines
2.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>