import { useState } from 'react'; import { Link, useLocation } from 'react-router-dom'; import { Avatar, Badge, Box, Collapse, Divider, List, ListItem, ListItemAvatar, ListItemButton, ListItemIcon, ListItemText, Typography, } from '@mui/material'; import ExpandLess from '@mui/icons-material/ExpandLess'; import ExpandMore from '@mui/icons-material/ExpandMore'; import HomeOutlinedIcon from '@mui/icons-material/HomeOutlined'; import GroupsOutlinedIcon from '@mui/icons-material/GroupsOutlined'; import CategoryOutlinedIcon from '@mui/icons-material/CategoryOutlined'; import PersonOutlineOutlinedIcon from '@mui/icons-material/PersonOutlineOutlined'; import CollectionsBookmarkOutlinedIcon from '@mui/icons-material/CollectionsBookmarkOutlined'; import SettingsOutlinedIcon from '@mui/icons-material/SettingsOutlined'; import HelpOutlineOutlinedIcon from '@mui/icons-material/HelpOutlineOutlined'; import AdminPanelSettingsOutlinedIcon from '@mui/icons-material/AdminPanelSettingsOutlined'; import LogoutOutlinedIcon from '@mui/icons-material/LogoutOutlined'; import LoginOutlinedIcon from '@mui/icons-material/LoginOutlined'; import NotificationsOutlinedIcon from '@mui/icons-material/NotificationsOutlined'; import PeopleOutlineOutlinedIcon from '@mui/icons-material/PeopleOutlineOutlined'; import { useTranslation } from 'react-i18next'; import { useAuth } from '../../hooks/useAuth'; import { GlobalSearch } from '../../app/GlobalSearch'; import { NotificationMenu } from './NotificationMenu'; import { BrandMark } from './BrandMark'; export const NAV_SIDEBAR_WIDTH = 280; export interface NavSidebarProps { categories: { name: string; slug: string }[]; onNavigate?: () => void; showSearch?: boolean; showNotifications?: boolean; } export const NavSidebar = ({ categories, onNavigate, showSearch = false, showNotifications = false, }: NavSidebarProps) => { const { t } = useTranslation(); const location = useLocation(); const { user, following, logout } = useAuth(); // Categories are the primary browse axis — open by default so they're // discoverable without an extra click (UX audit #4). const [catOpen, setCatOpen] = useState(true); const [followingOpen, setFollowingOpen] = useState(false); const [notifAnchorEl, setNotifAnchorEl] = useState(null); const close = () => onNavigate?.(); const isActive = (path: string) => path === '/' ? location.pathname === '/' : location.pathname.startsWith(path); const unreadCount = user?.unread_notifications_count || 0; return ( {user ? ( {user.username.charAt(0).toUpperCase()} {user.username} {t('nav.profile')} ) : null} {showSearch && ( )} {user && ( )} {user && showNotifications && ( setNotifAnchorEl(e.currentTarget)}> )} setCatOpen(!catOpen)} selected={location.pathname.startsWith('/category/')} > {catOpen ? : } {categories.map((cat) => ( ))} {user && ( <> {user.is_superuser && ( <> )} {following.length > 0 && ( <> setFollowingOpen(!followingOpen)}> {t('nav.following')} {following.length} } /> {followingOpen ? : } {following.map((f) => ( {!f.avatar && f.username.charAt(0).toUpperCase()} ))} )} )} {!user && ( <> )} {user && ( { close(); logout(); }} > )} {showNotifications && ( setNotifAnchorEl(null)} onItemNavigate={close} anchorOrigin={{ vertical: 'center', horizontal: 'right' }} transformOrigin={{ vertical: 'center', horizontal: 'left' }} paperSx={{ ml: 1 }} /> )} ); };