diff --git a/controllers/learningControllers/stdLearning.js b/controllers/learningControllers/stdLearning.js index 6c8603d..6ae2830 100644 --- a/controllers/learningControllers/stdLearning.js +++ b/controllers/learningControllers/stdLearning.js @@ -182,8 +182,8 @@ export const learningScoreByStdLearningId = async (req, res) => { model: models.Student, as: "students", attributes: ["NISN"], - } - ] + }, + ], }, ], }); @@ -421,3 +421,35 @@ export const learningHistoryByTopicId = async (req, res) => { response(500, null, "Internal Server Error", res); } }; + +export const getLastCreatedStdLearningByLevelId = async (req, res) => { + try { + if (!req.user) { + return response(401, null, "User not authenticated", res); + } + + const { ID } = req.user; + const { levelId } = req.params; + + if (!levelId) { + return response(400, null, "Level ID is required", res); + } + + const latestStdLearning = await models.StdLearning.findOne({ + where: { + ID: ID, + ID_LEVEL: levelId, + }, + order: [["STUDENT_START", "DESC"]], + }); + + if (!latestStdLearning) { + return response(404, null, "No StdLearning data found", res); + } + + response(200, latestStdLearning, "Success", res); + } catch (error) { + console.error(error); + response(500, null, "Internal Server Error", res); + } +}; diff --git a/controllers/usersControllers/report.js b/controllers/usersControllers/report.js new file mode 100644 index 0000000..957db88 --- /dev/null +++ b/controllers/usersControllers/report.js @@ -0,0 +1,139 @@ +import response from "../../response.js"; +import models from "../../models/index.js"; + +export const getReports = async (req, res) => { + try { + const reports = await models.Report.findAll({ + include: [ + { + model: models.User, + as: "reportUser", + attributes: ["NAME_USERS", "EMAIL"], + }, + ], + }); + + const modifiedReports = reports.map((report) => { + const reportData = report.toJSON(); + + reportData.USER_NAME = reportData.reportUser.NAME_USERS; + reportData.USER_EMAIL = reportData.reportUser.EMAIL; + + delete reportData.reportUser; + + return reportData; + }); + + response(200, modifiedReports, "Success", res); + } catch (error) { + console.log(error); + response(500, null, "Error retrieving reports data!", res); + } +}; + +export const getReportById = async (req, res) => { + try { + const { id } = req.params; + const report = await models.Report.findByPk(id, { + include: [ + { + model: models.User, + as: "reportUser", + attributes: ["NAME_USERS", "EMAIL"], + }, + ], + }); + + if (!report) { + return response(404, null, "Report data not found", res); + } + + const reportData = report.toJSON(); + reportData.USER_NAME = reportData.reportUser.NAME_USERS; + reportData.USER_EMAIL = reportData.reportUser.EMAIL; + + delete reportData.reportUser; + + response(200, reportData, "Success", res); + } catch (error) { + console.log(error); + response(500, null, "Internal Server Error", res); + } +}; + +export const getReportByUserId = async (req, res) => { + try { + const { id } = req.params; + + const reports = await models.Report.findAll({ + where: { ID: id }, + include: [ + { + model: models.User, + as: "reportUser", + attributes: ["NAME_USERS", "EMAIL"], + }, + ], + }); + + if (reports.length === 0) { + return response(404, null, "No report data found for this user", res); + } + + const modifiedReports = reports.map((report) => { + const reportData = report.toJSON(); + + reportData.USER_NAME = reportData.reportUser.NAME_USERS; + reportData.USER_EMAIL = reportData.reportUser.EMAIL; + + delete reportData.reportUser; + + return reportData; + }); + + response(200, modifiedReports, "Success", res); + } catch (error) { + console.log(error); + response(500, null, "Internal Server Error", res); + } +}; + +export const userReport = async (req, res) => { + if (!req.user) { + return response(401, null, "User not authenticated", res); + } + + const { REPORTS } = req.body; + + if (!REPORTS || REPORTS.trim() === "") { + return response(400, null, "Report content is required", res); + } + + try { + const newReport = await models.Report.create({ + ID: req.user.ID, + REPORTS: REPORTS, + }); + + const createdReport = await models.Report.findByPk(newReport.ID_REPORT, { + include: [ + { + model: models.User, + as: "reportUser", + attributes: ["NAME_USERS", "EMAIL"], + }, + ], + }); + + const reportData = createdReport.toJSON(); + reportData.USER_NAME = reportData.reportUser.NAME_USERS; + reportData.USER_EMAIL = reportData.reportUser.EMAIL; + + delete reportData.reportUser; + + response(201, reportData, "Report created successfully", res); + } catch (error) { + console.error(error); + response(500, null, "Internal Server Error", res); + } +}; diff --git a/models/index.js b/models/index.js index 536d254..3d85b66 100644 --- a/models/index.js +++ b/models/index.js @@ -14,6 +14,7 @@ import StdLearningModel from "./learningModels/stdLearningModel.js"; import StdExerciseModel from "./learningModels/stdExerciseModel.js"; import ClassModel from "./monitoringModels/classModel.js"; import MonitoringModel from "./monitoringModels/monitoringModel.js"; +import ReportModel from "./usersModels/reportModel.js"; const Op = Sequelize.Op; @@ -31,6 +32,7 @@ const StdLearning = StdLearningModel(Sequelize.DataTypes); const StdExercise = StdExerciseModel(Sequelize.DataTypes); const Class = ClassModel(Sequelize.DataTypes); const Monitoring = MonitoringModel(Sequelize.DataTypes); +const Report = ReportModel(Sequelize.DataTypes); User.hasOne(Teacher, { foreignKey: "ID", as: "teachers" }); Teacher.belongsTo(User, { foreignKey: "ID", as: "teacherUser" }); @@ -126,6 +128,9 @@ Monitoring.belongsTo(Teacher, { as: "monitoringTeacher", }); +User.hasMany(Report, { foreignKey: "ID", as: "userReport" }); +Report.belongsTo(User, { foreignKey: "ID", as: "reportUser" }); + const models = { User, Teacher, @@ -141,6 +146,7 @@ const models = { StdExercise, Class, Monitoring, + Report, Sequelize, Op, db, diff --git a/models/monitoringModels/classModel.js b/models/monitoringModels/classModel.js index 646c2fb..5c83a72 100644 --- a/models/monitoringModels/classModel.js +++ b/models/monitoringModels/classModel.js @@ -24,6 +24,11 @@ const ClassModel = (DataTypes) => { type: DataTypes.INTEGER, allowNull: true, }, + TIME_REPORT: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: DataTypes.NOW, + }, }, { timestamps: false, diff --git a/models/monitoringModels/monitoringModel.js b/models/monitoringModels/monitoringModel.js index 80336c7..7f2d3c0 100644 --- a/models/monitoringModels/monitoringModel.js +++ b/models/monitoringModels/monitoringModel.js @@ -44,6 +44,11 @@ const MonitoringModel = (DataTypes) => { type: DataTypes.STRING(200), allowNull: true, }, + TIME_MONITORING: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: DataTypes.NOW, + }, }, { timestamps: false, diff --git a/models/usersModels/reportModel.js b/models/usersModels/reportModel.js new file mode 100644 index 0000000..c4e4ccc --- /dev/null +++ b/models/usersModels/reportModel.js @@ -0,0 +1,48 @@ +import db from "../../database/db.js"; + +const ReportModel = (DataTypes) => { + const Reports = db.define( + "report", + { + ID_REPORT: { + type: DataTypes.UUID, + primaryKey: true, + defaultValue: DataTypes.UUIDV4, + allowNull: false, + validate: { + notEmpty: true, + }, + }, + ID: { + type: DataTypes.UUID, + allowNull: false, + validate: { + notEmpty: true, + }, + references: { + model: "users", + key: "ID", + }, + }, + REPORTS: { + type: DataTypes.STRING, + allowNull: false, + validate: { + notEmpty: true, + }, + }, + TIME_REPORT: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: DataTypes.NOW, + }, + }, + { + timestamps: false, + tableName: "report", + } + ); + return Reports; +}; + +export default ReportModel; diff --git a/models/usersModels/userModel.js b/models/usersModels/userModel.js index f6a5b2e..abf4b9d 100644 --- a/models/usersModels/userModel.js +++ b/models/usersModels/userModel.js @@ -41,6 +41,11 @@ const UserModel = (DataTypes) => { type: DataTypes.STRING, allowNull: true, }, + TIME_USERS: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: DataTypes.NOW, + }, }, { timestamps: false, diff --git a/public/uploads/avatar/user-ca6e061f610f0c6c1d2700fd845a2f61.jpg b/public/uploads/avatar/user-ca6e061f610f0c6c1d2700fd845a2f61.jpg deleted file mode 100644 index 408e510..0000000 Binary files a/public/uploads/avatar/user-ca6e061f610f0c6c1d2700fd845a2f61.jpg and /dev/null differ diff --git a/public/uploads/avatar/user-f247bdc2c503a780944ea7eed44bcfd8.jpg b/public/uploads/avatar/user-f247bdc2c503a780944ea7eed44bcfd8.jpg new file mode 100644 index 0000000..1740d26 Binary files /dev/null and b/public/uploads/avatar/user-f247bdc2c503a780944ea7eed44bcfd8.jpg differ diff --git a/routes/index.js b/routes/index.js index 8613e7b..dd3a9d4 100644 --- a/routes/index.js +++ b/routes/index.js @@ -9,6 +9,7 @@ import stdLearning_routes from "./learning/stdLearning.js"; import stdExercise_routes from "./learning/stdExercise.js"; import class_routes from "./monitoring/class.js"; import monitoring_routes from "./monitoring/monitoring.js"; +import report_routes from "./user/report.js"; const route = express(); route.use(user_routes); @@ -21,5 +22,6 @@ route.use(stdLearning_routes); route.use(stdExercise_routes); route.use(class_routes); route.use(monitoring_routes); +route.use(report_routes); export default route; diff --git a/routes/learning/stdLearning.js b/routes/learning/stdLearning.js index aaf7784..f6df1bd 100644 --- a/routes/learning/stdLearning.js +++ b/routes/learning/stdLearning.js @@ -1,5 +1,5 @@ import express from "express"; -import { getStdLearnings, getStdLearningById, createStdLearning, learningScoreByStdLearningId, learningHistory, learningHistoryBySectionId, learningHistoryByTopicId } from "../../controllers/learningControllers/stdLearning.js"; +import { getStdLearnings, getStdLearningById, createStdLearning, learningScoreByStdLearningId, learningHistory, learningHistoryBySectionId, learningHistoryByTopicId, getLastCreatedStdLearningByLevelId } from "../../controllers/learningControllers/stdLearning.js"; import { verifyLoginUser } from "../../middlewares/User/authUser.js"; const router = express.Router(); @@ -16,6 +16,8 @@ router.get("/learningHistory/section/:sectionId", verifyLoginUser, learningHisto router.get("/learningHistory/topic/:topicId", verifyLoginUser, learningHistoryByTopicId); +router.get("/stdLearning/level/:levelId", verifyLoginUser, getLastCreatedStdLearningByLevelId); + router.post("/stdLearning", verifyLoginUser, createStdLearning); export default router \ No newline at end of file diff --git a/routes/user/report.js b/routes/user/report.js new file mode 100644 index 0000000..006b67e --- /dev/null +++ b/routes/user/report.js @@ -0,0 +1,15 @@ +import express from "express"; +import { getReports, getReportById, getReportByUserId, userReport } from "../../controllers/usersControllers/report.js"; +import { verifyLoginUser, adminOnly } from "../../middlewares/User/authUser.js"; + +const router = express.Router(); + +router.get("/report", verifyLoginUser, adminOnly, getReports); + +router.get("/report/user/:id", verifyLoginUser, adminOnly, getReportByUserId); + +router.get("/report/:id", verifyLoginUser, adminOnly, getReportById); + +router.post("/report", verifyLoginUser, userReport); + +export default router \ No newline at end of file