diff --git a/client/src/App.js b/client/src/App.js index e215dbe..102ed67 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -12,6 +12,7 @@ import FilterPage from "./Pages/FilterPage"; import WelcomeWithFilter from "./Pages/WelcomeWithFilter"; import "react-toastify/dist/ReactToastify.css"; import CourseTable from "./Pages/CourseTable"; +import GenerateCSV from "./Pages/GenerateCSV"; function App() { return ( @@ -19,6 +20,7 @@ function App() { {/* */} }> + } /> } /> } /> } /> diff --git a/client/src/Pages/GenerateCSV.jsx b/client/src/Pages/GenerateCSV.jsx new file mode 100644 index 0000000..a2158df --- /dev/null +++ b/client/src/Pages/GenerateCSV.jsx @@ -0,0 +1,26 @@ +import React from "react"; +import axios from "axios"; + +const GenerateCSV = () => { + const handleGenerateCSV = async () => { + try { + const response = await axios.get("http://localhost:8080/api/csv/generate"); + if (response.status === 200) { + alert("CSV generated successfully. Check the generated_csv folder in the server."); + } + } catch (error) { + console.error("Error generating CSV:", error); + alert("Failed to generate CSV"); + } + }; + + return ( +
+ +
+ ); +}; + +export default GenerateCSV; diff --git a/server/controller/csvGeneratorController.js b/server/controller/csvGeneratorController.js new file mode 100644 index 0000000..8b94f47 --- /dev/null +++ b/server/controller/csvGeneratorController.js @@ -0,0 +1,50 @@ +const path = require("path"); +const createCsvWriter = require("csv-writer").createObjectCsvWriter; +const Appointment = require("../models/Appointment"); + +const generateAppointmentCSV = async (req, res) => { + try { + const appointments = await Appointment.find(); + const groupedData = appointments.reduce((acc, appointment) => { + if (!acc[appointment.facultyId]) { + acc[appointment.facultyId] = { + facultyId: appointment.facultyId, + facultyName: appointment.facultyName, + tasks: [], + }; + } + acc[appointment.facultyId].tasks.push({ + courseId: appointment.courseId, + courseName: appointment.courseName, + task: appointment.task, + }); + return acc; + }, {}); + + const csvData = []; + Object.values(groupedData).forEach(({ facultyId, facultyName, tasks }) => { + tasks.forEach(({ courseId, courseName, task }) => { + csvData.push({ facultyId, facultyName, courseId, courseName, task }); + }); + }); + + const csvWriter = createCsvWriter({ + path: path.join(__dirname, "../generated_csv/appointments.csv"), + header: [ + { id: "facultyId", title: "Faculty ID" }, + { id: "facultyName", title: "Faculty Name" }, + { id: "courseId", title: "Course ID" }, + { id: "courseName", title: "Course Name" }, + { id: "task", title: "Task" }, + ], + }); + + await csvWriter.writeRecords(csvData); + res.status(200).json({ message: "CSV generated successfully", path: "/generated_csv/appointments.csv" }); + } catch (error) { + console.error("Error generating CSV:", error); + res.status(500).json({ message: "Failed to generate CSV" }); + } +}; + +module.exports = { generateAppointmentCSV }; diff --git a/server/package-lock.json b/server/package-lock.json index 5ab6d3c..d2be342 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -14,12 +14,13 @@ "connect-mongo": "^5.1.0", "cors": "^2.8.5", "crypto": "^1.0.1", + "csv-writer": "^1.6.0", "dotenv": "^16.4.5", "express": "^4.19.2", "express-session": "^1.18.0", "googleapis": "^134.0.0", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.3.1", + "mongoose": "^8.9.5", "mongoose-findorcreate": "^4.0.0", "nodemailer": "^6.9.13", "passport": "^0.7.0", @@ -255,9 +256,9 @@ } }, "node_modules/bson": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.0.tgz", - "integrity": "sha512-ROchNosXMJD2cbQGm84KoP7vOGPO6/bOAW0veMMbzhXLqoZptcaYRVLitwvuhwhjjpU1qP4YZRWLhgETdgqUQw==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.1.tgz", + "integrity": "sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA==", "license": "Apache-2.0", "engines": { "node": ">=16.20.1" @@ -425,6 +426,12 @@ "deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.", "license": "ISC" }, + "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==", + "license": "MIT" + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1384,14 +1391,13 @@ } }, "node_modules/mongodb": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.11.0.tgz", - "integrity": "sha512-yVbPw0qT268YKhG241vAMLaDQAPbRyTgo++odSgGc9kXnzOujQI60Iyj23B9sQQFPSvmNPvMZ3dsFz0aN55KgA==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.12.0.tgz", + "integrity": "sha512-RM7AHlvYfS7jv7+BXund/kR64DryVI+cHbVAy9P61fnb1RcWZqOW1/Wj2YhqMCx+MuYhqTRGv7AwHBzmsCKBfA==", "license": "Apache-2.0", - "peer": true, "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "^6.10.0", + "bson": "^6.10.1", "mongodb-connection-string-url": "^3.0.0" }, "engines": { @@ -1399,7 +1405,7 @@ }, "peerDependencies": { "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0", + "@mongodb-js/zstd": "^1.1.0 || ^2.0.0", "gcp-metadata": "^5.2.0", "kerberos": "^2.0.1", "mongodb-client-encryption": ">=6.0.0 <7", @@ -1441,14 +1447,14 @@ } }, "node_modules/mongoose": { - "version": "8.8.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.3.tgz", - "integrity": "sha512-/I4n/DcXqXyIiLRfAmUIiTjj3vXfeISke8dt4U4Y8Wfm074Wa6sXnQrXN49NFOFf2mM1kUdOXryoBvkuCnr+Qw==", + "version": "8.9.5", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.9.5.tgz", + "integrity": "sha512-SPhOrgBm0nKV3b+IIHGqpUTOmgVL5Z3OO9AwkFEmvOZznXTvplbomstCnPOGAyungtRXE5pJTgKpKcZTdjeESg==", "license": "MIT", "dependencies": { - "bson": "^6.7.0", + "bson": "^6.10.1", "kareem": "2.6.3", - "mongodb": "~6.10.0", + "mongodb": "~6.12.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -1468,52 +1474,6 @@ "integrity": "sha512-wi0vrTmazWBeZn8wHVdb8NEa+ZrAbnmfI8QltnFeIgvC33VlnooapvPSk21W22IEhs0vZ0cBz0MmXcc7eTTSZQ==", "license": "MIT" }, - "node_modules/mongoose/node_modules/mongodb": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz", - "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", - "license": "Apache-2.0", - "dependencies": { - "@mongodb-js/saslprep": "^1.1.5", - "bson": "^6.7.0", - "mongodb-connection-string-url": "^3.0.0" - }, - "engines": { - "node": ">=16.20.1" - }, - "peerDependencies": { - "@aws-sdk/credential-providers": "^3.188.0", - "@mongodb-js/zstd": "^1.1.0", - "gcp-metadata": "^5.2.0", - "kerberos": "^2.0.1", - "mongodb-client-encryption": ">=6.0.0 <7", - "snappy": "^7.2.2", - "socks": "^2.7.1" - }, - "peerDependenciesMeta": { - "@aws-sdk/credential-providers": { - "optional": true - }, - "@mongodb-js/zstd": { - "optional": true - }, - "gcp-metadata": { - "optional": true - }, - "kerberos": { - "optional": true - }, - "mongodb-client-encryption": { - "optional": true - }, - "snappy": { - "optional": true - }, - "socks": { - "optional": true - } - } - }, "node_modules/mongoose/node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/server/package.json b/server/package.json index 53728c5..c0df411 100644 --- a/server/package.json +++ b/server/package.json @@ -23,12 +23,13 @@ "connect-mongo": "^5.1.0", "cors": "^2.8.5", "crypto": "^1.0.1", + "csv-writer": "^1.6.0", "dotenv": "^16.4.5", "express": "^4.19.2", "express-session": "^1.18.0", "googleapis": "^134.0.0", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.3.1", + "mongoose": "^8.9.5", "mongoose-findorcreate": "^4.0.0", "nodemailer": "^6.9.13", "passport": "^0.7.0", diff --git a/server/routes/csvRoutes.js b/server/routes/csvRoutes.js new file mode 100644 index 0000000..2500d1f --- /dev/null +++ b/server/routes/csvRoutes.js @@ -0,0 +1,8 @@ +const express = require("express"); +const { generateAppointmentCSV } = require("../controller/csvGeneratorController"); + +const router = express.Router(); + +router.get("/generate", generateAppointmentCSV); + +module.exports = router;