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