import { useState, useMemo } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; import { Home, Bell, Search, Clapperboard, BarChart3, Palette, PartyPopper, User, Settings, Bookmark, UserPlus, LogOut, Check, Moon, Sun, Cat, Heart, ChevronDown } from 'lucide-react'; import { ChestIcon } from '@/components/icons/ChestIcon'; import { Button } from '@/components/ui/button'; import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, DropdownMenuLabel, DropdownMenuSeparator } from '@/components/ui/dropdown-menu'; import { MewLogo } from '@/components/MewLogo'; import { ProfileSearchDropdown } from '@/components/ProfileSearchDropdown'; import LoginDialog from '@/components/auth/LoginDialog'; import SignupDialog from '@/components/auth/SignupDialog'; import { useCurrentUser } from '@/hooks/useCurrentUser'; import { useLoggedInAccounts, type Account } from '@/hooks/useLoggedInAccounts'; import { useLoginActions } from '@/hooks/useLoginActions'; import { useTheme } from '@/hooks/useTheme'; import { useFeedSettings } from '@/hooks/useFeedSettings'; import { EXTRA_KINDS } from '@/lib/extraKinds'; import { genUserName } from '@/lib/genUserName'; import { cn } from '@/lib/utils'; import type { Theme } from '@/contexts/AppContext'; interface NavItemProps { to: string; icon: React.ReactNode; label: string; active?: boolean; } function NavItem({ to, icon, label, active }: NavItemProps) { return ( {icon} {label} ); } export function LeftSidebar() { const location = useLocation(); const navigate = useNavigate(); const { user, metadata } = useCurrentUser(); const { currentUser, otherUsers, setLogin } = useLoggedInAccounts(); const { logout } = useLoginActions(); const { theme, setTheme } = useTheme(); const { feedSettings } = useFeedSettings(); const [loginDialogOpen, setLoginDialogOpen] = useState(false); const [signupDialogOpen, setSignupDialogOpen] = useState(false); const [accountPopoverOpen, setAccountPopoverOpen] = useState(false); /** Map route name → lucide icon (size-6 for sidebar). */ const ROUTE_ICONS: Record = { vines: , polls: , treasures: , colors: , packs: , }; const navItems = useMemo(() => { const items = [ { to: '/', icon: , label: 'Home' }, { to: '/notifications', icon: , label: 'Notifications' }, { to: '/search', icon: , label: 'Search' }, ]; // Add enabled extra-kind links from the shared config for (const def of EXTRA_KINDS) { if (feedSettings[def.showKey]) { items.push({ to: `/${def.route}`, icon: ROUTE_ICONS[def.route] ?? , label: def.label, }); } } items.push( { to: '/profile', icon: , label: 'Profile' }, { to: '/bookmarks', icon: , label: 'Bookmarks' }, { to: '/settings', icon: , label: 'Settings' }, ); return items; }, [feedSettings]); const getDisplayName = (account: Account): string => { return account.metadata.name ?? genUserName(account.pubkey); }; const handleLogin = () => { setLoginDialogOpen(false); setSignupDialogOpen(false); }; const handleLogout = async () => { // Close popover first to avoid state update on unmounted component setAccountPopoverOpen(false); // Wait for logout to complete before navigation await logout(); navigate('/'); }; const themes: { value: Theme; label: string; icon: React.ReactNode }[] = [ { value: 'dark', label: 'Mew', icon: }, { value: 'light', label: 'Light', icon: }, { value: 'black', label: 'Black', icon: }, { value: 'pink', label: 'Pink', icon: }, ]; return ( ); }