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 Button from "../Low/Button"; import useExamStore from "@/stores/examStore"; export default function FillBlanksSolutions({ id, type, prompt, solutions, words, text, onNext, onBack, }: FillBlanksExercise & CommonProps) { const storeUserSolutions = useExamStore((state) => state.userSolutions); const correctUserSolutions = storeUserSolutions.find( (solution) => solution.exercise === id )?.solutions; const shuffles = useExamStore((state) => state.shuffles); const calculateScore = () => { const total = text.match(/({{\d+}})/g)?.length || 0; const correct = correctUserSolutions!.filter((x) => { const solution = solutions.find((y) => x.id.toString() === y.id.toString())?.solution; if (!solution) return false; const option = words.find((w) => { if (typeof w === "string") { return w.toLowerCase() === x.solution.toLowerCase(); } else if ('letter' in w) { return w.letter.toLowerCase() === x.solution.toLowerCase(); } else { return w.id.toString() === x.id.toString(); } }); if (!option) return false; if (typeof option === "string") { return solution.toLowerCase() === option.toLowerCase(); } else if ('letter' in option) { return solution.toLowerCase() === option.word.toLowerCase(); } 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 }; }; const typeCheckWordsMC = (words: any[]): words is FillBlanksMCOption[] => { return Array.isArray(words) && words.every( word => word && typeof word === 'object' && 'id' in word && 'options' in word ); } const renderLines = (line: string) => { return ( {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 questionShuffleMap = shuffles.find((x) => x.exerciseID == id)?.shuffles.find((y) => y.questionID == questionId); 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 ); answerText = options!.options[correctKey as keyof typeof options]; } else { answerText = answerSolution; } return ( ); } 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 ); const userSolutionText = typeof userSolutionWord === "string" ? userSolutionWord : 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 ); 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; } if (correct) { return ( ); } else { return ( <> ); } })} ); }; return ( <>
{correctUserSolutions && text.split("\\n").map((line, index) => (

{renderLines(line)}

))}
Correct
Unanswered
Wrong
); }