From f8725857ad01759dfb34813b139236a534ae3427 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Tue, 11 Feb 2025 21:42:16 +0100 Subject: [PATCH] =?UTF-8?q?refactor:=20d=C3=A9place=20la=20logique=20de=20?= =?UTF-8?q?filtrage=20des=20tomes=20dans=20PaginatedBookGrid=20et=20met=20?= =?UTF-8?q?=C3=A0=20jour=20le=20devbook?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devbook.md | 2 + src/components/series/PaginatedBookGrid.tsx | 139 ++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 src/components/series/PaginatedBookGrid.tsx 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é" + )} +

+ +
+ +
+ {/* Indicateur de chargement */} + {isChangingPage && ( +
+
+ + Chargement... +
+
+ )} + + {/* Grille avec animation de transition */} +
+ +
+
+ +
+

+ Page {currentPage} sur {totalPages} +

+ +
+
+ ); +}