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();
}