feat: monitoring data to csv
This commit is contained in:
parent
cbd3977858
commit
c5aecb2af9
|
|
@ -1,6 +1,6 @@
|
|||
APP_PORT = 3001
|
||||
NODE_ENV = development
|
||||
FE_DOMAIN = http://localhost:5173
|
||||
CLIENT_URL = http://localhost:5173
|
||||
|
||||
DB_HOST = localhost
|
||||
DB_USER = root
|
||||
|
|
|
|||
|
|
@ -389,7 +389,7 @@ export const forgotPassword = async (req, res) => {
|
|||
}
|
||||
);
|
||||
|
||||
const resetLink = `${process.env.FE_DOMAIN}/resetPassword/${resetToken}`;
|
||||
const resetLink = `${process.env.CLIENT_URL}/resetPassword/${resetToken}`;
|
||||
|
||||
const mailOptions = {
|
||||
from: process.env.EMAIL_USER,
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@ export const getStudentAnswersByStdLearningId = async (req, res) => {
|
|||
const exerciseDetails = exercise.stdExerciseExercises;
|
||||
const questionType = exerciseDetails.QUESTION_TYPE;
|
||||
|
||||
// Create the formatted exercise object
|
||||
const formattedExercise = {
|
||||
ID_STUDENT_EXERCISE: exerciseData.ID_STUDENT_EXERCISE,
|
||||
ID_ADMIN_EXERCISE: exerciseDetails.ID_ADMIN_EXERCISE,
|
||||
|
|
@ -183,7 +182,6 @@ export const getStudentAnswersByStdLearningId = async (req, res) => {
|
|||
RESULT_SCORE_STUDENT: exercise.RESULT_SCORE_STUDENT,
|
||||
};
|
||||
|
||||
// Include appropriate details based on question type
|
||||
if (questionType === "MCQ") {
|
||||
formattedExercise.multipleChoices = exerciseDetails.multipleChoices;
|
||||
} else if (questionType === "MPQ") {
|
||||
|
|
@ -193,12 +191,22 @@ export const getStudentAnswersByStdLearningId = async (req, res) => {
|
|||
return formattedExercise;
|
||||
});
|
||||
|
||||
return response(200, {
|
||||
...stdLearningData,
|
||||
stdExercises: mappedExercises,
|
||||
}, "Student learning exercises retrieved successfully", res);
|
||||
return response(
|
||||
200,
|
||||
{
|
||||
...stdLearningData,
|
||||
stdExercises: mappedExercises,
|
||||
},
|
||||
"Student learning exercises retrieved successfully",
|
||||
res
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return response(500, null, "Error retrieving student learning exercises", res);
|
||||
return response(
|
||||
500,
|
||||
null,
|
||||
"Error retrieving student learning exercises",
|
||||
res
|
||||
);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
import response from "../../response.js";
|
||||
import models from "../../models/index.js";
|
||||
import { createObjectCsvWriter } from "csv-writer";
|
||||
import { Readable } from "stream";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
export const getMonitorings = async (req, res) => {
|
||||
try {
|
||||
|
|
@ -373,7 +378,21 @@ export const monitoringStudentProgressById = async (req, res) => {
|
|||
} else if (sort === "score") {
|
||||
return b.SCORE - a.SCORE;
|
||||
} else if (sort === "feedback") {
|
||||
return a.FEEDBACK_STUDENT.localeCompare(b.FEEDBACK_STUDENT);
|
||||
if (a.FEEDBACK_STUDENT === null && b.FEEDBACK_STUDENT !== null) {
|
||||
return 1;
|
||||
} else if (
|
||||
a.FEEDBACK_STUDENT !== null &&
|
||||
b.FEEDBACK_STUDENT === null
|
||||
) {
|
||||
return -1;
|
||||
} else if (
|
||||
a.FEEDBACK_STUDENT === null &&
|
||||
b.FEEDBACK_STUDENT === null
|
||||
) {
|
||||
return 0;
|
||||
} else {
|
||||
return a.FEEDBACK_STUDENT.localeCompare(b.FEEDBACK_STUDENT);
|
||||
}
|
||||
} else if (sort === "start") {
|
||||
return new Date(a.STUDENT_START) - new Date(b.STUDENT_START);
|
||||
} else if (sort === "finish") {
|
||||
|
|
@ -848,27 +867,41 @@ export const getClassMonitoringDataByClassAndTopic = async (req, res) => {
|
|||
"STUDENT_START",
|
||||
"STUDENT_FINISH",
|
||||
],
|
||||
order: [["STUDENT_FINISH", "DESC"]],
|
||||
});
|
||||
|
||||
const sortedRecords = allStdLearning.sort((a, b) => {
|
||||
const userComparison = a.learningUser.NAME_USERS.localeCompare(
|
||||
b.learningUser.NAME_USERS
|
||||
);
|
||||
if (userComparison !== 0) {
|
||||
return userComparison;
|
||||
}
|
||||
|
||||
if (sort === "nisn") {
|
||||
return String(a.learningUser.students.NISN).localeCompare(
|
||||
String(b.learningUser.students.NISN)
|
||||
);
|
||||
} else if (sort === "user") {
|
||||
return a.learningUser.NAME_USERS.localeCompare(
|
||||
b.learningUser.NAME_USERS
|
||||
);
|
||||
} else if (sort === "name") {
|
||||
return userComparison;
|
||||
} else if (sort === "level") {
|
||||
return a.level.NAME_LEVEL.localeCompare(b.level.NAME_LEVEL);
|
||||
} else if (sort === "score") {
|
||||
return b.SCORE - a.SCORE;
|
||||
} else if (sort === "feedback") {
|
||||
return a.FEEDBACK_STUDENT.localeCompare(b.FEEDBACK_STUDENT);
|
||||
if (a.FEEDBACK_STUDENT === null && b.FEEDBACK_STUDENT !== null) {
|
||||
return 1;
|
||||
} else if (a.FEEDBACK_STUDENT !== null && b.FEEDBACK_STUDENT === null) {
|
||||
return -1;
|
||||
} else if (a.FEEDBACK_STUDENT === null && b.FEEDBACK_STUDENT === null) {
|
||||
return 0;
|
||||
} else {
|
||||
return a.FEEDBACK_STUDENT.localeCompare(b.FEEDBACK_STUDENT);
|
||||
}
|
||||
} else if (sort === "start") {
|
||||
return new Date(a.STUDENT_START) - new Date(b.STUDENT_START);
|
||||
}
|
||||
// Default sorting by student finish
|
||||
|
||||
return new Date(a.STUDENT_FINISH) - new Date(b.STUDENT_FINISH);
|
||||
});
|
||||
|
||||
|
|
@ -956,8 +989,6 @@ export const monitoringFeedbackByClassAndTopic = async (req, res) => {
|
|||
],
|
||||
});
|
||||
|
||||
console.log("Monitoring Data:", JSON.stringify(monitoringData, null, 2));
|
||||
|
||||
if (!monitoringData || monitoringData.length === 0) {
|
||||
return response(
|
||||
404,
|
||||
|
|
@ -1027,3 +1058,375 @@ export const monitoringFeedbackByClassAndTopic = async (req, res) => {
|
|||
response(500, null, "Error updating teacher feedback!", res);
|
||||
}
|
||||
};
|
||||
|
||||
export const monitoringStudentProgressCSVById = async (req, res) => {
|
||||
const { id } = req.params;
|
||||
|
||||
try {
|
||||
const monitoring = await models.Monitoring.findOne({
|
||||
where: { ID_MONITORING: id },
|
||||
include: [
|
||||
{
|
||||
model: models.StdLearning,
|
||||
as: "stdLearningMonitoring",
|
||||
attributes: [
|
||||
"ID",
|
||||
"ID_LEVEL",
|
||||
"SCORE",
|
||||
"FEEDBACK_STUDENT",
|
||||
"STUDENT_START",
|
||||
"STUDENT_FINISH",
|
||||
"ID_STUDENT_LEARNING",
|
||||
],
|
||||
include: [
|
||||
{
|
||||
model: models.Level,
|
||||
as: "level",
|
||||
attributes: ["ID_TOPIC", "NAME_LEVEL"],
|
||||
include: [
|
||||
{
|
||||
model: models.Topic,
|
||||
as: "levelTopic",
|
||||
attributes: ["NAME_TOPIC"],
|
||||
include: [
|
||||
{
|
||||
model: models.Section,
|
||||
as: "topicSection",
|
||||
attributes: ["NAME_SECTION"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
model: models.User,
|
||||
as: "learningUser",
|
||||
attributes: ["NAME_USERS"],
|
||||
include: [
|
||||
{
|
||||
model: models.Student,
|
||||
as: "students",
|
||||
attributes: ["NISN"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (!monitoring) {
|
||||
return response(404, null, "Monitoring data not found!", res);
|
||||
}
|
||||
|
||||
const stdLearning = monitoring.stdLearningMonitoring;
|
||||
|
||||
if (!stdLearning || stdLearning.length === 0) {
|
||||
return response(404, null, "No student learning data found!", res);
|
||||
}
|
||||
|
||||
const userID = stdLearning.ID;
|
||||
const topicID = stdLearning.level.ID_TOPIC;
|
||||
const studentName = stdLearning.learningUser.NAME_USERS;
|
||||
const nisn = stdLearning.learningUser.students.NISN;
|
||||
const topicName = stdLearning.level.levelTopic.NAME_TOPIC;
|
||||
const sectionName = stdLearning.level.levelTopic.topicSection.NAME_SECTION;
|
||||
|
||||
const levels = await models.StdLearning.findAll({
|
||||
where: {
|
||||
ID: userID,
|
||||
STUDENT_FINISH: {
|
||||
[models.Sequelize.Op.ne]: null,
|
||||
},
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: models.Level,
|
||||
as: "level",
|
||||
attributes: ["NAME_LEVEL", "ID_TOPIC"],
|
||||
where: {
|
||||
ID_TOPIC: topicID,
|
||||
},
|
||||
},
|
||||
],
|
||||
attributes: [
|
||||
"SCORE",
|
||||
"FEEDBACK_STUDENT",
|
||||
"STUDENT_START",
|
||||
"STUDENT_FINISH",
|
||||
],
|
||||
order: [["STUDENT_FINISH", "DESC"]],
|
||||
distinct: true,
|
||||
});
|
||||
|
||||
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,
|
||||
}));
|
||||
|
||||
const tempDir = os.tmpdir();
|
||||
const tempFilePath = path.join(
|
||||
tempDir,
|
||||
`Student_Monitoring_${nisn}_${studentName}.csv`
|
||||
);
|
||||
|
||||
const csvWriter = createObjectCsvWriter({
|
||||
path: tempFilePath,
|
||||
header: [
|
||||
{ id: "field", title: "Field" },
|
||||
{ id: "value", title: "Value" },
|
||||
],
|
||||
});
|
||||
|
||||
const records = [
|
||||
{ field: "Section Name", value: sectionName },
|
||||
{ field: "Topic Name", value: topicName },
|
||||
{ field: "Student Name", value: studentName },
|
||||
{ field: "NISN", value: nisn },
|
||||
];
|
||||
|
||||
await csvWriter.writeRecords(records);
|
||||
|
||||
const levelCsvWriter = createObjectCsvWriter({
|
||||
path: tempFilePath,
|
||||
append: true,
|
||||
header: [
|
||||
{ id: "NAME_LEVEL", title: "Level Name" },
|
||||
{ id: "SCORE", title: "Score" },
|
||||
{ id: "FEEDBACK_STUDENT", title: "Student Feedback" },
|
||||
{ id: "STUDENT_START", title: "Start Exercise" },
|
||||
{ id: "STUDENT_FINISH", title: "Finish Exercise" },
|
||||
],
|
||||
});
|
||||
|
||||
fs.appendFileSync(tempFilePath, "\n");
|
||||
|
||||
fs.appendFileSync(
|
||||
tempFilePath,
|
||||
"Name Level,Score,Student Feedback,Start Exercise,Finish Exercise\n"
|
||||
);
|
||||
|
||||
await levelCsvWriter.writeRecords(levelArray);
|
||||
|
||||
res.setHeader("Content-Type", "text/csv");
|
||||
res.setHeader(
|
||||
"Content-Disposition",
|
||||
`attachment; filename="Student_Monitoring_${nisn}_${studentName}.csv.csv"`
|
||||
);
|
||||
|
||||
const fileStream = fs.createReadStream(tempFilePath);
|
||||
fileStream.pipe(res).on("finish", () => {
|
||||
fs.unlinkSync(tempFilePath);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
response(500, null, "Error retrieving student progress!", res);
|
||||
}
|
||||
};
|
||||
|
||||
export const classMonitoringCSVByClassAndTopic = async (req, res) => {
|
||||
const { ID_CLASS, ID_TOPIC } = req.body;
|
||||
|
||||
try {
|
||||
const classData = await models.Class.findOne({
|
||||
where: { ID_CLASS: ID_CLASS },
|
||||
attributes: ["ID_CLASS", "NAME_CLASS"],
|
||||
});
|
||||
|
||||
if (!classData) {
|
||||
return response(404, null, "Class not found!", res);
|
||||
}
|
||||
|
||||
const className = classData.NAME_CLASS;
|
||||
|
||||
const topicData = await models.Topic.findOne({
|
||||
where: { ID_TOPIC: ID_TOPIC },
|
||||
include: [
|
||||
{
|
||||
model: models.Section,
|
||||
as: "topicSection",
|
||||
attributes: ["ID_SECTION", "NAME_SECTION"],
|
||||
},
|
||||
],
|
||||
attributes: ["ID_TOPIC", "NAME_TOPIC"],
|
||||
});
|
||||
|
||||
if (!topicData) {
|
||||
return response(404, null, "Topic not found!", res);
|
||||
}
|
||||
|
||||
const topicName = topicData.NAME_TOPIC;
|
||||
const sectionName = topicData.topicSection?.NAME_SECTION;
|
||||
|
||||
const monitoringData = await models.Monitoring.findAll({
|
||||
where: { ID_CLASS: ID_CLASS },
|
||||
include: [
|
||||
{
|
||||
model: models.StdLearning,
|
||||
as: "stdLearningMonitoring",
|
||||
required: true,
|
||||
attributes: ["ID", "ID_LEVEL"],
|
||||
include: [
|
||||
{
|
||||
model: models.Level,
|
||||
as: "level",
|
||||
attributes: ["ID_LEVEL", "ID_TOPIC"],
|
||||
where: { ID_TOPIC: ID_TOPIC },
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (!monitoringData || monitoringData.length === 0) {
|
||||
const result = {
|
||||
ID_CLASS: classData.ID_CLASS,
|
||||
ID_SECTION: topicData.topicSection?.ID_SECTION,
|
||||
ID_TOPIC: topicData.ID_TOPIC,
|
||||
NAME_CLASS: className,
|
||||
NAME_SECTION: sectionName,
|
||||
NAME_TOPIC: topicName,
|
||||
};
|
||||
return response(
|
||||
200,
|
||||
result,
|
||||
"No monitoring data found for this class and topic!",
|
||||
res
|
||||
);
|
||||
}
|
||||
|
||||
const userIds = monitoringData.map(
|
||||
(monitoring) => monitoring.stdLearningMonitoring.ID
|
||||
);
|
||||
|
||||
const allStdLearning = await models.StdLearning.findAll({
|
||||
where: {
|
||||
ID_LEVEL: {
|
||||
[models.Sequelize.Op.in]: (
|
||||
await models.Level.findAll({
|
||||
where: { ID_TOPIC: ID_TOPIC },
|
||||
attributes: ["ID_LEVEL"],
|
||||
})
|
||||
).map((level) => level.ID_LEVEL),
|
||||
},
|
||||
ID: {
|
||||
[models.Sequelize.Op.in]: userIds,
|
||||
},
|
||||
STUDENT_FINISH: {
|
||||
[models.Sequelize.Op.ne]: null,
|
||||
},
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: models.Level,
|
||||
as: "level",
|
||||
attributes: ["NAME_LEVEL", "ID_TOPIC"],
|
||||
},
|
||||
{
|
||||
model: models.User,
|
||||
as: "learningUser",
|
||||
attributes: ["NAME_USERS"],
|
||||
include: [
|
||||
{
|
||||
model: models.Student,
|
||||
as: "students",
|
||||
attributes: ["NISN"],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
attributes: [
|
||||
"SCORE",
|
||||
"FEEDBACK_STUDENT",
|
||||
"STUDENT_START",
|
||||
"STUDENT_FINISH",
|
||||
],
|
||||
order: [
|
||||
[{ model: models.User, as: "learningUser" }, "NAME_USERS", "ASC"],
|
||||
["STUDENT_FINISH", "DESC"],
|
||||
],
|
||||
});
|
||||
|
||||
const formattedData = allStdLearning.map((stdLearning) => {
|
||||
const level = stdLearning?.level;
|
||||
const user = stdLearning?.learningUser;
|
||||
const student = user?.students;
|
||||
|
||||
return {
|
||||
NISN: student?.NISN,
|
||||
NAME_USERS: user?.NAME_USERS,
|
||||
NAME_LEVEL: level?.NAME_LEVEL,
|
||||
SCORE: stdLearning?.SCORE,
|
||||
FEEDBACK_STUDENT: stdLearning?.FEEDBACK_STUDENT,
|
||||
STUDENT_START: stdLearning?.STUDENT_START,
|
||||
STUDENT_FINISH: stdLearning?.STUDENT_FINISH,
|
||||
};
|
||||
});
|
||||
|
||||
const sanitizedClassName = className.replace(/\s+/g, "_");
|
||||
const sanitizedTopicName = topicName.replace(/\s+/g, "_");
|
||||
|
||||
const tempDir = os.tmpdir();
|
||||
const tempFilePath = path.join(
|
||||
tempDir,
|
||||
`Class_Monitoring_${sanitizedClassName}_${sanitizedTopicName}.csv`
|
||||
);
|
||||
|
||||
const csvWriter = createObjectCsvWriter({
|
||||
path: tempFilePath,
|
||||
header: [
|
||||
{ id: "field", title: "Field" },
|
||||
{ id: "value", title: "Value" },
|
||||
],
|
||||
});
|
||||
|
||||
const records = [
|
||||
{ field: "Class Name", value: className },
|
||||
{ field: "Section Name", value: sectionName },
|
||||
{ field: "Topic Name", value: topicName },
|
||||
];
|
||||
|
||||
await csvWriter.writeRecords(records);
|
||||
|
||||
const levelCsvWriter = createObjectCsvWriter({
|
||||
path: tempFilePath,
|
||||
append: true,
|
||||
header: [
|
||||
{ id: "NISN", title: "NISN" },
|
||||
{ id: "NAME_USERS", title: "Student Name" },
|
||||
{ id: "NAME_LEVEL", title: "Level Name" },
|
||||
{ id: "SCORE", title: "Score" },
|
||||
{ id: "FEEDBACK_STUDENT", title: "Student Feedback" },
|
||||
{ id: "STUDENT_START", title: "Start Exercise" },
|
||||
{ id: "STUDENT_FINISH", title: "Finish Exercise" },
|
||||
],
|
||||
});
|
||||
|
||||
fs.appendFileSync(tempFilePath, "\n");
|
||||
|
||||
fs.appendFileSync(
|
||||
tempFilePath,
|
||||
"NISN,Student Name,Level Name,Score,Student Feedback,Start Exercise,Finish Exercise\n"
|
||||
);
|
||||
|
||||
await levelCsvWriter.writeRecords(formattedData);
|
||||
|
||||
res.setHeader("Content-Type", "text/csv");
|
||||
res.setHeader(
|
||||
"Content-Disposition",
|
||||
`attachment; filename=Class_Monitoring_${sanitizedClassName}_${sanitizedTopicName}.csv`
|
||||
);
|
||||
|
||||
const fileStream = fs.createReadStream(tempFilePath);
|
||||
fileStream.pipe(res).on("finish", () => {
|
||||
fs.unlinkSync(tempFilePath);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error fetching monitoring data:", error);
|
||||
response(500, null, "Error retrieving monitoring data!", res);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
4
index.js
4
index.js
|
|
@ -9,7 +9,7 @@ dotenv.config();
|
|||
const app = express();
|
||||
|
||||
const corsOptions = {
|
||||
origin: "http://localhost:5173",
|
||||
origin: `${process.env.CLIENT_URL}`,
|
||||
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
||||
allowedHeaders: ["Content-Type", "Authorization"],
|
||||
credentials: true,
|
||||
|
|
@ -27,6 +27,6 @@ app.use(express.static("public"));
|
|||
app.listen(process.env.APP_PORT, () => {
|
||||
testConnection();
|
||||
console.log(
|
||||
`Server running on port http://localhost:${process.env.APP_PORT}`
|
||||
`Server running on port ${process.env.APP_PORT}`
|
||||
);
|
||||
});
|
||||
|
|
|
|||
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -12,6 +12,7 @@
|
|||
"bcrypt": "^5.1.1",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cors": "^2.8.5",
|
||||
"csv-writer": "^1.6.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
|
|
@ -646,6 +647,11 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/csv-writer": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/csv-writer/-/csv-writer-1.6.0.tgz",
|
||||
"integrity": "sha512-NOx7YDFWEsM/fTRAJjRpPp8t+MKRVvniAg9wQlUKx20MFrPs73WLJhFf5iteqrxNYnsy924K3Iroh3yNHeYd2g=="
|
||||
},
|
||||
"node_modules/d": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
"bcrypt": "^5.1.1",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"cors": "^2.8.5",
|
||||
"csv-writer": "^1.6.0",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"jsonwebtoken": "^9.0.2",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import express from "express";
|
||||
import { getMonitorings, getMonitoringById,monitoringStudentsProgress, monitoringStudentProgressById, getClassMonitoringByClassId, getClassMonitoringDataByClassAndTopic, getMonitoringByTopicId, monitoringFeedback, monitoringFeedbackByClassAndTopic } from "../../controllers/monitoringControllers/monitoring.js";
|
||||
import { getMonitorings, getMonitoringById,monitoringStudentsProgress, monitoringStudentProgressById, getClassMonitoringByClassId, getClassMonitoringDataByClassAndTopic, getMonitoringByTopicId, monitoringFeedback, monitoringFeedbackByClassAndTopic, monitoringStudentProgressCSVById, classMonitoringCSVByClassAndTopic } from "../../controllers/monitoringControllers/monitoring.js";
|
||||
import { verifyLoginUser, adminOrTeacherOnly } from "../../middlewares/User/authUser.js";
|
||||
|
||||
const router = express.Router();
|
||||
|
|
@ -12,12 +12,16 @@ router.get("/monitoring/class", verifyLoginUser, getClassMonitoringDataByClassAn
|
|||
|
||||
router.get("/monitoring/:id", verifyLoginUser, getMonitoringById);
|
||||
|
||||
router.get("/monitoring/class/csv", verifyLoginUser, adminOrTeacherOnly, classMonitoringCSVByClassAndTopic);
|
||||
|
||||
router.get("/monitoring/class/:classId", verifyLoginUser, adminOrTeacherOnly, getClassMonitoringByClassId);
|
||||
|
||||
router.get("/monitoring/topic/:topicId", verifyLoginUser, getMonitoringByTopicId);
|
||||
|
||||
router.get("/monitoring/progress/:id", verifyLoginUser, adminOrTeacherOnly, monitoringStudentProgressById);
|
||||
|
||||
router.get("/monitoring/progress/csv/:id", verifyLoginUser, adminOrTeacherOnly, monitoringStudentProgressCSVById);
|
||||
|
||||
router.post("/monitoring/feedback/class", verifyLoginUser, adminOrTeacherOnly, monitoringFeedbackByClassAndTopic);
|
||||
|
||||
router.post("/monitoring/feedback/:id", verifyLoginUser, adminOrTeacherOnly, monitoringFeedback);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user