67 lines
2.0 KiB
TypeScript
67 lines
2.0 KiB
TypeScript
'use client'
|
|
|
|
import { useEffect, 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'
|
|
|
|
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
|
'pdfjs-dist/build/pdf.worker.min.mjs',
|
|
import.meta.url,
|
|
).toString()
|
|
|
|
interface Props {
|
|
url: string
|
|
}
|
|
|
|
function proxyUrl(url: string): string {
|
|
return `/api/pdf?url=${encodeURIComponent(url)}`
|
|
}
|
|
|
|
export default function PdfViewer({ url }: Props) {
|
|
const containerRef = useRef<HTMLDivElement>(null)
|
|
const [containerWidth, setContainerWidth] = useState(0)
|
|
const [numPages, setNumPages] = useState(0)
|
|
|
|
useEffect(() => {
|
|
const el = containerRef.current
|
|
if (!el) return
|
|
const ro = new ResizeObserver(([entry]) => setContainerWidth(entry.contentRect.width))
|
|
ro.observe(el)
|
|
return () => ro.disconnect()
|
|
}, [])
|
|
|
|
return (
|
|
<div ref={containerRef} style={{ height: '100%', overflowY: 'auto', background: '#e5e7eb' }}>
|
|
<Document
|
|
file={proxyUrl(url)}
|
|
onLoadSuccess={({ numPages }) => setNumPages(numPages)}
|
|
loading={
|
|
<div className="h-full flex items-center justify-center">
|
|
<div
|
|
className="w-8 h-8 rounded-full border-2 border-t-transparent animate-spin"
|
|
style={{ borderColor: 'var(--color-primary)', borderTopColor: 'transparent' }}
|
|
/>
|
|
</div>
|
|
}
|
|
error={
|
|
<div style={{ padding: 32, textAlign: 'center', color: 'var(--color-text-muted)' }}>
|
|
Impossible de charger le PDF
|
|
</div>
|
|
}
|
|
>
|
|
{Array.from({ length: numPages }, (_, i) => (
|
|
<div key={i + 1} style={{ marginBottom: 8, display: 'flex', justifyContent: 'center' }}>
|
|
<Page
|
|
pageNumber={i + 1}
|
|
width={containerWidth || undefined}
|
|
renderTextLayer={false}
|
|
renderAnnotationLayer={false}
|
|
/>
|
|
</div>
|
|
))}
|
|
</Document>
|
|
</div>
|
|
)
|
|
}
|