feat(#2526): add popup thanks and method for payment

keep-around/f09ad060abadb54ab731d2923f633e5162e907d2
Andrei Dekterev 4 years ago
parent 2ffa73944a
commit e96760b3db
  1. 3
      src/config/lexics/payment.tsx
  2. 11
      src/features/AddCardForm/components/Form/hooks/index.tsx
  3. 1
      src/libs/index.ts
  4. 56
      src/libs/objects/Check.tsx
  5. 16
      src/pages/HighlightsPage/components/FormHighlights/hooks.tsx
  6. 7
      src/pages/HighlightsPage/components/FormHighlights/index.tsx
  7. 12
      src/pages/HighlightsPage/components/FormHighlights/styled.tsx
  8. 6
      src/pages/HighlightsPage/components/MatchesHighlights/index.tsx
  9. 6
      src/pages/HighlightsPage/components/MatchesHighlights/styled.tsx
  10. 2
      src/pages/HighlightsPage/components/PriceInfo/index.tsx
  11. 22
      src/pages/HighlightsPage/components/PriceInfo/styled.tsx
  12. 41
      src/pages/HighlightsPage/components/ThanksPopup/index.tsx
  13. 67
      src/pages/HighlightsPage/components/ThanksPopup/styled.tsx
  14. 9
      src/pages/HighlightsPage/index.tsx
  15. 16
      src/pages/HighlightsPage/storeHighlightsAtoms.tsx
  16. 9
      src/pages/HighlightsPage/styled.tsx
  17. 18
      src/requests/onePayment.tsx

@ -19,6 +19,8 @@ export const paymentLexics = {
error_payment_unsuccessful: 14446, error_payment_unsuccessful: 14446,
if_you_cancel: 18189, if_you_cancel: 18189,
next_payment: 18183, next_payment: 18183,
notify_by_email: 18366,
order_received: 18365,
payment_date: 15603, payment_date: 15603,
payment_method: 2010, payment_method: 2010,
save_sub: 18190, save_sub: 18190,
@ -26,6 +28,7 @@ export const paymentLexics = {
sub_not_renewed: 15060, sub_not_renewed: 15060,
subscription_plan: 18182, subscription_plan: 18182,
sum: 838, sum: 838,
thank_you: 6579,
unsubscribe: 18188, unsubscribe: 18188,
using_payment: 18187, using_payment: 18187,
watch_match: 18199, watch_match: 18199,

@ -16,7 +16,7 @@ import {
useElements, useElements,
} from '@stripe/react-stripe-js' } from '@stripe/react-stripe-js'
import { useRecoilValue } from 'recoil' import { useRecoilState } from 'recoil'
import toUpper from 'lodash/toUpper' import toUpper from 'lodash/toUpper'
@ -85,7 +85,7 @@ export const useFormSubmit = ({ onAddSuccess }: Props) => {
const [inputStates, setInputStates] = useObjectState(initialState) const [inputStates, setInputStates] = useObjectState(initialState)
const [errorMessage, setErrorMessage] = useState('') const [errorMessage, setErrorMessage] = useState('')
const [loader, setLoader] = useState(false) const [loader, setLoader] = useState(false)
const dataFormHighlights = useRecoilValue(dataForPayHighlights) const [dataHighlights, setDataHighlights] = useRecoilState(dataForPayHighlights)
console.log('inputStates', inputStates) console.log('inputStates', inputStates)
@ -183,8 +183,11 @@ console.log('inputStates', inputStates)
setErrorMessage('') setErrorMessage('')
onePayment({ onePayment({
cardId: defaultCard?.id, cardId: defaultCard?.id,
item: { ...dataFormHighlights }, order: { ...dataHighlights.data },
}) }).then(() => setDataHighlights((prev) => ({
...prev,
isOpenThanksPopup: true,
})))
return return
} }

@ -2,6 +2,7 @@ export { Arrow } from './objects/Arrow'
export { Date } from './objects/Date' export { Date } from './objects/Date'
export { Edit } from './objects/Edit' export { Edit } from './objects/Edit'
export { Calendar } from './objects/Calendar' export { Calendar } from './objects/Calendar'
export { Check } from './objects/Check'
export { Basketball } from './objects/Basketball' export { Basketball } from './objects/Basketball'
export { Football } from './objects/Football' export { Football } from './objects/Football'
export { Hockey } from './objects/Hockey' export { Hockey } from './objects/Hockey'

@ -0,0 +1,56 @@
export const Check = () => (
<svg
width='90'
height='90'
viewBox='0 0 90 90'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<g filter='url(#filter0_d_28368_255927)'>
<path
d='M1 44C1 19.6995 20.6995 0 45 0C69.3005 0 89 19.6995 89 44C89 68.3005 69.3005 88 45 88C20.6995 88 1 68.3005 1 44Z'
fill='white'
/>
<path
d='M39.8572 51.8614L30.7836 42.7878C30.1142 42.1183 29.0288 42.1183 28.3593 42.7878C27.6898 43.4573 27.6898 44.5427 28.3593 45.2122L38.645 55.4979C39.3145 56.1674 40.3999 56.1674 41.0694 55.4979L61.6408 34.9265C62.3103 34.257 62.3103 33.1716 61.6408 32.5021C60.9713 31.8326 59.8859 31.8326 59.2164 32.5021L39.8572 51.8614Z'
fill='black'
/>
</g>
<defs>
<filter
id='filter0_d_28368_255927'
x='0'
y='0'
width='90'
height='90'
filterUnits='userSpaceOnUse'
colorInterpolationFilters='sRGB'
>
<feFlood floodOpacity='0' result='BackgroundImageFix' />
<feColorMatrix
in='SourceAlpha'
type='matrix'
values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'
result='hardAlpha'
/>
<feOffset dy='1' />
<feGaussianBlur stdDeviation='0.5' />
<feColorMatrix
type='matrix'
values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.3 0'
/>
<feBlend
mode='normal'
in2='BackgroundImageFix'
result='effect1_dropShadow_28368_255927'
/>
<feBlend
mode='normal'
in='SourceGraphic'
in2='effect1_dropShadow_28368_255927'
result='shape'
/>
</filter>
</defs>
</svg>
)

@ -220,12 +220,16 @@ export const useHighlightsForm = () => {
useEffect(() => { useEffect(() => {
if (formState?.selectedPlayer?.id) { if (formState?.selectedPlayer?.id) {
setDatahighlights({ setDatahighlights({
duration: Number(formState?.duration), data: {
lang: 'en', duration: Number(formState?.duration),
matches: playerMatches?.map((match) => match.id), lang: 'en',
player_id: formState?.selectedPlayer?.id, matches: playerMatches?.map((match) => match.id),
sport_id: formState?.sport.id, player_id: formState?.selectedPlayer?.id,
stats: Boolean(formState?.stats?.id), price: playerMatches?.length * 25,
sport_id: formState?.sport.id,
stats: Boolean(formState?.stats?.id),
},
isOpenThanksPopup: false,
}) })
} }
}, [formState, playerMatches]) }, [formState, playerMatches])

@ -3,6 +3,8 @@ import { Input } from 'features/Common'
import { T9n } from 'features/T9n' import { T9n } from 'features/T9n'
import { Icon } from 'features/Icon' import { Icon } from 'features/Icon'
import { isMobileDevice } from 'config/userAgent'
import { import {
useHighlightsForm, useHighlightsForm,
} from './hooks' } from './hooks'
@ -16,10 +18,12 @@ import {
ScInfoBlock, ScInfoBlock,
} from './styled' } from './styled'
import { PriceInfoType, PriceInfo } from '../PriceInfo'
const labelWidth = 180 const labelWidth = 180
const wrapperHeight = 50 const wrapperHeight = 50
export const FormHighlights = () => { export const FormHighlights = ({ price }: PriceInfoType) => {
const { const {
formRef, formRef,
formState: { formState: {
@ -50,6 +54,7 @@ export const FormHighlights = () => {
return ( return (
<ScWrapper> <ScWrapper>
{isMobileDevice ? <PriceInfo price={price} /> : null}
<ScInfoBlock> <ScInfoBlock>
<ScTitle> <ScTitle>
<T9n t='choose_player' /> <T9n t='choose_player' />

@ -8,6 +8,12 @@ export const ScWrapper = styled.div`
flex-direction: column; flex-direction: column;
color: #FFFFFF; color: #FFFFFF;
padding: 0 80px 0 40px; padding: 0 80px 0 40px;
${isMobileDevice
? css`
padding: 5px;
`
: ''};
` `
export const ScInfoBlock = styled.div` export const ScInfoBlock = styled.div`
display: flex; display: flex;
@ -63,4 +69,10 @@ export const ScForm = styled.form`
max-height: 200px; max-height: 200px;
} }
} }
${isMobileDevice
? css`
max-width: 100%;
`
: ''};
` `

@ -3,6 +3,8 @@ import { Checkbox } from 'features/Common/Checkbox'
import { ArrowLoader } from 'features/ArrowLoader' import { ArrowLoader } from 'features/ArrowLoader'
import { SportIcon } from 'features/SportIcon' import { SportIcon } from 'features/SportIcon'
import { isMobileDevice } from 'config/userAgent'
import { useHighlighMatches } from './hooks' import { useHighlighMatches } from './hooks'
import { import {
@ -22,13 +24,13 @@ import {
ScLoaderWrapper, ScLoaderWrapper,
} from './styled' } from './styled'
export const MatchesHighlights = ({ matches }: any) => { export const MatchesHighlights = () => {
const { onChangeSelectedMatches, playerMatches } = useHighlighMatches() const { onChangeSelectedMatches, playerMatches } = useHighlighMatches()
return ( return (
<ScMatchesWrapper> <ScMatchesWrapper>
<ScTitle> <ScTitle>
<T9n t='matches_highlight' /> <T9n t='matches_highlight' />{isMobileDevice ? ` (${playerMatches.length})` : ''}
</ScTitle> </ScTitle>
<ScMatchesList> <ScMatchesList>
{playerMatches.length ? (playerMatches?.map(({ {playerMatches.length ? (playerMatches?.map(({

@ -15,6 +15,12 @@ export const ScTitle = styled.span`
font-size: 34px; font-size: 34px;
line-height: 40px; line-height: 40px;
margin-bottom: 75px; margin-bottom: 75px;
${isMobileDevice
? css`
text-align: center;
`
: ''};
` `
export const ScMatchesList = styled.div` export const ScMatchesList = styled.div`

@ -8,7 +8,7 @@ import {
ScWatchDemo, ScWatchDemo,
} from './styled' } from './styled'
type PriceInfoType = { export type PriceInfoType = {
price: number, price: number,
} }

@ -1,6 +1,8 @@
import { isMobileDevice } from 'config/userAgent'
import styled, { css } from 'styled-components/macro' import styled, { css } from 'styled-components/macro'
export const ScPriceInfo = styled.div` export const ScPriceInfo = styled.div`
min-width: 106px;
height: 186px; height: 186px;
border: 1px solid #FFFFFF; border: 1px solid #FFFFFF;
border-radius: 34px; border-radius: 34px;
@ -18,19 +20,39 @@ export const ScPriceInfo = styled.div`
> * { > * {
margin: 10px 0; margin: 10px 0;
} }
${isMobileDevice
? css`
font-size: 10px;
padding: 5px;
`
: ''};
` `
export const ScTitle = styled.span` export const ScTitle = styled.span`
text-align: center; text-align: center;
` `
export const ScPrice = styled.span` export const ScPrice = styled.span`
font-size: 80px; font-size: 80px;
text-align: center; text-align: center;
${isMobileDevice
? css`
font-size: 32px;
`
: ''};
` `
export const ScCurrency = styled.span` export const ScCurrency = styled.span`
font-size: 40px; font-size: 40px;
${isMobileDevice
? css`
font-size: 16px;
`
: ''};
` `
export const ScWatchDemo = styled.span` export const ScWatchDemo = styled.span`

@ -0,0 +1,41 @@
import { Icon } from 'features/Icon'
import { T9n } from 'features/T9n'
import { useState } from 'react'
import { useRecoilState } from 'recoil'
import {
ScModal,
ScHeader,
ScTitle,
ScText,
ScButton,
} from './styled'
import { dataForPayHighlights } from '../../storeHighlightsAtoms'
export const ThanksPopup = () => {
const [isOpenThanksPopup, setIsOpenThanksPopup] = useState(true)
const [dataHighlights, setDataHighlights] = useRecoilState(dataForPayHighlights)
return (
<ScModal
isOpen={dataHighlights.isOpenThanksPopup}
close={() => setDataHighlights({ ...dataHighlights, isOpenThanksPopup: false })}
>
<ScHeader>
<T9n t='thank_you' />
</ScHeader>
<Icon refIcon='Check' />
<ScTitle>
<T9n t='order_received' />
</ScTitle>
<ScText>
<T9n t='notify_by_email' />
</ScText>
<ScButton onClick={() => setDataHighlights({ ...dataHighlights, isOpenThanksPopup: false })}>
Ok
</ScButton>
</ScModal>
)
}

@ -0,0 +1,67 @@
import styled, { css } from 'styled-components/macro'
import { ModalWindow } from 'features/Modal/styled'
import { Modal as BaseModal } from 'features/Modal'
import { ButtonSolid } from 'features/Common'
import { isMobileDevice } from 'config/userAgent'
export const ScModal = styled(BaseModal)`
background-color: rgba(0, 0, 0, 0.7);
${ModalWindow} {
background-color: #333333;
border-radius: 5px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
padding: 50px;
width: 497px;
height: 430px;
> * {
margin-bottom: 25px;
}
${isMobileDevice
? css`
width: calc(100vw - 60px);
@media screen and (orientation: landscape){
max-width: calc(100vw - 80px);
height: calc(100vh - 20px);
overflow: auto;
}
`
: ''};
}
`
export const ScHeader = styled.span`
font-weight: 700;
font-size: 28px;
line-height: 24px;
text-align: center;
`
export const ScTitle = styled.span`
font-weight: 400;
font-size: 24px;
line-height: 28px;
text-align: center;
`
export const ScText = styled.span`
font-weight: 400;
font-size: 18px;
line-height: 28px;
text-align: center;
`
export const ScButton = styled(ButtonSolid)`
width: 194px;
height: 50px;
font-weight: 600;
font-size: 20px;
line-height: 50px;
`

@ -1,5 +1,6 @@
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { isMobileDevice } from 'config/userAgent'
import { PAGES } from 'config' import { PAGES } from 'config'
import { useRecoilValue, useRecoilState } from 'recoil' import { useRecoilValue, useRecoilState } from 'recoil'
@ -12,6 +13,7 @@ import { MultiSourcePlayer } from 'features/MultiSourcePlayer'
import { PriceInfo } from './components/PriceInfo' import { PriceInfo } from './components/PriceInfo'
import { FormHighlights } from './components/FormHighlights' import { FormHighlights } from './components/FormHighlights'
import { MatchesHighlights } from './components/MatchesHighlights' import { MatchesHighlights } from './components/MatchesHighlights'
import { ThanksPopup } from './components/ThanksPopup'
import { import {
playerMatchesState, playerMatchesState,
@ -44,12 +46,12 @@ const HighlightsPage = () => {
</Link> </Link>
</ScHeader> </ScHeader>
<ScWrapperContent> <ScWrapperContent>
<PriceInfo price={countIsCheckedMatches * 25} /> {isMobileDevice ? null : <PriceInfo price={countIsCheckedMatches * 25} />}
<FormHighlights /> <FormHighlights price={countIsCheckedMatches * 25} />
<MatchesHighlights /> <MatchesHighlights />
</ScWrapperContent> </ScWrapperContent>
<ScButtonWrap onClick={() => setIsOpenPopupChangeCard(true)}> <ScButtonWrap onClick={() => setIsOpenPopupChangeCard(true)}>
<ScButton disabled={!!countIsCheckedMatches}> <ScButton disabled={!countIsCheckedMatches}>
<T9n t='order_and_buy' /> <T9n t='order_and_buy' />
</ScButton> </ScButton>
</ScButtonWrap> </ScButtonWrap>
@ -60,6 +62,7 @@ const HighlightsPage = () => {
setChangeCardPopupOpen={setIsOpenPopupChangeCard} setChangeCardPopupOpen={setIsOpenPopupChangeCard}
title='payment' title='payment'
/> />
<ThanksPopup />
</ScWrapper> </ScWrapper>
) )
} }

@ -6,12 +6,16 @@ export type PlayerMatchesType = Array<Match & {isChecked: boolean}
> >
type DataForm = { type DataForm = {
duration: number, data: {
lang: string, duration: number,
matches: Array<number>, lang: string,
player_id: number, matches: Array<number>,
sport_id: number, player_id: number,
stats: boolean, price: number,
sport_id: number,
stats: boolean,
},
isOpenThanksPopup: boolean,
} }
export const playerMatchesState = atom({ export const playerMatchesState = atom({

@ -3,6 +3,8 @@ import styled, { css } from 'styled-components/macro'
import { Logo } from 'features/Logo' import { Logo } from 'features/Logo'
import { ButtonSolid } from 'features/Common/Button' import { ButtonSolid } from 'features/Common/Button'
import { isMobileDevice } from 'config/userAgent'
export const ScHeader = styled.div` export const ScHeader = styled.div`
width: 100%; width: 100%;
max-height: 95px; max-height: 95px;
@ -25,6 +27,13 @@ export const ScWrapperContent = styled.div`
display: flex; display: flex;
flex-direction: row; flex-direction: row;
padding: 100px 170px 82px 170px; padding: 100px 170px 82px 170px;
${isMobileDevice
? css`
padding: 5px;
flex-direction: column;
`
: ''};
` `
export const ScButton = styled(ButtonSolid)` export const ScButton = styled(ButtonSolid)`

@ -3,22 +3,32 @@ import { callApi } from 'helpers'
export type Props = { export type Props = {
cardId: string, cardId: string,
item: { order: {
duration: number, duration: number,
lang: string, lang: string,
matches: Array<number>, matches: Array<number>,
player_id: number, player_id: number,
price: number,
sport_id: number, sport_id: number,
stats: boolean, stats: boolean,
}, },
} }
export const onePayment = async ({ cardId, item }: Props) => { export const onePayment = async ({
cardId,
order,
}: Props) => {
const config = { const config = {
body: { body: {
action: 'one_payment', action: 'one_payment',
card_id: cardId, data: {
item, card_id: cardId,
item: {
currency_iso: 'USD',
order,
price: order.price,
},
},
service: 'stripe_ott', service: 'stripe_ott',
}, },
} }

Loading…
Cancel
Save