-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#340-sidebar #398
#340-sidebar #398
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,72 @@ | ||
import type { FC } from 'react' | ||
import { useDispatch } from 'react-redux' | ||
import { type FC, useEffect, useState } from 'react' | ||
import { useDispatch, useSelector } from 'react-redux' | ||
import { NavLink, useParams } from 'react-router-dom' | ||
|
||
import { setCategoryId } from '@/entities/Category/slice/categoryIdSlice' | ||
import { setCategorySlug } from '@/entities/Category/slice/categorySlugSlice' | ||
import styles from '@/features/CategoryItem/CategoryItem.module.scss' | ||
import SideBar from '@/features/SideBar' | ||
import { Routes } from '@/shared/config/routerConfig/routes' | ||
import Link from '@/shared/ui/Link/Link' | ||
import { getCategorySelector } from '@/widgets/CategoryList/selectors/selectors' | ||
import type { BranchesData, MainCategoryInfo } from '@/widgets/CategoryList/types/types' | ||
|
||
type Props = { | ||
name: string | ||
slug: string | ||
count: number | ||
id: number | ||
item: MainCategoryInfo | ||
} | ||
|
||
/** | ||
* Компонент единицы категории в списке категорий бокового меню | ||
* @param {string} name - название категории; | ||
* @param {string} slug - URL для страницы категориии; | ||
* @param {number} count - количество товаров в категории; | ||
* @param {number} id - id категории; | ||
* @param {MainCategoryInfo} item - главная категория с ветками; | ||
*/ | ||
export const CategoryItem: FC<Props> = ({ name, slug, count, id }) => { | ||
export const CategoryItem: FC<Props> = ({ item }) => { | ||
const dispatch = useDispatch() | ||
|
||
const { slug } = useParams() | ||
const getMainCategories = useSelector(getCategorySelector) | ||
|
||
const [itemActive, setItemActive] = useState<MainCategoryInfo | BranchesData>() | ||
const [branch, setBranch] = useState<MainCategoryInfo | BranchesData>() | ||
|
||
useEffect(() => { | ||
if (getMainCategories.find(el => el.slug === slug)) { | ||
setItemActive(getMainCategories.find(el => el.slug === slug)) | ||
} else if (item.branches.find(el => el.slug === slug)) { | ||
setItemActive(item.branches.find(el => el.slug === slug)) | ||
setBranch(getMainCategories.find(el => el.branches.find(el => el.name === itemActive?.name))) | ||
} | ||
}, [itemActive]) | ||
|
||
return ( | ||
<li className={styles['category-list__item']}> | ||
<Link | ||
to={`${Routes.CATEGORIES}/${slug}`} | ||
className={styles['category-list__link']} | ||
onClick={() => { | ||
dispatch(setCategoryId(id)) | ||
dispatch(setCategorySlug(slug)) | ||
}}> | ||
{name} ({count}) | ||
</Link> | ||
</li> | ||
<SideBar | ||
key={item.id} | ||
isVisible={true} | ||
title={`${item.name} (${item.total_count})`} | ||
onClick={() => { | ||
dispatch(setCategoryId(item.id)) | ||
dispatch(setCategorySlug(item.slug)) | ||
}} | ||
to={`${Routes.CATEGORIES}/${item.slug}`} | ||
activeElement={itemActive} | ||
branch={branch} | ||
itemName={item.name}> | ||
<ul role="list"> | ||
{item.branches.map(el => ( | ||
<li key={el.id} className={styles['category-list__item']}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Может добавим проверку, что в item есть branches? |
||
<NavLink | ||
role="link" | ||
to={`${Routes.CATEGORIES}/${el.slug}`} | ||
className={({ isActive }) => | ||
isActive ? styles['category-list__link_active'] : styles['category-list__link'] | ||
} | ||
onClick={() => { | ||
dispatch(setCategoryId(el.id)) | ||
dispatch(setCategorySlug(el.slug)) | ||
}}> | ||
{el.name} ({el.products_count}) | ||
</NavLink> | ||
</li> | ||
))} | ||
</ul> | ||
</SideBar> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import { KeyboardEvent, KeyboardEventHandler, ReactElement, useState, type FC } from 'react' | ||
import { KeyboardEvent, KeyboardEventHandler, ReactElement, useState, type FC, useEffect } from 'react' | ||
|
||
import ArrowIcon from '@/assets/images/sideBarMenu/IconArrowDown.svg' | ||
import Link from '@/shared/ui/Link/Link' | ||
import Paragraph from '@/shared/ui/Paragraph/Paragraph' | ||
import { BranchesData, MainCategoryInfo } from '@/widgets/CategoryList/types/types' | ||
|
||
import styles from './SideBar.module.scss' | ||
|
||
|
@@ -11,6 +13,10 @@ export interface ISideBar { | |
onClick?: () => void | ||
onKeyUp?: KeyboardEventHandler<HTMLLIElement> | ||
children?: ReactElement | JSX.Element | JSX.Element[] | ||
to?: string | undefined | ||
activeElement?: MainCategoryInfo | BranchesData | ||
branch?: MainCategoryInfo | BranchesData | ||
itemName?: string | ||
} | ||
|
||
/** | ||
|
@@ -20,11 +26,36 @@ export interface ISideBar { | |
* @param {function} onClick - функция выхода из профиля handleLogOut; | ||
* @param {function} onKeyUp - функция выхода из профиля handleLogOut при нажатии клавиши Enter; | ||
* @param {JSX.Element} children - контент; | ||
* Далее, для сайдбара на странице категори; | ||
* @param {string} to - если есть ссылка для item верхнего уровня, передает путь | ||
* @param {MainCategoryInfo | BranchesData} activeElement - item верхнего уровня, на который кликнули | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Эти параметры я бы передавал объектом, так же еще я бы добавил флаг - раскрывающийся или нет это sidebar, чтобы было сразу понятно, как мы его используем |
||
* @param {MainCategoryInfo | BranchesData} branch - item из children, на который кликнули | ||
* @param {string} itemName - название item, на который кликнули | ||
*/ | ||
|
||
const SideBar: FC<ISideBar> = ({ title, isVisible, onClick, onKeyUp, children }) => { | ||
const SideBar: FC<ISideBar> = ({ | ||
title, | ||
isVisible, | ||
onClick, | ||
onKeyUp, | ||
children, | ||
to, | ||
activeElement, | ||
branch, | ||
itemName | ||
}) => { | ||
const [isActive, setIsActive] = useState(false) | ||
|
||
useEffect(() => { | ||
if (activeElement?.name === itemName && activeElement !== undefined) { | ||
setIsActive(true) | ||
} else if (branch) { | ||
setIsActive(true) | ||
} else { | ||
setIsActive(false) | ||
} | ||
}, [activeElement?.slug, branch]) | ||
|
||
const handleClick = () => { | ||
setIsActive(!isActive) | ||
} | ||
|
@@ -38,17 +69,22 @@ const SideBar: FC<ISideBar> = ({ title, isVisible, onClick, onKeyUp, children }) | |
} | ||
|
||
return ( | ||
<li | ||
tabIndex={0} | ||
role="button" | ||
onKeyUp={onKeyUp} | ||
onKeyDown={handleKeyDown} | ||
onClick={onClick} | ||
className={styles.sideBar}> | ||
<li tabIndex={0} role="button" onKeyUp={onKeyUp} onKeyDown={handleKeyDown} className={styles.sideBar}> | ||
<div onClick={handleClick} className={styles.sideBar__header}> | ||
<Paragraph className={styles.sideBar__headerText}>{title}</Paragraph> | ||
{to ? ( | ||
<Link to={to}> | ||
<Paragraph className={styles.sideBar__headerText} onClick={onClick}> | ||
{title} | ||
</Paragraph> | ||
</Link> | ||
) : ( | ||
<Paragraph className={styles.sideBar__headerText} onClick={onClick}> | ||
{title} | ||
</Paragraph> | ||
)} | ||
{isVisible && ( | ||
<ArrowIcon | ||
onClick={handleClick} | ||
className={`${styles.sideBar__headerArrow} ${isActive && styles.sideBar__headerArrow_active}`} | ||
/> | ||
)} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Давай эти два стейта и useEffect вынесем в кастомный хук, откуда будем получать эти параметры.
Положить его можно в папку с этим же компонентом в models