feat: implement core e-learning classroom functionality including login, lesson viewing, and quiz pages.
This commit is contained in:
parent
0641b2547a
commit
8e57cb124a
3 changed files with 21 additions and 23 deletions
|
|
@ -100,13 +100,14 @@ const handleLogin = async () => {
|
|||
}
|
||||
|
||||
// Show error on specific fields
|
||||
if (result.error === 'ไม่พบอีเมลในระบบ') {
|
||||
errors.value.email = 'กรุณาเช็ค Email หรือ รหัสผ่านใหม่อีกครั้ง'
|
||||
errors.value.password = 'กรุณาเช็ค Email หรือ รหัสผ่านใหม่อีกครั้ง'
|
||||
} else if (result.error === 'Email ไม่ถูกต้อง') {
|
||||
errors.value.email = result.error
|
||||
// Show generic error for security (or specific if role mismatch)
|
||||
if (result.error === 'Email ไม่ถูกต้อง') {
|
||||
errors.value.email = result.error // Role mismatch case
|
||||
} else {
|
||||
errors.value.password = 'กรอกรหัสผ่านไม่ถูกต้อง'
|
||||
// Generic login failure (401, 404, etc.)
|
||||
const msg = 'กรุณาเช็ค Email หรือ รหัสผ่านใหม่อีกครั้ง'
|
||||
errors.value.email = msg
|
||||
errors.value.password = msg
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -282,8 +282,8 @@ const markLessonAsCompletedLocally = (lessonId: number) => {
|
|||
for (const chapter of courseData.value.chapters) {
|
||||
const lesson = chapter.lessons.find((l: any) => l.id === lessonId)
|
||||
if (lesson) {
|
||||
if (!lesson.progress) lesson.progress = {}
|
||||
lesson.progress.is_completed = true
|
||||
// Compatible with API structure
|
||||
lesson.is_completed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
@ -423,19 +423,9 @@ const onVideoEnded = async () => {
|
|||
await loadCourseData()
|
||||
alert(t('course.completed') || "ยินดีด้วย! คุณเรียนจบหลักสูตรแล้ว")
|
||||
} else if (res.data.next_lesson_id) {
|
||||
// Suggest next lesson
|
||||
if (confirm(t('common.next') + '?')) {
|
||||
const nextId = res.data.next_lesson_id
|
||||
|
||||
// Update URL without reload if possible, but router.push is standard
|
||||
await router.push({
|
||||
path: '/classroom/learning',
|
||||
query: { ...route.query, lesson_id: nextId }
|
||||
})
|
||||
|
||||
// Manually load the lesson since we don't have a watcher on query
|
||||
handleLessonSelect(nextId)
|
||||
}
|
||||
// Auto-advance removed as per request.
|
||||
// User will manually select the next lesson from the sidebar.
|
||||
console.log('Video finished. Next lesson available:', res.data.next_lesson_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -532,7 +522,7 @@ onBeforeUnmount(() => {
|
|||
</q-item-section>
|
||||
|
||||
<q-item-section side>
|
||||
<q-icon v-if="lesson.progress?.is_completed" name="check_circle" color="positive" size="xs" />
|
||||
<q-icon v-if="lesson.is_completed" name="check_circle" color="positive" size="xs" />
|
||||
<q-icon v-else-if="currentLesson?.id === lesson.id" name="play_circle" color="primary" size="xs" />
|
||||
<q-icon v-else name="radio_button_unchecked" color="grey-4" size="xs" />
|
||||
</q-item-section>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const { t } = useI18n()
|
|||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const $q = useQuasar()
|
||||
const { fetchCourseLearningInfo, fetchLessonContent, submitQuiz: apiSubmitQuiz } = useCourse()
|
||||
const { fetchCourseLearningInfo, fetchLessonContent, submitQuiz: apiSubmitQuiz, markLessonComplete } = useCourse()
|
||||
|
||||
// State Management
|
||||
const currentScreen = ref<'start' | 'taking' | 'result' | 'review'>('start')
|
||||
|
|
@ -185,6 +185,13 @@ const submitQuiz = async (auto = false) => {
|
|||
|
||||
if (res.success) {
|
||||
quizResult.value = res.data
|
||||
|
||||
// Force mark lesson complete if passed (Fix for checkmark issue)
|
||||
if (res.data.is_passed) {
|
||||
markLessonComplete(courseId, lessonId).then(() => {
|
||||
console.log('Explicitly marked lesson complete')
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Fallback error handling
|
||||
alert(res.error || 'Failed to submit quiz')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue