HEX
Server: nginx
System: Linux pool195-106-36.bur.atomicsites.net 6.12.57+deb12-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.12.57-1~bpo12+1 (2025-11-17) x86_64
User: (0)
PHP: 8.3.32
Disabled: pcntl_fork
Upload Files
File: /wordpress/plugins/jetpack/16.0/_inc/content-guidelines-ai/components/block-suggestion-buttons.jsx
import { useAiFeature } from '@automattic/jetpack-ai-client';
import { Button } from '@wordpress/components';
import { useDispatch, useSelect } from '@wordpress/data';
import { useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { store as noticesStore } from '@wordpress/notices';
import { STORE_NAME } from '../constants';
import { suggestGuidelines } from '../lib/api';
import { acceptBlockSuggestion } from '../lib/dom';
import { recordGuidelinesEvent } from '../lib/tracks';
import { AI_STORE_NAME } from '../store';

export default function BlockSuggestionButtons( { blockName, blockModal } ) {
	const { createErrorNotice } = useDispatch( noticesStore );
	const { startSectionLoading, stopSectionLoading, setSuggestion, clearSuggestion } =
		useDispatch( AI_STORE_NAME );
	const { hasFeature } = useAiFeature();

	const blockLoading = useSelect(
		select => select( AI_STORE_NAME ).isSectionLoading( blockName ),
		[ blockName ]
	);

	const suggestion = useSelect(
		select => select( AI_STORE_NAME ).getSuggestion( blockName ),
		[ blockName ]
	);

	const saved = useSelect(
		select => select( STORE_NAME ).getBlockGuideline( blockName ),
		[ blockName ]
	);

	const handleGenerate = useCallback( async () => {
		const action = saved ? 'improve' : 'generate';
		recordGuidelinesEvent( 'generate', { type: 'block', slug: blockName, action } );

		const textarea = blockModal?.querySelector( '.components-textarea-control__input' );
		const currentText = textarea?.value || '';

		startSectionLoading( blockName );
		try {
			const existingContent = currentText ? { [ blockName ]: currentText } : {};
			const response = await suggestGuidelines( [ blockName ], existingContent );
			const text = response?.suggestions?.[ blockName ];
			if ( ! text ) {
				throw new Error( 'No suggestion returned.' );
			}
			setSuggestion( blockName, text );
		} catch {
			createErrorNotice( __( 'Failed to generate guidelines. Please try again.', 'jetpack' ), {
				type: 'snackbar',
			} );
		} finally {
			stopSectionLoading( blockName );
		}
	}, [
		blockModal,
		blockName,
		saved,
		startSectionLoading,
		stopSectionLoading,
		setSuggestion,
		createErrorNotice,
	] );

	const handleAccept = useCallback( () => {
		recordGuidelinesEvent( 'accept', { type: 'block', slug: blockName } );
		acceptBlockSuggestion( blockModal, blockName, suggestion, clearSuggestion );
	}, [ blockModal, blockName, suggestion, clearSuggestion ] );

	const handleDismiss = useCallback( () => {
		recordGuidelinesEvent( 'dismiss', { type: 'block', slug: blockName } );
		clearSuggestion( blockName );
	}, [ blockName, clearSuggestion ] );

	if ( suggestion ) {
		return (
			<div className="jetpack-content-guidelines-ai__suggestion-actions">
				<Button variant="primary" onClick={ handleAccept }>
					{ __( 'Accept suggestion', 'jetpack' ) }
				</Button>
				<Button variant="tertiary" onClick={ handleDismiss }>
					{ __( 'Dismiss', 'jetpack' ) }
				</Button>
			</div>
		);
	}

	const generateLabel = __( 'Generate guidelines', 'jetpack' );
	const improveLabel = __( 'Improve guidelines', 'jetpack' );
	const label = saved ? improveLabel : generateLabel;

	return (
		<div className="jetpack-content-guidelines-ai__suggestion-actions">
			<Button
				variant="secondary"
				onClick={ handleGenerate }
				disabled={ blockLoading || ! hasFeature }
				accessibleWhenDisabled
				className="jetpack-content-guidelines-ai__section-generate-button"
			>
				{ label }
			</Button>
		</div>
	);
}