diff options
author | Francesco Agosti <francesco.agosti93@gmail.com> | 2018-07-07 06:38:51 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-07 06:38:51 +0800 |
commit | 269b56b907f8af49e5d92bdcf3aedbc9af03e368 (patch) | |
tree | 8edcdaab384b8808f8f8520347e5cf6929f0c57e /packages/website | |
parent | e929fb4337b227bae55b1b8456b5035f7df5eb4f (diff) | |
parent | 60ebfcf36df3d2e4f15142823fb5821d8d65937e (diff) | |
download | dexon-sol-tools-269b56b907f8af49e5d92bdcf3aedbc9af03e368.tar dexon-sol-tools-269b56b907f8af49e5d92bdcf3aedbc9af03e368.tar.gz dexon-sol-tools-269b56b907f8af49e5d92bdcf3aedbc9af03e368.tar.bz2 dexon-sol-tools-269b56b907f8af49e5d92bdcf3aedbc9af03e368.tar.lz dexon-sol-tools-269b56b907f8af49e5d92bdcf3aedbc9af03e368.tar.xz dexon-sol-tools-269b56b907f8af49e5d92bdcf3aedbc9af03e368.tar.zst dexon-sol-tools-269b56b907f8af49e5d92bdcf3aedbc9af03e368.zip |
Merge pull request #838 from 0xProject/feature/website/portal-final-touches
Some final polish touches for portal!
Diffstat (limited to 'packages/website')
12 files changed, 165 insertions, 107 deletions
diff --git a/packages/website/public/images/unlock-mm.png b/packages/website/public/images/unlock-mm.png Binary files differnew file mode 100644 index 000000000..531c95dd2 --- /dev/null +++ b/packages/website/public/images/unlock-mm.png diff --git a/packages/website/ts/components/onboarding/add_eth_onboarding_step.tsx b/packages/website/ts/components/onboarding/add_eth_onboarding_step.tsx index bccdc0c18..ca71fcd50 100644 --- a/packages/website/ts/components/onboarding/add_eth_onboarding_step.tsx +++ b/packages/website/ts/components/onboarding/add_eth_onboarding_step.tsx @@ -1,10 +1,10 @@ import { BigNumber } from '@0xproject/utils'; import * as React from 'react'; +import { Balance } from 'ts/components/ui/balance'; import { Container } from 'ts/components/ui/container'; import { Image } from 'ts/components/ui/image'; import { Text } from 'ts/components/ui/text'; import { constants } from 'ts/utils/constants'; -import { utils } from 'ts/utils/utils'; export interface AddEthOnboardingStepProps { userEthBalanceInWei: BigNumber; @@ -15,13 +15,11 @@ export const AddEthOnboardingStep: React.StatelessComponent<AddEthOnboardingStep <div className="flex items-center flex-column"> <Text> Great! Looks like you already have{' '} - <b> - {utils.getFormattedAmount( - props.userEthBalanceInWei, - constants.DECIMAL_PLACES_ETH, - constants.ETHER_SYMBOL, - )}{' '} - </b> + <Balance + amount={props.userEthBalanceInWei} + decimals={constants.DECIMAL_PLACES_ETH} + symbol={constants.ETHER_SYMBOL} + />{' '} in your wallet. </Text> <Container marginTop="15px" marginBottom="15px"> diff --git a/packages/website/ts/components/onboarding/onboarding_card.tsx b/packages/website/ts/components/onboarding/onboarding_card.tsx index ba5b3d6ea..e1b0f304b 100644 --- a/packages/website/ts/components/onboarding/onboarding_card.tsx +++ b/packages/website/ts/components/onboarding/onboarding_card.tsx @@ -12,6 +12,7 @@ export type ContinueButtonDisplay = 'enabled' | 'disabled'; export interface OnboardingCardProps { title?: string; + shouldCenterTitle?: boolean; content: React.ReactNode; isLastStep: boolean; onClose: () => void; @@ -23,10 +24,13 @@ export interface OnboardingCardProps { shouldHideNextButton?: boolean; continueButtonText?: string; borderRadius?: string; + // Used for super-custom content. + shouldRemoveExtraSpacing?: boolean; } export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({ title, + shouldCenterTitle, content, continueButtonDisplay, continueButtonText, @@ -37,55 +41,75 @@ export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({ shouldHideBackButton, shouldHideNextButton, borderRadius, -}) => ( - <Island borderRadius={borderRadius}> - <Container paddingRight="30px" paddingLeft="30px" paddingTop="15px" paddingBottom="15px"> - <div className="flex flex-column"> - <div className="flex justify-between"> - <Title>{title}</Title> - <Container position="relative" bottom="20px" left="15px"> - <IconButton color={colors.grey} iconName="zmdi-close" onClick={onClose}> - Close - </IconButton> + shouldRemoveExtraSpacing, +}) => { + const padding = shouldRemoveExtraSpacing + ? {} + : { + paddingRight: '30px', + paddingLeft: '30px', + paddingTop: '15px', + paddingBottom: '15px', + }; + const closeIconPositioning = shouldRemoveExtraSpacing + ? { right: '15px', bottom: '3px' } + : { bottom: '20px', left: '15px' }; + return ( + <Island borderRadius={borderRadius}> + <Container {...padding}> + <div className="flex flex-column"> + <Container className="flex justify-between"> + <Container width="100%"> + <Title center={shouldCenterTitle}>{title}</Title> + </Container> + <Container position="relative" {...closeIconPositioning}> + <IconButton color={colors.grey} iconName="zmdi-close" onClick={onClose}> + Close + </IconButton> + </Container> </Container> + <Container marginBottom={shouldRemoveExtraSpacing ? undefined : '15px'}> + <Text>{content}</Text> + </Container> + {continueButtonDisplay && ( + <Button + isDisabled={continueButtonDisplay === 'disabled'} + onClick={!_.isUndefined(onContinueButtonClick) ? onContinueButtonClick : onClickNext} + fontColor={colors.white} + fontSize="15px" + backgroundColor={colors.mediumBlue} + > + {continueButtonText} + </Button> + )} + {!(shouldHideBackButton && shouldHideNextButton) && ( + <Container className="clearfix" marginTop="15px"> + <div className="left"> + {!shouldHideBackButton && ( + <Text fontColor={colors.grey} onClick={onClickBack}> + Back + </Text> + )} + </div> + <div className="right"> + {!shouldHideNextButton && ( + <Text fontColor={colors.grey} onClick={onClickNext}> + Skip + </Text> + )} + </div> + </Container> + )} </div> - <Container marginBottom="15px"> - <Text>{content}</Text> - </Container> - {continueButtonDisplay && ( - <Button - isDisabled={continueButtonDisplay === 'disabled'} - onClick={!_.isUndefined(onContinueButtonClick) ? onContinueButtonClick : onClickNext} - fontColor={colors.white} - fontSize="15px" - backgroundColor={colors.mediumBlue} - > - {continueButtonText} - </Button> - )} - <Container className="clearfix" marginTop="15px"> - <div className="left"> - {!shouldHideBackButton && ( - <Text fontColor={colors.grey} onClick={onClickBack}> - Back - </Text> - )} - </div> - <div className="right"> - {!shouldHideNextButton && ( - <Text fontColor={colors.grey} onClick={onClickNext}> - Skip - </Text> - )} - </div> - </Container> - </div> - </Container> - </Island> -); + </Container> + </Island> + ); +}; OnboardingCard.defaultProps = { continueButtonText: 'Continue', + shouldCenterTitle: false, + shouldRemoveExtraSpacing: false, }; OnboardingCard.displayName = 'OnboardingCard'; diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx index 46dc897bd..91d5f2476 100644 --- a/packages/website/ts/components/onboarding/onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx @@ -2,11 +2,14 @@ import * as React from 'react'; import { Placement, Popper, PopperChildrenProps } from 'react-popper'; import { OnboardingCard } from 'ts/components/onboarding/onboarding_card'; -import { ContinueButtonDisplay, OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip'; +import { + ContinueButtonDisplay, + OnboardingTooltip, + TooltipPointerDisplay, +} from 'ts/components/onboarding/onboarding_tooltip'; import { Animation } from 'ts/components/ui/animation'; import { Container } from 'ts/components/ui/container'; import { Overlay } from 'ts/components/ui/overlay'; -import { PointerDirection } from 'ts/components/ui/pointer'; import { zIndex } from 'ts/style/z_index'; export interface FixedPositionSettings { @@ -15,7 +18,7 @@ export interface FixedPositionSettings { bottom?: string; left?: string; right?: string; - pointerDirection?: PointerDirection; + tooltipPointerDisplay?: TooltipPointerDisplay; } export interface TargetPositionSettings { @@ -28,12 +31,15 @@ export interface Step { // Provide either a CSS selector, or fixed position settings. Only applies to desktop. position: TargetPositionSettings | FixedPositionSettings; title?: string; + shouldCenterTitle?: boolean; content: React.ReactNode; shouldHideBackButton?: boolean; shouldHideNextButton?: boolean; continueButtonDisplay?: ContinueButtonDisplay; continueButtonText?: string; onContinueButtonClick?: () => void; + // Only used for very custom steps. + shouldRemoveExtraSpacing?: boolean; } export interface OnboardingFlowProps { @@ -69,7 +75,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> { </Popper> ); } else if (currentStep.position.type === 'fixed') { - const { top, right, bottom, left, pointerDirection } = currentStep.position; + const { top, right, bottom, left, tooltipPointerDisplay } = currentStep.position; onboardingElement = ( <Container position="fixed" @@ -79,7 +85,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> { bottom={bottom} left={left} > - {this._renderToolTip(pointerDirection)} + {this._renderToolTip(tooltipPointerDisplay)} </Container> ); } @@ -103,7 +109,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> { </div> ); } - private _renderToolTip(pointerDirection?: PointerDirection): React.ReactNode { + private _renderToolTip(tooltipPointerDisplay?: TooltipPointerDisplay): React.ReactNode { const { steps, stepIndex } = this.props; const step = steps[stepIndex]; const isLastStep = steps.length - 1 === stepIndex; @@ -111,6 +117,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> { <Container marginLeft="30px" width="400px"> <OnboardingTooltip title={step.title} + shouldCenterTitle={step.shouldCenterTitle} content={step.content} isLastStep={isLastStep} shouldHideBackButton={step.shouldHideBackButton} @@ -121,7 +128,8 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> { continueButtonDisplay={step.continueButtonDisplay} continueButtonText={step.continueButtonText} onContinueButtonClick={step.onContinueButtonClick} - pointerDirection={pointerDirection} + pointerDisplay={tooltipPointerDisplay} + shouldRemoveExtraSpacing={step.shouldRemoveExtraSpacing} /> </Container> ); @@ -135,6 +143,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> { <Container position="relative" zIndex={1}> <OnboardingCard title={step.title} + shouldCenterTitle={step.shouldCenterTitle} content={step.content} isLastStep={isLastStep} shouldHideBackButton={step.shouldHideBackButton} @@ -146,6 +155,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> { continueButtonText={step.continueButtonText} onContinueButtonClick={step.onContinueButtonClick} borderRadius="10px 10px 0px 0px" + shouldRemoveExtraSpacing={step.shouldRemoveExtraSpacing} /> </Container> ); diff --git a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx index d8065625d..15d47908d 100644 --- a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx +++ b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx @@ -4,22 +4,27 @@ import { OnboardingCard, OnboardingCardProps } from 'ts/components/onboarding/on import { Pointer, PointerDirection } from 'ts/components/ui/pointer'; export type ContinueButtonDisplay = 'enabled' | 'disabled'; +export type TooltipPointerDisplay = PointerDirection | 'none'; export interface OnboardingTooltipProps extends OnboardingCardProps { className?: string; - pointerDirection?: PointerDirection; + pointerDisplay?: TooltipPointerDisplay; } export const OnboardingTooltip: React.StatelessComponent<OnboardingTooltipProps> = props => { - const { pointerDirection, className, ...cardProps } = props; + const { pointerDisplay, className, ...cardProps } = props; + const card = <OnboardingCard {...cardProps} />; + if (pointerDisplay === 'none') { + return card; + } return ( - <Pointer className={className} direction={pointerDirection}> + <Pointer className={className} direction={pointerDisplay}> <OnboardingCard {...cardProps} /> </Pointer> ); }; OnboardingTooltip.defaultProps = { - pointerDirection: 'left', + pointerDisplay: 'left', }; OnboardingTooltip.displayName = 'OnboardingTooltip'; diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 503f2163d..20a8f0a32 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -91,9 +91,9 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp }; const underMetamaskExtension: FixedPositionSettings = { type: 'fixed', - top: '30px', + top: '10px', right: '10px', - pointerDirection: 'top', + tooltipPointerDisplay: 'none', }; const steps: Step[] = [ { @@ -105,10 +105,12 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp }, { position: underMetamaskExtension, - title: '0x Ecosystem Setup', + title: 'Please Unlock Metamask...', content: <UnlockWalletOnboardingStep />, shouldHideBackButton: true, shouldHideNextButton: true, + shouldCenterTitle: true, + shouldRemoveExtraSpacing: true, }, { position: nextToWalletPosition, @@ -140,13 +142,7 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp { position: nextToWalletPosition, title: 'Step 2: Wrap ETH', - content: ( - <WrapEthOnboardingStep3 - formattedWethBalanceIfExists={ - this._userHasVisibleWeth() ? this._getFormattedWethBalance() : undefined - } - /> - ), + content: <WrapEthOnboardingStep3 wethAmount={this._getWethBalance()} />, continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled', }, { @@ -187,11 +183,6 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp const ethTokenState = this.props.trackedTokenStateByAddress[ethToken.address]; return ethTokenState.balance; } - private _getFormattedWethBalance(): string { - const ethToken = utils.getEthToken(this.props.tokenByAddress); - const ethTokenState = this.props.trackedTokenStateByAddress[ethToken.address]; - return utils.getFormattedAmountFromToken(ethToken, ethTokenState); - } private _userHasVisibleWeth(): boolean { return this._getWethBalance() > new BigNumber(0); } diff --git a/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx b/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx index 4ed7137d4..358141520 100644 --- a/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx +++ b/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx @@ -1,16 +1,8 @@ import * as React from 'react'; -import { Container } from 'ts/components/ui/container'; -import { Text } from 'ts/components/ui/text'; +import { Image } from 'ts/components/ui/image'; export interface UnlockWalletOnboardingStepProps {} export const UnlockWalletOnboardingStep: React.StatelessComponent<UnlockWalletOnboardingStepProps> = () => ( - <div className="flex items-center flex-column"> - <div className="flex items-center flex-column"> - <Container marginTop="15px" marginBottom="15px"> - <img src="/images/metamask_icon.png" height="50px" width="50px" /> - </Container> - <Text center={true}>Unlock your MetaMask extension to get started.</Text> - </div> - </div> + <Image src="/images/unlock-mm.png" /> ); diff --git a/packages/website/ts/components/onboarding/wrap_eth_onboarding_step.tsx b/packages/website/ts/components/onboarding/wrap_eth_onboarding_step.tsx index 4d336c80f..e4332de75 100644 --- a/packages/website/ts/components/onboarding/wrap_eth_onboarding_step.tsx +++ b/packages/website/ts/components/onboarding/wrap_eth_onboarding_step.tsx @@ -1,8 +1,11 @@ import { colors } from '@0xproject/react-shared'; +import { BigNumber } from '@0xproject/utils'; import * as React from 'react'; +import { Balance } from 'ts/components/ui/balance'; import { Container } from 'ts/components/ui/container'; import { IconButton } from 'ts/components/ui/icon_button'; import { Text } from 'ts/components/ui/text'; +import { constants } from 'ts/utils/constants'; export interface WrapEthOnboardingStep1Props {} @@ -51,16 +54,20 @@ export const WrapEthOnboardingStep2: React.StatelessComponent<WrapEthOnboardingS ); export interface WrapEthOnboardingStep3Props { - formattedWethBalanceIfExists?: string; + wethAmount: BigNumber; } -export const WrapEthOnboardingStep3: React.StatelessComponent<WrapEthOnboardingStep3Props> = ({ - formattedWethBalanceIfExists, -}) => ( +export const WrapEthOnboardingStep3: React.StatelessComponent<WrapEthOnboardingStep3Props> = ({ wethAmount }) => ( <div className="flex items-center flex-column"> <Text> - You have <b>{formattedWethBalanceIfExists || '0 WETH'}</b> in your wallet. - {formattedWethBalanceIfExists && ' Great!'} + You have{' '} + <Balance + amount={wethAmount} + decimals={constants.DECIMAL_PLACES_ETH} + symbol={constants.ETHER_TOKEN_SYMBOL} + />{' '} + in your wallet. + {wethAmount.gt(0) && ' Great!'} </Text> <Container width="100%" marginTop="25px" marginBottom="15px" className="flex justify-center"> <div className="flex flex-column items-center"> diff --git a/packages/website/ts/components/ui/balance.tsx b/packages/website/ts/components/ui/balance.tsx new file mode 100644 index 000000000..9e5a256b6 --- /dev/null +++ b/packages/website/ts/components/ui/balance.tsx @@ -0,0 +1,27 @@ +import { BigNumber } from '@0xproject/utils'; +import * as React from 'react'; +import { Container } from 'ts/components/ui/container'; +import { Text } from 'ts/components/ui/text'; +import { utils } from 'ts/utils/utils'; + +export interface BalanceProps { + amount: BigNumber; + decimals: number; + symbol: string; +} + +export const Balance: React.StatelessComponent<BalanceProps> = ({ amount, decimals, symbol }) => { + const formattedAmout = utils.getFormattedAmount(amount, decimals); + return ( + <span> + <Text Tag="span" fontSize="16px" fontWeight="700" lineHeight="1em"> + {formattedAmout} + </Text> + <Container marginLeft="0.3em" Tag="span"> + <Text Tag="span" fontSize="12px" fontWeight="700" lineHeight="1em"> + {symbol} + </Text> + </Container> + </span> + ); +}; diff --git a/packages/website/ts/components/ui/container.tsx b/packages/website/ts/components/ui/container.tsx index edbf8814b..427cc6cc7 100644 --- a/packages/website/ts/components/ui/container.tsx +++ b/packages/website/ts/components/ui/container.tsx @@ -2,6 +2,8 @@ import * as React from 'react'; type StringOrNum = string | number; +export type ContainerTag = 'div' | 'span'; + export interface ContainerProps { marginTop?: StringOrNum; marginBottom?: StringOrNum; @@ -28,15 +30,21 @@ export interface ContainerProps { right?: string; bottom?: string; zIndex?: number; + Tag?: ContainerTag; } -export const Container: React.StatelessComponent<ContainerProps> = ({ children, className, isHidden, ...style }) => { +export const Container: React.StatelessComponent<ContainerProps> = props => { + const { children, className, Tag, isHidden, ...style } = props; const visibility = isHidden ? 'hidden' : undefined; return ( - <div style={{ ...style, visibility }} className={className}> + <Tag style={{ ...style, visibility }} className={className}> {children} - </div> + </Tag> ); }; +Container.defaultProps = { + Tag: 'div', +}; + Container.displayName = 'Container'; diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 1c7dafca0..6c1c495d7 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -8,6 +8,7 @@ import firstBy = require('thenby'); import { Blockchain } from 'ts/blockchain'; import { AccountConnection } from 'ts/components/ui/account_connection'; +import { Balance } from 'ts/components/ui/balance'; import { Container } from 'ts/components/ui/container'; import { DropDown, DropdownMouseEvent } from 'ts/components/ui/drop_down'; import { IconButton } from 'ts/components/ui/icon_button'; @@ -269,7 +270,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { position: 'relative', overflowY: this.state.isHoveringSidebar ? 'scroll' : 'hidden', marginRight: this.state.isHoveringSidebar ? 0 : 4, - // TODO: make this completely responsive + minHeight: '250px', maxHeight: !utils.isMobileWidth(this.props.screenWidth) ? 'calc(90vh - 300px)' : undefined, }; } @@ -436,12 +437,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> { </PlaceHolder> ); } else { - const result = utils.getFormattedAmount(amount, decimals, symbol); - return ( - <Text fontSize="16px" fontWeight="bold" lineHeight="1em"> - {result} - </Text> - ); + return <Balance amount={amount} decimals={decimals} symbol={symbol} />; } } private _renderValue( diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts index d50e9c619..6af7f5613 100644 --- a/packages/website/ts/utils/utils.ts +++ b/packages/website/ts/utils/utils.ts @@ -381,9 +381,9 @@ export const utils = { return trackedTokens; }, getFormattedAmountFromToken(token: Token, tokenState: TokenState): string { - return utils.getFormattedAmount(tokenState.balance, token.decimals, token.symbol); + return utils.getFormattedAmount(tokenState.balance, token.decimals); }, - getFormattedAmount(amount: BigNumber, decimals: number, symbol: string): string { + getFormattedAmount(amount: BigNumber, decimals: number): string { const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals); // if the unit amount is less than 1, show the natural number of decimal places with a max of 4 // if the unit amount is greater than or equal to 1, show only 2 decimal places @@ -392,7 +392,7 @@ export const utils = { : 2; const format = `0,0.${_.repeat('0', precision)}`; const formattedAmount = numeral(unitAmount).format(format); - return `${formattedAmount} ${symbol}`; + return formattedAmount; }, getUsdValueFormattedAmount(amount: BigNumber, decimals: number, price: BigNumber): string { const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals); |