150 lines
10 KiB
TypeScript
150 lines
10 KiB
TypeScript
/**
|
|
* Règles de validation des numéros de téléphone locaux par indicatif pays.
|
|
* Le numéro local est celui saisi par l'utilisateur SANS le 0 initial et SANS l'indicatif.
|
|
* Exemples : France 06 12 34 56 78 → local = "612345678" (9 chiffres)
|
|
* Brésil 11 9 1234-5678 → local = "11912345678" (11 chiffres)
|
|
*/
|
|
|
|
export type PhoneRule = {
|
|
/** Longueur minimale du numéro local (chiffres uniquement) */
|
|
minLength: number;
|
|
/** Longueur maximale du numéro local (chiffres uniquement) */
|
|
maxLength: number;
|
|
/** Regex optionnelle pour validation de format */
|
|
pattern?: RegExp;
|
|
/** Exemple de numéro local valide (pour le placeholder) */
|
|
example: string;
|
|
/** Hint affiché sous le champ */
|
|
hint: string;
|
|
};
|
|
|
|
/** Règles par dialCode (indicatif sans le +) */
|
|
export const PHONE_RULES: Record<string, PhoneRule> = {
|
|
// ── France & DOM-TOM ──────────────────────────────────────────────────────
|
|
"33": { minLength: 9, maxLength: 9, pattern: /^[67]\d{8}$/, example: "612345678", hint: "9 chiffres, commençant par 6 ou 7 (ex : 612 345 678)" },
|
|
"590": { minLength: 9, maxLength: 9, example: "690123456", hint: "9 chiffres (Guadeloupe)" },
|
|
"596": { minLength: 9, maxLength: 9, example: "696123456", hint: "9 chiffres (Martinique)" },
|
|
"262": { minLength: 9, maxLength: 9, example: "692123456", hint: "9 chiffres (Réunion / Mayotte)" },
|
|
"594": { minLength: 9, maxLength: 9, example: "694123456", hint: "9 chiffres (Guyane)" },
|
|
"687": { minLength: 6, maxLength: 6, example: "123456", hint: "6 chiffres (Nouvelle-Calédonie)" },
|
|
"689": { minLength: 8, maxLength: 8, example: "87123456", hint: "8 chiffres (Polynésie française)" },
|
|
"508": { minLength: 6, maxLength: 6, example: "551234", hint: "6 chiffres (Saint-Pierre-et-Miquelon)" },
|
|
"681": { minLength: 6, maxLength: 6, example: "721234", hint: "6 chiffres (Wallis-et-Futuna)" },
|
|
|
|
// ── Europe ────────────────────────────────────────────────────────────────
|
|
"32": { minLength: 8, maxLength: 9, example: "470123456", hint: "8-9 chiffres (Belgique)" },
|
|
"41": { minLength: 9, maxLength: 9, example: "791234567", hint: "9 chiffres (Suisse)" },
|
|
"352": { minLength: 6, maxLength: 9, example: "621123456", hint: "6-9 chiffres (Luxembourg)" },
|
|
"377": { minLength: 8, maxLength: 8, example: "61234567", hint: "8 chiffres (Monaco)" },
|
|
"49": { minLength: 10, maxLength: 11, example: "15123456789", hint: "10-11 chiffres (Allemagne)" },
|
|
"34": { minLength: 9, maxLength: 9, example: "612345678", hint: "9 chiffres (Espagne)" },
|
|
"39": { minLength: 9, maxLength: 10, example: "3123456789", hint: "9-10 chiffres (Italie)" },
|
|
"351": { minLength: 9, maxLength: 9, example: "912345678", hint: "9 chiffres (Portugal)" },
|
|
"44": { minLength: 10, maxLength: 10, example: "7911123456", hint: "10 chiffres (Royaume-Uni)" },
|
|
"31": { minLength: 9, maxLength: 9, example: "612345678", hint: "9 chiffres (Pays-Bas)" },
|
|
"48": { minLength: 9, maxLength: 9, example: "512345678", hint: "9 chiffres (Pologne)" },
|
|
"46": { minLength: 7, maxLength: 9, example: "701234567", hint: "7-9 chiffres (Suède)" },
|
|
"47": { minLength: 8, maxLength: 8, example: "91234567", hint: "8 chiffres (Norvège)" },
|
|
"45": { minLength: 8, maxLength: 8, example: "20123456", hint: "8 chiffres (Danemark)" },
|
|
"358": { minLength: 9, maxLength: 10, example: "412345678", hint: "9-10 chiffres (Finlande)" },
|
|
"43": { minLength: 10, maxLength: 11, example: "6641234567", hint: "10-11 chiffres (Autriche)" },
|
|
"30": { minLength: 10, maxLength: 10, example: "6912345678", hint: "10 chiffres (Grèce)" },
|
|
"40": { minLength: 9, maxLength: 9, example: "712345678", hint: "9 chiffres (Roumanie)" },
|
|
"36": { minLength: 9, maxLength: 9, example: "201234567", hint: "9 chiffres (Hongrie)" },
|
|
"420": { minLength: 9, maxLength: 9, example: "601234567", hint: "9 chiffres (Rép. tchèque)" },
|
|
"90": { minLength: 10, maxLength: 10, example: "5321234567", hint: "10 chiffres (Turquie)" },
|
|
|
|
// ── Afrique ───────────────────────────────────────────────────────────────
|
|
"212": { minLength: 9, maxLength: 9, example: "612345678", hint: "9 chiffres (Maroc)" },
|
|
"213": { minLength: 9, maxLength: 9, example: "551234567", hint: "9 chiffres (Algérie)" },
|
|
"216": { minLength: 8, maxLength: 8, example: "20123456", hint: "8 chiffres (Tunisie)" },
|
|
"221": { minLength: 9, maxLength: 9, example: "771234567", hint: "9 chiffres (Sénégal)" },
|
|
"225": { minLength: 10, maxLength: 10, example: "0712345678", hint: "10 chiffres (Côte d'Ivoire)" },
|
|
"237": { minLength: 9, maxLength: 9, example: "612345678", hint: "9 chiffres (Cameroun)" },
|
|
"243": { minLength: 9, maxLength: 9, example: "812345678", hint: "9 chiffres (Congo RDC)" },
|
|
"242": { minLength: 9, maxLength: 9, example: "061234567", hint: "9 chiffres (Congo Brazzaville)" },
|
|
"261": { minLength: 9, maxLength: 9, example: "321234567", hint: "9 chiffres (Madagascar)" },
|
|
"223": { minLength: 8, maxLength: 8, example: "70123456", hint: "8 chiffres (Mali)" },
|
|
"226": { minLength: 8, maxLength: 8, example: "70123456", hint: "8 chiffres (Burkina Faso)" },
|
|
"227": { minLength: 8, maxLength: 8, example: "90123456", hint: "8 chiffres (Niger)" },
|
|
"235": { minLength: 8, maxLength: 8, example: "63123456", hint: "8 chiffres (Tchad)" },
|
|
"224": { minLength: 9, maxLength: 9, example: "621234567", hint: "9 chiffres (Guinée)" },
|
|
"229": { minLength: 8, maxLength: 8, example: "97123456", hint: "8 chiffres (Bénin)" },
|
|
"228": { minLength: 8, maxLength: 8, example: "90123456", hint: "8 chiffres (Togo)" },
|
|
"222": { minLength: 8, maxLength: 8, example: "22123456", hint: "8 chiffres (Mauritanie)" },
|
|
"241": { minLength: 7, maxLength: 8, example: "6123456", hint: "7-8 chiffres (Gabon)" },
|
|
"240": { minLength: 9, maxLength: 9, example: "222123456", hint: "9 chiffres (Guinée équatoriale)" },
|
|
"236": { minLength: 8, maxLength: 8, example: "72123456", hint: "8 chiffres (Centrafrique)" },
|
|
"269": { minLength: 7, maxLength: 7, example: "3212345", hint: "7 chiffres (Comores)" },
|
|
"253": { minLength: 8, maxLength: 8, example: "77123456", hint: "8 chiffres (Djibouti)" },
|
|
"230": { minLength: 8, maxLength: 8, example: "52123456", hint: "8 chiffres (Maurice)" },
|
|
"248": { minLength: 7, maxLength: 7, example: "2512345", hint: "7 chiffres (Seychelles)" },
|
|
"20": { minLength: 10, maxLength: 10, example: "1012345678", hint: "10 chiffres (Égypte)" },
|
|
|
|
// ── Amériques ─────────────────────────────────────────────────────────────
|
|
"1": { minLength: 10, maxLength: 10, example: "2125551234", hint: "10 chiffres (US/Canada, sans le 1 initial)" },
|
|
"52": { minLength: 10, maxLength: 10, example: "5512345678", hint: "10 chiffres (Mexique)" },
|
|
"55": { minLength: 10, maxLength: 11, example: "11912345678", hint: "10-11 chiffres (Brésil, avec DDD)" },
|
|
"54": { minLength: 10, maxLength: 11, example: "91123456789", hint: "10-11 chiffres (Argentine)" },
|
|
"57": { minLength: 10, maxLength: 10, example: "3001234567", hint: "10 chiffres (Colombie)" },
|
|
"56": { minLength: 9, maxLength: 9, example: "912345678", hint: "9 chiffres (Chili)" },
|
|
"51": { minLength: 9, maxLength: 9, example: "912345678", hint: "9 chiffres (Pérou)" },
|
|
"58": { minLength: 10, maxLength: 10, example: "4121234567", hint: "10 chiffres (Venezuela)" },
|
|
"593": { minLength: 9, maxLength: 9, example: "991234567", hint: "9 chiffres (Équateur)" },
|
|
"591": { minLength: 8, maxLength: 8, example: "71234567", hint: "8 chiffres (Bolivie)" },
|
|
"595": { minLength: 9, maxLength: 9, example: "981234567", hint: "9 chiffres (Paraguay)" },
|
|
"598": { minLength: 8, maxLength: 9, example: "91234567", hint: "8-9 chiffres (Uruguay)" },
|
|
"509": { minLength: 8, maxLength: 8, example: "36123456", hint: "8 chiffres (Haïti)" },
|
|
|
|
// ── Asie & Océanie ────────────────────────────────────────────────────────
|
|
"91": { minLength: 10, maxLength: 10, example: "9123456789", hint: "10 chiffres (Inde)" },
|
|
"86": { minLength: 11, maxLength: 11, example: "13912345678", hint: "11 chiffres (Chine)" },
|
|
"81": { minLength: 10, maxLength: 11, example: "9012345678", hint: "10-11 chiffres (Japon)" },
|
|
"61": { minLength: 9, maxLength: 9, example: "412345678", hint: "9 chiffres (Australie)" },
|
|
"961": { minLength: 7, maxLength: 8, example: "3123456", hint: "7-8 chiffres (Liban)" },
|
|
};
|
|
|
|
/** Règle par défaut si le dialCode n'est pas dans la liste */
|
|
export const DEFAULT_RULE: PhoneRule = {
|
|
minLength: 6,
|
|
maxLength: 15,
|
|
example: "123456789",
|
|
hint: "6-15 chiffres",
|
|
};
|
|
|
|
/**
|
|
* Valide un numéro local (sans indicatif, sans 0 initial).
|
|
* @returns null si valide, message d'erreur sinon
|
|
*/
|
|
export function validateLocalPhone(dialCode: string, localNumber: string): string | null {
|
|
const digits = localNumber.replace(/\D/g, "");
|
|
const rule = PHONE_RULES[dialCode] ?? DEFAULT_RULE;
|
|
|
|
if (digits.length === 0) return "Veuillez saisir votre numéro.";
|
|
if (digits.length < rule.minLength) {
|
|
return `Numéro trop court (minimum ${rule.minLength} chiffres). ${rule.hint}`;
|
|
}
|
|
if (digits.length > rule.maxLength) {
|
|
return `Numéro trop long (maximum ${rule.maxLength} chiffres). ${rule.hint}`;
|
|
}
|
|
if (rule.pattern && !rule.pattern.test(digits)) {
|
|
return `Format invalide. ${rule.hint}`;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Retourne le placeholder adapté au pays sélectionné.
|
|
*/
|
|
export function getPhonePlaceholder(dialCode: string): string {
|
|
const rule = PHONE_RULES[dialCode] ?? DEFAULT_RULE;
|
|
return rule.example;
|
|
}
|
|
|
|
/**
|
|
* Retourne le hint d'aide pour un dialCode.
|
|
*/
|
|
export function getPhoneHint(dialCode: string): string {
|
|
const rule = PHONE_RULES[dialCode] ?? DEFAULT_RULE;
|
|
return rule.hint;
|
|
}
|