article

Monday, September 4, 2023

React JS Node Express Employee Management System | Mysql bcrypt jsonwebtoken

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/

Related Post