Add introduction banner card into multichannel marketing page (#37110)
This commit is contained in:
commit
bebad071a3
|
@ -8,3 +8,4 @@ export { PluginCardBody, SmartPluginCardBody } from './PluginCardBody';
|
|||
export { CardHeaderTitle } from './CardHeaderTitle';
|
||||
export { CardHeaderDescription } from './CardHeaderDescription';
|
||||
export { CenteredSpinner } from './CenteredSpinner';
|
||||
export { CreateNewCampaignModal } from './CreateNewCampaignModal';
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
export { useIntroductionBanner } from './useIntroductionBanner';
|
||||
export { useInstalledPlugins } from './useInstalledPlugins';
|
||||
export { useRegisteredChannels } from './useRegisteredChannels';
|
||||
export { useRecommendedChannels } from './useRecommendedChannels';
|
||||
export { useCampaignTypes } from './useCampaignTypes';
|
||||
export { useCampaigns } from './useCampaigns';
|
||||
|
|
|
@ -27,13 +27,10 @@ type UseCampaignsType = {
|
|||
/**
|
||||
* Custom hook to get campaigns.
|
||||
*
|
||||
* @param page Page number. First page is `1`.
|
||||
* @param perPage Page size, i.e. number of records in one page.
|
||||
* @param page Page number. Default is `1`.
|
||||
* @param perPage Page size, i.e. number of records in one page. Default is `5`.
|
||||
*/
|
||||
export const useCampaigns = (
|
||||
page: number,
|
||||
perPage: number
|
||||
): UseCampaignsType => {
|
||||
export const useCampaigns = ( page = 1, perPage = 5 ): UseCampaignsType => {
|
||||
const { data: channels } = useRegisteredChannels();
|
||||
|
||||
return useSelect(
|
|
@ -0,0 +1,45 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useDispatch, useSelect } from '@wordpress/data';
|
||||
import { OPTIONS_STORE_NAME } from '@woocommerce/data';
|
||||
import { recordEvent } from '@woocommerce/tracks';
|
||||
|
||||
type UseIntroductionBanner = {
|
||||
loading: boolean;
|
||||
isIntroductionBannerDismissed: boolean;
|
||||
dismissIntroductionBanner: () => void;
|
||||
};
|
||||
|
||||
const OPTION_NAME_BANNER_DISMISSED =
|
||||
'woocommerce_marketing_overview_multichannel_banner_dismissed';
|
||||
const OPTION_VALUE_YES = 'yes';
|
||||
|
||||
export const useIntroductionBanner = (): UseIntroductionBanner => {
|
||||
const { updateOptions } = useDispatch( OPTIONS_STORE_NAME );
|
||||
|
||||
const dismissIntroductionBanner = () => {
|
||||
updateOptions( {
|
||||
[ OPTION_NAME_BANNER_DISMISSED ]: OPTION_VALUE_YES,
|
||||
} );
|
||||
recordEvent( 'marketing_multichannel_banner_dismissed', {} );
|
||||
};
|
||||
|
||||
const { loading, data } = useSelect( ( select ) => {
|
||||
const { getOption, hasFinishedResolution } =
|
||||
select( OPTIONS_STORE_NAME );
|
||||
|
||||
return {
|
||||
loading: ! hasFinishedResolution( 'getOption', [
|
||||
OPTION_NAME_BANNER_DISMISSED,
|
||||
] ),
|
||||
data: getOption( OPTION_NAME_BANNER_DISMISSED ),
|
||||
};
|
||||
}, [] );
|
||||
|
||||
return {
|
||||
loading,
|
||||
isIntroductionBannerDismissed: data === OPTION_VALUE_YES,
|
||||
dismissIntroductionBanner,
|
||||
};
|
||||
};
|
|
@ -7,21 +7,23 @@ import userEvent from '@testing-library/user-event';
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { useCampaigns } from './useCampaigns';
|
||||
import { useCampaignTypes } from '~/marketing/hooks';
|
||||
import { useCampaignTypes, useCampaigns } from '~/marketing/hooks';
|
||||
import { Campaigns } from './Campaigns';
|
||||
|
||||
jest.mock( './useCampaigns', () => ( {
|
||||
useCampaigns: jest.fn(),
|
||||
} ) );
|
||||
|
||||
jest.mock( '~/marketing/hooks', () => ( {
|
||||
useCampaigns: jest.fn(),
|
||||
useCampaignTypes: jest.fn(),
|
||||
} ) );
|
||||
|
||||
jest.mock( './CreateNewCampaignModal', () => ( {
|
||||
CreateNewCampaignModal: () => <div>Mocked CreateNewCampaignModal</div>,
|
||||
} ) );
|
||||
jest.mock( '~/marketing/components', () => {
|
||||
const originalModule = jest.requireActual( '~/marketing/components' );
|
||||
|
||||
return {
|
||||
__esModule: true,
|
||||
...originalModule,
|
||||
CreateNewCampaignModal: () => <div>Mocked CreateNewCampaignModal</div>,
|
||||
};
|
||||
} );
|
||||
|
||||
/**
|
||||
* Create a test campaign data object.
|
||||
|
|
|
@ -24,9 +24,11 @@ import {
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { CardHeaderTitle } from '~/marketing/components';
|
||||
import { useCampaigns } from './useCampaigns';
|
||||
import { CreateNewCampaignModal } from './CreateNewCampaignModal';
|
||||
import {
|
||||
CardHeaderTitle,
|
||||
CreateNewCampaignModal,
|
||||
} from '~/marketing/components';
|
||||
import { useCampaigns } from '~/marketing/hooks';
|
||||
import './Campaigns.scss';
|
||||
|
||||
const tableCaption = __( 'Campaigns', 'woocommerce' );
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { Fragment, useState } from '@wordpress/element';
|
||||
import {
|
||||
Fragment,
|
||||
useState,
|
||||
forwardRef,
|
||||
useImperativeHandle,
|
||||
useRef,
|
||||
} from '@wordpress/element';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import {
|
||||
Card,
|
||||
|
@ -32,72 +38,97 @@ type ChannelsProps = {
|
|||
onInstalledAndActivated?: () => void;
|
||||
};
|
||||
|
||||
export const Channels: React.FC< ChannelsProps > = ( {
|
||||
registeredChannels,
|
||||
recommendedChannels,
|
||||
onInstalledAndActivated,
|
||||
} ) => {
|
||||
const hasRegisteredChannels = registeredChannels.length >= 1;
|
||||
|
||||
export type ChannelsRef = {
|
||||
/**
|
||||
* State to collapse / expand the recommended channels.
|
||||
* Initial state is expanded if there are no registered channels in first page load.
|
||||
* Scroll into the "Add channels" section in the card.
|
||||
* The section will be expanded, and the "Add channels" button will be in focus.
|
||||
*/
|
||||
const [ expanded, setExpanded ] = useState( ! hasRegisteredChannels );
|
||||
scrollIntoAddChannels: () => void;
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="woocommerce-marketing-channels-card">
|
||||
<CardHeader>
|
||||
<CardHeaderTitle>
|
||||
{ __( 'Channels', 'woocommerce' ) }
|
||||
</CardHeaderTitle>
|
||||
{ ! hasRegisteredChannels && (
|
||||
<CardHeaderDescription>
|
||||
{ __(
|
||||
'Start by adding a channel to your store',
|
||||
'woocommerce'
|
||||
) }
|
||||
</CardHeaderDescription>
|
||||
) }
|
||||
</CardHeader>
|
||||
export const Channels = forwardRef< ChannelsRef, ChannelsProps >(
|
||||
(
|
||||
{ registeredChannels, recommendedChannels, onInstalledAndActivated },
|
||||
ref
|
||||
) => {
|
||||
const hasRegisteredChannels = registeredChannels.length >= 1;
|
||||
|
||||
{ /* Registered channels section. */ }
|
||||
{ registeredChannels.map( ( el, idx ) => {
|
||||
return (
|
||||
/**
|
||||
* State to collapse / expand the recommended channels.
|
||||
* Initial state is expanded if there are no registered channels in first page load.
|
||||
*/
|
||||
const [ expanded, setExpanded ] = useState( ! hasRegisteredChannels );
|
||||
const addChannelsButtonRef = useRef< HTMLButtonElement >( null );
|
||||
|
||||
useImperativeHandle(
|
||||
ref,
|
||||
() => ( {
|
||||
scrollIntoAddChannels: () => {
|
||||
setExpanded( true );
|
||||
addChannelsButtonRef.current?.focus();
|
||||
addChannelsButtonRef.current?.scrollIntoView( {
|
||||
block: 'center',
|
||||
} );
|
||||
},
|
||||
} ),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<Card className="woocommerce-marketing-channels-card">
|
||||
<CardHeader>
|
||||
<CardHeaderTitle>
|
||||
{ __( 'Channels', 'woocommerce' ) }
|
||||
</CardHeaderTitle>
|
||||
{ ! hasRegisteredChannels && (
|
||||
<CardHeaderDescription>
|
||||
{ __(
|
||||
'Start by adding a channel to your store',
|
||||
'woocommerce'
|
||||
) }
|
||||
</CardHeaderDescription>
|
||||
) }
|
||||
</CardHeader>
|
||||
|
||||
{ /* Registered channels section. */ }
|
||||
{ registeredChannels.map( ( el, idx ) => (
|
||||
<Fragment key={ el.slug }>
|
||||
<RegisteredChannelCardBody registeredChannel={ el } />
|
||||
{ idx !== registeredChannels.length - 1 && (
|
||||
<CardDivider />
|
||||
) }
|
||||
</Fragment>
|
||||
);
|
||||
} ) }
|
||||
) ) }
|
||||
|
||||
{ /* Recommended channels section. */ }
|
||||
{ recommendedChannels.length >= 1 && (
|
||||
<div>
|
||||
{ !! hasRegisteredChannels && (
|
||||
<>
|
||||
<CardDivider />
|
||||
<CardBody>
|
||||
<Button
|
||||
variant="link"
|
||||
onClick={ () => setExpanded( ! expanded ) }
|
||||
>
|
||||
{ __( 'Add channels', 'woocommerce' ) }
|
||||
<Icon
|
||||
icon={
|
||||
expanded ? chevronUp : chevronDown
|
||||
{ /* Recommended channels section. */ }
|
||||
{ recommendedChannels.length >= 1 && (
|
||||
<div>
|
||||
{ !! hasRegisteredChannels && (
|
||||
<>
|
||||
<CardDivider />
|
||||
<CardBody>
|
||||
<Button
|
||||
ref={ addChannelsButtonRef }
|
||||
variant="link"
|
||||
onClick={ () =>
|
||||
setExpanded( ! expanded )
|
||||
}
|
||||
size={ 24 }
|
||||
/>
|
||||
</Button>
|
||||
</CardBody>
|
||||
</>
|
||||
) }
|
||||
{ !! expanded &&
|
||||
recommendedChannels.map( ( el, idx ) => {
|
||||
return (
|
||||
>
|
||||
{ __( 'Add channels', 'woocommerce' ) }
|
||||
<Icon
|
||||
icon={
|
||||
expanded
|
||||
? chevronUp
|
||||
: chevronDown
|
||||
}
|
||||
size={ 24 }
|
||||
/>
|
||||
</Button>
|
||||
</CardBody>
|
||||
</>
|
||||
) }
|
||||
{ !! expanded &&
|
||||
recommendedChannels.map( ( el, idx ) => (
|
||||
<Fragment key={ el.plugin }>
|
||||
<SmartPluginCardBody
|
||||
plugin={ el }
|
||||
|
@ -110,10 +141,10 @@ export const Channels: React.FC< ChannelsProps > = ( {
|
|||
<CardDivider />
|
||||
) }
|
||||
</Fragment>
|
||||
);
|
||||
} ) }
|
||||
</div>
|
||||
) }
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
) ) }
|
||||
</div>
|
||||
) }
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
export { Channels } from './Channels';
|
||||
export type { ChannelsRef } from './Channels';
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
.woocommerce-marketing-introduction-banner {
|
||||
& > div {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.woocommerce-marketing-introduction-banner-content {
|
||||
flex: 1 0;
|
||||
margin: 32px 20px 32px 40px;
|
||||
|
||||
.woocommerce-marketing-introduction-banner-title {
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
margin-bottom: $gap-smaller;
|
||||
}
|
||||
|
||||
.woocommerce-marketing-introduction-banner-features {
|
||||
color: $gray-700;
|
||||
|
||||
svg {
|
||||
fill: $studio-woocommerce-purple-50;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-marketing-introduction-banner-buttons {
|
||||
margin-top: $gap;
|
||||
}
|
||||
}
|
||||
|
||||
.woocommerce-marketing-introduction-banner-illustration {
|
||||
flex: 0 0 270px;
|
||||
background: linear-gradient(90deg, rgba(247, 237, 247, 0) 5.31%, rgba(196, 152, 217, 0.12) 77.75%),
|
||||
linear-gradient(90deg, rgba(247, 237, 247, 0) 22%, rgba(196, 152, 217, 0.12) 84.6%);
|
||||
|
||||
.woocommerce-marketing-introduction-banner-image-placeholder {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: center / contain no-repeat;
|
||||
}
|
||||
|
||||
.woocommerce-marketing-introduction-banner-close-button {
|
||||
position: absolute;
|
||||
top: $gap-small;
|
||||
right: $gap;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { useState } from '@wordpress/element';
|
||||
import { Card, Flex, FlexItem, FlexBlock, Button } from '@wordpress/components';
|
||||
import { Icon, trendingUp, megaphone, closeSmall } from '@wordpress/icons';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { CreateNewCampaignModal } from '~/marketing/components';
|
||||
import {
|
||||
useRegisteredChannels,
|
||||
useRecommendedChannels,
|
||||
} from '~/marketing/hooks';
|
||||
import './IntroductionBanner.scss';
|
||||
import wooIconUrl from './woo.svg';
|
||||
import illustrationUrl from './illustration.svg';
|
||||
|
||||
type IntroductionBannerProps = {
|
||||
onDismissClick: () => void;
|
||||
onAddChannelsClick: () => void;
|
||||
};
|
||||
|
||||
export const IntroductionBanner = ( {
|
||||
onDismissClick,
|
||||
onAddChannelsClick,
|
||||
}: IntroductionBannerProps ) => {
|
||||
const [ isModalOpen, setModalOpen ] = useState( false );
|
||||
const { data: dataRegistered } = useRegisteredChannels();
|
||||
const { data: dataRecommended } = useRecommendedChannels();
|
||||
|
||||
const showCreateCampaignButton = !! dataRegistered?.length;
|
||||
|
||||
/**
|
||||
* Boolean to display the "Add channels" button in the introduction banner.
|
||||
*
|
||||
* This depends on the number of registered channels,
|
||||
* because if there are no registered channels,
|
||||
* the Channels card will not have the "Add channels" toggle button,
|
||||
* and it does not make sense to display the "Add channels" button in this introduction banner
|
||||
* that will do nothing upon click.
|
||||
*
|
||||
* If there are registered channels and recommended channels,
|
||||
* the Channels card will display the "Add channels" toggle button,
|
||||
* and clicking on the "Add channels" button in this introduction banner
|
||||
* will scroll to the button in Channels card.
|
||||
*/
|
||||
const showAddChannelsButton =
|
||||
!! dataRegistered?.length && !! dataRecommended?.length;
|
||||
|
||||
return (
|
||||
<Card className="woocommerce-marketing-introduction-banner">
|
||||
<div className="woocommerce-marketing-introduction-banner-content">
|
||||
<div className="woocommerce-marketing-introduction-banner-title">
|
||||
{ __(
|
||||
'Reach new customers and increase sales without leaving WooCommerce',
|
||||
'woocommerce'
|
||||
) }
|
||||
</div>
|
||||
<Flex
|
||||
className="woocommerce-marketing-introduction-banner-features"
|
||||
direction="column"
|
||||
gap={ 1 }
|
||||
expanded={ false }
|
||||
>
|
||||
<FlexItem>
|
||||
<Flex>
|
||||
<Icon icon={ trendingUp } />
|
||||
<FlexBlock>
|
||||
{ __(
|
||||
'Reach customers on other sales channels',
|
||||
'woocommerce'
|
||||
) }
|
||||
</FlexBlock>
|
||||
</Flex>
|
||||
</FlexItem>
|
||||
<FlexItem>
|
||||
<Flex>
|
||||
<Icon icon={ megaphone } />
|
||||
<FlexBlock>
|
||||
{ __(
|
||||
'Advertise with marketing campaigns',
|
||||
'woocommerce'
|
||||
) }
|
||||
</FlexBlock>
|
||||
</Flex>
|
||||
</FlexItem>
|
||||
<FlexItem>
|
||||
<Flex>
|
||||
<img
|
||||
src={ wooIconUrl }
|
||||
alt={ __( 'WooCommerce logo', 'woocommerce' ) }
|
||||
width="24"
|
||||
height="24"
|
||||
/>
|
||||
<FlexBlock>
|
||||
{ __( 'Built by WooCommerce', 'woocommerce' ) }
|
||||
</FlexBlock>
|
||||
</Flex>
|
||||
</FlexItem>
|
||||
</Flex>
|
||||
{ ( showCreateCampaignButton || showAddChannelsButton ) && (
|
||||
<Flex
|
||||
className="woocommerce-marketing-introduction-banner-buttons"
|
||||
justify="flex-start"
|
||||
>
|
||||
{ showCreateCampaignButton && (
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={ () => {
|
||||
setModalOpen( true );
|
||||
} }
|
||||
>
|
||||
{ __( 'Create a campaign', 'woocommerce' ) }
|
||||
</Button>
|
||||
) }
|
||||
{ showAddChannelsButton && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={ onAddChannelsClick }
|
||||
>
|
||||
{ __( 'Add channels', 'woocommerce' ) }
|
||||
</Button>
|
||||
) }
|
||||
</Flex>
|
||||
) }
|
||||
{ isModalOpen && (
|
||||
<CreateNewCampaignModal
|
||||
onRequestClose={ () => setModalOpen( false ) }
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
<div className="woocommerce-marketing-introduction-banner-illustration">
|
||||
<Button
|
||||
isSmall
|
||||
className="woocommerce-marketing-introduction-banner-close-button"
|
||||
onClick={ onDismissClick }
|
||||
>
|
||||
<Icon icon={ closeSmall } />
|
||||
</Button>
|
||||
<div
|
||||
className="woocommerce-marketing-introduction-banner-image-placeholder"
|
||||
style={ {
|
||||
backgroundImage: `url("${ illustrationUrl }")`,
|
||||
} }
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
);
|
||||
};
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 25 KiB |
|
@ -0,0 +1 @@
|
|||
export { IntroductionBanner } from './IntroductionBanner';
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg preserveAspectRatio="xMidYMid" version="1.1" viewBox="0 0 256 153" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<title>WooCommerce Logo</title>
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path d="m23.759 0h208.38c13.187 0 23.863 10.675 23.863 23.863v79.542c0 13.187-10.675 23.863-23.863 23.863h-74.727l10.257 25.118-45.109-25.118h-98.695c-13.187 0-23.863-10.675-23.863-23.863v-79.542c-0.10466-13.083 10.571-23.863 23.758-23.863z" fill="#7f54b3"/>
|
||||
<path d="m14.578 21.75c1.4569-1.9772 3.6423-3.0179 6.5561-3.226 5.3073-0.41626 8.3252 2.0813 9.0537 7.4927 3.226 21.75 6.7642 40.169 10.511 55.259l22.79-43.395c2.0813-3.9545 4.6829-6.0358 7.8049-6.2439 4.5789-0.3122 7.3886 2.6016 8.5333 8.7415 2.6016 13.841 5.9317 25.6 9.8862 35.59 2.7057-26.433 7.2846-45.476 13.737-57.236 1.561-2.9138 3.8504-4.3707 6.8683-4.5789 2.3935-0.20813 4.5789 0.52033 6.5561 2.0813 1.9772 1.561 3.0179 3.5382 3.226 5.9317 0.10406 1.8732-0.20813 3.4341-1.0407 4.9951-4.0585 7.4927-7.3886 20.085-10.094 37.567-2.6016 16.963-3.5382 30.179-2.9138 39.649 0.20813 2.6016-0.20813 4.8911-1.2488 6.8683-1.2488 2.2894-3.122 3.5382-5.5154 3.7463-2.7057 0.20813-5.5154-1.0406-8.2211-3.8504-9.678-9.8862-17.379-24.663-22.998-44.332-6.7642 13.32-11.759 23.311-14.985 29.971-6.1398 11.759-11.343 17.795-15.714 18.107-2.8098 0.20813-5.2033-2.1854-7.2846-7.1805-5.3073-13.633-11.031-39.961-17.171-78.985-0.41626-2.7057 0.20813-5.0992 1.665-6.9724zm223.64 16.338c-3.7463-6.5561-9.2618-10.511-16.65-12.072-1.9772-0.41626-3.8504-0.62439-5.6195-0.62439-9.9902 0-18.107 5.2033-24.455 15.61-5.4114 8.8455-8.1171 18.628-8.1171 29.346 0 8.013 1.665 14.881 4.9951 20.605 3.7463 6.5561 9.2618 10.511 16.65 12.072 1.9772 0.41626 3.8504 0.62439 5.6195 0.62439 10.094 0 18.211-5.2033 24.455-15.61 5.4114-8.9496 8.1171-18.732 8.1171-29.45 0.10406-8.1171-1.665-14.881-4.9951-20.501zm-13.112 28.826c-1.4569 6.8683-4.0585 11.967-7.9089 15.402-3.0179 2.7057-5.8276 3.8504-8.4293 3.3301-2.4976-0.52033-4.5789-2.7057-6.1398-6.7642-1.2488-3.226-1.8732-6.452-1.8732-9.4699 0-2.6016 0.20813-5.2033 0.72846-7.5967 0.93659-4.2667 2.7057-8.4293 5.5154-12.384 3.4341-5.0992 7.0764-7.1805 10.823-6.452 2.4976 0.52033 4.5789 2.7057 6.1398 6.7642 1.2488 3.226 1.8732 6.452 1.8732 9.4699 0 2.7057-0.20813 5.3073-0.72846 7.7008zm-52.033-28.826c-3.7463-6.5561-9.3659-10.511-16.65-12.072-1.9772-0.41626-3.8504-0.62439-5.6195-0.62439-9.9902 0-18.107 5.2033-24.455 15.61-5.4114 8.8455-8.1171 18.628-8.1171 29.346 0 8.013 1.665 14.881 4.9951 20.605 3.7463 6.5561 9.2618 10.511 16.65 12.072 1.9772 0.41626 3.8504 0.62439 5.6195 0.62439 10.094 0 18.211-5.2033 24.455-15.61 5.4114-8.9496 8.1171-18.732 8.1171-29.45 0-8.1171-1.665-14.881-4.9951-20.501zm-13.216 28.826c-1.4569 6.8683-4.0585 11.967-7.9089 15.402-3.0179 2.7057-5.8276 3.8504-8.4293 3.3301-2.4976-0.52033-4.5789-2.7057-6.1398-6.7642-1.2488-3.226-1.8732-6.452-1.8732-9.4699 0-2.6016 0.20813-5.2033 0.72846-7.5967 0.93658-4.2667 2.7057-8.4293 5.5154-12.384 3.4341-5.0992 7.0764-7.1805 10.823-6.452 2.4976 0.52033 4.5789 2.7057 6.1398 6.7642 1.2488 3.226 1.8732 6.452 1.8732 9.4699 0.10406 2.7057-0.20813 5.3073-0.72846 7.7008z" fill="#fff"/>
|
||||
</svg>
|
After Width: | Height: | Size: 3.4 KiB |
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { useRef } from '@wordpress/element';
|
||||
import { useUser } from '@woocommerce/data';
|
||||
|
||||
/**
|
||||
|
@ -10,19 +11,28 @@ import '~/marketing/data';
|
|||
import '~/marketing/data-multichannel';
|
||||
import { CenteredSpinner } from '~/marketing/components';
|
||||
import {
|
||||
useIntroductionBanner,
|
||||
useCampaigns,
|
||||
useRegisteredChannels,
|
||||
useRecommendedChannels,
|
||||
useCampaignTypes,
|
||||
} from '~/marketing/hooks';
|
||||
import { getAdminSetting } from '~/utils/admin-settings';
|
||||
import { IntroductionBanner } from './IntroductionBanner';
|
||||
import { Campaigns } from './Campaigns';
|
||||
import { Channels } from './Channels';
|
||||
import { Channels, ChannelsRef } from './Channels';
|
||||
import { InstalledExtensions } from './InstalledExtensions';
|
||||
import { DiscoverTools } from './DiscoverTools';
|
||||
import { LearnMarketing } from './LearnMarketing';
|
||||
import './MarketingOverviewMultichannel.scss';
|
||||
|
||||
export const MarketingOverviewMultichannel: React.FC = () => {
|
||||
const {
|
||||
loading: loadingIntroductionBanner,
|
||||
isIntroductionBannerDismissed,
|
||||
dismissIntroductionBanner,
|
||||
} = useIntroductionBanner();
|
||||
const { loading: loadingCampaigns, meta: metaCampaigns } = useCampaigns();
|
||||
const {
|
||||
loading: loadingCampaignTypes,
|
||||
data: dataCampaignTypes,
|
||||
|
@ -36,8 +46,11 @@ export const MarketingOverviewMultichannel: React.FC = () => {
|
|||
const { loading: loadingRecommended, data: dataRecommended } =
|
||||
useRecommendedChannels();
|
||||
const { currentUserCan } = useUser();
|
||||
const channelsRef = useRef< ChannelsRef >( null );
|
||||
|
||||
if (
|
||||
loadingIntroductionBanner ||
|
||||
( loadingCampaigns && metaCampaigns?.total === undefined ) ||
|
||||
( loadingCampaignTypes && ! dataCampaignTypes ) ||
|
||||
( loadingRegistered && ! dataRegistered ) ||
|
||||
( loadingRecommended && ! dataRecommended )
|
||||
|
@ -45,6 +58,11 @@ export const MarketingOverviewMultichannel: React.FC = () => {
|
|||
return <CenteredSpinner />;
|
||||
}
|
||||
|
||||
const shouldShowCampaigns = !! (
|
||||
dataRegistered?.length &&
|
||||
( isIntroductionBannerDismissed || metaCampaigns?.total )
|
||||
);
|
||||
|
||||
const shouldShowExtensions =
|
||||
getAdminSetting( 'allowMarketplaceSuggestions', false ) &&
|
||||
currentUserCan( 'install_plugins' );
|
||||
|
@ -56,10 +74,19 @@ export const MarketingOverviewMultichannel: React.FC = () => {
|
|||
|
||||
return (
|
||||
<div className="woocommerce-marketing-overview-multichannel">
|
||||
{ !! dataRegistered?.length && <Campaigns /> }
|
||||
{ ! isIntroductionBannerDismissed && (
|
||||
<IntroductionBanner
|
||||
onDismissClick={ dismissIntroductionBanner }
|
||||
onAddChannelsClick={ () => {
|
||||
channelsRef.current?.scrollIntoAddChannels();
|
||||
} }
|
||||
/>
|
||||
) }
|
||||
{ shouldShowCampaigns && <Campaigns /> }
|
||||
{ !! ( dataRegistered && dataRecommended ) &&
|
||||
!! ( dataRegistered.length || dataRecommended.length ) && (
|
||||
<Channels
|
||||
ref={ channelsRef }
|
||||
registeredChannels={ dataRegistered }
|
||||
recommendedChannels={ dataRecommended }
|
||||
onInstalledAndActivated={ refetch }
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add introduction banner to multichannel marketing page.
|
Loading…
Reference in New Issue