Skip to content

Commit

Permalink
#55: added autosugest, restructure, created search multiple index, ap…
Browse files Browse the repository at this point in the history
…ply easy style, refactoring
  • Loading branch information
st3phan-cs committed Feb 20, 2020
1 parent e9f0fcb commit c1f1760
Show file tree
Hide file tree
Showing 6 changed files with 349 additions and 40 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@
"tailwindcss": "^1.1.4",
"typeface-montserrat": "^0.0.75",
"webpack": "^4.41.5",
"yallist": "^4.0.0"
"yallist": "^4.0.0",
"react-autosuggest": "^9.4.3",
"@types/react-autosuggest": "^9.3.13"
},
"devDependencies": {
"@babel/core": "^7.8.3",
Expand Down
166 changes: 164 additions & 2 deletions src/assets/theme/src/components/_search_results.sass
Original file line number Diff line number Diff line change
@@ -1,2 +1,164 @@
.ais-Highlight-highlighted
@apply text-celeste
.page-search-reesult
.ais-Highlight-highlighted
@apply text-celeste

.seacrh-header
display: inline-block
width: 100%
margin-bottom: 30px

.left-panel
float: left
width: 65%

.providers,
.pages,
.blog
display: inline-block

ul
li
float: left
width: 100%
margin: 10px 0
padding: 30px 10px 10px 10px
position: relative

&:first-of-type
margin-top: 0

&:after
position: absolute
top: 0
right: 5px
font-size: 20px
font-weight: bold
text-transform: uppercase

.providers
ul
li
border: 1px solid deeppink

&:after
content: 'provider'
color: deeppink

.pages
ul
li
border: 1px solid darkgreen

&:after
content: 'page'
color: darkgreen

.blog
ul
li
border: 1px solid dodgerblue

&:after
content: 'blog post'
color: dodgerblue

.ais-Pagination
clear: left
display: inline-block
margin-bottom: 50px

ul
li
float: left
padding: 5px 10px
margin: 0 10px
border: 1px solid dimgrey
line-height: 1

&:first-of-type
margin-left: 0

&:last-of-type
margin-right: 0

.right-panel
float: right
width: 30%
padding: 10px
border: 1px solid darkslategrey

#stats
text-align: center

.ais-ClearRefinements
display: inline-block
margin: 30px 0

.filter
h2
float: left
width: 100%
clear: left
padding-bottom: 10px
margin-bottom: 10px
border-bottom: 1px solid darkred

.ais-RefinementList
display: inline-block
margin-bottom: 20px

ul
li
display: block
width: 100%
clear: left
bordr-bottom: 1px solid grey

label
display: block
width: 100%
padding: 3px 0

input
float: left
width: auto
margin: 3px 10px 0 0

span
float: left
line-height: 1

&.ais-RefinementList-count
margin: 0 0 0 10px

&:before
content: '('

&:after
content: ')'

.react-autosuggest__container
.react-autosuggest__input
margin: 0

&.react-autosuggest__input--focused,
&.react-autosuggest__input--open
border-radius: 0.25rem 0.25rem 0 0

.react-autosuggest__suggestions-container
display: none
border: 1px solid yellowgreen
border-top: unset
padding: 10px

&.react-autosuggest__suggestions-container--open
display: block

.react-autosuggest__section-title
font-weight: bold
text-transform: uppercase
border-bottom: 1px solid dimgrey

ul.react-autosuggest__suggestions-list
li
border-bottom: 1px solid lightgrey
79 changes: 79 additions & 0 deletions src/components/pages/SearchResult/AutoComplete.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import { Highlight, connectAutoComplete } from 'react-instantsearch-dom';
// @ts-ignore
import AutoSuggest from 'react-autosuggest';

class AutoComplete extends React.Component<{}> {
// @ts-ignore
state = { value: this.props.currentRefinement };

onChange = (event: any, { newValue }: any) => {
this.setState({
value: newValue,
});
};

onSuggestionsFetchRequested = ({ value }: any) => {
// @ts-ignore
this.props.refine(value);
};

onSuggestionsClearRequested = () => {
// @ts-ignore
this.props.refine();
};

getSuggestionValue(hit: any) {
return hit.name;
}

renderSuggestion(hit: any) {
let result: any;
if (hit.name) {
result = <Highlight attribute="name" hit={hit} tagName="mark" />;
} else if (hit.title) {
result = <Highlight attribute="title" hit={hit} tagName="mark" />;
} else {
result = false;
}

return result;
}

renderSectionTitle(section: any) {
return section.index;
}

getSectionSuggestions(section: any) {
return section.hits;
}

render() {
const { hits, onSuggestionSelected }: any = this.props;
const { value } = this.state;

const inputProps = {
placeholder: 'Cauta...',
onChange: this.onChange,
value,
};

return (
<AutoSuggest
suggestions={hits}
multiSection={true}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={onSuggestionSelected}
getSuggestionValue={this.getSuggestionValue}
renderSuggestion={this.renderSuggestion}
inputProps={inputProps}
renderSectionTitle={this.renderSectionTitle}
getSectionSuggestions={this.getSectionSuggestions}
/>
);
}
}

// @ts-ignore
export default connectAutoComplete(AutoComplete);
91 changes: 55 additions & 36 deletions src/components/pages/SearchResult/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,61 @@
import React from 'react';
// Update the import
import {
InstantSearch,
Hits,
SearchBox,
Pagination,
Highlight,
ClearRefinements,
RefinementList,
Configure,
Stats,
Index,
} from 'react-instantsearch-dom';
// for the default version
import algoliasearch from 'algoliasearch';
import AutoComplete from './AutoComplete';

const indexProviders: string | undefined = `${process.env.ALGOLIA_INDEX_NAME_PROVIDERS}`;
// const indexPages: string | undefined = `${process.env.ALGOLIA_INDEX_NAME_PAGES}`;
// const indexBlog: string | undefined = `${process.env.ALGOLIA_INDEX_NAME_BLOG}`;
const indexPages: string | undefined = `${process.env.ALGOLIA_INDEX_NAME_PAGES}`;
const indexBlog: string | undefined = `${process.env.ALGOLIA_INDEX_NAME_BLOG}`;

const client = algoliasearch(`${process.env.ALGOLIA_APP_ID}`, `${process.env.ALGOLIA_API_KEY}`);
const providers = client.initIndex(indexProviders);
// const pages = client.initIndex(indexPages);
// const blog = client.initIndex(indexBlog);

providers
.setSettings({
searchableAttributes: ['name', 'location', 'district', 'address', 'unordered(service)'],
customRanking: ['desc(popularity)'],
attributesForFaceting: ['searchable(name)', 'location', 'district', 'service'],
})
.then(() => {
// done
});

// Update the App component
export default class App extends React.Component {
// const client = algoliasearch('YourApplicationID', 'YourAdminAPIKey');
// const index = client.initIndex('your_index_name');

Hit(props: any) {
hitProviders(props: any) {
const { supplier } = props.hit;
return (
<>
<div className="hit-name">
<strong>Name: </strong>
<Highlight attribute="name" hit={props.hit} />
</div>
<div className="hit-location">
<Highlight attribute="location" hit={props.hit} />,
<Highlight attribute="district" hit={props.hit} />
<strong>Location / District: </strong>
<Highlight attribute="location" hit={props.hit} />, <Highlight attribute="district" hit={props.hit} />
</div>
<div className="hit-location">
<Highlight attribute="location" hit={props.hit} />
{supplier.name && (
<div className="hit-supplier">
<strong>Supplier Name: </strong>
<span>{supplier.name}</span>
</div>
)}
</>
);
}

hitPagesBlog(props: any) {
const { summary } = props.hit;
return (
<>
<div className="hit-name">
<strong>Title: </strong>
<Highlight attribute="title" hit={props.hit} />
</div>
{summary && (
<div className="hit-summary">
<strong>Summary: </strong>
<Highlight attribute="summary" hit={props.hit} />
</div>
)}
</>
);
}
Expand All @@ -60,24 +65,38 @@ export default class App extends React.Component {
<div className="ais-InstantSearch">
<InstantSearch indexName={`${indexProviders}`} searchClient={client}>
<div className="seacrh-header">
<SearchBox />
<div id="stats" className="text-right text-muted">
<Stats />
</div>
<AutoComplete />
</div>
<div className="left-panel">
<div className="items">
<Hits hitComponent={this.Hit} />
</div>
<Pagination />
<Index indexName={`${indexProviders}`}>
<div className="providers">
<Hits hitComponent={this.hitProviders} />
</div>
<Pagination />
</Index>
<Index indexName={`${indexPages}`}>
<div className="pages">
<Hits hitComponent={this.hitPagesBlog} />
</div>
<Pagination />
</Index>
<Index indexName={`${indexBlog}`}>
<div className="blog">
<Hits hitComponent={this.hitPagesBlog} />
</div>
<Pagination />
</Index>
</div>
<div className="right-panel">
<div id="stats" className="text-right text-muted">
<Stats />
</div>
<ClearRefinements />
<div className="filter location">
<h2>Location</h2>
<RefinementList attribute="location" />
</div>
<div className="filter location">
<div className="filter district">
<h2>District</h2>
<RefinementList attribute="district" />
</div>
Expand Down
Loading

0 comments on commit c1f1760

Please sign in to comment.