import { useState, useEffect } from 'react'; import { useSearchParams } from 'react-router-dom'; import api from '../api/client'; import PackageGrid from '../components/PackageGrid'; import LoadingSpinner from '../components/LoadingSpinner'; import { Filter, Search, Grid, List, CheckCircle, AlertTriangle, Star, Download, Globe, ExternalLink, Trash2, Shield, Package } from 'lucide-react'; export default function SearchPage() { const [searchParams] = useSearchParams(); const query = searchParams.get('q') || ''; const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const [source, setSource] = useState('all'); const [error, setError] = useState(null); const [layoutMode, setLayoutMode] = useState('grid'); const [sortBy, setSortBy] = useState('relevance'); const [filters, setFilters] = useState({ installed: false, outOfDate: false, hasVotes: false }); // Selected package details for right preview panel const [selectedPkgName, setSelectedPkgName] = useState(null); const [pkgDetail, setPkgDetail] = useState(null); const [detailLoading, setDetailLoading] = useState(false); const [scanResult, setScanResult] = useState(null); const [scanning, setScanning] = useState(false); const [actionLog, setActionLog] = useState(''); const [acting, setActing] = useState(false); useEffect(() => { if (query.trim()) { performSearch(query, source); } else { setResults([]); setSelectedPkgName(null); setPkgDetail(null); } }, [query, source]); useEffect(() => { if (selectedPkgName) { loadDetails(selectedPkgName); } else { setPkgDetail(null); setScanResult(null); } }, [selectedPkgName]); async function performSearch(q, s) { setLoading(true); setError(null); try { const data = await api.searchPackages(q, s); const resList = data.results || []; setResults(resList); if (resList.length > 0) { setSelectedPkgName(resList[0].name); } else { setSelectedPkgName(null); } } catch (err) { setError(err.message); setResults([]); setSelectedPkgName(null); } finally { setLoading(false); } } async function loadDetails(name) { setDetailLoading(true); setScanResult(null); setActionLog(''); try { const detail = await api.getPackageInfo(name); setPkgDetail(detail); if (detail.source === 'aur') { doScan(detail.name); } } catch { // silent fallback } finally { setDetailLoading(false); } } async function doScan(name) { setScanning(true); try { const scan = await api.scanPackage(name); setScanResult(scan); } catch { // silent fallback } finally { setScanning(false); } } async function handleInstall() { if (!pkgDetail) return; setActing(true); setActionLog('Retrieving database structures...\nInitializing builder pipeline...\n'); try { const res = await api.installPackage(pkgDetail.name); if (res.success) { setActionLog(prev => prev + '\nā Build completed successfully!\n' + res.message); loadDetails(pkgDetail.name); } else { setError('Installation failed: ' + res.message); } } catch (e) { setError(e.message); } finally { setActing(false); } } async function handleUninstall() { if (!pkgDetail || !confirm(`Remove ${pkgDetail.name}?`)) return; setActing(true); setActionLog('Resolving package graph...\nRemoving target dependencies...\n'); try { const res = await api.removePackage(pkgDetail.name); if (res.success) { setActionLog(prev => prev + '\nā Uninstallation complete!\n' + res.message); loadDetails(pkgDetail.name); } else { setError('Removal failed: ' + res.message); } } catch (e) { setError(e.message); } finally { setActing(false); } } const tabs = [ { id: 'all', label: 'All Packages' }, { id: 'pacman', label: 'Official' }, { id: 'aur', label: 'AUR Repos' }, ]; const filteredResults = results .filter((pkg) => !filters.installed || pkg.installed) .filter((pkg) => !filters.outOfDate || pkg.out_of_date) .filter((pkg) => !filters.hasVotes || (pkg.votes || 0) > 0); const sortedResults = [...filteredResults].sort((a, b) => { if (sortBy === 'name') return a.name.localeCompare(b.name); if (sortBy === 'votes') return (b.votes || 0) - (a.votes || 0); if (sortBy === 'popularity') return (b.popularity || 0) - (a.popularity || 0); return 0; }); return (
{query ? <>Queried results for "{query}"> : 'Query pacman databases and AUR repositories'}
Refine the query or check for alternative repository scopes.
{pkg.description || 'No description available.'}
{pkgDetail.description || 'No description specs available for this system library.'}
{actionLog}
Select a Package for Details
Click on any searched package to review security scans, versions, votes, and maintainer specifications instantly.
Search across official core, extra, multilib repositories, and the community-driven AUR. Use the top navigation bar to initialize queries.