├── backend ├── .env ├── .gitignore ├── db.js ├── package.json ├── src │ ├── Helper.js │ ├── middleware │ │ └── Auth.js │ └── queries.js ├── index.js └── commands │ └── DDL.sql ├── payroll-frontend ├── src │ ├── baseUrl.js │ ├── Assets │ │ ├── Logo.png │ │ ├── squares.png │ │ └── logo.svg │ ├── testData.js │ ├── setupTests.js │ ├── App.test.js │ ├── index.css │ ├── reportWebVitals.js │ ├── index.js │ ├── StyleSheets │ │ ├── Report.css │ │ ├── Profile.css │ │ ├── Welcome.css │ │ └── AdminOptions.css │ ├── Components │ │ └── Buttons.js │ ├── Screens │ │ ├── Attendance.js │ │ ├── AttendanceLog.js │ │ ├── Welcome.js │ │ ├── AdminAddInfo.js │ │ ├── ChangePassword.js │ │ ├── AdminDashboard.js │ │ ├── Reports.js │ │ ├── AdminUpdateInfo.js │ │ ├── AddExtras.js │ │ ├── EmployeeProfile.js │ │ ├── AddDep.js │ │ ├── EmployeeDrawer.js │ │ ├── AddGrade.js │ │ ├── ResetPassword.js │ │ ├── EmployeeLogin.js │ │ ├── AdminLogin.js │ │ ├── AddEmployee.js │ │ └── UpdateDetails.js │ └── App.js ├── public │ ├── robots.txt │ ├── favicon.ico │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── index.html ├── .gitignore ├── package.json └── README.md ├── ERDiagramFinal.pdf ├── AgileDocumentation ├── SRS.pdf ├── Estimation.pdf ├── User Stories.pdf ├── Sprint Backlog.pdf ├── Use Case Diagram.png ├── Website Workflow.pdf ├── Architecture Qualities.pdf ├── UI prototyping │ ├── addGrade.png │ ├── welcome.png │ ├── Admin Login.jpeg │ ├── addDepartment.png │ ├── addEmployee.png │ ├── adminAddInfo.png │ ├── Burndown Chart.jpeg │ ├── Employee Login.jpeg │ ├── adminDashboard.png │ ├── employeeProfile.png │ ├── generateReport.png │ ├── markAttendance.png │ ├── employeeDashboard.png │ ├── Reset Password Admin.jpeg │ └── Reset Pssword Employee.jpeg └── High Level Domain Architecture.jpeg └── README.md /backend/.env: -------------------------------------------------------------------------------- 1 | SECRET="TOPSECRET" -------------------------------------------------------------------------------- /backend/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /payroll-frontend/src/baseUrl.js: -------------------------------------------------------------------------------- 1 | export const base_url = "http://localhost:3003/api/"; 2 | -------------------------------------------------------------------------------- /ERDiagramFinal.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/ERDiagramFinal.pdf -------------------------------------------------------------------------------- /payroll-frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /AgileDocumentation/SRS.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/SRS.pdf -------------------------------------------------------------------------------- /AgileDocumentation/Estimation.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/Estimation.pdf -------------------------------------------------------------------------------- /AgileDocumentation/User Stories.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/User Stories.pdf -------------------------------------------------------------------------------- /payroll-frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/payroll-frontend/public/favicon.ico -------------------------------------------------------------------------------- /payroll-frontend/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/payroll-frontend/public/logo192.png -------------------------------------------------------------------------------- /payroll-frontend/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/payroll-frontend/public/logo512.png -------------------------------------------------------------------------------- /payroll-frontend/src/Assets/Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/payroll-frontend/src/Assets/Logo.png -------------------------------------------------------------------------------- /AgileDocumentation/Sprint Backlog.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/Sprint Backlog.pdf -------------------------------------------------------------------------------- /AgileDocumentation/Use Case Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/Use Case Diagram.png -------------------------------------------------------------------------------- /AgileDocumentation/Website Workflow.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/Website Workflow.pdf -------------------------------------------------------------------------------- /payroll-frontend/src/Assets/squares.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/payroll-frontend/src/Assets/squares.png -------------------------------------------------------------------------------- /AgileDocumentation/Architecture Qualities.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/Architecture Qualities.pdf -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/addGrade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/addGrade.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/welcome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/welcome.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/Admin Login.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/Admin Login.jpeg -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/addDepartment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/addDepartment.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/addEmployee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/addEmployee.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/adminAddInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/adminAddInfo.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/Burndown Chart.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/Burndown Chart.jpeg -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/Employee Login.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/Employee Login.jpeg -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/adminDashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/adminDashboard.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/employeeProfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/employeeProfile.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/generateReport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/generateReport.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/markAttendance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/markAttendance.png -------------------------------------------------------------------------------- /AgileDocumentation/High Level Domain Architecture.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/High Level Domain Architecture.jpeg -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/employeeDashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/employeeDashboard.png -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/Reset Password Admin.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/Reset Password Admin.jpeg -------------------------------------------------------------------------------- /AgileDocumentation/UI prototyping/Reset Pssword Employee.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nandwalritik/PayrollManagement/HEAD/AgileDocumentation/UI prototyping/Reset Pssword Employee.jpeg -------------------------------------------------------------------------------- /payroll-frontend/src/testData.js: -------------------------------------------------------------------------------- 1 | export const testData=[{ 2 | id:123, 3 | Name:'John', 4 | age:15 5 | },{ 6 | id:231, 7 | Name:'Mary', 8 | age:21 9 | }, 10 | { 11 | id:212, 12 | Name:'Lata', 13 | age:22 14 | }] -------------------------------------------------------------------------------- /payroll-frontend/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /payroll-frontend/src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /payroll-frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /payroll-frontend/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /payroll-frontend/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 4 | getCLS(onPerfEntry); 5 | getFID(onPerfEntry); 6 | getFCP(onPerfEntry); 7 | getLCP(onPerfEntry); 8 | getTTFB(onPerfEntry); 9 | }); 10 | } 11 | }; 12 | 13 | export default reportWebVitals; 14 | -------------------------------------------------------------------------------- /backend/db.js: -------------------------------------------------------------------------------- 1 | const Pool = require("pg").Pool; 2 | const pool = new Pool({ 3 | user: "me", 4 | host: "localhost", 5 | database: "api", 6 | password: "password", 7 | port: 5432, 8 | }); 9 | 10 | const query = (text, params) => { 11 | return new Promise((resolve, reject) => { 12 | pool 13 | .query(text, params) 14 | .then((res) => { 15 | resolve(res); 16 | }) 17 | .catch((err) => { 18 | reject(err); 19 | }); 20 | }); 21 | }; 22 | module.exports = { query }; 23 | -------------------------------------------------------------------------------- /payroll-frontend/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | 7 | 8 | ReactDOM.render( 9 | 10 | 11 | , 12 | document.getElementById('root') 13 | ); 14 | 15 | // If you want to start measuring performance in your app, pass a function 16 | // to log results (for example: reportWebVitals(console.log)) 17 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 18 | reportWebVitals(); 19 | -------------------------------------------------------------------------------- /backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "version": "1.0.0", 4 | "description": "\"Restful api for payroll management system\"", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "bcrypt": "^5.0.0", 13 | "body-parser": "^1.19.0", 14 | "cors": "^2.8.5", 15 | "dotenv": "^8.2.0", 16 | "express": "^4.17.1", 17 | "jsonwebtoken": "^8.5.1", 18 | "moment": "^2.29.1", 19 | "nodemon": "^2.0.6", 20 | "pg": "^8.5.1", 21 | "uuid": "^8.3.1" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /payroll-frontend/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /backend/src/Helper.js: -------------------------------------------------------------------------------- 1 | const jwt = require('jsonwebtoken') 2 | const bcrypt = require('bcrypt') 3 | 4 | const hashPassword = (password) => { 5 | return bcrypt.hashSync(password, bcrypt.genSaltSync(8)) 6 | } 7 | const comparePassword = (hashPassword, password) => { 8 | return bcrypt.compareSync(password, hashPassword) 9 | } 10 | const isValidEmail = (email) => { 11 | return /\S+@\S+\.\S+/.test(email); 12 | } 13 | const generateToken = (id) => { 14 | const token = jwt.sign({ 15 | userId: id 16 | }, 17 | process.env.SECRET, { expiresIn: '7d' } 18 | ); 19 | console.log("Token generated for userid ",id) 20 | return token; 21 | } 22 | 23 | module.exports = { hashPassword, comparePassword, isValidEmail, generateToken } -------------------------------------------------------------------------------- /payroll-frontend/src/StyleSheets/Report.css: -------------------------------------------------------------------------------- 1 | 2 | .report-wrapper { 3 | padding: 8px; 4 | margin-top: 150px; 5 | background-color: transparent; 6 | box-sizing: border-box; 7 | display: flex; 8 | flex-direction: column; 9 | width: 100%; 10 | } 11 | 12 | .part { 13 | font-size: 1.1em; 14 | font-weight: 800; 15 | border-bottom: 1px solid grey; 16 | margin-bottom: 10px; 17 | padding-bottom: 8px; 18 | } 19 | 20 | .pair { 21 | color: black; 22 | padding: 8px; 23 | margin-bottom: 8px; 24 | width: 100%; 25 | display: flex; 26 | flex-direction: row; 27 | } 28 | 29 | .emt { 30 | text-align: right; 31 | width: 25%; 32 | color: #242424; 33 | } 34 | .val { 35 | border: 1px solid blue; 36 | width: 70%; 37 | background-color: lightblue; 38 | opacity: 0.8; 39 | margin-left: 20px; 40 | padding-left: 6px; 41 | font-size: 1.1rem; 42 | } 43 | 44 | .top .val { 45 | width:40%; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /backend/src/middleware/Auth.js: -------------------------------------------------------------------------------- 1 | // import jwt from "jsonwebtoken"; 2 | // import query from "../../db"; 3 | const jwt = require('jsonwebtoken') 4 | const query = require('../../db') 5 | 6 | const verifyToken = async (req, res, next) => { 7 | const token = req.headers["x-access-token"]; 8 | if (!token) { 9 | return res.status(400).send({ message: "Token is not provided" }); 10 | } 11 | try { 12 | const decoded = await jwt.verify(token, process.env.SECRET); 13 | const text = "SELECT * FROM admin WHERE id = $1"; 14 | const { rows } = await query(text, [decoded.userId]); 15 | if (!rows[0]) { 16 | return res 17 | .status(400) 18 | .send({ message: "The token you provided is invalid" }); 19 | } 20 | req.user = { id: decoded.userId }; 21 | next(); 22 | } catch (error) { 23 | return res.status(400).send(error); 24 | } 25 | } 26 | 27 | module.exports={verifyToken} 28 | // export default Auth; 29 | -------------------------------------------------------------------------------- /payroll-frontend/src/Components/Buttons.js: -------------------------------------------------------------------------------- 1 | // import React from 'react' 2 | 3 | // export const Buttons = (props) => { 4 | // return ( 5 | //
6 | 7 | //
8 | // ) 9 | // } 10 | // const styles = { 11 | // button:{ 12 | // width: 13 | // } 14 | // } 15 | // import React from "react"; 16 | // import logo from "../Assets/Logo.png"; 17 | // import "../StyleSheets/Welcome.css"; 18 | 19 | // export const Welcome = () => { 20 | // return ( 21 | //
22 | //
23 | //

Payroll Management System

24 | //
25 | // logo 26 | //
27 | //
28 | // 29 | // 30 | //
31 | // ); 32 | // }; -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/Attendance.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 6 | import { faFile, faPen } from "@fortawesome/free-solid-svg-icons"; 7 | import { useHistory } from "react-router-dom"; 8 | 9 | 10 | const Attendance=()=>{ 11 | let history = useHistory(); 12 | return ( 13 | 14 | <> 15 |
16 |
17 |

Payroll Management System

18 |
19 | logo 20 |
21 |
22 |
history.push("/attendancelog")}> 24 | 25 |

Attendance Log

26 |
27 |
28 | 29 |

Mark Attendance

30 |
31 |
32 |
33 | 34 | ); 35 | }; 36 | 37 | 38 | export default Attendance; 39 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AttendanceLog.js: -------------------------------------------------------------------------------- 1 | 2 | import React, { useState } from "react"; 3 | import logo from "../Assets/Logo.png"; 4 | import "../StyleSheets/Welcome.css"; 5 | import "../StyleSheets/AdminOptions.css"; 6 | import "../StyleSheets/Report.css"; 7 | 8 | const AttendanceLog=()=>{ 9 | 10 | return ( 11 | 12 |
13 |
14 |

Payroll Management System

15 |
16 | logo 17 |
18 |
19 |
20 |
21 |
Total Working Days:
22 |
01
23 |
24 |
25 |
Days attended:
26 |
01
27 |
28 |
29 |
Encashed Leaves:
30 |
01
31 |
32 |
33 |
Paid Leaves Standing:
34 |
01
35 |
36 |
37 |
38 |
39 | ); 40 | }; 41 | 42 | 43 | export default AttendanceLog; 44 | -------------------------------------------------------------------------------- /payroll-frontend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "payroll-frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@fortawesome/fontawesome-free": "^5.15.1", 7 | "@fortawesome/fontawesome-svg-core": "^1.2.32", 8 | "@fortawesome/free-solid-svg-icons": "^5.15.1", 9 | "@fortawesome/react-fontawesome": "^0.1.13", 10 | "@material-ui/core": "^4.11.1", 11 | "@material-ui/icons": "^4.9.1", 12 | "@testing-library/jest-dom": "^5.11.4", 13 | "@testing-library/react": "^11.1.0", 14 | "@testing-library/user-event": "^12.1.10", 15 | "formik": "^2.2.6", 16 | "moment": "^2.29.1", 17 | "react": "^17.0.1", 18 | "react-dom": "^17.0.1", 19 | "react-modal": "^3.12.1", 20 | "react-router-dom": "^5.2.0", 21 | "react-scripts": "4.0.0", 22 | "web-vitals": "^0.2.4" 23 | }, 24 | "scripts": { 25 | "start": "react-scripts start", 26 | "build": "react-scripts build", 27 | "test": "react-scripts test", 28 | "eject": "react-scripts eject" 29 | }, 30 | "eslintConfig": { 31 | "extends": [ 32 | "react-app", 33 | "react-app/jest" 34 | ] 35 | }, 36 | "browserslist": { 37 | "production": [ 38 | ">0.2%", 39 | "not dead", 40 | "not op_mini all" 41 | ], 42 | "development": [ 43 | "last 1 chrome version", 44 | "last 1 firefox version", 45 | "last 1 safari version" 46 | ] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/Welcome.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import Modal from "react-modal"; 5 | import { Redirect } from "react-router-dom"; 6 | import { useHistory } from "react-router-dom"; 7 | 8 | const Welcome = () => { 9 | const [showId, setShowid] = useState(0); 10 | const [adminModal, setAdminmodal] = useState(false); 11 | const [userModal, setUsermodal] = useState(false); 12 | console.log("Value set to ", showId); 13 | const history = useHistory() 14 | return ( 15 |
16 |
17 |

Payroll Management System

18 |
19 | logo 20 |
21 |
22 | 25 | 28 |
29 |
30 |
31 | ); 32 | }; 33 | const styles = { 34 | content: { 35 | // top: "50%", 36 | // left: "50%", 37 | // right: "auto", 38 | // bottom: "auto", 39 | // marginRight: "-50%", 40 | // transform: "translate(-50%, -50%)", 41 | width: "20%", 42 | }, 43 | }; 44 | export default Welcome; 45 | -------------------------------------------------------------------------------- /payroll-frontend/src/StyleSheets/Profile.css: -------------------------------------------------------------------------------- 1 | .profile-wrapper { 2 | display: flex; 3 | flex-direction: row-reverse; 4 | width: 100%; 5 | } 6 | 7 | .profile-wrapper-in { 8 | width: 50%; 9 | margin-top: 5em; 10 | padding: 1em 0; 11 | margin: 2em auto; 12 | margin-left: auto; 13 | } 14 | 15 | .pair { 16 | color: black; 17 | padding: 8px; 18 | margin-bottom: 8px; 19 | width: 100%; 20 | display: flex; 21 | flex-direction: row; 22 | } 23 | 24 | .emt { 25 | text-align: right; 26 | width: 25%; 27 | color: #242424; 28 | font-size:1.1em; 29 | } 30 | .val { 31 | width: 70%; 32 | border: 2px solid transparent; 33 | opacity: 0.8; 34 | margin-left: 20px; 35 | padding-left: 6px; 36 | font-size: 1.1rem; 37 | box-sizing: border-box; 38 | } 39 | 40 | .val:hover { 41 | border: 2px solid rgb(24, 160, 248); 42 | } 43 | 44 | 45 | .button { 46 | display: block; 47 | text-align: center; 48 | margin: 2em auto; 49 | width: 12em; 50 | height: 9em; 51 | background-color: #fff; 52 | border: 2px solid #8ee3e3; 53 | border-radius: 1em; 54 | padding: 1em 0; 55 | letter-spacing: 0.125em; 56 | word-spacing: 0.15em; 57 | font-size: 1.1em; 58 | color: #444; 59 | } 60 | 61 | .button:hover { 62 | border-color: rgb(24, 160, 248); 63 | } 64 | 65 | .button:focus { 66 | outline: none; 67 | } 68 | 69 | .button .svg-inline--fa { 70 | width: 3rem; 71 | height: 3rem; 72 | fill: #8ee3e3; 73 | } 74 | @media (max-width: 768px) { 75 | .profile-wrapper { 76 | display: flex; 77 | flex-direction:column; 78 | align-items:center; 79 | } 80 | .button { 81 | position: relative; 82 | 83 | } 84 | .profile-wrapper-in { 85 | position: relative; 86 | width: 100%; 87 | left:1em; 88 | top: 1em; 89 | margin-right:0; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AdminAddInfo.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import { useHistory } from "react-router-dom"; 5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 6 | import { faUser,faBuilding,faAward ,faCoins} from '@fortawesome/free-solid-svg-icons'; 7 | 8 | const AdminAddInfo=()=>{ 9 | const history = useHistory(); 10 | 11 | return
12 |
13 |

Payroll Management System

14 |
15 | logo 16 |
17 |
18 |
19 |
history.push('/addEmployee')}> 20 | 21 |

Employee

22 |
23 |
history.push('/addDep')}> 24 | 25 |

Department

26 |
27 |
28 | 29 |
30 |
history.push('/addGrade')} > 31 | 32 |

Grade

33 |
34 |
history.push('/addExtras')} > 35 | 36 |

Extras

37 |
38 |
39 | 40 | 41 |
42 | 43 |
44 |
45 | } 46 | 47 | export default AdminAddInfo; -------------------------------------------------------------------------------- /backend/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const bodyParser = require("body-parser"); 3 | const app = express(); 4 | const port = 3003; 5 | const db = require("./db"); 6 | const Auth = require("./src/middleware/Auth"); 7 | const User = require("./src/queries"); 8 | const dotenv = require("dotenv"); 9 | const cors = require("cors"); 10 | app.use(cors()); 11 | dotenv.config(); 12 | app.use(bodyParser.json()); 13 | 14 | app.use( 15 | bodyParser.urlencoded({ 16 | extended: true, 17 | }) 18 | ); 19 | 20 | app.get("/", (request, response) => { 21 | response.json({ info: "Node.js, Express, and Postgres API" }); 22 | }); 23 | app.post("/api/adminSignup", User.createAdmin); 24 | app.post("/api/adminLogin", User.adminLogin); 25 | app.post("/api/addEmployee", User.createEmployee); 26 | app.post("/api/deleteEmployee", User.deleteEmployee); 27 | app.get("/api/getAllEmployees", User.getAllEmployees); 28 | app.post("/api/employeeLogin", User.employeeLogin); 29 | app.get("/api/employeeDetails/:email", User.getEmployeeProfile); 30 | app.get("/api/getReports", User.generateReports); 31 | app.post("/api/updateEmployeeData", User.updateEmployeedata); 32 | app.post("/api/addDepartment", User.addDepartment); 33 | app.post("/api/addGrade", User.addGrade); 34 | app.post("/api/updateEmployeePassword", User.updateEmployeePassword); 35 | app.post("/api/updateAdminPassword", User.updateAdminPassword); 36 | app.get("/api/getDepartments", User.getDepartments); 37 | app.get("/api/getGrades", User.getGrades); 38 | app.post("/api/addOrganisation", User.addOrganisation); 39 | app.post("/api/markAttendance", User.markAttendance); 40 | app.post("/api/addExtras", User.addExtras); 41 | app.get("/api/getExtras", User.getExtras); 42 | app.post("/api/addIsgiven", User.addIsgiven); 43 | app.get("/api/getExtraForemp/:email", User.getExtraForemp); 44 | app.get("/api/getReports/:mail", User.generateReports); 45 | app.listen(port, () => { 46 | console.log(`App running on port ${port}.`); 47 | }); 48 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/ChangePassword.js: -------------------------------------------------------------------------------- 1 | 2 | import React, { useState } from "react"; 3 | import logo from "../Assets/Logo.png"; 4 | import "../StyleSheets/Welcome.css"; 5 | import "../StyleSheets/AdminOptions.css"; 6 | 7 | 8 | const ChangePassword=()=>{ 9 | const [password,setpass]=useState({old:'',new:''}) 10 | const [people, setPeople] = useState([]); 11 | 12 | const handleSubmit = (e) => { 13 | e.preventDefault(); 14 | setPeople([...people,password]) 15 | 16 | setpass({old:'',new:''}) 17 | }; 18 | 19 | const handleChange=(e)=>{ 20 | const name=e.target.name; 21 | const value=e.target.value; 22 | 23 | setpass({...password,[name]:value}) 24 | } 25 | return ( 26 | <> 27 |
28 |
29 |

Payroll Management System

30 |
31 | logo 32 |
33 |
34 |
35 | 36 | 44 |
45 |
46 | 47 | 55 |
56 | 57 | 58 |
59 | 60 |
61 | 62 | ); 63 | } 64 | 65 | export default ChangePassword; 66 | -------------------------------------------------------------------------------- /payroll-frontend/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 19 | 28 | React App 29 | 30 | 31 | 32 |
33 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AdminDashboard.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import Modal from "react-modal"; 6 | import { Redirect } from "react-router-dom"; 7 | import ReactDOM from "react-dom"; 8 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 9 | import { faPlus, faPen } from "@fortawesome/free-solid-svg-icons"; 10 | import { useHistory } from "react-router-dom"; 11 | 12 | const AdminDashboard = () => { 13 | const [showId, setShowid] = useState(0); 14 | const [adminModal, setAdminmodal] = useState(false); 15 | const [userModal, setUsermodal] = useState(false); 16 | // console.log("Value set to ", showId); 17 | let history = useHistory(); 18 | 19 | return ( 20 |
21 |
22 |

Payroll Management System

23 |
24 | logo 25 |
26 |
39 |
history.push("/adminAddInfo")} 42 | > 43 | 44 |

Add Info

45 |
46 |
history.push("/adminUpdateInfo")}> 48 | 49 |

Update Info

50 |
51 |
52 | 53 |
54 |
55 | ); 56 | }; 57 | const styles = { 58 | content: { 59 | // align:"center", 60 | // width: "20%", 61 | }, 62 | }; 63 | export default AdminDashboard; 64 | -------------------------------------------------------------------------------- /payroll-frontend/src/App.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BrowserRouter as Router, Route } from "react-router-dom"; 3 | import AdminLogin from "./Screens/AdminLogin"; 4 | import EmployeeLogin from "./Screens/EmployeeLogin"; 5 | import Welcome from "./Screens/Welcome"; 6 | import AdminDashboard from "./Screens/AdminDashboard"; 7 | import AdminAddInfo from "./Screens/AdminAddInfo"; 8 | import AdminUpdateInfo from "./Screens/AdminUpdateInfo"; 9 | import AddEmployee from "./Screens/AddEmployee"; 10 | import AddGrade from "./Screens/AddGrade"; 11 | import AddDep from "./Screens/AddDep"; 12 | import AddExtras from "./Screens/AddExtras"; 13 | import EmployeeDrawer from "./Screens/EmployeeDrawer"; 14 | import Reports from "./Screens/Reports"; 15 | import Attendance from "./Screens/Attendance"; 16 | import ResetPassword from "./Screens/ResetPassword"; 17 | import Profile from "./Screens/EmployeeProfile"; 18 | import UpdateDetails from "./Screens/UpdateDetails"; 19 | const App = () => { 20 | return ( 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 |
40 |
41 | ); 42 | }; 43 | export default App; 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gr07_PayrollManagementSystem 2 | 3 | - Trello Link For User Stories 4 | - https://trello.com/b/jhUf9Eb9/payroll-management-systemgr07 5 | 6 | ## Getting Started 7 | 8 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. 9 | ```bash 10 | git clone https://github.com/nandwalritik/PayrollManagement 11 | cd PayrollManagement 12 | ``` 13 | 14 | ## Requirements 15 | 16 | - Any operating system (i.e. Linux, Windows, MacOS X) 17 | - A little knowledge of React and Node.js . Don't worry if you are new to it, you just need knack to learn. 18 | 19 | ## Agile Documentation 20 | 21 | - Move to PayrollManagement/AgileDocumentation to look at:- 22 | - **UI Prototyping** 23 | - **Architecture Qualities** 24 | - **Estimation** 25 | - **High Level Domain Architecture** 26 | - **Software Requirement Analysis** 27 | - **Sprint Backlog** 28 | - **Use Case Diagram** 29 | - **User Stories** 30 | - **Website Workflow** 31 | 32 | ## Development Setup 33 | 34 | - Install node, npm. 35 | 36 | ## To start FrontEnd React Server 37 | ```bash 38 | cd PayrollManagement/payroll-frontend 39 | npm i 40 | npm start 41 | ``` 42 | 43 | ## To start Backend Server 44 | ```bash 45 | cd PayrollManagement/backend 46 | npm i 47 | nodemon index.js 48 | ``` 49 | 50 | ## To [Create User](https://blog.logrocket.com/nodejs-expressjs-postgresql-crud-rest-api-example/#:~:text=have%20superuser%20privileges.-,Creating%20a%20role%20in%20Postgres,-First%2C%20we%E2%80%99ll%20create) in Postgresql 51 | 52 | - create a role called **me** and give it a password of **password**. A role can function as a user or a group , so in this case, we’ll be using it as a user. 53 | - We want **me** to be able to create a database.So run the following :- 54 | ```bash 55 | ALTER ROLE me CREATEDB ; 56 | ``` 57 | - After that create a database named api 58 | ```bash 59 | CREATE DATABASE api ; 60 | ``` 61 | - For connecting postgres with **me**.Run : 62 | ```bash 63 | psql -d postgres -h localhost -U me 64 | ``` 65 | 66 | ## To Create Tables 67 | 68 | - Run the sql commands mentioned in PayrollManagement/commands/DDL.sql file. 69 | 70 | ## Authors 71 | 72 | - **Ritik Nandwal** 73 | - **Dhanshree Kulkarni** 74 | - **Nehal Jain** 75 | - **Mumal Kumari Rathore** 76 | 77 | ## License 78 | 79 | This project is licensed under the SGSITS. 80 | 81 | [![ForTheBadge built-by-developers](http://ForTheBadge.com/images/badges/built-by-developers.svg)] 82 | [![ForTheBadge built-with-love](http://ForTheBadge.com/images/badges/built-with-love.svg)] 83 | -------------------------------------------------------------------------------- /payroll-frontend/src/Assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /payroll-frontend/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `yarn start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `yarn test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `yarn build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `yarn eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `yarn build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/Reports.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import "../StyleSheets/Report.css"; 6 | import { useFormik } from "formik"; 7 | import { base_url } from "../baseUrl"; 8 | const Reports = (props) => { 9 | const initialValues = { 10 | transId: "", 11 | month: "", 12 | year: "", 13 | grossPay: "", 14 | incomeTax: "", 15 | PF: "", 16 | inHandsalary: "", 17 | }; 18 | const formik = useFormik({ 19 | initialValues, 20 | }); 21 | useEffect(() => { 22 | getReports(); 23 | }, []); 24 | const getReports = async () => { 25 | fetch(`${base_url}getReports/${props.location.state.email}`, { 26 | method: "GET", 27 | headers: { 28 | "Content-Type": "application/json", 29 | }, 30 | }) 31 | .then((res) => res.json()) 32 | .then((res) => { 33 | console.log(res); 34 | const data = res.data[0]; 35 | formik.setFieldValue("transId", data.transaction_id); 36 | formik.setFieldValue("month", data.month); 37 | formik.setFieldValue("year", data.year); 38 | formik.setFieldValue("grossPay", data.gross_pay); 39 | formik.setFieldValue("incomeTax", data.income_tax); 40 | formik.setFieldValue("PF", data.grade_pf); 41 | formik.setFieldValue( 42 | "inHandsalary", 43 | data.gross_pay - data.income_tax - data.grade_pf 44 | ); 45 | }) 46 | .catch((err) => { 47 | console.error(err); 48 | }); 49 | }; 50 | return ( 51 | <> 52 |
53 |
54 |

Payroll Management System

55 |
56 | logo 57 |
58 |
59 |
60 |
61 |
62 |
Transaction-id:
63 |
{formik.values.transId}
64 |
65 |
66 |
Month:
67 |
{formik.values.month}
68 |
69 |
70 |
Year:
71 |
{formik.values.year}
72 |
73 |
74 |
Employee Salary Breakdown
75 |
76 |
Gross Pay:
77 |
{formik.values.grossPay}
78 |
79 |
80 |
Income Tax:
81 |
{formik.values.incomeTax}
82 |
83 | 84 |
85 |
PF:
86 |
{formik.values.PF}
87 |
88 |
89 |
In-hand Salary:
90 |
{formik.values.inHandsalary}
91 |
92 |
93 |
94 |
95 | 96 | ); 97 | }; 98 | 99 | export default Reports; 100 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AdminUpdateInfo.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 6 | import { faTimes } from "@fortawesome/free-solid-svg-icons"; 7 | import { testData } from "../testData.js"; 8 | import AddEmployee from "./AddEmployee.js"; 9 | import { useHistory } from "react-router-dom"; 10 | import { base_url } from "../baseUrl"; 11 | //testData used for testing.It is to be replaced by employee's db 12 | 13 | const AdminUpdateInfo = () => { 14 | // const [search, setSearch] = useState(0); 15 | const [emp, setEmp] = useState([]); 16 | const [callUpdate, setCallUpdate] = useState(false); 17 | const history = useHistory(); 18 | const upDate = () => { 19 | setCallUpdate(true); 20 | document.getElementById("id01").style.display = "block"; 21 | }; 22 | 23 | const closeModal = () => { 24 | document.getElementById("id01").style.display = "none"; 25 | setCallUpdate(false); 26 | }; 27 | 28 | useEffect(() => { 29 | getAllEmployees(); 30 | }, []); 31 | const getAllEmployees = async () => { 32 | fetch(`${base_url}getAllEmployees`, { 33 | method: "GET", 34 | headers: { 35 | "Content-Type": "application/json", 36 | }, 37 | }) 38 | .then((res) => res.json()) 39 | .then((res) => { 40 | setEmp(res.data); 41 | }) 42 | .catch((err) => { 43 | console.error(err); 44 | }); 45 | }; 46 | const handleUpdate = (emp) => { 47 | history.push("/updateProfile", { email: emp.email }); 48 | }; 49 | const handleDelete = async (emp) => { 50 | console.log(emp) 51 | fetch(`${base_url}deleteEmployee`, { 52 | method: "POST", 53 | body: JSON.stringify({ 54 | email: emp.email, 55 | }), 56 | headers: { 57 | "Content-Type": "application/json", 58 | }, 59 | }) 60 | .then((res) => res.json()) 61 | .then((res) => { 62 | if (res.message === "User.Deleted") { 63 | getAllEmployees(); 64 | } 65 | }) 66 | .catch((err) => { 67 | console.error(err); 68 | }); 69 | }; 70 | return ( 71 |
72 |
73 |

Payroll Management System

74 |
75 | logo 76 |
77 |
78 | 79 | {emp.map((Emp) => ( 80 | 81 | 82 | 85 | 93 | 94 | ))} 95 |
{Emp.name} 83 | 84 | 86 | 92 |
96 |
97 |
98 |
99 | 100 | closeModal()} 103 | > 104 | 105 | 106 |
107 |
108 |
109 |
110 |
111 | ); 112 | }; 113 | 114 | export default AdminUpdateInfo; 115 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AddExtras.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import { useFormik } from "formik"; 6 | import { base_url } from "../baseUrl"; 7 | import Dialog from "@material-ui/core/Dialog"; 8 | import DialogActions from "@material-ui/core/DialogActions"; 9 | import DialogContent from "@material-ui/core/DialogContent"; 10 | import DialogContentText from "@material-ui/core/DialogContentText"; 11 | import DialogTitle from "@material-ui/core/DialogTitle"; 12 | import Button from "@material-ui/core/Button"; 13 | import {useHistory} from "react-router-dom" 14 | const AddExtras = () => { 15 | const history = useHistory(); 16 | const [open, setOpen] = useState(false); 17 | const [msg, setMessage] = useState(""); 18 | 19 | const handleClickOpen = () => { 20 | setOpen(true); 21 | }; 22 | 23 | const handleClose = () => { 24 | setOpen(false); 25 | history.goBack(); 26 | }; 27 | const initialValues = { 28 | ex_type: "", 29 | }; 30 | const onSubmit = async (values) => { 31 | console.log(values); 32 | const body = JSON.stringify(values); 33 | fetch(`${base_url}addExtras`, { 34 | method: "POST", 35 | body: body, 36 | headers: { 37 | "Content-Type": "application/json", 38 | }, 39 | }) 40 | .then((res) => res.json()) 41 | .then((res) => { 42 | if (res.message === "Extras added") { 43 | setMessage(res.message); 44 | handleClickOpen(); 45 | } 46 | }) 47 | .catch((err) => { 48 | console.error(err); 49 | }); 50 | }; 51 | const formik = useFormik({ 52 | initialValues, 53 | onSubmit, 54 | }); 55 | return ( 56 | <> 57 |
58 | 64 | {"Message"} 65 | 66 | 67 | {msg} 68 | 69 | 70 | 71 | 74 | 75 | 76 |
77 |
78 |
79 |

Payroll Management System

80 |
81 | logo 82 |
83 |
84 | {/*
85 | 86 | 94 |
*/} 95 |
96 | 97 | 105 |
106 | 107 | 108 |
109 |
110 | 111 | ); 112 | }; 113 | 114 | export default AddExtras; 115 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/EmployeeProfile.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import "../StyleSheets/Profile.css"; 6 | import { Redirect } from "react-router-dom"; 7 | import ReactDOM from "react-dom"; 8 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 9 | import { faFile, faPen, faUser } from "@fortawesome/free-solid-svg-icons"; 10 | import { useHistory } from "react-router-dom"; 11 | import { useFormik } from "formik"; 12 | import { base_url } from "../baseUrl"; 13 | import moment from "moment"; 14 | const EmployeeProfile = (props) => { 15 | let history = useHistory(); 16 | const initialValues = { 17 | name: "", 18 | dob: "", 19 | city: "", 20 | state: "", 21 | pincode: "", 22 | address: "", 23 | dept_id: "", 24 | grade_id: "", 25 | org_name: "SGSITS", 26 | doj: "", 27 | email: props.location.state.email, 28 | years_of_service: "", 29 | }; 30 | const formik = useFormik({ 31 | initialValues, 32 | }); 33 | useEffect(() => { 34 | getDetails(); 35 | }, []); 36 | const getDetails = async () => { 37 | // console.log(props.location.state.email); 38 | fetch(`${base_url}employeeDetails/${props.location.state.email}`, { 39 | method: "GET", 40 | headers: { 41 | "Content-Type": "application/json", 42 | }, 43 | }) 44 | .then((res) => res.json()) 45 | .then((res) => { 46 | formik.setFieldValue("name", res.data[0].name); 47 | formik.setFieldValue( 48 | "dob", 49 | moment(res.data[0].dob.slice(0, 10), "YYYY-MM-DD").format( 50 | "YYYY-MM-DD" 51 | ) 52 | ); 53 | formik.setFieldValue("city", res.data[0].city); 54 | formik.setFieldValue("state", res.data[0].state); 55 | formik.setFieldValue("pincode", res.data[0].pincode); 56 | formik.setFieldValue("address", res.data[0].address); 57 | formik.setFieldValue( 58 | "doj", 59 | moment(res.data[0].doj.slice(0, 4), "YYYY-MM-DD").format( 60 | "YYYY" 61 | ) 62 | ); 63 | formik.setFieldValue("dept_id", res.data[0].dept_id); 64 | formik.setFieldValue("grade_id", res.data[0].grade_id); 65 | }) 66 | .catch((err) => { 67 | console.error(err); 68 | }); 69 | }; 70 | const d = new Date(); 71 | console.log(formik.values.doj) 72 | return ( 73 | <> 74 |
75 |
76 |

Payroll Management System

77 |
78 | logo 79 |
80 |
81 |
82 | {/*
83 |
Employee-id:
84 |
01
85 |
*/} 86 |
87 |
Name:
88 |
{formik.values.name}
89 |
90 |
91 |
Date of Birth:
92 |
{formik.values.dob}
93 |
94 |
95 |
Date of joining:
96 |
{formik.values.doj}
97 |
98 |
99 |
Address:
100 |
{formik.values.address}
101 |
102 |
103 |
Years of service:
104 |
{d.getFullYear()-formik.values.doj}
105 |
106 |
107 |
108 |
109 | 110 | ); 111 | }; 112 | 113 | export default EmployeeProfile; 114 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AddDep.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import { useFormik } from "formik"; 6 | import { base_url } from "../baseUrl"; 7 | import { useHistory } from "react-router-dom"; 8 | import Dialog from "@material-ui/core/Dialog"; 9 | import DialogActions from "@material-ui/core/DialogActions"; 10 | import DialogContent from "@material-ui/core/DialogContent"; 11 | import DialogContentText from "@material-ui/core/DialogContentText"; 12 | import DialogTitle from "@material-ui/core/DialogTitle"; 13 | import Button from "@material-ui/core/Button"; 14 | 15 | const AddDep = () => { 16 | const [open, setOpen] = useState(false); 17 | const [msg, setMessage] = useState(""); 18 | const history = useHistory(); 19 | const handleClickOpen = () => { 20 | setOpen(true); 21 | }; 22 | 23 | const handleClose = () => { 24 | setOpen(false); 25 | history.goBack(); 26 | }; 27 | const initialValues = { 28 | dept_name: "", 29 | org_name: "", 30 | }; 31 | const onSubmit = async (values) => { 32 | console.log(values); 33 | const body = JSON.stringify(values); 34 | fetch(`${base_url}addDepartment`, { 35 | method: "POST", 36 | body: body, 37 | headers: { 38 | "Content-Type": "application/json", 39 | }, 40 | }) 41 | .then((res) => res.json()) 42 | .then((res) => { 43 | console.log(res); 44 | setMessage(res.message); 45 | handleClickOpen(); 46 | }) 47 | .catch((err) => { 48 | console.error(err); 49 | }); 50 | }; 51 | const formik = useFormik({ 52 | initialValues, 53 | onSubmit, 54 | }); 55 | return ( 56 | <> 57 |
58 |
59 | 65 | {"Message"} 66 | 67 | 68 | {msg} 69 | 70 | 71 | 72 | 75 | 76 | 77 |
78 |
79 |

Payroll Management System

80 |
81 | logo 82 |
83 |
84 | {/*
85 | 86 | 94 |
*/} 95 |
96 | 97 | 105 |
106 | 107 |
108 | 109 | 117 |
118 | 119 |
120 |
121 | 122 | ); 123 | }; 124 | 125 | export default AddDep; 126 | -------------------------------------------------------------------------------- /backend/commands/DDL.sql: -------------------------------------------------------------------------------- 1 | create table admin( 2 | admin_id varchar(255), 3 | username varchar(255), 4 | email varchar(255), 5 | password varchar(255), 6 | primary key(email) 7 | ); 8 | create table organisation( 9 | org_name varchar(255), 10 | email varchar(255), 11 | location varchar(255), 12 | contact_number varchar(255), 13 | paid_leave_limit int, 14 | encashed_leave_limit int, 15 | primary key (org_name), 16 | foreign key (email) references admin on delete 17 | set null 18 | ); 19 | create table department( 20 | dept_id varchar(255), 21 | dept_name varchar(255), 22 | org_name varchar(255), 23 | primary key (dept_id), 24 | foreign key (org_name) references organisation on delete 25 | set null 26 | ); 27 | create table gradepay( 28 | grade_id varchar(255), 29 | grade_name varchar(255), 30 | basic_pay int, 31 | grade_pf varchar(255), 32 | grade_bonus int, 33 | grade_ta varchar(255), 34 | grade_da varchar(255), 35 | primary key (grade_id) 36 | ); 37 | create table employee( 38 | present int, 39 | paid_leave_taken int, 40 | encashed_leave_this_month int, 41 | encashed_leave_till_date int, 42 | e_id varchar(255), 43 | doj date, 44 | name varchar(255), 45 | dob date, 46 | address varchar(255), 47 | city varchar(255), 48 | state varchar(255), 49 | pincode numeric(6, 0), 50 | email varchar(255) unique, 51 | password varchar(255), 52 | org_name varchar(255), 53 | dept_id varchar(255), 54 | grade_id varchar(255), 55 | primary key(email), 56 | foreign key (org_name) references organisation on delete 57 | set null, 58 | foreign key (dept_id) references department on delete 59 | set null, 60 | foreign key (grade_id) references gradepay on delete 61 | set null 62 | ); 63 | create table is_given( 64 | ex_id varchar(255), 65 | amount int, 66 | email varchar(255), 67 | primary key (ex_id, email), 68 | foreign key (email) references employee on delete 69 | cascade, 70 | foreign key (ex_id) references extras on delete 71 | cascade 72 | ); 73 | create table extras( 74 | ex_type varchar(255), 75 | ex_id varchar(255), 76 | primary key (ex_id) 77 | ); 78 | create table payroll( 79 | transaction_id SERIAL, 80 | month int, 81 | year int, 82 | gross_pay int, 83 | income_tax int, 84 | emp_mail varchar(255), 85 | admin_mail varchar(255), 86 | primary key (transaction_id), 87 | foreign key (emp_mail) references employee(email) on delete 88 | set null, 89 | foreign key (admin_mail) references admin(email) on delete 90 | set null 91 | ); 92 | create function record_attendance() returns trigger as $record_attendance$ BEGIN if date_part('day', current_date) = 1 then with result as ( 93 | select case 94 | when sum(amount) is null then gross 95 | else gross + sum(amount) 96 | end as gross_pay, 97 | income_tax, 98 | email, 99 | admin_mail 100 | from ( 101 | select basic_pay + grade_ta + grade_da + grade_bonus -((paid_leave_taken - paid_leave_limit) * 10) as gross, 102 | 0.12 * basic_pay as income_tax, 103 | email, 104 | admin_mail, 105 | is_given.amount as amount 106 | from ( 107 | ( 108 | select email, 109 | admin_mail, 110 | grade_id, 111 | paid_leave_taken, 112 | paid_leave_limit 113 | from employee 114 | natural join organisation 115 | where email = new.email 116 | ) as result_1 117 | natural join gradepay 118 | ) as result_2 119 | left outer join is_given on result_2.email = is_given.emp_mail 120 | ) as result_3 121 | group by gross, 122 | income_tax, 123 | email, 124 | admin_mail 125 | ) 126 | insert into payroll( 127 | month, 128 | year, 129 | gross_pay, 130 | income_tax, 131 | emp_mail, 132 | admin_mail 133 | ) 134 | values ( 135 | date_part('month', current_date), 136 | date_part('year', current_date), 137 | ( 138 | select gross_pay 139 | from result 140 | ), 141 | ( 142 | select income_tax 143 | from result 144 | ), 145 | ( 146 | select email 147 | from result 148 | ), 149 | ( 150 | select admin_mail 151 | from result 152 | ) 153 | ); 154 | else if new.present = 1 then new.present := old.present + 1; 155 | new.encashed_leave_this_month := old.encashed_leave_this_month; 156 | new.paid_leave_taken := old.paid_leave_taken; 157 | end if; 158 | if new.encashed_leave_this_month = 1 then new.encashed_leave_this_month := old.encashed_leave_this_month + 1; 159 | new.present := old.present; 160 | new.paid_leave_taken := old.paid_leave_taken; 161 | end if; 162 | if new.paid_leave_taken = 1 then new.paid_leave_taken := old.paid_leave_taken + 1; 163 | new.encashed_leave_this_month := old.encashed_leave_this_month; 164 | new.present := old.present; 165 | end if; 166 | end if; 167 | return new; 168 | end; 169 | $record_attendance$ language plpgsql; 170 | create trigger record_attendance before 171 | update on employee for each row execute procedure record_attendance(); 172 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/EmployeeDrawer.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import Modal from "react-modal"; 6 | import { Redirect } from "react-router-dom"; 7 | import ReactDOM from "react-dom"; 8 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; 9 | import { faFile, faPen, faUser } from "@fortawesome/free-solid-svg-icons"; 10 | import { useHistory } from "react-router-dom"; 11 | import Button from "@material-ui/core/Button"; 12 | import Avatar from "@material-ui/core/Avatar"; 13 | import List from "@material-ui/core/List"; 14 | import ListItem from "@material-ui/core/ListItem"; 15 | import ListItemAvatar from "@material-ui/core/ListItemAvatar"; 16 | import ListItemText from "@material-ui/core/ListItemText"; 17 | import DialogTitle from "@material-ui/core/DialogTitle"; 18 | import Dialog from "@material-ui/core/Dialog"; 19 | import { useFormik } from "formik"; 20 | import { base_url } from "../baseUrl"; 21 | const EmployeeDrawer = (props) => { 22 | const [showId, setShowid] = useState(0); 23 | const [adminModal, setAdminmodal] = useState(false); 24 | const [userModal, setUsermodal] = useState(false); 25 | const [open, setOpen] = useState(false); 26 | const handleOpen = () => { 27 | setOpen(true); 28 | }; 29 | const handleClose = () => { 30 | setOpen(false); 31 | }; 32 | const history = useHistory(); 33 | 34 | const onSubmit = async (values) => { 35 | handleClose(); 36 | console.log(values); 37 | const body = JSON.stringify(values); 38 | fetch(`${base_url}markAttendance`, { 39 | method: "POST", 40 | body: body, 41 | headers: { 42 | "Content-Type": "application/json", 43 | }, 44 | }) 45 | .then((res) => res.json()) 46 | .then((res) => { 47 | console.log(res); 48 | }) 49 | .catch((err) => { 50 | console.error(err); 51 | }); 52 | }; 53 | const initialValues = { 54 | present: 0, 55 | paid_leave_taken: 0, 56 | encashed_leave_this_month: 0, 57 | email: props.location.state.email, 58 | }; 59 | const formik = useFormik({ 60 | initialValues, 61 | onSubmit, 62 | }); 63 | return ( 64 |
65 |
66 |

Payroll Management System

67 |
68 | logo 69 |
70 |
71 | 76 | Mark Attendance 77 | 78 | { 81 | formik.setFieldValue("present", 1); 82 | formik.handleSubmit(); 83 | }} 84 | > 85 | Present 86 | 87 | { 90 | formik.setFieldValue("paid_leave_taken", 1); 91 | formik.handleSubmit(); 92 | }} 93 | > 94 | Paid Leave Taken 95 | 96 | { 99 | formik.setFieldValue("encashed_leave_this_month", 1); 100 | formik.handleSubmit(); 101 | }} 102 | > 103 | Encashed Leave Taken 104 | 105 | 106 | 107 |
108 |
119 |
122 | history.push("/reports", { email: props.location.state.email }) 123 | } 124 | > 125 | 126 |

Generate Report

127 |
128 |
131 | history.push("/profile", { email: props.location.state.email }) 132 | } 133 | > 134 | 135 |

My Profile

136 |
137 |
138 | 139 |

Mark Attendance

140 |
141 |
142 |
143 | ); 144 | }; 145 | const styles = { 146 | content: { 147 | // align:"center", 148 | // width: "20%", 149 | }, 150 | }; 151 | export default EmployeeDrawer; 152 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AddGrade.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import "../StyleSheets/AdminOptions.css"; 5 | import { useFormik } from "formik"; 6 | import { base_url } from "../baseUrl"; 7 | import { useHistory } from "react-router-dom"; 8 | import Dialog from "@material-ui/core/Dialog"; 9 | import DialogActions from "@material-ui/core/DialogActions"; 10 | import DialogContent from "@material-ui/core/DialogContent"; 11 | import DialogContentText from "@material-ui/core/DialogContentText"; 12 | import DialogTitle from "@material-ui/core/DialogTitle"; 13 | import Button from "@material-ui/core/Button"; 14 | 15 | const AddGrade = () => { 16 | const [open, setOpen] = useState(false); 17 | const [msg, setMessage] = useState(""); 18 | const history = useHistory(); 19 | const handleClickOpen = () => { 20 | setOpen(true); 21 | }; 22 | 23 | const handleClose = () => { 24 | setOpen(false); 25 | history.goBack(); 26 | }; 27 | const initialValues = { 28 | grade_name: "", 29 | grade_pay: "", 30 | grade_pf: "", 31 | grade_bonus: "", 32 | grade_ta: "", 33 | grade_da: "", 34 | }; 35 | const onSubmit = async (values) => { 36 | console.log(values); 37 | const body = JSON.stringify(values); 38 | 39 | fetch(`${base_url}addGrade`, { 40 | method: "POST", 41 | body: body, 42 | headers: { 43 | "Content-Type": "application/json", 44 | }, 45 | }) 46 | .then((res) => res.json()) 47 | .then((res) => { 48 | console.log(res); 49 | setMessage(res.message); 50 | handleClickOpen(); 51 | }) 52 | .catch((err) => { 53 | console.error(err); 54 | }); 55 | }; 56 | const formik = useFormik({ 57 | initialValues, 58 | onSubmit, 59 | }); 60 | return ( 61 | <> 62 |
63 | 69 | {"Message"} 70 | 71 | 72 | {msg} 73 | 74 | 75 | 76 | 79 | 80 | 81 |
82 |
83 |
84 |

Payroll Management System

85 |
86 | logo 87 |
88 |
89 |
90 | 91 | 99 |
100 |
101 | 102 | 110 |
111 |
112 | 113 | 121 |
122 |
123 | 124 | 132 |
133 |
134 | 135 | 143 |
144 |
145 | 146 | 154 |
155 | 156 |
157 |
158 | 159 | ); 160 | }; 161 | 162 | export default AddGrade; 163 | -------------------------------------------------------------------------------- /payroll-frontend/src/StyleSheets/Welcome.css: -------------------------------------------------------------------------------- 1 | .App { 2 | padding: 2em 3em 0; 3 | background: url("../Assets/squares.png") no-repeat; 4 | background-position: 3em 9em; 5 | min-height: 80vh; 6 | font-family: "Lato", sans-serif; 7 | position: relative; 8 | } 9 | 10 | header { 11 | margin: 0 4em 2em; 12 | position: relative; 13 | } 14 | 15 | header h1 { 16 | font-weight: normal; 17 | } 18 | 19 | header hr { 20 | background-color: #8ee3e3; 21 | border: none; 22 | height: 2px; 23 | } 24 | 25 | header img { 26 | position: absolute; 27 | right: 4em; 28 | bottom: -2.5em; 29 | height: 6em; 30 | width: 6em; 31 | } 32 | 33 | .Login { 34 | margin-top: 10em; 35 | } 36 | 37 | .Login-button { 38 | display: block; 39 | text-align: center; 40 | margin: 2em auto; 41 | width: 15em; 42 | background-color: #fff; 43 | border: 2px solid #8ee3e3; 44 | border-radius: 1em; 45 | padding: 1em 0; 46 | letter-spacing: 0.125em; 47 | word-spacing: 0.15em; 48 | font-size: 1.1em; 49 | color: #444; 50 | } 51 | 52 | .Login-button:hover { 53 | border-color: rgb(24, 160, 248); 54 | } 55 | 56 | .Login-button:focus { 57 | outline: none; 58 | } 59 | 60 | .Login-button .svg-inline--fa { 61 | width: 3rem; 62 | height: 3rem; 63 | fill: #8ee3e3; 64 | } 65 | 66 | .Film { 67 | width: 100vw; 68 | height: 100vh; 69 | position: absolute; 70 | left: 0; 71 | top: 0; 72 | background-color: rgba(40, 40, 40, 0.5); 73 | z-index: 2; 74 | display: none; 75 | } 76 | 77 | .Login-form { 78 | text-align: center; 79 | color: #444; 80 | background-color: #fff; 81 | border: 2px solid #18a0f8; 82 | border-radius: 1em; 83 | width: 50vw; 84 | margin: 0 auto; 85 | padding: 2em 0; 86 | z-index: 4; 87 | position: absolute; 88 | top: 12vh; 89 | left: 25vw; 90 | display: none; 91 | } 92 | 93 | .Login-form .Back { 94 | position: relative; 95 | left: 22vw; 96 | outline: none; 97 | border: none; 98 | background-color: #fff; 99 | font-size: 1.7em; 100 | color: #8ee3e3; 101 | } 102 | 103 | .Login-form .Back:hover { 104 | color: #18a0f8; 105 | } 106 | 107 | .Login-form h1 { 108 | font-weight: 600; 109 | word-spacing: 0.2em; 110 | letter-spacing: 0.05em; 111 | margin-bottom: 2em; 112 | } 113 | 114 | .Login-form input { 115 | display: block; 116 | margin: 0 auto 3em; 117 | border: 2px solid #8ee3e3; 118 | border-radius: 2em; 119 | padding: 0.7em 1em; 120 | } 121 | 122 | .Login-form input:hover { 123 | border-color: #18a0f8; 124 | } 125 | 126 | .Login-form input:focus { 127 | outline: none; 128 | } 129 | 130 | .Input-field { 131 | width: 40em; 132 | height: 1.5em; 133 | } 134 | 135 | .Login-form input[type="submit"] { 136 | width: 8em; 137 | height: 2.5em; 138 | font-size: 1.1em; 139 | background-color: #fff; 140 | color: #444; 141 | } 142 | 143 | .Error { 144 | background-color: red; 145 | display: none; 146 | width: 15em; 147 | margin-left: 5em; 148 | padding: 0.25em 0; 149 | font-size: 0.75em; 150 | color: white; 151 | position: relative; 152 | top: -3em; 153 | border-radius: 0.6em; 154 | } 155 | 156 | @media (max-width: 1024px) { 157 | .Login-form { 158 | top: 20vh; 159 | } 160 | .Input-field { 161 | width: 30em; 162 | } 163 | } 164 | 165 | @media (max-width: 768px) { 166 | .App { 167 | padding: 2em 2em 0; 168 | } 169 | header h1 { 170 | font-size: 1.75em; 171 | } 172 | header img { 173 | right: 2.5em; 174 | bottom: -2em; 175 | width: 5em; 176 | height: 5em; 177 | } 178 | .Login-form .Back { 179 | left: 20vw; 180 | } 181 | .Login-form h1 { 182 | font-size: 1.75em; 183 | } 184 | .Input-field { 185 | width: 20em; 186 | } 187 | .Login-form input[type="submit"] { 188 | font-size: 1em; 189 | } 190 | } 191 | 192 | @media (max-width: 425px) { 193 | .App { 194 | padding: 0.5em 0; 195 | background-size: 20% 20%; 196 | background-position: 1em 5em; 197 | } 198 | header { 199 | margin: 0 2em; 200 | } 201 | header h1 { 202 | font-size: 1.25em; 203 | } 204 | header img { 205 | right: 2em; 206 | bottom: -0.75em; 207 | width: 2em; 208 | height: 2em; 209 | } 210 | .Login { 211 | margin-top: 5em; 212 | } 213 | .Login-button { 214 | width: 12.5em; 215 | font-size: 1em; 216 | margin-top: 0; 217 | } 218 | .Login-form { 219 | width: 80vw; 220 | left: 10vw; 221 | } 222 | .Login-form .Back { 223 | left: 32vw; 224 | top: -1.5vh; 225 | } 226 | .Login-form h1 { 227 | font-size: 1.6em; 228 | } 229 | .Login-form input[type="submit"] { 230 | font-size: 0.8em; 231 | } 232 | } 233 | 234 | @media (max-width: 375px) { 235 | .App { 236 | padding: 1.5em 0; 237 | background-position: 1em 7em; 238 | } 239 | header img { 240 | right: 1em; 241 | } 242 | .Login-button { 243 | width: 11em; 244 | font-size: 1em; 245 | } 246 | .Login-form { 247 | width: 95vw; 248 | left: 2.5vw; 249 | } 250 | .Login-form .Back { 251 | left: 40vw; 252 | } 253 | } 254 | 255 | @media (max-width: 320px) { 256 | .App { 257 | background-size: 20% 17%; 258 | } 259 | header { 260 | margin: 0 1em; 261 | } 262 | header img { 263 | right: 0.2em; 264 | } 265 | .Login { 266 | margin-top: 3.5em; 267 | } 268 | .Login-button { 269 | width: 9em; 270 | font-size: 0.75em; 271 | } 272 | .Login-form { 273 | padding: 0.5em 0; 274 | width: 98vw; 275 | left: 0.5vw; 276 | } 277 | .Login-form .Back { 278 | top: 1vh; 279 | } 280 | .Login-form input[type="submit"] { 281 | margin-bottom: 1em; 282 | } 283 | } 284 | 285 | -------------------------------------------------------------------------------- /payroll-frontend/src/StyleSheets/AdminOptions.css: -------------------------------------------------------------------------------- 1 | /* 2 | =============== 3 | Variables 4 | =============== 5 | */ 6 | 7 | :root { 8 | /* dark shades of primary color*/ 9 | --clr-primary-1: hsl(205, 86%, 17%); 10 | --clr-primary-2: hsl(205, 77%, 27%); 11 | --clr-primary-3: hsl(205, 72%, 37%); 12 | --clr-primary-4: hsl(205, 63%, 48%); 13 | /* primary/main color */ 14 | --clr-primary-5: hsl(205, 78%, 60%); 15 | /* lighter shades of primary color */ 16 | --clr-primary-6: hsl(205, 89%, 70%); 17 | --clr-primary-7: hsl(205, 90%, 76%); 18 | --clr-primary-8: hsl(205, 86%, 81%); 19 | --clr-primary-9: hsl(205, 90%, 88%); 20 | --clr-primary-10: hsl(205, 100%, 96%); 21 | /* darkest grey - used for headings */ 22 | --clr-grey-1: hsl(209, 61%, 16%); 23 | --clr-grey-2: hsl(211, 39%, 23%); 24 | --clr-grey-3: hsl(209, 34%, 30%); 25 | --clr-grey-4: hsl(209, 28%, 39%); 26 | /* grey used for paragraphs */ 27 | --clr-grey-5: hsl(210, 22%, 49%); 28 | --clr-grey-6: hsl(209, 23%, 60%); 29 | --clr-grey-7: hsl(211, 27%, 70%); 30 | --clr-grey-8: hsl(210, 31%, 80%); 31 | --clr-grey-9: hsl(212, 33%, 89%); 32 | --clr-grey-10: hsl(210, 36%, 96%); 33 | --clr-white: #fff; 34 | --clr-red-dark: hsl(360, 67%, 44%); 35 | --clr-red-light: hsl(360, 71%, 66%); 36 | --clr-green-dark: hsl(125, 67%, 44%); 37 | --clr-green-light: hsl(125, 71%, 66%); 38 | --clr-black: #222; 39 | --transition: all 0.3s linear; 40 | --spacing: 0.1rem; 41 | --radius: 0.25rem; 42 | --light-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); 43 | --dark-shadow: 0 5px 15px rgba(0, 0, 0, 0.4); 44 | --max-width: 1170px; 45 | --fixed-width: 450px; 46 | --clr-orange-1: hsl(12, 83%, 98%); 47 | --clr-orange-2: hsl(14, 91%, 95%); 48 | --clr-orange-3: hsl(12, 89%, 89%); 49 | --clr-orange-4: hsl(13, 87%, 82%); 50 | --clr-orange-5: hsl(13, 88%, 68%); 51 | --clr-orange-6: hsl(13, 88%, 55%); 52 | --clr-orange-7: hsl(13, 74%, 49%); 53 | --clr-orange-8: hsl(13, 74%, 33%); 54 | --clr-orange-9: hsl(13, 73%, 25%); 55 | --clr-orange-10: hsl(13, 73%, 16%); 56 | } 57 | 58 | /* Styling for forms */ 59 | 60 | .form { 61 | background: var(--clr-grey-10); 62 | max-width: var(--fixed-width); 63 | margin: 0 auto; 64 | margin-bottom: 4rem; 65 | padding: 1rem 2rem; 66 | border-radius: var(--radius); 67 | } 68 | .form input { 69 | background: var(--clr-grey-9); 70 | border-color: transparent; 71 | border-radius: var(--radius); 72 | padding: 0.25rem 0.5rem; 73 | } 74 | .form-control { 75 | margin: 0.5rem 0; 76 | display: grid; 77 | grid-template-columns: 100px 1fr; 78 | align-items: center; 79 | } 80 | .form button { 81 | display: inline-block; 82 | text-align: center; 83 | background: rgb(24, 160, 248); 84 | color: var(--clr-white); 85 | padding: 0.25rem 0.75rem; 86 | border-radius: var(--radius); 87 | border-color: transparent; 88 | text-transform: capitalize; 89 | font-size: 1rem; 90 | letter-spacing: var(--spacing); 91 | margin-top: 2rem; 92 | margin-left: 0.5rem; 93 | margin-right: 0.5rem; 94 | cursor: pointer; 95 | transition: var(--transition); 96 | } 97 | .form button:hover { 98 | color: #444; 99 | } 100 | 101 | /* class for grouping inputs of same type */ 102 | .grouping { 103 | margin-top: 3rem; 104 | margin-bottom: 3em; 105 | } 106 | 107 | /* search-bar */ 108 | .search { 109 | margin: 0 auto; 110 | max-width: var(--fixed-width); 111 | display: grid; 112 | align-items: center; 113 | } 114 | 115 | .search h4 { 116 | font-weight: 50; 117 | } 118 | 119 | .search-container button { 120 | padding: 6px 10px; 121 | margin-top: 8px; 122 | margin-right: 16px; 123 | background: #ddd; 124 | font-size: 18px; 125 | border: none; 126 | cursor: pointer; 127 | } 128 | 129 | .search-container button:hover { 130 | background: #ccc; 131 | } 132 | 133 | .search-container input { 134 | padding: 6px; 135 | margin-top: 8px; 136 | font-size: 17px; 137 | border: #8ee3e3 solid 0.25px; 138 | } 139 | 140 | .item { 141 | max-width: var(--fixed-width); 142 | margin: 0 auto; 143 | background: var(--clr-grey-10); 144 | padding: 1rem 2rem; 145 | border-radius: var(--radius); 146 | margin-top: 1rem; 147 | } 148 | 149 | .item .btn { 150 | display: inline; 151 | border: 0.1rem solid black; 152 | padding: 1rem; 153 | float: right; 154 | margin: auto 0.2rem; 155 | } 156 | 157 | .w3-container { 158 | content: ""; 159 | display: table; 160 | clear: both; 161 | width: 30rem; 162 | margin: 0 auto; 163 | } 164 | .w3-bordered tr { 165 | border-bottom: 1px solid #ddd; 166 | } 167 | .w3-table { 168 | border-collapse: collapse; 169 | border-spacing: 0; 170 | width: 100%; 171 | display: table; 172 | } 173 | .w3-table tr td { 174 | padding: 0.5rem; 175 | } 176 | .w3-table tr td button { 177 | background-color: #4caf50; /* Green */ 178 | border: none; 179 | color: white; 180 | padding: 10px 25px; 181 | text-align: center; 182 | text-decoration: none; 183 | display: inline-block; 184 | font-size: 16px; 185 | margin: 4px 2px; 186 | cursor: pointer; 187 | border-radius: var(--radius); 188 | } 189 | .w3-modal { 190 | z-index: 3; 191 | display: none; 192 | padding-top: 100px; 193 | position: fixed; 194 | left: 0; 195 | top: 0; 196 | width: 100%; 197 | height: 100%; 198 | overflow: scroll; 199 | background-color: rgb(0, 0, 0); 200 | background-color: rgba(0, 0, 0, 0.4); 201 | } 202 | .w3-modal-content { 203 | margin: auto; 204 | background-color: #fff; 205 | position: relative; 206 | padding: 0; 207 | outline: 0; 208 | width: 600px; 209 | } 210 | .w3-display-topright { 211 | position: absolute; 212 | right: 0; 213 | top: 0; 214 | } 215 | .w3-button { 216 | border: none; 217 | display: inline-block; 218 | padding: 8px 16px; 219 | vertical-align: middle; 220 | overflow: hidden; 221 | text-decoration: none; 222 | color: inherit; 223 | background-color: inherit; 224 | text-align: center; 225 | cursor: pointer; 226 | white-space: nowrap; 227 | } 228 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/ResetPassword.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import Avatar from "@material-ui/core/Avatar"; 5 | import Button from "@material-ui/core/Button"; 6 | import CssBaseline from "@material-ui/core/CssBaseline"; 7 | import TextField from "@material-ui/core/TextField"; 8 | import FormControlLabel from "@material-ui/core/FormControlLabel"; 9 | import Checkbox from "@material-ui/core/Checkbox"; 10 | import Link from "@material-ui/core/Link"; 11 | import Grid from "@material-ui/core/Grid"; 12 | import Box from "@material-ui/core/Box"; 13 | import { useHistory } from "react-router-dom"; 14 | 15 | import AccountCircleIcon from "@material-ui/icons/AccountCircle"; 16 | import Typography from "@material-ui/core/Typography"; 17 | import { makeStyles } from "@material-ui/core/styles"; 18 | import Container from "@material-ui/core/Container"; 19 | import SupervisorAccountIcon from "@material-ui/icons/SupervisorAccount"; 20 | import Dialog from "@material-ui/core/Dialog"; 21 | import DialogActions from "@material-ui/core/DialogActions"; 22 | import DialogContent from "@material-ui/core/DialogContent"; 23 | import DialogContentText from "@material-ui/core/DialogContentText"; 24 | import DialogTitle from "@material-ui/core/DialogTitle"; 25 | 26 | import LockIcon from "@material-ui/icons/Lock"; 27 | import { base_url } from "../baseUrl"; 28 | function Copyright() { 29 | return ( 30 | 31 | {"Copyright © "} 32 | 33 | Your Website 34 | {" "} 35 | {new Date().getFullYear()} 36 | {"."} 37 | 38 | ); 39 | } 40 | 41 | const useStyles = makeStyles((theme) => ({ 42 | paper: { 43 | marginTop: theme.spacing(8), 44 | display: "flex", 45 | flexDirection: "column", 46 | alignItems: "center", 47 | }, 48 | avatar: { 49 | margin: theme.spacing(1), 50 | backgroundColor: "#707070", 51 | }, 52 | form: { 53 | width: "100%", // Fix IE 11 issue. 54 | marginTop: theme.spacing(1), 55 | }, 56 | submit: { 57 | margin: theme.spacing(3, 0, 2), 58 | }, 59 | })); 60 | 61 | const ResetPassword = (props) => { 62 | // console.log("Thsi is props ",props.location.state) 63 | const classes = useStyles(); 64 | const [email, setEmail] = useState(""); 65 | const [password, setPassword] = useState(""); 66 | const history = useHistory(); 67 | const [open, setOpen] = useState(false); 68 | const [msg, setMessage] = useState(""); 69 | 70 | const handleClickOpen = () => { 71 | setOpen(true); 72 | }; 73 | 74 | const handleClose = () => { 75 | setOpen(false); 76 | history.goBack(); 77 | }; 78 | const body = JSON.stringify({ 79 | email: email, 80 | password: password, 81 | }); 82 | const handleSubmit = async (e) => { 83 | e.preventDefault(); 84 | fetch( 85 | props.location.state.text === "admin" 86 | ? `${base_url}updateAdminPassword` 87 | : `${base_url}updateEmployeePassword`, 88 | { 89 | method: "POST", 90 | body: body, 91 | headers: { 92 | "Content-Type": "application/json", 93 | }, 94 | } 95 | ) 96 | .then((res) => res.json()) 97 | .then((res) => { 98 | console.log(res); 99 | handleClickOpen(); 100 | setMessage(res.message); 101 | }) 102 | .catch((err) => { 103 | console.log(err); 104 | }); 105 | }; 106 | 107 | return ( 108 |
109 |
110 | 116 | {"Message"} 117 | 118 | 119 | {msg} 120 | 121 | 122 | 123 | {/* */} 126 | 129 | 130 | 131 |
132 |
133 |

Payroll Management System

134 |
135 | logo 136 |
137 | 138 | 139 |
140 | 141 | 142 | 143 | 144 | Reset Password {props.location.state.text.toUpperCase()} 145 | 146 |
147 | { 159 | setEmail(event.target.value); 160 | }} 161 | /> 162 | { 174 | setPassword(event.target.value); 175 | }} 176 | /> 177 | 178 | 190 | 191 |
192 | {/* */} 193 |
194 |
195 | ); 196 | }; 197 | 198 | export default ResetPassword; 199 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/EmployeeLogin.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import Avatar from "@material-ui/core/Avatar"; 5 | import Button from "@material-ui/core/Button"; 6 | import CssBaseline from "@material-ui/core/CssBaseline"; 7 | import TextField from "@material-ui/core/TextField"; 8 | import FormControlLabel from "@material-ui/core/FormControlLabel"; 9 | import Checkbox from "@material-ui/core/Checkbox"; 10 | import Link from "@material-ui/core/Link"; 11 | import Grid from "@material-ui/core/Grid"; 12 | import Box from "@material-ui/core/Box"; 13 | import { useHistory } from "react-router-dom"; 14 | 15 | import AccountCircleIcon from "@material-ui/icons/AccountCircle"; 16 | import Typography from "@material-ui/core/Typography"; 17 | import { makeStyles } from "@material-ui/core/styles"; 18 | import Container from "@material-ui/core/Container"; 19 | import SupervisorAccountIcon from "@material-ui/icons/SupervisorAccount"; 20 | import Dialog from "@material-ui/core/Dialog"; 21 | import DialogActions from "@material-ui/core/DialogActions"; 22 | import DialogContent from "@material-ui/core/DialogContent"; 23 | import DialogContentText from "@material-ui/core/DialogContentText"; 24 | import DialogTitle from "@material-ui/core/DialogTitle"; 25 | import { base_url } from "../baseUrl"; 26 | function Copyright() { 27 | return ( 28 | 29 | {"Copyright © "} 30 | 31 | Your Website 32 | {" "} 33 | {new Date().getFullYear()} 34 | {"."} 35 | 36 | ); 37 | } 38 | 39 | const useStyles = makeStyles((theme) => ({ 40 | paper: { 41 | marginTop: theme.spacing(8), 42 | display: "flex", 43 | flexDirection: "column", 44 | alignItems: "center", 45 | }, 46 | avatar: { 47 | margin: theme.spacing(1), 48 | backgroundColor: "#707070", 49 | }, 50 | form: { 51 | width: "100%", // Fix IE 11 issue. 52 | marginTop: theme.spacing(1), 53 | }, 54 | submit: { 55 | margin: theme.spacing(3, 0, 2), 56 | }, 57 | })); 58 | 59 | const EmployeeLogin = () => { 60 | const classes = useStyles(); 61 | const [email, setEmail] = useState(""); 62 | const [password, setPassword] = useState(""); 63 | const history = useHistory(); 64 | const [open, setOpen] = useState(false); 65 | const [msg, setMessage] = useState(""); 66 | 67 | const handleClickOpen = () => { 68 | setOpen(true); 69 | }; 70 | 71 | const handleClose = () => { 72 | setOpen(false); 73 | }; 74 | const body = JSON.stringify({ 75 | email: email, 76 | password: password, 77 | }); 78 | const handleSubmit = async (e) => { 79 | e.preventDefault(); 80 | fetch(`${base_url}employeeLogin`, { 81 | method: "POST", 82 | body: body, 83 | headers: { 84 | "Content-Type": "application/json", 85 | }, 86 | }) 87 | .then((res) => res.json()) 88 | .then((res) => { 89 | console.log(res); 90 | if (res.message === "Auth.verified") { 91 | history.push("/employeeDashboard",{email:email}); 92 | } else { 93 | handleClickOpen(); 94 | setMessage(res.message); 95 | } 96 | }) 97 | .catch((err) => { 98 | console.log(err); 99 | }); 100 | }; 101 | 102 | return ( 103 |
104 |
105 | 111 | 112 | {"Authentification Error"} 113 | 114 | 115 | 116 | {msg} 117 | 118 | 119 | 120 | 123 | 124 | 125 |
126 |
127 |

Payroll Management System

128 |
129 | logo 130 |
131 | 132 | 133 |
134 | 135 | 136 | 137 | 138 | Employee Login 139 | 140 |
141 | { 153 | setEmail(event.target.value); 154 | }} 155 | /> 156 | { 168 | setPassword(event.target.value); 169 | }} 170 | /> 171 | 172 | 184 | 185 | 186 | { 189 | history.push("/resetPassword",{ 190 | text:"employee" 191 | }); 192 | }} 193 | > 194 | Forgot password? 195 | 196 | 197 | 198 | 199 |
200 |
201 |
202 | ); 203 | }; 204 | 205 | export default EmployeeLogin; 206 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AdminLogin.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import logo from "../Assets/Logo.png"; 3 | import "../StyleSheets/Welcome.css"; 4 | import Avatar from "@material-ui/core/Avatar"; 5 | import Button from "@material-ui/core/Button"; 6 | import CssBaseline from "@material-ui/core/CssBaseline"; 7 | import TextField from "@material-ui/core/TextField"; 8 | import FormControlLabel from "@material-ui/core/FormControlLabel"; 9 | import Checkbox from "@material-ui/core/Checkbox"; 10 | import Link from "@material-ui/core/Link"; 11 | import Grid from "@material-ui/core/Grid"; 12 | import Box from "@material-ui/core/Box"; 13 | import LockOutlinedIcon from "@material-ui/icons/LockOutlined"; 14 | import Typography from "@material-ui/core/Typography"; 15 | import { makeStyles } from "@material-ui/core/styles"; 16 | import Container from "@material-ui/core/Container"; 17 | import SupervisorAccountIcon from "@material-ui/icons/SupervisorAccount"; 18 | import { useHistory } from "react-router-dom"; 19 | import Dialog from "@material-ui/core/Dialog"; 20 | import DialogActions from "@material-ui/core/DialogActions"; 21 | import DialogContent from "@material-ui/core/DialogContent"; 22 | import DialogContentText from "@material-ui/core/DialogContentText"; 23 | import DialogTitle from "@material-ui/core/DialogTitle"; 24 | import { base_url } from "../baseUrl"; 25 | 26 | const useStyles = makeStyles((theme) => ({ 27 | paper: { 28 | marginTop: theme.spacing(8), 29 | display: "flex", 30 | flexDirection: "column", 31 | alignItems: "center", 32 | }, 33 | avatar: { 34 | margin: theme.spacing(1), 35 | backgroundColor: "#707070", 36 | }, 37 | form: { 38 | width: "100%", // Fix IE 11 issue. 39 | marginTop: theme.spacing(1), 40 | }, 41 | submit: { 42 | margin: theme.spacing(3, 0, 2), 43 | }, 44 | })); 45 | 46 | const AdminLogin = () => { 47 | // console.log(base_url) 48 | const classes = useStyles(); 49 | const [email, setEmail] = useState(""); 50 | const [password, setPassword] = useState(""); 51 | const [open, setOpen] = useState(false); 52 | const [msg, setMessage] = useState(""); 53 | 54 | const handleClickOpen = () => { 55 | setOpen(true); 56 | }; 57 | 58 | const handleClose = () => { 59 | setOpen(false); 60 | }; 61 | const body = JSON.stringify({ 62 | email: email, 63 | password: password, 64 | }); 65 | const history = useHistory(); 66 | 67 | const handleSubmit = async (e) => { 68 | e.preventDefault(); 69 | fetch(`${base_url}adminLogin`, { 70 | method: "POST", 71 | body: body, 72 | headers: { 73 | "Content-Type": "application/json", 74 | }, 75 | }) 76 | .then((res) => res.json()) 77 | .then((res) => { 78 | console.log(res); 79 | if (res.message === "Auth.verified") { 80 | history.push("/adminDashboard"); 81 | } else { 82 | handleClickOpen(); 83 | setMessage(res.message); 84 | } 85 | }) 86 | .catch((err) => { 87 | console.log(err); 88 | }); 89 | }; 90 | 91 | return ( 92 |
93 |
94 | {/* */} 97 | 103 | 104 | {"Authentification Error"} 105 | 106 | 107 | 108 | {msg} 109 | 110 | 111 | 112 | {/* */} 115 | 118 | 119 | 120 |
121 |
122 |

Payroll Management System

123 |
124 | logo 125 |
126 | 127 | 128 |
129 | 130 | 131 | 132 | 133 | Admin Login 134 | 135 |
136 | { 148 | setEmail(event.target.value); 149 | }} 150 | /> 151 | { 163 | setPassword(event.target.value); 164 | }} 165 | /> 166 | {/* } 168 | label="Remember me" 169 | /> */} 170 | 182 | 183 | 184 | { 187 | history.push("/resetPassword",{ 188 | text:"admin" 189 | }); 190 | }} 191 | > 192 | Forgot password? 193 | 194 | 195 | 196 | 197 |
198 | {/* */} 199 |
200 |
201 | ); 202 | }; 203 | 204 | export default AdminLogin; 205 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/AddEmployee.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import "../StyleSheets/Welcome.css"; 3 | import "../StyleSheets/AdminOptions.css"; 4 | import { useFormik } from "formik"; 5 | import { base_url } from "../baseUrl"; 6 | import Dialog from "@material-ui/core/Dialog"; 7 | import DialogActions from "@material-ui/core/DialogActions"; 8 | import DialogContent from "@material-ui/core/DialogContent"; 9 | import DialogContentText from "@material-ui/core/DialogContentText"; 10 | import DialogTitle from "@material-ui/core/DialogTitle"; 11 | import Button from "@material-ui/core/Button"; 12 | import { useHistory } from "react-router-dom"; 13 | 14 | const AddEmployee = () => { 15 | const [departmentsList, setDeplist] = useState([]); 16 | const [gradesList, setGradeslist] = useState([]); 17 | const history = useHistory(); 18 | const [open, setOpen] = useState(false); 19 | const [msg, setMessage] = useState(""); 20 | 21 | const handleClickOpen = () => { 22 | setOpen(true); 23 | }; 24 | 25 | const handleClose = () => { 26 | setOpen(false); 27 | history.goBack(); 28 | }; 29 | const initialValues = { 30 | name: "", 31 | dob: "", 32 | city: "", 33 | state: "", 34 | pincode: "", 35 | address: "", 36 | dept_id: "", 37 | grade_id: "", 38 | org_name: "SGSITS", 39 | doj: "", 40 | email: "", 41 | }; 42 | 43 | const onSubmit = async (values) => { 44 | console.log(values); 45 | const body = JSON.stringify(values); 46 | fetch(`${base_url}addEmployee`, { 47 | method: "POST", 48 | body: body, 49 | headers: { 50 | "Content-Type": "application/json", 51 | }, 52 | }) 53 | .then((res) => res.json()) 54 | .then((res) => { 55 | setMessage(res.message); 56 | handleClickOpen(); 57 | }) 58 | .catch((err) => { 59 | console.error(err); 60 | }); 61 | }; 62 | const formik = useFormik({ 63 | initialValues, 64 | onSubmit, 65 | }); 66 | useEffect(() => { 67 | getDepartments(); 68 | getGrades(); 69 | }, []); 70 | const getDepartments = async () => { 71 | fetch(`${base_url}getDepartments`, { 72 | method: "GET", 73 | headers: { 74 | "Content-Type": "application/json", 75 | }, 76 | }) 77 | .then((res) => res.json()) 78 | .then((res) => { 79 | setDeplist(res); 80 | }) 81 | .catch((err) => { 82 | console.log(err); 83 | }); 84 | }; 85 | const getGrades = async () => { 86 | fetch(`${base_url}getGrades`, { 87 | method: "GET", 88 | headers: { 89 | "Content-Type": "application/json", 90 | }, 91 | }) 92 | .then((res) => res.json()) 93 | .then((res) => { 94 | setGradeslist(res); 95 | }) 96 | .catch((err) => { 97 | console.log(err); 98 | }); 99 | }; 100 | const departments = departmentsList.map((dept) => { 101 | return ; 102 | }); 103 | const grades = gradesList.map((grade) => { 104 | return ; 105 | }); 106 | return ( 107 | <> 108 |
109 | 115 | {"Message"} 116 | 117 | 118 | {msg} 119 | 120 | 121 | 122 | {/* */} 125 | 128 | 129 | 130 |
131 |
132 |
133 |
134 |

Basic Details

135 |
136 |
137 | 138 | 146 |
147 | 148 |
149 | 150 | 158 |
159 |
160 | 161 | 169 |
170 |
171 | 172 | 180 |
181 |
182 | 183 | 191 |
192 |
193 | 196 | 205 |
206 |
207 | 208 |
209 |

Company Details

210 |
211 |
212 | 213 | 221 |
222 |
223 | 224 | 232 |
233 |
234 | 235 | 243 |
244 |
245 | 246 | 255 |
256 |
257 | 258 | 267 |
268 |
269 | 272 |
273 |
274 | 275 | ); 276 | }; 277 | 278 | const styles = { 279 | input: { 280 | width: window.innerWidth / 4.5, 281 | height: "70%", 282 | backgroundColor: "white", 283 | borderWidth: 2, 284 | borderColor: "black", 285 | marginTop: "1%", 286 | }, 287 | dropDown: { 288 | width: window.innerWidth / 4.4, 289 | height: window.innerHeight / 25, 290 | backgroundColor: "hsl(212deg 33% 89%)", 291 | borderWidth: 0, 292 | borderColor: "black", 293 | borderRadius: 5, 294 | marginTop: "1%", 295 | }, 296 | }; 297 | export default AddEmployee; 298 | -------------------------------------------------------------------------------- /payroll-frontend/src/Screens/UpdateDetails.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import "../StyleSheets/Welcome.css"; 3 | import "../StyleSheets/AdminOptions.css"; 4 | import { useFormik } from "formik"; 5 | import { base_url } from "../baseUrl"; 6 | import Dialog from "@material-ui/core/Dialog"; 7 | import DialogActions from "@material-ui/core/DialogActions"; 8 | import DialogContent from "@material-ui/core/DialogContent"; 9 | import DialogContentText from "@material-ui/core/DialogContentText"; 10 | import DialogTitle from "@material-ui/core/DialogTitle"; 11 | import Button from "@material-ui/core/Button"; 12 | import { useHistory } from "react-router-dom"; 13 | import moment from "moment"; 14 | const UpdateDetails = (props) => { 15 | const [departmentsList, setDeplist] = useState([]); 16 | const [gradesList, setGradeslist] = useState([]); 17 | const [extrasList, setExtraslist] = useState([]); 18 | const history = useHistory(); 19 | const [open, setOpen] = useState(false); 20 | const [msg, setMessage] = useState(""); 21 | const [amount, setAmount] = useState(0); 22 | const [ex_type, setExtype] = useState(""); 23 | const handleClickOpen = () => { 24 | setOpen(true); 25 | }; 26 | 27 | const handleClose = () => { 28 | setOpen(false); 29 | history.goBack(); 30 | }; 31 | const initialValues = { 32 | name: "", 33 | dob: "", 34 | city: "", 35 | state: "", 36 | pincode: "", 37 | address: "", 38 | dept_id: "", 39 | grade_id: "", 40 | org_name: "SGSITS", 41 | doj: "", 42 | email: props.location.state.email, 43 | }; 44 | const submitExtras = async () => { 45 | fetch(`${base_url}addIsgiven`, { 46 | method: "POST", 47 | body: JSON.stringify({ 48 | ex_id: ex_type, 49 | amount: amount, 50 | email:props.location.state.email 51 | }), 52 | headers: { 53 | "Content-Type": "application/json", 54 | }, 55 | }) 56 | .then((res) => res.json()) 57 | .then((res) => { 58 | console.log(res); 59 | }) 60 | .catch((err) => { 61 | console.error(err); 62 | }); 63 | }; 64 | const onSubmit = async (values) => { 65 | submitExtras() 66 | console.log(values); 67 | const body = JSON.stringify(values); 68 | fetch(`${base_url}updateEmployeeData`, { 69 | method: "POST", 70 | body: body, 71 | headers: { 72 | "Content-Type": "application/json", 73 | }, 74 | }) 75 | .then((res) => res.json()) 76 | .then((res) => { 77 | console.log(res); 78 | setMessage(res.message); 79 | // console.log(res.data); 80 | // handleClickOpen(); 81 | }) 82 | .catch((err) => { 83 | console.error(err); 84 | }); 85 | }; 86 | const formik = useFormik({ 87 | initialValues, 88 | onSubmit, 89 | }); 90 | useEffect(() => { 91 | getDepartments(); 92 | getGrades(); 93 | getDetails(); 94 | getExtras(); 95 | getExtraDetails(); 96 | }, []); 97 | const getDepartments = async () => { 98 | fetch(`${base_url}getDepartments`, { 99 | method: "GET", 100 | headers: { 101 | "Content-Type": "application/json", 102 | }, 103 | }) 104 | .then((res) => res.json()) 105 | .then((res) => { 106 | setDeplist(res); 107 | }) 108 | .catch((err) => { 109 | console.log(err); 110 | }); 111 | }; 112 | const getGrades = async () => { 113 | fetch(`${base_url}getGrades`, { 114 | method: "GET", 115 | headers: { 116 | "Content-Type": "application/json", 117 | }, 118 | }) 119 | .then((res) => res.json()) 120 | .then((res) => { 121 | setGradeslist(res); 122 | }) 123 | .catch((err) => { 124 | console.log(err); 125 | }); 126 | }; 127 | const getExtras = async () => { 128 | fetch(`${base_url}getExtras`, { 129 | method: "GET", 130 | headers: { 131 | "Content-Type": "application/json", 132 | }, 133 | }) 134 | .then((res) => res.json()) 135 | .then((res) => { 136 | setExtraslist(res); 137 | }) 138 | .catch((err) => { 139 | console.log(err); 140 | }); 141 | }; 142 | const getDetails = async () => { 143 | console.log(props.location.state.email); 144 | fetch(`${base_url}employeeDetails/${props.location.state.email}`, { 145 | method: "GET", 146 | headers: { 147 | "Content-Type": "application/json", 148 | }, 149 | }) 150 | .then((res) => res.json()) 151 | .then((res) => { 152 | // console.log(res.data[0]) 153 | console.log( 154 | moment(res.data[0].dob.slice(0, 10), "YYYY-MM-DD").format( 155 | "MM/DD/YYYY" 156 | ) 157 | ); 158 | formik.setFieldValue("name", res.data[0].name); 159 | formik.setFieldValue( 160 | "dob", 161 | moment(res.data[0].dob.slice(0, 10), "YYYY-MM-DD").format( 162 | "YYYY-MM-DD" 163 | ) 164 | ); 165 | formik.setFieldValue("city", res.data[0].city); 166 | formik.setFieldValue("state", res.data[0].state); 167 | formik.setFieldValue("pincode", res.data[0].pincode); 168 | formik.setFieldValue("address", res.data[0].address); 169 | formik.setFieldValue( 170 | "doj", 171 | moment(res.data[0].doj.slice(0, 10), "YYYY-MM-DD").format( 172 | "YYYY-MM-DD" 173 | ) 174 | ); 175 | formik.setFieldValue("dept_id", res.data[0].dept_id); 176 | formik.setFieldValue("grade_id", res.data[0].grade_id); 177 | }) 178 | .catch((err) => { 179 | console.error(err); 180 | }); 181 | }; 182 | const getExtraDetails = async()=>{ 183 | fetch(`${base_url}getExtraForemp/${props.location.state.email}`,{ 184 | method:"GET", 185 | headers: { 186 | "Content-Type": "application/json", 187 | }, 188 | }) 189 | .then(res=>res.json()) 190 | .then(res=>{ 191 | setExtype(res[0].ex_id) 192 | setAmount(res[0].amount) 193 | }) 194 | .catch(err=>{ 195 | console.error(err); 196 | }) 197 | } 198 | const departments = departmentsList.map((dept) => { 199 | return ; 200 | }); 201 | const grades = gradesList.map((grade) => { 202 | return ; 203 | }); 204 | const extras = extrasList.map((extra) => { 205 | return ; 206 | }); 207 | return ( 208 | <> 209 |
210 | 216 | {"Message"} 217 | 218 | 219 | {msg} 220 | 221 | 222 | 223 | 226 | 227 | 228 |
229 |
230 |
231 |
232 |

Basic Details

233 |
234 |
235 | 236 | 244 |
245 | 246 |
247 | 248 | 256 |
257 |
258 | 259 | 267 |
268 |
269 | 270 | 278 |
279 |
280 | 281 | 289 |
290 |
291 | 294 | 303 |
304 |
305 | 306 |
307 |

Company Details

308 |
309 | {/*
310 | 311 | 319 |
*/} 320 |
321 | 322 | 330 |
331 |
332 | 333 | 341 |
342 |
343 | 344 | 353 |
354 |
355 | 356 | 365 |
366 |
367 | 368 | 379 |
380 |
381 | 382 | setAmount(e.target.value)} 388 | required 389 | /> 390 |
391 |
392 | 393 |
394 |
395 | 396 | ); 397 | }; 398 | 399 | const styles = { 400 | input: { 401 | width: window.innerWidth / 4.5, 402 | height: "70%", 403 | backgroundColor: "white", 404 | borderWidth: 2, 405 | borderColor: "black", 406 | marginTop: "1%", 407 | }, 408 | dropDown: { 409 | width: window.innerWidth / 4.4, 410 | height: window.innerHeight / 25, 411 | backgroundColor: "hsl(212deg 33% 89%)", 412 | borderWidth: 0, 413 | borderColor: "black", 414 | borderRadius: 5, 415 | marginTop: "1%", 416 | }, 417 | }; 418 | export default UpdateDetails; 419 | -------------------------------------------------------------------------------- /backend/src/queries.js: -------------------------------------------------------------------------------- 1 | const uuid = require("uuid"); 2 | const db = require("../db"); 3 | const Helper = require("./Helper"); 4 | const createAdmin = async (req, res) => { 5 | if (!req.body.username || !req.body.password) { 6 | return res 7 | .status(400) 8 | .send({ message: "Please enter all required fields" }); 9 | } 10 | if (!Helper.isValidEmail(req.body.email)) { 11 | return res 12 | .status(400) 13 | .send({ message: "Please enter a valid email address" }); 14 | } 15 | //console.log(req) 16 | const hashPassword = Helper.hashPassword(req.body.password); 17 | const createQuery = `INSERT INTO admin(admin_id,username,email,password) VALUES($1,$2,$3,$4) returning *`; 18 | const values = [uuid.v4(), req.body.username, req.body.email, hashPassword]; 19 | try { 20 | const { rows } = await db.query(createQuery, values); 21 | const token = Helper.generateToken(rows[0].email); 22 | //console.log("This is token ",token) 23 | return res.status(201).send({ message: "Account.Create", token: token }); 24 | } catch (err) { 25 | if (err.routine === "_bt_check_unique") { 26 | return res 27 | .status(400) 28 | .send({ message: "Email address is already taken" }); 29 | } 30 | return res.status(400).send(err); 31 | } 32 | }; 33 | const adminLogin = async (req, res) => { 34 | //console.log(req); 35 | if (!req.body.email || !req.body.password) { 36 | return res 37 | .status(400) 38 | .send({ message: "Please enter a valid email address" }); 39 | } 40 | if (!Helper.isValidEmail(req.body.email)) { 41 | return res 42 | .status(400) 43 | .send({ message: "Please enter a valid email address" }); 44 | } 45 | const query = "SELECT * FROM admin where email = $1"; 46 | try { 47 | const { rows } = await db.query(query, [req.body.email]); 48 | if (!rows[0]) { 49 | return res 50 | .status(400) 51 | .send({ message: "The credentials you provided is incorrect" }); 52 | } 53 | if (!Helper.comparePassword(rows[0].password, req.body.password)) { 54 | return res 55 | .status(400) 56 | .send({ message: "The credentials you provided is incorrect" }); 57 | } 58 | const token = Helper.generateToken(rows[0].email); 59 | return res.status(200).send({ message: "Auth.verified", token: token }); 60 | } catch (error) { 61 | return res.status(400).send({ message: error }); 62 | } 63 | }; 64 | const createEmployee = async (req, res) => { 65 | const query = `INSERT INTO employee( 66 | present, 67 | paid_leave_taken, 68 | encashed_leave_this_month, 69 | encashed_leave_till_date, 70 | e_id, 71 | doj, 72 | name, 73 | dob, 74 | address, 75 | city, 76 | state, 77 | pincode, 78 | email, 79 | password, 80 | org_name, 81 | dept_id, 82 | grade_id) 83 | VALUES($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17) 84 | returning *`; 85 | const hashPassword = Helper.hashPassword("abcd1234"); 86 | //console.log(req.body); 87 | const values = [ 88 | 0, 89 | 0, 90 | 0, 91 | 0, 92 | uuid.v4(), 93 | req.body.doj, 94 | req.body.name, 95 | req.body.dob, 96 | req.body.address, 97 | req.body.city, 98 | req.body.state, 99 | req.body.pincode, 100 | req.body.email, 101 | hashPassword, 102 | req.body.org_name, 103 | req.body.dept_id, 104 | req.body.grade_id, 105 | ]; 106 | try { 107 | const { rows } = await db.query(query, values); 108 | // const token = Helper.generateToken(rows[0].e_id); 109 | //console.log("This is token ",token) 110 | //console.log(rows); 111 | return res.status(201).send({ message: "User Added" }); 112 | } catch (err) { 113 | //console.log(err); 114 | if (err.routine === "_bt_check_unique") { 115 | return res 116 | .status(400) 117 | .send({ message: "Email address is already taken" }); 118 | } 119 | return res.status(400).send({ error: err }); 120 | } 121 | }; 122 | const deleteEmployee = async (req, res) => { 123 | const query = `DELETE FROM Employee WHERE email = $1`; 124 | try { 125 | const { rows } = await db.query(query, [req.body.email]); 126 | return res.status(200).send({ message: "User.Deleted" }); 127 | } catch (err) { 128 | return res.status(400).send({ error: err }); 129 | } 130 | }; 131 | const getAllEmployees = async (req, res) => { 132 | const query = `SELECT * from employee`; 133 | try { 134 | const { rows } = await db.query(query); 135 | // //console.log(rows); 136 | return res.status(200).send({ message: "All Employees", data: rows }); 137 | } catch (err) { 138 | return res.status(400).send({ error: err }); 139 | } 140 | }; 141 | const employeeLogin = async (req, res) => { 142 | //console.log(req); 143 | if (!req.body.email || !req.body.password) { 144 | return res 145 | .status(400) 146 | .send({ message: "Please enter a valid email address" }); 147 | } 148 | if (!Helper.isValidEmail(req.body.email)) { 149 | return res 150 | .status(400) 151 | .send({ message: "Please enter a valid email address" }); 152 | } 153 | const query = "SELECT * FROM employee where email = $1"; 154 | try { 155 | const { rows } = await db.query(query, [req.body.email]); 156 | //console.log(rows); 157 | if (!rows[0]) { 158 | return res 159 | .status(400) 160 | .send({ message: "The credentials you provided is incorrect" }); 161 | } 162 | if (!Helper.comparePassword(rows[0].password, req.body.password)) { 163 | return res 164 | .status(400) 165 | .send({ message: "The credentials you provided is incorrect" }); 166 | } 167 | const token = Helper.generateToken(rows[0].email); 168 | return res.status(200).send({ message: "Auth.verified", token: token }); 169 | } catch (error) { 170 | return res.status(400).send({ message: error }); 171 | } 172 | }; 173 | const getEmployeeProfile = async (req, res) => { 174 | // console.log(req.params); 175 | const query = "SELECT * FROM employee where email = $1"; 176 | try { 177 | const { rows } = await db.query(query, [req.params.email]); 178 | //console.log(rows); 179 | return res.status(200).send({ message: "Employee Data", data: rows }); 180 | } catch (error) { 181 | return res.status(400).send({ message: error }); 182 | } 183 | }; 184 | // const generateReports = async (req, res) => { 185 | // //console.log(req); 186 | // const query = "SELECT * FROM employee natural join payroll where email = $1"; 187 | // try { 188 | // const { rows } = await db.query(query, [req.body.email]); 189 | // //console.log(rows); 190 | // return res.status(200).send({ message: "Report Data", data: rows }); 191 | // } catch (error) { 192 | // return res.status(400).send({ message: error }); 193 | // } 194 | // }; 195 | const updateEmployeedata = async (req, res) => { 196 | const queryGet = "SELECT * FROM employee where email=$1"; 197 | console.log(req.body.email); 198 | // var data = {}; 199 | // try { 200 | // const employee = await db.query(queryGet, [req.body.email]); 201 | // data = employee.rows[0]; 202 | // } catch (err) { 203 | // console.log(err); 204 | // } 205 | // //console.log("Data that is to be updated ", data); 206 | 207 | const updateQuery = `UPDATE employee set 208 | doj=$1, 209 | name=$2, 210 | dob=$3, 211 | address=$4, 212 | city=$5, 213 | state=$6, 214 | pincode=$7, 215 | org_name=$8, 216 | dept_id=$9, 217 | grade_id=$10 218 | where email=$11 219 | returning *`; 220 | //console.log(req.body.dob, data.dob); 221 | // const values = [ 222 | // req.body.doj !== undefined ? req.body.doj : data.doj, 223 | // req.body.name !== undefined ? req.body.name : data.name, 224 | // req.body.dob !== undefined ? req.body.doj : data.doj, 225 | // req.body.address !== undefined ? req.body.address : data.address, 226 | // req.body.city !== undefined ? req.body.city : data.city, 227 | // req.body.state !== undefined ? req.body.state : data.state, 228 | // req.body.pincode !== undefined ? req.body.pincode : data.pincode, 229 | // req.body.org_name !== undefined ? req.body.org_name : data.org_name, 230 | // req.body.dept_id !== undefined ? req.body.dept_id : data.dept_id, 231 | // req.body.grade_id !== undefined ? req.body.grade_id : data.grade_id, 232 | // req.body.email 233 | // ]; 234 | const values = [ 235 | req.body.doj, 236 | req.body.name, 237 | req.body.dob, 238 | req.body.address, 239 | req.body.city, 240 | req.body.state, 241 | req.body.pincode, 242 | req.body.org_name, 243 | req.body.dept_id, 244 | req.body.grade_id, 245 | req.body.email, 246 | ]; 247 | //console.log(values); 248 | try { 249 | const { rows } = await db.query(updateQuery, values); 250 | ////console.log(rows); 251 | return res 252 | .status(200) 253 | .send({ message: "User data updated successfully", data: rows }); 254 | } catch (err) { 255 | return res.status(400).send({ message: err }); 256 | } 257 | }; 258 | const addDepartment = async (req, res) => { 259 | const query = `INSERT into department( 260 | dept_id, 261 | dept_name, 262 | org_name) 263 | VALUES($1,$2,$3)`; 264 | const values = [uuid.v4(), req.body.dept_name, req.body.org_name]; 265 | try { 266 | const { rows } = await db.query(query, values); 267 | ////console.log(rows); 268 | return res.status(200).send({ 269 | message: "Department Added Successfully", 270 | data: rows, 271 | }); 272 | } catch (err) { 273 | if (err.routine === "_bt_check_unique") { 274 | return res.status(400).send({ message: "Department already exists" }); 275 | } 276 | return res.status(400).send({ message: err }); 277 | } 278 | }; 279 | const getDepartments = async (req, res) => { 280 | const query = `SELECT * from department`; 281 | try { 282 | const { rows } = await db.query(query); 283 | return res.status(200).send(rows); 284 | } catch (err) { 285 | return res.status(400).send({ message: err }); 286 | } 287 | }; 288 | const addGrade = async (req, res) => { 289 | const query = `INSERT into gradepay( 290 | grade_id, 291 | grade_name, 292 | basic_pay, 293 | grade_pf, 294 | grade_bonus, 295 | grade_ta, 296 | grade_da) 297 | VALUES($1,$2,$3,$4,$5,$6,$7) 298 | returning *`; 299 | const values = [ 300 | uuid.v4(), 301 | req.body.grade_name, 302 | req.body.grade_pay, 303 | req.body.grade_pf, 304 | req.body.grade_bonus, 305 | req.body.grade_ta, 306 | req.body.grade_da, 307 | ]; 308 | try { 309 | const { rows } = await db.query(query, values); 310 | return res 311 | .status(200) 312 | .send({ message: "Grade added for employee", data: rows }); 313 | } catch (err) { 314 | if (err.routine === "_bt_check_unique") { 315 | return res.status(400).send({ message: "Grade already exists" }); 316 | } 317 | return res.status(400).send({ message: err }); 318 | } 319 | }; 320 | const getGrades = async (req, res) => { 321 | const query = `Select * from gradepay`; 322 | try { 323 | const { rows } = await db.query(query); 324 | return res.status(200).send(rows); 325 | } catch (err) { 326 | return res.status(400).send({ message: err }); 327 | } 328 | }; 329 | const updateEmployeePassword = async (req, res) => { 330 | if (!req.body.email || !req.body.password) { 331 | return res 332 | .status(400) 333 | .send({ message: "Please enter a valid email address and password" }); 334 | } 335 | if (!Helper.isValidEmail(req.body.email)) { 336 | return res 337 | .status(400) 338 | .send({ message: "Please enter a valid email address" }); 339 | } 340 | const query = `UPDATE employee set password = $1 where email=$2 returning email,password`; 341 | const newPassword = Helper.hashPassword(req.body.password); 342 | const values = [newPassword, req.body.email]; 343 | try { 344 | const { rows } = await db.query(query, values); 345 | return res 346 | .status(200) 347 | .send({ message: "Password updated successfully", data: rows }); 348 | } catch (err) { 349 | return res.status(400).send({ message: err }); 350 | } 351 | }; 352 | const updateAdminPassword = async (req, res) => { 353 | if (!req.body.email || !req.body.password) { 354 | return res 355 | .status(400) 356 | .send({ message: "Please enter a valid email address and password" }); 357 | } 358 | if (!Helper.isValidEmail(req.body.email)) { 359 | return res 360 | .status(400) 361 | .send({ message: "Please enter a valid email address" }); 362 | } 363 | const query = `UPDATE admin set password = $1 where email=$2 returning email,password`; 364 | const newPassword = Helper.hashPassword(req.body.password); 365 | const values = [newPassword, req.body.email]; 366 | try { 367 | const { rows } = await db.query(query, values); 368 | return res 369 | .status(200) 370 | .send({ message: "Password updated successfully", data: rows }); 371 | } catch (err) { 372 | return res.status(400).send({ message: err }); 373 | } 374 | }; 375 | const addOrganisation = async (req, res) => { 376 | const query = `INSERT into organisation( 377 | org_name, 378 | email, 379 | location, 380 | contact_number, 381 | paid_leave_limit, 382 | encashed_leave_limit 383 | ) values($1,$2,$3,$4,$5,$6) returning *`; 384 | const values = [ 385 | req.body.org_name, 386 | req.body.email, 387 | req.body.location, 388 | req.body.contact_number, 389 | req.body.paid_leave_limit, 390 | req.body.encashed_leave_limit, 391 | ]; 392 | try { 393 | const { rows } = await db.query(query, values); 394 | return res.status(200).send({ message: "Organisation.Added", data: rows }); 395 | } catch (err) { 396 | return res.status(400).send({ message: err }); 397 | } 398 | }; 399 | const markAttendance = async (req, res) => { 400 | const updateQuery = `UPDATE employee set 401 | present=$1, 402 | paid_leave_taken=$2, 403 | encashed_leave_this_month=$3 404 | where email=$4 405 | returning *`; 406 | const values = [ 407 | req.body.present === 1 ? 1 : 0, 408 | req.body.paid_leave_taken === 1 ? 1 : 0, 409 | req.body.encashed_leave_this_month === 1 ? 1 : 0, 410 | req.body.email, 411 | ]; 412 | try { 413 | const { rows } = await db.query(updateQuery, values); 414 | //console.log(rows); 415 | return res 416 | .status(200) 417 | .send({ message: "Attendance recorded successfully", data: rows }); 418 | } catch (err) { 419 | return res.status(400).send({ message: err }); 420 | } 421 | }; 422 | const addExtras = async (req, res) => { 423 | const query = `INSERT into extras( 424 | ex_type, 425 | ex_id 426 | ) values($1,$2) returning *`; 427 | const values = [req.body.ex_type, uuid.v4()]; 428 | try { 429 | const { rows } = await db.query(query, values); 430 | return res.status(200).send({ message: "Extras added", data: rows }); 431 | } catch (err) { 432 | return res.status(400).send(err); 433 | } 434 | }; 435 | const getExtras = async (req, res) => { 436 | const query = `Select * from extras`; 437 | try { 438 | const { rows } = await db.query(query); 439 | return res.status(200).send(rows); 440 | } catch (err) { 441 | return res.status(400).send({ message: err }); 442 | } 443 | }; 444 | const addIsgiven = async (req, res) => { 445 | const query = `Insert into is_given( 446 | ex_id, 447 | amount, 448 | email) 449 | values($1,$2,$3) 450 | returning *`; 451 | const values = [req.body.ex_id, req.body.amount, req.body.email]; 452 | try { 453 | const { rows } = await db.query(query, values); 454 | return res 455 | .status(200) 456 | .send({ message: "Extras added for employee", data: rows }); 457 | } catch (err) { 458 | return res.status(400).send({ message: err }); 459 | } 460 | }; 461 | const getExtraForemp = async (req, res) => { 462 | const query = `Select * from is_given where email=$1`; 463 | const values = [req.params.email]; 464 | try { 465 | const { rows } = await db.query(query, values); 466 | return res.status(200).send(rows); 467 | } catch (err) { 468 | return res.status(400).send({ message: err }); 469 | } 470 | }; 471 | const generateReports = async (req, res) => { 472 | // console.log(req); 473 | const { mail } = req.params; 474 | console.log(mail); 475 | const query = `WITH T AS 476 | (Select * from 477 | employee,payroll,gradepay 478 | where 479 | employee.email = payroll.emp_mail and employee.grade_id = gradepay.grade_id) 480 | Select * from T where email=$1 and month=$2 and year=$3`; 481 | 482 | try { 483 | const { rows } = await db.query(query,[mail,12,2020]); 484 | console.log(rows); 485 | return res.status(200).send({ message: "Report Data", data: rows }); 486 | } catch (error) { 487 | return res.status(400).send({ message: error }); 488 | } 489 | }; 490 | module.exports = { 491 | createAdmin, 492 | adminLogin, 493 | createEmployee, 494 | deleteEmployee, 495 | getAllEmployees, 496 | employeeLogin, 497 | getEmployeeProfile, 498 | generateReports, 499 | updateEmployeedata, 500 | addDepartment, 501 | addGrade, 502 | updateEmployeePassword, 503 | updateAdminPassword, 504 | getDepartments, 505 | getGrades, 506 | addOrganisation, 507 | markAttendance, 508 | addExtras, 509 | getExtras, 510 | addIsgiven, 511 | getExtraForemp, 512 | generateReports, 513 | }; 514 | --------------------------------------------------------------------------------