import React, { useState, useEffect } from 'react'; import { useNavigate } from '@tanstack/react-router'; import { Search, User, Folder, Clock, X, History } from 'lucide-react'; import { useQuery } from '@tanstack/react-query'; import { api } from '../lib/api'; interface SearchResult { id: string; type: 'customer' | 'project' | 'time-entry'; label: string; subtitle?: string; } export default function SearchBar() { const [query, setQuery] = useState(''); const [isOpen, setIsOpen] = useState(false); const [history, setHistory] = useState([]); const navigate = useNavigate(); useEffect(() => { const saved = localStorage.getItem('search_history'); if (saved) { try { setHistory(JSON.parse(saved)); } catch (e) { console.error('Failed to parse search history'); } } }, []); const addToHistory = (term: string) => { if (!term.trim()) return; const updated = [term, ...history.filter((item) => item !== term)].slice(0, 10); setHistory(updated); localStorage.setItem('search_history', JSON.stringify(updated)); }; const { data: results, isLoading } = useQuery({ queryKey: ['search', query], queryFn: async () => { if (query.length >= 2) { addToHistory(query); } return api.search(query); }, enabled: query.length >= 2, }); useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') setIsOpen(false); }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, []); const handleSelect = (result: SearchResult) => { const paths: Record = { customer: `/customers/${result.id}`, project: `/projects/${result.id}`, 'time-entry': `/time-entries/${result.id}`, }; navigate({ to: paths[result.type] }); setQuery(''); setIsOpen(false); }; const handleHistoryClick = (term: string) => { setQuery(term); setIsOpen(true); }; const getIcon = (type: SearchResult['type']) => { switch (type) { case 'customer': return ; case 'project': return ; case 'time-entry': return ; } }; return (
{ setQuery(e.target.value); setIsOpen(true); }} onFocus={() => setIsOpen(true)} /> {query && ( )}
{isOpen && (
{query.length === 0 ? (
Recent Searches
{history.length > 0 ? ( history.map((term) => ( )) ) : (
No recent searches
)}
) : isLoading ? (
Searching...
) : results && results.length > 0 ? (
{(['customer', 'project', 'time-entry'] as const).map((type) => { const filtered = results.filter((r: SearchResult) => r.type === type); if (filtered.length === 0) return null; return (
{type}s
{filtered.map((result: SearchResult) => ( ))}
); })}
) : (
No results found
)}
)}
); }