Spaces:
Sleeping
Sleeping
File size: 12,074 Bytes
a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 9aff625 a82e7d4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
const quizContainer = document.getElementById('quiz');
const scoreContainer = document.getElementById('score');
const quizInfoContainer = document.getElementById('quiz-info');
let totalQuestions = 0;
let correctAnswers = 0;
let currentCardIndex = 0;
// Remove the DOMContentLoaded event listener since initialization is now handled in index.html
// The displayQuiz function will be called from the HTML after quiz data is loaded
function displayQuiz(data) {
const quizContainer = document.getElementById('quiz');
// Clear any existing content
quizContainer.innerHTML = '';
// Get saved progress or start from beginning
const progress = data.progress || {};
currentCardIndex = progress.current_card || 0;
data.cards.forEach((question, index) => {
const questionDiv = document.createElement('div');
questionDiv.className = 'question-container';
// Show cards up to and including current position
if (index <= currentCardIndex) {
questionDiv.classList.add('active');
}
if (question.type === 'concept') {
questionDiv.innerHTML = `
<div class="concept-content">
<h2>${question.content.heading}</h2>
<p>${question.content.sentence1}</p>
<p>${question.content.sentence2}</p>
<p>${question.content.sentence3}</p>
</div>
<button class="submit-answer-btn" onclick="nextQuestion(${index})">Continue</button>
`;
} else {
const isAnswered = progress.answers && progress.answers[index.toString()];
const userAnswer = isAnswered ? progress.answers[index.toString()].selected : null;
const isCorrect = isAnswered ? progress.answers[index.toString()].correct : false;
questionDiv.innerHTML = `
<div class="question">${getQuestionNumber(data.cards, index)}. ${question.question}</div>
<div class="choices">
${question.choices.map((choice, choiceIndex) => `
<label class="choice-label">
<input type="radio" name="q${index}" value="${choice}"
${userAnswer === choice ? 'checked' : ''}
${isAnswered ? 'disabled' : ''}>
<span>${choice}</span>
</label>
`).join('')}
</div>
<button class="submit-answer-btn" onclick="submitAnswer(${index})"
${isAnswered ? 'disabled' : ''}>
${isAnswered ? 'Answered' : 'Submit Answer'}
</button>
<div id="feedback-${index}" class="feedback" ${isAnswered ? 'style="display: block;"' : ''}>
<div id="result-${index}" class="${isAnswered ? (isCorrect ? 'correct' : 'incorrect') : ''}">
${isAnswered ? (isCorrect ? 'β Correct!' : `β Incorrect. The correct answer is: ${question.answer}`) : ''}
</div>
<div id="justification-${index}" class="justification">
${isAnswered ? question.justification : ''}
</div>
</div>
`;
// Apply correct/incorrect styling if already answered
if (isAnswered) {
const feedbackDiv = questionDiv.querySelector(`#feedback-${index}`);
feedbackDiv.className = `feedback ${isCorrect ? 'correct' : 'incorrect'}`;
}
}
quizContainer.appendChild(questionDiv);
});
// Update initial score display
updateScore();
// Find the next unanswered question to resume at
let resumeIndex = currentCardIndex;
if (progress.answers) {
// Find the first unanswered question or concept after answered ones
for (let i = 0; i < data.cards.length; i++) {
if (data.cards[i].type === 'concept') {
// Always show concept cards
continue;
} else if (!progress.answers[i.toString()]) {
// Found first unanswered question
resumeIndex = i;
break;
}
}
// Update currentCardIndex to the resume position
currentCardIndex = Math.max(currentCardIndex, resumeIndex);
// Make sure all cards up to the resume point are visible
data.cards.forEach((card, index) => {
if (index <= currentCardIndex) {
const cardElement = document.querySelector(`.question-container:nth-child(${index + 1})`);
if (cardElement) {
cardElement.classList.add('active');
}
}
});
}
// Scroll to the appropriate position when resuming
if (currentCardIndex > 0 || resumeIndex > 0) {
setTimeout(() => {
const targetIndex = Math.max(currentCardIndex, resumeIndex);
const targetCard = document.querySelector(`.question-container:nth-child(${targetIndex + 1})`);
if (targetCard) {
targetCard.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
}, 500);
// Save the updated progress if we advanced the position
if (currentCardIndex > (progress.current_card || 0)) {
saveQuizProgress();
}
}
}
function getQuestionNumber(cards, cardIndex) {
// Count only quiz questions before this index
let questionNumber = 0;
for (let i = 0; i <= cardIndex; i++) {
if (cards[i].type !== 'concept') {
questionNumber++;
}
}
return questionNumber;
}
async function saveQuizProgress() {
if (!window.currentQuizFilename) return;
const progress = {
current_card: currentCardIndex,
answers: {},
correct_count: 0,
incorrect_count: 0,
completed: false,
last_updated: new Date().toISOString()
};
// Collect all answered questions
quizData.cards.forEach((question, index) => {
if (question.type === 'concept') return;
const selectedAnswer = document.querySelector(`input[name="q${index}"]:checked`);
const feedbackDiv = document.getElementById(`feedback-${index}`);
if (selectedAnswer && feedbackDiv && feedbackDiv.style.display === 'block') {
const isCorrect = selectedAnswer.value === question.answer;
progress.answers[index.toString()] = {
selected: selectedAnswer.value,
correct: isCorrect
};
if (isCorrect) {
progress.correct_count++;
} else {
progress.incorrect_count++;
}
}
});
// Check if quiz is completed
const totalQuizQuestions = quizData.cards.filter(q => q.type !== 'concept').length;
progress.completed = (progress.correct_count + progress.incorrect_count) >= totalQuizQuestions;
// Save progress via API
try {
const response = await fetch('/api/save-progress', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
filename: window.currentQuizFilename,
progress: progress
})
});
if (response.ok) {
console.log('Progress saved successfully');
}
} catch (error) {
console.error('Failed to save progress:', error);
}
}
function submitAnswer(questionIndex) {
const selectedAnswer = document.querySelector(`input[name="q${questionIndex}"]:checked`);
const feedbackDiv = document.getElementById(`feedback-${questionIndex}`);
const resultDiv = document.getElementById(`result-${questionIndex}`);
const justificationDiv = document.getElementById(`justification-${questionIndex}`);
const submitButton = feedbackDiv.previousElementSibling;
if (!selectedAnswer) {
alert('Please select an answer first!');
return;
}
const question = quizData.cards[questionIndex];
const isCorrect = selectedAnswer.value === question.answer;
feedbackDiv.style.display = 'block';
feedbackDiv.className = `feedback ${isCorrect ? 'correct' : 'incorrect'}`;
resultDiv.textContent = isCorrect ?
'β Correct!' :
`β Incorrect. The correct answer is: ${question.answer}`;
justificationDiv.textContent = question.justification;
// Disable the submit button and radio buttons after submission
submitButton.disabled = true;
submitButton.textContent = 'Answered';
document.querySelectorAll(`input[name="q${questionIndex}"]`).forEach(input => {
input.disabled = true;
});
// Update current card index
currentCardIndex = Math.max(currentCardIndex, questionIndex);
// Update the overall score
updateScore();
// Save progress
saveQuizProgress();
// Scroll to the feedback section instead of the next question
feedbackDiv.scrollIntoView({ behavior: 'smooth', block: 'center' });
// Show next question (without scrolling)
const nextQuestion = document.querySelector(`.question-container:nth-child(${questionIndex + 2})`);
if (nextQuestion) {
nextQuestion.classList.add('active');
}
}
function updateScore() {
let correctAnswers = 0;
let incorrectAnswers = 0;
const totalQuestions = quizData.cards.filter(q => q.type !== 'concept').length;
quizData.cards.forEach((question, index) => {
// Skip concept cards
if (question.type === 'concept') return;
const feedbackDiv = document.getElementById(`feedback-${index}`);
if (feedbackDiv && feedbackDiv.classList.contains('correct')) {
correctAnswers++;
} else if (feedbackDiv && feedbackDiv.style.display === 'block') {
incorrectAnswers++;
}
});
// Calculate and update score percentage
const scorePercentage = Math.round((correctAnswers / totalQuestions) * 100) || 0;
document.getElementById('score-percentage').textContent = scorePercentage;
// Update progress bars and counts
const correctProgress = document.getElementById('correct-progress');
const incorrectProgress = document.getElementById('incorrect-progress');
const correctCount = document.getElementById('correct-count');
const incorrectCount = document.getElementById('incorrect-count');
const remainingCount = document.getElementById('remaining-count');
correctProgress.style.width = `${(correctAnswers / totalQuestions) * 100}%`;
incorrectProgress.style.width = `${(incorrectAnswers / totalQuestions) * 100}%`;
correctCount.textContent = correctAnswers;
incorrectCount.textContent = incorrectAnswers;
remainingCount.textContent = totalQuestions - (correctAnswers + incorrectAnswers);
}
// Hide the original submit button since we're now handling individual submissions
document.addEventListener('DOMContentLoaded', function() {
const submitButton = document.getElementById('submit-button');
if (submitButton) {
submitButton.style.display = 'none';
}
});
// Add this function to handle the concept card navigation
function nextQuestion(index) {
// Update current card index
currentCardIndex = Math.max(currentCardIndex, index);
const nextQuestion = document.querySelector(`.question-container:nth-child(${index + 2})`);
if (nextQuestion) {
// Show next question
nextQuestion.classList.add('active');
// Scroll to the next question smoothly
nextQuestion.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
// Save progress after advancing through concept
saveQuizProgress();
} |