Added the capability for users to resume their previously stopped sessions

This commit is contained in:
Tiago Ribeiro
2024-02-06 14:44:22 +00:00
parent c4b61c4787
commit 4ec439492e
7 changed files with 200 additions and 21 deletions

View File

@@ -22,6 +22,7 @@ import {useRouter} from "next/router";
import {toast, ToastContainer} from "react-toastify";
import {v4 as uuidv4} from "uuid";
import useSessions from "@/hooks/useSessions";
import ShortUniqueId from "short-unique-id";
interface Props {
page: "exams" | "exercises";
@@ -36,15 +37,17 @@ export default function ExamPage({page}: Props) {
const [statsAwaitingEvaluation, setStatsAwaitingEvaluation] = useState<string[]>([]);
const [timeSpent, setTimeSpent] = useState(0);
const partIndex = useExamStore((state) => state.partIndex);
const resetStore = useExamStore((state) => state.reset);
const assignment = useExamStore((state) => state.assignment);
const initialTimeSpent = useExamStore((state) => state.timeSpent);
const exerciseIndex = useExamStore((state) => state.exerciseIndex);
const {exam, setExam} = useExamStore((state) => state);
const {exams, setExams} = useExamStore((state) => state);
const {sessionId, setSessionId} = useExamStore((state) => state);
const {partIndex, setPartIndex} = useExamStore((state) => state);
const {moduleIndex, setModuleIndex} = useExamStore((state) => state);
const {questionIndex, setQuestionIndex} = useExamStore((state) => state);
const {exerciseIndex, setExerciseIndex} = useExamStore((state) => state);
const {userSolutions, setUserSolutions} = useExamStore((state) => state);
const {showSolutions, setShowSolutions} = useExamStore((state) => state);
const {selectedModules, setSelectedModules} = useExamStore((state) => state);
@@ -52,10 +55,23 @@ export default function ExamPage({page}: Props) {
const {user} = useUser({redirectTo: "/login"});
const router = useRouter();
const reset = () => {
resetStore();
setVariant("full");
setAvoidRepeated(false);
setHasBeenUploaded(false);
setShowAbandonPopup(false);
setIsEvaluationLoading(false);
setStatsAwaitingEvaluation([]);
setTimeSpent(0);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
const saveSession = async () => {
await axios.post("/api/sessions", {
id: sessionId,
sessionId,
date: new Date().toISOString(),
userSolutions,
moduleIndex,
selectedModules,
@@ -65,6 +81,7 @@ export default function ExamPage({page}: Props) {
exam,
partIndex,
exerciseIndex,
questionIndex,
user: user?.id,
});
};
@@ -82,7 +99,7 @@ export default function ExamPage({page}: Props) {
if (sessionId.length > 0 && userSolutions.length > 0 && selectedModules.length > 0 && exams.length > 0 && !!exam && timeSpent > 0)
saveSession();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [assignment, exam, exams, moduleIndex, selectedModules, sessionId, userSolutions, user, exerciseIndex, partIndex]);
}, [assignment, exam, exams, moduleIndex, selectedModules, sessionId, userSolutions, user, exerciseIndex, partIndex, questionIndex]);
useEffect(() => {
if (timeSpent % 20 === 0 && timeSpent > 0) saveSession();
@@ -90,10 +107,11 @@ export default function ExamPage({page}: Props) {
}, [timeSpent]);
useEffect(() => {
if (selectedModules.length > 0) {
setSessionId(uuidv4());
if (selectedModules.length > 0 && sessionId.length === 0) {
const shortUID = new ShortUniqueId();
setSessionId(shortUID.randomUUID(8));
}
}, [setSessionId, selectedModules]);
}, [setSessionId, selectedModules, sessionId]);
useEffect(() => {
if (user?.type === "developer") console.log(exam);
}, [exam, user]);
@@ -258,6 +276,10 @@ export default function ExamPage({page}: Props) {
setUserSolutions([...userSolutions.filter((x) => !solutionIds.includes(x.exercise)), ...solutions]);
setModuleIndex(moduleIndex + 1);
setPartIndex(0);
setExerciseIndex(-1);
setQuestionIndex(0);
};
const aggregateScoresByModule = (answers: UserSolution[]): {module: Module; total: number; missing: number; correct: number}[] => {
@@ -377,7 +399,9 @@ export default function ExamPage({page}: Props) {
abandonPopupTitle="Leave Exercise"
abandonPopupDescription="Are you sure you want to leave the exercise? You will lose all your progress."
abandonConfirmButtonText="Confirm"
onAbandon={() => router.reload()}
onAbandon={() => {
reset();
}}
onCancel={() => setShowAbandonPopup(false)}
/>
)}