Skip to content

Instantly share code, notes, and snippets.

@jlei523

jlei523/Search.js

Last active Nov 17, 2019
Embed
What would you like to do?
import React from "react";
import Autosuggest from "react-autosuggest";
import "../../style.css";
import BuildingsSVG from "../../static/buildings.svg";
import UnitsSVG from "../../static/units.svg";
import match from "autosuggest-highlight/match";
import parse from "autosuggest-highlight/parse";
import axios from "axios";
import slugify from "slugify";
import Router from "next/router";
const formatMultiSection = data => {
let buildings = data.filter(value => {
return value.type === "building";
});
let units = data.filter(value => {
return value.type === "unit";
});
let buildingsObj = {
type: "Buildings",
results: buildings
};
let unitsObj = {
type: "Units",
results: units
};
let suggestions = [];
if (buildingsObj.results.length > 0) {
suggestions.push(buildingsObj);
}
if (unitsObj.results.length > 0) {
suggestions.push(unitsObj);
}
return suggestions;
};
const getSectionSuggestions = section => {
return section.results;
};
const getSuggestionValue = suggestion => {
return suggestion.label;
};
const renderSuggestion = (suggestion, { query }) => {
const suggestionText = suggestion.label;
const suggestionAddress = suggestion.buildingaddress;
const matches = match(suggestionText, query);
const parts = parse(suggestionText, matches);
return (
<div className={"suggestion-content"}>
<div>
{parts.map((part, index) =>
part.highlight ? (
<span key={String(index)} style={{ fontWeight: 600 }}>
{part.text}
</span>
) : (
<strong key={String(index)} style={{ fontWeight: 400 }}>
{part.text}
</strong>
)
)}
</div>
<div
style={{
color: "#1D2C4C",
fontSize: 13,
fontWeight: 400,
marginTop: 10
}}
>
{suggestionAddress}
</div>
</div>
);
};
const renderSectionTitle = section => {
if (section.type === "Buildings") {
return (
<div style={{ display: "flex", alignItems: "flex-end" }}>
<div style={{ marginRight: 8 }}>
<BuildingsSVG />
</div>
<strong style={{ color: "#1D2C4C" }}>{section.type}</strong>
</div>
);
} else {
return (
<div style={{ display: "flex", alignItems: "flex-end" }}>
<div style={{ marginRight: 8 }}>
<UnitsSVG />
</div>
<strong style={{ color: "#1D2C4C" }}>{section.type}</strong>
</div>
);
}
};
class App extends React.Component {
state = {
value: "",
suggestions: []
};
onChange = (event, { newValue, method }) => {
this.setState({
value: newValue
});
};
onSuggestionsFetchRequested = ({ value }) => {
axios.get(`/autocomplete2/${value}`).then(data => {
if (data.data.length) {
this.setState({
suggestions: formatMultiSection(data.data)
});
}
});
};
onSuggestionsClearRequested = () => {
this.setState({
suggestions: []
});
};
handleSelected = (event, data) => {
const url = slugify(data.suggestion.label, {
remove: /[*+~.(),'"/!:@-]/g,
lower: true
});
if (data.suggestion.type === "unit") {
Router.push(
`/property?id=${data.suggestion.unitcode}`,
`/property/${url}/${data.suggestion.unitcode}`
).then(() => window.scrollTo(0, 0));
} else {
Router.push(
`/building?id=${data.suggestion.buildingcode}`,
`/property/${url}/${data.suggestion.buildingcode}`
).then(() => window.scrollTo(0, 0));
}
};
render() {
const { value, suggestions } = this.state;
const inputProps = {
placeholder: "Search by building or address",
value,
onChange: this.onChange
};
return (
<Autosuggest
multiSection={true}
suggestions={suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={inputProps}
renderSectionTitle={renderSectionTitle}
getSectionSuggestions={getSectionSuggestions}
onSuggestionSelected={this.handleSelected}
highlightFirstSuggestion={true}
/>
);
}
}
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment