Basic search
This commit is contained in:
@@ -1,22 +1,54 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
|
import _debounce from 'lodash/debounce';
|
||||||
|
|
||||||
import Flex from 'components/Flex';
|
import Flex from 'components/Flex';
|
||||||
import Layout from 'components/Layout';
|
import Layout from 'components/Layout';
|
||||||
import CenteredContent from 'components/CenteredContent';
|
import CenteredContent from 'components/CenteredContent';
|
||||||
|
import SearchField from './components/SearchField';
|
||||||
|
import DocumentPreview from 'components/DocumentPreview';
|
||||||
|
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
|
||||||
|
|
||||||
|
import styles from './Search.scss';
|
||||||
|
|
||||||
|
import SearchStore from './SearchStore';
|
||||||
|
|
||||||
@observer
|
@observer
|
||||||
class Search extends React.Component {
|
class Search extends React.Component {
|
||||||
|
static store;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.store = new SearchStore();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const search = _debounce((searchTerm) => {
|
||||||
|
this.store.search(searchTerm);
|
||||||
|
}, 250);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout
|
<Layout
|
||||||
title="Search"
|
title="Search"
|
||||||
titleText="Search"
|
titleText="Search"
|
||||||
search={ false }
|
search={ false }
|
||||||
|
loading={ this.store.isFetching }
|
||||||
>
|
>
|
||||||
<CenteredContent>
|
<CenteredContent>
|
||||||
<Flex direction="column" flex={ true }>
|
<Flex direction="column" flex={ true }>
|
||||||
TBA
|
<Flex flex={ true }>
|
||||||
|
<img
|
||||||
|
src={ require('assets/icons/search.svg') }
|
||||||
|
className={ styles.icon }
|
||||||
|
/>
|
||||||
|
<SearchField
|
||||||
|
searchTerm={ this.store.searchTerm }
|
||||||
|
onChange={ search }
|
||||||
|
/>
|
||||||
|
</Flex>
|
||||||
|
{ this.store.documents && this.store.documents.map((document) => {
|
||||||
|
return (<DocumentPreview key={ document.id } document={ document } />);
|
||||||
|
}) }
|
||||||
</Flex>
|
</Flex>
|
||||||
</CenteredContent>
|
</CenteredContent>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
.icon {
|
||||||
|
width: 38px;
|
||||||
|
margin-bottom: -3px;
|
||||||
|
margin-right: 20px;
|
||||||
|
opacity: 0.15;
|
||||||
|
}
|
||||||
|
|||||||
39
src/scenes/Search/SearchStore.js
Normal file
39
src/scenes/Search/SearchStore.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { observable, action, runInAction } from 'mobx';
|
||||||
|
import { client } from 'utils/ApiClient';
|
||||||
|
import { browserHistory } from 'react-router';
|
||||||
|
|
||||||
|
class SearchStore {
|
||||||
|
@observable documents;
|
||||||
|
@observable pagination;
|
||||||
|
@observable selectedDocument;
|
||||||
|
@observable searchTerm;
|
||||||
|
|
||||||
|
@observable isFetching = false;
|
||||||
|
|
||||||
|
/* Actions */
|
||||||
|
|
||||||
|
@action search = async (query) => {
|
||||||
|
this.searchTerm = query;
|
||||||
|
this.isFetching = true;
|
||||||
|
|
||||||
|
if (query) {
|
||||||
|
try {
|
||||||
|
const res = await client.post('/documents.search', { query });
|
||||||
|
const { data, pagination } = res;
|
||||||
|
runInAction('search document', () => {
|
||||||
|
this.documents = data;
|
||||||
|
this.pagination = pagination;
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Something went wrong");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.documents = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isFetching = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SearchStore;
|
||||||
32
src/scenes/Search/components/SearchField/SearchField.js
Normal file
32
src/scenes/Search/components/SearchField/SearchField.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import React, { PropTypes } from 'react';
|
||||||
|
import { observer } from 'mobx-react';
|
||||||
|
|
||||||
|
import Flex from 'components/Flex';
|
||||||
|
|
||||||
|
import styles from './SearchField.scss';
|
||||||
|
|
||||||
|
@observer
|
||||||
|
class SearchField extends React.Component {
|
||||||
|
static propTypes = {
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange = (event) => {
|
||||||
|
this.props.onChange(event.currentTarget.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className={ styles.container }>
|
||||||
|
<input
|
||||||
|
onChange={ this.onChange }
|
||||||
|
className={ styles.field }
|
||||||
|
placeholder="Search"
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SearchField;
|
||||||
31
src/scenes/Search/components/SearchField/SearchField.scss
Normal file
31
src/scenes/Search/components/SearchField/SearchField.scss
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
.container {
|
||||||
|
padding: 40px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 48px;
|
||||||
|
font-weight: 400;
|
||||||
|
outline: none;
|
||||||
|
border: 0;
|
||||||
|
// border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global {
|
||||||
|
::-webkit-input-placeholder {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
:-moz-placeholder {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-moz-placeholder {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
:-ms-input-placeholder {
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
src/scenes/Search/components/SearchField/index.js
Normal file
2
src/scenes/Search/components/SearchField/index.js
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
import SearchField from './SearchField';
|
||||||
|
export default SearchField;
|
||||||
Reference in New Issue
Block a user