If someone else wants to join in on the fun be my guest
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
/* eslint-disable @next/next/no-img-element */
|
||||
import {MultipleChoiceExercise, MultipleChoiceQuestion} 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";
|
||||
|
||||
function Question({
|
||||
@@ -14,7 +14,30 @@ function Question({
|
||||
solution,
|
||||
options,
|
||||
userSolution,
|
||||
}: MultipleChoiceQuestion & {userSolution: string | undefined; onSelectOption?: (option: string) => void; showSolution?: boolean}) {
|
||||
}: MultipleChoiceQuestion & { userSolution: string | undefined; onSelectOption?: (option: string) => void; showSolution?: boolean }) {
|
||||
const { userSolutions } = useExamStore((state) => state);
|
||||
|
||||
const questionShuffleMap = userSolutions.reduce((foundMap, userSolution) => {
|
||||
if (foundMap) return foundMap;
|
||||
return userSolution.shuffleMaps?.find(map => map.id === id) || null;
|
||||
}, null as ShuffleMap | null);
|
||||
|
||||
const shuffledOptions = new Array(options.length);
|
||||
options.forEach(option => {
|
||||
const newId = questionShuffleMap?.map[option.id];
|
||||
const newIndex = options.findIndex(opt => opt.id === newId);
|
||||
shuffledOptions[newIndex] = option;
|
||||
});
|
||||
|
||||
const lettersMap = ['A', 'B', 'C', 'D'];
|
||||
const optionsWithLetters = shuffledOptions.map((option, index) => ({
|
||||
...option,
|
||||
id: lettersMap[index]
|
||||
}));
|
||||
|
||||
const questionOptions = questionShuffleMap ? optionsWithLetters : options;
|
||||
const newQuestionSolution = questionShuffleMap ? questionShuffleMap.map[solution] : solution;
|
||||
|
||||
const renderPrompt = (prompt: string) => {
|
||||
return reactStringReplace(prompt, /((<u>)[\w\s']+(<\/u>))/g, (match) => {
|
||||
const word = match.replaceAll("<u>", "").replaceAll("</u>", "");
|
||||
@@ -23,11 +46,11 @@ function Question({
|
||||
};
|
||||
|
||||
const optionColor = (option: string) => {
|
||||
if (option === solution && !userSolution) {
|
||||
if (option === newQuestionSolution && !userSolution) {
|
||||
return "!border-mti-gray-davy !text-mti-gray-davy";
|
||||
}
|
||||
|
||||
if (option === solution) {
|
||||
if (option === newQuestionSolution) {
|
||||
return "!border-mti-purple-light !text-mti-purple-light";
|
||||
}
|
||||
|
||||
@@ -47,24 +70,24 @@ function Question({
|
||||
)}
|
||||
<div className="grid grid-cols-4 gap-4 place-items-center">
|
||||
{variant === "image" &&
|
||||
options.map((option) => (
|
||||
questionOptions.map((option) => (
|
||||
<div
|
||||
key={option.id}
|
||||
key={option?.id}
|
||||
className={clsx(
|
||||
"flex flex-col items-center border border-mti-gray-platinum p-4 px-8 rounded-xl gap-4 cursor-pointer bg-white relative",
|
||||
optionColor(option.id),
|
||||
optionColor(option!.id),
|
||||
)}>
|
||||
<span className={clsx("text-sm", solution !== option.id && userSolution !== option.id && "opacity-50")}>{option.id}</span>
|
||||
<img src={option.src!} alt={`Option ${option.id}`} />
|
||||
<span className={clsx("text-sm", newQuestionSolution !== option?.id && userSolution !== option?.id && "opacity-50")}>{option?.id}</span>
|
||||
<img src={option?.src!} alt={`Option ${option?.id}`} />
|
||||
</div>
|
||||
))}
|
||||
{variant === "text" &&
|
||||
options.map((option) => (
|
||||
questionOptions.map((option) => (
|
||||
<div
|
||||
key={option.id}
|
||||
className={clsx("flex border p-4 rounded-xl gap-2 cursor-pointer bg-white text-sm", optionColor(option.id))}>
|
||||
<span className="font-semibold">{option.id}.</span>
|
||||
<span>{option.text}</span>
|
||||
key={option?.id}
|
||||
className={clsx("flex border p-4 rounded-xl gap-2 cursor-pointer bg-white text-sm", optionColor(option!.id))}>
|
||||
<span className="font-semibold">{option?.id}.</span>
|
||||
<span>{option?.text}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@@ -72,8 +95,8 @@ function Question({
|
||||
);
|
||||
}
|
||||
|
||||
export default function MultipleChoice({id, type, prompt, questions, userSolutions, onNext, onBack}: MultipleChoiceExercise & CommonProps) {
|
||||
const {questionIndex, setQuestionIndex} = useExamStore((state) => state);
|
||||
export default function MultipleChoice({ id, type, prompt, questions, userSolutions, onNext, onBack }: MultipleChoiceExercise & CommonProps) {
|
||||
const { questionIndex, setQuestionIndex } = useExamStore((state) => state);
|
||||
|
||||
const calculateScore = () => {
|
||||
const total = questions.length;
|
||||
@@ -82,12 +105,12 @@ export default function MultipleChoice({id, type, prompt, questions, userSolutio
|
||||
).length;
|
||||
const missing = total - userSolutions.filter((x) => questions.find((y) => y.id.toString() === x.question.toString())).length;
|
||||
|
||||
return {total, correct, missing};
|
||||
return { total, correct, missing };
|
||||
};
|
||||
|
||||
const next = () => {
|
||||
if (questionIndex === questions.length - 1) {
|
||||
onNext({exercise: id, solutions: userSolutions, score: calculateScore(), type});
|
||||
onNext({ exercise: id, solutions: userSolutions, score: calculateScore(), type });
|
||||
} else {
|
||||
setQuestionIndex(questionIndex + 1);
|
||||
}
|
||||
@@ -95,7 +118,7 @@ export default function MultipleChoice({id, type, prompt, questions, userSolutio
|
||||
|
||||
const back = () => {
|
||||
if (questionIndex === 0) {
|
||||
onBack({exercise: id, solutions: userSolutions, score: calculateScore(), type});
|
||||
onBack({ exercise: id, solutions: userSolutions, score: calculateScore(), type });
|
||||
} else {
|
||||
setQuestionIndex(questionIndex - 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user