@foreverrbum/ethsign
Version:
This package will allow you to electronically sign documents within your application
209 lines (196 loc) • 10.4 kB
JavaScript
import React, { useState, useEffect } from 'react';
import Identicon from 'react-identicons';
import Loader from '../UI/loader';
import HistoryNotFound from '../../assets/history_not_found.svg';
import { FormattedMessage } from 'react-intl';
const HistoryDetail = (props) => {
const { doc, data, contract, provider, signers, ethAccount, ensEnabled, error, fromSave, shouldSave, savedCards, handleSavedCards } = props;
const [loaded, handleLoaded] = useState(false);
const [cards, handleCards] = useState([]);
const [empty, handleEmpty] = useState(false);
const [signerData, handleSignerData] = useState({});
useEffect(() => {
// Each card needs:
// - type
// - timestamp
// - action
// - involvedParty
(async () => {
let isSubscribed = true;
handleLoaded(false);
if(fromSave && savedCards) {
handleCards(savedCards);
handleLoaded(true);
handleEmpty(savedCards.length > 0 ? false : true);
return;
}
if(!data) {
return;
}
let newCards = [];
let tempSignerData = signerData;
for(let entry of data) {
let tempEntry = {type: entry.type, number: entry.number, involvedParty: entry.initiator, signer: entry.signer, actionString: entry.actionString, timestamp: entry.timestamp * 1000};
// if(tempEntry.type === "LogAddedNewSignerForDocument") {
// if(ethAccount.localeCompare(tempEntry.involvedParty, undefined, { sensitivity: 'accent' }) === 0) {
// tempEntry.actionString = "were " + tempEntry.actionString;
// } else {
// tempEntry.actionString = "was " + tempEntry.actionString;
// }
// }
if(ensEnabled && tempEntry.involvedParty) {
if(tempSignerData[tempEntry.involvedParty]) {
tempEntry.involvedPartyAlias = tempSignerData[tempEntry.involvedParty].alias;
tempEntry.involvedPartyAvatar = tempSignerData[tempEntry.involvedParty].avatar;
} else {
try {
let alias = await provider.lookupAddress(tempEntry.involvedParty);
if(alias) {
tempEntry.involvedPartyAlias = alias;
}
const resolver = await provider.getResolver(alias);
if(resolver) {
tempEntry.involvedPartyAvatar = await resolver.getText("avatar");
}
tempSignerData[tempEntry.involvedParty] = {alias: tempEntry.involvedPartyAlias, avatar: tempEntry.involvedPartyAvatar};
} catch(err) {
console.log(err)
}
}
}
newCards.push(tempEntry);
}
handleSignerData(tempSignerData);
if(shouldSave && handleSavedCards) {
handleSavedCards(newCards);
}
handleCards(newCards);
handleLoaded(true);
handleEmpty(newCards.length > 0 ? false : true);
return () => isSubscribed = false;
})();
}, [doc, data])
const getActionStringID = (card) => {
switch(card.actionString) {
case 0:
return 'CREATED_THE_DOCUMENT';
case 1:
return 'DOC_STORAGE_CHANGED';
case 2:
return 'ADDED_AS_A_SIGNER';
case 3:
return 'UPDATED_NUMBER_SIG_FIELDS_TO';
case 4:
return 'SIGNED_THE_DOCUMENT';
}
}
const checkAndUpdateDate = (timestamp) => {
const tempDate = ((new Date(timestamp)).toLocaleDateString());
if(tempDate !== lastDate) {
lastDate = tempDate;
return true;
}
return false;
}
let lastDate = 0;
const CardElements = cards.map((card, i) => (
checkAndUpdateDate(card.timestamp) ?
<>
<li id={`li-history-date-${i}`} className="bg-gray-70 w-24 p-0 mr-auto flex justify-center text-white rounded-2xl border-0">
{(new Date(card.timestamp)).toLocaleDateString()}
</li>
<li id={`li-history-${i}`} className="flex flex-col mb-1 border-b-0 border-r-0 border-t-0 border border-l-2 border-dashed border-gray-200 p-0 xs:ml-2 sm:ml-4 md:ml-12 lg:ml-12 ml-4">
<div className="flex flex-row my-2">
<span className="shadow-history bg-gray-200 border-2 border-gray-200 my-auto rounded-full w-4 h-4 -ml-2.5 leading-4 inline-flex origin-center items-center justify-center"></span>
<ul className="pl-5 m-0 flex-1 border-dashed border-t-2 border-gray-200 rounded-none transform translate-y-2/4"></ul>
<div className="min-h-20 bg-white shadow-md px-5 py-4 flex w-full max-w-xl relative flex-wrap xs:flex-nowrap md:flex-wrap lg:flex-nowrap">
<div className="flex flex-col-reverse md:flex-row w-full">
<div className="flex flex-row w-full">
{card.type !== "LogChangedDocumentStorage" &&
<div className="mr-3 border border-orange-500 rounded-full my-auto flex-shrink-0">
{card.involvedPartyAvatar ? <img className="rounded-full object-cover h-11 w-11" src={card.involvedPartyAvatar} />
:
<div className="p-2">
<Identicon string={card.involvedParty} size="15" palette={['#D7EEFF', '#eef2ff', '#991A1A', '#FFDECC', '#E98234', '#D98234','#EE9F63', '#464648']} />
</div>
}
</div>
}
<div className={`my-auto pr-2 text-gray-300`}><b>{card.involvedParty && (ethAccount ? (ethAccount.localeCompare(card.involvedParty, undefined, { sensitivity: 'accent' }) === 0 ? <FormattedMessage id="YOU" /> : (card.involvedPartyAlias ? card.involvedPartyAlias : card.involvedParty)) : card.involvedParty)} </b>
{ card.type === "LogAddedNewSignerForDocument" ?
(ethAccount?.localeCompare(card.involvedParty, undefined, { sensitivity: 'accent' }) === 0 ?
<FormattedMessage id='WERE'/>
:
<FormattedMessage id='WAS'/>)
: ''}
{card.type === "LogSetNumberOfSignatureFields" ? <FormattedMessage id={getActionStringID(card)} values={{number: card.number}}/>
: <FormattedMessage id={getActionStringID(card)}/>} <b>{card.type === "LogNewDocument" && doc.name + "."}</b></div>
</div>
<div className="text-xs text-gray-200 ml-auto flex-none -mt-2 md:mt-0 -mr-2 md:mr-0">{(new Date(card.timestamp)).toLocaleTimeString()}</div>
</div>
</div>
</div>
</li>
</>
:
<li id={`li-history-${i}`} className="flex mb-1 border-b-0 border-r-0 border-t-0 border border-l-2 border-dashed border-gray-200 p-0 flex-col border-b-0 xs:ml-2 sm:ml-4 md:ml-12 lg:ml-12 ml-4">
<div className="flex flex-row my-2">
<span className="shadow-history bg-gray-200 border-2 border-gray-200 my-auto rounded-full w-4 h-4 -ml-2.5 leading-4 inline-flex origin-center items-center justify-center"></span>
<ul className="pl-5 m-0 flex-1 border-dashed border-t-2 border-gray-200 rounded-none transform translate-y-2/4"></ul>
<div className="min-h-20 bg-white shadow-md px-5 py-4 flex w-full max-w-xl relative flex-wrap xs:flex-nowrap md:flex-wrap lg:flex-nowrap">
<div className="flex flex-col-reverse md:flex-row w-full">
<div className="flex flex-row w-full">
{card.involvedParty &&
<div className="mr-3 border border-orange-500 rounded-full my-auto flex-shrink-0">
{card.involvedPartyAvatar ?
<img className="rounded-full object-cover w-11 h-11" src={card.involvedPartyAvatar} />
:
<div className="p-2">
<Identicon string={card.involvedParty} size="15" palette={['#D7EEFF', '#eef2ff', '#991A1A', '#FFDECC', '#E98234', '#D98234','#EE9F63', '#464648']} />
</div>
}
</div>
}
<div className={`my-auto pr-2 text-gray-300`}><b>{card.involvedParty && (ethAccount ? (ethAccount.localeCompare(card.involvedParty, undefined, { sensitivity: 'accent' }) === 0 ? <FormattedMessage id="YOU" /> : (card.involvedPartyAlias ? card.involvedPartyAlias : card.involvedParty)) : card.involvedParty)} </b>
{ card.type === "LogAddedNewSignerForDocument" ?
(ethAccount?.localeCompare(card.involvedParty, undefined, { sensitivity: 'accent' }) === 0 ?
<FormattedMessage id='WERE'/>
:
<FormattedMessage id='WAS'/>
)
: ''}
{card.type === "LogSetNumberOfSignatureFields" ? <FormattedMessage id={getActionStringID(card)} values={{signer: card.signer, number: card.number}}/>
: <FormattedMessage id={getActionStringID(card)}/>} <b>{card.type === "LogNewDocument" && doc.name + "."}</b></div>
</div>
<div className="text-xs text-gray-200 ml-auto flex-none -mt-2 md:mt-0 -mr-2 md:mr-0">{(new Date(card.timestamp)).toLocaleTimeString()}</div>
</div>
</div>
</div>
</li>
))
return (
<div className="history-detail-list w-full">
<ul className="mt-4 px-4 list-none">
{!error && CardElements}
{!loaded && !error &&
<div className="flex justify-center">
<Loader />
</div>
}
{error &&
<div className="select-none w-full my-auto flex flex-col justify-center">
<img className="pointer-events-none mx-auto" src={HistoryNotFound} />
<div className="text-15 text-center text-gray-500"><><FormattedMessage id='THE_CURRENT_NETWORK_DOES_NOT_SUPPORT_DOCUMENT_HISTORY'/><br /><FormattedMessage id='PLEASE_SWITCH_TO_A_DIFFERENT_NETWORK_AND_TRY_AGAIN'/></></div>
</div>
}
{!error && loaded && empty &&
<div className="select-none w-full my-auto flex flex-col justify-center">
<img className="pointer-events-none mx-auto" src={HistoryNotFound} />
<div className="text-15 text-center text-gray-500"><><FormattedMessage id='THE_DOCUMENT_HISTORY_COULD_NOT_BE_LOADED'/><br /><FormattedMessage id='PLEASE_CHECK_YOUR_INTERNET_CONNECTION_AND_TRY_AGAIN'/></></div>
</div>
}
</ul>
</div>
);
}
export default HistoryDetail;