diff --git a/client/src/App.css b/client/src/App.css index d87bb11..b599c7c 100644 --- a/client/src/App.css +++ b/client/src/App.css @@ -24,9 +24,6 @@ body { background-color:#ffffff; /* background: linear-gradient(to right, #dab8fc, #afc2ff); */ - display: flex; - align-items: center; - justify-content: center; height: 100vh; } body h1{ @@ -486,3 +483,10 @@ height:auto !important; } } + +.LoginPage { + display: flex; + align-items: center; + justify-content: center; + height: 100vh; +} \ No newline at end of file diff --git a/client/src/App.js b/client/src/App.js index e2242bb..e5c5bc2 100644 --- a/client/src/App.js +++ b/client/src/App.js @@ -15,11 +15,8 @@ import CourseTable from "./Pages/CourseTable"; import GenerateCSV from "./Pages/GenerateCSV"; import ConsolidatedTable from "./Pages/ConsolidatedTable"; - function App() { return ( - - {/* */} }> } /> @@ -34,7 +31,6 @@ function App() { } /> } /> - ); } diff --git a/client/src/Pages/ConsolidatedTable.jsx b/client/src/Pages/ConsolidatedTable.jsx index 7f70b7f..264e3a1 100644 --- a/client/src/Pages/ConsolidatedTable.jsx +++ b/client/src/Pages/ConsolidatedTable.jsx @@ -1,8 +1,84 @@ import React, { useState, useEffect } from "react"; import axios from "axios"; import * as XLSX from "xlsx-js-style"; -import { sendEmail } from "../api"; -import { createExcelBook } from "../api"; +import { sendEmail, createExcelBook } from "../api"; +import Navbar from "./Navbar"; + +const styles = { + header: { + background: '#003366', + color: 'white', + padding: '20px 0', + textAlign: 'center', + fontSize: '24px', + marginBottom: '0', + }, + buttonRow: { + display: 'flex', + justifyContent: 'space-around', + alignItems: 'center', + padding: '10px 0', + margin: '0', + backgroundColor: '#003366', + boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)' + }, + button: { + padding: '10px 20px', + borderRadius: '5px', + color: 'white', + border: 'none', + cursor: 'pointer', + fontSize: '16px', + flex: '1', + }, + bulkDownloadButton: { + backgroundColor: '#3fb5a3', + }, + downloadButton: { + backgroundColor: '#28a745', + }, + emailButton: { + backgroundColor: '#ff6f61', + }, + tableContainer: { + maxHeight: "70vh", + overflowY: "auto", + border: "1px solid #ccc", + padding: "10px", + borderRadius: "5px", + backgroundColor: "#f9f9f9", + marginBottom: "20px", + }, + table: { + width: "100%", + marginTop: "20px", + borderCollapse: "collapse", + }, + th: { + backgroundColor: "#333", + color: "white", + padding: "10px 15px", + }, + td: { + padding: "10px", + textAlign: "left", + borderBottom: "1px solid #ddd", + }, + paginationContainer: { + textAlign: "center", + marginTop: "20px", + }, + paginationButton: { + padding: "10px 15px", + backgroundColor: "#007bff", + color: "white", + borderRadius: "5px", + border: "none", + }, + main: { + width: "100%", + } +}; const ConsolidatedTable = () => { const [data, setData] = useState([]); @@ -63,7 +139,7 @@ const ConsolidatedTable = () => { }; const handleSendEmail = async (teacher, teacherData) => { - const facultyId = teacherData[0].facultyId; // This assumes all rows for a teacher have the same facultyId + const facultyId = teacherData[0].facultyId; try { const response = await axios.get( `http://localhost:8080/api/faculty/${facultyId}` @@ -87,15 +163,15 @@ const ConsolidatedTable = () => { formData.append("file", file); try { - const response = await sendEmail(formData); + const emailResponse = await sendEmail(formData); alert(`Email sent successfully to ${facultyEmail}`); - console.log("Response from server:", response); - } catch (error) { - console.error("Error sending email:", error); + console.log("Response from server:", emailResponse); + } catch (emailError) { + console.error("Error sending email:", emailError); alert("Failed to send email."); } - } catch (error) { - console.error("Error fetching Faculty data:", error); + } catch (facultyError) { + console.error("Error fetching Faculty data:", facultyError); alert("Failed to fetch faculty data."); } }; @@ -110,66 +186,35 @@ const ConsolidatedTable = () => { }; return ( -
-

+ <> + +
+

Faculty Tables with Download Options

- -
+ +
-
-
+
{currentTeachers.map((teacher, index) => { const teacherData = data.filter((row) => row.Name === teacher); return ( @@ -180,93 +225,71 @@ const ConsolidatedTable = () => { justifyContent: "space-between", alignItems: "center", cursor: "pointer", - backgroundColor: "#ffffff", - color: "white", padding: "10px", borderRadius: "5px", + backgroundColor: "#ffffff", + boxShadow: "0 2px 4px rgba(0,0,0,0.1)" }} onClick={() => setExpandedTeacher(expandedTeacher === teacher ? null : teacher)} > -

{teacher}'s Table

+

{teacher}'s Table

{expandedTeacher === teacher && ( - +
- - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + {teacherData.map((row, idx) => ( - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + ))} @@ -278,18 +301,11 @@ const ConsolidatedTable = () => { {/* Pagination controls */} -
+
@@ -299,19 +315,13 @@ const ConsolidatedTable = () => {
+ ); }; diff --git a/client/src/Pages/CourseForm.css b/client/src/Pages/CourseForm.css index e8e4714..aa37fbb 100644 --- a/client/src/Pages/CourseForm.css +++ b/client/src/Pages/CourseForm.css @@ -1,130 +1,99 @@ -/* CourseForm.css */ -.form-container { - max-width: 600px; - margin: 50px auto; - padding: 20px; - border: 1px solid #ccc; - border-radius: 10px; - background-color: #f9f9f9; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +/* General container styles */ +.courseFormContainer { + display: flex ; + justify-content: center ; + align-items: center ; + padding: 20px ; } -h2 { - text-align: center; - color: #333; - margin-bottom: 20px; - font-size: 1.8rem; +.courseFormFormContainer { + background: #f4f4f4 ; + padding: 20px ; + border-radius: 8px ; + box-shadow: 0 4px 8px rgba(0,0,0,0.1) ; + width: 100% ; + max-width: 960px ; } -form { - display: flex; - flex-direction: column; - gap: 15px; +.courseFormHeader { + text-align: center ; + color: #333 ; + grid-column: 1 / -1 ; /* Spans the entire width */ } -label { - font-size: 1rem; - font-weight: bold; - color: #555; - display: flex; - flex-direction: column; +.courseForm { + display: grid ; + grid-template-columns: repeat(3, 1fr) ; /* Creates three columns */ + grid-gap: 20px ; + align-items: start ; } -input[type="text"] { - padding: 10px; - font-size: 1rem; - border: 1px solid #ccc; - border-radius: 5px; - background-color: #fff; - transition: border-color 0.3s ease; +.courseFormLabel { + display: block ; + color: #666 ; + font-weight: bold ; } -input[type="text"]:focus { - border-color: #007bff; - outline: none; +.courseFormInput, .courseFormSelect, .courseFormButton { + width: 100% ; + padding: 8px ; + margin-top: 5px ; + border: 1px solid #ddd ; + border-radius: 4px ; + box-sizing: border-box ; /* Makes sure the padding doesn't affect the final width */ } -button { - padding: 10px 15px; - font-size: 1rem; - font-weight: bold; - color: #fff; - background-color: #007bff; - border: none; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.3s ease; +.courseFormReadOnly { + background: #eee ; + color: #666 ; } -button:hover { - background-color: #0056b3; +.courseFormButton { + padding: 10px 20px ; + background-color: #a71515 ; + color: white ; + border: none ; + border-radius: 4px ; + cursor: pointer ; } -button:active { - background-color: #003d7a; +.courseFormButton:hover { + background-color: #e14a4a ; } -button[type="submit"] { - align-self: center; - width: 50%; +.courseFormErrorMessage { + color: red ; + font-size: 12px ; + grid-column: 1 / -1 ; /* Spans the entire width */ } -.suggestions { - list-style-type: none; - margin: 0; - padding: 0; - border: 1px solid #ccc; - max-height: 150px; - overflow-y: auto; - background: #fff; - position: absolute; - width: 100%; - z-index: 10; +.courseFormErrorInput, .courseFormErrorSelect { + border-color: red ; } -.suggestions li { - padding: 8px; - cursor: pointer; +/* Adjusting list styles for better grid integration */ +.courseFormSuggestions, .courseFormTempList { + list-style: none ; + padding: 0 ; + width: 100% ; + position: absolute ; + z-index: 1000 ; } -.suggestions li:hover { - background-color: #f0f0f0; +.courseFormSuggestionsItem, .courseFormTempListItem { + padding: 8px ; + background-color: #fff ; + border: 1px solid #ddd ; + cursor: pointer ; } -.error-message { - color: red; - font-size: 12px; +.courseFormSuggestionsItem:hover, .courseFormTempListItem:hover { + background-color: #f0f0f0 ; } -.error input { - border-color: red; +.courseFormRemoveFacultyBtn { + background: none ; + border: none ; + color: red ; + cursor: pointer ; } - - -@media (max-width: 768px) { - .form-container { - margin: 20px; - padding: 15px; - } - - h2 { - font-size: 1.5rem; - } - - button[type="submit"] { - width: 100%; - } -} -.remove-faculty-btn { - padding: 0px 0px; - background: none; - border: none; - color: red; - cursor: pointer; - font-size: 16px; - margin-left: 10px; -} - -.remove-faculty-btn:hover { - color: darkred; -} \ No newline at end of file diff --git a/client/src/Pages/CourseForm.jsx b/client/src/Pages/CourseForm.jsx index 1b3490f..b1f5a60 100644 --- a/client/src/Pages/CourseForm.jsx +++ b/client/src/Pages/CourseForm.jsx @@ -2,6 +2,8 @@ import React, { useState, useEffect } from "react"; import { useLocation, useParams, useNavigate } from "react-router-dom"; import { fetchFaculties, saveAppointment, updateCourseStatus } from "../api"; import "./CourseForm.css"; +import "./Navbar.jsx"; +import Navbar from "./Navbar.jsx"; const CourseForm = () => { const { id } = useParams(); @@ -146,156 +148,130 @@ const CourseForm = () => { }; return ( -
-

Course Info

-
- - - {[ - { name: "oralsPracticals", label: "Orals/Practicals" }, - { name: "assessment", label: "Assessment" }, - { name: "reassessment", label: "Reassessment" }, - { name: "paperSetting", label: "Paper Setting" }, - { name: "moderation", label: "Moderation" }, - { name: "pwdPaperSetter", label: "PwD Paper Setter" }, - ].map(({ name, label }) => ( -
- - {tempAssignments[name].length > 0 && ( -
    - {tempAssignments[name].map((faculty, index) => ( -
  • - {faculty.name} - -
  • - ))} -
- )} - {errors[name] && ( - {errors[name]} - )} + + +
- ))} -
- - - - - {errors.examPeriod && ( - {errors.examPeriod} - )}
- - -
+ + + + + ); }; diff --git a/client/src/Pages/CourseTable.css b/client/src/Pages/CourseTable.css index 863b9d5..2dec255 100644 --- a/client/src/Pages/CourseTable.css +++ b/client/src/Pages/CourseTable.css @@ -1,7 +1,7 @@ /* CourseTable.css */ .course-table { - width: 80%; + width: 90vw; margin: 0 auto; padding: 20px; background-color: #f9f9f9; diff --git a/client/src/Pages/CourseTable.jsx b/client/src/Pages/CourseTable.jsx index 9933b3d..c1884b5 100644 --- a/client/src/Pages/CourseTable.jsx +++ b/client/src/Pages/CourseTable.jsx @@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react"; import { useLocation, useNavigate } from "react-router-dom"; import "./CourseTable.css"; import { fetchCourses } from "../api"; +import Navbar from "./Navbar"; const CourseTable = () => { const { state } = useLocation(); @@ -49,6 +50,8 @@ const CourseTable = () => { }; return ( + <> +
SemesterCourse CodeCourse NameExam TypeYearMarksNameAffiliation/CollegeHighest QualificationCareer ExperienceOral/PracticalAssessmentReassessmentPaper SettingModerationPwD Paper SettingSemesterCourse 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}{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}
@@ -73,6 +76,7 @@ const CourseTable = () => { )}
+ ); }; diff --git a/client/src/Pages/FacultyForm.css b/client/src/Pages/FacultyForm.css index 4644429..6c6e4dc 100644 --- a/client/src/Pages/FacultyForm.css +++ b/client/src/Pages/FacultyForm.css @@ -42,7 +42,7 @@ } button { - padding: 12px; + padding: 12px; font-size: 16px; background-color: #4caf50; color: white; diff --git a/client/src/Pages/FacultyForm.jsx b/client/src/Pages/FacultyForm.jsx index c05ce54..b728967 100644 --- a/client/src/Pages/FacultyForm.jsx +++ b/client/src/Pages/FacultyForm.jsx @@ -1,29 +1,33 @@ import React from "react"; import { useParams } from "react-router-dom"; import "./FacultyForm.css"; +import Navbar from "./Navbar"; const FacultyForm = () => { const { id } = useParams(); // Get the faculty ID from the URL params return ( -
-

Faculty Info

-
- - - - -
-
+ <> + +
+

Faculty Info

+
+ + + + +
+
+ ); }; diff --git a/client/src/Pages/FilterPage.css b/client/src/Pages/FilterPage.css index 6643268..6117721 100644 --- a/client/src/Pages/FilterPage.css +++ b/client/src/Pages/FilterPage.css @@ -47,7 +47,7 @@ button { margin: 5px; - padding: 10px 20px; + padding: 10px 20px; cursor: pointer; background-color: #ddd; border: 1px solid #ccc; diff --git a/client/src/Pages/FilterPage.jsx b/client/src/Pages/FilterPage.jsx index 85de54f..5c20a6d 100644 --- a/client/src/Pages/FilterPage.jsx +++ b/client/src/Pages/FilterPage.jsx @@ -2,6 +2,7 @@ import React, { useState } from "react"; import { useNavigate } from "react-router-dom"; import "./FilterPage.css"; import { fetchCourses } from "../api"; +import Navbar from "./Navbar"; const FilterPage = () => { const [formData, setFormData] = useState({ @@ -28,14 +29,14 @@ const FilterPage = () => { alert("Please fill all the fields before applying the filter."); return; } - + try { const filteredCourses = await fetchCourses(formData); console.log(formData); if (filteredCourses.length > 0) { // Save filteredCourses in localStorage localStorage.setItem("filteredCourses", JSON.stringify(filteredCourses)); - + navigate("/courses", { state: { courses: filteredCourses } }); } else { alert("No courses found for the selected filters."); @@ -45,7 +46,7 @@ const FilterPage = () => { alert("Failed to fetch courses. Please try again later."); } }; - + const getSemesters = () => { if (!formData.program) return []; @@ -59,50 +60,53 @@ const FilterPage = () => { }; return ( -
-
- - - - - + <> + +
+
+ + + + + +
-
+ ); }; diff --git a/client/src/Pages/Login.jsx b/client/src/Pages/Login.jsx index 078e583..e9646cd 100644 --- a/client/src/Pages/Login.jsx +++ b/client/src/Pages/Login.jsx @@ -3,6 +3,7 @@ import { Container, Col, Row } from "react-bootstrap"; import { FcGoogle } from "react-icons/fc"; import axios from "axios"; import md5 from "md5"; + import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; diff --git a/client/src/Pages/Navbar.css b/client/src/Pages/Navbar.css index 1d12455..665098c 100644 --- a/client/src/Pages/Navbar.css +++ b/client/src/Pages/Navbar.css @@ -1,44 +1,57 @@ .navbar { background-color: #800000; /* Maroon background */ - height: 50px; /* Navbar height */ + height: 50px; /* Increased navbar height */ width: 100%; /* Full width */ - display: flex; /* Flexbox for alignment */ - justify-content: flex-end; /* Align items to the right */ - align-items: center; /* Center vertically */ - padding: 0 20px; /* Horizontal padding for spacing */ + display: flex; /* Use flexbox for layout */ + justify-content: space-between; /* Space between items */ + align-items: center; /* Align items vertically */ + padding: 0 20px; /* Horizontal padding */ box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); /* Subtle shadow */ - position: fixed; /* Fix the navbar to the top */ + position: fixed; /* Fixed position */ top: 0; - z-index: 1000; /* Place above other elements */ + z-index: 1000; } -.navbar { - box-sizing: border-box; /* Include padding and border in the height calculation */ +.mb-10 { + margin-bottom: 20px; } -* { - margin: 0; - padding: 1000; - box-sizing: border-box; +.navbar-container{ +display: flex; +align-items: center; +justify-content: space-between; +width: 100%; } -.navbar select, -.navbar input { - height: auto; - margin: 0; - padding: 5px 10px; - font-size: 16px; /* Ensure consistent font size */ -} - - -/* User Icon */ .user-icon { - font-size: 30px; /* Icon size */ - color: #fff; /* White color for the icon */ - cursor: pointer; /* Pointer cursor on hover */ - transition: color 0.3s ease-in-out; /* Smooth hover effect */ + font-size: 30px; /* Size of user icon */ + color: #fff; /* Color of the icon */ + margin-left: 20px; /* Space after the icon before the buttons */ + cursor: pointer; /* Cursor type */ + transition: color 0.3s ease-in-out; /* Transition for hover effect */ } .user-icon:hover { - color: #ffcccc; /* Light pink on hover */ + color: #ffcccc; /* Color on hover */ +} + +.button-container { + display: flex; /* Flexbox for buttons */ + gap: 20px; /* Gap between buttons */ +} + +.button-container button { + background-color: #c00000; /* Button color */ + color: white; /* Text color */ + border: none; /* No border */ + + cursor: pointer; /* Cursor type */ + font-size: 12px; /* Font size */ + white-space: nowrap; /* Prevent text wrapping */ + transition: background-color 0.3s; /* Smooth transition for hover */ + padding: 6px 10px; +} + +.button-container button:hover { + background-color: #ffcccc; /* Hover color */ } diff --git a/client/src/Pages/Navbar.jsx b/client/src/Pages/Navbar.jsx index facff03..7830bb6 100644 --- a/client/src/Pages/Navbar.jsx +++ b/client/src/Pages/Navbar.jsx @@ -1,25 +1,24 @@ import React from "react"; import { FaUserCircle } from "react-icons/fa"; -import { useNavigate } from "react-router-dom"; // Import for navigation +import { NavLink } from "react-router-dom"; // Import NavLink for navigation import "./Navbar.css"; // Navbar-specific styles const Navbar = () => { - const navigate = useNavigate(); // Hook for navigation - - const goToConsolidatedPage = () => { - navigate("/consolidated"); // Route to the consolidated page - }; - return ( -
+
- +
+ + Faculty Form + + + Course Form + +
+
+ +
); diff --git a/client/src/Pages/Welcom.jsx b/client/src/Pages/Welcom.jsx index d3cfacd..62a9996 100644 --- a/client/src/Pages/Welcom.jsx +++ b/client/src/Pages/Welcom.jsx @@ -1,25 +1,25 @@ -import React from "react"; -import { useNavigate } from "react-router-dom"; -import "./Welcom.css"; +// import React from "react"; +// import { useNavigate } from "react-router-dom"; +// import "./Welcom.css"; -const Welcom = () => { - const navigate = useNavigate(); +// const Welcom = () => { +// const navigate = useNavigate(); - const goToFilterPage = () => { - navigate("/Filter"); - }; +// const goToFilterPage = () => { +// navigate("/Filter"); +// }; - return ( -
-
-

Welcome

-

You're signed in

-
- -
- ); -}; +// return ( +//
+//
+//

Welcome

+//

You're signed in

+//
+// +//
+// ); +// }; -export default Welcom; +// export default Welcom; diff --git a/client/src/Pages/Welcome.jsx b/client/src/Pages/Welcome.jsx index 0b005ab..1535517 100644 --- a/client/src/Pages/Welcome.jsx +++ b/client/src/Pages/Welcome.jsx @@ -1,28 +1,28 @@ -import React from "react"; -import { useNavigate } from "react-router-dom"; +// import React from "react"; +// import { useNavigate } from "react-router-dom"; -const Welcome = () => { - const navigate = useNavigate(); +// const Welcome = () => { +// const navigate = useNavigate(); - const handleRedirect = () => { - navigate("/AuthpPage"); - }; +// const handleRedirect = () => { +// navigate("/AuthpPage"); +// }; - return ( -
-
-
-

Welcome Page

- -
-
-
- ); -}; +// return ( +//
+//
+//
+//

Welcome Page

+// +//
+//
+//
+// ); +// }; -export default Welcome; +// export default Welcome; diff --git a/client/src/Pages/WelcomeWithFilter.jsx b/client/src/Pages/WelcomeWithFilter.jsx index b489c1d..2c9289f 100644 --- a/client/src/Pages/WelcomeWithFilter.jsx +++ b/client/src/Pages/WelcomeWithFilter.jsx @@ -22,8 +22,6 @@ const WelcomeWithFilter = () => { return (
- {/* Navbar */} - {/* Filter Section */}
diff --git a/client/src/index.css b/client/src/index.css index c3bc051..64a18be 100644 --- a/client/src/index.css +++ b/client/src/index.css @@ -14,4 +14,5 @@ code { #root{ width: 100vw; + height: 100vh; } \ No newline at end of file diff --git a/client/src/index.js b/client/src/index.js index b12d11c..86fca38 100644 --- a/client/src/index.js +++ b/client/src/index.js @@ -1,15 +1,17 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import './index.css'; +// import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import "bootstrap/dist/css/bootstrap.min.css"; +import Navbar from './Pages/Navbar.jsx'; +import { BrowserRouter } from 'react-router-dom'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( - + - + ); reportWebVitals();