diff --git a/src/pages/FormReturnPage/FormReturnPage.tsx b/src/pages/FormReturnPage/FormReturnPage.tsx
index 520c7ac9..3b8ccb32 100644
--- a/src/pages/FormReturnPage/FormReturnPage.tsx
+++ b/src/pages/FormReturnPage/FormReturnPage.tsx
@@ -1,32 +1,89 @@
+import { KeyboardEvent, FC, Suspense, lazy, useState } from 'react'
+
import WrapperForMainContent from '@/components/WrapperForMainContent/WrapperForMainContent'
+import SideBarButton from '@/entities/SideBarButton'
+import { Routes } from '@/shared/config/routerConfig/routes'
+import { useResize } from '@/shared/libs/hooks/useResize'
import Breadcrumbs from '@/shared/ui/Breadcrumbs/Breadcrumbs'
import Heading, { HeadingType } from '@/shared/ui/Heading/Heading'
+import Modal from '@/shared/ui/Modal/Modal'
+import Spinner from '@/shared/ui/Spinner/Spinner'
import FormReturn from '@/widgets/FormReturn'
+import SideBarMenu from '@/widgets/SideBarMenu'
import styles from './FormReturnPage.module.scss'
+const SideBarMenuModal = lazy(() => import('@/features/SideBarMenuModal'))
+
const links = [
- { heading: 'Главная', href: '/' },
- { heading: 'Личный Кабинет', href: '/login' },
+ { heading: 'Главная', href: Routes.HOME },
+ { heading: 'Личный Кабинет', href: Routes.LOGIN },
{ heading: 'Возврат товара', href: '' }
]
-const FormReturnPage = () => {
+const FormReturnPage: FC = () => {
+ const [isModalOpen, setIsModalOpen] = useState
(false)
+ const [isModalClosing, setIsModalClosing] = useState(false)
+ const [user, setUser] = useState('Elon Musk') // позже юзера будем получать из редакса
+
+ const { isScreenMd } = useResize()
+
+ const changeModalState = () => {
+ setIsModalOpen(!isModalOpen)
+ }
+
+ const handleClick = () => {
+ setIsModalOpen(true)
+ }
+
+ const handleLogOut = () => {
+ setUser('')
+ }
+
+ const handleKeyUp = (e: KeyboardEvent) => {
+ if (e.code === 'Enter' || e.code === 'Space') {
+ e.preventDefault()
+ handleLogOut()
+ }
+ }
+
return (
-
-
-
-
- Возврат товара
-
-
-
-
-
-
+ <>
+ {isModalOpen && (
+
+ }>
+
+
+
+ )}
+
+
+
+
+ Возврат товара
+
+
+
+
+ {isScreenMd ? (
+
+ ) : (
+
+ )}
+
+
+
+
+ >
)
}
diff --git a/src/shared/api/types.ts b/src/shared/api/types.ts
index db6103c4..bc674244 100644
--- a/src/shared/api/types.ts
+++ b/src/shared/api/types.ts
@@ -13,7 +13,8 @@ export enum ApiRoutes {
STORIES = 'stories',
PRODUCT = 'catalogue',
CART_LIST = 'cart',
- INCREASE_PRODUCT_AMOUNT = 'cart/add/'
+ INCREASE_PRODUCT_AMOUNT = 'cart/add/',
+ DECREASE_PRODUCT_AMOUNT = 'cart/subtract/'
}
export enum ApiErrorTypes {
diff --git a/src/models/CartModel.ts b/src/shared/model/types/CartModel.ts
similarity index 86%
rename from src/models/CartModel.ts
rename to src/shared/model/types/CartModel.ts
index c8861912..1789b898 100644
--- a/src/models/CartModel.ts
+++ b/src/shared/model/types/CartModel.ts
@@ -5,4 +5,5 @@ export interface ICart {
products: IProductCartList[]
user: number
cart_full_price: number
+ cart_full_weight: number
}
diff --git a/src/models/ImageModel.ts b/src/shared/model/types/ImageModel.ts
similarity index 100%
rename from src/models/ImageModel.ts
rename to src/shared/model/types/ImageModel.ts
diff --git a/src/models/ProductCartListModel.ts b/src/shared/model/types/ProductCartListModel.ts
similarity index 86%
rename from src/models/ProductCartListModel.ts
rename to src/shared/model/types/ProductCartListModel.ts
index 1deb61e9..79f8da98 100644
--- a/src/models/ProductCartListModel.ts
+++ b/src/shared/model/types/ProductCartListModel.ts
@@ -4,4 +4,5 @@ export interface IProductCartList {
amount: number
product: IProduct
full_price: number
+ full_weight: number
}
diff --git a/src/models/ProductModel.ts b/src/shared/model/types/ProductModel.ts
similarity index 95%
rename from src/models/ProductModel.ts
rename to src/shared/model/types/ProductModel.ts
index 62220fe4..627dc61d 100644
--- a/src/models/ProductModel.ts
+++ b/src/shared/model/types/ProductModel.ts
@@ -16,4 +16,5 @@ export interface IProduct {
wholesale?: number
label_hit?: boolean
label_popular?: boolean
+ weight?: string
}
diff --git a/src/shared/ui/CatalogLink/ui/skeleton/CatalogLinkSkeleton.tsx b/src/shared/ui/CatalogLink/ui/skeleton/CatalogLinkSkeleton.tsx
new file mode 100644
index 00000000..014d2a44
--- /dev/null
+++ b/src/shared/ui/CatalogLink/ui/skeleton/CatalogLinkSkeleton.tsx
@@ -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 = ({ key, width, height }) => {
+ return (
+
+
+
+ )
+}
+
+export default CatalogLinkSkeleton
diff --git a/src/shared/ui/FormMsg/FormMsg.module.scss b/src/shared/ui/FormMsg/FormMsg.module.scss
index d8c5d99d..61bfa907 100644
--- a/src/shared/ui/FormMsg/FormMsg.module.scss
+++ b/src/shared/ui/FormMsg/FormMsg.module.scss
@@ -19,6 +19,20 @@
border-radius: 10px;
@include font(18px);
+ &_ispopup {
+ width: 300px;
+ opacity: 0;
+ position: fixed;
+ top: 50px;
+ left: -350px;
+ transition: all 0.5s;
+ }
+
+ &_popupIsOpen {
+ left: 50px;
+ opacity: 1;
+ }
+
&_iserror {
background-color: color.$promo-color;
}
diff --git a/src/shared/ui/FormMsg/FormMsg.stories.tsx b/src/shared/ui/FormMsg/FormMsg.stories.tsx
index 8422ea15..00b2155a 100644
--- a/src/shared/ui/FormMsg/FormMsg.stories.tsx
+++ b/src/shared/ui/FormMsg/FormMsg.stories.tsx
@@ -19,7 +19,7 @@ export const Succeed: Story = {
text: 'Данные успешно отправлены!',
isError: false,
disableClose: false,
- closeHandel: () => {
+ closeHandle: () => {
alert('Выполненяются действия из переданной функции')
}
}
@@ -30,7 +30,7 @@ export const Error: Story = {
text: 'Ошибка отправки данных на сервер!',
isError: true,
disableClose: false,
- closeHandel: () => {
+ closeHandle: () => {
alert('Выполненяются действия из переданной функции')
}
}
diff --git a/src/shared/ui/FormMsg/FormMsg.tsx b/src/shared/ui/FormMsg/FormMsg.tsx
index 4cf83c76..c51ebb13 100644
--- a/src/shared/ui/FormMsg/FormMsg.tsx
+++ b/src/shared/ui/FormMsg/FormMsg.tsx
@@ -1,13 +1,15 @@
-import { FC, MouseEvent } from 'react'
+import { FC, MouseEvent, useEffect, useState } from 'react'
import styles from './FormMsg.module.scss'
+import { EMsgType } from './model/types/types'
interface IFormMsgProps {
text: string
isError: boolean
disableClose?: boolean
- closeHandel?: () => void
+ closeHandle?: () => void
className?: string
+ type?: EMsgType
}
/**
@@ -15,24 +17,43 @@ interface IFormMsgProps {
* @param {string} text текст сообщения
* @param {boolean} isError true, если это сообщение об ошибке
* @param {boolean} [disableClose = false] true, если необходимо убрать возможность закрытия окна
- * @param {function} closeHandel void-функция, вызываемая при нажатии на кнопку закрытия
+ * @param {function} closeHandle void-функция, вызываемая при нажатии на кнопку закрытия
+ * @param {EMsgType} type тип высплывающей ошибки: EMsgType.popup - открывает как банер-попап ввреху страницы, EMsgType.form (по умолчанию) открывает в зависимости от места в tsx
*/
export const FormMsg: FC = ({
text,
isError,
- closeHandel,
+ closeHandle,
className = '',
+ type = EMsgType.form,
disableClose = false
}) => {
+ const [isOpen, setIsOpen] = useState(false)
const onCloseHandel = (e: MouseEvent) => {
e.stopPropagation()
- if (closeHandel) {
- closeHandel()
+ if (typeof closeHandle === 'function') {
+ if (type === EMsgType.popup) {
+ setIsOpen(false)
+ setTimeout(() => {
+ closeHandle()
+ }, 500)
+ } else {
+ closeHandle()
+ }
}
}
+ useEffect(() => {
+ if (type === EMsgType.popup) {
+ setIsOpen(true)
+ }
+ }, [])
+
return (
-
+
{text}
{!disableClose && (
diff --git a/src/widgets/Header/Header.tsx b/src/widgets/Header/Header.tsx
index 93e316af..7b8ba612 100644
--- a/src/widgets/Header/Header.tsx
+++ b/src/widgets/Header/Header.tsx
@@ -3,7 +3,11 @@ import { useEffect, useMemo, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { AppDispatch } from '@/app/providers/StoreProvider/config/store'
-import { selectCategories, selectDisplayedCategories } from '@/entities/Category/selectors/categorySelectors'
+import {
+ getLoading,
+ selectCategories,
+ selectDisplayedCategories
+} from '@/entities/Category/selectors/categorySelectors'
import { fetchCategories } from '@/entities/Category/slice/categorySlice'
import HeaderAccount from '@/entities/HeaderAccount/HeaderAccount'
import CallBack from '@/features/CallBack'
@@ -14,9 +18,11 @@ import IconCategories from '@/shared/icons/IconCategories.svg'
import { linkItems } from '@/shared/mockData/catalogListData'
import { headerAccountData } from '@/shared/mockData/headerAccountData'
import CatalogLink from '@/shared/ui/CatalogLink/CatalogLink'
+import CatalogLinkSkeleton from '@/shared/ui/CatalogLink/ui/skeleton/CatalogLinkSkeleton'
import ContextMenuElement from '@/shared/ui/ContextMenuElement/ContextMenuElement'
import Link from '@/shared/ui/Link/Link'
import Logo from '@/shared/ui/logo/Logo'
+import LogoSkeleton from '@/shared/ui/logo/model/skeleton/LogoSkeleton'
import Modal from '@/shared/ui/Modal/Modal'
import Paragraph from '@/shared/ui/Paragraph/Paragraph'
import CatalogNodeItem from '@/widgets/CatalogNodeItem/CatalogNodeItem'
@@ -37,6 +43,9 @@ function Header() {
const [isModalOpen, setIsModalOpen] = useState(false)
const [isModalClosing, setIsModalClosing] = useState(false)
const phoneNumber = coreBaseData.header.support.phone_number
+ const logo = coreBaseData.header.main_logo.image
+
+ const isCategoriesLoading = useSelector(getLoading)
const changeModalState = () => {
setIsModalOpen(!isModalOpen)
@@ -147,7 +156,11 @@ function Header() {
-
+ {!logo ? (
+
+ ) : (
+
+ )}
@@ -163,15 +176,25 @@ function Header() {
- {displayedCategories.map(category => (
-
- {category.name}
-
- ))}
+ {isCategoriesLoading ? (
+
+ {Array(4)
+ .fill(0)
+ .map((_, i) => (
+
+ ))}
+
+ ) : (
+ displayedCategories.map(category => (
+
+ {category.name}
+
+ ))
+ )}