diff --git a/public/images/exclamation.svg b/public/images/exclamation.svg new file mode 100644 index 00000000..7d6e8e64 --- /dev/null +++ b/public/images/exclamation.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/index.html b/public/index.html index 382252e4..eb0f51de 100644 --- a/public/index.html +++ b/public/index.html @@ -11,6 +11,7 @@ +
diff --git a/src/config/lexics/indexLexics.tsx b/src/config/lexics/indexLexics.tsx index b0633f4c..d7b7b586 100644 --- a/src/config/lexics/indexLexics.tsx +++ b/src/config/lexics/indexLexics.tsx @@ -2,6 +2,7 @@ import { proceduresLexics } from './procedures' export const indexLexics = { add_to_favorites: 1701, + add_to_favorites_error: 12943, added_to_favorites: 13048, basketball: 6960, broadcast: 13049, diff --git a/src/features/HomePage/index.tsx b/src/features/HomePage/index.tsx index 9f80b657..8a0be7b1 100644 --- a/src/features/HomePage/index.tsx +++ b/src/features/HomePage/index.tsx @@ -1,7 +1,6 @@ import React from 'react' import { Matches } from 'features/Matches' - import { Content } from './styled' export const HomePage = () => ( diff --git a/src/features/Modal/index.tsx b/src/features/Modal/index.tsx new file mode 100644 index 00000000..7315aaba --- /dev/null +++ b/src/features/Modal/index.tsx @@ -0,0 +1,38 @@ +import type { ReactNode } from 'react' + +import React, { + useRef, +} from 'react' +import ReactDOM from 'react-dom' + +import { + ModalContainer, + ModalWindow, + ModalCloseButton, +} from './styled' + +type TModalProps = { + children: ReactNode, + close: ()=> void, + isOpen: boolean, +} + +export const Modal = ({ + children, + close, + isOpen, +}: TModalProps) => { + const modalRoot = useRef(document.getElementById('modal-root')) + + return isOpen + ? ReactDOM.createPortal( + + + + {children} + + , + modalRoot.current as Element, + ) + : null +}; diff --git a/src/features/Modal/styled.tsx b/src/features/Modal/styled.tsx new file mode 100644 index 00000000..b75a1026 --- /dev/null +++ b/src/features/Modal/styled.tsx @@ -0,0 +1,32 @@ +import styled from 'styled-components/macro' + +import { CloseButton } from 'features/Common/CloseButton' + +export const ModalContainer = styled.div` + position: fixed; + top: 0; + left: 0; + height: 100vh; + width: 100vw; + display: flex; + align-items: center; + justify-content: center; + z-index: 3; + color: white; + font-weight: 600; +` +export const ModalWindow = styled.div` + background: #3F3F3F; + position: relative; + padding: 15px; + box-shadow: 0px 5px 30px rgba(0, 0, 0, 0.7); + border-radius: 10px; +` + +export const ModalCloseButton = styled(CloseButton)` + margin-right: 19px; + margin-top: 16px; + width: 12.82px; + height: 12.82px; + cursor: pointer; +` diff --git a/src/features/OutsideClick/hooks/index.tsx b/src/features/OutsideClick/hooks/index.tsx index d9cbfd1e..11cd5156 100644 --- a/src/features/OutsideClick/hooks/index.tsx +++ b/src/features/OutsideClick/hooks/index.tsx @@ -15,7 +15,7 @@ export const useOutsideClickEffect = ({ : null /** деструктуризация wrapperRef не сработает, ссылка на реф теряется */ - if (wrapperRef.current && !wrapperRef.current.contains(targetNode)) { + if (!wrapperRef.current?.contains(targetNode)) { onClick() } } diff --git a/src/features/ProfileCard/hooks.tsx b/src/features/ProfileCard/hooks.tsx index 8c34df5f..f91e25ab 100644 --- a/src/features/ProfileCard/hooks.tsx +++ b/src/features/ProfileCard/hooks.tsx @@ -4,9 +4,11 @@ import { useCallback } from 'react' import findIndex from 'lodash/findIndex' import { handleImageError, getProfileLogo } from 'helpers' -import { useUserFavoritesStore } from 'features/UserFavorites/store' + import { useSportNameParam, usePageId } from 'hooks' +import { useUserFavoritesStore } from 'features/UserFavorites/store' + import type { ProfileCardProps } from './types' export const useProfileCard = ({ profileType }: ProfileCardProps) => { diff --git a/src/features/UserFavorites/hooks/index.tsx b/src/features/UserFavorites/hooks/index.tsx index a02e542d..11921d30 100644 --- a/src/features/UserFavorites/hooks/index.tsx +++ b/src/features/UserFavorites/hooks/index.tsx @@ -6,8 +6,11 @@ import { import type { UserFavorites } from 'requests' import { modifyUserFavorites, getUserFavorites } from 'requests' + import { useLexicsStore } from 'features/LexicsStore' +import { useToggle } from 'hooks/useToggle' + import { normalizeUserFavorites } from '../helpers' type Args = Parameters[0] @@ -16,12 +19,18 @@ export const useUserFavorites = () => { const { suffix } = useLexicsStore() const [userFavorites, setUserFavorites] = useState([]) + const { + close, + isOpen, + open, + } = useToggle() + useEffect(() => { getUserFavorites().then(setUserFavorites) }, []) const addRemoveFavorite = (args: Args) => { - modifyUserFavorites(args).then(setUserFavorites) + modifyUserFavorites(args).then(setUserFavorites, open) } const memoizedUserFavorites = useMemo( @@ -31,6 +40,9 @@ export const useUserFavorites = () => { return { addRemoveFavorite, + close, + isOpen, + open, userFavorites: memoizedUserFavorites, } } diff --git a/src/features/UserFavorites/index.tsx b/src/features/UserFavorites/index.tsx index 68a9ab89..07fdfe5f 100644 --- a/src/features/UserFavorites/index.tsx +++ b/src/features/UserFavorites/index.tsx @@ -4,8 +4,10 @@ import map from 'lodash/map' import { handleImageError } from 'helpers' -import { useUserFavoritesStore } from './store' +import { Modal } from 'features/Modal' + import { TooltipBlock } from './TooltipBlock' + import { StyledLink, UserSportFavItemLogoWrapper, @@ -14,10 +16,19 @@ import { UserSportFavStar, UserSportFavLogoWrapper, UserSportFavWrapper, + ExclamationSign, + FavoriteModal, + Text, } from './styled' +import { useUserFavoritesStore } from './store' export const UserFavorites = () => { - const { addRemoveFavorite, userFavorites } = useUserFavoritesStore() + const { + addRemoveFavorite, + close, + isOpen, + userFavorites, + } = useUserFavoritesStore() return ( @@ -56,6 +67,15 @@ export const UserFavorites = () => { )) } + + + + + + ) } diff --git a/src/features/UserFavorites/styled.tsx b/src/features/UserFavorites/styled.tsx index 6617ffc4..5b2a2baa 100644 --- a/src/features/UserFavorites/styled.tsx +++ b/src/features/UserFavorites/styled.tsx @@ -3,6 +3,8 @@ import { Link } from 'react-router-dom' import styled from 'styled-components/macro' import { Logo } from 'features/Logo' +import { T9n } from 'features/T9n' + import { TooltipBlockWrapper } from './TooltipBlock/styled' export const StyledLink = styled(Link)`` @@ -83,3 +85,24 @@ export const UserSportFavStar = styled.div` background: #3f3f3f url('/images/sportFavStar.png') no-repeat center; margin-bottom: 16px; ` + +export const FavoriteModal = styled.div` + width: 411px; + height: 202px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +` + +export const ExclamationSign = styled.div` + width: 77px; + height: 66px; + background: url(/images/exclamation.svg) no-repeat; + margin-bottom: 20px; +` + +export const Text = styled(T9n)` + text-align: center; + line-height: 160.2%; +` diff --git a/src/requests/modifyUserSportFavs.tsx b/src/requests/modifyUserSportFavs.tsx index 2203e97f..dc50c150 100644 --- a/src/requests/modifyUserSportFavs.tsx +++ b/src/requests/modifyUserSportFavs.tsx @@ -1,17 +1,20 @@ -import isArray from 'lodash/isArray' - import { DATA_URL, PROCEDURES, SportTypes, ProfileTypes, } from 'config' -import { callApi, getResponseData } from 'helpers' +import { callApi } from 'helpers' import { UserFavorites } from './getUserSportFavs' const proc = PROCEDURES.save_user_favorite +enum FavoriteStatusTypes { + SUCCESS = 1, + FAILURE = 2, +} + type Args = { action: number, id: number, @@ -38,10 +41,13 @@ export const modifyUserFavorites = async ({ }, } - const data = await callApi({ + const { _p_data, _p_status } = await callApi({ config, url: DATA_URL, - }).then(getResponseData(proc)) + }) - return isArray(data) ? data : [] + if (_p_status === FavoriteStatusTypes.FAILURE) { + return Promise.reject() + } + return Promise.resolve(_p_data) }