Ott 141 match status filters (#56)
parent
ac57e5c3f8
commit
0785026496
@ -1,69 +0,0 @@ |
||||
import { |
||||
useState, |
||||
useCallback, |
||||
useEffect, |
||||
} from 'react' |
||||
|
||||
import debounce from 'lodash/debounce' |
||||
import format from 'date-fns/format' |
||||
import addDays from 'date-fns/addDays' |
||||
import startOfDay from 'date-fns/startOfDay' |
||||
|
||||
import { getMatches } from 'requests' |
||||
import { useToggle } from 'hooks' |
||||
import { useLexicsStore } from 'features/LexicsStore' |
||||
|
||||
import { getDisplayDate } from '../helpers' |
||||
|
||||
const dateFormat = 'dd/MM/yyyy HH:mm:ss' |
||||
|
||||
export const useDateFilter = () => { |
||||
const { lang } = useLexicsStore() |
||||
const { |
||||
close, |
||||
isOpen, |
||||
open, |
||||
} = useToggle() |
||||
const fetchMatches = useCallback(debounce(getMatches, 300), []) |
||||
const [currentDate, setCurrentDate] = useState(new Date()) |
||||
|
||||
const date = getDisplayDate({ |
||||
date: currentDate, |
||||
lang, |
||||
}) |
||||
|
||||
const onPreviousClick = () => { |
||||
setCurrentDate(addDays(currentDate, -1)) |
||||
} |
||||
|
||||
const onNextClick = () => { |
||||
setCurrentDate(addDays(currentDate, 1)) |
||||
} |
||||
|
||||
const onDateChange = (newDate: Date | null) => { |
||||
if (newDate) { |
||||
setCurrentDate(newDate) |
||||
close() |
||||
} |
||||
} |
||||
|
||||
useEffect(() => { |
||||
const formattedDate = format(startOfDay(currentDate), dateFormat) |
||||
fetchMatches({ |
||||
date: formattedDate, |
||||
sportType: 1, |
||||
tournamentId: 8, |
||||
}) |
||||
}, [fetchMatches, currentDate]) |
||||
|
||||
return { |
||||
close, |
||||
currentDate, |
||||
date, |
||||
isOpen, |
||||
onDateChange, |
||||
onNextClick, |
||||
onPreviousClick, |
||||
open, |
||||
} |
||||
} |
||||
@ -0,0 +1,48 @@ |
||||
import addDays from 'date-fns/addDays' |
||||
|
||||
import { useToggle } from 'hooks' |
||||
import { useLexicsStore } from 'features/LexicsStore' |
||||
import { useHeaderFiltersStore } from 'features/HeaderFilters' |
||||
|
||||
import { getDisplayDate } from '../helpers' |
||||
|
||||
export const useDateFilter = () => { |
||||
const { selectedDate, setSelectedDate } = useHeaderFiltersStore() |
||||
const { lang } = useLexicsStore() |
||||
const { |
||||
close, |
||||
isOpen, |
||||
open, |
||||
} = useToggle() |
||||
|
||||
const date = getDisplayDate({ |
||||
date: selectedDate, |
||||
lang, |
||||
}) |
||||
|
||||
const onPreviousClick = () => { |
||||
setSelectedDate(addDays(selectedDate, -1)) |
||||
} |
||||
|
||||
const onNextClick = () => { |
||||
setSelectedDate(addDays(selectedDate, 1)) |
||||
} |
||||
|
||||
const onDateChange = (newDate: Date | null) => { |
||||
if (newDate) { |
||||
setSelectedDate(newDate) |
||||
close() |
||||
} |
||||
} |
||||
|
||||
return { |
||||
close, |
||||
date, |
||||
isOpen, |
||||
onDateChange, |
||||
onNextClick, |
||||
onPreviousClick, |
||||
open, |
||||
selectedDate, |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@ |
||||
import React from 'react' |
||||
|
||||
import { T9n } from 'features/T9n' |
||||
|
||||
import { MatchStatuses, useHeaderFiltersStore } from '../../store' |
||||
import { |
||||
RadioButtonGroup, |
||||
RadioButton, |
||||
} from './styled' |
||||
|
||||
export const MatchStatusFilter = () => { |
||||
const { selectedMatchStatus, setSelectedMatchStatus } = useHeaderFiltersStore() |
||||
return ( |
||||
<RadioButtonGroup> |
||||
<RadioButton |
||||
selected={selectedMatchStatus === MatchStatuses.Live} |
||||
onClick={() => setSelectedMatchStatus(MatchStatuses.Live)} |
||||
buttonWidth={80} |
||||
> |
||||
<T9n t='match_status_live' /> |
||||
</RadioButton> |
||||
<RadioButton |
||||
selected={selectedMatchStatus === MatchStatuses.Finished} |
||||
onClick={() => setSelectedMatchStatus(MatchStatuses.Finished)} |
||||
buttonWidth={121} |
||||
> |
||||
<T9n t='match_status_finished' /> |
||||
</RadioButton> |
||||
<RadioButton |
||||
selected={selectedMatchStatus === MatchStatuses.Soon} |
||||
onClick={() => setSelectedMatchStatus(MatchStatuses.Soon)} |
||||
buttonWidth={87} |
||||
> |
||||
<T9n t='match_status_soon' /> |
||||
</RadioButton> |
||||
</RadioButtonGroup> |
||||
) |
||||
} |
||||
@ -0,0 +1,47 @@ |
||||
import styled from 'styled-components/macro' |
||||
|
||||
export const RadioButtonGroup = styled.div` |
||||
height: 100%; |
||||
box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3); |
||||
border-radius: 2px; |
||||
overflow: hidden; |
||||
` |
||||
|
||||
type RadioButtonProps = { |
||||
buttonWidth?: number, |
||||
selected?: boolean, |
||||
} |
||||
|
||||
export const RadioButton = styled.button<RadioButtonProps>` |
||||
border: none; |
||||
outline: none; |
||||
height: 100%; |
||||
width: ${({ buttonWidth }) => (buttonWidth ? `${buttonWidth}px` : '')}; |
||||
font-weight: 600; |
||||
font-size: 18px; |
||||
cursor: pointer; |
||||
|
||||
${({ selected }) => ( |
||||
selected |
||||
? ` |
||||
background-color: #666666; |
||||
color: #ffffff; |
||||
` |
||||
: ` |
||||
background-color: #3F3F3F; |
||||
color: #999999; |
||||
|
||||
:hover { |
||||
background-color: #484848; |
||||
} |
||||
` |
||||
)} |
||||
|
||||
:first-child { |
||||
text-transform: uppercase; |
||||
} |
||||
|
||||
:not(:last-child) { |
||||
border-right: 1px solid #222222; |
||||
} |
||||
` |
||||
@ -0,0 +1,5 @@ |
||||
export * from './components/DateFilter' |
||||
export * from './components/MatchStatusFilter' |
||||
export * from './components/SportTypeFilter' |
||||
export * from './components/TournamentFilter' |
||||
export * from './store' |
||||
@ -0,0 +1,69 @@ |
||||
import { |
||||
useMemo, |
||||
useState, |
||||
useEffect, |
||||
useCallback, |
||||
} from 'react' |
||||
|
||||
import debounce from 'lodash/debounce' |
||||
import format from 'date-fns/format' |
||||
import startOfDay from 'date-fns/startOfDay' |
||||
|
||||
import { getMatches } from 'requests' |
||||
|
||||
import { useTournaments } from './useTournaments' |
||||
|
||||
export enum MatchStatuses { |
||||
Live = 1, |
||||
Finished = 2, |
||||
Soon = 3, |
||||
} |
||||
|
||||
export enum SportTypes { |
||||
Football = 1, |
||||
Basketball = 2, |
||||
Hockey = 3, |
||||
} |
||||
|
||||
const dateFormat = 'dd/MM/yyyy HH:mm:ss' |
||||
|
||||
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 fetchMatches = useCallback(debounce(getMatches, 300), []) |
||||
|
||||
// временно здесь запрашиваются матчи при изменении фильтров,
|
||||
// можно эту логику вырезать и вставить в компонент матчей
|
||||
useEffect(() => { |
||||
const formattedDate = format(startOfDay(selectedDate), dateFormat) |
||||
fetchMatches({ |
||||
date: formattedDate, |
||||
matchStatus: selectedMatchStatus, |
||||
sportType: selectedSportType, |
||||
tournamentId: 8, |
||||
}) |
||||
}, [ |
||||
selectedDate, |
||||
selectedMatchStatus, |
||||
selectedSportType, |
||||
fetchMatches, |
||||
]) |
||||
|
||||
const store = useMemo(() => ({ |
||||
selectedDate, |
||||
selectedMatchStatus, |
||||
selectedSportType, |
||||
setSelectedDate, |
||||
setSelectedMatchStatus, |
||||
setSelectedSportTypes, |
||||
tournaments, |
||||
}), [ |
||||
selectedDate, |
||||
selectedMatchStatus, |
||||
selectedSportType, |
||||
tournaments, |
||||
]) |
||||
return store |
||||
} |
||||
@ -0,0 +1,14 @@ |
||||
type TournamentOption = {} |
||||
|
||||
type Tournaments = { |
||||
options: Array<TournamentOption>, |
||||
selected: TournamentOption | null, |
||||
} |
||||
|
||||
const initialState: Tournaments = { |
||||
options: [], |
||||
selected: null, |
||||
} |
||||
|
||||
// доделаем на таске по турнирам
|
||||
export const useTournaments = () => initialState |
||||
@ -0,0 +1,26 @@ |
||||
import type { ReactNode } from 'react' |
||||
import React, { |
||||
useContext, |
||||
createContext, |
||||
} from 'react' |
||||
|
||||
import { useFilters } from './hooks' |
||||
|
||||
export * from './hooks' |
||||
|
||||
type HeaderFiltersStore = ReturnType<typeof useFilters> |
||||
|
||||
const FiltersContext = createContext({} as HeaderFiltersStore) |
||||
|
||||
type Props = { children: ReactNode } |
||||
|
||||
export const HeaderFiltersStore = ({ children }: Props) => { |
||||
const filters = useFilters() |
||||
return ( |
||||
<FiltersContext.Provider value={filters}> |
||||
{children} |
||||
</FiltersContext.Provider> |
||||
) |
||||
} |
||||
|
||||
export const useHeaderFiltersStore = () => useContext(FiltersContext) |
||||
@ -1,5 +0,0 @@ |
||||
import React from 'react' |
||||
|
||||
import { Wrapper } from './styled' |
||||
|
||||
export const MatchStatusFilter = () => <Wrapper /> |
||||
@ -1,3 +0,0 @@ |
||||
import styled from 'styled-components/macro' |
||||
|
||||
export const Wrapper = styled.div`` |
||||
Loading…
Reference in new issue