Ott 339 matches request (#103)

* refactor(#314): moved matches state from header filters store to specific profiles

* refactor(#314): changed Mathes type import path

Co-authored-by: mirlan.maksitaliev <mirlan.maksitaliev@instatsport.com>
keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Mirlan 5 years ago committed by GitHub
parent 01124ce8ca
commit c2c5e9ad0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 114
      src/features/HeaderFilters/store/hooks/index.tsx
  2. 39
      src/features/HomePage/hooks.tsx
  3. 15
      src/features/HomePage/index.tsx
  4. 2
      src/features/MatchCard/CardFinished/index.tsx
  5. 2
      src/features/MatchCard/CardLive/index.tsx
  6. 4
      src/features/MatchCard/CardSoon/index.tsx
  7. 2
      src/features/MatchCard/index.tsx
  8. 83
      src/features/Matches/hooks.tsx
  9. 19
      src/features/Matches/index.tsx
  10. 2
      src/features/MatchesGrid/index.tsx
  11. 2
      src/features/MatchesSlider/hooks.tsx
  12. 2
      src/features/MatchesSlider/index.tsx
  13. 41
      src/features/TeamPage/hooks.tsx
  14. 3
      src/features/TeamPage/index.tsx
  15. 49
      src/features/TournamentPage/hooks.tsx
  16. 3
      src/features/TournamentPage/index.tsx

@ -1,50 +1,18 @@
import {
useMemo,
useState,
useEffect,
useCallback,
} from 'react'
import { useMemo } from 'react'
import map from 'lodash/map'
import flatten from 'lodash/flatten'
import pipe from 'lodash/fp/pipe'
import fpMap from 'lodash/fp/map'
import fpOrderBy from 'lodash/fp/orderBy'
import isNumber from 'lodash/isNumber'
import format from 'date-fns/format'
import startOfDay from 'date-fns/startOfDay'
import type { Matches, Content } from 'requests'
import { getMatches } from 'requests'
import { SportTypes, SPORT_NAMES } from 'config'
import { getProfileLogo } from 'helpers'
import { SportTypes } from 'config'
import { useQueryParamStore } from 'hooks'
import { useLexicsStore } from 'features/LexicsStore'
import { filterKeys } from '../config'
import { isValidDate } from '../helpers/isValidDate'
import { isValidSportType } from '../helpers/isValidSportType'
import { isValidMatchStatus } from '../helpers/isValidMatchStatus'
type Name = 'name_rus' | 'name_eng'
export type Match = {
date: string,
id: number,
preview: string,
sportName: string,
sportType: number,
streamStatus: number,
team1Logo: string,
team1Name: string,
team1Score: number,
team2Logo: string,
team2Name: string,
team2Score: number,
tournamentName: string,
}
export enum MatchStatuses {
Live = 2,
Finished = 3,
@ -54,9 +22,6 @@ export enum MatchStatuses {
const dateFormat = 'dd/MM/yyyy HH:mm:ss'
export const useFilters = () => {
const {
suffix,
} = useLexicsStore()
const [selectedDate, setSelectedDate] = useQueryParamStore({
defaultValue: new Date(),
key: filterKeys.DATE,
@ -90,79 +55,9 @@ export const useFilters = () => {
validator: isNumber,
})
const [teamId, setTeamId] = useState<number | null>(null)
const [matches, setMatches] = useState<Matches>({
broadcast: [],
features: [],
highlights: [],
isVideoSections: false,
})
// временно здесь запрашиваются матчи при изменении фильтров,
// можно эту логику вырезать и вставить в компонент матчей
useEffect(() => {
const formattedDate = format(startOfDay(selectedDate), dateFormat)
getMatches({
date: formattedDate,
matchStatus: selectedMatchStatus,
sportType: selectedSportTypeId,
teamId,
tournamentId: selectedTournamentId,
}).then(setMatches)
}, [
selectedDate,
selectedMatchStatus,
selectedSportTypeId,
selectedTournamentId,
teamId,
])
const prepareMatches = useCallback((content: Array<Content>) => pipe(
fpMap<Content, Array<Match>>(({
matches: matchesList,
sport,
...rest
}) => map(matchesList, ({
date,
id,
stream_status,
team1,
team2,
}) => ({
date,
id,
preview: '/images/preview.png',
sportName: SPORT_NAMES[sport],
sportType: sport,
streamStatus: stream_status,
team1Logo: getProfileLogo({
id: team1.id,
profileType: 2,
sportType: sport,
}),
team1Name: team1[`name_${suffix}` as Name],
team1Score: team1.score,
team2Logo: getProfileLogo({
id: team2.id,
profileType: 2,
sportType: sport,
}),
team2Name: team2[`name_${suffix}` as Name],
team2Score: team2.score,
tournamentName: rest[`name_${suffix}` as Name],
}))),
flatten,
fpOrderBy((match: Match) => Number(new Date(match.date)), 'desc'),
)(content) as Array<Match>, [suffix])
const store = useMemo(() => ({
matches: {
broadcast: prepareMatches(matches.broadcast),
features: prepareMatches(matches.features),
highlights: prepareMatches(matches.highlights),
isVideoSections: matches.isVideoSections,
},
selectedDate,
selectedDateFormatted: format(startOfDay(selectedDate), dateFormat),
selectedMatchStatus,
selectedSportTypeId,
selectedTournamentId,
@ -170,7 +65,6 @@ export const useFilters = () => {
setSelectedMatchStatus,
setSelectedSportTypeId,
setSelectedTournamentId,
setTeamId,
}), [
selectedDate,
selectedMatchStatus,
@ -180,8 +74,6 @@ export const useFilters = () => {
setSelectedMatchStatus,
setSelectedSportTypeId,
setSelectedTournamentId,
matches,
prepareMatches,
])
return store

@ -0,0 +1,39 @@
import { useEffect, useState } from 'react'
import type { Matches } from 'requests'
import { getMatches } from 'requests'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
export const useHomePage = () => {
const {
selectedDateFormatted,
selectedMatchStatus,
selectedSportTypeId,
selectedTournamentId,
} = useHeaderFiltersStore()
const [matches, setMatches] = useState<Matches>({
broadcast: [],
features: [],
highlights: [],
isVideoSections: false,
})
useEffect(() => {
getMatches({
date: selectedDateFormatted,
matchStatus: selectedMatchStatus,
sportType: selectedSportTypeId,
teamId: null,
tournamentId: selectedTournamentId,
}).then(setMatches)
}, [
selectedDateFormatted,
selectedMatchStatus,
selectedSportTypeId,
selectedTournamentId,
])
return { matches }
}

@ -1,10 +1,15 @@
import React from 'react'
import { Matches } from 'features/Matches'
import { useHomePage } from './hooks'
import { Content } from './styled'
export const HomePage = () => (
<Content>
<Matches />
</Content>
)
export const HomePage = () => {
const { matches } = useHomePage()
return (
<Content>
<Matches matches={matches} />
</Content>
)
}

@ -2,7 +2,7 @@ import React from 'react'
import styled from 'styled-components/macro'
import type { Match } from 'features/HeaderFilters'
import type { Match } from 'features/Matches'
import { getSportColor } from 'helpers'
import { SportName } from 'features/Common'
import { T9n } from 'features/T9n'

@ -7,7 +7,7 @@ import React, {
import styled from 'styled-components/macro'
import differenceInMilliseconds from 'date-fns/differenceInMilliseconds'
import type { Match } from 'features/HeaderFilters'
import type { Match } from 'features/Matches'
import { getSportColor, msToMinutesAndSeconds } from 'helpers'
import { SportName } from 'features/Common'
import { T9n } from 'features/T9n'

@ -4,7 +4,7 @@ import React, { useCallback } from 'react'
import styled from 'styled-components/macro'
import format from 'date-fns/format'
import type { Match } from 'features/HeaderFilters'
import type { Match } from 'features/Matches'
import { getSportColor, handleImageError } from 'helpers'
import { SportName } from 'features/Common'
import { T9n } from 'features/T9n'
@ -35,7 +35,7 @@ const TeamLogos = styled.div`
`
const TeamLogo = styled.img`
width: 70px;
width: 70px;
`
const TeamName = styled(CommonTeamName)`

@ -1,6 +1,6 @@
import React from 'react'
import type { Match } from 'features/HeaderFilters'
import type { Match } from 'features/Matches'
import { MatchStatuses } from 'features/HeaderFilters'
import { CardLive } from './CardLive'

@ -0,0 +1,83 @@
import { useMemo } from 'react'
import map from 'lodash/map'
import flatten from 'lodash/flatten'
import pipe from 'lodash/fp/pipe'
import fpMap from 'lodash/fp/map'
import fpOrderBy from 'lodash/fp/orderBy'
import type { Matches, Content } from 'requests'
import { SPORT_NAMES } from 'config'
import { getProfileLogo } from 'helpers'
import { useLexicsStore } from 'features/LexicsStore'
export type Props = {
matches: Matches,
}
type Name = 'name_rus' | 'name_eng'
export type Match = {
date: string,
id: number,
preview: string,
sportName: string,
sportType: number,
streamStatus: number,
team1Logo: string,
team1Name: string,
team1Score: number,
team2Logo: string,
team2Name: string,
team2Score: number,
tournamentName: string,
}
const prepareMatches = (content: Array<Content>, suffix: string) => pipe(
fpMap<Content, Array<Match>>(({
matches: matchesList,
sport,
...rest
}) => map(matchesList, ({
date,
id,
stream_status,
team1,
team2,
}) => ({
date,
id,
preview: '/images/preview.png',
sportName: SPORT_NAMES[sport],
sportType: sport,
streamStatus: stream_status,
team1Logo: getProfileLogo({
id: team1.id,
profileType: 2,
sportType: sport,
}),
team1Name: team1[`name_${suffix}` as Name],
team1Score: team1.score,
team2Logo: getProfileLogo({
id: team2.id,
profileType: 2,
sportType: sport,
}),
team2Name: team2[`name_${suffix}` as Name],
team2Score: team2.score,
tournamentName: rest[`name_${suffix}` as Name],
}))),
flatten,
fpOrderBy((match: Match) => Number(new Date(match.date)), 'desc'),
)(content) as Array<Match>
export const useMatches = ({ matches }: Props) => {
const { suffix } = useLexicsStore()
return useMemo(() => ({
broadcast: prepareMatches(matches.broadcast, suffix),
features: prepareMatches(matches.features, suffix),
highlights: prepareMatches(matches.highlights, suffix),
isVideoSections: matches.isVideoSections,
}), [suffix, matches])
}

@ -2,22 +2,23 @@ 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 type { Props } from './hooks'
import { useMatches } from './hooks'
import { Title, Section } from './styled'
export const Matches = () => {
export type { Match } from './hooks'
export const Matches = (props: Props) => {
const {
matches: {
broadcast,
features,
highlights,
isVideoSections,
},
} = useHeaderFiltersStore()
broadcast,
features,
highlights,
isVideoSections,
} = useMatches(props)
if (isVideoSections) {
return (

@ -2,7 +2,7 @@ import React from 'react'
import map from 'lodash/map'
import type { Match } from 'features/HeaderFilters'
import type { Match } from 'features/Matches'
import { MatchCard } from 'features/MatchCard'
import { Wrapper } from './styled'

@ -8,7 +8,7 @@ import {
import throttle from 'lodash/throttle'
import type { Match } from 'features/HeaderFilters'
import type { Match } from 'features/Matches'
import { MATCH_CARD_WIDTH, MATCH_CARD_GAP } from 'features/MatchCard/config'
const MATCHES_TO_SCROLL = 6

@ -3,7 +3,7 @@ import React from 'react'
import map from 'lodash/map'
import isEmpty from 'lodash/isEmpty'
import type { Match } from 'features/HeaderFilters'
import type { Match } from 'features/Matches'
import { MatchCard } from 'features/MatchCard'
import { useMatchesSlider } from './hooks'

@ -1,7 +1,7 @@
import { useEffect, useState } from 'react'
import type { TeamInfo } from 'requests'
import { getTeamInfo } from 'requests'
import type { TeamInfo, Matches } from 'requests'
import { getTeamInfo, getMatches } from 'requests'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
import { useLexicsStore } from 'features/LexicsStore'
@ -17,10 +17,17 @@ export const useTeamPage = () => {
const { suffix } = useLexicsStore()
const {
setSelectedSportTypeId,
setTeamId,
selectedDateFormatted,
selectedMatchStatus,
} = useHeaderFiltersStore()
const [matches, setMatches] = useState<Matches>({
broadcast: [],
features: [],
highlights: [],
isVideoSections: false,
})
const {
[`name_${suffix}` as Name]: name = '',
} = teamProfile || {}
@ -30,26 +37,32 @@ export const useTeamPage = () => {
} = teamProfile?.country || {}
useEffect(() => {
setSelectedSportTypeId(sportType)
setTeamId(teamId)
getTeamInfo(sportType, teamId)
.then(setTeamProfile)
return () => {
setSelectedSportTypeId(null)
setTeamId(null)
}
},
[
sportType,
teamId,
setSelectedSportTypeId,
setTeamId,
])
useEffect(() => {
getMatches({
date: selectedDateFormatted,
matchStatus: selectedMatchStatus,
sportType,
teamId,
tournamentId: null,
}).then(setMatches)
}, [
selectedDateFormatted,
selectedMatchStatus,
sportType,
teamId,
])
return {
infoItems: [country],
matches,
name,
sportType,
}

@ -12,6 +12,7 @@ import { Content } from './styled'
export const TeamPage = () => {
const {
infoItems,
matches,
name,
} = useTeamPage()
@ -24,7 +25,7 @@ export const TeamPage = () => {
name={name}
infoItems={infoItems}
/>
<Matches />
<Matches matches={matches} />
</Content>
</Fragment>
)

@ -1,11 +1,10 @@
import type { TournamentInfo } from 'requests'
import { useEffect, useState } from 'react'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
import { useLexicsStore } from 'features/LexicsStore'
import { getTournamentInfo } from 'requests'
import type { TournamentInfo, Matches } from 'requests'
import { getTournamentInfo, getMatches } from 'requests'
import { useSportNameParam, usePageId } from 'hooks'
@ -14,14 +13,21 @@ type Name = 'name_rus' | 'name_eng'
export const useTournamentPage = () => {
const [tournamentProfile, setTournamentProfile] = useState<TournamentInfo>(null)
const { sportType } = useSportNameParam()
const pageId = usePageId()
const tournamentId = usePageId()
const { suffix } = useLexicsStore()
const {
setSelectedSportTypeId,
setSelectedTournamentId,
selectedDateFormatted,
selectedMatchStatus,
} = useHeaderFiltersStore()
const [matches, setMatches] = useState<Matches>({
broadcast: [],
features: [],
highlights: [],
isVideoSections: false,
})
const {
[`name_${suffix}` as Name]: name = '',
} = tournamentProfile || {}
@ -31,26 +37,33 @@ export const useTournamentPage = () => {
} = tournamentProfile?.country || {}
useEffect(() => {
setSelectedSportTypeId(sportType)
setSelectedTournamentId(pageId)
getTournamentInfo(sportType, pageId)
getTournamentInfo(sportType, tournamentId)
.then(setTournamentProfile)
return () => {
setSelectedSportTypeId(null)
setSelectedTournamentId(null)
}
},
[
sportType,
pageId,
setSelectedSportTypeId,
setSelectedTournamentId,
tournamentId,
])
useEffect(() => {
getMatches({
date: selectedDateFormatted,
matchStatus: selectedMatchStatus,
sportType,
teamId: null,
tournamentId,
}).then(setMatches)
}, [
selectedDateFormatted,
selectedMatchStatus,
sportType,
tournamentId,
])
return {
infoItems: [country],
matches,
name,
}
}

@ -12,6 +12,7 @@ import { Content } from './styled'
export const TournamentPage = () => {
const {
infoItems,
matches,
name,
} = useTournamentPage()
@ -24,7 +25,7 @@ export const TournamentPage = () => {
name={name}
infoItems={infoItems}
/>
<Matches />
<Matches matches={matches} />
</Content>
</Fragment>
)

Loading…
Cancel
Save