diff --git a/controllers/contentControllers/level.js b/controllers/contentControllers/level.js index 37e2367..80923b5 100644 --- a/controllers/contentControllers/level.js +++ b/controllers/contentControllers/level.js @@ -103,6 +103,23 @@ export const getLevelsByTopicId = async (req, res) => { .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"], + }, + ], + order: [["STUDENT_FINISH", "DESC"]], + }); + const levelsWithScore = levels.map((level) => { const SCORE = level.stdLearning.length > 0 ? level.stdLearning[0].SCORE : 0; @@ -121,7 +138,29 @@ export const getLevelsByTopicId = async (req, res) => { }; }); - res.status(200).json({ message: "Success", data: levelsWithScore }); + 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, + FINISHED_AT: lastCompletedLearning.STUDENT_FINISH, + } + : null, + levels: sortedLevels, + }; + + res.status(200).json({ message: "Success", data: responsePayload }); } catch (error) { console.log(error); res.status(500).json({ message: "Internal Server Error" }); diff --git a/controllers/learningControllers/stdLearning.js b/controllers/learningControllers/stdLearning.js index 431317a..6c8603d 100644 --- a/controllers/learningControllers/stdLearning.js +++ b/controllers/learningControllers/stdLearning.js @@ -154,6 +154,71 @@ export const updateStdLearningById = async (req, res) => { } }; +export const learningScoreByStdLearningId = async (req, res) => { + try { + if (!req.user) { + return response(401, null, "User not authenticated", res); + } + + const { ID } = req.user; + const { stdLearningId } = req.params; + + const stdLearning = await models.StdLearning.findOne({ + where: { + ID_STUDENT_LEARNING: stdLearningId, + ID: ID, + }, + include: [ + { + model: models.Level, + as: "nextLevel", + }, + { + model: models.User, + as: "learningUser", + attributes: ["NAME_USERS"], + include: [ + { + model: models.Student, + as: "students", + attributes: ["NISN"], + } + ] + }, + ], + }); + + if (!stdLearning) { + return response( + 404, + null, + "No matching learning data found for this user", + res + ); + } + + if (!stdLearning.NEXT_LEARNING || !stdLearning.nextLevel) { + return response(200, null, "No next learning level found", res); + } + + const nextLearningData = { + ID_STUDENT_LEARNING: stdLearning.ID_STUDENT_LEARNING, + NAME_USERS: stdLearning.learningUser.NAME_USERS, + NISN: stdLearning.learningUser.students + ? stdLearning.learningUser.students.NISN + : null, + SCORE: stdLearning.SCORE, + NEXT_LEARNING: stdLearning.NEXT_LEARNING, + NEXT_LEARNING_NAME: stdLearning.nextLevel.NAME_LEVEL, + }; + + return response(200, nextLearningData, "Success", res); + } catch (error) { + console.log(error); + return response(500, null, "Internal Server Error", res); + } +}; + export const learningHistory = async (req, res) => { try { if (!req.user) { diff --git a/middlewares/User/authUser.js b/middlewares/User/authUser.js index edcc1e5..698eaa6 100644 --- a/middlewares/User/authUser.js +++ b/middlewares/User/authUser.js @@ -28,7 +28,9 @@ export const verifyLoginUser = async (req, res, next) => { next(); } catch (error) { - if (error.name === "JsonWebTokenError") { + if (error.name === "TokenExpiredError") { + return response(401, null, "Session expired. Please log in again.", res); + } else if (error.name === "JsonWebTokenError") { return response(403, null, "Invalid token!", res); } else { return response(500, null, "An error occurred on the server!", res); diff --git a/public/uploads/avatar/user-ca6e061f610f0c6c1d2700fd845a2f61.jpg b/public/uploads/avatar/user-ca6e061f610f0c6c1d2700fd845a2f61.jpg new file mode 100644 index 0000000..408e510 Binary files /dev/null and b/public/uploads/avatar/user-ca6e061f610f0c6c1d2700fd845a2f61.jpg differ diff --git a/routes/learning/stdLearning.js b/routes/learning/stdLearning.js index 201bb53..aaf7784 100644 --- a/routes/learning/stdLearning.js +++ b/routes/learning/stdLearning.js @@ -1,5 +1,5 @@ import express from "express"; -import { getStdLearnings, getStdLearningById, createStdLearning, learningHistory, learningHistoryBySectionId, learningHistoryByTopicId } from "../../controllers/learningControllers/stdLearning.js"; +import { getStdLearnings, getStdLearningById, createStdLearning, learningScoreByStdLearningId, learningHistory, learningHistoryBySectionId, learningHistoryByTopicId } from "../../controllers/learningControllers/stdLearning.js"; import { verifyLoginUser } from "../../middlewares/User/authUser.js"; const router = express.Router(); @@ -8,6 +8,8 @@ router.get("/stdLearning", verifyLoginUser, getStdLearnings); router.get("/stdLearning/:id", verifyLoginUser, getStdLearningById); +router.get("/stdLearning/score/:stdLearningId", verifyLoginUser, learningScoreByStdLearningId); + router.get("/learningHistory", verifyLoginUser, learningHistory); router.get("/learningHistory/section/:sectionId", verifyLoginUser, learningHistoryBySectionId);