UNPKG

@foreverrbum/ethsign

Version:

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

318 lines (306 loc) 14.5 kB
import React, {useState, useEffect, useRef, Fragment} from 'react'; import ProgressBar from './Create/ProgressBar'; import Create from './Create/Create'; import ReviewSend from './Create/ReviewSend'; import Invite from './Create/Invite'; import Prepare from './Create/Prepare'; import Sending from './Create/Sending'; import { storeNotif, getNewDocumentKey } from '../helpers/dashboard'; import { getContract } from '../helpers/client'; import { validateUploadFile } from '../helpers/newdocument'; import { useIntl } from 'react-intl'; import { isSignersWithFields } from '../helpers/pdf'; import { checkAndUpdateAnnotList } from '../helpers/pdf'; import Alert from './Alert'; import LoadingScreen from './LoadingScreen'; import { withRouter } from 'react-router-dom'; const NewContract = (props) => { const {location, fm, torus, ethAccount, provider, handleActivePage, contract, appLogout, ensEnabled, handleData, changeNetwork, ethAlias, ethAvatar, clearStoredSessionData, storedData, handleStoredData, handleOpen } = props; const [shouldShowRestoreDialog, handleShouldShowRestoreDialog] = useState(false); const [showRestoreDialog, handleShowRestoreDialog] = useState(false); const [progress, handleProgress] = useState(0); const [pageCount, handlePageCount] = useState(null); const [signers, handleSigners] = useState([ { address: ethAccount, alias: ethAlias, avatar: ethAvatar } ]) const [loading, handleLoading] = useState(true); const [tempCredentials, handleTempCredentials] = useState(null); const [recovering, handleRecovering] = useState(false); const [webviewer, handleWebviewer] = useState(null) const [file, handleFile] = useState(null); const [filename, handleFilename] = useState(null); const [withPassword, handleWithPassword] = useState(true); const [password, handlePassword] = useState(""); const [withExpiry, handleWithExpiry] = useState(false); const [expiryBlock, handleExpiryBlock] = useState(0); const [sending, handleSending] = useState(false); const [documentKey, handleDocumentKey] = useState(null); const [storageProvider, handleStorageProvider] = useState('FL'); const [originalFilename, handleOriginalFilename] = useState(''); // newdocument.js states const [addedSigners, handleAddedSigners] = useState([]); const [createProgress, handleCreateProgress] = useState(0); const [indicatorProgress, handleIndicatorProgress] = useState(0); const [storageHash, handleStorageHash] = useState(null); const [annotations, handleAnnotations] = useState(null); const [annotList, handleAnnotList] = useState([]) const { formatMessage } = useIntl(); const viewer = useRef(null); const validateProgress = progress => { if(file) { if(file.name.length <= 4) { storeNotif(formatMessage({id: 'NO_FILENAME'}), formatMessage({id: 'PROVIDE_FILENAME'}),'danger') } else { if(signers.length > 0 || progress <= 1) { if (progress == 3){ const addresses = signers.map((signer)=>{ return signer.address }) const test = isSignersWithFields(addresses, [...annotList]); if(!test){ handleProgress(2) storeNotif(formatMessage({id: 'NO_SIGNATURE_FIELDS'}), formatMessage({id: 'PLEASE_ADD_SIGNER_TO_CONTINUE'}), 'danger') return; }else{ handleProgress(progress) } }else{ handleProgress(progress) } } else { storeNotif(formatMessage({id: 'NO_SIGNERS'}), formatMessage({id: 'PLEASE_INCLUDE_AT_LEAST_ONE_SINGER'}),'danger') return; } } updateStoredData(null, null, progress); } else if(progress) { storeNotif(formatMessage({id: 'NO_FILE_UPLOADED'}), formatMessage({id: 'A_PDF_NEEDS_TO_BE_UPLOAD'}),'danger') } } const recoverStoredSessionData = async () => { handleCreateProgress(storedData.createProgress); handleOriginalFilename(storedData.originalFilename); handleFilename(storedData.filename); handleSigners(storedData.signers); handleIndicatorProgress(storedData.indicatorProgress); handleStorageHash(storedData.storageHash); handleStorageProvider(storedData.storageProvider); handleAnnotations(storedData.annotations); handleDocumentKey(storedData.documentKey); handlePassword(storedData.password); handleExpiryBlock(storedData.expiryBlock); handleWithPassword(storedData.withPassword); handleWithExpiry(storedData.withExpiry); const annot_list = await checkAndUpdateAnnotList(file, storedData.filename, handleWebviewer, viewer, ethAlias, ethAccount, storedData.annotations, signers); handleAnnotList(annot_list) handleProgress(storedData.progress); handleRecovering(false) } const updateStoredData = (signers_arr, annots_xfdf, prog) => { if(!shouldShowRestoreDialog && handleStoredData){ handleStoredData({ createProgress: createProgress, documentKey: documentKey, progress: prog? prog:progress, originalFilename: originalFilename, filename: filename, signers: signers_arr? signers_arr:signers, indicatorProgress: indicatorProgress, storageHash: storageHash, storageProvider: storageProvider, annotations: annots_xfdf? annots_xfdf:annotations, documentKey: documentKey, password: password, expiryBlock: expiryBlock, withPassword: withPassword, withExpiry: withExpiry }) } } useEffect (()=>{ let isSubscribed = true; (async () => { if(handleActivePage){ handleActivePage('create'); } let key = ''; if(!contract){ const credentials = await getContract({ provider: provider }) console.log(credentials) handleTempCredentials(credentials); key = await getNewDocumentKey(credentials.contract); }else{ key = await getNewDocumentKey(contract); } handleDocumentKey(key); if(storedData?.documentKey && storedData?.originalFilename) { handleShouldShowRestoreDialog(true); } handleLoading(false) })(); return () => isSubscribed = false; },[]); useEffect (()=>{ let isSubscribed = true; const temp = signers; const index = _.findIndex(temp, function(o) { return o.address == ethAccount; }); if (index>-1){ temp[index].alias = ethAlias; temp[index].avatar = ethAvatar; } handleSigners(temp) return () => isSubscribed = false; },[ethAlias, ethAvatar]); useEffect (()=>{ let isSubscribed = true; if(file!=null){ handleAnnotations(null) if(shouldShowRestoreDialog && storedData.originalFilename !== '' && storedData.originalFilename === file.name) { handleShowRestoreDialog(true); handleShouldShowRestoreDialog(false); } } return () => isSubscribed = false; },[file]); return( <> {sending && <div className="select-none fixed top-0 bottom-0 w-full h-full z-40 bg-black-1000 bg-opacity-25 flex flex-col justify-center"> <Sending data = {{ file: file, filename: filename, signers: signers.map((signer)=>{ return signer.address }), password: password, expiryBlock: expiryBlock }} contract={contract? contract : tempCredentials.contract} web3={contract? provider : tempCredentials.provider} webviewer={webviewer} handleData={handleData} addedSigners={addedSigners} handleAddedSigners={handleAddedSigners} createProgress={createProgress} handleCreateProgress={handleCreateProgress} indicatorProgress={indicatorProgress} handleIndicatorProgress={handleIndicatorProgress} storageHash={storageHash} handleStorageHash={handleStorageHash} annotations={annotations} documentKey={documentKey} close={()=>{handleSending(false)}} annotList={[...annotList]} storageProvider={storageProvider} handleStorageProvider={handleStorageProvider} updateStoredData={updateStoredData} /> </div> } <ProgressBar fm={fm} torus={torus} ethAlias={ethAlias} ethAvatar={ethAvatar} changeNetwork={(chain)=>changeNetwork(chain)} provider={provider} progress={progress} handleProgress={validateProgress} appLogout={appLogout} ethAccount={ethAccount} handleOpen={handleOpen}/> {loading == true? // TODO: ADD A LOADING SCREEN <LoadingScreen location={location}/> : <Fragment> {{ 0: <Create file={file} handleProgress={validateProgress} pageCount={pageCount} handlePageCount={handlePageCount} validateUploadFile={ (file) => { validateUploadFile(file, handlePageCount, handleFile, handleFilename, handleOriginalFilename, formatMessage); } } filename={filename} handleFilename={handleFilename} updateStoredData={updateStoredData} />, 1: <Invite provider={provider} ethAccount={ethAccount} handleProgress={validateProgress} handleSigners={handleSigners} signers={signers} ensEnabled={ensEnabled} addedSigners={addedSigners} updateStoredData={updateStoredData} />, 2: <Prepare file={file} filename={filename} handleWebviewer={handleWebviewer} ethAccount={ethAccount} ethAlias={ethAlias} handleProgress={validateProgress} signers={signers} annotations={annotations} handleAnnotations={handleAnnotations} handleAnnotList={handleAnnotList} updateStoredData={updateStoredData} />, 3: <ReviewSend web3={provider} file={file} filename={filename} handleFilename={handleFilename} handleProgress={validateProgress} signers={signers} handleSigners={handleSigners} pageCount={pageCount} handleSending={handleSending} expiryBlock={expiryBlock} handleExpiryBlock={handleExpiryBlock} password={password} handlePassword={handlePassword} ethAccount={ethAccount} provider={provider} addedSigners={addedSigners} ensEnabled={ensEnabled} withPassword={withPassword} handleWithPassword={handleWithPassword} withExpiry={withExpiry} handleWithExpiry={handleWithExpiry} updateStoredData={updateStoredData} ethAlias={ethAlias} handleProgress={validateProgress} signers={signers} annotations={annotations} handleAnnotations={handleAnnotations} handleAnnotList={handleAnnotList} />, }[progress]} </Fragment> } {(showRestoreDialog || recovering == true) && <Alert message={formatMessage({id: 'DETECTED_DATA_RESTORE'})} closeOnOutsideClick={!recovering} closeButtonText={formatMessage({id: 'NO'})} replaceButtonsWithLoader={recovering} closeCallback={async () => { if (recovering !== true){ clearStoredSessionData(); handleShowRestoreDialog(false); } }} okButtonText={formatMessage({id: "YES"})} okCallback={() => { if(recovering !== true){ handleRecovering(true) recoverStoredSessionData(); handleShowRestoreDialog(false); } }} /> } <div ref={viewer} className="absolute invisible"></div> </> ); } export default withRouter(NewContract);