parent
873718947f
commit
291d44c858
|
After Width: | Height: | Size: 329 B |
|
After Width: | Height: | Size: 314 B |
|
After Width: | Height: | Size: 609 B |
|
After Width: | Height: | Size: 590 B |
|
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,101 @@ |
|||||||
|
import { useMemo, useState } from 'react' |
||||||
|
|
||||||
|
import includes from 'lodash/includes' |
||||||
|
import filter from 'lodash/filter' |
||||||
|
import isEmpty from 'lodash/isEmpty' |
||||||
|
import size from 'lodash/size' |
||||||
|
|
||||||
|
type TTogglePlayers = { |
||||||
|
id: Number, |
||||||
|
team: String, |
||||||
|
} |
||||||
|
|
||||||
|
type TFilters = { |
||||||
|
events: Array<Number>, |
||||||
|
players: Array<Number>, |
||||||
|
} |
||||||
|
|
||||||
|
export const useFiltersPopup = () => { |
||||||
|
const [isOpen, setIsOpen] = useState(false) |
||||||
|
const [activeEvents, setActiveEvents] = useState<Array<Number>>([]) |
||||||
|
const [activeFirstTeamPlayers, setActiveFirstTeamPlayers] = useState<Array<Number>>([]) |
||||||
|
const [activeSecondTeamPlayers, setActiveSecondTeamPlayers] = useState<Array<Number>>([]) |
||||||
|
const [activeFilters, setActiveFilters] = useState<TFilters>({ events: [], players: [] }) |
||||||
|
|
||||||
|
const toggle = () => { |
||||||
|
setIsOpen(!isOpen) |
||||||
|
} |
||||||
|
|
||||||
|
const close = () => { |
||||||
|
setIsOpen(false) |
||||||
|
} |
||||||
|
|
||||||
|
const toggleActiveEvents = (id: number) => () => { |
||||||
|
setActiveEvents(includes(activeEvents, id) |
||||||
|
? [...filter(activeEvents, (item) => item !== id)] |
||||||
|
: [...activeEvents, id]) |
||||||
|
} |
||||||
|
|
||||||
|
const toggleActivePlayers = ({ id, team }: TTogglePlayers) => () => { |
||||||
|
const teamState = team === 'team1' |
||||||
|
? activeFirstTeamPlayers |
||||||
|
: activeSecondTeamPlayers |
||||||
|
|
||||||
|
const setterTeamState = team === 'team1' |
||||||
|
? setActiveFirstTeamPlayers |
||||||
|
: setActiveSecondTeamPlayers |
||||||
|
|
||||||
|
setterTeamState(includes(teamState, id) |
||||||
|
? [...filter(teamState, (item) => item !== id)] |
||||||
|
: [...teamState, id]) |
||||||
|
} |
||||||
|
|
||||||
|
const resetPlayers = (team: string) => () => { |
||||||
|
const teamState = team === 'team1' |
||||||
|
? activeFirstTeamPlayers |
||||||
|
: activeSecondTeamPlayers |
||||||
|
|
||||||
|
const setterTeamState = team === 'team1' |
||||||
|
? setActiveFirstTeamPlayers |
||||||
|
: setActiveSecondTeamPlayers |
||||||
|
|
||||||
|
if (isEmpty(teamState)) return |
||||||
|
setterTeamState([]) |
||||||
|
} |
||||||
|
|
||||||
|
const resetEvents = () => { |
||||||
|
if (isEmpty(activeEvents)) return |
||||||
|
setActiveEvents([]) |
||||||
|
} |
||||||
|
|
||||||
|
const applyFilters = () => { |
||||||
|
setActiveFilters({ |
||||||
|
events: [...activeEvents], |
||||||
|
players: [...activeFirstTeamPlayers, ...activeSecondTeamPlayers], |
||||||
|
}) |
||||||
|
close() |
||||||
|
} |
||||||
|
|
||||||
|
const isEmptyFilters = useMemo(() => ( |
||||||
|
isEmpty(activeFilters.events) && isEmpty(activeFilters.players)), [activeFilters]) |
||||||
|
|
||||||
|
const countOfFilters = useMemo(() => ( |
||||||
|
size(activeFilters.events) + size(activeFilters.players)), [activeFilters]) |
||||||
|
|
||||||
|
return { |
||||||
|
activeEvents, |
||||||
|
activeFirstTeamPlayers, |
||||||
|
activeSecondTeamPlayers, |
||||||
|
applyFilters, |
||||||
|
close, |
||||||
|
countOfFilters, |
||||||
|
filters: activeFilters, |
||||||
|
isEmptyFilters, |
||||||
|
isOpen, |
||||||
|
resetEvents, |
||||||
|
resetPlayers, |
||||||
|
toggle, |
||||||
|
toggleActiveEvents, |
||||||
|
toggleActivePlayers, |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,80 @@ |
|||||||
|
import { |
||||||
|
useCallback, |
||||||
|
useMemo, |
||||||
|
useState, |
||||||
|
} from 'react' |
||||||
|
|
||||||
|
import map from 'lodash/map' |
||||||
|
import groupBy from 'lodash/groupBy' |
||||||
|
import reverse from 'lodash/reverse' |
||||||
|
import filter from 'lodash/filter' |
||||||
|
import values from 'lodash/values' |
||||||
|
import flatten from 'lodash/flatten' |
||||||
|
import { Events, MatchInfo } from 'requests' |
||||||
|
import { useToggle } from 'hooks' |
||||||
|
import { EventPlaylistOption } from 'features/MatchPage/types' |
||||||
|
|
||||||
|
type TPropsTabEvents = { |
||||||
|
events?: Events, |
||||||
|
profile?: MatchInfo, |
||||||
|
} |
||||||
|
|
||||||
|
export const useTabEvents = ({ |
||||||
|
events, |
||||||
|
profile, |
||||||
|
}: TPropsTabEvents) => { |
||||||
|
const [likesOnly, setLikesOnly] = useState(false) |
||||||
|
|
||||||
|
const { |
||||||
|
close: setUnreversed, |
||||||
|
isOpen: areEventsReversed, |
||||||
|
open: setReversed, |
||||||
|
} = useToggle() |
||||||
|
|
||||||
|
const likeToggle = useCallback(() => setLikesOnly((state) => !state), []) |
||||||
|
const likeImage = likesOnly ? '/images/like-active-icon.svg' : '/images/likeDisable.svg' |
||||||
|
|
||||||
|
const isLiveMatch = profile?.live |
||||||
|
const reverseStatus = (areEventsReversed || isLiveMatch) && (areEventsReversed !== isLiveMatch) |
||||||
|
const activeStatus = isLiveMatch ? areEventsReversed : !areEventsReversed |
||||||
|
|
||||||
|
const reversedGroupEvents = useMemo(() => { |
||||||
|
const eventsList = likesOnly ? filter(events, 'like') : events |
||||||
|
const groupedEvents = values( |
||||||
|
groupBy( |
||||||
|
reverseStatus |
||||||
|
? reverse([...eventsList!]) |
||||||
|
: eventsList, |
||||||
|
({ h }) => h, |
||||||
|
), |
||||||
|
) |
||||||
|
return reverseStatus |
||||||
|
? reverse(groupedEvents) |
||||||
|
: groupedEvents |
||||||
|
}, [ |
||||||
|
events, |
||||||
|
likesOnly, |
||||||
|
reverseStatus, |
||||||
|
]) |
||||||
|
|
||||||
|
const episodesToPlay = map(flatten(reversedGroupEvents), ((event) => ({ |
||||||
|
episodes: [{ |
||||||
|
e: event.e, |
||||||
|
h: event.h, |
||||||
|
s: event.s, |
||||||
|
}], |
||||||
|
id: event.n, |
||||||
|
type: 3, |
||||||
|
}))) as Array<EventPlaylistOption> |
||||||
|
|
||||||
|
return { |
||||||
|
activeStatus, |
||||||
|
episodesToPlay, |
||||||
|
isLiveMatch, |
||||||
|
likeImage, |
||||||
|
likeToggle, |
||||||
|
reversedGroupEvents, |
||||||
|
setReversed, |
||||||
|
setUnreversed, |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,145 @@ |
|||||||
|
import uniq from 'lodash/uniq' |
||||||
|
import map from 'lodash/map' |
||||||
|
import isEmpty from 'lodash/isEmpty' |
||||||
|
import includes from 'lodash/includes' |
||||||
|
import filter from 'lodash/filter' |
||||||
|
|
||||||
|
import { T9n } from 'features/T9n' |
||||||
|
import { useMatchPageStore } from 'features/MatchPage/store' |
||||||
|
import { PlayerPlaylistOption } from 'features/MatchPage/types' |
||||||
|
import { CloseButton } from 'features/PopupComponents' |
||||||
|
import { Name, useName } from 'features/Name' |
||||||
|
|
||||||
|
import { |
||||||
|
Checkbox, |
||||||
|
CloseButtonContainer, |
||||||
|
PartBlock, |
||||||
|
HeaderText, |
||||||
|
ItemBlock, |
||||||
|
ItemsContainer, |
||||||
|
ItemText, |
||||||
|
MainCheckboxContainer, |
||||||
|
PopupContainer, |
||||||
|
PopupHeader, |
||||||
|
Button, |
||||||
|
ButtonConatiner, |
||||||
|
PlayerNumber, |
||||||
|
} from './styled' |
||||||
|
|
||||||
|
type TLabelProps = { |
||||||
|
player: PlayerPlaylistOption, |
||||||
|
} |
||||||
|
|
||||||
|
const Label = ({ player }: TLabelProps) => { |
||||||
|
const { num } = player |
||||||
|
return ( |
||||||
|
<ItemText> |
||||||
|
<PlayerNumber> |
||||||
|
{num} |
||||||
|
</PlayerNumber> |
||||||
|
<Name nameObj={player} /> |
||||||
|
</ItemText> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
export const FiltersPopup = () => { |
||||||
|
const { |
||||||
|
activeEvents, |
||||||
|
activeFirstTeamPlayers, |
||||||
|
activeSecondTeamPlayers, |
||||||
|
applyFilters, |
||||||
|
closePopup, |
||||||
|
events, |
||||||
|
matchPlaylists, |
||||||
|
profile, |
||||||
|
resetEvents, |
||||||
|
resetPlayers, |
||||||
|
toggleActiveEvents, |
||||||
|
toggleActivePlayers, |
||||||
|
} = useMatchPageStore() |
||||||
|
const currentEvents = filter(events, (event) => event.pl !== undefined |
||||||
|
&& event.t !== undefined) |
||||||
|
|
||||||
|
const uniqEvents = uniq(map(currentEvents, ({ l }) => l)) |
||||||
|
|
||||||
|
const team1Name = useName(profile!.team1) |
||||||
|
const team2Name = useName(profile!.team2) |
||||||
|
|
||||||
|
return ( |
||||||
|
<PopupContainer> |
||||||
|
<CloseButtonContainer> |
||||||
|
<CloseButton onClick={closePopup} /> |
||||||
|
</CloseButtonContainer> |
||||||
|
<PopupHeader> |
||||||
|
<HeaderText> |
||||||
|
<T9n t='filter' /> |
||||||
|
</HeaderText> |
||||||
|
</PopupHeader> |
||||||
|
<PartBlock> |
||||||
|
<MainCheckboxContainer> |
||||||
|
<Checkbox |
||||||
|
onChange={resetEvents} |
||||||
|
checked={isEmpty(activeEvents)} |
||||||
|
labelLexic='all_actions' |
||||||
|
/> |
||||||
|
</MainCheckboxContainer> |
||||||
|
<ItemsContainer> |
||||||
|
{map(uniqEvents, ((event) => ( |
||||||
|
<ItemBlock key={event}> |
||||||
|
<Checkbox |
||||||
|
checked={includes(activeEvents, event)} |
||||||
|
onChange={toggleActiveEvents(event)} |
||||||
|
labelLexic={event} |
||||||
|
/> |
||||||
|
</ItemBlock> |
||||||
|
)))} |
||||||
|
</ItemsContainer> |
||||||
|
</PartBlock> |
||||||
|
<PartBlock> |
||||||
|
<MainCheckboxContainer> |
||||||
|
<Checkbox |
||||||
|
checked={isEmpty(activeFirstTeamPlayers)} |
||||||
|
label={team1Name} |
||||||
|
onChange={resetPlayers('team1')} |
||||||
|
/> |
||||||
|
</MainCheckboxContainer> |
||||||
|
<ItemsContainer> |
||||||
|
{map(matchPlaylists.players.team1, ((player) => ( |
||||||
|
<ItemBlock key={player.id}> |
||||||
|
<Checkbox |
||||||
|
onChange={toggleActivePlayers({ id: player.id, team: 'team1' })} |
||||||
|
checked={includes(activeFirstTeamPlayers, player.id)} |
||||||
|
label={(<Label player={player} />)} |
||||||
|
/> |
||||||
|
</ItemBlock> |
||||||
|
)))} |
||||||
|
</ItemsContainer> |
||||||
|
</PartBlock> |
||||||
|
<PartBlock> |
||||||
|
<MainCheckboxContainer> |
||||||
|
<Checkbox |
||||||
|
checked={isEmpty(activeSecondTeamPlayers)} |
||||||
|
label={team2Name} |
||||||
|
onChange={resetPlayers('team2')} |
||||||
|
/> |
||||||
|
</MainCheckboxContainer> |
||||||
|
<ItemsContainer> |
||||||
|
{map(matchPlaylists.players.team2, ((player) => ( |
||||||
|
<ItemBlock key={player.id}> |
||||||
|
<Checkbox |
||||||
|
onChange={toggleActivePlayers({ id: player.id, team: 'team2' })} |
||||||
|
checked={includes(activeSecondTeamPlayers, player.id)} |
||||||
|
label={(<Label player={player} />)} |
||||||
|
/> |
||||||
|
</ItemBlock> |
||||||
|
)))} |
||||||
|
</ItemsContainer> |
||||||
|
</PartBlock> |
||||||
|
<ButtonConatiner> |
||||||
|
<Button onClick={applyFilters}> |
||||||
|
<T9n t='apply_filter' /> |
||||||
|
</Button> |
||||||
|
</ButtonConatiner> |
||||||
|
</PopupContainer> |
||||||
|
) |
||||||
|
} |
||||||
@ -0,0 +1,199 @@ |
|||||||
|
import styled, { css } from 'styled-components/macro' |
||||||
|
|
||||||
|
import { Checkbox as BaseCheckbox } from 'features/Common/Checkbox' |
||||||
|
import { Label } from 'features/Common/Checkbox/styled' |
||||||
|
import { CheckboxSvg } from 'features/Common/Checkbox/Icon' |
||||||
|
import { customScrollbar } from 'features/Common' |
||||||
|
import { NameStyled } from 'features/Name' |
||||||
|
import { isMobileDevice } from 'config/userAgent' |
||||||
|
import { BaseButton } from 'features/PopupComponents' |
||||||
|
|
||||||
|
export const PopupContainer = styled.div` |
||||||
|
background: #333333; |
||||||
|
box-shadow: 0px 2px 40px rgba(0, 0, 0, 0.6); |
||||||
|
border-radius: 2px; |
||||||
|
display: flex; |
||||||
|
flex-direction: column; |
||||||
|
position: absolute; |
||||||
|
overflow-y: auto; |
||||||
|
z-index: 1000; |
||||||
|
height: 100%; |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
|
||||||
|
${customScrollbar} |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
position: fixed; |
||||||
|
height: calc(100vh - 40px); |
||||||
|
width: 100%; |
||||||
|
padding-bottom: 70px; |
||||||
|
top: 40px;` |
||||||
|
: css` |
||||||
|
width: 651px;`}
|
||||||
|
` |
||||||
|
|
||||||
|
export const PopupHeader = styled.div` |
||||||
|
flex: 0 0 auto; |
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
height: auto; |
||||||
|
padding: 12px 0px 0px 0px; |
||||||
|
margin-bottom: 14px;` |
||||||
|
: css` |
||||||
|
height: 50px; |
||||||
|
padding: 17px 22px 0px 22px;`}
|
||||||
|
` |
||||||
|
|
||||||
|
export const CloseButtonContainer = styled.div` |
||||||
|
position: absolute; |
||||||
|
top: 14px; |
||||||
|
right: 12px; |
||||||
|
|
||||||
|
${BaseButton} { |
||||||
|
top: -4px; |
||||||
|
right:0 ; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const HeaderText = styled.div` |
||||||
|
font-family: 'Montserrat'; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 700; |
||||||
|
text-transform: uppercase; |
||||||
|
|
||||||
|
color: #FFFFFF; |
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
font-size: 12px; |
||||||
|
line-height: 15px; |
||||||
|
text-align: center;` |
||||||
|
: css` |
||||||
|
font-size: 18px; |
||||||
|
line-height: 22px; |
||||||
|
margin-bottom: 21px;`}
|
||||||
|
` |
||||||
|
|
||||||
|
export const PartBlock = styled.div` |
||||||
|
flex: 1 0 auto; |
||||||
|
border-bottom: 1px solid #505050; |
||||||
|
padding: 17px 22px 17px 22px; |
||||||
|
` |
||||||
|
|
||||||
|
export const ItemsContainer = styled.ul` |
||||||
|
display: flex; |
||||||
|
flex-direction: row; |
||||||
|
flex-wrap: wrap; |
||||||
|
` |
||||||
|
|
||||||
|
export const MainCheckboxContainer = styled.div` |
||||||
|
margin-bottom: 15px; |
||||||
|
display: flex; |
||||||
|
` |
||||||
|
|
||||||
|
export const ItemBlock = styled.div` |
||||||
|
flex: 0 0 33.33%; |
||||||
|
margin-bottom: 4px; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
flex: 0 0 50%;` |
||||||
|
: css` |
||||||
|
flex: 0 0 33.33%;`}
|
||||||
|
` |
||||||
|
|
||||||
|
export const Checkbox = styled(BaseCheckbox)` |
||||||
|
height: 28px; |
||||||
|
display: block; |
||||||
|
|
||||||
|
${Label} { |
||||||
|
height: 100%; |
||||||
|
font-style: normal; |
||||||
|
font-weight: 400; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
font-size: 12px; |
||||||
|
line-height: 18px;` |
||||||
|
: css` |
||||||
|
font-size: 14px; |
||||||
|
line-height: 16px;`}
|
||||||
|
|
||||||
|
${({ checked }) => (checked |
||||||
|
? css`` |
||||||
|
: css` |
||||||
|
color: rgba(255, 255, 255, 0.6);` |
||||||
|
)} |
||||||
|
} |
||||||
|
|
||||||
|
${CheckboxSvg} { |
||||||
|
margin-right: 8px; |
||||||
|
width: 20px; |
||||||
|
height: 20px; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const ItemText = styled.div` |
||||||
|
display: flex; |
||||||
|
height: 100%; |
||||||
|
align-items: center; |
||||||
|
|
||||||
|
${NameStyled} { |
||||||
|
white-space: nowrap; |
||||||
|
overflow: hidden; |
||||||
|
text-overflow: ellipsis; |
||||||
|
width: 130px; |
||||||
|
} |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
width: 110px;` |
||||||
|
: css` |
||||||
|
width: 130px;`}
|
||||||
|
` |
||||||
|
|
||||||
|
export const TeamBlock = styled.div`` |
||||||
|
|
||||||
|
export const ButtonConatiner = styled.div` |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
flex: 0 0 66px; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
position: fixed; |
||||||
|
bottom: 14px; |
||||||
|
left: 50%; |
||||||
|
transform: translate(-50%, 0);` |
||||||
|
: css``} |
||||||
|
` |
||||||
|
|
||||||
|
export const Button = styled.button` |
||||||
|
height: 41px; |
||||||
|
background: #294FC4; |
||||||
|
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3); |
||||||
|
border-radius: 5px; |
||||||
|
border: none; |
||||||
|
cursor: pointer; |
||||||
|
font-size: 15px; |
||||||
|
line-height: 50px; |
||||||
|
font-weight: 600; |
||||||
|
display: flex; |
||||||
|
align-items: center; |
||||||
|
justify-content: center; |
||||||
|
color: #ffff; |
||||||
|
|
||||||
|
${isMobileDevice |
||||||
|
? css` |
||||||
|
width: 301px;` |
||||||
|
: css` |
||||||
|
width: 167px;`}
|
||||||
|
` |
||||||
|
export const PlayerNumber = styled.span` |
||||||
|
margin-right: 8px; |
||||||
|
font-size: 11px; |
||||||
|
line-height: 16px; |
||||||
|
font-weight: 600; |
||||||
|
` |
||||||
Loading…
Reference in new issue