Ott 1395 favorites for mobiles (#440)
* feat(ott-1395): add favorites for mobile * feat(ott-1395): change variable name * feat(ott-1395): remove useless indent * feat(ott-1395): code review fixkeep-around/af30b88d367751c9e05a735e4a0467a96238ef47
parent
5bc7188809
commit
1f21b70ab7
|
After Width: | Height: | Size: 448 B |
|
After Width: | Height: | Size: 449 B |
|
After Width: | Height: | Size: 327 B |
@ -0,0 +1,41 @@ |
|||||||
|
import { ProfileTypes } from 'config' |
||||||
|
|
||||||
|
import type { UserFavorite } from 'requests/getUserSportFavs' |
||||||
|
import { getName } from 'features/Name' |
||||||
|
|
||||||
|
export const getFavoriteItemNames = (item: UserFavorite, suffix: string) => { |
||||||
|
const { info, type } = item |
||||||
|
|
||||||
|
const currentName = { |
||||||
|
name_eng: info.name_eng || info.nickname_eng, |
||||||
|
name_rus: info.name_rus || info.nickname_rus, |
||||||
|
} |
||||||
|
|
||||||
|
const countryOrTeamParams = () => { |
||||||
|
switch (type) { |
||||||
|
case ProfileTypes.TOURNAMENTS: |
||||||
|
case ProfileTypes.TEAMS: |
||||||
|
return { |
||||||
|
id: info.country?.id, |
||||||
|
name_eng: info.country?.name_eng, |
||||||
|
name_rus: info.country?.name_rus, |
||||||
|
} |
||||||
|
case ProfileTypes.PLAYERS: |
||||||
|
return { |
||||||
|
id: info.country?.id, |
||||||
|
name_eng: info.team?.name_eng, |
||||||
|
name_rus: info.team?.name_rus, |
||||||
|
} |
||||||
|
default: |
||||||
|
return {} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const name = getName({ nameObj: currentName, suffix }) |
||||||
|
const countryOrTeam = getName({ nameObj: countryOrTeamParams(), suffix }) |
||||||
|
|
||||||
|
return { |
||||||
|
countryOrTeam, |
||||||
|
name, |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,84 @@ |
|||||||
|
import { useState } from 'react' |
||||||
|
|
||||||
|
import map from 'lodash/map' |
||||||
|
|
||||||
|
import type { UserFavorites } from 'requests/getUserSportFavs' |
||||||
|
import { T9n } from 'features/T9n' |
||||||
|
import { SportIcon } from 'features/SportIcon' |
||||||
|
import { useLexicsStore } from 'features/LexicsStore' |
||||||
|
import { ProfileLink } from 'features/ProfileLink' |
||||||
|
import { UserSportFavImgWrapper } from 'features/UserFavorites/styled' |
||||||
|
import { Flag } from 'features/ItemsList/styled' |
||||||
|
|
||||||
|
import { getFavoriteItemNames } from './helpers' |
||||||
|
import { |
||||||
|
BlockWrapper, |
||||||
|
ContentWrapper, |
||||||
|
EmptyDiv, |
||||||
|
EmptySpan, |
||||||
|
Item, |
||||||
|
CountryAndTeamInfo, |
||||||
|
SportItemLogoWrapper, |
||||||
|
Arrows, |
||||||
|
TitleWrapper, |
||||||
|
Name, |
||||||
|
} from './styled' |
||||||
|
|
||||||
|
type Props = { |
||||||
|
groupBlock: { |
||||||
|
items: UserFavorites, |
||||||
|
typeLexic: string, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
export const GroupBlock = ({ groupBlock }: Props) => { |
||||||
|
const [activeItems, setActiveItems] = useState(true) |
||||||
|
const { items, typeLexic } = groupBlock |
||||||
|
const { suffix } = useLexicsStore() |
||||||
|
|
||||||
|
return ( |
||||||
|
<BlockWrapper> |
||||||
|
<TitleWrapper> |
||||||
|
<T9n t={typeLexic} /> |
||||||
|
<Arrows |
||||||
|
onClick={() => setActiveItems(!activeItems)} |
||||||
|
active={activeItems} |
||||||
|
/> |
||||||
|
</TitleWrapper> |
||||||
|
<ContentWrapper> |
||||||
|
{activeItems && map(items, (item) => { |
||||||
|
const favoriteItemNames = getFavoriteItemNames(item, suffix) |
||||||
|
const { countryOrTeam, name } = favoriteItemNames |
||||||
|
|
||||||
|
return ( |
||||||
|
<Item key={item.id}> |
||||||
|
<SportItemLogoWrapper> |
||||||
|
<ProfileLink |
||||||
|
id={item.id} |
||||||
|
sportType={item.sport} |
||||||
|
profileType={item.type} |
||||||
|
> |
||||||
|
<UserSportFavImgWrapper |
||||||
|
id={item.id} |
||||||
|
altNameObj={item} |
||||||
|
sportType={item.sport} |
||||||
|
profileType={item.type} |
||||||
|
/> |
||||||
|
</ProfileLink> |
||||||
|
</SportItemLogoWrapper> |
||||||
|
|
||||||
|
<EmptyDiv> |
||||||
|
<Name>{name}</Name> |
||||||
|
<CountryAndTeamInfo> |
||||||
|
<SportIcon sport={item.sport} /> |
||||||
|
<Flag src={`https://instatscout.com/images/flags/48/${item.info.country?.id}.png`} /> |
||||||
|
<EmptySpan>{countryOrTeam}</EmptySpan> |
||||||
|
</CountryAndTeamInfo> |
||||||
|
</EmptyDiv> |
||||||
|
</Item> |
||||||
|
) |
||||||
|
})} |
||||||
|
</ContentWrapper> |
||||||
|
</BlockWrapper> |
||||||
|
) |
||||||
|
} |
||||||
@ -0,0 +1,87 @@ |
|||||||
|
import styled from 'styled-components/macro' |
||||||
|
|
||||||
|
import { devices } from 'config' |
||||||
|
import { UserSportFavItemLogoWrapper } from 'features/UserFavorites/styled' |
||||||
|
|
||||||
|
type Props = { |
||||||
|
active?: boolean, |
||||||
|
} |
||||||
|
|
||||||
|
export const BlockWrapper = styled.div` |
||||||
|
margin-top: 20px; |
||||||
|
width: 32%; |
||||||
|
|
||||||
|
@media ${devices.mobile} { |
||||||
|
font-size: 14px; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const TitleWrapper = styled.div` |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
` |
||||||
|
|
||||||
|
export const ContentWrapper = styled.div` |
||||||
|
margin-top: 10px; |
||||||
|
background-color: #3F3F3F; |
||||||
|
border-radius: 1.4px; |
||||||
|
` |
||||||
|
|
||||||
|
export const Item = styled.div` |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
padding: 10px; |
||||||
|
font-size: 11px; |
||||||
|
|
||||||
|
@media ${devices.mobile} { |
||||||
|
padding-left: 2rem; |
||||||
|
font-size: 11px; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const CountryAndTeamInfo = styled.div` |
||||||
|
margin-top: 0.4rem; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
color: rgba(255, 255, 255, 0.7); |
||||||
|
` |
||||||
|
|
||||||
|
export const SportItemLogoWrapper = styled(UserSportFavItemLogoWrapper)` |
||||||
|
margin-right: 0.5rem; |
||||||
|
|
||||||
|
:not(:last-child) { |
||||||
|
margin-bottom: 0; |
||||||
|
} |
||||||
|
|
||||||
|
@media ${devices.mobile} { |
||||||
|
width: 4.6rem; |
||||||
|
height: 4.6rem; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const Arrows = styled.span<Props>` |
||||||
|
display: inline-block; |
||||||
|
width: 1rem; |
||||||
|
height: 1rem; |
||||||
|
background-repeat: no-repeat; |
||||||
|
background-position: center; |
||||||
|
background-image: url(/images/arrowUpWhite.svg); |
||||||
|
transform: ${({ active }) => (active ? '' : 'rotate(180deg)')}; |
||||||
|
|
||||||
|
@media ${devices.mobile} { |
||||||
|
width: 2.5rem; |
||||||
|
height: 1.5rem; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const Name = styled.div` |
||||||
|
@media ${devices.mobile} { |
||||||
|
font-size: 10px; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const EmptySpan = styled.span`` |
||||||
|
|
||||||
|
export const EmptyDiv = styled.div`` |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
import groupBy from 'lodash/groupBy' |
||||||
|
import map from 'lodash/map' |
||||||
|
|
||||||
|
import { ProfileTypes } from 'config' |
||||||
|
import { useUserFavoritesStore } from 'features/UserFavorites/store' |
||||||
|
|
||||||
|
export const useFavoritesMobilePopup = () => { |
||||||
|
const { userFavorites } = useUserFavoritesStore() |
||||||
|
|
||||||
|
const getTypeLexic = (typeLexic: number) => { |
||||||
|
switch (typeLexic) { |
||||||
|
case ProfileTypes.TOURNAMENTS: |
||||||
|
return 'tournament' |
||||||
|
case ProfileTypes.TEAMS: |
||||||
|
return 'team' |
||||||
|
case ProfileTypes.PLAYERS: |
||||||
|
return 'player' |
||||||
|
default: |
||||||
|
return '' |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const groupedFavorites = map( |
||||||
|
groupBy(userFavorites, 'type'), |
||||||
|
(item) => ({ items: item, typeLexic: getTypeLexic(item[0].type) }), |
||||||
|
) |
||||||
|
|
||||||
|
return { groupedFavorites } |
||||||
|
} |
||||||
@ -0,0 +1,71 @@ |
|||||||
|
import { Fragment } from 'react' |
||||||
|
|
||||||
|
import map from 'lodash/map' |
||||||
|
|
||||||
|
import { useToggle } from 'hooks' |
||||||
|
import { Icon, MenuItem } from 'features/Menu/styled' |
||||||
|
|
||||||
|
import { GroupBlock } from './components/GroupBlock' |
||||||
|
import { useFavoritesMobilePopup } from './hooks' |
||||||
|
import { |
||||||
|
FavoritesPopup, |
||||||
|
Wrapper, |
||||||
|
EmptyDiv, |
||||||
|
HomeIcon, |
||||||
|
HeaderWrapper, |
||||||
|
GroupWrapper, |
||||||
|
MainLogo, |
||||||
|
} from './styled' |
||||||
|
|
||||||
|
export const FavoritesMobilePopup = () => { |
||||||
|
const { groupedFavorites } = useFavoritesMobilePopup() |
||||||
|
const { |
||||||
|
close, |
||||||
|
isOpen, |
||||||
|
open, |
||||||
|
} = useToggle() |
||||||
|
|
||||||
|
return ( |
||||||
|
<Fragment> |
||||||
|
{ |
||||||
|
isOpen |
||||||
|
? ( |
||||||
|
<FavoritesPopup> |
||||||
|
<Wrapper> |
||||||
|
|
||||||
|
<HeaderWrapper> |
||||||
|
<EmptyDiv /> |
||||||
|
<MainLogo width={4} height={0.95} /> |
||||||
|
<HomeIcon |
||||||
|
src='homeFavorites' |
||||||
|
size='1rem' |
||||||
|
onClick={close} |
||||||
|
/> |
||||||
|
</HeaderWrapper> |
||||||
|
|
||||||
|
<GroupWrapper> |
||||||
|
{map(groupedFavorites, (group) => ( |
||||||
|
<GroupBlock |
||||||
|
key={group.typeLexic} |
||||||
|
groupBlock={group} |
||||||
|
/> |
||||||
|
))} |
||||||
|
</GroupWrapper> |
||||||
|
|
||||||
|
</Wrapper> |
||||||
|
</FavoritesPopup> |
||||||
|
) |
||||||
|
: ( |
||||||
|
<MenuItem> |
||||||
|
<Icon |
||||||
|
src='starEmpty' |
||||||
|
size='1.4rem' |
||||||
|
onClick={open} |
||||||
|
/> |
||||||
|
</MenuItem> |
||||||
|
) |
||||||
|
|
||||||
|
} |
||||||
|
</Fragment> |
||||||
|
) |
||||||
|
} |
||||||
@ -0,0 +1,60 @@ |
|||||||
|
import styled from 'styled-components/macro' |
||||||
|
|
||||||
|
import { devices } from 'config' |
||||||
|
import { Logo } from 'features/Logo' |
||||||
|
import { ModalContainer } from 'features/Modal/styled' |
||||||
|
import { Icon } from 'features/Menu/styled' |
||||||
|
|
||||||
|
export const FavoritesPopup = styled(ModalContainer)` |
||||||
|
background-color: black; |
||||||
|
background-image: url(/images/Checker.png); |
||||||
|
background-size: 12px; |
||||||
|
` |
||||||
|
|
||||||
|
export const MainLogo = styled(Logo)` |
||||||
|
@media ${devices.mobile} { |
||||||
|
width: 100px; |
||||||
|
height: 25px; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const Wrapper = styled.div` |
||||||
|
padding: 2rem 3rem; |
||||||
|
width: 100%; |
||||||
|
height: 100%; |
||||||
|
background: radial-gradient( |
||||||
|
49.07% 49.07% at 50% 29.54%, |
||||||
|
rgba(255, 255, 255, 0.14) 0%, |
||||||
|
rgba(255, 255, 255, 0) 100% |
||||||
|
), rgba(0, 0, 0, 0.9); |
||||||
|
` |
||||||
|
|
||||||
|
export const HomeIcon = styled(Icon)` |
||||||
|
opacity: 1; |
||||||
|
|
||||||
|
&:only-child { |
||||||
|
margin: 0; |
||||||
|
} |
||||||
|
|
||||||
|
@media ${devices.mobile} { |
||||||
|
width: 3.5rem; |
||||||
|
height: 3.5rem; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const HeaderWrapper = styled.div` |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
` |
||||||
|
|
||||||
|
export const GroupWrapper = styled.div` |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
|
||||||
|
@media ${devices.mobile} { |
||||||
|
flex-wrap: wrap; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const EmptyDiv = styled.div`` |
||||||
Loading…
Reference in new issue