/** * External dependencies */ import { assign, fromCallback, setup } from 'xstate5'; import React from 'react'; import { getQuery } from '@woocommerce/navigation'; import type { TaskListType } from '@woocommerce/data'; /** * Internal dependencies */ import { LoadingPage } from './pages/loading'; import { SitePreviewPage } from './pages/site-preview'; import type { LaunchYourStoreComponentProps } from '..'; import { createQueryParamsListener, updateQueryParams } from '../common'; import { services as congratsServices, events as congratsEvents, actions as congratsActions, LaunchYourStoreSuccess, } from './pages/launch-store-success'; export type MainContentMachineContext = { congratsScreen: { hasLoadedCongratsData: boolean; hasCompleteSurvey: boolean; allTasklists: TaskListType[]; activePlugins: string[]; }; siteIsShowingCachedContent: boolean; }; export type MainContentComponentProps = LaunchYourStoreComponentProps & { context: MainContentMachineContext; }; export type MainContentMachineEvents = | { type: 'SHOW_LAUNCH_STORE_SUCCESS' } | { type: 'SHOW_LAUNCH_STORE_PENDING_CACHE' } | { type: 'EXTERNAL_URL_UPDATE' } | { type: 'SHOW_LOADING' } | congratsEvents; const contentQueryParamListener = fromCallback( ( { sendBack } ) => { return createQueryParamsListener( 'content', sendBack ); } ); export const mainContentMachine = setup( { types: {} as { context: MainContentMachineContext; events: MainContentMachineEvents; }, actions: { updateQueryParams: ( _, params: { sidebar?: string; content?: string } ) => { updateQueryParams( params ); }, assignSiteCachedStatus: assign( { siteIsShowingCachedContent: true, } ), }, guards: { hasContentLocation: ( _, { contentLocation }: { contentLocation: string } ) => { const { content } = getQuery() as { content?: string }; return !! content && content === contentLocation; }, }, actors: { contentQueryParamListener, fetchCongratsData: congratsServices.fetchCongratsData, }, } ).createMachine( { id: 'mainContent', initial: 'navigate', context: { congratsScreen: { hasLoadedCongratsData: false, hasCompleteSurvey: false, allTasklists: [], activePlugins: [], }, siteIsShowingCachedContent: false, }, invoke: { id: 'contentQueryParamListener', src: 'contentQueryParamListener', }, states: { navigate: { always: [ { guard: { type: 'hasContentLocation', params: { contentLocation: 'site-preview' }, }, }, { guard: { type: 'hasContentLocation', params: { contentLocation: 'launch-store-success' }, }, target: 'launchStoreSuccess', }, { target: '#sitePreview', }, ], }, sitePreview: { id: 'sitePreview', meta: { component: SitePreviewPage, }, }, launchStoreSuccess: { id: 'launchStoreSuccess', invoke: [ { src: 'fetchCongratsData', onDone: { actions: assign( congratsActions.assignCongratsData ), }, }, ], entry: [ { type: 'updateQueryParams', params: { content: 'launch-store-success' }, }, ], meta: { component: LaunchYourStoreSuccess, }, on: { COMPLETE_SURVEY: { actions: assign( congratsActions.assignCompleteSurvey ), }, }, }, loading: { id: 'loading', meta: { component: LoadingPage, }, }, }, on: { EXTERNAL_URL_UPDATE: { target: '.navigate', }, SHOW_LAUNCH_STORE_SUCCESS: { target: '#launchStoreSuccess', }, SHOW_LAUNCH_STORE_PENDING_CACHE: { actions: [ 'assignSiteCachedStatus' ], target: '#launchStoreSuccess', }, SHOW_LOADING: { target: '#loading', }, }, } ); export const MainContentContainer = ( { children, }: { children: React.ReactNode; } ) => { return (