"use client"; import Image from "next/image"; import { ImageOff, Book, BookOpen, BookMarked, Star, StarOff } from "lucide-react"; import { KomgaSeries } from "@/types/komga"; import { useState, useEffect } from "react"; import { Button } from "../ui/button"; import { useToast } from "@/components/ui/use-toast"; import { cn } from "@/lib/utils"; interface SeriesHeaderProps { series: KomgaSeries; onSeriesUpdate?: (series: KomgaSeries) => void; } interface ReadingStatusInfo { label: string; className: string; icon: React.ElementType; } // Fonction utilitaire pour obtenir les informations de lecture d'une série const getReadingStatusInfo = (series: KomgaSeries): ReadingStatusInfo => { const { booksCount, booksReadCount, booksUnreadCount } = series; const booksInProgressCount = booksCount - (booksReadCount + booksUnreadCount); if (booksReadCount === booksCount) { return { label: "Lu", className: "bg-green-500/10 text-green-500", icon: BookOpen, }; } if (booksInProgressCount > 0 || (booksReadCount > 0 && booksReadCount < booksCount)) { return { label: `${booksReadCount}/${booksCount}`, className: "bg-blue-500/10 text-blue-500", icon: BookMarked, }; } return { label: "Non lu", className: "bg-yellow-500/10 text-yellow-500", icon: Book, }; }; export const SeriesHeader = ({ series, onSeriesUpdate }: SeriesHeaderProps) => { const { toast } = useToast(); const [languageDisplay, setLanguageDisplay] = useState(series.metadata.language); const [imageError, setImageError] = useState(false); const [readingStatus, setReadingStatus] = useState( getReadingStatusInfo(series) ); const [isFavorite, setIsFavorite] = useState(false); const [isLoading, setIsLoading] = useState(false); const [mounted, setMounted] = useState(false); // Vérifier si la série est dans les favoris au chargement useEffect(() => { const checkFavorite = async () => { try { const response = await fetch("/api/komga/favorites"); if (response.ok) { const favoriteIds = await response.json(); setIsFavorite(favoriteIds.includes(series.id)); } } catch (error) { console.error("Erreur lors de la vérification des favoris:", error); } }; checkFavorite(); setMounted(true); }, [series.id]); useEffect(() => { setReadingStatus(getReadingStatusInfo(series)); }, [series]); useEffect(() => { try { if (series.metadata.language) { const displayNames = new Intl.DisplayNames([navigator.language || "fr-FR"], { type: "language", }); setLanguageDisplay(displayNames.of(series.metadata.language) || series.metadata.language); } } catch (error) { console.error("Erreur lors de la traduction de la langue:", error); setLanguageDisplay(series.metadata.language); } }, [series.metadata.language]); const handleToggleFavorite = async () => { try { setIsLoading(true); const response = await fetch("/api/komga/favorites", { method: isFavorite ? "DELETE" : "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ seriesId: series.id }), }); if (!response.ok) { throw new Error("Erreur lors de la modification des favoris"); } setIsFavorite(!isFavorite); if (onSeriesUpdate) { onSeriesUpdate({ ...series, favorite: !isFavorite }); } // Dispatch l'événement pour notifier les autres composants window.dispatchEvent(new Event("favoritesChanged")); toast({ title: isFavorite ? "Retiré des favoris" : "Ajouté aux favoris", variant: "default", }); } catch (error) { toast({ title: "Une erreur est survenue", variant: "destructive", }); } finally { setIsLoading(false); } }; const StatusIcon = readingStatus.icon; return (
{/* Fond flou */}
{!imageError && (
)}
{/* Contenu */}
{/* Image de couverture */}
{!imageError ? (
{series.name} setImageError(true)} priority unoptimized />
) : (
)}
{/* Informations */}

{series.name}

{mounted && ( )}
{/* Métadonnées */}
{series.metadata.publisher && ( {series.metadata.publisher} )} {languageDisplay && ( {languageDisplay} )} {series.metadata.status && ( {series.metadata.status.toLowerCase()} )}
{/* Stats */}
{readingStatus.label}
{series.booksCount} tomes {series.booksReadCount} lus {series.booksInProgressCount} en cours
{/* Description */} {series.metadata.summary && (

{series.metadata.summary}

)} {/* Tags et genres */} {(series.metadata.tags?.length > 0 || series.metadata.genres?.length > 0) && (
{[...(series.metadata.genres || []), ...(series.metadata.tags || [])].map((tag) => ( {tag} ))}
)}
); };