From a19445cc9d583be17cb943e8cd8df145e5c54de4 Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Mon, 22 Jan 2024 13:19:19 +0400 Subject: [PATCH 01/11] feat: added formInputfield to accounts v2 --- .../components/FormFields/FormInputField.tsx | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 packages/account-v2/src/components/FormFields/FormInputField.tsx diff --git a/packages/account-v2/src/components/FormFields/FormInputField.tsx b/packages/account-v2/src/components/FormFields/FormInputField.tsx new file mode 100644 index 000000000000..49ca726c1d26 --- /dev/null +++ b/packages/account-v2/src/components/FormFields/FormInputField.tsx @@ -0,0 +1,47 @@ +import React, { ComponentProps } from 'react'; +import { Field, FieldProps } from 'formik'; +import * as Yup from 'yup'; +import { WalletTextField as TextField } from '../base/WalletTextField'; + +type FormInputFieldProps = Omit, 'errorMessage' | 'isInvalid' | 'showMessage'> & { + name: string; + validationSchema?: Yup.AnySchema; +}; + +/** + * FormInputField is a wrapper around Input that can be used with Formik. + * @name FormInputField + * @param name - Name of the field + * @param [validationSchema] - Yup validation schema to use for the field + * @param [props] - Other props to pass to Input + * @returns ReactNode + */ +const FormInputField = ({ name, validationSchema, ...rest }: FormInputFieldProps) => { + const validateField = (value: unknown) => { + try { + if (validationSchema) { + validationSchema.validateSync(value); + } + } catch (err: unknown) { + return (err as Yup.ValidationError).message; + } + }; + + return ( + + {({ field, meta: { error, touched } }: FieldProps) => ( + + )} + + ); +}; + +export default FormInputField; From cc9703b67bd0d48ae7bf3fc6d48a0a06b944cecd Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Mon, 22 Jan 2024 13:19:46 +0400 Subject: [PATCH 02/11] feat: Added formdropdownfield to accounts v2 --- .../FormFields/FormDropDownField.tsx | 51 +++++++++++++++++++ .../base/WalletDropdown/WalletDropdown.scss | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 packages/account-v2/src/components/FormFields/FormDropDownField.tsx diff --git a/packages/account-v2/src/components/FormFields/FormDropDownField.tsx b/packages/account-v2/src/components/FormFields/FormDropDownField.tsx new file mode 100644 index 000000000000..2ef17e5d7598 --- /dev/null +++ b/packages/account-v2/src/components/FormFields/FormDropDownField.tsx @@ -0,0 +1,51 @@ +import React, { ComponentProps } from 'react'; +import { Field, FieldProps } from 'formik'; +import * as Yup from 'yup'; +import { useBreakpoint } from '@deriv/quill-design'; +import { WalletDropdown as DropDown } from '../base/WalletDropdown'; + +type FormDropDownFieldProps = Omit< + ComponentProps, + 'errorMessage' | 'isRequired' | 'onSelect' | 'variant' +> & { + name: string; + validationSchema?: Yup.AnySchema; +}; + +/** + * FormDropDownField is a wrapper around Dropdown that can be used with Formik. + * @name FormDropDownField + * @param name - Name of the field + * @param [props] - Other props to pass to Input + * @returns ReactNode + */ +const FormDropDownField = ({ name, validationSchema, ...rest }: FormDropDownFieldProps) => { + const { isMobile } = useBreakpoint(); + + const validateField = (value: unknown) => { + try { + if (validationSchema) { + validationSchema.validateSync(value); + } + } catch (err: unknown) { + return (err as Yup.ValidationError).message; + } + }; + + return ( + + {({ field, form, meta: { error, touched } }: FieldProps) => ( + form.setFieldValue(name, value)} + variant={isMobile ? 'prompt' : 'comboBox'} + /> + )} + + ); +}; + +export default FormDropDownField; diff --git a/packages/account-v2/src/components/base/WalletDropdown/WalletDropdown.scss b/packages/account-v2/src/components/base/WalletDropdown/WalletDropdown.scss index 88d5c44b9df9..0e67cab35118 100644 --- a/packages/account-v2/src/components/base/WalletDropdown/WalletDropdown.scss +++ b/packages/account-v2/src/components/base/WalletDropdown/WalletDropdown.scss @@ -74,7 +74,7 @@ label, &__field:focus ~ &__label { position: absolute; - top: -0.5rem; + top: 0; display: block; transition: 0.2s; font-size: 1rem; From f45c183c66d62a877e72649032188acce4f77ece Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Mon, 22 Jan 2024 13:20:48 +0400 Subject: [PATCH 03/11] feat: added address field validations --- .../src/modules/AddressFields/validations.ts | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 packages/account-v2/src/modules/AddressFields/validations.ts diff --git a/packages/account-v2/src/modules/AddressFields/validations.ts b/packages/account-v2/src/modules/AddressFields/validations.ts new file mode 100644 index 000000000000..784742849a24 --- /dev/null +++ b/packages/account-v2/src/modules/AddressFields/validations.ts @@ -0,0 +1,66 @@ +import * as Yup from 'yup'; + +const regexChecks = { + address_details: { + address_city: /^\p{L}[\p{L}\s'.-]{0,99}$/u, + address_line_1: /^[\p{L}\p{Nd}\s'.,:;()\u00b0@#/-]{1,70}$/u, + address_line_2: /^[\p{L}\p{Nd}\s'.,:;()\u00b0@#/-]{0,70}$/u, + address_postcode: /^[a-zA-Z0-9\s-]{0,20}$/, + address_state: /^[\w\s\W'.;,-]{0,99}$/, + non_jersey_postcode: /^(?!\s*je.*)[a-zA-Z0-9\s-]*/i, + }, +}; + +const addressPermittedSpecialCharactersMessage = ". , ' : ; ( ) ° @ # / -"; + +export const addressDetailValidations = (countryCode: string, isSvg: boolean) => ({ + addressCity: Yup.string() + .required('City is required') + .max(99, 'Only 99 characters, please.') + .matches( + regexChecks.address_details.address_city, + 'Only letters, periods, hyphens, apostrophes, and spaces, please.' + ), + addressLine1: Yup.string() + .required('First line of address is required') + .max(70, 'Only 70 characters, please.') + .matches( + regexChecks.address_details.address_line_1, + `Use only the following special characters: ${addressPermittedSpecialCharactersMessage}` + ) + .when({ + is: () => isSvg, + then: Yup.string().test( + 'po_box', + 'P.O. Box is not accepted in address', + value => !/p[.\s]+o[.\s]+box/i.test(value ?? '') + ), + }), + addressLine2: Yup.string() + .max(70, 'Only 70 characters, please.') + .matches( + regexChecks.address_details.address_line_2, + `Use only the following special characters: ${addressPermittedSpecialCharactersMessage}` + ) + .when({ + is: () => isSvg, + then: Yup.string().test( + 'po_box', + 'P.O. Box is not accepted in address', + value => !/p[.\s]+o[.\s]+box/i.test(value ?? '') + ), + }), + addressPostcode: Yup.string() + .max(20, 'Please enter a postal/ZIP code under 20 characters.') + .matches(regexChecks.address_details.address_postcode, 'Letters, numbers, spaces, hyphens only') + .when({ + is: () => countryCode === 'gb', + then: Yup.string().matches( + regexChecks.address_details.non_jersey_postcode, + 'Our accounts and services are unavailable for the Jersey postal code.' + ), + }), + addressState: Yup.string() + .required('State is required') + .matches(regexChecks.address_details.address_state, 'State is not in a proper format'), +}); From 9aa50b4f75f5f5d9b6dc3d7e551b510115680b95 Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Mon, 22 Jan 2024 13:21:18 +0400 Subject: [PATCH 04/11] feat: Added address fields in account v2 package --- .../modules/AddressFields/AddressFields.tsx | 70 +++++++++++++++++++ .../src/modules/AddressFields/index.ts | 1 + packages/api/src/hooks/useStatesList.ts | 4 +- 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 packages/account-v2/src/modules/AddressFields/AddressFields.tsx create mode 100644 packages/account-v2/src/modules/AddressFields/index.ts diff --git a/packages/account-v2/src/modules/AddressFields/AddressFields.tsx b/packages/account-v2/src/modules/AddressFields/AddressFields.tsx new file mode 100644 index 000000000000..8ab91fe99fe3 --- /dev/null +++ b/packages/account-v2/src/modules/AddressFields/AddressFields.tsx @@ -0,0 +1,70 @@ +import React from 'react'; +import { useAuthorize, useSettings, useStatesList } from '@deriv/api'; +import FormDropDownField from '../../components/FormFields/FormDropDownField'; +import FormInputField from '../../components/FormFields/FormInputField'; +import { addressDetailValidations } from './validations'; + +export const AddressFields = () => { + const { data: activeAccount } = useAuthorize(); + const { data: settings } = useSettings(); + + const { landing_company_name: landingCompanyName, upgradeable_landing_companies: upgradableLandingCompanies } = + activeAccount; + + const isSvg = landingCompanyName === 'svg' || !!upgradableLandingCompanies?.includes('svg'); + const { data: statesList, isFetched: statesListFetched } = useStatesList(settings.country_code || '', { + enabled: !!settings.country_code, + }); + + const { + addressCity: addressCitySchema, + addressLine1: addressLine1Schema, + addressLine2: addressLine2Schema, + addressPostcode: addressPostcodeSchema, + addressState: addressStateSchema, + } = addressDetailValidations(settings.country_code || '', isSvg); + + return ( +
+ + + + {statesListFetched && statesList.length ? ( + + ) : ( + + )} + +
+ ); +}; diff --git a/packages/account-v2/src/modules/AddressFields/index.ts b/packages/account-v2/src/modules/AddressFields/index.ts new file mode 100644 index 000000000000..e40aee0650f7 --- /dev/null +++ b/packages/account-v2/src/modules/AddressFields/index.ts @@ -0,0 +1 @@ +export { AddressFields } from './AddressFields'; diff --git a/packages/api/src/hooks/useStatesList.ts b/packages/api/src/hooks/useStatesList.ts index 89a8d3e21536..a3a8700cf22f 100644 --- a/packages/api/src/hooks/useStatesList.ts +++ b/packages/api/src/hooks/useStatesList.ts @@ -1,15 +1,17 @@ import { useMemo } from 'react'; import useQuery from '../useQuery'; import useSettings from './useSettings'; +import { TSocketRequestQueryOptions } from '../../types'; /** Custom hook to get states list for a particular country. */ type TStatesList = Exclude['data']['residence' | 'country']>, undefined>; -const useStatesList = (country: TStatesList) => { +const useStatesList = (country: TStatesList, options: TSocketRequestQueryOptions<'states_list'>) => { const { data, ...rest } = useQuery('states_list', { // @ts-expect-error The `states_list` type from `@deriv/api-types` is not correct. // The type should be `string`, but it's an alias to string type. payload: { states_list: country }, + options, }); const modified_states_list = useMemo(() => [...(data?.states_list || [])], [data?.states_list]); From f0a3e1f4fcf877aaebfc75dadbcf2ccb58829a90 Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Mon, 22 Jan 2024 13:38:19 +0400 Subject: [PATCH 05/11] fix: Make the options parameter optional in useStatesList --- packages/api/src/hooks/useStatesList.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/api/src/hooks/useStatesList.ts b/packages/api/src/hooks/useStatesList.ts index a3a8700cf22f..8ba266afa1f3 100644 --- a/packages/api/src/hooks/useStatesList.ts +++ b/packages/api/src/hooks/useStatesList.ts @@ -6,7 +6,7 @@ import { TSocketRequestQueryOptions } from '../../types'; /** Custom hook to get states list for a particular country. */ type TStatesList = Exclude['data']['residence' | 'country']>, undefined>; -const useStatesList = (country: TStatesList, options: TSocketRequestQueryOptions<'states_list'>) => { +const useStatesList = (country: TStatesList, options?: TSocketRequestQueryOptions<'states_list'>) => { const { data, ...rest } = useQuery('states_list', { // @ts-expect-error The `states_list` type from `@deriv/api-types` is not correct. // The type should be `string`, but it's an alias to string type. From 2fd8524665ea3e396dec7451818a6987d7f150d1 Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Tue, 23 Jan 2024 13:34:50 +0400 Subject: [PATCH 06/11] refactor: Append tests, refactor constants --- .../account-v2/src/constants/constants.ts | 7 ++ .../modules/AddressFields/AddressFields.tsx | 6 +- .../__tests__/validations.spec.ts | 88 +++++++++++++++++++ .../src/modules/AddressFields/validations.ts | 4 +- .../hooks/__tests__/useStatesList.spec.tsx | 44 ++++++++++ packages/api/src/hooks/useStatesList.ts | 2 +- 6 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 packages/account-v2/src/constants/constants.ts create mode 100644 packages/account-v2/src/modules/AddressFields/__tests__/validations.spec.ts create mode 100644 packages/api/src/hooks/__tests__/useStatesList.spec.tsx diff --git a/packages/account-v2/src/constants/constants.ts b/packages/account-v2/src/constants/constants.ts new file mode 100644 index 000000000000..a2bce68574e6 --- /dev/null +++ b/packages/account-v2/src/constants/constants.ts @@ -0,0 +1,7 @@ +export const LANDING_COMPANY = { + BVI: 'bvi', + LABUAN: 'labuan', + MALTAINVEST: 'maltainvest', + SVG: 'svg', + VANUATU: 'vanuatu', +} as const; diff --git a/packages/account-v2/src/modules/AddressFields/AddressFields.tsx b/packages/account-v2/src/modules/AddressFields/AddressFields.tsx index 8ab91fe99fe3..ce271e4045a0 100644 --- a/packages/account-v2/src/modules/AddressFields/AddressFields.tsx +++ b/packages/account-v2/src/modules/AddressFields/AddressFields.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { useAuthorize, useSettings, useStatesList } from '@deriv/api'; import FormDropDownField from '../../components/FormFields/FormDropDownField'; import FormInputField from '../../components/FormFields/FormInputField'; +import { LANDING_COMPANY } from '../../constants/constants'; import { addressDetailValidations } from './validations'; export const AddressFields = () => { @@ -11,7 +12,8 @@ export const AddressFields = () => { const { landing_company_name: landingCompanyName, upgradeable_landing_companies: upgradableLandingCompanies } = activeAccount; - const isSvg = landingCompanyName === 'svg' || !!upgradableLandingCompanies?.includes('svg'); + const isSvg = + landingCompanyName === LANDING_COMPANY.SVG || !!upgradableLandingCompanies?.includes(LANDING_COMPANY.SVG); const { data: statesList, isFetched: statesListFetched } = useStatesList(settings.country_code || '', { enabled: !!settings.country_code, }); @@ -22,7 +24,7 @@ export const AddressFields = () => { addressLine2: addressLine2Schema, addressPostcode: addressPostcodeSchema, addressState: addressStateSchema, - } = addressDetailValidations(settings.country_code || '', isSvg); + } = addressDetailValidations(settings.country_code ?? '', isSvg); return (
diff --git a/packages/account-v2/src/modules/AddressFields/__tests__/validations.spec.ts b/packages/account-v2/src/modules/AddressFields/__tests__/validations.spec.ts new file mode 100644 index 000000000000..7b88fead8418 --- /dev/null +++ b/packages/account-v2/src/modules/AddressFields/__tests__/validations.spec.ts @@ -0,0 +1,88 @@ +import { addressDetailValidations as validations, addressPermittedSpecialCharactersMessage } from '../validations'; + +describe('validations', () => { + const maxCharsMessage = 'Only 70 characters, please.'; + it('validates addressLine1 correctly without svg flag', async () => { + const { addressLine1 } = validations('id', false); + + await expect(addressLine1.validate('123 Main St')).resolves.toBe('123 Main St'); + await expect(addressLine1.validate('')).rejects.toThrow('First line of address is required'); + await expect(addressLine1.validate('a$^&')).rejects.toThrow( + `Use only the following special characters: ${addressPermittedSpecialCharactersMessage}` + ); + await expect(addressLine1.validate('a'.repeat(71))).rejects.toThrow(maxCharsMessage); + await expect(addressLine1.validate('P.O. Box 121')).resolves.toBe('P.O. Box 121'); + }); + + it('validates addressLine1 correctly with svg flag', async () => { + const { addressLine1 } = validations('id', true); + + await expect(addressLine1.validate('123 Main St1')).resolves.toBe('123 Main St1'); + await expect(addressLine1.validate('')).rejects.toThrow('First line of address is required'); + await expect(addressLine1.validate('a'.repeat(71))).rejects.toThrow(maxCharsMessage); + await expect(addressLine1.validate('P.O. Box 123')).rejects.toThrow('P.O. Box is not accepted in address'); + }); + + it('validates addressLine2 correctly', async () => { + const { addressLine2 } = validations('id', false); + + await expect(addressLine2.validate('Apt 4B')).resolves.toBe('Apt 4B'); + await expect(addressLine2.validate('a$^&')).rejects.toThrow( + `Use only the following special characters: ${addressPermittedSpecialCharactersMessage}` + ); + await expect(addressLine2.validate('a'.repeat(71))).rejects.toThrow(maxCharsMessage); + await expect(addressLine2.validate('P.O. Box 120')).resolves.toBe('P.O. Box 120'); + }); + + it('validates addressLine2 correctly with svg flag', async () => { + const { addressLine2 } = validations('id', true); + + await expect(addressLine2.validate('Apt 4B')).resolves.toBe('Apt 4B'); + await expect(addressLine2.validate('a'.repeat(71))).rejects.toThrow(maxCharsMessage); + await expect(addressLine2.validate('P.O. Box 122')).rejects.toThrow('P.O. Box is not accepted in address'); + }); + + it('validates addressPostcode correctly with country gb', async () => { + const { addressPostcode } = validations('gb', false); + + await expect(addressPostcode.validate('12345')).resolves.toBe('12345'); + await expect(addressPostcode.validate('$%&')).rejects.toThrow('Letters, numbers, spaces, hyphens only'); + await expect(addressPostcode.validate('a'.repeat(21))).rejects.toThrow( + 'Please enter a postal/ZIP code under 20 characters.' + ); + await expect(addressPostcode.validate('JE1 1AA')).rejects.toThrow( + 'Our accounts and services are unavailable for the Jersey postal code.' + ); + }); + + it('validates addressPostcode correctly with country id', async () => { + const { addressPostcode } = validations('id', false); + + await expect(addressPostcode.validate('12345')).resolves.toBe('12345'); + await expect(addressPostcode.validate('$%&')).rejects.toThrow('Letters, numbers, spaces, hyphens only'); + await expect(addressPostcode.validate('a'.repeat(21))).rejects.toThrow( + 'Please enter a postal/ZIP code under 20 characters.' + ); + await expect(addressPostcode.validate('JE1 1AA')).resolves.toBe('JE1 1AA'); + }); + + it('validates addressState correctly', async () => { + const { addressState } = validations('id', false); + + await expect(addressState.validate('NY')).resolves.toBe('NY'); + await expect(addressState.validate('')).rejects.toThrow('State is required'); + await expect(addressState.validate('a'.repeat(100))).rejects.toThrow('State is not in a proper format'); + await expect(addressState.validate('%_ASD')).rejects.toThrow('State is not in a proper format'); + }); + + it('validates addressCity correctly', async () => { + const { addressCity } = validations('id', false); + + await expect(addressCity.validate('New York')).resolves.toBe('New York'); + await expect(addressCity.validate('')).rejects.toThrow('City is required'); + await expect(addressCity.validate('a'.repeat(100))).rejects.toThrow('Only 99 characters, please.'); + await expect(addressCity.validate('%_ASD')).rejects.toThrow( + 'Only letters, periods, hyphens, apostrophes, and spaces, please.' + ); + }); +}); diff --git a/packages/account-v2/src/modules/AddressFields/validations.ts b/packages/account-v2/src/modules/AddressFields/validations.ts index 784742849a24..7d16aeb4380e 100644 --- a/packages/account-v2/src/modules/AddressFields/validations.ts +++ b/packages/account-v2/src/modules/AddressFields/validations.ts @@ -6,12 +6,12 @@ const regexChecks = { address_line_1: /^[\p{L}\p{Nd}\s'.,:;()\u00b0@#/-]{1,70}$/u, address_line_2: /^[\p{L}\p{Nd}\s'.,:;()\u00b0@#/-]{0,70}$/u, address_postcode: /^[a-zA-Z0-9\s-]{0,20}$/, - address_state: /^[\w\s\W'.;,-]{0,99}$/, + address_state: /^[\w\s'.;,-]{0,99}$/, non_jersey_postcode: /^(?!\s*je.*)[a-zA-Z0-9\s-]*/i, }, }; -const addressPermittedSpecialCharactersMessage = ". , ' : ; ( ) ° @ # / -"; +export const addressPermittedSpecialCharactersMessage = ". , ' : ; ( ) ° @ # / -"; export const addressDetailValidations = (countryCode: string, isSvg: boolean) => ({ addressCity: Yup.string() diff --git a/packages/api/src/hooks/__tests__/useStatesList.spec.tsx b/packages/api/src/hooks/__tests__/useStatesList.spec.tsx new file mode 100644 index 000000000000..2e846c6e8740 --- /dev/null +++ b/packages/api/src/hooks/__tests__/useStatesList.spec.tsx @@ -0,0 +1,44 @@ +import { renderHook } from '@testing-library/react-hooks'; +import useQuery from '../../useQuery'; +import useStatesList from '../useStatesList'; + +jest.mock('../../useQuery'); + +const mockUseQuery = useQuery as jest.MockedFunction>; + +describe('useStatesList', () => { + it('should return an empty array when the store is not ready', () => { + // @ts-expect-error need to come up with a way to mock the return type of useFetch + mockUseQuery.mockReturnValue({ + data: { + states_list: [], + }, + }); + const { result } = renderHook(() => useStatesList('in')); + + expect(result.current.data).toHaveLength(0); + }); + + it('should return data fetched along with correct status', () => { + // @ts-expect-error need to come up with a way to mock the return type of useFetch + mockUseQuery.mockReturnValue({ + data: { + states_list: [ + { text: 'state 1', value: 's1' }, + { text: 'state 2', value: 's2' }, + ], + }, + isFetched: true, + }); + const { result } = renderHook(() => useStatesList('in')); + expect(result.current.isFetched).toBeTruthy(); + }); + + it('should call the useQuery with options if passed', () => { + renderHook(() => useStatesList('in', { enabled: false })); + expect(mockUseQuery).toHaveBeenCalledWith('states_list', { + payload: { states_list: 'in' }, + options: { enabled: false }, + }); + }); +}); diff --git a/packages/api/src/hooks/useStatesList.ts b/packages/api/src/hooks/useStatesList.ts index 8ba266afa1f3..6a1e67df8937 100644 --- a/packages/api/src/hooks/useStatesList.ts +++ b/packages/api/src/hooks/useStatesList.ts @@ -14,7 +14,7 @@ const useStatesList = (country: TStatesList, options?: TSocketRequestQueryOption options, }); - const modified_states_list = useMemo(() => [...(data?.states_list || [])], [data?.states_list]); + const modified_states_list = useMemo(() => [...(data?.states_list ?? [])], [data?.states_list]); return { /** The states list for the given country. */ From 7f4708de28e1b37818407067d9e683f86ac0559f Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Tue, 23 Jan 2024 13:50:55 +0400 Subject: [PATCH 07/11] fix: fix regex character duplication --- packages/account-v2/src/modules/AddressFields/validations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-v2/src/modules/AddressFields/validations.ts b/packages/account-v2/src/modules/AddressFields/validations.ts index 7d16aeb4380e..ea65eb5462e7 100644 --- a/packages/account-v2/src/modules/AddressFields/validations.ts +++ b/packages/account-v2/src/modules/AddressFields/validations.ts @@ -7,7 +7,7 @@ const regexChecks = { address_line_2: /^[\p{L}\p{Nd}\s'.,:;()\u00b0@#/-]{0,70}$/u, address_postcode: /^[a-zA-Z0-9\s-]{0,20}$/, address_state: /^[\w\s'.;,-]{0,99}$/, - non_jersey_postcode: /^(?!\s*je.*)[a-zA-Z0-9\s-]*/i, + non_jersey_postcode: /^(?!\s*je.*)[a-z0-9\s-]*/, }, }; From 86edb3d3bd9642d77402eb838cbeee06d55f86a7 Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Tue, 23 Jan 2024 13:55:15 +0400 Subject: [PATCH 08/11] chore: update deriv-com/ui package version --- packages/account-v2/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-v2/package.json b/packages/account-v2/package.json index 638091cd341f..5823504fe2ec 100644 --- a/packages/account-v2/package.json +++ b/packages/account-v2/package.json @@ -11,7 +11,7 @@ "start": "rimraf dist && npm run test && npm run serve" }, "dependencies": { - "@deriv-com/ui": "0.0.1-beta.4", + "@deriv-com/ui": "0.0.1-beta.7", "@deriv/api": "^1.0.0", "@deriv/library": "^1.0.0", "@deriv/quill-design": "^1.3.2", From 28a9a0f3f4f87cd95de337fbd4f3491d407e7ddd Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Tue, 23 Jan 2024 16:19:10 +0400 Subject: [PATCH 09/11] chore: change deriv ui package version --- packages/account-v2/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-v2/package.json b/packages/account-v2/package.json index 5823504fe2ec..0fe1d5793502 100644 --- a/packages/account-v2/package.json +++ b/packages/account-v2/package.json @@ -11,7 +11,7 @@ "start": "rimraf dist && npm run test && npm run serve" }, "dependencies": { - "@deriv-com/ui": "0.0.1-beta.7", + "@deriv-com/ui": "0.0.1-beta.5", "@deriv/api": "^1.0.0", "@deriv/library": "^1.0.0", "@deriv/quill-design": "^1.3.2", From 531bdbf646919c2d09592a6865e2a608ae62673c Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Wed, 24 Jan 2024 10:54:27 +0400 Subject: [PATCH 10/11] fix: fix regex for postcode --- packages/account-v2/src/modules/AddressFields/validations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/account-v2/src/modules/AddressFields/validations.ts b/packages/account-v2/src/modules/AddressFields/validations.ts index ea65eb5462e7..c0bb62cbd20e 100644 --- a/packages/account-v2/src/modules/AddressFields/validations.ts +++ b/packages/account-v2/src/modules/AddressFields/validations.ts @@ -7,7 +7,7 @@ const regexChecks = { address_line_2: /^[\p{L}\p{Nd}\s'.,:;()\u00b0@#/-]{0,70}$/u, address_postcode: /^[a-zA-Z0-9\s-]{0,20}$/, address_state: /^[\w\s'.;,-]{0,99}$/, - non_jersey_postcode: /^(?!\s*je.*)[a-z0-9\s-]*/, + non_jersey_postcode: /^(?!\s*je.*)[a-z0-9\s-]*/i, }, }; From 692abd722654e54a0ac16df1b788a50f150f8e10 Mon Sep 17 00:00:00 2001 From: arshad-rao-deriv Date: Tue, 30 Jan 2024 18:04:29 +0400 Subject: [PATCH 11/11] refactor: export modules and useKycAuthStatus hook --- packages/account-v2/src/modules/index.ts | 2 ++ packages/api/src/hooks/index.ts | 1 + 2 files changed, 3 insertions(+) create mode 100644 packages/account-v2/src/modules/index.ts diff --git a/packages/account-v2/src/modules/index.ts b/packages/account-v2/src/modules/index.ts new file mode 100644 index 000000000000..e59868a5cae6 --- /dev/null +++ b/packages/account-v2/src/modules/index.ts @@ -0,0 +1,2 @@ +export { AddressFields } from './AddressFields'; +export { IDVForm } from './IDVForm'; diff --git a/packages/api/src/hooks/index.ts b/packages/api/src/hooks/index.ts index 7ab86fd26b95..c61084a17405 100644 --- a/packages/api/src/hooks/index.ts +++ b/packages/api/src/hooks/index.ts @@ -76,3 +76,4 @@ export { default as useResetVirtualBalance } from './useResetVirtualBalance'; export { default as useTotalAssets } from './useTotalAssets'; export { default as useExchangeRates } from './useExchangeRates'; export { default as useIsDIELEnabled } from './useIsDIELEnabled'; +export { default as useKycAuthStatus } from './useKycAuthStatus';