Skip to content
This repository has been archived by the owner on Sep 26, 2024. It is now read-only.

Aswathy/DPROD-3448/Deriv Academy new Sign Up flow #7090

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2cf7ff5
feat: new signup page
aswathy-deriv Feb 16, 2024
1581285
fix: redirection of login page
aswathy-deriv Feb 17, 2024
df55287
feat: academy app id redirection for login
aswathy-deriv Feb 18, 2024
f1d14ae
fix: window error issue
aswathy-deriv Feb 19, 2024
43c9b90
fix: window error
aswathy-deriv Feb 19, 2024
48bc72d
fix: app id connection and login page
aswathy-deriv Feb 19, 2024
99d00ec
fix: changed the url flow for academy signup flow
aswathy-deriv Feb 20, 2024
3f73ee4
fix: passowrd changes
aswathy-deriv Feb 20, 2024
f50bdfe
fix: validation for password
aswathy-deriv Feb 21, 2024
7e830cc
fix: password feature button
aswathy-deriv Feb 21, 2024
352c8be
fix: added the token auth
aswathy-deriv Feb 21, 2024
0645ff9
fix: added authorized token
aswathy-deriv Feb 21, 2024
797409f
fix: background color issue
aswathy-deriv Feb 22, 2024
f7e75de
fix: redirection of url to thinkific
aswathy-deriv Feb 22, 2024
3be632d
fix: authorize the api call
aswathy-deriv Feb 22, 2024
4e0bd54
fix: redirection of language to english only
aswathy-deriv Feb 22, 2024
751d9a0
fix: merge conflicts
aswathy-deriv Feb 22, 2024
90afe3a
fix: for handling the response for the country
aswathy-deriv Feb 26, 2024
1f2316d
fix: flickering logo issue
aswathy-deriv Feb 26, 2024
a3000ef
fix: flickering logo issue with use state
aswathy-deriv Feb 26, 2024
034c0b2
fix: flickering logo
aswathy-deriv Feb 26, 2024
bbc1599
fix: created the academy nav logo
aswathy-deriv Feb 26, 2024
997ec18
fix: logo fix flicker
aswathy-deriv Feb 27, 2024
599e96d
fix: password page
aswathy-deriv Feb 27, 2024
232ab09
fix: country selection and disabling button
aswathy-deriv Feb 27, 2024
6dcfb67
fix: redirection issue
aswathy-deriv Feb 27, 2024
ad2b109
fix: logo issue
aswathy-deriv Feb 28, 2024
4f3725d
fix: translations issue
aswathy-deriv Feb 28, 2024
e1baff6
fix: logo issue
aswathy-deriv Feb 28, 2024
1826933
fix: changed the logo
aswathy-deriv Feb 28, 2024
1b50c27
fix: minimized the logo size
aswathy-deriv Feb 28, 2024
2009c0b
fix: dropdown issues
aswathy-deriv Feb 29, 2024
2f71676
fix: sonar cloud issues
aswathy-deriv Feb 29, 2024
280638d
fix: issues in the design
aswathy-deriv Feb 29, 2024
9fc281a
fix: dropdown is reverted to old one
aswathy-deriv Feb 29, 2024
228b74a
fix: dropdown issues
aswathy-deriv Mar 1, 2024
6fa0c42
fix: removed the button width for residence page
aswathy-deriv Mar 1, 2024
068a99f
fix: focus blur
aswathy-deriv Mar 1, 2024
9527edc
fix: added the dropdown search changes
aswathy-deriv Mar 4, 2024
16026b1
fix: merge conflicts
aswathy-deriv Mar 4, 2024
e2065bc
fix: changed the css file
aswathy-deriv Mar 4, 2024
2fc7081
fix: renamed the css file
aswathy-deriv Mar 4, 2024
10899ac
fix: percy issues
aswathy-deriv Mar 4, 2024
26d7a44
fix: percy run issue
aswathy-deriv Mar 5, 2024
36e7a0c
fix: renamed the password files
aswathy-deriv Mar 5, 2024
b660c11
fix: sonarcloud issues
aswathy-deriv Mar 6, 2024
2e00be4
fix: merge changes
aswathy-deriv Mar 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 17 additions & 49 deletions crowdin/messages.json

Large diffs are not rendered by default.

20 changes: 16 additions & 4 deletions src/common/login.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import Cookies from 'js-cookie'
import { useEffect, useState } from 'react'
import { isStorageSupported } from './storage'
import { getCookiesFields, getCookiesObject, getDataLink, getDataObjFromCookies } from './cookies'
import { getAppId } from './websocket/config'
import { redirectToTradingPlatform } from './utility'
import { isBrowser, redirectToTradingPlatform } from './utility'
import { brand_name, deriv_app_id, oauth_url } from 'common/constants'

export type TSocialProvider = 'google' | 'facebook' | 'apple'

const Login = (() => {
const url = isBrowser() && window.location.href
const is_academy = isBrowser() && url.includes('academy')

const redirectToLogin = () => {
if (isStorageSupported(sessionStorage)) {
window.location.href = loginUrl()
Expand All @@ -31,9 +35,17 @@ const Login = (() => {

const sub_url = redirectToTradingPlatform()

return server_url && /qa/.test(server_url)
? `https://${server_url}/oauth2/authorize?app_id=${getAppId()}&l=${language}&brand=${brand_name.toLowerCase()}${affiliate_token_link}${cookies_link}&platform=${sub_url}`
: `${oauth_url}/oauth2/authorize?app_id=${deriv_app_id}&l=${language}&brand=${brand_name.toLowerCase()}${affiliate_token_link}${cookies_link}&platform=${sub_url}`
if (is_academy) {
if (server_url && /qa/.test(server_url)) {
return `https://${server_url}/oauth2/authorize?app_id=37228&l=${language}&brand=${brand_name.toLowerCase()}${affiliate_token_link}${cookies_link}&platform=${sub_url}`
}
return `${oauth_url}/oauth2/authorize?app_id=37228&l=${language}&brand=${brand_name.toLowerCase()}${affiliate_token_link}${cookies_link}&platform=${sub_url}`
} else {
if (server_url && /qa/.test(server_url)) {
return `https://${server_url}/oauth2/authorize?app_id=${getAppId()}&l=${language}&brand=${brand_name.toLowerCase()}${affiliate_token_link}${cookies_link}&platform=${sub_url}`
}
return `${oauth_url}/oauth2/authorize?app_id=${deriv_app_id}&l=${language}&brand=${brand_name.toLowerCase()}${affiliate_token_link}${cookies_link}&platform=${sub_url}`
}
}

const initOneAll = (provider: TSocialProvider, utm_content?: string): void => {
Expand Down
41 changes: 23 additions & 18 deletions src/common/websocket/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ const isStaging = () => isBrowser() && domain_config.staging.hostname === window
const isBeta = () => isBrowser() && domain_config.beta.hostname === window.location.hostname
const isLive = () => isProduction() || isStaging() || isBeta()
const isLocalHost = () => isBrowser() && domain_config.local.hostname === window.location.hostname

const url = isBrowser() && window.location.href
const is_academy = isBrowser() && url.includes('academy')
const getAppId = (): null | number | string => {
let app_id = null
const user_app_id = '' // you can insert Application ID of your registered application here
Expand All @@ -83,24 +84,28 @@ const getAppId = (): null | number | string => {

const config_app_id = window.localStorage.getItem('config.app_id')

if (url_app_id) {
app_id = url_app_id
} else if (config_app_id) {
app_id = config_app_id
} else if (isStaging()) {
window.localStorage.removeItem('config.default_app_id')
app_id = domain_config.staging.app_id
} else if (isBeta()) {
window.localStorage.removeItem('config.default_app_id')
app_id = domain_config.beta.app_id
} else if (user_app_id.length) {
window.localStorage.setItem('config.default_app_id', user_app_id) // it's being used in endpoint chrome extension - please do not remove
app_id = user_app_id
} else if (isLocalHost()) {
app_id = domain_config.local.app_id
if (is_academy) {
app_id = 37228
} else {
window.localStorage.removeItem('config.default_app_id')
app_id = isProduction() ? prod_app_id : domain_config.test.app_id
if (url_app_id) {
app_id = url_app_id
} else if (config_app_id) {
app_id = config_app_id
} else if (isStaging()) {
window.localStorage.removeItem('config.default_app_id')
app_id = domain_config.staging.app_id
} else if (isBeta()) {
window.localStorage.removeItem('config.default_app_id')
app_id = domain_config.beta.app_id
} else if (user_app_id.length) {
window.localStorage.setItem('config.default_app_id', user_app_id) // it's being used in endpoint chrome extension - please do not remove
app_id = user_app_id
} else if (isLocalHost()) {
app_id = domain_config.local.app_id
} else {
window.localStorage.removeItem('config.default_app_id')
app_id = isProduction() ? prod_app_id : domain_config.test.app_id
}
}
}
return app_id
Expand Down
9 changes: 8 additions & 1 deletion src/features/hooks/use-residence-list/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useMemo } from 'react'
import { useEffect, useMemo, useState } from 'react'
import useWS from 'components/hooks/useWS'

export type ResidenceType = {
Expand Down Expand Up @@ -34,6 +34,13 @@ export const useResidenceList = ({
restricted_countries?: ['Iran', 'North Korea', 'Myanmar (Burma)', 'Syria', 'Cuba']
} = {}) => {
const { send, data } = useWS('residence_list')
// console.log(
// data.map((item) => {
// if (item.disabled === 'DISABLED') {

// }
// }),
// )
useEffect(() => {
send()
}, [send])
Expand Down
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 } 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

setPassword(value)
if (academy_validation) {
const error_msg = academy_validation.password(value)
setFormErrors(error_msg)
}
}

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>
<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
Loading
Loading