import clsx from 'clsx'; import React, { useEffect, useState } from 'react'; import Image from 'next/image'; import { Book } from '@/types/book'; import { BookDoc } from '@/libs/document'; import { useEnv } from '@/context/EnvContext'; import { useSettingsStore } from '@/store/settingsStore'; import { useTranslation } from '@/hooks/useTranslation'; import { useLibraryStore } from '@/store/libraryStore'; import { formatAuthors, formatDate, formatLanguage, formatPublisher, formatSubject, formatTitle, } from '@/utils/book'; import Alert from '@/components/Alert'; import Spinner from './Spinner'; import Dialog from './Dialog'; interface BookDetailModalProps { book: Book; isOpen: boolean; onClose: () => void; } const BookDetailModal = ({ book, isOpen, onClose }: BookDetailModalProps) => { const _ = useTranslation(); const [loading, setLoading] = useState(false); const [showDeleteAlert, setShowDeleteAlert] = useState(false); const [bookMeta, setBookMeta] = useState(null); const { envConfig, appService } = useEnv(); const { settings } = useSettingsStore(); const { updateBook } = useLibraryStore(); useEffect(() => { const loadingTimeout = setTimeout(() => setLoading(true), 300); const fetchBookDetails = async () => { const appService = await envConfig.getAppService(); try { const details = await appService.fetchBookDetails(book, settings); setBookMeta(details); } finally { if (loadingTimeout) clearTimeout(loadingTimeout); setLoading(false); } }; fetchBookDetails(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [book]); const handleClose = () => { setBookMeta(null); onClose(); }; const handleDelete = () => { setShowDeleteAlert(true); }; const confirmDelete = async () => { await appService?.deleteBook(book, !!book.uploadedAt); await updateBook(envConfig, book); handleClose(); setShowDeleteAlert(false); }; if (!bookMeta) return ( loading && (
) ); return (
{formatTitle(book.title)} { (e.target as HTMLImageElement).style.display = 'none'; (e.target as HTMLImageElement).nextElementSibling?.classList.remove( 'invisible', ); }} />
{formatTitle(book.title)}

{formatTitle(book.title) || _('Untitled')}

{formatAuthors(book.author, bookMeta.language) || _('Unknown')}

{window.innerWidth >= 400 && (
)}
{window.innerWidth < 400 && (
)}
{_('Publisher:')}

{formatPublisher(bookMeta.publisher || '') || _('Unknown')}

{_('Published:')}

{formatDate(bookMeta.published) || _('Unknown')}

{_('Updated:')}

{formatDate(book.lastUpdated) || ''}

{_('Language:')}

{formatLanguage(bookMeta.language) || _('Unknown')}

{_('Identifier:')}

{bookMeta.identifier || 'N/A'}

{_('Subjects:')}

{formatSubject(bookMeta.subject) || _('Unknown')}

{showDeleteAlert && (
{ setShowDeleteAlert(false); }} onConfirm={confirmDelete} />
)}
); }; export default BookDetailModal;