Updated the Writing exercise to have the evaluation in the user solutions instead of the exercise itself

This commit is contained in:
Tiago Ribeiro
2023-06-23 10:28:33 +01:00
parent 9cbb5b93c8
commit b2cc706a5e
5 changed files with 44 additions and 38 deletions

View File

@@ -107,7 +107,7 @@ export default function Writing({id, prompt, info, type, wordCounter, attachment
<Button <Button
color="green" color="green"
disabled={!isSubmitEnabled} disabled={!isSubmitEnabled}
onClick={() => onNext({exercise: id, solutions: [inputText], score: {correct: 1, total: 1, missing: 0}, type})} onClick={() => onNext({exercise: id, solutions: [{id, solution: inputText}], score: {correct: 1, total: 1, missing: 0}, type})}
className="max-w-[200px] self-end w-full"> className="max-w-[200px] self-end w-full">
Next Next
</Button> </Button>

View File

@@ -10,7 +10,7 @@ import {toast} from "react-toastify";
import Button from "../Low/Button"; import Button from "../Low/Button";
import {Dialog, Transition} from "@headlessui/react"; import {Dialog, Transition} from "@headlessui/react";
export default function Writing({id, prompt, info, evaluation, attachment, userSolutions, onNext, onBack}: WritingExercise & CommonProps) { export default function Writing({id, prompt, info, attachment, userSolutions, onNext, onBack}: WritingExercise & CommonProps) {
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
return ( return (
@@ -74,21 +74,25 @@ export default function Writing({id, prompt, info, evaluation, attachment, userS
className="w-full h-full min-h-[320px] cursor-text px-7 py-8 input border-2 border-mti-gray-platinum bg-white rounded-3xl" className="w-full h-full min-h-[320px] cursor-text px-7 py-8 input border-2 border-mti-gray-platinum bg-white rounded-3xl"
contentEditable={false} contentEditable={false}
readOnly readOnly
value={userSolutions[0] as any} value={userSolutions[0]!.solution}
/> />
</div> </div>
)} )}
{userSolutions && userSolutions.length > 0 && (
<div className="flex flex-col gap-4 w-full"> <div className="flex flex-col gap-4 w-full">
<div className="flex gap-4 px-1"> <div className="flex gap-4 px-1">
{Object.keys(evaluation!.task_response).map((key) => ( {Object.keys(userSolutions[0].evaluation!.task_response).map((key) => (
<div className="bg-ielts-writing text-ielts-writing-light rounded-xl px-4 py-2" key={key}> <div className="bg-ielts-writing text-ielts-writing-light rounded-xl px-4 py-2" key={key}>
{key}: Level {evaluation!.task_response[key]} {key}: Level {userSolutions[0].evaluation!.task_response[key]}
</div> </div>
))} ))}
</div> </div>
<div className="w-full h-full min-h-fit cursor-text px-7 py-8 bg-mti-gray-smoke rounded-3xl">{evaluation!.comment}</div> <div className="w-full h-full min-h-fit cursor-text px-7 py-8 bg-mti-gray-smoke rounded-3xl">
{userSolutions[0].evaluation!.comment}
</div> </div>
</div> </div>
)}
</div>
</div> </div>
<div className="self-end flex justify-between w-full gap-8 absolute bottom-8 left-0 px-8"> <div className="self-end flex justify-between w-full gap-8 absolute bottom-8 left-0 px-8">

View File

@@ -89,6 +89,7 @@ export interface WritingExercise {
userSolutions: { userSolutions: {
id: string; id: string;
solution: string; solution: string;
evaluation?: WritingEvaluation;
}[]; }[];
} }

View File

@@ -40,6 +40,8 @@ async function post(req: NextApiRequest, res: NextApiResponse) {
return; return;
} }
console.log("HERE");
const stats = req.body as Stat[]; const stats = req.body as Stat[];
await stats.forEach(async (stat) => await addDoc(collection(db, "stats"), stat)); await stats.forEach(async (stat) => await addDoc(collection(db, "stats"), stat));

View File

@@ -82,8 +82,7 @@ export default function Page() {
}, [selectedModules, setExams, exams]); }, [selectedModules, setExams, exams]);
useEffect(() => { useEffect(() => {
(async () => { if (selectedModules.length > 0 && exams.length !== 0 && moduleIndex >= selectedModules.length && !hasBeenUploaded) {
if (selectedModules.length > 0 && exams.length === 0 && moduleIndex >= selectedModules.length && !hasBeenUploaded) {
const newStats: Stat[] = userSolutions.map((solution) => ({ const newStats: Stat[] = userSolutions.map((solution) => ({
...solution, ...solution,
session: sessionId, session: sessionId,
@@ -93,12 +92,13 @@ export default function Page() {
date: new Date().getTime(), date: new Date().getTime(),
})); }));
console.log("GOING TO SAVE");
axios axios
.post<{ok: boolean}>("/api/stats", newStats) .post<{ok: boolean}>("/api/stats", newStats)
.then((response) => setHasBeenUploaded(response.data.ok)) .then((response) => setHasBeenUploaded(response.data.ok))
.catch(() => setHasBeenUploaded(false)); .catch(() => setHasBeenUploaded(false));
} }
})();
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedModules, moduleIndex, hasBeenUploaded]); }, [selectedModules, moduleIndex, hasBeenUploaded]);
@@ -123,21 +123,20 @@ export default function Page() {
} }
}; };
const evaluateWritingAnswer = async (examId: string, exerciseId: string, answer: string) => { const evaluateWritingAnswer = async (examId: string, exerciseId: string, solution: UserSolution) => {
const writingExam = exams.find((x) => x.id === examId)!; const writingExam = exams.find((x) => x.id === examId)!;
const exercise = writingExam.exercises.find((x) => x.id === exerciseId)! as WritingExercise; const exercise = writingExam.exercises.find((x) => x.id === exerciseId)! as WritingExercise;
const response = await axios.post("/api/exam/writing/evaluate", { const response = await axios.post("/api/exam/writing/evaluate", {
question: `${exercise.prompt} ${exercise.attachment ? exercise.attachment.description : ""}`.replaceAll("\n", ""), question: `${exercise.prompt} ${exercise.attachment ? exercise.attachment.description : ""}`.replaceAll("\n", ""),
answer: answer.trim().replaceAll("\n", " "), answer: solution.solutions[0].solution.trim().replaceAll("\n", " "),
}); });
if (response.status === 200) { if (response.status === 200) {
writingExam.exercises = [ setUserSolutions([
...writingExam.exercises.filter((x) => x.id !== exerciseId), ...userSolutions.filter((x) => x.exercise !== exerciseId),
Object.assign(exercise, {evaluation: response.data}), {...solution, solutions: [{id: exerciseId, solution: solution.solutions[0].solution, evaluation: response.data}]},
]; ]);
setExams([...exams.filter((x) => x.id !== examId), writingExam].sort(sortByModule));
} }
}; };
@@ -153,13 +152,13 @@ export default function Page() {
const solutionIds = solutions.map((x) => x.exercise); const solutionIds = solutions.map((x) => x.exercise);
if (exam && exam.module === "writing" && solutions.length > 0 && !showSolutions) { if (exam && exam.module === "writing" && solutions.length > 0 && !showSolutions) {
setHasBeenUploaded(true);
setIsEvaluationLoading(true); setIsEvaluationLoading(true);
Promise.all( Promise.all(
exam.exercises.map((exercise) => exam.exercises.map((exercise) => evaluateWritingAnswer(exam.id, exercise.id, solutions.find((x) => x.exercise === exercise.id)!)),
evaluateWritingAnswer(exam.id, exercise.id, solutions.find((x) => x.exercise === exercise.id)!.solutions[0]),
),
).finally(() => { ).finally(() => {
setIsEvaluationLoading(false); setIsEvaluationLoading(false);
setHasBeenUploaded(false);
}); });
} }