Skip to content

Commit

Permalink
Merge pull request #350 from newfold-labs/PRESS0-2212
Browse files Browse the repository at this point in the history
Homepage Plugins nudge - UI
  • Loading branch information
circlecube authored Oct 9, 2024
2 parents af885e2 + d634220 commit 1c4a5a1
Show file tree
Hide file tree
Showing 13 changed files with 410 additions and 15 deletions.
2 changes: 1 addition & 1 deletion build/index.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-data', 'wp-date', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '00a9f8f0dd08a3e19f74');
<?php return array('dependencies' => array('lodash', 'moment', 'react', 'react-dom', 'wp-api-fetch', 'wp-data', 'wp-date', 'wp-dom-ready', 'wp-element', 'wp-i18n', 'wp-url'), 'version' => '9c0b6e7c532590756eee');
19 changes: 18 additions & 1 deletion includes/Data/Plugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ final class Plugins {
),
);

/**
* An associative array of premium plugins with their corresponding admin page URLs and file paths.
*
* @var array<string, array<string, string>> $free_plugins
*/
public static $premium_plugins = array(
// TODO: More plugins to be added here as once their data is available
'wp-seo' => array(
'url' => 'wp-admin/admin.php?page=wpseo_dashboard#top#first-time-configuration',
'file' => 'wordpress-seo/wp-seo.php'
),
'sensei-lms' => array(
'url' => 'wp-admin/admin.php?page=wpseo_dashboard#top#first-time-configuration',
'file' => 'sensei-lms/sensei-lms.php'
),
);

/**
* An associative array of supported plugins with their corresponding file paths and admin page URLs.
*
Expand Down Expand Up @@ -120,6 +137,6 @@ final class Plugins {
* @return array<string, array<string, string>> A combined array of supported and free plugins.
*/
public static function supported_plugins() {
return array_merge( self::$supported_plugins, self::$free_plugins );
return array_merge( self::$supported_plugins, self::$free_plugins, self::$premium_plugins );
}
}
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
},
"dependencies": {
"@faizaanceg/pandora": "^1.1.1",
"uuid": "^9.0.1",
"@heroicons/react": "2.1.3",
"@newfold-labs/js-utility-ui-analytics": "^1.2.0",
"@newfold-labs/wp-module-runtime": "^1.0.0",
Expand All @@ -32,8 +31,9 @@
"@wordpress/element": "^5.32.0",
"@wordpress/i18n": "^4.55.0",
"classnames": "2.5.1",
"moment": "^2.29.4",
"swr": "2.1.5"
"moment": "^2.29.4",
"swr": "2.1.5",
"uuid": "^9.0.1"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.7",
Expand Down
80 changes: 80 additions & 0 deletions src/components/NoExistingPlan.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { Button } from "@newfold/ui-component-library";
import { __ } from "@wordpress/i18n";
import { ReactComponent as FiftyOff } from "../icons/fifty-off.svg";
import { ReactComponent as GreenTick } from "../icons/green-tick.svg";
import { Section } from "./Section";


export function NoExistingPlan(props){
const { availableSolutions } = props;

const HtmlContent = ({ htmlString }) => {
return (
<div
dangerouslySetInnerHTML={{ __html: htmlString }}
/>
);
};


return(
<Section.Container className="nfd-container">
<Section.Header
title={__("Upgrade your plan for success.", "wp-module-ecommerce")}
subTitle={__("Choose the set of plugins and services that's right for your needs. You're covered by our no-quibble, 30 day money back guarantee.", "wp-module-ecommerce")}
/>
<Section.Content className="nfd-app-section-home">
{
availableSolutions?.map((solution) => {
return(
<div className="nfd-border nfd-border-[#E2E8F0] nfd-p-6 nfd-rounded-lg nfd-mb-6 nfd-relative">
<FiftyOff className="nfd-absolute nfd-top-0 nfd-right-0 nfd-hidden" />
<h2 className="nfd-text-[#0F172A] nfd-text-lg nfd-font-semibold nfd-mb-5">
{ __(`${solution.name.toUpperCase()}`, "wp-module-ecommerce") }
</h2>
<div className="nfd-flex nfd-flex-row">
<p className="nfd-text-[#0F172A] nfd-text-base nfd-mb-7 nfd-w-[480px]">
{__(`${solution.description}`, "wp-module-ecommerce")}
</p>
<p className="nfd-text-[#000000] nfd-text-4xl nfd-font-extrabold nfd-ml-auto nfd-mr-10">
{solution.price}
<span className="nfd-text-2xl nfd-text-[#000000] nfd-font-semibold nfd-relative nfd--top-[5px]">
{__("/mo", "wp-module-ecommerce")}
</span>
<br />
<span className="nfd-text-sm nfd-text-[#404040] nfd-font-normal nfd-relative nfd--top-9 nfd-hidden">
<span>{__("Original price ", "wp-module-ecommerce")}</span>
<span className="nfd-line-through">{solution.fullPrice}</span>
<span>{__("/mo", "wp-module-ecommerce")}</span>
</span>
</p>
</div>
<div className="nfd-flex nfd-flex-row nfd--mt-8">
<ul className="nfd-mr-6 nfd-grid nfd-grid-cols-2 nfd-gap-x-6 nfd-mt-6">
{
solution?.features.map((feat, index) => {
return(
<li className={classNames( "nfd-flex", "nfd-flex-row", "nfd-items-center",
{ 'nfd-border-b nfd-border-[#cccccc] nfd-mb-3 nfd-pb-3': (index === 0 || index === 1) })}
>
<GreenTick className="nfd-mt-1.5 nfd-mr-2" />
<span className="nfd-text-[#404040] nfd-text-base">
<HtmlContent htmlString={__(`${feat}`, "wp-module-ecommerce")} />
</span>
</li>
)
})
}
</ul>
<Button as="a" href={solution.url} className="nfd-button nfd-button--secondary nfd-self-end nfd-ml-auto">
{__("Learn more", "wp-module-ecommerce")}
</Button>
</div>
</div>
)
})
}
</Section.Content>
</Section.Container>
)
}
147 changes: 147 additions & 0 deletions src/components/WPSolutionsBanner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
import { Button, Spinner } from "@newfold/ui-component-library";
import apiFetch from '@wordpress/api-fetch';
import { useEffect, useState } from "@wordpress/element";
import { __ } from "@wordpress/i18n";
import useSWR from "swr";
import { myPluginsAndToolsPageLink, solutionButtonTextObject, wpSolutionsPromotedPluginsList } from "../constants";
import { ReactComponent as RightArrow } from "../icons/right-arrow.svg";
import { NewfoldRuntime } from "../sdk/NewfoldRuntime";
import { PluginsSdk } from "../sdk/plugins";
import { NoExistingPlan } from "./NoExistingPlan";
import { Section } from "./Section";


export function WPSolutionsBanner() {

const entitlementsEndPoint = NewfoldRuntime.createApiUrl("/newfold-solutions/v1/entitlements");
const [ error, setError ] = useState(null);
const [ apiResponse, setApiResponse ] = useState(null);
const [ isLoaded, setIsLoaded ] = useState( false );
const [ purchasedSolution, setPurchasedSolution] = useState(null)
const [ availableSolutions, setAvailableSolutions] = useState([]);
const [ pluginActiveStatusArray, setPluginActiveStatusArray] = useState([]);
let currentSolution = [];

//TODO: To add slug information for all premium plugins once data is available
let premiumPluginStatus = useSWR(
"nfd_slug_wonder_cart",
() =>
PluginsSdk.queries
.status("nfd_slug_wonder_cart", "sensei-lms", "wp-seo")
.then(res => {
setPluginActiveStatusArray(res?.details)
}),
{ refreshInterval: 30 * 1000 }
);

const routeChange = () =>{
location.href = myPluginsAndToolsPageLink;
}

useEffect( () => {
apiFetch( { url: `${ entitlementsEndPoint }` } ).then(
( result ) => {
setIsLoaded(true);
setApiResponse(result)
setPurchasedSolution(result['solution'])
setAvailableSolutions(result['solutions'])
},
( error ) => {
setIsLoaded(true);
setError(error);
}
);
}, [] );

if ( error ) {
//Uncomment below line, to debug error in API response
//console.log(error.message, "error");
return (
<div className="nfd-flex nfd-p-6 nfd-bg-white nfd-w-full nfd-rounded-lg nfd-text-red-700">
<ExclamationTriangleIcon className="nfd-w-[24px] nfd-h-[24px]" />
<span className="nfd-ml-1.5">{__("Oops! something went wrong. Please try again later", "wp-module-ecommerce")}</span>
</div>
);
}
else if (!isLoaded){
return (
<div className="nfd-flex nfd-items-center nfd-text-center nfd-justify-center nfd-h-full">
<Spinner size="8" className="nfd-text-primary" />
</div>
);
}
else if (apiResponse) {
if (purchasedSolution === null) {
return (<NoExistingPlan availableSolutions={availableSolutions} />);
}
else{
currentSolution = purchasedSolution === "WP_SOLUTION_CREATOR" ?
wpSolutionsPromotedPluginsList[0]['WP_SOLUTION_CREATOR'] :
purchasedSolution === "WP_SOLUTION_SERVICE" ?
wpSolutionsPromotedPluginsList[0]['WP_SOLUTION_SERVICE'] : wpSolutionsPromotedPluginsList[0]['WP_SOLUTION_COMMERCE'];
let solutionsCards = Object.values(currentSolution);
return(
<Section.Container className="nfd-container">
<Section.Header
title={__("Explore Your Plugins and Tools", "wp-module-ecommerce")}
subTitle={__("Improve your site with the tools and services included in your plan.", "wp-module-ecommerce")}
secondaryAction={{title : __( `View ${solutionButtonTextObject[purchasedSolution]} tools`, "wp-module-ecommerce" ), className: false, onClick: routeChange }}
/>
<Section.Content className="nfd-app-section-home">
<div className="nfd-flex nfd-flex-row nfd-flex-wrap">
{
solutionsCards?.map((details, index) => {
return (<div key="index" className={"nfd-flex nfd-flex-col nfd-bg-[#F1F5F7] nfd-p-6 nfd-rounded-lg nfd-border nfd-border-[#E2E8F0] nfd-box-content "+ (index === 0 ? "nfd-w-[38.33%] nfd-mr-6 nfd-mb-6" : index === 1 ? "nfd-w-6/12 nfd-mb-6" : index === 2 ? "nfd-w-6/12 nfd-mr-6" : "nfd-w-[38.33%]") }>
<h2 className="nfd-text-[#0F172A] nfd-text-lg nfd-leading-5 nfd-font-semibold nfd-mb-4">
{ __(`${details['title']}`,"wp-module-ecommerce") }
</h2>
<p className="nfd-text-[#0F172A] nfd-text-lg nfd-leading-5 nfd-font-normal nfd-mb-10">
{ __(`${details['description']}`,"wp-module-ecommerce") }
</p>
{
details.slug !== "" ?
Object.entries(pluginActiveStatusArray).map(([slug, { status, url }]) => (
details.slug === slug ?
status === "active" ?
<Button className="nfd-button nfd-button--primary nfd-mt-9 nfd-mt-auto nfd-self-start" as="a" href={url}>
{ __(`${details['buttonText']}`,"wp-module-ecommerce") }
<RightArrow className="nfd-mt-2.5" />
</Button>
:
status === "need_to_install" || "installing" ?
<Button
className="nfd-button nfd-button--primary nfd-mt-9 nfd-mt-auto nfd-self-start"
as="button"
data-nfd-installer-plugin-slug={slug}
data-nfd-installer-plugin-provider={details.providerName}
data-nfd-installer-plugin-activate={true}
isLoading={status==="installing"}
>
{ status==="installing" ? __("Installing","wp-module-ecommerce") : __("Install","wp-module-ecommerce") }
<RightArrow className="nfd-mt-2.5" />
</Button> : null
:
null
))
:
<Button className="nfd-button nfd-button--primary nfd-mt-9 nfd-mt-auto nfd-self-start" as="button" disabled={true}>
{ __(`${details['buttonText']}`,"wp-module-ecommerce") }
<RightArrow className="nfd-mt-2.5" />
</Button>
}
</div>)
})
}
</div>

<Button as="a" href={myPluginsAndToolsPageLink} className="nfd-button nfd-button--secondary nfd-flex nfd-w-56 nfd-mx-auto nfd-mt-3">
{__(`View all ${solutionButtonTextObject[purchasedSolution]} tools`, "wp-module-ecommerce")}
</Button>
</Section.Content>
</Section.Container>
)
}

}
}
18 changes: 11 additions & 7 deletions src/components/YITHPlugins.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Button, Modal, Spinner } from "@newfold/ui-component-library";
import apiFetch from "@wordpress/api-fetch";
import { useEffect, useState } from "@wordpress/element";
import { __ } from "@wordpress/i18n";
import { Modal, Spinner } from "@newfold/ui-component-library";
import classNames from "classnames";
import { YITHPluginsDefinitions } from "../configs/YITHPlugins.config";
import { myPluginsAndToolsPageLink } from "../constants";
import lightchest from '../icons/light-chest.svg';
import { NewfoldRuntime } from "../sdk/NewfoldRuntime";
import { LoadingPanel } from "./LoadingPanel";
import { Section } from "./Section";
import { useCardManager } from "./useCardManager";
import classNames from "classnames";
import { useEffect, useState } from "@wordpress/element";
import apiFetch from "@wordpress/api-fetch";
import { NewfoldRuntime } from "../sdk/NewfoldRuntime";
import { YithFeatureCard } from "./YithFeatureCard";
import lightchest from '../icons/light-chest.svg';
import { LoadingPanel } from "./LoadingPanel";

export function YITHPlugins({ wpModules }) {
const [isOpen, setIsOpen] = useState(false);
Expand Down Expand Up @@ -127,6 +128,9 @@ export function YITHPlugins({ wpModules }) {
"Unlock the full power of your plan with access to a range of exclusive WooCommerce tools powered by \nYITH. Enhance your store and keep your customers coming back for more!",
"wp-module-ecommerce"
)}
<Button as="a" href={myPluginsAndToolsPageLink} className="nfd-button nfd-button--secondary nfd-flex nfd-self-end nfd-ml-auto">
{__( "View all Commerce tools", "wp-module-ecommerce" )}
</Button>
</div>
</div>
<Section.Content className={"nfd-pt-4 nfd-pl-4 nfd-pr-4"}>
Expand Down
Loading

0 comments on commit 1c4a5a1

Please sign in to comment.