"use client"; import { ChevronLeftIcon, ChevronRightIcon, ZoomInIcon, ZoomOutIcon } from "lucide-react"; import { useCallback, useRef, useState } from "react"; import { Document, Page, pdfjs } from "react-pdf"; import "react-pdf/dist/Page/AnnotationLayer.css"; import "react-pdf/dist/Page/TextLayer.css"; import { Button } from "@/components/ui/button"; import { Spinner } from "@/components/ui/spinner"; import { getAuthHeaders } from "@/lib/auth-utils"; pdfjs.GlobalWorkerOptions.workerSrc = new URL( "pdfjs-dist/build/pdf.worker.min.mjs", import.meta.url ).toString(); interface PdfViewerProps { pdfUrl: string; } const ZOOM_STEP = 0.15; const MIN_ZOOM = 0.5; const MAX_ZOOM = 3; export function PdfViewer({ pdfUrl }: PdfViewerProps) { const [numPages, setNumPages] = useState(0); const [pageNumber, setPageNumber] = useState(1); const [scale, setScale] = useState(1); const [loadError, setLoadError] = useState(null); const containerRef = useRef(null); const documentOptionsRef = useRef({ httpHeaders: getAuthHeaders() }); const onDocumentLoadSuccess = useCallback(({ numPages }: { numPages: number }) => { setNumPages(numPages); setPageNumber(1); setLoadError(null); }, []); const onDocumentLoadError = useCallback((error: Error) => { setLoadError(error.message || "Failed to load PDF"); }, []); const goToPrevPage = useCallback(() => { setPageNumber((prev) => Math.max(1, prev - 1)); }, []); const goToNextPage = useCallback(() => { setPageNumber((prev) => Math.min(numPages, prev + 1)); }, [numPages]); const zoomIn = useCallback(() => { setScale((prev) => Math.min(MAX_ZOOM, prev + ZOOM_STEP)); }, []); const zoomOut = useCallback(() => { setScale((prev) => Math.max(MIN_ZOOM, prev - ZOOM_STEP)); }, []); if (loadError) { return (

Failed to load resume preview

{loadError}

); } return (
{/* Controls bar */} {numPages > 0 && (
{numPages > 1 && ( <> {pageNumber} / {numPages}
)} {Math.round(scale * 100)}%
)} {/* PDF content */}
} > Failed to render page {pageNumber}
} />
); }