import { renderExercise } from "@/components/Exercises"; import ModuleTitle from "@/components/Medium/ModuleTitle"; import { renderSolution } from "@/components/Solutions"; import { UserSolution, WritingExam } from "@/interfaces/exam"; import useExamStore, { usePersistentExamStore } from "@/stores/examStore"; import { countExercises } from "@/utils/moduleUtils"; import PartDivider from "./Navigation/SectionDivider"; import { useEffect, useState } from "react"; interface Props { exam: WritingExam; showSolutions?: boolean; preview?: boolean; onFinish: (userSolutions: UserSolution[]) => void; } export default function Writing({ exam, showSolutions = false, preview = false, onFinish }: Props) { const writingBgColor = "bg-ielts-writing-light"; const examState = useExamStore((state) => state); const persistentExamState = usePersistentExamStore((state) => state); const { userSolutions, exerciseIndex, hasExamEnded, setBgColor, setUserSolutions, setHasExamEnded, setExerciseIndex, } = !preview ? examState : persistentExamState; const [seenParts, setSeenParts] = useState>(new Set(showSolutions ? exam.exercises.map((_, index) => index) : [])); const [showPartDivider, setShowPartDivider] = useState(typeof exam.exercises[0].intro === "string" && exam.exercises[0].intro !== ""); useEffect(() => { if (hasExamEnded && exerciseIndex === -1) { setExerciseIndex(exerciseIndex + 1); } }, [hasExamEnded, exerciseIndex, setExerciseIndex]); const scrollToTop = () => Array.from(document.getElementsByTagName("body")).forEach((body) => body.scrollTo(0, 0)); useEffect(() => { if (!showSolutions && exam.exercises[exerciseIndex]?.intro !== undefined && exam.exercises[exerciseIndex]?.intro !== "" && !seenParts.has(exerciseIndex)) { setShowPartDivider(true); setBgColor(writingBgColor); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [exerciseIndex]); const nextExercise = (solution?: UserSolution) => { scrollToTop(); if (solution) { setUserSolutions([...userSolutions.filter((x) => x.exercise !== solution.exercise), { ...solution, module: "writing", exam: exam.id }]); } if (exerciseIndex + 1 < exam.exercises.length) { setExerciseIndex(exerciseIndex + 1); return; } if (exerciseIndex >= exam.exercises.length) return; setHasExamEnded(false); if (solution) { onFinish([...userSolutions.filter((x) => x.exercise !== solution.exercise), { ...solution, module: "writing", exam: exam.id }]); } else { onFinish(userSolutions); } }; const previousExercise = (solution?: UserSolution) => { scrollToTop(); if (solution) { setUserSolutions([...userSolutions.filter((x) => x.exercise !== solution.exercise), { ...solution, module: "writing", exam: exam.id }]); } if (exerciseIndex > 0) { setExerciseIndex(exerciseIndex - 1); } }; const getExercise = () => { const exercise = exam.exercises[exerciseIndex]; return { ...exercise, userSolutions: userSolutions.find((x) => x.exercise === exercise.id)?.solutions || [], }; }; return ( <> {(showPartDivider) ? { setShowPartDivider(false); setBgColor("bg-white"); setSeenParts((prev) => new Set(prev).add(exerciseIndex))}} /> : (
{exerciseIndex > -1 && exerciseIndex < exam.exercises.length && !showSolutions && renderExercise(getExercise(), exam.id, nextExercise, previousExercise, preview)} {exerciseIndex > -1 && exerciseIndex < exam.exercises.length && showSolutions && renderSolution(exam.exercises[exerciseIndex], nextExercise, previousExercise)}
) } ); }