diff --git a/controllers/contentControllers/topic.js b/controllers/contentControllers/topic.js index 85a8c5b..9534000 100644 --- a/controllers/contentControllers/topic.js +++ b/controllers/contentControllers/topic.js @@ -215,10 +215,6 @@ export const getCompletedTopicsBySection = async (req, res) => { const result = Object.values(completedSections); - if (!result.length) { - return response(404, null, "No completed topics for Level 6 found", res); - } - response( 200, result, diff --git a/controllers/monitoringControllers/class.js b/controllers/monitoringControllers/class.js index 193df8e..8688872 100644 --- a/controllers/monitoringControllers/class.js +++ b/controllers/monitoringControllers/class.js @@ -234,3 +234,93 @@ export const updateStudentClassByName = async (req, res) => { response(500, null, "Internal Server Error", res); } }; + +export const getStudentsByClassId = async (req, res) => { + try { + const { classId } = req.params; + + const studentsInClass = await models.User.findAll({ + where: { + ROLE: "student", + }, + attributes: ["ID", "NAME_USERS", "EMAIL", "ROLE"], + include: [ + { + model: models.Student, + as: "students", + attributes: ["NISN", "ID_CLASS"], + include: [ + { + model: models.Class, + as: "studentClass", + attributes: ["NAME_CLASS"], + }, + ], + where: { + ID_CLASS: classId, + }, + }, + ], + raw: true, + nest: true, + }); + + const formattedStudents = studentsInClass.map((student) => ({ + ID: student.ID, + NAME_USERS: student.NAME_USERS, + EMAIL: student.EMAIL, + NISN: student.students.NISN, + NAME_CLASS: student.students.studentClass.NAME_CLASS, + ROLE: student.ROLE, + })); + + response(200, formattedStudents, "Success", res); + } catch (error) { + console.log(error); + response(500, null, "Error retrieving students by class ID", res); + } +}; + +export const getStudentsWithNoClass = async (req, res) => { + try { + const studentsWithoutClass = await models.User.findAll({ + where: { + ROLE: "student", + }, + attributes: ["ID", "NAME_USERS", "EMAIL", "ROLE"], + include: [ + { + model: models.Student, + as: "students", + attributes: ["NISN", "ID_CLASS"], + include: [ + { + model: models.Class, + as: "studentClass", + attributes: ["NAME_CLASS"], + }, + ], + where: { + ID_CLASS: null, + }, + }, + ], + raw: true, + nest: true, + }); + + const formattedStudents = studentsWithoutClass.map((student) => ({ + ID: student.ID, + NAME_USERS: student.NAME_USERS, + EMAIL: student.EMAIL, + NISN: student.students.NISN, + NAME_CLASS: student.students.studentClass.NAME_CLASS, + ROLE: student.ROLE, + })); + + response(200, formattedStudents, "Success", res); + } catch (error) { + console.log(error); + response(500, null, "Error retrieving students with no class", res); + } +}; diff --git a/controllers/monitoringControllers/monitoring.js b/controllers/monitoringControllers/monitoring.js index 2c319e9..007dc47 100644 --- a/controllers/monitoringControllers/monitoring.js +++ b/controllers/monitoringControllers/monitoring.js @@ -229,17 +229,21 @@ export const monitoringStudentProgressById = async (req, res) => { return response(404, null, "No student learning data found!", res); } - const { ID } = stdLearning; + const userID = stdLearning.ID; + const topicID = stdLearning.level.ID_TOPIC; const levels = await models.StdLearning.findAll({ where: { - ID, + ID: userID, }, include: [ { model: models.Level, as: "level", attributes: ["NAME_LEVEL", "ID_TOPIC"], + where: { + ID_TOPIC: topicID, + }, }, ], attributes: [ @@ -250,17 +254,36 @@ export const monitoringStudentProgressById = async (req, res) => { ], }); - const levelArray = levels.map((learning) => ({ - NAME_LEVEL: learning.level.NAME_LEVEL, - SCORE: learning.SCORE, - FEEDBACK_STUDENT: learning.FEEDBACK_STUDENT, - STUDENT_START: learning.STUDENT_START, - STUDENT_FINISH: learning.STUDENT_FINISH, - })); + if (levels.length === 0) { + return response( + 404, + null, + "No levels found for the given user and topic!", + res + ); + } + + const levelArray = levels + .map((learning) => ({ + NAME_LEVEL: learning.level.NAME_LEVEL, + SCORE: learning.SCORE, + FEEDBACK_STUDENT: learning.FEEDBACK_STUDENT, + STUDENT_START: learning.STUDENT_START, + STUDENT_FINISH: learning.STUDENT_FINISH, + })) + .sort((a, b) => { + if (a.NAME_LEVEL === "Pretest") return -1; + if (b.NAME_LEVEL === "Pretest") return 1; + + const levelNumberA = parseInt(a.NAME_LEVEL.replace("Level ", ""), 10); + const levelNumberB = parseInt(b.NAME_LEVEL.replace("Level ", ""), 10); + return levelNumberA - levelNumberB; + }); const result = { ID_MONITORING: monitoring.ID_MONITORING, levels: levelArray, + FEEDBACK_GURU: monitoring.FEEDBACK_GURU, }; response(200, result, "Success retrieving student progress!", res); @@ -345,3 +368,92 @@ export const monitoringFeedback = async (req, res) => { response(500, null, "Error updating teacher feedback!", res); } }; + +export const getMonitoringByTopicId = async (req, res) => { + const { topicId } = req.params; + + if (!req.user) { + return response(401, null, "User not authenticated", res); + } + + const { ID } = req.user; + + if (!ID) { + return response(401, null, "Unauthorized: User ID not provided", res); + } + + try { + const stdLearning = await models.StdLearning.findOne({ + where: { + ID: ID, + }, + include: [ + { + model: models.Level, + as: "level", + where: { ID_TOPIC: topicId }, + attributes: ["ID_LEVEL", "NAME_LEVEL"], + include: [ + { + model: models.Topic, + as: "levelTopic", + attributes: ["NAME_TOPIC"], + }, + ], + }, + ], + }); + + if (!stdLearning) { + return response( + 404, + null, + "Student learning data not found for this topic!", + res + ); + } + + const monitoringData = await models.Monitoring.findOne({ + where: { + ID_STUDENT_LEARNING: stdLearning.ID_STUDENT_LEARNING, + }, + include: [ + { + model: models.Teacher, + as: "monitoringTeacher", + attributes: ["ID_GURU"], + include: [ + { + model: models.User, + as: "teacherUser", + attributes: ["NAME_USERS"], + }, + ], + }, + ], + }); + + if (!monitoringData) { + return response( + 404, + null, + "Monitoring data not found for this learning record!", + res + ); + } + + const result = { + ID_MONITORING: monitoringData.ID_MONITORING, + NAME_TOPIC: stdLearning.level?.levelTopic?.NAME_TOPIC, + NAME_LEVEL: stdLearning.level?.NAME_LEVEL, + TEACHER_NAME: monitoringData.monitoringTeacher?.teacherUser?.NAME_USERS, + FEEDBACK_GURU: monitoringData.FEEDBACK_GURU, + TIME_MONITORING: monitoringData.TIME_MONITORING, + }; + + response(200, result, "Success retrieving monitoring data!", res); + } catch (error) { + console.error("Error in getMonitoringByTopicId:", error); + response(500, null, "Error retrieving monitoring data!", res); + } +}; diff --git a/controllers/usersControllers/user.js b/controllers/usersControllers/user.js index 01d52a1..bb2f3a6 100644 --- a/controllers/usersControllers/user.js +++ b/controllers/usersControllers/user.js @@ -133,50 +133,6 @@ export const getStudents = async (req, res) => { } }; -export const getStudentsWithNoClass = async (req, res) => { - try { - const studentsWithoutClass = await models.User.findAll({ - where: { - ROLE: "student", - }, - attributes: ["ID", "NAME_USERS", "EMAIL", "ROLE"], - include: [ - { - model: models.Student, - as: "students", - attributes: ["NISN", "ID_CLASS"], - include: [ - { - model: models.Class, - as: "studentClass", - attributes: ["NAME_CLASS"], - }, - ], - where: { - ID_CLASS: null, - }, - }, - ], - raw: true, - nest: true, - }); - - const formattedStudents = studentsWithoutClass.map((student) => ({ - ID: student.ID, - NAME_USERS: student.NAME_USERS, - EMAIL: student.EMAIL, - NISN: student.students.NISN, - NAME_CLASS: student.students.studentClass.NAME_CLASS, - ROLE: student.ROLE, - })); - - response(200, formattedStudents, "Success", res); - } catch (error) { - console.log(error); - response(500, null, "Error retrieving students with no class", res); - } -}; - export const getUserById = async (req, res) => { try { const { id } = req.params; diff --git a/routes/monitoring/class.js b/routes/monitoring/class.js index 51cb5a7..0b21032 100644 --- a/routes/monitoring/class.js +++ b/routes/monitoring/class.js @@ -1,6 +1,6 @@ import express from "express"; -import { getClasses, getClassById, createClass, updateClassById, deleteClassById, updateStudentClassByName } from "../../controllers/monitoringControllers/class.js"; -import { verifyLoginUser } from "../../middlewares/User/authUser.js"; +import { getClasses, getClassById, getStudentsByClassId, getStudentsWithNoClass, createClass, updateClassById, deleteClassById, updateStudentClassByName } from "../../controllers/monitoringControllers/class.js"; +import { verifyLoginUser, adminOrTeacherOnly } from "../../middlewares/User/authUser.js"; const router = express.Router(); @@ -8,9 +8,13 @@ router.get("/classes", verifyLoginUser, getClasses); router.get("/class/:id", verifyLoginUser, getClassById); +router.get("/class/student/unassigned", verifyLoginUser, adminOrTeacherOnly, getStudentsWithNoClass); + +router.get("/class/student/:classId", verifyLoginUser, adminOrTeacherOnly, getStudentsByClassId); + router.post("/class", verifyLoginUser, createClass); -router.put("/class/update/:id", verifyLoginUser, updateClassById); +router.put("/class/update/:classId", verifyLoginUser, updateClassById); router.delete("/class/delete/:id", verifyLoginUser, deleteClassById); diff --git a/routes/monitoring/monitoring.js b/routes/monitoring/monitoring.js index 03398d3..066f04f 100644 --- a/routes/monitoring/monitoring.js +++ b/routes/monitoring/monitoring.js @@ -1,11 +1,17 @@ import express from "express"; -import { monitoringStudentsProgress, monitoringStudentProgressById, monitoringFeedback } from "../../controllers/monitoringControllers/monitoring.js"; +import { getMonitorings, getMonitoringById,monitoringStudentsProgress, monitoringStudentProgressById, getMonitoringByTopicId, monitoringFeedback } from "../../controllers/monitoringControllers/monitoring.js"; import { verifyLoginUser, adminOrTeacherOnly } from "../../middlewares/User/authUser.js"; const router = express.Router(); +router.get("/monitoring", verifyLoginUser, getMonitorings); + router.get("/monitoring/progress", verifyLoginUser, adminOrTeacherOnly, monitoringStudentsProgress); +router.get("/monitoring/:id", verifyLoginUser, getMonitoringById); + +router.get("/monitoring/topic/:topicId", verifyLoginUser, getMonitoringByTopicId); + router.get("/monitoring/progress/:id", verifyLoginUser, adminOrTeacherOnly, monitoringStudentProgressById); router.post("/monitoring/feedback/:id", verifyLoginUser, adminOrTeacherOnly, monitoringFeedback); diff --git a/routes/user/user.js b/routes/user/user.js index 0ba3429..0f7c637 100644 --- a/routes/user/user.js +++ b/routes/user/user.js @@ -1,5 +1,5 @@ import express from "express"; -import { getUsers, getAdmins, getTeachers, getStudents, getStudentsWithNoClass, getUserById, getUserByName, updateUserById, updateUserPasswordById, deleteUserById, getMe } from "../../controllers/usersControllers/user.js"; +import { getUsers, getAdmins, getTeachers, getStudents, getUserById, getUserByName, updateUserById, updateUserPasswordById, deleteUserById, getMe } from "../../controllers/usersControllers/user.js"; import { verifyLoginUser, adminOnly, adminOrTeacherOnly } from "../../middlewares/User/authUser.js"; import handleUpload from "../../middlewares/User/uploadUser.js"; @@ -14,8 +14,6 @@ router.get("/user/teacher", verifyLoginUser, adminOnly, getTeachers); router.get("/user/student", verifyLoginUser, adminOrTeacherOnly, getStudents); -router.get("/user/student/unassigned", verifyLoginUser, adminOrTeacherOnly, getStudentsWithNoClass); - router.get("/user/:id", verifyLoginUser, getUserById); router.get("/user/name/:name", verifyLoginUser, adminOrTeacherOnly, getUserByName);