forked from deriv-com/deriv-app
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[TRAH] Sergei / TRAH - 2831 / Citizenship selection modal (deriv-com#…
…13641) * feat: create useClientCountry hook * feat: intermediate result * feat: done with citizenship modal * feat: move changes back for AppContent * fix: sonarcloud issue * feat: implement review comments * feat: implement review comments #2
- Loading branch information
1 parent
4f4fe75
commit 6f53181
Showing
11 changed files
with
241 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { renderHook } from '@testing-library/react-hooks'; | ||
import useQuery from '../../useQuery'; | ||
import useClientCountry from '../useClientCountry'; | ||
|
||
jest.mock('../../useQuery'); | ||
|
||
const mockUseQuery = useQuery as jest.MockedFunction<typeof useQuery<'website_status'>>; | ||
|
||
describe('useClientCountry', () => { | ||
it('should return an undefined', () => { | ||
// @ts-expect-error need to come up with a way to mock the return type of useFetch | ||
mockUseQuery.mockReturnValue({ | ||
data: { | ||
website_status: undefined, | ||
}, | ||
}); | ||
const { result } = renderHook(() => useClientCountry()); | ||
|
||
expect(result.current.data).toBeUndefined(); | ||
}); | ||
|
||
it('should return Indonesia country code', () => { | ||
// @ts-expect-error need to come up with a way to mock the return type of useFetch | ||
mockUseQuery.mockReturnValue({ | ||
data: { | ||
website_status: { | ||
api_call_limits: { | ||
max_proposal_subscription: { | ||
applies_to: '', | ||
max: 0, | ||
}, | ||
max_requestes_general: { | ||
applies_to: '', | ||
hourly: 0, | ||
minutely: 0, | ||
}, | ||
max_requests_outcome: { | ||
applies_to: '', | ||
hourly: 0, | ||
minutely: 0, | ||
}, | ||
max_requests_pricing: { | ||
applies_to: '', | ||
hourly: 0, | ||
minutely: 0, | ||
}, | ||
}, | ||
currencies_config: {}, | ||
clients_country: 'id', | ||
}, | ||
}, | ||
}); | ||
const { result } = renderHook(() => useClientCountry()); | ||
expect(result.current.data).toBe('id'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { useMemo } from 'react'; | ||
import useQuery from '../useQuery'; | ||
|
||
/** A custom hook that gets the client country. */ | ||
const useClientCountry = () => { | ||
const { data, ...website_status_rest } = useQuery('website_status'); | ||
|
||
/** Modify the client country. */ | ||
const modified_client_country = useMemo(() => { | ||
return data?.website_status?.clients_country; | ||
}, [data]); | ||
|
||
return { | ||
/** The client's country */ | ||
data: modified_client_country, | ||
...website_status_rest, | ||
}; | ||
}; | ||
|
||
export default useClientCountry; |
89 changes: 89 additions & 0 deletions
89
packages/tradershub/src/flows/Signup/CitizenshipModal/CitizenshipModal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import { useFormikContext } from 'formik'; | ||
import { isCVMEnabled } from '@/helpers'; | ||
import { useClientCountry, useResidenceList } from '@deriv/api'; | ||
import { LabelPairedChevronDownMdRegularIcon } from '@deriv/quill-icons'; | ||
import { Button, Checkbox, Dropdown, Text } from '@deriv-com/ui'; | ||
import { TSignupFormValues } from '../SignupWrapper/SignupWrapper'; | ||
|
||
type TCitizenshipModal = { | ||
onClickNext: VoidFunction; | ||
}; | ||
|
||
const CitizenshipModal = ({ onClickNext }: TCitizenshipModal) => { | ||
const { data: residenceList, isLoading: residenceListLoading } = useResidenceList(); | ||
const { data: clientCountry, isLoading: clientCountryLoading } = useClientCountry(); | ||
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 | ||
if (clientCountryLoading && residenceListLoading) return null; | ||
|
||
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' | ||
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> | ||
); | ||
}; | ||
|
||
export default CitizenshipModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as CitizenshipModal } from './CitizenshipModal'; |
24 changes: 24 additions & 0 deletions
24
packages/tradershub/src/flows/Signup/SignupScreens/SignupScreens.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React, { Dispatch } from 'react'; | ||
import { CitizenshipModal } from '../CitizenshipModal'; | ||
|
||
type TSignupScreens = { | ||
setStep: Dispatch<React.SetStateAction<number>>; | ||
step: number; | ||
}; | ||
|
||
const SignupScreens = ({ step, setStep }: TSignupScreens) => { | ||
switch (step) { | ||
case 1: | ||
return <CitizenshipModal onClickNext={() => setStep(prev => prev + 1)} />; | ||
case 2: | ||
return ( | ||
<div className='max-w-[328px] lg:max-w-[440px] bg-system-light-primary-background rounded-default p-16 space-y-16 lg:space-y-24 lg:p-24'> | ||
Screen 2 | ||
</div> | ||
); | ||
default: | ||
return null; | ||
} | ||
}; | ||
|
||
export default SignupScreens; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as SignupScreens } from './SignupScreens'; |
43 changes: 43 additions & 0 deletions
43
packages/tradershub/src/flows/Signup/SignupWrapper/SignupWrapper.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import { Form, Formik } from 'formik'; | ||
import ReactModal from 'react-modal'; | ||
import { CUSTOM_STYLES } from '@/helpers'; | ||
import { SignupScreens } from '../SignupScreens'; | ||
|
||
export type TSignupFormValues = { | ||
citizenship: string; | ||
country: string; | ||
password: string; | ||
}; | ||
|
||
const SignupWrapper = () => { | ||
// setIsOpen will be added later when flow is completed | ||
const [isOpen] = useState(false); | ||
const [step, setStep] = useState(1); | ||
|
||
const initialValues = { | ||
country: '', | ||
citizenship: '', | ||
password: '', | ||
}; | ||
|
||
const handleSubmit = () => { | ||
// will be added later | ||
}; | ||
|
||
useEffect(() => { | ||
ReactModal.setAppElement('#v2_modal_root'); | ||
}, []); | ||
|
||
return ( | ||
<ReactModal isOpen={isOpen} shouldCloseOnOverlayClick={false} style={CUSTOM_STYLES}> | ||
<Formik initialValues={initialValues} onSubmit={handleSubmit}> | ||
<Form> | ||
<SignupScreens setStep={setStep} step={step} /> | ||
</Form> | ||
</Formik> | ||
</ReactModal> | ||
); | ||
}; | ||
|
||
export default SignupWrapper; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as SignupWrapper } from './SignupWrapper'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import { SignupWrapper as Signup } from './SignupWrapper'; | ||
|
||
export default Signup; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters