diff --git a/src/components/SelectFilter/index.tsx b/src/components/SelectFilter/index.tsx index 435a53d3..8f24c661 100644 --- a/src/components/SelectFilter/index.tsx +++ b/src/components/SelectFilter/index.tsx @@ -11,7 +11,7 @@ import { type SportsFilterProps = { onModalOpen?: () => void, open: boolean, - selectItem: TournamentType | undefined, + selectItem: TournamentType | null, withArrow?: boolean, } diff --git a/src/features/HeaderFilters/components/DateFilter/hooks/index.tsx b/src/features/HeaderFilters/components/DateFilter/hooks/index.tsx index e462d1a2..8ef7b9a2 100644 --- a/src/features/HeaderFilters/components/DateFilter/hooks/index.tsx +++ b/src/features/HeaderFilters/components/DateFilter/hooks/index.tsx @@ -24,7 +24,7 @@ export const useDateFilter = () => { setSelectedDate, setSelectedFilters, setSelectedLeague, - setSelectTournament, + setSelectedTournament, } = useHeaderFiltersStore() const { lang } = useLexicsStore() @@ -52,10 +52,11 @@ export const useDateFilter = () => { && parseFilters.selectedLeague[0] !== 'all_competitions') { setIsShowTournament(false) setSelectedLeague(parseFilters.selectedLeague) - setSelectTournament(parseFilters.selectTournament) + setSelectedTournament(parseFilters.selectedTournament) } else { setIsShowTournament(true) setSelectedFilters([]) + setSelectedTournament(null) setSelectedLeague(['all_competitions']) } // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/src/features/HeaderFilters/store/hooks/index.tsx b/src/features/HeaderFilters/store/hooks/index.tsx index e6cbd6c3..4005bf69 100644 --- a/src/features/HeaderFilters/store/hooks/index.tsx +++ b/src/features/HeaderFilters/store/hooks/index.tsx @@ -23,6 +23,14 @@ export const useFilters = () => { key: filterKeys.DATE, validator: isValidDate, }) + const [selectedSport, setSelectedSport] = useState(['all_sports']) + const [selectedLeague, setSelectedLeague] = useState>(['all_competitions']) + const [selectedFilters, setSelectedFilters] = useState>([]) + const [isShowTournament, setIsShowTournament] = useState(true) + const [selectedTournament, setSelectedTournament] = useState(null) + const [sportIds, setSportIds] = useState() + const isTodaySelected = isToday(selectedDate) + const { activeFilters, changeInput, @@ -33,26 +41,22 @@ export const useFilters = () => { closeDropdownList, confirmClear, currentFilters, - filtersList, filtersSize, getDropdownList, handleSetFilters, inputValue, isEmptyFilters, + isFiltersShown, isOpenList, + matchesList, openDropdownList, openPopup, queryParams, - setFilters, - } = useMatchFilters(selectedDate) - const [selectedSport, setSelectedSport] = useState(['all_sports']) - const [selectedLeague, setSelectedLeague] = useState>(['all_competitions']) - const [selectedFilters, setSelectedFilters] = useState>([]) - const [isShowTournament, setIsShowTournament] = useState(true) - const [selectTournament, setSelectTournament] = useState() - const [sportIds, setSportIds] = useState() - const [isFiltersShown, setIsFiltersShown] = useState(true) - const isTodaySelected = isToday(selectedDate) + setTournamentMatches, + } = useMatchFilters({ + selectedDate, + selectedTournament, + }) const resetFilters = useCallback(() => { setIsShowTournament(true) @@ -66,9 +70,9 @@ export const useFilters = () => { useEffect(() => { localStorage.setItem('filters', JSON.stringify({ - selectTournament, selectedDate: selectedDate.getDate(), selectedLeague, + selectedTournament, })) // eslint-disable-next-line }, [selectedLeague]) @@ -83,6 +87,20 @@ export const useFilters = () => { search, ]) + const handleClickBack = useCallback(() => { + setTournamentMatches([]) + clearAllFilters() + setIsShowTournament(true) + setSelectedTournament(null) + setSelectedLeague(['all_competitions']) + }, [ + clearAllFilters, + setTournamentMatches, + setIsShowTournament, + setSelectedTournament, + setSelectedLeague, + ]) + const store = useMemo(() => ({ activeFilters, changeInput, @@ -93,9 +111,9 @@ export const useFilters = () => { closeDropdownList, confirmClear, currentFilters, - filtersList, filtersSize, getDropdownList, + handleClickBack, handleSetFilters, inputValue, isEmptyFilters, @@ -103,39 +121,38 @@ export const useFilters = () => { isOpenList, isShowTournament, isTodaySelected, + matchesList, openDropdownList, openPopup, queryParams, resetFilters, - selectTournament, selectedDate, selectedFilters, selectedLeague, selectedSport, - setFilters, - setIsFiltersShown, + selectedTournament, setIsShowTournament, - setSelectTournament, setSelectedDate, setSelectedFilters, setSelectedLeague, setSelectedSport, + setSelectedTournament, setSportIds, sportIds, updateDate, }), [ activeFilters, - clickCancel, - clickClearAll, - confirmClear, changeInput, clearAllFilters, clearFilters, + clickCancel, + clickClearAll, closeDropdownList, + confirmClear, currentFilters, - filtersList, filtersSize, getDropdownList, + handleClickBack, handleSetFilters, inputValue, isEmptyFilters, @@ -143,23 +160,22 @@ export const useFilters = () => { isOpenList, isShowTournament, isTodaySelected, - openPopup, + matchesList, openDropdownList, + openPopup, queryParams, resetFilters, - selectTournament, selectedDate, selectedFilters, selectedLeague, selectedSport, - setFilters, - setIsFiltersShown, + selectedTournament, setIsShowTournament, - setSelectTournament, setSelectedDate, setSelectedFilters, setSelectedLeague, setSelectedSport, + setSelectedTournament, setSportIds, sportIds, updateDate, diff --git a/src/features/HeaderFilters/store/hooks/useMatchFilters.tsx b/src/features/HeaderFilters/store/hooks/useMatchFilters.tsx index 35126857..93e69f61 100644 --- a/src/features/HeaderFilters/store/hooks/useMatchFilters.tsx +++ b/src/features/HeaderFilters/store/hooks/useMatchFilters.tsx @@ -33,6 +33,7 @@ import { Match, TQueryParams, } from 'requests' +import type { TournamentType } from 'requests/getMatches/types' const MATCHES_LIMIT = 1000 const OFFSET = 0 @@ -47,23 +48,31 @@ const getDate = (date: Date) => format(date, 'yyyy-MM-dd') export type TActiveFilters = { [key: string]: Array, } + export type TDefaultType = { id: number, name_eng: string, name_rus: string, } -export const useMatchFilters = (selectedDate: Date) => { - const [filtersList, setFiltersList] = useState>([]) +type TUseMatchFilters = { + selectedDate: Date, + selectedTournament: TournamentType | null, +} + +const DEFAULT_FILTERS = {} + +export const useMatchFilters = ({ + selectedDate, + selectedTournament, +}: TUseMatchFilters) => { + const [matchesList, setMatchesList] = useState>([]) + const [tournamentMatches, setTournamentMatches] = useState>([]) const [isOpenList, setOpenList] = useState('') - const [activeFilters, setActiveFilters] = useState({}) + const [activeFilters, setActiveFilters] = useState(DEFAULT_FILTERS) const [inputValue, setInputValue] = useState('') const [openPopup, setOpenPopup] = useState(false) - const setFilters = (filters: Array) => { - setFiltersList(filters) - } - const openDropdownList = (title: string) => () => { setOpenList(title === isOpenList ? '' : title) } @@ -71,6 +80,12 @@ export const useMatchFilters = (selectedDate: Date) => { const closeDropdownList = () => { setOpenList('') } + + const clearAllFilters = () => { + setInputValue('') + setActiveFilters(DEFAULT_FILTERS) + } + const fetchMatches = useCallback( (limit: number, offset: number) => getHomeMatches({ date: getDate(selectedDate), @@ -82,46 +97,84 @@ export const useMatchFilters = (selectedDate: Date) => { ) useEffect(() => { - fetchMatches(MATCHES_LIMIT, OFFSET).then((resp) => setFiltersList(resp.broadcast)) - // eslint-disable-next-line react-hooks/exhaustive-deps + clearAllFilters() + setMatchesList([]) + setTournamentMatches([]) + + fetchMatches(MATCHES_LIMIT, OFFSET).then(({ broadcast }) => { + setMatchesList(broadcast) + }) + // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedDate]) - const getDropdownList = (filterName: string, queryString: string) => { + useEffect(() => { + if (selectedTournament) { + setTournamentMatches( + filter(matchesList, + (match) => match.tournament.id === selectedTournament.id), + ) + } + }, [ + matchesList, + selectedTournament, + ]) + + const matchesForFilters = useMemo(() => ( + selectedTournament ? tournamentMatches : matchesList), + [ + matchesList, + selectedTournament, + tournamentMatches, + ]) + + const getDropdownList = useCallback((filterName: string, queryString: string) => { switch (filterName) { case 'gender': - return getGender(filtersList) + return getGender(matchesForFilters) case 'youth_age': - return getAge(filtersList) + return getAge(matchesForFilters) case 'division': - return getDivision(filtersList) + return getDivision(matchesForFilters) case 'main_team': - return getMainTeam(filtersList) + return getMainTeam(matchesForFilters) case 'arena': - return getArena(filtersList, queryString) + return getArena(matchesForFilters, queryString) case 'round': - return getRound(filtersList) + return getRound(matchesForFilters) case 'sport': - return getSport(filtersList) + return getSport(matchesForFilters) default: return [] } - } + }, [matchesForFilters]) - const filters = useMemo(() => { + const currentFilters = useMemo(() => { const arr = [] - if (some(filtersList, (item) => !isNil(item.sport))) arr.push('sport') - if (some(filtersList, (item) => !isNil(item.arena?.id))) arr.push('arena') - if (some(filtersList, (item) => !isNil(item.round?.id))) arr.push('round') - if (some(filtersList, (item) => !isNil(item.team1?.main_team) || !isNil(item.team2?.main_team))) arr.push('main_team') - if (some(filtersList, (item) => !isNil(item.team1?.youth_age) || !isNil(item.team2?.youth_age))) arr.push('youth_age') - if (some(filtersList, (item) => !isNil(item.team1?.gender) || !isNil(item.team2?.gender))) arr.push('gender') - if (some(filtersList, (item) => !isNil(item.team1?.division?.id) || !isNil(item.team2?.division?.id))) arr.push('division') - return arr - }, [filtersList]) - - const filtersWitnMoreThenOneValue = filter(filters, (filterName) => ( - getDropdownList(filterName, '').length > 1 - )) + + const hasArena = some(matchesForFilters, (item) => !isNil(item.arena?.id)) + const hasRound = some(matchesForFilters, (item) => !isNil(item.round?.id)) + const hasSport = some(matchesForFilters, (item) => !isNil(item.sport)) + const hasMainTeam = some(matchesForFilters, + (item) => !isNil(item.team1?.main_team) || !isNil(item.team2?.main_team)) + const hasGender = some(matchesForFilters, + (item) => !isNil(item.team1?.gender) || !isNil(item.team2?.gender)) + const hasDivision = some(matchesForFilters, + (item) => !isNil(item.team1?.division?.id) || !isNil(item.team2?.division?.id)) + const hasYouthAge = some(matchesForFilters, + (item) => !isNil(item.team1?.youth_age) || !isNil(item.team2?.youth_age)) + + if (hasSport) arr.push('sport') + if (hasArena) arr.push('arena') + if (hasRound) arr.push('round') + if (hasMainTeam) arr.push('main_team') + if (hasYouthAge) arr.push('youth_age') + if (hasGender) arr.push('gender') + if (hasDivision) arr.push('division') + + return filter(arr, (filterName) => ( + getDropdownList(filterName, '').length > 1 + )) + }, [getDropdownList, matchesForFilters]) const handleSetFilters = (filterName: string, value: number) => { const activeFilter = activeFilters[filterName as keyof typeof activeFilters] @@ -138,6 +191,7 @@ export const useMatchFilters = (selectedDate: Date) => { [filterName]: currentValue, }) } + return setActiveFilters({ ...activeFilters, [filterName]: [value], @@ -147,17 +201,17 @@ export const useMatchFilters = (selectedDate: Date) => { const clearFilters = (filterName: string) => (e: MouseEvent | ChangeEvent) => { e.stopPropagation() e.preventDefault() - return setActiveFilters({ + + if (filterName === 'arena') { + setInputValue('') + } + + setActiveFilters({ ...activeFilters, [filterName]: [], }) } - const clearAllFilters = (e: MouseEvent) => { - e.stopPropagation() - setActiveFilters({}) - } - const isEmptyFilters = every(activeFilters, (filterItem) => isEmpty(filterItem)) const queryParams: TQueryParams = useMemo(() => { @@ -185,7 +239,7 @@ export const useMatchFilters = (selectedDate: Date) => { const confirmClear = (e: MouseEvent) => { setOpenPopup(false) - clearAllFilters(e) + clearAllFilters() } const clickCancel = () => { @@ -198,6 +252,10 @@ export const useMatchFilters = (selectedDate: Date) => { value, ) => result + size(value), 0) + const isFiltersShown = useMemo(() => ( + size(matchesList) < 12 || selectedTournament), + [matchesList, selectedTournament]) + return { activeFilters, changeInput, @@ -207,17 +265,18 @@ export const useMatchFilters = (selectedDate: Date) => { clickClearAll, closeDropdownList, confirmClear, - currentFilters: filtersWitnMoreThenOneValue, - filtersList, + currentFilters, filtersSize, getDropdownList, handleSetFilters, inputValue, isEmptyFilters, + isFiltersShown, isOpenList, + matchesList, openDropdownList, openPopup, queryParams, - setFilters, + setTournamentMatches, } } diff --git a/src/features/HomePage/components/Dropdown/helpers.tsx b/src/features/HomePage/components/Dropdown/helpers.tsx index c0be6591..ec5415e0 100644 --- a/src/features/HomePage/components/Dropdown/helpers.tsx +++ b/src/features/HomePage/components/Dropdown/helpers.tsx @@ -5,12 +5,12 @@ import uniq from 'lodash/uniq' import uniqBy from 'lodash/uniqBy' import flatten from 'lodash/flatten' import compact from 'lodash/compact' -import startsWith from 'lodash/startsWith' +import includes from 'lodash/includes' import toLower from 'lodash/toLower' import { Match } from 'requests' -const checkStartString = (text: string, searchString: string) => startsWith( +const checkString = (text: string, searchString: string) => includes( toLower(text), toLower(searchString), ) @@ -44,8 +44,8 @@ export const getArena = (filterList: Array, inputValue: string) => filter map( filterList, (item) => item.arena, ), (item) => item?.id - && (checkStartString(item.name_eng, inputValue) - || checkStartString(item.name_rus, inputValue)), + && (checkString(item.name_eng, inputValue) + || checkString(item.name_rus, inputValue)), ) export const getSport = (filterList: Array) => uniqBy( diff --git a/src/features/HomePage/components/Dropdown/index.tsx b/src/features/HomePage/components/Dropdown/index.tsx index 59a83888..f259aea9 100644 --- a/src/features/HomePage/components/Dropdown/index.tsx +++ b/src/features/HomePage/components/Dropdown/index.tsx @@ -68,6 +68,7 @@ export const DropDown = ({ onChange={changeInput} onClick={(e) => e.stopPropagation()} placeholder={translate('search')} + value={inputValue} /> )} diff --git a/src/features/HomePage/components/HeaderFilters/index.tsx b/src/features/HomePage/components/HeaderFilters/index.tsx index f82197d3..a0b34a10 100644 --- a/src/features/HomePage/components/HeaderFilters/index.tsx +++ b/src/features/HomePage/components/HeaderFilters/index.tsx @@ -40,19 +40,13 @@ const ClearButton = styled.span` export const HeaderFilters = () => { const { clickClearAll, + handleClickBack, isEmptyFilters, isFiltersShown, isShowTournament, - selectTournament, - setIsShowTournament, - setSelectedLeague, + selectedTournament, } = useHeaderFiltersStore() - const handleClickBack = () => { - setIsShowTournament(true) - setSelectedLeague(['all_competitions']) - } - return ( {!isShowTournament && ( @@ -64,7 +58,7 @@ export const HeaderFilters = () => { /> diff --git a/src/features/HomePage/components/MatchesFilters/index.tsx b/src/features/HomePage/components/MatchesFilters/index.tsx index f7163802..5bdda89f 100644 --- a/src/features/HomePage/components/MatchesFilters/index.tsx +++ b/src/features/HomePage/components/MatchesFilters/index.tsx @@ -54,12 +54,12 @@ export const MatchesFilters = ({ isMobile }: TFiltersProps) => { changeInput, clearFilters, currentFilters, - filtersList, filtersSize, getDropdownList, handleSetFilters, inputValue, isOpenList, + matchesList, openDropdownList, } = useHeaderFiltersStore() @@ -75,7 +75,7 @@ export const MatchesFilters = ({ isMobile }: TFiltersProps) => { ? [currentActiveFilters[0], currentActiveFilters[1]] : currentActiveFilters - const dropdownList = getDropdownList(filterTitle, inputValue) as Array + const dropdownList = getDropdownList(filterTitle, '') as Array return ( { )} - {isOpenList === filterTitle && !isNil(filtersList) && !isMobileDevice && ( + {isOpenList === filterTitle && !isNil(matchesList) && !isMobileDevice && ( { clickClearAll, closeDropdownList, currentFilters, - filtersList, filtersSize, handleSetFilters, inputValue, + isEmptyFilters, isOpenList, + matchesList, } = useHeaderFiltersStore() const openFilters = () => setOpen(true) @@ -56,7 +57,7 @@ export const MobileMatchesFilters = () => { ? ( <> - {filtersSize !== 0 && ( + {!isEmptyFilters && ( @@ -66,7 +67,7 @@ export const MobileMatchesFilters = () => { ) : ( <> - {!isNil(filtersList) && ( + {!isNil(matchesList) && ( { const { + arena, calc, country, country_id, @@ -21,6 +22,7 @@ const prepareMatch = (match: Match) => { live, preview, previewURL, + round, sport, sport_info, storage, @@ -32,6 +34,7 @@ const prepareMatch = (match: Match) => { const date = parseDate(matchDate) return { access: getMatchAccess(match), + arena, calc, countryId: country_id, countryInfo: country, @@ -44,6 +47,7 @@ const prepareMatch = (match: Match) => { live, preview, previewURL, + round, sportInfo: sport_info, sportType: sport, storage, diff --git a/src/features/TournamentList/components/CollapseTournament/index.tsx b/src/features/TournamentList/components/CollapseTournament/index.tsx index 34095d52..7d5167d8 100644 --- a/src/features/TournamentList/components/CollapseTournament/index.tsx +++ b/src/features/TournamentList/components/CollapseTournament/index.tsx @@ -33,10 +33,9 @@ export const CollapseTournament = ({ tournamentMatches, }: TournamentProps) => { const { - setIsFiltersShown, setIsShowTournament, setSelectedLeague, - setSelectTournament, + setSelectedTournament, } = useHeaderFiltersStore() const { countryId, @@ -46,10 +45,9 @@ export const CollapseTournament = ({ } = tournament const handleClick = () => { - setIsFiltersShown(true) setIsShowTournament(false) setSelectedLeague([tournament.id]) - setSelectTournament(tournament) + setSelectedTournament(tournament) } const { countryInfo, sportInfo } = tournamentMatches[0] diff --git a/src/features/TournamentList/index.tsx b/src/features/TournamentList/index.tsx index 4a56bf77..96215326 100644 --- a/src/features/TournamentList/index.tsx +++ b/src/features/TournamentList/index.tsx @@ -1,9 +1,7 @@ -import { useEffect } from 'react' import { useRouteMatch } from 'react-router-dom' import type { Match } from 'features/Matches' import { MatchCard } from 'features/MatchCard' -import { useHeaderFiltersStore } from 'features/HeaderFilters' import type { TournamentType } from 'requests/getMatches/types' @@ -35,19 +33,6 @@ export type TournamentListProps = { export const TournamentList = ({ matches }: TournamentTypeProps) => { const { tournaments, tournamentSort } = useTournaments(matches) const isHomePage = useRouteMatch(PAGES.home)?.isExact - const { setIsFiltersShown } = useHeaderFiltersStore() - - useEffect(() => { - if (isHomePage && matches.length >= 12) { - setIsFiltersShown(false) - } else { - setIsFiltersShown(true) - } - }, [ - isHomePage, - matches.length, - setIsFiltersShown, - ]) switch (true) { case isMobileDevice && isHomePage: