Skip to content

Commit

Permalink
enhancement_338_sidebar_menu_modal
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderMorugin committed May 3, 2024
1 parent 6a46e34 commit 449db55
Show file tree
Hide file tree
Showing 16 changed files with 520 additions and 16 deletions.
3 changes: 3 additions & 0 deletions src/assets/icons/iconCategory.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/images/sideBarMenu/iconCategory.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/entities/SideBarButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import SideBarButton from './ui/SideBarButton'
export default SideBarButton
20 changes: 20 additions & 0 deletions src/entities/SideBarButton/ui/SideBarButton.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
@use '@/shared/styles/utils/variables' as var;

.sideBarButton {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
width: fit-content;
background: var.$white;
font-size: 14px;
color: var.$body-color;
fill: var.$body-color;
padding: 5px 15px;
transition: 0.25s;
}

.sideBarButton:hover {
color: var.$theme-secondary-color;
fill: var.$theme-secondary-color;
}
17 changes: 17 additions & 0 deletions src/entities/SideBarButton/ui/SideBarButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Meta, StoryObj } from '@storybook/react'

import SideBarButton from './SideBarButton'

const meta = {
title: 'entities/SideBarButton',
component: SideBarButton,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
} satisfies Meta<typeof SideBarButton>

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = {}
31 changes: 31 additions & 0 deletions src/entities/SideBarButton/ui/SideBarButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { FC } from 'react'

import CategoryIcon from '@/assets/images/sideBarMenu/iconCategory.svg'
import { Button, ButtonDesign, ButtonSize } from '@/shared/ui/Button/Button'

import styles from './SideBarButton.module.scss'

interface ISideBarButton {
onClick: () => void
}

/**
* Компонент кнопки "Меню" - для адаптива Side Bar Menu
* @param {function} onClick - функция клика для открытия модального окна SideBarMenuModal
*/

const SideBarButton: FC<ISideBarButton> = ({ onClick }) => {
return (
<Button
design={ButtonDesign.SQUARE}
size={ButtonSize.S}
type="button"
onClick={onClick}
className={styles.sideBarButton}>
<span>Меню</span>
<CategoryIcon />
</Button>
)
}

export default SideBarButton
22 changes: 22 additions & 0 deletions src/features/SideBarMenuModal/SideBarLink/SideBarLink.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@use '@/shared/styles/utils/variables' as var;

.sideBarLink {
display: flex;
justify-content: space-between;
align-items: center;
gap: 10px;
background: var.$body-bg;
min-height: 45px;
border-radius: 5px;
padding: 10px 15px;
cursor: pointer;

&__paragraph {
font-size: 15px;
color: var.$body-color;
}

&__arrow {
transform: rotate(270deg);
}
}
32 changes: 32 additions & 0 deletions src/features/SideBarMenuModal/SideBarLink/SideBarLink.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { KeyboardEventHandler, FC } from 'react'

import ArrowIcon from '@/assets/images/sideBarMenu/IconArrowDown.svg'
import Paragraph from '@/shared/ui/Paragraph/Paragraph'

import styles from './SideBarLink.module.scss'

export interface ISideBarLink {
isVisible?: boolean
onKeyUp?: KeyboardEventHandler<HTMLDivElement>
onClick?: () => void
title?: string
}

/**
* Компонент модального окна SideBarMenuModal, отвечающий за развертывание названий обьектов массива
* @param {boolean} isVisible - булево значение скрывающее стрелку;
* @param {function} onKeyUp - функция обнуляющая пользователя по нажатии клавиши Enter;
* @param {function} onClick - функция клика по роуту;
* @param {string} title - название роута;
*/

const SideBarLink: FC<ISideBarLink> = ({ isVisible, onKeyUp, onClick, title }) => {
return (
<div tabIndex={0} role="button" onKeyUp={onKeyUp} className={styles.sideBarLink} onClick={onClick}>
<Paragraph className={styles.sideBarLink__paragraph}>{title}</Paragraph>
{isVisible && <ArrowIcon className={styles.sideBarLink__arrow} />}
</div>
)
}

export default SideBarLink
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@use '@/shared/styles/utils/variables' as var;

.sideBarSublinks {
display: flex;
flex-direction: column;
align-items: center;
background: var.$white;
width: 100%;
border-radius: 5px;

&__header {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
margin-bottom: 18px;
cursor: pointer;
}

&__headerArrow {
transform: rotate(90deg);
}

&__routes {
display: flex;
flex-direction: column;
gap: 5px;
width: 100%;
}

&__route {
display: flex;
align-items: center;
background: var.$body-bg;
min-height: 45px;
border-radius: 5px;
font-size: 15px;
color: var.$body-color;
padding: 10px 10px 10px 15px;
}
}
76 changes: 76 additions & 0 deletions src/features/SideBarMenuModal/SideBarSublinks/SideBarSublinks.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { KeyboardEvent, FC } from 'react'
import { useNavigate } from 'react-router-dom'

import ArrowIcon from '@/assets/images/sideBarMenu/IconArrowDown.svg'
import Heading, { HeadingType } from '@/shared/ui/Heading/Heading'
import Link from '@/shared/ui/Link/Link'

import styles from './SideBarSublinks.module.scss'

export interface IData {
routes?: IRoute[]
subtitle?: string
route?: string
}

export interface IRoute {
subtitle?: string
route?: string
}

export interface ISideBarSublinks {
isActive?: boolean
choice?: number
index?: number
item?: IData
title?: string
}

/**
* Компонент модального окна SideBarMenuModal, отвечающий за развертывание роутов и их названий
* @param {boolean} isActive - булево значение;
* @param {number} choice - изменяемое состояние индекса;
* @param {number} index - индекс выбранной кнопки;
* @param {object} item - обьект массива;
* @param {string} title - заголовок обьекта массива;
*/

const SideBarSublinks: FC<ISideBarSublinks> = ({ isActive, choice, index, item, title }) => {
const navigate = useNavigate()

const handleKeyDown = (e: KeyboardEvent<HTMLAnchorElement>, index: string) => {
if (e.code === 'Enter' || e.code === 'Space') {
e.preventDefault()
navigate(index)
}
}

return (
<>
{choice === index && (
<div className={styles.sideBarSublinks}>
<div tabIndex={0} role="button" className={styles.sideBarSublinks__header}>
<ArrowIcon className={styles.sideBarSublinks__headerArrow} />
<Heading type={HeadingType.SMALL}>{title}</Heading>
</div>
<ul role="list" className={styles.sideBarSublinks__routes}>
{isActive &&
choice === index &&
item?.routes?.map((el: IData, i: number) => (
<li role="link" key={i}>
<Link
onKeyDown={e => handleKeyDown(e, el.route || '#')}
to={el.route || '#'}
className={styles.sideBarSublinks__route}>
{el.subtitle}
</Link>
</li>
))}
</ul>
</div>
)}
</>
)
}

export default SideBarSublinks
2 changes: 2 additions & 0 deletions src/features/SideBarMenuModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import SideBarMenuModal from './ui/SideBarMenuModal'
export default SideBarMenuModal
54 changes: 54 additions & 0 deletions src/features/SideBarMenuModal/model/data/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Routes } from '@/shared/config/routerConfig/routes'

// import { IData } from '../types/types'

const user = [
{
title: 'Мои данные',
routes: [
{ subtitle: 'Личный Кабинет', route: Routes.HOME }, // '/my-account' - данного роута пока нет
{ subtitle: 'Изменить контактную информацию', route: Routes.HOME }, // '/edit-account' - данного роута пока нет
{ subtitle: 'Изменить свой пароль', route: Routes.HOME }, // '/change-password' - данного роута пока нет
{ subtitle: 'Изменить мои адреса', route: Routes.HOME }, // '/address-book' - данного роута пока нет
{ subtitle: 'Посмотреть закладки', route: Routes.HOME } // '/wishlist' - данного роута пока нет
]
}
]

const noUser = [
{
title: 'Мои данные',
routes: [
{ subtitle: 'Вход', route: Routes.LOGIN },
{ subtitle: 'Регистрация', route: Routes.HOME }, // '/create-account' - данного роута пока нет
{ subtitle: 'Забыли пароль?', route: Routes.HOME }, // '/forgot-password' - данного роута пока нет
{ subtitle: 'Личный Кабинет', route: Routes.HOME } // '/my-account' - данного роута пока нет
]
}
]

const forAll = [
{
title: 'Мои заказы',
routes: [
{ subtitle: 'История заказов', route: Routes.HOME }, // '/order-history' - данного роута пока нет
{ subtitle: 'Файлы для скачивания', route: Routes.HOME }, // '/downloads' - данного роута пока нет
{ subtitle: 'Бонусные баллы: 0', route: Routes.HOME }, // '/reward-points' - данного роута пока нет
{ subtitle: 'Запросы на возврат', route: Routes.HOME }, // '/returns' - данного роута пока нет
{ subtitle: 'История транзакций', route: Routes.HOME }, // '/transactions' - данного роута пока нет
{ subtitle: 'Периодические платежи', route: Routes.HOME } // '/index.php?route=account/recurring' - данного роута пока нет
]
},
{
title: 'Мой партнерский аккаунт',
routes: [{ subtitle: 'Регистрация партнерского аккаунта', route: Routes.HOME }]
}, // '/index.php?route=account/affiliate/add' - данного роута пока нет
{
title: 'Подписка',
routes: [{ subtitle: 'Подписаться или отказаться от рассылки новостей', route: Routes.HOME }]
} // '/newsletter' - данного роута пока нет
]

export const userData = user.concat(forAll)

export const noUserData = noUser.concat(forAll)
38 changes: 38 additions & 0 deletions src/features/SideBarMenuModal/ui/SideBarMenuModal.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@use '@/shared/styles/utils/variables' as var;

.sideBarMenuModal {
position: absolute;
bottom: 0;
display: flex;
flex-direction: column;
justify-content: flex-end;
gap: 5px;
width: 100%;
padding: 25px;

&__container {
display: flex;
flex-direction: column;
gap: 18px;
background: var.$white;
border-radius: 10px;
padding: 30px;
}

&__list {
display: flex;
flex-direction: column;
gap: 5px;
list-style: none;
}

&__button {
display: flex;
align-items: center;
background: var.$white;
border-radius: 10px;
font-size: 15px;
color: var.$body-color;
padding: 10px 20px;
}
}
34 changes: 34 additions & 0 deletions src/features/SideBarMenuModal/ui/SideBarMenuModal.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Meta, StoryObj } from '@storybook/react'
import { useState } from 'react'

import SideBarMenuModal from './SideBarMenuModal'

const meta = {
title: 'features/SideBarMenuModal',
component: SideBarMenuModal,
parameters: {
layout: 'centered'
},
tags: ['autodocs']
} satisfies Meta<typeof SideBarMenuModal>

export default meta
type Story = StoryObj<typeof meta>

export const Default: Story = () => {
const [user, setUser] = useState('Elon Musk')

const handleLogOut = () => {
setUser('')
}

return (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<SideBarMenuModal user={user} handleLogOut={handleLogOut} />
</div>
)
}

Default.args = {
user: 'Elon Musk'
}
Loading

0 comments on commit 449db55

Please sign in to comment.