├── 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 | //
22 | //
23 | // Payroll Management System
24 | //
25 | //
26 | //
27 | //
28 | // Admin Login
29 | // Employee Login
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 |
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 |
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 |
20 |
21 |
22 | history.push('/adminLogin')}>
23 | Admin Login
24 |
25 | history.push('/employeeLogin')}>
26 | Employee Login
27 |
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 |
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 |
32 |
33 |
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 |
You need to enable JavaScript to run this app.
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 |
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 | []
82 | []
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 |
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 |
76 |
77 |
78 |
79 | {emp.map((Emp) => (
80 |
81 | {Emp.name}
82 |
83 | handleUpdate(Emp)}>Edit
84 |
85 |
86 | handleDelete(Emp)}
89 | >
90 | Delete
91 |
92 |
93 |
94 | ))}
95 |
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 |
72 | OK
73 |
74 |
75 |
76 |
77 |
78 |
79 | Payroll Management System
80 |
81 |
82 |
83 |
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 |
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 |
73 | OK
74 |
75 |
76 |
77 |
78 |
79 | Payroll Management System
80 |
81 |
82 |
83 |
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 |
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 |
77 | OK
78 |
79 |
80 |
81 |
82 |
83 |
84 | Payroll Management System
85 |
86 |
87 |
88 |
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 | {/*
124 | Disagree
125 | */}
126 |
127 | OK
128 |
129 |
130 |
131 |
132 |
133 | Payroll Management System
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 | Reset Password {props.location.state.text.toUpperCase()}
145 |
146 |
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 |
121 | OK
122 |
123 |
124 |
125 |
126 |
127 | Payroll Management System
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | Employee Login
139 |
140 |
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 | {/*
95 | Open alert dialog
96 | */}
97 |
103 |
104 | {"Authentification Error"}
105 |
106 |
107 |
108 | {msg}
109 |
110 |
111 |
112 | {/*
113 | Disagree
114 | */}
115 |
116 | OK
117 |
118 |
119 |
120 |
121 |
122 | Payroll Management System
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 | Admin Login
134 |
135 |
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
{dept.dept_name} ;
102 | });
103 | const grades = gradesList.map((grade) => {
104 | return
{grade.grade_name} ;
105 | });
106 | return (
107 | <>
108 |
109 |
115 | {"Message"}
116 |
117 |
118 | {msg}
119 |
120 |
121 |
122 | {/*
123 | Disagree
124 | */}
125 |
126 | OK
127 |
128 |
129 |
130 |
131 |
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
{dept.dept_name} ;
200 | });
201 | const grades = gradesList.map((grade) => {
202 | return
{grade.grade_name} ;
203 | });
204 | const extras = extrasList.map((extra) => {
205 | return
{extra.ex_type} ;
206 | });
207 | return (
208 | <>
209 |
210 |
216 | {"Message"}
217 |
218 |
219 | {msg}
220 |
221 |
222 |
223 |
224 | OK
225 |
226 |
227 |
228 |
229 |
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 |
--------------------------------------------------------------------------------