File size: 2,256 Bytes
a5871f0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
62
63
64
65
66
67
68
69
70
71
72
73

'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>
  );
}