import {Link, NavLink, useLocation, useNavigate} from 'react-router-dom'; import {useTranslation} from 'react-i18next'; import {ChartColumn, Dices, Eye, Languages, LayoutDashboard, Library, LogOut, Megaphone, Moon, Settings, Shield, Sun} from 'lucide-react'; import {toast} from 'sonner'; import {Badge} from '@/components/ui/badge'; import {Button} from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import {usePreferences} from '@/context/PreferencesContext.jsx'; import {cn} from '@/lib/utils'; import Logo from './Logo.jsx'; import PageContainer from './PageContainer.jsx'; import SteamAvatar from './SteamAvatar.jsx'; import useCurrentUser from '../hooks/useCurrentUser.js'; import useSteamProfile from '../hooks/useSteamProfile.js'; import {ROLES, viewAs} from '../utils/admin.js'; import {expireSession, markSession} from '../utils/auth.js'; const NAV_ITEMS = [ {to: '/dashboard', labelKey: 'NAV.DASHBOARD', Icon: LayoutDashboard}, // The wishlist is a tab of the library. {to: '/library', labelKey: 'NAV.LIBRARY', Icon: Library, alsoActiveOn: ['/wishlist']}, {to: '/play-next', labelKey: 'NAV.PLAY_NEXT', Icon: Dices}, {to: '/stats', labelKey: 'NAV.STATS', Icon: ChartColumn}, ]; const navLinkClass = (isActive) => cn( 'flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors', isActive ? 'bg-accent text-accent-foreground' : 'text-muted-foreground hover:bg-muted hover:text-foreground', ); export default function AppHeader({isAuthenticated, onLogout}) { const {t, i18n} = useTranslation(); const {isDarkMode, setDarkMode, setLanguage} = usePreferences(); const {pathname} = useLocation(); const steamProfile = useSteamProfile(isAuthenticated); const currentUser = useCurrentUser(isAuthenticated); const navigate = useNavigate(); const isAdmin = currentUser?.role === 'PLATFORM_ADMIN'; const viewingAs = currentUser && currentUser.activeRole !== currentUser.role ? currentUser.activeRole : null; const switchRole = async (role) => { try { const response = await viewAs(role === currentUser.role ? null : role); if (response.ok) { // New cookies with the other role; the new stamp loads the user and the Steam data again. markSession(); navigate('/dashboard'); return; } if (response.status === 401) { expireSession(); return; } } catch (err) { console.error('View as error:', err); } toast.error(t('NAV.VIEW_AS.ERROR')); }; // Unsaved, the next login would switch back to Auth's language. const toggleLanguage = async () => { try { const response = await setLanguage(i18n.language === 'de' ? 'en' : 'de'); if (response && !response.ok) toast.error(t('SETTINGS.ERROR_SAVE')); } catch (err) { console.error('Language save error:', err); toast.error(t('INFO.ERROR.NETWORK_FAILURE')); } }; const toggleTheme = () => setDarkMode(!isDarkMode); const ThemeIcon = isDarkMode ? Sun : Moon; return (
{/* On a narrow phone the menu and buttons need the room; the logo alone stays. */} ToBePlayed {isAuthenticated && ( )}
{isAuthenticated && viewingAs && ( {t('NAV.VIEW_AS.BADGE', {role: t(`ROLES.${viewingAs}`)})} )} {isAuthenticated ? ( {t('NAV.SETTINGS')} {isAdmin && !viewingAs && ( <> {t('NAV.ADMIN')} {t('NAV.ADMIN_HINTS')} )} {isAdmin && ( {t('NAV.VIEW_AS.MENU')} {ROLES.map((role) => ( switchRole(role)}> {t(`ROLES.${role}`)} ))} )} {t('NAV.LANGUAGE')}: {i18n.language.toUpperCase()} {t(isDarkMode ? 'NAV.LIGHT_MODE' : 'NAV.DARK_MODE')} {t('MAIN.LOGOUT')} ) : ( <> )}
); }