Files
group-2-threaded-project-pe…/web/app/adopt/page.js
augmentedpotato 3ee59521fd Fix web routing
2026-04-03 14:48:24 -06:00

127 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState, useEffect } from "react";
import PetCard from "@/components/PetCard";
const API_BASE = "";
export default function AdoptPage() {
const [pets, setPets] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [health, setHealth] = useState(null);
const [search, setSearch] = useState("");
const [query, setQuery] = useState("");
const PAGE_SIZE = 200;
useEffect(() => {
fetch(`${API_BASE}/api/v1/health`)
.then((res) => (res.ok ? setHealth("online") : setHealth("error")))
.catch(() => setHealth("offline"));
}, []);
useEffect(() => {
const params = new URLSearchParams({ page: 0, size: PAGE_SIZE, sort: "petId,asc" });
if (query) params.set("q", query);
fetch(`${API_BASE}/api/v1/pets?${params}`)
.then((res) => {
if (!res.ok) throw new Error(`HTTP ${res.status} ${res.statusText}`);
return res.json();
})
.then((data) => {
setPets(data.content ?? []);
})
.catch((err) => setError(err.message))
.finally(() => setLoading(false));
}, [query]);
function handleSearch(e) {
e.preventDefault();
setLoading(true);
setError(null);
setQuery(search.trim());
}
return (
<main className="adopt-page">
<section className="adopt-hero">
<h1 className="adopt-hero-title">Find Your Perfect Companion</h1>
<p className="adopt-hero-subtitle">Give a loving pet their forever home</p>
<div className="title-decoration"></div>
</section>
<section className="adopt-controls">
<div className="adopt-controls-row">
<form className="adopt-search-form" onSubmit={handleSearch}>
<input
className="adopt-search-input"
type="text"
placeholder="Search by name or species..."
value={search}
onChange={(e) => setSearch(e.target.value)}
/>
<button className="adopt-search-btn" type="submit">Search</button>
{query && (
<button
className="adopt-clear-btn"
type="button"
onClick={() => { setLoading(true); setError(null); setSearch(""); setQuery(""); }}
>
Clear
</button>
)}
</form>
<span
className={`backend-status backend-status--${health ?? "checking"}`}
title={
health === "online" ? "Backend online" :
health === "offline" ? "Backend offline" :
health === "error" ? "Backend error" : "Checking…"
}
/>
</div>
</section>
<section className="adopt-grid-section">
{loading && <p className="adopt-status-msg">Loading pets...</p>}
{error && (
<div className="adopt-error-box">
<p className="adopt-error-title">Failed to load pets</p>
<code className="adopt-error-detail">{error}</code>
<p className="adopt-error-hint">
{health === "offline"
? "The Spring Boot backend is not reachable. Make sure it is running in IntelliJ on port 8080."
: health === "error"
? "The backend responded with an error. Check the IntelliJ Run console for stack traces."
: "The backend is reachable but the /pets endpoint failed. Check the IntelliJ Run console."}
</p>
</div>
)}
{!loading && !error && pets.length === 0 && (
<p className="adopt-status-msg">No pets found.</p>
)}
{!loading && !error && pets.length > 0 && (
<div className="adopt-grid">
{pets.map((pet) => (
<PetCard
key={pet.petId}
petId={pet.petId}
petName={pet.petName}
petSpecies={pet.petSpecies}
petStatus={pet.petStatus}
imageUrl={pet.imageUrl}
/>
))}
</div>
)}
</section>
</main>
);
}