feat: enhance home and library pages by integrating new data fetching methods, improving error handling, and refactoring components for better structure
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 4m17s

This commit is contained in:
Julien Froidefond
2026-01-04 06:19:45 +01:00
parent 489e570348
commit b497746cfa
19 changed files with 598 additions and 834 deletions

View File

@@ -16,7 +16,6 @@ import { cn } from "@/lib/utils";
import { signOut } from "next-auth/react";
import { useEffect, useState, useCallback } from "react";
import type { KomgaLibrary, KomgaSeries } from "@/types/komga";
import { usePreferences } from "@/contexts/PreferencesContext";
import { AppError } from "@/utils/errors";
import { ERROR_CODES } from "@/constants/errorCodes";
import { getErrorMessage } from "@/utils/errors";
@@ -26,10 +25,6 @@ import { NavButton } from "@/components/ui/nav-button";
import { IconButton } from "@/components/ui/icon-button";
import logger from "@/lib/logger";
// Module-level flags to prevent duplicate fetches (survives StrictMode remounts)
let sidebarInitialFetchDone = false;
let sidebarFetchInProgress = false;
interface SidebarProps {
isOpen: boolean;
onClose: () => void;
@@ -48,37 +43,12 @@ export function Sidebar({
const { t } = useTranslate();
const pathname = usePathname();
const router = useRouter();
const { preferences } = usePreferences();
const [libraries, setLibraries] = useState<KomgaLibrary[]>(initialLibraries || []);
const [favorites, setFavorites] = useState<KomgaSeries[]>(initialFavorites || []);
const [isRefreshing, setIsRefreshing] = useState(false);
const { toast } = useToast();
const refreshLibraries = useCallback(async () => {
setIsRefreshing(true);
try {
const response = await fetch("/api/komga/libraries");
if (!response.ok) {
throw new AppError(ERROR_CODES.LIBRARY.FETCH_ERROR);
}
const data = await response.json();
setLibraries(data);
} catch (error) {
logger.error({ err: error }, "Erreur de chargement des bibliothèques:");
toast({
title: "Erreur",
description:
error instanceof AppError
? error.message
: getErrorMessage(ERROR_CODES.LIBRARY.FETCH_ERROR),
variant: "destructive",
});
} finally {
setIsRefreshing(false);
}
}, [toast]);
const refreshFavorites = useCallback(async () => {
try {
const favoritesResponse = await fetch("/api/komga/favorites");
@@ -115,22 +85,6 @@ export function Sidebar({
}
}, [toast]);
useEffect(() => {
// Only load once when preferences become available (module-level flag survives StrictMode)
if (
!sidebarInitialFetchDone &&
!sidebarFetchInProgress &&
Object.keys(preferences).length > 0
) {
sidebarFetchInProgress = true;
sidebarInitialFetchDone = true;
Promise.all([refreshLibraries(), refreshFavorites()]).finally(() => {
sidebarFetchInProgress = false;
});
}
}, [preferences, refreshLibraries, refreshFavorites]);
// Mettre à jour les favoris quand ils changent
useEffect(() => {
const handleFavoritesChange = () => {
@@ -146,15 +100,14 @@ export function Sidebar({
const handleRefresh = async () => {
setIsRefreshing(true);
await Promise.all([refreshLibraries(), refreshFavorites()]);
// Revalider côté serveur via router.refresh()
router.refresh();
// Petit délai pour laisser le temps au serveur
setTimeout(() => setIsRefreshing(false), 500);
};
const handleLogout = async () => {
try {
// Reset module-level flags to allow refetch on next login
sidebarInitialFetchDone = false;
sidebarFetchInProgress = false;
await signOut({ callbackUrl: "/login" });
setLibraries([]);
setFavorites([]);