@foreverrbum/ethsign
Version:
This package will allow you to electronically sign documents within your application
191 lines (178 loc) • 10.9 kB
JavaScript
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);