second commit

This commit is contained in:
Anbarasu
2026-05-27 10:35:09 +05:30
parent c53794c04c
commit 1435ac47b0
501 changed files with 52818 additions and 0 deletions

View 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");
}
}
}

View 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;
}
}