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

Site Migration: Update Plans page for migrations flow #97062

Merged
merged 49 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3720d28
Initial start at new plans page for migrations
sixhours Dec 3, 2024
0be5072
Update loader styles/markup
sixhours Dec 4, 2024
f4819c7
Fix header styles
sixhours Dec 4, 2024
7b8ca9b
Remove descriptions
sixhours Dec 4, 2024
cbd0846
Fix spacing
sixhours Dec 4, 2024
2af1e3a
Refactor pricing
sixhours Dec 4, 2024
ea00343
Fix typing
sixhours Dec 4, 2024
e1d7348
Fix checkout ctas, update wording for 2 year plan
sixhours Dec 4, 2024
862cdd8
Simplify loader
sixhours Dec 4, 2024
a967266
Simplify pricing output
sixhours Dec 4, 2024
c4f074d
Tweak copy, remove unused function param
sixhours Dec 4, 2024
9f51fb0
Simplify rendering
sixhours Dec 4, 2024
08c29e9
Add vars for repeated constants
sixhours Dec 4, 2024
4bffcdc
Revert changes to Skeleton
sixhours Dec 4, 2024
efd3ab7
Revert unnecessary name change
sixhours Dec 4, 2024
1799b57
Fix tabs
sixhours Dec 4, 2024
b86ba5f
Fix for loader display
sixhours Dec 4, 2024
7faf794
Simplify
sixhours Dec 4, 2024
f8c9088
Prevent flash of uncentered loader
sixhours Dec 4, 2024
e7de03f
Update language for consistency
sixhours Dec 4, 2024
8f3f847
More specific typing, pass planSlugs through so we don't have to repeat
sixhours Dec 4, 2024
1266076
Use feature flag being introduced in separate PR
sixhours Dec 4, 2024
d8da194
Use consistent variable
sixhours Dec 4, 2024
25dbce6
Ensure we have planSlugs before reducer
sixhours Dec 4, 2024
43ee4c4
Update test
sixhours Dec 4, 2024
67cbc8f
Fix mobile spacing, update pricing copy
sixhours Dec 5, 2024
17bad2b
Mobile refund text
sixhours Dec 5, 2024
6a308ff
Fix flash of original skeleton
sixhours Dec 5, 2024
578824f
Fix box shadow on secondary buttons
sixhours Dec 5, 2024
17d3a35
Don't show storage
sixhours Dec 5, 2024
be5757e
Use styles to make first list item bold, tweaks to spacing
sixhours Dec 5, 2024
93579ac
No bold text for feature flag
sixhours Dec 5, 2024
872e05a
Add refund tooltip
sixhours Dec 5, 2024
b55a781
Account for border width
sixhours Dec 5, 2024
4d9b36c
Update spacing under header
sixhours Dec 5, 2024
7ffe981
Fix title spacing
sixhours Dec 5, 2024
1cf3132
Bold around days
sixhours Dec 5, 2024
d33fb0f
New strings for features
sixhours Dec 5, 2024
08c33bd
Separate Jetpack and WPcom features
sixhours Dec 5, 2024
c650646
Fix jetpack logo color
sixhours Dec 5, 2024
8c1c32f
Logo spacing
sixhours Dec 5, 2024
1f1bd56
Move so we can take full advantage of hooks in translate, add bold text
sixhours Dec 5, 2024
bd62be1
Revert changes to plan feature list
sixhours Dec 5, 2024
ea30faf
Remove unused prop
sixhours Dec 5, 2024
71a6156
Fix button colors
sixhours Dec 9, 2024
a65521c
Alignment issues
sixhours Dec 9, 2024
3fdf8cd
Fix alignment issues
sixhours Dec 9, 2024
184d049
Update loader colors to gray
sixhours Dec 9, 2024
6ef486d
Calculate percentage rather than hard-coding, consolidate features
sixhours Dec 10, 2024
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
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
Loading