Skip to content

Commit

Permalink
Unify user connection flows in My Jetpack
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeyGuyDylan committed Dec 16, 2024
1 parent e82cdcd commit 9ef5301
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const ConnectedProductCard: FC< ConnectedProductCardProps > = ( {
manageUrl,
} = detail;

const navigateToConnectionPage = useMyJetpackNavigate( MyJetpackRoutes.Connection );
const navigateToConnectionPage = useMyJetpackNavigate( MyJetpackRoutes.ConnectionSkipPricing );

/*
* Redirect only if connected
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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();

Expand All @@ -28,6 +31,7 @@ const ConnectionScreen: FC = () => {
apiRoot={ apiRoot }
apiNonce={ apiNonce }
registrationNonce={ registrationNonce }
skipPricingPage={ shouldSkipPricing }
footer={ <ConnectionScreenFooter /> }
/>
</Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -34,7 +36,8 @@ const ActionButton: FC< ActionButtonProps > = ( {
additionalActions,
primaryActionOverride,
onManage,
onFixConnection,
onFixUserConnection,
onFixSiteConnection,
isFetching,
isInstallingStandalone,
className,
Expand All @@ -48,14 +51,18 @@ 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 );
const { recordEvent } = useAnalytics();

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 > >( () => {
Expand Down Expand Up @@ -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 ] ),
Expand Down Expand Up @@ -216,7 +222,8 @@ const ActionButton: FC< ActionButtonProps > = ( {
buttonState,
slug,
onAdd,
onFixConnection,
onFixUserConnection,
onFixSiteConnection,
onActivate,
onInstall,
onLearnMore,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -181,7 +199,8 @@ const ProductCard: FC< ProductCardProps > = props => {
<ActionButton
{ ...ownProps }
onActivate={ activateHandler }
onFixConnection={ fixConnectionHandler }
onFixUserConnection={ fixUserConnectionHandler }
onFixSiteConnection={ fixSiteConnectionHandler }
onManage={ manageHandler }
onAdd={ addHandler }
onInstall={ installStandaloneHandler }
Expand All @@ -197,7 +216,7 @@ const ProductCard: FC< ProductCardProps > = props => {
</div>
<Status
status={ status }
isFetching={ isFetching }
isFetching={ isLoading }
isInstallingStandalone={ isInstallingStandalone }
isOwned={ isOwned }
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions projects/packages/my-jetpack/_inc/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Original file line number Diff line number Diff line change
Expand Up @@ -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( {
Expand All @@ -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(
Expand Down Expand Up @@ -121,6 +121,7 @@ const useSiteConnectionNotice = ( redBubbleAlerts: RedBubbleAlerts ) => {
options: noticeOptions,
} );
}, [
isSiteConnected,
connectSite,
navToConnection,
products,
Expand Down

0 comments on commit 9ef5301

Please sign in to comment.