diff --git a/src/components/Exercises/MultipleChoice.tsx b/src/components/Exercises/MultipleChoice.tsx index c00222c9..fd52cf92 100644 --- a/src/components/Exercises/MultipleChoice.tsx +++ b/src/components/Exercises/MultipleChoice.tsx @@ -18,8 +18,6 @@ function Question({ const renderPrompt = (prompt: string) => { return reactStringReplace(prompt, /(()\w+(<\/u>))/g, (match) => { const word = match.replaceAll("", "").replaceAll("", ""); - console.log(word); - return word.length > 0 ? {word} : null; }); }; diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx index 91d49c60..42f3b2c8 100644 --- a/src/components/Sidebar.tsx +++ b/src/components/Sidebar.tsx @@ -1,382 +1,229 @@ import clsx from "clsx"; -import { IconType } from "react-icons"; -import { MdSpaceDashboard } from "react-icons/md"; +import {IconType} from "react-icons"; +import {MdSpaceDashboard} from "react-icons/md"; import { - BsFileEarmarkText, - BsClockHistory, - BsPencil, - BsGraphUp, - BsChevronBarRight, - BsChevronBarLeft, - BsShieldFill, - BsCloudFill, - BsCurrencyDollar, - BsClipboardData, - BsFileLock, + BsFileEarmarkText, + BsClockHistory, + BsPencil, + BsGraphUp, + BsChevronBarRight, + BsChevronBarLeft, + BsShieldFill, + BsCloudFill, + BsCurrencyDollar, + BsClipboardData, + BsFileLock, } from "react-icons/bs"; -import { RiLogoutBoxFill } from "react-icons/ri"; -import { SlPencil } from "react-icons/sl"; -import { FaAward } from "react-icons/fa"; +import {RiLogoutBoxFill} from "react-icons/ri"; +import {SlPencil} from "react-icons/sl"; +import {FaAward} from "react-icons/fa"; import Link from "next/link"; -import { useRouter } from "next/router"; +import {useRouter} from "next/router"; import axios from "axios"; import FocusLayer from "@/components/FocusLayer"; -import { preventNavigation } from "@/utils/navigation.disabled"; -import { useEffect, useState } from "react"; +import {preventNavigation} from "@/utils/navigation.disabled"; +import {useEffect, useState} from "react"; import usePreferencesStore from "@/stores/preferencesStore"; -import { User } from "@/interfaces/user"; +import {User} from "@/interfaces/user"; import useTicketsListener from "@/hooks/useTicketsListener"; -import { checkAccess, getTypesOfUser } from "@/utils/permissions"; +import {checkAccess, getTypesOfUser} from "@/utils/permissions"; interface Props { - path: string; - navDisabled?: boolean; - focusMode?: boolean; - onFocusLayerMouseEnter?: () => void; - className?: string; - user: User; + path: string; + navDisabled?: boolean; + focusMode?: boolean; + onFocusLayerMouseEnter?: () => void; + className?: string; + user: User; } interface NavProps { - Icon: IconType; - label: string; - path: string; - keyPath: string; - disabled?: boolean; - isMinimized?: boolean; - badge?: number; + Icon: IconType; + label: string; + path: string; + keyPath: string; + disabled?: boolean; + isMinimized?: boolean; + badge?: number; } -const Nav = ({ - Icon, - label, - path, - keyPath, - disabled = false, - isMinimized = false, - badge, -}: NavProps) => { - return ( - - - {!isMinimized && {label}} - {!!badge && badge > 0 && ( -
- {badge} -
- )} - - ); +const Nav = ({Icon, label, path, keyPath, disabled = false, isMinimized = false, badge}: NavProps) => { + return ( + + + {!isMinimized && {label}} + {!!badge && badge > 0 && ( +
+ {badge} +
+ )} + + ); }; -export default function Sidebar({ - path, - navDisabled = false, - focusMode = false, - user, - onFocusLayerMouseEnter, - className, -}: Props) { - const router = useRouter(); +export default function Sidebar({path, navDisabled = false, focusMode = false, user, onFocusLayerMouseEnter, className}: Props) { + const router = useRouter(); - const [isMinimized, toggleMinimize] = usePreferencesStore((state) => [ - state.isSidebarMinimized, - state.toggleSidebarMinimized, - ]); + const [isMinimized, toggleMinimize] = usePreferencesStore((state) => [state.isSidebarMinimized, state.toggleSidebarMinimized]); - const { totalAssignedTickets } = useTicketsListener(user.id); + const {totalAssignedTickets} = useTicketsListener(user.id); - const logout = async () => { - axios.post("/api/logout").finally(() => { - setTimeout(() => router.reload(), 500); - }); - }; + const logout = async () => { + axios.post("/api/logout").finally(() => { + setTimeout(() => router.reload(), 500); + }); + }; - const disableNavigation = preventNavigation(navDisabled, focusMode); + const disableNavigation = preventNavigation(navDisabled, focusMode); - return ( -
-
-
-
-
+ return ( +
+
+
+
+
-
-
- {isMinimized ? ( - - ) : ( - - )} - {!isMinimized && ( - Minimize - )} -
-
{} : logout} - className={clsx( - "hover:text-mti-rose flex cursor-pointer items-center gap-4 rounded-full p-4 text-black transition duration-300 ease-in-out", - isMinimized ? "w-fit" : "w-full min-w-[250px] px-8" - )} - > - - {!isMinimized && ( - Log Out - )} -
-
- {focusMode && ( - - )} -
- ); +
+
+ {isMinimized ? : } + {!isMinimized && Minimize} +
+
{} : logout} + className={clsx( + "hover:text-mti-rose flex cursor-pointer items-center gap-4 rounded-full p-4 text-black transition duration-300 ease-in-out", + isMinimized ? "w-fit" : "w-full min-w-[250px] px-8", + )}> + + {!isMinimized && Log Out} +
+
+ {focusMode && } +
+ ); } diff --git a/src/components/Solutions/MultipleChoice.tsx b/src/components/Solutions/MultipleChoice.tsx index bab2d45b..a1808a67 100644 --- a/src/components/Solutions/MultipleChoice.tsx +++ b/src/components/Solutions/MultipleChoice.tsx @@ -18,8 +18,6 @@ function Question({ const renderPrompt = (prompt: string) => { return reactStringReplace(prompt, /(()\w+(<\/u>))/g, (match) => { const word = match.replaceAll("", "").replaceAll("", ""); - console.log(word); - return word.length > 0 ? {word} : null; }); }; diff --git a/src/pages/(generation)/LevelGeneration.tsx b/src/pages/(generation)/LevelGeneration.tsx index 55aa0efb..2728eb98 100644 --- a/src/pages/(generation)/LevelGeneration.tsx +++ b/src/pages/(generation)/LevelGeneration.tsx @@ -1,3 +1,5 @@ +import FillBlanksEdit from "@/components/Generation/fill.blanks.edit"; +import WriteBlankEdits from "@/components/Generation/write.blanks.edit"; import Input from "@/components/Low/Input"; import Select from "@/components/Low/Select"; import { @@ -8,6 +10,7 @@ import { LevelPart, FillBlanksExercise, WriteBlanksExercise, + Exercise, } from "@/interfaces/exam"; import useExamStore from "@/stores/examStore"; import {getExamById} from "@/utils/exams"; @@ -42,8 +45,6 @@ const QuestionDisplay = ({question, onUpdate}: {question: MultipleChoiceQuestion const renderPrompt = (prompt: string) => { return reactStringReplace(prompt, /(()\w+(<\/u>))/g, (match) => { const word = match.replaceAll("", "").replaceAll("", ""); - console.log(word); - return word.length > 0 ? {word} : null; }); }; @@ -118,10 +119,67 @@ const TaskTab = ({section, setSection}: {section: LevelSection; setSection: (sec questions: (x as MultipleChoiceExercise).questions.map((q) => (q.id === question.id ? question : q)), })), }; - console.log(updatedExam); setSection(updatedExam as any); }; + const renderExercise = (exercise: Exercise) => { + if (exercise.type === "multipleChoice") + return ( +
+
+ Multiple Choice + {exercise.questions.length} questions +
+ {exercise.prompt} +
+ {exercise.questions.map((question) => ( + + ))} +
+
+ ); + + if (exercise.type === "fillBlanks") + return ( +
+
+ Fill Blanks +
+ {exercise.prompt} + + setSection({ + ...section, + part: {...section.part!, exercises: section.part!.exercises.map((x) => (x.id === exercise.id ? {...x, ...data} : x))}, + }) + } + /> +
+ ); + + if (exercise.type === "writeBlanks") + return ( +
+
+ Write Blanks +
+ {exercise.prompt} + + setSection({ + ...section, + part: {...section.part!, exercises: section.part!.exercises.map((x) => (x.id === exercise.id ? {...x, ...data} : x))}, + }) + } + /> +
+ ); + }; + return (
@@ -159,28 +217,8 @@ const TaskTab = ({section, setSection}: {section: LevelSection; setSection: (sec )} {section?.part && (
- {section.part.exercises - .filter((x) => x.type === "multipleChoice") - .map((ex) => { - const exercise = ex as MultipleChoiceExercise; - - return ( -
-
- Multiple Choice - - {exercise.questions.length} questions - -
- {exercise.prompt} -
- {exercise.questions.map((question) => ( - - ))} -
-
- ); - })} + {section.part.context &&
{section.part.context}
} + {section.part.exercises.map(renderExercise)}
)} @@ -237,6 +275,8 @@ const LevelGeneration = () => { } }); + let newParts = [...parts]; + axios .post<{exercises: {[key: string]: any}}>("/api/exam/level/generate/level", {nr_exercises: numberOfParts, ...body}) .then((result) => { @@ -270,22 +310,20 @@ const LevelGeneration = () => { userSolutions: [], }; - setParts((prev) => - prev.map((p, i) => - i === index - ? { - ...p, - part: { - exercises: [exercise], - }, - } - : p, - ), - ); - - return { + const item = { exercises: [exercise], }; + + newParts = newParts.map((p, i) => + i === index + ? { + ...p, + part: item, + } + : p, + ); + + return item; } if (part.type === "blank_space_text") { @@ -300,22 +338,20 @@ const LevelGeneration = () => { userSolutions: [], }; - setParts((prev) => - prev.map((p, i) => - i === index - ? { - ...p, - part: { - exercises: [exercise], - }, - } - : p, - ), - ); - - return { + const item = { exercises: [exercise], }; + + newParts = newParts.map((p, i) => + i === index + ? { + ...p, + part: item, + } + : p, + ); + + return item; } const mcExercise: MultipleChoiceExercise = { @@ -339,29 +375,26 @@ const LevelGeneration = () => { userSolutions: [], }; - setParts((prev) => - prev.map((p, i) => - i === index - ? { - ...p, - part: { - context: currentExercise.text.content, - exercises: [mcExercise, wbExercise], - }, - } - : p, - ), - ); - - return { + const item = { context: currentExercise.text.content, exercises: [mcExercise, wbExercise], }; + + newParts = newParts.map((p, i) => + i === index + ? { + ...p, + part: item, + } + : p, + ); + + return item; }) .filter((x) => !!x) as LevelPart[], }; - console.log(exam); + setParts(newParts); setGeneratedExam(exam); }) .finally(() => setIsLoading(false)); @@ -375,8 +408,13 @@ const LevelGeneration = () => { setIsLoading(true); + const exam = { + ...generatedExam, + parts: generatedExam.parts.map((p, i) => ({...p, exercises: parts[i].part!.exercises})), + }; + axios - .post(`/api/exam/level`, generatedExam) + .post(`/api/exam/level`, exam) .then((result) => { playSound("sent"); console.log(`Generated Exam ID: ${result.data.id}`); @@ -437,7 +475,10 @@ const LevelGeneration = () => { setParts((prev) => prev.map((x, i) => (i === index ? part : x)))} + setSection={(part) => { + console.log(part); + setParts((prev) => prev.map((x, i) => (i === index ? part : x))); + }} /> ))}