diff --git a/src/components/AudioPlayer/hooks.tsx b/src/components/AudioPlayer/hooks.tsx index 8ef7b642..e7762416 100644 --- a/src/components/AudioPlayer/hooks.tsx +++ b/src/components/AudioPlayer/hooks.tsx @@ -1,21 +1,24 @@ -import { useEffect, useState } from 'react' -import { getSound } from 'requests/getSound' +import { + SyntheticEvent, + useEffect, + useState, +} from 'react' import { readToken } from 'helpers' -export const useAudioPlayer = (id: number | string) => { +export const useAudioPlayer = (asset: string) => { const [audio, setAudio] = useState() const [playing, setPlaying] = useState(false) - const toggle = () => { + const toggle = (e: SyntheticEvent) => { + e.preventDefault() + e.stopPropagation() setPlaying(!playing) } useEffect(() => { - getSound(id).then(({ asset }) => { - setAudio(new Audio(`${asset}?access_token=${readToken()}`)) - }) + asset && setAudio(new Audio(`${asset}?access_token=${readToken()}`)) // eslint-disable-next-line react-hooks/exhaustive-deps - }, [id]) + }, [asset]) useEffect(() => { if (!audio) return diff --git a/src/components/AudioPlayer/index.tsx b/src/components/AudioPlayer/index.tsx index f3b40aef..97e869bd 100644 --- a/src/components/AudioPlayer/index.tsx +++ b/src/components/AudioPlayer/index.tsx @@ -6,11 +6,11 @@ import { ScAudioContainer } from './styled' import { useAudioPlayer } from './hooks' type AudioPropsType = { - id: number | string, + asset: string, } -export const AudioPlayer = memo(({ id }: AudioPropsType) => { - const { playing, toggle } = useAudioPlayer(id) +export const AudioPlayer = memo(({ asset }: AudioPropsType) => { + const { playing, toggle } = useAudioPlayer(asset) return ( diff --git a/src/features/Combobox/hooks/index.tsx b/src/features/Combobox/hooks/index.tsx index be5ce81a..70d11b37 100644 --- a/src/features/Combobox/hooks/index.tsx +++ b/src/features/Combobox/hooks/index.tsx @@ -98,6 +98,7 @@ export const useCombobox = ({ const target = event.relatedTarget as HTMLElement | null // клик по элементу списка тоже вызывает onBlur // если кликали элемент списка то событие обрабатывает onOptionSelect + if (isOptionClicked(target)) return onBlur?.(event) diff --git a/src/features/Combobox/index.tsx b/src/features/Combobox/index.tsx index 7deb60d1..d553ed18 100644 --- a/src/features/Combobox/index.tsx +++ b/src/features/Combobox/index.tsx @@ -21,6 +21,7 @@ import { Label, LabelTitle, LabelAfter, + LabelBefore, } from 'features/Common/Input/styled' import { Props, Option } from './types' @@ -29,7 +30,6 @@ import { PopOver, ListOption, WrapperIcon, - ScAudioWrap, ScLoaderWrapper, } from './styled' @@ -43,6 +43,7 @@ export const Combobox = (props: Props) => { iconName, label, labelAfter, + labelBefore, labelLexic, labelWidth, loading, @@ -84,6 +85,11 @@ export const Combobox = (props: Props) => { > {labelLexic ? : label} + {labelBefore && ( + + + + )} (props: Props) => { onKeyDown={onKeyDown} placeholder={translate(labelLexic || '')} isUserAccountPage={isUserAccountPage} + style={{ cursor: noSearch ? 'pointer' : '' }} /> {labelAfter && query && {labelAfter}} @@ -118,21 +125,13 @@ export const Combobox = (props: Props) => { {map(options, (option, i) => ( ((e.target as Element)?.id ? onOptionSelect(option.name, e) : '') - } + onClick={(e) => onOptionSelect(option.name, e)} aria-selected={index === i} isHighlighted={index === i} key={option.id} id={option.id.toString()} > {option.name} - {option?.src - ? ( - - - - ) : ''} ))} diff --git a/src/features/Combobox/styled.tsx b/src/features/Combobox/styled.tsx index 957b70b2..11cb03e4 100644 --- a/src/features/Combobox/styled.tsx +++ b/src/features/Combobox/styled.tsx @@ -57,8 +57,7 @@ export const WrapperIcon = styled.span` top: 50%; width: 15px; height: 15px; - transform: translateY(-50%); - + transform: translateY(-60%); ` export const ScAudioWrap = styled.div` diff --git a/src/features/Combobox/types.tsx b/src/features/Combobox/types.tsx index 194a2f6a..3a46b596 100644 --- a/src/features/Combobox/types.tsx +++ b/src/features/Combobox/types.tsx @@ -25,6 +25,7 @@ export type Props = Pick, ( iconName?: string, label?: string, labelAfter?: string | ReactNode, + labelBefore?: string | null, labelLexic?: string, labelWidth?: number, loading?: boolean, diff --git a/src/features/Common/Input/styled.tsx b/src/features/Common/Input/styled.tsx index e80136fa..31ef9756 100644 --- a/src/features/Common/Input/styled.tsx +++ b/src/features/Common/Input/styled.tsx @@ -214,3 +214,8 @@ export const LabelAfter = styled.span` ` : ''}; ` + +export const LabelBefore = styled(LabelAfter)` + margin-left: -40px; + padding-top: 5px; +` diff --git a/src/features/UserAccount/components/ChangeCardPopup/index.tsx b/src/features/UserAccount/components/ChangeCardPopup/index.tsx index c372c747..3a162cc1 100644 --- a/src/features/UserAccount/components/ChangeCardPopup/index.tsx +++ b/src/features/UserAccount/components/ChangeCardPopup/index.tsx @@ -30,6 +30,7 @@ export const ChangeCardPopup = ({ return ( { const { playerHighlight } = useUserFavoritesStore() const [sports, setSports] = useState>([]) + const [sounds, setSounds] = useState([]) const [isFetchingTeams, setIsFetchingTeams] = useState(false) const [teams, setTeams] = useState>([]) const [playersData, setPlayersData] = useState>([]) const [players, setPlayers] = useState>([]) const [formState, setFormState] = useState(defaultValues) const [playerMatches, setPlayerMatches] = useRecoilState(playerMatchesState) + const { + checkedMatchesLength, + } = useRecoilValue(checkedMatches) const setDatahighlights = useSetRecoilState(dataForPayHighlights) const setIsFetching = useSetRecoilState(fetchingMatches) @@ -283,6 +217,25 @@ export const useHighlightsForm = () => { name: sport?.name_eng, })), )) + + getSounds() + .then((state) => { + setSounds([{ + asset: null, + id: 100, + name: 'No', + }, + ...state, + ]) + setFormState((prev) => ({ + ...prev, + selectedSound: { + asset: null, + id: 100, + name: 'No', + }, + })) + }) }, []) useEffect(() => { @@ -328,6 +281,16 @@ export const useHighlightsForm = () => { [formState.teamValue], ) + useEffect(() => { + if (Number(formState?.duration) < checkedMatchesLength * 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() @@ -339,12 +302,12 @@ export const useHighlightsForm = () => { if (formState?.selectedPlayer?.id && formState?.sport) { setDatahighlights({ data: { - background_music: formState?.selectedSound?.src, + 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: playerMatches?.length * 25, + price: checkedMatchesLength * 25, sport_id: formState?.sport.id, stats: Boolean(formState?.stats?.id), }, @@ -378,6 +341,7 @@ export const useHighlightsForm = () => { && getPlayerMatches({ limit: 1000, offset: 0, + p_match_completed: true, playerId: formState?.selectedPlayer?.id, sportType: formState?.sport?.id, sub_only: false, @@ -391,6 +355,7 @@ export const useHighlightsForm = () => { }, [formState?.selectedPlayer, formState?.selectedTeam]) return { + checkedMatchesLength, formRef, formState, handleSubmit, diff --git a/src/pages/HighlightsPage/components/FormHighlights/index.tsx b/src/pages/HighlightsPage/components/FormHighlights/index.tsx index 9a3bf3e3..82495f81 100644 --- a/src/pages/HighlightsPage/components/FormHighlights/index.tsx +++ b/src/pages/HighlightsPage/components/FormHighlights/index.tsx @@ -1,7 +1,6 @@ import { Combobox } from 'features/Combobox' import { Input } from 'features/Common' import { T9n } from 'features/T9n' -import { Icon } from 'features/Icon' import { isMobileDevice } from 'config/userAgent' @@ -115,11 +114,10 @@ export const FormHighlights = ({ price }: PriceInfoType) => { withError={false} wrapperHeight={wrapperHeight} iconName='Search' - className='FormHighlights__select__players' /> { maxLength={500} withError={false} wrapperHeight={wrapperHeight} - labelAfter={} + labelBefore={selectedSound?.asset} className='FormHighlights__input__sound' /> { /> ))) : (Array.from(Array(12)).map(() => ( - + - - + + )))} diff --git a/src/pages/HighlightsPage/components/MatchesHighlights/styled.tsx b/src/pages/HighlightsPage/components/MatchesHighlights/styled.tsx index 654d5822..e584d838 100644 --- a/src/pages/HighlightsPage/components/MatchesHighlights/styled.tsx +++ b/src/pages/HighlightsPage/components/MatchesHighlights/styled.tsx @@ -121,6 +121,19 @@ export const ScFakeWrapper = styled.div` align-items: center; margin-bottom: 14px; position: relative; + + .skeleton { + animation: skeleton-loading 1s linear infinite alternate; + } + + @keyframes skeleton-loading { + 0% { + background-color: rgba(78, 78, 78, 0.4); + } + 100% { + background-color: rgba(78, 78, 78, 1); + } +} ` export const ScLoaderWrapper = styled.div` diff --git a/src/pages/HighlightsPage/components/ThanksPopup/index.tsx b/src/pages/HighlightsPage/components/ThanksPopup/index.tsx index d9e62e58..4afd396b 100644 --- a/src/pages/HighlightsPage/components/ThanksPopup/index.tsx +++ b/src/pages/HighlightsPage/components/ThanksPopup/index.tsx @@ -34,7 +34,7 @@ export const ThanksPopup = () => { { setDataHighlights({ ...dataHighlights, isOpenThanksPopup: false }) - window.location.href = '/' + window.location.reload() }} > Ok diff --git a/src/pages/HighlightsPage/index.tsx b/src/pages/HighlightsPage/index.tsx index 3954f1fa..7629ae7b 100644 --- a/src/pages/HighlightsPage/index.tsx +++ b/src/pages/HighlightsPage/index.tsx @@ -69,7 +69,7 @@ const HighlightsPage = () => { - {isMobileDevice ? ` | $${price}` : ''} + {` | $${price}`} diff --git a/src/pages/HighlightsPage/storeHighlightsAtoms.tsx b/src/pages/HighlightsPage/storeHighlightsAtoms.tsx index 55aa8b2b..ce2b9aa2 100644 --- a/src/pages/HighlightsPage/storeHighlightsAtoms.tsx +++ b/src/pages/HighlightsPage/storeHighlightsAtoms.tsx @@ -1,4 +1,4 @@ -import { atom } from 'recoil' +import { atom, selector } from 'recoil' import type { Match } from 'requests' @@ -10,7 +10,7 @@ export type PlayerMatchesType = Array type DataForm = { data: { - background_music: string | undefined, + background_music: string | null, duration: number, lang: string, matches: Array, @@ -42,3 +42,19 @@ export const fetchingMatches = atom({ default: false, key: 'fetchingMatches', }) + +export const checkedMatches = selector({ + get: ({ get }) => { + const matches = get(playerMatchesState) + const checkedPlayerMatches = matches.filter(({ isChecked }) => isChecked) + const idsCheckedMatches = checkedPlayerMatches.map(({ id }) => id) + const checkedMatchesLength = checkedPlayerMatches.length + + return { + checkedMatchesLength, + checkedPlayerMatches, + idsCheckedMatches, + } + }, + key: 'checkedMatches', +}) diff --git a/src/pages/HighlightsPage/styled.tsx b/src/pages/HighlightsPage/styled.tsx index d2ebfe4e..63bf12f3 100644 --- a/src/pages/HighlightsPage/styled.tsx +++ b/src/pages/HighlightsPage/styled.tsx @@ -59,4 +59,5 @@ export const ScButtonWrap = styled.div<{disabled: boolean}>` export const ScPrice = styled.span` font-weight: 400; font-size: 14px; + margin: auto 0; ` diff --git a/src/requests/getMatches/getPlayerMatches.tsx b/src/requests/getMatches/getPlayerMatches.tsx index aaa44f0b..b0ad4fe1 100644 --- a/src/requests/getMatches/getPlayerMatches.tsx +++ b/src/requests/getMatches/getPlayerMatches.tsx @@ -13,6 +13,7 @@ const proc = PROCEDURES.get_player_matches type Args = { limit: number, offset: number, + p_match_completed?: boolean, playerId: number, sportType: SportTypes, sub_only?: boolean, @@ -21,6 +22,7 @@ type Args = { export const getPlayerMatches = async ({ limit, offset, + p_match_completed, playerId, sportType, sub_only, @@ -29,6 +31,7 @@ export const getPlayerMatches = async ({ body: { params: { _p_limit: limit, + _p_match_completed: p_match_completed, _p_offset: offset, _p_player_id: playerId, _p_sport: sportType, diff --git a/src/requests/getSounds.tsx b/src/requests/getSounds.tsx new file mode 100644 index 00000000..b1110a57 --- /dev/null +++ b/src/requests/getSounds.tsx @@ -0,0 +1,18 @@ +import { callApi } from 'helpers' +import { API_ROOT } from 'config' + +type ResponseSound = { + asset: string, + name: string, +} + +export const getSounds = async (): Promise> => { + const config = { + method: 'GET', + } + + return callApi({ + config, + url: `${API_ROOT}/v1/aws/highlights/music`, + }) +}