chore: initial commit — monorepo ReadaBook (API NestJS, web PWA, Docker)

This commit is contained in:
Git Agent
2026-08-23 09:56:53 +02:00
commit 8f1140127f
79 changed files with 6456 additions and 0 deletions

View File

@ -0,0 +1,48 @@
import { FormEvent, useEffect, useState } from "react";
import { Search } from "lucide-react";
import type { BookDto } from "@readabook/shared";
import { api } from "../api/client";
import { BookCard } from "../components/BookCard";
import { EmptyState, LoadingState, Panel } from "../components/ui";
export function SearchPage() {
const [query, setQuery] = useState("");
const [books, setBooks] = useState<BookDto[] | null>(null);
useEffect(() => {
api.books().then(setBooks);
}, []);
async function submit(event: FormEvent) {
event.preventDefault();
setBooks(null);
setBooks(query.trim() ? await api.search(query.trim()) : await api.books());
}
return (
<div className="page-grid">
<Panel className="span-3">
<form className="search-form" onSubmit={submit}>
<Search size={20} />
<input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Titre, auteur, ISBN" />
<button className="primary-button" type="submit">
Chercher
</button>
</form>
</Panel>
{!books ? (
<LoadingState />
) : books.length ? (
<section className="book-grid span-3">
{books.map((book) => (
<BookCard key={book.id} book={book} />
))}
</section>
) : (
<Panel className="span-3">
<EmptyState title="Aucun specimen" detail="Essaie un autre terme ou relance l'indexation." />
</Panel>
)}
</div>
);
}