Spaces:
Sleeping
Sleeping
File size: 2,195 Bytes
da957b0 9cc2491 b584890 da957b0 9cc2491 b584890 da957b0 e7f7858 0018d88 da957b0 b584890 9cc2491 b584890 9cc2491 b584890 e7f7858 b584890 9cc2491 b584890 da957b0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | "use client";
import { useState, useEffect } from 'react';
export default function PdfViewer({ pdfUrl, pageNumber }) {
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 the PDF through our own API to bypass CORS restrictions.
// Then use the browser's built-in PDF viewer via <object> tag.
const proxyUrl = `/api/pdf-proxy?url=${encodeURIComponent(pdfUrl)}#page=${viewerPage}&zoom=75`;
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>
);
}
|