Repository: shashiben/Hostel-Management
Branch: master
Commit: 0a2153e5af2b
Files: 65
Total size: 156.2 KB
Directory structure:
gitextract_epyapo_v/
├── .eslintcache
├── .gitignore
├── .vscode/
│ └── settings.json
├── Procfile
├── README.md
├── frontend/
│ ├── .eslintcache
│ ├── index.html
│ ├── package.json
│ ├── public/
│ │ ├── manifest.json
│ │ └── robots.txt
│ ├── src/
│ │ ├── App.jsx
│ │ ├── actions/
│ │ │ ├── attendanceActions.jsx
│ │ │ ├── studentActions.jsx
│ │ │ └── userActions.jsx
│ │ ├── components/
│ │ │ ├── analysisComponent.jsx
│ │ │ ├── attendanceTable.jsx
│ │ │ ├── attendanceTableComponent.jsx
│ │ │ ├── footer.jsx
│ │ │ ├── formContainer.jsx
│ │ │ ├── header.jsx
│ │ │ ├── loader.jsx
│ │ │ ├── message.jsx
│ │ │ ├── paginate.jsx
│ │ │ ├── rating.jsx
│ │ │ ├── searchBox.jsx
│ │ │ └── student.jsx
│ │ ├── constants/
│ │ │ ├── attendanceConstant.jsx
│ │ │ ├── studentConstant.jsx
│ │ │ └── userConstants.jsx
│ │ ├── css/
│ │ │ └── index.css
│ │ ├── main.jsx
│ │ ├── reducers/
│ │ │ ├── attendanceReducer.jsx
│ │ │ ├── studentsReducer.jsx
│ │ │ └── userReducers.jsx
│ │ ├── reportWebVitals.js
│ │ ├── screens/
│ │ │ ├── Authentication Screens/
│ │ │ │ ├── LoginView.jsx
│ │ │ │ └── RegisterView.jsx
│ │ │ ├── addStudentView.jsx
│ │ │ ├── analysisView.jsx
│ │ │ ├── attendanceView.jsx
│ │ │ ├── homeView.jsx
│ │ │ ├── profileView.jsx
│ │ │ ├── studentDetailsView.jsx
│ │ │ ├── studentTableView.jsx
│ │ │ ├── userEditView.jsx
│ │ │ └── userListView.jsx
│ │ └── store.jsx
│ └── vite.config.js
├── package.json
└── server/
├── config/
│ └── mongoDBConfig.js
├── controllers/
│ ├── attendanceController.js
│ ├── studentController.js
│ └── userController.js
├── data/
│ └── students.js
├── index.js
├── middleware/
│ ├── authMiddleware.js
│ └── errorMiddleware.js
├── models/
│ ├── attendance.js
│ ├── student.js
│ └── user.js
├── routes/
│ ├── attendanceRoutes.js
│ ├── studentRoutes.js
│ └── userRoutes.js
├── seeder.js
└── utils/
└── generateToken.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .eslintcache
================================================
[{"/home/shashi/Projects/React Projects/hostel-app/src/reportWebVitals.js":"1","/home/shashi/Projects/React Projects/hostel-app/src/components/header.jsx":"2","/home/shashi/Projects/React Projects/hostel-app/src/reducers/orphanageReducer.jsx":"3","/home/shashi/Projects/React Projects/hostel-app/src/components/orphanage.jsx":"4","/home/shashi/Projects/React Projects/hostel-app/src/constants/orphanageConstant.jsx":"5","/home/shashi/Projects/React Projects/hostel-app/src/App.js":"6","/home/shashi/Projects/React Projects/hostel-app/src/screens/orphangeDetailsView.jsx":"7","/home/shashi/Projects/React Projects/hostel-app/src/screens/homeView.jsx":"8","/home/shashi/Projects/React Projects/hostel-app/src/components/searchBox.jsx":"9","/home/shashi/Projects/React Projects/hostel-app/src/screens/addStudentView.jsx":"10","/home/shashi/Projects/React Projects/hostel-app/src/screens/analysisView.jsx":"11","/home/shashi/Projects/React Projects/hostel-app/src/actions/orphanageActions.jsx":"12","/home/shashi/Projects/React Projects/hostel-app/src/screens/editOrphanageDetails.jsx":"13"},{"size":362,"mtime":1611587355656,"results":"14","hashOfConfig":"15"},{"size":1420,"mtime":1611588899653,"results":"16","hashOfConfig":"15"},{"size":2572,"mtime":1611587355656,"results":"17","hashOfConfig":"15"},{"size":1015,"mtime":1611587355656,"results":"18","hashOfConfig":"15"},{"size":1091,"mtime":1611587355656,"results":"19","hashOfConfig":"15"},{"size":1181,"mtime":1611590345616,"results":"20","hashOfConfig":"15"},{"size":3630,"mtime":1611587679636,"results":"21","hashOfConfig":"15"},{"size":1240,"mtime":1611588079853,"results":"22","hashOfConfig":"15"},{"size":783,"mtime":1611588125620,"results":"23","hashOfConfig":"15"},{"size":4986,"mtime":1611590107133,"results":"24","hashOfConfig":"15"},{"size":1222,"mtime":1611591364130,"results":"25","hashOfConfig":"15"},{"size":4092,"mtime":1611587355653,"results":"26","hashOfConfig":"15"},{"size":4936,"mtime":1611587355656,"results":"27","hashOfConfig":"15"},{"filePath":"28","messages":"29","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"30"},"cbixyl",{"filePath":"31","messages":"32","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"33","usedDeprecatedRules":"30"},{"filePath":"34","messages":"35","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"38","messages":"39","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"40","messages":"41","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"42","messages":"43","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"44","usedDeprecatedRules":"45"},{"filePath":"46","messages":"47","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"30"},{"filePath":"48","messages":"49","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"45"},{"filePath":"50","messages":"51","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"52","messages":"53","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"54","usedDeprecatedRules":"30"},{"filePath":"55","messages":"56","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"57","messages":"58","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/home/shashi/Projects/React Projects/hostel-app/src/reportWebVitals.js",[],["59","60"],"/home/shashi/Projects/React Projects/hostel-app/src/components/header.jsx",["61","62"],"import React from 'react'\nimport { Container, Nav, Navbar, NavDropdown } from 'react-bootstrap'\nimport { Route } from 'react-router-dom'\nimport { LinkContainer } from 'react-router-bootstrap'\nimport SearchBox from './searchBox'\n\nconst Header = () => {\n return (\n \n \n \n \n NSD Solutions\n \n \n \n } />\n\n \n \n \n \n \n )\n}\n\nexport default Header\n","/home/shashi/Projects/React Projects/hostel-app/src/reducers/orphanageReducer.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/src/components/orphanage.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/src/constants/orphanageConstant.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/src/App.js",[],"/home/shashi/Projects/React Projects/hostel-app/src/screens/orphangeDetailsView.jsx",["63"],"import React, { useEffect } from 'react'\nimport { useDispatch, useSelector } from 'react-redux'\n\nimport {\n getorphanageDetails,\n deleteOrphanage,\n} from '../actions/orphanageActions'\nimport { Row, Col, Image, ListGroup, Card, Button } from 'react-bootstrap'\nimport { Link } from 'react-router-dom'\nimport Rating from '../components/rating'\nimport Loading from '../components/loader.jsx'\nimport Message from '../components/message.jsx'\nimport { ORPHANAGE_DELETE_RESET } from '../constants/orphanageConstant'\n\nconst OrphanageDetailsView = ({ history, match }) => {\n const orphanageId = match.params.id\n const dispatch = useDispatch()\n const orphanageDetails = useSelector((state) => state.orphanageDetails)\n const { loading, error, orphanage } = orphanageDetails\n const orphanageDelete = useSelector((state) => state.orphanageDelete)\n const {\n loading: loadingDelete,\n error: errorDelete,\n success,\n } = orphanageDelete\n useEffect(() => {\n if (success) {\n dispatch({ type: ORPHANAGE_DELETE_RESET })\n history.push('/')\n }\n console.log(JSON.stringify(orphanage))\n if (orphanageId !== orphanage._id) {\n dispatch(getorphanageDetails(orphanageId))\n }\n }, [dispatch, match, success])\n\n const pushToEdit = () => {\n history.push(`/orphanage/${orphanage._id}/edit`)\n }\n\n const deleteOrphanag = () => {\n dispatch(deleteOrphanage(orphanageId))\n }\n\n \n\n \n\n return (\n <>\n \n Go Back\n \n {loadingDelete && }\n {errorDelete && {errorDelete}}\n {loading ? (\n \n ) : error ? (\n {error}\n ) : (\n \n \n \n \n \n \n \n {orphanage.name}
\n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n Contact:\n \n {orphanage.contact}\n \n
\n \n \n \n Address:\n \n {orphanage.city},{orphanage.state}\n \n
\n \n \n \n \n \n \n \n \n
\n )}\n >\n )\n}\n\nexport default OrphanageDetailsView\n",["64","65"],"/home/shashi/Projects/React Projects/hostel-app/src/screens/homeView.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/src/components/searchBox.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/src/screens/addStudentView.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/src/screens/analysisView.jsx",["66"],"import React, { useState, useEffect } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { Row, Col, Table } from \"react-bootstrap\";\nimport DatePicker from \"react-datepicker\";\nimport \"react-datepicker/dist/react-datepicker.css\";\n\nconst AnalysisView = () => {\n const [startDate, setStartDate] = useState(new Date());\n\n return (\n <>\n \n Go Back\n \n
\n \n \n Analysis for
\n \n {startDate.toISOString().toString().substring(0, 10)}\n \n \n \n setStartDate(date)}\n />\n \n
\n \n \n \n | Name | \n Contact No | \n Room No | \n Block No | \n Category | \n Attendance | \n
\n \n
\n \n >\n );\n};\n\nexport default AnalysisView;\n","/home/shashi/Projects/React Projects/hostel-app/src/actions/orphanageActions.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/src/screens/editOrphanageDetails.jsx",[],{"ruleId":"67","replacedBy":"68"},{"ruleId":"69","replacedBy":"70"},{"ruleId":"71","severity":1,"message":"72","line":3,"column":10,"nodeType":"73","messageId":"74","endLine":3,"endColumn":15},{"ruleId":"71","severity":1,"message":"75","line":5,"column":8,"nodeType":"73","messageId":"74","endLine":5,"endColumn":17},{"ruleId":"76","severity":1,"message":"77","line":35,"column":6,"nodeType":"78","endLine":35,"endColumn":32,"suggestions":"79"},{"ruleId":"67","replacedBy":"80"},{"ruleId":"69","replacedBy":"81"},{"ruleId":"71","severity":1,"message":"82","line":1,"column":27,"nodeType":"73","messageId":"74","endLine":1,"endColumn":36},"no-native-reassign",["83"],"no-negated-in-lhs",["84"],"no-unused-vars","'Route' is defined but never used.","Identifier","unusedVar","'SearchBox' is defined but never used.","react-hooks/exhaustive-deps","React Hook useEffect has missing dependencies: 'history', 'orphanage', and 'orphanageId'. Either include them or remove the dependency array.","ArrayExpression",["85"],["83"],["84"],"'useEffect' is defined but never used.","no-global-assign","no-unsafe-negation",{"desc":"86","fix":"87"},"Update the dependencies array to be: [dispatch, history, match, orphanage, orphanageId, success]",{"range":"88","text":"89"},[1198,1224],"[dispatch, history, match, orphanage, orphanageId, success]"]
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
node_modules/
/.pnp
.pnp.js
# testing
/coverage
# production
/frontend/build
/frontend/dist
/frontend/node_modules
# misc
.DS_Store
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
================================================
FILE: .vscode/settings.json
================================================
{
"cmake.configureOnOpen": true
}
================================================
FILE: Procfile
================================================
web: node server/index.js
================================================
FILE: README.md
================================================
# 🏠 Hostel Management
**MERN-ish chaos, now with Vite** — Express + MongoDB in the back, React + Redux up front. No Next.js; we’re not that fancy. Yet.
---
## 🚀 Run this thing (3 steps, you’ve got this)
1. **Feed the machine**
```bash
npm install && npm install --prefix frontend
```
2. **Summon Mongo** 🍃
Have MongoDB running somewhere. If it’s not up, the API will ghost you harder than a bad roommate.
3. **Whisper secrets** (repo root, `.env`)
```env
NODE_ENV=development
PORT=5000
MONGO_URI=mongodb://127.0.0.1:27017/your_db_name
JWT_SECRET=make_it_long_and_random_no_password123_pls
```
4. **Hit go** 🎬
```bash
npm run dev
```
- UI: [http://localhost:3000](http://localhost:3000)
- API: [http://localhost:5000](http://localhost:5000) (dev says “API is running” — it’s shy, not broken)
**Production build** (when you’re showing off):
`npm run build --prefix frontend` then `NODE_ENV=production npm start`
---
## ✨ What it does (feature buffet)
| | |
|---|---|
| 🔐 | Register / login (navbar stays minimal until you’re in — we’re not nosy) |
| 👤 | Student CRUD + details |
| 📍 | Update student whereabouts |
| ✅ | Daily attendance |
| 📊 | Analysis views |
| 📥 | CSV export for attendance |
| 🗑️ | Nuke old attendance by “last N days” |
| 👑 | Admin: user list + toggle admin status |
---
## 🤝 Contributing
PRs welcome. Big ideas? Open an issue first so we can panic together constructively.
Tests: `npm test --prefix frontend` (Vitest; add tests if you’re feeling brave).
================================================
FILE: frontend/.eslintcache
================================================
[{"/home/shashi/Projects/React Projects/hostel-app/frontend/src/App.js":"1","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/homeView.jsx":"2","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/addStudentView.jsx":"3","/home/shashi/Projects/React Projects/hostel-app/frontend/src/index.js":"4","/home/shashi/Projects/React Projects/hostel-app/frontend/src/store.jsx":"5","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/header.jsx":"6","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/message.jsx":"7","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/rating.jsx":"8","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/searchBox.jsx":"9","/home/shashi/Projects/React Projects/hostel-app/frontend/src/reducers/studentsReducer.jsx":"10","/home/shashi/Projects/React Projects/hostel-app/frontend/src/constants/studentConstant.jsx":"11","/home/shashi/Projects/React Projects/hostel-app/frontend/src/actions/studentActions.jsx":"12","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/student.jsx":"13","/home/shashi/Projects/React Projects/hostel-app/frontend/src/actions/userActions.jsx":"14","/home/shashi/Projects/React Projects/hostel-app/frontend/src/reducers/userReducers.jsx":"15","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/Authentication Screens/LoginView.jsx":"16","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/formContainer.jsx":"17","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/Authentication Screens/RegisterView.jsx":"18","/home/shashi/Projects/React Projects/hostel-app/frontend/src/constants/userConstants.jsx":"19","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/analysisView.jsx":"20","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/loader.jsx":"21","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/footer.jsx":"22","/home/shashi/Projects/React Projects/hostel-app/frontend/src/reportWebVitals.js":"23","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/paginate.jsx":"24","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/studentDetailsView.jsx":"25","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/studentTableView.jsx":"26","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/attendanceView.jsx":"27","/home/shashi/Projects/React Projects/hostel-app/frontend/src/reducers/attendanceReducer.jsx":"28","/home/shashi/Projects/React Projects/hostel-app/frontend/src/actions/attendanceActions.jsx":"29","/home/shashi/Projects/React Projects/hostel-app/frontend/src/constants/attendanceConstant.jsx":"30","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/analysisComponent.jsx":"31","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/attendanceTable.jsx":"32","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/attendanceTableComponent.jsx":"33","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/profileView.jsx":"34","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/userListView.jsx":"35","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/userEditView.jsx":"36"},{"size":2000,"mtime":1612457509687,"results":"37","hashOfConfig":"38"},{"size":2760,"mtime":1612458544737,"results":"39","hashOfConfig":"38"},{"size":7160,"mtime":1612266721633,"results":"40","hashOfConfig":"38"},{"size":595,"mtime":1611587355656,"results":"41","hashOfConfig":"38"},{"size":1760,"mtime":1612540038213,"results":"42","hashOfConfig":"38"},{"size":2509,"mtime":1612455514013,"results":"43","hashOfConfig":"38"},{"size":236,"mtime":1611587355656,"results":"44","hashOfConfig":"38"},{"size":1670,"mtime":1611587355656,"results":"45","hashOfConfig":"38"},{"size":783,"mtime":1611588125620,"results":"46","hashOfConfig":"38"},{"size":3180,"mtime":1612338704456,"results":"47","hashOfConfig":"38"},{"size":1297,"mtime":1612276158097,"results":"48","hashOfConfig":"38"},{"size":4652,"mtime":1612511277820,"results":"49","hashOfConfig":"38"},{"size":861,"mtime":1612458074420,"results":"50","hashOfConfig":"38"},{"size":6593,"mtime":1612243543269,"results":"51","hashOfConfig":"38"},{"size":3520,"mtime":1612243170023,"results":"52","hashOfConfig":"38"},{"size":2146,"mtime":1612242755929,"results":"53","hashOfConfig":"38"},{"size":331,"mtime":1611587355653,"results":"54","hashOfConfig":"38"},{"size":3149,"mtime":1612243440719,"results":"55","hashOfConfig":"38"},{"size":1502,"mtime":1612242844223,"results":"56","hashOfConfig":"38"},{"size":3733,"mtime":1612540523853,"results":"57","hashOfConfig":"38"},{"size":386,"mtime":1611587355656,"results":"58","hashOfConfig":"38"},{"size":280,"mtime":1611587355653,"results":"59","hashOfConfig":"38"},{"size":362,"mtime":1611587355656,"results":"60","hashOfConfig":"38"},{"size":743,"mtime":1612503930076,"results":"61","hashOfConfig":"38"},{"size":5749,"mtime":1612511177533,"results":"62","hashOfConfig":"38"},{"size":2402,"mtime":1612440885763,"results":"63","hashOfConfig":"38"},{"size":1116,"mtime":1612453105207,"results":"64","hashOfConfig":"38"},{"size":1789,"mtime":1612540078413,"results":"65","hashOfConfig":"38"},{"size":2462,"mtime":1612540492013,"results":"66","hashOfConfig":"38"},{"size":859,"mtime":1612539882713,"results":"67","hashOfConfig":"38"},{"size":2641,"mtime":1612539718740,"results":"68","hashOfConfig":"38"},{"size":2085,"mtime":1612454468233,"results":"69","hashOfConfig":"38"},{"size":3361,"mtime":1612453607120,"results":"70","hashOfConfig":"38"},{"size":3635,"mtime":1612455338080,"results":"71","hashOfConfig":"38"},{"size":2730,"mtime":1612457423720,"results":"72","hashOfConfig":"38"},{"size":3182,"mtime":1612457679380,"results":"73","hashOfConfig":"38"},{"filePath":"74","messages":"75","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"76"},"cy2yr9",{"filePath":"77","messages":"78","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"79","usedDeprecatedRules":"76"},{"filePath":"80","messages":"81","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"83","messages":"84","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"85"},{"filePath":"86","messages":"87","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"88","messages":"89","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"90","messages":"91","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"92"},{"filePath":"93","messages":"94","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"96","messages":"97","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"98"},{"filePath":"99","messages":"100","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},{"filePath":"102","messages":"103","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"76"},{"filePath":"104","messages":"105","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"106","messages":"107","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},{"filePath":"108","messages":"109","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"76"},{"filePath":"110","messages":"111","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},{"filePath":"112","messages":"113","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"114","messages":"115","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},{"filePath":"116","messages":"117","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"118","messages":"119","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},{"filePath":"120","messages":"121","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"122"},{"filePath":"123","messages":"124","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"125","messages":"126","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},{"filePath":"127","messages":"128","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},{"filePath":"129","messages":"130","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},{"filePath":"131","messages":"132","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"133","usedDeprecatedRules":"101"},{"filePath":"134","messages":"135","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"136","usedDeprecatedRules":"82"},{"filePath":"137","messages":"138","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"76"},{"filePath":"139","messages":"140","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"141","messages":"142","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"143","messages":"144","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"145","messages":"146","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"147","messages":"148","errorCount":0,"warningCount":3,"fixableErrorCount":0,"fixableWarningCount":0,"source":"149","usedDeprecatedRules":"82"},{"filePath":"150","messages":"151","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":"152"},{"filePath":"153","messages":"154","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"95"},{"filePath":"155","messages":"156","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"157","messages":"158","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"101"},"/home/shashi/Projects/React Projects/hostel-app/frontend/src/App.js",[],["159","160"],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/homeView.jsx",["161"],"import React, { useEffect, useState } from \"react\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport Student from \"../components/student\";\nimport Loading from \"../components/loader.jsx\";\nimport Message from \"../components/message.jsx\";\nimport { listStudents } from \"../actions/studentActions\";\nimport Paginate from \"../components/paginate\";\nimport {\n Row,\n Col,\n ButtonGroup,\n ToggleButton,\n Container,\n} from \"react-bootstrap\";\nimport StudentsTableView from \"./studentTableView\";\n\nconst HomeView = ({ match, history }) => {\n const [isGrid, setIsGrid] = useState(true);\n const keyword = match.params.keyword;\n\n const pageNumber = match.params.pageNumber || 1;\n const userLogin = useSelector((state) => state.userLogin);\n const { loading: userLoading, userInfo } = userLogin;\n\n const dispatch = useDispatch();\n\n const studentsList = useSelector((state) => state.studentsList);\n const { loading, error, students, page, pages } = studentsList;\n\n useEffect(() => {\n if (!userLoading && !userInfo) {\n history.push(\"/login\");\n }\n dispatch(listStudents(keyword, pageNumber));\n }, [keyword, pageNumber]);\n\n return (\n <>\n <>\n \n \n \n \n \n {[\"Grid\", \"Table\"].map((type) => (\n \n setIsGrid(e.target.value === \"Grid\" ? true : false)\n }\n >\n {type === \"Grid\" ? <> Grid> : <> Table >}\n \n ))}\n \n \n \n
\n \n >\n\n Students
\n {loading ? (\n \n ) : error ? (\n {error}\n ) : isGrid ? (\n <>\n \n {students.map((student) => (\n \n \n \n ))}\n
\n \n >\n ) : (\n <>\n \n >\n )}\n >\n );\n};\n\nexport default HomeView;\n","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/addStudentView.jsx",[],["162","163"],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/index.js",[],["164","165"],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/store.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/header.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/message.jsx",[],["166","167"],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/rating.jsx",[],["168","169"],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/searchBox.jsx",[],["170","171"],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/reducers/studentsReducer.jsx",[],["172","173"],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/constants/studentConstant.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/actions/studentActions.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/student.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/actions/userActions.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/reducers/userReducers.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/Authentication Screens/LoginView.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/formContainer.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/Authentication Screens/RegisterView.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/constants/userConstants.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/analysisView.jsx",["174","175"],"import React, { useState, useEffect } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { Row, Col, Button, Modal, Form } from \"react-bootstrap\";\nimport DatePicker from \"react-datepicker\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport \"react-datepicker/dist/react-datepicker.css\";\nimport {\n deleteAttendanceByDate,\n getAnalysisByDate,\n} from \"../actions/attendanceActions\";\nimport AnalysisComponent from \"../components/analysisComponent\";\nimport Loading from \"../components/loader\";\nimport Message from \"../components/message\";\n\nconst AnalysisView = () => {\n const dispatch = useDispatch();\n const [modal, setModal] = useState(false);\n const [days, setDays] = useState(0);\n const [idList, setIdList] = useState([]);\n const [startDate, setStartDate] = useState(new Date());\n const attendanceAnalysis = useSelector((state) => state.attendanceAnalysis);\n const { attendance } = attendanceAnalysis;\n const attendanceDelete = useSelector((state) => state.attendanceDelete);\n const {\n loading: loadingDelete,\n success: successDelete,\n error: errorDelete,\n } = attendanceDelete;\n useEffect(() => {\n if (attendance) {\n var temp = idList;\n Object.entries(attendance.details).map((at) => {\n temp.push(at[0]);\n });\n\n setIdList(temp);\n } else {\n dispatch(getAnalysisByDate(startDate.toString().substring(0, 15)));\n }\n }, [attendance, dispatch]);\n\n const changeDate = (date) => {\n dispatch(getAnalysisByDate(date.toString().substring(0, 15)));\n setStartDate(date);\n };\n const showModal = () => {\n setModal(true);\n };\n const closeModal = () => {\n setModal(false);\n };\n\n const startDelete = () => {\n setModal(false);\n dispatch(deleteAttendanceByDate(days));\n };\n\n return (\n <>\n \n \n Go Back\n \n \n \n
\n
\n {loadingDelete && }\n {errorDelete && {errorDelete}}\n {successDelete && Attendance Deleted}\n\n \n \n \n Analysis for
\n \n {startDate.toISOString().toString().substring(0, 10)}\n \n \n \n changeDate(date)}\n />\n \n
\n \n \n Enter Number of days before to delete\n \n \n \n Enter no of days\n setDays(e.target.value)}\n >\n \n \n \n \n \n \n \n \n {}\n \n >\n );\n};\n\nexport default AnalysisView;\n","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/loader.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/footer.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/reportWebVitals.js",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/paginate.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/studentDetailsView.jsx",["176"],"import React, { useState, useEffect } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport {\n Row,\n Col,\n Image,\n ListGroup,\n Card,\n Button,\n Form,\n} from \"react-bootstrap\";\nimport Loading from \"../components/loader\";\nimport Message from \"../components/message\";\nimport {\n getStudentDetails,\n updateStudent,\n deleteStudent,\n} from \"../actions/studentActions\";\nimport { STUDENT_UPDATE_RESET } from \"../constants/studentConstant\";\nconst StudentDetailsView = ({ match, history }) => {\n const [status, setStatus] = useState(\"\");\n const dispatch = useDispatch();\n const studentDetails = useSelector((state) => state.studentDetails);\n const { loading, error, student } = studentDetails;\n const studentUpdate = useSelector((state) => state.studentUpdate);\n const {\n loading: loadingUpdate,\n error: errorUpdate,\n success: successUpdate,\n } = studentUpdate;\n const studentDelete = useSelector((state) => state.studentDelete);\n const {\n loading: loadingDelete,\n error: errorDelete,\n success: successDelete,\n } = studentDelete;\n\n useEffect(() => {\n if (successDelete) {\n history.push(\"/\");\n }\n if (successUpdate) {\n dispatch({ type: STUDENT_UPDATE_RESET });\n }\n if (!student || !student._id || student._id !== match.params.id) {\n dispatch(getStudentDetails(match.params.id));\n }\n if (student && student._id && !status) {\n setStatus(student.status);\n }\n }, [dispatch, match, successUpdate, successDelete]);\n\n const navigateToEdit = () => {\n history.push({\n pathname: `/student/edit/${student._id}`,\n state: { studentProps: student },\n });\n };\n const updateStatus = () => {\n student.status = status;\n dispatch(updateStudent(student));\n };\n\n const deleteStuden = () => {\n if (window.confirm(\"Are you sure\")) {\n dispatch(deleteStudent(student._id));\n }\n };\n return (\n <>\n \n Go Back\n \n {loading || loadingUpdate || loadingDelete ? (\n \n ) : error ? (\n {error}\n ) : (\n <>\n {errorUpdate && {errorUpdate}}\n {errorDelete && {errorDelete}}\n {student && (\n \n \n \n \n \n \n \n {student.name}
\n \n \n Phone No:{student.contact}\n \n \n Father Contact:{student.fatherContact}\n \n \n City:{student.city}\n \n \n Address:{student.address}\n \n \n \n \n \n \n \n \n Room No:\n {student.roomNo}\n
\n \n \n \n Block No:\n {student.blockNo}\n
\n \n \n \n Status:\n \n setStatus(e.target.value)}\n >\n {[\"Hostel\", \"Outside\", \"Home\"].map((x) => (\n \n ))}\n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n \n \n
\n )}\n >\n )}\n >\n );\n};\n\nexport default StudentDetailsView;\n","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/studentTableView.jsx",["177"],"import React, { useEffect } from \"react\";\nimport { Table } from \"react-bootstrap\";\nimport { useDispatch, useSelector } from \"react-redux\";\nimport Message from \"../components/message\";\nimport Loader from \"../components/loader\";\nimport Paginate from \"../components/paginate\";\nimport { listStudents } from \"../actions/studentActions\";\nimport { Link } from \"react-router-dom\";\n\nconst StudentsTableView = ({ keyword, pageNumber }) => {\n const dispatch = useDispatch();\n\n const studentsList = useSelector((state) => state.studentsList);\n const { loading, error, students, page, pages } = studentsList;\n useEffect(() => {\n if (!students) {\n dispatch(listStudents(keyword, pageNumber));\n }\n }, [dispatch, keyword, pageNumber]);\n return (\n <>\n {loading ? (\n \n ) : error ? (\n {error}\n ) : (\n <>\n \n \n \n | Stream | \n NAME | \n STATUS | \n CONTACT | \n ROOM NO | \n CITY | \n
\n \n \n {students.map((student) => (\n \n | {student.category} | \n \n {student.name}\n | \n \n \n {student.status}\n \n | \n \n {student.contact}\n | \n {student.roomNo} | \n {student.city} | \n
\n ))}\n \n
\n \n >\n )}\n >\n );\n};\n\nexport default StudentsTableView;\n","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/attendanceView.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/reducers/attendanceReducer.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/actions/attendanceActions.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/constants/attendanceConstant.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/analysisComponent.jsx",["178"],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/attendanceTable.jsx",["179","180","181"],"import React, { useEffect, useState } from \"react\";\nimport { useSelector, useDispatch } from \"react-redux\";\nimport Loading from \"./loader\";\nimport Message from \"./message\";\nimport AttendanceTableComponent from \"./attendanceTableComponent\";\n\nconst AttendanceTable = ({ roomNo }) => {\n const dispatch = useDispatch();\n const [attendanceMap, setAttendanceMap] = useState({});\n\n const getStudentsByRoomNo = useSelector((state) => state.getStudentsByRoomNo);\n const { loading, error, students, attendance } = getStudentsByRoomNo;\n const attendanceDataEnter = useSelector((state) => state.attendanceDataEnter);\n const {\n loading: loadingAttendance,\n error: errorAttendance,\n } = attendanceDataEnter;\n useEffect(() => {\n if (students) {\n arrangeTable();\n }\n }, [dispatch, attendance, attendanceMap, students]);\n\n const arrangeTable = () => {\n if (attendance) {\n var tempMap = attendanceMap;\n students.map((student) => {\n if (attendance.data[student._id]) {\n tempMap[student._id] = attendance.data[student._id];\n } else {\n tempMap[student._id] = \"Hostel\";\n }\n });\n setAttendanceMap(attendanceMap);\n } else {\n students.map((student) => {\n var temp = attendanceMap;\n temp[student._id] = \"Hostel\";\n setAttendanceMap(temp);\n });\n }\n var temp = attendanceMap;\n setAttendanceMap(temp);\n };\n\n return (\n <>\n {error && {error}}\n {loading || loadingAttendance ? (\n \n ) : (\n <>\n {errorAttendance && (\n {errorAttendance}\n )}\n {students && (\n <>\n \n >\n )}\n >\n )}\n >\n );\n};\n\nexport default AttendanceTable;\n","/home/shashi/Projects/React Projects/hostel-app/frontend/src/components/attendanceTableComponent.jsx",["182"],"import React, { useEffect } from \"react\";\nimport { Table, Form, Button } from \"react-bootstrap\";\nimport { useDispatch } from \"react-redux\";\nimport { postAttendance } from \"../actions/attendanceActions\";\nimport { Link } from \"react-router-dom\";\nconst AttendanceTableComponent = ({\n students,\n attendanceMap,\n setAttendanceMap,\n attendance,\n roomNo,\n}) => {\n const dispatch = useDispatch();\n useEffect(() => {}, [dispatch, attendanceMap]);\n const updateAttendance = () => {\n if (attendance) {\n if (!attendance.roomNo.includes(roomNo)) {\n attendance.roomNo.push(roomNo);\n }\n }\n const roomData = attendance ? attendance.roomNo : roomNo;\n const dataData = attendanceMap;\n const detailsData = attendance ? attendance.details : {};\n students.map((student) => {\n detailsData[student._id] = {\n name: student.name,\n contact: student.contact,\n roomNo: student.roomNo,\n };\n });\n\n dispatch(\n postAttendance({\n roomNo: roomData,\n details: detailsData,\n data: dataData,\n })\n );\n };\n return (\n <>\n \n \n \n | NAME | \n Attendance | \n STATUS | \n CONTACT | \n CITY | \n
\n \n \n {students &&\n students.map((student) => (\n <>\n \n | \n {student.name}\n | \n \n \n {\n var tempMap = attendanceMap;\n tempMap[student._id] = e.target.value;\n setAttendanceMap(tempMap);\n }}\n >\n \n \n \n \n \n \n | \n \n \n {student.status}\n \n | \n \n {student.contact}\n | \n {student.city} | \n
\n >\n ))}\n \n
\n \n >\n );\n};\n\nexport default AttendanceTableComponent;\n","/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/profileView.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/userListView.jsx",[],"/home/shashi/Projects/React Projects/hostel-app/frontend/src/screens/userEditView.jsx",[],{"ruleId":"183","replacedBy":"184"},{"ruleId":"185","replacedBy":"186"},{"ruleId":"187","severity":1,"message":"188","line":35,"column":6,"nodeType":"189","endLine":35,"endColumn":27,"suggestions":"190"},{"ruleId":"183","replacedBy":"191"},{"ruleId":"185","replacedBy":"192"},{"ruleId":"183","replacedBy":"193"},{"ruleId":"185","replacedBy":"194"},{"ruleId":"183","replacedBy":"195"},{"ruleId":"185","replacedBy":"196"},{"ruleId":"183","replacedBy":"197"},{"ruleId":"185","replacedBy":"198"},{"ruleId":"183","replacedBy":"199"},{"ruleId":"185","replacedBy":"200"},{"ruleId":"183","replacedBy":"201"},{"ruleId":"185","replacedBy":"202"},{"ruleId":"203","severity":1,"message":"204","line":32,"column":51,"nodeType":"205","messageId":"206","endLine":32,"endColumn":53},{"ruleId":"187","severity":1,"message":"207","line":40,"column":6,"nodeType":"189","endLine":40,"endColumn":28,"suggestions":"208"},{"ruleId":"187","severity":1,"message":"209","line":52,"column":6,"nodeType":"189","endLine":52,"endColumn":53,"suggestions":"210"},{"ruleId":"187","severity":1,"message":"211","line":19,"column":6,"nodeType":"189","endLine":19,"endColumn":37,"suggestions":"212"},{"ruleId":"203","severity":1,"message":"204","line":22,"column":56,"nodeType":"205","messageId":"206","endLine":22,"endColumn":58},{"ruleId":"187","severity":1,"message":"213","line":22,"column":6,"nodeType":"189","endLine":22,"endColumn":53,"suggestions":"214"},{"ruleId":"203","severity":1,"message":"204","line":27,"column":30,"nodeType":"205","messageId":"206","endLine":27,"endColumn":32},{"ruleId":"203","severity":1,"message":"204","line":36,"column":30,"nodeType":"205","messageId":"206","endLine":36,"endColumn":32},{"ruleId":"203","severity":1,"message":"204","line":24,"column":28,"nodeType":"205","messageId":"206","endLine":24,"endColumn":30},"no-native-reassign",["215"],"no-negated-in-lhs",["216"],"react-hooks/exhaustive-deps","React Hook useEffect has missing dependencies: 'dispatch', 'history', 'userInfo', and 'userLoading'. Either include them or remove the dependency array.","ArrayExpression",["217"],["215"],["216"],["215"],["216"],["215"],["216"],["215"],["216"],["215"],["216"],["215"],["216"],"array-callback-return","Array.prototype.map() expects a return value from arrow function.","ArrowFunctionExpression","expectedInside","React Hook useEffect has missing dependencies: 'idList' and 'startDate'. Either include them or remove the dependency array.",["218"],"React Hook useEffect has missing dependencies: 'history', 'status', and 'student'. Either include them or remove the dependency array.",["219"],"React Hook useEffect has a missing dependency: 'students'. Either include it or remove the dependency array.",["220"],"React Hook useEffect has a missing dependency: 'arrangeTable'. Either include it or remove the dependency array.",["221"],"no-global-assign","no-unsafe-negation",{"desc":"222","fix":"223"},{"desc":"224","fix":"225"},{"desc":"226","fix":"227"},{"desc":"228","fix":"229"},{"desc":"230","fix":"231"},"Update the dependencies array to be: [dispatch, history, keyword, pageNumber, userInfo, userLoading]",{"range":"232","text":"233"},"Update the dependencies array to be: [attendance, dispatch, idList, startDate]",{"range":"234","text":"235"},"Update the dependencies array to be: [dispatch, match, successUpdate, successDelete, student, status, history]",{"range":"236","text":"237"},"Update the dependencies array to be: [dispatch, keyword, pageNumber, students]",{"range":"238","text":"239"},"Update the dependencies array to be: [dispatch, attendance, attendanceMap, students, arrangeTable]",{"range":"240","text":"241"},[1116,1137],"[dispatch, history, keyword, pageNumber, userInfo, userLoading]",[1402,1424],"[attendance, dispatch, idList, startDate]",[1494,1541],"[dispatch, match, successUpdate, successDelete, student, status, history]",[702,733],"[dispatch, keyword, pageNumber, students]",[780,827],"[dispatch, attendance, attendanceMap, students, arrangeTable]"]
================================================
FILE: frontend/index.html
================================================
Hostel Management
================================================
FILE: frontend/package.json
================================================
{
"name": "hostel-app",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest run --passWithNoTests"
},
"dependencies": {
"@redux-devtools/extension": "^3.3.0",
"axios": "^1.7.9",
"react": "^18.3.1",
"react-bootstrap": "^1.6.8",
"react-csv": "^2.2.2",
"react-datepicker": "^4.25.0",
"react-dom": "^18.3.1",
"react-redux": "^8.1.3",
"react-router-bootstrap": "^0.25.0",
"react-router-dom": "^5.3.4",
"redux": "^4.2.1",
"redux-thunk": "^2.4.2",
"web-vitals": "^4.2.4"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^14.3.1",
"@testing-library/user-event": "^14.5.2",
"@vitejs/plugin-react": "^4.3.4",
"jsdom": "^25.0.1",
"vite": "^6.0.11",
"vitest": "^3.0.4"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
================================================
FILE: frontend/public/manifest.json
================================================
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
================================================
FILE: frontend/public/robots.txt
================================================
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
================================================
FILE: frontend/src/App.jsx
================================================
import React from "react";
import HomeView from "./screens/homeView";
import { BrowserRouter as Router, Route } from "react-router-dom";
import { Container } from "react-bootstrap";
import Header from "./components/header";
import Footer from "./components/footer";
import AddStudentView from "./screens/addStudentView";
import AnalysisView from "./screens/analysisView";
import LoginView from "./screens/Authentication Screens/LoginView";
import RegisterView from "./screens/Authentication Screens/RegisterView";
import StudentDetailsView from "./screens/studentDetailsView";
import AttendanceView from "./screens/attendanceView";
import ProfileView from "./screens/profileView";
import UserListView from "./screens/userListView";
import UserEditView from "./screens/userEditView";
const App = () => {
return (
);
};
export default App;
================================================
FILE: frontend/src/actions/attendanceActions.jsx
================================================
import {
ATTENDANCE_DATA_ENTER_FAIL,
ATTENDANCE_DATA_ENTER_REQUEST,
ATTENDANCE_DATA_ENTER_SUCCESS,
ATTENDANCE_ANALYSIS_FAIL,
ATTENDANCE_ANALYSIS_REQUEST,
ATTENDANCE_ANALYSIS_SUCCESS,
ATTENDANCE_DELETE_REQUEST,
ATTENDANCE_DELETE_SUCCESS,
ATTENDANCE_DELETE_FAIL,
} from "../constants/attendanceConstant";
import axios from "axios";
export const postAttendance = (attendance) => async (dispatch, getState) => {
try {
dispatch({ type: ATTENDANCE_DATA_ENTER_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.post(`/attendance/`, attendance, config);
dispatch({
type: ATTENDANCE_DATA_ENTER_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: ATTENDANCE_DATA_ENTER_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const getAnalysisByDate = (date) => async (dispatch, getState) => {
try {
dispatch({ type: ATTENDANCE_ANALYSIS_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.post(
`/attendance/getAnalysis`,
{ date: date },
config
);
dispatch({
type: ATTENDANCE_ANALYSIS_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: ATTENDANCE_ANALYSIS_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const deleteAttendanceByDate = (days) => async (dispatch, getState) => {
try {
dispatch({ type: ATTENDANCE_DELETE_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.delete(`/attendance/${days}`, config);
dispatch({
type: ATTENDANCE_DELETE_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: ATTENDANCE_DELETE_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
================================================
FILE: frontend/src/actions/studentActions.jsx
================================================
import {
STUDENT_LIST_REQUEST,
STUDENT_LIST_SUCCESS,
STUDENT_LIST_ERROR,
STUDENT_ADD_ERROR,
STUDENT_ADD_REQUEST,
STUDENT_ADD_SUCCESS,
STUDENT_DELETE_ERROR,
STUDENT_DELETE_REQUEST,
STUDENT_DELETE_SUCCESS,
STUDENT_UPDATE_ERROR,
STUDENT_UPDATE_REQUEST,
STUDENT_UPDATE_SUCCESS,
STUDENT_DETAILS_REQUEST,
STUDENT_DETAILS_SUCCESS,
STUDENT_DETAILS_ERROR,
STUDENT_ROOM_NO_REQUEST,
STUDENT_ROOM_NO_SUCCESS,
STUDENT_ROOM_NO_ERROR,
} from "../constants/studentConstant";
import axios from "axios";
export const listStudents = (keyword = "", pageNumber = "") => async (
dispatch,
getState
) => {
try {
dispatch({ type: STUDENT_LIST_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.get(
`/student/all?keyword=${keyword}&pageNumber=${pageNumber}`,
config
);
dispatch({
type: STUDENT_LIST_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: STUDENT_LIST_ERROR,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const addStudent = (student) => async (dispatch, getState) => {
try {
dispatch({ type: STUDENT_ADD_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.post(`/student/addStudent`, student, config);
dispatch({
type: STUDENT_ADD_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: STUDENT_ADD_ERROR,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const getStudentDetails = (id) => async (dispatch, getState) => {
try {
dispatch({ type: STUDENT_DETAILS_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.get(`/student/${id}`, config);
dispatch({
type: STUDENT_DETAILS_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: STUDENT_DETAILS_ERROR,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const updateStudent = (student) => async (dispatch, getState) => {
try {
dispatch({ type: STUDENT_UPDATE_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.put(
`/student/${student._id}`,
student,
config
);
dispatch({
type: STUDENT_UPDATE_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: STUDENT_UPDATE_ERROR,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const deleteStudent = (id) => async (dispatch, getState) => {
try {
dispatch({ type: STUDENT_DELETE_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.delete(`/student/${id}`, config);
dispatch({
type: STUDENT_DELETE_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: STUDENT_DELETE_ERROR,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const getStudentsByRoomNo = (roomNo) => async (dispatch, getState) => {
try {
dispatch({ type: STUDENT_ROOM_NO_REQUEST });
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.get(`/student/room/${roomNo}`, config);
dispatch({
type: STUDENT_ROOM_NO_SUCCESS,
payload: data,
});
} catch (error) {
dispatch({
type: STUDENT_ROOM_NO_ERROR,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
================================================
FILE: frontend/src/actions/userActions.jsx
================================================
import axios from "axios";
import {
USER_DETAILS_FAIL,
USER_DETAILS_REQUEST,
USER_DETAILS_SUCCESS,
USER_LOGIN_FAIL,
USER_LOGIN_REQUEST,
USER_LOGIN_SUCCESS,
USER_LOGOUT,
USER_REGISTER_FAIL,
USER_REGISTER_REQUEST,
USER_REGISTER_SUCCESS,
USER_UPDATE_PROFILE_FAIL,
USER_UPDATE_PROFILE_REQUEST,
USER_UPDATE_PROFILE_SUCCESS,
USER_DETAILS_RESET,
USER_LIST_FAIL,
USER_LIST_SUCCESS,
USER_LIST_REQUEST,
USER_LIST_RESET,
USER_DELETE_REQUEST,
USER_DELETE_SUCCESS,
USER_DELETE_FAIL,
USER_UPDATE_FAIL,
USER_UPDATE_SUCCESS,
USER_UPDATE_REQUEST,
} from "../constants/userConstants";
export const login = (email, password) => async (dispatch) => {
try {
dispatch({
type: USER_LOGIN_REQUEST,
});
const config = {
headers: {
"Content-Type": "application/json",
},
};
const { data } = await axios.post(
"/users/login",
{ email, password },
config
);
dispatch({
type: USER_LOGIN_SUCCESS,
payload: data,
});
localStorage.setItem("userInfo", JSON.stringify(data));
} catch (error) {
dispatch({
type: USER_LOGIN_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const logout = () => (dispatch) => {
localStorage.removeItem("userInfo");
dispatch({ type: USER_LOGOUT });
dispatch({ type: USER_DETAILS_RESET });
dispatch({ type: USER_LIST_RESET });
document.location.href = "/login";
};
export const register = (name, email, password) => async (dispatch) => {
try {
dispatch({
type: USER_REGISTER_REQUEST,
});
const config = {
headers: {
"Content-Type": "application/json",
},
};
const { data } = await axios.post(
"/users",
{ name, email, password },
config
);
dispatch({
type: USER_REGISTER_SUCCESS,
payload: data,
});
dispatch({
type: USER_LOGIN_SUCCESS,
payload: data,
});
localStorage.setItem("userInfo", JSON.stringify(data));
} catch (error) {
dispatch({
type: USER_REGISTER_FAIL,
payload:
error.response && error.response.data.message
? error.response.data.message
: error.message,
});
}
};
export const getUserDetails = (id) => async (dispatch, getState) => {
try {
dispatch({
type: USER_DETAILS_REQUEST,
});
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.get(`/users/${id}`, config);
dispatch({
type: USER_DETAILS_SUCCESS,
payload: data,
});
} catch (error) {
const message =
error.response && error.response.data.message
? error.response.data.message
: error.message;
if (message === "Not authorized, token failed") {
dispatch(logout());
}
dispatch({
type: USER_DETAILS_FAIL,
payload: message,
});
}
};
export const updateUserProfile = (user) => async (dispatch, getState) => {
try {
dispatch({
type: USER_UPDATE_PROFILE_REQUEST,
});
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.put(`/users/profile`, user, config);
dispatch({
type: USER_UPDATE_PROFILE_SUCCESS,
payload: data,
});
dispatch({
type: USER_LOGIN_SUCCESS,
payload: data,
});
localStorage.setItem("userInfo", JSON.stringify(data));
} catch (error) {
const message =
error.response && error.response.data.message
? error.response.data.message
: error.message;
if (message === "Not authorized, token failed") {
dispatch(logout());
}
dispatch({
type: USER_UPDATE_PROFILE_FAIL,
payload: message,
});
}
};
export const listUsers = () => async (dispatch, getState) => {
try {
dispatch({
type: USER_LIST_REQUEST,
});
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.get(`/users`, config);
dispatch({
type: USER_LIST_SUCCESS,
payload: data,
});
} catch (error) {
const message =
error.response && error.response.data.message
? error.response.data.message
: error.message;
if (message === "Not authorized, token failed") {
dispatch(logout());
}
dispatch({
type: USER_LIST_FAIL,
payload: message,
});
}
};
export const deleteUser = (id) => async (dispatch, getState) => {
try {
dispatch({
type: USER_DELETE_REQUEST,
});
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
Authorization: `Bearer ${userInfo.token}`,
},
};
await axios.delete(`/users/${id}`, config);
dispatch({ type: USER_DELETE_SUCCESS });
} catch (error) {
const message =
error.response && error.response.data.message
? error.response.data.message
: error.message;
if (message === "Not authorized, token failed") {
dispatch(logout());
}
dispatch({
type: USER_DELETE_FAIL,
payload: message,
});
}
};
export const updateUser = (user) => async (dispatch, getState) => {
try {
dispatch({
type: USER_UPDATE_REQUEST,
});
const {
userLogin: { userInfo },
} = getState();
const config = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${userInfo.token}`,
},
};
const { data } = await axios.put(`/users/${user._id}`, user, config);
dispatch({ type: USER_UPDATE_SUCCESS });
dispatch({ type: USER_DETAILS_SUCCESS, payload: data });
dispatch({ type: USER_DETAILS_RESET });
} catch (error) {
const message =
error.response && error.response.data.message
? error.response.data.message
: error.message;
if (message === "Not authorized, token failed") {
dispatch(logout());
}
dispatch({
type: USER_UPDATE_FAIL,
payload: message,
});
}
};
================================================
FILE: frontend/src/components/analysisComponent.jsx
================================================
import React, { useEffect, useState } from "react";
import { Table } from "react-bootstrap";
import { useSelector } from "react-redux";
import Loading from "./loader";
import Message from "./message";
import { CSVLink } from "react-csv";
const AnalysisComponent = () => {
const attendanceAnalysis = useSelector((state) => state.attendanceAnalysis);
const { loading, error, attendance } = attendanceAnalysis;
const [data, setData] = useState([]);
const [headers, setHeaders] = useState([]);
useEffect(() => {
if (attendance) {
setHeaders([
{ label: "Name", key: "name" },
{ label: "Contact", key: "contact" },
{ label: "Room No", key: "roomNo" },
{ label: "Status", key: "attendance" },
]);
var csvMapList = [];
Object.entries(attendance.details).map((student) => {
var csvMap = {};
csvMap["name"] = student[1].name;
csvMap["contact"] = student[1].contact;
csvMap["roomNo"] = student[1].roomNo;
csvMap["attendance"] = attendance.data[student[0]];
csvMapList.push(csvMap);
});
setData(csvMapList);
}
}, [attendance]);
return (
<>
{error && {error}}
{loading ? (
) : (
<>
{attendance && (
<>
| Name |
Contact No |
Room No |
Attendance |
{attendance &&
Object.entries(attendance.details).map((student) => {
return (
| {student[1].name} |
{student[1].contact} |
{student[1].roomNo} |
{attendance.data[student[0]]} |
);
})}
Download
>
)}
>
)}
>
);
};
export default AnalysisComponent;
================================================
FILE: frontend/src/components/attendanceTable.jsx
================================================
import React, { useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import Loading from "./loader";
import Message from "./message";
import AttendanceTableComponent from "./attendanceTableComponent";
const AttendanceTable = ({ roomNo }) => {
const dispatch = useDispatch();
const [attendanceMap, setAttendanceMap] = useState({});
const getStudentsByRoomNo = useSelector((state) => state.getStudentsByRoomNo);
const { loading, error, students, attendance } = getStudentsByRoomNo;
const attendanceDataEnter = useSelector((state) => state.attendanceDataEnter);
const {
loading: loadingAttendance,
error: errorAttendance,
} = attendanceDataEnter;
useEffect(() => {
if (students) {
arrangeTable();
}
}, [dispatch, attendance, attendanceMap, students]);
const arrangeTable = () => {
if (attendance) {
var tempMap = attendanceMap;
students.map((student) => {
if (attendance.data[student._id]) {
tempMap[student._id] = attendance.data[student._id];
} else {
tempMap[student._id] = "Hostel";
}
});
setAttendanceMap(attendanceMap);
} else {
students.map((student) => {
var temp = attendanceMap;
temp[student._id] = "Hostel";
setAttendanceMap(temp);
});
}
var temp = attendanceMap;
setAttendanceMap(temp);
};
return (
<>
{error && {error}}
{loading || loadingAttendance ? (
) : (
<>
{errorAttendance && (
{errorAttendance}
)}
{students && (
<>
>
)}
>
)}
>
);
};
export default AttendanceTable;
================================================
FILE: frontend/src/components/attendanceTableComponent.jsx
================================================
import React, { useEffect } from "react";
import { Table, Form, Button } from "react-bootstrap";
import { useDispatch } from "react-redux";
import { postAttendance } from "../actions/attendanceActions";
import { Link } from "react-router-dom";
const AttendanceTableComponent = ({
students,
attendanceMap,
setAttendanceMap,
attendance,
roomNo,
}) => {
const dispatch = useDispatch();
useEffect(() => {}, [dispatch, attendanceMap]);
const updateAttendance = () => {
if (attendance) {
if (!attendance.roomNo.includes(roomNo)) {
attendance.roomNo.push(roomNo);
}
}
const roomData = attendance ? attendance.roomNo : roomNo;
const dataData = attendanceMap;
const detailsData = attendance ? attendance.details : {};
students.map((student) => {
detailsData[student._id] = {
name: student.name,
contact: student.contact,
roomNo: student.roomNo,
};
});
dispatch(
postAttendance({
roomNo: roomData,
details: detailsData,
data: dataData,
})
);
};
return (
<>
| NAME |
Attendance |
STATUS |
CONTACT |
CITY |
{students &&
students.map((student) => (
<>
|
{student.name}
|
{
var tempMap = attendanceMap;
tempMap[student._id] = e.target.value;
setAttendanceMap(tempMap);
}}
>
|
{student.status}
|
{student.contact}
|
{student.city} |
>
))}
>
);
};
export default AttendanceTableComponent;
================================================
FILE: frontend/src/components/footer.jsx
================================================
import React from 'react'
import { Container, Row, Col } from 'react-bootstrap'
const Footer = () => {
return (
Copyright ©NSD Solutions
)
}
export default Footer
================================================
FILE: frontend/src/components/formContainer.jsx
================================================
import React from 'react'
import { Col, Container, Row } from 'react-bootstrap'
const FormContainer = ({ children }) => {
return (
{children}
)
}
export default FormContainer
================================================
FILE: frontend/src/components/header.jsx
================================================
import React from "react";
import { Container, Nav, Navbar, NavDropdown } from "react-bootstrap";
import { Route, useHistory } from "react-router-dom";
import { LinkContainer } from "react-router-bootstrap";
import SearchBox from "./searchBox";
import { useDispatch, useSelector } from "react-redux";
import { logout } from "../actions/userActions";
const Header = () => {
const dispatch = useDispatch();
const history = useHistory();
const userLogin = useSelector((state) => state.userLogin);
const { userInfo } = userLogin;
const logoutHandler = () => {
dispatch(logout());
history.push("/login");
};
return (
NSD Solutions
{userInfo && (
} />
)}
);
};
export default Header;
================================================
FILE: frontend/src/components/loader.jsx
================================================
import React from 'react'
import { Spinner } from 'react-bootstrap'
const Loading = () => {
return (
Loading...
)
}
export default Loading
================================================
FILE: frontend/src/components/message.jsx
================================================
import React from 'react'
import { Alert } from 'react-bootstrap'
const Message = ({ variant, children }) => {
return {children}
}
Message.defaultProps = {
variant: 'info',
}
export default Message
================================================
FILE: frontend/src/components/paginate.jsx
================================================
import React from "react";
import { Pagination } from "react-bootstrap";
import { LinkContainer } from "react-router-bootstrap";
const Paginate = ({ pages, page, isAdmin = false, keyword = "" }) => {
return (
pages > 1 && (
{[...Array(pages).keys()].map((x) => (
{x + 1}
))}
)
);
};
export default Paginate;
================================================
FILE: frontend/src/components/rating.jsx
================================================
import React from 'react'
import PropTypes from 'prop-types'
const Rating = ({ value, text, color }) => {
return (
= 1
? 'fas fa-star'
: value >= 0.5
? 'fas fa-star-half-alt'
: 'far fa-star'
}
>
= 2
? 'fas fa-star'
: value >= 1.5
? 'fas fa-star-half-alt'
: 'far fa-star'
}
>
= 3
? 'fas fa-star'
: value >= 2.5
? 'fas fa-star-half-alt'
: 'far fa-star'
}
>
= 4
? 'fas fa-star'
: value >= 3.5
? 'fas fa-star-half-alt'
: 'far fa-star'
}
>
= 5
? 'fas fa-star'
: value >= 4.5
? 'fas fa-star-half-alt'
: 'far fa-star'
}
>
{text && text}
)
}
Rating.defaultProps = {
color: '#f8e825',
}
Rating.propTypes = {
text: PropTypes.string,
color: PropTypes.string,
}
export default Rating
================================================
FILE: frontend/src/components/searchBox.jsx
================================================
import React, { useState } from 'react'
import { Form, Button } from 'react-bootstrap'
const SearchBox = ({history}) => {
const [keyword, setKeyword] = useState('')
const submitHandler = (e) => {
e.preventDefault ()
if(keyword.trim()){
history.push(`/search/${keyword}`)
}else{
history.push(`/`)
}
}
return (
setKeyword(e.target.value)}
>
)
}
export default SearchBox
================================================
FILE: frontend/src/components/student.jsx
================================================
import React from "react";
import { Card, Col, Row, Image } from "react-bootstrap";
import { Link } from "react-router-dom";
const Student = ({ stuentDetails: student }) => {
return (
{student.name}
Room No: {student.roomNo}
Stream: {student.category}
Contact:
{student.contact}
);
};
export default Student;
================================================
FILE: frontend/src/constants/attendanceConstant.jsx
================================================
export const ATTENDANCE_DATA_ENTER_REQUEST = "ATTENDANCE_DATA_ENTER_REQUEST";
export const ATTENDANCE_DATA_ENTER_SUCCESS = "ATTENDANCE_DATA_ENTER_SUCCESS";
export const ATTENDANCE_DATA_ENTER_FAIL = "ATTENDANCE_DATA_ENTER_FAIL";
export const ATTENDANCE_DATA_ENTER_RESET = "ATTENDANCE_DATA_ENTER_RESET";
export const ATTENDANCE_ANALYSIS_REQUEST = "ATTENDANCE_ANALYSIS_REQUEST";
export const ATTENDANCE_ANALYSIS_SUCCESS = "ATTENDANCE_ANALYSIS_SUCCESS";
export const ATTENDANCE_ANALYSIS_FAIL = "ATTENDANCE_ANALYSIS_FAIL";
export const ATTENDANCE_ANALYSIS_RESET = "ATTENDANCE_ANALYSIS_RESET";
export const ATTENDANCE_DELETE_REQUEST = "ATTENDANCE_DELETE_REQUEST";
export const ATTENDANCE_DELETE_SUCCESS = "ATTENDANCE_DELETE_SUCCESS";
export const ATTENDANCE_DELETE_FAIL = "ATTENDANCE_DELETE_FAIL";
export const ATTENDANCE_DELETE_RESET = "ATTENDANCE_DELETE_RESET";
================================================
FILE: frontend/src/constants/studentConstant.jsx
================================================
export const STUDENT_LIST_REQUEST = "STUDENT_LIST_REQUEST";
export const STUDENT_LIST_SUCCESS = "STUDENT_LIST_SUCCESS";
export const STUDENT_LIST_ERROR = "STUDENT_LIST_ERROR";
export const STUDENT_ADD_REQUEST = "STUDENT_ADD_REQUEST";
export const STUDENT_ADD_SUCCESS = "STUDENT_ADD_SUCCESS";
export const STUDENT_ADD_ERROR = "STUDENT_ADD_ERROR";
export const STUDENT_DETAILS_REQUEST = "STUDENT_DETAILS_REQUEST";
export const STUDENT_DETAILS_SUCCESS = "STUDENT_DETAILS_SUCCESS";
export const STUDENT_DETAILS_ERROR = "STUDENT_DETAILS_ERROR";
export const STUDENT_UPDATE_REQUEST = "STUDENT_UPDATE_REQUEST";
export const STUDENT_UPDATE_SUCCESS = "STUDENT_UPDATE_SUCCESS";
export const STUDENT_UPDATE_ERROR = "STUDENT_UPDATE_ERROR";
export const STUDENT_UPDATE_RESET = "STUDENT_UPDATE_RESET";
export const STUDENT_DELETE_REQUEST = "STUDENT_DELETE_REQUEST";
export const STUDENT_DELETE_SUCCESS = "STUDENT_DELETE_SUCCESS";
export const STUDENT_DELETE_ERROR = "STUDENT_DELETE_ERROR";
export const STUDENT_DELETE_RESET = "STUDENT_DELETE_RESET";
export const STUDENT_ROOM_NO_REQUEST = "STUDENT_ROOM_NO_REQUEST";
export const STUDENT_ROOM_NO_SUCCESS = "STUDENT_ROOM_NO_SUCCESS";
export const STUDENT_ROOM_NO_ERROR = "STUDENT_ROOM_NO_ERROR";
export const STUDENT_ROOM_NO_RESET = "STUDENT_ROOM_NO_RESET";
================================================
FILE: frontend/src/constants/userConstants.jsx
================================================
export const USER_LOGIN_REQUEST = "USER_LOGIN_REQUEST";
export const USER_LOGIN_SUCCESS = "USER_LOGIN_SUCCESS";
export const USER_LOGIN_FAIL = "USER_LOGIN_FAIL";
export const USER_LOGOUT = "USER_LOGOUT";
export const USER_REGISTER_REQUEST = "USER_REGISTER_REQUEST";
export const USER_REGISTER_SUCCESS = "USER_REGISTER_SUCCESS";
export const USER_REGISTER_FAIL = "USER_REGISTER_FAIL";
export const USER_DETAILS_REQUEST = "USER_DETAILS_REQUEST";
export const USER_DETAILS_SUCCESS = "USER_DETAILS_SUCCESS";
export const USER_DETAILS_FAIL = "USER_DETAILS_FAIL";
export const USER_DETAILS_RESET = "USER_DETAILS_RESET";
export const USER_UPDATE_PROFILE_REQUEST = "USER_UPDATE_PROFILE_REQUEST";
export const USER_UPDATE_PROFILE_SUCCESS = "USER_UPDATE_PROFILE_SUCCESS";
export const USER_UPDATE_PROFILE_FAIL = "USER_UPDATE_PROFILE_FAIL";
export const USER_UPDATE_PROFILE_RESET = "USER_UPDATE_PROFILE_RESET";
export const USER_LIST_REQUEST = "USER_LIST_REQUEST";
export const USER_LIST_SUCCESS = "USER_LIST_SUCCESS";
export const USER_LIST_FAIL = "USER_LIST_FAIL";
export const USER_LIST_RESET = "USER_LIST_RESET";
export const USER_DELETE_REQUEST = "USER_DELETE_REQUEST";
export const USER_DELETE_SUCCESS = "USER_DELETE_SUCCESS";
export const USER_DELETE_FAIL = "USER_DELETE_FAIL";
export const USER_UPDATE_REQUEST = "USER_UPDATE_REQUEST";
export const USER_UPDATE_SUCCESS = "USER_UPDATE_SUCCESS";
export const USER_UPDATE_FAIL = "USER_UPDATE_FAIL";
export const USER_UPDATE_RESET = "USER_UPDATE_RESET";
================================================
FILE: frontend/src/css/index.css
================================================
main {
min-height: 80vh;
}
.rating span {
margin: 0.1rem;
}
h3 {
padding: 1rem 0;
}
h1 {
font-size: 1.8rem;
padding: 1rem 0;
}
h2 {
font-size: 1.4rem;
padding: 0.5rem 0;
}
================================================
FILE: frontend/src/main.jsx
================================================
import React from "react";
import { createRoot } from "react-dom/client";
import "./css/index.css";
import { Provider } from "react-redux";
import store from "./store";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import "./css/bootstrap.min.css";
const root = createRoot(document.getElementById("root"));
root.render(
);
reportWebVitals();
================================================
FILE: frontend/src/reducers/attendanceReducer.jsx
================================================
import {
ATTENDANCE_DATA_ENTER_FAIL,
ATTENDANCE_DATA_ENTER_REQUEST,
ATTENDANCE_DATA_ENTER_RESET,
ATTENDANCE_DATA_ENTER_SUCCESS,
ATTENDANCE_ANALYSIS_FAIL,
ATTENDANCE_ANALYSIS_REQUEST,
ATTENDANCE_ANALYSIS_RESET,
ATTENDANCE_ANALYSIS_SUCCESS,
ATTENDANCE_DELETE_REQUEST,
ATTENDANCE_DELETE_SUCCESS,
ATTENDANCE_DELETE_FAIL,
} from "../constants/attendanceConstant";
export const attendanceDataEnterReducer = (state = {}, action) => {
switch (action.type) {
case ATTENDANCE_DATA_ENTER_REQUEST:
return { ...state, loading: true };
case ATTENDANCE_DATA_ENTER_SUCCESS:
return {
loading: false,
attendance: action.payload,
};
case ATTENDANCE_DATA_ENTER_FAIL:
return { loading: false, error: action.payload };
case ATTENDANCE_DATA_ENTER_RESET:
return {};
default:
return state;
}
};
export const attendanceAnalysisReducer = (state = {}, action) => {
switch (action.type) {
case ATTENDANCE_ANALYSIS_REQUEST:
return { loading: true };
case ATTENDANCE_ANALYSIS_SUCCESS:
return {
loading: false,
attendance: action.payload,
};
case ATTENDANCE_ANALYSIS_FAIL:
return { loading: false, error: action.payload };
case ATTENDANCE_ANALYSIS_RESET:
return {};
default:
return state;
}
};
export const deleteAttendanceReducer = (state = {}, action) => {
switch (action.type) {
case ATTENDANCE_DELETE_REQUEST:
return { loading: true };
case ATTENDANCE_DELETE_SUCCESS:
return {
loading: false,
success: true,
};
case ATTENDANCE_DELETE_FAIL:
return { loading: false, error: action.payload };
case ATTENDANCE_ANALYSIS_RESET:
return {};
default:
return state;
}
};
================================================
FILE: frontend/src/reducers/studentsReducer.jsx
================================================
import {
STUDENT_LIST_REQUEST,
STUDENT_LIST_SUCCESS,
STUDENT_LIST_ERROR,
STUDENT_ADD_ERROR,
STUDENT_ADD_REQUEST,
STUDENT_ADD_SUCCESS,
STUDENT_UPDATE_ERROR,
STUDENT_UPDATE_REQUEST,
STUDENT_UPDATE_SUCCESS,
STUDENT_UPDATE_RESET,
STUDENT_DELETE_ERROR,
STUDENT_DELETE_REQUEST,
STUDENT_DELETE_SUCCESS,
STUDENT_DELETE_RESET,
STUDENT_DETAILS_REQUEST,
STUDENT_DETAILS_SUCCESS,
STUDENT_DETAILS_ERROR,
STUDENT_ROOM_NO_REQUEST,
STUDENT_ROOM_NO_SUCCESS,
STUDENT_ROOM_NO_ERROR,
STUDENT_ROOM_NO_RESET,
} from "../constants/studentConstant";
export const studentListReducer = (state = { students: [] }, action) => {
switch (action.type) {
case STUDENT_LIST_REQUEST:
return { ...state, loading: true };
case STUDENT_LIST_SUCCESS:
return {
loading: false,
students: action.payload.students,
pages: action.payload.pages,
page: action.payload.page,
};
case STUDENT_LIST_ERROR:
return { loading: false, error: action.payload };
default:
return state;
}
};
export const studentAddReducer = (state = { students: {} }, action) => {
switch (action.type) {
case STUDENT_ADD_REQUEST:
return { ...state, loading: true };
case STUDENT_ADD_SUCCESS:
return { loading: false, success: true };
case STUDENT_ADD_ERROR:
return { loading: false, error: action.payload };
default:
return state;
}
};
export const studentDetailsReducer = (state = {}, action) => {
switch (action.type) {
case STUDENT_DETAILS_REQUEST:
return { ...state, loading: true };
case STUDENT_DETAILS_SUCCESS:
return { loading: false, student: action.payload };
case STUDENT_DETAILS_ERROR:
return { loading: false, error: action.payload };
default:
return state;
}
};
export const studentUpdateReducer = (state = {}, action) => {
switch (action.type) {
case STUDENT_UPDATE_REQUEST:
return { ...state, loading: true };
case STUDENT_UPDATE_SUCCESS:
return { loading: false, success: true };
case STUDENT_UPDATE_ERROR:
return { loading: false, error: action.payload };
case STUDENT_UPDATE_RESET:
return {};
default:
return state;
}
};
export const studentDeleteReducer = (state = {}, action) => {
switch (action.type) {
case STUDENT_DELETE_REQUEST:
return { ...state, loading: true };
case STUDENT_DELETE_SUCCESS:
return { loading: false, success: true };
case STUDENT_DELETE_ERROR:
return { loading: false, error: action.payload };
case STUDENT_DELETE_RESET:
return {};
default:
return state;
}
};
export const getStudentsByRoomNoReducer = (state = {}, action) => {
switch (action.type) {
case STUDENT_ROOM_NO_REQUEST:
return { ...state, loading: true };
case STUDENT_ROOM_NO_SUCCESS:
return {
loading: false,
students: action.payload.students,
attendance: action.payload.attendance,
};
case STUDENT_ROOM_NO_ERROR:
return { loading: false, error: action.payload };
case STUDENT_ROOM_NO_RESET:
return {};
default:
return state;
}
};
================================================
FILE: frontend/src/reducers/userReducers.jsx
================================================
import {
USER_DETAILS_FAIL,
USER_DETAILS_REQUEST,
USER_DETAILS_RESET,
USER_DETAILS_SUCCESS,
USER_LIST_REQUEST,
USER_LIST_SUCCESS,
USER_LIST_FAIL,
USER_LIST_RESET,
USER_LOGIN_FAIL,
USER_LOGIN_REQUEST,
USER_LOGIN_SUCCESS,
USER_LOGOUT,
USER_REGISTER_FAIL,
USER_REGISTER_REQUEST,
USER_REGISTER_SUCCESS,
USER_UPDATE_PROFILE_FAIL,
USER_UPDATE_PROFILE_REQUEST,
USER_UPDATE_PROFILE_SUCCESS,
USER_DELETE_REQUEST,
USER_DELETE_SUCCESS,
USER_DELETE_FAIL,
USER_UPDATE_RESET,
USER_UPDATE_REQUEST,
USER_UPDATE_SUCCESS,
USER_UPDATE_FAIL,
USER_UPDATE_PROFILE_RESET,
} from "../constants/userConstants";
export const userLoginReducer = (state = {}, action) => {
switch (action.type) {
case USER_LOGIN_REQUEST:
return { loading: true };
case USER_LOGIN_SUCCESS:
return { loading: false, userInfo: action.payload };
case USER_LOGIN_FAIL:
return { loading: false, error: action.payload };
case USER_LOGOUT:
return {};
default:
return state;
}
};
export const userRegisterReducer = (state = {}, action) => {
switch (action.type) {
case USER_REGISTER_REQUEST:
return { loading: true };
case USER_REGISTER_SUCCESS:
return { loading: false, userInfo: action.payload };
case USER_REGISTER_FAIL:
return { loading: false, error: action.payload };
case USER_LOGOUT:
return {};
default:
return state;
}
};
export const userDetailsReducer = (state = { user: {} }, action) => {
switch (action.type) {
case USER_DETAILS_REQUEST:
return { ...state, loading: true };
case USER_DETAILS_SUCCESS:
return { loading: false, user: action.payload };
case USER_DETAILS_FAIL:
return { loading: false, error: action.payload };
case USER_DETAILS_RESET:
return { user: {} };
default:
return state;
}
};
export const userUpdateProfileReducer = (state = {}, action) => {
switch (action.type) {
case USER_UPDATE_PROFILE_REQUEST:
return { loading: true };
case USER_UPDATE_PROFILE_SUCCESS:
return { loading: false, success: true, userInfo: action.payload };
case USER_UPDATE_PROFILE_FAIL:
return { loading: false, error: action.payload };
case USER_UPDATE_PROFILE_RESET:
return {};
default:
return state;
}
};
export const userListReducer = (state = { users: [] }, action) => {
switch (action.type) {
case USER_LIST_REQUEST:
return { loading: true };
case USER_LIST_SUCCESS:
return { loading: false, users: action.payload };
case USER_LIST_FAIL:
return { loading: false, error: action.payload };
case USER_LIST_RESET:
return { users: [] };
default:
return state;
}
};
export const userDeleteReducer = (state = {}, action) => {
switch (action.type) {
case USER_DELETE_REQUEST:
return { loading: true };
case USER_DELETE_SUCCESS:
return { loading: false, success: true };
case USER_DELETE_FAIL:
return { loading: false, error: action.payload };
default:
return state;
}
};
export const userUpdateReducer = (state = { user: {} }, action) => {
switch (action.type) {
case USER_UPDATE_REQUEST:
return { loading: true };
case USER_UPDATE_SUCCESS:
return { loading: false, success: true };
case USER_UPDATE_FAIL:
return { loading: false, error: action.payload };
case USER_UPDATE_RESET:
return {
user: {},
};
default:
return state;
}
};
================================================
FILE: frontend/src/reportWebVitals.js
================================================
const reportWebVitals = (onPerfEntry) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import("web-vitals").then(
({ onCLS, onINP, onFCP, onLCP, onTTFB }) => {
onCLS(onPerfEntry);
onINP(onPerfEntry);
onFCP(onPerfEntry);
onLCP(onPerfEntry);
onTTFB(onPerfEntry);
}
);
}
};
export default reportWebVitals;
================================================
FILE: frontend/src/screens/Authentication Screens/LoginView.jsx
================================================
import React, { useState, useEffect } from 'react'
import { Link } from 'react-router-dom'
import { Form, Button, Row, Col } from 'react-bootstrap'
import { useDispatch, useSelector } from 'react-redux'
import Message from '../../components/message'
import Loader from '../../components/loader'
import FormContainer from '../../components/formContainer'
import { login } from '../../actions/userActions'
const LoginView = ({ location, history }) => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const dispatch = useDispatch()
const userLogin = useSelector((state) => state.userLogin)
const { loading, error, userInfo } = userLogin
const redirect = location.search ? location.search.split('=')[1] : '/'
useEffect(() => {
if (userInfo) {
history.push(redirect)
}
}, [history, userInfo, redirect])
const submitHandler = (e) => {
e.preventDefault()
dispatch(login(email, password))
}
return (
Sign In
{error && {error}}
{loading && }
Email Address
setEmail(e.target.value)}
>
Password
setPassword(e.target.value)}
>
New Customer?{' '}
Register
)
}
export default LoginView
================================================
FILE: frontend/src/screens/Authentication Screens/RegisterView.jsx
================================================
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Form, Button, Row, Col } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import Message from "../../components/message";
import Loader from "../../components/loader";
import FormContainer from "../../components/formContainer";
import { register } from "../../actions/userActions";
const RegisterView = ({ location, history }) => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [message, setMessage] = useState(null);
const dispatch = useDispatch();
const userRegister = useSelector((state) => state.userRegister);
const { loading, error, userInfo } = userRegister;
const redirect = location.search ? location.search.split("=")[1] : "/";
useEffect(() => {
if (userInfo) {
history.push(redirect);
}
}, [history, userInfo, redirect]);
const submitHandler = (e) => {
e.preventDefault();
if (password !== confirmPassword) {
setMessage("Passwords do not match");
} else {
dispatch(register(name, email, password));
}
};
return (
Sign Up
{message && {message}}
{error && {error}}
{loading && }
Name
setName(e.target.value)}
>
Email Address
setEmail(e.target.value)}
>
Password
setPassword(e.target.value)}
>
Confirm Password
setConfirmPassword(e.target.value)}
>
Have an Account?{" "}
Login
);
};
export default RegisterView;
================================================
FILE: frontend/src/screens/addStudentView.jsx
================================================
import React, { useState, useEffect } from "react";
import { Button, Form } from "react-bootstrap";
import { Link, useHistory } from "react-router-dom";
import FormContainer from "../components/formContainer";
import { useDispatch, useSelector } from "react-redux";
import { addStudent, updateStudent } from "../actions/studentActions";
import Loading from "../components/loader.jsx";
import Message from "../components/message.jsx";
import { STUDENT_UPDATE_RESET } from "../constants/studentConstant";
import Loader from "../components/loader";
const AddStudentView = () => {
const history = useHistory();
const [isEdit, setIsEdit] = useState(false);
const [name, setName] = useState("");
const [address, setAddress] = useState("");
const [category, setCategory] = useState("");
const [city, setCity] = useState("");
const [contact, setContact] = useState("");
const [fatherContact, setFatherContact] = useState("");
const [image, setImage] = useState("");
const [roomNo, setRoomNo] = useState("");
const [blockNo, setBlockNo] = useState("");
const [status, setStatus] = useState("Hostel");
const dispatch = useDispatch();
const studentAdd = useSelector((state) => state.studentAdd);
const { loading, error, success } = studentAdd;
const studentUpdate = useSelector((state) => state.studentUpdate);
const {
loading: loadingUpdate,
error: errorUpdate,
success: successUpdate,
} = studentUpdate;
useEffect(() => {
if (successUpdate) {
dispatch({ type: STUDENT_UPDATE_RESET });
history.push("/");
}
if (history.location.state && history.location.state.studentProps) {
setIsEdit(true);
const student = history.location.state.studentProps;
setName(student.name);
setAddress(student.address);
setCategory(student.category);
setCity(student.city);
setContact(student.contact);
setFatherContact(student.fatherContact);
setImage(student.image);
setRoomNo(student.roomNo);
setBlockNo(student.blockNo);
setStatus(student.status);
}
if (success) {
history.push("/");
}
}, [dispatch, history, success, successUpdate]);
const submitHandler = () => {
if (isEdit === true) {
const _id = history.location.state.studentProps._id;
dispatch(
updateStudent({
_id,
name,
address,
category,
city,
contact,
fatherContact,
image,
roomNo,
blockNo,
status,
})
);
} else {
dispatch(
addStudent({
name,
address,
category,
city,
contact,
fatherContact,
image,
roomNo,
blockNo,
status,
})
);
}
};
return (
<>
Go Back
{loading || loadingUpdate ? (
) : (
<>
{errorUpdate && {errorUpdate}}
{isEdit ? "Edit Student" : "Add Student"}
{loading && }
{error && {error}}
Name
setName(e.target.value)}
>
Status
setStatus(e.target.value)}
>
{["Hostel", "Outside", "Home"].map((x) => (
))}
Address
setAddress(e.target.value)}
>
City
setCity(e.target.value)}
>
Contact
setContact(e.target.value)}
>
Father Contact
setFatherContact(e.target.value)}
>
Room No
setRoomNo(e.target.value)}
>
Block Number
setBlockNo(e.target.value)}
>
Image Url
setImage(e.target.value)}
>
Category
setCategory(e.target.value)}
>
>
)}
>
);
};
export default AddStudentView;
================================================
FILE: frontend/src/screens/analysisView.jsx
================================================
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Row, Col, Button, Modal, Form } from "react-bootstrap";
import DatePicker from "react-datepicker";
import { useDispatch, useSelector } from "react-redux";
import "react-datepicker/dist/react-datepicker.css";
import {
deleteAttendanceByDate,
getAnalysisByDate,
} from "../actions/attendanceActions";
import AnalysisComponent from "../components/analysisComponent";
import Loading from "../components/loader";
import Message from "../components/message";
const AnalysisView = () => {
const dispatch = useDispatch();
const [modal, setModal] = useState(false);
const [days, setDays] = useState(0);
const [idList, setIdList] = useState([]);
const [startDate, setStartDate] = useState(new Date());
const attendanceAnalysis = useSelector((state) => state.attendanceAnalysis);
const { attendance } = attendanceAnalysis;
const attendanceDelete = useSelector((state) => state.attendanceDelete);
const {
loading: loadingDelete,
success: successDelete,
error: errorDelete,
} = attendanceDelete;
useEffect(() => {
if (attendance) {
var temp = idList;
Object.entries(attendance.details).map((at) => {
temp.push(at[0]);
});
setIdList(temp);
} else {
dispatch(getAnalysisByDate(startDate.toString().substring(0, 15)));
}
}, [attendance, dispatch]);
const changeDate = (date) => {
dispatch(getAnalysisByDate(date.toString().substring(0, 15)));
setStartDate(date);
};
const showModal = () => {
setModal(true);
};
const closeModal = () => {
setModal(false);
};
const startDelete = () => {
setModal(false);
dispatch(deleteAttendanceByDate(days));
};
return (
<>
Go Back
{loadingDelete && }
{errorDelete && {errorDelete}}
{successDelete && Attendance Deleted}
Analysis for
{startDate.toISOString().toString().substring(0, 10)}
changeDate(date)}
/>
Enter Number of days before to delete
Enter no of days
setDays(e.target.value)}
>
{}
>
);
};
export default AnalysisView;
================================================
FILE: frontend/src/screens/attendanceView.jsx
================================================
import React, { useState, useEffect } from "react";
import { Form, Button } from "react-bootstrap";
import { useDispatch } from "react-redux";
import { getStudentsByRoomNo as action } from "../actions/studentActions";
import AttendanceTable from "../components/attendanceTable";
const AttendanceView = () => {
const [roomNo, setRoomNo] = useState("");
const dispatch = useDispatch();
useEffect(() => {}, [dispatch]);
const submitHandler = (e) => {
e.preventDefault();
dispatch(action(roomNo));
};
const changeRoomNo = (e) => {
setRoomNo(e.target.value);
};
return (
<>
Take Attendance
changeRoomNo(e)}
>
>
);
};
export default AttendanceView;
================================================
FILE: frontend/src/screens/homeView.jsx
================================================
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import Student from "../components/student";
import Loading from "../components/loader.jsx";
import Message from "../components/message.jsx";
import { listStudents } from "../actions/studentActions";
import Paginate from "../components/paginate";
import {
Row,
Col,
ButtonGroup,
ToggleButton,
Container,
} from "react-bootstrap";
import StudentsTableView from "./studentTableView";
const HomeView = ({ match, history }) => {
const [isGrid, setIsGrid] = useState(true);
const keyword = match.params.keyword;
const pageNumber = match.params.pageNumber || 1;
const userLogin = useSelector((state) => state.userLogin);
const { loading: userLoading, userInfo } = userLogin;
const dispatch = useDispatch();
const studentsList = useSelector((state) => state.studentsList);
const { loading, error, students, page, pages } = studentsList;
useEffect(() => {
if (!userLoading && !userInfo) {
history.push("/login");
}
dispatch(listStudents(keyword, pageNumber));
}, [keyword, pageNumber]);
return (
<>
<>
{["Grid", "Table"].map((type) => (
setIsGrid(e.target.value === "Grid" ? true : false)
}
>
{type === "Grid" ? <> Grid> : <> Table >}
))}
>
Students
{loading ? (
) : error ? (
{error}
) : isGrid ? (
<>
{students.map((student) => (
))}
>
) : (
<>
>
)}
>
);
};
export default HomeView;
================================================
FILE: frontend/src/screens/profileView.jsx
================================================
import React, { useState, useEffect } from "react";
import { Form, Button, Row, Col } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import Message from "../components/message";
import Loader from "../components/loader";
import { getUserDetails, updateUserProfile } from "../actions/userActions";
import { USER_UPDATE_PROFILE_RESET } from "../constants/userConstants";
const ProfileView = ({ history }) => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [message, setMessage] = useState(null);
const dispatch = useDispatch();
const userDetails = useSelector((state) => state.userDetails);
const { loading, error, user } = userDetails;
const userLogin = useSelector((state) => state.userLogin);
const { userInfo } = userLogin;
const userUpdateProfile = useSelector((state) => state.userUpdateProfile);
const { success } = userUpdateProfile;
useEffect(() => {
if (!userInfo) {
history.push("/login");
} else {
if (!user || !user.name || success) {
dispatch({ type: USER_UPDATE_PROFILE_RESET });
dispatch(getUserDetails("profile"));
} else {
setName(user.name);
setEmail(user.email);
}
}
}, [dispatch, history, userInfo, user, success]);
const submitHandler = (e) => {
e.preventDefault();
if (password !== confirmPassword) {
setMessage("Passwords do not match");
} else {
dispatch(updateUserProfile({ id: user._id, name, email, password }));
}
};
return (
Profile
{message && {message}}
{success && Profile Updated}
{loading ? (
) : error ? (
{error}
) : (
Name
setName(e.target.value)}
>
Email Address
setEmail(e.target.value)}
>
Password
setPassword(e.target.value)}
>
Confirm Password
setConfirmPassword(e.target.value)}
>
)}
);
};
export default ProfileView;
================================================
FILE: frontend/src/screens/studentDetailsView.jsx
================================================
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import {
Row,
Col,
Image,
ListGroup,
Card,
Button,
Form,
} from "react-bootstrap";
import Loading from "../components/loader";
import Message from "../components/message";
import {
getStudentDetails,
updateStudent,
deleteStudent,
} from "../actions/studentActions";
import { STUDENT_UPDATE_RESET } from "../constants/studentConstant";
const StudentDetailsView = ({ match, history }) => {
const [status, setStatus] = useState("");
const dispatch = useDispatch();
const studentDetails = useSelector((state) => state.studentDetails);
const { loading, error, student } = studentDetails;
const studentUpdate = useSelector((state) => state.studentUpdate);
const {
loading: loadingUpdate,
error: errorUpdate,
success: successUpdate,
} = studentUpdate;
const studentDelete = useSelector((state) => state.studentDelete);
const {
loading: loadingDelete,
error: errorDelete,
success: successDelete,
} = studentDelete;
useEffect(() => {
if (successDelete) {
history.push("/");
}
if (successUpdate) {
dispatch({ type: STUDENT_UPDATE_RESET });
}
if (!student || !student._id || student._id !== match.params.id) {
dispatch(getStudentDetails(match.params.id));
}
if (student && student._id && !status) {
setStatus(student.status);
}
}, [dispatch, match, successUpdate, successDelete]);
const navigateToEdit = () => {
history.push({
pathname: `/student/edit/${student._id}`,
state: { studentProps: student },
});
};
const updateStatus = () => {
student.status = status;
dispatch(updateStudent(student));
};
const deleteStuden = () => {
if (window.confirm("Are you sure")) {
dispatch(deleteStudent(student._id));
}
};
return (
<>
Go Back
{loading || loadingUpdate || loadingDelete ? (
) : error ? (
{error}
) : (
<>
{errorUpdate && {errorUpdate}}
{errorDelete && {errorDelete}}
{student && (
{student.name}
Phone No:{student.contact}
Father Contact:{student.fatherContact}
City:{student.city}
Address:{student.address}
Room No:
{student.roomNo}
Block No:
{student.blockNo}
Status:
setStatus(e.target.value)}
>
{["Hostel", "Outside", "Home"].map((x) => (
))}
)}
>
)}
>
);
};
export default StudentDetailsView;
================================================
FILE: frontend/src/screens/studentTableView.jsx
================================================
import React, { useEffect } from "react";
import { Table } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import Message from "../components/message";
import Loader from "../components/loader";
import Paginate from "../components/paginate";
import { listStudents } from "../actions/studentActions";
import { Link } from "react-router-dom";
const StudentsTableView = ({ keyword, pageNumber }) => {
const dispatch = useDispatch();
const studentsList = useSelector((state) => state.studentsList);
const { loading, error, students, page, pages } = studentsList;
useEffect(() => {
if (!students) {
dispatch(listStudents(keyword, pageNumber));
}
}, [dispatch, keyword, pageNumber]);
return (
<>
{loading ? (
) : error ? (
{error}
) : (
<>
| Stream |
NAME |
STATUS |
CONTACT |
ROOM NO |
CITY |
{students.map((student) => (
| {student.category} |
{student.name}
|
{student.status}
|
{student.contact}
|
{student.roomNo} |
{student.city} |
))}
>
)}
>
);
};
export default StudentsTableView;
================================================
FILE: frontend/src/screens/userEditView.jsx
================================================
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { Form, Button } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import Message from "../components/message";
import Loader from "../components/loader";
import FormContainer from "../components/formContainer";
import { getUserDetails, updateUser } from "../actions/userActions";
import { USER_UPDATE_RESET } from "../constants/userConstants";
const UserEditView = ({ match, history }) => {
const userId = match.params.userId;
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [isAdmin, setIsAdmin] = useState(false);
const dispatch = useDispatch();
const userDetails = useSelector((state) => state.userDetails);
const { loading, error, user } = userDetails;
const userUpdate = useSelector((state) => state.userUpdate);
const {
loading: loadingUpdate,
error: errorUpdate,
success: successUpdate,
} = userUpdate;
useEffect(() => {
console.log(userId);
if (successUpdate) {
dispatch({ type: USER_UPDATE_RESET });
history.push("/userList");
} else {
if (!user || !user.name || user._id !== userId) {
dispatch(getUserDetails(userId));
} else {
setName(user.name);
setEmail(user.email);
setIsAdmin(user.isAdmin);
}
}
}, [dispatch, history, userId, user, successUpdate]);
const submitHandler = (e) => {
e.preventDefault();
dispatch(updateUser({ _id: userId, name, email, isAdmin }));
};
return (
<>
Go Back
Edit User
{loadingUpdate && }
{errorUpdate && {errorUpdate}}
{loading ? (
) : error ? (
{error}
) : (
Name
setName(e.target.value)}
>
Email Address
setEmail(e.target.value)}
>
setIsAdmin(e.target.checked)}
>
)}
>
);
};
export default UserEditView;
================================================
FILE: frontend/src/screens/userListView.jsx
================================================
import React, { useEffect } from "react";
import { LinkContainer } from "react-router-bootstrap";
import { Table, Button } from "react-bootstrap";
import { useDispatch, useSelector } from "react-redux";
import Message from "../components/message";
import Loader from "../components/loader";
import { listUsers, deleteUser } from "../actions/userActions";
const UserListView = ({ history }) => {
const dispatch = useDispatch();
const userList = useSelector((state) => state.userList);
const { loading, error, users } = userList;
const userLogin = useSelector((state) => state.userLogin);
const { userInfo } = userLogin;
const userDelete = useSelector((state) => state.userDelete);
const { success: successDelete } = userDelete;
useEffect(() => {
if (userInfo && userInfo.isAdmin) {
dispatch(listUsers());
} else {
history.push("/login");
}
}, [dispatch, history, successDelete, userInfo]);
const deleteHandler = (id) => {
if (window.confirm("Are you sure")) {
dispatch(deleteUser(id));
}
};
return (
<>
Users
{loading ? (
) : error ? (
{error}
) : (
| ID |
NAME |
EMAIL |
ADMIN |
|
{users.map((user) => (
| {user._id} |
{user.name} |
{user.email}
|
{user.isAdmin ? (
) : (
)}
|
|
))}
)}
>
);
};
export default UserListView;
================================================
FILE: frontend/src/store.jsx
================================================
import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { composeWithDevTools } from "@redux-devtools/extension";
import {
studentListReducer,
studentAddReducer,
studentDetailsReducer,
getStudentsByRoomNoReducer,
studentUpdateReducer,
studentDeleteReducer,
} from "./reducers/studentsReducer";
import {
userLoginReducer,
userRegisterReducer,
userDetailsReducer,
userUpdateProfileReducer,
userListReducer,
userDeleteReducer,
userUpdateReducer,
} from "./reducers/userReducers";
import {
attendanceDataEnterReducer,
attendanceAnalysisReducer,
deleteAttendanceReducer,
} from "./reducers/attendanceReducer";
const reducer = combineReducers({
studentsList: studentListReducer,
studentDetails: studentDetailsReducer,
studentAdd: studentAddReducer,
studentUpdate: studentUpdateReducer,
studentDelete: studentDeleteReducer,
getStudentsByRoomNo: getStudentsByRoomNoReducer,
userLogin: userLoginReducer,
userRegister: userRegisterReducer,
userDetails: userDetailsReducer,
userUpdateProfile: userUpdateProfileReducer,
userList: userListReducer,
userDelete: userDeleteReducer,
userUpdate: userUpdateReducer,
attendanceDataEnter: attendanceDataEnterReducer,
attendanceAnalysis: attendanceAnalysisReducer,
attendanceDelete: deleteAttendanceReducer,
});
const userInfoFromStorage = localStorage.getItem("userInfo")
? JSON.parse(localStorage.getItem("userInfo"))
: null;
const initialState = {
userLogin: { userInfo: userInfoFromStorage },
};
const middleware = [thunk];
const store = createStore(
reducer,
initialState,
composeWithDevTools(applyMiddleware(...middleware))
);
export default store;
================================================
FILE: frontend/vite.config.js
================================================
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
port: 3000,
proxy: {
"/users": { target: "http://127.0.0.1:5000", changeOrigin: true },
"/student": { target: "http://127.0.0.1:5000", changeOrigin: true },
"/attendance": { target: "http://127.0.0.1:5000", changeOrigin: true },
},
},
});
================================================
FILE: package.json
================================================
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"engines": {
"node": ">=20"
},
"scripts": {
"start": "node server/index.js",
"server": "nodemon server/index.js",
"client": "npm run dev --prefix frontend",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"test": "echo \"Error: no test specified\" && exit 1",
"heroku-postbuild": "NPM_CONFIG_PRODUCTION=false npm install --prefix frontend && npm run build --prefix frontend"
},
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express-async-handler": "^1.2.0",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.9.5",
"morgan": "^1.10.0"
},
"devDependencies": {
"concurrently": "^9.1.2",
"nodemon": "^3.1.9"
}
}
================================================
FILE: server/config/mongoDBConfig.js
================================================
import mongoose from "mongoose";
const connectDB = async () => {
try {
const conn = await mongoose.connect(process.env.MONGO_URI);
console.log(`MongoDB Connected: ${conn.connection.host}`);
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
};
export default connectDB;
================================================
FILE: server/controllers/attendanceController.js
================================================
import asyncHandler from "express-async-handler";
import Attendance from "../models/attendance.js";
const getAttendanceByRoomNo = asyncHandler(async (req, res) => {
const date = req.body.date || Date().toString().substring(0, 15);
const attendance = await Attendance.findOne({
roomNo: { $in: [req.body.roomNo] },
date: date,
});
if (attendance) {
res.json(attendance);
} else {
res.status(404);
throw new Error(
`You didn't take attendance today for room No:${req.params.roomId}`
);
}
});
const getAttendance = asyncHandler(async (req, res) => {
const date = req.body.date || Date().toString().substring(0, 15);
const attendance = await Attendance.findOne({
date: date,
});
if (attendance) {
res.json(attendance);
} else {
res.status(404);
throw new Error(`You didn't take attendance ${date}!!`);
}
});
const enterAttendanceByRoomNo = asyncHandler(async (req, res) => {
const date = req.body.date || Date().toString().substring(0, 15);
const attendance = await Attendance.findOne({
date: date,
});
if (attendance) {
const dataTemp = attendance.data;
const detailsTemp = attendance.details;
for (const [key, value] of Object.entries(req.body.data)) {
dataTemp.set(key, value);
}
for (const [key, value] of Object.entries(req.body.details)) {
detailsTemp.set(key, value);
}
attendance.details = detailsTemp;
attendance.data = dataTemp;
const updatedAttendance = await attendance.save();
res.json(updatedAttendance);
} else {
const newAttendance = await Attendance.create({
roomNo: [req.body.roomNo],
date: date,
data: req.body.data,
details: req.body.details,
});
res.json(newAttendance);
}
});
const deleteAttendanceByDays = asyncHandler(async (req, res) => {
const days = req.params.days;
var date = new Date();
var deletionDate = new Date(date.setDate(date.getDate() - days));
await Attendance.deleteMany({
createdAt: { $lt: deletionDate },
});
res.json({ message: `Deleted Attendance for before past ${days} days` });
});
export {
getAttendanceByRoomNo,
enterAttendanceByRoomNo,
getAttendance,
deleteAttendanceByDays,
};
================================================
FILE: server/controllers/studentController.js
================================================
import asyncHandler from "express-async-handler";
import Student from "../models/student.js";
import Attendance from "../models/attendance.js";
const addStudent = asyncHandler(async (req, res) => {
const {
name,
address,
category,
city,
contact,
fatherContact,
image,
roomNo,
blockNo,
status,
} = req.body;
const studentExist = await Student.findOne({ name: name });
if (studentExist) {
res.status(400);
throw new Error("Student already exists");
}
const student = await Student.create({
name,
address,
category,
city,
contact,
fatherContact,
image,
roomNo,
blockNo,
status,
});
if (student) {
res.status(201).json({
_id: student._id,
name: student.name,
address: student.address,
category: student.category,
city: student.city,
contact: student.contact,
fatherContact: student.fatherContact,
image: student.image,
roomNo: student.roomNo,
blockNo: student.blockNo,
status: student.status,
});
} else {
res.status(400);
throw new Error("Invalid Student data");
}
});
const updateStudentProfile = asyncHandler(async (req, res) => {
const student = await Student.findById(req.body._id);
if (student) {
student.name = req.body.name || student.name;
student.address = req.body.address || student.address;
student.category = req.body.category || student.category;
student.city = req.body.city || student.city;
student.contact = req.body.contact || student.contact;
student.fatherContact = req.body.fatherContact || student.fatherContact;
student.image = req.body.image || student.image;
student.roomNo = req.body.roomNo || student.roomNo;
student.blockNo = req.body.blockNo || student.blockNo;
student.status = req.body.status || student.status;
const updatedStudent = await student.save();
res.json({
_id: updatedStudent._id,
name: updatedStudent.name,
address: updatedStudent.address,
category: updatedStudent.category,
city: updatedStudent.city,
contact: updatedStudent.contact,
fatherContact: updatedStudent.fatherContact,
image: updatedStudent.image,
roomNo: updatedStudent.roomNo,
blockNo: updatedStudent.blockNo,
status: updatedStudent.status,
});
} else {
res.status(404);
throw new Error("Student not found");
}
});
const getAllStudents = asyncHandler(async (req, res) => {
const pageSize = 15;
const page = Number(req.query.pageNumber) || 1;
const keyword = req.query.keyword
? {
name: {
$regex: req.query.keyword,
$options: "i",
},
}
: {};
const count = await Student.countDocuments({ ...keyword });
const students = await Student.find({ ...keyword })
.limit(pageSize)
.skip(pageSize * (page - 1));
if (students && students.length != 0) {
res.json({ students, page, pages: Math.ceil(count / pageSize) });
} else {
res.status(404);
throw new Error("No Students Found");
}
});
const deleteStudent = asyncHandler(async (req, res) => {
const student = await Student.findById(req.params.id);
if (student) {
await student.remove();
res.json({ message: "Student removed" });
} else {
res.status(404);
throw new Error("Student not found");
}
});
const getStudentById = asyncHandler(async (req, res) => {
const student = await Student.findById(req.params.id);
if (student) {
res.json(student);
} else {
res.status(404);
throw new Error("Students not found");
}
});
const getStudentByRoomNo = asyncHandler(async (req, res) => {
const attendance = await Attendance.findOne({
date: Date().toString().substring(0, 15),
roomNo: { $in: [req.params.roomId] },
});
const students = await Student.find({ roomNo: req.params.roomId });
if (students) {
attendance
? res.json({ students: students, attendance: attendance })
: res.json({ students: students });
} else {
res.status(404);
throw new Error("Students not found");
}
});
export {
addStudent,
updateStudentProfile,
getAllStudents,
deleteStudent,
getStudentById,
getStudentByRoomNo,
};
================================================
FILE: server/controllers/userController.js
================================================
import asyncHandler from "express-async-handler";
import generateToken from "../utils/generateToken.js";
import User from "../models/user.js";
const authUser = asyncHandler(async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (user && (await user.matchPassword(password))) {
res.json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
token: generateToken(user._id),
});
} else {
res.status(401);
throw new Error("Invalid email or password");
}
});
const registerUser = asyncHandler(async (req, res) => {
const { name, email, password } = req.body;
const userExists = await User.findOne({ email });
if (userExists) {
res.status(400);
throw new Error("User already exists");
}
const user = await User.create({
name,
email,
password,
});
if (user) {
const token = generateToken(user._id);
res.status(201).json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
token: token,
});
} else {
res.status(400);
throw new Error("Invalid user data");
}
});
const getUserProfile = asyncHandler(async (req, res) => {
const user = await User.findById(req.user._id);
if (user) {
res.json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
});
} else {
res.status(404);
throw new Error("User not found");
}
});
const updateUserProfile = asyncHandler(async (req, res) => {
const user = await User.findById(req.user._id);
if (user) {
user.name = req.body.name || user.name;
user.email = req.body.email || user.email;
if (req.body.password) {
user.password = req.body.password;
}
const updatedUser = await user.save();
res.json({
_id: updatedUser._id,
name: updatedUser.name,
email: updatedUser.email,
isAdmin: updatedUser.isAdmin,
token: generateToken(updatedUser._id),
});
} else {
res.status(404);
throw new Error("User not found");
}
});
const getUsers = asyncHandler(async (req, res) => {
const users = await User.find({});
res.json(users);
});
const deleteUser = asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (user) {
await user.remove();
res.json({ message: "User removed" });
} else {
res.status(404);
throw new Error("User not found");
}
});
const getUserById = asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id).select("-password");
if (user) {
res.json(user);
} else {
res.status(404);
throw new Error("User not found");
}
});
const updateUser = asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
if (user) {
user.name = req.body.name || user.name;
user.email = req.body.email || user.email;
user.isAdmin = req.body.isAdmin;
const updatedUser = await user.save();
res.json({
_id: updatedUser._id,
name: updatedUser.name,
email: updatedUser.email,
isAdmin: updatedUser.isAdmin,
});
} else {
res.status(404);
throw new Error("User not found");
}
});
export {
authUser,
registerUser,
getUserProfile,
updateUserProfile,
getUsers,
deleteUser,
getUserById,
updateUser,
};
================================================
FILE: server/data/students.js
================================================
const students = [];
export default students;
================================================
FILE: server/index.js
================================================
import express from "express";
import userRoutes from "./routes/userRoutes.js";
import studentRoutes from "./routes/studentRoutes.js";
import attendanceRoutes from "./routes/attendanceRoutes.js";
import path from "path";
import morgan from "morgan";
import dotenv from "dotenv";
import connectDB from "./config/mongoDBConfig.js";
import { errorHandler, notFound } from "./middleware/errorMiddleware.js";
dotenv.config();
connectDB();
const app = express();
if (process.env.NODE_ENV === "development") {
app.use(morgan("dev"));
}
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use("/users", userRoutes);
app.use("/student", studentRoutes);
app.use("/attendance", attendanceRoutes);
const __dirname = path.resolve();
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "/frontend/dist")));
app.get("*", (req, res) =>
res.sendFile(path.resolve(__dirname, "frontend", "dist", "index.html"))
);
} else {
app.get("/", (req, res) => {
res.send("API is running....");
});
}
app.use(notFound);
app.use(errorHandler);
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(
`Server running in ${process.env.NODE_ENV || "development"} mode on port ${PORT}`
);
});
================================================
FILE: server/middleware/authMiddleware.js
================================================
import jwt from "jsonwebtoken";
import asyncHandler from "express-async-handler";
import User from "../models/user.js";
const protect = asyncHandler(async (req, res, next) => {
let token;
if (
req.headers.authorization &&
req.headers.authorization.startsWith("Bearer")
) {
try {
token = req.headers.authorization.split(" ")[1];
const decoded = jwt.verify(token, process.env.JWT_SECRET);
req.user = await User.findById(decoded.id).select("-password");
next();
} catch (error) {
console.error(error);
res.status(401);
throw new Error("Not authorized, token failed");
}
}
if (!token) {
res.status(401);
throw new Error("Not authorized, no token");
}
});
const admin = (req, res, next) => {
if (req.user && req.user.isAdmin) {
next();
} else {
res.status(401);
throw new Error("Not authorized as an admin");
}
};
export { protect, admin };
================================================
FILE: server/middleware/errorMiddleware.js
================================================
const notFound = (req, res, next) => {
const error = new Error(`Not Found - ${req.originalUrl}`);
res.status(404);
next(error);
};
const errorHandler = (err, req, res, next) => {
const statusCode = res.statusCode === 200 ? 500 : res.statusCode;
res.status(statusCode);
res.json({
message: err.message,
stack: process.env.NODE_ENV === "production" ? null : err.stack,
});
};
export { notFound, errorHandler };
================================================
FILE: server/models/attendance.js
================================================
import mongoose from "mongoose";
const attendanceSchema = mongoose.Schema(
{
roomNo: {
type: Array,
required: true,
},
date: {
type: String,
default: Date().toString().substring(0, 15),
},
data: {
type: Map,
required: true,
default: {},
},
details: {
type: Map,
required: true,
default: {},
},
},
{
timestamps: true,
}
);
const Attendance = mongoose.model("Attendance", attendanceSchema);
export default Attendance;
================================================
FILE: server/models/student.js
================================================
import mongoose from "mongoose";
const studentSchema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
address: {
type: String,
required: true,
},
category: {
type: String,
required: true,
},
city: {
type: String,
required: true,
},
contact: {
type: Number,
required: true,
},
fatherContact: {
type: Number,
required: true,
},
image: {
type: String,
required: true,
},
roomNo: {
type: String,
required: true,
},
blockNo: {
type: String,
required: true,
},
status: {
type: String,
required: true,
},
},
{
timestamps: true,
}
);
const Student = mongoose.model("Student", studentSchema);
export default Student;
================================================
FILE: server/models/user.js
================================================
import mongoose from "mongoose";
import bcrypt from "bcryptjs";
const userSchema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
isAdmin: {
type: Boolean,
required: true,
default: false,
},
},
{
timestamps: true,
}
);
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password);
};
userSchema.pre("save", async function () {
if (!this.isModified("password")) {
return;
}
const salt = await bcrypt.genSalt(10);
this.password = await bcrypt.hash(this.password, salt);
});
const User = mongoose.model("User", userSchema);
export default User;
================================================
FILE: server/routes/attendanceRoutes.js
================================================
import express from "express";
import {
deleteAttendanceByDays,
enterAttendanceByRoomNo,
getAttendance,
getAttendanceByRoomNo,
} from "../controllers/attendanceController.js";
import { protect, admin } from "../middleware/authMiddleware.js";
const router = express.Router();
router.route("/:roomId").get(protect, getAttendanceByRoomNo);
router.route("/").post(protect, admin, enterAttendanceByRoomNo);
router.route("/:days").delete(protect, admin, deleteAttendanceByDays);
router.route("/getAnalysis").post(protect, getAttendance);
export default router;
================================================
FILE: server/routes/studentRoutes.js
================================================
import express from "express";
import {
addStudent,
deleteStudent,
getAllStudents,
getStudentById,
updateStudentProfile,
getStudentByRoomNo,
} from "../controllers/studentController.js";
import { protect, admin } from "../middleware/authMiddleware.js";
const router = express.Router();
router.route("/all").get(protect, getAllStudents);
router.route("/addStudent").post(protect, admin, addStudent);
router
.route("/:id")
.get(protect, getStudentById)
.delete(protect, admin, deleteStudent)
.put(protect, admin, updateStudentProfile);
router.route("/room/:roomId").get(getStudentByRoomNo);
export default router;
================================================
FILE: server/routes/userRoutes.js
================================================
import express from "express";
const router = express.Router();
import {
authUser,
registerUser,
getUserProfile,
updateUserProfile,
getUsers,
deleteUser,
getUserById,
updateUser,
} from "../controllers/userController.js";
import { protect, admin } from "../middleware/authMiddleware.js";
router.route("/").post(registerUser).get(protect, admin, getUsers);
router.post("/login", authUser);
router
.route("/profile")
.get(protect, getUserProfile)
.put(protect, updateUserProfile);
router
.route("/:id")
.delete(protect, admin, deleteUser)
.get(protect, admin, getUserById)
.put(protect, admin, updateUser);
export default router;
================================================
FILE: server/seeder.js
================================================
import dotenv from "dotenv";
import Student from "./models/student.js";
import connectDB from "./config/mongoDBConfig.js";
dotenv.config();
const importData = async () => {
try {
await connectDB();
await Student.deleteMany();
console.log("Data Imported!");
process.exit();
} catch (error) {
console.error(`${error}`);
process.exit(1);
}
};
const destroyData = async () => {
try {
await connectDB();
await Student.deleteMany();
console.log("Data Destroyed!");
process.exit();
} catch (error) {
console.error(`${error}`);
process.exit(1);
}
};
if (process.argv[2] === "-d") {
destroyData();
} else {
importData();
}
================================================
FILE: server/utils/generateToken.js
================================================
import jwt from 'jsonwebtoken'
const generateToken = (id) => {
return jwt.sign({ id }, process.env.JWT_SECRET, {
expiresIn: '30d',
})
}
export default generateToken