feat: add classroom learning interface with video playback, progress tracking, and a dedicated quiz page.
All checks were successful
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Successful in 52s
Build and Deploy Frontend Learner / Deploy E-learning Frontend Learner to Dev Server (push) Successful in 3s
Build and Deploy Frontend Learner / Notify Deployment Status (push) Successful in 1s
All checks were successful
Build and Deploy Frontend Learner / Build Frontend Learner Docker Image (push) Successful in 52s
Build and Deploy Frontend Learner / Deploy E-learning Frontend Learner to Dev Server (push) Successful in 3s
Build and Deploy Frontend Learner / Notify Deployment Status (push) Successful in 1s
This commit is contained in:
parent
350e3c27b3
commit
220dc0148d
2 changed files with 13 additions and 27 deletions
|
|
@ -606,16 +606,20 @@ onBeforeUnmount(() => {
|
|||
<p class="text-slate-600 dark:text-slate-400 text-base md:text-lg leading-relaxed mb-6" v-if="currentLesson.description">{{ getLocalizedText(currentLesson.description) }}</p>
|
||||
|
||||
<!-- Lesson Content Area (Text/HTML) -->
|
||||
<div v-if="currentLesson.type === 'QUIZ'" class="p-8 bg-gradient-to-br from-blue-50 to-indigo-50 dark:from-slate-800 dark:to-slate-800/50 rounded-2xl border border-blue-100 dark:border-white/5 text-center">
|
||||
<div class="bg-white dark:bg-slate-700 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4 shadow-sm text-blue-500 dark:text-blue-300">
|
||||
<div v-if="currentLesson.type === 'QUIZ'" class="p-8 bg-gradient-to-br from-blue-50/50 to-indigo-50/50 dark:from-slate-800/50 dark:to-slate-900/50 rounded-2xl border border-blue-100 dark:border-white/5 text-center">
|
||||
<div class="bg-white dark:bg-slate-800 w-20 h-20 rounded-full flex items-center justify-center mx-auto mb-4 shadow-sm text-blue-500 dark:text-blue-400 border dark:border-white/10">
|
||||
<q-icon name="quiz" size="40px" />
|
||||
</div>
|
||||
<h2 class="text-xl font-bold mb-2 text-slate-900 dark:text-white">{{ $t('quiz.startTitle', 'แบบทดสอบท้ายบทเรียน') }}</h2>
|
||||
<p class="text-slate-500 dark:text-slate-400 mb-6 max-w-md mx-auto">{{ getLocalizedText(currentLesson.quiz?.description || currentLesson.description) }}</p>
|
||||
|
||||
<div class="flex justify-center flex-wrap gap-3 text-sm text-slate-600 dark:text-slate-300 mb-8">
|
||||
<span v-if="currentLesson.quiz?.questions?.length" class="px-3 py-1 bg-white dark:bg-slate-900 rounded-full border border-gray-200 dark:border-white/10 shadow-sm flex items-center gap-1.5"><q-icon name="format_list_numbered" size="14px" class="text-blue-500" /> {{ currentLesson.quiz.questions.length }} ข้อ</span>
|
||||
<span v-if="currentLesson.quiz?.time_limit" class="px-3 py-1 bg-white dark:bg-slate-900 rounded-full border border-gray-200 dark:border-white/10 shadow-sm flex items-center gap-1.5"><q-icon name="schedule" size="14px" class="text-orange-500" /> {{ currentLesson.quiz.time_limit }} นาที</span>
|
||||
<div class="flex justify-center flex-wrap gap-3 text-sm mb-8">
|
||||
<span v-if="currentLesson.quiz?.questions?.length" class="px-3 py-1 bg-white dark:bg-white rounded-full border border-gray-200 dark:border-white/10 shadow-sm flex items-center gap-1.5 text-slate-900 font-bold">
|
||||
<q-icon name="format_list_numbered" size="14px" class="text-blue-600" /> {{ currentLesson.quiz.questions.length }} ข้อ
|
||||
</span>
|
||||
<span v-if="currentLesson.quiz?.time_limit" class="px-3 py-1 bg-white dark:bg-white rounded-full border border-gray-200 dark:border-white/10 shadow-sm flex items-center gap-1.5 text-slate-900 font-bold">
|
||||
<q-icon name="schedule" size="14px" class="text-orange-600" /> {{ currentLesson.quiz.time_limit }} นาที
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<q-btn
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ const getQuestionStatusClass = (index: number, questionId: number) => {
|
|||
}
|
||||
|
||||
// 4. Not Started = Grey
|
||||
return 'bg-slate-200 text-slate-400 border-slate-300 dark:bg-white/5 dark:border-white/10 dark:text-slate-500 hover:bg-slate-300 dark:hover:bg-white/10'
|
||||
return 'bg-slate-200 text-slate-400 border-slate-300 dark:bg-white/5 dark:border-white/5 dark:text-slate-600 hover:bg-slate-300 dark:hover:bg-white/10'
|
||||
}
|
||||
|
||||
const jumpToQuestion = (targetIndex: number) => {
|
||||
|
|
@ -377,7 +377,7 @@ const getCorrectChoiceId = (questionId: number) => {
|
|||
|
||||
<div class="flex justify-center mb-10">
|
||||
<div class="w-20 h-20 rounded-3xl bg-blue-50 dark:bg-blue-500/10 border border-blue-100 dark:border-blue-500/20 flex items-center justify-center shadow-inner">
|
||||
<q-icon name="quiz" size="2rem" color="primary" />
|
||||
<q-icon name="quiz" size="2.5rem" color="primary" class="dark:text-blue-400" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -466,25 +466,7 @@ const getCorrectChoiceId = (questionId: number) => {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mb-8 px-2">
|
||||
<div class="text-xs font-bold text-slate-400 uppercase tracking-widest mb-3">
|
||||
{{ $t('quiz.statusLabel', 'สถานะข้อสอบ') }}
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-4">
|
||||
<div class="flex items-center gap-2 text-sm font-medium text-slate-500 dark:text-slate-400">
|
||||
<div class="w-2.5 h-2.5 rounded-full bg-blue-500 ring-2 ring-blue-100 dark:ring-blue-900/30"></div> {{ $t('quiz.statusCurrent', 'Current') }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm font-medium text-slate-500 dark:text-slate-400">
|
||||
<div class="w-2.5 h-2.5 rounded-full bg-emerald-500"></div> {{ $t('quiz.statusCompleted', 'Completed') }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm font-medium text-slate-500 dark:text-slate-400">
|
||||
<div class="w-2.5 h-2.5 rounded-full bg-orange-500"></div> {{ $t('quiz.statusSkipped', 'Skipped') }}
|
||||
</div>
|
||||
<div class="flex items-center gap-2 text-sm font-medium text-slate-500 dark:text-slate-400">
|
||||
<div class="w-2.5 h-2.5 rounded-full bg-slate-200 dark:bg-slate-700"></div> {{ $t('quiz.statusNotStarted', 'Not Started') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Controls -->
|
||||
<div class="flex justify-between items-center pt-8 border-t border-slate-100 dark:border-white/5">
|
||||
|
|
@ -602,7 +584,7 @@ const getCorrectChoiceId = (questionId: number) => {
|
|||
:class="{
|
||||
'border-emerald-500 bg-emerald-50 dark:bg-emerald-500/10': choice.id === getCorrectChoiceId(question.id),
|
||||
'border-red-500 bg-red-50 dark:bg-red-500/10': userAnswers[question.id] === choice.id && choice.id !== getCorrectChoiceId(question.id),
|
||||
'border-slate-100 dark:border-white/5 opacity-60': userAnswers[question.id] !== choice.id && choice.id !== getCorrectChoiceId(question.id)
|
||||
'border-slate-100 dark:border-white/5 opacity-80 dark:opacity-40': userAnswers[question.id] !== choice.id && choice.id !== getCorrectChoiceId(question.id)
|
||||
}"
|
||||
>
|
||||
<!-- Indicator Icon -->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue