Skip to content

Commit

Permalink
chore: add signup flow
Browse files Browse the repository at this point in the history
  • Loading branch information
thisyahlen-deriv committed Apr 19, 2024
1 parent b74f364 commit 79e216a
Show file tree
Hide file tree
Showing 14 changed files with 215 additions and 8 deletions.
91 changes: 91 additions & 0 deletions src/flows/Signup/CitizenshipModal/CitizenshipModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import React, { useEffect, useState } from 'react';
import { useFormikContext } from 'formik';

import { LabelPairedChevronDownMdRegularIcon } from '@deriv/quill-icons';
import { useResidenceList, useWebsiteStatus } from '@deriv-com/api-hooks';
import { Button, Checkbox, Dropdown, Text } from '@deriv-com/ui';

import { isCVMEnabled } from '@/helpers';

import { TSignupFormValues } from '../SignupWrapper/SignupWrapper';

type TCitizenshipModal = {
onClickNext: VoidFunction;
};

export const CitizenshipModal = ({ onClickNext }: TCitizenshipModal) => {
const { data: residenceList } = useResidenceList();
const { data: websiteStatus } = useWebsiteStatus();
const clientCountry = websiteStatus?.clients_country;
const [isCheckBoxChecked, setIsCheckBoxChecked] = useState(false);
const { values, setFieldValue } = useFormikContext<TSignupFormValues>();
const isCheckboxVisible = isCVMEnabled(values.country);

useEffect(() => {
if (residenceList?.length && clientCountry && values.country === '') {
setFieldValue('country', clientCountry);
}
}, [clientCountry, setFieldValue, residenceList, values.country]);

// Add <Loading /> here later when it's created

return (
<div className='h-full rounded-default max-w-[328px] lg:max-w-[440px] bg-system-light-primary-background'>
<div className='flex flex-col p-16 space-y-16 lg:space-y-24 lg:p-24'>
<Text weight='bold'>Select your country and citizenship:</Text>
<Dropdown
dropdownIcon={<LabelPairedChevronDownMdRegularIcon />}
errorMessage='Country of residence is where you currently live.'
label='Country of residence'
list={residenceList ?? []}
name='country'
onSelect={selectedItem => {
setFieldValue('country', selectedItem);
}}
value={values.country}
variant='comboBox'
/>
<Dropdown
dropdownIcon={<LabelPairedChevronDownMdRegularIcon />}
errorMessage='Select your citizenship/nationality as it appears on your passport or other government-issued ID.'
label='Citizenship'
list={residenceList ?? []}
name='citizenship'
onSelect={selectedItem => {
setFieldValue('citizenship', selectedItem);
}}
value={values.citizenship}
variant='comboBox'
/>
{isCheckboxVisible && (
<Checkbox
checked={isCheckBoxChecked}
label={
<Text size='sm'>
I hereby confirm that my request for opening an account with Deriv to trade OTC products
issued and offered exclusively outside Brazil was initiated by me. I fully understand
that Deriv is not regulated by CVM and by approaching Deriv I intend to set up a
relation with a foreign company.
</Text>
}
labelClassName='flex-1'
name='cvmCheckbox'
onChange={(event: React.ChangeEvent<HTMLInputElement>) =>
setIsCheckBoxChecked(event.target.checked)
}
wrapperClassName='w-auto'
/>
)}
<Button
className='w-full lg:self-end lg:w-fit'
disabled={Boolean(
!values.country || !values.citizenship || (isCheckboxVisible && !isCheckBoxChecked)
)}
onClick={onClickNext}
>
Next
</Button>
</div>
</div>
);
};
1 change: 1 addition & 0 deletions src/flows/Signup/CitizenshipModal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { CitizenshipModal } from './CitizenshipModal';
43 changes: 43 additions & 0 deletions src/flows/Signup/PasswordSettingModal/PasswordSettingModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { ChangeEvent } from 'react';
import { useFormikContext } from 'formik';

import { Button, PasswordInput, Text } from '@deriv-com/ui';

import { validPassword } from '@/utils';

import { TSignupFormValues } from '../SignupWrapper/SignupWrapper';

export const PasswordSettingModal = () => {
const { values, setFieldValue } = useFormikContext<TSignupFormValues>();

const onPasswordChange = (e: ChangeEvent<HTMLInputElement>) => {
setFieldValue('password', e.target.value);
};

return (
<div className='h-full rounded-default max-w-[328px] lg:max-w-[440px] bg-system-light-primary-background'>
<div className='flex flex-col p-16 space-y-16 lg:space-y-24 lg:p-24'>
<Text align='center' weight='bold'>
Keep your account secure with a password
</Text>
<PasswordInput
isFullWidth
label='Create a password'
onChange={onPasswordChange}
value={values.password}
/>
<Text align='center' size='xs'>
Strong passwords contain at least 8 characters. combine uppercase and lowercase letters, numbers,
and symbols.
</Text>
<Button
className='w-full lg:self-end lg:w-fit'
disabled={!validPassword(values.password)}
type='submit'
>
Start trading
</Button>
</div>
</div>
);
};
1 change: 1 addition & 0 deletions src/flows/Signup/PasswordSettingModal/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PasswordSettingModal } from './PasswordSettingModal';
20 changes: 20 additions & 0 deletions src/flows/Signup/SignupScreens/SignupScreens.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { Dispatch } from 'react';

import { CitizenshipModal } from '../CitizenshipModal';
import { PasswordSettingModal } from '../PasswordSettingModal';

type TSignupScreens = {
setStep: Dispatch<React.SetStateAction<number>>;
step: number;
};

export const SignupScreens = ({ step, setStep }: TSignupScreens) => {
switch (step) {
case 1:
return <CitizenshipModal onClickNext={() => setStep(prev => prev + 1)} />;
case 2:
return <PasswordSettingModal />;
default:
return null;
}
};
1 change: 1 addition & 0 deletions src/flows/Signup/SignupScreens/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SignupScreens } from './SignupScreens';
41 changes: 41 additions & 0 deletions src/flows/Signup/SignupWrapper/SignupWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useState } from 'react';
import { Form, Formik } from 'formik';

import { Modal } from '@deriv-com/ui';

import { useQueryParams } from '@/hooks';
import { signup } from '@/utils/validations';

import { SignupScreens } from '../SignupScreens';

export type TSignupFormValues = {
citizenship: string;
country: string;
password: string;
};

export const SignupWrapper = () => {
const [step, setStep] = useState(1);
const { openModal, isModalOpen } = useQueryParams();

const initialValues = {
country: '',
citizenship: '',
password: '',
};

const handleSubmit = () => {
// logic will be added later
openModal('RealAccountCreation');
};

return (
<Modal ariaHideApp={false} isOpen={isModalOpen('Signup')} shouldCloseOnOverlayClick={false}>
<Formik initialValues={initialValues} onSubmit={handleSubmit} validationSchema={signup}>
<Form>
<SignupScreens setStep={setStep} step={step} />
</Form>
</Formik>
</Modal>
);
};
1 change: 1 addition & 0 deletions src/flows/Signup/SignupWrapper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SignupWrapper } from './SignupWrapper';
1 change: 1 addition & 0 deletions src/flows/Signup/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SignupWrapper as Signup } from './SignupWrapper';
1 change: 1 addition & 0 deletions src/flows/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './RealAccountCreation';
export * from './Signup';
1 change: 1 addition & 0 deletions src/helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './urls';
export * from './currencies';
export * from './formikHelpers';
export * from './isEUCountry';
export * from './signupModalHelpers';
1 change: 1 addition & 0 deletions src/helpers/signupModalHelpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const isCVMEnabled = (countryCode: string) => countryCode === 'br';
3 changes: 2 additions & 1 deletion src/modals/Modals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
MT5SuccessModal,
TradeModal,
} from '@/cfd/modals';
import { RealAccountCreation } from '@/flows';
import { RealAccountCreation, Signup } from '@/flows';

import { JurisdictionModal } from './JurisdictionModal';
import { RegulationModal } from './RegulationModal';
Expand All @@ -33,6 +33,7 @@ export const Modals = () => {
<RealAccountCreation />
<RegulationModal />
<TradeModal />
<Signup />
</Fragment>
);
};
17 changes: 10 additions & 7 deletions src/pages/signup/signup.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Link } from 'react-router-dom';
import { useEffect } from 'react';

import { useQueryParams } from '@/hooks';

export const Signup = () => {
return (
<>
<h1>Signup</h1>
<Link to='/'>Go to Homepage</Link>
</>
);
const { openModal, isModalOpen } = useQueryParams();

useEffect(() => {
openModal('Signup');
}, [isModalOpen, openModal]);

return null;
};

0 comments on commit 79e216a

Please sign in to comment.