Ott 143 tournaments dropdown (#62)

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Mirlan 5 years ago committed by GitHub
parent 7c2495daab
commit 1d5b0d5e5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      src/config/procedures.tsx
  2. 6
      src/features/HeaderFilters/components/SportTypeFilter/hooks.tsx
  3. 35
      src/features/HeaderFilters/components/TournamentFilter/helpers.tsx
  4. 58
      src/features/HeaderFilters/components/TournamentFilter/hooks.tsx
  5. 50
      src/features/HeaderFilters/components/TournamentFilter/index.tsx
  6. 83
      src/features/HeaderFilters/components/TournamentFilter/styled.tsx
  7. 71
      src/features/HeaderFilters/components/TournamentList/index.tsx
  8. 22
      src/features/HeaderFilters/components/TournamentList/styled.tsx
  9. 16
      src/features/HeaderFilters/store/hooks/index.tsx
  10. 14
      src/features/HeaderFilters/store/hooks/useTournaments.tsx
  11. 1
      src/features/HomePage/styled.tsx
  12. 41
      src/requests/getSportTournaments.tsx
  13. 1
      src/requests/index.tsx

@ -5,6 +5,7 @@ export const PROCEDURES = {
get_matches: 'get_matches',
get_players_teams_tournaments: 'get_players_teams_tournaments',
get_sport_list: 'get_sport_list',
get_tournament_list: 'get_tournament_list',
get_user_favorites: 'get_user_favorites',
logout_user: 'logout_user',
lst_c_country: 'lst_c_country',

@ -12,7 +12,10 @@ import { CustomOption } from './styled'
export const useSportTypeFilter = () => {
const [sportList, setSportList] = useState<SportList>([])
const { setSelectedSportTypes } = useHeaderFiltersStore()
const {
setSelectedSportTypes,
setSelectedTournamentId,
} = useHeaderFiltersStore()
const {
translate,
@ -35,6 +38,7 @@ export const useSportTypeFilter = () => {
const onSelect = (option: Option | null) => {
if (option) {
setSelectedSportTypes(option.id)
setSelectedTournamentId(null)
}
}

@ -0,0 +1,35 @@
import map from 'lodash/map'
import type { Tournaments } from 'requests'
import { LOGOS_FALLBACKS } from 'config'
import { getLogo, SPORT_TYPES } from 'helpers'
type Name = 'name_rus' | 'name_eng'
type ShortName = 'short_name_rus' | 'short_name_eng'
export const normalizeTournaments = (tournaments: Tournaments, suffix: string) => (
map(tournaments, (tournament) => {
const { c_sport, id } = tournament
const sportType = SPORT_TYPES[c_sport]
const name = tournament[`name_${suffix}` as Name]
const shortName = tournament[`short_name_${suffix}` as ShortName] || name
const country = tournament.country?.[`name_${suffix}` as Name]
const logo = getLogo({
id,
sportType,
type: 'tournaments',
})
return {
country,
fallbackImage: LOGOS_FALLBACKS[sportType].tournaments,
id,
logo,
name,
shortName,
sportType,
}
})
)

@ -0,0 +1,58 @@
import { useEffect, useState } from 'react'
import find from 'lodash/find'
import type { Tournaments } from 'requests'
import { getSportTournaments } from 'requests'
import { useToggle } from 'hooks'
import { useHeaderFiltersStore } from 'features/HeaderFilters'
import { useLexicsStore } from 'features/LexicsStore'
import { normalizeTournaments } from './helpers'
const useTournamentsList = () => {
const { selectedSportType } = useHeaderFiltersStore()
const [list, setList] = useState<Tournaments>([])
useEffect(() => {
setList([])
getSportTournaments(selectedSportType).then(setList)
}, [selectedSportType])
return list
}
export const useTournamentFilter = () => {
const { suffix } = useLexicsStore()
const {
selectedTournamentId,
setSelectedTournamentId,
} = useHeaderFiltersStore()
const {
close,
isOpen,
open,
} = useToggle()
const tournamentList = useTournamentsList()
const tournaments = normalizeTournaments(tournamentList, suffix)
const selectedTournament = find(
tournaments,
(tournament) => tournament.id === selectedTournamentId,
)
const onTournamentSelect = (tournamentId: number) => {
setSelectedTournamentId(tournamentId)
close()
}
return {
close,
isOpen,
onTournamentSelect,
open,
selectedTournament,
tournaments,
}
}

@ -1,5 +1,51 @@
import React from 'react'
import { Wrapper } from './styled'
import { T9n } from 'features/T9n'
import { OutsideClick } from 'features/OutsideClick'
export const TournamentFilter = () => <Wrapper />
import { TournamentList } from '../TournamentList'
import { useTournamentFilter } from './hooks'
import {
Wrapper,
ListWrapper,
DropdownButton,
ButtonTitle,
Arrows,
} from './styled'
export const TournamentFilter = () => {
const {
close,
isOpen,
onTournamentSelect,
open,
selectedTournament,
tournaments,
} = useTournamentFilter()
return (
<Wrapper>
<DropdownButton onClick={open} active={isOpen}>
<ButtonTitle>
{
selectedTournament
? selectedTournament.shortName
: <T9n t='tournament' />
}
</ButtonTitle>
<Arrows active={isOpen} />
</DropdownButton>
{
isOpen && (
<OutsideClick onClick={close}>
<ListWrapper>
<TournamentList
tournaments={tournaments}
onSelect={onTournamentSelect}
/>
</ListWrapper>
</OutsideClick>
)
}
</Wrapper>
)
}

@ -1,3 +1,84 @@
import styled from 'styled-components/macro'
export const Wrapper = styled.div``
import { сustomScrollbar } from 'features/Common'
export const Wrapper = styled.div`
height: 100%;
width: 50%;
position: relative;
`
export const ListWrapper = styled.div`
position: absolute;
left: -100%;
top: calc(100% + 8px);
width: 448px;
height: 456px;
overflow-y: scroll;
${сustomScrollbar}
`
type Props = {
active?: boolean,
}
export const DropdownButton = styled.button<Props>`
position: relative;
height: 100%;
width: 100%;
outline: none;
border: none;
display: flex;
align-items: center;
background-color: #3F3F3F;
font-weight: 600;
font-size: 18px;
cursor: pointer;
border-left: 1px solid #222222;
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
background-size: 12px 12px;
background-repeat: no-repeat;
background-position: 113px;
${({ active }) => (
active
? `
background-color: #666666;
color: #fff;
`
: `
color: #999999;
:hover {
background-color: #484848;
}
`
)}
`
export const ButtonTitle = styled.span`
display: inline-block;
width: 80%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: normal;
`
export const Arrows = styled.span<Props>`
position: absolute;
right: 19px;
display: inline-block;
width: 12px;
height: 12px;
background-repeat: no-repeat;
background-position: center;
${({ active }) => (
active
? 'background-image: url(/images/arrowUp.svg);'
: 'background-image: url(/images/arrowDown.svg);'
)}
`

@ -0,0 +1,71 @@
import React from 'react'
import map from 'lodash/map'
import { SPORT_COLORS } from 'config'
import type { SportType } from 'features/Search/config'
import { useItemsList } from 'features/ItemsList/hooks'
import {
Logo,
LogoWrapper,
ItemInfo,
Name,
SportName,
TeamOrCountry,
Wrapper,
} from 'features/ItemsList/styled'
import { ListItem } from './styled'
type Tournament = {
country?: string,
fallbackImage: string,
id: number,
logo: string,
name: string,
sportType: SportType,
}
type TournamentListProps = {
onSelect: (id: number) => void,
tournaments: Array<Tournament>,
}
export const TournamentList = ({ onSelect, tournaments }: TournamentListProps) => {
const {
onError,
ref,
} = useItemsList()
return (
<Wrapper ref={ref}>
{map(tournaments, ({
country,
fallbackImage,
id,
logo,
name,
sportType,
}) => (
<ListItem key={id} onClick={() => onSelect(id)}>
<LogoWrapper>
<Logo
data-src={logo}
onError={onError(fallbackImage)}
alt={name}
/>
</LogoWrapper>
<ItemInfo>
<Name>{name}</Name>
<SportName
color={SPORT_COLORS[sportType]}
t={sportType}
/>
<TeamOrCountry>{country}</TeamOrCountry>
</ItemInfo>
</ListItem>
))}
</Wrapper>
)
}

@ -0,0 +1,22 @@
import styled from 'styled-components/macro'
import { Item } from 'features/ItemsList/styled'
export const ListItem = styled(Item)`
display: flex;
align-items: center;
width: 100%;
height: 56px;
background-color: #666;
cursor: pointer;
:focus-within,
:hover {
background-color: #999;
outline: none;
}
:focus {
background-color: #999;
}
`

@ -11,8 +11,6 @@ import startOfDay from 'date-fns/startOfDay'
import { getMatches } from 'requests'
import { useTournaments } from './useTournaments'
export enum MatchStatuses {
Live = 1,
Finished = 2,
@ -31,23 +29,26 @@ export const useFilters = () => {
const [selectedDate, setSelectedDate] = useState(new Date())
const [selectedMatchStatus, setSelectedMatchStatus] = useState<MatchStatuses>(MatchStatuses.Live)
const [selectedSportType, setSelectedSportTypes] = useState<SportTypes>(SportTypes.Football)
const tournaments = useTournaments()
const [selectedTournamentId, setSelectedTournamentId] = useState<number | null>(null)
const fetchMatches = useCallback(debounce(getMatches, 300), [])
// временно здесь запрашиваются матчи при изменении фильтров,
// можно эту логику вырезать и вставить в компонент матчей
useEffect(() => {
if (!selectedTournamentId) return
const formattedDate = format(startOfDay(selectedDate), dateFormat)
fetchMatches({
date: formattedDate,
matchStatus: selectedMatchStatus,
sportType: selectedSportType,
tournamentId: 8,
tournamentId: selectedTournamentId,
})
}, [
selectedDate,
selectedMatchStatus,
selectedSportType,
selectedTournamentId,
fetchMatches,
])
@ -55,15 +56,18 @@ export const useFilters = () => {
selectedDate,
selectedMatchStatus,
selectedSportType,
selectedTournamentId,
setSelectedDate,
setSelectedMatchStatus,
setSelectedSportTypes,
tournaments,
setSelectedTournamentId,
}), [
selectedDate,
selectedMatchStatus,
selectedSportType,
tournaments,
selectedTournamentId,
setSelectedTournamentId,
])
return store
}

@ -1,14 +0,0 @@
type TournamentOption = {}
type Tournaments = {
options: Array<TournamentOption>,
selected: TournamentOption | null,
}
const initialState: Tournaments = {
options: [],
selected: null,
}
// доделаем на таске по турнирам
export const useTournaments = () => initialState

@ -4,4 +4,5 @@ export const FilterWrapper = styled.div`
width: 288px;
height: 48px;
margin-right: 16px;
display: flex;
`

@ -0,0 +1,41 @@
import { DATA_URL, PROCEDURES } from 'config'
import { callApi, getResponseData } from 'helpers'
import { SportTypes } from 'features/HeaderFilters'
const proc = PROCEDURES.get_tournament_list
type Country = {
id: number,
name_eng: string,
name_rus: string,
}
export type Tournament = {
c_gender: number | null,
c_sport: SportTypes,
c_tournament_type: number,
country: Country,
id: number,
name_eng: string,
name_rus: string,
short_name_eng: string | null,
short_name_rus: string | null,
}
export type Tournaments = Array<Tournament>
export const getSportTournaments = (sportId: number): Promise<Tournaments> => {
const config = {
body: {
params: {
_p_sport: sportId,
},
proc,
},
}
return callApi({
config,
url: DATA_URL,
}).then(getResponseData(proc))
}

@ -8,3 +8,4 @@ export * from './getSearchItems'
export * from './getMatches'
export * from './getUserSportFavs'
export * from './modifyUserSportFavs'
export * from './getSportTournaments'

Loading…
Cancel
Save