Skip to content
Merged
Binary file added client/assets/images/cancellation/built-by.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/assets/images/cancellation/free-month.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added client/assets/images/cancellation/live-chat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ export const CANCELLATION_REASONS: CancellationReason[] = [
return translate( 'Couldn’t find what I wanted.' );
},
},
{
value: 'tooComplicated',
get label() {
return translate( 'It’s too complicated for me.' );
},
},
],
},
{
Expand Down Expand Up @@ -355,3 +361,23 @@ export function getExtraJetpackReasons(
},
];
}

export function getReasonLabelByValue( value: string ) {
for ( const first of CANCELLATION_REASONS ) {
if ( first.value === value ) {
return first.label;
}

if ( ! first.selectOptions ) {
continue;
}

for ( const second of first.selectOptions ) {
if ( second.value === value ) {
return second.label;
}
}
}

return 'Unknown';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import {
isWpComMonthlyPlan,
isWpComBusinessPlan,
isWpComPremiumPlan,
isWpComAnnualPlan,
isWpComBiennialPlan,
isWpComEcommercePlan,
} from '@automattic/calypso-products';

type UpsellOptions = {
productSlug: string;
canRefund: boolean;
canDowngrade: boolean;
canOfferFreeMonth: boolean;
};

export type UpsellType =
| ''
| 'downgrade-monthly'
| 'downgrade-personal'
| 'free-month-offer'
| 'built-by'
| 'live-chat:plans'
| 'live-chat:plugins'
| 'live-chat:themes'
| 'live-chat:domains'
| 'upgrade-atomic';

/**
* Get a relevant upsell nudge for the chosen reason if exists.
*
* @param {string} reason The chosen reason for cancellation
* @param {UpsellOptions} opts The options for the upsell nudge
* @returns {UpsellType} The upsell nudge type
*/
export function getUpsellType( reason: string, opts: UpsellOptions ): UpsellType {
const { productSlug, canRefund, canDowngrade, canOfferFreeMonth } = opts;

if ( ! productSlug ) {
return '';
}

switch ( reason ) {
case 'tooExpensive':
case 'wantCheaperPlan':
if ( ! canDowngrade ) {
return '';
}

if (
canRefund &&
( isWpComAnnualPlan( productSlug ) || isWpComBiennialPlan( productSlug ) )
) {
return 'downgrade-monthly';
}

if ( isWpComPremiumPlan( productSlug ) && isWpComMonthlyPlan( productSlug ) ) {
return 'downgrade-personal';
}
break;

case 'noTime':
case 'siteIsNotReady':
if ( isWpComMonthlyPlan( productSlug ) && canOfferFreeMonth ) {
return 'free-month-offer';
}
return 'built-by';

case 'needProfessionalHelp':
case 'tooComplicated':
case 'customization':
return 'built-by';

case 'eCommerceFeatures':
return 'live-chat:plugins';

case 'cannotFindWhatIWanted':
case 'otherFeatures':
return 'live-chat:plans';

case 'cannotUsePlugin':
case 'cannotUseTheme':
if ( isWpComBusinessPlan( productSlug ) || isWpComEcommercePlan( productSlug ) ) {
return reason === 'cannotUsePlugin' ? 'live-chat:plugins' : 'live-chat:themes';
}
return 'upgrade-atomic';

case 'didNotGetFreeDomain':
case 'otherDomainIssues':
case 'domainConnection':
return 'live-chat:domains';
}

return '';
}
101 changes: 24 additions & 77 deletions client/components/marketing-survey/cancel-purchase-form/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,6 @@ import {
isGSuiteOrGoogleWorkspace,
isPlan,
isWpComMonthlyPlan,
isWpComBusinessPlan,
isWpComPersonalPlan,
isWpComPremiumPlan,
planMatches,
TERM_ANNUALLY,
TERM_BIENNIALLY,
GROUP_WPCOM,
} from '@automattic/calypso-products';
import { WPCOM_FEATURES_BACKUPS } from '@automattic/calypso-products/src';
import { getCurrencyDefaults } from '@automattic/format-currency';
Expand Down Expand Up @@ -46,6 +39,7 @@ import siteHasFeature from 'calypso/state/selectors/site-has-feature';
import getSite from 'calypso/state/sites/selectors/get-site';
import { CANCEL_FLOW_TYPE } from './constants';
import enrichedSurveyData from './enriched-survey-data';
import { getUpsellType } from './get-upsell-type';
import initialSurveyState from './initial-survey-state';
import nextStep from './next-step';
import {
Expand Down Expand Up @@ -84,7 +78,7 @@ class CancelPurchaseForm extends Component {
if ( ! isPlan( this.props.purchase ) ) {
steps = [ NEXT_ADVENTURE_STEP ];
} else if ( this.state.upsell ) {
steps = [ FEEDBACK_STEP, UPSELL_STEP ];
steps = [ FEEDBACK_STEP, UPSELL_STEP, NEXT_ADVENTURE_STEP ];
} else if ( this.state.questionTwoOrder.length ) {
steps = [ FEEDBACK_STEP, NEXT_ADVENTURE_STEP ];
}
Expand Down Expand Up @@ -134,62 +128,6 @@ class CancelPurchaseForm extends Component {
};
}

/**
* Get a related upsell nudge for the chosen reason.
*
* @param {string} reason Selected cancellation reason
* @returns {string} Upsell type
*/
getUpsellType( reason ) {
const { purchase, downgradeClick, freeMonthOfferClick } = this.props;
const productSlug = purchase?.productSlug || '';

if ( ! productSlug ) {
return '';
}

const canRefund = !! parseFloat( this.getRefundAmount() );

if (
[ 'cannotUsePlugin', 'cannotUseTheme' ].includes( reason ) &&
isWpComBusinessPlan( productSlug )
) {
return 'business-atomic';
}

if (
[ 'cannotUsePlugin', 'cannotUseTheme' ].includes( reason ) &&
( isWpComPremiumPlan( productSlug ) || isWpComPersonalPlan( productSlug ) )
) {
return 'upgrade-atomic';
}

if ( [ 'tooExpensive', 'wantCheaperPlan' ].includes( reason ) && !! downgradeClick ) {
if ( isWpComPremiumPlan( productSlug ) ) {
return 'downgrade-personal';
}

if (
canRefund &&
( planMatches( productSlug, { term: TERM_ANNUALLY, group: GROUP_WPCOM } ) ||
planMatches( productSlug, { term: TERM_BIENNIALLY, group: GROUP_WPCOM } ) )
) {
return 'downgrade-monthly';
}
}

if (
[ 'noTime', 'siteIsNotReady' ].includes( reason ) &&
isWpComMonthlyPlan( productSlug ) &&
!! freeMonthOfferClick &&
! this.state.purchaseIsAlreadyExtended
) {
return 'free-month-offer';
}

return '';
}

recordEvent = ( name, properties = {} ) => {
const { purchase, flowType, isAtomicSite } = this.props;

Expand Down Expand Up @@ -223,10 +161,17 @@ class CancelPurchaseForm extends Component {

onTextOneChange = ( eventOrValue ) => {
const value = eventOrValue?.currentTarget?.value ?? eventOrValue;
const { purchaseIsAlreadyExtended } = this.state;
const newState = {
...this.state,
questionOneText: value,
upsell: this.getUpsellType( value ) || '',
upsell:
getUpsellType( value, {
productSlug: this.props.purchase?.productSlug || '',
canRefund: !! parseFloat( this.getRefundAmount() ),
canDowngrade: !! this.props.downgradeClick,
canOfferFreeMonth: !! this.props.freeMonthOfferClick && ! purchaseIsAlreadyExtended,
} ) || '',
};
this.setState( newState );
};
Expand Down Expand Up @@ -382,16 +327,25 @@ class CancelPurchaseForm extends Component {
}

if ( surveyStep === UPSELL_STEP ) {
const allSteps = this.getAllSurveySteps();
const isLastStep = surveyStep === allSteps[ allSteps.length - 1 ];

return (
<UpsellStep
upsell={ this.state.upsell }
cancellationReason={ this.state.questionOneText }
purchase={ purchase }
site={ site }
upsell={ this.state.upsell }
disabled={ this.state.isSubmitting }
refundAmount={ this.getRefundAmount() }
downgradePlanPrice={ this.props.downgradePlanPrice }
downgradeClick={ this.downgradeClick }
closeDialog={ this.closeDialog }
cancelBundledDomain={ this.props.cancelBundledDomain }
includedDomainPurchase={ this.props.includedDomainPurchase }
onDeclineUpsell={ isLastStep ? this.onSubmit : this.clickNext }
onClickDowngrade={ this.downgradeClick }
onClickFreeMonthOffer={ this.freeMonthOfferClick }
/>
);
}
Expand Down Expand Up @@ -581,6 +535,10 @@ class CancelPurchaseForm extends Component {
const allSteps = this.getAllSurveySteps();
const isLastStep = surveyStep === allSteps[ allSteps.length - 1 ];

if ( surveyStep === UPSELL_STEP ) {
return null;
}

if ( ! isLastStep ) {
return (
<GutenbergButton
Expand All @@ -606,17 +564,6 @@ class CancelPurchaseForm extends Component {
>
{ this.getFinalActionText() }
</GutenbergButton>
{ surveyStep === UPSELL_STEP && (
<UpsellStep.Button
disabled={ isCancelling }
isBusy={ isSubmitting && solution }
siteSlug={ this.props.site.slug }
upsell={ this.state.upsell }
closeDialog={ this.closeDialog }
freeMonthOfferClick={ this.freeMonthOfferClick }
downgradeClick={ this.downgradeClick }
/>
) }
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,22 @@
right: 1rem;
font-size: inherit;

&.button {
display: none;
}

&.at-bottom {
display: inline-block;
font-size: 0;
}

@include break-small {
display: inline-block;
transform: translateY(-4px);

&.button {
display: inline-block;
}

&.at-bottom {
display: none;
}
Expand Down
Loading