diff --git a/src/app/epub/[id]/page.tsx b/src/app/epub/[id]/page.tsx new file mode 100644 index 0000000..acc40c8 --- /dev/null +++ b/src/app/epub/[id]/page.tsx @@ -0,0 +1,33 @@ +'use client'; + +import { useParams } from "next/navigation"; +import Link from 'next/link'; + +export default function EPUBPage() { + const { id } = useParams(); + + return ( + <> +
+
+
+ { }} + className="inline-flex items-center px-3 py-1 bg-base text-foreground rounded-lg hover:bg-offbase transform transition-transform duration-200 ease-in-out hover:scale-[1.02]" + > + + + + Documents + +
+

+ {id} +

+
+
+ + + ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index 7a08e77..9472cb3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,7 +1,7 @@ 'use client'; import { useState } from 'react'; -import { PDFUploader } from '@/components/PDFUploader'; +import { DocumentUploader } from '@/components/DocumentUploader'; import { DocumentList } from '@/components/DocumentList'; import { SettingsModal } from '@/components/SettingsModal'; import { SettingsIcon } from '@/components/icons/Icons'; @@ -23,7 +23,7 @@ export default function Home() {

OpenReader WebUI

A bring your own text-to-speech api web interface for reading documents with high quality voices

- +
diff --git a/src/app/pdf/[id]/page.tsx b/src/app/pdf/[id]/page.tsx index 92afb34..591a86c 100644 --- a/src/app/pdf/[id]/page.tsx +++ b/src/app/pdf/[id]/page.tsx @@ -5,7 +5,7 @@ import { usePDF } from '@/contexts/PDFContext'; import { useParams } from 'next/navigation'; import Link from 'next/link'; import { useCallback, useEffect, useState } from 'react'; -import { PDFSkeleton } from '@/components/PDFSkeleton'; +import { DocumentSkeleton } from '@/components/DocumentSkeleton'; import { useTTS } from '@/contexts/TTSContext'; import { Button } from '@headlessui/react'; import { PDFViewSettings } from '@/components/PDFViewSettings'; @@ -16,7 +16,7 @@ const PDFViewer = dynamic( () => import('@/components/PDFViewer').then((module) => module.PDFViewer), { ssr: false, - loading: () => + loading: () => } ); @@ -118,7 +118,7 @@ export default function PDFViewerPage() { {isLoading ? (
- +
) : ( diff --git a/src/components/DocumentList.tsx b/src/components/DocumentList.tsx index 06a3ecf..0d0cb33 100644 --- a/src/components/DocumentList.tsx +++ b/src/components/DocumentList.tsx @@ -1,27 +1,44 @@ import { usePDF } from '@/contexts/PDFContext'; +import { useEpubDocuments } from '@/hooks/epub/useEpubDocuments'; import Link from 'next/link'; import { Button, Dialog } from '@headlessui/react'; import { Transition, TransitionChild, DialogPanel, DialogTitle } from '@headlessui/react'; import { Fragment, useState } from 'react'; +type DocumentToDelete = { + id: string; + name: string; + type: 'pdf' | 'epub'; +}; + export function DocumentList() { - const { documents, removeDocument, isDocsLoading } = usePDF(); + const { documents: pdfDocs, removeDocument: removePDF, isDocsLoading: isPDFLoading } = usePDF(); + const { documents: epubDocs, removeDocument: removeEPUB, isLoading: isEPUBLoading } = useEpubDocuments(); const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); - const [documentToDelete, setDocumentToDelete] = useState<{ id: string; name: string } | null>(null); + const [documentToDelete, setDocumentToDelete] = useState(null); const handleDelete = async () => { - if (documentToDelete) { - try { - await removeDocument(documentToDelete.id); - setIsDeleteDialogOpen(false); - setDocumentToDelete(null); - } catch (err) { - console.error('Failed to remove document:', err); + if (!documentToDelete) return; + + try { + if (documentToDelete.type === 'pdf') { + await removePDF(documentToDelete.id); + } else { + await removeEPUB(documentToDelete.id); } + setIsDeleteDialogOpen(false); + setDocumentToDelete(null); + } catch (err) { + console.error('Failed to remove document:', err); } }; - if (isDocsLoading) { + const allDocuments = [ + ...pdfDocs.map(doc => ({ ...doc, type: 'pdf' as const })), + ...epubDocs.map(doc => ({ ...doc, type: 'epub' as const })), + ].sort((a, b) => b.lastModified - a.lastModified); + + if (isPDFLoading || isEPUBLoading) { return (
Loading documents... @@ -29,7 +46,7 @@ export function DocumentList() { ); } - if (documents.length === 0) { + if (allDocuments.length === 0) { return (
No documents uploaded yet @@ -41,9 +58,9 @@ export function DocumentList() {

Your Documents

- {documents.map((doc) => ( + {allDocuments.map((doc) => ( -
+
- - - + {doc.type === 'pdf' ? ( + + + + ) : ( + + + + )}
-

{doc.name}

+
+

{doc.name}

+ + {doc.type} + +

{(doc.size / 1024 / 1024).toFixed(2)} MB

@@ -73,7 +99,7 @@ export function DocumentList() {