"use client"; import { useEffect, useState } from "react"; import { PaginatedSeriesGrid } from "@/components/library/PaginatedSeriesGrid"; import { RefreshButton } from "@/components/library/RefreshButton"; import { ErrorMessage } from "@/components/ui/ErrorMessage"; import { useTranslate } from "@/hooks/useTranslate"; import { OptimizedSkeleton } from "@/components/skeletons/OptimizedSkeletons"; import type { LibraryResponse } from "@/types/library"; import type { KomgaSeries, KomgaLibrary } from "@/types/komga"; import type { UserPreferences } from "@/types/preferences"; interface ClientLibraryPageProps { currentPage: number; libraryId: string; preferences: UserPreferences; unreadOnly: boolean; search?: string; pageSize?: number; } const DEFAULT_PAGE_SIZE = 20; export function ClientLibraryPage({ currentPage, libraryId, preferences, unreadOnly, search, pageSize, }: ClientLibraryPageProps) { const { t } = useTranslate(); const [library, setLibrary] = useState(null); const [series, setSeries] = 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), }); if (search) { params.append("search", search); } const response = await fetch(`/api/komga/libraries/${libraryId}/series?${params}`); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error?.code || "SERIES_FETCH_ERROR"); } const data = await response.json(); setLibrary(data.library); setSeries(data.series); } catch (err) { console.error("Error fetching library series:", err); setError(err instanceof Error ? err.message : "SERIES_FETCH_ERROR"); } finally { setLoading(false); } }; fetchData(); }, [libraryId, currentPage, unreadOnly, search, effectivePageSize]); const handleRefresh = async (libraryId: string) => { try { // Invalidate cache via API const cacheResponse = await fetch(`/api/komga/libraries/${libraryId}/series`, { method: 'DELETE', }); if (!cacheResponse.ok) { throw new Error("Error invalidating cache"); } // Recharger les données const params = new URLSearchParams({ page: String(currentPage - 1), size: String(effectivePageSize), unread: String(unreadOnly), }); if (search) { params.append("search", search); } const response = await fetch(`/api/komga/libraries/${libraryId}/series?${params}`); if (!response.ok) { throw new Error("Error refreshing library"); } const data = await response.json(); setLibrary(data.library); setSeries(data.series); return { success: true }; } catch (error) { console.error("Error during refresh:", error); return { success: false, error: "Error refreshing library" }; } }; const handleRetry = async () => { setError(null); setLoading(true); try { const params = new URLSearchParams({ page: String(currentPage - 1), size: String(effectivePageSize), unread: String(unreadOnly), }); if (search) { params.append("search", search); } const response = await fetch(`/api/komga/libraries/${libraryId}/series?${params}`); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error?.code || "SERIES_FETCH_ERROR"); } const data = await response.json(); setLibrary(data.library); setSeries(data.series); } catch (err) { console.error("Error fetching library series:", err); setError(err instanceof Error ? err.message : "SERIES_FETCH_ERROR"); } finally { setLoading(false); } }; if (loading) { return (
{Array.from({ length: effectivePageSize }).map((_, i) => ( ))}
); } if (error) { return (

{library?.name || t("series.empty")}

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

{library.name}

{series.totalElements > 0 && (

{t("series.display.showing", { start: ((currentPage - 1) * effectivePageSize) + 1, end: Math.min(currentPage * effectivePageSize, series.totalElements), total: series.totalElements, })}

)}
); }