Skip to content

Commit 55702cd

Browse files
committed
Enhance quiz category generation by adding a 'comprehensive' category option. Improve QuestionRenderer to shuffle answer options and maintain correct answer mapping. Update QuizInterface layout for better alignment of question navigator.
1 parent 882d5da commit 55702cd

3 files changed

Lines changed: 40 additions & 11 deletions

File tree

app/quiz/[category]/page.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ import { getCategoriesForStaticGeneration } from '@/lib/getCategoriesStatic';
33

44
export function generateStaticParams() {
55
const categories = getCategoriesForStaticGeneration();
6-
return categories.map(category => ({
7-
category,
8-
}));
6+
return [
7+
...categories.map(category => ({
8+
category,
9+
})),
10+
{ category: 'comprehensive' },
11+
];
912
}
1013

1114
interface PageProps {

components/QuestionRenderer.tsx

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
'use client';
22

3-
import { useEffect, useRef, useState } from 'react';
3+
import { useEffect, useRef, useState, useMemo } from 'react';
44
import Prism from 'prismjs';
55
import 'prismjs/components/prism-javascript';
66
import type { Question } from '@/lib/types';
77
import { CodePlayground } from './CodePlayground';
8+
import { shuffleArray } from '@/lib/utils';
89

910
interface QuestionRendererProps {
1011
question: Question;
@@ -28,6 +29,22 @@ function QuestionRendererContent({
2829
// Derive usePlayground - disable if question requires non-strict mode
2930
const usePlayground = question.nonStrictMode ? false : usePlaygroundInternal;
3031

32+
const { shuffledOptions, shuffledToOriginal, originalToShuffled } = useMemo(() => {
33+
const indices = question.options.map((_, i) => i);
34+
const shuffledIndices = shuffleArray(indices);
35+
36+
const shuffledOptions = shuffledIndices.map(i => question.options[i]);
37+
const shuffledToOriginal = new Map<number, number>();
38+
const originalToShuffled = new Map<number, number>();
39+
40+
shuffledIndices.forEach((originalIndex, shuffledIndex) => {
41+
shuffledToOriginal.set(shuffledIndex, originalIndex);
42+
originalToShuffled.set(originalIndex, shuffledIndex);
43+
});
44+
45+
return { shuffledOptions, shuffledToOriginal, originalToShuffled };
46+
}, [question.options]);
47+
3148
useEffect(() => {
3249
if (question.code && codeRef.current) {
3350
Prism.highlightElement(codeRef.current);
@@ -162,9 +179,11 @@ function QuestionRendererContent({
162179
)}
163180

164181
<div className="space-y-2">
165-
{question.options.map((option, index) => {
166-
const isSelected = selectedAnswer === index;
167-
const isCorrect = index === question.correctAnswer;
182+
{shuffledOptions.map((option, shuffledIndex) => {
183+
const originalIndex = shuffledToOriginal.get(shuffledIndex)!;
184+
const isSelected = selectedAnswer === originalIndex;
185+
const correctShuffledIndex = originalToShuffled.get(question.correctAnswer);
186+
const isCorrect = correctShuffledIndex !== undefined && shuffledIndex === correctShuffledIndex;
168187

169188
let buttonClass = 'option-button-compact';
170189

@@ -180,14 +199,21 @@ function QuestionRendererContent({
180199

181200
return (
182201
<button
183-
key={index}
184-
onClick={() => !disabled && onSelectAnswer?.(index)}
202+
key={shuffledIndex}
203+
onClick={() => {
204+
if (!disabled && onSelectAnswer) {
205+
const originalIdx = shuffledToOriginal.get(shuffledIndex);
206+
if (originalIdx !== undefined) {
207+
onSelectAnswer(originalIdx);
208+
}
209+
}
210+
}}
185211
disabled={disabled}
186212
className={buttonClass}
187213
>
188214
<div className="flex items-center gap-3">
189215
<span className="option-letter-compact">
190-
{String.fromCharCode(65 + index)}
216+
{String.fromCharCode(65 + shuffledIndex)}
191217
</span>
192218
<span className="flex-1 text-left text-sm">{option}</span>
193219
{showCorrect && isCorrect && (

components/QuizInterface.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export function QuizInterface({ questions, category }: QuizInterfaceProps) {
230230

231231
<div
232232
ref={questionNavigatorRef}
233-
className="flex items-center gap-1 sm:gap-1.5 mt-2 overflow-x-auto pb-1 question-navigator-scroll -mx-1 px-1 justify-start"
233+
className="flex items-center gap-1 sm:gap-1.5 mt-2 overflow-x-auto pb-1 question-navigator-scroll -mx-1 px-1 justify-start sm:justify-center"
234234
>
235235
{currentSession.questions.map((qId, idx) => {
236236
const isAnswered = answers.has(qId);

0 commit comments

Comments
 (0)