1- NAVIGATION - NavBar.tsx
import React, { useState } from "react";
import { BrowserRouter as Router, Routes, Route, Navigate, useLocation, useNavigate } from "react-router-dom";
import "bootstrap/dist/css/bootstrap.min.css";
import "@fortawesome/fontawesome-free/css/all.min.css";
// Component imports
import AddEmployee from "./components/AddEnployee";
import EmployeeList from "./components/EmployeeList";
import EditEmployee from "./components/EditEmployee";
import NaviBar from "./components/NaviBar";
import Login from "./components/Login";
import PrivateRoute from "./components/PrivateRoute";
import Unauthorized from "./components/Unauthorized";
import AdminDashboard from './components/AdminDashBoard';
import ManagerDashboard from './components/ManagerDashboard';
import ReceptionistDashboard from './components/ReceptionistDashboard';
// Main application content component
const AppContent: React.FC = () => {
// State management for user authentication
const [userName, setUserName] = useState<string>(
// Initialize userName from localStorage or empty string
() => localStorage.getItem("userName") || ""
);
// Assume user is logged in initially (might need adjustment)
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(true);
// Router hooks
const location = useLocation(); // Gets current route location
const showHeader = location.pathname !== "/login"; // Hide header on login page
const navigate = useNavigate(); // Programmatic navigation
// Logout handler function
const handleLogout = () => {
localStorage.clear(); // Clear all client-side storage
setIsLoggedIn(false); // Update auth state
setUserName(""); // Clear username
navigate("/login"); // Redirect to login
};
return (
<>
{/* Conditional header rendering */}
{showHeader && <NaviBar userName={userName} onLogout={handleLogout} />}
{/* Main content container */}
<div className="container mt-4">
{/* Route configuration */}
<Routes>
{/* Public routes */}
{/* Login route with success callback */}
<Route
path="/login"
element={
<Login onLoginSuccess={(username) => {
setUserName(username);
setIsLoggedIn(true);
navigate('/list'); // Redirect after login
}}
/>
}
/>
{/* Unauthorized access route */}
<Route path="/unauthorized" element={<Unauthorized />} />
{/* Role-protected routes */}
{/* Admin route (role 1) */}
<Route
path="/admin"
element={
<PrivateRoute allowedRoles={['1']}>
<AdminDashboard />
</PrivateRoute>
}
/>
{/* Manager route (role 2) */}
<Route
path="/manager"
element={
<PrivateRoute allowedRoles={['2']}>
<ManagerDashboard />
</PrivateRoute>
}
/>
{/* Receptionist route (role 3) */}
<Route
path="/receptionist"
element={
<PrivateRoute allowedRoles={['3']}>
<ReceptionistDashboard />
</PrivateRoute>
}
/>
{/* Employee list route (protected but no specific role required) */}
<Route
path="/list"
element={
<PrivateRoute>
<EmployeeList />
</PrivateRoute>
}
/>
{/* Add employee route */}
<Route
path="/add"
element={
<PrivateRoute>
<AddEmployee />
</PrivateRoute>
}
/>
{/* Edit employee route (dynamic parameter) */}
<Route
path="/edit/:empId"
element={
<PrivateRoute>
<EditEmployee />
</PrivateRoute>
}
/>
{/* Catch-all route for unknown paths */}
<Route path="*" element={<Navigate to="/unauthorized" replace />} />
</Routes>
</div>
</>
);
};
// Main App component with Router wrapper
const App: React.FC = () => (
<Router>
<AppContent />
</Router>
);
export default App;
Key Architecture and Decisions:
Authentication Flow:
Uses localStorage for persistent user session
Implements login/logout state management
Assumes initial logged-in state (may need adjustment)
Routing Structure:
Public routes (login, unauthorized)
Role-protected routes (admin, manager, receptionist)
General protected routes (employee list, add/edit)
404-style catch-all route
Security:
PrivateRoute component guards protected routes
Role-based access control via allowedRoles prop
Automatic cleanup on logout (localStorage.clear())
UI Decisions:
Conditional header rendering
Bootstrap styling framework
Font Awesome icons
Consistent container layout
Navigation:
Programmatic navigation after login/logout
Route parameters for dynamic paths (edit/:empId)
Replace navigation to prevent back-button issues
No comments:
Post a Comment