feat: add password requirement display and enhance password validation on the signup page.
All checks were successful
Deploy Flutter to Firebase (Mac) / deploy-android (push) Successful in 2m40s

This commit is contained in:
Van Leemput Dayron
2025-12-15 16:02:50 +01:00
parent ca3f62c709
commit 63fc18ea74
3 changed files with 73 additions and 1 deletions

View File

@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
class PasswordRequirements extends StatelessWidget {
final String password;
const PasswordRequirements({super.key, required this.password});
bool get _hasMinLength => password.length >= 8;
bool get _hasUppercase => password.contains(RegExp(r'[A-Z]'));
bool get _hasLowercase => password.contains(RegExp(r'[a-z]'));
bool get _hasDigit => password.contains(RegExp(r'[0-9]'));
bool get _hasSpecialChar =>
password.contains(RegExp(r'[!@#\$%^&*(),.?":{}|<>]'));
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 10),
const Text(
'Votre mot de passe doit contenir :',
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
_buildRequirement(_hasMinLength, 'Au moins 8 caractères'),
_buildRequirement(_hasUppercase, 'Une majuscule'),
_buildRequirement(_hasLowercase, 'Une minuscule'),
_buildRequirement(_hasDigit, 'Un chiffre'),
_buildRequirement(_hasSpecialChar, 'Un caractère spécial'),
],
);
}
Widget _buildRequirement(bool isMet, String text) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 2.0),
child: Row(
children: [
Icon(
isMet ? Icons.check_circle : Icons.circle_outlined,
color: isMet ? Colors.green : Colors.grey,
size: 16,
),
const SizedBox(width: 8),
Text(
text,
style: TextStyle(
color: isMet ? Colors.green : Colors.grey,
fontSize: 12,
),
),
],
),
);
}
}

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:sign_in_button/sign_in_button.dart'; import 'package:sign_in_button/sign_in_button.dart';
import 'package:travel_mate/components/loading/laoding_content.dart'; import 'package:travel_mate/components/loading/laoding_content.dart';
import 'package:travel_mate/components/signup/password_requirements.dart';
import 'package:travel_mate/components/signup/sign_up_platform_content.dart'; import 'package:travel_mate/components/signup/sign_up_platform_content.dart';
import 'package:travel_mate/services/auth_service.dart'; import 'package:travel_mate/services/auth_service.dart';
import '../blocs/auth/auth_bloc.dart'; import '../blocs/auth/auth_bloc.dart';
@@ -66,6 +67,18 @@ class _SignUpPageState extends State<SignUpPage> {
if (value.length < 8) { if (value.length < 8) {
return 'Le mot de passe doit contenir au moins 8 caractères'; return 'Le mot de passe doit contenir au moins 8 caractères';
} }
if (!value.contains(RegExp(r'[A-Z]'))) {
return 'Le mot de passe doit contenir une majuscule';
}
if (!value.contains(RegExp(r'[a-z]'))) {
return 'Le mot de passe doit contenir une minuscule';
}
if (!value.contains(RegExp(r'[0-9]'))) {
return 'Le mot de passe doit contenir un chiffre';
}
if (!value.contains(RegExp(r'[!@#\$%^&*(),.?":{}|<>]'))) {
return 'Le mot de passe doit contenir un caractère spécial';
}
return null; return null;
} }
@@ -209,6 +222,7 @@ class _SignUpPageState extends State<SignUpPage> {
controller: _passwordController, controller: _passwordController,
validator: _validatePassword, validator: _validatePassword,
obscureText: _obscurePassword, obscureText: _obscurePassword,
onChanged: (value) => setState(() {}),
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'Mot de passe', labelText: 'Mot de passe',
border: const OutlineInputBorder( border: const OutlineInputBorder(
@@ -229,6 +243,7 @@ class _SignUpPageState extends State<SignUpPage> {
), ),
), ),
), ),
PasswordRequirements(password: _passwordController.text),
const SizedBox(height: 20), const SizedBox(height: 20),
// Champ Confirmation mot de passe // Champ Confirmation mot de passe

View File

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.0.2+3 version: 1.0.3+1
environment: environment:
sdk: ^3.9.2 sdk: ^3.9.2