feat: Implement initial e-learning platform frontend structure including dashboard, course management, authentication, and common UI components.
This commit is contained in:
parent
aceeb80d9a
commit
ad11c6b7c5
44 changed files with 720 additions and 578 deletions
|
|
@ -1,8 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
/**
|
||||
* @file CourseCard.vue
|
||||
* @description Standardized Course Card Component.
|
||||
* Usage: <CourseCard :id="1" title="..." ... />
|
||||
* @description คอมโพเนนต์การ์ดแสดงคอร์สเรียนมาตรฐาน (Standardized Course Card Component)
|
||||
* วิธีใช้งาน: <CourseCard :id="1" title="..." ... />
|
||||
*/
|
||||
|
||||
interface CourseCardProps {
|
||||
|
|
@ -20,7 +20,7 @@ interface CourseCardProps {
|
|||
image?: string
|
||||
loading?: boolean
|
||||
|
||||
// Action Flags
|
||||
// ตัวควบคุมการแสดงปุ่มต่างๆ (Action Flags)
|
||||
showViewDetails?: boolean
|
||||
showContinue?: boolean
|
||||
showCertificate?: boolean
|
||||
|
|
@ -59,7 +59,7 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
<template>
|
||||
<div class="group relative flex flex-col bg-white dark:!bg-slate-900 rounded-3xl overflow-hidden border border-slate-200 dark:border-white/5 shadow-sm hover:shadow-xl dark:shadow-none hover:-translate-y-1 transition-all duration-300 h-full">
|
||||
|
||||
<!-- Thumbnail Section -->
|
||||
<!-- ส่วนรูปหน้าปก (Thumbnail Section) -->
|
||||
<div class="relative w-full aspect-video overflow-hidden">
|
||||
<img
|
||||
v-if="image"
|
||||
|
|
@ -71,12 +71,12 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
<q-icon name="image" size="48px" class="text-slate-300 dark:text-slate-600" />
|
||||
</div>
|
||||
|
||||
<!-- Overlays -->
|
||||
<!-- เลเยอร์ฟิลเตอร์ซ้อนทับ (Overlays) -->
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-slate-900/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity"></div>
|
||||
|
||||
|
||||
|
||||
<!-- Completed Badge -->
|
||||
<!-- ป้ายแสดงสถานะเรียนจบ (Completed Badge) -->
|
||||
<div v-if="completed" class="absolute inset-0 bg-emerald-900/40 backdrop-blur-[2px] flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
||||
<span class="bg-emerald-500 text-white w-12 h-12 rounded-full flex items-center justify-center shadow-lg transform scale-75 group-hover:scale-100 transition-transform">
|
||||
<q-icon name="check" size="24px" />
|
||||
|
|
@ -84,9 +84,9 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content Section -->
|
||||
<!-- ส่วนเนื้อหาข้อมูล (Content Section) -->
|
||||
<div class="p-6 flex flex-col flex-grow">
|
||||
<!-- Meta Info (Lessons/Duration) -->
|
||||
<!-- ข้อมูลประกอบย่อย เช่น บทเรียน/ระยะเวลา (Meta Info - Lessons/Duration) -->
|
||||
<div class="flex items-center gap-3 text-xs font-bold text-slate-500 dark:text-slate-400 mb-3 uppercase tracking-wider">
|
||||
<span v-if="lessons" class="flex items-center gap-1">
|
||||
<q-icon name="menu_book" size="14px" /> {{ lessons }} {{ $t('course.lessonsUnit') }}
|
||||
|
|
@ -96,18 +96,18 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Title -->
|
||||
<!-- ชื่อคอร์ส (Title) -->
|
||||
<h3 class="text-lg font-black text-slate-900 dark:text-white mb-2 line-clamp-2 leading-tight group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors">
|
||||
{{ displayTitle }}
|
||||
</h3>
|
||||
|
||||
<!-- Description -->
|
||||
<!-- รายละเอียดเพิ่มเติม (Description) -->
|
||||
<p v-if="displayDescription" class="text-sm text-slate-500 dark:text-slate-400 line-clamp-2 mb-6">
|
||||
{{ displayDescription }}
|
||||
</p>
|
||||
|
||||
<div class="mt-auto pt-4">
|
||||
<!-- Progress Bar -->
|
||||
<!-- หลอดความคืบหน้า (Progress Bar) -->
|
||||
<div v-if="progress !== undefined && !completed && !hideProgress" class="mb-4">
|
||||
<div class="flex justify-between text-[10px] font-bold uppercase mb-1">
|
||||
<span class="text-slate-500 dark:text-slate-400">{{ $t('course.progress') }}</span>
|
||||
|
|
@ -118,9 +118,9 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<!-- ปุ่มปฏิบัติการต่างๆ (Action Buttons) -->
|
||||
<div v-if="!hideActions" class="flex flex-col gap-3">
|
||||
<!-- View Details (Secondary Action) -->
|
||||
<!-- ปุ่มดูรายละเอียด (ปุ่มรอง) (View Details - Secondary Action) -->
|
||||
<q-btn
|
||||
v-if="showViewDetails && !completed && !progress"
|
||||
flat
|
||||
|
|
@ -130,7 +130,7 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
:to="`/course/${id}`"
|
||||
/>
|
||||
|
||||
<!-- Continue Learning (Primary Action) -->
|
||||
<!-- ปุ่มเรียนต่อ/เริ่มเรียน (ปุ่มหลัก) (Continue Learning - Primary Action) -->
|
||||
<q-btn
|
||||
v-if="showContinue || (progress && !completed) || (progress === 0 && !completed)"
|
||||
unelevated
|
||||
|
|
@ -142,7 +142,7 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
</div>
|
||||
|
||||
<div v-if="completed" class="space-y-2">
|
||||
<!-- Study Again -->
|
||||
<!-- ปุ่มเรียนอีกครั้ง (Study Again) -->
|
||||
<q-btn
|
||||
v-if="showStudyAgain"
|
||||
unelevated
|
||||
|
|
@ -152,7 +152,7 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
:to="`/classroom/learning?course_id=${id}`"
|
||||
/>
|
||||
|
||||
<!-- Download Certificate -->
|
||||
<!-- ปุ่มดาวน์โหลดใบรับรอง (Download Certificate) -->
|
||||
<q-btn
|
||||
v-if="showCertificate"
|
||||
unelevated
|
||||
|
|
@ -168,5 +168,5 @@ const displayCategory = computed(() => getLocalizedText(props.category))
|
|||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* Scoped overrides if needed */
|
||||
/* ใส่โค้ด CSS เพิ่มได้ถ้าต้องการครอบคลุมเฉพาะไฟล์นี้ (Scoped overrides if needed) */
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue