diff --git a/src/components/Diagnostic.tsx b/src/components/Diagnostic.tsx new file mode 100644 index 00000000..a67159f5 --- /dev/null +++ b/src/components/Diagnostic.tsx @@ -0,0 +1,119 @@ +import {infoButtonStyle} from "@/constants/buttonStyles"; +import {BAND_SCORES} from "@/constants/ielts"; +import {Module} from "@/interfaces"; +import {User} from "@/interfaces/user"; +import useExamStore from "@/stores/examStore"; +import {getExamById} from "@/utils/exams"; +import axios from "axios"; +import clsx from "clsx"; +import {capitalize} from "lodash"; +import {useRouter} from "next/router"; +import {useState} from "react"; +import {toast} from "react-toastify"; + +interface Props { + user: User; + onFinish: () => void; +} + +const DIAGNOSTIC_EXAMS = [ + ["reading", "CurQtQoxWmHaJHeN0JW2"], + ["listening", "Y6cMao8kUcVnPQOo6teV"], + ["writing", "hbueuDaEZXV37EW7I12A"], + ["speaking", "QVFm4pdcziJQZN2iUTDo"], +]; + +export default function Diagnostic({onFinish}: Props) { + const [focus, setFocus] = useState<"academic" | "general">(); + const [isInsert, setIsInsert] = useState(false); + const [levels, setLevels] = useState({reading: 0, listening: 0, writing: 0, speaking: 0}); + + const router = useRouter(); + + const setExams = useExamStore((state) => state.setExams); + const setSelectedModules = useExamStore((state) => state.setSelectedModules); + + const selectExam = () => { + const examPromises = DIAGNOSTIC_EXAMS.map((exam) => getExamById(exam[0] as Module, exam[1])); + + Promise.all(examPromises).then((exams) => { + if (exams.every((x) => !!x)) { + setExams(exams.map((x) => x!)); + setSelectedModules(exams.map((x) => x!.module)); + router.push("/exam"); + } + }); + }; + + const updateUser = (callback: () => void) => { + axios + .patch("/api/users/update", {focus, levels, isFirstLogin: false}) + .then(callback) + .catch(() => { + toast.error("Something went wrong, please try again later!", {toastId: "user-update-error"}); + }); + }; + + if (!focus) { + return ( +
+

What is your focus?

+
+ + +
+
+ ); + } + + if (isInsert) { + return ( +
+

What is your level?

+
+ {Object.keys(levels).map((module) => ( +
+ {capitalize(module)} + setLevels((prev) => ({...prev, [module]: parseFloat(e.target.value)}))} + /> +
+ ))} +
+ +
+ ); + } + + return ( +
+

What is your current IELTS level?

+
+ + +
+
+ ); +} diff --git a/src/components/Exercises/Writing.tsx b/src/components/Exercises/Writing.tsx index 5db9d90b..cf2d5063 100644 --- a/src/components/Exercises/Writing.tsx +++ b/src/components/Exercises/Writing.tsx @@ -1,3 +1,4 @@ +/* eslint-disable @next/next/no-img-element */ import {errorButtonStyle, infoButtonStyle} from "@/constants/buttonStyles"; import {WritingExercise} from "@/interfaces/exam"; import {mdiArrowLeft, mdiArrowRight} from "@mdi/js"; @@ -7,7 +8,7 @@ import {CommonProps} from "."; import {Fragment, useEffect, useState} from "react"; import {toast} from "react-toastify"; -export default function Writing({id, prompt, info, type, wordCounter, onNext, onBack}: WritingExercise & CommonProps) { +export default function Writing({id, prompt, info, type, wordCounter, attachment, onNext, onBack}: WritingExercise & CommonProps) { const [inputText, setInputText] = useState(""); const [isSubmitEnabled, setIsSubmitEnabled] = useState(false); @@ -40,6 +41,7 @@ export default function Writing({id, prompt, info, type, wordCounter, onNext, on You should write {wordCounter.type === "min" ? "at least" : "at most"} {wordCounter.limit} words. + {attachment && Exercise attachment}