From f6507657d4fbc0b218b8396fe7a99afa1c543d1b Mon Sep 17 00:00:00 2001 From: Kimmo Puputti Date: Tue, 10 Apr 2018 13:54:56 +0300 Subject: [PATCH] Extract images section into a separate file --- src/containers/ListingPage/ActionBarMaybe.js | 61 ++++++++ src/containers/ListingPage/ListingPage.css | 3 + src/containers/ListingPage/ListingPage.js | 119 ++------------ .../ListingPage/ListingPage.test.js | 3 +- src/containers/ListingPage/SectionImages.js | 75 +++++++++ .../__snapshots__/ListingPage.test.js.snap | 146 ++++++------------ 6 files changed, 203 insertions(+), 204 deletions(-) create mode 100644 src/containers/ListingPage/ActionBarMaybe.js create mode 100644 src/containers/ListingPage/SectionImages.js diff --git a/src/containers/ListingPage/ActionBarMaybe.js b/src/containers/ListingPage/ActionBarMaybe.js new file mode 100644 index 00000000..823bd665 --- /dev/null +++ b/src/containers/ListingPage/ActionBarMaybe.js @@ -0,0 +1,61 @@ +import React from 'react'; +import { bool, oneOfType, object } from 'prop-types'; +import { FormattedMessage } from 'react-intl'; +import classNames from 'classnames'; +import { LISTING_STATE_PENDING_APPROVAL, LISTING_STATE_CLOSED, propTypes } from '../../util/types'; +import { NamedLink } from '../../components'; +import EditIcon from './EditIcon'; + +import css from './ListingPage.css'; + +export const ActionBarMaybe = props => { + const { isOwnListing, listing, editParams } = props; + const state = listing.attributes.state; + const isPendingApproval = state === LISTING_STATE_PENDING_APPROVAL; + const isClosed = state === LISTING_STATE_CLOSED; + + if (isOwnListing) { + let ownListingTextTranslationId = 'ListingPage.ownListing'; + + if (isPendingApproval) { + ownListingTextTranslationId = 'ListingPage.ownListingPendingApproval'; + } else if (isClosed) { + ownListingTextTranslationId = 'ListingPage.ownClosedListing'; + } + + const ownListingTextClasses = classNames(css.ownListingText, { + [css.ownListingTextPendingApproval]: isPendingApproval, + }); + + return ( +
+

+ +

+ + + + +
+ ); + } else if (isClosed) { + return ( +
+

+ +

+
+ ); + } + return null; +}; + +ActionBarMaybe.propTypes = { + isOwnListing: bool.isRequired, + listing: oneOfType([propTypes.listing, propTypes.ownListing]).isRequired, + editParams: object.isRequired, +}; + +ActionBarMaybe.displayName = 'ActionBarMaybe'; + +export default ActionBarMaybe; diff --git a/src/containers/ListingPage/ListingPage.css b/src/containers/ListingPage/ListingPage.css index 9e043d21..c54fd964 100644 --- a/src/containers/ListingPage/ListingPage.css +++ b/src/containers/ListingPage/ListingPage.css @@ -17,6 +17,9 @@ margin: 24px; } +.sectionImages { +} + .threeToTwoWrapper { /* Layout */ display: block; diff --git a/src/containers/ListingPage/ListingPage.js b/src/containers/ListingPage/ListingPage.js index 6caff5e2..f084ba99 100644 --- a/src/containers/ListingPage/ListingPage.js +++ b/src/containers/ListingPage/ListingPage.js @@ -1,11 +1,10 @@ /* eslint-disable jsx-a11y/no-static-element-interactions */ import React, { Component } from 'react'; -import { arrayOf, bool, func, object, shape, string, oneOf, oneOfType } from 'prop-types'; +import { arrayOf, bool, func, shape, string, oneOf } from 'prop-types'; import { FormattedMessage, intlShape, injectIntl } from 'react-intl'; import { compose } from 'redux'; import { connect } from 'react-redux'; import { withRouter } from 'react-router-dom'; -import classNames from 'classnames'; import config from '../../config'; import routeConfiguration from '../../routeConfiguration'; import { LISTING_STATE_PENDING_APPROVAL, LISTING_STATE_CLOSED, propTypes } from '../../util/types'; @@ -23,11 +22,9 @@ import { Button, ModalInMobile, Page, - ResponsiveImage, NamedLink, NamedRedirect, Modal, - ImageCarousel, InlineTextButton, LayoutSingleColumn, LayoutWrapperTopbar, @@ -41,7 +38,7 @@ import { import { BookingDatesForm, TopbarContainer, EnquiryForm, NotFoundPage } from '../../containers'; import { sendEnquiry, loadData, setInitialValues } from './ListingPage.duck'; -import EditIcon from './EditIcon'; +import SectionImages from './SectionImages'; import SectionRulesMaybe from './SectionRulesMaybe'; import SectionMapMaybe from './SectionMapMaybe'; import css from './ListingPage.css'; @@ -66,56 +63,6 @@ const priceData = (price, intl) => { return {}; }; -export const ActionBarMaybe = props => { - const { isOwnListing, listing, editParams } = props; - const state = listing.attributes.state; - const isPendingApproval = state === LISTING_STATE_PENDING_APPROVAL; - const isClosed = state === LISTING_STATE_CLOSED; - - if (isOwnListing) { - let ownListingTextTranslationId = 'ListingPage.ownListing'; - - if (isPendingApproval) { - ownListingTextTranslationId = 'ListingPage.ownListingPendingApproval'; - } else if (isClosed) { - ownListingTextTranslationId = 'ListingPage.ownClosedListing'; - } - - const ownListingTextClasses = classNames(css.ownListingText, { - [css.ownListingTextPendingApproval]: isPendingApproval, - }); - - return ( -
-

- -

- - - - -
- ); - } else if (isClosed) { - return ( -
-

- -

-
- ); - } - return null; -}; - -ActionBarMaybe.propTypes = { - isOwnListing: bool.isRequired, - listing: oneOfType([propTypes.listing, propTypes.ownListing]).isRequired, - editParams: object.isRequired, -}; - -ActionBarMaybe.displayName = 'ActionBarMaybe'; - const openBookModal = (history, listing) => { if (!listing.id) { // Listing not fully loaded yet @@ -363,9 +310,6 @@ export class ListingPageComponent extends Component { ); } - const hasImages = currentListing.images && currentListing.images.length > 0; - const firstImage = hasImages ? currentListing.images[0] : null; - const handleViewPhotosClick = e => { // Stop event from bubbling up to prevent image click handler // trying to open the carousel as well. @@ -374,15 +318,6 @@ export class ListingPageComponent extends Component { imageCarouselOpen: true, }); }; - const viewPhotosButton = hasImages ? ( - - ) : null; - const authorAvailable = currentListing && currentListing.author; const userAndListingAuthorAvailable = !!(currentUser && authorAvailable); const isOwnListing = @@ -443,18 +378,6 @@ export class ListingPageComponent extends Component { } }; - // Action bar is wrapped with a div that prevents the click events - // to the parent that would otherwise open the image carousel - const actionBar = currentListing.id ? ( -
e.stopPropagation()}> - -
- ) : null; - const listingImages = (listing, variantName) => (listing.images || []) .map(image => { @@ -517,36 +440,16 @@ export class ListingPageComponent extends Component { {topbar}
-
-
- {actionBar} - - {viewPhotosButton} -
-
- this.setState({ imageCarouselOpen: false })} + this.setState({ imageCarouselOpen: false })} + handleViewPhotosClick={handleViewPhotosClick} onManageDisableScrolling={onManageDisableScrolling} - > - - - + />
diff --git a/src/containers/ListingPage/ListingPage.test.js b/src/containers/ListingPage/ListingPage.test.js index 2820c972..5fa87e54 100644 --- a/src/containers/ListingPage/ListingPage.test.js +++ b/src/containers/ListingPage/ListingPage.test.js @@ -24,7 +24,8 @@ import { showListingRequest, showListingError, showListing } from './ListingPage // Otherwise, ListingPage itself is not initialized correctly when routeConfiguration is imported // (loadData call fails). import routeConfiguration from '../../routeConfiguration'; -import { ListingPageComponent, ActionBarMaybe } from './ListingPage'; +import { ListingPageComponent } from './ListingPage'; +import ActionBarMaybe from './ActionBarMaybe'; const { UUID } = sdkTypes; const noop = () => null; diff --git a/src/containers/ListingPage/SectionImages.js b/src/containers/ListingPage/SectionImages.js new file mode 100644 index 00000000..2bfcc2f9 --- /dev/null +++ b/src/containers/ListingPage/SectionImages.js @@ -0,0 +1,75 @@ +import React from 'react'; +import { FormattedMessage } from 'react-intl'; +import { ResponsiveImage, Modal, ImageCarousel } from '../../components'; +import ActionBarMaybe from './ActionBarMaybe'; + +import css from './ListingPage.css'; + +const SectionImages = props => { + const { + title, + listing, + isOwnListing, + editParams, + handleViewPhotosClick, + imageCarouselOpen, + onImageCarouselClose, + onManageDisableScrolling, + } = props; + + const hasImages = listing.images && listing.images.length > 0; + const firstImage = hasImages ? listing.images[0] : null; + + // Action bar is wrapped with a div that prevents the click events + // to the parent that would otherwise open the image carousel + const actionBar = listing.id ? ( +
e.stopPropagation()}> + +
+ ) : null; + + const viewPhotosButton = hasImages ? ( + + ) : null; + + return ( +
+
+
+ {actionBar} + + {viewPhotosButton} +
+
+ + + +
+ ); +}; + +export default SectionImages; diff --git a/src/containers/ListingPage/__snapshots__/ListingPage.test.js.snap b/src/containers/ListingPage/__snapshots__/ListingPage.test.js.snap index 64fac301..9b170ea1 100644 --- a/src/containers/ListingPage/__snapshots__/ListingPage.test.js.snap +++ b/src/containers/ListingPage/__snapshots__/ListingPage.test.js.snap @@ -34,103 +34,59 @@ exports[`ListingPage matches snapshot 1`] = ` rootClassName={null} >
-
-
-
- -
- -
-
- - - + title="listing1 title" + />