From a04395d47ca0b46e0f5406cf59336e86b05189d2 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Mon, 1 Apr 2024 16:45:25 +0530 Subject: [PATCH 1/4] Sitegen: Refactor Error State --- src/OnboardingSPA/components/App/index.js | 11 +- .../Step/SiteGen}/contents.js | 1 + .../Step/SiteGen}/index.js | 43 +-- .../Step/SiteGen}/stylesheet.scss | 0 .../SiteGenHeader/step-navigation.js | 64 ++--- .../components/ImageUploaderWithText/index.js | 91 ++----- .../components/ImageUploaderWithText/utils.js | 52 ++++ .../NewfoldInterfaceSkeleton/SiteGen/index.js | 251 ++++++++++-------- .../{SitegenAi => SiteGen}/contents.js | 0 .../{SitegenAi => SiteGen}/index.js | 19 +- .../components/StateHandlers/index.js | 2 + .../steps/SiteGen/Experience/index.js | 37 ++- .../steps/SiteGen/Preview/index.js | 56 ++-- .../steps/SiteGen/SiteDetails/index.js | 63 +++-- .../steps/SiteGen/SiteLogo/index.js | 60 +++-- .../steps/SiteGen/SocialMedia/index.js | 60 +++-- src/OnboardingSPA/styles/app.scss | 2 +- src/OnboardingSPA/utils/api/siteGen.js | 20 +- 18 files changed, 460 insertions(+), 372 deletions(-) rename src/OnboardingSPA/components/{SiteGenError => ErrorState/Step/SiteGen}/contents.js (98%) rename src/OnboardingSPA/components/{SiteGenError => ErrorState/Step/SiteGen}/index.js (88%) rename src/OnboardingSPA/components/{SiteGenError => ErrorState/Step/SiteGen}/stylesheet.scss (100%) create mode 100644 src/OnboardingSPA/components/ImageUploader/components/ImageUploaderWithText/utils.js rename src/OnboardingSPA/components/StateHandlers/{SitegenAi => SiteGen}/contents.js (100%) rename src/OnboardingSPA/components/StateHandlers/{SitegenAi => SiteGen}/index.js (76%) diff --git a/src/OnboardingSPA/components/App/index.js b/src/OnboardingSPA/components/App/index.js index 042a7be14..0d7f40240 100644 --- a/src/OnboardingSPA/components/App/index.js +++ b/src/OnboardingSPA/components/App/index.js @@ -1,16 +1,11 @@ +// WordPress import { FullscreenMode } from '@wordpress/interface'; import { SlotFillProvider } from '@wordpress/components'; import { Fragment } from '@wordpress/element'; -import FlowStateHandler from '../StateHandlers/Flow'; +// Components +import { FlowStateHandler } from '../StateHandlers'; -/** - * Primary app that renders the . - * - * Is a child of the hash router and error boundary. - * - * @return {WPComponent} App Component - */ const App = () => { return ( diff --git a/src/OnboardingSPA/components/SiteGenError/contents.js b/src/OnboardingSPA/components/ErrorState/Step/SiteGen/contents.js similarity index 98% rename from src/OnboardingSPA/components/SiteGenError/contents.js rename to src/OnboardingSPA/components/ErrorState/Step/SiteGen/contents.js index 4581201b1..ee1df09aa 100644 --- a/src/OnboardingSPA/components/SiteGenError/contents.js +++ b/src/OnboardingSPA/components/ErrorState/Step/SiteGen/contents.js @@ -1,3 +1,4 @@ +// WordPress import { __ } from '@wordpress/i18n'; const getContents = () => { diff --git a/src/OnboardingSPA/components/SiteGenError/index.js b/src/OnboardingSPA/components/ErrorState/Step/SiteGen/index.js similarity index 88% rename from src/OnboardingSPA/components/SiteGenError/index.js rename to src/OnboardingSPA/components/ErrorState/Step/SiteGen/index.js index 788723f94..c95180184 100644 --- a/src/OnboardingSPA/components/SiteGenError/index.js +++ b/src/OnboardingSPA/components/ErrorState/Step/SiteGen/index.js @@ -1,24 +1,35 @@ +// WordPress import { useViewportMatch } from '@wordpress/compose'; import { useEffect } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; -import getContents from './contents'; import { Button, Fill } from '@wordpress/components'; -import { store as nfdOnboardingStore } from '../../store'; -import CommonLayout from '../Layouts/Common'; -import OrbAnimation from '../OrbAnimation'; -import { SITEGEN_FLOW, DEFAULT_FLOW } from '../../data/flows/constants'; -import { validateFlow } from '../../data/flows/utils'; -import { resolveGetDataForFlow } from '../../data/flows'; + +// Third-party import { useNavigate } from 'react-router-dom'; + +// Classes and functions +import getContents from './contents'; +import { validateFlow } from '../../../../data/flows/utils'; +import { resolveGetDataForFlow } from '../../../../data/flows'; + +// Components +import CommonLayout from '../../../Layouts/Common'; +import OrbAnimation from '../../../OrbAnimation'; + +// Misc +import { store as nfdOnboardingStore } from '../../../../store'; +import { SITEGEN_FLOW, DEFAULT_FLOW } from '../../../../data/flows/constants'; import { FOOTER_SITEGEN, FOOTER_END, HEADER_SITEGEN, pluginDashboardPage, -} from '../../../constants'; +} from '../../../../../constants'; -const SiteGenSiteError = () => { +const SiteGenStepErrorState = () => { const navigate = useNavigate(); + const isLargeViewport = useViewportMatch( 'small' ); + const { setIsHeaderEnabled, setSidebarActiveView, @@ -38,11 +49,11 @@ const SiteGenSiteError = () => { useEffect( () => { setHideFooterNav( true ); setIsHeaderEnabled( true ); - setSidebarActiveView( false ); setHeaderActiveView( HEADER_SITEGEN ); setIsHeaderNavigationEnabled( true ); setDrawerActiveView( false ); - } ); + setSidebarActiveView( false ); + }, [] ); const { brandConfig, currentData } = useSelect( ( select ) => { return { @@ -51,13 +62,10 @@ const SiteGenSiteError = () => { select( nfdOnboardingStore ).getCurrentOnboardingData(), }; } ); - const isLargeViewport = useViewportMatch( 'small' ); - const content = getContents(); const oldFlow = window.nfdOnboarding?.oldFlow ? window.nfdOnboarding.oldFlow : DEFAULT_FLOW; - const switchFlow = ( newFlow ) => { if ( ! validateFlow( brandConfig, newFlow ) ) { return false; @@ -77,15 +85,18 @@ const SiteGenSiteError = () => { currentData.activeFlow = newFlow; currentData.continueWithoutAi = true; setCurrentOnboardingData( currentData ); - updateSiteGenErrorStatus( false ); if ( SITEGEN_FLOW !== newFlow ) { updateInitialize( true ); } navigate( data.steps[ 1 ].path ); }; + const handleRetry = () => { updateSiteGenErrorStatus( false ); }; + + const content = getContents(); + return (
@@ -151,4 +162,4 @@ const SiteGenSiteError = () => { ); }; -export default SiteGenSiteError; +export default SiteGenStepErrorState; diff --git a/src/OnboardingSPA/components/SiteGenError/stylesheet.scss b/src/OnboardingSPA/components/ErrorState/Step/SiteGen/stylesheet.scss similarity index 100% rename from src/OnboardingSPA/components/SiteGenError/stylesheet.scss rename to src/OnboardingSPA/components/ErrorState/Step/SiteGen/stylesheet.scss diff --git a/src/OnboardingSPA/components/Header/components/SiteGenHeader/step-navigation.js b/src/OnboardingSPA/components/Header/components/SiteGenHeader/step-navigation.js index 78e54bbde..600d552b5 100644 --- a/src/OnboardingSPA/components/Header/components/SiteGenHeader/step-navigation.js +++ b/src/OnboardingSPA/components/Header/components/SiteGenHeader/step-navigation.js @@ -1,40 +1,39 @@ +// WordPress import { useSelect, useDispatch } from '@wordpress/data'; -import { useNavigate } from 'react-router-dom'; import { Icon, chevronLeft } from '@wordpress/icons'; import { __ } from '@wordpress/i18n'; -import { store as nfdOnboardingStore } from '../../../../store'; +// Third-party +import { useNavigate } from 'react-router-dom'; + +// Components import ButtonDark from '../../../Button/ButtonDark'; + +// Misc +import { store as nfdOnboardingStore } from '../../../../store'; import { stepSiteGenPreview } from '../../../../steps/SiteGen/Preview/step'; import { stepSiteGenSiteLogo } from '../../../../steps/SiteGen/SiteLogo/step'; -/** - * Back step Navigation button. - * - * @param {*} param0 - * - * @return {WPComponent} Back Component - */ -const Back = ( { path, showErrorDialog } ) => { - const { setNavErrorContinuePath, updateSiteGenErrorStatus } = - useDispatch( nfdOnboardingStore ); +const Back = ( { path } ) => { const { siteGenErrorStatus } = useSelect( ( select ) => { return { siteGenErrorStatus: select( nfdOnboardingStore ).getSiteGenErrorStatus(), }; } ); + + const { updateSiteGenErrorStatus } = useDispatch( nfdOnboardingStore ); + const navigate = useNavigate(); + const navigateBack = () => { - if ( siteGenErrorStatus === true ) { + if ( true === siteGenErrorStatus ) { updateSiteGenErrorStatus( false ); } - if ( showErrorDialog !== false ) { - setNavErrorContinuePath( path ); - } else { - navigate( path, { state: { origin: 'header' } } ); - } + + navigate( path, { state: { origin: 'header' } } ); }; + return ( @@ -43,35 +42,28 @@ const Back = ( { path, showErrorDialog } ) => { ); }; -/** - * Step buttons presented in Header. - * - * @return {WPComponent} StepNavigation Component - */ const StepNavigation = () => { - const { previousStep, currentStep, showErrorDialog } = useSelect( - ( select ) => { - return { - previousStep: select( nfdOnboardingStore ).getPreviousStep(), - currentStep: select( nfdOnboardingStore ).getCurrentStep(), - showErrorDialog: - select( nfdOnboardingStore ).getShowErrorDialog(), - }; - }, - [] - ); + const { previousStep, currentStep } = useSelect( ( select ) => { + return { + previousStep: select( nfdOnboardingStore ).getPreviousStep(), + currentStep: select( nfdOnboardingStore ).getCurrentStep(), + }; + }, [] ); + const isFirstStep = null === previousStep || false === previousStep; const isPreviewStep = currentStep.path === stepSiteGenPreview.path; + return (
- { isFirstStep ? null : ( + { isFirstStep ? ( + <> + ) : ( ) }
diff --git a/src/OnboardingSPA/components/ImageUploader/components/ImageUploaderWithText/index.js b/src/OnboardingSPA/components/ImageUploader/components/ImageUploaderWithText/index.js index 35b91c12c..587293281 100644 --- a/src/OnboardingSPA/components/ImageUploader/components/ImageUploaderWithText/index.js +++ b/src/OnboardingSPA/components/ImageUploader/components/ImageUploaderWithText/index.js @@ -1,87 +1,38 @@ +// WordPress import { __ } from '@wordpress/i18n'; - import { memo, useContext, useRef, useState } from '@wordpress/element'; +import { Icon, closeSmall } from '@wordpress/icons'; + +// Third-party +import classNames from 'classnames'; +import bytes from 'bytes'; + +// Classes and functions import { uploadImage } from '../../../../utils/api/uploader'; -import Spinner from '../../../Loaders/Spinner'; +import { getDominantColor, getContrastingColor } from './utils'; + +// Components import { ThemeContext } from '../../../ThemeContextProvider'; -import classNames from 'classnames'; +import Spinner from '../../../Loaders/Spinner'; + +// Misc import { THEME_LIGHT, THEME_DARK } from '../../../../../constants'; -import bytes from 'bytes'; -import { Icon, closeSmall } from '@wordpress/icons'; -import { store as nfdOnboardingStore } from '../../../../store'; -import { useDispatch } from '@wordpress/data'; -const ImageUploaderWithText = ( { image, imageSetter } ) => { +const ImageUploaderWithText = ( { image, imageSetter, onFailure } ) => { const inputRef = useRef( null ); const { theme } = useContext( ThemeContext ); const [ isUploading, setIsUploading ] = useState( false ); const [ onDragActive, setOnDragActive ] = useState( false ); const [ pngLogoBgTheme, setPngLogoBgTheme ] = useState( '' ); - const { updateSiteGenErrorStatus } = useDispatch( nfdOnboardingStore ); - - const getDominantColor = ( imageSrc, callback ) => { - // eslint-disable-next-line no-undef - const img = new Image(); - img.crossOrigin = 'Anonymous'; - /* Registering on load before src to so that event listener is ready capture when image loads */ - img.onload = () => { - const canvas = document.createElement( 'canvas' ); - const ctx = canvas.getContext( '2d' ); - canvas.width = img.width; - canvas.height = img.height; - ctx.drawImage( img, 0, 0 ); - const imageData = ctx.getImageData( - 0, - 0, - canvas.width, - canvas.height - ); - const data = imageData.data; - let r = 0, - g = 0, - b = 0, - count = 0; - - /* skip transparent areas as the 0 alpha value leads to lower rgb values even in white logos */ - for ( let i = 0; i < data.length; i += 4 ) { - const alpha = data[ i + 3 ]; - if ( alpha > 0 ) { - r += data[ i ]; - g += data[ i + 1 ]; - b += data[ i + 2 ]; - count++; - } - } - - /* Get the average rgb value of the image */ - if ( count > 0 ) { - // To avoid division by zero - r = Math.floor( r / count ); - g = Math.floor( g / count ); - b = Math.floor( b / count ); - } - - // Callback with the avrage dominant color - callback( `rgb(${ r }, ${ g }, ${ b })` ); - }; - img.src = imageSrc; - }; - - const getContrastingColor = ( color ) => { - /* if the contrast value more than 150 it should have black bg, otherwise white */ - const [ r, g, b ] = color.match( /\d+/g ).map( Number ); - const contrastValue = 0.2126 * r + 0.7152 * g + 0.0722 * b; - return contrastValue > 160 ? THEME_DARK : THEME_LIGHT; - }; - async function updateItem( fileData ) { if ( fileData ) { setIsUploading( true ); const res = await uploadImage( fileData ); if ( ! res?.body ) { - updateSiteGenErrorStatus( true ); - return setIsUploading( false ); + setIsUploading( false ); + handleFailure(); + return false; } const id = res.body?.id; const url = res.body?.source_url; @@ -104,6 +55,12 @@ const ImageUploaderWithText = ( { image, imageSetter } ) => { setIsUploading( false ); } + const handleFailure = () => { + if ( typeof onFailure === 'function' ) { + return onFailure(); + } + }; + const handleClick = () => { inputRef?.current.click(); }; diff --git a/src/OnboardingSPA/components/ImageUploader/components/ImageUploaderWithText/utils.js b/src/OnboardingSPA/components/ImageUploader/components/ImageUploaderWithText/utils.js new file mode 100644 index 000000000..f729a64f5 --- /dev/null +++ b/src/OnboardingSPA/components/ImageUploader/components/ImageUploaderWithText/utils.js @@ -0,0 +1,52 @@ +// Misc +import { THEME_LIGHT, THEME_DARK } from '../../../../../constants'; + +export const getDominantColor = ( imageSrc, callback ) => { + // eslint-disable-next-line no-undef + const img = new Image(); + img.crossOrigin = 'Anonymous'; + /* Registering on load before src to so that event listener is ready capture when image loads */ + img.onload = () => { + const canvas = document.createElement( 'canvas' ); + const ctx = canvas.getContext( '2d' ); + canvas.width = img.width; + canvas.height = img.height; + ctx.drawImage( img, 0, 0 ); + const imageData = ctx.getImageData( 0, 0, canvas.width, canvas.height ); + const data = imageData.data; + let r = 0, + g = 0, + b = 0, + count = 0; + + /* skip transparent areas as the 0 alpha value leads to lower rgb values even in white logos */ + for ( let i = 0; i < data.length; i += 4 ) { + const alpha = data[ i + 3 ]; + if ( alpha > 0 ) { + r += data[ i ]; + g += data[ i + 1 ]; + b += data[ i + 2 ]; + count++; + } + } + + /* Get the average rgb value of the image */ + if ( count > 0 ) { + // To avoid division by zero + r = Math.floor( r / count ); + g = Math.floor( g / count ); + b = Math.floor( b / count ); + } + + // Callback with the avrage dominant color + callback( `rgb(${ r }, ${ g }, ${ b })` ); + }; + img.src = imageSrc; +}; + +export const getContrastingColor = ( color ) => { + /* if the contrast value more than 150 it should have black bg, otherwise white */ + const [ r, g, b ] = color.match( /\d+/g ).map( Number ); + const contrastValue = 0.2126 * r + 0.7152 * g + 0.0722 * b; + return contrastValue > 160 ? THEME_DARK : THEME_LIGHT; +}; diff --git a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js index c30791eb9..bbdeaac5f 100644 --- a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js +++ b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js @@ -1,36 +1,44 @@ +// WordPress import { useEffect, useRef, useState } from '@wordpress/element'; import { store as coreStore } from '@wordpress/core-data'; -import { useLocation } from 'react-router-dom'; import { useSelect, useDispatch } from '@wordpress/data'; -import Header from '../../Header'; -import Content from '../../Content'; -import Sidebar from '../../Sidebar'; -import themeToggleHOC from '../themeToggleHOC'; -import NewfoldInterfaceSkeleton from '../index'; -import { ThemeProvider } from '../../ThemeContextProvider'; -import { store as nfdOnboardingStore } from '../../../store'; +// Third-party +import { useLocation } from 'react-router-dom'; import classNames from 'classnames'; + +// Classes and functions import { setFlow } from '../../../utils/api/flow'; +import themeToggleHOC from '../themeToggleHOC'; import { generateSiteGenMeta, getHomepages, getSiteGenIdentifiers, } from '../../../utils/api/siteGen'; -import Footer from '../../Footer'; import { initialize as initializeSettings } from '../../../utils/api/settings'; import { init as initializePlugins } from '../../../utils/api/plugins'; import { init as initializeThemes } from '../../../utils/api/themes'; import { trigger as cronTrigger } from '../../../utils/api/cronTrigger'; +import { + OnboardingEvent, + trackOnboardingEvent, +} from '../../../utils/analytics/hiive'; + +// Components +import Header from '../../Header'; +import Content from '../../Content'; +import Sidebar from '../../Sidebar'; +import Footer from '../../Footer'; +import NewfoldInterfaceSkeleton from '../index'; +import { ThemeProvider } from '../../ThemeContextProvider'; + +// Misc +import { store as nfdOnboardingStore } from '../../../store'; import { MAX_RETRIES_SITE_GEN, SKIP_FLOW_ERROR_CODE_DATABASE, SKIP_FLOW_ERROR_CODE_20, } from '../../../../constants'; -import { - OnboardingEvent, - trackOnboardingEvent, -} from '../../../utils/analytics/hiive'; import { ACTION_ONBOARDING_CHAPTER_COMPLETE, ACTION_ONBOARDING_CHAPTER_STARTED, @@ -46,8 +54,7 @@ const ThemedNewfoldInterfaceSkeleton = themeToggleHOC( ); const SiteGen = () => { - const [ failedApi, setFailedApi ] = useState( [] ); - const location = useLocation(); + const [ failedSiteMetaAPIs, setFailedSiteMetaAPIs ] = useState( [] ); const { currentData, @@ -81,33 +88,70 @@ const SiteGen = () => { setActiveChapter, } = useDispatch( nfdOnboardingStore ); - // Update Title and Tagline on the site. - const { editEntityRecord } = useDispatch( coreStore ); const { getEditedEntityRecord } = useSelect( ( select ) => { return select( coreStore ); }, [] ); + const { editEntityRecord } = useDispatch( coreStore ); + + const location = useLocation(); + const prevSiteGenErrorStatus = useRef(); + + useEffect( () => { + initializeThemes(); + initializeSettings(); + getEditedEntityRecord( 'root', 'site' ); + }, [] ); + useEffect( () => { document.body.classList.add( `nfd-brand-${ newfoldBrand }` ); }, [ newfoldBrand ] ); - const prevSiteGenErrorStatus = useRef(); + useEffect( () => { + trackChapters(); + }, [ currentStep ] ); + + useEffect( () => { + if ( initialize ) { + initializePlugins( pluginInstallHash ); + setInterval( cronTrigger, 45000 ); + } + }, [ initialize ] ); + + useEffect( () => { + syncStoreToDB(); + generateSiteGenData(); + handlePreviousStepTracking(); + }, [ location.pathname ] ); + + useEffect( () => { + if ( + prevSiteGenErrorStatus.current === true && + siteGenErrorStatus === false + ) { + generateSiteGenData(); + } + prevSiteGenErrorStatus.current = siteGenErrorStatus; + }, [ siteGenErrorStatus ] ); async function syncStoreToDB() { // The First Fork Step doesn't have any Store changes if ( currentData && location?.pathname !== stepTheFork.path ) { //Set the Flow Data and sync store and DB const result = await setFlow( currentData ); - if ( result?.error !== null ) { - switch ( result?.error.code ) { - case SKIP_FLOW_ERROR_CODE_DATABASE: - break; - case SKIP_FLOW_ERROR_CODE_20: - break; - default: - updateSiteGenErrorStatus( true ); - break; - } + if ( result.body !== null ) { + return true; + } + + switch ( result.error.code ) { + case SKIP_FLOW_ERROR_CODE_DATABASE: + case SKIP_FLOW_ERROR_CODE_20: + return true; + } + + if ( false === siteGenErrorStatus ) { + updateSiteGenErrorStatus( true ); + return false; } } } @@ -118,49 +162,13 @@ const SiteGen = () => { skipCache, retryCount = 1 ) { - try { - const data = await generateSiteGenMeta( - siteInfo, - identifier, - skipCache - ); - if ( data !== null ) { - // A Identifier request was sucessfuly made with valid response - currentData.sitegen.siteGenMetaStatus.currentStatus += 1; - if ( - currentData.sitegen.siteGenMetaStatus.currentStatus === - currentData.sitegen.siteGenMetaStatus.totalCount - ) { - // Once all requests are completed use cache to get data - currentData.sitegen.skipCache = false; - - // Increase count after site meta calls to ensure systematic call of homepages - currentData.sitegen.siteGenMetaStatus.totalCount += 1; - setCurrentOnboardingData( currentData ); - - // Get the homepages and set that in flow - getHomepages( currentData.sitegen.siteDetails.prompt ).then( - ( response ) => { - if ( response.body ) { - currentData.sitegen.homepages.data = - response.body; - } - currentData.sitegen.siteGenMetaStatus.currentStatus += 1; - } - ); - } - // Sync the current request changed to State - setCurrentOnboardingData( currentData ); - - // Sets the Site Title and Taglin in Live Preview - if ( identifier === 'site_config' ) { - editEntityRecord( 'root', 'site', undefined, { - title: data.site_title, - description: data.tagline, - } ); - } - } - } catch ( err ) { + const data = await generateSiteGenMeta( + siteInfo, + identifier, + skipCache + ); + + if ( data.error ) { // Check if it failed then retry again if ( retryCount < MAX_RETRIES_SITE_GEN ) { return performSiteGenMetaGeneration( @@ -172,25 +180,64 @@ const SiteGen = () => { } // If the retry also did not work show the error state - setFailedApi( ( prevState ) => { + setFailedSiteMetaAPIs( ( prevState ) => { // If the error doesn't exist add it to the Failed List if ( ! prevState.includes( identifier ) ) { return [ ...prevState, identifier ]; } + return prevState; } ); - // Activate the Error Page - currentData.sitegen.siteGenErrorStatus = true; - setCurrentOnboardingData( currentData ); + + if ( siteGenErrorStatus === false ) { + updateSiteGenErrorStatus( true ); + } + + if ( window.nfdOnboarding.siteGenTimerInterval ) { + clearInterval( window.nfdOnboarding.siteGenTimerInterval ); + } + + return; } - } - async function generateSiteGenData( forceRun = false ) { - // ForceRun tells us to bypass the page check or not - // because the requests failed on Logo step is retried in Experience step + // Sets the Site Title and Taglin in Live Preview + if ( identifier === 'site_config' ) { + editEntityRecord( 'root', 'site', undefined, { + title: data.body.site_title, + description: data.body.tagline, + } ); + } + + // A Identifier request was sucessfuly made with valid response + currentData.sitegen.siteGenMetaStatus.currentStatus += 1; + + if ( + currentData.sitegen.siteGenMetaStatus.currentStatus === + currentData.sitegen.siteGenMetaStatus.totalCount + ) { + // Once all requests are completed use cache to get data + currentData.sitegen.skipCache = false; + // Get the homepages and set that in flow + const response = await getHomepages( + currentData.sitegen.siteDetails.prompt + ); + + if ( response.body ) { + currentData.sitegen.homepages.data = response.body; + } + } + // Sync the current request changed to State + setCurrentOnboardingData( currentData ); + } + + async function generateSiteGenData() { // Start the API Requests when the loader is shown. - if ( ! location.pathname.includes( 'site-logo' ) && ! forceRun ) { + if ( + true === siteGenErrorStatus || + ( ! location.pathname.includes( 'site-logo' ) && + ! location.pathname.includes( 'experience' ) ) + ) { return; } @@ -210,9 +257,12 @@ const SiteGen = () => { } let identifiers; - if ( Array.isArray( failedApi ) && failedApi.length > 0 ) { - identifiers = failedApi; - setFailedApi( [] ); + if ( + Array.isArray( failedSiteMetaAPIs ) && + failedSiteMetaAPIs.length > 0 + ) { + identifiers = failedSiteMetaAPIs; + setFailedSiteMetaAPIs( [] ); } else { identifiers = await getSiteGenIdentifiers(); identifiers = identifiers.body; @@ -293,41 +343,6 @@ const SiteGen = () => { } }; - useEffect( () => { - trackChapters(); - }, [ currentStep ] ); - - useEffect( () => { - if ( initialize ) { - initializePlugins( pluginInstallHash ); - setInterval( cronTrigger, 45000 ); - } - }, [ initialize ] ); - - useEffect( () => { - syncStoreToDB(); - generateSiteGenData(); - handlePreviousStepTracking(); - }, [ location.pathname ] ); - - useEffect( () => { - if ( - prevSiteGenErrorStatus.current === true && - siteGenErrorStatus === false - ) { - generateSiteGenData( true ); - syncStoreToDB(); - } - prevSiteGenErrorStatus.current = siteGenErrorStatus; - }, [ siteGenErrorStatus ] ); - - useEffect( () => { - initializeThemes(); - initializeSettings(); - getEditedEntityRecord( 'root', 'site' ); - updateSiteGenErrorStatus( false ); - }, [] ); - return ( { +const SiteGenStateHandler = ( { children } ) => { const { siteGenErrorStatus } = useSelect( ( select ) => { return { siteGenErrorStatus: @@ -20,7 +25,7 @@ const SitegenAiStateHandler = ( { children } ) => { } ); useEffect( () => { - if ( siteGenErrorStatus === true ) { + if ( true === siteGenErrorStatus ) { trackOnboardingEvent( new OnboardingEvent( ACTION_SITEGEN_ERROR_STATE_TRIGGERED, @@ -35,7 +40,7 @@ const SitegenAiStateHandler = ( { children } ) => { const handleRender = () => { if ( siteGenErrorStatus ) { - return ; + return ; } return children; @@ -43,4 +48,4 @@ const SitegenAiStateHandler = ( { children } ) => { return { handleRender() }; }; -export default SitegenAiStateHandler; +export default SiteGenStateHandler; diff --git a/src/OnboardingSPA/components/StateHandlers/index.js b/src/OnboardingSPA/components/StateHandlers/index.js index b18f3eb9a..f4d0967be 100644 --- a/src/OnboardingSPA/components/StateHandlers/index.js +++ b/src/OnboardingSPA/components/StateHandlers/index.js @@ -1 +1,3 @@ export { default as DesignStateHandler } from './Design'; +export { default as FlowStateHandler } from './Flow'; +export { default as SiteGenStateHandler } from './SiteGen'; diff --git a/src/OnboardingSPA/steps/SiteGen/Experience/index.js b/src/OnboardingSPA/steps/SiteGen/Experience/index.js index 6be5ffaca..204f1318d 100644 --- a/src/OnboardingSPA/steps/SiteGen/Experience/index.js +++ b/src/OnboardingSPA/steps/SiteGen/Experience/index.js @@ -1,29 +1,36 @@ +// WordPress import { useSelect, useDispatch } from '@wordpress/data'; import { useEffect, useState } from '@wordpress/element'; +// Classes and functions import getContents from './contents'; -import { HEADER_SITEGEN } from '../../../../constants'; -import { store as nfdOnboardingStore } from '../../../store'; -import CommonLayout from '../../../components/Layouts/Common'; -import CardWithOptions from '../../../components/CardWithOptions'; -import SiteGenLoader from '../../../components/Loaders/SiteGenLoader'; -import SitegenAiStateHandler from '../../../components/StateHandlers/SitegenAi'; import { OnboardingEvent, trackOnboardingEvent, } from '../../../utils/analytics/hiive'; + +// Components +import CommonLayout from '../../../components/Layouts/Common'; +import CardWithOptions from '../../../components/CardWithOptions'; +import SiteGenLoader from '../../../components/Loaders/SiteGenLoader'; +import { SiteGenStateHandler } from '../../../components/StateHandlers'; + +// Misc +import { HEADER_SITEGEN } from '../../../../constants'; +import { store as nfdOnboardingStore } from '../../../store'; import { ACTION_EXPERIENCE_LEVEL_SET } from '../../../utils/analytics/hiive/constants'; import { SITEGEN_FLOW } from '../../../data/flows/constants'; const SiteGenExperience = () => { - const content = getContents(); // Index of the selection user makes const [ selection, setSelection ] = useState( 0 ); - const { currentData } = useSelect( ( select ) => { + const { currentData, siteGenErrorStatus } = useSelect( ( select ) => { return { currentData: select( nfdOnboardingStore ).getCurrentOnboardingData(), + siteGenErrorStatus: + select( nfdOnboardingStore ).getSiteGenErrorStatus(), }; } ); @@ -44,11 +51,17 @@ const SiteGenExperience = () => { setIsHeaderNavigationEnabled( false ); setHeaderActiveView( HEADER_SITEGEN ); setDrawerActiveView( false ); + }, [] ); + + useEffect( () => { + if ( true === siteGenErrorStatus ) { + return; + } if ( currentData.sitegen.experience?.level ) { setSelection( currentData.sitegen.experience.level ); } - } ); + }, [ siteGenErrorStatus ] ); const checkAndNavigate = ( idx ) => { // 0 - Not Selected @@ -83,8 +96,10 @@ const SiteGenExperience = () => { } }; + const content = getContents(); + return ( - +
{ />
-
+ ); }; diff --git a/src/OnboardingSPA/steps/SiteGen/Preview/index.js b/src/OnboardingSPA/steps/SiteGen/Preview/index.js index 41353b534..6887974b1 100644 --- a/src/OnboardingSPA/steps/SiteGen/Preview/index.js +++ b/src/OnboardingSPA/steps/SiteGen/Preview/index.js @@ -1,24 +1,30 @@ +// WordPress import { useEffect, useState, useRef } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; + +// Third-party import { useNavigate } from 'react-router-dom'; // eslint-disable-next-line import/no-extraneous-dependencies import { cloneDeep, isEmpty } from 'lodash'; -import CommonLayout from '../../../components/Layouts/Common'; -import { store as nfdOnboardingStore } from '../../../store'; -import { HEADER_SITEGEN } from '../../../../constants'; -import { SiteGenPreviewSelectableCard } from '../../../components/LivePreview'; +// Classes and functions import getContents from './contents'; -import HeartAnimation from './heartAnimation'; -import RegeneratingSiteCard from './regeneratingCard'; import { getHomepages, regenerateHomepage } from '../../../utils/api/siteGen'; import { getGlobalStyles } from '../../../utils/api/themes'; -import SitegenAiStateHandler from '../../../components/StateHandlers/SitegenAi'; -import Animate from '../../../components/Animate'; import { OnboardingEvent, trackOnboardingEvent, } from '../../../utils/analytics/hiive'; + +// Components +import CommonLayout from '../../../components/Layouts/Common'; +import { SiteGenPreviewSelectableCard } from '../../../components/LivePreview'; +import HeartAnimation from './heartAnimation'; +import RegeneratingSiteCard from './regeneratingCard'; +import Animate from '../../../components/Animate'; +import { SiteGenStateHandler } from '../../../components/StateHandlers'; + +// Misc import { ACTION_SITEGEN_HOMEPAGE_FAVORITED, ACTION_SITEGEN_HOMEPAGE_REGENERATED, @@ -26,28 +32,18 @@ import { ACTION_SITEGEN_SITE_GENERATION_TIME, } from '../../../utils/analytics/hiive/constants'; import { SITEGEN_FLOW } from '../../../data/flows/constants'; +import { store as nfdOnboardingStore } from '../../../store'; +import { HEADER_SITEGEN } from '../../../../constants'; const SiteGenPreview = () => { - const navigate = useNavigate(); const [ homepages, setHomepages ] = useState( false ); const [ isRegenerating, setIsRegenerating ] = useState( false ); const [ isPreviewLoading, setIsPreviewLoading ] = useState( false ); const [ globalStyles, setGlobalStyles ] = useState( false ); + const navigate = useNavigate(); const prevSiteGenErrorStatus = useRef(); - const { - setIsHeaderEnabled, - setSidebarActiveView, - setHeaderActiveView, - setDrawerActiveView, - setCurrentOnboardingData, - updateInitialize, - setHideFooterNav, - updateSiteGenErrorStatus, - setIsHeaderNavigationEnabled, - } = useDispatch( nfdOnboardingStore ); - const { currentData, nextStep, siteGenErrorStatus } = useSelect( ( select ) => { return { @@ -60,6 +56,18 @@ const SiteGenPreview = () => { } ); + const { + setIsHeaderEnabled, + setSidebarActiveView, + setHeaderActiveView, + setDrawerActiveView, + setCurrentOnboardingData, + updateInitialize, + setHideFooterNav, + updateSiteGenErrorStatus, + setIsHeaderNavigationEnabled, + } = useDispatch( nfdOnboardingStore ); + useEffect( () => { setIsHeaderEnabled( true ); setHideFooterNav( true ); @@ -68,7 +76,7 @@ const SiteGenPreview = () => { setDrawerActiveView( false ); updateInitialize( true ); setIsHeaderNavigationEnabled( false ); - }, [ currentData ] ); + }, [] ); useEffect( () => { if ( @@ -294,7 +302,7 @@ const SiteGenPreview = () => { const content = getContents(); return ( - +
{ ! isPreviewLoading && ( @@ -326,7 +334,7 @@ const SiteGenPreview = () => { { content.favouriteNote }
-
+ ); }; diff --git a/src/OnboardingSPA/steps/SiteGen/SiteDetails/index.js b/src/OnboardingSPA/steps/SiteGen/SiteDetails/index.js index de6343386..2b324d0ed 100644 --- a/src/OnboardingSPA/steps/SiteGen/SiteDetails/index.js +++ b/src/OnboardingSPA/steps/SiteGen/SiteDetails/index.js @@ -1,29 +1,34 @@ +// WordPress import { useViewportMatch } from '@wordpress/compose'; import { useSelect, useDispatch } from '@wordpress/data'; import { useEffect, useState } from '@wordpress/element'; +// Classes and functions +import { + OnboardingEvent, + trackOnboardingEvent, +} from '../../../utils/analytics/hiive'; import getContents from './contents'; + +// Components import Animate from '../../../components/Animate'; -import { HEADER_SITEGEN } from '../../../../constants'; -import { store as nfdOnboardingStore } from '../../../store'; import AIHeading from '../../../components/Heading/AIHeading'; import CommonLayout from '../../../components/Layouts/Common'; import TextInputSiteGen from '../../../components/TextInput/TextInputSiteGen'; import NextButtonSiteGen from '../../../components/Button/NextButtonSiteGen'; -import SitegenAiStateHandler from '../../../components/StateHandlers/SitegenAi'; -import { - OnboardingEvent, - trackOnboardingEvent, -} from '../../../utils/analytics/hiive'; +import { SiteGenStateHandler } from '../../../components/StateHandlers'; + +// Misc +import { HEADER_SITEGEN } from '../../../../constants'; +import { store as nfdOnboardingStore } from '../../../store'; import { ACTION_SITEGEN_SITE_DETAILS_PROMPT_SET } from '../../../utils/analytics/hiive/constants'; import { SITEGEN_FLOW } from '../../../data/flows/constants'; const SiteGenSiteDetails = () => { - const content = getContents(); - const isLargeViewport = useViewportMatch( 'small' ); const [ customerInput, setCustomerInput ] = useState(); const [ customerInputStrength, setCustomerInputStrength ] = useState( 0 ); const [ isValidInput, setIsValidInput ] = useState( false ); + const { currentData } = useSelect( ( select ) => { return { currentData: @@ -42,6 +47,8 @@ const SiteGenSiteDetails = () => { setIsHeaderNavigationEnabled, } = useDispatch( nfdOnboardingStore ); + const isLargeViewport = useViewportMatch( 'small' ); + useEffect( () => { setHideFooterNav( false ); setIsHeaderEnabled( true ); @@ -57,6 +64,23 @@ const SiteGenSiteDetails = () => { setIsFooterNavAllowed( false ); }, [] ); + useEffect( () => { + if ( + customerInput !== undefined && + customerInput !== '' && + customerInput !== currentData.sitegen.siteDetails.prompt + ) { + currentData.sitegen.siteDetails.prompt = customerInput?.trim(); + currentData.sitegen.siteDetails.mode = 'simple'; + currentData.sitegen.skipCache = true; + currentData.sitegen.sitemapPagesGenerated = false; + currentData.sitegen.homepages.active = {}; + currentData.sitegen.homepages.data = {}; + setCurrentOnboardingData( currentData ); + } + setIsFooterNavAllowed( isValidInput ); + }, [ customerInput ] ); + const trackPromptSetEvent = () => { let customerInputStrengthForEvent = false; switch ( customerInputStrength ) { @@ -82,25 +106,10 @@ const SiteGenSiteDetails = () => { } }; - useEffect( () => { - if ( - customerInput !== undefined && - customerInput !== '' && - customerInput !== currentData.sitegen.siteDetails.prompt - ) { - currentData.sitegen.siteDetails.prompt = customerInput?.trim(); - currentData.sitegen.siteDetails.mode = 'simple'; - currentData.sitegen.skipCache = true; - currentData.sitegen.sitemapPagesGenerated = false; - currentData.sitegen.homepages.active = {}; - currentData.sitegen.homepages.data = {}; - setCurrentOnboardingData( currentData ); - } - setIsFooterNavAllowed( isValidInput ); - }, [ customerInput ] ); + const content = getContents(); return ( - +
@@ -135,7 +144,7 @@ const SiteGenSiteDetails = () => {
-
+ ); }; diff --git a/src/OnboardingSPA/steps/SiteGen/SiteLogo/index.js b/src/OnboardingSPA/steps/SiteGen/SiteLogo/index.js index 52c95fb39..96fdf63be 100644 --- a/src/OnboardingSPA/steps/SiteGen/SiteLogo/index.js +++ b/src/OnboardingSPA/steps/SiteGen/SiteLogo/index.js @@ -1,20 +1,26 @@ +// WordPress import { useViewportMatch } from '@wordpress/compose'; import { useEffect, useState } from '@wordpress/element'; import { useSelect, useDispatch } from '@wordpress/data'; import { store as coreStore } from '@wordpress/core-data'; +// Classes and functions import getContents from './contents'; -import { HEADER_SITEGEN } from '../../../../constants'; +import { + OnboardingEvent, + trackOnboardingEvent, +} from '../../../utils/analytics/hiive'; + +// Components import SkipButton from '../../../components/SkipButton'; -import { store as nfdOnboardingStore } from '../../../store'; import AIHeading from '../../../components/Heading/AIHeading'; import CommonLayout from '../../../components/Layouts/Common'; import NextButtonSiteGen from '../../../components/Button/NextButtonSiteGen'; import ImageUploaderWithText from '../../../components/ImageUploader/components/ImageUploaderWithText'; -import { - OnboardingEvent, - trackOnboardingEvent, -} from '../../../utils/analytics/hiive'; + +// Misc +import { store as nfdOnboardingStore } from '../../../store'; +import { HEADER_SITEGEN } from '../../../../constants'; import { ACTION_LOGO_ADDED, ACTION_SITEGEN_LOGO_SKIPPED, @@ -23,6 +29,7 @@ import { SITEGEN_FLOW } from '../../../data/flows/constants'; const SiteGenSiteLogo = () => { const [ siteLogo, setSiteLogo ] = useState(); + const isLargeViewport = useViewportMatch( 'small' ); const { currentData } = useSelect( ( select ) => { @@ -32,12 +39,12 @@ const SiteGenSiteLogo = () => { }; } ); - const { editEntityRecord } = useDispatch( coreStore ); - const { getEditedEntityRecord } = useSelect( ( select ) => { return select( coreStore ); }, [] ); + const { editEntityRecord } = useDispatch( coreStore ); + const { setIsFooterNavAllowed, setIsHeaderEnabled, @@ -47,8 +54,24 @@ const SiteGenSiteLogo = () => { setHideFooterNav, setCurrentOnboardingData, setIsHeaderNavigationEnabled, + updateSiteGenErrorStatus, } = useDispatch( nfdOnboardingStore ); + useEffect( () => { + setHideFooterNav( false ); + setIsHeaderEnabled( true ); + setSidebarActiveView( false ); + setIsHeaderNavigationEnabled( true ); + setHeaderActiveView( HEADER_SITEGEN ); + setDrawerActiveView( false ); + if ( currentData.sitegen.siteLogo?.id !== 0 ) { + setIsFooterNavAllowed( true ); + return setSiteLogo( currentData.sitegen.siteLogo ); + } + setIsFooterNavAllowed( false ); + getEditedEntityRecord( 'root', 'site' ); + }, [] ); + const resetSiteLogo = () => { const currentDataCopy = { ...currentData }; currentDataCopy.sitegen.siteLogo = { @@ -67,21 +90,6 @@ const SiteGenSiteLogo = () => { ); }; - useEffect( () => { - setHideFooterNav( false ); - setIsHeaderEnabled( true ); - setSidebarActiveView( false ); - setIsHeaderNavigationEnabled( true ); - setHeaderActiveView( HEADER_SITEGEN ); - setDrawerActiveView( false ); - if ( currentData.sitegen.siteLogo?.id !== 0 ) { - setIsFooterNavAllowed( true ); - return setSiteLogo( currentData.sitegen.siteLogo ); - } - setIsFooterNavAllowed( false ); - getEditedEntityRecord( 'root', 'site' ); - }, [] ); - const handleSiteLogo = ( siteLogoNew ) => { const currentDataCopy = { ...currentData }; currentDataCopy.sitegen.siteLogo.id = siteLogoNew.id; @@ -96,7 +104,12 @@ const SiteGenSiteLogo = () => { setSiteLogo( siteLogoNew ); }; + const handleFailure = () => { + updateSiteGenErrorStatus( true ); + }; + const content = getContents(); + return ( {
{ - const isLargeViewport = useViewportMatch( 'small' ); - const navigate = useNavigate(); const [ connected, setConnected ] = useState( false ); const [ interacted, setInteracted ] = useState( false ); + const isLargeViewport = useViewportMatch( 'small' ); + const navigate = useNavigate(); + + const { nextStep } = useSelect( ( select ) => { + return { + nextStep: select( nfdOnboardingStore ).getNextStep(), + }; + } ); + const { setIsHeaderEnabled, setSidebarActiveView, @@ -46,11 +61,12 @@ const SiteGenSiteSocialMedia = () => { setIsHeaderNavigationEnabled( true ); } ); - const { nextStep } = useSelect( ( select ) => { - return { - nextStep: select( nfdOnboardingStore ).getNextStep(), - }; - } ); + useEffect( () => { + setIsFooterNavAllowed( connected ); + if ( interacted && connected ) { + navigate( nextStep.path ); + } + }, [ interacted, connected ] ); const handleConnect = () => { trackOnboardingEvent( @@ -78,16 +94,10 @@ const SiteGenSiteSocialMedia = () => { ); }; - useEffect( () => { - setIsFooterNavAllowed( connected ); - if ( interacted && connected ) { - navigate( nextStep.path ); - } - }, [ interacted, connected ] ); - const content = getContents(); + return ( - + {
- + ); }; diff --git a/src/OnboardingSPA/styles/app.scss b/src/OnboardingSPA/styles/app.scss index 09ae7c727..7cc9ceecc 100644 --- a/src/OnboardingSPA/styles/app.scss +++ b/src/OnboardingSPA/styles/app.scss @@ -33,6 +33,7 @@ @import "../components/Button/NavCardButton/stylesheet"; @import "../steps/Ecommerce/stylesheet"; @import "../components/ErrorState/stylesheet"; +@import "../components/ErrorState/Step/SiteGen/stylesheet.scss"; @import "../components/ErrorModal/stylesheet"; @import "../components/CheckboxTemplate/CheckboxItem/stylesheet"; @import "../components/CheckboxTemplate/CheckboxList/stylesheet"; @@ -65,7 +66,6 @@ @import "../components/TextInput/TextAreaSiteGenDetails/stylesheet"; @import "../components/TextInput/TextInputSiteGenDetails/stylesheet"; @import "../components/OrbAnimation/stylesheet"; -@import "../components/SiteGenError/stylesheet"; // CSS for Pages @import "../steps/BasicInfo/stylesheet"; diff --git a/src/OnboardingSPA/utils/api/siteGen.js b/src/OnboardingSPA/utils/api/siteGen.js index 64893f1c0..70a403dbc 100644 --- a/src/OnboardingSPA/utils/api/siteGen.js +++ b/src/OnboardingSPA/utils/api/siteGen.js @@ -16,15 +16,17 @@ export async function generateSiteGenMeta( identifier, skipCache = true ) { - const data = await apiFetch( { - url: onboardingRestURL( 'sitegen/generate' ), - method: 'POST', - data: { - site_info: siteInfo, - identifier, - skip_cache: skipCache, - }, - } ); + const data = await resolve( + apiFetch( { + url: onboardingRestURL( 'sitegen/generate' ), + method: 'POST', + data: { + site_info: siteInfo, + identifier, + skip_cache: skipCache, + }, + } ) + ); return data; } From 2a93d40f68eb715f571916b49811c0b5a0d77647 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Mon, 1 Apr 2024 16:49:17 +0530 Subject: [PATCH 2/4] SASS Lint fix --- src/OnboardingSPA/styles/app.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OnboardingSPA/styles/app.scss b/src/OnboardingSPA/styles/app.scss index 7cc9ceecc..80e31765c 100644 --- a/src/OnboardingSPA/styles/app.scss +++ b/src/OnboardingSPA/styles/app.scss @@ -33,7 +33,7 @@ @import "../components/Button/NavCardButton/stylesheet"; @import "../steps/Ecommerce/stylesheet"; @import "../components/ErrorState/stylesheet"; -@import "../components/ErrorState/Step/SiteGen/stylesheet.scss"; +@import "../components/ErrorState/Step/SiteGen/stylesheet"; @import "../components/ErrorModal/stylesheet"; @import "../components/CheckboxTemplate/CheckboxItem/stylesheet"; @import "../components/CheckboxTemplate/CheckboxList/stylesheet"; From 0066d442c9915a2d9d8286aa47e6c961ce354e07 Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Fri, 5 Apr 2024 17:41:38 +0530 Subject: [PATCH 3/4] Add a site meta generation state --- .../NewfoldInterfaceSkeleton/SiteGen/index.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js index bbdeaac5f..ac19b48b9 100644 --- a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js +++ b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js @@ -55,6 +55,7 @@ const ThemedNewfoldInterfaceSkeleton = themeToggleHOC( const SiteGen = () => { const [ failedSiteMetaAPIs, setFailedSiteMetaAPIs ] = useState( [] ); + const [ isGeneratingSiteMeta, setIsGeneratingSiteMeta ] = useState( false ); const { currentData, @@ -191,6 +192,7 @@ const SiteGen = () => { if ( siteGenErrorStatus === false ) { updateSiteGenErrorStatus( true ); + setIsGeneratingSiteMeta( false ); } if ( window.nfdOnboarding.siteGenTimerInterval ) { @@ -208,7 +210,7 @@ const SiteGen = () => { } ); } - // A Identifier request was sucessfuly made with valid response + // A Identifier request was successfully made with valid response currentData.sitegen.siteGenMetaStatus.currentStatus += 1; if ( @@ -217,7 +219,8 @@ const SiteGen = () => { ) { // Once all requests are completed use cache to get data currentData.sitegen.skipCache = false; - + // Increase count after site meta calls to ensure systematic call of homepages + currentData.sitegen.siteGenMetaStatus.totalCount += 1; // Get the homepages and set that in flow const response = await getHomepages( currentData.sitegen.siteDetails.prompt @@ -225,6 +228,8 @@ const SiteGen = () => { if ( response.body ) { currentData.sitegen.homepages.data = response.body; + currentData.sitegen.siteGenMetaStatus.currentStatus += 1; + setIsGeneratingSiteMeta( false ); } } // Sync the current request changed to State @@ -235,6 +240,7 @@ const SiteGen = () => { // Start the API Requests when the loader is shown. if ( true === siteGenErrorStatus || + true === isGeneratingSiteMeta || ( ! location.pathname.includes( 'site-logo' ) && ! location.pathname.includes( 'experience' ) ) ) { @@ -249,6 +255,8 @@ const SiteGen = () => { return; } + setIsGeneratingSiteMeta( true ); + if ( ! window.nfdOnboarding?.siteGenTimerInterval ) { window.nfdOnboarding.siteGenTime = 0; window.nfdOnboarding.siteGenTimerInterval = setInterval( () => { From b66c868733914e3cfaedd05e0605fe57e96e44bb Mon Sep 17 00:00:00 2001 From: arunshenoy99 Date: Mon, 8 Apr 2024 14:02:53 +0530 Subject: [PATCH 4/4] Handle homepage failure --- .../components/Loaders/SiteGenLoader/index.js | 22 +++++++------ .../NewfoldInterfaceSkeleton/SiteGen/index.js | 16 +++++++--- .../steps/SiteGen/Preview/index.js | 2 +- src/OnboardingSPA/store/actions.js | 20 ++---------- src/OnboardingSPA/store/reducer.js | 30 ++++------------- src/OnboardingSPA/store/selectors.js | 32 ++----------------- 6 files changed, 36 insertions(+), 86 deletions(-) diff --git a/src/OnboardingSPA/components/Loaders/SiteGenLoader/index.js b/src/OnboardingSPA/components/Loaders/SiteGenLoader/index.js index d8a5297d6..54e039a7a 100644 --- a/src/OnboardingSPA/components/Loaders/SiteGenLoader/index.js +++ b/src/OnboardingSPA/components/Loaders/SiteGenLoader/index.js @@ -11,13 +11,17 @@ const SiteGenLoader = ( { customNavPercentage, watcher = null } ) => { const [ percentage, setPercentage ] = useState( 0 ); const [ status, setStatus ] = useState( content.status[ statusIdx ].title ); - const { currentData, nextStep } = useSelect( ( select ) => { - return { - currentData: - select( nfdOnboardingStore ).getCurrentOnboardingData(), - nextStep: select( nfdOnboardingStore ).getNextStep(), - }; - } ); + const { currentData, nextStep, isGeneratingHomepages } = useSelect( + ( select ) => { + return { + currentData: + select( nfdOnboardingStore ).getCurrentOnboardingData(), + nextStep: select( nfdOnboardingStore ).getNextStep(), + isGeneratingHomepages: + select( nfdOnboardingStore ).isGeneratingHomepages(), + }; + } + ); useEffect( () => { const statusTimer = setInterval( () => { @@ -42,7 +46,7 @@ const SiteGenLoader = ( { customNavPercentage, watcher = null } ) => { }, [ currentData?.sitegen?.siteGenMetaStatus?.currentStatus ] ); useEffect( () => { - if ( percentage === customNavPercentage ) { + if ( percentage === customNavPercentage && ! isGeneratingHomepages ) { if ( nextStep ) { if ( watcher !== null && watcher === false ) { return; @@ -50,7 +54,7 @@ const SiteGenLoader = ( { customNavPercentage, watcher = null } ) => { navigate( nextStep.path ); } } - }, [ percentage, watcher ] ); + }, [ percentage, watcher, isGeneratingHomepages ] ); return (
diff --git a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js index ac19b48b9..e1b0f14c6 100644 --- a/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js +++ b/src/OnboardingSPA/components/NewfoldInterfaceSkeleton/SiteGen/index.js @@ -87,6 +87,7 @@ const SiteGen = () => { setCurrentOnboardingData, updateSiteGenErrorStatus, setActiveChapter, + setIsGeneratingHomepages, } = useDispatch( nfdOnboardingStore ); const { getEditedEntityRecord } = useSelect( ( select ) => { @@ -219,18 +220,23 @@ const SiteGen = () => { ) { // Once all requests are completed use cache to get data currentData.sitegen.skipCache = false; + setIsGeneratingSiteMeta( false ); // Increase count after site meta calls to ensure systematic call of homepages - currentData.sitegen.siteGenMetaStatus.totalCount += 1; // Get the homepages and set that in flow + setIsGeneratingHomepages( true ); const response = await getHomepages( currentData.sitegen.siteDetails.prompt ); - if ( response.body ) { - currentData.sitegen.homepages.data = response.body; - currentData.sitegen.siteGenMetaStatus.currentStatus += 1; - setIsGeneratingSiteMeta( false ); + if ( response.error ) { + updateSiteGenErrorStatus( true ); + setIsGeneratingHomepages( false ); + setCurrentOnboardingData( currentData ); + return; } + + currentData.sitegen.homepages.data = response.body; + setIsGeneratingHomepages( false ); } // Sync the current request changed to State setCurrentOnboardingData( currentData ); diff --git a/src/OnboardingSPA/steps/SiteGen/Preview/index.js b/src/OnboardingSPA/steps/SiteGen/Preview/index.js index 6887974b1..255ff28de 100644 --- a/src/OnboardingSPA/steps/SiteGen/Preview/index.js +++ b/src/OnboardingSPA/steps/SiteGen/Preview/index.js @@ -75,7 +75,6 @@ const SiteGenPreview = () => { setHeaderActiveView( HEADER_SITEGEN ); setDrawerActiveView( false ); updateInitialize( true ); - setIsHeaderNavigationEnabled( false ); }, [] ); useEffect( () => { @@ -85,6 +84,7 @@ const SiteGenPreview = () => { ) { loadHomepages(); loadGlobalStyles(); + setIsHeaderNavigationEnabled( false ); } prevSiteGenErrorStatus.current = siteGenErrorStatus; }, [ siteGenErrorStatus ] ); diff --git a/src/OnboardingSPA/store/actions.js b/src/OnboardingSPA/store/actions.js index af82d6321..fe61075e8 100644 --- a/src/OnboardingSPA/store/actions.js +++ b/src/OnboardingSPA/store/actions.js @@ -292,24 +292,10 @@ export function resetNavError() { }; } -export const setHomepagesData = ( homepagesData ) => { +export const setIsGeneratingHomepages = ( isGeneratingHomepages ) => { return { - type: 'SET_HOMEPAGES_DATA', - homepagesData, - }; -}; - -export const setActiveHomepage = ( activeHomepage ) => { - return { - type: 'SET_ACTIVE_HOMEPAGE', - activeHomepage, - }; -}; - -export const toggleFavorite = ( slug ) => { - return { - type: 'TOGGLE_FAVORITE', - slug, + type: 'SET_IS_GENERATING_HOMEPAGES', + isGeneratingHomepages, }; }; diff --git a/src/OnboardingSPA/store/reducer.js b/src/OnboardingSPA/store/reducer.js index ce5158fa2..f4c36a80a 100644 --- a/src/OnboardingSPA/store/reducer.js +++ b/src/OnboardingSPA/store/reducer.js @@ -162,6 +162,7 @@ export function drawer( return state; } + export function data( state = {}, action ) { switch ( action.type ) { case 'SET_CURRENT_DATA': @@ -178,42 +179,23 @@ export function data( state = {}, action ) { ...action.socialData, }, }; - case 'SET_HOMEPAGES_DATA': - return { - ...state, - flowData: { - ...state.flowData, - sitegen: { - ...state.flowData.sitegen, - homepages: action.homepagesData, - }, - }, - }; - case 'SET_ACTIVE_HOMEPAGE': + case 'SET_SITEGEN_AI_ERROR_STATUS': return { ...state, flowData: { ...state.flowData, sitegen: { ...state.flowData.sitegen, - homepages: { - ...state.flowData.sitegen.homepages, - active: action.activeHomepage, - }, + siteGenErrorStatus: action.siteGenErrorStatus, }, }, }; - case 'SET_SITEGEN_AI_ERROR_STATUS': + + case 'SET_IS_GENERATING_HOMEPAGES': return { ...state, - flowData: { - ...state.flowData, - sitegen: { - ...state.flowData.sitegen, - siteGenErrorStatus: action.siteGenErrorStatus, - }, - }, + isGeneratingHomepages: action.isGeneratingHomepages, }; } diff --git a/src/OnboardingSPA/store/selectors.js b/src/OnboardingSPA/store/selectors.js index 020b8ef2b..4884bfd2e 100644 --- a/src/OnboardingSPA/store/selectors.js +++ b/src/OnboardingSPA/store/selectors.js @@ -431,36 +431,8 @@ export function getCurrentUserDetails( state ) { return currentUserInfo; } -/** - * Gets homepages - * - * @param {*} state - * @return {Object} homepages - */ -export const getHomepagesData = ( state ) => { - return state.data.flowData.sitegen.homepages; -}; - -/** - * Gets actove homepage - * - * @param {*} state - * @return {Object} active - */ - -export const getActiveHomepage = ( state ) => { - return state.data.flowData.sitegen.homepages.active; -}; - -/** - * Gets all homepage - * - * @param {*} state - * @return {Object} data - */ - -export const getAllHomepages = ( state ) => { - return state.data.flowData.sitegen.homepages.data; +export const isGeneratingHomepages = ( state ) => { + return state.data.isGeneratingHomepages; }; export function getCustomizeSidebarData( state ) {