feat: Add new classroom learning page with course content display, video playback, progress tracking, lesson access control, and course announcements.
This commit is contained in:
parent
8c495f3871
commit
350e3c27b3
1 changed files with 27 additions and 18 deletions
|
|
@ -133,15 +133,23 @@ const resetAndNavigate = (path: string) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logic loadLesson แยกออกมา
|
// Logic loadLesson ให้ลื่นไหลแบบ SPA
|
||||||
const handleLessonSelect = (lessonId: number) => {
|
const handleLessonSelect = (lessonId: number) => {
|
||||||
if (currentLesson.value?.id === lessonId) return
|
if (currentLesson.value?.id === lessonId) return
|
||||||
const url = new URL(window.location.href)
|
|
||||||
url.searchParams.set('lesson_id', lessonId.toString())
|
// 1. เปลี่ยน URL แบบนุ่มนวล
|
||||||
resetAndNavigate(url.toString())
|
router.push({ query: { ...route.query, lesson_id: lessonId.toString() } })
|
||||||
|
|
||||||
|
// 2. โหลดเนื้อหาใหม่โดยไม่ Refresh หน้า
|
||||||
|
loadLesson(lessonId)
|
||||||
|
|
||||||
|
// ปิด Sidebar บนมือถือเมื่อเลือกบทเรียน
|
||||||
|
if (sidebarOpen.value) {
|
||||||
|
sidebarOpen.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logic สำหรับการกดย้อนกลับหรืออกจากหน้าเรียน
|
// Logic สำหรับการกดย้อนกลับหรือออกจากหน้าเรียน (ใช้ Hard Reload ตามเดิม)
|
||||||
const handleExit = (path: string) => {
|
const handleExit = (path: string) => {
|
||||||
resetAndNavigate(path)
|
resetAndNavigate(path)
|
||||||
}
|
}
|
||||||
|
|
@ -155,24 +163,25 @@ const handleExit = (path: string) => {
|
||||||
const loadCourseData = async () => {
|
const loadCourseData = async () => {
|
||||||
if (!courseId.value) return
|
if (!courseId.value) return
|
||||||
isLoading.value = true
|
isLoading.value = true
|
||||||
// Reset states before loading new course
|
|
||||||
courseData.value = null
|
|
||||||
currentLesson.value = null
|
|
||||||
announcements.value = []
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetchCourseLearningInfo(courseId.value)
|
const res = await fetchCourseLearningInfo(courseId.value)
|
||||||
if (res.success) {
|
if (res.success) {
|
||||||
courseData.value = res.data
|
courseData.value = res.data
|
||||||
|
|
||||||
// Auto-load logic: ถ้ายังไม่ได้เลือกบทเรียน ให้โหลดบทแรกที่ไม่ล็อคมาแสดง
|
// Auto-load logic: เช็คจาก URL ก่อน ถ้าไม่มีค่อยหาบทแรก
|
||||||
if (!currentLesson.value) {
|
const urlLessonId = route.query.lesson_id ? Number(route.query.lesson_id) : null
|
||||||
const firstChapter = res.data.chapters[0]
|
|
||||||
if (firstChapter && firstChapter.lessons.length > 0) {
|
if (urlLessonId) {
|
||||||
// Find first unlocked or just first
|
// ถ้ามีใน URL ให้โหลดบทนั้นเลย
|
||||||
const availableLesson = firstChapter.lessons.find((l: any) => !l.is_locked) || firstChapter.lessons[0]
|
loadLesson(urlLessonId)
|
||||||
loadLesson(availableLesson.id)
|
} else if (!currentLesson.value) {
|
||||||
}
|
// ถ้าไม่มีใน URL ให้หาบทแรกที่ไม่ล็อค
|
||||||
|
const firstChapter = res.data.chapters[0]
|
||||||
|
if (firstChapter && firstChapter.lessons.length > 0) {
|
||||||
|
const availableLesson = firstChapter.lessons.find((l: any) => !l.is_locked) || firstChapter.lessons[0]
|
||||||
|
loadLesson(availableLesson.id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch Announcements
|
// Fetch Announcements
|
||||||
|
|
@ -507,7 +516,7 @@ onBeforeUnmount(() => {
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<q-header bordered class="bg-[var(--bg-surface)] border-b border-gray-200 dark:border-white/5 text-[var(--text-main)] h-14">
|
<q-header bordered class="bg-[var(--bg-surface)] border-b border-gray-200 dark:border-white/5 text-[var(--text-main)] h-14">
|
||||||
<q-toolbar>
|
<q-toolbar>
|
||||||
<q-btn flat round dense icon="menu" class="lg:hidden mr-2 text-slate-900 dark:text-white" @click="toggleSidebar" />
|
<q-btn flat round dense icon="menu" class="mr-2 text-slate-900 dark:text-white hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors" @click="toggleSidebar" />
|
||||||
|
|
||||||
<!-- Back Button & Branding -->
|
<!-- Back Button & Branding -->
|
||||||
<div class="flex items-center gap-2 mr-6">
|
<div class="flex items-center gap-2 mr-6">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue