import { FormEvent, useEffect, useState } from "react"; import { Search } from "lucide-react"; import type { BookDto, JobDto } from "@readabook/shared"; import { api, getApiFallback } from "../api/client"; import { hasActiveCoverWork, isBookCoverUpdating } from "../api/types"; import { BookCard } from "../components/BookCard"; import { EmptyState, LoadingState, Panel } from "../components/ui"; export function SearchPage() { const [query, setQuery] = useState(""); const [books, setBooks] = useState([]); const [jobs, setJobs] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(); async function loadBooks(nextQuery = query) { setLoading(true); setError(undefined); try { const [nextBooks, nextJobs] = await Promise.all([nextQuery.trim() ? api.search(nextQuery.trim()) : api.books(), api.jobs().catch(() => [])]); setBooks(nextBooks); setJobs(nextJobs); } catch (loadError) { const fallback = getApiFallback(loadError); setBooks(fallback ?? []); setError(fallback ? "Catalogue indisponible, affichage de secours." : "Recherche indisponible."); } finally { setLoading(false); } } const fallbackCoverLoading = hasActiveCoverWork(jobs); useEffect(() => { void loadBooks(""); }, []); async function submit(event: FormEvent) { event.preventDefault(); await loadBooks(query); } return (
setQuery(event.target.value)} placeholder="Titre, auteur, ISBN" /> {error && (
{error}
)}
{loading && !books.length ? ( ) : books.length ? (
{books.map((book) => ( ))}
) : ( )}
); }