import { AccessTime, CalendarMonth, ExpandMore, Gesture, PictureAsPdf, Badge, Work } from '@mui/icons-material' import { Box, Typography, Accordion, AccordionDetails, AccordionSummary, CircularProgress } from '@mui/material' import styles from './style.module.scss' import { useEffect, useState } from 'react' import * as PDFJS from "pdfjs-dist"; PDFJS.GlobalWorkerOptions.workerSrc = 'node_modules/pdfjs-dist/build/pdf.worker.mjs'; interface Props { selectedFiles: any[] } interface PdfFile { file: File, pages: string[] expanded?: boolean } interface DrawTool { identifier: 'signature' | 'jobtitle' | 'fullname' | 'date' | 'datetime' label: string icon: JSX.Element, defaultValue?: string selected?: boolean } export const DrawPDFFields = (props: Props) => { const { selectedFiles } = props const [pdfFiles, setPdfFiles] = useState([]) const [parsingPdf, setParsingPdf] = useState(false) const [showDrawToolBox, setShowDrawToolBox] = useState(false) const [selectedTool, setSelectedTool] = useState() const [toolbox] = useState([ { identifier: 'signature', icon: , label: 'Signature' }, { identifier: 'fullname', icon: , label: 'Full Name' }, { identifier: 'jobtitle', icon: , label: 'Job Title' }, { identifier: 'date', icon: , label: 'Date' }, { identifier: 'datetime', icon: , label: 'Datetime' }, ]) useEffect(() => { if (selectedFiles) { setParsingPdf(true) parsePdfPages().finally(() => { setParsingPdf(false) }) } }, [selectedFiles]) const parsePdfPages = async () => { const pdfFiles: PdfFile[] = [] for (const file of selectedFiles) { if (file.type.toLowerCase().includes('pdf')) { const data = await readPdf(file) const pages = await pdfToImages(data) pdfFiles.push({ file: file, pages: pages }) } } setPdfFiles(pdfFiles) } const getPdfPages = (pdfFile: PdfFile) => { return ( {pdfFile.pages.map((page: string) => { return (
) })}
) } /** * Converts pdf to the images * @param data pdf file bytes */ const pdfToImages = async (data: any): Promise => { const images: string[] = []; const pdf = await PDFJS.getDocument(data).promise; const canvas = document.createElement("canvas"); for (let i = 0; i < pdf.numPages; i++) { const page = await pdf.getPage(i + 1); const viewport = page.getViewport({ scale: 3 }); const context = canvas.getContext("2d"); canvas.height = viewport.height; canvas.width = viewport.width; await page.render({ canvasContext: context!, viewport: viewport }).promise; images.push(canvas.toDataURL()); } return Promise.resolve(images) } const readPdf = (file: File) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e: any) => { const data = e.target.result resolve(data) }; reader.onerror = (err) => { console.error('err', err) reject(err) }; reader.readAsDataURL(file); }) } const hasExpandedPdf = () => { return !!pdfFiles.filter(pdfFile => !!pdfFile.expanded).length } const handleAccordionExpandChange = (event: React.SyntheticEvent, expanded: boolean, pdfFile: PdfFile) => { pdfFile.expanded = expanded setPdfFiles(pdfFiles) setShowDrawToolBox(hasExpandedPdf()) } const handleToolSelect = (drawTool: DrawTool) => { // If clicked on the same tool, unselect if (drawTool.identifier === selectedTool?.identifier) { setSelectedTool(null) return } setSelectedTool(drawTool) } if (parsingPdf) { return ( ) } if (!pdfFiles.length) { return '' } return ( Draw fields on the PDFs: {pdfFiles.map((pdfFile) => { return ( {handleAccordionExpandChange(event, expanded, pdfFile)}}> } aria-controls="panel1-content" id="panel1-header" > {pdfFile.file.name} {getPdfPages(pdfFile)} ) })} {showDrawToolBox && ( {toolbox.map((drawTool: DrawTool) => { return ( {handleToolSelect(drawTool)}} className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`}> { drawTool.icon } { drawTool.label } ) })} )} ) }