You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
spa_instat_tv/src/pages/HighlightsPage/components/FormHighlights/hooks.tsx

439 lines
11 KiB

import {
ChangeEvent,
useEffect,
useRef,
useState,
useMemo,
} from 'react'
import debounce from 'lodash/debounce'
import {
useRecoilState,
useSetRecoilState,
useRecoilValue,
} from 'recoil'
import { useUserFavoritesStore } from 'features/UserFavorites/store'
import type { Match } from 'requests/getMatches/types'
import type { Sport } from 'requests/getSportList'
import { getSounds } from 'requests/getSounds'
import {
getSportTeams,
Team,
SportTeamsType,
} from 'requests/getSportTeams'
import { getPlayerMatches } from 'requests/getMatches/getPlayerMatches'
import { getTeamPlayers, Player } from 'requests/getTeamPlayers'
import { getSearchItems, PlayerTypeFromSearch } from 'requests'
import { getLocalStorageItem } from 'helpers/getLocalStorage'
import { querieKeys } from 'config'
import {
checkedMatches,
playerMatchesState,
dataForPayHighlights,
fetchingMatches,
} from '../../storeHighlightsAtoms'
type SportTypeName = Sport & {
disabled?: boolean,
name: string,
}
type PlayerType = {
firstname_eng: string,
firstname_rus: string,
id: number,
lastname_eng: string,
lastname_rus: string,
name: string,
sport?: number,
sport_id?: number,
team?: {
id: number,
name_eng: string,
name_rus: string,
},
}
type TeamType = {
id: number,
name: string,
name_eng: string,
name_rus: string,
short_name_eng?: string,
short_name_rus?: string,
}
type Sound = {
asset?: string | null,
id: number,
name: string,
}
type StatsType = {
id: number,
name: string,
}
type FormType = {
duration: string,
playerValue: string,
players: Array<string>,
selectedPlayer: PlayerType | null,
selectedSound: Sound | null,
selectedTeam: TeamType | null,
sport: SportTypeName | null,
stats: StatsType,
teamValue: string,
}
const summaryStats = [
{
id: 0,
name: 'No',
},
{
id: 1,
name: 'Yes',
},
]
const defaultValues = {
duration: '2',
playerValue: '',
players: [],
selectedPlayer: null,
selectedSound: null,
selectedTeam: null,
sport: null,
stats: summaryStats[0],
teamValue: '',
}
export const useHighlightsForm = () => {
const { playerHighlight } = useUserFavoritesStore()
const [sports, setSports] = useState<Array<SportTypeName>>([])
const [sounds, setSounds] = useState<Array<Sound>>([])
const [isFetchingTeams, setIsFetchingTeams] = useState(false)
const [teams, setTeams] = useState<Array<TeamType>>([])
const [playersData, setPlayersData] = useState<Array<PlayerType>>([])
const [players, setPlayers] = useState<Array<PlayerType>>([])
const [formState, setFormState] = useState<FormType>(defaultValues)
const [playerMatches, setPlayerMatches] = useRecoilState(playerMatchesState)
const {
checkedMatchesLength,
} = useRecoilValue(checkedMatches)
const setDatahighlights = useSetRecoilState(dataForPayHighlights)
const setIsFetching = useSetRecoilState(fetchingMatches)
const formRef = useRef<HTMLFormElement>(null)
const onSportSelect = (selectedSport: SportTypeName | null) => {
if (selectedSport) {
setFormState((state) => ({
...state,
playerValue: '',
selectedPlayer: null,
selectedTeam: null,
sport: selectedSport,
teamValue: '',
}))
setTeams([])
setPlayers([])
setPlayerMatches([])
}
}
const onTeamSelect = (selectedTeam: TeamType | null) => {
if (selectedTeam) {
setFormState((state) => ({
...state,
duration: '2',
selectedTeam,
}))
}
}
const onPlayerSelect = (selectedPlayer: PlayerType | null) => {
if (!selectedPlayer) return
setFormState((state: FormType) => ({
...state,
duration: '2',
playerValue: '',
selectedPlayer,
teamValue: '',
}))
if (selectedPlayer.team && !formState.selectedTeam) {
setFormState((state: FormType) => ({
...state,
selectedTeam: {
id: selectedPlayer?.team?.id || 0,
name: selectedPlayer?.team?.name_eng || '',
name_eng: selectedPlayer?.team?.name_eng || '',
name_rus: selectedPlayer?.team?.name_rus || '',
},
}))
}
}
const onSoundSelect = (selectedSound: Sound | null) => {
if (!selectedSound) return
setFormState((state) => ({
...state,
selectedSound,
}))
}
const onStatsSelect = (stats: StatsType | null) => {
if (!stats) return
setFormState((state) => ({
...state,
stats,
}))
}
const onChangeMaxDuration = (e: ChangeEvent<HTMLInputElement>) => {
if ((Number(e.target.value) > 0 && Number(e.target.value) <= 100) || e.target.value === '') {
setFormState((state) => ({
...state,
duration: e.target.value,
}))
}
}
const onChangeTeam = (e: ChangeEvent<HTMLInputElement>) => {
if (!e.target.value) {
setTeams([])
}
setFormState((state: FormType) => ({
...state,
playerValue: '',
selectedPlayer: null,
selectedTeam: null,
teamValue: e?.target?.value,
}))
setPlayers([])
setPlayerMatches([])
}
const onChangePlayer = (e: ChangeEvent<HTMLInputElement>) => {
if (!/[A-Za-z\s]/g.test(e.target.value) && e.target.value.length) return
if (!formState.selectedTeam) {
e.target?.value?.length > 3
&& getSearchItems(formState.playerValue)
.then((state) => {
setPlayersData(state?.players?.map((player: PlayerTypeFromSearch) => ({
...player,
name: `${player?.firstname_eng} ${player?.lastname_eng}`,
})) || [])
setPlayers(state?.players?.map((player: PlayerTypeFromSearch) => ({
...player,
name: `${player?.firstname_eng} ${player?.lastname_eng}`,
})) || [])
})
}
setPlayerMatches([])
setFormState((state: FormType) => ({
...state,
playerValue: e?.target?.value,
selectedPlayer: null,
selectedTeam: state.selectedTeam ?? null,
}))
setPlayers(
playersData?.filter(
(player: PlayerType) => player
&& player?.name
?.toLowerCase()
.indexOf(e?.target?.value.toLowerCase()) >= 0,
),
)
}
useEffect(() => {
const sportsList = getLocalStorageItem(querieKeys.sportsList)
const sportsArray = Object.values(sportsList as Array<Sport>)
?.reduce((acc, cur) => {
if ([1, 3].includes(cur.id)) {
return [
...acc, {
...cur,
name: cur.name_eng,
}]
}
return acc
}, [] as Array<SportTypeName>)
setSports(sportsArray)
getSounds()
.then((state) => {
setSounds([{
asset: null,
id: 100,
name: 'No',
},
...state,
])
setFormState((prev) => ({
...prev,
duration: '2',
selectedSound: {
asset: null,
id: 100,
name: 'No',
},
}))
})
}, [])
useEffect(() => {
onSportSelect(sports[0])
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [sports])
useEffect(() => {
if (playerHighlight?.sportType && playerHighlight?.profile) {
// TODO: исправить any
// eslint-disable-next-line
setFormState((state: any) => ({
...state,
selectedPlayer: {
...playerHighlight.profile,
name: `${playerHighlight.profile?.name_eng}`,
},
selectedTeam: playerHighlight?.profile?.additionalInfo,
sport: sports?.find((sportType) => sportType.id === playerHighlight.sportType),
}))
}
}, [sports, playerHighlight, teams])
const fetchTeams = useMemo(
() => debounce(() => {
setIsFetchingTeams(true)
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
formState?.sport?.id
&& getSportTeams(
formState?.sport?.id,
-1,
formState.teamValue,
)
.then(({ data }: SportTeamsType) => {
setTeams(
data?.map((team: Team) => ({
...team,
name: team.name_eng,
})),
)
})
.finally(() => setIsFetchingTeams(false))
}, 1000),
// eslint-disable-next-line react-hooks/exhaustive-deps
[formState.teamValue],
)
useEffect(() => {
if (checkedMatchesLength * 2 >= 2) {
setFormState((prev) => ({
...prev,
duration: (checkedMatchesLength * 2).toString(),
}))
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [checkedMatchesLength])
useEffect(() => {
if (formState?.teamValue?.length >= 3 && formState?.sport) {
fetchTeams()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [formState.teamValue, formState?.sport, playerHighlight])
useEffect(() => {
if (formState?.selectedPlayer?.id && formState?.sport) {
setDatahighlights({
data: {
background_music: formState?.selectedSound?.asset || null,
duration: Number(formState?.duration) * 60,
lang: 'en',
matches: playerMatches?.filter(({ isChecked }) => (isChecked)).map(({ id }) => id),
player_id: formState?.selectedPlayer?.id,
price: checkedMatchesLength * 25,
sport_id: formState?.sport.id,
stats: Boolean(formState?.stats?.id),
},
isDisabledButton: true,
isOpenThanksPopup: false,
})
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [formState, playerMatches])
useEffect(() => {
formState?.selectedTeam?.id
&& getTeamPlayers(
formState?.sport?.id || playerHighlight.sportType,
formState?.selectedTeam?.id
|| playerHighlight?.profile?.additionalInfo?.id,
)
.then((state) => {
setPlayersData(state?.map((player: Player) => ({
...player,
name: `${player?.firstname_eng} ${player?.lastname_eng}`,
})))
setPlayers(state?.map((player: Player) => ({
...player,
name: `${player?.firstname_eng} ${player?.lastname_eng}`,
})))
})
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [formState?.selectedTeam, playerHighlight])
useEffect(() => {
if (!formState?.selectedPlayer || !formState?.sport) return
setIsFetching(true)
formState?.selectedPlayer
&& getPlayerMatches({
limit: 1000,
offset: 0,
p_match_completed: true,
playerId: formState?.selectedPlayer?.id,
sportType: formState?.sport?.id,
sub_only: true,
})
.then(({ broadcast }) => setPlayerMatches(
broadcast.map((match: Match) => ({ ...match, isChecked: false })),
))
.finally(() => setIsFetching(false))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [formState?.selectedPlayer, formState?.selectedTeam])
return {
checkedMatchesLength,
formRef,
formState,
isFetchingTeams,
onChangeMaxDuration,
onChangePlayer,
onChangeTeam,
onPlayerSelect,
onSoundSelect,
onSportSelect,
onStatsSelect,
onTeamSelect,
playerMatches,
players,
sounds,
sports,
summaryStats,
teams,
}
}