parent
18068fd10f
commit
a7eb04b6f4
@ -1,159 +0,0 @@ |
||||
import { |
||||
useMemo, |
||||
useEffect, |
||||
useState, |
||||
} from 'react' |
||||
|
||||
import throttle from 'lodash/throttle' |
||||
import isEmpty from 'lodash/isEmpty' |
||||
import every from 'lodash/every' |
||||
import find from 'lodash/find' |
||||
|
||||
import type { |
||||
MatchInfo, |
||||
PlayersStats, |
||||
Player, |
||||
} from 'requests' |
||||
import { getPlayersStats, getMatchParticipants } from 'requests' |
||||
|
||||
import { useObjectState, usePageParams } from 'hooks' |
||||
|
||||
import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config' |
||||
|
||||
const REQUEST_DELAY = 3000 |
||||
const STATS_POLL_INTERVAL = 30000 |
||||
|
||||
type UsePlayersStatsArgs = { |
||||
matchProfile: MatchInfo, |
||||
playingProgress: number, |
||||
statsType: StatsType, |
||||
} |
||||
|
||||
type PlayersData = { |
||||
team1: Array<Player>, |
||||
team2: Array<Player>, |
||||
} |
||||
|
||||
export const usePlayersStats = ({ |
||||
matchProfile, |
||||
playingProgress, |
||||
statsType, |
||||
}: UsePlayersStatsArgs) => { |
||||
const [playersStats, setPlayersStats] = useObjectState<Record<string, PlayersStats>>({}) |
||||
const [playersData, setPlayersData] = useState<PlayersData>({ team1: [], team2: [] }) |
||||
|
||||
const { |
||||
profileId: matchId, |
||||
sportName, |
||||
sportType, |
||||
} = usePageParams() |
||||
|
||||
const isCurrentStats = statsType === StatsType.CURRENT_STATS |
||||
|
||||
const progressSec = Math.floor(playingProgress / 1000) |
||||
|
||||
const isEmptyPlayersStats = (teamId: number) => ( |
||||
isEmpty(playersStats[teamId]) |
||||
|| every(playersStats[teamId], isEmpty) |
||||
|| isEmpty(playersData[matchProfile?.team1.id === teamId ? 'team1' : 'team2']) |
||||
) |
||||
|
||||
const fetchPlayers = useMemo(() => throttle((second?: number) => { |
||||
if (!matchProfile?.team1.id || !matchProfile?.team1.id) return |
||||
|
||||
try { |
||||
getMatchParticipants({ |
||||
matchId, |
||||
second, |
||||
sportType, |
||||
}).then((data) => { |
||||
const team1Players = find(data, { team_id: matchProfile.team1.id })?.players || [] |
||||
const team2Players = find(data, { team_id: matchProfile.team2.id })?.players || [] |
||||
|
||||
setPlayersData({ |
||||
team1: team1Players, |
||||
team2: team2Players, |
||||
}) |
||||
}) |
||||
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {} |
||||
}, REQUEST_DELAY), [ |
||||
matchId, |
||||
matchProfile?.team1.id, |
||||
matchProfile?.team2.id, |
||||
sportType, |
||||
]) |
||||
|
||||
const fetchPlayersStats = useMemo(() => throttle((second?: number) => { |
||||
if (!sportName || !matchProfile?.team1.id || !matchProfile?.team2.id) return |
||||
|
||||
try { |
||||
getPlayersStats({ |
||||
matchId, |
||||
second, |
||||
sportName, |
||||
teamId: matchProfile.team1.id, |
||||
}).then((data) => setPlayersStats({ [matchProfile.team1.id]: data })) |
||||
|
||||
getPlayersStats({ |
||||
matchId, |
||||
second, |
||||
sportName, |
||||
teamId: matchProfile.team2.id, |
||||
}).then((data) => setPlayersStats({ [matchProfile?.team2.id]: data })) |
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {} |
||||
}, REQUEST_DELAY), [ |
||||
matchId, |
||||
matchProfile?.team1.id, |
||||
matchProfile?.team2.id, |
||||
setPlayersStats, |
||||
sportName, |
||||
]) |
||||
|
||||
useEffect(() => { |
||||
let interval: NodeJS.Timeout |
||||
|
||||
fetchPlayers() |
||||
|
||||
if (!isCurrentStats) { |
||||
fetchPlayersStats() |
||||
} |
||||
|
||||
if (matchProfile?.live) { |
||||
interval = setInterval(() => { |
||||
if (isCurrentStats) return |
||||
|
||||
fetchPlayersStats() |
||||
fetchPlayers() |
||||
}, STATS_POLL_INTERVAL) |
||||
} |
||||
|
||||
return () => clearInterval(interval) |
||||
}, [ |
||||
fetchPlayersStats, |
||||
fetchPlayers, |
||||
isCurrentStats, |
||||
matchProfile?.live, |
||||
]) |
||||
|
||||
useEffect(() => { |
||||
if (isCurrentStats) { |
||||
fetchPlayersStats(progressSec) |
||||
fetchPlayers(progressSec) |
||||
} |
||||
}, [ |
||||
fetchPlayersStats, |
||||
fetchPlayers, |
||||
progressSec, |
||||
isCurrentStats, |
||||
matchProfile?.live, |
||||
]) |
||||
|
||||
return { |
||||
isEmptyPlayersStats, |
||||
playersData, |
||||
playersStats, |
||||
} |
||||
} |
||||
@ -1,12 +0,0 @@ |
||||
import { useState } from 'react' |
||||
|
||||
import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config' |
||||
|
||||
export const useStatsTab = () => { |
||||
const [statsType, setStatsType] = useState<StatsType>(StatsType.FINAL_STATS) |
||||
|
||||
return { |
||||
setStatsType, |
||||
statsType, |
||||
} |
||||
} |
||||
@ -1,78 +0,0 @@ |
||||
import { |
||||
useEffect, |
||||
useState, |
||||
useMemo, |
||||
} from 'react' |
||||
|
||||
import throttle from 'lodash/throttle' |
||||
|
||||
import type { MatchInfo } from 'requests' |
||||
import { getTeamsStats, TeamStatItem } from 'requests' |
||||
|
||||
import { usePageParams } from 'hooks/usePageParams' |
||||
|
||||
import { StatsType } from 'features/MatchSidePlaylists/components/TabStats/config' |
||||
|
||||
const REQUEST_DELAY = 3000 |
||||
const STATS_POLL_INTERVAL = 30000 |
||||
|
||||
type UseTeamsStatsArgs = { |
||||
matchProfile: MatchInfo, |
||||
playingProgress: number, |
||||
statsType: StatsType, |
||||
} |
||||
|
||||
export const useTeamsStats = ({ |
||||
matchProfile, |
||||
playingProgress, |
||||
statsType, |
||||
}: UseTeamsStatsArgs) => { |
||||
const [teamsStats, setTeamsStats] = useState<{ |
||||
[teamId: string]: Array<TeamStatItem>, |
||||
}>({}) |
||||
|
||||
const { profileId: matchId, sportName } = usePageParams() |
||||
|
||||
const progressSec = Math.floor(playingProgress / 1000) |
||||
|
||||
const isCurrentStats = statsType === StatsType.CURRENT_STATS |
||||
|
||||
const fetchTeamsStats = useMemo(() => throttle((second?: number) => { |
||||
if (!sportName) return |
||||
|
||||
getTeamsStats({ |
||||
matchId, |
||||
second, |
||||
sportName, |
||||
}).then(setTeamsStats) |
||||
}, REQUEST_DELAY), [matchId, sportName]) |
||||
|
||||
useEffect(() => { |
||||
let timer: ReturnType<typeof setInterval> |
||||
|
||||
if (!isCurrentStats) { |
||||
fetchTeamsStats() |
||||
} |
||||
|
||||
if (matchProfile?.live) { |
||||
timer = setInterval(() => { |
||||
if (isCurrentStats) return |
||||
|
||||
fetchTeamsStats() |
||||
}, STATS_POLL_INTERVAL) |
||||
} |
||||
|
||||
return () => clearInterval(timer) |
||||
}, [fetchTeamsStats, matchProfile?.live, isCurrentStats]) |
||||
|
||||
useEffect(() => { |
||||
if (isCurrentStats) { |
||||
fetchTeamsStats(progressSec) |
||||
} |
||||
}, [fetchTeamsStats, progressSec, isCurrentStats]) |
||||
|
||||
return { |
||||
statsType, |
||||
teamsStats, |
||||
} |
||||
} |
||||
@ -1,6 +0,0 @@ |
||||
export const PARAM_COLUMN_WIDTH = 50 |
||||
export const REQUEST_DELAY = 3000 |
||||
export const STATS_POLL_INTERVAL = 30000 |
||||
export const DISPLAYED_PARAMS_COLUMNS = 4 |
||||
export const FIRST_COLUMN_WIDTH_DEFAULT = 100 |
||||
export const SCROLLBAR_WIDTH = 8 |
||||
@ -1,58 +0,0 @@ |
||||
import { useState } from 'react' |
||||
|
||||
import type { SortCondition, PlayersTableProps } from '../types' |
||||
import { usePlayers } from './usePlayers' |
||||
import { useTable } from './useTable' |
||||
|
||||
export const usePlayersTable = ({ teamId }: PlayersTableProps) => { |
||||
const [sortCondition, setSortCondition] = useState<SortCondition>({ dir: 'asc', paramId: null }) |
||||
|
||||
const { |
||||
getFullName, |
||||
getPlayerParams, |
||||
players, |
||||
} = usePlayers({ sortCondition, teamId }) |
||||
|
||||
const { |
||||
containerRef, |
||||
firstColumnWidth, |
||||
getDisplayedValue, |
||||
handleScroll, |
||||
handleSortClick, |
||||
isExpanded, |
||||
paramColumnWidth, |
||||
params, |
||||
showExpandButton, |
||||
showLeftArrow, |
||||
showRightArrow, |
||||
slideLeft, |
||||
slideRight, |
||||
tableWrapperRef, |
||||
toggleIsExpanded, |
||||
} = useTable({ |
||||
setSortCondition, |
||||
teamId, |
||||
}) |
||||
|
||||
return { |
||||
containerRef, |
||||
firstColumnWidth, |
||||
getDisplayedValue, |
||||
getFullName, |
||||
getPlayerParams, |
||||
handleScroll, |
||||
handleSortClick, |
||||
isExpanded, |
||||
paramColumnWidth, |
||||
params, |
||||
players, |
||||
showExpandButton, |
||||
showLeftArrow, |
||||
showRightArrow, |
||||
slideLeft, |
||||
slideRight, |
||||
sortCondition, |
||||
tableWrapperRef, |
||||
toggleIsExpanded, |
||||
} |
||||
} |
||||
@ -1,83 +0,0 @@ |
||||
import { useMemo, useCallback } from 'react' |
||||
|
||||
import orderBy from 'lodash/orderBy' |
||||
import isNil from 'lodash/isNil' |
||||
import trim from 'lodash/trim' |
||||
|
||||
import type { Player, PlayerParam } from 'requests' |
||||
|
||||
import { useToggle } from 'hooks' |
||||
|
||||
import { useMatchPageStore } from 'features/MatchPage/store' |
||||
import { useLexicsStore } from 'features/LexicsStore' |
||||
|
||||
import type { SortCondition } from '../types' |
||||
|
||||
type UsePlayersArgs = { |
||||
sortCondition: SortCondition, |
||||
teamId: number, |
||||
} |
||||
|
||||
export const usePlayers = ({ sortCondition, teamId }: UsePlayersArgs) => { |
||||
const { isOpen: isExpanded, toggle: toggleIsExpanded } = useToggle() |
||||
const { |
||||
playersData, |
||||
playersStats, |
||||
profile: matchProfile, |
||||
} = useMatchPageStore() |
||||
const { suffix } = useLexicsStore() |
||||
|
||||
const getPlayerParams = useCallback( |
||||
(playerId: number) => playersStats[teamId][playerId] || {}, |
||||
[playersStats, teamId], |
||||
) |
||||
|
||||
const getDisplayedValue = ({ val }: PlayerParam) => (isNil(val) ? '-' : val) |
||||
|
||||
const getFullName = useCallback((player: Player) => ( |
||||
trim(`${player[`firstname_${suffix}`]} ${player[`lastname_${suffix}`]}`) |
||||
), [suffix]) |
||||
|
||||
const getParamValue = useCallback((playerId: number, paramId: number) => { |
||||
const playerParams = getPlayerParams(playerId) |
||||
const { val } = playerParams[paramId] || {} |
||||
|
||||
return val |
||||
}, [getPlayerParams]) |
||||
|
||||
const sortedPlayers = useMemo(() => { |
||||
const players = playersData[matchProfile?.team1.id === teamId ? 'team1' : 'team2'] |
||||
|
||||
return isNil(sortCondition.paramId) |
||||
? orderBy(players, getFullName) |
||||
: orderBy( |
||||
players, |
||||
[ |
||||
(player) => { |
||||
const paramValue = getParamValue(player.id, sortCondition.paramId!) |
||||
|
||||
return isNil(paramValue) ? -1 : paramValue |
||||
}, |
||||
getFullName, |
||||
], |
||||
sortCondition.dir, |
||||
) |
||||
}, [ |
||||
getFullName, |
||||
getParamValue, |
||||
playersData, |
||||
matchProfile?.team1.id, |
||||
sortCondition.dir, |
||||
sortCondition.paramId, |
||||
teamId, |
||||
]) |
||||
|
||||
return { |
||||
getDisplayedValue, |
||||
getFullName, |
||||
getPlayerParams, |
||||
isExpanded, |
||||
players: sortedPlayers, |
||||
toggleIsExpanded, |
||||
} |
||||
} |
||||
@ -1,171 +0,0 @@ |
||||
import type { |
||||
SyntheticEvent, |
||||
Dispatch, |
||||
SetStateAction, |
||||
} from 'react' |
||||
import { |
||||
useRef, |
||||
useState, |
||||
useEffect, |
||||
useMemo, |
||||
} from 'react' |
||||
|
||||
import size from 'lodash/size' |
||||
import isNil from 'lodash/isNil' |
||||
import reduce from 'lodash/reduce' |
||||
import forEach from 'lodash/forEach' |
||||
import values from 'lodash/values' |
||||
import round from 'lodash/round' |
||||
import map from 'lodash/map' |
||||
|
||||
import { isMobileDevice } from 'config' |
||||
|
||||
import type { PlayerParam, PlayersStats } from 'requests' |
||||
|
||||
import { useToggle } from 'hooks' |
||||
|
||||
import { useMatchPageStore } from 'features/MatchPage/store' |
||||
import { useLexicsConfig } from 'features/LexicsStore' |
||||
|
||||
import type { SortCondition } from '../types' |
||||
import { |
||||
PARAM_COLUMN_WIDTH, |
||||
DISPLAYED_PARAMS_COLUMNS, |
||||
FIRST_COLUMN_WIDTH_DEFAULT, |
||||
SCROLLBAR_WIDTH, |
||||
} from '../config' |
||||
|
||||
type UseTableArgs = { |
||||
setSortCondition: Dispatch<SetStateAction<SortCondition>>, |
||||
teamId: number, |
||||
} |
||||
|
||||
type HeaderParam = Pick<PlayerParam, 'id' | 'lexica_short' | 'lexic'> |
||||
|
||||
export const useTable = ({ |
||||
setSortCondition, |
||||
teamId, |
||||
}: UseTableArgs) => { |
||||
const containerRef = useRef<HTMLDivElement>(null) |
||||
const tableWrapperRef = useRef<HTMLDivElement>(null) |
||||
|
||||
const [showLeftArrow, setShowLeftArrow] = useState(false) |
||||
const [showRightArrow, setShowRightArrow] = useState(false) |
||||
|
||||
const { isOpen: isExpanded, toggle: toggleIsExpanded } = useToggle() |
||||
const { playersStats } = useMatchPageStore() |
||||
|
||||
const params = useMemo(() => ( |
||||
reduce<PlayersStats, Record<string, HeaderParam>>( |
||||
playersStats[teamId], |
||||
(acc, curr) => { |
||||
forEach(values(curr), ({ |
||||
id, |
||||
lexic, |
||||
lexica_short, |
||||
}) => { |
||||
acc[id] = acc[id] || { |
||||
id, |
||||
lexic, |
||||
lexica_short, |
||||
} |
||||
}) |
||||
|
||||
return acc |
||||
}, |
||||
{}, |
||||
) |
||||
), [playersStats, teamId]) |
||||
|
||||
const lexics = useMemo(() => ( |
||||
reduce<HeaderParam, Array<number>>( |
||||
values(params), |
||||
(acc, { lexic, lexica_short }) => { |
||||
if (lexic) acc.push(lexic) |
||||
if (lexica_short) acc.push(lexica_short) |
||||
|
||||
return acc |
||||
}, |
||||
[], |
||||
) |
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
), [map(params, 'id').sort().join('')]) |
||||
|
||||
useLexicsConfig(lexics) |
||||
|
||||
const paramsCount = size(params) |
||||
|
||||
const getParamColumnWidth = () => { |
||||
const rest = ( |
||||
(containerRef.current?.clientWidth || 0) - FIRST_COLUMN_WIDTH_DEFAULT - SCROLLBAR_WIDTH |
||||
) |
||||
const desktopWith = PARAM_COLUMN_WIDTH |
||||
const mobileWidth = paramsCount < DISPLAYED_PARAMS_COLUMNS ? 0 : rest / DISPLAYED_PARAMS_COLUMNS |
||||
|
||||
return isMobileDevice ? mobileWidth : desktopWith |
||||
} |
||||
|
||||
const getFirstColumnWidth = () => { |
||||
if (isExpanded) return 0 |
||||
|
||||
return paramsCount < DISPLAYED_PARAMS_COLUMNS ? 0 : FIRST_COLUMN_WIDTH_DEFAULT |
||||
} |
||||
|
||||
const paramColumnWidth = getParamColumnWidth() |
||||
const firstColumnWidth = getFirstColumnWidth() |
||||
|
||||
const slideLeft = () => tableWrapperRef.current?.scrollBy(-paramColumnWidth, 0) |
||||
const slideRight = () => tableWrapperRef.current?.scrollBy(paramColumnWidth, 0) |
||||
|
||||
const getDisplayedValue = ({ val }: PlayerParam) => (isNil(val) ? '-' : round(val, 2)) |
||||
|
||||
const handleScroll = (e: SyntheticEvent<HTMLDivElement>) => { |
||||
const { |
||||
clientWidth, |
||||
scrollLeft, |
||||
scrollWidth, |
||||
} = e.currentTarget |
||||
|
||||
const scrollRight = scrollWidth - (scrollLeft + clientWidth) |
||||
|
||||
setShowLeftArrow(scrollLeft > 0) |
||||
setShowRightArrow(scrollRight > 0) |
||||
} |
||||
|
||||
const handleSortClick = (paramId: number) => () => { |
||||
setSortCondition((curr) => ({ |
||||
dir: curr.dir === 'asc' || curr.paramId !== paramId ? 'desc' : 'asc', |
||||
paramId, |
||||
})) |
||||
} |
||||
|
||||
useEffect(() => { |
||||
const { |
||||
clientWidth = 0, |
||||
scrollLeft = 0, |
||||
scrollWidth = 0, |
||||
} = tableWrapperRef.current || {} |
||||
|
||||
const scrollRight = scrollWidth - (scrollLeft + clientWidth) |
||||
|
||||
setShowRightArrow(scrollRight > 0) |
||||
}, [isExpanded]) |
||||
|
||||
return { |
||||
containerRef, |
||||
firstColumnWidth, |
||||
getDisplayedValue, |
||||
handleScroll, |
||||
handleSortClick, |
||||
isExpanded, |
||||
paramColumnWidth, |
||||
params, |
||||
showExpandButton: !isMobileDevice && paramsCount > DISPLAYED_PARAMS_COLUMNS, |
||||
showLeftArrow, |
||||
showRightArrow, |
||||
slideLeft, |
||||
slideRight, |
||||
tableWrapperRef, |
||||
toggleIsExpanded, |
||||
} |
||||
} |
||||
@ -1,166 +1,243 @@ |
||||
import { Fragment } from 'react' |
||||
|
||||
import map from 'lodash/map' |
||||
import includes from 'lodash/includes' |
||||
|
||||
import { PlayerParam } from 'requests' |
||||
|
||||
import { T9n } from 'features/T9n' |
||||
|
||||
import type { PlayersTableProps } from './types' |
||||
import { usePlayersTable } from './hooks' |
||||
import { |
||||
Container, |
||||
TableWrapper, |
||||
Table, |
||||
FirstColumn, |
||||
Cell, |
||||
Row, |
||||
Thead, |
||||
Th, |
||||
Tbody, |
||||
Tr, |
||||
Td, |
||||
PlayerNum, |
||||
PlayerNameWrapper, |
||||
PlayerName, |
||||
ParamShortTitle, |
||||
ArrowButtonRight, |
||||
ArrowButtonLeft, |
||||
Arrow, |
||||
ExpandButton, |
||||
Tooltip, |
||||
} from './styled' |
||||
|
||||
export const PlayersTable = (props: PlayersTableProps) => { |
||||
const { |
||||
containerRef, |
||||
firstColumnWidth, |
||||
getDisplayedValue, |
||||
getFullName, |
||||
getPlayerParams, |
||||
handleScroll, |
||||
handleSortClick, |
||||
isExpanded, |
||||
paramColumnWidth, |
||||
params, |
||||
players, |
||||
showExpandButton, |
||||
showLeftArrow, |
||||
showRightArrow, |
||||
slideLeft, |
||||
slideRight, |
||||
sortCondition, |
||||
tableWrapperRef, |
||||
toggleIsExpanded, |
||||
} = usePlayersTable(props) |
||||
|
||||
return ( |
||||
<Container |
||||
ref={containerRef} |
||||
isExpanded={isExpanded} |
||||
> |
||||
<TableWrapper |
||||
ref={tableWrapperRef} |
||||
isExpanded={isExpanded} |
||||
onScroll={handleScroll} |
||||
> |
||||
{!isExpanded && ( |
||||
<Fragment> |
||||
{showLeftArrow && ( |
||||
<ArrowButtonLeft |
||||
aria-label='Scroll to left' |
||||
onClick={slideLeft} |
||||
> |
||||
<Arrow direction='left' /> |
||||
</ArrowButtonLeft> |
||||
)} |
||||
{showRightArrow && ( |
||||
<ArrowButtonRight |
||||
aria-label='Scroll to right' |
||||
onClick={slideRight} |
||||
> |
||||
<Arrow direction='right' /> |
||||
</ArrowButtonRight> |
||||
)} |
||||
</Fragment> |
||||
)} |
||||
<FirstColumn columnWidth={firstColumnWidth}> |
||||
<Row> |
||||
<Cell> |
||||
{showExpandButton && ( |
||||
<ExpandButton |
||||
aria-label={isExpanded ? 'Reduce' : 'Expand'} |
||||
onClick={toggleIsExpanded} |
||||
> |
||||
<Arrow direction={isExpanded ? 'right' : 'left'} /> |
||||
<Arrow direction={isExpanded ? 'right' : 'left'} /> |
||||
</ExpandButton> |
||||
)} |
||||
</Cell> |
||||
</Row> |
||||
{map(players, (player) => { |
||||
const fullName = getFullName(player) |
||||
|
||||
return ( |
||||
<Row key={player.id}> |
||||
<Cell> |
||||
<PlayerNum> |
||||
{player.club_shirt_num} |
||||
</PlayerNum>{' '} |
||||
<PlayerNameWrapper> |
||||
<PlayerName columnWidth={firstColumnWidth}> |
||||
{fullName} |
||||
</PlayerName> |
||||
<Tooltip> |
||||
<PlayerName>{fullName}</PlayerName> |
||||
</Tooltip> |
||||
</PlayerNameWrapper> |
||||
</Cell> |
||||
</Row> |
||||
) |
||||
})} |
||||
</FirstColumn> |
||||
<Table> |
||||
<Row> |
||||
{map(params, ({ |
||||
id, |
||||
lexic, |
||||
lexica_short, |
||||
}) => ( |
||||
<Cell |
||||
key={id} |
||||
columnWidth={paramColumnWidth} |
||||
onClick={handleSortClick(id)} |
||||
sorted={sortCondition.paramId === id} |
||||
headerCell |
||||
> |
||||
<ParamShortTitle t={lexica_short || ''} /> |
||||
<Tooltip> |
||||
<T9n t={lexic} /> |
||||
</Tooltip> |
||||
</Cell> |
||||
))} |
||||
</Row> |
||||
|
||||
{map(players, (player) => ( |
||||
<Row key={player.id}> |
||||
{map(params, ({ id }) => { |
||||
const playerParam = getPlayerParams(player.id)[id] as PlayerParam | undefined |
||||
const value = playerParam ? getDisplayedValue(playerParam) : '-' |
||||
const clickable = Boolean(playerParam?.clickable) && !includes([0, '-'], value) |
||||
const sorted = sortCondition.paramId === id |
||||
|
||||
return ( |
||||
<Cell |
||||
columnWidth={paramColumnWidth} |
||||
key={id} |
||||
clickable={clickable} |
||||
sorted={sorted} |
||||
> |
||||
{value} |
||||
</Cell> |
||||
) |
||||
})} |
||||
</Row> |
||||
))} |
||||
</Table> |
||||
</TableWrapper> |
||||
</Container> |
||||
) |
||||
} |
||||
export const PlayersTable = () => ( |
||||
<Table> |
||||
<Thead> |
||||
<Th /> |
||||
<Th> |
||||
<ParamShortTitle>Min</ParamShortTitle> |
||||
</Th> |
||||
<Th sorted> |
||||
<ParamShortTitle>Pt</ParamShortTitle> |
||||
</Th> |
||||
<Th> |
||||
<ParamShortTitle>Reb</ParamShortTitle> |
||||
</Th> |
||||
<Th> |
||||
<ParamShortTitle>Ass</ParamShortTitle> |
||||
</Th> |
||||
<Th> |
||||
<ParamShortTitle>To</ParamShortTitle> |
||||
</Th> |
||||
</Thead> |
||||
<Tbody> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
<Tr> |
||||
<Td><PlayerNum>57</PlayerNum> Selikhov</Td> |
||||
<Td clickable>97</Td> |
||||
<Td sorted>12</Td> |
||||
<Td>2</Td> |
||||
<Td>1</Td> |
||||
<Td>4</Td> |
||||
</Tr> |
||||
</Tbody> |
||||
</Table> |
||||
) |
||||
|
||||
@ -1,8 +0,0 @@ |
||||
export type PlayersTableProps = { |
||||
teamId: number, |
||||
} |
||||
|
||||
export type SortCondition = { |
||||
dir: 'asc' | 'desc', |
||||
paramId: number | null, |
||||
} |
||||
@ -1,68 +0,0 @@ |
||||
import { useEffect, useState } from 'react' |
||||
|
||||
import isEmpty from 'lodash/isEmpty' |
||||
|
||||
import { useMatchPageStore } from 'features/MatchPage/store' |
||||
|
||||
import { StatsType, Tabs } from './config' |
||||
|
||||
export const useTabStats = () => { |
||||
const [selectedTab, setSelectedTab] = useState<Tabs>(Tabs.TEAMS) |
||||
|
||||
const { |
||||
isEmptyPlayersStats, |
||||
profile: matchProfile, |
||||
setStatsType, |
||||
statsType, |
||||
teamsStats, |
||||
} = useMatchPageStore() |
||||
|
||||
const isFinalStatsType = statsType === StatsType.FINAL_STATS |
||||
|
||||
const switchTitleLexic = isFinalStatsType ? 'final_stats' : 'current_stats' |
||||
const tooltipLexic = isFinalStatsType ? 'display_all_stats' : 'display_stats_according_to_video' |
||||
|
||||
const isVisibleTeamsTab = !isEmpty(teamsStats) |
||||
const isVisibleTeam1PlayersTab = Boolean( |
||||
matchProfile && !isEmptyPlayersStats(matchProfile.team1.id), |
||||
) |
||||
const isVisibleTeam2PlayersTab = Boolean( |
||||
matchProfile && !isEmptyPlayersStats(matchProfile.team2.id), |
||||
) |
||||
|
||||
const toggleStatsType = () => { |
||||
const newStatsType = isFinalStatsType ? StatsType.CURRENT_STATS : StatsType.FINAL_STATS |
||||
|
||||
setStatsType(newStatsType) |
||||
} |
||||
|
||||
useEffect(() => { |
||||
switch (true) { |
||||
case isVisibleTeamsTab: |
||||
setSelectedTab(Tabs.TEAMS) |
||||
break |
||||
|
||||
case isVisibleTeam1PlayersTab: |
||||
setSelectedTab(Tabs.TEAM1) |
||||
break |
||||
|
||||
case isVisibleTeam2PlayersTab: |
||||
setSelectedTab(Tabs.TEAM2) |
||||
break |
||||
|
||||
default: |
||||
} |
||||
}, [isVisibleTeam1PlayersTab, isVisibleTeam2PlayersTab, isVisibleTeamsTab]) |
||||
|
||||
return { |
||||
isFinalStatsType, |
||||
isVisibleTeam1PlayersTab, |
||||
isVisibleTeam2PlayersTab, |
||||
isVisibleTeamsTab, |
||||
selectedTab, |
||||
setSelectedTab, |
||||
switchTitleLexic, |
||||
toggleStatsType, |
||||
tooltipLexic, |
||||
} |
||||
} |
||||
@ -0,0 +1,276 @@ |
||||
import { |
||||
Container, |
||||
Row, |
||||
TeamShortName, |
||||
ParamValueContainer, |
||||
ParamValue, |
||||
ParamTitle, |
||||
} from './styled' |
||||
|
||||
export const TeamsStats = () => ( |
||||
<Container> |
||||
<Row> |
||||
<TeamShortName>DIN</TeamShortName> |
||||
<TeamShortName>SPA</TeamShortName> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue clickable>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue clickable>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
<Row> |
||||
<ParamValueContainer> |
||||
<ParamValue>90</ParamValue> |
||||
</ParamValueContainer> |
||||
<ParamTitle>Points</ParamTitle> |
||||
<ParamValue>123</ParamValue> |
||||
</Row> |
||||
</Container> |
||||
) |
||||
@ -1,31 +0,0 @@ |
||||
import isNumber from 'lodash/isNumber' |
||||
import find from 'lodash/find' |
||||
import round from 'lodash/round' |
||||
|
||||
import type { Param } from 'requests' |
||||
|
||||
import { useMatchPageStore } from 'features/MatchPage/store' |
||||
|
||||
export const useTeamsStatsTable = () => { |
||||
const { profile, teamsStats } = useMatchPageStore() |
||||
|
||||
const getDisplayedValue = (val: any) => ( |
||||
isNumber(val) ? round(val, 2) : '-' |
||||
) |
||||
|
||||
const getStatItemById = (paramId: number) => { |
||||
if (!profile) return null |
||||
|
||||
return find(teamsStats[profile?.team2.id], ({ param1 }) => param1.id === paramId) || null |
||||
} |
||||
|
||||
const isClickable = (param: Param) => ( |
||||
Boolean(param.val) && param.clickable |
||||
) |
||||
|
||||
return { |
||||
getDisplayedValue, |
||||
getStatItemById, |
||||
isClickable, |
||||
} |
||||
} |
||||
@ -1,93 +0,0 @@ |
||||
import { Fragment } from 'react' |
||||
|
||||
import map from 'lodash/map' |
||||
|
||||
import { useMatchPageStore } from 'features/MatchPage/store' |
||||
import { useLexicsStore } from 'features/LexicsStore' |
||||
|
||||
import { useTeamsStatsTable } from './hooks' |
||||
import { |
||||
Container, |
||||
Row, |
||||
TeamShortName, |
||||
ParamValueContainer, |
||||
ParamValue, |
||||
StatItemTitle, |
||||
Divider, |
||||
} from './styled' |
||||
|
||||
export const TeamsStatsTable = () => { |
||||
const { profile, teamsStats } = useMatchPageStore() |
||||
const { |
||||
getDisplayedValue, |
||||
getStatItemById, |
||||
isClickable, |
||||
} = useTeamsStatsTable() |
||||
const { lang } = useLexicsStore() |
||||
|
||||
if (!profile) return null |
||||
|
||||
return ( |
||||
<Container> |
||||
<Row> |
||||
<TeamShortName |
||||
nameObj={profile.team1} |
||||
prefix='abbrev_' |
||||
/> |
||||
<TeamShortName |
||||
nameObj={profile.team2} |
||||
prefix='abbrev_' |
||||
/> |
||||
</Row> |
||||
|
||||
{map(teamsStats[profile.team1.id], (team1StatItem) => { |
||||
const team2StatItem = getStatItemById(team1StatItem.param1.id) |
||||
const statItemTitle = team1StatItem[`name_${lang === 'ru' ? 'ru' : 'en'}`] |
||||
|
||||
return ( |
||||
<Row key={team1StatItem.param1.id}> |
||||
<ParamValueContainer> |
||||
<ParamValue |
||||
clickable={isClickable(team1StatItem.param1)} |
||||
> |
||||
{getDisplayedValue(team1StatItem.param1.val)} |
||||
</ParamValue> |
||||
{team1StatItem.param2 && ( |
||||
<Fragment> |
||||
<Divider>/</Divider> |
||||
<ParamValue |
||||
clickable={isClickable(team1StatItem.param2)} |
||||
> |
||||
{getDisplayedValue(team1StatItem.param2.val)} |
||||
</ParamValue> |
||||
</Fragment> |
||||
)} |
||||
</ParamValueContainer> |
||||
|
||||
<StatItemTitle>{statItemTitle}</StatItemTitle> |
||||
|
||||
{team2StatItem && ( |
||||
<ParamValueContainer> |
||||
<ParamValue |
||||
clickable={isClickable(team2StatItem.param1)} |
||||
> |
||||
{getDisplayedValue(team2StatItem.param1.val)} |
||||
</ParamValue> |
||||
{team2StatItem.param2 && ( |
||||
<Fragment> |
||||
<Divider>/</Divider> |
||||
<ParamValue |
||||
clickable={isClickable(team2StatItem.param2)} |
||||
> |
||||
{getDisplayedValue(team2StatItem.param2.val)} |
||||
</ParamValue> |
||||
</Fragment> |
||||
)} |
||||
</ParamValueContainer> |
||||
)} |
||||
</Row> |
||||
) |
||||
})} |
||||
</Container> |
||||
) |
||||
} |
||||
@ -1,25 +0,0 @@ |
||||
import toUpper from 'lodash/toUpper' |
||||
import split from 'lodash/split' |
||||
import size from 'lodash/size' |
||||
|
||||
import pipe from 'lodash/fp/pipe' |
||||
import take from 'lodash/fp/take' |
||||
import join from 'lodash/fp/join' |
||||
import map from 'lodash/fp/map' |
||||
|
||||
export const getTeamAbbr = (teamName: string) => { |
||||
const nameParts = split(teamName, ' ') |
||||
|
||||
return size(nameParts) > 1 |
||||
? pipe( |
||||
map(take(1)), |
||||
join(''), |
||||
toUpper, |
||||
)(nameParts) |
||||
|
||||
: pipe( |
||||
take(3), |
||||
join(''), |
||||
toUpper, |
||||
)(nameParts[0]) |
||||
} |
||||
@ -1,65 +0,0 @@ |
||||
import isUndefined from 'lodash/isUndefined' |
||||
|
||||
import { SportTypes } from 'config' |
||||
|
||||
import { callApi } from 'helpers' |
||||
|
||||
export type Player = { |
||||
birthday: string | null, |
||||
c_country: number, |
||||
c_gender: number, |
||||
club_f_team: number, |
||||
club_shirt_num: number, |
||||
firstname_eng: string, |
||||
firstname_national: string | null, |
||||
firstname_rus: string, |
||||
height: number | null, |
||||
id: number, |
||||
is_gk: boolean, |
||||
lastname_eng: string, |
||||
lastname_national: string | null, |
||||
lastname_rus: string, |
||||
national_f_team: number | null, |
||||
national_shirt_num: number, |
||||
nickname_eng: string | null, |
||||
nickname_rus: string | null, |
||||
weight: number | null, |
||||
} |
||||
|
||||
type DataItem = { |
||||
players: Array<Player>, |
||||
team_id: number, |
||||
} |
||||
|
||||
type Response = { |
||||
data?: Array<DataItem>, |
||||
error?: { |
||||
code: string, |
||||
message: string, |
||||
}, |
||||
} |
||||
|
||||
type GetMatchParticipantsArgs = { |
||||
matchId: number, |
||||
second?: number, |
||||
sportType: SportTypes, |
||||
} |
||||
|
||||
export const getMatchParticipants = async ({ |
||||
matchId, |
||||
second, |
||||
sportType, |
||||
}: GetMatchParticipantsArgs) => { |
||||
const config = { |
||||
method: 'GET', |
||||
} |
||||
|
||||
const response: Response = await callApi({ |
||||
config, |
||||
url: `http://136.243.17.103:8888/ask/participants?sport_id=${sportType}&match_id=${matchId}${isUndefined(second) ? '' : `&second=${second}`}`, |
||||
}) |
||||
|
||||
if (response.error) Promise.reject(response) |
||||
|
||||
return Promise.resolve(response.data || []) |
||||
} |
||||
@ -1,54 +0,0 @@ |
||||
import isUndefined from 'lodash/isUndefined' |
||||
|
||||
import { callApi } from 'helpers' |
||||
|
||||
export type PlayerParam = { |
||||
clickable: boolean, |
||||
data_type: string, |
||||
id: number, |
||||
lexic: number, |
||||
lexica_short: number | null, |
||||
markers: Array<number> | null, |
||||
name_en: string, |
||||
name_ru: string, |
||||
val: number | null, |
||||
} |
||||
|
||||
export type PlayersStats = { |
||||
[playerId: string]: { |
||||
[paramId: string]: PlayerParam, |
||||
}, |
||||
} |
||||
|
||||
type Response = { |
||||
data?: PlayersStats, |
||||
error?: string, |
||||
message?: string, |
||||
} |
||||
|
||||
type GetPlayersStatsArgs = { |
||||
matchId: number, |
||||
second?: number, |
||||
sportName: string, |
||||
teamId: number, |
||||
} |
||||
|
||||
export const getPlayersStats = async ({ |
||||
matchId, |
||||
second, |
||||
sportName, |
||||
teamId, |
||||
}: GetPlayersStatsArgs) => { |
||||
const config = { |
||||
method: 'GET', |
||||
} |
||||
|
||||
const response: Response = await callApi({ |
||||
config, |
||||
url: `http://136.243.17.103:8888/${sportName}/matches/${matchId}/teams/${teamId}/players/stats${isUndefined(second) ? '' : `?second=${second}`}`, |
||||
}) |
||||
|
||||
if (response.error) Promise.reject(response) |
||||
|
||||
return Promise.resolve(response.data || {}) |
||||
} |
||||
@ -1,56 +0,0 @@ |
||||
import isUndefined from 'lodash/isUndefined' |
||||
|
||||
import { callApi } from 'helpers' |
||||
|
||||
export type Param = { |
||||
clickable: boolean, |
||||
data_type: string, |
||||
id: number, |
||||
lexic: number, |
||||
markers: Array<number>, |
||||
name_en: string, |
||||
name_ru: string, |
||||
val: number | null, |
||||
} |
||||
|
||||
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://136.243.17.103:8888/${sportName}/matches/${matchId}/teams/stats?group_num=0${isUndefined(second) ? '' : `&second=${second}`}`, |
||||
}) |
||||
|
||||
if (response.error) Promise.reject(response) |
||||
|
||||
return Promise.resolve(response.data || {}) |
||||
} |
||||
Loading…
Reference in new issue