EditListingPoliciesPanel

This commit is contained in:
Vesa Luusua 2018-01-23 17:18:19 +02:00
parent 116df03f14
commit 335b15da80
5 changed files with 159 additions and 5 deletions

View file

@ -0,0 +1,22 @@
@import '../../marketplace.css';
.root {
flex-grow: 1;
width: 100%;
height: auto;
display: flex;
flex-direction: column;
padding: 11px 24px 0 24px;
}
.form {
flex-grow: 1;
}
.title {
margin-bottom: 19px;
@media (--viewportLarge) {
margin-bottom: 44px;
}
}

View file

@ -0,0 +1,86 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { FormattedMessage } from 'react-intl';
import { ensureListing } from '../../util/data';
import { createSlug } from '../../util/urlHelpers';
import { NamedLink } from '../../components';
import { EditListingPoliciesForm } from '../../containers';
import css from './EditListingPoliciesPanel.css';
const EditListingPoliciesPanel = props => {
const {
className,
rootClassName,
listing,
onSubmit,
onChange,
submitButtonText,
panelUpdated,
updateInProgress,
errors,
} = props;
const classes = classNames(rootClassName || css.root, className);
const currentListing = ensureListing(listing);
const { title, publicData } = currentListing.attributes;
const listingTitle = title || '';
const listingLink = currentListing.id ? (
<NamedLink name="ListingPage" params={{ id: currentListing.id.uuid, slug: createSlug(title) }}>
{listingTitle}
</NamedLink>
) : (
''
);
const panelTitle = currentListing.id ? (
<FormattedMessage id="EditListingPoliciesPanel.title" values={{ listingTitle: listingLink }} />
) : (
<FormattedMessage id="EditListingPoliciesPanel.createListingTitle" />
);
const saunaRules = publicData && publicData.saunaRules ? publicData.saunaRules : '';
const initialSearchFormValues = { saunaRules };
return (
<div className={classes}>
<h1 className={css.title}>{panelTitle}</h1>
<EditListingPoliciesForm
className={css.form}
initialValues={initialSearchFormValues}
onSubmit={onSubmit}
onChange={onChange}
saveActionMsg={submitButtonText}
updated={panelUpdated}
updateError={errors.updateListingError}
updateInProgress={updateInProgress}
/>
</div>
);
};
const { func, object, string, bool } = PropTypes;
EditListingPoliciesPanel.defaultProps = {
className: null,
rootClassName: null,
listing: null,
};
EditListingPoliciesPanel.propTypes = {
className: string,
rootClassName: string,
// We cannot use propTypes.listing since the listing might be a draft.
listing: object,
onSubmit: func.isRequired,
onChange: func.isRequired,
submitButtonText: string.isRequired,
panelUpdated: bool.isRequired,
updateInProgress: bool.isRequired,
errors: object.isRequired,
};
export default EditListingPoliciesPanel;

View file

@ -12,6 +12,7 @@ import {
EditListingDescriptionPanel,
EditListingLocationPanel,
EditListingPhotosPanel,
EditListingPoliciesPanel,
EditListingPricingPanel,
NamedRedirect,
Tabs,
@ -20,10 +21,11 @@ import {
import css from './EditListingWizard.css';
const DESCRIPTION = 'description';
const POLICY = 'policy';
const LOCATION = 'location';
const PRICING = 'pricing';
const PHOTOS = 'photos';
const STEPS = [DESCRIPTION, LOCATION, PRICING, PHOTOS];
const STEPS = [DESCRIPTION, POLICY, LOCATION, PRICING, PHOTOS];
// Tabs are horizontal in small screens
const MAX_HORIZONTAL_NAV_SCREEN_WIDTH = 1023;
@ -32,6 +34,8 @@ const submitText = (intl, isNew, step) => {
let key = null;
if (step === DESCRIPTION) {
key = isNew ? 'EditListingWizard.saveNewDescription' : 'EditListingWizard.saveEditDescription';
} else if (step === POLICY) {
key = isNew ? 'EditListingWizard.saveNewPolicies' : 'EditListingWizard.saveEditPolicies';
} else if (step === LOCATION) {
key = isNew ? 'EditListingWizard.saveNewLocation' : 'EditListingWizard.saveEditLocation';
} else if (step === PRICING) {
@ -53,6 +57,7 @@ const submitText = (intl, isNew, step) => {
const stepsActive = listing => {
const { description, geolocation, price, title, publicData } = listing.attributes;
const descriptionStep = !!(title && description);
const policyStep = !!(publicData && typeof publicData.saunaRules !== 'undefined');
const locationStep = !!(
geolocation &&
publicData &&
@ -65,7 +70,8 @@ const stepsActive = listing => {
return {
[DESCRIPTION]: true,
[LOCATION]: descriptionStep,
[POLICY]: descriptionStep,
[LOCATION]: policyStep,
[PRICING]: locationStep,
[PHOTOS]: pricingStep,
};
@ -186,7 +192,7 @@ class EditListingWizard extends Component {
if (isNew) {
onUpsertListingDraft(updateValues);
const pathParams = tabParams(LOCATION);
const pathParams = tabParams(POLICY);
// Redirect to location tab
history.push(
createResourceLocatorString('EditListingPage', routeConfiguration(), pathParams, {})
@ -196,6 +202,39 @@ class EditListingWizard extends Component {
}
}}
/>
<EditListingPoliciesPanel
className={css.panel}
tabId={`${id}_${POLICY}`}
tabLabel={intl.formatMessage({ id: 'EditListingWizard.tabLabelPolicy' })}
tabLinkProps={tabLink(POLICY)}
selected={selectedTab === POLICY}
panelUpdated={updatedTab === POLICY}
updateInProgress={updateInProgress}
disabled={!stepsStatus[POLICY]}
errors={errors}
listing={listing}
submitButtonText={submitText(intl, isNew, POLICY)}
onChange={onChange}
onSubmit={values => {
const { saunaRules = '' } = values;
const updateValues = {
publicData: {
saunaRules,
},
};
if (isNew) {
onUpdateListingDraft(updateValues);
const pathParams = tabParams(LOCATION);
// Redirect to pricing tab
history.push(
createResourceLocatorString('EditListingPage', routeConfiguration(), pathParams, {})
);
} else {
update(POLICY, updateValues);
}
}}
/>
<EditListingLocationPanel
className={css.panel}
tabId={`${id}_${LOCATION}`}
@ -220,7 +259,6 @@ class EditListingWizard extends Component {
};
if (isNew) {
// TODO When API supports building number, etc. change this to use those fields instead.
onUpdateListingDraft(updateValues);
const pathParams = tabParams(PRICING);
// Redirect to pricing tab

View file

@ -20,6 +20,9 @@ export {
default as EditListingLocationPanel,
} from './EditListingLocationPanel/EditListingLocationPanel';
export { default as EditListingPhotosPanel } from './EditListingPhotosPanel/EditListingPhotosPanel';
export {
default as EditListingPoliciesPanel,
} from './EditListingPoliciesPanel/EditListingPoliciesPanel';
export {
default as EditListingPricingPanel,
} from './EditListingPricingPanel/EditListingPricingPanel';

View file

@ -150,6 +150,8 @@
"EditListingPoliciesForm.rulesLabel": "Sauna rules",
"EditListingPoliciesForm.rulesPlaceholder": "Descripe the no-nos",
"EditListingPoliciesForm.updateFailed": "Failed to update listing. Please try again.",
"EditListingPoliciesPanel.createListingTitle": "Time to set some ground rules for the bathers.",
"EditListingPoliciesPanel.title": "Edit the rules of {listingTitle}",
"EditListingPricingForm.priceInputPlaceholder": "Choose your price…",
"EditListingPricingForm.pricePerUnit": "Price per night in euros",
"EditListingPricingForm.priceRequired": "You need to add a valid price.",
@ -160,14 +162,17 @@
"EditListingWizard.saveEditDescription": "Save description",
"EditListingWizard.saveEditLocation": "Save location",
"EditListingWizard.saveEditPhotos": "Save photos",
"EditListingWizard.saveEditPolicies": "Save rules",
"EditListingWizard.saveEditPricing": "Save pricing",
"EditListingWizard.saveNewDescription": "Next: Location",
"EditListingWizard.saveNewDescription": "Next: Policies",
"EditListingWizard.saveNewLocation": "Next: Pricing",
"EditListingWizard.saveNewPhotos": "Publish listing",
"EditListingWizard.saveNewPolicies": "Next: location",
"EditListingWizard.saveNewPricing": "Next: Photos",
"EditListingWizard.tabLabelDescription": "Description",
"EditListingWizard.tabLabelLocation": "Location",
"EditListingWizard.tabLabelPhotos": "Photos",
"EditListingWizard.tabLabelPolicy": "Sauna rules",
"EditListingWizard.tabLabelPricing": "Pricing",
"EmailVerificationForm.finishAccountSetup": "We will need to send you email notifications. To allow this, please verify your email address {email}.",
"EmailVerificationForm.successButtonText": "Continue exploring",