If someone else wants to join in on the fun be my guest
This commit is contained in:
@@ -20,6 +20,7 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
|
||||
onNext,
|
||||
onBack,
|
||||
}) => {
|
||||
const { shuffleMaps } = useExamStore((state) => state);
|
||||
const [answers, setAnswers] = useState<{ id: string; solution: string }[]>(userSolutions);
|
||||
const hasExamEnded = useExamStore((state) => state.hasExamEnded);
|
||||
|
||||
@@ -62,6 +63,15 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
|
||||
} else if ('letter' in option) {
|
||||
return solution.toLowerCase() === option.word.toLowerCase();
|
||||
} else if ('options' in option) {
|
||||
if (shuffleMaps.length !== 0) {
|
||||
const shuffleMap = shuffleMaps.find((map) => map.id == x.id)
|
||||
if (!shuffleMap) {
|
||||
return false;
|
||||
}
|
||||
const original = shuffleMap[x.solution as keyof typeof shuffleMap];
|
||||
return solution.toLowerCase() === (option.options[original as keyof typeof option.options] || '').toLowerCase();
|
||||
}
|
||||
|
||||
return solution.toLowerCase() === (option.options[x.solution as keyof typeof option.options] || '').toLowerCase();
|
||||
}
|
||||
return false;
|
||||
@@ -119,6 +129,18 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
|
||||
setAnswers((prev) => [...prev.filter((x) => x.id !== id), { id: id, solution: value }]);
|
||||
}
|
||||
|
||||
const getShuffles = () => {
|
||||
let shuffle = {};
|
||||
if (shuffleMaps.length !== 0) {
|
||||
shuffle = {
|
||||
shuffleMaps: shuffleMaps.filter((map) =>
|
||||
answers.some(answer => answer.id === map.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
return shuffle;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-4 mt-4 h-full w-full mb-20">
|
||||
@@ -190,14 +212,14 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
|
||||
<Button
|
||||
color="purple"
|
||||
variant="outline"
|
||||
onClick={() => onBack({ exercise: id, solutions: answers, score: calculateScore(), type })}
|
||||
onClick={() => onBack({ exercise: id, solutions: answers, score: calculateScore(), type, ...getShuffles() })}
|
||||
className="max-w-[200px] w-full">
|
||||
Back
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color="purple"
|
||||
onClick={() => onNext({ exercise: id, solutions: answers, score: calculateScore(), type })}
|
||||
onClick={() => onNext({ exercise: id, solutions: answers, score: calculateScore(), type, ...getShuffles() })}
|
||||
className="max-w-[200px] self-end w-full">
|
||||
Next
|
||||
</Button>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
import {MultipleChoiceExercise, MultipleChoiceQuestion} from "@/interfaces/exam";
|
||||
import { MultipleChoiceExercise, MultipleChoiceQuestion } 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";
|
||||
|
||||
function Question({
|
||||
@@ -14,12 +14,10 @@ function Question({
|
||||
options,
|
||||
userSolution,
|
||||
onSelectOption,
|
||||
setContextHighlight
|
||||
}: MultipleChoiceQuestion & {
|
||||
userSolution: string | undefined;
|
||||
onSelectOption?: (option: string) => void;
|
||||
userSolution: string | undefined;
|
||||
onSelectOption?: (option: string) => void;
|
||||
showSolution?: boolean,
|
||||
setContextHighlight?: React.Dispatch<React.SetStateAction<string[]>>
|
||||
}) {
|
||||
|
||||
/*
|
||||
@@ -35,11 +33,11 @@ function Question({
|
||||
// {renderPrompt(prompt).filter((x) => x?.toString() !== "<u>")}
|
||||
<div className="flex flex-col gap-10">
|
||||
{isNaN(Number(id)) ? (
|
||||
<span dangerouslySetInnerHTML={{__html: prompt}} />
|
||||
<span dangerouslySetInnerHTML={{ __html: prompt }} />
|
||||
) : (
|
||||
<span className="">
|
||||
<>
|
||||
{id} - <span dangerouslySetInnerHTML={{__html: prompt}} />
|
||||
{id} - <span dangerouslySetInnerHTML={{ __html: prompt }} />
|
||||
</>
|
||||
</span>
|
||||
)}
|
||||
@@ -75,53 +73,79 @@ 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, setQuestionIndex} = useExamStore((state) => state);
|
||||
const {userSolutions: storeUserSolutions, setUserSolutions} = useExamStore((state) => state);
|
||||
const { shuffleMaps } = useExamStore((state) => state);
|
||||
const { questionIndex, setQuestionIndex } = useExamStore((state) => state);
|
||||
const { userSolutions: storeUserSolutions, setUserSolutions } = useExamStore((state) => state);
|
||||
const hasExamEnded = useExamStore((state) => state.hasExamEnded);
|
||||
|
||||
const scrollToTop = () => Array.from(document.getElementsByTagName("body")).forEach((body) => body.scrollTo(0, 0));
|
||||
|
||||
useEffect(() => {
|
||||
setUserSolutions([...storeUserSolutions.filter((x) => x.exercise !== id), {exercise: id, solutions: answers, score: calculateScore(), type}]);
|
||||
setUserSolutions(
|
||||
[...storeUserSolutions.filter((x) => x.exercise !== id), {
|
||||
exercise: id, solutions: answers, score: calculateScore(), type
|
||||
}]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [answers]);
|
||||
|
||||
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}]);
|
||||
setAnswers((prev) => [...prev.filter((x) => x.question !== question.id), { option, question: question.id }]);
|
||||
};
|
||||
|
||||
const calculateScore = () => {
|
||||
const total = questions.length;
|
||||
const correct = answers.filter(
|
||||
(x) => questions.find((y) => y.id.toString() === x.question.toString())?.solution === x.option || false,
|
||||
).length;
|
||||
const missing = total - answers.filter((x) => questions.find((y) => y.id.toString() === x.question.toString())).length;
|
||||
const correct = answers.filter((x) => {
|
||||
const matchingQuestion = questions.find((y) => {
|
||||
return y.id.toString() === x.question.toString();
|
||||
});
|
||||
|
||||
return {total, correct, missing};
|
||||
let isSolutionCorrect;
|
||||
if (shuffleMaps.length == 0) {
|
||||
isSolutionCorrect = matchingQuestion?.solution === x.option;
|
||||
} else {
|
||||
const shuffleMap = shuffleMaps.find((map) => map.id == x.question)
|
||||
isSolutionCorrect = shuffleMap?.map[x.option] == matchingQuestion?.solution;
|
||||
}
|
||||
return isSolutionCorrect || false;
|
||||
}).length;
|
||||
const missing = total - correct;
|
||||
|
||||
return { total, correct, missing };
|
||||
};
|
||||
|
||||
const getShuffles = () => {
|
||||
let shuffle = {};
|
||||
if (shuffleMaps.length !== 0) {
|
||||
shuffle = {
|
||||
shuffleMaps: shuffleMaps.filter((map) =>
|
||||
answers.some(answer => answer.question === map.id)
|
||||
)
|
||||
}
|
||||
}
|
||||
return shuffle;
|
||||
}
|
||||
|
||||
const next = () => {
|
||||
if (questionIndex === questions.length - 1) {
|
||||
onNext({exercise: id, solutions: answers, score: calculateScore(), type});
|
||||
onNext({ exercise: id, solutions: answers, score: calculateScore(), type, ...getShuffles() });
|
||||
} else {
|
||||
setQuestionIndex(questionIndex + 1);
|
||||
}
|
||||
|
||||
scrollToTop();
|
||||
};
|
||||
|
||||
const back = () => {
|
||||
if (questionIndex === 0) {
|
||||
onBack({exercise: id, solutions: answers, score: calculateScore(), type});
|
||||
onBack({ exercise: id, solutions: answers, score: calculateScore(), type, ...getShuffles() });
|
||||
} else {
|
||||
setQuestionIndex(questionIndex - 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user