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 { |
||||
WATCH, |
||||
EVENTS, |
||||
VIDEO |
||||
} |
||||
|
||||
Loading…
Reference in new issue