diff --git a/src/config/lexics/indexLexics.tsx b/src/config/lexics/indexLexics.tsx
index 059418c6..10eeccb5 100644
--- a/src/config/lexics/indexLexics.tsx
+++ b/src/config/lexics/indexLexics.tsx
@@ -21,13 +21,19 @@ const matchPopupLexics = {
}
const buyMatchPopupLexics = {
+ buy_for: 14095,
buy_subscription: 13565,
change_card: 13564,
choose_subscription: 13563,
+ error_not_enough_balance: 14098,
for_month: 13561,
for_year: 13562,
+ payment: 14096,
+ payment_confirmation: 14094,
per_month: 13573,
per_year: 13574,
+ subscription_done: 2668,
+ success_subscription: 14097,
}
export const indexLexics = {
diff --git a/src/features/BuyMatchPopup/components/ConfirmationStep/index.tsx b/src/features/BuyMatchPopup/components/ConfirmationStep/index.tsx
new file mode 100644
index 00000000..a5a3af39
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/ConfirmationStep/index.tsx
@@ -0,0 +1,48 @@
+import { currencySymbols } from 'config'
+
+import { T9n } from 'features/T9n'
+import {
+ CloseButton,
+ Header,
+ HeaderActions,
+ HeaderTitle,
+} from 'features/PopupComponents'
+
+import { useBuyMatchPopupStore } from '../../store'
+import { SubscriptionsList } from '../SubscriptionsList'
+import {
+ Wrapper,
+ Footer,
+ Button,
+ Body,
+} from '../../styled'
+
+export const ConfirmationStep = () => {
+ const {
+ close,
+ selectedSubscriptions,
+ subscribeToMatches,
+ totalPrice,
+ } = useBuyMatchPopupStore()
+
+ return (
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/features/BuyMatchPopup/components/ErrorStep/index.tsx b/src/features/BuyMatchPopup/components/ErrorStep/index.tsx
new file mode 100644
index 00000000..f759c7ff
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/ErrorStep/index.tsx
@@ -0,0 +1,34 @@
+import { T9n } from 'features/T9n'
+import {
+ Header,
+ HeaderTitle,
+ HeaderActions,
+ CloseButton,
+} from 'features/PopupComponents'
+
+import { useBuyMatchPopupStore } from '../../store'
+import {
+ Wrapper,
+ Body,
+ ResultText,
+} from '../../styled'
+
+export const ErrorStep = () => {
+ const { close } = useBuyMatchPopupStore()
+
+ return (
+
+
+
+
+
+
+ )
+}
diff --git a/src/features/BuyMatchPopup/components/MatchSubscriptions/index.tsx b/src/features/BuyMatchPopup/components/SubscriptionSelectionStep/index.tsx
similarity index 59%
rename from src/features/BuyMatchPopup/components/MatchSubscriptions/index.tsx
rename to src/features/BuyMatchPopup/components/SubscriptionSelectionStep/index.tsx
index b8481bd6..efe5a69a 100644
--- a/src/features/BuyMatchPopup/components/MatchSubscriptions/index.tsx
+++ b/src/features/BuyMatchPopup/components/SubscriptionSelectionStep/index.tsx
@@ -1,11 +1,6 @@
-import styled from 'styled-components/macro'
-
-import isEmpty from 'lodash/isEmpty'
-
import { MDASH } from 'config'
import { T9n } from 'features/T9n'
-import { useBuyMatchPopupStore } from 'features/BuyMatchPopup'
import {
CloseButton,
Header,
@@ -15,27 +10,21 @@ import {
import { Name } from 'features/Name'
import { Steps } from 'features/BuyMatchPopup/types'
+import { useBuyMatchPopupStore } from '../../store'
import { SelectedCard } from '../SelectedCard'
import { Subscriptions } from '../Subscriptions'
-import { Button } from '../../styled'
-
-const Wrapper = styled.div`
- width: 870px;
- height: 695px;
-`
-
-const Center = styled.div`
- width: 100%;
- display: flex;
- justify-content: center;
-`
+import {
+ Wrapper,
+ Body,
+ Footer,
+ Button,
+} from '../../styled'
-export const MatchSubscriptionsStep = () => {
+export const SubscriptionSelectionStep = () => {
const {
close,
goTo,
match,
- selectedSubscriptions,
} = useBuyMatchPopupStore()
if (!match) return null
@@ -52,16 +41,17 @@ export const MatchSubscriptionsStep = () => {
-
-
-
+
+
+
+
+
+
)
}
diff --git a/src/features/BuyMatchPopup/components/Subscriptions/index.tsx b/src/features/BuyMatchPopup/components/Subscriptions/index.tsx
index e050f5a0..5e37630e 100644
--- a/src/features/BuyMatchPopup/components/Subscriptions/index.tsx
+++ b/src/features/BuyMatchPopup/components/Subscriptions/index.tsx
@@ -1,9 +1,9 @@
import styled from 'styled-components/macro'
import { T9n } from 'features/T9n'
-import { useBuyMatchPopupStore } from 'features/BuyMatchPopup'
import { PaymentPeriodTabs } from 'features/PaymentPeriodTabs'
+import { useBuyMatchPopupStore } from '../../store'
import { SubscriptionsList } from '../SubscriptionsList'
const Wrapper = styled.div`
@@ -22,7 +22,13 @@ const Title = styled.span`
`
export const Subscriptions = () => {
- const { onPeriodSelect, selectedPeriod } = useBuyMatchPopupStore()
+ const {
+ onPeriodSelect,
+ onSubscriptionSelect,
+ selectedPeriod,
+ selectedSubscriptions,
+ subscriptions,
+ } = useBuyMatchPopupStore()
return (
{
-
+
)
}
diff --git a/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx b/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx
index 6b10e1e3..d365772d 100644
--- a/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx
+++ b/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx
@@ -1,7 +1,7 @@
import map from 'lodash/map'
import includes from 'lodash/includes'
-import { useBuyMatchPopupStore } from 'features/BuyMatchPopup/store'
+import type { MatchSubscriptions, MatchSubscription } from 'requests'
import {
List,
@@ -12,41 +12,39 @@ import {
Price,
} from './styled'
-export const SubscriptionsList = () => {
- const {
- onSubscriptionSelect,
- selectedSubscriptions,
- subscriptions,
- } = useBuyMatchPopupStore()
+type Props = {
+ height?: number,
+ onSelect?: (subscription: MatchSubscription) => void,
+ selectedSubscriptions?: MatchSubscriptions,
+ subscriptions: MatchSubscriptions,
+}
- return (
-
- {
- map(subscriptions, ({
- description,
- header,
- price,
- subscription_id,
- type,
- }) => (
- - onSubscriptionSelect(subscription_id)}
- active={includes(selectedSubscriptions, subscription_id)}
- >
-
-
-
- {description}
-
-
+export const SubscriptionsList = ({
+ height,
+ onSelect,
+ selectedSubscriptions,
+ subscriptions,
+}: Props) => (
+
+ {
+ map(subscriptions, (subscription) => (
+ - onSelect?.(subscription)}
+ active={includes(selectedSubscriptions, subscription)}
+ >
+
+
+ {subscription.header}
+
+
+ {subscription.description}
+
+
-
-
- ))
- }
-
- )
-}
+
+
+ ))
+ }
+
+)
diff --git a/src/features/BuyMatchPopup/components/SubscriptionsList/styled.tsx b/src/features/BuyMatchPopup/components/SubscriptionsList/styled.tsx
index a4268558..1545f3b6 100644
--- a/src/features/BuyMatchPopup/components/SubscriptionsList/styled.tsx
+++ b/src/features/BuyMatchPopup/components/SubscriptionsList/styled.tsx
@@ -4,8 +4,14 @@ import { popupScrollbarStyles } from 'features/PopupComponents'
import { Price as BasePrice } from 'features/Price'
import { PriceAmount, PriceDetails } from 'features/Price/styled'
-export const List = styled.ul`
- height: 364px;
+type ListProps = {
+ height?: number,
+ marginTop?: number,
+}
+
+export const List = styled.ul`
+ max-height: 364px;
+ height: ${({ height }) => (height ? `${height}px` : 'auto')};
display: flex;
flex-direction: column;
overflow-y: auto;
diff --git a/src/features/BuyMatchPopup/components/SuccessStep/index.tsx b/src/features/BuyMatchPopup/components/SuccessStep/index.tsx
new file mode 100644
index 00000000..b7616219
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/SuccessStep/index.tsx
@@ -0,0 +1,36 @@
+import { T9n } from 'features/T9n'
+import {
+ Header,
+ HeaderTitle,
+} from 'features/PopupComponents'
+
+import { useBuyMatchPopupStore } from '../../store'
+import {
+ Wrapper,
+ Body,
+ Footer,
+ Button,
+ ResultText,
+} from '../../styled'
+
+export const SuccessStep = () => {
+ const { close } = useBuyMatchPopupStore()
+
+ return (
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/features/BuyMatchPopup/index.tsx b/src/features/BuyMatchPopup/index.tsx
index ce76de14..db0cff87 100644
--- a/src/features/BuyMatchPopup/index.tsx
+++ b/src/features/BuyMatchPopup/index.tsx
@@ -1,6 +1,8 @@
-import { useBuyMatchPopupStore } from 'features/BuyMatchPopup'
-
-import { MatchSubscriptionsStep } from './components/MatchSubscriptions'
+import { useBuyMatchPopupStore } from './store'
+import { SubscriptionSelectionStep } from './components/SubscriptionSelectionStep'
+import { ConfirmationStep } from './components/ConfirmationStep'
+import { SuccessStep } from './components/SuccessStep'
+import { ErrorStep } from './components/ErrorStep'
import { Modal } from './styled'
import { Steps } from './types'
@@ -9,11 +11,11 @@ export * from './store'
const Empty = () => null
const components = {
- [Steps.Subscriptions]: MatchSubscriptionsStep,
+ [Steps.Subscriptions]: SubscriptionSelectionStep,
[Steps.CardSelection]: Empty,
- [Steps.Confirmation]: Empty,
- [Steps.Success]: Empty,
- [Steps.Error]: Empty,
+ [Steps.Confirmation]: ConfirmationStep,
+ [Steps.Success]: SuccessStep,
+ [Steps.Error]: ErrorStep,
}
export const BuyMatchPopup = () => {
diff --git a/src/features/BuyMatchPopup/store/hooks/index.tsx b/src/features/BuyMatchPopup/store/hooks/index.tsx
index abb70811..977e65f6 100644
--- a/src/features/BuyMatchPopup/store/hooks/index.tsx
+++ b/src/features/BuyMatchPopup/store/hooks/index.tsx
@@ -1,5 +1,9 @@
import type { MouseEvent } from 'react'
-import { useCallback, useState } from 'react'
+import {
+ useCallback,
+ useState,
+ useEffect,
+} from 'react'
import last from 'lodash/last'
@@ -17,18 +21,10 @@ type MatchData = Pick {
const [steps, setSteps] = useState>([])
const [match, setMatch] = useState(null)
- const {
- onPeriodSelect,
- onSubscriptionSelect,
- resetSubscriptions,
- selectedPeriod,
- selectedSubscriptions,
- subscriptions,
- } = useSubscriptions()
const goTo = useCallback(
- (e: MouseEvent, step: Steps) => setSteps((state) => {
- e.stopPropagation()
+ (step: Steps, e?: MouseEvent) => setSteps((state) => {
+ e?.stopPropagation()
return [...state, step]
}),
[],
@@ -47,9 +43,25 @@ export const useBuyMatchPopup = () => {
const closePopup = () => {
setMatch(null)
setSteps([])
- resetSubscriptions()
}
+ const {
+ fetchSubscriptions,
+ onPeriodSelect,
+ onSubscriptionSelect,
+ selectedPeriod,
+ selectedSubscriptions,
+ subscribeToMatches,
+ subscriptions,
+ totalPrice,
+ } = useSubscriptions(goTo)
+
+ useEffect(() => {
+ if (match) {
+ fetchSubscriptions()
+ }
+ }, [match, fetchSubscriptions])
+
return {
close: closePopup,
currentStep: last(steps),
@@ -59,9 +71,10 @@ export const useBuyMatchPopup = () => {
onPeriodSelect,
onSubscriptionSelect,
open: openPopup,
- resetSubscriptions,
selectedPeriod,
selectedSubscriptions,
+ subscribeToMatches,
subscriptions,
+ totalPrice,
}
}
diff --git a/src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx b/src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx
index b0fa8e95..1b127ac0 100644
--- a/src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx
+++ b/src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx
@@ -1,22 +1,30 @@
+import type { MouseEvent } from 'react'
import {
useMemo,
useState,
- useEffect,
useCallback,
} from 'react'
+import sumBy from 'lodash/sumBy'
import filter from 'lodash/filter'
+import without from 'lodash/without'
import includes from 'lodash/includes'
-import type { MatchSubscriptions } from 'requests'
-import { SubscriptionType, getMatchSubscriptions } from 'requests'
+import type { MatchSubscriptions, MatchSubscription } from 'requests'
+import {
+ SubscriptionType,
+ getMatchSubscriptions,
+ buyMatchSubscriptions,
+} from 'requests'
+
+import { Steps } from 'features/BuyMatchPopup/types'
-export const useSubscriptions = () => {
+export const useSubscriptions = (goTo: (step: Steps) => void) => {
const [selectedPeriod, setSelectedPeriod] = useState(SubscriptionType.Month)
const [subscriptionsList, setSubscriptionsList] = useState([])
- const [selectedSubscriptions, setSelectedSubscriptions] = useState>([])
+ const [selectedSubscriptions, setSelectedSubscriptions] = useState([])
- useEffect(() => {
+ const fetchSubscriptions = useCallback(() => {
getMatchSubscriptions().then(setSubscriptionsList)
}, [])
@@ -25,16 +33,16 @@ export const useSubscriptions = () => {
[selectedPeriod, subscriptionsList],
)
- const onSubscriptionSelect = (id: number) => {
- if (includes(selectedSubscriptions, id)) {
- const newSubscriptions = filter(
- selectedSubscriptions,
- (subscriptionId) => subscriptionId !== id,
- )
- setSelectedSubscriptions(newSubscriptions)
- } else {
- setSelectedSubscriptions([...selectedSubscriptions, id])
- }
+ const totalPrice = useMemo(
+ () => sumBy(selectedSubscriptions, (subscription) => subscription.price),
+ [selectedSubscriptions],
+ )
+
+ const onSubscriptionSelect = (selected: MatchSubscription) => {
+ const newSubscriptions = includes(selectedSubscriptions, selected)
+ ? without(selectedSubscriptions, selected)
+ : [...selectedSubscriptions, selected]
+ setSelectedSubscriptions(newSubscriptions)
}
const resetSubscriptions = useCallback(() => {
@@ -42,12 +50,22 @@ export const useSubscriptions = () => {
setSelectedSubscriptions([])
}, [])
+ const subscribeToMatches = (e: MouseEvent) => {
+ e.stopPropagation()
+ buyMatchSubscriptions()
+ .then(() => goTo(Steps.Success))
+ .catch(() => goTo(Steps.Error))
+ }
+
return {
+ fetchSubscriptions,
onPeriodSelect: setSelectedPeriod,
onSubscriptionSelect,
resetSubscriptions,
selectedPeriod,
selectedSubscriptions,
+ subscribeToMatches,
subscriptions,
+ totalPrice,
}
}
diff --git a/src/features/BuyMatchPopup/styled.tsx b/src/features/BuyMatchPopup/styled.tsx
index c584600a..19416e6b 100644
--- a/src/features/BuyMatchPopup/styled.tsx
+++ b/src/features/BuyMatchPopup/styled.tsx
@@ -5,13 +5,14 @@ import { devices } from 'config'
import { Modal as BaseModal } from 'features/Modal'
import { ModalWindow } from 'features/Modal/styled'
import { ButtonSolid } from 'features/Common'
+import { T9n } from 'features/T9n'
export const Modal = styled(BaseModal)`
background-color: rgba(0, 0, 0, 0.7);
${ModalWindow} {
min-width: 517px;
- min-height: 310px;
+ min-height: auto;
padding: 20px 0;
background-color: #3F3F3F;
border-radius: 5px;
@@ -37,3 +38,43 @@ export const Button = styled(ButtonSolid)`
opacity: 0.5;
}
`
+
+type WrapperProps = {
+ width?: number,
+}
+
+export const Wrapper = styled.div`
+ width: ${({ width }) => (width ? `${width}px` : '870px')};
+`
+
+type BodyProps = {
+ marginBottom?: number,
+ marginTop?: number,
+}
+
+export const Body = styled.div`
+ margin-top: ${({ marginTop }) => (marginTop ? `${marginTop}px` : '')};
+ margin-bottom: ${({ marginBottom }) => (marginBottom ? `${marginBottom}px` : '')};
+`
+
+type FooterProps = {
+ marginTop?: number,
+}
+
+export const Footer = styled.div`
+ width: 100%;
+ display: flex;
+ justify-content: center;
+
+ margin-top: ${({ marginTop }) => (marginTop ? `${marginTop}px` : '')};
+ margin-bottom: 15px;
+`
+
+export const ResultText = styled(T9n)`
+ width: 100%;
+ display: inline-block;
+ text-align: center;
+ font-weight: normal;
+ font-size: 20px;
+ line-height: 27px;
+`
diff --git a/src/features/PaymentPeriodTabs/index.tsx b/src/features/PaymentPeriodTabs/index.tsx
index c80a4342..0fc42c0d 100644
--- a/src/features/PaymentPeriodTabs/index.tsx
+++ b/src/features/PaymentPeriodTabs/index.tsx
@@ -14,9 +14,7 @@ type ItemProps = {
active?: boolean,
}
-export const Item = styled.li.attrs(() => ({
- tabIndex: 0,
-}))`
+export const Item = styled.li`
width: 50%;
font-size: 20px;
line-height: 42px;
diff --git a/src/requests/buyMatchSubscriptions.tsx b/src/requests/buyMatchSubscriptions.tsx
new file mode 100644
index 00000000..bea8e952
--- /dev/null
+++ b/src/requests/buyMatchSubscriptions.tsx
@@ -0,0 +1,18 @@
+import { API_ROOT } from 'config'
+import { callApi } from 'helpers'
+
+export const buyMatchSubscriptions = () => {
+ const config = {
+ body: {
+ _p_c_subscription_plan: 1,
+ _p_is_scheduled: 0,
+ },
+ }
+
+ callApi({
+ config,
+ url: `${API_ROOT}/account/purchase`,
+ })
+
+ return Promise.resolve()
+}
diff --git a/src/requests/getMatchSubscriptions.tsx b/src/requests/getMatchSubscriptions.tsx
index 024495dc..86ae5ad4 100644
--- a/src/requests/getMatchSubscriptions.tsx
+++ b/src/requests/getMatchSubscriptions.tsx
@@ -6,7 +6,7 @@ export enum SubscriptionType {
Year = 'year',
}
-type MatchSubscription = {
+export type MatchSubscription = {
description: string,
header: string,
price: number,
diff --git a/src/requests/index.tsx b/src/requests/index.tsx
index c4c397b0..19bbc9a3 100644
--- a/src/requests/index.tsx
+++ b/src/requests/index.tsx
@@ -25,3 +25,4 @@ export * from './getSportActions'
export * from './getMatchPlaylists'
export * from './getPlayerPlaylists'
export * from './getMatchSubscriptions'
+export * from './buyMatchSubscriptions'