-
Notifications
You must be signed in to change notification settings - Fork 297
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
Enhancement/10175 setup banner #10208
base: develop
Are you sure you want to change the base?
Changes from all commits
9ab84a7
a96b1dc
e93a7a0
3e2d619
5579318
ef52421
77c60e7
5920e42
af5a08c
cf4f6bd
c8a2f7a
caab7b4
a39011e
c6e53c4
23258be
b8ad0df
22ae366
5267a5d
47855e1
a75f758
ff9205b
884e5ea
d97e33a
6947055
6464299
268cc35
feceedf
31ce027
0831bde
2ce5c5f
9c4f5ea
3221969
172ebb3
f66d913
046ddd5
9997652
e474b21
c28f063
b26c310
0cdc41c
9decaa3
94e1a47
0ea6a39
31d05a4
c188380
b7ff88a
e6f2cfc
3c2b5d5
444a1e5
b65aa1e
cee9813
1b7bef6
d9b3a1d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,170 +24,222 @@ import PropTypes from 'prop-types'; | |
/** | ||
* WordPress dependencies | ||
*/ | ||
import { compose } from '@wordpress/compose'; | ||
import { useCallback } from '@wordpress/element'; | ||
import { Fragment, useState } from '@wordpress/element'; | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { useDispatch, useSelect } from 'googlesitekit-data'; | ||
import { Button } from 'googlesitekit-components'; | ||
import { | ||
BREAKPOINT_SMALL, | ||
BREAKPOINT_TABLET, | ||
useBreakpoint, | ||
} from '../../hooks/useBreakpoint'; | ||
import { ADS_MODULE_SETUP_BANNER_PROMPT_DISMISSED_KEY } from '../../modules/ads/datastore/constants'; | ||
import { CORE_NOTIFICATIONS } from '../../googlesitekit/notifications/datastore/constants'; | ||
import { CORE_USER } from '../../googlesitekit/datastore/user/constants'; | ||
import { WEEK_IN_SECONDS } from '../../util'; | ||
import { Cell, Grid, Row } from '../../material-components'; | ||
import whenInactive from '../../util/when-inactive'; | ||
import { withWidgetComponentProps } from '../../googlesitekit/widgets/util'; | ||
import useActivateModuleCallback from '../../hooks/useActivateModuleCallback'; | ||
import AdsSetupSVG from '../../../svg/graphics/ads-setup.svg'; | ||
import AdsSetupTabletSVG from '../../../svg/graphics/ads-setup-tablet.svg'; | ||
import AdsSetupMobileSVG from '../../../svg/graphics/ads-setup-mobile.svg'; | ||
import NotificationWithSVG from '../../googlesitekit/notifications/components/layout/NotificationWithSVG'; | ||
import Description from '../../googlesitekit/notifications/components/common/Description'; | ||
import LearnMoreLink from '../../googlesitekit/notifications/components/common/LearnMoreLink'; | ||
import ActionsCTALinkDismiss from '../../googlesitekit/notifications/components/common/ActionsCTALinkDismiss'; | ||
import useActivateModuleCallback from '../../hooks/useActivateModuleCallback'; | ||
import AdBlockerWarning from './AdBlockerWarning'; | ||
import { | ||
AdminMenuTooltip, | ||
useShowTooltip, | ||
useTooltipState, | ||
} from '../AdminMenuTooltip'; | ||
import { | ||
BREAKPOINT_SMALL, | ||
BREAKPOINT_TABLET, | ||
useBreakpoint, | ||
} from '../../hooks/useBreakpoint'; | ||
import { WooCommerceRedirectModal } from '../../modules/ads/components/common'; | ||
import { useCallback } from 'react'; | ||
import { | ||
ADS_WOOCOMMERCE_REDIRECT_MODAL_DISMISS_KEY, | ||
MODULES_ADS, | ||
} from '../../modules/ads/datastore/constants'; | ||
|
||
const breakpointSVGMap = { | ||
[ BREAKPOINT_SMALL ]: AdsSetupMobileSVG, | ||
[ BREAKPOINT_TABLET ]: AdsSetupTabletSVG, | ||
}; | ||
|
||
function AdsModuleSetupCTAWidget( { WidgetNull, Widget } ) { | ||
export default function AdsModuleSetupCTAWidget( { id, Notification } ) { | ||
const breakpoint = useBreakpoint(); | ||
const isMobileBreakpoint = breakpoint === BREAKPOINT_SMALL; | ||
const isTabletBreakpoint = breakpoint === BREAKPOINT_TABLET; | ||
const [ openDialog, setOpenDialog ] = useState( false ); | ||
const [ isSaving, setIsSaving ] = useState( false ); | ||
|
||
const onSetupCallback = useActivateModuleCallback( 'ads' ); | ||
const learnMoreURL = undefined; | ||
|
||
const isDismissed = useSelect( ( select ) => | ||
select( CORE_USER ).isPromptDismissed( | ||
ADS_MODULE_SETUP_BANNER_PROMPT_DISMISSED_KEY | ||
) | ||
const isAdBlockerActive = useSelect( ( select ) => | ||
select( CORE_USER ).isAdBlockerActive() | ||
); | ||
|
||
const isDismissalFinal = useSelect( ( select ) => | ||
select( CORE_NOTIFICATIONS ).isNotificationDismissalFinal( id ) | ||
); | ||
const isCTADismissed = useSelect( ( select ) => | ||
select( CORE_NOTIFICATIONS ).isNotificationDismissed( id ) | ||
); | ||
const dismissCount = useSelect( ( select ) => | ||
select( CORE_USER ).getPromptDismissCount( | ||
ADS_MODULE_SETUP_BANNER_PROMPT_DISMISSED_KEY | ||
const dismissedPromptsLoaded = useSelect( ( select ) => | ||
select( CORE_USER ).hasFinishedResolution( 'getDismissedPrompts', [] ) | ||
); | ||
const hideCTABanner = isCTADismissed || ! dismissedPromptsLoaded; | ||
|
||
const shouldShowWooCommerceRedirectModal = useSelect( ( select ) => { | ||
const { | ||
isWooCommerceActivated, | ||
isGoogleForWooCommerceActivated, | ||
hasGoogleForWooCommerceAdsAccount, | ||
} = select( MODULES_ADS ); | ||
|
||
return ( | ||
( isWooCommerceActivated() && | ||
isGoogleForWooCommerceActivated() && | ||
! hasGoogleForWooCommerceAdsAccount() ) || | ||
( isWooCommerceActivated() && ! isGoogleForWooCommerceActivated() ) | ||
); | ||
} ); | ||
|
||
const isWooCommerceRedirectModalDismissed = useSelect( ( select ) => | ||
select( CORE_USER ).isItemDismissed( | ||
ADS_WOOCOMMERCE_REDIRECT_MODAL_DISMISS_KEY | ||
) | ||
); | ||
|
||
const { dismissPrompt } = useDispatch( CORE_USER ); | ||
const { dismissNotification } = useDispatch( CORE_NOTIFICATIONS ); | ||
|
||
const onDismiss = useCallback( async () => { | ||
if ( dismissCount < 1 ) { | ||
const twoWeeksInSeconds = WEEK_IN_SECONDS * 2; | ||
const markNotificationDismissed = useCallback( () => { | ||
dismissNotification( id, { | ||
skipHidingFromQueue: true, | ||
expiresInSeconds: 2 * WEEK_IN_SECONDS, | ||
} ); | ||
}, [ id, dismissNotification ] ); | ||
|
||
await dismissPrompt( ADS_MODULE_SETUP_BANNER_PROMPT_DISMISSED_KEY, { | ||
expiresInSeconds: twoWeeksInSeconds, | ||
} ); | ||
} else { | ||
// For the second dismissal, dismiss permanently. | ||
await dismissPrompt( ADS_MODULE_SETUP_BANNER_PROMPT_DISMISSED_KEY ); | ||
const activateModule = useActivateModuleCallback( 'ads' ); | ||
|
||
const onSetupCallback = useCallback( () => { | ||
if ( | ||
! shouldShowWooCommerceRedirectModal || | ||
isWooCommerceRedirectModalDismissed | ||
) { | ||
markNotificationDismissed(); | ||
activateModule(); | ||
setIsSaving( true ); | ||
return; | ||
} | ||
}, [ dismissCount, dismissPrompt ] ); | ||
|
||
if ( dismissCount > 1 || isDismissed || isDismissed === undefined ) { | ||
return <WidgetNull />; | ||
setOpenDialog( true ); | ||
}, [ | ||
shouldShowWooCommerceRedirectModal, | ||
activateModule, | ||
markNotificationDismissed, | ||
isWooCommerceRedirectModalDismissed, | ||
] ); | ||
|
||
const onModalDismiss = useCallback( () => { | ||
markNotificationDismissed(); | ||
setOpenDialog( false ); | ||
}, [ markNotificationDismissed, setOpenDialog ] ); | ||
|
||
const showTooltip = useShowTooltip( id ); | ||
const { isTooltipVisible } = useTooltipState( id ); | ||
|
||
if ( isTooltipVisible ) { | ||
return ( | ||
<Fragment> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
<AdminMenuTooltip | ||
title="" | ||
content={ __( | ||
'You can always enable Ads from Settings later', | ||
'google-site-kit' | ||
) } | ||
dismissLabel={ __( 'Got it', 'google-site-kit' ) } | ||
tooltipStateKey={ id } | ||
/> | ||
</Fragment> | ||
); | ||
} | ||
|
||
// TODO: Don't use `skipHidingFromQueue` and remove the need to check | ||
// if this component should output anything. | ||
// | ||
// We "incorrectly" pass true to the `skipHidingFromQueue` option when dismissing this banner. | ||
// This is because we don't want the component removed from the DOM as we have to still render | ||
// the `AdminMenuTooltip` in this component. This means that we have to rely on manually | ||
// checking for the dismissal state here. | ||
if ( hideCTABanner ) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<div className="googlesitekit-widget-context"> | ||
<Grid className="googlesitekit-widget-area"> | ||
<Row> | ||
<Cell size={ 12 }> | ||
<Widget | ||
noPadding | ||
className="googlesitekit-setup-cta-banner googlesitekit-ads-setup-cta-widget" | ||
> | ||
<Grid collapsed> | ||
<Row> | ||
<Cell | ||
smSize={ 12 } | ||
mdSize={ 8 } | ||
lgSize={ 6 } | ||
className="googlesitekit-setup-cta-banner__primary-cell" | ||
> | ||
<h3 className="googlesitekit-setup-cta-banner__title"> | ||
{ __( | ||
'Get better quality leads and enhance conversions with Ads', | ||
'google-site-kit' | ||
) } | ||
</h3> | ||
<div className="googlesitekit-setup-cta-banner__description"> | ||
<p> | ||
{ __( | ||
'Help drive sales, leads, or site traffic by getting your business in front of people who are actively searching Google for products or services you offer.', | ||
'google-site-kit' | ||
) } | ||
</p> | ||
</div> | ||
|
||
<div className="googlesitekit-setup-cta-banner__actions-wrapper"> | ||
<Button | ||
className="googlesitekit-key-metrics-cta-button" | ||
onClick={ onSetupCallback } | ||
> | ||
{ __( | ||
'Set up Ads', | ||
'google-site-kit' | ||
) } | ||
</Button> | ||
<Button | ||
tertiary | ||
onClick={ onDismiss } | ||
> | ||
{ dismissCount < 1 | ||
? __( | ||
'Maybe later', | ||
'google-site-kit' | ||
) | ||
: __( | ||
'Don’t show again', | ||
'google-site-kit' | ||
) } | ||
</Button> | ||
</div> | ||
</Cell> | ||
{ ! isMobileBreakpoint && | ||
! isTabletBreakpoint && ( | ||
<Cell | ||
alignBottom | ||
className="googlesitekit-setup-cta-banner__svg-wrapper" | ||
mdSize={ 8 } | ||
lgSize={ 6 } | ||
> | ||
<AdsSetupSVG /> | ||
</Cell> | ||
) } | ||
{ isTabletBreakpoint && ( | ||
<Cell | ||
className="googlesitekit-setup-cta-banner__svg-wrapper" | ||
mdSize={ 8 } | ||
> | ||
<AdsSetupTabletSVG /> | ||
</Cell> | ||
<Fragment> | ||
<Notification> | ||
<NotificationWithSVG | ||
id={ id } | ||
title={ __( | ||
'Get better quality leads and enhance conversions with Ads', | ||
'google-site-kit' | ||
) } | ||
description={ | ||
<Description | ||
text={ __( | ||
'Help drive sales, leads, or site traffic by getting your business in front of people who are actively searching Google for products or services you offer.', | ||
'google-site-kit' | ||
) } | ||
learnMoreLink={ | ||
<LearnMoreLink | ||
id={ id } | ||
label={ __( | ||
'Learn more', | ||
'google-site-kit' | ||
) } | ||
{ isMobileBreakpoint && ( | ||
<Cell | ||
alignBottom | ||
className="googlesitekit-setup-cta-banner__svg-wrapper" | ||
smSize={ 12 } | ||
> | ||
<AdsSetupMobileSVG /> | ||
</Cell> | ||
) } | ||
</Row> | ||
</Grid> | ||
</Widget> | ||
</Cell> | ||
</Row> | ||
</Grid> | ||
</div> | ||
url={ learnMoreURL } | ||
/> | ||
} | ||
AdditionalComponent={ | ||
isAdBlockerActive && ( | ||
<AdBlockerWarning moduleSlug="ads" /> | ||
) | ||
} | ||
/> | ||
} | ||
actions={ | ||
<ActionsCTALinkDismiss | ||
id={ id } | ||
className="googlesitekit-setup-cta-banner__actions-wrapper" | ||
ctaLabel={ __( 'Set up Ads', 'google-site-kit' ) } | ||
onCTAClick={ onSetupCallback } | ||
dismissOnCTAClick={ false } | ||
isSaving={ isSaving } | ||
dismissLabel={ | ||
isDismissalFinal | ||
? __( | ||
'Don’t show again', | ||
'google-site-kit' | ||
) | ||
: __( 'Maybe later', 'google-site-kit' ) | ||
} | ||
dismissOptions={ { | ||
skipHidingFromQueue: true, | ||
} } | ||
onDismiss={ showTooltip } | ||
dismissExpires={ 2 * WEEK_IN_SECONDS } | ||
/> | ||
} | ||
SVG={ breakpointSVGMap[ breakpoint ] || AdsSetupSVG } | ||
/> | ||
</Notification> | ||
<WooCommerceRedirectModal | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's move this to the |
||
dialogActive={ openDialog } | ||
onDismiss={ onModalDismiss } | ||
/> | ||
Comment on lines
+234
to
+237
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps instead of always rendering this component, we should render it conditionally? { openDialog && <WooCommerceRedirectModal onDismiss={ onModalDismiss } dialogActive /> } |
||
</Fragment> | ||
); | ||
} | ||
|
||
AdsModuleSetupCTAWidget.propTypes = { | ||
Widget: PropTypes.elementType.isRequired, | ||
WidgetNull: PropTypes.elementType.isRequired, | ||
id: PropTypes.string, | ||
Notification: PropTypes.elementType, | ||
Comment on lines
+243
to
+244
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These props should be required. |
||
}; | ||
|
||
export default compose( | ||
whenInactive( { moduleName: 'ads' } ), | ||
withWidgetComponentProps( 'ads-setup-cta' ) | ||
)( AdsModuleSetupCTAWidget ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, we need to move this component to the Ads module because we register it there. Plus this is no longer a widget, thus we need to rename it accordingly.