From a0219f8212e6959747da8009b9529691c0625ef5 Mon Sep 17 00:00:00 2001 From: Mirlan Date: Thu, 1 Jul 2021 19:17:27 +0600 Subject: [PATCH] Ott 1049 stripe payments (#390) * Ott 1028 get token (#353) * feat(1028): get card token * fix(1028): fixed lang type * Ott 1028 card crud (#354) * feat(1028): added card requests * feat(1028): crud on card * feat(1028): buy subs. (#355) * feat(1072): production configuration (#356) * feat(1051): display payment and card link errors (#358) * Ott 1073 one time subs (#359) * refactor(1073): migrate to new proc response type * feat(1073): one time payments * Ott 1066 display default card (#360) * refactor(1066): display default card in subs list popup * fix(1066): test fix * feat(1080): 3ds (#361) * feat(1080): wip, 3ds * fix(1080): pr comments * refactor: url change (#382) --- Makefile | 2 +- package.json | 2 + public/index.html | 1 + src/config/env.tsx | 2 + src/config/lexics/indexLexics.tsx | 5 +- src/config/lexics/payment.tsx | 6 ++ src/config/lexics/userAccount.tsx | 5 +- src/config/procedures.tsx | 1 + .../components/ElementContainer/index.tsx | 63 ++++++++++++ .../components/Form/hooks/index.tsx | 55 +++++++++++ .../AddCardForm/components/Form/index.tsx | 96 +++++++++++++++++++ src/features/AddCardForm/index.tsx | 82 ++++++++-------- src/features/AddCardForm/styled.tsx | 41 +++++--- src/features/App/AuthenticatedApp.tsx | 81 +++++++++------- .../components/CardStep/index.tsx | 56 +++++++++++ .../components/CardsList/index.tsx | 44 +++++++++ .../components/ErrorStep/index.tsx | 6 +- .../components/SelectedCard/index.tsx | 38 +++----- .../SubscriptionSelectionStep/index.tsx | 24 ++++- .../components/SubscriptionsList/index.tsx | 9 +- .../components/SuccessStep/index.tsx | 4 +- src/features/BuyMatchPopup/index.tsx | 5 +- src/features/BuyMatchPopup/store/helpers.tsx | 32 +++++-- .../BuyMatchPopup/store/hooks/index.tsx | 84 ++++++++++++++-- .../store/hooks/useLexicsFetcher.tsx | 6 +- .../store/hooks/useStripe3DSecure.tsx | 20 ++++ .../store/hooks/useSubscriptions.tsx | 21 ++-- src/features/BuyMatchPopup/styled.tsx | 5 +- src/features/BuyMatchPopup/types.tsx | 9 +- src/features/CardsStore/hooks/index.tsx | 51 ++++++++++ src/features/CardsStore/index.tsx | 20 ++++ src/features/LanguageSelect/config.tsx | 4 +- src/features/LanguageSelect/index.tsx | 3 +- src/features/LexicsStore/hooks/useLang.tsx | 6 +- .../getMatchClickAction/__tests__/index.tsx | 2 +- src/features/Price/index.tsx | 15 ++- src/features/StripeElements/index.tsx | 24 +++++ .../UserAccount/components/BankCard/index.tsx | 22 +++-- .../components/BankCard/styled.tsx | 26 +++-- .../components/PageBankCards/index.tsx | 46 +++++---- src/helpers/callApi/logoutIfUnauthorized.tsx | 6 +- src/requests/addCard.tsx | 15 +++ src/requests/buyMatchSubscriptions.tsx | 24 ----- .../buyMatchPayOnceSubscription.tsx | 24 +++++ .../buySubscription/buyMatchSubscriptions.tsx | 25 +++++ .../handleUnsuccessfulSubscription.tsx | 39 ++++++++ src/requests/buySubscription/index.tsx | 4 + .../notifySuccessfulSubscription.tsx | 23 +++++ src/requests/deleteCard.tsx | 15 +++ src/requests/getCardsList.tsx | 22 +++++ src/requests/getSubscriptions.tsx | 15 ++- src/requests/index.tsx | 2 +- src/requests/setDefaultCard.tsx | 15 +++ 53 files changed, 999 insertions(+), 254 deletions(-) create mode 100644 src/config/lexics/payment.tsx create mode 100644 src/features/AddCardForm/components/ElementContainer/index.tsx create mode 100644 src/features/AddCardForm/components/Form/hooks/index.tsx create mode 100644 src/features/AddCardForm/components/Form/index.tsx create mode 100644 src/features/BuyMatchPopup/components/CardStep/index.tsx create mode 100644 src/features/BuyMatchPopup/components/CardsList/index.tsx create mode 100644 src/features/BuyMatchPopup/store/hooks/useStripe3DSecure.tsx create mode 100644 src/features/CardsStore/hooks/index.tsx create mode 100644 src/features/CardsStore/index.tsx create mode 100644 src/features/StripeElements/index.tsx create mode 100644 src/requests/addCard.tsx delete mode 100644 src/requests/buyMatchSubscriptions.tsx create mode 100644 src/requests/buySubscription/buyMatchPayOnceSubscription.tsx create mode 100644 src/requests/buySubscription/buyMatchSubscriptions.tsx create mode 100644 src/requests/buySubscription/handleUnsuccessfulSubscription.tsx create mode 100644 src/requests/buySubscription/index.tsx create mode 100644 src/requests/buySubscription/notifySuccessfulSubscription.tsx create mode 100644 src/requests/deleteCard.tsx create mode 100644 src/requests/getCardsList.tsx create mode 100644 src/requests/setDefaultCard.tsx diff --git a/Makefile b/Makefile index 39f84f15..277e001a 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ build: production-build: rm -rf build - REACT_APP_PRODUCTION=true npm run build + REACT_APP_PRODUCTION=true REACT_APP_STRIPE_PK=pk_live_ANI76cBhSo69DZUxPmyRVIZW npm run build .PHONY: build diff --git a/package.json b/package.json index 79bab867..f78ae89f 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "build-storybook": "build-storybook -s public" }, "dependencies": { + "@stripe/react-stripe-js": "^1.4.0", + "@stripe/stripe-js": "^1.13.2", "date-fns": "^2.14.0", "history": "^4.10.1", "hls.js": "^0.14.15", diff --git a/public/index.html b/public/index.html index eb0f51de..77ff5080 100644 --- a/public/index.html +++ b/public/index.html @@ -7,6 +7,7 @@ + Instat TV diff --git a/src/config/env.tsx b/src/config/env.tsx index 7590618f..de85b24d 100644 --- a/src/config/env.tsx +++ b/src/config/env.tsx @@ -1 +1,3 @@ export const isProduction = process.env.REACT_APP_PRODUCTION === 'true' + +export const STRIPE_PUBLIC_KEY = process.env.REACT_APP_STRIPE_PK || 'pk_test_fkEjSoWfJXuCwMgwHRpbOGPt' diff --git a/src/config/lexics/indexLexics.tsx b/src/config/lexics/indexLexics.tsx index a75b8e28..32f9cbef 100644 --- a/src/config/lexics/indexLexics.tsx +++ b/src/config/lexics/indexLexics.tsx @@ -1,4 +1,6 @@ +import { paymentLexics } from './payment' import { proceduresLexics } from './procedures' +import { publicLexics } from './public' const matchPopupLexics = { apply: 13491, @@ -75,7 +77,6 @@ export const indexLexics = { round_highilights: 13050, save: 828, search_results: 9014, - select_language: 1005, sport: 12993, team: 658, to_home: 13376, @@ -88,4 +89,6 @@ export const indexLexics = { ...proceduresLexics, ...matchPopupLexics, ...buyMatchPopupLexics, + ...publicLexics, + ...paymentLexics, } diff --git a/src/config/lexics/payment.tsx b/src/config/lexics/payment.tsx new file mode 100644 index 00000000..2f8315a2 --- /dev/null +++ b/src/config/lexics/payment.tsx @@ -0,0 +1,6 @@ +export const paymentLexics = { + add_card: 8313, + card_holder_name: 2021, + error_can_not_add_card: 14447, + error_payment_unsuccessful: 14446, +} diff --git a/src/config/lexics/userAccount.tsx b/src/config/lexics/userAccount.tsx index 411a843a..cf6e031b 100644 --- a/src/config/lexics/userAccount.tsx +++ b/src/config/lexics/userAccount.tsx @@ -1,4 +1,5 @@ -import { publicLexics } from 'config/lexics/public' +import { publicLexics } from './public' +import { paymentLexics } from './payment' const navigations = { bank_card: 14205, @@ -8,7 +9,6 @@ const navigations = { } export const userAccountLexics = { - add_card: 8313, change: 12614, country: 835, delete: 848, @@ -27,4 +27,5 @@ export const userAccountLexics = { user_account: 12928, ...navigations, ...publicLexics, + ...paymentLexics, } diff --git a/src/config/procedures.tsx b/src/config/procedures.tsx index 46377231..8fe91f0b 100644 --- a/src/config/procedures.tsx +++ b/src/config/procedures.tsx @@ -1,5 +1,6 @@ export const PROCEDURES = { auth_user: 'auth_user', + bind_ott_subscription: 'bind_ott_subscription', create_user: 'create_user', get_cities: 'get_cities', get_match_info: 'get_match_info', diff --git a/src/features/AddCardForm/components/ElementContainer/index.tsx b/src/features/AddCardForm/components/ElementContainer/index.tsx new file mode 100644 index 00000000..45be3d32 --- /dev/null +++ b/src/features/AddCardForm/components/ElementContainer/index.tsx @@ -0,0 +1,63 @@ +import { ReactNode } from 'react' + +import styled from 'styled-components/macro' + +import { T9n } from 'features/T9n' + +type LabelProps = { + backgroundColor?: string, + width?: string, +} + +const Label = styled.label` + display: flex; + height: 50px; + width: ${({ width }) => width || '100%'}; + padding: 0 25px; + background-color: ${({ backgroundColor = '#3F3F3F' }) => backgroundColor}; + box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.3); + border-radius: 2px; + border: 1px solid transparent; + + font-family: Montserrat; + font-style: normal; + font-weight: normal; + font-size: 16px; + line-height: 48px; + letter-spacing: -0.01em; + color: rgba(255, 255, 255, 0.5); + + :not(:first-child) { + margin-top: 10px; + } +` + +const Text = styled(T9n)` + margin-right: 20px; +` + +const ElementWrapper = styled.div` + height: 100%; + flex-grow: 1; +` + +type Props = { + backgroundColor?: string, + children: ReactNode, + label?: string, + width?: string, +} + +export const ElementContainer = ({ + backgroundColor, + children, + label, + width, +}: Props) => ( + +) diff --git a/src/features/AddCardForm/components/Form/hooks/index.tsx b/src/features/AddCardForm/components/Form/hooks/index.tsx new file mode 100644 index 00000000..23051384 --- /dev/null +++ b/src/features/AddCardForm/components/Form/hooks/index.tsx @@ -0,0 +1,55 @@ +import { FormEvent, useState } from 'react' + +import { + CardNumberElement, + useStripe, + useElements, +} from '@stripe/react-stripe-js' + +import { useCardsStore } from 'features/CardsStore' + +export type Props = { + initialformOpen?: boolean, + inputsBackground?: string, + onAddSuccess?: () => void, + submitButton?: 'outline' |'solid', +} + +export const useFormSubmit = ({ onAddSuccess }: Props) => { + const stripe = useStripe() + const elements = useElements() + const { onAddCard } = useCardsStore() + const [error, setError] = useState('') + + const handleSubmit = async (e: FormEvent) => { + e.preventDefault() + + if (!stripe || !elements) { + // Stripe.js has not loaded yet. + return + } + + const name: string = e.currentTarget.cardHolderName.value + + if (!name) { + setError('Name can not be empty') + return + } + + const cardNumberElement = elements.getElement(CardNumberElement) + if (!cardNumberElement) return + + const { error: tokenError, token } = await stripe.createToken( + cardNumberElement, + { name }, + ) + + if (tokenError) { + setError(tokenError.message || '') + } else if (token) { + onAddCard(token.id).then(onAddSuccess) + } + } + + return { error, handleSubmit } +} diff --git a/src/features/AddCardForm/components/Form/index.tsx b/src/features/AddCardForm/components/Form/index.tsx new file mode 100644 index 00000000..243cb349 --- /dev/null +++ b/src/features/AddCardForm/components/Form/index.tsx @@ -0,0 +1,96 @@ +import { + CardNumberElement, + CardExpiryElement, + CardCvcElement, +} from '@stripe/react-stripe-js' + +import { T9n } from 'features/T9n' +import { useCardsStore } from 'features/CardsStore' +import { OutlineButton, SolidButton } from 'features/UserAccount/styled' + +import { ElementContainer } from '../ElementContainer' + +import type { Props } from './hooks' +import { useFormSubmit } from './hooks' + +import { + Form, + Column, + ButtonsBlock, + Input, + Errors, +} from '../../styled' + +const baseStyles = { + color: '#fff', + fontFamily: 'Montserrat, Tahoma, sans-serif', + fontSize: '20px', + fontWeight: 'bold', + lineHeight: '50px', +} + +const options = { placeholder: '', style: { base: baseStyles } } + +const buttons = { + outline: OutlineButton, + solid: SolidButton, +} + +export const AddCardFormInner = (props: Props) => { + const { + inputsBackground, + submitButton = 'solid', + } = props + const { error: cardError } = useCardsStore() + const { error: formError, handleSubmit } = useFormSubmit(props) + + const SubmitButton = buttons[submitButton] + + return ( +
+ + + + + + + + + + + + + + + + + + + {(formError || cardError) && ( + + {formError} + + + ) } + + + Сохранить + + +
+ ) +} diff --git a/src/features/AddCardForm/index.tsx b/src/features/AddCardForm/index.tsx index 31440386..adef78fe 100644 --- a/src/features/AddCardForm/index.tsx +++ b/src/features/AddCardForm/index.tsx @@ -1,44 +1,42 @@ -import { SolidButton } from 'features/UserAccount/styled' +import type { MouseEvent } from 'react' -import { - Form, - Column, - ButtonsBlock, - Input, -} from './styled' +import { useToggle } from 'hooks' -export const AddCardForm = () => ( -
- - - - - - - - - Сохранить - - -
-) +import { T9n } from 'features/T9n' +import { OutlineButton, Icon } from 'features/UserAccount/styled' + +import type { Props } from './components/Form/hooks' +import { AddCardFormInner } from './components/Form' + +export const AddCardForm = ({ + initialformOpen, + inputsBackground, + submitButton, +}: Props) => { + const { isOpen, toggle } = useToggle(initialformOpen) + + const onAddClick = (e: MouseEvent) => { + e.stopPropagation() + toggle() + } + + return ( + isOpen + ? ( + + ) + : ( + + + + + ) + ) +} diff --git a/src/features/AddCardForm/styled.tsx b/src/features/AddCardForm/styled.tsx index 58d40c41..fb2d7560 100644 --- a/src/features/AddCardForm/styled.tsx +++ b/src/features/AddCardForm/styled.tsx @@ -1,8 +1,5 @@ import styled from 'styled-components/macro' -import { Input as InputBase } from 'features/Common' -import { InputWrapper } from 'features/Common/Input/styled' - export const Form = styled.form`` export const Column = styled.div` @@ -14,21 +11,37 @@ export const Column = styled.div` export const ButtonsBlock = styled.div` display: flex; + flex-direction: column; + align-items: start; margin-top: 40px; ` -export const Input = styled(InputBase).attrs(() => ({ - withError: false, -}))` - width: auto; +export const Input = styled.input` + color: #fff; + font-family: Montserrat, Tahoma, sans-serif; + font-size: 20px; + font-weight: bold; + line-height: 48px; + background-color: transparent; + border: none; + outline: none; + width: 100%; + padding: 0; + margin: 0; - ${InputWrapper} { - height: 50px; - padding: 0 24px; - margin-top: 10px; + :-webkit-autofill, + :-webkit-autofill:hover, + :-webkit-autofill:focus, + :-webkit-autofill:active { + box-shadow: 0 0 0 30px #535353 inset; + caret-color: ${({ theme: { colors } }) => colors.text}; + -webkit-text-fill-color: ${({ theme: { colors } }) => colors.text}; } +` - :first-child ${InputWrapper} { - margin-top: 0; - } +export const Errors = styled.span` + margin-bottom: 40px; + font-size: 16px; + line-height: 16px; + color: red; ` diff --git a/src/features/App/AuthenticatedApp.tsx b/src/features/App/AuthenticatedApp.tsx index 27788ef0..962cf6ec 100644 --- a/src/features/App/AuthenticatedApp.tsx +++ b/src/features/App/AuthenticatedApp.tsx @@ -9,6 +9,8 @@ import { import { indexLexics } from 'config/lexics/indexLexics' import { PAGES } from 'config' +import { StripeElements } from 'features/StripeElements' + import { useLexicsConfig } from 'features/LexicsStore' import { ExtendedSearchStore, ExtendedSearchPage } from 'features/ExtendedSearchPage' @@ -16,6 +18,7 @@ import { MatchSwitchesStore } from 'features/MatchSwitches' import { UserFavoritesStore } from 'features/UserFavorites/store' import { MatchPopup, MatchPopupStore } from 'features/MatchPopup' import { BuyMatchPopup, BuyMatchPopupStore } from 'features/BuyMatchPopup' +import { CardsStore } from 'features/CardsStore' const HomePage = lazy(() => import('features/HomePage')) const TeamPage = lazy(() => import('features/TeamPage')) @@ -28,43 +31,47 @@ export const AuthenticatedApp = () => { useLexicsConfig(indexLexics) return ( - - - - - - - + + + + + + + + + - {/* в Switch как прямой children можно рендерить только Route или Redirect */} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + {/* в Switch как прямой children можно рендерить только Route или Redirect */} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) } diff --git a/src/features/BuyMatchPopup/components/CardStep/index.tsx b/src/features/BuyMatchPopup/components/CardStep/index.tsx new file mode 100644 index 00000000..f30f6eff --- /dev/null +++ b/src/features/BuyMatchPopup/components/CardStep/index.tsx @@ -0,0 +1,56 @@ +import isEmpty from 'lodash/isEmpty' + +import { AddCardForm } from 'features/AddCardForm' +import { useCardsStore } from 'features/CardsStore' +import { useBuyMatchPopupStore } from 'features/BuyMatchPopup/store' +import { + CloseButton, + Header, + HeaderActions, + HeaderTitle, +} from 'features/PopupComponents' +import { T9n } from 'features/T9n' + +import { CardsList } from '../CardsList' + +import { + Wrapper, + Body, + Footer, + Button, +} from '../../styled' + +export const CardStep = () => { + const { cards } = useCardsStore() + const { close, subscribeToMatch } = useBuyMatchPopupStore() + + const emptyCards = isEmpty(cards) + + return ( + +
+ + {emptyCards ? 'Добавление карты' : 'Выберите карту для оплаты'} + + + + +
+ + + + +
+ {!emptyCards && ( + + )} +
+
+ ) +} diff --git a/src/features/BuyMatchPopup/components/CardsList/index.tsx b/src/features/BuyMatchPopup/components/CardsList/index.tsx new file mode 100644 index 00000000..79e698af --- /dev/null +++ b/src/features/BuyMatchPopup/components/CardsList/index.tsx @@ -0,0 +1,44 @@ +import map from 'lodash/map' +import styled from 'styled-components/macro' + +import { Radio } from 'features/Common' +import { useCardsStore } from 'features/CardsStore' + +const List = styled.ul` + width: 100%; + display: flex; + flex-wrap: wrap; + margin-top: 20px; + margin-bottom: 25px; +` + +const Item = styled.li` + width: 50%; + height: 50px; + display: flex; + align-items: center; +` + +export const CardsList = () => { + const { + cards, + defaultCard, + onSetDefaultCard, + } = useCardsStore() + + return ( + + { + map(cards, (card) => ( + + onSetDefaultCard(card.id)} + /> + + )) + } + + ) +} diff --git a/src/features/BuyMatchPopup/components/ErrorStep/index.tsx b/src/features/BuyMatchPopup/components/ErrorStep/index.tsx index f759c7ff..f8ff71e9 100644 --- a/src/features/BuyMatchPopup/components/ErrorStep/index.tsx +++ b/src/features/BuyMatchPopup/components/ErrorStep/index.tsx @@ -14,7 +14,7 @@ import { } from '../../styled' export const ErrorStep = () => { - const { close } = useBuyMatchPopupStore() + const { close, error: paymentError } = useBuyMatchPopupStore() return ( @@ -27,7 +27,9 @@ export const ErrorStep = () => { - + + {paymentError || } + ) diff --git a/src/features/BuyMatchPopup/components/SelectedCard/index.tsx b/src/features/BuyMatchPopup/components/SelectedCard/index.tsx index d9c046aa..fb6ec811 100644 --- a/src/features/BuyMatchPopup/components/SelectedCard/index.tsx +++ b/src/features/BuyMatchPopup/components/SelectedCard/index.tsx @@ -1,7 +1,8 @@ import styled from 'styled-components/macro' -import { T9n } from 'features/T9n' -import { ButtonOutline } from 'features/Common' +import capitalize from 'lodash/capitalize' + +import { useCardsStore } from 'features/CardsStore' const Wrapper = styled.div` display: flex; @@ -17,29 +18,14 @@ const CardInfo = styled.span` 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; +export const SelectedCard = () => { + const { defaultCard } = useCardsStore() - :hover { - color: rgba(255, 255, 255); - } -` + if (!defaultCard) return null -export const SelectedCard = () => ( - - Mastercard •••• 4432 - - - - -) + return ( + + {capitalize(defaultCard?.brand)} •••• {defaultCard?.last4} + + ) +} diff --git a/src/features/BuyMatchPopup/components/SubscriptionSelectionStep/index.tsx b/src/features/BuyMatchPopup/components/SubscriptionSelectionStep/index.tsx index de8d09b2..af5a4850 100644 --- a/src/features/BuyMatchPopup/components/SubscriptionSelectionStep/index.tsx +++ b/src/features/BuyMatchPopup/components/SubscriptionSelectionStep/index.tsx @@ -1,6 +1,9 @@ +import { useEffect } from 'react' + +import isNull from 'lodash/isNull' + import { MDASH } from 'config' -import { T9n } from 'features/T9n' import { CloseButton, Header, @@ -8,10 +11,12 @@ import { HeaderTitle, } from 'features/PopupComponents' import { Name } from 'features/Name' +import { useCardsStore } from 'features/CardsStore' import { useBuyMatchPopupStore } from '../../store' import { SelectedCard } from '../SelectedCard' import { Subscriptions } from '../Subscriptions' +import { Steps } from '../../types' import { Wrapper, Body, @@ -20,13 +25,24 @@ import { } from '../../styled' export const SubscriptionSelectionStep = () => { + const { + cards, + fetchCards, + } = useCardsStore() + const { close, + goTo, match, selectedSubscription, - subscribeToMatch, } = useBuyMatchPopupStore() + useEffect(() => { + if (isNull(cards)) { + fetchCards() + } + }, [cards, fetchCards]) + if (!match) return null return ( @@ -48,9 +64,9 @@ export const SubscriptionSelectionStep = () => {
diff --git a/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx b/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx index 1efa60ce..a5510849 100644 --- a/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx +++ b/src/features/BuyMatchPopup/components/SubscriptionsList/index.tsx @@ -1,10 +1,7 @@ import map from 'lodash/map' import { T9n } from 'features/T9n' -import type { - MatchSubscriptions, - MatchSubscription, -} from 'features/BuyMatchPopup/types' +import { MatchSubscription, SubscriptionType } from 'features/BuyMatchPopup/types' import { Header, @@ -17,7 +14,7 @@ import { type Props = { onSelect: (subscription: MatchSubscription) => void, selectedSubscription: MatchSubscription | null, - subscriptions: MatchSubscriptions, + subscriptions: Array, } export const SubscriptionsList = ({ @@ -52,7 +49,7 @@ export const SubscriptionsList = ({ ) diff --git a/src/features/BuyMatchPopup/components/SuccessStep/index.tsx b/src/features/BuyMatchPopup/components/SuccessStep/index.tsx index b7616219..3f9947a8 100644 --- a/src/features/BuyMatchPopup/components/SuccessStep/index.tsx +++ b/src/features/BuyMatchPopup/components/SuccessStep/index.tsx @@ -24,7 +24,9 @@ export const SuccessStep = () => { - + + +