aboutsummaryrefslogblamecommitdiffstats
path: root/packages/website/ts/components/top_bar/top_bar.tsx
blob: d2f530fb58e33253a2049c901b8016c4457b144b (plain) (tree)
1
2
3
4
5
6
7
8
9
                                                           
                                                                                                      
                            
                                        
                                    
                                            
                               
                                        
                                           
                                                              

                                                                         
                                                       
                                                      
                                                 
                                                                                     
                                               
                                               
 





                               
                         





                                      

                                
                         

                                    
                    
                                                        
                                    
                        

                                
                                                 
                                    
                      

                          






                          
             
                                      
                      
                             
               
                         
                  





                                                         
                                  

                         




                          











                                                          
                          

                           

                                                                       
                                               

                              

                         
      
                                                                                


                                                                                                     





                                     






                                                                           
                                      
                                                         
                                                                                            


                                                       
                                                                                
                                           

                                                                                                       
                    
                                                                                                                     



                                                                                            
                    
                                                                                                         



                                                                                      
                    



                                                      
                                                                
             



                                                                                                 
                 
                                                                                                              

                                                                  
                                                                                          

                    
                                                                                                                 

                                                                  
                                                                                           

                    
                                                                                                               

                                                                  


                                                                                          





                                                                                                                         
                                                                                                                

                                                                  
                                                                                          

                    





                                                                                                      





                                                                                                                    


















                                                                                                
          
                                                                                         
                                                                    
                                                                                                               


                                                             



                                                      
          
                            
                                                                                  
                                                                                                            





                                                                                                           
                














                                                                                                      

                                                     
                                                                               
                                         
                                                           


                                                                                               
                                                           

                                               
                                                                                        


                                                                   


                                                      
                                                                                        



                                                                   

                                               
                                                                                         


                                                                   
                                                      

                                               
                                                                                                     


                                                                   
                                                                                       
                                                                   
                                                      


                                  
                      
                                                 
                                                         











                                                                                      
                                                       

                                                                                                         
                              
                          
                            
                                                                                             


                  
                                                    






                                                                    







                                                                          


                     
                                              




                                              
                                                                    
             
                                          


                                                                                               
                                                                         

                                                                                  
                                                                                                           
                           
                                                                                       
                                                                                                           
                           









                                                                                    

                                                                                             


                                                                                         


                                                                                                            
                                                                                                                 

                                                                                        
                                                                                                            
                           
                                                                                                  
                                                                                                           


                                                                                                  
                                                                         
                                   
                           
                      


                     
                                                


                                                                                           
            
                                 

                                          
                             
         

                                             
                                  
                                                  
                                                                                  
                                                            
                                                       
                                                                        
                                                            
                                                              
                                                                    



                  
                                            
                                     
                             



                                             


                                                                                  
                                                            
                                                       
                                                                        



                  
                                        



                                                   
                                         

                                                                             


                                                                           
                                      

                                                                          

                                                               
     
                                       

                                                                           
                                                


                                                                                           
                
                                
                                    
                                   
                                    
                                   
          
     
                                       
import { DocsInfo, DocsMenu } from '@0xproject/react-docs';
import { colors, MenuSubsectionsBySection, NestedSidebarMenu, Styles } from '@0xproject/react-shared';
import * as _ from 'lodash';
import Drawer from 'material-ui/Drawer';
import Menu from 'material-ui/Menu';
import MenuItem from 'material-ui/MenuItem';
import * as React from 'react';
import { Link } from 'react-router-dom';
import { Blockchain } from 'ts/blockchain';
import { DrawerMenu } from 'ts/components/portal/drawer_menu';
import { ProviderDisplay } from 'ts/components/top_bar/provider_display';
import { TopBarMenuItem } from 'ts/components/top_bar/top_bar_menu_item';
import { Container } from 'ts/components/ui/container';
import { DropDown } from 'ts/components/ui/drop_down';
import { Dispatcher } from 'ts/redux/dispatcher';
import { Deco, Key, ProviderType, WebsiteLegacyPaths, WebsitePaths } from 'ts/types';
import { constants } from 'ts/utils/constants';
import { Translate } from 'ts/utils/translate';

export enum TopBarDisplayType {
    Default,
    Expanded,
}

export interface TopBarProps {
    userAddress?: string;
    networkId?: number;
    injectedProviderName?: string;
    providerType?: ProviderType;
    onToggleLedgerDialog?: () => void;
    blockchain?: Blockchain;
    dispatcher?: Dispatcher;
    blockchainIsLoaded: boolean;
    location: Location;
    translate: Translate;
    docsVersion?: string;
    availableDocVersions?: string[];
    menu?: DocsMenu;
    menuSubsectionsBySection?: MenuSubsectionsBySection;
    displayType?: TopBarDisplayType;
    docsInfo?: DocsInfo;
    style?: React.CSSProperties;
    isNightVersion?: boolean;
    onVersionSelected?: (semver: string) => void;
    sidebarHeader?: React.ReactNode;
    maxWidth?: number;
    paddingLeft?: number;
    paddingRight?: number;
}

interface TopBarState {
    isDrawerOpen: boolean;
}

const styles: Styles = {
    topBar: {
        backgroundColor: colors.white,
        width: '100%',
        position: 'relative',
        top: 0,
        paddingBottom: 1,
        zIndex: 1,
    },
    bottomBar: {
        boxShadow: 'rgba(0, 0, 0, 0.187647) 0px 1px 3px',
    },
    menuItem: {
        fontSize: 14,
        color: colors.darkestGrey,
        paddingTop: 6,
        paddingBottom: 6,
        cursor: 'pointer',
        fontWeight: 400,
    },
};

const DOC_WEBSITE_PATHS_TO_KEY = {
    [WebsitePaths.SolCov]: Key.SolCov,
    [WebsitePaths.SmartContracts]: Key.SmartContracts,
    [WebsitePaths.Web3Wrapper]: Key.Web3Wrapper,
    [WebsitePaths.SolCompiler]: Key.SolCompiler,
    [WebsitePaths.JSONSchemas]: Key.JsonSchemas,
    [WebsitePaths.Subproviders]: Key.Subproviders,
    [WebsitePaths.ContractWrappers]: Key.ContractWrappers,
    [WebsitePaths.Connect]: Key.Connect,
    [WebsitePaths.ZeroExJs]: Key.ZeroExJs,
}

const DEFAULT_HEIGHT = 68;
const EXPANDED_HEIGHT = 75;

export class TopBar extends React.Component<TopBarProps, TopBarState> {
    public static defaultProps: Partial<TopBarProps> = {
        displayType: TopBarDisplayType.Default,
        style: {},
        isNightVersion: false,
        paddingLeft: 20,
        paddingRight: 20,
    };
    public static heightForDisplayType(displayType: TopBarDisplayType): number {
        const result = displayType === TopBarDisplayType.Expanded ? EXPANDED_HEIGHT : DEFAULT_HEIGHT;
        return result + 1;
    }
    constructor(props: TopBarProps) {
        super(props);
        this.state = {
            isDrawerOpen: false,
        };
    }
    public componentWillReceiveProps(nextProps: TopBarProps): void {
        if (nextProps.location.pathname !== this.props.location.pathname) {
            this.setState({
                isDrawerOpen: false,
            });
        }
    }
    public render(): React.ReactNode {
        const isNightVersion = this.props.isNightVersion;
        const isExpandedDisplayType = this.props.displayType === TopBarDisplayType.Expanded;
        const parentClassNames = !isExpandedDisplayType
            ? 'flex mx-auto items-center max-width-4'
            : 'flex mx-auto items-center';
        const height = isExpandedDisplayType ? EXPANDED_HEIGHT : DEFAULT_HEIGHT;
        const developerSectionMenuItems = [
            <Link key="subMenuItem-zeroEx" to={WebsitePaths.ZeroExJs} className="text-decoration-none">
                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" />
            </Link>,
            <Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.SmartContract, Deco.CapWords)}
                />
            </Link>,
            <Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.Connect, Deco.CapWords)}
                />
            </Link>,
            <a
                key="subMenuItem-standard-relayer-api"
                target="_blank"
                className="text-decoration-none"
                href={constants.URL_STANDARD_RELAYER_API_GITHUB}
            >
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.StandardRelayerApi, Deco.CapWords)}
                />
            </a>,
            <Link key="subMenuItem-jsonSchema" to={WebsitePaths.JSONSchemas} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.JsonSchemas, Deco.CapWords)}
                />
            </Link>,
            <Link key="subMenuItem-subproviders" to={WebsitePaths.Subproviders} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.Subproviders, Deco.CapWords)}
                />
            </Link>,
            <Link key="subMenuItem-web3Wrapper" to={WebsitePaths.Web3Wrapper} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.Web3Wrapper, Deco.CapWords)}
                />
            </Link>,
            <Link key="subMenuItem-contractWrappers" to={WebsitePaths.ContractWrappers} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.ContractWrappers, Deco.CapWords)}
                />
            </Link>,
            <Link key="subMenuItem-sol-compiler" to={WebsitePaths.SolCompiler} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.SolCompiler, Deco.CapWords)}
                />
            </Link>,
            <Link key="subMenuItem-sol-cov" to={WebsitePaths.SolCov} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.SolCov, Deco.CapWords)}
                />
            </Link>,
            <Link key="subMenuItem-ethereum-types" to={WebsitePaths.EthereumTypes} className="text-decoration-none">
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.EthereumTypes, Deco.CapWords)}
                />
            </Link>,
            <a
                key="subMenuItem-whitePaper"
                target="_blank"
                className="text-decoration-none"
                href={`${WebsitePaths.Whitepaper}`}
            >
                <MenuItem
                    style={{ fontSize: styles.menuItem.fontSize }}
                    primaryText={this.props.translate.get(Key.Whitepaper, Deco.CapWords)}
                />
            </a>,
            <a
                key="subMenuItem-github"
                target="_blank"
                className="text-decoration-none"
                href={constants.URL_GITHUB_ORG}
            >
                <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="GitHub" />
            </a>,
        ];
        const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {};
        const fullWidthClasses = isExpandedDisplayType ? 'pr4' : '';
        const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png';
        const menuClasses = `col col-${
            isExpandedDisplayType ? '4' : '5'
        } ${fullWidthClasses} lg-pr0 md-pr2 sm-hide xs-hide`;
        const menuIconStyle = {
            fontSize: 25,
            color: isNightVersion ? 'white' : 'black',
            cursor: 'pointer',
        };
        const activeNode = (
            <div className="flex relative" style={{ color: menuIconStyle.color }}>
                <div style={{ paddingRight: 10 }}>{this.props.translate.get(Key.Developers, Deco.Cap)}</div>
                <div className="absolute" style={{ paddingLeft: 3, right: 3, top: -2 }}>
                    <i className="zmdi zmdi-caret-right" style={{ fontSize: 22 }} />
                </div>
            </div>
        );
        const popoverContent = <Menu style={{ color: colors.darkGrey }}>{developerSectionMenuItems}</Menu>;
        return (
            <div
                style={{ ...styles.topBar, ...bottomBorderStyle, ...this.props.style, ...{ height } }}
                className="pb1 flex items-center"
            >
                <Container
                    className={parentClassNames}
                    width="100%"
                    maxWidth={this.props.maxWidth}
                    paddingLeft={this.props.paddingLeft}
                    paddingRight={this.props.paddingRight}
                >
                    <Link to={`${WebsitePaths.Home}`} className="text-decoration-none">
                        <img src={logoUrl} height="30" />
                    </Link>
                    <div className="flex-auto" />
                    {!this._isViewingPortal() && (
                        <div className={menuClasses}>
                            <div className="flex items-center justify-between">
                                <DropDown
                                    activeNode={activeNode}
                                    popoverContent={popoverContent}
                                    anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }}
                                    targetOrigin={{ horizontal: 'middle', vertical: 'top' }}
                                    style={styles.menuItem}
                                />
                                <TopBarMenuItem
                                    title={this.props.translate.get(Key.Wiki, Deco.Cap)}
                                    path={`${WebsitePaths.Wiki}`}
                                    style={styles.menuItem}
                                    isNightVersion={isNightVersion}
                                    isExternal={false}
                                />
                                <TopBarMenuItem
                                    title={this.props.translate.get(Key.Blog, Deco.Cap)}
                                    path={constants.URL_BLOG}
                                    style={styles.menuItem}
                                    isNightVersion={isNightVersion}
                                    isExternal={true}
                                />
                                <TopBarMenuItem
                                    title={this.props.translate.get(Key.About, Deco.Cap)}
                                    path={`${WebsitePaths.About}`}
                                    style={styles.menuItem}
                                    isNightVersion={isNightVersion}
                                    isExternal={false}
                                />
                                <TopBarMenuItem
                                    title={this.props.translate.get(Key.TradeCallToAction, Deco.Cap)}
                                    path={`${WebsitePaths.Portal}`}
                                    isPrimary={true}
                                    style={styles.menuItem}
                                    className={`${isExpandedDisplayType && 'md-hide'}`}
                                    isNightVersion={isNightVersion}
                                    isExternal={false}
                                />
                            </div>
                        </div>
                    )}
                    {this._isViewingPortal() && (
                        <div className="sm-hide xs-hide">
                            <ProviderDisplay
                                dispatcher={this.props.dispatcher}
                                userAddress={this.props.userAddress}
                                networkId={this.props.networkId}
                                injectedProviderName={this.props.injectedProviderName}
                                providerType={this.props.providerType}
                                onToggleLedgerDialog={this.props.onToggleLedgerDialog}
                                blockchain={this.props.blockchain}
                                blockchainIsLoaded={this.props.blockchainIsLoaded}
                            />
                        </div>
                    )}
                    <div className={'md-hide lg-hide'}>
                        <div style={menuIconStyle}>
                            <i className="zmdi zmdi-menu" onClick={this._onMenuButtonClick.bind(this)} />
                        </div>
                    </div>
                </Container>
                {this._isViewingPortal() ? this._renderPortalDrawer() : this._renderDrawer()}
            </div>
        );
    }
    private _renderPortalDrawer(): React.ReactNode {
        return (
            <Drawer
                open={this.state.isDrawerOpen}
                docked={false}
                openSecondary={true}
                onRequestChange={this._onMenuButtonClick.bind(this)}
            >
                <DrawerMenu
                    selectedPath={this.props.location.pathname}
                    userAddress={this.props.userAddress}
                    injectedProviderName={this.props.injectedProviderName}
                    providerType={this.props.providerType}
                    blockchainIsLoaded={this.props.blockchainIsLoaded}
                    blockchain={this.props.blockchain}
                />
            </Drawer>
        );
    }
    private _renderDrawer(): React.ReactNode {
        return (
            <Drawer
                open={this.state.isDrawerOpen}
                docked={false}
                openSecondary={true}
                onRequestChange={this._onMenuButtonClick.bind(this)}
            >
                <div className="clearfix">
                    {this._renderDocsMenu()}
                    {this._renderWiki()}
                    <div className="pl1 py1 mt3" style={{ backgroundColor: colors.lightGrey }}>
                        {this.props.translate.get(Key.Website, Deco.Cap)}
                    </div>
                    <Link to={WebsitePaths.Home} className="text-decoration-none">
                        <MenuItem className="py2">{this.props.translate.get(Key.Home, Deco.Cap)}</MenuItem>
                    </Link>
                    <Link to={`${WebsitePaths.Wiki}`} className="text-decoration-none">
                        <MenuItem className="py2">{this.props.translate.get(Key.Wiki, Deco.Cap)}</MenuItem>
                    </Link>
                    {_.map(DOC_WEBSITE_PATHS_TO_KEY, (key, websitePath) => {
                        if (!this._doesUrlInclude(websitePath)) {
                            <Link to={websitePath} className="text-decoration-none">
                                <MenuItem className="py2">
                                    {this.props.translate.get(key, Deco.Cap)}{' '}
                                    {this.props.translate.get(Key.Docs, Deco.Cap)}
                                </MenuItem>
                            </Link>
                        }
                    })}
                    {!this._isViewingPortal() && (
                        <Link to={`${WebsitePaths.Portal}`} className="text-decoration-none">
                            <MenuItem className="py2">
                                {this.props.translate.get(Key.PortalDApp, Deco.CapWords)}
                            </MenuItem>
                        </Link>
                    )}
                    <a className="text-decoration-none" target="_blank" href={`${WebsitePaths.Whitepaper}`}>
                        <MenuItem className="py2">{this.props.translate.get(Key.Whitepaper, Deco.Cap)}</MenuItem>
                    </a>
                    <Link to={`${WebsitePaths.About}`} className="text-decoration-none">
                        <MenuItem className="py2">{this.props.translate.get(Key.About, Deco.Cap)}</MenuItem>
                    </Link>
                    <a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}>
                        <MenuItem className="py2">{this.props.translate.get(Key.Blog, Deco.Cap)}</MenuItem>
                    </a>
                    <Link to={`${WebsitePaths.FAQ}`} className="text-decoration-none">
                        <MenuItem className="py2" onTouchTap={this._onMenuButtonClick.bind(this)}>
                            {this.props.translate.get(Key.Faq, Deco.Cap)}
                        </MenuItem>
                    </Link>
                </div>
            </Drawer>
        );
    }
    private _renderDocsMenu(): React.ReactNode {
        const isViewingDocsPage = _.some(DOC_WEBSITE_PATHS_TO_KEY, (_key, websitePath) => {
            return this._doesUrlInclude(websitePath);
        });
        if (
            !isViewingDocsPage ||
            _.isUndefined(this.props.menu)
        ) {
            return undefined;
        }
        return (
            <div className="lg-hide md-hide">
                <NestedSidebarMenu
                    topLevelMenu={this.props.menu}
                    menuSubsectionsBySection={this.props.menuSubsectionsBySection}
                    sidebarHeader={this.props.sidebarHeader}
                    shouldDisplaySectionHeaders={false}
                    onMenuItemClick={this._onMenuButtonClick.bind(this)}
                    selectedVersion={this.props.docsVersion}
                    versions={this.props.availableDocVersions}
                    onVersionSelected={this.props.onVersionSelected}
                />
            </div>
        );
    }
    private _renderWiki(): React.ReactNode {
        if (!this._isViewingWiki()) {
            return undefined;
        }

        return (
            <div className="lg-hide md-hide">
                <NestedSidebarMenu
                    topLevelMenu={this.props.menuSubsectionsBySection}
                    menuSubsectionsBySection={this.props.menuSubsectionsBySection}
                    sidebarHeader={this.props.sidebarHeader}
                    shouldDisplaySectionHeaders={false}
                    onMenuItemClick={this._onMenuButtonClick.bind(this)}
                />
            </div>
        );
    }
    private _onMenuButtonClick(): void {
        this.setState({
            isDrawerOpen: !this.state.isDrawerOpen,
        });
    }
    private _isViewingPortal(): boolean {
        return _.includes(this.props.location.pathname, WebsitePaths.Portal);
    }
    private _isViewingDocs(): boolean {
        return _.includes(this.props.location.pathname, WebsitePaths.Docs);
    }
    private _isViewingFAQ(): boolean {
        return _.includes(this.props.location.pathname, WebsitePaths.FAQ);
    }
    private _doesUrlInclude(aPath: string): boolean {
        return _.includes(this.props.location.pathname, aPath);
    }
    private _isViewingWiki(): boolean {
        return _.includes(this.props.location.pathname, WebsitePaths.Wiki);
    }
    private _shouldDisplayBottomBar(): boolean {
        const isViewingDocsPage = _.some(DOC_WEBSITE_PATHS_TO_KEY, (_key, websitePath) => {
            return this._doesUrlInclude(websitePath);
        });
        return (
            isViewingDocsPage ||
            this._isViewingWiki() ||
            this._isViewingFAQ() ||
            this._isViewingDocs() ||
            this._isViewingPortal()
        );
    }
} // tslint:disable:max-file-line-count