diff --git a/devbook.md b/devbook.md index d17575f..c3499e3 100644 --- a/devbook.md +++ b/devbook.md @@ -114,6 +114,8 @@ Créer une application web moderne avec Next.js permettant de lire des fichiers - [x] Couverture et informations - [x] Liste des tomes - [x] Progression de lecture + - [x] Pagination des tomes + - [x] Filtre "À lire" (non lus et en cours) - [x] Bouton de lecture contextuel - [x] Page de détails du tome - [x] Couverture et informations diff --git a/src/components/series/PaginatedBookGrid.tsx b/src/components/series/PaginatedBookGrid.tsx new file mode 100644 index 0000000..5912dcc --- /dev/null +++ b/src/components/series/PaginatedBookGrid.tsx @@ -0,0 +1,139 @@ +"use client"; + +import { BookGrid } from "./BookGrid"; +import { Pagination } from "@/components/ui/Pagination"; +import { useRouter, usePathname, useSearchParams } from "next/navigation"; +import { useState, useEffect } from "react"; +import { Loader2, Filter } from "lucide-react"; +import { cn } from "@/lib/utils"; +import { KomgaBook } from "@/types/komga"; + +interface PaginatedBookGridProps { + books: KomgaBook[]; + serverUrl: string; + currentPage: number; + totalPages: number; + totalElements: number; + pageSize: number; + onBookClick?: (book: KomgaBook) => void; +} + +export function PaginatedBookGrid({ + books, + serverUrl, + currentPage, + totalPages, + totalElements, + pageSize, + onBookClick, +}: PaginatedBookGridProps) { + const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + const [isChangingPage, setIsChangingPage] = useState(false); + const [showOnlyUnread, setShowOnlyUnread] = useState(searchParams.get("unread") === "true"); + + // Réinitialiser l'état de chargement quand les tomes changent + useEffect(() => { + setIsChangingPage(false); + }, [books]); + + const handlePageChange = (page: number) => { + setIsChangingPage(true); + // Créer un nouvel objet URLSearchParams pour manipuler les paramètres + const params = new URLSearchParams(searchParams); + params.set("page", page.toString()); + if (showOnlyUnread) { + params.set("unread", "true"); + } + + // Rediriger vers la nouvelle URL avec les paramètres mis à jour + router.push(`${pathname}?${params.toString()}`); + }; + + const handleUnreadFilter = () => { + setIsChangingPage(true); + const params = new URLSearchParams(searchParams); + params.set("page", "1"); // Retourner à la première page lors du changement de filtre + + if (!showOnlyUnread) { + params.set("unread", "true"); + } else { + params.delete("unread"); + } + + setShowOnlyUnread(!showOnlyUnread); + router.push(`${pathname}?${params.toString()}`); + }; + + // Calcul des indices de début et de fin pour l'affichage + const startIndex = (currentPage - 1) * pageSize + 1; + const endIndex = Math.min(currentPage * pageSize, totalElements); + + const getBookThumbnailUrl = (bookId: string) => { + return `/api/komga/images/books/${bookId}/thumbnail`; + }; + + return ( +
+ {totalElements > 0 ? ( + <> + Affichage des tomes {startIndex} à{" "} + {endIndex} sur{" "} + {totalElements} + > + ) : ( + "Aucun tome trouvé" + )} +
+ ++ Page {currentPage} sur {totalPages} +
+