Added a confirmation dialog for when the user leaves questions unanswered
This commit is contained in:
56
src/components/BlankQuestionsModal.tsx
Normal file
56
src/components/BlankQuestionsModal.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import {Dialog, Transition} from "@headlessui/react";
|
||||
import {Fragment} from "react";
|
||||
import Button from "./Low/Button";
|
||||
|
||||
interface Props {
|
||||
isOpen: boolean;
|
||||
onClose: (next?: boolean) => void;
|
||||
}
|
||||
|
||||
export default function BlankQuestionsModal({isOpen, onClose}: Props) {
|
||||
return (
|
||||
<Transition show={isOpen} as={Fragment}>
|
||||
<Dialog onClose={() => onClose(false)} className="relative z-50">
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0"
|
||||
enterTo="opacity-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100"
|
||||
leaveTo="opacity-0">
|
||||
<div className="fixed inset-0 bg-black/30" />
|
||||
</Transition.Child>
|
||||
|
||||
<Transition.Child
|
||||
as={Fragment}
|
||||
enter="ease-out duration-300"
|
||||
enterFrom="opacity-0 scale-95"
|
||||
enterTo="opacity-100 scale-100"
|
||||
leave="ease-in duration-200"
|
||||
leaveFrom="opacity-100 scale-100"
|
||||
leaveTo="opacity-0 scale-95">
|
||||
<div className="fixed inset-0 flex items-center justify-center p-4">
|
||||
<Dialog.Panel className="w-full max-w-2xl h-fit p-8 rounded-xl bg-white flex flex-col gap-4">
|
||||
<Dialog.Title className="font-bold text-xl">Questions Unanswered</Dialog.Title>
|
||||
<span>
|
||||
Please note that you are finishing the current module and once you proceed to the next module, you will no longer be
|
||||
able to change the answers in the current one, including your unanswered questions. <br />
|
||||
<br />
|
||||
Are you sure you want to continue without completing those questions?
|
||||
</span>
|
||||
<div className="w-full flex justify-between mt-8">
|
||||
<Button color="green" onClick={() => onClose(false)} variant="outline" className="max-w-[200px] self-end w-full">
|
||||
Go Back
|
||||
</Button>
|
||||
<Button color="green" onClick={() => onClose(true)} className="max-w-[200px] self-end w-full">
|
||||
Continue
|
||||
</Button>
|
||||
</div>
|
||||
</Dialog.Panel>
|
||||
</div>
|
||||
</Transition.Child>
|
||||
</Dialog>
|
||||
</Transition>
|
||||
);
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import {renderSolution} from "@/components/Solutions";
|
||||
import ModuleTitle from "@/components/Medium/ModuleTitle";
|
||||
import AudioPlayer from "@/components/Low/AudioPlayer";
|
||||
import Button from "@/components/Low/Button";
|
||||
import BlankQuestionsModal from "@/components/BlankQuestionsModal";
|
||||
|
||||
interface Props {
|
||||
exam: ListeningExam;
|
||||
@@ -20,6 +21,16 @@ export default function Listening({exam, showSolutions = false, onFinish}: Props
|
||||
const [exerciseIndex, setExerciseIndex] = useState(-1);
|
||||
const [timesListened, setTimesListened] = useState(0);
|
||||
const [userSolutions, setUserSolutions] = useState<UserSolution[]>([]);
|
||||
const [showBlankModal, setShowBlankModal] = useState(false);
|
||||
|
||||
const confirmFinishModule = (keepGoing?: boolean) => {
|
||||
if (!keepGoing) {
|
||||
setShowBlankModal(false);
|
||||
return;
|
||||
}
|
||||
|
||||
onFinish(userSolutions.map((x) => ({...x, module: "reading", exam: exam.id})));
|
||||
};
|
||||
|
||||
const nextExercise = (solution?: UserSolution) => {
|
||||
if (solution) {
|
||||
@@ -31,6 +42,11 @@ export default function Listening({exam, showSolutions = false, onFinish}: Props
|
||||
return;
|
||||
}
|
||||
|
||||
if (!userSolutions.map((x) => x.score.missing).every((x) => x === 0)) {
|
||||
setShowBlankModal(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (solution) {
|
||||
onFinish(
|
||||
[...userSolutions.filter((x) => x.exercise !== solution.exercise), solution].map((x) => ({...x, module: "listening", exam: exam.id})),
|
||||
@@ -79,6 +95,7 @@ export default function Listening({exam, showSolutions = false, onFinish}: Props
|
||||
|
||||
return (
|
||||
<>
|
||||
<BlankQuestionsModal isOpen={showBlankModal} onClose={confirmFinishModule} />
|
||||
<div className="flex flex-col h-full w-full gap-8 justify-between">
|
||||
<ModuleTitle
|
||||
exerciseIndex={exerciseIndex + 1}
|
||||
|
||||
@@ -15,6 +15,7 @@ import ProgressBar from "@/components/Low/ProgressBar";
|
||||
import ModuleTitle from "@/components/Medium/ModuleTitle";
|
||||
import {Divider} from "primereact/divider";
|
||||
import Button from "@/components/Low/Button";
|
||||
import BlankQuestionsModal from "@/components/BlankQuestionsModal";
|
||||
|
||||
interface Props {
|
||||
exam: ReadingExam;
|
||||
@@ -83,6 +84,16 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
|
||||
const [exerciseIndex, setExerciseIndex] = useState(-1);
|
||||
const [showTextModal, setShowTextModal] = useState(false);
|
||||
const [userSolutions, setUserSolutions] = useState<UserSolution[]>([]);
|
||||
const [showBlankModal, setShowBlankModal] = useState(false);
|
||||
|
||||
const confirmFinishModule = (keepGoing?: boolean) => {
|
||||
if (!keepGoing) {
|
||||
setShowBlankModal(false);
|
||||
return;
|
||||
}
|
||||
|
||||
onFinish(userSolutions.map((x) => ({...x, module: "reading", exam: exam.id})));
|
||||
};
|
||||
|
||||
const nextExercise = (solution?: UserSolution) => {
|
||||
if (solution) {
|
||||
@@ -94,6 +105,11 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!userSolutions.map((x) => x.score.missing).every((x) => x === 0)) {
|
||||
setShowBlankModal(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (solution) {
|
||||
onFinish(
|
||||
[...userSolutions.filter((x) => x.exercise !== solution.exercise), solution].map((x) => ({...x, module: "reading", exam: exam.id})),
|
||||
@@ -142,6 +158,7 @@ export default function Reading({exam, showSolutions = false, onFinish}: Props)
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col h-full w-full gap-8">
|
||||
<BlankQuestionsModal isOpen={showBlankModal} onClose={confirmFinishModule} />
|
||||
<TextModal {...exam.text} isOpen={showTextModal} onClose={() => setShowTextModal(false)} />
|
||||
<ModuleTitle
|
||||
minTimer={exam.minTimer}
|
||||
|
||||
Reference in New Issue
Block a user