Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to ListingPage #46

Merged
merged 6 commits into from
Nov 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ https://github.com/sharetribe/flex-template-web/

## Upcoming version 2019-XX-XX

- [change] Changes to `ListingPage` desing: make header image full width and avatar bigger, show
only selected yoga styles, move price from `SectionHeading` to Panel and remove hosted by text and
the whole `SectionHostMaybe`. We also moved the `Modal` with `EnquiryForm` directly to
`ListingPage`. [#46](https://github.com/sharetribe/ftw-time/pull/46)
- [add] EditListingAvailabilityPanel: add list of current AvailabilityExceptions and edit form in
modal. [#45](https://github.com/sharetribe/ftw-time/pull/45)
- [fix] Fix date formatting in example tx process email templates
[#48](https://github.com/sharetribe/ftw-time/pull/48)
- [change] Change images and update favicons. Also, update links on the `LandingPage`. Make the
Expand Down
18 changes: 15 additions & 3 deletions src/components/Avatar/Avatar.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ const AVATAR_IMAGE_VARIANTS = [
];

export const AvatarComponent = props => {
const { rootClassName, className, user, renderSizes, disableProfileLink, intl } = props;
const {
rootClassName,
className,
initialsClassName,
user,
renderSizes,
disableProfileLink,
intl,
} = props;
const classes = classNames(rootClassName || css.root, className);

const userIsCurrentUser = user && user.type === 'currentUser';
Expand Down Expand Up @@ -61,6 +69,8 @@ export const AvatarComponent = props => {
const hasProfileImage = avatarUser.profileImage && avatarUser.profileImage.id;
const profileLinkEnabled = !disableProfileLink;

const classForInitials = initialsClassName || css.initials;

if (isBannedUser || isDeletedUser) {
return (
<div {...rootProps}>
Expand Down Expand Up @@ -95,14 +105,14 @@ export const AvatarComponent = props => {
// Placeholder avatar (initials)
return (
<NamedLink {...rootProps} {...linkProps}>
<span className={css.initials}>{abbreviatedName}</span>
<span className={classForInitials}>{abbreviatedName}</span>
</NamedLink>
);
} else {
// Placeholder avatar (initials)
return (
<div {...rootProps}>
<span className={css.initials}>{abbreviatedName}</span>
<span className={classForInitials}>{abbreviatedName}</span>
</div>
);
}
Expand All @@ -111,6 +121,7 @@ export const AvatarComponent = props => {
AvatarComponent.defaultProps = {
className: null,
rootClassName: null,
initialsClassName: null,
user: null,
renderSizes: AVATAR_SIZES,
disableProfileLink: false,
Expand All @@ -119,6 +130,7 @@ AvatarComponent.defaultProps = {
AvatarComponent.propTypes = {
rootClassName: string,
className: string,
initialsClassName: string,
user: oneOfType([propTypes.user, propTypes.currentUser]),

renderSizes: string,
Expand Down
36 changes: 36 additions & 0 deletions src/components/BookingPanel/BookingPanel.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,42 @@
margin-bottom: 33px;
}
}
.desktopPriceContainer {
display: none;

@media (--viewportLarge) {
/* Layout */
display: flex;
flex-direction: row;
align-items: flex-end;
flex-shrink: 0;
margin: 0 48px 0 0;
padding: 0;
}
}

.desktopPriceValue {
/* Font */
@apply --marketplaceH2FontStyles;
color: var(--marketplaceColor);

@media (--viewportMedium) {
margin-top: 0;
margin-bottom: 6px;
}
}

.desktopPerUnit {
/* Font */
@apply --marketplaceH5FontStyles;
color: var(--matterColor);

@media (--viewportMedium) {
margin-top: 0;
margin-bottom: 6px;
margin-left: 6px;
}
}

.bookingTitle {
/* Font */
Expand Down
20 changes: 13 additions & 7 deletions src/components/BookingPanel/BookingPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ const BookingPanel = props => {
onSubmit,
title,
subTitle,
authorDisplayName,
onManageDisableScrolling,
onFetchTimeSlots,
monthlyTimeSlots,
Expand Down Expand Up @@ -110,15 +109,22 @@ const BookingPanel = props => {
>
<div className={css.modalHeading}>
<h1 className={css.title}>{title}</h1>
<div className={css.author}>
<FormattedMessage id="BookingPanel.hostedBy" values={{ name: authorDisplayName }} />
</div>
</div>

<div className={css.bookingHeading}>
<h2 className={titleClasses}>{title}</h2>
{subTitleText ? <div className={css.bookingHelp}>{subTitleText}</div> : null}
<div className={css.desktopPriceContainer}>
<div className={css.desktopPriceValue} title={priceTitle}>
{formattedPrice}
</div>
<div className={css.desktopPerUnit}>
<FormattedMessage id={unitTranslationKey} />
</div>
</div>
<div className={css.bookingHeadingContainer}>
<h2 className={titleClasses}>{title}</h2>
{subTitleText ? <div className={css.bookingHelp}>{subTitleText}</div> : null}
</div>
</div>

{showBookingTimeForm ? (
<BookingTimeForm
className={css.bookingForm}
Expand Down
22 changes: 12 additions & 10 deletions src/containers/ListingPage/ListingPage.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,6 @@
display: block;
width: 100%;
position: relative;

@media (--viewportMedium) {
padding: 0;
}

@media (--viewportLarge) {
padding: 36px 36px 0 36px;
}
}

/* Firefox doesn't support image aspect ratio inside flexbox */
Expand Down Expand Up @@ -251,7 +243,7 @@
.sectionAvatar {
/* Position (over the listing image)*/
margin-left: 24px;
margin-top: -31px;
margin-top: -72px;

/* Rendering context to the same lavel as listing image */
position: relative;
Expand All @@ -261,14 +253,16 @@

@media (--viewportMedium) {
position: absolute;
top: -49px;
top: -112px;
margin-left: 0;
margin-top: 0;
}
}

.avatarMobile {
display: flex;
width: 96px;
height: 96px;

@media (--viewportMedium) {
display: none; /* Hide the medium avatar from the bigger screens */
Expand All @@ -277,12 +271,20 @@

.avatarDesktop {
display: none; /* Hide the large avatar from the smaller screens */
width: 152px;
height: 152px;

@media (--viewportMedium) {
display: flex;
}
}

.initialsDesktop {
font-size: 48px;
font-weight: var(--fontWeightBold);
padding-bottom: 8px;
}

.sectionHeading {
margin-top: 22px;
margin-bottom: 34px;
Expand Down
35 changes: 19 additions & 16 deletions src/containers/ListingPage/ListingPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { manageDisableScrolling, isScrollingDisabled } from '../../ducks/UI.duck
import { initializeCardPaymentData } from '../../ducks/stripe.duck.js';
import {
Page,
Modal,
NamedLink,
NamedRedirect,
LayoutSingleColumn,
Expand All @@ -40,6 +41,7 @@ import {
Footer,
BookingPanel,
} from '../../components';
import { EnquiryForm } from '../../forms';
import { TopbarContainer, NotFoundPage } from '../../containers';

import { sendEnquiry, loadData, setInitialValues, fetchTimeSlots } from './ListingPage.duck';
Expand All @@ -49,8 +51,6 @@ import SectionHeading from './SectionHeading';
import SectionDescriptionMaybe from './SectionDescriptionMaybe';
import SectionFeaturesMaybe from './SectionFeaturesMaybe';
import SectionReviews from './SectionReviews';
import SectionHostMaybe from './SectionHostMaybe';
import SectionRulesMaybe from './SectionRulesMaybe';
import SectionMapMaybe from './SectionMapMaybe';
import css from './ListingPage.css';

Expand Down Expand Up @@ -423,26 +423,12 @@ export class ListingPageComponent extends Component {
/>
<SectionDescriptionMaybe description={description} />
<SectionFeaturesMaybe options={yogaStylesConfig} publicData={publicData} />
<SectionRulesMaybe publicData={publicData} />
<SectionMapMaybe
geolocation={geolocation}
publicData={publicData}
listingId={currentListing.id}
/>
<SectionReviews reviews={reviews} fetchReviewsError={fetchReviewsError} />
<SectionHostMaybe
title={title}
listing={currentListing}
authorDisplayName={authorDisplayName}
onContactUser={this.onContactUser}
isEnquiryModalOpen={isAuthenticated && this.state.enquiryModalOpen}
OtterleyW marked this conversation as resolved.
Show resolved Hide resolved
onCloseEnquiryModal={() => this.setState({ enquiryModalOpen: false })}
sendEnquiryError={sendEnquiryError}
sendEnquiryInProgress={sendEnquiryInProgress}
onSubmitEnquiry={this.onSubmitEnquiry}
currentUser={currentUser}
onManageDisableScrolling={onManageDisableScrolling}
/>
</div>
<BookingPanel
className={css.bookingPanel}
Expand All @@ -459,6 +445,23 @@ export class ListingPageComponent extends Component {
/>
</div>
</div>
<Modal
id="ListingPage.enquiry"
contentClassName={css.enquiryModalContent}
isOpen={isAuthenticated && this.state.enquiryModalOpen}
onClose={() => this.setState({ enquiryModalOpen: false })}
onManageDisableScrolling={onManageDisableScrolling}
>
<EnquiryForm
className={css.enquiryForm}
submitButtonWrapperClassName={css.enquirySubmitButtonWrapper}
listingTitle={title}
authorDisplayName={authorDisplayName}
sendEnquiryError={sendEnquiryError}
onSubmit={this.onSubmitEnquiry}
inProgress={sendEnquiryInProgress}
/>
</Modal>
</LayoutWrapperMain>
<LayoutWrapperFooter>
<Footer />
Expand Down
18 changes: 10 additions & 8 deletions src/containers/ListingPage/SectionAvatar.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import React from 'react';
import { NamedLink, AvatarLarge, AvatarMedium } from '../../components';
import { AvatarLarge, AvatarMedium } from '../../components';

import css from './ListingPage.css';

const SectionAvatar = props => {
const { user, params } = props;
const { user } = props;
return (
<div className={css.sectionAvatar}>
<NamedLink name="ListingPage" params={params} to={{ hash: '#host' }}>
<AvatarLarge user={user} className={css.avatarDesktop} disableProfileLink />
</NamedLink>
<NamedLink name="ListingPage" params={params} to={{ hash: '#host' }}>
<AvatarMedium user={user} className={css.avatarMobile} disableProfileLink />
</NamedLink>
<AvatarLarge
user={user}
className={css.avatarDesktop}
initialsClassName={css.initialsDesktop}
disableProfileLink
/>

<AvatarMedium user={user} className={css.avatarMobile} disableProfileLink />
</div>
);
};
Expand Down
6 changes: 4 additions & 2 deletions src/containers/ListingPage/SectionFeaturesMaybe.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ const SectionFeaturesMaybe = props => {
}

const selectedOptions = publicData && publicData.yogaStyles ? publicData.yogaStyles : [];
const selectedConfigOptions = options.filter(o => selectedOptions.find(s => s === o.key));

return (
<div className={css.sectionFeatures}>
<h2 className={css.featuresTitle}>
<FormattedMessage id="ListingPage.featuresTitle" />
</h2>
<PropertyGroup
id="ListingPage.yogaStyles"
options={options}
options={selectedConfigOptions}
selectedOptions={selectedOptions}
twoColumns={true}
twoColumns={selectedConfigOptions > 5}
/>
</div>
);
Expand Down
22 changes: 0 additions & 22 deletions src/containers/ListingPage/SectionHeading.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import React from 'react';
import { FormattedMessage } from '../../util/reactIntl';
import { InlineTextButton } from '../../components';
import { LINE_ITEM_NIGHT, LINE_ITEM_DAY } from '../../util/types';
import config from '../../config';

import css from './ListingPage.css';

Expand All @@ -12,37 +10,17 @@ const getCertificateInfo = (certificateConfig, key) => {

const SectionHeading = props => {
const {
priceTitle,
formattedPrice,
richTitle,
listingCertificate,
certificateConfig,
showContactUser,
onContactUser,
} = props;

const unitType = config.bookingUnitType;
const isNightly = unitType === LINE_ITEM_NIGHT;
const isDaily = unitType === LINE_ITEM_DAY;

const unitTranslationKey = isNightly
? 'ListingPage.perNight'
: isDaily
? 'ListingPage.perDay'
: 'ListingPage.perUnit';

const certificate = getCertificateInfo(certificateConfig, listingCertificate);
const showCertificate = certificate && !certificate.hideFromListingInfo;
return (
<div className={css.sectionHeading}>
<div className={css.desktopPriceContainer}>
<div className={css.desktopPriceValue} title={priceTitle}>
{formattedPrice}
</div>
<div className={css.desktopPerUnit}>
<FormattedMessage id={unitTranslationKey} />
</div>
</div>
<div className={css.heading}>
<h1 className={css.title}>{richTitle}</h1>
<div className={css.author}>
Expand Down
Loading