import React from 'react';
import PropTypes from 'prop-types';
import { compose } from 'redux';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import classNames from 'classnames';
import { FormattedMessage, intlShape, injectIntl } from 'react-intl';
import { createResourceLocatorString, findRouteByRouteName } from '../../util/routes';
import routeConfiguration from '../../routeConfiguration';
import { propTypes } from '../../util/types';
import { ensureListing, ensureTransaction } from '../../util/data';
import { dateFromAPIToLocalNoon } from '../../util/dates';
import { createSlug } from '../../util/urlHelpers';
import { txIsPaymentPending } from '../../util/transaction';
import { getMarketplaceEntities } from '../../ducks/marketplaceData.duck';
import { isScrollingDisabled, manageDisableScrolling } from '../../ducks/UI.duck';
import { initializeCardPaymentData } from '../../ducks/stripe.duck.js';
import {
NamedRedirect,
TransactionPanel,
Page,
LayoutSingleColumn,
LayoutWrapperTopbar,
LayoutWrapperMain,
LayoutWrapperFooter,
Footer,
} from '../../components';
import { TopbarContainer } from '../../containers';
import {
acceptSale,
declineSale,
loadData,
setInitialValues,
sendMessage,
sendReview,
fetchMoreMessages,
} from './TransactionPage.duck';
import css from './TransactionPage.css';
const PROVIDER = 'provider';
const CUSTOMER = 'customer';
// TransactionPage handles data loading for Sale and Order views to transaction pages in Inbox.
export const TransactionPageComponent = props => {
const {
currentUser,
initialMessageFailedToTransaction,
fetchMessagesError,
fetchMessagesInProgress,
totalMessagePages,
oldestMessagePageFetched,
fetchTransactionError,
history,
intl,
messages,
onManageDisableScrolling,
onSendMessage,
onSendReview,
onShowMoreMessages,
params,
scrollingDisabled,
sendMessageError,
sendMessageInProgress,
sendReviewError,
sendReviewInProgress,
transaction,
transactionRole,
acceptInProgress,
acceptSaleError,
declineInProgress,
declineSaleError,
onAcceptSale,
onDeclineSale,
timeSlots,
fetchTimeSlotsError,
callSetInitialValues,
onInitializeCardPaymentData,
} = props;
const currentTransaction = ensureTransaction(transaction);
const currentListing = ensureListing(currentTransaction.listing);
const isProviderRole = transactionRole === PROVIDER;
const isCustomerRole = transactionRole === CUSTOMER;
const redirectToCheckoutPageWithInitialValues = (initialValues, listing) => {
const routes = routeConfiguration();
// Customize checkout page state with current listing and selected bookingDates
const { setInitialValues } = findRouteByRouteName('CheckoutPage', routes);
callSetInitialValues(setInitialValues, initialValues);
// Clear previous Stripe errors from store if there is any
onInitializeCardPaymentData();
// Redirect to CheckoutPage
history.push(
createResourceLocatorString(
'CheckoutPage',
routes,
{ id: currentListing.id.uuid, slug: createSlug(currentListing.attributes.title) },
{}
)
);
};
// If payment is pending, redirect to CheckoutPage
if (txIsPaymentPending(currentTransaction) && isCustomerRole) {
const currentBooking = ensureListing(currentTransaction.booking);
const initialValues = {
listing: currentListing,
// Transaction with payment pending should be passed to CheckoutPage
transaction: currentTransaction,
// Original bookingData content is not available,
// but it is already used since booking is created.
// (E.g. quantity is used when booking is created.)
bookingData: {},
bookingDates: {
bookingStart: dateFromAPIToLocalNoon(currentBooking.attributes.start),
bookingEnd: dateFromAPIToLocalNoon(currentBooking.attributes.end),
},
};
redirectToCheckoutPageWithInitialValues(initialValues, currentListing);
}
// Customer can create a booking, if the tx is in "enquiry" state.
const handleSubmitBookingRequest = values => {
const { bookingDates, ...bookingData } = values;
const initialValues = {
listing: currentListing,
// enquired transaction should be passed to CheckoutPage
transaction: currentTransaction,
bookingData,
bookingDates: {
bookingStart: bookingDates.startDate,
bookingEnd: bookingDates.endDate,
},
confirmPaymentError: null,
};
redirectToCheckoutPageWithInitialValues(initialValues, currentListing);
};
const deletedListingTitle = intl.formatMessage({
id: 'TransactionPage.deletedListing',
});
const listingTitle = currentListing.attributes.deleted
? deletedListingTitle
: currentListing.attributes.title;
// Redirect users with someone else's direct link to their own inbox/sales or inbox/orders page.
const isDataAvailable =
currentUser &&
currentTransaction.id &&
currentTransaction.id.uuid === params.id &&
currentTransaction.attributes.lineItems &&
currentTransaction.customer &&
currentTransaction.provider &&
!fetchTransactionError;
const isOwnSale =
isDataAvailable &&
isProviderRole &&
currentUser.id.uuid === currentTransaction.provider.id.uuid;
const isOwnOrder =
isDataAvailable &&
isCustomerRole &&
currentUser.id.uuid === currentTransaction.customer.id.uuid;
if (isDataAvailable && isProviderRole && !isOwnSale) {
// eslint-disable-next-line no-console
console.error('Tried to access a sale that was not owned by the current user');
return