feat(ott-1726): add choise of subscription on buy match popup (#546)

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
PolyakovaM 4 years ago committed by Mirlan
parent b681fa3fd6
commit 64403dd85e
  1. 1
      src/config/lexics/indexLexics.tsx
  2. 118
      src/features/BuyMatchPopup/components/SelectSubscription/index.tsx
  3. 27
      src/features/BuyMatchPopup/components/SubscriptionSelectionStep/index.tsx
  4. 1
      src/features/BuyMatchPopup/components/SubscriptionsList/styled.tsx
  5. 2
      src/features/BuyMatchPopup/index.tsx
  6. 2
      src/features/BuyMatchPopup/store/helpers.tsx
  7. 48
      src/features/BuyMatchPopup/store/hooks/index.tsx
  8. 59
      src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx
  9. 29
      src/features/BuyMatchPopup/store/hooks/useSubscriptionsLexics.tsx
  10. 7
      src/features/BuyMatchPopup/styled.tsx
  11. 1
      src/features/BuyMatchPopup/types.tsx
  12. 15
      src/requests/getSubscriptions.tsx

@ -47,6 +47,7 @@ const buyMatchPopupLexics = {
for_month: 13561,
for_view: 15064,
for_year: 13562,
next_choose: 15156,
pass_league: 15065,
pass_match_access: 15067,
pass_team: 15066,

@ -0,0 +1,118 @@
import { useState } from 'react'
import styled from 'styled-components/macro'
import map from 'lodash/map'
import { MDASH } from 'config'
import { SelectSubscriptionData } from 'requests'
import { Name as Names } from 'features/Name'
import { T9n } from 'features/T9n'
import { useBuyMatchPopupStore } from 'features/BuyMatchPopup/store'
import { CloseButton, HeaderActions } from 'features/PopupComponents'
import { ArrowLoader } from 'features/ArrowLoader'
import {
Body,
Button,
Footer,
Header,
HeaderTitle,
Wrapper,
} from 'features/BuyMatchPopup/styled'
import {
Description,
InfoWrapper,
Item,
List,
Name,
Pass,
} from '../SubscriptionsList/styled'
export const ChooseSub = styled.div`
font-weight: 600;
font-size: 16px;
margin: 30px 0;
`
export const SelectSubscriptionStep = () => {
const [active, setActive] = useState<number | null>(null)
const {
close,
initialSubscription,
loader,
match,
onChooseSub,
onSubscriptionPackagesSelect,
selectedSubscriptionPackage,
setSelectSubName,
} = useBuyMatchPopupStore()
if (!match || !initialSubscription) return null
const onItemClick = (subscription: SelectSubscriptionData, index: number) => {
onSubscriptionPackagesSelect({
...subscription.packages,
season: initialSubscription.season,
})
setActive(index)
setSelectSubName(subscription.lexic)
}
return (
<Wrapper>
<Header>
<HeaderTitle>
<Names nameObj={match.team1} />
{` ${MDASH} `}
<Names nameObj={match.team2} />
<ChooseSub>
<T9n t='choose_subscription' />
</ChooseSub>
</HeaderTitle>
<HeaderActions position='right'>
<CloseButton onClick={close} />
</HeaderActions>
</Header>
<Body marginTop={15}>
<List>
{
map(initialSubscription.data, (subscription, index) => (
<Item
key={subscription.id}
onClick={() => onItemClick(subscription, index)}
active={active === index}
>
<InfoWrapper>
<Pass>
<T9n t={subscription.lexic} />
</Pass>
<Name>
<T9n t={subscription.lexic2} />
</Name>
<Description>
<T9n t={subscription.lexic3} />
</Description>
</InfoWrapper>
</Item>
))
}
</List>
</Body>
<Footer>
{loader
? <ArrowLoader width='204px' disabled />
: (
<Button
disabled={!selectedSubscriptionPackage}
onClick={onChooseSub}
>
<T9n t='next_choose' />
</Button>
)}
</Footer>
</Wrapper>
)
}

@ -1,4 +1,4 @@
import { useEffect } from 'react'
import { Fragment, useEffect } from 'react'
import isNull from 'lodash/isNull'
@ -21,6 +21,7 @@ import {
Body,
Footer,
Button,
ButtonPrevious,
Header,
HeaderTitle,
} from '../../styled'
@ -33,10 +34,13 @@ export const SubscriptionSelectionStep = () => {
const {
close,
getSub,
loader,
match,
onBuyClick,
selectedSubName,
selectedSubscription,
selectedSubStep,
} = useBuyMatchPopupStore()
useEffect(() => {
@ -50,10 +54,25 @@ export const SubscriptionSelectionStep = () => {
return (
<Wrapper>
<Header>
{selectedSubStep
&& (
<HeaderActions position='left'>
<ButtonPrevious
onClick={getSub}
direction='left'
/>
</HeaderActions>
)}
<HeaderTitle>
<Name nameObj={match.team1} />
{` ${MDASH} `}
<Name nameObj={match.team2} />
{selectedSubStep
? <T9n t={selectedSubName} />
: (
<Fragment>
<Name nameObj={match.team1} />
{` ${MDASH} `}
<Name nameObj={match.team2} />
</Fragment>
)}
</HeaderTitle>
<HeaderActions position='right'>
<CloseButton onClick={close} />

@ -63,6 +63,7 @@ export const Item = styled.li.attrs(() => ({
justify-content: space-between;
align-items: center;
cursor: pointer;
overflow: auto;
:not(:last-child) {
margin-bottom: 20px;

@ -2,6 +2,7 @@ import { CardStep } from './components/CardStep'
import { ErrorStep } from './components/ErrorStep'
import { SuccessStep } from './components/SuccessStep'
import { SubscriptionSelectionStep } from './components/SubscriptionSelectionStep'
import { SelectSubscriptionStep } from './components/SelectSubscription'
import { Steps } from './types'
import { Modal } from './styled'
@ -15,6 +16,7 @@ const components = {
[Steps.CardSelection]: CardStep,
[Steps.Success]: SuccessStep,
[Steps.Error]: ErrorStep,
[Steps.SelectSubscription]: SelectSubscriptionStep,
}
export const BuyMatchPopup = () => {

@ -50,7 +50,7 @@ const transformSubscription = ({
team: teamName,
},
},
id: `${key} ${subscription.id}`,
id: `${key} ${subscription.sub.id}`,
name: teamName,
originalObject: subscription,
pass: passLexics[key],

@ -9,6 +9,7 @@ import { useHistory } from 'react-router-dom'
import type { PaymentIntent, StripeError } from '@stripe/stripe-js'
import last from 'lodash/last'
import isEmpty from 'lodash/isEmpty'
import { PAGES, ProfileTypes } from 'config'
@ -48,6 +49,8 @@ export const useBuyMatchPopup = () => {
const [match, setMatch] = useState<Match | null>(null)
const [error, setError] = useState('')
const [loader, setLoader] = useState(false)
const [selectedSubStep, setSelectedSubStep] = useState(false)
const [selectedSubName, setSelectSubName] = useState<number>(0)
const goTo = useCallback(
(step: Steps, e?: MouseEvent<HTMLButtonElement>) => setSteps((state) => {
@ -65,27 +68,48 @@ export const useBuyMatchPopup = () => {
return newState
}), [])
const openPopup = useCallback((matchData: Match) => {
setMatch(matchData)
setSteps([Steps.Subscriptions])
}, [])
const {
fetchSubscriptions,
fetchSubscriptionsPackages,
initialSubscription,
matchSubscriptions,
onPeriodSelect,
onSubscriptionPackagesSelect,
onSubscriptionSelect,
resetSubscriptions,
selectedPeriod,
selectedSubscription,
selectedSubscriptionPackage,
setSelectedSubscriptionPackage,
subscriptions,
} = useSubscriptions()
const onChooseSub = () => {
if (match) {
fetchSubscriptionsPackages(match)
setSelectedSubStep(true)
}
}
const openPopup = useCallback((matchData: Match) => {
setMatch(matchData)
}, [])
useEffect(() => {
if (!isEmpty(initialSubscription)) {
!initialSubscription?.data
? setSteps([Steps.Subscriptions])
: setSteps([Steps.SelectSubscription])
}
}, [subscriptions, initialSubscription])
const closePopup = () => {
setMatch(null)
setSteps([])
setError('')
resetSubscriptions()
setSelectedSubscriptionPackage(null)
setSelectedSubStep(false)
if (isMatchPage()) history.push(PAGES.home)
}
@ -158,28 +182,40 @@ export const useBuyMatchPopup = () => {
}
}
useEffect(() => {
const getSub = useCallback(() => {
if (match) {
fetchSubscriptions(match)
}
}, [match, fetchSubscriptions])
useEffect(() => {
getSub()
}, [getSub])
return {
close: closePopup,
currentStep: last(steps),
error,
getSub,
goBack,
goTo,
initialSubscription,
loader,
match,
matchSubscriptions,
onBuyClick,
onChooseSub,
onPeriodSelect,
onSubscriptionPackagesSelect,
onSubscriptionSelect,
open: openPopup,
postPaymentHandler,
selectedPeriod,
selectedSubName,
selectedSubStep,
selectedSubscription,
selectedSubscriptionPackage,
setSelectSubName,
subscriptions,
}
}

@ -8,7 +8,7 @@ import find from 'lodash/find'
import isEmpty from 'lodash/isEmpty'
import first from 'lodash/first'
import { getSubscriptions } from 'requests'
import { getSubscriptions, SubscriptionsByPeriods } from 'requests'
import { useLexicsStore } from 'features/LexicsStore'
@ -19,6 +19,7 @@ import type {
} from '../../types'
import { SubscriptionType } from '../../types'
import { transformSubsciptions } from '../helpers'
import { useSubscriptionsLexics } from './useSubscriptionsLexics'
const defaultSubscriptions: MatchSubscriptions = {
[SubscriptionType.Month]: [],
@ -28,24 +29,53 @@ const defaultSubscriptions: MatchSubscriptions = {
export const useSubscriptions = () => {
const { suffix } = useLexicsStore()
const { fetchLexics } = useSubscriptionsLexics()
const [selectedPeriod, setSelectedPeriod] = useState(SubscriptionType.Month)
const [matchSubscriptions, setMatchSubscriptionsList] = useState(defaultSubscriptions)
const [selectedSubscription, setSelectedSubscription] = useState<MatchSubscription | null>(null)
const [
initialSubscription, setInitialSubscription,
] = useState<SubscriptionsByPeriods | null>(null)
const [
selectedSubscriptionPackage, setSelectedSubscriptionPackage,
] = useState<SubscriptionsByPeriods | null>(null)
const fetchSubscriptions = useCallback((match: Match) => {
getSubscriptions(match.sportType, match.id)
.then((subscriptions) => transformSubsciptions({
const fetchSubscriptions = useCallback(async (match: Match) => {
const subscriptions = await getSubscriptions(match.sportType, match.id)
if (!subscriptions.data) {
const convertedSubscriptions = transformSubsciptions({
match,
subscriptions,
suffix,
}))
.then((subscriptions) => {
setMatchSubscriptionsList(subscriptions)
const firstSubscription = find(subscriptions, (subscription) => !isEmpty(subscription))
setSelectedPeriod(first(firstSubscription)?.type || SubscriptionType.Month)
})
}, [suffix])
setInitialSubscription(subscriptions)
setMatchSubscriptionsList(convertedSubscriptions)
const firstSubscription = find(
convertedSubscriptions, (subscription) => !isEmpty(subscription),
)
setSelectedPeriod(first(firstSubscription)?.type || SubscriptionType.Month)
} else {
setInitialSubscription(subscriptions)
fetchLexics(subscriptions.data)
}
}, [fetchLexics, suffix])
const fetchSubscriptionsPackages = useCallback((match) => {
if (selectedSubscriptionPackage) {
const convertedSubscriptions = transformSubsciptions({
match,
subscriptions: selectedSubscriptionPackage,
suffix,
})
setInitialSubscription(selectedSubscriptionPackage)
setMatchSubscriptionsList(convertedSubscriptions)
const firstSubscription = find(
convertedSubscriptions, (subscription) => !isEmpty(subscription),
)
setSelectedPeriod(first(firstSubscription)?.type || SubscriptionType.Month)
}
}, [selectedSubscriptionPackage, suffix])
const resetSubscriptions = useCallback(() => {
setSelectedSubscription(null)
@ -56,6 +86,10 @@ export const useSubscriptions = () => {
setSelectedSubscription(subscription === selectedSubscription ? null : subscription)
}
const onSubscriptionPackagesSelect = (packages: SubscriptionsByPeriods) => {
setSelectedSubscriptionPackage(packages === selectedSubscriptionPackage ? null : packages)
}
useEffect(() => {
const isOnlySubscriptionVariant = matchSubscriptions[selectedPeriod].length === 1
if (isOnlySubscriptionVariant) {
@ -67,12 +101,17 @@ export const useSubscriptions = () => {
return {
fetchSubscriptions,
fetchSubscriptionsPackages,
initialSubscription,
matchSubscriptions,
onPeriodSelect: setSelectedPeriod,
onSubscriptionPackagesSelect,
onSubscriptionSelect,
resetSubscriptions,
selectedPeriod,
selectedSubscription,
selectedSubscriptionPackage,
setSelectedSubscriptionPackage,
subscriptions: matchSubscriptions[selectedPeriod],
}
}

@ -0,0 +1,29 @@
import { useCallback } from 'react'
import isEmpty from 'lodash/isEmpty'
import flatMap from 'lodash/flatMap'
import uniq from 'lodash/uniq'
import type { SelectSubscriptionData } from 'requests'
import { useLexicsStore } from 'features/LexicsStore'
export const useSubscriptionsLexics = () => {
const { addLexicsConfig } = useLexicsStore()
const fetchLexics = useCallback((data: Array<SelectSubscriptionData>) => {
const lexics = uniq(flatMap(data, ({
lexic,
lexic2,
lexic3,
}) => [lexic, lexic2, lexic3]))
if (!isEmpty(lexics)) {
addLexicsConfig(lexics)
}
return data
}, [addLexicsConfig])
return { fetchLexics }
}

@ -5,6 +5,7 @@ import { isMobileDevice } from 'config/userAgent'
import { ButtonSolid } from 'features/Common'
import { ModalWindow } from 'features/Modal/styled'
import { Modal as BaseModal } from 'features/Modal'
import { Arrow } from 'features/HeaderFilters/components/DateFilter/styled'
export const Modal = styled(BaseModal)`
background-color: rgba(0, 0, 0, 0.7);
@ -183,3 +184,9 @@ export const ResultText = styled.span`
export const SmallButton = styled(Button)`
min-width: 70px;
`
export const ButtonPrevious = styled(Arrow)`
top: 30px;
left: 30px;
cursor: pointer;
`

@ -5,6 +5,7 @@ import type { SubscriptionResponse } from 'requests'
export enum Steps {
CardSelection = 'CardSelection',
Error = 'Error',
SelectSubscription = 'SelectSubscription',
Subscriptions = 'Subscriptions',
Success = 'Success',
}

@ -8,13 +8,28 @@ import { callApi } from 'helpers'
const proc = PROCEDURES.get_match_subscriptions
export type SelectSubscriptionData = {
id: number,
lexic: number,
lexic2: number,
lexic3: number,
packages: SelectSubscriptionPackages,
}
export type SubscriptionsByPeriods = {
data?: Array<SelectSubscriptionData>,
month: Subscriptions,
pay_per_view: SubscriptionResponse,
season: Season,
year: Subscriptions,
}
export type SelectSubscriptionPackages = Pick<SubscriptionsByPeriods, (
'month'
| 'pay_per_view'
| 'year'
)>
export type Subscriptions = {
all: SubscriptionResponse,
team1: SubscriptionResponse,

Loading…
Cancel
Save