chore: initial commit — monorepo ReadaBook (API NestJS, web PWA, Docker)
This commit is contained in:
53
apps/web/src/pages/BookPage.tsx
Normal file
53
apps/web/src/pages/BookPage.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { BookOpen, LibraryBig } from "lucide-react";
|
||||
import type { BookDto, ProgressDto } from "@readabook/shared";
|
||||
import { api } from "../api/client";
|
||||
import { FormatPill, LoadingState, Meter, Panel } from "../components/ui";
|
||||
import { navigate } from "../router";
|
||||
|
||||
export function BookPage({ bookId }: { bookId: number }) {
|
||||
const [book, setBook] = useState<BookDto | null>(null);
|
||||
const [progress, setProgress] = useState<ProgressDto | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let alive = true;
|
||||
Promise.all([api.book(bookId), api.progress(bookId)]).then(([nextBook, nextProgress]) => {
|
||||
if (!alive) return;
|
||||
setBook(nextBook);
|
||||
setProgress(nextProgress);
|
||||
});
|
||||
return () => {
|
||||
alive = false;
|
||||
};
|
||||
}, [bookId]);
|
||||
|
||||
if (!book) return <LoadingState />;
|
||||
|
||||
return (
|
||||
<div className="book-detail">
|
||||
<section className="book-portrait">
|
||||
{book.coverPath ? <img src={api.bookCoverUrl(book.id)} alt="" /> : <BookOpen size={72} />}
|
||||
</section>
|
||||
<Panel className="book-facts">
|
||||
<div className="book-card-meta">
|
||||
<FormatPill format={book.format} />
|
||||
<span>{book.language ?? "langue inconnue"}</span>
|
||||
</div>
|
||||
<h1>{book.title}</h1>
|
||||
<p className="lead">{book.author ?? "Auteur inconnu"}</p>
|
||||
<p>{book.description ?? "Notice absente du catalogue."}</p>
|
||||
{progress && <Meter value={progress.percent} />}
|
||||
<div className="book-card-actions">
|
||||
<button className="primary-button" onClick={() => navigate(`/reader/${book.id}`)}>
|
||||
<BookOpen size={18} />
|
||||
Lire
|
||||
</button>
|
||||
<button className="ghost-button" onClick={() => navigate(`/library/${book.libraryId}`)}>
|
||||
<LibraryBig size={18} />
|
||||
Rayon
|
||||
</button>
|
||||
</div>
|
||||
</Panel>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user