119 lines
4.7 KiB
TypeScript
119 lines
4.7 KiB
TypeScript
import { Module } from "@/interfaces";
|
|
import ExamEditorStore, { Generating, ReadingSectionSettings, Section, SectionSettings, SectionState } from "../types";
|
|
import { DragEndEvent } from "@dnd-kit/core";
|
|
import { LevelPart, ListeningPart, ReadingPart } from "@/interfaces/exam";
|
|
import { reorderSection } from "../reorder/global";
|
|
|
|
export type SectionActions =
|
|
| { type: 'UPDATE_SECTION_SINGLE_FIELD'; payload: { module: Module; sectionId: number; field: string; value: any } }
|
|
| { type: 'UPDATE_SECTION_SETTINGS'; payload: { sectionId: number; module: Module; update: Partial<SectionSettings>; } }
|
|
| { type: 'UPDATE_SECTION_STATE'; payload: { sectionId: number; module: Module; update: Partial<Section>; } }
|
|
| { type: 'REORDER_EXERCISES'; payload: { event: DragEndEvent, module: Module; sectionId: number; } };
|
|
|
|
export const SECTION_ACTIONS = [
|
|
'UPDATE_SECTION_SETTINGS',
|
|
'UPDATE_SECTION_STATE',
|
|
'UPDATE_SECTION_SINGLE_FIELD',
|
|
];
|
|
|
|
export const sectionReducer = (
|
|
state: ExamEditorStore,
|
|
action: SectionActions
|
|
): Partial<ExamEditorStore> => {
|
|
switch (action.type) {
|
|
case 'UPDATE_SECTION_SINGLE_FIELD':{
|
|
const { module, field, value, sectionId } = action.payload;
|
|
return {
|
|
modules: {
|
|
...state.modules,
|
|
[module]: {
|
|
...state.modules[module],
|
|
sections: state.modules[module].sections.map((section: SectionState) =>
|
|
section.sectionId === sectionId
|
|
? {
|
|
...section,
|
|
[field]: value
|
|
}
|
|
: section
|
|
)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
case 'UPDATE_SECTION_SETTINGS':{
|
|
const {module, sectionId, update} = action.payload;
|
|
return {
|
|
modules: {
|
|
...state.modules,
|
|
[module]: {
|
|
...state.modules[module],
|
|
sections: state.modules[module].sections.map((section: SectionState) =>
|
|
section.sectionId === sectionId
|
|
? {
|
|
...section,
|
|
settings: {
|
|
...section.settings,
|
|
...update
|
|
}
|
|
}
|
|
: section
|
|
)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
case 'UPDATE_SECTION_STATE': {
|
|
const { update, module, sectionId }= action.payload;
|
|
return {
|
|
modules: {
|
|
...state.modules,
|
|
[module]: {
|
|
...state.modules[module],
|
|
sections: state.modules[module].sections.map(section =>
|
|
section.sectionId === sectionId
|
|
? { ...section, state: { ...section.state, ...update } }
|
|
: section
|
|
)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
case 'REORDER_EXERCISES': {
|
|
const { event, sectionId, module } = action.payload;
|
|
const {over, active} = event;
|
|
if (!over) return state;
|
|
|
|
const oldIndex = active.id as number;
|
|
const newIndex = over.id as number;
|
|
|
|
const currentSectionState = state.modules[module].sections.find((s) => s.sectionId === sectionId)!.state as ReadingPart | ListeningPart | LevelPart;
|
|
const exercises = [...currentSectionState.exercises];
|
|
const [removed] = exercises.splice(oldIndex, 1);
|
|
exercises.splice(newIndex, 0, removed);
|
|
|
|
const { exercises: reorderedExercises } = reorderSection(exercises, 1);
|
|
|
|
const newSectionState = {
|
|
...currentSectionState,
|
|
exercises: reorderedExercises
|
|
};
|
|
|
|
return {
|
|
...state,
|
|
modules: {
|
|
...state.modules,
|
|
[module]: {
|
|
...state.modules[module],
|
|
sections: state.modules[module].sections.map(section =>
|
|
section.sectionId === sectionId
|
|
? { ...section, state: newSectionState }
|
|
: section
|
|
)
|
|
}
|
|
}
|
|
};
|
|
}
|
|
default:
|
|
return {};
|
|
}
|
|
}; |