119 lines
3.4 KiB
TypeScript
119 lines
3.4 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { Search, Bell, Clock, LogOut, Home, ArrowLeft } from 'lucide-react';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { logout } from '../utils/auth';
|
|
import './TopBar.css';
|
|
|
|
export const TopBar: React.FC = () => {
|
|
const [time, setTime] = useState(new Date());
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
const timer = setInterval(() => setTime(new Date()), 1000);
|
|
return () => clearInterval(timer);
|
|
}, []);
|
|
|
|
const handleLogout = () => {
|
|
logout();
|
|
};
|
|
|
|
const user = React.useMemo(() => {
|
|
try {
|
|
const stored = localStorage.getItem('teleems_user');
|
|
if (!stored || stored === 'undefined' || stored === 'null') return {};
|
|
const parsed = JSON.parse(stored);
|
|
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
} catch {
|
|
return {};
|
|
}
|
|
}, []);
|
|
|
|
const displayName = String(user.username || 'Admin');
|
|
const rawRole = Array.isArray(user.roles) ? (user.roles[0] || 'Administrator') : 'Administrator';
|
|
|
|
const roleLabel = rawRole
|
|
.replace(/_/g, ' ')
|
|
.replace('CURESELECT ADMIN', 'CS ADMIN')
|
|
.replace('HOSPITAL ADMIN', 'H. ADMIN')
|
|
.replace('FLEET OPERATOR', 'FLEET OPS')
|
|
.replace('STATION INCHARGE', 'STATION IC');
|
|
|
|
const initials = displayName.substring(0, 2).toUpperCase() || 'AD';
|
|
|
|
const formattedTime = time.toLocaleTimeString('en-US', {
|
|
hour12: false,
|
|
timeZone: 'Asia/Kolkata',
|
|
hour: '2-digit',
|
|
minute: '2-digit'
|
|
});
|
|
|
|
const tzLabel = 'IST';
|
|
|
|
return (
|
|
<header className="topbar-container">
|
|
<div className="topbar-left">
|
|
<div className="nav-actions">
|
|
<button
|
|
onClick={() => navigate(-1)}
|
|
className="nav-btn"
|
|
title="Go Back"
|
|
>
|
|
<ArrowLeft size={16} />
|
|
<span>BACK</span>
|
|
</button>
|
|
|
|
<button
|
|
onClick={() => navigate('/')}
|
|
className="nav-btn home"
|
|
title="Return Home"
|
|
>
|
|
<Home size={16} />
|
|
<span>HOME</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div className="search-wrap">
|
|
<Search size={14} className="search-icon" style={{ position: 'absolute', left: '12px', top: '50%', transform: 'translateY(-50%)', opacity: 0.5 }} />
|
|
<input
|
|
type="text"
|
|
placeholder="Search resources..."
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="topbar-right">
|
|
<div className="clock-wrap">
|
|
<Clock size={14} />
|
|
<span className="clock-time">
|
|
{formattedTime} <small style={{ fontSize: '0.6rem', opacity: 0.6 }}>{tzLabel}</small>
|
|
</span>
|
|
</div>
|
|
|
|
<div className="notification-bell">
|
|
<Bell size={18} />
|
|
<div className="bell-badge">3</div>
|
|
</div>
|
|
|
|
<div style={{ height: '20px', width: '1px', background: 'var(--card-border)' }} />
|
|
|
|
<div
|
|
className="user-profile"
|
|
onClick={handleLogout}
|
|
title="Click to logout"
|
|
>
|
|
<div className="avatar-circle">
|
|
{initials}
|
|
</div>
|
|
|
|
<div className="user-info">
|
|
<span className="user-name">{displayName}</span>
|
|
<span className="user-role">{roleLabel} • Logout</span>
|
|
</div>
|
|
|
|
<LogOut size={14} style={{ opacity: 0.5 }} />
|
|
</div>
|
|
</div>
|
|
</header>
|
|
);
|
|
};
|