UNPKG

@foreverrbum/ethsign

Version:

This package will allow you to electronically sign documents within your application

191 lines (178 loc) 10.9 kB
import React, {useEffect, useState, useRef} from 'react'; import { aggregateHandleDocumentUpload, handleDocumentReupload, setDocStorageForDocument, aggregateNewBasicDocumentAndSetStorage, autoSelfSign, getEncryptedStringFromFile } from '../../helpers/newdocument'; import ProgressBarIndicator from '../Dashboard/ProgressBarIndicator'; import {storeNotif} from '../../helpers/dashboard'; import { ReactTypeformEmbed } from 'react-typeform-embed'; import { withRouter } from 'react-router'; import { useIntl, FormattedMessage } from 'react-intl'; import { getxfdfString } from '../../helpers/pdf'; const Sending = (props) => { const {data, contract, web3, webviewer, close, handleData, createProgress, handleCreateProgress, storageHash, handleStorageHash, documentKey, selfSignOnSubmit, indicatorProgress, handleIndicatorProgress, shouldResubmit, filter, idx, annotList, storageProvider, handleStorageProvider, updateStoredData} = props; const [submitButton, handleSubmitButton] = useState('Submitting') const typeform = useRef(null); const { formatMessage } = useIntl(); const [signers, handleSigners] = useState(null) const [signerFieldCount, handleSignerFieldCount] = useState(null) const [sigFields, handleSigFields] = useState(null) const [annotations, handleAnnotations] = useState(null) const [initialized, handleInitialized] = useState(false); /** * progress bar: * max: 3 + 2*(# signers) + (1 if self-signing) * * progress (non-aggregated): * 1 - newBasicDocument created * 2 - uploaded to storage platforms * 3 - added fileHash to document * 4 - added signers to document * 5 - added signature fields to document * 6 - (optional) completed self-signing * * progress (aggregated): * 1 - aggregateHandleDocumentUpload completed * 2 - aggregateNewBasicDocumentAndSetStorage completed * 3 - aggregateAddSignersAndNumOfSigFieldsForDocument completed * 4 - (optional) completed self-signing * 5 - Feedback survey completed * 6 - Notification completed for successful creation */ useEffect (()=>{ (async () => { if(webviewer && annotList.length > 0 && !initialized) { const {sigFieldsXFDF, annotationsXFDF, addresses, count} = await getxfdfString(webviewer, annotList); handleSigFields(sigFieldsXFDF) handleAnnotations(annotationsXFDF) handleSigners(addresses) handleSignerFieldCount(count) handleInitialized(true); updateStoredData(); } })(); }, [webviewer, annotList]); useEffect (()=>{ (async () => { if (signerFieldCount){ if(shouldResubmit) { let progress = createProgress; if(progress == 0) { progress += await handleDocumentReupload(storageProvider, handleSubmitButton, data.password, documentKey, data.file, storageHash, handleStorageHash, createProgress, handleCreateProgress, indicatorProgress, handleIndicatorProgress, continueResubmitCallback, close, formatMessage); } if(progress > 0) { continueResubmitCallback(progress, indicatorProgress, storageHash, storageProvider) } } else { // TODO: upload a blank file if file is null let progress = createProgress; // New way using aggregated signers: if(progress == 0) { // Upload document // File encryption var signaturesFile = new Blob([sigFields], {type: 'text/plain'}); var annotationsFile = new Blob([annotations], {type: 'text/plain'}); handleSubmitButton(formatMessage({id: 'ENCRYPTING_FILE'})) const encryptedFile = await getEncryptedStringFromFile(data.file, data.password) const encryptedSigFields = await getEncryptedStringFromFile(signaturesFile, data.password) const encryptedAnnotations = await getEncryptedStringFromFile(annotationsFile, data.password) progress += await aggregateHandleDocumentUpload(web3, contract, storageProvider, handleStorageProvider, handleSubmitButton, documentKey, encryptedFile, handleStorageHash, encryptedSigFields, encryptedAnnotations, handleCreateProgress, indicatorProgress, handleIndicatorProgress, continueCallback, close, formatMessage); } // This will only trigger if createProgress is > 0. // Otherwise, progress won't be updated since it gets updated from reader.onloadend which is async else if(progress > 0) { continueCallback(progress, indicatorProgress, storageHash, storageProvider); } // await handleAddSigners(contract, web3, documentKey, data.signers, handleSubmitButton); } } })(); }, [signerFieldCount]); const continueResubmitCallback = async (progress, indicatorProgress, docuStorageHash, storageProvider) => { if(progress == 1) { // We just need to update the storage at this stage setDocStorageForDocument(contract, web3, documentKey, storageProvider, docuStorageHash, indicatorProgress, handleIndicatorProgress, handleCreateProgress, handleSubmitButton, continueResubmitCallback, close, formatMessage); } if(progress == 2) { handleSubmitButton(formatMessage({id: 'CONTRACT_SUCCESFULLY_CREATED'})); storeNotif(formatMessage({id: 'CONTRACT_SUCCESFULLY_CREATED'}), '', 'info') if(handleData){ handleData(documentKey, filter ? filter : 'original', idx); } } } const continueCallback = async (progress, indicatorProgress, docuStorageHash, storageProvider) => { if(progress == 1) { // New basic document and set storage aggregateNewBasicDocumentAndSetStorage(web3, contract, documentKey, data.filename.name+data.filename.ext, data.expiryBlock, storageProvider, docuStorageHash, signers, signerFieldCount, handleSubmitButton, formatMessage, async (tx)=>{ const networkId = (await web3.getNetwork()).chainId; await tx.wait(networkId == 1287 ? 2 : 1).then((receipt) => { handleCreateProgress(2); indicatorProgress += 1; handleIndicatorProgress(indicatorProgress); continueCallback(2, indicatorProgress); }); }, ()=>{ close(); }, formatMessage({id: "SUBMIT"}) ); } else if(progress == 2 && selfSignOnSubmit) { // Add signers and number of signer fields autoSelfSign(contract, web3, documentKey, createProgress, handleCreateProgress, indicatorProgress, handleIndicatorProgress, handleSubmitButton, continueCallback, close, formatMessage); } else if(progress == 3 || (progress == 2 && !selfSignOnSubmit)) { // Self-sign the document if the checkbox is checked handleSubmitButton(formatMessage({id: 'CONTRACT_SUCCESFULLY_CREATED'})); storeNotif(formatMessage({id: 'CONTRACT_SUCCESFULLY_CREATED'}), '', 'info') if(handleData){ handleData(documentKey); } handleCreateProgress(3); } } return( <div className="max-w-7xl mx-auto bg-white w-11/12 sm:w-7/12 border-t-4 border-orange-500"> <div className="py-5 px-5 flex flex-col justify-center w-full"> <div className="pt-3 pb-1 mx-auto text-center"> {((shouldResubmit && createProgress == 2) || createProgress == 3) ? formatMessage({id: 'HELP_US_IMPROVE_AND_RATE_YOUR_EXPERIENCE'}) : submitButton} </div> {/* For the old way of adding signers one at a time: max={3 + (data.signers.length * 2) + (selfSignOnSubmit ? 1 : 0)} */} {!((shouldResubmit && createProgress == 2) || createProgress == 3) && <ProgressBarIndicator value={indicatorProgress} max={shouldResubmit ? 2 : 2 + (selfSignOnSubmit ? 1 : 0)} />} <div className="-z-10 relative"> <ReactTypeformEmbed url="https://dygdc65xyp5.typeform.com/to/lC3Sns44" // style={"display:inline-block;text-decoration:none;background-color:#E98234;color:white;cursor:pointer;font-family:Helvetica,Arial,sans-serif;font-size:20px;line-height:50px;text-align:center;margin:0;height:50px;padding:0px 33px;border-radius:25px;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:bold;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;"} popup={true} ref={typeform} autoOpen={false} autoClose={0} onSubmit={()=>{ storeNotif("", formatMessage({id: 'WE_APPRECITE_AND_VALUE_YOU_FEEDBACK'}), "info") if(handleData){ props.history.push({ pathname: '/contracts' }) } }} /> </div> {((shouldResubmit && createProgress == 2) || createProgress == 3) && <div className="flex flex-wrap text-white justify-center my-5"> <div className="cursor-pointer bg-gray-300 px-3 py-2 hover:bg-gray-600 rounded-md mx-3" onClick={()=>{ if(handleData){ props.history.push({ pathname: '/contracts' }) } }}> <FormattedMessage id='NOT_NOW'/> </div> <div className=" cursor-pointer bg-orange-500 px-3 py-2 rounded-md hover:bg-orange-600 mx-3" onClick={()=>{ typeform.current.typeform.open() }}> <FormattedMessage id='GIVE_FEEDBACK'/> </div> </div> } </div> </div> ); } export default withRouter(Sending);