Merge pull request #10 from instat/OTT-37-registration-layout

keep-around/af30b88d367751c9e05a735e4a0467a96238ef47
Andrey Razdorskiy 6 years ago committed by GitHub
commit 09568e1b65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      package.json
  2. 1
      src/config/pages.tsx
  3. 34
      src/features/App/index.tsx
  4. 5
      src/features/Background/styled.tsx
  5. 9
      src/features/Common/Arrows/index.tsx
  6. 5
      src/features/Common/Button/styled.tsx
  7. 2
      src/features/Common/Checkbox/styled.tsx
  8. 2
      src/features/Common/Radio/index.tsx
  9. 1
      src/features/Common/Radio/styled.tsx
  10. 8
      src/features/Login/index.tsx
  11. 22
      src/features/Login/styled.tsx
  12. 27
      src/features/Register/AdditionalSubscription/index.tsx
  13. 29
      src/features/Register/AdditionalSubscription/styled.tsx
  14. 27
      src/features/Register/MainSubscription/index.tsx
  15. 24
      src/features/Register/Price/index.tsx
  16. 24
      src/features/Register/Price/styled.tsx
  17. 48
      src/features/Register/Steps/Card/index.tsx
  18. 57
      src/features/Register/Steps/Registration/index.tsx
  19. 57
      src/features/Register/Steps/Subscriptions/index.tsx
  20. 97
      src/features/Register/Steps/Subscriptions/styled.tsx
  21. 3
      src/features/Register/Steps/index.tsx
  22. 31
      src/features/Register/index.tsx
  23. 34
      src/features/Register/styled.tsx

@ -13,9 +13,12 @@
"build-storybook": "build-storybook -s public"
},
"dependencies": {
"history": "^4.10.1",
"lodash": "^4.17.15",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"styled-components": "^5.1.1"
},
@ -32,11 +35,14 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@types/history": "^4.7.6",
"@types/jest": "^24.0.0",
"@types/lodash": "^4.14.154",
"@types/node": "^12.0.0",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/react-router": "^5.1.7",
"@types/react-router-dom": "^5.1.5",
"@types/styled-components": "^5.1.0",
"commitizen": "^4.1.2",
"eslint": "6.8.0",

@ -1,3 +1,4 @@
export const PAGES = {
login: '/login',
register: '/register',
}

@ -1,12 +1,36 @@
import React from 'react'
import {
Router,
Route,
Redirect,
Switch,
} from 'react-router-dom'
import { createBrowserHistory } from 'history'
import { PAGES } from 'config'
import { GlobalStyles } from 'features/GlobalStyles'
import { Theme } from 'features/Theme'
import { Login } from 'features/Login'
import { GlobalStyles } from 'features/GlobalStyles'
import { Register } from 'features/Register'
const history = createBrowserHistory()
export const App = () => (
<Theme>
<GlobalStyles />
<Login />
</Theme>
<Router history={history}>
<Theme>
<GlobalStyles />
<Switch>
<Route path={PAGES.login}>
<Login />
</Route>
<Route path={PAGES.register}>
<Register />
</Route>
<Redirect to={PAGES.login} />
</Switch>
</Theme>
</Router>
)

@ -1,8 +1,8 @@
import styled from 'styled-components/macro'
const Container = styled.div`
width: 100vw;
height: 100vh;
width: 100%;
min-height: 100vh;
`
export const ImageBackground = styled(Container)`
@ -21,5 +21,4 @@ export const CenterBlock = styled.div`
display: flex;
flex-direction: column;
align-items: center;
margin-top: 140px;
`

@ -9,6 +9,9 @@ const ArrowStyled = styled.button`
background-color: transparent;
background-position: center;
outline: none;
z-index: 1;
position: absolute;
cursor: pointer;
:active {
background-color: rgba(117, 117, 117, 1);
@ -21,8 +24,14 @@ const ArrowStyled = styled.button`
export const ArrowLeft = styled(ArrowStyled)`
background-image: url(/images/arrowLeft.svg);
top: 50%;
left: 0px;
transform: translate(-10px, -50%);
`
export const ArrowRight = styled(ArrowStyled)`
background-image: url(/images/arrowRight.svg);
top: 50%;
right: 0px;
transform: translate(10px, -50%);
`

@ -27,10 +27,9 @@ export const outlineButtonStyles = css`
export const solidButtonStyles = css`
${baseButtonStyles}
padding-top: 18.5px;
padding-bottom: 13px;
color: #FFFFFF;
color: #fff;
font-weight: bold;
cursor: pointer;
border-color: transparent;
background: ${({ theme: { colors } }) => colors.primary};
`

@ -1,7 +1,6 @@
import styled from 'styled-components/macro'
export const Wrapper = styled.div`
`
export const Label = styled.label`
@ -32,6 +31,7 @@ export const Input = styled.input`
background-repeat: no-repeat;
background-position: center center;
background-image: url(/images/checkboxUnchecked.svg);
cursor: pointer;
}
&:checked+${Label}::before {

@ -19,7 +19,7 @@ type TCheckbox = Pick<InputHTMLAttributes<HTMLInputElement>, (
export const Radio = ({
checked,
id,
label,
label = '',
name,
onChange,
value,

@ -32,6 +32,7 @@ export const Input = styled.input`
background-repeat: no-repeat;
background-position: center center;
background-image: url(/images/radioUnchecked.svg);
cursor: pointer;
}
&:checked+${Label}::before {

@ -1,11 +1,12 @@
import React from 'react'
import { PAGES } from 'config'
import { Background } from 'features/Background'
import { Logo } from 'features/Logo'
import {
Input,
ButtonSolid,
ButtonOutline,
} from 'features/Common'
import {
@ -13,6 +14,7 @@ import {
CenterBlock,
ButtonsBlock,
Form,
RegisterButton,
} from './styled'
const labelWidth = 60
@ -41,9 +43,9 @@ export const Login = () => (
<ButtonsBlock>
<ButtonSolid>Войти</ButtonSolid>
<ButtonOutline type='button'>
<RegisterButton to={PAGES.register}>
Зарегистрироваться
</ButtonOutline>
</RegisterButton>
</ButtonsBlock>
</Form>
</CenterBlock>

@ -1,15 +1,19 @@
import { Link } from 'react-router-dom'
import styled from 'styled-components/macro'
import { outlineButtonStyles } from 'features/Common'
export const CenterBlock = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
margin-top: 140px;
`
export const Form = styled.form`
width: 544px;
margin-top: 80px;
margin: 80px 0 140px 0;
display: flex;
flex-direction: column;
align-items: center;
@ -26,12 +30,18 @@ export const BlockTitle = styled.span`
transition: color 0.3s ease-in-out;
`
export const ButtonsBlock = styled.div`
export const ButtonsBlock = styled.div<{forSubsPage?: boolean}>`
display: flex;
flex-direction: column;
margin-top: 60px;
margin-top: ${({ forSubsPage }) => (forSubsPage ? '80px' : '60px')};
margin-bottom: ${({ forSubsPage }) => (forSubsPage ? '96px' : '')};
position: relative;
`
& > * {
margin-bottom: 40px;
}
export const RegisterButton = styled(Link)`
${outlineButtonStyles}
margin-top: 40px;
display: flex;
align-items: center;
justify-content: center;
`

@ -0,0 +1,27 @@
import React from 'react'
import { Checkbox } from 'features/Common'
import { Price } from '../Price'
import {
PriceItemTitle,
PriceItem,
PriceItemCol,
} from './styled'
type TAdditionalSubscription = {
price: number,
title: string,
}
export const AdditionalSubscription = ({ price, title }: TAdditionalSubscription) => (
<PriceItem>
<PriceItemCol>
<Checkbox name='additionalSubscription' id={title} />
</PriceItemCol>
<PriceItemCol>
<PriceItemTitle>{title}</PriceItemTitle>
<Price amount={price} />
</PriceItemCol>
</PriceItem>
)

@ -0,0 +1,29 @@
import styled from 'styled-components/macro'
export const PriceItem = styled.div`
position: relative;
width: 288px;
height: 176px;
padding: 24px 25px 40px;
margin: 0;
display: flex;
flex-direction: row;
background: #3F3F3F;
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.4);
border-radius: 2px;
`
export const PriceItemTitle = styled.span`
font-style: normal;
font-weight: bold;
font-size: 18px;
line-height: 24px;
color: ${({ theme: { colors } }) => colors.text};
margin: 3px 5px 0 0;
`
export const PriceItemCol = styled.div`
display: flex;
flex-direction: column;
justify-content: space-between;
`

@ -0,0 +1,27 @@
import React from 'react'
import { Radio } from 'features/Common'
import { Price } from '../Price'
import {
SubscriptionWrapper,
SubscriptionTitle,
Row,
} from '../Steps/Subscriptions/styled'
type TMainSubscription = {
price: number,
title: string,
}
export const MainSubscription = ({ price, title }: TMainSubscription) => (
<SubscriptionWrapper>
<Row>
<Radio name='mainSubscription' id={title} />
<SubscriptionTitle>{title}</SubscriptionTitle>
</Row>
<Row left={70} bottom={100}>
<Price amount={price} />
</Row>
</SubscriptionWrapper>
)

@ -0,0 +1,24 @@
import React from 'react'
import {
PriceWrapper,
PriceAmount,
PriceDetails,
} from './styled'
type TPrice = {
amount: number,
currency?: string,
perPeriod?: string,
}
export const Price = ({
amount,
currency = '₽',
perPeriod = 'мес',
}: TPrice) => (
<PriceWrapper>
<PriceAmount>{amount}</PriceAmount>
<PriceDetails>{currency} / {perPeriod}</PriceDetails>
</PriceWrapper>
)

@ -0,0 +1,24 @@
import styled from 'styled-components/macro'
export const PriceWrapper = styled.div`
display: flex;
align-items: flex-start;
`
export const PriceAmount = styled.span`
font-style: normal;
font-weight: 600;
font-size: 48px;
line-height: 40px;
color: ${({ theme: { colors } }) => colors.text};
`
export const PriceDetails = styled.span`
margin-left: 5px;
font-style: normal;
font-weight: normal;
font-size: 18px;
line-height: 21px;
color: ${({ theme: { colors } }) => colors.text};
text-transform: uppercase;
`

@ -0,0 +1,48 @@
import React from 'react'
import { Input } from 'features/Common'
import {
BlockTitle,
ButtonsBlock,
Form,
} from 'features/Login/styled'
import {
NextButton,
Card,
Row,
} from '../../styled'
export const CardStep = () => (
<Form>
<BlockTitle>Привязка карты</BlockTitle>
<Card>
<Input
id='cardNumber'
label='Номер карты'
paddingX={21}
/>
<Row>
<Input
id='expiration'
label='Срок действия'
wrapperWidth={280}
inputWidth={85}
paddingX={21}
/>
<Input
id='code'
label='CVC / CVV'
wrapperWidth={184}
inputWidth={30}
maxLength={3}
paddingX={18.6}
/>
</Row>
</Card>
<ButtonsBlock>
<NextButton to='subscriptions'>Далее</NextButton>
</ButtonsBlock>
</Form>
)

@ -0,0 +1,57 @@
import React from 'react'
import { PAGES } from 'config'
import { Input } from 'features/Common'
import {
BlockTitle,
ButtonsBlock,
Form,
} from 'features/Login/styled'
import { NextButton } from '../../styled'
const labelWidth = 78
export const Registration = () => (
<Form>
<BlockTitle>Регистрация</BlockTitle>
<Input
id='firstname'
label='Имя'
labelWidth={labelWidth}
/>
<Input
id='lastname'
label='Фамилия'
labelWidth={labelWidth}
/>
<Input
id='phone'
label='Телефон'
labelWidth={labelWidth}
/>
<Input
id='email'
type='email'
label='E-mail'
labelWidth={labelWidth}
/>
{/* TODO: it should be Dropdown */}
<Input
id='country'
label='Страна'
labelWidth={labelWidth}
/>
<Input
id='address'
label='Адрес'
labelWidth={labelWidth}
/>
<ButtonsBlock>
<NextButton to={`${PAGES.register}/card`}>Далее</NextButton>
</ButtonsBlock>
</Form>
)

@ -0,0 +1,57 @@
import React, { Fragment } from 'react'
import { ButtonSolid } from 'features/Common/Button'
import { ArrowLeft, ArrowRight } from 'features/Common/Arrows'
import { ButtonsBlock } from 'features/Login/styled'
import { MainSubscription } from 'features/Register/MainSubscription'
import { AdditionalSubscription } from 'features/Register/AdditionalSubscription'
import {
SubscriptionsBlock,
AdditionalBlockTitle,
BlockTitle,
SubscriptionList,
SubscriptionListItem,
PricesBlock,
TotalInfoBlock,
TotalInfoText,
TotalPriceAmmount,
TotalPriceDetails,
} from './styled'
export const SubscriptionStep = () => (
<Fragment>
<SubscriptionsBlock>
<BlockTitle>Выбор подписки</BlockTitle>
<SubscriptionList>
<SubscriptionListItem>
<MainSubscription title='Бесплатная' price={0} />
</SubscriptionListItem>
<SubscriptionListItem>
<MainSubscription title='Базовая' price={1999} />
</SubscriptionListItem>
</SubscriptionList>
</SubscriptionsBlock>
<SubscriptionsBlock forAdditionalTitle>
<AdditionalBlockTitle>Дополнительно</AdditionalBlockTitle>
<PricesBlock>
<ArrowLeft />
<AdditionalSubscription title='Российская премьер-лига' price={1999} />
<AdditionalSubscription title='Primera División' price={1999} />
<AdditionalSubscription title='Manchester United' price={999} />
<AdditionalSubscription title='Василий Березуцкий' price={299} />
<ArrowRight />
</PricesBlock>
</SubscriptionsBlock>
<ButtonsBlock forSubsPage>
<ButtonSolid>Готово</ButtonSolid>
<TotalInfoBlock>
<TotalInfoText>Базовая + 2 дополнительно за
<TotalPriceAmmount>6997</TotalPriceAmmount>
<TotalPriceDetails> / МЕС</TotalPriceDetails>
</TotalInfoText>
</TotalInfoBlock>
</ButtonsBlock>
</Fragment>
)

@ -0,0 +1,97 @@
import styled from 'styled-components/macro'
export const SubscriptionsBlock = styled.div<{forAdditionalTitle?: boolean}>`
display: flex;
flex-direction: column;
align-items: center;
margin-top: ${({ forAdditionalTitle }) => (forAdditionalTitle ? '75px' : '80px')};
`
export const BlockTitle = styled.span`
display: block;
font-style: normal;
font-weight: bold;
font-size: 36px;
line-height: 24px;
color: ${({ theme: { colors } }) => colors.text};
transition: color 0.3s ease-in-out;
`
export const AdditionalBlockTitle = styled(BlockTitle)`
font-size: 32px;
margin-bottom: 40px;
`
export const SubscriptionList = styled.ul`
display: flex;
margin-top: 40px;
`
export const SubscriptionListItem = styled.li``
export const SubscriptionWrapper = styled.div`
position: relative;
width: 288px;
height: 216px;
padding: 24px;
margin: 0 8px;
display: flex;
flex-direction: column;
background: #3F3F3F;
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.4);
border-radius: 2px;
`
export const SubscriptionTitle = styled.span`
font-style: normal;
font-weight: bold;
font-size: 18px;
line-height: 21px;
color: ${({ theme: { colors } }) => colors.text};
`
type TRow = {
bottom?: number,
left?: number,
}
export const Row = styled.div<TRow>`
position: absolute;
display: flex;
align-items: center;
left: ${({ left }) => left}px;
bottom: ${({ bottom }) => bottom}px;
`
export const PricesBlock = styled.div`
width: 1200px;
display: flex;
justify-content: space-between;
position: relative;
`
export const TotalInfoBlock = styled.div`
width: 201px;
position: absolute;
display: flex;
flex-wrap: wrap;
top: 4px;
left: 294px;
`
export const TotalInfoText = styled.span`
font-weight: normal;
font-size: 14px;
line-height: 22px;
color: rgba(255, 255, 255, 0.3);
`
export const TotalPriceAmmount = styled(TotalInfoText)`
font-weight: bold;
margin-left: 6px;
`
export const TotalPriceDetails = styled(TotalInfoText)`
text-transform: uppercase;
margin-left: 7px;
`

@ -0,0 +1,3 @@
export * from './Registration'
export * from './Card'
export * from './Subscriptions'

@ -0,0 +1,31 @@
import React from 'react'
import { Route } from 'react-router'
import { PAGES } from 'config'
import { Background } from 'features/Background'
import { Logo } from 'features/Logo'
import { CenterBlock } from 'features/Login/styled'
import {
Registration,
CardStep,
SubscriptionStep,
} from './Steps'
export const Register = () => (
<Background>
<CenterBlock>
<Logo />
<Route exact path={`${PAGES.register}`}>
<Registration />
</Route>
<Route exact path={`${PAGES.register}/card`}>
<CardStep />
</Route>
<Route exact path={`${PAGES.register}/subscriptions`}>
<SubscriptionStep />
</Route>
</CenterBlock>
</Background>
)

@ -0,0 +1,34 @@
import { Link } from 'react-router-dom'
import styled from 'styled-components/macro'
import { solidButtonStyles } from 'features/Common'
export const NextButton = styled(Link)`
${solidButtonStyles}
display: flex;
align-items: center;
justify-content: center;
`
export const Card = styled.div`
width: 546px;
height: 340px;
margin: 20px 0;
padding: 0 32px;
border: 1px solid rgba(255, 255, 255, 0.1);
box-sizing: border-box;
border-radius: 16px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`
export const Row = styled.div`
width: 100%;
display: flex;
& div:last-child {
margin-left: 16px;
}
`
Loading…
Cancel
Save