import React, { useEffect } from 'react'; import { FileText, Clock, Home, Puzzle, History } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { SidebarContent, SidebarFooter, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarGroup, SidebarGroupContent, SidebarSeparator, } from '../ui/sidebar'; import { ChatSmart, Gear } from '../icons'; import { ViewOptions, View } from '../../App'; import { useChatContext } from '../../contexts/ChatContext'; import { DEFAULT_CHAT_TITLE } from '../../contexts/ChatContext'; interface SidebarProps { onSelectSession: (sessionId: string) => void; refreshTrigger?: number; children?: React.ReactNode; setIsGoosehintsModalOpen?: (isOpen: boolean) => void; setView?: (view: View, viewOptions?: ViewOptions) => void; currentPath?: string; } interface NavigationItem { type: 'item'; path: string; label: string; icon: React.ComponentType<{ className?: string }>; tooltip: string; } interface NavigationSeparator { type: 'separator'; } type NavigationEntry = NavigationItem | NavigationSeparator; const menuItems: NavigationEntry[] = [ { type: 'item', path: '/', label: 'Home', icon: Home, tooltip: 'Go back to the main chat screen', }, { type: 'separator' }, { type: 'item', path: '/pair', label: 'Chat', icon: ChatSmart, tooltip: 'Start pairing with Goose', }, { type: 'item', path: '/sessions', label: 'History', icon: History, tooltip: 'View your session history', }, { type: 'separator' }, { type: 'item', path: '/recipes', label: 'Recipes', icon: FileText, tooltip: 'Browse your saved recipes', }, { type: 'item', path: '/schedules', label: 'Scheduler', icon: Clock, tooltip: 'Manage scheduled runs', }, { type: 'item', path: '/extensions', label: 'Extensions', icon: Puzzle, tooltip: 'Manage your extensions', }, { type: 'separator' }, { type: 'item', path: '/settings', label: 'Settings', icon: Gear, tooltip: 'Configure Goose settings', }, ]; const AppSidebar: React.FC = ({ currentPath }) => { const navigate = useNavigate(); const chatContext = useChatContext(); useEffect(() => { const timer = setTimeout(() => { // setIsVisible(true); }, 100); // eslint-disable-next-line no-undef return () => clearTimeout(timer); }, []); useEffect(() => { const currentItem = menuItems.find( (item) => item.type === 'item' && item.path === currentPath ) as NavigationItem | undefined; const titleBits = ['Goose']; if ( currentPath === '/pair' && chatContext?.chat?.title && chatContext.chat.title !== DEFAULT_CHAT_TITLE ) { titleBits.push(chatContext.chat.title); } else if (currentPath !== '/' && currentItem) { titleBits.push(currentItem.label); } document.title = titleBits.join(' - '); }, [currentPath, chatContext?.chat?.title]); const isActivePath = (path: string) => { return currentPath === path; }; const renderMenuItem = (entry: NavigationEntry, index: number) => { if (entry.type === 'separator') { return ; } const IconComponent = entry.icon; return (
navigate(entry.path)} isActive={isActivePath(entry.path)} tooltip={entry.tooltip} className="w-full justify-start px-3 rounded-lg h-fit hover:bg-background-medium/50 transition-all duration-200 data-[active=true]:bg-background-medium" > {entry.label}
); }; return ( <> {menuItems.map((entry, index) => renderMenuItem(entry, index))} ); }; export default AppSidebar;