godaddy-wordpress/go

View on GitHub
.dev/assets/admin/js/common-action-modal/index.js

Summary

Maintainability
A
0 mins
Test Coverage
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,
};