Increase the size and boldness of the timer
This commit is contained in:
@@ -1,80 +1,80 @@
|
|||||||
import useExamStore from "@/stores/examStore";
|
import useExamStore from "@/stores/examStore";
|
||||||
import { useEffect, useState } from "react";
|
import {useEffect, useState} from "react";
|
||||||
import { motion } from "framer-motion";
|
import {motion} from "framer-motion";
|
||||||
import TimerEndedModal from "../TimerEndedModal";
|
import TimerEndedModal from "../TimerEndedModal";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { BsStopwatch } from "react-icons/bs";
|
import {BsStopwatch} from "react-icons/bs";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
minTimer: number;
|
minTimer: number;
|
||||||
disableTimer?: boolean;
|
disableTimer?: boolean;
|
||||||
standalone?: boolean;
|
standalone?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Timer: React.FC<Props> = ({minTimer, disableTimer, standalone = false}) => {
|
const Timer: React.FC<Props> = ({minTimer, disableTimer, standalone = false}) => {
|
||||||
const [timer, setTimer] = useState(minTimer * 60);
|
const [timer, setTimer] = useState(minTimer * 60);
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
const [warningMode, setWarningMode] = useState(false);
|
const [warningMode, setWarningMode] = useState(false);
|
||||||
|
|
||||||
const setHasExamEnded = useExamStore((state) => state.setHasExamEnded);
|
const setHasExamEnded = useExamStore((state) => state.setHasExamEnded);
|
||||||
const { timeSpent } = useExamStore((state) => state);
|
const {timeSpent} = useExamStore((state) => state);
|
||||||
|
|
||||||
useEffect(() => setTimer((prev) => prev - timeSpent), [timeSpent]);
|
useEffect(() => setTimer((prev) => prev - timeSpent), [timeSpent]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!disableTimer) {
|
if (!disableTimer) {
|
||||||
const timerInterval = setInterval(() => setTimer((prev) => prev - 1), 1000);
|
const timerInterval = setInterval(() => setTimer((prev) => prev - 1), 1000);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(timerInterval);
|
clearInterval(timerInterval);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}, [disableTimer, minTimer]);
|
}, [disableTimer, minTimer]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (timer <= 0) setShowModal(true);
|
if (timer <= 0) setShowModal(true);
|
||||||
}, [timer]);
|
}, [timer]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (timer < 300 && !warningMode) setWarningMode(true);
|
if (timer < 300 && !warningMode) setWarningMode(true);
|
||||||
}, [timer, warningMode]);
|
}, [timer, warningMode]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TimerEndedModal
|
<TimerEndedModal
|
||||||
isOpen={showModal}
|
isOpen={showModal}
|
||||||
onClose={() => {
|
onClose={() => {
|
||||||
setHasExamEnded(true);
|
setHasExamEnded(true);
|
||||||
setShowModal(false);
|
setShowModal(false);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<motion.div
|
<motion.div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
"absolute right-6 bg-mti-gray-seasalt px-4 py-3 flex items-center gap-2 rounded-full text-mti-gray-davy",
|
"absolute right-6 bg-mti-gray-seasalt px-4 py-3 flex items-center gap-2 rounded-full text-mti-gray-davy",
|
||||||
standalone ? "top-10" : "top-4",
|
standalone ? "top-10" : "top-4",
|
||||||
warningMode && !disableTimer && "bg-mti-red-light text-mti-gray-seasalt",
|
warningMode && !disableTimer && "bg-mti-red-light text-mti-gray-seasalt",
|
||||||
)}
|
)}
|
||||||
initial={{ scale: warningMode && !disableTimer ? 0.8 : 1 }}
|
initial={{scale: warningMode && !disableTimer ? 0.8 : 1}}
|
||||||
animate={{ scale: warningMode && !disableTimer ? 1.1 : 1 }}
|
animate={{scale: warningMode && !disableTimer ? 1.1 : 1}}
|
||||||
transition={{ repeat: Infinity, repeatType: "reverse", duration: 0.5, ease: "easeInOut" }}>
|
transition={{repeat: Infinity, repeatType: "reverse", duration: 0.5, ease: "easeInOut"}}>
|
||||||
<BsStopwatch className="w-6 h-6" />
|
<BsStopwatch className="w-6 h-6" />
|
||||||
<span className="text-base font-semibold w-12">
|
<span className="text-lg font-bold w-12">
|
||||||
{timer > 0 && (
|
{timer > 0 && (
|
||||||
<>
|
<>
|
||||||
{Math.floor(timer / 60)
|
{Math.floor(timer / 60)
|
||||||
.toString(10)
|
.toString(10)
|
||||||
.padStart(2, "0")}
|
.padStart(2, "0")}
|
||||||
:
|
:
|
||||||
{Math.floor(timer % 60)
|
{Math.floor(timer % 60)
|
||||||
.toString(10)
|
.toString(10)
|
||||||
.padStart(2, "0")}
|
.padStart(2, "0")}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{timer <= 0 && <>00:00</>}
|
{timer <= 0 && <>00:00</>}
|
||||||
</span>
|
</span>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default Timer;
|
export default Timer;
|
||||||
|
|||||||
@@ -437,7 +437,6 @@ export default function MasterCorporateDashboard({ user }: Props) {
|
|||||||
|
|
||||||
const { data: stats } = useFilterRecordsByUser<Stat[]>();
|
const { data: stats } = useFilterRecordsByUser<Stat[]>();
|
||||||
const { users, reload } = useUsers();
|
const { users, reload } = useUsers();
|
||||||
const { codes } = useCodes(user.id);
|
|
||||||
const { groups } = useGroups({ admin: user.id, userType: user.type });
|
const { groups } = useGroups({ admin: user.id, userType: user.type });
|
||||||
const { balance } = useUserBalance();
|
const { balance } = useUserBalance();
|
||||||
|
|
||||||
@@ -447,9 +446,9 @@ export default function MasterCorporateDashboard({ user }: Props) {
|
|||||||
),
|
),
|
||||||
], [groups, user.id]);
|
], [groups, user.id]);
|
||||||
|
|
||||||
const corporateUserGroups = [
|
const corporateUserGroups = useMemo(() => [
|
||||||
...new Set(groups.flatMap((g) => g.participants)),
|
...new Set(groups.flatMap((g) => g.participants)),
|
||||||
];
|
], [groups])
|
||||||
|
|
||||||
const {
|
const {
|
||||||
assignments,
|
assignments,
|
||||||
|
|||||||
Reference in New Issue
Block a user