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