feat(#2341): add new filters and tournaments

keep-around/26e96e2488f7881e90a1e330fecc8568ebc21871
Andrei Dekterev 4 years ago
parent 556811823d
commit 9c0e1adefb
  1. 16
      Makefile
  2. 1
      src/config/lexics/indexLexics.tsx
  3. 19
      src/features/HeaderFilters/components/DateFilter/hooks/index.tsx
  4. 21
      src/features/HeaderFilters/store/hooks/index.tsx
  5. 24
      src/features/HomePage/components/HeaderFilters/index.tsx
  6. 11
      src/features/HomePage/components/HeaderFilters/styled.tsx
  7. 22
      src/features/MatchesGrid/index.tsx
  8. 2
      src/features/SportsFilter/components/SelectSport/index.tsx
  9. 11
      src/features/SportsFilter/components/SelectSport/styled.tsx
  10. 81
      src/features/SportsFilter/components/SelectSportPopup/index.tsx
  11. 22
      src/features/SportsFilter/index.tsx
  12. 13
      src/features/TournamentList/components/CollapseTournament/index.tsx
  13. 1
      src/features/TournamentList/components/CollapseTournament/styled.tsx
  14. 26
      src/features/TournamentList/hooks.tsx
  15. 6
      src/features/TournamentList/index.tsx

@ -57,6 +57,13 @@ build-e: clean
REACT_APP_STAGE=e-staging \
npm run build
build-f: clean
REACT_APP_TYPE=ott \
REACT_APP_ENV=staging \
REACT_APP_CLIENT=instat \
REACT_APP_STAGE=f-staging \
npm run build
auth-build:
rm -rf build_auth
@ -96,7 +103,7 @@ prod: clean
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@de.instat.tv:/usr/local/www/ott/wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@fr.instat.tv:/usr/local/www/ott/wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@bkup.instat.tv:/usr/local/www/ott/wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@10.0.3.8:/usr/local/www/ott/wwwroot/
preprod: clean
REACT_APP_TYPE=ott \
@ -105,7 +112,7 @@ preprod: clean
REACT_APP_STRIPE_PK=pk_live_ANI76cBhSo69DZUxPmyRVIZW \
npm run build
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-test@test.instat.tv:/usr/local/www/ott-test/wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-test@10.0.3.8:/usr/local/www/ott-test/wwwroot/
facr-prod: clean
REACT_APP_TYPE=ott \
@ -116,7 +123,7 @@ facr-prod: clean
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@de.instat.tv:/usr/local/www/ott/facr-wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@fr.instat.tv:/usr/local/www/ott/facr-wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@bkup.instat.tv:/usr/local/www/ott/facr-wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@10.0.3.8:/usr/local/www/ott/facr-wwwroot/
deploy-all: prod preprod facr-prod
@ -138,6 +145,9 @@ d-stage: build-d
e-stage: build-e
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@staging.instat.tv:/usr/local/www/ott-staging/e-wwwroot/
f-stage: build-f
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/f-wwwroot/
test:
npm test

@ -100,6 +100,7 @@ export const indexLexics = {
football: 6958,
full_game: 13028,
futsal: 17670,
game: 9680,
game_finished: 13026,
game_time: 13029,
games: 15773,

@ -1,5 +1,8 @@
import type { MouseEvent } from 'react'
import { useMemo } from 'react'
import {
MouseEvent,
useEffect,
useMemo,
} from 'react'
import addDays from 'date-fns/addDays'
@ -11,7 +14,12 @@ import { useHeaderFiltersStore } from 'features/HeaderFilters'
import { getDisplayDate, getWeeks } from '../helpers'
export const useDateFilter = () => {
const { selectedDate, setSelectedDate } = useHeaderFiltersStore()
const {
selectedDate,
setIsShowTournament,
setSelectedDate,
} = useHeaderFiltersStore()
const { lang } = useLexicsStore()
const {
close,
@ -28,6 +36,11 @@ export const useDateFilter = () => {
lang,
})
useEffect(() => {
setIsShowTournament(true)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedDate])
const onPreviousClick = () => {
setSelectedDate(addDays(selectedDate, -7))
}

@ -22,16 +22,12 @@ export const useFilters = () => {
serialize: serializeDate,
validator: isValidDate,
})
const [allFilters, setAllFilters] = useState({
selectedFilters: [],
selectedLeague: [],
selectedSports: [],
})
const [selectedSport, setSelectedSport] = useState(['all_sports'])
const [selectedLeague, setSelectedLeague] = useState(['all_competitions'])
const [selectedLeague, setSelectedLeague] = useState<Array<string | number>>(['all_competitions'])
const [selectedFilters, setSelectedFilters] = useState<Array<string>>([])
const [isShowTournament, setIsShowTournament] = useState(true)
const [sportIds, setSportIds] = useState<any>()
const isTodaySelected = isToday(selectedDate)
const resetFilters = useCallback(() => {
@ -49,10 +45,8 @@ export const useFilters = () => {
])
const store = useMemo(() => ({
allFilters,
isShowTournament,
isTodaySelected,
setAllFilters,
selectedDate,
selectedFilters,
selectedLeague,
@ -60,12 +54,13 @@ export const useFilters = () => {
setIsShowTournament,
setSelectedDate,
setSelectedFilters,
setSelectedLeague,
setSelectedSport,
setSportIds,
sportIds,
}), [
allFilters,
isShowTournament,
isTodaySelected,
setAllFilters,
selectedDate,
selectedFilters,
selectedLeague,
@ -73,8 +68,10 @@ export const useFilters = () => {
setIsShowTournament,
setSelectedDate,
setSelectedFilters,
setSelectedLeague,
setSelectedSport,
setSportIds,
sportIds,
])
return store

@ -1,14 +1,22 @@
import { SportsFilter } from 'features/SportsFilter'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
import { T9n } from 'features/T9n'
import { SelectFilter } from 'components/SelectFilter'
import { ScHeaderFilters, ScFilterItemsWrap, ScFilterItem } from './styled'
import {
ScArrow,
ScHeaderFilters,
ScFilterItemsWrap,
ScFilterItem,
} from './styled'
export const HeaderFilters = () => {
const {
isShowTournament,
selectedFilters,
setIsShowTournament,
setSelectedFilters,
setSelectedLeague,
setSelectedSport,
} = useHeaderFiltersStore()
const isActiveFilter = (filterItem: string) => selectedFilters.indexOf(filterItem) >= 0
@ -19,14 +27,22 @@ export const HeaderFilters = () => {
: setSelectedFilters([...selectedFilters, item])
}
const handleClickBack = () => {
setIsShowTournament(true)
setSelectedFilters([])
setSelectedSport(['all_sports'])
setSelectedLeague(['all_competitions'])
}
return (
<ScHeaderFilters>
{!isShowTournament && <ScArrow refIcon='Arrow' color='#ffffff' direction={90} onClick={() => handleClickBack()} />}
<SportsFilter />
<SelectFilter
{/* <SelectFilter
onModalOpen={() => console.log(1)}
open={false}
selectItem='all_competitions'
/>
/> */}
<ScFilterItemsWrap>
<ScFilterItem
className={isActiveFilter('live') ? 'activeLive' : ''}

@ -1,5 +1,7 @@
import styled from 'styled-components/macro'
import { Icon } from 'features/Icon'
export const ScHeaderFilters = styled.div`
display: flex;
flex-direction: row;
@ -39,3 +41,12 @@ export const ScFilterItem = styled.div<Props>`
text-align: center;
padding: 6px 16px;
`
export const ScArrow = styled(Icon)`
margin-right: 15px;
cursor: pointer;
:hover {
/* background-color: rgba(255, 255, 255, 0.5);; */
}
`

@ -16,13 +16,21 @@ type MatchesGridProps = {
export const MatchesGrid = memo(({ matches }: MatchesGridProps) => {
const isHomePage = useRouteMatch(PAGES.home)?.isExact
const { selectedFilters, isShowTournament } = useHeaderFiltersStore()
const filteredMatches = selectedFilters?.length
const {
isShowTournament,
selectedFilters,
selectedLeague,
} = useHeaderFiltersStore()
const filteredMatches = isHomePage && selectedFilters?.length
? matches.filter((match) => (
match.live && selectedFilters.indexOf('live') >= 0)
|| (selectedFilters.indexOf('upcoming') >= 0 && match.date > new Date())
|| (selectedFilters.indexOf('completed') >= 0 && match.is_finished))
((match.live
&& selectedFilters.indexOf('live') >= 0)
|| (selectedFilters.indexOf('upcoming') >= 0 && match.date > new Date())
|| (selectedFilters.indexOf('completed') >= 0 && match.is_finished))))
.filter((match) => ((selectedLeague.indexOf(match.tournament.id) >= 0
|| selectedLeague[0] === 'all_competitions')))
: matches
return (
@ -30,9 +38,7 @@ export const MatchesGrid = memo(({ matches }: MatchesGridProps) => {
{isHomePage && isShowTournament ? (
<TournamentList matches={filteredMatches} />
) : (
filteredMatches.map((match) => (
<MatchCard key={match.id} match={match} />
))
filteredMatches.map((match) => <MatchCard key={match.id} match={match} />)
)}
</Wrapper>
)

@ -13,7 +13,7 @@ export const SelectSport = ({
open,
sport,
}: SportsFilterProps) => (
<ScSportsFilter onClick={onModalOpen}>
<ScSportsFilter onClick={onModalOpen} opacity={sport[0] === 'all_sports' ? 0.5 : 1}>
<T9n t={sport[0]} />
&nbsp;
{sport.length > 1 ? `+ ${sport.length - 1}` : ''}

@ -3,18 +3,23 @@ import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent'
import { Icon } from 'features/Icon'
export const ScSportsFilter = styled.div`
type PropsFilter = {
opacity: number,
}
export const ScSportsFilter = styled.div<PropsFilter>`
display: flex;
color: white;
color: #ffffff;
opacity: ${({ opacity }) => opacity};
font-size: 14px;
width: 30%;
text-transform: uppercase;
font-weight: 700;
cursor: pointer;
align-items: center;
width: 20%;
${isMobileDevice
? css`
width: 30%;
letter-spacing: 0.15rem;
font-size: 10px;
`

@ -1,4 +1,5 @@
import { T9n } from 'features/T9n'
import { getSportLexic } from 'helpers/getSportLexic'
import {
ScBody,
@ -9,48 +10,62 @@ import {
ScSportName,
} from './styled'
const sports = [
'all_sports',
'basketball',
'football_popup',
'handball',
'hockey_popup',
'volleyball',
]
const sports = {
all_sports: 'all_sports',
basketball: 'basketball',
football: 'football_popup',
handball: 'handball',
hockey: 'hockey_popup',
volleyball: 'volleyball',
}
type Props = {
isOpen: boolean,
onModalClose: () => void,
onSportClick: (sport: string) => void,
selectedSport: Array<string>,
sportIds: Array<string>,
}
export const SelectSportPopup = ({
isOpen,
onModalClose,
onSportClick,
selectedSport,
}: Props) => (
<>
<ScModal isOpen={isOpen} withCloseButton close={onModalClose} closeSize={9}>
<ScHeaderGroup>
<ScHeaderTitle>
<T9n t='choose_sport' />
</ScHeaderTitle>
</ScHeaderGroup>
<ScBody>
{sports.map((sport: string) => (
<ScSport
key={sport}
onClick={() => onSportClick(sport)}
className={selectedSport.indexOf(sport) >= 0 ? 'active' : ''}
active={selectedSport.indexOf(sport) >= 0}
>
<ScSportName>
<T9n t={sport} />
</ScSportName>
</ScSport>
))}
</ScBody>
</ScModal>
</>
)
sportIds,
}: Props) => {
const sportNames = sportIds
&& Array.from(sportIds)
.map((id) => String(getSportLexic(Number(id))))
sportNames?.unshift('all_sports')
return (
<>
<ScModal
isOpen={isOpen}
withCloseButton
close={onModalClose}
closeSize={9}
>
<ScHeaderGroup>
<ScHeaderTitle>
<T9n t='choose_sport' />
</ScHeaderTitle>
</ScHeaderGroup>
<ScBody>
{sportNames?.map((sport: string) => (
<ScSport
key={sport}
onClick={() => onSportClick(sport)}
className={selectedSport.indexOf(sport) >= 0 ? 'active' : ''}
active={selectedSport.indexOf(sport) >= 0}
>
<ScSportName>
<T9n t={sports[sport as keyof typeof sports]} />
</ScSportName>
</ScSport>
))}
</ScBody>
</ScModal>
</>
)
}

@ -6,18 +6,35 @@ import { SelectSport } from './components/SelectSport'
import { SelectSportPopup } from './components/SelectSportPopup'
export const SportsFilter = () => {
const { selectedSport, setSelectedSport, setIsShowTournament } = useHeaderFiltersStore()
const {
isShowTournament,
selectedSport,
setIsShowTournament,
setSelectedLeague,
setSelectedSport,
sportIds,
} = useHeaderFiltersStore()
const [isOpen, setIsOpen] = useState(false)
const onSportClick = (sport: string) => {
if (!isShowTournament) return
if (sport === 'all_sports') {
setSelectedLeague(['all_competitions'])
setSelectedSport([sport])
} else {
}
if (selectedSport.indexOf(sport) === -1) {
setSelectedSport((prev) => [
...prev.filter((item) => item !== 'all_sports'),
sport,
])
} else {
setSelectedSport((prev) => [
...prev.filter((item) => item !== 'all_sports' && item === sport),
])
}
setSelectedLeague(['all_competitions'])
setIsShowTournament(true)
setIsOpen(false)
}
@ -42,6 +59,7 @@ export const SportsFilter = () => {
isOpen={isOpen}
onModalClose={onModalClose}
selectedSport={selectedSport}
sportIds={sportIds}
/>
</>
)

@ -32,7 +32,11 @@ export const CollapseTournament = ({
tournament,
tournamentMatches,
}: TournamentProps) => {
const { setSelectedSport, setIsShowTournament } = useHeaderFiltersStore()
const {
setIsShowTournament,
setSelectedLeague,
setSelectedSport,
} = useHeaderFiltersStore()
const { isInFavorites } = useUserFavoritesStore()
const {
countryId,
@ -49,6 +53,7 @@ export const CollapseTournament = ({
const sportName = getSportLexic(sportType)
setIsShowTournament(false)
setSelectedSport([sportName])
setSelectedLeague([tournament.id])
}
return (
@ -90,7 +95,11 @@ export const CollapseTournament = ({
<CountMatches>
{tournamentMatches.length}
&nbsp;
<T9n t='games' />
<T9n t={
tournamentMatches.length > 1
? 'games' : 'game'
}
/>
</CountMatches>
</Info>
</CardWrapper>

@ -180,6 +180,7 @@ export const CountMatches = styled.span`
font-size: 10px;
line-height: 16px;
color: #FFFFFF;
text-transform: lowercase;
`
export const TournamentName = styled(Name)`

@ -1,3 +1,4 @@
import { useEffect } from 'react'
import { getSportLexic } from 'helpers/getSportLexic'
import { TournamentListProps } from 'features/TournamentList'
@ -5,7 +6,11 @@ import type { Match } from 'features/Matches'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
export const useTournaments = (matches: Array<Match>) => {
const { selectedSport } = useHeaderFiltersStore()
const {
selectedLeague,
selectedSport,
setSportIds,
} = useHeaderFiltersStore()
const compareSport = (match: Match, sportNames: Array<string>) => {
if (sportNames[0] === 'all_sports') {
@ -15,11 +20,20 @@ export const useTournaments = (matches: Array<Match>) => {
return (sportNames.indexOf(sport) >= 0 || sportNames.indexOf(`${sport}_popup`) >= 0)
}
const compareLeague = (id: number) => {
if (selectedLeague[0] === 'all_competitions') {
return true
}
return (selectedLeague.indexOf(id) >= 0)
}
const tournamentSort: Array<number> = []
const sportIds = new Set<number>([])
const tournaments = matches.reduce((acc: TournamentListProps, match: Match) => {
if (matches.length === 0) return {}
if (!acc[match.tournament.id] && compareSport(match, selectedSport)) {
if (!acc[match.tournament.id] && compareSport(match, selectedSport)
&& compareLeague(match.tournament.id)) {
const tournament = {
...match.tournament,
countryId: match.countryId,
@ -34,7 +48,8 @@ export const useTournaments = (matches: Array<Match>) => {
tournamentMatches: [match],
}
tournamentSort.push(match.tournament.id)
} else if (compareSport(match, selectedSport)) {
sportIds.add(match.sportType)
} else if (compareSport(match, selectedSport) && compareLeague(match.tournament.id)) {
acc[match.tournament.id] = {
...acc[match.tournament.id],
tournament: {
@ -49,6 +64,11 @@ export const useTournaments = (matches: Array<Match>) => {
return acc
}, {})
useEffect(() => {
sportIds && setSportIds(sportIds)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [matches])
return {
tournamentSort,
tournaments,

@ -22,9 +22,9 @@ export type TournamentListProps = {
countryId: number,
live: boolean,
sportType: number,
}
},
tournamentMatches: Array<Match>,
}
},
}
export const TournamentList = ({ matches }: TournamentTypeProps) => {
@ -44,7 +44,7 @@ export const TournamentList = ({ matches }: TournamentTypeProps) => {
))}
</>
)
case isHomePage && matches.length <= 12:
case isHomePage && matches.length >= 12:
return (
<>
{tournamentSort?.map((id) => (

Loading…
Cancel
Save