From 16decd89c81f127ca710f7e2e19a1b5878b0ed18 Mon Sep 17 00:00:00 2001 From: bagasbanuna Date: Thu, 26 Mar 2026 12:17:05 +0800 Subject: [PATCH] Refactor: apply PhoneInputCustom to PortofolioEdit 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 - Add phone number state management - Implement country detection from existing phone number - Auto-detect country based on calling code on load - Improve phone number formatting logic Features Applied: ✅ NO emoji flags - only calling codes (+62, +65, etc) ✅ Clean, professional UI ✅ Modal country picker with search ✅ Auto-detect country from saved phone number ✅ Real-time phone number formatting ✅ Auto-update country code on change ✅ Consistent with LoginView & ScreenPortofolioCreate Phone Detection Logic: - Load existing phone number from API - Detect country by matching calling code - Extract phone number without country code for display - Set detected country for country picker - Re-format on country change UI: - Phone Input: [+62 ⌄ | xxx-xxx-xxx] - Country Picker: Modal with search - Display: Country name + calling code only Co-authored-by: Qwen-Coder --- .../(user)/portofolio/[id]/edit.tsx | 81 ++++++++++++++----- components/_ShareComponent/NewWrapper.tsx | 2 +- 2 files changed, 64 insertions(+), 19 deletions(-) diff --git a/app/(application)/(user)/portofolio/[id]/edit.tsx b/app/(application)/(user)/portofolio/[id]/edit.tsx index 6b6f70c..b1dbfad 100644 --- a/app/(application)/(user)/portofolio/[id]/edit.tsx +++ b/app/(application)/(user)/portofolio/[id]/edit.tsx @@ -5,6 +5,7 @@ import { ButtonCustom, CenterCustom, NewWrapper, + PhoneInputCustom, SelectCustom, Spacing, StackCustom, @@ -15,6 +16,7 @@ import { import ListSkeletonComponent from "@/components/_ShareComponent/ListSkeletonComponent"; import { MainColor } from "@/constants/color-palet"; import { ICON_SIZE_XLARGE } from "@/constants/constans-value"; +import { DEFAULT_COUNTRY, type CountryData, COUNTRIES } from "@/constants/countries"; import { apiMasterBidangBisnis, apiMasterSubBidangBisnis, @@ -32,7 +34,6 @@ import { router, useLocalSearchParams } from "expo-router"; import _ from "lodash"; import { useEffect, useState } from "react"; import { Text, View } from "react-native"; -import PhoneInput, { ICountry } from "react-native-international-phone-number"; import { ActivityIndicator } from "react-native-paper"; import Toast from "react-native-toast-message"; @@ -59,8 +60,8 @@ export default function PortofolioEdit() { const { id } = useLocalSearchParams(); const [isLoading, setIsLoading] = useState(false); const [data, setData] = useState({}); - - const [selectedCountry, setSelectedCountry] = useState(null); + const [phoneNumber, setPhoneNumber] = useState(""); + const [selectedCountry, setSelectedCountry] = useState(DEFAULT_COUNTRY); const [bidangBisnis, setBidangBisnis] = useState< IMasterBidangBisnis[] | null >(null); @@ -72,12 +73,42 @@ export default function PortofolioEdit() { IListSubBidangSelected[] >([]); - function handleInputValue(phoneNumber: string) { - setData({ ...data, tlpn: phoneNumber }); + function 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 }); } - function handleSelectedCountry(country: ICountry) { + function 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 }); } const onLoadMasterBidang = async () => { @@ -122,8 +153,27 @@ export default function PortofolioEdit() { const response = await apiGetOnePortofolio({ id: id }); if (response.success) { - const fixNumber = response.data.tlpn.replace("62", ""); - setData({ ...response.data, tlpn: fixNumber }); + // Extract phone number without country code for display + const fullNumber = response.data.tlpn; + let displayNumber = fullNumber; + let detectedCountry = DEFAULT_COUNTRY; + + // Try to detect country from calling code + for (const country of COUNTRIES) { + if (fullNumber.startsWith(country.callingCode)) { + detectedCountry = country; + displayNumber = fullNumber.substring(country.callingCode.length); + break; + } + } + + setSelectedCountry(detectedCountry); + + // Remove leading zero if present + displayNumber = displayNumber.replace(/^0+/, ""); + + setPhoneNumber(displayNumber); + setData({ ...response.data, tlpn: displayNumber }); // Cek apakah ada sub bidang bisnis yang terpilih const prevSubBidang = response.data.Portofolio_BidangDanSubBidangBisnis; @@ -244,15 +294,11 @@ export default function PortofolioEdit() { } const handleSubmitUpdate = async () => { - const callingCode = selectedCountry?.callingCode.replace(/^\+/, "") || ""; - let fixNumber = data.tlpn.replace(/\s+/g, "").replace(/^0+/, ""); - const realNumber = callingCode + fixNumber; - const newData: IFormData = { id_Portofolio: data.id_Portofolio, namaBisnis: data.namaBisnis, alamatKantor: data.alamatKantor, - tlpn: realNumber, + tlpn: data.tlpn, // Already formatted by PhoneInputCustom deskripsi: data.deskripsi, masterBidangBisnisId: data.masterBidangBisnisId, subBidang: listSubBidangSelected, @@ -435,12 +481,11 @@ export default function PortofolioEdit() { * - diff --git a/components/_ShareComponent/NewWrapper.tsx b/components/_ShareComponent/NewWrapper.tsx index 3748ece..512ac15 100644 --- a/components/_ShareComponent/NewWrapper.tsx +++ b/components/_ShareComponent/NewWrapper.tsx @@ -160,7 +160,7 @@ const NewWrapper = (props: NewWrapperProps) => { {renderContainer(staticProps.children)}