CYS: Add homepage template AI completion and revamped header footer (#40363)
* Moved homepage templates, added header and footer to homepage templates, revamped templates to use metadata. removed header and footer completion calls * Lint * Slight adjustment to completion prompt and changelog * Lint * Use header and footer in 'Change your homepage' * Add test * Lint * Add back homepage templates exclusion header and footer for assembler use * Add test for useHomeTemplates * Lint
This commit is contained in:
parent
8685fd211e
commit
0b2ad50a21
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { useHomeTemplates, getTemplatePatterns } from '../use-home-templates';
|
||||
import { usePatterns } from '../use-patterns';
|
||||
|
||||
// Mocking the dependent hooks and data
|
||||
jest.mock( '../use-patterns' );
|
||||
jest.mock( '~/customize-store/data/homepageTemplates', () => ( {
|
||||
HOMEPAGE_TEMPLATES: {
|
||||
template1: { blocks: [ 'header', 'content1', 'content2', 'footer' ] },
|
||||
template2: { blocks: [ 'header', 'content3', 'footer' ] },
|
||||
},
|
||||
} ) );
|
||||
|
||||
const mockUsePatterns = usePatterns;
|
||||
|
||||
const mockPatternsByName = {
|
||||
header: { name: 'header', content: '<div>Header</div>' },
|
||||
content1: { name: 'content1', content: '<div>Content1</div>' },
|
||||
content2: { name: 'content2', content: '<div>Content2</div>' },
|
||||
content3: { name: 'content3', content: '<div>Content3</div>' },
|
||||
footer: { name: 'footer', content: '<div>Footer</div>' },
|
||||
};
|
||||
|
||||
describe( 'useHomeTemplates', () => {
|
||||
beforeEach( () => {
|
||||
mockUsePatterns.mockReturnValue( {
|
||||
blockPatterns: Object.values( mockPatternsByName ),
|
||||
isLoading: false,
|
||||
} );
|
||||
} );
|
||||
|
||||
it( 'should return home templates without first and last items', () => {
|
||||
const { result } = renderHook( () => useHomeTemplates() );
|
||||
|
||||
// The expected result based on the HOMEPAGE_TEMPLATES and mock patterns
|
||||
const expectedResult = {
|
||||
template1: getTemplatePatterns(
|
||||
[ 'content1', 'content2' ],
|
||||
mockPatternsByName
|
||||
),
|
||||
template2: getTemplatePatterns(
|
||||
[ 'content3' ],
|
||||
mockPatternsByName
|
||||
),
|
||||
};
|
||||
|
||||
expect( result.current.homeTemplates ).toEqual( expectedResult );
|
||||
} );
|
||||
} );
|
|
@ -10,72 +10,7 @@ import { parse } from '@wordpress/blocks';
|
|||
* Internal dependencies
|
||||
*/
|
||||
import { usePatterns, Pattern, PatternWithBlocks } from './use-patterns';
|
||||
|
||||
// TODO: It might be better to create an API endpoint to get the templates.
|
||||
export const LARGE_BUSINESS_TEMPLATES = {
|
||||
template1: [
|
||||
'a8c/cover-image-with-left-aligned-call-to-action',
|
||||
'woocommerce-blocks/featured-products-5-item-grid',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'woocommerce-blocks/featured-category-triple',
|
||||
'a8c/3-column-testimonials',
|
||||
'a8c/quotes-2',
|
||||
'woocommerce-blocks/social-follow-us-in-social-media',
|
||||
],
|
||||
template2: [
|
||||
'woocommerce-blocks/hero-product-split',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'woocommerce-blocks/featured-category-triple',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'a8c/three-columns-with-images-and-text',
|
||||
'woocommerce-blocks/testimonials-3-columns',
|
||||
'a8c/subscription',
|
||||
],
|
||||
template3: [
|
||||
'a8c/call-to-action-7',
|
||||
'a8c/3-column-testimonials',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'woocommerce-blocks/featured-category-cover-image',
|
||||
'woocommerce-blocks/featured-products-5-item-grid',
|
||||
'woocommerce-blocks/featured-products-5-item-grid',
|
||||
'woocommerce-blocks/social-follow-us-in-social-media',
|
||||
],
|
||||
};
|
||||
|
||||
export const SMALL_MEDIUM_BUSINESS_TEMPLATES = {
|
||||
template1: [
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'woocommerce-blocks/testimonials-single',
|
||||
'woocommerce-blocks/hero-product-3-split',
|
||||
'a8c/contact-8',
|
||||
],
|
||||
template2: [
|
||||
'a8c/about-me-4',
|
||||
'a8c/product-feature-with-buy-button',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'a8c/subscription',
|
||||
'woocommerce-blocks/testimonials-3-columns',
|
||||
'a8c/contact-with-map-on-the-left',
|
||||
],
|
||||
template3: [
|
||||
'a8c/heading-and-video',
|
||||
'a8c/3-column-testimonials',
|
||||
'woocommerce-blocks/product-hero',
|
||||
'a8c/quotes-2',
|
||||
'a8c/product-feature-with-buy-button',
|
||||
'a8c/simple-two-column-layout',
|
||||
'woocommerce-blocks/social-follow-us-in-social-media',
|
||||
],
|
||||
};
|
||||
|
||||
const TEMPLATES = {
|
||||
template1: LARGE_BUSINESS_TEMPLATES.template1,
|
||||
template2: LARGE_BUSINESS_TEMPLATES.template2,
|
||||
template3: LARGE_BUSINESS_TEMPLATES.template3,
|
||||
template4: SMALL_MEDIUM_BUSINESS_TEMPLATES.template1,
|
||||
template5: SMALL_MEDIUM_BUSINESS_TEMPLATES.template2,
|
||||
template6: SMALL_MEDIUM_BUSINESS_TEMPLATES.template3,
|
||||
};
|
||||
import { HOMEPAGE_TEMPLATES } from '~/customize-store/data/homepageTemplates';
|
||||
|
||||
export const getTemplatePatterns = (
|
||||
template: string[],
|
||||
|
@ -106,6 +41,7 @@ export const patternsToNameMap = ( blockPatterns: Pattern[] ) =>
|
|||
{}
|
||||
);
|
||||
|
||||
// Returns home template patterns excluding header and footer.
|
||||
export const useHomeTemplates = () => {
|
||||
const { blockPatterns, isLoading } = usePatterns();
|
||||
|
||||
|
@ -116,7 +52,7 @@ export const useHomeTemplates = () => {
|
|||
|
||||
const homeTemplates = useMemo( () => {
|
||||
if ( isLoading ) return {};
|
||||
const recommendedTemplates = TEMPLATES;
|
||||
const recommendedTemplates = HOMEPAGE_TEMPLATES;
|
||||
|
||||
return Object.entries( recommendedTemplates ).reduce(
|
||||
(
|
||||
|
@ -125,7 +61,7 @@ export const useHomeTemplates = () => {
|
|||
) => {
|
||||
if ( templateName in recommendedTemplates ) {
|
||||
acc[ templateName ] = getTemplatePatterns(
|
||||
template,
|
||||
template.blocks.slice( 1, -1 ),
|
||||
patternsByName
|
||||
);
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ export const SidebarNavigationScreenHomepage = () => {
|
|||
shownPatterns={ homePatterns }
|
||||
blockPatterns={ homePatterns }
|
||||
onClickPattern={ onClickPattern }
|
||||
label={ 'Hompeage' }
|
||||
label={ 'Homepage' }
|
||||
orientation="vertical"
|
||||
category={ 'homepage' }
|
||||
isDraggable={ false }
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
// TODO: It might be better to create an API endpoint to get the templates.
|
||||
export const HOMEPAGE_TEMPLATES = {
|
||||
template1: {
|
||||
blocks: [
|
||||
// Header
|
||||
'woocommerce-blocks/header-centered-menu-with-search',
|
||||
|
||||
// Body
|
||||
'a8c/cover-image-with-left-aligned-call-to-action',
|
||||
'woocommerce-blocks/featured-products-5-item-grid',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'woocommerce-blocks/featured-category-triple',
|
||||
'a8c/3-column-testimonials',
|
||||
'a8c/quotes-2',
|
||||
'woocommerce-blocks/social-follow-us-in-social-media',
|
||||
|
||||
// Footer
|
||||
'woocommerce-blocks/footer-with-3-menus',
|
||||
],
|
||||
metadata: {
|
||||
businessType: [ 'e-commerce', 'large-business' ],
|
||||
contentFocus: [ 'featured products' ],
|
||||
audience: [ 'general' ],
|
||||
design: [ 'contemporary' ],
|
||||
features: [
|
||||
'fullwidth-image-banner',
|
||||
'testimonials',
|
||||
'social-media',
|
||||
'search',
|
||||
],
|
||||
complexity: 'high',
|
||||
},
|
||||
},
|
||||
template2: {
|
||||
blocks: [
|
||||
// Header
|
||||
'woocommerce-blocks/header-essential',
|
||||
|
||||
// Body
|
||||
'woocommerce-blocks/hero-product-split',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'woocommerce-blocks/featured-category-triple',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'a8c/three-columns-with-images-and-text',
|
||||
'woocommerce-blocks/testimonials-3-columns',
|
||||
'a8c/subscription',
|
||||
|
||||
// Footer
|
||||
'woocommerce-blocks/footer-large',
|
||||
],
|
||||
metadata: {
|
||||
businessType: [ 'e-commerce', 'subscription', 'large-business' ],
|
||||
contentFocus: [ 'catalog' ],
|
||||
audience: [ 'general' ],
|
||||
design: [ 'contemporary' ],
|
||||
features: [ 'small-banner', 'testimonials', 'newsletter' ],
|
||||
complexity: 'high',
|
||||
},
|
||||
},
|
||||
template3: {
|
||||
blocks: [
|
||||
// Header
|
||||
'woocommerce-blocks/header-centered-menu-with-search',
|
||||
|
||||
// Body
|
||||
'a8c/call-to-action-7',
|
||||
'a8c/3-column-testimonials',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'woocommerce-blocks/featured-category-cover-image',
|
||||
'woocommerce-blocks/featured-products-5-item-grid',
|
||||
'woocommerce-blocks/featured-products-5-item-grid',
|
||||
'woocommerce-blocks/social-follow-us-in-social-media',
|
||||
|
||||
// Footer
|
||||
'woocommerce-blocks/footer-with-3-menus',
|
||||
],
|
||||
metadata: {
|
||||
businessType: [ 'subscription', 'large-business' ],
|
||||
contentFocus: [ 'catalog', 'call-to-action' ],
|
||||
audience: [ 'general' ],
|
||||
design: [ 'contemporary' ],
|
||||
features: [ 'small-banner', 'social-media' ],
|
||||
complexity: 'high',
|
||||
},
|
||||
},
|
||||
template4: {
|
||||
blocks: [
|
||||
// Header
|
||||
'woocommerce-blocks/header-essential',
|
||||
|
||||
// Body
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'woocommerce-blocks/testimonials-single',
|
||||
'woocommerce-blocks/hero-product-3-split',
|
||||
'a8c/contact-8',
|
||||
|
||||
// Footer
|
||||
'woocommerce-blocks/footer-simple-menu-and-cart', // This is supposed to be the "Footer with Newsletter Subscription Form"
|
||||
],
|
||||
metadata: {
|
||||
businessType: [ 'e-commerce', 'small-medium-business' ],
|
||||
contentFocus: [ 'products' ],
|
||||
audience: [ 'focused' ],
|
||||
design: [ 'sleek' ],
|
||||
features: [ 'single-testimonial', 'contact', 'call-to-action' ],
|
||||
complexity: 'medium',
|
||||
},
|
||||
},
|
||||
template5: {
|
||||
blocks: [
|
||||
// Header
|
||||
'woocommerce-blocks/header-essential',
|
||||
|
||||
// Body
|
||||
'a8c/about-me-4',
|
||||
'a8c/product-feature-with-buy-button',
|
||||
'woocommerce-blocks/featured-products-fresh-and-tasty',
|
||||
'a8c/subscription',
|
||||
'woocommerce-blocks/testimonials-3-columns',
|
||||
'a8c/contact-with-map-on-the-left',
|
||||
|
||||
// Footer
|
||||
'woocommerce-blocks/footer-simple-menu-and-cart',
|
||||
],
|
||||
metadata: {
|
||||
businessType: [ 'e-commerce', 'small-medium-business' ],
|
||||
contentFocus: [ 'products', 'featured-product' ],
|
||||
audience: [ 'focused' ],
|
||||
design: [ 'sleek' ],
|
||||
features: [ 'testimonial' ],
|
||||
complexity: 'medium',
|
||||
},
|
||||
},
|
||||
template6: {
|
||||
blocks: [
|
||||
// Header
|
||||
'woocommerce-blocks/header-minimal',
|
||||
|
||||
// Body
|
||||
'a8c/heading-and-video',
|
||||
'a8c/3-column-testimonials',
|
||||
'woocommerce-blocks/product-hero',
|
||||
'a8c/quotes-2',
|
||||
'a8c/product-feature-with-buy-button',
|
||||
'a8c/simple-two-column-layout',
|
||||
'woocommerce-blocks/social-follow-us-in-social-media',
|
||||
|
||||
// Footer
|
||||
'woocommerce-blocks/footer-simple-menu-and-cart',
|
||||
],
|
||||
metadata: {
|
||||
businessType: [ 'e-commerce', 'creative', 'small-medium-business' ],
|
||||
contentFocus: [ 'services', 'storytelling', 'video' ],
|
||||
audience: [ 'focused' ],
|
||||
design: [ 'modern' ],
|
||||
features: [ 'social-media', 'video' ],
|
||||
complexity: 'high',
|
||||
},
|
||||
},
|
||||
};
|
|
@ -18,6 +18,7 @@ import {
|
|||
LookAndToneCompletionResponse,
|
||||
Header,
|
||||
Footer,
|
||||
HomepageTemplate,
|
||||
} from './types';
|
||||
import { aiWizardClosedBeforeCompletionEvent } from './events';
|
||||
import {
|
||||
|
@ -150,6 +151,24 @@ const assignFooter = assign<
|
|||
},
|
||||
} );
|
||||
|
||||
const assignHomepageTemplate = assign<
|
||||
designWithAiStateMachineContext,
|
||||
designWithAiStateMachineEvents
|
||||
>( {
|
||||
aiSuggestions: ( context, event: unknown ) => {
|
||||
return {
|
||||
...context.aiSuggestions,
|
||||
homepageTemplate: (
|
||||
event as {
|
||||
data: {
|
||||
response: HomepageTemplate;
|
||||
};
|
||||
}
|
||||
).data.response.homepage_template,
|
||||
};
|
||||
},
|
||||
} );
|
||||
|
||||
const updateWooAiStoreDescriptionOption = ( descriptionText: string ) => {
|
||||
return dispatch( OPTIONS_STORE_NAME ).updateOptions( {
|
||||
woo_ai_describe_store_description: descriptionText,
|
||||
|
@ -243,6 +262,7 @@ export const actions = {
|
|||
assignFontPairing,
|
||||
assignHeader,
|
||||
assignFooter,
|
||||
assignHomepageTemplate,
|
||||
logAIAPIRequestError,
|
||||
updateQueryStep,
|
||||
recordTracksStepViewed,
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* External dependencies
|
||||
*/
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { HOMEPAGE_TEMPLATES } from '~/customize-store/data/homepageTemplates';
|
||||
|
||||
const allowedTemplates: string[] = Object.keys( HOMEPAGE_TEMPLATES );
|
||||
|
||||
export const homepageTemplateValidator = z.object( {
|
||||
homepage_template: z
|
||||
.string()
|
||||
.refine( ( template ) => allowedTemplates.includes( template ), {
|
||||
message: 'Template not part of allowed list',
|
||||
} ),
|
||||
} );
|
||||
|
||||
export const defaultHomepageTemplate = {
|
||||
queryId: 'default_template',
|
||||
|
||||
// make sure version is updated every time the prompt is changed
|
||||
version: '2023-09-21',
|
||||
prompt: ( businessDescription: string, look: string, tone: string ) => {
|
||||
return `
|
||||
You are a WordPress theme expert and a business analyst. Analyse the following store description, merchant's chosen look and tone, template metadata, and determine the most appropriate template.
|
||||
Consider the business size based on business description, where some templates are more suited for small and medium businesses, and some for large businesses.
|
||||
Use metadata with the key "businessType" to determine the business size and type.
|
||||
This is important, respond only with ONE template identifier (e.g., { "homepage_template": "template1" }). Do not explain or add any other information since it will fail the validation.
|
||||
|
||||
Chosen look and tone: ${ look } look, ${ tone } tone.
|
||||
Business description: ${ businessDescription }
|
||||
|
||||
Templates to choose from:
|
||||
${ JSON.stringify( HOMEPAGE_TEMPLATES ) }
|
||||
`;
|
||||
},
|
||||
responseValidation: homepageTemplateValidator.parse,
|
||||
};
|
|
@ -3,3 +3,4 @@ export * from './lookAndTone';
|
|||
export * from './fontPairings';
|
||||
export * from './header';
|
||||
export * from './footer';
|
||||
export * from './homepageTemplate';
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Internal dependencies
|
||||
*/
|
||||
import { homepageTemplateValidator } from '..';
|
||||
|
||||
describe( 'homepageTemplateValidator', () => {
|
||||
it( 'should validate when template is part of the allowed list', () => {
|
||||
const validTemplate = { homepage_template: 'template1' };
|
||||
expect( () =>
|
||||
homepageTemplateValidator.parse( validTemplate )
|
||||
).not.toThrow();
|
||||
} );
|
||||
|
||||
it( 'should not validate when template is not part of the allowed list', () => {
|
||||
const invalidTemplate = {
|
||||
homepage_template: 'nonexistingtemplate',
|
||||
};
|
||||
expect( () => homepageTemplateValidator.parse( invalidTemplate ) )
|
||||
.toThrowErrorMatchingInlineSnapshot( `
|
||||
"[
|
||||
{
|
||||
\\"code\\": \\"custom\\",
|
||||
\\"message\\": \\"Template not part of allowed list\\",
|
||||
\\"path\\": [
|
||||
\\"homepage_template\\"
|
||||
]
|
||||
}
|
||||
]"
|
||||
` );
|
||||
} );
|
||||
|
||||
it( 'should not validate when template is not a string', () => {
|
||||
const invalidType = { homepage_template: 123 };
|
||||
expect( () => homepageTemplateValidator.parse( invalidType ) )
|
||||
.toThrowErrorMatchingInlineSnapshot( `
|
||||
"[
|
||||
{
|
||||
\\"code\\": \\"invalid_type\\",
|
||||
\\"expected\\": \\"string\\",
|
||||
\\"received\\": \\"number\\",
|
||||
\\"path\\": [
|
||||
\\"homepage_template\\"
|
||||
],
|
||||
\\"message\\": \\"Expected string, received number\\"
|
||||
}
|
||||
]"
|
||||
` );
|
||||
} );
|
||||
} );
|
|
@ -24,9 +24,8 @@ import { COLOR_PALETTES } from '../assembler-hub/sidebar/global-styles/color-pal
|
|||
import {
|
||||
patternsToNameMap,
|
||||
getTemplatePatterns,
|
||||
LARGE_BUSINESS_TEMPLATES,
|
||||
SMALL_MEDIUM_BUSINESS_TEMPLATES,
|
||||
} from '../assembler-hub/hooks/use-home-templates';
|
||||
import { HOMEPAGE_TEMPLATES } from '../data/homepageTemplates';
|
||||
|
||||
const browserPopstateHandler =
|
||||
() => ( sendBack: Sender< { type: 'EXTERNAL_URL_UPDATE' } > ) => {
|
||||
|
@ -278,36 +277,21 @@ const updateGlobalStyles = async ( {
|
|||
|
||||
// Update the current theme template
|
||||
const updateTemplate = async ( {
|
||||
headerSlug,
|
||||
businessSize,
|
||||
homepageTemplateId,
|
||||
footerSlug,
|
||||
}: {
|
||||
headerSlug: string;
|
||||
businessSize: 'SMB' | 'LB';
|
||||
homepageTemplateId:
|
||||
| keyof typeof SMALL_MEDIUM_BUSINESS_TEMPLATES
|
||||
| keyof typeof LARGE_BUSINESS_TEMPLATES;
|
||||
footerSlug: string;
|
||||
homepageTemplateId: keyof typeof HOMEPAGE_TEMPLATES;
|
||||
} ) => {
|
||||
const patterns = ( await resolveSelect(
|
||||
coreStore
|
||||
// @ts-ignore No types for this exist yet.
|
||||
).getBlockPatterns() ) as Pattern[];
|
||||
|
||||
const patternsByName = patternsToNameMap( patterns );
|
||||
|
||||
const headerPattern = patternsByName[ headerSlug ];
|
||||
const footerPattern = patternsByName[ footerSlug ];
|
||||
|
||||
const homepageTemplate = getTemplatePatterns(
|
||||
businessSize === 'SMB'
|
||||
? SMALL_MEDIUM_BUSINESS_TEMPLATES[ homepageTemplateId ]
|
||||
: LARGE_BUSINESS_TEMPLATES[ homepageTemplateId ],
|
||||
HOMEPAGE_TEMPLATES[ homepageTemplateId ].blocks,
|
||||
patternsByName
|
||||
);
|
||||
|
||||
const content = [ headerPattern, ...homepageTemplate, footerPattern ]
|
||||
const content = [ ...homepageTemplate ]
|
||||
.filter( Boolean )
|
||||
.map( ( pattern ) => pattern.content )
|
||||
.join( '\n\n' );
|
||||
|
@ -356,11 +340,9 @@ export const assembleSite = async (
|
|||
|
||||
try {
|
||||
await updateTemplate( {
|
||||
headerSlug: context.aiSuggestions.header,
|
||||
// TODO: Get from context
|
||||
businessSize: 'SMB',
|
||||
homepageTemplateId: 'template1',
|
||||
footerSlug: context.aiSuggestions.footer,
|
||||
homepageTemplateId: context.aiSuggestions
|
||||
.homepageTemplate as keyof typeof HOMEPAGE_TEMPLATES,
|
||||
} );
|
||||
recordEvent( 'customize_your_store_ai_update_template_success' );
|
||||
} catch ( error ) {
|
||||
|
|
|
@ -11,9 +11,8 @@ import {
|
|||
designWithAiStateMachineContext,
|
||||
designWithAiStateMachineEvents,
|
||||
FontPairing,
|
||||
Header,
|
||||
Footer,
|
||||
ColorPaletteResponse,
|
||||
HomepageTemplate,
|
||||
} from './types';
|
||||
import {
|
||||
BusinessInfoDescription,
|
||||
|
@ -26,8 +25,7 @@ import { services } from './services';
|
|||
import {
|
||||
defaultColorPalette,
|
||||
fontPairings,
|
||||
defaultHeader,
|
||||
defaultFooter,
|
||||
defaultHomepageTemplate,
|
||||
} from './prompts';
|
||||
|
||||
export const hasStepInUrl = (
|
||||
|
@ -79,8 +77,7 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
aiSuggestions: {
|
||||
defaultColorPalette: {} as ColorPaletteResponse,
|
||||
fontPairing: '' as FontPairing[ 'pair_name' ],
|
||||
header: '' as Header[ 'slug' ],
|
||||
footer: '' as Footer[ 'slug' ],
|
||||
homepageTemplate: '' as HomepageTemplate[ 'homepage_template' ],
|
||||
},
|
||||
},
|
||||
initial: 'navigate',
|
||||
|
@ -346,7 +343,7 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
success: { type: 'final' },
|
||||
},
|
||||
},
|
||||
chooseHeader: {
|
||||
chooseHomepageTemplate: {
|
||||
initial: 'pending',
|
||||
states: {
|
||||
pending: {
|
||||
|
@ -354,8 +351,8 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
src: 'queryAiEndpoint',
|
||||
data: ( context ) => {
|
||||
return {
|
||||
...defaultHeader,
|
||||
prompt: defaultHeader.prompt(
|
||||
...defaultHomepageTemplate,
|
||||
prompt: defaultHomepageTemplate.prompt(
|
||||
context
|
||||
.businessInfoDescription
|
||||
.descriptionText,
|
||||
|
@ -367,36 +364,9 @@ export const designWithAiStateMachineDefinition = createMachine(
|
|||
};
|
||||
},
|
||||
onDone: {
|
||||
actions: [ 'assignHeader' ],
|
||||
target: 'success',
|
||||
},
|
||||
},
|
||||
},
|
||||
success: { type: 'final' },
|
||||
},
|
||||
},
|
||||
chooseFooter: {
|
||||
initial: 'pending',
|
||||
states: {
|
||||
pending: {
|
||||
invoke: {
|
||||
src: 'queryAiEndpoint',
|
||||
data: ( context ) => {
|
||||
return {
|
||||
...defaultFooter,
|
||||
prompt: defaultFooter.prompt(
|
||||
context
|
||||
.businessInfoDescription
|
||||
.descriptionText,
|
||||
context.lookAndFeel
|
||||
.choice,
|
||||
context.toneOfVoice
|
||||
.choice
|
||||
),
|
||||
};
|
||||
},
|
||||
onDone: {
|
||||
actions: [ 'assignFooter' ],
|
||||
actions: [
|
||||
'assignHomepageTemplate',
|
||||
],
|
||||
target: 'success',
|
||||
},
|
||||
},
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
headerValidator,
|
||||
footerValidator,
|
||||
colorPaletteResponseValidator,
|
||||
homepageTemplateValidator,
|
||||
} from './prompts';
|
||||
|
||||
export type designWithAiStateMachineContext = {
|
||||
|
@ -27,8 +28,7 @@ export type designWithAiStateMachineContext = {
|
|||
aiSuggestions: {
|
||||
defaultColorPalette: ColorPaletteResponse;
|
||||
fontPairing: FontPairing[ 'pair_name' ];
|
||||
header: Header[ 'slug' ];
|
||||
footer: Footer[ 'slug' ];
|
||||
homepageTemplate: HomepageTemplate[ 'homepage_template' ];
|
||||
};
|
||||
// If we require more data from options, previously provided core profiler details,
|
||||
// we can retrieve them in preBusinessInfoDescription and then assign them here
|
||||
|
@ -70,3 +70,5 @@ export type FontPairing = z.infer< typeof fontChoiceValidator >;
|
|||
export type Header = z.infer< typeof headerValidator >;
|
||||
|
||||
export type Footer = z.infer< typeof footerValidator >;
|
||||
|
||||
export type HomepageTemplate = z.infer< typeof homepageTemplateValidator >;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Add homepage template AI completion and revamped header footer
|
Loading…
Reference in New Issue