diff --git a/src/components/home/HeroSection.tsx b/src/components/home/HeroSection.tsx index 758ba30..23d7a86 100644 --- a/src/components/home/HeroSection.tsx +++ b/src/components/home/HeroSection.tsx @@ -1,7 +1,8 @@ "use client"; -import { Cover } from "@/components/ui/cover"; +import { SeriesCover } from "@/components/ui/series-cover"; import { useTranslate } from "@/hooks/useTranslate"; +import { KomgaSeries } from "@/types/komga"; interface OptimizedHeroSeries { id: string; @@ -31,9 +32,8 @@ export function HeroSection({ series }: HeroSectionProps) { key={series.id} className="relative aspect-[2/3] bg-muted rounded-lg overflow-hidden" > -
{isSeries ? ( - + ) : ( - + )} {/* Overlay avec les informations au survol */}
diff --git a/src/components/library/LibraryGrid.tsx b/src/components/library/LibraryGrid.tsx deleted file mode 100644 index 0ec2246..0000000 --- a/src/components/library/LibraryGrid.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { Book } from "lucide-react"; -import { Cover } from "@/components/ui/cover"; -import { KomgaLibrary } from "@/types/komga"; -import { useTranslate } from "@/hooks/useTranslate"; - -interface LibraryGridProps { - libraries: KomgaLibrary[]; - onLibraryClick?: (library: KomgaLibrary) => void; -} - -// Utility function to format date safely -const formatDate = (dateString: string, locale: string): string => { - try { - const date = new Date(dateString); - if (isNaN(date.getTime())) { - return "Date unavailable"; - } - return new Intl.DateTimeFormat(locale, { - year: "numeric", - month: "long", - day: "numeric", - }).format(date); - } catch (error) { - console.error("Error formatting date:", error); - return "Date unavailable"; - } -}; - -export function LibraryGrid({ libraries, onLibraryClick }: LibraryGridProps) { - const { t } = useTranslate(); - - if (!libraries.length) { - return ( -
-

{t("library.empty")}

-
- ); - } - - return ( -
- {libraries.map((library) => ( - onLibraryClick?.(library)} /> - ))} -
- ); -} - -interface LibraryCardProps { - library: KomgaLibrary; - onClick?: () => void; -} - -function LibraryCard({ library, onClick }: LibraryCardProps) { - const { t, i18n } = useTranslate(); - - return ( - - ); -} diff --git a/src/components/library/SeriesGrid.tsx b/src/components/library/SeriesGrid.tsx index bc4b171..6477d10 100644 --- a/src/components/library/SeriesGrid.tsx +++ b/src/components/library/SeriesGrid.tsx @@ -3,7 +3,7 @@ import { KomgaSeries } from "@/types/komga"; import { useRouter } from "next/navigation"; import { cn } from "@/lib/utils"; -import { Cover } from "@/components/ui/cover"; +import { SeriesCover } from "@/components/ui/series-cover"; import { useTranslate } from "@/hooks/useTranslate"; interface SeriesGridProps { @@ -65,13 +65,11 @@ export function SeriesGrid({ series }: SeriesGridProps) { series.booksCount === series.booksReadCount && "opacity-50" )} > -

{series.metadata.title}

diff --git a/src/components/series/BookGrid.tsx b/src/components/series/BookGrid.tsx index f775c81..7086fe8 100644 --- a/src/components/series/BookGrid.tsx +++ b/src/components/series/BookGrid.tsx @@ -2,7 +2,7 @@ import { KomgaBook } from "@/types/komga"; import { formatDate } from "@/lib/utils"; -import { Cover } from "@/components/ui/cover"; +import { BookCover } from "@/components/ui/book-cover"; import { MarkAsReadButton } from "@/components/ui/mark-as-read-button"; import { MarkAsUnreadButton } from "@/components/ui/mark-as-unread-button"; import { BookOfflineButton } from "@/components/ui/book-offline-button"; @@ -106,7 +106,6 @@ export function BookGrid({ books, onBookClick }: BookGridProps) { const statusInfo = getReadingStatusInfo(book, t); const isRead = book.readProgress?.completed || false; const hasReadProgress = book.readProgress !== null; - const currentPage = ClientOfflineBookService.getCurrentPage(book); return (
onBookClick(book)} className="w-full h-full hover:opacity-100 transition-all" > - diff --git a/src/components/series/SeriesHeader.tsx b/src/components/series/SeriesHeader.tsx index 5b783e4..b41a847 100644 --- a/src/components/series/SeriesHeader.tsx +++ b/src/components/series/SeriesHeader.tsx @@ -5,12 +5,12 @@ import { KomgaSeries } from "@/types/komga"; import { useState, useEffect } from "react"; import { Button } from "../ui/button"; import { useToast } from "@/components/ui/use-toast"; -import { Cover } from "@/components/ui/cover"; 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"; interface SeriesHeaderProps { series: KomgaSeries; @@ -122,9 +122,8 @@ export const SeriesHeader = ({ series, refreshSeries }: SeriesHeaderProps) => {
{/* Image de fond */}
- {
{/* Image principale */}
- diff --git a/src/components/ui/book-cover.tsx b/src/components/ui/book-cover.tsx new file mode 100644 index 0000000..e5760e0 --- /dev/null +++ b/src/components/ui/book-cover.tsx @@ -0,0 +1,37 @@ +"use client"; + +import { CoverClient } from "./cover-client"; +import { ProgressBar } from "./progress-bar"; +import { BookCoverProps, getImageUrl } from "./cover-utils"; +import { ClientOfflineBookService } from "@/lib/services/client-offlinebook.service"; + +export function BookCover({ + book, + alt = "Image de couverture", + className, + quality = 80, + sizes = "100vw", +}: BookCoverProps) { + if (!book) return null; + + const imageUrl = getImageUrl("book", book.id); + const isCompleted = book.readProgress?.completed || false; + + const currentPage = ClientOfflineBookService.getCurrentPage(book); + const totalPages = book.media.pagesCount; + const showProgress = currentPage && totalPages && currentPage > 0 && !isCompleted; + + return ( +
+ + {showProgress && } +
+ ); +} diff --git a/src/components/ui/cover-utils.tsx b/src/components/ui/cover-utils.tsx new file mode 100644 index 0000000..7e58bd9 --- /dev/null +++ b/src/components/ui/cover-utils.tsx @@ -0,0 +1,23 @@ +import { KomgaBook, KomgaSeries } from "@/types/komga"; + +export interface BaseCoverProps { + alt?: string; + className?: string; + quality?: number; + sizes?: string; +} + +export interface BookCoverProps extends BaseCoverProps { + book?: KomgaBook; +} + +export interface SeriesCoverProps extends BaseCoverProps { + series: KomgaSeries; +} + +export function getImageUrl(type: "series" | "book", id: string) { + if (type === "series") { + return `/api/komga/images/series/${id}/thumbnail`; + } + return `/api/komga/images/books/${id}/thumbnail`; +} diff --git a/src/components/ui/cover.tsx b/src/components/ui/cover.tsx deleted file mode 100644 index e3a8a0a..0000000 --- a/src/components/ui/cover.tsx +++ /dev/null @@ -1,79 +0,0 @@ -"use client"; - -import { CoverClient } from "./cover-client"; -import { ProgressBar } from "./progress-bar"; - -interface BaseCoverProps { - type: "series" | "book"; - id: string; - alt?: string; - className?: string; - quality?: number; - sizes?: string; - isCompleted?: boolean; -} - -interface BookCoverProps extends BaseCoverProps { - type: "book"; - currentPage?: number; - totalPages?: number; -} - -interface SeriesCoverProps extends BaseCoverProps { - type: "series"; - readBooks?: number; - totalBooks?: number; -} - -type CoverProps = BookCoverProps | SeriesCoverProps; - -function getImageUrl(type: "series" | "book", id: string) { - if (type === "series") { - return `/api/komga/images/series/${id}/thumbnail`; - } - return `/api/komga/images/books/${id}/thumbnail`; -} - -export function Cover(props: CoverProps) { - const { - type, - id, - alt = "Image de couverture", - className, - quality = 80, - sizes = "100vw", - isCompleted = false, - } = props; - - const imageUrl = getImageUrl(type, id); - - const showProgress = () => { - if (type === "book") { - const { currentPage, totalPages } = props; - return currentPage && totalPages && currentPage > 0 && !isCompleted ? ( - - ) : null; - } - - if (type === "series") { - const { readBooks, totalBooks } = props; - return readBooks && totalBooks && readBooks > 0 && !isCompleted ? ( - - ) : null; - } - }; - - return ( -
- - {showProgress()} -
- ); -} diff --git a/src/components/ui/series-cover.tsx b/src/components/ui/series-cover.tsx new file mode 100644 index 0000000..a7fd910 --- /dev/null +++ b/src/components/ui/series-cover.tsx @@ -0,0 +1,36 @@ +"use client"; + +import { CoverClient } from "./cover-client"; +import { ProgressBar } from "./progress-bar"; +import { SeriesCoverProps, getImageUrl } from "./cover-utils"; + +export function SeriesCover({ + series, + alt = "Image de couverture", + className, + quality = 80, + sizes = "100vw", +}: SeriesCoverProps) { + if (!series) return null; + + const imageUrl = getImageUrl("series", series.id); + const isCompleted = series.booksCount === series.booksReadCount; + + const readBooks = series.booksReadCount; + const totalBooks = series.booksCount; + const showProgress = readBooks && totalBooks && readBooks > 0 && !isCompleted; + + return ( +
+ + {showProgress && } +
+ ); +}