mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-29 13:06:03 +10:00
Merge pull request #668 from sharetribe/edit-listing-services
Edit listing features form
This commit is contained in:
commit
a7932134e1
12 changed files with 225 additions and 50 deletions
|
|
@ -15,7 +15,7 @@ const FormComponent = props => {
|
|||
<FieldCheckbox
|
||||
id="field-checkbox-example-id"
|
||||
name="field-checkbox-example-name"
|
||||
text="Check here"
|
||||
label="Check here"
|
||||
/>
|
||||
|
||||
<Button style={{ marginTop: 24 }} type="submit" disabled={submitDisabled}>
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const { node, string } = PropTypes;
|
|||
IconCheckbox.propTypes = { className: string };
|
||||
|
||||
const FieldCheckbox = props => {
|
||||
const { rootClassName, className, svgClassName, id, name, text } = props;
|
||||
const { rootClassName, className, svgClassName, id, name, label } = props;
|
||||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ const FieldCheckbox = props => {
|
|||
<Field id={id} name={name} className={css.input} type="checkbox" component="input" />
|
||||
<label htmlFor={id} className={css.label}>
|
||||
<IconCheckbox className={svgClassName} />
|
||||
<span className={css.text}>{text}</span>
|
||||
<span className={css.text}>{label}</span>
|
||||
</label>
|
||||
</span>
|
||||
);
|
||||
|
|
@ -58,7 +58,7 @@ FieldCheckbox.defaultProps = {
|
|||
className: null,
|
||||
rootClassName: null,
|
||||
svgClassName: null,
|
||||
text: null,
|
||||
label: null,
|
||||
};
|
||||
|
||||
FieldCheckbox.propTypes = {
|
||||
|
|
@ -67,7 +67,7 @@ FieldCheckbox.propTypes = {
|
|||
svgClassName: string,
|
||||
id: string.isRequired,
|
||||
name: string.isRequired,
|
||||
text: node,
|
||||
label: node,
|
||||
};
|
||||
|
||||
export default FieldCheckbox;
|
||||
|
|
|
|||
|
|
@ -12,36 +12,36 @@ const componentProps = {
|
|||
legend: legend,
|
||||
options: [
|
||||
{
|
||||
name: 'towels',
|
||||
text: 'Towels',
|
||||
key: 'towels',
|
||||
label: 'Towels',
|
||||
},
|
||||
{
|
||||
name: 'bathroom',
|
||||
text: 'Bathfoom',
|
||||
key: 'bathroom',
|
||||
label: 'Bathroom',
|
||||
},
|
||||
{
|
||||
name: 'swimming_pool',
|
||||
text: 'Swimming pool',
|
||||
key: 'swimming_pool',
|
||||
label: 'Swimming pool',
|
||||
},
|
||||
{
|
||||
name: 'own_drinks',
|
||||
text: 'Own drinks allowed',
|
||||
key: 'own_drinks',
|
||||
label: 'Own drinks allowed',
|
||||
},
|
||||
{
|
||||
name: 'jacuzzi',
|
||||
text: 'Jacuzzi',
|
||||
key: 'jacuzzi',
|
||||
label: 'Jacuzzi',
|
||||
},
|
||||
{
|
||||
name: 'audiovisual_entertainment',
|
||||
text: 'Audiovisual entertainment',
|
||||
key: 'audiovisual_entertainment',
|
||||
label: 'Audiovisual entertainment',
|
||||
},
|
||||
{
|
||||
name: 'barbeque',
|
||||
text: 'Barbeque',
|
||||
key: 'barbeque',
|
||||
label: 'Barbeque',
|
||||
},
|
||||
{
|
||||
name: 'own_food_allowed',
|
||||
text: 'Own food allowed',
|
||||
key: 'own_food_allowed',
|
||||
label: 'Own food allowed',
|
||||
},
|
||||
],
|
||||
twoColumns: true,
|
||||
|
|
|
|||
|
|
@ -7,41 +7,35 @@
|
|||
*
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { FieldCheckbox } from '../../components';
|
||||
import css from './FieldGroupCheckbox.css';
|
||||
|
||||
class FieldGroupCheckbox extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { selected: [] };
|
||||
}
|
||||
const FieldGroupCheckbox = props => {
|
||||
const { rootClassName, className, id, legend, options, twoColumns } = props;
|
||||
|
||||
render() {
|
||||
const { rootClassName, className, id, legend, options, twoColumns } = this.props;
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
const listClasses = twoColumns ? classNames(css.list, css.twoColumns) : css.list;
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
const listClasses = twoColumns ? classNames(css.list, css.twoColumns) : css.list;
|
||||
|
||||
return (
|
||||
<fieldset className={classes}>
|
||||
{legend ? <legend>{legend}</legend> : null}
|
||||
<ul className={listClasses}>
|
||||
{options.map(option => {
|
||||
const fieldId = `${id}.${option.name}`;
|
||||
return (
|
||||
<li key={fieldId} className={css.item}>
|
||||
<FieldCheckbox id={fieldId} name={option.name} text={option.text} />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</fieldset>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<fieldset className={classes}>
|
||||
{legend ? <legend>{legend}</legend> : null}
|
||||
<ul className={listClasses}>
|
||||
{options.map(option => {
|
||||
const fieldId = `${id}.${option.key}`;
|
||||
return (
|
||||
<li key={fieldId} className={css.item}>
|
||||
<FieldCheckbox id={fieldId} name={option.key} label={option.label} />
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
</fieldset>
|
||||
);
|
||||
};
|
||||
|
||||
FieldGroupCheckbox.defaultProps = {
|
||||
rootClassName: null,
|
||||
|
|
@ -59,8 +53,8 @@ FieldGroupCheckbox.propTypes = {
|
|||
legend: node,
|
||||
options: arrayOf(
|
||||
shape({
|
||||
name: string.isRequired,
|
||||
text: node.isRequired,
|
||||
key: string.isRequired,
|
||||
label: node.isRequired,
|
||||
})
|
||||
).isRequired,
|
||||
twoColumns: bool,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import * as custom from './marketplace-custom-config.js';
|
||||
|
||||
const env = process.env.REACT_APP_ENV || 'production';
|
||||
const dev = process.env.REACT_APP_ENV === 'development';
|
||||
|
||||
|
|
@ -298,6 +300,7 @@ const config = {
|
|||
facebookAppId,
|
||||
sentryDsn,
|
||||
usingSSL,
|
||||
custom,
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
@import '../../marketplace.css';
|
||||
|
||||
:root {
|
||||
--formMargins: {
|
||||
margin-bottom: 24px;
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.root {
|
||||
}
|
||||
|
||||
.features {
|
||||
@apply --formMargins;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: var(--failColor);
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
margin-top: auto;
|
||||
margin-bottom: 24px;
|
||||
flex-shrink: 0;
|
||||
|
||||
@media (--viewportLarge) {
|
||||
display: inline-block;
|
||||
width: 241px;
|
||||
margin-top: 100px;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import EditListingFeaturesForm from './EditListingFeaturesForm';
|
||||
|
||||
const initialValueArray = ['towels', 'jacuzzi', 'bathroom'];
|
||||
|
||||
export const Amenities = {
|
||||
component: EditListingFeaturesForm,
|
||||
props: {
|
||||
onSubmit: values => console.log('EditListingFeaturesForm submit:', values),
|
||||
initialValues: initialValueArray.reduce((map, value) => {
|
||||
map[value] = true;
|
||||
return map;
|
||||
}, {}),
|
||||
saveActionMsg: 'Save amenities',
|
||||
updated: false,
|
||||
updateInProgress: false,
|
||||
},
|
||||
group: 'forms',
|
||||
};
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { propTypes } from '../../util/types';
|
||||
import config from '../../config';
|
||||
import { Button, FieldGroupCheckbox, Form } from '../../components';
|
||||
|
||||
import css from './EditListingFeaturesForm.css';
|
||||
|
||||
const EditListingFeaturesFormComponent = props => {
|
||||
const {
|
||||
form,
|
||||
submitting,
|
||||
disabled,
|
||||
rootClassName,
|
||||
className,
|
||||
handleSubmit,
|
||||
saveActionMsg,
|
||||
updated,
|
||||
updateError,
|
||||
updateInProgress,
|
||||
} = props;
|
||||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
const submitReady = updated;
|
||||
const submitInProgress = submitting || updateInProgress;
|
||||
const submitDisabled = disabled || submitInProgress;
|
||||
|
||||
const errorMessage = updateError ? (
|
||||
<p className={css.error}>
|
||||
<FormattedMessage id="EditListingFeaturesForm.updateFailed" />
|
||||
</p>
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<Form className={classes} onSubmit={handleSubmit}>
|
||||
{errorMessage}
|
||||
|
||||
<FieldGroupCheckbox
|
||||
className={css.features}
|
||||
id={`${form}.amenities`}
|
||||
options={config.custom.amenities}
|
||||
/>
|
||||
|
||||
<Button
|
||||
className={css.submitButton}
|
||||
type="submit"
|
||||
inProgress={submitInProgress}
|
||||
disabled={submitDisabled}
|
||||
ready={submitReady}
|
||||
>
|
||||
{saveActionMsg}
|
||||
</Button>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
EditListingFeaturesFormComponent.defaultProps = {
|
||||
rootClassName: null,
|
||||
className: null,
|
||||
updateError: null,
|
||||
};
|
||||
|
||||
const { bool, func, string } = PropTypes;
|
||||
|
||||
EditListingFeaturesFormComponent.propTypes = {
|
||||
...formPropTypes,
|
||||
rootClassName: string,
|
||||
className: string,
|
||||
handleSubmit: func.isRequired,
|
||||
saveActionMsg: string.isRequired,
|
||||
updated: bool.isRequired,
|
||||
updateError: propTypes.error,
|
||||
updateInProgress: bool.isRequired,
|
||||
};
|
||||
|
||||
const defaultFormName = 'EditListingFeaturesForm';
|
||||
|
||||
export default reduxForm({ form: defaultFormName })(EditListingFeaturesFormComponent);
|
||||
|
|
@ -7,6 +7,9 @@ export { default as ContactDetailsPage } from './ContactDetailsPage/ContactDetai
|
|||
export {
|
||||
default as EditListingDescriptionForm,
|
||||
} from './EditListingDescriptionForm/EditListingDescriptionForm';
|
||||
export {
|
||||
default as EditListingFeaturesForm,
|
||||
} from './EditListingFeaturesForm/EditListingFeaturesForm';
|
||||
export {
|
||||
default as EditListingLocationForm,
|
||||
} from './EditListingLocationForm/EditListingLocationForm';
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ import * as UserCard from './components/UserCard/UserCard.example';
|
|||
import * as BookingDatesForm from './containers/BookingDatesForm/BookingDatesForm.example';
|
||||
import * as Colors from './containers/StyleguidePage/Colors.example';
|
||||
import * as EditListingDescriptionForm from './containers/EditListingDescriptionForm/EditListingDescriptionForm.example';
|
||||
import * as EditListingFeaturesForm from './containers/EditListingFeaturesForm/EditListingFeaturesForm.example';
|
||||
import * as EditListingLocationForm from './containers/EditListingLocationForm/EditListingLocationForm.example';
|
||||
import * as EditListingPhotosForm from './containers/EditListingPhotosForm/EditListingPhotosForm.example';
|
||||
import * as EditListingPoliciesForm from './containers/EditListingPoliciesForm/EditListingPoliciesForm.example';
|
||||
|
|
@ -84,6 +85,7 @@ export {
|
|||
CurrencyInputField,
|
||||
DateRangeInputField,
|
||||
EditListingDescriptionForm,
|
||||
EditListingFeaturesForm,
|
||||
EditListingLocationForm,
|
||||
EditListingPhotosForm,
|
||||
EditListingPoliciesForm,
|
||||
|
|
|
|||
38
src/marketplace-custom-config.js
Normal file
38
src/marketplace-custom-config.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Marketplace specific configuration.
|
||||
*/
|
||||
|
||||
export const amenities = [
|
||||
{
|
||||
key: 'towels',
|
||||
label: 'Towels',
|
||||
},
|
||||
{
|
||||
key: 'bathroom',
|
||||
label: 'Bathroom',
|
||||
},
|
||||
{
|
||||
key: 'swimming_pool',
|
||||
label: 'Swimming pool',
|
||||
},
|
||||
{
|
||||
key: 'own_drinks',
|
||||
label: 'Own drinks allowed',
|
||||
},
|
||||
{
|
||||
key: 'jacuzzi',
|
||||
label: 'Jacuzzi',
|
||||
},
|
||||
{
|
||||
key: 'audiovisual_entertainment',
|
||||
label: 'Audiovisual entertainment',
|
||||
},
|
||||
{
|
||||
key: 'barbeque',
|
||||
label: 'Barbeque',
|
||||
},
|
||||
{
|
||||
key: 'own_food_allowed',
|
||||
label: 'Own food allowed',
|
||||
},
|
||||
];
|
||||
|
|
@ -119,6 +119,7 @@
|
|||
"EditListingDescriptionForm.updateFailed": "Failed to update listing. Please try again.",
|
||||
"EditListingDescriptionPanel.createListingTitle": "Add your sauna",
|
||||
"EditListingDescriptionPanel.title": "Edit details of {listingTitle}",
|
||||
"EditListingFeaturesForm.updateFailed": "Failed to update listing. Please try again.",
|
||||
"EditListingLocationForm.address": "Address",
|
||||
"EditListingLocationForm.addressNotRecognized": "We didn't recognize this location. Please try another location.",
|
||||
"EditListingLocationForm.addressPlaceholder": "123 Example Street",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue