backend_adaptive_learning/controllers/contentControllers/level.js
2024-12-02 14:27:15 +07:00

1042 lines
26 KiB
JavaScript

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({
where: {
IS_DELETED: 0,
},
attributes: {
exclude: [
"ROUTE_1",
"ROUTE_2",
"ROUTE_3",
"ROUTE_4",
"ROUTE_5",
"ROUTE_6",
],
},
});
response(200, levels, "Success", res);
} catch (error) {
console.log(error);
response(500, null, "Error retrieving levels data!", res);
}
};
export const getLevelById = async (req, res) => {
try {
const { id } = req.params;
const level = await models.Level.findByPk(id, {
where: {
IS_DELETED: 0,
},
attributes: {
exclude: [
"ROUTE_1",
"ROUTE_2",
"ROUTE_3",
"ROUTE_4",
"ROUTE_5",
"ROUTE_6",
],
},
include: [
{
model: models.Topic,
as: "levelTopic",
attributes: ["NAME_TOPIC"],
include: {
model: models.Section,
as: "topicSection",
attributes: ["NAME_SECTION"],
},
},
],
});
if (!level) {
return response(404, null, "Level not found", res);
}
const levelJSON = level.toJSON();
const NAME_SECTION = levelJSON.levelTopic.topicSection.NAME_SECTION;
const NAME_TOPIC = levelJSON.levelTopic.NAME_TOPIC;
delete levelJSON.levelTopic;
delete levelJSON.levelTopic?.topicSection;
const responsePayload = {
NAME_SECTION,
NAME_TOPIC,
...levelJSON,
};
response(200, responsePayload, "Success", res);
} catch (error) {
console.log(error);
response(500, null, "Internal Server Error", res);
}
};
export const getLevelForAdmin = async (req, res) => {
const { page = 1, limit = 10, search = "", sort = "time" } = req.query;
try {
const { count, rows: levels } = await models.Level.findAndCountAll({
where: {
IS_DELETED: 0,
...(search && {
[models.Op.or]: [
{
"$levelTopic->topicSection.NAME_SECTION$": {
[models.Op.like]: `%${search}%`,
},
},
{
"$levelTopic.NAME_TOPIC$": {
[models.Op.like]: `%${search}%`,
},
},
{
NAME_LEVEL: { [models.Op.like]: `%${search}%` },
},
],
}),
},
attributes: ["ID_LEVEL", "NAME_LEVEL", "TIME_LEVEL"],
include: [
{
model: models.Topic,
as: "levelTopic",
attributes: ["ID_TOPIC", "NAME_TOPIC"],
include: [
{
model: models.Section,
as: "topicSection",
attributes: ["ID_SECTION", "NAME_SECTION"],
},
],
},
],
distinct: true,
});
const formattedLevels = levels.map((level) => ({
ID_LEVEL: level.ID_LEVEL,
ID_SECTION: level.levelTopic.topicSection.ID_SECTION,
ID_TOPIC: level.levelTopic.ID_TOPIC,
NAME_SECTION: level.levelTopic.topicSection.NAME_SECTION,
NAME_TOPIC: level.levelTopic.NAME_TOPIC,
NAME_LEVEL: level.NAME_LEVEL,
TIME_LEVEL: level.TIME_LEVEL,
}));
if (sort === "section") {
formattedLevels.sort((a, b) =>
a.NAME_SECTION.localeCompare(b.NAME_SECTION)
);
} else if (sort === "topic") {
formattedLevels.sort((a, b) => {
const topicComparison = a.NAME_TOPIC.localeCompare(b.NAME_TOPIC);
if (topicComparison === 0) {
if (a.NAME_LEVEL === "Pretest") return -1;
if (b.NAME_LEVEL === "Pretest") return 1;
const levelA = parseInt(a.NAME_LEVEL.replace("Level ", "")) || 0;
const levelB = parseInt(b.NAME_LEVEL.replace("Level ", "")) || 0;
return levelA - levelB;
}
return topicComparison;
});
} else if (sort === "level") {
formattedLevels.sort((a, b) => {
if (a.NAME_LEVEL === "Pretest") return -1;
if (b.NAME_LEVEL === "Pretest") return 1;
const levelA = parseInt(a.NAME_LEVEL.replace("Level ", "")) || 0;
const levelB = parseInt(b.NAME_LEVEL.replace("Level ", "")) || 0;
return levelA - levelB;
});
} else {
formattedLevels.sort(
(a, b) => new Date(b.TIME_LEVEL) - new Date(a.TIME_LEVEL)
);
}
const paginatedLevels = formattedLevels.slice(
(page - 1) * limit,
page * limit
);
const totalPages = Math.ceil(count / limit);
const currentPage = parseInt(page);
response(
200,
{
levels: paginatedLevels,
currentPage,
totalPages,
totalItems: count,
},
"Levels retrieved successfully",
res
);
} catch (error) {
console.log(error);
response(500, null, "Error retrieving levels data!", res);
}
};
export const getLevelsByTopicId = async (req, res) => {
try {
const { idTopic } = req.params;
const { ID } = req.user;
const topicExists = await models.Topic.findByPk(idTopic, {
include: {
model: models.Section,
as: "topicSection",
attributes: ["NAME_SECTION"],
},
});
if (!topicExists) {
return res.status(404).json({ message: "Topic not found" });
}
const levels = await models.Level.findAll({
where: {
ID_TOPIC: idTopic,
IS_DELETED: 0,
},
attributes: {
exclude: [
"ROUTE_1",
"ROUTE_2",
"ROUTE_3",
"ROUTE_4",
"ROUTE_5",
"ROUTE_6",
],
},
include: [
{
model: models.StdLearning,
as: "stdLearning",
attributes: [
"SCORE",
"ID_STUDENT_LEARNING",
"STUDENT_START",
"STUDENT_FINISH",
"NEXT_LEARNING",
],
where: {
ID: ID,
},
required: false,
order: [["STUDENT_START", "DESC"]],
limit: 1,
},
{
model: models.Topic,
as: "levelTopic",
attributes: ["NAME_TOPIC"],
include: {
model: models.Section,
as: "topicSection",
attributes: ["NAME_SECTION"],
},
},
],
});
if (!levels || levels.length === 0) {
return res
.status(200)
.json({ message: "No levels found for the given topic." });
}
const lastCompletedLearning = await models.StdLearning.findOne({
where: {
ID: ID,
STUDENT_FINISH: { [models.Op.not]: null },
},
include: [
{
model: models.Level,
as: "level",
attributes: ["ID_LEVEL", "NAME_LEVEL"],
where: {
ID_TOPIC: idTopic,
IS_DELETED: 0,
},
},
],
order: [["STUDENT_FINISH", "DESC"]],
});
let currentLearningLevel = null;
if (lastCompletedLearning?.NEXT_LEARNING) {
currentLearningLevel = await models.Level.findOne({
where: {
ID_LEVEL: lastCompletedLearning.NEXT_LEARNING,
IS_DELETED: 0,
},
attributes: ["ID_LEVEL", "NAME_LEVEL"],
});
}
const nextLearningLevel = currentLearningLevel;
const unlockedLevels = lastCompletedLearning
? await models.Level.findAll({
where: {
ID_TOPIC: idTopic,
IS_DELETED: 0,
[models.Op.or]: [
{ NAME_LEVEL: { [models.Op.lt]: nextLearningLevel?.NAME_LEVEL } },
{ NAME_LEVEL: "Pretest" },
],
},
attributes: ["NAME_LEVEL"],
order: [["NAME_LEVEL", "ASC"]],
})
: [{ NAME_LEVEL: "Pretest" }];
const unlockedLevelNames = unlockedLevels.map((lvl) => lvl.NAME_LEVEL);
if (
nextLearningLevel &&
!unlockedLevelNames.includes(nextLearningLevel.NAME_LEVEL)
) {
unlockedLevelNames.push(nextLearningLevel.NAME_LEVEL);
}
const levelsWithScore = levels.map((level) => {
const SCORE =
level.stdLearning && level.stdLearning.length > 0
? level.stdLearning[0]?.SCORE
: null;
const ID_STUDENT_LEARNING =
level.stdLearning && level.stdLearning.length > 0
? level.stdLearning[0]?.ID_STUDENT_LEARNING
: null;
const levelJSON = level.toJSON();
const NAME_SECTION = levelJSON.levelTopic.topicSection.NAME_SECTION;
const NAME_TOPIC = levelJSON.levelTopic.NAME_TOPIC;
delete levelJSON.stdLearning;
delete levelJSON.levelTopic;
delete levelJSON.levelTopic?.topicSection;
const isUnlocked = unlockedLevelNames.includes(levelJSON.NAME_LEVEL);
if (isUnlocked) {
return {
NAME_SECTION,
NAME_TOPIC,
...levelJSON,
ID_STUDENT_LEARNING,
SCORE,
IS_PRETEST: levelJSON.NAME_LEVEL === "Pretest" ? 1 : 0,
};
} else {
return {
ID_LEVEL: levelJSON.ID_LEVEL,
NAME_LEVEL: levelJSON.NAME_LEVEL,
IS_PRETEST: levelJSON.NAME_LEVEL === "Pretest" ? 1 : 0,
SCORE,
};
}
});
const sortedLevels = levelsWithScore.sort((a, b) => {
if (a.NAME_LEVEL === "Pretest") return -1;
if (b.NAME_LEVEL === "Pretest") return 1;
const levelA = parseInt(a.NAME_LEVEL.replace("Level ", ""));
const levelB = parseInt(b.NAME_LEVEL.replace("Level ", ""));
return levelA - levelB;
});
const responsePayload = {
lastCompletedLevel: lastCompletedLearning
? {
ID_STUDENT_LEARNING: lastCompletedLearning.ID_STUDENT_LEARNING,
ID_LEVEL: lastCompletedLearning.level.ID_LEVEL,
NAME_LEVEL: lastCompletedLearning.level.NAME_LEVEL,
SCORE: lastCompletedLearning.SCORE,
NEXT_LEARNING: lastCompletedLearning.NEXT_LEARNING,
NEXT_LEARNING_LEVEL: nextLearningLevel
? nextLearningLevel.NAME_LEVEL
: null,
FINISHED_AT: lastCompletedLearning.STUDENT_FINISH,
UNLOCKED_LEVELS: unlockedLevelNames,
}
: {
UNLOCKED_LEVELS: unlockedLevelNames,
},
levels: sortedLevels,
};
res.status(200).json({ message: "Success", data: responsePayload });
} catch (error) {
console.error(error);
res.status(500).json({ message: "Internal Server Error" });
}
};
export const createLevel = async (req, res, next) => {
const { NAME_LEVEL, ID_SECTION, ID_TOPIC, CONTENT, VIDEO } = req.body;
const { AUDIO, IMAGE } = req.filesToSave || {};
if (!NAME_LEVEL) {
clearFileBuffers({ AUDIO, IMAGE });
return response(400, null, "Level name is required", res);
}
if (!ID_SECTION) {
clearFileBuffers({ AUDIO, IMAGE });
return response(400, null, "Section is required", res);
}
if (!ID_TOPIC) {
clearFileBuffers({ AUDIO, IMAGE });
return response(400, null, "Topic is required", res);
}
const transaction = await models.db.transaction();
try {
const sectionWithTopic = await models.Topic.findOne({
where: { ID_SECTION, ID_TOPIC },
transaction,
});
if (!sectionWithTopic) {
clearFileBuffers({ AUDIO, IMAGE });
await transaction.rollback();
return response(
400,
null,
"Topic does not relate to the provided Section!",
res
);
}
const existingLevel = await models.Level.findOne({
where: {
NAME_LEVEL,
ID_TOPIC,
IS_DELETED: 0,
},
transaction,
});
if (existingLevel) {
clearFileBuffers({ AUDIO, IMAGE });
await transaction.rollback();
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: 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,
},
{ transaction }
);
req.body.newLevelId = newLevel.ID_LEVEL;
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.AUDIO = audioFilename;
newLevel.IMAGE = imageFilename;
await newLevel.save({ transaction });
await transaction.commit();
await updateOtherLevelsRoutes(req, res, next);
response(201, newLevel, "Level created successfully", res);
} catch (error) {
console.log(error);
clearFileBuffers({ AUDIO, IMAGE });
await transaction.rollback();
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, VIDEO } = req.body;
const { AUDIO, IMAGE } = req.filesToSave || {};
const transaction = await models.db.transaction();
try {
const level = await models.Level.findByPk(id, { transaction });
if (!level) {
clearFileBuffers({ AUDIO, IMAGE });
await transaction.rollback();
return response(404, null, "Level not found", res);
}
const sectionWithTopic = await models.Topic.findOne({
where: { ID_SECTION, ID_TOPIC },
transaction,
});
if (!sectionWithTopic) {
clearFileBuffers({ AUDIO, IMAGE });
await transaction.rollback();
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 },
IS_DELETED: 0,
},
transaction,
});
if (existingLevel) {
clearFileBuffers({ AUDIO, IMAGE });
await transaction.rollback();
return response(
409,
null,
"A level with this name already exists under this topic",
res
);
}
}
if (NAME_LEVEL) {
level.NAME_LEVEL = NAME_LEVEL;
level.IS_PRETEST = NAME_LEVEL === "Pretest" ? 1 : 0;
}
if (ID_SECTION) level.ID_SECTION = ID_SECTION;
if (ID_TOPIC) level.ID_TOPIC = ID_TOPIC;
if (CONTENT) level.CONTENT = CONTENT;
if (VIDEO) level.VIDEO = VIDEO;
if (AUDIO) {
if (level.AUDIO) {
const oldAudioPath = path.join(
process.cwd(),
"media/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(
process.cwd(),
"media/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({ transaction });
await transaction.commit();
await updateOtherLevelsRoutes(req, res, next);
response(200, level, "Level updated successfully", res);
} catch (error) {
console.log(error);
clearFileBuffers({ AUDIO, IMAGE });
await transaction.rollback();
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);
}
level.IS_DELETED = 1;
await level.save();
await models.Exercise.update(
{ IS_DELETED: 1 },
{ where: { ID_LEVEL: id } }
);
req.body.newLevelId = level.ID_LEVEL;
await updateOtherLevelsRoutesOnDelete(req, res, next);
response(
200,
null,
"Level and related exercises soft deleted successfully",
res
);
} catch (error) {
console.log(error);
return response(500, null, "Internal Server Error", res);
}
};
export const deleteLevelFileById = async (req, res) => {
const { id } = req.params;
const { fileType } = req.body;
if (!["audio", "image", "video"].includes(fileType)) {
return response(400, null, "Invalid file type specified", res);
}
try {
const level = await models.Level.findByPk(id);
if (!level) {
return response(404, null, "Level not found", res);
}
let filePath;
let fileName;
if (fileType === "audio" && level.AUDIO) {
fileName = level.AUDIO;
filePath = path.join(
process.cwd(),
"media/uploads/level/audio",
fileName
);
level.AUDIO = null;
} else if (fileType === "image" && level.IMAGE) {
fileName = level.IMAGE;
filePath = path.join(
process.cwd(),
"media/uploads/level/image",
fileName
);
level.IMAGE = null;
} else if (fileType === "video" && level.VIDEO) {
level.VIDEO = null;
} else {
return response(
404,
null,
`${
fileType.charAt(0).toUpperCase() + fileType.slice(1)
} file not found`,
res
);
}
if (filePath && fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
}
await level.save();
response(
200,
level,
`${
fileType.charAt(0).toUpperCase() + fileType.slice(1)
} file deleted successfully`,
res
);
} catch (error) {
console.log(error);
response(500, null, "Internal Server Error", res);
}
};
export const deleteLevelFilesById = async (req, res) => {
const { id } = req.params;
const { fileName } = req.body;
const filePattern =
/^(AUDIO|IMAGE)-([a-f0-9-]{36})-[a-f0-9]{32}\.(mp3|jpg|jpeg|png)$/;
const match = fileName.match(filePattern);
if (!match) {
return response(400, null, "Invalid file name format", res);
}
const fileType = match[1];
const levelIdFromFile = match[2];
if (levelIdFromFile !== id) {
return response(400, null, "Level ID in file name does not match", res);
}
try {
const level = await models.Level.findByPk(id);
if (!level) {
return response(404, null, "Level not found", res);
}
let filePath;
if (fileType === "AUDIO") {
filePath = path.join(
process.cwd(),
"media/uploads/level/audio",
fileName
);
} else if (fileType === "IMAGE") {
filePath = path.join(
process.cwd(),
"media/uploads/level/image",
fileName
);
} else {
return response(400, null, "Invalid file type", res);
}
if (filePath && fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
return response(200, null, `${fileType} file deleted successfully`, res);
} else {
return response(404, null, "File not found on the server", res);
}
} catch (error) {
console.log(error);
response(500, null, "Internal Server Error", res);
}
};
export const getPreviousLevel = async (req, res) => {
try {
const { next_learning } = req.params;
const { ID } = req.user;
const currentLevel = await models.Level.findByPk(next_learning, {
where: {
IS_DELETED: 0,
},
include: [
{
model: models.StdLearning,
as: "stdLearning",
attributes: [
"SCORE",
"ID_STUDENT_LEARNING",
"STUDENT_START",
"STUDENT_FINISH",
],
where: {
ID: ID,
},
required: false,
order: [["STUDENT_FINISH", "DESC"]],
limit: 1,
},
],
attributes: {
exclude: [
"ROUTE_1",
"ROUTE_2",
"ROUTE_3",
"ROUTE_4",
"ROUTE_5",
"ROUTE_6",
],
},
});
if (!currentLevel) {
return res.status(404).json({ message: "Level not found" });
}
const { NAME_LEVEL, ID_TOPIC } = currentLevel;
const levelNumber = parseInt(NAME_LEVEL.replace("Level ", ""));
if (isNaN(levelNumber)) {
return res.status(400).json({ message: "Invalid level format" });
}
const previousLevels = await models.Level.findAll({
where: {
ID_TOPIC: ID_TOPIC,
IS_DELETED: 0,
NAME_LEVEL: {
[models.Op.or]: [
{ [models.Op.like]: "Pretest" },
{ [models.Op.regexp]: `^Level [0-9]+$` },
],
},
[models.Op.or]: [
{ IS_PRETEST: 1 },
{
NAME_LEVEL: {
[models.Op.lt]: `Level ${levelNumber}`,
},
},
],
},
attributes: {
exclude: [
"ROUTE_1",
"ROUTE_2",
"ROUTE_3",
"ROUTE_4",
"ROUTE_5",
"ROUTE_6",
],
},
include: [
{
model: models.StdLearning,
as: "stdLearning",
attributes: [
"SCORE",
"ID_STUDENT_LEARNING",
"STUDENT_START",
"STUDENT_FINISH",
],
where: {
ID: ID,
},
required: false,
order: [["STUDENT_START", "DESC"]],
limit: 1,
},
],
});
const previousLevelsWithScore = previousLevels.map((level) => {
const SCORE =
level.stdLearning && level.stdLearning.length > 0
? level.stdLearning[0]?.SCORE
: null;
const ID_STUDENT_LEARNING =
level.stdLearning && level.stdLearning.length > 0
? level.stdLearning[0]?.ID_STUDENT_LEARNING
: null;
const levelJSON = level.toJSON();
delete levelJSON.stdLearning;
return {
...levelJSON,
ID_STUDENT_LEARNING,
SCORE,
};
});
const currentLevelWithScore = {
...currentLevel.toJSON(),
ID_STUDENT_LEARNING:
currentLevel.stdLearning && currentLevel.stdLearning.length > 0
? currentLevel.stdLearning[0]?.ID_STUDENT_LEARNING
: null,
SCORE:
currentLevel.stdLearning && currentLevel.stdLearning.length > 0
? currentLevel.stdLearning[0]?.SCORE
: null,
};
delete currentLevelWithScore.stdLearning;
const sortedLevels = previousLevelsWithScore.sort((a, b) => {
if (a.NAME_LEVEL === "Pretest") return -1;
if (b.NAME_LEVEL === "Pretest") return 1;
const levelA = parseInt(a.NAME_LEVEL.replace("Level ", ""));
const levelB = parseInt(b.NAME_LEVEL.replace("Level ", ""));
return levelA - levelB;
});
if (!sortedLevels.length && !currentLevelWithScore) {
return res.status(404).json({ message: "No levels found" });
}
const result = {
currentLevel: currentLevelWithScore,
previousLevels: sortedLevels,
};
res.status(200).json({ message: "Success", data: result });
} catch (error) {
console.error(error);
res.status(500).json({ message: "Internal Server Error" });
}
};
export const uploadLevelFile = async (req, res) => {
const { levelId } = req.params;
try {
const level = await models.Level.findByPk(levelId);
if (!level) {
return response(404, null, "Level not found", res);
}
const filesToSave = req.filesToSave;
if (!filesToSave || Object.keys(filesToSave).length === 0) {
return response(400, null, "No files to upload", res);
}
const { ID_TOPIC, ID_SECTION } = level;
const savedFiles = {};
Object.keys(filesToSave).forEach((key) => {
let filename;
if (key.startsWith("AUDIO")) {
const audioFile = filesToSave[key];
filename = saveFileToDisk(
audioFile,
"AUDIO",
ID_TOPIC,
ID_SECTION,
levelId
);
} else if (key.startsWith("IMAGE")) {
const imageFile = filesToSave[key];
filename = saveFileToDisk(
imageFile,
"IMAGE",
ID_TOPIC,
ID_SECTION,
levelId
);
}
if (filename) {
savedFiles[key] = filename;
}
});
if (Object.keys(savedFiles).length === 0) {
return response(400, null, "Failed to save files", res);
}
return response(200, savedFiles, "Files uploaded successfully", res);
} catch (error) {
console.error(error);
return response(500, null, "Internal server error", res);
}
};
export const getLevelFiles = async (req, res) => {
const { levelId } = req.params;
try {
const audioFolderPath = path.join(
process.cwd(),
"media/uploads/level/audio"
);
const imageFolderPath = path.join(
process.cwd(),
"media/uploads/level/image"
);
const getFilesByLevelId = (folderPath, fileType) => {
if (fs.existsSync(folderPath)) {
const files = fs.readdirSync(folderPath);
return files.filter((file) =>
file.startsWith(`${fileType}-${levelId}`)
);
}
return [];
};
const audioFiles = getFilesByLevelId(audioFolderPath, "AUDIO");
const imageFiles = getFilesByLevelId(imageFolderPath, "IMAGE");
if (audioFiles.length === 0 && imageFiles.length === 0) {
return response(200, null, "No files found for this level", res);
}
const levelFiles = {
audioFiles,
imageFiles,
};
return response(200, levelFiles, "Files retrieved successfully", res);
} catch (error) {
console.error(error);
return response(500, null, "Internal server error", res);
}
};