391 lines
13 KiB
Dart
391 lines
13 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
import 'dart:math';
|
|
import 'package:country_currency_pickers/country.dart';
|
|
import 'package:country_currency_pickers/utils/utils.dart';
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:http/http.dart';
|
|
import 'package:http/http.dart' as dio1;
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:intl/intl.dart';
|
|
import 'package:otp_timer_button/otp_timer_button.dart';
|
|
import 'package:rounded_loading_button_plus/rounded_loading_button.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:sms_autofill/sms_autofill.dart';
|
|
import '../../Data/Repository/Authentication/loginrepository.dart';
|
|
import '../../Helper/Constants/Colorconstants.dart';
|
|
import '../../Helper/Logger.dart';
|
|
import '../../Helper/toast.dart';
|
|
import '../../Model/Request/Authentication/Loginrequest.dart';
|
|
import '../../Model/Response/Authentication/Loginresponse.dart';
|
|
import '../../View/Authentication/Otpverification.dart';
|
|
import '../../View/Authentication/Usercreate/Usercreateview.dart';
|
|
|
|
|
|
class AuthController extends GetxController with CodeAutoFill{
|
|
|
|
String? formatter;
|
|
String? currencyCode;
|
|
String? fcmEntryToken;
|
|
|
|
String? resendOtp;
|
|
|
|
|
|
String? userFcmToken;
|
|
String? contactNo;
|
|
|
|
|
|
//Otp
|
|
String? smsOtp;
|
|
String verifyId = "";
|
|
|
|
int authmode = 0;
|
|
|
|
bool termsChecking =false;
|
|
|
|
//Otp
|
|
bool codeSent = false;
|
|
|
|
var loginStatus;
|
|
|
|
String? contactLength;
|
|
|
|
|
|
// FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
|
|
FirebaseMessaging firebaseMessaging = FirebaseMessaging.instance;
|
|
|
|
|
|
Country selectedDialogCountry = CountryPickerUtils.getCountryByIsoCode('IN');
|
|
|
|
|
|
// final RoundedLoadingButtonController btnController = RoundedLoadingButtonController();
|
|
|
|
final RoundedLoadingButtonController loginController = RoundedLoadingButtonController();
|
|
|
|
//Otp
|
|
OtpTimerButtonController otpTimerController = OtpTimerButtonController();
|
|
|
|
|
|
TextEditingController loginPhoneNumberController = TextEditingController();
|
|
TextEditingController otpController = TextEditingController();
|
|
TextEditingController textEditingController = TextEditingController();
|
|
|
|
LoginRepository loginRepository = LoginRepository();
|
|
|
|
|
|
@override
|
|
void onInit() {
|
|
getId();
|
|
fcmToken();
|
|
listenForCode();
|
|
super.onInit();
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
cancel(); /// Stop listening for the OTP code
|
|
super.onClose();
|
|
}
|
|
|
|
@override
|
|
void codeUpdated() {
|
|
otpController.text = code ?? '';
|
|
logger.i("OTP Code Received: ${otpController.text}");
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
// TODO: implement dispose
|
|
SmsAutoFill().unregisterListener();
|
|
loginPhoneNumberController.dispose();
|
|
otpController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
|
|
|
|
fcmToken() async {
|
|
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
var token = await firebaseMessaging.getToken();
|
|
logger.i("firebase token======$token");
|
|
fcmEntryToken = token;
|
|
prefs.setString('fcmToken', token!);
|
|
logger.i("tenanttokensetstring ${prefs.getString('fcmToken')}");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void currency() async {
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
currencyCode = prefs.getString('Code_Currency')!;
|
|
final formats = NumberFormat();
|
|
formatter = formats.simpleCurrencySymbol("$currencyCode");
|
|
prefs.setString('Currency_Symbol', formatter!);
|
|
}
|
|
|
|
void loginTenant(context) async {
|
|
Timer(const Duration(seconds: 1), () {
|
|
// btnController.success();
|
|
profileValidation(context);
|
|
});
|
|
}
|
|
|
|
profileValidation(context)async{
|
|
if (loginPhoneNumberController.text.isEmpty) {
|
|
loginController.reset();
|
|
Toast.showToast("Please Enter Mobile Number");
|
|
} else if (!RegExp(
|
|
r'^\s*(?:\+?(\d{1,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *x(\d+))?\s*$')
|
|
.hasMatch(loginPhoneNumberController.text)) {
|
|
loginController.reset();
|
|
Toast.showToast("Please Enter a Valid Phone Number");
|
|
} else if(termsChecking==false){
|
|
loginController.reset();
|
|
Toast.showToast("Please Select Terms of Service");
|
|
|
|
}
|
|
else {
|
|
signIn(context);
|
|
}
|
|
}
|
|
|
|
String? uniqueDeviceId;
|
|
String? deviceId;
|
|
var iosDeviceInfo;
|
|
var androidDeviceInfo;
|
|
Future<String?> getId() async {
|
|
// var deviceInfo = DeviceInfoPlugin();
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
if (Platform.isIOS) { // import 'dart:io'
|
|
// iosDeviceInfo = await deviceInfo.iosInfo;
|
|
deviceId = iosDeviceInfo.toMap().toString();
|
|
uniqueDeviceId = iosDeviceInfo.id;
|
|
prefs.setString('deviceId',uniqueDeviceId!);
|
|
print('iosDeviceInfodeviceId$deviceId');
|
|
print('uniqueDeviceId${prefs.getString('deviceId')}');
|
|
return iosDeviceInfo.identifierForVendor; // Unique ID on iOS
|
|
} else {
|
|
// androidDeviceInfo = await deviceInfo.androidInfo;
|
|
deviceId = androidDeviceInfo.toMap().toString();
|
|
uniqueDeviceId = androidDeviceInfo.id;
|
|
prefs.setString('deviceId',uniqueDeviceId!);
|
|
print('androidDeviceInfodeviceId$deviceId');
|
|
print('uniqueDeviceId${prefs.getString('deviceId')}');
|
|
return androidDeviceInfo.androidId; // Unique ID on Android
|
|
}
|
|
print('${deviceId =androidDeviceInfo.androidId}');
|
|
}
|
|
|
|
|
|
|
|
//Authentication
|
|
|
|
signIn(context) async {
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
|
|
// ✅ Ensure FCM token is ready before calling API
|
|
if (fcmEntryToken == null) {
|
|
await fcmToken();
|
|
}
|
|
|
|
// Prepare data
|
|
final contactNo = loginPhoneNumberController.text;
|
|
final configId = 1;
|
|
final deviceType = Platform.operatingSystem;
|
|
final fcmTokenValue = fcmEntryToken ?? '';
|
|
final deviceId1 = deviceId ?? '';
|
|
|
|
// ✅ Print all values before sending
|
|
print("========= LOGIN REQUEST DATA =========");
|
|
print("📱 Contact No : $contactNo");
|
|
print("⚙️ Config ID : $configId");
|
|
print("💻 Device Type : $deviceType");
|
|
print("🔑 FCM Token : $fcmTokenValue");
|
|
print("🆔 Device ID : $deviceId1");
|
|
print("======================================");
|
|
|
|
// Call login API
|
|
loginApi(
|
|
LoginRequest(
|
|
contactno: contactNo,
|
|
configid: configId,
|
|
devicetype: deviceType,
|
|
userfcmtoken: fcmTokenValue,
|
|
deviceid: deviceId1,
|
|
),
|
|
context,
|
|
);
|
|
}
|
|
|
|
|
|
loginApi(LoginRequest data,context) async {
|
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
LoginResponse? result = await loginRepository.signIn(data);
|
|
if (result?.status == true) {
|
|
|
|
loginStatus = result?.status;
|
|
authmode = result?.details?.authmode??0;
|
|
userFcmToken = result?.details?.userfcmtoken;
|
|
contactNo = result?.details?.contactno;
|
|
|
|
|
|
logger.i('loginApilocationname ${result?.details?.locationname}');
|
|
|
|
|
|
prefs.setInt('userId', result?.details?.userid ?? 0);
|
|
prefs.setString('authName', result?.details?.authname ?? '');
|
|
prefs.setInt('configId', result?.details?.configid ?? 0);
|
|
prefs.setInt('authMode', result?.details?.authmode ?? 0);
|
|
prefs.setInt('roleId', result?.details?.roleid ?? 0);
|
|
prefs.setString('userFirstName', result?.details?.firstname ?? '');
|
|
prefs.setString('userLastName', result?.details?.lastname ?? '');
|
|
prefs.setString('userPassword', result?.details?.password ?? '');
|
|
prefs.setString('userEmail', result?.details?.email ?? '');
|
|
// prefs.setString('tenantContactNo', result?.details?.contactno ?? '');
|
|
prefs.setString('address', result?.details?.address ?? '');
|
|
prefs.setString('userSuburb', result?.details?.suburb ?? '');
|
|
prefs.setString('userCity', result?.details?.city ?? '');
|
|
prefs.setString('userState', result?.details?.state ?? '');
|
|
prefs.setString('userPostcode', result?.details?.postcode ?? '');
|
|
// prefs.setString('tenantFcmToken', result?.details?.userfcmtoken ?? '');
|
|
prefs.setInt('userPin', result?.details?.pin ?? 0);
|
|
prefs.setInt('partnerId', result?.details?.partnerid ?? 0);
|
|
prefs.setInt('tenantId', result?.details?.tenantid ?? 0);
|
|
prefs.setString('userName', result?.details?.fullname ?? '');
|
|
prefs.setString('tenantName', result?.details?.tenantname ?? '');
|
|
prefs.setString('tenantAddress', result?.details?.tenantaddress ?? '');
|
|
prefs.setString('tenantCity', result?.details?.tenantcity ?? '');
|
|
prefs.setString('tenantPostcode', result?.details?.tenantpostcode ?? '');
|
|
prefs.setString('tenantLatitude', result?.details?.tenantlat ?? '');
|
|
prefs.setString('tenantLongitude', result?.details?.tenantlong ?? '');
|
|
prefs.setInt('locationId', result?.details?.locationid ?? 0);
|
|
prefs.setString('locationName', result?.details?.locationname ?? '');
|
|
prefs.setString('appLocation', result?.details?.applocation ?? '');
|
|
prefs.setString('appLatitude', result?.details?.applatitude ?? '');
|
|
prefs.setString('appLongitude', result?.details?.applongitude ?? '');
|
|
prefs.setInt('appRadius', result?.details?.appradius ?? 0);
|
|
prefs.setInt('appLocationId', result?.details?.applocationid ?? 0);
|
|
prefs.setInt('moduleId', result?.details?.moduleid ?? 0);
|
|
logger.i('App location Id from login : ${prefs.getInt('appLocationId')}');
|
|
logger.i('location Id from login : ${prefs.getInt('locationId')}');
|
|
update();
|
|
}
|
|
|
|
if(authmode !=1) {
|
|
sendSmsOtp('${loginPhoneNumberController.text.trim()}',
|
|
authmode: result?.details?.authmode ?? 0);
|
|
}
|
|
else{
|
|
otpController.clear();
|
|
resendOtp = '123456';
|
|
if(authmode==1){
|
|
var snackBar = SnackBar(
|
|
backgroundColor: ColorConstants.primaryColor,
|
|
duration: const Duration(seconds: 5),
|
|
content: Text('Please enter your 6 digit verification code provided by Nearlexpress Business',style: TextStyle(color: ColorConstants.secondaryColor),)
|
|
);
|
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
}
|
|
Get.to(()=>OTPVerification(otp: '$resendOtp' ,authmode: authmode,logInStatus:loginStatus ,));
|
|
}
|
|
loginController.reset();
|
|
}
|
|
|
|
//Otp
|
|
|
|
sendSmsOtp(String mobile, {authmode=0}) async {
|
|
int otpInput = await otpGenerator();
|
|
smsOtp = otpInput.toString();
|
|
if(authmode==1)
|
|
{
|
|
onNavigateToProfileNumberVerification(otp: "123456",authmode: authmode);
|
|
}
|
|
|
|
else {
|
|
receiveSmsOtp(mobile,smsOtp.toString(), Get.context);
|
|
}
|
|
}
|
|
|
|
Future<void> receiveSmsOtp(String phoneNumber, String otp, context) async {
|
|
final appSignature = await SmsAutoFill().getAppSignature;
|
|
|
|
final message = "<#> Dear customer, use OTP $otp to sign in to Nearle App.\n$appSignature";
|
|
final encodedMessage = Uri.encodeComponent(message);
|
|
|
|
final url = Uri.parse(
|
|
'https://msg.lionsms.com/api/smsapi?'
|
|
'key=e57f5c9679af26077be1a7eadabb1b2a'
|
|
'&route=7'
|
|
'&sender=NEARLE'
|
|
'&number=$phoneNumber'
|
|
'&sms=$encodedMessage'
|
|
'&templateid=1107174712357438611',
|
|
);
|
|
|
|
logger.i('urlsendOtp $url');
|
|
logger.i('appSignaturereceiveSmsOtp $appSignature');
|
|
|
|
try {
|
|
final response = await http.get(url);
|
|
if (response.statusCode == 200) {
|
|
logger.i("SMS sent successfully");
|
|
receiveOtp(response, otp);
|
|
} else {
|
|
logger.i("Failed to send SMS: ${response.body}");
|
|
}
|
|
} catch (e) {
|
|
logger.i("Error sending SMS: $e");
|
|
}
|
|
}
|
|
|
|
receiveOtp(model,otp) async{
|
|
onNavigateToProfileNumberVerification(otp: otp);
|
|
}
|
|
|
|
onNavigateToProfileNumberVerification({String? otp,authmode=0}){
|
|
otpController.clear();
|
|
print('onNavigateToProfileNumberVerification $otp');
|
|
resendOtp = otp;
|
|
Get.to(()=>OTPVerification(otp: resendOtp??'' ,authmode: authmode,logInStatus: loginStatus,));
|
|
}
|
|
|
|
|
|
otpGenerator(){
|
|
var rng = Random();
|
|
var next = rng.nextDouble() * 1000000;
|
|
while (next < 100000) {
|
|
next *= 10;
|
|
}
|
|
print(next.toInt());
|
|
print("random${next.toInt()}");
|
|
return next.toInt();
|
|
}
|
|
|
|
|
|
Future<void> getHintPhoneNumber(context) async {
|
|
try {
|
|
final phoneNumber = await SmsAutoFill().hint;
|
|
if (phoneNumber != null) {
|
|
// Remove +91 from the phone number
|
|
String cleanedPhoneNumber = phoneNumber.startsWith('+91')
|
|
? phoneNumber.substring(3)
|
|
: phoneNumber;
|
|
|
|
loginPhoneNumberController.text = cleanedPhoneNumber;
|
|
contactLength = cleanedPhoneNumber;
|
|
// doSomething(context);
|
|
update();
|
|
|
|
logger.i("Phone number retrieved: ${loginPhoneNumberController.text}");
|
|
}
|
|
} catch (e) {
|
|
logger.i("Failed to retrieve phone number hint: $e");
|
|
}
|
|
}
|
|
|
|
} |