From 80de2108b8f2345a9a8af4b935f1d23119e83d2f Mon Sep 17 00:00:00 2001 From: elangptra Date: Thu, 10 Oct 2024 12:39:09 +0700 Subject: [PATCH] refactor: get user function and get learning history function --- .../learningControllers/stdLearning.js | 71 ++++++--- controllers/usersControllers/user.js | 138 +++++++++++++++++- 2 files changed, 182 insertions(+), 27 deletions(-) diff --git a/controllers/learningControllers/stdLearning.js b/controllers/learningControllers/stdLearning.js index cc336a9..a36e538 100644 --- a/controllers/learningControllers/stdLearning.js +++ b/controllers/learningControllers/stdLearning.js @@ -92,7 +92,8 @@ export const updateStdLearningById = async (req, res) => { stdLearning.STUDENT_FINISH = new Date(); stdLearning.SCORE = req.body.SCORE || stdLearning.SCORE; - stdLearning.NEXT_LEARNING = req.body.NEXT_LEARNING || stdLearning.NEXT_LEARNING; + stdLearning.NEXT_LEARNING = + req.body.NEXT_LEARNING || stdLearning.NEXT_LEARNING; stdLearning.IS_PASS = req.body.IS_PASS || stdLearning.IS_PASS; if (FEEDBACK_STUDENT) { @@ -248,9 +249,7 @@ export const learningHistory = async (req, res) => { const { ID } = req.user; const stdLearnings = await models.StdLearning.findAll({ - where: { - ID: ID, - }, + where: { ID }, include: [ { model: models.Level, @@ -259,18 +258,31 @@ export const learningHistory = async (req, res) => { { model: models.Topic, as: "levelTopic", + required: true, include: [ { model: models.Section, as: "topicSection", + required: true, }, ], }, ], + required: true, }, ], + order: [["STUDENT_START", "DESC"]], }); + if (!stdLearnings.length) { + return response( + 404, + null, + "No learning history found for this user", + res + ); + } + const result = await Promise.all( stdLearnings.map(async (learning) => { let nextLevelName = null; @@ -285,18 +297,20 @@ export const learningHistory = async (req, res) => { return { SCORE: learning.SCORE, - CURRENT_LEVEL: learning.level.NAME_LEVEL, + CURRENT_LEVEL: learning.level?.NAME_LEVEL || "No level", NEXT_LEVEL: nextLevelName, STUDENT_FINISH: learning.STUDENT_FINISH, - TOPIC_NAME: learning.level.levelTopic.NAME_TOPIC, - SECTION_NAME: learning.level.levelTopic.topicSection.NAME_SECTION, + TOPIC_NAME: learning.level?.levelTopic?.NAME_TOPIC || "No topic", + SECTION_NAME: + learning.level?.levelTopic?.topicSection?.NAME_SECTION || + "No section", }; }) ); response(200, result, "Success", res); } catch (error) { - console.log(error); + console.error(error); response(500, null, "Internal Server Error", res); } }; @@ -311,9 +325,7 @@ export const learningHistoryBySectionId = async (req, res) => { const { sectionId } = req.params; const stdLearnings = await models.StdLearning.findAll({ - where: { - ID: ID, - }, + where: { ID }, include: [ { model: models.Level, @@ -327,12 +339,16 @@ export const learningHistoryBySectionId = async (req, res) => { model: models.Section, as: "topicSection", where: { ID_SECTION: sectionId }, + required: true, }, ], + required: true, }, ], + required: true, }, ], + order: [["STUDENT_START", "DESC"]], }); if (!stdLearnings.length) { @@ -358,11 +374,13 @@ export const learningHistoryBySectionId = async (req, res) => { return { SCORE: learning.SCORE, - CURRENT_LEVEL: learning.level.NAME_LEVEL, + CURRENT_LEVEL: learning.level?.NAME_LEVEL || "No level", NEXT_LEVEL: nextLevelName, STUDENT_FINISH: learning.STUDENT_FINISH, - TOPIC_NAME: learning.level.levelTopic.NAME_TOPIC, - SECTION_NAME: learning.level.levelTopic.topicSection.NAME_SECTION, + TOPIC_NAME: learning.level?.levelTopic?.NAME_TOPIC || "No topic", + SECTION_NAME: + learning.level?.levelTopic?.topicSection?.NAME_SECTION || + "No section", }; }) ); @@ -388,9 +406,7 @@ export const learningHistoryByTopicId = async (req, res) => { } const stdLearnings = await models.StdLearning.findAll({ - where: { - ID: ID, - }, + where: { ID }, include: [ { model: models.Level, @@ -400,18 +416,31 @@ export const learningHistoryByTopicId = async (req, res) => { model: models.Topic, as: "levelTopic", where: { ID_TOPIC: topicId }, + required: true, include: [ { model: models.Section, as: "topicSection", + required: true, }, ], }, ], + required: true, }, ], + order: [["STUDENT_START", "DESC"]], }); + if (!stdLearnings.length) { + return response( + 404, + null, + "No learning history found for the specified topic", + res + ); + } + const result = await Promise.all( stdLearnings.map(async (learning) => { let nextLevelName = null; @@ -426,11 +455,13 @@ export const learningHistoryByTopicId = async (req, res) => { return { SCORE: learning.SCORE, - CURRENT_LEVEL: learning.level.NAME_LEVEL, + CURRENT_LEVEL: learning.level?.NAME_LEVEL || "No level", NEXT_LEVEL: nextLevelName, STUDENT_FINISH: learning.STUDENT_FINISH, - TOPIC_NAME: learning.level.levelTopic.NAME_TOPIC, - SECTION_NAME: learning.level.levelTopic.topicSection.NAME_SECTION, + TOPIC_NAME: learning.level?.levelTopic?.NAME_TOPIC || "No topic", + SECTION_NAME: + learning.level?.levelTopic?.topicSection?.NAME_SECTION || + "No section", }; }) ); diff --git a/controllers/usersControllers/user.js b/controllers/usersControllers/user.js index 19e8ec3..475a511 100644 --- a/controllers/usersControllers/user.js +++ b/controllers/usersControllers/user.js @@ -60,12 +60,39 @@ export const getAdmins = async (req, res) => { }; export const getTeachers = async (req, res) => { + const { page = 1, limit = 10, search = "", sort = "time" } = req.query; + try { - const teachers = await models.User.findAll({ + const totalTeachersCount = await models.User.count({ where: { ROLE: "teacher", }, - attributes: ["ID", "NAME_USERS", "EMAIL", "ROLE"], + }); + + const { count, rows: teachers } = await models.User.findAndCountAll({ + where: { + ROLE: "teacher", + ...(search && { + [models.Op.or]: [ + { + NAME_USERS: { + [models.Op.like]: `%${search}%`, + }, + }, + { + EMAIL: { + [models.Op.like]: `%${search}%`, + }, + }, + { + "$teachers.NIP$": { + [models.Op.like]: `%${search}%`, + }, + }, + ], + }), + }, + attributes: ["ID", "NAME_USERS", "EMAIL", "ROLE", "TIME_USERS"], include: [ { model: models.Teacher, @@ -73,6 +100,7 @@ export const getTeachers = async (req, res) => { attributes: ["NIP"], }, ], + distinct: true, raw: true, nest: true, }); @@ -83,9 +111,43 @@ export const getTeachers = async (req, res) => { EMAIL: teacher.EMAIL, NIP: teacher.teachers.NIP, ROLE: teacher.ROLE, + TIME_USERS: teacher.TIME_USERS, })); - response(200, formattedTeachers, "Success", res); + if (sort === "nip") { + formattedTeachers.sort((a, b) => a.NIP.localeCompare(b.NIP)); + } else if (sort === "name") { + formattedTeachers.sort((a, b) => + a.NAME_USERS.localeCompare(b.NAME_USERS) + ); + } else if (sort === "email") { + formattedTeachers.sort((a, b) => a.EMAIL.localeCompare(b.EMAIL)); + } else { + formattedTeachers.sort( + (a, b) => new Date(b.TIME_USERS) - new Date(a.TIME_USERS) + ); + } + + const paginatedTeachers = formattedTeachers.slice( + (page - 1) * limit, + page * limit + ); + + const totalPages = Math.ceil(count / limit); + const currentPage = parseInt(page); + + response( + 200, + { + teachers: paginatedTeachers, + currentPage, + totalPages, + totalSearchedItems: count, + totalTeachers: totalTeachersCount, + }, + "Teachers retrieved successfully", + res + ); } catch (error) { console.log(error); response(500, null, "Error retrieving teacher data!", res); @@ -93,12 +155,39 @@ export const getTeachers = async (req, res) => { }; export const getStudents = async (req, res) => { + const { page = 1, limit = 10, search = "", sort = "time" } = req.query; + try { - const students = await models.User.findAll({ + const totalStudentsCount = await models.User.count({ where: { ROLE: "student", }, - attributes: ["ID", "NAME_USERS", "EMAIL", "ROLE"], + }); + + const { count, rows: students } = await models.User.findAndCountAll({ + where: { + ROLE: "student", + ...(search && { + [models.Op.or]: [ + { + NAME_USERS: { + [models.Op.like]: `%${search}%`, + }, + }, + { + EMAIL: { + [models.Op.like]: `%${search}%`, + }, + }, + { + "$students.NISN$": { + [models.Op.like]: `%${search}%`, + }, + }, + ], + }), + }, + attributes: ["ID", "NAME_USERS", "EMAIL", "ROLE", "TIME_USERS"], include: [ { model: models.Student, @@ -113,6 +202,7 @@ export const getStudents = async (req, res) => { ], }, ], + distinct: true, raw: true, nest: true, }); @@ -124,12 +214,46 @@ export const getStudents = async (req, res) => { EMAIL: student.EMAIL, NAME_CLASS: student.students.studentClass.NAME_CLASS, ROLE: student.ROLE, + TIME_USERS: student.TIME_USERS, })); - response(200, formattedStudents, "Success", res); + if (sort === "nisn") { + formattedStudents.sort((a, b) => a.NISN.localeCompare(b.NISN)); + } else if (sort === "name") { + formattedStudents.sort((a, b) => + a.NAME_USERS.localeCompare(b.NAME_USERS) + ); + } else if (sort === "email") { + formattedStudents.sort((a, b) => a.EMAIL.localeCompare(b.EMAIL)); + } else { + formattedStudents.sort( + (a, b) => new Date(b.TIME_USERS) - new Date(a.TIME_USERS) + ); + } + + const paginatedStudents = formattedStudents.slice( + (page - 1) * limit, + page * limit + ); + + const totalPages = Math.ceil(count / limit); + const currentPage = parseInt(page); + + response( + 200, + { + students: paginatedStudents, + currentPage, + totalPages, + totalSearchedItems: count, + totalStudents: totalStudentsCount, + }, + "Students retrieved successfully", + res + ); } catch (error) { console.log(error); - response(500, null, "Error retrieving student data!", res); + response(500, null, "Error retrieving students data!", res); } };