react-router, better navigation

This commit is contained in:
Aleksandr Pantiukhov 2018-10-09 17:03:20 +02:00 committed by Barry G
parent 2273f58576
commit a09eee1287
8 changed files with 303 additions and 218 deletions

View File

@ -3,15 +3,35 @@ import Typography from '@material-ui/core/Typography';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { YOUR_CONTACT_CODE } from './constants'; import { YOUR_CONTACT_CODE } from './constants';
import { checkAndDispatchStatusContactCode } from '../../actions/accounts'; import { checkAndDispatchStatusContactCode } from '../../actions/accounts';
import styled from "styled-components";
const WrappedDisplayBox = ({ displayType, pubKey, getStatusContactCode }) => ( const DisplayLabel = styled.div`
font-size: 14px;
color: #939BA1;
margin: 0 1em;
`;
const DisplayBox = styled.div`
border: 1px solid #EEF2F5;
border-radius: 8px;
margin: 7px 12px 14px 12px;
display: flex;
flex-direction: column;
justifyContent: space-around;
min-height: 4em;
word-wrap: break-word;
`;
const WrappedDisplayBox = ({displayType, pubKey, getStatusContactCode}) => (
<div onClick={() => getStatusContactCode(displayType, pubKey)}> <div onClick={() => getStatusContactCode(displayType, pubKey)}>
<div style={{ fontSize: '14px', color: '#939BA1', margin: '0 1em' }}>{displayType}</div> <DisplayLabel>
<div style={{ border: '1px solid #EEF2F5', borderRadius: '8px', margin: '7px 12px 14px 12px', display: 'flex', flexDirection: 'column', justifyContent: 'space-around', minHeight: '4em' }}> {displayType}
<div style={{ margin: '16px', wordBreak: 'break-word' }}> </DisplayLabel>
<DisplayBox>
<div style={{margin: '16px'}}>
<Typography type='body1'>{pubKey}</Typography> <Typography type='body1'>{pubKey}</Typography>
</div> </div>
</div> </DisplayBox>
</div> </div>
); );

View File

@ -1 +1,2 @@
export const YOUR_CONTACT_CODE = 'Your contact code'; export const YOUR_CONTACT_CODE = 'Your contact code';
export const YOUR_WALLET_ADDRESS = 'Your wallet address';

View File

@ -34,6 +34,7 @@ import { nullAddress, getResolver } from './utils/domain';
import { YOUR_CONTACT_CODE } from './constants'; import { YOUR_CONTACT_CODE } from './constants';
import DisplayBox from './DisplayBox'; import DisplayBox from './DisplayBox';
import styled from "styled-components"; import styled from "styled-components";
import { Route } from "react-router-dom";
const normalizer = new IDNANormalizer(); const normalizer = new IDNANormalizer();
const invalidSuffix = '0000000000000000000000000000000000000000' const invalidSuffix = '0000000000000000000000000000000000000000'
@ -240,6 +241,7 @@ class Register extends PureComponent {
const formattedDomain = formatName(domainName); const formattedDomain = formatName(domainName);
const formattedDomainArray = formattedDomain.split('.'); const formattedDomainArray = formattedDomain.split('.');
const isOwner = defaultAccount === ownerAddress; const isOwner = defaultAccount === ownerAddress;
return ( return (
<div style={style}> <div style={style}>
{!registered && !submitted ? {!registered && !submitted ?
@ -267,7 +269,7 @@ const mapDispatchToProps = dispatch => ({
const mapStateToProps = state => ({ const mapStateToProps = state => ({
defaultAccount: getDefaultAccount(state) defaultAccount: getDefaultAccount(state)
}) });
const ConnectedRegister = connect(mapStateToProps, mapDispatchToProps)(Register); const ConnectedRegister = connect(mapStateToProps, mapDispatchToProps)(Register);
@ -283,94 +285,51 @@ const DisplayAddress = connect(mapStateToProps)((props) => (
</Hidden> </Hidden>
} }
</Fragment> </Fragment>
)) ));
const LookupForm = ({ handleSubmit, values, handleChange, isWarningDisplayed }) => ( class LookupForm extends React.Component {
<Fragment> render() {
<form onSubmit={handleSubmit} onBlur={handleSubmit} > const { handleSubmit, values, handleChange, isWarningDisplayed } = this.props;
<Hidden mdDown>
<Field label="Enter Domain or Status Name" style={{ margin: 50 }}>
<TextInput
value={values.domainName}
name="domainName"
onChange={handleChange}
wide
required />
</Field>
</Hidden>
<Hidden mdUp>
<MobileSearch
search
name="domainName"
placeholder='Search for available name'
value={values.domainName}
onChange={handleChange}
required
wide />
{isWarningDisplayed && <Warning>Names are made with<br/>letters and numbers only</Warning>}
</Hidden>
<Hidden mdDown>
<Button mode="strong" type="submit" style={{ marginLeft: '3%', maxWidth: '95%' }} wide>
Lookup Address
</Button>
</Hidden>
</form>
</Fragment>
)
const InnerForm = ({ return (
values, <Fragment>
errors, <form onSubmit={handleSubmit} onBlur={handleSubmit}>
touched, <Hidden mdDown>
handleChange, <Field label="Enter Domain or Status Name" style={{margin: 50}}>
handleBlur, <TextInput
handleSubmit, value={values.domainName}
isSubmitting, name="domainName"
status, onChange={handleChange}
setStatus, wide
defaultAccount required/>
}) => ( </Field>
<div> </Hidden>
<Hidden mdDown> <Hidden mdUp>
<span style={{ display: 'flex', justifyContent: 'space-evenly', margin: '50 0 10 0' }}> <MobileSearch
<StatusLogo /> search
<img style={{maxWidth: '150px', alignSelf: 'center'}} src={EnsLogo} alt="Ens Logo"/> name="domainName"
</span> placeholder='Search for available name'
</Hidden> value={values.domainName}
{!status || !status.address ? onChange={handleChange}
<LookupForm {...{handleSubmit, values, handleChange}} isWarningDisplayed={status && status.isInvalidDomain}/> required
: wide/>
validAddress(status.address) || defaultAccount === status.ownerAddress ? {isWarningDisplayed && <Warning>Names are made with<br/>letters and numbers only</Warning>}
<DisplayAddress </Hidden>
{...{handleSubmit, values, handleChange}} <Hidden mdDown>
domainName={status.domainName} <Button mode="strong" type="submit" style={{marginLeft: '3%', maxWidth: '95%'}} wide>
address={status.address} Lookup Address
statusAccount={status.statusAccount} </Button>
expirationTime={status.expirationTime} </Hidden>
creationTime={status.creationTime} ownerAddress={status.ownerAddress} </form>
registryOwnsDomain={status.registryOwnsDomain} </Fragment>
setStatus={setStatus}/> : );
<div> }
<LookupForm {...{handleSubmit, values, handleChange}} isWarningDisplayed={false}/> }
<ConnectedRegister
style={{position: 'relative'}}
setStatus={setStatus}
registryOwnsDomain={status.registryOwnsDomain}
ownerAddress={status.ownerAddress}
domainName={status.domainName}/>
</div>
}
</div>
);
const isValidDomainName = val => /^([a-z0-9]+)$/.test(val.toLowerCase()); const isValidDomainName = val => /^([a-z0-9]+)$/.test(val.toLowerCase());
const NameLookup = withFormik({ class SearchResultsPage extends React.Component {
mapPropsToValues: props => ({ domainName: '' }), async loadDomainInformation({setStatus, domainName}) {
async handleSubmit(values, { status, setSubmitting, setStatus }) {
const { domainName } = values;
if (isValidDomainName(domainName)) { if (isValidDomainName(domainName)) {
const { methods: { owner, resolver } } = ENSRegistry; const { methods: { owner, resolver } } = ENSRegistry;
const lookupHash = hash(formatName(domainName)); const lookupHash = hash(formatName(domainName));
@ -403,6 +362,109 @@ const NameLookup = withFormik({
setStatus({isInvalidDomain: true }); setStatus({isInvalidDomain: true });
} }
} }
})(InnerForm);
export default connect(mapStateToProps)(NameLookup); componentDidMount() {
const { setValues } = this.props;
const domainName = this.props.match.params.domainName;
setValues({domainName: domainName});
this.loadDomainInformation({
setStatus: this.props.setStatus,
domainName: domainName
});
}
componentWillReceiveProps(nextProps) {
const { setValues, match } = this.props;
const oldDomainName = match.params.domainName;
const newDomainName = nextProps.match.params.domainName;
if (oldDomainName !== newDomainName) {
setValues({domainName: newDomainName});
this.loadDomainInformation({
setStatus: this.props.setStatus,
domainName: newDomainName
});
}
}
render() {
const {
values,
handleChange,
handleSubmit,
status,
setStatus,
defaultAccount
} = this.props;
return (
<div>
{!status || !status.address ?
<LookupForm {...this.props} isWarningDisplayed={status && status.isInvalidDomain}/>
:
validAddress(status.address) || defaultAccount === status.ownerAddress ?
<DisplayAddress
{...{handleSubmit, values, handleChange}}
domainName={status.domainName}
address={status.address}
statusAccount={status.statusAccount}
expirationTime={status.expirationTime}
creationTime={status.creationTime} ownerAddress={status.ownerAddress}
registryOwnsDomain={status.registryOwnsDomain}
setStatus={setStatus}/> :
<div>
<LookupForm {...this.props} isWarningDisplayed={false}/>
<ConnectedRegister
style={{position: 'relative'}}
setStatus={setStatus}
registryOwnsDomain={status.registryOwnsDomain}
ownerAddress={status.ownerAddress}
domainName={status.domainName}/>
</div>
}
</div>
);
}
}
class NameLookupContainer extends React.Component {
render() {
const {match, status} = this.props;
return (
<div>
<Hidden mdDown>
<span style={{ display: 'flex', justifyContent: 'space-evenly', margin: '50 0 10 0' }}>
<StatusLogo />
<img style={{maxWidth: '150px', alignSelf: 'center'}} src={EnsLogo} alt="Ens Logo"/>
</span>
</Hidden>
{match &&
<div>
<Route
exact
path={match.url}
render={() => <LookupForm {...this.props} isWarningDisplayed={status && status.isInvalidDomain}/>}/>
<Route
path={`${match.url}/:domainName`}
render={({match}) => <SearchResultsPage {...this.props} match={match}/>}/>
</div>
}
</div>
)
}
}
const NameLookupContainerWrapped = withFormik({
mapPropsToValues: () => ({ domainName: '' }),
async handleSubmit(values, { props }) {
const { domainName } = values;
props.history.push(`${props.match.url}/${domainName}`);
}
})(NameLookupContainer);
export default connect(mapStateToProps)(NameLookupContainerWrapped);

View File

@ -2,27 +2,44 @@ import web3 from "Embark/web3"
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar'; import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
import TestToken from 'Embark/contracts/TestToken'; import TestToken from 'Embark/contracts/TestToken';
import React from 'react'; import React from 'react';
import { connect } from 'react-redux'; import {connect} from 'react-redux';
import Hidden from '@material-ui/core/Hidden'; import Hidden from '@material-ui/core/Hidden';
import {withStyles} from '@material-ui/core/styles';
import CircularProgress from '@material-ui/core/CircularProgress'; import CircularProgress from '@material-ui/core/CircularProgress';
import { Button, MobileButton } from '../../ui/components'; import {Button, MobileButton} from '../../ui/components';
import { withFormik } from 'formik'; import {withFormik} from 'formik';
import { hash } from 'eth-ens-namehash'; import {hash} from 'eth-ens-namehash';
import { zeroAddress, zeroBytes32, formatPrice } from './utils'; import {zeroAddress, zeroBytes32, formatPrice} from './utils';
import { getStatusContactCode, getSNTAllowance, getCurrentAccount } from '../../reducers/accounts'; import {getStatusContactCode, getSNTAllowance, getCurrentAccount} from '../../reducers/accounts';
import FieldGroup from '../standard/FieldGroup'; import FieldGroup from '../standard/FieldGroup';
import LinearProgress from '@material-ui/core/LinearProgress'; import LinearProgress from '@material-ui/core/LinearProgress';
import Terms from './terms'; import Terms from './terms';
import { generateXY } from '../../utils/ecdsa'; import {generateXY} from '../../utils/ecdsa';
import { getResolver } from './utils/domain'; import {getResolver} from './utils/domain';
import DisplayBox from './DisplayBox'; import DisplayBox from './DisplayBox';
import { YOUR_CONTACT_CODE } from './constants'; import { YOUR_CONTACT_CODE, YOUR_WALLET_ADDRESS } from './constants';
import classNames from "classnames";
const { soliditySha3, fromWei } = web3.utils; const { soliditySha3, fromWei } = web3.utils;
const styles = theme => ({
button: {
margin: theme.spacing.unit,
backgroundColor: 'rgba(67, 96, 223, 0.1)',
},
buttonText: {
color: '#4360df',
margin: '0 20px',
fontWeight: 400,
textTransform: 'uppercase'
}
});
const formRef = React.createRef(); const formRef = React.createRef();
const displayTerms = status => status === 'terms'; const displayTerms = status => status === 'terms';
const InnerForm = ({ const InnerForm = ({
classes,
values, values,
errors, errors,
handleChange, handleChange,
@ -64,13 +81,14 @@ const InnerForm = ({
button={ button={
<Button <Button
mode="strong" mode="strong"
style={{ marginTop: '5px' }} style={{marginTop: '5px'}}
onClick={() => { onClick={() => {
UsernameRegistrar.methods.getPrice() UsernameRegistrar.methods.getPrice()
.call() .call()
.then((res) => { setFieldValue('price', fromWei(res)); }); .then((res) => {
}} setFieldValue('price', fromWei(res));
> });
}}>
Get Price Get Price
</Button> </Button>
} }
@ -110,41 +128,18 @@ const InnerForm = ({
<Hidden mdUp> <Hidden mdUp>
<DisplayBox displayType="Your wallet address" pubKey={values.address} /> <DisplayBox displayType={YOUR_WALLET_ADDRESS} pubKey={values.address} />
<DisplayBox displayType={YOUR_CONTACT_CODE} pubKey={values.statusAddress} /> <DisplayBox displayType={YOUR_CONTACT_CODE} pubKey={values.statusAddress} />
{/*<div style={{ fontSize: '14px', color: '#939BA1', margin: '0 1em' }}>Your contact code</div>*/} <div style={{ position: 'relative', left: 0, right: 0, bottom: 0, textAlign: 'center' }}>
{/*<div style={{ border: '1px solid #EEF2F5', borderRadius: '8px', margin: '0.5 1em 1em', display: 'flex', flexDirection: 'column', justifyContent: 'space-around', minHeight: '4em' }}>*/} {!isSubmitting ?
{/*<div style={{ margin: '3%', wordBreak: 'break-word' }}>*/} <Button onClick={() => {setStatus('terms')}} className={classNames(classes.button)}>
{/*<Typography type='body1' onClick={() => setFieldValue('statusAddress', '')} style={{ textAlign: 'center', padding: '30px 0', color: 'blue', cursor: 'pointer'}}>*/} <div className={classNames(classes.buttonText)}>
{/*Grant Access*/} {`${editAccount ? 'Save' : 'Register'} with transaction`}
{/*</Typography>*/} </div>
{/*</div>*/} </Button>
{/*</div>*/} :
<CircularProgress />}
{/*<Field label="Your Wallet Address">*/}
{/*<MobileSearch*/}
{/*name="address"*/}
{/*style={{ marginTop: '10px' }}*/}
{/*placeholder="Your wallet address"*/}
{/*value={values.address}*/}
{/*onChange={handleChange}*/}
{/*onClick={() => setFieldValue('address', '')}*/}
{/*required*/}
{/*wide />*/}
{/*</Field>*/}
{/*<Field label="Your contact code">*/}
{/*<MobileSearch*/}
{/*name="statusAddress"*/}
{/*style={{ marginTop: '10px' }}*/}
{/*placeholder="Status Messenger Address"*/}
{/*value={values.statusAddress}*/}
{/*onChange={handleChange}*/}
{/*onClick={() => setFieldValue('statusAddress', '')}*/}
{/*wide />*/}
{/*</Field>*/}
<div style={{ position: 'relative', left: 0, right: 0, bottom: 0 }}>
{!isSubmitting ? <MobileButton onClick={() => { setStatus('terms') }} text={`${editAccount ? 'Save' : 'Register'} with transaction`} style={{ width: '100%' }} /> : <CircularProgress style={{ marginLeft: '45%' }} />}
<Terms open={displayTerms(status)} onSubmit={() => { setStatus(null); formRef.current.dispatchEvent(new Event('submit')) }} form={formRef} /> <Terms open={displayTerms(status)} onSubmit={() => { setStatus(null); formRef.current.dispatchEvent(new Event('submit')) }} form={formRef} />
</div> </div>
</Hidden> </Hidden>
@ -152,6 +147,8 @@ const InnerForm = ({
</form> </form>
); );
const StyledInnerForm = withStyles(styles)(InnerForm);
const RegisterSubDomain = withFormik({ const RegisterSubDomain = withFormik({
mapPropsToValues: props => ({ subDomain: '', domainName: '', price: '', statusAddress: props.statusContactCode || '', address: web3.eth.defaultAccount || '' }), mapPropsToValues: props => ({ subDomain: '', domainName: '', price: '', statusAddress: props.statusContactCode || '', address: web3.eth.defaultAccount || '' }),
validate(values, props) { validate(values, props) {
@ -219,7 +216,7 @@ const RegisterSubDomain = withFormik({
}); });
} }
} }
})(InnerForm); })(StyledInnerForm);
const mapStateToProps = state => ({ const mapStateToProps = state => ({
statusContactCode: getStatusContactCode(state), statusContactCode: getStatusContactCode(state),

View File

@ -1,54 +1,65 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { withStyles } from '@material-ui/core/styles'; import {withStyles} from '@material-ui/core/styles';
import Button from '@material-ui/core/Button'; import {Button} from '../../ui/components';
import StatusCards from '../../ui/icons/svg/intro_name.svg'; import StatusCards from '../../ui/icons/svg/intro_name.svg';
import {BrowserRouter as Router, Route, Link} from "react-router-dom";
import './welcome.css'; import './welcome.css';
const styles = theme => ({ const styles = theme => ({
button: { button: {
margin: theme.spacing.unit, margin: theme.spacing.unit,
borderRadius: '4px',
backgroundColor: 'rgba(67, 96, 223, 0.1)', backgroundColor: 'rgba(67, 96, 223, 0.1)',
},
buttonText: {
color: '#4360df',
margin: '0 20px',
fontWeight: 400,
textTransform: 'uppercase'
} }
}); });
const buttonText = { color: '#4360df', margin: '0 20px', fontWeight: 300 };
const WelcomeContent = () => ( const WelcomeContent = () => (
<div> <div>
<div className="ens-welcome__guide"><span>How it works</span></div> <div className="ens-welcome__guide"><span>How it works</span></div>
<ol className="ens-welcome__list"> <ol className="ens-welcome__list">
<li className="item"> <li className="item">
<div className="title">Simplify your ETH address</div> <div className="title">Simplify your ETH address</div>
<div className="text">Your complex wallet address (0x...) becomes an easy to read, remember & share URL: <span className="ens-welcome__highlight">myname.stateofus.eth</span></div> <div className="text">Your complex wallet address (0x...) becomes an easy to read, remember & share URL: <span
</li> className="ens-welcome__highlight">myname.stateofus.eth</span></div>
<li className="item"> </li>
<div className="title">100 SNT to register</div> <li className="item">
<div className="text">Register once to keep the name forever. After 1 year, you can release the name and get your SNT back.</div> <div className="title">100 SNT to register</div>
</li> <div className="text">Register once to keep the name forever. After 1 year, you can release the name and get
<li className="item"> your SNT back.
<div className="title">Connect & get paid</div> </div>
<div className="text">Share your name to chat on Status or receive ETH and tokens.</div> </li>
</li> <li className="item">
</ol> <div className="title">Connect & get paid</div>
<div className="ens-welcome__info">Already have a Status subdomain? <a href="">Manage it</a></div> <div className="text">Share your name to chat on Status or receive ETH and tokens.</div>
<div className="text-light"><small>Powered by Ethereum Name Services</small></div> </li>
</ol>
<div className="ens-welcome__info">Already have a Status subdomain? <a href="">Manage it</a></div>
<div className="text-light">
<small>Powered by Ethereum Name Services</small>
</div> </div>
</div>
); );
const Welcome = ({ classes, toggleSearch }) => ( const Welcome = ({ classes }) => (
<div className="ens-welcome"> <div className="ens-welcome">
<img className="ens-welcome__img" src={StatusCards} /> <img className="ens-welcome__img" src={StatusCards} />
<h2 className="ens-welcome__title"> <h2 className="ens-welcome__title">
ENS names transform those crazy-long addresses into unique usernames ENS names transform those crazy-long addresses into unique usernames
</h2> </h2>
<Button size="large" className={classNames(classes.button)} onClick={toggleSearch}> <Link to="/search">
<div style={buttonText}>Let's Go</div> <Button className={classNames(classes.button)}>
</Button> <div className={classNames(classes.buttonText)}>Let's Go</div>
<WelcomeContent /> </Button>
</Link>
<WelcomeContent/>
</div> </div>
); );

View File

@ -1,43 +1,54 @@
import React, { Fragment } from 'react'; import React from 'react';
import ReactDOM from 'react-dom';
import 'typeface-roboto' import 'typeface-roboto'
import CssBaseline from '@material-ui/core/CssBaseline';
import { Tabs, Tab } from 'react-bootstrap';
import Toggle from 'react-toggle'; import Toggle from 'react-toggle';
import EmbarkJS from 'Embark/EmbarkJS'; import EmbarkJS from 'Embark/EmbarkJS';
import TopNavbar from './components/topnavbar';
import TestTokenUI from './components/testtoken';
import ERC20TokenUI from './components/erc20token';
import TestToken from 'Embark/contracts/TestToken'; import TestToken from 'Embark/contracts/TestToken';
import ENSSubManagement from './components/ensSubManagement';
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar'; import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
import NameLookup from './components/ens/nameLookup'; import NameLookup from './components/ens/nameLookup';
import AdminMode from './components/AdminMode'; import AdminMode from './components/AdminMode';
import TokenPermissions from './components/standard/TokenPermissionConnect'; import TokenPermissions from './components/standard/TokenPermissionConnect';
import web3 from "Embark/web3"; import web3 from "Embark/web3";
import Paper from '@material-ui/core/Paper';
import Typography from '@material-ui/core/Typography';
import Welcome from './components/ens/welcome'; import Welcome from './components/ens/welcome';
import Fade from '@material-ui/core/Fade';
import Hidden from '@material-ui/core/Hidden'; import Hidden from '@material-ui/core/Hidden';
import Web3Render from './components/standard/Web3Render'; import Web3Render from './components/standard/Web3Render';
import StatusOptimized from './components/standard/StatusOptimized'; import StatusOptimized from './components/standard/StatusOptimized';
import { HashRouter, Route } from "react-router-dom";
import './dapp.css'; import './dapp.css';
const { getNetworkType } = web3.eth.net; const { getNetworkType } = web3.eth.net;
const symbols = { const symbols = {
'ropsten': 'STT', 'ropsten': 'STT',
'private': 'SNT', 'private': 'SNT',
'main': 'SNT' 'main': 'SNT'
} }
const Web3RenderContent = ({ network, history, match }) => (
<Web3Render ready={network === 'ropsten'} network={'Ropsten'}>
<div>
<NameLookup {...{history, match}}/>
<Hidden mdDown>
<div style={{textAlign: 'center', margin: '0px 40px'}}>
<TokenPermissions
symbol={symbols[network] || 'SNT'}
spender={UsernameRegistrar._address}
methods={TestToken.methods}/>
<hr/>
<Toggle onChange={() => {
this.setState({admin: !admin})
}}/>
<br/>
<span>Admin Mode</span>
</div>
</Hidden>
</div>
</Web3Render>
);
class App extends React.Component { class App extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props)
} }
state = { admin: false, searching: false }; state = { admin: false };
componentDidMount(){ componentDidMount(){
EmbarkJS.onReady((err) => { EmbarkJS.onReady((err) => {
@ -46,43 +57,24 @@ class App extends React.Component {
} }
render() { render() {
const { admin, network, searching } = this.state; const { admin, network } = this.state;
const toggleSearch = () => { this.setState({ searching: !searching }) };
const isRopsten = network === 'ropsten';
const isMainnet = network === 'main';
return ( return (
<div> <HashRouter>
<Hidden mdDown> <div>
<StatusOptimized /> <Hidden mdDown>
</Hidden> <StatusOptimized/>
<div style={{ display: admin ? 'block' : 'none' }} > </Hidden>
<AdminMode style={{ display: admin ? 'block' : 'none' }}/> <div style={{display: admin ? 'block' : 'none'}}>
</div> <AdminMode style={{display: admin ? 'block' : 'none'}}/>
{!searching && <Fade in={!searching}>
<div>
<Welcome toggleSearch={toggleSearch} />
</div> </div>
</Fade>}
{searching && <Fade in={searching}> <Route exact path="/" component={Welcome}/>
<Web3Render ready={isRopsten} network={'Ropsten'}> <Route path="/search" render={({history, match}) => (
<div> <Web3RenderContent {...{history, match, network}} />
<NameLookup /> )}/>
<Hidden mdDown> </div>
<div style={{ textAlign: 'center', margin: '0px 40px' }}> </HashRouter>
<TokenPermissions
symbol={symbols[network] || 'SNT'}
spender={UsernameRegistrar._address}
methods={TestToken.methods} />
<hr/>
<Toggle onChange={() => { this.setState({ admin: !admin })}} />
<br/>
<span>Admin Mode</span>
</div>
</Hidden>
</div>
</Web3Render>
</Fade>}
</div>
); );
} }
} }

View File

@ -177,7 +177,7 @@ const StyledButton = styled.button.attrs({ type: 'button' })`
color: ${textSecondary}; color: ${textSecondary};
background: ${contentBackground}; background: ${contentBackground};
border: 0; border: 0;
border-radius: 3px; border-radius: 4px;
outline: 0; outline: 0;
cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')}; cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')};
&, &,

View File

@ -35,6 +35,8 @@
"react-copy-to-clipboard": "^5.0.1", "react-copy-to-clipboard": "^5.0.1",
"react-dom": "^16.4.2", "react-dom": "^16.4.2",
"react-redux": "^5.0.7", "react-redux": "^5.0.7",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"react-toggle": "^4.0.2", "react-toggle": "^4.0.2",
"redux": "^4.0.0", "redux": "^4.0.0",
"redux-action-creator": "^2.3.0", "redux-action-creator": "^2.3.0",