From 1ee43bce5427dde8910f9a5b46e18510e9b2719a Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Fri, 22 Aug 2025 11:32:16 +0800 Subject: [PATCH 1/3] feat: added new place of birth field on complete user profile modal --- .../src/App/Containers/Modals/app-modals.jsx | 4 +- .../complete-user-profile-modal.tsx | 128 ++++++++++++++++-- 2 files changed, 119 insertions(+), 13 deletions(-) diff --git a/packages/core/src/App/Containers/Modals/app-modals.jsx b/packages/core/src/App/Containers/Modals/app-modals.jsx index e52941dc6735..751902f275ee 100644 --- a/packages/core/src/App/Containers/Modals/app-modals.jsx +++ b/packages/core/src/App/Containers/Modals/app-modals.jsx @@ -158,14 +158,14 @@ const AppModals = observer(() => { React.useEffect(() => { if (!is_client_store_initialized || !account_settings || is_tnc_update_modal_open) return; - const { citizen, date_of_birth, address_line_1, address_city } = account_settings; + const { citizen, date_of_birth, address_line_1, address_city, place_of_birth } = account_settings; const shouldShow = !has_wallet && is_logged_in && is_authorize && has_active_real_account && - (!citizen || !date_of_birth || !address_line_1 || !address_city || no_currency); + (!citizen || !date_of_birth || !address_line_1 || !address_city || !place_of_birth || no_currency); if (shouldShow) { setShouldShowCompleteUserProfileModal(true); diff --git a/packages/core/src/App/Containers/Modals/complete-user-profile-modal/complete-user-profile-modal.tsx b/packages/core/src/App/Containers/Modals/complete-user-profile-modal/complete-user-profile-modal.tsx index d6ef63bc28c3..d30f68bb82a0 100644 --- a/packages/core/src/App/Containers/Modals/complete-user-profile-modal/complete-user-profile-modal.tsx +++ b/packages/core/src/App/Containers/Modals/complete-user-profile-modal/complete-user-profile-modal.tsx @@ -43,6 +43,7 @@ type TCurrencyFormProps = { type TPersonalDetailsFormProps = { date_of_birth: string; + place_of_birth: string; }; type TCountryandCitizenshipFormProps = { @@ -114,6 +115,7 @@ const CompleteUserProfile = observer( const [address_state_to_display, setAddressStateToDisplay] = React.useState(''); const [citizen_to_display, setCitizenToDisplay] = React.useState(''); + const [place_of_birth_to_display, setPlaceOfBirthToDisplay] = React.useState(''); const [submitting_currency, setSubmittingCurrency] = React.useState(false); const { data: states_list, isFetched: state_list_fetched } = useStatesList(residence); @@ -121,6 +123,7 @@ const CompleteUserProfile = observer( const { citizen, date_of_birth, + place_of_birth, address_line_1, address_line_2, address_city, @@ -132,6 +135,7 @@ const CompleteUserProfile = observer( currency: '', citizen: citizen || '', date_of_birth: date_of_birth || '', + place_of_birth: place_of_birth || '', address_line_1: address_line_1 || '', address_line_2: address_line_2 || '', address_city: address_city || '', @@ -295,7 +299,7 @@ const CompleteUserProfile = observer( )} )} - {!date_of_birth && ( + {(!date_of_birth || !place_of_birth) && ( <> - + {!date_of_birth && ( + + )} + {!place_of_birth && ( + <> + {!residence_list_fetched && ( +
+ +
+ )} + {residence_list?.length > 0 ? ( + + {({ field }: FieldProps) => ( + <> + {isDesktop ? ( + { + setFieldValue( + 'place_of_birth', + value, + true + ); + setPlaceOfBirthToDisplay(text); + }} + list_portal_id='modal_root' + className='complete-user-profile-modal__bottom-margin-field' + value={ + place_of_birth_to_display || + values.place_of_birth + } + required + onChange={e => { + if (place_of_birth_to_display) { + setPlaceOfBirthToDisplay(''); + } + setFieldValue('citizen', '', false); + field.onChange(e); + }} + onBlur={e => { + if ( + !e.target.value && + values.citizen + ) { + setPlaceOfBirthToDisplay( + residence_list.find( + item => + item.value === + values.place_of_birth + )?.text || + values.place_of_birth + ); + } + field.onBlur(e); + }} + /> + ) : ( + { + handleChange(e); + setFieldValue( + 'place_of_birth', + e.target.value, + true + ); + setPlaceOfBirthToDisplay( + e.target.text + ); + }} + className='complete-user-profile-modal__bottom-margin-field' + required + /> + )} + + )} + + ) : ( + // Fallback to input field when residence list is empty + + )} + + )} )} {!citizen && ( From da257ef6851335d75e6c91cedb0d22602ac8f476 Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Wed, 27 Aug 2025 18:37:44 +0800 Subject: [PATCH 2/3] chore: update place of birth validation required field --- .../Modals/complete-user-profile-modal/validation.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/core/src/App/Containers/Modals/complete-user-profile-modal/validation.ts b/packages/core/src/App/Containers/Modals/complete-user-profile-modal/validation.ts index 8cb9a9adc092..3bf2466b9fbf 100644 --- a/packages/core/src/App/Containers/Modals/complete-user-profile-modal/validation.ts +++ b/packages/core/src/App/Containers/Modals/complete-user-profile-modal/validation.ts @@ -24,6 +24,11 @@ export const ValidationSchema = (is_svg: boolean, account_settings?: Record schema, }), + place_of_birth: Yup.string().when([], { + is: () => !account_settings?.place_of_birth, + then: schema => schema.required(localize('Place of birth is required.')), + otherwise: schema => schema, + }), citizen: Yup.string().when([], { is: () => !account_settings?.citizen, then: schema => schema.required(localize('Citizenship is required.')), From 58d286cb0a8c8c57a9d1c817730a002a5e608db1 Mon Sep 17 00:00:00 2001 From: aizad-deriv Date: Fri, 29 Aug 2025 15:16:11 +0800 Subject: [PATCH 3/3] chore: added new improvements --- .../complete-user-profile-modal.tsx | 82 ++++++++++++++++--- 1 file changed, 71 insertions(+), 11 deletions(-) diff --git a/packages/core/src/App/Containers/Modals/complete-user-profile-modal/complete-user-profile-modal.tsx b/packages/core/src/App/Containers/Modals/complete-user-profile-modal/complete-user-profile-modal.tsx index d30f68bb82a0..caa8c8a5dbfa 100644 --- a/packages/core/src/App/Containers/Modals/complete-user-profile-modal/complete-user-profile-modal.tsx +++ b/packages/core/src/App/Containers/Modals/complete-user-profile-modal/complete-user-profile-modal.tsx @@ -340,7 +340,7 @@ const CompleteUserProfile = observer( { - if ( - !e.target.value && - values.citizen - ) { + const typed_value = + e.target.value.trim(); + + if (typed_value) { + const exact_match = + residence_list.find( + item => + item.text.toLowerCase() === + typed_value.toLowerCase() + ); + + if (exact_match) { + // If exact match found, use the country code (value) + setFieldValue( + 'place_of_birth', + exact_match.value, + true + ); + setPlaceOfBirthToDisplay( + exact_match.text + ); + } else { + // If no exact match, clear the field + setFieldValue( + 'place_of_birth', + '', + true + ); + setPlaceOfBirthToDisplay( + '' + ); + } + } else if (values.place_of_birth) { + // If input is empty but there's a stored value, restore the display setPlaceOfBirthToDisplay( residence_list.find( item => item.value === - values.place_of_birth - )?.text || - values.place_of_birth + values.citizen + )?.text || values.citizen ); } + field.onBlur(e); }} /> @@ -442,7 +476,7 @@ const CompleteUserProfile = observer( { - if (!e.target.value && values.citizen) { + const typed_value = e.target.value.trim(); + + if (typed_value) { + const exact_match = residence_list.find( + item => + item.text.toLowerCase() === + typed_value.toLowerCase() + ); + + if (exact_match) { + // If exact match found, use the country code (value) + setFieldValue( + 'citizen', + exact_match.value, + true + ); + setCitizenToDisplay( + exact_match.text + ); + } else { + // If no exact match, clear the field + setFieldValue('citizen', '', true); + setCitizenToDisplay(''); + } + } else if (values.citizen) { + // If input is empty but there's a stored value, restore the display setCitizenToDisplay( residence_list.find( item => @@ -474,6 +533,7 @@ const CompleteUserProfile = observer( )?.text || values.citizen ); } + field.onBlur(e); }} />