import { useEffect, useMemo, useRef, useState } from "react"; import { Document, Page, pdfjs } from "react-pdf"; import { ChevronLeft, ChevronRight, ZoomIn, ZoomOut, Loader2 } from "lucide-react"; import { pdfUrl } from "@/lib/api"; import { Button } from "@/components/ui/button"; // pdf.js worker (bundled by Vite) pdfjs.GlobalWorkerOptions.workerSrc = new URL( "pdfjs-dist/build/pdf.worker.min.mjs", import.meta.url, ).toString(); export function PdfViewer({ filename, page, highlights, onPageChange, }: { filename: string | null; page: number; highlights: number[][]; onPageChange: (p: number) => void; }) { const containerRef = useRef(null); const [containerWidth, setContainerWidth] = useState(600); const [numPages, setNumPages] = useState(0); const [zoom, setZoom] = useState(1); const [renderScale, setRenderScale] = useState(1); // px per PDF point useEffect(() => { if (!containerRef.current) return; const el = containerRef.current; const ro = new ResizeObserver(() => setContainerWidth(el.clientWidth - 32)); ro.observe(el); setContainerWidth(el.clientWidth - 32); return () => ro.disconnect(); }, []); const file = useMemo(() => (filename ? pdfUrl(filename) : null), [filename]); const pageWidth = Math.max(200, containerWidth * zoom); if (!file) { return (
Upload or select a document to preview it here
); } return (
{/* toolbar */}
Page {page} / {numPages || "…"}
{Math.round(zoom * 100)}%
{/* page */}
setNumPages(pdf.numPages)} loading={
Loading document…
} error={
Failed to load PDF.
} className="flex justify-center" >
setRenderScale(pageWidth / p.originalWidth)} /> {/* highlight overlay (PDF points → pixels via renderScale) */}
{highlights.map((b, i) => (
))}
); }