-
- 55
-
+
+
+ 55
+
+
+
+
+
+
+
-
+
+
+ listing1
+
+
+ title
+
-
-
- listing1
-
-
- title
-
+ }
+ >
+
+
-
-
-
`;
diff --git a/src/containers/EditListingPage/EditListingPage.duck.js b/src/containers/EditListingPage/EditListingPage.duck.js
index ca821c67d2..76885dca4b 100644
--- a/src/containers/EditListingPage/EditListingPage.duck.js
+++ b/src/containers/EditListingPage/EditListingPage.duck.js
@@ -1,13 +1,9 @@
import omit from 'lodash/omit';
-import omitBy from 'lodash/omitBy';
-import isUndefined from 'lodash/isUndefined';
-import mergeWith from 'lodash/mergeWith';
import { types as sdkTypes } from '../../util/sdkLoader';
import { storableError } from '../../util/errors';
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import * as log from '../../util/log';
import { fetchCurrentUserHasListingsSuccess } from '../../ducks/user.duck';
-import { overrideArrays } from '../../util/data';
const { UUID } = sdkTypes;
@@ -22,9 +18,13 @@ const errorAction = actionType => error => ({ type: actionType, payload: error,
export const MARK_TAB_UPDATED = 'app/EditListingPage/MARK_TAB_UPDATED';
export const CLEAR_UPDATED_TAB = 'app/EditListingPage/CLEAR_UPDATED_TAB';
-export const CREATE_LISTING_REQUEST = 'app/EditListingPage/CREATE_LISTING_REQUEST';
-export const CREATE_LISTING_SUCCESS = 'app/EditListingPage/CREATE_LISTING_SUCCESS';
-export const CREATE_LISTING_ERROR = 'app/EditListingPage/CREATE_LISTING_ERROR';
+export const CREATE_LISTING_DRAFT_REQUEST = 'app/EditListingPage/CREATE_LISTING_DRAFT_REQUEST';
+export const CREATE_LISTING_DRAFT_SUCCESS = 'app/EditListingPage/CREATE_LISTING_DRAFT_SUCCESS';
+export const CREATE_LISTING_DRAFT_ERROR = 'app/EditListingPage/CREATE_LISTING_DRAFT_ERROR';
+
+export const PUBLISH_LISTING_REQUEST = 'app/EditListingPage/PUBLISH_LISTING_REQUEST';
+export const PUBLISH_LISTING_SUCCESS = 'app/EditListingPage/PUBLISH_LISTING_SUCCESS';
+export const PUBLISH_LISTING_ERROR = 'app/EditListingPage/PUBLISH_LISTING_ERROR';
export const UPDATE_LISTING_REQUEST = 'app/EditListingPage/UPDATE_LISTING_REQUEST';
export const UPDATE_LISTING_SUCCESS = 'app/EditListingPage/UPDATE_LISTING_SUCCESS';
@@ -40,20 +40,19 @@ export const UPLOAD_IMAGE_ERROR = 'app/EditListingPage/UPLOAD_IMAGE_ERROR';
export const UPDATE_IMAGE_ORDER = 'app/EditListingPage/UPDATE_IMAGE_ORDER';
-export const CREATE_LISTING_DRAFT = 'app/EditListingPage/CREATE_LISTING_DRAFT';
-export const UPDATE_LISTING_DRAFT = 'app/EditListingPage/UPDATE_LISTING_DRAFT';
-
export const REMOVE_LISTING_IMAGE = 'app/EditListingPage/REMOVE_LISTING_IMAGE';
// ================ Reducer ================ //
const initialState = {
// Error instance placeholders for each endpoint
- createListingsError: null,
+ createListingDraftError: null,
+ publishingListing: null,
+ publishListingError: null,
updateListingError: null,
showListingsError: null,
uploadImageError: null,
- createListingInProgress: false,
+ createListingDraftInProgress: false,
submittedListingId: null,
redirectToListing: false,
images: {},
@@ -72,28 +71,52 @@ export default function reducer(state = initialState, action = {}) {
case CLEAR_UPDATED_TAB:
return { ...state, updatedTab: null, updateListingError: null };
- case CREATE_LISTING_REQUEST:
+ case CREATE_LISTING_DRAFT_REQUEST:
return {
...state,
- createListingInProgress: true,
- createListingsError: null,
+ createListingDraftInProgress: true,
+ createListingDraftError: null,
submittedListingId: null,
- redirectToListing: false,
+ listingDraft: null,
};
- case CREATE_LISTING_SUCCESS:
+
+ case CREATE_LISTING_DRAFT_SUCCESS:
return {
...state,
- createListingInProgress: false,
+ createListingDraftInProgress: false,
submittedListingId: payload.data.id,
+ listingDraft: payload.data,
+ };
+ case CREATE_LISTING_DRAFT_ERROR:
+ return {
+ ...state,
+ createListingDraftInProgress: false,
+ createListingDraftError: payload,
+ };
+
+ case PUBLISH_LISTING_REQUEST:
+ return {
+ ...state,
+ publishingListing: payload.listingId,
+ publishListingError: null,
+ };
+ case PUBLISH_LISTING_SUCCESS:
+ return {
redirectToListing: true,
+ publishingListing: null,
};
- case CREATE_LISTING_ERROR:
+ case PUBLISH_LISTING_ERROR: {
+ // eslint-disable-next-line no-console
+ console.error(payload);
return {
...state,
- createListingInProgress: false,
- createListingsError: payload,
- redirectToListing: false,
+ publishingListing: null,
+ publishListingError: {
+ listingId: state.publishingListing,
+ error: payload,
+ },
};
+ }
case UPDATE_LISTING_REQUEST:
return { ...state, updateInProgress: true, updateListingError: null };
@@ -141,23 +164,6 @@ export default function reducer(state = initialState, action = {}) {
case UPDATE_IMAGE_ORDER:
return { ...state, imageOrder: payload.imageOrder };
- case CREATE_LISTING_DRAFT:
- case UPDATE_LISTING_DRAFT: {
- const { attributes, images } = state.listingDraft || {};
- const updatedImages = payload.images || images;
- return {
- ...state,
- listingDraft: {
- attributes: mergeWith(
- attributes,
- omitBy(payload.attributes, isUndefined),
- overrideArrays
- ),
- images: updatedImages,
- },
- };
- }
-
case REMOVE_LISTING_IMAGE: {
const id = payload.imageId;
@@ -198,28 +204,6 @@ export const updateImageOrder = imageOrder => ({
payload: { imageOrder },
});
-export const createListingDraft = listingData => {
- const { images, ...attributes } = listingData;
- return {
- type: CREATE_LISTING_DRAFT,
- payload: {
- attributes,
- images,
- },
- };
-};
-
-export const updateListingDraft = listingData => {
- const { images, ...attributes } = listingData;
- return {
- type: UPDATE_LISTING_DRAFT,
- payload: {
- attributes,
- images,
- },
- };
-};
-
export const removeListingImage = imageId => ({
type: REMOVE_LISTING_IMAGE,
payload: { imageId },
@@ -230,9 +214,14 @@ export const removeListingImage = imageId => ({
// expects.
// SDK method: ownListings.create
-export const createListing = requestAction(CREATE_LISTING_REQUEST);
-export const createListingSuccess = successAction(CREATE_LISTING_SUCCESS);
-export const createListingError = errorAction(CREATE_LISTING_ERROR);
+export const createListingDraft = requestAction(CREATE_LISTING_DRAFT_REQUEST);
+export const createListingDraftSuccess = successAction(CREATE_LISTING_DRAFT_SUCCESS);
+export const createListingDraftError = errorAction(CREATE_LISTING_DRAFT_ERROR);
+
+// SDK method: ownListings.publish
+export const publishListing = requestAction(PUBLISH_LISTING_REQUEST);
+export const publishListingSuccess = successAction(PUBLISH_LISTING_SUCCESS);
+export const publishListingError = errorAction(PUBLISH_LISTING_ERROR);
// SDK method: ownListings.update
export const updateListing = requestAction(UPDATE_LISTING_REQUEST);
@@ -267,40 +256,56 @@ export function requestShowListing(actionPayload) {
};
}
-export function requestCreateListing(data) {
+export function requestCreateListingDraft(data) {
return (dispatch, getState, sdk) => {
- dispatch(createListing(data));
+ dispatch(createListingDraft(data));
+
+ const queryParams = {
+ expand: true,
+ include: ['author', 'images'],
+ 'fields.image': ['variants.landscape-crop', 'variants.landscape-crop2x'],
+ };
return sdk.ownListings
- .create(data)
- .then(response => {
- const id = response.data.data.id.uuid;
- // Modify store to understand that we have created listing and can redirect away
- dispatch(createListingSuccess(response));
- // Fetch listing data so that redirection is smooth
- dispatch(
- requestShowListing({
- id,
- include: ['author', 'images'],
- 'fields.image': ['variants.landscape-crop', 'variants.landscape-crop2x'],
- })
- );
- return response;
- })
+ .createDraft(data, queryParams)
.then(response => {
+ //const id = response.data.data.id.uuid;
+
+ // Add the created listing to the marketplace data
+ dispatch(addMarketplaceEntities(response));
+
// We must update the user duck since this might be the first
// listing for the user, therefore changing the
// currentUserHasListings flag in the store.
dispatch(fetchCurrentUserHasListingsSuccess(true));
+
+ // Modify store to understand that we have created listing and can redirect away
+ dispatch(createListingDraftSuccess(response));
return response;
})
.catch(e => {
- log.error(e, 'create-listing-failed', { listingData: data });
- return dispatch(createListingError(storableError(e)));
+ log.error(e, 'create-listing-draft-failed', { listingData: data });
+ return dispatch(createListingDraftError(storableError(e)));
});
};
}
+export const requestPublishListingDraft = listingId => (dispatch, getState, sdk) => {
+ dispatch(publishListing(listingId));
+
+ return sdk.ownListings
+ .publishDraft({ id: listingId }, { expand: true })
+ .then(response => {
+ // Add the created listing to the marketplace data
+ dispatch(addMarketplaceEntities(response));
+ dispatch(publishListingSuccess(response));
+ return response;
+ })
+ .catch(e => {
+ dispatch(publishListingError(storableError(e)));
+ });
+};
+
// Images return imageId which we need to map with previously generated temporary id
export function requestImageUpload(actionPayload) {
return (dispatch, getState, sdk) => {
@@ -335,6 +340,7 @@ export function requestUpdateListing(tab, data) {
.then(() => {
dispatch(markTabUpdated(tab));
dispatch(updateListingSuccess(updateResponse));
+ return updateResponse;
})
.catch(e => {
log.error(e, 'update-listing-failed', { listingData: data });
diff --git a/src/containers/EditListingPage/EditListingPage.js b/src/containers/EditListingPage/EditListingPage.js
index 3e066b38d1..800f3974c0 100644
--- a/src/containers/EditListingPage/EditListingPage.js
+++ b/src/containers/EditListingPage/EditListingPage.js
@@ -5,8 +5,15 @@ import { withRouter } from 'react-router-dom';
import { intlShape, injectIntl } from 'react-intl';
import { connect } from 'react-redux';
import { types as sdkTypes } from '../../util/sdkLoader';
-import { LISTING_PAGE_PENDING_APPROVAL_VARIANT, createSlug } from '../../util/urlHelpers';
-import { LISTING_STATE_PENDING_APPROVAL, propTypes } from '../../util/types';
+import {
+ LISTING_PAGE_PARAM_TYPE_DRAFT,
+ LISTING_PAGE_PARAM_TYPE_NEW,
+ LISTING_PAGE_PARAM_TYPES,
+ LISTING_PAGE_PENDING_APPROVAL_VARIANT,
+ createSlug,
+} from '../../util/urlHelpers';
+import { LISTING_STATE_DRAFT, LISTING_STATE_PENDING_APPROVAL, propTypes } from '../../util/types';
+import { ensureOwnListing } from '../../util/data';
import { getMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import { manageDisableScrolling, isScrollingDisabled } from '../../ducks/UI.duck';
import { stripeAccountClearError, createStripeAccount } from '../../ducks/user.duck';
@@ -14,9 +21,8 @@ import { EditListingWizard, NamedRedirect, Page } from '../../components';
import { TopbarContainer } from '../../containers';
import {
- createListingDraft,
- updateListingDraft,
- requestCreateListing,
+ requestCreateListingDraft,
+ requestPublishListingDraft,
requestUpdateListing,
requestImageUpload,
updateImageOrder,
@@ -38,16 +44,15 @@ export const EditListingPageComponent = props => {
getOwnListing,
history,
intl,
- onCreateListing,
- onUpdateListing,
onCreateListingDraft,
+ onPublishListingDraft,
+ onUpdateListing,
onImageUpload,
onRemoveListingImage,
onManageDisableScrolling,
onPayoutDetailsSubmit,
onPayoutDetailsFormChange,
onUpdateImageOrder,
- onUpdateListingDraft,
onChange,
page,
params,
@@ -55,18 +60,21 @@ export const EditListingPageComponent = props => {
} = props;
const { id, type } = params;
+ const isNewURI = type === LISTING_PAGE_PARAM_TYPE_NEW;
+ const isDraftURI = type === LISTING_PAGE_PARAM_TYPE_DRAFT;
- const isNew = type === 'new';
- const newListingCreated = isNew && !!page.submittedListingId;
const listingId = page.submittedListingId || (id ? new UUID(id) : null);
- const currentListing = getOwnListing(listingId);
- const isPendingApproval =
- currentListing && currentListing.attributes.state === LISTING_STATE_PENDING_APPROVAL;
+ const currentListing = ensureOwnListing(getOwnListing(listingId));
+ const { state: currentListingState } = currentListing.attributes;
- const shouldRedirect = page.submittedListingId && currentListing;
- const showForm = isNew || currentListing;
+ const isPastDraft = currentListingState && currentListingState !== LISTING_STATE_DRAFT;
+ const shouldRedirect = (isNewURI || isDraftURI) && listingId && isPastDraft;
+ const showForm = isNewURI || currentListing.id;
if (shouldRedirect) {
+ const isPendingApproval =
+ currentListing && currentListingState === LISTING_STATE_PENDING_APPROVAL;
+
// If page has already listingId (after submit) and current listings exist
// redirect to listing page
const listingSlug = currentListing ? createSlug(currentListing.attributes.title) : null;
@@ -91,36 +99,44 @@ export const EditListingPageComponent = props => {
return
;
} else if (showForm) {
const {
- createListingsError = null,
+ createListingDraftError = null,
+ publishListingError = null,
updateListingError = null,
showListingsError = null,
uploadImageError = null,
} = page;
const errors = {
- createListingsError,
+ createListingDraftError,
+ publishListingError,
updateListingError,
showListingsError,
uploadImageError,
createStripeAccountError,
};
+ const newListingPublished =
+ isDraftURI && currentListing && currentListingState !== LISTING_STATE_DRAFT;
// Show form if user is posting a new listing or editing existing one
const disableForm = page.redirectToListing && !showListingsError;
// Images are passed to EditListingForm so that it can generate thumbnails out of them
- const currentListingImages = currentListing ? currentListing.images : [];
+ const currentListingImages =
+ currentListing && currentListing.images ? currentListing.images : [];
// Images not yet connected to the listing
- const unattachedImages = page.imageOrder.map(i => page.images[i]);
+ const imageOrder = page.imageOrder || [];
+ const unattachedImages = imageOrder.map(i => page.images[i]);
const allImages = currentListingImages.concat(unattachedImages);
+ const removedImageIds = page.removedImageIds || [];
const images = allImages.filter(img => {
- return !page.removedImageIds.includes(img.id);
+ return !removedImageIds.includes(img.id);
});
- const title = isNew
- ? intl.formatMessage({ id: 'EditListingPage.titleCreateListing' })
- : intl.formatMessage({ id: 'EditListingPage.titleEditListing' });
+ const title =
+ isNewURI || isDraftURI
+ ? intl.formatMessage({ id: 'EditListingPage.titleCreateListing' })
+ : intl.formatMessage({ id: 'EditListingPage.titleEditListing' });
return (
@@ -137,14 +153,13 @@ export const EditListingPageComponent = props => {
disabled={disableForm}
errors={errors}
fetchInProgress={fetchInProgress}
- newListingCreated={newListingCreated}
+ newListingPublished={newListingPublished}
history={history}
images={images}
- listing={isNew ? page.listingDraft : currentListing}
- onCreateListing={onCreateListing}
+ listing={currentListing}
onUpdateListing={onUpdateListing}
onCreateListingDraft={onCreateListingDraft}
- onUpdateListingDraft={onUpdateListingDraft}
+ onPublishListingDraft={onPublishListingDraft}
onPayoutDetailsFormChange={onPayoutDetailsFormChange}
onPayoutDetailsSubmit={onPayoutDetailsSubmit}
onImageUpload={onImageUpload}
@@ -154,7 +169,7 @@ export const EditListingPageComponent = props => {
currentUser={currentUser}
onManageDisableScrolling={onManageDisableScrolling}
updatedTab={page.updatedTab}
- updateInProgress={page.updateInProgress || page.createListingInProgress}
+ updateInProgress={page.updateInProgress || page.createListingDraftInProgress}
/>
);
@@ -187,22 +202,21 @@ EditListingPageComponent.propTypes = {
currentUser: propTypes.currentUser,
fetchInProgress: bool.isRequired,
getOwnListing: func.isRequired,
- onCreateListing: func.isRequired,
onCreateListingDraft: func.isRequired,
+ onPublishListingDraft: func.isRequired,
onImageUpload: func.isRequired,
onManageDisableScrolling: func.isRequired,
onPayoutDetailsFormChange: func.isRequired,
onPayoutDetailsSubmit: func.isRequired,
onUpdateImageOrder: func.isRequired,
onRemoveListingImage: func.isRequired,
- onUpdateListingDraft: func.isRequired,
onUpdateListing: func.isRequired,
onChange: func.isRequired,
page: object.isRequired,
params: shape({
id: string.isRequired,
slug: string.isRequired,
- type: oneOf(['new', 'edit']).isRequired,
+ type: oneOf(LISTING_PAGE_PARAM_TYPES).isRequired,
tab: string.isRequired,
}).isRequired,
scrollingDisabled: bool.isRequired,
@@ -238,9 +252,9 @@ const mapStateToProps = state => {
};
const mapDispatchToProps = dispatch => ({
- onCreateListing: values => dispatch(requestCreateListing(values)),
onUpdateListing: (tab, values) => dispatch(requestUpdateListing(tab, values)),
- onCreateListingDraft: values => dispatch(createListingDraft(values)),
+ onCreateListingDraft: values => dispatch(requestCreateListingDraft(values)),
+ onPublishListingDraft: listingId => dispatch(requestPublishListingDraft(listingId)),
onImageUpload: data => dispatch(requestImageUpload(data)),
onManageDisableScrolling: (componentId, disableScrolling) =>
dispatch(manageDisableScrolling(componentId, disableScrolling)),
@@ -248,7 +262,6 @@ const mapDispatchToProps = dispatch => ({
onPayoutDetailsSubmit: values => dispatch(createStripeAccount(values)),
onUpdateImageOrder: imageOrder => dispatch(updateImageOrder(imageOrder)),
onRemoveListingImage: imageId => dispatch(removeListingImage(imageId)),
- onUpdateListingDraft: values => dispatch(updateListingDraft(values)),
onChange: () => dispatch(clearUpdatedTab()),
});
diff --git a/src/containers/EditListingPage/EditListingPage.test.js b/src/containers/EditListingPage/EditListingPage.test.js
index 7137f06628..5a9637fc97 100644
--- a/src/containers/EditListingPage/EditListingPage.test.js
+++ b/src/containers/EditListingPage/EditListingPage.test.js
@@ -24,7 +24,7 @@ describe('EditListingPageComponent', () => {
onManageDisableScrolling={noop}
onCreateListing={noop}
onCreateListingDraft={noop}
- onUpdateListingDraft={noop}
+ onPublishListingDraft={noop}
onUpdateListing={noop}
onImageUpload={noop}
onRemoveListingImage={noop}
diff --git a/src/containers/EditListingPage/__snapshots__/EditListingPage.test.js.snap b/src/containers/EditListingPage/__snapshots__/EditListingPage.test.js.snap
index 08f5d6d533..9a7f6d6b3d 100644
--- a/src/containers/EditListingPage/__snapshots__/EditListingPage.test.js.snap
+++ b/src/containers/EditListingPage/__snapshots__/EditListingPage.test.js.snap
@@ -10,8 +10,9 @@ exports[`EditListingPageComponent matches snapshot 1`] = `
currentUser={null}
errors={
Object {
- "createListingsError": null,
+ "createListingDraftError": null,
"createStripeAccountError": null,
+ "publishListingError": null,
"showListingsError": null,
"updateListingError": null,
"uploadImageError": null,
@@ -25,18 +26,27 @@ exports[`EditListingPageComponent matches snapshot 1`] = `
}
id="EditListingWizard"
images={Array []}
- newListingCreated={false}
+ listing={
+ Object {
+ "attributes": Object {
+ "publicData": Object {},
+ },
+ "id": null,
+ "images": Array [],
+ "type": "ownListing",
+ }
+ }
+ newListingPublished={false}
onChange={[Function]}
- onCreateListing={[Function]}
onCreateListingDraft={[Function]}
onImageUpload={[Function]}
onManageDisableScrolling={[Function]}
onPayoutDetailsFormChange={[Function]}
onPayoutDetailsSubmit={[Function]}
+ onPublishListingDraft={[Function]}
onRemoveImage={[Function]}
onUpdateImageOrder={[Function]}
onUpdateListing={[Function]}
- onUpdateListingDraft={[Function]}
params={
Object {
"id": "id",
diff --git a/src/containers/ListingPage/ActionBarMaybe.js b/src/containers/ListingPage/ActionBarMaybe.js
index 823bd665c4..5b07d19a42 100644
--- a/src/containers/ListingPage/ActionBarMaybe.js
+++ b/src/containers/ListingPage/ActionBarMaybe.js
@@ -2,7 +2,12 @@ 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 {
+ LISTING_STATE_PENDING_APPROVAL,
+ LISTING_STATE_CLOSED,
+ LISTING_STATE_DRAFT,
+ propTypes,
+} from '../../util/types';
import { NamedLink } from '../../components';
import EditIcon from './EditIcon';
@@ -13,6 +18,7 @@ export const ActionBarMaybe = props => {
const state = listing.attributes.state;
const isPendingApproval = state === LISTING_STATE_PENDING_APPROVAL;
const isClosed = state === LISTING_STATE_CLOSED;
+ const isDraft = state === LISTING_STATE_DRAFT;
if (isOwnListing) {
let ownListingTextTranslationId = 'ListingPage.ownListing';
@@ -21,8 +27,12 @@ export const ActionBarMaybe = props => {
ownListingTextTranslationId = 'ListingPage.ownListingPendingApproval';
} else if (isClosed) {
ownListingTextTranslationId = 'ListingPage.ownClosedListing';
+ } else if (isDraft) {
+ ownListingTextTranslationId = 'ListingPage.ownListingDraft';
}
+ const message = isDraft ? 'ListingPage.finishListing' : 'ListingPage.editListing';
+
const ownListingTextClasses = classNames(css.ownListingText, {
[css.ownListingTextPendingApproval]: isPendingApproval,
});
@@ -34,7 +44,7 @@ export const ActionBarMaybe = props => {
-
+
);
diff --git a/src/containers/ListingPage/ListingPage.duck.js b/src/containers/ListingPage/ListingPage.duck.js
index 1728586c3c..56fbdeeb10 100644
--- a/src/containers/ListingPage/ListingPage.duck.js
+++ b/src/containers/ListingPage/ListingPage.duck.js
@@ -6,7 +6,10 @@ import { storableError } from '../../util/errors';
import { addMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import { denormalisedResponseEntities } from '../../util/data';
import { TRANSITION_ENQUIRE } from '../../util/types';
-import { LISTING_PAGE_PENDING_APPROVAL_VARIANT } from '../../util/urlHelpers';
+import {
+ LISTING_PAGE_DRAFT_VARIANT,
+ LISTING_PAGE_PENDING_APPROVAL_VARIANT,
+} from '../../util/urlHelpers';
import { fetchCurrentUser, fetchCurrentUserHasOrdersSuccess } from '../../ducks/user.duck';
const { UUID } = sdkTypes;
@@ -269,7 +272,8 @@ export const sendEnquiry = (listingId, message) => (dispatch, getState, sdk) =>
export const loadData = (params, search) => dispatch => {
const listingId = new UUID(params.id);
- if (params.variant === LISTING_PAGE_PENDING_APPROVAL_VARIANT) {
+ const ownListingVariants = [LISTING_PAGE_DRAFT_VARIANT, LISTING_PAGE_PENDING_APPROVAL_VARIANT];
+ if (ownListingVariants.includes(params.variant)) {
return dispatch(showListing(listingId, true));
}
diff --git a/src/containers/ListingPage/ListingPage.js b/src/containers/ListingPage/ListingPage.js
index 9e11022c9b..f5a4266712 100644
--- a/src/containers/ListingPage/ListingPage.js
+++ b/src/containers/ListingPage/ListingPage.js
@@ -9,7 +9,14 @@ import config from '../../config';
import routeConfiguration from '../../routeConfiguration';
import { LISTING_STATE_PENDING_APPROVAL, LISTING_STATE_CLOSED, propTypes } from '../../util/types';
import { types as sdkTypes } from '../../util/sdkLoader';
-import { LISTING_PAGE_PENDING_APPROVAL_VARIANT, createSlug, parse } from '../../util/urlHelpers';
+import {
+ LISTING_PAGE_DRAFT_VARIANT,
+ LISTING_PAGE_PENDING_APPROVAL_VARIANT,
+ LISTING_PAGE_PARAM_TYPE_DRAFT,
+ LISTING_PAGE_PARAM_TYPE_EDIT,
+ createSlug,
+ parse,
+} from '../../util/urlHelpers';
import { formatMoney } from '../../util/currency';
import { createResourceLocatorString, findRouteByRouteName } from '../../util/routes';
import { ensureListing, ensureOwnListing, ensureUser, userDisplayName } from '../../util/data';
@@ -32,7 +39,7 @@ import { sendEnquiry, loadData, setInitialValues } from './ListingPage.duck';
import SectionImages from './SectionImages';
import SectionAvatar from './SectionAvatar';
import SectionHeading from './SectionHeading';
-import SectionDescription from './SectionDescription';
+import SectionDescriptionMaybe from './SectionDescriptionMaybe';
import SectionFeatures from './SectionFeatures';
import SectionReviews from './SectionReviews';
import SectionHost from './SectionHost';
@@ -206,13 +213,20 @@ export class ListingPageComponent extends Component {
const isBook = !!parse(location.search).book;
const listingId = new UUID(rawParams.id);
const isPendingApprovalVariant = rawParams.variant === LISTING_PAGE_PENDING_APPROVAL_VARIANT;
- const currentListing = isPendingApprovalVariant
- ? ensureOwnListing(getOwnListing(listingId))
- : ensureListing(getListing(listingId));
+ const isDraftVariant = rawParams.variant === LISTING_PAGE_DRAFT_VARIANT;
+ const currentListing =
+ isPendingApprovalVariant || isDraftVariant
+ ? ensureOwnListing(getOwnListing(listingId))
+ : ensureListing(getListing(listingId));
const listingSlug = rawParams.slug || createSlug(currentListing.attributes.title || '');
const params = { slug: listingSlug, ...rawParams };
+ const listingType = isDraftVariant
+ ? LISTING_PAGE_PARAM_TYPE_DRAFT
+ : LISTING_PAGE_PARAM_TYPE_EDIT;
+ const listingTab = isDraftVariant ? 'photos' : 'description';
+
const isApproved =
currentListing.id && currentListing.attributes.state !== LISTING_STATE_PENDING_APPROVAL;
@@ -224,7 +238,9 @@ export class ListingPageComponent extends Component {
// another user. We use this information to try to fetch the
// public listing.
const pendingOtherUsersListing =
- isPendingApprovalVariant && showListingError && showListingError.status === 403;
+ (isPendingApprovalVariant || isDraftVariant) &&
+ showListingError &&
+ showListingError.status === 403;
const shouldShowPublicListingPage = pendingIsApproved || pendingOtherUsersListing;
if (shouldShowPublicListingPage) {
@@ -418,8 +434,8 @@ export class ListingPageComponent extends Component {
editParams={{
id: listingId.uuid,
slug: listingSlug,
- type: 'edit',
- tab: 'description',
+ type: listingType,
+ tab: listingTab,
}}
imageCarouselOpen={this.state.imageCarouselOpen}
onImageCarouselClose={() => this.setState({ imageCarouselOpen: false })}
@@ -438,7 +454,7 @@ export class ListingPageComponent extends Component {
showContactUser={showContactUser}
onContactUser={this.onContactUser}
/>
-