Spaces:
Build error
Build error
| 'use client'; | |
| import * as React from 'react'; | |
| import { Document, Page, pdfjs } from 'react-pdf'; | |
| import 'react-pdf/dist/esm/Page/AnnotationLayer.css'; | |
| import 'react-pdf/dist/esm/Page/TextLayer.css'; | |
| import { Loader2, AlertTriangle } from 'lucide-react'; | |
| import { Skeleton } from './ui/skeleton'; | |
| import { cn } from '@/lib/utils'; | |
| pdfjs.GlobalWorkerOptions.workerSrc = `/pdf.worker.min.js`; | |
| interface PdfThumbnailProps { | |
| fileUrl: string; | |
| className?: string; | |
| } | |
| export function PdfThumbnail({ fileUrl, className }: PdfThumbnailProps) { | |
| const [numPages, setNumPages] = React.useState<number | null>(null); | |
| const [error, setError] = React.useState<string | null>(null); | |
| const containerRef = React.useRef<HTMLDivElement>(null); | |
| const [width, setWidth] = React.useState(200); | |
| React.useEffect(() => { | |
| if (containerRef.current) { | |
| setWidth(containerRef.current.getBoundingClientRect().width); | |
| } | |
| }, []); | |
| function onDocumentLoadSuccess({ numPages }: { numPages: number }) { | |
| setNumPages(numPages); | |
| setError(null); | |
| } | |
| function onDocumentLoadError(error: Error) { | |
| console.error('Failed to load PDF for thumbnail:', error); | |
| setError('Failed to load preview.'); | |
| } | |
| const loadingSkeleton = <Skeleton className="w-full aspect-[3/4]" />; | |
| if (error) { | |
| return ( | |
| <div className={cn("w-full aspect-[3/4] flex flex-col items-center justify-center bg-muted text-destructive text-sm p-4", className)}> | |
| <AlertTriangle className="h-8 w-8 mb-2" /> | |
| <p className="text-center">{error}</p> | |
| </div> | |
| ); | |
| } | |
| return ( | |
| <div ref={containerRef} className={cn("w-full aspect-[3/4] overflow-hidden flex items-center justify-center bg-muted rounded-t-md", className)}> | |
| <Document | |
| file={fileUrl} | |
| onLoadSuccess={onDocumentLoadSuccess} | |
| onLoadError={onDocumentLoadError} | |
| loading={loadingSkeleton} | |
| className="flex items-center justify-center" | |
| > | |
| <Page | |
| pageNumber={1} | |
| width={width} | |
| renderTextLayer={false} | |
| renderAnnotationLayer={false} | |
| loading={loadingSkeleton} | |
| /> | |
| </Document> | |
| </div> | |
| ); | |
| } | |