import { FillBlanksExercise, LevelPart, ListeningPart, MatchSentencesExercise, MultipleChoiceExercise, ReadingPart, TrueFalseExercise, WriteBlanksExercise } from "@/interfaces/exam"; import { ModuleState } from "../types"; import ReorderResult from "./types"; const reorderFillBlanks = (exercise: FillBlanksExercise, startId: number): ReorderResult => { const newSolutions = exercise.solutions .sort((a, b) => parseInt(a.id) - parseInt(b.id)) .map((solution, index) => ({ ...solution, id: (startId + index).toString() })); const idMapping = exercise.solutions .sort((a, b) => parseInt(a.id) - parseInt(b.id)) .reduce((acc, solution, index) => { acc[solution.id] = (startId + index).toString(); return acc; }, {} as Record); let newText = exercise.text; Object.entries(idMapping).forEach(([oldId, newId]) => { const regex = new RegExp(`\\{\\{${oldId}\\}\\}`, 'g'); newText = newText.replace(regex, `{{${newId}}}`); }); const newWords = exercise.words.map(word => { if (typeof word === 'string') { return word; } else if ('letter' in word && 'word' in word) { return word; } else if ('options' in word) { return word; } return word; }); const newUserSolutions = exercise.userSolutions?.map(solution => ({ ...solution, id: idMapping[solution.id] || solution.id })); return { exercise: { ...exercise, solutions: newSolutions, text: newText, words: newWords, userSolutions: newUserSolutions }, lastId: startId + newSolutions.length - 1 }; }; const reorderWriteBlanks = (exercise: WriteBlanksExercise, startId: number): ReorderResult => { const newSolutions = exercise.solutions .sort((a, b) => parseInt(a.id) - parseInt(b.id)) .map((solution, index) => ({ ...solution, id: (startId + index).toString() })); return { exercise: { ...exercise, solutions: newSolutions, text: newSolutions.reduce((text, solution, index) => { return text.replace( new RegExp(`\\{\\{${solution.id}\\}\\}`), `{{${startId + index}}}` ); }, exercise.text) }, lastId: startId + newSolutions.length }; }; const reorderTrueFalse = (exercise: TrueFalseExercise, startId: number): ReorderResult => { const newQuestions = exercise.questions .sort((a, b) => parseInt(a.id) - parseInt(b.id)) .map((question, index) => ({ ...question, id: (startId + index).toString() })); return { exercise: { ...exercise, questions: newQuestions }, lastId: startId + newQuestions.length }; }; const reorderMatchSentences = (exercise: MatchSentencesExercise, startId: number): ReorderResult => { const newSentences = exercise.sentences .sort((a, b) => parseInt(a.id) - parseInt(b.id)) .map((sentence, index) => ({ ...sentence, id: (startId + index).toString() })); return { exercise: { ...exercise, sentences: newSentences }, lastId: startId + newSentences.length }; }; const reorderMultipleChoice = (exercise: MultipleChoiceExercise, startId: number): ReorderResult => { const newQuestions = exercise.questions .sort((a, b) => parseInt(a.id) - parseInt(b.id)) .map((question, index) => ({ ...question, id: (startId + index).toString() })); return { exercise: { ...exercise, questions: newQuestions }, lastId: startId + newQuestions.length }; }; const reorderExercises = (moduleState: ModuleState) => { let currentId = 1; const reorderedSections = moduleState.sections.map(section => { const currentSection = section.state as ReadingPart | ListeningPart |LevelPart; const reorderedExercises = currentSection.exercises.map(exercise => { let result; switch (exercise.type) { case 'fillBlanks': result = reorderFillBlanks(exercise, currentId); currentId = result.lastId; return result.exercise; case 'writeBlanks': result = reorderWriteBlanks(exercise, currentId); currentId = result.lastId; return result.exercise; case 'trueFalse': result = reorderTrueFalse(exercise, currentId); currentId = result.lastId; return result.exercise; case 'matchSentences': result = reorderMatchSentences(exercise, currentId); currentId = result.lastId; return result.exercise; case 'multipleChoice': result = reorderMultipleChoice(exercise, currentId); currentId = result.lastId return result.exercise; default: return exercise; } }); return { ...section, state: { ...currentSection, exercises: reorderedExercises } }; }); return { ...moduleState, sections: reorderedSections }; }; export { reorderFillBlanks, reorderWriteBlanks, reorderTrueFalse, reorderMatchSentences, reorderExercises, reorderMultipleChoice, };