fcsc_ipi_frontend/ipi-survey-platform/src/components/layout/HeaderBar.jsx
2025-10-29 15:39:30 +05:30

186 lines
8.2 KiB
JavaScript

import React from 'react';
import { NavLink, useNavigate } from 'react-router-dom';
import Logo from '../../assets/images/fcsclogo.svg';
import SurveyIconActive from '../../assets/images/vector.svg';
import SurveyIconInactive from '../../assets/images/vectorblack.svg';
import DashboardIconActive from '../../assets/images/cuida_dashboard-outline.svg';
import DashboardIconInactive from '../../assets/images/cuida_dashboard-outline-inactive.svg';
import HistoryIconActive from '../../assets/images/mdi_history.svg';
import HistoryIconInactive from '../../assets/images/history.svg';
const HeaderBar = () => {
const [open, setOpen] = React.useState(false);
const [userOpen, setUserOpen] = React.useState(false);
const [userName, setUserName] = React.useState('User');
const [userEmail, setUserEmail] = React.useState('');
const navigate = useNavigate();
React.useEffect(() => {
let parsed;
try {
const stored = sessionStorage.getItem('user_profile');
if (stored) {
parsed = JSON.parse(stored);
}
} catch (error) {
parsed = undefined;
}
const name = parsed?.name || parsed?.username || parsed?.email || '';
const email = parsed?.email || '';
if (name) {
setUserName(name);
}
if (email) {
setUserEmail(email);
}
}, []);
const onLogout = () => {
try {
sessionStorage.removeItem('auth_token');
sessionStorage.removeItem('user_profile');
sessionStorage.removeItem('user_role');
sessionStorage.removeItem('establishment_id');
} catch {}
setUserOpen(false);
navigate('/login');
};
const onChangePassword = () => {
setUserOpen(false);
navigate('/reset-password');
};
const initials = React.useMemo(() => {
const source = userName || userEmail;
if (!source) return 'U';
const parts = source.trim().split(' ');
const letters = parts.slice(0, 2).map((part) => part.charAt(0)).join('');
return letters ? letters.toUpperCase() : 'U';
}, [userEmail, userName]);
return (
<header className="bg-white border-b border-b-[#E2E8F0]">
<div className="max-w-[1280px] mx-auto px-4">
<div className="flex items-center justify-between h-16">
<img src={Logo} alt="FCSC" className="w-[131px] h-[40px] opacity-100 rotate-0" />
<nav className="hidden md:flex items-center gap-8 text-[14px] leading-5">
<NavLink
to="/dashboard"
className={({ isActive }) => `inline-flex items-center gap-2 pb-1 border-b-2 ${isActive ? 'text-[#92722A] font-medium border-[#92722A]' : 'text-[#232528] hover:text-gray-900 border-transparent'}`}
aria-current="page"
>
{({ isActive }) => (
<>
<img src={isActive ? DashboardIconActive : DashboardIconInactive} alt="Dashboard" className="h-[18px] w-[18px]" />
<span>Dashboard</span>
</>
)}
</NavLink>
<NavLink
to="/survey"
className={({ isActive }) => `inline-flex items-center gap-2 pb-1 border-b-2 ${isActive ? 'text-[#92722A] font-medium border-[#92722A]' : 'text-[#232528] hover:text-gray-900 border-transparent'}`}
>
{({ isActive }) => (
<>
<img src={isActive ? SurveyIconActive : SurveyIconInactive} alt="Survey" className="h-[18px] w-[18px]" />
<span>Survey</span>
</>
)}
</NavLink>
<NavLink
to="/history"
className={({ isActive }) => `inline-flex items-center gap-2 pb-1 border-b-2 ${isActive ? 'text-[#92722A] font-medium border-[#92722A]' : 'text-[#232528] hover:text-gray-900 border-transparent'}`}
>
{({ isActive }) => (
<>
<img src={isActive ? HistoryIconActive : HistoryIconInactive} alt="History" className="h-[18px] w-[18px]" />
<span>History</span>
</>
)}
</NavLink>
<div className="relative">
<button
type="button"
onClick={() => setUserOpen((v) => !v)}
className="h-8 w-8 rounded-full bg-gray-200 grid place-items-center text-[12px] text-gray-700 cursor-pointer"
aria-label="Profile"
>
{initials}
</button>
{userOpen && (
<div className="absolute right-0 mt-3 w-48 rounded-lg border border-[#E2E8F0] bg-white shadow-lg z-50">
<div className="px-4 py-3 border-b border-[#F1F5F9] text-center space-y-0.5">
<p className="text-sm font-semibold text-[#232528] truncate" title={userName}>{userName}</p>
{userEmail && <p className="text-xs text-[#64748B] truncate" title={userEmail}>{userEmail}</p>}
</div>
<button
type="button"
onClick={onChangePassword}
className="w-full px-4 py-2.5 text-center text-sm text-[#232528] hover:bg-[#F2ECCF] transition-colors"
>
Change Password
</button>
<button
type="button"
onClick={onLogout}
className="w-full px-4 py-2.5 text-center text-sm text-[#B91C1C] hover:bg-[#FEE2E2] transition-colors"
>
Logout
</button>
</div>
)}
</div>
</nav>
<button
type="button"
aria-label="Open Menu"
className="md:hidden inline-flex items-center justify-center h-9 w-9 rounded hover:bg-gray-100"
onClick={() => setOpen((v) => !v)}
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 12h16M4 18h16" />
</svg>
</button>
</div>
{open && (
<div className="md:hidden pb-3">
<nav className="flex flex-col gap-2 text-[14px] leading-5">
<NavLink to="/dashboard" onClick={() => setOpen(false)} className={({ isActive }) => `inline-flex items-center gap-2 px-2 py-2 rounded border-b-2 ${isActive ? 'text-[#92722A] bg-[#F2ECCF] border-[#92722A]' : 'text-[#232528] hover:bg-gray-100 border-transparent'}`}>
<img src={DashboardIconInactive} alt="Dashboard" className="h-[18px] w-[18px]" />
<span>Dashboard</span>
</NavLink>
<NavLink to="/survey" onClick={() => setOpen(false)} className={({ isActive }) => `inline-flex items-center gap-2 px-2 py-2 rounded border-b-2 ${isActive ? 'text-[#92722A] bg-[#F2ECCF] border-[#92722A]' : 'text-[#232528] hover:bg-gray-100 border-transparent'}`}>
<img src={SurveyIconInactive} alt="Survey" className="h-[18px] w-[18px]" />
<span>Survey</span>
</NavLink>
<NavLink to="/history" onClick={() => setOpen(false)} className={({ isActive }) => `inline-flex items-center gap-2 px-2 py-2 rounded border-b-2 ${isActive ? 'text-[#92722A] bg-[#F2ECCF] border-[#92722A]' : 'text-[#232528] hover:bg-gray-100 border-transparent'}`}>
<img src={HistoryIconInactive} alt="History" className="h-[18px] w-[18px]" />
<span>History</span>
</NavLink>
<button
type="button"
onClick={() => {
setOpen(false);
navigate('/reset-password');
}}
className="inline-flex items-center gap-2 px-2 py-2 rounded text-[#232528] hover:bg-gray-100 text-left"
>
<span>Change Password</span>
</button>
<button
type="button"
onClick={onLogout}
className="inline-flex items-center gap-2 px-2 py-2 rounded text-[#232528] hover:bg-gray-100 text-left"
>
<span>Logout</span>
</button>
</nav>
</div>
)}
</div>
</header>
);
};
export default HeaderBar;