From 39f2c99395cd57889a0dee98ed44cd6f1bbb88a9 Mon Sep 17 00:00:00 2001 From: Marshal Date: Mon, 22 Jun 2026 12:35:01 +0000 Subject: [PATCH] feat: add phone number normalization to Ethiopian E.164 format in CompanyProfileForm --- .../portal/src/components/PhoneField.tsx | 18 +++++++++++++ .../src/pages/accounts/CompanyProfileForm.tsx | 26 ++++++++++++------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/apps/edr-freight-web/portal/src/components/PhoneField.tsx b/apps/edr-freight-web/portal/src/components/PhoneField.tsx index e1ad3cd56..a50621e60 100644 --- a/apps/edr-freight-web/portal/src/components/PhoneField.tsx +++ b/apps/edr-freight-web/portal/src/components/PhoneField.tsx @@ -14,6 +14,24 @@ import "./phone-field.css"; export const isValidPhone = (value?: string | null): boolean => !!value && isValidPhoneNumber(value); +/** + * Normalize a raw (often eTrade) phone string to Ethiopian E.164 (+251…). + * eTrade returns local numbers like "0912345678" / "0355235416"; the phone + * input needs +251… to parse, so we drop a leading 0 and prepend +251. Numbers + * already in +… form, or that can't be coerced, are returned trimmed/as-is. + */ +export const toEthiopianE164 = (raw?: string | null): string => { + if (!raw) return ""; + const trimmed = raw.trim(); + if (trimmed.startsWith("+")) return trimmed.replace(/[^\d+]/g, ""); + // Keep digits only, drop a single leading zero (national trunk prefix). + const digits = trimmed.replace(/\D/g, "").replace(/^0/, ""); + if (!digits) return ""; + // Already includes the 251 country code. + if (digits.startsWith("251")) return `+${digits}`; + return `+251${digits}`; +}; + /** * The text input rendered inside react-phone-number-input, styled to match the * portal's Mantine fields (44px height, 10px radius, edr border). Must forward diff --git a/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx b/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx index fca6ecb44..29055a2e8 100644 --- a/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx +++ b/apps/edr-freight-web/portal/src/pages/accounts/CompanyProfileForm.tsx @@ -34,7 +34,11 @@ import type { AuthUser } from "@/types/auth"; import type { CreateCompanyPayload } from "@/services/companies.service"; import type { ProfileResponse, UpdateProfilePayload } from "@/types/profile"; import type { CompanyRegistrationData } from "@edr/types"; -import { ControlledPhoneField, isValidPhone } from "@/components/PhoneField"; +import { + ControlledPhoneField, + isValidPhone, + toEthiopianE164, +} from "@/components/PhoneField"; import { SmartFileInput } from "@edr/ui-common"; import { api } from "@/services/api"; import RoleLicenseStep, { @@ -421,7 +425,10 @@ export default function CompanyProfileForm({ setValue("woreda", data.woreda); setValue("kebele", data.kebele); setValue("houseNo", data.houseNo); - setValue("etradePhone", data.regularPhone || data.mobilePhone); + setValue( + "etradePhone", + toEthiopianE164(data.regularPhone || data.mobilePhone), + ); // Compose a readable company address from the granular eTrade parts. const addressParts = [ @@ -436,14 +443,16 @@ export default function CompanyProfileForm({ } // Pre-fill the company contact phone from eTrade's mobile number. - const mobile = data.mobilePhone || data.regularPhone; + const mobile = toEthiopianE164(data.mobilePhone || data.regularPhone); if (mobile) { - setValue("companyPhone", mobile ?? "", { shouldValidate: true }); + setValue("companyPhone", mobile, { shouldValidate: true }); } setEtradeOwner({ name: data.managerName, - phone: data.managerPhone || data.regularPhone || data.mobilePhone, + phone: toEthiopianE164( + data.managerPhone || data.regularPhone || data.mobilePhone, + ), }); }; @@ -763,11 +772,10 @@ export default function CompanyProfileForm({ error={errors.houseNo?.message} {...register("houseNo")} /> -