feat: Introduce core e-learning features with new pages for course details, dashboard, authentication, browsing, and learning, supported by a useCourse composable.

This commit is contained in:
supalerk-ar66 2026-01-23 09:47:32 +07:00
parent c982ab2c05
commit 0eb9b522f6
6 changed files with 109 additions and 38 deletions

View file

@ -1,12 +1,12 @@
<script setup lang="ts">
/**
* @file learning.vue
* @description Course Learning Interface ("Classroom" view).
* Defines the main learning environment where users watch video lessons and track progress.
* Layout mimics a typical LMS with a sidebar for curriculum and a main content area for video/details.
* @important Matches the provided design mockups pixel-perfectly.
* @description หน้าเรียนออนไลน์ (Classroom Interface)
* จัดการแสดงผลวิดีโอรายการบทเรียน และติดตามความคืบหน้า
* ออกแบบให้เหมือนระบบ LMS มาตรฐาน
*/
definePageMeta({
layout: false, // Custom layout defined within this component
middleware: 'auth'
@ -24,18 +24,23 @@ const sidebarOpen = ref(false)
const activeTab = ref<'details' | 'announcements'>('details')
const courseId = computed(() => Number(route.query.course_id))
// ==========================================
// 1. ตัวแปร State (สถานะของ UI)
// ==========================================
// courseData: เก็บข้อมูลโครงสร้างคอร์ส (บทเรียนต่างๆ)
const courseData = ref<any>(null)
// currentLesson: บทเรียนที่กำลังเรียนอยู่ปัจจุบัน
const currentLesson = ref<any>(null)
const isLoading = ref(true)
const isLessonLoading = ref(false)
const isLoading = ref(true) // โหลดข้อมูลคอร์ส
const isLessonLoading = ref(false) // โหลดเนื้อหาบทเรียน
// Video Player Logic
// Video Player State (สถานะวิดีโอ)
const videoRef = ref<HTMLVideoElement | null>(null)
const isPlaying = ref(false)
const videoProgress = ref(0)
const currentTime = ref(0)
const duration = ref(0)
const saveProgressInterval = ref<any>(null)
const saveProgressInterval = ref<any>(null) // ตัวแปรเก็บ setInterval สำหรับบันทึกความคืบหน้าอัตโนมัติ
// Helper for localization
const getLocalizedText = (text: any) => {
@ -59,6 +64,11 @@ const switchTab = (tab: 'details' | 'announcements', lessonId: any = null) => {
}
// Data Fetching
// ==========================================
// 2. ฟังก์ชันโหลดข้อมูล (Data Fetching)
// ==========================================
// โหลดโครงสร้างคอร์สและบทเรียนทั้งหมด
const loadCourseData = async () => {
if (!courseId.value) return
isLoading.value = true
@ -67,7 +77,7 @@ const loadCourseData = async () => {
if (res.success) {
courseData.value = res.data
// Auto-load first unlocked lesson if no current lesson
// Auto-load logic: ถ้ายังไม่ได้เลือกบทเรียน ให้โหลดบทแรกที่ไม่ล็อคมาแสดง
if (!currentLesson.value) {
const firstChapter = res.data.chapters[0]
if (firstChapter && firstChapter.lessons.length > 0) {
@ -164,7 +174,10 @@ const videoSrc = computed(() => {
return ''
})
// Save progress periodically
// ==========================================
// 3. ระบบบันทึกความคืบหน้า (Progress Tracking)
// ==========================================
// บันทึกอัตโนมัติทุกๆ 10 วินาทีเมื่อเล่นวิดีโอ
watch(() => isPlaying.value, (playing) => {
if (playing) {
saveProgressInterval.value = setInterval(() => {
@ -190,11 +203,12 @@ watch(() => isPlaying.value, (playing) => {
}
})
// เมื่อวิดีโอจบ ให้บันทึกว่าเรียนจบ (Complete)
const onVideoEnded = async () => {
isPlaying.value = false
if (currentLesson.value) {
await markLessonComplete(courseId.value, currentLesson.value.id)
// Reload course data to update sidebar progress/locks
// โหลดข้อมูลคอร์สใหม่เพื่ออัปเดตสถานะติ๊กถูกด้านข้าง
await loadCourseData()
// Auto play next logic could go here