"use client"; import { Book, BookOpen, BookMarked, Star, StarOff } from "lucide-react"; import type { KomgaSeries } from "@/types/komga"; import { useState, useEffect } from "react"; import { useToast } from "@/components/ui/use-toast"; import { RefreshButton } from "@/components/library/RefreshButton"; import { AppError } from "@/utils/errors"; import { ERROR_CODES } from "@/constants/errorCodes"; import { getErrorMessage } from "@/utils/errors"; import { useTranslate } from "@/hooks/useTranslate"; import { SeriesCover } from "@/components/ui/series-cover"; import { StatusBadge } from "@/components/ui/status-badge"; import { IconButton } from "@/components/ui/icon-button"; import logger from "@/lib/logger"; interface SeriesHeaderProps { series: KomgaSeries; refreshSeries: (seriesId: string) => Promise<{ success: boolean; error?: string }>; } export const SeriesHeader = ({ series, refreshSeries }: SeriesHeaderProps) => { const { toast } = useToast(); const [isFavorite, setIsFavorite] = useState(false); const { t } = useTranslate(); useEffect(() => { const checkFavorite = async () => { try { const response = await fetch("/api/komga/favorites"); if (!response.ok) { throw new AppError(ERROR_CODES.FAVORITE.STATUS_CHECK_ERROR); } const favoriteIds = await response.json(); setIsFavorite(favoriteIds.includes(series.id)); } catch (error) { logger.error({ err: error }, "Erreur lors de la vérification des favoris:"); toast({ title: "Erreur", description: error instanceof AppError ? error.message : getErrorMessage(ERROR_CODES.FAVORITE.NETWORK_ERROR), variant: "destructive", }); } }; checkFavorite(); }, [series.id, toast]); const handleToggleFavorite = async () => { try { 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) { setIsFavorite(!isFavorite); // Dispatcher l'événement avec le seriesId pour mise à jour optimiste de la sidebar const event = new CustomEvent("favoritesChanged", { detail: { seriesId: series.id, action: isFavorite ? "remove" : "add" }, }); window.dispatchEvent(event); toast({ title: t(isFavorite ? "series.header.favorite.remove" : "series.header.favorite.add"), description: series.metadata.title, }); } else if (response.status === 500) { throw new AppError(ERROR_CODES.FAVORITE.SERVER_ERROR); } else if (response.status === 404) { throw new AppError(ERROR_CODES.FAVORITE.UPDATE_ERROR); } else { throw new AppError( isFavorite ? ERROR_CODES.FAVORITE.DELETE_ERROR : ERROR_CODES.FAVORITE.ADD_ERROR ); } } catch (error) { logger.error({ err: error }, "Erreur lors de la modification des favoris:"); toast({ title: "Erreur", description: error instanceof AppError ? error.message : getErrorMessage(ERROR_CODES.FAVORITE.NETWORK_ERROR), variant: "destructive", }); } }; const getReadingStatusInfo = () => { const { booksCount, booksReadCount, booksUnreadCount } = series; const booksInProgressCount = booksCount - (booksReadCount + booksUnreadCount); if (booksReadCount === booksCount) { return { label: t("series.header.status.read"), status: "success" as const, icon: BookMarked, }; } if (booksInProgressCount > 0 || (booksReadCount > 0 && booksReadCount < booksCount)) { return { label: t("series.header.status.progress", { read: booksReadCount, total: booksCount, }), status: "reading" as const, icon: BookOpen, }; } return { label: t("series.header.status.unread"), status: "unread" as const, icon: Book, }; }; const statusInfo = getReadingStatusInfo(); return (
{series.metadata.summary}
)}