fix(#2556): display of tabs on match or event page
parent
af97087ab7
commit
1cc39c24e2
@ -0,0 +1,55 @@ |
|||||||
|
import { |
||||||
|
useEffect, |
||||||
|
useMemo, |
||||||
|
useState, |
||||||
|
} from 'react' |
||||||
|
|
||||||
|
import { format } from 'date-fns' |
||||||
|
import sortedUniq from 'lodash/sortedUniq' |
||||||
|
import isNull from 'lodash/isNull' |
||||||
|
import sortBy from 'lodash/sortBy' |
||||||
|
|
||||||
|
import type { Match } from 'features/Matches' |
||||||
|
import { prepareMatches } from 'features/Matches/helpers/prepareMatches' |
||||||
|
|
||||||
|
import { getTournamentMatches } from 'requests' |
||||||
|
|
||||||
|
import { parseDate } from 'helpers/parseDate' |
||||||
|
|
||||||
|
import { usePageParams } from 'hooks/usePageParams' |
||||||
|
|
||||||
|
import { TournamentData } from '../types' |
||||||
|
|
||||||
|
export const useTournamentData = (tournamentId: number | null) => { |
||||||
|
const { sportType } = usePageParams() |
||||||
|
|
||||||
|
const [tournamentMatches, setTournamentMatches] = useState<Array<Match>>([]) |
||||||
|
const [matchDates, setMatchDates] = useState<Array<string>>([]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
if (!isNull(tournamentId)) { |
||||||
|
(async () => { |
||||||
|
const matchesBySection = await getTournamentMatches({ |
||||||
|
limit: 1000, |
||||||
|
offset: 0, |
||||||
|
sportType, |
||||||
|
tournamentId, |
||||||
|
}) |
||||||
|
|
||||||
|
const matchDateList = matchesBySection.broadcast.map((match) => ( |
||||||
|
parseDate(match.date) |
||||||
|
)).sort((a, b) => a.getTime() - b.getTime()) |
||||||
|
|
||||||
|
setMatchDates(sortedUniq(matchDateList.map((date) => format(date, 'yyyy-MM-dd')))) |
||||||
|
setTournamentMatches(sortBy(prepareMatches(matchesBySection.broadcast), ['date'])) |
||||||
|
})() |
||||||
|
} |
||||||
|
}, [tournamentId, sportType]) |
||||||
|
|
||||||
|
const tournamentData: TournamentData = useMemo(() => ({ |
||||||
|
matchDates, |
||||||
|
matches: tournamentMatches, |
||||||
|
}), [matchDates, tournamentMatches]) |
||||||
|
|
||||||
|
return { tournamentData } |
||||||
|
} |
||||||
@ -0,0 +1,73 @@ |
|||||||
|
import { |
||||||
|
useCallback, |
||||||
|
useMemo, |
||||||
|
} from 'react' |
||||||
|
|
||||||
|
import { format } from 'date-fns' |
||||||
|
|
||||||
|
import { WeekDay, Wrapper } from './styled' |
||||||
|
|
||||||
|
export type Props = { |
||||||
|
matchDates: Array<string>, |
||||||
|
onDateClick: (date: string) => void, |
||||||
|
selectedDate: string, |
||||||
|
} |
||||||
|
|
||||||
|
export const VideoDate = (props: Props) => { |
||||||
|
const { |
||||||
|
matchDates, |
||||||
|
onDateClick, |
||||||
|
selectedDate, |
||||||
|
} = props |
||||||
|
|
||||||
|
const selectedDateIndex = useMemo(() => ( |
||||||
|
matchDates.findIndex((date) => date === selectedDate) |
||||||
|
), [matchDates, selectedDate]) |
||||||
|
|
||||||
|
const currentDay = useMemo(() => ( |
||||||
|
matchDates.length ? matchDates[selectedDateIndex] : null |
||||||
|
), [matchDates, selectedDateIndex]) |
||||||
|
|
||||||
|
const previousDay = useMemo(() => { |
||||||
|
if (selectedDateIndex !== 0) { |
||||||
|
return matchDates[selectedDateIndex - 1] |
||||||
|
} |
||||||
|
return null |
||||||
|
}, [matchDates, selectedDateIndex]) |
||||||
|
|
||||||
|
const nextDay = useMemo(() => { |
||||||
|
if (selectedDateIndex !== matchDates.length - 1) { |
||||||
|
return matchDates[selectedDateIndex + 1] |
||||||
|
} |
||||||
|
return null |
||||||
|
}, [matchDates, selectedDateIndex]) |
||||||
|
|
||||||
|
const onDayClick = (date: string) => { |
||||||
|
onDateClick?.(date) |
||||||
|
} |
||||||
|
|
||||||
|
const formatDate = useCallback((date: string) => format(Date.parse(date), 'MMM dd, EE'), []) |
||||||
|
|
||||||
|
return ( |
||||||
|
<Wrapper> |
||||||
|
{previousDay && ( |
||||||
|
<WeekDay |
||||||
|
onClick={() => onDayClick(previousDay)} |
||||||
|
>{formatDate(previousDay)} |
||||||
|
</WeekDay> |
||||||
|
)} |
||||||
|
{currentDay && ( |
||||||
|
<WeekDay |
||||||
|
isActive |
||||||
|
>{formatDate(currentDay)} |
||||||
|
</WeekDay> |
||||||
|
)} |
||||||
|
{nextDay && ( |
||||||
|
<WeekDay |
||||||
|
onClick={() => onDayClick(nextDay)} |
||||||
|
>{formatDate(nextDay)} |
||||||
|
</WeekDay> |
||||||
|
)} |
||||||
|
</Wrapper> |
||||||
|
) |
||||||
|
} |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
import styled, { css } from 'styled-components' |
||||||
|
|
||||||
|
export const Wrapper = styled.div` |
||||||
|
color: #FFFFFF; |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
margin-bottom: 10px; |
||||||
|
|
||||||
|
> :not(:last-child) { |
||||||
|
margin-right: 20px; |
||||||
|
} |
||||||
|
` |
||||||
|
|
||||||
|
export const WeekDay = styled.div.attrs(() => ({ |
||||||
|
'aria-hidden': true, |
||||||
|
}))<{isActive?: boolean}>` |
||||||
|
position: relative; |
||||||
|
color: rgba(255, 255, 255, 0.5); |
||||||
|
font-size: 12px; |
||||||
|
white-space: nowrap; |
||||||
|
padding: 5px; |
||||||
|
cursor: pointer; |
||||||
|
|
||||||
|
${({ isActive }) => ( |
||||||
|
isActive |
||||||
|
? css` |
||||||
|
color: #FFFFFF; |
||||||
|
cursor: default; |
||||||
|
|
||||||
|
:after { |
||||||
|
position: absolute; |
||||||
|
bottom: 0; |
||||||
|
left: 0; |
||||||
|
content: ''; |
||||||
|
width: 100%; |
||||||
|
height: 2px; |
||||||
|
background-color: #FFFFFF; |
||||||
|
} |
||||||
|
` |
||||||
|
: '')} |
||||||
|
` |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
import { |
||||||
|
Fragment, |
||||||
|
useMemo, |
||||||
|
useState, |
||||||
|
} from 'react' |
||||||
|
|
||||||
|
import { format } from 'date-fns' |
||||||
|
import map from 'lodash/map' |
||||||
|
|
||||||
|
import { MatchCard } from 'features/MatchCard' |
||||||
|
import { TournamentData } from 'features/MatchPage/types' |
||||||
|
|
||||||
|
import { MatchInfo } from 'requests' |
||||||
|
|
||||||
|
import { parseDate } from 'helpers/parseDate' |
||||||
|
|
||||||
|
import { usePageParams } from 'hooks/usePageParams' |
||||||
|
|
||||||
|
import { VideoDate } from './components/VideoDate/VideoDate' |
||||||
|
import { MatchesWrapper } from './styled' |
||||||
|
|
||||||
|
type Props = { |
||||||
|
profile: MatchInfo, |
||||||
|
tournamentData: TournamentData, |
||||||
|
} |
||||||
|
|
||||||
|
export const TabVideo = ({ |
||||||
|
profile, |
||||||
|
tournamentData, |
||||||
|
}: Props) => { |
||||||
|
const { profileId } = usePageParams() |
||||||
|
const [selectedDate, setSelectedDate] = useState(format(parseDate(profile?.date!), 'yyyy-MM-dd')) |
||||||
|
|
||||||
|
const matches = useMemo(() => ( |
||||||
|
tournamentData.matches.filter((match) => ( |
||||||
|
format(match.date, 'yyyy-MM-dd') === selectedDate && match.id !== profileId |
||||||
|
)) |
||||||
|
), [profileId, selectedDate, tournamentData.matches]) |
||||||
|
|
||||||
|
return ( |
||||||
|
<Fragment> |
||||||
|
<VideoDate |
||||||
|
matchDates={tournamentData.matchDates} |
||||||
|
selectedDate={selectedDate} |
||||||
|
onDateClick={setSelectedDate} |
||||||
|
/> |
||||||
|
<MatchesWrapper> |
||||||
|
{ |
||||||
|
map(matches, (match) => ( |
||||||
|
<MatchCard |
||||||
|
key={match.id} |
||||||
|
match={match} |
||||||
|
/> |
||||||
|
)) |
||||||
|
} |
||||||
|
</MatchesWrapper> |
||||||
|
</Fragment> |
||||||
|
) |
||||||
|
} |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
import styled from 'styled-components' |
||||||
|
|
||||||
|
export const MatchesWrapper = styled.div` |
||||||
|
> :not(:last-child) { |
||||||
|
margin-bottom: 15px; |
||||||
|
} |
||||||
|
` |
||||||
@ -1,4 +1,5 @@ |
|||||||
export enum Tabs { |
export enum Tabs { |
||||||
WATCH, |
WATCH, |
||||||
EVENTS, |
EVENTS, |
||||||
|
VIDEO |
||||||
} |
} |
||||||
|
|||||||
Loading…
Reference in new issue