2024-06-18 12:16:16 +00:00
/* eslint-disable @woocommerce/dependency-group */
/* eslint-disable @typescript-eslint/ban-ts-comment */
/ * *
* External dependencies
* /
import {
Button ,
CheckboxControl ,
// @ts-ignore No types for this exist yet.
__experimentalItemGroup as ItemGroup ,
Modal ,
// @ts-ignore No types for this exist yet.
__experimentalNavigatorButton as NavigatorButton ,
// @ts-ignore No types for this exist yet.
} from '@wordpress/components' ;
import {
createInterpolateElement ,
useContext ,
2024-06-20 11:35:42 +00:00
useMemo ,
2024-06-18 12:16:16 +00:00
useState ,
} from '@wordpress/element' ;
import { __ } from '@wordpress/i18n' ;
import interpolateComponents from '@automattic/interpolate-components' ;
2024-06-20 11:35:42 +00:00
import {
store as coreStore ,
// @ts-expect-error No types for this exist yet.
} from '@wordpress/core-data' ;
2024-06-18 12:16:16 +00:00
// @ts-expect-error Missing type.
import SidebarNavigationItem from '@wordpress/edit-site/build-module/components/sidebar-navigation-item' ;
/ * *
* Internal dependencies
* /
import { ADMIN_URL } from '~/utils/admin-settings' ;
2024-07-15 12:02:56 +00:00
import { SidebarNavigationScreen } from '../sidebar-navigation-screen' ;
2024-06-18 12:16:16 +00:00
import { trackEvent } from '~/customize-store/tracking' ;
2024-07-15 12:02:56 +00:00
import { CustomizeStoreContext } from '../..' ;
2024-06-18 12:16:16 +00:00
import { Link } from '@woocommerce/components' ;
2024-07-15 12:02:56 +00:00
import { PATTERN_CATEGORIES } from '../pattern-screen/categories' ;
2024-06-18 12:16:16 +00:00
import { capitalize } from 'lodash' ;
2024-07-02 08:03:56 +00:00
import { getNewPath , navigateTo , useQuery } from '@woocommerce/navigation' ;
2024-06-18 12:16:16 +00:00
import { useSelect } from '@wordpress/data' ;
import { useNetworkStatus } from '~/utils/react-hooks/use-network-status' ;
import { isIframe , sendMessageToParent } from '~/customize-store/utils' ;
2024-07-15 12:02:56 +00:00
import { useEditorBlocks } from '../../hooks/use-editor-blocks' ;
import { isTrackingAllowed } from '../../utils/is-tracking-allowed' ;
2024-07-02 08:03:56 +00:00
import clsx from 'clsx' ;
2024-07-15 12:02:56 +00:00
import './style.scss' ;
2024-07-23 19:03:26 +00:00
import { usePatterns } from '~/customize-store/assembler-hub/hooks/use-patterns' ;
import { THEME_SLUG } from '~/customize-store/data/constants' ;
2024-07-02 08:03:56 +00:00
const isActiveElement = ( path : string | undefined , category : string ) = > {
if ( path ? . includes ( category ) ) {
return true ;
}
} ;
2024-06-18 12:16:16 +00:00
export const SidebarNavigationScreenHomepagePTK = ( {
onNavigateBackClick ,
} : {
onNavigateBackClick : ( ) = > void ;
} ) = > {
const { context , sendEvent } = useContext ( CustomizeStoreContext ) ;
const isNetworkOffline = useNetworkStatus ( ) ;
const isPTKPatternsAPIAvailable = context . isPTKPatternsAPIAvailable ;
2024-06-20 11:35:42 +00:00
const currentTemplate = useSelect (
( sel ) = >
// @ts-expect-error No types for this exist yet.
sel ( coreStore ) . __experimentalGetTemplateForLink ( '/' ) ,
[ ]
) ;
const [ blocks ] = useEditorBlocks (
'wp_template' ,
currentTemplate ? . id ? ? ''
) ;
const numberOfPatternsAdded = useMemo ( ( ) = > {
const categories = Object . keys ( PATTERN_CATEGORIES ) ;
const initialAccumulator = categories . reduce (
( acc , cat ) = > ( {
. . . acc ,
[ cat ] : 0 ,
} ) ,
{ } as Record < string , number >
) ;
return blocks . reduce ( ( acc , block ) = > {
const blockCategories : Array < string > =
block . attributes ? . metadata ? . categories ? ? [ ] ;
const foundCategory = blockCategories . find ( ( blockCategory ) = >
categories . includes ( blockCategory )
) ;
if ( foundCategory ) {
return {
. . . acc ,
[ foundCategory ] : acc [ foundCategory ] + 1 ,
} ;
}
return acc ;
} , initialAccumulator ) ;
} , [ blocks ] ) ;
2024-07-23 19:03:26 +00:00
const { blockPatterns , isLoading : isLoadingPatterns } = usePatterns ( ) ;
const patternsFromPTK = blockPatterns . filter (
( pattern ) = >
! pattern . name . includes ( THEME_SLUG ) &&
! pattern . name . includes ( 'woocommerce' ) &&
pattern . source !== 'core' &&
pattern . source !== 'pattern-directory/featured' &&
pattern . source !== 'pattern-directory/theme' &&
pattern . source !== 'pattern-directory/core'
) ;
2024-06-18 12:16:16 +00:00
let notice ;
if ( isNetworkOffline ) {
notice = __ (
"Looks like we can't detect your network. Please double-check your internet connection and refresh the page." ,
'woocommerce'
) ;
} else if ( ! isPTKPatternsAPIAvailable ) {
notice = __ (
"Unfortunately, we're experiencing some technical issues — please come back later to access more patterns." ,
'woocommerce'
) ;
2024-06-28 09:38:27 +00:00
} else if ( ! isTrackingAllowed ( ) ) {
2024-06-18 12:16:16 +00:00
notice = __ (
'Opt in to <OptInModal>usage tracking</OptInModal> to get access to more patterns.' ,
'woocommerce'
) ;
2024-07-23 19:03:26 +00:00
} else if ( ! isLoadingPatterns && patternsFromPTK . length === 0 ) {
notice = __ (
'Unfortunately, a technical issue is preventing more patterns from being displayed. Please <FetchPatterns>try again</FetchPatterns> later.' ,
'woocommerce'
) ;
2024-06-18 12:16:16 +00:00
}
const [ isModalOpen , setIsModalOpen ] = useState ( false ) ;
const openModal = ( ) = > setIsModalOpen ( true ) ;
const closeModal = ( ) = > setIsModalOpen ( false ) ;
const [ optInDataSharing , setIsOptInDataSharing ] =
useState < boolean > ( true ) ;
const optIn = ( ) = > {
trackEvent (
'customize_your_store_assembler_hub_opt_in_usage_tracking'
) ;
} ;
const skipOptIn = ( ) = > {
trackEvent (
'customize_your_store_assembler_hub_skip_opt_in_usage_tracking'
) ;
} ;
2024-06-27 09:50:45 +00:00
const title = __ ( 'Design your homepage' , 'woocommerce' ) ;
const sidebarMessage = __ (
'Create an engaging homepage by adding and combining different patterns and layouts. You can continue customizing this page, including the content, later via the <EditorLink>Editor</EditorLink>.' ,
'woocommerce'
) ;
2024-06-18 12:16:16 +00:00
2024-07-02 08:03:56 +00:00
const path = useQuery ( ) . path ;
2024-06-18 12:16:16 +00:00
return (
< SidebarNavigationScreen
title = { title }
onNavigateBackClick = { onNavigateBackClick }
description = { createInterpolateElement ( sidebarMessage , {
EditorLink : (
< Link
onClick = { ( ) = > {
trackEvent (
'customize_your_store_assembler_hub_editor_link_click' ,
{
source : 'homepage' ,
}
) ;
window . open (
` ${ ADMIN_URL } site-editor.php ` ,
'_blank'
) ;
return false ;
} }
href = ""
/ >
) ,
} ) }
content = {
< div className = "woocommerce-customize-store__sidebar-homepage-content" >
< div className = "edit-site-sidebar-navigation-screen-patterns__group-homepage" >
{ Object . entries ( PATTERN_CATEGORIES ) . map (
( [ categoryKey , { label } ] , index ) = > (
< ItemGroup key = { index } >
< NavigatorButton
2024-07-02 08:03:56 +00:00
className = { clsx ( {
'edit-site-sidebar-navigation-screen-patterns__group-homepage-item--active' :
isActiveElement (
path ,
categoryKey
) ,
} ) }
2024-06-18 12:16:16 +00:00
path = { ` /customize-store/assembler-hub/homepage/ ${ categoryKey } ` }
onClick = { ( ) = > {
const categoryUrl = getNewPath (
{ customizing : true } ,
` /customize-store/assembler-hub/homepage/ ${ categoryKey } ` ,
{ }
) ;
2024-07-02 08:03:56 +00:00
navigateTo ( {
url : categoryUrl ,
} ) ;
2024-07-16 11:24:55 +00:00
trackEvent (
'customize_your_store_assembler_pattern_category_click' ,
{ category : categoryKey }
) ;
2024-06-18 12:16:16 +00:00
} }
as = { SidebarNavigationItem }
withChevron
>
2024-06-20 11:35:42 +00:00
< div className = "edit-site-sidebar-navigation-screen-patterns__group-homepage-label-container" >
< span > { capitalize ( label ) } < / span >
{ blocks . length > 0 &&
numberOfPatternsAdded [
categoryKey
] > 0 && (
< span className = "edit-site-sidebar-navigation-screen-patterns__group-homepage-number-pattern" >
{
numberOfPatternsAdded [
categoryKey
]
}
< / span >
) }
< / div >
2024-06-18 12:16:16 +00:00
< / NavigatorButton >
< / ItemGroup >
)
) }
{ notice && (
< div className = "woocommerce-customize-store_sidebar-patterns-upgrade-notice" >
< h4 >
{ __ (
'Want more patterns?' ,
'woocommerce'
) }
< / h4 >
< p >
{ createInterpolateElement ( notice , {
OptInModal : (
< Button
onClick = { ( ) = > {
openModal ( ) ;
} }
variant = "link"
/ >
) ,
2024-07-23 19:03:26 +00:00
FetchPatterns : (
< Button
onClick = { ( ) = > {
if ( isIframe ( window ) ) {
sendMessageToParent ( {
type : 'INSTALL_PATTERNS' ,
} ) ;
} else {
sendEvent (
'INSTALL_PATTERNS'
) ;
}
} }
variant = "link"
/ >
) ,
2024-06-18 12:16:16 +00:00
} ) }
< / p >
{ isModalOpen && (
< Modal
className = {
'woocommerce-customize-store__opt-in-usage-tracking-modal'
}
title = { __ (
2024-07-24 12:55:25 +00:00
'Access more patterns' ,
2024-06-18 12:16:16 +00:00
'woocommerce'
) }
onRequestClose = { closeModal }
shouldCloseOnClickOutside = { false }
>
< CheckboxControl
className = "core-profiler__checkbox"
label = { interpolateComponents ( {
mixedString : __ (
2024-07-24 12:55:25 +00:00
'More patterns from the WooCommerce.com library are available! Opt in to connect your store and access the full library, plus get more relevant content and a tailored store setup experience. Opting in will enable {{link}}usage tracking{{/link}}, which you can opt out of at any time via WooCommerce settings.' ,
2024-06-18 12:16:16 +00:00
'woocommerce'
) ,
components : {
link : (
< Link
href = "https://woocommerce.com/usage-tracking?utm_medium=product"
target = "_blank"
type = "external"
/ >
) ,
} ,
} ) }
checked = { optInDataSharing }
onChange = { setIsOptInDataSharing }
/ >
< div className = "woocommerce-customize-store__design-change-warning-modal-footer" >
< Button
onClick = { ( ) = > {
skipOptIn ( ) ;
closeModal ( ) ;
} }
variant = "link"
>
{ __ (
'Cancel' ,
'woocommerce'
) }
< / Button >
< Button
onClick = { ( ) = > {
optIn ( ) ;
if ( isIframe ( window ) ) {
sendMessageToParent ( {
type : 'INSTALL_PATTERNS' ,
} ) ;
} else {
sendEvent (
'INSTALL_PATTERNS'
) ;
}
} }
variant = "primary"
disabled = { ! optInDataSharing }
>
{ __ (
'Opt in' ,
'woocommerce'
) }
< / Button >
< / div >
< / Modal >
) }
< / div >
) }
< / div >
< / div >
}
/ >
) ;
} ;