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

Add upgrade section in Jetpack plans page #52381

Merged
merged 5 commits into from Apr 28, 2021

Conversation

monsieur-z
Copy link
Contributor

Changes proposed in this Pull Request

This PR adds an upgrade section to the plans page, when the compare_plans query parameter is set with proper values.

Fixes 1200196139286276-as-1200247432598890

Implementation notes

These tasks will be dealt with in separate PRs:

  • Replace legacy product card
  • Match legacy Jetpack plans with recommended products
  • Add a term toggle in the upgrade section
  • Add tests to the plan-upgrade folder

Testing instructions

Prerequisite

  • Download the PR and run Calypso

Regression testing

  • Visit /plans/:site and check that it looks and behaves as in production

Upgrade section

  • Visit plans/:site?compare_plans=:legacy-slug,:new-slug, where :legacy-slug is the slug of a Jetpack legacy plan, and :new-slug: the slug of a currently available Jetpack product
  • Check that you see the upgrade section and that it looks like in the video below
  • Verify that it doesn't break when resizing the screen
  • Verify that the prices are updated when switching the term
  • Test again with 2 recommended products (?compare_plans=:legacy-slug,:new-slug,:new-slug)
  • Eventually, use invalid values for the compare_plans parameter, and check that you see the regular plans page

Screenshots

One recommended product

Screen.Recording.2021-04-28.at.8.58.13.AM.mov

Two recommended products

Screen.Recording.2021-04-28.at.8.57.27.AM.mov

@monsieur-z monsieur-z added Jetpack [Feature] Plans & Upgrades All of the plans on WordPress.com and flow for upgrading plans. [Size] M Medium sized issue labels Apr 28, 2021
@monsieur-z monsieur-z requested a review from a team April 28, 2021 13:09
@matticbot matticbot added the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Apr 28, 2021
@github-actions
Copy link

@matticbot
Copy link
Contributor

matticbot commented Apr 28, 2021

Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

App Entrypoints (~21 bytes removed 📉 [gzipped])

name        parsed_size           gzip_size
entry-main        -12 B  (-0.0%)      -21 B  (-0.0%)

Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used.

Sections (~260 bytes added 📈 [gzipped])

name                   parsed_size           gzip_size
plans                      +2649 B  (+0.4%)     +797 B  (+0.4%)
jetpack-connect            +2425 B  (+0.4%)     +704 B  (+0.4%)
jetpack-cloud-pricing      +2425 B  (+0.7%)     +681 B  (+0.7%)
site-purchases               +14 B  (+0.0%)      +10 B  (+0.0%)
settings-performance         +14 B  (+0.0%)      +10 B  (+0.0%)
purchases                    +14 B  (+0.0%)      +10 B  (+0.0%)
purchase-product             +14 B  (+0.0%)      +10 B  (+0.0%)
marketing                    +14 B  (+0.0%)      +10 B  (+0.0%)
domains                      +14 B  (+0.0%)      +10 B  (+0.0%)
activity                     +14 B  (+0.0%)      +10 B  (+0.0%)

Sections contain code specific for a given set of routes. Is downloaded and parsed only when a particular route is navigated to.

Async-loaded Components (~3 bytes removed 📉 [gzipped])

name                                   parsed_size           gzip_size
async-load-calypso-blocks-inline-help        -12 B  (-0.0%)       -3 B  (-0.0%)

React components that are loaded lazily, when a certain part of UI is displayed for the first time.

Legend

What is parsed and gzip size?

Parsed Size: Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
Gzip Size: Compressed size of the JS and CSS files. This much data needs to be downloaded over network.

Generated by performance advisor bot at iscalypsofastyet.com.

@@ -61,6 +61,8 @@ export const PERFORMANCE = 'performance';
export const SECURITY = 'security';
export const PLAN_COMPARISON_PAGE = 'https://jetpack.com/features/comparison/';

export const INTRO_PRICING_DISCOUNT_PERCENTAGE = 40;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Extracting as a constant since it's used in several places.

components: {
product: (
<span className="plan-upgrade__product">
{ newItems.reduce( ( result, { displayName }, index ) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Separate names by commas and a &. displayName is not necessarily a string, so using join wasn't possible.

</p>
<ul className="plan-upgrade__list">
<li className="plan-upgrade__legacy-item">
<ProductCard
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This will be replaced by a legacy product card.

margin-bottom: 6rem;
}

.with-single-reco & {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

When only one product is recommended, the breakpoint should be smaller.

I'm not thrilled by these style duplicates, but I haven't found a better solution yet.

/**
* External dependencies
*/
import isJetpackPurchsableItem from '@automattic/calypso-products/src/is-jetpack-purchasable-item';
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a small typo in isJetpackPurchsableItem.

<li className="plan-upgrade__new-items">
<ul className="plan-upgrade__new-items-list">
{ newItems.map( ( product ) => (
<li key={ product.iconSlug }>
Copy link
Contributor

Choose a reason for hiding this comment

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

We are getting the typical React warning about not having unique keys. Maybe iconSlug is undefined or we need to use something else that is really unique.

image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you remember which values you used for the products, @rcanepa? I wasn't able to reproduce this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I used ?compare_plans=jetpack_premium,jetpack_security_daily,jetpack_backup_realtime.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is really strange. It only happens to me with these specific products, and the debugger clearly shows they have different keys (at no point are they undefined) 🤔 .

Comment on lines 22 to 37
const StandardPlansHeader = ( { context }: { context: PageJS.Context } ) => (
<>
<FormattedHeader headerText={ translate( 'Plans' ) } align="left" brandFont />
<PlansNavigation path={ '/plans' } />
<h2 className="jetpack-plans__pricing-header">
{ preventWidows(
translate( 'Security, performance, and marketing tools made for WordPress' )
) }
</h2>
{ ! getPlanRecommendationFromContext( context ) && (
<h2 className="jetpack-plans__pricing-header">
{ preventWidows(
translate( 'Security, performance, and marketing tools made for WordPress' )
) }
</h2>
) }
Copy link
Contributor

Choose a reason for hiding this comment

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

The purpose of getPlanRecommendationFromContext was hard to understand. Maybe we could rename it to something like shouldShowPlansRecommendation or something like that, and compute that value on the parent component. I don't see a strong reason to pass the whole context object when we can accomplish the same just by passing a boolean.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair point. I'll update that.

Copy link
Contributor

@rcanepa rcanepa left a comment

Choose a reason for hiding this comment

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

LGTM. It works and looks as expected.

I left a couple of non-blocking comments. We can definitely improve them in a follow-up PR.

Also, I noticed that when there are two or more plans being recommended, their cards don't have the same width.

image

I think this can be solved by adding flex: 1 1 100%; to each product card since the parent container is a flex container.

Awesome work!

@monsieur-z
Copy link
Contributor Author

Also, I noticed that when there are two or more plans being recommended, their cards don't have the same width.

Good catch! Thank you.

@monsieur-z monsieur-z force-pushed the add/legacy-plan-comparison-section branch from bd7757e to 953275c Compare April 28, 2021 15:38
@monsieur-z monsieur-z merged commit cd3e7f9 into trunk Apr 28, 2021
@monsieur-z monsieur-z deleted the add/legacy-plan-comparison-section branch April 28, 2021 15:53
@github-actions github-actions bot removed the [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. label Apr 28, 2021
@a8ci18n
Copy link

a8ci18n commented Apr 28, 2021

This Pull Request is now available for translation here: https://translate.wordpress.com/deliverables/5809392

Hi @monsieur-z, could you please edit the description of this PR and add a screenshot for our translators? Ideally it'd include all of the following strings:

  • We recommend {{product/}} based on your selection
  • Jetpack has introduced new flexible plans and pricing options. As an added bonus, we're offering {{b}}%(percentage)s% off{{/b}} your first term.

Thank you in advance!

@a8ci18n
Copy link

a8ci18n commented May 7, 2021

Translation for this Pull Request has now been finished.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Plans & Upgrades All of the plans on WordPress.com and flow for upgrading plans. Jetpack [Size] M Medium sized issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants