in source/app/components/FileUpload/FileUpload.js [41:202]
function FileUpload({ dispatch }) {
const [canUseCamera, setCanUseCamera] = useState({})
const [cameraCapturing, setCameraCapturing] = useState(false)
const [fileStatus, setFileStatus] = useState({})
const [uploadStatus, setUploadStatus] = useState('')
const [files, setFiles] = useState({})
const {modal, setModal} = isROMode==="true"? useContext(ModalContext): useState('')
const fileNames = Object.keys(files)
// Aggregate upload statuses
const isUploadPending = uploadStatus === 'pending'
const isUploadSuccessful = uploadStatus === 'success'
const isUploadFailed = uploadStatus === 'error'
const isReadyToUpload = !uploadStatus
useEffect(() => {
const md = window.navigator && navigator.mediaDevices
if (!md || !md.enumerateDevices) {
setCanUseCamera(false)
} else {
md.enumerateDevices().then(devices => {
setCanUseCamera(devices.some(device => device.kind === 'videoinput'))
})
}
}, [])
// Configure dropzone
const onDrop = useCallback(acceptedFiles => {
if(isROMode === 'true'){
setModal(true)
}
else{
const fileMap = {}
setUploadStatus('')
acceptedFiles.forEach(file => {
fileMap[file.name] = file
})
setFiles(files => ({ ...files, ...fileMap }))
}
}, [])
const { getRootProps, getInputProps, isDragActive } = useDropzone({
onDrop,
disabled: !isReadyToUpload,
})
/**
* Handle clicks on the select documents CTA when the mode is Demonstration Mode
*
*/
const handleSelectDocumentsClickDemoOnly = useCallback(() => {setModal(true) },[])
// Dynamic class names
const fileUploadClassNames = classNames(css.fileUpload, {
[css.dragActive]: isDragActive,
})
/**
* Click handler for upload button
*/
const handleUploadClick = useCallback(() => {
// Set aggregate status
setUploadStatus('pending')
// Upload files
const uploads = uploadFiles({
fileNames,
files,
onProgress({ fileName, progress }) {
setFileStatus(fileStatus => ({
...fileStatus,
...{
[fileName]: {
progress: `${Math.min(Math.round((progress.loaded / progress.total) * 100), 99)}%`,
},
},
}))
},
onSuccess({ result, fileName }) {
return dispatch(submitDocument({ key: `public/${result.key}` })).then(() => {
setFileStatus(fileStatus => ({
...fileStatus,
...{ [fileName]: { success: true } },
}))
})
},
onError({ fileName }) {
setFileStatus(fileStatus => ({
...fileStatus,
...{ [fileName]: { error: true } },
}))
},
})
// Set aggregate status based on result of upload promises
Promise.all(uploads)
.then(() => {
dispatch(clearSearchQuery())
setUploadStatus('success')
})
.catch(error => {
setUploadStatus('error')})
}, [dispatch, fileNames, files])
/**
* Delete a file
*
* @param {String} fileName The name of the file to delete
*/
function deleteFile(fileName) {
setFiles(({ ...files }) => delete files[fileName] && files)
}
const startCamera = useCallback(() => {
setCameraCapturing(true)
}, [])
const cameraCaptured = useCallback(blob => {
setCameraCapturing(false)
const datestring = format(new Date(), 'YYYYMMDDHHmmss')
const filename = `cameracapture-${datestring}.jpg`
setFiles(files => ({ ...files, [filename]: blob }))
}, [])
if (isROMode==="true"){
return (
<div>
<div
{...getRootProps({
className: fileUploadClassNames,
onClick: handleSelectDocumentsClickDemoOnly,
tabIndex: -1,
})}
>
<input {...getInputProps({
disabled: true
})} />
<img src="/static/images/icon_file-upload.svg" alt="File Upload Icon" />
{isDragActive && <p className={css.instructions}>Drop the documents here...</p>}
{!isDragActive && isReadyToUpload && (
<>
<p className={css.instructions}>
Drag and drop files or <em tabIndex="0">Choose documents</em>
</p>
{isReadyToUpload && (
<p className={css.limits}>
Accepts JPG/PNG (max 5MB) and PDF (max 150 MB, max 200 pages)
</p>
)}
{canUseCamera && (
<p className={css.instructions}>
or <Button onClick={() => setModal(true)}>use your camera</Button>
</p>
)}
</>
)}
</div>
</div>
)
}