feat: SMS OTP auth + phone verification gate + improved login UI

- Usuario model: add isPhoneVerified field from is_phone_verified
- auth_provider.dart: fix access_token key, add _navigateAfterAuth gate
  (redirects to phoneLoginRoute if phone not verified), add verifyPhoneNumber,
  signInWithOTP, verifyPhoneNumberForLink, linkPhoneWithOTP methods
- phone_login_view.dart: full rewrite with logo, +57 prefix, two-step OTP flow
  (phone input → code input), 60s resend timer, email login fallback

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-06-25 15:54:15 -05:00
co-authored by Claude Sonnet 4.6
parent f941270bd9
commit cc18246e1f
3 changed files with 265 additions and 108 deletions
+11 -2
View File
@@ -21,6 +21,14 @@ class AuthProvider extends ChangeNotifier {
isAuthenticated();
}
void _navigateAfterAuth() {
if (user?.isPhoneVerified == false) {
NavigationService.replaceTo(Flurorouter.phoneLoginRoute);
} else {
NavigationService.replaceTo(Flurorouter.dashboardRoute);
}
}
Future<void> login(String email, String password) async {
try {
final data = await _api.post('/auth/login', {'email': email, 'password': password});
@@ -29,7 +37,7 @@ class AuthProvider extends ChangeNotifier {
userAverageScore = await _loadAverageScore(user!.id);
authStatus = AuthStatus.authenticated;
notifyListeners();
NavigationService.replaceTo(Flurorouter.dashboardRoute);
_navigateAfterAuth();
} catch (e) {
authStatus = AuthStatus.notAuthenticated;
notifyListeners();
@@ -48,7 +56,7 @@ class AuthProvider extends ChangeNotifier {
user = Usuario.fromDocument(data['user'] as Map<String, dynamic>);
authStatus = AuthStatus.authenticated;
notifyListeners();
NavigationService.replaceTo(Flurorouter.dashboardRoute);
_navigateAfterAuth();
} catch (e) {
authStatus = AuthStatus.notAuthenticated;
notifyListeners();
@@ -70,6 +78,7 @@ class AuthProvider extends ChangeNotifier {
final data = await _api.post('/auth/phone', {'phone': phoneNumber, 'code': smsCode});
await _api.saveToken(data['access_token'] as String);
user = Usuario.fromDocument(data['user'] as Map<String, dynamic>);
userAverageScore = await _loadAverageScore(user!.id);
authStatus = AuthStatus.authenticated;
notifyListeners();
NavigationService.replaceTo(Flurorouter.dashboardRoute);