diff --git a/acrobat/blocks/acom-widget/acom-widget.css b/acrobat/blocks/acom-widget/acom-widget.css index ea1ec9d9..fbed218b 100644 --- a/acrobat/blocks/acom-widget/acom-widget.css +++ b/acrobat/blocks/acom-widget/acom-widget.css @@ -137,6 +137,17 @@ background: #0054b6; } +.acom-error { + background: #d8120b; + width: fit-content; + border-radius: 8px; + padding: 11px 27px; + color: white; + white-space: nowrap; + font-weight: 700; + display: flex; +} + .acom-heading { color: #2c2c2c; text-align: left; diff --git a/acrobat/blocks/acom-widget/acom-widget.js b/acrobat/blocks/acom-widget/acom-widget.js index 3d8724d8..839360ee 100644 --- a/acrobat/blocks/acom-widget/acom-widget.js +++ b/acrobat/blocks/acom-widget/acom-widget.js @@ -8,6 +8,9 @@ import { getAcrobatWebLink, } from './pdfAssetManager.js'; +import LIMITS from './limits.js'; + + import { setLibs } from '../../scripts/utils.js'; const miloLibs = setLibs('/libs'); @@ -17,100 +20,134 @@ const { createTag } = await import(`${miloLibs}/utils/utils.js`); const PAGE_URL = new URL(window.location.href); const redirect = PAGE_URL.searchParams.get('redirect'); -const uploadToAdobe = async (file) => { +const uploadToAdobe = async (file, verb, err) => { const filename = file.name; - const extension = filename.split('.').pop().toLowerCase(); let xhr; - const contentTypes = { - png: 'image/png', - jpg: 'image/jpeg', - jpeg: 'image/jpeg', - svg: 'image/svg+xml', - pdf: 'application/pdf', - }; - - const contentType = contentTypes[extension]; - if (!contentType) { - // eslint-disable-next-line no-alert - alert('This file is invalid'); + // Check file type + if (LIMITS[verb].acceptedFiles.indexOf(file.type) < 0) { + err.classList.add('acom-error'); + err.classList.remove('hide'); + err.textContent = 'USE mph / not accepted'; + + setTimeout(() => { + err.classList.remove('acom-error'); + err.classList.add('hide'); + }, 3000); return; } - try { - const { accessToken, discoveryResources } = await initializePdfAssetManager(); - const uploadEndpoint = validateSSRF(discoveryResources.assets.upload.uri); - const formData = prepareFormData(file, filename); - - xhr = new XMLHttpRequest(); - xhr.open('POST', uploadEndpoint, true); - xhr.setRequestHeader('Authorization', `Bearer ${accessToken}`); - - xhr.onreadystatechange = async () => { - if (xhr.readyState === 4 && xhr.status === 201) { - const uploadResult = JSON.parse(xhr.responseText); - const assetUri = uploadResult.uri; - - if (contentType !== 'application/pdf') { - const createPdfEndpoint = validateSSRF(discoveryResources.assets.createpdf.uri); - const createPdfPayload = { - asset_uri: assetUri, - name: filename, - persistence: 'transient', - }; - try { - const createPdfResult = await createPdf( - createPdfEndpoint, - createPdfPayload, - accessToken, - ); - const jobUri = createPdfResult.job_uri; - await checkJobStatus(jobUri, accessToken, discoveryResources); - } catch (error) { - // eslint-disable-next-line no-alert - alert('Failed to create PDF'); - throw new Error('Error creating PDF:', error); - } - } - - try { - const downloadUri = await getDownloadUri(assetUri, accessToken, discoveryResources); - const blobViewerUrl = validateSSRF(getAcrobatWebLink(filename, assetUri, downloadUri)); - if (redirect !== 'off') { - window.location.href = blobViewerUrl; - } else { - // eslint-disable-next-line no-console - console.log('Blob Viewer URL:', `View PDF`); - } - } catch (error) { - throw new Error('Error getting download URI:', error); - } - } - }; - xhr.send(formData); - } catch (error) { - // eslint-disable-next-line no-alert - alert('An error occurred during the upload process. Please try again.'); - throw new Error('Error uploading file:', error); + // Check file size + if (file.size > LIMITS[verb].maxFileSize + || file.size < 1) { + err.classList.add('acom-error'); + err.classList.remove('hide'); + err.textContent = `${file.size < 1 ? 'FILE IS EMPTY' : 'FILE IS TOO BIG'}`; + + setTimeout(() => { + err.classList.remove('acom-error'); + err.classList.add('hide'); + }, 3000); + return; + } + + // try { + // const { accessToken, discoveryResources } = await initializePdfAssetManager(); + // const uploadEndpoint = validateSSRF(discoveryResources.assets.upload.uri); + // const formData = prepareFormData(file, filename); + + // xhr = new XMLHttpRequest(); + // xhr.open('POST', uploadEndpoint, true); + // xhr.setRequestHeader('Authorization', `Bearer ${accessToken}`); + + // xhr.onreadystatechange = async () => { + // if (xhr.readyState === 4 && xhr.status === 201) { + // const uploadResult = JSON.parse(xhr.responseText); + // const assetUri = uploadResult.uri; + + // if (contentType !== 'application/pdf') { + // const createPdfEndpoint = validateSSRF(discoveryResources.assets.createpdf.uri); + // const createPdfPayload = { + // asset_uri: assetUri, + // name: filename, + // persistence: 'transient', + // }; + // try { + // const createPdfResult = await createPdf( + // createPdfEndpoint, + // createPdfPayload, + // accessToken, + // ); + // const jobUri = createPdfResult.job_uri; + // await checkJobStatus(jobUri, accessToken, discoveryResources); + // } catch (error) { + // // eslint-disable-next-line no-alert + // alert('Failed to create PDF'); + // throw new Error('Error creating PDF:', error); + // } + // } + + // try { + // const downloadUri = await getDownloadUri(assetUri, accessToken, discoveryResources); + // const blobViewerUrl = validateSSRF(getAcrobatWebLink(filename, assetUri, downloadUri)); + // if (redirect !== 'off') { + // window.location.href = blobViewerUrl; + // } else { + // // eslint-disable-next-line no-console + // console.log('Blob Viewer URL:', `View PDF`); + // } + // } catch (error) { + // throw new Error('Error getting download URI:', error); + // } + // } + // }; + + // xhr.send(formData); + // } catch (error) { + // // eslint-disable-next-line no-alert + // alert('An error occurred during the upload process. Please try again.'); + // throw new Error('Error uploading file:', error); + // } +}; + +const dropFiles = (ev, verb, errorState) => { + ev.preventDefault(); + console.log(ev); + + if (ev.dataTransfer.items) { + [...ev.dataTransfer.items].forEach((item) => { + // Add check for multiple files. + if (item.kind === 'file') { + const file = item.getAsFile(); + uploadToAdobe(file, verb, errorState); + } + }); + } else { + [...ev.dataTransfer.files].forEach((file, i) => { + // copy functionality from dataTransfer.items + }); } }; export default async function init(element) { const children = element.querySelectorAll(':scope > div'); + const VERB = element.classList[1]; + const widgetHeading = createTag('h1', { class: 'acom-heading' }, children[0].textContent); + children.forEach((child) => { child.remove(); }); - const widget = createTag('div', { class: 'acom-wrapper' }); + const widget = createTag('div', { id: 'drop-zone', class: 'acom-wrapper' }); const widgetContainer = createTag('div', { class: 'acom-container' }); const widgetRow = createTag('div', { class: 'acom-row' }); const widgetLeft = createTag('div', { class: 'acom-col' }); const widgetRight = createTag('div', { class: 'acom-col' }); const widgetIcon = createTag('div', { class: 'acom-icon' }); - const widgetHeading = createTag('h1', { class: 'acom-heading' }, 'Fill and sign a PDF'); const widgetCopy = createTag('p', { class: 'acom-copy' }, 'Drag and drop a PDF to use the Acrobat PDF form filler.'); - const widgetButton = createTag('lavel', { for: 'file-upload', class: 'acom-cta' }, 'Select a file'); + const widgetButton = createTag('label', { for: 'file-upload', class: 'acom-cta' }, 'Select a file'); const button = createTag('input', { type: 'file', id: 'file-upload', class: 'hide' }); + const errorState = createTag('div', { class: 'hide' }); const legal = createTag('p', { class: 'acom-legal' }, 'Your file will be securely handled by Adobe servers and deleted unless you sign in to save it. By using this service, you agree to the Adobe Terms of Use and Privacy Policy.'); const iconSecurity = createTag('div', { class: 'security-icon' }); @@ -120,14 +157,23 @@ export default async function init(element) { widget.append(widgetContainer); widgetContainer.append(widgetRow); widgetRow.append(widgetLeft, widgetRight); - widgetLeft.append(widgetIcon, widgetHeading, widgetCopy, widgetButton); + widgetLeft.append(widgetIcon, widgetHeading, widgetCopy, errorState, widgetButton, button); element.append(widget, footer); button.addEventListener('change', (e) => { const file = e.target.files[0]; if (file) { - uploadToAdobe(file); + uploadToAdobe(file, VERB, errorState); } }); + + widget.addEventListener('dragover', (e) => { + e.preventDefault(); + // make a function that does the CSS for drag state + }); + + widget.addEventListener('drop', (e) => { + dropFiles(e, VERB, errorState); + }); } diff --git a/acrobat/blocks/acom-widget/limits.js b/acrobat/blocks/acom-widget/limits.js new file mode 100644 index 00000000..d828239a --- /dev/null +++ b/acrobat/blocks/acom-widget/limits.js @@ -0,0 +1,24 @@ +const LIMITS = { + fillsign: { + maxFileSize: 100000000, // 1 MB + acceptedFiles: ['application/pdf'], + maxNumFiles: 1, + }, + 'delete-pages': { + maxFileSize: 100000000, // 1 MB + acceptedFiles: ['application/pdf'], + maxNumFiles: 1, + }, + 'number-pages': { + maxFileSize: 100000000, // 1 MB + acceptedFiles: ['application/pdf'], + maxNumFiles: 1, + }, + 'compress-pdf': { + maxFileSize: 100000000, + acceptedFiles: ['application/pdf'], + maxNumFiles: 1, + }, +}; + +export default LIMITS;