139 lines
5.5 KiB
TypeScript
139 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";
|
|
import { access } from "fs";
|
|
|
|
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,
|
|
access: exam.access,
|
|
sections: examState,
|
|
importModule: false,
|
|
sectionLabels:
|
|
exam.module === "level" ?
|
|
sectionLabels(examModule, exam.parts.length) :
|
|
sectionLabels(examModule)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
return {};
|
|
}
|
|
}; |