fix($#2579): add search to player name,autocomplete for team, fix audio for ios and fix some styles for mobile

keep-around/1461a3b0814b008b76b9697499c74c28b837bee1
Andrei Dekterev 3 years ago
parent d190b869cb
commit 1461a3b081
  1. 28
      Makefile
  2. 25
      src/components/AudioPlayer/hooks.tsx
  3. 6
      src/config/lexics/highlightsPageLexic.tsx
  4. 1
      src/config/lexics/payment.tsx
  5. 2
      src/config/routes.tsx
  6. 70
      src/features/AddCardForm/components/Form/hooks/index.tsx
  7. 2
      src/features/AddCardForm/styled.tsx
  8. 2
      src/features/AuthServiceApp/components/Login/hooks.tsx
  9. 31
      src/features/BuyMatchPopup/components/CardStep/index.tsx
  10. 3
      src/features/BuyMatchPopup/store/hooks/index.tsx
  11. 47
      src/features/BuyMatchPopup/styled.tsx
  12. 14
      src/features/CardsStore/hooks/index.tsx
  13. 9
      src/features/Combobox/index.tsx
  14. 14
      src/features/Combobox/styled.tsx
  15. 1
      src/features/Combobox/types.tsx
  16. 4
      src/features/Common/Input/index.tsx
  17. 35
      src/features/Common/Input/styled.tsx
  18. 6
      src/features/PopupComponents/BaseButton/index.tsx
  19. 2
      src/features/UserAccount/components/ChangeCardPopup/styled.tsx
  20. 1
      src/features/UserAccount/styled.tsx
  21. 1
      src/helpers/dateForIos/index.tsx
  22. 29
      src/hooks/useLocalStorage.tsx
  23. 79
      src/pages/HighlightsPage/components/FormHighlights/hooks.tsx
  24. 10
      src/pages/HighlightsPage/components/FormHighlights/index.tsx
  25. 21
      src/pages/HighlightsPage/components/FormHighlights/styled.tsx
  26. 4
      src/pages/HighlightsPage/components/MatchesHighlights/index.tsx
  27. 5
      src/pages/HighlightsPage/components/MatchesHighlights/styled.tsx
  28. 2
      src/pages/HighlightsPage/components/VideoHighlight/index.tsx
  29. 7
      src/pages/HighlightsPage/components/VideoHighlight/styled.tsx
  30. 51
      src/pages/HighlightsPage/index.tsx
  31. 6
      src/pages/HighlightsPage/storeHighlightsAtoms.tsx
  32. 32
      src/pages/HighlightsPage/styled.tsx
  33. 10
      src/requests/getSearchItems.tsx

@ -130,7 +130,7 @@ prod: clean
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@de.instat.tv:/usr/local/www/ott/wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@de.instat.tv:/usr/local/www/ott/wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@fr.instat.tv:/usr/local/www/ott/wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@fr.instat.tv:/usr/local/www/ott/wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@10.0.3.8:/usr/local/www/ott/wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@137.74.33.74:/usr/local/www/ott/wwwroot/
preprod: clean preprod: clean
REACT_APP_TYPE=ott \ REACT_APP_TYPE=ott \
@ -139,7 +139,7 @@ preprod: clean
REACT_APP_STRIPE_PK=pk_live_ANI76cBhSo69DZUxPmyRVIZW \ REACT_APP_STRIPE_PK=pk_live_ANI76cBhSo69DZUxPmyRVIZW \
npm run build npm run build
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-test@10.0.3.8:/usr/local/www/ott-test/wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-test@137.74.33.74:/usr/local/www/ott-test/wwwroot/
facr-prod: clean facr-prod: clean
REACT_APP_TYPE=ott \ REACT_APP_TYPE=ott \
@ -150,7 +150,7 @@ facr-prod: clean
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@de.instat.tv:/usr/local/www/ott/facr-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@de.instat.tv:/usr/local/www/ott/facr-wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@fr.instat.tv:/usr/local/www/ott/facr-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@fr.instat.tv:/usr/local/www/ott/facr-wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@10.0.3.8:/usr/local/www/ott/facr-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@137.74.33.74:/usr/local/www/ott/facr-wwwroot/
lff-prod: clean lff-prod: clean
REACT_APP_TYPE=ott \ REACT_APP_TYPE=ott \
@ -161,39 +161,39 @@ lff-prod: clean
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@de.instat.tv:/usr/local/www/ott/lff-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@de.instat.tv:/usr/local/www/ott/lff-wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@fr.instat.tv:/usr/local/www/ott/lff-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@fr.instat.tv:/usr/local/www/ott/lff-wwwroot/
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@10.0.3.8:/usr/local/www/ott/lff-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott@137.74.33.74:/usr/local/www/ott/lff-wwwroot/
deploy-all: prod preprod facr-prod lff-prod deploy-all: prod preprod facr-prod lff-prod
stage: build-stage stage: build-stage
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/wwwroot/
a-stage: build-a a-stage: build-a
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/a-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/a-wwwroot/
b-stage: build-b b-stage: build-b
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/b-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/b-wwwroot/
c-stage: build-c c-stage: build-c
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/c-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/c-wwwroot/
d-stage: build-d d-stage: build-d
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/d-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/d-wwwroot/
e-stage: build-e e-stage: build-e
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/e-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/e-wwwroot/
f-stage: build-f f-stage: build-f
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/f-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/f-wwwroot/
g-stage: build-g g-stage: build-g
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/g-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/g-wwwroot/
h-stage: build-h h-stage: build-h
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/h-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/h-wwwroot/
i-stage: build-i i-stage: build-i
rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@10.0.3.8:/usr/local/www/ott-staging/i-wwwroot/ rsync -zavP --delete-before build/ -e 'ssh -p 666' ott-staging@137.74.33.74:/usr/local/www/ott-staging/i-wwwroot/
test: test:
npm test npm test

@ -2,35 +2,36 @@ import {
SyntheticEvent, SyntheticEvent,
useEffect, useEffect,
useState, useState,
useRef,
} from 'react' } from 'react'
import { readToken } from 'helpers' import { readToken } from 'helpers'
export const useAudioPlayer = (asset: string) => { export const useAudioPlayer = (asset: string) => {
const [audio, setAudio] = useState<HTMLAudioElement | null>(null) const audio = useRef<HTMLAudioElement>(new Audio(''))
const [playing, setPlaying] = useState(false) const [playing, setPlaying] = useState(false)
const toggle = (e: SyntheticEvent) => { const toggle = (e: SyntheticEvent) => {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
setPlaying(!playing) if (audio.current.paused) {
audio.current.play()
setPlaying(true)
} else {
audio.current.pause()
setPlaying(false)
}
} }
useEffect(() => { useEffect(() => {
setPlaying(false) setPlaying(false)
audio?.pause() audio.current?.pause()
asset && setAudio(new Audio(`${asset}?access_token=${readToken()}`)) audio.current = new Audio(`${asset}?access_token=${readToken()}`)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [asset]) }, [asset])
useEffect(() => { useEffect(() => {
playing ? audio?.play() : audio?.pause() audio.current?.addEventListener('ended', () => audio.current.pause())
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [playing])
useEffect(() => {
audio?.addEventListener('ended', () => setPlaying(false))
return () => { return () => {
audio?.removeEventListener('ended', () => setPlaying(false)) audio.current?.removeEventListener('ended', () => audio.current.pause())
} }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) }, [])

@ -2,15 +2,19 @@ export const highlightsPageLexic = {
add_summary: 18360, add_summary: 18360,
background_music: 18359, background_music: 18359,
choose_player: 18362, choose_player: 18362,
describe_duration: 18358,
describe_music: 19527,
describe_statistic: 19528,
get_highlights: 18355, get_highlights: 18355,
highlight_will_be_generated: 18364, highlight_will_be_generated: 18364,
matches_highlight: 419, matches_highlight: 419,
maximal_duration: 18358, maximal_duration: 2543,
order_and_buy: 18361, order_and_buy: 18361,
player_highlight: 630, player_highlight: 630,
price: 18356, price: 18356,
purchase_auto_generated: 18363, purchase_auto_generated: 18363,
sport_highlight: 15115, sport_highlight: 15115,
statistics_highlights: 1587,
team_highlight: 657, team_highlight: 657,
watch_demo: 18357, watch_demo: 18357,
} }

@ -8,6 +8,7 @@ export const paymentLexics = {
card_holder_name: 2021, card_holder_name: 2021,
change_card: 14018, change_card: 14018,
city: 15206, city: 15206,
clear: 18313,
country: 835, country: 835,
error_address_latin_letters: 15758, error_address_latin_letters: 15758,
error_can_not_add_card: 14447, error_can_not_add_card: 14447,

@ -4,7 +4,7 @@ import { ENV, isProduction } from './env'
export const APIS = { export const APIS = {
preproduction: { preproduction: {
api: 'https://api-aws-stage.instat.tv:11630', api: 'https://api.instat.tv', // 'https://api-aws-stage.instat.tv:11630',
auth: 'https://auth.instat.tv', auth: 'https://auth.instat.tv',
}, },
production: { production: {

@ -12,6 +12,8 @@ import {
import type { StripeElementChangeEvent } from '@stripe/stripe-js' import type { StripeElementChangeEvent } from '@stripe/stripe-js'
import { import {
CardNumberElement, CardNumberElement,
CardCvcElement,
CardExpiryElement,
useStripe, useStripe,
useElements, useElements,
} from '@stripe/react-stripe-js' } from '@stripe/react-stripe-js'
@ -49,10 +51,12 @@ export enum ElementTypes {
export type Props = { export type Props = {
children?: ReactNode, children?: ReactNode,
clearInputs?: boolean,
initialformOpen?: boolean, initialformOpen?: boolean,
inputsBackground?: string, inputsBackground?: string,
loader?: boolean, loader?: boolean,
onAddSuccess?: () => void, onAddSuccess?: () => void,
setClearInputs?: ((clear: boolean) => void) | undefined,
} }
const inputState = { const inputState = {
@ -70,15 +74,21 @@ const initialState = {
cardNumber: inputState, cardNumber: inputState,
} }
export const useFormSubmit = ({ onAddSuccess }: Props) => { export const useFormSubmit = ({
clearInputs,
onAddSuccess,
setClearInputs,
}: Props) => {
const stripe = useStripe() const stripe = useStripe()
const elements = useElements() const elements = useElements()
const { translate } = useLexicsStore() const { translate } = useLexicsStore()
const { const {
defaultCard, defaultCard,
isHighlightsPage, isHighlightsPage,
lastCard,
onAddCard, onAddCard,
setError: setCardError, setError: setCardError,
setLastCard,
} = useCardsStore() } = useCardsStore()
const [name, setName] = useState('') const [name, setName] = useState('')
const [city, setCity] = useState('') const [city, setCity] = useState('')
@ -91,6 +101,7 @@ export const useFormSubmit = ({ onAddSuccess }: Props) => {
const { const {
onSuccessfulHighlights, onSuccessfulHighlights,
onUnsuccessfulSubscription, onUnsuccessfulSubscription,
setShowClearBtn,
} = useBuyMatchPopupStore() } = useBuyMatchPopupStore()
const { const {
@ -104,8 +115,23 @@ export const useFormSubmit = ({ onAddSuccess }: Props) => {
setCardError('') setCardError('')
}, [setErrorMessage, setCardError]) }, [setErrorMessage, setCardError])
const resetInputs = () => {
resetErrors()
setName('')
setCity('')
setAddress('')
setSelectedCountry(null)
elements?.getElement(CardNumberElement)?.clear()
elements?.getElement(CardCvcElement)?.clear()
elements?.getElement(CardExpiryElement)?.clear()
setInputStates(initialState)
setShowClearBtn(false)
setClearInputs && setClearInputs(false)
}
const setElementTypeState = useCallback((elementType: ElementTypes, value: string) => { const setElementTypeState = useCallback((elementType: ElementTypes, value: string) => {
const elementState = inputStates[elementType] const elementState = inputStates[elementType]
setInputStates({ setInputStates({
[elementType]: { [elementType]: {
...elementState, ...elementState,
@ -154,6 +180,7 @@ export const useFormSubmit = ({ onAddSuccess }: Props) => {
const onInputsChange = (e: StripeElementChangeEvent) => { const onInputsChange = (e: StripeElementChangeEvent) => {
const value = inputStates[e.elementType as ElementTypes] const value = inputStates[e.elementType as ElementTypes]
setInputStates({ [e.elementType]: { ...value, empty: e.empty } }) setInputStates({ [e.elementType]: { ...value, empty: e.empty } })
resetErrors() resetErrors()
} }
@ -172,6 +199,8 @@ export const useFormSubmit = ({ onAddSuccess }: Props) => {
inputStates[elementType].empty && !inputStates[elementType].focused inputStates[elementType].empty && !inputStates[elementType].focused
) )
const allInputEmpty = Object.values(inputStates).every((inputValue) => inputValue.empty)
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => { const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault() e.preventDefault()
resetErrors() resetErrors()
@ -181,8 +210,6 @@ export const useFormSubmit = ({ onAddSuccess }: Props) => {
return return
} }
const allInputEmpty = Object.values(inputStates).every((inputValue) => inputValue.empty)
if (isHighlightsPage && defaultCard && allInputEmpty) { if (isHighlightsPage && defaultCard && allInputEmpty) {
setErrorMessage('') setErrorMessage('')
setLoader(true) setLoader(true)
@ -228,25 +255,38 @@ export const useFormSubmit = ({ onAddSuccess }: Props) => {
setLoader(true) setLoader(true)
onAddCard(token.id) onAddCard(token.id)
.then(onAddSuccess) .then(onAddSuccess)
.then(() => defaultCard && isHighlightsPage && setInputStates(initialState)) .then(() => lastCard && isHighlightsPage && setInputStates(initialState))
.then(() => { .catch(() => setLoader(false))
if (defaultCard && isHighlightsPage) {
onePayment({
cardId: defaultCard.id,
order: { ...dataHighlights?.data },
})
.then(onSuccessfulHighlights, onUnsuccessfulSubscription)
.catch(() => setErrorMessage(translate('error_payment_unsuccessful')))
}
})
.finally(() => setLoader(false))
} }
} }
useEffect(() => {
if (lastCard && isHighlightsPage) {
onePayment({
cardId: lastCard,
order: { ...dataHighlights?.data },
})
.then(onSuccessfulHighlights, onUnsuccessfulSubscription)
.catch(() => setErrorMessage(translate('error_payment_unsuccessful')))
.finally(() => setLoader(false))
}
setLastCard(null)
// eslint-disable-next-line
}, [lastCard])
useEffect(() => { useEffect(() => {
setCardError('') setCardError('')
}, [setCardError]) }, [setCardError])
useEffect(() => {
if (!allInputEmpty) setShowClearBtn(true)
}, [allInputEmpty, setShowClearBtn])
useEffect(() => {
if (clearInputs) resetInputs()
// eslint-disable-next-line
}, [clearInputs])
return { return {
address, address,
city, city,

@ -83,7 +83,7 @@ export const SectionTitle = styled.span`
margin-bottom: 8px; margin-bottom: 8px;
${isMobileDevice ${isMobileDevice
? css` ? css`
margin-bottom: 25px; margin-bottom: 5px;
font-size: 10px; font-size: 10px;
@media (orientation: landscape){ @media (orientation: landscape){
margin-bottom: 10px; margin-bottom: 10px;

@ -73,8 +73,6 @@ export const useLoginForm = () => {
scope, scope,
}, },
}) })
const numberVisits = localStorage.getItem('countVisits') ?? 0
localStorage.setItem('countVisits', (Number(numberVisits) + 1).toString())
submitForm() submitForm()
} catch (err) { } catch (err) {
handleError(String(err)) handleError(String(err))

@ -1,3 +1,5 @@
import { useState } from 'react'
import isEmpty from 'lodash/isEmpty' import isEmpty from 'lodash/isEmpty'
import { AddCardFormInner } from 'features/AddCardForm/components/Form' import { AddCardFormInner } from 'features/AddCardForm/components/Form'
@ -18,6 +20,8 @@ import {
Header, Header,
HeaderTitle, HeaderTitle,
Button, Button,
ButtonBlock,
ButtonClear,
ButtonPrevious, ButtonPrevious,
} from '../../styled' } from '../../styled'
@ -32,8 +36,13 @@ export const CardStep = ({
closeHandle, closeHandle,
title, title,
}: CardStepType) => { }: CardStepType) => {
const [clearInputs, setClearInputs] = useState(false)
const { cards, isHighlightsPage } = useCardsStore() const { cards, isHighlightsPage } = useCardsStore()
const { close, goBack } = useBuyMatchPopupStore() const {
close,
goBack,
showClearBtn,
} = useBuyMatchPopupStore()
const emptyCards = isEmpty(cards) const emptyCards = isEmpty(cards)
@ -56,10 +65,24 @@ export const CardStep = ({
onAddSuccess={goBack} onAddSuccess={goBack}
initialformOpen={emptyCards} initialformOpen={emptyCards}
inputsBackground='rgba(255, 255, 255, 0.1)' inputsBackground='rgba(255, 255, 255, 0.1)'
clearInputs={clearInputs}
setClearInputs={setClearInputs}
> >
<Button type='submit'> <ButtonBlock showClearBtn={showClearBtn}>
<T9n t={btnName ?? 'add'} /> {isHighlightsPage
</Button> && showClearBtn && (
<ButtonClear onClick={(e) => {
e.preventDefault()
setClearInputs(true)
}}
>
<T9n t='clear' />
</ButtonClear>
)}
<Button type='submit'>
<T9n t={btnName ?? 'add'} />
</Button>
</ButtonBlock>
</AddCardFormInner> </AddCardFormInner>
</Body> </Body>
</Wrapper> </Wrapper>

@ -53,6 +53,7 @@ export const useBuyMatchPopup = () => {
const [error, setError] = useState('') const [error, setError] = useState('')
const [loader, setLoader] = useState(false) const [loader, setLoader] = useState(false)
const [disabledBuyBtn, setDisabledBuyBtn] = useState(false) const [disabledBuyBtn, setDisabledBuyBtn] = useState(false)
const [showClearBtn, setShowClearBtn] = useState(false)
const [lastSelectedPackage, setLastSelectedPackage] = useState('') const [lastSelectedPackage, setLastSelectedPackage] = useState('')
const setDataHighlights = useSetRecoilState(dataForPayHighlights) const setDataHighlights = useSetRecoilState(dataForPayHighlights)
@ -226,6 +227,8 @@ export const useBuyMatchPopup = () => {
selectedSubscription, selectedSubscription,
setDisabledBuyBtn, setDisabledBuyBtn,
setLastSelectedPackage, setLastSelectedPackage,
setShowClearBtn,
showClearBtn,
subscriptions, subscriptions,
} }
} }

@ -2,7 +2,7 @@ import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent' import { isMobileDevice } from 'config/userAgent'
import { ButtonSolid } from 'features/Common' import { ButtonOutline, ButtonSolid } from 'features/Common'
import { ModalWindow } from 'features/Modal/styled' import { ModalWindow } from 'features/Modal/styled'
import { Modal as BaseModal } from 'features/Modal' import { Modal as BaseModal } from 'features/Modal'
@ -48,8 +48,7 @@ export const HeaderTitle = styled.h2`
` `
export const Button = styled(ButtonSolid)` export const Button = styled(ButtonSolid)`
min-width: 270px; width: 275px;
width: auto;
height: 50px; height: 50px;
padding: 0 20px; padding: 0 20px;
background-color: ${({ theme: { colors } }) => colors.button}; background-color: ${({ theme: { colors } }) => colors.button};
@ -58,13 +57,15 @@ export const Button = styled(ButtonSolid)`
border-radius: 5px; border-radius: 5px;
font-weight: 600; font-weight: 600;
font-size: 20px; font-size: 20px;
${isMobileDevice ${isMobileDevice
? css` ? css`
height: 32px; max-height: 38px;
min-width: 117px; min-width: 117px;
font-size: 12px; max-width: 49%;
font-size: 16px;
@media screen and (orientation: landscape){ @media screen and (orientation: landscape){
min-width: 178px; /* min-width: 178px; */
} }
` `
@ -108,7 +109,7 @@ export const Wrapper = styled.div<WrapperProps>`
} }
@media (max-width: 650px){ @media (max-width: 650px){
width: 100%; width: 100%;
padding: 40px 10px 20px; padding: 20px 10px 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-evenly; justify-content: space-evenly;
@ -190,3 +191,35 @@ export const ButtonPrevious = styled.button`
left: 20px; left: 20px;
cursor: pointer; cursor: pointer;
` `
export const ButtonClear = styled(ButtonOutline)`
border: 1px solid #FFFFFF;
border-radius: 4px;
font-weight: 600;
font-size: 20px;
line-height: 16px;
height: 50px;
width: 275px;
max-width: 49%;
${isMobileDevice
? css`
height: 100%;
font-size: 16px;
width: 100%;
padding: 0 20px;
max-width: 49%;
max-height: 38px;
`
: ''};
`
type ButtonsProps = {
showClearBtn: boolean,
}
export const ButtonBlock = styled.div<ButtonsProps>`
display: flex;
flex-direction: row;
height: 38px;
width: 100%;
justify-content: ${({ showClearBtn }) => (showClearBtn ? 'space-between' : 'center')};
`

@ -25,6 +25,7 @@ export const useBankCards = () => {
const [isHighlightsPage, setIsHighlightsPage] = useState(false) const [isHighlightsPage, setIsHighlightsPage] = useState(false)
const [error, setError] = useState('') const [error, setError] = useState('')
const [cards, setCards] = useState<Cards | null>(null) const [cards, setCards] = useState<Cards | null>(null)
const [lastCard, setLastCard] = useState<string | null>(null)
const defaultCard = useMemo( const defaultCard = useMemo(
() => find(cards, { default: true }), () => find(cards, { default: true }),
[cards], [cards],
@ -38,6 +39,9 @@ export const useBankCards = () => {
setError('error_can_not_add_card') setError('error_can_not_add_card')
return Promise.reject() return Promise.reject()
}) })
.then(({ card }) => {
isHighlightsPage && setLastCard(card.id)
})
.then(fetchCards) .then(fetchCards)
) )
@ -49,12 +53,8 @@ export const useBankCards = () => {
} }
useEffect(() => { useEffect(() => {
if (window.location.pathname === PAGES.highlights) { setIsHighlightsPage(window.location.pathname === PAGES.highlights)
setIsHighlightsPage(true) }, [cards])
} else {
setIsHighlightsPage(false)
}
}, [])
return { return {
cards, cards,
@ -64,10 +64,12 @@ export const useBankCards = () => {
infoModalOpen, infoModalOpen,
isFetching, isFetching,
isHighlightsPage, isHighlightsPage,
lastCard,
onAddCard, onAddCard,
onDeleteCard: handleCardDelete, onDeleteCard: handleCardDelete,
onSetDefaultCard, onSetDefaultCard,
setError, setError,
setLastCard,
toggleInfoModal, toggleInfoModal,
} }
} }

@ -22,6 +22,7 @@ import {
LabelTitle, LabelTitle,
LabelAfter, LabelAfter,
LabelBefore, LabelBefore,
ScTooltip,
} from 'features/Common/Input/styled' } from 'features/Common/Input/styled'
import { Props, Option } from './types' import { Props, Option } from './types'
@ -50,6 +51,7 @@ export const Combobox = <T extends Option>(props: Props<T>) => {
maxLength, maxLength,
noSearch, noSearch,
title, title,
toolTip,
withError, withError,
wrapperHeight, wrapperHeight,
} = props } = props
@ -82,8 +84,15 @@ export const Combobox = <T extends Option>(props: Props<T>) => {
<LabelTitle <LabelTitle
labelWidth={labelWidth} labelWidth={labelWidth}
isUserAccountPage={isUserAccountPage} isUserAccountPage={isUserAccountPage}
onClick={(e) => {
if (toolTip) {
e.preventDefault()
e.stopPropagation()
}
}}
> >
{labelLexic ? <T9n t={labelLexic} /> : label} {labelLexic ? <T9n t={labelLexic} /> : label}
{toolTip && <ScTooltip className='Highlight__Tooltip'><T9n t={toolTip} /></ScTooltip>}
</LabelTitle> </LabelTitle>
{labelBefore && ( {labelBefore && (
<LabelBefore> <LabelBefore>

@ -50,6 +50,14 @@ export const ListOption = styled.li.attrs(() => ({
background-color: #999; background-color: #999;
color: #fff; color: #fff;
} }
${isMobileDevice
? css`
font-size: 12px;
height: 36px;
padding-left: 14px;
`
: ''};
` `
export const WrapperIcon = styled.span` export const WrapperIcon = styled.span`
position: absolute; position: absolute;
@ -58,6 +66,12 @@ export const WrapperIcon = styled.span`
width: 15px; width: 15px;
height: 15px; height: 15px;
transform: translateY(-60%); transform: translateY(-60%);
${isMobileDevice
? css`
right: 11px;
`
: ''};
` `
export const ScAudioWrap = styled.div` export const ScAudioWrap = styled.div`

@ -35,6 +35,7 @@ export type Props<T> = Pick<InputHTMLAttributes<HTMLInputElement>, (
onSelect?: (option: T | null) => void, onSelect?: (option: T | null) => void,
options: Array<T>, options: Array<T>,
selected?: boolean, selected?: boolean,
toolTip?: string,
value: string, value: string,
withError?: boolean, withError?: boolean,
wrapperHeight?: number, wrapperHeight?: number,

@ -16,6 +16,7 @@ import {
LabelTitle, LabelTitle,
Error, Error,
Column, Column,
ScTooltip,
} from './styled' } from './styled'
type Props = { type Props = {
@ -38,6 +39,7 @@ type Props = {
pattern?: string, pattern?: string,
required?: boolean, required?: boolean,
title?: string, title?: string,
toolTip?: string,
type?: string, type?: string,
value?: string, value?: string,
withError?: boolean, withError?: boolean,
@ -65,6 +67,7 @@ export const Input = ({
pattern, pattern,
required, required,
title, title,
toolTip,
type, type,
value, value,
withError = true, withError = true,
@ -85,6 +88,7 @@ export const Input = ({
<Label> <Label>
<LabelTitle labelWidth={labelWidth} isUserAccountPage={isUserAccountPage}> <LabelTitle labelWidth={labelWidth} isUserAccountPage={isUserAccountPage}>
{labelLexic ? <T9n t={labelLexic} /> : label} {labelLexic ? <T9n t={labelLexic} /> : label}
{toolTip && <ScTooltip className='Highlight__Tooltip'><T9n t={toolTip} /></ScTooltip>}
</LabelTitle> </LabelTitle>
<InputStyled <InputStyled
autoComplete={autoComplete} autoComplete={autoComplete}

@ -28,6 +28,12 @@ export const wrapperStyles = css<WrapperProps>`
border-radius: 2px; border-radius: 2px;
border: 1px solid ${(({ error }) => (isNil(error) ? 'transparent' : '#E64646'))}; border: 1px solid ${(({ error }) => (isNil(error) ? 'transparent' : '#E64646'))};
border-width: 1px; border-width: 1px;
${isMobileDevice
? css`
padding-left: 0;
`
: ''};
` `
type TitleProps = { type TitleProps = {
@ -52,6 +58,12 @@ export const LabelTitle = styled.p<TitleProps>`
width: ${({ labelWidth }) => (labelWidth ? `${labelWidth}px` : '')}; width: ${({ labelWidth }) => (labelWidth ? `${labelWidth}px` : '')};
min-width: ${({ labelWidth }) => (labelWidth ? `${labelWidth}px` : '')}; min-width: ${({ labelWidth }) => (labelWidth ? `${labelWidth}px` : '')};
&:hover{
.Highlight__Tooltip {
display: block;
}
}
@media ${devices.tablet} { @media ${devices.tablet} {
font-size: 1.6rem; font-size: 1.6rem;
width: 9rem; width: 9rem;
@ -219,3 +231,26 @@ export const LabelBefore = styled(LabelAfter)`
margin-left: -30px; margin-left: -30px;
padding-top: 5px; padding-top: 5px;
` `
export const ScTooltip = styled.div`
display: none;
position: absolute;
font-weight: 600;
font-size: 0.8rem;
line-height: 18px;
color: #000000;
background: #FFFFFF;
border-radius: 6px;
padding: 3px 6px;
max-width: 292px;
overflow-wrap: break-word;
white-space: normal;
z-index: 10;
${isMobileDevice
? css`
font-size: 12px;
`
: ''};
`

@ -20,10 +20,10 @@ export const BaseButton = styled.button<Props>`
height: ${({ height = 1.6 }) => height}rem; height: ${({ height = 1.6 }) => height}rem;
padding: ${({ padding = 0 }) => padding}px; padding: ${({ padding = 0 }) => padding}px;
color: white; color: white;
/* background-color: rgba(255, 255, 255, 0.12); background-color: rgba(255, 255, 255, 0.12);
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
border-radius: 50%; */ border-radius: 50%;
:hover { :hover {
background-color: rgba(255, 255, 255, 0.22); background-color: rgba(255, 255, 255, 0.22);
@ -35,7 +35,7 @@ export const BaseButton = styled.button<Props>`
height: 18px; height: 18px;
padding: 4px; padding: 4px;
position: absolute; position: absolute;
top: -10px; top: -20px;
right: -30px; right: -30px;
@media screen and (orientation: landscape){ @media screen and (orientation: landscape){
width: 24px; width: 24px;

@ -16,7 +16,7 @@ export const Modal = styled(BaseModal)`
width: calc(100vw - 60px); width: calc(100vw - 60px);
@media screen and (orientation: landscape){ @media screen and (orientation: landscape){
max-width: calc(100vw - 80px); max-width: calc(100vw - 80px);
height: calc(100vh - 20px); height: calc(100vh - 10px);
overflow: auto; overflow: auto;
} }
` `

@ -264,6 +264,7 @@ export const ScButtonGetHighlight = styled(ButtonOutline)`
margin: 30px 0; margin: 30px 0;
border: 1px solid #FFFFFF; border: 1px solid #FFFFFF;
border-radius: 5px; border-radius: 5px;
width: 95%;
filter: drop-shadow(0px 1px 1px rgba(0, 0, 0, 0.3)); filter: drop-shadow(0px 1px 1px rgba(0, 0, 0, 0.3));
${isMobileDevice ${isMobileDevice

@ -0,0 +1 @@
export const dateForIos = (date: string) => Date.parse(date?.replace(/ /, 'T'))

@ -0,0 +1,29 @@
import { useState } from 'react'
export const useLocalStorage = (keyName: string, defaultValue?: any) => {
const [storedValue, setStoredValue] = useState(() => {
try {
const value = localStorage.getItem(keyName)
if (value) {
return JSON.parse(value)
}
localStorage.setItem(keyName, JSON.stringify(defaultValue))
return defaultValue
} catch (err) {
return defaultValue
}
})
const setValue = (newValue: any) => {
try {
localStorage.setItem(keyName, JSON.stringify(newValue))
} catch (err) {
/* eslint-disable-next-line */
console.log(err)
}
setStoredValue(newValue)
}
return [storedValue, setValue]
}

@ -1,6 +1,5 @@
import { import {
ChangeEvent, ChangeEvent,
FormEvent,
useEffect, useEffect,
useRef, useRef,
useState, useState,
@ -28,6 +27,7 @@ import {
} from 'requests/getSportTeams' } from 'requests/getSportTeams'
import { getPlayerMatches } from 'requests/getMatches/getPlayerMatches' import { getPlayerMatches } from 'requests/getMatches/getPlayerMatches'
import { getTeamPlayers, Player } from 'requests/getTeamPlayers' import { getTeamPlayers, Player } from 'requests/getTeamPlayers'
import { getSearchItems, PlayerTypeFromSearch } from 'requests'
import { import {
checkedMatches, checkedMatches,
@ -48,12 +48,29 @@ type SportTypeName = SportType & {
name: string, name: string,
} }
type PlayerType = Player & { type PlayerType = {
firstname_eng: string,
firstname_rus: string,
id: number,
lastname_eng: string,
lastname_rus: string,
name: string, name: string,
sport?: number,
sport_id?: number,
team?: {
id: number,
name_eng: string,
name_rus: string,
},
} }
type TeamType = Team & { type TeamType = {
id: number,
name: string, name: string,
name_eng: string,
name_rus: string,
short_name_eng?: string,
short_name_rus?: string,
} }
type Sound = { type Sound = {
@ -73,7 +90,7 @@ type FormType = {
players: Array<string>, players: Array<string>,
selectedPlayer: PlayerType | null, selectedPlayer: PlayerType | null,
selectedSound: Sound | null, selectedSound: Sound | null,
selectedTeam: Team | null, selectedTeam: TeamType | null,
sport: SportTypeName | null, sport: SportTypeName | null,
stats: StatsType, stats: StatsType,
teamValue: string, teamValue: string,
@ -98,7 +115,7 @@ const defaultValues = {
selectedSound: null, selectedSound: null,
selectedTeam: null, selectedTeam: null,
sport: null, sport: null,
stats: summaryStats[1], stats: summaryStats[0],
teamValue: '', teamValue: '',
} }
@ -141,6 +158,7 @@ export const useHighlightsForm = () => {
if (selectedTeam) { if (selectedTeam) {
setFormState((state) => ({ setFormState((state) => ({
...state, ...state,
duration: '2',
selectedTeam, selectedTeam,
})) }))
} }
@ -148,10 +166,25 @@ export const useHighlightsForm = () => {
const onPlayerSelect = (selectedPlayer: PlayerType | null) => { const onPlayerSelect = (selectedPlayer: PlayerType | null) => {
if (!selectedPlayer) return if (!selectedPlayer) return
setFormState((state) => ({ setFormState((state: FormType) => ({
...state, ...state,
duration: '2',
playerValue: '',
selectedPlayer, 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) => { const onSoundSelect = (selectedSound: Sound | null) => {
@ -186,31 +219,49 @@ export const useHighlightsForm = () => {
setFormState((state: FormType) => ({ setFormState((state: FormType) => ({
...state, ...state,
playerValue: '',
selectedPlayer: null,
selectedTeam: null, selectedTeam: null,
teamValue: e?.target?.value, teamValue: e?.target?.value,
})) }))
setPlayers([])
setPlayerMatches([])
} }
const onChangePlayer = (e: ChangeEvent<HTMLInputElement>) => { 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) => ({ setFormState((state: FormType) => ({
...state, ...state,
playerValue: e?.target?.value, playerValue: e?.target?.value,
selectedPlayer: null, selectedPlayer: null,
selectedTeam: state.selectedTeam ?? null,
})) }))
setPlayers( setPlayers(
playersData?.filter( playersData?.filter(
(player: PlayerType) => player (player: PlayerType) => player
&& player.name && player?.name
?.toLowerCase() ?.toLowerCase()
.indexOf(e?.target?.value.toLowerCase()) >= 0, .indexOf(e?.target?.value.toLowerCase()) >= 0,
), ),
) )
} }
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
}
useEffect(() => { useEffect(() => {
getSportList() getSportList()
.then((res) => setSports( .then((res) => setSports(
@ -233,6 +284,7 @@ export const useHighlightsForm = () => {
]) ])
setFormState((prev) => ({ setFormState((prev) => ({
...prev, ...prev,
duration: '2',
selectedSound: { selectedSound: {
asset: null, asset: null,
id: 100, id: 100,
@ -286,7 +338,7 @@ export const useHighlightsForm = () => {
) )
useEffect(() => { useEffect(() => {
if (Number(formState?.duration) < checkedMatchesLength * 2) { if (checkedMatchesLength * 2 >= 2) {
setFormState((prev) => ({ setFormState((prev) => ({
...prev, ...prev,
duration: (checkedMatchesLength * 2).toString(), duration: (checkedMatchesLength * 2).toString(),
@ -352,7 +404,7 @@ export const useHighlightsForm = () => {
p_match_completed: true, p_match_completed: true,
playerId: formState?.selectedPlayer?.id, playerId: formState?.selectedPlayer?.id,
sportType: formState?.sport?.id, sportType: formState?.sport?.id,
sub_only: false, sub_only: true,
}) })
.then(({ broadcast }) => setPlayerMatches( .then(({ broadcast }) => setPlayerMatches(
broadcast.map((match: Match) => ({ ...match, isChecked: false })), broadcast.map((match: Match) => ({ ...match, isChecked: false })),
@ -366,7 +418,6 @@ export const useHighlightsForm = () => {
checkedMatchesLength, checkedMatchesLength,
formRef, formRef,
formState, formState,
handleSubmit,
isFetchingTeams, isFetchingTeams,
onChangeMaxDuration, onChangeMaxDuration,
onChangePlayer, onChangePlayer,

@ -103,11 +103,11 @@ export const FormHighlights = ({ price, setIsOpenPopupVideo }: PriceInfoType) =>
loading={isFetchingTeams} loading={isFetchingTeams}
/> />
<Combobox <Combobox
disabled={!sport || !selectedTeam} disabled={!sport}
selected selected
labelLexic='player_highlight' labelLexic='player_highlight'
labelWidth={labelWidth} labelWidth={labelWidth}
value={selectedPlayer?.name || playerValue || ''} value={playerValue || selectedPlayer?.name || ''}
onSelect={onPlayerSelect} onSelect={onPlayerSelect}
onChange={onChangePlayer} onChange={onChangePlayer}
options={players} options={players}
@ -127,7 +127,7 @@ export const FormHighlights = ({ price, setIsOpenPopupVideo }: PriceInfoType) =>
wrapperHeight={wrapperHeight} wrapperHeight={wrapperHeight}
labelAfter='min' labelAfter='min'
className='FormHighlights__input__duration' className='FormHighlights__input__duration'
required toolTip='describe_duration'
/> />
<Combobox <Combobox
disabled={!sport} disabled={!sport}
@ -144,12 +144,13 @@ export const FormHighlights = ({ price, setIsOpenPopupVideo }: PriceInfoType) =>
labelBefore={selectedSound?.asset} labelBefore={selectedSound?.asset}
className={selectedSound?.asset className={selectedSound?.asset
? 'FormHighlights__input__sound' : ''} ? 'FormHighlights__input__sound' : ''}
toolTip='describe_music'
/> />
<Combobox <Combobox
disabled disabled
noSearch noSearch
selected selected
labelLexic='add_summary' labelLexic='statistics_highlights'
labelWidth={labelWidth} labelWidth={labelWidth}
value={stats?.name || ''} value={stats?.name || ''}
onSelect={onStatsSelect} onSelect={onStatsSelect}
@ -157,6 +158,7 @@ export const FormHighlights = ({ price, setIsOpenPopupVideo }: PriceInfoType) =>
maxLength={500} maxLength={500}
withError={false} withError={false}
wrapperHeight={wrapperHeight} wrapperHeight={wrapperHeight}
toolTip='describe_statistic'
/> />
</ScInputGroup> </ScInputGroup>
</ScForm> </ScForm>

@ -1,6 +1,7 @@
import styled, { css } from 'styled-components/macro' import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent' import { isMobileDevice } from 'config/userAgent'
import { InputWrapper } from 'features/Common/Input/styled'
export const ScWrapper = styled.div` export const ScWrapper = styled.div`
max-width: 560px; max-width: 560px;
@ -45,7 +46,6 @@ export const ScTitle = styled.span`
` `
: ''}; : ''};
/* margin-bottom: 15px; */
` `
export const ScText = styled.div` export const ScText = styled.div`
@ -67,7 +67,19 @@ export const ScInfoWrap = styled.div`
` `
export const ScInputGroup = styled.div` export const ScInputGroup = styled.div`
${InputWrapper} {
${isMobileDevice
? css`
margin-top: 5px;
padding-left: 0;
@media screen and (orientation: landscape){
padding-left: 10px;
}
`
: ''};
}
.Search__input { .Search__input {
transform: translateY(50%); transform: translateY(50%);
} }
@ -77,15 +89,12 @@ export const ScForm = styled.form`
max-width: 560px; max-width: 560px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
${isMobileDevice
? css`
`
: ''};
& ul { & ul {
max-height: 200px; max-height: 200px;
} }
& input { & input {
font-size: 12px;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
@ -112,4 +121,6 @@ export const ScForm = styled.form`
max-width: 100%; max-width: 100%;
` `
: ''}; : ''};
` `

@ -9,6 +9,8 @@ import { ArrowLoader } from 'features/ArrowLoader'
import { isMobileDevice } from 'config/userAgent' import { isMobileDevice } from 'config/userAgent'
import { dateForIos } from 'helpers/dateForIos'
import { MatchType, fetchingMatches } from '../../storeHighlightsAtoms' import { MatchType, fetchingMatches } from '../../storeHighlightsAtoms'
import { useHighlighMatches } from './hooks' import { useHighlighMatches } from './hooks'
@ -67,7 +69,7 @@ export const MatchesHighlights = () => {
label={( label={(
<ScLabel> <ScLabel>
<ScDate> <ScDate>
{format(new Date(date), 'd MMM yyyy H:mm')} {format(new Date(dateForIos(date)), 'd MMM yyyy H:mm')}
</ScDate>&nbsp; </ScDate>&nbsp;
{team1.name_eng} - {team2.name_eng} {team1.name_eng} - {team2.name_eng}
<ScTournament> <ScTournament>

@ -46,11 +46,6 @@ export const ScMatchesList = styled.div`
margin-bottom: 15px; margin-bottom: 15px;
} }
} }
${isMobileDevice
? css`
`
: ''};
` `
export const ScLabel = styled.div` export const ScLabel = styled.div`

@ -34,7 +34,7 @@ export const VideoHighlight = ({
<VideoPlayer <VideoPlayer
src={`${isProduction ? urls.production : urls.stage}?access_token=${readToken()}`} src={`${isProduction ? urls.production : urls.stage}?access_token=${readToken()}`}
ref={videoRef} ref={videoRef}
playing={Boolean(true)} playing={Boolean(false)}
muted={false} muted={false}
isFullscreen={false} isFullscreen={false}
controls={Boolean(true)} controls={Boolean(true)}

@ -49,4 +49,11 @@ export const ScCloseButton = styled.div`
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
${isMobileDevice
? css`
right: 0;
top: 170px;
`
: ''};
` `

@ -1,4 +1,4 @@
import { useState } from 'react' import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { isMobileDevice } from 'config/userAgent' import { isMobileDevice } from 'config/userAgent'
@ -20,10 +20,9 @@ import { ThanksPopup } from './components/ThanksPopup'
import { VideoHighlight } from './components/VideoHighlight' import { VideoHighlight } from './components/VideoHighlight'
import { import {
checkedMatches,
dataForPayHighlights, dataForPayHighlights,
MatchType,
openPopupChangeCard, openPopupChangeCard,
playerMatchesState,
} from './storeHighlightsAtoms' } from './storeHighlightsAtoms'
import { import {
@ -37,7 +36,9 @@ import {
} from './styled' } from './styled'
const HighlightsPage = () => { const HighlightsPage = () => {
const playerMatches = useRecoilValue(playerMatchesState) const { checkedMatchesLength } = useRecoilValue(checkedMatches)
const [startHeight] = useState(window.innerHeight)
const [showBtn, setShowBtn] = useState(true)
const [isOpenPopupChangeCard, setIsOpenPopupChangeCard] = useRecoilState(openPopupChangeCard) const [isOpenPopupChangeCard, setIsOpenPopupChangeCard] = useRecoilState(openPopupChangeCard)
const [isOpenPopupVideo, setIsOpenPopupVideo] = useState(false) const [isOpenPopupVideo, setIsOpenPopupVideo] = useState(false)
const { data } = useRecoilValue(dataForPayHighlights) const { data } = useRecoilValue(dataForPayHighlights)
@ -49,10 +50,20 @@ const HighlightsPage = () => {
|| !isBoolean(data?.stats) || !isBoolean(data?.stats)
|| data?.matches.length > 10 || data?.matches.length > 10
|| data.background_music === undefined || data.background_music === undefined
|| !checkedMatchesLength
const price = playerMatches?.filter( const price = checkedMatchesLength * 25
({ isChecked }: MatchType) => isChecked,
).length * 25 useEffect(() => {
window.addEventListener('resize', (e) => {
setShowBtn(startHeight === window.innerHeight)
})
return () => {
window.removeEventListener('resize', () => setShowBtn(true))
}
// eslint-disable-next-line
}, [])
return ( return (
<ScWrapper> <ScWrapper>
@ -68,17 +79,21 @@ const HighlightsPage = () => {
<FormHighlights price={price} setIsOpenPopupVideo={setIsOpenPopupVideo} /> <FormHighlights price={price} setIsOpenPopupVideo={setIsOpenPopupVideo} />
<MatchesHighlights /> <MatchesHighlights />
</ScWrapperContent> </ScWrapperContent>
<ScButtonWrap {
disabled={isNotEmpty} showBtn && (
onClick={() => !isNotEmpty && setIsOpenPopupChangeCard(true)} <ScButtonWrap
> disabled={isNotEmpty}
<ScButton> onClick={() => !isNotEmpty && setIsOpenPopupChangeCard(true)}
<T9n t='order_and_buy' /> >
<ScPrice> <ScButton>
&nbsp;${price} <T9n t='order_and_buy' />
</ScPrice> <ScPrice>
</ScButton> &nbsp;${price}
</ScButtonWrap> </ScPrice>
</ScButton>
</ScButtonWrap>
)
}
<CompanyInfo clientName={client.name} textAlign='center' /> <CompanyInfo clientName={client.name} textAlign='center' />
<ChangeCardPopup <ChangeCardPopup
btnName='buy_subscription' btnName='buy_subscription'

@ -46,9 +46,9 @@ export const fetchingMatches = atom({
export const checkedMatches = selector({ export const checkedMatches = selector({
get: ({ get }) => { get: ({ get }) => {
const matches = get(playerMatchesState) const matches = get(playerMatchesState)
const checkedPlayerMatches = matches.filter(({ isChecked }) => isChecked) const checkedPlayerMatches = matches?.filter(({ isChecked }) => isChecked)
const idsCheckedMatches = checkedPlayerMatches.map(({ id }) => id) const idsCheckedMatches = checkedPlayerMatches?.map(({ id }) => id)
const checkedMatchesLength = checkedPlayerMatches.length const checkedMatchesLength = checkedPlayerMatches?.length
return { return {
checkedMatchesLength, checkedMatchesLength,

@ -7,20 +7,27 @@ import { isMobileDevice } from 'config/userAgent'
export const ScHeader = styled.div` export const ScHeader = styled.div`
width: 100%; width: 100%;
max-height: 95px;
padding: 32px 36px; padding: 32px 36px;
background: linear-gradient(236.13deg, rgba(53, 96, 225, 0.56) -4.49%, rgba(0, 0, 0, 0) 98.29%), #000000; background: linear-gradient(236.13deg, rgba(53, 96, 225, 0.56) -4.49%, rgba(0, 0, 0, 0) 98.29%), #000000;
${isMobileDevice
? css`
display: flex;
justify-content: center;
padding: 10px;
`
: ''};
` `
export const ScHeaderLogo = styled(Logo)` export const ScHeaderLogo = styled(Logo)`
` `
export const ScWrapper = styled.div` export const ScWrapper = styled.div`
width: 100%;
max-height: 100vh;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%;
height: 100vh;
padding-bottom: 0;
` `
export const ScWrapperContent = styled.div` export const ScWrapperContent = styled.div`
@ -53,7 +60,22 @@ export const ScButtonWrap = styled.div<{disabled: boolean}>`
justify-content: center; justify-content: center;
margin-bottom: 100px; margin-bottom: 100px;
opacity: ${({ disabled }) => (disabled ? 0.5 : 1)} ${isMobileDevice
? css`
position: fixed;
bottom: 10px;
left: 50%;
transform: translate(-62%, 0);
margin-bottom: 0px;
width: 270px;
@media (orientation: landscape) {
transform: translate(-50%, 0);
}
`
: ''};
opacity: ${({ disabled }) => (disabled ? 0.7 : 1)}
` `
export const ScPrice = styled.span` export const ScPrice = styled.span`

@ -12,13 +12,13 @@ export enum Gender {
FEMALE = 2, FEMALE = 2,
} }
type NamedObject = { export type NamedObject = {
id: number, id: number,
name_eng: string, name_eng: string,
name_rus: string, name_rus: string,
} }
type Player = { export type PlayerTypeFromSearch = {
country?: NamedObject, country?: NamedObject,
firstname_eng: string, firstname_eng: string,
firstname_rus: string, firstname_rus: string,
@ -30,6 +30,8 @@ type Player = {
team?: NamedObject, team?: NamedObject,
} }
export type PlayersType = Array<PlayerTypeFromSearch>
type Team = { type Team = {
country?: NamedObject, country?: NamedObject,
gender?: Gender, gender?: Gender,
@ -49,14 +51,14 @@ type Tournament = {
} }
export type SearchItems = { export type SearchItems = {
players?: Array<Player>, players?: PlayersType,
teams?: Array<Team>, teams?: Array<Team>,
tournaments?: Array<Tournament>, tournaments?: Array<Tournament>,
} }
export const getSearchItems = ( export const getSearchItems = (
searchString: string, searchString: string,
abortSignal: AbortSignal, abortSignal?: AbortSignal,
): Promise<SearchItems> => { ): Promise<SearchItems> => {
const config = { const config = {
body: { body: {

Loading…
Cancel
Save