Skip to content

Commit

Permalink
Live Preview: Add the upgrade-needed notice for Premium and Woo themes (
Browse files Browse the repository at this point in the history
  • Loading branch information
okmttdhr authored Nov 30, 2023
1 parent 3bed44e commit 575d080
Show file tree
Hide file tree
Showing 8 changed files with 420 additions and 126 deletions.
1 change: 1 addition & 0 deletions apps/wpcom-block-editor/src/wpcom/editor.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
@import "./features/use-classic-block-guide";
@import "./features/live-preview/upgrade-notice";

.blog-onboarding-hide {
.components-external-link, // "Connect an account" link in Jetpack sidebar
Expand Down
126 changes: 0 additions & 126 deletions apps/wpcom-block-editor/src/wpcom/features/live-preview.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import {
FEATURE_WOOP,
WPCOM_FEATURES_ATOMIC,
WPCOM_FEATURES_PREMIUM_THEMES,
PLAN_PREMIUM,
PLAN_BUSINESS,
} from '@automattic/calypso-products';
import { getCalypsoUrl } from '@automattic/calypso-url';
import { useEffect, useState, useCallback } from 'react';
import wpcom from 'calypso/lib/wp';
import { PREMIUM_THEME, WOOCOMMERCE_THEME } from '../utils';
import { usePreviewingTheme } from './use-previewing-theme';
import type { SiteDetails } from '@automattic/data-stores';

const checkNeedUpgrade = ( {
site,
previewingThemeType,
}: {
site?: SiteDetails;
previewingThemeType?: string;
} ) => {
const activeFeatures = site?.plan?.features?.active;
if ( ! activeFeatures ) {
return false;
}

/**
* This logic is extracted from `client/state/themes/selectors/can-use-theme.js`.
*/
const canUseWooCommerceTheme =
previewingThemeType === WOOCOMMERCE_THEME &&
[ WPCOM_FEATURES_PREMIUM_THEMES, FEATURE_WOOP, WPCOM_FEATURES_ATOMIC ].every( ( feature ) =>
activeFeatures.includes( feature )
);
if ( canUseWooCommerceTheme ) {
return false;
}
const canUsePremiumTheme =
previewingThemeType === PREMIUM_THEME &&
activeFeatures.includes( WPCOM_FEATURES_PREMIUM_THEMES );
if ( canUsePremiumTheme ) {
return false;
}

return true;
};

export const useCanPreviewButNeedUpgrade = ( {
previewingTheme,
}: {
previewingTheme: ReturnType< typeof usePreviewingTheme >;
} ) => {
const [ canPreviewButNeedUpgrade, setCanPreviewButNeedUpgrade ] = useState( false );
const [ siteSlug, setSiteSlug ] = useState< string | undefined >();

/**
* Get the theme and site info to decide whether the user needs to upgrade the plan.
*/
useEffect( () => {
/**
* Currently, Live Preview only supports upgrades for WooCommerce and Premium themes.
*/
if ( previewingTheme.type !== WOOCOMMERCE_THEME && previewingTheme.type !== PREMIUM_THEME ) {
setCanPreviewButNeedUpgrade( false );
return;
}

wpcom.req
.get( `/sites/${ window._currentSiteId }`, { apiVersion: '1.2' } )
.then( ( site: any ) => {
let parsedUrl;
try {
parsedUrl = new URL( site.URL );
const { hostname } = parsedUrl;
setSiteSlug( hostname );
} catch {
// Invalid URL
}
return site;
} )
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.then( ( site: any ) => {
if ( ! checkNeedUpgrade( { site, previewingThemeType: previewingTheme.type } ) ) {
setCanPreviewButNeedUpgrade( false );
return;
}
setCanPreviewButNeedUpgrade( true );
} )
.catch( () => {
// do nothing
} );
}, [ previewingTheme.type, setCanPreviewButNeedUpgrade, setSiteSlug ] );

const upgradePlan = useCallback( () => {
const generateCheckoutUrl = ( plan: string ) => {
const locationHref = window.location.href;
let url = locationHref;
try {
/**
* If the site has a custom domain, change the hostname to a custom domain.
* This allows the checkout to redirect back to the custom domain.
* @see `client/my-sites/checkout/src/hooks/use-valid-checkout-back-url.ts`
*/
if ( siteSlug ) {
const parsedUrl = new URL( locationHref );
parsedUrl.hostname = siteSlug;
url = parsedUrl.toString();
}
} catch ( error ) {
// Do nothing.
}
return `${ getCalypsoUrl() }/checkout/${
window._currentSiteId
}/${ plan }?redirect_to=${ encodeURIComponent( url ) }&checkoutBackUrl=${ encodeURIComponent(
url
) }`;
};
const link =
previewingTheme.type === WOOCOMMERCE_THEME
? /**
* For a WooCommerce theme, the users should have the Business plan or higher,
* AND the WooCommerce plugin has to be installed.
*/
generateCheckoutUrl( PLAN_BUSINESS )
: // For a Premium theme, the users should have the Premium plan or higher.
generateCheckoutUrl( PLAN_PREMIUM );
window.location.href = link;

// TODO: Add the track event.
}, [ previewingTheme.type, siteSlug ] );

return {
canPreviewButNeedUpgrade,
upgradePlan,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { useEffect, useState } from 'react';
import wpcom from 'calypso/lib/wp';
import { currentlyPreviewingTheme, PREMIUM_THEME, WOOCOMMERCE_THEME } from '../utils';
import type { Theme } from 'calypso/types';

/**
* Get the theme type.
* This only support WooCommerce and Premium themes.
*/
const getThemeType = ( theme?: Theme ) => {
const theme_software_set = theme?.taxonomies?.theme_software_set;
const isWooCommerceTheme = theme_software_set && theme_software_set.length > 0;
if ( isWooCommerceTheme ) {
return WOOCOMMERCE_THEME;
}
const themeStylesheet = theme?.stylesheet;
const isPremiumTheme = themeStylesheet && themeStylesheet.startsWith( 'premium/' );
if ( isPremiumTheme ) {
return PREMIUM_THEME;
}
return undefined;
};

export const usePreviewingTheme = () => {
const previewingThemeSlug = currentlyPreviewingTheme();
const previewingThemeId =
( previewingThemeSlug as string )?.split( '/' )?.[ 1 ] || previewingThemeSlug;
const [ previewingThemeName, setPreviewingThemeName ] = useState< string >(
previewingThemeSlug as string
);
const [ previewingThemeType, setPreviewingThemeType ] = useState< string >();
const previewingThemeTypeDisplay =
previewingThemeType === WOOCOMMERCE_THEME ? 'WooCommerce' : 'Premium';

useEffect( () => {
wpcom.req
.get( `/themes/${ previewingThemeId }`, { apiVersion: '1.2' } )
.then( ( theme: Theme ) => {
const name = theme?.name;
if ( name ) {
setPreviewingThemeName( name );
}
return theme;
} )
.then( ( theme: Theme ) => {
const type = getThemeType( theme );
if ( ! type ) {
return;
}
setPreviewingThemeType( type );
} )
.catch( () => {
// do nothing
} );
return;
}, [ previewingThemeId ] );

return {
name: previewingThemeName,
type: previewingThemeType,
typeDisplay: previewingThemeTypeDisplay,
};
};
Loading

0 comments on commit 575d080

Please sign in to comment.