better style search bar with error and loading

This commit is contained in:
Jonathan Rainville 2018-10-18 15:30:01 -04:00 committed by Pascal Precht
parent 47beac499f
commit 423d8dcdf0
No known key found for this signature in database
GPG Key ID: 0EE28D8D6FD85D7D
6 changed files with 48 additions and 13 deletions

View File

@ -66,15 +66,19 @@ class Layout extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = {loading: false}; this.state = {
searchLoading: false,
searchError: false
};
} }
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
if (nextProps.searchResult && Object.keys(nextProps.searchResult).length && if (nextProps.searchResult && Object.keys(nextProps.searchResult).length &&
nextProps.searchResult !== this.props.searchResult) { nextProps.searchResult !== this.props.searchResult) {
this.setState({loading: false}); this.setState({searchLoading: false});
if (nextProps.searchResult.error) { if (nextProps.searchResult.error) {
this.setState({searchError: true});
return true; return true;
} }
@ -101,7 +105,11 @@ class Layout extends React.Component {
searchTheExplorer(value) { searchTheExplorer(value) {
this.props.explorerSearch(value); this.props.explorerSearch(value);
this.setState({loading: true}); this.setState({searchLoading: true});
}
closeSearchError() {
this.setState({searchError: false});
} }
renderNav() { renderNav() {
@ -120,11 +128,10 @@ class Layout extends React.Component {
} }
renderRightNav() { renderRightNav() {
const searchResult = this.props.searchResult; // {searchResult.error && <Alert color="danger">{searchResult.error}</Alert>}
return (<Nav className="ml-auto" navbar> return (<Nav className="ml-auto" navbar>
<SearchBar searchSubmit={searchValue => this.searchTheExplorer(searchValue)}/> {<SearchBar hidden={this.state.searchLoading} searchSubmit={searchValue => this.searchTheExplorer(searchValue)}/>}
{this.state.loading && <p>Searching...</p>} {this.state.searchLoading && <p className="search-loading">Searching... <FontAwesome name="spinner" spin /></p>}
{searchResult.error && <Alert color="danger">{searchResult.error}</Alert>}
{this.renderSettings()} {this.renderSettings()}
</Nav>); </Nav>);
@ -169,7 +176,7 @@ class Layout extends React.Component {
} }
render() { render() {
const {children} = this.props; const {children, searchResult} = this.props;
return (<div className="app animated fadeIn"> return (<div className="app animated fadeIn">
<AppHeader fixed> <AppHeader fixed>
@ -189,6 +196,12 @@ class Layout extends React.Component {
{this.renderSideBar()} {this.renderSideBar()}
<main className="main"> <main className="main">
{searchResult.error && this.state.searchError && <Alert color="danger">{searchResult.error}
<span className="search-error-close" onClick={(e) => this.closeSearchError(e)}>
<FontAwesome name="times-circle"/>
</span>
</Alert>}
<Container fluid className="h-100" style={{marginTop: '24px'}}> <Container fluid className="h-100" style={{marginTop: '24px'}}>
{children} {children}
</Container> </Container>

View File

@ -1,12 +1,13 @@
import React from 'react'; import React from 'react';
import {Row, Col} from 'reactstrap'; import {Row, Col} from 'reactstrap';
import FontAwesome from 'react-fontawesome';
import "./Loading.css"; import "./Loading.css";
const Loading = () => ( const Loading = () => (
<Row className="align-items-center mt-5"> <Row className="align-items-center mt-5">
<Col className="text-center"> <Col className="text-center">
<i className="fa fa-spinner fa-spin fa-3x fa-fw"></i> <FontAwesome name="spinner" spin className="fa-3x fa-fw" />
</Col> </Col>
</Row> </Row>
); );

View File

@ -33,7 +33,7 @@ class SearchBar extends React.Component {
render() { render() {
return ( return (
<Row> <Row className={this.props.hidden ? 'hidden' : ''}>
<Col className="col-sm-12"> <Col className="col-sm-12">
<Form inline className="search-bar float-right my-2"> <Form inline className="search-bar float-right my-2">
<FormGroup> <FormGroup>
@ -51,7 +51,8 @@ class SearchBar extends React.Component {
} }
SearchBar.propTypes = { SearchBar.propTypes = {
searchSubmit: PropTypes.func.isRequired searchSubmit: PropTypes.func.isRequired,
hidden: PropTypes.bool
}; };
export default SearchBar; export default SearchBar;

View File

@ -17,3 +17,19 @@
border-bottom-left-radius: 0; border-bottom-left-radius: 0;
box-shadow: none; box-shadow: none;
} }
.search-loading {
margin-top: 16px;
}
.search-loading .fa-spinner {
font-size: 2em;
vertical-align: middle;
margin-left: 10px;
}
.search-error-close {
position: absolute;
cursor: pointer;
right: 20px;
}

View File

@ -17,3 +17,7 @@
.text-wrap { .text-wrap {
word-wrap: break-word; word-wrap: break-word;
} }
.hidden {
display: none;
}

View File

@ -51,5 +51,5 @@ export function *searchExplorer(entity, payload) {
return yield put(entity.success(result)); return yield put(entity.success(result));
} }
return yield put(entity.success({error: 'No result found in transactions, accounts or blocks'})); return yield put(entity.success({error: 'No result found in transactions, accounts, contracts, or blocks'}));
} }