ENCOA-137: Top right side Next Button on the exams
This commit is contained in:
@@ -1,28 +1,17 @@
|
||||
import { FillBlanksExercise, FillBlanksMCOption, ShuffleMap } from "@/interfaces/exam";
|
||||
import {FillBlanksExercise, FillBlanksMCOption, ShuffleMap} from "@/interfaces/exam";
|
||||
import clsx from "clsx";
|
||||
import reactStringReplace from "react-string-replace";
|
||||
import { CommonProps } from ".";
|
||||
import { Fragment } from "react";
|
||||
import {CommonProps} from ".";
|
||||
import {Fragment} from "react";
|
||||
import Button from "../Low/Button";
|
||||
import useExamStore from "@/stores/examStore";
|
||||
|
||||
export default function FillBlanksSolutions({
|
||||
id,
|
||||
type,
|
||||
prompt,
|
||||
solutions,
|
||||
words,
|
||||
text,
|
||||
onNext,
|
||||
onBack,
|
||||
}: FillBlanksExercise & CommonProps) {
|
||||
export default function FillBlanksSolutions({id, type, prompt, solutions, words, text, onNext, onBack}: FillBlanksExercise & CommonProps) {
|
||||
const storeUserSolutions = useExamStore((state) => state.userSolutions);
|
||||
const {questionIndex, setQuestionIndex, partIndex, exam} = useExamStore((state) => state);
|
||||
|
||||
const correctUserSolutions = storeUserSolutions.find(
|
||||
(solution) => solution.exercise === id
|
||||
)?.solutions;
|
||||
|
||||
const correctUserSolutions = storeUserSolutions.find((solution) => solution.exercise === id)?.solutions;
|
||||
|
||||
const shuffles = useExamStore((state) => state.shuffles);
|
||||
|
||||
const calculateScore = () => {
|
||||
@@ -34,7 +23,7 @@ export default function FillBlanksSolutions({
|
||||
const option = words.find((w) => {
|
||||
if (typeof w === "string") {
|
||||
return w.toLowerCase() === x.solution.toLowerCase();
|
||||
} else if ('letter' in w) {
|
||||
} else if ("letter" in w) {
|
||||
return w.letter.toLowerCase() === x.solution.toLowerCase();
|
||||
} else {
|
||||
return w.id.toString() === x.id.toString();
|
||||
@@ -44,23 +33,20 @@ export default function FillBlanksSolutions({
|
||||
|
||||
if (typeof option === "string") {
|
||||
return solution.toLowerCase() === option.toLowerCase();
|
||||
} else if ('letter' in option) {
|
||||
} else if ("letter" in option) {
|
||||
return solution.toLowerCase() === option.word.toLowerCase();
|
||||
} else if ('options' in option) {
|
||||
} else if ("options" in option) {
|
||||
return option.options[solution as keyof typeof option.options] == x.solution;
|
||||
}
|
||||
return false;
|
||||
}).length;
|
||||
const missing = total - correctUserSolutions!.filter((x) => solutions.find((y) => x.id.toString() === y.id.toString())).length;
|
||||
return { total, correct, missing };
|
||||
return {total, correct, missing};
|
||||
};
|
||||
|
||||
|
||||
const typeCheckWordsMC = (words: any[]): words is FillBlanksMCOption[] => {
|
||||
return Array.isArray(words) && words.every(
|
||||
word => word && typeof word === 'object' && 'id' in word && 'options' in word
|
||||
);
|
||||
}
|
||||
return Array.isArray(words) && words.every((word) => word && typeof word === "object" && "id" in word && "options" in word);
|
||||
};
|
||||
|
||||
const renderLines = (line: string) => {
|
||||
return (
|
||||
@@ -68,17 +54,17 @@ export default function FillBlanksSolutions({
|
||||
{reactStringReplace(line, /({{\d+}})/g, (match) => {
|
||||
const questionId = match.replaceAll(/[\{\}]/g, "");
|
||||
const userSolution = correctUserSolutions!.find((x) => x.id.toString() === questionId.toString());
|
||||
const answerSolution = solutions.find(sol => sol.id.toString() === questionId.toString())!.solution;
|
||||
const answerSolution = solutions.find((sol) => sol.id.toString() === questionId.toString())!.solution;
|
||||
const questionShuffleMap = shuffles.find((x) => x.exerciseID == id)?.shuffles.find((y) => y.questionID == questionId);
|
||||
const newAnswerSolution = questionShuffleMap ? questionShuffleMap.map[answerSolution].toLowerCase() : answerSolution.toLowerCase();
|
||||
const newAnswerSolution = questionShuffleMap
|
||||
? questionShuffleMap.map[answerSolution].toLowerCase()
|
||||
: answerSolution.toLowerCase();
|
||||
|
||||
if (!userSolution) {
|
||||
let answerText;
|
||||
if (typeCheckWordsMC(words)) {
|
||||
const options = words.find((x) => x.id.toString() === questionId.toString());
|
||||
const correctKey = Object.keys(options!.options).find(key =>
|
||||
key.toLowerCase() === newAnswerSolution
|
||||
);
|
||||
const correctKey = Object.keys(options!.options).find((key) => key.toLowerCase() === newAnswerSolution);
|
||||
answerText = options!.options[correctKey as keyof typeof options];
|
||||
} else {
|
||||
answerText = answerSolution;
|
||||
@@ -97,37 +83,34 @@ export default function FillBlanksSolutions({
|
||||
const userSolutionWord = words.find((w) =>
|
||||
typeof w === "string"
|
||||
? w.toLowerCase() === userSolution.solution.toLowerCase()
|
||||
: 'letter' in w
|
||||
? w.letter.toLowerCase() === userSolution.solution.toLowerCase()
|
||||
: 'options' in w
|
||||
? w.id === userSolution.questionId
|
||||
: false
|
||||
: "letter" in w
|
||||
? w.letter.toLowerCase() === userSolution.solution.toLowerCase()
|
||||
: "options" in w
|
||||
? w.id === userSolution.questionId
|
||||
: false,
|
||||
);
|
||||
|
||||
const userSolutionText =
|
||||
typeof userSolutionWord === "string"
|
||||
? userSolutionWord
|
||||
: userSolutionWord && 'letter' in userSolutionWord
|
||||
? userSolutionWord.word
|
||||
: userSolutionWord && 'options' in userSolutionWord
|
||||
? userSolution.solution
|
||||
: userSolution.solution;
|
||||
: userSolutionWord && "letter" in userSolutionWord
|
||||
? userSolutionWord.word
|
||||
: userSolutionWord && "options" in userSolutionWord
|
||||
? userSolution.solution
|
||||
: userSolution.solution;
|
||||
|
||||
let correct;
|
||||
let solutionText;
|
||||
if (typeCheckWordsMC(words)) {
|
||||
const options = words.find((x) => x.id.toString() === questionId.toString());
|
||||
if (options) {
|
||||
const correctKey = Object.keys(options.options).find(key =>
|
||||
key.toLowerCase() === newAnswerSolution
|
||||
);
|
||||
const correctKey = Object.keys(options.options).find((key) => key.toLowerCase() === newAnswerSolution);
|
||||
correct = userSolution.solution == options.options[correctKey as keyof typeof options.options];
|
||||
solutionText = options.options[correctKey as keyof typeof options.options] || answerSolution;
|
||||
} else {
|
||||
correct = false;
|
||||
solutionText = answerSolution;
|
||||
}
|
||||
|
||||
} else {
|
||||
correct = userSolutionText === answerSolution;
|
||||
solutionText = answerSolution;
|
||||
@@ -170,7 +153,25 @@ export default function FillBlanksSolutions({
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex justify-between w-full gap-8">
|
||||
<Button
|
||||
color="purple"
|
||||
variant="outline"
|
||||
onClick={() => onBack({exercise: id, solutions: correctUserSolutions!, score: calculateScore(), type})}
|
||||
className="max-w-[200px] w-full"
|
||||
disabled={exam && typeof partIndex !== "undefined" && exam.module === "level" && questionIndex === 0 && partIndex === 0}>
|
||||
Back
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color="purple"
|
||||
onClick={() => onNext({exercise: id, solutions: correctUserSolutions!, score: calculateScore(), type})}
|
||||
className="max-w-[200px] self-end w-full">
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 mt-4 h-full w-full mb-20">
|
||||
<span className="bg-mti-gray-smoke rounded-xl px-5 py-6">
|
||||
{correctUserSolutions &&
|
||||
@@ -201,25 +202,19 @@ export default function FillBlanksSolutions({
|
||||
<Button
|
||||
color="purple"
|
||||
variant="outline"
|
||||
onClick={() => onBack({ exercise: id, solutions: correctUserSolutions!, score: calculateScore(), type })}
|
||||
onClick={() => onBack({exercise: id, solutions: correctUserSolutions!, score: calculateScore(), type})}
|
||||
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
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
color="purple"
|
||||
onClick={() => onNext({ exercise: id, solutions: correctUserSolutions!, score: calculateScore(), type })}
|
||||
onClick={() => onNext({exercise: id, solutions: correctUserSolutions!, score: calculateScore(), type})}
|
||||
className="max-w-[200px] self-end w-full">
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user