feat(in-142): match stats tab

pull/11/head
Ruslan Khayrullin 3 years ago
parent 376aedaea2
commit ee3b93c622
  1. 5
      src/config/lexics/indexLexics.tsx
  2. 4
      src/features/MatchPage/store/hooks/index.tsx
  3. 6
      src/features/MatchPage/store/hooks/useMatchData.tsx
  4. 58
      src/features/MatchPage/store/hooks/useTeamsStats.tsx
  5. 5
      src/features/MatchSidePlaylists/components/PlayersPlaylists/index.tsx
  6. 5
      src/features/MatchSidePlaylists/components/PlayersPlaylists/styled.tsx
  7. 1
      src/features/MatchSidePlaylists/components/PlayersTable/config.tsx
  8. 61
      src/features/MatchSidePlaylists/components/PlayersTable/hooks.tsx
  9. 1557
      src/features/MatchSidePlaylists/components/PlayersTable/index.tsx
  10. 77
      src/features/MatchSidePlaylists/components/PlayersTable/styled.tsx
  11. 5
      src/features/MatchSidePlaylists/components/TabStats/config.tsx
  12. 32
      src/features/MatchSidePlaylists/components/TabStats/hooks.tsx
  13. 57
      src/features/MatchSidePlaylists/components/TabStats/index.tsx
  14. 39
      src/features/MatchSidePlaylists/components/TabStats/styled.tsx
  15. 6
      src/features/MatchSidePlaylists/components/TeamsStats/styled.tsx
  16. 35
      src/features/MatchSidePlaylists/hooks.tsx
  17. 16
      src/features/MatchSidePlaylists/index.tsx
  18. 18
      src/features/MatchSidePlaylists/styled.tsx
  19. 1
      src/hooks/usePageParams.tsx
  20. 56
      src/requests/getTeamsStats.tsx
  21. 1
      src/requests/index.tsx

@ -9,8 +9,12 @@ const matchPopupLexics = {
apply: 13491, apply: 13491,
choose_fav_team: 19776, choose_fav_team: 19776,
commentators: 15424, commentators: 15424,
current_stats: 19592,
display_all_stats: 19932,
display_stats_according_to_video: 19931,
episode_duration: 13410, episode_duration: 13410,
events: 1020, events: 1020,
final_stats: 19591,
from_end_match: 15396, from_end_match: 15396,
from_price: 3992, from_price: 3992,
from_start_match: 15395, from_start_match: 15395,
@ -160,6 +164,7 @@ export const indexLexics = {
no_match_access_body: 13419, no_match_access_body: 13419,
no_match_access_title: 13418, no_match_access_title: 13418,
player: 14975, player: 14975,
players: 164,
players_video: 13032, players_video: 13032,
privacy_policy_and_statement: 15404, privacy_policy_and_statement: 15404,
round_highilights: 13050, round_highilights: 13050,

@ -65,10 +65,12 @@ export const useMatchPage = () => {
const { const {
events, events,
fetchTeamsStats,
handlePlaylistClick, handlePlaylistClick,
matchPlaylists, matchPlaylists,
selectedPlaylist, selectedPlaylist,
setFullMatchPlaylistDuration, setFullMatchPlaylistDuration,
teamsStats,
} = useMatchData(matchProfile) } = useMatchData(matchProfile)
const profile = matchProfile const profile = matchProfile
@ -156,6 +158,7 @@ export const useMatchPage = () => {
countOfFilters, countOfFilters,
disablePlayingEpisodes, disablePlayingEpisodes,
events, events,
fetchTeamsStats,
filteredEvents, filteredEvents,
handlePlaylistClick, handlePlaylistClick,
hideProfileCard, hideProfileCard,
@ -183,6 +186,7 @@ export const useMatchPage = () => {
setUnreversed, setUnreversed,
setWatchAllEpisodesTimer, setWatchAllEpisodesTimer,
showProfileCard, showProfileCard,
teamsStats,
toggleActiveEvents, toggleActiveEvents,
toggleActivePlayers, toggleActivePlayers,
togglePopup, togglePopup,

@ -6,7 +6,7 @@ import {
import debounce from 'lodash/debounce' import debounce from 'lodash/debounce'
import { MatchInfo } from 'requests/getMatchInfo' import type { MatchInfo } from 'requests/getMatchInfo'
import { usePageParams } from 'hooks/usePageParams' import { usePageParams } from 'hooks/usePageParams'
import { useInterval } from 'hooks/useInterval' import { useInterval } from 'hooks/useInterval'
@ -16,6 +16,7 @@ import { useMatchPopupStore } from 'features/MatchPopup'
import { useMatchPlaylists } from './useMatchPlaylists' import { useMatchPlaylists } from './useMatchPlaylists'
import { useEvents } from './useEvents' import { useEvents } from './useEvents'
import { useTeamsStats } from './useTeamsStats'
const MATCH_DATA_POLL_INTERVAL = 60000 const MATCH_DATA_POLL_INTERVAL = 60000
const MATCH_PLAYLISTS_DELAY = 5000 const MATCH_PLAYLISTS_DELAY = 5000
@ -33,6 +34,7 @@ export const useMatchData = (profile: MatchInfo) => {
setSelectedPlaylist, setSelectedPlaylist,
} = useMatchPlaylists(profile) } = useMatchPlaylists(profile)
const { events, fetchMatchEvents } = useEvents() const { events, fetchMatchEvents } = useEvents()
const { fetchTeamsStats, teamsStats } = useTeamsStats(profile)
const fetchPlaylistsDebounced = useMemo( const fetchPlaylistsDebounced = useMemo(
() => debounce(fetchMatchPlaylists, MATCH_PLAYLISTS_DELAY), () => debounce(fetchMatchPlaylists, MATCH_PLAYLISTS_DELAY),
@ -92,9 +94,11 @@ export const useMatchData = (profile: MatchInfo) => {
return { return {
events, events,
fetchTeamsStats,
handlePlaylistClick, handlePlaylistClick,
matchPlaylists, matchPlaylists,
selectedPlaylist, selectedPlaylist,
setFullMatchPlaylistDuration, setFullMatchPlaylistDuration,
teamsStats,
} }
} }

@ -0,0 +1,58 @@
import {
useEffect,
useState,
useMemo,
useCallback,
} from 'react'
import flatMap from 'lodash/flatMap'
import reduce from 'lodash/reduce'
import includes from 'lodash/includes'
import type { MatchInfo } from 'requests'
import { getTeamsStats, TeamStatItem } from 'requests'
import { usePageParams } from 'hooks/usePageParams'
import { useLexicsConfig } from 'features/LexicsStore'
export const useTeamsStats = (matchProfile: MatchInfo) => {
const [teamsStats, setTeamsStats] = useState<{
[teamId: string]: Array<TeamStatItem>,
}>({})
const { profileId: matchId, sportName } = usePageParams()
const lexics = useMemo(() => reduce<TeamStatItem, Array<number>>(
flatMap(teamsStats),
(acc, curr) => {
if (curr.param1?.lexic && !includes(acc, curr.param1.lexic)) {
acc.push(curr.param1.lexic)
}
return acc
},
[],
), [teamsStats])
useLexicsConfig(lexics)
const fetchTeamsStats = useCallback((second?: number) => {
if (!sportName) return
getTeamsStats({
matchId,
second,
sportName,
}).then(setTeamsStats)
}, [matchId, sportName])
useEffect(() => {
fetchTeamsStats()
}, [fetchTeamsStats])
return {
fetchTeamsStats,
teamsStats,
}
}

@ -15,12 +15,10 @@ import type {
} from 'features/MatchPage/types' } from 'features/MatchPage/types'
import { Name } from 'features/Name' import { Name } from 'features/Name'
import { T9n } from 'features/T9n'
import { isEqual } from '../../helpers' import { isEqual } from '../../helpers'
import { PlayButton } from '../PlayButton' import { PlayButton } from '../PlayButton'
import { BlockTitle } from '../../styled'
import { import {
Wrapper, Wrapper,
List, List,
@ -58,9 +56,6 @@ export const PlayersPlaylists = ({
return ( return (
<Wrapper> <Wrapper>
<BlockTitle>
<T9n t='players_episodes' />
</BlockTitle>
<Tabs> <Tabs>
<Tab <Tab
active={selectedTeam === Teams.TEAM1} active={selectedTeam === Teams.TEAM1}

@ -28,9 +28,7 @@ export const PlayerAvatar = styled(ProfileLogo)`
` `
export const Tabs = styled.div` export const Tabs = styled.div`
display: flex; margin-bottom: 23px;
margin-top: 4px;
margin-bottom: 8px;
` `
type TabProps = { type TabProps = {
@ -40,7 +38,6 @@ type TabProps = {
export const Tab = styled.button<TabProps>` export const Tab = styled.button<TabProps>`
position: relative; position: relative;
border: none; border: none;
height: 34px;
padding: 0; padding: 0;
background-color: transparent; background-color: transparent;
font-size: 12px; font-size: 12px;

@ -0,0 +1,61 @@
import type { SyntheticEvent } from 'react'
import {
useRef,
useState,
useEffect,
} from 'react'
import { isMobileDevice } from 'config/userAgent'
import { CELL_WIDTH } from './config'
export const usePlayersTable = () => {
const containerRef = useRef<HTMLDivElement>(null)
const tableWrapperRef = useRef<HTMLDivElement>(null)
const [showLeftArrow, setShowLeftArrow] = useState(false)
const [showRightArrow, setShowRightArrow] = useState(false)
const cellWidth = isMobileDevice
? ((containerRef.current?.clientWidth || 0) - 98) / 4
: CELL_WIDTH
const slideLeft = () => tableWrapperRef.current!.scrollBy(-cellWidth, 0)
const slideRight = () => tableWrapperRef.current!.scrollBy(cellWidth, 0)
const handleScroll = (e: SyntheticEvent<HTMLDivElement>) => {
const {
clientWidth,
scrollLeft,
scrollWidth,
} = e.currentTarget
const scrollRight = scrollWidth - (scrollLeft + clientWidth)
setShowLeftArrow(scrollLeft > 1)
setShowRightArrow(scrollRight > 1)
}
useEffect(() => {
const {
clientWidth = 0,
scrollLeft = 0,
scrollWidth = 0,
} = tableWrapperRef.current || {}
const scrollRight = scrollWidth - (scrollLeft + clientWidth)
setShowRightArrow(scrollRight > 1)
}, [])
return {
cellWidth,
containerRef,
handleScroll,
showLeftArrow,
showRightArrow,
slideLeft,
slideRight,
tableWrapperRef,
}
}

@ -1,16 +1,33 @@
import styled, { css } from 'styled-components/macro' import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent'
import { customScrollbar } from 'features/Common' import { customScrollbar } from 'features/Common'
import {
ArrowButton as ArrowButtonBase,
Arrow as ArrowBase,
} from 'features/HeaderFilters/components/DateFilter/styled'
import { CELL_WIDTH } from './config'
export const Container = styled.div`
position: relative;
`
export const TableWrapper = styled.div`
max-height: calc(100vh - 235px);
border-radius: 5px;
overflow-x: auto;
scroll-behavior: smooth;
${customScrollbar}
`
export const Table = styled.table` export const Table = styled.table`
width: 100%; width: 100%;
border-radius: 5px; border-radius: 5px;
border-collapse: collapse; border-collapse: collapse;
letter-spacing: -0.078px; letter-spacing: -0.078px;
background-color: #333333;
table-layout: fixed; table-layout: fixed;
${customScrollbar}
` `
export const Thead = styled.thead` export const Thead = styled.thead`
@ -20,21 +37,33 @@ export const Thead = styled.thead`
type ThProps = { type ThProps = {
sorted?: boolean, sorted?: boolean,
width?: number,
} }
export const Th = styled.th<ThProps>` export const Th = styled.th.attrs({ tabIndex: 0 })<ThProps>`
position: sticky;
left: 0;
top: 0;
width: ${({ width }) => width || CELL_WIDTH}px;
font-size: 11px; font-size: 11px;
color: ${({ theme }) => theme.colors.white}; color: ${({ theme }) => theme.colors.white};
text-transform: uppercase; text-transform: uppercase;
cursor: pointer;
background-color: #333333;
z-index: 2;
:first-child { :first-child {
width: 115px; width: 90px;
z-index: 3;
cursor: default;
} }
${({ sorted }) => (sorted ${({ sorted }) => (sorted
? '' ? ''
: css` : css`
${ParamShortTitle} {
opacity: 0.5; opacity: 0.5;
}
`)} `)}
` `
@ -56,18 +85,26 @@ type TdProps = {
sorted?: boolean, sorted?: boolean,
} }
export const Td = styled.td<TdProps>` export const Td = styled.td.attrs(({ clickable }: TdProps) => ({
...clickable && { tabIndex: 0 },
}))<TdProps>`
font-size: 11px; font-size: 11px;
text-align: center; text-align: center;
color: ${({ clickable, theme }) => (clickable ? '#5EB2FF' : theme.colors.white)}; color: ${({ clickable, theme }) => (clickable ? '#5EB2FF' : theme.colors.white)};
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
background-color: #333333;
:first-child { :first-child {
position: sticky;
left: 0;
z-index: 1;
padding-left: 13px; padding-left: 13px;
text-align: left; text-align: left;
color: ${({ theme }) => theme.colors.white}; color: ${({ theme }) => theme.colors.white};
} }
${({ sorted }) => (sorted ${({ sorted }) => (sorted
? css` ? css`
font-weight: bold; font-weight: bold;
@ -84,3 +121,29 @@ export const Td = styled.td<TdProps>`
export const PlayerNum = styled.span` export const PlayerNum = styled.span`
color: rgba(255, 255, 255, 0.5); color: rgba(255, 255, 255, 0.5);
` `
const ArrowButton = styled(ArrowButtonBase)`
position: absolute;
margin-top: 2px;
z-index: 4;
${isMobileDevice
? css`
height: 45px;
margin-top: 0;
`
: ''};
`
export const ArrowButtonRight = styled(ArrowButton)`
right: 0;
`
export const ArrowButtonLeft = styled(ArrowButton)`
left: 75px;
`
export const Arrow = styled(ArrowBase)`
width: 10px;
height: 10px;
`

@ -3,3 +3,8 @@ export enum Tabs {
TEAM1, TEAM1,
TEAM2, TEAM2,
} }
export enum StatsType {
FINAL_STATS,
CURRENT_STATS,
}

@ -0,0 +1,32 @@
import { useState } from 'react'
import { useMatchPageStore } from 'features/MatchPage/store'
import { StatsType, Tabs } from './config'
export const useTabStats = () => {
const [statsType, setStatsType] = useState<StatsType>(StatsType.FINAL_STATS)
const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.TEAMS)
const { fetchTeamsStats, teamsStats } = useMatchPageStore()
const isFinalStatsType = statsType === StatsType.FINAL_STATS
const switchTitleLexic = isFinalStatsType ? 'final_stats' : 'current_stats'
const tooltipLexic = isFinalStatsType ? 'display_stats_according_to_video' : 'display_all_stats'
const toggleStatsType = () => {
const newStatsType = isFinalStatsType ? StatsType.CURRENT_STATS : StatsType.FINAL_STATS
setStatsType(newStatsType)
}
return {
isFinalStatsType,
selectedTab,
setSelectedTab,
switchTitleLexic,
toggleStatsType,
tooltipLexic,
}
}

@ -1,5 +1,8 @@
import { Tooltip } from 'features/Tooltip' import { Tooltip } from 'features/Tooltip'
import { T9n } from 'features/T9n'
import { Tabs } from './config'
import { useTabStats } from './hooks'
import { PlayersTable } from '../PlayersTable' import { PlayersTable } from '../PlayersTable'
import { TeamsStats } from '../TeamsStats' import { TeamsStats } from '../TeamsStats'
@ -13,22 +16,58 @@ import {
SwitchButton, SwitchButton,
} from './styled' } from './styled'
export const TabStats = () => ( const tabPanes = {
[Tabs.TEAMS]: TeamsStats,
[Tabs.TEAM1]: PlayersTable,
[Tabs.TEAM2]: PlayersTable,
}
export const TabStats = () => {
const {
isFinalStatsType,
selectedTab,
setSelectedTab,
switchTitleLexic,
toggleStatsType,
tooltipLexic,
} = useTabStats()
const TabPane = tabPanes[selectedTab]
return (
<Container> <Container>
<Header> <Header>
<TabList> <TabList>
<Tab selected>Teams</Tab> <Tab
<Tab>DIN</Tab> aria-pressed={selectedTab === Tabs.TEAMS}
<Tab>SPA</Tab> onClick={() => setSelectedTab(Tabs.TEAMS)}
>
<T9n t='team' />
</Tab>
{/* <Tab
aria-pressed={selectedTab === Tabs.TEAM1}
onClick={() => setSelectedTab(Tabs.TEAM1)}
>
DIN
</Tab> */}
{/* <Tab
aria-pressed={selectedTab === Tabs.TEAM2}
onClick={() => setSelectedTab(Tabs.TEAM2)}
>
SPA
</Tab> */}
</TabList> </TabList>
<Switch> <Switch>
<SwitchTitle>Final Stats</SwitchTitle> <SwitchTitle t={switchTitleLexic} />
<SwitchButton> <SwitchButton
<Tooltip lexic='others' /> isFinalStatsType={isFinalStatsType}
onClick={toggleStatsType}
>
<Tooltip lexic={tooltipLexic} />
</SwitchButton> </SwitchButton>
</Switch> </Switch>
</Header> </Header>
<PlayersTable /> <TabPane />
{/* <TeamsStats /> */}
</Container> </Container>
) )
}

@ -1,6 +1,7 @@
import styled, { css } from 'styled-components/macro' import styled, { css } from 'styled-components/macro'
import { TooltipWrapper } from 'features/Tooltip' import { TooltipWrapper } from 'features/Tooltip'
import { T9n } from 'features/T9n'
export const Container = styled.div`` export const Container = styled.div``
@ -14,42 +15,40 @@ export const TabList = styled.div.attrs({ role: 'tablist' })`
display: flex; display: flex;
` `
type TabProps = { export const Tab = styled.button.attrs({ role: 'tab' })`
selected?: boolean,
}
export const Tab = styled.div.attrs(({ selected }: TabProps) => ({
'aria-pressed': selected,
role: 'tab',
}))<TabProps>`
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0 15px 10px; padding: 0 10px 10px;
font-size: 12px; font-size: 12px;
color: ${({ theme }) => theme.colors.white}; color: ${({ theme }) => theme.colors.white};
opacity: ${({ selected }) => (selected ? '1' : '0.4')}; opacity: 0.4;
cursor: pointer; cursor: pointer;
border: none;
background: none;
border-bottom: 2px solid transparent; border-bottom: 2px solid transparent;
&[aria-pressed="true"] {
${({ selected, theme }) => (selected opacity: 1;
? css` border-color: currentColor;
border-color: ${theme.colors.white}; }
`
: '')}
` `
export const Switch = styled.div` export const Switch = styled.div`
display: flex; display: flex;
` `
export const SwitchTitle = styled.span` export const SwitchTitle = styled(T9n)`
font-size: 12px; font-size: 12px;
color: ${({ theme }) => theme.colors.white}; color: ${({ theme }) => theme.colors.white};
white-space: nowrap;
` `
export const SwitchButton = styled.button` type SwitchButtonProps = {
isFinalStatsType: boolean,
}
export const SwitchButton = styled.button<SwitchButtonProps>`
position: relative; position: relative;
width: 20px; width: 20px;
height: 7px; height: 7px;
@ -66,6 +65,8 @@ export const SwitchButton = styled.button`
padding: 2px 10px; padding: 2px 10px;
border-radius: 6px; border-radius: 6px;
transform: none; transform: none;
font-size: 11px;
line-height: 1;
::before { ::before {
display: none; display: none;
@ -78,7 +79,7 @@ export const SwitchButton = styled.button`
} }
} }
${({ theme }) => (true // Позже будет добавлен пропс ${({ isFinalStatsType, theme }) => (!isFinalStatsType
? css` ? css`
background-image: linear-gradient( background-image: linear-gradient(
to right, to right,

@ -1,13 +1,8 @@
import styled, { css } from 'styled-components/macro' import styled, { css } from 'styled-components/macro'
import { customScrollbar } from 'features/Common'
export const Container = styled.div` export const Container = styled.div`
width: 100%; width: 100%;
font-size: 11px; font-size: 11px;
background-color: #333333;
${customScrollbar}
` `
export const TeamShortName = styled.span` export const TeamShortName = styled.span`
@ -25,6 +20,7 @@ export const Row = styled.div`
height: 45px; height: 45px;
padding: 0 12px; padding: 0 12px;
border-bottom: 0.5px solid rgba(255, 255, 255, 0.5); border-bottom: 0.5px solid rgba(255, 255, 255, 0.5);
background-color: #333333;
:last-child { :last-child {
border-bottom: none; border-bottom: none;

@ -5,6 +5,8 @@ import {
} from 'react' } from 'react'
import reduce from 'lodash/reduce' import reduce from 'lodash/reduce'
import isEmpty from 'lodash/isEmpty'
import compact from 'lodash/compact'
import { useMatchPageStore } from 'features/MatchPage/store' import { useMatchPageStore } from 'features/MatchPage/store'
@ -15,6 +17,7 @@ export const useMatchSidePlaylists = () => {
closePopup, closePopup,
events, events,
matchPlaylists: playlists, matchPlaylists: playlists,
teamsStats,
} = useMatchPageStore() } = useMatchPageStore()
const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.WATCH) const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.WATCH)
const isWatchTabVisible = useMemo(() => { const isWatchTabVisible = useMemo(() => {
@ -34,6 +37,21 @@ export const useMatchSidePlaylists = () => {
events.length > 0 events.length > 0
), [events]) ), [events])
const isPlayersTabVisible = useMemo(() => (
!isEmpty(playlists.players.team1)
), [playlists.players.team1])
const isStatsTabVisible = useMemo(() => (
!isEmpty(teamsStats)
), [teamsStats])
const hasLessThanFourTabs = compact([
isWatchTabVisible,
isEventTabVisible,
isPlayersTabVisible,
isStatsTabVisible,
]).length < 4
useEffect(() => { useEffect(() => {
switch (true) { switch (true) {
case isWatchTabVisible: case isWatchTabVisible:
@ -42,16 +60,29 @@ export const useMatchSidePlaylists = () => {
case isEventTabVisible: case isEventTabVisible:
setSelectedTab(Tabs.EVENTS) setSelectedTab(Tabs.EVENTS)
break break
case isPlayersTabVisible:
setSelectedTab(Tabs.PLAYERS)
break
case isStatsTabVisible:
setSelectedTab(Tabs.STATS)
break
} }
}, [isEventTabVisible, isWatchTabVisible]) }, [
isEventTabVisible,
isPlayersTabVisible,
isStatsTabVisible,
isWatchTabVisible,
])
useEffect(() => { useEffect(() => {
if (selectedTab !== Tabs.EVENTS) closePopup() if (selectedTab !== Tabs.EVENTS) closePopup()
}, [selectedTab, closePopup]) }, [selectedTab, closePopup])
return { return {
hasLessThanFourTabs,
isEventTabVisible, isEventTabVisible,
isStatsTabVisible: true, isPlayersTabVisible,
isStatsTabVisible,
isWatchTabVisible, isWatchTabVisible,
onTabClick: setSelectedTab, onTabClick: setSelectedTab,
selectedTab, selectedTab,

@ -42,8 +42,6 @@ type Props = {
setCircleAnimation?: TSetCircleAnimation, setCircleAnimation?: TSetCircleAnimation,
} }
const hasLessThanFourTabs = false
export const MatchSidePlaylists = ({ export const MatchSidePlaylists = ({
circleAnimation, circleAnimation,
onSelect, onSelect,
@ -59,7 +57,9 @@ export const MatchSidePlaylists = ({
} = useMatchPageStore() } = useMatchPageStore()
const { const {
hasLessThanFourTabs,
isEventTabVisible, isEventTabVisible,
isPlayersTabVisible,
isStatsTabVisible, isStatsTabVisible,
isWatchTabVisible, isWatchTabVisible,
onTabClick, onTabClick,
@ -108,7 +108,7 @@ export const MatchSidePlaylists = ({
<TabsGroup hasLessThanFourTabs={hasLessThanFourTabs}> <TabsGroup hasLessThanFourTabs={hasLessThanFourTabs}>
{isWatchTabVisible ? ( {isWatchTabVisible ? (
<Tab <Tab
selected={selectedTab === Tabs.WATCH} aria-pressed={selectedTab === Tabs.WATCH}
onClick={() => onTabClick(Tabs.WATCH)} onClick={() => onTabClick(Tabs.WATCH)}
> >
<TabIcon icon='watch' /> <TabIcon icon='watch' />
@ -117,25 +117,25 @@ export const MatchSidePlaylists = ({
) : null} ) : null}
{isEventTabVisible ? ( {isEventTabVisible ? (
<Tab <Tab
selected={selectedTab === Tabs.EVENTS} aria-pressed={selectedTab === Tabs.EVENTS}
onClick={() => onTabClick(Tabs.EVENTS)} onClick={() => onTabClick(Tabs.EVENTS)}
> >
<TabIcon icon='plays' /> <TabIcon icon='plays' />
<TabTitle t='actions' /> <TabTitle t='actions' />
</Tab> </Tab>
) : null} ) : null}
{isStatsTabVisible ? ( {isPlayersTabVisible ? (
<Tab <Tab
selected={selectedTab === Tabs.PLAYERS} aria-pressed={selectedTab === Tabs.PLAYERS}
onClick={() => onTabClick(Tabs.PLAYERS)} onClick={() => onTabClick(Tabs.PLAYERS)}
> >
<TabIcon icon='players' /> <TabIcon icon='players' />
<TabTitle t='stats' /> <TabTitle t='players' />
</Tab> </Tab>
) : null} ) : null}
{isStatsTabVisible ? ( {isStatsTabVisible ? (
<Tab <Tab
selected={selectedTab === Tabs.STATS} aria-pressed={selectedTab === Tabs.STATS}
onClick={() => onTabClick(Tabs.STATS)} onClick={() => onTabClick(Tabs.STATS)}
> >
<TabIcon icon='stats' /> <TabIcon icon='stats' />

@ -43,7 +43,7 @@ export const TabsGroup = styled.div.attrs({ role: 'tablist' })<TabsGroupProps>`
height: 40px; height: 40px;
${Tab} { ${Tab} {
justify-content: initial; justify-content: center;
flex-direction: row; flex-direction: row;
gap: 5px; gap: 5px;
} }
@ -56,23 +56,18 @@ export const TabsGroup = styled.div.attrs({ role: 'tablist' })<TabsGroupProps>`
: ''}; : ''};
` `
type TabProps = { export const Tab = styled.button.attrs({ role: 'tab' })`
selected?: boolean,
}
export const Tab = styled.div.attrs(({ selected }: TabProps) => ({
'aria-pressed': selected,
role: 'tab',
}))<TabProps>`
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
flex: 1; flex: 1;
opacity: ${({ selected }) => (selected ? '1' : '0.4')}; opacity: 0.4;
cursor: pointer; cursor: pointer;
border: none;
background: none;
:hover { &[aria-pressed="true"], :hover {
opacity: 1; opacity: 1;
} }
` `
@ -103,6 +98,7 @@ export const TabTitle = styled(T9n)`
` `
type TContainer = { type TContainer = {
forVideoTab?: boolean,
hasScroll: boolean, hasScroll: boolean,
} }

@ -22,6 +22,7 @@ export const usePageParams = () => {
return { return {
profileId: Number(pageId), profileId: Number(pageId),
profileType: ProfileTypes[toUpper(profileName) as keyof typeof ProfileTypes], profileType: ProfileTypes[toUpper(profileName) as keyof typeof ProfileTypes],
sportName,
sportType: SportTypes[toUpper(sportName) as keyof typeof SportTypes], sportType: SportTypes[toUpper(sportName) as keyof typeof SportTypes],
} }
} }

@ -0,0 +1,56 @@
import isUndefined from 'lodash/isUndefined'
import { callApi } from 'helpers'
type Param = {
clickable: boolean,
data_type: string,
id: number,
lexic: number,
markers: Array<number>,
name_en: string,
name_ru: string,
val: number,
}
export type TeamStatItem = {
lexic: number,
name_en: string,
name_ru: string,
order: number,
param1: Param,
param2: Param | null,
}
type Response = {
data?: {
[teamId: string]: Array<TeamStatItem>,
},
error?: string,
message?: string,
}
type GetTeamsStatsArgs = {
matchId: number,
second?: number,
sportName: string,
}
export const getTeamsStats = async ({
matchId,
second,
sportName,
}: GetTeamsStatsArgs) => {
const config = {
method: 'GET',
}
const response: Response = await callApi({
config,
url: `http://3.248.230.144:8888/${sportName}/matches/${matchId}/teams/stats?group_num=0${isUndefined(second) ? '' : `&second=${second}`}`,
})
if (response.error) Promise.reject(response)
return Promise.resolve(response.data || {})
}

@ -25,3 +25,4 @@ export * from './getPlayerPlaylists'
export * from './getSubscriptions' export * from './getSubscriptions'
export * from './buySubscription' export * from './buySubscription'
export * from './saveMatchStats' export * from './saveMatchStats'
export * from './getTeamsStats'

Loading…
Cancel
Save