import { useState, useRef, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { AppBar, Toolbar, IconButton, Box, InputBase, Avatar, Typography, Stack, Menu, MenuItem, Divider, ListItemIcon, Popper, Paper, ClickAwayListener, CircularProgress, alpha } from '@mui/material'; import MenuIcon from '@mui/icons-material/Menu'; import SearchIcon from '@mui/icons-material/Search'; import SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined'; import LogoutIcon from '@mui/icons-material/Logout'; import Logo from '@/components/Logo'; import UserAvatar from '@/components/UserAvatar'; import { fetchClients, fetchUsers } from '@/utils/apiClient'; import { toClient } from '@/utils/mappers'; const RED = '#C01227'; export default function Header({ onToggle }) { const navigate = useNavigate(); const [account, setAccount] = useState(null); const [search, setSearch] = useState(''); // Read user from localStorage let storedUserObj = { name: 'Admin', role: 'Operations Admin', id: 0 }; try { const storedUser = localStorage.getItem('user'); if (storedUser) { storedUserObj = JSON.parse(storedUser); } } catch(e) {} const [activeUserName, setActiveUserName] = useState(storedUserObj.name || 'Admin'); const displayRole = storedUserObj.role === 'admin' ? 'Administrator' : storedUserObj.role === 'manager' ? 'Manager' : storedUserObj.role === 'executive' ? 'Executive' : 'Operations Admin'; const displayInitial = activeUserName.charAt(0).toUpperCase(); const searchRef = useRef(null); const [clients, setClients] = useState([]); const [loadedClients, setLoadedClients] = useState(false); const [loadingClients, setLoadingClients] = useState(false); const [openResults, setOpenResults] = useState(false); // Fetch users to get the real name if the login payload didn't have it useEffect(() => { fetchUsers().then((users) => { if (storedUserObj.email) { // Strictly use email to match, as stored ID might belong to the doormile_auth table instead of appusers table const matchingUser = users.find(u => u.email === storedUserObj.email); if (matchingUser && matchingUser.first_name) { setActiveUserName(matchingUser.first_name); // Also update localStorage so it's fresh const updatedUser = { ...storedUserObj, name: matchingUser.first_name }; localStorage.setItem('user', JSON.stringify(updatedUser)); } } }).catch(console.error); }, []); const ensureClients = () => { if (loadedClients || loadingClients) return; setLoadingClients(true); fetchClients() .then((points) => setClients(points.map(toClient))) .catch(() => {}) .finally(() => { setLoadedClients(true); setLoadingClients(false); }); }; const q = search.trim().toLowerCase(); const results = q ? clients.filter((c) => [c.name, c.city, c.businessType, c.phone].join(' ').toLowerCase().includes(q)).slice(0, 6) : []; const onSearchChange = (e) => { setSearch(e.target.value); ensureClients(); setOpenResults(true); }; const goToClients = (term) => { navigate(`/tenants?q=${encodeURIComponent(term)}`); setSearch(''); setOpenResults(false); }; const submitSearch = (e) => { e.preventDefault(); const term = search.trim(); if (term) goToClients(term); }; return ( t.zIndex.drawer + 1, borderBottom: 1, borderColor: 'divider' }} > navigate('/dashboard')} sx={{ display: 'flex', alignItems: 'center', cursor: 'pointer' }} > setOpenResults(false)}> { ensureClients(); if (search.trim()) setOpenResults(true); }} placeholder="Search clients…" sx={{ color: 'grey.800', fontSize: '0.875rem', flex: 1, '&::placeholder': { color: 'grey.500' } }} inputProps={{ 'aria-label': 'search' }} /> {loadingClients && results.length === 0 ? ( ) : results.length === 0 ? ( No clients match “{search.trim()}”. ) : ( <> {results.map((c) => ( goToClients(c.name)} sx={{ py: 1, gap: 1.25 }}> {c.name} {[c.businessType, c.city].filter(Boolean).join(' · ') || c.phone} ))} goToClients(search.trim())} sx={{ py: 1.25, color: 'primary.main', fontWeight: 600 }}> See all results for “{search.trim()}” )} setAccount(e.currentTarget)} sx={{ display: 'flex', alignItems: 'center', gap: 1, ml: 0.5, cursor: 'pointer', py: 0.5, px: 0.5, borderRadius: 2, '&:hover': { bgcolor: 'grey.100' } }} > {displayInitial} {activeUserName} {displayRole} setAccount(null)} transformOrigin={{ horizontal: 'right', vertical: 'top' }} anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }} PaperProps={{ sx: { mt: 1, minWidth: 220 } }} > {displayInitial} {activeUserName} {displayRole} { setAccount(null); navigate('/settings'); }}> Settings { setAccount(null); localStorage.removeItem('auth_token'); navigate('/login'); }} sx={{ color: 'error.main' }}> Logout ); }