// /public/js/quiz.js // State variables for managing the quiz lifecycle let questions = []; let currentQuestionIndex = 0; let score = 0; let isAnswered = false; // Initializes the quiz by fetching data from the internal API. // Behavior: // - Detects mode (standard vs all) from the window path // - Toggles visibility between loading, error, and quiz states async function initQuiz() { const loadingState = document.getElementById('loading-state'); const quizInterface = document.getElementById('quiz-interface'); const errorState = document.getElementById('error-state'); // Determine if we are in "All Questions" mode based on the current URL const isAllMode = window.location.pathname.includes('/all'); const apiUrl = isAllMode ? '/api/quiz/questions?mode=all' : '/api/quiz/questions'; try { const response = await fetch(apiUrl); if (!response.ok) { throw new Error('Failed to fetch questions'); } questions = await response.json(); loadingState.style.display = 'none'; if (questions.length > 0) { quizInterface.style.display = 'block'; startQuiz(); } else { throw new Error('No questions received'); } } catch (error) { console.error(error); loadingState.style.display = 'none'; errorState.style.display = 'block'; } } // Resets game state and triggers the first question render. function startQuiz() { currentQuestionIndex = 0; score = 0; document.getElementById('total-q').textContent = questions.length; renderQuestion(); } // Handles DOM construction for the current question and answers. // Behavior: // - Randomizes answer order visually for every question // - Attaches correctness data to buttons for validation function renderQuestion() { isAnswered = false; const currentQ = questions[currentQuestionIndex]; // Reset UI and navigation states document.getElementById('next-btn').disabled = true; document.getElementById('feedback-container').style.display = 'none'; document.getElementById('feedback-container').className = 'feedback-box'; // Update progress markers and score display document.getElementById('current-q').textContent = currentQuestionIndex + 1; document.getElementById('score-tracker').textContent = `Score: ${score}`; const progressPercent = ((currentQuestionIndex) / questions.length) * 100; document.getElementById('progress-fill').style.width = `${progressPercent}%`; // Populate question text (English, Phonetic, and Thai) document.getElementById('question-text-en').textContent = currentQ.question; document.getElementById('question-text-ph').textContent = currentQ.question_ph; document.getElementById('question-text-th').textContent = currentQ.question_th; const answersContainer = document.getElementById('answers-container'); answersContainer.innerHTML = ''; // Shuffle answer array to prevent position-based guessing const shuffledAnswers = [...currentQ.answers].sort(() => Math.random() - 0.5); shuffledAnswers.forEach(answer => { const btn = document.createElement('button'); btn.className = 'answer-btn'; // Tag the button for validation during the handleAnswer phase btn.dataset.correct = answer.is_correct; btn.innerHTML = `
You passed the practice test.
à¸à¸à¹à¸ªà¸à¸à¸à¸§à¸²à¸¡à¸¢à¸´à¸à¸à¸µ! à¸à¸¸à¸à¸ªà¸à¸à¸à¹à¸²à¸à¹à¸à¸à¸à¸à¸ªà¸à¸à¸à¸¶à¸à¸«à¸±à¸
`; } else { scoreDisplay.style.color = 'var(--danger-red)'; resultMsg.innerHTML = `You need 75% to pass.
à¸à¸¶à¸à¸à¸à¸à¹à¸à¹à¸ à¸à¸¸à¸à¸à¹à¸à¸à¹à¸à¹à¸à¸°à¹à¸à¸ 75% à¹à¸à¸·à¹à¸à¸ªà¸à¸à¸à¹à¸²à¸
`; } } // Main event loop initialization document.addEventListener('DOMContentLoaded', function() { initQuiz(); document.getElementById('next-btn').addEventListener('click', nextQuestion); document.getElementById('restart-btn').addEventListener('click', function() { document.getElementById('results-interface').style.display = 'none'; document.getElementById('loading-state').style.display = 'block'; initQuiz(); }); });