'use client'; import { useEffect, useState, useCallback } from 'react'; import { useRouter } from 'next/navigation'; import { LayoutDashboard, ListTodo, Flame, FolderKanban, NotebookPen, Share2, CalendarDays, Bot, Settings, Plus, Search, type LucideIcon, } from 'lucide-react'; import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from '@/components/ui/command'; interface NavItem { label: string; href: string; icon: LucideIcon; } const navItems: NavItem[] = [ { label: 'Dashboard', href: '/dashboard', icon: LayoutDashboard }, { label: 'Tasks', href: '/tasks', icon: ListTodo }, { label: 'Habits', href: '/habits', icon: Flame }, { label: 'Projects', href: '/projects', icon: FolderKanban }, { label: 'Notes', href: '/notes', icon: NotebookPen }, { label: 'Graph', href: '/graph', icon: Share2 }, { label: 'Calendar', href: '/calendar', icon: CalendarDays }, { label: 'Agent Activity', href: '/agents', icon: Bot }, { label: 'Settings', href: '/settings', icon: Settings }, ]; interface QuickAction { label: string; shortcut?: string; action: () => void; } export function CommandPalette() { const router = useRouter(); const [open, setOpen] = useState(false); const [deepSearch, setDeepSearch] = useState(false); const [searchResults, setSearchResults] = useState; }>>([]); // Keyboard shortcuts useEffect(() => { const down = (e: KeyboardEvent) => { if (e.key === 'k' && (e.metaKey || e.ctrlKey)) { e.preventDefault(); if (e.shiftKey) { setDeepSearch(true); setOpen(true); } else { setDeepSearch(false); setOpen(true); } } }; document.addEventListener('keydown', down); return () => document.removeEventListener('keydown', down); }, []); // Quick actions const quickActions: QuickAction[] = [ { label: 'New task', shortcut: 'N', action: () => router.push('/tasks?new=true') }, { label: 'New habit', action: () => router.push('/habits?new=true') }, { label: 'New project', action: () => router.push('/projects?new=true') }, { label: 'New note', action: () => router.push('/notes?new=true') }, { label: 'Ask AI agent...', shortcut: '@', action: () => { setOpen(false); // Dispatch event for AI dispatch flow document.dispatchEvent(new CustomEvent('open-ai-dispatch')); }}, ]; // Search handler const handleSearch = useCallback(async (query: string) => { if (!query.trim()) { setSearchResults([]); return; } try { const response = await fetch(`/api/search?q=${encodeURIComponent(query)}&limit=5`); if (response.ok) { const data = await response.json(); setSearchResults(data.results || []); } } catch { // Ignore search errors } }, []); const runCommand = useCallback((command: () => void) => { setOpen(false); command(); }, []); return ( No results found. {/* Navigation */} {!deepSearch && ( {navItems.map((item) => ( runCommand(() => router.push(item.href))} > {item.label} ))} )} {/* Quick Actions */} {quickActions.map((action) => ( runCommand(action.action)} > {action.label} {action.shortcut && ( {action.shortcut} )} ))} {/* Search Results (deep search mode) */} {deepSearch && searchResults.length > 0 && ( <> {searchResults.map((group) => ( {group.items.map((item) => ( { const typeRoute = group.type === 'tasks' ? '/tasks' : group.type === 'habits' ? '/habits' : group.type === 'projects' ? '/projects' : group.type === 'notes' ? '/notes' : '/reports'; runCommand(() => router.push(`${typeRoute}/${item.id}`)); }} > {item.title} ))} ))} )} {/* Footer hint */}
↑↓ navigate select esc close
); }