login auth

This commit is contained in:
2026-07-13 12:21:56 +05:30
parent 523609796e
commit 842c2307d0
4 changed files with 40 additions and 67 deletions

View File

@@ -1,4 +1,7 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError org.gradle.jvmargs=-Xmx1536m -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8
org.gradle.parallel=false
org.gradle.workers.max=1
org.gradle.daemon=false
android.useAndroidX=true android.useAndroidX=true
# This newDsl flag was added by the Flutter template # This newDsl flag was added by the Flutter template
android.newDsl=false android.newDsl=false

View File

@@ -7,6 +7,10 @@ class ApiConstants {
static const String verifyPin = '$baseUrl/customer/verify-pin'; static const String verifyPin = '$baseUrl/customer/verify-pin';
static const String resetPin = '$baseUrl/customer/reset-pin'; static const String resetPin = '$baseUrl/customer/reset-pin';
static const String logout = '$baseUrl/customer/logout'; static const String logout = '$baseUrl/customer/logout';
// ---- Email OTP (Replace Firebase) ----
static const String sendEmailOtp = '$baseUrl/customer/send-email-otp';
static const String verifyEmailOtp = '$baseUrl/customer/verify-email-otp';
// ---- Profile ---- // ---- Profile ----
static const String profile = '$baseUrl/customer/profile'; static const String profile = '$baseUrl/customer/profile';

View File

@@ -30,7 +30,6 @@ class _OtpScreenState extends State<OtpScreen> {
void initState() { void initState() {
super.initState(); super.initState();
_startTimer(); _startTimer();
// Pre-fill demo OTP for the no-backend prototype.
WidgetsBinding.instance.addPostFrameCallback((_) => _nodes[0].requestFocus()); WidgetsBinding.instance.addPostFrameCallback((_) => _nodes[0].requestFocus());
} }
@@ -148,10 +147,10 @@ class _OtpScreenState extends State<OtpScreen> {
height: 88, height: 88,
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: AppColors.primaryFixed, shape: BoxShape.circle), color: AppColors.primaryFixed, shape: BoxShape.circle),
child: const Icon(Icons.sms_rounded, size: 40, color: AppColors.primary), child: const Icon(Icons.mark_email_read_rounded, size: 40, color: AppColors.primary),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
Text('Verify your number', Text('Verify your email',
textAlign: TextAlign.center, style: AppTheme.headlineLg), textAlign: TextAlign.center, style: AppTheme.headlineLg),
const SizedBox(height: 8), const SizedBox(height: 8),
Text.rich( Text.rich(
@@ -160,7 +159,7 @@ class _OtpScreenState extends State<OtpScreen> {
children: [ children: [
const TextSpan(text: 'We sent a 6-digit code to '), const TextSpan(text: 'We sent a 6-digit code to '),
TextSpan( TextSpan(
text: '+91 ${phone.isEmpty ? '98111 22334' : phone}', text: context.read<AppState>().pendingEmail ?? 'your email',
style: AppTheme.labelMd, style: AppTheme.labelMd,
), ),
], ],
@@ -194,9 +193,6 @@ class _OtpScreenState extends State<OtpScreen> {
loading: _loading, loading: _loading,
onPressed: filled ? _verify : null, onPressed: filled ? _verify : null,
), ),
const SizedBox(height: 8),
Text('Tip: enter any 6 digits to continue',
style: AppTheme.caption.copyWith(color: AppColors.outline)),
], ],
), ),
), ),

View File

@@ -133,74 +133,44 @@ class AppState extends ChangeNotifier {
pendingFirstName = firstName; pendingFirstName = firstName;
pendingEmail = email; pendingEmail = email;
isResettingPin = resetPin; isResettingPin = resetPin;
try {
if (kIsWeb) {
debugPrint('⚠️ RUNNING ON WEB: Bypassing Firebase OTP (Mocking success)');
Future.delayed(const Duration(seconds: 1), () {
verificationId = 'mock_verification_id_$fullPhone';
onSuccess();
});
return;
}
debugPrint('===================================='); if (email == null || email.isEmpty) {
debugPrint('🚀 INITIATING LIVE FIREBASE OTP FOR: $fullPhone'); onError('Email address is required for verification.');
await FirebaseAuth.instance.verifyPhoneNumber( return;
phoneNumber: fullPhone, }
verificationCompleted: (PhoneAuthCredential credential) async {
debugPrint('✅ VERIFICATION COMPLETED AUTOMATICALLY'); try {
try { final res = await http.post(
await FirebaseAuth.instance.signInWithCredential(credential); Uri.parse(ApiConstants.sendEmailOtp),
} catch (e) { headers: {'Content-Type': 'application/json'},
debugPrint('❌ ERROR SIGNING IN: $e'); body: jsonEncode({"email": email, "phone": fullPhone}),
onError(e.toString());
}
},
verificationFailed: (FirebaseAuthException e) {
debugPrint('❌ VERIFICATION FAILED: ${e.code} - ${e.message}');
onError(e.message ?? 'Verification failed');
},
codeSent: (String vId, int? resendToken) {
debugPrint('✅ CODE SUCCESSFULLY SENT. Verification ID: $vId');
verificationId = vId;
onSuccess();
},
codeAutoRetrievalTimeout: (String vId) {
debugPrint('⚠️ AUTO RETRIEVAL TIMEOUT. Verification ID: $vId');
verificationId = vId;
},
); );
if (res.statusCode >= 200 && res.statusCode < 300) {
onSuccess();
} else {
final body = jsonDecode(res.body);
onError(body['message'] ?? 'Failed to send verification code.');
}
} catch (e) { } catch (e) {
debugPrint('💥 FIREBASE OTP CRASHED COMPLETELY: $e'); onError('Error: $e');
onError('Firebase OTP Error: $e');
} }
} }
Future<void> verifyOtp(String smsCode, {required Function onSuccess, required Function(String) onError}) async { Future<void> verifyOtp(String smsCode, {required Function onSuccess, required Function(String) onError}) async {
if (verificationId == null) {
onError('Verification ID is missing. Please resend OTP.');
return;
}
try { try {
if (kIsWeb) { final res = await http.post(
debugPrint('⚠️ RUNNING ON WEB: Bypassing Firebase OTP verification (Mocking success)'); Uri.parse(ApiConstants.verifyEmailOtp),
Future.delayed(const Duration(seconds: 1), () { headers: {'Content-Type': 'application/json'},
if (smsCode.length == 6) { body: jsonEncode({"email": pendingEmail, "otp": smsCode}),
onSuccess();
} else {
onError('Invalid mock OTP code (must be 6 digits).');
}
});
return;
}
PhoneAuthCredential credential = PhoneAuthProvider.credential(
verificationId: verificationId!,
smsCode: smsCode,
); );
await FirebaseAuth.instance.signInWithCredential(credential);
onSuccess(); if (res.statusCode >= 200 && res.statusCode < 300) {
onSuccess();
} else {
final body = jsonDecode(res.body);
onError(body['message'] ?? 'Invalid verification code.');
}
} catch (e) { } catch (e) {
onError('Error: $e'); onError('Error: $e');
} }