mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-29 05:00:43 +10:00
Merge pull request #600 from sharetribe/listing-enquiry
Listing enquiry form
This commit is contained in:
commit
40fdc60f55
10 changed files with 212 additions and 1 deletions
8
src/components/IconEnquiry/IconEnquiry.css
Normal file
8
src/components/IconEnquiry/IconEnquiry.css
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
@import '../../marketplace.css';
|
||||
|
||||
.root {
|
||||
}
|
||||
|
||||
.marketplaceColorStroke {
|
||||
stroke: var(--marketplaceColor);
|
||||
}
|
||||
7
src/components/IconEnquiry/IconEnquiry.example.js
Normal file
7
src/components/IconEnquiry/IconEnquiry.example.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import IconEnquiry from './IconEnquiry';
|
||||
|
||||
export const Icon = {
|
||||
component: IconEnquiry,
|
||||
props: {},
|
||||
group: 'icons',
|
||||
};
|
||||
42
src/components/IconEnquiry/IconEnquiry.js
Normal file
42
src/components/IconEnquiry/IconEnquiry.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import React from 'react';
|
||||
import { string } from 'prop-types';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import css from './IconEnquiry.css';
|
||||
|
||||
const IconEnquiry = props => {
|
||||
const { rootClassName, className } = props;
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
return (
|
||||
<svg className={classes} width="47" height="46" xmlns="http://www.w3.org/2000/svg">
|
||||
<g
|
||||
className={css.marketplaceColorStroke}
|
||||
fill="none"
|
||||
fillRule="evenodd"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path
|
||||
d="M37.522 17L45 22.22v19.933C45 43.724 43.744 45 42.196 45H4.804C3.256 45 2 43.724 2 42.153V22.22L9.478 17"
|
||||
strokeWidth="2"
|
||||
/>
|
||||
<path
|
||||
strokeWidth="2.5"
|
||||
d="M8 40l9.412-8h13.176L40 40M45 23l-11 8M2 23l11 8M38 27V2H10v25M15 8h4M19 13h13M15 19h17M15 24h17"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
IconEnquiry.defaultProps = {
|
||||
rootClassName: null,
|
||||
className: null,
|
||||
};
|
||||
|
||||
IconEnquiry.propTypes = {
|
||||
rootClassName: string,
|
||||
className: string,
|
||||
};
|
||||
|
||||
export default IconEnquiry;
|
||||
|
|
@ -36,6 +36,7 @@ export { default as IconClose } from './IconClose/IconClose';
|
|||
export { default as IconEmailAttention } from './IconEmailAttention/IconEmailAttention';
|
||||
export { default as IconEmailSent } from './IconEmailSent/IconEmailSent';
|
||||
export { default as IconEmailSuccess } from './IconEmailSuccess/IconEmailSuccess';
|
||||
export { default as IconEnquiry } from './IconEnquiry/IconEnquiry';
|
||||
export { default as IconKeys } from './IconKeys/IconKeys';
|
||||
export { default as IconKeysSuccess } from './IconKeysSuccess/IconKeysSuccess';
|
||||
export { default as IconReviewStar } from './IconReviewStar/IconReviewStar';
|
||||
|
|
|
|||
32
src/containers/EnquiryForm/EnquiryForm.css
Normal file
32
src/containers/EnquiryForm/EnquiryForm.css
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
@import '../../marketplace.css';
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: none;
|
||||
|
||||
@media (--viewportMedium) {
|
||||
display: block;
|
||||
margin-bottom: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.heading {
|
||||
@apply --marketplaceModalTitleStyles;
|
||||
}
|
||||
|
||||
.field {
|
||||
margin: 25px 0 24px 0;
|
||||
|
||||
@media (--viewportMedium) {
|
||||
margin: 22px 0 24px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.submitButton {
|
||||
/* Push to bottom of the flex container */
|
||||
margin-top: auto;
|
||||
}
|
||||
13
src/containers/EnquiryForm/EnquiryForm.example.js
Normal file
13
src/containers/EnquiryForm/EnquiryForm.example.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import EnquiryForm from './EnquiryForm';
|
||||
|
||||
export const Empty = {
|
||||
component: EnquiryForm,
|
||||
props: {
|
||||
listingTitle: 'Sauna with a view',
|
||||
authorDisplayName: 'Janne',
|
||||
onSubmit(values) {
|
||||
console.log('submit with values:', values);
|
||||
},
|
||||
},
|
||||
group: 'forms',
|
||||
};
|
||||
98
src/containers/EnquiryForm/EnquiryForm.js
Normal file
98
src/containers/EnquiryForm/EnquiryForm.js
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import React from 'react';
|
||||
import { string, bool } from 'prop-types';
|
||||
import { compose } from 'redux';
|
||||
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
||||
import { reduxForm, propTypes as formPropTypes } from 'redux-form';
|
||||
import classNames from 'classnames';
|
||||
import { Form, PrimaryButton, TextInputField, IconEnquiry } from '../../components';
|
||||
import * as validators from '../../util/validators';
|
||||
|
||||
import css from './EnquiryForm.css';
|
||||
|
||||
const EnquiryFormComponent = props => {
|
||||
const {
|
||||
rootClassName,
|
||||
className,
|
||||
form,
|
||||
handleSubmit,
|
||||
submitting,
|
||||
inProgress,
|
||||
intl,
|
||||
listingTitle,
|
||||
authorDisplayName,
|
||||
} = props;
|
||||
|
||||
const messageLabel = intl.formatMessage(
|
||||
{
|
||||
id: 'EnquiryForm.messageLabel',
|
||||
},
|
||||
{ authorDisplayName }
|
||||
);
|
||||
const messagePlaceholder = intl.formatMessage(
|
||||
{
|
||||
id: 'EnquiryForm.messagePlaceholder',
|
||||
},
|
||||
{ authorDisplayName }
|
||||
);
|
||||
const messageRequiredMessage = intl.formatMessage({
|
||||
id: 'EnquiryForm.messageRequired',
|
||||
});
|
||||
const messageRequired = validators.required(messageRequiredMessage);
|
||||
|
||||
const classes = classNames(rootClassName || css.root, className);
|
||||
|
||||
const submitInProgress = submitting || inProgress;
|
||||
const submitDisabled = submitInProgress;
|
||||
|
||||
return (
|
||||
<Form className={classes} onSubmit={handleSubmit}>
|
||||
<IconEnquiry className={css.icon} />
|
||||
<h2 className={css.heading}>
|
||||
<FormattedMessage id="EnquiryForm.heading" values={{ listingTitle }} />
|
||||
</h2>
|
||||
<TextInputField
|
||||
className={css.field}
|
||||
type="textarea"
|
||||
name="message"
|
||||
id={`${form}.message`}
|
||||
label={messageLabel}
|
||||
placeholder={messagePlaceholder}
|
||||
validate={[messageRequired]}
|
||||
/>
|
||||
<PrimaryButton
|
||||
className={css.submitButton}
|
||||
type="submit"
|
||||
inProgress={submitInProgress}
|
||||
disabled={submitDisabled}
|
||||
>
|
||||
<FormattedMessage id="EnquiryForm.submitButtonText" />
|
||||
</PrimaryButton>
|
||||
</Form>
|
||||
);
|
||||
};
|
||||
|
||||
EnquiryFormComponent.defaultProps = {
|
||||
rootClassName: null,
|
||||
className: null,
|
||||
inProgress: false,
|
||||
};
|
||||
|
||||
EnquiryFormComponent.propTypes = {
|
||||
...formPropTypes,
|
||||
rootClassName: string,
|
||||
className: string,
|
||||
|
||||
inProgress: bool,
|
||||
|
||||
listingTitle: string.isRequired,
|
||||
authorDisplayName: string.isRequired,
|
||||
|
||||
// from injectIntl
|
||||
intl: intlShape.isRequired,
|
||||
};
|
||||
|
||||
const defaultFormName = 'EnquiryForm';
|
||||
|
||||
const EnquiryForm = compose(reduxForm({ form: defaultFormName }), injectIntl)(EnquiryFormComponent);
|
||||
|
||||
export default EnquiryForm;
|
||||
|
|
@ -15,6 +15,7 @@ export { default as EditListingPhotosForm } from './EditListingPhotosForm/EditLi
|
|||
export { default as EditListingPricingForm } from './EditListingPricingForm/EditListingPricingForm';
|
||||
export { default as EmailVerificationForm } from './EmailVerificationForm/EmailVerificationForm';
|
||||
export { default as EmailVerificationPage } from './EmailVerificationPage/EmailVerificationPage';
|
||||
export { default as EnquiryForm } from './EnquiryForm/EnquiryForm';
|
||||
export { default as InboxPage } from './InboxPage/InboxPage';
|
||||
export { default as LandingPage } from './LandingPage/LandingPage';
|
||||
export { default as ListingPage } from './ListingPage/ListingPage';
|
||||
|
|
|
|||
|
|
@ -18,11 +18,12 @@ import * as IconClose from './components/IconClose/IconClose.example';
|
|||
import * as IconEmailAttention from './components/IconEmailAttention/IconEmailAttention.example';
|
||||
import * as IconEmailSent from './components/IconEmailSent/IconEmailSent.example';
|
||||
import * as IconEmailSuccess from './components/IconEmailSuccess/IconEmailSuccess.example';
|
||||
import * as IconEnquiry from './components/IconEnquiry/IconEnquiry.example';
|
||||
import * as IconKeys from './components/IconKeys/IconKeys.example';
|
||||
import * as IconKeysSuccess from './components/IconKeysSuccess/IconKeysSuccess.example';
|
||||
import * as IconSearch from './components/IconSearch/IconSearch.example';
|
||||
import * as IconReviewStar from './components/IconReviewStar/IconReviewStar.example';
|
||||
import * as IconReviewUser from './components/IconReviewUser/IconReviewUser.example';
|
||||
import * as IconSearch from './components/IconSearch/IconSearch.example';
|
||||
import * as IconSocialMediaFacebook from './components/IconSocialMediaFacebook/IconSocialMediaFacebook.example';
|
||||
import * as IconSocialMediaInstagram from './components/IconSocialMediaInstagram/IconSocialMediaInstagram.example';
|
||||
import * as IconSocialMediaTwitter from './components/IconSocialMediaTwitter/IconSocialMediaTwitter.example';
|
||||
|
|
@ -56,6 +57,7 @@ import * as EditListingLocationForm from './containers/EditListingLocationForm/E
|
|||
import * as EditListingPhotosForm from './containers/EditListingPhotosForm/EditListingPhotosForm.example';
|
||||
import * as EditListingPricingForm from './containers/EditListingPricingForm/EditListingPricingForm.example';
|
||||
import * as EmailVerificationForm from './containers/EmailVerificationForm/EmailVerificationForm.example';
|
||||
import * as EnquiryForm from './containers/EnquiryForm/EnquiryForm.example';
|
||||
import * as LoginForm from './containers/LoginForm/LoginForm.example';
|
||||
import * as PasswordRecoveryForm from './containers/PasswordRecoveryForm/PasswordRecoveryForm.example';
|
||||
import * as PasswordResetForm from './containers/PasswordResetForm/PasswordResetForm.example';
|
||||
|
|
@ -84,6 +86,7 @@ export {
|
|||
EditListingPricingForm,
|
||||
EditListingWizard,
|
||||
EmailVerificationForm,
|
||||
EnquiryForm,
|
||||
ExpandingTextarea,
|
||||
FieldReviewRating,
|
||||
Footer,
|
||||
|
|
@ -93,6 +96,7 @@ export {
|
|||
IconEmailAttention,
|
||||
IconEmailSent,
|
||||
IconEmailSuccess,
|
||||
IconEnquiry,
|
||||
IconKeys,
|
||||
IconKeysSuccess,
|
||||
IconReviewStar,
|
||||
|
|
|
|||
|
|
@ -169,6 +169,11 @@
|
|||
"EmailVerificationForm.verifying": "Verifying…",
|
||||
"EmailVerificationPage.loadingUserInformation": "Loading user information…",
|
||||
"EmailVerificationPage.title": "Verify your email address",
|
||||
"EnquiryForm.heading": "Enquire about {listingTitle}",
|
||||
"EnquiryForm.messageLabel": "Message to {authorDisplayName}",
|
||||
"EnquiryForm.messagePlaceholder": "Hello {authorDisplayName}! I'm looking forward to…",
|
||||
"EnquiryForm.messageRequired": "A message is required",
|
||||
"EnquiryForm.submitButtonText": "Send enquiry",
|
||||
"FieldReviewRating.star1": "Bad experience - 1 star",
|
||||
"FieldReviewRating.star2": "Not so nice - 2 stars",
|
||||
"FieldReviewRating.star3": "OK - 3 stars",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue