import { useState, useRef, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { ChevronRight, Search, Bell, ChevronDown, Menu, LogOut, User } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { useAppDispatch, useAppSelector } from '@/hooks/redux-hooks'; import { logoutAsync } from '@/store/authSlice'; import { cn } from '@/lib/utils'; import { showToast } from '@/utils/toast'; import type { ReactElement } from 'react'; interface HeaderProps { breadcrumbs?: Array<{ label: string; path?: string }>; currentPage: string; onMenuClick?: () => void; } export const Header = ({ breadcrumbs, currentPage, onMenuClick }: HeaderProps): ReactElement => { const navigate = useNavigate(); const dispatch = useAppDispatch(); const { user, isLoading,roles } = useAppSelector((state) => state.auth); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const dropdownRef = useRef(null); // Get user initials for avatar const getUserInitials = (): string => { if (user?.first_name && user?.last_name) { return `${user.first_name[0]}${user.last_name[0]}`.toUpperCase(); } if (user?.email) { return user.email[0].toUpperCase(); } return 'A'; }; // Get user display name const getUserDisplayName = (): string => { if (user?.first_name && user?.last_name) { return `${user.first_name} - ${roles[0] || 'N/A'}`; } return user?.email?.split('@')[0] || 'Admin'; }; // Handle click outside to close dropdown useEffect(() => { const handleClickOutside = (event: MouseEvent) => { const target = event.target as Node; // Check if click is outside the dropdown container if (dropdownRef.current && !dropdownRef.current.contains(target)) { setIsDropdownOpen(false); } }; if (isDropdownOpen) { // Use mousedown instead of click to avoid interfering with button clicks // Add listener in bubble phase (not capture) so button clicks fire first document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isDropdownOpen]); // Handle logout const handleLogout = async (e: React.MouseEvent): Promise => { e.preventDefault(); e.stopPropagation(); // Close dropdown immediately setIsDropdownOpen(false); // Check if user is on a tenant route to determine redirect path const isTenantRoute = window.location.pathname.startsWith('/tenant'); const redirectPath = isTenantRoute ? '/tenant/login' : '/'; try { // Call logout API with Bearer token const result = await dispatch(logoutAsync()).unwrap(); const message = result.message || 'Logged out successfully'; const description = result.message ? undefined : 'You have been logged out'; showToast.success(message, description); // Clear state and redirect to appropriate login page navigate(redirectPath, { replace: true }); } catch (error: any) { // Even if API call fails, clear local state and redirect to login console.error('Logout error:', error); // Try to get message from error response const message = error?.message || 'Logged out successfully'; const description = error?.message ? undefined : 'You have been logged out'; // Dispatch logout action to clear local state dispatch({ type: 'auth/logout' }); showToast.success(message, description); navigate(redirectPath, { replace: true }); } }; return (
{/* Left Side - Menu Button (Mobile) + Breadcrumbs */}
{/* Mobile Menu Button */} {/* Breadcrumbs */}
{/* Right Side */}
{/* Desktop User Dropdown */}
{/* Dropdown Menu */} {isDropdownOpen && (
e.stopPropagation()} > {/* User Info Section */}

{getUserDisplayName()}

{user?.email}

{/* Logout Button */}
)}
{/* Mobile User Avatar */}
{/* Mobile Dropdown Menu */} {isDropdownOpen && (
e.stopPropagation()} > {/* User Info Section */}

{getUserDisplayName()}

{user?.email}

{/* Logout Button */}
)}
); };