Updated the eval calls to the backend, passed the navigation logic of level to useExamNavigation hook
This commit is contained in:
@@ -34,10 +34,8 @@ export default function ExamPage({ page, user, destination = "/", hideSidebar =
|
||||
const router = useRouter();
|
||||
const [variant, setVariant] = useState<Variant>("full");
|
||||
const [avoidRepeated, setAvoidRepeated] = useState(false);
|
||||
const [hasBeenUploaded, setHasBeenUploaded] = useState(false);
|
||||
const [showAbandonPopup, setShowAbandonPopup] = useState(false);
|
||||
const [isEvaluationLoading, setIsEvaluationLoading] = useState(false);
|
||||
const [statsAwaitingEvaluation, setStatsAwaitingEvaluation] = useState<string[]>([]);
|
||||
const [pendingExercises, setPendingExercises] = useState<string[]>([]);
|
||||
|
||||
const {
|
||||
exam, setExam,
|
||||
@@ -59,11 +57,11 @@ export default function ExamPage({ page, user, destination = "/", hideSidebar =
|
||||
saveStats,
|
||||
saveSession,
|
||||
setFlags,
|
||||
setShuffles
|
||||
setShuffles,
|
||||
evaluated,
|
||||
setEvaluated,
|
||||
} = useExamStore();
|
||||
|
||||
const { finalizeModule, finalizeExam } = flags;
|
||||
|
||||
const [isFetchingExams, setIsFetchingExams] = useState(false);
|
||||
const [isExamLoaded, setIsExamLoaded] = useState(moduleIndex < selectedModules.length);
|
||||
|
||||
@@ -114,99 +112,115 @@ export default function ExamPage({ page, user, destination = "/", hideSidebar =
|
||||
resetStore();
|
||||
setVariant("full");
|
||||
setAvoidRepeated(false);
|
||||
setHasBeenUploaded(false);
|
||||
setShowAbandonPopup(false);
|
||||
setIsEvaluationLoading(false);
|
||||
setStatsAwaitingEvaluation([]);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (finalizeModule && !showSolutions) {
|
||||
/*if (exam && (exam.module === "writing" || exam.module === "speaking") && userSolutions.length > 0 && !showSolutions) {
|
||||
setIsEvaluationLoading(true);
|
||||
if (flags.finalizeModule && !showSolutions && flags.pendingEvaluation) {
|
||||
if (exam && (exam.module === "writing" || exam.module === "speaking") && userSolutions.length > 0 && !showSolutions) {
|
||||
const exercisesToEvaluate = exam.exercises
|
||||
.map(exercise => exercise.id);
|
||||
|
||||
setPendingExercises(exercisesToEvaluate);
|
||||
(async () => {
|
||||
const responses: UserSolution[] = (
|
||||
await Promise.all(
|
||||
exam.exercises.map(async (exercise, index) => {
|
||||
const evaluationID = uuidv4();
|
||||
if (exercise.type === "writing")
|
||||
return await evaluateWritingAnswer(exercise, index + 1, userSolutions.find((x) => x.exercise === exercise.id)!, evaluationID);
|
||||
await Promise.all(
|
||||
exam.exercises.map(async (exercise, index) => {
|
||||
if (exercise.type === "writing")
|
||||
await evaluateWritingAnswer(user.id, sessionId, exercise, index + 1, userSolutions.find((x) => x.exercise === exercise.id)!);
|
||||
|
||||
if (exercise.type === "interactiveSpeaking" || exercise.type === "speaking")
|
||||
return await evaluateSpeakingAnswer(
|
||||
exercise,
|
||||
userSolutions.find((x) => x.exercise === exercise.id)!,
|
||||
evaluationID,
|
||||
index + 1,
|
||||
);
|
||||
}),
|
||||
)
|
||||
).filter((x) => !!x) as UserSolution[];
|
||||
if (exercise.type === "interactiveSpeaking" || exercise.type === "speaking")
|
||||
await evaluateSpeakingAnswer(
|
||||
user.id,
|
||||
sessionId,
|
||||
exercise,
|
||||
userSolutions.find((x) => x.exercise === exercise.id)!,
|
||||
index + 1,
|
||||
);
|
||||
}),
|
||||
)
|
||||
})();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}, [exam, finalizeModule, showSolutions, userSolutions]);
|
||||
|
||||
/*useEffect(() => {
|
||||
// poll backend and setIsEvaluationLoading to false
|
||||
|
||||
}, []);*/
|
||||
}, [exam, showSolutions, userSolutions, sessionId, user?.id, flags]);
|
||||
|
||||
useEffect(() => {
|
||||
if (finalizeExam && !isEvaluationLoading) {
|
||||
if (!flags.pendingEvaluation || pendingExercises.length === 0) return;
|
||||
|
||||
const pollStatus = async () => {
|
||||
try {
|
||||
// Will fetch evaluations that either were completed or had an error
|
||||
const { data } = await axios.get('/api/evaluate/status', {
|
||||
params: {
|
||||
sessionId,
|
||||
userId: user.id,
|
||||
exerciseIds: pendingExercises.join(',')
|
||||
}
|
||||
});
|
||||
|
||||
if (data.finishedExerciseIds.length > 0) {
|
||||
const remainingExercises = pendingExercises.filter(id => !data.finishedExerciseIds.includes(id));
|
||||
|
||||
setPendingExercises(remainingExercises);
|
||||
if (remainingExercises.length === 0) {
|
||||
const evaluatedData = await axios.post('/api/evaluate/fetchSolutions', {
|
||||
sessionId,
|
||||
userId: user.id,
|
||||
userSolutions
|
||||
});
|
||||
|
||||
const newEvaluations = evaluatedData.data.filter(
|
||||
(newEval: UserSolution) => !evaluated.some(
|
||||
existingEval => existingEval.exercise === newEval.exercise
|
||||
)
|
||||
);
|
||||
|
||||
setEvaluated([...evaluated, ...newEvaluations]);
|
||||
setFlags({ pendingEvaluation: false });
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (pendingExercises.length > 0) {
|
||||
setTimeout(pollStatus, 5000);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
setTimeout(pollStatus, 5000);
|
||||
}
|
||||
};
|
||||
|
||||
pollStatus();
|
||||
}, [sessionId, user.id, userSolutions, setFlags, setEvaluated, evaluated, flags, pendingExercises]);
|
||||
|
||||
useEffect(() => {
|
||||
if (flags.finalizeExam && moduleIndex !== -1) {
|
||||
setModuleIndex(-1);
|
||||
}
|
||||
}, [flags.finalizeExam, moduleIndex, setModuleIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (flags.finalizeExam && !flags.pendingEvaluation && pendingExercises.length === 0) {
|
||||
(async () => {
|
||||
axios.get("/api/stats/update");
|
||||
if (evaluated.length !== 0) {
|
||||
setUserSolutions(
|
||||
userSolutions.map(solution => {
|
||||
const evaluatedSolution = evaluated.find(e => e.exercise === solution.exercise);
|
||||
if (evaluatedSolution) {
|
||||
return { ...solution, ...evaluatedSolution };
|
||||
}
|
||||
return solution;
|
||||
})
|
||||
);
|
||||
}
|
||||
await saveStats();
|
||||
setModuleIndex(-1);
|
||||
await axios.get("/api/stats/update");
|
||||
setShowSolutions(true);
|
||||
setFlags({ finalizeExam: false });
|
||||
dispatch({type: "UPDATE_EXAMS"})
|
||||
})();
|
||||
}
|
||||
}, [finalizeExam, saveStats, setFlags, setModuleIndex, isEvaluationLoading]);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [saveStats, setFlags, setModuleIndex, evaluated, pendingExercises, setUserSolutions]);
|
||||
|
||||
const onFinish = async (solutions: UserSolution[]) => {
|
||||
const solutionIds = solutions.map((x) => x.exercise);
|
||||
const solutionExams = solutions.map((x) => x.exam);
|
||||
|
||||
let newSolutions = [...solutions];
|
||||
|
||||
if (exam && !solutionExams.includes(exam.id)) return;
|
||||
|
||||
if (exam && (exam.module === "writing" || exam.module === "speaking") && solutions.length > 0 && !showSolutions) {
|
||||
setHasBeenUploaded(true);
|
||||
setIsEvaluationLoading(true);
|
||||
|
||||
const responses: UserSolution[] = (
|
||||
await Promise.all(
|
||||
exam.exercises.map(async (exercise, index) => {
|
||||
const evaluationID = uuidv4();
|
||||
if (exercise.type === "writing")
|
||||
return await evaluateWritingAnswer(exercise, index + 1, solutions.find((x) => x.exercise === exercise.id)!, evaluationID);
|
||||
|
||||
if (exercise.type === "interactiveSpeaking" || exercise.type === "speaking")
|
||||
return await evaluateSpeakingAnswer(
|
||||
exercise,
|
||||
solutions.find((x) => x.exercise === exercise.id)!,
|
||||
evaluationID,
|
||||
index + 1,
|
||||
);
|
||||
}),
|
||||
)
|
||||
).filter((x) => !!x) as UserSolution[];
|
||||
|
||||
newSolutions = [...newSolutions.filter((x) => !responses.map((y) => y.exercise).includes(x.exercise)), ...responses];
|
||||
setStatsAwaitingEvaluation((prev) => [...prev, ...responses.filter((x) => !!x).map((r) => (r as any).id)]);
|
||||
setHasBeenUploaded(false);
|
||||
}
|
||||
|
||||
axios.get("/api/stats/update");
|
||||
|
||||
setUserSolutions([...userSolutions.filter((x) => !solutionIds.includes(x.exercise)), ...newSolutions]);
|
||||
setModuleIndex(moduleIndex + 1);
|
||||
|
||||
setPartIndex(0);
|
||||
setExerciseIndex(0);
|
||||
setQuestionIndex(0);
|
||||
};
|
||||
|
||||
const aggregateScoresByModule = (): {
|
||||
module: Module;
|
||||
@@ -306,7 +320,7 @@ export default function ExamPage({ page, user, destination = "/", hideSidebar =
|
||||
)}
|
||||
{(moduleIndex === -1 && selectedModules.length !== 0) &&
|
||||
<Finish
|
||||
isLoading={isEvaluationLoading}
|
||||
isLoading={flags.pendingEvaluation}
|
||||
user={user!}
|
||||
modules={selectedModules}
|
||||
solutions={userSolutions}
|
||||
@@ -331,6 +345,7 @@ export default function ExamPage({ page, user, destination = "/", hideSidebar =
|
||||
setUserSolutions(userSolutions);
|
||||
}
|
||||
setShuffles([]);
|
||||
console.log(exam);
|
||||
if (index === undefined) {
|
||||
setFlags({ reviewAll: true });
|
||||
setModuleIndex(0);
|
||||
|
||||
Reference in New Issue
Block a user