mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-29 13:06:03 +10:00
EditListingLocationPanel and form within
This commit is contained in:
parent
c3a5036497
commit
d14fcef98f
11 changed files with 229 additions and 0 deletions
|
|
@ -0,0 +1,6 @@
|
|||
.root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { EditListingLocationForm } from '../../containers';
|
||||
|
||||
import css from './EditListingLocationPanel.css';
|
||||
|
||||
const EditListingLocationPanel = props => {
|
||||
const { className, rootClassName, listing, onSubmit } = props;
|
||||
|
||||
const rootClass = rootClassName || css.root;
|
||||
const classes = classNames(rootClass, className);
|
||||
const { attributes: { address, geolocation } } = listing || { attributes: {} };
|
||||
|
||||
// Only render current search if full place object is available in the URL params
|
||||
// TODO bounds and country are missing - those need to be queried directly from Google Places
|
||||
const locationFieldsPresent = address && geolocation;
|
||||
const initialSearchFormValues = {
|
||||
location: locationFieldsPresent
|
||||
? {
|
||||
search: address,
|
||||
selectedPlace: { address, origin: geolocation },
|
||||
}
|
||||
: null,
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={classes}>
|
||||
<h1><FormattedMessage id="EditListingLocationPanel.title" /></h1>
|
||||
<EditListingLocationForm initialValues={initialSearchFormValues} onSubmit={onSubmit} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const { func, object, string } = PropTypes;
|
||||
|
||||
EditListingLocationPanel.defaultProps = {
|
||||
className: null,
|
||||
rootClassName: null,
|
||||
listing: null,
|
||||
};
|
||||
|
||||
EditListingLocationPanel.propTypes = {
|
||||
className: string,
|
||||
rootClassName: string,
|
||||
listing: object, // TODO Should be propTypes.listing after API support is added.
|
||||
onSubmit: func.isRequired,
|
||||
};
|
||||
|
||||
export default EditListingLocationPanel;
|
||||
|
|
@ -8,6 +8,7 @@ import CurrencyInput from './CurrencyInput/CurrencyInput';
|
|||
import DateInput from './DateInput/DateInput';
|
||||
import Discussion from './Discussion/Discussion';
|
||||
import EditListingDescriptionPanel from './EditListingDescriptionPanel/EditListingDescriptionPanel';
|
||||
import EditListingLocationPanel from './EditListingLocationPanel/EditListingLocationPanel';
|
||||
import EditListingWizard from './EditListingWizard/EditListingWizard';
|
||||
import ExternalLink from './ExternalLink/ExternalLink';
|
||||
import FilterPanel from './FilterPanel/FilterPanel';
|
||||
|
|
@ -50,6 +51,7 @@ export {
|
|||
DateInput,
|
||||
Discussion,
|
||||
EditListingDescriptionPanel,
|
||||
EditListingLocationPanel,
|
||||
EditListingWizard,
|
||||
ExternalLink,
|
||||
FilterPanel,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
.root {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/* eslint-disable no-console */
|
||||
import EditListingLocationForm from './EditListingLocationForm';
|
||||
|
||||
export const Empty = {
|
||||
component: EditListingLocationForm,
|
||||
props: {
|
||||
onSubmit: values => {
|
||||
console.log('Submit EditListingLocationForm with (unformatted) values:', values);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
import React, { Component, PropTypes } from 'react';
|
||||
import { compose } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import { Field, reduxForm, formValueSelector, propTypes as formPropTypes } from 'redux-form';
|
||||
import { intlShape, injectIntl } from 'react-intl';
|
||||
import * as propTypes from '../../util/propTypes';
|
||||
import { enhancedField } from '../../util/forms';
|
||||
import { autocompleteSearchRequired, autocompletePlaceSelected } from '../../util/validators';
|
||||
import { LocationAutocompleteInput, Button } from '../../components';
|
||||
|
||||
import css from './EditListingLocationForm.css';
|
||||
|
||||
export class EditListingLocationFormComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// We must create the enhanced components outside the render function
|
||||
// to avoid losing focus.
|
||||
// See: https://github.com/erikras/redux-form/releases/tag/v6.0.0-alpha.14
|
||||
this.EnhancedLocationAutocompleteInput = enhancedField(LocationAutocompleteInput);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
disabled,
|
||||
handleSubmit,
|
||||
intl,
|
||||
invalid,
|
||||
saveActionMsg,
|
||||
submitting,
|
||||
} = this.props;
|
||||
|
||||
const titleRequiredMessage = intl.formatMessage({ id: 'EditListingLocationForm.location' });
|
||||
const locationRequiredMessage = intl.formatMessage({
|
||||
id: 'EditListingLocationForm.locationRequired',
|
||||
});
|
||||
const locationNotRecognizedMessage = intl.formatMessage({
|
||||
id: 'EditListingLocationForm.locationNotRecognized',
|
||||
});
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Field
|
||||
name="location"
|
||||
label={titleRequiredMessage}
|
||||
format={null}
|
||||
component={this.EnhancedLocationAutocompleteInput}
|
||||
validate={[
|
||||
autocompleteSearchRequired(locationRequiredMessage),
|
||||
autocompletePlaceSelected(locationNotRecognizedMessage),
|
||||
]}
|
||||
/>
|
||||
|
||||
<Button
|
||||
className={css.submitButton}
|
||||
type="submit"
|
||||
disabled={invalid || submitting || disabled}
|
||||
>
|
||||
{saveActionMsg}
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EditListingLocationFormComponent.defaultProps = {
|
||||
saveActionMsg: 'Next: pricing',
|
||||
selectedPlace: null,
|
||||
};
|
||||
|
||||
const { func, string } = PropTypes;
|
||||
|
||||
EditListingLocationFormComponent.propTypes = {
|
||||
...formPropTypes,
|
||||
intl: intlShape.isRequired,
|
||||
onSubmit: func.isRequired,
|
||||
saveActionMsg: string,
|
||||
selectedPlace: propTypes.place,
|
||||
};
|
||||
|
||||
const formName = 'EditListingLocationForm';
|
||||
|
||||
// When a field depends on the value of another field, we must connect
|
||||
// to the store and select the required values to inject to the
|
||||
// component.
|
||||
//
|
||||
// See: http://redux-form.com/6.6.1/examples/selectingFormValues/
|
||||
const selector = formValueSelector(formName);
|
||||
const mapStateToProps = state => {
|
||||
const location = selector(state, 'location');
|
||||
return {
|
||||
selectedPlace: location && location.selectedPlace ? location.selectedPlace : null,
|
||||
};
|
||||
};
|
||||
|
||||
export default compose(connect(mapStateToProps), reduxForm({ form: formName }), injectIntl)(
|
||||
EditListingLocationFormComponent
|
||||
);
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// TODO: renderdeep doesn't work due to Google Maps API integration
|
||||
import React from 'react';
|
||||
import { renderShallow } from '../../util/test-helpers';
|
||||
import { fakeIntl, fakeFormProps } from '../../util/test-data';
|
||||
import { EditListingLocationFormComponent } from './EditListingLocationForm';
|
||||
|
||||
const noop = () => null;
|
||||
|
||||
describe('EditListingLocationForm', () => {
|
||||
it('matches snapshot', () => {
|
||||
const tree = renderShallow(
|
||||
<EditListingLocationFormComponent
|
||||
{...fakeFormProps}
|
||||
intl={fakeIntl}
|
||||
dispatch={noop}
|
||||
onSubmit={v => v}
|
||||
/>
|
||||
);
|
||||
expect(tree).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
exports[`EditListingLocationForm matches snapshot 1`] = `
|
||||
<form
|
||||
onSubmit={[Function]}>
|
||||
<Field
|
||||
component={[Function]}
|
||||
format={null}
|
||||
label="EditListingLocationForm.location"
|
||||
name="location"
|
||||
validate={
|
||||
Array [
|
||||
[Function],
|
||||
[Function],
|
||||
]
|
||||
} />
|
||||
<Button
|
||||
className={null}
|
||||
rootClassName=""
|
||||
type="submit">
|
||||
Next: pricing
|
||||
</Button>
|
||||
</form>
|
||||
`;
|
||||
|
|
@ -5,6 +5,7 @@ import ChangePasswordForm from './ChangePasswordForm/ChangePasswordForm';
|
|||
import CheckoutPage from './CheckoutPage/CheckoutPage';
|
||||
import ContactDetailsPage from './ContactDetailsPage/ContactDetailsPage';
|
||||
import EditListingDescriptionForm from './EditListingDescriptionForm/EditListingDescriptionForm';
|
||||
import EditListingLocationForm from './EditListingLocationForm/EditListingLocationForm';
|
||||
import EditListingPage from './EditListingPage/EditListingPage';
|
||||
import EditProfilePage from './EditProfilePage/EditProfilePage';
|
||||
import SearchForm from './SearchForm/SearchForm';
|
||||
|
|
@ -36,6 +37,7 @@ export {
|
|||
CheckoutPage,
|
||||
ContactDetailsPage,
|
||||
EditListingDescriptionForm,
|
||||
EditListingLocationForm,
|
||||
EditListingPage,
|
||||
EditProfilePage,
|
||||
SearchForm,
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ import * as ChangeAccountPasswordForm
|
|||
import * as ChangePasswordForm from './containers/ChangePasswordForm/ChangePasswordForm.example';
|
||||
import * as EditListingDescriptionForm
|
||||
from './containers/EditListingDescriptionForm/EditListingDescriptionForm.example';
|
||||
import * as EditListingLocationForm
|
||||
from './containers/EditListingLocationForm/EditListingLocationForm.example';
|
||||
import * as SearchForm from './containers/SearchForm/SearchForm.example';
|
||||
import * as LoginForm from './containers/LoginForm/LoginForm.example';
|
||||
import * as PasswordForgottenForm
|
||||
|
|
@ -42,6 +44,7 @@ export {
|
|||
CurrencyInput,
|
||||
DateInput,
|
||||
EditListingDescriptionForm,
|
||||
EditListingLocationForm,
|
||||
EditListingWizard,
|
||||
ListingCard,
|
||||
LocationAutocompleteInput,
|
||||
|
|
|
|||
|
|
@ -39,6 +39,10 @@
|
|||
"EditListingDescriptionForm.titlePlaceholder": "What's the name of your sauna?",
|
||||
"EditListingDescriptionForm.titleRequired": "You need to add a name.",
|
||||
"EditListingDescriptionPanel.title": "Add your sauna",
|
||||
"EditListingLocationForm.location": "Location",
|
||||
"EditListingLocationForm.locationRequired": "You need to provide a location",
|
||||
"EditListingLocationForm.locationNotRecognized": "We didn't recognize this location. Please try another location.",
|
||||
"EditListingLocationPanel.title": "Where's your sauna located?",
|
||||
"EditListingPage.titleCreateListing": "Create a listing",
|
||||
"EditListingPage.titleEditListing": "Edit listing",
|
||||
"HeroSection.subTitle": "The largest online community to rent music studios",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue