second commit
This commit is contained in:
391
lib/Controller/Authentication/Authcontroller.dart
Normal file
391
lib/Controller/Authentication/Authcontroller.dart
Normal file
@@ -0,0 +1,391 @@
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
599
lib/Controller/Authentication/Createtenantusercontroller.dart
Normal file
599
lib/Controller/Authentication/Createtenantusercontroller.dart
Normal file
@@ -0,0 +1,599 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:geolocator/geolocator.dart' as LocationAccuracy;
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:geocoding/geocoding.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:minio/io.dart';
|
||||
import 'package:minio/minio.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'dart:io';
|
||||
import 'package:rounded_loading_button_plus/rounded_loading_button.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../Data/Provider/Appcategory/Appcategoryprovider.dart';
|
||||
import '../../Data/Repository/Appcategory/Appcategoryrepository.dart';
|
||||
import '../../Data/Repository/Applocation/Applocationrepository.dart';
|
||||
import '../../Data/Repository/Authentication/Createtenantuser/Createtenantuserrepository.dart';
|
||||
import '../../Data/Repository/TenantPartner/Tenantpartnerrepository.dart';
|
||||
import '../../Helper/Logger.dart';
|
||||
import '../../Helper/location_service.dart';
|
||||
import '../../Helper/toast.dart';
|
||||
import '../../Model/Request/Authentication/Createuser/Createuserresponse.dart';
|
||||
import '../../Model/Response/Appcategory/app_category_response.dart';
|
||||
import '../../Model/Response/Applocations/Applocationresponse.dart';
|
||||
import '../../Model/Response/Authentication/Createtenantuser/Createtenantuserresponse.dart';
|
||||
import '../../Model/Response/Partners/Getpartnerinforequest.dart';
|
||||
import '../../View/Success/Successview.dart';
|
||||
|
||||
class CreateUserController extends GetxController {
|
||||
String appLocationName = '';
|
||||
String appCategoryName = '';
|
||||
String partnerName = '';
|
||||
String? latitude;
|
||||
String? longitude;
|
||||
String? catName;
|
||||
int? moduleIdByCategory = 0;
|
||||
String? subCatName;
|
||||
String? fcmEntryToken;
|
||||
|
||||
String? todayDate;
|
||||
String? validityDate;
|
||||
String? url; // This will hold the uploaded image URL
|
||||
|
||||
int selectedIndex = 0;
|
||||
int? catId;
|
||||
int? subCatId;
|
||||
|
||||
String? deviceId;
|
||||
|
||||
int appLocationId = 0;
|
||||
int partnerSelectedIndex = -1;
|
||||
int? partnerId;
|
||||
|
||||
List<AppLocationDetails> locations = [];
|
||||
List<PartnerInfoDetails> getPartners = [];
|
||||
List<AppCategoryDetails> appCategory = [];
|
||||
|
||||
Position? resultPosition;
|
||||
|
||||
List<SubCategory> subCategories = [];
|
||||
|
||||
Future<void> getFcmToken() async {
|
||||
try {
|
||||
await FirebaseMessaging.instance.requestPermission();
|
||||
|
||||
fcmEntryToken = await FirebaseMessaging.instance.getToken();
|
||||
print('FCM Token: $fcmEntryToken');
|
||||
|
||||
FirebaseMessaging.instance.onTokenRefresh.listen((newToken) {
|
||||
fcmEntryToken = newToken;
|
||||
print('FCM Token Refreshed: $fcmEntryToken');
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error getting FCM token: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getSubCategories() async {
|
||||
final provider = SubCategoryProvider();
|
||||
final List<SubCategory> fetched = await provider.fetchSubCategories();
|
||||
subCategories.assignAll(fetched);
|
||||
update();
|
||||
}
|
||||
|
||||
final String apiUrl = "https://fiesta.nearle.app/live/api/v1/mob/utils/getsubcategories";
|
||||
|
||||
Future<GetSubCategoriesResponse?> fetchSubCategories() async {
|
||||
try {
|
||||
final response = await http.get(Uri.parse(apiUrl));
|
||||
if (response.statusCode == 200) {
|
||||
final jsonData = json.decode(response.body);
|
||||
return GetSubCategoriesResponse.fromJson(jsonData);
|
||||
} else {
|
||||
print("Failed to load subcategories: ${response.statusCode}");
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error fetching subcategories: $e");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool shimmer = true;
|
||||
bool categoryShimmer = true;
|
||||
bool isEnterAddress = false;
|
||||
String selectedCategoryName = '';
|
||||
var currentLat;
|
||||
var currentLong;
|
||||
|
||||
TextEditingController firstnameController = TextEditingController();
|
||||
TextEditingController lastnameController = TextEditingController();
|
||||
TextEditingController companyNameController = TextEditingController();
|
||||
TextEditingController emailController = TextEditingController();
|
||||
TextEditingController gstinNumberController = TextEditingController();
|
||||
TextEditingController contactNoController = TextEditingController();
|
||||
TextEditingController addressController = TextEditingController();
|
||||
TextEditingController stateController = TextEditingController();
|
||||
TextEditingController cityController = TextEditingController();
|
||||
TextEditingController suburbController = TextEditingController();
|
||||
TextEditingController postcodeController = TextEditingController();
|
||||
|
||||
final searchText = ''.obs;
|
||||
final predictions = <Map<String, dynamic>>[].obs;
|
||||
final selectedPlace = {}.obs;
|
||||
|
||||
final RoundedLoadingButtonController btnController = RoundedLoadingButtonController();
|
||||
|
||||
AppLocationRepository appLocationRepository = AppLocationRepository();
|
||||
GetPartnersRepository getPartnersRepository = GetPartnersRepository();
|
||||
AppCategoryRepository appCategoryRepository = AppCategoryRepository();
|
||||
CreateTenantUserRepository createTenantUserRepository = CreateTenantUserRepository();
|
||||
|
||||
final GooglePlacesService placesService = GooglePlacesService();
|
||||
|
||||
getAppLocations() async {
|
||||
GetAppLocations? result = await appLocationRepository.getAppLocations();
|
||||
if (result?.code == 200) {
|
||||
locations = result?.details ?? [];
|
||||
shimmer = false;
|
||||
update();
|
||||
} else {
|
||||
Toast.showToast("${result?.message}");
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentLocation() async {
|
||||
resultPosition = await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy: LocationAccuracy.LocationAccuracy.high);
|
||||
currentLat = resultPosition?.latitude.toString();
|
||||
currentLong = resultPosition?.longitude.toString();
|
||||
print('currentLatinlocation $currentLat');
|
||||
print('currentLonglocation $currentLong');
|
||||
getAddressFromLatLongs(double.parse(currentLat), double.parse(currentLong));
|
||||
}
|
||||
|
||||
getAppCategory() async {
|
||||
categoryShimmer = true;
|
||||
update();
|
||||
|
||||
try {
|
||||
final provider = SubCategoryProvider();
|
||||
final List<SubCategory> subCats = await provider.fetchSubCategories();
|
||||
|
||||
final Map<int, AppCategoryDetails> uniqueCats = {};
|
||||
|
||||
for (var sub in subCats) {
|
||||
if (sub.categoryid != null && sub.catgeoryname != null) {
|
||||
uniqueCats[sub.categoryid!] = AppCategoryDetails(
|
||||
categoryid: sub.categoryid,
|
||||
categoryname: sub.catgeoryname,
|
||||
moduleid: sub.moduleid,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
appCategory = uniqueCats.values.toList();
|
||||
logger.i('Loaded ${appCategory.length} categories');
|
||||
|
||||
if (appCategory.isNotEmpty) {
|
||||
catId = appCategory[0].categoryid;
|
||||
catName = appCategory[0].categoryname;
|
||||
moduleIdByCategory = appCategory[0].moduleid;
|
||||
}
|
||||
} catch (e) {
|
||||
logger.e('Error loading categories: $e');
|
||||
Toast.showToast("Failed to load categories");
|
||||
}
|
||||
|
||||
categoryShimmer = false;
|
||||
update();
|
||||
}
|
||||
|
||||
Future<void> getAddressFromLatLongs(double latitudes, double longitudes) async {
|
||||
await placemarkFromCoordinates(latitudes, longitudes).then((List<Placemark> placemarks) {
|
||||
Placemark place = placemarks[0];
|
||||
cityController.text = place.locality ?? '';
|
||||
stateController.text = place.administrativeArea ?? '';
|
||||
suburbController.text = '${place.subLocality ?? place.street}';
|
||||
postcodeController.text = place.postalCode ?? '';
|
||||
latitude = latitudes.toString();
|
||||
longitude = longitudes.toString();
|
||||
addressController.text =
|
||||
'${place.street}, ${place.subLocality}, ${place.locality}, ${place.administrativeArea} ${place.subAdministrativeArea}, ${place.country}, ${place.postalCode}.';
|
||||
update();
|
||||
}).catchError((e) {
|
||||
debugPrint(e);
|
||||
});
|
||||
}
|
||||
|
||||
getPartnersInfo(locationId) async {
|
||||
GetPartnersInfo? result = await getPartnersRepository.getPartners(locationId);
|
||||
getPartners = result?.details ?? [];
|
||||
partnerId = getPartners.isNotEmpty ? getPartners[0].partnerid : null;
|
||||
print('getPartnerslengthss${getPartners.length}');
|
||||
print('getpartnerId$partnerId');
|
||||
}
|
||||
|
||||
onSearchTextChanged(String text) async {
|
||||
searchText.value = text;
|
||||
if (text.length > 2) {
|
||||
try {
|
||||
final places = await placesService.getPlacesPredictions(text);
|
||||
predictions.assignAll(places);
|
||||
update();
|
||||
} catch (e) {
|
||||
print('Error fetching predictions: $e');
|
||||
}
|
||||
} else {
|
||||
predictions.clear();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
getPlaceDetails(String placeId, locationAddress) async {
|
||||
try {
|
||||
final details = await placesService.getPlaceDetails(placeId);
|
||||
selectedPlace.value = details;
|
||||
getAddressFromLatLng(
|
||||
selectedPlace['geometry']['location']['lat'],
|
||||
selectedPlace['geometry']['location']['lng'],
|
||||
locationAddress,
|
||||
);
|
||||
} catch (e) {
|
||||
print('Error fetching place details: $e');
|
||||
}
|
||||
}
|
||||
|
||||
getAddressFromLatLng(double latitudes, double longitudes, locationAddress) async {
|
||||
await placemarkFromCoordinates(latitudes, longitudes).then((List<Placemark> placemarks) {
|
||||
Placemark place = placemarks[0];
|
||||
cityController.text = place.locality ?? '';
|
||||
stateController.text = place.administrativeArea ?? '';
|
||||
suburbController.text = (place.subLocality?.isNotEmpty == true) ? place.subLocality! : place.street!;
|
||||
postcodeController.text = place.postalCode ?? '';
|
||||
addressController.text = locationAddress;
|
||||
latitude = latitudes.toString();
|
||||
longitude = longitudes.toString();
|
||||
predictions.clear();
|
||||
update();
|
||||
}).catchError((e) {
|
||||
debugPrint(e);
|
||||
});
|
||||
}
|
||||
|
||||
void doSomething() async {
|
||||
Timer(const Duration(seconds: 1), () {
|
||||
profileValidation();
|
||||
});
|
||||
}
|
||||
|
||||
profileValidation() async {
|
||||
if (firstnameController.text.isEmpty) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Please Enter Firstname");
|
||||
return;
|
||||
}
|
||||
if (companyNameController.text.isEmpty) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Please Enter Companyname");
|
||||
return;
|
||||
}
|
||||
if (emailController.text.isEmpty) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Please Enter Email");
|
||||
return;
|
||||
}
|
||||
if (addressController.text.isEmpty) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Please Enter Address");
|
||||
return;
|
||||
}
|
||||
if (suburbController.text.isEmpty) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Please Enter Suburb");
|
||||
return;
|
||||
}
|
||||
if (cityController.text.isEmpty) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Please Enter City");
|
||||
return;
|
||||
}
|
||||
if (stateController.text.isEmpty) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Please Enter State");
|
||||
return;
|
||||
}
|
||||
if (postcodeController.text.isEmpty) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Please Enter Postcode");
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle image upload if selected
|
||||
if (profileImage != null) {
|
||||
btnController.start();
|
||||
final uploadedUrl = await uploadImageAndSave(File(profileImage!.path));
|
||||
if (uploadedUrl == null) {
|
||||
btnController.reset();
|
||||
Toast.showToast("Image upload failed. Please try again.");
|
||||
return;
|
||||
}
|
||||
url = uploadedUrl;
|
||||
} else {
|
||||
url = null; // Optional: send empty or placeholder
|
||||
}
|
||||
|
||||
// Now safe to create tenant
|
||||
createTenantUser();
|
||||
}
|
||||
|
||||
createTenantUser() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
DateTime now = DateTime.now();
|
||||
|
||||
todayDate = DateFormat("yyyy-MM-dd").format(now);
|
||||
validityDate = DateTime(now.year + 1, now.month, now.day).toString();
|
||||
|
||||
deviceId = prefs.getString('deviceId');
|
||||
|
||||
final request = CreateTenantUser(
|
||||
tenantimage: url, // Now correctly set
|
||||
|
||||
configid: 1,
|
||||
allocationid: 2,
|
||||
roleid: 1,
|
||||
tenantname: companyNameController.text,
|
||||
tenanttype: "D",
|
||||
registrationno: gstinNumberController.text,
|
||||
devicetype: Platform.isAndroid ? "android" : "ios",
|
||||
deviceid: deviceId ?? '',
|
||||
tenanttoken: fcmEntryToken ?? '',
|
||||
companyname: companyNameController.text,
|
||||
firstname: firstnameController.text,
|
||||
primaryemail: emailController.text,
|
||||
primarycontact: contactNoController.text,
|
||||
categoryid: catId,
|
||||
subcategoryid: subCatId,
|
||||
moduleid: 2,
|
||||
address: addressController.text,
|
||||
suburb: suburbController.text,
|
||||
state: stateController.text,
|
||||
city: cityController.text,
|
||||
postcode: postcodeController.text,
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
applocationid: 1,
|
||||
approved: 0,
|
||||
|
||||
tenantlocations: Tenantlocations(
|
||||
locationid: 0,
|
||||
applocationid: appLocationId,
|
||||
tenantid: 0,
|
||||
moduleid: 2,
|
||||
locationname: companyNameController.text,
|
||||
email: emailController.text,
|
||||
contactno: contactNoController.text,
|
||||
address: addressController.text,
|
||||
suburb: suburbController.text,
|
||||
state: stateController.text,
|
||||
city: cityController.text,
|
||||
postcode: postcodeController.text,
|
||||
latitude: latitude,
|
||||
longitude: longitude,
|
||||
partnerid: partnerId,
|
||||
opentime: "09:00",
|
||||
closetime: "21:00",
|
||||
deliverytype: 0,
|
||||
deliverymins: 60,
|
||||
cancelsecs: 20,
|
||||
),
|
||||
|
||||
tenantsubscriptions: Tenantsubscriptions(
|
||||
subscriptionid: 0,
|
||||
tenantid: 0,
|
||||
transactiondate: todayDate,
|
||||
moduleid: 2,
|
||||
applocationid: appLocationId,
|
||||
categoryid: catId,
|
||||
subcategoryid: subCatId,
|
||||
validitydate: validityDate?.split(' ')[0] ?? '',
|
||||
subscriptionprice: 300.00,
|
||||
quantity: 1,
|
||||
taxamount: 0.00,
|
||||
taxpercent: 18,
|
||||
totalamount: 300.00,
|
||||
paymentstatus: 1,
|
||||
),
|
||||
);
|
||||
|
||||
createTenantUserResult(request);
|
||||
}
|
||||
|
||||
createTenantUserResult(CreateTenantUser data) async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
|
||||
CreateTenantUserResponse? result = await createTenantUserRepository.createTenantUser(data);
|
||||
if (result?.status == true) {
|
||||
await Future.wait([
|
||||
prefs.setInt('userId', result?.details?.userid ?? 0),
|
||||
prefs.setInt('configId', result?.details?.configid ?? 0),
|
||||
prefs.setString('userEmail', result?.details?.authname ?? ''),
|
||||
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('userName', result?.details?.fullname ?? ''),
|
||||
prefs.setString('password', result?.details?.password ?? ''),
|
||||
prefs.setString('userEmail', result?.details?.email ?? ''),
|
||||
prefs.setString('tenantContactNo', result?.details?.contactno ?? ''),
|
||||
prefs.setString('userAddress', 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('userFcmToken', result?.details?.userfcmtoken ?? ''),
|
||||
prefs.setInt('userPin', result?.details?.pin ?? 0),
|
||||
prefs.setInt('partnerId', result?.details?.partnerid ?? 0),
|
||||
prefs.setInt('locationId', result?.details?.locationid ?? 0),
|
||||
prefs.setInt('tenantId', result?.details?.tenantid ?? 0),
|
||||
prefs.setString('tenantName', result?.details?.tenantname ?? ''),
|
||||
prefs.setString('tenantAddress', result?.details?.address ?? ''),
|
||||
prefs.setString('tenantSuburb', result?.details?.suburb ?? ''),
|
||||
prefs.setString('tenantCity', result?.details?.city ?? ''),
|
||||
prefs.setString('tenantState', result?.details?.state ?? ''),
|
||||
prefs.setString('tenantPostcode', result?.details?.postcode ?? ''),
|
||||
prefs.setInt('moduleId', result?.details?.moduleid ?? 0),
|
||||
prefs.setString('locationName', result?.details?.locationname ?? ''),
|
||||
prefs.setInt('categoryId', result?.details?.categoryid ?? 0),
|
||||
prefs.setInt('subcategoryId', result?.details?.subcategoryid ?? 0),
|
||||
prefs.setInt('appLocationId', result?.details?.applocationid ?? 0),
|
||||
]);
|
||||
|
||||
logger.i('TenantId From Create Tenant Response: ${prefs.getInt('tenantId')}');
|
||||
|
||||
// Clear fields
|
||||
firstnameController.clear();
|
||||
companyNameController.clear();
|
||||
emailController.clear();
|
||||
addressController.clear();
|
||||
suburbController.clear();
|
||||
cityController.clear();
|
||||
stateController.clear();
|
||||
postcodeController.clear();
|
||||
profileImage = null;
|
||||
url = null;
|
||||
|
||||
btnController.reset();
|
||||
update();
|
||||
await Future.delayed(Duration(milliseconds: 100));
|
||||
Get.to(() => AccountCreatedScreen());
|
||||
} else {
|
||||
btnController.reset();
|
||||
Toast.showToast("${result?.message}");
|
||||
}
|
||||
}
|
||||
|
||||
Future<Position> getLocation() async {
|
||||
LocationPermission permission = await Geolocator.checkPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
permission = await Geolocator.requestPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
return Future.error('Location permissions are denied');
|
||||
}
|
||||
}
|
||||
if (permission == LocationPermission.deniedForever) {
|
||||
await Geolocator.openLocationSettings();
|
||||
return Future.error('Location permissions are permanently denied');
|
||||
}
|
||||
Position position = await Geolocator.getCurrentPosition();
|
||||
await getAddressFromLatLongs(position.latitude, position.longitude);
|
||||
logger.i(position);
|
||||
return position;
|
||||
}
|
||||
|
||||
XFile? profileImage;
|
||||
final _picker = ImagePicker();
|
||||
RxString uploadedFileUrl = ''.obs;
|
||||
|
||||
// Only pick image — upload later
|
||||
Future getProfileImage() async {
|
||||
final XFile? selectedImage = await _picker.pickImage(source: ImageSource.gallery);
|
||||
if (selectedImage != null) {
|
||||
profileImage = selectedImage;
|
||||
update();
|
||||
} else {
|
||||
Toast.showToast('Image Not Selected');
|
||||
}
|
||||
}
|
||||
|
||||
// Upload image and return public URL
|
||||
Future<String?> uploadImageAndSave(File selectedImage) async {
|
||||
try {
|
||||
var rng = Random();
|
||||
const String region = "sgp1";
|
||||
const String accessKey = "DO00NQER7N2FRYZAB2HR";
|
||||
const String secretKey = "nMDewX25IBEu1FM5dakK+v28/WbW3TzBAwq913+dxP0";
|
||||
const String bucketName = "nearle";
|
||||
const String folderName = "deals";
|
||||
|
||||
String fileName = 'profile-${rng.nextInt(1000)}-1234.jpg';
|
||||
String endpointUrl = "https://$bucketName.$region.digitaloceanspaces.com/$folderName/$fileName";
|
||||
|
||||
final minio = Minio(
|
||||
endPoint: '$region.digitaloceanspaces.com', // ✅ FIXED HERE
|
||||
accessKey: accessKey,
|
||||
secretKey: secretKey,
|
||||
region: region,
|
||||
useSSL: true,
|
||||
);
|
||||
|
||||
await minio.fPutObject(
|
||||
bucketName,
|
||||
'$folderName/$fileName',
|
||||
selectedImage.path,
|
||||
metadata: {
|
||||
'Content-Type': 'image/jpeg',
|
||||
'x-amz-acl': 'public-read',
|
||||
},
|
||||
);
|
||||
|
||||
print("File uploaded successfully: $endpointUrl");
|
||||
return endpointUrl;
|
||||
} catch (e) {
|
||||
Get.snackbar("Error", "Image upload failed: $e");
|
||||
print("Upload error: $e");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
getFcmToken();
|
||||
getLocation();
|
||||
getSubCategories();
|
||||
getAppCategory();
|
||||
super.onInit();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
firstnameController.dispose();
|
||||
lastnameController.dispose();
|
||||
companyNameController.dispose();
|
||||
emailController.dispose();
|
||||
gstinNumberController.dispose();
|
||||
contactNoController.dispose();
|
||||
addressController.dispose();
|
||||
stateController.dispose();
|
||||
cityController.dispose();
|
||||
suburbController.dispose();
|
||||
postcodeController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
class SubCategoryService {
|
||||
final String apiUrl = "https://fiesta.nearle.app/live/api/v1/mob/utils/getsubcategories";
|
||||
|
||||
Future<GetSubCategoriesResponse?> fetchSubCategories() async {
|
||||
try {
|
||||
final response = await http.get(Uri.parse(apiUrl));
|
||||
if (response.statusCode == 200) {
|
||||
final jsonData = json.decode(response.body);
|
||||
print(response.body);
|
||||
return GetSubCategoriesResponse.fromJson(jsonData);
|
||||
} else {
|
||||
print("Failed to load subcategories: ${response.statusCode}");
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error fetching subcategories: $e");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user