'use client' import * as React from 'react' import Link from 'next/link' import { Folder, ChevronRight } from 'lucide-react' import { Input } from '@/components/ui/input' import { Badge } from '@/components/ui/badge' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select' import { Skeleton } from '@/components/ui/skeleton' interface AwesomeList { id: number name: string url: string description: string | null category: string | null stars: number | null } interface Category { name: string count: number } interface BrowseResponse { lists: AwesomeList[] categories: Category[] total: number } export default function BrowsePage() { const [data, setData] = React.useState(null) const [loading, setLoading] = React.useState(true) const [searchQuery, setSearchQuery] = React.useState('') const [selectedCategory, setSelectedCategory] = React.useState('') React.useEffect(() => { const params = new URLSearchParams() if (selectedCategory) { params.set('category', selectedCategory) } fetch(`/api/lists?${params}`) .then(res => res.json()) .then(data => { setData(data) setLoading(false) }) .catch(err => { console.error('Failed to fetch lists:', err) setLoading(false) }) }, [selectedCategory]) const filteredLists = React.useMemo(() => { if (!data) return [] let filtered = data.lists if (searchQuery) { const query = searchQuery.toLowerCase() filtered = filtered.filter(list => list.name.toLowerCase().includes(query) || list.description?.toLowerCase().includes(query) || list.category?.toLowerCase().includes(query) ) } return filtered }, [data, searchQuery]) // Group lists by category const groupedLists = React.useMemo(() => { const groups: Record = {} filteredLists.forEach(list => { const category = list.category || 'Uncategorized' if (!groups[category]) { groups[category] = [] } groups[category].push(list) }) // Sort categories by name return Object.keys(groups) .sort() .reduce((acc, key) => { acc[key] = groups[key].sort((a, b) => (b.stars || 0) - (a.stars || 0)) return acc }, {} as Record) }, [filteredLists]) return (
{/* Header */}

Browse Collections

Explore {data?.total || '...'} curated awesome lists organized by category

{/* Filters */}
setSearchQuery(e.target.value)} />
{/* Content */}
{loading && (
{[...Array(3)].map((_, i) => (
{[...Array(6)].map((_, j) => ( ))}
))}
)} {!loading && Object.keys(groupedLists).length === 0 && (

No lists found matching your criteria

)} {!loading && Object.keys(groupedLists).length > 0 && (
{Object.entries(groupedLists).map(([category, lists]) => (

{category}

{lists.length}
{lists.map(list => (

{list.name}

{list.description && (

{list.description}

)} ))}
))}
)}
) }