Implemented the Writing exercise's solution display
This commit is contained in:
@@ -6,7 +6,7 @@ import {Module} from "@/interfaces";
|
||||
|
||||
import Selection from "@/exams/Selection";
|
||||
import Reading from "@/exams/Reading";
|
||||
import {Exam, ListeningExam, ReadingExam, SpeakingExam, UserSolution, WritingExam} from "@/interfaces/exam";
|
||||
import {Exam, ListeningExam, ReadingExam, SpeakingExam, UserSolution, WritingExam, WritingExercise} from "@/interfaces/exam";
|
||||
import Listening from "@/exams/Listening";
|
||||
import Writing from "@/exams/Writing";
|
||||
import {ToastContainer, toast} from "react-toastify";
|
||||
@@ -21,6 +21,7 @@ import useUser from "@/hooks/useUser";
|
||||
import useExamStore from "@/stores/examStore";
|
||||
import Sidebar from "@/components/Sidebar";
|
||||
import Layout from "@/components/High/Layout";
|
||||
import {sortByModule} from "@/utils/moduleUtils";
|
||||
|
||||
export const getServerSideProps = withIronSessionSsr(({req, res}) => {
|
||||
const user = req.session.user;
|
||||
@@ -46,7 +47,7 @@ export default function Page() {
|
||||
const [moduleIndex, setModuleIndex] = useState(0);
|
||||
const [sessionId, setSessionId] = useState("");
|
||||
const [exam, setExam] = useState<Exam>();
|
||||
const [timer, setTimer] = useState(-1);
|
||||
const [isEvaluationLoading, setIsEvaluationLoading] = useState(false);
|
||||
|
||||
const [exams, setExams] = useExamStore((state) => [state.exams, state.setExams]);
|
||||
const [userSolutions, setUserSolutions] = useExamStore((state) => [state.userSolutions, state.setUserSolutions]);
|
||||
@@ -101,17 +102,6 @@ export default function Page() {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedModules, moduleIndex, hasBeenUploaded]);
|
||||
|
||||
useEffect(() => {
|
||||
if (exam) {
|
||||
setTimer(exam.minTimer * 60);
|
||||
const timerInterval = setInterval(() => setTimer((prev) => (prev && prev > 0 ? prev - 1 : 0)), 1000);
|
||||
|
||||
return () => {
|
||||
clearInterval(timerInterval);
|
||||
};
|
||||
}
|
||||
}, [exam]);
|
||||
|
||||
const getExam = async (module: Module): Promise<Exam | undefined> => {
|
||||
const examRequest = await axios<Exam[]>(`/api/exam/${module}`);
|
||||
if (examRequest.status !== 200) {
|
||||
@@ -133,6 +123,24 @@ export default function Page() {
|
||||
}
|
||||
};
|
||||
|
||||
const evaluateWritingAnswer = async (examId: string, exerciseId: string, answer: string) => {
|
||||
const writingExam = exams.find((x) => x.id === examId)!;
|
||||
const exercise = writingExam.exercises.find((x) => x.id === exerciseId)! as WritingExercise;
|
||||
|
||||
const response = await axios.post("/api/exam/writing/evaluate", {
|
||||
question: `${exercise.prompt} ${exercise.attachment ? exercise.attachment.description : ""}`.replaceAll("\n", ""),
|
||||
answer: answer.trim().replaceAll("\n", " "),
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
writingExam.exercises = [
|
||||
...writingExam.exercises.filter((x) => x.id !== exerciseId),
|
||||
Object.assign(exercise, {evaluation: response.data}),
|
||||
];
|
||||
setExams([...exams.filter((x) => x.id !== examId), writingExam].sort(sortByModule));
|
||||
}
|
||||
};
|
||||
|
||||
const updateExamWithUserSolutions = (exam: Exam): Exam => {
|
||||
const exercises = exam.exercises.map((x) =>
|
||||
Object.assign(x, !x.userSolutions ? {userSolutions: userSolutions.find((y) => x.id === y.exercise)?.solutions} : x.userSolutions),
|
||||
@@ -144,6 +152,17 @@ export default function Page() {
|
||||
const onFinish = (solutions: UserSolution[]) => {
|
||||
const solutionIds = solutions.map((x) => x.exercise);
|
||||
|
||||
if (exam && exam.module === "writing" && solutions.length > 0 && !showSolutions) {
|
||||
setIsEvaluationLoading(true);
|
||||
Promise.all(
|
||||
exam.exercises.map((exercise) =>
|
||||
evaluateWritingAnswer(exam.id, exercise.id, solutions.find((x) => x.exercise === exercise.id)!.solutions[0]),
|
||||
),
|
||||
).finally(() => {
|
||||
setIsEvaluationLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
setUserSolutions([...userSolutions.filter((x) => !solutionIds.includes(x.exercise)), ...solutions]);
|
||||
setModuleIndex((prev) => prev + 1);
|
||||
};
|
||||
@@ -193,6 +212,7 @@ export default function Page() {
|
||||
if (moduleIndex >= selectedModules.length) {
|
||||
return (
|
||||
<Finish
|
||||
isLoading={isEvaluationLoading}
|
||||
user={user!}
|
||||
modules={selectedModules}
|
||||
onViewResults={() => {
|
||||
@@ -213,11 +233,6 @@ export default function Page() {
|
||||
return <Listening exam={exam} onFinish={onFinish} showSolutions={showSolutions} />;
|
||||
}
|
||||
|
||||
if (exam && exam.module === "writing" && showSolutions) {
|
||||
setModuleIndex((prev) => prev + 1);
|
||||
return <></>;
|
||||
}
|
||||
|
||||
if (exam && exam.module === "writing") {
|
||||
return <Writing exam={exam} onFinish={onFinish} showSolutions={showSolutions} />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user