"use client"; import { useEffect, useState } from "react"; import { PaginatedBookGrid } from "@/components/series/PaginatedBookGrid"; import { SeriesHeader } from "@/components/series/SeriesHeader"; import { ErrorMessage } from "@/components/ui/ErrorMessage"; import { PullToRefreshIndicator } from "@/components/common/PullToRefreshIndicator"; import { usePullToRefresh } from "@/hooks/usePullToRefresh"; import { OptimizedSkeleton } from "@/components/skeletons/OptimizedSkeletons"; import type { LibraryResponse } from "@/types/library"; import type { KomgaBook, KomgaSeries } from "@/types/komga"; import type { UserPreferences } from "@/types/preferences"; import { ERROR_CODES } from "@/constants/errorCodes"; interface ClientSeriesPageProps { seriesId: string; currentPage: number; preferences: UserPreferences; unreadOnly: boolean; pageSize?: number; } const DEFAULT_PAGE_SIZE = 20; export function ClientSeriesPage({ seriesId, currentPage, preferences, unreadOnly, pageSize, }: ClientSeriesPageProps) { const [series, setSeries] = useState(null); const [books, setBooks] = useState | null>(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const effectivePageSize = pageSize || preferences.displayMode?.itemsPerPage || DEFAULT_PAGE_SIZE; useEffect(() => { const fetchData = async () => { setLoading(true); setError(null); try { const params = new URLSearchParams({ page: String(currentPage - 1), size: String(effectivePageSize), unread: String(unreadOnly), }); const response = await fetch(`/api/komga/series/${seriesId}/books?${params}`, { cache: 'default' // Utilise le cache HTTP du navigateur }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error?.code || ERROR_CODES.BOOK.PAGES_FETCH_ERROR); } const data = await response.json(); setSeries(data.series); setBooks(data.books); } catch (err) { console.error("Error fetching series books:", err); setError(err instanceof Error ? err.message : ERROR_CODES.BOOK.PAGES_FETCH_ERROR); } finally { setLoading(false); } }; fetchData(); }, [seriesId, currentPage, unreadOnly, effectivePageSize]); const handleRefresh = async (seriesId: string) => { try { // Invalidate cache via API const cacheResponse = await fetch(`/api/komga/series/${seriesId}/books`, { method: 'DELETE', }); if (!cacheResponse.ok) { throw new Error("Erreur lors de l'invalidation du cache"); } // Recharger les données const params = new URLSearchParams({ page: String(currentPage - 1), size: String(effectivePageSize), unread: String(unreadOnly), }); const response = await fetch(`/api/komga/series/${seriesId}/books?${params}`, { cache: 'reload' // Force un nouveau fetch après invalidation }); if (!response.ok) { throw new Error("Erreur lors du rafraîchissement de la série"); } const data = await response.json(); setSeries(data.series); setBooks(data.books); return { success: true }; } catch (error) { console.error("Erreur lors du rafraîchissement:", error); return { success: false, error: "Erreur lors du rafraîchissement de la série" }; } }; const handleRetry = async () => { setError(null); setLoading(true); try { const params = new URLSearchParams({ page: String(currentPage - 1), size: String(effectivePageSize), unread: String(unreadOnly), }); const response = await fetch(`/api/komga/series/${seriesId}/books?${params}`, { cache: 'reload' // Force un nouveau fetch lors du retry }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error?.code || ERROR_CODES.BOOK.PAGES_FETCH_ERROR); } const data = await response.json(); setSeries(data.series); setBooks(data.books); } catch (err) { console.error("Error fetching series books:", err); setError(err instanceof Error ? err.message : ERROR_CODES.BOOK.PAGES_FETCH_ERROR); } finally { setLoading(false); } }; const pullToRefresh = usePullToRefresh({ onRefresh: async () => { await handleRefresh(seriesId); }, enabled: !loading && !error && !!series && !!books, }); if (loading) { return (
{Array.from({ length: effectivePageSize }).map((_, i) => ( ))}
); } if (error) { return (

Série

); } if (!series || !books) { return (

Série

); } return ( <>
); }