Navigation rework, added prompt edit to components that were missing

This commit is contained in:
Carlos-Mesquita
2024-11-25 16:50:46 +00:00
parent e9b7bd14cc
commit 114da173be
105 changed files with 3761 additions and 3728 deletions

View File

@@ -39,7 +39,7 @@ const MCDropdown: React.FC<MCDropdownProps> = ({
});
return (
<div className={`${className} inline-block`} style={{ width: `${width}px` }}>
<div key={`dropdown-${id}`} className={`${className} inline-block`} style={{ width: `${width}px` }}>
<button
onClick={() => onToggle(id)}
className={

View File

@@ -1,12 +1,13 @@
//import "@/utils/wdyr";
import { FillBlanksExercise, FillBlanksMCOption } from "@/interfaces/exam";
import useExamStore, { usePersistentExamStore } from "@/stores/examStore";
import clsx from "clsx";
import { Fragment, useCallback, useEffect, useMemo, useRef, useState } from "react";
import reactStringReplace from "react-string-replace";
import { CommonProps } from "..";
import Button from "../../Low/Button";
import { CommonProps } from "../types";
import { v4 } from "uuid";
import MCDropdown from "./MCDropdown";
import useExamStore, { usePersistentExamStore } from "@/stores/exam";
const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
id,
@@ -18,43 +19,29 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
words,
userSolutions,
variant,
registerSolution,
headerButtons,
footerButtons,
preview,
onNext,
onBack,
disableProgressButtons = false
}) => {
const examState = useExamStore((state) => state);
const persistentExamState = usePersistentExamStore((state) => state);
const {
hasExamEnded,
exerciseIndex,
partIndex,
questionIndex,
shuffles,
exam,
setCurrentSolution,
} = !preview ? examState : persistentExamState;
} = examState; !preview ? examState : persistentExamState;
const [answers, setAnswers] = useState<{ id: string; solution: string }[]>(userSolutions);
const shuffleMaps = shuffles.find((x) => x.exerciseID == id)?.shuffles;
const dropdownRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (disableProgressButtons) onNext({ exercise: id, solutions: answers, score: calculateScore(), type, isPractice });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [answers, disableProgressButtons])
const excludeWordMCType = (x: any) => {
return typeof x === "string" ? x : (x as { letter: string; word: string });
};
useEffect(() => {
if (hasExamEnded) onNext({ exercise: id, solutions: answers, score: calculateScore(), type });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasExamEnded]);
let correctWords: any;
if (exam && (exam.module === "level" || exam.module === "reading") && exam.parts[partIndex].exercises[exerciseIndex].type === "fillBlanks") {
correctWords = (exam.parts[partIndex].exercises[exerciseIndex] as FillBlanksExercise).words;
@@ -73,7 +60,7 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
};
}, []);
const calculateScore = () => {
const calculateScore = useCallback(() => {
const total = text.match(/({{\d+}})/g)?.length || 0;
const correct = answers!.filter((x) => {
const solution = solutions.find((y) => x.id.toString() === y.id.toString())?.solution;
@@ -100,7 +87,19 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
}).length;
const missing = total - answers!.filter((x) => solutions.find((y) => x.id.toString() === y.id.toString())).length;
return { total, correct, missing };
};
}, [answers, correctWords, solutions, text]);
useEffect(() => {
registerSolution(() => ({
exercise: id,
solutions: answers,
score: calculateScore(),
type,
shuffleMaps,
isPractice
}));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [id, answers, type, isPractice, shuffleMaps, calculateScore]);
const [openDropdownId, setOpenDropdownId] = useState<string | null>(null);
@@ -137,6 +136,7 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
/>
) : (
<input
key={`input-${id}`}
className={styles}
onChange={(e) => setAnswers((prev) => [...prev.filter((x) => x.id !== id), { id, solution: e.target.value }])}
value={userSolution?.solution}
@@ -151,10 +151,10 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
const memoizedLines = useMemo(() => {
return text.split("\\n").map((line, index) => (
<p key={index} className={clsx(variant === "mc" && "whitespace-pre-wrap")}>
<div key={index} className={clsx(variant === "mc" && "whitespace-pre-wrap")}>
{renderLines(line)}
<br />
</p>
</div>
));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [text, variant, renderLines]);
@@ -163,40 +163,10 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
setAnswers((prev) => [...prev.filter((x) => x.id !== questionID), { id: questionID, solution: value }]);
};
useEffect(() => {
if (variant === "mc") {
setCurrentSolution({ exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps });
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [answers]);
const progressButtons = () => (
<div className="flex justify-between w-full gap-8">
<Button
color="purple"
variant="outline"
onClick={() => onBack({ exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps, isPractice })}
className="max-w-[200px] w-full"
disabled={exam && exam.module === "level" && partIndex === 0 && questionIndex === 0}>
Previous Page
</Button>
<Button
color="purple"
onClick={() => {
onNext({ exercise: id, solutions: answers, score: calculateScore(), type, shuffleMaps: shuffleMaps, isPractice });
}}
className="max-w-[200px] self-end w-full">
Next Page
</Button>
</div>
)
return (
<div className="flex flex-col gap-4">
{!disableProgressButtons && progressButtons()}
<div className={clsx("flex flex-col gap-4 mt-4 h-full w-full", !disableProgressButtons && "mb-20")}>
{headerButtons}
<div className={clsx("flex flex-col gap-4 mt-4 h-full w-full", (!headerButtons && !footerButtons) && "mb-20")}>
{variant !== "mc" && (
<span className="text-sm w-full leading-6">
{prompt.split("\\n").map((line, index) => (
@@ -234,11 +204,12 @@ const FillBlanks: React.FC<FillBlanksExercise & CommonProps> = ({
</div>
</div>
)}
{footerButtons}
</div>
{!disableProgressButtons && progressButtons()}
</div>
);
};
//FillBlanks.whyDidYouRender = true
export default FillBlanks;