Skip to content

Commit

Permalink
Design Picker: Include premium themes (#59293)
Browse files Browse the repository at this point in the history
* Add PremiumBadge component

* Only fetch free themes if the premium themes are not available to user

* Apply PremiumBadge to Design Picker of Gutenboarding

* Adjust delay of Tooltip

* Refactor useSelector usage to follow best practice

* Update copy of tooltip

* Change to use planHasFeature

* Return array from useSelector

* Rollback the change of getRecommendedThemes

* Fix ts error

* Move planHasFeature out of useSelector

* Use theme demo API v1.1

* Use stylesheet if possible

* Update tests

* Test situation where the design config info is missing stylesheet

Co-authored-by: Philip Jackson <p-jackson@live.com>
  • Loading branch information
arthur791004 and p-jackson committed Jan 20, 2022
1 parent 3478ea4 commit 4b4cae6
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 77 deletions.
11 changes: 2 additions & 9 deletions client/landing/gutenboarding/onboarding-block/designs/index.tsx
@@ -1,6 +1,7 @@
import { isEnabled } from '@automattic/calypso-config';
import DesignPicker, {
FeaturedPicksButtons,
PremiumBadge,
getAvailableDesigns,
useCategorization,
} from '@automattic/design-picker';
Expand All @@ -11,8 +12,6 @@ import { useI18n } from '@wordpress/react-i18n';
import classnames from 'classnames';
import { useEffect, useMemo } from 'react';
import * as React from 'react';
import JetpackLogo from 'calypso/components/jetpack-logo'; // @TODO: extract to @automattic package
import Badge from '../../components/badge';
import useStepNavigation from '../../hooks/use-step-navigation';
import { useTrackStep } from '../../hooks/use-track-step';
import { useIsAnchorFm } from '../../path';
Expand Down Expand Up @@ -75,7 +74,6 @@ const Header: React.FunctionComponent = () => {
};

const Designs: React.FunctionComponent = () => {
const { __ } = useI18n();
const locale = useLocale();
const { goNext } = useStepNavigation();
const { setSelectedDesign, setFonts, resetFonts, setRandomizedDesigns } = useDispatch(
Expand Down Expand Up @@ -175,12 +173,7 @@ const Designs: React.FunctionComponent = () => {
isGridMinimal={ isAnchorFmSignup }
locale={ locale }
onSelect={ onSelect }
premiumBadge={
<Badge className="designs__premium-badge">
<JetpackLogo className="designs__premium-badge-logo" size={ 20 } />
<span className="designs__premium-badge-text">{ __( 'Premium' ) }</span>
</Badge>
}
premiumBadge={ <PremiumBadge /> }
categorization={ isDesignPickerCategoriesEnabled ? categorization : undefined }
categoriesHeading={ isDesignPickerCategoriesEnabled && <Header /> }
categoriesFooter={
Expand Down
30 changes: 0 additions & 30 deletions client/landing/gutenboarding/onboarding-block/designs/style.scss
Expand Up @@ -20,36 +20,6 @@
flex-grow: 1;
}

.designs__premium-badge {
background-color: var( --studio-gray-80 );
/* stylelint-disable-next-line */
border-radius: 1em;
color: var( --studio-white );
margin: 0;
padding: 2px 8px;
white-space: nowrap;
}

.designs__premium-badge-logo {
height: auto;
margin-left: -4px;
width: 14px;

.jetpack-logo__icon-circle {
fill: transparent;
}

.jetpack-logo__icon-triangle {
fill: var( --studio-white );
}
}

.designs__premium-badge-text {
display: inline-block;
margin-top: -0.05em;
text-transform: uppercase;
}

.designs__has-categories {
@include onboarding-heading-padding;
margin-bottom: 0;
Expand Down
19 changes: 14 additions & 5 deletions client/signup/steps/design-picker/index.jsx
@@ -1,6 +1,8 @@
import { isEnabled } from '@automattic/calypso-config';
import { planHasFeature, FEATURE_PREMIUM_THEMES } from '@automattic/calypso-products';
import DesignPicker, {
FeaturedPicksButtons,
PremiumBadge,
isBlankCanvasDesign,
getDesignUrl,
useCategorization,
Expand Down Expand Up @@ -37,8 +39,16 @@ export default function DesignPickerStep( props ) {
showLetUsChoose,
hideFullScreenPreview,
hideDesignTitle,
sitePlanSlug,
} = props;

const isPremiumThemesAvailable = useMemo(
() => planHasFeature( sitePlanSlug, FEATURE_PREMIUM_THEMES ),
[ sitePlanSlug ]
);

const userLoggedIn = useSelector( ( state ) => isUserLoggedIn( state ) );

// In order to show designs with a "featured" term in the theme_picks taxonomy at the below of categories filter
const useFeaturedPicksButtons =
showDesignPickerCategories && isEnabled( 'signup/design-picker-use-featured-picks-buttons' );
Expand All @@ -50,7 +60,7 @@ export default function DesignPickerStep( props ) {
const scrollTop = useRef( 0 );

const { data: apiThemes = [] } = useThemeDesignsQuery(
{ tier: 'free' },
{ tier: isPremiumThemesAvailable ? 'all' : 'free' },
{ enabled: ! props.useDIFMThemes }
);

Expand Down Expand Up @@ -82,8 +92,6 @@ export default function DesignPickerStep( props ) {
};
}, [ props.stepSectionName ] );

const userLoggedIn = useSelector( isUserLoggedIn );

const { designs, featuredPicksDesigns } = useMemo( () => {
return {
designs: shuffle( allThemes.filter( ( theme ) => ! theme.is_featured_picks ) ),
Expand Down Expand Up @@ -125,7 +133,7 @@ export default function DesignPickerStep( props ) {
const locale = ! userLoggedIn ? getLocaleSlug() : '';

recordTracksEvent( 'calypso_signup_design_preview_select', {
theme: `pub/${ _selectedDesign.theme }`,
theme: _selectedDesign?.stylesheet ?? `pub/${ _selectedDesign.theme }`,
template: _selectedDesign.template,
flow: props.flowName,
intent: props.signupDependencies.intent,
Expand All @@ -137,7 +145,7 @@ export default function DesignPickerStep( props ) {

function submitDesign( _selectedDesign = selectedDesign ) {
recordTracksEvent( 'calypso_signup_select_design', {
theme: `pub/${ _selectedDesign?.theme }`,
theme: _selectedDesign?.stylesheet ?? `pub/${ _selectedDesign?.theme }`,
template: _selectedDesign?.template,
flow: props.flowName,
intent: props.signupDependencies.intent,
Expand All @@ -158,6 +166,7 @@ export default function DesignPickerStep( props ) {
'design-picker-step__has-categories': showDesignPickerCategories,
} ) }
highResThumbnails
premiumBadge={ <PremiumBadge /> }
categorization={ showDesignPickerCategories ? categorization : undefined }
categoriesHeading={
<FormattedHeader
Expand Down
13 changes: 3 additions & 10 deletions packages/design-picker/src/components/index.tsx
@@ -1,7 +1,7 @@
/* eslint-disable wpcalypso/jsx-classname-namespace */

import { MShotsImage } from '@automattic/onboarding';
import { Button, Tooltip } from '@wordpress/components';
import { Button } from '@wordpress/components';
import { useViewportMatch } from '@wordpress/compose';
import { sprintf } from '@wordpress/i18n';
import { useI18n } from '@wordpress/react-i18n';
Expand Down Expand Up @@ -53,7 +53,7 @@ const DesignButton: React.FC< DesignButtonProps > = ( {
locale,
onSelect,
design,
premiumBadge,
premiumBadge = null,
highRes,
disabled,
hideDesignTitle,
Expand Down Expand Up @@ -105,14 +105,7 @@ const DesignButton: React.FC< DesignButtonProps > = ( {
{ ! hideDesignTitle && (
<span className="design-picker__option-name">{ designTitle }</span>
) }
{ design.is_premium && premiumBadge && (
<Tooltip
position="bottom center"
text={ __( 'Requires a Personal plan or above', __i18n_text_domain__ ) }
>
<div className="design-picker__premium-container">{ premiumBadge }</div>
</Tooltip>
) }
{ design.is_premium && premiumBadge }
</span>
</span>
</button>
Expand Down
35 changes: 35 additions & 0 deletions packages/design-picker/src/components/premium-badge/index.tsx
@@ -0,0 +1,35 @@
import { Gridicon } from '@automattic/components';
import { Tooltip } from '@wordpress/components';
import { useI18n } from '@wordpress/react-i18n';
import classNames from 'classnames';
import type { FunctionComponent } from 'react';

import './style.scss';

interface Props {
className?: string;
}

const PremiumBadge: FunctionComponent< Props > = ( { className } ) => {
const { __ } = useI18n();

return (
<Tooltip
position="top center"
// @ts-expect-error: @types/wordpress__components doesn't align with latest @wordpress/components
delay={ 300 }
text={ __(
'Let your site stand out from the crowd with a modern and stylish Premium theme.',
__i18n_text_domain__
) }
>
<div className={ classNames( 'premium-badge', className ) }>
{ /* eslint-disable-next-line wpcalypso/jsx-gridicon-size */ }
<Gridicon className="premium-badge__logo" icon="star" size={ 14 } />
<span>{ __( 'Premium' ) }</span>
</div>
</Tooltip>
);
};

export default PremiumBadge;
37 changes: 37 additions & 0 deletions packages/design-picker/src/components/premium-badge/style.scss
@@ -0,0 +1,37 @@
.premium-badge {
display: inline-flex;
align-items: center;
height: 20px;
line-height: 20px;
padding: 0 10px 0 9px;
border-radius: 20px; /* stylelint-disable-line scales/radii */
margin-left: 10px;
box-sizing: border-box;
font-size: 0.75rem;
color: var( --studio-white );
background: var( --studio-black );
z-index: 1;

.design-picker .design-picker__option-meta & {
min-height: 0;
}

.premium-badge__logo {
margin-top: -1px;
margin-right: 3px;
}

.components-tooltip .components-popover__content {
border-radius: 4px;
margin: 8px;
background-color: var( --studio-gray-100 );
white-space: pre-line;

> div {
max-width: 300px;
width: max-content;
padding: 8px 10px;
text-align: start;
}
}
}
10 changes: 0 additions & 10 deletions packages/design-picker/src/components/style.scss
Expand Up @@ -203,16 +203,6 @@
font-weight: 500; /* stylelint-disable-line scales/font-weights */
margin-top: -0.1em;
}

.design-picker__premium-container {
margin-left: 6px;
/* stylelint-disable-next-line */
font-size: rem( 10px ); //typography-exception

.components-popover__content {
background-color: var( --studio-gray-80 );
}
}
}

// dark theme styles
Expand Down
Expand Up @@ -65,6 +65,7 @@ function apiThemeToDesign( { id, name, taxonomies, stylesheet }: any ): Design {
features: [],
is_premium: stylesheet && stylesheet.startsWith( 'premium/' ),
is_featured_picks: isFeaturedPicks,
stylesheet,
slug: id,
template: id,
theme: id,
Expand Down
1 change: 1 addition & 0 deletions packages/design-picker/src/index.ts
@@ -1,6 +1,7 @@
export { default } from './components';

export { default as FeaturedPicksButtons } from './components/featured-picks-buttons';
export { default as PremiumBadge } from './components/premium-badge';
export {
availableDesignsConfig,
getAvailableDesigns,
Expand Down
1 change: 1 addition & 0 deletions packages/design-picker/src/types.ts
Expand Up @@ -21,6 +21,7 @@ export interface Design {
is_alpha?: boolean;
is_fse?: boolean;
is_premium: boolean;
stylesheet?: string;
slug: string;
template: string;
theme: string;
Expand Down

0 comments on commit 4b4cae6

Please sign in to comment.