diff --git a/projects/packages/my-jetpack/_inc/components/connected-product-card/index.tsx b/projects/packages/my-jetpack/_inc/components/connected-product-card/index.tsx
index d93ac23088bb8..9c43c7f3c30c9 100644
--- a/projects/packages/my-jetpack/_inc/components/connected-product-card/index.tsx
+++ b/projects/packages/my-jetpack/_inc/components/connected-product-card/index.tsx
@@ -66,7 +66,7 @@ const ConnectedProductCard: FC< ConnectedProductCardProps > = ( {
manageUrl,
} = detail;
- const navigateToConnectionPage = useMyJetpackNavigate( MyJetpackRoutes.Connection );
+ const navigateToConnectionPage = useMyJetpackNavigate( MyJetpackRoutes.ConnectionSkipPricing );
/*
* Redirect only if connected
diff --git a/projects/packages/my-jetpack/_inc/components/connection-screen/index.tsx b/projects/packages/my-jetpack/_inc/components/connection-screen/index.tsx
index 52954e68d9a06..f8da3fddc6c45 100644
--- a/projects/packages/my-jetpack/_inc/components/connection-screen/index.tsx
+++ b/projects/packages/my-jetpack/_inc/components/connection-screen/index.tsx
@@ -1,5 +1,6 @@
import { Container, Col, AdminPage } from '@automattic/jetpack-components';
import { __ } from '@wordpress/i18n';
+import { useSearchParams } from 'react-router-dom';
import useMyJetpackConnection from '../../hooks/use-my-jetpack-connection';
import useMyJetpackReturnToPage from '../../hooks/use-my-jetpack-return-to-page';
import CloseLink from '../close-link';
@@ -9,6 +10,8 @@ import styles from './styles.module.scss';
import type { FC } from 'react';
const ConnectionScreen: FC = () => {
+ const [ searchParams ] = useSearchParams();
+ const shouldSkipPricing = searchParams.get( 'skip_pricing' ) === 'true';
const returnToPage = useMyJetpackReturnToPage();
const { apiRoot, apiNonce, registrationNonce } = useMyJetpackConnection();
@@ -28,6 +31,7 @@ const ConnectionScreen: FC = () => {
apiRoot={ apiRoot }
apiNonce={ apiNonce }
registrationNonce={ registrationNonce }
+ skipPricingPage={ shouldSkipPricing }
footer={ }
/>
diff --git a/projects/packages/my-jetpack/_inc/components/connections-section/index.jsx b/projects/packages/my-jetpack/_inc/components/connections-section/index.jsx
index ffb1da1e64cd9..a1ba26eff727f 100644
--- a/projects/packages/my-jetpack/_inc/components/connections-section/index.jsx
+++ b/projects/packages/my-jetpack/_inc/components/connections-section/index.jsx
@@ -12,7 +12,7 @@ import ConnectionStatusCard from '../connection-status-card';
*/
export default function ConnectionsSection() {
const { apiRoot, apiNonce, topJetpackMenuItemUrl, connectedPlugins } = useMyJetpackConnection();
- const navigate = useMyJetpackNavigate( MyJetpackRoutes.Connection );
+ const navigate = useMyJetpackNavigate( MyJetpackRoutes.ConnectionSkipPricing );
const products = useAllProducts();
const onDisconnected = () => document?.location?.reload( true ); // TODO: replace with a better experience.
const productsThatRequireUserConnection = getProductSlugsThatRequireUserConnection( products );
diff --git a/projects/packages/my-jetpack/_inc/components/plans-section/index.tsx b/projects/packages/my-jetpack/_inc/components/plans-section/index.tsx
index 0a7f47e1d3f04..a92023e96f30a 100644
--- a/projects/packages/my-jetpack/_inc/components/plans-section/index.tsx
+++ b/projects/packages/my-jetpack/_inc/components/plans-section/index.tsx
@@ -157,7 +157,7 @@ const PlanSectionFooter: FC< PlanSectionHeaderAndFooterProps > = ( { numberOfPur
recordEvent( 'jetpack_myjetpack_plans_purchase_click' );
}, [ recordEvent ] );
- const navigateToConnectionPage = useMyJetpackNavigate( MyJetpackRoutes.Connection );
+ const navigateToConnectionPage = useMyJetpackNavigate( MyJetpackRoutes.ConnectionSkipPricing );
const activateLicenseClickHandler = useCallback( () => {
recordEvent( 'jetpack_myjetpack_activate_license_click' );
if ( ! isUserConnected ) {
diff --git a/projects/packages/my-jetpack/_inc/components/product-card/action-button.tsx b/projects/packages/my-jetpack/_inc/components/product-card/action-button.tsx
index 61984095e7a30..b27606ae85cda 100644
--- a/projects/packages/my-jetpack/_inc/components/product-card/action-button.tsx
+++ b/projects/packages/my-jetpack/_inc/components/product-card/action-button.tsx
@@ -7,14 +7,16 @@ import { useCallback, useState, useEffect, useMemo, useRef } from 'react';
import { PRODUCT_STATUSES } from '../../constants';
import useProduct from '../../data/products/use-product';
import useAnalytics from '../../hooks/use-analytics';
+import useMyJetpackConnection from '../../hooks/use-my-jetpack-connection';
import useOutsideAlerter from '../../hooks/use-outside-alerter';
import styles from './style.module.scss';
import { ProductCardProps } from '.';
import type { SecondaryButtonProps } from './secondary-button';
-import type { FC, ComponentProps } from 'react';
+import type { FC, ComponentProps, MouseEvent } from 'react';
type ActionButtonProps< A = () => void > = ProductCardProps & {
- onFixConnection?: A;
+ onFixUserConnection?: A;
+ onFixSiteConnection?: ( { e }: { e: MouseEvent< HTMLButtonElement > } ) => void;
onManage?: A;
onAdd?: A;
onInstall?: A;
@@ -34,7 +36,8 @@ const ActionButton: FC< ActionButtonProps > = ( {
additionalActions,
primaryActionOverride,
onManage,
- onFixConnection,
+ onFixUserConnection,
+ onFixSiteConnection,
isFetching,
isInstallingStandalone,
className,
@@ -48,6 +51,7 @@ const ActionButton: FC< ActionButtonProps > = ( {
const [ currentAction, setCurrentAction ] = useState< ComponentProps< typeof Button > >( {} );
const { detail } = useProduct( slug );
const { manageUrl, purchaseUrl, managePaidPlanPurchaseUrl, renewPaidPlanPurchaseUrl } = detail;
+ const { siteIsRegistering } = useMyJetpackConnection();
const isManageDisabled = ! manageUrl;
const dropdownRef = useRef( null );
const chevronRef = useRef( null );
@@ -55,7 +59,10 @@ const ActionButton: FC< ActionButtonProps > = ( {
slug === 'jetpack-ai' && debug( slug, detail );
- const isBusy = isFetching || isInstallingStandalone;
+ const isBusy =
+ isFetching ||
+ isInstallingStandalone ||
+ ( siteIsRegistering && status === PRODUCT_STATUSES.SITE_CONNECTION_ERROR );
const hasAdditionalActions = additionalActions?.length > 0;
const buttonState = useMemo< Partial< SecondaryButtonProps > >( () => {
@@ -158,20 +165,19 @@ const ActionButton: FC< ActionButtonProps > = ( {
case PRODUCT_STATUSES.SITE_CONNECTION_ERROR:
return {
...buttonState,
- href: '#/connection',
variant: 'primary',
label: __( 'Connect', 'jetpack-my-jetpack' ),
- onClick: onFixConnection,
+ onClick: onFixSiteConnection,
...( primaryActionOverride &&
PRODUCT_STATUSES.SITE_CONNECTION_ERROR in primaryActionOverride &&
primaryActionOverride[ PRODUCT_STATUSES.SITE_CONNECTION_ERROR ] ),
};
case PRODUCT_STATUSES.USER_CONNECTION_ERROR:
return {
- href: '#/connection',
+ href: '#/connection?skip_pricing=true',
variant: 'primary',
label: __( 'Connect', 'jetpack-my-jetpack' ),
- onClick: onFixConnection,
+ onClick: onFixUserConnection,
...( primaryActionOverride &&
PRODUCT_STATUSES.USER_CONNECTION_ERROR in primaryActionOverride &&
primaryActionOverride[ PRODUCT_STATUSES.USER_CONNECTION_ERROR ] ),
@@ -216,7 +222,8 @@ const ActionButton: FC< ActionButtonProps > = ( {
buttonState,
slug,
onAdd,
- onFixConnection,
+ onFixUserConnection,
+ onFixSiteConnection,
onActivate,
onInstall,
onLearnMore,
diff --git a/projects/packages/my-jetpack/_inc/components/product-card/index.tsx b/projects/packages/my-jetpack/_inc/components/product-card/index.tsx
index 72b536197a895..7884fa5163a80 100644
--- a/projects/packages/my-jetpack/_inc/components/product-card/index.tsx
+++ b/projects/packages/my-jetpack/_inc/components/product-card/index.tsx
@@ -4,6 +4,8 @@ import { useCallback, useEffect } from 'react';
import { PRODUCT_STATUSES } from '../../constants';
import { getMyJetpackWindowInitialState } from '../../data/utils/get-my-jetpack-window-state';
import useAnalytics from '../../hooks/use-analytics';
+import useConnectSite from '../../hooks/use-connect-site';
+import useMyJetpackConnection from '../../hooks/use-my-jetpack-connection';
import Card from '../card';
import ActionButton from './action-button';
import PriceComponent from './pricing-component';
@@ -13,7 +15,7 @@ import Status from './status';
import styles from './style.module.scss';
import type { AdditionalAction, SecondaryAction } from './types';
import type { MutateCallback } from '../../data/use-simple-mutation';
-import type { FC, MouseEventHandler, ReactNode } from 'react';
+import type { FC, MouseEvent, MouseEventHandler, ReactNode } from 'react';
export type ProductCardProps = {
children?: ReactNode;
@@ -85,6 +87,15 @@ const ProductCard: FC< ProductCardProps > = props => {
} );
const { recordEvent } = useAnalytics();
+ const { siteIsRegistering } = useMyJetpackConnection();
+ const isLoading =
+ isFetching || ( siteIsRegistering && status === PRODUCT_STATUSES.SITE_CONNECTION_ERROR );
+ const { connectSite } = useConnectSite( {
+ tracksInfo: {
+ event: 'jetpack_myjetpack_product_card_fix_site_connection',
+ properties: {},
+ },
+ } );
/**
* Calls the passed function onActivate after firing Tracks event
@@ -117,12 +128,19 @@ const ProductCard: FC< ProductCardProps > = props => {
/**
* Calls the passed function onFixConnection after firing Tracks event
*/
- const fixConnectionHandler = useCallback( () => {
+ const fixUserConnectionHandler = useCallback( () => {
recordEvent( 'jetpack_myjetpack_product_card_fixconnection_click', {
product: slug,
} );
}, [ slug, recordEvent ] );
+ const fixSiteConnectionHandler = useCallback(
+ ( { e }: { e: MouseEvent< HTMLButtonElement > } ) => {
+ connectSite( e );
+ },
+ [ connectSite ]
+ );
+
/**
* Calls when the "Learn more" button is clicked
*/
@@ -181,7 +199,8 @@ const ProductCard: FC< ProductCardProps > = props => {
= props => {
diff --git a/projects/packages/my-jetpack/_inc/components/product-card/secondary-button.tsx b/projects/packages/my-jetpack/_inc/components/product-card/secondary-button.tsx
index 66f123af9e6b0..6e00803829ef8 100644
--- a/projects/packages/my-jetpack/_inc/components/product-card/secondary-button.tsx
+++ b/projects/packages/my-jetpack/_inc/components/product-card/secondary-button.tsx
@@ -1,6 +1,6 @@
import { Button } from '@automattic/jetpack-components';
import { __ } from '@wordpress/i18n';
-import type { FC, ReactNode } from 'react';
+import type { FC, ReactNode, MouseEvent } from 'react';
export type SecondaryButtonProps = {
href?: string;
@@ -9,7 +9,7 @@ export type SecondaryButtonProps = {
weight?: 'bold' | 'regular';
label?: string;
shouldShowButton?: () => boolean;
- onClick?: () => void;
+ onClick?: ( () => void ) | ( ( { e }: { e: MouseEvent< HTMLButtonElement > } ) => void );
isExternalLink?: boolean;
icon?: ReactNode;
iconSize?: number;
diff --git a/projects/packages/my-jetpack/_inc/constants.ts b/projects/packages/my-jetpack/_inc/constants.ts
index af4cdacb11fe5..92e8ef5096f51 100644
--- a/projects/packages/my-jetpack/_inc/constants.ts
+++ b/projects/packages/my-jetpack/_inc/constants.ts
@@ -6,6 +6,7 @@ export const MY_JETPACK_PRODUCT_CHECKOUT = 'my-jetpack-product-checkout';
export const MyJetpackRoutes = {
Home: '/',
Connection: '/connection',
+ ConnectionSkipPricing: '/connection?skip_pricing=true',
AddAkismet: '/add-akismet',
AddAntiSpam: '/add-anti-spam', // Old route for Anti Spam
AddBackup: '/add-backup',
diff --git a/projects/packages/my-jetpack/_inc/hooks/use-my-jetpack-navigate/index.ts b/projects/packages/my-jetpack/_inc/hooks/use-my-jetpack-navigate/index.ts
index b35c1d9a2bbfd..1a4a0936d3576 100644
--- a/projects/packages/my-jetpack/_inc/hooks/use-my-jetpack-navigate/index.ts
+++ b/projects/packages/my-jetpack/_inc/hooks/use-my-jetpack-navigate/index.ts
@@ -3,18 +3,14 @@ import { useNavigate } from 'react-router-dom';
import { MyJetpackRoutes } from '../../constants';
import type { NavigateOptions } from 'react-router-dom';
-/**
- * Custom My Jetpack navigator hook
- *
- * @param {string} route - route to navigate to
- * @return {Function} - navigate function
- */
-export default function useMyJetpackNavigate(
+const useMyJetpackNavigate = (
route: ( typeof MyJetpackRoutes )[ keyof typeof MyJetpackRoutes ]
-) {
+) => {
const navigate = useNavigate();
return useCallback(
( options?: NavigateOptions ) => navigate( route, options ),
[ navigate, route ]
);
-}
+};
+
+export default useMyJetpackNavigate;
diff --git a/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-site-connection-notice.tsx b/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-site-connection-notice.tsx
index a2a731a4a956a..aee80801246ee 100644
--- a/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-site-connection-notice.tsx
+++ b/projects/packages/my-jetpack/_inc/hooks/use-notification-watcher/use-site-connection-notice.tsx
@@ -19,11 +19,11 @@ type RedBubbleAlerts = Window[ 'myJetpackInitialState' ][ 'redBubbleAlerts' ];
const useSiteConnectionNotice = ( redBubbleAlerts: RedBubbleAlerts ) => {
const { recordEvent } = useAnalytics();
const { setNotice, resetNotice } = useContext( NoticeContext );
- const { siteIsRegistering } = useMyJetpackConnection( {
+ const { siteIsRegistering, isSiteConnected } = useMyJetpackConnection( {
skipUserConnection: true,
} );
const products = useAllProducts();
- const navToConnection = useMyJetpackNavigate( MyJetpackRoutes.Connection );
+ const navToConnection = useMyJetpackNavigate( MyJetpackRoutes.ConnectionSkipPricing );
const redBubbleSlug = 'missing-connection';
const connectionError = redBubbleAlerts[ redBubbleSlug ];
const { connectSite } = useConnectSite( {
@@ -48,9 +48,9 @@ const useSiteConnectionNotice = ( redBubbleAlerts: RedBubbleAlerts ) => {
if ( requiresUserConnection ) {
recordEvent( 'jetpack_my_jetpack_user_connection_notice_cta_click' );
navToConnection();
+ } else {
+ connectSite( e );
}
-
- connectSite( e );
};
const oneProductMessage = sprintf(
@@ -121,6 +121,7 @@ const useSiteConnectionNotice = ( redBubbleAlerts: RedBubbleAlerts ) => {
options: noticeOptions,
} );
}, [
+ isSiteConnected,
connectSite,
navToConnection,
products,