114 lines
3.3 KiB
TypeScript
114 lines
3.3 KiB
TypeScript
import { Module } from "@/interfaces";
|
|
import {
|
|
Exam,
|
|
ReadingExam,
|
|
ListeningExam,
|
|
WritingExam,
|
|
SpeakingExam,
|
|
Exercise,
|
|
UserSolution,
|
|
LevelExam,
|
|
Variant,
|
|
InstructorGender,
|
|
} from "@/interfaces/exam";
|
|
import axios from "axios";
|
|
|
|
export const getExam = async (
|
|
module: Module,
|
|
avoidRepeated: boolean,
|
|
variant?: Variant,
|
|
instructorGender?: InstructorGender,
|
|
): Promise<Exam | undefined> => {
|
|
const url = new URLSearchParams();
|
|
url.append("avoidRepeated", avoidRepeated.toString());
|
|
|
|
if (variant) url.append("variant", variant);
|
|
if (module === "speaking" && instructorGender) url.append("instructorGender", instructorGender);
|
|
|
|
const examRequest = await axios<Exam[]>(`/api/exam/${module}?${url.toString()}`);
|
|
if (examRequest.status !== 200) {
|
|
return undefined;
|
|
}
|
|
|
|
const newExam = examRequest.data;
|
|
|
|
switch (module) {
|
|
case "reading":
|
|
return newExam.shift() as ReadingExam;
|
|
case "listening":
|
|
return newExam.shift() as ListeningExam;
|
|
case "writing":
|
|
return newExam.shift() as WritingExam;
|
|
case "speaking":
|
|
return newExam.shift() as SpeakingExam;
|
|
case "level":
|
|
return newExam.shift() as LevelExam;
|
|
}
|
|
};
|
|
|
|
export const getExamById = async (module: Module, id: string): Promise<Exam | undefined> => {
|
|
const examRequest = await axios<Exam>(`/api/exam/${module}/${id}`);
|
|
if (examRequest.status !== 200) {
|
|
return undefined;
|
|
}
|
|
|
|
const newExam = examRequest.data;
|
|
|
|
switch (module) {
|
|
case "reading":
|
|
return newExam as ReadingExam;
|
|
case "listening":
|
|
return newExam as ListeningExam;
|
|
case "writing":
|
|
return newExam as WritingExam;
|
|
case "speaking":
|
|
return newExam as SpeakingExam;
|
|
case "level":
|
|
return newExam as LevelExam;
|
|
}
|
|
};
|
|
|
|
export const defaultExamUserSolutions = (exam: Exam) => {
|
|
if (exam.module === "reading" || exam.module === "listening" || exam.module === "level")
|
|
return (exam.parts.flatMap((x) => x.exercises) ?? []).map((x) => defaultUserSolutions(x, exam));
|
|
|
|
return (exam.exercises ?? []).map((x) => defaultUserSolutions(x, exam));
|
|
};
|
|
|
|
export const defaultUserSolutions = (exercise: Exercise, exam: Exam): UserSolution => {
|
|
const defaultSettings = {
|
|
exam: exam.id,
|
|
exercise: exercise.id,
|
|
solutions: [],
|
|
module: exam.module,
|
|
type: exercise.type,
|
|
};
|
|
|
|
let total = 0;
|
|
switch (exercise.type) {
|
|
case "fillBlanks":
|
|
total = exercise.text.match(/({{\d+}})/g)?.length || 0;
|
|
return { ...defaultSettings, score: { correct: 0, total, missing: total } };
|
|
case "matchSentences":
|
|
total = exercise.sentences.length;
|
|
return { ...defaultSettings, score: { correct: 0, total, missing: total } };
|
|
case "multipleChoice":
|
|
total = exercise.questions.length;
|
|
return { ...defaultSettings, score: { correct: 0, total, missing: total } };
|
|
case "writeBlanks":
|
|
total = exercise.text.match(/({{\d+}})/g)?.length || 0;
|
|
return { ...defaultSettings, score: { correct: 0, total, missing: total } };
|
|
case "trueFalse":
|
|
total = exercise.questions.length;
|
|
return { ...defaultSettings, score: { correct: 0, total, missing: total } };
|
|
case "writing":
|
|
total = 1;
|
|
return { ...defaultSettings, score: { correct: 0, total, missing: total } };
|
|
case "speaking":
|
|
total = 1;
|
|
return { ...defaultSettings, score: { correct: 0, total, missing: total } };
|
|
default:
|
|
return { ...defaultSettings, score: { correct: 0, total: 0, missing: 0 } };
|
|
}
|
|
};
|