/// Classe utilitaire pour la validation des champs de formulaire. /// /// Cette classe fournit des méthodes statiques pour valider différents /// types de données d'entrée utilisateur. /// /// **Usage:** /// ```dart /// final emailError = Validators.validateEmail(emailController.text); /// if (emailError != null) { /// // Afficher l'erreur /// } /// ``` class Validators { /// Constructeur privé pour empêcher l'instanciation Validators._(); /// Expression régulière pour valider les emails static final RegExp _emailRegex = RegExp( r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$', ); /// Expression régulière pour valider les mots de passe forts /// (au moins 8 caractères, une majuscule, une minuscule, un chiffre) static final RegExp _strongPasswordRegex = RegExp( r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d@$!%*?&]{8,}$', ); /// Valide une adresse email. /// /// [value] La valeur à valider /// /// Returns `null` si l'email est valide, sinon un message d'erreur. /// /// **Exemple:** /// ```dart /// final error = Validators.validateEmail('user@example.com'); /// // Retourne null si valide /// ``` static String? validateEmail(String? value) { if (value == null || value.trim().isEmpty) { return 'Veuillez entrer votre email'; } final trimmedValue = value.trim(); if (!_emailRegex.hasMatch(trimmedValue)) { return 'Veuillez entrer un email valide'; } // Validation supplémentaire de la longueur if (trimmedValue.length > 254) { return 'L\'email est trop long (maximum 254 caractères)'; } return null; } /// Valide un mot de passe. /// /// [value] La valeur à valider /// [minLength] Longueur minimale requise (par défaut: 6) /// [requireStrong] Si true, exige un mot de passe fort (par défaut: false) /// /// Returns `null` si le mot de passe est valide, sinon un message d'erreur. /// /// **Exemple:** /// ```dart /// final error = Validators.validatePassword('password123', minLength: 8); /// // Retourne null si valide /// ``` static String? validatePassword( String? value, { int minLength = 6, bool requireStrong = false, }) { if (value == null || value.isEmpty) { return 'Veuillez entrer votre mot de passe'; } if (value.length < minLength) { return 'Le mot de passe doit comporter au moins $minLength caractères'; } if (requireStrong && !_strongPasswordRegex.hasMatch(value)) { return 'Le mot de passe doit contenir au moins une majuscule, ' 'une minuscule et un chiffre'; } // Validation de la longueur maximale if (value.length > 128) { return 'Le mot de passe est trop long (maximum 128 caractères)'; } return null; } /// Valide que deux mots de passe correspondent. /// /// [password] Le premier mot de passe /// [confirmPassword] Le mot de passe de confirmation /// /// Returns `null` si les mots de passe correspondent, sinon un message d'erreur. /// /// **Exemple:** /// ```dart /// final error = Validators.validatePasswordMatch( /// 'password123', /// 'password123', /// ); /// // Retourne null si correspond /// ``` static String? validatePasswordMatch(String? password, String? confirmPassword) { if (password == null || password.isEmpty) { return 'Veuillez entrer votre mot de passe'; } if (confirmPassword == null || confirmPassword.isEmpty) { return 'Veuillez confirmer votre mot de passe'; } if (password != confirmPassword) { return 'Les mots de passe ne correspondent pas'; } return null; } /// Valide un nom (prénom ou nom de famille). /// /// [value] La valeur à valider /// [fieldName] Le nom du champ (pour le message d'erreur) /// /// Returns `null` si le nom est valide, sinon un message d'erreur. static String? validateName(String? value, {String fieldName = 'ce champ'}) { if (value == null || value.trim().isEmpty) { return 'Veuillez entrer $fieldName'; } final trimmedValue = value.trim(); if (trimmedValue.length < 2) { return '$fieldName doit contenir au moins 2 caractères'; } if (trimmedValue.length > 100) { return '$fieldName est trop long (maximum 100 caractères)'; } // Validation des caractères (lettres, espaces, tirets, apostrophes) if (!RegExp(r"^[a-zA-ZÀ-ÿ\s\-']+$").hasMatch(trimmedValue)) { return '$fieldName ne doit contenir que des lettres'; } return null; } /// Valide un numéro de téléphone. /// /// [value] La valeur à valider /// /// Returns `null` si le numéro est valide, sinon un message d'erreur. static String? validatePhoneNumber(String? value) { if (value == null || value.trim().isEmpty) { return 'Veuillez entrer votre numéro de téléphone'; } final trimmedValue = value.trim().replaceAll(RegExp(r'[\s\-\(\)]'), ''); // Validation du format (10 chiffres pour la France) if (!RegExp(r'^\+?[0-9]{10,15}$').hasMatch(trimmedValue)) { return 'Veuillez entrer un numéro de téléphone valide'; } return null; } /// Valide une URL. /// /// [value] La valeur à valider /// /// Returns `null` si l'URL est valide, sinon un message d'erreur. static String? validateUrl(String? value) { if (value == null || value.trim().isEmpty) { return 'Veuillez entrer une URL'; } final trimmedValue = value.trim(); try { final uri = Uri.parse(trimmedValue); if (!uri.hasScheme || !uri.hasAuthority) { return 'Veuillez entrer une URL valide'; } return null; } catch (e) { return 'Veuillez entrer une URL valide'; } } /// Valide qu'un champ n'est pas vide. /// /// [value] La valeur à valider /// [fieldName] Le nom du champ (pour le message d'erreur) /// /// Returns `null` si le champ n'est pas vide, sinon un message d'erreur. static String? validateRequired(String? value, {String fieldName = 'ce champ'}) { if (value == null || value.trim().isEmpty) { return 'Veuillez remplir $fieldName'; } return null; } /// Valide la longueur d'une chaîne. /// /// [value] La valeur à valider /// [minLength] Longueur minimale /// [maxLength] Longueur maximale /// [fieldName] Le nom du champ (pour le message d'erreur) /// /// Returns `null` si la longueur est valide, sinon un message d'erreur. static String? validateLength( String? value, { int? minLength, int? maxLength, String fieldName = 'ce champ', }) { if (value == null) { return 'Veuillez remplir $fieldName'; } final length = value.length; if (minLength != null && length < minLength) { return '$fieldName doit contenir au moins $minLength caractères'; } if (maxLength != null && length > maxLength) { return '$fieldName ne doit pas dépasser $maxLength caractères'; } return null; } }