feat: enhance ClientSeriesPage to utilize initial series and books props for improved data handling and loading state management

This commit is contained in:
Julien Froidefond
2025-12-07 10:03:44 +01:00
parent 39e3328123
commit 239ea19ac3
3 changed files with 27 additions and 38 deletions

View File

@@ -19,6 +19,8 @@ interface ClientSeriesPageProps {
preferences: UserPreferences; preferences: UserPreferences;
unreadOnly: boolean; unreadOnly: boolean;
pageSize?: number; pageSize?: number;
initialSeries: KomgaSeries;
initialBooks: LibraryResponse<KomgaBook>;
} }
const DEFAULT_PAGE_SIZE = 20; const DEFAULT_PAGE_SIZE = 20;
@@ -29,48 +31,21 @@ export function ClientSeriesPage({
preferences, preferences,
unreadOnly, unreadOnly,
pageSize, pageSize,
initialSeries,
initialBooks,
}: ClientSeriesPageProps) { }: ClientSeriesPageProps) {
const [series, setSeries] = useState<KomgaSeries | null>(null); const [series, setSeries] = useState<KomgaSeries | null>(initialSeries);
const [books, setBooks] = useState<LibraryResponse<KomgaBook> | null>(null); const [books, setBooks] = useState<LibraryResponse<KomgaBook> | null>(initialBooks);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const effectivePageSize = pageSize || preferences.displayMode?.itemsPerPage || DEFAULT_PAGE_SIZE; const effectivePageSize = pageSize || preferences.displayMode?.itemsPerPage || DEFAULT_PAGE_SIZE;
// Sync avec les props initiales quand elles changent (navigation via URL)
useEffect(() => { useEffect(() => {
const fetchData = async () => { setSeries(initialSeries);
setLoading(true); setBooks(initialBooks);
setError(null); }, [initialSeries, initialBooks]);
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) {
logger.error({ err }, "Error fetching series books");
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) => { const handleRefresh = async (seriesId: string) => {
try { try {

View File

@@ -1,4 +1,5 @@
import { PreferencesService } from "@/lib/services/preferences.service"; import { PreferencesService } from "@/lib/services/preferences.service";
import { SeriesService } from "@/lib/services/series.service";
import { ClientSeriesPage } from "./ClientSeriesPage"; import { ClientSeriesPage } from "./ClientSeriesPage";
import type { UserPreferences } from "@/types/preferences"; import type { UserPreferences } from "@/types/preferences";
@@ -7,6 +8,8 @@ interface PageProps {
searchParams: Promise<{ page?: string; unread?: string; size?: string }>; searchParams: Promise<{ page?: string; unread?: string; size?: string }>;
} }
const DEFAULT_PAGE_SIZE = 20;
export default async function SeriesPage({ params, searchParams }: PageProps) { export default async function SeriesPage({ params, searchParams }: PageProps) {
const seriesId = (await params).seriesId; const seriesId = (await params).seriesId;
const page = (await searchParams).page; const page = (await searchParams).page;
@@ -18,6 +21,15 @@ export default async function SeriesPage({ params, searchParams }: PageProps) {
// Utiliser le paramètre d'URL s'il existe, sinon utiliser la préférence utilisateur // Utiliser le paramètre d'URL s'il existe, sinon utiliser la préférence utilisateur
const unreadOnly = unread !== undefined ? unread === "true" : preferences.showOnlyUnread; const unreadOnly = unread !== undefined ? unread === "true" : preferences.showOnlyUnread;
const effectivePageSize = size
? parseInt(size)
: preferences.displayMode?.itemsPerPage || DEFAULT_PAGE_SIZE;
// Fetch côté serveur
const [books, series] = await Promise.all([
SeriesService.getSeriesBooks(seriesId, currentPage - 1, effectivePageSize, unreadOnly),
SeriesService.getSeries(seriesId),
]);
return ( return (
<ClientSeriesPage <ClientSeriesPage
@@ -25,7 +37,9 @@ export default async function SeriesPage({ params, searchParams }: PageProps) {
currentPage={currentPage} currentPage={currentPage}
preferences={preferences} preferences={preferences}
unreadOnly={unreadOnly} unreadOnly={unreadOnly}
pageSize={size ? parseInt(size) : undefined} pageSize={effectivePageSize}
initialSeries={series}
initialBooks={books}
/> />
); );
} }

View File

@@ -66,7 +66,7 @@ export class SeriesService extends BaseApiService {
{ {
path: "books/list", path: "books/list",
params: { params: {
size: "1000", // On récupère un maximum de livres size: "5000", // On récupère un maximum de livres
}, },
}, },
headers, headers,