Skip to content

Commit

Permalink
Design Picker: Add free tier filter to Type category in design picker (
Browse files Browse the repository at this point in the history
…#97323)

* add free filter to type filters

* remove free only filter component

* Just move free-only toggle into types and keep functionalites the same

* Update track events

---------

Co-authored-by: arthur <[email protected]>
  • Loading branch information
madhusudhand and arthur791004 authored Dec 12, 2024
1 parent f505c7b commit 8e22d48
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 110 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { getCategoryType } from '@automattic/design-picker';
import {
getCategoryType,
useDesignPickerFilters,
DESIGN_TIER_CATEGORIES,
} from '@automattic/design-picker';
import { useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { recordTracksEvent } from 'calypso/lib/analytics/tracks';

interface Props {
Expand All @@ -10,14 +13,12 @@ interface Props {
}

const useTrackFilters = ( { preselectedFilters, isBigSkyEligible, isMultiSelection }: Props ) => {
const [ searchParams ] = useSearchParams();
const { selectedCategories, selectedDesignTiers } = useDesignPickerFilters();

const selectedFilters = searchParams.get( 'categories' )?.split( ',' ) || [];

const isIncludedWithPlan = searchParams.get( 'tier' ) === 'free';
const isIncludedWithPlan = selectedDesignTiers.includes( DESIGN_TIER_CATEGORIES.FREE );

const filters = useMemo( () => {
return selectedFilters.reduce(
return selectedCategories.reduce(
( result, filterSlug, index ) => ( {
...result,
// The property cannot contain `-` character.
Expand All @@ -27,13 +28,13 @@ const useTrackFilters = ( { preselectedFilters, isBigSkyEligible, isMultiSelecti
} ),
{}
);
}, [ selectedFilters ] );
}, [ selectedCategories ] );

const commonFilterProperties = {
is_filter_included_with_plan_enabled: isIncludedWithPlan,
is_big_sky_eligible: isBigSkyEligible,
preselected_filters: preselectedFilters.join( ',' ),
selected_filters: selectedFilters.join( ',' ),
selected_filters: selectedCategories.join( ',' ),
...filters,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ const UnifiedDesignPickerStep: Step = ( { navigation, flow, stepName } ) => {
isMultiSelection: isGoalCentricFeature,
} );

const { commonFilterProperties, handleSelectFilter, handleDeselectFilter } = useTrackFilters( {
const { commonFilterProperties } = useTrackFilters( {
preselectedFilters: categorizationOptions.defaultSelections,
isBigSkyEligible,
isMultiSelection: isGoalCentricFeature,
Expand All @@ -244,20 +244,10 @@ const UnifiedDesignPickerStep: Step = ( { navigation, flow, stepName } ) => {
const categorization = useCategorization( allDesigns?.filters?.subject || EMPTY_OBJECT, {
...categorizationOptions,
isMultiSelection: isGoalCentricFeature,
handleSelect: handleSelectFilter,
handleDeselect: handleDeselectFilter,
} );

const designPickerFilters = useDesignPickerFilters();

const handleChangeTier = ( value: boolean ) => {
if ( value ) {
handleSelectFilter( 'free', 'included_with_plan' );
} else {
handleDeselectFilter( 'free', 'included_with_plan' );
}
};

// ********** Logic for selecting a design and style variation
const {
isPreviewingDesign,
Expand Down Expand Up @@ -965,9 +955,7 @@ const UnifiedDesignPickerStep: Step = ( { navigation, flow, stepName } ) => {
oldHighResImageLoading={ oldHighResImageLoading }
siteActiveTheme={ siteActiveTheme?.[ 0 ]?.stylesheet ?? null }
showActiveThemeBadge={ intent !== 'build' }
isTierFilterEnabled={ isGoalCentricFeature }
isMultiFilterEnabled={ isGoalCentricFeature }
onChangeTier={ handleChangeTier }
isBigSkyEligible={ isBigSkyEligible }
recommendedDesignSlugs={ allDesigns?.recommendation || [] }
/>
Expand Down

This file was deleted.

This file was deleted.

26 changes: 10 additions & 16 deletions packages/design-picker/src/components/unified-design-picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { useTranslate } from 'i18n-calypso';
import { useCallback, useMemo, useRef, useState } from 'react';
import { InView } from 'react-intersection-observer';
import { SHOW_ALL_SLUG } from '../constants';
import { useDesignTiers, useDesignPickerFilters } from '../hooks/use-design-picker-filters';
import { useFilteredDesignsByGroup } from '../hooks/use-filtered-designs';
import {
isDefaultGlobalStylesVariationSlug,
isFeatureCategory,
isLockedStyleVariation,
} from '../utils';
import DesignPickerCategoryFilter from './design-picker-category-filter';
import DesignPickerTierFilter from './design-picker-tier-filter';
import DesignPreviewImage from './design-preview-image';
import NoResults from './no-results';
import ThemeCard from './theme-card';
Expand Down Expand Up @@ -275,9 +275,7 @@ interface DesignPickerProps {
oldHighResImageLoading?: boolean; // Temporary for A/B test
siteActiveTheme?: string | null;
showActiveThemeBadge?: boolean;
isTierFilterEnabled?: boolean;
isMultiFilterEnabled?: boolean;
onChangeTier?: ( value: boolean ) => void;
isBigSkyEligible?: boolean;
recommendedDesignSlugs?: string[];
}
Expand All @@ -295,20 +293,23 @@ const DesignPicker: React.FC< DesignPickerProps > = ( {
oldHighResImageLoading,
siteActiveTheme = null,
showActiveThemeBadge = false,
isTierFilterEnabled = false,
isMultiFilterEnabled = false,
onChangeTier,
isBigSkyEligible = false,
recommendedDesignSlugs = [],
} ) => {
const translate = useTranslate();
const { selectedCategoriesWithoutDesignTier } = useDesignPickerFilters();
const { all, best, ...designsByGroup } = useFilteredDesignsByGroup( designs );

const categories = categorization?.categories || [];

const tierFilters = useDesignTiers();

const categoryTypes = useMemo(
() => categories.filter( ( { slug } ) => isFeatureCategory( slug ) ),
[ categorization?.categories ]
() => [ ...categories.filter( ( { slug } ) => isFeatureCategory( slug ) ), ...tierFilters ],
[ categorization?.categories, tierFilters ]
);

const categoryTopics = useMemo(
() => categories.filter( ( { slug } ) => ! isFeatureCategory( slug ) ),
[ categorization?.categories ]
Expand Down Expand Up @@ -376,7 +377,6 @@ const DesignPicker: React.FC< DesignPickerProps > = ( {
</DesignPickerFilterGroup>
) }
<DesignPickerFilterGroup>
{ isTierFilterEnabled && <DesignPickerTierFilter onChange={ onChangeTier } /> }
{ isBigSkyEligible && (
<Button
className={ clsx(
Expand All @@ -402,15 +402,15 @@ const DesignPicker: React.FC< DesignPickerProps > = ( {
/>
) }

{ isMultiFilterEnabled && categorization && categorization.selections.length > 1 && (
{ isMultiFilterEnabled && selectedCategoriesWithoutDesignTier.length > 1 && (
<DesignCardGroup
{ ...designCardProps }
title={ translate( 'Best matching themes' ) }
category="best"
designs={ best }
/>
) }
{ isMultiFilterEnabled && categorization && categorization.selections.length === 0 && (
{ isMultiFilterEnabled && selectedCategoriesWithoutDesignTier.length === 0 && (
<DesignCardGroup { ...designCardProps } designs={ all } />
) }
{ /* We want to show the last one on top first. */ }
Expand Down Expand Up @@ -452,9 +452,7 @@ export interface UnifiedDesignPickerProps {
oldHighResImageLoading?: boolean; // Temporary for A/B test
siteActiveTheme?: string | null;
showActiveThemeBadge?: boolean;
isTierFilterEnabled?: boolean;
isMultiFilterEnabled?: boolean;
onChangeTier?: ( value: boolean ) => void;
isBigSkyEligible?: boolean;
recommendedDesignSlugs?: string[];
}
Expand All @@ -474,9 +472,7 @@ const UnifiedDesignPicker: React.FC< UnifiedDesignPickerProps > = ( {
oldHighResImageLoading,
siteActiveTheme = null,
showActiveThemeBadge = false,
isTierFilterEnabled = false,
isMultiFilterEnabled = false,
onChangeTier,
isBigSkyEligible = false,
recommendedDesignSlugs = [],
} ) => {
Expand All @@ -503,9 +499,7 @@ const UnifiedDesignPicker: React.FC< UnifiedDesignPickerProps > = ( {
oldHighResImageLoading={ oldHighResImageLoading }
siteActiveTheme={ siteActiveTheme }
showActiveThemeBadge={ showActiveThemeBadge }
isTierFilterEnabled={ isTierFilterEnabled }
isMultiFilterEnabled={ isMultiFilterEnabled }
onChangeTier={ onChangeTier }
isBigSkyEligible={ isBigSkyEligible }
recommendedDesignSlugs={ recommendedDesignSlugs }
/>
Expand Down
4 changes: 4 additions & 0 deletions packages/design-picker/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ export const FEATURE_CATEGORIES = {
STORE: 'store',
};

export const DESIGN_TIER_CATEGORIES = {
FREE: FREE_THEME,
};

export const SUBJECT_CATEGORIES = {
BUSINESS: 'business',
COMMUNITY_NON_PROFIT: 'community-non-profit',
Expand Down
56 changes: 30 additions & 26 deletions packages/design-picker/src/hooks/use-design-picker-filters.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { useTranslate } from 'i18n-calypso';
import { useMemo } from 'react';
import { useSearchParams } from 'react-router-dom';
import { DESIGN_TIER_CATEGORIES } from '../constants';
import { isDesignTierCategory } from '../utils';

// The `currentSearchParams` parameter from the callback of the `setSearchParams` function
// might not have the latest query parameter on multiple calls at the same time.
Expand Down Expand Up @@ -26,44 +30,44 @@ const useCategoriesFilter = () => {
return { selectedCategories, setSelectedCategories };
};

const useDesignTierFilter = () => {
const [ searchParams, setSearchParams ] = useSearchParams();

const selectedDesignTier = searchParams.get( 'tier' ) ?? '';
export const useDesignTiers = () => {
const translate = useTranslate();

const setSelectedDesignTier = ( value: string ) => {
setSearchParams(
makeSearchParams( ( currentSearchParams: any ) => {
if ( value ) {
currentSearchParams.set( 'tier', value );
} else {
currentSearchParams.delete( 'tier' );
}

return currentSearchParams;
} ),
{ replace: true }
);
};
const designTiers = useMemo(
() => [
{
slug: DESIGN_TIER_CATEGORIES.FREE,
name: translate( 'Free' ),
},
],
[ translate ]
);

return {
selectedDesignTier,
setSelectedDesignTier,
};
return designTiers;
};

export const useDesignPickerFilters = () => {
const { selectedCategories, setSelectedCategories } = useCategoriesFilter();
const { selectedDesignTier, setSelectedDesignTier } = useDesignTierFilter();

// Split selectedCategories into categorySlugs and designTierSlugs.
const { selectedCategoriesWithoutDesignTier, selectedDesignTiers } = useMemo( () => {
return {
selectedCategoriesWithoutDesignTier: selectedCategories.filter(
( slug: string ) => ! isDesignTierCategory( slug )
),
selectedDesignTiers: selectedCategories.filter( ( slug: string ) =>
isDesignTierCategory( slug )
),
};
}, [ selectedCategories ] );

return {
selectedCategories,
selectedDesignTier,
selectedCategoriesWithoutDesignTier,
selectedDesignTiers,
setSelectedCategories,
setSelectedDesignTier,
resetFilters: () => {
setSelectedCategories( [] );
setSelectedDesignTier( '' );
},
};
};
19 changes: 12 additions & 7 deletions packages/design-picker/src/hooks/use-filtered-designs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { isBlankCanvasDesign } from '../utils/available-designs';
import { isBlankCanvasDesign } from '../utils';
import { useDesignPickerFilters } from './use-design-picker-filters';
import type { Design } from '../types';

Expand All @@ -8,11 +8,12 @@ import type { Design } from '../types';
export const getFilteredDesignsByCategory = (
designs: Design[],
categorySlugs: string[] | null | undefined,
selectedDesignTier: string = ''
designTierSlugs: string[]
) => {
const filteredDesigns = designs.filter(
( design ) =>
( ! selectedDesignTier || design.design_tier === selectedDesignTier ) &&
( ! designTierSlugs.length ||
( design.design_tier && designTierSlugs.includes( design.design_tier ) ) ) &&
! isBlankCanvasDesign( design )
);

Expand Down Expand Up @@ -62,17 +63,21 @@ export const getFilteredDesignsByCategory = (
};

export const useFilteredDesignsByGroup = ( designs: Design[] ): { [ key: string ]: Design[] } => {
const { selectedCategories, selectedDesignTier } = useDesignPickerFilters();
const { selectedCategoriesWithoutDesignTier, selectedDesignTiers } = useDesignPickerFilters();

const filteredDesigns = useMemo( () => {
if ( selectedCategories.length > 0 || selectedDesignTier ) {
return getFilteredDesignsByCategory( designs, selectedCategories, selectedDesignTier );
if ( selectedCategoriesWithoutDesignTier.length > 0 || selectedDesignTiers.length > 0 ) {
return getFilteredDesignsByCategory(
designs,
selectedCategoriesWithoutDesignTier,
selectedDesignTiers
);
}

return {
all: designs,
};
}, [ designs, selectedCategories, selectedDesignTier ] );
}, [ designs, selectedCategoriesWithoutDesignTier ] );

return filteredDesigns;
};
1 change: 1 addition & 0 deletions packages/design-picker/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export {
MARKETPLACE_THEME,
SHOW_ALL_SLUG,
CATEGORIES,
DESIGN_TIER_CATEGORIES,
} from './constants';
export type {
Design,
Expand Down
Loading

0 comments on commit 8e22d48

Please sign in to comment.