Updated the MatchSentences exercise to work better now
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {MultipleChoiceExercise, ReadingExam, UserSolution} from "@/interfaces/exam";
|
||||
import {MultipleChoiceExercise, ReadingExam, ReadingPart, UserSolution} from "@/interfaces/exam";
|
||||
import {Fragment, useEffect, useState} from "react";
|
||||
import Icon from "@mdi/react";
|
||||
import {mdiArrowRight, mdiNotebook} from "@mdi/js";
|
||||
@@ -10,7 +10,7 @@ import {renderExercise} from "@/components/Exercises";
|
||||
import {renderSolution} from "@/components/Solutions";
|
||||
import {Panel} from "primereact/panel";
|
||||
import {Steps} from "primereact/steps";
|
||||
import {BsAlarm, BsBook, BsClock, BsStopwatch} from "react-icons/bs";
|
||||
import {BsAlarm, BsBook, BsChevronDown, BsChevronUp, BsClock, BsStopwatch} from "react-icons/bs";
|
||||
import ProgressBar from "@/components/Low/ProgressBar";
|
||||
import ModuleTitle from "@/components/Medium/ModuleTitle";
|
||||
import {Divider} from "primereact/divider";
|
||||
@@ -26,6 +26,8 @@ interface Props {
|
||||
onFinish: (userSolutions: UserSolution[]) => void;
|
||||
}
|
||||
|
||||
const numberToLetter = (number: number) => (number + 9).toString(36).toUpperCase();
|
||||
|
||||
function TextModal({isOpen, title, content, onClose}: {isOpen: boolean; title: string; content: string; onClose: () => void}) {
|
||||
return (
|
||||
<Transition appear show={isOpen} as={Fragment}>
|
||||
@@ -80,12 +82,37 @@ function TextModal({isOpen, title, content, onClose}: {isOpen: boolean; title: s
|
||||
);
|
||||
}
|
||||
|
||||
function TextComponent({part, exerciseType}: {part: ReadingPart; exerciseType: string}) {
|
||||
return (
|
||||
<div className="flex flex-col gap-2 w-full">
|
||||
<h3 className="text-xl font-semibold">{part.text.title}</h3>
|
||||
<div className="border border-mti-gray-dim w-full rounded-full opacity-10" />
|
||||
{part.text.content
|
||||
.split(/\n|(\\n)/g)
|
||||
.filter((x) => x && x.length > 0)
|
||||
.map((line, index) => (
|
||||
<Fragment key={index}>
|
||||
{exerciseType === "matchSentences" && (
|
||||
<div className="flex gap-3 border border-transparent hover:border-mti-purple-light rounded-lg transition ease-in-out duration-300 p-2 px-3 cursor-pointer">
|
||||
<span className="font-bold text-mti-purple-dark">{numberToLetter(index + 1)}</span>
|
||||
<p>{line}</p>
|
||||
</div>
|
||||
)}
|
||||
{exerciseType !== "matchSentences" && <p key={index}>{line}</p>}
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Reading({exam, showSolutions = false, onFinish}: Props) {
|
||||
const [questionIndex, setQuestionIndex] = useState(0);
|
||||
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
|
||||
const [showTextModal, setShowTextModal] = useState(false);
|
||||
const [showBlankModal, setShowBlankModal] = useState(false);
|
||||
const [multipleChoicesDone, setMultipleChoicesDone] = useState<{id: string; amount: number}[]>([]);
|
||||
const [isTextMinimized, setIsTextMinimzed] = useState(false);
|
||||
const [exerciseType, setExerciseType] = useState("");
|
||||
|
||||
const {userSolutions, setUserSolutions} = useExamStore((state) => state);
|
||||
const {hasExamEnded, setHasExamEnded} = useExamStore((state) => state);
|
||||
@@ -154,6 +181,7 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
|
||||
}
|
||||
if (storeQuestionIndex > 0) {
|
||||
const exercise = getExercise();
|
||||
setExerciseType(exercise.type);
|
||||
setMultipleChoicesDone((prev) => [...prev.filter((x) => x.id !== exercise.id), {id: exercise.id, amount: storeQuestionIndex}]);
|
||||
}
|
||||
setStoreQuestionIndex(0);
|
||||
@@ -211,6 +239,7 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
|
||||
useEffect(() => {
|
||||
if (partIndex > -1 && exerciseIndex > -1) {
|
||||
const exercise = getExercise();
|
||||
setExerciseType(exercise.type);
|
||||
setMultipleChoicesDone((prev) => prev.filter((x) => x.id !== exercise.id));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -234,22 +263,29 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
|
||||
};
|
||||
|
||||
const renderText = () => (
|
||||
<div className="flex flex-col gap-6 w-full bg-mti-gray-seasalt rounded-xl py-8 px-16 mt-4">
|
||||
<div className="flex flex-col w-full gap-2">
|
||||
<h4 className="text-xl font-semibold">
|
||||
Please read the following excerpt attentively, you will then be asked questions about the text you've read.
|
||||
</h4>
|
||||
<span className="text-base">You will be allowed to read the text while doing the exercises</span>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2 w-full">
|
||||
<h3 className="text-xl font-semibold">{exam.parts[partIndex].text.title}</h3>
|
||||
<div className="border border-mti-gray-dim w-full rounded-full opacity-10" />
|
||||
<span className="overflow-auto">
|
||||
{exam.parts[partIndex].text.content.split("\\n").map((line, index) => (
|
||||
<p key={index}>{line}</p>
|
||||
))}
|
||||
</span>
|
||||
</div>
|
||||
<div className={clsx("flex flex-col gap-6 w-full bg-mti-gray-seasalt rounded-xl mt-4 relative", isTextMinimized ? "p-2 px-8" : "py-8 px-16")}>
|
||||
<button
|
||||
data-tip={isTextMinimized ? "Maximise" : "Minimize"}
|
||||
className={clsx("absolute right-8 tooltip", isTextMinimized ? "top-1/2 -translate-y-1/2" : "top-8")}
|
||||
onClick={() => setIsTextMinimzed((prev) => !prev)}>
|
||||
{isTextMinimized ? (
|
||||
<BsChevronDown className="text-mti-purple-dark text-lg" />
|
||||
) : (
|
||||
<BsChevronUp className="text-mti-purple-dark text-lg" />
|
||||
)}
|
||||
</button>
|
||||
{!isTextMinimized && (
|
||||
<>
|
||||
<div className="flex flex-col w-full gap-2">
|
||||
<h4 className="text-xl font-semibold">
|
||||
Please read the following excerpt attentively, you will then be asked questions about the text you've read.
|
||||
</h4>
|
||||
<span className="text-base">You will be allowed to read the text while doing the exercises</span>
|
||||
</div>
|
||||
<TextComponent part={exam.parts[partIndex]} exerciseType={exerciseType} />
|
||||
</>
|
||||
)}
|
||||
{isTextMinimized && <span className="font-semibold">Reading Passage</span>}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -266,7 +302,12 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
|
||||
disableTimer={showSolutions}
|
||||
label={exerciseIndex === -1 ? undefined : convertCamelCaseToReadable(exam.parts[partIndex].exercises[exerciseIndex].type)}
|
||||
/>
|
||||
<div className={clsx("mb-20 w-full", exerciseIndex > -1 && "grid grid-cols-2 gap-4")}>
|
||||
<div
|
||||
className={clsx(
|
||||
"mb-20 w-full",
|
||||
exerciseIndex > -1 && !isTextMinimized && "grid grid-cols-2 gap-4",
|
||||
exerciseIndex > -1 && isTextMinimized && "flex flex-col gap-2",
|
||||
)}>
|
||||
{partIndex > -1 && renderText()}
|
||||
|
||||
{exerciseIndex > -1 &&
|
||||
|
||||
Reference in New Issue
Block a user