This commit is contained in:
Richard Roberson 2025-01-18 13:04:38 -07:00
parent 8263a84e40
commit ae8eb084c2
3 changed files with 47 additions and 60 deletions

View file

@ -12,29 +12,6 @@ export default function PDFViewerPage() {
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 (
<>
<div className="p-2 pb-2 border-b border-offbase">
@ -48,10 +25,10 @@ export default function PDFViewerPage() {
</svg>
Documents
</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>
<PDFViewer pdfFile={document.data} highlightText={'Richard Roberson'} />
<PDFViewer pdfFile={document?.data} />
</>
);
);
}

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

View file

@ -3,52 +3,30 @@
import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/Page/AnnotationLayer.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
pdfjs.GlobalWorkerOptions.workerSrc = '/pdf.worker.mjs';
interface PDFViewerProps {
pdfFile: string;
highlightText?: string; // Text to highlight in the PDF
pdfFile: string | undefined;
}
export function PDFViewer({ pdfFile, highlightText }: PDFViewerProps) {
export function PDFViewer({ pdfFile }: PDFViewerProps) {
const [numPages, setNumPages] = useState<number>();
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
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 (
<div className="flex flex-col items-center">
<Document
file={pdfFile}
onLoadSuccess={onDocumentLoadSuccess}
loading={<PDFSkeleton />}
noData={<PDFSkeleton />}
className="flex flex-col items-center"
>
{Array.from(
@ -65,13 +43,8 @@ export function PDFViewer({ pdfFile, highlightText }: PDFViewerProps) {
pageNumber={index + 1}
renderAnnotationLayer={true}
renderTextLayer={true}
className="rounded-xl shadow-lg"
className="shadow-lg"
scale={1.2}
customTextRenderer={(textItem) =>
highlightText ?
highlightPattern(textItem.str, highlightText) :
textItem.str
}
/>
</div>
</div>