Add frontend validation to send-token

This commit is contained in:
Chi Kei Chan 2017-09-11 23:18:54 -07:00
parent 1e83835ba8
commit 836bf2e1a3
7 changed files with 119 additions and 14 deletions

View File

@ -22,7 +22,7 @@ InputNumber.prototype.componentWillMount = function () {
}
InputNumber.prototype.setValue = function (newValue) {
const { fixed, min, onChange } = this.props
const { fixed, min = -1, onChange } = this.props
if (fixed) newValue = Number(newValue.toFixed(4))

View File

@ -2,6 +2,7 @@ const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
const ethUtil = require('ethereumjs-util')
const classnames = require('classnames')
const inherits = require('util').inherits
const actions = require('../../actions')
const selectors = require('../../selectors')
@ -62,10 +63,60 @@ function SendTokenScreen () {
Component.call(this)
this.state = {
to: '',
amount: null,
selectedCurrency: 'USD',
isGasTooltipOpen: false,
gasPrice: '0x5d21dba00',
gasLimit: '0x7b0d',
errors: {},
}
}
SendTokenScreen.prototype.validate = function () {
const {
to,
amount,
gasPrice: hexGasPrice,
gasLimit: hexGasLimit,
} = this.state
const gasPrice = parseInt(hexGasPrice, 16)
const gasLimit = parseInt(hexGasLimit, 16) / 1000000000
if (to && amount && gasPrice && gasLimit) {
return {
isValid: true,
errors: {},
}
}
const errors = {
to: !to ? 'Required' : null,
amount: !Number(amount) ? 'Required' : null,
gasPrice: !gasPrice ? 'Gas Price Required' : null,
gasLimit: !gasLimit ? 'Gas Limit Required' : null,
}
return {
isValid: false,
errors,
}
}
SendTokenScreen.prototype.submit = function () {
// const {
// to,
// amount,
// selectedCurrency,
// isGasTooltipOpen,
// gasPrice,
// gasLimit,
// } = this.state
const { isValid, errors } = this.validate()
if (!isValid) {
return this.setState({ errors })
}
}
@ -77,16 +128,24 @@ SendTokenScreen.prototype.renderToAddressInput = function () {
const {
to,
errors: { to: errorMessage },
} = this.state
return h('div.send-screen-input-wrapper', {}, [
return h('div', {
className: classnames('send-screen-input-wrapper', {
'send-screen-input-wrapper--error': errorMessage,
}),
}, [
h('div', ['To:']),
h('input.large-input.send-screen-input', {
name: 'address',
list: 'addresses',
placeholder: 'Address',
value: to,
onChange: e => this.setState({ to: e.target.value }),
onChange: e => this.setState({
to: e.target.value,
errors: {},
}),
}),
h('datalist#addresses', [
// Corresponds to the addresses owned.
@ -105,23 +164,30 @@ SendTokenScreen.prototype.renderToAddressInput = function () {
})
}),
]),
h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
])
}
SendTokenScreen.prototype.renderAmountInput = function () {
const {
selectedCurrency,
amount,
errors: { amount: errorMessage },
} = this.state
const {
selectedToken: {symbol},
} = this.props
return h('div.send-screen-input-wrapper', {}, [
return h('div.send-screen-input-wrapper', {
className: classnames('send-screen-input-wrapper', {
'send-screen-input-wrapper--error': errorMessage,
}),
}, [
h('div.send-screen-amount-labels', [
h('span', ['Amount']),
h(CurrencyToggle, {
selectedCurrency,
currentCurrency: selectedCurrency,
currencies: [ symbol, 'USD' ],
onClick: currency => this.setState({ selectedCurrency: currency }),
}),
@ -129,8 +195,13 @@ SendTokenScreen.prototype.renderAmountInput = function () {
h('input.large-input.send-screen-input', {
placeholder: `0 ${symbol}`,
type: 'number',
onChange: e => this.setState({ amount: e.target.value }),
value: amount,
onChange: e => this.setState({
amount: e.target.value,
errors: {},
}),
}),
h('div.send-screen-input-wrapper__error-message', [ errorMessage ]),
])
}
@ -140,6 +211,10 @@ SendTokenScreen.prototype.renderGasInput = function () {
gasPrice,
gasLimit,
selectedCurrency,
errors: {
gasPrice: gasPriceErrorMessage,
gasLimit: gasLimitErrorMessage,
},
} = this.state
const {
@ -147,14 +222,18 @@ SendTokenScreen.prototype.renderGasInput = function () {
currentBlockGasLimit,
} = this.props
return h('div.send-screen-input-wrapper', [
return h('div.send-screen-input-wrapper', {
className: classnames('send-screen-input-wrapper', {
'send-screen-input-wrapper--error': gasPriceErrorMessage || gasLimitErrorMessage,
}),
}, [
isGasTooltipOpen && h(GasTooltip, {
className: 'send-tooltip',
gasPrice,
gasLimit,
onClose: () => this.setState({ isGasTooltipOpen: false }),
onFeeChange: ({ gasLimit, gasPrice }) => {
this.setState({ gasLimit, gasPrice })
this.setState({ gasLimit, gasPrice, errors: {} })
},
}),
@ -176,6 +255,9 @@ SendTokenScreen.prototype.renderGasInput = function () {
['Customize']
),
]),
h('div.send-screen-input-wrapper__error-message', [
gasPriceErrorMessage || gasLimitErrorMessage,
]),
])
}
@ -194,7 +276,7 @@ SendTokenScreen.prototype.renderButtons = function () {
return h('div.send-token__button-group', [
h('button.send-token__button-next.btn-secondary', {
onClick: () => this.submit(),
}, ['Next']),
h('button.send-token__button-cancel.btn-tertiary', {
onClick: () => backToAccountDetail(selectedAddress),

View File

@ -22,14 +22,14 @@ CurrencyToggle.prototype.render = function () {
'currency-toggle__item--selected': currencyA === currentCurrency,
}),
onClick: () => onClick(currencyA),
}, ['ETH']),
}, [ currencyA ]),
'<>',
h('span', {
className: classnames('currency-toggle__item', {
'currency-toggle__item--selected': currencyB === currentCurrency,
}),
onClick: () => onClick(currencyB),
}, ['USD']),
}, [ currencyB ]),
]) // holding on icon from design
}

View File

@ -1,5 +1,6 @@
.confirm-screen-container {
position: absolute;
align-items: center;
@media screen and (max-width: 575px) {
margin-top: 35px;

View File

@ -87,10 +87,10 @@
}
button.btn-clear {
font-size: 75%;
background: $white;
border: 1px solid;
border-radius: 2px;
font-size: 12px;
@media screen and (max-width: $break-small) {
width: 23%;
@ -99,10 +99,9 @@
}
@media screen and (min-width: $break-large) {
font-size: .6em;
border-color: $curious-blue;
color: $curious-blue;
padding: 0px;
padding: 0;
width: 85px;
height: 34px;
}

View File

@ -42,6 +42,8 @@
.network-check__transparent {
opacity: 0;
width: 16px;
margin: 0;
}
.menu-icon-circle, .menu-icon-circle--active {

View File

@ -46,6 +46,27 @@
.send-screen-input-wrapper {
width: 95%;
position: relative;
&__error-message {
display: none;
}
&--error {
input,
.send-screen-gas-input {
border-color: $red !important;
}
.send-screen-input-wrapper__error-message {
display: block;
position: absolute;
bottom: 4px;
font-size: 12px;
line-height: 12px;
left: 8px;
color: $red;
}
}
}
.send-screen-input {