feat(12-01): PreviewModal component with react-pdf Document/Page

- 'use client' component accepting ArrayBuffer prop and onClose callback
- Configures pdfjs worker independently from PdfViewer module
- Imports AnnotationLayer.css and TextLayer.css
- Prev/Next page navigation with disabled states
- Fixed overlay (rgba black 70%) with white inner container
This commit is contained in:
Chandler Copeland
2026-03-21 15:30:07 -06:00
parent 99205bca9f
commit f4589391ff

View File

@@ -0,0 +1,79 @@
'use client';
import { useState } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/Page/AnnotationLayer.css';
import 'react-pdf/dist/Page/TextLayer.css';
// Worker setup — configured independently from PdfViewer (separate module)
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
'pdfjs-dist/build/pdf.worker.min.mjs',
import.meta.url,
).toString();
interface PreviewModalProps {
pdfBytes: ArrayBuffer;
onClose: () => void;
}
export function PreviewModal({ pdfBytes, onClose }: PreviewModalProps) {
const [numPages, setNumPages] = useState(0);
const [pageNumber, setPageNumber] = useState(1);
return (
<div
style={{
position: 'fixed',
inset: 0,
background: 'rgba(0,0,0,0.7)',
zIndex: 50,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}
>
<div
style={{
background: 'white',
maxWidth: '900px',
width: '90vw',
maxHeight: '90vh',
overflowY: 'auto',
padding: '16px',
}}
>
{/* Navigation controls */}
<div className="flex items-center gap-3 text-sm mb-4">
<button
onClick={() => setPageNumber(p => Math.max(1, p - 1))}
disabled={pageNumber <= 1}
className="px-3 py-1 border rounded disabled:opacity-40 hover:bg-gray-100"
>
Prev
</button>
<span>{pageNumber} / {numPages || '?'}</span>
<button
onClick={() => setPageNumber(p => Math.min(numPages, p + 1))}
disabled={pageNumber >= numPages}
className="px-3 py-1 border rounded disabled:opacity-40 hover:bg-gray-100"
>
Next
</button>
<button
onClick={onClose}
className="ml-auto px-3 py-1 border rounded hover:bg-gray-100"
>
Close
</button>
</div>
{/* PDF renderer */}
<Document
file={pdfBytes}
onLoadSuccess={({ numPages }) => setNumPages(numPages)}
>
<Page pageNumber={pageNumber} />
</Document>
</div>
</div>
);
}