diff --git a/src/config/currencies.tsx b/src/config/currencies.tsx
new file mode 100644
index 00000000..03cf0426
--- /dev/null
+++ b/src/config/currencies.tsx
@@ -0,0 +1,4 @@
+export const currencySymbols = {
+ dollar: '$',
+ ruble: '₽',
+}
diff --git a/src/config/dashes.tsx b/src/config/dashes.tsx
new file mode 100644
index 00000000..1053f668
--- /dev/null
+++ b/src/config/dashes.tsx
@@ -0,0 +1 @@
+export const MDASH = '\u2014'
diff --git a/src/config/index.tsx b/src/config/index.tsx
index ab2ad3fe..d03692c7 100644
--- a/src/config/index.tsx
+++ b/src/config/index.tsx
@@ -6,3 +6,5 @@ export * from './sportTypes'
export * from './profileTypes'
export * from './history'
export * from './devices'
+export * from './currencies'
+export * from './dashes'
diff --git a/src/config/lexics/indexLexics.tsx b/src/config/lexics/indexLexics.tsx
index 4613aecf..e6f62c6a 100644
--- a/src/config/lexics/indexLexics.tsx
+++ b/src/config/lexics/indexLexics.tsx
@@ -19,6 +19,16 @@ const matchPopupLexics = {
watch_live_stream: 13020,
}
+const buyMatchPopupLexics = {
+ buy_subscription: 13565,
+ change_card: 13564,
+ choose_subscription: 13563,
+ for_month: 13561,
+ for_year: 13562,
+ per_month: 13573,
+ per_year: 13574,
+}
+
export const indexLexics = {
add_to_favorites: 1701,
add_to_favorites_error: 12943,
@@ -69,4 +79,5 @@ export const indexLexics = {
...proceduresLexics,
...matchPopupLexics,
+ ...buyMatchPopupLexics,
}
diff --git a/src/features/App/AuthenticatedApp.tsx b/src/features/App/AuthenticatedApp.tsx
index e803a398..16274879 100644
--- a/src/features/App/AuthenticatedApp.tsx
+++ b/src/features/App/AuthenticatedApp.tsx
@@ -20,6 +20,7 @@ import { UserAccountForm } from 'features/UserAccount'
import { MatchSwitchesStore } from 'features/MatchSwitches'
import { UserFavoritesStore } from 'features/UserFavorites/store'
import { MatchPopupStore } from 'features/MatchPopup'
+import { BuyMatchPopup, BuyMatchPopupStore } from 'features/BuyMatchPopup'
export const AuthenticatedApp = () => {
useLexicsConfig(indexLexics)
@@ -29,32 +30,35 @@ export const AuthenticatedApp = () => {
+
+
- {/* в Switch как прямой children можно рендерить только Route или Redirect */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ {/* в Switch как прямой children можно рендерить только Route или Redirect */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/features/BuyMatchPopup/components/MatchSubscriptions/index.tsx b/src/features/BuyMatchPopup/components/MatchSubscriptions/index.tsx
new file mode 100644
index 00000000..24ce4084
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/MatchSubscriptions/index.tsx
@@ -0,0 +1,67 @@
+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,
+ HeaderActions,
+ HeaderTitle,
+} from 'features/PopupComponents'
+import { Name } from 'features/Name'
+import { Steps } from 'features/BuyMatchPopup/types'
+
+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;
+`
+
+export const MatchSubscriptionsStep = () => {
+ const {
+ close,
+ goTo,
+ match,
+ selectedSubscriptions,
+ } = useBuyMatchPopupStore()
+
+ if (!match) return null
+
+ return (
+
+
+
+
+ {' '} {MDASH} {' '}
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/features/BuyMatchPopup/components/PaymentPeriods/index.tsx b/src/features/BuyMatchPopup/components/PaymentPeriods/index.tsx
new file mode 100644
index 00000000..ec5d5966
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/PaymentPeriods/index.tsx
@@ -0,0 +1,59 @@
+import styled, { css } from 'styled-components/macro'
+
+import { SubscriptionType } from 'requests'
+
+import { T9n } from 'features/T9n'
+import { useBuyMatchPopupStore } from 'features/BuyMatchPopup/store'
+
+const List = styled.ul`
+ display: flex;
+ padding: 0 35px;
+ margin-top: 9px;
+`
+
+type ItemProps = {
+ active?: boolean,
+}
+
+const Item = styled.li.attrs(() => ({
+ tabIndex: 0,
+}))`
+ width: 50%;
+ font-size: 20px;
+ line-height: 42px;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: rgba(255, 255, 255, 0.5);
+ cursor: pointer;
+
+ ${({ active }) => (
+ active
+ ? css`
+ border-bottom: 3px solid #fff;
+ color: #fff;
+ `
+ : ''
+ )}
+`
+
+export const PaymentPeriods = () => {
+ const { onPeriodSelect, selectedPeriod } = useBuyMatchPopupStore()
+ return (
+
+ - onPeriodSelect(SubscriptionType.Month)}
+ >
+
+
+ - onPeriodSelect(SubscriptionType.Year)}
+ >
+
+
+
+ )
+}
diff --git a/src/features/BuyMatchPopup/components/SelectedCard/index.tsx b/src/features/BuyMatchPopup/components/SelectedCard/index.tsx
new file mode 100644
index 00000000..d9c046aa
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/SelectedCard/index.tsx
@@ -0,0 +1,45 @@
+import styled from 'styled-components/macro'
+
+import { T9n } from 'features/T9n'
+import { ButtonOutline } from 'features/Common'
+
+const Wrapper = styled.div`
+ display: flex;
+ margin-top: 40px;
+ margin-bottom: 30px;
+ padding: 0 35px;
+`
+
+const CardInfo = styled.span`
+ font-weight: 500;
+ font-size: 18px;
+ line-height: 20px;
+ color: rgba(255, 255, 255, 0.7);
+`
+
+const ChangeCardButton = styled(ButtonOutline)`
+ border: none;
+ padding: 0;
+ width: auto;
+ height: auto;
+
+ padding: 0 10px;
+ margin-left: 10px;
+ line-height: 20px;
+ font-size: 14px;
+ color: rgba(255, 255, 255, 0.5);
+ cursor: pointer;
+
+ :hover {
+ color: rgba(255, 255, 255);
+ }
+`
+
+export const SelectedCard = () => (
+
+ Mastercard •••• 4432
+
+
+
+
+)
diff --git a/src/features/BuyMatchPopup/components/Subscriptions/index.tsx b/src/features/BuyMatchPopup/components/Subscriptions/index.tsx
new file mode 100644
index 00000000..a1e79b80
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/Subscriptions/index.tsx
@@ -0,0 +1,31 @@
+import styled from 'styled-components/macro'
+
+import { T9n } from 'features/T9n'
+
+import { PaymentPeriods } from '../PaymentPeriods'
+import { SubscriptionsList } from '../SubscriptionsList'
+
+const Wrapper = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+`
+
+const Title = styled.span`
+ font-weight: normal;
+ font-size: 20px;
+ line-height: 21px;
+ text-transform: uppercase;
+ margin-top: 30px;
+ padding: 0 35px;
+`
+
+export const Subscriptions = () => (
+
+
+
+
+
+
+
+)
diff --git a/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx b/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx
new file mode 100644
index 00000000..6b10e1e3
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx
@@ -0,0 +1,52 @@
+import map from 'lodash/map'
+import includes from 'lodash/includes'
+
+import { useBuyMatchPopupStore } from 'features/BuyMatchPopup/store'
+
+import {
+ List,
+ Item,
+ InfoWrapper,
+ Header,
+ Description,
+ Price,
+} from './styled'
+
+export const SubscriptionsList = () => {
+ const {
+ onSubscriptionSelect,
+ selectedSubscriptions,
+ subscriptions,
+ } = useBuyMatchPopupStore()
+
+ return (
+
+ {
+ map(subscriptions, ({
+ description,
+ header,
+ price,
+ subscription_id,
+ type,
+ }) => (
+ - onSubscriptionSelect(subscription_id)}
+ active={includes(selectedSubscriptions, subscription_id)}
+ >
+
+
+
+ {description}
+
+
+
+
+
+ ))
+ }
+
+ )
+}
diff --git a/src/features/BuyMatchPopup/components/SubscriptionsList/styled.tsx b/src/features/BuyMatchPopup/components/SubscriptionsList/styled.tsx
new file mode 100644
index 00000000..a4268558
--- /dev/null
+++ b/src/features/BuyMatchPopup/components/SubscriptionsList/styled.tsx
@@ -0,0 +1,80 @@
+import styled from 'styled-components/macro'
+
+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;
+ display: flex;
+ flex-direction: column;
+ overflow-y: auto;
+ margin-top: 20px;
+ padding: 0 35px;
+
+ ${popupScrollbarStyles}
+`
+
+type ItemProps = {
+ active?: boolean,
+}
+
+export const Item = styled.li.attrs(() => ({
+ tabIndex: 0,
+}))`
+ width: 100%;
+ min-height: 108px;
+ padding: 20px;
+ background: linear-gradient(180deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 100%), #5C5C5C;
+ box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3);
+ border-radius: 2px;
+
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ cursor: pointer;
+
+ :first-child {
+ margin-top: 2px;
+ }
+
+ :not(:last-child) {
+ margin-bottom: 20px;
+ }
+
+ ${({ active }) => (
+ active ? 'background-color: #294FC3' : ''
+ )};
+`
+
+export const InfoWrapper = styled.div`
+ width: 80%;
+`
+
+export const Header = styled.span`
+ font-weight: 600;
+ font-size: 20px;
+ line-height: 23px;
+ letter-spacing: 0.03em;
+`
+
+export const Description = styled.p`
+ margin-top: 10px;
+ font-weight: 500;
+ font-size: 17px;
+ letter-spacing: 0.03em;
+`
+
+export const Price = styled(BasePrice)`
+ ${PriceAmount} {
+ font-size: 24px;
+ line-height: 24px;
+ font-weight: normal;
+ }
+
+ ${PriceDetails} {
+ font-weight: 500;
+ font-size: 12px;
+ line-height: 18px;
+ }
+`
diff --git a/src/features/BuyMatchPopup/index.tsx b/src/features/BuyMatchPopup/index.tsx
new file mode 100644
index 00000000..ce76de14
--- /dev/null
+++ b/src/features/BuyMatchPopup/index.tsx
@@ -0,0 +1,39 @@
+import { useBuyMatchPopupStore } from 'features/BuyMatchPopup'
+
+import { MatchSubscriptionsStep } from './components/MatchSubscriptions'
+import { Modal } from './styled'
+import { Steps } from './types'
+
+export * from './store'
+
+const Empty = () => null
+
+const components = {
+ [Steps.Subscriptions]: MatchSubscriptionsStep,
+ [Steps.CardSelection]: Empty,
+ [Steps.Confirmation]: Empty,
+ [Steps.Success]: Empty,
+ [Steps.Error]: Empty,
+}
+
+export const BuyMatchPopup = () => {
+ const {
+ close,
+ currentStep,
+ match,
+ } = useBuyMatchPopupStore()
+
+ if (!match || !currentStep) return null
+
+ const Step = components[currentStep]
+
+ return (
+
+
+
+ )
+}
diff --git a/src/features/BuyMatchPopup/store/hooks/index.tsx b/src/features/BuyMatchPopup/store/hooks/index.tsx
new file mode 100644
index 00000000..bad5d886
--- /dev/null
+++ b/src/features/BuyMatchPopup/store/hooks/index.tsx
@@ -0,0 +1,71 @@
+import type { MouseEvent } from 'react'
+import { useCallback, useState } from 'react'
+
+import last from 'lodash/last'
+
+import type { Match } from 'features/Matches/hooks'
+import { useMatchPopupStore } from 'features/MatchPopup'
+import { Steps } from 'features/BuyMatchPopup/types'
+
+import { useSubscriptions } from './useSubscriptions'
+
+type MatchData = Pick | null
+
+export const useBuyMatchPopup = () => {
+ const { closePopup: closeMatchPopup } = useMatchPopupStore()
+ 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()
+ return [...state, step]
+ }),
+ [],
+ )
+ const goBack = useCallback(() => setSteps((state) => {
+ const newState = [...state]
+ newState.pop()
+ return newState
+ }), [])
+
+ const openPopup = (e: MouseEvent, matchData: MatchData) => {
+ closeMatchPopup()
+ e.stopPropagation()
+ setMatch(matchData)
+ setSteps([Steps.Subscriptions])
+ }
+
+ const closePopup = () => {
+ setMatch(null)
+ setSteps([])
+ resetSubscriptions()
+ }
+
+ return {
+ close: closePopup,
+ currentStep: last(steps),
+ goBack,
+ goTo,
+ match,
+ onPeriodSelect,
+ onSubscriptionSelect,
+ open: openPopup,
+ resetSubscriptions,
+ selectedPeriod,
+ selectedSubscriptions,
+ subscriptions,
+ }
+}
diff --git a/src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx b/src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx
new file mode 100644
index 00000000..b0fa8e95
--- /dev/null
+++ b/src/features/BuyMatchPopup/store/hooks/useSubscriptions.tsx
@@ -0,0 +1,53 @@
+import {
+ useMemo,
+ useState,
+ useEffect,
+ useCallback,
+} from 'react'
+
+import filter from 'lodash/filter'
+import includes from 'lodash/includes'
+
+import type { MatchSubscriptions } from 'requests'
+import { SubscriptionType, getMatchSubscriptions } from 'requests'
+
+export const useSubscriptions = () => {
+ const [selectedPeriod, setSelectedPeriod] = useState(SubscriptionType.Month)
+ const [subscriptionsList, setSubscriptionsList] = useState([])
+ const [selectedSubscriptions, setSelectedSubscriptions] = useState>([])
+
+ useEffect(() => {
+ getMatchSubscriptions().then(setSubscriptionsList)
+ }, [])
+
+ const subscriptions = useMemo(
+ () => filter(subscriptionsList, { type: selectedPeriod }),
+ [selectedPeriod, subscriptionsList],
+ )
+
+ const onSubscriptionSelect = (id: number) => {
+ if (includes(selectedSubscriptions, id)) {
+ const newSubscriptions = filter(
+ selectedSubscriptions,
+ (subscriptionId) => subscriptionId !== id,
+ )
+ setSelectedSubscriptions(newSubscriptions)
+ } else {
+ setSelectedSubscriptions([...selectedSubscriptions, id])
+ }
+ }
+
+ const resetSubscriptions = useCallback(() => {
+ setSelectedPeriod(SubscriptionType.Month)
+ setSelectedSubscriptions([])
+ }, [])
+
+ return {
+ onPeriodSelect: setSelectedPeriod,
+ onSubscriptionSelect,
+ resetSubscriptions,
+ selectedPeriod,
+ selectedSubscriptions,
+ subscriptions,
+ }
+}
diff --git a/src/features/BuyMatchPopup/store/index.tsx b/src/features/BuyMatchPopup/store/index.tsx
new file mode 100644
index 00000000..6e94cc80
--- /dev/null
+++ b/src/features/BuyMatchPopup/store/index.tsx
@@ -0,0 +1,20 @@
+import type { ReactNode } from 'react'
+import { createContext, useContext } from 'react'
+
+import { useBuyMatchPopup } from './hooks'
+
+type Context = ReturnType
+type Props = { children: ReactNode }
+
+const BuyMatchPopupContext = createContext({} as Context)
+
+export const BuyMatchPopupStore = ({ children }: Props) => {
+ const value = useBuyMatchPopup()
+ return (
+
+ {children}
+
+ )
+}
+
+export const useBuyMatchPopupStore = () => useContext(BuyMatchPopupContext)
diff --git a/src/features/BuyMatchPopup/styled.tsx b/src/features/BuyMatchPopup/styled.tsx
new file mode 100644
index 00000000..c584600a
--- /dev/null
+++ b/src/features/BuyMatchPopup/styled.tsx
@@ -0,0 +1,39 @@
+import styled from 'styled-components/macro'
+
+import { devices } from 'config'
+
+import { Modal as BaseModal } from 'features/Modal'
+import { ModalWindow } from 'features/Modal/styled'
+import { ButtonSolid } from 'features/Common'
+
+export const Modal = styled(BaseModal)`
+ background-color: rgba(0, 0, 0, 0.7);
+
+ ${ModalWindow} {
+ min-width: 517px;
+ min-height: 310px;
+ padding: 20px 0;
+ background-color: #3F3F3F;
+ border-radius: 5px;
+
+ @media ${devices.mobile} {
+ width: 100vw;
+ height: 100vh;
+ padding: 0;
+ }
+ }
+`
+
+export const Button = styled(ButtonSolid)`
+ min-width: 142px;
+ width: auto;
+ height: 50px;
+ padding: 0 20px;
+ background-color: #294FC4;
+ box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3);
+ border-radius: 5px;
+
+ :disabled {
+ opacity: 0.5;
+ }
+`
diff --git a/src/features/BuyMatchPopup/types.tsx b/src/features/BuyMatchPopup/types.tsx
new file mode 100644
index 00000000..be52b946
--- /dev/null
+++ b/src/features/BuyMatchPopup/types.tsx
@@ -0,0 +1,7 @@
+export enum Steps {
+ CardSelection = 'CardSelection',
+ Confirmation = 'Confirmation',
+ Error = 'Error',
+ Subscriptions = 'Subscriptions',
+ Success = 'Success',
+}
diff --git a/src/features/MatchCard/CardFrontside/index.tsx b/src/features/MatchCard/CardFrontside/index.tsx
index 9669bd19..0d5d6f8a 100644
--- a/src/features/MatchCard/CardFrontside/index.tsx
+++ b/src/features/MatchCard/CardFrontside/index.tsx
@@ -7,6 +7,7 @@ import { ProfileTypes } from 'config'
import type { Match } from 'features/Matches'
import { SportName } from 'features/Common'
import { useMatchSwitchesStore } from 'features/MatchSwitches'
+import { useBuyMatchPopupStore } from 'features/BuyMatchPopup'
import { useName } from 'features/Name'
import { NoAccessMessage } from '../NoAccessMessage'
@@ -36,7 +37,12 @@ type Props = {
}
export const CardFrontside = ({
- match: {
+ match,
+ onClick,
+ onKeyPress,
+ showSportName,
+}: Props) => {
+ const {
accessibleBySubscription,
accessibleInUsersCountry,
date,
@@ -49,12 +55,9 @@ export const CardFrontside = ({
team2,
time,
tournament,
- },
- onClick,
- onKeyPress,
- showSportName,
-}: Props) => {
+ } = match
const tournamentName = useName(tournament)
+ const { open } = useBuyMatchPopupStore()
const { isScoreHidden } = useMatchSwitchesStore()
const { selectedMatchStatus } = useHeaderFiltersStore()
const unixTimeOfMatch = getUnixTime(date)
@@ -95,7 +98,11 @@ export const CardFrontside = ({
)
}
- {!accessibleBySubscription && }
+ {!accessibleBySubscription && (
+ open(e, match)}
+ />
+ )}
{(accessibleBySubscription && !accessibleInUsersCountry) && }
{formattedDate}
diff --git a/src/features/MatchPopup/components/BackButton/index.tsx b/src/features/MatchPopup/components/BackButton/index.tsx
index c495cf6a..7c40dea6 100644
--- a/src/features/MatchPopup/components/BackButton/index.tsx
+++ b/src/features/MatchPopup/components/BackButton/index.tsx
@@ -1,8 +1,7 @@
import styled from 'styled-components/macro'
-import { useMatchPopupStore } from 'features/MatchPopup/store'
-
-import { BaseButton } from '../../styled'
+import { useMatchPopupStore } from 'features/MatchPopup'
+import { BaseButton } from 'features/PopupComponents'
const Button = styled(BaseButton)`
background-image: url(/images/back-icon.svg);
diff --git a/src/features/MatchPopup/components/CloseButton/index.tsx b/src/features/MatchPopup/components/CloseButton/index.tsx
deleted file mode 100644
index cdc8fb18..00000000
--- a/src/features/MatchPopup/components/CloseButton/index.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Close } from 'features/Icons/Close'
-import { useMatchPopupStore } from 'features/MatchPopup/store'
-
-import { BaseButton } from '../../styled'
-
-export const CloseButton = () => {
- const { closePopup } = useMatchPopupStore()
- return (
-
-
-
- )
-}
diff --git a/src/features/MatchPopup/components/FinishedMatchPopup/index.tsx b/src/features/MatchPopup/components/FinishedMatchPopup/index.tsx
index 7033211f..c4d6274d 100644
--- a/src/features/MatchPopup/components/FinishedMatchPopup/index.tsx
+++ b/src/features/MatchPopup/components/FinishedMatchPopup/index.tsx
@@ -9,8 +9,6 @@ import { FinishedPlaylistPage } from '../../components/FinishedPlaylistPage'
import { PopupPages } from '../../types'
import { Modal } from './styled'
-export * from '../../store'
-
export const FinishedMatchPopup = () => {
const {
closePopup,
diff --git a/src/features/MatchPopup/components/FinishedPlaylistPage/index.tsx b/src/features/MatchPopup/components/FinishedPlaylistPage/index.tsx
index c41f685e..1871325b 100644
--- a/src/features/MatchPopup/components/FinishedPlaylistPage/index.tsx
+++ b/src/features/MatchPopup/components/FinishedPlaylistPage/index.tsx
@@ -6,22 +6,26 @@ import { useMatchSwitchesStore } from 'features/MatchSwitches'
import { Name } from 'features/Name'
import { MediaQuery } from 'features/MediaQuery'
import { useMatchPopupStore } from 'features/MatchPopup'
+import {
+ CloseButton,
+ Header,
+ HeaderActions,
+ HeaderTitle,
+} from 'features/PopupComponents'
import { SettingsButton } from '../SettingsButton'
-import { CloseButton } from '../CloseButton'
import { BackButton } from '../BackButton'
import { FinishedMatchPlaylist } from '../FinishedMatchPlaylist'
import { PlayersListDesktop } from '../PlayersListDesktop'
import { PlayersListMobile } from '../PlayersListMobile'
-import {
- Content,
- Header,
- HeaderActions,
- HeaderTitle,
-} from '../../styled'
+import { Content } from '../../styled'
export const FinishedPlaylistPage = () => {
- const { match, matchPlaylists } = useMatchPopupStore()
+ const {
+ closePopup,
+ match,
+ matchPlaylists,
+ } = useMatchPopupStore()
const { isScoreHidden } = useMatchSwitchesStore()
if (!match) return null
@@ -50,7 +54,7 @@ export const FinishedPlaylistPage = () => {
-
+
diff --git a/src/features/MatchPopup/components/LivePlaylistPage/index.tsx b/src/features/MatchPopup/components/LivePlaylistPage/index.tsx
index c35ff9cf..cdac1619 100644
--- a/src/features/MatchPopup/components/LivePlaylistPage/index.tsx
+++ b/src/features/MatchPopup/components/LivePlaylistPage/index.tsx
@@ -1,7 +1,9 @@
+import { MDASH } from 'config'
+
import { Name } from 'features/Name'
import { useMatchPopupStore } from 'features/MatchPopup'
+import { CloseButton } from 'features/PopupComponents'
-import { CloseButton } from '../CloseButton'
import { LiveMatchPlaylist } from '../LiveMatchPlaylist'
import {
@@ -12,7 +14,11 @@ import {
} from './styled'
export const LivePlaylistPage = () => {
- const { match, matchPlaylists } = useMatchPopupStore()
+ const {
+ closePopup,
+ match,
+ matchPlaylists,
+ } = useMatchPopupStore()
if (!match) return null
const { team1, team2 } = match
@@ -22,12 +28,12 @@ export const LivePlaylistPage = () => {
- {' '} — {' '}
+ {' '} {MDASH} {' '}
-
+
diff --git a/src/features/MatchPopup/components/PlayersListDesktop/index.tsx b/src/features/MatchPopup/components/PlayersListDesktop/index.tsx
index bdcea602..a69c2291 100644
--- a/src/features/MatchPopup/components/PlayersListDesktop/index.tsx
+++ b/src/features/MatchPopup/components/PlayersListDesktop/index.tsx
@@ -1,7 +1,7 @@
import styled from 'styled-components/macro'
import { T9n } from 'features/T9n'
-import { customScrollbar } from 'features/Common'
+import { popupScrollbarStyles } from 'features/PopupComponents'
import { useMatchPopupStore } from 'features/MatchPopup'
import { Teams } from '../../types'
@@ -24,18 +24,7 @@ const ListsWrapper = styled.div`
flex-direction: row;
justify-content: space-around;
- ${customScrollbar};
-
- ::-webkit-scrollbar-thumb {
- border-radius: 3px;
- background: rgba(196, 196, 196, 0.3);
- }
-
- ::-webkit-scrollbar-track,
- ::-webkit-scrollbar-corner {
- border-radius: 3px;
- background: rgba(103, 103, 103, 0.3);
- }
+ ${popupScrollbarStyles};
`
export const PlayersListDesktop = () => {
diff --git a/src/features/MatchPopup/components/SettingsButton/index.tsx b/src/features/MatchPopup/components/SettingsButton/index.tsx
index 832f78c4..1989bd52 100644
--- a/src/features/MatchPopup/components/SettingsButton/index.tsx
+++ b/src/features/MatchPopup/components/SettingsButton/index.tsx
@@ -1,8 +1,7 @@
import styled from 'styled-components/macro'
-import { useMatchPopupStore } from 'features/MatchPopup/store'
-
-import { BaseButton } from '../../styled'
+import { useMatchPopupStore } from 'features/MatchPopup'
+import { BaseButton } from 'features/PopupComponents'
const Button = styled(BaseButton)`
background-image: url(/images/settings.svg);
diff --git a/src/features/MatchPopup/components/SettingsPage/index.tsx b/src/features/MatchPopup/components/SettingsPage/index.tsx
index 514da38b..2544768c 100644
--- a/src/features/MatchPopup/components/SettingsPage/index.tsx
+++ b/src/features/MatchPopup/components/SettingsPage/index.tsx
@@ -2,17 +2,18 @@ import styled from 'styled-components/macro'
import { MediaQuery } from 'features/MediaQuery'
import { T9n } from 'features/T9n'
-
-import { CloseButton } from '../CloseButton'
-import { BackButton } from '../BackButton'
-import { SettingsDesktop } from '../SettingsDesktop'
-import { SettingsMobile } from '../SettingsMobile'
import {
- Content,
+ CloseButton,
Header,
HeaderActions,
HeaderTitle,
-} from '../../styled'
+} from 'features/PopupComponents'
+
+import { useMatchPopupStore } from '../../store'
+import { BackButton } from '../BackButton'
+import { SettingsDesktop } from '../SettingsDesktop'
+import { SettingsMobile } from '../SettingsMobile'
+import { Content } from '../../styled'
const ButtonLabel = styled(T9n)`
display: flex;
@@ -23,38 +24,42 @@ const ButtonLabel = styled(T9n)`
color: rgba(255, 255, 255, 0.5);
`
-export const SettingsPage = () => (
-
-
-
-
-
-
+export const SettingsPage = () => {
+ const { closePopup } = useMatchPopupStore()
+
+ return (
+
+
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-)
+
+
+
+
+ )
+}
diff --git a/src/features/MatchPopup/styled.tsx b/src/features/MatchPopup/styled.tsx
index 74abdd11..e575f6fd 100644
--- a/src/features/MatchPopup/styled.tsx
+++ b/src/features/MatchPopup/styled.tsx
@@ -1,35 +1,9 @@
-import styled, { css } from 'styled-components/macro'
+import styled from 'styled-components/macro'
import { devices } from 'config'
import { customScrollbar } from 'features/Common'
-export const BaseButton = styled.button`
- padding: 0;
- border: none;
- background: none;
-
- cursor: pointer;
- width: 34px;
- height: 34px;
- color: white;
- background-color: rgba(255, 255, 255, 0.12);
- background-position: center;
- background-repeat: no-repeat;
- border-radius: 50%;
-
- :hover {
- background-color: rgba(255, 255, 255, 0.22);
- }
-
- @media ${devices.mobile} {
- width: 24px;
- height: 24px;
- background-color: transparent;
- border-radius: 0;
- }
-`
-
type ContentProps = {
height?: number,
}
@@ -51,67 +25,6 @@ export const Content = styled.div`
}
`
-export const Header = styled.div`
- position: relative;
- height: 35px;
- display: flex;
- align-items: center;
-
- @media ${devices.mobile} {
- height: 52px;
- background-color: rgba(255, 255, 255, 0.1);
- padding: 0 12px;
- }
-`
-
-type HeaderActionsProps = {
- marginLeft?: number,
- position: 'left' | 'right',
-}
-
-export const HeaderActions = styled.div`
- position: absolute;
- display: flex;
-
- ${({ marginLeft = 0, position }) => css`
- ${position}: 20px;
- margin-left: ${marginLeft}px;
- `}
-
- @media ${devices.mobile} {
- ${({ position }) => css`
- ${position}: 12px;
- margin-left: 0;
- `}
- }
-
- ${BaseButton}:not(:last-child) {
- margin-right: 20px;
- }
-`
-
-export const HeaderTitle = styled.h2`
- position: absolute;
- width: 70%;
- left: 50%;
- transform: translateX(-50%);
-
- font-weight: 600;
- font-size: 24px;
- line-height: 42px;
- color: #FFFFFF;
- text-align: center;
-
- @media ${devices.mobile} {
- font-size: 19px;
- line-height: 28px;
- text-align: center;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- }
-`
-
export const BlockTitle = styled.h3`
font-weight: normal;
font-size: 20px;
diff --git a/src/features/PopupComponents/BaseButton/index.tsx b/src/features/PopupComponents/BaseButton/index.tsx
new file mode 100644
index 00000000..742f41b2
--- /dev/null
+++ b/src/features/PopupComponents/BaseButton/index.tsx
@@ -0,0 +1,29 @@
+import styled from 'styled-components/macro'
+
+import { devices } from 'config'
+
+export const BaseButton = styled.button`
+ padding: 0;
+ border: none;
+ background: none;
+
+ cursor: pointer;
+ width: 34px;
+ height: 34px;
+ color: white;
+ background-color: rgba(255, 255, 255, 0.12);
+ background-position: center;
+ background-repeat: no-repeat;
+ border-radius: 50%;
+
+ :hover {
+ background-color: rgba(255, 255, 255, 0.22);
+ }
+
+ @media ${devices.mobile} {
+ width: 24px;
+ height: 24px;
+ background-color: transparent;
+ border-radius: 0;
+ }
+`
diff --git a/src/features/PopupComponents/CloseButton/index.tsx b/src/features/PopupComponents/CloseButton/index.tsx
new file mode 100644
index 00000000..30f5e7e3
--- /dev/null
+++ b/src/features/PopupComponents/CloseButton/index.tsx
@@ -0,0 +1,15 @@
+import type { MouseEvent } from 'react'
+
+import { Close } from 'features/Icons/Close'
+
+import { BaseButton } from '../BaseButton'
+
+type Props = {
+ onClick: (e: MouseEvent) => void,
+}
+
+export const CloseButton = ({ onClick }: Props) => (
+
+
+
+)
diff --git a/src/features/PopupComponents/Header/index.tsx b/src/features/PopupComponents/Header/index.tsx
new file mode 100644
index 00000000..d2e57b5a
--- /dev/null
+++ b/src/features/PopupComponents/Header/index.tsx
@@ -0,0 +1,69 @@
+import styled, { css } from 'styled-components/macro'
+
+import { devices } from 'config'
+
+import { BaseButton } from '../BaseButton'
+
+type HeaderProps = {
+ height?: number,
+}
+
+export const Header = styled.div`
+ position: relative;
+ height: ${({ height = 35 }) => height}px;
+ display: flex;
+
+ @media ${devices.mobile} {
+ height: 52px;
+ background-color: rgba(255, 255, 255, 0.1);
+ padding: 0 12px;
+ }
+`
+
+type HeaderActionsProps = {
+ marginLeft?: number,
+ position: 'left' | 'right',
+}
+
+export const HeaderActions = styled.div`
+ position: absolute;
+ display: flex;
+
+ ${({ marginLeft = 0, position }) => css`
+ ${position}: 20px;
+ margin-left: ${marginLeft}px;
+ `}
+
+ @media ${devices.mobile} {
+ ${({ position }) => css`
+ ${position}: 12px;
+ margin-left: 0;
+ `}
+ }
+
+ ${BaseButton}:not(:last-child) {
+ margin-right: 20px;
+ }
+`
+
+export const HeaderTitle = styled.h2`
+ position: absolute;
+ width: 70%;
+ left: 50%;
+ transform: translateX(-50%);
+
+ font-weight: 600;
+ font-size: 24px;
+ line-height: 42px;
+ color: #FFFFFF;
+ text-align: center;
+
+ @media ${devices.mobile} {
+ font-size: 19px;
+ line-height: 28px;
+ text-align: center;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+ }
+`
diff --git a/src/features/PopupComponents/index.tsx b/src/features/PopupComponents/index.tsx
new file mode 100644
index 00000000..9b85c26b
--- /dev/null
+++ b/src/features/PopupComponents/index.tsx
@@ -0,0 +1,4 @@
+export * from './BaseButton'
+export * from './CloseButton'
+export * from './Header'
+export * from './popupScrollbarStyles'
diff --git a/src/features/PopupComponents/popupScrollbarStyles/index.tsx b/src/features/PopupComponents/popupScrollbarStyles/index.tsx
new file mode 100644
index 00000000..7ec1720c
--- /dev/null
+++ b/src/features/PopupComponents/popupScrollbarStyles/index.tsx
@@ -0,0 +1,18 @@
+import { css } from 'styled-components/macro'
+
+import { customScrollbar } from 'features/Common'
+
+export const popupScrollbarStyles = css`
+ ${customScrollbar}
+
+ ::-webkit-scrollbar-thumb {
+ border-radius: 3px;
+ background: rgba(196, 196, 196, 0.3);
+ }
+
+ ::-webkit-scrollbar-track,
+ ::-webkit-scrollbar-corner {
+ border-radius: 3px;
+ background: rgba(103, 103, 103, 0.3);
+ }
+`
diff --git a/src/features/Price/index.tsx b/src/features/Price/index.tsx
new file mode 100644
index 00000000..d8ba71e7
--- /dev/null
+++ b/src/features/Price/index.tsx
@@ -0,0 +1,30 @@
+import { currencySymbols } from 'config'
+
+import { T9n } from 'features/T9n'
+
+import {
+ PriceWrapper,
+ PriceAmount,
+ PriceDetails,
+} from './styled'
+
+type Props = {
+ amount: number,
+ className?: string,
+ currency?: string,
+ perPeriod?: string,
+}
+
+export const Price = ({
+ amount,
+ className,
+ currency = currencySymbols.ruble,
+ perPeriod = 'month',
+}: Props) => (
+
+ {amount}
+
+ {currency} /
+
+
+)
diff --git a/src/features/Register/components/Price/styled.tsx b/src/features/Price/styled.tsx
similarity index 100%
rename from src/features/Register/components/Price/styled.tsx
rename to src/features/Price/styled.tsx
diff --git a/src/features/Register/components/AdditionalSubscription/index.tsx b/src/features/Register/components/AdditionalSubscription/index.tsx
index 3105b923..bb70d7a4 100644
--- a/src/features/Register/components/AdditionalSubscription/index.tsx
+++ b/src/features/Register/components/AdditionalSubscription/index.tsx
@@ -1,7 +1,7 @@
import { Checkbox } from 'features/Common'
import { MediaQuery } from 'features/MediaQuery'
+import { Price } from 'features//Price'
-import { Price } from '../Price'
import {
PriceItemTitle,
PriceItem,
diff --git a/src/features/Register/components/MainSubscription/index.tsx b/src/features/Register/components/MainSubscription/index.tsx
index 93170df4..33ea7da4 100644
--- a/src/features/Register/components/MainSubscription/index.tsx
+++ b/src/features/Register/components/MainSubscription/index.tsx
@@ -1,7 +1,7 @@
import { Radio } from 'features/Common'
import { MediaQuery } from 'features/MediaQuery'
+import { Price } from 'features/Price'
-import { Price } from '../Price'
import {
SubscriptionWrapper,
SubscriptionTitle,
diff --git a/src/features/Register/components/Price/index.tsx b/src/features/Register/components/Price/index.tsx
deleted file mode 100644
index fad97f58..00000000
--- a/src/features/Register/components/Price/index.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { useLexicsStore } from 'features/LexicsStore'
-
-import {
- PriceWrapper,
- PriceAmount,
- PriceDetails,
-} from './styled'
-
-type Props = {
- amount: number,
- currency?: string,
- perPeriod?: string,
-}
-
-export const Price = ({
- amount,
- currency = '₽',
- perPeriod = 'month',
-}: Props) => {
- const { translate } = useLexicsStore()
- const perPeriodTranslated = translate(perPeriod)
-
- return (
-
- {amount}
-
- {currency} / {perPeriodTranslated}
-
-
- )
-}
diff --git a/src/features/UserAccount/components/CardNumber/styled.tsx b/src/features/UserAccount/components/CardNumber/styled.tsx
index 26df887f..025a8dde 100644
--- a/src/features/UserAccount/components/CardNumber/styled.tsx
+++ b/src/features/UserAccount/components/CardNumber/styled.tsx
@@ -1,9 +1,9 @@
-import styled, { css } from 'styled-components/macro'
+import styled from 'styled-components/macro'
import { devices } from 'config/devices'
import { Label } from 'features/Common/Radio/styled'
-import { PriceAmount, PriceDetails } from 'features/Register/components/Price/styled'
+import { PriceAmount, PriceDetails } from 'features/Price/styled'
export const CardNumberWrapper = styled.div`
display: flex;
@@ -28,8 +28,8 @@ export const CardNumberWrapper = styled.div`
max-width: 415px;
${Label} {
- font-size: 16px;
-
+ font-size: 16px;
+
&::before {
margin-left: 12px;
margin-right: 12px;
@@ -76,11 +76,11 @@ export const CardNumberTextWrapper = styled(TextWrapper)`
}
`
-export type Props = {
+type Props = {
noMarginRight?: boolean,
}
-export const priceWrapperStyles = css`
+export const PriceWrapper = styled.div`
margin-left: auto;
margin-right: 24px;
@@ -103,8 +103,3 @@ export const priceWrapperStyles = css`
}
}
`
-
-export const PriceWrapper = styled.div`
- ${priceWrapperStyles}
-
-`
diff --git a/src/features/UserAccount/components/Subscription/index.tsx b/src/features/UserAccount/components/Subscription/index.tsx
index 83c69368..c8afa5db 100644
--- a/src/features/UserAccount/components/Subscription/index.tsx
+++ b/src/features/UserAccount/components/Subscription/index.tsx
@@ -1,4 +1,4 @@
-import { Price } from 'features/Register/components/Price'
+import { Price } from 'features/Price'
import { Radio } from 'features/Common/Radio'
import { Checkbox } from 'features/Common/Checkbox'
diff --git a/src/features/UserAccount/components/TextNoBorder/index.tsx b/src/features/UserAccount/components/TextNoBorder/index.tsx
index 65759aff..c37b59a0 100644
--- a/src/features/UserAccount/components/TextNoBorder/index.tsx
+++ b/src/features/UserAccount/components/TextNoBorder/index.tsx
@@ -1,4 +1,4 @@
-import { Price } from 'features/Register/components/Price'
+import { Price } from 'features/Price'
import { TextNoBorderWrapper, TextNoBorderTextWrapper } from './styled'
import { PriceWrapper } from '../CardNumber/styled'
diff --git a/src/features/UserAccount/components/UserAccountSubscription/index.tsx b/src/features/UserAccount/components/UserAccountSubscription/index.tsx
index cee2e7a9..d952b7b5 100644
--- a/src/features/UserAccount/components/UserAccountSubscription/index.tsx
+++ b/src/features/UserAccount/components/UserAccountSubscription/index.tsx
@@ -1,7 +1,7 @@
import { T9n } from 'features/T9n'
import type { ObjectWithName } from 'features/Name'
import { Name } from 'features/Name'
-import { Price } from 'features/Register/components/Price'
+import { Price } from 'features/Price'
import {
UserAccountSubscriptionWrapper,
diff --git a/src/features/UserAccount/components/UserAccountSubscriptionMatch/index.tsx b/src/features/UserAccount/components/UserAccountSubscriptionMatch/index.tsx
index 9d06e07c..7b3a3d4d 100644
--- a/src/features/UserAccount/components/UserAccountSubscriptionMatch/index.tsx
+++ b/src/features/UserAccount/components/UserAccountSubscriptionMatch/index.tsx
@@ -4,7 +4,7 @@ import format from 'date-fns/format'
import type { Match } from 'features/UserAccount/hooks/useUserSubscriptions'
import { Name } from 'features/Name'
-import { Price } from 'features/Register/components/Price'
+import { Price } from 'features/Price'
import { T9n } from 'features/T9n'
import {
diff --git a/src/requests/getMatchSubscriptions.tsx b/src/requests/getMatchSubscriptions.tsx
new file mode 100644
index 00000000..024495dc
--- /dev/null
+++ b/src/requests/getMatchSubscriptions.tsx
@@ -0,0 +1,28 @@
+import { API_ROOT } from 'config'
+import { callApi } from 'helpers'
+
+export enum SubscriptionType {
+ Month = 'month',
+ Year = 'year',
+}
+
+type MatchSubscription = {
+ description: string,
+ header: string,
+ price: number,
+ subscription_id: number,
+ type: SubscriptionType,
+}
+
+export type MatchSubscriptions = Array
+
+export const getMatchSubscriptions = (): Promise => {
+ const config = {
+ method: 'GET',
+ }
+
+ return callApi({
+ config,
+ url: `${API_ROOT}/account/get-subscriptions`,
+ })
+}
diff --git a/src/requests/index.tsx b/src/requests/index.tsx
index 78ee6a53..c4c397b0 100644
--- a/src/requests/index.tsx
+++ b/src/requests/index.tsx
@@ -24,3 +24,4 @@ export * from './getMatchesPreviewImages'
export * from './getSportActions'
export * from './getMatchPlaylists'
export * from './getPlayerPlaylists'
+export * from './getMatchSubscriptions'