Skip to content

Commit

Permalink
Add tooltip for installed with no videos (#38842)
Browse files Browse the repository at this point in the history
* Add tooltip for installed with no videos

* Add tooltip for inactive with videos

* Add tooltips for active states

* Add changelog

* Update copy

* Update tooltip location when videos are present but plugin is inactive

* Move info tooltip to heading

* Nitpicks
  • Loading branch information
CodeyGuyDylan authored Aug 16, 2024
1 parent eb13dd7 commit 66515fb
Show file tree
Hide file tree
Showing 15 changed files with 288 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,23 @@ import { Gridicon } from '@automattic/jetpack-components';
import { Popover } from '@wordpress/components';
import { useViewportMatch } from '@wordpress/compose';
import { useState, useCallback, useRef } from 'react';
import useAnalytics from '../../../../hooks/use-analytics';
import useAnalytics from '../../hooks/use-analytics';
import type { FC, ReactNode } from 'react';

import './style.scss';

type Props = {
children: ReactNode;
className?: string;
icon?: string;
iconSize?: number;
tracksEventName?: string;
tracksEventProps?: { [ key: string ]: string | boolean | number };
tracksEventProps?: Record< Lowercase< string >, unknown >;
};

export const InfoTooltip: FC< Props > = ( {
children,
className,
icon = 'info-outline',
iconSize = 14,
tracksEventName,
Expand All @@ -33,7 +35,6 @@ export const InfoTooltip: FC< Props > = ( {
if ( ! prevState === true && tracksEventName ) {
recordEvent( `jetpack_${ tracksEventName }`, {
page: 'my-jetpack',
feature: 'jetpack-protect',
...tracksEventProps,
} );
}
Expand All @@ -51,7 +52,7 @@ export const InfoTooltip: FC< Props > = ( {
}, [ setIsPopoverVisible, useTooltipRef ] );

return (
<span>
<span className={ className }>
<button className="info-tooltip__button" onClick={ toggleTooltip } ref={ useTooltipRef }>
<Gridicon icon={ icon } size={ iconSize } />
</button>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
.info-tooltip__button {
display: flex;
align-items: center;
background: transparent;
border: none;
color: var(--jp-gray-50);
padding: 2px;
cursor: pointer;
svg {
margin: 0 auto;
}
}

.info-tooltip__content {
h3 {
font-size: var(--font-title-small);
line-height: calc(var(--font-title-small) + 6px);;
color: var(--jp-black);
margin: 0 0 calc(var(--spacing-base) * 2);
font-weight: 500;
}

p {
font-size: var(--font-body);
line-height: var(--font-title-small);
color: var(--jp-gray-70);

margin-bottom: 0;

a {
color: var(--jp-black);
text-decoration: underline;
}
a:hover, a:focus {
text-decoration: none;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { __ } from '@wordpress/i18n';
import useProduct from '../../../data/products/use-product';
import { getMyJetpackWindowInitialState } from '../../../data/utils/get-my-jetpack-window-state';
import useMyJetpackConnection from '../../../hooks/use-my-jetpack-connection';
import { InfoTooltip } from '../../info-tooltip';
import ShieldInactive from './assets/shield-inactive.svg';
import ShieldOff from './assets/shield-off.svg';
import ShieldSuccess from './assets/shield-success.svg';
import { InfoTooltip } from './info-tooltip';
import { useProtectTooltipCopy } from './use-protect-tooltip-copy';
import type { ReactElement, PropsWithChildren } from 'react';

Expand Down Expand Up @@ -75,12 +75,13 @@ function WafStatus( { status }: { status: 'active' | 'inactive' | 'off' } ) {
tracksEventProps={ {
location: 'auto-firewall',
status: status,
feature: 'jetpack-protect',
has_paid_plan: hasPaidPlanForProduct,
} }
>
<>
<h3 className="value-section__tooltip-heading">{ autoFirewallTooltip.title }</h3>
<p className="value-section__tooltip-content">{ autoFirewallTooltip.text }</p>
<h3>{ autoFirewallTooltip.title }</h3>
<p>{ autoFirewallTooltip.text }</p>
</>
</InfoTooltip>
</>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import useProduct from '../../../data/products/use-product';
import { getMyJetpackWindowInitialState } from '../../../data/utils/get-my-jetpack-window-state';
import useMyJetpackConnection from '../../../hooks/use-my-jetpack-connection';
import { isJetpackPluginActive } from '../../../utils/is-jetpack-plugin-active';
import { InfoTooltip } from '../../info-tooltip';
import ShieldOff from './assets/shield-off.svg';
import ShieldPartial from './assets/shield-partial.svg';
import { InfoTooltip } from './info-tooltip';
import { useProtectTooltipCopy } from './use-protect-tooltip-copy';
import type { ReactElement, PropsWithChildren } from 'react';

Expand Down Expand Up @@ -74,12 +74,13 @@ function BlockedStatus( { status }: { status: 'active' | 'inactive' | 'off' } )
tracksEventProps={ {
location: 'blocked-logins',
status: status,
feature: 'jetpack-protect',
message: 'no data yet',
} }
>
<>
<h3 className="value-section__tooltip-heading">{ blockedLoginsTooltip.title }</h3>
<p className="value-section__tooltip-content">{ blockedLoginsTooltip.text }</p>
<h3>{ blockedLoginsTooltip.title }</h3>
<p>{ blockedLoginsTooltip.text }</p>
</>
</InfoTooltip>
</>
Expand Down Expand Up @@ -118,12 +119,13 @@ function BlockedStatus( { status }: { status: 'active' | 'inactive' | 'off' } )
tracksEventName={ 'protect_card_tooltip_open' }
tracksEventProps={ {
location: 'blocked-logins',
feature: 'jetpack-protect',
status: status,
} }
>
<>
<h3 className="value-section__tooltip-heading">{ blockedLoginsTooltip.title }</h3>
<p className="value-section__tooltip-content">{ blockedLoginsTooltip.text }</p>
<h3>{ blockedLoginsTooltip.title }</h3>
<p>{ blockedLoginsTooltip.text }</p>
</>
</InfoTooltip>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import useProduct from '../../../data/products/use-product';
import { InfoTooltip } from '../../info-tooltip';
import baseStyles from '../style.module.scss';
import { AutoFirewallStatus } from './auto-firewall-status';
import { InfoTooltip } from './info-tooltip';
import { LoginsBlockedStatus } from './logins-blocked-status';
import { ScanAndThreatStatus } from './scan-threats-status';
import { useLastScanText } from './use-last-scan-text';
Expand All @@ -26,12 +26,13 @@ const ProtectValueSection = () => {
tracksEventName={ 'protect_card_tooltip_open' }
tracksEventProps={ {
location: 'plugins&themes',
feature: 'jetpack-protect',
status: 'inactive',
} }
>
<>
<h3 className="value-section__tooltip-heading">{ pluginsThemesTooltip.title }</h3>
<p className="value-section__tooltip-content">{ pluginsThemesTooltip.text }</p>
<h3>{ pluginsThemesTooltip.title }</h3>
<p>{ pluginsThemesTooltip.text }</p>
</>
</InfoTooltip>
) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import useProduct from '../../../data/products/use-product';
import { getMyJetpackWindowInitialState } from '../../../data/utils/get-my-jetpack-window-state';
import useAnalytics from '../../../hooks/use-analytics';
import useMyJetpackConnection from '../../../hooks/use-my-jetpack-connection';
import { InfoTooltip } from '../../info-tooltip';
import baseStyles from '../style.module.scss';
import ShieldOff from './assets/shield-off.svg';
import ShieldPartial from './assets/shield-partial.svg';
import ShieldSuccess from './assets/shield-success.svg';
import { InfoTooltip } from './info-tooltip';
import { useProtectTooltipCopy } from './use-protect-tooltip-copy';
import type { PropsWithChildren, ReactElement } from 'react';

Expand Down Expand Up @@ -140,8 +140,8 @@ function ThreatStatus( {
onClose={ hideTooltip }
>
<>
<h3 className="value-section__tooltip-heading">{ scanThreatsTooltip.title }</h3>
<p className="value-section__tooltip-content">{ scanThreatsTooltip.text }</p>
<h3>{ scanThreatsTooltip.title }</h3>
<p>{ scanThreatsTooltip.text }</p>
</>
</Popover>
) }
Expand Down Expand Up @@ -217,13 +217,14 @@ function ScanStatus( { status }: { status: 'success' | 'partial' | 'off' } ) {
tracksEventProps={ {
location: 'scan',
status: status,
feature: 'jetpack-protect',
has_paid_plan: false,
threats: 0,
} }
>
<>
<h3 className="value-section__tooltip-heading">{ scanThreatsTooltip.title }</h3>
<p className="value-section__tooltip-content">{ scanThreatsTooltip.text }</p>
<h3>{ scanThreatsTooltip.title }</h3>
<p>{ scanThreatsTooltip.text }</p>
</>
</InfoTooltip>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,6 @@
}
}

&__tooltip-heading {
font-size: var(--font-title-small);
line-height: calc(var(--font-title-small) + 6px);;
color: var(--jp-black);
margin: 0 0 calc(var(--spacing-base) * 2);
font-weight: 500;
}

&__tooltip-content {
font-size: var(--font-body);
line-height: var(--font-title-small);
color: var(--jp-gray-70);
a {
color: var(--jp-black);
text-decoration: underline;
}
a:hover, a:focus {
text-decoration: none;
}
}

&__data {
display: flex;
align-items: center;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createInterpolateElement } from '@wordpress/element';
import { __, _n, sprintf } from '@wordpress/i18n';
import { useCallback, useMemo, createElement, type ReactElement } from 'react';
import { PRODUCT_SLUGS } from '../../../data/constants';
import useProduct from '../../../data/products/use-product';
import { getMyJetpackWindowInitialState } from '../../../data/utils/get-my-jetpack-window-state';
import useAnalytics from '../../../hooks/use-analytics';
Expand All @@ -24,7 +25,7 @@ export type TooltipContent = {
* @returns {TooltipContent} An object containing each tooltip's title and text content.
*/
export function useProtectTooltipCopy(): TooltipContent {
const slug = 'protect';
const slug = PRODUCT_SLUGS.PROTECT;
const { detail } = useProduct( slug );
const { isPluginActive: isProtectPluginActive, hasPaidPlanForProduct: hasProtectPaidPlan } =
detail || {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { PRODUCT_SLUGS } from '../../../data/constants';
import useProduct from '../../../data/products/use-product';
import { getMyJetpackWindowInitialState } from '../../../data/utils/get-my-jetpack-window-state';
import ProductCard from '../../connected-product-card';
import { InfoTooltip } from '../../info-tooltip';
import useTooltipCopy from './use-tooltip-copy';
import useVideoPressCardDescription from './use-videopress-description';
import VideoPressValueSection from './videopress-value-section';
import type { ProductCardComponent } from '../types';
Expand All @@ -20,30 +22,49 @@ const VideopressCard: ProductCardComponent = ( { admin } ) => {
const { detail } = useProduct( slug );
const { status } = detail || {};
const { videopress: data } = getMyJetpackWindowInitialState();
const { activeAndNoVideos } = useTooltipCopy();
const videoCount = data?.videoCount || 0;

const isPluginActive =
status === PRODUCT_STATUSES.ACTIVE || status === PRODUCT_STATUSES.CAN_UPGRADE;

const descriptionText = useVideoPressCardDescription( {
isPluginActive,
videoCount: data.videoCount,
videoCount,
} );

const Description = useCallback( () => {
return (
<Text variant="body-small" className="description">
{ descriptionText }
{ descriptionText || detail.description }
{ isPluginActive && ! videoCount && (
<InfoTooltip
className="videopress-card__no-video-tooltip"
tracksEventName={ 'videopress_card_tooltip_open' }
tracksEventProps={ {
location: 'description',
feature: 'jetpack-videopress',
status,
video_count: videoCount,
} }
>
<h3>{ activeAndNoVideos.title }</h3>
<p>{ activeAndNoVideos.text }</p>
</InfoTooltip>
) }
</Text>
);
}, [ descriptionText ] );
}, [
descriptionText,
detail.description,
videoCount,
status,
activeAndNoVideos,
isPluginActive,
] );

return (
<ProductCard
slug={ slug }
showMenu
admin={ admin }
Description={ descriptionText ? Description : null }
>
<ProductCard slug={ slug } showMenu admin={ admin } Description={ Description }>
<VideoPressValueSection isPluginActive={ isPluginActive } data={ data } />
</ProductCard>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
.videopress-card__video-count {
display: flex;

font-size: calc( var( --font-headline-small ) - 4px );
color: var( --jp-gray-90 );
line-height: 1.125;

margin-top: calc( var( --spacing-base ) / 2 );

.videopress-card__tooltip {
height: 18px;
}
}

p.description {
Expand All @@ -28,4 +34,16 @@ p.description {
color: var( --jp-gray-90 );
line-height: 1.125;
}

&__heading {
display: flex;
align-items: center;
}
}

.videopress-card__no-video-tooltip {
.info-tooltip__button {
display: inline;
vertical-align: middle;
}
}
Loading

0 comments on commit 66515fb

Please sign in to comment.