post_enrollment_app/lib/pages/email_verify.dart

1482 lines
66 KiB
Dart
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// import 'package:firebase_auth/firebase_auth.dart';
// import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart';
import 'package:nhance_app_pwa/pages/service/SessionManager.dart';
import 'package:nhance_app_pwa/pages/service/TokenService.dart';
import 'package:nhance_app_pwa/pages/service/data_manager.dart';
import 'package:pinput/pinput.dart';
import 'dart:async';
import 'package:flutter/gestures.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:io';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:jwt_decode/jwt_decode.dart';
import '../config/environment.dart';
import '../customAppBar/responsive.dart';
import '../customAppBar/toastHelper.dart';
import '../models/platform_helper_mobile.dart'
if (dart.library.html) '../models/platform_helper_other.dart';
// import 'dart:html' as html;
import '../pages/helpers/html_stub.dart'
if (dart.library.html) '../pages/helpers/html_web.dart';
import 'package:nhance_app_pwa/logger.dart';
// import '../pages/helpers/html_stub.dart' if (dart.library.html) 'html_web.dart';
class MyEmailVerify extends StatefulWidget {
final String type; // 'email' or 'mobile'
final String value;
const MyEmailVerify({super.key, required this.type, required this.value});
@override
State<MyEmailVerify> createState() => _MyEmailVerifyState();
}
class _MyEmailVerifyState extends State<MyEmailVerify> {
late ApiService apiService;
TextEditingController _otpController = TextEditingController();
final _formKey = GlobalKey<FormState>();
late Timer _timer;
int _secondsRemaining = 60;
bool _isTimerRunning = false;
dynamic enrollmentEmpClientBranchId;
dynamic enrollmentEmpCodeString;
dynamic enrollmentEmpPrimaryId;
dynamic enrollmentGpaEmpName;
dynamic enrollmentClient_id;
dynamic enrollmentEmp_status;
dynamic empCodeString;
dynamic empClientBranchId;
dynamic empPrimaryId;
dynamic gpaEmpName;
dynamic client_id;
dynamic _preToken;
dynamic _postToken;
dynamic clientName;
dynamic clientLogo;
dynamic emp_status;
String? fcmToken;
String? apnsToken;
late String verificationId;
// final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
// final FirebaseAuth _auth = FirebaseAuth.instance;
bool _isLoading = false;
bool _isOtpVerified = false;
late String _verificationId;
dynamic empMobileNo;
dynamic empEmailid;
late SessionManager session;
final dataManager = DataManager();
@override
void initState() {
super.initState();
apiService = ApiService(context);
startTimer();
}
@override
void dispose() {
_timer.cancel();
super.dispose();
}
// Future<void> initNotification() async {
// try {
// // Request permission
// NotificationSettings settings =
// await _firebaseMessaging.requestPermission(
// alert: true,
// badge: true,
// sound: true,
// );
// logDebug('🔔 Permission: ${settings.authorizationStatus}');
//
// if (Platform.isIOS || Platform.isMacOS) {
// // Get APNS token
// apnsToken = await _firebaseMessaging.getAPNSToken();
// logDebug('📱 APNS Token (iOS): $apnsToken');
//
// // Retry if null
// if (apnsToken == null) {
// await Future.delayed(const Duration(seconds: 3));
// apnsToken = await _firebaseMessaging.getAPNSToken();
// logDebug('🔁 Retried APNS Token: $apnsToken');
// }
//
// if (apnsToken != null) {
// await sendDeviceToken(apnsToken!);
// }
// } else if (Platform.isAndroid) {
// // Get FCM token
// fcmToken = await _firebaseMessaging.getToken();
// logDebug('🔥 FCM Token (Android): $fcmToken');
//
// if (fcmToken != null) {
// await sendDeviceToken(fcmToken!);
// }
// }
//
// // Background handler
// FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
//
// // Foreground listener
// FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// logDebug('💬 Message: ${message.notification?.title}');
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(content: Text(message.notification?.title ?? 'New Notification')),
// );
// });
// } catch (e) {
// logDebug('❌ Notification init error: $e');
// }
// }
// Future<void> initNotification() async {
// await _firebaseMessaging.requestPermission();
// fCMToken = await _firebaseMessaging.getToken();
// logDebug('Token : $fCMToken');
// sendDeviceToken(fCMToken);
// FirebaseMessaging.onBackgroundMessage(handleBackgroundMessage);
// }
//
// Future<void> handleBackgroundMessage(RemoteMessage message) async {
// logDebug('Title ${message.notification?.title}');
// logDebug('Body ${message.notification?.body}');
// logDebug('Playload ${message.data}');
// }
Future<void> sendDeviceToken(deviceToken) async {
// Retrieve the passed mobile number value
final session = SessionManager();
try {
final response = await http.post(
Uri.parse(Environment.apiUrl + 'storeFireBase'),
body: json.encode(
{'mobile': session.mobileNo, 'firebase_token': deviceToken}),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
'Authorization': 'Bearer $_preToken',
'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
},
);
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
logDebug('data: $data');
String status = data['status'];
logDebug(status);
if (status == 'success') {
logDebug('Token Store Successfully');
} else {
logDebug('Please try again');
}
} else {
throw Exception('Failed to store');
}
} catch (e) {
logDebug('Error: $e');
}
}
void startTimer() {
_isTimerRunning = true;
_timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {
setState(() {
if (_secondsRemaining > 0) {
_secondsRemaining--;
} else {
_isTimerRunning = false;
_timer.cancel();
}
});
});
}
void verifyOTP(String otp) async {
if (_isLoading) return; // prevent double tap
setState(() {
_isLoading = true;
});
try {
// logDebug('EMAIL PARAMS : ${widget.email} - OTP : $otp');
final Map<String, dynamic> payload = (widget.type == 'mobile')
? {'otp': _otpController.text, 'mobile_number': widget.value}
: {'otp': _otpController.text, 'email_id': widget.value};
final response = await http.post(
Uri.parse(Environment.apiUrlEnrollment + 'getVerifiedUserData'),
body: json.encode(payload),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
},
);
logDebug('response : ${response.statusCode}');
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
logDebug('data: $data');
/// Check API response status first
if (data['status'] == 'Invalid OTP') {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear();
ToastHelper.showErrorToast(context, data['message'] ?? 'Invalid OTP');
logDebug('API error → ${data['message']}');
return; // stop execution
}
if (data['status'] == 'OTP is required') {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear();
ToastHelper.showErrorToast(context, data['message'] ?? 'OTP is required');
logDebug('API error → ${data['message']}');
return; // stop execution
}
// --- Extract tokens safely ---
String? preToken;
if (data['data'] is String) {
preToken = data['data'];
}
String? postToken;
if (data['post_enrollment'] != null &&
data['post_enrollment']['data'] is String) {
postToken = data['post_enrollment']['data'];
}
// Save tokens
await TokenService.saveTokens(preToken: preToken, postToken: postToken);
logDebug('Tokens saved → preToken: $preToken, postToken: $postToken');
_preToken = preToken;
String status = data['status'];
// Directly access the post_enrollment data
Map<String, dynamic>? post;
if (data['post_enrollment'] != null &&
data['post_enrollment'] is Map<String, dynamic>) {
post = data['post_enrollment'];
}
logDebug('post: $post');
_postToken = postToken;
if (post != null && post['status'] == 'success') {
setState(() {
_isOtpVerified = true; // ✅ LOCK
});
postSuccessData(post, data);
} else if (status == 'success') {
setState(() {
_isOtpVerified = true; // ✅ LOCK
});
enrollmentSuccessData(data);
} else {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear();
ToastHelper.showErrorToast(context, 'OTP verification failed. Please try again.');
// Show a Snackbar if the OTP is invalid
logDebug('OTP verification failed. Please try again.');
}
} else if (response.statusCode == 401) {
setState(() {
_isLoading = false;
});
await SessionManager().clear();
ToastHelper.showErrorToast(context, 'Session Out');
if (!context.mounted) return;
context.go('/login');
} else if (response.statusCode == 429) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else if (response.statusCode == 403) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else if (response.statusCode == 451) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else {
setState(() {
_isLoading = false;
});
throw Exception('Failed to load data');
}
} catch (e) {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear();
logDebug('Error: $e');
ToastHelper.showWarningToast(context, 'Unable to process. Please try again later');
// Show a Snackbar if there's an error while verifying OTP
logDebug('Failed to verify OTP. Please try again.');
} finally {
if (mounted) {
setState(() {
_isLoading = false;
});
}
}
}
void loginUser({
required dynamic gpaEmpName,
required dynamic empPrimaryId,
required dynamic empCodeString,
required dynamic client_id,
required dynamic empClientBranchId,
}) {
HtmlHelper.saveLoginData({
'gpaEmpName': gpaEmpName,
'empPrimaryId': empPrimaryId,
'empCode': empCodeString,
'client_id': client_id,
'empClientBranchId': empClientBranchId,
});
logDebug('Successfully Login');
}
void postSuccessData(post, data) async {
String status = data['status'];
String postStatus = post['status'];
if (postStatus == 'success') {
final SharedPreferences prefs = await SharedPreferences.getInstance();
// prefs.setString('_postToken', post['data']);
await SessionManager().initializeFromPostToken(post['data']);
session = await SessionManager();
// if (session.client_id != null && session.client_id!.isNotEmpty) {
// await dataManager.loadSelfEmployeeProfile(
// clientId: session.client_id!,
// empCode: session.empCodeString!,
// clientBranchId: session.empClientBranchId!,
// );
// }
// // Decode the JWT token received from the API response
// Map<String, dynamic>? decodedToken = Jwt.parseJwt(post['data']);
// logDebug('PostdecodedToken : $decodedToken');
// empClientBranchId = decodedToken['client_branch_id'];
// prefs.setString('empClientBranchId', empClientBranchId);
// empCodeString = decodedToken['emp_code'].toString();
// prefs.setString('empCode', empCodeString);
// empPrimaryId = decodedToken['id'];
// prefs.setString('empPrimaryId', empPrimaryId);
// gpaEmpName = decodedToken['name'].toString();
// prefs.setString('gpaEmpName', gpaEmpName);
// client_id = decodedToken['client_id'];
// prefs.setString('client_id', client_id);
// emp_status = decodedToken['emp_status'];
// prefs.setString('emp_status', emp_status);
// // getClientLogoAndDetails();
logDebug('Successfully Login');
// loginUser(
// gpaEmpName: session.gpaEmpName,
// empPrimaryId: session.empPrimaryId,
// empCodeString: session.empCodeString,
// client_id: session.client_id,
// empClientBranchId: session.empClientBranchId,
// );
// if (kIsWeb) {
// html.window.localStorage['gpaEmpName'] = gpaEmpName;
// html.window.localStorage['empPrimaryId'] = empPrimaryId;
// html.window.localStorage['empCode'] = empCodeString;
// html.window.localStorage['client_id'] = client_id;
// html.window.localStorage['empClientBranchId'] = empClientBranchId;
//
// // Dispatch a custom event with a message
//
// // 🌟 Dispatch event to notify JavaScript
// html.window.dispatchEvent(
// html.CustomEvent('userLoggedIn', detail: {'status': 'success'}));
//
// logDebug("✅ User logged in! LocalStorage values set.");
//
// logDebug('Successfully Login');
// }
// getClientLogoAndDetails();
// Redirect to another page
}
if (status == 'success') {
final SharedPreferences prefs = await SharedPreferences.getInstance();
// prefs.setString('enrollToken', data['data']);
await SessionManager().initializeFromPreToken(data['data']);
session = await SessionManager();
// Decode the JWT token received from the API response
// Map<String, dynamic>? decodedToken = Jwt.parseJwt(data['data']);
// logDebug('enrolldecodedToken : $decodedToken');
// enrollmentEmpClientBranchId = decodedToken['client_branch_id'];
// prefs.setString(
// 'enrollmentEmpClientBranchId', enrollmentEmpClientBranchId);
// enrollmentEmpCodeString = decodedToken['emp_code'].toString();
// prefs.setString('enrollmentEmpCodeString', enrollmentEmpCodeString);
// enrollmentEmpPrimaryId = decodedToken['id'];
// prefs.setString('enrollmentEmpPrimaryId', enrollmentEmpPrimaryId);
// enrollmentGpaEmpName = decodedToken['name'].toString();
// prefs.setString('enrollmentGpaEmpName', enrollmentGpaEmpName);
// enrollmentClient_id = decodedToken['client_id'];
// prefs.setString('enrollmentClient_id', enrollmentClient_id);
// enrollmentEmp_status = decodedToken['emp_status'];
// prefs.setString('enrollmentEmp_status', enrollmentEmp_status);
// getClientLogoAndDetails();
}
//
// if(kIsWeb) {
// html.window.localStorage['gpaEmpName'] = gpaEmpName;
// html.window.localStorage['empPrimaryId'] = empPrimaryId;
// html.window.localStorage['empCode'] = empCodeString;
// html.window.localStorage['client_id'] = client_id;
// html.window.localStorage['empClientBranchId'] = empClientBranchId;
//
// // Dispatch a custom event with a message
//
// // 🌟 Dispatch event to notify JavaScript
// html.window.dispatchEvent(
// html.CustomEvent('userLoggedIn', detail: {'status': 'success'}));
//
// logDebug("✅ User logged in! LocalStorage values set.");
//
// logDebug('Successfully Login');
// }
// final SharedPreferences prefs = await SharedPreferences.getInstance();
// final _postToken = prefs.getString('_postToken');
// int skipStatus = prefs.getInt('skipStatus') ?? 1;
// final mpinText = prefs.getString('mpinText');
// logDebug(isMobilePlatform());
if (isMobilePlatform()) {
// if (prefs.containsKey('mpin') && mpinText == 'Mpin - exist') {
if (_postToken != null && _postToken.isNotEmpty) {
final SharedPreferences prefs = await SharedPreferences.getInstance();
if (widget.type == 'mobile') {
prefs.setString('empMobileNo', widget.value);
} else {
prefs.setString('empEmailid', widget.value);
}
// await initNotification();
checkLoginPin(context);
}
// }
} else {
if (_postToken != null && _postToken.isNotEmpty) {
final SharedPreferences prefs = await SharedPreferences.getInstance();
// prefs.setString('empEmailid', widget.email);
ToastHelper.showSuccessToast(context, 'Successfully Logged In');
if (session.client_id != null && session.client_id!.isNotEmpty) {
prefs.setBool('isRetailLoggedIn', false);
checkPassword(context, session.empEmailCorporate, session.client_id, 'home');
} else {
if (session.client_id == null || session.client_id!.isEmpty ||
session.empCodeString == null || session.empCodeString!.isEmpty ||
session.empClientBranchId == null || session.empClientBranchId!.isEmpty) {
prefs.setBool('isRetailLoggedIn', true);
}
// context.go('/home');
context.replace('/home');
}
// if (emp_status == 'enrolled' || emp_status == 'active') {
// context.go('/home');
// Navigator.pushReplacementNamed(context, 'home');
// } else {
// Navigator.pushReplacementNamed(context, 'empDetails');
// }
}
}
}
void enrollmentSuccessData(data) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
// prefs.setString('enrollToken', data['data']);
await SessionManager().initializeFromPreToken(data['data']);
session = await SessionManager();
// // Decode the JWT token received from the API response
// Map<String, dynamic>? decodedToken = Jwt.parseJwt(data['data']);
// logDebug('decodedToken : $decodedToken');
// enrollmentEmpClientBranchId = decodedToken['client_branch_id'];
// prefs.setString('enrollmentEmpClientBranchId', enrollmentEmpClientBranchId);
// enrollmentEmpCodeString = decodedToken['emp_code'].toString();
// prefs.setString('enrollmentEmpCodeString', enrollmentEmpCodeString);
// enrollmentEmpPrimaryId = decodedToken['id'];
// prefs.setString('enrollmentEmpPrimaryId', enrollmentEmpPrimaryId);
// enrollmentGpaEmpName = decodedToken['name'].toString();
// prefs.setString('enrollmentGpaEmpName', enrollmentGpaEmpName);
// enrollmentClient_id = decodedToken['client_id'];
// prefs.setString('enrollmentClient_id', enrollmentClient_id);
// enrollmentEmp_status = decodedToken['emp_status'];
// prefs.setString('enrollmentEmp_status', enrollmentEmp_status);
// getClientLogoAndDetails();
logDebug('Successfully Login');
// Redirect to another page
// final enrollToken = prefs.getString('enrollToken');
// int skipStatus = prefs.getInt('skipStatus') ?? 1;
// final mpinText = prefs.getString('mpinText');
// logDebug(isMobilePlatform());
if (isMobilePlatform()) {
// if (prefs.containsKey('mpin') && mpinText == 'Mpin - exist') {
if (_preToken != null && _preToken.isNotEmpty) {
final SharedPreferences prefs = await SharedPreferences.getInstance();
if (widget.type == 'mobile') {
prefs.setString('empMobileNo', widget.value);
} else {
prefs.setString('empEmailid', widget.value);
}
// await initNotification();
checkLoginPin(context);
}
// }
} else {
if (_preToken != null && _preToken.isNotEmpty) {
ToastHelper.showSuccessToast(context, 'Successfully Logged In');
checkPassword(context,session.enrollmentEmailCorporate,session.enrollmentClient_id,'empDetails');
// if (emp_status == 'enrolled' || emp_status == 'active') {
// Navigator.pushReplacementNamed(context, 'home');
// } else {
// context.go('/empDetails');
// Navigator.pushReplacementNamed(context, 'empDetails');
// }
}
}
}
void _resendOTP() {
setState(() {
_otpController.text = '';
_secondsRemaining = 60;
_isTimerRunning = true;
_isLoading = false;
});
startTimer();
verifyMobileAndEmailNumber();
}
Future<void> verifyMobileAndEmailNumber() async {
try {
// var enteredMobileNumber = mobileController.text;
final Map<String, dynamic> payload = (widget.type == 'mobile')
? {'mobile_number': widget.value}
: {'email': widget.value};
String apiEndpoint = (widget.type == 'mobile')
? Environment.apiUrlEnrollment + 'verifyEmployeeNumber'
: Environment.apiUrlEnrollment + 'verifyEmployeeEmailId';
final response = await http.post(
Uri.parse(apiEndpoint),
body: json.encode(payload),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
},
);
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
bool userVerification = data['data']['user_verification'];
String message = data['data']['message'];
if (userVerification) {
if (widget.type == 'mobile') {
ToastHelper.showSuccessToast(
context, 'Verification code sent to ${widget.value}');
} else {
ToastHelper.showSuccessToast(
context, 'Verification code sent to ${widget.value}');
}
} else {
ToastHelper.showErrorToast(context, message);
logDebug('Invalid mobile number');
}
} else if (response.statusCode == 429) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else if (response.statusCode == 403) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else if (response.statusCode == 451) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else {
ToastHelper.showErrorToast(context, 'Unable to process. Please try again later');
throw Exception('Failed to verify mobile number');
}
} catch (e) {
ToastHelper.showErrorToast(context, 'Unable to process. Please try again later');
logDebug('Error: $e');
}
}
Future<void> checkLoginPin(BuildContext context) async {
logDebug('checkLoginPin');
try {
final SharedPreferences prefs = await SharedPreferences.getInstance();
empMobileNo = prefs.getString('empMobileNo');
empEmailid = prefs.getString('empEmailid');
logDebug('empMobileNo $empMobileNo');
logDebug('empEmailid $empEmailid');
// _token = prefs.getString('token');
var params = {};
if (empMobileNo != null && empMobileNo.isNotEmpty) {
params = {'mobile_number': empMobileNo};
} else if (empEmailid != null && empEmailid.isNotEmpty) {
params = {'email_id': empEmailid};
}
logDebug('params $params');
final response = await http.post(
Uri.parse(Environment.apiUrlEnrollment + 'checkMpin'),
body: json.encode(params),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
},
);
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
if (data['status'] == 'success') {
if (data['data'] != null) {
prefs.setString('mpinText', data['data']);
}
if (data['Mpin'] != null) {
prefs.setString('mpin', data['Mpin']);
}
if (data['is_biometric_enabled'] != null) {
prefs.setString(
'is_biometric_enabled', data['is_biometric_enabled']);
}
if (data['is_mpin_skipped'] != null) {
prefs.setString('is_mpin_skipped', data['is_mpin_skipped']);
}
if (_postToken != null && _postToken.isNotEmpty) {
ToastHelper.showSuccessToast(context, 'Successfully Logged In');
SessionManager().unlockMobileAppSession();
context.replace('/home');
// context.go('/home');
// Navigator.pushReplacementNamed(context, 'home');
} else {
SessionManager().unlockMobileAppSession();
context.replace('/empDetails');
// context.go('/empDetails');
// Navigator.pushReplacementNamed(context, 'empDetails');
}
// if (data['is_mpin_skipped'] != null &&
// data['is_mpin_skipped'] == '0') {
// context.go('/pinPage');
// // Navigator.pushReplacementNamed(context, 'pinPage');
// } else {
// if (_postToken != null && _postToken.isNotEmpty) {
// ToastHelper.showSuccessToast(context, 'Successfully Login');
// context.go('/home');
// // Navigator.pushReplacementNamed(context, 'home');
// } else {
// context.go('/empDetails');
// // Navigator.pushReplacementNamed(context, 'empDetails');
// }
// }
} else {
context.go('/pinSettingPage');
// Navigator.pushReplacementNamed(context, 'pinSettingPage');
}
} else if (response.statusCode == 429) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else if (response.statusCode == 403) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else if (response.statusCode == 451) {
setState(() {
_isLoading = false;
});
Map<String, dynamic> data = json.decode(response.body);
if (data.containsKey('error')) {
final message = data['error']['message'];
ToastHelper.showErrorToast(context, message);
} else {
final message = data['message'];
ToastHelper.showErrorToast(context, message);
}
} else {
ToastHelper.showErrorToast(context, 'Unable to process. Please try again later');
throw Exception('Failed to verify pin number');
}
} catch (e) {
ToastHelper.showErrorToast(context, 'Unable to process. Please try again later');
logDebug('Error: $e');
}
}
Future<void> checkPassword(BuildContext context,email_id,client_id,route) async {
logDebug('checkLoginPin');
try {
final params = {'email_id': email_id,'client_id':client_id};
logDebug('params $params');
final response = await http.post(
Uri.parse(Environment.apiUrlEnrollment + 'checkPassword'),
body: json.encode(params),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
},
);
if (response.statusCode == 200) {
Map<String, dynamic> data = json.decode(response.body);
if(data['status'] == 'success') {
context.replace('/${route}');
// context.go('/${route}');
} else if(data['status'] == 'failed'){
logDebug('setPassword');
// goNamed
context.replaceNamed(
'setPassword',
queryParameters: {
'email': email_id,
'client_id': client_id,
'route': route,
},
);
}
} else {
ToastHelper.showErrorToast(context, 'Unable to process. Please try again later');
throw Exception('Failed to verify pin number');
}
} catch (e) {
ToastHelper.showErrorToast(context, 'Unable to process. Please try again later');
logDebug('Error: $e');
}
}
Future<void> getClientLogoAndDetails() async {
var url = Uri.parse(Environment.apiUrlEnrollment +
'getClientDetails?post_client_id=${session.client_id}&post_branch_id=${session.empClientBranchId}&pre_client_id=${session.enrollmentClient_id}&pre_branch_id=${session.enrollmentEmpClientBranchId}');
try {
var response = await http.get(
url,
headers: {
'Authorization':
'Bearer $_preToken', // Add token to the Authorization header
'APP-SIGNATURE': 'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
},
);
if (response.statusCode == 200) {
// logDebug('response.statusCode == 200');
Map<String, dynamic> data = json.decode(response.body);
// logDebug(data);
if (data.containsKey('data')) {
dynamic clientDetails = data['data'];
final SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString(
'clientLogo', clientDetails['client']['client_logo']);
await prefs.setString(
'clientName', clientDetails['client']['client_name']);
await prefs.setString(
'addon_subheading', clientDetails['client']['addon_subheading']);
setState(() {
// dynamic clientDetails = data['data'];
// logDebug(clientDetails);
clientName = clientDetails['client']['client_name'];
logDebug(clientName);
clientLogo = clientDetails['client']['client_logo'];
logDebug(clientLogo);
});
} else {
// Handle other status messages if needed
// ToastHelper.showErrorToast(
// context, 'API request failed with status: ${data['status']}');
logDebug('API request failed with status: ${data['status']}');
}
} else {
// Handle other status codes
// ToastHelper.showErrorToast(
// context, 'Request failed with status: ${response.statusCode}');
logDebug('Request failed with status: ${response.statusCode}');
}
} catch (e) {
// Handle exceptions
logDebug('Exception occurred: $e');
}
}
@override
Widget build(BuildContext context) {
// Retrieve the passed mobile number value
// final String mobileNumber =
// ModalRoute.of(context)!.settings.arguments as String;
Size _size = MediaQuery.of(context).size;
EdgeInsets marginInsets = EdgeInsets.zero;
if (Responsive.isDesktop(context)) {
marginInsets = const EdgeInsets.only(
left: 0,
right: 0,
bottom: 0,
top: 0,
);
} else if (Responsive.isMobile(context)) {
marginInsets = const EdgeInsets.only(
left: 25, // Example value for mobile
right: 25, // Example value for mobile
bottom: 0, // Example value for mobile
top: 0, // Example value for mobile
);
} else if (Responsive.isTablet(context)) {
marginInsets = const EdgeInsets.only(
left: 25, // Example value for mobile
right: 25, // Example value for mobile
bottom: 0, // Example value for mobile
top: 0, // Example value for mobile
);
}
final defaultPinTheme = PinTheme(
width: 56,
height: 56,
textStyle: TextStyle(
fontSize: 20,
color: Color.fromRGBO(30, 60, 87, 1),
fontWeight: FontWeight.w600,
),
decoration: BoxDecoration(
border: Border.all(color: Color.fromRGBO(234, 239, 243, 1)),
borderRadius: BorderRadius.circular(20),
),
);
final focusedPinTheme = defaultPinTheme.copyDecorationWith(
border: Border.all(color: Color.fromRGBO(114, 178, 238, 1)),
borderRadius: BorderRadius.circular(8),
);
final submittedPinTheme = defaultPinTheme.copyWith(
decoration: defaultPinTheme.decoration?.copyWith(
color: Color.fromRGBO(234, 239, 243, 1),
),
);
return WillPopScope(
onWillPop: () async {
context.go('/login');
// Navigator.pushReplacementNamed(context, 'login');
return false;
},
child: Scaffold(
body: SingleChildScrollView(
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
child: Container(
height: _size.height,
color: Colors.white,
child: Stack(
children: [
Visibility(
visible: _size.width <= 1100,
child: ClipRRect(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
child: Container(
height: _size.height / 3,
width: double.infinity,
color: Color(0xFFFFFCE5),
child: Stack(
children: [
Column(
children: [
SizedBox(
height: _size.height /
6.4), // Adjust the spacing between the rows
Row(
mainAxisAlignment: MainAxisAlignment
.center, // Align to the center
children: [
Expanded(
flex: Responsive.isDesktop(context)
? 10
: 12,
child: Align(
alignment: Responsive.isDesktop(context)
? Alignment.centerLeft
: Alignment.bottomCenter,
child: Image.asset(
'assets/nhance_app_logo.png',
width: 150,
height: 150,
),
),
),
],
),
],
),
],
),
),
),
),
Container(
margin: marginInsets,
alignment: Responsive.isDesktop(context) ? Alignment.center : Alignment.bottomCenter,
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
children: [
Row(
children: [
Expanded(
flex: _size.width < 1100 ? 6 : 12,
child: Container(
margin: _size.width > 1100
? EdgeInsets.only(left: 20, right: 20)
: EdgeInsets.only(left: 0, right: 0),
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
if (!Responsive.isMobile(context) &&
!Responsive.isTablet(context))...[
Row(
children: [
Expanded(
flex: 10,
child: Align(
alignment: Responsive
.isDesktop(context)
? Alignment.center
: Alignment
.bottomCenter, // Align to the start
child: _size.width <= 1100
? Image.asset(
'assets/nhance_app_logo.png',
width: 150,
height: 150,
)
: _size.width > 1100
? Image.asset(
'assets/nhance_app_logo.png',
width: 150,
height: 150,
)
: Image.asset(
'assets/nhance_app_logo.png',
width: 150,
height: 150,
),
)),
],
),
SizedBox(height: 10),
],
// SizedBox(
// height: Responsive.isDesktop(context)
// ? _size.height * 0.1
// : 10,
// ),
Container(
margin: Responsive.isDesktop(context)
? EdgeInsets.symmetric(
horizontal: 150)
: EdgeInsets.symmetric(
horizontal: 0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.center,
children: [
Text(
"Welcome to Nhance",
style: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
],
),
),
SizedBox(height: 10),
Container(
margin: Responsive.isDesktop(context)
? EdgeInsets.symmetric(
horizontal: 150)
: EdgeInsets.symmetric(
horizontal: 0),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text:
"Please enter the one-time usage code sent to your ",
style: TextStyle(
fontSize: 12,
height: 1.5,
color: Color(0xFF000000)),
children: [
TextSpan(
text: widget.type == 'mobile'
? 'mobile number ${widget.value}'
: 'Email Id ${widget.value}',
),
TextSpan(
text: widget.type == 'mobile'
? ' (Change Mobile)'
: ' (Change Email)',
style: TextStyle(
fontSize: 12,
color: Color(
0xFFE26728)), // Change color as desired
recognizer:
TapGestureRecognizer()
..onTap = () {
context.go('/login');
// Navigator.pushNamed(
// context, 'login');
},
),
],
),
),
),
SizedBox(height: 15),
Container(
margin: Responsive.isDesktop(context)
? EdgeInsets.symmetric(
horizontal: 150)
: EdgeInsets.symmetric(
horizontal: 0),
child: Pinput(
length: 6,
// defaultPinTheme: defaultPinTheme,
// focusedPinTheme: focusedPinTheme,
// submittedPinTheme: submittedPinTheme,
inputFormatters: [
FilteringTextInputFormatter
.digitsOnly, // ✅ allows only 09
],
keyboardType: TextInputType.number,
textInputAction:
TextInputAction.done,
showCursor: true,
controller: _otpController,
onCompleted: (value) {
if (_isLoading ||
_isOtpVerified) {
return;
}
if (_formKey.currentState
?.validate() ==
true) {
verifyOTP(value.trim());
}
},
onSubmitted: (value) {
if (_isLoading ||
_isOtpVerified) {
return;
}
if (_formKey.currentState
?.validate() ==
true) {
verifyOTP(value.trim());
}
},
validator: (value) {
if (value == null || value.isEmpty) {
return 'OTP is required';
}
if (value.length < 6) {
return 'Please enter a valid 6-digit OTP';
}
return null;
},
),
),
SizedBox(height: 10),
Container(
margin: Responsive.isDesktop(context)
? EdgeInsets.symmetric(
horizontal: 150)
: EdgeInsets.symmetric(
horizontal: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment
.end, // Align text to the right
children: [
_isTimerRunning
? Text(
"Resend OTP in $_secondsRemaining seconds",
style:
GoogleFonts.poppins(
color:
Colors.black),
)
: InkWell(
onTap: () {
_resendOTP();
},
child: Text(
"Resend OTP",
style:
GoogleFonts.poppins(
color: Colors
.blue),
),
),
],
),
),
SizedBox(height: 10),
Container(
margin: Responsive.isDesktop(context)
? EdgeInsets.symmetric(
horizontal: 150)
: EdgeInsets.symmetric(
horizontal: 0),
child: SizedBox(
width: double.infinity,
height: 45,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor:
Color(0xFF00989E),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10),
),
),
onPressed: (_isLoading || _isOtpVerified)
? null
: () {
if (_formKey.currentState!.validate()) {
verifyOTP(_otpController.text.trim());
}
},
child: _isLoading
? CircularProgressIndicator(
valueColor:
AlwaysStoppedAnimation<
Color>(
Color(0xFF00989E),
),
)
: Text( "Submit",
style: GoogleFonts
.poppins(
color: Color(
0xFFFFFFFF),
),
)
),
),
),
// _size.width > 1100
// ? Container(
// margin: EdgeInsets.symmetric(
// horizontal: 150),
// child: Column(
// children: [
// SizedBox(height: 20),
// Text(
// "Benefits of Login",
// style:
// GoogleFonts.poppins(
// fontSize: 20,
// fontWeight:
// FontWeight.bold,
// ),
// ),
// SizedBox(height: 15),
// ],
// ))
// : SizedBox(),
// _size.width > 1100
// ? Container(
// margin: EdgeInsets.symmetric(
// horizontal: 150),
// child: Row(
// mainAxisAlignment:
// MainAxisAlignment.center,
// children: [
// Expanded(
// flex: 6,
// child: Container(
// padding: EdgeInsets
// .symmetric(
// vertical: 8),
// child: Row(
// mainAxisAlignment:
// MainAxisAlignment
// .center,
// children: [
// Expanded(
// child: Container(
// padding: EdgeInsets
// .symmetric(
// vertical:
// 12),
// decoration:
// BoxDecoration(
// border:
// Border(
// right:
// BorderSide(
// width: 1,
// color: Colors
// .black,
// ),
// ),
// ),
// child: Column(
// children: [
// Icon(
// Icons
// .policy,
// color: Color(
// 0xFFE26728)),
// SizedBox(
// height:
// 10),
// Text(
// "View Policy",
// style: GoogleFonts
// .poppins()),
// ],
// ),
// ),
// ),
// Expanded(
// child: Container(
// padding: EdgeInsets
// .symmetric(
// vertical:
// 12),
// child: Column(
// children: [
// Icon(
// Icons
// .edit,
// color: Color(
// 0xFFE26728)),
// SizedBox(
// height:
// 10),
// Text(
// "Manage Claims",
// style: GoogleFonts
// .poppins()),
// ],
// ),
// ),
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// )
// : SizedBox(
// height: Responsive.isDesktop(
// context)
// ? _size.height * 0.1
// : _size.height * 0.2,
// ),
SizedBox(
height: 15,
),
Container(
alignment: Responsive.isDesktop(context) ? Alignment.center : Alignment.bottomCenter,
padding:
EdgeInsets.symmetric(vertical: 8),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
text:
'By continuing, you agree with our ',
style: GoogleFonts.poppins(
color: Colors.black,
fontSize: 9,
),
children: <TextSpan>[
TextSpan(
text: 'privacy policy ',
style: GoogleFonts.poppins(
color: Color(0xFF00989E),
fontSize: 9,
),
),
TextSpan(
text: 'and ',
style: GoogleFonts.poppins(
color: Colors.black,
fontSize: 9,
),
),
TextSpan(
text: 'terms of use',
style: GoogleFonts.poppins(
color: Color(0xFF00989E),
fontSize: 9,
),
),
],
),
),
),
SizedBox(
height: Responsive.isDesktop(context)
? _size.height * 0.2
: _size.height * 0.3,
),
],
),
),
),
if (_size.width > 1100)
Expanded(
flex: _size.width < 1100 ? 6 : 12,
child: LayoutBuilder(
builder: (BuildContext context,
BoxConstraints constraints) {
if (constraints.maxWidth > 600) {
return Image.asset(
'assets/login_web.jpg',
height: _size.height,
fit: BoxFit.cover,
);
} else {
return SizedBox();
}
},
),
),
],
),
],
),
),
),
),
],
)),
)));
}
}
// ✅ Must be outside any class — this fixes your error
// @pragma('vm:entry-point')
// Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// logDebug('📨 Handling background message: ${message.messageId}');
// logDebug('Title: ${message.notification?.title}');
// logDebug('Body: ${message.notification?.body}');
// logDebug('Data: ${message.data}');
// }