mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-26 06:47:17 +10:00
EditListingWizard: use onCreateListingDraft and onPublishListingDraft
instead of plain createListing.
This commit is contained in:
parent
98e279542d
commit
9e48a1fca7
2 changed files with 106 additions and 56 deletions
|
|
@ -4,6 +4,11 @@ import { compose } from 'redux';
|
|||
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
|
||||
import classNames from 'classnames';
|
||||
import { withViewport } from '../../util/contextHelpers';
|
||||
import {
|
||||
LISTING_PAGE_PARAM_TYPE_DRAFT,
|
||||
LISTING_PAGE_PARAM_TYPE_NEW,
|
||||
LISTING_PAGE_PARAM_TYPES,
|
||||
} from '../../util/urlHelpers';
|
||||
import { ensureListing } from '../../util/data';
|
||||
import { PayoutDetailsForm } from '../../forms';
|
||||
import { Modal, NamedRedirect, Tabs } from '../../components';
|
||||
|
|
@ -111,11 +116,11 @@ class EditListingWizard extends Component {
|
|||
this.hasScrolledToTab = false;
|
||||
|
||||
this.state = {
|
||||
submittedValues: null,
|
||||
draftId: null,
|
||||
showPayoutDetails: false,
|
||||
};
|
||||
this.handleCreateFlowTabScrolling = this.handleCreateFlowTabScrolling.bind(this);
|
||||
this.handleCreateListing = this.handleCreateListing.bind(this);
|
||||
this.handlePublishListing = this.handlePublishListing.bind(this);
|
||||
this.handlePayoutModalClose = this.handlePayoutModalClose.bind(this);
|
||||
this.handlePayoutSubmit = this.handlePayoutSubmit.bind(this);
|
||||
}
|
||||
|
|
@ -124,15 +129,15 @@ class EditListingWizard extends Component {
|
|||
this.hasScrolledToTab = shouldScroll;
|
||||
}
|
||||
|
||||
handleCreateListing(values) {
|
||||
const { onCreateListing, currentUser } = this.props;
|
||||
handlePublishListing(id) {
|
||||
const { onPublishListingDraft, currentUser } = this.props;
|
||||
const stripeConnected =
|
||||
currentUser && currentUser.attributes && currentUser.attributes.stripeConnected;
|
||||
if (stripeConnected) {
|
||||
onCreateListing(values);
|
||||
onPublishListingDraft(id);
|
||||
} else {
|
||||
this.setState({
|
||||
submittedValues: values,
|
||||
draftId: id,
|
||||
showPayoutDetails: true,
|
||||
});
|
||||
}
|
||||
|
|
@ -149,7 +154,7 @@ class EditListingWizard extends Component {
|
|||
.then(() => {
|
||||
this.setState({ showPayoutDetails: false });
|
||||
this.props.onManageDisableScrolling('EditListingWizard.payoutModal', false);
|
||||
this.props.onCreateListing(this.state.submittedValues);
|
||||
this.props.onPublishListingDraft(this.state.draftId);
|
||||
})
|
||||
.catch(() => {
|
||||
// do nothing
|
||||
|
|
@ -173,15 +178,22 @@ class EditListingWizard extends Component {
|
|||
} = this.props;
|
||||
|
||||
const selectedTab = params.tab;
|
||||
const isNew = params.type === 'new';
|
||||
const isNewListingFlow = [LISTING_PAGE_PARAM_TYPE_NEW, LISTING_PAGE_PARAM_TYPE_DRAFT].includes(
|
||||
params.type
|
||||
);
|
||||
const rootClasses = rootClassName || css.root;
|
||||
const classes = classNames(rootClasses, className);
|
||||
const currentListing = ensureListing(listing);
|
||||
const tabsStatus = tabsActive(isNew, currentListing);
|
||||
const tabsStatus = tabsActive(isNewListingFlow, currentListing);
|
||||
|
||||
// If selectedTab is not active, redirect to the beginning of wizard
|
||||
if (!tabsStatus[selectedTab]) {
|
||||
return <NamedRedirect name="EditListingPage" params={{ ...params, tab: TABS[0] }} />;
|
||||
const currentTabIndex = TABS.indexOf(selectedTab);
|
||||
const nearestActiveTab = TABS.slice(0, currentTabIndex)
|
||||
.reverse()
|
||||
.find(t => tabsStatus[t]);
|
||||
|
||||
return <NamedRedirect name="EditListingPage" params={{ ...params, tab: nearestActiveTab }} />;
|
||||
}
|
||||
|
||||
const { width } = viewport;
|
||||
|
|
@ -220,7 +232,7 @@ class EditListingWizard extends Component {
|
|||
tabLabel={tabLabel(intl, tab)}
|
||||
tabLinkProps={tabLink(tab)}
|
||||
selected={selectedTab === tab}
|
||||
disabled={isNew && !tabsStatus[tab]}
|
||||
disabled={isNewListingFlow && !tabsStatus[tab]}
|
||||
tab={tab}
|
||||
intl={intl}
|
||||
params={params}
|
||||
|
|
@ -228,7 +240,7 @@ class EditListingWizard extends Component {
|
|||
marketplaceTabs={TABS}
|
||||
errors={errors}
|
||||
handleCreateFlowTabScrolling={this.handleCreateFlowTabScrolling}
|
||||
handleCreateListing={this.handleCreateListing}
|
||||
handlePublishListing={this.handlePublishListing}
|
||||
fetchInProgress={fetchInProgress}
|
||||
/>
|
||||
);
|
||||
|
|
@ -276,7 +288,7 @@ EditListingWizard.propTypes = {
|
|||
params: shape({
|
||||
id: string.isRequired,
|
||||
slug: string.isRequired,
|
||||
type: oneOf(['new', 'edit']).isRequired,
|
||||
type: oneOf(LISTING_PAGE_PARAM_TYPES).isRequired,
|
||||
tab: oneOf(TABS).isRequired,
|
||||
}).isRequired,
|
||||
|
||||
|
|
@ -293,14 +305,14 @@ EditListingWizard.propTypes = {
|
|||
}),
|
||||
|
||||
errors: shape({
|
||||
createListingsError: object,
|
||||
createListingDraftError: object,
|
||||
updateListingError: object,
|
||||
publishListingError: object,
|
||||
showListingsError: object,
|
||||
uploadImageError: object,
|
||||
createStripeAccountError: object,
|
||||
}),
|
||||
}).isRequired,
|
||||
fetchInProgress: bool.isRequired,
|
||||
onCreateListing: func.isRequired,
|
||||
onPayoutDetailsFormChange: func.isRequired,
|
||||
onPayoutDetailsSubmit: func.isRequired,
|
||||
onManageDisableScrolling: func.isRequired,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@ import React from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { intlShape } from 'react-intl';
|
||||
import routeConfiguration from '../../routeConfiguration';
|
||||
import {
|
||||
LISTING_PAGE_PARAM_TYPE_DRAFT,
|
||||
LISTING_PAGE_PARAM_TYPE_NEW,
|
||||
LISTING_PAGE_PARAM_TYPES,
|
||||
} from '../../util/urlHelpers';
|
||||
import { ensureListing } from '../../util/data';
|
||||
import { createResourceLocatorString } from '../../util/routes';
|
||||
import {
|
||||
|
|
@ -34,6 +39,28 @@ const pathParamsToNextTab = (params, tab, marketplaceTabs) => {
|
|||
return { ...params, tab: nextTab };
|
||||
};
|
||||
|
||||
// When user has update draft listing, he should be redirected to next EditListingWizardTab
|
||||
const redirectAfterDraftUpdate = (listingId, params, tab, marketplaceTabs, history) => {
|
||||
const currentPathParams = {
|
||||
...params,
|
||||
type: LISTING_PAGE_PARAM_TYPE_DRAFT,
|
||||
id: listingId,
|
||||
};
|
||||
const routes = routeConfiguration();
|
||||
|
||||
// Replace current "new" path to "draft" path.
|
||||
// Browser's back button should lead to editing current draft instead of creating a new one.
|
||||
if (params.type === LISTING_PAGE_PARAM_TYPE_NEW) {
|
||||
const draftURI = createResourceLocatorString('EditListingPage', routes, currentPathParams, {});
|
||||
history.replace(draftURI);
|
||||
}
|
||||
|
||||
// Redirect to next tab
|
||||
const nextPathParams = pathParamsToNextTab(currentPathParams, tab, marketplaceTabs);
|
||||
const to = createResourceLocatorString('EditListingPage', routes, nextPathParams, {});
|
||||
history.push(to);
|
||||
};
|
||||
|
||||
const EditListingWizardTab = props => {
|
||||
const {
|
||||
tab,
|
||||
|
|
@ -41,55 +68,66 @@ const EditListingWizardTab = props => {
|
|||
params,
|
||||
errors,
|
||||
fetchInProgress,
|
||||
newListingCreated,
|
||||
newListingPublished,
|
||||
history,
|
||||
images,
|
||||
listing,
|
||||
handleCreateFlowTabScrolling,
|
||||
handleCreateListing,
|
||||
handlePublishListing,
|
||||
onUpdateListing,
|
||||
onCreateListingDraft,
|
||||
onImageUpload,
|
||||
onUpdateImageOrder,
|
||||
onRemoveImage,
|
||||
onUpdateListingDraft,
|
||||
onChange,
|
||||
updatedTab,
|
||||
updateInProgress,
|
||||
intl,
|
||||
} = props;
|
||||
|
||||
const isNew = params.type === 'new';
|
||||
const { type } = params;
|
||||
const isNewURI = type === LISTING_PAGE_PARAM_TYPE_NEW;
|
||||
const isDraftURI = type === LISTING_PAGE_PARAM_TYPE_DRAFT;
|
||||
const isNewListingFlow = isNewURI || isDraftURI;
|
||||
|
||||
const currentListing = ensureListing(listing);
|
||||
const imageIds = images => {
|
||||
return images ? images.map(img => img.imageId || img.id) : null;
|
||||
};
|
||||
|
||||
const onCompleteEditListingWizardTab = (tab, updateValues) => {
|
||||
if (isNew) {
|
||||
const onUpsertListingDraft =
|
||||
tab !== marketplaceTabs[0] ? onUpdateListingDraft : onCreateListingDraft;
|
||||
onUpsertListingDraft(updateValues);
|
||||
// Normalize images for API call
|
||||
const { images: updatedImages, ...otherValues } = updateValues;
|
||||
const imageProperty =
|
||||
typeof updatedImages !== 'undefined' ? { images: imageIds(updatedImages) } : {};
|
||||
const updateValuesWithImages = { ...otherValues, ...imageProperty };
|
||||
|
||||
if (tab !== marketplaceTabs[marketplaceTabs.length - 1]) {
|
||||
// Create listing flow: smooth scrolling polyfill to scroll to correct tab
|
||||
handleCreateFlowTabScrolling(false);
|
||||
// Redirect to next tab
|
||||
const pathParams = pathParamsToNextTab(params, tab, marketplaceTabs);
|
||||
history.push(
|
||||
createResourceLocatorString('EditListingPage', routeConfiguration(), pathParams, {})
|
||||
);
|
||||
} else {
|
||||
// Normalize images for API call
|
||||
const imageIdArray = imageIds(updateValues.images);
|
||||
handleCreateListing({ ...listing.attributes, images: imageIdArray });
|
||||
}
|
||||
if (isNewListingFlow) {
|
||||
const onUpsertListingDraft = isNewURI
|
||||
? (tab, updateValues) => onCreateListingDraft(updateValues)
|
||||
: onUpdateListing;
|
||||
|
||||
const upsertValues = isNewURI
|
||||
? updateValuesWithImages
|
||||
: { ...updateValuesWithImages, id: currentListing.id };
|
||||
|
||||
onUpsertListingDraft(tab, upsertValues)
|
||||
.then(r => {
|
||||
if (tab !== marketplaceTabs[marketplaceTabs.length - 1]) {
|
||||
// Create listing flow: smooth scrolling polyfill to scroll to correct tab
|
||||
handleCreateFlowTabScrolling(false);
|
||||
|
||||
// After successful saving of draft data, user should be redirected to next tab
|
||||
redirectAfterDraftUpdate(r.data.data.id.uuid, params, tab, marketplaceTabs, history);
|
||||
} else {
|
||||
handlePublishListing(currentListing.id);
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
// No need for extra actions
|
||||
});
|
||||
} else {
|
||||
const { images: updatedImages, ...rest } = updateValues;
|
||||
// Normalize images for API call
|
||||
const imageProperty =
|
||||
typeof updatedImages !== 'undefined' ? { images: imageIds(updatedImages) } : {};
|
||||
onUpdateListing(tab, { ...rest, id: currentListing.id, ...imageProperty });
|
||||
onUpdateListing(tab, { ...updateValuesWithImages, id: currentListing.id });
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -106,7 +144,7 @@ const EditListingWizardTab = props => {
|
|||
|
||||
switch (tab) {
|
||||
case DESCRIPTION: {
|
||||
const submitButtonTranslationKey = isNew
|
||||
const submitButtonTranslationKey = isNewListingFlow
|
||||
? 'EditListingWizard.saveNewDescription'
|
||||
: 'EditListingWizard.saveEditDescription';
|
||||
return (
|
||||
|
|
@ -120,7 +158,7 @@ const EditListingWizardTab = props => {
|
|||
);
|
||||
}
|
||||
case FEATURES: {
|
||||
const submitButtonTranslationKey = isNew
|
||||
const submitButtonTranslationKey = isNewListingFlow
|
||||
? 'EditListingWizard.saveNewFeatures'
|
||||
: 'EditListingWizard.saveEditFeatures';
|
||||
return (
|
||||
|
|
@ -134,7 +172,7 @@ const EditListingWizardTab = props => {
|
|||
);
|
||||
}
|
||||
case POLICY: {
|
||||
const submitButtonTranslationKey = isNew
|
||||
const submitButtonTranslationKey = isNewListingFlow
|
||||
? 'EditListingWizard.saveNewPolicies'
|
||||
: 'EditListingWizard.saveEditPolicies';
|
||||
return (
|
||||
|
|
@ -148,7 +186,7 @@ const EditListingWizardTab = props => {
|
|||
);
|
||||
}
|
||||
case LOCATION: {
|
||||
const submitButtonTranslationKey = isNew
|
||||
const submitButtonTranslationKey = isNewListingFlow
|
||||
? 'EditListingWizard.saveNewLocation'
|
||||
: 'EditListingWizard.saveEditLocation';
|
||||
return (
|
||||
|
|
@ -162,7 +200,7 @@ const EditListingWizardTab = props => {
|
|||
);
|
||||
}
|
||||
case PRICING: {
|
||||
const submitButtonTranslationKey = isNew
|
||||
const submitButtonTranslationKey = isNewListingFlow
|
||||
? 'EditListingWizard.saveNewPricing'
|
||||
: 'EditListingWizard.saveEditPricing';
|
||||
return (
|
||||
|
|
@ -176,16 +214,16 @@ const EditListingWizardTab = props => {
|
|||
);
|
||||
}
|
||||
case PHOTOS: {
|
||||
const submitButtonTranslationKey = isNew
|
||||
const submitButtonTranslationKey = isNewListingFlow
|
||||
? 'EditListingWizard.saveNewPhotos'
|
||||
: 'EditListingWizard.saveEditPhotos';
|
||||
|
||||
// newListingCreated and fetchInProgress are flags for the last wizard tab
|
||||
// newListingPublished and fetchInProgress are flags for the last wizard tab
|
||||
return (
|
||||
<EditListingPhotosPanel
|
||||
{...panelProps(PHOTOS)}
|
||||
submitButtonText={intl.formatMessage({ id: submitButtonTranslationKey })}
|
||||
newListingCreated={newListingCreated}
|
||||
newListingPublished={newListingPublished}
|
||||
fetchInProgress={fetchInProgress}
|
||||
images={images}
|
||||
onImageUpload={onImageUpload}
|
||||
|
|
@ -203,7 +241,6 @@ const EditListingWizardTab = props => {
|
|||
};
|
||||
|
||||
EditListingWizardTab.defaultProps = {
|
||||
errors: null,
|
||||
listing: null,
|
||||
updatedTab: null,
|
||||
};
|
||||
|
|
@ -214,19 +251,21 @@ EditListingWizardTab.propTypes = {
|
|||
params: shape({
|
||||
id: string.isRequired,
|
||||
slug: string.isRequired,
|
||||
type: oneOf(['new', 'edit']).isRequired,
|
||||
type: oneOf(LISTING_PAGE_PARAM_TYPES).isRequired,
|
||||
tab: oneOf(SUPPORTED_TABS).isRequired,
|
||||
}).isRequired,
|
||||
errors: shape({
|
||||
createListingsError: object,
|
||||
createListingDraftError: object,
|
||||
publishListingError: object,
|
||||
updateListingError: object,
|
||||
showListingsError: object,
|
||||
uploadImageError: object,
|
||||
}).isRequired,
|
||||
fetchInProgress: bool.isRequired,
|
||||
newListingCreated: bool.isRequired,
|
||||
newListingPublished: bool.isRequired,
|
||||
history: shape({
|
||||
push: func.isRequired,
|
||||
replace: func.isRequired,
|
||||
}).isRequired,
|
||||
images: array.isRequired,
|
||||
|
||||
|
|
@ -243,13 +282,12 @@ EditListingWizardTab.propTypes = {
|
|||
}),
|
||||
|
||||
handleCreateFlowTabScrolling: func.isRequired,
|
||||
handleCreateListing: func.isRequired,
|
||||
handlePublishListing: func.isRequired,
|
||||
onUpdateListing: func.isRequired,
|
||||
onCreateListingDraft: func.isRequired,
|
||||
onImageUpload: func.isRequired,
|
||||
onUpdateImageOrder: func.isRequired,
|
||||
onRemoveImage: func.isRequired,
|
||||
onUpdateListingDraft: func.isRequired,
|
||||
onChange: func.isRequired,
|
||||
updatedTab: string,
|
||||
updateInProgress: bool.isRequired,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue