From 592aadf4ab7e9920d2de312c2645c874b71abe6a Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Fri, 17 Oct 2025 16:18:38 +0200 Subject: [PATCH] feat: refactor book page to use ClientBookPage component and enhance data fetching with next book information --- src/app/api/komga/books/[bookId]/route.ts | 4 +- src/app/books/[bookId]/page.tsx | 38 +++--------- src/components/home/ClientHomePage.tsx | 63 ++++++++++--------- src/components/reader/ClientBookPage.tsx | 76 +++++++++++++++++++++++ 4 files changed, 121 insertions(+), 60 deletions(-) create mode 100644 src/components/reader/ClientBookPage.tsx diff --git a/src/app/api/komga/books/[bookId]/route.ts b/src/app/api/komga/books/[bookId]/route.ts index b9c5f83..bb88be0 100644 --- a/src/app/api/komga/books/[bookId]/route.ts +++ b/src/app/api/komga/books/[bookId]/route.ts @@ -14,7 +14,9 @@ export async function GET( const bookId: string = (await params).bookId; const data: KomgaBookWithPages = await BookService.getBook(bookId); - return NextResponse.json(data); + const nextBook = await BookService.getNextBook(bookId, data.book.seriesId); + + return NextResponse.json({ ...data, nextBook }); } catch (error) { console.error("API Books - Erreur:", error); if (error instanceof AppError) { diff --git a/src/app/books/[bookId]/page.tsx b/src/app/books/[bookId]/page.tsx index 4a218ce..3a25b6a 100644 --- a/src/app/books/[bookId]/page.tsx +++ b/src/app/books/[bookId]/page.tsx @@ -1,38 +1,16 @@ import { Suspense } from "react"; -import { ClientBookWrapper } from "@/components/reader/ClientBookWrapper"; +import { ClientBookPage } from "@/components/reader/ClientBookPage"; import { BookSkeleton } from "@/components/skeletons/BookSkeleton"; -import { BookService } from "@/lib/services/book.service"; import { withPageTiming } from "@/lib/hoc/withPageTiming"; -import type { KomgaBookWithPages } from "@/types/komga"; -import { ErrorMessage } from "@/components/ui/ErrorMessage"; -import { ERROR_CODES } from "@/constants/errorCodes"; -import { AppError } from "@/utils/errors"; async function BookPage({ params }: { params: { bookId: string } }) { - try { - const { bookId } = await params; - const data: KomgaBookWithPages = await BookService.getBook(bookId); - const nextBook = await BookService.getNextBook(bookId, data.book.seriesId); - return ( - }> - - - ); - } catch (error) { - console.error("Erreur:", error); - if (error instanceof AppError) { - return ( -
- -
- ); - } - return ( -
- -
- ); - } + const { bookId } = await params; + + return ( + }> + + + ); } export default withPageTiming("BookPage", BookPage); diff --git a/src/components/home/ClientHomePage.tsx b/src/components/home/ClientHomePage.tsx index fc261e7..734bddb 100644 --- a/src/components/home/ClientHomePage.tsx +++ b/src/components/home/ClientHomePage.tsx @@ -14,39 +14,40 @@ export function ClientHomePage() { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); - useEffect(() => { - const fetchData = async () => { - setLoading(true); - setError(null); + const fetchData = async () => { + setLoading(true); + setError(null); - try { - const response = await fetch("/api/komga/home"); + try { + const response = await fetch("/api/komga/home"); - if (!response.ok) { - const errorData = await response.json(); - const errorCode = errorData.error?.code || ERROR_CODES.KOMGA.SERVER_UNREACHABLE; - - // Si la config Komga est manquante, rediriger vers les settings - if (errorCode === ERROR_CODES.KOMGA.MISSING_CONFIG) { - router.push("/settings"); - return; - } - - throw new Error(errorCode); + if (!response.ok) { + const errorData = await response.json(); + const errorCode = errorData.error?.code || ERROR_CODES.KOMGA.SERVER_UNREACHABLE; + + // Si la config Komga est manquante, rediriger vers les settings + if (errorCode === ERROR_CODES.KOMGA.MISSING_CONFIG) { + router.push("/settings"); + return; } - - const homeData = await response.json(); - setData(homeData); - } catch (err) { - console.error("Error fetching home data:", err); - setError(err instanceof Error ? err.message : ERROR_CODES.KOMGA.SERVER_UNREACHABLE); - } finally { - setLoading(false); + + throw new Error(errorCode); } - }; + const homeData = await response.json(); + setData(homeData); + } catch (err) { + console.error("Error fetching home data:", err); + setError(err instanceof Error ? err.message : ERROR_CODES.KOMGA.SERVER_UNREACHABLE); + } finally { + setLoading(false); + } + }; + + useEffect(() => { fetchData(); - }, [router]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const handleRefresh = async () => { try { @@ -80,10 +81,14 @@ export function ClientHomePage() { return ; } + const handleRetry = () => { + fetchData(); + }; + if (error) { return (
- +
); } @@ -91,7 +96,7 @@ export function ClientHomePage() { if (!data) { return (
- +
); } diff --git a/src/components/reader/ClientBookPage.tsx b/src/components/reader/ClientBookPage.tsx new file mode 100644 index 0000000..339c749 --- /dev/null +++ b/src/components/reader/ClientBookPage.tsx @@ -0,0 +1,76 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { ClientBookWrapper } from "./ClientBookWrapper"; +import { BookSkeleton } from "@/components/skeletons/BookSkeleton"; +import { ErrorMessage } from "@/components/ui/ErrorMessage"; +import { ERROR_CODES } from "@/constants/errorCodes"; +import type { KomgaBook } from "@/types/komga"; + +interface ClientBookPageProps { + bookId: string; +} + +export function ClientBookPage({ bookId }: ClientBookPageProps) { + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [data, setData] = useState<{ + book: KomgaBook; + pages: number[]; + nextBook: KomgaBook | null; + } | null>(null); + + const fetchBookData = async () => { + try { + setLoading(true); + setError(null); + + const response = await fetch(`/api/komga/books/${bookId}`); + + if (!response.ok) { + const errorData = await response.json(); + throw new Error(errorData.error?.code || ERROR_CODES.BOOK.PAGES_FETCH_ERROR); + } + + const bookData = await response.json(); + setData(bookData); + } catch (err) { + console.error("Error fetching book:", err); + setError(err instanceof Error ? err.message : ERROR_CODES.BOOK.PAGES_FETCH_ERROR); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + fetchBookData(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [bookId]); + + const handleRetry = () => { + fetchBookData(); + }; + + if (loading) { + return ; + } + + if (error) { + return ( +
+ +
+ ); + } + + if (!data) { + return ( +
+ +
+ ); + } + + return ; +} +