Skip to content

Commit

Permalink
"Added authentication and authorization features to Admin dashboard, …
Browse files Browse the repository at this point in the history
…including login and logout functionality, protected routes, and admin role"
  • Loading branch information
VishalRMahajan committed Nov 13, 2024
1 parent 4d8c231 commit b4afaad
Show file tree
Hide file tree
Showing 14 changed files with 440 additions and 30 deletions.
62 changes: 55 additions & 7 deletions Admin/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React, { useState } from "react";
import React, { useContext } from "react";
import { Route, Routes, Navigate } from "react-router-dom";
import Sidebar from "./components/Sidebar/Sidebar";
import { Route, Routes } from "react-router-dom";
import Add from "./pages/Add/Add";
import List from "./pages/List/List";
import Orders from "./pages/Orders/Orders";
import PromoCode from "./pages/PromoCode/PromoCode";
import UpdatePromoCode from "./pages/PromoCode/UpdatePromoCode";
import Login from "./pages/Login/Login";
import ProtectedRoute from "./components/ProtectedRoute";
import WelcomeAdmin from "./pages/WelcomeAdmin/WelcomeAdmin";
import { Toaster } from "react-hot-toast";
import { StoreContext } from "./context/StoreContext";

const App = () => {
const url = import.meta.env.VITE_BACKEND_URL;
const { isAuthenticated } = useContext(StoreContext);

return (
<div>
Expand All @@ -18,15 +23,58 @@ const App = () => {
<Sidebar />
<div className="app-side-section">
<Routes>
<Route path="/add" element={<Add url={url} />} />
<Route path="/list" element={<List url={url} />} />
<Route path="/order" element={<Orders url={url} />} />
<Route path="/promo" element={<PromoCode url={url} />} />
<Route
path="/login"
element={
isAuthenticated ? <Navigate to="/" /> : <Login url={url} />
}
/>
<Route
path="/"
element={
<ProtectedRoute>
<WelcomeAdmin />
</ProtectedRoute>
}
/>
<Route
path="/add"
element={
<ProtectedRoute>
<Add url={url} />
</ProtectedRoute>
}
/>
<Route
path="/list"
element={
<ProtectedRoute>
<List url={url} />
</ProtectedRoute>
}
/>
<Route
path="/order"
element={
<ProtectedRoute>
<Orders url={url} />
</ProtectedRoute>
}
/>
<Route
path="/promo"
element={
<ProtectedRoute>
<PromoCode url={url} />
</ProtectedRoute>
}
/>
<Route path="*" element={<Navigate to="/" />} />
</Routes>
</div>
</div>
</div>
);
};

export default App;
export default App;
16 changes: 16 additions & 0 deletions Admin/src/components/Layout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { Outlet } from 'react-router-dom';
import Sidebar from './Sidebar/Sidebar';

const Layout = () => {
return (
<div className="app-content">
<Sidebar />
<div className="app-side-section">
<Outlet />
</div>
</div>
);
};

export default Layout;
10 changes: 10 additions & 0 deletions Admin/src/components/ProtectedRoute.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { useContext } from 'react';
import { Navigate } from 'react-router-dom';
import { StoreContext } from '../context/StoreContext';

const ProtectedRoute = ({ children }) => {
const { isAuthenticated } = useContext(StoreContext);
return isAuthenticated ? children : <Navigate to="/login" />;
};

export default ProtectedRoute;
34 changes: 33 additions & 1 deletion Admin/src/components/Sidebar/Sidebar.css
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,30 @@
padding: 8px;
}

.sidebar-option.active{
.sidebar-option.active {
background-color: rgba(255, 255, 255, 0.9);
color: #7bae37;
border-top-right-radius: 50px;
border-bottom-right-radius: 50px;
transition: background-color 1s ease 0s;
}

.logout-button {
padding: 10px;
background-color: white;
border: none;
border-radius: 20px;
cursor: pointer;
color: #7bae37;
font-size: 16px;
transition: background-color 0.3s ease;
margin: 20px 10px;
width: calc(100% - 20px);
}

.logout-button:hover {
background-color: #5c8a28;
}

.navbar {
display: none;
Expand Down Expand Up @@ -134,4 +150,20 @@
padding: 8px;
}

.logout-button {
padding: 10px;
background-color: white;
border: none;
border-radius: 20px;
cursor: pointer;
color: #7bae37;
font-size: 16px;
transition: background-color 0.3s ease;
margin: 20px 10px;
width: calc(100% - 20px);
}

.logout-button:hover {
background-color: #5c8a28;
}
}
47 changes: 36 additions & 11 deletions Admin/src/components/Sidebar/Sidebar.jsx
Original file line number Diff line number Diff line change
@@ -1,59 +1,84 @@
import React, { useState } from "react";
import React, { useContext, useState } from "react";
import "./Sidebar.css";
import { IoIosAddCircle } from "react-icons/io";
import { FaListAlt, FaShoppingCart,FaRegMoneyBillAlt } from "react-icons/fa";
import { FaListAlt, FaShoppingCart, FaRegMoneyBillAlt } from "react-icons/fa";
import { assets } from "../../assets/assets";
import { NavLink } from "react-router-dom";
import { NavLink, useNavigate } from "react-router-dom";
import { StoreContext } from "../../context/StoreContext";

const Sidebar = () => {
const [isOpen, setIsOpen] = useState(false);
const { isAuthenticated, setToken, setIsAuthenticated } = useContext(StoreContext);
const navigate = useNavigate();

const toggleSidebar = () => {
setIsOpen(!isOpen);
};

const handleLogout = () => {
localStorage.removeItem("token");
setToken("");
setIsAuthenticated(false);
navigate("/login");
};

return (
<>
<div className="sidebar">
<img src={assets.whitelogo} alt="" className="logo" />
<div className="sidebar-options">
<NavLink to='/add' className="sidebar-option">
<NavLink to="/add" className="sidebar-option">
<IoIosAddCircle className="icon" />
<p>Add Items</p>
</NavLink>
<NavLink to='/list' className="sidebar-option">
<NavLink to="/list" className="sidebar-option">
<FaListAlt className="icon" />
<p>List Items</p>
</NavLink>
<NavLink to='/order' className="sidebar-option">
<NavLink to="/order" className="sidebar-option">
<FaShoppingCart className="icon" />
<p>Display Orders</p>
</NavLink>
<NavLink to='/promo' className="sidebar-option">
<FaRegMoneyBillAlt className="icon" />
<NavLink to="/promo" className="sidebar-option">
<FaRegMoneyBillAlt className="icon" />
<p>Promo Code</p>
</NavLink>
</div>
{isAuthenticated && (
<button className="logout-button" onClick={handleLogout}>
Logout
</button>
)}
</div>
<div className="navbar">
<img src={assets.whitelogo} alt="" className="navbar-logo" />
<button className="toggle-button" onClick={toggleSidebar}>
</button>
<div className={`navbar-options ${isOpen ? "show" : ""}`}>
<NavLink to='/add' className="navbar-option">
<NavLink to="/add" className="navbar-option">
<IoIosAddCircle className="icon" />
<p>Add Items</p>
</NavLink>
<NavLink to='/list' className="navbar-option">
<NavLink to="/list" className="navbar-option">
<FaListAlt className="icon" />
<p>List Items</p>
</NavLink>
<NavLink to='/order' className="navbar-option">
<NavLink to="/order" className="navbar-option">
<FaShoppingCart className="icon" />
<p>Display Orders</p>
</NavLink>
<NavLink to="/promo" className="navbar-option">
<FaRegMoneyBillAlt className="icon" />
<p>Promo Code</p>
</NavLink>
{isAuthenticated && (
<button className="logout-button" onClick={handleLogout}>
Logout
</button>
)}
</div>

</div>
</>
);
Expand Down
32 changes: 32 additions & 0 deletions Admin/src/context/StoreContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { createContext, useEffect, useState } from "react";

export const StoreContext = createContext(null);

const StoreContextProvider = (props) => {
const [token, setToken] = useState("");
const [isAuthenticated, setIsAuthenticated] = useState(false);

useEffect(() => {
const savedToken = localStorage.getItem("token");
if (savedToken) {
setToken(savedToken);
setIsAuthenticated(true);
}
else{
setIsAuthenticated(false);
}
}, []);

return (
<StoreContext.Provider value={{
token,
setToken,
isAuthenticated,
setIsAuthenticated
}}>
{props.children}
</StoreContext.Provider>
);
};

export default StoreContextProvider;
23 changes: 14 additions & 9 deletions Admin/src/main.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { BrowserRouter } from 'react-router-dom'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import './index.css'

import React from 'react';
import { BrowserRouter } from 'react-router-dom';
import { createRoot } from 'react-dom/client';
import App from './App.jsx';
import StoreContextProvider from './context/StoreContext.jsx';
import './index.css';

createRoot(document.getElementById('root')).render(
<BrowserRouter>
<App />
</BrowserRouter>,
)
<React.StrictMode>
<StoreContextProvider>
<BrowserRouter>
<App />
</BrowserRouter>
</StoreContextProvider>
</React.StrictMode>,
);
Loading

0 comments on commit b4afaad

Please sign in to comment.