From 250d97a7c4eacceb8d6be0b23a640e22cec5a43c Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Tue, 3 Apr 2018 11:12:55 -0700 Subject: Implement initial relayer grid --- packages/website/ts/components/portal.tsx | 19 +++- packages/website/ts/components/portal_menu.tsx | 26 +++-- .../components/relayer_index/relayer_grid_tile.tsx | 84 +++++++++++++++ .../ts/components/relayer_index/relayer_index.tsx | 118 +++++++++++++++++++++ .../relayer_index/relayer_top_tokens.tsx | 46 ++++++++ packages/website/ts/components/wallet/wallet.tsx | 4 +- packages/website/ts/types.ts | 8 ++ 7 files changed, 294 insertions(+), 11 deletions(-) create mode 100644 packages/website/ts/components/relayer_index/relayer_grid_tile.tsx create mode 100644 packages/website/ts/components/relayer_index/relayer_index.tsx create mode 100644 packages/website/ts/components/relayer_index/relayer_top_tokens.tsx diff --git a/packages/website/ts/components/portal.tsx b/packages/website/ts/components/portal.tsx index ceb0ecc72..b79f5e288 100644 --- a/packages/website/ts/components/portal.tsx +++ b/packages/website/ts/components/portal.tsx @@ -15,6 +15,7 @@ import { EthWrappers } from 'ts/components/eth_wrappers'; import { FillOrder } from 'ts/components/fill_order'; import { Footer } from 'ts/components/footer'; import { PortalMenu } from 'ts/components/portal_menu'; +import { RelayerIndex } from 'ts/components/relayer_index/relayer_index'; import { TokenBalances } from 'ts/components/token_balances'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { TradeHistory } from 'ts/components/trade_history/trade_history'; @@ -155,6 +156,7 @@ export class Portal extends React.Component { const updateShouldBlockchainErrDialogBeOpen = this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen.bind( this.props.dispatcher, ); + const isDevelopment = configs.ENVIRONMENT === Environments.DEVELOPMENT; const portalStyle: React.CSSProperties = { minHeight: '100vh', display: 'flex', @@ -204,12 +206,18 @@ export class Portal extends React.Component {
{this.props.blockchainIsLoaded ? ( - {configs.ENVIRONMENT === Environments.DEVELOPMENT && ( + {isDevelopment && ( )} + {isDevelopment && ( + + )} {
); } + private _renderRelayers() { + return ( +
+
+ +
+
+ ); + } private _renderEthWrapper() { return ( {configs.ENVIRONMENT === Environments.DEVELOPMENT && ( - - {this._renderMenuItemWithIcon('Wallet', 'zmdi-balance-wallet')} - +
+ + {this._renderMenuItemWithIcon('Wallet', 'zmdi-balance-wallet')} + + + {this._renderMenuItemWithIcon('Relayers', 'zmdi-input-antenna')} + +
)} ); diff --git a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx new file mode 100644 index 000000000..530576828 --- /dev/null +++ b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx @@ -0,0 +1,84 @@ +import { colors, Styles } from '@0xproject/react-shared'; +import * as _ from 'lodash'; +import { GridTile } from 'material-ui/GridList'; +import * as React from 'react'; + +import { TopTokens } from 'ts/components/relayer_index/relayer_top_tokens'; +import { TokenIcon } from 'ts/components/ui/token_icon'; +import { RelayerInfo, Token } from 'ts/types'; + +export interface RelayerGridTileProps { + relayerInfo: RelayerInfo; + networkId: number; +} + +const styles: Styles = { + root: { + backgroundColor: colors.white, + borderBottomRightRadius: 10, + borderBottomLeftRadius: 10, + borderTopRightRadius: 10, + borderTopLeftRadius: 10, + boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`, + overflow: 'hidden', + boxSizing: 'border-box', + }, + innerDiv: { + padding: 6, + height: '100%', + boxSizing: 'border-box', + }, + header: { + height: '50%', + width: '100%', + objectFit: 'cover', + borderBottomRightRadius: 4, + borderBottomLeftRadius: 4, + borderTopRightRadius: 4, + borderTopLeftRadius: 4, + }, + body: { + paddingLeft: 6, + paddingRight: 6, + height: '50%', + width: '100%', + boxSizing: 'border-box', + }, + marketShareBar: { + height: 14, + width: '100%', + backgroundColor: colors.mediumBlue, + }, + subLabel: { + fontSize: 12, + color: colors.lightGrey, + }, + relayerNameLabel: { + fontSize: 16, + fontWeight: 'bold', + color: colors.black, + }, +}; + +export const RelayerGridTile: React.StatelessComponent = (props: RelayerGridTileProps) => { + return ( + +
+ +
+
+ {props.relayerInfo.name} +
+
+
+ Market share +
+ +
+ Top tokens +
+
+
+ + ); +}; diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx new file mode 100644 index 000000000..db3cf07b5 --- /dev/null +++ b/packages/website/ts/components/relayer_index/relayer_index.tsx @@ -0,0 +1,118 @@ +import { colors, Styles } from '@0xproject/react-shared'; +import { GridList } from 'material-ui/GridList'; +import * as React from 'react'; + +import { RelayerGridTile } from 'ts/components/relayer_index/relayer_grid_tile'; +import { RelayerInfo } from 'ts/types'; + +export interface RelayerIndexProps { + networkId: number; +} + +const styles: Styles = { + root: { + width: '100%', + }, + item: { + backgroundColor: colors.white, + borderBottomRightRadius: 10, + borderBottomLeftRadius: 10, + borderTopRightRadius: 10, + borderTopLeftRadius: 10, + boxShadow: `0px 4px 6px ${colors.walletBoxShadow}`, + overflow: 'hidden', + padding: 4, + }, +}; + +// TODO: replace fake data with real, remote data +const topTokens = [ + { + address: '0x1dad4783cf3fe3085c1426157ab175a6119a04ba', + decimals: 18, + iconUrl: '/images/token_icons/makerdao.png', + isRegistered: true, + isTracked: true, + name: 'Maker DAO', + symbol: 'MKR', + }, + { + address: '0x323b5d4c32345ced77393b3530b1eed0f346429d', + decimals: 18, + iconUrl: '/images/token_icons/melon.png', + isRegistered: true, + isTracked: true, + name: 'Melon Token', + symbol: 'MLN', + }, + { + address: '0xb18845c260f680d5b9d84649638813e342e4f8c9', + decimals: 18, + iconUrl: '/images/token_icons/augur.png', + isRegistered: true, + isTracked: true, + name: 'Augur Reputation Token', + symbol: 'REP', + }, +]; + +const relayerInfos: RelayerInfo[] = [ + { + id: '1', + headerUrl: '/images/og_image.png', + name: 'Radar Relay', + marketShare: 0.5, + topTokens, + }, + { + id: '2', + headerUrl: '/images/og_image.png', + name: 'Paradex', + marketShare: 0.5, + topTokens, + }, + { + id: '3', + headerUrl: '/images/og_image.png', + name: 'yo', + marketShare: 0.5, + topTokens, + }, + { + id: '4', + headerUrl: '/images/og_image.png', + name: 'test', + marketShare: 0.5, + topTokens, + }, + { + id: '5', + headerUrl: '/images/og_image.png', + name: 'blahg', + marketShare: 0.5, + topTokens, + }, + { + id: '6', + headerUrl: '/images/og_image.png', + name: 'hello', + marketShare: 0.5, + topTokens, + }, +]; + +const CELL_HEIGHT = 260; +const NUMBER_OF_COLUMNS = 4; +const GRID_PADDING = 16; + +export const RelayerIndex: React.StatelessComponent = (props: RelayerIndexProps) => { + return ( +
+ + {relayerInfos.map((relayerInfo: RelayerInfo) => ( + + ))} + +
+ ); +}; diff --git a/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx new file mode 100644 index 000000000..233590b78 --- /dev/null +++ b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx @@ -0,0 +1,46 @@ +import { colors, EtherscanLinkSuffixes, Styles, utils as sharedUtils } from '@0xproject/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; + +import { TokenIcon } from 'ts/components/ui/token_icon'; +import { Token } from 'ts/types'; + +export interface TopTokensProps { + tokens: Token[]; + networkId: number; +} + +const styles: Styles = { + tokenLabel: { + textDecoration: 'none', + color: colors.mediumBlue, + }, + followingTokenLabel: { + paddingLeft: 16, + }, +}; + +export const TopTokens: React.StatelessComponent = (props: TopTokensProps) => { + return ( +
+ {_.map(props.tokens, (token: Token, index: number) => { + const firstItemStyle = { ...styles.tokenLabel, ...styles.followingTokenLabel }; + const style = index !== 0 ? firstItemStyle : styles.tokenLabel; + return ( + + {token.symbol} + + ); + })} +
+ ); +}; + +function tokenLinkFromToken(token: Token, networkId: number) { + return sharedUtils.getEtherScanLinkIfExists(token.address, networkId, EtherscanLinkSuffixes.Address); +} diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 39c95d31c..8bda27925 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -71,7 +71,7 @@ interface AccessoryItemConfig { } const styles: Styles = { - wallet: { + root: { width: 346, backgroundColor: colors.white, borderBottomRightRadius: 10, @@ -174,7 +174,7 @@ export class Wallet extends React.Component { } public render() { const isReadyToRender = this.props.blockchainIsLoaded && this.props.blockchainErr === BlockchainErrs.NoError; - return
{isReadyToRender && this._renderRows()}
; + return
{isReadyToRender && this._renderRows()}
; } private _renderRows() { const isAddressAvailable = !_.isEmpty(this.props.userAddress); diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 901483327..dba59f704 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -490,4 +490,12 @@ export interface TokenState { allowance: BigNumber; isLoaded: boolean; } + +export interface RelayerInfo { + headerUrl: string; + id: string; + name: string; + marketShare: number; + topTokens: Token[]; +} // tslint:disable:max-file-line-count -- cgit