"use client"; import { Book, BookOpen, BookMarked, BookX, Star, StarOff, User } from "lucide-react"; import type { NormalizedSeries } from "@/lib/providers/types"; 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"; import { addToFavorites, removeFromFavorites } from "@/app/actions/favorites"; import { useAnonymous } from "@/contexts/AnonymousContext"; interface SeriesHeaderProps { series: NormalizedSeries; refreshSeries: (seriesId: string) => Promise<{ success: boolean; error?: string }>; initialIsFavorite: boolean; } export const SeriesHeader = ({ series, refreshSeries, initialIsFavorite }: SeriesHeaderProps) => { const { toast } = useToast(); const { isAnonymous } = useAnonymous(); const [isFavorite, setIsFavorite] = useState(initialIsFavorite); const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false); const { t } = useTranslate(); useEffect(() => { setIsFavorite(initialIsFavorite); }, [series.id, initialIsFavorite]); const handleToggleFavorite = async () => { try { const action = isFavorite ? removeFromFavorites : addToFavorites; const result = await action(series.id); if (result.success) { 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", series: isFavorite ? undefined : series, }, }); window.dispatchEvent(event); toast({ title: t(isFavorite ? "series.header.favorite.remove" : "series.header.favorite.add"), description: series.name, }); } 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 { bookCount, booksReadCount } = series; const booksUnreadCount = bookCount - booksReadCount; const booksInProgressCount = bookCount - (booksReadCount + booksUnreadCount); if (booksReadCount === bookCount) { return { label: t("series.header.status.read"), status: "success" as const, icon: BookMarked, }; } if (booksInProgressCount > 0 || (booksReadCount > 0 && booksReadCount < bookCount)) { return { label: t("series.header.status.progress", { read: booksReadCount, total: bookCount, }), status: "reading" as const, icon: BookOpen, }; } return { label: t("series.header.status.unread"), status: "unread" as const, icon: Book, }; }; const statusInfo = isAnonymous ? null : getReadingStatusInfo(); const authorsText = series.authors?.length ? series.authors.map((a) => a.name).join(", ") : null; return (
{series.summary}