.dev/assets/admin/js/common-action-modal/index.js
import PropTypes from 'prop-types';
import { safeHTML } from '@wordpress/dom';
import { Button, ButtonGroup, CheckboxControl, Modal, TextControl } from '@wordpress/components';
import { useCallback, useEffect, useState } from '@wordpress/element';
const language = document.documentElement.getAttribute( 'lang' ) || 'en-US';
const fetchData = async ( apiUrl, getParams = null ) => {
const params = {
...getParams,
language,
random: 1,
};
let paramString = '';
Object.keys( params ).forEach( ( key ) => paramString += `${ key }=${ params[ key ] }&` );
try {
const response = await fetch( `${ apiUrl }?${ paramString.slice( 0, -1 ) }` );
if ( ! response.ok ) {
return null;
}
return await response.json();
} catch ( e ) {
return null;
}
};
const DeactivateModal = ( { apiUrl, getParams, isEvent, pageData } ) => {
const [ href, setHref ] = useState( null );
const [ isOpen, setOpen ] = useState( false );
const [ feedbackData, setFeedbackData ] = useState( null );
const [ formData, setFormData ] = useState( {} );
useEffect( () => {
const getData = async () => {
const data = await fetchData( apiUrl, getParams );
if ( data && data.can_submit_feedback ) {
window.addEventListener( 'click', clickHandler );
setInitialData( data );
}
};
getData();
return () => {
window.removeEventListener( 'click', clickHandler );
};
}, [] );
const setInitialData = ( data ) => {
setFeedbackData( data );
const textFields = {};
data.choices.forEach( ( choice ) => {
if ( !! choice.text_field ) {
textFields[ choice.text_field ] = '';
}
} );
setFormData( {
choices: [],
domain: pageData.domain,
go_theme_version: pageData.goThemeVersion,
hostname: pageData.hostname,
language,
wp_version: pageData.wpVersion,
...textFields,
} );
};
const clickHandler = useCallback( ( e ) => {
if ( ! isEvent( e ) ) {
return;
}
e.preventDefault();
setOpen( true );
setHref( e.target.href );
} );
const onCheckboxChange = ( isChecked, slug ) => {
setFormData( ( prevFormData ) => {
const choices = prevFormData.choices;
if ( isChecked ) {
choices.push( slug );
} else {
choices.splice( choices.indexOf( slug ), 1 );
}
return {
...prevFormData,
choices,
};
} );
};
const onTextChange = ( key, value ) => {
setFormData( ( prevFormData ) => ( {
...prevFormData,
[ key ]: value,
} ) );
};
const onAction = async ( submit = false ) => {
if ( submit && formData.choices.length >= feedbackData.choices_min ) {
await fetch( apiUrl, {
body: JSON.stringify( formData ),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
} );
}
setOpen( false );
window.location.href = href;
};
if ( ! isOpen || ! feedbackData ) {
return null;
}
return (
<Modal
className="go-deactivate-modal"
onRequestClose={ () => setOpen( false ) }
title={ feedbackData.labels.title }
>
<div className="go-deactivate-modal__checkbox">
{ feedbackData.choices.map( ( choice ) => {
const isChecked = formData.choices.indexOf( choice.slug ) >= 0;
return (
<div key={ choice.slug }>
<CheckboxControl
checked={ isChecked }
label={ choice.label }
onChange={ ( checked ) => onCheckboxChange( checked, choice.slug ) }
/>
{ !! choice.text_field && (
<TextControl
className={ `go-deactivate-modal__text ${
isChecked ? 'show' : ''
}` }
onChange={ ( value ) => onTextChange( choice.text_field, value ) }
value={ formData[ choice.text_field ] }
/>
) }
</div>
);
} ) }
</div>
<ButtonGroup>
<Button
className="go-deactivate-modal__button"
onClick={ () => onAction( true ) }
variant="primary"
>
{ feedbackData.labels.submit_deactivate }
</Button>
<Button
className="go-deactivate-modal__button"
onClick={ () => onAction( false ) }
variant="link"
>
{ feedbackData.labels.skip_deactivate }
</Button>
</ButtonGroup>
<footer className="go-deactivate-modal__footer">
<div
dangerouslySetInnerHTML={ {
__html: safeHTML( feedbackData.labels.privacy_disclaimer ),
} }
/>
</footer>
</Modal>
);
};
DeactivateModal.propTypes = {
apiUrl: PropTypes.string.isRequired,
getParams: PropTypes.object,
isEvent: PropTypes.func.isRequired,
pageData: PropTypes.object.isRequired,
};
export {
DeactivateModal as default,
fetchData,
};