From 4654c21d922b5fa9d2fc4b7d3ae93702b871e878 Mon Sep 17 00:00:00 2001 From: Tiago Ribeiro Date: Wed, 4 Sep 2024 11:41:48 +0100 Subject: [PATCH] ENCOA-154: Increase the number of questions per page in all modules (Priority in Level Test) --- src/components/Exercises/MultipleChoice.tsx | 114 ++++++++++---------- src/components/Solutions/MultipleChoice.tsx | 40 ++++--- 2 files changed, 82 insertions(+), 72 deletions(-) diff --git a/src/components/Exercises/MultipleChoice.tsx b/src/components/Exercises/MultipleChoice.tsx index 0de7dd17..d98d9301 100644 --- a/src/components/Exercises/MultipleChoice.tsx +++ b/src/components/Exercises/MultipleChoice.tsx @@ -1,12 +1,12 @@ /* eslint-disable @next/next/no-img-element */ -import { MultipleChoiceExercise, MultipleChoiceQuestion, ShuffleMap } from "@/interfaces/exam"; +import {MultipleChoiceExercise, MultipleChoiceQuestion, ShuffleMap} from "@/interfaces/exam"; import useExamStore from "@/stores/examStore"; import clsx from "clsx"; -import { useEffect, useState } from "react"; +import {useEffect, useState} from "react"; import reactStringReplace from "react-string-replace"; -import { CommonProps } from "."; +import {CommonProps} from "."; import Button from "../Low/Button"; -import { v4 } from "uuid"; +import {v4} from "uuid"; function Question({ id, @@ -18,9 +18,8 @@ function Question({ }: MultipleChoiceQuestion & { userSolution: string | undefined; onSelectOption?: (option: string) => void; - showSolution?: boolean, + showSolution?: boolean; }) { - const renderPrompt = (prompt: string) => { return reactStringReplace(prompt, /(.*?<\/u>)/g, (match) => { const word = match.replaceAll("", "").replaceAll("", ""); @@ -49,7 +48,9 @@ function Question({ "flex flex-col items-center border border-mti-gray-platinum p-4 px-8 rounded-xl gap-4 cursor-pointer bg-white relative select-none", userSolution === option.id.toString() && "border-mti-purple-light", )}> - {option.id.toString()} + + {option.id.toString()} + {`Option ))} @@ -71,38 +72,30 @@ function Question({ ); } -export default function MultipleChoice({ id, prompt, type, questions, userSolutions, onNext, onBack }: MultipleChoiceExercise & CommonProps) { - const [answers, setAnswers] = useState<{ question: string; option: string }[]>(userSolutions); +export default function MultipleChoice({id, prompt, type, questions, userSolutions, onNext, onBack}: MultipleChoiceExercise & CommonProps) { + const [answers, setAnswers] = useState<{question: string; option: string}[]>(userSolutions); - const { - questionIndex, - exerciseIndex, - exam, - shuffles, - hasExamEnded, - partIndex, - setQuestionIndex, - setCurrentSolution - } = useExamStore((state) => state); + const {questionIndex, exerciseIndex, exam, shuffles, hasExamEnded, partIndex, setQuestionIndex, setCurrentSolution} = useExamStore( + (state) => state, + ); const shuffleMaps = shuffles.find((x) => x.exerciseID == id)?.shuffles; const scrollToTop = () => Array.from(document.getElementsByTagName("body")).forEach((body) => body.scrollTo(0, 0)); useEffect(() => { - if (hasExamEnded) onNext({ exercise: id, solutions: answers, score: calculateScore(), type }); + if (hasExamEnded) onNext({exercise: id, solutions: answers, score: calculateScore(), type}); // eslint-disable-next-line react-hooks/exhaustive-deps }, [hasExamEnded]); - const onSelectOption = (option: string) => { - const question = questions[questionIndex]; - setAnswers((prev) => [...prev.filter((x) => x.question !== question.id), { option, question: question.id }]); + const onSelectOption = (option: string, question: MultipleChoiceQuestion) => { + setAnswers((prev) => [...prev.filter((x) => x.question !== question.id), {option, question: question.id}]); }; useEffect(() => { - setCurrentSolution({ exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps }); + setCurrentSolution({exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps}); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [answers, setAnswers]) + }, [answers, setAnswers]); const getShuffledSolution = (originalSolution: string, questionShuffleMap: ShuffleMap) => { for (const [newPosition, originalPosition] of Object.entries(questionShuffleMap.map)) { @@ -111,8 +104,7 @@ export default function MultipleChoice({ id, prompt, type, questions, userSoluti } } return originalSolution; - } - + }; const calculateScore = () => { const total = questions.length; @@ -135,24 +127,24 @@ export default function MultipleChoice({ id, prompt, type, questions, userSoluti return isSolutionCorrect || false; }).length; const missing = total - answers!.filter((x) => questions.find((y) => x.question.toString() === y.id.toString())).length; - return { total, correct, missing }; + return {total, correct, missing}; }; const next = () => { - if (questionIndex === questions.length - 1) { - onNext({ exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps }); + if (questionIndex + 1 >= questions.length - 1) { + onNext({exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps}); } else { - setQuestionIndex(questionIndex + 1); + setQuestionIndex(questionIndex + 2); } scrollToTop(); }; const back = () => { if (questionIndex === 0) { - onBack({ exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps }); + onBack({exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps}); } else { - if (exam?.module === "level" && typeof exam.parts[0].intro !== "undefined" && questionIndex === 0) return; - setQuestionIndex(questionIndex - 1); + if (exam?.module === "level" && typeof exam.parts[0].intro !== "undefined" && questionIndex === 0) return; + setQuestionIndex(questionIndex - 2); } scrollToTop(); @@ -160,35 +152,47 @@ export default function MultipleChoice({ id, prompt, type, questions, userSoluti return ( <> -
- {/*{"Select the appropriate option."}*/} - {questionIndex < questions.length && ( - questions[questionIndex].id === x.question)?.option} - onSelectOption={onSelectOption} - /> +
+
+ {/*{"Select the appropriate option."}*/} + {questionIndex < questions.length && ( + questions[questionIndex].id === x.question)?.option} + onSelectOption={(option) => onSelectOption(option, questions[questionIndex])} + /> + )} +
+ + {questionIndex + 1 < questions.length && ( +
+ questions[questionIndex + 1].id === x.question)?.option} + onSelectOption={(option) => onSelectOption(option, questions[questionIndex + 1])} + /> +
)}
-
diff --git a/src/components/Solutions/MultipleChoice.tsx b/src/components/Solutions/MultipleChoice.tsx index 0c28555d..665be922 100644 --- a/src/components/Solutions/MultipleChoice.tsx +++ b/src/components/Solutions/MultipleChoice.tsx @@ -111,10 +111,10 @@ export default function MultipleChoice({id, type, prompt, questions, userSolutio }; const next = () => { - if (questionIndex === questions.length - 1) { + if (questionIndex + 1 >= questions.length - 1) { onNext({exercise: id, solutions: userSolutions, score: calculateScore(), type}); } else { - setQuestionIndex(questionIndex + 1); + setQuestionIndex(questionIndex + 2); } }; @@ -122,22 +122,34 @@ export default function MultipleChoice({id, type, prompt, questions, userSolutio if (questionIndex === 0) { onBack({exercise: id, solutions: userSolutions, score: calculateScore(), type}); } else { - setQuestionIndex(questionIndex - 1); + setQuestionIndex(questionIndex - 2); } }; return ( <>
-
- {/*{prompt}*/} - {userSolutions && questionIndex < questions.length && ( - questions[questionIndex].id === x.question)?.option} - /> +
+
+ {/*{prompt}*/} + {userSolutions && questionIndex < questions.length && ( + questions[questionIndex].id === x.question)?.option} + /> + )} +
+ + {userSolutions && questionIndex + 1 < questions.length && ( +
+ questions[questionIndex + 1].id === x.question)?.option} + /> +
)}
+
@@ -160,13 +172,7 @@ export default function MultipleChoice({id, type, prompt, questions, userSolutio variant="outline" onClick={back} className="max-w-[200px] w-full" - disabled={ - exam && - typeof partIndex !== "undefined" && - exam.module === "level" && - questionIndex === 0 && - partIndex === 0 - }> + disabled={exam && typeof partIndex !== "undefined" && exam.module === "level" && questionIndex === 0 && partIndex === 0}> Back