186 lines
8.2 KiB
JavaScript
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;
|