Merge pull request #602 from sharetribe/enquiry-in-transactionpanel

Enquiry in transactionpanel
This commit is contained in:
Vesa Luusua 2017-12-19 14:47:22 +02:00 committed by GitHub
commit 666d4589cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 111 additions and 127 deletions

View file

@ -21,6 +21,7 @@
&:hover {
border-bottom: 4px solid var(--marketplaceColor);
border-radius: 0;
text-decoration: none;
}
}

View file

@ -152,7 +152,7 @@
}
}
.desktopAside {
.asideDesktop {
margin: 1px 0 0 0;
@media (--viewportLarge) {
@ -162,7 +162,7 @@
}
}
.breakdownDesktop {
.detailCard {
display: none;
position: sticky;
@ -177,24 +177,25 @@
}
}
.breakdownImageWrapper {
.detailCardImageWrapper {
/* Layout */
display: block;
width: 100%;
position: relative;
}
.breakdownHeadings {
.detailCardHeadings {
display: none;
@media (--viewportLarge) {
display: block;
margin-left: 48px;
margin-right: 48px;
margin-bottom: 37px;
}
}
.breakdownTitle {
.detailCardTitle {
margin-bottom: 10px;
@media (--viewportLarge) {
@ -203,7 +204,7 @@
}
}
.breakdownSubtitle {
.detailCardSubtitle {
@apply --marketplaceH5FontStyles;
color: var(--matterColorAnti);
@ -300,6 +301,12 @@
}
}
.requestToBookButton {
@apply --marketplaceButtonStylesPrimary;
text-decoration: none;
}
.actionButtons {
/* Position action button row above the footer */
z-index: 9;

View file

@ -92,9 +92,37 @@ export const BreakdownMaybe = props => {
) : null;
};
// Functional component as a helper to build ActionButtons
// Provider only when state is preauthorized
export const ActionButtonsMaybe = props => {
const createListingLink = (listing, label, listingPageName = 'ListingPage', className = '') => {
const listingLoaded = !!listing.id;
if (listingLoaded && !listing.attributes.deleted) {
const title = listing.attributes.title;
const params = { id: listing.id.uuid, slug: createSlug(title) };
return (
<NamedLink className={className} name={listingPageName} params={params}>
{label}
</NamedLink>
);
} else {
return <FormattedMessage id="TransactionPanel.deletedListingOrderTitle" />;
}
};
// Functional component as a helper to build ActionButtons for
// provider when state is preauthorized
export const OrderActionButtonMaybe = props => {
const { className, rootClassName, canShowButtons, listing } = props;
const title = <FormattedMessage id="TransactionPanel.requestToBook" />;
const listingLink = createListingLink(listing, title, 'ListingPageBook', css.requestToBookButton);
const classes = classNames(rootClassName || css.actionButtons, className);
return canShowButtons ? <div className={classes}>{listingLink}</div> : null;
};
// Functional component as a helper to build ActionButtons for
// provider when state is preauthorized
export const SaleActionButtonsMaybe = props => {
const {
className,
rootClassName,
@ -149,19 +177,6 @@ export const ActionButtonsMaybe = props => {
) : null;
};
const createListingLink = (listingLoaded, title, id) => {
if (listingLoaded && title) {
const params = { id: id.uuid, slug: createSlug(title) };
return (
<NamedLink name="ListingPage" params={params}>
{title}
</NamedLink>
);
} else {
return <FormattedMessage id="TransactionPanel.deletedListingOrderTitle" />;
}
};
// Functional component as a helper to build order title
export const OrderTitle = props => {
const {
@ -172,12 +187,19 @@ export const OrderTitle = props => {
currentListing,
listingTitle,
} = props;
const listingLoaded = !!currentListing.id;
const listingLink = createListingLink(listingLoaded, listingTitle, currentListing.id);
const listingLink = createListingLink(currentListing, listingTitle);
const classes = classNames(rootClassName || css.headingOrder, className);
if (propTypes.txIsPreauthorized(transaction)) {
if (propTypes.txIsEnquired(transaction)) {
return (
<h1 className={classes}>
<span className={css.mainTitle}>
<FormattedMessage id="TransactionPanel.orderEnquiredTitle" values={{ listingLink }} />
</span>
</h1>
);
} else if (propTypes.txIsPreauthorized(transaction)) {
return (
<h1 className={classes}>
<span className={css.mainTitle}>
@ -283,12 +305,20 @@ export const SaleTitle = props => {
currentListing,
listingTitle,
} = props;
const listingLoaded = !!currentListing.id;
const listingLink = createListingLink(listingLoaded, listingTitle, currentListing.id);
const listingLink = createListingLink(currentListing, listingTitle);
const classes = classNames(rootClassName || css.headingSale, className);
if (propTypes.txIsPreauthorized(transaction)) {
if (propTypes.txIsEnquired(transaction)) {
return (
<h1 className={classes}>
<FormattedMessage
id="TransactionPanel.saleEnquiredTitle"
values={{ customerName, listingLink }}
/>
</h1>
);
} else if (propTypes.txIsPreauthorized(transaction)) {
return (
<h1 className={classes}>
<FormattedMessage

View file

@ -10,9 +10,10 @@ import { SendMessageForm } from '../../containers';
// These are internal components that make this file more readable.
import {
ActionButtonsMaybe,
BreakdownMaybe,
FeedSection,
OrderActionButtonMaybe,
SaleActionButtonsMaybe,
TransactionPageTitle,
TransactionPageMessage,
displayNames,
@ -138,8 +139,12 @@ export class TransactionPanelComponent extends Component {
const listingDeleted = listingLoaded && currentListing.attributes.deleted;
const customerLoaded = !!currentCustomer.id;
const isCustomerBanned = customerLoaded && currentCustomer.attributes.banned;
const canShowButtons =
const canShowSaleButtons =
isProvider && propTypes.txIsPreauthorized(currentTransaction) && !isCustomerBanned;
const isProviderLoaded = !!currentProvider.id;
const isProviderBanned = isProviderLoaded && currentProvider.attributes.banned;
const canShowBookButton =
isCustomer && propTypes.txIsEnquired(currentTransaction) && !isProviderBanned;
const bannedUserDisplayName = intl.formatMessage({
id: 'TransactionPanel.bannedUserDisplayName',
@ -166,19 +171,32 @@ export class TransactionPanelComponent extends Component {
[css.actionButtonsWithFormFocused]: this.state.sendMessageFormFocused,
});
const actionButtons = (
<ActionButtonsMaybe
rootClassName={actionButtonClasses}
canShowButtons={canShowButtons}
transaction={currentTransaction}
acceptInProgress={acceptInProgress}
declineInProgress={declineInProgress}
acceptSaleError={acceptSaleError}
declineSaleError={declineSaleError}
onAcceptSale={onAcceptSale}
onDeclineSale={onDeclineSale}
/>
);
const canShowActionButtons = canShowBookButton || canShowSaleButtons;
let actionButtons = null;
if (canShowSaleButtons) {
actionButtons = (
<SaleActionButtonsMaybe
rootClassName={actionButtonClasses}
canShowButtons={canShowSaleButtons}
transaction={currentTransaction}
acceptInProgress={acceptInProgress}
declineInProgress={declineInProgress}
acceptSaleError={acceptSaleError}
declineSaleError={declineSaleError}
onAcceptSale={onAcceptSale}
onDeclineSale={onDeclineSale}
/>
);
} else if (canShowBookButton) {
actionButtons = (
<OrderActionButtonMaybe
rootClassName={actionButtonClasses}
canShowButtons={canShowBookButton}
listing={currentListing}
/>
);
}
const sendMessagePlaceholder = intl.formatMessage(
{ id: 'TransactionPanel.sendMessagePlaceholder' },
@ -186,7 +204,7 @@ export class TransactionPanelComponent extends Component {
);
const sendMessageFormClasses = classNames(css.sendMessageForm, {
[css.sendMessageFormFixed]: !canShowButtons || this.state.sendMessageFormFocused,
[css.sendMessageFormFixed]: !canShowActionButtons || this.state.sendMessageFormFocused,
[css.sendMessageFormFocusedInMobileSafari]:
this.isMobSaf && this.state.sendMessageFormFocused,
});
@ -244,9 +262,6 @@ export class TransactionPanelComponent extends Component {
/>
<div className={css.breakdownMobile}>
<h3 className={css.bookingBreakdownTitle}>
<FormattedMessage id="TransactionPanel.bookingBreakdownTitle" />
</h3>
<BreakdownMaybe transaction={currentTransaction} transactionRole={transactionRole} />
</div>
@ -274,14 +289,14 @@ export class TransactionPanelComponent extends Component {
onBlur={this.onSendMessageFormBlur}
onSubmit={this.onMessageSubmit}
/>
{isProvider && canShowButtons ? (
{canShowActionButtons ? (
<div className={css.mobileActionButtons}>{actionButtons}</div>
) : null}
</div>
<div className={css.desktopAside}>
<div className={css.breakdownDesktop}>
<div className={css.breakdownImageWrapper}>
<div className={css.asideDesktop}>
<div className={css.detailCard}>
<div className={css.detailCardImageWrapper}>
<div className={css.aspectWrapper}>
<ResponsiveImage
rootClassName={css.rootForImage}
@ -301,9 +316,9 @@ export class TransactionPanelComponent extends Component {
</div>
) : null}
{isCustomer ? (
<div className={css.breakdownHeadings}>
<h2 className={css.breakdownTitle}>{listingTitle}</h2>
<p className={css.breakdownSubtitle}>
<div className={css.detailCardHeadings}>
<h2 className={css.detailCardTitle}>{listingTitle}</h2>
<p className={css.detailCardSubtitle}>
<FormattedMessage
id="TransactionPanel.hostedBy"
values={{ name: authorDisplayName }}
@ -312,7 +327,7 @@ export class TransactionPanelComponent extends Component {
</div>
) : null}
<BreakdownMaybe transaction={currentTransaction} transactionRole={transactionRole} />
{isProvider && canShowButtons ? (
{canShowActionButtons ? (
<div className={css.desktopActionButtons}>{actionButtons}</div>
) : null}
</div>

View file

@ -322,12 +322,6 @@ exports[`TransactionPanel - Order accepted matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -1147,12 +1141,6 @@ exports[`TransactionPanel - Order autodeclined matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -1972,12 +1960,6 @@ exports[`TransactionPanel - Order canceled matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -2797,12 +2779,6 @@ exports[`TransactionPanel - Order declined matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -3622,12 +3598,6 @@ exports[`TransactionPanel - Order delivered matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -4447,12 +4417,6 @@ exports[`TransactionPanel - Order preauthorized matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -5241,12 +5205,6 @@ exports[`TransactionPanel - Sale accepted matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -5998,12 +5956,6 @@ exports[`TransactionPanel - Sale autodeclined matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -6755,12 +6707,6 @@ exports[`TransactionPanel - Sale canceled matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -7512,12 +7458,6 @@ exports[`TransactionPanel - Sale declined matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -8269,12 +8209,6 @@ exports[`TransactionPanel - Sale delivered matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {
@ -9026,12 +8960,6 @@ exports[`TransactionPanel - Sale preauthorized matches snapshot 1`] = `
}
/>
<div>
<h3>
<FormattedMessage
id="TransactionPanel.bookingBreakdownTitle"
values={Object {}}
/>
</h3>
<Component
transaction={
Object {

View file

@ -619,13 +619,16 @@
"TransactionPanel.orderCancelledTitle": "{customerName}, your booking for {listingLink} has been cancelled.",
"TransactionPanel.orderDeclinedTitle": "{customerName}, your booking for {listingLink} has been declined.",
"TransactionPanel.orderDeliveredTitle": "{customerName}, your booking for {listingLink} has been completed.",
"TransactionPanel.orderEnquiredTitle": "You enquired about {listingLink}",
"TransactionPanel.orderPreauthorizedInfo": "{providerName} has been notified about the booking request. Sit back and relax.",
"TransactionPanel.orderPreauthorizedSubtitle": "You have requested to book {listingLink}.",
"TransactionPanel.orderPreauthorizedTitle": "Great success, {customerName}!",
"TransactionPanel.requestToBook": "Request to book",
"TransactionPanel.saleAcceptedTitle": "You accepted a request from {customerName} to book {listingLink}.",
"TransactionPanel.saleCancelledTitle": "The booking from {customerName} for {listingLink} has been cancelled.",
"TransactionPanel.saleDeclinedTitle": "The request from {customerName} to book {listingLink} has been declined.",
"TransactionPanel.saleDeliveredTitle": "The booking from {customerName} for {listingLink} has been completed.",
"TransactionPanel.saleEnquiredTitle": "{customerName} enquired about {listingLink}",
"TransactionPanel.saleRequestedInfo": "{customerName} is waiting for your response.",
"TransactionPanel.saleRequestedTitle": "{customerName} has requested to book {listingLink}.",
"TransactionPanel.sendMessagePlaceholder": "Send a message to {name}…",