Files
encoach_frontend/src/stores/examEditor/reducers/index.ts
Carlos-Mesquita 6f9be29cd8 ENCOA-312
2025-01-13 21:02:34 +00:00

138 lines
5.5 KiB
TypeScript

import { Exam, ExerciseOnlyExam, PartExam } from "@/interfaces/exam";
import defaultModuleSettings, { defaultSectionSettings, defaultSettings, sectionLabels } from "../defaults";
import ExamEditorStore, { SectionState } from "../types";
import { MODULE_ACTIONS, ModuleActions, moduleReducer } from "./moduleReducer";
import { SECTION_ACTIONS, SectionActions, sectionReducer } from "./sectionReducer";
import { Module } from "@/interfaces";
import { updateExamWithUserSolutions } from "@/stores/exam/utils";
import { defaultExamUserSolutions } from "@/utils/exams";
type RootActions = { type: 'FULL_RESET' } |
{ type: 'INIT_EXAM_EDIT', payload: { exam: Exam; examModule: Module; id: string } } |
{ type: 'UPDATE_ROOT'; payload: { updates: Partial<ExamEditorStore> } } |
{ type: 'RESET_MODULE'; payload: { module: Module } };
export type Action = ModuleActions | SectionActions | RootActions;
export const rootReducer = (
state: ExamEditorStore,
action: Action
): Partial<ExamEditorStore> => {
if (MODULE_ACTIONS.includes(action.type as any)) {
if (action.type === "REORDER_EXERCISES") {
const updatedState = sectionReducer(state, action as SectionActions);
if (!updatedState.modules) return state;
return moduleReducer({
...state,
modules: updatedState.modules
}, { type: "REORDER_EXERCISES" });
}
return moduleReducer(state, action as ModuleActions);
}
if (SECTION_ACTIONS.includes(action.type as any)) {
if (action.type === "UPDATE_SECTION_STATE") {
const updatedState = sectionReducer(state, action as SectionActions);
if (!updatedState.modules) return state;
return moduleReducer({
...state,
modules: updatedState.modules
}, { type: "REORDER_EXERCISES" });
}
return sectionReducer(state, action as SectionActions);
}
switch (action.type) {
case 'UPDATE_ROOT':
const { updates } = action.payload;
return {
...state,
...updates
};
case 'RESET_MODULE':
const { module } = action.payload;
const timer = ["reading", "writing", "level"].includes(module) ?
60 : (module === "speaking" ? 14 : 30);
return {
modules: {
...state.modules,
[module]: defaultModuleSettings(module, timer, true),
},
};
case 'FULL_RESET':
return {
title: "",
currentModule: "reading",
speakingAvatars: [],
modules: {
reading: defaultModuleSettings("reading", 60),
writing: defaultModuleSettings("writing", 60),
speaking: defaultModuleSettings("speaking", 14),
listening: defaultModuleSettings("listening", 30),
level: defaultModuleSettings("level", 60)
},
};
case 'INIT_EXAM_EDIT': {
const { exam, id, examModule } = action.payload;
let typedExam;
let examState;
if (["reading", "listening", "level"].includes(examModule)) {
typedExam = updateExamWithUserSolutions(exam, defaultExamUserSolutions(exam)) as PartExam;
examState = typedExam.parts.map((part, index) => {
return {
...defaultSectionSettings(examModule, index + 1, part),
sectionId: index + 1,
settings: {
...defaultSettings(examModule),
category: part.category,
introOption: { label: 'Custom', value: 'Custom' },
currentIntro: part.intro
},
}
})
} else {
typedExam = updateExamWithUserSolutions(exam, defaultExamUserSolutions(exam)) as ExerciseOnlyExam;
examState = typedExam.exercises.map((exercise, index) => {
return {
...defaultSectionSettings(examModule, index + 1),
sectionId: index + 1,
settings: {
...defaultSettings(examModule),
category: exercise.category,
introOption: { label: 'Custom', value: 'Custom' },
currentIntro: exercise.intro
},
state: exercise,
}
})
}
return {
title: id,
modules: {
...state.modules,
[examModule]: {
...defaultModuleSettings(examModule, exam.minTimer),
examLabel: exam.label,
difficulty: exam.difficulty,
isPrivate: exam.private,
sections: examState,
importModule: false,
sectionLabels:
exam.module === "level" ?
sectionLabels(examModule, exam.parts.length) :
sectionLabels(examModule)
}
}
}
}
default:
return {};
}
};