import response from "../../response.js"; import models from "../../models/index.js"; import { clearFileBuffers, saveFileToDisk, } from "../../middlewares/Level/uploadLevel.js"; import fs from "fs"; import path from "path"; import { updateOtherLevelsRoutes, updateOtherLevelsRoutesOnDelete, } from "../../middlewares/Level/checkLevel.js"; export const getLevels = async (req, res) => { try { const levels = await models.Level.findAll({ attributes: { exclude: [ "ROUTE_1", "ROUTE_2", "ROUTE_3", "ROUTE_4", "ROUTE_5", "ROUTE_6", ], }, }); response(200, levels, "Success", res); } catch (error) { console.log(error); res.status(500).json({ message: "Internal Server Error" }); } }; export const getLevelById = async (req, res) => { try { const { id } = req.params; const level = await models.Level.findByPk(id, { attributes: { exclude: [ "ROUTE_1", "ROUTE_2", "ROUTE_3", "ROUTE_4", "ROUTE_5", "ROUTE_6", ], }, }); if (!level) { return response(404, null, "Level not found", res); } response(200, level, "Success", res); } catch (error) { console.log(error); res.status(500).json({ message: "Internal Server Error" }); } }; export const createLevel = async (req, res, next) => { const { NAME_LEVEL, ID_SECTION, ID_TOPIC, CONTENT } = req.body; const { video, image, audio } = req.filesToSave || {}; if (!NAME_LEVEL) { clearFileBuffers({ video, image, audio }); return response(400, null, "Level name is required", res); } if (!ID_SECTION) { clearFileBuffers({ video, image, audio }); return response(400, null, "Section is required", res); } if (!ID_TOPIC) { clearFileBuffers({ video, image, audio }); return response(400, null, "Topic is required", res); } try { const sectionWithTopic = await models.Topic.findOne({ where: { ID_SECTION, ID_TOPIC }, }); if (!sectionWithTopic) { clearFileBuffers({ video, image, audio }); return response( 400, null, "Topic does not relate to the provided Section!", res ); } const existingLevel = await models.Level.findOne({ where: { NAME_LEVEL, ID_TOPIC }, }); if (existingLevel) { clearFileBuffers({ video, image, audio }); return response( 409, null, "A level with this name already exists under this topic", res ); } const newLevel = await models.Level.create({ NAME_LEVEL, ID_SECTION, ID_TOPIC, IS_PRETEST: req.body.IS_PRETEST || 0, CONTENT, VIDEO: null, AUDIO: null, IMAGE: null, ROUTE_1: req.body.ROUTE_1, ROUTE_2: req.body.ROUTE_2, ROUTE_3: req.body.ROUTE_3, ROUTE_4: req.body.ROUTE_4, ROUTE_5: req.body.ROUTE_5, ROUTE_6: req.body.ROUTE_6, }); req.body.newLevelId = newLevel.ID_LEVEL; const videoFilename = video ? saveFileToDisk(video, "video", ID_TOPIC, ID_SECTION, newLevel.ID_LEVEL) : null; const audioFilename = audio ? saveFileToDisk(audio, "audio", ID_TOPIC, ID_SECTION, newLevel.ID_LEVEL) : null; const imageFilename = image ? saveFileToDisk(image, "image", ID_TOPIC, ID_SECTION, newLevel.ID_LEVEL) : null; newLevel.VIDEO = videoFilename; newLevel.AUDIO = audioFilename; newLevel.IMAGE = imageFilename; await newLevel.save(); await updateOtherLevelsRoutes(req, res, next); response(201, newLevel, "Level created successfully", res); } catch (error) { console.log(error); clearFileBuffers({ video, image, audio }); return response(500, null, "Internal Server Error", res); } }; export const updateLevelById = async (req, res, next) => { const { id } = req.params; const { NAME_LEVEL, ID_SECTION, ID_TOPIC, CONTENT } = req.body; const { video, image, audio } = req.filesToSave || {}; try { const level = await models.Level.findByPk(id); if (!level) { clearFileBuffers({ video, image, audio }); return response(404, null, "Level not found", res); } const sectionWithTopic = await models.Topic.findOne({ where: { ID_SECTION, ID_TOPIC }, }); if (!sectionWithTopic) { clearFileBuffers({ video, image, audio }); return response( 400, null, "Topic does not relate to the provided Section", res ); } if (NAME_LEVEL && ID_TOPIC) { const existingLevel = await models.Level.findOne({ where: { NAME_LEVEL, ID_TOPIC, ID_LEVEL: { [models.Sequelize.Op.ne]: id }, }, }); if (existingLevel) { clearFileBuffers({ video, image, audio }); return response( 409, null, "A level with this name already exists under this topic", res ); } } if (NAME_LEVEL) { level.NAME_LEVEL = NAME_LEVEL; if (NAME_LEVEL === "Level 1") { level.IS_PRETEST = 1; } else { level.IS_PRETEST = 0; } } if (ID_SECTION) level.ID_SECTION = ID_SECTION; if (ID_TOPIC) level.ID_TOPIC = ID_TOPIC; if (CONTENT) level.CONTENT = CONTENT; if (video) { if (level.VIDEO) { const oldVideoPath = path.join( "public/uploads/level/video", level.VIDEO ); if (fs.existsSync(oldVideoPath)) { fs.unlinkSync(oldVideoPath); } } level.VIDEO = saveFileToDisk( video, "video", ID_TOPIC || level.ID_TOPIC, ID_SECTION || level.ID_SECTION, level.ID_LEVEL ); } if (audio) { if (level.AUDIO) { const oldAudioPath = path.join( "public/uploads/level/audio", level.AUDIO ); if (fs.existsSync(oldAudioPath)) { fs.unlinkSync(oldAudioPath); } } level.AUDIO = saveFileToDisk( audio, "audio", ID_TOPIC || level.ID_TOPIC, ID_SECTION || level.ID_SECTION, level.ID_LEVEL ); } if (image) { if (level.IMAGE) { const oldImagePath = path.join( "public/uploads/level/image", level.IMAGE ); if (fs.existsSync(oldImagePath)) { fs.unlinkSync(oldImagePath); } } level.IMAGE = saveFileToDisk( image, "image", ID_TOPIC || level.ID_TOPIC, ID_SECTION || level.ID_SECTION, level.ID_LEVEL ); } await level.save(); req.body.newLevelId = level.ID_LEVEL; await updateOtherLevelsRoutes(req, res, next); response(200, level, "Level updated successfully", res); } catch (error) { console.log(error); clearFileBuffers({ video, image, audio }); return response(500, null, "Internal Server Error", res); } }; export const deleteLevelById = async (req, res, next) => { const { id } = req.params; try { const level = await models.Level.findByPk(id); if (!level) { return response(404, null, "Level not found", res); } const deleteFile = (filePath) => { if (fs.existsSync(filePath)) { fs.unlinkSync(filePath); } }; if (level.VIDEO) { const videoPath = path.join("public/uploads/level/video", level.VIDEO); deleteFile(videoPath); } if (level.AUDIO) { const audioPath = path.join("public/uploads/level/audio", level.AUDIO); deleteFile(audioPath); } if (level.IMAGE) { const imagePath = path.join("public/uploads/level/image", level.IMAGE); deleteFile(imagePath); } req.body.newLevelId = level.ID_LEVEL; await level.destroy(); await updateOtherLevelsRoutesOnDelete(req, res, next); response(200, null, "Level deleted successfully", res); } catch (error) { console.log(error); return response(500, null, "Internal Server Error", res); } }; export const unlockPreviousRoutes = async (req, res) => { const { NEXT_LEARNING } = req.params; };