2023-09-19 05:54:19 +00:00
/* eslint-disable @woocommerce/dependency-group */
/* eslint-disable @typescript-eslint/ban-ts-comment */
2023-08-28 01:28:05 +00:00
/ * *
* External dependencies
* /
import { __ } from '@wordpress/i18n' ;
2023-09-19 05:54:19 +00:00
import {
useCallback ,
useMemo ,
2023-10-02 08:28:13 +00:00
useEffect ,
2024-02-14 08:07:55 +00:00
useContext ,
2023-09-19 05:54:19 +00:00
} from '@wordpress/element' ;
2024-07-19 12:26:24 +00:00
import { Spinner } from '@wordpress/components' ;
2024-05-08 07:36:45 +00:00
// @ts-expect-error Missing type.
import { unlock } from '@wordpress/edit-site/build-module/lock-unlock' ;
2024-02-29 14:32:44 +00:00
// @ts-expect-error No types for this exist yet.
import { store as coreStore } from '@wordpress/core-data' ;
2024-05-08 07:36:45 +00:00
import {
__experimentalBlockPatternsList as BlockPatternList ,
2024-05-28 06:55:14 +00:00
store as blockEditorStore ,
2024-05-08 07:36:45 +00:00
// @ts-expect-error No types for this exist yet.
} from '@wordpress/block-editor' ;
2024-03-20 13:28:56 +00:00
// @ts-expect-error Missing type in core-data.
import { useIsSiteEditorLoading } from '@wordpress/edit-site/build-module/components/layout/hooks' ;
2023-09-19 03:37:46 +00:00
2023-08-28 01:28:05 +00:00
/ * *
* Internal dependencies
* /
2024-07-22 13:46:11 +00:00
import { SidebarNavigationScreen } from '../sidebar-navigation-screen' ;
import { useEditorBlocks } from '../../hooks/use-editor-blocks' ;
import { useHomeTemplates } from '../../hooks/use-home-templates' ;
2023-09-19 05:54:19 +00:00
import { BlockInstance } from '@wordpress/blocks' ;
2024-07-22 13:46:11 +00:00
import { useSelectedPattern } from '../../hooks/use-selected-pattern' ;
import { useEditorScroll } from '../../hooks/use-editor-scroll' ;
2024-02-14 08:07:55 +00:00
import { FlowType } from '~/customize-store/types' ;
import { CustomizeStoreContext } from '~/customize-store/assembler-hub' ;
2024-06-24 12:43:26 +00:00
import { select , useSelect } from '@wordpress/data' ;
2024-05-08 07:36:45 +00:00
import {
PRODUCT_HERO_PATTERN_BUTTON_STYLE ,
2024-07-19 10:15:10 +00:00
findButtonBlockInsideCoverBlockWithBlackBackgroundPatternAndUpdate ,
2024-07-22 13:46:11 +00:00
} from '../../utils/black-background-pattern-update-button' ;
import { useIsActiveNewNeutralVariation } from '../../hooks/use-is-active-new-neutral-variation' ;
import './style.scss' ;
2023-08-28 01:28:05 +00:00
2024-06-11 13:26:04 +00:00
export const SidebarNavigationScreenHomepage = ( {
onNavigateBackClick ,
} : {
onNavigateBackClick : ( ) = > void ;
} ) = > {
2023-10-26 10:15:30 +00:00
const { scroll } = useEditorScroll ( {
editorSelector : '.woocommerce-customize-store__block-editor iframe' ,
scrollDirection : 'top' ,
} ) ;
2023-09-19 05:54:19 +00:00
const { isLoading , homeTemplates } = useHomeTemplates ( ) ;
2023-10-02 08:28:13 +00:00
// eslint-disable-next-line react-hooks/exhaustive-deps
const { selectedPattern , setSelectedPattern } = useSelectedPattern ( ) ;
2023-09-19 05:54:19 +00:00
2024-02-29 14:32:44 +00:00
const currentTemplate = useSelect (
2024-05-28 07:32:26 +00:00
( sel ) = >
2024-02-29 14:32:44 +00:00
// @ts-expect-error No types for this exist yet.
2024-05-28 07:32:26 +00:00
sel ( coreStore ) . __experimentalGetTemplateForLink ( '/' ) ,
2024-02-29 14:32:44 +00:00
[ ]
) ;
const [ blocks , , onChange ] = useEditorBlocks (
'wp_template' ,
2024-06-07 09:38:46 +00:00
currentTemplate ? . id ? ? ''
2024-02-29 14:32:44 +00:00
) ;
2024-05-28 06:55:14 +00:00
2023-09-19 05:54:19 +00:00
const onClickPattern = useCallback (
2023-10-02 08:28:13 +00:00
( pattern , selectedBlocks ) = > {
2024-03-20 13:28:56 +00:00
if ( pattern === selectedPattern ) {
return ;
}
2023-10-02 08:28:13 +00:00
setSelectedPattern ( pattern ) ;
2023-09-19 05:54:19 +00:00
onChange (
[ blocks [ 0 ] , . . . selectedBlocks , blocks [ blocks . length - 1 ] ] ,
{ selection : { } }
) ;
2023-10-26 10:15:30 +00:00
scroll ( ) ;
2023-09-19 05:54:19 +00:00
} ,
2024-06-24 12:43:26 +00:00
[ selectedPattern , setSelectedPattern , onChange , blocks , scroll ]
2023-09-19 05:54:19 +00:00
) ;
2024-03-20 13:28:56 +00:00
const isEditorLoading = useIsSiteEditorLoading ( ) ;
2024-07-05 12:41:27 +00:00
const isActiveNewNeutralVariation = useIsActiveNewNeutralVariation ( ) ;
2024-05-08 07:36:45 +00:00
2023-09-19 05:54:19 +00:00
const homePatterns = useMemo ( ( ) = > {
return Object . entries ( homeTemplates ) . map (
( [ templateName , patterns ] ) = > {
2024-05-08 07:36:45 +00:00
if ( templateName === 'template1' ) {
return {
name : templateName ,
title : templateName ,
blocks : patterns.reduce (
( acc : BlockInstance [ ] , pattern ) = > {
2024-05-28 07:32:26 +00:00
const parsedPattern = unlock (
select ( blockEditorStore )
) . __experimentalGetParsedPattern (
pattern . name
) ;
if ( ! parsedPattern ) {
return acc ;
}
2024-05-08 07:36:45 +00:00
if ( ! isActiveNewNeutralVariation ) {
2024-07-19 10:15:10 +00:00
const updatedBlocks =
findButtonBlockInsideCoverBlockWithBlackBackgroundPatternAndUpdate (
parsedPattern . blocks ,
(
buttonBlocks : BlockInstance [ ]
) = > {
buttonBlocks . forEach (
( buttonBlock ) = > {
buttonBlock . attributes . style =
{ } ;
}
) ;
}
) ;
return [ . . . acc , . . . updatedBlocks ] ;
2024-05-08 07:36:45 +00:00
}
const updatedBlocks =
2024-07-19 10:15:10 +00:00
findButtonBlockInsideCoverBlockWithBlackBackgroundPatternAndUpdate (
2024-05-28 07:32:26 +00:00
parsedPattern . blocks ,
2024-07-19 10:15:10 +00:00
( buttonBlocks : BlockInstance [ ] ) = > {
buttonBlocks . forEach (
( buttonBlock ) = > {
buttonBlock . attributes . style =
PRODUCT_HERO_PATTERN_BUTTON_STYLE ;
}
) ;
2024-05-08 07:36:45 +00:00
}
) ;
return [ . . . acc , . . . updatedBlocks ] ;
} ,
[ ]
) ,
blockTypes : [ '' ] ,
categories : [ '' ] ,
content : '' ,
source : '' ,
} ;
}
2023-09-19 05:54:19 +00:00
return {
name : templateName ,
2023-10-02 08:28:13 +00:00
title : templateName ,
2023-09-19 05:54:19 +00:00
blocks : patterns.reduce (
2024-05-28 07:32:26 +00:00
( acc : BlockInstance [ ] , pattern ) = > {
const parsedPattern = unlock (
select ( blockEditorStore )
) . __experimentalGetParsedPattern ( pattern . name ) ;
2024-05-28 08:16:25 +00:00
if ( ! parsedPattern ) {
return acc ;
}
2024-05-28 07:32:26 +00:00
return [ . . . acc , . . . parsedPattern . blocks ] ;
} ,
2023-09-19 05:54:19 +00:00
[ ]
) ,
2023-10-02 08:28:13 +00:00
blockTypes : [ '' ] ,
categories : [ '' ] ,
content : '' ,
source : '' ,
2023-09-19 05:54:19 +00:00
} ;
}
) ;
2024-05-08 07:36:45 +00:00
} , [ homeTemplates , isActiveNewNeutralVariation ] ) ;
2023-09-19 05:54:19 +00:00
2023-10-02 08:28:13 +00:00
useEffect ( ( ) = > {
2024-04-08 10:43:41 +00:00
if (
selectedPattern ||
! blocks . length ||
! homePatterns . length ||
isLoading ||
isEditorLoading
) {
2023-10-02 08:28:13 +00:00
return ;
}
2024-03-05 17:21:44 +00:00
const currentSelectedPattern = homePatterns . find ( ( patterns ) = > {
//'blocks' contains all blocks in the template, including the
// header and footer blocks, while the 'patterns.blocks' does
// not. For that reason we are removing the first and last
// blocks from the 'blocks' to be able to compare then
const homeBlocks = blocks . slice ( 1 , blocks . length - 1 ) ;
2023-10-26 10:15:30 +00:00
2024-03-05 17:21:44 +00:00
if ( patterns . blocks . length !== homeBlocks . length ) {
return false ;
}
return homeBlocks . every (
( block , i ) = > block . name === patterns . blocks [ i ] . name
) ;
} ) ;
setSelectedPattern ( currentSelectedPattern ) ;
2023-10-02 08:28:13 +00:00
// eslint-disable-next-line react-hooks/exhaustive-deps -- we don't want to re-run this effect when currentSelectedPattern changes
2024-04-08 10:43:41 +00:00
} , [ blocks , homePatterns , isLoading , isEditorLoading ] ) ;
2023-10-02 08:28:13 +00:00
2024-07-19 12:26:24 +00:00
const { context } = useContext ( CustomizeStoreContext ) ;
2024-02-22 08:48:49 +00:00
const aiOnline = context . flowType === FlowType . AIOnline ;
const title = aiOnline
? __ ( 'Change your homepage' , 'woocommerce' )
2024-02-26 09:15:02 +00:00
: __ ( 'Choose your homepage' , 'woocommerce' ) ;
2024-02-22 08:48:49 +00:00
const sidebarMessage = aiOnline
? __ (
2024-08-07 14:16:42 +00:00
'Based on the most successful stores in your industry and location, our AI tool has recommended this template for your business. Prefer a different layout? Choose from the templates below now, or later via the Editor.' ,
2024-02-22 08:48:49 +00:00
'woocommerce'
)
: __ (
2024-08-07 14:16:42 +00:00
'Create an engaging homepage by selecting one of our pre-designed layouts. You can continue customizing this page, including the content, later via the Editor.' ,
2024-02-22 08:48:49 +00:00
'woocommerce'
) ;
2024-02-14 08:07:55 +00:00
2023-08-28 01:28:05 +00:00
return (
< SidebarNavigationScreen
2024-02-22 08:48:49 +00:00
title = { title }
2024-06-11 13:26:04 +00:00
onNavigateBackClick = { onNavigateBackClick }
2024-08-07 14:16:42 +00:00
description = { sidebarMessage }
2023-08-28 01:28:05 +00:00
content = {
2023-09-19 05:54:19 +00:00
< div className = "woocommerce-customize-store__sidebar-homepage-content" >
< div className = "edit-site-sidebar-navigation-screen-patterns__group-homepage" >
2024-03-20 13:28:56 +00:00
{ /* This is necessary to fix this issue: https:/ / github . com / woocommerce / woocommerce / issues / 45711
If the user switch the homepage while the editor is loading , header and footer could disappear .
For more details check : https : //github.com/woocommerce/woocommerce/pull/45735
* / }
{ isLoading || isEditorLoading ? (
2023-09-19 05:54:19 +00:00
< span className = "components-placeholder__preview" >
< Spinner / >
< / span >
) : (
< BlockPatternList
shownPatterns = { homePatterns }
blockPatterns = { homePatterns }
onClickPattern = { onClickPattern }
2023-09-25 10:30:31 +00:00
label = { 'Homepage' }
2023-09-19 05:54:19 +00:00
orientation = "vertical"
category = { 'homepage' }
isDraggable = { false }
2023-10-26 10:15:30 +00:00
showTitlesAsTooltip = { false }
2023-09-19 05:54:19 +00:00
/ >
) }
< / div >
< / div >
2023-08-28 01:28:05 +00:00
}
/ >
) ;
} ;