mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-28 20:53:24 +10:00
Merge pull request #671 from sharetribe/category-config
Categories in publicData
This commit is contained in:
commit
071b46c540
27 changed files with 251 additions and 348 deletions
|
|
@ -6,6 +6,7 @@ import { ensureListing } from '../../util/data';
|
|||
import { createSlug } from '../../util/urlHelpers';
|
||||
import { NamedLink } from '../../components';
|
||||
import { EditListingDescriptionForm } from '../../containers';
|
||||
import config from '../../config';
|
||||
|
||||
import css from './EditListingDescriptionPanel.css';
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ const EditListingDescriptionPanel = props => {
|
|||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
const currentListing = ensureListing(listing);
|
||||
const { description, title, customAttributes } = currentListing.attributes;
|
||||
const { description, title, publicData } = currentListing.attributes;
|
||||
const listingTitle = title || '';
|
||||
const listingLink = currentListing.id ? (
|
||||
<NamedLink name="ListingPage" params={{ id: currentListing.id.uuid, slug: createSlug(title) }}>
|
||||
|
|
@ -48,14 +49,19 @@ const EditListingDescriptionPanel = props => {
|
|||
<h1 className={css.title}>{panelTitle}</h1>
|
||||
<EditListingDescriptionForm
|
||||
className={css.form}
|
||||
initialValues={{ title, description, ...customAttributes }}
|
||||
initialValues={{ title, description, category: publicData.category }}
|
||||
saveActionMsg={submitButtonText}
|
||||
onSubmit={values => {
|
||||
const { title, description, category } = values;
|
||||
const updateValues = {
|
||||
title,
|
||||
description,
|
||||
|
||||
// Save category also to the deprecated customAttributes
|
||||
// so it can be used in search.
|
||||
// TODO: remove when publicData is used in search
|
||||
customAttributes: { category },
|
||||
|
||||
publicData: { category },
|
||||
};
|
||||
|
||||
|
|
@ -65,6 +71,7 @@ const EditListingDescriptionPanel = props => {
|
|||
updated={panelUpdated}
|
||||
updateError={errors.updateListingError}
|
||||
updateInProgress={updateInProgress}
|
||||
categories={config.custom.categories}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -191,7 +191,6 @@ EditListingWizard.propTypes = {
|
|||
// We cannot use propTypes.listing since the listing might be a draft.
|
||||
listing: shape({
|
||||
attributes: shape({
|
||||
customAttributes: object, // structure (key: value) can be defined in management console
|
||||
publicData: object,
|
||||
description: string,
|
||||
geolocation: object,
|
||||
|
|
|
|||
|
|
@ -219,7 +219,6 @@ EditListingWizardTab.propTypes = {
|
|||
// We cannot use propTypes.listing since the listing might be a draft.
|
||||
listing: shape({
|
||||
attributes: shape({
|
||||
customAttributes: object, // structure (key: value) can be defined in management console
|
||||
publicData: object,
|
||||
description: string,
|
||||
geolocation: object,
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
@import '../../marketplace.css';
|
||||
|
||||
.root {
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
import React from 'react';
|
||||
import { string } from 'prop-types';
|
||||
import { intlShape, injectIntl } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import config from '../../config';
|
||||
import { required } from '../../util/validators';
|
||||
import { SelectField } from '../../components';
|
||||
|
||||
import css from './FieldCustomAttributeSelect.css';
|
||||
|
||||
const FieldCustomAttributeSelect = props => {
|
||||
const { className, rootClassName, id, customAttribute, intl } = props;
|
||||
|
||||
// Does custom attribute 'customAttribute' exists in current marketplace configuration
|
||||
const ca = config.customAttributes && config.customAttributes[customAttribute];
|
||||
const isSingleChoice = ca && ca.select === 'single' && ca.type === 'string';
|
||||
|
||||
// If custom attribute config for given 'customAttribute' doesn't exist, don't print SelectField
|
||||
if (!isSingleChoice) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const caLabel = intl.formatMessage({ id: `FieldCustomAttributeSelect.${customAttribute}.label` });
|
||||
const caPlaceholder = intl.formatMessage({
|
||||
id: `FieldCustomAttributeSelect.${customAttribute}.placeholder`,
|
||||
});
|
||||
const caRequired = required(
|
||||
intl.formatMessage({
|
||||
id: `FieldCustomAttributeSelect.${customAttribute}.required`,
|
||||
})
|
||||
);
|
||||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
|
||||
return (
|
||||
<SelectField
|
||||
className={classes}
|
||||
name={customAttribute}
|
||||
id={id}
|
||||
label={caLabel}
|
||||
validate={caRequired}
|
||||
>
|
||||
<option value="">{caPlaceholder}</option>
|
||||
{ca.values.map(c => (
|
||||
<option key={c} value={c}>
|
||||
{intl.formatMessage({ id: `FieldCustomAttributeSelect.${customAttribute}.option.${c}` })}
|
||||
</option>
|
||||
))}
|
||||
</SelectField>
|
||||
);
|
||||
};
|
||||
|
||||
FieldCustomAttributeSelect.defaultProps = {
|
||||
className: null,
|
||||
rootClassName: null,
|
||||
};
|
||||
|
||||
FieldCustomAttributeSelect.propTypes = {
|
||||
className: string,
|
||||
rootClassName: string,
|
||||
id: string.isRequired,
|
||||
customAttribute: string.isRequired,
|
||||
|
||||
// From react-intl
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
export default injectIntl(FieldCustomAttributeSelect);
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { compose } from 'redux';
|
||||
import { object, string, bool, number, func, shape, array } from 'prop-types';
|
||||
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { omit } from 'lodash';
|
||||
|
|
@ -8,9 +9,10 @@ import { omit } from 'lodash';
|
|||
import { SelectSingleFilter } from '../../components';
|
||||
import routeConfiguration from '../../routeConfiguration';
|
||||
import { createResourceLocatorString } from '../../util/routes';
|
||||
import config from '../../config';
|
||||
import css from './SearchFilters.css';
|
||||
|
||||
const CATEGORY_URL_PARAM = 'ca_category';
|
||||
|
||||
const SearchFiltersComponent = props => {
|
||||
const {
|
||||
rootClassName,
|
||||
|
|
@ -19,7 +21,9 @@ const SearchFiltersComponent = props => {
|
|||
listingsAreLoaded,
|
||||
resultsCount,
|
||||
searchInProgress,
|
||||
categories,
|
||||
history,
|
||||
intl,
|
||||
} = props;
|
||||
|
||||
const loadingResults = <FormattedMessage id="SearchFilters.loadingResults" />;
|
||||
|
|
@ -32,27 +36,27 @@ const SearchFiltersComponent = props => {
|
|||
|
||||
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}`;
|
||||
const categoryLabel = intl.formatMessage({
|
||||
id: 'SearchFilters.categoryLabel',
|
||||
});
|
||||
|
||||
const onSelectOption = (urlParam, option) => {
|
||||
// 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);
|
||||
? { ...urlQueryParams, [urlParam]: option }
|
||||
: omit(urlQueryParams, urlParam);
|
||||
|
||||
history.push(createResourceLocatorString('SearchPage', routeConfiguration(), {}, queryParams));
|
||||
};
|
||||
|
||||
const hasCategoryConfig = config.customAttributes && config.customAttributes.category;
|
||||
const categoryFilter = hasCategoryConfig ? (
|
||||
const categoryFilter = categories ? (
|
||||
<SelectSingleFilter
|
||||
customAttribute="category"
|
||||
urlQueryParams={urlQueryParams}
|
||||
onSelect={onSelectSingle}
|
||||
urlParam={CATEGORY_URL_PARAM}
|
||||
paramLabel={categoryLabel}
|
||||
onSelect={onSelectOption}
|
||||
options={categories}
|
||||
/>
|
||||
) : null;
|
||||
return (
|
||||
|
|
@ -68,13 +72,12 @@ const SearchFiltersComponent = props => {
|
|||
);
|
||||
};
|
||||
|
||||
const { object, string, bool, number, func, shape } = PropTypes;
|
||||
|
||||
SearchFiltersComponent.defaultProps = {
|
||||
rootClassName: null,
|
||||
className: null,
|
||||
resultsCount: null,
|
||||
searchingInProgress: false,
|
||||
categories: null,
|
||||
};
|
||||
|
||||
SearchFiltersComponent.propTypes = {
|
||||
|
|
@ -86,13 +89,17 @@ SearchFiltersComponent.propTypes = {
|
|||
searchingInProgress: bool,
|
||||
onMapIconClick: func.isRequired,
|
||||
onManageDisableScrolling: func.isRequired,
|
||||
categories: array,
|
||||
|
||||
// from withRouter
|
||||
history: shape({
|
||||
push: func.isRequired,
|
||||
}).isRequired,
|
||||
|
||||
// from injectIntl
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
const SearchFilters = withRouter(SearchFiltersComponent);
|
||||
const SearchFilters = compose(withRouter, injectIntl)(SearchFiltersComponent);
|
||||
|
||||
export default SearchFilters;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { object, string, bool, number, func, shape, array } from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
|
@ -8,18 +8,16 @@ import { omit, toPairs } from 'lodash';
|
|||
import routeConfiguration from '../../routeConfiguration';
|
||||
import { createResourceLocatorString } from '../../util/routes';
|
||||
import { SecondaryButton, ModalInMobile, Button, SelectSingleFilterMobile } from '../../components';
|
||||
import config from '../../config';
|
||||
import css from './SearchFiltersMobile.css';
|
||||
|
||||
// prefix for all custom attribute query params
|
||||
const CA_PREFIX = 'ca_';
|
||||
const CATEGORY_URL_PARAM = 'ca_category';
|
||||
|
||||
const validateParamValue = value => value !== null && value !== undefined && value.length > 0;
|
||||
|
||||
// Check if a filter parameter is included query parameters
|
||||
const hasFilterQueryParams = queryParams => {
|
||||
const firstFilterParam = toPairs(queryParams).find(entry => {
|
||||
return !!(entry[0].startsWith(CA_PREFIX) && validateParamValue(entry[1]));
|
||||
return validateParamValue(entry[1]);
|
||||
});
|
||||
return !!firstFilterParam;
|
||||
};
|
||||
|
|
@ -29,9 +27,6 @@ class SearchFiltersMobileComponent extends Component {
|
|||
super(props);
|
||||
this.state = { isFiltersOpenOnMobile: false };
|
||||
|
||||
//TODO: take as props
|
||||
this.customAttribute = 'category';
|
||||
|
||||
this.openFilters = this.openFilters.bind(this);
|
||||
this.cancelFilters = this.cancelFilters.bind(this);
|
||||
this.closeFilters = this.closeFilters.bind(this);
|
||||
|
|
@ -68,19 +63,14 @@ class SearchFiltersMobileComponent extends Component {
|
|||
this.setState({ isFiltersOpenOnMobile: false });
|
||||
}
|
||||
|
||||
onSelectSingle(customAttribute, option) {
|
||||
onSelectSingle(urlParam, option) {
|
||||
const { urlQueryParams, history } = this.props;
|
||||
|
||||
// Name of the corresponding query parameter.
|
||||
// The custom attribute query parameters are named
|
||||
// ca_<custom_attribute_name> in the API.
|
||||
const caParam = `${CA_PREFIX}${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);
|
||||
? { ...urlQueryParams, [urlParam]: option }
|
||||
: omit(urlQueryParams, urlParam);
|
||||
|
||||
history.push(createResourceLocatorString('SearchPage', routeConfiguration(), {}, queryParams));
|
||||
}
|
||||
|
|
@ -89,8 +79,7 @@ class SearchFiltersMobileComponent extends Component {
|
|||
resetAll(e) {
|
||||
const { urlQueryParams, history } = this.props;
|
||||
|
||||
const caParam = `${CA_PREFIX}${this.customAttribute}`;
|
||||
const queryParams = omit(urlQueryParams, caParam);
|
||||
const queryParams = omit(urlQueryParams, CATEGORY_URL_PARAM);
|
||||
history.push(createResourceLocatorString('SearchPage', routeConfiguration(), {}, queryParams));
|
||||
|
||||
// blur event target if event is passed
|
||||
|
|
@ -110,6 +99,7 @@ class SearchFiltersMobileComponent extends Component {
|
|||
showAsModalMaxWidth,
|
||||
onMapIconClick,
|
||||
onManageDisableScrolling,
|
||||
categories,
|
||||
intl,
|
||||
} = this.props;
|
||||
|
||||
|
|
@ -138,12 +128,16 @@ class SearchFiltersMobileComponent extends Component {
|
|||
</SecondaryButton>
|
||||
);
|
||||
|
||||
const hasCategoryConfig = config.customAttributes && config.customAttributes.category;
|
||||
const categoryFilter = hasCategoryConfig ? (
|
||||
const categoryLabel = intl.formatMessage({
|
||||
id: 'SearchFiltersMobile.categoryLabel',
|
||||
});
|
||||
const categoryFilter = categories ? (
|
||||
<SelectSingleFilterMobile
|
||||
customAttribute={this.customAttribute}
|
||||
urlQueryParams={urlQueryParams}
|
||||
urlParam={CATEGORY_URL_PARAM}
|
||||
paramLabel={categoryLabel}
|
||||
onSelect={this.onSelectSingle}
|
||||
options={categories}
|
||||
intl={intl}
|
||||
/>
|
||||
) : null;
|
||||
|
|
@ -188,8 +182,6 @@ class SearchFiltersMobileComponent extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
const { object, string, bool, number, func, shape } = PropTypes;
|
||||
|
||||
SearchFiltersMobileComponent.defaultProps = {
|
||||
rootClassName: null,
|
||||
className: null,
|
||||
|
|
@ -211,6 +203,7 @@ SearchFiltersMobileComponent.propTypes = {
|
|||
onManageDisableScrolling: func.isRequired,
|
||||
onOpenModal: func,
|
||||
onCloseModal: func,
|
||||
categories: array,
|
||||
|
||||
// from injectIntl
|
||||
intl: intlShape.isRequired,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
||||
import { object, string, func, arrayOf, shape } from 'prop-types';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import config from '../../config';
|
||||
import { Menu, MenuContent, MenuItem, MenuLabel } from '../../components';
|
||||
import css from './SelectSingleFilter.css';
|
||||
|
||||
class SelectSingleFilterComponent extends Component {
|
||||
const optionLabel = (options, key) => {
|
||||
const option = options.find(o => o.key === key);
|
||||
return option ? option.label : key;
|
||||
};
|
||||
|
||||
class SelectSingleFilter extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
|
@ -20,25 +24,19 @@ class SelectSingleFilterComponent extends Component {
|
|||
this.setState({ isOpen: isOpen });
|
||||
}
|
||||
|
||||
selectOption(customAttribute, option) {
|
||||
selectOption(urlParam, option) {
|
||||
this.setState({ isOpen: false });
|
||||
this.props.onSelect(customAttribute, option);
|
||||
this.props.onSelect(urlParam, option);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { rootClassName, className, customAttribute, urlQueryParams, intl } = this.props;
|
||||
const { rootClassName, className, urlQueryParams, urlParam, paramLabel, options } = this.props;
|
||||
|
||||
// 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 currentValue = urlQueryParams[urlParam];
|
||||
|
||||
// resolve menu label text and class
|
||||
const menuLabel = currentValue
|
||||
? intl.formatMessage({ id: `SelectSingleFilter.category.option.${currentValue}` })
|
||||
: intl.formatMessage({ id: `SelectSingleFilter.${customAttribute}.label` });
|
||||
const menuLabel = currentValue ? optionLabel(options, currentValue) : paramLabel;
|
||||
const menuLabelClass = currentValue ? css.menuLabelSelected : css.menuLabel;
|
||||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
|
|
@ -53,29 +51,26 @@ class SelectSingleFilterComponent extends Component {
|
|||
>
|
||||
<MenuLabel className={menuLabelClass}>{menuLabel}</MenuLabel>
|
||||
<MenuContent className={css.menuContent}>
|
||||
{ca.values.map(v => {
|
||||
{options.map(option => {
|
||||
// check if this option is selected
|
||||
const selected = currentValue === v;
|
||||
const selected = currentValue === option.key;
|
||||
// menu item border class
|
||||
const menuItemBorderClass = selected ? css.menuItemBorderSelected : css.menuItemBorder;
|
||||
|
||||
return (
|
||||
<MenuItem key={v}>
|
||||
<MenuItem key={option.key}>
|
||||
<button
|
||||
className={css.menuItem}
|
||||
onClick={() => this.selectOption(customAttribute, v)}
|
||||
onClick={() => this.selectOption(urlParam, option.key)}
|
||||
>
|
||||
<span className={menuItemBorderClass} />
|
||||
<FormattedMessage id={`SelectSingleFilter.category.option.${v}`} />
|
||||
{option.label}
|
||||
</button>
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
<MenuItem key={'clearLink'}>
|
||||
<button
|
||||
className={css.clearMenuItem}
|
||||
onClick={() => this.selectOption(customAttribute, null)}
|
||||
>
|
||||
<button className={css.clearMenuItem} onClick={() => this.selectOption(urlParam, null)}>
|
||||
<FormattedMessage id={'SelectSingleFilter.clear'} />
|
||||
</button>
|
||||
</MenuItem>
|
||||
|
|
@ -85,24 +80,25 @@ class SelectSingleFilterComponent extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
const { object, string, func } = PropTypes;
|
||||
|
||||
SelectSingleFilterComponent.defaultProps = {
|
||||
SelectSingleFilter.defaultProps = {
|
||||
rootClassName: null,
|
||||
className: null,
|
||||
};
|
||||
|
||||
SelectSingleFilterComponent.propTypes = {
|
||||
SelectSingleFilter.propTypes = {
|
||||
rootClassName: string,
|
||||
className: string,
|
||||
customAttribute: string.isRequired,
|
||||
urlQueryParams: object.isRequired,
|
||||
urlParam: string.isRequired,
|
||||
paramLabel: string.isRequired,
|
||||
onSelect: func.isRequired,
|
||||
|
||||
// from injectIntl
|
||||
intl: intlShape.isRequired,
|
||||
options: arrayOf(
|
||||
shape({
|
||||
key: string.isRequired,
|
||||
label: string.isRequired,
|
||||
})
|
||||
).isRequired,
|
||||
};
|
||||
|
||||
const SelectSingleFilter = injectIntl(SelectSingleFilterComponent);
|
||||
|
||||
export default SelectSingleFilter;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { object, string, func, arrayOf, shape } from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import config from '../../config';
|
||||
import css from './SelectSingleFilterMobile.css';
|
||||
|
||||
class SelectSingleFilterMobileComponent extends Component {
|
||||
class SelectSingleFilterMobile extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { isOpen: true };
|
||||
|
|
@ -15,8 +14,8 @@ class SelectSingleFilterMobileComponent extends Component {
|
|||
}
|
||||
|
||||
selectOption(option, e) {
|
||||
const { customAttribute, onSelect } = this.props;
|
||||
onSelect(customAttribute, option);
|
||||
const { urlParam, onSelect } = this.props;
|
||||
onSelect(urlParam, option);
|
||||
|
||||
// blur event target if event is passed
|
||||
if (e && e.currentTarget) {
|
||||
|
|
@ -29,17 +28,10 @@ class SelectSingleFilterMobileComponent extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { rootClassName, className, customAttribute, urlQueryParams, intl } = this.props;
|
||||
const { rootClassName, className, urlQueryParams, urlParam, paramLabel, options } = this.props;
|
||||
|
||||
const filterLabel = intl.formatMessage({
|
||||
id: `SelectSingleFilterMobile.${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 currentValue = urlQueryParams[urlParam];
|
||||
|
||||
const labelClass = currentValue ? css.filterLabelSelected : css.filterLabel;
|
||||
|
||||
|
|
@ -53,22 +45,26 @@ class SelectSingleFilterMobileComponent extends Component {
|
|||
<div className={classes}>
|
||||
<div className={labelClass}>
|
||||
<button className={css.labelButton} onClick={this.toggleIsOpen}>
|
||||
<span className={labelClass}>{filterLabel}</span>
|
||||
<span className={labelClass}>{paramLabel}</span>
|
||||
</button>
|
||||
<button className={css.clearButton} onClick={e => this.selectOption(null, e)}>
|
||||
<FormattedMessage id={'SelectSingleFilterMobile.clear'} />
|
||||
</button>
|
||||
</div>
|
||||
<div className={optionsContainerClass}>
|
||||
{ca.values.map(v => {
|
||||
{options.map(option => {
|
||||
// check if this option is selected
|
||||
const selected = currentValue === v;
|
||||
const selected = currentValue === option.key;
|
||||
// menu item border class
|
||||
const optionBorderClass = selected ? css.optionBorderSelected : css.optionBorder;
|
||||
return (
|
||||
<button key={v} className={css.option} onClick={() => this.selectOption(v)}>
|
||||
<button
|
||||
key={option.key}
|
||||
className={css.option}
|
||||
onClick={() => this.selectOption(option.key)}
|
||||
>
|
||||
<span className={optionBorderClass} />
|
||||
<FormattedMessage id={`SelectSingleFilterMobile.category.option.${v}`} />
|
||||
{option.label}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
|
|
@ -78,24 +74,25 @@ class SelectSingleFilterMobileComponent extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
const { object, string, func } = PropTypes;
|
||||
|
||||
SelectSingleFilterMobileComponent.defaultProps = {
|
||||
SelectSingleFilterMobile.defaultProps = {
|
||||
rootClassName: null,
|
||||
className: null,
|
||||
};
|
||||
|
||||
SelectSingleFilterMobileComponent.propTypes = {
|
||||
SelectSingleFilterMobile.propTypes = {
|
||||
rootClassName: string,
|
||||
className: string,
|
||||
customAttribute: string.isRequired,
|
||||
urlQueryParams: object.isRequired,
|
||||
urlParam: string.isRequired,
|
||||
paramLabel: string.isRequired,
|
||||
onSelect: func.isRequired,
|
||||
|
||||
// from injectIntl
|
||||
intl: intlShape.isRequired,
|
||||
options: arrayOf(
|
||||
shape({
|
||||
key: string.isRequired,
|
||||
label: string.isRequired,
|
||||
})
|
||||
).isRequired,
|
||||
};
|
||||
|
||||
const SelectSingleFilterMobile = injectIntl(SelectSingleFilterMobileComponent);
|
||||
|
||||
export default SelectSingleFilterMobile;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -168,7 +167,6 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -300,7 +298,6 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -429,7 +426,6 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -558,7 +554,6 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -805,7 +800,6 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -915,7 +909,6 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -1028,7 +1021,6 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -1160,7 +1152,6 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -1289,7 +1280,6 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -1418,7 +1408,6 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -1665,7 +1654,6 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -1775,7 +1763,6 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -1888,7 +1875,6 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -2020,7 +2006,6 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -2149,7 +2134,6 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -2278,7 +2262,6 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -2525,7 +2508,6 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -2635,7 +2617,6 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -2748,7 +2729,6 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -2880,7 +2860,6 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -3009,7 +2988,6 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -3138,7 +3116,6 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -3385,7 +3362,6 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -3495,7 +3471,6 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -3608,7 +3583,6 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -3740,7 +3714,6 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -3869,7 +3842,6 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -3998,7 +3970,6 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -4245,7 +4216,6 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -4355,7 +4325,6 @@ exports[`TransactionPanel - Order enquired matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -4468,7 +4437,6 @@ exports[`TransactionPanel - Order enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -4600,7 +4568,6 @@ exports[`TransactionPanel - Order enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -4729,7 +4696,6 @@ exports[`TransactionPanel - Order enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -4858,7 +4824,6 @@ exports[`TransactionPanel - Order enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -5105,7 +5070,6 @@ exports[`TransactionPanel - Order enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -5215,7 +5179,6 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -5328,7 +5291,6 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -5460,7 +5422,6 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -5589,7 +5550,6 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -5718,7 +5678,6 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -5965,7 +5924,6 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -6069,7 +6027,6 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -6182,7 +6139,6 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -6301,7 +6257,6 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -6418,7 +6373,6 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -6535,7 +6489,6 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -6770,7 +6723,6 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -6861,7 +6813,6 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -6974,7 +6925,6 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -7093,7 +7043,6 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -7210,7 +7159,6 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -7327,7 +7275,6 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -7562,7 +7509,6 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -7653,7 +7599,6 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -7766,7 +7711,6 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -7885,7 +7829,6 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -8002,7 +7945,6 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -8119,7 +8061,6 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -8354,7 +8295,6 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -8445,7 +8385,6 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -8558,7 +8497,6 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -8677,7 +8615,6 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -8794,7 +8731,6 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -8911,7 +8847,6 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -9146,7 +9081,6 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -9237,7 +9171,6 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -9350,7 +9283,6 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -9469,7 +9401,6 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -9586,7 +9517,6 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -9703,7 +9633,6 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -9938,7 +9867,6 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -10029,7 +9957,6 @@ exports[`TransactionPanel - Sale enquired matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -10142,7 +10069,6 @@ exports[`TransactionPanel - Sale enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -10261,7 +10187,6 @@ exports[`TransactionPanel - Sale enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -10378,7 +10303,6 @@ exports[`TransactionPanel - Sale enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -10495,7 +10419,6 @@ exports[`TransactionPanel - Sale enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -10730,7 +10653,6 @@ exports[`TransactionPanel - Sale enquired matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -10821,7 +10743,6 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = `
|
|||
currentListing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -10934,7 +10855,6 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -11053,7 +10973,6 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -11170,7 +11089,6 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -11287,7 +11205,6 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -11522,7 +11439,6 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
|
|||
|
|
@ -31,9 +31,6 @@ export { default as ExpandingTextarea } from './ExpandingTextarea/ExpandingTexta
|
|||
export { default as ExternalLink } from './ExternalLink/ExternalLink';
|
||||
export { default as FilterPanel } from './FilterPanel/FilterPanel';
|
||||
export { default as FieldCheckbox } from './FieldCheckbox/FieldCheckbox';
|
||||
export {
|
||||
default as FieldCustomAttributeSelect,
|
||||
} from './FieldCustomAttributeSelect/FieldCustomAttributeSelect';
|
||||
export { default as FieldGroupCheckbox } from './FieldGroupCheckbox/FieldGroupCheckbox';
|
||||
export { default as FieldReviewRating } from './FieldReviewRating/FieldReviewRating';
|
||||
export { default as Footer } from './Footer/Footer';
|
||||
|
|
|
|||
|
|
@ -211,41 +211,6 @@ const stripeSupportedCountries = [
|
|||
},
|
||||
];
|
||||
|
||||
// Custom attributes are marketplace specific listing data (e.g. listing could have a category).
|
||||
// Custom attributes can be defined through management console and code related to custom
|
||||
// attributes should be changed accordingly.
|
||||
//
|
||||
// Here's an example what custom attributes might look like for bicycle listings. This code
|
||||
// assumes that a custom attribute, called 'category', is created through management console
|
||||
// with 4 possible values: 'road', 'mountain', 'track', and 'other'.
|
||||
//
|
||||
// When listing information is queried customAttributes is returned among other attributes:
|
||||
// {
|
||||
// id: 1,
|
||||
// type: 'listing',
|
||||
// attributes: {
|
||||
// title: 'sauna',
|
||||
// // and description, price, etc.
|
||||
// customAttributes: {
|
||||
// category: "mountain",
|
||||
// // and other added custom attributes as "key: value" pairs
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
const exampleCustomAttributes = {
|
||||
category: {
|
||||
select: 'single', // possible values: 'single' (only type supported atm.)
|
||||
type: 'string',
|
||||
values: ['road', 'mountain', 'track', 'other'],
|
||||
},
|
||||
};
|
||||
|
||||
// To use the example custom attributes, set the
|
||||
// REACT_APP_USE_EXAMPLE_CUSTOM_ATTRIBUTES variable to `true` in the
|
||||
// gitignored `.env.development.local` file
|
||||
const useExampleCustomAttributes = process.env.REACT_APP_USE_EXAMPLE_CUSTOM_ATTRIBUTES === 'true';
|
||||
const customAttributes = useExampleCustomAttributes ? exampleCustomAttributes : {};
|
||||
|
||||
// Address information is used in SEO schema for Organization (http://schema.org/PostalAddress)
|
||||
const addressCountry = 'FI';
|
||||
const addressRegion = 'Helsinki';
|
||||
|
|
@ -284,7 +249,6 @@ const config = {
|
|||
sdk: { clientId: sdkClientId, baseUrl: sdkBaseUrl },
|
||||
currency,
|
||||
currencyConfig,
|
||||
customAttributes,
|
||||
stripe: { publishableKey: stripePublishableKey, supportedCountries: stripeSupportedCountries },
|
||||
canonicalRootURL,
|
||||
address: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
import React from 'react';
|
||||
import { required } from '../../util/validators';
|
||||
import { SelectField } from '../../components';
|
||||
|
||||
import css from './EditListingDescriptionForm.css';
|
||||
|
||||
const CustomCategorySelectFieldMaybe = props => {
|
||||
const { name, id, categories, intl } = props;
|
||||
const categoryLabel = intl.formatMessage({
|
||||
id: 'EditListingDescriptionForm.categoryLabel',
|
||||
});
|
||||
const categoryPlaceholder = intl.formatMessage({
|
||||
id: 'EditListingDescriptionForm.categoryPlaceholder',
|
||||
});
|
||||
const categoryRequired = required(
|
||||
intl.formatMessage({
|
||||
id: 'EditListingDescriptionForm.categoryRequired',
|
||||
})
|
||||
);
|
||||
return categories ? (
|
||||
<SelectField
|
||||
className={css.category}
|
||||
name={name}
|
||||
id={id}
|
||||
label={categoryLabel}
|
||||
validate={categoryRequired}
|
||||
>
|
||||
<option value="">{categoryPlaceholder}</option>
|
||||
{categories.map(c => (
|
||||
<option key={c.key} value={c.key}>
|
||||
{c.label}
|
||||
</option>
|
||||
))}
|
||||
</SelectField>
|
||||
) : null;
|
||||
};
|
||||
|
||||
export default CustomCategorySelectFieldMaybe;
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { bool, func, string, arrayOf, shape } from 'prop-types';
|
||||
import { compose } from 'redux';
|
||||
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
|
||||
import { intlShape, injectIntl, FormattedMessage } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import { propTypes } from '../../util/types';
|
||||
import { maxLength, required } from '../../util/validators';
|
||||
import { FieldCustomAttributeSelect, Form, Button, TextInputField } from '../../components';
|
||||
import { Form, Button, TextInputField } from '../../components';
|
||||
import CustomCategorySelectFieldMaybe from './CustomCategorySelectFieldMaybe';
|
||||
|
||||
import css from './EditListingDescriptionForm.css';
|
||||
|
||||
|
|
@ -25,6 +26,7 @@ const EditListingDescriptionFormComponent = props => {
|
|||
updated,
|
||||
updateError,
|
||||
updateInProgress,
|
||||
categories,
|
||||
} = props;
|
||||
|
||||
const titleMessage = intl.formatMessage({ id: 'EditListingDescriptionForm.title' });
|
||||
|
|
@ -86,10 +88,11 @@ const EditListingDescriptionFormComponent = props => {
|
|||
validate={[required(descriptionRequiredMessage)]}
|
||||
/>
|
||||
|
||||
<FieldCustomAttributeSelect
|
||||
className={css.category}
|
||||
<CustomCategorySelectFieldMaybe
|
||||
name="category"
|
||||
id={`${form}.category`}
|
||||
customAttribute="category"
|
||||
categories={categories}
|
||||
intl={intl}
|
||||
/>
|
||||
|
||||
<Button
|
||||
|
|
@ -107,8 +110,6 @@ const EditListingDescriptionFormComponent = props => {
|
|||
|
||||
EditListingDescriptionFormComponent.defaultProps = { className: null, updateError: null };
|
||||
|
||||
const { bool, func, string } = PropTypes;
|
||||
|
||||
EditListingDescriptionFormComponent.propTypes = {
|
||||
...formPropTypes,
|
||||
className: string,
|
||||
|
|
@ -118,6 +119,12 @@ EditListingDescriptionFormComponent.propTypes = {
|
|||
updated: bool.isRequired,
|
||||
updateError: propTypes.error,
|
||||
updateInProgress: bool.isRequired,
|
||||
categories: arrayOf(
|
||||
shape({
|
||||
key: string.isRequired,
|
||||
label: string.isRequired,
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
const formName = 'EditListingDescriptionForm';
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ describe('EditListingDescriptionForm', () => {
|
|||
saveActionMsg="Save description"
|
||||
updated={false}
|
||||
updateInProgress={false}
|
||||
categories={[{ key: 'cat1', label: 'Cat 1' }, { key: 'cat2', label: 'Cat 2' }]}
|
||||
/>
|
||||
);
|
||||
expect(tree).toMatchSnapshot();
|
||||
|
|
|
|||
|
|
@ -54,6 +54,42 @@ exports[`EditListingDescriptionForm matches snapshot 1`] = `
|
|||
value=""
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className=""
|
||||
>
|
||||
<label
|
||||
htmlFor="fakeTestForm.category"
|
||||
>
|
||||
EditListingDescriptionForm.categoryLabel
|
||||
</label>
|
||||
<select
|
||||
className=""
|
||||
id="fakeTestForm.category"
|
||||
name="category"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onDragStart={[Function]}
|
||||
onDrop={[Function]}
|
||||
onFocus={[Function]}
|
||||
value=""
|
||||
>
|
||||
<option
|
||||
value=""
|
||||
>
|
||||
EditListingDescriptionForm.categoryPlaceholder
|
||||
</option>
|
||||
<option
|
||||
value="cat1"
|
||||
>
|
||||
Cat 1
|
||||
</option>
|
||||
<option
|
||||
value="cat2"
|
||||
>
|
||||
Cat 2
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<button
|
||||
className=""
|
||||
disabled={true}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,11 @@ const gotoListingTab = (history, listing) => {
|
|||
);
|
||||
};
|
||||
|
||||
const categoryLabel = (categories, key) => {
|
||||
const cat = categories.find(c => c.key === key);
|
||||
return cat ? cat.label : key;
|
||||
};
|
||||
|
||||
// TODO: price unit (per x), custom fields, contact, reviews
|
||||
// N.B. All the presentational content needs to be extracted to their own components
|
||||
export class ListingPageComponent extends Component {
|
||||
|
|
@ -262,13 +267,10 @@ export class ListingPageComponent extends Component {
|
|||
publicData,
|
||||
} = currentListing.attributes;
|
||||
|
||||
const { customAttributes } = currentListing.attributes;
|
||||
const hasCategoryConfig = config.customAttributes && config.customAttributes.category;
|
||||
const hasCategoryAttribute = customAttributes && customAttributes.category;
|
||||
const category =
|
||||
hasCategoryConfig && hasCategoryAttribute ? (
|
||||
publicData && publicData.category ? (
|
||||
<span>
|
||||
<FormattedMessage id={`ListingPage.category.${customAttributes.category}`} />
|
||||
{categoryLabel(config.custom.categories, publicData.category)}
|
||||
<span className={css.separator}>•</span>
|
||||
</span>
|
||||
) : null;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ exports[`ListingPage matches snapshot 1`] = `
|
|||
listing={
|
||||
Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
|
|||
|
|
@ -42,10 +42,12 @@ const MODAL_BREAKPOINT = 768; // Search is in modal on mobile layout
|
|||
const SEARCH_WITH_MAP_DEBOUNCE = 300; // Little bit of debounce before search is initiated.
|
||||
const BOUNDS_FIXED_PRECISION = 8;
|
||||
|
||||
const CATEGORY_URL_PARAM = 'ca_category';
|
||||
|
||||
// extract search parameters, including a custom attribute named category
|
||||
const pickSearchParamsOnly = params => {
|
||||
const { address, origin, bounds, ca_category } = params || {};
|
||||
return { address, origin, bounds, ca_category };
|
||||
const { address, origin, bounds, ...rest } = params || {};
|
||||
return { address, origin, bounds, [CATEGORY_URL_PARAM]: rest[CATEGORY_URL_PARAM] };
|
||||
};
|
||||
|
||||
export class SearchPageComponent extends Component {
|
||||
|
|
@ -185,6 +187,7 @@ export class SearchPageComponent extends Component {
|
|||
searchInProgress,
|
||||
searchListingsError,
|
||||
searchParams,
|
||||
categories,
|
||||
} = this.props;
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { mapSearch, page, ...searchInURL } = parse(location.search, {
|
||||
|
|
@ -301,6 +304,7 @@ export class SearchPageComponent extends Component {
|
|||
searchListingsError={searchListingsError}
|
||||
onMapIconClick={onMapIconClick}
|
||||
onManageDisableScrolling={onManageDisableScrolling}
|
||||
categories={categories}
|
||||
/>
|
||||
<SearchFiltersMobile
|
||||
className={css.searchFiltersMobile}
|
||||
|
|
@ -314,6 +318,7 @@ export class SearchPageComponent extends Component {
|
|||
onManageDisableScrolling={onManageDisableScrolling}
|
||||
onOpenModal={this.onOpenMobileModal}
|
||||
onCloseModal={this.onCloseMobileModal}
|
||||
categories={categories}
|
||||
/>
|
||||
<div
|
||||
className={classNames(css.listings, {
|
||||
|
|
@ -354,6 +359,7 @@ SearchPageComponent.defaultProps = {
|
|||
searchListingsError: null,
|
||||
searchParams: {},
|
||||
tab: 'listings',
|
||||
categories: config.custom.categories,
|
||||
};
|
||||
|
||||
const { array, bool, func, oneOf, object, shape, string } = PropTypes;
|
||||
|
|
@ -369,6 +375,7 @@ SearchPageComponent.propTypes = {
|
|||
searchListingsError: propTypes.error,
|
||||
searchParams: object,
|
||||
tab: oneOf(['filters', 'listings', 'map']).isRequired,
|
||||
categories: array,
|
||||
|
||||
// from withRouter
|
||||
history: shape({
|
||||
|
|
@ -429,9 +436,9 @@ SearchPage.loadData = (params, search) => {
|
|||
latlng: ['origin'],
|
||||
latlngBounds: ['bounds'],
|
||||
});
|
||||
const page = queryParams.page || 1;
|
||||
const { page = 1, ...rest } = queryParams;
|
||||
return searchListings({
|
||||
...queryParams,
|
||||
...rest,
|
||||
page,
|
||||
perPage: RESULT_PAGE_SIZE,
|
||||
include: ['author', 'images'],
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ describe('SearchPageComponent', () => {
|
|||
onSearchMapListings: noop,
|
||||
sendVerificationEmailInProgress: false,
|
||||
onResendVerificationEmail: noop,
|
||||
categories: [{ key: 'cat1', label: 'Cat 1' }, { key: 'cat2', label: 'Cat 2' }],
|
||||
};
|
||||
const tree = renderShallow(<SearchPageComponent {...props} />);
|
||||
expect(tree).toMatchSnapshot();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,19 @@ exports[`SearchPageComponent matches snapshot 1`] = `
|
|||
<withRouter(Connect(TopbarContainerComponent)) />
|
||||
<div>
|
||||
<div>
|
||||
<withRouter(SearchFiltersComponent)
|
||||
<withRouter(InjectIntl(SearchFiltersComponent))
|
||||
categories={
|
||||
Array [
|
||||
Object {
|
||||
"key": "cat1",
|
||||
"label": "Cat 1",
|
||||
},
|
||||
Object {
|
||||
"key": "cat2",
|
||||
"label": "Cat 2",
|
||||
},
|
||||
]
|
||||
}
|
||||
listingsAreLoaded={true}
|
||||
onManageDisableScrolling={[Function]}
|
||||
onMapIconClick={[Function]}
|
||||
|
|
@ -37,6 +49,18 @@ exports[`SearchPageComponent matches snapshot 1`] = `
|
|||
}
|
||||
/>
|
||||
<InjectIntl(withRouter(SearchFiltersMobileComponent))
|
||||
categories={
|
||||
Array [
|
||||
Object {
|
||||
"key": "cat1",
|
||||
"label": "Cat 1",
|
||||
},
|
||||
Object {
|
||||
"key": "cat2",
|
||||
"label": "Cat 2",
|
||||
},
|
||||
]
|
||||
}
|
||||
listingsAreLoaded={true}
|
||||
onCloseModal={[Function]}
|
||||
onManageDisableScrolling={[Function]}
|
||||
|
|
|
|||
|
|
@ -148,7 +148,6 @@ exports[`TransactionPage - Order matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
@ -346,7 +345,6 @@ exports[`TransactionPage - Sale matches snapshot 1`] = `
|
|||
},
|
||||
"listing": Object {
|
||||
"attributes": Object {
|
||||
"customAttributes": Object {},
|
||||
"deleted": false,
|
||||
"description": "listing1 description",
|
||||
"geolocation": LatLng {
|
||||
|
|
|
|||
|
|
@ -36,3 +36,10 @@ export const amenities = [
|
|||
label: 'Own food allowed',
|
||||
},
|
||||
];
|
||||
|
||||
export const categories = [
|
||||
{ key: 'road', label: 'Road' },
|
||||
{ key: 'mountain', label: 'Mountain' },
|
||||
{ key: 'track', label: 'Track' },
|
||||
{ key: 'other', label: 'Other' },
|
||||
];
|
||||
|
|
|
|||
|
|
@ -109,6 +109,9 @@
|
|||
"DateRangeInputField.invalidStartDate": "The start date is not valid",
|
||||
"DateRangeInputField.screenReaderInputMessage": "Date input",
|
||||
"DateRangeInputField.startDatePlaceholderText": "Add start date",
|
||||
"EditListingDescriptionForm.categoryLabel": "Sauna type",
|
||||
"EditListingDescriptionForm.categoryPlaceholder": "Choose the type of your sauna…",
|
||||
"EditListingDescriptionForm.categoryRequired": "You need to select a category for your sauna.",
|
||||
"EditListingDescriptionForm.description": "Describe your sauna",
|
||||
"EditListingDescriptionForm.descriptionPlaceholder": "How many people can fit at once? Does the sauna come with towels?",
|
||||
"EditListingDescriptionForm.descriptionRequired": "A description is required.",
|
||||
|
|
@ -191,13 +194,6 @@
|
|||
"EnquiryForm.messageRequired": "A message is required",
|
||||
"EnquiryForm.sendEnquiryError": "Whoops, something went wrong. Please try again.",
|
||||
"EnquiryForm.submitButtonText": "Send enquiry",
|
||||
"FieldCustomAttributeSelect.category.label": "Sauna type",
|
||||
"FieldCustomAttributeSelect.category.option.mountain": "Mountain",
|
||||
"FieldCustomAttributeSelect.category.option.other": "Other",
|
||||
"FieldCustomAttributeSelect.category.option.road": "Road",
|
||||
"FieldCustomAttributeSelect.category.option.track": "Track",
|
||||
"FieldCustomAttributeSelect.category.placeholder": "Choose the type of your sauna…",
|
||||
"FieldCustomAttributeSelect.category.required": "You need to select a category for your sauna.",
|
||||
"FieldReviewRating.star1": "Bad experience - 1 star",
|
||||
"FieldReviewRating.star2": "Not so nice - 2 stars",
|
||||
"FieldReviewRating.star3": "OK - 3 stars",
|
||||
|
|
@ -255,10 +251,6 @@
|
|||
"ListingPage.bookingHelp": "Start by choosing your dates.",
|
||||
"ListingPage.bookingHelpClosedListing": "Sorry, this listing has been closed.",
|
||||
"ListingPage.bookingTitle": "Book {title}",
|
||||
"ListingPage.category.mountain": "Mountain",
|
||||
"ListingPage.category.other": "Other",
|
||||
"ListingPage.category.road": "Road",
|
||||
"ListingPage.category.track": "Track",
|
||||
"ListingPage.closedListing": "This listing has been closed and can't be booked.",
|
||||
"ListingPage.closedListingButtonText": "Sorry, this listing has been closed.",
|
||||
"ListingPage.contactUser": "Contact",
|
||||
|
|
@ -477,6 +469,7 @@
|
|||
"ReviewModal.description": "Reviews are an important part of the Saunatime community. Please share what went well and what could have been improved.",
|
||||
"ReviewModal.later": "Later",
|
||||
"ReviewModal.title": "Leave a review for {revieweeName}",
|
||||
"SearchFilters.categoryLabel": "Category",
|
||||
"SearchFilters.filtersButtonLabel": "Filters",
|
||||
"SearchFilters.foundResults": "{count, number} {count, plural, one {result} other {results}}",
|
||||
"SearchFilters.loadingResults": "Loading search results…",
|
||||
|
|
@ -485,6 +478,7 @@
|
|||
"SearchFilters.noResultsMobile": "No results.",
|
||||
"SearchFilters.openMapView": "Map",
|
||||
"SearchFiltersMobile.cancel": "CANCEL",
|
||||
"SearchFiltersMobile.categoryLabel": "Category",
|
||||
"SearchFiltersMobile.heading": "Filter saunas",
|
||||
"SearchFiltersMobile.resetAll": "Reset all",
|
||||
"SearchFiltersMobile.showListings": "Show {count, number} {count, plural, one {sauna} other {saunas}}",
|
||||
|
|
@ -510,17 +504,7 @@
|
|||
"SectionLocations.listingsInLocation": "Saunas in {location}",
|
||||
"SectionLocations.subtitle": "We have more than 1000 saunas around Finland. Here are some of our most popular locations.",
|
||||
"SectionLocations.title": "We have wooden saunas, electric saunas, and even tent saunas.",
|
||||
"SelectSingleFilter.category.label": "Category",
|
||||
"SelectSingleFilter.category.option.mountain": "Mountain",
|
||||
"SelectSingleFilter.category.option.other": "Other",
|
||||
"SelectSingleFilter.category.option.road": "Road",
|
||||
"SelectSingleFilter.category.option.track": "Track",
|
||||
"SelectSingleFilter.clear": "Clear",
|
||||
"SelectSingleFilterMobile.category.label": "Category",
|
||||
"SelectSingleFilterMobile.category.option.mountain": "Mountain",
|
||||
"SelectSingleFilterMobile.category.option.other": "Other",
|
||||
"SelectSingleFilterMobile.category.option.road": "Road",
|
||||
"SelectSingleFilterMobile.category.option.track": "Track",
|
||||
"SelectSingleFilterMobile.clear": "Clear",
|
||||
"SendMessageForm.sendFailed": "Failed to send. Please try again.",
|
||||
"SendMessageForm.sendMessage": "Send message",
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ export const ensureListing = listing => {
|
|||
const empty = {
|
||||
id: null,
|
||||
type: 'listing',
|
||||
attributes: { customAttributes: {}, publicData: {} },
|
||||
attributes: { publicData: {} },
|
||||
images: [],
|
||||
};
|
||||
return { ...empty, ...listing };
|
||||
|
|
@ -180,7 +180,7 @@ export const ensureOwnListing = listing => {
|
|||
const empty = {
|
||||
id: null,
|
||||
type: 'ownListing',
|
||||
attributes: { customAttributes: {}, publicData: {} },
|
||||
attributes: { publicData: {} },
|
||||
images: [],
|
||||
};
|
||||
return { ...empty, ...listing };
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ export const createListing = (id, attributes = {}, includes = {}) => ({
|
|||
deleted: false,
|
||||
state: LISTING_STATE_PUBLISHED,
|
||||
price: new Money(5500, 'USD'),
|
||||
customAttributes: {},
|
||||
publicData: {},
|
||||
...attributes,
|
||||
},
|
||||
|
|
@ -104,7 +103,6 @@ export const createOwnListing = (id, attributes = {}, includes = {}) => ({
|
|||
deleted: false,
|
||||
state: LISTING_STATE_PUBLISHED,
|
||||
price: new Money(5500, 'USD'),
|
||||
customAttributes: {},
|
||||
publicData: {},
|
||||
...attributes,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ const listingAttributes = shape({
|
|||
deleted: propTypes.value(false).isRequired,
|
||||
state: oneOf(LISTING_STATES).isRequired,
|
||||
price: propTypes.money,
|
||||
customAttributes: object,
|
||||
publicData: object.isRequired,
|
||||
});
|
||||
|
||||
|
|
@ -153,7 +152,6 @@ const ownListingAttributes = shape({
|
|||
deleted: propTypes.value(false).isRequired,
|
||||
state: oneOf(LISTING_STATES).isRequired,
|
||||
price: propTypes.money,
|
||||
customAttributes: object,
|
||||
publicData: object.isRequired,
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue