React JS Node Express Employee Management System | Mysql bcrypt jsonwebtoken https://expressjs.com/
Express JS
Fast, unopinionated, minimalist web framework for Node.js
Install
$ npm install express --save
PS C:\nodeproject> npm install express --save
https://expressjs.com/en/starter/hello-world.html
run PS C:\nodeproject> node index.js
//C:\nodeproject> node index.js
const express = require("express");
const mysql = require("mysql");
const cors = require("cors");
const bcrypt = require('bcrypt'); // https://www.npmjs.com/package/bcrypt npm i bcrypt
var jwt = require('jsonwebtoken'); //https://github.com/auth0/node-jsonwebtoken npm install jsonwebtoken
const app = express();
const port = 3001
app.use(express.json());
app.use(cors());
const con = mysql.createConnection({
user: "root",
host: "localhost",
password: "",
database: "nodejsdb"
})
con.connect(function(err) {
if(err) {
console.log("Error in Connection");
} else {
console.log("Connected");
}
})
app.get('/getEmployee', (req, res) => {
const sql = "SELECT * FROM employee";
con.query(sql, (err, result) => {
if(err) return res.json({Error: "Get employee error in sql"});
return res.json({Status: "Success", Result: result})
})
})
app.get('/get/:id', (req, res) => {
const id = req.params.id;
const sql = "SELECT * FROM employee where id = ?";
con.query(sql, [id], (err, result) => {
if(err) return res.json({Error: "Get employee error in sql"});
return res.json({Status: "Success", Result: result})
})
})
app.put("/update/:id", (req, res) => {
const userId = req.params.id;
const q = "UPDATE employee SET `name`= ?, `email`= ?, `salary`= ?, `address`= ? WHERE id = ?";
const values = [
req.body.name,
req.body.email,
req.body.salary,
req.body.address,
];
con.query(q, [...values,userId], (err, data) => {
if (err) return res.send(err);
return res.json(data);
//return res.json({Status: "Success"})
});
});
app.delete('/delete/:id', (req, res) => {
const id = req.params.id;
const sql = "Delete FROM employee WHERE id = ?";
con.query(sql, [id], (err, result) => {
if(err) return res.json({Error: "delete employee error in sql"});
return res.json({Status: "Success"})
})
})
app.get('/adminCount', (req, res) => {
const sql = "Select count(id) as admin from users";
con.query(sql, (err, result) => {
if(err) return res.json({Error: "Error in runnig query"});
return res.json(result);
})
})
app.get('/employeeCount', (req, res) => {
const sql = "Select count(id) as employee from employee";
con.query(sql, (err, result) => {
if(err) return res.json({Error: "Error in runnig query"});
return res.json(result);
})
})
app.get('/salary', (req, res) => {
const sql = "Select sum(salary) as sumOfSalary from employee";
con.query(sql, (err, result) => {
if(err) return res.json({Error: "Error in runnig query"});
return res.json(result);
})
})
app.post('/create', (req, res) => {
const name = req.body.name;
const email = req.body.email;
const address = req.body.address;
const salary = req.body.salary;
con.query("INSERT INTO employee (name, email, address, salary) VALUES (?, ?, ?, ?)", [name, email, address, salary],
(err, result) => {
if(result){
res.send(result);
}else{
res.send({message: "ENTER CORRECT DETAILS!"})
}
}
)
})
app.get('/hash', (req, res) => {
bcrypt.hash("123456", 10, (err, hash) => {
if(err) return res.json({Error: "Error in hashing password"});
const values = [
hash
]
return res.json({result: hash});
} )
})
app.post('/login', (req, res) => {
const sql = "SELECT * FROM users Where email = ?";
con.query(sql, [req.body.email], (err, result) => {
if(err) return res.json({Status: "Error", Error: "Error in runnig query"});
if(result.length > 0) {
bcrypt.compare(req.body.password.toString(), result[0].password, (err, response)=> {
if(err) return res.json({Error: "password error"});
if(response) {
const token = jwt.sign({role: "admin"}, "jwt-secret-key", {expiresIn: '1d'});
return res.json({Status: "Success", Token: token})
} else {
return res.json({Status: "Error", Error: "Wrong Email or Password"});
}
})
} else {
return res.json({Status: "Error", Error: "Wrong Email or Password"});
}
})
})
app.post('/register',(req, res) => {
const sql = "INSERT INTO users (`name`,`email`,`password`) VALUES (?)";
bcrypt.hash(req.body.password.toString(), 10, (err, hash) => {
if(err) return res.json({Error: "Error in hashing password"});
const values = [
req.body.name,
req.body.email,
hash,
]
con.query(sql, [values], (err, result) => {
if(err) return res.json({Error: "Error query"});
return res.json({Status: "Success"});
})
} )
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
Install Requirements
mysql
https://github.com/mysqljs/mysql
$ npm install mysql
PS C:\nodeproject>npm install mysql
cors
CORS is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options.
https://www.npmjs.com/package/cors
PS C:\nodeproject>npm i cors
bcrypt
A library to help you hash passwords.
https://www.npmjs.com/package/bcrypt
$ npm i bcrypt
PS C:\nodeproject>npm i bcrypt
jsonwebtoken
An implementation of JSON Web Tokens.
https://github.com/auth0/node-jsonwebtoken
$ npm install jsonwebtoken
PS C:\nodeproject>npm install jsonwebtoken
React JS
https://create-react-app.dev/
Create Project
C:\react-js>npx create-react-app my-app
Run
C:\react-js\my-app> npm start
C:\react-js\my-app\src\App.js
//C:\react-js\my-app\src\App.js
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Login from "./components/login";
import SignUp from "./components/signup";
import {RequireToken} from './components/Auth.js'
import Dashboard from "./components/dashboard";
import Home from "./components/home";
import Employee from "./components/employee";
import Profile from "./components/profile";
import AddEmployee from "./components/addemployee";
import EditEmployee from './components/editemployee'
function App() {
return (
<div className="app">
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<SignUp />} />
<Route path='/' element={
<RequireToken>
<Dashboard />
</RequireToken>
}>
<Route path='' element={<Home />}></Route>
<Route path='/employee' element={<Employee />}></Route>
<Route path='/profile' element={<Profile />}></Route>
<Route path='/create' element={<AddEmployee />}></Route>
<Route path='/employeeedit/:id' element={<EditEmployee />}></Route>
</Route>
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
C:\react-js\my-app\src\components\signup.js
//C:\react-js\my-app\src\components\signup.js
import { useState } from "react";
import Axios from "axios";
const SignUp = () => {
const [email, setEmail] = useState("");
const [name, setName] = useState("");
const [password, setPassword] = useState("");
const [registerStatus, setRegisterStatus] = useState("");
const register = (e) => {
e.preventDefault();
Axios.post("http://localhost:3001/register", {
email: email,
name: name,
password: password,
}).then((response) => {
console.log(response);
if(response.data.message){
setRegisterStatus(response.data.message);
}else{
setRegisterStatus("ACCOUNT CREATED SUCCESSFULLY");
}
})
}
let imgs = [
'https://as2.ftcdn.net/v2/jpg/03/39/70/91/1000_F_339709132_H9HSSTtTmayePcbARkTSB2qoZTubJ6bR.jpg',
];
return (
<div className="container" style={{paddingTop: 60}}>
<div className="container-fluid h-custom">
<div className="row d-flex justify-content-center align-items-center h-100">
<div className="col-md-8 col-lg-6 col-xl-4 offset-xl-1">
<form>
<div className="d-flex flex-row align-items-center justify-content-center justify-content-lg-start">
<p className="lead fw-normal mb-0 me-3">Create Your Account</p>
</div>
<p><h1 style={{fontSize: '15px', textAlign: 'center', marginTop: '20px'}}>{registerStatus}</h1></p>
<div className="form-outline mb-4">
<input
type="text"
className="form-control form-control-lg"
placeholder="Enter Name"
onChange={(e) => {setName(e.target.value)}} placeholder="Enter your Name" required
/>
<label className="form-label">Name</label>
</div>
<div className="form-outline mb-4">
<input
type="email"
className="form-control form-control-lg"
onChange={(e) => {setEmail(e.target.value)}} placeholder="Enter your Email Address" required
/>
<label className="form-label">Email address</label>
</div>
<div className="form-outline mb-3">
<input
type="password"
className="form-control form-control-lg"
onChange={(e) => {setPassword(e.target.value)}} placeholder="Enter your Password" required
/>
<label className="form-label">Password</label>
</div>
<div className="d-flex justify-content-between align-items-center">
<div className="form-check mb-0">
<input className="form-check-input me-2" type="checkbox" value=""/>
<label className="form-check-label">
Remember me
</label>
</div>
<a href="#" className="text-body">Forgot password?</a>
</div>
<div className="text-center text-lg-start mt-4 pt-2">
<button type="button" className="btn btn-primary btn-lg" onClick={register}>Sign Up</button>
<p className="small fw-bold mt-2 pt-1 mb-0">Login to your account <a href="login" className="link-danger">Login</a></p>
</div>
</form>
</div>
<div className="col-md-9 col-lg-6 col-xl-5">
<img src={imgs[0]} className="img-fluid"/>
</div>
</div>
</div>
</div>
);
};
export default SignUp;
C:\react-js\my-app\src\components\login.js
//C:\react-js\my-app\src\components\login.js
import React, {useState} from "react";
import axios from "axios";
import { useNavigate } from 'react-router-dom'
import loginimg from './login.png';
import {setToken} from './Auth.js'
const Login = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState('')
const navigate = useNavigate()
const login = (e) => {
e.preventDefault();
axios.post("http://localhost:3001/login", {
email: email,
password: password,
})
.then(res => {
console.log(res);
if(res.data.Status === 'Success') {
console.log(res.data.Token);
setToken(res.data.Token)
navigate('/');
} else {
setError(res.data.Error);
}
})
.catch(err => console.log(err));
}
return (
<div className="container" style={{paddingTop: 60}}>
<div className="container-fluid h-custom">
<div className="row d-flex justify-content-center align-items-center h-100">
<div className="col-md-9 col-lg-6 col-xl-5">
<img src={loginimg} alt="" className="img-fluid"/>
</div>
<div className="col-md-8 col-lg-6 col-xl-4 offset-xl-1">
<form>
<div className="d-flex flex-row align-items-center justify-content-center justify-content-lg-start">
<p className="lead fw-normal mb-0 me-3">Login to your account</p>
</div>
<h1 style={{color: 'red', fontSize: '15px', textAlign: 'center', marginTop: '20px'}}>{error && error}</h1>
<div className="form-outline mb-4">
<input
type="email"
className="form-control form-control-lg"
placeholder="Enter a valid email address"
onChange={(e) => {setEmail(e.target.value)}} required
/>
<label className="form-label">Email address</label>
</div>
<div className="form-outline mb-3">
<input
type="password"
className="form-control form-control-lg"
placeholder="Enter password"
onChange={(e) => {setPassword(e.target.value)}} required
/>
<label className="form-label">Password</label>
</div>
<div className="d-flex justify-content-between align-items-center">
<div className="form-check mb-0">
<input className="form-check-input me-2" type="checkbox" value=""/>
<label className="form-check-label">
Remember me
</label>
</div>
<a href="/#" className="text-body">Forgot password?</a>
</div>
<div className="text-center text-lg-start mt-4 pt-2">
<button type="button" className="btn btn-primary btn-lg" onClick={login}>Login</button>
<p className="small fw-bold mt-2 pt-1 mb-0">Login to your account <a href="signup" className="link-danger">Sign Up</a></p>
</div>
</form>
</div>
</div>
</div>
</div>
);
};
export default Login;
C:\react-js\my-app\src\components\Auth.js
//C:\react-js\my-app\src\components\Auth.js
import React, { } from "react";
import {
Navigate ,
useLocation
} from "react-router-dom";
export const setToken = (token) =>{
// set token in localStorage
localStorage.setItem('Token', token)
}
export const fetchToken = (token) =>{
// fetch the token
return localStorage.getItem('Token')
}
export function RequireToken({children}) {
let auth = fetchToken()
let location = useLocation();
if (!auth) {
return <Navigate to="/login" state={{ from: location }} />;
}
return children;
}
C:\react-js\my-app\src\components\dashboard.js
//C:\react-js\my-app\src\components\dashboard.js
import React, { } from 'react'
import { Link, Outlet, useNavigate } from 'react-router-dom'
function Dashboard() {
const navigate = useNavigate();
const signOut = () => {
localStorage.removeItem('Token')
navigate("/login");
}
return (
<div className="container-fluid">
<div className="row flex-nowrap">
<div className="col-auto col-md-3 col-xl-2 px-sm-2 px-0 bg-dark">
<div className="d-flex flex-column align-items-center align-items-sm-start px-3 pt-2 text-white min-vh-100">
<a href="/" className="d-flex align-items-center pb-3 mb-md-1 mt-md-3 me-md-auto text-white text-decoration-none">
<span className="fs-5 fw-bolder d-none d-sm-inline">Admin Dashboard</span>
</a>
<ul className="nav nav-pills flex-column mb-sm-auto mb-0 align-items-center align-items-sm-start" id="menu">
<li>
<Link to="/" data-bs-toggle="collapse" className="nav-link text-white px-0 align-middle">
<span className="ms-1 d-none d-sm-inline">Dashboard</span>
</Link>
</li>
<li>
<Link to="/employee" className="nav-link px-0 align-middle text-white">
<span className="ms-1 d-none d-sm-inline">Manage Employees</span>
</Link>
</li>
<li>
<Link to="profile" className="nav-link px-0 align-middle text-white">
<span className="ms-1 d-none d-sm-inline">Profile</span>
</Link>
</li>
<li>
<button type = 'button' className="btn btn-success" onClick= {signOut}>Sign Out</button>
</li>
</ul>
</div>
</div>
<div className="col p-0 m-0">
<div className='p-2 d-flex justify-content-center shadow'>
<h4>Employee Management System</h4>
</div>
<Outlet />
</div>
</div>
</div>
)
}
export default Dashboard
C:\react-js\my-app\src\components\home.js
//C:\react-js\my-app\src\components\home.js
import React, { useEffect, useState } from 'react'
import axios from 'axios'
function Home() {
const [adminCount, setAdminCount] = useState()
const [employeeCount, setEmployeeCount] = useState()
const [salary, setSalary] = useState()
useEffect(() => {
axios.get('http://localhost:3001/adminCount')
.then(res => {
setAdminCount(res.data[0].admin)
}).catch(err => console.log(err));
axios.get('http://localhost:3001/employeeCount')
.then(res => {
setEmployeeCount(res.data[0].employee)
}).catch(err => console.log(err));
axios.get('http://localhost:3001/salary')
.then(res => {
setSalary(res.data[0].sumOfSalary)
}).catch(err => console.log(err));
} , [])
return (
<div>
<div className='p-3 d-flex justify-content-around mt-3'>
<div className='px-3 pt-2 pb-3 border shadow-sm w-25'>
<div className='text-center pb-1'>
<h4>Admin</h4>
</div>
<hr />
<div>
<h5>Total: {adminCount}</h5>
</div>
</div>
<div className='px-3 pt-2 pb-3 border shadow-sm w-25'>
<div className='text-center pb-1'>
<h4>Employee</h4>
</div>
<hr />
<div>
<h5>Total: {employeeCount}</h5>
</div>
</div>
<div className='px-3 pt-2 pb-3 border shadow-sm w-25'>
<div className='text-center pb-1'>
<h4>Salary</h4>
</div>
<hr />
<div>
<h5>Total: {salary}</h5>
</div>
</div>
</div>
</div>
)
}
export default Home
C:\react-js\my-app\src\components\employee.js
//C:\react-js\my-app\src\components\employee.js
import axios from 'axios'
import React, { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
function Employee() {
const [data, setData] = useState([])
useEffect(()=> {
axios.get('http://localhost:3001/getEmployee')
.then(res => {
if(res.data.Status === "Success") {
setData(res.data.Result);
} else {
alert("Error")
}
})
.catch(err => console.log(err));
}, [])
const handleDelete = (id) => {
axios.delete('http://localhost:3001/delete/'+id)
.then(res => {
if(res.data.Status === "Success") {
window.location.reload(true);
} else {
alert("Error")
}
})
.catch(err => console.log(err));
}
return (
<div className='px-5 py-3'>
<div className='d-flex justify-content-center mt-2'>
<h3>Employee List</h3>
</div>
<Link to="/create" className='btn btn-success'>Add Employee</Link>
<div className='mt-3'>
<table className="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Address</th>
<th>Salary</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{data.map((employee, index) => {
return <tr key={index}>
<td>{employee.name}</td>
<td>{employee.email}</td>
<td>{employee.address}</td>
<td>{employee.salary}</td>
<td>
<Link to={`/employeeedit/`+employee.id} className='btn btn-primary btn-sm me-2'>edit</Link>
<button onClick={e => handleDelete(employee.id)} className='btn btn-sm btn-danger'>delete</button>
</td>
</tr>
})}
</tbody>
</table>
</div>
</div>
)
}
export default Employee
C:\react-js\my-app\src\components\addemployee.js
//C:\react-js\my-app\src\components\addemployee.js
import axios from 'axios';
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom';
function AddEmployee() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [address, setaddress] = useState("");
const [salary, setsalary] = useState("");
const [registerStatus, setRegisterStatus] = useState("");
const navigate = useNavigate()
const create = (e) => {
e.preventDefault();
axios.post("http://localhost:3001/create", {
name: name,
email: email,
address: address,
salary: salary,
}).then((response) => {
// setRegisterStatus(response);
console.log(response);
if(response.data.message){
setRegisterStatus(response.data.message);
}else{
navigate('/employee')
alert("Success");
}
})
.catch(err => console.log(err));
}
return (
<div className='d-flex flex-column align-items-center pt-4'>
<h2>Add Employee</h2>
<form className="row g-3 w-50">
<h1 style={{fontSize: '15px', textAlign: 'center', marginTop: '20px'}}>{registerStatus}</h1>
<div className="col-12">
<label className="form-label">Name</label>
<input type="text" className="form-control" placeholder='Enter Name' autoComplete='off'
onChange={(e) => {setName(e.target.value)}}/>
</div>
<div className="col-12">
<label className="form-label">Email</label>
<input type="email" className="form-control" placeholder='Enter Email' autoComplete='off'
onChange={(e) => {setEmail(e.target.value)}}/>
</div>
<div className="col-12">
<label className="form-label">Salary</label>
<input type="text" className="form-control" placeholder="Enter Salary" autoComplete='off'
onChange={(e) => {setsalary(e.target.value)}}/>
</div>
<div className="col-12">
<label className="form-label">Address</label>
<input type="text" className="form-control" placeholder="1234 Main St" autoComplete='off'
onChange={(e) => {setaddress(e.target.value)}}/>
</div>
<div className="col-12">
<button type="submit" className="btn btn-primary" onClick={create}>Create</button>
</div>
</form>
</div>
)
}
export default AddEmployee
C:\react-js\my-app\src\components\editemployee.js
//C:\react-js\my-app\src\components\editemployee.js
import axios from 'axios';
import React, { useState, useEffect } from 'react'
import { useLocation, useNavigate, useParams } from "react-router-dom";
function EditEmployee() {
const {id} = useParams();
const [employee, setemployee] = useState({
name: "",
email: "",
address: "",
salary: "",
});
const location = useLocation();
const navigate = useNavigate();
const employeeId = location.pathname.split("/")[2];
//alert(employeeId);
const handleChange = (e) => {
setemployee((prev) => ({ ...prev, [e.target.name]: e.target.value }));
};
useEffect(() => {
axios.get("http://localhost:3001/get/"+id)
.then(res => {
console.log(res.data.Result[0])
setemployee(res.data.Result[0]);
})
.catch(err => console.log(err))
}, []);
const handleUpdate = async (e) => {
e.preventDefault();
try {
await axios.put(`http://localhost:3001/update/${employeeId}`, employee);
navigate("/");
} catch (err) {
console.log(err);
}
};
return (
<div className='d-flex flex-column align-items-center pt-4'>
<h2>Edit Employee</h2>
<form className="row g-3 w-50">
<div className="col-12">
<input type="text" className="form-control" id="id" name="id" value={id} disabled />
<label className="form-label">Name</label>
<input type="text" className="form-control" placeholder='Enter Name' autoComplete='off'
name="name" value={employee.name} onChange={handleChange}/>
</div>
<div className="col-12">
<label className="form-label">Email</label>
<input type="email" className="form-control" placeholder='Enter Email' autoComplete='off'
name="email" value={employee.email} onChange={handleChange}/>
</div>
<div className="col-12">
<label className="form-label">Salary</label>
<input type="text" className="form-control" placeholder="Enter Salary" autoComplete='off'
name="salary" value={employee.salary} onChange={handleChange}/>
</div>
<div className="col-12">
<label className="form-label">Address</label>
<input type="text" className="form-control" placeholder="1234 Main St" autoComplete='off'
name="address" value={employee.address} onChange={handleChange}/>
</div>
<div className="col-12">
<button type="submit" className="btn btn-primary" onClick={handleUpdate}>Update</button>
</div>
</form>
</div>
)
}
export default EditEmployee
C:\react-js\my-app\src\components\profile.js
//C:\react-js\my-app\src\components\profile.js
import React, { } from "react";
export default function Profile(){
return(
<div className="container" style={{paddingTop: 60}}>
<div className="row">
<div style = {{minHeight: 800, marginTop: 20 }}>
<h1>Profile Page</h1>
<p>Hi, this is your profile</p>
</div>
</div>
</div>
)
}
Install axios
https://github.com/axios/axios
Installing the Axios Client
$ npm install axios
C:\reactdev\myreactdev>npm install axios
Install React Router Dom
https://www.npmjs.com/package/react-router-dom
C:\react-js\myreactdev>npm i react-router-dom --save
//react-js\my-app\public\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css">
</head>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html
Run C:\react-j\my-app>npm start
http://localhost:3000/
VIDEO