mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-27 19:42:11 +10:00
Add category search filter
This commit is contained in:
parent
f831172273
commit
2fe85ad730
3 changed files with 154 additions and 2 deletions
|
|
@ -66,12 +66,13 @@
|
|||
|
||||
.modalContainer {
|
||||
width: 100%;
|
||||
padding: 94px 24px;
|
||||
padding: 94px 0;
|
||||
}
|
||||
|
||||
.modalHeadingWrapper {
|
||||
padding-bottom: 26px;
|
||||
border-bottom: 1px solid var(--matterColorNegative);
|
||||
margin: 0 24px 30px 24px;
|
||||
}
|
||||
|
||||
.modalHeading {
|
||||
|
|
@ -99,3 +100,64 @@
|
|||
color: var(--matterColor);
|
||||
}
|
||||
}
|
||||
|
||||
.filterLabel {
|
||||
@apply --marketplaceH3FontStyles;
|
||||
color: var(--matterColorDark);
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.filterLabelSelected {
|
||||
@apply --marketplaceH3FontStyles;
|
||||
color: var(--marketplaceColor);
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
/* left animated "border" like hover element */
|
||||
.optionBorder {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 0px;
|
||||
height: calc(100% - 7px);
|
||||
width: 0;
|
||||
background-color: var(--matterColorDark);
|
||||
transition: width var(--transitionStyleButton);
|
||||
}
|
||||
|
||||
/* left static border for selected element */
|
||||
.optionBorderSelected {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 0px;
|
||||
height: calc(100% - 7px);
|
||||
width: 12px;
|
||||
background-color: var(--matterColorDark);
|
||||
transition: width var(--transitionStyleButton);
|
||||
}
|
||||
|
||||
.option {
|
||||
@apply --marketplaceH3FontStyles;
|
||||
font-weight: var(--fontWeightMedium);
|
||||
color: var(--matterColor);
|
||||
|
||||
/* Layout */
|
||||
display: block;
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 4px 24px 4px 44px;
|
||||
|
||||
/* Override button styles */
|
||||
outline: none;
|
||||
border: none;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
color: var(--matterColorDark);
|
||||
}
|
||||
|
||||
&:hover .menuItemBorder {
|
||||
width: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,63 @@ import PropTypes from 'prop-types';
|
|||
import classNames from 'classnames';
|
||||
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { omit } from 'lodash';
|
||||
|
||||
import routeConfiguration from '../../routeConfiguration';
|
||||
import { createResourceLocatorString } from '../../util/routes';
|
||||
import { SecondaryButton, ModalInMobile } from '../../components';
|
||||
import config from '../../config';
|
||||
import css from './SearchFiltersMobile.css';
|
||||
|
||||
class SelectSingleCustomAttributeMobile extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.selectOption = this.selectOption.bind(this);
|
||||
}
|
||||
|
||||
selectOption(option) {
|
||||
const customAttribute = this.props.customAttribute;
|
||||
console.log(`select option and ca: ${option} - ${customAttribute}`);
|
||||
//this.setState({ isOpen: false });
|
||||
this.props.onSelect(customAttribute, option);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { customAttribute, urlQueryParams, intl } = this.props;
|
||||
const filterLabel = intl.formatMessage({
|
||||
id: `SelectSingleCustomAttribute.${customAttribute}.label`,
|
||||
});
|
||||
// custom attribute content
|
||||
const ca = customAttribute && config.customAttributes[customAttribute];
|
||||
// name of the corresponding query parameter
|
||||
const caParam = `ca_${customAttribute}`;
|
||||
// current value of this custom attribute filter
|
||||
const currentValue = urlQueryParams[caParam];
|
||||
|
||||
const labelClass = currentValue ? css.filterLabelSelected : css.filterLabel;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={labelClass}>
|
||||
{filterLabel}
|
||||
</div>
|
||||
{ca.values.map(v => {
|
||||
// check if this option is selected
|
||||
const selected = currentValue === v;
|
||||
// menu item border class
|
||||
const optionBorderClass = selected ? css.optionBorderSelected : css.optionBorder;
|
||||
return (
|
||||
<button key={v} className={css.option} onClick={() => this.selectOption(v)}>
|
||||
<span className={optionBorderClass} />
|
||||
<FormattedMessage id={`SelectSingleCustomAttributeMobile.category.option.${v}`} />
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SearchFiltersMobileComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
|
@ -24,6 +77,7 @@ class SearchFiltersMobileComponent extends Component {
|
|||
showAsModalMaxWidth,
|
||||
onMapIconClick,
|
||||
onManageDisableScrolling,
|
||||
history,
|
||||
intl,
|
||||
} = this.props;
|
||||
|
||||
|
|
@ -44,6 +98,33 @@ class SearchFiltersMobileComponent extends Component {
|
|||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
|
||||
const onSelectSingle = (customAttribute, option) => {
|
||||
// Name of the corresponding query parameter.
|
||||
// The custom attribute query parameters are named
|
||||
// ca_<custom_attribute_name> in the API.
|
||||
const caParam = `ca_${customAttribute}`;
|
||||
|
||||
// query parameters after selecting the option
|
||||
// if no option is passed, clear the selection for the filter
|
||||
const queryParams = option
|
||||
? { ...urlQueryParams, [caParam]: option }
|
||||
: omit(urlQueryParams, caParam);
|
||||
|
||||
history.push(createResourceLocatorString('SearchPage', routeConfiguration(), {}, queryParams));
|
||||
};
|
||||
|
||||
const customAttribute = 'category';
|
||||
|
||||
const hasCategoryConfig = config.customAttributes && config.customAttributes.category;
|
||||
const categoryFilter = hasCategoryConfig ? (
|
||||
<SelectSingleCustomAttributeMobile
|
||||
customAttribute={customAttribute}
|
||||
urlQueryParams={urlQueryParams}
|
||||
onSelect={onSelectSingle}
|
||||
intl={intl}
|
||||
/>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
<div className={css.searchResultSummary}>
|
||||
|
|
@ -73,7 +154,10 @@ class SearchFiltersMobileComponent extends Component {
|
|||
<FormattedMessage id={'SearchFiltersMobile.resetAll'} />
|
||||
</button>
|
||||
</div>
|
||||
<div className={css.mobileFilterWrapper} />
|
||||
<div className={css.filtersContainer}>{categoryFilter}</div>
|
||||
<button onClick={closeMobileFilters}>
|
||||
"Show saunas"
|
||||
</button>
|
||||
</ModalInMobile>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -502,6 +502,12 @@
|
|||
"SelectSingleCustomAttribute.category.option.road": "Road",
|
||||
"SelectSingleCustomAttribute.category.option.track": "Track",
|
||||
"SelectSingleCustomAttribute.clear": "Clear",
|
||||
"SelectSingleCustomAttributeMobile.category.label": "Category",
|
||||
"SelectSingleCustomAttributeMobile.category.option.mountain": "Mountain",
|
||||
"SelectSingleCustomAttributeMobile.category.option.other": "Other",
|
||||
"SelectSingleCustomAttributeMobile.category.option.road": "Road",
|
||||
"SelectSingleCustomAttributeMobile.category.option.track": "Track",
|
||||
"SelectSingleCustomAttributeMobile.clear": "Clear",
|
||||
"SendMessageForm.sendFailed": "Failed to send. Please try again.",
|
||||
"SendMessageForm.sendMessage": "Send message",
|
||||
"SignupForm.emailInvalid": "A valid email address is required",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue