diff options
Diffstat (limited to 'packages/instant/src/components')
4 files changed, 90 insertions, 17 deletions
diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 5a32b9575..097b8e547 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -1,19 +1,56 @@ +import { BuyQuote } from '@0xproject/asset-buyer'; +import * as _ from 'lodash'; import * as React from 'react'; import { ColorOption } from '../style/theme'; +import { assetBuyer } from '../util/asset_buyer'; +import { web3Wrapper } from '../util/web3_wrapper'; import { Button, Container, Text } from './ui'; -export interface BuyButtonProps {} +export interface BuyButtonProps { + buyQuote?: BuyQuote; + onClick: (buyQuote: BuyQuote) => void; + onBuySuccess: (buyQuote: BuyQuote) => void; + onBuyFailure: (buyQuote: BuyQuote) => void; + text: string; +} -export const BuyButton: React.StatelessComponent<BuyButtonProps> = props => ( - <Container padding="20px" width="100%"> - <Button width="100%"> - <Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px"> - Buy - </Text> - </Button> - </Container> -); +const boundNoop = _.noop.bind(_); -BuyButton.displayName = 'BuyButton'; +export class BuyButton extends React.Component<BuyButtonProps> { + public static defaultProps = { + onClick: boundNoop, + onBuySuccess: boundNoop, + onBuyFailure: boundNoop, + }; + public render(): React.ReactNode { + const shouldDisableButton = _.isUndefined(this.props.buyQuote); + return ( + <Container padding="20px" width="100%"> + <Button width="100%" onClick={this._handleClick} isDisabled={shouldDisableButton}> + <Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px"> + {this.props.text} + </Text> + </Button> + </Container> + ); + } + private readonly _handleClick = async () => { + // The button is disabled when there is no buy quote anyway. + if (_.isUndefined(this.props.buyQuote)) { + return; + } + this.props.onClick(this.props.buyQuote); + try { + const txnHash = await assetBuyer.executeBuyQuoteAsync(this.props.buyQuote, { + // HACK: There is a calculation issue in asset-buyer. ETH is refunded anyway so just over-estimate. + ethAmount: this.props.buyQuote.worstCaseQuoteInfo.totalEthAmount.mul(2), + }); + await web3Wrapper.awaitTransactionSuccessAsync(txnHash); + } catch { + this.props.onBuyFailure(this.props.buyQuote); + } + this.props.onBuySuccess(this.props.buyQuote); + }; +} diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index be0414b8d..cde3862c7 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -1,11 +1,42 @@ +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as _ from 'lodash'; import * as React from 'react'; +import { ethDecimals } from '../constants'; import { SelectedAssetAmountInput } from '../containers/selected_asset_amount_input'; import { ColorOption } from '../style/theme'; import { Container, Flex, Text } from './ui'; -export interface InstantHeadingProps {} +export interface InstantHeadingProps { + selectedAssetAmount?: BigNumber; + totalEthBaseAmount?: BigNumber; + ethUsdPrice?: BigNumber; +} + +const displaytotalEthBaseAmount = ({ selectedAssetAmount, totalEthBaseAmount }: InstantHeadingProps): string => { + if (_.isUndefined(selectedAssetAmount)) { + return '0 ETH'; + } + if (_.isUndefined(totalEthBaseAmount)) { + return '...loading'; + } + const ethUnitAmount = Web3Wrapper.toUnitAmount(totalEthBaseAmount, ethDecimals); + const roundedAmount = ethUnitAmount.round(4); + return `${roundedAmount} ETH`; +}; + +const displayUsdAmount = ({ totalEthBaseAmount, selectedAssetAmount, ethUsdPrice }: InstantHeadingProps): string => { + if (_.isUndefined(selectedAssetAmount)) { + return '$0.00'; + } + if (_.isUndefined(totalEthBaseAmount) || _.isUndefined(ethUsdPrice)) { + return '...loading'; + } + const ethUnitAmount = Web3Wrapper.toUnitAmount(totalEthBaseAmount, ethDecimals); + return `$${ethUnitAmount.mul(ethUsdPrice).round(2)}`; +}; export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = props => ( <Container backgroundColor={ColorOption.primaryColor} padding="20px" width="100%" borderRadius="3px 3px 0px 0px"> @@ -26,18 +57,18 @@ export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = pro <SelectedAssetAmountInput fontSize="45px" /> <Container display="inline-block" marginLeft="10px"> <Text fontSize="45px" fontColor={ColorOption.white} textTransform="uppercase"> - rep + zrx </Text> </Container> </Container> <Flex direction="column" justify="space-between"> <Container marginBottom="5px"> <Text fontSize="16px" fontColor={ColorOption.white} fontWeight={500}> - 0 ETH + {displaytotalEthBaseAmount(props)} </Text> </Container> <Text fontSize="16px" fontColor={ColorOption.white} opacity={0.7}> - $0.00 + {displayUsdAmount(props)} </Text> </Flex> </Flex> diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx index 0e6230d1b..17ef737c9 100644 --- a/packages/instant/src/components/zero_ex_instant.tsx +++ b/packages/instant/src/components/zero_ex_instant.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { Provider } from 'react-redux'; +import { asyncData } from '../redux/async_data'; import { store } from '../redux/store'; import { fonts } from '../style/fonts'; import { theme, ThemeProvider } from '../style/theme'; @@ -8,6 +9,7 @@ import { theme, ThemeProvider } from '../style/theme'; import { ZeroExInstantContainer } from './zero_ex_instant_container'; fonts.include(); +asyncData.fetchAndDispatchToStore(); export interface ZeroExInstantProps {} diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 716227b51..4ff8b51bd 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -1,5 +1,8 @@ import * as React from 'react'; +import { SelectedAssetBuyButton } from '../containers/selected_asset_buy_button'; +import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; + import { ColorOption } from '../style/theme'; import { BuyButton } from './buy_button'; @@ -12,9 +15,9 @@ export interface ZeroExInstantContainerProps {} export const ZeroExInstantContainer: React.StatelessComponent<ZeroExInstantContainerProps> = props => ( <Container hasBoxShadow={true} width="350px" backgroundColor={ColorOption.white} borderRadius="3px"> <Flex direction="column" justify="flex-start"> - <InstantHeading /> + <SelectedAssetInstantHeading /> <OrderDetails /> - <BuyButton /> + <SelectedAssetBuyButton /> </Flex> </Container> ); |