From d53915e7e34e3c6de865342ee2e5063fe959ce5d Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Thu, 10 May 2018 14:25:56 -0700
Subject: Add routes

---
 packages/website/ts/components/portal/portal.tsx | 107 ++++++++++++++++++++++-
 1 file changed, 105 insertions(+), 2 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index e572b7911..d227678d6 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -3,20 +3,35 @@ import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 import * as React from 'react';
 import * as DocumentTitle from 'react-document-title';
+import { Route, Switch } from 'react-router-dom';
 
 import { Blockchain } from 'ts/blockchain';
 import { BlockchainErrDialog } from 'ts/components/dialogs/blockchain_err_dialog';
 import { LedgerConfigDialog } from 'ts/components/dialogs/ledger_config_dialog';
 import { PortalDisclaimerDialog } from 'ts/components/dialogs/portal_disclaimer_dialog';
+import { EthWrappers } from 'ts/components/eth_wrappers';
+import { FillOrder } from 'ts/components/fill_order';
 import { AssetPicker } from 'ts/components/generate_order/asset_picker';
 import { RelayerIndex } from 'ts/components/relayer_index/relayer_index';
+import { TokenBalances } from 'ts/components/token_balances';
 import { TopBar, TopBarDisplayType } from 'ts/components/top_bar/top_bar';
+import { TradeHistory } from 'ts/components/trade_history/trade_history';
 import { FlashMessage } from 'ts/components/ui/flash_message';
 import { Wallet } from 'ts/components/wallet/wallet';
+import { GenerateOrderForm } from 'ts/containers/generate_order_form';
 import { localStorage } from 'ts/local_storage/local_storage';
 import { trackedTokenStorage } from 'ts/local_storage/tracked_token_storage';
 import { Dispatcher } from 'ts/redux/dispatcher';
-import { BlockchainErrs, HashData, Order, ProviderType, ScreenWidths, TokenByAddress, TokenVisibility } from 'ts/types';
+import {
+    BlockchainErrs,
+    HashData,
+    Order,
+    ProviderType,
+    ScreenWidths,
+    TokenByAddress,
+    TokenVisibility,
+    WebsitePaths,
+} from 'ts/types';
 import { configs } from 'ts/utils/configs';
 import { constants } from 'ts/utils/constants';
 import { Translate } from 'ts/utils/translate';
@@ -85,6 +100,7 @@ const styles: Styles = {
 
 export class Portal extends React.Component<PortalProps, PortalState> {
     private _blockchain: Blockchain;
+    private _sharedOrderIfExists: Order;
     private _throttledScreenWidthUpdate: () => void;
     constructor(props: PortalProps) {
         super(props);
@@ -200,7 +216,22 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                             <div className="py3" style={styles.title}>
                                 Explore 0x Ecosystem
                             </div>
-                            <RelayerIndex networkId={this.props.networkId} />
+                            <Switch>
+                                <Route
+                                    path={`${WebsitePaths.Portal}/weth`}
+                                    render={this._renderEthWrapper.bind(this)}
+                                />
+                                <Route path={`${WebsitePaths.Portal}/fill`} render={this._renderFillOrder.bind(this)} />
+                                <Route
+                                    path={`${WebsitePaths.Portal}/balances`}
+                                    render={this._renderTokenBalances.bind(this)}
+                                />
+                                <Route
+                                    path={`${WebsitePaths.Portal}/trades`}
+                                    component={this._renderTradeHistory.bind(this)}
+                                />
+                                <Route path={`${WebsitePaths.Home}`} component={this._renderRelayerIndex.bind(this)} />
+                            </Switch>
                         </div>
                     </div>
                     <BlockchainErrDialog
@@ -241,6 +272,78 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
+    private _renderEthWrapper() {
+        return (
+            <EthWrappers
+                networkId={this.props.networkId}
+                blockchain={this._blockchain}
+                dispatcher={this.props.dispatcher}
+                tokenByAddress={this.props.tokenByAddress}
+                userAddress={this.props.userAddress}
+                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+            />
+        );
+    }
+    private _renderTradeHistory() {
+        return (
+            <TradeHistory
+                tokenByAddress={this.props.tokenByAddress}
+                userAddress={this.props.userAddress}
+                networkId={this.props.networkId}
+            />
+        );
+    }
+    private _renderTokenBalances() {
+        const allTokens = _.values(this.props.tokenByAddress);
+        const trackedTokens = _.filter(allTokens, t => t.isTracked);
+        return (
+            <TokenBalances
+                blockchain={this._blockchain}
+                blockchainErr={this.props.blockchainErr}
+                blockchainIsLoaded={this.props.blockchainIsLoaded}
+                dispatcher={this.props.dispatcher}
+                screenWidth={this.props.screenWidth}
+                tokenByAddress={this.props.tokenByAddress}
+                trackedTokens={trackedTokens}
+                userAddress={this.props.userAddress}
+                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                networkId={this.props.networkId}
+                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+            />
+        );
+    }
+    private _renderFillOrder(match: any, location: Location, history: History) {
+        const initialFillOrder = !_.isUndefined(this.props.userSuppliedOrderCache)
+            ? this.props.userSuppliedOrderCache
+            : this._sharedOrderIfExists;
+        return (
+            <FillOrder
+                blockchain={this._blockchain}
+                blockchainErr={this.props.blockchainErr}
+                initialOrder={initialFillOrder}
+                isOrderInUrl={!_.isUndefined(this._sharedOrderIfExists)}
+                orderFillAmount={this.props.orderFillAmount}
+                networkId={this.props.networkId}
+                userAddress={this.props.userAddress}
+                tokenByAddress={this.props.tokenByAddress}
+                dispatcher={this.props.dispatcher}
+                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+            />
+        );
+    }
+    private _renderGenerateOrderForm(match: any, location: Location, history: History) {
+        return (
+            <GenerateOrderForm
+                blockchain={this._blockchain}
+                hashData={this.props.hashData}
+                dispatcher={this.props.dispatcher}
+            />
+        );
+    }
+    private _renderRelayerIndex() {
+        return <RelayerIndex networkId={this.props.networkId} />;
+    }
     private _onTokenChosen(tokenAddress: string): void {
         if (_.isEmpty(tokenAddress)) {
             this.setState({
-- 
cgit 


From 9e76d2ca63090e28379688505e5e179ec642d3b1 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Thu, 10 May 2018 15:11:49 -0700
Subject: Add menu

---
 packages/website/ts/components/portal/portal.tsx | 59 ++++++++++++++++--------
 packages/website/ts/components/wallet/wallet.tsx |  2 +-
 2 files changed, 41 insertions(+), 20 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index d227678d6..e6a92d9a8 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -12,6 +12,7 @@ import { PortalDisclaimerDialog } from 'ts/components/dialogs/portal_disclaimer_
 import { EthWrappers } from 'ts/components/eth_wrappers';
 import { FillOrder } from 'ts/components/fill_order';
 import { AssetPicker } from 'ts/components/generate_order/asset_picker';
+import { LegacyPortalMenu } from 'ts/components/legacy_portal/legacy_portal_menu';
 import { RelayerIndex } from 'ts/components/relayer_index/relayer_index';
 import { TokenBalances } from 'ts/components/token_balances';
 import { TopBar, TopBarDisplayType } from 'ts/components/top_bar/top_bar';
@@ -164,8 +165,6 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen.bind(
             this.props.dispatcher,
         );
-        const allTokens = _.values(this.props.tokenByAddress);
-        const trackedTokens = _.filter(allTokens, t => t.isTracked);
         const isAssetPickerDialogOpen = this.state.tokenManagementState !== TokenManagementState.None;
         const tokenVisibility =
             this.state.tokenManagementState === TokenManagementState.Add
@@ -194,23 +193,19 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                             <div className="py3" style={styles.title}>
                                 Your Account
                             </div>
-                            <Wallet
-                                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={trackedTokens}
-                                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-                                injectedProviderName={this.props.injectedProviderName}
-                                providerType={this.props.providerType}
-                                onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
-                                onAddToken={this._onAddToken.bind(this)}
-                                onRemoveToken={this._onRemoveToken.bind(this)}
-                            />
+                            <div style={{ width: 346 }}>
+                                <Switch>
+                                    <Route
+                                        path={`${WebsitePaths.Portal}/:route`}
+                                        render={this._renderMenu.bind(this)}
+                                    />
+                                    <Route
+                                        exact={true}
+                                        path={`${WebsitePaths.Portal}`}
+                                        component={this._renderWallet.bind(this)}
+                                    />
+                                </Switch>
+                            </div>
                         </div>
                         <div className="flex-auto px3" style={styles.scrollContainer}>
                             <div className="py3" style={styles.title}>
@@ -272,6 +267,32 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
+    private _renderMenu() {
+        return <LegacyPortalMenu menuItemStyle={{ color: colors.darkerGrey }} />;
+    }
+    private _renderWallet() {
+        const allTokens = _.values(this.props.tokenByAddress);
+        const trackedTokens = _.filter(allTokens, t => t.isTracked);
+        return (
+            <Wallet
+                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={trackedTokens}
+                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                injectedProviderName={this.props.injectedProviderName}
+                providerType={this.props.providerType}
+                onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
+                onAddToken={this._onAddToken.bind(this)}
+                onRemoveToken={this._onRemoveToken.bind(this)}
+            />
+        );
+    }
     private _renderEthWrapper() {
         return (
             <EthWrappers
diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index 95f31582e..d9c97e34a 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -80,7 +80,7 @@ interface AccessoryItemConfig {
 
 const styles: Styles = {
     root: {
-        width: 346,
+        width: '100%',
         backgroundColor: colors.white,
         borderBottomRightRadius: 10,
         borderBottomLeftRadius: 10,
-- 
cgit 


From 55d1228abb308e27c913b0f717bac7c4395ec08c Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Thu, 10 May 2018 16:29:10 -0700
Subject: Implement new menu styling

---
 packages/website/ts/components/portal/portal.tsx   |  8 +-
 .../website/ts/components/portal/portal_menu.tsx   | 91 ++++++++++++++++++++++
 2 files changed, 95 insertions(+), 4 deletions(-)
 create mode 100644 packages/website/ts/components/portal/portal_menu.tsx

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index e6a92d9a8..d6bc82587 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -3,7 +3,7 @@ import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 import * as React from 'react';
 import * as DocumentTitle from 'react-document-title';
-import { Route, Switch } from 'react-router-dom';
+import { Route, RouteComponentProps, Switch } from 'react-router-dom';
 
 import { Blockchain } from 'ts/blockchain';
 import { BlockchainErrDialog } from 'ts/components/dialogs/blockchain_err_dialog';
@@ -12,7 +12,7 @@ import { PortalDisclaimerDialog } from 'ts/components/dialogs/portal_disclaimer_
 import { EthWrappers } from 'ts/components/eth_wrappers';
 import { FillOrder } from 'ts/components/fill_order';
 import { AssetPicker } from 'ts/components/generate_order/asset_picker';
-import { LegacyPortalMenu } from 'ts/components/legacy_portal/legacy_portal_menu';
+import { PortalMenu } from 'ts/components/portal/portal_menu';
 import { RelayerIndex } from 'ts/components/relayer_index/relayer_index';
 import { TokenBalances } from 'ts/components/token_balances';
 import { TopBar, TopBarDisplayType } from 'ts/components/top_bar/top_bar';
@@ -267,8 +267,8 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderMenu() {
-        return <LegacyPortalMenu menuItemStyle={{ color: colors.darkerGrey }} />;
+    private _renderMenu(routeComponentProps: RouteComponentProps<any>) {
+        return <PortalMenu selectedPath={routeComponentProps.location.pathname} />;
     }
     private _renderWallet() {
         const allTokens = _.values(this.props.tokenByAddress);
diff --git a/packages/website/ts/components/portal/portal_menu.tsx b/packages/website/ts/components/portal/portal_menu.tsx
new file mode 100644
index 000000000..33835fd98
--- /dev/null
+++ b/packages/website/ts/components/portal/portal_menu.tsx
@@ -0,0 +1,91 @@
+import { colors, Styles } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+import { MenuItem } from 'ts/components/ui/menu_item';
+import { Environments, WebsitePaths } from 'ts/types';
+import { configs } from 'ts/utils/configs';
+
+export interface PortalMenuProps {
+    selectedPath?: string;
+}
+
+interface MenuItemEntry {
+    to: string;
+    labelText: string;
+    iconName: string;
+}
+
+const menuItemEntries: MenuItemEntry[] = [
+    {
+        to: `${WebsitePaths.Portal}`,
+        labelText: 'Generate order',
+        iconName: 'zmdi-arrow-right-top',
+    },
+    {
+        to: `${WebsitePaths.Portal}/fill`,
+        labelText: 'Fill order',
+        iconName: 'zmdi-arrow-left-bottom',
+    },
+    {
+        to: `${WebsitePaths.Portal}/balances`,
+        labelText: 'Balances',
+        iconName: 'zmdi-balance-wallet',
+    },
+    {
+        to: `${WebsitePaths.Portal}/trades`,
+        labelText: 'Trade History',
+        iconName: 'zmdi-format-list-bulleted',
+    },
+    {
+        to: `${WebsitePaths.Portal}/weth`,
+        labelText: 'Wrap ETH',
+        iconName: 'zmdi-circle-o',
+    },
+];
+
+const DEFAULT_LABEL_COLOR = colors.darkerGrey;
+const DEFAULT_ICON_COLOR = colors.darkerGrey;
+const SELECTED_ICON_COLOR = colors.yellow800;
+
+export const PortalMenu: React.StatelessComponent<PortalMenuProps> = (props: PortalMenuProps) => {
+    return (
+        <div>
+            {_.map(menuItemEntries, entry => {
+                const selected = entry.to === props.selectedPath;
+                return (
+                    <MenuItem key={entry.to} className="py2" to={entry.to}>
+                        <PortalMenuItemLabel title={entry.labelText} iconName={entry.iconName} selected={selected} />
+                    </MenuItem>
+                );
+            })}
+        </div>
+    );
+};
+
+interface PortalMenuItemLabelProps {
+    title: string;
+    iconName: string;
+    selected: boolean;
+}
+const PortalMenuItemLabel: React.StatelessComponent<PortalMenuItemLabelProps> = (props: PortalMenuItemLabelProps) => {
+    const styles: Styles = {
+        iconStyle: {
+            color: props.selected ? SELECTED_ICON_COLOR : DEFAULT_ICON_COLOR,
+            fontSize: 20,
+        },
+        textStyle: {
+            color: DEFAULT_LABEL_COLOR,
+            fontWeight: props.selected ? 'bold' : 'normal',
+        },
+    };
+    return (
+        <div className="flex">
+            <div className="pr1 pl2">
+                <i style={styles.iconStyle} className={`zmdi ${props.iconName}`} />
+            </div>
+            <div className="pl1" style={styles.textStyle}>
+                {props.title}
+            </div>
+        </div>
+    );
+};
-- 
cgit 


From ef1e9743465d40cb3a2c3a1479155437694951b9 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Fri, 11 May 2018 14:17:40 -0700
Subject: Back button and title components

---
 packages/website/ts/components/portal/portal.tsx   | 129 ++++++++++++++-------
 .../website/ts/components/portal/portal_menu.tsx   |  29 ++---
 packages/website/ts/components/wallet/wallet.tsx   |  18 +--
 3 files changed, 112 insertions(+), 64 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index d6bc82587..70c99921c 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -3,7 +3,7 @@ import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
 import * as React from 'react';
 import * as DocumentTitle from 'react-document-title';
-import { Route, RouteComponentProps, Switch } from 'react-router-dom';
+import { Link, Route, RouteComponentProps, Switch } from 'react-router-dom';
 
 import { Blockchain } from 'ts/blockchain';
 import { BlockchainErrDialog } from 'ts/components/dialogs/blockchain_err_dialog';
@@ -78,6 +78,7 @@ enum TokenManagementState {
 
 const THROTTLE_TIMEOUT = 100;
 const TOP_BAR_HEIGHT = TopBar.heightForDisplayType(TopBarDisplayType.Expanded);
+const BACK_BUTTON_HEIGHT = 28;
 
 const styles: Styles = {
     root: {
@@ -97,6 +98,16 @@ const styles: Styles = {
         fontWeight: 'bold',
         fontSize: 20,
     },
+    backButton: {
+        height: BACK_BUTTON_HEIGHT,
+        backgroundColor: colors.white,
+        borderRadius: BACK_BUTTON_HEIGHT,
+        boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`,
+    },
+    backButtonIcon: {
+        color: colors.mediumBlue,
+        fontSize: 20,
+    },
 };
 
 export class Portal extends React.Component<PortalProps, PortalState> {
@@ -190,9 +201,6 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                 <div id="portal" style={styles.body}>
                     <div className="sm-flex flex-center">
                         <div className="flex-last px3">
-                            <div className="py3" style={styles.title}>
-                                Your Account
-                            </div>
                             <div style={{ width: 346 }}>
                                 <Switch>
                                     <Route
@@ -208,9 +216,6 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                             </div>
                         </div>
                         <div className="flex-auto px3" style={styles.scrollContainer}>
-                            <div className="py3" style={styles.title}>
-                                Explore 0x Ecosystem
-                            </div>
                             <Switch>
                                 <Route
                                     path={`${WebsitePaths.Portal}/weth`}
@@ -218,7 +223,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                                 />
                                 <Route path={`${WebsitePaths.Portal}/fill`} render={this._renderFillOrder.bind(this)} />
                                 <Route
-                                    path={`${WebsitePaths.Portal}/balances`}
+                                    path={`${WebsitePaths.Portal}/account`}
                                     render={this._renderTokenBalances.bind(this)}
                                 />
                                 <Route
@@ -268,29 +273,37 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         );
     }
     private _renderMenu(routeComponentProps: RouteComponentProps<any>) {
-        return <PortalMenu selectedPath={routeComponentProps.location.pathname} />;
+        return (
+            <div>
+                <BackButton />
+                <PortalMenu selectedPath={routeComponentProps.location.pathname} />
+            </div>
+        );
     }
     private _renderWallet() {
         const allTokens = _.values(this.props.tokenByAddress);
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
-            <Wallet
-                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={trackedTokens}
-                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-                injectedProviderName={this.props.injectedProviderName}
-                providerType={this.props.providerType}
-                onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
-                onAddToken={this._onAddToken.bind(this)}
-                onRemoveToken={this._onRemoveToken.bind(this)}
-            />
+            <div>
+                <Title titleText={'Your Account'} />
+                <Wallet
+                    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={trackedTokens}
+                    userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                    lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                    injectedProviderName={this.props.injectedProviderName}
+                    providerType={this.props.providerType}
+                    onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
+                    onAddToken={this._onAddToken.bind(this)}
+                    onRemoveToken={this._onRemoveToken.bind(this)}
+                />
+            </div>
         );
     }
     private _renderEthWrapper() {
@@ -319,19 +332,22 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         const allTokens = _.values(this.props.tokenByAddress);
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
-            <TokenBalances
-                blockchain={this._blockchain}
-                blockchainErr={this.props.blockchainErr}
-                blockchainIsLoaded={this.props.blockchainIsLoaded}
-                dispatcher={this.props.dispatcher}
-                screenWidth={this.props.screenWidth}
-                tokenByAddress={this.props.tokenByAddress}
-                trackedTokens={trackedTokens}
-                userAddress={this.props.userAddress}
-                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                networkId={this.props.networkId}
-                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-            />
+            <div>
+                <Title titleText={'Your Account'} />
+                <TokenBalances
+                    blockchain={this._blockchain}
+                    blockchainErr={this.props.blockchainErr}
+                    blockchainIsLoaded={this.props.blockchainIsLoaded}
+                    dispatcher={this.props.dispatcher}
+                    screenWidth={this.props.screenWidth}
+                    tokenByAddress={this.props.tokenByAddress}
+                    trackedTokens={trackedTokens}
+                    userAddress={this.props.userAddress}
+                    userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                    networkId={this.props.networkId}
+                    lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                />
+            </div>
         );
     }
     private _renderFillOrder(match: any, location: Location, history: History) {
@@ -363,7 +379,12 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         );
     }
     private _renderRelayerIndex() {
-        return <RelayerIndex networkId={this.props.networkId} />;
+        return (
+            <div>
+                <Title titleText={'Explore 0x Relayers'} />
+                <RelayerIndex networkId={this.props.networkId} />
+            </div>
+        );
     }
     private _onTokenChosen(tokenAddress: string): void {
         if (_.isEmpty(tokenAddress)) {
@@ -419,3 +440,31 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         this.props.dispatcher.updateScreenWidth(newScreenWidth);
     }
 }
+
+interface TitleProps {
+    titleText: string;
+}
+const Title = (props: TitleProps) => {
+    return (
+        <div className="py3" style={styles.title}>
+            {props.titleText}
+        </div>
+    );
+};
+
+const BackButton = () => {
+    return (
+        <div style={{ height: 65, paddingTop: 25 }}>
+            <Link to={`${WebsitePaths.Portal}`} style={{ textDecoration: 'none' }}>
+                <div className="flex right" style={{ ...styles.backButton, paddingTop: 10 }}>
+                    <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 }}>back to Relayers</div>
+                    </div>
+                </div>
+            </Link>
+        </div>
+    );
+};
diff --git a/packages/website/ts/components/portal/portal_menu.tsx b/packages/website/ts/components/portal/portal_menu.tsx
index 33835fd98..e073596e2 100644
--- a/packages/website/ts/components/portal/portal_menu.tsx
+++ b/packages/website/ts/components/portal/portal_menu.tsx
@@ -17,39 +17,34 @@ interface MenuItemEntry {
 
 const menuItemEntries: MenuItemEntry[] = [
     {
-        to: `${WebsitePaths.Portal}`,
-        labelText: 'Generate order',
-        iconName: 'zmdi-arrow-right-top',
-    },
-    {
-        to: `${WebsitePaths.Portal}/fill`,
-        labelText: 'Fill order',
-        iconName: 'zmdi-arrow-left-bottom',
-    },
-    {
-        to: `${WebsitePaths.Portal}/balances`,
-        labelText: 'Balances',
+        to: `${WebsitePaths.Portal}/account`,
+        labelText: 'Account Overview',
         iconName: 'zmdi-balance-wallet',
     },
     {
         to: `${WebsitePaths.Portal}/trades`,
-        labelText: 'Trade History',
+        labelText: 'Trade history',
         iconName: 'zmdi-format-list-bulleted',
     },
     {
         to: `${WebsitePaths.Portal}/weth`,
-        labelText: 'Wrap ETH',
+        labelText: 'Wrapped ETH',
         iconName: 'zmdi-circle-o',
     },
+    {
+        to: `${WebsitePaths.Portal}/direct`,
+        labelText: 'Trade direct',
+        iconName: 'zmdi-swap',
+    },
 ];
 
 const DEFAULT_LABEL_COLOR = colors.darkerGrey;
 const DEFAULT_ICON_COLOR = colors.darkerGrey;
-const SELECTED_ICON_COLOR = colors.yellow800;
+const SELECTED_ICON_COLOR = colors.yellow900;
 
 export const PortalMenu: React.StatelessComponent<PortalMenuProps> = (props: PortalMenuProps) => {
     return (
-        <div>
+        <div style={{ paddingLeft: 185 }}>
             {_.map(menuItemEntries, entry => {
                 const selected = entry.to === props.selectedPath;
                 return (
@@ -80,7 +75,7 @@ const PortalMenuItemLabel: React.StatelessComponent<PortalMenuItemLabelProps> =
     };
     return (
         <div className="flex">
-            <div className="pr1 pl2">
+            <div className="pr1">
                 <i style={styles.iconStyle} className={`zmdi ${props.iconName}`} />
             </div>
             <div className="pl1" style={styles.textStyle}>
diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index d9c97e34a..ac79d5a21 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -18,6 +18,7 @@ import NavigationArrowDownward from 'material-ui/svg-icons/navigation/arrow-down
 import NavigationArrowUpward from 'material-ui/svg-icons/navigation/arrow-upward';
 import Close from 'material-ui/svg-icons/navigation/close';
 import * as React from 'react';
+import { Link } from 'react-router-dom';
 import ReactTooltip = require('react-tooltip');
 import firstBy = require('thenby');
 
@@ -38,6 +39,7 @@ import {
     TokenByAddress,
     TokenState,
     TokenStateByAddress,
+    WebsitePaths,
 } from 'ts/types';
 import { backendClient } from 'ts/utils/backend_client';
 import { constants } from 'ts/utils/constants';
@@ -237,13 +239,15 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
         const userAddress = this.props.userAddress;
         const primaryText = utils.getAddressBeginAndEnd(userAddress);
         return (
-            <ListItem
-                key={HEADER_ITEM_KEY}
-                primaryText={primaryText}
-                leftIcon={<Identicon address={userAddress} diameter={ICON_DIMENSION} />}
-                style={{ ...styles.paddedItem, ...styles.borderedItem }}
-                innerDivStyle={styles.headerItemInnerDiv}
-            />
+            <Link to={`${WebsitePaths.Portal}/account`} style={{ textDecoration: 'none' }}>
+                <ListItem
+                    key={HEADER_ITEM_KEY}
+                    primaryText={primaryText}
+                    leftIcon={<Identicon address={userAddress} diameter={ICON_DIMENSION} />}
+                    style={{ ...styles.paddedItem, ...styles.borderedItem }}
+                    innerDivStyle={styles.headerItemInnerDiv}
+                />
+            </Link>
         );
     }
     private _renderBody(): React.ReactElement<{}> {
-- 
cgit 


From 807250510ac5be9ef7cd291aa16db64a5eff1418 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Fri, 11 May 2018 14:21:56 -0700
Subject: Add props to back button

---
 packages/website/ts/components/portal/portal.tsx | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index 70c99921c..fb047a28a 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -275,7 +275,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     private _renderMenu(routeComponentProps: RouteComponentProps<any>) {
         return (
             <div>
-                <BackButton />
+                <BackButton to={`${WebsitePaths.Portal}`} labelText={'back to Relayers'} />
                 <PortalMenu selectedPath={routeComponentProps.location.pathname} />
             </div>
         );
@@ -285,7 +285,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
             <div>
-                <Title titleText={'Your Account'} />
+                <Title labelText={'Your Account'} />
                 <Wallet
                     userAddress={this.props.userAddress}
                     networkId={this.props.networkId}
@@ -333,7 +333,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
             <div>
-                <Title titleText={'Your Account'} />
+                <Title labelText={'Your Account'} />
                 <TokenBalances
                     blockchain={this._blockchain}
                     blockchainErr={this.props.blockchainErr}
@@ -381,7 +381,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     private _renderRelayerIndex() {
         return (
             <div>
-                <Title titleText={'Explore 0x Relayers'} />
+                <Title labelText={'Explore 0x Relayers'} />
                 <RelayerIndex networkId={this.props.networkId} />
             </div>
         );
@@ -442,26 +442,30 @@ export class Portal extends React.Component<PortalProps, PortalState> {
 }
 
 interface TitleProps {
-    titleText: string;
+    labelText: string;
 }
 const Title = (props: TitleProps) => {
     return (
         <div className="py3" style={styles.title}>
-            {props.titleText}
+            {props.labelText}
         </div>
     );
 };
 
-const BackButton = () => {
+interface BackButtonProps {
+    to: string;
+    labelText: string;
+}
+const BackButton = (props: BackButtonProps) => {
     return (
         <div style={{ height: 65, paddingTop: 25 }}>
-            <Link to={`${WebsitePaths.Portal}`} style={{ textDecoration: 'none' }}>
+            <Link to={props.to} style={{ textDecoration: 'none' }}>
                 <div className="flex right" style={{ ...styles.backButton, paddingTop: 10 }}>
                     <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 }}>back to Relayers</div>
+                        <div style={{ fontSize: 16, color: colors.lightGrey }}>{props.labelText}</div>
                     </div>
                 </div>
             </Link>
-- 
cgit 


From d6e321e97ff374b4f46356179bc1e280e4a00260 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Fri, 11 May 2018 15:25:04 -0700
Subject: Add manage you wallet footer

---
 packages/website/ts/components/wallet/wallet.tsx | 65 +++++++++++++++---------
 1 file changed, 41 insertions(+), 24 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index ac79d5a21..ff7127604 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -279,31 +279,48 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
     }
     private _renderFooterRows(): React.ReactElement<{}> {
         return (
-            <ListItem
-                key={FOOTER_ITEM_KEY}
-                primaryText={
-                    <div className="flex">
-                        <FloatingActionButton mini={true} zDepth={0} onClick={this.props.onAddToken}>
-                            <ContentAdd />
-                        </FloatingActionButton>
-                        <FloatingActionButton mini={true} zDepth={0} className="px1" onClick={this.props.onRemoveToken}>
-                            <ContentRemove />
-                        </FloatingActionButton>
-                        <div
-                            style={{
-                                paddingLeft: 10,
-                                position: 'relative',
-                                top: '50%',
-                                transform: 'translateY(33%)',
-                            }}
-                        >
-                            add/remove tokens
+            <div key={FOOTER_ITEM_KEY}>
+                <ListItem
+                    primaryText={
+                        <div className="flex">
+                            <FloatingActionButton mini={true} zDepth={0} onClick={this.props.onAddToken}>
+                                <ContentAdd />
+                            </FloatingActionButton>
+                            <FloatingActionButton
+                                mini={true}
+                                zDepth={0}
+                                className="px1"
+                                onClick={this.props.onRemoveToken}
+                            >
+                                <ContentRemove />
+                            </FloatingActionButton>
+                            <div
+                                style={{
+                                    paddingLeft: 10,
+                                    position: 'relative',
+                                    top: '50%',
+                                    transform: 'translateY(33%)',
+                                }}
+                            >
+                                add/remove tokens
+                            </div>
                         </div>
-                    </div>
-                }
-                disabled={true}
-                innerDivStyle={styles.footerItemInnerDiv}
-            />
+                    }
+                    disabled={true}
+                    innerDivStyle={styles.footerItemInnerDiv}
+                    style={styles.borderedItem}
+                />
+                <Link to={`${WebsitePaths.Portal}/account`} style={{ textDecoration: 'none' }}>
+                    <ListItem
+                        primaryText={
+                            <div className="flex right" style={{ color: colors.mediumBlue, fontWeight: 'bold' }}>
+                                {'manage your wallet'}
+                            </div>
+                        }
+                        style={{ ...styles.paddedItem, ...styles.borderedItem }}
+                    />
+                </Link>
+            </div>
         );
     }
     private _renderEthRows(): React.ReactNode {
-- 
cgit 


From ea948ac2c885c395f1e07b285c65232264c58b7b Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Fri, 11 May 2018 16:09:22 -0700
Subject: Trade direct route

---
 packages/website/ts/components/portal/portal.tsx   | 79 ++++++++++------------
 .../website/ts/components/portal/portal_menu.tsx   |  2 +-
 2 files changed, 37 insertions(+), 44 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index fb047a28a..09f2ba10a 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -221,7 +221,6 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                                     path={`${WebsitePaths.Portal}/weth`}
                                     render={this._renderEthWrapper.bind(this)}
                                 />
-                                <Route path={`${WebsitePaths.Portal}/fill`} render={this._renderFillOrder.bind(this)} />
                                 <Route
                                     path={`${WebsitePaths.Portal}/account`}
                                     render={this._renderTokenBalances.bind(this)}
@@ -230,6 +229,10 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                                     path={`${WebsitePaths.Portal}/trades`}
                                     component={this._renderTradeHistory.bind(this)}
                                 />
+                                <Route
+                                    path={`${WebsitePaths.Portal}/direct`}
+                                    component={this._renderTradeDirect.bind(this)}
+                                />
                                 <Route path={`${WebsitePaths.Home}`} component={this._renderRelayerIndex.bind(this)} />
                             </Switch>
                         </div>
@@ -308,24 +311,42 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     }
     private _renderEthWrapper() {
         return (
-            <EthWrappers
-                networkId={this.props.networkId}
-                blockchain={this._blockchain}
-                dispatcher={this.props.dispatcher}
-                tokenByAddress={this.props.tokenByAddress}
-                userAddress={this.props.userAddress}
-                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-            />
+            <div>
+                <Title labelText={'Wrapped ETH'} />
+                <EthWrappers
+                    networkId={this.props.networkId}
+                    blockchain={this._blockchain}
+                    dispatcher={this.props.dispatcher}
+                    tokenByAddress={this.props.tokenByAddress}
+                    userAddress={this.props.userAddress}
+                    userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                    lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                />
+            </div>
         );
     }
     private _renderTradeHistory() {
         return (
-            <TradeHistory
-                tokenByAddress={this.props.tokenByAddress}
-                userAddress={this.props.userAddress}
-                networkId={this.props.networkId}
-            />
+            <div>
+                <Title labelText={'Trade History'} />
+                <TradeHistory
+                    tokenByAddress={this.props.tokenByAddress}
+                    userAddress={this.props.userAddress}
+                    networkId={this.props.networkId}
+                />
+            </div>
+        );
+    }
+    private _renderTradeDirect(match: any, location: Location, history: History) {
+        return (
+            <div>
+                <Title labelText={'Trade Direct'} />
+                <GenerateOrderForm
+                    blockchain={this._blockchain}
+                    hashData={this.props.hashData}
+                    dispatcher={this.props.dispatcher}
+                />
+            </div>
         );
     }
     private _renderTokenBalances() {
@@ -350,34 +371,6 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderFillOrder(match: any, location: Location, history: History) {
-        const initialFillOrder = !_.isUndefined(this.props.userSuppliedOrderCache)
-            ? this.props.userSuppliedOrderCache
-            : this._sharedOrderIfExists;
-        return (
-            <FillOrder
-                blockchain={this._blockchain}
-                blockchainErr={this.props.blockchainErr}
-                initialOrder={initialFillOrder}
-                isOrderInUrl={!_.isUndefined(this._sharedOrderIfExists)}
-                orderFillAmount={this.props.orderFillAmount}
-                networkId={this.props.networkId}
-                userAddress={this.props.userAddress}
-                tokenByAddress={this.props.tokenByAddress}
-                dispatcher={this.props.dispatcher}
-                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-            />
-        );
-    }
-    private _renderGenerateOrderForm(match: any, location: Location, history: History) {
-        return (
-            <GenerateOrderForm
-                blockchain={this._blockchain}
-                hashData={this.props.hashData}
-                dispatcher={this.props.dispatcher}
-            />
-        );
-    }
     private _renderRelayerIndex() {
         return (
             <div>
diff --git a/packages/website/ts/components/portal/portal_menu.tsx b/packages/website/ts/components/portal/portal_menu.tsx
index e073596e2..c8e2dacfa 100644
--- a/packages/website/ts/components/portal/portal_menu.tsx
+++ b/packages/website/ts/components/portal/portal_menu.tsx
@@ -18,7 +18,7 @@ interface MenuItemEntry {
 const menuItemEntries: MenuItemEntry[] = [
     {
         to: `${WebsitePaths.Portal}/account`,
-        labelText: 'Account Overview',
+        labelText: 'Account overview',
         iconName: 'zmdi-balance-wallet',
     },
     {
-- 
cgit 


From c787dc735695be351b23e1e91b792da44e01fc11 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Mon, 14 May 2018 14:19:39 -0700
Subject: Fix linter errors and relayer index reloading

---
 .../ts/components/legacy_portal/legacy_portal.tsx  |  2 +-
 packages/website/ts/components/portal/portal.tsx   | 26 +++++++++++++---------
 packages/website/ts/components/wallet/wallet.tsx   |  3 +--
 3 files changed, 17 insertions(+), 14 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/legacy_portal/legacy_portal.tsx b/packages/website/ts/components/legacy_portal/legacy_portal.tsx
index 002b258fb..a5ea95629 100644
--- a/packages/website/ts/components/legacy_portal/legacy_portal.tsx
+++ b/packages/website/ts/components/legacy_portal/legacy_portal.tsx
@@ -217,7 +217,7 @@ export class LegacyPortal extends React.Component<LegacyPortalProps, LegacyPorta
                                                 />
                                                 <Route
                                                     path={`${WebsitePaths.Portal}/trades`}
-                                                    component={this._renderTradeHistory.bind(this)}
+                                                    render={this._renderTradeHistory.bind(this)}
                                                 />
                                                 <Route
                                                     path={`${WebsitePaths.Home}`}
diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index 09f2ba10a..f3b0cc721 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -210,7 +210,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                                     <Route
                                         exact={true}
                                         path={`${WebsitePaths.Portal}`}
-                                        component={this._renderWallet.bind(this)}
+                                        render={this._renderWallet.bind(this)}
                                     />
                                 </Switch>
                             </div>
@@ -227,13 +227,17 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                                 />
                                 <Route
                                     path={`${WebsitePaths.Portal}/trades`}
-                                    component={this._renderTradeHistory.bind(this)}
+                                    render={this._renderTradeHistory.bind(this)}
                                 />
                                 <Route
                                     path={`${WebsitePaths.Portal}/direct`}
-                                    component={this._renderTradeDirect.bind(this)}
+                                    render={this._renderTradeDirect.bind(this)}
+                                />
+                                <Route
+                                    exact={true}
+                                    path={`${WebsitePaths.Portal}/`}
+                                    render={this._renderRelayerIndex.bind(this)}
                                 />
-                                <Route path={`${WebsitePaths.Home}`} component={this._renderRelayerIndex.bind(this)} />
                             </Switch>
                         </div>
                     </div>
@@ -275,7 +279,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderMenu(routeComponentProps: RouteComponentProps<any>) {
+    private _renderMenu(routeComponentProps: RouteComponentProps<any>): React.ReactNode {
         return (
             <div>
                 <BackButton to={`${WebsitePaths.Portal}`} labelText={'back to Relayers'} />
@@ -283,7 +287,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderWallet() {
+    private _renderWallet(): React.ReactNode {
         const allTokens = _.values(this.props.tokenByAddress);
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
@@ -309,7 +313,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderEthWrapper() {
+    private _renderEthWrapper(): React.ReactNode {
         return (
             <div>
                 <Title labelText={'Wrapped ETH'} />
@@ -325,7 +329,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderTradeHistory() {
+    private _renderTradeHistory(): React.ReactNode {
         return (
             <div>
                 <Title labelText={'Trade History'} />
@@ -337,7 +341,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderTradeDirect(match: any, location: Location, history: History) {
+    private _renderTradeDirect(match: any, location: Location, history: History): React.ReactNode {
         return (
             <div>
                 <Title labelText={'Trade Direct'} />
@@ -349,7 +353,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderTokenBalances() {
+    private _renderTokenBalances(): React.ReactNode {
         const allTokens = _.values(this.props.tokenByAddress);
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
@@ -371,7 +375,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
-    private _renderRelayerIndex() {
+    private _renderRelayerIndex(): React.ReactNode {
         return (
             <div>
                 <Title labelText={'Explore 0x Relayers'} />
diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index ff7127604..b7c3d5229 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -239,9 +239,8 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
         const userAddress = this.props.userAddress;
         const primaryText = utils.getAddressBeginAndEnd(userAddress);
         return (
-            <Link to={`${WebsitePaths.Portal}/account`} style={{ textDecoration: 'none' }}>
+            <Link key={HEADER_ITEM_KEY} to={`${WebsitePaths.Portal}/account`} style={{ textDecoration: 'none' }}>
                 <ListItem
-                    key={HEADER_ITEM_KEY}
                     primaryText={primaryText}
                     leftIcon={<Identicon address={userAddress} diameter={ICON_DIMENSION} />}
                     style={{ ...styles.paddedItem, ...styles.borderedItem }}
-- 
cgit 


From e0482f5400261bcaced8ea2263b1032939d25b92 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Mon, 14 May 2018 22:11:12 -0700
Subject: Wait for blockchain to display the account management routes

---
 packages/website/ts/components/portal/portal.tsx   | 48 +++++++++++++++-------
 .../ts/components/relayer_index/relayer_index.tsx  |  4 +-
 packages/website/ts/pages/fullscreen_message.tsx   | 30 ++++++++++++++
 packages/website/ts/pages/not_found.tsx            | 43 ++++++-------------
 4 files changed, 78 insertions(+), 47 deletions(-)
 create mode 100644 packages/website/ts/pages/fullscreen_message.tsx

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index f3b0cc721..bdaf9b18e 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -1,6 +1,7 @@
 import { colors, Styles } from '@0xproject/react-shared';
 import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
+import CircularProgress from 'material-ui/CircularProgress';
 import * as React from 'react';
 import * as DocumentTitle from 'react-document-title';
 import { Link, Route, RouteComponentProps, Switch } from 'react-router-dom';
@@ -22,6 +23,7 @@ import { Wallet } from 'ts/components/wallet/wallet';
 import { GenerateOrderForm } from 'ts/containers/generate_order_form';
 import { localStorage } from 'ts/local_storage/local_storage';
 import { trackedTokenStorage } from 'ts/local_storage/tracked_token_storage';
+import { FullscreenMessage } from 'ts/pages/fullscreen_message';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import {
     BlockchainErrs,
@@ -218,20 +220,8 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                         <div className="flex-auto px3" style={styles.scrollContainer}>
                             <Switch>
                                 <Route
-                                    path={`${WebsitePaths.Portal}/weth`}
-                                    render={this._renderEthWrapper.bind(this)}
-                                />
-                                <Route
-                                    path={`${WebsitePaths.Portal}/account`}
-                                    render={this._renderTokenBalances.bind(this)}
-                                />
-                                <Route
-                                    path={`${WebsitePaths.Portal}/trades`}
-                                    render={this._renderTradeHistory.bind(this)}
-                                />
-                                <Route
-                                    path={`${WebsitePaths.Portal}/direct`}
-                                    render={this._renderTradeDirect.bind(this)}
+                                    path={`${WebsitePaths.Portal}/:route`}
+                                    render={this._renderAccountManagement.bind(this)}
                                 />
                                 <Route
                                     exact={true}
@@ -313,6 +303,28 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
+    private _renderAccountManagement(): React.ReactNode {
+        return this.props.blockchainIsLoaded ? (
+            <Switch>
+                <Route path={`${WebsitePaths.Portal}/weth`} render={this._renderEthWrapper.bind(this)} />
+                <Route path={`${WebsitePaths.Portal}/account`} render={this._renderTokenBalances.bind(this)} />
+                <Route path={`${WebsitePaths.Portal}/trades`} render={this._renderTradeHistory.bind(this)} />
+                <Route path={`${WebsitePaths.Portal}/direct`} render={this._renderTradeDirect.bind(this)} />
+                <Route render={this._renderNotFoundMessage.bind(this)} />
+            </Switch>
+        ) : (
+            <div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
+                <div
+                    className="relative sm-px2 sm-pt2 sm-m1"
+                    style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
+                >
+                    <div className="center pb2">
+                        <CircularProgress size={40} thickness={5} />
+                    </div>
+                </div>
+            </div>
+        );
+    }
     private _renderEthWrapper(): React.ReactNode {
         return (
             <div>
@@ -383,6 +395,14 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
+    private _renderNotFoundMessage(): React.ReactNode {
+        return (
+            <FullscreenMessage
+                headerText={'404 Not Found'}
+                bodyText={"Hm... looks like we couldn't find what you are looking for."}
+            />
+        );
+    }
     private _onTokenChosen(tokenAddress: string): void {
         if (_.isEmpty(tokenAddress)) {
             this.setState({
diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx
index d4fd6aeaf..9eaf9fe03 100644
--- a/packages/website/ts/components/relayer_index/relayer_index.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_index.tsx
@@ -59,10 +59,10 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
         const readyToRender = _.isUndefined(this.state.error) && !_.isUndefined(this.state.relayerInfos);
         if (!readyToRender) {
             return (
-                <div className="col col-12" style={{ ...styles.root, height: '100%' }}>
+                <div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
                     <div
                         className="relative sm-px2 sm-pt2 sm-m1"
-                        style={{ height: 122, top: '33%', transform: 'translateY(-50%)' }}
+                        style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
                     >
                         <div className="center pb2">
                             {_.isUndefined(this.state.error) ? (
diff --git a/packages/website/ts/pages/fullscreen_message.tsx b/packages/website/ts/pages/fullscreen_message.tsx
new file mode 100644
index 000000000..141fb38a4
--- /dev/null
+++ b/packages/website/ts/pages/fullscreen_message.tsx
@@ -0,0 +1,30 @@
+import { Styles } from '@0xproject/react-shared';
+import * as React from 'react';
+
+export interface FullscreenMessageProps {
+    headerText: string;
+    bodyText: string;
+}
+
+const styles: Styles = {
+    thin: {
+        fontWeight: 100,
+    },
+};
+
+export const FullscreenMessage = (props: FullscreenMessageProps) => {
+    return (
+        <div className="mx-auto max-width-4 py4">
+            <div className="center py4">
+                <div className="py4">
+                    <div className="py4">
+                        <h1 style={{ ...styles.thin }}>{props.headerText}</h1>
+                        <div className="py1">
+                            <div className="py3">{props.bodyText}</div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    );
+};
diff --git a/packages/website/ts/pages/not_found.tsx b/packages/website/ts/pages/not_found.tsx
index 96c73d4ec..674271636 100644
--- a/packages/website/ts/pages/not_found.tsx
+++ b/packages/website/ts/pages/not_found.tsx
@@ -3,6 +3,7 @@ import * as _ from 'lodash';
 import * as React from 'react';
 import { Footer } from 'ts/components/footer';
 import { TopBar } from 'ts/components/top_bar/top_bar';
+import { FullscreenMessage } from 'ts/pages/fullscreen_message';
 import { Dispatcher } from 'ts/redux/dispatcher';
 import { Translate } from 'ts/utils/translate';
 
@@ -12,35 +13,15 @@ export interface NotFoundProps {
     dispatcher: Dispatcher;
 }
 
-interface NotFoundState {}
-
-const styles: Styles = {
-    thin: {
-        fontWeight: 100,
-    },
+export const NotFound = (props: NotFoundProps) => {
+    return (
+        <div>
+            <TopBar blockchainIsLoaded={false} location={this.props.location} translate={this.props.translate} />
+            <FullscreenMessage
+                headerText={'404 Not Found'}
+                bodyText={"Hm... looks like we couldn't find what you are looking for."}
+            />
+            <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} />
+        </div>
+    );
 };
-
-export class NotFound extends React.Component<NotFoundProps, NotFoundState> {
-    public render(): React.ReactNode {
-        return (
-            <div>
-                <TopBar blockchainIsLoaded={false} location={this.props.location} translate={this.props.translate} />
-                <div className="mx-auto max-width-4 py4">
-                    <div className="center py4">
-                        <div className="py4">
-                            <div className="py4">
-                                <h1 style={{ ...styles.thin }}>404 Not Found</h1>
-                                <div className="py1">
-                                    <div className="py3">
-                                        Hm... looks like we couldn't find what you are looking for.
-                                    </div>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-                <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} />
-            </div>
-        );
-    }
-}
-- 
cgit 


From 09692dc70e914a62c18bf33bfee4d01fcb55713e Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Tue, 15 May 2018 11:44:05 -0700
Subject: Fix comments

---
 packages/website/ts/components/portal/portal.tsx               | 9 ++++++---
 packages/website/ts/components/portal/portal_menu.tsx          | 4 +++-
 packages/website/ts/components/relayer_index/relayer_index.tsx | 1 +
 3 files changed, 10 insertions(+), 4 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index bdaf9b18e..cb4e24654 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -11,7 +11,6 @@ import { BlockchainErrDialog } from 'ts/components/dialogs/blockchain_err_dialog
 import { LedgerConfigDialog } from 'ts/components/dialogs/ledger_config_dialog';
 import { PortalDisclaimerDialog } from 'ts/components/dialogs/portal_disclaimer_dialog';
 import { EthWrappers } from 'ts/components/eth_wrappers';
-import { FillOrder } from 'ts/components/fill_order';
 import { AssetPicker } from 'ts/components/generate_order/asset_picker';
 import { PortalMenu } from 'ts/components/portal/portal_menu';
 import { RelayerIndex } from 'ts/components/relayer_index/relayer_index';
@@ -81,6 +80,7 @@ enum TokenManagementState {
 const THROTTLE_TIMEOUT = 100;
 const TOP_BAR_HEIGHT = TopBar.heightForDisplayType(TopBarDisplayType.Expanded);
 const BACK_BUTTON_HEIGHT = 28;
+const LEFT_COLUMN_WIDTH = 346;
 
 const styles: Styles = {
     root: {
@@ -91,6 +91,9 @@ const styles: Styles = {
     body: {
         height: `calc(100vh - ${TOP_BAR_HEIGHT}px)`,
     },
+    leftColumn: {
+        width: LEFT_COLUMN_WIDTH,
+    },
     scrollContainer: {
         height: `calc(100vh - ${TOP_BAR_HEIGHT}px)`,
         WebkitOverflowScrolling: 'touch',
@@ -114,7 +117,6 @@ const styles: Styles = {
 
 export class Portal extends React.Component<PortalProps, PortalState> {
     private _blockchain: Blockchain;
-    private _sharedOrderIfExists: Order;
     private _throttledScreenWidthUpdate: () => void;
     constructor(props: PortalProps) {
         super(props);
@@ -203,7 +205,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                 <div id="portal" style={styles.body}>
                     <div className="sm-flex flex-center">
                         <div className="flex-last px3">
-                            <div style={{ width: 346 }}>
+                            <div style={styles.leftColumn}>
                                 <Switch>
                                     <Route
                                         path={`${WebsitePaths.Portal}/:route`}
@@ -313,6 +315,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                 <Route render={this._renderNotFoundMessage.bind(this)} />
             </Switch>
         ) : (
+            // TODO: consolidate this loading component with the one in relayer_index
             <div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
                 <div
                     className="relative sm-px2 sm-pt2 sm-m1"
diff --git a/packages/website/ts/components/portal/portal_menu.tsx b/packages/website/ts/components/portal/portal_menu.tsx
index c8e2dacfa..dc8f01d41 100644
--- a/packages/website/ts/components/portal/portal_menu.tsx
+++ b/packages/website/ts/components/portal/portal_menu.tsx
@@ -42,9 +42,11 @@ const DEFAULT_LABEL_COLOR = colors.darkerGrey;
 const DEFAULT_ICON_COLOR = colors.darkerGrey;
 const SELECTED_ICON_COLOR = colors.yellow900;
 
+const LEFT_PADDING = 185;
+
 export const PortalMenu: React.StatelessComponent<PortalMenuProps> = (props: PortalMenuProps) => {
     return (
-        <div style={{ paddingLeft: 185 }}>
+        <div style={{ paddingLeft: LEFT_PADDING }}>
             {_.map(menuItemEntries, entry => {
                 const selected = entry.to === props.selectedPath;
                 return (
diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx
index 9eaf9fe03..5ab2e8c17 100644
--- a/packages/website/ts/components/relayer_index/relayer_index.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_index.tsx
@@ -59,6 +59,7 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
         const readyToRender = _.isUndefined(this.state.error) && !_.isUndefined(this.state.relayerInfos);
         if (!readyToRender) {
             return (
+                // TODO: consolidate this loading component with the one in portal
                 <div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
                     <div
                         className="relative sm-px2 sm-pt2 sm-m1"
-- 
cgit 


From 6a0cda7396573ac900d948d2427f93a740ca48a0 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Tue, 15 May 2018 11:45:02 -0700
Subject: Fix lint error

---
 packages/website/ts/components/wallet/wallet.tsx | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index b7c3d5229..818cff05b 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -314,8 +314,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
                         primaryText={
                             <div className="flex right" style={{ color: colors.mediumBlue, fontWeight: 'bold' }}>
                                 {'manage your wallet'}
-                            </div>
-                        }
+                            </div>}
                         style={{ ...styles.paddedItem, ...styles.borderedItem }}
                     />
                 </Link>
-- 
cgit 


From b6776f53ab3031a60eaaabffefc73d1e6d6f3d7c Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Wed, 16 May 2018 12:10:36 -0700
Subject: Get rid of extra curly brackets

---
 packages/website/ts/components/portal/portal.tsx | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index cb4e24654..aa4392935 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -274,7 +274,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     private _renderMenu(routeComponentProps: RouteComponentProps<any>): React.ReactNode {
         return (
             <div>
-                <BackButton to={`${WebsitePaths.Portal}`} labelText={'back to Relayers'} />
+                <BackButton to={`${WebsitePaths.Portal}`} labelText="back to Relayers" />
                 <PortalMenu selectedPath={routeComponentProps.location.pathname} />
             </div>
         );
@@ -284,7 +284,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
             <div>
-                <Title labelText={'Your Account'} />
+                <Title labelText="Your Account" />
                 <Wallet
                     userAddress={this.props.userAddress}
                     networkId={this.props.networkId}
@@ -331,7 +331,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     private _renderEthWrapper(): React.ReactNode {
         return (
             <div>
-                <Title labelText={'Wrapped ETH'} />
+                <Title labelText="Wrapped ETH" />
                 <EthWrappers
                     networkId={this.props.networkId}
                     blockchain={this._blockchain}
@@ -347,7 +347,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     private _renderTradeHistory(): React.ReactNode {
         return (
             <div>
-                <Title labelText={'Trade History'} />
+                <Title labelText="Trade History" />
                 <TradeHistory
                     tokenByAddress={this.props.tokenByAddress}
                     userAddress={this.props.userAddress}
@@ -359,7 +359,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     private _renderTradeDirect(match: any, location: Location, history: History): React.ReactNode {
         return (
             <div>
-                <Title labelText={'Trade Direct'} />
+                <Title labelText="Trade Direct" />
                 <GenerateOrderForm
                     blockchain={this._blockchain}
                     hashData={this.props.hashData}
@@ -373,7 +373,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
             <div>
-                <Title labelText={'Your Account'} />
+                <Title labelText="Your Account" />
                 <TokenBalances
                     blockchain={this._blockchain}
                     blockchainErr={this.props.blockchainErr}
@@ -393,7 +393,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     private _renderRelayerIndex(): React.ReactNode {
         return (
             <div>
-                <Title labelText={'Explore 0x Relayers'} />
+                <Title labelText="Explore 0x Relayers" />
                 <RelayerIndex networkId={this.props.networkId} />
             </div>
         );
@@ -401,8 +401,8 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     private _renderNotFoundMessage(): React.ReactNode {
         return (
             <FullscreenMessage
-                headerText={'404 Not Found'}
-                bodyText={"Hm... looks like we couldn't find what you are looking for."}
+                headerText="404 Not Found"
+                bodyText="Hm... looks like we couldn't find what you are looking for."
             />
         );
     }
-- 
cgit 


From 63e7391981fca437efba221ff4babdb9d6fdac5b Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Wed, 16 May 2018 13:47:50 -0700
Subject: Add portal layout component

---
 packages/website/ts/components/portal/portal.tsx | 67 +++++++++++++-----------
 1 file changed, 36 insertions(+), 31 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index aa4392935..ce7911e10 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -105,6 +105,7 @@ const styles: Styles = {
     },
     backButton: {
         height: BACK_BUTTON_HEIGHT,
+        paddingTop: 10,
         backgroundColor: colors.white,
         borderRadius: BACK_BUTTON_HEIGHT,
         boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`,
@@ -203,36 +204,17 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                     style={{ backgroundColor: colors.lightestGrey }}
                 />
                 <div id="portal" style={styles.body}>
-                    <div className="sm-flex flex-center">
-                        <div className="flex-last px3">
-                            <div style={styles.leftColumn}>
-                                <Switch>
-                                    <Route
-                                        path={`${WebsitePaths.Portal}/:route`}
-                                        render={this._renderMenu.bind(this)}
-                                    />
-                                    <Route
-                                        exact={true}
-                                        path={`${WebsitePaths.Portal}`}
-                                        render={this._renderWallet.bind(this)}
-                                    />
-                                </Switch>
-                            </div>
-                        </div>
-                        <div className="flex-auto px3" style={styles.scrollContainer}>
-                            <Switch>
-                                <Route
-                                    path={`${WebsitePaths.Portal}/:route`}
-                                    render={this._renderAccountManagement.bind(this)}
-                                />
-                                <Route
-                                    exact={true}
-                                    path={`${WebsitePaths.Portal}/`}
-                                    render={this._renderRelayerIndex.bind(this)}
-                                />
-                            </Switch>
-                        </div>
-                    </div>
+                    <Switch>
+                        <Route
+                            path={`${WebsitePaths.Portal}/:route`}
+                            render={this._renderMenuAndAccountManagement.bind(this)}
+                        />
+                        <Route
+                            exact={true}
+                            path={`${WebsitePaths.Portal}/`}
+                            render={this._renderWalletAndRelayerIndex.bind(this)}
+                        />
+                    </Switch>
                     <BlockchainErrDialog
                         blockchain={this._blockchain}
                         blockchainErr={this.props.blockchainErr}
@@ -271,6 +253,12 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             </div>
         );
     }
+    private _renderWalletAndRelayerIndex(): React.ReactNode {
+        return <PortalLayout left={this._renderWallet()} right={this._renderRelayerIndex()} />;
+    }
+    private _renderMenuAndAccountManagement(routeComponentProps: RouteComponentProps<any>): React.ReactNode {
+        return <PortalLayout left={this._renderMenu(routeComponentProps)} right={this._renderAccountManagement()} />;
+    }
     private _renderMenu(routeComponentProps: RouteComponentProps<any>): React.ReactNode {
         return (
             <div>
@@ -480,7 +468,7 @@ 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, paddingTop: 10 }}>
+                <div className="flex right" style={styles.backButton}>
                     <div style={{ marginLeft: 12 }}>
                         <i style={styles.backButtonIcon} className={`zmdi zmdi-arrow-left`} />
                     </div>
@@ -492,3 +480,20 @@ const BackButton = (props: BackButtonProps) => {
         </div>
     );
 };
+
+interface PortalLayoutProps {
+    left: React.ReactNode;
+    right: React.ReactNode;
+}
+const PortalLayout = (props: PortalLayoutProps) => {
+    return (
+        <div className="sm-flex flex-center">
+            <div className="flex-last px3">
+                <div style={styles.leftColumn}>{props.left}</div>
+            </div>
+            <div className="flex-auto px3" style={styles.scrollContainer}>
+                {props.right}
+            </div>
+        </div>
+    );
+};
-- 
cgit 


From 00515eb6f96c44387575fbae6f527c3661e84f43 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Wed, 16 May 2018 16:47:04 -0700
Subject: Refactor a bunch of layouts into their own files

---
 .../website/ts/components/portal/back_button.tsx   |  41 ++++
 packages/website/ts/components/portal/menu.tsx     |  88 +++++++++
 packages/website/ts/components/portal/portal.tsx   | 209 +++++++++------------
 .../website/ts/components/portal/portal_menu.tsx   |  88 ---------
 packages/website/ts/components/portal/section.tsx  |  15 ++
 .../website/ts/components/portal/text_header.tsx   |  21 +++
 .../ts/components/relayer_index/relayer_index.tsx  |  19 +-
 7 files changed, 259 insertions(+), 222 deletions(-)
 create mode 100644 packages/website/ts/components/portal/back_button.tsx
 create mode 100644 packages/website/ts/components/portal/menu.tsx
 delete mode 100644 packages/website/ts/components/portal/portal_menu.tsx
 create mode 100644 packages/website/ts/components/portal/section.tsx
 create mode 100644 packages/website/ts/components/portal/text_header.tsx

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/back_button.tsx b/packages/website/ts/components/portal/back_button.tsx
new file mode 100644
index 000000000..68934f88e
--- /dev/null
+++ b/packages/website/ts/components/portal/back_button.tsx
@@ -0,0 +1,41 @@
+import { colors, Styles } from '@0xproject/react-shared';
+import * as React from 'react';
+import { Link } from 'react-router-dom';
+
+export interface BackButtonProps {
+    to: string;
+    labelText: string;
+}
+
+const BACK_BUTTON_HEIGHT = 28;
+
+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,
+        fontSize: 20,
+    },
+};
+
+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}>
+                    <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>
+            </Link>
+        </div>
+    );
+};
diff --git a/packages/website/ts/components/portal/menu.tsx b/packages/website/ts/components/portal/menu.tsx
new file mode 100644
index 000000000..9014d8d42
--- /dev/null
+++ b/packages/website/ts/components/portal/menu.tsx
@@ -0,0 +1,88 @@
+import { colors, Styles } from '@0xproject/react-shared';
+import * as _ from 'lodash';
+import * as React from 'react';
+import { MenuItem } from 'ts/components/ui/menu_item';
+import { Environments, WebsitePaths } from 'ts/types';
+import { configs } from 'ts/utils/configs';
+
+export interface MenuProps {
+    selectedPath?: string;
+}
+
+interface MenuItemEntry {
+    to: string;
+    labelText: string;
+    iconName: string;
+}
+
+const menuItemEntries: MenuItemEntry[] = [
+    {
+        to: `${WebsitePaths.Portal}/account`,
+        labelText: 'Account overview',
+        iconName: 'zmdi-balance-wallet',
+    },
+    {
+        to: `${WebsitePaths.Portal}/trades`,
+        labelText: 'Trade history',
+        iconName: 'zmdi-format-list-bulleted',
+    },
+    {
+        to: `${WebsitePaths.Portal}/weth`,
+        labelText: 'Wrapped ETH',
+        iconName: 'zmdi-circle-o',
+    },
+    {
+        to: `${WebsitePaths.Portal}/direct`,
+        labelText: 'Trade direct',
+        iconName: 'zmdi-swap',
+    },
+];
+
+const DEFAULT_LABEL_COLOR = colors.darkerGrey;
+const DEFAULT_ICON_COLOR = colors.darkerGrey;
+const SELECTED_ICON_COLOR = colors.yellow900;
+
+const LEFT_PADDING = 185;
+
+export const Menu: React.StatelessComponent<MenuProps> = (props: MenuProps) => {
+    return (
+        <div style={{ paddingLeft: LEFT_PADDING }}>
+            {_.map(menuItemEntries, entry => {
+                const selected = entry.to === props.selectedPath;
+                return (
+                    <MenuItem key={entry.to} className="py2" to={entry.to}>
+                        <MenuItemLabel title={entry.labelText} iconName={entry.iconName} selected={selected} />
+                    </MenuItem>
+                );
+            })}
+        </div>
+    );
+};
+
+interface MenuItemLabelProps {
+    title: string;
+    iconName: string;
+    selected: boolean;
+}
+const MenuItemLabel: React.StatelessComponent<MenuItemLabelProps> = (props: MenuItemLabelProps) => {
+    const styles: Styles = {
+        iconStyle: {
+            color: props.selected ? SELECTED_ICON_COLOR : DEFAULT_ICON_COLOR,
+            fontSize: 20,
+        },
+        textStyle: {
+            color: DEFAULT_LABEL_COLOR,
+            fontWeight: props.selected ? 'bold' : 'normal',
+        },
+    };
+    return (
+        <div className="flex">
+            <div className="pr1">
+                <i style={styles.iconStyle} className={`zmdi ${props.iconName}`} />
+            </div>
+            <div className="pl1" style={styles.textStyle}>
+                {props.title}
+            </div>
+        </div>
+    );
+};
diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index ce7911e10..81afe57e5 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -12,7 +12,10 @@ import { LedgerConfigDialog } from 'ts/components/dialogs/ledger_config_dialog';
 import { PortalDisclaimerDialog } from 'ts/components/dialogs/portal_disclaimer_dialog';
 import { EthWrappers } from 'ts/components/eth_wrappers';
 import { AssetPicker } from 'ts/components/generate_order/asset_picker';
-import { PortalMenu } from 'ts/components/portal/portal_menu';
+import { BackButton } from 'ts/components/portal/back_button';
+import { Menu } from 'ts/components/portal/menu';
+import { Section } from 'ts/components/portal/section';
+import { TextHeader } from 'ts/components/portal/text_header';
 import { RelayerIndex } from 'ts/components/relayer_index/relayer_index';
 import { TokenBalances } from 'ts/components/token_balances';
 import { TopBar, TopBarDisplayType } from 'ts/components/top_bar/top_bar';
@@ -79,7 +82,6 @@ enum TokenManagementState {
 
 const THROTTLE_TIMEOUT = 100;
 const TOP_BAR_HEIGHT = TopBar.heightForDisplayType(TopBarDisplayType.Expanded);
-const BACK_BUTTON_HEIGHT = 28;
 const LEFT_COLUMN_WIDTH = 346;
 
 const styles: Styles = {
@@ -99,21 +101,6 @@ const styles: Styles = {
         WebkitOverflowScrolling: 'touch',
         overflow: 'auto',
     },
-    title: {
-        fontWeight: 'bold',
-        fontSize: 20,
-    },
-    backButton: {
-        height: BACK_BUTTON_HEIGHT,
-        paddingTop: 10,
-        backgroundColor: colors.white,
-        borderRadius: BACK_BUTTON_HEIGHT,
-        boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`,
-    },
-    backButtonIcon: {
-        color: colors.mediumBlue,
-        fontSize: 20,
-    },
 };
 
 export class Portal extends React.Component<PortalProps, PortalState> {
@@ -261,36 +248,38 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     }
     private _renderMenu(routeComponentProps: RouteComponentProps<any>): React.ReactNode {
         return (
-            <div>
-                <BackButton to={`${WebsitePaths.Portal}`} labelText="back to Relayers" />
-                <PortalMenu selectedPath={routeComponentProps.location.pathname} />
-            </div>
+            <Section
+                header={<BackButton to={`${WebsitePaths.Portal}`} labelText="back to Relayers" />}
+                body={<Menu selectedPath={routeComponentProps.location.pathname} />}
+            />
         );
     }
     private _renderWallet(): React.ReactNode {
         const allTokens = _.values(this.props.tokenByAddress);
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
-            <div>
-                <Title labelText="Your Account" />
-                <Wallet
-                    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={trackedTokens}
-                    userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                    lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-                    injectedProviderName={this.props.injectedProviderName}
-                    providerType={this.props.providerType}
-                    onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
-                    onAddToken={this._onAddToken.bind(this)}
-                    onRemoveToken={this._onRemoveToken.bind(this)}
-                />
-            </div>
+            <Section
+                header={<TextHeader labelText="Your Account" />}
+                body={
+                    <Wallet
+                        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={trackedTokens}
+                        userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                        lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                        injectedProviderName={this.props.injectedProviderName}
+                        providerType={this.props.providerType}
+                        onToggleLedgerDialog={this._onToggleLedgerDialog.bind(this)}
+                        onAddToken={this._onAddToken.bind(this)}
+                        onRemoveToken={this._onRemoveToken.bind(this)}
+                    />
+                }
+            />
         );
     }
     private _renderAccountManagement(): React.ReactNode {
@@ -318,72 +307,80 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     }
     private _renderEthWrapper(): React.ReactNode {
         return (
-            <div>
-                <Title labelText="Wrapped ETH" />
-                <EthWrappers
-                    networkId={this.props.networkId}
-                    blockchain={this._blockchain}
-                    dispatcher={this.props.dispatcher}
-                    tokenByAddress={this.props.tokenByAddress}
-                    userAddress={this.props.userAddress}
-                    userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                    lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-                />
-            </div>
+            <Section
+                header={<TextHeader labelText="Wrapped ETH" />}
+                body={
+                    <EthWrappers
+                        networkId={this.props.networkId}
+                        blockchain={this._blockchain}
+                        dispatcher={this.props.dispatcher}
+                        tokenByAddress={this.props.tokenByAddress}
+                        userAddress={this.props.userAddress}
+                        userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                        lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                    />
+                }
+            />
         );
     }
     private _renderTradeHistory(): React.ReactNode {
         return (
-            <div>
-                <Title labelText="Trade History" />
-                <TradeHistory
-                    tokenByAddress={this.props.tokenByAddress}
-                    userAddress={this.props.userAddress}
-                    networkId={this.props.networkId}
-                />
-            </div>
+            <Section
+                header={<TextHeader labelText="Trade History" />}
+                body={
+                    <TradeHistory
+                        tokenByAddress={this.props.tokenByAddress}
+                        userAddress={this.props.userAddress}
+                        networkId={this.props.networkId}
+                    />
+                }
+            />
         );
     }
     private _renderTradeDirect(match: any, location: Location, history: History): React.ReactNode {
         return (
-            <div>
-                <Title labelText="Trade Direct" />
-                <GenerateOrderForm
-                    blockchain={this._blockchain}
-                    hashData={this.props.hashData}
-                    dispatcher={this.props.dispatcher}
-                />
-            </div>
+            <Section
+                header={<TextHeader labelText="Trade Direct" />}
+                body={
+                    <GenerateOrderForm
+                        blockchain={this._blockchain}
+                        hashData={this.props.hashData}
+                        dispatcher={this.props.dispatcher}
+                    />
+                }
+            />
         );
     }
     private _renderTokenBalances(): React.ReactNode {
         const allTokens = _.values(this.props.tokenByAddress);
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
-            <div>
-                <Title labelText="Your Account" />
-                <TokenBalances
-                    blockchain={this._blockchain}
-                    blockchainErr={this.props.blockchainErr}
-                    blockchainIsLoaded={this.props.blockchainIsLoaded}
-                    dispatcher={this.props.dispatcher}
-                    screenWidth={this.props.screenWidth}
-                    tokenByAddress={this.props.tokenByAddress}
-                    trackedTokens={trackedTokens}
-                    userAddress={this.props.userAddress}
-                    userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                    networkId={this.props.networkId}
-                    lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-                />
-            </div>
+            <Section
+                header={<TextHeader labelText="Your Account" />}
+                body={
+                    <TokenBalances
+                        blockchain={this._blockchain}
+                        blockchainErr={this.props.blockchainErr}
+                        blockchainIsLoaded={this.props.blockchainIsLoaded}
+                        dispatcher={this.props.dispatcher}
+                        screenWidth={this.props.screenWidth}
+                        tokenByAddress={this.props.tokenByAddress}
+                        trackedTokens={trackedTokens}
+                        userAddress={this.props.userAddress}
+                        userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                        networkId={this.props.networkId}
+                        lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                    />
+                }
+            />
         );
     }
     private _renderRelayerIndex(): React.ReactNode {
         return (
-            <div>
-                <Title labelText="Explore 0x Relayers" />
-                <RelayerIndex networkId={this.props.networkId} />
-            </div>
+            <Section
+                header={<TextHeader labelText="Explore 0x Relayers" />}
+                body={<RelayerIndex networkId={this.props.networkId} />}
+            />
         );
     }
     private _renderNotFoundMessage(): React.ReactNode {
@@ -449,38 +446,6 @@ export class Portal extends React.Component<PortalProps, PortalState> {
     }
 }
 
-interface TitleProps {
-    labelText: string;
-}
-const Title = (props: TitleProps) => {
-    return (
-        <div className="py3" style={styles.title}>
-            {props.labelText}
-        </div>
-    );
-};
-
-interface BackButtonProps {
-    to: string;
-    labelText: string;
-}
-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}>
-                    <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>
-            </Link>
-        </div>
-    );
-};
-
 interface PortalLayoutProps {
     left: React.ReactNode;
     right: React.ReactNode;
@@ -496,4 +461,4 @@ const PortalLayout = (props: PortalLayoutProps) => {
             </div>
         </div>
     );
-};
+}; // tslint:disable:max-file-line-count
diff --git a/packages/website/ts/components/portal/portal_menu.tsx b/packages/website/ts/components/portal/portal_menu.tsx
deleted file mode 100644
index dc8f01d41..000000000
--- a/packages/website/ts/components/portal/portal_menu.tsx
+++ /dev/null
@@ -1,88 +0,0 @@
-import { colors, Styles } from '@0xproject/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-import { MenuItem } from 'ts/components/ui/menu_item';
-import { Environments, WebsitePaths } from 'ts/types';
-import { configs } from 'ts/utils/configs';
-
-export interface PortalMenuProps {
-    selectedPath?: string;
-}
-
-interface MenuItemEntry {
-    to: string;
-    labelText: string;
-    iconName: string;
-}
-
-const menuItemEntries: MenuItemEntry[] = [
-    {
-        to: `${WebsitePaths.Portal}/account`,
-        labelText: 'Account overview',
-        iconName: 'zmdi-balance-wallet',
-    },
-    {
-        to: `${WebsitePaths.Portal}/trades`,
-        labelText: 'Trade history',
-        iconName: 'zmdi-format-list-bulleted',
-    },
-    {
-        to: `${WebsitePaths.Portal}/weth`,
-        labelText: 'Wrapped ETH',
-        iconName: 'zmdi-circle-o',
-    },
-    {
-        to: `${WebsitePaths.Portal}/direct`,
-        labelText: 'Trade direct',
-        iconName: 'zmdi-swap',
-    },
-];
-
-const DEFAULT_LABEL_COLOR = colors.darkerGrey;
-const DEFAULT_ICON_COLOR = colors.darkerGrey;
-const SELECTED_ICON_COLOR = colors.yellow900;
-
-const LEFT_PADDING = 185;
-
-export const PortalMenu: React.StatelessComponent<PortalMenuProps> = (props: PortalMenuProps) => {
-    return (
-        <div style={{ paddingLeft: LEFT_PADDING }}>
-            {_.map(menuItemEntries, entry => {
-                const selected = entry.to === props.selectedPath;
-                return (
-                    <MenuItem key={entry.to} className="py2" to={entry.to}>
-                        <PortalMenuItemLabel title={entry.labelText} iconName={entry.iconName} selected={selected} />
-                    </MenuItem>
-                );
-            })}
-        </div>
-    );
-};
-
-interface PortalMenuItemLabelProps {
-    title: string;
-    iconName: string;
-    selected: boolean;
-}
-const PortalMenuItemLabel: React.StatelessComponent<PortalMenuItemLabelProps> = (props: PortalMenuItemLabelProps) => {
-    const styles: Styles = {
-        iconStyle: {
-            color: props.selected ? SELECTED_ICON_COLOR : DEFAULT_ICON_COLOR,
-            fontSize: 20,
-        },
-        textStyle: {
-            color: DEFAULT_LABEL_COLOR,
-            fontWeight: props.selected ? 'bold' : 'normal',
-        },
-    };
-    return (
-        <div className="flex">
-            <div className="pr1">
-                <i style={styles.iconStyle} className={`zmdi ${props.iconName}`} />
-            </div>
-            <div className="pl1" style={styles.textStyle}>
-                {props.title}
-            </div>
-        </div>
-    );
-};
diff --git a/packages/website/ts/components/portal/section.tsx b/packages/website/ts/components/portal/section.tsx
new file mode 100644
index 000000000..9b172aae0
--- /dev/null
+++ b/packages/website/ts/components/portal/section.tsx
@@ -0,0 +1,15 @@
+import { Styles } from '@0xproject/react-shared';
+import * as React from 'react';
+
+export interface SectionProps {
+    header: React.ReactNode;
+    body: React.ReactNode;
+}
+export const Section = (props: SectionProps) => {
+    return (
+        <div className="flex flex-column" style={{ height: '100%' }}>
+            {props.header}
+            <div className="flex-auto">{props.body}</div>
+        </div>
+    );
+};
diff --git a/packages/website/ts/components/portal/text_header.tsx b/packages/website/ts/components/portal/text_header.tsx
new file mode 100644
index 000000000..4aabd47d0
--- /dev/null
+++ b/packages/website/ts/components/portal/text_header.tsx
@@ -0,0 +1,21 @@
+import { Styles } from '@0xproject/react-shared';
+import * as React from 'react';
+
+export interface TextHeaderProps {
+    labelText: string;
+}
+
+const styles: Styles = {
+    title: {
+        fontWeight: 'bold',
+        fontSize: 20,
+    },
+};
+
+export const TextHeader = (props: TextHeaderProps) => {
+    return (
+        <div className="py3" style={styles.title}>
+            {props.labelText}
+        </div>
+    );
+};
diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx
index 5ab2e8c17..d8b06010b 100644
--- a/packages/website/ts/components/relayer_index/relayer_index.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_index.tsx
@@ -60,18 +60,13 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
         if (!readyToRender) {
             return (
                 // TODO: consolidate this loading component with the one in portal
-                <div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
-                    <div
-                        className="relative sm-px2 sm-pt2 sm-m1"
-                        style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
-                    >
-                        <div className="center pb2">
-                            {_.isUndefined(this.state.error) ? (
-                                <CircularProgress size={40} thickness={5} />
-                            ) : (
-                                <Retry onRetry={this._fetchRelayerInfosAsync.bind(this)} />
-                            )}
-                        </div>
+                <div style={styles.root}>
+                    <div className="center">
+                        {_.isUndefined(this.state.error) ? (
+                            <CircularProgress size={40} thickness={5} />
+                        ) : (
+                            <Retry onRetry={this._fetchRelayerInfosAsync.bind(this)} />
+                        )}
                     </div>
                 </div>
             );
-- 
cgit 


From 48b0b5481982b378277e517380cdd343773c7c64 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Wed, 16 May 2018 17:23:39 -0700
Subject: Add loading component

---
 packages/website/ts/components/portal/loading.tsx  | 21 +++++
 packages/website/ts/components/portal/portal.tsx   | 92 ++++++++++++----------
 .../ts/components/relayer_index/relayer_index.tsx  | 14 ++--
 3 files changed, 77 insertions(+), 50 deletions(-)
 create mode 100644 packages/website/ts/components/portal/loading.tsx

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/loading.tsx b/packages/website/ts/components/portal/loading.tsx
new file mode 100644
index 000000000..d804dd1b8
--- /dev/null
+++ b/packages/website/ts/components/portal/loading.tsx
@@ -0,0 +1,21 @@
+import CircularProgress from 'material-ui/CircularProgress';
+import * as React from 'react';
+
+const CIRCULAR_PROGRESS_SIZE = 40;
+const CIRCULAR_PROGRESS_THICKNESS = 5;
+
+export interface LoadingProps {
+    isLoading: boolean;
+    content: React.ReactNode;
+}
+export const Loading = (props: LoadingProps) => {
+    if (props.isLoading) {
+        return (
+            <div className="center">
+                <CircularProgress size={CIRCULAR_PROGRESS_SIZE} thickness={CIRCULAR_PROGRESS_THICKNESS} />
+            </div>
+        );
+    } else {
+        return <div>{props.content}</div>;
+    }
+};
diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index 81afe57e5..bcb8e60ef 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -1,7 +1,6 @@
 import { colors, Styles } from '@0xproject/react-shared';
 import { BigNumber } from '@0xproject/utils';
 import * as _ from 'lodash';
-import CircularProgress from 'material-ui/CircularProgress';
 import * as React from 'react';
 import * as DocumentTitle from 'react-document-title';
 import { Link, Route, RouteComponentProps, Switch } from 'react-router-dom';
@@ -13,6 +12,7 @@ import { PortalDisclaimerDialog } from 'ts/components/dialogs/portal_disclaimer_
 import { EthWrappers } from 'ts/components/eth_wrappers';
 import { AssetPicker } from 'ts/components/generate_order/asset_picker';
 import { BackButton } from 'ts/components/portal/back_button';
+import { Loading } from 'ts/components/portal/loading';
 import { Menu } from 'ts/components/portal/menu';
 import { Section } from 'ts/components/portal/section';
 import { TextHeader } from 'ts/components/portal/text_header';
@@ -283,7 +283,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         );
     }
     private _renderAccountManagement(): React.ReactNode {
-        return this.props.blockchainIsLoaded ? (
+        return (
             <Switch>
                 <Route path={`${WebsitePaths.Portal}/weth`} render={this._renderEthWrapper.bind(this)} />
                 <Route path={`${WebsitePaths.Portal}/account`} render={this._renderTokenBalances.bind(this)} />
@@ -291,18 +291,6 @@ export class Portal extends React.Component<PortalProps, PortalState> {
                 <Route path={`${WebsitePaths.Portal}/direct`} render={this._renderTradeDirect.bind(this)} />
                 <Route render={this._renderNotFoundMessage.bind(this)} />
             </Switch>
-        ) : (
-            // TODO: consolidate this loading component with the one in relayer_index
-            <div className="pt4 sm-px2 sm-pt2 sm-m1" style={{ height: 500 }}>
-                <div
-                    className="relative sm-px2 sm-pt2 sm-m1"
-                    style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }}
-                >
-                    <div className="center pb2">
-                        <CircularProgress size={40} thickness={5} />
-                    </div>
-                </div>
-            </div>
         );
     }
     private _renderEthWrapper(): React.ReactNode {
@@ -310,14 +298,19 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             <Section
                 header={<TextHeader labelText="Wrapped ETH" />}
                 body={
-                    <EthWrappers
-                        networkId={this.props.networkId}
-                        blockchain={this._blockchain}
-                        dispatcher={this.props.dispatcher}
-                        tokenByAddress={this.props.tokenByAddress}
-                        userAddress={this.props.userAddress}
-                        userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                        lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                    <Loading
+                        isLoading={!this.props.blockchainIsLoaded}
+                        content={
+                            <EthWrappers
+                                networkId={this.props.networkId}
+                                blockchain={this._blockchain}
+                                dispatcher={this.props.dispatcher}
+                                tokenByAddress={this.props.tokenByAddress}
+                                userAddress={this.props.userAddress}
+                                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                            />
+                        }
                     />
                 }
             />
@@ -328,10 +321,15 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             <Section
                 header={<TextHeader labelText="Trade History" />}
                 body={
-                    <TradeHistory
-                        tokenByAddress={this.props.tokenByAddress}
-                        userAddress={this.props.userAddress}
-                        networkId={this.props.networkId}
+                    <Loading
+                        isLoading={!this.props.blockchainIsLoaded}
+                        content={
+                            <TradeHistory
+                                tokenByAddress={this.props.tokenByAddress}
+                                userAddress={this.props.userAddress}
+                                networkId={this.props.networkId}
+                            />
+                        }
                     />
                 }
             />
@@ -342,10 +340,15 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             <Section
                 header={<TextHeader labelText="Trade Direct" />}
                 body={
-                    <GenerateOrderForm
-                        blockchain={this._blockchain}
-                        hashData={this.props.hashData}
-                        dispatcher={this.props.dispatcher}
+                    <Loading
+                        isLoading={!this.props.blockchainIsLoaded}
+                        content={
+                            <GenerateOrderForm
+                                blockchain={this._blockchain}
+                                hashData={this.props.hashData}
+                                dispatcher={this.props.dispatcher}
+                            />
+                        }
                     />
                 }
             />
@@ -358,18 +361,23 @@ export class Portal extends React.Component<PortalProps, PortalState> {
             <Section
                 header={<TextHeader labelText="Your Account" />}
                 body={
-                    <TokenBalances
-                        blockchain={this._blockchain}
-                        blockchainErr={this.props.blockchainErr}
-                        blockchainIsLoaded={this.props.blockchainIsLoaded}
-                        dispatcher={this.props.dispatcher}
-                        screenWidth={this.props.screenWidth}
-                        tokenByAddress={this.props.tokenByAddress}
-                        trackedTokens={trackedTokens}
-                        userAddress={this.props.userAddress}
-                        userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                        networkId={this.props.networkId}
-                        lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                    <Loading
+                        isLoading={!this.props.blockchainIsLoaded}
+                        content={
+                            <TokenBalances
+                                blockchain={this._blockchain}
+                                blockchainErr={this.props.blockchainErr}
+                                blockchainIsLoaded={this.props.blockchainIsLoaded}
+                                dispatcher={this.props.dispatcher}
+                                screenWidth={this.props.screenWidth}
+                                tokenByAddress={this.props.tokenByAddress}
+                                trackedTokens={trackedTokens}
+                                userAddress={this.props.userAddress}
+                                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                                networkId={this.props.networkId}
+                                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
+                            />
+                        }
                     />
                 }
             />
diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx
index d8b06010b..b327c9817 100644
--- a/packages/website/ts/components/relayer_index/relayer_index.tsx
+++ b/packages/website/ts/components/relayer_index/relayer_index.tsx
@@ -60,14 +60,12 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde
         if (!readyToRender) {
             return (
                 // TODO: consolidate this loading component with the one in portal
-                <div style={styles.root}>
-                    <div className="center">
-                        {_.isUndefined(this.state.error) ? (
-                            <CircularProgress size={40} thickness={5} />
-                        ) : (
-                            <Retry onRetry={this._fetchRelayerInfosAsync.bind(this)} />
-                        )}
-                    </div>
+                <div className="center">
+                    {_.isUndefined(this.state.error) ? (
+                        <CircularProgress size={40} thickness={5} />
+                    ) : (
+                        <Retry onRetry={this._fetchRelayerInfosAsync.bind(this)} />
+                    )}
                 </div>
             );
         } else {
-- 
cgit 


From 3d4e03f2cd4cb2db3df535a2c95dd2e500fb6f6e Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Wed, 16 May 2018 17:44:10 -0700
Subject: Refactor account management itmes

---
 packages/website/ts/components/portal/portal.tsx | 144 +++++++++++------------
 1 file changed, 70 insertions(+), 74 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx
index bcb8e60ef..d9d50c5ab 100644
--- a/packages/website/ts/components/portal/portal.tsx
+++ b/packages/website/ts/components/portal/portal.tsx
@@ -74,6 +74,12 @@ interface PortalState {
     tokenManagementState: TokenManagementState;
 }
 
+interface AccountManagementItem {
+    pathName: string;
+    headerText: string;
+    render: () => React.ReactNode;
+}
+
 enum TokenManagementState {
     Add = 'Add',
     Remove = 'Remove',
@@ -95,6 +101,7 @@ const styles: Styles = {
     },
     leftColumn: {
         width: LEFT_COLUMN_WIDTH,
+        height: '100%',
     },
     scrollContainer: {
         height: `calc(100vh - ${TOP_BAR_HEIGHT}px)`,
@@ -241,7 +248,7 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         );
     }
     private _renderWalletAndRelayerIndex(): React.ReactNode {
-        return <PortalLayout left={this._renderWallet()} right={this._renderRelayerIndex()} />;
+        return <PortalLayout left={this._renderWallet()} right={this._renderRelayerIndexSection()} />;
     }
     private _renderMenuAndAccountManagement(routeComponentProps: RouteComponentProps<any>): React.ReactNode {
         return <PortalLayout left={this._renderMenu(routeComponentProps)} right={this._renderAccountManagement()} />;
@@ -283,74 +290,73 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         );
     }
     private _renderAccountManagement(): React.ReactNode {
+        const accountManagementItems: AccountManagementItem[] = [
+            {
+                pathName: `${WebsitePaths.Portal}/weth`,
+                headerText: 'Wrapped ETH',
+                render: this._renderEthWrapper.bind(this),
+            },
+            {
+                pathName: `${WebsitePaths.Portal}/account`,
+                headerText: 'Your Account',
+                render: this._renderTokenBalances.bind(this),
+            },
+            {
+                pathName: `${WebsitePaths.Portal}/trades`,
+                headerText: 'Trade History',
+                render: this._renderTradeHistory.bind(this),
+            },
+            {
+                pathName: `${WebsitePaths.Portal}/direct`,
+                headerText: 'Trade Direct',
+                render: this._renderTradeDirect.bind(this),
+            },
+        ];
         return (
             <Switch>
-                <Route path={`${WebsitePaths.Portal}/weth`} render={this._renderEthWrapper.bind(this)} />
-                <Route path={`${WebsitePaths.Portal}/account`} render={this._renderTokenBalances.bind(this)} />
-                <Route path={`${WebsitePaths.Portal}/trades`} render={this._renderTradeHistory.bind(this)} />
-                <Route path={`${WebsitePaths.Portal}/direct`} render={this._renderTradeDirect.bind(this)} />
+                {_.map(accountManagementItems, item => {
+                    return <Route path={item.pathName} render={this._renderAccountManagementItem.bind(this, item)} />;
+                })}}
                 <Route render={this._renderNotFoundMessage.bind(this)} />
             </Switch>
         );
     }
-    private _renderEthWrapper(): React.ReactNode {
+    private _renderAccountManagementItem(item: AccountManagementItem): React.ReactNode {
         return (
             <Section
-                header={<TextHeader labelText="Wrapped ETH" />}
-                body={
-                    <Loading
-                        isLoading={!this.props.blockchainIsLoaded}
-                        content={
-                            <EthWrappers
-                                networkId={this.props.networkId}
-                                blockchain={this._blockchain}
-                                dispatcher={this.props.dispatcher}
-                                tokenByAddress={this.props.tokenByAddress}
-                                userAddress={this.props.userAddress}
-                                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-                            />
-                        }
-                    />
-                }
+                header={<TextHeader labelText={item.headerText} />}
+                body={<Loading isLoading={!this.props.blockchainIsLoaded} content={item.render()} />}
+            />
+        );
+    }
+    private _renderEthWrapper(): React.ReactNode {
+        return (
+            <EthWrappers
+                networkId={this.props.networkId}
+                blockchain={this._blockchain}
+                dispatcher={this.props.dispatcher}
+                tokenByAddress={this.props.tokenByAddress}
+                userAddress={this.props.userAddress}
+                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
             />
         );
     }
     private _renderTradeHistory(): React.ReactNode {
         return (
-            <Section
-                header={<TextHeader labelText="Trade History" />}
-                body={
-                    <Loading
-                        isLoading={!this.props.blockchainIsLoaded}
-                        content={
-                            <TradeHistory
-                                tokenByAddress={this.props.tokenByAddress}
-                                userAddress={this.props.userAddress}
-                                networkId={this.props.networkId}
-                            />
-                        }
-                    />
-                }
+            <TradeHistory
+                tokenByAddress={this.props.tokenByAddress}
+                userAddress={this.props.userAddress}
+                networkId={this.props.networkId}
             />
         );
     }
     private _renderTradeDirect(match: any, location: Location, history: History): React.ReactNode {
         return (
-            <Section
-                header={<TextHeader labelText="Trade Direct" />}
-                body={
-                    <Loading
-                        isLoading={!this.props.blockchainIsLoaded}
-                        content={
-                            <GenerateOrderForm
-                                blockchain={this._blockchain}
-                                hashData={this.props.hashData}
-                                dispatcher={this.props.dispatcher}
-                            />
-                        }
-                    />
-                }
+            <GenerateOrderForm
+                blockchain={this._blockchain}
+                hashData={this.props.hashData}
+                dispatcher={this.props.dispatcher}
             />
         );
     }
@@ -358,32 +364,22 @@ export class Portal extends React.Component<PortalProps, PortalState> {
         const allTokens = _.values(this.props.tokenByAddress);
         const trackedTokens = _.filter(allTokens, t => t.isTracked);
         return (
-            <Section
-                header={<TextHeader labelText="Your Account" />}
-                body={
-                    <Loading
-                        isLoading={!this.props.blockchainIsLoaded}
-                        content={
-                            <TokenBalances
-                                blockchain={this._blockchain}
-                                blockchainErr={this.props.blockchainErr}
-                                blockchainIsLoaded={this.props.blockchainIsLoaded}
-                                dispatcher={this.props.dispatcher}
-                                screenWidth={this.props.screenWidth}
-                                tokenByAddress={this.props.tokenByAddress}
-                                trackedTokens={trackedTokens}
-                                userAddress={this.props.userAddress}
-                                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
-                                networkId={this.props.networkId}
-                                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
-                            />
-                        }
-                    />
-                }
+            <TokenBalances
+                blockchain={this._blockchain}
+                blockchainErr={this.props.blockchainErr}
+                blockchainIsLoaded={this.props.blockchainIsLoaded}
+                dispatcher={this.props.dispatcher}
+                screenWidth={this.props.screenWidth}
+                tokenByAddress={this.props.tokenByAddress}
+                trackedTokens={trackedTokens}
+                userAddress={this.props.userAddress}
+                userEtherBalanceInWei={this.props.userEtherBalanceInWei}
+                networkId={this.props.networkId}
+                lastForceTokenStateRefetch={this.props.lastForceTokenStateRefetch}
             />
         );
     }
-    private _renderRelayerIndex(): React.ReactNode {
+    private _renderRelayerIndexSection(): React.ReactNode {
         return (
             <Section
                 header={<TextHeader labelText="Explore 0x Relayers" />}
-- 
cgit 


From 6b1a91160476205b6c2f0462d3a9d64ddcf20098 Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Wed, 16 May 2018 18:16:27 -0700
Subject: Fix spread

---
 packages/website/ts/pages/fullscreen_message.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/pages/fullscreen_message.tsx b/packages/website/ts/pages/fullscreen_message.tsx
index 141fb38a4..6fcf7b32c 100644
--- a/packages/website/ts/pages/fullscreen_message.tsx
+++ b/packages/website/ts/pages/fullscreen_message.tsx
@@ -18,7 +18,7 @@ export const FullscreenMessage = (props: FullscreenMessageProps) => {
             <div className="center py4">
                 <div className="py4">
                     <div className="py4">
-                        <h1 style={{ ...styles.thin }}>{props.headerText}</h1>
+                        <h1 style={styles.thin}>{props.headerText}</h1>
                         <div className="py1">
                             <div className="py3">{props.bodyText}</div>
                         </div>
-- 
cgit 


From 943b7d39c685345b00b38ed8a50b7adcffc24f9e Mon Sep 17 00:00:00 2001
From: Brandon Millman <brandon.millman@gmail.com>
Date: Thu, 17 May 2018 10:57:03 -0700
Subject: Fix tslint false positive

---
 packages/website/ts/components/wallet/wallet.tsx | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

(limited to 'packages/website/ts')

diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx
index 818cff05b..75dbd12e9 100644
--- a/packages/website/ts/components/wallet/wallet.tsx
+++ b/packages/website/ts/components/wallet/wallet.tsx
@@ -136,6 +136,10 @@ const styles: Styles = {
         overflow: 'auto',
         WebkitOverflowScrolling: 'touch',
     },
+    manageYourWalletText: {
+        color: colors.mediumBlue,
+        fontWeight: 'bold',
+    },
 };
 
 const ETHER_ICON_PATH = '/images/ether.png';
@@ -312,9 +316,12 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
                 <Link to={`${WebsitePaths.Portal}/account`} style={{ textDecoration: 'none' }}>
                     <ListItem
                         primaryText={
-                            <div className="flex right" style={{ color: colors.mediumBlue, fontWeight: 'bold' }}>
+                            <div className="flex right" style={styles.manageYourWalletText}>
                                 {'manage your wallet'}
-                            </div>}
+                            </div>
+                            // https://github.com/palantir/tslint-react/issues/140
+                            // tslint:disable-next-line:jsx-curly-spacing
+                        }
                         style={{ ...styles.paddedItem, ...styles.borderedItem }}
                     />
                 </Link>
-- 
cgit