diff --git a/includes/RestApi/SiteGenController.php b/includes/RestApi/SiteGenController.php index a4ab08de2..fb6a98079 100644 --- a/includes/RestApi/SiteGenController.php +++ b/includes/RestApi/SiteGenController.php @@ -4,6 +4,7 @@ use NewfoldLabs\WP\Module\Onboarding\Permissions; use NewfoldLabs\WP\Module\Onboarding\Data\Services\SiteGenService; +use NewfoldLabs\WP\Module\Onboarding\Data\Services\WonderBlocksService; use NewfoldLabs\WP\Module\Onboarding\Data\SiteGen as SiteGenData; /** @@ -143,6 +144,11 @@ public function get_homepages_args() { 'required' => true, 'type' => 'string', ), + 'fallback' => array( + 'required' => false, + 'type' => 'boolean', + 'default' => false, + ), ); } @@ -235,18 +241,23 @@ public function get_homepages( \WP_REST_Request $request ) { return new \WP_REST_Response( $existing_homepages, 200 ); } + $fallback = $request->get_param( 'fallback' ); + if ( true === $fallback ) { + return WonderBlocksService::get_fallback_homepages(); + } + $site_description = $request->get_param( 'site_description' ); $locale = $request->get_param( 'locale' ); $site_info = array( 'site_description' => $site_description ); $target_audience = SiteGenService::instantiate_site_meta( $site_info, 'target_audience', $locale ); if ( is_wp_error( $target_audience ) ) { - return $target_audience; + return WonderBlocksService::get_fallback_homepages(); } $content_style = SiteGenService::instantiate_site_meta( $site_info, 'content_tones', $locale ); if ( is_wp_error( $content_style ) ) { - return $content_style; + return WonderBlocksService::get_fallback_homepages(); } $homepages = SiteGenService::generate_homepages( @@ -257,7 +268,7 @@ public function get_homepages( \WP_REST_Request $request ) { ); if ( is_wp_error( $homepages ) ) { - return $homepages; + return WonderBlocksService::get_fallback_homepages(); } return new \WP_REST_Response( $homepages, 201 ); diff --git a/src/app/data/store/slices/runtime.js b/src/app/data/store/slices/runtime.js index 3b8b6e69b..59a968a6b 100644 --- a/src/app/data/store/slices/runtime.js +++ b/src/app/data/store/slices/runtime.js @@ -126,14 +126,4 @@ export const selectors = { getSiteGenIdentifiers( state ) { return state.runtime.siteGen.identifiers; }, - - /** - * Gets the fallback homepages. - * - * @param {*} state - * @return {Object} fallbackHomepages - */ - getFallbackHomepages( state ) { - return state.runtime.fallbackHomepages; - }, }; diff --git a/src/app/data/store/slices/sitegen.js b/src/app/data/store/slices/sitegen.js index a7de7b9b3..e1ae687a0 100644 --- a/src/app/data/store/slices/sitegen.js +++ b/src/app/data/store/slices/sitegen.js @@ -33,6 +33,12 @@ export function sitegen( state = DEFAULT_STATE, action ) { homepages: action.homepages, version: state.version + 1, }; + case 'SET_FALLBACK_HOMEPAGES': + return { + ...state, + fallbackHomepages: action.fallbackHomepages, + version: state.version + 1, + }; case 'SET_SELECTED_HOMEPAGE': return { ...state, @@ -81,6 +87,12 @@ export const actions = { homepages, }; }, + setFallbackHomepages: ( fallbackHomepages ) => { + return { + type: 'SET_FALLBACK_HOMEPAGES', + fallbackHomepages, + }; + }, setSelectedHomepage: ( selectedHomepage ) => { return { type: 'SET_SELECTED_HOMEPAGE', @@ -116,6 +128,7 @@ export const actions = { export const selectors = { getSiteGenSlice: ( state ) => state.sitegen, getHomepages: ( state ) => state.sitegen.homepages, + getFallbackHomepages: ( state ) => state.sitegen.fallbackHomepages, getSelectedHomepage: ( state ) => state.sitegen.selectedHomepage, getHasGeneratedSitePages: ( state ) => state.sitegen.hasGeneratedSitePages, getSelectedColorPalette: ( state ) => state.sitegen.homepages[ state.sitegen.selectedHomepage ]?.color?.palette, diff --git a/src/app/steps/Generating/GeneratingStep.js b/src/app/steps/Generating/GeneratingStep.js index 4cb7d2d1d..d5ef2fc19 100644 --- a/src/app/steps/Generating/GeneratingStep.js +++ b/src/app/steps/Generating/GeneratingStep.js @@ -7,19 +7,25 @@ import { generateSite } from '@/utils/sitegen'; import { ExperienceOptions } from './'; import { OnboardingEvent, trackOnboardingEvent } from '@/utils/analytics/hiive'; import { ACTION_EXPERIENCE_LEVEL_SET } from '@/utils/analytics/hiive/constants'; +import { useEffect, useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; const GeneratingStep = () => { - const [ isSiteGenerationComplete, setIsSiteGenerationComplete ] = useState( false ); + const [ isSiteGenerationComplete, setIsSiteGenerationComplete ] = + useState( false ); const [ isTimerComplete, setIsTimerComplete ] = useState( false ); const [ isReadyToAnimate, setIsReadyToAnimate ] = useState( false ); - const { selectedExperienceLevel, homepages, retryMode } = useSelect( ( select ) => { - return { - experienceLevel: select( nfdOnboardingStore ).getExperienceLevel(), - homepages: select( nfdOnboardingStore ).getHomepages(), - retryMode: select( nfdOnboardingStore ).getRetryMode(), - }; - } ); + const { selectedExperienceLevel, homepages, retryMode } = useSelect( + ( select ) => { + return { + experienceLevel: + select( nfdOnboardingStore ).getExperienceLevel(), + homepages: select( nfdOnboardingStore ).getHomepages(), + retryMode: select( nfdOnboardingStore ).getRetryMode(), + }; + } + ); const navigate = useNavigate(); @@ -50,6 +56,7 @@ const GeneratingStep = () => { /** * Whether to render the component or navigate a different step. + * * @return {boolean} True if the component should render, false otherwise. */ const shouldRender = () => { @@ -86,6 +93,7 @@ const GeneratingStep = () => { * Logic: * - If Sitegen has failed for the first time, restart the generation process to try again. * - If Sitegen has failed for the second time, navigate to the previews step to generate fallback pages. + * * @return {void} */ const handleFailedSiteGeneration = () => { @@ -111,7 +119,7 @@ const GeneratingStep = () => { * This function will initiate the site generation process. */ const initiateSiteGeneration = async () => { - const result = await generateSite(); + const result = await generateSite( retryMode ); if ( result ) { setIsSiteGenerationComplete( true ); } else { @@ -171,15 +179,29 @@ const GeneratingStep = () => {
- { __( 'Building your website…', 'wp-module-onboarding' ) } + { __( + 'Building your website…', + 'wp-module-onboarding' + ) }

- { __( 'Hang tight while we create some wonderful options for you.', 'wp-module-onboarding' ) } + { __( + 'Hang tight while we create some wonderful options for you.', + 'wp-module-onboarding' + ) }

@@ -195,7 +217,10 @@ const GeneratingStep = () => { >

- { __( 'While we wait, let us know how familiar you are with WordPress, so we can tailor the experience to your needs:', 'wp-module-onboarding' ) } + { __( + 'While we wait, let us know how familiar you are with WordPress, so we can tailor the experience to your needs:', + 'wp-module-onboarding' + ) }

diff --git a/src/app/utils/api/onboarding.js b/src/app/utils/api/onboarding.js index 5112ea03e..fc7517f89 100644 --- a/src/app/utils/api/onboarding.js +++ b/src/app/utils/api/onboarding.js @@ -144,11 +144,12 @@ export async function getSiteMetaForIdentifier( /** * Get the homepages. * - * @param {string} prompt - * @param {string} locale + * @param {string} prompt - The site description prompt. + * @param {string} locale - The selected locale. + * @param {boolean} fallback - Whether to fetch fallback homepages. * @return {Promise} response */ -export async function getHomepages( prompt, locale ) { +export async function getHomepages( prompt, locale, fallback = false ) { const response = await resolve( apiFetch( { url: onboardingRestURL( 'sitegen/homepages' ), @@ -156,6 +157,7 @@ export async function getHomepages( prompt, locale ) { data: { site_description: prompt, locale, + fallback, }, } ) ); diff --git a/src/app/utils/sitegen/generateHomePages.js b/src/app/utils/sitegen/generateHomePages.js index 520356cd3..c88a916c6 100644 --- a/src/app/utils/sitegen/generateHomePages.js +++ b/src/app/utils/sitegen/generateHomePages.js @@ -6,34 +6,48 @@ import { ACTION_ERROR_STATE_TRIGGERED } from '@/utils/analytics/hiive/constants' /** * Generate the home pages for the site. - * @return {boolean} True if successful, false otherwise. + * + * @param {boolean} fallback - Whether to explicitly request fallback homepages. + * @return {Promise} True if successful, false otherwise. */ -const generateHomePages = async () => { +const generateHomePages = async ( fallback = false ) => { const prompt = select( nfdOnboardingStore ).getPrompt(); const locale = select( nfdOnboardingStore ).getSelectedLocale(); - const response = await getHomepages( prompt, locale ); + const response = await getHomepages( prompt, locale, fallback ); + if ( response.error ) { trackOnboardingEvent( new OnboardingEvent( ACTION_ERROR_STATE_TRIGGERED, 'homepages', - { - source: 'quickstart', - } + { source: 'quickstart' } ) ); // eslint-disable-next-line no-console console.error( 'Failed to generate home pages' ); - return false; } + const homepages = response.body; - // Set the homepages in the store - dispatch( nfdOnboardingStore ).setHomepages( homepages ); + // If backend returned a fallback flag, track it and handle accordingly + if ( homepages?.fallback ) { + trackOnboardingEvent( + new OnboardingEvent( + ACTION_ERROR_STATE_TRIGGERED, + 'homepages_fallback', + { source: 'quickstart' } + ) + ); + + delete homepages.fallback; + dispatch( nfdOnboardingStore ).setFallbackHomepages( homepages ); + return false; + } + dispatch( nfdOnboardingStore ).setHomepages( homepages ); return true; }; diff --git a/src/app/utils/sitegen/generateSite.js b/src/app/utils/sitegen/generateSite.js index a1ec4603e..35fe72b25 100644 --- a/src/app/utils/sitegen/generateSite.js +++ b/src/app/utils/sitegen/generateSite.js @@ -1,14 +1,24 @@ import { generateSiteMeta, generateHomePages, generateSitePages } from '.'; -const generateSite = async () => { +const generateSite = async ( retryMode ) => { // Generate site meta const siteMeta = await generateSiteMeta(); - if ( ! siteMeta ) { + + // Not in retryMode and site meta fails + if ( ! retryMode && ! siteMeta ) { return false; } - // Generate home pages - const homePages = await generateHomePages(); + // Determine whether to use fallback for homepages + let useFallback = false; + + // In retryMode and site meta fails -> use fallback + if ( retryMode && ! siteMeta ) { + useFallback = true; + } + + // In either mode and site meta passes -> no fallback (default false) + const homePages = await generateHomePages( useFallback ); if ( ! homePages ) { return false; }