- Create apps/web/lib/phone.ts with VN_PHONE_REGEX, normalizePhone, formatPhone, and zaloHref helpers - Deduplicate phone regex: auth.ts and inquiry.ts now import VN_PHONE_REGEX from @/lib/phone instead of defining their own local patterns - Replace raw .replace(/^0/, '84') in inquiry-detail-dialog.tsx and lead-detail-dialog.tsx with zaloHref(); use formatPhone() for display Resolves GOO-209 Co-Authored-By: Paperclip <noreply@paperclip.ing>
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
/**
|
|
* Vietnamese phone number helpers.
|
|
*
|
|
* Regex covers the current VN numbering plan:
|
|
* 0[35789]x xxxxxxx — Viettel, Mobifone, Vinaphone, Gmobile, Indochina
|
|
*
|
|
* See: https://en.wikipedia.org/wiki/Telephone_numbers_in_Vietnam
|
|
*/
|
|
|
|
/** Matches a VN mobile number, with optional +84 or leading 0. */
|
|
export const VN_PHONE_REGEX =
|
|
/^(0|\+84)(3[2-9]|5[2689]|7[06-9]|8[1-9]|9[0-9])\d{7}$/;
|
|
|
|
/**
|
|
* Normalise a VN phone number to the E.164-ish form used by Zalo / APIs:
|
|
* strip leading 0 and prepend the country code (84).
|
|
*
|
|
* "0987654321" → "84987654321"
|
|
* "+84987654321" → "84987654321"
|
|
* "84987654321" → "84987654321" (already normalised — idempotent)
|
|
*/
|
|
export function normalizePhone(phone: string): string {
|
|
const cleaned = phone.trim();
|
|
if (cleaned.startsWith('+84')) return `84${cleaned.slice(3)}`;
|
|
if (cleaned.startsWith('84')) return cleaned;
|
|
if (cleaned.startsWith('0')) return `84${cleaned.slice(1)}`;
|
|
return cleaned;
|
|
}
|
|
|
|
/**
|
|
* Format a raw VN phone number for display.
|
|
* Handles 10-digit numbers (0xx xxxx xxxx).
|
|
*
|
|
* "0987654321" → "0987 654 321"
|
|
* Passthrough for anything that doesn't match.
|
|
*/
|
|
export function formatPhone(phone: string): string {
|
|
const cleaned = phone.trim().replace(/\s+/g, '');
|
|
|
|
// 10-digit local format: 0xxx yyy zzz
|
|
const tenDigit = cleaned.match(/^(0\d{3})(\d{3})(\d{3})$/);
|
|
if (tenDigit) return `${tenDigit[1]} ${tenDigit[2]} ${tenDigit[3]}`;
|
|
|
|
// +84 prefix → treat as 10-digit local after swapping prefix
|
|
const e164 = cleaned.match(/^\+84(\d{9})$/);
|
|
if (e164) return formatPhone(`0${e164[1]}`);
|
|
|
|
return phone;
|
|
}
|
|
|
|
/**
|
|
* Returns the https://zalo.me deep-link URL for a given phone number.
|
|
*
|
|
* Zalo expects the number without a leading zero, prefixed with 84.
|
|
* "0987654321" → "https://zalo.me/84987654321"
|
|
*/
|
|
export function zaloHref(phone: string): string {
|
|
return `https://zalo.me/${normalizePhone(phone)}`;
|
|
}
|