Skip to content

Commit

Permalink
Site Migration: Update Plans page for migrations flow (#97062)
Browse files Browse the repository at this point in the history
* Initial start at new plans page for migrations

* Update loader styles/markup

* Fix header styles

* Remove descriptions

* Fix spacing

* Refactor pricing

* Fix typing

* Fix checkout ctas, update wording for 2 year plan

* Simplify loader

* Simplify pricing output

* Tweak copy, remove unused function param

* Simplify rendering

* Add vars for repeated constants

* Revert changes to Skeleton

* Revert unnecessary name change

* Fix tabs

* Fix for loader display

* Simplify

* Prevent flash of uncentered loader

* Update language for consistency

* More specific typing, pass planSlugs through so we don't have to repeat

* Use feature flag being introduced in separate PR

* Use consistent variable

* Ensure we have planSlugs before reducer

* Update test

* Fix mobile spacing, update pricing copy

* Mobile refund text

* Fix flash of original skeleton

* Fix box shadow on secondary buttons

* Don't show storage

* Use styles to make first list item bold, tweaks to spacing

* No bold text for feature flag

* Add refund tooltip

* Account for border width

* Update spacing under header

* Fix title spacing

* Bold around days

* New strings for features

* Separate Jetpack and WPcom features

* Fix jetpack logo color

* Logo spacing

* Move so we can take full advantage of hooks in translate, add bold text

* Revert changes to plan feature list

* Remove unused prop

* Fix button colors

* Alignment issues

* Fix alignment issues

* Update loader colors to gray

* Calculate percentage rather than hard-coding, consolidate features
  • Loading branch information
sixhours authored Dec 11, 2024
1 parent 4886b4f commit f85d691
Show file tree
Hide file tree
Showing 12 changed files with 595 additions and 77 deletions.
69 changes: 50 additions & 19 deletions client/blocks/importer/wordpress/upgrade-plan/index.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
import { recordTracksEvent } from '@automattic/calypso-analytics';
import { isEnabled } from '@automattic/calypso-config';
import { getPlan, PLAN_BUSINESS } from '@automattic/calypso-products';
import {
getPlan,
PLAN_BUSINESS,
PLAN_BUSINESS_2_YEARS,
PLAN_BUSINESS_MONTHLY,
} from '@automattic/calypso-products';
import { Button } from '@automattic/components';
import { Plans } from '@automattic/data-stores';
import { useHasEnTranslation, useIsEnglishLocale } from '@automattic/i18n-utils';
import { Title, SubTitle, NextButton } from '@automattic/onboarding';
import { Icon, reusableBlock } from '@wordpress/icons';
import { useTranslate } from 'i18n-calypso';
import React, { useEffect } from 'react';
import useCheckEligibilityMigrationTrialPlan from 'calypso/data/plans/use-check-eligibility-migration-trial-plan';
import PlanNoticeCreditUpgrade from 'calypso/my-sites/plans-features-main/components/plan-notice-credit-update';
import useCheckPlanAvailabilityForPurchase from 'calypso/my-sites/plans-features-main/hooks/use-check-plan-availability-for-purchase';
import { useUpgradePlanHostingDetailsList } from './hooks/use-get-upgrade-plan-hosting-details-list';
import { Skeleton } from './skeleton';
import { VariantsSkeleton } from './skeleton/variants-skeleton';
import UpgradePlanDetails from './upgrade-plan-details';
import './style.scss';
import withMigrationSticker from './with-migration-sticker';
import type { UpgradePlanProps } from './types';
import type { PlanSlug } from '@automattic/calypso-products';
import type { PricingMetaForGridPlan } from '@automattic/data-stores';

export const UnwrappedUpgradePlan: React.FunctionComponent< UpgradePlanProps > = ( props ) => {
const translate = useTranslate();
const isEnglishLocale = useIsEnglishLocale();
const plan = getPlan( PLAN_BUSINESS );
const hasEnTranslation = useHasEnTranslation();
const {
site,
Expand All @@ -35,6 +43,7 @@ export const UnwrappedUpgradePlan: React.FunctionComponent< UpgradePlanProps > =
trackingEventsProps,
hideFreeMigrationTrialForNonVerifiedEmail = false,
visiblePlan = PLAN_BUSINESS,
showVariants = false,
} = props;
const { data: migrationTrialEligibility } = useCheckEligibilityMigrationTrialPlan( site.ID );
const isEligibleForTrialPlan =
Expand All @@ -44,26 +53,37 @@ export const UnwrappedUpgradePlan: React.FunctionComponent< UpgradePlanProps > =

const { list: upgradePlanHostingDetailsList, isFetching: isFetchingHostingDetails } =
useUpgradePlanHostingDetailsList();
const plan = getPlan( visiblePlan );

const planMonthly = PLAN_BUSINESS_MONTHLY;
const planBiennial = PLAN_BUSINESS_2_YEARS;

const planSlugs: PlanSlug[] = [ visiblePlan, planMonthly, planBiennial ];

const pricingMeta = Plans.usePricingMetaForGridPlans( {
coupon: undefined,
planSlugs: [ visiblePlan ],
planSlugs: planSlugs,
siteId: site.ID,
storageAddOns: null,
useCheckPlanAvailabilityForPurchase,
} );

const pricing =
pricingMeta && pricingMeta[ visiblePlan ] ? pricingMeta[ visiblePlan ] : undefined;
const pricing = planSlugs.reduce(
( acc, planSlug: string ) => {
acc[ planSlug ] = pricingMeta?.[ planSlug ];
return acc;
},
{} as Record< string, PricingMetaForGridPlan | undefined >
);

const introOfferAvailable =
isEnabled( 'migration-flow/introductory-offer' ) &&
pricing?.introOffer &&
pricing.introOffer.rawPrice &&
! pricing.introOffer.isOfferComplete &&
pricing.originalPrice.monthly &&
pricing.originalPrice.full &&
pricing.currencyCode;
pricing[ visiblePlan ]?.introOffer &&
pricing[ visiblePlan ]?.introOffer.rawPrice &&
! pricing[ visiblePlan ]?.introOffer.isOfferComplete &&
pricing[ visiblePlan ]?.originalPrice &&
pricing[ visiblePlan ]?.originalPrice.monthly &&
pricing[ visiblePlan ]?.originalPrice.full &&
pricing[ visiblePlan ]?.currencyCode;

const hideFreeMigrationTrial =
introOfferAvailable ||
Expand Down Expand Up @@ -104,7 +124,7 @@ export const UnwrappedUpgradePlan: React.FunctionComponent< UpgradePlanProps > =

if ( hideFreeMigrationTrial ) {
return (
<NextButton isBusy={ isBusy } onClick={ onCtaClick }>
<NextButton isBusy={ isBusy } onClick={ () => onCtaClick( visiblePlan ) }>
{ cta }
</NextButton>
);
Expand All @@ -114,7 +134,7 @@ export const UnwrappedUpgradePlan: React.FunctionComponent< UpgradePlanProps > =
return (
<>
<NextButton onClick={ onFreeTrialClick }>{ trialText }</NextButton>
<Button busy={ isBusy } transparent onClick={ onCtaClick }>
<Button busy={ isBusy } transparent onClick={ () => onCtaClick( visiblePlan ) }>
{ cta }
</Button>
</>
Expand All @@ -123,7 +143,7 @@ export const UnwrappedUpgradePlan: React.FunctionComponent< UpgradePlanProps > =

return (
<>
<NextButton isBusy={ isBusy } onClick={ onCtaClick }>
<NextButton isBusy={ isBusy } onClick={ () => onCtaClick( visiblePlan ) }>
{ cta }
</NextButton>
<Button disabled transparent>
Expand Down Expand Up @@ -154,8 +174,11 @@ export const UnwrappedUpgradePlan: React.FunctionComponent< UpgradePlanProps > =
'Migrations are exclusive to the Creator plan. Check out all its benefits, and upgrade to get started.'
);

if ( isFetchingHostingDetails || ! pricing ) {
return <Skeleton />;
if ( isFetchingHostingDetails || ! pricing[ visiblePlan ] ) {
if ( ! showVariants ) {
return <Skeleton />;
}
return <VariantsSkeleton />;
}

return (
Expand Down Expand Up @@ -194,14 +217,22 @@ export const UnwrappedUpgradePlan: React.FunctionComponent< UpgradePlanProps > =
) }

<PlanNoticeCreditUpgrade siteId={ site.ID } visiblePlans={ [ visiblePlan ] } />

<UpgradePlanDetails
pricing={ pricing }
planSlugs={ planSlugs }
pricing={ pricing as { [ key: string ]: PricingMetaForGridPlan } }
introOfferAvailable={ !! introOfferAvailable }
upgradePlanHostingDetailsList={ upgradePlanHostingDetailsList }
showVariants={ showVariants }
onCtaClick={ onCtaClick }
>
{ renderCTAs() }
</UpgradePlanDetails>
{ showVariants && (
<div className="import__upgrade-plan-refund-sub-text">
<Icon icon={ reusableBlock } />
{ translate( 'Fully refundable. No questions asked.' ) }
</div>
) }
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import type { FC } from 'react';
import './style.scss';

export const VariantsSkeleton: FC = () => {
const variantSkeleton = (
<div className="import__upgrade-plan-container">
<div className="import__upgrade-plan-features-container">
<div
className="import-upgrade-plan-skeleton import-upgrade-plan-skeleton--dark-gray"
style={ { width: '173px', height: '32px', marginBottom: '20px' } }
/>
<div className="import-upgrade-plan-skeleton" style={ { width: '277px' } } />
<div
className="import-upgrade-plan-skeleton"
style={ { width: '195px', marginBottom: '40px' } }
/>
<div
className="import-upgrade-plan-skeleton import-upgrade-plan-skeleton--dark-gray"
style={ { width: '173px', height: '32px' } }
/>
<div
className="import-upgrade-plan-skeleton"
style={ { width: '103px', marginBottom: '40px' } }
/>
<div
className="import-upgrade-plan-skeleton import-upgrade-plan-skeleton--dark-highlight"
style={ { width: '305px', height: '32px', borderRadius: '4px' } }
/>
<div
className="import-upgrade-plan-skeleton import-upgrade-plan-skeleton--dark-highlight"
style={ { width: '103px', margin: '0 auto' } }
/>
</div>
</div>
);
return (
<div className="import__upgrade-plan">
<div className="import__upgrade-plan-details import__upgrade-plan-details--loading">
{ variantSkeleton }
{ variantSkeleton }
{ variantSkeleton }
</div>
</div>
);
};
6 changes: 6 additions & 0 deletions client/blocks/importer/wordpress/upgrade-plan/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,12 @@ $business-plan-color: #7f54b3;

ul {
margin: 0;

li {
&:first-child {
font-weight: bold;
}
}
}

.import__upgrade-plan-feature.logo {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* @jest-environment jsdom
*/
import { PLAN_BUSINESS } from '@automattic/calypso-products';
import { type PricingMetaForGridPlan } from '@automattic/data-stores';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { screen, waitFor } from '@testing-library/react';
Expand Down Expand Up @@ -54,7 +55,8 @@ describe( 'UpgradePlanDetails', () => {

it( 'should show the pricing description for the introductory offer when the intro offer is avaiable', async () => {
renderUpgradePlanDetailsComponent( {
pricing: getPricing(),
planSlugs: [ PLAN_BUSINESS ],
pricing: { [ PLAN_BUSINESS ]: getPricing() },
introOfferAvailable: true,
children: 'Content',
upgradePlanHostingDetailsList: [],
Expand Down Expand Up @@ -83,7 +85,8 @@ describe( 'UpgradePlanDetails', () => {

it( 'should show the standard pricing offer description when the introductory offer is not avaiable', async () => {
renderUpgradePlanDetailsComponent( {
pricing: getPricing(),
planSlugs: [ PLAN_BUSINESS ],
pricing: { [ PLAN_BUSINESS ]: getPricing() },
introOfferAvailable: false,
children: 'Content',
upgradePlanHostingDetailsList: [],
Expand Down
8 changes: 6 additions & 2 deletions client/blocks/importer/wordpress/upgrade-plan/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ export type HostingDetails = {
export type UpgradePlanDetailsProps = {
children: React.ReactNode;
introOfferAvailable: boolean;
pricing?: PricingMetaForGridPlan;
pricing?: { [ key: string ]: PricingMetaForGridPlan };
upgradePlanHostingDetailsList: Array< HostingDetailsItem >;
showVariants?: boolean;
onCtaClick?: ( planSlug: PlanSlug ) => void;
planSlugs: Array< PlanSlug >;
};

export type UpgradePlanProps = {
Expand All @@ -27,9 +30,10 @@ export type UpgradePlanProps = {
hideTitleAndSubTitle?: boolean;
onFreeTrialClick?: () => void;
navigateToVerifyEmailStep: () => void;
onCtaClick: () => void;
onCtaClick: ( planSlug: PlanSlug ) => void;
onContentOnlyClick?: () => void;
trackingEventsProps?: Record< string, unknown >;
hideFreeMigrationTrialForNonVerifiedEmail?: boolean;
showVariants?: boolean;
visiblePlan?: PlanSlug;
};
Loading

0 comments on commit f85d691

Please sign in to comment.