import type { LucideIcon } from 'lucide-react'; import { NavLink } from 'react-router'; import { Archive, Compass, Heart, Images, Map as MapIcon, Plug, Search, Share2, Trash2, Users } from 'lucide-react'; import { AccountSwitcher } from './AccountSwitcher'; import { PHOTOS_SECTIONS, photosSectionPath, type PhotosSectionId } from './shared'; import { useAssetStats } from './usePhotosData'; // Left panel of the /photos workspace, mirroring Immich's own sidebar: library sections up top, the sharing // and cleanup ones below a divider, and the library size at the bottom. // // Sections are react-router NavLinks to /photos/
— active state from the router, cmd-click works. const ICONS: Record = { timeline: Images, explore: Compass, map: MapIcon, search: Search, albums: Images, people: Users, favorites: Heart, archive: Archive, sharing: Share2, trash: Trash2, settings: Plug, }; // Immich draws the same line: browsing the library, then everything else. const LIBRARY: PhotosSectionId[] = ['timeline', 'explore', 'map', 'search', 'albums', 'people', 'favorites']; const ROW = 'group relative flex items-center gap-3 rounded-lg px-3 py-2 text-left text-sm transition-colors'; export const PhotosNav = () => { const { data: stats } = useAssetStats(); const group = (ids: PhotosSectionId[]) => PHOTOS_SECTIONS.filter((section) => ids.includes(section.id)).map(({ id, label }) => { const Icon = ICONS[id]; return ( `${ROW} ${ isActive ? 'bg-primary/10 font-medium text-primary' : 'text-muted-foreground hover:bg-muted hover:text-foreground' }` } > {({ isActive }) => ( <> {isActive && ( )} {label} )} ); }); const rest = PHOTOS_SECTIONS.map((section) => section.id).filter((id) => !LIBRARY.includes(id)); return (
Photos
{stats && (

{stats.total.toLocaleString()} items

{stats.images.toLocaleString()} photos · {stats.videos.toLocaleString()} videos

)}
); };