Ott 283 matches list changes (#81)

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Ruslan Khayrullin 5 years ago committed by GitHub
parent 22d93b845c
commit 53cd031d5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/config/lexics/indexLexics.tsx
  2. 12
      src/features/HeaderFilters/components/DateFilter/index.tsx
  3. 8
      src/features/HeaderFilters/components/MatchStatusFilter/styled.tsx
  4. 15
      src/features/HeaderFilters/components/SportTypeFilter/index.tsx
  5. 4
      src/features/HeaderFilters/components/SportTypeFilter/styled.tsx
  6. 9
      src/features/HeaderFilters/components/TournamentFilter/index.tsx
  7. 8
      src/features/HeaderFilters/components/TournamentList/index.tsx
  8. 2
      src/features/HeaderFilters/store/hooks/index.tsx
  9. 45
      src/features/HomePage/components/Matches/hooks.tsx
  10. 22
      src/features/HomePage/components/Matches/index.tsx
  11. 10
      src/features/HomePage/index.tsx
  12. 9
      src/features/HomePage/styled.tsx
  13. 4
      src/features/LanguageSelect/index.tsx
  14. 4
      src/features/LanguageSelect/styled.tsx
  15. 6
      src/features/MatchCard/CardFinished/index.tsx
  16. 0
      src/features/MatchCard/CardFinishedHover/index.tsx
  17. 6
      src/features/MatchCard/CardLive/index.tsx
  18. 0
      src/features/MatchCard/CardLiveHover/index.tsx
  19. 6
      src/features/MatchCard/CardSoon/index.tsx
  20. 0
      src/features/MatchCard/config/index.tsx
  21. 6
      src/features/MatchCard/index.tsx
  22. 3
      src/features/MatchCard/styled.tsx
  23. 59
      src/features/Matches/index.tsx
  24. 14
      src/features/Matches/styled.tsx
  25. 18
      src/features/MatchesGrid/index.tsx
  26. 9
      src/features/MatchesGrid/styled.tsx
  27. 3
      src/features/MatchesSlider/hooks.tsx
  28. 2
      src/features/MatchesSlider/index.tsx
  29. 8
      src/features/Menu/index.tsx
  30. 2
      src/features/Menu/styled.tsx
  31. 6
      src/features/ToggleScore/index.tsx
  32. 2
      src/features/UserFavorites/styled.tsx
  33. 2
      src/requests/getMatches.tsx

@ -2,6 +2,8 @@ import { proceduresLexics } from './procedures'
export const indexLexics = {
basketball: 6960,
broadcast: 13049,
features: 13051,
football: 6958,
full_game: 13028,
game_finished: 13026,
@ -20,6 +22,8 @@ export const indexLexics = {
match_video: 13025,
player: 630,
players_video: 13032,
round_highilights: 13050,
select_language: 1005,
sport: 12993,
team: 658,
tournament: 1009,

@ -29,7 +29,11 @@ export const DateFilter = () => {
} = useDateFilter()
return (
<Wrapper active={isOpen}>
<Button onClick={onPreviousClick} borderLeftRadius={2}>
<Button
onClick={onPreviousClick}
borderLeftRadius={2}
aria-label='Previous day'
>
<ArrowLeft />
</Button>
<OutsideClick onClick={close}>
@ -46,7 +50,11 @@ export const DateFilter = () => {
onChange={onDateChange}
/>
</OutsideClick>
<Button onClick={onNextClick} borderRightRadius={2}>
<Button
onClick={onNextClick}
borderRightRadius={2}
aria-label='Next day'
>
<ArrowRight />
</Button>
</Wrapper>

@ -1,6 +1,8 @@
import styled from 'styled-components/macro'
export const RadioButtonGroup = styled.div`
export const RadioButtonGroup = styled.div.attrs({
role: 'group',
})`
height: 100%;
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3);
border-radius: 2px;
@ -12,7 +14,9 @@ type RadioButtonProps = {
selected?: boolean,
}
export const RadioButton = styled.button<RadioButtonProps>`
export const RadioButton = styled.button.attrs(({ selected }: RadioButtonProps) => ({
'aria-pressed': selected,
}))<RadioButtonProps>`
border: none;
outline: none;
height: 100%;

@ -29,7 +29,12 @@ export const SportTypeFilter = () => {
return (
<Wrapper>
<DropdownButton active={isOpen} onClick={open}>
<DropdownButton
active={isOpen}
onClick={open}
aria-expanded={isOpen}
aria-controls='sportList'
>
<ButtonTitle>
<T9n t={selectedSportType?.lexic || 'sport'} />
</ButtonTitle>
@ -39,7 +44,7 @@ export const SportTypeFilter = () => {
{
isOpen && (
<OutsideClick onClick={close}>
<SportList>
<SportList id='sportList' role='listbox'>
{
map(sportList, ({
id,
@ -48,10 +53,12 @@ export const SportTypeFilter = () => {
}) => (
<CustomOption
key={id}
t={lexic}
image={name}
onClick={() => onSelect(id)}
/>
role='option'
>
<T9n t={lexic} />
</CustomOption>
))
}
</SportList>

@ -1,7 +1,5 @@
import styled from 'styled-components/macro'
import { T9n } from 'features/T9n'
import { DropdownButton } from '../TournamentFilter/styled'
export const Wrapper = styled.div`
@ -27,7 +25,7 @@ export const SportList = styled.ul`
z-index: 1;
`
export const CustomOption = styled(T9n)<{ image: string }>`
export const CustomOption = styled.li<{ image: string }>`
width: 100%;
height: 48px;
display: flex;

@ -24,7 +24,12 @@ export const TournamentFilter = () => {
} = useTournamentFilter()
return (
<Wrapper>
<DropdownButton onClick={open} active={isOpen}>
<DropdownButton
onClick={open}
active={isOpen}
aria-expanded={isOpen}
aria-controls='tournamentsList'
>
<ButtonTitle>
{
selectedTournament
@ -37,7 +42,7 @@ export const TournamentFilter = () => {
{
isOpen && (
<OutsideClick onClick={close}>
<ListWrapper>
<ListWrapper id='tournamentsList'>
<TournamentList
tournaments={tournaments}
onSelect={onTournamentSelect}

@ -37,7 +37,7 @@ export const TournamentList = ({ onSelect, tournaments }: TournamentListProps) =
} = useItemsList()
return (
<Wrapper ref={ref}>
<Wrapper ref={ref} role='listbox'>
{map(tournaments, ({
color,
country,
@ -47,7 +47,11 @@ export const TournamentList = ({ onSelect, tournaments }: TournamentListProps) =
name,
sportLexic,
}) => (
<ListItem key={id} onClick={() => onSelect(id)}>
<ListItem
key={id}
onClick={() => onSelect(id)}
role='option'
>
<LogoWrapper>
<Logo
data-src={logo}

@ -57,6 +57,7 @@ export const useFilters = () => {
broadcast: [],
features: [],
highlights: [],
isVideoSections: false,
})
// временно здесь запрашиваются матчи при изменении фильтров,
@ -119,6 +120,7 @@ export const useFilters = () => {
broadcast: prepareMatches(matches.broadcast),
features: prepareMatches(matches.features),
highlights: prepareMatches(matches.highlights),
isVideoSections: matches.isVideoSections,
}
const store = useMemo(() => ({

@ -1,45 +0,0 @@
import size from 'lodash/size'
import slice from 'lodash/slice'
import chunk from 'lodash/chunk'
import type { Match } from 'features/HeaderFilters'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
const MATCHES_PER_ROW = 6
const ROWS_COUNT = 3
export const useMatches = () => {
const {
matches: {
broadcast: matchesList,
},
} = useHeaderFiltersStore()
const matchesCount = size(matchesList)
let groupedMatches: Array<Array<Match>> = []
/**
* Распределяем матчи в ROWS_COUNT рядов
* Если общее количество матчей не больше количества
* ячеек в сетке размера ROWS_COUNT x MATCHES_PER_ROW,
* заполняем по максимуму каждый ряд с MATCHES_PER_ROW
* матчей в каждом, иначе распределяем поровну
*/
if (matchesCount <= MATCHES_PER_ROW * ROWS_COUNT) {
for (let i = 0; i < ROWS_COUNT; i++) {
const matches = slice(
matchesList,
i * MATCHES_PER_ROW,
i * MATCHES_PER_ROW + MATCHES_PER_ROW,
)
groupedMatches.push(matches)
}
} else {
groupedMatches = chunk(matchesList, Math.ceil(matchesCount / ROWS_COUNT))
}
return {
groupedMatches,
}
}

@ -1,22 +0,0 @@
import React, { Fragment } from 'react'
import map from 'lodash/map'
import { MatchesSlider } from 'features/MatchesSlider'
import { useMatches } from './hooks'
export const Matches = () => {
const { groupedMatches } = useMatches()
return (
<Fragment>
{map(groupedMatches, (matches, i) => (
<MatchesSlider
key={i}
matches={matches}
/>
))}
</Fragment>
)
}

@ -13,14 +13,9 @@ import {
HeaderFiltersStore,
} from 'features/HeaderFilters'
import { UserFavorites } from 'features/UserFavorites'
import { T9n } from 'features/T9n'
import { Matches } from 'features/Matches'
import { Matches } from './components/Matches'
import {
FilterWrapper,
Title,
Content,
} from './styled'
import { FilterWrapper, Content } from './styled'
export const HomePage = () => {
useLexicsConfig(homeLexics)
@ -48,7 +43,6 @@ export const HomePage = () => {
</FilterWrapper>
</Header>
<Content>
<Title><T9n t='video_from_my_subscriptions' /></Title>
<Matches />
</Content>
</MainWrapper>

@ -11,12 +11,3 @@ export const Content = styled.main`
margin-top: 75px;
padding: 0 16px;
`
export const Title = styled.h1`
margin-bottom: 17px;
font-weight: bold;
font-size: 36px;
line-height: 24px;
letter-spacing: -0.02em;
color: #fff;
`

@ -37,9 +37,11 @@ export const LanguageSelect = () => {
onClick={open}
active={isOpen}
title={translate('select_language')}
aria-expanded={isOpen}
aria-controls='langsList'
/>
{isOpen && (
<LangsList>
<LangsList id='langsList'>
{
map(
langsList,

@ -10,10 +10,12 @@ type WorldIconProps = {
active?: boolean,
}
export const WorldIcon = styled.span<WorldIconProps>`
export const WorldIcon = styled.button<WorldIconProps>`
display: block;
width: 18px;
height: 18px;
border: none;
background: none;
background-image: url(/images/worldIcon.svg);
background-position-x: -1px;
cursor: pointer;

@ -68,14 +68,14 @@ export const CardFinished = ({
</PreviewWrapper>
<Info>
<SportName t={sportName} color={getSportColor(sportType)} />
<TournamentName>{tournamentName}</TournamentName>
<TournamentName title={tournamentName}>{tournamentName}</TournamentName>
<Teams>
<Team>
<TeamName>{team1Name}</TeamName>
<TeamName title={team1Name}>{team1Name}</TeamName>
<Score>{team1Score}</Score>
</Team>
<Team>
<TeamName>{team2Name}</TeamName>
<TeamName title={team2Name}>{team2Name}</TeamName>
<Score>{team2Score}</Score>
</Team>
</Teams>

@ -92,14 +92,14 @@ export const CardLive = ({
</PreviewWrapper>
<Info>
<SportName t={sportName} color={getSportColor(sportType)} />
<TournamentName>{tournamentName}</TournamentName>
<TournamentName title={tournamentName}>{tournamentName}</TournamentName>
<Teams>
<Team>
<TeamName>{team1Name}</TeamName>
<TeamName title={team1Name}>{team1Name}</TeamName>
<Score>{team1Score}</Score>
</Team>
<Team>
<TeamName>{team2Name}</TeamName>
<TeamName title={team2Name}>{team2Name}</TeamName>
<Score>{team2Score}</Score>
</Team>
</Teams>

@ -87,13 +87,13 @@ export const CardSoon = ({
</PreviewWrapper>
<Info>
<SportName t={sportName} color={getSportColor(sportType)} />
<TournamentName>{tournamentName}</TournamentName>
<TournamentName title={tournamentName}>{tournamentName}</TournamentName>
<Teams>
<Team>
<TeamName>{team1Name}</TeamName>
<TeamName title={team1Name}>{team1Name}</TeamName>
</Team>
<Team>
<TeamName>{team2Name}</TeamName>
<TeamName title={team2Name}>{team2Name}</TeamName>
</Team>
</Teams>
</Info>

@ -3,9 +3,9 @@ import React from 'react'
import type { Match } from 'features/HeaderFilters'
import { MatchStatuses } from 'features/HeaderFilters'
import { CardLive } from '../CardLive'
import { CardFinished } from '../CardFinished'
import { CardSoon } from '../CardSoon'
import { CardLive } from './CardLive'
import { CardFinished } from './CardFinished'
import { CardSoon } from './CardSoon'
type MatchCardProps = {
match: Match,

@ -2,7 +2,7 @@ import styled from 'styled-components/macro'
import { T9n } from 'features/T9n'
import { MATCH_CARD_WIDTH, MATCH_CARD_GAP } from '../config'
import { MATCH_CARD_WIDTH, MATCH_CARD_GAP } from './config'
export const CardWrapper = styled.li.attrs({
tabIndex: 0,
@ -42,6 +42,7 @@ export const MatchStatus = styled.div`
text-transform: uppercase;
letter-spacing: 0.1em;
text-align: center;
white-space: nowrap;
`
export const Info = styled.div`

@ -0,0 +1,59 @@
import React, { Fragment } from 'react'
import isEmpty from 'lodash/isEmpty'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
import { MatchesSlider } from 'features/MatchesSlider'
import { MatchesGrid } from 'features/MatchesGrid'
import { T9n } from 'features/T9n'
import { Title, Section } from './styled'
export const Matches = () => {
const {
matches: {
broadcast,
features,
highlights,
isVideoSections,
},
} = useHeaderFiltersStore()
if (isVideoSections) {
return (
<Fragment>
{!isEmpty(broadcast) && (
<Section>
<Title><T9n t='broadcast' /></Title>
<MatchesSlider matches={broadcast} />
</Section>
)}
{!isEmpty(highlights) && (
<Section>
<Title><T9n t='round_highilights' /></Title>
<MatchesSlider matches={highlights} />
</Section>
)}
{!isEmpty(features) && (
<Section>
<Title><T9n t='features' /></Title>
<MatchesSlider matches={highlights} />
</Section>
)}
</Fragment>
)
}
return (
<Fragment>
{!isEmpty(broadcast) && (
<Section>
<Title><T9n t='broadcast' /></Title>
<MatchesGrid matches={broadcast} />
</Section>
)}
</Fragment>
)
}

@ -0,0 +1,14 @@
import styled from 'styled-components/macro'
export const Section = styled.section`
margin-bottom: 30px;
`
export const Title = styled.h2`
margin-bottom: 17px;
font-weight: bold;
font-size: 36px;
line-height: 24px;
letter-spacing: -0.02em;
color: #fff;
`

@ -0,0 +1,18 @@
import React from 'react'
import map from 'lodash/map'
import type { Match } from 'features/HeaderFilters'
import { MatchCard } from 'features/MatchCard'
import { Wrapper } from './styled'
type MatchesGridProps = {
matches: Array<Match>,
}
export const MatchesGrid = ({ matches }: MatchesGridProps) => (
<Wrapper>
{map(matches, (match) => <MatchCard key={match.id} match={match} />)}
</Wrapper>
)

@ -0,0 +1,9 @@
import styled from 'styled-components/macro'
import { MATCH_CARD_WIDTH } from 'features/MatchCard/config'
export const Wrapper = styled.ul`
display: grid;
grid-template-columns: repeat(6, ${MATCH_CARD_WIDTH}px);
grid-gap: 13px;
`

@ -7,10 +7,9 @@ import {
} from 'react'
import type { Match } from 'features/HeaderFilters'
import { MATCH_CARD_WIDTH, MATCH_CARD_GAP } from 'features/MatchCard/config'
import { useToggle } from 'hooks'
import { MATCH_CARD_WIDTH, MATCH_CARD_GAP } from './config'
export const useCard = () => {
const {
close,

@ -4,9 +4,9 @@ import map from 'lodash/map'
import isEmpty from 'lodash/isEmpty'
import type { Match } from 'features/HeaderFilters'
import { MatchCard } from 'features/MatchCard'
import { useMatchesSlider } from './hooks'
import { MatchCard } from './components/MatchCard'
import {
Wrapper,
Arrow,

@ -27,9 +27,13 @@ export const Menu = () => {
return (
<OutsideClick onClick={close}>
<Wrapper>
<ToggleButton onClick={open} />
<ToggleButton
onClick={open}
aria-expanded={isOpen}
aria-controls='menuList'
/>
{isOpen && (
<MenuList>
<MenuList id='menuList'>
<MenuItem>
<Icon image='userAccount' />
<StyledLink to={PAGES.useraccount}>

@ -2,7 +2,7 @@ import { Link } from 'react-router-dom'
import styled, { css } from 'styled-components/macro'
export const Wrapper = styled.div`
export const Wrapper = styled.nav`
position: relative;
display: flex;
justify-content: center;

@ -12,7 +12,11 @@ export * from './store'
export const ToggleScore = () => {
const { isVisible, toggle } = useScoreStore()
return (
<Switch onClick={toggle}>
<Switch
onClick={toggle}
role='switch'
aria-checked={isVisible}
>
<Title t='hide_score' />
<Icon isOn={isVisible} />
</Switch>

@ -7,7 +7,7 @@ import { TooltipBlockWrapper } from './TooltipBlock/styled'
export const StyledLink = styled(Link)``
export const UserSportFavWrapper = styled.div`
export const UserSportFavWrapper = styled.aside`
position: fixed;
left: 0;
top: 0;

@ -60,6 +60,7 @@ export type Matches = {
broadcast: Array<Content>,
features: Array<Content>,
highlights: Array<Content>,
isVideoSections: boolean,
}
export const getMatches = async ({
@ -95,5 +96,6 @@ export const getMatches = async ({
broadcast: broadcast.content || [],
features: features.content || [],
highlights: highlights.content || [],
isVideoSections: data.is_video_sections,
}
}

Loading…
Cancel
Save