import { useEffect, useState } from 'react'; import { Trash2, Info } from 'lucide-react'; import { useTheme } from '../lib/theme'; import { api } from '../lib/api'; import type { Package } from '../types'; interface InstalledProps { onSelectPackage: (name: string) => void; } export default function Installed({ onSelectPackage }: InstalledProps) { const { theme } = useTheme(); const isDark = theme === 'dark'; const [packages, setPackages] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [filter, setFilter] = useState(''); const [sourceFilter, setSourceFilter] = useState('all'); const [removing, setRemoving] = useState(null); useEffect(() => { loadPackages(); }, []); const loadPackages = async () => { setLoading(true); try { const data = await api.listInstalled(); setPackages(data.results); } catch (err: any) { setError(err.message || 'Failed to load installed packages'); } finally { setLoading(false); } }; const handleRemove = async (name: string) => { setRemoving(name); try { await api.removePackage(name); await loadPackages(); } catch { // silently fail } finally { setRemoving(null); } }; const filtered = packages.filter(pkg => { const matchesName = pkg.name.toLowerCase().includes(filter.toLowerCase()); const matchesSource = sourceFilter === 'all' || pkg.source === sourceFilter; return matchesName && matchesSource; }); 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 (

Installed Packages

{packages.length} total, {filtered.length} shown
{/* Filters */}
setFilter(e.target.value)} placeholder="Filter packages..." className={`${inputClass} flex-1`} />
{/* Error */} {error && (
{error}
)} {/* Package list */}
{loading ? (
Loading installed packages...
) : filtered.length === 0 ? (
{filter ? `No packages matching "${filter}".` : 'No installed packages found.'}
) : (
{filtered.map(pkg => ( onSelectPackage(pkg.name)} > ))}
Package Description Version Source
{pkg.name} {pkg.description} {pkg.version} {pkg.source === 'aur' ? 'AUR' : pkg.repository || 'pacman'}
)}
); }