Added a new feature to check for and register inactivity during an exam

This commit is contained in:
Tiago Ribeiro
2024-06-04 22:18:45 +01:00
parent 975f4c8285
commit 8ea97ee944
6 changed files with 232 additions and 144 deletions

View File

@@ -35,14 +35,14 @@ export default function ExamPage({page}: Props) {
const [showAbandonPopup, setShowAbandonPopup] = useState(false);
const [isEvaluationLoading, setIsEvaluationLoading] = useState(false);
const [statsAwaitingEvaluation, setStatsAwaitingEvaluation] = useState<string[]>([]);
const [inactivityTimer, setInactivityTimer] = useState(0);
const [totalInactivity, setTotalInactivity] = useState(0);
const [timeSpent, setTimeSpent] = useState(0);
const resetStore = useExamStore((state) => state.reset);
const assignment = useExamStore((state) => state.assignment);
const initialTimeSpent = useExamStore((state) => state.timeSpent);
const examStore = useExamStore;
const {exam, setExam} = useExamStore((state) => state);
const {exams, setExams} = useExamStore((state) => state);
const {sessionId, setSessionId} = useExamStore((state) => state);
@@ -53,10 +53,20 @@ export default function ExamPage({page}: Props) {
const {userSolutions, setUserSolutions} = useExamStore((state) => state);
const {showSolutions, setShowSolutions} = useExamStore((state) => state);
const {selectedModules, setSelectedModules} = useExamStore((state) => state);
const {inactivity, setInactivity} = useExamStore((state) => state);
const {user} = useUser({redirectTo: "/login"});
const router = useRouter();
// eslint-disable-next-line react-hooks/exhaustive-deps
const resetInactivityTimer = () => {
setInactivityTimer((prev) => {
if (moduleIndex >= selectedModules.length || moduleIndex === -1) return 0;
if (prev >= 120) setTotalInactivity((totalPrev) => totalPrev + prev);
return 0;
});
};
const reset = () => {
resetStore();
setVariant("full");
@@ -66,8 +76,21 @@ export default function ExamPage({page}: Props) {
setIsEvaluationLoading(false);
setStatsAwaitingEvaluation([]);
setTimeSpent(0);
setInactivity(0);
document.removeEventListener("keydown", resetInactivityTimer);
document.removeEventListener("mousemove", resetInactivityTimer);
document.removeEventListener("mousedown", resetInactivityTimer);
};
useEffect(() => {
if (moduleIndex >= selectedModules.length || moduleIndex === -1 || showSolutions) {
document.removeEventListener("keydown", resetInactivityTimer);
document.removeEventListener("mousemove", resetInactivityTimer);
document.removeEventListener("mousedown", resetInactivityTimer);
}
}, [moduleIndex, resetInactivityTimer, selectedModules.length, showSolutions]);
// eslint-disable-next-line react-hooks/exhaustive-deps
const saveSession = async () => {
console.log("Saving your session...");
@@ -81,6 +104,7 @@ export default function ExamPage({page}: Props) {
selectedModules,
assignment,
timeSpent,
inactivity: totalInactivity,
exams,
exam,
partIndex,
@@ -90,7 +114,8 @@ export default function ExamPage({page}: Props) {
});
};
useEffect(() => setTimeSpent((prev) => prev + initialTimeSpent), [initialTimeSpent]);
useEffect(() => setTimeSpent(initialTimeSpent), [initialTimeSpent]);
useEffect(() => setTotalInactivity(inactivity), [inactivity]);
useEffect(() => {
if (userSolutions.length === 0 && exams.length > 0) {
@@ -144,7 +169,34 @@ export default function ExamPage({page}: Props) {
}, [selectedModules.length]);
useEffect(() => {
if (showSolutions) setModuleIndex(-1);
if (selectedModules.length > 0 && !showSolutions && inactivityTimer === 0) {
const inactivityInterval = setInterval(() => {
setInactivityTimer((prev) => prev + 1);
}, 1000);
return () => {
clearInterval(inactivityInterval);
};
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedModules.length]);
useEffect(() => {
document.addEventListener("keydown", resetInactivityTimer);
document.addEventListener("mousemove", resetInactivityTimer);
document.addEventListener("mousedown", resetInactivityTimer);
return () => {
document.removeEventListener("keydown", resetInactivityTimer);
document.removeEventListener("mousemove", resetInactivityTimer);
document.removeEventListener("mousedown", resetInactivityTimer);
};
});
useEffect(() => {
if (showSolutions) {
setModuleIndex(-1);
}
}, [setModuleIndex, showSolutions]);
useEffect(() => {
@@ -190,6 +242,7 @@ export default function ExamPage({page}: Props) {
...solution,
id: solution.id || uuidv4(),
timeSpent,
inactivity: totalInactivity,
session: sessionId,
exam: solution.exam!,
module: solution.module!,
@@ -392,6 +445,10 @@ export default function ExamPage({page}: Props) {
isLoading={isEvaluationLoading}
user={user!}
modules={selectedModules}
information={{
timeSpent,
inactivity: totalInactivity,
}}
onViewResults={(index?: number) => {
setShowSolutions(true);
setModuleIndex(index || 0);