fix(2105): subscriptions lexic and per view tab rendering

keep-around/18b5c8c2d85d9265c82f81450a4aa6ac0a73fdd3
Mirlan 4 years ago committed by Макситалиев Мирлан
parent c838b5b01b
commit 18b5c8c2d8
  1. 28
      src/features/BuyMatchPopup/components/PackageSelectionStep/index.tsx
  2. 20
      src/features/BuyMatchPopup/components/Packages/index.tsx
  3. 70
      src/features/BuyMatchPopup/components/PackagesList/index.tsx
  4. 5
      src/features/BuyMatchPopup/components/PackagesList/styled.tsx
  5. 80
      src/features/BuyMatchPopup/components/SelectSubscription/index.tsx
  6. 19
      src/features/BuyMatchPopup/components/SelectSubscription/styled.tsx
  7. 62
      src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx
  8. 4
      src/features/BuyMatchPopup/index.tsx
  9. 124
      src/features/BuyMatchPopup/store/helpers.tsx
  10. 62
      src/features/BuyMatchPopup/store/hooks/index.tsx
  11. 121
      src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx
  12. 4
      src/features/BuyMatchPopup/store/hooks/useSubscriptionsLexics.tsx
  13. 21
      src/features/BuyMatchPopup/styled.tsx
  14. 24
      src/features/BuyMatchPopup/types.tsx
  15. 6
      src/features/PaymentPeriodTabs/helpers.tsx
  16. 25
      src/features/PaymentPeriodTabs/index.tsx
  17. 29
      src/requests/getSubscriptions.tsx

@ -12,10 +12,11 @@ import { T9n } from 'features/T9n'
import { Name } from 'features/Name' import { Name } from 'features/Name'
import { useCardsStore } from 'features/CardsStore' import { useCardsStore } from 'features/CardsStore'
import { ArrowLoader } from 'features/ArrowLoader' import { ArrowLoader } from 'features/ArrowLoader'
import { Arrow } from 'features/HeaderFilters/components/DateFilter/styled'
import { useBuyMatchPopupStore } from '../../store' import { useBuyMatchPopupStore } from '../../store'
import { SelectedCard } from '../SelectedCard' import { SelectedCard } from '../SelectedCard'
import { Subscriptions } from '../Subscriptions' import { Packages } from '../Packages'
import { import {
Wrapper, Wrapper,
Body, Body,
@ -26,7 +27,7 @@ import {
HeaderTitle, HeaderTitle,
} from '../../styled' } from '../../styled'
export const SubscriptionSelectionStep = () => { export const PackageSelectionStep = () => {
const { const {
cards, cards,
fetchCards, fetchCards,
@ -34,13 +35,13 @@ export const SubscriptionSelectionStep = () => {
const { const {
close, close,
getSub, goBack,
hasPreviousStep,
loader, loader,
match, match,
onBuyClick, onBuyClick,
selectedSubName, selectedPackage,
selectedSubscription, selectedSubscription,
selectedSubStep,
} = useBuyMatchPopupStore() } = useBuyMatchPopupStore()
useEffect(() => { useEffect(() => {
@ -54,17 +55,16 @@ export const SubscriptionSelectionStep = () => {
return ( return (
<Wrapper> <Wrapper>
<Header> <Header>
{selectedSubStep && ( {hasPreviousStep && (
<HeaderActions position='left'> <HeaderActions position='left'>
<ButtonPrevious <ButtonPrevious onClick={goBack}>
onClick={getSub} <Arrow direction='left' />
direction='left' </ButtonPrevious>
/>
</HeaderActions> </HeaderActions>
)} )}
<HeaderTitle> <HeaderTitle>
{selectedSubStep {hasPreviousStep && selectedSubscription
? <T9n t={selectedSubName} /> ? <T9n t={selectedSubscription?.lexic} />
: ( : (
<Fragment> <Fragment>
<Name nameObj={match.team1} /> <Name nameObj={match.team1} />
@ -78,7 +78,7 @@ export const SubscriptionSelectionStep = () => {
</HeaderActions> </HeaderActions>
</Header> </Header>
<Body marginTop={20}> <Body marginTop={20}>
<Subscriptions /> <Packages />
<SelectedCard /> <SelectedCard />
</Body> </Body>
<Footer> <Footer>
@ -86,7 +86,7 @@ export const SubscriptionSelectionStep = () => {
? <ArrowLoader width='204px' disabled /> ? <ArrowLoader width='204px' disabled />
: ( : (
<Button <Button
disabled={!selectedSubscription} disabled={!selectedPackage}
onClick={onBuyClick} onClick={onBuyClick}
> >
<T9n t='buy_subscription' /> <T9n t='buy_subscription' />

@ -3,7 +3,7 @@ import styled from 'styled-components/macro'
import { PaymentPeriodTabs } from 'features/PaymentPeriodTabs' import { PaymentPeriodTabs } from 'features/PaymentPeriodTabs'
import { useBuyMatchPopupStore } from '../../store' import { useBuyMatchPopupStore } from '../../store'
import { SubscriptionsList } from '../SubscriptionsList' import { PackagesList } from '../PackagesList'
const Wrapper = styled.div` const Wrapper = styled.div`
width: 100%; width: 100%;
@ -12,27 +12,29 @@ const Wrapper = styled.div`
align-items: center; align-items: center;
` `
export const Subscriptions = () => { export const Packages = () => {
const { const {
matchSubscriptions, onPackageSelect,
onPeriodSelect, onPeriodSelect,
onSubscriptionSelect, selectedPackage,
selectedPeriod, selectedPeriod,
selectedSubscription, selectedSubscription,
subscriptions, subscriptions,
} = useBuyMatchPopupStore() } = useBuyMatchPopupStore()
if (!selectedSubscription) return null
return ( return (
<Wrapper> <Wrapper>
<PaymentPeriodTabs <PaymentPeriodTabs
onPeriodSelect={onPeriodSelect} onPeriodSelect={onPeriodSelect}
selectedPeriod={selectedPeriod} selectedPeriod={selectedPeriod}
matchSubscriptions={matchSubscriptions}
/>
<SubscriptionsList
subscriptions={subscriptions}
selectedSubscription={selectedSubscription} selectedSubscription={selectedSubscription}
onSelect={onSubscriptionSelect} />
<PackagesList
packages={subscriptions}
selectedPackage={selectedPackage}
onSelect={onPackageSelect}
/> />
</Wrapper> </Wrapper>
) )

@ -0,0 +1,70 @@
import isNumber from 'lodash/isNumber'
import map from 'lodash/map'
import { T9n } from 'features/T9n'
import { MatchPackage, SubscriptionType } from 'features/BuyMatchPopup/types'
import {
Pass,
Name,
Description,
InfoWrapper,
Item,
List,
Price,
} from './styled'
type Props = {
onSelect: (subscription: MatchPackage) => void,
packages: Array<MatchPackage>,
selectedPackage: MatchPackage | null,
}
export const PackagesList = ({
onSelect,
packages,
selectedPackage,
}: Props) => (
<List>
{
map(
packages,
(subPackage) => (
<Item
key={subPackage.id}
onClick={() => onSelect(subPackage)}
active={subPackage === selectedPackage}
>
<InfoWrapper>
<Pass>
<T9n t={subPackage.pass} />
</Pass>
<Name>
{
isNumber(subPackage.nameLexic)
? <T9n t={subPackage.nameLexic} />
: subPackage.name
}
</Name>
<Description>
<T9n
t={subPackage.description.lexic}
values={subPackage.description.values}
/>
</Description>
</InfoWrapper>
<Price
amount={subPackage.price}
currency={subPackage.currency}
perPeriod={
subPackage.type !== SubscriptionType.Month
? null
: `per_${subPackage.type}`
}
/>
</Item>
),
)
}
</List>
)

@ -12,8 +12,6 @@ import {
export const List = styled.ul` export const List = styled.ul`
width: 100%; width: 100%;
height: 460px; height: 460px;
display: flex;
flex-direction: column;
overflow-y: auto; overflow-y: auto;
margin-top: 25px; margin-top: 25px;
padding: 0 40px; padding: 0 40px;
@ -63,6 +61,7 @@ export const Item = styled.li.attrs(() => ({
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
cursor: pointer; cursor: pointer;
transition: background-color 0.3s;
:not(:last-child) { :not(:last-child) {
margin-bottom: 20px; margin-bottom: 20px;
@ -97,7 +96,7 @@ export const Item = styled.li.attrs(() => ({
} }
` `
: ''}; : ''};
@media (max-width: 850px) and (orientation: landscape){ @media (max-width: 850px) and (orientation: landscape){
min-height: 52.29px; min-height: 52.29px;
height: 52.29px; height: 52.29px;

@ -1,18 +1,12 @@
import { useState } from 'react' import first from 'lodash/first'
import styled from 'styled-components/macro'
import map from 'lodash/map' import map from 'lodash/map'
import isNull from 'lodash/isNull'
import { MDASH } from 'config' import { MDASH } from 'config'
import { SelectSubscriptionData } from 'requests'
import { Name as Names } from 'features/Name' import { Name as Names } from 'features/Name'
import { T9n } from 'features/T9n' import { T9n } from 'features/T9n'
import { useBuyMatchPopupStore } from 'features/BuyMatchPopup/store' import { useBuyMatchPopupStore } from 'features/BuyMatchPopup/store'
import { CloseButton, HeaderActions } from 'features/PopupComponents' import { CloseButton, HeaderActions } from 'features/PopupComponents'
import { ArrowLoader } from 'features/ArrowLoader'
import { import {
Body, Body,
@ -25,52 +19,28 @@ import {
import { import {
Description, Description,
InfoWrapper, InfoWrapper,
Item,
List,
Name, Name,
Pass, Pass,
} from '../SubscriptionsList/styled' } from '../PackagesList/styled'
import { Price } from './styled'
export const ChooseSub = styled.div`
font-weight: 600;
font-size: 16px;
margin: 35px 0 17px;
`
export const ChooseSubItem = styled(Item)`
min-height: auto;
`
export const ChooseSubList = styled(List)` import {
height: auto; Price,
` ChooseSub,
ChooseSubItem,
ChooseSubList,
} from './styled'
export const SelectSubscriptionStep = () => { export const SelectSubscriptionStep = () => {
const [active, setActive] = useState<number | null>(null)
const { const {
close, close,
initialSubscription,
loader,
match, match,
onChooseSub, matchSubscriptions,
onSubscriptionPackagesSelect, onNext,
selectedSubscriptionPackage, onSubscriptionSelect,
setSelectSubName, selectedSubscription,
} = useBuyMatchPopupStore() } = useBuyMatchPopupStore()
if (!match || !initialSubscription) return null if (!match || !matchSubscriptions) return null
const onItemClick = (subscription: SelectSubscriptionData, index: number) => {
onSubscriptionPackagesSelect({
...subscription.packages,
season: initialSubscription.season,
})
index === active ? setActive(null) : setActive(index)
setSelectSubName(subscription.lexic)
}
return ( return (
<Wrapper> <Wrapper>
@ -89,11 +59,11 @@ export const SelectSubscriptionStep = () => {
</Header> </Header>
<Body marginTop={15}> <Body marginTop={15}>
<ChooseSubList> <ChooseSubList>
{map(initialSubscription.data, (subscription, index) => ( {map(matchSubscriptions, (subscription) => (
<ChooseSubItem <ChooseSubItem
key={subscription.id} key={subscription.id}
onClick={() => onItemClick(subscription, index)} onClick={() => onSubscriptionSelect(subscription)}
active={active === index} active={subscription === selectedSubscription}
> >
<InfoWrapper> <InfoWrapper>
<Pass> <Pass>
@ -109,7 +79,7 @@ export const SelectSubscriptionStep = () => {
<Price <Price
amount={subscription.min_price || 0} amount={subscription.min_price || 0}
currency={subscription.packages.month.all.currency_iso} currency={first(subscription.packages.month)?.currency}
isFrom={Boolean(subscription.min_price)} isFrom={Boolean(subscription.min_price)}
/> />
</ChooseSubItem> </ChooseSubItem>
@ -117,16 +87,12 @@ export const SelectSubscriptionStep = () => {
</ChooseSubList> </ChooseSubList>
</Body> </Body>
<Footer> <Footer>
{loader <Button
? <ArrowLoader width='204px' disabled /> disabled={!selectedSubscription}
: ( onClick={onNext}
<Button >
disabled={!selectedSubscriptionPackage || isNull(active)} <T9n t='next_choose' />
onClick={onChooseSub} </Button>
>
<T9n t='next_choose' />
</Button>
)}
</Footer> </Footer>
</Wrapper> </Wrapper>
) )

@ -2,6 +2,11 @@ import styled from 'styled-components/macro'
import { Price as BasePrice } from 'features/Price' import { Price as BasePrice } from 'features/Price'
import { PriceAmount, PriceDetails } from 'features/Price/styled' import { PriceAmount, PriceDetails } from 'features/Price/styled'
import {
Item,
List,
} from '../PackagesList/styled'
export const Price = styled(BasePrice)` export const Price = styled(BasePrice)`
${PriceAmount} { ${PriceAmount} {
font-size: 24px; font-size: 24px;
@ -12,3 +17,17 @@ export const Price = styled(BasePrice)`
font-size: 12px; font-size: 12px;
} }
` `
export const ChooseSub = styled.div`
font-weight: 600;
font-size: 16px;
margin: 35px 0 17px;
`
export const ChooseSubItem = styled(Item)`
min-height: auto;
`
export const ChooseSubList = styled(List)`
height: auto;
`

@ -1,62 +0,0 @@
import map from 'lodash/map'
import { T9n } from 'features/T9n'
import { MatchSubscription, SubscriptionType } from 'features/BuyMatchPopup/types'
import {
Pass,
Name,
Description,
InfoWrapper,
Item,
List,
Price,
} from './styled'
type Props = {
onSelect: (subscription: MatchSubscription) => void,
selectedSubscription: MatchSubscription | null,
subscriptions: Array<MatchSubscription>,
}
export const SubscriptionsList = ({
onSelect,
selectedSubscription,
subscriptions,
}: Props) => (
<List>
{
map(
subscriptions,
(subscription) => {
const { description, type } = subscription
return (
<Item
key={subscription.id}
onClick={() => onSelect?.(subscription)}
active={subscription === selectedSubscription}
>
<InfoWrapper>
<Pass>
<T9n t={subscription.pass} />
</Pass>
<Name>
{subscription.name}
</Name>
<Description>
<T9n t={description.lexic} values={description.values} />
</Description>
</InfoWrapper>
<Price
amount={subscription.price}
currency={subscription.currency}
perPeriod={type !== SubscriptionType.Month ? null : `per_${type}`}
/>
</Item>
)
},
)
}
</List>
)

@ -1,7 +1,7 @@
import { CardStep } from './components/CardStep' import { CardStep } from './components/CardStep'
import { ErrorStep } from './components/ErrorStep' import { ErrorStep } from './components/ErrorStep'
import { SuccessStep } from './components/SuccessStep' import { SuccessStep } from './components/SuccessStep'
import { SubscriptionSelectionStep } from './components/SubscriptionSelectionStep' import { PackageSelectionStep } from './components/PackageSelectionStep'
import { SelectSubscriptionStep } from './components/SelectSubscription' import { SelectSubscriptionStep } from './components/SelectSubscription'
import { Steps } from './types' import { Steps } from './types'
@ -12,7 +12,7 @@ export * from './store'
export * from './store/helpers' export * from './store/helpers'
const components = { const components = {
[Steps.Subscriptions]: SubscriptionSelectionStep, [Steps.SelectPackage]: PackageSelectionStep,
[Steps.CardSelection]: CardStep, [Steps.CardSelection]: CardStep,
[Steps.Success]: SuccessStep, [Steps.Success]: SuccessStep,
[Steps.Error]: ErrorStep, [Steps.Error]: ErrorStep,

@ -3,8 +3,10 @@ import map from 'lodash/map'
import { currencySymbols } from 'config' import { currencySymbols } from 'config'
import type { import type {
SubscriptionsByPeriods, SubscriptionsData,
Subscriptions, Subscription,
Packages,
Season,
} from 'requests/getSubscriptions' } from 'requests/getSubscriptions'
import { getName } from 'features/Name' import { getName } from 'features/Name'
@ -12,7 +14,9 @@ import { getName } from 'features/Name'
import type { import type {
MatchSubscriptions, MatchSubscriptions,
MatchSubscription, MatchSubscription,
MatchPackage,
Match, Match,
Desciption,
} from '../types' } from '../types'
import { SubscriptionType } from '../types' import { SubscriptionType } from '../types'
import { import {
@ -23,79 +27,119 @@ import {
type SubscriptionArgs = { type SubscriptionArgs = {
match: Match, match: Match,
subscriptions: SubscriptionsByPeriods, season: Season,
subscription: Subscription,
suffix: string, suffix: string,
} }
const transformSubscription = ({ const transformPackage = ({
match, match,
subscriptions, season,
subscription,
suffix, suffix,
}: SubscriptionArgs) => ( }: SubscriptionArgs) => (
type: SubscriptionType.Month | SubscriptionType.Year, type: SubscriptionType.Month | SubscriptionType.Year,
): Array<MatchSubscription> => { ): Array<MatchPackage> => (
const { season } = subscriptions map(subscription.packages[type], (subscriptionPackage, rawKey) => {
return map(subscriptions[type], (subscription, rawKey) => { const key = rawKey as keyof Packages
const key = rawKey as keyof Subscriptions const isLeaguePass = key === 'all'
const teamName = getName({ const teamName = getName({
nameObj: match[passNameKeys[key]], nameObj: match[passNameKeys[key]],
suffix, suffix,
}) })
return { const description: Desciption = isLeaguePass
currency: currencySymbols[subscription.currency_iso], ? {
description: { lexic: subscription.lexic3,
values: {},
}
: {
lexic: descriptionLexics[key], lexic: descriptionLexics[key],
values: { values: {
season: season.name, season: season.name,
team: teamName, team: teamName,
}, },
}, }
id: `${key} ${subscription.sub.id}`, const nameLexic = isLeaguePass ? subscription.lexic2 : null
return {
currency: currencySymbols[subscriptionPackage.currency_iso],
description,
id: `${key} ${subscriptionPackage.sub.id}`,
name: teamName, name: teamName,
originalObject: subscription, nameLexic,
originalObject: subscriptionPackage,
pass: passLexics[key], pass: passLexics[key],
price: subscription.price, price: subscriptionPackage.price,
seasonName: season.name,
type, type,
} }
}) })
} )
type SubsciptionsArgs = { type PackagesArgs = {
match: Match, match: Match,
subscriptions: SubscriptionsByPeriods, season: Season,
subscription: Subscription,
suffix: string, suffix: string,
} }
export const transformSubsciptions = ({ const transformPackages = ({
match, match,
subscriptions, season,
subscription,
suffix, suffix,
}: SubsciptionsArgs): MatchSubscriptions => { }: PackagesArgs): MatchSubscription => {
const { pay_per_view: payPerView } = subscriptions const { pay_per_view: payPerView } = subscription.packages
const team1Name = getName({ nameObj: match.team1, suffix }) const team1Name = getName({ nameObj: match.team1, suffix })
const team2Name = getName({ nameObj: match.team2, suffix }) const team2Name = getName({ nameObj: match.team2, suffix })
const transformByType = transformSubscription({ const transformByType = transformPackage({
match, match,
subscriptions, season,
subscription,
suffix, suffix,
}) })
return { const packages = {
[SubscriptionType.Month]: transformByType(SubscriptionType.Month), [SubscriptionType.Month]: transformByType(SubscriptionType.Month),
[SubscriptionType.Year]: transformByType(SubscriptionType.Year), [SubscriptionType.Year]: transformByType(SubscriptionType.Year),
[SubscriptionType.PayPerView]: subscriptions.pay_per_view ? ([{ [SubscriptionType.PayPerView]:
currency: currencySymbols[payPerView?.currency_iso], payPerView
description: { ? [{
lexic: 'description_match_live_and_on_demand', currency: currencySymbols[payPerView.currency_iso],
values: {}, description: {
}, lexic: 'description_match_live_and_on_demand',
id: '0', values: {},
name: `${team1Name} - ${team2Name}`, },
originalObject: payPerView, id: '0',
pass: 'pass_match_access', name: `${team1Name} - ${team2Name}`,
price: payPerView?.price, originalObject: payPerView,
type: SubscriptionType.PayPerView, pass: 'pass_match_access',
}]) : [], price: payPerView.price,
type: SubscriptionType.PayPerView,
}]
: [],
}
return {
...subscription,
packages,
} }
} }
type SubsciptionsArgs = {
match: Match,
subscriptions: SubscriptionsData,
suffix: string,
}
export const transformSubscriptions = ({
match,
subscriptions,
suffix,
}: SubsciptionsArgs): MatchSubscriptions => map(
subscriptions.data,
(subscription) => transformPackages({
match,
season: subscriptions.season,
subscription,
suffix,
}),
)

@ -50,8 +50,6 @@ export const useBuyMatchPopup = () => {
const [match, setMatch] = useState<Match | null>(null) const [match, setMatch] = useState<Match | null>(null)
const [error, setError] = useState('') const [error, setError] = useState('')
const [loader, setLoader] = useState(false) const [loader, setLoader] = useState(false)
const [selectedSubStep, setSelectedSubStep] = useState(false)
const [selectedSubName, setSelectSubName] = useState<number>(0)
const goTo = useCallback( const goTo = useCallback(
(step: Steps, e?: MouseEvent<HTMLButtonElement>) => setSteps((state) => { (step: Steps, e?: MouseEvent<HTMLButtonElement>) => setSteps((state) => {
@ -71,46 +69,42 @@ export const useBuyMatchPopup = () => {
const { const {
fetchSubscriptions, fetchSubscriptions,
fetchSubscriptionsPackages,
initialSubscription,
matchSubscriptions, matchSubscriptions,
onPackageSelect,
onPeriodSelect, onPeriodSelect,
onSubscriptionPackagesSelect,
onSubscriptionSelect, onSubscriptionSelect,
resetSubscriptions, resetSubscriptions,
selectedPackage,
selectedPeriod, selectedPeriod,
selectedSubscription, selectedSubscription,
selectedSubscriptionPackage, setSelectedPackage,
setSelectedSubscriptionPackage,
subscriptions, subscriptions,
} = useSubscriptions() } = useSubscriptions()
const onChooseSub = () => { const onNext = (e: MouseEvent<HTMLButtonElement>) => goTo(Steps.SelectPackage, e)
if (match) {
fetchSubscriptionsPackages(match)
setSelectedSubStep(true)
}
}
const openPopup = useCallback((matchData: Match) => { const openPopup = useCallback((matchData: Match) => {
setMatch(matchData) setMatch(matchData)
setSteps([])
}, []) }, [])
useEffect(() => { useEffect(() => {
if (!isEmpty(initialSubscription)) { if (isEmpty(matchSubscriptions)) return
!initialSubscription?.data || size(initialSubscription?.data) === 1
? setSteps([Steps.Subscriptions]) if (size(matchSubscriptions) === 1) {
: setSteps([Steps.SelectSubscription]) setSteps([Steps.SelectPackage])
onSubscriptionSelect(matchSubscriptions[0])
} else {
setSteps([Steps.SelectSubscription])
} }
}, [subscriptions, initialSubscription]) }, [matchSubscriptions, onSubscriptionSelect])
const closePopup = () => { const closePopup = () => {
setMatch(null) setMatch(null)
setSteps([]) setSteps([])
setError('') setError('')
resetSubscriptions() resetSubscriptions()
setSelectedSubscriptionPackage(null) setSelectedPackage(null)
setSelectedSubStep(false)
if (isMatchPage()) history.push(PAGES.home) if (isMatchPage()) history.push(PAGES.home)
} }
@ -142,8 +136,8 @@ export const useBuyMatchPopup = () => {
} }
const onConfirmationSuccess = ({ id }: PaymentIntent) => { const onConfirmationSuccess = ({ id }: PaymentIntent) => {
if (!selectedSubscription) return if (!selectedPackage) return
const item = selectedSubscription.originalObject const item = selectedPackage.originalObject
notifySuccessfulSubscription({ item, paymentIntentId: id }) notifySuccessfulSubscription({ item, paymentIntentId: id })
.then(onSuccessfulSubscription, goToError) .then(onSuccessfulSubscription, goToError)
} }
@ -163,10 +157,10 @@ export const useBuyMatchPopup = () => {
} }
const subscribeToMatch = () => { const subscribeToMatch = () => {
if (!selectedSubscription || !defaultCard) return if (!selectedPackage || !defaultCard) return
const item = selectedSubscription.originalObject const item = selectedPackage.originalObject
const buy = requests[selectedSubscription.type] const buy = requests[selectedPackage.type]
setLoader(true) setLoader(true)
buy({ cardId: defaultCard.id, item }).then( buy({ cardId: defaultCard.id, item }).then(
onSuccessfulSubscription, onSuccessfulSubscription,
@ -183,40 +177,32 @@ export const useBuyMatchPopup = () => {
} }
} }
const getSub = useCallback(() => { useEffect(() => {
if (match) { if (match) {
fetchSubscriptions(match) fetchSubscriptions(match)
} }
}, [match, fetchSubscriptions]) }, [match, fetchSubscriptions])
useEffect(() => {
getSub()
}, [getSub])
return { return {
close: closePopup, close: closePopup,
currentStep: last(steps), currentStep: last(steps),
error, error,
getSub,
goBack, goBack,
goTo, goTo,
initialSubscription, hasPreviousStep: size(steps) > 1,
loader, loader,
match, match,
matchSubscriptions, matchSubscriptions,
onBuyClick, onBuyClick,
onChooseSub, onNext,
onPackageSelect,
onPeriodSelect, onPeriodSelect,
onSubscriptionPackagesSelect,
onSubscriptionSelect, onSubscriptionSelect,
open: openPopup, open: openPopup,
postPaymentHandler, postPaymentHandler,
selectedPackage,
selectedPeriod, selectedPeriod,
selectedSubName,
selectedSubStep,
selectedSubscription, selectedSubscription,
selectedSubscriptionPackage,
setSelectSubName,
subscriptions, subscriptions,
} }
} }

@ -9,116 +9,105 @@ import isEmpty from 'lodash/isEmpty'
import first from 'lodash/first' import first from 'lodash/first'
import size from 'lodash/size' import size from 'lodash/size'
import { getSubscriptions, SubscriptionsByPeriods } from 'requests' import { getSubscriptions } from 'requests/getSubscriptions'
import { useLexicsStore } from 'features/LexicsStore' import { useLexicsStore } from 'features/LexicsStore'
import type { import type {
MatchSubscriptions, MatchSubscriptions,
MatchSubscription, MatchSubscription,
MatchPackage,
Match, Match,
} from '../../types' } from '../../types'
import { SubscriptionType } from '../../types' import { SubscriptionType } from '../../types'
import { transformSubsciptions } from '../helpers' import { transformSubscriptions } from '../helpers'
import { useSubscriptionsLexics } from './useSubscriptionsLexics' import { useSubscriptionsLexics } from './useSubscriptionsLexics'
const defaultSubscriptions: MatchSubscriptions = { const defaultSubscriptions: MatchSubscriptions = []
[SubscriptionType.Month]: [], const defaultPeriod = SubscriptionType.Month
[SubscriptionType.Year]: [],
[SubscriptionType.PayPerView]: [], const getInitialPeriod = (subscription?: MatchSubscription) => {
const { packages } = subscription || {}
if (!packages) return defaultPeriod
return first(packages.year)?.type
|| first(packages.month)?.type
|| first(packages.pay_per_view)?.type
|| defaultPeriod
} }
export const useSubscriptions = () => { export const useSubscriptions = () => {
const { suffix } = useLexicsStore() const { suffix } = useLexicsStore()
const { fetchLexics } = useSubscriptionsLexics() const { fetchLexics } = useSubscriptionsLexics()
const [selectedPeriod, setSelectedPeriod] = useState(SubscriptionType.Month) const [selectedPeriod, setSelectedPeriod] = useState(defaultPeriod)
const [matchSubscriptions, setMatchSubscriptionsList] = useState(defaultSubscriptions) const [
const [selectedSubscription, setSelectedSubscription] = useState<MatchSubscription | null>(null) matchSubscriptions,
setMatchSubscriptionsList,
] = useState(defaultSubscriptions)
const [ const [
initialSubscription, setInitialSubscription, selectedSubscription,
] = useState<SubscriptionsByPeriods | null>(null) setSelectedSubscription,
] = useState<MatchSubscription | null>(null)
const [ const [
selectedSubscriptionPackage, setSelectedSubscriptionPackage, selectedPackage,
] = useState<SubscriptionsByPeriods | null>(null) setSelectedPackage,
] = useState<MatchPackage | null>(null)
const fetchSubscriptions = useCallback(async (match: Match) => { const fetchSubscriptions = useCallback(async (match: Match) => {
const subscriptions = await getSubscriptions(match.sportType, match.id) const subscriptions = await getSubscriptions(match.sportType, match.id)
const subscriptionData = subscriptions.data && size(subscriptions.data) === 1 const convertedSubscriptions = transformSubscriptions({
? { match,
...subscriptions.data[0].packages, subscriptions,
season: subscriptions.season, suffix,
} })
: subscriptions setMatchSubscriptionsList(convertedSubscriptions)
if (!subscriptions.data || size(subscriptions.data) === 1) { fetchLexics(subscriptions.data || [])
const convertedSubscriptions = transformSubsciptions({ const firstPackage = find(
match, convertedSubscriptions, (subscription) => !isEmpty(subscription),
subscriptions: subscriptionData, )
suffix, setSelectedPeriod(getInitialPeriod(firstPackage))
})
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]) }, [fetchLexics, suffix])
const fetchSubscriptionsPackages = useCallback((match) => { const onSubscriptionSelect = useCallback((nextSubscription: MatchSubscription) => {
if (selectedSubscriptionPackage) { setSelectedSubscription(nextSubscription)
const convertedSubscriptions = transformSubsciptions({ const nextPeriod = getInitialPeriod(nextSubscription)
match, setSelectedPeriod(nextPeriod)
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(() => { const resetSubscriptions = useCallback(() => {
setSelectedSubscription(null) setSelectedSubscription(null)
setSelectedPackage(null)
setMatchSubscriptionsList(defaultSubscriptions) setMatchSubscriptionsList(defaultSubscriptions)
}, []) }, [])
const onSubscriptionSelect = (subscription: MatchSubscription) => { const onPackageSelect = (subscriptionPackage: MatchPackage) => {
setSelectedSubscription(subscription === selectedSubscription ? null : subscription) setSelectedPackage(subscriptionPackage === selectedPackage ? null : subscriptionPackage)
}
const onSubscriptionPackagesSelect = (packages: SubscriptionsByPeriods) => {
setSelectedSubscriptionPackage(packages === selectedSubscriptionPackage ? null : packages)
} }
useEffect(() => { useEffect(() => {
const isOnlySubscriptionVariant = matchSubscriptions[selectedPeriod].length === 1 if (!selectedSubscription) return
const packages = selectedSubscription.packages[selectedPeriod]
const isOnlySubscriptionVariant = size(packages) === 1
if (isOnlySubscriptionVariant) { if (isOnlySubscriptionVariant) {
setSelectedSubscription(matchSubscriptions[selectedPeriod][0]) setSelectedPackage(packages[0])
} else { } else {
setSelectedSubscription(null) setSelectedPackage(null)
} }
}, [matchSubscriptions, selectedPeriod]) }, [selectedSubscription, selectedPeriod])
return { return {
fetchSubscriptions, fetchSubscriptions,
fetchSubscriptionsPackages,
initialSubscription,
matchSubscriptions, matchSubscriptions,
onPackageSelect,
onPeriodSelect: setSelectedPeriod, onPeriodSelect: setSelectedPeriod,
onSubscriptionPackagesSelect,
onSubscriptionSelect, onSubscriptionSelect,
resetSubscriptions, resetSubscriptions,
selectedPackage,
selectedPeriod, selectedPeriod,
selectedSubscription, selectedSubscription,
selectedSubscriptionPackage, setSelectedPackage,
setSelectedSubscriptionPackage, subscriptions: selectedSubscription?.packages?.[selectedPeriod] || [],
subscriptions: matchSubscriptions[selectedPeriod],
} }
} }

@ -4,14 +4,14 @@ import isEmpty from 'lodash/isEmpty'
import flatMap from 'lodash/flatMap' import flatMap from 'lodash/flatMap'
import uniq from 'lodash/uniq' import uniq from 'lodash/uniq'
import type { SelectSubscriptionData } from 'requests' import type { Subscriptions } from 'requests/getSubscriptions'
import { useLexicsStore } from 'features/LexicsStore' import { useLexicsStore } from 'features/LexicsStore'
export const useSubscriptionsLexics = () => { export const useSubscriptionsLexics = () => {
const { addLexicsConfig } = useLexicsStore() const { addLexicsConfig } = useLexicsStore()
const fetchLexics = useCallback((data: Array<SelectSubscriptionData>) => { const fetchLexics = useCallback((data: Subscriptions) => {
const lexics = uniq(flatMap(data, ({ const lexics = uniq(flatMap(data, ({
lexic, lexic,
lexic2, lexic2,

@ -5,7 +5,6 @@ import { isMobileDevice } from 'config/userAgent'
import { ButtonSolid } from 'features/Common' import { 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'
import { Arrow } from 'features/HeaderFilters/components/DateFilter/styled'
export const Modal = styled(BaseModal)` export const Modal = styled(BaseModal)`
background-color: rgba(0, 0, 0, 0.7); background-color: rgba(0, 0, 0, 0.7);
@ -45,7 +44,7 @@ export const HeaderTitle = styled.h2`
font-weight: 700; font-weight: 700;
` `
: ''}; : ''};
` `
export const Button = styled(ButtonSolid)` export const Button = styled(ButtonSolid)`
@ -104,7 +103,7 @@ export const Wrapper = styled.div<WrapperProps>`
@media (max-width: 1370px) { @media (max-width: 1370px) {
max-width: 743px; max-width: 743px;
max-height: 650px; max-height: 650px;
} }
@media (max-width: 650px){ @media (max-width: 650px){
width: 100%; width: 100%;
@ -125,11 +124,11 @@ type BodyProps = {
export const Body = styled.div<BodyProps>` export const Body = styled.div<BodyProps>`
margin-top: ${({ marginTop }) => (marginTop ? `${marginTop}px` : '')}; margin-top: ${({ marginTop }) => (marginTop ? `${marginTop}px` : '')};
margin-bottom: ${({ marginBottom }) => ( margin-bottom: ${({ marginBottom }) => (
marginBottom ? `${marginBottom}px` : '' marginBottom ? `${marginBottom}px` : ''
)}; )};
padding: ${({ padding }) => (padding || '')}; padding: ${({ padding }) => (padding || '')};
${isMobileDevice ${isMobileDevice
? css` ? css`
@ -172,7 +171,6 @@ export const ResultText = styled.span`
? css` ? css`
font-size: 14px; font-size: 14px;
line-height: 18px; line-height: 18px;
/* margin-top: 10px; */
` `
: ''}; : ''};
` `
@ -181,8 +179,13 @@ export const SmallButton = styled(Button)`
min-width: 70px; min-width: 70px;
` `
export const ButtonPrevious = styled(Arrow)` export const ButtonPrevious = styled.button`
top: 45px; border: none;
left: 30px; outline: none;
background-color: transparent;
padding: 15px;
position: absolute;
top: 30px;
left: 20px;
cursor: pointer; cursor: pointer;
` `

@ -1,12 +1,13 @@
import type { SubscriptionResponse, Subscription } from 'requests/getSubscriptions'
import type { LexicsId, Values } from 'features/LexicsStore/types' import type { LexicsId, Values } from 'features/LexicsStore/types'
import type { Match as MatchBase } from 'features/Matches/hooks' import type { Match as MatchBase } from 'features/Matches/hooks'
import type { SubscriptionResponse } from 'requests'
export enum Steps { export enum Steps {
CardSelection = 'CardSelection', CardSelection = 'CardSelection',
Error = 'Error', Error = 'Error',
SelectPackage = 'SelectPackage',
SelectSubscription = 'SelectSubscription', SelectSubscription = 'SelectSubscription',
Subscriptions = 'Subscriptions',
Success = 'Success', Success = 'Success',
} }
@ -16,20 +17,20 @@ export enum SubscriptionType {
Year = 'year', Year = 'year',
} }
type Desciption = { export type Desciption = {
lexic: LexicsId, lexic: LexicsId,
values: Values, values: Values,
} }
export type MatchSubscription = { export type MatchPackage = {
currency: string, currency: string,
description: Desciption, description: Desciption,
id: string, id: string,
name: string, name: string,
nameLexic?: LexicsId | null,
originalObject: SubscriptionResponse, originalObject: SubscriptionResponse,
pass: string, pass: string,
price: number, price: number,
seasonName?: string,
type: SubscriptionType, type: SubscriptionType,
} }
@ -43,4 +44,15 @@ export type Match = Pick<MatchBase, (
| 'hasVideo' | 'hasVideo'
)> )>
export type MatchSubscriptions = Record<SubscriptionType, Array<MatchSubscription>> export type MatchSubscription = Pick<Subscription, (
'id'
| 'lexic'
| 'lexic2'
| 'lexic3'
| 'min_price'
)>
& {
packages: Record<SubscriptionType, Array<MatchPackage>>,
}
export type MatchSubscriptions = Array<MatchSubscription>

@ -2,7 +2,7 @@ import omitBy from 'lodash/omitBy'
import isEmpty from 'lodash/isEmpty' import isEmpty from 'lodash/isEmpty'
import map from 'lodash/map' import map from 'lodash/map'
import type { MatchSubscriptions, SubscriptionType } from 'features/BuyMatchPopup/types' import type { MatchSubscription, SubscriptionType } from 'features/BuyMatchPopup/types'
type PaymentTab = { type PaymentTab = {
tabLexic: string, tabLexic: string,
@ -22,8 +22,8 @@ const getTabLexic = (type: string) => {
} }
} }
export const getCorrectPaymentTabs = (matchSubscriptions: MatchSubscriptions) => { export const getCorrectPaymentTabs = (matchSubscriptions: MatchSubscription) => {
const matchSubscriptionsWithValues = omitBy(matchSubscriptions, isEmpty) const matchSubscriptionsWithValues = omitBy(matchSubscriptions.packages, isEmpty)
return map(matchSubscriptionsWithValues, (matchSubscription, key) => ({ return map(matchSubscriptionsWithValues, (matchSubscription, key) => ({
tabLexic: getTabLexic(key), tabLexic: getTabLexic(key),
type: key, type: key,

@ -6,7 +6,7 @@ import styled, { css } from 'styled-components/macro'
import { isMobileDevice } from 'config/userAgent' import { isMobileDevice } from 'config/userAgent'
import type { MatchSubscriptions, SubscriptionType } from 'features/BuyMatchPopup/types' import type { MatchSubscription, SubscriptionType } from 'features/BuyMatchPopup/types'
import { T9n } from 'features/T9n' import { T9n } from 'features/T9n'
import { getCorrectPaymentTabs } from './helpers' import { getCorrectPaymentTabs } from './helpers'
@ -49,17 +49,22 @@ const Item = styled.li<ItemProps>`
justify-content: center; justify-content: center;
color: rgba(255, 255, 255, 0.5); color: rgba(255, 255, 255, 0.5);
cursor: pointer; cursor: pointer;
transition: color 0.3s;
::after {
transition: background-color 0.3s;
position: absolute;
content: '';
bottom: 0px;
width: 130px;
height: 3px;
}
${({ active }) => ( ${({ active }) => (
active active
? css` ? css`
color: #fff; color: #fff;
::after { ::after {
position: absolute;
content: '';
bottom: 0px;
width: 130px;
height: 3px;
background-color: #fff; background-color: #fff;
} }
` `
@ -79,20 +84,20 @@ const Item = styled.li<ItemProps>`
type Props = { type Props = {
className?: string, className?: string,
matchSubscriptions: MatchSubscriptions,
onPeriodSelect: (period: SubscriptionType) => void, onPeriodSelect: (period: SubscriptionType) => void,
selectedPeriod: SubscriptionType, selectedPeriod: SubscriptionType,
selectedSubscription: MatchSubscription,
} }
export const PaymentPeriodTabs = ({ export const PaymentPeriodTabs = ({
className, className,
matchSubscriptions,
onPeriodSelect, onPeriodSelect,
selectedPeriod, selectedPeriod,
selectedSubscription,
}: Props) => { }: Props) => {
const matchSubscriptionsWithValues = useMemo(() => ( const matchSubscriptionsWithValues = useMemo(() => (
getCorrectPaymentTabs(matchSubscriptions) getCorrectPaymentTabs(selectedSubscription)
), [matchSubscriptions]) ), [selectedSubscription])
return ( return (
<List className={className} countSubscriptions={size(matchSubscriptionsWithValues)}> <List className={className} countSubscriptions={size(matchSubscriptionsWithValues)}>

@ -8,30 +8,29 @@ import { callApi } from 'helpers'
const proc = PROCEDURES.get_match_subscriptions const proc = PROCEDURES.get_match_subscriptions
export type SelectSubscriptionData = { export type Subscription = {
id: number, id: number,
lexic: number, lexic: number,
lexic2: number, lexic2: number,
lexic3: number, lexic3: number,
min_price?: number, min_price?: number,
packages: SelectSubscriptionPackages, packages: PackagesGroup,
} }
export type SubscriptionsByPeriods = { export type Subscriptions = Array<Subscription>
data?: Array<SelectSubscriptionData>,
month: Subscriptions, export type SubscriptionsData = {
pay_per_view: SubscriptionResponse, data?: Subscriptions,
season: Season, season: Season,
year: Subscriptions,
} }
export type SelectSubscriptionPackages = Pick<SubscriptionsByPeriods, ( type PackagesGroup = {
'month' month: Packages,
| 'pay_per_view' pay_per_view: SubscriptionResponse,
| 'year' year: Packages,
)> }
export type Subscriptions = { export type Packages = {
all: SubscriptionResponse, all: SubscriptionResponse,
team1: SubscriptionResponse, team1: SubscriptionResponse,
team2: SubscriptionResponse, team2: SubscriptionResponse,
@ -59,7 +58,7 @@ type Sub = {
team_id?: number, team_id?: number,
} }
type Season = { export type Season = {
id: number, id: number,
name: string, name: string,
} }
@ -67,7 +66,7 @@ type Season = {
export const getSubscriptions = async ( export const getSubscriptions = async (
sport: SportTypes, sport: SportTypes,
matchId: number, matchId: number,
): Promise<SubscriptionsByPeriods> => { ): Promise<SubscriptionsData> => {
const config = { const config = {
body: { body: {
params: { params: {

Loading…
Cancel
Save