Solved the exercise counter bug

This commit is contained in:
Tiago Ribeiro
2024-03-25 01:16:56 +00:00
parent 08e71c4dd8
commit f02fff55e7
2 changed files with 97 additions and 33 deletions

View File

@@ -1,4 +1,4 @@
import {ReadingExam, UserSolution} from "@/interfaces/exam";
import {MultipleChoiceExercise, ReadingExam, UserSolution} from "@/interfaces/exam";
import {Fragment, useEffect, useState} from "react";
import Icon from "@mdi/react";
import {mdiArrowRight, mdiNotebook} from "@mdi/js";
@@ -85,12 +85,13 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
const [showTextModal, setShowTextModal] = useState(false);
const [showBlankModal, setShowBlankModal] = useState(false);
const [multipleChoicesDone, setMultipleChoicesDone] = useState<{id: string; amount: number}[]>([]);
const {userSolutions, setUserSolutions} = useExamStore((state) => state);
const {hasExamEnded, setHasExamEnded} = useExamStore((state) => state);
const {partIndex, setPartIndex} = useExamStore((state) => state);
const {exerciseIndex, setExerciseIndex} = useExamStore((state) => state);
const setStoreQuestionIndex = useExamStore((state) => state.setQuestionIndex);
const [storeQuestionIndex, setStoreQuestionIndex] = useExamStore((state) => [state.questionIndex, state.setQuestionIndex]);
const scrollToTop = () => Array.from(document.getElementsByTagName("body")).forEach((body) => body.scrollTo(0, 0));
@@ -98,6 +99,21 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
if (showSolutions) setExerciseIndex(-1);
}, [setExerciseIndex, showSolutions]);
useEffect(() => {
const previousParts = exam.parts.filter((_, index) => index < partIndex);
let previousMultipleChoice = previousParts.flatMap((x) => x.exercises).filter((x) => x.type === "multipleChoice") as MultipleChoiceExercise[];
if (partIndex > -1 && exerciseIndex > -1) {
const previousPartExercises = exam.parts[partIndex].exercises.filter((_, index) => index < exerciseIndex);
const partMultipleChoice = previousPartExercises.filter((x) => x.type === "multipleChoice") as MultipleChoiceExercise[];
previousMultipleChoice = [...previousMultipleChoice, ...partMultipleChoice];
}
setMultipleChoicesDone(previousMultipleChoice.map((x) => ({id: x.id, amount: x.questions.length - 1})));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
const listener = (e: KeyboardEvent) => {
if (e.key === "F3" || ((e.ctrlKey || e.metaKey) && e.key === "f")) {
@@ -136,7 +152,10 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
if (solution) {
setUserSolutions([...userSolutions.filter((x) => x.exercise !== solution.exercise), {...solution, module: "reading", exam: exam.id}]);
}
setQuestionIndex((prev) => prev + currentQuestionIndex);
if (storeQuestionIndex > 0) {
const exercise = getExercise();
setMultipleChoicesDone((prev) => [...prev.filter((x) => x.id !== exercise.id), {id: exercise.id, amount: storeQuestionIndex}]);
}
setStoreQuestionIndex(0);
if (exerciseIndex + 1 < exam.parts[partIndex].exercises.length && !hasExamEnded) {
@@ -189,6 +208,31 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
};
};
useEffect(() => {
if (partIndex > -1 && exerciseIndex > -1) {
const exercise = getExercise();
setMultipleChoicesDone((prev) => prev.filter((x) => x.id !== exercise.id));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [exerciseIndex, partIndex]);
const calculateExerciseIndex = () => {
if (partIndex === -1) return 0;
if (partIndex === 0)
return (
(exerciseIndex === -1 ? 0 : exerciseIndex + 1) + storeQuestionIndex + multipleChoicesDone.reduce((acc, curr) => acc + curr.amount, 0)
);
const exercisesPerPart = exam.parts.map((x) => x.exercises.length);
const exercisesDone = exercisesPerPart.filter((_, index) => index < partIndex).reduce((acc, curr) => curr + acc, 0);
return (
exercisesDone +
(exerciseIndex === -1 ? 0 : exerciseIndex + 1) +
storeQuestionIndex +
multipleChoicesDone.reduce((acc, curr) => acc + curr.amount, 0)
);
};
const renderText = () => (
<div className="flex flex-col gap-6 w-full bg-mti-gray-seasalt rounded-xl py-8 px-16 mt-4">
<div className="flex flex-col w-full gap-2">
@@ -216,19 +260,7 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
{partIndex > -1 && <TextModal {...exam.parts[partIndex].text} isOpen={showTextModal} onClose={() => setShowTextModal(false)} />}
<ModuleTitle
minTimer={exam.minTimer}
exerciseIndex={
(exam.parts
.flatMap((x) => x.exercises)
.findIndex(
(x) =>
x.id ===
exam.parts[partIndex > -1 ? partIndex : 0].exercises[exerciseIndex === -1 ? exerciseIndex + 1 : exerciseIndex]
?.id,
) || 0) +
(exerciseIndex === -1 ? 0 : 1) +
questionIndex +
currentQuestionIndex
}
exerciseIndex={calculateExerciseIndex()}
module="reading"
totalExercises={countExercises(exam.parts.flatMap((x) => x.exercises))}
disableTimer={showSolutions}