Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Checkout Plan Upsell: Improve UX by adding a "Plan" column heading #92727

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -206,16 +206,14 @@ export function CheckoutSidebarPlanUpsell() {
<>
<PromoCard title={ cardTitle } className="checkout-sidebar-plan-upsell">
<div className="checkout-sidebar-plan-upsell__plan-grid">
{ isComparisonWithIntroOffer && (
<>
<div className="checkout-sidebar-plan-upsell__plan-grid-cell"></div>
<div className="checkout-sidebar-plan-upsell__plan-grid-cell">
<strong>{ cellLabel }</strong>
</div>
</>
) }
<div className="checkout-sidebar-plan-upsell__plan-grid-cell">
{ currentVariant.variantLabel }
<strong>{ __( 'Plan' ) }</strong>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we want to consider something that indicates it is the billing term, or, 'plan length'?

"Plan" is usually used to describe the feature set of the subscription whereas billing term is often used to indicate how many units of time until expiration of the plan. So in this case, 'billing term' or some variant of that would likely be more accurate as a header.

</div>
<div className="checkout-sidebar-plan-upsell__plan-grid-cell">
<strong>{ isComparisonWithIntroOffer ? cellLabel : __( 'Cost' ) }</strong>
</div>
<div className="checkout-sidebar-plan-upsell__plan-grid-cell">
{ currentVariant.variantLabel.adjective }
</div>
<div className="checkout-sidebar-plan-upsell__plan-grid-cell">
{ formatCurrency(
Expand All @@ -229,7 +227,7 @@ export function CheckoutSidebarPlanUpsell() {
) }
</div>
<div className="checkout-sidebar-plan-upsell__plan-grid-cell">
{ upsellVariant.variantLabel }
{ upsellVariant.variantLabel.adjective }
</div>
<div className="checkout-sidebar-plan-upsell__plan-grid-cell">
{ compareToPriceForVariantTerm && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ function ItemVariantOptionList( {
<OptionList role="listbox" tabIndex={ -1 }>
{ variants.map( ( variant, index ) => (
<ItemVariantOption
key={ variant.productSlug + variant.variantLabel }
key={ variant.productSlug + variant.variantLabel.noun }
isSelected={ index === highlightedVariantIndex }
onSelect={ () =>
handleChange(
Expand Down Expand Up @@ -219,7 +219,7 @@ function ItemVariantOption( {
<Option
id={ productId.toString() }
className={ isSelected ? 'item-variant-option--selected' : undefined }
aria-label={ variantLabel }
aria-label={ variantLabel.noun }
data-product-slug={ productSlug }
role="option"
onClick={ onSelect }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const JetpackItemVariantDropDownPrice: FunctionComponent< {
return (
<Variant>
<Label>
{ variant.variantLabel }
{ variant.variantLabel.noun }
{ isMobile && discountInteger > 0 && (
<JetpackDiscountDisplay
finalPriceInteger={ variant.priceInteger }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ import type { ResponseCartProduct } from '@automattic/shopping-cart';

export type WPCOMProductSlug = string;

export type WPCOMProductVariantLabel = {
noun: string;
adjective: string;
};

export type WPCOMProductVariant = {
priceInteger: number;
termIntervalInMonths: number;
termIntervalInDays: number;
currency: string;
productId: number;
productSlug: WPCOMProductSlug;
variantLabel: string;
variantLabel: WPCOMProductVariantLabel;
introductoryTerm: string;
introductoryInterval: number;
priceBeforeDiscounts: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export const ItemVariantDropDownPrice: FunctionComponent< {
return (
<Variant>
<Label>
{ variant.variantLabel }
{ variant.variantLabel.noun }
{ hasDiscount && isMobile && <DiscountPercentage percent={ discountPercentage } /> }
</Label>
<PriceTextContainer>
Expand Down
79 changes: 66 additions & 13 deletions client/my-sites/checkout/src/hooks/product-variants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ export function useGetProductVariants(
const term = getBillingTermForMonths( variant.bill_period_in_months );
const introductoryTerms = variant.introductory_offer_terms;
return {
variantLabel: getTermText( term, translate ),
variantLabel: {
noun: getTermText( term, translate, 'noun' ),
adjective: getTermText( term, translate, 'adjective' ),
},
productSlug: variant.product_slug,
productId: variant.product_id,
priceInteger: variant.price_integer,
Expand Down Expand Up @@ -143,43 +146,93 @@ function sortVariant( a: ResponseCartProductVariant, b: ResponseCartProductVaria
return 0;
}

function getTermText( term: string, translate: ReturnType< typeof useTranslate > ): string {
function getTermText(
term: string,
translate: ReturnType< typeof useTranslate >,
type: 'noun' | 'adjective' = 'noun'
): string {
const asAdjective = type === 'adjective';

switch ( term ) {
case TERM_CENTENNIALLY:
return String( translate( 'Hundred years' ) );

case TERM_DECENNIALLY:
return String( translate( 'Ten years' ) );
return String(
asAdjective
? translate( 'Ten-year', { context: 'adjective' } )
: translate( 'Ten years', { context: 'noun' } )
);

case TERM_NOVENNIALLY:
return String( translate( 'Nine years' ) );
return String(
asAdjective
? translate( 'Nine-year', { context: 'adjective' } )
: translate( 'Nine years', { context: 'noun' } )
);

case TERM_OCTENNIALLY:
return String( translate( 'Eight years' ) );
return String(
asAdjective
? translate( 'Eight-year', { context: 'adjective' } )
: translate( 'Eight years', { context: 'noun' } )
);

case TERM_SEPTENNIALLY:
return String( translate( 'Seven years' ) );
return String(
asAdjective
? translate( 'Seven-year', { context: 'adjective' } )
: translate( 'Seven years', { context: 'noun' } )
);

case TERM_SEXENNIALLY:
return String( translate( 'Six years' ) );
return String(
asAdjective
? translate( 'Six-year', { context: 'adjective' } )
: translate( 'Six years', { context: 'noun' } )
);

case TERM_QUINQUENNIALLY:
return String( translate( 'Five years' ) );
return String(
asAdjective
? translate( 'Five-year', { context: 'adjective' } )
: translate( 'Five years', { context: 'noun' } )
);

case TERM_QUADRENNIALLY:
return String( translate( 'Four years' ) );
return String(
asAdjective
? translate( 'Four-year', { context: 'adjective' } )
: translate( 'Four years', { context: 'noun' } )
);

case TERM_TRIENNIALLY:
return String( translate( 'Three years' ) );
return String(
asAdjective
? translate( 'Three-year', { context: 'adjective' } )
: translate( 'Three years', { context: 'noun' } )
);

case TERM_BIENNIALLY:
return String( translate( 'Two years' ) );
return String(
asAdjective
? translate( 'Two-year', { context: 'adjective' } )
: translate( 'Two years', { context: 'noun' } )
);

case TERM_ANNUALLY:
return String( translate( 'One year' ) );
return String(
asAdjective
? translate( 'One-year', { context: 'adjective' } )
: translate( 'One year', { context: 'noun' } )
);

case TERM_MONTHLY:
return String( translate( 'One month' ) );
return String(
asAdjective
? translate( 'One-month', { context: 'adjective' } )
: translate( 'One month', { context: 'noun' } )
);

default:
return '';
Expand Down
Loading