-
Notifications
You must be signed in to change notification settings - Fork 877
/
ai-assessment-fixes-button.js
124 lines (108 loc) · 4.48 KB
/
ai-assessment-fixes-button.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import PropTypes from "prop-types";
import { __ } from "@wordpress/i18n";
import { useCallback, useRef, useState } from "@wordpress/element";
import { doAction } from "@wordpress/hooks";
import { useSelect, useDispatch } from "@wordpress/data";
/* Yoast dependencies */
import { IconAIFixesButton } from "@yoast/components";
import { Modal, useToggleState } from "@yoast/ui-library";
import { Paper } from "yoastseo";
/* Internal dependencies */
import { ModalContent } from "./modal-content";
import { SparklesIcon } from "./sparkles-icon";
/**
* The AI Assessment Fixes button component.
*
* @param {string} id The assessment ID for which the AI fixes should be applied to.
* @param {boolean} isPremium Whether the premium add-on is active.
*
* @returns {JSX.Element} The AI Assessment Fixes button.
*/
const AIAssessmentFixesButton = ( { id, isPremium } ) => {
const aiFixesId = id + "AIFixes";
const ariaLabel = __( "Optimize with AI", "wordpress-seo" );
const [ isModalOpen, , , setIsModalOpenTrue, setIsModalOpenFalse ] = useToggleState( false );
const activeAIButtonId = useSelect( select => select( "yoast-seo/editor" ).getActiveAIFixesButton(), [] );
const activeMarker = useSelect( select => select( "yoast-seo/editor" ).getActiveMarker(), [] );
const { setActiveAIFixesButton, setActiveMarker, setMarkerPauseStatus } = useDispatch( "yoast-seo/editor" );
const focusElementRef = useRef( null );
const [ buttonClass, setButtonClass ] = useState( "" );
/**
* Handles the button press state.
* @returns {void}
*/
const handlePressedButton = () => {
// If there is an active marker when the AI fixes button is clicked, remove it.
if ( activeMarker ) {
setActiveMarker( null );
setMarkerPauseStatus( false );
// Remove highlighting from the editor.
window.YoastSEO.analysis.applyMarks( new Paper( "", {} ), [] );
}
/* If the current pressed button ID is the same as the active AI button id,
we want to set the active AI button to null. Otherwise, update the active AI button ID. */
if ( aiFixesId === activeAIButtonId ) {
setActiveAIFixesButton( null );
} else {
setActiveAIFixesButton( aiFixesId );
}
// Dismiss the tooltip when the button is pressed.
setButtonClass( "" );
};
const handleClick = useCallback( () => {
if ( isPremium ) {
doAction( "yoast.ai.fixAssessments", aiFixesId );
/* Only handle the pressed button state in Premium.
We don't want to change the background color of the button and other styling when it's pressed in Free.
This is because clicking on the button in Free will open the modal, and the button will not be in a pressed state. */
handlePressedButton();
} else {
setIsModalOpenTrue();
}
}, [ handlePressedButton, setIsModalOpenTrue ] );
// The button is pressed when the active AI button id is the same as the current button id.
const isButtonPressed = activeAIButtonId === aiFixesId;
// Add tooltip classes on mouse enter and remove them on mouse leave.
const handleMouseEnter = useCallback( () => {
// Add tooltip classes on mouse enter
setButtonClass( "yoast-tooltip yoast-tooltip-w" );
}, [] );
const handleMouseLeave = useCallback( () => {
// Remove tooltip classes on mouse leave
setButtonClass( "" );
}, [] );
// Generate a unique gradient ID for the SparklesIcon component.
const gradientId = `gradient-${ Math.random().toString( 36 ).substring( 2, 9 ) }`;
return (
<>
<IconAIFixesButton
onClick={ handleClick }
ariaLabel={ ariaLabel }
onMouseEnter={ handleMouseEnter }
onMouseLeave={ handleMouseLeave }
id={ aiFixesId }
className={ `ai-button ${buttonClass}` }
pressed={ isButtonPressed }
>
<SparklesIcon pressed={ isButtonPressed } gradientId={ gradientId } />
{
// We put the logic for the Upsell component in place.
// The Modal below is only a placeholder/mock. When we have the design for the real upsell, the modal should be replaced.
isModalOpen && <Modal className="yst-introduction-modal" isOpen={ isModalOpen } onClose={ setIsModalOpenFalse } initialFocus={ focusElementRef }>
<Modal.Panel className="yst-max-w-lg yst-p-0 yst-rounded-3xl yst-introduction-modal-panel">
<ModalContent onClose={ setIsModalOpenFalse } focusElementRef={ focusElementRef } />
</Modal.Panel>
</Modal>
}
</IconAIFixesButton>
</>
);
};
AIAssessmentFixesButton.propTypes = {
id: PropTypes.string.isRequired,
isPremium: PropTypes.bool,
};
AIAssessmentFixesButton.defaultProps = {
isPremium: false,
};
export default AIAssessmentFixesButton;