Skip to content

Commit

Permalink
feat: new signup page
Browse files Browse the repository at this point in the history
  • Loading branch information
aswathy-deriv committed Feb 16, 2024
1 parent 640340a commit 2cf7ff5
Show file tree
Hide file tree
Showing 18 changed files with 989 additions and 49 deletions.
66 changes: 17 additions & 49 deletions crowdin/messages.json

Large diffs are not rendered by default.

134 changes: 134 additions & 0 deletions src/features/pages/signup-academy-complete/academy-input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React, { useRef, useState } from 'react'
import styled, { css } from 'styled-components'
import device from 'themes/device'
import {
InputProps,
InputWrapper,
RelativeWrapper,
StyledInput,
StyledLabel,
} from 'components/form/input'
import OpenedEye from 'images/svg/signup-affiliates/opened-eye.svg'
import ClosedEye from 'images/svg/eye.svg'

type AcademyPasswordInputProps = {
password_icon?: boolean
} & InputProps

export const StyledRelativeWrapper = styled(RelativeWrapper)`
margin-block: 16px 36px;
`
export const ErrorMessage = styled.div<{ error?: boolean }>`
position: absolute;
font-size: 12px;
color: ${({ error }) => (error ? 'var(--color-red-1)' : 'var(--color-grey-5)')};
padding: 6px 0;
`
const StyledIcon = styled.img<{ password_icon?: boolean }>`
position: absolute;
right: ${({ password_icon }) => (password_icon ? '2.8rem' : '0.8rem')};
top: 1.5rem;
height: 1rem;
width: 1.5rem;
cursor: pointer;
@media ${device.tablet} {
right: ${({ password_icon }) => (password_icon ? '4rem' : '2rem')};
top: 1.6rem;
}
@media ${device.desktopL} {
top: 1rem;
}
`
export const Label = styled(StyledLabel)`
top: 1.5rem;
color: var(--color-grey-5);
`
export const StyledInputWrapper = styled(InputWrapper)<{
password_length?: number
is_password?: boolean
}>`
border-radius: 4px;
border: solid 1px var(--color-grey-7);
${({ password_length, is_password }) => {
if (is_password && password_length == 0)
return css`
border-bottom: solid 4px var(--color-grey-5);
`
else if (is_password && password_length >= 1)
return css`
border-bottom: solid 4px var(--color-blue-7);
&:hover {
border-color: var(--color-blue-7);
}
`
else
return css`
border-bottom: solid 1px var(--color-grey-7);
&:hover {
border-color: var(--color-grey-5);
& > label {
color: var(--color-grey-5);
}
}
`
}}
@media ${device.tabletL} {
height: unset;
border-radius: 4px;
}
`

const AcademyPasswordInput = ({
label = '',
id = '',
error = '',
password_icon,
...props
}: AcademyPasswordInputProps) => {
const current_input = useRef(null)
const [is_password_visible, setPasswordVisible] = useState(false)

return (
<StyledRelativeWrapper>
<StyledInputWrapper
error={error}
is_password={props.type === 'password'}
password_length={props.type === 'password' && props.value.length}
>
<StyledInput
{...props}
id={id}
width={500}
error={error}
showLabel={label}
background="white"
ref={current_input}
type={is_password_visible ? 'text' : props.type}
/>
{label && (
<Label error={error} htmlFor={id}>
{label}
</Label>
)}
</StyledInputWrapper>
{password_icon && (
<StyledIcon
src={is_password_visible ? ClosedEye : OpenedEye}
password_icon={password_icon}
alt="eye icon"
onClick={() => setPasswordVisible(!is_password_visible)}
/>
)}
{error && (
<>
<ErrorMessage error>{error}</ErrorMessage>
</>
)}
</StyledRelativeWrapper>
)
}

export default AcademyPasswordInput
26 changes: 26 additions & 0 deletions src/features/pages/signup-academy-complete/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react'
import { signup_wrapper, static_nav_logo } from '../signup-academy/signup.module.scss'
import Layout from 'features/components/templates/layout'
import PopUpMenu from './pop-up-menu'
import NavTemplate from 'features/components/templates/navigation/template'
import LogoImage from 'images/common/deriv-academy.svg'
import Link from 'features/components/atoms/link'
import Image from 'features/components/atoms/image'

const SignupCompleteAcademy = () => {
return (
<Layout>
<NavTemplate
has_centered_items
has_centered_logo
renderLogo={() => (
<Link url={{ type: 'internal', to: '/' }}>
<Image src={LogoImage} className={static_nav_logo} />
</Link>
)}
/>
<PopUpMenu />
</Layout>
)
}
export default SignupCompleteAcademy
103 changes: 103 additions & 0 deletions src/features/pages/signup-academy-complete/password-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import React, { useState } from 'react'
import styled from 'styled-components'
import { navigate } from 'gatsby'
import { trading_btn, signup_form_line, input_field } from './signup-academy.module.scss'
import AcademyInput from './academy-input'
import { academy_validation } from './password-validation'
import Flex from 'features/components/atoms/flex-box'
import Typography from 'features/components/atoms/typography'
import { Localize, localize } from 'components/localization'
import { Button } from 'components/form'
import apiManager from 'common/websocket'

type AcademyPasswordFormProps = {
residence: string
}

const AcademyPasswordForm = ({ residence }: AcademyPasswordFormProps) => {
const [password, setPassword] = useState('')
const [form_errors, setFormErrors] = useState('')
const [submit_status, setSubmitStatus] = useState('')
const [submit_error_msg, setSubmitErrorMsg] = useState('')
const GoTrading = styled(Button)`
border-radius: 4px;
`

const handleInput = (e) => {
e.preventDefault()
const { value } = e.target
console.log('value', value)
value && setPassword(value)
if (academy_validation) {
const error_msg = academy_validation.password(value)
setFormErrors(error_msg)
}
}
console.log('hi')
const handleError = () => {
setFormErrors('')
}

const GetDerivAcademy = () => {
apiManager
.augmentedSend('new_account_virtual', {
new_account_virtual: 1,
type: 'trading',
client_password: password,
residence: residence,
verification_code: 'uoJvVuQ6',
})
.then((response) => {
console.log(response)
if (response.error) {
setSubmitStatus('error')
setSubmitErrorMsg(response.error.message)
} else {
setSubmitStatus('success')
navigate(
'https://oauth.deriv.com/oauth2/session/thinkific/create?app_id=37228',
{ replace: true },
)
}
})
}

return (
<Flex.Box direction="col" padding="12x">
<Typography.Paragraph weight="bold" pb="12x" align="center">
<Localize translate_text="_t_Keep your account secure with a password_t_" />
</Typography.Paragraph>

<Flex.Item className={input_field}>
<AcademyInput
id="dm-password"
name="password"
type="password"
label="Create a password"
value={password}
error={form_errors}
placeholder="Create a password"
password_icon={true}
onChange={handleInput}
handleError={() => handleError()}
/>
</Flex.Item>
<Typography.Paragraph size="xs" align="center" pb="12x">
<Localize
translate_text={localize(
'_t_Strong passwords contain at least 8 characters. combine uppercase and lowercase letters, numbers, and symbols._t_',
)}
/>
</Typography.Paragraph>

<Flex.Item className={signup_form_line} />
<div className={trading_btn} onClick={GetDerivAcademy}>
<GoTrading secondary disabled={form_errors || !password}>
<Localize translate_text="_t_Go to Deriv Academy_t_" />
</GoTrading>
</div>
</Flex.Box>
)
}

export default AcademyPasswordForm
23 changes: 23 additions & 0 deletions src/features/pages/signup-academy-complete/password-validation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { localize } from 'components/localization'

export const password_regex_validate = {
password: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()\-_=+[{\]};:'",<.>/?]).{8,}$/,
}

export const validation_is_lack_number = (input, min_digit) => input.length + 1 > min_digit

export const passwordValidation = (input) => {
if (!input) {
return localize('_t_You should enter 8-25 characters._t_')
} else if (!password_regex_validate.password.test(input)) {
return localize(
`_t_Password should have lower and uppercase English letters with numbers._t_`,
)
}
}

export const academy_validation = {
password: (input) => {
return passwordValidation(input)
},
}
75 changes: 75 additions & 0 deletions src/features/pages/signup-academy-complete/pop-up-menu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { useState } from 'react'
import styled from 'styled-components'
import ResidenceForm from './residence-form'
import PasswordForm from './password-form'
import device from 'themes/device'
import { useResidenceList } from 'features/hooks/use-residence-list'

const Card = styled.div`
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
z-index: 99;
`
const ModalCard = styled.div`
position: relative;
z-index: 310;
display: flex;
flex-direction: column;
border-radius: 8px;
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.3);
inline-size: 44rem;
background: var(--color-white);
@media ${device.tablet} {
width: 80%;
}
`
const Background = styled.div`
position: absolute;
width: 100%;
height: 100vh;
top: 0;
left: 0;
background-color: var(--color-black-6);
opacity: 0.4;
z-index: 10;
`
const PopUpMenu = () => {
const [residence_list] = useResidenceList({
restricted_countries: ['Iran', 'North Korea', 'Myanmar (Burma)', 'Syria', 'Cuba'],
})
const [is_password, setIsPassword] = useState(false)
const [selected_value, setSelectedValue] = useState({
country: null,
citizenship: null,
})
console.log('country', selected_value.country)
console.log('citizenship', selected_value.citizenship)
return (
<>
<Card>
<ModalCard>
{!is_password && (
<ResidenceForm
residence_list={residence_list}
handleNext={() => setIsPassword(true)}
selected_value={selected_value}
setSelectedValue={setSelectedValue}
/>
)}
{is_password && <PasswordForm residence={selected_value.country.symbol} />}
</ModalCard>

<Background></Background>
</Card>
</>
)
}

export default PopUpMenu
Loading

0 comments on commit 2cf7ff5

Please sign in to comment.