Update
This commit is contained in:
parent
8263a84e40
commit
ae8eb084c2
3 changed files with 47 additions and 60 deletions
|
|
@ -12,29 +12,6 @@ export default function PDFViewerPage() {
|
||||||
|
|
||||||
const document = getDocument(id as string);
|
const document = getDocument(id as string);
|
||||||
|
|
||||||
if (!document) {
|
|
||||||
return (
|
|
||||||
<div className="min-h-screen bg-background py-6 px-4 sm:py-8">
|
|
||||||
<div className="max-w-6xl mx-auto">
|
|
||||||
<div className="bg-base rounded-lg shadow-lg p-6">
|
|
||||||
<p className="text-center text-lg text-muted">Document not found. Please select a document from the home page.</p>
|
|
||||||
<div className="mt-6 text-center">
|
|
||||||
<Link
|
|
||||||
href="/"
|
|
||||||
className="inline-flex items-center px-4 py-2 bg-base text-foreground rounded-lg hover:bg-offbase transition-colors"
|
|
||||||
>
|
|
||||||
<svg className="w-5 h-5 mr-2 text-muted" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
|
||||||
</svg>
|
|
||||||
Back to Documents
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="p-2 pb-2 border-b border-offbase">
|
<div className="p-2 pb-2 border-b border-offbase">
|
||||||
|
|
@ -48,10 +25,10 @@ export default function PDFViewerPage() {
|
||||||
</svg>
|
</svg>
|
||||||
Documents
|
Documents
|
||||||
</Link>
|
</Link>
|
||||||
<h1 className="mr-2 text-xl font-semibold text-foreground">{document.name}</h1>
|
<h1 className="mr-2 text-xl font-semibold text-foreground">{document?.name}</h1>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<PDFViewer pdfFile={document.data} highlightText={'Richard Roberson'} />
|
<PDFViewer pdfFile={document?.data} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
37
src/components/PDFSkeleton.tsx
Normal file
37
src/components/PDFSkeleton.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
export function PDFSkeleton() {
|
||||||
|
const [showNotification, setShowNotification] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setShowNotification(true);
|
||||||
|
}, 3000);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col items-center w-full">
|
||||||
|
{showNotification && (
|
||||||
|
<div className="fixed top-4 left-1/2 transform -translate-x-1/2 bg-yellow-100 border border-yellow-400 text-yellow-700 px-4 py-2 rounded shadow-lg z-50">
|
||||||
|
There might be an issue with the file import. Please try again.
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="flex flex-col items-center w-full animate-pulse">
|
||||||
|
{/* Show 3 skeleton pages by default */}
|
||||||
|
{[1, 2, 3].map((index) => (
|
||||||
|
<div key={`skeleton_${index}`}>
|
||||||
|
{/* Page content skeleton */}
|
||||||
|
<div className="flex justify-center my-4">
|
||||||
|
<div className="bg-gray-200 shadow-lg">
|
||||||
|
{/* Approximate dimensions of a PDF page */}
|
||||||
|
<div className="w-[595px] h-[842px]"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -3,52 +3,30 @@
|
||||||
import { Document, Page, pdfjs } from 'react-pdf';
|
import { Document, Page, pdfjs } from 'react-pdf';
|
||||||
import 'react-pdf/dist/Page/AnnotationLayer.css';
|
import 'react-pdf/dist/Page/AnnotationLayer.css';
|
||||||
import 'react-pdf/dist/Page/TextLayer.css';
|
import 'react-pdf/dist/Page/TextLayer.css';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState } from 'react';
|
||||||
|
import { PDFSkeleton } from './PDFSkeleton';
|
||||||
|
|
||||||
// Set worker from public directory
|
// Set worker from public directory
|
||||||
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.mjs';
|
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.mjs';
|
||||||
|
|
||||||
interface PDFViewerProps {
|
interface PDFViewerProps {
|
||||||
pdfFile: string;
|
pdfFile: string | undefined;
|
||||||
highlightText?: string; // Text to highlight in the PDF
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PDFViewer({ pdfFile, highlightText }: PDFViewerProps) {
|
export function PDFViewer({ pdfFile }: PDFViewerProps) {
|
||||||
const [numPages, setNumPages] = useState<number>();
|
const [numPages, setNumPages] = useState<number>();
|
||||||
|
|
||||||
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
|
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
|
||||||
setNumPages(numPages);
|
setNumPages(numPages);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to highlight text in the PDF
|
|
||||||
const highlightPattern = (text: string, pattern: string) => {
|
|
||||||
if (!pattern) return text;
|
|
||||||
const regex = new RegExp(`(${pattern})`, 'gi');
|
|
||||||
return text.replace(regex, '<mark>$1</mark>');
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add styles for highlighted text
|
|
||||||
useEffect(() => {
|
|
||||||
const style = document.createElement('style');
|
|
||||||
style.textContent = `
|
|
||||||
.react-pdf__Page__textContent mark {
|
|
||||||
background-color: yellow;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
document.head.appendChild(style);
|
|
||||||
return () => {
|
|
||||||
document.head.removeChild(style);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
<Document
|
<Document
|
||||||
file={pdfFile}
|
file={pdfFile}
|
||||||
onLoadSuccess={onDocumentLoadSuccess}
|
onLoadSuccess={onDocumentLoadSuccess}
|
||||||
|
loading={<PDFSkeleton />}
|
||||||
|
noData={<PDFSkeleton />}
|
||||||
className="flex flex-col items-center"
|
className="flex flex-col items-center"
|
||||||
>
|
>
|
||||||
{Array.from(
|
{Array.from(
|
||||||
|
|
@ -65,13 +43,8 @@ export function PDFViewer({ pdfFile, highlightText }: PDFViewerProps) {
|
||||||
pageNumber={index + 1}
|
pageNumber={index + 1}
|
||||||
renderAnnotationLayer={true}
|
renderAnnotationLayer={true}
|
||||||
renderTextLayer={true}
|
renderTextLayer={true}
|
||||||
className="rounded-xl shadow-lg"
|
className="shadow-lg"
|
||||||
scale={1.2}
|
scale={1.2}
|
||||||
customTextRenderer={(textItem) =>
|
|
||||||
highlightText ?
|
|
||||||
highlightPattern(textItem.str, highlightText) :
|
|
||||||
textItem.str
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue