rafmacalaba's picture
Initial commit with Git LFS
7addaf4
Raw
History Blame Contribute Delete
2.46 kB
"use client";
import { useState, useEffect } from 'react';
export default function PdfViewer({ pdfUrl, pageNumber, searchTerm }) {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
// Reset loading state when URL or page changes
useEffect(() => {
setLoading(true);
setError(false);
}, [pdfUrl, pageNumber]);
if (!pdfUrl) {
return (
<div className="pdf-placeholder">
<p>No PDF available for this document.</p>
</div>
);
}
// PDF pages in our data are 0-indexed; PDF.js viewer expects 1-indexed pages
const viewerPage = (pageNumber ?? 0) + 1;
// Proxy/Route the PDF through our local PDF.js viewer to support highlighting and bypass CORS.
const isLocal = pdfUrl.startsWith('/') || pdfUrl.includes('localhost') || pdfUrl.includes('127.0.0.1');
const viewerPdfUrl = isLocal ? pdfUrl : `/api/pdf-proxy?url=${encodeURIComponent(pdfUrl)}`;
const proxyUrl = `/pdfjs/web/viewer.html?file=${encodeURIComponent(viewerPdfUrl)}#page=${viewerPage}${searchTerm ? `&search=${encodeURIComponent(searchTerm)}&phrase=true` : ''}`;
return (
<div className="pdf-container">
{loading && !error && (
<div className="pdf-loading">
<div className="loading-spinner" />
<p>Loading PDF...</p>
<p className="pdf-loading-hint">This may take a moment for large documents.</p>
</div>
)}
{error && (
<div className="pdf-error">
<p>⚠️ Failed to load PDF</p>
<p className="pdf-error-hint">The document may be unavailable or too large.</p>
<a href={pdfUrl} target="_blank" rel="noopener noreferrer" className="btn btn-secondary">
Open PDF directly ↗
</a>
</div>
)}
<iframe
key={`pdf-${pdfUrl}-page-${viewerPage}`}
src={proxyUrl}
className="pdf-frame"
title={`PDF Page ${viewerPage}`}
allow="fullscreen"
style={{ display: loading && !error ? 'none' : 'block' }}
onLoad={() => setLoading(false)}
onError={() => { setLoading(false); setError(true); }}
/>
</div>
);
}