diff --git a/packages/account/src/Components/forms/idv-form.tsx b/packages/account/src/Components/forms/idv-form.tsx index bff0be253e6b..25a2d3e2fae0 100644 --- a/packages/account/src/Components/forms/idv-form.tsx +++ b/packages/account/src/Components/forms/idv-form.tsx @@ -1,11 +1,11 @@ import React from 'react'; -import { Form, Field, FormikValues, FormikProps, FormikHandlers } from 'formik'; +import classNames from 'classnames'; +import { Field, FormikValues, FormikProps, FormikHandlers } from 'formik'; +import { ResidenceList } from '@deriv/api-types'; import { localize, Localize } from '@deriv/translations'; import { formatInput, IDV_NOT_APPLICABLE_OPTION } from '@deriv/shared'; import { Autocomplete, DesktopWrapper, Input, MobileWrapper, SelectNative, Text } from '@deriv/components'; -import { getDocumentData, preventEmptyClipboardPaste } from 'Helpers/utils'; -import classNames from 'classnames'; -import { GetSettings, ResidenceList } from '@deriv/api-types'; +import { getDocumentData, preventEmptyClipboardPaste, generatePlaceholderText } from 'Helpers/utils'; type TDocumentList = Array<{ id: string; @@ -17,41 +17,50 @@ type TDocumentList = Array<{ }>; type TFormProps = { - document_list: TDocumentList; + document_type: TDocumentList[0]; document_number: string; document_additional: string; }; type TIDVForm = { - account_settings: GetSettings; - residence: string; - residence_list: ResidenceList; + selected_country: ResidenceList[0]; + is_from_external: boolean; hide_hint?: boolean; + class_name?: string; } & FormikHandlers & FormikProps; -const IDVForm = ({ errors, touched, values, handleBlur, handleChange, setFieldValue, ...props }: TIDVForm) => { +const IDVForm = ({ + errors, + touched, + values, + handleBlur, + handleChange, + setFieldValue, + class_name, + ...props +}: TIDVForm) => { const [document_list, setDocumentList] = React.useState([]); const [document_image, setDocumentImage] = React.useState(null); - const [is_doc_selected, setDocSelected] = React.useState(false); + const [selected_doc, setSelectedDoc] = React.useState(''); - const { account_settings, residence, residence_list } = props; - const citizen = account_settings?.citizen || residence; + const { selected_country, is_from_external } = props; + // const citizen = account_settings?.citizen || residence; - const { documents_supported: document_data, has_visual_sample }: any = - residence_list.find(residence_data => residence_data.value === citizen)?.identity.services?.idv || {}; + const { documents_supported: document_data, has_visual_sample } = selected_country?.identity?.services?.idv || {}; + // residence_list.find(residence_data => residence_data.value === citizen)?.identity.services?.idv || {}; React.useEffect(() => { const document_types = Object.keys(document_data); if (document_types.length === 0) return; - const filtered_documents = ['gh', 'ng'].includes(citizen) + const filtered_documents = ['gh', 'ng'].includes(selected_country.value) ? document_types.filter(d => d !== 'voter_id') : document_types; setDocumentList([ ...filtered_documents.map(key => { const { display_name, format } = document_data[key]; - const { new_display_name, example_format, sample_image } = getDocumentData(citizen, key); + const { new_display_name, example_format, sample_image } = getDocumentData(selected_country.value, key); const needs_additional_document = !!document_data[key].additional; if (needs_additional_document) { @@ -111,181 +120,200 @@ const IDVForm = ({ errors, touched, values, handleBlur, handleChange, setFieldVa }; return ( -
-
-
-
+ +
+
+
-
-
- - {({ field }: FormikValues) => ( - - -
- +
+
+ + {({ field }: FormikValues) => ( + + +
+ { + handleBlur(e); + if (!getDocument(e.target.value)) { + resetDocumentItemSelected(); + } + }} + onChange={handleChange} + onItemSelection={item => { + if ( + item.text === 'No results found' || + !item.text + ) { + setSelectedDoc(''); + resetDocumentItemSelected(); + } else { + setFieldValue('document_type', item, true); + setSelectedDoc(item.id); + if (has_visual_sample) { + setDocumentImage(item.sample_image || ''); + } + } + }} + required + /> +
+
+ + { - handleBlur(e); - if (!getDocument(e.target.value)) { - resetDocumentItemSelected(); - } - }} - onChange={handleChange} - onItemSelection={item => { - if (item.text === 'No results found' || !item.text) { - setDocSelected(false); - resetDocumentItemSelected(); - } else { - setFieldValue('document_type', item, true); - setDocSelected(true); + value={values.document_type.text} + onChange={e => { + handleChange(e); + const selected_document = getDocument(e.target.value); + if (selected_document) { + setSelectedDoc(selected_document.id); + setFieldValue( + 'document_type', + selected_document, + true + ); if (has_visual_sample) { - setDocumentImage(item.sample_image || ''); + setDocumentImage( + selected_document.sample_image + ); } } }} + use_text={true} required /> -
- - - { - handleChange(e); - const selected_document = getDocument(e.target.value); - if (selected_document) { - setDocSelected(true); - setFieldValue('document_type', selected_document, true); - if (has_visual_sample) { - setDocumentImage( - // eslint-disable-next-line max-len - selected_document.sample_image - ); - } - } - }} - use_text={true} - required - /> - - - )} - -
-
- - {({ field }: FormikValues) => ( - - - onKeyUp(e, 'document_number') - } - required - /> - {values.document_type.additional?.display_name && ( + + + )} + +
+
+ + {({ field }: FormikValues) => ( + - onKeyUp(e, 'document_additional') + onKeyUp(e, 'document_number') } required /> - )} - - )} - -
-
- {document_image && ( -
- - {localize('Sample:')} - -
- document sample image -
+ {values.document_type.additional?.display_name && ( + + onKeyUp(e, 'document_additional') + } + required + /> + )} + + )} + +
- )} - {is_doc_selected && !props.hide_hint && ( - - - - )} + {document_image && ( +
+ + {localize('Sample:')} + +
+ document sample image +
+
+ )} +
-
- + + {selected_doc && !props.hide_hint && ( + + + + )} + ); }; diff --git a/packages/account/src/Components/forms/personal-details-form.jsx b/packages/account/src/Components/forms/personal-details-form.jsx index 201b4b6afd73..050b580d56b6 100644 --- a/packages/account/src/Components/forms/personal-details-form.jsx +++ b/packages/account/src/Components/forms/personal-details-form.jsx @@ -92,6 +92,8 @@ const PersonalDetailsForm = ({ closeRealAccountSignup, salutation_list, is_rendered_for_onfido, + should_close_tooltip, + setShouldCloseTooltip, } = props; const autocomplete_value = 'none'; const PoiNameDobExampleIcon = PoiNameDobExample; @@ -99,6 +101,13 @@ const PersonalDetailsForm = ({ const [is_tax_residence_popover_open, setIsTaxResidencePopoverOpen] = React.useState(false); const [is_tin_popover_open, setIsTinPopoverOpen] = React.useState(false); + React.useEffect(() => { + if (should_close_tooltip) { + handleToolTipStatus(); + setShouldCloseTooltip(false); + } + }, [should_close_tooltip]); + const getLastNameLabel = () => { if (is_appstore) return localize('Family name*'); return is_svg || is_mf ? localize('Last name*') : localize('Last name'); @@ -117,6 +126,15 @@ const PersonalDetailsForm = ({ ); }; + const handleToolTipStatus = () => { + if (is_tax_residence_popover_open) { + setIsTaxResidencePopoverOpen(false); + } + if (is_tin_popover_open) { + setIsTinPopoverOpen(false); + } + }; + const name_dob_clarification_message = ( - + {!is_qualified_for_idv || + (is_rendered_for_onfido && ( + + ))} } diff --git a/packages/account/src/Components/personal-details/personal-details.jsx b/packages/account/src/Components/personal-details/personal-details.jsx index dce7eb1824fc..7462876e51bc 100644 --- a/packages/account/src/Components/personal-details/personal-details.jsx +++ b/packages/account/src/Components/personal-details/personal-details.jsx @@ -41,8 +41,7 @@ const PersonalDetails = ({ }) => { const { account_status, account_settings, residence, real_account_signup_target } = props; const { is_appstore } = React.useContext(PlatformContext); - const [is_tax_residence_popover_open, setIsTaxResidencePopoverOpen] = React.useState(false); - const [is_tin_popover_open, setIsTinPopoverOpen] = React.useState(false); + const [should_close_tooltip, setShouldCloseTooltip] = React.useState(false); const [warning_items, setWarningItems] = React.useState({}); const is_submit_disabled_ref = React.useRef(true); @@ -116,22 +115,7 @@ const PersonalDetails = ({ return error_data; }; - const closeTooltipOnScroll = () => { - // Close any open tooltip - if (!is_tax_residence_popover_open || !is_tin_popover_open) { - setIsTaxResidencePopoverOpen(false); - setIsTinPopoverOpen(false); - } - }; - - const handleClickOutside = () => { - if (is_tax_residence_popover_open) { - setIsTaxResidencePopoverOpen(false); - } - if (is_tin_popover_open) { - setIsTinPopoverOpen(false); - } - }; + const closeToolTip = () => setShouldCloseTooltip(true); /* In most modern browsers, setting autocomplete to "off" will not prevent a password manager from asking the user if they would like to save username and password information, or from automatically filling in those values in a site's login form. @@ -143,6 +127,9 @@ const PersonalDetails = ({ return example_format ? localize('Example: ') + example_format : ''; }; + const citizen = account_settings?.citizen || residence; + const selected_country = residence_list.find(residence_data => residence_data.value === citizen) || {}; + return ( {!is_qualified_for_idv && ( @@ -175,7 +163,7 @@ const PersonalDetails = ({ )} {!is_qualified_for_idv && is_appstore && ( @@ -198,9 +186,7 @@ const PersonalDetails = ({ {({ field }) => (
diff --git a/packages/account/src/Components/poi/idv-document-submit/idv-document-submit.jsx b/packages/account/src/Components/poi/idv-document-submit/idv-document-submit.jsx index d27f75a928ad..56d67e2741da 100644 --- a/packages/account/src/Components/poi/idv-document-submit/idv-document-submit.jsx +++ b/packages/account/src/Components/poi/idv-document-submit/idv-document-submit.jsx @@ -1,104 +1,21 @@ import React from 'react'; import PropTypes from 'prop-types'; -import classNames from 'classnames'; -import { Autocomplete, Button, DesktopWrapper, Input, MobileWrapper, Text, SelectNative } from '@deriv/components'; +import { Button, Text } from '@deriv/components'; import { Formik, Field } from 'formik'; -import { localize, Localize } from '@deriv/translations'; -import { formatInput, WS } from '@deriv/shared'; -import { documentAdditionalError, getRegex, preventEmptyClipboardPaste } from './utils'; +import { localize } from '@deriv/translations'; +import { WS } from '@deriv/shared'; +import { documentAdditionalError, getRegex } from './utils'; import FormFooter from 'Components/form-footer'; import BackButtonIcon from 'Assets/ic-poi-back-btn.svg'; import DocumentSubmitLogo from 'Assets/ic-document-submit-icon.svg'; -import { getDocumentData, generatePlaceholderText } from 'Helpers/utils'; +import IDVForm from 'Components/forms/idv-form'; const IdvDocumentSubmit = ({ handleBack, handleViewComplete, selected_country, is_from_external }) => { - const [document_list, setDocumentList] = React.useState([]); - const [document_image, setDocumentImage] = React.useState(null); - const [is_input_disable, setInputDisable] = React.useState(true); - const [selected_doc, setSelectedDoc] = React.useState(null); - - const document_data = selected_country.identity.services.idv.documents_supported; - - const { - value: country_code, - identity: { - services: { - idv: { has_visual_sample }, - }, - }, - } = selected_country; - - React.useEffect(() => { - // NOTE: This is a temporary filter. Remove after backend handles this from their side - const document_types = Object.keys(document_data); - const filtered_documents = ['gh', 'ng'].includes(country_code) - ? document_types.filter(d => d !== 'voter_id') - : document_types; - - setDocumentList( - filtered_documents.map(key => { - const { display_name, format } = document_data[key]; - const { new_display_name, example_format, sample_image } = getDocumentData(country_code, key); - const needs_additional_document = !!document_data[key].additional; - - if (needs_additional_document) { - return { - id: key, - text: new_display_name || display_name, - additional: { - display_name: document_data[key].additional?.display_name, - format: document_data[key].additional?.format, - }, - value: format, - sample_image, - example_format, - }; - } - return { - id: key, - text: new_display_name || display_name, - value: format, - sample_image, - example_format, - }; - }) - ); - }, [country_code, document_data]); - - const onKeyUp = (e, document_name, values, setFieldValue) => { - const { example_format } = - document_name === 'document_number' ? values.document_type : values.document_type.additional; - const current_input = example_format.includes('-') - ? formatInput(example_format, current_input || e.target.value, '-') - : e.target.value; - setFieldValue(document_name, current_input, true); - validateFields(values); - }; - - const resetDocumentItemSelected = setFieldValue => { - setFieldValue( - 'document_type', - { - id: '', - text: '', - value: '', - example_format: '', - sample_image: '', - }, - true - ); - setDocumentImage(''); - }; - const initial_form_values = { document_type: '', document_number: '', }; - const getDocument = text => { - return document_list.find(d => d.text === text); - }; - const getExampleFormat = example_format => { return example_format ? localize('Example: ') + example_format : ''; }; @@ -111,8 +28,6 @@ const IdvDocumentSubmit = ({ handleBack, handleViewComplete, selected_country, i if (!document_type || !document_type.text || !document_type.value) { errors.document_type = localize('Please select a document type.'); - } else { - setInputDisable(false); } if (needs_additional_document) { @@ -145,7 +60,7 @@ const IdvDocumentSubmit = ({ handleBack, handleViewComplete, selected_country, i document_number: values.document_number, document_additional: values.document_additional || '', document_type: values.document_type.id, - issuing_country: country_code, + issuing_country: selected_country.value, }; WS.send(submit_data).then(response => { @@ -180,161 +95,24 @@ const IdvDocumentSubmit = ({ handleBack, handleViewComplete, selected_country, i {localize('Please select the document type and enter the ID number.')} -
-
-
- - {({ field }) => ( - - -
- { - handleBlur(e); - if (!getDocument(e.target.value)) { - resetDocumentItemSelected(setFieldValue); - } - }} - onChange={handleChange} - onItemSelection={item => { - if (item.text === 'No results found' || !item.text) { - setSelectedDoc(null); - resetDocumentItemSelected(setFieldValue); - } else { - setFieldValue('document_type', item, true); - setSelectedDoc(item.id); - if (has_visual_sample) { - setDocumentImage(item.sample_image || ''); - } - } - }} - required - /> -
-
- - { - handleChange(e); - const selected_document = getDocument(e.target.value); - if (selected_document) { - setSelectedDoc(selected_document.id); - setFieldValue('document_type', selected_document, true); - if (has_visual_sample) { - setDocumentImage(selected_document.sample_image); - } - } - }} - use_text={true} - required - /> - -
- )} -
-
-
- - {({ field }) => ( - - onKeyUp(e, 'document_number', values, setFieldValue)} - required - /> - {values.document_type.additional?.display_name && ( - - onKeyUp(e, 'document_additional', values, setFieldValue) - } - /> - )} - - )} - -
-
- {document_image && ( -
- - {localize('Sample:')} - -
- document sample image -
-
+ + {({ field }) => ( + )} -
- {selected_doc && ( - - - - )} + +