import * as React from 'react'; import { useEffect, useState } from 'react'; import { ThemeProvider } from '@elementor/editor-ui'; import { isExperimentActive } from '@elementor/editor-v1-adapters'; import { useMixpanel } from '@elementor/events'; import { httpService } from '@elementor/http-client'; import { AlertCircleIcon, CheckIcon } from '@elementor/icons'; import { bindDialog, Button, CloseButton, Dialog, DialogContent, DialogHeader, DialogTitle, Popover, Stack, TextField, usePopupState, } from '@elementor/ui'; import { __ } from '@wordpress/i18n'; import { EXPERIMENT_NAME, FEEDBACK_TOGGLE_EVENT } from '../../extensions/feedback/feedback-consts'; import { type ExtendedWindow } from '../../types'; const checkIfUserIsConnected = () => { const extendedWindow = window as unknown as ExtendedWindow; return ( extendedWindow?.elementorCommon?.config.library_connect.is_connected || extendedWindow?.elementorPro?.config.isActive ); }; type FeedbackResult = { success: boolean; message: string; }; export default function SendFeedbackPopupLocation() { const isActive = isExperimentActive( EXPERIMENT_NAME ); const extendedWindow = window as unknown as ExtendedWindow; const [ isUserConnected, setIsUserConnected ] = useState< boolean >( checkIfUserIsConnected() ); const connectUrl = extendedWindow?.elementor?.config.user.top_bar.connect_url; const [ feedbackContent, setFeedbackContent ] = useState( '' ); const [ feedbackResult, setFeedbackResult ] = useState< FeedbackResult | null >( null ); const [ submitDisabled, setSubmitDisabled ] = useState( true ); const { dispatchEvent: trackEvent = ( ...args: unknown[] ) => void args } = useMixpanel(); const popupState = usePopupState( { variant: 'dialog', popupId: FEEDBACK_TOGGLE_EVENT, } ); const [ isFetching, setIsFetching ] = useState( false ); useEffect( () => { const handler = () => { popupState.toggle(); // reason to re-check: clicking "connect to elementor" closes the dialog. At this time the user can perform connect, and the state might change externally. setIsUserConnected( checkIfUserIsConnected() ); setFeedbackResult( null ); trackEvent( 'feedback_modal_opened', { source: 'top_bar', context: 'v4_beta', } ); }; window.addEventListener( FEEDBACK_TOGGLE_EVENT, handler ); return () => { window.removeEventListener( FEEDBACK_TOGGLE_EVENT, handler ); }; }, [ popupState, trackEvent ] ); useEffect( () => { setSubmitDisabled( feedbackContent.trim().length < 10 || ! isUserConnected || isFetching ); }, [ feedbackContent, feedbackResult, isUserConnected, isFetching ] ); const handleClose = () => { popupState.close(); trackEvent( 'feedback_modal_closed', { feedback_text: feedbackContent, } ); }; const handleStartAntoher = () => { setFeedbackContent( '' ); setFeedbackResult( null ); }; const submitFeedback = () => { setIsFetching( true ); httpService() .post( 'elementor/v1/feedback/submit', { description: feedbackContent.trim(), } ) .then( ( response ) => { setFeedbackResult( { message: response.data.message, success: response.data.success, } ); // check if unauthorized - not signed in or expired, needs to reconnect to my-elementor account if ( ( ! response.data.success && response.data.code.toString() === '401' ) || response.data.code.toString() === '403' ) { setIsUserConnected( false ); } trackEvent( response.data.success ? 'feedback_submitted' : 'feedback_error', { feedback_length: feedbackContent.length, error_type: response.data.success ? undefined : 'server', error_message: response.data.success ? undefined : response.data.message, } ); } ) .finally( () => setIsFetching( false ) ); }; if ( ! isActive ) { return null; } return ( handleClose() }> { __( 'Submit Feedback', 'elementor' ) } { isUserConnected ? ( <> ) => setFeedbackContent( event.target.value ) } value={ feedbackContent } /> { feedbackResult && ( <> { feedbackResult.success ? ( ) : ( ) } { feedbackResult.message } ) } { feedbackResult?.success ? ( ) : ( ) } ) : ( <> ) } ); }