"use client"; import { useState, useEffect, useMemo } from "react"; import PetCard from "@/components/PetCard"; import { fetchAllPages } from "@/lib/fetchAllPages"; import { useCart } from "@/context/CartContext"; const API_BASE = ""; const PAGE_SIZE = 10000; export default function AdoptPage() { const { selectedStoreId } = useCart(); // pets = everything returned by the server (filtered by species + store + text query) const [pets, setPets] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [search, setSearch] = useState(""); const [query, setQuery] = useState(""); const [selectedSpecies, setSelectedSpecies] = useState(""); const [selectedBreed, setSelectedBreed] = useState(""); // Species options come from a dedicated fetch (only store-filtered, no species filter) const [speciesOptions, setSpeciesOptions] = useState([]); useEffect(() => { setSelectedSpecies(""); const params = new URLSearchParams({ page: "0", size: String(PAGE_SIZE) }); if (selectedStoreId) params.set("storeId", String(selectedStoreId)); fetch(`${API_BASE}/api/v1/pets?${params}`) .then((r) => (r.ok ? r.json() : null)) .then((data) => { const items = data?.content ?? []; const species = [...new Set(items.map((p) => p.petSpecies).filter(Boolean))].sort((a, b) => a.localeCompare(b, undefined, { sensitivity: "base" }) ); setSpeciesOptions(species); }) .catch(() => setSpeciesOptions([])); }, [selectedStoreId]); useEffect(() => { setSelectedBreed(""); }, [selectedSpecies]); useEffect(() => { setLoading(true); setError(null); fetchAllPages((page) => { const params = new URLSearchParams({ page: String(page), size: String(PAGE_SIZE), sort: "id,asc", }); if (query) params.set("q", query); if (selectedSpecies) params.set("species", selectedSpecies); if (selectedStoreId) params.set("storeId", String(selectedStoreId)); return `${API_BASE}/api/v1/pets?${params}`; }) .then(setPets) .catch((err) => setError(err.message)) .finally(() => setLoading(false)); }, [query, selectedSpecies, selectedStoreId]); const breedOptions = useMemo( () => [...new Set(pets.map((p) => p.petBreed).filter(Boolean))].sort((a, b) => a.localeCompare(b, undefined, { sensitivity: "base" }) ), [pets] ); const ITEMS_PER_PAGE = 24; const [currentPage, setCurrentPage] = useState(0); const filteredPets = useMemo( () => (selectedBreed ? pets.filter((p) => p.petBreed === selectedBreed) : pets), [pets, selectedBreed] ); const totalPages = Math.ceil(filteredPets.length / ITEMS_PER_PAGE); const displayedPets = filteredPets.slice(currentPage * ITEMS_PER_PAGE, (currentPage + 1) * ITEMS_PER_PAGE); function handleSearch(e) { e.preventDefault(); setCurrentPage(0); setQuery(search.trim()); } function handleClearFilters() { setSearch(""); setQuery(""); setSelectedSpecies(""); setSelectedBreed(""); setCurrentPage(0); } const hasActiveFilters = query || selectedSpecies || selectedBreed; return (

Find Your Perfect Companion

Give a loving pet their forever home

setSearch(e.target.value)} />
{hasActiveFilters && ( )}
{loading &&

Loading pets...

} {error && (

Unable to load pets, please try again later.

)} {!loading && !error && displayedPets.length === 0 && (

No pets found matching your filters.

)} {!loading && !error && displayedPets.length > 0 && (
{displayedPets.map((pet) => ( ))}
)} {!loading && !error && totalPages > 1 && (
{(() => { const pages = []; const delta = 2; const left = Math.max(0, currentPage - delta); const right = Math.min(totalPages - 1, currentPage + delta); if (left > 0) { pages.push(0); if (left > 1) pages.push("..."); } for (let i = left; i <= right; i++) pages.push(i); if (right < totalPages - 1) { if (right < totalPages - 2) pages.push("..."); pages.push(totalPages - 1); } return pages.map((p, i) => p === "..." ? ( ) : ( ) ); })()}
)}
); }