// src/components/Header.jsx import React, { useState, useEffect, useRef } from 'react'; import { NavLink, useNavigate } from 'react-router-dom'; import LanguageSelector from './LanguageSelector'; import { useTranslation } from '../js/i18n'; import logo from '/assets/logo.png'; function Header() { const { t } = useTranslation(); const navigate = useNavigate(); const [user, setUser] = useState(null); const [menuOpen, setMenuOpen] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); const menuRef = useRef(null); // Check for user on component mount and localStorage changes useEffect(() => { const checkUser = () => { try { const userData = localStorage.getItem('user'); if (userData) { setUser(JSON.parse(userData)); } else { setUser(null); } } catch (error) { console.error('Failed to parse user data'); setUser(null); } }; checkUser(); // Listen for storage events (in case user logs in/out in another tab) window.addEventListener('storage', checkUser); return () => window.removeEventListener('storage', checkUser); }, []); const toggleMenu = () => { setMenuOpen(!menuOpen); }; useEffect(() => { const handleClickOutside = (event) => { if (menuRef.current && !menuRef.current.contains(event.target)) { setMenuOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [menuRef]); const handleLogout = () => { localStorage.removeItem('user'); setUser(null); navigate('/login'); setMobileMenuOpen(false); }; const toggleMobileMenu = () => { setMobileMenuOpen(!mobileMenuOpen); }; const handleNavClick = () => { setMobileMenuOpen(false); }; // 添加键盘导航支持 const handleKeyDown = (e) => { if (e.key === 'Escape') { setMenuOpen(false); setMobileMenuOpen(false); } }; // 添加焦点管理 useEffect(() => { const handleFocusTrap = (e) => { if (!mobileMenuOpen) return; const mobileMenu = document.querySelector('[role="dialog"]'); const focusableElements = mobileMenu.querySelectorAll( 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])' ); const firstElement = focusableElements[0]; const lastElement = focusableElements[focusableElements.length - 1]; if (e.key === 'Tab') { if (e.shiftKey && document.activeElement === firstElement) { e.preventDefault(); lastElement.focus(); } else if (!e.shiftKey && document.activeElement === lastElement) { e.preventDefault(); firstElement.focus(); } } }; document.addEventListener('keydown', handleKeyDown); document.addEventListener('keydown', handleFocusTrap); return () => { document.removeEventListener('keydown', handleKeyDown); document.removeEventListener('keydown', handleFocusTrap); }; }, [mobileMenuOpen]); // 处理滚动锁定 useEffect(() => { if (mobileMenuOpen) { document.body.style.overflow = 'hidden'; } else { document.body.style.overflow = ''; } return () => { document.body.style.overflow = ''; }; }, [mobileMenuOpen]); return (
); } export default Header;