import { useState } from 'react'; import { Search as SearchIcon, Download } from 'lucide-react'; import { useTheme } from '../lib/theme'; import { api } from '../lib/api'; import type { Package } from '../types'; interface SearchProps { onSelectPackage: (name: string) => void; } export default function SearchPage({ onSelectPackage }: SearchProps) { const { theme } = useTheme(); const isDark = theme === 'dark'; const [query, setQuery] = useState(''); const [source, setSource] = useState('all'); const [sort, setSort] = useState('name'); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const [searched, setSearched] = useState(false); const [error, setError] = useState(''); const [installing, setInstalling] = useState(null); const doSearch = async () => { if (!query.trim()) return; setLoading(true); setError(''); setSearched(true); try { const data = await api.searchPackages(query.trim(), source); let sorted = [...data.results]; if (sort === 'name') sorted.sort((a, b) => a.name.localeCompare(b.name)); else if (sort === 'repo') sorted.sort((a, b) => a.repository.localeCompare(b.repository)); setResults(sorted); } catch (err: any) { setError(err.message || 'Search failed'); setResults([]); } finally { setLoading(false); } }; const handleInstall = async (name: string) => { setInstalling(name); try { await api.installPackage(name); // Refresh search await doSearch(); } catch { // silently fail for demo } finally { setInstalling(null); } }; const panelClass = `border rounded-sm ${ isDark ? 'bg-dark-panel border-dark-border' : 'bg-light-panel border-light-border' }`; const secondaryText = isDark ? 'text-dark-text-secondary' : 'text-light-text-secondary'; const inputClass = `px-3 py-1.5 text-sm border rounded-sm ${ isDark ? 'bg-dark-bg border-dark-border text-dark-text' : 'bg-light-bg border-light-border text-light-text' }`; const selectClass = `px-2 py-1.5 text-sm border rounded-sm ${ isDark ? 'bg-dark-bg border-dark-border text-dark-text' : 'bg-light-bg border-light-border text-light-text' }`; return (

Search Packages

{/* Search controls */}
Search Options
setQuery(e.target.value)} onKeyDown={e => e.key === 'Enter' && doSearch()} placeholder="Enter package name..." className={`${inputClass} w-full pl-8`} />
{/* Results */} {error && (
{error}
)} {searched && (
Results {results.length} package{results.length !== 1 ? 's' : ''} found
{results.length === 0 && !loading ? (
No packages found matching "{query}".
) : (
{results.map(pkg => ( onSelectPackage(pkg.name)} > ))}
Package Description Repository Version Status
{pkg.name} {pkg.description} {pkg.source === 'aur' ? 'AUR' : pkg.repository || 'pacman'} {pkg.version} {pkg.installed ? ( Installed ) : ( Not installed )} {pkg.installed ? ( ) : ( )}
)}
)}
); }