Add features filter

This commit is contained in:
Hannu Lyytikainen 2018-02-02 21:09:45 +02:00
parent d850bc1286
commit 8c362b6dca
3 changed files with 87 additions and 4 deletions

View file

@ -6,12 +6,15 @@ import classNames from 'classnames';
import { withRouter } from 'react-router-dom';
import { omit } from 'lodash';
import { SelectSingleFilter } from '../../components';
import { SelectSingleFilter, SelectMultipleFilter } from '../../components';
import routeConfiguration from '../../routeConfiguration';
import { createResourceLocatorString } from '../../util/routes';
import css from './SearchFilters.css';
const CATEGORY_URL_PARAM = 'pub_category';
const FEATURES_URL_PARAM = 'pub_features';
const FILTER_OFFSET = -14;
const SearchFiltersComponent = props => {
const {
@ -22,6 +25,7 @@ const SearchFiltersComponent = props => {
resultsCount,
searchInProgress,
categories,
features,
history,
intl,
} = props;
@ -40,6 +44,19 @@ const SearchFiltersComponent = props => {
id: 'SearchFilters.categoryLabel',
});
const initialFeatures =
urlQueryParams[FEATURES_URL_PARAM] && urlQueryParams[FEATURES_URL_PARAM].split(',');
const handleSelectOptions = options => {
console.log('Select features', options);
const queryParams = options
? { ...urlQueryParams, [FEATURES_URL_PARAM]: options.join(',') }
: omit(urlQueryParams, FEATURES_URL_PARAM);
history.push(createResourceLocatorString('SearchPage', routeConfiguration(), {}, queryParams));
};
const onSelectOption = (urlParam, option) => {
// query parameters after selecting the option
// if no option is passed, clear the selection for the filter
@ -57,12 +74,25 @@ const SearchFiltersComponent = props => {
paramLabel={categoryLabel}
onSelect={onSelectOption}
options={categories}
contentPlacementOffset={-14}
contentPlacementOffset={FILTER_OFFSET}
/>
) : null;
const featuresFilter = features ? (
<SelectMultipleFilter
onSubmit={handleSelectOptions}
options={features}
initialValues={initialFeatures}
contentPlacementOffset={FILTER_OFFSET}
/>
) : null;
return (
<div className={classes}>
<div className={css.filters}>{categoryFilter}</div>
<div className={css.filters}>
{categoryFilter}
{featuresFilter}
</div>
<div className={css.searchResultSummary}>
{listingsAreLoaded && resultsCount > 0 ? resultsFound : null}
@ -79,6 +109,7 @@ SearchFiltersComponent.defaultProps = {
resultsCount: null,
searchingInProgress: false,
categories: null,
features: null,
};
SearchFiltersComponent.propTypes = {
@ -91,6 +122,7 @@ SearchFiltersComponent.propTypes = {
onMapIconClick: func.isRequired,
onManageDisableScrolling: func.isRequired,
categories: array,
features: array,
// from withRouter
history: shape({

View file

@ -43,11 +43,18 @@ const SEARCH_WITH_MAP_DEBOUNCE = 300; // Little bit of debounce before search is
const BOUNDS_FIXED_PRECISION = 8;
const CATEGORY_URL_PARAM = 'pub_category';
const FEATURES_URL_PARAM = 'pub_features';
// extract search parameters, including a custom attribute named category
const pickSearchParamsOnly = params => {
const { address, origin, bounds, ...rest } = params || {};
return { address, origin, bounds, [CATEGORY_URL_PARAM]: rest[CATEGORY_URL_PARAM] };
return {
address,
origin,
bounds,
[CATEGORY_URL_PARAM]: rest[CATEGORY_URL_PARAM],
[FEATURES_URL_PARAM]: rest[FEATURES_URL_PARAM],
};
};
export class SearchPageComponent extends Component {
@ -103,6 +110,7 @@ export class SearchPageComponent extends Component {
latlngBounds: ['bounds'],
});
const category = rest[CATEGORY_URL_PARAM];
const features = rest[FEATURES_URL_PARAM];
const viewportGMapBounds = googleMap.getBounds();
const viewportBounds = sdkBoundsToFixedCoordinates(
@ -124,6 +132,7 @@ export class SearchPageComponent extends Component {
country,
mapSearch: true,
[CATEGORY_URL_PARAM]: category,
[FEATURES_URL_PARAM]: features,
};
history.push(
createResourceLocatorString('SearchPage', routeConfiguration(), {}, searchParams)
@ -189,6 +198,7 @@ export class SearchPageComponent extends Component {
searchListingsError,
searchParams,
categories,
features,
} = this.props;
// eslint-disable-next-line no-unused-vars
const { mapSearch, page, ...searchInURL } = parse(location.search, {
@ -306,6 +316,7 @@ export class SearchPageComponent extends Component {
onMapIconClick={onMapIconClick}
onManageDisableScrolling={onManageDisableScrolling}
categories={categories}
features={features}
/>
<SearchFiltersMobile
className={css.searchFiltersMobile}
@ -361,6 +372,7 @@ SearchPageComponent.defaultProps = {
searchParams: {},
tab: 'listings',
categories: config.custom.categories,
features: config.custom.amenities,
};
const { array, bool, func, oneOf, object, shape, string } = PropTypes;
@ -377,6 +389,7 @@ SearchPageComponent.propTypes = {
searchParams: object,
tab: oneOf(['filters', 'listings', 'map']).isRequired,
categories: array,
features: array,
// from withRouter
history: shape({

View file

@ -33,6 +33,42 @@ exports[`SearchPageComponent matches snapshot 1`] = `
},
]
}
features={
Array [
Object {
"key": "towels",
"label": "Towels",
},
Object {
"key": "bathroom",
"label": "Bathroom",
},
Object {
"key": "swimming_pool",
"label": "Swimming pool",
},
Object {
"key": "own_drinks",
"label": "Own drinks allowed",
},
Object {
"key": "jacuzzi",
"label": "Jacuzzi",
},
Object {
"key": "audiovisual_entertainment",
"label": "Audiovisual entertainment",
},
Object {
"key": "barbeque",
"label": "Barbeque",
},
Object {
"key": "own_food_allowed",
"label": "Own food allowed",
},
]
}
listingsAreLoaded={true}
onManageDisableScrolling={[Function]}
onMapIconClick={[Function]}
@ -45,6 +81,7 @@ exports[`SearchPageComponent matches snapshot 1`] = `
"bounds": undefined,
"origin": undefined,
"pub_category": undefined,
"pub_features": undefined,
}
}
/>
@ -76,6 +113,7 @@ exports[`SearchPageComponent matches snapshot 1`] = `
"bounds": undefined,
"origin": undefined,
"pub_category": undefined,
"pub_features": undefined,
}
}
/>