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

Task: Create Plans page for Jetpack App Site Creation #82135

Merged
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d0f33a4
Create a basic structure for /jetpack-app-plans page
staskus Sep 25, 2023
b02dc10
Remove use of deprecated params
guarani Sep 25, 2023
c5cfdc1
Set intent for Jetpack app plans in site creation
staskus Sep 26, 2023
377e11f
Hide yearly/monthly selector
staskus Sep 26, 2023
3c896d6
Pass selected plan through redirection url
staskus Sep 26, 2023
45e88f7
Use snake case for passing cart item
staskus Sep 26, 2023
15d3f53
Merge branch 'trunk' into task/82131-create-plans-page-for-jetpack-ap…
staskus Sep 26, 2023
07e5c4a
Fix plan retrieval from cart
guarani Sep 26, 2023
0c741da
Check if cartItems exist before fetching plan
staskus Sep 27, 2023
20b2a8e
Hide top and sidebars in jetpack-app-plans flow
staskus Sep 27, 2023
46c9d1f
Add a header to jetpack-app-plans page
staskus Sep 27, 2023
a2cc114
Refactor to improve code style
staskus Sep 27, 2023
362bac9
Show a different header label when no domain name is passed
staskus Sep 27, 2023
60a48a9
Hide feature comparison
staskus Sep 27, 2023
ce04567
Rename domain_name to paid_domain_name for more clarity
staskus Sep 27, 2023
d4109ec
Reuse the same translation from previous label
staskus Sep 27, 2023
86616c6
Merge branch 'trunk' into task/82131-create-plans-page-for-jetpack-ap…
staskus Sep 28, 2023
864bfe0
Renaming plans-grid path
staskus Sep 28, 2023
4d76322
Simplify redirect by passing only plan product id
staskus Oct 2, 2023
ea33f08
Remove redundant flow name
staskus Oct 4, 2023
4a2cd2d
Set a lighter web view color for Jetpack App Plans to match other pla…
staskus Oct 5, 2023
1e773e8
Merge branch 'trunk' into task/82131-create-plans-page-for-jetpack-ap…
staskus Oct 5, 2023
6f08ea2
Merge branch 'trunk' into task/82131-create-plans-page-for-jetpack-ap…
staskus Oct 6, 2023
a06919a
Create a middleware for Jetpack App pages layout
staskus Oct 9, 2023
b6eac81
Change jetpack-app-plans to jetpack-app/plans route
staskus Oct 9, 2023
1bcaf9f
Remove redundant style
staskus Oct 9, 2023
c7fe9e7
Remove Loading and Plans subcomponents to improve readability
staskus Oct 10, 2023
21a4d96
Use useTranslate hook
staskus Oct 10, 2023
9822307
Convert JS to TS
staskus Oct 10, 2023
b5f5ecf
Use --studio-white for Jetpack App Plans background color
staskus Oct 11, 2023
2f30134
Remove explicit { yes } from parameters
staskus Oct 11, 2023
af02274
Use import type for imports only for typing purposes
staskus Oct 11, 2023
910dd09
Use a consistent Context definition
staskus Oct 11, 2023
7d480b3
Use addQueryArgs for building redirection URL
staskus Oct 11, 2023
1cf554b
Use a jetpack-app__ prefix for class names
staskus Oct 11, 2023
e1b4a6b
Use grid-unit variables for spacing
staskus Oct 11, 2023
ada828f
Redirect to originalUrl with select plan_id and plan_slug
staskus Oct 11, 2023
a69a6a2
Merge branch 'trunk' into task/82131-create-plans-page-for-jetpack-ap…
staskus Oct 11, 2023
0889d5c
Handle an entire jetpack-app/ route
staskus Oct 12, 2023
5a7dbaa
Redirect to home if jetpack-app/ route is not accessed via the app
staskus Oct 12, 2023
fe58732
Merge branch 'trunk' into task/82131-create-plans-page-for-jetpack-ap…
staskus Oct 12, 2023
2554437
Added README.md explaining jetpack-app/ route
staskus Oct 12, 2023
d355851
Remove forward slash from the section path
staskus Oct 12, 2023
d18c027
Merge branch 'trunk' into task/82131-create-plans-page-for-jetpack-ap…
staskus Oct 12, 2023
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
53 changes: 53 additions & 0 deletions client/jetpack-app/page-middleware/layout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { QueryClientProvider } from '@tanstack/react-query';
import { Provider as ReduxProvider } from 'react-redux';
staskus marked this conversation as resolved.
Show resolved Hide resolved
import CalypsoI18nProvider from 'calypso/components/calypso-i18n-provider';
import { RouteProvider } from 'calypso/components/route';
import { CalypsoReactQueryDevtools } from 'calypso/lib/react-query-devtools-helper';

export { render, hydrate } from 'calypso/controller/web-util';

export const ProviderWrappedLayout = ( {
store,
queryClient,
currentSection,
currentRoute,
currentQuery,
primary,
} ) => {
return (
<CalypsoI18nProvider>
<RouteProvider
currentSection={ currentSection }
currentRoute={ currentRoute }
currentQuery={ currentQuery }
>
<QueryClientProvider client={ queryClient }>
<ReduxProvider store={ store }>{ primary }</ReduxProvider>
<CalypsoReactQueryDevtools />
</QueryClientProvider>
</RouteProvider>
</CalypsoI18nProvider>
);
};

export function makeJetpackAppLayoutMiddleware( LayoutComponent ) {
return ( context, next ) => {
const { i18n, store, queryClient, section, pathname, query, primary } = context;

context.layout = (
<LayoutComponent
i18n={ i18n }
store={ store }
queryClient={ queryClient }
currentSection={ section }
currentRoute={ pathname }
currentQuery={ query }
primary={ primary }
redirectUri={ context.originalUrl }
/>
);
next();
};
}

export const makeJetpackAppLayout = makeJetpackAppLayoutMiddleware( ProviderWrappedLayout );
12 changes: 12 additions & 0 deletions client/jetpack-app/plans/controller.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import JetpackAppPlans from './main';

export function jetpackAppPlans( context, next ) {
context.primary = (
<JetpackAppPlans
paidDomainName={ context.query.paid_domain_name }
redirectTo={ context.query.redirect_to }
/>
);

next();
}
16 changes: 16 additions & 0 deletions client/jetpack-app/plans/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import page from 'page';
import { render as clientRender } from 'calypso/controller';
import { navigation, siteSelection } from 'calypso/my-sites/controller';
import { makeJetpackAppLayout } from '../page-middleware/layout';
import { jetpackAppPlans } from './controller';

export default () => {
page(
'/jetpack-app/plans',
siteSelection,
navigation,
jetpackAppPlans,
makeJetpackAppLayout,
clientRender
);
};
109 changes: 109 additions & 0 deletions client/jetpack-app/plans/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { getPlan, PLAN_FREE } from '@automattic/calypso-products';
import { translate } from 'i18n-calypso';
import { useSelector } from 'react-redux';
import QueryPlans from 'calypso/components/data/query-plans';
import FormattedHeader from 'calypso/components/formatted-header';
import { LoadingEllipsis } from 'calypso/components/loading-ellipsis';
import Main from 'calypso/components/main';
import { getPlanCartItem } from 'calypso/lib/cart-values/cart-items';
import PlansFeaturesMain from 'calypso/my-sites/plans-features-main';
import { getPlanSlug } from 'calypso/state/plans/selectors';

import './style.scss';

const Header = ( { paidDomainName } ) => (
<div className="plans__header">
<FormattedHeader
brandFont
headerText={ translate( 'Choose the perfect plan' ) }
staskus marked this conversation as resolved.
Show resolved Hide resolved
align="center"
/>
{ paidDomainName ? (
<>
<p>
{ translate(
'With your annual plan, you’ll get %(domainName)s {{strong}}free for the first year{{/strong}}.',
{
args: {
domainName: paidDomainName,
},
components: { strong: <strong /> },
}
) }
</p>
<p>
{ translate(
'You’ll also unlock advanced features that make it easy to build and grow your site.'
) }
</p>
</>
) : (
<p>{ translate( 'See and compare the features available on each WordPress.com plan.' ) }</p>
) }
</div>
);

const Plans = ( { paidDomainName, onUpgradeClick, handleRedirect } ) => (
<PlansFeaturesMain
paidDomainName={ paidDomainName }
intent="plans-jetpack-app-site-creation"
isInSignup={ true }
intervalType="yearly"
onUpgradeClick={ onUpgradeClick }
plansWithScroll={ false }
removePaidDomain={ handleRedirect }
hidePlanTypeSelector={ true }
hidePlansFeatureComparison={ true }
/>
);

const Loading = () => (
<div className="plans__loading">
<LoadingEllipsis active />
</div>
);
staskus marked this conversation as resolved.
Show resolved Hide resolved

const JetpackAppPlans = ( { paidDomainName, redirectTo } ) => {
const planSlug = useSelector( ( state ) =>
getPlanSlug( state, getPlan( PLAN_FREE )?.getProductId() || 0 )
);
const plansLoaded = Boolean( planSlug );
staskus marked this conversation as resolved.
Show resolved Hide resolved

const handleRedirect = ( planId ) => {
if ( redirectTo ) {
const cartItemParam = planId ? `?plan_id=${ planId }` : '';
window.location.href = `${ redirectTo }${ cartItemParam }`;
}
};

const onUpgradeClick = ( cartItems ) => {
if ( ! cartItems ) {
return handleRedirect();
}

const { product_slug: planProductSlug } = getPlanCartItem( cartItems );
const plan = getPlan( planProductSlug );

handleRedirect( plan.getProductId() );
};

return (
<Main className="jetpack-app-plans">
<QueryPlans />
{ plansLoaded ? (
<>
<Header paidDomainName={ paidDomainName } />
<Plans
paidDomainName={ paidDomainName }
onUpgradeClick={ onUpgradeClick }
handleRedirect={ handleRedirect }
/>
</>
) : (
<Loading />
) }
</Main>
);
};

export default JetpackAppPlans;
33 changes: 33 additions & 0 deletions client/jetpack-app/plans/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@import "calypso/my-sites/plans-grid/media-queries";

body {
background-color: #fdfdfd;
staskus marked this conversation as resolved.
Show resolved Hide resolved
}

.jetpack-app-plans {
@include plan-features-layout-switcher;

.plans__header {
display: block;
overflow: auto;

.formatted-header__title,
.formatted-header__subtitle {
max-width: unset;
staskus marked this conversation as resolved.
Show resolved Hide resolved
}

h1 {
font-family: $brand-serif;
font-size: $font-headline-small;
margin-bottom: 16px;
}

p {
font-size: $font-body;
color: var(--color-text-subtle);
text-align: center;
padding: 0 16px;
staskus marked this conversation as resolved.
Show resolved Hide resolved
margin-bottom: 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export type PlansIntent =
| 'plans-new-hosted-site'
| 'plans-plugins'
| 'plans-jetpack-app'
| 'plans-jetpack-app-site-creation'
| 'plans-import'
| 'plans-woocommerce'
| 'plans-paid-media'
Expand Down Expand Up @@ -217,6 +218,9 @@ const usePlanTypesWithIntent = ( {
case 'plans-jetpack-app':
planTypes = [ TYPE_PERSONAL, TYPE_PREMIUM, TYPE_BUSINESS, TYPE_ECOMMERCE ];
break;
case 'plans-jetpack-app-site-creation':
planTypes = [ TYPE_FREE, TYPE_PERSONAL, TYPE_PREMIUM, TYPE_BUSINESS, TYPE_ECOMMERCE ];
break;
case 'plans-paid-media':
planTypes = [ TYPE_PERSONAL, TYPE_PREMIUM, TYPE_BUSINESS, TYPE_ECOMMERCE ];
break;
Expand Down
5 changes: 5 additions & 0 deletions client/sections.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ const sections = [
enableLoggedOut: true,
isomorphic: true,
},
{
name: 'jetpack-app-plans',
paths: [ '/jetpack-app/plans' ],
staskus marked this conversation as resolved.
Show resolved Hide resolved
staskus marked this conversation as resolved.
Show resolved Hide resolved
module: 'calypso/jetpack-app/plans',
},
{
name: 'stats',
paths: [ '/stats' ],
Expand Down