Made it so the timer is more dynamic

This commit is contained in:
Tiago Ribeiro
2023-07-27 20:25:57 +01:00
parent d38ca76182
commit d879f4afab
7 changed files with 88 additions and 11 deletions

View File

@@ -31,7 +31,6 @@ export default function MatchSentences({id, options, type, prompt, sentences, us
};
useEffect(() => {
console.log({hasExamEnded});
if (hasExamEnded) onNext({exercise: id, solutions: answers, score: calculateScore(), type});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasExamEnded]);

View File

@@ -1,9 +1,12 @@
import {Module} from "@/interfaces";
import useExamStore from "@/stores/examStore";
import {moduleLabels} from "@/utils/moduleUtils";
import clsx from "clsx";
import {motion} from "framer-motion";
import {ReactNode, useEffect, useState} from "react";
import {BsBook, BsHeadphones, BsMegaphone, BsPen, BsStopwatch} from "react-icons/bs";
import ProgressBar from "../Low/ProgressBar";
import TimerEndedModal from "../TimerEndedModal";
interface Props {
minTimer: number;
@@ -16,6 +19,8 @@ interface Props {
export default function ModuleTitle({minTimer, module, label, exerciseIndex, totalExercises, disableTimer = false}: Props) {
const [timer, setTimer] = useState(minTimer * 60);
const [showModal, setShowModal] = useState(false);
const [warningMode, setWarningMode] = useState(false);
const setHasExamEnded = useExamStore((state) => state.setHasExamEnded);
useEffect(() => {
@@ -29,8 +34,12 @@ export default function ModuleTitle({minTimer, module, label, exerciseIndex, tot
}, [disableTimer, minTimer]);
useEffect(() => {
if (timer <= 0) setHasExamEnded(true);
}, [setHasExamEnded, timer]);
if (timer <= 0) setShowModal(true);
}, [timer]);
useEffect(() => {
if (timer < 300 && !warningMode) setWarningMode(true);
}, [timer, warningMode]);
const moduleIcon: {[key in Module]: ReactNode} = {
reading: <BsBook className="text-ielts-reading w-6 h-6" />,
@@ -41,7 +50,21 @@ export default function ModuleTitle({minTimer, module, label, exerciseIndex, tot
return (
<>
<div className="absolute top-4 right-6 bg-mti-gray-seasalt px-3 py-2 flex items-center gap-2 rounded-full text-mti-gray-davy">
<TimerEndedModal
isOpen={showModal}
onClose={() => {
setHasExamEnded(true);
setShowModal(false);
}}
/>
<motion.div
className={clsx(
"absolute top-4 right-6 bg-mti-gray-seasalt px-3 py-2 flex items-center gap-2 rounded-full text-mti-gray-davy",
warningMode && !disableTimer && "bg-mti-red-light text-mti-gray-seasalt",
)}
initial={{scale: warningMode && !disableTimer ? 0.8 : 1}}
animate={{scale: warningMode && !disableTimer ? 1.1 : 1}}
transition={{repeat: Infinity, repeatType: "reverse", duration: 0.5, ease: "easeInOut"}}>
<BsStopwatch className="w-4 h-4" />
<span className="text-sm font-semibold w-11">
{timer > 0 && (
@@ -57,7 +80,7 @@ export default function ModuleTitle({minTimer, module, label, exerciseIndex, tot
)}
{timer <= 0 && <>00:00</>}
</span>
</div>
</motion.div>
<div className="flex gap-6 w-full h-fit items-center mt-5">
<div className="w-12 h-12 bg-mti-gray-smoke flex items-center justify-center rounded-lg">{moduleIcon[module]}</div>
<div className="flex flex-col gap-3 w-full">

View File

@@ -0,0 +1,49 @@
import {Dialog, Transition} from "@headlessui/react";
import {Fragment} from "react";
import Button from "./Low/Button";
interface Props {
isOpen: boolean;
onClose: () => void;
}
export default function TimerEndedModal({isOpen, onClose}: Props) {
return (
<Transition show={isOpen} as={Fragment}>
<Dialog onClose={onClose} 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">Time&apos;s up!</Dialog.Title>
<span>
The timer has ended! Your answers have been registered and saved, you will now move on to the next module (or to the
finish screen, if this was the last one).
</span>
<Button color="purple" onClick={onClose} className="max-w-[200px] self-end w-full mt-8">
Continue
</Button>
</Dialog.Panel>
</div>
</Transition.Child>
</Dialog>
</Transition>
);
}