gocodebox/lifterlms

View on GitHub
src/blocks/access-plan-button/index.jsx

Summary

Maintainability
C
1 day
Test Coverage
import { registerBlockType } from '@wordpress/blocks';
import {
    PanelBody,
    PanelRow,
    ButtonGroup,
    Flex,
    Disabled,
    SelectControl,
    Button,
    BaseControl,
    Spinner,
    TextControl,
} from '@wordpress/components';
import {
    InspectorControls,
    useBlockProps,
} from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import ServerSideRender from '@wordpress/server-side-render';
import apiFetch from '@wordpress/api-fetch';
import { useEffect, useState, useMemo } from '@wordpress/element';

import blockJson from './block.json';
import Icon from './icon.jsx';

const Edit = ( props ) => {
    const { attributes, setAttributes } = props;
    const blockProps = useBlockProps();
    const [ accessPlans, setAccessPlans ] = useState( [
        {
            label: __( 'No Access Plans Found', 'lifterlms' ),
            value: '',
        },
    ] );

    useEffect( () => {
        apiFetch( {
            path: '/llms/v1/access-plans',
        } )
            .then( ( plans ) => {
                const planOptions = plans.map( ( plan ) => {
                    return {
                        label: plan.title.rendered,
                        value: plan.id,
                    };
                } );

                setAccessPlans( [
                    {
                        label: __( 'Select access plan', 'lifterlms' ),
                        value: '',
                    },
                    ...planOptions,
                ] );
            } )
            .catch( () => {
                setAccessPlans( [] );
            } );
    }, [] );

    const memoizedServerSideRender = useMemo( () => {
        let emptyPlaceholder = __( 'No Access Plans found matching your selection. This block will not be displayed.', 'lifterlms' );

        if ( ! attributes.id && accessPlans.length > 0 ) {
            emptyPlaceholder = __( 'No Access Plan selected. Please choose an Access Plan from the block sidebar panel.', 'lifterlms' );
        }

        return (
            <ServerSideRender
                block={ blockJson.name }
                attributes={ attributes }
                LoadingResponsePlaceholder={ () => <Spinner /> }
                ErrorResponsePlaceholder={ () => (
                    <p className={ 'llms-block-error' }>
                        { __(
                            'Error loading content. Please check block settings are valid. This block will not be displayed.',
                            'lifterlms'
                        ) }
                    </p>
                ) }
                EmptyResponsePlaceholder={ () => (
                    <p className={ 'llms-block-empty' }>
                        { emptyPlaceholder }
                    </p>
                ) }
            />
        );
    }, [ attributes ] );

    return (
        <>
            <InspectorControls>
                <PanelBody title={ __( 'Access Plan Button Settings', 'lifterlms' ) }>
                    <PanelRow>
                        <SelectControl
                            label={ __( 'Access Plan', 'lifterlms' ) }
                            help={ __(
                                'Select the access plan to display a button for.',
                                'lifterlms'
                            ) }
                            value={ attributes.id ?? '' }
                            options={ accessPlans }
                            onChange={ ( id ) => setAttributes( { id } ) }
                        />
                    </PanelRow>
                    <PanelRow>
                        <BaseControl
                            help={ __(
                                'Controls the size of the button.',
                                'lifterlms'
                            ) }
                        >
                            <Flex direction={ 'column' }>
                                <BaseControl.VisualLabel>
                                    { __( 'Size', 'lifterlms' ) }
                                </BaseControl.VisualLabel>
                                <ButtonGroup>
                                    { [ 'Default', 'Large', 'Small' ].map( ( size ) => {
                                        const value = size.toLowerCase();

                                        return (
                                            <Button
                                                key={ value }
                                                isPrimary={
                                                    value === attributes.size
                                                }
                                                onClick={ () =>
                                                    setAttributes( {
                                                        size: value,
                                                    } )
                                                }
                                            >
                                                { size }
                                            </Button>
                                        );
                                    } ) }
                                </ButtonGroup>
                            </Flex>
                        </BaseControl>
                    </PanelRow>
                    <PanelRow>
                        <SelectControl
                            label={ __( 'Type', 'lifterlms' ) }
                            help={ __(
                                'Controls the style of the button. Your theme and/or custom CSS may alter the colors defined by these styles.',
                                'lifterlms'
                            ) }
                            value={ attributes.type }
                            options={ [
                                {
                                    label: __( 'Primary', 'lifterlms' ),
                                    value: 'primary',
                                },
                                {
                                    label: __( 'Secondary', 'lifterlms' ),
                                    value: 'secondary',
                                },
                                {
                                    label: __( 'Action', 'lifterlms' ),
                                    value: 'action',
                                },
                                {
                                    label: __( 'Danger', 'lifterlms' ),
                                    value: 'danger',
                                },
                            ] }
                            onChange={ ( type ) => setAttributes( { type } ) }
                        />
                    </PanelRow>
                    <PanelRow>
                        <TextControl
                            label={ __( 'Text', 'lifterlms' ) }
                            help={ __(
                                'The text to display on the button.',
                                'lifterlms'
                            ) }
                            value={ attributes.text }
                            onChange={ ( text ) => setAttributes( { text } ) }
                        />
                    </PanelRow>
                </PanelBody>
            </InspectorControls>
            <div { ...blockProps }>
                <Disabled>{ memoizedServerSideRender }</Disabled>
            </div>
        </>
    );
};

registerBlockType( blockJson, {
    icon: Icon,
    edit: Edit,
} );