feat: activate
This commit is contained in:
parent
06358334c4
commit
abc53d3eef
@ -4,6 +4,7 @@ import { BreakpointProvider } from './components/Breakpoint'
|
||||
import { Layout } from './components/Layout'
|
||||
import { Home } from './pages/activation/home'
|
||||
import { Login } from './pages/activation/login'
|
||||
import { Activate } from './pages/activation/activate'
|
||||
|
||||
function App() {
|
||||
return (
|
||||
@ -12,6 +13,7 @@ function App() {
|
||||
<Route path="/" element={<Layout />}>
|
||||
<Route index element={<Home />} />
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route path="/activate" element={<Activate />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</BreakpointProvider>
|
||||
|
19
src/components/Typography/Text.tsx
Normal file
19
src/components/Typography/Text.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import React, { FC, ComponentProps } from 'react'
|
||||
import { Typography, TypographyProps } from 'antd'
|
||||
import styled from 'styled-components'
|
||||
|
||||
type TextProps = ComponentProps<TypographyProps['Text']> & {
|
||||
primary?: boolean
|
||||
inherit?: boolean
|
||||
}
|
||||
|
||||
const StyledText = styled(Typography.Text)<{
|
||||
$inherit?: boolean
|
||||
$primary?: boolean
|
||||
}>`
|
||||
${({ $inherit }) => $inherit ? 'font-size: inherit;line-height:inherit;' : ''}
|
||||
${({ $primary, theme }) => $primary ? `color: ${theme.brandPrimary}` : ''}
|
||||
`
|
||||
export const Text: FC<TextProps> = ({ primary, inherit, ...props }) => {
|
||||
return <StyledText {...props} $primary={primary} $inherit={inherit} />
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import { Typography } from 'antd'
|
||||
|
||||
const { Text, Title, Link } = Typography
|
||||
const { Title, Link } = Typography
|
||||
export * from './Paragraph'
|
||||
export * from './ButtonText'
|
||||
export * from './TinyText'
|
||||
export { Text, Title, Link }
|
||||
export * from './Text'
|
||||
export { Title, Link }
|
||||
|
||||
|
85
src/pages/activation/activate/Activate.tsx
Normal file
85
src/pages/activation/activate/Activate.tsx
Normal file
@ -0,0 +1,85 @@
|
||||
import React, { FC, useState } from 'react'
|
||||
import {
|
||||
StyledContainer,
|
||||
StyledImageWrapper,
|
||||
StyledMainContent,
|
||||
StyledHeadline,
|
||||
StyledContent,
|
||||
StyledButton,
|
||||
StyledParagraph, StyledHint, StyledFormContent,
|
||||
} from './styled'
|
||||
import { Form } from 'antd'
|
||||
import { Paragraph, Link, Text } from '../../../components/Typography'
|
||||
import { Input, ErrorMessage } from '../../../components/FormControl'
|
||||
import { ActivateGuide } from './ActivateGuide'
|
||||
|
||||
export const Activate: FC = () => {
|
||||
const [logined] = useState(true)
|
||||
const [showModal, setModal] = useState(false)
|
||||
const handleShowModal = () => {
|
||||
setModal(true)
|
||||
}
|
||||
|
||||
const handleCloseModal = () => {
|
||||
setModal(false)
|
||||
}
|
||||
const onFinish = (values: any) => {
|
||||
// TODO: login
|
||||
console.log('Success:', values);
|
||||
};
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledImageWrapper />
|
||||
<StyledMainContent>
|
||||
<StyledContent>
|
||||
{logined ? (
|
||||
<StyledHeadline level={1} $login={logined}>
|
||||
Hello, <Text inherit primary>John</Text>
|
||||
<br />
|
||||
Welcome to your kit activation.
|
||||
</StyledHeadline>
|
||||
) : (
|
||||
<StyledHeadline level={1} $login={logined}>
|
||||
Welcome to your kit <Text inherit primary>activation</Text>.
|
||||
</StyledHeadline>
|
||||
)}
|
||||
<StyledParagraph>Your kit needs to be activated before the lab can process your sample.</StyledParagraph>
|
||||
<StyledFormContent>
|
||||
<Form
|
||||
layout="vertical"
|
||||
onFinish={onFinish}
|
||||
>
|
||||
<Form.Item
|
||||
label="Activation Code"
|
||||
name="code"
|
||||
rules={[
|
||||
{
|
||||
required: true, message: <ErrorMessage message="Please input your activation code" />
|
||||
},
|
||||
// Activation code not found
|
||||
]}
|
||||
>
|
||||
<Input placeholder="xxxx-xxxx-xxxx" />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<StyledButton block htmlType="submit">Next</StyledButton>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
<StyledHint>
|
||||
<Paragraph>
|
||||
{!logined ?
|
||||
<>
|
||||
Already have an account?
|
||||
<Link href="/login">Log in</Link>
|
||||
<br />
|
||||
</> : null}
|
||||
<Link onClick={handleShowModal}>Can’t find your activation code?</Link>
|
||||
</Paragraph>
|
||||
</StyledHint>
|
||||
</StyledFormContent>
|
||||
</StyledContent>
|
||||
</StyledMainContent>
|
||||
<ActivateGuide open={showModal} onClose={handleCloseModal} />
|
||||
</StyledContainer>
|
||||
)
|
||||
}
|
56
src/pages/activation/activate/ActivateGuide.tsx
Normal file
56
src/pages/activation/activate/ActivateGuide.tsx
Normal file
@ -0,0 +1,56 @@
|
||||
import React, { FC } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import { Modal, ModalProps } from '../../../components/Modal'
|
||||
import { Title, Text, Paragraph } from '../../../components/Typography'
|
||||
|
||||
type Props = Pick<ModalProps, 'open'> & {
|
||||
onClose?: () => void
|
||||
}
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
min-height: 366px;
|
||||
|
||||
${props => props.theme.breakpoints.up('s')} {
|
||||
justify-content: center;
|
||||
}
|
||||
`
|
||||
const StyledMain = styled.div`
|
||||
width: 100%;
|
||||
|
||||
${props => props.theme.breakpoints.up('s')} {
|
||||
width: 400px;
|
||||
padding-top: 16px;
|
||||
}
|
||||
|
||||
${props => props.theme.breakpoints.down('s')} {
|
||||
padding-top: 33px;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
}
|
||||
`
|
||||
const StyledTitle = styled(Title)`
|
||||
margin-bottom: 3px !important;
|
||||
|
||||
${props => props.theme.breakpoints.down('s')} {
|
||||
margin-bottom: 27px !important;
|
||||
}
|
||||
`
|
||||
export const ActivateGuide: FC<Props> = ({ onClose, ...props }) => {
|
||||
const handleClose = () => {
|
||||
onClose && onClose()
|
||||
}
|
||||
return (
|
||||
<Modal {...props} width={688} destroyOnClose onCancel={handleClose}>
|
||||
<StyledWrapper>
|
||||
<StyledMain>
|
||||
<StyledTitle>Can’t find your <Text inherit primary>activation code</Text>?</StyledTitle>
|
||||
<Paragraph level={2}>The activation code is located on the Kit ID Card in your home collection
|
||||
kit.</Paragraph>
|
||||
</StyledMain>
|
||||
</StyledWrapper>
|
||||
</Modal>
|
||||
)
|
||||
}
|
BIN
src/pages/activation/activate/images/activate@2x.png
Normal file
BIN
src/pages/activation/activate/images/activate@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 978 KiB |
BIN
src/pages/activation/activate/images/activateMobile@2x.png
Normal file
BIN
src/pages/activation/activate/images/activateMobile@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 273 KiB |
1
src/pages/activation/activate/index.ts
Normal file
1
src/pages/activation/activate/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './Activate'
|
85
src/pages/activation/activate/styled.tsx
Normal file
85
src/pages/activation/activate/styled.tsx
Normal file
@ -0,0 +1,85 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import Image from './images/activate@2x.png'
|
||||
import ImageMobile from './images/activateMobile@2x.png'
|
||||
import { Title, Paragraph } from '../../../components/Typography'
|
||||
import { Button } from '../../../components/Button'
|
||||
|
||||
export const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 25px 0 25px 40px;
|
||||
|
||||
${props => props.theme.breakpoints.down('s')} {
|
||||
padding: 12px 16px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
`
|
||||
export const StyledImageWrapper = styled.div`
|
||||
width: 54%;
|
||||
max-width: 737px;
|
||||
height: 809px;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-image: url(${Image});
|
||||
flex: 0 0 auto;
|
||||
|
||||
${props => props.theme.breakpoints.down('s')} {
|
||||
background-image: url(${ImageMobile});
|
||||
max-width: 358px;
|
||||
width: 100%;
|
||||
height: 232px;
|
||||
}
|
||||
`
|
||||
|
||||
export const StyledMainContent = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
flex: auto;
|
||||
|
||||
${props => props.theme.breakpoints.down('s')} {
|
||||
width: 100%;
|
||||
padding-top: 20px;
|
||||
}
|
||||
`
|
||||
|
||||
export const StyledHeadline = styled(Title)<{$login: boolean}>`
|
||||
margin-bottom: ${({ $login }) => $login ? '0' : '37'}px !important;
|
||||
font-size: 36px;
|
||||
|
||||
${props => props.theme.breakpoints.down('s')} {
|
||||
margin-bottom: 1px !important;
|
||||
}
|
||||
`
|
||||
export const StyledParagraph = styled(Paragraph)`
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
`
|
||||
export const StyledContent = styled.div`
|
||||
width: 388px;
|
||||
|
||||
${props => props.theme.breakpoints.down('s')} {
|
||||
width: 100%;
|
||||
}
|
||||
`
|
||||
|
||||
export const StyledFormContent = styled.div`
|
||||
margin-top: 26px;
|
||||
`
|
||||
|
||||
export const StyledButton = styled(Button)`
|
||||
margin-top: 15px;
|
||||
`
|
||||
|
||||
|
||||
export const StyledHint = styled.div`
|
||||
text-align: center;
|
||||
margin-top: 33px;
|
||||
${props => props.theme.breakpoints.down('s')} {
|
||||
margin-top: 18px;
|
||||
}
|
||||
`
|
@ -30,7 +30,7 @@ export const Login: FC = () => {
|
||||
<StyledContainer>
|
||||
<StyledImageWrapper />
|
||||
<StyledMainContent>
|
||||
<StyledHeadline level={1} style={{ fontSize: 36 }}>Welcome Back!</StyledHeadline>
|
||||
<StyledHeadline level={1}>Welcome Back!</StyledHeadline>
|
||||
<StyledTitle level={3}>Log in to continue</StyledTitle>
|
||||
<StyledContent>
|
||||
<Form
|
||||
|
Loading…
Reference in New Issue
Block a user