feat: implement core e-learning pages, course composable, and i18n localization.

This commit is contained in:
supalerk-ar66 2026-02-09 11:40:41 +07:00
parent f736eb7f38
commit e94410d0e7
9 changed files with 235 additions and 138 deletions

View file

@ -20,7 +20,7 @@ const route = useRoute()
const router = useRouter()
const { t } = useI18n()
const { user } = useAuth()
const { fetchCourseLearningInfo, fetchLessonContent, saveVideoProgress, checkLessonAccess, fetchVideoProgress, fetchCourseAnnouncements, markLessonComplete } = useCourse()
const { fetchCourseLearningInfo, fetchLessonContent, saveVideoProgress, checkLessonAccess, fetchVideoProgress, fetchCourseAnnouncements, markLessonComplete, getLocalizedText } = useCourse()
// Media Prefs (Global Volume)
const { volume, muted: isMuted, setVolume, setMuted, applyTo } = useMediaPrefs()
@ -94,12 +94,6 @@ const currentTime = ref(0)
const duration = ref(0)
// Helper for localization
const getLocalizedText = (text: any) => {
if (!text) return ''
if (typeof text === 'string') return text
return text.th || text.en || ''
}
const toggleSidebar = () => {
sidebarOpen.value = !sidebarOpen.value

View file

@ -238,37 +238,32 @@ const retryQuiz = () => {
}
const submitQuiz = async (auto = false) => {
// if (!auto && !confirm(t('quiz.submitConfirm'))) return
// 1. Manual Validation: Check if all questions are answered
if (!auto) {
const answeredCount = Object.keys(userAnswers.value).length
if (answeredCount < totalQuestions.value) {
$q.notify({
type: 'warning',
message: t('quiz.alertIncomplete', 'กรุณาเลือกคำตอบให้ครบทุกข้อ'),
position: 'top',
timeout: 2000
})
return
}
// Confirmation before submission
if (!confirm(t('quiz.submitConfirm', 'ยืนยันการส่งคำตอบ?'))) {
return
}
}
// 2. Start Submission Process
if (timerInterval) clearInterval(timerInterval)
isSubmitting.value = true
currentScreen.value = 'result' // Switch to result screen immediately to show loader
currentScreen.value = 'result' // Switch to result screen to show progress
try {
// Validate completion (User Request: Must answer ALL questions)
if (!auto) {
const answeredCount = Object.keys(userAnswers.value).length
if (answeredCount < totalQuestions.value) {
$q.notify({
type: 'warning',
message: t('quiz.alertIncomplete', 'กรุณาเลือกคำตอบให้ครบทุกข้อ'),
position: 'top',
timeout: 2000
})
isSubmitting.value = false
currentScreen.value = 'taking'
return
}
// Confirm submission only if manual
if (!confirm(t('quiz.submitConfirm', 'ยืนยันการส่งคำตอบ?'))) {
isSubmitting.value = false
currentScreen.value = 'taking'
return
}
}
// Prepare Payload
const answersPayload = Object.entries(userAnswers.value).map(([qId, cId]) => ({
question_id: Number(qId),
@ -574,6 +569,7 @@ const getCorrectChoiceId = (questionId: number) => {
</button>
<button
v-if="quizResult?.is_passed"
@click="reviewQuiz"
class="w-full py-2 text-blue-500 hover:text-blue-700 dark:hover:text-blue-400 font-bold text-sm transition-colors mt-2"
>