Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions assets/apps/dashboard/src/Components/Content/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,28 +139,30 @@ const Settings = () => {
<div className="shrink-0 w-full lg:w-[300px]">
<Menu tab={tab} setTab={setTab} />
</div>
<Card className="grow">
{tab === 'general' && (
<TransitionWrapper>
<GeneralTabContent />
</TransitionWrapper>
)}
{tab === 'performance' && (
<TransitionWrapper>
<PerformanceTabContent />
</TransitionWrapper>
)}
{tab === 'white-label' && (
<TransitionWrapper>
<WhiteLabelTabContent />
</TransitionWrapper>
)}
{tab === 'manage-modules' && (
<TransitionWrapper>
<ManageModulesTabContent />
</TransitionWrapper>
)}
</Card>
<div className="grow flex flex-col gap-6">
<Card>
{tab === 'general' && (
<TransitionWrapper>
<GeneralTabContent />
</TransitionWrapper>
)}
{tab === 'performance' && (
<TransitionWrapper>
<PerformanceTabContent />
</TransitionWrapper>
)}
{tab === 'white-label' && (
<TransitionWrapper>
<WhiteLabelTabContent />
</TransitionWrapper>
)}
{tab === 'manage-modules' && (
<TransitionWrapper>
<ManageModulesTabContent />
</TransitionWrapper>
)}
</Card>
</div>
</div>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/* global neveDash */
import { useSelect } from '@wordpress/data';
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 Card from '../../../Layout/Card';
import usePluginActions from '../../../Hooks/usePluginActions';
import {
NEVE_HIDE_PLUGINS,
NEVE_PLUGIN_ICON_MAP,
NEVE_STORE,
} from '../../../utils/constants';

const PROMOTED_SLUGS = ['optimole-wp', 'wp-cloudflare-page-cache'];

const PluginCard = ({ slug }) => {
const ICON = NEVE_PLUGIN_ICON_MAP[slug] || LucidePuzzle;
// Titles and descriptions are already localized in inc/admin/dashboard/main.php.
const { title, description } = neveDash.plugins[slug];

const [error, setError] = useState(null);
const [success, setSuccess] = useState(false);

const { doPluginAction, loading, buttonText } = usePluginActions(
slug,
true
);

const isPluginActive = useSelect(
(select) => select(NEVE_STORE).getPlugins()[slug]?.cta === 'deactivate'
);

useEffect(() => {
if (!success) {
return;
}

const timeoutId = window.setTimeout(() => {
setSuccess(false);
}, 1500);

return () => window.clearTimeout(timeoutId);
}, [success]);

if (isPluginActive && !success) {
return null;
}
Comment on lines +50 to +52

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 (
<div
className="flex flex-col h-full p-4 bg-white rounded-lg border border-gray-100"
data-plugin={slug}
>
<div className="flex gap-3 items-center">
<ICON className="size-6 text-blue-500 shrink-0" />
<h3 className="text-sm font-medium text-gray-900">{title}</h3>

{success && (
<div className="ml-auto">
<TransitionInOut show>
<Pill type="success">{__('Active', 'neve')}</Pill>
</TransitionInOut>
</div>
)}
</div>

{/* grow keeps the CTAs aligned when descriptions wrap to different heights */}
<p className="grow text-sm leading-relaxed text-gray-600 mt-2">
{description}
</p>

{!success && (
<button
onClick={handleClick}
disabled={loading}
className={cn(
'mt-3 self-start text-blue-600 hover:text-blue-700 text-sm font-medium flex items-center',
{ 'opacity-75 cursor-not-allowed': loading }
)}
>
{loading && (
<LoaderCircle size={14} className="animate-spin mr-2" />
)}
<span>{buttonText}</span>
</button>
)}

{error && (
<div className="mt-2">
<Toast type="error" dismiss={setError} message={error} />
</div>
)}
</div>
);
};

const PerformancePlugins = () => {
const plugins = useSelect((select) => select(NEVE_STORE).getPlugins(), []);

// A promoted plugin can be absent entirely, e.g. Super Page Cache is dropped when SPC Pro is installed.
const availableSlugs = PROMOTED_SLUGS.filter(
(slug) => plugins[slug] && plugins[slug].cta !== 'deactivate'
);

if (NEVE_HIDE_PLUGINS || availableSlugs.length < 1) {
return null;
}

return (
<Card
flat
className="mt-6 pt-6 border-t border-gray-200"
icon={<LucideRocket size={18} />}
title={__('Recommended Plugins', 'neve')}
>
<div
className={cn('grid gap-4', {
'md:grid-cols-2': availableSlugs.length > 1,
})}
>
{availableSlugs.map((slug) => (
<PluginCard key={slug} slug={slug} />
))}
</div>
</Card>
);
};

export default PerformancePlugins;
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ToggleControl from '../../Controls/ToggleControl';
import Button from '../../Common/Button';
import useLicenseData from '../../../Hooks/useLicenseData';
import OptionGroup from './OptionGroup';
import PerformancePlugins from './PerformancePlugins';

const LOCAL_HOSTING_OPTION = 'enable_local_fonts';

Expand Down Expand Up @@ -115,6 +116,8 @@ export default () => {

{(isLicenseValid && <ProModuleSettings />) || <DummySettings />}
</div>

<PerformancePlugins />
</>
);
};
6 changes: 4 additions & 2 deletions assets/apps/dashboard/src/Layout/Card.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ export default ({
afterTitle,
className = '',
id = null,
flat = false,
}) => {
// `flat` keeps the header styling but drops the box, for cards nested inside another one.
const classes = cn(
[
'p-6 rounded-lg shadow-sm',
{
'bg-white': !className.includes('bg-'),
'p-6 rounded-lg shadow-sm': !flat,
'bg-white': !flat && !className.includes('bg-'),
},
],
className
Expand Down
Loading