aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancesco Agosti <francesco.agosti93@gmail.com>2018-05-18 04:15:24 +0800
committerGitHub <noreply@github.com>2018-05-18 04:15:24 +0800
commit72503c068931d644e65e1b4a78fdc940a11fb4e1 (patch)
treedef4514311e9a16b5ca96c58beba5028a13b8d2e
parentc9d304146008eb621397657865a184767bc6df7e (diff)
parente9e570db4f158119dc86141201b695f52b3a5ca2 (diff)
downloaddexon-sol-tools-72503c068931d644e65e1b4a78fdc940a11fb4e1.tar
dexon-sol-tools-72503c068931d644e65e1b4a78fdc940a11fb4e1.tar.gz
dexon-sol-tools-72503c068931d644e65e1b4a78fdc940a11fb4e1.tar.bz2
dexon-sol-tools-72503c068931d644e65e1b4a78fdc940a11fb4e1.tar.lz
dexon-sol-tools-72503c068931d644e65e1b4a78fdc940a11fb4e1.tar.xz
dexon-sol-tools-72503c068931d644e65e1b4a78fdc940a11fb4e1.tar.zst
dexon-sol-tools-72503c068931d644e65e1b4a78fdc940a11fb4e1.zip
Merge pull request #596 from 0xProject/feature/website/weth-eth-conversion-errors
Show error messages in the wrapped ether item
-rw-r--r--packages/website/ts/components/inputs/balance_bounded_input.tsx47
-rw-r--r--packages/website/ts/components/inputs/eth_amount_input.tsx11
-rw-r--r--packages/website/ts/components/inputs/token_amount_input.tsx28
-rw-r--r--packages/website/ts/components/wallet/wrap_ether_item.tsx54
-rw-r--r--packages/website/ts/pages/about/about.tsx6
-rw-r--r--packages/website/ts/types.ts1
6 files changed, 104 insertions, 43 deletions
diff --git a/packages/website/ts/components/inputs/balance_bounded_input.tsx b/packages/website/ts/components/inputs/balance_bounded_input.tsx
index 68b77cfc3..f91a99355 100644
--- a/packages/website/ts/components/inputs/balance_bounded_input.tsx
+++ b/packages/website/ts/components/inputs/balance_bounded_input.tsx
@@ -5,7 +5,7 @@ import TextField from 'material-ui/TextField';
import * as React from 'react';
import { Link } from 'react-router-dom';
import { RequiredLabel } from 'ts/components/ui/required_label';
-import { InputErrMsg, ValidatedBigNumberCallback, WebsitePaths } from 'ts/types';
+import { ValidatedBigNumberCallback, WebsitePaths } from 'ts/types';
import { utils } from 'ts/utils/utils';
interface BalanceBoundedInputProps {
@@ -14,18 +14,21 @@ interface BalanceBoundedInputProps {
amount?: BigNumber;
hintText?: string;
onChange: ValidatedBigNumberCallback;
+ onErrorMsgChange?: (errorMsg: React.ReactNode) => void;
shouldShowIncompleteErrs?: boolean;
shouldCheckBalance: boolean;
- validate?: (amount: BigNumber) => InputErrMsg;
+ validate?: (amount: BigNumber) => React.ReactNode;
onVisitBalancesPageClick?: () => void;
shouldHideVisitBalancesLink?: boolean;
isDisabled?: boolean;
shouldShowErrs?: boolean;
shouldShowUnderline?: boolean;
+ inputStyle?: React.CSSProperties;
+ inputHintStyle?: React.CSSProperties;
}
interface BalanceBoundedInputState {
- errMsg: InputErrMsg;
+ errMsg: React.ReactNode;
amountString: string;
}
@@ -36,6 +39,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
isDisabled: false,
shouldShowErrs: true,
hintText: 'amount',
+ onErrorMsgChange: _.noop,
shouldShowUnderline: true,
};
constructor(props: BalanceBoundedInputProps) {
@@ -63,17 +67,11 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
}
if (shouldResetState) {
const amountString = nextProps.amount.toString();
- this.setState({
- errMsg: this._validate(amountString, nextProps.balance),
- amountString,
- });
+ this._setAmountState(amountString, nextProps.balance);
}
} else if (isCurrentAmountNumeric) {
const amountString = '';
- this.setState({
- errMsg: this._validate(amountString, nextProps.balance),
- amountString,
- });
+ this._setAmountState(amountString, nextProps.balance);
}
}
public render(): React.ReactNode {
@@ -99,21 +97,21 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
hintText={<span style={{ textTransform: 'capitalize' }}>{this.props.hintText}</span>}
onChange={this._onValueChange.bind(this)}
underlineStyle={{ width: 'calc(100% + 50px)' }}
+ inputStyle={this.props.inputStyle}
+ hintStyle={this.props.inputHintStyle}
underlineShow={this.props.shouldShowUnderline}
disabled={this.props.isDisabled}
/>
);
}
private _onValueChange(e: any, amountString: string): void {
- const errMsg = this._validate(amountString, this.props.balance);
- this.setState(
- {
- amountString,
- errMsg,
- },
+ this._setAmountState(
+ amountString,
+ this.props.balance,
() => {
- const isValid = _.isUndefined(errMsg);
- if (utils.isNumeric(amountString) && !_.includes(amountString, '-')) {
+ const isValid = _.isUndefined(this._validate(amountString, this.props.balance));
+ const isPositiveNumber = utils.isNumeric(amountString) && !_.includes(amountString, '-');
+ if (isPositiveNumber) {
this.props.onChange(isValid, new BigNumber(amountString));
} else {
this.props.onChange(isValid);
@@ -121,7 +119,7 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
},
);
}
- private _validate(amountString: string, balance: BigNumber): InputErrMsg {
+ private _validate(amountString: string, balance: BigNumber): React.ReactNode {
if (!utils.isNumeric(amountString)) {
return amountString !== '' ? 'Must be a number' : '';
}
@@ -161,4 +159,13 @@ export class BalanceBoundedInput extends React.Component<BalanceBoundedInputProp
);
}
}
+
+ private _setAmountState(amount: string, balance: BigNumber, callback: () => void = _.noop): void {
+ const errorMsg = this._validate(amount, balance);
+ this.props.onErrorMsgChange(errorMsg);
+ this.setState({
+ amountString: amount,
+ errMsg: errorMsg,
+ }, callback);
+ }
}
diff --git a/packages/website/ts/components/inputs/eth_amount_input.tsx b/packages/website/ts/components/inputs/eth_amount_input.tsx
index c3822a80b..fa684d85c 100644
--- a/packages/website/ts/components/inputs/eth_amount_input.tsx
+++ b/packages/website/ts/components/inputs/eth_amount_input.tsx
@@ -12,6 +12,7 @@ interface EthAmountInputProps {
amount?: BigNumber;
hintText?: string;
onChange: ValidatedBigNumberCallback;
+ onErrorMsgChange?: (errorMsg: React.ReactNode) => void;
shouldShowIncompleteErrs: boolean;
onVisitBalancesPageClick?: () => void;
shouldCheckBalance: boolean;
@@ -19,6 +20,8 @@ interface EthAmountInputProps {
shouldShowErrs?: boolean;
shouldShowUnderline?: boolean;
style?: React.CSSProperties;
+ labelStyle?: React.CSSProperties;
+ inputHintStyle?: React.CSSProperties;
}
interface EthAmountInputState {}
@@ -40,6 +43,7 @@ export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmou
balance={this.props.balance}
amount={amount}
onChange={this._onChange.bind(this)}
+ onErrorMsgChange={this.props.onErrorMsgChange}
shouldCheckBalance={this.props.shouldCheckBalance}
shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
onVisitBalancesPageClick={this.props.onVisitBalancesPageClick}
@@ -47,8 +51,10 @@ export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmou
hintText={this.props.hintText}
shouldShowErrs={this.props.shouldShowErrs}
shouldShowUnderline={this.props.shouldShowUnderline}
+ inputStyle={this.props.style}
+ inputHintStyle={this.props.inputHintStyle}
/>
- <div style={{ paddingTop: _.isUndefined(this.props.label) ? 15 : 40 }}>ETH</div>
+ <div style={this._getLabelStyle()}>ETH</div>
</div>
);
}
@@ -58,4 +64,7 @@ export class EthAmountInput extends React.Component<EthAmountInputProps, EthAmou
: ZeroEx.toBaseUnitAmount(amount, constants.DECIMAL_PLACES_ETH);
this.props.onChange(isValid, baseUnitAmountIfExists);
}
+ private _getLabelStyle(): React.CSSProperties {
+ return this.props.labelStyle || { paddingTop: _.isUndefined(this.props.label) ? 15 : 40 };
+ }
}
diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx
index 9a74bdd51..f040928f1 100644
--- a/packages/website/ts/components/inputs/token_amount_input.tsx
+++ b/packages/website/ts/components/inputs/token_amount_input.tsx
@@ -6,7 +6,7 @@ import * as React from 'react';
import { Link } from 'react-router-dom';
import { Blockchain } from 'ts/blockchain';
import { BalanceBoundedInput } from 'ts/components/inputs/balance_bounded_input';
-import { InputErrMsg, Token, ValidatedBigNumberCallback, WebsitePaths } from 'ts/types';
+import { Token, ValidatedBigNumberCallback, WebsitePaths } from 'ts/types';
interface TokenAmountInputProps {
userAddress: string;
@@ -20,11 +20,14 @@ interface TokenAmountInputProps {
shouldCheckBalance: boolean;
shouldCheckAllowance: boolean;
onChange: ValidatedBigNumberCallback;
+ onErrorMsgChange?: (errorMsg: React.ReactNode) => void;
onVisitBalancesPageClick?: () => void;
lastForceTokenStateRefetch: number;
shouldShowErrs?: boolean;
shouldShowUnderline?: boolean;
style?: React.CSSProperties;
+ labelStyle?: React.CSSProperties;
+ inputHintStyle?: React.CSSProperties;
}
interface TokenAmountInputState {
@@ -74,17 +77,14 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
const amount = this.props.amount
? ZeroEx.toUnitAmount(this.props.amount, this.props.token.decimals)
: undefined;
- const hasLabel = !_.isUndefined(this.props.label);
- const style = !_.isUndefined(this.props.style)
- ? this.props.style
- : { height: hasLabel ? HEIGHT_WITH_LABEL : HEIGHT_WITHOUT_LABEL };
return (
- <div className="flex overflow-hidden" style={style}>
+ <div className="flex overflow-hidden" style={this._getStyle()}>
<BalanceBoundedInput
label={this.props.label}
amount={amount}
balance={ZeroEx.toUnitAmount(this.state.balance, this.props.token.decimals)}
onChange={this._onChange.bind(this)}
+ onErrorMsgChange={this.props.onErrorMsgChange}
validate={this._validate.bind(this)}
shouldCheckBalance={this.props.shouldCheckBalance}
shouldShowIncompleteErrs={this.props.shouldShowIncompleteErrs}
@@ -93,8 +93,10 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
hintText={this.props.hintText}
shouldShowErrs={this.props.shouldShowErrs}
shouldShowUnderline={this.props.shouldShowUnderline}
+ inputStyle={this.props.style}
+ inputHintStyle={this.props.inputHintStyle}
/>
- <div style={{ paddingTop: hasLabel ? 39 : 14 }}>{this.props.token.symbol}</div>
+ <div style={this._getLabelStyle()}>{this.props.token.symbol}</div>
</div>
);
}
@@ -105,7 +107,7 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
}
this.props.onChange(isValid, baseUnitAmount);
}
- private _validate(amount: BigNumber): InputErrMsg {
+ private _validate(amount: BigNumber): React.ReactNode {
if (this.props.shouldCheckAllowance && amount.gt(this.state.allowance)) {
return (
<span>
@@ -139,4 +141,14 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok
});
}
}
+ private _getStyle(): React.CSSProperties {
+ const hasLabel = !_.isUndefined(this.props.label);
+ return !_.isUndefined(this.props.style)
+ ? this.props.style
+ : { height: hasLabel ? HEIGHT_WITH_LABEL : HEIGHT_WITHOUT_LABEL };
+ }
+ private _getLabelStyle(): React.CSSProperties {
+ const hasLabel = !_.isUndefined(this.props.label);
+ return this.props.labelStyle || { paddingTop: hasLabel ? 39 : 14 };
+ }
}
diff --git a/packages/website/ts/components/wallet/wrap_ether_item.tsx b/packages/website/ts/components/wallet/wrap_ether_item.tsx
index 2ed924bcd..581d2ba97 100644
--- a/packages/website/ts/components/wallet/wrap_ether_item.tsx
+++ b/packages/website/ts/components/wallet/wrap_ether_item.tsx
@@ -31,8 +31,8 @@ export interface WrapEtherItemProps {
interface WrapEtherItemState {
currentInputAmount?: BigNumber;
- currentInputHasErrors: boolean;
isEthConversionHappening: boolean;
+ errorMsg: React.ReactNode;
}
const styles: Styles = {
@@ -46,13 +46,29 @@ const styles: Styles = {
padding: 4,
width: 125,
},
- ethAmountInput: { height: 32 },
- innerDiv: { paddingLeft: 60, paddingTop: 0 },
- wrapEtherConfirmationButtonContainer: { width: 128, top: 16 },
+ amountInput: { height: 34 },
+ amountInputLabel: {
+ paddingTop: 10,
+ paddingRight: 10,
+ paddingLeft: 5,
+ color: colors.grey,
+ fontSize: 14,
+ },
+ amountInputHint: {
+ bottom: 18,
+ },
+ innerDiv: { paddingLeft: 60, paddingTop: 0, paddingBottom: 10 },
+ wrapEtherConfirmationButtonContainer: { width: 128, top: 19 },
wrapEtherConfirmationButtonLabel: {
- fontSize: 10,
+ fontSize: 12,
color: colors.white,
},
+ errorMsg: {
+ fontSize: 12,
+ marginTop: 4,
+ color: colors.red,
+ minHeight: 20,
+ },
};
export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEtherItemState> {
@@ -60,8 +76,8 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
super(props);
this.state = {
currentInputAmount: undefined,
- currentInputHasErrors: false,
isEthConversionHappening: false,
+ errorMsg: null,
};
}
public render(): React.ReactNode {
@@ -84,7 +100,10 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
shouldShowIncompleteErrs={false}
shouldShowErrs={false}
shouldShowUnderline={false}
- style={styles.ethAmountInput}
+ style={styles.amountInput}
+ labelStyle={styles.amountInputLabel}
+ inputHintStyle={styles.amountInputHint}
+ onErrorMsgChange={this._onErrorMsgChange.bind(this)}
/>
) : (
<TokenAmountInput
@@ -99,12 +118,16 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
onChange={this._onValueChange.bind(this)}
amount={this.state.currentInputAmount}
hintText="0.00"
- shouldShowErrs={false} // TODO: error handling
+ shouldShowErrs={false}
shouldShowUnderline={false}
- style={styles.ethAmountInput}
+ style={styles.amountInput}
+ labelStyle={styles.amountInputLabel}
+ inputHintStyle={styles.amountInputHint}
+ onErrorMsgChange={this._onErrorMsgChange.bind(this)}
/>
)}
</div>
+ {this._renderErrorMsg()}
</div>
}
secondaryTextLines={2}
@@ -119,7 +142,11 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
private _onValueChange(isValid: boolean, amount?: BigNumber): void {
this.setState({
currentInputAmount: amount,
- currentInputHasErrors: !isValid,
+ });
+ }
+ private _onErrorMsgChange(errorMsg: React.ReactNode): void {
+ this.setState({
+ errorMsg,
});
}
private _renderIsEthConversionHappeningSpinner(): React.ReactElement<{}> {
@@ -144,6 +171,13 @@ export class WrapEtherItem extends React.Component<WrapEtherItemProps, WrapEther
</div>
);
}
+ private _renderErrorMsg(): React.ReactNode {
+ return (
+ <div style={styles.errorMsg}>
+ {this.state.errorMsg}
+ </div>
+ );
+ }
private async _wrapEtherConfirmationActionAsync(): Promise<void> {
this.setState({
isEthConversionHappening: true,
diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx
index 360cbb136..ac67ca968 100644
--- a/packages/website/ts/pages/about/about.tsx
+++ b/packages/website/ts/pages/about/about.tsx
@@ -37,7 +37,7 @@ const teamRow1: ProfileInfo[] = [
name: 'Fabio Berger',
title: 'Senior Engineer',
description: `Full-stack blockchain engineer. Previously software engineer \
- at Airtable and founder of WealthLift. Computer science at Duke.`,
+ at Airtable and founder of WealthLift. Computer Science at Duke.`,
image: '/images/team/fabio.jpg',
linkedIn: 'https://www.linkedin.com/in/fabio-berger-03ab261a/',
github: 'https://github.com/fabioberger',
@@ -60,7 +60,7 @@ const teamRow2: ProfileInfo[] = [
name: 'Leonid Logvinov',
title: 'Engineer',
description: `Full-stack blockchain engineer. Previously blockchain engineer \
- at Neufund. Computer science at University of Warsaw.`,
+ at Neufund. Computer Science at University of Warsaw.`,
image: '/images/team/leonid.png',
linkedIn: 'https://www.linkedin.com/in/leonidlogvinov/',
github: 'https://github.com/LogvinovLeon',
@@ -152,7 +152,7 @@ const teamRow5: ProfileInfo[] = [
{
name: 'Francesco Agosti',
title: 'Senior Frontend Engineer',
- description: `Full-stack engineer. Previously senior software engineer at Yelp. Computer science Duke.`,
+ description: `Full-stack engineer. Previously senior software engineer at Yelp. Computer Science at Duke.`,
image: 'images/team/fragosti.png',
linkedIn: 'https://www.linkedin.com/in/fragosti/',
github: 'http://github.com/fragosti',
diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts
index 5caf5e73c..33e4d6c30 100644
--- a/packages/website/ts/types.ts
+++ b/packages/website/ts/types.ts
@@ -207,7 +207,6 @@ export interface ContractEvent {
args: any;
}
-export type InputErrMsg = React.ReactNode | string | undefined;
export type ValidatedBigNumberCallback = (isValid: boolean, amount?: BigNumber) => void;
export enum ScreenWidths {
Sm = 'SM',