From 30d6f08da52b1aaf04c09a6636882b82341bfba5 Mon Sep 17 00:00:00 2001 From: Vit Horacek <36083550+mountiny@users.noreply.github.com> Date: Mon, 25 May 2026 14:44:22 +0200 Subject: [PATCH] Revert "Re-apply secure private personal details + fix address autocomplete and country auto-fill" --- package-lock.json | 12 +- src/CONST/index.ts | 821 ++++++++++++++++++ src/ROUTES.ts | 6 - src/SCREENS.ts | 2 - src/components/AddressForm.tsx | 7 +- src/languages/de.ts | 3 +- src/languages/en.ts | 3 +- src/languages/es.ts | 3 +- src/languages/fr.ts | 3 +- src/languages/it.ts | 3 +- src/languages/ja.ts | 3 +- src/languages/nl.ts | 3 +- src/languages/pl.ts | 3 +- src/languages/pt-BR.ts | 3 +- src/languages/zh-hans.ts | 3 +- .../UpdatePrivatePersonalDetailsParams.ts | 16 - src/libs/API/parameters/index.ts | 1 - src/libs/API/types.ts | 2 - .../ModalStackNavigators/index.tsx | 6 - .../RELATIONS/SETTINGS_TO_RHP.ts | 2 - src/libs/Navigation/linkingConfig/config.ts | 8 - src/libs/Navigation/types.ts | 4 - src/libs/PersonalDetailsUtils.ts | 24 - src/libs/actions/PersonalDetails.ts | 53 -- .../subPages/Address.tsx | 7 +- .../AddressFormFields.tsx | 2 +- ...atePersonalDetailsConfirmMagicCodePage.tsx | 81 -- .../PrivatePersonalDetailsPage.tsx | 414 --------- src/pages/settings/Profile/ProfilePage.tsx | 41 +- 29 files changed, 875 insertions(+), 664 deletions(-) delete mode 100644 src/libs/API/parameters/UpdatePrivatePersonalDetailsParams.ts delete mode 100644 src/pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsConfirmMagicCodePage.tsx delete mode 100644 src/pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsPage.tsx diff --git a/package-lock.json b/package-lock.json index 80fd5680ad4..6b898b3163e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23823,6 +23823,12 @@ "ua-parser-js": "^1.0.38" } }, + "node_modules/expensify-common/node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, "node_modules/expensify-common/node_modules/semver": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", @@ -31026,9 +31032,9 @@ } }, "node_modules/lodash": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz", + "integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==", "license": "MIT" }, "node_modules/lodash-es": { diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 37645e8ba0c..037b4934aaf 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -5481,6 +5481,827 @@ const CONST = { SEK: 'SE', } as Record, + // Sources: https://github.com/Expensify/App/issues/14958#issuecomment-1442138427 + // https://github.com/Expensify/App/issues/14958#issuecomment-1456026810 + COUNTRY_ZIP_REGEX_DATA: { + AC: { + regex: /^ASCN 1ZZ$/, + samples: 'ASCN 1ZZ', + }, + AD: { + regex: /^AD[1-7]0\d$/, + samples: 'AD206, AD403, AD106, AD406', + }, + + // We have kept the empty object for the countries which do not have any zip code validation + // to ensure consistency so that the amount of countries displayed and in this object are same + AE: {}, + AF: { + regex: /^\d{4}$/, + samples: '9536, 1476, 3842, 7975', + }, + AG: {}, + AI: { + regex: /^AI-2640$/, + samples: 'AI-2640', + }, + AL: { + regex: /^\d{4}$/, + samples: '1631, 9721, 2360, 5574', + }, + AM: { + regex: /^\d{4}$/, + samples: '5581, 7585, 8434, 2492', + }, + AO: {}, + AQ: {}, + AR: { + regex: /^((?:[A-HJ-NP-Z])?\d{4})([A-Z]{3})?$/, + samples: 'Q7040GFQ, K2178ZHR, P6240EJG, J6070IAE', + }, + AS: { + regex: /^96799$/, + samples: '96799', + }, + AT: { + regex: /^\d{4}$/, + samples: '4223, 2052, 3544, 5488', + }, + AU: { + regex: /^\d{4}$/, + samples: '7181, 7735, 9169, 8780', + }, + AW: {}, + AX: { + regex: /^22\d{3}$/, + samples: '22270, 22889, 22906, 22284', + }, + AZ: { + regex: /^(AZ) (\d{4})$/, + samples: 'AZ 6704, AZ 5332, AZ 3907, AZ 6892', + }, + BA: { + regex: /^\d{5}$/, + samples: '62722, 80420, 44595, 74614', + }, + BB: { + regex: /^BB\d{5}$/, + samples: 'BB64089, BB17494, BB73163, BB25752', + }, + BD: { + regex: /^\d{4}$/, + samples: '8585, 8175, 7381, 0154', + }, + BE: { + regex: /^\d{4}$/, + samples: '7944, 5303, 6746, 7921', + }, + BF: {}, + BG: { + regex: /^\d{4}$/, + samples: '6409, 7657, 1206, 7908', + }, + BH: { + regex: /^\d{3}\d?$/, + samples: '047, 1116, 490, 631', + }, + BI: {}, + BJ: {}, + BL: { + regex: /^97133$/, + samples: '97133', + }, + BM: { + regex: /^[A-Z]{2} ?[A-Z0-9]{2}$/, + samples: 'QV9P, OSJ1, PZ 3D, GR YK', + }, + BN: { + regex: /^[A-Z]{2} ?\d{4}$/, + samples: 'PF 9925, TH1970, SC 4619, NF0781', + }, + BO: {}, + BQ: {}, + BR: { + regex: /^\d{5}-?\d{3}$/, + samples: '18816-403, 95177-465, 43447-782, 39403-136', + }, + BS: {}, + BT: { + regex: /^\d{5}$/, + samples: '28256, 52484, 30608, 93524', + }, + BW: {}, + BY: { + regex: /^\d{6}$/, + samples: '504154, 360246, 741167, 895047', + }, + BZ: {}, + CA: { + regex: /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJ-NPRSTV-Z] ?\d[ABCEGHJ-NPRSTV-Z]\d$/, + samples: 'S1A7K8, Y5H 4G6, H9V0P2, H1A1B5', + }, + CC: { + regex: /^6799$/, + samples: '6799', + }, + CD: {}, + CF: {}, + CG: {}, + CH: { + regex: /^\d{4}$/, + samples: '6370, 5271, 7873, 8220', + }, + CI: {}, + CK: {}, + CL: { + regex: /^\d{7}$/, + samples: '7565829, 8702008, 3161669, 1607703', + }, + CM: {}, + CN: { + regex: /^\d{6}$/, + samples: '240543, 870138, 295528, 861683', + }, + CO: { + regex: /^\d{6}$/, + samples: '678978, 775145, 823943, 913970', + }, + CR: { + regex: /^\d{5}$/, + samples: '28256, 52484, 30608, 93524', + }, + CU: { + regex: /^(?:CP)?(\d{5})$/, + samples: '28256, 52484, 30608, 93524', + }, + CV: { + regex: /^\d{4}$/, + samples: '9056, 8085, 0491, 4627', + }, + CW: {}, + CX: { + regex: /^6798$/, + samples: '6798', + }, + CY: { + regex: /^\d{4}$/, + samples: '9301, 2478, 1981, 6162', + }, + CZ: { + regex: /^\d{3} ?\d{2}$/, + samples: '150 56, 50694, 229 08, 82811', + }, + DE: { + regex: /^\d{5}$/, + samples: '33185, 37198, 81711, 44262', + }, + DJ: {}, + DK: { + regex: /^\d{4}$/, + samples: '1429, 2457, 0637, 5764', + }, + DM: {}, + DO: { + regex: /^\d{5}$/, + samples: '11877, 95773, 93875, 98032', + }, + DZ: { + regex: /^\d{5}$/, + samples: '26581, 64621, 57550, 72201', + }, + EC: { + regex: /^\d{6}$/, + samples: '541124, 873848, 011495, 334509', + }, + EE: { + regex: /^\d{5}$/, + samples: '87173, 01127, 73214, 52381', + }, + EG: { + regex: /^\d{5}$/, + samples: '98394, 05129, 91463, 77359', + }, + EH: { + regex: /^\d{5}$/, + samples: '30577, 60264, 16487, 38593', + }, + ER: {}, + ES: { + regex: /^\d{5}$/, + samples: '03315, 00413, 23179, 89324', + }, + ET: { + regex: /^\d{4}$/, + samples: '6269, 8498, 4514, 7820', + }, + FI: { + regex: /^\d{5}$/, + samples: '21859, 72086, 22422, 03774', + }, + FJ: {}, + FK: { + regex: /^FIQQ 1ZZ$/, + samples: 'FIQQ 1ZZ', + }, + FM: { + regex: /^(9694[1-4])(?:[ -](\d{4}))?$/, + samples: '96942-9352, 96944-4935, 96941 9065, 96943-5369', + }, + FO: { + regex: /^\d{3}$/, + samples: '334, 068, 741, 787', + }, + FR: { + regex: /^\d{2} ?\d{3}$/, + samples: '25822, 53 637, 55354, 82522', + }, + GA: {}, + GB: { + regex: /^[A-Z]{1,2}[0-9R][0-9A-Z]?\s*([0-9][ABD-HJLNP-UW-Z]{2})?$/, + samples: 'LA102UX, BL2F8FX, BD1S9LU, WR4G 6LH, W1U', + }, + GD: {}, + GE: { + regex: /^\d{4}$/, + samples: '1232, 9831, 4717, 9428', + }, + GF: { + regex: /^9[78]3\d{2}$/, + samples: '98380, 97335, 98344, 97300', + }, + GG: { + regex: /^GY\d[\dA-Z]? ?\d[ABD-HJLN-UW-Z]{2}$/, + samples: 'GY757LD, GY6D 6XL, GY3Y2BU, GY85 1YO', + }, + GH: {}, + GI: { + regex: /^GX11 1AA$/, + samples: 'GX11 1AA', + }, + GL: { + regex: /^39\d{2}$/, + samples: '3964, 3915, 3963, 3956', + }, + GM: {}, + GN: { + regex: /^\d{3}$/, + samples: '465, 994, 333, 078', + }, + GP: { + regex: /^9[78][01]\d{2}$/, + samples: '98069, 97007, 97147, 97106', + }, + GQ: {}, + GR: { + regex: /^\d{3} ?\d{2}$/, + samples: '98654, 319 78, 127 09, 590 52', + }, + GS: { + regex: /^SIQQ 1ZZ$/, + samples: 'SIQQ 1ZZ', + }, + GT: { + regex: /^\d{5}$/, + samples: '30553, 69925, 09376, 83719', + }, + GU: { + regex: /^((969)[1-3][0-2])$/, + samples: '96922, 96932, 96921, 96911', + }, + GW: { + regex: /^\d{4}$/, + samples: '1742, 7941, 4437, 7728', + }, + GY: {}, + HK: { + regex: /^999077$|^$/, + samples: '999077', + }, + HN: { + regex: /^\d{5}$/, + samples: '86238, 78999, 03594, 30406', + }, + HR: { + regex: /^\d{5}$/, + samples: '85240, 80710, 78235, 98766', + }, + HT: { + regex: /^(?:HT)?(\d{4})$/, + samples: '5101, HT6991, HT3871, 1126', + }, + HU: { + regex: /^\d{4}$/, + samples: '0360, 2604, 3362, 4775', + }, + ID: { + regex: /^\d{5}$/, + samples: '60993, 52656, 16521, 34931', + }, + IE: {}, + IL: { + regex: /^\d{5}(?:\d{2})?$/, + samples: '74213, 6978354, 2441689, 4971551', + }, + IM: { + regex: /^IM\d[\dA-Z]? ?\d[ABD-HJLN-UW-Z]{2}$/, + samples: 'IM2X1JP, IM4V 9JU, IM3B1UP, IM8E 5XF', + }, + IN: { + regex: /^\d{6}$/, + samples: '946956, 143659, 243258, 938385', + }, + IO: { + regex: /^BBND 1ZZ$/, + samples: 'BBND 1ZZ', + }, + IQ: { + regex: /^\d{5}$/, + samples: '63282, 87817, 38580, 47725', + }, + IR: { + regex: /^\d{5}-?\d{5}$/, + samples: '0666174250, 6052682188, 02360-81920, 25102-08646', + }, + IS: { + regex: /^\d{3}$/, + samples: '408, 013, 001, 936', + }, + IT: { + regex: /^\d{5}$/, + samples: '31701, 61341, 92781, 45609', + }, + JE: { + regex: /^JE\d[\dA-Z]? ?\d[ABD-HJLN-UW-Z]{2}$/, + samples: 'JE0D 2EX, JE59 2OF, JE1X1ZW, JE0V 1SO', + }, + JM: {}, + JO: { + regex: /^\d{5}$/, + samples: '20789, 02128, 52170, 40284', + }, + JP: { + regex: /^\d{3}-?\d{4}$/, + samples: '5429642, 046-1544, 6463599, 368-5362', + }, + KE: { + regex: /^\d{5}$/, + samples: '33043, 98830, 59324, 42876', + }, + KG: { + regex: /^\d{6}$/, + samples: '500371, 176592, 184133, 225279', + }, + KH: { + regex: /^\d{5,6}$/, + samples: '220281, 18824, 35379, 09570', + }, + KI: { + regex: /^KI\d{4}$/, + samples: 'KI0104, KI0109, KI0112, KI0306', + }, + KM: {}, + KN: { + regex: /^KN\d{4}(-\d{4})?$/, + samples: 'KN2522, KN2560-3032, KN3507, KN4440', + }, + KP: {}, + KR: { + regex: /^\d{5}$/, + samples: '67417, 66648, 08359, 93750', + }, + KW: { + regex: /^\d{5}$/, + samples: '74840, 53309, 71276, 59262', + }, + KY: { + regex: /^KY\d-\d{4}$/, + samples: 'KY0-3078, KY1-7812, KY8-3729, KY3-4664', + }, + KZ: { + regex: /^\d{6}$/, + samples: '129113, 976562, 226811, 933781', + }, + LA: { + regex: /^\d{5}$/, + samples: '08875, 50779, 87756, 75932', + }, + LB: { + regex: /^(?:\d{4})(?: ?(?:\d{4}))?$/, + samples: '5436 1302, 9830 7470, 76911911, 9453 1306', + }, + LC: { + regex: /^(LC)?\d{2} ?\d{3}$/, + samples: '21080, LC99127, LC24 258, 51 740', + }, + LI: { + regex: /^\d{4}$/, + samples: '6644, 2852, 4630, 4541', + }, + LK: { + regex: /^\d{5}$/, + samples: '44605, 27721, 90695, 65514', + }, + LR: { + regex: /^\d{4}$/, + samples: '6644, 2852, 4630, 4541', + }, + LS: { + regex: /^\d{3}$/, + samples: '779, 803, 104, 897', + }, + LT: { + regex: /^((LT)[-])?(\d{5})$/, + samples: 'LT-22248, LT-12796, 69822, 37280', + }, + LU: { + regex: /^((L)[-])?(\d{4})$/, + samples: '5469, L-4476, 6304, 9739', + }, + LV: { + regex: /^((LV)[-])?\d{4}$/, + samples: '9344, LV-5030, LV-0132, 8097', + }, + LY: {}, + MA: { + regex: /^\d{5}$/, + samples: '50219, 95871, 80907, 79804', + }, + MC: { + regex: /^980\d{2}$/, + samples: '98084, 98041, 98070, 98062', + }, + MD: { + regex: /^(MD[-]?)?(\d{4})$/, + samples: '6250, MD-9681, MD3282, MD-0652', + }, + ME: { + regex: /^\d{5}$/, + samples: '87622, 92688, 23129, 59566', + }, + MF: { + regex: /^9[78][01]\d{2}$/, + samples: '97169, 98180, 98067, 98043', + }, + MG: { + regex: /^\d{3}$/, + samples: '854, 084, 524, 064', + }, + MH: { + regex: /^((969)[6-7][0-9])(-\d{4})?/, + samples: '96962, 96969, 96970-8530, 96960-3226', + }, + MK: { + regex: /^\d{4}$/, + samples: '8299, 6904, 6144, 9753', + }, + ML: {}, + MM: { + regex: /^\d{5}$/, + samples: '59188, 93943, 40829, 69981', + }, + MN: { + regex: /^\d{5}$/, + samples: '94129, 29906, 53374, 80141', + }, + MO: {}, + MP: { + regex: /^(9695[012])(?:[ -](\d{4}))?$/, + samples: '96952 3162, 96950 1567, 96951 2994, 96950 8745', + }, + MQ: { + regex: /^9[78]2\d{2}$/, + samples: '98297, 97273, 97261, 98282', + }, + MR: {}, + MS: { + regex: /^[Mm][Ss][Rr]\s{0,1}\d{4}$/, + samples: 'MSR1110, MSR1230, MSR1250, MSR1330', + }, + MT: { + regex: /^[A-Z]{3} [0-9]{4}|[A-Z]{2}[0-9]{2}|[A-Z]{2} [0-9]{2}|[A-Z]{3}[0-9]{4}|[A-Z]{3}[0-9]{2}|[A-Z]{3} [0-9]{2}$/, + samples: 'DKV 8196, KSU9264, QII0259, HKH 1020', + }, + MU: { + regex: /^([0-9A-R]\d{4})$/, + samples: 'H8310, 52591, M9826, F5810', + }, + MV: { + regex: /^\d{5}$/, + samples: '16354, 20857, 50991, 72527', + }, + MW: {}, + MX: { + regex: /^\d{5}$/, + samples: '71530, 76424, 73811, 50503', + }, + MY: { + regex: /^\d{5}$/, + samples: '75958, 15826, 86715, 37081', + }, + MZ: { + regex: /^\d{4}$/, + samples: '0902, 6258, 7826, 7150', + }, + NA: { + regex: /^\d{5}$/, + samples: '68338, 63392, 21820, 61211', + }, + NC: { + regex: /^988\d{2}$/, + samples: '98865, 98813, 98820, 98855', + }, + NE: { + regex: /^\d{4}$/, + samples: '9790, 3270, 2239, 0400', + }, + NF: { + regex: /^2899$/, + samples: '2899', + }, + NG: { + regex: /^\d{6}$/, + samples: '289096, 223817, 199970, 840648', + }, + NI: { + regex: /^\d{5}$/, + samples: '86308, 60956, 49945, 15470', + }, + NL: { + regex: /^\d{4} ?[A-Z]{2}$/, + samples: '6998 VY, 5390 CK, 2476 PS, 8873OX', + }, + NO: { + regex: /^\d{4}$/, + samples: '0711, 4104, 2683, 5015', + }, + NP: { + regex: /^\d{5}$/, + samples: '42438, 73964, 66400, 33976', + }, + NR: { + regex: /^(NRU68)$/, + samples: 'NRU68', + }, + NU: { + regex: /^(9974)$/, + samples: '9974', + }, + NZ: { + regex: /^\d{4}$/, + samples: '7015, 0780, 4109, 1422', + }, + OM: { + regex: /^(?:PC )?\d{3}$/, + samples: 'PC 851, PC 362, PC 598, PC 499', + }, + PA: { + regex: /^\d{4}$/, + samples: '0711, 4104, 2683, 5015', + }, + PE: { + regex: /^\d{5}$/, + samples: '10013, 12081, 14833, 24615', + }, + PF: { + regex: /^987\d{2}$/, + samples: '98755, 98710, 98748, 98791', + }, + PG: { + regex: /^\d{3}$/, + samples: '193, 166, 880, 553', + }, + PH: { + regex: /^\d{4}$/, + samples: '0137, 8216, 2876, 0876', + }, + PK: { + regex: /^\d{5}$/, + samples: '78219, 84497, 62102, 12564', + }, + PL: { + regex: /^\d{2}-\d{3}$/, + samples: '63-825, 26-714, 05-505, 15-200', + }, + PM: { + regex: /^(97500)$/, + samples: '97500', + }, + PN: { + regex: /^PCRN 1ZZ$/, + samples: 'PCRN 1ZZ', + }, + PR: { + regex: /^(00[679]\d{2})(?:[ -](\d{4}))?$/, + samples: '00989 3603, 00639 0720, 00707-9803, 00610 7362', + }, + PS: { + regex: /^(00[679]\d{2})(?:[ -](\d{4}))?$/, + samples: '00748, 00663, 00779-4433, 00934 1559', + }, + PT: { + regex: /^\d{4}-\d{3}$/, + samples: '0060-917, 4391-979, 5551-657, 9961-093', + }, + PW: { + regex: /^(969(?:39|40))(?:[ -](\d{4}))?$/, + samples: '96940, 96939, 96939 6004, 96940-1871', + }, + PY: { + regex: /^\d{4}$/, + samples: '7895, 5835, 8783, 5887', + }, + QA: {}, + RE: { + regex: /^9[78]4\d{2}$/, + samples: '98445, 97404, 98421, 98434', + }, + RO: { + regex: /^\d{6}$/, + samples: '935929, 407608, 637434, 174574', + }, + RS: { + regex: /^\d{5,6}$/, + samples: '929863, 259131, 687739, 07011', + }, + RU: { + regex: /^\d{6}$/, + samples: '138294, 617323, 307906, 981238', + }, + RW: {}, + SA: { + regex: /^\d{5}(-{1}\d{4})?$/, + samples: '86020-1256, 72375, 70280, 96328', + }, + SB: {}, + SC: {}, + SD: { + regex: /^\d{5}$/, + samples: '78219, 84497, 62102, 12564', + }, + SE: { + regex: /^\d{3} ?\d{2}$/, + samples: '095 39, 41052, 84687, 563 66', + }, + SG: { + regex: /^\d{6}$/, + samples: '606542, 233985, 036755, 265255', + }, + SH: { + regex: /^(?:ASCN|TDCU|STHL) 1ZZ$/, + samples: 'STHL 1ZZ, ASCN 1ZZ, TDCU 1ZZ', + }, + SI: { + regex: /^\d{4}$/, + samples: '6898, 3413, 2031, 5732', + }, + SJ: { + regex: /^\d{4}$/, + samples: '7616, 3163, 5769, 0237', + }, + SK: { + regex: /^\d{3} ?\d{2}$/, + samples: '594 52, 813 34, 867 67, 41814', + }, + SL: {}, + SM: { + regex: /^4789\d$/, + samples: '47894, 47895, 47893, 47899', + }, + SN: { + regex: /^[1-8]\d{4}$/, + samples: '48336, 23224, 33261, 82430', + }, + SO: {}, + SR: {}, + SS: { + regex: /^[A-Z]{2} ?\d{5}$/, + samples: 'JQ 80186, CU 46474, DE33738, MS 59107', + }, + ST: {}, + SV: {}, + SX: {}, + SY: {}, + SZ: { + regex: /^[HLMS]\d{3}$/, + samples: 'H458, L986, M477, S916', + }, + TA: { + regex: /^TDCU 1ZZ$/, + samples: 'TDCU 1ZZ', + }, + TC: { + regex: /^TKCA 1ZZ$/, + samples: 'TKCA 1ZZ', + }, + TD: {}, + TF: {}, + TG: {}, + TH: { + regex: /^\d{5}$/, + samples: '30706, 18695, 21044, 42496', + }, + TJ: { + regex: /^\d{6}$/, + samples: '381098, 961344, 519925, 667883', + }, + TK: {}, + TL: {}, + TM: { + regex: /^\d{6}$/, + samples: '544985, 164362, 425224, 374603', + }, + TN: { + regex: /^\d{4}$/, + samples: '6075, 7340, 2574, 8988', + }, + TO: {}, + TR: { + regex: /^\d{5}$/, + samples: '42524, 81057, 50859, 42677', + }, + TT: { + regex: /^\d{6}$/, + samples: '041238, 033990, 763476, 981118', + }, + TV: {}, + TW: { + regex: /^\d{3}(?:\d{2})?$/, + samples: '21577, 76068, 68698, 08912', + }, + TZ: {}, + UA: { + regex: /^\d{5}$/, + samples: '10629, 81138, 15668, 30055', + }, + UG: {}, + UM: {}, + US: { + regex: /^[0-9]{5}(?:[- ][0-9]{4})?$/, + samples: '12345, 12345-1234, 12345 1234', + }, + UY: { + regex: /^\d{5}$/, + samples: '40073, 30136, 06583, 00021', + }, + UZ: { + regex: /^\d{6}$/, + samples: '205122, 219713, 441699, 287471', + }, + VA: { + regex: /^(00120)$/, + samples: '00120', + }, + VC: { + regex: /^VC\d{4}$/, + samples: 'VC0600, VC0176, VC0616, VC4094', + }, + VE: { + regex: /^\d{4}$/, + samples: '9692, 1953, 6680, 8302', + }, + VG: { + regex: /^VG\d{4}$/, + samples: 'VG1204, VG7387, VG3431, VG6021', + }, + VI: { + regex: /^(008(?:(?:[0-4]\d)|(?:5[01])))(?:[ -](\d{4}))?$/, + samples: '00820, 00804 2036, 00825 3344, 00811-5900', + }, + VN: { + regex: /^\d{6}$/, + samples: '133836, 748243, 894060, 020597', + }, + VU: {}, + WF: { + regex: /^986\d{2}$/, + samples: '98692, 98697, 98698, 98671', + }, + WS: { + regex: /^WS[1-2]\d{3}$/, + samples: 'WS1349, WS2798, WS1751, WS2090', + }, + XK: { + regex: /^[1-7]\d{4}$/, + samples: '56509, 15863, 46644, 21896', + }, + YE: {}, + YT: { + regex: /^976\d{2}$/, + samples: '97698, 97697, 97632, 97609', + }, + ZA: { + regex: /^\d{4}$/, + samples: '6855, 5179, 6956, 7147', + }, + ZM: { + regex: /^\d{5}$/, + samples: '77603, 97367, 80454, 94484', + }, + ZW: {}, + }, + + GENERIC_ZIP_CODE_REGEX: /^(?:(?![\s-])[\w -]{0,9}[\w])?$/, + // Values for checking if polyfill is required on a platform POLYFILL_TEST: { STYLE: 'currency', diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 2c9b79f2fc8..3966b0b9e5a 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -384,7 +384,6 @@ const DYNAMIC_ROUTES = { path: 'country', entryScreens: [ SCREENS.SETTINGS.PROFILE.ADDRESS, - SCREENS.SETTINGS.PROFILE.PRIVATE_PERSONAL_DETAILS, SCREENS.WORKSPACE.DYNAMIC_WORKSPACE_OVERVIEW_ADDRESS, SCREENS.SETTINGS.WALLET.CARDS_DIGITAL_DETAILS_UPDATE_ADDRESS, SCREENS.DOMAIN_CARD.DOMAIN_CARD_UPDATE_ADDRESS, @@ -1198,11 +1197,6 @@ const ROUTES = { SETTINGS_DATE_OF_BIRTH: 'settings/profile/date-of-birth', SETTINGS_PHONE_NUMBER: 'settings/profile/phone', SETTINGS_ADDRESS: 'settings/profile/address', - SETTINGS_PRIVATE_PERSONAL_DETAILS: { - route: 'settings/profile/private-personal-details', - getRoute: (fieldToFocus?: string) => `settings/profile/private-personal-details${fieldToFocus ? `?fieldToFocus=${encodeURIComponent(fieldToFocus)}` : ''}` as const, - }, - SETTINGS_PRIVATE_PERSONAL_DETAILS_CONFIRM_MAGIC_CODE: 'settings/profile/private-personal-details/confirm', SETTINGS_ADDRESS_STATE: { route: 'settings/profile/address/state', diff --git a/src/SCREENS.ts b/src/SCREENS.ts index e0efc25942e..8eaebf73b0d 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -161,8 +161,6 @@ const SCREENS = { DATE_OF_BIRTH: 'Settings_DateOfBirth', PHONE_NUMBER: 'Settings_PhoneNumber', ADDRESS: 'Settings_Address', - PRIVATE_PERSONAL_DETAILS: 'Settings_PrivatePersonalDetails', - PRIVATE_PERSONAL_DETAILS_CONFIRM_MAGIC_CODE: 'Settings_PrivatePersonalDetails_ConfirmMagicCode', AVATAR: 'Settings_Avatar', DYNAMIC_ADDRESS_COUNTRY: 'Dynamic_Address_Country', ADDRESS_STATE: 'Settings_Address_State', diff --git a/src/components/AddressForm.tsx b/src/components/AddressForm.tsx index e36d09770bb..e354ecc1c4b 100644 --- a/src/components/AddressForm.tsx +++ b/src/components/AddressForm.tsx @@ -1,4 +1,3 @@ -import {CONST as COMMON_CONST} from 'expensify-common'; import React, {useCallback} from 'react'; import {View} from 'react-native'; import useLocalize from '@hooks/useLocalize'; @@ -82,7 +81,7 @@ function AddressForm({ const styles = useThemeStyles(); const {translate} = useLocalize(); - const zipSampleFormat = (country && (COMMON_CONST.COUNTRY_ZIP_REGEX_DATA[country] as CountryZipRegex)?.samples) ?? ''; + const zipSampleFormat = (country && (CONST.COUNTRY_ZIP_REGEX_DATA[country] as CountryZipRegex)?.samples) ?? ''; const zipFormat = translate('common.zipCodeExampleFormat', zipSampleFormat); @@ -137,7 +136,7 @@ function AddressForm({ } // If no country is selected, default value is an empty string and there's no related regex data so we default to an empty object - const countryRegexDetails = (values.country ? COMMON_CONST.COUNTRY_ZIP_REGEX_DATA?.[values.country] : {}) as CountryZipRegex; + const countryRegexDetails = (values.country ? CONST.COUNTRY_ZIP_REGEX_DATA?.[values.country] : {}) as CountryZipRegex; // The postal code system might not exist for a country, so no regex either for them. const countrySpecificZipRegex = countryRegexDetails?.regex; @@ -151,7 +150,7 @@ function AddressForm({ errors.zipPostCode = translate('common.error.fieldRequired'); } } - } else if (!COMMON_CONST.GENERIC_ZIP_CODE_REGEX.test(values?.zipPostCode?.trim()?.toUpperCase() ?? '')) { + } else if (!CONST.GENERIC_ZIP_CODE_REGEX.test(values?.zipPostCode?.trim()?.toUpperCase() ?? '')) { errors.zipPostCode = translate('privatePersonalDetails.error.incorrectZipFormat'); } diff --git a/src/languages/de.ts b/src/languages/de.ts index 2ab596c7001..ce8c5a714cb 100644 --- a/src/languages/de.ts +++ b/src/languages/de.ts @@ -3330,7 +3330,6 @@ ${amount} für ${merchant} – ${date}`, enterPhoneNumber: 'Wie lautet deine Telefonnummer?', personalDetails: 'Persönliche Angaben', privateDataMessage: 'Diese Angaben werden für Reisen und Zahlungen verwendet. Sie werden niemals in deinem öffentlichen Profil angezeigt.', - basicDetails: 'Grundlegende Angaben', legalName: 'Rechtlicher Name', legalFirstName: 'Rechtlicher Vorname', legalLastName: 'Rechtlicher Nachname', @@ -3525,7 +3524,7 @@ ${amount} für ${merchant} – ${date}`, noBankAccountSelected: 'Bitte wähle ein Konto aus', taxID: 'Bitte geben Sie eine gültige Steueridentifikationsnummer ein', website: 'Bitte eine gültige Website eingeben', - zipCode: `Bitte gib eine gültige Postleitzahl im folgenden Format ein: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `Bitte gib eine gültige Postleitzahl im folgenden Format ein: ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: 'Bitte gib eine gültige Telefonnummer ein', email: 'Bitte gib eine gültige E-Mail-Adresse ein', companyName: 'Bitte gib einen gültigen Unternehmensnamen ein', diff --git a/src/languages/en.ts b/src/languages/en.ts index 653fcec7296..b906821bb14 100644 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3406,7 +3406,6 @@ const translations = { enterPhoneNumber: "What's your phone number?", personalDetails: 'Personal details', privateDataMessage: 'These details are used for travel and payments. They are never shown on your public profile.', - basicDetails: 'Basic details', legalName: 'Legal name', legalFirstName: 'Legal first name', legalLastName: 'Legal last name', @@ -3604,7 +3603,7 @@ const translations = { noBankAccountSelected: 'Please choose an account', taxID: 'Please enter a valid tax ID number', website: 'Please enter a valid website', - zipCode: `Please enter a valid ZIP code using the format: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `Please enter a valid ZIP code using the format: ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: 'Please enter a valid phone number', email: 'Please enter a valid email address', companyName: 'Please enter a valid business name', diff --git a/src/languages/es.ts b/src/languages/es.ts index e9be75ab258..abd929878e6 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3207,7 +3207,6 @@ ${amount} para ${merchant} - ${date}`, enterPhoneNumber: '¿Cuál es tu número de teléfono?', personalDetails: 'Datos personales', privateDataMessage: 'Estos detalles se utilizan para viajes y pagos. Nunca se mostrarán en tu perfil público.', - basicDetails: 'Datos básicos', legalName: 'Nombre completo', legalFirstName: 'Nombre legal', legalLastName: 'Apellidos legales', @@ -3405,7 +3404,7 @@ ${amount} para ${merchant} - ${date}`, noBankAccountSelected: 'Por favor, elige una cuenta bancaria', taxID: 'Por favor, introduce un número de identificación fiscal válido', website: 'Por favor, introduce un sitio web válido', - zipCode: `Formato de código postal incorrecto. Formato aceptable: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}.`, + zipCode: `Formato de código postal incorrecto. Formato aceptable: ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}.`, phoneNumber: 'Por favor, introduce un teléfono válido', email: 'Por favor, introduce una dirección de correo electrónico válida', companyName: 'Por favor, introduce un nombre comercial legal válido', diff --git a/src/languages/fr.ts b/src/languages/fr.ts index f55cc611506..4605fb05181 100644 --- a/src/languages/fr.ts +++ b/src/languages/fr.ts @@ -3338,7 +3338,6 @@ ${amount} pour ${merchant} - ${date}`, enterPhoneNumber: 'Quel est votre numéro de téléphone ?', personalDetails: 'Informations personnelles', privateDataMessage: 'Ces informations sont utilisées pour les déplacements et les paiements. Elles ne s’affichent jamais sur votre profil public.', - basicDetails: 'Détails de base', legalName: 'Nom légal', legalFirstName: 'Prénom légal', legalLastName: 'Nom de famille légal', @@ -3536,7 +3535,7 @@ ${amount} pour ${merchant} - ${date}`, noBankAccountSelected: 'Veuillez choisir un compte', taxID: 'Veuillez saisir un numéro d’identification fiscale valide', website: 'Veuillez saisir un site web valide', - zipCode: `Veuillez saisir un code postal valide au format : ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `Veuillez saisir un code postal valide au format : ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: 'Veuillez saisir un numéro de téléphone valide', email: 'Veuillez saisir une adresse e-mail valide', companyName: 'Veuillez saisir un nom d’entreprise valide', diff --git a/src/languages/it.ts b/src/languages/it.ts index 1c121e97f4e..31c4dadfb11 100644 --- a/src/languages/it.ts +++ b/src/languages/it.ts @@ -3323,7 +3323,6 @@ ${amount} per ${merchant} - ${date}`, enterPhoneNumber: 'Qual è il tuo numero di telefono?', personalDetails: 'Dati personali', privateDataMessage: 'Questi dettagli vengono utilizzati per viaggi e pagamenti. Non vengono mai mostrati sul tuo profilo pubblico.', - basicDetails: 'Dettagli di base', legalName: 'Nome legale', legalFirstName: 'Nome legale di battesimo', legalLastName: 'Cognome legale', @@ -3517,7 +3516,7 @@ ${amount} per ${merchant} - ${date}`, noBankAccountSelected: 'Scegli un account per favore', taxID: 'Inserisci un numero di codice fiscale valido', website: 'Inserisci un sito web valido', - zipCode: `Inserisci un CAP valido usando il formato: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `Inserisci un CAP valido usando il formato: ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: 'Inserisci un numero di telefono valido', email: 'Inserisci un indirizzo email valido', companyName: 'Inserisci un nome aziendale valido', diff --git a/src/languages/ja.ts b/src/languages/ja.ts index 1b0145224a8..ea43439d02c 100644 --- a/src/languages/ja.ts +++ b/src/languages/ja.ts @@ -3296,7 +3296,6 @@ ${integrationName === CONST.ONBOARDING_ACCOUNTING_MAPPING.other ? 'あなたの' enterPhoneNumber: '電話番号は何ですか?', personalDetails: '個人情報', privateDataMessage: 'これらの詳細は出張と支払いに使用されます。公開プロフィールに表示されることは決してありません。', - basicDetails: '基本情報', legalName: '法的氏名', legalFirstName: '法的な名', legalLastName: '法的な姓', @@ -3488,7 +3487,7 @@ ${integrationName === CONST.ONBOARDING_ACCOUNTING_MAPPING.other ? 'あなたの' noBankAccountSelected: 'アカウントを選択してください', taxID: '有効な納税者番号を入力してください', website: '有効なウェブサイトを入力してください', - zipCode: `有効なZIPコードを、次の形式で入力してください: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `有効なZIPコードを、次の形式で入力してください: ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: '有効な電話番号を入力してください', email: '有効なメールアドレスを入力してください', companyName: '有効な会社名を入力してください', diff --git a/src/languages/nl.ts b/src/languages/nl.ts index 15ce8513ac3..c206abbe545 100644 --- a/src/languages/nl.ts +++ b/src/languages/nl.ts @@ -3319,7 +3319,6 @@ ${amount} voor ${merchant} - ${date}`, enterPhoneNumber: 'Wat is je telefoonnummer?', personalDetails: 'Persoonlijke gegevens', privateDataMessage: 'Deze gegevens worden gebruikt voor reizen en betalingen. Ze worden nooit weergegeven op je openbare profiel.', - basicDetails: 'Basisgegevens', legalName: 'Wettelijke naam', legalFirstName: 'Juridische voornaam', legalLastName: 'Wettelijke achternaam', @@ -3512,7 +3511,7 @@ ${amount} voor ${merchant} - ${date}`, noBankAccountSelected: 'Kies een account', taxID: 'Voer een geldig btw-identificatienummer in', website: 'Voer een geldige website in', - zipCode: `Voer een geldige postcode in met het volgende formaat: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `Voer een geldige postcode in met het volgende formaat: ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: 'Voer een geldig telefoonnummer in', email: 'Voer een geldig e-mailadres in', companyName: 'Voer een geldige bedrijfsnaam in', diff --git a/src/languages/pl.ts b/src/languages/pl.ts index aa6de0fd276..508e837cf9f 100644 --- a/src/languages/pl.ts +++ b/src/languages/pl.ts @@ -3312,7 +3312,6 @@ ${amount} dla ${merchant} - ${date}`, enterPhoneNumber: 'Jaki jest Twój numer telefonu?', personalDetails: 'Dane osobiste', privateDataMessage: 'Te dane są używane do podróży i płatności. Nigdy nie są wyświetlane w Twoim publicznym profilu.', - basicDetails: 'Podstawowe dane', legalName: 'Imię i nazwisko (pełne)', legalFirstName: 'Imię (zgodnie z dokumentem tożsamości)', legalLastName: 'Nazwisko zgodne z dokumentami', @@ -3504,7 +3503,7 @@ ${amount} dla ${merchant} - ${date}`, noBankAccountSelected: 'Wybierz konto', taxID: 'Wprowadź prawidłowy numer identyfikacji podatkowej', website: 'Wprowadź prawidłową stronę internetową', - zipCode: `Wprowadź prawidłowy kod ZIP w formacie: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `Wprowadź prawidłowy kod ZIP w formacie: ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: 'Wprowadź prawidłowy numer telefonu', email: 'Wpisz prawidłowy adres e‑mail', companyName: 'Wprowadź prawidłową nazwę firmy', diff --git a/src/languages/pt-BR.ts b/src/languages/pt-BR.ts index 46a328068ab..a4a26d2f68a 100644 --- a/src/languages/pt-BR.ts +++ b/src/languages/pt-BR.ts @@ -3313,7 +3313,6 @@ ${amount} para ${merchant} - ${date}`, enterPhoneNumber: 'Qual é o seu número de telefone?', personalDetails: 'Dados pessoais', privateDataMessage: 'Esses dados são usados para viagens e pagamentos. Eles nunca são exibidos no seu perfil público.', - basicDetails: 'Detalhes básicos', legalName: 'Nome legal', legalFirstName: 'Primeiro nome legal', legalLastName: 'Sobrenome legal', @@ -3505,7 +3504,7 @@ ${amount} para ${merchant} - ${date}`, noBankAccountSelected: 'Escolha uma conta', taxID: 'Insira um número de identificação fiscal válido', website: 'Insira um site válido', - zipCode: `Insira um CEP válido usando o formato: ${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `Insira um CEP válido usando o formato: ${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: 'Insira um número de telefone válido', email: 'Insira um endereço de e-mail válido', companyName: 'Insira um nome comercial válido', diff --git a/src/languages/zh-hans.ts b/src/languages/zh-hans.ts index 05fa78aae4b..c2b3d3c3382 100644 --- a/src/languages/zh-hans.ts +++ b/src/languages/zh-hans.ts @@ -3236,7 +3236,6 @@ ${amount},商户:${merchant} - 日期:${date}`, enterPhoneNumber: '你的电话号码是多少?', personalDetails: '个人信息', privateDataMessage: '这些详细信息将用于出行和付款,绝不会显示在你的公开个人资料中。', - basicDetails: '基本信息', legalName: '法定姓名', legalFirstName: '法定名(名)', legalLastName: '法定姓氏', @@ -3425,7 +3424,7 @@ ${amount},商户:${merchant} - 日期:${date}`, noBankAccountSelected: '请选择一个账户', taxID: '请输入有效的税号', website: '请输入有效的网站', - zipCode: `请输入有效的邮政编码,格式为:${COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, + zipCode: `请输入有效的邮政编码,格式为:${CONST.COUNTRY_ZIP_REGEX_DATA.US.samples}`, phoneNumber: '请输入有效的电话号码', email: '请输入有效的邮箱地址', companyName: '请输入有效的公司名称', diff --git a/src/libs/API/parameters/UpdatePrivatePersonalDetailsParams.ts b/src/libs/API/parameters/UpdatePrivatePersonalDetailsParams.ts deleted file mode 100644 index 177a5dfacfc..00000000000 --- a/src/libs/API/parameters/UpdatePrivatePersonalDetailsParams.ts +++ /dev/null @@ -1,16 +0,0 @@ -type UpdatePrivatePersonalDetailsParams = { - legalFirstName: string; - legalLastName: string; - phoneNumber: string; - addressCity: string; - addressStreet: string; - addressStreet2: string; - addressZip: string; - addressCountry: string; - dob: string; - validateCode: string; - addressState: string; - addressProvince: string; -}; - -export default UpdatePrivatePersonalDetailsParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index d5c1d61fb39..51e87764cee 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -111,7 +111,6 @@ export type {default as UpdateHomeAddressParams} from './UpdateHomeAddressParams export type {default as UpdatePolicyAddressParams} from './UpdatePolicyAddressParams'; export type {default as UpdateLegalNameParams} from './UpdateLegalNameParams'; export type {default as UpdatePhoneNumberParams} from './UpdatePhoneNumberParams'; -export type {default as UpdatePrivatePersonalDetailsParams} from './UpdatePrivatePersonalDetailsParams'; export type {default as UpdateNewsletterSubscriptionParams} from './UpdateNewsletterSubscriptionParams'; export type {default as UpdatePersonalInformationForBankAccountParams} from './UpdatePersonalInformationForBankAccountParams'; export type {default as UpdatePreferredEmojiSkinToneParams} from './UpdatePreferredEmojiSkinToneParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 96c61776cba..539c5b285b6 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -73,7 +73,6 @@ const WRITE_COMMANDS = { UPDATE_DATE_OF_BIRTH: 'UpdateDateOfBirth', UPDATE_PHONE_NUMBER: 'UpdatePhoneNumber', UPDATE_HOME_ADDRESS: 'UpdateHomeAddress', - UPDATE_PRIVATE_PERSONAL_DETAILS: 'UpdatePrivatePersonalDetails', UPDATE_POLICY_ADDRESS: 'SetPolicyAddress', UPDATE_AUTOMATIC_TIMEZONE: 'UpdateAutomaticTimezone', UPDATE_SELECTED_TIMEZONE: 'UpdateSelectedTimezone', @@ -674,7 +673,6 @@ type WriteCommandParameters = { [WRITE_COMMANDS.UPDATE_PHONE_NUMBER]: Parameters.UpdatePhoneNumberParams; [WRITE_COMMANDS.UPDATE_POLICY_ADDRESS]: Parameters.UpdatePolicyAddressParams; [WRITE_COMMANDS.UPDATE_HOME_ADDRESS]: Parameters.UpdateHomeAddressParams; - [WRITE_COMMANDS.UPDATE_PRIVATE_PERSONAL_DETAILS]: Parameters.UpdatePrivatePersonalDetailsParams; [WRITE_COMMANDS.UPDATE_AUTOMATIC_TIMEZONE]: Parameters.UpdateAutomaticTimezoneParams; [WRITE_COMMANDS.UPDATE_SELECTED_TIMEZONE]: Parameters.UpdateSelectedTimezoneParams; [WRITE_COMMANDS.UPDATE_USER_AVATAR]: Parameters.UpdateUserAvatarParams; diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx index 5241583c5d0..9eebea79c35 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx @@ -428,12 +428,6 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../../pages/settings/Profile/PersonalDetails/DateOfBirthPage').default), [SCREENS.SETTINGS.PROFILE.PHONE_NUMBER]: withAgentAccessDenied(() => require('../../../../pages/settings/Profile/PersonalDetails/PhoneNumberPage').default), [SCREENS.SETTINGS.PROFILE.ADDRESS]: withAgentAccessDenied(() => require('../../../../pages/settings/Profile/PersonalDetails/PersonalAddressPage').default), - [SCREENS.SETTINGS.PROFILE.PRIVATE_PERSONAL_DETAILS]: withAgentAccessDenied( - () => require('../../../../pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsPage').default, - ), - [SCREENS.SETTINGS.PROFILE.PRIVATE_PERSONAL_DETAILS_CONFIRM_MAGIC_CODE]: withAgentAccessDenied( - () => require('../../../../pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsConfirmMagicCodePage').default, - ), [SCREENS.SETTINGS.PROFILE.DYNAMIC_ADDRESS_COUNTRY]: withAgentAccessDenied( () => require('../../../../pages/settings/Profile/PersonalDetails/DynamicCountrySelectionPage').default, ), diff --git a/src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts b/src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts index bea4205dbde..8ea3a17509a 100755 --- a/src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts +++ b/src/libs/Navigation/linkingConfig/RELATIONS/SETTINGS_TO_RHP.ts @@ -23,8 +23,6 @@ const SETTINGS_TO_RHP: Partial['config'] = { path: ROUTES.SETTINGS_ADDRESS, exact: true, }, - [SCREENS.SETTINGS.PROFILE.PRIVATE_PERSONAL_DETAILS]: { - path: ROUTES.SETTINGS_PRIVATE_PERSONAL_DETAILS.route, - exact: true, - }, - [SCREENS.SETTINGS.PROFILE.PRIVATE_PERSONAL_DETAILS_CONFIRM_MAGIC_CODE]: { - path: ROUTES.SETTINGS_PRIVATE_PERSONAL_DETAILS_CONFIRM_MAGIC_CODE, - exact: true, - }, [SCREENS.SETTINGS.PROFILE.DYNAMIC_ADDRESS_COUNTRY]: DYNAMIC_ROUTES.ADDRESS_COUNTRY.path, [SCREENS.SETTINGS.PROFILE.ADDRESS_STATE]: { path: ROUTES.SETTINGS_ADDRESS_STATE.route, diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 06d7338abed..675cff9a505 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -81,10 +81,6 @@ type SettingsNavigatorParamList = { [SCREENS.SETTINGS.PROFILE.TIMEZONE_SELECT]: undefined; [SCREENS.SETTINGS.PROFILE.LEGAL_NAME]: undefined; [SCREENS.SETTINGS.PROFILE.DATE_OF_BIRTH]: undefined; - [SCREENS.SETTINGS.PROFILE.PRIVATE_PERSONAL_DETAILS]: { - fieldToFocus?: string; - }; - [SCREENS.SETTINGS.PROFILE.PRIVATE_PERSONAL_DETAILS_CONFIRM_MAGIC_CODE]: undefined; [SCREENS.SETTINGS.PROFILE.ADDRESS]: { country?: Country | ''; }; diff --git a/src/libs/PersonalDetailsUtils.ts b/src/libs/PersonalDetailsUtils.ts index 91bc328f7fb..4a6115b84bd 100644 --- a/src/libs/PersonalDetailsUtils.ts +++ b/src/libs/PersonalDetailsUtils.ts @@ -4,8 +4,6 @@ import Onyx from 'react-native-onyx'; import type {LocaleContextProps, LocalizedTranslate} from '@components/LocaleContextProvider'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {PersonalDetailsForm} from '@src/types/form'; -import INPUT_IDS from '@src/types/form/PersonalDetailsForm'; import type {OnyxInputOrEntry, PersonalDetails, PersonalDetailsList, PrivatePersonalDetails} from '@src/types/onyx'; import type {Address} from '@src/types/onyx/PrivatePersonalDetails'; import type {OnyxData} from '@src/types/onyx/Request'; @@ -320,27 +318,6 @@ function getCurrentAddress(privatePersonalDetails: OnyxEntry, draftValues?: PersonalDetailsForm | null): PersonalDetailsForm { - const address = getCurrentAddress(privatePersonalDetails); - const [street1, street2] = getStreetLines(address?.street); - return { - [INPUT_IDS.LEGAL_FIRST_NAME]: draftValues?.[INPUT_IDS.LEGAL_FIRST_NAME] ?? privatePersonalDetails?.legalFirstName ?? '', - [INPUT_IDS.LEGAL_LAST_NAME]: draftValues?.[INPUT_IDS.LEGAL_LAST_NAME] ?? privatePersonalDetails?.legalLastName ?? '', - [INPUT_IDS.DATE_OF_BIRTH]: draftValues?.[INPUT_IDS.DATE_OF_BIRTH] ?? privatePersonalDetails?.dob ?? '', - [INPUT_IDS.PHONE_NUMBER]: draftValues?.[INPUT_IDS.PHONE_NUMBER] ?? privatePersonalDetails?.phoneNumber ?? '', - [INPUT_IDS.ADDRESS_LINE_1]: draftValues?.[INPUT_IDS.ADDRESS_LINE_1] ?? street1 ?? '', - [INPUT_IDS.ADDRESS_LINE_2]: draftValues?.[INPUT_IDS.ADDRESS_LINE_2] ?? street2 ?? '', - [INPUT_IDS.CITY]: draftValues?.[INPUT_IDS.CITY] ?? address?.city ?? '', - [INPUT_IDS.STATE]: draftValues?.[INPUT_IDS.STATE] ?? address?.state ?? '', - [INPUT_IDS.ZIP_POST_CODE]: draftValues?.[INPUT_IDS.ZIP_POST_CODE] ?? address?.zip ?? '', - [INPUT_IDS.COUNTRY]: draftValues?.[INPUT_IDS.COUNTRY] ?? address?.country ?? '', - }; -} - /** * Formats an address object into an easily readable string * @@ -510,7 +487,6 @@ export { getCurrentAddress, getFormattedAddress, getFormattedStreet, - getPrivatePersonalDetailsFormValues, getStreetLines, getEffectiveDisplayName, createDisplayName, diff --git a/src/libs/actions/PersonalDetails.ts b/src/libs/actions/PersonalDetails.ts index ff2c09fa89d..b5b72114564 100644 --- a/src/libs/actions/PersonalDetails.ts +++ b/src/libs/actions/PersonalDetails.ts @@ -12,7 +12,6 @@ import type { UpdateHomeAddressParams, UpdateLegalNameParams, UpdatePhoneNumberParams, - UpdatePrivatePersonalDetailsParams, UpdatePronounsParams, UpdateSelectedTimezoneParams, UpdateUserAvatarParams, @@ -512,57 +511,6 @@ function deleteAvatar(currentUserPersonalDetails: Pick, validateCode: string, countryCode: number) { - const stateValue = (values.state ?? '').trim(); - const parameters: UpdatePrivatePersonalDetailsParams = { - legalFirstName: values.legalFirstName?.trim() ?? '', - legalLastName: values.legalLastName?.trim() ?? '', - phoneNumber: LoginUtils.appendCountryCode(values.phoneNumber?.trim() ?? '', countryCode), - addressCity: (values.city ?? '').trim(), - addressStreet: values.addressLine1?.trim() ?? '', - addressStreet2: values.addressLine2?.trim() ?? '', - addressZip: values.zipPostCode?.trim().toUpperCase() ?? '', - addressCountry: values.country ?? '', - addressState: stateValue, - addressProvince: values.country !== CONST.COUNTRY.US ? stateValue : '', - dob: values.dob ?? '', - validateCode, - }; - - API.write(WRITE_COMMANDS.UPDATE_PRIVATE_PERSONAL_DETAILS, parameters, { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS, - value: { - isLoading: true, - errorFields: {personalDetails: null}, - }, - }, - ], - successData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS, - value: { - isLoading: false, - }, - }, - ], - failureData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS, - value: { - isLoading: false, - errorFields: {personalDetails: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage')}, - }, - }, - ], }); } @@ -608,7 +556,6 @@ export { clearPhoneNumberError, updatePronouns, updateSelectedTimezone, - updatePrivatePersonalDetails, updatePersonalDetailsAndShipExpensifyCards, clearPersonalDetailsErrors, buildSetPersonalDetailsAndShipExpensifyCardsParams, diff --git a/src/pages/MissingPersonalDetails/subPages/Address.tsx b/src/pages/MissingPersonalDetails/subPages/Address.tsx index ff69362c422..c222f485040 100644 --- a/src/pages/MissingPersonalDetails/subPages/Address.tsx +++ b/src/pages/MissingPersonalDetails/subPages/Address.tsx @@ -1,4 +1,3 @@ -import {CONST as COMMON_CONST} from 'expensify-common'; import React, {useCallback, useRef, useState} from 'react'; import {View} from 'react-native'; import AddressSearch from '@components/AddressSearch'; @@ -78,7 +77,7 @@ function AddressStep({isEditing, onNext, personalDetailsValues}: CustomSubPagePr } // If no country is selected, default value is an empty string and there's no related regex data so we default to an empty object - const countryRegexDetails = (values.country ? COMMON_CONST.COUNTRY_ZIP_REGEX_DATA?.[values.country] : {}) as CountryZipRegex; + const countryRegexDetails = (values.country ? CONST.COUNTRY_ZIP_REGEX_DATA?.[values.country] : {}) as CountryZipRegex; // The postal code system might not exist for a country, so no regex either for them. const countrySpecificZipRegex = countryRegexDetails?.regex; @@ -91,7 +90,7 @@ function AddressStep({isEditing, onNext, personalDetailsValues}: CustomSubPagePr errors[INPUT_IDS.ZIP_POST_CODE] = translate('common.error.fieldRequired'); } } - } else if (!COMMON_CONST.GENERIC_ZIP_CODE_REGEX.test(values[INPUT_IDS.ZIP_POST_CODE]?.trim()?.toUpperCase() ?? '')) { + } else if (!CONST.GENERIC_ZIP_CODE_REGEX.test(values[INPUT_IDS.ZIP_POST_CODE]?.trim()?.toUpperCase() ?? '')) { errors[INPUT_IDS.ZIP_POST_CODE] = translate('privatePersonalDetails.error.incorrectZipFormat'); } return errors; @@ -129,7 +128,7 @@ function AddressStep({isEditing, onNext, personalDetailsValues}: CustomSubPagePr const isUSAForm = currentCountry === CONST.COUNTRY.US; - const zipSampleFormat = (currentCountry && (COMMON_CONST.COUNTRY_ZIP_REGEX_DATA[currentCountry] as CountryZipRegex)?.samples) ?? ''; + const zipSampleFormat = (currentCountry && (CONST.COUNTRY_ZIP_REGEX_DATA[currentCountry] as CountryZipRegex)?.samples) ?? ''; const zipFormat = translate('common.zipCodeExampleFormat', zipSampleFormat); diff --git a/src/pages/ReimbursementAccount/AddressFormFields.tsx b/src/pages/ReimbursementAccount/AddressFormFields.tsx index f4d80781992..c92cb2acd0a 100644 --- a/src/pages/ReimbursementAccount/AddressFormFields.tsx +++ b/src/pages/ReimbursementAccount/AddressFormFields.tsx @@ -190,7 +190,7 @@ function AddressFormFields({ value={values?.zipCode} defaultValue={defaultValues?.zipCode} errorText={errors?.zipCode ? translate('bankAccount.error.zipCode') : ''} - hint={translate('common.zipCodeExampleFormat', COMMON_CONST.COUNTRY_ZIP_REGEX_DATA.US.samples)} + hint={translate('common.zipCodeExampleFormat', CONST.COUNTRY_ZIP_REGEX_DATA.US.samples)} containerStyles={styles.mt3} forwardedFSClass={forwardedFSClass} autoComplete="postal-code" diff --git a/src/pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsConfirmMagicCodePage.tsx b/src/pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsConfirmMagicCodePage.tsx deleted file mode 100644 index bac67536154..00000000000 --- a/src/pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsConfirmMagicCodePage.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React, {useEffect, useRef} from 'react'; -import ValidateCodeActionContent from '@components/ValidateCodeActionModal/ValidateCodeActionContent'; -import useLocalize from '@hooks/useLocalize'; -import useOnyx from '@hooks/useOnyx'; -import usePrimaryContactMethod from '@hooks/usePrimaryContactMethod'; -import {clearPersonalDetailsErrors, updatePrivatePersonalDetails} from '@libs/actions/PersonalDetails'; -import {requestValidateCodeAction, resetValidateActionCodeSent} from '@libs/actions/User'; -import {normalizeCountryCode} from '@libs/CountryUtils'; -import {getLatestErrorField, getLatestErrorMessageField} from '@libs/ErrorUtils'; -import Navigation from '@libs/Navigation/Navigation'; -import {getPrivatePersonalDetailsFormValues} from '@libs/PersonalDetailsUtils'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import type {PersonalDetailsForm} from '@src/types/form'; -import {isEmptyObject} from '@src/types/utils/EmptyObject'; - -function PrivatePersonalDetailsConfirmMagicCodePage() { - const {translate} = useLocalize(); - const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS); - const [draftValues] = useOnyx(ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM_DRAFT); - const [countryCode = CONST.DEFAULT_COUNTRY_CODE] = useOnyx(ONYXKEYS.COUNTRY_CODE); - const primaryLogin = usePrimaryContactMethod(); - - const [validateCodeAction] = useOnyx(ONYXKEYS.VALIDATE_ACTION_CODE); - - // Errors may be written to either errorFields (preferred) or errors depending on - // how the backend reports the failure, so check both. - const personalDetailsErrorField = getLatestErrorField(privatePersonalDetails, 'personalDetails'); - const personalDetailsError = getLatestErrorMessageField(privatePersonalDetails); - const submitError = !isEmptyObject(personalDetailsErrorField) ? personalDetailsErrorField : personalDetailsError; - const hasErrors = !isEmptyObject(submitError) || !isEmptyObject(validateCodeAction?.errorFields); - - const clearError = () => { - if (!hasErrors) { - return; - } - clearPersonalDetailsErrors(); - }; - - const wasLoading = useRef(false); - useEffect(() => { - if (privatePersonalDetails?.isLoading) { - wasLoading.current = true; - return; - } - if (wasLoading.current && !hasErrors) { - wasLoading.current = false; - resetValidateActionCodeSent(); - Navigation.goBack(ROUTES.SETTINGS_PROFILE.route); - } - wasLoading.current = false; - }, [privatePersonalDetails?.isLoading, hasErrors]); - - const values = normalizeCountryCode(getPrivatePersonalDetailsFormValues(privatePersonalDetails, draftValues)) as PersonalDetailsForm; - - const handleSubmitForm = (validateCode: string) => { - updatePrivatePersonalDetails(values, validateCode, countryCode); - }; - - return ( - requestValidateCodeAction()} - validateCodeActionErrorField="personalDetails" - handleSubmitForm={handleSubmitForm} - validateError={submitError} - clearError={clearError} - onClose={() => { - resetValidateActionCodeSent(); - Navigation.goBack(ROUTES.SETTINGS_PRIVATE_PERSONAL_DETAILS.route); - }} - isLoading={privatePersonalDetails?.isLoading} - /> - ); -} - -PrivatePersonalDetailsConfirmMagicCodePage.displayName = 'PrivatePersonalDetailsConfirmMagicCodePage'; - -export default PrivatePersonalDetailsConfirmMagicCodePage; diff --git a/src/pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsPage.tsx b/src/pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsPage.tsx deleted file mode 100644 index 19889cf5664..00000000000 --- a/src/pages/settings/Profile/PersonalDetails/PrivatePersonalDetailsPage.tsx +++ /dev/null @@ -1,414 +0,0 @@ -import {useRoute} from '@react-navigation/native'; -import {subYears} from 'date-fns'; -import {CONST as COMMON_CONST} from 'expensify-common'; -import React, {useEffect, useState} from 'react'; -import {View} from 'react-native'; -import AddressSearch from '@components/AddressSearch'; -import CountrySelector from '@components/CountrySelector'; -import DatePicker from '@components/DatePicker'; -import DelegateNoAccessWrapper from '@components/DelegateNoAccessWrapper'; -import FormProvider from '@components/Form/FormProvider'; -import InputWrapper from '@components/Form/InputWrapper'; -import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; -import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import ScreenWrapper from '@components/ScreenWrapper'; -import type {State} from '@components/StateSelector'; -import StateSelector from '@components/StateSelector'; -import Text from '@components/Text'; -import TextInput from '@components/TextInput'; -import useLocalize from '@hooks/useLocalize'; -import useOnyx from '@hooks/useOnyx'; -import useThemeStyles from '@hooks/useThemeStyles'; -import {clearDraftValues, setDraftValues} from '@libs/actions/FormActions'; -import {normalizeCountryCode} from '@libs/CountryUtils'; -import {appendCountryCode} from '@libs/LoginUtils'; -import Navigation from '@libs/Navigation/Navigation'; -import type {PlatformStackRouteProp} from '@libs/Navigation/PlatformStackNavigation/types'; -import type {SettingsNavigatorParamList} from '@libs/Navigation/types'; -import {getCurrentAddress, getStreetLines} from '@libs/PersonalDetailsUtils'; -import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan'; -import {doesContainReservedWord, getAgeRequirementError, isRequiredFulfilled, isValidDisplayName, isValidPhoneNumber} from '@libs/ValidationUtils'; -import CONST from '@src/CONST'; -import type {Country} from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import ROUTES from '@src/ROUTES'; -import type SCREENS from '@src/SCREENS'; -import INPUT_IDS from '@src/types/form/PersonalDetailsForm'; -import type {Address} from '@src/types/onyx/PrivatePersonalDetails'; - -// StateSelector keys on 2-letter codes, but stored addresses may use full state names (e.g. "California"). -function resolveStateCode(stateValue: string): string { - if (!stateValue || stateValue in COMMON_CONST.STATES) { - return stateValue; - } - const match = Object.entries(COMMON_CONST.STATES).find(([, v]) => v.stateName.toLowerCase() === stateValue.toLowerCase()); - return match ? match[0] : stateValue; -} - -function PrivatePersonalDetailsPage() { - const route = useRoute>(); - const fieldToFocus = route.params?.fieldToFocus; - const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS); - const [isLoadingApp = true] = useOnyx(ONYXKEYS.IS_LOADING_APP); - const [countryCode = CONST.DEFAULT_COUNTRY_CODE] = useOnyx(ONYXKEYS.COUNTRY_CODE); - const [defaultCountry] = useOnyx(ONYXKEYS.COUNTRY); - const styles = useThemeStyles(); - const {translate} = useLocalize(); - - const legalFirstName = privatePersonalDetails?.legalFirstName ?? ''; - const legalLastName = privatePersonalDetails?.legalLastName ?? ''; - const phoneNumber = privatePersonalDetails?.phoneNumber ?? ''; - const dob = privatePersonalDetails?.dob ?? ''; - const address = normalizeCountryCode(getCurrentAddress(privatePersonalDetails)) as Address | undefined; - const [street1, street2Fallback] = getStreetLines(address?.street); - const initialStreet1 = street1 ?? ''; - const initialStreet2 = address?.street2 ?? street2Fallback ?? ''; - const city = address?.city ?? ''; - const state = address?.state ?? ''; - const zip = address?.zip ?? ''; - const country = address?.country ?? ''; - - const normalizedState = resolveStateCode(state); - const [selectedCountry, setSelectedCountry] = useState(country || ((defaultCountry as Country | undefined) ?? '')); - const [selectedState, setSelectedState] = useState(normalizedState); - - useEffect( - () => () => { - clearDraftValues(ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM); - }, - [], - ); - - const validate = (values: FormOnyxValues): FormInputErrors => { - const errors: FormInputErrors = {}; - - const firstNameValue = values[INPUT_IDS.LEGAL_FIRST_NAME] ?? ''; - if (!firstNameValue.trim()) { - errors[INPUT_IDS.LEGAL_FIRST_NAME] = translate('common.error.fieldRequired'); - } else if (!isValidDisplayName(firstNameValue)) { - errors[INPUT_IDS.LEGAL_FIRST_NAME] = translate('privatePersonalDetails.error.cannotIncludeCommaOrSemicolon'); - } else if (firstNameValue.length > CONST.LEGAL_NAME.MAX_LENGTH) { - errors[INPUT_IDS.LEGAL_FIRST_NAME] = translate('common.error.characterLimitExceedCounter', firstNameValue.length, CONST.LEGAL_NAME.MAX_LENGTH); - } else if (doesContainReservedWord(firstNameValue, CONST.DISPLAY_NAME.RESERVED_NAMES)) { - errors[INPUT_IDS.LEGAL_FIRST_NAME] = translate('personalDetails.error.containsReservedWord'); - } - - const lastNameValue = values[INPUT_IDS.LEGAL_LAST_NAME] ?? ''; - if (!lastNameValue.trim()) { - errors[INPUT_IDS.LEGAL_LAST_NAME] = translate('common.error.fieldRequired'); - } else if (!isValidDisplayName(lastNameValue)) { - errors[INPUT_IDS.LEGAL_LAST_NAME] = translate('privatePersonalDetails.error.cannotIncludeCommaOrSemicolon'); - } else if (lastNameValue.length > CONST.LEGAL_NAME.MAX_LENGTH) { - errors[INPUT_IDS.LEGAL_LAST_NAME] = translate('common.error.characterLimitExceedCounter', lastNameValue.length, CONST.LEGAL_NAME.MAX_LENGTH); - } else if (doesContainReservedWord(lastNameValue, CONST.DISPLAY_NAME.RESERVED_NAMES)) { - errors[INPUT_IDS.LEGAL_LAST_NAME] = translate('personalDetails.error.containsReservedWord'); - } - - const dobValue = values[INPUT_IDS.DATE_OF_BIRTH] ?? ''; - if (!dobValue) { - errors[INPUT_IDS.DATE_OF_BIRTH] = translate('common.error.fieldRequired'); - } else { - const dateError = getAgeRequirementError(translate, dobValue, CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT, CONST.DATE_BIRTH.MAX_AGE); - if (dateError) { - errors[INPUT_IDS.DATE_OF_BIRTH] = dateError; - } - } - - const phoneValue = values[INPUT_IDS.PHONE_NUMBER] ?? ''; - if (!isRequiredFulfilled(phoneValue)) { - errors[INPUT_IDS.PHONE_NUMBER] = translate('common.error.fieldRequired'); - } else { - const phoneWithCountryCode = appendCountryCode(phoneValue, countryCode); - if (!isValidPhoneNumber(phoneWithCountryCode)) { - errors[INPUT_IDS.PHONE_NUMBER] = translate('common.error.phoneNumber'); - } - } - - const streetValue = values[INPUT_IDS.ADDRESS_LINE_1] ?? ''; - if (!streetValue.trim()) { - errors[INPUT_IDS.ADDRESS_LINE_1] = translate('common.error.fieldRequired'); - } - - const cityValue = values[INPUT_IDS.CITY] ?? ''; - if (!cityValue.trim()) { - errors[INPUT_IDS.CITY] = translate('common.error.fieldRequired'); - } - - const stateValue = values[INPUT_IDS.STATE] || selectedState || ''; - const effectiveCountry = (values[INPUT_IDS.COUNTRY] || selectedCountry) ?? ''; - if (!stateValue.trim()) { - errors[INPUT_IDS.STATE] = translate('common.error.fieldRequired'); - } - - const zipValue = values[INPUT_IDS.ZIP_POST_CODE] ?? ''; - const countryRegexDetails = effectiveCountry ? (COMMON_CONST.COUNTRY_ZIP_REGEX_DATA?.[effectiveCountry] as {regex?: RegExp; samples?: string}) : undefined; - const countrySpecificZipRegex = countryRegexDetails?.regex; - if (countrySpecificZipRegex) { - if (!countrySpecificZipRegex.test(zipValue.trim().toUpperCase())) { - if (isRequiredFulfilled(zipValue.trim())) { - errors[INPUT_IDS.ZIP_POST_CODE] = translate('privatePersonalDetails.error.incorrectZipFormat', countryRegexDetails?.samples ?? ''); - } else { - errors[INPUT_IDS.ZIP_POST_CODE] = translate('common.error.fieldRequired'); - } - } - } else if (!COMMON_CONST.GENERIC_ZIP_CODE_REGEX.test(zipValue.trim().toUpperCase())) { - errors[INPUT_IDS.ZIP_POST_CODE] = translate('privatePersonalDetails.error.incorrectZipFormat'); - } - - if (!effectiveCountry) { - errors[INPUT_IDS.COUNTRY] = translate('common.error.fieldRequired'); - } - - return errors; - }; - - const hasChanges = (values: FormOnyxValues): boolean => { - if ((values[INPUT_IDS.LEGAL_FIRST_NAME] ?? '') !== legalFirstName) { - return true; - } - if ((values[INPUT_IDS.LEGAL_LAST_NAME] ?? '') !== legalLastName) { - return true; - } - if ((values[INPUT_IDS.DATE_OF_BIRTH] ?? '') !== dob) { - return true; - } - if ((values[INPUT_IDS.PHONE_NUMBER] ?? '') !== phoneNumber) { - return true; - } - if ((values[INPUT_IDS.ADDRESS_LINE_1] ?? '') !== initialStreet1) { - return true; - } - if ((values[INPUT_IDS.ADDRESS_LINE_2] ?? '') !== initialStreet2) { - return true; - } - if ((values[INPUT_IDS.CITY] ?? '') !== city) { - return true; - } - if ((values[INPUT_IDS.STATE] ?? '') !== normalizedState) { - return true; - } - if ((values[INPUT_IDS.ZIP_POST_CODE] ?? '') !== zip) { - return true; - } - if ((values[INPUT_IDS.COUNTRY] ?? '') !== country) { - return true; - } - return false; - }; - - const onSubmit = (values: FormOnyxValues) => { - if (!hasChanges(values)) { - Navigation.goBack(); - return; - } - // UI-prefilled values (geolocation country, normalized state) only live in component state until the user touches - // a field, so write the full form values to the draft before navigating so the confirm step submits them. - setDraftValues(ONYXKEYS.FORMS.PERSONAL_DETAILS_FORM, values); - Navigation.navigate(ROUTES.SETTINGS_PRIVATE_PERSONAL_DETAILS_CONFIRM_MAGIC_CODE); - }; - - const reasonAttributes: SkeletonSpanReasonAttributes = {context: 'PrivatePersonalDetailsPage', isLoadingApp}; - - if (isLoadingApp) { - return ( - - ); - } - - return ( - - - Navigation.goBack()} - /> - - {translate('privatePersonalDetails.basicDetails')} - - - - - - - - - - - - - {translate('privatePersonalDetails.address')} - - { - if (key === INPUT_IDS.COUNTRY) { - setSelectedCountry((value ?? '') as Country | ''); - } else if (key === INPUT_IDS.STATE) { - setSelectedState((value ?? '') as string); - } - }} - /> - - - - - - - - {selectedCountry === CONST.COUNTRY.US ? ( - - setSelectedState((value ?? '') as string)} - shouldSaveDraft - /> - - ) : ( - - - - )} - - - - - { - const newCountry = (value ?? '') as Country | ''; - setSelectedCountry(newCountry); - if (newCountry === CONST.COUNTRY.US) { - const resolved = resolveStateCode(selectedState); - if (resolved !== selectedState) { - setSelectedState(resolved); - } - } - }} - shouldSaveDraft - /> - - - - - ); -} - -PrivatePersonalDetailsPage.displayName = 'PrivatePersonalDetailsPage'; - -export default PrivatePersonalDetailsPage; diff --git a/src/pages/settings/Profile/ProfilePage.tsx b/src/pages/settings/Profile/ProfilePage.tsx index 57e78733fd8..7c3f8e7cf52 100755 --- a/src/pages/settings/Profile/ProfilePage.tsx +++ b/src/pages/settings/Profile/ProfilePage.tsx @@ -41,7 +41,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import INPUT_IDS from '@src/types/form/PersonalDetailsForm'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; function ProfilePage() { @@ -133,39 +132,55 @@ function ProfilePage() { : []), ]; - const navigateToPrivateDetails = (fieldToFocus?: string) => { - if (isActingAsDelegate) { - showDelegateNoAccessModal(); - return; - } - Navigation.navigate(ROUTES.SETTINGS_PRIVATE_PERSONAL_DETAILS.getRoute(fieldToFocus)); - }; - const privateOptions = [ { description: translate('privatePersonalDetails.legalName'), title: legalName, sentryLabel: CONST.SENTRY_LABEL.SETTINGS_PROFILE.LEGAL_NAME, - action: () => navigateToPrivateDetails(INPUT_IDS.LEGAL_FIRST_NAME), + action: () => { + if (isActingAsDelegate) { + showDelegateNoAccessModal(); + return; + } + Navigation.navigate(ROUTES.SETTINGS_LEGAL_NAME); + }, }, { description: translate('common.dob'), title: privateDetails.dob ?? '', sentryLabel: CONST.SENTRY_LABEL.SETTINGS_PROFILE.DATE_OF_BIRTH, - action: () => navigateToPrivateDetails(INPUT_IDS.DATE_OF_BIRTH), + action: () => { + if (isActingAsDelegate) { + showDelegateNoAccessModal(); + return; + } + Navigation.navigate(ROUTES.SETTINGS_DATE_OF_BIRTH); + }, }, { description: translate('common.phoneNumber'), title: privateDetails.phoneNumber ?? '', sentryLabel: CONST.SENTRY_LABEL.SETTINGS_PROFILE.PHONE_NUMBER, - action: () => navigateToPrivateDetails(INPUT_IDS.PHONE_NUMBER), + action: () => { + if (isActingAsDelegate) { + showDelegateNoAccessModal(); + return; + } + Navigation.navigate(ROUTES.SETTINGS_PHONE_NUMBER); + }, brickRoadIndicator: privatePersonalDetails?.errorFields?.phoneNumber ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, }, { description: translate('privatePersonalDetails.address'), title: getFormattedAddress(privateDetails), sentryLabel: CONST.SENTRY_LABEL.SETTINGS_PROFILE.ADDRESS, - action: () => navigateToPrivateDetails(INPUT_IDS.ADDRESS_LINE_1), + action: () => { + if (isActingAsDelegate) { + showDelegateNoAccessModal(); + return; + } + Navigation.navigate(ROUTES.SETTINGS_ADDRESS); + }, }, ];