diff --git a/plugins/woocommerce-admin/client/dashboard/index.js b/plugins/woocommerce-admin/client/dashboard/index.js index caf81663f73..a58f51f73e7 100644 --- a/plugins/woocommerce-admin/client/dashboard/index.js +++ b/plugins/woocommerce-admin/client/dashboard/index.js @@ -7,6 +7,7 @@ import { Spinner } from '@woocommerce/components'; /** * Internal dependencies */ +import { OrderAttributionInstallBanner } from '~/order-attribution-install-banner'; import './style.scss'; const CustomizableDashboard = lazy( () => @@ -19,6 +20,7 @@ class Dashboard extends Component { return ( }> + ); diff --git a/plugins/woocommerce-admin/client/order-attribution-install-banner/index.js b/plugins/woocommerce-admin/client/order-attribution-install-banner/index.js new file mode 100644 index 00000000000..57919323e11 --- /dev/null +++ b/plugins/woocommerce-admin/client/order-attribution-install-banner/index.js @@ -0,0 +1 @@ +export * from './order-attribution-install-banner'; diff --git a/plugins/woocommerce-admin/client/order-attribution-install-banner/order-attribution-install-banner-image.js b/plugins/woocommerce-admin/client/order-attribution-install-banner/order-attribution-install-banner-image.js new file mode 100644 index 00000000000..a2ae282a154 --- /dev/null +++ b/plugins/woocommerce-admin/client/order-attribution-install-banner/order-attribution-install-banner-image.js @@ -0,0 +1,62 @@ +const OrderAttributionInstallBannerImage = () => ( + + + + + + + + + + + + + + + + + + + +); + +export default OrderAttributionInstallBannerImage; diff --git a/plugins/woocommerce-admin/client/order-attribution-install-banner/order-attribution-install-banner.js b/plugins/woocommerce-admin/client/order-attribution-install-banner/order-attribution-install-banner.js new file mode 100644 index 00000000000..6247a3ffaa7 --- /dev/null +++ b/plugins/woocommerce-admin/client/order-attribution-install-banner/order-attribution-install-banner.js @@ -0,0 +1,106 @@ +/** + * External dependencies + */ +import { Button, Card, CardBody } from '@wordpress/components'; +import { useEffect } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import { Text } from '@woocommerce/experimental'; +import { recordEvent } from '@woocommerce/tracks'; +import { getPath } from '@woocommerce/navigation'; + +/** + * Internal dependencies + */ +import OrderAttributionInstallBannerImage from './order-attribution-install-banner-image'; +import useOrderAttributionInstallBanner from './use-order-attribution-install-banner'; +import './style.scss'; + +export const OrderAttributionInstallBanner = ( { + bannerImage = , + eventContext = 'analytics-overview', +} ) => { + const { isDismissed, dismiss, shouldShowBanner } = + useOrderAttributionInstallBanner(); + + useEffect( () => { + if ( ! shouldShowBanner || isDismissed ) { + return; + } + recordEvent( 'order_attribution_install_banner_viewed', { + path: getPath(), + context: eventContext, + } ); + }, [ eventContext, shouldShowBanner, isDismissed ] ); + + if ( ! shouldShowBanner || isDismissed ) { + return null; + } + + return ( + + +
+ { bannerImage } +
+
+
+ + { __( 'New', 'woocommerce' ) } + +
+ + { __( + 'Discover what drives your sales', + 'woocommerce' + ) } + + + { __( + 'Understand what truly drives revenue with our powerful order attribution extension. Use it to track your sales journey, identify your most effective marketing channels, and optimize your sales strategy.', + 'woocommerce' + ) } + +
+ + +
+
+
+
+ ); +}; diff --git a/plugins/woocommerce-admin/client/order-attribution-install-banner/style.scss b/plugins/woocommerce-admin/client/order-attribution-install-banner/style.scss new file mode 100644 index 00000000000..c0370fb75f7 --- /dev/null +++ b/plugins/woocommerce-admin/client/order-attribution-install-banner/style.scss @@ -0,0 +1,62 @@ +.woocommerce-order-attribution-install-banner { + + margin: 0 15px 10px 0; + animation: isLoaded; + animation-duration: 250ms; + + &.components-card { + box-shadow: none; + border: 1px solid $table-border; + border-radius: 8px; + } + + .woocommerce-order-attribution-install-banner__body { + display: flex; + align-items: center; + + @media (max-width: $break-small) { + flex-direction: column; + } + } + + .woocommerce-order-attribution-install-banner__image_container { + display: flex; + padding-left: 15px; + } + + .woocommerce-order-attribution-install-banner__text_container { + margin-inline: 24px; + + > * { + margin-block: 1rem; + } + + p { + margin-block: 0.1rem; + } + } + + .woocommerce-order-attribution-install-banner__text-badge { + display: inline-flex; + justify-content: center; + background: $studio-gray-0; + border-radius: 2px; + padding: 2px 5px; + + p { + color: $studio-gray-80; + } + } + + .woocommerce-order-attribution-install-banner__text-title { + color: $studio-gray-90; + line-height: 24px; + font-weight: 600; + } + + .woocommerce-order-attribution-install-banner__text-description { + color: $studio-gray-90; + line-height: 16px; + max-width: 580px; + } +} diff --git a/plugins/woocommerce-admin/client/order-attribution-install-banner/use-order-attribution-install-banner.js b/plugins/woocommerce-admin/client/order-attribution-install-banner/use-order-attribution-install-banner.js new file mode 100644 index 00000000000..38a6d0f839d --- /dev/null +++ b/plugins/woocommerce-admin/client/order-attribution-install-banner/use-order-attribution-install-banner.js @@ -0,0 +1,75 @@ +/** + * External dependencies + */ +import { useDispatch, useSelect } from '@wordpress/data'; +import { + OPTIONS_STORE_NAME, + PLUGINS_STORE_NAME, + useUser, +} from '@woocommerce/data'; +import { recordEvent } from '@woocommerce/tracks'; +import { getPath } from '@woocommerce/navigation'; + +const OPTION_NAME_BANNER_DISMISSED = + 'woocommerce_order_attribution_install_banner_dismissed'; +const OPTION_VALUE_YES = 'yes'; + +/** + * A utility hook designed specifically for the order attribution install banner, + * which determines if the banner should be displayed, checks if it has been dismissed, and provides a function to dismiss it. + */ +const useOrderAttributionInstallBanner = () => { + const { updateOptions } = useDispatch( OPTIONS_STORE_NAME ); + const { currentUserCan } = useUser(); + + const dismiss = ( eventContext = 'analytics-overview' ) => { + updateOptions( { + [ OPTION_NAME_BANNER_DISMISSED ]: OPTION_VALUE_YES, + } ); + recordEvent( 'order_attribution_install_banner_dismissed', { + path: getPath(), + context: eventContext, + } ); + }; + + const { canUserInstallPlugins, orderAttributionInstallState } = useSelect( + ( select ) => { + const { getPluginInstallState } = select( PLUGINS_STORE_NAME ); + const installState = getPluginInstallState( + 'woocommerce-analytics' + ); + + return { + orderAttributionInstallState: installState, + canUserInstallPlugins: currentUserCan( 'install_plugins' ), + }; + }, + [ currentUserCan ] + ); + + const { loading, isBannerDismissed } = useSelect( ( select ) => { + const { getOption, hasFinishedResolution } = + select( OPTIONS_STORE_NAME ); + + return { + loading: ! hasFinishedResolution( 'getOption', [ + OPTION_NAME_BANNER_DISMISSED, + ] ), + isBannerDismissed: getOption( OPTION_NAME_BANNER_DISMISSED ), + }; + }, [] ); + + return { + loading, + isDismissed: isBannerDismissed === OPTION_VALUE_YES, + dismiss, + shouldShowBanner: + ! loading && + canUserInstallPlugins && + ! [ 'installed', 'activated' ].includes( + orderAttributionInstallState + ), + }; +}; + +export default useOrderAttributionInstallBanner; diff --git a/plugins/woocommerce/src/Admin/API/Options.php b/plugins/woocommerce/src/Admin/API/Options.php index 836886fec81..ae6a64fafd9 100644 --- a/plugins/woocommerce/src/Admin/API/Options.php +++ b/plugins/woocommerce/src/Admin/API/Options.php @@ -223,6 +223,7 @@ class Options extends \WC_REST_Data_Controller { 'woocommerce_private_link', 'woocommerce_share_key', 'woocommerce_show_lys_tour', + 'woocommerce_order_attribution_install_banner_dismissed', // WC Test helper options. 'wc-admin-test-helper-rest-api-filters', 'wc_admin_helper_feature_values',