import { NavLink, useNavigate } from 'react-router'; import { useTranslation } from 'react-i18next'; import { Icon, type IconName } from '../common/Icon'; import { useAppDispatch } from '../../hooks/useAppDispatch'; import { usePermissions, type Permission } from '../../hooks/usePermissions'; import { useConnectionStatusSync } from '../../hooks/useConnectionStatus'; import { logout } from '../../store/slices/auth'; import { useGetPlaylistsQuery } from '../../api/endpoints/playlists'; import { getActiveInstance } from '../../config/instances'; interface NavDef { to: string; labelKey: string; icon: IconName; end?: boolean; /** Hide this item unless the user holds the permission. */ perm?: Permission; } const MAIN_NAV: NavDef[] = [ { to: '/library', labelKey: 'nav.library', icon: 'vinyl-record' }, { to: '/discover', labelKey: 'nav.search', icon: 'magnifying-glass', perm: 'download' }, { to: '/downloads', labelKey: 'nav.downloads', icon: 'arrow-circle-down', perm: 'download' }, { to: '/upload', labelKey: 'nav.upload', icon: 'upload-simple', perm: 'upload' }, { to: '/storage', labelKey: 'nav.storage', icon: 'hard-drives' }, ]; const CONN_KEY: Record = { connected: { cls: 'online', txtKey: 'conn.connected' }, connecting: { cls: 'syncing', txtKey: 'conn.connecting' }, disconnected: { cls: 'offline', txtKey: 'conn.disconnected' }, error: { cls: 'error', txtKey: 'conn.error' }, }; function navClass({ isActive }: { isActive: boolean }) { return isActive ? 'nav-item active' : 'nav-item'; } export function Sidebar() { const { t } = useTranslation(); const dispatch = useAppDispatch(); const navigate = useNavigate(); const { user, isAdmin, hasPermission } = usePermissions(); const status = useConnectionStatusSync(); const { data: playlists } = useGetPlaylistsQuery(); const instance = getActiveInstance(); const conn = CONN_KEY[status] ?? CONN_KEY.connecting; const online = status === 'connected'; const handleLogout = (e: React.MouseEvent) => { e.stopPropagation(); dispatch(logout()); void navigate('/connect'); }; return ( ); }