aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant/src/components
diff options
context:
space:
mode:
authorSteve Klebanoff <steve.klebanoff@gmail.com>2018-12-08 03:14:55 +0800
committerSteve Klebanoff <steve.klebanoff@gmail.com>2018-12-12 06:37:45 +0800
commit5cbe04acab982ead39f7794547de0f045952a1b7 (patch)
tree5847cfb56df0c357997d5b1dfeb7811394a5da98 /packages/instant/src/components
parentd37680610b772d7bb585203047bef0af0439df0a (diff)
downloaddexon-0x-contracts-5cbe04acab982ead39f7794547de0f045952a1b7.tar.gz
dexon-0x-contracts-5cbe04acab982ead39f7794547de0f045952a1b7.tar.zst
dexon-0x-contracts-5cbe04acab982ead39f7794547de0f045952a1b7.zip
feat(instant): ETH/USD toggle
Diffstat (limited to 'packages/instant/src/components')
-rw-r--r--packages/instant/src/components/order_details.tsx196
1 files changed, 161 insertions, 35 deletions
diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx
index a8e0e2513..85761a5b9 100644
--- a/packages/instant/src/components/order_details.tsx
+++ b/packages/instant/src/components/order_details.tsx
@@ -6,63 +6,92 @@ import { oc } from 'ts-optchain';
import { BIG_NUMBER_ZERO } from '../constants';
import { ColorOption } from '../style/theme';
+import { BaseCurrency } from '../types';
+import { buyQuoteUtil } from '../util/buy_quote';
import { format } from '../util/format';
import { AmountPlaceholder } from './amount_placeholder';
import { Container } from './ui/container';
import { Flex } from './ui/flex';
-import { Text } from './ui/text';
+import { Text, TextProps } from './ui/text';
+
+interface BaseCurrenySwitchProps {
+ currencyName: string;
+ onClick: () => void;
+ isSelected: boolean;
+}
+const BaseCurrencySelector: React.StatelessComponent<BaseCurrenySwitchProps> = props => {
+ const textStyle: TextProps = { onClick: props.onClick, fontSize: '12px' };
+ if (props.isSelected) {
+ textStyle.fontColor = ColorOption.primaryColor;
+ textStyle.fontWeight = 700;
+ }
+ return <Text {...textStyle}>{props.currencyName}</Text>;
+};
export interface OrderDetailsProps {
buyQuoteInfo?: BuyQuoteInfo;
selectedAssetUnitAmount?: BigNumber;
ethUsdPrice?: BigNumber;
isLoading: boolean;
+ assetName?: string;
+ baseCurrency: BaseCurrency;
+ onBaseCurrencySwitchEth: () => void;
+ onBaseCurrencySwitchUsd: () => void;
}
export class OrderDetails extends React.Component<OrderDetailsProps> {
public render(): React.ReactNode {
const { buyQuoteInfo, ethUsdPrice, selectedAssetUnitAmount } = this.props;
- const buyQuoteAccessor = oc(buyQuoteInfo);
- const assetEthBaseUnitAmount = buyQuoteAccessor.assetEthAmount();
- const feeEthBaseUnitAmount = buyQuoteAccessor.feeEthAmount();
- const totalEthBaseUnitAmount = buyQuoteAccessor.totalEthAmount();
- const pricePerTokenEth =
- !_.isUndefined(assetEthBaseUnitAmount) &&
- !_.isUndefined(selectedAssetUnitAmount) &&
- !selectedAssetUnitAmount.eq(BIG_NUMBER_ZERO)
- ? assetEthBaseUnitAmount.div(selectedAssetUnitAmount).ceil()
- : undefined;
+ const weiAmounts = buyQuoteUtil.getWeiAmounts(selectedAssetUnitAmount, buyQuoteInfo);
+
+ const displayAmounts =
+ this.props.baseCurrency === BaseCurrency.USD
+ ? buyQuoteUtil.displayAmountsUsd(weiAmounts, ethUsdPrice)
+ : buyQuoteUtil.displayAmountsEth(weiAmounts, ethUsdPrice);
+
return (
<Container width="100%" flexGrow={1} padding="20px 20px 0px 20px">
<Container marginBottom="10px">
- <Text
- letterSpacing="1px"
- fontColor={ColorOption.primaryColor}
- fontWeight={600}
- textTransform="uppercase"
- fontSize="14px"
- >
- Order Details
- </Text>
+ <Flex justify="space-between">
+ <Text
+ letterSpacing="1px"
+ fontColor={ColorOption.primaryColor}
+ fontWeight={600}
+ textTransform="uppercase"
+ fontSize="14px"
+ >
+ Order Details
+ </Text>
+
+ <Container>
+ <BaseCurrencySelector
+ onClick={this.props.onBaseCurrencySwitchEth}
+ currencyName="ETH"
+ isSelected={this.props.baseCurrency === BaseCurrency.ETH}
+ />
+ <Container marginLeft="3px" marginRight="3px" display="inline">
+ <Text fontSize="12px">/</Text>
+ </Container>
+ <BaseCurrencySelector
+ onClick={this.props.onBaseCurrencySwitchUsd}
+ currencyName="USD"
+ isSelected={this.props.baseCurrency === BaseCurrency.USD}
+ />
+ </Container>
+ </Flex>
</Container>
- <EthAmountRow
- rowLabel="Token Price"
- ethAmount={pricePerTokenEth}
- ethUsdPrice={ethUsdPrice}
- isLoading={this.props.isLoading}
- />
- <EthAmountRow
- rowLabel="Fee"
- ethAmount={feeEthBaseUnitAmount}
- ethUsdPrice={ethUsdPrice}
+ <TokenAmountRow
+ numTokens={selectedAssetUnitAmount}
+ assetName={this.props.assetName}
+ displayPricePerToken={displayAmounts.pricePerToken}
+ displayTotalPrice={displayAmounts.assetTotal}
isLoading={this.props.isLoading}
/>
- <EthAmountRow
- rowLabel="Total Cost"
- ethAmount={totalEthBaseUnitAmount}
- ethUsdPrice={ethUsdPrice}
- shouldEmphasize={true}
+ <OrderDetailsRow labelText="Fee" value={displayAmounts.feeTotal} isLoading={this.props.isLoading} />
+ <TotalCostRow
+ displaySecondaryTotalCost={displayAmounts.secondaryGrandTotal}
+ displayPrimaryTotalCost={displayAmounts.primaryGrandTotal}
isLoading={this.props.isLoading}
/>
</Container>
@@ -79,6 +108,103 @@ export interface EthAmountRowProps {
isLoading: boolean;
}
+export interface OrderDetailsRowProps {
+ labelText: string;
+ isLabelBold?: boolean;
+ isLoading: boolean;
+ value?: React.ReactNode;
+}
+export class OrderDetailsRow extends React.Component<OrderDetailsRowProps, {}> {
+ public render(): React.ReactNode {
+ const { labelText, value, isLabelBold, isLoading } = this.props;
+ return (
+ <Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}>
+ <Flex justify="space-between">
+ <Text fontWeight={isLabelBold ? 700 : 400} fontColor={ColorOption.grey}>
+ {labelText}
+ </Text>
+ <Container>
+ {value || (
+ <Container opacity={0.5}>
+ <AmountPlaceholder color={ColorOption.lightGrey} isPulsating={isLoading} />
+ </Container>
+ )}
+ </Container>
+ </Flex>
+ </Container>
+ );
+ }
+}
+export interface TotalCostRowProps {
+ displayPrimaryTotalCost?: React.ReactNode;
+ displaySecondaryTotalCost?: React.ReactNode;
+ isLoading: boolean;
+}
+export class TotalCostRow extends React.Component<TotalCostRowProps, {}> {
+ public render(): React.ReactNode {
+ let value: React.ReactNode;
+ if (this.props.displayPrimaryTotalCost) {
+ const secondaryText = this.props.displaySecondaryTotalCost && (
+ <Container marginRight="3px" display="inline-block">
+ <Text fontColor={ColorOption.lightGrey}>({this.props.displaySecondaryTotalCost})</Text>
+ </Container>
+ );
+ value = (
+ <React.Fragment>
+ {secondaryText}
+ <Text fontWeight={700} fontColor={ColorOption.grey}>
+ {this.props.displayPrimaryTotalCost}
+ </Text>
+ </React.Fragment>
+ );
+ }
+
+ return (
+ <OrderDetailsRow isLoading={this.props.isLoading} isLabelBold={true} labelText="Total Cost" value={value} />
+ );
+ }
+}
+
+export interface TokenAmountRowProps {
+ assetName?: string;
+ displayPricePerToken?: React.ReactNode;
+ displayTotalPrice?: React.ReactNode;
+ isLoading: boolean;
+ numTokens?: BigNumber;
+}
+export class TokenAmountRow extends React.Component<TokenAmountRowProps> {
+ public static DEFAULT_TEXT: string = 'Token Price';
+ public render(): React.ReactNode {
+ return (
+ <OrderDetailsRow
+ isLoading={this.props.isLoading}
+ labelText={this._labelText()}
+ value={this.props.displayTotalPrice}
+ />
+ );
+ }
+ private _labelText(): string {
+ if (this.props.isLoading) {
+ return TokenAmountRow.DEFAULT_TEXT;
+ }
+ const { numTokens, displayPricePerToken, assetName } = this.props;
+ if (numTokens) {
+ let numTokensWithSymbol = numTokens.toString();
+
+ if (assetName) {
+ numTokensWithSymbol += ` ${assetName}`;
+ }
+
+ if (displayPricePerToken) {
+ numTokensWithSymbol += ` @ ${displayPricePerToken}`;
+ }
+ return numTokensWithSymbol;
+ }
+
+ return TokenAmountRow.DEFAULT_TEXT;
+ }
+}
+
export class EthAmountRow extends React.Component<EthAmountRowProps> {
public static defaultProps = {
shouldEmphasize: false,