Skip to content

Commit

Permalink
Jetpack SEO: process assistant results summary (#41585)
Browse files Browse the repository at this point in the history
* address primary buttons styles

* lower delay to 1500 on all steps

* update onStart signature and add includeResults on steps

* add results collection and summary process, remove unnecessary props on hooks, add includeResults where needed along with label

* changelog
  • Loading branch information
CGastrell authored Feb 6, 2025
1 parent d254bc6 commit 854e36c
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 68 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: other

Jetpack SEO: add completion summary step
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function AssistantWizard( { close } ) {
stepsEndRef.current?.scrollIntoView( { behavior: 'smooth' } );
};
const keywordsInputRef = useRef( null );
const [ , setResults ] = useState( {} );
const [ results, setResults ] = useState( {} );
const [ lastStepValue, setLastStepValue ] = useState( '' );

useEffect( () => {
Expand Down Expand Up @@ -52,9 +52,10 @@ export default function AssistantWizard( { close } ) {
await currentStepData?.onStart( {
fromSkip: ! lastStepValue,
stepValue: lastStepValue,
results,
} );
setIsBusy( false );
}, [ currentStepData, lastStepValue ] );
}, [ currentStepData, lastStepValue, results ] );

const handleNext = useCallback( () => {
debug( 'handleNext, stepsCount', stepsCount );
Expand Down Expand Up @@ -97,22 +98,25 @@ export default function AssistantWizard( { close } ) {
setIsBusy( true );
const stepValue = await steps[ currentStep ]?.onSubmit?.();
debug( 'stepValue', stepValue );
const newResults = {
[ steps[ currentStep ].id ]: {
value: steps[ currentStep ].value.trim(),
type: steps[ currentStep ].type,
label: steps[ currentStep ].label,
},
};
debug( 'newResults', newResults );
setResults( prev => ( { ...prev, ...newResults } ) );
if ( steps[ currentStep ].includeInResults ) {
const newResults = {
[ steps[ currentStep ].id ]: {
value: stepValue?.trim?.(),
type: steps[ currentStep ].type,
label: steps[ currentStep ].label,
},
};
debug( 'newResults', newResults );
setResults( prev => ( { ...prev, ...newResults } ) );
}
debug( 'set last step value', stepValue );
setLastStepValue( stepValue.trim() );
setLastStepValue( stepValue?.trim?.() );

if ( steps[ currentStep ]?.type === 'completion' ) {
debug( 'completion step, closing wizard' );
handleDone();
} else {
// always give half a second before moving forward
debug( 'step type', steps[ currentStep ]?.type );
handleNext();
}
}, [ currentStep, handleDone, handleNext, steps ] );
Expand All @@ -139,6 +143,7 @@ export default function AssistantWizard( { close } ) {

const handleBack = () => {
if ( currentStep > 1 ) {
setIsBusy( true );
debug( 'moving back to ' + ( currentStep - 1 ) );
setCurrentStep( currentStep - 1 );
setCurrentStepData( steps[ currentStep - 1 ] );
Expand All @@ -148,8 +153,19 @@ export default function AssistantWizard( { close } ) {
const handleSkip = useCallback( async () => {
setIsBusy( true );
await steps[ currentStep ]?.onSkip?.();
const step = steps[ currentStep ];
if ( ! results[ step.id ] && step.includeInResults ) {
setResults( prev => ( {
...prev,
[ step.id ]: {
value: '',
type: step.type,
label: step.label,
},
} ) );
}
handleNext();
}, [ currentStep, steps, handleNext ] );
}, [ currentStep, steps, handleNext, results ] );

const handleRetry = useCallback( async () => {
debug( 'handleRetry' );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@
width: unset;
}

.components-button.is-primary {
background-color: #3858E9;
}

.components-button.is-secondary {
box-shadow: inset 0 0 0 1px #3858e9, 0 0 0 currentColor;
color: #3858e9;
}

&__header {
flex: 0 0 auto;
display: flex;
Expand Down Expand Up @@ -154,10 +163,6 @@
box-shadow: none;
outline: 0;
}

.components-button.is-primary {
background-color: #3858E9;
}
}

// submit and retry buttons
Expand Down Expand Up @@ -204,15 +209,6 @@
align-items: center;
gap: 16px;
animation: assistantInputAppear 0.3s ease-out;

.components-button.is-primary {
background-color: #3858E9;
}

.components-button.is-secondary {
box-shadow: inset 0 0 0 1px #3858e9, 0 0 0 currentColor;
color: #3858e9;
}
}

&__completion {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,29 @@ export interface Message {

export type OptionMessage = Pick< Message, 'id' | 'content' >;

export interface Results {
[ key: string ]: {
value: string;
type: string;
label: string;
};
}

export interface Step {
id: string;
title: string;
label?: string;
messages: Message[];
type: StepType;
onStart?: ( options?: { fromSkip: boolean; stepValue: string } ) => void;
onStart?: ( options?: { fromSkip: boolean; stepValue: string; results: Results } ) => void;
onSubmit?: () => Promise< string >;
onSkip?: () => void;
value?: string;
setValue?:
| React.Dispatch< React.SetStateAction< string > >
| React.Dispatch< React.SetStateAction< Array< string > > >;
setCompleted?: React.Dispatch< React.SetStateAction< boolean > >;
completed?: boolean;
autoAdvance?: number;
includeInResults?: boolean;

// Input step properties
placeholder?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { createInterpolateElement, useCallback, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useMessages } from './wizard-messages';
import type { Step } from './types';
import type { Step, Results } from './types';

export const useCompletionStep = (): Step => {
const [ keywords, setKeywords ] = useState( '' );
const [ completed, setCompleted ] = useState( false );
const [ value, setValue ] = useState( '' );
const { messages, setMessages, addMessage } = useMessages();

const startHandler = useCallback(
async ( { fromSkip } ) => {
async ( { fromSkip, results } ) => {
const firstMessages = [];

if ( fromSkip ) {
firstMessages.push( {
content: __( 'Skipped!', 'jetpack' ),
Expand All @@ -19,32 +19,62 @@ export const useCompletionStep = (): Step => {
} );
}
setMessages( firstMessages );
await new Promise( resolve => setTimeout( resolve, 2000 ) );

await new Promise( resolve => setTimeout( resolve, 1500 ) );

const resultsString = Object.values( results )
.map( ( result: Results[ string ] ) => `${ result.value ? '✅' : '❌' } ${ result.label }` )
.join( '<br />' );

addMessage( {
content: createInterpolateElement(
"Here's your updated checklist:<br />✅ Title<br />✅ Meta description<br /><br />",
`Here's your updated checklist:<br />${ resultsString }<br /><br />`,
{
br: <br />,
}
),
id: '1',
} );
addMessage( {
content: createInterpolateElement(
__(
'<strong>SEO optimization complete! 🎉</strong><br/>Your blog post is now search-engine friendly.',
'jetpack'

const incomplete: { total: number; completed: number } = Object.values( results ).reduce(
( acc: { total: number; completed: number }, result: Results[ string ] ) => {
const total = acc.total + 1;
const completed = acc.completed + ( result.value ? 1 : 0 );
return { total, completed };
},
{ total: 0, completed: 0 }
) as { total: number; completed: number };

const incompleteString =
incomplete.completed === incomplete.total
? ''
: `${ incomplete.completed } out of ${ incomplete.total }`;

if ( incompleteString ) {
addMessage( {
content: createInterpolateElement(
`<strong>You've optimized ${ incompleteString } items! 🎉</strong><br />Your post is looking great! Come back anytime to complete the rest.`,
{
strong: <strong />,
br: <br />,
}
),
{ br: <br />, strong: <strong /> }
),
showIcon: false,
id: '3',
} );
addMessage( {
content: __( 'Happy blogging! 😊', 'jetpack' ),
showIcon: false,
id: '4',
} );
id: '2',
} );
} else {
addMessage( {
content: createInterpolateElement(
__(
'<strong>SEO optimization complete! 🎉</strong><br/>Your blog post is now search-engine friendly.<br />Happy blogging! 😊',
'jetpack'
),
{ br: <br />, strong: <strong /> }
),
showIcon: false,
id: '3',
} );
}

return 'completion';
},
[ setMessages, addMessage ]
Expand All @@ -58,9 +88,7 @@ export const useCompletionStep = (): Step => {
type: 'completion',
onStart: startHandler,
submitCtaLabel: __( 'Done!', 'jetpack' ),
completed,
setCompleted,
value: keywords,
setValue: setKeywords,
value,
setValue,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const useMetaDescriptionStep = (): Step => {
const [ metaDescriptionOptions, setMetaDescriptionOptions ] = useState< OptionMessage[] >( [] );
const { messages, setMessages, addMessage, editLastMessage, setSelectedMessage } = useMessages();
const { editPost } = useDispatch( 'core/editor' );
const [ completed, setCompleted ] = useState( false );

const handleMetaDescriptionSelect = useCallback(
( option: OptionMessage ) => {
Expand All @@ -22,7 +21,6 @@ export const useMetaDescriptionStep = (): Step => {
const handleMetaDescriptionSubmit = useCallback( async () => {
await editPost( { meta: { advanced_seo_description: selectedMetaDescription } } );
addMessage( { content: __( 'Meta description updated! ✅', 'jetpack' ) } );
setCompleted( true );
return selectedMetaDescription;
}, [ selectedMetaDescription, addMessage, editPost ] );

Expand Down Expand Up @@ -54,7 +52,7 @@ export const useMetaDescriptionStep = (): Step => {
'Explore breathtaking flower and plant photography in our Flora Guide, featuring tips and inspiration for gardening and plant enthusiasts to enhance their outdoor spaces.',
},
] ),
3000
1500
)
);
}
Expand Down Expand Up @@ -90,7 +88,7 @@ export const useMetaDescriptionStep = (): Step => {
'Explore breathtaking flower and plant photography in our Flora Guide, featuring tips and inspiration for gardening and plant enthusiasts to enhance their outdoor spaces.',
},
] ),
3000
1500
)
);

Expand All @@ -101,6 +99,7 @@ export const useMetaDescriptionStep = (): Step => {
return {
id: 'meta',
title: __( 'Add meta description', 'jetpack' ),
label: __( 'Meta description', 'jetpack' ),
messages: messages,
type: 'options',
options: metaDescriptionOptions,
Expand All @@ -112,7 +111,6 @@ export const useMetaDescriptionStep = (): Step => {
onStart: handleMetaDescriptionGenerate,
value: selectedMetaDescription,
setValue: setSelectedMetaDescription,
completed,
setCompleted,
includeInResults: true,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const useTitleStep = (): Step => {
const [ titleOptions, setTitleOptions ] = useState< OptionMessage[] >( [] );
const { editPost } = useDispatch( 'core/editor' );
const { messages, setMessages, addMessage, editLastMessage, setSelectedMessage } = useMessages();
const [ completed, setCompleted ] = useState( false );
const [ prevStepValue, setPrevStepValue ] = useState();

const handleTitleSelect = useCallback(
Expand Down Expand Up @@ -57,7 +56,7 @@ export const useTitleStep = (): Step => {
'Flora Guide: Beautiful Photos of Flowers and Plants for Gardening Enthusiasts',
},
] ),
3000
1500
)
);
}
Expand Down Expand Up @@ -107,7 +106,7 @@ export const useTitleStep = (): Step => {
'Flora Guide: Beautiful Photos of Flowers and Plants for Gardening Enthusiasts',
},
] ),
2000
1500
)
);
setTitleOptions( [ ...titleOptions, ...newTitles ] );
Expand All @@ -117,13 +116,13 @@ export const useTitleStep = (): Step => {
const handleTitleSubmit = useCallback( async () => {
await editPost( { title: selectedTitle, meta: { jetpack_seo_html_title: selectedTitle } } );
addMessage( { content: __( 'Title updated! ✅', 'jetpack' ) } );
setCompleted( true );
return selectedTitle;
}, [ selectedTitle, addMessage, editPost ] );

return {
id: 'title',
title: __( 'Optimise Title', 'jetpack' ),
label: __( 'Title', 'jetpack' ),
messages,
type: 'options',
options: titleOptions,
Expand All @@ -135,7 +134,6 @@ export const useTitleStep = (): Step => {
onStart: handleTitleGenerate,
value: selectedTitle,
setValue: setSelectedTitle,
completed,
setCompleted,
includeInResults: true,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ export const useWelcomeStep = (): Step => {
id: '2',
},
],
autoAdvance: 2000,
autoAdvance: 1500,
};
};

0 comments on commit 854e36c

Please sign in to comment.