"use client"; import { Home, Library, Settings, LogOut, RefreshCw, Star, Download } from "lucide-react"; import { usePathname, useRouter } from "next/navigation"; import { cn } from "@/lib/utils"; import { authService } from "@/lib/services/auth.service"; import { useEffect, useState, useCallback } from "react"; import { KomgaLibrary, KomgaSeries } from "@/types/komga"; import { usePreferences } from "@/contexts/PreferencesContext"; import { AppError } from "@/utils/errors"; import { ERROR_CODES } from "@/constants/errorCodes"; import { ERROR_MESSAGES } from "@/constants/errorMessages"; import { useToast } from "@/components/ui/use-toast"; interface SidebarProps { isOpen: boolean; onClose: () => void; } export function Sidebar({ isOpen, onClose }: SidebarProps) { const pathname = usePathname(); const router = useRouter(); const { preferences } = usePreferences(); const [libraries, setLibraries] = useState([]); const [favorites, setFavorites] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isRefreshing, setIsRefreshing] = useState(false); const [isLoadingFavorites, setIsLoadingFavorites] = useState(true); const { toast } = useToast(); const fetchLibraries = useCallback(async () => { setIsLoading(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) { console.error("Erreur de chargement des bibliothèques:", error); toast({ title: "Erreur", description: error instanceof AppError ? error.message : ERROR_MESSAGES[ERROR_CODES.LIBRARY.FETCH_ERROR], variant: "destructive", }); setLibraries([]); } finally { setIsLoading(false); setIsRefreshing(false); } }, [toast]); const fetchFavorites = useCallback(async () => { setIsLoadingFavorites(true); try { const favoritesResponse = await fetch("/api/komga/favorites"); if (!favoritesResponse.ok) { throw new AppError(ERROR_CODES.FAVORITE.FETCH_ERROR); } const favoriteIds = await favoritesResponse.json(); if (favoriteIds.length === 0) { setFavorites([]); return; } const promises = favoriteIds.map(async (id: string) => { const response = await fetch(`/api/komga/series/${id}`); if (!response.ok) { throw new AppError(ERROR_CODES.SERIES.FETCH_ERROR); } return response.json(); }); const results = await Promise.all(promises); setFavorites(results.filter((series): series is KomgaSeries => series !== null)); } catch (error) { console.error("Erreur de chargement des favoris:", error); toast({ title: "Erreur", description: error instanceof AppError ? error.message : ERROR_MESSAGES[ERROR_CODES.FAVORITE.FETCH_ERROR], variant: "destructive", }); setFavorites([]); } finally { setIsLoadingFavorites(false); } }, [toast]); // Chargement initial des données useEffect(() => { fetchLibraries(); fetchFavorites(); }, [fetchLibraries, fetchFavorites]); // Rafraîchir les données quand les préférences changent useEffect(() => { fetchLibraries(); fetchFavorites(); }, [preferences, fetchLibraries, fetchFavorites]); // Mettre à jour les favoris quand ils changent useEffect(() => { const handleFavoritesChange = () => { fetchFavorites(); }; window.addEventListener("favoritesChanged", handleFavoritesChange); return () => { window.removeEventListener("favoritesChanged", handleFavoritesChange); }; }, [fetchFavorites]); const handleRefresh = async () => { setIsRefreshing(true); await Promise.all([fetchLibraries(), fetchFavorites()]); }; const handleLogout = async () => { try { await authService.logout(); setLibraries([]); setFavorites([]); onClose(); router.push("/login"); } catch (error) { console.error("Erreur lors de la déconnexion:", error); toast({ title: "Erreur", description: error instanceof AppError ? error.message : ERROR_MESSAGES[ERROR_CODES.AUTH.LOGOUT_ERROR], variant: "destructive", }); } }; const handleLinkClick = useCallback( async (path: string) => { if (pathname === path) { onClose(); return; } window.dispatchEvent(new Event("navigationStart")); router.push(path); onClose(); // On attend que la page soit chargée await new Promise((resolve) => setTimeout(resolve, 300)); window.dispatchEvent(new Event("navigationComplete")); }, [pathname, router, onClose] ); const mainNavItems = [ { title: "Accueil", href: "/", icon: Home, }, { title: "Téléchargements", href: "/downloads", icon: Download, }, ]; return ( ); }