aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website
diff options
context:
space:
mode:
authorFabio Berger <me@fabioberger.com>2018-06-22 16:39:07 +0800
committerFabio Berger <me@fabioberger.com>2018-06-22 16:39:07 +0800
commit3ce295a2af17feef6cd4e3140196501805493719 (patch)
tree964df912ce86d98a211f81f3d6159d797a37c3b3 /packages/website
parenta30107ab867964d371b2d5fc6791c7b1963f1c7b (diff)
parent0515c6acded983bba05320895ea2c2891f37055c (diff)
downloaddexon-sol-tools-3ce295a2af17feef6cd4e3140196501805493719.tar
dexon-sol-tools-3ce295a2af17feef6cd4e3140196501805493719.tar.gz
dexon-sol-tools-3ce295a2af17feef6cd4e3140196501805493719.tar.bz2
dexon-sol-tools-3ce295a2af17feef6cd4e3140196501805493719.tar.lz
dexon-sol-tools-3ce295a2af17feef6cd4e3140196501805493719.tar.xz
dexon-sol-tools-3ce295a2af17feef6cd4e3140196501805493719.tar.zst
dexon-sol-tools-3ce295a2af17feef6cd4e3140196501805493719.zip
Merge branch 'v2-prototype' into refactor/check-revert-reasons
* v2-prototype: (40 commits) Use make-promises-safe as a preloader instead of manually importing Updated compiler runs to be 1,000,000 Add event to setSignatureValidatorApproval, rename signer => signerAddress accross all contracts Add senderAddress to Fill and Cancel logs, add comments to events and types Fix Island component Add missing image assets for Chris and Mel Fix some bugs in sol-cov Remove unreachable PreSigned check Fix linting Buttons look hella disabled now Remove border radius, fix width issue for unlock step Add Chris and Mel to about page fix linter issues only call getLocationByOffset if source if defined Set settleOrder and settleMatchedOrders to private Prevent prettier issue Support mobile friendly onboarding flows Removed MixinSettlement. Moved `settleOrder` into `MixinExchangeCore` and `settleMatchedOrders` into `MixinMatchOrders` Migrations after rebasing Linter ...
Diffstat (limited to 'packages/website')
-rw-r--r--packages/website/public/images/team/chris.pngbin0 -> 96388 bytes
-rw-r--r--packages/website/public/images/team/mel.pngbin0 -> 110351 bytes
-rw-r--r--packages/website/ts/components/generate_order/asset_picker.tsx4
-rw-r--r--packages/website/ts/components/onboarding/onboarding_card.tsx84
-rw-r--r--packages/website/ts/components/onboarding/onboarding_flow.tsx52
-rw-r--r--packages/website/ts/components/onboarding/onboarding_tooltip.tsx87
-rw-r--r--packages/website/ts/components/onboarding/portal_onboarding_flow.tsx5
-rw-r--r--packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx2
-rw-r--r--packages/website/ts/components/portal/back_button.tsx7
-rw-r--r--packages/website/ts/components/portal/portal.tsx115
-rw-r--r--packages/website/ts/components/top_bar/provider_display.tsx7
-rw-r--r--packages/website/ts/components/ui/animation.tsx32
-rw-r--r--packages/website/ts/components/ui/button.tsx16
-rw-r--r--packages/website/ts/components/ui/container.tsx1
-rw-r--r--packages/website/ts/components/ui/identicon.tsx2
-rw-r--r--packages/website/ts/components/ui/island.tsx27
-rw-r--r--packages/website/ts/components/wallet/wallet.tsx4
-rw-r--r--packages/website/ts/containers/portal_onboarding_flow.ts4
-rw-r--r--packages/website/ts/pages/about/about.tsx21
-rw-r--r--packages/website/ts/pages/about/profile.tsx2
-rw-r--r--packages/website/ts/style/colors.ts2
21 files changed, 301 insertions, 173 deletions
diff --git a/packages/website/public/images/team/chris.png b/packages/website/public/images/team/chris.png
new file mode 100644
index 000000000..242a2813f
--- /dev/null
+++ b/packages/website/public/images/team/chris.png
Binary files differ
diff --git a/packages/website/public/images/team/mel.png b/packages/website/public/images/team/mel.png
new file mode 100644
index 000000000..52d779ad2
--- /dev/null
+++ b/packages/website/public/images/team/mel.png
Binary files differ
diff --git a/packages/website/ts/components/generate_order/asset_picker.tsx b/packages/website/ts/components/generate_order/asset_picker.tsx
index d7cc554c4..b43ac1f2e 100644
--- a/packages/website/ts/components/generate_order/asset_picker.tsx
+++ b/packages/website/ts/components/generate_order/asset_picker.tsx
@@ -151,12 +151,12 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt
height: TILE_DIMENSION,
...tileStyles,
}}
- className="p2 mx-auto"
+ className="p2 flex flex-column items-center"
onClick={this._onChooseToken.bind(this, address)}
onMouseEnter={this._onToggleHover.bind(this, address, true)}
onMouseLeave={this._onToggleHover.bind(this, address, false)}
>
- <div className="p1 center">
+ <div className="p1">
<TokenIcon token={token} diameter={TOKEN_ICON_DIMENSION} />
</div>
<div className="center">{token.name}</div>
diff --git a/packages/website/ts/components/onboarding/onboarding_card.tsx b/packages/website/ts/components/onboarding/onboarding_card.tsx
new file mode 100644
index 000000000..bc83b8034
--- /dev/null
+++ b/packages/website/ts/components/onboarding/onboarding_card.tsx
@@ -0,0 +1,84 @@
+import { colors } from '@0xproject/react-shared';
+import * as React from 'react';
+
+import { Button } from 'ts/components/ui/button';
+import { Container } from 'ts/components/ui/container';
+import { IconButton } from 'ts/components/ui/icon_button';
+import { Island } from 'ts/components/ui/island';
+import { Text, Title } from 'ts/components/ui/text';
+
+export type ContinueButtonDisplay = 'enabled' | 'disabled';
+
+export interface OnboardingCardProps {
+ title?: string;
+ content: React.ReactNode;
+ isLastStep: boolean;
+ onClose: () => void;
+ onClickNext: () => void;
+ onClickBack: () => void;
+ continueButtonDisplay?: ContinueButtonDisplay;
+ shouldHideBackButton?: boolean;
+ shouldHideNextButton?: boolean;
+ continueButtonText?: string;
+ borderRadius?: string;
+}
+
+export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({
+ title,
+ content,
+ continueButtonDisplay,
+ continueButtonText,
+ onClickNext,
+ onClickBack,
+ onClose,
+ shouldHideBackButton,
+ shouldHideNextButton,
+ borderRadius,
+}) => (
+ <Island borderRadius={borderRadius}>
+ <Container paddingRight="30px" paddingLeft="30px" maxWidth={350} 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>
+ </Container>
+ </div>
+ <Container marginBottom="15px">
+ <Text>{content}</Text>
+ </Container>
+ {continueButtonDisplay && (
+ <Button
+ isDisabled={continueButtonDisplay === 'disabled'}
+ onClick={onClickNext}
+ fontColor={colors.white}
+ fontSize="15px"
+ backgroundColor={colors.mediumBlue}
+ >
+ {continueButtonText}
+ </Button>
+ )}
+ <Container className="flex justify-between" marginTop="15px">
+ {!shouldHideBackButton && (
+ <Text fontColor={colors.grey} onClick={onClickBack}>
+ Back
+ </Text>
+ )}
+ {!shouldHideNextButton && (
+ <Text fontColor={colors.grey} onClick={onClickNext}>
+ Skip
+ </Text>
+ )}
+ </Container>
+ </div>
+ </Container>
+ </Island>
+);
+
+OnboardingCard.defaultProps = {
+ continueButtonText: 'Continue',
+};
+
+OnboardingCard.displayName = 'OnboardingCard';
diff --git a/packages/website/ts/components/onboarding/onboarding_flow.tsx b/packages/website/ts/components/onboarding/onboarding_flow.tsx
index 34aeace82..331899469 100644
--- a/packages/website/ts/components/onboarding/onboarding_flow.tsx
+++ b/packages/website/ts/components/onboarding/onboarding_flow.tsx
@@ -1,7 +1,9 @@
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 { Animation } from 'ts/components/ui/animation';
import { Container } from 'ts/components/ui/container';
import { Overlay } from 'ts/components/ui/overlay';
@@ -22,26 +24,37 @@ export interface OnboardingFlowProps {
isRunning: boolean;
onClose: () => void;
updateOnboardingStep: (stepIndex: number) => void;
+ disableOverlay?: boolean;
+ isMobile: boolean;
}
export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
+ public static defaultProps = {
+ disableOverlay: false,
+ isMobile: false,
+ };
public render(): React.ReactNode {
if (!this.props.isRunning) {
return null;
}
- return (
- <Overlay>
+ let onboardingElement = null;
+ if (this.props.isMobile) {
+ onboardingElement = <Animation type="easeUpFromBottom">{this._renderOnboardignCard()}</Animation>;
+ } else {
+ onboardingElement = (
<Popper referenceElement={this._getElementForStep()} placement={this._getCurrentStep().placement}>
{this._renderPopperChildren.bind(this)}
</Popper>
- </Overlay>
- );
+ );
+ }
+ if (this.props.disableOverlay) {
+ return onboardingElement;
+ }
+ return <Overlay>{onboardingElement}</Overlay>;
}
-
private _getElementForStep(): Element {
return document.querySelector(this._getCurrentStep().target);
}
-
private _renderPopperChildren(props: PopperChildrenProps): React.ReactNode {
return (
<div ref={props.ref} style={props.style} data-placement={props.placement}>
@@ -49,13 +62,12 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
</div>
);
}
-
private _renderToolTip(): React.ReactNode {
const { steps, stepIndex } = this.props;
const step = steps[stepIndex];
const isLastStep = steps.length - 1 === stepIndex;
return (
- <Container marginLeft="30px">
+ <Container marginLeft="30px" maxWidth={350}>
<OnboardingTooltip
title={step.title}
content={step.content}
@@ -72,10 +84,31 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
);
}
+ private _renderOnboardignCard(): React.ReactNode {
+ const { steps, stepIndex } = this.props;
+ const step = steps[stepIndex];
+ const isLastStep = steps.length - 1 === stepIndex;
+ return (
+ <Container position="relative" zIndex={1} maxWidth="100vw">
+ <OnboardingCard
+ title={step.title}
+ content={step.content}
+ isLastStep={isLastStep}
+ shouldHideBackButton={step.shouldHideBackButton}
+ shouldHideNextButton={step.shouldHideNextButton}
+ onClose={this.props.onClose}
+ onClickNext={this._goToNextStep.bind(this)}
+ onClickBack={this._goToPrevStep.bind(this)}
+ continueButtonDisplay={step.continueButtonDisplay}
+ continueButtonText={step.continueButtonText}
+ borderRadius="10px 10px 0px 0px"
+ />
+ </Container>
+ );
+ }
private _getCurrentStep(): Step {
return this.props.steps[this.props.stepIndex];
}
-
private _goToNextStep(): void {
const nextStep = this.props.stepIndex + 1;
if (nextStep < this.props.steps.length) {
@@ -84,7 +117,6 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
this.props.onClose();
}
}
-
private _goToPrevStep(): void {
const nextStep = this.props.stepIndex - 1;
if (nextStep >= 0) {
diff --git a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx
index 45851b4de..d8065625d 100644
--- a/packages/website/ts/components/onboarding/onboarding_tooltip.tsx
+++ b/packages/website/ts/components/onboarding/onboarding_tooltip.tsx
@@ -1,90 +1,25 @@
-import { colors } from '@0xproject/react-shared';
import * as React from 'react';
-import { Button } from 'ts/components/ui/button';
-import { Container } from 'ts/components/ui/container';
-import { IconButton } from 'ts/components/ui/icon_button';
-import { Island } from 'ts/components/ui/island';
+import { OnboardingCard, OnboardingCardProps } from 'ts/components/onboarding/onboarding_card';
import { Pointer, PointerDirection } from 'ts/components/ui/pointer';
-import { Text, Title } from 'ts/components/ui/text';
export type ContinueButtonDisplay = 'enabled' | 'disabled';
-export interface OnboardingTooltipProps {
- title?: string;
- content: React.ReactNode;
- isLastStep: boolean;
- onClose: () => void;
- onClickNext: () => void;
- onClickBack: () => void;
- continueButtonDisplay?: ContinueButtonDisplay;
- shouldHideBackButton?: boolean;
- shouldHideNextButton?: boolean;
- pointerDirection?: PointerDirection;
- continueButtonText?: string;
+export interface OnboardingTooltipProps extends OnboardingCardProps {
className?: string;
+ pointerDirection?: PointerDirection;
}
-export const OnboardingTooltip: React.StatelessComponent<OnboardingTooltipProps> = ({
- title,
- content,
- continueButtonDisplay,
- continueButtonText,
- onClickNext,
- onClickBack,
- onClose,
- shouldHideBackButton,
- shouldHideNextButton,
- pointerDirection,
- className,
-}) => (
- <Pointer className={className} direction={pointerDirection}>
- <Island>
- <Container paddingRight="30px" paddingLeft="30px" maxWidth={350} 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>
- </Container>
- </div>
- <Container marginBottom="15px">
- <Text>{content}</Text>
- </Container>
- {continueButtonDisplay && (
- <Button
- isDisabled={continueButtonDisplay === 'disabled'}
- onClick={onClickNext}
- fontColor={colors.white}
- fontSize="15px"
- backgroundColor={colors.mediumBlue}
- >
- {continueButtonText}
- </Button>
- )}
- <Container className="flex justify-between" marginTop="15px">
- {!shouldHideBackButton && (
- <Text fontColor={colors.grey} onClick={onClickBack}>
- Back
- </Text>
- )}
- {!shouldHideNextButton && (
- <Text fontColor={colors.grey} onClick={onClickNext}>
- Skip
- </Text>
- )}
- </Container>
- </div>
- </Container>
- </Island>
- </Pointer>
-);
-
+export const OnboardingTooltip: React.StatelessComponent<OnboardingTooltipProps> = props => {
+ const { pointerDirection, className, ...cardProps } = props;
+ return (
+ <Pointer className={className} direction={pointerDirection}>
+ <OnboardingCard {...cardProps} />
+ </Pointer>
+ );
+};
OnboardingTooltip.defaultProps = {
pointerDirection: 'left',
- continueButtonText: 'Continue',
};
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 7e40192f6..10d4af30e 100644
--- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx
+++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx
@@ -14,7 +14,7 @@ import { SetAllowancesOnboardingStep } from 'ts/components/onboarding/set_allowa
import { UnlockWalletOnboardingStep } from 'ts/components/onboarding/unlock_wallet_onboarding_step';
import { WrapEthOnboardingStep } from 'ts/components/onboarding/wrap_eth_onboarding_step';
import { AllowanceToggle } from 'ts/containers/inputs/allowance_toggle';
-import { ProviderType, Token, TokenByAddress, TokenStateByAddress } from 'ts/types';
+import { ProviderType, ScreenWidths, Token, TokenByAddress, TokenStateByAddress } from 'ts/types';
import { analytics } from 'ts/utils/analytics';
import { utils } from 'ts/utils/utils';
@@ -34,6 +34,7 @@ export interface PortalOnboardingFlowProps extends RouteComponentProps<any> {
updateIsRunning: (isRunning: boolean) => void;
updateOnboardingStep: (stepIndex: number) => void;
refetchTokenStateAsync: (tokenAddress: string) => Promise<void>;
+ screenWidth: ScreenWidths;
}
class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProps> {
@@ -57,6 +58,8 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
isRunning={this.props.isRunning}
onClose={this._closeOnboarding.bind(this)}
updateOnboardingStep={this._updateOnboardingStep.bind(this)}
+ disableOverlay={this.props.screenWidth === ScreenWidths.Sm}
+ isMobile={this.props.screenWidth === ScreenWidths.Sm}
/>
);
}
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 6e6a74a06..0039aa545 100644
--- a/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx
+++ b/packages/website/ts/components/onboarding/unlock_wallet_onboarding_step.tsx
@@ -10,7 +10,7 @@ export const UnlockWalletOnboardingStep: React.StatelessComponent<UnlockWalletOn
<Container marginTop="15px" marginBottom="15px">
<img src="/images/metamask_icon.png" height="50px" width="50px" />
</Container>
- <Text>Unlock your metamask extension to begin.</Text>
+ <Text center={true}>Unlock your metamask extension to get started.</Text>
</div>
</div>
);
diff --git a/packages/website/ts/components/portal/back_button.tsx b/packages/website/ts/components/portal/back_button.tsx
index 2d0bbefc3..ca35abc2b 100644
--- a/packages/website/ts/components/portal/back_button.tsx
+++ b/packages/website/ts/components/portal/back_button.tsx
@@ -2,6 +2,7 @@ import { Styles } from '@0xproject/react-shared';
import * as React from 'react';
import { Link } from 'react-router-dom';
+import { Island } from 'ts/components/ui/island';
import { colors } from 'ts/style/colors';
export interface BackButtonProps {
@@ -15,9 +16,7 @@ const styles: Styles = {
backButton: {
height: BACK_BUTTON_HEIGHT,
paddingTop: 10,
- backgroundColor: colors.white,
borderRadius: BACK_BUTTON_HEIGHT,
- boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`,
},
backButtonIcon: {
color: colors.mediumBlue,
@@ -29,14 +28,14 @@ export const BackButton = (props: BackButtonProps) => {
return (
<div style={{ height: 65, paddingTop: 25 }}>
<Link to={props.to} style={{ textDecoration: 'none' }}>
- <div className="flex right" style={styles.backButton}>
+ <Island className="flex right" style={styles.backButton}>
<div style={{ marginLeft: 12 }}>
<i style={styles.backButtonIcon} className={`zmdi zmdi-arrow-left`} />
</div>
<div style={{ marginLeft: 12, marginRight: 12 }}>
<div style={{ fontSize: 16, color: colors.lightGrey }}>{props.labelText}</div>
</div>
- </div>
+ </Island>
</Link>
</div>
);
diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index 67314678b..11b3b43f4 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -246,11 +246,6 @@ export class Portal extends React.Component<PortalProps, PortalState> {
: TokenVisibility.TRACKED;
return (
<div style={styles.root}>
- <PortalOnboardingFlow
- blockchain={this._blockchain}
- trackedTokenStateByAddress={this.state.trackedTokenStateByAddress}
- refetchTokenStateAsync={this._refetchTokenStateAsync.bind(this)}
- />
<DocumentTitle title="0x Portal DApp" />
<TopBar
userAddress={this.props.userAddress}
@@ -307,6 +302,11 @@ export class Portal extends React.Component<PortalProps, PortalState> {
tokenVisibility={tokenVisibility}
/>
</div>
+ <PortalOnboardingFlow
+ blockchain={this._blockchain}
+ trackedTokenStateByAddress={this.state.trackedTokenStateByAddress}
+ refetchTokenStateAsync={this._refetchTokenStateAsync.bind(this)}
+ />
</div>
);
}
@@ -340,62 +340,77 @@ export class Portal extends React.Component<PortalProps, PortalState> {
);
}
private _renderWallet(): React.ReactNode {
+ const startOnboarding = this._renderStartOnboarding();
+ const isMobile = this.props.screenWidth === ScreenWidths.Sm;
+ // We need room to scroll down for mobile onboarding
+ const marginBottom = isMobile ? '200px' : '15px';
return (
<div>
- <Wallet
- style={this.props.isPortalOnboardingShowing ? { zIndex: zIndex.aboveOverlay } : undefined}
- userAddress={this.props.userAddress}
- networkId={this.props.networkId}
- blockchain={this._blockchain}
- blockchainIsLoaded={this.props.blockchainIsLoaded}
- blockchainErr={this.props.blockchainErr}
- dispatcher={this.props.dispatcher}
- tokenByAddress={this.props.tokenByAddress}
- trackedTokens={this._getCurrentTrackedTokens()}
- userEtherBalanceInWei={this.props.userEtherBalanceInWei}
- lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
- injectedProviderName={this.props.injectedProviderName}
- providerType={this.props.providerType}
- screenWidth={this.props.screenWidth}
- location={this.props.location}
- trackedTokenStateByAddress={this.state.trackedTokenStateByAddress}
- onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
- onAddToken={this._onAddToken.bind(this)}
- onRemoveToken={this._onRemoveToken.bind(this)}
- refetchTokenStateAsync={this._refetchTokenStateAsync.bind(this)}
- />
- <Container marginTop="15px">
- <Island>
- <Container
- marginTop="30px"
- marginBottom="30px"
- marginLeft="30px"
- marginRight="30px"
- className="flex justify-around items-center"
- >
- <ActionAccountBalanceWallet
- style={{ width: '30px', height: '30px' }}
- color={colors.orange}
- />
- <Text
- fontColor={colors.grey}
- fontSize="16px"
- center={true}
- onClick={this._startOnboarding.bind(this)}
- >
- Learn how to set up your account
- </Text>
- </Container>
- </Island>
+ {isMobile && <Container marginBottom="15px">{startOnboarding}</Container>}
+ <Container marginBottom={marginBottom}>
+ <Wallet
+ style={
+ !isMobile && this.props.isPortalOnboardingShowing
+ ? { zIndex: zIndex.aboveOverlay, position: 'relative' }
+ : undefined
+ }
+ userAddress={this.props.userAddress}
+ networkId={this.props.networkId}
+ blockchain={this._blockchain}
+ blockchainIsLoaded={this.props.blockchainIsLoaded}
+ blockchainErr={this.props.blockchainErr}
+ dispatcher={this.props.dispatcher}
+ tokenByAddress={this.props.tokenByAddress}
+ trackedTokens={this._getCurrentTrackedTokens()}
+ userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+ lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+ injectedProviderName={this.props.injectedProviderName}
+ providerType={this.props.providerType}
+ screenWidth={this.props.screenWidth}
+ location={this.props.location}
+ trackedTokenStateByAddress={this.state.trackedTokenStateByAddress}
+ onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
+ onAddToken={this._onAddToken.bind(this)}
+ onRemoveToken={this._onRemoveToken.bind(this)}
+ refetchTokenStateAsync={this._refetchTokenStateAsync.bind(this)}
+ />
</Container>
+ {!isMobile && <Container marginTop="15px">{startOnboarding}</Container>}
</div>
);
}
+ private _renderStartOnboarding(): React.ReactNode {
+ return (
+ <Island>
+ <Container
+ marginTop="30px"
+ marginBottom="30px"
+ marginLeft="30px"
+ marginRight="30px"
+ className="flex justify-around items-center"
+ >
+ <ActionAccountBalanceWallet style={{ width: '30px', height: '30px' }} color={colors.orange} />
+ <Text
+ fontColor={colors.grey}
+ fontSize="16px"
+ center={true}
+ onClick={this._startOnboarding.bind(this)}
+ >
+ Learn how to set up your account
+ </Text>
+ </Container>
+ </Island>
+ );
+ }
private _startOnboarding(): void {
const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId];
analytics.logEvent('Portal', 'Onboarding Started - Manual', networkName, this.props.portalOnboardingStep);
this.props.dispatcher.updatePortalOnboardingShowing(true);
+ // On mobile, make sure the wallet is completely visible.
+ if (this.props.screenWidth === ScreenWidths.Sm) {
+ document.querySelector('.wallet').scrollIntoView();
+ }
}
private _renderWalletSection(): React.ReactNode {
return <Section header={<TextHeader labelText="Your Account" />} body={this._renderWallet()} />;
diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx
index 1e8855c14..496e5cae0 100644
--- a/packages/website/ts/components/top_bar/provider_display.tsx
+++ b/packages/website/ts/components/top_bar/provider_display.tsx
@@ -10,6 +10,7 @@ import { Container } from 'ts/components/ui/container';
import { DropDown } from 'ts/components/ui/drop_down';
import { Identicon } from 'ts/components/ui/identicon';
import { Image } from 'ts/components/ui/image';
+import { Island } from 'ts/components/ui/island';
import { Text } from 'ts/components/ui/text';
import { Dispatcher } from 'ts/redux/dispatcher';
import { colors } from 'ts/style/colors';
@@ -35,9 +36,7 @@ interface ProviderDisplayState {}
const styles: Styles = {
root: {
height: ROOT_HEIGHT,
- backgroundColor: colors.white,
borderRadius: ROOT_HEIGHT,
- boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`,
},
};
@@ -62,7 +61,7 @@ export class ProviderDisplay extends React.Component<ProviderDisplayProps, Provi
this.props.providerType === ProviderType.Injected ? injectedProviderName : 'Ledger Nano S';
const isProviderMetamask = providerTitle === constants.PROVIDER_NAME_METAMASK;
const hoverActiveNode = (
- <div className="flex items-center p1" style={styles.root}>
+ <Island className="flex items-center p1" style={styles.root}>
<div>
{this._isBlockchainReady() ? (
<Identicon address={this.props.userAddress} diameter={ROOT_HEIGHT} />
@@ -78,7 +77,7 @@ export class ProviderDisplay extends React.Component<ProviderDisplayProps, Provi
{isProviderMetamask && (
<Image src="/images/metamask_icon.png" height={ROOT_HEIGHT} width={ROOT_HEIGHT} />
)}
- </div>
+ </Island>
);
const hasLedgerProvider = this.props.providerType === ProviderType.Ledger;
const horizontalPosition = isExternallyInjectedProvider || hasLedgerProvider ? 'left' : 'middle';
diff --git a/packages/website/ts/components/ui/animation.tsx b/packages/website/ts/components/ui/animation.tsx
new file mode 100644
index 000000000..cbda2993d
--- /dev/null
+++ b/packages/website/ts/components/ui/animation.tsx
@@ -0,0 +1,32 @@
+import * as React from 'react';
+import { keyframes, styled } from 'ts/style/theme';
+
+export type AnimationType = 'easeUpFromBottom';
+
+export interface AnimationProps {
+ type: AnimationType;
+}
+
+const PlainAnimation: React.StatelessComponent<AnimationProps> = props => <div {...props} />;
+
+const appearFromBottomFrames = keyframes`
+ from {
+ position: absolute;
+ bottom: -500px;
+ }
+
+ to {
+ position: absolute;
+ bottom: 0px;
+ }
+`;
+
+const animations: { [K in AnimationType]: string } = {
+ easeUpFromBottom: `${appearFromBottomFrames} 1s ease 0s 1 forwards`,
+};
+
+export const Animation = styled(PlainAnimation)`
+ animation: ${props => animations[props.type]};
+`;
+
+Animation.displayName = 'Animation';
diff --git a/packages/website/ts/components/ui/button.tsx b/packages/website/ts/components/ui/button.tsx
index cb542a386..02fa47480 100644
--- a/packages/website/ts/components/ui/button.tsx
+++ b/packages/website/ts/components/ui/button.tsx
@@ -1,5 +1,5 @@
import { colors } from '@0xproject/react-shared';
-import { darken, grayscale } from 'polished';
+import { darken, saturate } from 'polished';
import * as React from 'react';
import { styled } from 'ts/style/theme';
@@ -17,7 +17,7 @@ export interface ButtonProps {
}
const PlainButton: React.StatelessComponent<ButtonProps> = ({ children, isDisabled, onClick, type, className }) => (
- <button type={type} className={className} onClick={isDisabled ? undefined : onClick}>
+ <button type={type} className={className} onClick={isDisabled ? undefined : onClick} disabled={isDisabled}>
{children}
</button>
);
@@ -26,14 +26,15 @@ export const Button = styled(PlainButton)`
cursor: ${props => (props.isDisabled ? 'default' : 'pointer')};
font-size: ${props => props.fontSize};
color: ${props => props.fontColor};
- transition: background-color 0.5s ease;
+ transition: background-color, opacity 0.5s ease;
padding: 0.8em 2.2em;
border-radius: 6px;
box-shadow: 0px 0px 4px rgba(0, 0, 0, 0.25);
font-weight: 500;
+ outline: none;
font-family: ${props => props.fontFamily};
width: ${props => props.width};
- background-color: ${props => (props.isDisabled ? grayscale(props.backgroundColor) : props.backgroundColor)};
+ background-color: ${props => props.backgroundColor};
border: ${props => (props.borderColor ? `1px solid ${props.borderColor}` : 'none')};
&:hover {
background-color: ${props => (!props.isDisabled ? darken(0.1, props.backgroundColor) : '')};
@@ -41,6 +42,13 @@ export const Button = styled(PlainButton)`
&:active {
background-color: ${props => (!props.isDisabled ? darken(0.2, props.backgroundColor) : '')};
}
+ &:disabled {
+ opacity: 0.5;
+ box-shadow: none;
+ }
+ &:focus {
+ background-color: ${props => saturate(0.2, props.backgroundColor)};
+ }
`;
Button.defaultProps = {
diff --git a/packages/website/ts/components/ui/container.tsx b/packages/website/ts/components/ui/container.tsx
index 1776345da..90aec0e7c 100644
--- a/packages/website/ts/components/ui/container.tsx
+++ b/packages/website/ts/components/ui/container.tsx
@@ -23,6 +23,7 @@ export interface ContainerProps {
left?: string;
right?: string;
bottom?: string;
+ zIndex?: number;
}
export const Container: React.StatelessComponent<ContainerProps> = ({ children, className, isHidden, ...style }) => {
diff --git a/packages/website/ts/components/ui/identicon.tsx b/packages/website/ts/components/ui/identicon.tsx
index 30df995c8..cc1655962 100644
--- a/packages/website/ts/components/ui/identicon.tsx
+++ b/packages/website/ts/components/ui/identicon.tsx
@@ -23,7 +23,7 @@ export class Identicon extends React.Component<IdenticonProps, IdenticonState> {
const radius = diameter / 2;
return (
<div
- className="circle mx-auto relative transitionFix"
+ className="circle relative transitionFix"
style={{
width: diameter,
height: diameter,
diff --git a/packages/website/ts/components/ui/island.tsx b/packages/website/ts/components/ui/island.tsx
index de90b664f..c8abfb7e0 100644
--- a/packages/website/ts/components/ui/island.tsx
+++ b/packages/website/ts/components/ui/island.tsx
@@ -1,31 +1,28 @@
import * as React from 'react';
import { colors } from 'ts/style/colors';
+import { styled } from 'ts/style/theme';
export interface IslandProps {
style?: React.CSSProperties;
- children?: React.ReactNode;
className?: string;
Component?: string | React.ComponentClass<any> | React.StatelessComponent<any>;
+ borderRadius?: string;
}
-const defaultStyle: React.CSSProperties = {
- backgroundColor: colors.white,
- borderBottomRightRadius: 10,
- borderBottomLeftRadius: 10,
- borderTopRightRadius: 10,
- borderTopLeftRadius: 10,
- boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`,
- overflow: 'hidden',
-};
-
-export const Island: React.StatelessComponent<IslandProps> = (props: IslandProps) => (
- <props.Component style={{ ...defaultStyle, ...props.style }} className={props.className}>
- {props.children}
- </props.Component>
+const PlainIsland: React.StatelessComponent<IslandProps> = ({ Component, style, className, children }) => (
+ <Component style={style} className={className} children={children} />
);
+export const Island = styled(PlainIsland)`
+ background-color: ${colors.white};
+ border-radius: ${props => props.borderRadius};
+ box-shadow: 0px 4px 6px ${colors.walletBoxShadow};
+ overflow: hidden;
+`;
+
Island.defaultProps = {
Component: 'div',
+ borderRadius: '10px',
style: {},
};
diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index ac2fe0d31..f88fd6c24 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -86,7 +86,6 @@ interface AccessoryItemConfig {
const styles: Styles = {
root: {
width: '100%',
- position: 'relative',
},
footerItemInnerDiv: {
paddingLeft: 24,
@@ -323,6 +322,9 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
}
private _renderTokenRow(token: Token, _index: number): React.ReactNode {
const tokenState = this.props.trackedTokenStateByAddress[token.address];
+ if (_.isUndefined(tokenState)) {
+ return null;
+ }
const tokenLink = sharedUtils.getEtherScanLinkIfExists(
token.address,
this.props.networkId,
diff --git a/packages/website/ts/containers/portal_onboarding_flow.ts b/packages/website/ts/containers/portal_onboarding_flow.ts
index ba2b8f512..12daad021 100644
--- a/packages/website/ts/containers/portal_onboarding_flow.ts
+++ b/packages/website/ts/containers/portal_onboarding_flow.ts
@@ -3,7 +3,7 @@ import * as React from 'react';
import { connect } from 'react-redux';
import { Dispatch } from 'redux';
import { Blockchain } from 'ts/blockchain';
-import { ActionTypes, ProviderType, TokenByAddress, TokenStateByAddress } from 'ts/types';
+import { ActionTypes, ProviderType, ScreenWidths, TokenByAddress, TokenStateByAddress } from 'ts/types';
import { PortalOnboardingFlow as PortalOnboardingFlowComponent } from 'ts/components/onboarding/portal_onboarding_flow';
import { State } from 'ts/redux/reducer';
@@ -25,6 +25,7 @@ interface ConnectedState {
blockchainIsLoaded: boolean;
userEtherBalanceInWei?: BigNumber;
tokenByAddress: TokenByAddress;
+ screenWidth: ScreenWidths;
}
interface ConnectedDispatch {
@@ -43,6 +44,7 @@ const mapStateToProps = (state: State, _ownProps: PortalOnboardingFlowProps): Co
userEtherBalanceInWei: state.userEtherBalanceInWei,
tokenByAddress: state.tokenByAddress,
hasBeenSeen: state.hasPortalOnboardingBeenSeen,
+ screenWidth: state.screenWidth,
});
const mapDispatchToProps = (dispatch: Dispatch<State>): ConnectedDispatch => ({
diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx
index 3136dbca3..6830b64ab 100644
--- a/packages/website/ts/pages/about/about.tsx
+++ b/packages/website/ts/pages/about/about.tsx
@@ -150,12 +150,30 @@ const teamRow5: ProfileInfo[] = [
},
{
name: 'Francesco Agosti',
- title: 'Senior Frontend Engineer',
+ title: 'Engineer',
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',
},
+ {
+ name: 'Chris Kalani',
+ title: 'Director of Design',
+ description: `Previously founded Wake (acquired by InVision). Early Facebook product designer.`,
+ image: 'images/team/chris.png',
+ linkedIn: 'https://www.linkedin.com/in/chriskalani/',
+ github: 'https://github.com/chriskalani',
+ },
+];
+
+const teamRow6: ProfileInfo[] = [
+ {
+ name: 'Mel Oberto',
+ title: 'Office Operations / Executive Assistant',
+ description: `Daily Operations. Previously People Operations Associate at Heap. Marketing and MBA at Sacred Heart University.`,
+ image: 'images/team/mel.png',
+ linkedIn: 'https://www.linkedin.com/in/melanieoberto',
+ },
];
const advisors: ProfileInfo[] = [
@@ -252,6 +270,7 @@ export class About extends React.Component<AboutProps, AboutState> {
<div className="clearfix">{this._renderProfiles(teamRow3)}</div>
<div className="clearfix">{this._renderProfiles(teamRow4)}</div>
<div className="clearfix">{this._renderProfiles(teamRow5)}</div>
+ <div className="clearfix">{this._renderProfiles(teamRow6)}</div>
</div>
<div className="pt3 pb2">
<div
diff --git a/packages/website/ts/pages/about/profile.tsx b/packages/website/ts/pages/about/profile.tsx
index dd046a8cb..e73b1f193 100644
--- a/packages/website/ts/pages/about/profile.tsx
+++ b/packages/website/ts/pages/about/profile.tsx
@@ -47,7 +47,7 @@ export const Profile = (props: ProfileProps) => {
<div style={{ minHeight: 60, lineHeight: 1.4 }} className="pt1 pb2 mx-auto lg-h6 md-h6 sm-h5 sm-center">
{props.profileInfo.description}
</div>
- <div className="flex pb3 mx-auto sm-hide xs-hide" style={{ width: 280, opacity: 0.5 }}>
+ <div className="flex pb3 sm-hide xs-hide" style={{ width: 280, opacity: 0.5 }}>
{renderSocialMediaIcons(props.profileInfo)}
</div>
</div>
diff --git a/packages/website/ts/style/colors.ts b/packages/website/ts/style/colors.ts
index b15000d7a..45be4fe7f 100644
--- a/packages/website/ts/style/colors.ts
+++ b/packages/website/ts/style/colors.ts
@@ -1,7 +1,7 @@
import { colors as sharedColors } from '@0xproject/react-shared';
const appColors = {
- walletBoxShadow: 'rgba(56, 59, 137, 0.2)',
+ walletBoxShadow: 'rgba(0, 0, 0, 0.05)',
walletBorder: '#ededee',
walletDefaultItemBackground: '#fbfbfc',
walletFocusedItemBackground: '#f0f1f4',