From ee715e19e7cd303d7ec848d010cecefcabcf1817 Mon Sep 17 00:00:00 2001 From: Armen <35077035+Armen9393@users.noreply.github.com> Date: Tue, 3 Nov 2020 17:48:04 +0300 Subject: [PATCH] Ott 496 get set delete subscriptions (#207) * Ott 496 get set delete subscriptions 1 (#205) * feat(ott-496): part of the code * fix(ott-496): minor change in checkbo * fix(ott-496): fixed get subscriptions types * fix(ott-496): deleted unnecessary exports * fix(ott-496): fixed types * fix(ott-496): fixed types * fix(ott-496): deleted fullwidth from click outside * fix(ott-496): finish (#206) * fix(ott-496): finish * fix(ott-496): bug fix * fix(ott-496): added switch * fix(ott-496): bug fix according to Mirlan's comments * fix(ott-496): finish --- src/config/lexics/userAccount.tsx | 1 + src/config/procedures.tsx | 1 + src/features/Combobox/index.tsx | 2 +- src/features/Combobox/styled.tsx | 4 +- src/features/Common/Checkbox/index.tsx | 10 +- src/features/Common/Checkbox/styled.tsx | 1 + src/features/Common/Radio/index.tsx | 14 +-- src/features/Header/styled.tsx | 2 +- src/features/Login/index.tsx | 4 +- src/features/Login/styled.tsx | 3 +- .../MatchPage/MatchProfileCard/styled.tsx | 2 +- src/features/Modal/styled.tsx | 6 +- src/features/OutsideClick/index.tsx | 8 +- .../Register/components/CardStep/index.tsx | 5 +- .../components/RegistrationStep/index.tsx | 4 +- .../RegistrationSuccessful/index.tsx | 4 +- .../components/SubscriptionsStep/styled.tsx | 2 - .../components/CardNumber/index.tsx | 2 +- .../components/PageTitle/index.tsx | 2 +- .../components/Subscription/index.tsx | 67 ++++++++++ .../components/Subscription/styled.tsx | 84 +++++++++++++ .../components/SubscriptionsForm/index.tsx | 98 +++++++++++++++ .../components/SubscriptionsForm/styled.tsx | 16 +++ .../components/SubscriptionsModal/index.tsx | 70 +++++++++++ .../components/SubscriptionsModal/styled.tsx | 46 +++++++ .../components/TextNoBorder/index.tsx | 4 +- .../components/UserAccountButton/index.tsx | 15 ++- .../UserAccountSubscription/index.tsx | 29 ++++- .../UserAccountSubscription/styled.tsx | 41 ++++-- .../UserAccountSubscriptionMatch/index.tsx | 72 +++++++++++ .../UserAccountSubscriptionMatch/styled.tsx | 117 ++++++++++++++++++ .../UserAccount/hooks/useSubscriptions.tsx | 31 +++++ .../hooks/useUserSubscriptions.tsx | 92 +++++++++++--- src/features/UserAccount/index.tsx | 88 ++++++------- src/features/UserAccount/styled.tsx | 50 +++++++- src/requests/getSubscriptions.tsx | 34 +++++ src/requests/saveUserCustomSubscription.tsx | 33 +++-- src/requests/saveUserSubscription.tsx | 10 +- 38 files changed, 929 insertions(+), 145 deletions(-) create mode 100644 src/features/UserAccount/components/Subscription/index.tsx create mode 100644 src/features/UserAccount/components/Subscription/styled.tsx create mode 100644 src/features/UserAccount/components/SubscriptionsForm/index.tsx create mode 100644 src/features/UserAccount/components/SubscriptionsForm/styled.tsx create mode 100644 src/features/UserAccount/components/SubscriptionsModal/index.tsx create mode 100644 src/features/UserAccount/components/SubscriptionsModal/styled.tsx create mode 100644 src/features/UserAccount/components/UserAccountSubscriptionMatch/index.tsx create mode 100644 src/features/UserAccount/components/UserAccountSubscriptionMatch/styled.tsx create mode 100644 src/features/UserAccount/hooks/useSubscriptions.tsx create mode 100644 src/requests/getSubscriptions.tsx diff --git a/src/config/lexics/userAccount.tsx b/src/config/lexics/userAccount.tsx index 3108a9a1..a145a305 100644 --- a/src/config/lexics/userAccount.tsx +++ b/src/config/lexics/userAccount.tsx @@ -4,6 +4,7 @@ export const userAccountLexics = { add_card: 8313, change: 12614, country: 835, + delete: 848, delete_card: 8692, lastname: 858, mail: 12912, diff --git a/src/config/procedures.tsx b/src/config/procedures.tsx index 32bff37f..95e5c51e 100644 --- a/src/config/procedures.tsx +++ b/src/config/procedures.tsx @@ -8,6 +8,7 @@ export const PROCEDURES = { get_player_matches: 'get_player_matches', get_players_teams_tournaments: 'get_players_teams_tournaments', get_sport_list: 'get_sport_list', + get_subscriptions: 'get_subscriptions', get_team_info: 'get_team_info', get_team_matches: 'get_team_matches', get_tournament_info: 'get_tournament_info', diff --git a/src/features/Combobox/index.tsx b/src/features/Combobox/index.tsx index 71dde4ce..c9711cea 100644 --- a/src/features/Combobox/index.tsx +++ b/src/features/Combobox/index.tsx @@ -80,7 +80,7 @@ export const Combobox = (props: Props) => { /> )} {isOpen && !isEmpty(options) && ( - + diff --git a/src/features/Combobox/styled.tsx b/src/features/Combobox/styled.tsx index f8a1cbda..a25ca48e 100644 --- a/src/features/Combobox/styled.tsx +++ b/src/features/Combobox/styled.tsx @@ -17,8 +17,8 @@ export const PopOver = styled.ul` overflow: auto; z-index: 2; background: rgb(102, 102, 102); - ${customScrollbar} - ${customStylesMixin} + ${customScrollbar}; + ${customStylesMixin}; ` export const ListOption = styled.li<{isHighlighted?: boolean}>` diff --git a/src/features/Common/Checkbox/index.tsx b/src/features/Common/Checkbox/index.tsx index 69561388..57f3968c 100644 --- a/src/features/Common/Checkbox/index.tsx +++ b/src/features/Common/Checkbox/index.tsx @@ -10,8 +10,7 @@ type Props = Pick, ( | 'checked' | 'id' | 'name' - | 'value' - | 'onChange' + | 'onClick' )> & { label?: string, } @@ -21,16 +20,15 @@ export const Checkbox = ({ id, label, name, - onChange, - value, + onClick, }: Props) => ( diff --git a/src/features/Common/Checkbox/styled.tsx b/src/features/Common/Checkbox/styled.tsx index 09d653bb..b58f3d0b 100644 --- a/src/features/Common/Checkbox/styled.tsx +++ b/src/features/Common/Checkbox/styled.tsx @@ -13,6 +13,7 @@ export const Wrapper = styled.div` ` export const Label = styled.label` + display: flex; color: ${({ theme: { colors } }) => colors.text}; font-style: normal; font-weight: bold; diff --git a/src/features/Common/Radio/index.tsx b/src/features/Common/Radio/index.tsx index 587b36f5..0b5ec028 100644 --- a/src/features/Common/Radio/index.tsx +++ b/src/features/Common/Radio/index.tsx @@ -10,8 +10,7 @@ type Props = Pick, ( | 'checked' | 'id' | 'name' - | 'value' - | 'onChange' + | 'onClick' )> & { label?: string, } @@ -21,17 +20,18 @@ export const Radio = ({ id, label = '', name, - onChange, - value, + onClick, }: Props) => ( - + ) diff --git a/src/features/Header/styled.tsx b/src/features/Header/styled.tsx index c97baee8..e9ee6b6e 100644 --- a/src/features/Header/styled.tsx +++ b/src/features/Header/styled.tsx @@ -10,7 +10,7 @@ export const HomeButtonLink = styled(Link)` background-repeat: no-repeat; background-position: center; - &:hover{ + &:hover { background-image: url('/images/home-btn-hover.svg'); cursor:pointer; } diff --git a/src/features/Login/index.tsx b/src/features/Login/index.tsx index 3b561115..4de0ca05 100644 --- a/src/features/Login/index.tsx +++ b/src/features/Login/index.tsx @@ -35,9 +35,7 @@ const LoginForm = () => {
- - - + ` } ` -export const BlockTitle = styled.span` +export const BlockTitle = styled(T9n)` display: block; font-style: normal; font-weight: bold; diff --git a/src/features/MatchPage/MatchProfileCard/styled.tsx b/src/features/MatchPage/MatchProfileCard/styled.tsx index 026cc985..dc9f9155 100644 --- a/src/features/MatchPage/MatchProfileCard/styled.tsx +++ b/src/features/MatchPage/MatchProfileCard/styled.tsx @@ -27,7 +27,7 @@ export const Teams = styled.div` export const StyledLink = styled(ProfileLink)` font-weight: bold; color: white; - &:hover{ + &:hover { text-decoration: underline; } ` diff --git a/src/features/Modal/styled.tsx b/src/features/Modal/styled.tsx index b75a1026..153bffa3 100644 --- a/src/features/Modal/styled.tsx +++ b/src/features/Modal/styled.tsx @@ -16,7 +16,7 @@ export const ModalContainer = styled.div` font-weight: 600; ` export const ModalWindow = styled.div` - background: #3F3F3F; + background-color: #313131; position: relative; padding: 15px; box-shadow: 0px 5px 30px rgba(0, 0, 0, 0.7); @@ -26,7 +26,7 @@ export const ModalWindow = styled.div` export const ModalCloseButton = styled(CloseButton)` margin-right: 19px; margin-top: 16px; - width: 12.82px; - height: 12.82px; + width: 16px; + height: 16px; cursor: pointer; ` diff --git a/src/features/OutsideClick/index.tsx b/src/features/OutsideClick/index.tsx index 0dec7657..936b2a95 100644 --- a/src/features/OutsideClick/index.tsx +++ b/src/features/OutsideClick/index.tsx @@ -8,23 +8,19 @@ import { useOutsideClickEffect } from './hooks' type Props = { /** элемент, которому необходим функционал `OutsideClick` */ children: ReactNode, - fullWidth?: boolean, /** функция-коллбек, отрабатывающая по клику вне области элемента */ onClick: (event: MouseEvent) => void, } -const OutsideClickWrapper = styled.div<{fullWidth: boolean}>` - width: ${({ fullWidth }) => (fullWidth ? '100%' : '')}; -` +const OutsideClickWrapper = styled.div`` export const OutsideClick = ({ children, - fullWidth = false, onClick, }: Props) => { const wrapperRef = useOutsideClickEffect({ onClick }) return ( - + {children} ) diff --git a/src/features/Register/components/CardStep/index.tsx b/src/features/Register/components/CardStep/index.tsx index 068ec120..69c07e01 100644 --- a/src/features/Register/components/CardStep/index.tsx +++ b/src/features/Register/components/CardStep/index.tsx @@ -16,10 +16,7 @@ export const CardStep = () => { const defaultMessage = translate('please_fill_out_this_field') return ( - - - - + { return ( - - - + ( - - - + diff --git a/src/features/Register/components/SubscriptionsStep/styled.tsx b/src/features/Register/components/SubscriptionsStep/styled.tsx index 253e76d7..1519c041 100644 --- a/src/features/Register/components/SubscriptionsStep/styled.tsx +++ b/src/features/Register/components/SubscriptionsStep/styled.tsx @@ -41,8 +41,6 @@ export const SubscriptionsBlock = styled.div` return '80px' }}; } - - ` export const BlockTitle = styled.span` diff --git a/src/features/UserAccount/components/CardNumber/index.tsx b/src/features/UserAccount/components/CardNumber/index.tsx index d33d1b43..c2371b68 100644 --- a/src/features/UserAccount/components/CardNumber/index.tsx +++ b/src/features/UserAccount/components/CardNumber/index.tsx @@ -21,7 +21,7 @@ export const CardNumber = ({ {}} + onClick={() => {}} /> diff --git a/src/features/UserAccount/components/PageTitle/index.tsx b/src/features/UserAccount/components/PageTitle/index.tsx index ad12b2ad..08705830 100644 --- a/src/features/UserAccount/components/PageTitle/index.tsx +++ b/src/features/UserAccount/components/PageTitle/index.tsx @@ -20,7 +20,7 @@ export const PageTitle = ({ titleText }: Props) => { - {titleText} + ) diff --git a/src/features/UserAccount/components/Subscription/index.tsx b/src/features/UserAccount/components/Subscription/index.tsx new file mode 100644 index 00000000..6b8cbeb1 --- /dev/null +++ b/src/features/UserAccount/components/Subscription/index.tsx @@ -0,0 +1,67 @@ +import React from 'react' + +import { Price } from 'features/Register/components/Price' +import { Radio } from 'features/Common/Radio' +import { Checkbox } from 'features/Common/Checkbox' + +import { + CheckboxWrapper, + SubscriptionWrapper, + BoldTextWrapper, + NormalTextWrapper, +} from './styled' +import { PriceWrapper } from '../CardNumber/styled' + +type Props = { + amount: number, + checked?: boolean, + id: string, + inputType?: string, + label?: string, + noMarginBottom?: boolean, + noMarginTop?: boolean, + packageAction?: string, + packageName?: string, + selectSubscription: () => void, +} + +export const Subscription = ({ + amount, + checked, + id, + inputType, + label, + noMarginBottom, + noMarginTop, + packageAction, + packageName, + selectSubscription, +}: Props) => ( + + {inputType === 'radio' && ( + + )} + {inputType === 'checkbox' && ( + + + + )} + {packageName && {packageName}} + {packageAction && {packageAction}} + + + + +) diff --git a/src/features/UserAccount/components/Subscription/styled.tsx b/src/features/UserAccount/components/Subscription/styled.tsx new file mode 100644 index 00000000..b179b50a --- /dev/null +++ b/src/features/UserAccount/components/Subscription/styled.tsx @@ -0,0 +1,84 @@ +import styled, { css } from 'styled-components/macro' + +import { Label as CheckboxLabel } from 'features/Common/Checkbox/styled' +import { Label as RadioLabel } from 'features/Common/Radio/styled' + +import { TextWrapper } from '../CardNumber/styled' + +type Props = { + noMarginBottom?: boolean, + noMarginTop?: boolean, +} + +export const SubscriptionWrapperStyles = css` + display: flex; + align-items: center; + justify-content: flex-start; + height: 48px; + background-color: #3F3F3F; + border-top: ${({ noMarginBottom, noMarginTop }) => (noMarginBottom && noMarginTop ? '1px solid #000' : '')}; + border-bottom: ${({ noMarginBottom, noMarginTop }) => (noMarginBottom && noMarginTop ? '1px solid #000' : '')}; + border-radius: ${({ noMarginBottom, noMarginTop }) => { + switch (true) { + case noMarginTop && noMarginBottom: + return '0' + case noMarginTop: + return '0 0 2px 2px' + case noMarginBottom: + return '2px 2px 0 0' + default: + return '2px' + } + }}; + + + + margin-top: ${({ noMarginTop }) => (noMarginTop ? '0' : '20px')}; + margin-bottom: ${({ noMarginBottom }) => (noMarginBottom ? '0' : '20px')}; + width: 100%; + ${RadioLabel}::before { + margin-left: 22px; + } +` + +export const SubscriptionWrapper = styled.div` + ${SubscriptionWrapperStyles}; + + label{ + font-size: 16px; + } + &:nth-child(n+1) { + border-bottom: ${({ noMarginBottom }) => (noMarginBottom ? '1px solid #000' : '')}; + border-top: ${({ noMarginBottom, noMarginTop }) => (noMarginBottom && noMarginTop ? 'none' : '')}; + } +` + +export const CheckboxWrapper = styled.div` + ${CheckboxLabel} { + font-weight: bold; + font-size: 16px; + line-height: 24px; + + &::before { + margin-left: 22px; + } + } +` + +export const BoldTextWrapper = styled(TextWrapper)` + color: #fff; + font-weight: bold; + font-size: 20px; + margin-right: 24px; + + &:hover { + cursor: default; +} +` + +export const NormalTextWrapper = styled(TextWrapper)` + color: #fff; + font-weight: normal; + font-size: 16px; + margin-right: 24px; +` diff --git a/src/features/UserAccount/components/SubscriptionsForm/index.tsx b/src/features/UserAccount/components/SubscriptionsForm/index.tsx new file mode 100644 index 00000000..103dfbd3 --- /dev/null +++ b/src/features/UserAccount/components/SubscriptionsForm/index.tsx @@ -0,0 +1,98 @@ +import React, { Fragment } from 'react' + +import map from 'lodash/map' +import isNumber from 'lodash/isNumber' +import isArray from 'lodash/isArray' +import find from 'lodash/find' + +import type { SportList } from 'requests/getSportList' + +import { useLexicsStore } from 'features/LexicsStore' + +import type { Subscription, UserSubscriptions } from '../../hooks/useUserSubscriptions' +import { UserAccountButton } from '../UserAccountButton' +import { UserAccountSubscription } from '../UserAccountSubscription' +import { UserAccountSubscriptionMatch } from '../UserAccountSubscriptionMatch' +import { TextNoBorder } from '../TextNoBorder' + +import { + UserAccountBlockTitle, + SubscriptionTitle, +} from './styled' + +type Props = { + deleteUserSubscription: (subscription: Subscription, sport: number) => void, + open: () => void, + selectedSubscription: number | null, + selectedSubscriptionLexic: string, + sportList: SportList, + userSubscriptions: any, +} + +export const SubscriptionsForm = ({ + deleteUserSubscription, + open, + selectedSubscription, + selectedSubscriptionLexic, + sportList, + userSubscriptions, +}: Props) => { + const { translate } = useLexicsStore() + + return ( + + + {isNumber(selectedSubscription) && ( + + )} + {map(userSubscriptions, (subscription) => { + const sportName = find(sportList, (item) => subscription.sport === item.id) + return ( + + {sportName && } + {map(subscription, (item: UserSubscriptions) => { + if (isArray(item)) { + return map(item, (subscriptionObj) => { + if (subscriptionObj.date) { + return ( + deleteUserSubscription(subscriptionObj, subscription.sport) + } + /> + ) + } + return ( + deleteUserSubscription(subscriptionObj, subscription.sport) + } + /> + ) + }) + } + return null + })} + + ) + })} + + + + ) +} diff --git a/src/features/UserAccount/components/SubscriptionsForm/styled.tsx b/src/features/UserAccount/components/SubscriptionsForm/styled.tsx new file mode 100644 index 00000000..76f26ba0 --- /dev/null +++ b/src/features/UserAccount/components/SubscriptionsForm/styled.tsx @@ -0,0 +1,16 @@ +import styled from 'styled-components/macro' + +import { BlockTitle } from 'features/Login/styled' +import { T9n } from 'features/T9n' + +export const UserAccountBlockTitle = styled(BlockTitle)` + align-self: flex-start; +` + +export const SubscriptionTitle = styled(T9n)` + color: white; + font-weight: 500; + font-size: 25px; + align-self: flex-start; + margin-top: 40px; +` diff --git a/src/features/UserAccount/components/SubscriptionsModal/index.tsx b/src/features/UserAccount/components/SubscriptionsModal/index.tsx new file mode 100644 index 00000000..e9a360cc --- /dev/null +++ b/src/features/UserAccount/components/SubscriptionsModal/index.tsx @@ -0,0 +1,70 @@ +import React from 'react' + +import map from 'lodash/map' + +import type { SubscriptionType } from 'requests/getSubscriptions' + +import { Modal } from 'features/Modal' +import { useLexicsStore } from 'features/LexicsStore' + +import { Subscription } from '../Subscription' + +import { + AddSubscriptionModal, + Line, + ModalTitle, + SubscriptionsWrapper, + SaveButton, +} from './styled' + +type Props = { + close: () => void, + isOpen: boolean, + saveSubscription: () => void, + selectedSubscription: number | null, + setSelectedSubscription: (arg: number | null) => void, + subscriptions: Array, +} + +export const SubscriptionModal = ({ + close, + isOpen, + saveSubscription, + selectedSubscription, + setSelectedSubscription, + subscriptions, +}: Props) => { + const { translate } = useLexicsStore() + + return ( + + + + + + {map(subscriptions, (subscription) => ( + { + setSelectedSubscription(subscription.id) + }} + /> + ))} + + + Save + + + + ) +} diff --git a/src/features/UserAccount/components/SubscriptionsModal/styled.tsx b/src/features/UserAccount/components/SubscriptionsModal/styled.tsx new file mode 100644 index 00000000..ec5f6373 --- /dev/null +++ b/src/features/UserAccount/components/SubscriptionsModal/styled.tsx @@ -0,0 +1,46 @@ +import styled from 'styled-components/macro' + +import { customScrollbar, customStylesMixin } from 'features/Common' +import { T9n } from 'features/T9n' + +import { OutlinedButton } from '../../styled' + +export const AddSubscriptionModal = styled.div` + width: 538px; + height: 452px; + display: flex; + flex-direction: column; + align-items: center; +` + +export const ModalTitle = styled(T9n)` + display: block; + font-size: 24px; + font-weight: normal; +` + +export const Line = styled.hr` + position:absolute; + width: 100%; + top: 40px; + height: 1px; + border: 1px solid #3F3F3F; +` + +export const SaveButton = styled(OutlinedButton)` + width: 192px; + height: 36px; + display: block; + font-weight: normal; + margin-left: auto; + margin-top: auto; +` + +export const SubscriptionsWrapper = styled.div` + margin-top: 45px; + width: 100%; + height: 100%; + overflow: auto; + ${customScrollbar}; + ${customStylesMixin}; +` diff --git a/src/features/UserAccount/components/TextNoBorder/index.tsx b/src/features/UserAccount/components/TextNoBorder/index.tsx index e0a83b69..28e77112 100644 --- a/src/features/UserAccount/components/TextNoBorder/index.tsx +++ b/src/features/UserAccount/components/TextNoBorder/index.tsx @@ -15,7 +15,9 @@ export const TextNoBorder = ({ text, }: Props) => ( - {text} + + {text} + diff --git a/src/features/UserAccount/components/UserAccountButton/index.tsx b/src/features/UserAccount/components/UserAccountButton/index.tsx index 6fafbd1c..ea66638c 100644 --- a/src/features/UserAccount/components/UserAccountButton/index.tsx +++ b/src/features/UserAccount/components/UserAccountButton/index.tsx @@ -1,11 +1,20 @@ import React from 'react' +import { T9n } from 'features/T9n' + import { PlusIconWrapper } from '../PlusIcon' import { UserAccountButtonWrapper, PlusIconTextWrapper } from './styled' -export const UserAccountButton = ({ text }: { text: string }) => ( - +type Props = { + open?: () => void, + text: string, +} + +export const UserAccountButton = ({ open, text }: Props) => ( + - {text} + + + ) diff --git a/src/features/UserAccount/components/UserAccountSubscription/index.tsx b/src/features/UserAccount/components/UserAccountSubscription/index.tsx index d00ba920..7203367e 100644 --- a/src/features/UserAccount/components/UserAccountSubscription/index.tsx +++ b/src/features/UserAccount/components/UserAccountSubscription/index.tsx @@ -1,20 +1,25 @@ import React from 'react' +import { T9n } from 'features/T9n' +import type { ObjectWithName } from 'features/Name' +import { Name } from 'features/Name' import { Price } from 'features/Register/components/Price' import { UserAccountSubscriptionWrapper, UserAccountBoldTextWrapper, UserAccountNormalTextWrapper, - Text, + UserAccountText, + UserAccountDeleteButton, } from './styled' import { PriceWrapper } from '../CardNumber/styled' type Props = { amount: number, checked?: boolean, + deleteSubscription?: () => void, inputType?: string, - label?: string, + label?: ObjectWithName, noMarginBottom?: boolean, noMarginTop?: boolean, packageAction?: string, @@ -23,6 +28,7 @@ type Props = { export const UserAccountSubscription = ({ amount, + deleteSubscription, label, noMarginBottom, noMarginTop, @@ -33,11 +39,24 @@ export const UserAccountSubscription = ({ noMarginTop={noMarginTop} noMarginBottom={noMarginBottom} > - {label} - {packageName && {packageName}} - {packageAction && {packageAction}} + + + + {packageName + && ( + + + + )} + {packageAction + && {packageAction}} + {deleteSubscription && ( + + + + )} ) diff --git a/src/features/UserAccount/components/UserAccountSubscription/styled.tsx b/src/features/UserAccount/components/UserAccountSubscription/styled.tsx index 13eb5f4f..e397cd3c 100644 --- a/src/features/UserAccount/components/UserAccountSubscription/styled.tsx +++ b/src/features/UserAccount/components/UserAccountSubscription/styled.tsx @@ -10,7 +10,7 @@ type Props = { noMarginTop?: boolean, } -export const UserAccountSubscriptionWrapperStyles = css` +export const SubscriptionWrapperStyles = css` display: flex; align-items: center; justify-content: flex-start; @@ -19,16 +19,16 @@ export const UserAccountSubscriptionWrapperStyles = css` border-top: ${({ noMarginBottom, noMarginTop }) => (noMarginBottom && noMarginTop ? '1px solid #000' : '')}; border-bottom: ${({ noMarginBottom, noMarginTop }) => (noMarginBottom && noMarginTop ? '1px solid #000' : '')}; border-radius: ${({ noMarginBottom, noMarginTop }) => { - if (noMarginTop && noMarginBottom) { - return '0' + switch (true) { + case noMarginTop && noMarginBottom: + return '0' + case noMarginTop: + return '0 0 2px 2px' + case noMarginBottom: + return '2px 2px 0 0' + default: + return '2px' } - if (noMarginTop) { - return '0 0 2px 2px' - } - if (noMarginBottom) { - return '2px 2px 0 0' - } - return '2px' }}; margin-top: ${({ noMarginTop }) => (noMarginTop ? '0' : '20px')}; margin-bottom: ${({ noMarginBottom }) => (noMarginBottom ? '0' : '20px')}; @@ -39,8 +39,25 @@ export const UserAccountSubscriptionWrapperStyles = css` } ` +export const UserAccountDeleteButton = styled.button` + width: 80px; + height: 100%; + background: red; + cursor: pointer; + border: none; + color: white; + font-size: 15px; + font-weight: 600; + display: none; +` + export const UserAccountSubscriptionWrapper = styled.div` - ${UserAccountSubscriptionWrapperStyles}; + ${SubscriptionWrapperStyles}; + &:hover { + ${UserAccountDeleteButton} { + display: block; + } + } &:nth-child(n+1) { border-bottom: ${({ noMarginBottom }) => (noMarginBottom ? '1px solid #000' : '')}; @@ -60,7 +77,7 @@ export const CheckboxWrapper = styled.div` } ` -export const Text = styled.p` +export const UserAccountText = styled.p` color: #fff; font-size: 18px; cursor: default; diff --git a/src/features/UserAccount/components/UserAccountSubscriptionMatch/index.tsx b/src/features/UserAccount/components/UserAccountSubscriptionMatch/index.tsx new file mode 100644 index 00000000..a7125165 --- /dev/null +++ b/src/features/UserAccount/components/UserAccountSubscriptionMatch/index.tsx @@ -0,0 +1,72 @@ +import React, { Fragment } from 'react' + +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 { T9n } from 'features/T9n' + +import { + UserAccountSubscriptionWrapper, + UserAccountBoldTextWrapper, + UserAccountTextLeftPart, + UserAccountNormalTextWrapper, + UserAccountText, + UserAccountDate, + UserAccountDeleteButton, + UserAccountTeams, +} from './styled' +import { PriceWrapper } from '../CardNumber/styled' + +type Props = { + amount: number, + deleteSubscription?: () => void, + inputType?: string, + matchData: Match, + noMarginBottom?: boolean, + noMarginTop?: boolean, + packageAction?: string, + packageName?: string, +} + +export const UserAccountSubscriptionMatch = ({ + amount, + deleteSubscription, + matchData, + noMarginBottom, + noMarginTop, + packageAction, + packageName, +}: Props) => ( + + + + + {format(new Date(matchData.date), 'dd.MM.yyyy')} + + + + + + + - + + + {packageName + && {packageName}} + {packageAction + && {packageAction}} + + + + {deleteSubscription && ( + + + + )} + +) diff --git a/src/features/UserAccount/components/UserAccountSubscriptionMatch/styled.tsx b/src/features/UserAccount/components/UserAccountSubscriptionMatch/styled.tsx new file mode 100644 index 00000000..dab38986 --- /dev/null +++ b/src/features/UserAccount/components/UserAccountSubscriptionMatch/styled.tsx @@ -0,0 +1,117 @@ +import styled, { css } from 'styled-components/macro' + +import { Label as CheckboxLabel } from 'features/Common/Checkbox/styled' +import { Label as RadioLabel } from 'features/Common/Radio/styled' + +import { TextWrapper } from '../CardNumber/styled' + +type Props = { + noMarginBottom?: boolean, + noMarginTop?: boolean, +} + +export const SubscriptionWrapperStyles = css` + display: flex; + align-items: center; + justify-content: flex-start; + height: 75px; + background-color: #3F3F3F; + border-top: ${({ noMarginBottom, noMarginTop }) => (noMarginBottom && noMarginTop ? '1px solid #000' : '')}; + border-bottom: ${({ noMarginBottom, noMarginTop }) => (noMarginBottom && noMarginTop ? '1px solid #000' : '')}; + border-radius: ${({ noMarginBottom, noMarginTop }) => { + switch (true) { + case noMarginTop && noMarginBottom: + return '0' + case noMarginTop: + return '0 0 2px 2px' + case noMarginBottom: + return '2px 2px 0 0' + default: + return '2px' + } + }}; + margin-top: ${({ noMarginTop }) => (noMarginTop ? '0' : '20px')}; + margin-bottom: ${({ noMarginBottom }) => (noMarginBottom ? '0' : '20px')}; + padding-left: 20px; + width: 100%; + ${RadioLabel}::before { + margin-left: 22px; + } +` + +export const UserAccountDeleteButton = styled.button` + width: 80px; + height: 100%; + background: red; + cursor: pointer; + border: none; + color: white; + font-size: 15px; + font-weight: 600; + display: none; +` +export const UserAccountTextLeftPart = styled.div`` + +export const UserAccountSubscriptionWrapper = styled.div` + ${SubscriptionWrapperStyles}; + &:hover { + ${UserAccountDeleteButton} { + display: block; + } + } + + &:nth-child(n+1) { + border-bottom: ${({ noMarginBottom }) => (noMarginBottom ? '1px solid #000' : '')}; + border-top: ${({ noMarginBottom, noMarginTop }) => (noMarginBottom && noMarginTop ? 'none' : '')}; + } +` + +export const CheckboxWrapper = styled.div` + ${CheckboxLabel} { + font-weight: bold; + font-size: 16px; + line-height: 24px; + + &::before { + margin-left: 22px; + } + } +` + +export const UserAccountDate = styled.span` + color: #fff; + font-size: 17px; + cursor: default; +` +export const UserAccountText = styled.span` + color: #fff; + font-size: 18px; + cursor: default; + font-weight: 800; + margin-left: 20px; +` + +export const UserAccountTeams = styled.p` + color: #fff; + font-size: 18px; + cursor: default; + margin-top: 15px; +` + +export const UserAccountBoldTextWrapper = styled(TextWrapper)` + color: #fff; + font-weight: bold; + font-size: 20px; + margin-right: 24px; + + &:hover { + cursor: default; +} +` + +export const UserAccountNormalTextWrapper = styled(TextWrapper)` + color: #fff; + font-weight: normal; + font-size: 16px; + margin-right: 24px; +` diff --git a/src/features/UserAccount/hooks/useSubscriptions.tsx b/src/features/UserAccount/hooks/useSubscriptions.tsx new file mode 100644 index 00000000..73c003bf --- /dev/null +++ b/src/features/UserAccount/hooks/useSubscriptions.tsx @@ -0,0 +1,31 @@ +import { + useEffect, + useState, +} from 'react' + +import map from 'lodash/map' + +import type { SubscriptionType } from 'requests/getSubscriptions' +import { getSubscriptions } from 'requests/getSubscriptions' + +import { useLexicsStore } from 'features/LexicsStore' + +export const useSubscriptions = () => { + const [subscriptions, setSubscriptions] = useState>([]) + + const { addLexicsConfig } = useLexicsStore() + + useEffect(() => { + getSubscriptions().then((res) => { + const lexicsArray = map(res, (subscription) => ( + String(subscription.lexic) + )) + addLexicsConfig(lexicsArray) + setSubscriptions(res) + }) + }, [addLexicsConfig]) + + return { + subscriptions, + } +} diff --git a/src/features/UserAccount/hooks/useUserSubscriptions.tsx b/src/features/UserAccount/hooks/useUserSubscriptions.tsx index 0dc2bef4..943ae635 100644 --- a/src/features/UserAccount/hooks/useUserSubscriptions.tsx +++ b/src/features/UserAccount/hooks/useUserSubscriptions.tsx @@ -1,41 +1,99 @@ import { useEffect, useState, - useCallback, } from 'react' -import map from 'lodash/map' - +import type { SportList } from 'requests/getSportList' +import { + SubscriptionAction, + saveUserCustomSubscription, +} from 'requests/saveUserCustomSubscription' +import { getSportList } from 'requests/getSportList' import { getUserSubscriptions } from 'requests/getUserSubscriptions' +import { saveUserSubscription } from 'requests/saveUserSubscription' -import { useLexicsStore } from 'features/LexicsStore' +import { useToggle } from 'hooks' -export type Team = { +export type Subscription = { id: number, name_eng: string, name_rus: string, + type?: number, +} + +type Name = { + name_eng: string, + name_rus: string, +} + +export type Match = { + date: Date, + id: number, + team1: Name, + team2: Name, + tournament: Name, +} + +export type UserSubscriptions = { + matches?: Array, + sport: number, + teams?: Array, + tournaments?: Array, } export const useUserSubscriptions = () => { - const [subscriptions, setSubscriptions] = useState>([]) - const { suffix } = useLexicsStore() + const [userSubscriptions, setUserSubscriptions] = useState>([]) + const [selectedSubscription, setSelectedSubscription] = useState(null) + const [selectedSubscriptionLexic, setSelectedSubscriptionLexic] = useState('') + const [sportList, setSportList] = useState([]) - type Names = 'name_eng' | 'name_rus' + const { + close, + isOpen, + open, + } = useToggle() useEffect(() => { getUserSubscriptions().then((res) => { - setSubscriptions(res.custom?.[0].teams) + setUserSubscriptions(res.custom) + setSelectedSubscription(res.id) + setSelectedSubscriptionLexic(`${res.lexic}`) }) + + getSportList().then(setSportList) }, []) - const normalizeSubscriptions = useCallback(() => { - const nameKey = `name_${suffix}` as Names + const saveSubscription = async () => { + await saveUserSubscription(selectedSubscription) + close() + await getUserSubscriptions().then((res) => { + setSelectedSubscription(res.id) + setSelectedSubscriptionLexic(`${res.lexic}`) + }) + } - return map(subscriptions, (team) => ({ - ...team, - name: team[nameKey], - })) - }, [subscriptions, suffix]) + const deleteUserSubscription = async (subscription: Subscription, sport: number) => { + await saveUserCustomSubscription({ + action: SubscriptionAction.REMOVE, + id: subscription.id, + sport, + type: subscription.type as number, + }) + await getUserSubscriptions().then((res) => { + setUserSubscriptions(res.custom) + }) + } - return normalizeSubscriptions() + return { + close, + deleteUserSubscription, + isOpen, + open, + saveSubscription, + selectedSubscription, + selectedSubscriptionLexic, + setSelectedSubscription, + sportList, + userSubscriptions, + } } diff --git a/src/features/UserAccount/index.tsx b/src/features/UserAccount/index.tsx index ef657448..f02829fa 100644 --- a/src/features/UserAccount/index.tsx +++ b/src/features/UserAccount/index.tsx @@ -1,7 +1,5 @@ import React from 'react' -import map from 'lodash/map' - import { userAccountLexics } from 'config/lexics/userAccount' import { formIds } from 'config/form' @@ -10,24 +8,26 @@ import { Input } from 'features/Common' import { Form } from 'features/Login/styled' import { T9n } from 'features/T9n' import { Error } from 'features/Common/Input/styled' -import { useLexicsStore, useLexicsConfig } from 'features/LexicsStore' +import { useLexicsConfig } from 'features/LexicsStore' +import { useUserInfo } from './hooks/useUserInfo' +import { useUserSubscriptions } from './hooks/useUserSubscriptions' +import { useSubscriptions } from './hooks/useSubscriptions' import { CardNumber } from './components/CardNumber' import { UserAccountButton } from './components/UserAccountButton' import { PageTitle } from './components/PageTitle' -import { UserAccountSubscription } from './components/UserAccountSubscription' -import { TextNoBorder } from './components/TextNoBorder' -import { useUserInfo } from './hooks/useUserInfo' -import { useUserSubscriptions } from './hooks/useUserSubscriptions' + +import { SubscriptionModal } from './components/SubscriptionsModal' +import { SubscriptionsForm } from './components/SubscriptionsForm' import { FormWrapper, OutlinedButton, UserAccountWrapper, UserAccountFormWrapper, - UserAccountBlockTitle, UserAccountComponentWrapper, ButtonWrapper, + UserAccountBlockTitle, } from './styled' const labelWidth = 110 @@ -35,8 +35,6 @@ const labelWidth = 110 export const UserAccount = () => { useLexicsConfig(userAccountLexics) - const { translate } = useLexicsStore() - const { cities, countries, @@ -51,18 +49,31 @@ export const UserAccount = () => { updateFormValue, } = useUserInfo() - const subscriptions = useUserSubscriptions() + const { + close, + deleteUserSubscription, + isOpen, + open, + saveSubscription, + selectedSubscription, + selectedSubscriptionLexic, + setSelectedSubscription, + sportList, + userSubscriptions, + } = useUserSubscriptions() + + const { + subscriptions, + } = useSubscriptions() return ( - + - - - + { - - - + - +
- - - - - {map(subscriptions, (subscription) => ( - - ))} - -
+ + {/* Select subscription modal */} + +
) } diff --git a/src/features/UserAccount/styled.tsx b/src/features/UserAccount/styled.tsx index ddf7e799..48234dd6 100644 --- a/src/features/UserAccount/styled.tsx +++ b/src/features/UserAccount/styled.tsx @@ -1,7 +1,8 @@ import styled from 'styled-components/macro' -import { BlockTitle, Form } from 'features/Login/styled' +import { Form, BlockTitle } from 'features/Login/styled' import { outlineButtonStyles } from 'features/Common/Button' +import { customScrollbar, customStylesMixin } from 'features/Common' export const OutlinedButton = styled.button` ${outlineButtonStyles}; @@ -18,6 +19,10 @@ export const OutlinedButton = styled.button` } ` +export const UserAccountBlockTitle = styled(BlockTitle)` + align-self: flex-start; +` + export const UserAccountFormWrapper = styled.div` display: flex; justify-content: center; @@ -36,10 +41,6 @@ export const UserAccountWrapper = styled.div` margin-top: 140px; ` -export const UserAccountBlockTitle = styled(BlockTitle)` - align-self: flex-start; -` - export const UserAccountComponentWrapper = styled.div`` export const FormWrapper = styled.div` @@ -53,3 +54,42 @@ export const FormWrapper = styled.div` margin-right: 0; } ` + +export const AddSubscriptionModal = styled.div` + width: 538px; + height: 452px; + display: flex; + flex-direction: column; + align-items: center; +` + +export const ModalTitle = styled.p` + font-size: 24px; + font-weight: normal; +` + +export const Line = styled.hr` + position:absolute; + width: 100%; + top: 40px; + height: 1px; + border: 1px solid #3F3F3F; +` + +export const SaveButton = styled(OutlinedButton)` + width: 192px; + height: 36px; + display: block; + font-weight: normal; + margin-left: auto; + margin-top: auto; +` + +export const SubscriptionsWrapper = styled.div` + margin-top: 45px; + width: 100%; + height: 100%; + overflow: auto; + ${customScrollbar} + ${customStylesMixin} +` diff --git a/src/requests/getSubscriptions.tsx b/src/requests/getSubscriptions.tsx new file mode 100644 index 00000000..20adf742 --- /dev/null +++ b/src/requests/getSubscriptions.tsx @@ -0,0 +1,34 @@ +import { + DATA_URL, + PROCEDURES, +} from 'config' +import { callApi } from 'helpers' + +const proc = PROCEDURES.get_subscriptions + +type Tournament = { + id: number, + name_eng: string, + name_rus: string, + sport: number, +} + +export type SubscriptionType = { + id: number, + lexic: number, + tournaments: Array, +} + +export const getSubscriptions = (): Promise> => { + const config = { + body: { + params: {}, + proc, + }, + } + + return callApi({ + config, + url: DATA_URL, + }) +} diff --git a/src/requests/saveUserCustomSubscription.tsx b/src/requests/saveUserCustomSubscription.tsx index 46c8bbcc..f3b34186 100644 --- a/src/requests/saveUserCustomSubscription.tsx +++ b/src/requests/saveUserCustomSubscription.tsx @@ -1,31 +1,48 @@ import { DATA_URL, PROCEDURES, + ProfileTypes, + SportTypes, } from 'config' import { callApi } from 'helpers' const proc = PROCEDURES.save_user_custom_subscription +export enum SubscriptionAction { + ADD = 1, + REMOVE = 2, +} + type Response = { _p_error: string | null, _p_status: 1 | 2, } +type Args = { + action: SubscriptionAction, + id: number, + sport: SportTypes, + type: ProfileTypes, +} + const responseStatus = { FAILURE: 2, SUCCESS: 1, } -export const saveUserCustomSubscription = async () => { +export const saveUserCustomSubscription = async ({ + action, + id, + sport, + type, +} : Args) => { const config = { body: { params: { - _p_action: 1, - _p_id: 1, - _p_sport: 1, - _p_status: 1, - _p_type: 1, - _p_user_id: 1, + _p_action: action, + _p_id: id, + _p_sport: sport, + _p_type: type, }, proc, }, @@ -37,7 +54,7 @@ export const saveUserCustomSubscription = async () => { }) if (response._p_status === responseStatus.SUCCESS) { - return Promise.resolve(response) + return Promise.resolve() } return Promise.reject(response._p_error) } diff --git a/src/requests/saveUserSubscription.tsx b/src/requests/saveUserSubscription.tsx index c4d8a031..a65696c3 100644 --- a/src/requests/saveUserSubscription.tsx +++ b/src/requests/saveUserSubscription.tsx @@ -6,10 +6,6 @@ import { callApi } from 'helpers' const proc = PROCEDURES.save_user_subscription -type Type = { - subscriptionId: number, -} - type Response = { _p_error: string | null, _p_status: 1 | 2, @@ -20,11 +16,11 @@ const responseStatus = { SUCCESS: 1, } -export const saveUserSubscription = async ({ subscriptionId }: Type) => { +export const saveUserSubscription = async (subscriptionId : number | null) => { const config = { body: { params: { - p_subscription_id: subscriptionId, + _p_subscription_id: subscriptionId, }, proc, }, @@ -36,7 +32,7 @@ export const saveUserSubscription = async ({ subscriptionId }: Type) => { }) if (response._p_status === responseStatus.SUCCESS) { - return Promise.resolve(response) + return Promise.resolve() } return Promise.reject(response._p_error) }