[#38], empty contact code field fix, more style fixes, cleanup

This commit is contained in:
Aleksandr Pantiukhov 2018-10-22 19:34:08 +02:00 committed by Alexander Pantyuhov
parent 42cf08898b
commit 94530050bf
7 changed files with 215 additions and 190 deletions

View File

@ -6,7 +6,7 @@ import { getDefaultAccount } from '../utils/web3Helpers'
import { actions as accountActions } from '../reducers/accounts'
import { isNil } from 'lodash'
const { receiveAccounts, receiveStatusContactCode } = accountActions
const { receiveAccounts, receiveStatusContactCode } = accountActions;
export const fetchAndDispatchAccountsWithBalances = (web3, dispatch) => {
web3.eth.getAccounts((err, addresses) => {
@ -23,15 +23,16 @@ export const fetchAndDispatchAccountsWithBalances = (web3, dispatch) => {
}
})
}
export const checkAndDispatchStatusContactCode = dispatch => {
export const checkAndDispatchStatusContactCode = (dispatch, callback) => {
window.web3.currentProvider.status
.getContactCode()
.then(data => {
dispatch(receiveStatusContactCode(data));
})
.catch(err => {
console.warn('Error:', err);
})
.getContactCode()
.then(data => {
callback(data);
dispatch(receiveStatusContactCode(data));
})
.catch(err => {
console.warn('Error:', err);
})
};
export const fetchAndDispatchSNTAllowance = dispatch => {

View File

@ -1,8 +1,5 @@
import React from 'react';
import Typography from '@material-ui/core/Typography';
import { connect } from 'react-redux';
import { YOUR_CONTACT_CODE } from './constants';
import { checkAndDispatchStatusContactCode } from '../../actions/accounts';
import styled from "styled-components";
const DisplayLabel = styled.div`
@ -11,34 +8,46 @@ const DisplayLabel = styled.div`
margin: 0 1em;
`;
const DisplayBox = styled.div`
const DisplayBoxDiv = 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;
justify-content: space-around;
align-items: ${props => props.showBlueBox ? "center" : "initial"};
word-wrap: break-word;
min-height: ${props => props.onClick ? "112px" : "0px"};
`;
const WrappedDisplayBox = ({displayType, pubKey, getStatusContactCode}) => (
const InnerDisplayBox = styled.div`
margin: 16px;
`;
const BlueBox = styled.div`
color: #4360df;
`;
const DisplayBox = ({displayType, text, onClick, showBlueBox}) => (
<div>
<DisplayLabel>
{displayType}
</DisplayLabel>
<DisplayBox onClick={() => getStatusContactCode(displayType, pubKey)}>
<div style={{margin: '16px'}}>
<Typography type='body1'>{pubKey}</Typography>
</div>
</DisplayBox>
<DisplayBoxDiv showBlueBox={showBlueBox} onClick={onClick}>
<InnerDisplayBox>
{
showBlueBox && onClick ?
<BlueBox>
Grant access
</BlueBox>
:
<Typography type='body1'>
{text}
</Typography>
}
</InnerDisplayBox>
</DisplayBoxDiv>
</div>
);
const mapDispatchToDisplayBoxProps = dispatch => ({
getStatusContactCode(displayType, pubKey) {
if (displayType === YOUR_CONTACT_CODE && !pubKey) checkAndDispatchStatusContactCode(dispatch);
},
});
export default connect(null, mapDispatchToDisplayBoxProps)(WrappedDisplayBox);
export default DisplayBox;

View File

@ -4,9 +4,8 @@ import TestToken from 'Embark/contracts/TestToken';
import React from 'react';
import {connect} from 'react-redux';
import Hidden from '@material-ui/core/Hidden';
import {withStyles} from '@material-ui/core/styles';
import CircularProgress from '@material-ui/core/CircularProgress';
import {Button, MobileButton} from '../../ui/components';
import {Button, StyledButton} from '../../ui/components';
import {withFormik} from 'formik';
import {hash} from 'eth-ens-namehash';
import {zeroAddress, zeroBytes32, formatPrice} from './utils';
@ -18,136 +17,153 @@ import {generateXY} from '../../utils/ecdsa';
import {getResolver} from './utils/domain';
import DisplayBox from './DisplayBox';
import { YOUR_CONTACT_CODE, YOUR_WALLET_ADDRESS } from './constants';
import classNames from "classnames";
import {checkAndDispatchStatusContactCode} from "../../actions/accounts";
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 displayTerms = status => status === 'terms';
const InnerForm = ({
classes,
values,
errors,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
setFieldValue,
subDomain,
domainName,
domainPrice,
editAccount,
setStatus,
status,
SNTAllowance,
SNTBalance,
}) => (
<form onSubmit={handleSubmit} ref={formRef}>
<div style={{ margin: '12px' }}>
{!subDomain &&
<FieldGroup
id="subDomain"
name="subDomain"
type="text"
label="Sub Domain"
onChange={handleChange}
onBlur={handleBlur}
value={values.subDomain}
error={errors.subDomain}
/>}
{!domainName &&
<FieldGroup
id="domainName"
name="domainName"
type="text"
label="Domain Name"
onChange={handleChange}
onBlur={handleBlur}
value={values.domainName}
button={
<Button
mode="strong"
style={{marginTop: '5px'}}
onClick={() => {
UsernameRegistrar.methods.getPrice()
.call()
.then((res) => {
setFieldValue('price', fromWei(res));
});
}}>
Get Price
</Button>
}
/>}
{!domainPrice &&
<FieldGroup
id="price"
name="price"
label="Domain Price"
disabled
value={values.price ? `${formatPrice(values.price)} SNT` : ''} />}
<Hidden mdDown>
<FieldGroup
id="statusAddress"
name="statusAddress"
type="text"
label="Status messenger address domain resolves to"
onChange={handleChange}
onBlur={handleBlur}
value={values.statusAddress}
error={errors.statusAddress}
wide="true"
/>
<FieldGroup
id="address"
name="address"
type="text"
label="Ethereum address domain resolves to"
onChange={handleChange}
onBlur={handleBlur}
value={values.address}
error={errors.address}
button={<Button mode="strong" style={{ padding: '5px 15px 5px 15px', marginTop: '5px' }} onClick={() => setFieldValue('address', web3.eth.defaultAccount)}>Use My Primary Address</Button>}
/>
{!isSubmitting ? <Button wide mode="strong" type="submit" disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? 'Submit' : 'Submitting to the Blockchain - (this may take awhile)'}</Button> : <LinearProgress />}
</Hidden>
class InnerForm extends React.Component {
requestStatusContactCode = ({getStatusContactCode, setValues, values}) => {
getStatusContactCode((result) => {
setValues({...values, statusAddress: result});
});
};
<Hidden mdUp>
onRegisterClick = ({values, setStatus}) => {
if (values.statusAddress) {
setStatus("terms");
} else {
alert("You have to grant access to your contact code first")
}
};
<DisplayBox displayType={YOUR_WALLET_ADDRESS} pubKey={values.address} />
<DisplayBox displayType={YOUR_CONTACT_CODE} pubKey={values.statusAddress} />
render() {
const {
values,
errors,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
setFieldValue,
subDomain,
domainName,
domainPrice,
editAccount,
setStatus,
status
} = this.props;
<div style={{ position: 'relative', left: 0, right: 0, bottom: 0, textAlign: 'center' }}>
{!isSubmitting ?
<Button onClick={() => {setStatus('terms')}} className={classNames(classes.button)}>
<div className={classNames(classes.buttonText)}>
{`${editAccount ? 'Save' : 'Register'} with transaction`}
</div>
</Button>
:
<CircularProgress />}
<Terms open={displayTerms(status)} onSubmit={() => { setStatus(null); formRef.current.dispatchEvent(new Event('submit')) }} form={formRef} />
return (
<form onSubmit={handleSubmit} ref={formRef}>
<div style={{margin: '12px'}}>
{!subDomain &&
<FieldGroup
id="subDomain"
name="subDomain"
type="text"
label="Sub Domain"
onChange={handleChange}
onBlur={handleBlur}
value={values.subDomain}
error={errors.subDomain}
/>}
{!domainName &&
<FieldGroup
id="domainName"
name="domainName"
type="text"
label="Domain Name"
onChange={handleChange}
onBlur={handleBlur}
value={values.domainName}
button={
<Button
mode="strong"
style={{marginTop: '5px'}}
onClick={() => {
UsernameRegistrar.methods.getPrice()
.call()
.then((res) => {
setFieldValue('price', fromWei(res));
});
}}>
Get Price
</Button>
}
/>}
{!domainPrice &&
<FieldGroup
id="price"
name="price"
label="Domain Price"
disabled
value={values.price ? `${formatPrice(values.price)} SNT` : ''}/>}
<Hidden mdDown>
<FieldGroup
id="statusAddress"
name="statusAddress"
type="text"
label="Status messenger address domain resolves to"
onChange={handleChange}
onBlur={handleBlur}
value={values.statusAddress}
error={errors.statusAddress}
wide="true"
/>
<FieldGroup
id="address"
name="address"
type="text"
label="Ethereum address domain resolves to"
onChange={handleChange}
onBlur={handleBlur}
value={values.address}
error={errors.address}
button={<Button mode="strong"
style={{padding: '5px 15px 5px 15px', marginTop: '5px'}}
onClick={() => setFieldValue('address', web3.eth.defaultAccount)}>Use My Primary
Address</Button>}
/>
{!isSubmitting ? <Button wide mode="strong" type="submit"
disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? 'Submit' : 'Submitting to the Blockchain - (this may take awhile)'}</Button> :
<LinearProgress/>}
</Hidden>
<Hidden mdUp>
<DisplayBox displayType={YOUR_WALLET_ADDRESS}
text={values.address}/>
<DisplayBox displayType={YOUR_CONTACT_CODE}
text={values.statusAddress}
showBlueBox={!values.statusAddress}
onClick={() => this.requestStatusContactCode(this.props)}/>
<div style={{position: 'relative', left: 0, right: 0, bottom: 0, textAlign: 'center'}}>
{!isSubmitting ?
<StyledButton onClick={() => this.onRegisterClick(this.props)}>
<div>
{`${editAccount ? 'Save' : 'Register'}`}
</div>
</StyledButton>
:
<CircularProgress/>}
<Terms open={displayTerms(status)}
onSubmit={() => {
setStatus(null);
formRef.current.dispatchEvent(new Event('submit'))
}}
form={formRef}/>
</div>
</Hidden>
</div>
</Hidden>
</div>
</form>
);
const StyledInnerForm = withStyles(styles)(InnerForm);
</form>
);
}
}
const RegisterSubDomain = withFormik({
mapPropsToValues: props => ({ subDomain: '', domainName: '', price: '', statusAddress: props.statusContactCode || '', address: web3.eth.defaultAccount || '' }),
@ -196,7 +212,7 @@ const RegisterSubDomain = withFormik({
toSend.send({ gas })
.on('transactionHash', (txHash) => { if (preRegisteredCallback) preRegisteredCallback(txHash); })
.then((txId) => {
if (txId.status == "0x1" || txId.status == "0x01"){
if (txId.status === "0x1" || txId.status === "0x01"){
console.log("Register send success. :)");
} else {
console.log("Register send errored. :( Out of gas? ");
@ -215,12 +231,15 @@ const RegisterSubDomain = withFormik({
})
}).catch(err => {
console.log("Register would error. :/ Already Registered? Have Token Balance? Is Allowance set?")
console.dir(err)
console.dir(err);
if (err && err.message) {
alert(err.message);
}
setSubmitting(false);
});
}
}
})(StyledInnerForm);
})(InnerForm);
const mapStateToProps = state => ({
statusContactCode: getStatusContactCode(state),
@ -228,4 +247,10 @@ const mapStateToProps = state => ({
SNTBalance: getCurrentAccount(state) && getCurrentAccount(state).SNTBalance,
});
export default connect(mapStateToProps)(RegisterSubDomain);
const mapDispatchToDisplayBoxProps = dispatch => ({
getStatusContactCode(callback) {
checkAndDispatchStatusContactCode(dispatch, callback);
},
});
export default connect(mapStateToProps, mapDispatchToDisplayBoxProps)(RegisterSubDomain);

View File

@ -1,8 +1,6 @@
import React from 'react';
import classNames from 'classnames';
import {withStyles} from '@material-ui/core/styles';
import Dialog from '@material-ui/core/Dialog';
import {Button} from '../../ui/components';
import {StyledButton} from '../../ui/components';
import styled from "styled-components";
const TermsContainer = styled.div`
@ -35,18 +33,9 @@ const ListContainer = styled.ul`
}
`;
const StyledButton = styled(Button)`
background-color: rgba(67, 96, 223, 0.1);
div {
color: #4360df;
margin: 0 20px;
font-weight: 400;
text-transform: uppercase;
}
`;
const buttonText = { color: '#4360df', margin: '0 20px', fontWeight: 300 };
const Terms = ({ open, onSubmit }) => (
const Terms = ({ classes, open, onSubmit }) => (
<Dialog fullScreen open={open}>
<TermsContainer>
<InfoHeading className="ens-terms__title">Terms of name registration</InfoHeading>

View File

@ -1,25 +1,10 @@
import React from 'react';
import classNames from 'classnames';
import {withStyles} from '@material-ui/core/styles';
import {Button} from '../../ui/components';
import {StyledButton} from '../../ui/components';
import StatusCards from '../../ui/icons/svg/intro_name.svg';
import {BrowserRouter as Router, Route, Link} from "react-router-dom";
import {Link} from "react-router-dom";
import './welcome.css';
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 WelcomeContent = () => (
<div>
<div className="ens-welcome__guide"><span>How it works</span></div>
@ -47,19 +32,19 @@ const WelcomeContent = () => (
</div>
);
const Welcome = ({ classes }) => (
const Welcome = () => (
<div className="ens-welcome">
<img className="ens-welcome__img" src={StatusCards} />
<h2 className="ens-welcome__title">
ENS names transform those crazy-long addresses into unique usernames
</h2>
<Link to="/search">
<Button className={classNames(classes.button)}>
<div className={classNames(classes.buttonText)}>Let's Go</div>
</Button>
<StyledButton>
<div>Let's Go</div>
</StyledButton>
</Link>
<WelcomeContent/>
</div>
);
export default withStyles(styles)(Welcome);
export default Welcome;

View File

@ -0,0 +1,15 @@
import {Button} from "./index";
import styled from "styled-components";
const StyledButton = styled(Button)`
background-color: rgba(67, 96, 223, 0.1);
div {
color: #4360df;
margin: 0 20px;
font-weight: 400;
text-transform: uppercase;
}
`;
export default StyledButton;

View File

@ -1,6 +1,7 @@
// @create-index
export * from './Button';
export { default as StyledButton } from './StyledButton.js';
export { default as Card } from './Card.js';
export { default as Field } from './Field.js';
export { default as Text } from './Text.js';