diff options
Diffstat (limited to 'packages/instant')
7 files changed, 143 insertions, 42 deletions
diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index cde3862c7..951858695 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -6,6 +6,7 @@ import * as React from 'react'; import { ethDecimals } from '../constants'; import { SelectedAssetAmountInput } from '../containers/selected_asset_amount_input'; import { ColorOption } from '../style/theme'; +import { format } from '../util/format'; import { Container, Flex, Text } from './ui'; @@ -19,23 +20,14 @@ const displaytotalEthBaseAmount = ({ selectedAssetAmount, totalEthBaseAmount }: 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`; + return format.ethBaseAmount(totalEthBaseAmount, 4, '...loading'); }; 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)}`; + return format.ethBaseAmountInUsd(totalEthBaseAmount, ethUsdPrice, 2, '...loading'); }; export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = props => ( diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index dbf2c1f0b..78359898f 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -1,53 +1,88 @@ +import { BuyQuoteInfo } from '@0xproject/asset-buyer'; +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as _ from 'lodash'; import * as React from 'react'; +import { BIG_NUMBER_ZERO, ethDecimals } from '../constants'; + import { ColorOption } from '../style/theme'; +import { format } from '../util/format'; import { Container, Flex, Text } from './ui'; -export interface OrderDetailsProps {} - -export const OrderDetails: React.StatelessComponent<OrderDetailsProps> = props => ( - <Container padding="20px" width="100%"> - <Container marginBottom="10px"> - <Text - letterSpacing="1px" - fontColor={ColorOption.primaryColor} - fontWeight={600} - textTransform="uppercase" - fontSize="14px" - > - Order Details - </Text> - </Container> - <OrderDetailsRow name="Token Price" primaryValue=".013 ETH" secondaryValue="$24.32" /> - <OrderDetailsRow name="Fee" primaryValue=".005 ETH" secondaryValue="$1.04" /> - <OrderDetailsRow name="Total Cost" primaryValue="1.66 ETH" secondaryValue="$589.56" shouldEmphasize={true} /> - </Container> -); +export interface OrderDetailsProps { + buyQuoteInfo?: BuyQuoteInfo; + ethUsdPrice?: BigNumber; +} -OrderDetails.displayName = 'OrderDetails'; +export class OrderDetails extends React.Component<OrderDetailsProps> { + public render(): React.ReactNode { + const { buyQuoteInfo, ethUsdPrice } = this.props; + const ethAssetPrice = _.get(buyQuoteInfo, 'ethPerAssetPrice'); + const ethTokenFee = _.get(buyQuoteInfo, 'feeEthAmount'); + const totalEthAmount = _.get(buyQuoteInfo, 'totalEthAmount'); + return ( + <Container padding="20px" width="100%"> + <Container marginBottom="10px"> + <Text + letterSpacing="1px" + fontColor={ColorOption.primaryColor} + fontWeight={600} + textTransform="uppercase" + fontSize="14px" + > + Order Details + </Text> + </Container> + <OrderDetailsRow + name="Token Price" + ethAmount={ethAssetPrice} + ethUsdPrice={ethUsdPrice} + shouldConvertEthToUnitAmount={false} + /> + <OrderDetailsRow name="Fee" ethAmount={ethTokenFee} ethUsdPrice={ethUsdPrice} /> + <OrderDetailsRow + name="Total Cost" + ethAmount={totalEthAmount} + ethUsdPrice={ethUsdPrice} + shouldEmphasize={true} + /> + </Container> + ); + } +} export interface OrderDetailsRowProps { name: string; - primaryValue: string; - secondaryValue: string; + ethAmount?: BigNumber; + shouldConvertEthToUnitAmount?: boolean; + ethUsdPrice?: BigNumber; shouldEmphasize?: boolean; } -export const OrderDetailsRow: React.StatelessComponent<OrderDetailsRowProps> = props => { - const fontWeight = props.shouldEmphasize ? 700 : 400; +export const OrderDetailsRow: React.StatelessComponent<OrderDetailsRowProps> = ({ + name, + ethAmount, + shouldConvertEthToUnitAmount, + ethUsdPrice, + shouldEmphasize, +}) => { + const fontWeight = shouldEmphasize ? 700 : 400; + const usdFormatter = shouldConvertEthToUnitAmount ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd; + const ethFormatter = shouldConvertEthToUnitAmount ? format.ethBaseAmount : format.ethUnitAmount; return ( <Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}> <Flex justify="space-between"> <Text fontWeight={fontWeight} fontColor={ColorOption.grey}> - {props.name} + {name} </Text> <Container> <Container marginRight="3px" display="inline-block"> - <Text fontColor={ColorOption.lightGrey}>({props.secondaryValue}) </Text> + <Text fontColor={ColorOption.lightGrey}>({usdFormatter(ethAmount, ethUsdPrice)})</Text> </Container> <Text fontWeight={fontWeight} fontColor={ColorOption.grey}> - {props.primaryValue} + {ethFormatter(ethAmount)} </Text> </Container> </Flex> @@ -57,6 +92,7 @@ export const OrderDetailsRow: React.StatelessComponent<OrderDetailsRowProps> = p OrderDetailsRow.defaultProps = { shouldEmphasize: false, + shouldConvertEthToUnitAmount: true, }; OrderDetailsRow.displayName = 'OrderDetailsRow'; diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx index 4ff8b51bd..44f702aa2 100644 --- a/packages/instant/src/components/zero_ex_instant_container.tsx +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; +import { LatestBuyQuoteOrderDetails } from '../containers/latest_buy_quote_order_details'; import { SelectedAssetBuyButton } from '../containers/selected_asset_buy_button'; import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; @@ -7,7 +8,6 @@ import { ColorOption } from '../style/theme'; import { BuyButton } from './buy_button'; import { InstantHeading } from './instant_heading'; -import { OrderDetails } from './order_details'; import { Container, Flex } from './ui'; export interface ZeroExInstantContainerProps {} @@ -16,7 +16,7 @@ export const ZeroExInstantContainer: React.StatelessComponent<ZeroExInstantConta <Container hasBoxShadow={true} width="350px" backgroundColor={ColorOption.white} borderRadius="3px"> <Flex direction="column" justify="flex-start"> <SelectedAssetInstantHeading /> - <OrderDetails /> + <LatestBuyQuoteOrderDetails /> <SelectedAssetBuyButton /> </Flex> </Container> diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 397c9b07a..75afc474a 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -1,3 +1,5 @@ +import { BigNumber } from '@0xproject/utils'; +export const BIG_NUMBER_ZERO = new BigNumber(0); export const sraApiUrl = 'https://api.radarrelay.com/0x/v2/'; export const zrxContractAddress = '0xe41d2489571d322189246dafa5ebde1f4699f498'; export const zrxDecimals = 18; diff --git a/packages/instant/src/containers/latest_buy_quote_order_details.ts b/packages/instant/src/containers/latest_buy_quote_order_details.ts new file mode 100644 index 000000000..77d84289b --- /dev/null +++ b/packages/instant/src/containers/latest_buy_quote_order_details.ts @@ -0,0 +1,26 @@ +import { BuyQuoteInfo } from '@0xproject/asset-buyer'; +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as React from 'react'; +import { connect } from 'react-redux'; + +import { State } from '../redux/reducer'; + +import { OrderDetails } from '../components/order_details'; + +export interface LatestBuyQuoteOrderDetailsProps {} + +interface ConnectedState { + buyQuoteInfo?: BuyQuoteInfo; + ethUsdPrice?: BigNumber; +} + +const mapStateToProps = (state: State, _ownProps: LatestBuyQuoteOrderDetailsProps): ConnectedState => ({ + // use the worst case quote info + buyQuoteInfo: _.get(state, 'latestBuyQuote.worstCaseQuoteInfo'), + ethUsdPrice: state.ethUsdPrice, +}); + +export const LatestBuyQuoteOrderDetails: React.ComponentClass<LatestBuyQuoteOrderDetailsProps> = connect( + mapStateToProps, +)(OrderDetails); diff --git a/packages/instant/src/containers/selected_asset_buy_button.ts b/packages/instant/src/containers/selected_asset_buy_button.ts index f537294e4..678c7e445 100644 --- a/packages/instant/src/containers/selected_asset_buy_button.ts +++ b/packages/instant/src/containers/selected_asset_buy_button.ts @@ -9,7 +9,7 @@ import { Action, ActionTypes, AsyncProcessState } from '../types'; import { assetBuyer } from '../util/asset_buyer'; import { web3Wrapper } from '../util/web3_wrapper'; -import { BuyButton } from '../components/buy_button'; +import { BuyButton, BuyButtonProps } from '../components/buy_button'; export interface SelectedAssetBuyButtonProps {} diff --git a/packages/instant/src/util/format.ts b/packages/instant/src/util/format.ts new file mode 100644 index 000000000..de7eb62e6 --- /dev/null +++ b/packages/instant/src/util/format.ts @@ -0,0 +1,45 @@ +import { BigNumber } from '@0xproject/utils'; +import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import * as _ from 'lodash'; + +import { ethDecimals } from '../constants'; + +export const format = { + ethBaseAmount: (ethBaseAmount?: BigNumber, decimalPlaces: number = 4, defaultText: string = '0 ETH'): string => { + if (_.isUndefined(ethBaseAmount)) { + return defaultText; + } + const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseAmount, ethDecimals); + return format.ethUnitAmount(ethUnitAmount, decimalPlaces); + }, + ethUnitAmount: (ethUnitAmount?: BigNumber, decimalPlaces: number = 4, defaultText: string = '0 ETH'): string => { + if (_.isUndefined(ethUnitAmount)) { + return defaultText; + } + const roundedAmount = ethUnitAmount.round(decimalPlaces); + return `${roundedAmount} ETH`; + }, + ethBaseAmountInUsd: ( + ethBaseAmount?: BigNumber, + ethUsdPrice?: BigNumber, + decimalPlaces: number = 2, + defaultText: string = '$0.00', + ): string => { + if (_.isUndefined(ethBaseAmount) || _.isUndefined(ethUsdPrice)) { + return defaultText; + } + const ethUnitAmount = Web3Wrapper.toUnitAmount(ethBaseAmount, ethDecimals); + return format.ethUnitAmountInUsd(ethUnitAmount, ethUsdPrice, decimalPlaces); + }, + ethUnitAmountInUsd: ( + ethUnitAmount?: BigNumber, + ethUsdPrice?: BigNumber, + decimalPlaces: number = 2, + defaultText: string = '$0.00', + ): string => { + if (_.isUndefined(ethUnitAmount) || _.isUndefined(ethUsdPrice)) { + return defaultText; + } + return `$${ethUnitAmount.mul(ethUsdPrice).round(decimalPlaces)}`; + }, +}; |