Showing {filteredPackages.length} package{filteredPackages.length !== 1 ? 's' : ''}
An error occurred while fetching packages: {error}
No packages found matching your search.
import { useState, useEffect, JSX } from 'react'; import { Header } from './components/Header'; import { SearchBar } from './components/SearchBar'; import { PackageList } from './components/PackageList'; import { usePackages } from './hooks/usePackages'; import { Repository } from './types'; export default function App(): JSX.Element { const { packages, loading, error } = usePackages(); const [search, setSearch] = useState(''); const [selectedRepository, setSelectedRepository] = useState('all'); const [debouncedSearch, setDebouncedSearch] = useState(search); // Debounce search to optimize performance useEffect(() => { const timeoutId = setTimeout(() => { setDebouncedSearch(search); }, 300); // Wait for 300ms after the last keystroke return () => clearTimeout(timeoutId); }, [search]); // Filter packages based on search query and selected repository const filteredPackages = packages .filter((pkg) => { // Filter by repository if (selectedRepository !== 'all' && pkg.repository !== selectedRepository) { return false; } // Filter by search query return pkg.name.toLowerCase().includes(debouncedSearch.toLowerCase()) || pkg.description.toLowerCase().includes(debouncedSearch.toLowerCase()); }); const handleSearchChange = (value: string) => { setSearch(value); }; const handleRepositoryFilterChange = (repo: Repository) => { setSelectedRepository(repo); }; return (
Showing {filteredPackages.length} package{filteredPackages.length !== 1 ? 's' : ''}
An error occurred while fetching packages: {error}
No packages found matching your search.