Responsive Layout

This commit is contained in:
Anthony Laibe 2018-10-22 11:00:20 +01:00 committed by Pascal Precht
parent 3bb696e4d3
commit 4ed329c21d
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
4 changed files with 86 additions and 65 deletions

View File

@ -0,0 +1,3 @@
.sidebar-minimizer {
display: block !important;
}

View File

@ -7,6 +7,8 @@ import {explorerSearch} from "../actions";
import {LIGHT_THEME, DARK_THEME} from '../constants'; import {LIGHT_THEME, DARK_THEME} from '../constants';
import FontAwesome from 'react-fontawesome'; import FontAwesome from 'react-fontawesome';
import "./Layout.css";
import { import {
AppFooter, AppFooter,
AppHeader, AppHeader,
@ -106,62 +108,83 @@ class Layout extends React.Component {
this.setState({searchLoading: true}); this.setState({searchLoading: true});
} }
closeSearchError() { dismissSearchError() {
this.setState({searchError: false}); this.setState({searchError: false});
} }
renderNav() { renderNav() {
return (<Nav className="d-md-down-none" navbar> return (
{HEADER_NAV_ITEMS.map((item) => { <React.Fragment>
return ( <Nav className="d-lg-down-none" navbar>
<NavItem className="px-3" key={item.to}> {HEADER_NAV_ITEMS.map((item) => {
<NavLink tag={Link} to={item.to}> return (
<FontAwesome className="mr-2" name={item.icon} /> <NavItem className="px-3" key={item.to}>
{item.name} <NavLink tag={Link} to={item.to}>
</NavLink> <FontAwesome className="mr-2" name={item.icon} />
</NavItem> {item.name}
); </NavLink>
})} </NavItem>
</Nav>); );
})}
</Nav>
<AppHeaderDropdown className="list-unstyled d-xl-none" direction="down">
<DropdownToggle nav>
<FontAwesome name='bars'/>
</DropdownToggle>
<DropdownMenu left style={{ left: 'auto' }}>
{HEADER_NAV_ITEMS.map((item) => (
<DropdownItem key={item.to} to={item.to} tag={Link}>
<FontAwesome className="mr-2" name={item.icon} />
{item.name}
</DropdownItem>
))}
</DropdownMenu>
</AppHeaderDropdown>
</React.Fragment>
);
} }
renderRightNav() { renderRightNav() {
return (<Nav className="ml-auto" navbar> return (
{<SearchBar hidden={this.state.searchLoading} searchSubmit={searchValue => this.searchTheExplorer(searchValue)}/>} <Nav className="ml-auto" navbar>
{this.state.searchLoading && <p className="search-loading"> <NavItem className="d-sm-down-none">
Searching... <FontAwesome name="spinner" size="2x" spin className="align-middle ml-2"/> <SearchBar loading={this.state.searchLoading} searchSubmit={searchValue => this.searchTheExplorer(searchValue)}/>
</p>} </NavItem>
{this.renderSettings()}
{this.renderSettings()} </Nav>
</Nav>); );
} }
renderSettings() { renderSettings() {
const {logout, toggleTheme, currentTheme} = this.props; const {logout, toggleTheme, currentTheme} = this.props;
return (<AppHeaderDropdown direction="down"> return (
<DropdownToggle nav> <AppHeaderDropdown direction="down">
<i className="icon-settings" /> <DropdownToggle nav>
</DropdownToggle> <i className="icon-settings" />
<DropdownMenu right style={{ right: 'auto' }}> </DropdownToggle>
<DropdownItem className="text-capitalize" onClick={() => toggleTheme()}> <DropdownMenu right style={{ right: 'auto' }}>
<FontAwesome name={currentTheme === DARK_THEME ? 'sun-o' : 'moon-o'} /> <DropdownItem className="text-capitalize" onClick={() => toggleTheme()}>
{currentTheme === DARK_THEME ? LIGHT_THEME : DARK_THEME} Mode <FontAwesome name={currentTheme === DARK_THEME ? 'sun-o' : 'moon-o'} />
</DropdownItem> {currentTheme === DARK_THEME ? LIGHT_THEME : DARK_THEME} Mode
<DropdownItem onClick={logout}><FontAwesome name="lock" /> Logout</DropdownItem> </DropdownItem>
</DropdownMenu> <DropdownItem onClick={logout}><FontAwesome name="lock" /> Logout</DropdownItem>
</AppHeaderDropdown>); </DropdownMenu>
</AppHeaderDropdown>
);
} }
renderFooter() { renderFooter() {
return (<AppFooter> return (
<AppFooter>
<span className="ml-auto"> <span className="ml-auto">
Embark&nbsp; Embark&nbsp;
<a href="https://embark.status.im" title="Documentation" rel="noopener noreferrer" target="_blank">Documentation</a> <a href="https://embark.status.im" title="Documentation" rel="noopener noreferrer" target="_blank">Documentation</a>
&nbsp;|&nbsp; &nbsp;|&nbsp;
<a href="https://github.com/embark-framework" title="Github" rel="noopener noreferrer" target="_blank">Github</a> <a href="https://github.com/embark-framework" title="Github" rel="noopener noreferrer" target="_blank">Github</a>
</span> </span>
</AppFooter>); </AppFooter>
);
} }
render() { render() {
@ -173,11 +196,9 @@ class Layout extends React.Component {
return (<div className="app animated fadeIn"> return (<div className="app animated fadeIn">
<AppHeader fixed> <AppHeader fixed>
<AppNavbarBrand className="mx-3" <AppNavbarBrand full={{src: logo, width: 50, height: 50, alt: 'Embark Logo'}}
full={{src: logo, width: 50, height: 50, alt: 'Embark Logo'}} minimized={{src: logo, width: 50, height: 50, alt: 'Embark Logo'}}
minimized={{src: logo, width: 30, height: 30, alt: 'Embark Logo'}}
/> />
{this.renderNav()} {this.renderNav()}
{this.renderRightNav()} {this.renderRightNav()}
@ -185,7 +206,7 @@ class Layout extends React.Component {
<div className="app-body"> <div className="app-body">
{sidebar && {sidebar &&
<AppSidebar fixed display="lg"> <AppSidebar fixed display="sm">
<AppSidebarHeader /> <AppSidebarHeader />
<AppSidebarForm /> <AppSidebarForm />
<AppSidebarNav navConfig={sidebar} location={location} /> <AppSidebarNav navConfig={sidebar} location={location} />
@ -195,11 +216,9 @@ class Layout extends React.Component {
} }
<main className="main"> <main className="main">
{searchResult.error && this.state.searchError && <Alert color="danger">{searchResult.error} <Alert color="danger" isOpen={this.state.searchError} toggle={() => this.dismissSearchError()}>
<span className="search-error-close" onClick={(e) => this.closeSearchError(e)}> {searchResult.error}
<FontAwesome name="times-circle"/> </Alert>
</span>
</Alert>}
<Container fluid className="h-100" style={{marginTop: '24px'}}> <Container fluid className="h-100" style={{marginTop: '24px'}}>
{children} {children}

View File

@ -18,12 +18,6 @@
box-shadow: none; box-shadow: none;
} }
.search-loading { .search-bar .search-loading {
margin-top: 16px; margin-top: 16px;
} }
.search-error-close {
position: absolute;
cursor: pointer;
right: 20px;
}

View File

@ -1,10 +1,10 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import {Form, FormGroup, Input, Button} from 'reactstrap'; import {Form, Input, Button} from 'reactstrap';
import FontAwesome from 'react-fontawesome'; import FontAwesome from 'react-fontawesome';
import classNames from 'classnames'; import classNames from 'classnames';
import './search.css'; import './SearchBar.css';
class SearchBar extends React.Component { class SearchBar extends React.Component {
constructor(props) { constructor(props) {
@ -34,15 +34,20 @@ class SearchBar extends React.Component {
render() { render() {
return ( return (
<Form inline className={classNames('search-bar', 'float-right', 'my-2', {hidden: this.props.hidden})}> <Form inline className={classNames('search-bar', 'mr-2', {hidden: this.props.hidden})}>
<FormGroup> {!this.props.loading &&
<Input type="text" name="search-bar" placeholder="Search by Address / Txhash / Block" <React.Fragment>
onChange={(e) => this.onChange(e)} <Input type="text" name="search-bar" placeholder="Search by Address / Txhash / Block"
value={this.state.searchValue} onKeyPress={e => this.onKeyPress(e)}/> onChange={(e) => this.onChange(e)}
<Button color="secondary" onClick={(e) => this.onSubmit(e)}> value={this.state.searchValue} onKeyPress={e => this.onKeyPress(e)}/>
<FontAwesome name="search"/> <Button color="secondary" onClick={(e) => this.onSubmit(e)}>
</Button> <FontAwesome name="search"/>
</FormGroup> </Button>
</React.Fragment>
}
{this.props.loading &&
<p className="search-loading">Searching... <FontAwesome name="spinner" size="2x" spin className="align-middle ml-2"/></p>
}
</Form> </Form>
); );
} }
@ -50,7 +55,7 @@ class SearchBar extends React.Component {
SearchBar.propTypes = { SearchBar.propTypes = {
searchSubmit: PropTypes.func.isRequired, searchSubmit: PropTypes.func.isRequired,
hidden: PropTypes.bool loading: PropTypes.bool
}; };
export default SearchBar; export default SearchBar;