diff --git a/assets/apps/dashboard/src/Components/Content/Settings/PerformancePlugins.js b/assets/apps/dashboard/src/Components/Content/Settings/PerformancePlugins.js new file mode 100644 index 0000000000..4e59635aee --- /dev/null +++ b/assets/apps/dashboard/src/Components/Content/Settings/PerformancePlugins.js @@ -0,0 +1,161 @@ +/* global neveDash */ +import { useEffect, useState } from '@wordpress/element'; +import { __ } from '@wordpress/i18n'; +import cn from 'classnames'; +import { LoaderCircle, LucidePuzzle, LucideRocket } from 'lucide-react'; + +import Pill from '../../Common/Pill'; +import Toast from '../../Common/Toast'; +import TransitionInOut from '../../Common/TransitionInOut'; +import ControlWrap from '../../Controls/ControlWrap'; +import usePluginActions from '../../../Hooks/usePluginActions'; +import { + NEVE_HIDE_PLUGINS, + NEVE_PLUGIN_ICON_MAP, +} from '../../../utils/constants'; + +const PROMOTED_SLUGS = ['optimole-wp', 'wp-cloudflare-page-cache']; + +// How long the "Active" pill stays up before the card removes itself. +const ACTIVE_PILL_TIMEOUT = 1500; + +const PluginCard = ({ slug, data, onDismiss }) => { + const ICON = NEVE_PLUGIN_ICON_MAP[slug] || LucidePuzzle; + // Titles and descriptions are already localized in inc/admin/dashboard/main.php. + const { title, description } = data; + + const [error, setError] = useState(null); + const [success, setSuccess] = useState(false); + + const { doPluginAction, loading, buttonText } = usePluginActions( + slug, + true + ); + + useEffect(() => { + if (!success) { + return; + } + + // Only `success` belongs in the deps: onDismiss is recreated on every + // parent render and would restart a countdown already in progress. + const timeoutId = window.setTimeout(() => { + onDismiss(slug); + }, ACTIVE_PILL_TIMEOUT); + + return () => window.clearTimeout(timeoutId); + }, [success]); + + const handleClick = async () => { + setError(null); + + window.tiTrk?.with('neve').set(slug, { + feature: 'performance-plugin-promo', + featureComponent: slug, + }); + + const result = await doPluginAction(); + + if (result.success) { + setSuccess(true); + + return; + } + + setError(result.error); + }; + + return ( +
+ {description} +
+ + {!success && ( + + )} + + {error && ( +