Finalized the Level Generation
This commit is contained in:
@@ -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, /((<u>)\w+(<\/u>))/g, (match) => {
|
||||
const word = match.replaceAll("<u>", "").replaceAll("</u>", "");
|
||||
console.log(word);
|
||||
|
||||
return word.length > 0 ? <u>{word}</u> : 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 (
|
||||
<div key={exercise.id} className="w-full h-full flex flex-col gap-2">
|
||||
<div className="flex gap-2">
|
||||
<span className="text-xl font-semibold">Multiple Choice</span>
|
||||
<span className="rounded-xl bg-white border border-ielts-level p-1 px-4 w-fit">{exercise.questions.length} questions</span>
|
||||
</div>
|
||||
<span>{exercise.prompt}</span>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{exercise.questions.map((question) => (
|
||||
<QuestionDisplay question={question} onUpdate={onUpdate} key={question.id} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (exercise.type === "fillBlanks")
|
||||
return (
|
||||
<div key={exercise.id} className="w-full h-full flex flex-col gap-2">
|
||||
<div className="flex gap-2">
|
||||
<span className="text-xl font-semibold">Fill Blanks</span>
|
||||
</div>
|
||||
<span>{exercise.prompt}</span>
|
||||
<FillBlanksEdit
|
||||
exercise={exercise}
|
||||
key={exercise.id}
|
||||
updateExercise={(data: any) =>
|
||||
setSection({
|
||||
...section,
|
||||
part: {...section.part!, exercises: section.part!.exercises.map((x) => (x.id === exercise.id ? {...x, ...data} : x))},
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (exercise.type === "writeBlanks")
|
||||
return (
|
||||
<div key={exercise.id} className="w-full h-full flex flex-col gap-2">
|
||||
<div className="flex gap-2">
|
||||
<span className="text-xl font-semibold">Write Blanks</span>
|
||||
</div>
|
||||
<span>{exercise.prompt}</span>
|
||||
<WriteBlankEdits
|
||||
exercise={exercise}
|
||||
key={exercise.id}
|
||||
updateExercise={(data: any) =>
|
||||
setSection({
|
||||
...section,
|
||||
part: {...section.part!, exercises: section.part!.exercises.map((x) => (x.id === exercise.id ? {...x, ...data} : x))},
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Tab.Panel className="w-full bg-ielts-level/20 min-h-[600px] h-full rounded-xl p-6 flex flex-col gap-4">
|
||||
<div className="flex flex-col gap-4">
|
||||
@@ -159,28 +217,8 @@ const TaskTab = ({section, setSection}: {section: LevelSection; setSection: (sec
|
||||
)}
|
||||
{section?.part && (
|
||||
<div className="flex flex-col gap-2 w-full overflow-y-scroll scrollbar-hide h-full">
|
||||
{section.part.exercises
|
||||
.filter((x) => x.type === "multipleChoice")
|
||||
.map((ex) => {
|
||||
const exercise = ex as MultipleChoiceExercise;
|
||||
|
||||
return (
|
||||
<div key={ex.id} className="w-full h-full flex flex-col gap-2">
|
||||
<div className="flex gap-2">
|
||||
<span className="text-xl font-semibold">Multiple Choice</span>
|
||||
<span className="rounded-xl bg-white border border-ielts-level p-1 px-4 w-fit">
|
||||
{exercise.questions.length} questions
|
||||
</span>
|
||||
</div>
|
||||
<span>{exercise.prompt}</span>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{exercise.questions.map((question) => (
|
||||
<QuestionDisplay question={question} onUpdate={onUpdate} key={question.id} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
{section.part.context && <div>{section.part.context}</div>}
|
||||
{section.part.exercises.map(renderExercise)}
|
||||
</div>
|
||||
)}
|
||||
</Tab.Panel>
|
||||
@@ -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 = () => {
|
||||
<TaskTab
|
||||
key={index}
|
||||
section={parts[index]}
|
||||
setSection={(part) => 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)));
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Tab.Panels>
|
||||
|
||||
Reference in New Issue
Block a user