Skip to content

Commit

Permalink
Merge pull request #37218 from Expensify/revert-35307-ts-migration/Se…
Browse files Browse the repository at this point in the history
…ttingsProfileDetails

Revert "[TS migration] Migrate 'SettingsProfileDetails' page to TypeScript"
  • Loading branch information
roryabraham authored Feb 26, 2024
2 parents 0ae5885 + 7a04a49 commit 066d6c8
Show file tree
Hide file tree
Showing 14 changed files with 280 additions and 246 deletions.
2 changes: 1 addition & 1 deletion src/components/Form/FormWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function FormWrapper({
buttonText={submitButtonText}
isAlertVisible={((!isEmptyObject(errors) || !isEmptyObject(formState?.errorFields)) && !shouldHideFixErrorsAlert) || !!errorMessage}
isLoading={!!formState?.isLoading}
message={typeof errorMessage === 'string' && isEmptyObject(formState?.errorFields) ? errorMessage : undefined}
message={isEmptyObject(formState?.errorFields) ? errorMessage : undefined}
onSubmit={onSubmit}
footerContent={footerContent}
onFixTheErrorsLinkPressed={onFixTheErrorsLinkPressed}
Expand Down
9 changes: 2 additions & 7 deletions src/components/Form/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ import type AmountForm from '@components/AmountForm';
import type AmountTextInput from '@components/AmountTextInput';
import type CheckboxWithLabel from '@components/CheckboxWithLabel';
import type CountrySelector from '@components/CountrySelector';
import type DatePicker from '@components/DatePicker';
import type Picker from '@components/Picker';
import type RadioButtons from '@components/RadioButtons';
import type SingleChoiceQuestion from '@components/SingleChoiceQuestion';
import type StatePicker from '@components/StatePicker';
import type TextInput from '@components/TextInput';
import type ValuePicker from '@components/ValuePicker';
import type {MaybePhraseKey} from '@libs/Localize';
import type BusinessTypePicker from '@pages/ReimbursementAccount/BusinessInfo/substeps/TypeBusiness/BusinessTypePicker';
import type {TranslationPaths} from '@src/languages/types';
import type {OnyxFormKey, OnyxValues} from '@src/ONYXKEYS';
import type {BaseForm} from '@src/types/form/Form';

Expand All @@ -36,7 +35,6 @@ type ValidInputs =
| typeof AmountForm
| typeof BusinessTypePicker
| typeof StatePicker
| typeof DatePicker
| typeof ValuePicker
| typeof RadioButtons;

Expand Down Expand Up @@ -66,9 +64,6 @@ type InputComponentBaseProps<TValue extends ValueTypeKey = ValueTypeKey> = Input
isFocused?: boolean;
measureLayout?: (ref: unknown, callback: MeasureLayoutOnSuccessCallback) => void;
focus?: () => void;
label?: string;
minDate?: Date;
maxDate?: Date;
onTouched?: (event: GestureResponderEvent) => void;
onBlur?: (event: FocusEvent | NativeSyntheticEvent<TextInputFocusEventData>) => void;
onPressOut?: (event: GestureResponderEvent) => void;
Expand Down Expand Up @@ -126,6 +121,6 @@ type FormProps<TFormID extends OnyxFormKey = OnyxFormKey> = {

type InputRefs = Record<string, MutableRefObject<InputComponentBaseProps>>;

type FormInputErrors<TFormID extends OnyxFormKey = OnyxFormKey> = Partial<Record<FormOnyxKeys<TFormID>, MaybePhraseKey>>;
type FormInputErrors<TFormID extends OnyxFormKey = OnyxFormKey> = Partial<Record<FormOnyxKeys<TFormID>, TranslationPaths>>;

export type {FormProps, ValidInputs, InputComponentValueProps, FormValue, ValueTypeKey, FormOnyxValues, FormOnyxKeys, FormInputErrors, InputRefs, InputComponentBaseProps, ValueTypeMap};
10 changes: 1 addition & 9 deletions src/libs/GetPhysicalCardUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,7 @@ function getUpdatedPrivatePersonalDetails(draftValues: OnyxEntry<GetPhysicalCard
legalFirstName,
legalLastName,
phoneNumber,
address: {
street: PersonalDetailsUtils.getFormattedStreet(addressLine1, addressLine2),
city,
country,
state,
zip: zipPostCode,
addressLine1: addressLine1 ?? '',
zipPostCode: zipPostCode ?? '',
},
address: {street: PersonalDetailsUtils.getFormattedStreet(addressLine1, addressLine2), city, country, state, zip: zipPostCode},
};
}

Expand Down
9 changes: 2 additions & 7 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,8 @@ type SettingsNavigatorParamList = {
[SCREENS.SETTINGS.PROFILE.TIMEZONE_SELECT]: undefined;
[SCREENS.SETTINGS.PROFILE.LEGAL_NAME]: undefined;
[SCREENS.SETTINGS.PROFILE.DATE_OF_BIRTH]: undefined;
[SCREENS.SETTINGS.PROFILE.ADDRESS]: {
country?: string;
};
[SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY]: {
backTo?: Routes;
country: string;
};
[SCREENS.SETTINGS.PROFILE.ADDRESS]: undefined;
[SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY]: undefined;
[SCREENS.SETTINGS.PROFILE.CONTACT_METHODS]: {
backTo: Routes;
};
Expand Down
4 changes: 2 additions & 2 deletions src/libs/PersonalDetailsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,8 @@ function getStreetLines(street = '') {
* @param privatePersonalDetails - details object
* @returns - formatted address
*/
function getFormattedAddress(privatePersonalDetails: OnyxEntry<PrivatePersonalDetails>): string {
const {address} = privatePersonalDetails ?? {};
function getFormattedAddress(privatePersonalDetails: PrivatePersonalDetails): string {
const {address} = privatePersonalDetails;
const [street1, street2] = getStreetLines(address?.street);
const formattedAddress =
formatPiece(street1) + formatPiece(street2) + formatPiece(address?.city) + formatPiece(address?.state) + formatPiece(address?.zip) + formatPiece(address?.country);
Expand Down
5 changes: 2 additions & 3 deletions src/libs/ValidationUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type {OnyxFormKey} from '@src/ONYXKEYS';
import type {Report} from '@src/types/onyx';
import * as CardUtils from './CardUtils';
import DateUtils from './DateUtils';
import type {MaybePhraseKey} from './Localize';
import * as LoginUtils from './LoginUtils';
import {parsePhoneNumber} from './PhoneNumber';
import StringUtils from './StringUtils';
Expand Down Expand Up @@ -191,7 +190,7 @@ function meetsMaximumAgeRequirement(date: string): boolean {
/**
* Validate that given date is in a specified range of years before now.
*/
function getAgeRequirementError(date: string, minimumAge: number, maximumAge: number): MaybePhraseKey {
function getAgeRequirementError(date: string, minimumAge: number, maximumAge: number): string | Array<string | Record<string, string>> {
const currentDate = startOfDay(new Date());
const testDate = parse(date, CONST.DATE.FNS_FORMAT_STRING, currentDate);

Expand Down Expand Up @@ -361,7 +360,7 @@ function isValidPersonName(value: string) {
/**
* Checks if the provided string includes any of the provided reserved words
*/
function doesContainReservedWord(value: string, reservedWords: typeof CONST.DISPLAY_NAME.RESERVED_NAMES): boolean {
function doesContainReservedWord(value: string, reservedWords: string[]): boolean {
const valueToCheck = value.trim().toLowerCase();
return reservedWords.some((reservedWord) => valueToCheck.includes(reservedWord.toLowerCase()));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {StackScreenProps} from '@react-navigation/stack';
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import AddressForm from '@components/AddressForm';
import FullscreenLoadingIndicator from '@components/FullscreenLoadingIndicator';
Expand All @@ -10,47 +10,66 @@ import useLocalize from '@hooks/useLocalize';
import usePrivatePersonalDetails from '@hooks/usePrivatePersonalDetails';
import useThemeStyles from '@hooks/useThemeStyles';
import Navigation from '@libs/Navigation/Navigation';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import * as PersonalDetails from '@userActions/PersonalDetails';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';
import type {PrivatePersonalDetails} from '@src/types/onyx';
import type {Address} from '@src/types/onyx/PrivatePersonalDetails';

type AddressPageOnyxProps = {
const propTypes = {
/* Onyx Props */

/** User's private personal details */
privatePersonalDetails: OnyxEntry<PrivatePersonalDetails>;
privatePersonalDetails: PropTypes.shape({
/** User's home address */
address: PropTypes.shape({
street: PropTypes.string,
city: PropTypes.string,
state: PropTypes.string,
zip: PropTypes.string,
country: PropTypes.string,
}),
}),

/** Route from navigation */
route: PropTypes.shape({
/** Params from the route */
params: PropTypes.shape({
/** Currently selected country */
country: PropTypes.string,
}),
}).isRequired,
};

type AddressPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.SETTINGS.PROFILE.ADDRESS> & AddressPageOnyxProps;
const defaultProps = {
privatePersonalDetails: {
address: {
street: '',
city: '',
state: '',
zip: '',
country: '',
},
},
};

/**
* Submit form to update user's first and last legal name
* @param values - form input values
* @param {Object} values - form input values
*/
function updateAddress(values: Address) {
PersonalDetails.updateAddress(
values.addressLine1.trim(),
values.addressLine2?.trim() ?? '',
values.city.trim(),
values.state.trim(),
values?.zipPostCode.trim().toUpperCase(),
values.country,
);
function updateAddress(values) {
PersonalDetails.updateAddress(values.addressLine1.trim(), values.addressLine2.trim(), values.city.trim(), values.state.trim(), values.zipPostCode.trim().toUpperCase(), values.country);
}

function AddressPage({privatePersonalDetails, route}: AddressPageProps) {
function AddressPage({privatePersonalDetails, route}) {
const styles = useThemeStyles();
usePrivatePersonalDetails();
const {translate} = useLocalize();
const address = useMemo(() => privatePersonalDetails?.address, [privatePersonalDetails]);
const countryFromUrl = route.params?.country;
const [currentCountry, setCurrentCountry] = useState(address?.country);
const isLoadingPersonalDetails = privatePersonalDetails?.isLoading ?? true;
const [street1, street2] = (address?.street ?? '').split('\n');
const [state, setState] = useState(address?.state);
const [city, setCity] = useState(address?.city);
const [zipcode, setZipcode] = useState(address?.zip);
const address = useMemo(() => lodashGet(privatePersonalDetails, 'address') || {}, [privatePersonalDetails]);
const countryFromUrl = lodashGet(route, 'params.country');
const [currentCountry, setCurrentCountry] = useState(address.country);
const isLoadingPersonalDetails = lodashGet(privatePersonalDetails, 'isLoading', true);
const [street1, street2] = (address.street || '').split('\n');
const [state, setState] = useState(address.state);
const [city, setCity] = useState(address.city);
const [zipcode, setZipcode] = useState(address.zip);

useEffect(() => {
if (!address) {
Expand All @@ -62,7 +81,7 @@ function AddressPage({privatePersonalDetails, route}: AddressPageProps) {
setZipcode(address.zip);
}, [address]);

const handleAddressChange = useCallback((value: string, key: keyof Address) => {
const handleAddressChange = useCallback((value, key) => {
if (key !== 'country' && key !== 'state' && key !== 'city' && key !== 'zipPostCode') {
return;
}
Expand Down Expand Up @@ -124,9 +143,11 @@ function AddressPage({privatePersonalDetails, route}: AddressPageProps) {
);
}

AddressPage.propTypes = propTypes;
AddressPage.defaultProps = defaultProps;
AddressPage.displayName = 'AddressPage';

export default withOnyx<AddressPageProps, AddressPageOnyxProps>({
export default withOnyx({
privatePersonalDetails: {
key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,46 @@
import type {StackScreenProps} from '@react-navigation/stack';
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {useCallback, useMemo, useState} from 'react';
import _ from 'underscore';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import ScreenWrapper from '@components/ScreenWrapper';
import SelectionList from '@components/SelectionList';
import RadioListItem from '@components/SelectionList/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import Navigation from '@libs/Navigation/Navigation';
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
import type {CountryData} from '@libs/searchCountryOptions';
import searchCountryOptions from '@libs/searchCountryOptions';
import StringUtils from '@libs/StringUtils';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type {Route} from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';

type CountrySelectionPageProps = StackScreenProps<SettingsNavigatorParamList, typeof SCREENS.SETTINGS.PROFILE.ADDRESS_COUNTRY>;
const propTypes = {
/** Route from navigation */
route: PropTypes.shape({
/** Params from the route */
params: PropTypes.shape({
/** Currently selected country */
country: PropTypes.string,

function CountrySelectionPage({route, navigation}: CountrySelectionPageProps) {
/** Route to navigate back after selecting a currency */
backTo: PropTypes.string,
}),
}).isRequired,

/** Navigation from react-navigation */
navigation: PropTypes.shape({
/** getState function retrieves the current navigation state from react-navigation's navigation property */
getState: PropTypes.func.isRequired,
}).isRequired,
};

function CountrySelectionPage({route, navigation}) {
const [searchValue, setSearchValue] = useState('');
const {translate} = useLocalize();
const currentCountry = route.params.country;
const currentCountry = lodashGet(route, 'params.country');

const countries = useMemo(
() =>
Object.keys(CONST.ALL_COUNTRIES).map((countryISO) => {
const countryName = translate(`allCountries.${countryISO}` as TranslationPaths);
_.map(_.keys(CONST.ALL_COUNTRIES), (countryISO) => {
const countryName = translate(`allCountries.${countryISO}`);
return {
value: countryISO,
keyForList: countryISO,
Expand All @@ -41,18 +56,19 @@ function CountrySelectionPage({route, navigation}: CountrySelectionPageProps) {
const headerMessage = searchValue.trim() && !searchResults.length ? translate('common.noResultsFound') : '';

const selectCountry = useCallback(
(option: CountryData) => {
const backTo = route.params.backTo ?? '';
(option) => {
const backTo = lodashGet(route, 'params.backTo', '');

// Check the navigation state and "backTo" parameter to decide navigation behavior
if (navigation.getState().routes.length === 1 && !backTo) {
if (navigation.getState().routes.length === 1 && _.isEmpty(backTo)) {
// If there is only one route and "backTo" is empty, go back in navigation
Navigation.goBack();
} else if (!!backTo && navigation.getState().routes.length === 1) {
} else if (!_.isEmpty(backTo) && navigation.getState().routes.length === 1) {
// If "backTo" is not empty and there is only one route, go back to the specific route defined in "backTo" with a country parameter
Navigation.goBack(`${route.params.backTo}?country=${option.value}` as Route);
Navigation.goBack(`${route.params.backTo}?country=${option.value}`);
} else {
// Otherwise, navigate to the specific route defined in "backTo" with a country parameter
Navigation.navigate(`${route.params.backTo}?country=${option.value}` as Route);
Navigation.navigate(`${route.params.backTo}?country=${option.value}`);
}
},
[route, navigation],
Expand All @@ -67,9 +83,9 @@ function CountrySelectionPage({route, navigation}: CountrySelectionPageProps) {
title={translate('common.country')}
shouldShowBackButton
onBackButtonPress={() => {
const backTo = route.params.backTo ?? '';
const backToRoute = backTo ? (`${backTo}?country=${currentCountry}` as const) : '';
Navigation.goBack(backToRoute as Route);
const backTo = lodashGet(route, 'params.backTo', '');
const backToRoute = backTo ? `${backTo}?country=${currentCountry}` : '';
Navigation.goBack(backToRoute);
}}
/>

Expand All @@ -89,5 +105,6 @@ function CountrySelectionPage({route, navigation}: CountrySelectionPageProps) {
}

CountrySelectionPage.displayName = 'CountrySelectionPage';
CountrySelectionPage.propTypes = propTypes;

export default CountrySelectionPage;
Loading

0 comments on commit 066d6c8

Please sign in to comment.