diff --git a/client/src/App.js b/client/src/App.js index 8659bb8..4b4b0d3 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -14,7 +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"; +import CourseConsolidated from "./Pages/courseConsolidated"; function App() { return ( diff --git a/client/src/Pages/ConsolidatedTable.jsx b/client/src/Pages/ConsolidatedTable.jsx index 264e3a1..2b9018f 100644 --- a/client/src/Pages/ConsolidatedTable.jsx +++ b/client/src/Pages/ConsolidatedTable.jsx @@ -80,7 +80,10 @@ const styles = { } }; + + const ConsolidatedTable = () => { + const [searchQuery, setSearchQuery] = useState(""); // State for search input const [data, setData] = useState([]); const [loading, setLoading] = useState(true); const [currentPage, setCurrentPage] = useState(1); @@ -108,15 +111,21 @@ const ConsolidatedTable = () => { return
Loading...
; } - // Extract unique faculty names - const uniqueTeachers = [...new Set(data.map((row) => row.Name))]; + // Extract unique faculty names and filter based on the search query + const filteredTeachers = [...new Set(data.map((row) => row.Name))].filter( + (teacher) => + teacher.toLowerCase().includes(searchQuery.toLowerCase()) // Filter by search query + ); - // Pagination + // Pagination logic applied to filtered teachers const indexOfLastTable = currentPage * tablesPerPage; const indexOfFirstTable = indexOfLastTable - tablesPerPage; - const currentTeachers = uniqueTeachers.slice(indexOfFirstTable, indexOfLastTable); + const currentTeachers = filteredTeachers.slice( + indexOfFirstTable, + indexOfLastTable + ); - const totalPages = Math.ceil(uniqueTeachers.length / tablesPerPage); + const totalPages = Math.ceil(filteredTeachers.length / tablesPerPage); const handleNextPage = () => { if (currentPage < totalPages) setCurrentPage((prevPage) => prevPage + 1); @@ -132,14 +141,14 @@ const ConsolidatedTable = () => { }; const bulkDownload = () => { - uniqueTeachers.forEach((teacher) => { + filteredTeachers.forEach((teacher) => { const teacherData = data.filter((row) => row.Name === teacher); createExcelFile(teacherData, teacher); }); }; const handleSendEmail = async (teacher, teacherData) => { - const facultyId = teacherData[0].facultyId; + const facultyId = teacherData[0].facultyId; try { const response = await axios.get( `http://localhost:8080/api/faculty/${facultyId}` @@ -176,9 +185,8 @@ const ConsolidatedTable = () => { } }; - // Send emails to all teachers const sendEmailsToAllTeachers = async () => { - for (let teacher of uniqueTeachers) { + for (let teacher of filteredTeachers) { const teacherData = data.filter((row) => row.Name === teacher); await handleSendEmail(teacher, teacherData); // Wait for each email to be sent before proceeding to the next } @@ -187,140 +195,172 @@ const ConsolidatedTable = () => { return ( <> - -
-

- Faculty Tables with Download Options -

- -
- - - -
+ +
+

Faculty Tables with Download Options

-
- {currentTeachers.map((teacher, index) => { - const teacherData = data.filter((row) => row.Name === teacher); - return ( -
-
setExpandedTeacher(expandedTeacher === teacher ? null : teacher)} - > -

{teacher}'s Table

-
- + + +
+ + {/* Search Bar */} +
+ setSearchQuery(e.target.value)} + placeholder="Search for a faculty..." + style={{ + width: "100%", + padding: "10px", + borderRadius: "5px", + border: "1px solid #ccc", + fontSize: "16px", + }} + /> +
+ +
+ {currentTeachers.map((teacher, index) => { + const teacherData = data.filter((row) => row.Name === teacher); + return ( +
+
+ setExpandedTeacher( + expandedTeacher === teacher ? null : teacher + ) + } + > +

- Download {teacher}'s Table - - + {teacher}'s Table +

+
+ + +
-
- {expandedTeacher === teacher && ( - - - - - - - - - - - - - - - - - - - - - - - {teacherData.map((row, idx) => ( - - - - - - - - - - - - - - - - - + {expandedTeacher === teacher && ( +
SemesterCourse CodeCourse NameExam TypeYearMarksNameAffiliation/CollegeHighest QualificationCareer ExperienceOral/PracticalAssessmentReassessmentPaper SettingModerationPwD Paper Setting
{row.semester}{row.courseCode}{row.courseName}{row.examType}{row.year}{row.marks}{row.Name}{row.affiliation}{row.qualification}{row.experience}{row.oralPractical}{row.assessment}{row.reassessment}{row.paperSetting}{row.moderation}{row.pwdPaperSetting}
+ + + + + + + + + + + + + + + + + + - ))} - -
SemesterCourse CodeCourse NameExam TypeYearMarksNameAffiliation/CollegeHighest QualificationCareer ExperienceOral/PracticalAssessmentReassessmentPaper SettingModerationPwD Paper Setting
- )} -
- ); - })} -
+ + + {teacherData.map((row, idx) => ( + + {row.semester} + {row.courseCode} + {row.courseName} + {row.examType} + {row.year} + {row.marks} + {row.Name} + {row.affiliation} + {row.qualification} + {row.experience} + {row.oralPractical} + {row.assessment} + {row.reassessment} + {row.paperSetting} + {row.moderation} + {row.pwdPaperSetting} + + ))} + + + )} +
+ ); + })} +
- {/* Pagination controls */} -
- - - Page {currentPage} of {totalPages} - - + {/* Pagination controls */} +
+ + + Page {currentPage} of {totalPages} + + +
-
); };