feat(in-141): matches cards redesign

pull/83/head
Ruslan Khayrullin 3 years ago
parent efd0b5a3cc
commit c16800dc3d
  1. 1
      src/config/lexics/indexLexics.tsx
  2. 22
      src/features/MatchCard/CardFrontside/index.tsx
  3. 23
      src/features/MatchCard/styled.tsx
  4. 13
      src/features/MatchSidePlaylists/components/MatchPlaylists/index.tsx
  5. 92
      src/features/MatchSidePlaylists/components/Matches/components/VideoDate/index.tsx
  6. 52
      src/features/MatchSidePlaylists/components/Matches/components/VideoDate/styled.tsx
  7. 43
      src/features/MatchSidePlaylists/components/Matches/index.tsx
  8. 15
      src/features/MatchSidePlaylists/components/Matches/styled.tsx
  9. 5
      src/features/MatchSidePlaylists/components/TabWatch/index.tsx

@ -28,6 +28,7 @@ const matchPopupLexics = {
match_interviews: 13031,
match_settings: 13490,
no_data: 15397,
other_games: 19997,
others: 19902,
players_episodes: 13398,
playlist_format: 13406,

@ -162,6 +162,17 @@ export const CardFrontside = ({
<Teams isMatchPage={isMatchPage}>
<Team isMatchPage={isMatchPage}>
<NameSignWrapper>
{isMatchPage && (
<TeamLogo
isMatchPage
id={team1.id}
logoUrl={team1.media?.logo_url}
nameAsTitle
altNameObj={team1}
sportType={sportType}
profileType={ProfileTypes.TEAMS}
/>
)}
<TeamName nameObj={team1} />
{team1InFavorites && <FavoriteSign />}
</NameSignWrapper>
@ -169,6 +180,17 @@ export const CardFrontside = ({
</Team>
<Team isMatchPage={isMatchPage}>
<NameSignWrapper>
{isMatchPage && (
<TeamLogo
isMatchPage
id={team2.id}
logoUrl={team2.media?.logo_url}
nameAsTitle
altNameObj={team2}
sportType={sportType}
profileType={ProfileTypes.TEAMS}
/>
)}
<TeamName nameObj={team2} />
{team2InFavorites && <FavoriteSign />}
</NameSignWrapper>

@ -89,9 +89,8 @@ export const PreviewWrapper = styled.div<TPreviewWrapper>`
isMatchPage
? css`
position: absolute;
bottom: 8px;
height: auto;
width: calc(100% - 1.25rem);
inset: 0;
height: 100%;
`
: ''
)}
@ -110,7 +109,6 @@ export const Preview = styled.img<CardProps>`
height: 100%;
object-fit: cover;
opacity: 0.4;
display: ${({ isMatchPage }) => (isMatchPage ? 'none' : 'block')};
`
export const MatchTimeInfo = styled.div<CardProps>`
@ -124,11 +122,10 @@ export const MatchTimeInfo = styled.div<CardProps>`
${({ isMatchPage }) => (
isMatchPage
? css`
position: initial;
padding: 0;
top: auto;
bottom: 0.519rem;
flex-direction: row-reverse;
justify-content: flex-end;
align-items: center;
`
: ''
)}
@ -186,10 +183,12 @@ export const Time = styled.span`
`
export const Info = styled.div<CardProps>`
position: relative;
display: flex;
flex-direction: column;
padding: ${({ isMatchPage }) => (isMatchPage ? '0 5px 5px 0' : '0.85rem 0.472rem 0 0.519rem')};
color: #fff;
z-index: 1;
${isMobileDevice
? css`
@ -284,7 +283,7 @@ export const TeamLogos = styled.div<CardProps>`
z-index: 1;
`
export const TeamLogo = styled(ProfileLogo)`
export const TeamLogo = styled(ProfileLogo)<CardProps>`
width: 33%;
max-height: 100%;
@ -297,6 +296,14 @@ export const TeamLogo = styled(ProfileLogo)`
width: 30%;
`
: ''};
${({ isMatchPage }) => (isMatchPage
? css`
width: 18px;
margin-right: 5px;
`
: '')
}
`
export const BuyMatchBadge = styled.span<CardProps>`

@ -15,7 +15,7 @@ import { T9n } from 'features/T9n'
import { PlayButton } from '../PlayButton'
export const LIST_ITEM_INDENT = 12
export const LIST_INDENT = 30
type Props = {
live?: boolean,
@ -24,18 +24,25 @@ type Props = {
selectedMathPlaylist?: PlaylistOption,
}
const List = styled.ul``
const List = styled.ul`
margin-bottom: ${LIST_INDENT}px;
`
const Item = styled.li`
margin-bottom: ${LIST_ITEM_INDENT}px;
margin-bottom: 12px;
width: 100%;
height: 36px;
${isMobileDevice
? css`
height: 32px;
margin-bottom: 9px;
`
: ''};
:last-child {
margin-bottom: 0;
}
`
export const MatchPlaylists = forwardRef(

@ -1,92 +0,0 @@
import { useCallback, useMemo } from 'react'
import { format } from 'date-fns'
import { parseDate } from 'helpers/parseDate'
import { WeekDay, Wrapper } from './styled'
export type Props = {
isInitialDateHidden: boolean,
matchDates: Array<string>,
onDateClick: (date: string) => void,
profileDate: string,
selectedDate: string,
}
export const VideoDate = (props: Props) => {
const {
isInitialDateHidden,
matchDates,
onDateClick,
profileDate,
selectedDate,
} = props
const selectedDateIndex = useMemo(() => (
matchDates.findIndex((date) => date === selectedDate)
), [matchDates, selectedDate])
const lastDateIndex = matchDates.length - 1
const initialDateIndex = useMemo(() => (
matchDates.findIndex((date) => date === profileDate)
), [matchDates, profileDate])
const currentDay = useMemo(() => (
matchDates.length && !(isInitialDateHidden && selectedDateIndex === initialDateIndex)
? matchDates[selectedDateIndex]
: null
), [initialDateIndex, isInitialDateHidden, matchDates, selectedDateIndex])
const previousDay = useMemo(() => {
if (selectedDateIndex !== 0) {
if (isInitialDateHidden && selectedDateIndex - 1 === initialDateIndex) {
return selectedDateIndex - 1 !== lastDateIndex ? matchDates[selectedDateIndex - 2] : null
}
return matchDates[selectedDateIndex - 1]
}
return null
}, [initialDateIndex, isInitialDateHidden, lastDateIndex, matchDates, selectedDateIndex])
const nextDay = useMemo(() => {
if (selectedDateIndex !== lastDateIndex) {
if (isInitialDateHidden && selectedDateIndex + 1 === initialDateIndex) {
return selectedDateIndex + 1 !== lastDateIndex ? matchDates[selectedDateIndex + 2] : null
}
return matchDates[selectedDateIndex + 1]
}
return null
}, [initialDateIndex, isInitialDateHidden, lastDateIndex, matchDates, selectedDateIndex])
const onDayClick = (date: string) => {
onDateClick?.(date)
}
const formatDate = useCallback((date: string) => (
format(parseDate(date, 'yyyy-MM-dd'), '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>
)
}

@ -1,52 +0,0 @@
import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent'
export const Wrapper = styled.div`
color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 10px;
> :not(:last-child) {
margin-right: 20px;
}
${isMobileDevice ? css`
@media screen and (orientation: landscape){
> :not(:last-child) {
margin-right: 3px;
}
}
` : ''}
`
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;
}
`
: '')}
`

@ -9,6 +9,7 @@ import {
import { format } from 'date-fns'
import map from 'lodash/map'
import sortBy from 'lodash/sortBy'
import isEmpty from 'lodash/isEmpty'
import { MatchCard } from 'features/MatchCard'
import { TournamentData } from 'features/MatchPage/types'
@ -19,11 +20,11 @@ import { parseDate } from 'helpers/parseDate'
import { usePageParams } from 'hooks/usePageParams'
import { VideoDate } from './components/VideoDate'
import { MatchesWrapper } from './styled'
import { MatchesWrapper, Title } from './styled'
type Props = {
additionalScrollHeight: number,
playListFilter: number,
profile: MatchInfo,
tournamentData: TournamentData,
}
@ -32,39 +33,21 @@ const formatDate = (date: Date) => format(date, 'yyyy-MM-dd')
export const Matches = ({
additionalScrollHeight,
playListFilter,
profile,
tournamentData,
}: Props) => {
const { profileId } = usePageParams()
const profileDate = useMemo(() => (
format(parseDate(profile?.date!), 'yyyy-MM-dd')
formatDate(parseDate(profile?.date!))
), [profile?.date])
const [selectedDate, setSelectedDate] = useState(profileDate)
const matches = useMemo(() => (
tournamentData.matches.filter((match) => (
formatDate(match.date) === selectedDate && match.id !== profileId
formatDate(match.date) === profileDate && match.id !== profileId
))
), [profileId, selectedDate, tournamentData.matches])
const isInitialDateHidden = useMemo(() => {
const someProfileMatch = tournamentData.matches.find((match) => (
formatDate(match.date) === profileDate && match.id !== profileId))
if (!someProfileMatch) {
const profileDateIndex = tournamentData.matchDates.findIndex((date) => date === profileDate)
if (profileDateIndex !== 0) {
setSelectedDate(tournamentData.matchDates[profileDateIndex - 1])
} else {
setSelectedDate(tournamentData.matchDates[profileDateIndex + 1])
}
}
return !someProfileMatch
}, [tournamentData, profileId, profileDate])
), [profileDate, profileId, tournamentData.matches])
const ref = useRef<HTMLDivElement | null>(null)
const [overflow, setOverflow] = useState(false)
@ -77,19 +60,13 @@ export const Matches = ({
const hasScroll = scrollHeight > clientHeight
setOverflow(hasScroll)
}, [ref.current?.clientHeight, selectedDate])
}, [ref.current?.clientHeight])
if (tournamentData.matches.length <= 1) return null
if (isEmpty(matches)) return null
return (
<Fragment>
<VideoDate
isInitialDateHidden={isInitialDateHidden}
matchDates={tournamentData.matchDates}
selectedDate={selectedDate}
profileDate={profileDate}
onDateClick={setSelectedDate}
/>
{playListFilter > 1 && <Title t='other_games' />}
<MatchesWrapper
ref={ref}
hasScroll={overflow}

@ -1,5 +1,8 @@
import styled, { css } from 'styled-components/macro'
import { customScrollbar } from 'features/Common'
import { T9n } from 'features/T9n'
import { isMobileDevice } from '../../../../config/userAgent'
type MatchesWrapperProps = {
@ -9,7 +12,7 @@ type MatchesWrapperProps = {
export const MatchesWrapper = styled.div<MatchesWrapperProps>`
overflow-y: auto;
max-height: calc(100vh - 165px - ${({ additionalScrollHeight }) => additionalScrollHeight}px);
max-height: calc(100vh - 200px - ${({ additionalScrollHeight }) => additionalScrollHeight}px);
padding-right: ${({ hasScroll }) => (hasScroll ? '10px' : '')};
> * {
@ -25,3 +28,13 @@ export const MatchesWrapper = styled.div<MatchesWrapperProps>`
max-height: initial;
` : ''}
`
export const Title = styled(T9n)`
display: flex;
justify-content: center;
margin-bottom: 15px;
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
color: rgba(255, 255, 255, 0.5);
`

@ -15,7 +15,7 @@ import type {
import type { MatchInfo } from 'requests'
import { DropdownSection } from '../DropdownSection'
import { MatchPlaylists, LIST_ITEM_INDENT } from '../MatchPlaylists'
import { MatchPlaylists, LIST_INDENT } from '../MatchPlaylists'
import { SideInterviews } from '../SideInterviews'
import { Matches } from '../Matches'
@ -38,7 +38,7 @@ export const TabWatch = ({
}: Props) => {
const matchPlaylistsRef = useRef<HTMLUListElement>(null)
const additionalScrollHeight = (matchPlaylistsRef.current?.clientHeight || 0) + LIST_ITEM_INDENT
const additionalScrollHeight = (matchPlaylistsRef.current?.clientHeight || 0) + LIST_INDENT
const filteredPlayListByDuration = useMemo(() => (
filter(playlists.match, (playlist) => (
@ -71,6 +71,7 @@ export const TabWatch = ({
</DropdownSection>
<Matches
profile={profile}
playListFilter={playListFilter}
tournamentData={tournamentData}
additionalScrollHeight={additionalScrollHeight}
/>

Loading…
Cancel
Save