@foreverrbum/ethsign
Version:
This package will allow you to electronically sign documents within your application
209 lines (195 loc) • 12.5 kB
JavaScript
import React, { useEffect, useState } from 'react';
import Identicon from 'react-identicons';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { saveEmail, useEmail, useUserInfo } from '../../../helpers/email';
import { chains, getChain, getMainNetChain, getTestNetChain } from '../../../helpers/chains';
import { useActiveChain } from '../../../helpers/network';
import DiscordSvg from '../../../assets/bi_discord.svg';
import AkarSvg from '../../../assets/akar-icons_telegram-fill.svg';
import Email from '../../../assets/clarity_email-line.svg';
import CarretDown from '../../../assets/carret_down_black.svg';
import { useIntl, FormattedMessage } from 'react-intl';
import { connectNetwork } from '../../../helpers/wallets/wallets';
import { storeNotif } from '../../../helpers/dashboard';
export const Profile = (props) => {
const {web3, fm, torus, changeNetwork, walletName } = props;
const [email, handleEmail] = useEmail(web3);
const {ethAddress} = useUserInfo(web3);
const [network, handleNetwork] = useState(null);
const [showNetworks, handleShowNetworks] = useState(false);
const { formatMessage } = useIntl();
useEffect(() => {
let isSubscribed = true;
(async () => {
try {
handleNetwork(getChain((await web3.getNetwork()).chainId))
handleShowNetworks(false);
} catch(err) {
console.log(err);
}
})();
return () => isSubscribed = false
}, [web3]);
useEffect(() => {
let networkDropdownListener = hideNetworkDropdown.bind(this);
document.addEventListener('click', networkDropdownListener);
return () => document.removeEventListener('click', networkDropdownListener);
}, [showNetworks]);
const hideNetworkDropdown = (event) => {
if(showNetworks) {
const networkDropdown = document.getElementById('network-dropdown');
if(!networkDropdown || (event && !networkDropdown.contains(event.target))) {
handleShowNetworks(false);
}
}
}
const handleNetworkChange = async (chain) => {
changeNetwork(chain);
}
return (
<>
<div className="px-4 w-full flex flex-col items-center justify-center max-w-5xl">
<div className="flex flex-col sm:flex-row justify-around w-full mt-8">
<div className="flex p-4 w-full sm:w-1/2 shadow rounded">
<div className={`identicon flex flex-col justify-center my-auto w-11 h-11 border border-orange-500 rounded-full`}>
<div className="p-2">
<Identicon string={ethAddress} size="25" palette={['#D7EEFF', '#eef2ff', '#991A1A', '#FFDECC', '#E98234', '#D98234','#EE9F63', '#464648']} />
</div>
</div>
<div className="flex flex-col justify-center ml-2">
<span className="font-bold mb-1"><FormattedMessage id='MY_ADDRESS' /></span>
<div className="flex">
<span>{ethAddress}</span>
<CopyToClipboard text={ethAddress}>
<div className="inline mb-1 cursor-pointer">
<svg width="15" height="17" viewBox="0 0 15 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.4375 0.1875H3.49219C3.41055 0.1875 3.34375 0.254297 3.34375 0.335938V1.375C3.34375 1.45664 3.41055 1.52344 3.49219 1.52344H12.6953V14.2891C12.6953 14.3707 12.7621 14.4375 12.8438 14.4375H13.8828C13.9645 14.4375 14.0312 14.3707 14.0312 14.2891V0.78125C14.0312 0.452832 13.7659 0.1875 13.4375 0.1875ZM11.0625 2.5625H1.5625C1.23408 2.5625 0.96875 2.82783 0.96875 3.15625V13.0032C0.96875 13.1609 1.03184 13.3112 1.14316 13.4226L4.35869 16.6381C4.39951 16.6789 4.4459 16.7123 4.496 16.7401V16.7754H4.57393C4.63887 16.7995 4.70752 16.8125 4.77803 16.8125H11.0625C11.3909 16.8125 11.6562 16.5472 11.6562 16.2188V3.15625C11.6562 2.82783 11.3909 2.5625 11.0625 2.5625ZM4.49414 14.8865L2.89658 13.2871H4.49414V14.8865ZM10.3203 15.4766H5.68164V12.8418C5.68164 12.4317 5.34951 12.0996 4.93945 12.0996H2.30469V3.89844H10.3203V15.4766Z" fill="currentColor" />
</svg>
</div>
</CopyToClipboard>
</div>
</div>
</div>
<div className="flex flex-col p-4 w-full sm:w-2/5 shadow rounded mt-4 sm:mt-0">
<span className="font-bold"><FormattedMessage id='NETWORK_SELECTION' /></span>
<div className="select-none flex text-15 my-3 flex-wrap xs:flex-nowrap w-full">
<div className="relative inline-block text-left flex-grow mb-2 xs:mb-0 mr-0 xs:mr-3 ">
<div
onClick={()=>{
handleShowNetworks(!showNetworks)
}}
>
<button type="button" className={`cursor-pointer w-full bg-white flex inline-flex justify-center rounded-none border shadow-sm px-2 py-1.5 focus:outline-none`} id="menu-button" aria-expanded="true" aria-haspopup="true">
<div className="text-left">{network ? network.name: <span className="invisible"><FormattedMessage id='NO_NETWORK'/></span>}</div>
<img src={CarretDown} className="h-2 w-2 ml-auto my-auto" />
</button>
</div>
{/* <!--
Dropdown menu, show/hide based on menu state.
Entering: "transition ease-out duration-100"
From: "transform opacity-0 scale-95"
To: "transform opacity-100 scale-100"
Leaving: "transition ease-in duration-75"
From: "transform opacity-100 scale-100"
To: "transform opacity-0 scale-95"
--> */}
{showNetworks &&
<div id="network-dropdown" className={`origin-top-right absolute right-0 w-full rounded-sm shadow-lg bg-white ring-1 ring-gray-200 focus:outline-none`} role="menu" aria-orientation="vertical" aria-labelledby="menu-button" tabIndex="-1">
<div className="py-1" role="none">
<div>
{
getMainNetChain()?.map((chain, key) => {
if(walletName==='Fortmatic') {
if(!chain.fortmaticSupport) {
return null;
}
} else if(walletName === 'Torus') {
if(!chain.torusSupport) {
return null;
}
}
return (
<div key={key}
onClick={()=>{
handleNetworkChange(chain)
}}
className="hover:bg-gray-25 cursor-pointer block px-4 py-2 text-sm" role="menuitem" tabIndex="-1" >{chain.name}</div>
)
})
}
</div>
<div className="border-t mx-4"/>
<div >
{
getTestNetChain()?.map((chain, key) => {
if(walletName==='Fortmatic') {
if(!chain.fortmaticSupport) {
return null;
}
} else if(walletName === 'Torus') {
if(!chain.torusSupport) {
return null;
}
}
return (
<div key={key}
onClick={()=>{
handleNetworkChange(chain)
}}
className="hover:bg-gray-25 cursor-pointer block px-4 py-2 text-sm" role="menuitem" tabIndex="-1" >{chain.name}</div>
)
})
}
</div>
</div>
</div>
}
</div>
</div>
</div>
</div>
<div className="border-t-2 border-gray-400 w-full my-16"/>
<div className="border-l-8 border-orange-500 shadow px-4 sm:px-8 py-4 w-full rounded flex flex-col">
<span className="font-bold"><FormattedMessage id="NOTIFICATION_MANAGEMENT"/></span>
<div className="my-8 flex flex-col ">
<span><FormattedMessage id='EMAIL_ADDRESS'/>:</span>
<div className="flex justify-between">
<div className="flex flex-grow justify-center items-center border rounded focus:outline-none focus:border-orange-500 pl-1 w-full mt-2 mr-2 select-none">
<img src={Email} alt="Email" className="w-8 px-1"/>
<input
placeholder={formatMessage({id: 'ENTER_YOUR_EMAIL'})}
className="py-1 pl-2 sm:pl-4 focus:outline-none w-full"
onChange={(evt) => {
handleEmail(evt.target.value)
}}
id="email-input"
value={email}
/>
</div>
<button
className="w-24 mt-2 font-bold flex-grow-0 bg-orange-500 focus:outline-none text-gray-40 py-3 rounded-sm hover:bg-orange-600 self-end select-none"
onClick={() => {
if(!email || email.trim().length == 0) {
storeNotif(formatMessage({id: 'INVALID_EMAIL'}), formatMessage({id: "INVALID_EMAIL_MESSAGE"}), "danger");
return;
}
saveEmail(web3, email.trim(), formatMessage)
.then(({success}) => {
handleEmail(email);
})
}}
>
<FormattedMessage id="SAVE"/>
</button>
</div>
</div>
<div className="my-8 flex items-center">
<span className="text-gray-200 self-center"><FormattedMessage id="MORE_NOTIFICATION_METHODS_COMING_SOON"/></span>
<img src={DiscordSvg} alt="discord" className="w-6 mx-4 self-center select-none"/>
<img src={AkarSvg} alt="akar" className="w-6 self-center select-none"/>
</div>
</div>
</div>
</>
)
}