"use client" import { useState, useEffect, useCallback } from "react" import { Input } from "@/components/ui/input" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Skeleton } from "@/components/ui/skeleton" import { Search, Eye, Filter, X, Loader2, RefreshCw } from "lucide-react" import Link from "next/link" interface Comparison { id: string title: string summary: string slug: string tags: string[] items: string[] viewCount: number createdAt: string } interface ComparisonsResponse { comparisons: Comparison[] total: number page: number limit: number } export default function ExplorePage() { const [comparisons, setComparisons] = useState([]) const [total, setTotal] = useState(0) const [page, setPage] = useState(1) const [loading, setLoading] = useState(false) const [error, setError] = useState(null) const [searchQuery, setSearchQuery] = useState("") const [debouncedSearch, setDebouncedSearch] = useState("") const [selectedCategory, setSelectedCategory] = useState("All") const limit = 20 const fetchComparisons = useCallback(async (pageNum: number, search: string, append = false) => { setLoading(true) setError(null) try { const params = new URLSearchParams({ page: pageNum.toString(), limit: limit.toString(), ...(search && { search }), }) const res = await fetch(`/api/comparisons?${params}`) if (!res.ok) throw new Error("Failed to fetch comparisons") const data: ComparisonsResponse = await res.json() setComparisons(prev => append ? [...prev, ...data.comparisons] : data.comparisons) setTotal(data.total) setPage(pageNum) } catch (err) { setError(err instanceof Error ? err.message : "Something went wrong") } finally { setLoading(false) } }, []) useEffect(() => { const timer = setTimeout(() => { setDebouncedSearch(searchQuery) setPage(1) fetchComparisons(1, searchQuery) }, 300) return () => clearTimeout(timer) }, [searchQuery, fetchComparisons]) useEffect(() => { fetchComparisons(1, "") }, [fetchComparisons]) const categories = ["All", ...Array.from(new Set(comparisons.flatMap(c => c.tags)))] const filteredComparisons = comparisons.filter((comparison) => { const matchesCategory = selectedCategory === "All" || comparison.tags.some((tag) => tag.toLowerCase() === selectedCategory.toLowerCase()) return matchesCategory }) const loadMore = () => { fetchComparisons(page + 1, debouncedSearch, true) } const hasMore = comparisons.length < total return (

Explore Comparisons

setSearchQuery(e.target.value)} className="pl-9" />
{categories.map((category) => ( ))}
{loading && comparisons.length === 0 ? (
{[...Array(6)].map((_, i) => (
))}
) : error ? (

Failed to load comparisons

{error}

) : filteredComparisons.length > 0 ? (
{filteredComparisons.map((comparison) => (
{comparison.title}
{comparison.summary}
{comparison.tags.map((tag) => ( {tag} ))}
{comparison.items.join(" vs ")}
{comparison.viewCount.toLocaleString()}
))}
) : (

No comparisons found

Try adjusting your search or filters

)} {loading && comparisons.length > 0 && (
)} {!loading && hasMore && (
)}
) }