From be324ec2276894f9fe995b1960081bf91ae827b3 Mon Sep 17 00:00:00 2001 From: Ilyas Foo Date: Wed, 28 Jun 2023 18:52:09 +0800 Subject: [PATCH] Customize Woo Express and free trial themes screen (#78570) * Tweak Woo Express and free trial selector to use site for faster performance * Force theme upsell banner for free trial sites, hide theme categories for Woo Express and free trial sites * Add hidden theme filters to force woo-on-plans filter * Redirect woo-on-plan themes to congrats page on theme activation * Customize upsell nudge arrangement for Woo Express and free trial * Add back current plan to selectors as a backup * Update client/my-sites/themes/theme-showcase.jsx Co-authored-by: Chi-Hsuan Huang * Fix hiddenFilters inserting empty array into join breaking other filters * Hardcode store filter instead since 5 WooCommerce only themes is too small to choose from --------- Co-authored-by: Chi-Hsuan Huang --- client/blocks/upsell-nudge/index.jsx | 12 ++++- client/my-sites/themes/theme-showcase.jsx | 48 ++++++++++++++----- client/my-sites/themes/theme-showcase.scss | 4 ++ client/my-sites/themes/themes-selection.jsx | 4 +- .../selectors/is-site-on-ecommerce-trial.ts | 9 ++-- .../plans/selectors/is-site-on-woo-express.ts | 8 +++- .../selectors/get-theme-hidden-filters.js | 18 +++++++ .../should-redirect-to-thank-you-page.js | 5 +- 8 files changed, 83 insertions(+), 25 deletions(-) create mode 100644 client/state/themes/selectors/get-theme-hidden-filters.js diff --git a/client/blocks/upsell-nudge/index.jsx b/client/blocks/upsell-nudge/index.jsx index 1aaf85994f73ea..7c79a569bfffc3 100644 --- a/client/blocks/upsell-nudge/index.jsx +++ b/client/blocks/upsell-nudge/index.jsx @@ -20,7 +20,11 @@ import isSiteAutomatedTransfer from 'calypso/state/selectors/is-site-automated-t import isSiteWPForTeams from 'calypso/state/selectors/is-site-wpforteams'; import isVipSite from 'calypso/state/selectors/is-vip-site'; import siteHasFeature from 'calypso/state/selectors/site-has-feature'; -import { getCurrentPlan } from 'calypso/state/sites/plans/selectors'; +import { + getCurrentPlan, + isSiteOnECommerceTrial, + isSiteOnWooExpress, +} from 'calypso/state/sites/plans/selectors'; import { getSite, isJetpackSite } from 'calypso/state/sites/selectors'; import { getSelectedSiteId, getSelectedSiteSlug } from 'calypso/state/ui/selectors'; @@ -75,6 +79,7 @@ export const UpsellNudge = ( { tracksImpressionName, tracksImpressionProperties, displayAsLink, + isSiteWooExpressOrEcomFreeTrial, } ) => { const shouldNotDisplay = isVip || @@ -113,7 +118,8 @@ export const UpsellNudge = ( { { 'is-upgrade-business': plan && isBusinessPlan( plan ) }, { 'is-upgrade-ecommerce': plan && isEcommercePlan( plan ) }, { 'is-jetpack-plan': plan && planMatches( plan, { group: GROUP_JETPACK } ) }, - { 'is-wpcom-plan': plan && planMatches( plan, { group: GROUP_WPCOM } ) } + { 'is-wpcom-plan': plan && planMatches( plan, { group: GROUP_WPCOM } ) }, + { 'is-wooexpress-or-free-trial-plan': isSiteWooExpressOrEcomFreeTrial } ); if ( dismissPreferenceName && forceHref && href ) { @@ -176,6 +182,8 @@ export default connect( ( state, ownProps ) => { isJetpack: isJetpackSite( state, siteId ), isAtomic: isSiteAutomatedTransfer( state, siteId ), isVip: isVipSite( state, siteId ), + isSiteWooExpressOrEcomFreeTrial: + isSiteOnECommerceTrial( state, siteId ) || isSiteOnWooExpress( state, siteId ), currentPlan: getCurrentPlan( state, siteId ), siteSlug: ownProps.disableHref ? null : getSelectedSiteSlug( state ), canUserUpgrade: canCurrentUser( state, getSelectedSiteId( state ), 'manage_options' ), diff --git a/client/my-sites/themes/theme-showcase.jsx b/client/my-sites/themes/theme-showcase.jsx index b514036f046c47..2cd180fbc89399 100644 --- a/client/my-sites/themes/theme-showcase.jsx +++ b/client/my-sites/themes/theme-showcase.jsx @@ -25,6 +25,7 @@ import { isUserLoggedIn } from 'calypso/state/current-user/selectors'; import getSiteFeaturesById from 'calypso/state/selectors/get-site-features'; import isAtomicSite from 'calypso/state/selectors/is-site-automated-transfer'; import siteHasFeature from 'calypso/state/selectors/site-has-feature'; +import { isSiteOnWooExpress, isSiteOnECommerceTrial } from 'calypso/state/sites/plans/selectors'; import { getSiteSlug } from 'calypso/state/sites/selectors'; import { setBackPath } from 'calypso/state/themes/actions'; import { @@ -375,14 +376,27 @@ class ThemeShowcase extends Component { }; renderBanner = () => { - const { loggedOutComponent, isExpertBannerDissmissed, upsellBanner, isUpsellCardDisplayed } = - this.props; + const { + loggedOutComponent, + isExpertBannerDissmissed, + upsellBanner, + isUpsellCardDisplayed, + isSiteECommerceFreeTrial, + } = this.props; // Don't show the banner if there is already an upsell card displayed if ( isUpsellCardDisplayed ) { return null; } + // In ecommerce trial sites, we only want to show upsell banner. + if ( isSiteECommerceFreeTrial ) { + if ( upsellBanner ) { + return upsellBanner; + } + return null; + } + const tabKey = this.state.tabFilter.key; const staticFilters = this.getStaticFilters(); @@ -433,8 +447,11 @@ class ThemeShowcase extends Component { isMultisite, locale, premiumThemesEnabled, + isSiteECommerceFreeTrial, + isSiteWooExpress, } = this.props; const tier = this.props.tier || ''; + const isSiteWooExpressOrEcomFreeTrial = isSiteECommerceFreeTrial || isSiteWooExpress; const canonicalUrl = 'https://wordpress.com' + pathName; @@ -536,6 +553,9 @@ class ThemeShowcase extends Component {
+ { isSiteWooExpressOrEcomFreeTrial && ( +
{ this.renderBanner() }
+ ) }
{ tabFilters && (
- - this.onFilterClick( - Object.values( tabFilters ).find( ( tabFilter ) => tabFilter.key === key ) - ) - } - /> + { ! isSiteWooExpressOrEcomFreeTrial && ( + + this.onFilterClick( + Object.values( tabFilters ).find( ( tabFilter ) => tabFilter.key === key ) + ) + } + /> + ) } { premiumThemesEnabled && ! isMultisite && (
- { this.renderBanner() } + { ! isSiteWooExpressOrEcomFreeTrial && this.renderBanner() } { this.renderThemes( themeProps ) }
{ siteId && } @@ -597,6 +619,8 @@ const mapStateToProps = ( state, { siteId, filter, tier, vertical } ) => { filterToTermTable: getThemeFilterToTermTable( state ), themesBookmark: getThemesBookmark( state ), isUpsellCardDisplayed: isUpsellCardDisplayedSelector( state ), + isSiteECommerceFreeTrial: isSiteOnECommerceTrial( state, siteId ), + isSiteWooExpress: isSiteOnWooExpress( state, siteId ), }; }; diff --git a/client/my-sites/themes/theme-showcase.scss b/client/my-sites/themes/theme-showcase.scss index 9443b3b0b6805f..54c355a0654cfe 100644 --- a/client/my-sites/themes/theme-showcase.scss +++ b/client/my-sites/themes/theme-showcase.scss @@ -141,6 +141,10 @@ padding: 24px 30px; border-radius: 4px; + &.is-wooexpress-or-free-trial-plan { + margin-bottom: 32px; + } + &.is-dismissible { .dismissible-card__close-button { height: 16px; diff --git a/client/my-sites/themes/themes-selection.jsx b/client/my-sites/themes/themes-selection.jsx index 0fc1de05841e45..8d04d9a385764c 100644 --- a/client/my-sites/themes/themes-selection.jsx +++ b/client/my-sites/themes/themes-selection.jsx @@ -27,6 +27,7 @@ import { isInstallingTheme, prependThemeFilterKeys, } from 'calypso/state/themes/selectors'; +import { getThemeHiddenFilters } from 'calypso/state/themes/selectors/get-theme-hidden-filters'; import { addStyleVariation, trackClick, interlaceThemes } from './helpers'; import SearchThemesTracks from './search-themes-tracks'; import './themes-selection.scss'; @@ -313,6 +314,7 @@ export const ConnectedThemesSelection = connect( const isJetpack = isJetpackSite( state, siteId ); const isAtomic = isSiteAutomatedTransfer( state, siteId ); const premiumThemesEnabled = arePremiumThemesEnabled( state, siteId ); + const hiddenFilters = getThemeHiddenFilters( state, siteId ); const hasUnlimitedPremiumThemes = siteHasFeature( state, siteId, @@ -340,7 +342,7 @@ export const ConnectedThemesSelection = connect( search, page, tier: premiumThemesEnabled ? tier : 'free', - filter: compact( [ filter, vertical ] ).join( ',' ), + filter: compact( [ filter, vertical ] ).concat( hiddenFilters ).join( ',' ), number, }; diff --git a/client/state/sites/plans/selectors/is-site-on-ecommerce-trial.ts b/client/state/sites/plans/selectors/is-site-on-ecommerce-trial.ts index 734fb48ce41aa6..14821b14ca4173 100644 --- a/client/state/sites/plans/selectors/is-site-on-ecommerce-trial.ts +++ b/client/state/sites/plans/selectors/is-site-on-ecommerce-trial.ts @@ -1,4 +1,5 @@ import { PLAN_ECOMMERCE_TRIAL_MONTHLY } from '@automattic/calypso-products'; +import { getSite } from 'calypso/state/sites/selectors'; import { getCurrentPlan } from '.'; import type { AppState } from 'calypso/types'; @@ -11,10 +12,8 @@ import type { AppState } from 'calypso/types'; */ export default function isSiteOnECommerceTrial( state: AppState, siteId: number ) { const currentPlan = getCurrentPlan( state, siteId ); + const site = getSite( state, siteId ); + const productSlug = currentPlan?.productSlug || site?.plan?.product_slug; - if ( ! currentPlan ) { - return false; - } - - return currentPlan.productSlug === PLAN_ECOMMERCE_TRIAL_MONTHLY; + return productSlug === PLAN_ECOMMERCE_TRIAL_MONTHLY; } diff --git a/client/state/sites/plans/selectors/is-site-on-woo-express.ts b/client/state/sites/plans/selectors/is-site-on-woo-express.ts index cb49566ced106e..94ed1ffbf58726 100644 --- a/client/state/sites/plans/selectors/is-site-on-woo-express.ts +++ b/client/state/sites/plans/selectors/is-site-on-woo-express.ts @@ -4,6 +4,7 @@ import { PLAN_WOOEXPRESS_SMALL, PLAN_WOOEXPRESS_SMALL_MONTHLY, } from '@automattic/calypso-products'; +import { getSite } from 'calypso/state/sites/selectors'; import { getCurrentPlan } from '.'; import type { AppState } from 'calypso/types'; @@ -16,6 +17,7 @@ import type { AppState } from 'calypso/types'; */ export default function isSiteOnWooExpress( state: AppState, siteId: number ) { const currentPlan = getCurrentPlan( state, siteId ); + const site = getSite( state, siteId ); const wooExpressPlans = [ PLAN_WOOEXPRESS_MEDIUM, PLAN_WOOEXPRESS_SMALL, @@ -23,9 +25,11 @@ export default function isSiteOnWooExpress( state: AppState, siteId: number ) { PLAN_WOOEXPRESS_SMALL_MONTHLY, ]; - if ( ! currentPlan ) { + const productSlug = currentPlan?.productSlug || site?.plan?.product_slug; + + if ( ! productSlug ) { return false; } - return wooExpressPlans.includes( currentPlan.productSlug ); + return wooExpressPlans.includes( productSlug ); } diff --git a/client/state/themes/selectors/get-theme-hidden-filters.js b/client/state/themes/selectors/get-theme-hidden-filters.js new file mode 100644 index 00000000000000..cd646338504dbd --- /dev/null +++ b/client/state/themes/selectors/get-theme-hidden-filters.js @@ -0,0 +1,18 @@ +import { isSiteOnECommerceTrial, isSiteOnWooExpress } from 'calypso/state/sites/plans/selectors'; + +/** + * Returns theme filters that are not shown in the UI nor navigation URL. + * + * @param {Object} state Global state tree + * @param {?number} siteId Site ID to optionally use as context + * @returns {Array} Array of filter slugs + */ +export function getThemeHiddenFilters( state, siteId ) { + const filters = []; + + if ( isSiteOnECommerceTrial( state, siteId ) || isSiteOnWooExpress( state, siteId ) ) { + filters.push( 'store' ); + } + + return filters; +} diff --git a/client/state/themes/selectors/should-redirect-to-thank-you-page.js b/client/state/themes/selectors/should-redirect-to-thank-you-page.js index 8612459824b0dd..1363597757fe68 100644 --- a/client/state/themes/selectors/should-redirect-to-thank-you-page.js +++ b/client/state/themes/selectors/should-redirect-to-thank-you-page.js @@ -1,6 +1,6 @@ import 'calypso/state/themes/init'; -import { getTheme, doesThemeBundleSoftwareSet, isExternallyManagedTheme } from '.'; +import { getTheme, isExternallyManagedTheme } from '.'; /** * Returns whether it should redirect to thank you page @@ -11,8 +11,7 @@ import { getTheme, doesThemeBundleSoftwareSet, isExternallyManagedTheme } from ' * @returns {boolean} */ export function shouldRedirectToThankYouPage( state, themeId ) { - const isWooTheme = doesThemeBundleSoftwareSet( state, themeId ); const isDotComTheme = !! getTheme( state, 'wpcom', themeId ); const isExternallyManaged = isExternallyManagedTheme( state, themeId ); - return isDotComTheme && ! isWooTheme && ! isExternallyManaged; + return isDotComTheme && ! isExternallyManaged; }