Refactor category modal into smaller components

[MAILPOET-6354]
This commit is contained in:
Jan Lysý
2024-12-03 18:42:06 +01:00
committed by Aschepikov
parent 74e4b333ac
commit 74c2a99e80
3 changed files with 111 additions and 94 deletions

View File

@ -0,0 +1,51 @@
import * as React from '@wordpress/element';
import { MenuGroup, MenuItem } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
const CategoryMenu = ( {
groupedTags,
activeCategory,
onCategorySelect,
}: {
groupedTags: Record< string, any[] >;
activeCategory: string | null;
onCategorySelect: ( category: string | null ) => void;
} ) => {
const getMenuItemClass = ( category: string | null ) =>
category === activeCategory
? 'mailpoet-personalization-tags-modal__menu-item-active'
: '';
return (
<MenuGroup className="mailpoet-personalization-tags-modal__menu">
<MenuItem
onClick={ () => onCategorySelect( null ) }
className={ getMenuItemClass( null ) }
>
{ __( 'All' ) }
</MenuItem>
<div
className="mailpoet-personalization-tags-modal__menu-separator"
aria-hidden="true"
></div>
{ Object.keys( groupedTags ).map( ( category, index, array ) => (
<React.Fragment key={ category }>
<MenuItem
onClick={ () => onCategorySelect( category ) }
className={ getMenuItemClass( category ) }
>
{ category }
</MenuItem>
{ index < array.length - 1 && (
<div
className="mailpoet-personalization-tags-modal__menu-separator"
aria-hidden="true"
></div>
) }
</React.Fragment>
) ) }
</MenuGroup>
);
};
export { CategoryMenu };

View File

@ -0,0 +1,48 @@
import { Button } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { PersonalizationTag } from '../../store';
const CategorySection = ( {
groupedTags,
activeCategory,
}: {
groupedTags: Record< string, PersonalizationTag[] >;
activeCategory: string | null;
} ) => {
const categoriesToRender: [ string, PersonalizationTag[] ][] =
activeCategory === null
? Object.entries( groupedTags ) // Render all categories
: [ [ activeCategory, groupedTags[ activeCategory ] || [] ] ]; // Render only one selected category
return (
<>
{ categoriesToRender.map(
( [ category, items ]: [ string, PersonalizationTag[] ] ) => (
<div key={ category }>
<div className="mailpoet-personalization-tags-modal__category">
{ category }
</div>
<div className="mailpoet-personalization-tags-modal__category-group">
{ items.map( ( item ) => (
<div
className="mailpoet-personalization-tags-modal__category-group-item"
key={ item.token }
>
<div className="mailpoet-personalization-tags-modal__item-text">
<strong>{ item.name }</strong>
{ item.token }
</div>
<Button variant="link">
{ __( 'Insert' ) }
</Button>
</div>
) ) }
</div>
</div>
)
) }
</>
);
};
export { CategorySection };

View File

@ -1,17 +1,12 @@
import * as React from '@wordpress/element';
import {
Modal,
Button,
MenuGroup,
MenuItem,
SearchControl,
} from '@wordpress/components';
import { Modal, SearchControl } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { PersonalizationTag, storeName } from '../../store';
import { useDispatch, useSelect } from '@wordpress/data';
import { external, Icon } from '@wordpress/icons';
import './index.scss';
import { useState } from '@wordpress/element';
import { CategoryMenu } from './category-menu';
import { CategorySection } from './category-section';
const PersonalizationTagsModal = () => {
const [ activeCategory, setActiveCategory ] = useState( null );
@ -47,11 +42,6 @@ const PersonalizationTagsModal = () => {
{} as Record< string, PersonalizationTag[] >
);
const getMenuItemClass = ( category ) =>
category === activeCategory
? 'mailpoet-personalization-tags-modal__menu-item-active'
: '';
return (
<Modal
size="medium"
@ -67,87 +57,15 @@ const PersonalizationTagsModal = () => {
<Icon icon={ external } size={ 16 } />
</p>
<SearchControl onChange={ setSearchQuery } value={ searchQuery } />
<MenuGroup className="mailpoet-personalization-tags-modal__menu">
<MenuItem
onClick={ () => setActiveCategory( null ) }
className={ `${ getMenuItemClass( null ) }` }
>
{ __( 'All' ) }
</MenuItem>
<div
className="mailpoet-personalization-tags-modal__menu-separator"
aria-hidden="true"
></div>
{ Object.entries( groupedTags ).map(
( [ category ], index, array ) => (
<React.Fragment key={ category }>
<MenuItem
onClick={ () => setActiveCategory( category ) }
className={ `${ getMenuItemClass(
category
) }` }
>
{ category }
</MenuItem>
{ index < array.length - 1 && (
<div
className="mailpoet-personalization-tags-modal__menu-separator"
aria-hidden="true"
></div>
) }
</React.Fragment>
)
) }
</MenuGroup>
{ activeCategory === null ? (
// Render all categories
Object.entries( groupedTags ).map( ( [ category, items ] ) => (
<div key={ category }>
<div className="mailpoet-personalization-tags-modal__category">
{ category }
</div>
<div className="mailpoet-personalization-tags-modal__category-group">
{ items.map( ( item ) => (
<div
className="mailpoet-personalization-tags-modal__category-group-item"
key={ item.token }
>
<div className="mailpoet-personalization-tags-modal__item-text">
<strong>{ item.name }</strong>
{ item.token }
</div>
<Button variant="link">
{ __( 'Insert' ) }
</Button>
</div>
) ) }
</div>
</div>
) )
) : (
// Render selected category
<div>
<div className="mailpoet-personalization-tags-modal__category">
{ activeCategory }
</div>
<div className="mailpoet-personalization-tags-modal__category-group">
{ groupedTags[ activeCategory ]?.map( ( item ) => (
<div
className="mailpoet-personalization-tags-modal__category-group-item"
key={ item.token }
>
<div className="mailpoet-personalization-tags-modal__item-text">
<strong>{ item.name }</strong>
{ item.token }
</div>
<Button variant="link">
{ __( 'Insert' ) }
</Button>
</div>
) ) }
</div>
</div>
) }
<CategoryMenu
groupedTags={ groupedTags }
activeCategory={ activeCategory }
onCategorySelect={ setActiveCategory }
/>
<CategorySection
groupedTags={ groupedTags }
activeCategory={ activeCategory }
/>
</Modal>
);
};