From ecbcc12abfc24f8f1dd264caa7c36340028527ec Mon Sep 17 00:00:00 2001 From: bagasbanuna Date: Thu, 26 Mar 2026 11:42:54 +0800 Subject: [PATCH] Refactor: apply PhoneInputCustom to ScreenPortofolioCreate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - Replace react-native-international-phone-number with PhoneInputCustom - Remove ICountry dependency, use CountryData from constants - Update state management (inputValue → phoneNumber) - Improve phone number formatting logic - Add handleCountryChange for better country switching Features Applied: ✅ NO emoji flags - only calling codes (+62, +65, etc) ✅ Clean, professional UI ✅ Modal country picker with search ✅ Real-time phone number formatting ✅ Auto-update country code on change ✅ Consistent with LoginView implementation Phone Input Logic: - Format on every phone change - Re-format when country changes - Remove duplicate country codes - Remove leading zeros - Store E.164 format in API data UI: - Phone Input: [+62 ⌄ | xxx-xxx-xxx] - Country Picker: Modal with search - Display: Country name + calling code only Co-authored-by: Qwen-Coder --- bun.lock | 3 ++ components/PhoneInput/PhoneInputCustom.tsx | 3 -- package.json | 1 + screens/Portofolio/ScreenPortofolioCreate.tsx | 52 ++++++++++++++----- 4 files changed, 43 insertions(+), 16 deletions(-) diff --git a/bun.lock b/bun.lock index 32d2144..646fe51 100644 --- a/bun.lock +++ b/bun.lock @@ -41,6 +41,7 @@ "expo-symbols": "~1.0.7", "expo-system-ui": "~6.0.7", "expo-web-browser": "~15.0.9", + "libphonenumber-js": "^1.12.40", "lodash": "^4.17.21", "moti": "^0.30.0", "react": "19.1.0", @@ -1772,6 +1773,8 @@ "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + "libphonenumber-js": ["libphonenumber-js@1.12.40", "", {}, "sha512-HKGs7GowShNls3Zh+7DTr6wYpPk5jC78l508yQQY3e8ZgJChM3A9JZghmMJZuK+5bogSfuTafpjksGSR3aMIEg=="], + "lighthouse-logger": ["lighthouse-logger@1.4.2", "", { "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g=="], "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="], diff --git a/components/PhoneInput/PhoneInputCustom.tsx b/components/PhoneInput/PhoneInputCustom.tsx index f385646..43b75e3 100644 --- a/components/PhoneInput/PhoneInputCustom.tsx +++ b/components/PhoneInput/PhoneInputCustom.tsx @@ -1,6 +1,5 @@ import { MainColor } from "@/constants/color-palet"; import { - COUNTRIES, DEFAULT_COUNTRY, searchCountries, type CountryData, @@ -61,7 +60,6 @@ export default function PhoneInputCustom({ activeOpacity={0.7} > +{selectedCountry.callingCode} - @@ -73,7 +71,6 @@ export default function PhoneInputCustom({ value={value} onChangeText={handlePhoneChange} keyboardType="phone-pad" - returnKeyType="done" autoComplete="tel" importantForAutofill="yes" editable={!disabled} diff --git a/package.json b/package.json index 2a8ec92..887615d 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "expo-symbols": "~1.0.7", "expo-system-ui": "~6.0.7", "expo-web-browser": "~15.0.9", + "libphonenumber-js": "^1.12.40", "lodash": "^4.17.21", "moti": "^0.30.0", "react": "19.1.0", diff --git a/screens/Portofolio/ScreenPortofolioCreate.tsx b/screens/Portofolio/ScreenPortofolioCreate.tsx index 002d426..6547b7b 100644 --- a/screens/Portofolio/ScreenPortofolioCreate.tsx +++ b/screens/Portofolio/ScreenPortofolioCreate.tsx @@ -5,6 +5,7 @@ import { CenterCustom, InformationBox, NewWrapper, + PhoneInputCustom, SelectCustom, Spacing, StackCustom, @@ -15,6 +16,7 @@ import { import { MainColor } from "@/constants/color-palet"; import { ICON_SIZE_XLARGE } from "@/constants/constans-value"; import DUMMY_IMAGE from "@/constants/dummy-image-value"; +import { DEFAULT_COUNTRY, type CountryData } from "@/constants/countries"; import Portofolio_ButtonCreate from "@/screens/Portofolio/ButtonCreatePortofolio"; import { apiMasterBidangBisnis, @@ -30,13 +32,12 @@ import { useFocusEffect, useLocalSearchParams } from "expo-router"; import _ from "lodash"; import { useCallback, useState } from "react"; import { Text, View } from "react-native"; -import PhoneInput, { ICountry } from "react-native-international-phone-number"; import { Avatar } from "react-native-paper"; export function ScreenPortofolioCreate() { const { id } = useLocalSearchParams(); - const [selectedCountry, setSelectedCountry] = useState(null); - const [inputValue, setInputValue] = useState(""); + const [selectedCountry, setSelectedCountry] = useState(DEFAULT_COUNTRY); + const [phoneNumber, setPhoneNumber] = useState(""); const [data, setData] = useState({ namaBisnis: "", masterBidangBisnisId: "", @@ -102,16 +103,42 @@ export function ScreenPortofolioCreate() { setSelectedSubBidang(selectedList as any[]); }; - const handleInputValue = (phoneNumber: string) => { - setInputValue(phoneNumber); - const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || ""; - let fixNumber = inputValue.replace(/\s+/g, "").replace(/^0+/, ""); + const handlePhoneChange = (phone: string) => { + setPhoneNumber(phone); + + // Format phone number for API + const callingCode = selectedCountry.callingCode; + let fixNumber = phone.replace(/\s+/g, "").replace(/^0+/, ""); + + // Remove country code if already present + if (fixNumber.startsWith(callingCode)) { + fixNumber = fixNumber.substring(callingCode.length); + } + + // Remove leading zero + fixNumber = fixNumber.replace(/^0+/, ""); + const realNumber = callingCode + fixNumber; setData({ ...data, tlpn: realNumber }); }; - const handleSelectedCountry = (country: ICountry) => { + const handleCountryChange = (country: CountryData) => { setSelectedCountry(country); + + // Re-format with new country code + const callingCode = country.callingCode; + let fixNumber = phoneNumber.replace(/\s+/g, "").replace(/^0+/, ""); + + // Remove country code if already present + if (fixNumber.startsWith(callingCode)) { + fixNumber = fixNumber.substring(callingCode.length); + } + + // Remove leading zero + fixNumber = fixNumber.replace(/^0+/, ""); + + const realNumber = callingCode + fixNumber; + setData({ ...data, tlpn: realNumber }); }; return ( @@ -234,12 +261,11 @@ export function ScreenPortofolioCreate() { * -