├── .DS_Store ├── .gitignore ├── LICENSE ├── README.md ├── client ├── .gitignore ├── package-lock.json ├── package.json ├── public │ ├── _redirects │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── App.js │ ├── components │ │ ├── admin │ │ │ ├── AdminHome.js │ │ │ ├── Body.js │ │ │ ├── Header.js │ │ │ ├── Sidebar.js │ │ │ ├── addAdmin │ │ │ │ ├── AddAdmin.js │ │ │ │ └── Body.js │ │ │ ├── addDepartment │ │ │ │ ├── AddDepartment.js │ │ │ │ └── Body.js │ │ │ ├── addFaculty │ │ │ │ ├── AddFaculty.js │ │ │ │ └── Body.js │ │ │ ├── addStudent │ │ │ │ ├── AddStudent.js │ │ │ │ └── Body.js │ │ │ ├── addSubject │ │ │ │ ├── AddSubject.js │ │ │ │ └── Body.js │ │ │ ├── createNotice │ │ │ │ ├── Body.js │ │ │ │ └── CreateNotice.js │ │ │ ├── deleteAdmin │ │ │ │ ├── Body.js │ │ │ │ └── DeleteAdmin.js │ │ │ ├── deleteDepartment │ │ │ │ ├── Body.js │ │ │ │ └── DeleteDepartment.js │ │ │ ├── deleteFaculty │ │ │ │ ├── Body.js │ │ │ │ └── DeleteFaculty.js │ │ │ ├── deleteStudent │ │ │ │ ├── Body.js │ │ │ │ └── DeleteStudent.js │ │ │ ├── deleteSubject │ │ │ │ ├── Body.js │ │ │ │ └── DeleteSubject.js │ │ │ ├── getFaculty │ │ │ │ ├── Body.js │ │ │ │ └── GetFaculty.js │ │ │ ├── getStudent │ │ │ │ ├── Body.js │ │ │ │ └── GetStudent.js │ │ │ ├── getSubject │ │ │ │ ├── Body.js │ │ │ │ └── GetSubject.js │ │ │ └── profile │ │ │ │ ├── Body.js │ │ │ │ ├── Data.js │ │ │ │ ├── Profile.js │ │ │ │ └── update │ │ │ │ ├── Body.js │ │ │ │ ├── Update.js │ │ │ │ ├── firstTimePassword │ │ │ │ ├── Body.js │ │ │ │ └── FirstTimePassword.js │ │ │ │ └── password │ │ │ │ ├── Body.js │ │ │ │ └── Password.js │ │ ├── faculty │ │ │ ├── Body.js │ │ │ ├── FacultyHome.js │ │ │ ├── Header.js │ │ │ ├── Sidebar.js │ │ │ ├── createTest │ │ │ │ ├── Body.js │ │ │ │ └── CreateTest.js │ │ │ ├── markAttendance │ │ │ │ ├── Body.js │ │ │ │ └── MarkAttendance.js │ │ │ ├── profile │ │ │ │ ├── Body.js │ │ │ │ ├── Data.js │ │ │ │ ├── Profile.js │ │ │ │ └── update │ │ │ │ │ ├── Body.js │ │ │ │ │ ├── Update.js │ │ │ │ │ ├── firstTimePassword │ │ │ │ │ ├── Body.js │ │ │ │ │ └── FirstTimePassword.js │ │ │ │ │ └── password │ │ │ │ │ ├── Body.js │ │ │ │ │ └── Password.js │ │ │ └── uploadMarks │ │ │ │ ├── Body.js │ │ │ │ └── UploadMarks.js │ │ ├── login │ │ │ ├── Login.js │ │ │ ├── adminLogin │ │ │ │ └── AdminLogin.js │ │ │ ├── facultyLogin │ │ │ │ └── FacultyLogin.js │ │ │ └── studentLogin │ │ │ │ └── StudentLogin.js │ │ ├── notices │ │ │ ├── Notice.js │ │ │ └── ShowNotice.js │ │ └── student │ │ │ ├── Body.js │ │ │ ├── Header.js │ │ │ ├── Sidebar.js │ │ │ ├── StudentHome.js │ │ │ ├── attendance │ │ │ ├── Attendance.js │ │ │ └── Body.js │ │ │ ├── profile │ │ │ ├── Body.js │ │ │ ├── Data.js │ │ │ ├── Profile.js │ │ │ └── update │ │ │ │ ├── Body.js │ │ │ │ ├── Update.js │ │ │ │ ├── firstTimePassword │ │ │ │ ├── Body.js │ │ │ │ └── FirstTimePassword.js │ │ │ │ └── password │ │ │ │ ├── Body.js │ │ │ │ └── Password.js │ │ │ ├── subjectList │ │ │ ├── Body.js │ │ │ └── SubjectList.js │ │ │ └── testResult │ │ │ ├── Body.js │ │ │ └── TestResult.js │ ├── index.css │ ├── index.js │ ├── redux │ │ ├── actionTypes.js │ │ ├── actions │ │ │ ├── adminActions.js │ │ │ ├── facultyActions.js │ │ │ └── studentActions.js │ │ ├── api │ │ │ └── index.js │ │ └── reducers │ │ │ ├── adminReducer.js │ │ │ ├── errorReducer.js │ │ │ ├── facultyReducer.js │ │ │ ├── index.js │ │ │ └── studentReducer.js │ └── utils │ │ ├── Spinner.js │ │ └── styles.js └── tailwind.config.js ├── preview ├── Admin.mp4 ├── Faculty.mp4 └── Student.mp4 └── server ├── .env.example ├── .gitignore ├── Procfile ├── controller ├── adminController.js ├── facultyController.js └── studentController.js ├── index.js ├── middleware └── auth.js ├── models ├── admin.js ├── attendance.js ├── department.js ├── faculty.js ├── marks.js ├── notice.js ├── student.js ├── subject.js └── test.js ├── package-lock.json ├── package.json └── routes ├── adminRoutes.js ├── facultyRoutes.js └── studentRoutes.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brogrammer07/College-Erp/0c35a7738b0ff2766b1efd22bdcc6b3a4c3a4eb9/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .env -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Tushar Tomar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # COLLEGE ERP 2 | 3 | College ERP using MERN Stack 4 | 5 | # Setup 6 | 1. Create a .env file in server folder. 7 | 2. Copy the content of .env.example to the newly created .env file 8 | 3. Change the MONGODB_URI to your MongoDB atlas URI 9 | 4. Open a terminal in client folder and run "npm run start" 10 | 5. Open another terminal in server folder and run "npm run start" 11 | 6. Go to "localhost:3000/login/adminlogin" 12 | 7. After successfully running the server, a dummy admin should be created. 13 | 8. Dummy admin username = ADMDUMMY, password = 123 14 | 15 | # TechStack 16 | 17 | 1. Reactjs 18 | 2. Tailwind CSS 19 | 3. MongoDB 20 | 4. Express.js 21 | 5. Redux 22 | 6. Material UI Icons 23 | 7. JWT 24 | 25 | # Features 26 | 27 | 1. Fully Functional Admin, Faculty and Student options 28 | 2. Login feature using JWT 29 | 3. User authentication using JWT 30 | 4. Admin can Update profile details, password in profile section 31 | 5. Admin can add delete or get any student, admin or faculty 32 | 6. Admin can add new departments and subjects 33 | 7. Admin can create new notices 34 | 8. Faculty can Update profile details, password in profile section 35 | 9. Faculty can create new test, mark attendance or students and also upload marks of created tests 36 | 10. Student can Update profile details, password in profile section 37 | 11. Student can check their attendance, marks and subject list 38 | 12. Error display feature available with form validation 39 | 14. Modern UI 40 | 41 | # Features to be added later in the future 42 | 43 | 1. Mobile Responsiveness 44 | 2. Sections other than academics 45 | 3. More freedom to admin while adding new students,admins,faculties or subjects 46 | 47 | # Preview 48 | 49 | Admin 50 | 51 | https://user-images.githubusercontent.com/90241373/156794210-af4db587-1aba-4289-9196-07f2e179d9bb.mp4 52 | 53 |
54 | 55 | Faculty 56 | 57 | https://user-images.githubusercontent.com/90241373/156794428-1a73579c-8116-45dd-bee4-140f3b6de2c8.mp4 58 | 59 |
60 | 61 | Student 62 | 63 | https://user-images.githubusercontent.com/90241373/156794474-1ba1d10e-30c8-4ce7-881b-520d7ab6aec6.mp4 64 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .env 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@emotion/react": "^11.7.1", 7 | "@emotion/styled": "^11.6.0", 8 | "@mui/icons-material": "^5.3.1", 9 | "@mui/material": "^5.4.0", 10 | "@testing-library/jest-dom": "^5.16.2", 11 | "@testing-library/react": "^12.1.2", 12 | "@testing-library/user-event": "^13.5.0", 13 | "axios": "^0.25.0", 14 | "jwt-decode": "^3.1.2", 15 | "react": "^17.0.2", 16 | "react-calendar": "^3.6.0", 17 | "react-dom": "^17.0.2", 18 | "react-file-base64": "^1.0.3", 19 | "react-loader-spinner": "^5.1.2", 20 | "react-redux": "^7.2.6", 21 | "react-router-dom": "^6.2.1", 22 | "react-scripts": "5.0.0", 23 | "react-spinners": "^0.11.0", 24 | "redux": "^4.1.2", 25 | "redux-thunk": "^2.4.1", 26 | "web-vitals": "^2.1.4" 27 | }, 28 | "scripts": { 29 | "start": "react-scripts start", 30 | "build": "react-scripts build", 31 | "test": "react-scripts test", 32 | "eject": "react-scripts eject" 33 | }, 34 | "eslintConfig": { 35 | "extends": [ 36 | "react-app", 37 | "react-app/jest" 38 | ] 39 | }, 40 | "browserslist": { 41 | "production": [ 42 | ">0.2%", 43 | "not dead", 44 | "not op_mini all" 45 | ], 46 | "development": [ 47 | "last 1 chrome version", 48 | "last 1 firefox version", 49 | "last 1 safari version" 50 | ] 51 | }, 52 | "devDependencies": { 53 | "tailwind-scrollbar": "^1.3.1", 54 | "tailwindcss": "^3.0.18" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /client/public/_redirects: -------------------------------------------------------------------------------- 1 | /* /index.html 200 2 | /api/* https://college-erp07.herokuapp.com/:splat 200 -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brogrammer07/College-Erp/0c35a7738b0ff2766b1efd22bdcc6b3a4c3a4eb9/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /client/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brogrammer07/College-Erp/0c35a7738b0ff2766b1efd22bdcc6b3a4c3a4eb9/client/public/logo192.png -------------------------------------------------------------------------------- /client/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brogrammer07/College-Erp/0c35a7738b0ff2766b1efd22bdcc6b3a4c3a4eb9/client/public/logo512.png -------------------------------------------------------------------------------- /client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /client/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /client/src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Routes, Route } from "react-router-dom"; 3 | import AddAdmin from "./components/admin/addAdmin/AddAdmin"; 4 | import AddDepartment from "./components/admin/addDepartment/AddDepartment"; 5 | import AddFaculty from "./components/admin/addFaculty/AddFaculty"; 6 | import AddStudent from "./components/admin/addStudent/AddStudent"; 7 | import AddSubject from "./components/admin/addSubject/AddSubject"; 8 | import AdminHome from "./components/admin/AdminHome"; 9 | 10 | import GetFaculty from "./components/admin/getFaculty/GetFaculty"; 11 | import GetStudent from "./components/admin/getStudent/GetStudent"; 12 | import GetSubject from "./components/admin/getSubject/GetSubject"; 13 | import AdminProfile from "./components/admin/profile/Profile"; 14 | import AdminFirstTimePassword from "./components/admin/profile/update/firstTimePassword/FirstTimePassword"; 15 | import AdminPassword from "./components/admin/profile/update/password/Password"; 16 | 17 | import AdminUpdate from "./components/admin/profile/update/Update"; 18 | import CreateTest from "./components/faculty/createTest/CreateTest"; 19 | import FacultyHome from "./components/faculty/FacultyHome"; 20 | import MarkAttendance from "./components/faculty/markAttendance/MarkAttendance"; 21 | import FacultyProfile from "./components/faculty/profile/Profile"; 22 | import FacultyFirstTimePassword from "./components/faculty/profile/update/firstTimePassword/FirstTimePassword"; 23 | import FacultyPassword from "./components/faculty/profile/update/password/Password"; 24 | import FacultyUpdate from "./components/faculty/profile/update/Update"; 25 | import UploadMarks from "./components/faculty/uploadMarks/UploadMarks"; 26 | import AdminLogin from "./components/login/adminLogin/AdminLogin"; 27 | import FacultyLogin from "./components/login/facultyLogin/FacultyLogin"; 28 | import Login from "./components/login/Login"; 29 | 30 | import StudentLogin from "./components/login/studentLogin/StudentLogin"; 31 | import StudentFirstTimePassword from "./components/student/profile/update/firstTimePassword/FirstTimePassword"; 32 | import StudentHome from "./components/student/StudentHome"; 33 | import StudentProfile from "./components/student/profile/Profile"; 34 | import StudentUpdate from "./components/student/profile/update/Update"; 35 | import StudentPassword from "./components/student/profile/update/password/Password"; 36 | import SubjectList from "./components/student/subjectList/SubjectList"; 37 | import TestResult from "./components/student/testResult/TestResult"; 38 | import Attendance from "./components/student/attendance/Attendance"; 39 | import DeleteAdmin from "./components/admin/deleteAdmin/DeleteAdmin"; 40 | import DeleteDepartment from "./components/admin/deleteDepartment/DeleteDepartment"; 41 | import DeleteFaculty from "./components/admin/deleteFaculty/DeleteFaculty"; 42 | import DeleteStudent from "./components/admin/deleteStudent/DeleteStudent"; 43 | import DeleteSubject from "./components/admin/deleteSubject/DeleteSubject"; 44 | import CreateNotice from "./components/admin/createNotice/CreateNotice"; 45 | 46 | const App = () => { 47 | return ( 48 | 49 | } /> 50 | 51 | {/* Admin */} 52 | 53 | } /> 54 | } /> 55 | } /> 56 | } /> 57 | } /> 58 | } 61 | /> 62 | } /> 63 | } /> 64 | } /> 65 | } /> 66 | } /> 67 | } /> 68 | } /> 69 | } /> 70 | } /> 71 | } /> 72 | } /> 73 | } /> 74 | } /> 75 | } /> 76 | 77 | {/* Faculty */} 78 | 79 | } /> 80 | } /> 81 | } /> 82 | } /> 83 | } /> 84 | } /> 85 | } /> 86 | } /> 87 | } /> 88 | 89 | {/* Student */} 90 | 91 | } /> 92 | } /> 93 | } /> 94 | } /> 95 | } /> 96 | } /> 97 | } /> 98 | } /> 99 | } /> 100 | 101 | ); 102 | }; 103 | 104 | export default App; 105 | -------------------------------------------------------------------------------- /client/src/components/admin/AdminHome.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { 4 | getAllStudent, 5 | getAllFaculty, 6 | getAllAdmin, 7 | getAllDepartment, 8 | getNotice, 9 | } from "../../redux/actions/adminActions"; 10 | import Body from "./Body"; 11 | import Header from "./Header"; 12 | import Sidebar from "./Sidebar"; 13 | 14 | const AdminHome = () => { 15 | const dispatch = useDispatch(); 16 | useEffect(() => { 17 | dispatch(getAllStudent()); 18 | dispatch(getAllFaculty()); 19 | dispatch(getAllAdmin()); 20 | dispatch(getAllDepartment()); 21 | dispatch(getNotice()); 22 | }, [dispatch]); 23 | return ( 24 |
25 |
26 |
27 |
28 | 29 | 30 |
31 |
32 |
33 | ); 34 | }; 35 | 36 | export default AdminHome; 37 | -------------------------------------------------------------------------------- /client/src/components/admin/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import HomeIcon from "@mui/icons-material/Home"; 3 | import Calendar from "react-calendar"; 4 | import EngineeringIcon from "@mui/icons-material/Engineering"; 5 | import BoyIcon from "@mui/icons-material/Boy"; 6 | import SupervisorAccountIcon from "@mui/icons-material/SupervisorAccount"; 7 | import MenuBookIcon from "@mui/icons-material/MenuBook"; 8 | import "react-calendar/dist/Calendar.css"; 9 | import { useSelector } from "react-redux"; 10 | import Notice from "../notices/Notice"; 11 | import ShowNotice from "../notices/ShowNotice"; 12 | import ReplyIcon from "@mui/icons-material/Reply"; 13 | const Body = () => { 14 | const [open, setOpen] = useState(false); 15 | const [openNotice, setOpenNotice] = useState({}); 16 | const notices = useSelector((state) => state.admin.notices.result); 17 | const [value, onChange] = useState(new Date()); 18 | const students = useSelector((state) => state.admin.allStudent); 19 | const faculties = useSelector((state) => state.admin.allFaculty); 20 | const admins = useSelector((state) => state.admin.allAdmin); 21 | const departments = useSelector((state) => state.admin.allDepartment); 22 | 23 | return ( 24 |
25 |
26 |
27 | 28 |

Dashboard

29 |
30 |
31 |
32 |
33 | 37 |
38 |

Faculty

39 |

{faculties?.length}

40 |
41 |
42 |
43 | 47 |
48 |

Student

49 |

{students?.length}

50 |
51 |
52 |
53 | 57 |
58 |

Admin

59 |

{admins?.length}

60 |
61 |
62 |
63 | 67 |
68 |

Department

69 |

{departments?.length}

70 |
71 |
72 |
73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 | {open && ( 82 | setOpen(false)} 84 | className="cursor-pointer" 85 | /> 86 | )} 87 |

88 | Notices 89 |

90 |
91 |
92 | {!open ? ( 93 | notices?.map((notice, idx) => ( 94 |
{ 96 | setOpen(true); 97 | setOpenNotice(notice); 98 | }} 99 | className=""> 100 | 101 |
102 | )) 103 | ) : ( 104 | 105 | )} 106 |
107 |
108 |
109 |
110 |
111 |
112 | ); 113 | }; 114 | 115 | export default Body; 116 | -------------------------------------------------------------------------------- /client/src/components/admin/Header.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Avatar } from "@mui/material"; 3 | import LogoutIcon from "@mui/icons-material/Logout"; 4 | import { useDispatch } from "react-redux"; 5 | import { useNavigate } from "react-router-dom"; 6 | const Header = () => { 7 | const user = JSON.parse(localStorage.getItem("user")); 8 | const dispatch = useDispatch(); 9 | const navigate = useNavigate(); 10 | const logout = () => { 11 | dispatch({ type: "LOGOUT" }); 12 | navigate("/login/adminLogin"); 13 | }; 14 | return ( 15 |
16 |
17 | 22 |

CMS

23 |
24 |

Welcome

25 |
26 | 32 |

{user.result.name.split(" ")[0]}

33 | 37 |
38 |
39 | ); 40 | }; 41 | 42 | export default Header; 43 | -------------------------------------------------------------------------------- /client/src/components/admin/addAdmin/AddAdmin.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const AddAdmin = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default AddAdmin; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/addDepartment/AddDepartment.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "../Header"; 3 | import Sidebar from "../Sidebar"; 4 | import Body from "./Body"; 5 | 6 | const AddDepartment = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default AddDepartment; 21 | -------------------------------------------------------------------------------- /client/src/components/admin/addDepartment/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import AddIcon from "@mui/icons-material/Add"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { addDepartment } from "../../../redux/actions/adminActions"; 5 | import Spinner from "../../../utils/Spinner"; 6 | import { ADD_DEPARTMENT, SET_ERRORS } from "../../../redux/actionTypes"; 7 | import * as classes from "../../../utils/styles"; 8 | const Body = () => { 9 | const dispatch = useDispatch(); 10 | const [loading, setLoading] = useState(false); 11 | const [department, setDepartment] = useState(""); 12 | const store = useSelector((state) => state); 13 | const [error, setError] = useState({}); 14 | useEffect(() => { 15 | if (Object.keys(store.errors).length !== 0) { 16 | setError(store.errors); 17 | } 18 | }, [store.errors]); 19 | 20 | const handleSubmit = (e) => { 21 | e.preventDefault(); 22 | setError({}); 23 | setLoading(true); 24 | dispatch(addDepartment({ department })); 25 | setDepartment(""); 26 | }; 27 | 28 | useEffect(() => { 29 | if (store.errors || store.admin.departmentAdded) { 30 | setLoading(false); 31 | if (store.admin.departmentAdded) { 32 | setDepartment(""); 33 | dispatch({ type: SET_ERRORS, payload: {} }); 34 | dispatch({ type: ADD_DEPARTMENT, payload: false }); 35 | } 36 | } else { 37 | setLoading(true); 38 | } 39 | }, [store.errors, store.admin.departmentAdded]); 40 | 41 | useEffect(() => { 42 | dispatch({ type: SET_ERRORS, payload: {} }); 43 | }, []); 44 | 45 | return ( 46 |
47 |
48 |
49 | 50 |

Add Subject

51 |
52 |
53 |
54 |
55 |
56 |
57 |

Department :

58 | 59 | setDepartment(e.target.value)} 66 | /> 67 |
68 |
69 |
70 |
71 | 74 | 80 |
81 |
82 | {loading && ( 83 | 90 | )} 91 | {(error.departmentError || error.backendError) && ( 92 |

93 | {error.departmentError || error.backendError} 94 |

95 | )} 96 |
97 |
98 |
99 |
100 |
101 | ); 102 | }; 103 | 104 | export default Body; 105 | -------------------------------------------------------------------------------- /client/src/components/admin/addFaculty/AddFaculty.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const AddFaculty = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default AddFaculty; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/addStudent/AddStudent.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const AddStudent = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default AddStudent; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/addSubject/AddSubject.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const AddSubject = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default AddSubject; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/createNotice/CreateNotice.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import Header from "../Header"; 4 | import Sidebar from "../Sidebar"; 5 | import Body from "./Body"; 6 | 7 | const CreateNotice = () => { 8 | return ( 9 |
10 |
11 |
12 |
13 | 14 | 15 |
16 |
17 |
18 | ); 19 | }; 20 | 21 | export default CreateNotice; 22 | -------------------------------------------------------------------------------- /client/src/components/admin/deleteAdmin/DeleteAdmin.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const DeleteAdmin = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default DeleteAdmin; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/deleteDepartment/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import EngineeringIcon from "@mui/icons-material/Engineering"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { 5 | deleteDepartment, 6 | getAllDepartment, 7 | } from "../../../redux/actions/adminActions"; 8 | import Select from "@mui/material/Select"; 9 | import Spinner from "../../../utils/Spinner"; 10 | import * as classes from "../../../utils/styles"; 11 | import MenuItem from "@mui/material/MenuItem"; 12 | import { DELETE_DEPARTMENT, SET_ERRORS } from "../../../redux/actionTypes"; 13 | const Body = () => { 14 | const dispatch = useDispatch(); 15 | const [department, setDepartment] = useState(""); 16 | const [error, setError] = useState({}); 17 | const departments = useSelector((state) => state.admin.allDepartment); 18 | 19 | const [loading, setLoading] = useState(false); 20 | const store = useSelector((state) => state); 21 | 22 | useEffect(() => { 23 | if (Object.keys(store.errors).length !== 0) { 24 | setError(store.errors); 25 | setLoading(false); 26 | } 27 | }, [store.errors]); 28 | 29 | const handleSubmit = (e) => { 30 | e.preventDefault(); 31 | 32 | setLoading(true); 33 | setError({}); 34 | dispatch(deleteDepartment({ department })); 35 | }; 36 | const faculties = useSelector((state) => state.admin.faculties.result); 37 | 38 | useEffect(() => { 39 | if (store.admin.departmentDeleted) { 40 | setLoading(false); 41 | setDepartment(""); 42 | dispatch(getAllDepartment()); 43 | dispatch({ type: DELETE_DEPARTMENT, payload: false }); 44 | } 45 | }, [store.admin.departmentDeleted]); 46 | useEffect(() => { 47 | if (faculties?.length !== 0) { 48 | setLoading(false); 49 | } 50 | }, [faculties]); 51 | 52 | useEffect(() => { 53 | dispatch({ type: SET_ERRORS, payload: {} }); 54 | }, []); 55 | 56 | return ( 57 |
58 |
59 |
60 | 61 |

All Faculty

62 |
63 |
64 |
67 | 68 | 82 | 87 |
88 |
89 |
90 | {loading && ( 91 | 98 | )} 99 | {(error.noFacultyError || error.backendError) && ( 100 |

101 | {error.noFacultyError || error.backendError} 102 |

103 | )} 104 |
105 |
106 |
107 |
108 |
109 | ); 110 | }; 111 | 112 | export default Body; 113 | -------------------------------------------------------------------------------- /client/src/components/admin/deleteDepartment/DeleteDepartment.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const DeleteDepartment = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default DeleteDepartment; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/deleteFaculty/DeleteFaculty.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const DeleteFaculty = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default DeleteFaculty; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/deleteStudent/DeleteStudent.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const DeleteStudent = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default DeleteStudent; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/deleteSubject/DeleteSubject.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const DeleteSubject = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default DeleteSubject; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/getFaculty/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import EngineeringIcon from "@mui/icons-material/Engineering"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { getFaculty } from "../../../redux/actions/adminActions"; 5 | import Select from "@mui/material/Select"; 6 | import Spinner from "../../../utils/Spinner"; 7 | import * as classes from "../../../utils/styles"; 8 | import MenuItem from "@mui/material/MenuItem"; 9 | import { SET_ERRORS } from "../../../redux/actionTypes"; 10 | const Body = () => { 11 | const dispatch = useDispatch(); 12 | const [department, setDepartment] = useState(""); 13 | const [error, setError] = useState({}); 14 | const departments = useSelector((state) => state.admin.allDepartment); 15 | const [search, setSearch] = useState(false); 16 | const [loading, setLoading] = useState(false); 17 | const store = useSelector((state) => state); 18 | 19 | useEffect(() => { 20 | if (Object.keys(store.errors).length !== 0) { 21 | setError(store.errors); 22 | setLoading(false); 23 | } 24 | }, [store.errors]); 25 | 26 | const handleSubmit = (e) => { 27 | e.preventDefault(); 28 | setSearch(true); 29 | setLoading(true); 30 | setError({}); 31 | dispatch(getFaculty({ department })); 32 | }; 33 | const faculties = useSelector((state) => state.admin.faculties.result); 34 | 35 | useEffect(() => { 36 | if (faculties?.length !== 0) { 37 | setLoading(false); 38 | } 39 | }, [faculties]); 40 | 41 | useEffect(() => { 42 | dispatch({ type: SET_ERRORS, payload: {} }); 43 | }, []); 44 | 45 | return ( 46 |
47 |
48 |
49 | 50 |

All Faculty

51 |
52 |
53 |
56 | 57 | 71 | 76 |
77 |
78 |
79 | {loading && ( 80 | 87 | )} 88 | {(error.noFacultyError || error.backendError) && ( 89 |

90 | {error.noFacultyError || error.backendError} 91 |

92 | )} 93 |
94 | 95 | {search && 96 | !loading && 97 | Object.keys(error).length === 0 && 98 | faculties?.length !== 0 && ( 99 |
100 |
101 |

102 | Sr no. 103 |

104 |

105 | Name 106 |

107 |

108 | Username 109 |

110 |

111 | Email 112 |

113 |

114 | Designation 115 |

116 |
117 | {faculties?.map((fac, idx) => ( 118 |
121 |

123 | {idx + 1} 124 |

125 |

127 | {fac.name} 128 |

129 |

131 | {fac.username} 132 |

133 |

135 | {fac.email} 136 |

137 |

139 | {fac.designation} 140 |

141 |
142 | ))} 143 |
144 | )} 145 |
146 |
147 |
148 |
149 | ); 150 | }; 151 | 152 | export default Body; 153 | -------------------------------------------------------------------------------- /client/src/components/admin/getFaculty/GetFaculty.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const GetFaculty = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default GetFaculty; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/getStudent/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import BoyIcon from "@mui/icons-material/Boy"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { getStudent } from "../../../redux/actions/adminActions"; 5 | import { MenuItem, Select } from "@mui/material"; 6 | import Spinner from "../../../utils/Spinner"; 7 | import * as classes from "../../../utils/styles"; 8 | import { SET_ERRORS } from "../../../redux/actionTypes"; 9 | const Body = () => { 10 | const dispatch = useDispatch(); 11 | const [error, setError] = useState({}); 12 | const departments = useSelector((state) => state.admin.allDepartment); 13 | const [loading, setLoading] = useState(false); 14 | const store = useSelector((state) => state); 15 | const [value, setValue] = useState({ 16 | department: "", 17 | year: "", 18 | }); 19 | const [search, setSearch] = useState(false); 20 | 21 | useEffect(() => { 22 | if (Object.keys(store.errors).length !== 0) { 23 | setError(store.errors); 24 | setLoading(false); 25 | } 26 | }, [store.errors]); 27 | 28 | const handleSubmit = (e) => { 29 | e.preventDefault(); 30 | setSearch(true); 31 | setLoading(true); 32 | setError({}); 33 | dispatch(getStudent(value)); 34 | }; 35 | const students = useSelector((state) => state.admin.students.result); 36 | 37 | useEffect(() => { 38 | if (students?.length !== 0) setLoading(false); 39 | }, [students]); 40 | 41 | useEffect(() => { 42 | dispatch({ type: SET_ERRORS, payload: {} }); 43 | }, []); 44 | 45 | return ( 46 |
47 |
48 |
49 | 50 |

All Students

51 |
52 |
53 |
56 | 57 | 73 | 74 | 87 | 92 |
93 |
94 |
95 | {loading && ( 96 | 103 | )} 104 | {(error.noStudentError || error.backendError) && ( 105 |

106 | {error.noStudentError || error.backendError} 107 |

108 | )} 109 |
110 | {search && 111 | !loading && 112 | Object.keys(error).length === 0 && 113 | students?.length !== 0 && ( 114 |
115 |
116 |

117 | Sr no. 118 |

119 |

120 | Name 121 |

122 |

123 | Username 124 |

125 |

126 | Email 127 |

128 |

129 | Section 130 |

131 |

132 | Batch 133 |

134 |
135 | {students?.map((stu, idx) => ( 136 |
139 |

141 | {idx + 1} 142 |

143 |

145 | {stu.name} 146 |

147 |

149 | {stu.username} 150 |

151 |

153 | {stu.email} 154 |

155 |

157 | {stu.section} 158 |

159 |

161 | {stu.batch} 162 |

163 |
164 | ))} 165 |
166 | )} 167 |
168 |
169 |
170 |
171 | ); 172 | }; 173 | 174 | export default Body; 175 | -------------------------------------------------------------------------------- /client/src/components/admin/getStudent/GetStudent.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const GetStudent = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default GetStudent; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/getSubject/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import MenuBookIcon from "@mui/icons-material/MenuBook"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { getSubject } from "../../../redux/actions/adminActions"; 5 | import { MenuItem, Select } from "@mui/material"; 6 | import Spinner from "../../../utils/Spinner"; 7 | import { SET_ERRORS } from "../../../redux/actionTypes"; 8 | import * as classes from "../../../utils/styles"; 9 | 10 | const Body = () => { 11 | const dispatch = useDispatch(); 12 | const [error, setError] = useState({}); 13 | const departments = useSelector((state) => state.admin.allDepartment); 14 | const [loading, setLoading] = useState(false); 15 | const store = useSelector((state) => state); 16 | const [value, setValue] = useState({ 17 | department: "", 18 | year: "", 19 | }); 20 | const [search, setSearch] = useState(false); 21 | 22 | useEffect(() => { 23 | if (Object.keys(store.errors).length !== 0) { 24 | setError(store.errors); 25 | setLoading(false); 26 | } 27 | }, [store.errors]); 28 | 29 | const handleSubmit = (e) => { 30 | e.preventDefault(); 31 | setSearch(true); 32 | setLoading(true); 33 | setError({}); 34 | dispatch(getSubject(value)); 35 | }; 36 | const subjects = useSelector((state) => state.admin.subjects.result); 37 | 38 | useEffect(() => { 39 | if (subjects?.length !== 0) setLoading(false); 40 | }, [subjects]); 41 | 42 | useEffect(() => { 43 | dispatch({ type: SET_ERRORS, payload: {} }); 44 | }, []); 45 | 46 | return ( 47 |
48 |
49 |
50 | 51 |

All Subjects

52 |
53 |
54 |
57 | 58 | 74 | 75 | 88 | 93 |
94 | 95 |
96 |
97 | {loading && ( 98 | 105 | )} 106 | {(error.noSubjectError || error.backendError) && ( 107 |

108 | {error.noSubjectError || error.backendError} 109 |

110 | )} 111 |
112 | {search && 113 | !loading && 114 | Object.keys(error).length === 0 && 115 | subjects?.length !== 0 && ( 116 |
117 |
118 |

119 | Sr no. 120 |

121 |

122 | Subject Code 123 |

124 |

125 | Subject Name 126 |

127 |

128 | Total Lectures 129 |

130 |
131 | {subjects?.map((sub, idx) => ( 132 |
135 |

137 | {idx + 1} 138 |

139 |

141 | {sub.subjectCode} 142 |

143 |

145 | {sub.subjectName} 146 |

147 |

149 | {sub.totalLectures} 150 |

151 |
152 | ))} 153 |
154 | )} 155 |
156 |
157 |
158 |
159 | ); 160 | }; 161 | 162 | export default Body; 163 | -------------------------------------------------------------------------------- /client/src/components/admin/getSubject/GetSubject.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAllDepartment } from "../../../redux/actions/adminActions"; 4 | import Header from "../Header"; 5 | import Sidebar from "../Sidebar"; 6 | import Body from "./Body"; 7 | 8 | const GetSubject = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default GetSubject; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/profile/Body.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import AssignmentIndIcon from "@mui/icons-material/AssignmentInd"; 3 | import SecurityUpdateIcon from "@mui/icons-material/SecurityUpdate"; 4 | import { Avatar } from "@mui/material"; 5 | import Data from "./Data"; 6 | import { useNavigate } from "react-router-dom"; 7 | const Body = () => { 8 | const user = JSON.parse(localStorage.getItem("user")); 9 | const navigate = useNavigate(); 10 | return ( 11 |
12 |
13 |
14 |
15 | 16 |

Profile

17 |
18 |
navigate("/admin/update")} 20 | className="flex space-x-2 cursor-pointer"> 21 | 22 |

Update

23 |
24 |
25 |
26 |
27 | 28 |
29 |
30 |
31 | 32 | 33 | 34 | 35 |
36 |
37 | 38 | 39 | 40 |
41 |
42 |
43 |
44 |
45 | ); 46 | }; 47 | 48 | export default Body; 49 | -------------------------------------------------------------------------------- /client/src/components/admin/profile/Data.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import * as classes from "../../../utils/styles"; 3 | const Data = ({ label, value }) => { 4 | return ( 5 |
6 |

{label} :

7 |

8 | {value} 9 |

10 |
11 | ); 12 | }; 13 | 14 | export default Data; 15 | -------------------------------------------------------------------------------- /client/src/components/admin/profile/Profile.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Body from "./Body"; 3 | import Header from "../Header"; 4 | import Sidebar from "../Sidebar"; 5 | 6 | const Profile = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default Profile; 21 | -------------------------------------------------------------------------------- /client/src/components/admin/profile/update/Update.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import Body from "./Body"; 3 | import Header from "../../Header"; 4 | import Sidebar from "../../Sidebar"; 5 | import { useDispatch } from "react-redux"; 6 | import { getAllDepartment } from "../../../../redux/actions/adminActions"; 7 | 8 | const Update = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default Update; 27 | -------------------------------------------------------------------------------- /client/src/components/admin/profile/update/firstTimePassword/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import VisibilityIcon from "@mui/icons-material/Visibility"; 3 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 4 | import Spinner from "../../../../../utils/Spinner"; 5 | import { useDispatch, useSelector } from "react-redux"; 6 | import { useNavigate } from "react-router-dom"; 7 | import { adminUpdatePassword } from "../../../../../redux/actions/adminActions"; 8 | 9 | const Body = () => { 10 | const [newPassword, setNewPassword] = useState(""); 11 | const [confirmPassword, setConfirmPassword] = useState(""); 12 | const [showPassword, setShowPassword] = useState(false); 13 | const [error, setError] = useState({}); 14 | const [loading, setLoading] = useState(false); 15 | const store = useSelector((state) => state); 16 | const dispatch = useDispatch(); 17 | const navigate = useNavigate(); 18 | const user = JSON.parse(localStorage.getItem("user")); 19 | 20 | useEffect(() => { 21 | if (Object.keys(store.errors).length !== 0) { 22 | setError(store.errors); 23 | setLoading(false); 24 | } 25 | }, [store.errors]); 26 | 27 | const update = (e) => { 28 | e.preventDefault(); 29 | 30 | setLoading(true); 31 | dispatch( 32 | adminUpdatePassword( 33 | { 34 | newPassword: newPassword, 35 | confirmPassword: confirmPassword, 36 | email: user.result.email, 37 | }, 38 | navigate 39 | ) 40 | ); 41 | }; 42 | 43 | useEffect(() => { 44 | if (store.errors) { 45 | setLoading(false); 46 | setNewPassword(""); 47 | setConfirmPassword(""); 48 | } 49 | }, [store.errors]); 50 | 51 | return ( 52 |
53 |
54 |

Update Password

55 |
56 |

New Password

57 |
58 | setNewPassword(e.target.value)} 60 | value={newPassword} 61 | required 62 | type={showPassword ? "text" : "password"} 63 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 64 | placeholder="New Password" 65 | /> 66 | {showPassword ? ( 67 | setShowPassword(!showPassword)} 69 | className="cursor-pointer" 70 | /> 71 | ) : ( 72 | setShowPassword(!showPassword)} 74 | className="cursor-pointer" 75 | /> 76 | )} 77 |
78 |
79 |
80 |

Confirm Password

81 |
82 | setConfirmPassword(e.target.value)} 84 | value={confirmPassword} 85 | required 86 | type={showPassword ? "text" : "password"} 87 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 88 | placeholder="Confirm Password" 89 | /> 90 | {showPassword ? ( 91 | setShowPassword(!showPassword)} 93 | className="cursor-pointer" 94 | /> 95 | ) : ( 96 | setShowPassword(!showPassword)} 98 | className="cursor-pointer" 99 | /> 100 | )} 101 |
102 |
103 | 108 | {loading && ( 109 | 116 | )} 117 | {(error.mismatchError || error.backendError) && ( 118 |

119 | {error.mismatchError || error.backendError} 120 |

121 | )} 122 | 123 |
124 | ); 125 | }; 126 | 127 | export default Body; 128 | -------------------------------------------------------------------------------- /client/src/components/admin/profile/update/firstTimePassword/FirstTimePassword.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Body from "./Body"; 3 | 4 | import Header from "../../../Header"; 5 | 6 | const FirstTimePassword = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 |
14 |
15 |
16 | ); 17 | }; 18 | 19 | export default FirstTimePassword; 20 | -------------------------------------------------------------------------------- /client/src/components/admin/profile/update/password/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import VisibilityIcon from "@mui/icons-material/Visibility"; 3 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 4 | import Spinner from "../../../../../utils/Spinner"; 5 | import { useDispatch, useSelector } from "react-redux"; 6 | import { useNavigate } from "react-router-dom"; 7 | import { adminUpdatePassword } from "../../../../../redux/actions/adminActions"; 8 | import * as classes from "../../../../../utils/styles"; 9 | const Body = () => { 10 | const [newPassword, setNewPassword] = useState(""); 11 | const [confirmPassword, setConfirmPassword] = useState(""); 12 | const [showPassword, setShowPassword] = useState(false); 13 | const [error, setError] = useState({}); 14 | const [loading, setLoading] = useState(false); 15 | const store = useSelector((state) => state); 16 | const dispatch = useDispatch(); 17 | const navigate = useNavigate(); 18 | const user = JSON.parse(localStorage.getItem("user")); 19 | 20 | useEffect(() => { 21 | if (Object.keys(store.errors).length !== 0) { 22 | setError(store.errors); 23 | setLoading(false); 24 | } 25 | }, [store.errors]); 26 | 27 | const update = (e) => { 28 | e.preventDefault(); 29 | 30 | setLoading(true); 31 | dispatch( 32 | adminUpdatePassword( 33 | { 34 | newPassword: newPassword, 35 | confirmPassword: confirmPassword, 36 | email: user.result.email, 37 | }, 38 | navigate 39 | ) 40 | ); 41 | }; 42 | 43 | useEffect(() => { 44 | if (store.errors) { 45 | setLoading(false); 46 | setNewPassword(""); 47 | setConfirmPassword(""); 48 | } 49 | }, [store.errors]); 50 | 51 | return ( 52 |
53 |
54 |
55 | 56 |

Password

57 |
58 | 59 |
60 |
63 |

Update Password

64 |
65 |

New Password

66 |
67 | setNewPassword(e.target.value)} 69 | value={newPassword} 70 | required 71 | type={showPassword ? "text" : "password"} 72 | className="rounded-lg outline-none py-2 placeholder:text-sm" 73 | placeholder="New Password" 74 | /> 75 | {showPassword ? ( 76 | setShowPassword(!showPassword)} 78 | className="cursor-pointer" 79 | /> 80 | ) : ( 81 | setShowPassword(!showPassword)} 83 | className="cursor-pointer" 84 | /> 85 | )} 86 |
87 |
88 |
89 |

90 | Confirm Password 91 |

92 |
93 | setConfirmPassword(e.target.value)} 95 | value={confirmPassword} 96 | required 97 | type={showPassword ? "text" : "password"} 98 | className="rounded-lg outline-none py-2 placeholder:text-sm" 99 | placeholder="Confirm Password" 100 | /> 101 | {showPassword ? ( 102 | setShowPassword(!showPassword)} 104 | className="cursor-pointer" 105 | /> 106 | ) : ( 107 | setShowPassword(!showPassword)} 109 | className="cursor-pointer" 110 | /> 111 | )} 112 |
113 |
114 |
115 | 118 | 124 |
125 | {loading && ( 126 | 133 | )} 134 | {(error.mismatchError || error.backendError) && ( 135 |

136 | {error.mismatchError || error.backendError} 137 |

138 | )} 139 | 140 |
141 |
142 |
143 | ); 144 | }; 145 | 146 | export default Body; 147 | -------------------------------------------------------------------------------- /client/src/components/admin/profile/update/password/Password.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "../../../Header"; 3 | import Sidebar from "../../../Sidebar"; 4 | import Body from "./Body"; 5 | 6 | const Password = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default Password; 21 | -------------------------------------------------------------------------------- /client/src/components/faculty/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import HomeIcon from "@mui/icons-material/Home"; 3 | import Calendar from "react-calendar"; 4 | import EngineeringIcon from "@mui/icons-material/Engineering"; 5 | import BoyIcon from "@mui/icons-material/Boy"; 6 | import SupervisorAccountIcon from "@mui/icons-material/SupervisorAccount"; 7 | import MenuBookIcon from "@mui/icons-material/MenuBook"; 8 | import "react-calendar/dist/Calendar.css"; 9 | import { useSelector } from "react-redux"; 10 | import Notice from "../notices/Notice"; 11 | import ReplyIcon from "@mui/icons-material/Reply"; 12 | import ShowNotice from "../notices/ShowNotice"; 13 | const Body = () => { 14 | const [value, onChange] = useState(new Date()); 15 | const [open, setOpen] = useState(false); 16 | const [openNotice, setOpenNotice] = useState({}); 17 | const notices = useSelector((state) => state.admin.notices.result); 18 | 19 | return ( 20 |
21 |
22 |
23 | 24 |

Dashboard

25 |
26 |
27 |
28 |
29 | 33 |
34 |

Class

35 |

12

36 |
37 |
38 |
39 | 43 |
44 |

Student

45 |

10

46 |
47 |
48 |
49 | 53 |
54 |

Subject

55 |

5

56 |
57 |
58 |
59 | 63 |
64 |

Test

65 |

3

66 |
67 |
68 |
69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 |
77 | {open && ( 78 | setOpen(false)} 80 | className="cursor-pointer" 81 | /> 82 | )} 83 |

84 | Notices 85 |

86 |
87 |
88 | {!open ? ( 89 | notices?.map((notice, idx) => ( 90 |
{ 92 | setOpen(true); 93 | setOpenNotice(notice); 94 | }} 95 | className=""> 96 | 97 |
98 | )) 99 | ) : ( 100 | 101 | )} 102 |
103 |
104 |
105 |
106 |
107 |
108 | ); 109 | }; 110 | 111 | export default Body; 112 | -------------------------------------------------------------------------------- /client/src/components/faculty/FacultyHome.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getNotice } from "../../redux/actions/adminActions"; 4 | import Body from "./Body"; 5 | import Header from "./Header"; 6 | import Sidebar from "./Sidebar"; 7 | 8 | const FacultyHome = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getNotice()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default FacultyHome; 27 | -------------------------------------------------------------------------------- /client/src/components/faculty/Header.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Avatar } from "@mui/material"; 3 | import LogoutIcon from "@mui/icons-material/Logout"; 4 | import { useDispatch } from "react-redux"; 5 | import { useNavigate } from "react-router-dom"; 6 | const Header = () => { 7 | const user = JSON.parse(localStorage.getItem("user")); 8 | const dispatch = useDispatch(); 9 | const navigate = useNavigate(); 10 | const logout = () => { 11 | dispatch({ type: "LOGOUT" }); 12 | navigate("/login/facultylogin"); 13 | }; 14 | return ( 15 |
16 |
17 | 22 |

CMS

23 |
24 |

Welcome

25 |
26 | 32 |

{user.result.name.split(" ")[0]}

33 | 37 |
38 |
39 | ); 40 | }; 41 | 42 | export default Header; 43 | -------------------------------------------------------------------------------- /client/src/components/faculty/Sidebar.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { NavLink, useNavigate } from "react-router-dom"; 3 | import HomeIcon from "@mui/icons-material/Home"; 4 | import AssignmentIndIcon from "@mui/icons-material/AssignmentInd"; 5 | import EngineeringIcon from "@mui/icons-material/Engineering"; 6 | import AddIcon from "@mui/icons-material/Add"; 7 | import { useDispatch } from "react-redux"; 8 | import decode from "jwt-decode"; 9 | const isNotActiveStyle = 10 | "flex items-center px-5 gap-3 text-gray-500 hover:text-black transition-all duration-200 ease-in-out capitalize hover:bg-gray-200 py-2 my-1"; 11 | const isActiveStyle = 12 | "flex items-center px-5 gap-3 text-blue-600 transition-all duration-200 ease-in-out capitalize hover:bg-gray-200 py-2 my-1"; 13 | 14 | const Sidebar = () => { 15 | const [user, setUser] = useState(JSON.parse(localStorage.getItem("user"))); 16 | const dispatch = useDispatch(); 17 | const navigate = useNavigate(); 18 | const logout = () => { 19 | alert("OOPS! Your session expired. Please Login again"); 20 | dispatch({ type: "LOGOUT" }); 21 | navigate("/login/facultylogin"); 22 | }; 23 | useEffect(() => { 24 | const token = user?.token; 25 | 26 | if (token) { 27 | const decodedToken = decode(token); 28 | if (decodedToken.exp * 1000 < new Date().getTime()) logout(); 29 | } 30 | 31 | setUser(JSON.parse(localStorage.getItem("faculty"))); 32 | }, [navigate]); 33 | return ( 34 |
35 |
36 |
37 | 40 | isActive ? isActiveStyle : isNotActiveStyle 41 | }> 42 | 43 |

Dashboard

44 |
45 | 48 | isActive ? isActiveStyle : isNotActiveStyle 49 | }> 50 | 51 |

Profile

52 |
53 |
54 |
55 | 58 | isActive ? isActiveStyle : isNotActiveStyle 59 | }> 60 | 61 |

Create Test

62 |
63 | 66 | isActive ? isActiveStyle : isNotActiveStyle 67 | }> 68 | 69 |

Upload Marks

70 |
71 |
72 |
73 | 76 | isActive ? isActiveStyle : isNotActiveStyle 77 | }> 78 | 79 |

Mark Attendance

80 |
81 |
82 |
83 |
84 | ); 85 | }; 86 | 87 | export default Sidebar; 88 | -------------------------------------------------------------------------------- /client/src/components/faculty/createTest/CreateTest.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Body from "./Body"; 3 | import Header from "../Header"; 4 | import Sidebar from "../Sidebar"; 5 | 6 | const CreateTest = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default CreateTest; 21 | -------------------------------------------------------------------------------- /client/src/components/faculty/markAttendance/MarkAttendance.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import Body from "./Body"; 3 | import Header from "../Header"; 4 | import Sidebar from "../Sidebar"; 5 | import { useDispatch } from "react-redux"; 6 | import { 7 | getAllDepartment, 8 | getAllSubject, 9 | } from "../../../redux/actions/adminActions"; 10 | 11 | const MarkAttendance = () => { 12 | const dispatch = useDispatch(); 13 | useEffect(() => { 14 | dispatch(getAllDepartment()); 15 | }, [dispatch]); 16 | return ( 17 |
18 |
19 |
20 |
21 | 22 | 23 |
24 |
25 |
26 | ); 27 | }; 28 | 29 | export default MarkAttendance; 30 | -------------------------------------------------------------------------------- /client/src/components/faculty/profile/Body.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import AssignmentIndIcon from "@mui/icons-material/AssignmentInd"; 3 | import SecurityUpdateIcon from "@mui/icons-material/SecurityUpdate"; 4 | import { Avatar } from "@mui/material"; 5 | import Data from "./Data"; 6 | import { useNavigate } from "react-router-dom"; 7 | const Body = () => { 8 | const user = JSON.parse(localStorage.getItem("user")); 9 | const navigate = useNavigate(); 10 | return ( 11 |
12 |
13 |
14 |
15 | 16 |

Profile

17 |
18 |
navigate("/faculty/update")} 20 | className="flex space-x-2 cursor-pointer"> 21 | 22 |

Update

23 |
24 |
25 |
26 |
27 | 28 |
29 |
30 |
31 | 32 | 33 | 34 | 35 |
36 |
37 | 38 | 39 | 40 | 41 |
42 |
43 |
44 |
45 |
46 | ); 47 | }; 48 | 49 | export default Body; 50 | -------------------------------------------------------------------------------- /client/src/components/faculty/profile/Data.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import * as classes from "../../../utils/styles"; 3 | const Data = ({ label, value }) => { 4 | return ( 5 |
6 |

{label} :

7 |

8 | {value} 9 |

10 |
11 | ); 12 | }; 13 | 14 | export default Data; 15 | -------------------------------------------------------------------------------- /client/src/components/faculty/profile/Profile.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Body from "./Body"; 3 | import Header from "../Header"; 4 | import Sidebar from "../Sidebar"; 5 | 6 | const Profile = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default Profile; 21 | -------------------------------------------------------------------------------- /client/src/components/faculty/profile/update/Update.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import Body from "./Body"; 3 | import Header from "../../Header"; 4 | import Sidebar from "../../Sidebar"; 5 | import { useDispatch } from "react-redux"; 6 | import { getAllDepartment } from "../../../../redux/actions/adminActions"; 7 | 8 | const Update = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default Update; 27 | -------------------------------------------------------------------------------- /client/src/components/faculty/profile/update/firstTimePassword/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import VisibilityIcon from "@mui/icons-material/Visibility"; 3 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 4 | import Spinner from "../../../../../utils/Spinner"; 5 | import { useDispatch, useSelector } from "react-redux"; 6 | import { useNavigate } from "react-router-dom"; 7 | import { facultyUpdatePassword } from "../../../../../redux/actions/facultyActions"; 8 | 9 | const Body = () => { 10 | const [newPassword, setNewPassword] = useState(""); 11 | const [confirmPassword, setConfirmPassword] = useState(""); 12 | const [showPassword, setShowPassword] = useState(false); 13 | const [error, setError] = useState({}); 14 | const [loading, setLoading] = useState(false); 15 | const store = useSelector((state) => state); 16 | const dispatch = useDispatch(); 17 | const navigate = useNavigate(); 18 | const user = JSON.parse(localStorage.getItem("user")); 19 | 20 | useEffect(() => { 21 | if (Object.keys(store.errors).length !== 0) { 22 | setError(store.errors); 23 | setLoading(false); 24 | } 25 | }, [store.errors]); 26 | 27 | const update = (e) => { 28 | e.preventDefault(); 29 | 30 | setLoading(true); 31 | dispatch( 32 | facultyUpdatePassword( 33 | { 34 | newPassword: newPassword, 35 | confirmPassword: confirmPassword, 36 | email: user.result.email, 37 | }, 38 | navigate 39 | ) 40 | ); 41 | }; 42 | 43 | useEffect(() => { 44 | if (store.errors) { 45 | setLoading(false); 46 | setNewPassword(""); 47 | setConfirmPassword(""); 48 | } 49 | }, [store.errors]); 50 | 51 | return ( 52 |
53 |
54 |

Update Password

55 |
56 |

New Password

57 |
58 | setNewPassword(e.target.value)} 60 | value={newPassword} 61 | required 62 | type={showPassword ? "text" : "password"} 63 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 64 | placeholder="New Password" 65 | /> 66 | {showPassword ? ( 67 | setShowPassword(!showPassword)} 69 | className="cursor-pointer" 70 | /> 71 | ) : ( 72 | setShowPassword(!showPassword)} 74 | className="cursor-pointer" 75 | /> 76 | )} 77 |
78 |
79 |
80 |

Confirm Password

81 |
82 | setConfirmPassword(e.target.value)} 84 | value={confirmPassword} 85 | required 86 | type={showPassword ? "text" : "password"} 87 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 88 | placeholder="Confirm Password" 89 | /> 90 | {showPassword ? ( 91 | setShowPassword(!showPassword)} 93 | className="cursor-pointer" 94 | /> 95 | ) : ( 96 | setShowPassword(!showPassword)} 98 | className="cursor-pointer" 99 | /> 100 | )} 101 |
102 |
103 | 108 | {loading && ( 109 | 116 | )} 117 | {(error.mismatchError || error.backendError) && ( 118 |

119 | {error.mismatchError || error.backendError} 120 |

121 | )} 122 | 123 |
124 | ); 125 | }; 126 | 127 | export default Body; 128 | -------------------------------------------------------------------------------- /client/src/components/faculty/profile/update/firstTimePassword/FirstTimePassword.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Body from "./Body"; 3 | 4 | import Header from "../../../Header"; 5 | 6 | const FirstTimePassword = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 |
14 |
15 |
16 | ); 17 | }; 18 | 19 | export default FirstTimePassword; 20 | -------------------------------------------------------------------------------- /client/src/components/faculty/profile/update/password/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import VisibilityIcon from "@mui/icons-material/Visibility"; 3 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 4 | import Spinner from "../../../../../utils/Spinner"; 5 | import { useDispatch, useSelector } from "react-redux"; 6 | import { useNavigate } from "react-router-dom"; 7 | import { adminUpdatePassword } from "../../../../../redux/actions/adminActions"; 8 | import * as classes from "../../../../../utils/styles"; 9 | import { facultyUpdatePassword } from "../../../../../redux/actions/facultyActions"; 10 | const Body = () => { 11 | const [newPassword, setNewPassword] = useState(""); 12 | const [confirmPassword, setConfirmPassword] = useState(""); 13 | const [showPassword, setShowPassword] = useState(false); 14 | const [error, setError] = useState({}); 15 | const [loading, setLoading] = useState(false); 16 | const store = useSelector((state) => state); 17 | const dispatch = useDispatch(); 18 | const navigate = useNavigate(); 19 | const user = JSON.parse(localStorage.getItem("user")); 20 | 21 | useEffect(() => { 22 | if (Object.keys(store.errors).length !== 0) { 23 | setError(store.errors); 24 | setLoading(false); 25 | } 26 | }, [store.errors]); 27 | 28 | const update = (e) => { 29 | e.preventDefault(); 30 | 31 | setLoading(true); 32 | dispatch( 33 | facultyUpdatePassword( 34 | { 35 | newPassword: newPassword, 36 | confirmPassword: confirmPassword, 37 | email: user.result.email, 38 | }, 39 | navigate 40 | ) 41 | ); 42 | }; 43 | 44 | useEffect(() => { 45 | if (store.errors) { 46 | setLoading(false); 47 | setNewPassword(""); 48 | setConfirmPassword(""); 49 | } 50 | }, [store.errors]); 51 | 52 | return ( 53 |
54 |
55 |
56 | 57 |

Password

58 |
59 | 60 |
61 |
64 |

Update Password

65 |
66 |

New Password

67 |
68 | setNewPassword(e.target.value)} 70 | value={newPassword} 71 | required 72 | type={showPassword ? "text" : "password"} 73 | className="rounded-lg outline-none py-2 placeholder:text-sm" 74 | placeholder="New Password" 75 | /> 76 | {showPassword ? ( 77 | setShowPassword(!showPassword)} 79 | className="cursor-pointer" 80 | /> 81 | ) : ( 82 | setShowPassword(!showPassword)} 84 | className="cursor-pointer" 85 | /> 86 | )} 87 |
88 |
89 |
90 |

91 | Confirm Password 92 |

93 |
94 | setConfirmPassword(e.target.value)} 96 | value={confirmPassword} 97 | required 98 | type={showPassword ? "text" : "password"} 99 | className="rounded-lg outline-none py-2 placeholder:text-sm" 100 | placeholder="Confirm Password" 101 | /> 102 | {showPassword ? ( 103 | setShowPassword(!showPassword)} 105 | className="cursor-pointer" 106 | /> 107 | ) : ( 108 | setShowPassword(!showPassword)} 110 | className="cursor-pointer" 111 | /> 112 | )} 113 |
114 |
115 |
116 | 119 | 125 |
126 | {loading && ( 127 | 134 | )} 135 | {(error.mismatchError || error.backendError) && ( 136 |

137 | {error.mismatchError || error.backendError} 138 |

139 | )} 140 | 141 |
142 |
143 |
144 | ); 145 | }; 146 | 147 | export default Body; 148 | -------------------------------------------------------------------------------- /client/src/components/faculty/profile/update/password/Password.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "../../../Header"; 3 | import Sidebar from "../../../Sidebar"; 4 | import Body from "./Body"; 5 | 6 | const Password = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default Password; 21 | -------------------------------------------------------------------------------- /client/src/components/faculty/uploadMarks/UploadMarks.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Body from "./Body"; 3 | import Header from "../Header"; 4 | import Sidebar from "../Sidebar"; 5 | 6 | const UploadMarks = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default UploadMarks; 21 | -------------------------------------------------------------------------------- /client/src/components/login/Login.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Link } from "react-router-dom"; 3 | const Login = () => { 4 | return ( 5 |
13 |
14 |

15 | ABC Institute of Technology 16 |

17 |
18 |
19 |

Faculty

20 | 21 | 25 | Login 26 | 27 |
28 |
29 |

Student

30 | 34 | Login 35 | 36 |
37 |
38 |
39 |
40 | ); 41 | }; 42 | 43 | export default Login; 44 | -------------------------------------------------------------------------------- /client/src/components/login/adminLogin/AdminLogin.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { useNavigate } from "react-router"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { adminSignIn } from "../../../redux/actions/adminActions"; 5 | import VisibilityIcon from "@mui/icons-material/Visibility"; 6 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 7 | import Spinner from "../../../utils/Spinner"; 8 | 9 | const AdminLogin = () => { 10 | const [translate, setTranslate] = useState(false); 11 | const [username, setUsername] = useState(""); 12 | const [password, setPassword] = useState(""); 13 | const [showPassword, setShowPassword] = useState(false); 14 | const [loading, setLoading] = useState(false); 15 | const dispatch = useDispatch(); 16 | const navigate = useNavigate(); 17 | const store = useSelector((state) => state); 18 | const [error, setError] = useState({}); 19 | useEffect(() => { 20 | setTimeout(() => { 21 | setTranslate(true); 22 | }, 1000); 23 | }, []); 24 | 25 | useEffect(() => { 26 | if (store.errors) { 27 | setError(store.errors); 28 | } 29 | }, [store.errors]); 30 | 31 | const login = (e) => { 32 | e.preventDefault(); 33 | setLoading(true); 34 | dispatch(adminSignIn({ username: username, password: password }, navigate)); 35 | }; 36 | 37 | useEffect(() => { 38 | if (store.errors) { 39 | setLoading(false); 40 | setUsername(""); 41 | setPassword(""); 42 | } 43 | }, [store.errors]); 44 | return ( 45 |
46 |
47 |
51 |

52 | Admin 53 |
54 | Login 55 |

56 |
57 |
64 |

Admin

65 |
66 |

Username

67 |
68 | setUsername(e.target.value)} 70 | value={username} 71 | type="text" 72 | required 73 | className="bg-[#515966] text-white px-2 outline-none py-2 rounded-lg placeholder:text-sm" 74 | placeholder="Username" 75 | /> 76 |
77 |
78 |
79 |

Password

80 |
81 | setPassword(e.target.value)} 83 | value={password} 84 | required 85 | type={showPassword ? "text" : "password"} 86 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 87 | placeholder="Password" 88 | /> 89 | {showPassword ? ( 90 | setShowPassword(!showPassword)} 92 | className="cursor-pointer" 93 | /> 94 | ) : ( 95 | setShowPassword(!showPassword)} 97 | className="cursor-pointer" 98 | /> 99 | )} 100 |
101 |
102 | 107 | {loading && ( 108 | 115 | )} 116 | {(error.usernameError || error.passwordError) && ( 117 |

118 | {error.usernameError || error.passwordError} 119 |

120 | )} 121 | 122 |
123 |
124 | ); 125 | }; 126 | 127 | export default AdminLogin; 128 | -------------------------------------------------------------------------------- /client/src/components/login/facultyLogin/FacultyLogin.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { useNavigate } from "react-router"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { signin } from "../../../redux/actions/adminActions"; 5 | import VisibilityIcon from "@mui/icons-material/Visibility"; 6 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 7 | import Spinner from "../../../utils/Spinner"; 8 | import { facultySignIn } from "../../../redux/actions/facultyActions"; 9 | 10 | const FacultyLogin = () => { 11 | const [translate, setTranslate] = useState(false); 12 | const [username, setUsername] = useState(""); 13 | const [password, setPassword] = useState(""); 14 | const [showPassword, setShowPassword] = useState(false); 15 | const [loading, setLoading] = useState(false); 16 | const dispatch = useDispatch(); 17 | const navigate = useNavigate(); 18 | const store = useSelector((state) => state); 19 | const [error, setError] = useState({}); 20 | useEffect(() => { 21 | setTimeout(() => { 22 | setTranslate(true); 23 | }, 1000); 24 | }, []); 25 | 26 | useEffect(() => { 27 | if (store.errors) { 28 | setError(store.errors); 29 | } 30 | }, [store.errors]); 31 | 32 | const login = (e) => { 33 | e.preventDefault(); 34 | setLoading(true); 35 | dispatch( 36 | facultySignIn({ username: username, password: password }, navigate) 37 | ); 38 | }; 39 | 40 | useEffect(() => { 41 | if (store.errors) { 42 | setLoading(false); 43 | setUsername(""); 44 | setPassword(""); 45 | } 46 | }, [store.errors]); 47 | return ( 48 |
49 |
50 |
54 |

55 | Faculty 56 |
57 | Login 58 |

59 |
60 |
67 |

Faculty

68 |
69 |

Username

70 |
71 | setUsername(e.target.value)} 73 | value={username} 74 | type="text" 75 | required 76 | className="bg-[#515966] text-white px-2 outline-none py-2 rounded-lg placeholder:text-sm" 77 | placeholder="Username" 78 | /> 79 |
80 |
81 |
82 |

Password

83 |
84 | setPassword(e.target.value)} 86 | value={password} 87 | required 88 | type={showPassword ? "text" : "password"} 89 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 90 | placeholder="Password" 91 | /> 92 | {showPassword ? ( 93 | setShowPassword(!showPassword)} 95 | className="cursor-pointer" 96 | /> 97 | ) : ( 98 | setShowPassword(!showPassword)} 100 | className="cursor-pointer" 101 | /> 102 | )} 103 |
104 |
105 | 110 | {loading && ( 111 | 118 | )} 119 | {(error.usernameError || error.passwordError) && ( 120 |

121 | {error.usernameError || error.passwordError} 122 |

123 | )} 124 | 125 |
126 |
127 | ); 128 | }; 129 | 130 | export default FacultyLogin; 131 | -------------------------------------------------------------------------------- /client/src/components/login/studentLogin/StudentLogin.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { useNavigate } from "react-router"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import VisibilityIcon from "@mui/icons-material/Visibility"; 5 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 6 | import Spinner from "../../../utils/Spinner"; 7 | import { studentSignIn } from "../../../redux/actions/studentActions"; 8 | 9 | const StudentLogin = () => { 10 | const [translate, setTranslate] = useState(false); 11 | const [username, setUsername] = useState(""); 12 | const [password, setPassword] = useState(""); 13 | const [showPassword, setShowPassword] = useState(false); 14 | const [loading, setLoading] = useState(false); 15 | const dispatch = useDispatch(); 16 | const navigate = useNavigate(); 17 | const store = useSelector((state) => state); 18 | const [error, setError] = useState({}); 19 | useEffect(() => { 20 | setTimeout(() => { 21 | setTranslate(true); 22 | }, 1000); 23 | }, []); 24 | 25 | useEffect(() => { 26 | if (store.errors) { 27 | setError(store.errors); 28 | } 29 | }, [store.errors]); 30 | 31 | const login = (e) => { 32 | e.preventDefault(); 33 | setLoading(true); 34 | dispatch( 35 | studentSignIn({ username: username, password: password }, navigate) 36 | ); 37 | }; 38 | 39 | useEffect(() => { 40 | if (store.errors) { 41 | setLoading(false); 42 | setUsername(""); 43 | setPassword(""); 44 | } 45 | }, [store.errors]); 46 | return ( 47 |
48 |
49 |
53 |

54 | Student 55 |
56 | Login 57 |

58 |
59 |
66 |

Student

67 |
68 |

Username

69 |
70 | setUsername(e.target.value)} 72 | value={username} 73 | type="text" 74 | required 75 | className="bg-[#515966] text-white px-2 outline-none py-2 rounded-lg placeholder:text-sm" 76 | placeholder="Username" 77 | /> 78 |
79 |
80 |
81 |

Password

82 |
83 | setPassword(e.target.value)} 85 | value={password} 86 | required 87 | type={showPassword ? "text" : "password"} 88 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 89 | placeholder="Password" 90 | /> 91 | {showPassword ? ( 92 | setShowPassword(!showPassword)} 94 | className="cursor-pointer" 95 | /> 96 | ) : ( 97 | setShowPassword(!showPassword)} 99 | className="cursor-pointer" 100 | /> 101 | )} 102 |
103 |
104 | 109 | {loading && ( 110 | 117 | )} 118 | {(error.usernameError || error.passwordError) && ( 119 |

120 | {error.usernameError || error.passwordError} 121 |

122 | )} 123 | 124 |
125 |
126 | ); 127 | }; 128 | 129 | export default StudentLogin; 130 | -------------------------------------------------------------------------------- /client/src/components/notices/Notice.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | const Notice = ({ idx, notice, notFor }) => { 4 | return ( 5 | notFor !== notice.noticeFor && ( 6 |
7 | ⚫ 8 |

9 | {notice.topic} 10 | {notice.topic} 11 | {notice.topic} 12 | {notice.topic} 13 | {notice.topic} 14 | {notice.topic} 15 |

16 |

17 | {notice.content} 18 |

19 |
20 | ) 21 | ); 22 | }; 23 | 24 | export default Notice; 25 | -------------------------------------------------------------------------------- /client/src/components/notices/ShowNotice.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | const ShowNotice = ({ notice }) => { 4 | return ( 5 |
6 |
7 |

8 | From: 9 | {notice.from} 10 |

11 |

{notice.date}

12 |
13 |

{notice.topic}

14 |

15 | {notice.content} 16 |

17 |
18 | ); 19 | }; 20 | 21 | export default ShowNotice; 22 | -------------------------------------------------------------------------------- /client/src/components/student/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import HomeIcon from "@mui/icons-material/Home"; 3 | import Calendar from "react-calendar"; 4 | import EngineeringIcon from "@mui/icons-material/Engineering"; 5 | import BoyIcon from "@mui/icons-material/Boy"; 6 | import SupervisorAccountIcon from "@mui/icons-material/SupervisorAccount"; 7 | import MenuBookIcon from "@mui/icons-material/MenuBook"; 8 | import "react-calendar/dist/Calendar.css"; 9 | import ShowNotice from "../notices/ShowNotice"; 10 | import { useSelector } from "react-redux"; 11 | import ReplyIcon from "@mui/icons-material/Reply"; 12 | import Notice from "../notices/Notice"; 13 | const Body = () => { 14 | const [open, setOpen] = useState(false); 15 | const [openNotice, setOpenNotice] = useState({}); 16 | const notices = useSelector((state) => state.admin.notices.result); 17 | const testResult = useSelector((state) => state.student.testResult.result); 18 | const attendance = useSelector((state) => state.student.attendance.result); 19 | const user = JSON.parse(localStorage.getItem("user")); 20 | const subjects = useSelector((state) => state.admin.subjects.result); 21 | var totalAttendance = 0; 22 | console.log(attendance); 23 | 24 | attendance?.map((att) => (totalAttendance += att.attended)); 25 | 26 | const [value, onChange] = useState(new Date()); 27 | 28 | return ( 29 |
30 |
31 |
32 | 33 |

Dashboard

34 |
35 |
36 |
37 |
38 | 42 |
43 |

Subjects

44 |

{subjects?.length}

45 |
46 |
47 |
48 | 52 |
53 |

Test

54 |

{testResult?.length}

55 |
56 |
57 |
58 | 62 |
63 |

Attendance

64 |

{totalAttendance}

65 |
66 |
67 |
68 | 72 |
73 |

Year

74 |

{user.result.year}

75 |
76 |
77 |
78 |
79 |
80 |
81 | 82 |
83 |
84 |
85 |
86 | {open && ( 87 | setOpen(false)} 89 | className="cursor-pointer" 90 | /> 91 | )} 92 |

93 | Notices 94 |

95 |
96 |
97 | {!open ? ( 98 | notices?.map((notice, idx) => ( 99 |
{ 101 | setOpen(true); 102 | setOpenNotice(notice); 103 | }} 104 | className=""> 105 | 106 |
107 | )) 108 | ) : ( 109 | 110 | )} 111 |
112 |
113 |
114 |
115 |
116 |
117 | ); 118 | }; 119 | 120 | export default Body; 121 | -------------------------------------------------------------------------------- /client/src/components/student/Header.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Avatar } from "@mui/material"; 3 | import LogoutIcon from "@mui/icons-material/Logout"; 4 | import { useDispatch } from "react-redux"; 5 | import { useNavigate } from "react-router-dom"; 6 | const Header = () => { 7 | const user = JSON.parse(localStorage.getItem("user")); 8 | const dispatch = useDispatch(); 9 | const navigate = useNavigate(); 10 | const logout = () => { 11 | dispatch({ type: "LOGOUT" }); 12 | navigate("/login/studentlogin"); 13 | }; 14 | return ( 15 |
16 |
17 | 22 |

CMS

23 |
24 |

Welcome

25 |
26 | 32 |

{user.result.name.split(" ")[0]}

33 | 37 |
38 |
39 | ); 40 | }; 41 | 42 | export default Header; 43 | -------------------------------------------------------------------------------- /client/src/components/student/Sidebar.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { NavLink, useNavigate } from "react-router-dom"; 3 | import HomeIcon from "@mui/icons-material/Home"; 4 | import AssignmentIndIcon from "@mui/icons-material/AssignmentInd"; 5 | import EngineeringIcon from "@mui/icons-material/Engineering"; 6 | import AddIcon from "@mui/icons-material/Add"; 7 | import { useDispatch } from "react-redux"; 8 | import decode from "jwt-decode"; 9 | const isNotActiveStyle = 10 | "flex items-center px-5 gap-3 text-gray-500 hover:text-black transition-all duration-200 ease-in-out capitalize hover:bg-gray-200 py-2 my-1"; 11 | const isActiveStyle = 12 | "flex items-center px-5 gap-3 text-blue-600 transition-all duration-200 ease-in-out capitalize hover:bg-gray-200 py-2 my-1"; 13 | 14 | const Sidebar = () => { 15 | const [user, setUser] = useState(JSON.parse(localStorage.getItem("user"))); 16 | const dispatch = useDispatch(); 17 | const navigate = useNavigate(); 18 | const logout = () => { 19 | alert("OOPS! Your session expired. Please Login again"); 20 | dispatch({ type: "LOGOUT" }); 21 | navigate("/login/studentlogin"); 22 | }; 23 | useEffect(() => { 24 | const token = user?.token; 25 | 26 | if (token) { 27 | const decodedToken = decode(token); 28 | if (decodedToken.exp * 1000 < new Date().getTime()) logout(); 29 | } 30 | 31 | setUser(JSON.parse(localStorage.getItem("faculty"))); 32 | }, [navigate]); 33 | return ( 34 |
35 |
36 |
37 | 40 | isActive ? isActiveStyle : isNotActiveStyle 41 | }> 42 | 43 |

Dashboard

44 |
45 | 48 | isActive ? isActiveStyle : isNotActiveStyle 49 | }> 50 | 51 |

Profile

52 |
53 |
54 |
55 | 58 | isActive ? isActiveStyle : isNotActiveStyle 59 | }> 60 | 61 |

Test results

62 |
63 | 66 | isActive ? isActiveStyle : isNotActiveStyle 67 | }> 68 | 69 |

Attendance

70 |
71 |
72 |
73 | 76 | isActive ? isActiveStyle : isNotActiveStyle 77 | }> 78 | 79 |

Subject List

80 |
81 |
82 |
83 |
84 | ); 85 | }; 86 | 87 | export default Sidebar; 88 | -------------------------------------------------------------------------------- /client/src/components/student/StudentHome.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getNotice } from "../../redux/actions/adminActions"; 4 | import { 5 | getAttendance, 6 | getSubject, 7 | getTestResult, 8 | } from "../../redux/actions/studentActions"; 9 | 10 | import Body from "./Body"; 11 | import Header from "./Header"; 12 | import Sidebar from "./Sidebar"; 13 | 14 | const StudentHome = () => { 15 | const user = JSON.parse(localStorage.getItem("user")); 16 | 17 | const dispatch = useDispatch(); 18 | useEffect(() => { 19 | dispatch(getSubject(user.result.department, user.result.year)); 20 | dispatch( 21 | getTestResult( 22 | user.result.department, 23 | user.result.year, 24 | user.result.section 25 | ) 26 | ); 27 | dispatch( 28 | getAttendance( 29 | user.result.department, 30 | user.result.year, 31 | user.result.section 32 | ) 33 | ); 34 | dispatch(getNotice()); 35 | }, [dispatch]); 36 | 37 | return ( 38 |
39 |
40 |
41 |
42 | 43 | 44 |
45 |
46 |
47 | ); 48 | }; 49 | 50 | export default StudentHome; 51 | -------------------------------------------------------------------------------- /client/src/components/student/attendance/Attendance.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getAttendance } from "../../../redux/actions/studentActions"; 4 | 5 | import Header from "../Header"; 6 | import Sidebar from "../Sidebar"; 7 | import Body from "./Body"; 8 | 9 | const Attendance = () => { 10 | const user = JSON.parse(localStorage.getItem("user")); 11 | 12 | const dispatch = useDispatch(); 13 | useEffect(() => { 14 | dispatch( 15 | getAttendance( 16 | user.result.department, 17 | user.result.year, 18 | user.result.section 19 | ) 20 | ); 21 | }, [dispatch]); 22 | return ( 23 |
24 |
25 |
26 |
27 | 28 | 29 |
30 |
31 |
32 | ); 33 | }; 34 | 35 | export default Attendance; 36 | -------------------------------------------------------------------------------- /client/src/components/student/attendance/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import MenuBookIcon from "@mui/icons-material/MenuBook"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { getSubject } from "../../../redux/actions/adminActions"; 5 | import { MenuItem, Select } from "@mui/material"; 6 | import Spinner from "../../../utils/Spinner"; 7 | import { SET_ERRORS } from "../../../redux/actionTypes"; 8 | import * as classes from "../../../utils/styles"; 9 | 10 | const Body = () => { 11 | const dispatch = useDispatch(); 12 | const [error, setError] = useState({}); 13 | const attendance = useSelector((state) => state.student.attendance.result); 14 | 15 | const [loading, setLoading] = useState(false); 16 | const store = useSelector((state) => state); 17 | 18 | const [search, setSearch] = useState(false); 19 | 20 | useEffect(() => { 21 | if (Object.keys(store.errors).length !== 0) { 22 | setError(store.errors); 23 | setLoading(false); 24 | } 25 | }, [store.errors]); 26 | 27 | const subjects = useSelector((state) => state.admin.subjects.result); 28 | 29 | useEffect(() => { 30 | if (subjects?.length !== 0) setLoading(false); 31 | }, [subjects]); 32 | 33 | useEffect(() => { 34 | dispatch({ type: SET_ERRORS, payload: {} }); 35 | }, []); 36 | 37 | return ( 38 |
39 |
40 |
41 | 42 |

All Subjects

43 |
44 |
45 |
46 |
47 | {loading && ( 48 | 55 | )} 56 | {error.noSubjectError && ( 57 |

58 | {error.noSubjectError} 59 |

60 | )} 61 |
62 | {!loading && 63 | Object.keys(error).length === 0 && 64 | subjects?.length !== 0 && ( 65 |
66 |
67 |

68 | Sr no. 69 |

70 |

71 | Subject Code 72 |

73 |

74 | Subject Name 75 |

76 |

77 | Attended 78 |

79 |

80 | Total 81 |

82 |

83 | Percentage 84 |

85 |
86 | {attendance?.map((res, idx) => ( 87 |
90 |

92 | {idx + 1} 93 |

94 |

96 | {res.subjectCode} 97 |

98 |

100 | {res.subjectName} 101 |

102 |

104 | {res.attended} 105 |

106 |

108 | {res.total} 109 |

110 |

112 | {res.percentage} 113 |

114 |
115 | ))} 116 |
117 | )} 118 |
119 |
120 |
121 |
122 | ); 123 | }; 124 | 125 | export default Body; 126 | -------------------------------------------------------------------------------- /client/src/components/student/profile/Body.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import AssignmentIndIcon from "@mui/icons-material/AssignmentInd"; 3 | import SecurityUpdateIcon from "@mui/icons-material/SecurityUpdate"; 4 | import { Avatar } from "@mui/material"; 5 | import Data from "./Data"; 6 | import { useNavigate } from "react-router-dom"; 7 | const Body = () => { 8 | const user = JSON.parse(localStorage.getItem("user")); 9 | const navigate = useNavigate(); 10 | return ( 11 |
12 |
13 |
14 |
15 | 16 |

Profile

17 |
18 |
navigate("/student/update")} 20 | className="flex space-x-2 cursor-pointer"> 21 | 22 |

Update

23 |
24 |
25 |
26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 |
39 |
40 | 41 | 42 | 46 | 47 | 51 | 52 |
53 |
54 |
{" "} 55 |
56 |
57 |
58 | ); 59 | }; 60 | 61 | export default Body; 62 | -------------------------------------------------------------------------------- /client/src/components/student/profile/Data.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import * as classes from "../../../utils/styles"; 3 | const Data = ({ label, value }) => { 4 | return ( 5 |
6 |

{label} :

7 |

8 | {value} 9 |

10 |
11 | ); 12 | }; 13 | 14 | export default Data; 15 | -------------------------------------------------------------------------------- /client/src/components/student/profile/Profile.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Body from "./Body"; 3 | import Header from "../Header"; 4 | import Sidebar from "../Sidebar"; 5 | 6 | const Profile = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default Profile; 21 | -------------------------------------------------------------------------------- /client/src/components/student/profile/update/Update.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import Body from "./Body"; 3 | import Header from "../../Header"; 4 | import Sidebar from "../../Sidebar"; 5 | import { useDispatch } from "react-redux"; 6 | import { getAllDepartment } from "../../../../redux/actions/adminActions"; 7 | 8 | const Update = () => { 9 | const dispatch = useDispatch(); 10 | useEffect(() => { 11 | dispatch(getAllDepartment()); 12 | }, [dispatch]); 13 | return ( 14 |
15 |
16 |
17 |
18 | 19 | 20 |
21 |
22 |
23 | ); 24 | }; 25 | 26 | export default Update; 27 | -------------------------------------------------------------------------------- /client/src/components/student/profile/update/firstTimePassword/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import VisibilityIcon from "@mui/icons-material/Visibility"; 3 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 4 | import Spinner from "../../../../../utils/Spinner"; 5 | import { useDispatch, useSelector } from "react-redux"; 6 | import { useNavigate } from "react-router-dom"; 7 | import { studentUpdatePassword } from "../../../../../redux/actions/studentActions"; 8 | 9 | const Body = () => { 10 | const [newPassword, setNewPassword] = useState(""); 11 | const [confirmPassword, setConfirmPassword] = useState(""); 12 | const [showPassword, setShowPassword] = useState(false); 13 | const [error, setError] = useState({}); 14 | const [loading, setLoading] = useState(false); 15 | const store = useSelector((state) => state); 16 | const dispatch = useDispatch(); 17 | const navigate = useNavigate(); 18 | const user = JSON.parse(localStorage.getItem("user")); 19 | 20 | useEffect(() => { 21 | if (Object.keys(store.errors).length !== 0) { 22 | setError(store.errors); 23 | setLoading(false); 24 | } 25 | }, [store.errors]); 26 | 27 | const update = (e) => { 28 | e.preventDefault(); 29 | 30 | setLoading(true); 31 | dispatch( 32 | studentUpdatePassword( 33 | { 34 | newPassword: newPassword, 35 | confirmPassword: confirmPassword, 36 | email: user.result.email, 37 | }, 38 | navigate 39 | ) 40 | ); 41 | }; 42 | 43 | useEffect(() => { 44 | if (store.errors) { 45 | setLoading(false); 46 | setNewPassword(""); 47 | setConfirmPassword(""); 48 | } 49 | }, [store.errors]); 50 | 51 | return ( 52 |
53 |
54 |

Update Password

55 |
56 |

New Password

57 |
58 | setNewPassword(e.target.value)} 60 | value={newPassword} 61 | required 62 | type={showPassword ? "text" : "password"} 63 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 64 | placeholder="New Password" 65 | /> 66 | {showPassword ? ( 67 | setShowPassword(!showPassword)} 69 | className="cursor-pointer" 70 | /> 71 | ) : ( 72 | setShowPassword(!showPassword)} 74 | className="cursor-pointer" 75 | /> 76 | )} 77 |
78 |
79 |
80 |

Confirm Password

81 |
82 | setConfirmPassword(e.target.value)} 84 | value={confirmPassword} 85 | required 86 | type={showPassword ? "text" : "password"} 87 | className=" bg-[#515966] text-white rounded-lg outline-none py-2 placeholder:text-sm" 88 | placeholder="Confirm Password" 89 | /> 90 | {showPassword ? ( 91 | setShowPassword(!showPassword)} 93 | className="cursor-pointer" 94 | /> 95 | ) : ( 96 | setShowPassword(!showPassword)} 98 | className="cursor-pointer" 99 | /> 100 | )} 101 |
102 |
103 | 108 | {loading && ( 109 | 116 | )} 117 | {error.mismatchError && ( 118 |

{error.mismatchError}

119 | )} 120 | 121 |
122 | ); 123 | }; 124 | 125 | export default Body; 126 | -------------------------------------------------------------------------------- /client/src/components/student/profile/update/firstTimePassword/FirstTimePassword.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "../../../../student/Header"; 3 | import Body from "./Body"; 4 | 5 | const FirstTimePassword = () => { 6 | return ( 7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 |
15 | ); 16 | }; 17 | 18 | export default FirstTimePassword; 19 | -------------------------------------------------------------------------------- /client/src/components/student/profile/update/password/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import VisibilityIcon from "@mui/icons-material/Visibility"; 3 | import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; 4 | import Spinner from "../../../../../utils/Spinner"; 5 | import { useDispatch, useSelector } from "react-redux"; 6 | import { useNavigate } from "react-router-dom"; 7 | import { adminUpdatePassword } from "../../../../../redux/actions/adminActions"; 8 | import * as classes from "../../../../../utils/styles"; 9 | import { facultyUpdatePassword } from "../../../../../redux/actions/facultyActions"; 10 | import { studentUpdatePassword } from "../../../../../redux/actions/studentActions"; 11 | const Body = () => { 12 | const [newPassword, setNewPassword] = useState(""); 13 | const [confirmPassword, setConfirmPassword] = useState(""); 14 | const [showPassword, setShowPassword] = useState(false); 15 | const [error, setError] = useState({}); 16 | const [loading, setLoading] = useState(false); 17 | const store = useSelector((state) => state); 18 | const dispatch = useDispatch(); 19 | const navigate = useNavigate(); 20 | const user = JSON.parse(localStorage.getItem("user")); 21 | 22 | useEffect(() => { 23 | if (Object.keys(store.errors).length !== 0) { 24 | setError(store.errors); 25 | setLoading(false); 26 | } 27 | }, [store.errors]); 28 | 29 | const update = (e) => { 30 | e.preventDefault(); 31 | 32 | setLoading(true); 33 | dispatch( 34 | studentUpdatePassword( 35 | { 36 | newPassword: newPassword, 37 | confirmPassword: confirmPassword, 38 | email: user.result.email, 39 | }, 40 | navigate 41 | ) 42 | ); 43 | }; 44 | 45 | useEffect(() => { 46 | if (store.errors) { 47 | setLoading(false); 48 | setNewPassword(""); 49 | setConfirmPassword(""); 50 | } 51 | }, [store.errors]); 52 | 53 | return ( 54 |
55 |
56 |
57 | 58 |

Password

59 |
60 | 61 |
62 |
65 |

Update Password

66 |
67 |

New Password

68 |
69 | setNewPassword(e.target.value)} 71 | value={newPassword} 72 | required 73 | type={showPassword ? "text" : "password"} 74 | className="rounded-lg outline-none py-2 placeholder:text-sm" 75 | placeholder="New Password" 76 | /> 77 | {showPassword ? ( 78 | setShowPassword(!showPassword)} 80 | className="cursor-pointer" 81 | /> 82 | ) : ( 83 | setShowPassword(!showPassword)} 85 | className="cursor-pointer" 86 | /> 87 | )} 88 |
89 |
90 |
91 |

92 | Confirm Password 93 |

94 |
95 | setConfirmPassword(e.target.value)} 97 | value={confirmPassword} 98 | required 99 | type={showPassword ? "text" : "password"} 100 | className="rounded-lg outline-none py-2 placeholder:text-sm" 101 | placeholder="Confirm Password" 102 | /> 103 | {showPassword ? ( 104 | setShowPassword(!showPassword)} 106 | className="cursor-pointer" 107 | /> 108 | ) : ( 109 | setShowPassword(!showPassword)} 111 | className="cursor-pointer" 112 | /> 113 | )} 114 |
115 |
116 |
117 | 120 | 126 |
127 | {loading && ( 128 | 135 | )} 136 | {error.mismatchError && ( 137 |

{error.mismatchError}

138 | )} 139 | 140 |
141 |
142 |
143 | ); 144 | }; 145 | 146 | export default Body; 147 | -------------------------------------------------------------------------------- /client/src/components/student/profile/update/password/Password.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Header from "../../../Header"; 3 | import Sidebar from "../../../Sidebar"; 4 | import Body from "./Body"; 5 | 6 | const Password = () => { 7 | return ( 8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | ); 18 | }; 19 | 20 | export default Password; 21 | -------------------------------------------------------------------------------- /client/src/components/student/subjectList/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import MenuBookIcon from "@mui/icons-material/MenuBook"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { getSubject } from "../../../redux/actions/adminActions"; 5 | import { MenuItem, Select } from "@mui/material"; 6 | import Spinner from "../../../utils/Spinner"; 7 | import { SET_ERRORS } from "../../../redux/actionTypes"; 8 | import * as classes from "../../../utils/styles"; 9 | 10 | const Body = () => { 11 | const dispatch = useDispatch(); 12 | const [error, setError] = useState({}); 13 | const [loading, setLoading] = useState(false); 14 | const store = useSelector((state) => state); 15 | const [value, setValue] = useState({ 16 | department: "", 17 | year: "", 18 | }); 19 | const [search, setSearch] = useState(false); 20 | 21 | useEffect(() => { 22 | if (Object.keys(store.errors).length !== 0) { 23 | setError(store.errors); 24 | setLoading(false); 25 | } 26 | }, [store.errors]); 27 | 28 | const handleSubmit = (e) => { 29 | e.preventDefault(); 30 | setSearch(true); 31 | setLoading(true); 32 | setError({}); 33 | dispatch(getSubject(value)); 34 | }; 35 | const subjects = useSelector((state) => state.admin.subjects.result); 36 | 37 | useEffect(() => { 38 | if (subjects?.length !== 0) setLoading(false); 39 | }, [subjects]); 40 | 41 | useEffect(() => { 42 | dispatch({ type: SET_ERRORS, payload: {} }); 43 | }, []); 44 | 45 | return ( 46 |
47 |
48 |
49 | 50 |

All Subjects

51 |
52 |
53 |
54 |
55 | {loading && ( 56 | 63 | )} 64 | {error.noSubjectError && ( 65 |

66 | {error.noSubjectError} 67 |

68 | )} 69 |
70 | {!loading && 71 | Object.keys(error).length === 0 && 72 | subjects?.length !== 0 && ( 73 |
74 |
75 |

76 | Sr no. 77 |

78 |

79 | Subject Code 80 |

81 |

82 | Subject Name 83 |

84 |

85 | Total Lectures 86 |

87 |
88 | {subjects?.map((sub, idx) => ( 89 |
92 |

94 | {idx + 1} 95 |

96 |

98 | {sub.subjectCode} 99 |

100 |

102 | {sub.subjectName} 103 |

104 |

106 | {sub.totalLectures} 107 |

108 |
109 | ))} 110 |
111 | )} 112 |
113 |
114 |
115 |
116 | ); 117 | }; 118 | 119 | export default Body; 120 | -------------------------------------------------------------------------------- /client/src/components/student/subjectList/SubjectList.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getSubject } from "../../../redux/actions/studentActions"; 4 | 5 | import Header from "../Header"; 6 | import Sidebar from "../Sidebar"; 7 | import Body from "./Body"; 8 | 9 | const SubjectList = () => { 10 | const user = JSON.parse(localStorage.getItem("user")); 11 | 12 | const dispatch = useDispatch(); 13 | useEffect(() => { 14 | dispatch(getSubject(user.result.department, user.result.year)); 15 | }, [dispatch]); 16 | return ( 17 |
18 |
19 |
20 |
21 | 22 | 23 |
24 |
25 |
26 | ); 27 | }; 28 | 29 | export default SubjectList; 30 | -------------------------------------------------------------------------------- /client/src/components/student/testResult/Body.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import MenuBookIcon from "@mui/icons-material/MenuBook"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { getSubject } from "../../../redux/actions/adminActions"; 5 | import { MenuItem, Select } from "@mui/material"; 6 | import Spinner from "../../../utils/Spinner"; 7 | import { SET_ERRORS } from "../../../redux/actionTypes"; 8 | import * as classes from "../../../utils/styles"; 9 | 10 | const Body = () => { 11 | const dispatch = useDispatch(); 12 | const [error, setError] = useState({}); 13 | const testResult = useSelector((state) => state.student.testResult.result); 14 | 15 | const [loading, setLoading] = useState(false); 16 | const store = useSelector((state) => state); 17 | 18 | const [search, setSearch] = useState(false); 19 | 20 | console.log(error); 21 | useEffect(() => { 22 | if (Object.keys(store.errors).length !== 0) { 23 | setError(store.errors); 24 | setLoading(false); 25 | } 26 | }, [store.errors]); 27 | 28 | const subjects = useSelector((state) => state.admin.subjects.result); 29 | 30 | useEffect(() => { 31 | if (subjects?.length !== 0) setLoading(false); 32 | }, [subjects]); 33 | 34 | useEffect(() => { 35 | dispatch({ type: SET_ERRORS, payload: {} }); 36 | }, []); 37 | 38 | return ( 39 |
40 |
41 |
42 | 43 |

All Subjects

44 |
45 |
46 |
47 |
48 | {loading && ( 49 | 56 | )} 57 | {error.noSubjectError && ( 58 |

59 | {error.noSubjectError} 60 |

61 | )} 62 |
63 | {!loading && 64 | Object.keys(error).length === 0 && 65 | subjects?.length !== 0 && ( 66 |
67 |
68 |

69 | Sr no. 70 |

71 |

72 | Subject Code 73 |

74 |

75 | Subject Name 76 |

77 |

78 | Test 79 |

80 |

81 | Marks Obtained 82 |

83 |

84 | Total Marks 85 |

86 |
87 | {testResult?.map((res, idx) => ( 88 |
91 |

93 | {idx + 1} 94 |

95 |

97 | {res.subjectCode} 98 |

99 |

101 | {res.subjectName} 102 |

103 |

105 | {res.test} 106 |

107 |

109 | {res.marks} 110 |

111 |

113 | {res.totalMarks} 114 |

115 |
116 | ))} 117 |
118 | )} 119 |
120 |
121 |
122 |
123 | ); 124 | }; 125 | 126 | export default Body; 127 | -------------------------------------------------------------------------------- /client/src/components/student/testResult/TestResult.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { useDispatch } from "react-redux"; 3 | import { getTestResult } from "../../../redux/actions/studentActions"; 4 | 5 | import Header from "../Header"; 6 | import Sidebar from "../Sidebar"; 7 | import Body from "./Body"; 8 | 9 | const TestResult = () => { 10 | const user = JSON.parse(localStorage.getItem("user")); 11 | 12 | const dispatch = useDispatch(); 13 | useEffect(() => { 14 | dispatch( 15 | getTestResult( 16 | user.result.department, 17 | user.result.year, 18 | user.result.section 19 | ) 20 | ); 21 | }, [dispatch]); 22 | return ( 23 |
24 |
25 |
26 |
27 | 28 | 29 |
30 |
31 |
32 | ); 33 | }; 34 | 35 | export default TestResult; 36 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import "./index.css"; 4 | import App from "./App"; 5 | import { Provider } from "react-redux"; 6 | import { createStore, applyMiddleware, compose } from "redux"; 7 | import { BrowserRouter as Router } from "react-router-dom"; 8 | import reducers from "./redux/reducers"; 9 | import thunk from "redux-thunk"; 10 | 11 | const store = createStore(reducers, compose(applyMiddleware(thunk))); 12 | 13 | ReactDOM.render( 14 | 15 | 16 | 17 | 18 | 19 | 20 | , 21 | document.getElementById("root") 22 | ); 23 | -------------------------------------------------------------------------------- /client/src/redux/actionTypes.js: -------------------------------------------------------------------------------- 1 | export const ADMIN_LOGIN = "ADMIN_AUTH"; 2 | export const LOGOUT = "LOGOUT"; 3 | export const UPDATE_PASSWORD = "UPDATE_PASSWORD"; 4 | export const UPDATE_ADMIN = "UPDATE_ADMIN"; 5 | export const ADD_ADMIN = "ADD_ADMIN"; 6 | export const ADD_DEPARTMENT = "ADD_DEPARTMENT"; 7 | export const ADD_FACULTY = "ADD_FACULTY"; 8 | export const GET_ALL_FACULTY = "GET_ALL_FACULTY"; 9 | export const ADD_SUBJECT = "ADD_SUBJECT"; 10 | export const GET_ALL_SUBJECT = "GET_ALL_SUBJECT"; 11 | export const ADD_STUDENT = "ADD_STUDENT"; 12 | export const GET_ALL_STUDENT = "GET_ALL_STUDENT"; 13 | export const GET_STUDENT = "GET_STUDENT"; 14 | export const GET_FACULTY = "GET_FACULTY"; 15 | export const GET_SUBJECT = "GET_SUBJECT"; 16 | export const GET_ALL_ADMIN = "GET_ALL_ADMIN"; 17 | export const GET_ALL_DEPARTMENT = "GET_ALL_DEPARTMENT"; 18 | export const SET_ERRORS = "SET_ERRORS"; 19 | export const FACULTY_LOGIN = "FACULTY_LOGIN"; 20 | export const UPDATE_FACULTY = "UPDATE_FACULTY"; 21 | export const ADD_TEST = "ADD_TEST"; 22 | export const GET_TEST = "GET_TEST"; 23 | export const MARKS_UPLOADED = "MARKS_UPLOADED"; 24 | export const ATTENDANCE_MARKED = "ATTENDANCE_MARKED"; 25 | export const STUDENT_LOGIN = "STUDENT_LOGIN"; 26 | export const UPDATE_STUDENT = "UPDATE_STUDENT"; 27 | export const TEST_RESULT = "TEST_RESULT"; 28 | export const ATTENDANCE = "ATTENDANCE"; 29 | export const GET_ADMIN = "GET_ADMIN"; 30 | export const DELETE_ADMIN = "DELETE_ADMIN"; 31 | export const DELETE_DEPARTMENT = "DELETE_DEPARTMENT"; 32 | export const DELETE_FACULTY = "DELETE_FACULTY"; 33 | export const DELETE_STUDENT = "DELETE_STUDENT"; 34 | export const DELETE_SUBJECT = "DELETE_SUBJECT"; 35 | export const CREATE_NOTICE = "CREATE_NOTICE"; 36 | export const GET_NOTICE = "GET_NOTICE"; 37 | -------------------------------------------------------------------------------- /client/src/redux/actions/facultyActions.js: -------------------------------------------------------------------------------- 1 | import { 2 | SET_ERRORS, 3 | FACULTY_LOGIN, 4 | UPDATE_PASSWORD, 5 | UPDATE_FACULTY, 6 | ADD_TEST, 7 | GET_TEST, 8 | GET_STUDENT, 9 | MARKS_UPLOADED, 10 | ATTENDANCE_MARKED, 11 | } from "../actionTypes"; 12 | import * as api from "../api"; 13 | 14 | export const facultySignIn = (formData, navigate) => async (dispatch) => { 15 | try { 16 | const { data } = await api.facultySignIn(formData); 17 | dispatch({ type: FACULTY_LOGIN, data }); 18 | if (data.result.passwordUpdated) navigate("/faculty/home"); 19 | else navigate("/faculty/password"); 20 | } catch (error) { 21 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 22 | } 23 | }; 24 | 25 | export const facultyUpdatePassword = 26 | (formData, navigate) => async (dispatch) => { 27 | try { 28 | const { data } = await api.facultyUpdatePassword(formData); 29 | dispatch({ type: UPDATE_PASSWORD, payload: true }); 30 | alert("Password Updated"); 31 | navigate("/faculty/home"); 32 | } catch (error) { 33 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 34 | } 35 | }; 36 | 37 | export const updateFaculty = (formData) => async (dispatch) => { 38 | try { 39 | const { data } = await api.updateFaculty(formData); 40 | dispatch({ type: UPDATE_FACULTY, payload: true }); 41 | } catch (error) { 42 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 43 | } 44 | }; 45 | 46 | export const createTest = (formData) => async (dispatch) => { 47 | try { 48 | const { data } = await api.createTest(formData); 49 | alert("Test Created Successfully"); 50 | 51 | dispatch({ type: ADD_TEST, payload: true }); 52 | } catch (error) { 53 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 54 | } 55 | }; 56 | 57 | export const getTest = (formData) => async (dispatch) => { 58 | try { 59 | const { data } = await api.getTest(formData); 60 | dispatch({ type: GET_TEST, payload: data }); 61 | } catch (error) { 62 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 63 | } 64 | }; 65 | 66 | export const getStudent = (formData) => async (dispatch) => { 67 | try { 68 | const { data } = await api.getMarksStudent(formData); 69 | dispatch({ type: GET_STUDENT, payload: data }); 70 | } catch (error) { 71 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 72 | } 73 | }; 74 | 75 | export const uploadMark = 76 | (marks, department, section, year, test) => async (dispatch) => { 77 | try { 78 | const formData = { 79 | marks, 80 | department, 81 | section, 82 | year, 83 | test, 84 | }; 85 | const { data } = await api.uploadMarks(formData); 86 | alert("Marks Uploaded Successfully"); 87 | dispatch({ type: MARKS_UPLOADED, payload: true }); 88 | } catch (error) { 89 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 90 | } 91 | }; 92 | 93 | export const markAttendance = 94 | (checkedValue, subjectName, department, year, section) => 95 | async (dispatch) => { 96 | try { 97 | const formData = { 98 | selectedStudents: checkedValue, 99 | subjectName, 100 | department, 101 | year, 102 | section, 103 | }; 104 | const { data } = await api.markAttendance(formData); 105 | alert("Attendance Marked Successfully"); 106 | dispatch({ type: ATTENDANCE_MARKED, payload: true }); 107 | } catch (error) { 108 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 109 | } 110 | }; 111 | -------------------------------------------------------------------------------- /client/src/redux/actions/studentActions.js: -------------------------------------------------------------------------------- 1 | import { 2 | SET_ERRORS, 3 | UPDATE_PASSWORD, 4 | TEST_RESULT, 5 | STUDENT_LOGIN, 6 | ATTENDANCE, 7 | UPDATE_STUDENT, 8 | GET_SUBJECT, 9 | } from "../actionTypes"; 10 | import * as api from "../api"; 11 | 12 | export const studentSignIn = (formData, navigate) => async (dispatch) => { 13 | try { 14 | const { data } = await api.studentSignIn(formData); 15 | dispatch({ type: STUDENT_LOGIN, data }); 16 | if (data.result.passwordUpdated) navigate("/student/home"); 17 | else navigate("/student/password"); 18 | } catch (error) { 19 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 20 | } 21 | }; 22 | 23 | export const studentUpdatePassword = 24 | (formData, navigate) => async (dispatch) => { 25 | try { 26 | const { data } = await api.studentUpdatePassword(formData); 27 | dispatch({ type: UPDATE_PASSWORD, payload: true }); 28 | alert("Password Updated"); 29 | navigate("/student/home"); 30 | } catch (error) { 31 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 32 | } 33 | }; 34 | 35 | export const updateStudent = (formData) => async (dispatch) => { 36 | try { 37 | const { data } = await api.updateStudent(formData); 38 | dispatch({ type: UPDATE_STUDENT, payload: true }); 39 | } catch (error) { 40 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 41 | } 42 | }; 43 | 44 | export const getSubject = (department, year) => async (dispatch) => { 45 | try { 46 | const formData = { 47 | department, 48 | year, 49 | }; 50 | const { data } = await api.getSubject(formData); 51 | dispatch({ type: GET_SUBJECT, payload: data }); 52 | } catch (error) { 53 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 54 | } 55 | }; 56 | 57 | export const getTestResult = 58 | (department, year, section) => async (dispatch) => { 59 | try { 60 | const formData = { 61 | department, 62 | year, 63 | section, 64 | }; 65 | const { data } = await api.getTestResult(formData); 66 | dispatch({ type: TEST_RESULT, payload: data }); 67 | } catch (error) { 68 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 69 | } 70 | }; 71 | 72 | export const getAttendance = 73 | (department, year, section) => async (dispatch) => { 74 | try { 75 | const formData = { 76 | department, 77 | year, 78 | section, 79 | }; 80 | const { data } = await api.getAttendance(formData); 81 | dispatch({ type: ATTENDANCE, payload: data }); 82 | } catch (error) { 83 | dispatch({ type: SET_ERRORS, payload: error.response.data }); 84 | } 85 | }; 86 | -------------------------------------------------------------------------------- /client/src/redux/api/index.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | // const API = axios.create({ baseURL: process.env.REACT_APP_SERVER_URL }); 4 | const API = axios.create({ baseURL: "http://localhost:5001/" }); 5 | 6 | API.interceptors.request.use((req) => { 7 | if (localStorage.getItem("user")) { 8 | req.headers.Authorization = `Bearer ${ 9 | JSON.parse(localStorage.getItem("user")).token 10 | }`; 11 | } 12 | return req; 13 | }); 14 | 15 | // Admin 16 | 17 | export const adminSignIn = (formData) => API.post("/api/admin/login", formData); 18 | 19 | export const adminUpdatePassword = (updatedPassword) => 20 | API.post("/api/admin/updatepassword", updatedPassword); 21 | 22 | export const getAllStudent = () => API.get("/api/admin/getallstudent"); 23 | 24 | export const getAllFaculty = () => API.get("/api/admin/getallfaculty"); 25 | 26 | export const getAllAdmin = () => API.get("/api/admin/getalladmin"); 27 | 28 | export const getAllDepartment = () => API.get("/api/admin/getalldepartment"); 29 | export const getAllSubject = () => API.get("/api/admin/getallsubject"); 30 | 31 | export const updateAdmin = (updatedAdmin) => 32 | API.post("/api/admin/updateprofile", updatedAdmin); 33 | 34 | export const addAdmin = (admin) => API.post("/api/admin/addadmin", admin); 35 | export const createNotice = (notice) => 36 | API.post("/api/admin/createnotice", notice); 37 | export const deleteAdmin = (data) => API.post("/api/admin/deleteadmin", data); 38 | export const deleteFaculty = (data) => 39 | API.post("/api/admin/deletefaculty", data); 40 | export const deleteStudent = (data) => 41 | API.post("/api/admin/deletestudent", data); 42 | export const deleteSubject = (data) => 43 | API.post("/api/admin/deletesubject", data); 44 | export const deleteDepartment = (data) => 45 | API.post("/api/admin/deletedepartment", data); 46 | 47 | export const getAdmin = (admin) => API.post("/api/admin/getadmin", admin); 48 | 49 | export const addDepartment = (department) => 50 | API.post("/api/admin/adddepartment", department); 51 | 52 | export const addFaculty = (faculty) => 53 | API.post("/api/admin/addfaculty", faculty); 54 | 55 | export const getFaculty = (department) => 56 | API.post("/api/admin/getfaculty", department); 57 | 58 | export const addSubject = (subject) => 59 | API.post("/api/admin/addsubject", subject); 60 | export const getSubject = (subject) => 61 | API.post("/api/admin/getsubject", subject); 62 | 63 | export const addStudent = (student) => 64 | API.post("/api/admin/addstudent", student); 65 | 66 | export const getStudent = (student) => 67 | API.post("/api/admin/getstudent", student); 68 | export const getNotice = (notice) => API.post("/api/admin/getnotice", notice); 69 | 70 | // Faculty 71 | 72 | export const facultySignIn = (formData) => 73 | API.post("/api/faculty/login", formData); 74 | 75 | export const facultyUpdatePassword = (updatedPassword) => 76 | API.post("/api/faculty/updatepassword", updatedPassword); 77 | 78 | export const updateFaculty = (updatedFaculty) => 79 | API.post("/api/faculty/updateprofile", updatedFaculty); 80 | 81 | export const createTest = (test) => API.post("/api/faculty/createtest", test); 82 | export const getTest = (test) => API.post("/api/faculty/gettest", test); 83 | export const getMarksStudent = (student) => 84 | API.post("/api/faculty/getstudent", student); 85 | export const uploadMarks = (data) => API.post("/api/faculty/uploadmarks", data); 86 | export const markAttendance = (data) => 87 | API.post("/api/faculty/markattendance", data); 88 | 89 | // Student 90 | 91 | export const studentSignIn = (formData) => 92 | API.post("/api/student/login", formData); 93 | 94 | export const studentUpdatePassword = (updatedPassword) => 95 | API.post("/api/student/updatepassword", updatedPassword); 96 | 97 | export const updateStudent = (updatedStudent) => 98 | API.post("/api/student/updateprofile", updatedStudent); 99 | export const getTestResult = (testResult) => 100 | API.post("/api/student/testresult", testResult); 101 | export const getAttendance = (attendance) => 102 | API.post("/api/student/attendance", attendance); 103 | -------------------------------------------------------------------------------- /client/src/redux/reducers/adminReducer.js: -------------------------------------------------------------------------------- 1 | import { 2 | ADD_ADMIN, 3 | ADD_FACULTY, 4 | ADD_STUDENT, 5 | ADD_SUBJECT, 6 | ADMIN_LOGIN, 7 | GET_FACULTY, 8 | GET_SUBJECT, 9 | LOGOUT, 10 | UPDATE_ADMIN, 11 | GET_STUDENT, 12 | ADD_DEPARTMENT, 13 | GET_ALL_STUDENT, 14 | GET_ALL_SUBJECT, 15 | GET_ALL_FACULTY, 16 | GET_ALL_ADMIN, 17 | GET_ALL_DEPARTMENT, 18 | UPDATE_PASSWORD, 19 | GET_ADMIN, 20 | DELETE_ADMIN, 21 | DELETE_DEPARTMENT, 22 | DELETE_FACULTY, 23 | DELETE_STUDENT, 24 | DELETE_SUBJECT, 25 | CREATE_NOTICE, 26 | GET_NOTICE, 27 | } from "../actionTypes"; 28 | 29 | const initialState = { 30 | authData: null, 31 | updatedPassword: false, 32 | updatedAdmin: false, 33 | adminAdded: false, 34 | departmentAdded: false, 35 | facultyAdded: false, 36 | studentAdded: false, 37 | subjectAdded: false, 38 | allFaculty: [], 39 | allSubject: [], 40 | allStudent: [], 41 | allAdmin: [], 42 | allDepartment: [], 43 | students: [], 44 | faculties: [], 45 | subjects: [], 46 | admins: [], 47 | notices: [], 48 | adminDeleted: false, 49 | departmentDeleted: false, 50 | facultyDeleted: false, 51 | studentDeleted: false, 52 | subjectDeleted: false, 53 | noticeCreated: false, 54 | }; 55 | 56 | const adminReducer = (state = initialState, action) => { 57 | switch (action.type) { 58 | case ADMIN_LOGIN: 59 | localStorage.setItem("user", JSON.stringify({ ...action?.data })); 60 | return { ...state, authData: action?.data }; 61 | case LOGOUT: 62 | localStorage.clear(); 63 | return { ...state, authData: null }; 64 | case UPDATE_PASSWORD: 65 | return { 66 | ...state, 67 | updatedPassword: action.payload, 68 | }; 69 | case UPDATE_ADMIN: 70 | return { 71 | ...state, 72 | updatedAdmin: action.payload, 73 | }; 74 | case ADD_ADMIN: 75 | return { 76 | ...state, 77 | adminAdded: action.payload, 78 | }; 79 | case CREATE_NOTICE: 80 | return { 81 | ...state, 82 | noticeCreated: action.payload, 83 | }; 84 | case DELETE_ADMIN: 85 | return { 86 | ...state, 87 | adminDeleted: action.payload, 88 | }; 89 | case DELETE_DEPARTMENT: 90 | return { 91 | ...state, 92 | departmentDeleted: action.payload, 93 | }; 94 | case DELETE_FACULTY: 95 | return { 96 | ...state, 97 | facultyDeleted: action.payload, 98 | }; 99 | case DELETE_STUDENT: 100 | return { 101 | ...state, 102 | studentDeleted: action.payload, 103 | }; 104 | case DELETE_SUBJECT: 105 | return { 106 | ...state, 107 | subjectDeleted: action.payload, 108 | }; 109 | case ADD_DEPARTMENT: 110 | return { 111 | ...state, 112 | departmentAdded: action.payload, 113 | }; 114 | case ADD_FACULTY: 115 | return { 116 | ...state, 117 | facultyAdded: action.payload, 118 | }; 119 | case GET_FACULTY: 120 | return { 121 | ...state, 122 | faculties: action.payload, 123 | }; 124 | case GET_NOTICE: 125 | return { 126 | ...state, 127 | notices: action.payload, 128 | }; 129 | case GET_ADMIN: 130 | return { 131 | ...state, 132 | admins: action.payload, 133 | }; 134 | case GET_ALL_FACULTY: 135 | return { 136 | ...state, 137 | allFaculty: action.payload, 138 | }; 139 | case GET_ALL_ADMIN: 140 | return { 141 | ...state, 142 | allAdmin: action.payload, 143 | }; 144 | case GET_ALL_DEPARTMENT: 145 | return { 146 | ...state, 147 | allDepartment: action.payload, 148 | }; 149 | case ADD_SUBJECT: 150 | return { 151 | ...state, 152 | subjectAdded: action.payload, 153 | }; 154 | case GET_SUBJECT: 155 | return { 156 | ...state, 157 | subjects: action.payload, 158 | }; 159 | case GET_ALL_SUBJECT: 160 | return { 161 | ...state, 162 | allSubject: action.payload, 163 | }; 164 | case ADD_STUDENT: 165 | return { 166 | ...state, 167 | studentAdded: action.payload, 168 | }; 169 | case GET_STUDENT: 170 | return { 171 | ...state, 172 | students: action.payload, 173 | }; 174 | case GET_ALL_STUDENT: 175 | return { 176 | ...state, 177 | allStudent: action.payload, 178 | }; 179 | default: 180 | return state; 181 | } 182 | }; 183 | 184 | export default adminReducer; 185 | -------------------------------------------------------------------------------- /client/src/redux/reducers/errorReducer.js: -------------------------------------------------------------------------------- 1 | import { SET_ERRORS } from "../actionTypes"; 2 | 3 | const initialState = {}; 4 | 5 | const errorReducer = (state = initialState, action) => { 6 | switch (action.type) { 7 | case SET_ERRORS: 8 | return action.payload; 9 | default: 10 | return state; 11 | } 12 | }; 13 | 14 | export default errorReducer; 15 | -------------------------------------------------------------------------------- /client/src/redux/reducers/facultyReducer.js: -------------------------------------------------------------------------------- 1 | import { 2 | ADD_TEST, 3 | ATTENDANCE_MARKED, 4 | FACULTY_LOGIN, 5 | GET_TEST, 6 | LOGOUT, 7 | MARKS_UPLOADED, 8 | UPDATE_FACULTY, 9 | UPDATE_PASSWORD, 10 | } from "../actionTypes"; 11 | 12 | const initialState = { 13 | authData: null, 14 | updatedPassword: false, 15 | updatedFaculty: false, 16 | testAdded: false, 17 | marksUploaded: false, 18 | attendanceUploaded: false, 19 | tests: [], 20 | }; 21 | 22 | const facultyReducer = (state = initialState, action) => { 23 | switch (action.type) { 24 | case FACULTY_LOGIN: 25 | localStorage.setItem("user", JSON.stringify({ ...action?.data })); 26 | return { ...state, authData: action?.data }; 27 | case LOGOUT: 28 | localStorage.clear(); 29 | return { ...state, authData: null }; 30 | case UPDATE_PASSWORD: 31 | return { 32 | ...state, 33 | updatedPassword: action.payload, 34 | }; 35 | case UPDATE_FACULTY: 36 | return { 37 | ...state, 38 | updatedFaculty: action.payload, 39 | }; 40 | case ADD_TEST: 41 | return { 42 | ...state, 43 | testAdded: action.payload, 44 | }; 45 | case GET_TEST: 46 | return { 47 | ...state, 48 | tests: action.payload, 49 | }; 50 | case MARKS_UPLOADED: 51 | return { 52 | ...state, 53 | marksUploaded: action.payload, 54 | }; 55 | case ATTENDANCE_MARKED: 56 | return { 57 | ...state, 58 | attendanceUploaded: action.payload, 59 | }; 60 | 61 | default: 62 | return state; 63 | } 64 | }; 65 | 66 | export default facultyReducer; 67 | -------------------------------------------------------------------------------- /client/src/redux/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from "redux"; 2 | import adminReducer from "./adminReducer"; 3 | import errorReducer from "./errorReducer"; 4 | import facultyReducer from "./facultyReducer"; 5 | import studentReducer from "./studentReducer"; 6 | 7 | export default combineReducers({ 8 | admin: adminReducer, 9 | errors: errorReducer, 10 | faculty: facultyReducer, 11 | student: studentReducer, 12 | }); 13 | -------------------------------------------------------------------------------- /client/src/redux/reducers/studentReducer.js: -------------------------------------------------------------------------------- 1 | import { 2 | LOGOUT, 3 | STUDENT_LOGIN, 4 | UPDATE_STUDENT, 5 | UPDATE_PASSWORD, 6 | TEST_RESULT, 7 | ATTENDANCE, 8 | } from "../actionTypes"; 9 | 10 | const initialState = { 11 | authData: null, 12 | updatedPassword: false, 13 | updatedStudent: false, 14 | testAdded: false, 15 | marksUploaded: false, 16 | attendanceUploaded: false, 17 | testResult: [], 18 | tests: [], 19 | attendance: [], 20 | }; 21 | 22 | const studentReducer = (state = initialState, action) => { 23 | switch (action.type) { 24 | case STUDENT_LOGIN: 25 | localStorage.setItem("user", JSON.stringify({ ...action?.data })); 26 | return { ...state, authData: action?.data }; 27 | case LOGOUT: 28 | localStorage.clear(); 29 | return { ...state, authData: null }; 30 | case UPDATE_PASSWORD: 31 | return { 32 | ...state, 33 | updatedPassword: action.payload, 34 | }; 35 | case UPDATE_STUDENT: 36 | return { 37 | ...state, 38 | updatedStudent: action.payload, 39 | }; 40 | case TEST_RESULT: 41 | return { 42 | ...state, 43 | testResult: action.payload, 44 | }; 45 | case ATTENDANCE: 46 | return { 47 | ...state, 48 | attendance: action.payload, 49 | }; 50 | 51 | default: 52 | return state; 53 | } 54 | }; 55 | 56 | export default studentReducer; 57 | -------------------------------------------------------------------------------- /client/src/utils/Spinner.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Circles } from "react-loader-spinner"; 3 | const Spinner = ({ message, height, width, color, messageColor }) => { 4 | return ( 5 |
6 | 7 |

8 | {message} 9 |

10 |
11 | ); 12 | }; 13 | 14 | export default Spinner; 15 | -------------------------------------------------------------------------------- /client/src/utils/styles.js: -------------------------------------------------------------------------------- 1 | export const adminData = 2 | "flex flex-col overflow-y-auto scrollbar-thin scrollbar-track-white scrollbar-thumb-black h-[25rem] shadow-lg pl-5 rounded-md overflow-x-hidden"; 3 | 4 | export const adminDataBody = 5 | "grid grid-cols-12 hover:scale-105 transition-all duration-150"; 6 | 7 | export const adminDataHeading = "font-bold py-2 px-2"; 8 | export const adminDataBodyFields = "py-2 px-2"; 9 | 10 | export const adminFormSubmitButton = 11 | "bg-red-500 w-24 h-8 rounded-md text-white hover:scale-105 hover:bg-red-700 transition-all duration-200 "; 12 | export const adminFormClearButton = 13 | "bg-blue-500 w-24 h-8 rounded-md text-white hover:scale-105 hover:bg-blue-700 transition-all duration-200"; 14 | export const adminFormButton = "self-center space-x-6"; 15 | 16 | export const adminForm0 = "flex flex-col mb-6"; 17 | export const adminForm1 = "flex py-10 ml-10 space-x-28"; 18 | export const adminForm2l = "flex flex-col space-y-10"; 19 | export const adminForm2r = "flex flex-col space-y-10 pr-6"; 20 | export const adminForm3 = "grid grid-cols-2 gap-10"; 21 | 22 | export const adminLabel = 23 | "font-bold text-lg bg-gray-700 shadow-xl text-white px-2 py-1 rounded-lg"; 24 | export const adminInput = "border-2 px-2 py-1 text-sm"; 25 | 26 | export const loadingAndError = "flex justify-center mt-6"; 27 | -------------------------------------------------------------------------------- /client/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [require("tailwind-scrollbar")], 7 | }; 8 | -------------------------------------------------------------------------------- /preview/Admin.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brogrammer07/College-Erp/0c35a7738b0ff2766b1efd22bdcc6b3a4c3a4eb9/preview/Admin.mp4 -------------------------------------------------------------------------------- /preview/Faculty.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brogrammer07/College-Erp/0c35a7738b0ff2766b1efd22bdcc6b3a4c3a4eb9/preview/Faculty.mp4 -------------------------------------------------------------------------------- /preview/Student.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brogrammer07/College-Erp/0c35a7738b0ff2766b1efd22bdcc6b3a4c3a4eb9/preview/Student.mp4 -------------------------------------------------------------------------------- /server/.env.example: -------------------------------------------------------------------------------- 1 | CONNECTION_URL=MONGODB_URI -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .env -------------------------------------------------------------------------------- /server/Procfile: -------------------------------------------------------------------------------- 1 | web: npm run start -------------------------------------------------------------------------------- /server/controller/studentController.js: -------------------------------------------------------------------------------- 1 | import student from "../models/student.js"; 2 | import Test from "../models/test.js"; 3 | import Student from "../models/student.js"; 4 | import Subject from "../models/subject.js"; 5 | import Marks from "../models/marks.js"; 6 | import Attendence from "../models/attendance.js"; 7 | import jwt from "jsonwebtoken"; 8 | import bcrypt from "bcryptjs"; 9 | 10 | export const studentLogin = async (req, res) => { 11 | const { username, password } = req.body; 12 | const errors = { usernameError: String, passwordError: String }; 13 | try { 14 | const existingStudent = await Student.findOne({ username }); 15 | if (!existingStudent) { 16 | errors.usernameError = "Student doesn't exist."; 17 | return res.status(404).json(errors); 18 | } 19 | const isPasswordCorrect = await bcrypt.compare( 20 | password, 21 | existingStudent.password 22 | ); 23 | if (!isPasswordCorrect) { 24 | errors.passwordError = "Invalid Credentials"; 25 | return res.status(404).json(errors); 26 | } 27 | 28 | const token = jwt.sign( 29 | { 30 | email: existingStudent.email, 31 | id: existingStudent._id, 32 | }, 33 | "sEcReT", 34 | { expiresIn: "1h" } 35 | ); 36 | 37 | res.status(200).json({ result: existingStudent, token: token }); 38 | } catch (error) { 39 | console.log(error); 40 | } 41 | }; 42 | 43 | export const updatedPassword = async (req, res) => { 44 | try { 45 | const { newPassword, confirmPassword, email } = req.body; 46 | const errors = { mismatchError: String }; 47 | if (newPassword !== confirmPassword) { 48 | errors.mismatchError = 49 | "Your password and confirmation password do not match"; 50 | return res.status(400).json(errors); 51 | } 52 | 53 | const student = await Student.findOne({ email }); 54 | let hashedPassword; 55 | hashedPassword = await bcrypt.hash(newPassword, 10); 56 | student.password = hashedPassword; 57 | await student.save(); 58 | if (student.passwordUpdated === false) { 59 | student.passwordUpdated = true; 60 | await student.save(); 61 | } 62 | 63 | res.status(200).json({ 64 | success: true, 65 | message: "Password updated successfully", 66 | response: student, 67 | }); 68 | } catch (error) { 69 | res.status(500).json(error); 70 | } 71 | }; 72 | 73 | export const updateStudent = async (req, res) => { 74 | try { 75 | const { 76 | name, 77 | dob, 78 | department, 79 | contactNumber, 80 | avatar, 81 | email, 82 | batch, 83 | section, 84 | year, 85 | fatherName, 86 | motherName, 87 | fatherContactNumber, 88 | } = req.body; 89 | const updatedStudent = await Student.findOne({ email }); 90 | if (name) { 91 | updatedStudent.name = name; 92 | await updatedStudent.save(); 93 | } 94 | if (dob) { 95 | updatedStudent.dob = dob; 96 | await updatedStudent.save(); 97 | } 98 | if (department) { 99 | updatedStudent.department = department; 100 | await updatedStudent.save(); 101 | } 102 | if (contactNumber) { 103 | updatedStudent.contactNumber = contactNumber; 104 | await updatedStudent.save(); 105 | } 106 | if (batch) { 107 | updatedStudent.batch = batch; 108 | await updatedStudent.save(); 109 | } 110 | if (section) { 111 | updatedStudent.section = section; 112 | await updatedStudent.save(); 113 | } 114 | if (year) { 115 | updatedStudent.year = year; 116 | await updatedStudent.save(); 117 | } 118 | if (motherName) { 119 | updatedStudent.motherName = motherName; 120 | await updatedStudent.save(); 121 | } 122 | if (fatherName) { 123 | updatedStudent.fatherName = fatherName; 124 | await updatedStudent.save(); 125 | } 126 | if (fatherContactNumber) { 127 | updatedStudent.fatherContactNumber = fatherContactNumber; 128 | await updatedStudent.save(); 129 | } 130 | if (avatar) { 131 | updatedStudent.avatar = avatar; 132 | await updatedStudent.save(); 133 | } 134 | res.status(200).json(updatedStudent); 135 | } catch (error) { 136 | res.status(500).json(error); 137 | } 138 | }; 139 | 140 | export const testResult = async (req, res) => { 141 | try { 142 | const { department, year, section } = req.body; 143 | const errors = { notestError: String }; 144 | const student = await Student.findOne({ department, year, section }); 145 | const test = await Test.find({ department, year, section }); 146 | if (test.length === 0) { 147 | errors.notestError = "No Test Found"; 148 | return res.status(404).json(errors); 149 | } 150 | var result = []; 151 | for (var i = 0; i < test.length; i++) { 152 | var subjectCode = test[i].subjectCode; 153 | var subject = await Subject.findOne({ subjectCode }); 154 | var marks = await Marks.findOne({ 155 | student: student._id, 156 | exam: test[i]._id, 157 | }); 158 | if (marks) { 159 | var temp = { 160 | marks: marks.marks, 161 | totalMarks: test[i].totalMarks, 162 | subjectName: subject.subjectName, 163 | subjectCode, 164 | test: test[i].test, 165 | }; 166 | 167 | result.push(temp); 168 | } 169 | } 170 | 171 | res.status(200).json({ result }); 172 | } catch (error) { 173 | res.status(500).json(error); 174 | } 175 | }; 176 | 177 | export const attendance = async (req, res) => { 178 | try { 179 | const { department, year, section } = req.body; 180 | const errors = { notestError: String }; 181 | const student = await Student.findOne({ department, year, section }); 182 | 183 | const attendence = await Attendence.find({ 184 | student: student._id, 185 | }).populate("subject"); 186 | if (!attendence) { 187 | res.status(400).json({ message: "Attendence not found" }); 188 | } 189 | 190 | res.status(200).json({ 191 | result: attendence.map((att) => { 192 | let res = {}; 193 | res.percentage = ( 194 | (att.lectureAttended / att.totalLecturesByFaculty) * 195 | 100 196 | ).toFixed(2); 197 | res.subjectCode = att.subject.subjectCode; 198 | res.subjectName = att.subject.subjectName; 199 | res.attended = att.lectureAttended; 200 | res.total = att.totalLecturesByFaculty; 201 | return res; 202 | }), 203 | }); 204 | } catch (error) { 205 | res.status(500).json(error); 206 | } 207 | }; 208 | -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import bodyParser from "body-parser"; 3 | import mongoose from "mongoose"; 4 | import cors from "cors"; 5 | import dotenv from "dotenv"; 6 | 7 | import adminRoutes from "./routes/adminRoutes.js"; 8 | import studentRoutes from "./routes/studentRoutes.js"; 9 | import facultyRoutes from "./routes/facultyRoutes.js"; 10 | import { addDummyAdmin } from "./controller/adminController.js"; 11 | const app = express(); 12 | dotenv.config(); 13 | app.use(bodyParser.json({ limit: "30mb", extended: true })); 14 | app.use(bodyParser.urlencoded({ limit: "30mb", extended: true })); 15 | app.use(cors()); 16 | 17 | app.use("/api/admin", adminRoutes); 18 | app.use("/api/faculty", facultyRoutes); 19 | app.use("/api/student", studentRoutes); 20 | 21 | const PORT = process.env.PORT || 5001; 22 | app.get("/", (req, res) => { 23 | res.send("Hello to college erp API"); 24 | }); 25 | mongoose 26 | .connect(process.env.CONNECTION_URL, { 27 | useNewUrlParser: true, 28 | useUnifiedTopology: true, 29 | }) 30 | .then(() => { 31 | addDummyAdmin(); 32 | app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); 33 | }) 34 | .catch((error) => console.log("Mongo Error", error.message)); 35 | -------------------------------------------------------------------------------- /server/middleware/auth.js: -------------------------------------------------------------------------------- 1 | import jwt from "jsonwebtoken"; 2 | 3 | const auth = async (req, res, next) => { 4 | try { 5 | const token = req.headers.authorization.split(" ")[1]; 6 | let decodedData; 7 | if (token) { 8 | decodedData = jwt.verify(token, "sEcReT"); 9 | req.userId = decodedData?.id; 10 | } 11 | next(); 12 | } catch (error) { 13 | console.log(error); 14 | } 15 | }; 16 | 17 | export default auth; 18 | -------------------------------------------------------------------------------- /server/models/admin.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const adminSchema = mongoose.Schema( 4 | { 5 | name: { 6 | type: String, 7 | require: true, 8 | }, 9 | email: { 10 | type: String, 11 | required: true, 12 | unique: true, 13 | }, 14 | password: { 15 | type: String, 16 | }, 17 | username: { 18 | type: String, 19 | }, 20 | department: { 21 | type: String, 22 | }, 23 | dob: { 24 | type: String, 25 | }, 26 | joiningYear: { 27 | type: String, 28 | }, 29 | avatar: { 30 | type: String, 31 | }, 32 | contactNumber: { 33 | type: Number, 34 | }, 35 | passwordUpdated: { 36 | type: Boolean, 37 | default: false, 38 | }, 39 | }, 40 | { strict: false } 41 | ); 42 | 43 | export default mongoose.model("admin", adminSchema); 44 | -------------------------------------------------------------------------------- /server/models/attendance.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | const { Schema } = mongoose; 3 | const attendenceSchema = new Schema({ 4 | student: { 5 | type: Schema.Types.ObjectId, 6 | ref: "student", 7 | }, 8 | subject: { 9 | type: Schema.Types.ObjectId, 10 | ref: "subject", 11 | }, 12 | totalLecturesByFaculty: { 13 | type: Number, 14 | default: 0, 15 | }, 16 | lectureAttended: { 17 | type: Number, 18 | default: 0, 19 | }, 20 | }); 21 | 22 | export default mongoose.model("attendance", attendenceSchema); 23 | -------------------------------------------------------------------------------- /server/models/department.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const departmentSchema = mongoose.Schema({ 4 | department: { 5 | type: String, 6 | required: true, 7 | }, 8 | departmentCode: { 9 | type: String, 10 | required: true, 11 | unique: true, 12 | }, 13 | }); 14 | 15 | export default mongoose.model("department", departmentSchema); 16 | -------------------------------------------------------------------------------- /server/models/faculty.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const facultySchema = mongoose.Schema({ 4 | name: { 5 | type: String, 6 | required: true, 7 | }, 8 | email: { 9 | type: String, 10 | required: true, 11 | unique: true, 12 | }, 13 | avatar: { 14 | type: String, 15 | }, 16 | password: { 17 | type: String, 18 | }, 19 | username: { 20 | type: String, 21 | }, 22 | gender: { 23 | type: String, 24 | }, 25 | designation: { 26 | type: String, 27 | required: true, 28 | }, 29 | department: { 30 | type: String, 31 | required: true, 32 | }, 33 | contactNumber: { 34 | type: Number, 35 | }, 36 | dob: { 37 | type: String, 38 | required: true, 39 | }, 40 | joiningYear: { 41 | type: Number, 42 | required: true, 43 | }, 44 | passwordUpdated: { 45 | type: Boolean, 46 | default: false, 47 | }, 48 | }); 49 | 50 | export default mongoose.model("faculty", facultySchema); 51 | -------------------------------------------------------------------------------- /server/models/marks.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | const { Schema } = mongoose; 3 | 4 | const marksSchema = new Schema({ 5 | exam: { 6 | type: Schema.Types.ObjectId, 7 | ref: "test", 8 | }, 9 | student: { 10 | type: Schema.Types.ObjectId, 11 | ref: "student", 12 | }, 13 | marks: { 14 | type: Number, 15 | default: -1, 16 | }, 17 | }); 18 | 19 | export default mongoose.model("marks", marksSchema); 20 | -------------------------------------------------------------------------------- /server/models/notice.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const noticeSchema = mongoose.Schema({ 4 | topic: { 5 | type: String, 6 | require: true, 7 | }, 8 | date: { 9 | type: String, 10 | require: true, 11 | }, 12 | content: { 13 | type: String, 14 | require: true, 15 | }, 16 | from: { 17 | type: String, 18 | require: true, 19 | }, 20 | noticeFor: { 21 | type: String, 22 | require: true, 23 | }, 24 | }); 25 | 26 | export default mongoose.model("notice", noticeSchema); 27 | -------------------------------------------------------------------------------- /server/models/student.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | const { Schema } = mongoose; 3 | const studentSchema = new Schema({ 4 | name: { 5 | type: String, 6 | required: true, 7 | }, 8 | email: { 9 | type: String, 10 | required: true, 11 | unique: true, 12 | }, 13 | avatar: { 14 | type: String, 15 | }, 16 | password: { 17 | type: String, 18 | required: true, 19 | }, 20 | year: { 21 | type: Number, 22 | required: true, 23 | }, 24 | subjects: [ 25 | { 26 | type: Schema.Types.ObjectId, 27 | ref: "subject", 28 | }, 29 | ], 30 | username: { 31 | type: String, 32 | }, 33 | gender: { 34 | type: String, 35 | }, 36 | fatherName: { 37 | type: String, 38 | }, 39 | motherName: { 40 | type: String, 41 | }, 42 | department: { 43 | type: String, 44 | required: true, 45 | }, 46 | section: { 47 | type: String, 48 | required: true, 49 | }, 50 | batch: { 51 | type: String, 52 | }, 53 | contactNumber: { 54 | type: Number, 55 | }, 56 | fatherContactNumber: { 57 | type: Number, 58 | }, 59 | dob: { 60 | type: String, 61 | required: true, 62 | }, 63 | passwordUpdated: { 64 | type: Boolean, 65 | default: false, 66 | }, 67 | }); 68 | 69 | export default mongoose.model("student", studentSchema); 70 | -------------------------------------------------------------------------------- /server/models/subject.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | const { Schema } = mongoose; 3 | const subjectSchema = new Schema({ 4 | subjectName: { 5 | type: String, 6 | required: true, 7 | trim: true, 8 | }, 9 | subjectCode: { 10 | type: String, 11 | required: true, 12 | }, 13 | department: { 14 | type: String, 15 | required: true, 16 | }, 17 | totalLectures: { 18 | type: Number, 19 | default: 10, 20 | }, 21 | year: { 22 | type: String, 23 | required: true, 24 | }, 25 | attendence: { 26 | type: Schema.Types.ObjectId, 27 | ref: "attendence", 28 | }, 29 | }); 30 | 31 | export default mongoose.model("subject", subjectSchema); 32 | -------------------------------------------------------------------------------- /server/models/test.js: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const testSchema = mongoose.Schema({ 4 | test: { 5 | type: String, 6 | required: true, 7 | trim: true, 8 | }, 9 | subjectCode: { 10 | type: String, 11 | required: true, 12 | }, 13 | department: { 14 | type: String, 15 | required: true, 16 | }, 17 | totalMarks: { 18 | type: Number, 19 | default: 10, 20 | }, 21 | year: { 22 | type: String, 23 | required: true, 24 | }, 25 | section: { 26 | type: String, 27 | required: true, 28 | }, 29 | date: { 30 | type: String, 31 | required: true, 32 | }, 33 | }); 34 | 35 | export default mongoose.model("test", testSchema); 36 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "nodemon index.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "bcryptjs": "^2.4.3", 15 | "body-parser": "^1.19.1", 16 | "cors": "^2.8.5", 17 | "dotenv": "^16.0.0", 18 | "express": "^4.17.2", 19 | "jsonwebtoken": "^8.5.1", 20 | "mongoose": "^6.2.0", 21 | "nodemon": "^2.0.15" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /server/routes/adminRoutes.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import auth from "../middleware/auth.js"; 3 | import { 4 | adminLogin, 5 | updateAdmin, 6 | addAdmin, 7 | addFaculty, 8 | getFaculty, 9 | addSubject, 10 | getSubject, 11 | addStudent, 12 | getStudent, 13 | addDepartment, 14 | getAllStudent, 15 | getAllFaculty, 16 | getAllAdmin, 17 | getAllDepartment, 18 | getAllSubject, 19 | updatedPassword, 20 | getAdmin, 21 | deleteAdmin, 22 | deleteDepartment, 23 | deleteFaculty, 24 | deleteStudent, 25 | deleteSubject, 26 | createNotice, 27 | getNotice, 28 | } from "../controller/adminController.js"; 29 | const router = express.Router(); 30 | 31 | router.post("/login", adminLogin); 32 | router.post("/updatepassword", auth, updatedPassword); 33 | router.get("/getallstudent", auth, getAllStudent); 34 | router.post("/createnotice", auth, createNotice); 35 | router.get("/getallfaculty", auth, getAllFaculty); 36 | router.get("/getalldepartment", auth, getAllDepartment); 37 | router.get("/getallsubject", auth, getAllSubject); 38 | router.get("/getalladmin", auth, getAllAdmin); 39 | router.post("/updateprofile", auth, updateAdmin); 40 | router.post("/addadmin", auth, addAdmin); 41 | router.post("/adddepartment", auth, addDepartment); 42 | router.post("/addfaculty", auth, addFaculty); 43 | router.post("/getfaculty", auth, getFaculty); 44 | router.post("/addsubject", auth, addSubject); 45 | router.post("/getsubject", auth, getSubject); 46 | router.post("/addstudent", auth, addStudent); 47 | router.post("/getstudent", auth, getStudent); 48 | router.post("/getnotice", auth, getNotice); 49 | router.post("/getadmin", auth, getAdmin); 50 | router.post("/deleteadmin", auth, deleteAdmin); 51 | router.post("/deletefaculty", auth, deleteFaculty); 52 | router.post("/deletestudent", auth, deleteStudent); 53 | router.post("/deletedepartment", auth, deleteDepartment); 54 | router.post("/deletesubject", auth, deleteSubject); 55 | 56 | export default router; 57 | -------------------------------------------------------------------------------- /server/routes/facultyRoutes.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { 3 | facultyLogin, 4 | updatedPassword, 5 | updateFaculty, 6 | createTest, 7 | getTest, 8 | getStudent, 9 | uploadMarks, 10 | markAttendance, 11 | } from "../controller/facultyController.js"; 12 | import auth from "../middleware/auth.js"; 13 | 14 | const router = express.Router(); 15 | 16 | router.post("/login", facultyLogin); 17 | router.post("/updatepassword", auth, updatedPassword); 18 | router.post("/updateprofile", auth, updateFaculty); 19 | router.post("/createtest", auth, createTest); 20 | router.post("/gettest", auth, getTest); 21 | router.post("/getstudent", auth, getStudent); 22 | router.post("/uploadmarks", auth, uploadMarks); 23 | router.post("/markattendance", auth, markAttendance); 24 | 25 | export default router; 26 | -------------------------------------------------------------------------------- /server/routes/studentRoutes.js: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { 3 | studentLogin, 4 | updatedPassword, 5 | updateStudent, 6 | testResult, 7 | attendance, 8 | } from "../controller/studentController.js"; 9 | import auth from "../middleware/auth.js"; 10 | 11 | const router = express.Router(); 12 | 13 | router.post("/login", studentLogin); 14 | router.post("/updatepassword", auth, updatedPassword); 15 | router.post("/updateprofile", auth, updateStudent); 16 | router.post("/testresult", auth, testResult); 17 | router.post("/attendance", auth, attendance); 18 | 19 | export default router; 20 | --------------------------------------------------------------------------------