From bb7902fd91ea54fd3f7113580b15acdb573e41af Mon Sep 17 00:00:00 2001 From: amNobodyyy Date: Sun, 26 Jan 2025 17:11:12 +0530 Subject: [PATCH] groupedByCourse --- client/src/App.js | 2 + client/src/Pages/courseConsolidated.jsx | 271 ++++++++++++++++++++++++ server/routes/consolidatedRoutes.js | 68 ++++++ 3 files changed, 341 insertions(+) create mode 100644 client/src/Pages/courseConsolidated.jsx diff --git a/client/src/App.js b/client/src/App.js index e2242bb..c18034c 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -14,6 +14,7 @@ import "react-toastify/dist/ReactToastify.css"; import CourseTable from "./Pages/CourseTable"; import GenerateCSV from "./Pages/GenerateCSV"; import ConsolidatedTable from "./Pages/ConsolidatedTable"; +import CourseConsolidated from "./Pages/courseConsolidated"; function App() { @@ -33,6 +34,7 @@ function App() { } /> } /> } /> + } /> ); diff --git a/client/src/Pages/courseConsolidated.jsx b/client/src/Pages/courseConsolidated.jsx new file mode 100644 index 0000000..97da622 --- /dev/null +++ b/client/src/Pages/courseConsolidated.jsx @@ -0,0 +1,271 @@ +import React, { useState, useEffect } from "react"; +import axios from "axios"; +import * as XLSX from "xlsx-js-style"; + +const CourseConsolidated = () => { + const [data, setData] = useState([]); + const [loading, setLoading] = useState(true); + const [currentPage, setCurrentPage] = useState(1); + const tablesPerPage = 5; + const [expandedCourse, setExpandedCourse] = useState(null); + + useEffect(() => { + const fetchData = async () => { + try { + const response = await axios.get( + "http://localhost:8080/api/table/course-consolidated" + ); + setData(response.data); + setLoading(false); + } catch (error) { + console.error("Error fetching table data:", error); + setLoading(false); + } + }; + + fetchData(); + }, []); + + if (loading) { + return
Loading...
; + } + + // Extract unique courses by courseCode + const uniqueCourses = [...new Set(data.map((row) => row.courseCode))]; + + // Pagination + const indexOfLastTable = currentPage * tablesPerPage; + const indexOfFirstTable = indexOfLastTable - tablesPerPage; + const currentCourses = uniqueCourses.slice( + indexOfFirstTable, + indexOfLastTable + ); + + const totalPages = Math.ceil(uniqueCourses.length / tablesPerPage); + + const handleNextPage = () => { + if (currentPage < totalPages) setCurrentPage((prevPage) => prevPage + 1); + }; + + const handlePrevPage = () => { + if (currentPage > 1) setCurrentPage((prevPage) => prevPage - 1); + }; + + const createExcelFile = (courseData, courseName) => { + const workbook = XLSX.utils.book_new(); + const worksheet = XLSX.utils.json_to_sheet(courseData); + XLSX.utils.book_append_sheet(workbook, worksheet, courseName); + XLSX.writeFile(workbook, `${courseName.replace(/\s+/g, "_")}_Table.xlsx`); + }; + + return ( +
+

+ Course Tables with Download Options +

+ +
+ {currentCourses.map((courseCode, index) => { + const courseData = data.filter( + (row) => row.courseCode === courseCode + ); + const courseName = courseData[0]?.courseName; // Get course name from first item + return ( +
+
+ setExpandedCourse( + expandedCourse === courseCode ? null : courseCode + ) + } + > +

{courseName}'s Table

+ +
+ + {expandedCourse === courseCode && ( + + + + + + + + + + + + + + + + + + {courseData.map((row, idx) => ( + + + + + + + + + + + + + + ))} + +
SemesterCourse CodeCourse NameExam TypeYearOral/PracticalAssessmentReassessmentPaper SettingModerationPwD Paper Setting
{row.semester}{row.courseCode}{row.courseName}{row.examType}{row.year} + {row.oralPracticalTeachers && + row.oralPracticalTeachers.length > 0 ? ( +
    + {row.oralPracticalTeachers.map((teacher, idx) => ( +
  • {teacher}
  • + ))} +
+ ) : ( + "N/A" + )} +
+ {row.assesmentTeachers && + row.assesmentTeachers.length > 0 ? ( +
    + {row.assesmentTeachers.map((teacher, idx) => ( +
  • {teacher}
  • + ))} +
+ ) : ( + "N/A" + )} +
+ {row.reassessmentTeachers && + row.reassessmentTeachers.length > 0 ? ( +
    + {row.reassessmentTeachers.map((teacher, idx) => ( +
  • {teacher}
  • + ))} +
+ ) : ( + "N/A" + )} +
+ {row.paperSettingTeachers && + row.paperSettingTeachers.length > 0 ? ( +
    + {row.paperSettingTeachers.map((teacher, idx) => ( +
  • {teacher}
  • + ))} +
+ ) : ( + "N/A" + )} +
+ {row.moderationTeachers && + row.moderationTeachers.length > 0 ? ( +
    + {row.moderationTeachers.map((teacher, idx) => ( +
  • {teacher}
  • + ))} +
+ ) : ( + "N/A" + )} +
+ {row.pwdPaperSettingTeachers && + row.pwdPaperSettingTeachers.length > 0 ? ( +
    + {row.pwdPaperSettingTeachers.map( + (teacher, idx) => ( +
  • {teacher}
  • + ) + )} +
+ ) : ( + "N/A" + )} +
+ )} +
+ ); + })} +
+ + {/* Pagination controls */} +
+ + + Page {currentPage} of {totalPages} + + +
+
+ ); +}; + +export default CourseConsolidated; diff --git a/server/routes/consolidatedRoutes.js b/server/routes/consolidatedRoutes.js index 83cd4dd..c27d42a 100644 --- a/server/routes/consolidatedRoutes.js +++ b/server/routes/consolidatedRoutes.js @@ -73,4 +73,72 @@ router.get("/consolidated-table", async (req, res) => { } }); +router.get("/course-consolidated", async (req, res) => { + try { + const appointments = await Appointment.find(); + const courses = await Course.find(); + + // Group appointments by courseId and task + const groupedByCourse = {}; + + appointments.forEach((appointment) => { + const courseId = appointment.courseId; + + if (!groupedByCourse[courseId]) { + groupedByCourse[courseId] = { + courseId: courseId, + courseName: appointment.courseName, + tasks: { + oralsPracticals: new Set(), + assessment: new Set(), + reassessment: new Set(), + paperSetting: new Set(), + moderation: new Set(), + pwdPaperSetter: new Set(), + }, + semester: "", + examType: "", + year: "", + }; + } + + // Add the faculty name to the appropriate task + if (appointment.task && groupedByCourse[courseId].tasks[appointment.task]) { + groupedByCourse[courseId].tasks[appointment.task].add(appointment.facultyName); + } + }); + + // Add course details to grouped data + Object.values(groupedByCourse).forEach((group) => { + const course = courses.find((c) => c.courseId === group.courseId); + + if (course) { + group.semester = course.semester; + group.examType = course.scheme; + group.year = course.program; + } + }); + + // Format the consolidated data + const consolidatedData = Object.values(groupedByCourse).map((course, index) => ({ + courseCode: course.courseId, + courseName: course.courseName, + semester: course.semester, + examType: course.examType, + year: course.year, + oralPracticalTeachers: Array.from(course.tasks.oralsPracticals), + assessmentTeachers: Array.from(course.tasks.assessment), + reassessmentTeachers: Array.from(course.tasks.reassessment), + paperSettingTeachers: Array.from(course.tasks.paperSetting), + moderationTeachers: Array.from(course.tasks.moderation), + pwdPaperSettingTeachers: Array.from(course.tasks.pwdPaperSetter), + })); + + res.status(200).json(consolidatedData); + } catch (error) { + console.error("Error fetching course consolidated data:", error); + res.status(500).json({ message: "Failed to fetch course consolidated data" }); + } +}); + module.exports = router;