feat: Add i18n support with English and Thai locales and implement the new classroom learning page with course curriculum and video playback.

This commit is contained in:
supalerk-ar66 2026-01-29 15:07:45 +07:00
parent 6146d65949
commit 38e7f1bf06
3 changed files with 45 additions and 6 deletions

View file

@ -145,7 +145,9 @@
"invalidEmail": "Invalid email address", "invalidEmail": "Invalid email address",
"invalidPhone": "Invalid phone number", "invalidPhone": "Invalid phone number",
"passwordTooShort": "At least 6 characters", "passwordTooShort": "At least 6 characters",
"passwordsDoNotMatch": "Passwords do not match" "passwordsDoNotMatch": "Passwords do not match",
"next": "Next",
"back": "Back"
}, },
"classroom": { "classroom": {
"backToDashboard": "Back to My Courses", "backToDashboard": "Back to My Courses",
@ -155,7 +157,8 @@
"notAvailable": "This lesson is not yet available.", "notAvailable": "This lesson is not yet available.",
"loadingTitle": "Loading...", "loadingTitle": "Loading...",
"chapter": "Chapter", "chapter": "Chapter",
"lessons": "Lessons" "lessons": "Lessons",
"attachments": "Attachments"
}, },
"quiz": { "quiz": {
"exitTitle": "Exit Quiz", "exitTitle": "Exit Quiz",
@ -169,6 +172,7 @@
"prevBtn": "Previous Question", "prevBtn": "Previous Question",
"submitBtn": "Submit Answers", "submitBtn": "Submit Answers",
"submitConfirm": "Are you sure you want to submit your answers?", "submitConfirm": "Are you sure you want to submit your answers?",
"submitValues": "Submit Answers",
"scoreTitle": "Quiz Results", "scoreTitle": "Quiz Results",
"passMessage": "Congratulations! You passed the quiz.", "passMessage": "Congratulations! You passed the quiz.",
"failMessage": "You didn't pass this time. Please review the lessons and try again.", "failMessage": "You didn't pass this time. Please review the lessons and try again.",
@ -177,6 +181,16 @@
"timeLeft": "Time Left", "timeLeft": "Time Left",
"noQuizData": "Sorry, no quiz data found", "noQuizData": "Sorry, no quiz data found",
"noQuizDesc": "This lesson might not have a quiz yet or it is being updated.", "noQuizDesc": "This lesson might not have a quiz yet or it is being updated.",
"underDevelopment": "System is loading questions..." "underDevelopment": "System is loading questions...",
"questions": "Questions",
"minutes": "Minutes",
"question": "Question",
"submitting": "Submitting...",
"resultPassed": "Congratulations! Passed",
"resultFailed": "Sorry, Failed",
"scoreLabel": "Score",
"correctLabel": "Correct",
"retryBtn": "Retry Quiz",
"pleaseSelectAnswer": "Please select an answer"
} }
} }

View file

@ -145,7 +145,9 @@
"invalidEmail": "อีเมลไม่ถูกต้อง", "invalidEmail": "อีเมลไม่ถูกต้อง",
"invalidPhone": "เบอร์โทรศัพท์ไม่ถูกต้อง", "invalidPhone": "เบอร์โทรศัพท์ไม่ถูกต้อง",
"passwordTooShort": "รหัสผ่านต้องมีอย่างน้อย 6 ตัวอักษร", "passwordTooShort": "รหัสผ่านต้องมีอย่างน้อย 6 ตัวอักษร",
"passwordsDoNotMatch": "รหัสผ่านใหม่ไม่ตรงกัน" "passwordsDoNotMatch": "รหัสผ่านใหม่ไม่ตรงกัน",
"next": "ถัดไป",
"back": "ย้อนกลับ"
}, },
"classroom": { "classroom": {
"backToDashboard": "กลับไปคอร์สของฉัน", "backToDashboard": "กลับไปคอร์สของฉัน",
@ -185,6 +187,10 @@
"noQuizData": "ไม่มีข้อมูลแบบทดสอบ", "noQuizData": "ไม่มีข้อมูลแบบทดสอบ",
"noQuizDesc": "ไม่พบข้อมูลแบบทดสอบในขณะนี้", "noQuizDesc": "ไม่พบข้อมูลแบบทดสอบในขณะนี้",
"pleaseSelectAnswer": "กรุณาเลือกคำตอบก่อนดำเนินการต่อ", "pleaseSelectAnswer": "กรุณาเลือกคำตอบก่อนดำเนินการต่อ",
"underDevelopment": "ส่วนนี้กำลังพัฒนา" "underDevelopment": "ส่วนนี้กำลังพัฒนา",
"nextBtn": "ข้อถัดไป",
"prevBtn": "ข้อย้อนกลับ",
"submitBtn": "ส่งคำตอบ",
"reviewAnswers": "ทบทวนคำตอบ"
} }
} }

View file

@ -17,6 +17,7 @@ useHead({
}) })
const route = useRoute() const route = useRoute()
const router = useRouter()
const { t } = useI18n() const { t } = useI18n()
const { user } = useAuth() const { user } = useAuth()
const { fetchCourseLearningInfo, fetchLessonContent, saveVideoProgress, markLessonComplete, checkLessonAccess, fetchVideoProgress } = useCourse() const { fetchCourseLearningInfo, fetchLessonContent, saveVideoProgress, markLessonComplete, checkLessonAccess, fetchVideoProgress } = useCourse()
@ -415,8 +416,26 @@ const onVideoEnded = async () => {
const res = await markLessonComplete(courseId.value, currentLesson.value.id) const res = await markLessonComplete(courseId.value, currentLesson.value.id)
if (res.success) { if (res.success) {
markLessonAsCompletedLocally(currentLesson.value.id) markLessonAsCompletedLocally(currentLesson.value.id)
// If course completed
if (res.data.is_course_completed) { if (res.data.is_course_completed) {
alert("ยินดีด้วย! คุณเรียนจบหลักสูตรแล้ว") // Refresh course data to update certificate status
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)
}
} }
} }
} }