/** * External dependencies */ import { useState } from '@wordpress/element'; import { useDispatch } from '@wordpress/data'; import { Button } from '@wordpress/components'; import { Pill } from '@woocommerce/components'; import { __ } from '@wordpress/i18n'; import { recordEvent } from '@woocommerce/tracks'; import { PLUGINS_STORE_NAME } from '@woocommerce/data'; /** * Internal dependencies */ import { PluginCardBody } from '~/marketing/components'; import { RecommendedPlugin } from '~/marketing/types'; import { getInAppPurchaseUrl } from '~/lib/in-app-purchase'; import { createNoticesFromResponse } from '~/lib/notices'; import { useIsPluginInstalledNotActivated } from './useIsPluginInstalledNotActivated'; import './PluginCardBody.scss'; type SmartPluginCardBodyProps = { plugin: RecommendedPlugin; onInstalledAndActivated?: () => void; }; /** * A smart wrapper around PluginCardBody that accepts a `plugin` prop. * * It knows how to render the action button for the plugin, * and has the logic for installing and activating plugin. * This allows users to install and activate multiple plugins at the same time. */ export const SmartPluginCardBody = ( { plugin, onInstalledAndActivated = () => {}, }: SmartPluginCardBodyProps ) => { const [ currentPlugin, setCurrentPlugin ] = useState< string | null >( null ); const { installAndActivatePlugins } = useDispatch( PLUGINS_STORE_NAME ); const { isPluginInstalledNotActivated } = useIsPluginInstalledNotActivated(); /** * Install and activate a plugin. * * When the process is successful, `onInstalledAndActivated` will be called. * A success notice will be displayed. * * When the process is not successful, an error notice will be displayed. */ const installAndActivate = async () => { setCurrentPlugin( plugin.product ); try { recordEvent( 'marketing_recommended_extension', { name: plugin.title, } ); const response = await installAndActivatePlugins( [ plugin.product, ] ); onInstalledAndActivated(); createNoticesFromResponse( response ); } catch ( error ) { createNoticesFromResponse( error ); } setCurrentPlugin( null ); }; const renderButton = () => { const buttonDisabled = !! currentPlugin; if ( isPluginInstalledNotActivated( plugin.product ) ) { return ( ); } if ( plugin.direct_install ) { return ( ); } return ( ); }; return ( } name={ plugin.title } pills={ plugin.tags.map( ( tag ) => ( { tag.name } ) ) } description={ plugin.description } button={ renderButton() } /> ); };