mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add frontend validation to send-token
This commit is contained in:
parent
1e83835ba8
commit
836bf2e1a3
@ -22,7 +22,7 @@ InputNumber.prototype.componentWillMount = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
InputNumber.prototype.setValue = function (newValue) {
|
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))
|
if (fixed) newValue = Number(newValue.toFixed(4))
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ const Component = require('react').Component
|
|||||||
const connect = require('react-redux').connect
|
const connect = require('react-redux').connect
|
||||||
const h = require('react-hyperscript')
|
const h = require('react-hyperscript')
|
||||||
const ethUtil = require('ethereumjs-util')
|
const ethUtil = require('ethereumjs-util')
|
||||||
|
const classnames = require('classnames')
|
||||||
const inherits = require('util').inherits
|
const inherits = require('util').inherits
|
||||||
const actions = require('../../actions')
|
const actions = require('../../actions')
|
||||||
const selectors = require('../../selectors')
|
const selectors = require('../../selectors')
|
||||||
@ -62,10 +63,60 @@ function SendTokenScreen () {
|
|||||||
Component.call(this)
|
Component.call(this)
|
||||||
this.state = {
|
this.state = {
|
||||||
to: '',
|
to: '',
|
||||||
|
amount: null,
|
||||||
selectedCurrency: 'USD',
|
selectedCurrency: 'USD',
|
||||||
isGasTooltipOpen: false,
|
isGasTooltipOpen: false,
|
||||||
gasPrice: '0x5d21dba00',
|
gasPrice: '0x5d21dba00',
|
||||||
gasLimit: '0x7b0d',
|
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 {
|
const {
|
||||||
to,
|
to,
|
||||||
|
errors: { to: errorMessage },
|
||||||
} = this.state
|
} = 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('div', ['To:']),
|
||||||
h('input.large-input.send-screen-input', {
|
h('input.large-input.send-screen-input', {
|
||||||
name: 'address',
|
name: 'address',
|
||||||
list: 'addresses',
|
list: 'addresses',
|
||||||
placeholder: 'Address',
|
placeholder: 'Address',
|
||||||
value: to,
|
value: to,
|
||||||
onChange: e => this.setState({ to: e.target.value }),
|
onChange: e => this.setState({
|
||||||
|
to: e.target.value,
|
||||||
|
errors: {},
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
h('datalist#addresses', [
|
h('datalist#addresses', [
|
||||||
// Corresponds to the addresses owned.
|
// 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 () {
|
SendTokenScreen.prototype.renderAmountInput = function () {
|
||||||
const {
|
const {
|
||||||
selectedCurrency,
|
selectedCurrency,
|
||||||
|
amount,
|
||||||
|
errors: { amount: errorMessage },
|
||||||
} = this.state
|
} = this.state
|
||||||
|
|
||||||
const {
|
const {
|
||||||
selectedToken: {symbol},
|
selectedToken: {symbol},
|
||||||
} = this.props
|
} = 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('div.send-screen-amount-labels', [
|
||||||
h('span', ['Amount']),
|
h('span', ['Amount']),
|
||||||
h(CurrencyToggle, {
|
h(CurrencyToggle, {
|
||||||
selectedCurrency,
|
currentCurrency: selectedCurrency,
|
||||||
currencies: [ symbol, 'USD' ],
|
currencies: [ symbol, 'USD' ],
|
||||||
onClick: currency => this.setState({ selectedCurrency: currency }),
|
onClick: currency => this.setState({ selectedCurrency: currency }),
|
||||||
}),
|
}),
|
||||||
@ -129,8 +195,13 @@ SendTokenScreen.prototype.renderAmountInput = function () {
|
|||||||
h('input.large-input.send-screen-input', {
|
h('input.large-input.send-screen-input', {
|
||||||
placeholder: `0 ${symbol}`,
|
placeholder: `0 ${symbol}`,
|
||||||
type: 'number',
|
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,
|
gasPrice,
|
||||||
gasLimit,
|
gasLimit,
|
||||||
selectedCurrency,
|
selectedCurrency,
|
||||||
|
errors: {
|
||||||
|
gasPrice: gasPriceErrorMessage,
|
||||||
|
gasLimit: gasLimitErrorMessage,
|
||||||
|
},
|
||||||
} = this.state
|
} = this.state
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -147,14 +222,18 @@ SendTokenScreen.prototype.renderGasInput = function () {
|
|||||||
currentBlockGasLimit,
|
currentBlockGasLimit,
|
||||||
} = this.props
|
} = 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, {
|
isGasTooltipOpen && h(GasTooltip, {
|
||||||
className: 'send-tooltip',
|
className: 'send-tooltip',
|
||||||
gasPrice,
|
gasPrice,
|
||||||
gasLimit,
|
gasLimit,
|
||||||
onClose: () => this.setState({ isGasTooltipOpen: false }),
|
onClose: () => this.setState({ isGasTooltipOpen: false }),
|
||||||
onFeeChange: ({ gasLimit, gasPrice }) => {
|
onFeeChange: ({ gasLimit, gasPrice }) => {
|
||||||
this.setState({ gasLimit, gasPrice })
|
this.setState({ gasLimit, gasPrice, errors: {} })
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -176,6 +255,9 @@ SendTokenScreen.prototype.renderGasInput = function () {
|
|||||||
['Customize']
|
['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', [
|
return h('div.send-token__button-group', [
|
||||||
h('button.send-token__button-next.btn-secondary', {
|
h('button.send-token__button-next.btn-secondary', {
|
||||||
|
onClick: () => this.submit(),
|
||||||
}, ['Next']),
|
}, ['Next']),
|
||||||
h('button.send-token__button-cancel.btn-tertiary', {
|
h('button.send-token__button-cancel.btn-tertiary', {
|
||||||
onClick: () => backToAccountDetail(selectedAddress),
|
onClick: () => backToAccountDetail(selectedAddress),
|
||||||
|
@ -22,14 +22,14 @@ CurrencyToggle.prototype.render = function () {
|
|||||||
'currency-toggle__item--selected': currencyA === currentCurrency,
|
'currency-toggle__item--selected': currencyA === currentCurrency,
|
||||||
}),
|
}),
|
||||||
onClick: () => onClick(currencyA),
|
onClick: () => onClick(currencyA),
|
||||||
}, ['ETH']),
|
}, [ currencyA ]),
|
||||||
'<>',
|
'<>',
|
||||||
h('span', {
|
h('span', {
|
||||||
className: classnames('currency-toggle__item', {
|
className: classnames('currency-toggle__item', {
|
||||||
'currency-toggle__item--selected': currencyB === currentCurrency,
|
'currency-toggle__item--selected': currencyB === currentCurrency,
|
||||||
}),
|
}),
|
||||||
onClick: () => onClick(currencyB),
|
onClick: () => onClick(currencyB),
|
||||||
}, ['USD']),
|
}, [ currencyB ]),
|
||||||
]) // holding on icon from design
|
]) // holding on icon from design
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
.confirm-screen-container {
|
.confirm-screen-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
@media screen and (max-width: 575px) {
|
@media screen and (max-width: 575px) {
|
||||||
margin-top: 35px;
|
margin-top: 35px;
|
||||||
|
@ -87,10 +87,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
button.btn-clear {
|
button.btn-clear {
|
||||||
font-size: 75%;
|
|
||||||
background: $white;
|
background: $white;
|
||||||
border: 1px solid;
|
border: 1px solid;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
@media screen and (max-width: $break-small) {
|
@media screen and (max-width: $break-small) {
|
||||||
width: 23%;
|
width: 23%;
|
||||||
@ -99,10 +99,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: $break-large) {
|
@media screen and (min-width: $break-large) {
|
||||||
font-size: .6em;
|
|
||||||
border-color: $curious-blue;
|
border-color: $curious-blue;
|
||||||
color: $curious-blue;
|
color: $curious-blue;
|
||||||
padding: 0px;
|
padding: 0;
|
||||||
width: 85px;
|
width: 85px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,8 @@
|
|||||||
|
|
||||||
.network-check__transparent {
|
.network-check__transparent {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
width: 16px;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon-circle, .menu-icon-circle--active {
|
.menu-icon-circle, .menu-icon-circle--active {
|
||||||
|
@ -46,6 +46,27 @@
|
|||||||
.send-screen-input-wrapper {
|
.send-screen-input-wrapper {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
position: relative;
|
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 {
|
.send-screen-input {
|
||||||
|
Loading…
Reference in New Issue
Block a user