Browse Source

Merge pull request #169 from SuperNETorg/35-send-form-validation

#35 - send form validation
all-modes
pbca26 8 years ago
committed by GitHub
parent
commit
bd25c8b045
  1. 108
      react/src/components/dashboard/sendCoin/sendCoin.js
  2. 8
      react/src/components/dashboard/sendCoin/sendCoin.render.js
  3. 5
      react/src/components/dashboard/walletsData/walletsData.render.js
  4. 54
      react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js
  5. 5
      react/src/translate/en.js
  6. 7
      react/src/util/number.js

108
react/src/components/dashboard/sendCoin/sendCoin.js

@ -29,8 +29,8 @@ import {
SendCoinRender
} from './sendCoin.render';
import { SocketProvider } from 'socket.io-react';
import io from 'socket.io-client';
import { isPositiveNumber } from '../../../util/number';
const socket = io.connect(`http://127.0.0.1:${Config.agamaPort}`);
// TODO: prevent any cache updates rather than utxo while on send coin form
@ -380,6 +380,12 @@ class SendCoin extends React.Component {
});
}
if (step === 1) {
if (!this.validateSendFormData()) {
return;
}
}
if (step === 1 ||
step === 2) {
this.setState(Object.assign({}, this.state, {
@ -757,6 +763,106 @@ class SendCoin extends React.Component {
return null;
}
// TODO same as in walletsNav and receiveCoin, find a way to reuse it?
checkTotalBalance() {
let _balance = '0';
const _mode = this.props.ActiveCoin.mode;
if (_mode === 'full') {
_balance = this.props.ActiveCoin.balance || 0;
} else if (_mode === 'basilisk') {
if (this.props.ActiveCoin.cache) {
const _cache = this.props.ActiveCoin.cache;
const _coin = this.props.ActiveCoin.coin;
const _address = this.props.ActiveCoin.activeAddress;
if (_address &&
_cache[_coin] &&
_cache[_coin][_address] &&
_cache[_coin][_address].getbalance &&
_cache[_coin][_address].getbalance.data &&
(_cache[_coin][_address].getbalance.data.balance ||
_cache[_coin][_address].getbalance.data.interest)) {
const _regBalance = _cache[_coin][_address].getbalance.data.balance ? _cache[_coin][_address].getbalance.data.balance : 0;
const _regInterest = _cache[_coin][_address].getbalance.data.interest ? _cache[_coin][_address].getbalance.data.interest : 0;
_balance = _regBalance + _regInterest;
}
}
} else if (_mode === 'native') {
if (this.props.ActiveCoin.balance &&
this.props.ActiveCoin.balance.total) {
_balance = this.props.ActiveCoin.balance.total;
}
}
return +_balance;
}
validateSendFormData() {
let valid = true;
if (!this.state.sendTo || this.state.sendTo.length < 34) {
Store.dispatch(
triggerToaster(
translate('SEND.SEND_TO_ADDRESS_MIN_LENGTH'),
'',
'error'
)
);
valid = false;
}
if (!isPositiveNumber(this.state.amount)) {
Store.dispatch(
triggerToaster(
translate('SEND.AMOUNT_POSITIVE_NUMBER'),
'',
'error'
)
);
valid = false;
}
if (!isPositiveNumber(this.state.fee)) {
Store.dispatch(
triggerToaster(
translate('SEND.FEE_POSITIVE_NUMBER'),
'',
'error'
)
);
valid = false;
}
if (!isPositiveNumber(this.getTotalAmount())) {
Store.dispatch(
triggerToaster(
translate('SEND.TOTAL_AMOUNT_POSITIVE_NUMBER'),
'',
'error'
)
);
valid = false;
}
if (this.state.amount > this.checkTotalBalance()) {
Store.dispatch(
triggerToaster(
translate('SEND.INSUFFICIENT_FUNDS'),
'',
'error'
)
);
valid = false;
}
return valid;
}
getTotalAmount() {
return Number(this.state.amount) - Number(this.state.fee);
}
render() {
if (this.props.ActiveCoin &&
this.props.ActiveCoin.send &&

8
react/src/components/dashboard/sendCoin/sendCoin.render.js

@ -248,7 +248,8 @@ export const SendCoinRender = function() {
{ this.props.ActiveCoin.coin }
</label>
<input
type="text"
type="number"
min="0"
className="form-control"
id="edexcoinAmount"
name="amount"
@ -264,7 +265,8 @@ export const SendCoinRender = function() {
{ translate('INDEX.FEE') }
</label>
<input
type="text"
type="number"
min="0"
className="form-control"
id="edexcoinFee"
name="fee"
@ -278,7 +280,7 @@ export const SendCoinRender = function() {
{ translate('INDEX.TOTAL') }&nbsp;
({ translate('INDEX.AMOUNT_SM') } - { translate('INDEX.FEE') }):
</strong>&nbsp;
{ Number(this.state.amount) - Number(this.state.fee) } { this.props.ActiveCoin.coin }
{ this.getTotalAmount() } { this.props.ActiveCoin.coin }
</div>
<div className={ this.state.sendApiType ? 'hide' : 'col-lg-10 margin-top-30' }>
<span className="pointer">

5
react/src/components/dashboard/walletsData/walletsData.render.js

@ -181,6 +181,9 @@ export const TxHistoryListRender = function() {
};
export const WalletsDataRender = function() {
let _basiliskProgressBarWidth = 100 - (this.state.currentStackLength * 100 / this.state.totalStackLength);
_basiliskProgressBarWidth = _basiliskProgressBarWidth < 20 ? 20 : _basiliskProgressBarWidth;
return (
<span>
<WalletsBasiliskRefresh {...this.props} />
@ -197,7 +200,7 @@ export const WalletsDataRender = function() {
<div className={ 'margin-bottom-3 basilisk-progress-bar ' + (this.state.currentStackLength === 1 || (this.state.currentStackLength === 0 && this.state.totalStackLength === 0) ? 'hide' : 'progress progress-sm') }>
<div
className="progress-bar progress-bar-striped active progress-bar-indicating progress-bar-success font-size-80-percent"
style={{ width: 100 - (this.state.currentStackLength * 100 / this.state.totalStackLength) + '%' }}>
style={{ width: _basiliskProgressBarWidth + '%' }}>
{ translate('SEND.PROCESSING_REQ') }: { this.state.currentStackLength } / { this.state.totalStackLength }
</div>
</div>

54
react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js

@ -16,6 +16,7 @@ import {
WalletsNativeSendFormRender,
_WalletsNativeSendFormRender
} from './walletsNativeSend.render';
import { isPositiveNumber } from "../../../util/number";
class WalletsNativeSend extends React.Component {
constructor(props) {
@ -269,6 +270,10 @@ class WalletsNativeSend extends React.Component {
}
handleSubmit() {
if (!this.validateSendFormData()) {
return;
}
Store.dispatch(
sendNativeTx(
this.props.ActiveCoin.coin,
@ -348,6 +353,55 @@ class WalletsNativeSend extends React.Component {
return null;
}
checkTotalBalance() {
let _balance = 0;
if (this.props.ActiveCoin.balance &&
this.props.ActiveCoin.balance.total) {
_balance = this.props.ActiveCoin.balance.total;
}
return _balance;
}
validateSendFormData() {
let valid = true;
if (!this.state.sendTo || this.state.sendTo.length < 34) {
Store.dispatch(
triggerToaster(
translate('SEND.SEND_TO_ADDRESS_MIN_LENGTH'),
'',
'error'
)
);
valid = false;
}
if (!isPositiveNumber(this.state.amount)) {
Store.dispatch(
triggerToaster(
translate('SEND.AMOUNT_POSITIVE_NUMBER'),
'',
'error'
)
);
valid = false;
}
if (this.state.amount > this.checkTotalBalance()) {
Store.dispatch(
triggerToaster(
translate('SEND.INSUFFICIENT_FUNDS'),
'',
'error'
)
);
valid = false;
}
return valid;
}
render() {
if (this.props &&
this.props.ActiveCoin &&

5
react/src/translate/en.js

@ -633,6 +633,11 @@ export const _lang = {
'ENTER_AN_ADDRESS': 'Enter an address',
'YOU_PICKED_OPT': 'You picked option',
'PLEASE_WAIT': 'Please wait',
'SEND_TO_ADDRESS_MIN_LENGTH': 'Send to address must be at least 34 characters long',
'AMOUNT_POSITIVE_NUMBER': 'Amount must be a positive number',
'FEE_POSITIVE_NUMBER': 'Fee must be a positive number',
'TOTAL_AMOUNT_POSITIVE_NUMBER': 'Total amount (amount - fee) must be a positive number',
'INSUFFICIENT_FUNDS': 'You don\'t have the necessary funds to make this transaction',
},
'FIAT_CURRENCIES': {
'AUD': 'Australian Dollar (AUD)',

7
react/src/util/number.js

@ -0,0 +1,7 @@
export function isNumber(value) {
return !isNaN(parseFloat(value)) && isFinite(value);
}
export function isPositiveNumber(value) {
return isNumber(value) && (+value) > 0;
}
Loading…
Cancel
Save