Skip to content

Commit

Permalink
Merge branch 'master' of github.com:Studio-Yandex-Practicum/maxboom_f…
Browse files Browse the repository at this point in the history
…rontend into layout_342_footer
  • Loading branch information
kirill-k88 committed May 5, 2024
2 parents 81db8f0 + 6a46e34 commit c023d8f
Show file tree
Hide file tree
Showing 18 changed files with 457 additions and 16 deletions.
3 changes: 3 additions & 0 deletions src/assets/images/sideBarMenu/IconArrowDown.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/Category/selectors/categorySelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ export const selectDisplayedCategories = (state: RootState) => state.category.di
export const selectCategoryId = (state: RootState) => state.categoryId.categoryId

export const selectCategorySlug = (state: RootState) => state.categorySlug.categorySlug

export const getLoading = (state: RootState) => state.category.isLoading
4 changes: 4 additions & 0 deletions src/entities/Category/slice/categorySlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ApiError, ApiErrorTypes, ApiRoutes } from '@/shared/api/types'
import type { Category, CategorySchema } from '../types/types'

const initialState: CategorySchema = {
isLoading: false,
categories: [],
displayedCategories: [],
error: undefined
Expand All @@ -34,13 +35,16 @@ const categorySlice = createSlice({
extraReducers: builder => {
builder
.addCase(fetchCategories.pending, state => {
state.isLoading = true
state.error = undefined
})
.addCase(fetchCategories.fulfilled, (state, action) => {
state.isLoading = false
state.categories = action.payload
state.displayedCategories = action.payload.filter((c: Category) => c.is_visible_on_main === true)
})
.addCase(fetchCategories.rejected, (state, { payload }) => {
state.isLoading = false
state.error = rejectedPayloadHandle(payload)
})
}
Expand Down
1 change: 1 addition & 0 deletions src/entities/Category/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export interface CategorySchema {
isLoading: boolean
categories: Category[]
displayedCategories: Category[]
error?: string | string[]
Expand Down
4 changes: 2 additions & 2 deletions src/features/CartEdit/ui/CartEdit/CartEdit.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
display: flex;
align-items: center;
justify-content: center;
width: 50px; // bug поменяла 20 на 50 для того,чтобы svg отображался в storybook, при 20px в storybook svg сжимается сильно и пропадает, на сайте padding от <Button> переписывается, а в storybook нет
width: 50px; // bug поменяла 20 на 50 для того,чтобы svg отображался в storybook, при 20px в storybook svg сжимается сильно и пропадает, на сайте padding от <Button> переписывается, а в storybook нет
height: 100%;
transition: background 0.25s;
}
Expand Down Expand Up @@ -174,4 +174,4 @@

.arrowIcon {
rotate: 180deg;
}
}
2 changes: 2 additions & 0 deletions src/features/SideBar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import SideBar from './ui/SideBar'
export default SideBar
50 changes: 50 additions & 0 deletions src/features/SideBar/ui/SideBar.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@use '@/shared/styles/utils/variables' as var;
@use '@/shared/styles/utils/mixins' as media;

.sideBar {
display: flex;
flex-direction: column;
min-width: 100%;
border-radius: 5px;

&__header {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
background: var.$body-bg;
border-radius: 6px;
padding: 10px 10px 10px 15px;
cursor: pointer;
}

&__headerText {
color: var.$body-color;
transition: 0.25s;
}

&__headerArrow {
transition: transform 0.25s;
}

&__headerArrow_active {
transform: rotate(180deg);
}

&__header:hover &__headerText {
color: var.$header-color;
}

&__header:hover &__headerArrow path {
fill: var.$header-color;
}

&__children {
padding: 15px 0 20px;
transition: 0.5s;

&_close {
padding: 0;
}
}
}
48 changes: 48 additions & 0 deletions src/features/SideBar/ui/SideBar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { Meta, StoryObj } from '@storybook/react'

import SideBar from './SideBar'

const meta = {
title: 'features/SideBar',
component: SideBar,
tags: ['autodocs'],
args: {}
} satisfies Meta<typeof SideBar>

export default meta

type Story = StoryObj<typeof SideBar>

export const Default: Story = () => {
return (
<div style={{ width: '340px' }}>
<SideBar isVisible={true} title="Мои данные">
<ul style={{ padding: '10px' }}>
<li style={{ paddingBottom: '10px' }}>
<a
style={{ textDecoration: 'none', color: '#343434', fontSize: '15px' }}
href="https://maxboom.ru/">
Текст
</a>
</li>
<li style={{ paddingBottom: '10px' }}>
<a
style={{ textDecoration: 'none', color: '#343434', fontSize: '15px' }}
href="https://maxboom.ru/">
Текст
</a>
</li>
<li style={{ paddingBottom: '10px' }}>
<a
style={{ textDecoration: 'none', color: '#343434', fontSize: '15px' }}
href="https://maxboom.ru/">
Текст
</a>
</li>
</ul>
</SideBar>
</div>
)
}

Default.args = {}
70 changes: 70 additions & 0 deletions src/features/SideBar/ui/SideBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { KeyboardEvent, KeyboardEventHandler, ReactElement, useState, type FC } from 'react'

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

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

export interface ISideBar {
title?: string
isVisible?: boolean
onClick?: () => void
onKeyUp?: KeyboardEventHandler<HTMLLIElement>
children?: ReactElement | JSX.Element | JSX.Element[]
}

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

const SideBar: FC<ISideBar> = ({ title, isVisible, onClick, onKeyUp, children }) => {
const [isActive, setIsActive] = useState(false)

const handleClick = () => {
setIsActive(!isActive)
}

const handleKeyDown = (e: KeyboardEvent<HTMLLIElement>) => {
if (e.code === 'Enter' || e.code === 'Space') {
e.preventDefault()
e.stopPropagation()
handleClick()
}
}

return (
<li
tabIndex={0}
role="button"
onKeyUp={onKeyUp}
onKeyDown={handleKeyDown}
onClick={onClick}
className={styles.sideBar}>
<div onClick={handleClick} className={styles.sideBar__header}>
<Paragraph className={styles.sideBar__headerText}>{title}</Paragraph>
{isVisible && (
<ArrowIcon
className={`${styles.sideBar__headerArrow} ${isActive && styles.sideBar__headerArrow_active}`}
/>
)}
</div>
{isVisible && (
<div
className={
isActive
? `${styles.sideBar__children}`
: `${styles.sideBar__children} ${styles.sideBar__children_close}`
}>
{isActive && children}
</div>
)}
</li>
)
}

export default SideBar
52 changes: 52 additions & 0 deletions src/mockData/sideBarProfileData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Routes } from '@/shared/config/routerConfig/routes'

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)
18 changes: 14 additions & 4 deletions src/pages/FormReturnPage/FormReturnPage.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import { FC, useState } from 'react'

import WrapperForMainContent from '@/components/WrapperForMainContent/WrapperForMainContent'
import { Routes } from '@/shared/config/routerConfig/routes'
import Breadcrumbs from '@/shared/ui/Breadcrumbs/Breadcrumbs'
import Heading, { HeadingType } from '@/shared/ui/Heading/Heading'
import FormReturn from '@/widgets/FormReturn'
import SideBarMenu from '@/widgets/SideBarMenu'

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

const links = [
{ heading: 'Главная', href: '/' },
{ heading: 'Личный Кабинет', href: '/login' },
{ heading: 'Главная', href: Routes.HOME },
{ heading: 'Личный Кабинет', href: Routes.LOGIN },
{ heading: 'Возврат товара', href: '' }
]

const FormReturnPage = () => {
const FormReturnPage: FC = () => {
const [user, setUser] = useState('Моругина Мария') // позже юзера будем получать из редакса

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

return (
<WrapperForMainContent>
<section className={styles.formReturn}>
Expand All @@ -22,7 +32,7 @@ const FormReturnPage = () => {
<Breadcrumbs links={links} />
</div>
<div className={styles.formReturn__mainBox}>
<div className={styles.formReturn__burger}>Burger menu</div>
<SideBarMenu user={user} handleLogOut={handleLogOut} />
<FormReturn />
</div>
</section>
Expand Down
26 changes: 26 additions & 0 deletions src/shared/ui/CatalogLink/ui/skeleton/CatalogLinkSkeleton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { FC } from 'react'
import Skeleton from 'react-loading-skeleton'
import 'react-loading-skeleton/dist/skeleton.css'

interface ICatalogLinkSkeleton {
key: number
width: number
height: number
}

/**
* Компонент CatalogLinkSkeleton - заставка, пока не загрузятся CatalogLink
* @param {number} key - индекс списка
* @param {number} width - ширина скелетона
* @param {number} height - высота скелетона
*/

const CatalogLinkSkeleton: FC<ICatalogLinkSkeleton> = ({ key, width, height }) => {
return (
<li key={key}>
<Skeleton count={1} height={height} width={width} />
</li>
)
}

export default CatalogLinkSkeleton
Loading

0 comments on commit c023d8f

Please sign in to comment.