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,281 @@
import 'package:country_currency_pickers/utils/utils.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:rounded_loading_button_plus/rounded_loading_button.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../Controller/Authentication/Authcontroller.dart';
import '../../Globalwidgets/textwidget.dart';
import '../../Globalwidgets/web_view.dart';
import '../../Helper/Constants/Assetconstants.dart';
import '../../Helper/Constants/Colorconstants.dart';
import '../../Helper/custombutton.dart';
import '../More/Faqview/privacy.dart';
class LoginView extends StatelessWidget {
LoginView({super.key});
final AuthController authController = Get.put(AuthController());
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () {
SystemNavigator.pop();
return Future.value(true);
},
child: GetBuilder<AuthController>(
initState: (_) {
authController.getHintPhoneNumber(context);
},
builder: (controller) {
return SafeArea(
top: false,
child: Scaffold(
backgroundColor: Colors.white,
body: Padding(
padding: const EdgeInsets.only(left: 15, right: 15),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Image.asset(
AssetConstants.nearledailyImage,
height: 300,
width: 300,
),
),
Center(
child: TextWidget(
text: "Enter Your Phone Number",
color: ColorConstants.primaryColor,
fontWeight: FontWeight.w700,
fontSize: 16,
),
),
const SizedBox(height: 10),
Center(
child: TextWidget(
text: "We will send you the 6 digit verification code",
fontSize: 14,
),
),
const SizedBox(height: 25),
TextWidget(
text: "Let's Get Started",
color: ColorConstants.primaryColor,
fontWeight: FontWeight.w700,
fontSize: 18,
),
const SizedBox(height: 10),
contactNo(context),
const SizedBox(height: 20),
// const SizedBox(height: 0),
// SizedBox(
// height: 100,
// child: submit(context),
// ),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
terms();
},
child: Container(
height: 20,
width: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(3),
color: controller.termsChecking
? Colors.green
: Colors.white,
border: Border.all(
color: controller.termsChecking
? Colors.green
: Colors.grey[400]!,
),
),
child: controller.termsChecking
? const Icon(
Icons.check,
color: Colors.white,
size: 19,
)
: const SizedBox(),
),
),
const SizedBox(width: 8),
Text(
"I agree to the Terms and &",
style: TextStyle(
color: ColorConstants.darkGreyColor,
fontSize: 14,
),
),
const SizedBox(width: 3),
InkWell(
onTap: () {
Get.to(() => const WebViewApp(
url: 'https://nearle.in/privacy',
appBarText: 'Privacy Policy',
));
},
child: Text(
"Privacy Policy",
style: TextStyle(
color: ColorConstants.darkGreyColor,
fontSize: 14,
decoration: TextDecoration.underline,
),
),
),
],
),
const SizedBox(height: 80), // Space so button doesn't overlap
],
),
),
),
bottomNavigationBar: Padding(
padding: const EdgeInsets.all(15.0),
child: SizedBox(
height: 100,
child: submit(context),
),
),
),
);
},
),
);
}
Widget contactNo(context) {
return TextFormField(
buildCounter: (BuildContext context,
{int? currentLength, int? maxLength, bool? isFocused}) =>
null,
maxLength: 10,
keyboardType:
const TextInputType.numberWithOptions(signed: true, decimal: true),
controller: authController.loginPhoneNumberController,
onChanged: (value){
if(value.length==10){
FocusScope.of(context).unfocus();
}
},
onTap: () async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('Code_Currency',
authController.selectedDialogCountry.currencyCode!);
prefs.setString('Currency_Code',
authController.selectedDialogCountry.currencyCode!);
prefs.setString('Country_Code',
authController.selectedDialogCountry.isoCode!);
prefs.setString('dialCode',
'+${authController.selectedDialogCountry.phoneCode!}');
prefs.setString('location_Country',
authController.selectedDialogCountry.isoCode!);
authController.currency();
},
decoration: InputDecoration(
labelText: 'Mobile Number',
labelStyle: const TextStyle(color: Colors.grey),
prefixIcon: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: Get.width * 0.3,
height: Get.height * 0.04,
child: Row(
children: [
const SizedBox(
width: 25,
),
InkWell(
child: CountryPickerUtils.getDefaultFlagImage(
authController.selectedDialogCountry),
// onTap: _openCountryPickerDialog,
),
const SizedBox(
width: 8,
),
Text(
"+${authController.selectedDialogCountry.phoneCode}"),
],
),
),
],
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(7.0),
borderSide: const BorderSide(
color: Color.fromRGBO(220, 220, 220, 0.6),
width: 2.0,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(7.0),
borderSide: const BorderSide(
color: Color.fromRGBO(220, 220, 220, 0.6),
width: 2.0,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(7.0),
borderSide: const BorderSide(
color: ColorConstants.primaryColor,
width: 1.0,
),
),
),
);
}
bool terms() {
authController.update();
authController.termsChecking = !authController.termsChecking;
return authController.termsChecking;
}
Widget submit(context) {
return GetBuilder<AuthController>(
builder: (controller) {
return RoundedLoadingButton(
color: ColorConstants.primaryColor,
width: Get.width,
controller: controller.loginController,
onPressed: () {
controller.loginTenant(context);
},
child: TextWidget(
text: 'Next',
fontSize: 18,
color: ColorConstants.secondaryColor,
fontWeight: FontWeight.w700,
)
);
// RoundedButton(
// height: Get.height*0.06,
// width: Get.width,
// onPressed: () {
// controller.loginTenant(context);
// },
// color: ColorConstants.primaryColor,
// title: 'Next',
// controller: controller.btnController,
// textStyle: const TextStyle(
// fontSize: 18,
// fontFamily: "Lato",
// color: Colors.white,
// fontWeight: FontWeight.bold),
// );
});
}
}

View File

@@ -0,0 +1,334 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:otp_timer_button/otp_timer_button.dart';
import 'package:pinput/pinput.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:sms_autofill/sms_autofill.dart';
import '../../Controller/Authentication/Authcontroller.dart';
import '../../Helper/Constants/Colorconstants.dart';
import '../../Helper/Logger.dart';
import '../../Helper/toast.dart';
import '../Home/Homeview.dart';
import 'Usercreate/Usercreateview.dart';
class OTPVerification extends StatelessWidget {
final String otp;
final int authmode;
final bool? logInStatus;
// final int? activeStatus;
OTPVerification({super.key, this.otp="",this.authmode=0, this.logInStatus});
final AuthController authController = AuthController();
final defaultPinTheme = PinTheme(
width: 60,
height: 56,
textStyle: const TextStyle(fontSize: 20, color: Colors.black, fontWeight: FontWeight.w600),
decoration: BoxDecoration(
border: Border.all(color: ColorConstants.primaryColor),
borderRadius: BorderRadius.circular(10),
),
);
@override
Widget build(BuildContext context) {
return GetBuilder<AuthController>(
initState: (_) {
// authController.loginController.reset();
},
builder: (controller) {
return Scaffold(
backgroundColor: ColorConstants.secondaryColor,
body: Column(
children: [
SizedBox(height: 20,),
Container(
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.elliptical(40, 40),
topRight: Radius.elliptical(40, 40)),
),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 20,
),
Row(
children: [
InkWell(
onTap: () {
Get.back();
},
child: Icon(Icons.arrow_back, color: Colors.grey[700],
),
),
SizedBox(width: 10,),
Text("Verification",
style: TextStyle(
fontSize: 30,
fontFamily: "Lato",
fontWeight: FontWeight.bold,
color: Colors.grey[700])),
],
),
const SizedBox(
height: 10,
),
Text("Please enter your 6 digit One-Time-Password",
style: TextStyle(
fontWeight: FontWeight.normal,
fontFamily: "Lato",
color: Colors.grey[600])),
const SizedBox(
height: 40,
),
Center(
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 20),
child: SizedBox(
width: 400,
child: PinFieldAutoFill(
controller: TextEditingController(text: controller.otpController.text), // Correct usage
textInputAction: TextInputAction.done,
onCodeChanged: (code) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
if (controller.resendOtp == code) {
if (authmode == 1) {
code = controller.resendOtp ?? '';
}
if (logInStatus == true) {
logger.i('Login status : $logInStatus');
prefs.setString('tenantContactNo', controller.contactNo ?? '');
prefs.setString('userFcmToken', controller.userFcmToken ?? '');
Get.to(() => HomeView(selectedIndex: 0));
} else {
if (code == controller.resendOtp) {
Get.to(() => CreateUserView(
phNumber: controller.loginPhoneNumberController.text,),
);
}
else{
controller.otpController.clear();
Toast.showToast('Please Enter Valid Otp');
}
}
}
},
keyboardType:TextInputType.number ,
autoFocus: true,
onCodeSubmitted: (code){
if(code != controller.resendOtp){
controller.otpController.clear();
logger.i('otpCompleted ${controller.resendOtp}');
Toast.showToast('Please Enter Valid Otp');
}
},
decoration: BoxLooseDecoration(
textStyle: const TextStyle(fontSize: 20, color: Colors.black),
radius: const Radius. circular(8.0),
strokeColorBuilder: FixedColorBuilder(Colors.black.withOpacity(0.3)),
),
),
),
),
// Padding(
// padding: const EdgeInsets.only(left: 20, right: 20),
// child: Pinput(
// defaultPinTheme: defaultPinTheme,
// pinContentAlignment: Alignment.center,
//
// length: 6,
// autofocus: true,
// keyboardType: TextInputType.number,
// androidSmsAutofillMethod: AndroidSmsAutofillMethod.smsUserConsentApi,
// pinAnimationType: PinAnimationType.fade,
// controller: controller.otpController,
// pinputAutovalidateMode: PinputAutovalidateMode.onSubmit,
// animationDuration: const Duration(milliseconds: 300),
// // Pass it here
// onChanged: (text) async{
// SharedPreferences prefs = await SharedPreferences.getInstance();
// // controller.smsOtp = text;
// // Check if the entered text is a valid phone number
// if (controller.resendOtp == text) {
// if(authmode == 1){
// text = controller.resendOtp??'';
// }
// if(logInStatus == true){
// prefs.setString('tenantContactNo',controller.contactNo ?? '');
// prefs.setString('tenantFcmToken', controller.userFcmToken ?? '');
// logger.i('Inside the login true status');
// Get.to(()=>HomeView(selectedIndex: 0));
// }else{
// logger.i('Inside the login false status');
// Get.to(() => CreateUserView(phNumber: controller.loginPhoneNumberController.text,));
// // showModalBottomSheet(
// // context: Get.context!,
// // isDismissible: true,
// // backgroundColor: ColorConstants.secondaryColor,
// // shape: const RoundedRectangleBorder(
// // borderRadius: BorderRadius.only(
// // topLeft: Radius.circular(20.0), topRight: Radius.circular(20)),
// // ),
// // builder: (context) {
// // return Column(
// // mainAxisAlignment: MainAxisAlignment.start,
// // crossAxisAlignment: CrossAxisAlignment.center,
// // children: [
// // SizedBox(
// // height: Get.height * 0.3,
// // // width: Get.width * 0.10,
// // child: Padding(
// // padding: const EdgeInsets.only(bottom: 0),
// // child: Center(child: Lottie.asset('assets/images/nodatafound.json',)),
// // ),
// // ),
// // const SizedBox(height: 15,),
// // SizedBox(
// // width: Get.width*0.85,
// // child: Center(
// // child: Text(
// // "Oops, we couldn't find your account. Instead, would you like to create a new one?",
// // style: TextStyle(
// // fontSize: 18,
// // fontFamily: "Inter",
// // fontWeight: FontWeight.normal,
// // color: ColorConstants.blackColor),
// // maxLines: 3,
// // textAlign: TextAlign.center,
// //
// // ),
// // ),
// // ),
// // const Spacer(),
// // Row(
// // mainAxisAlignment: MainAxisAlignment.center,
// // crossAxisAlignment: CrossAxisAlignment.center,
// // children: [
// // InkWell(
// // onTap: (){
// // Get.to(CreateUserView(phNumber: controller.loginPhoneNumberController.text,));
// // },
// // child: Container(
// // height: Get.height*0.06,
// // width: Get.width*0.4,
// // decoration: BoxDecoration(color: ColorConstants.primaryColor,borderRadius: BorderRadius.circular(10),),
// // child: Center(child: Text('Create Account',style: TextStyle(color: ColorConstants.secondaryColor,fontSize: 16,))),
// // ),
// // ),
// // const SizedBox(width: 10,),
// // InkWell(
// // onTap: (){
// // Get.back();
// // },
// // child: Container(
// // height: Get.height*0.06,
// // width: Get.width*0.4,
// // decoration: BoxDecoration(color: ColorConstants.primaryColor,borderRadius: BorderRadius.circular(10),),
// // child: Center(child: Text('Cancel',style: TextStyle(color: ColorConstants.secondaryColor,fontSize: 16,))),
// // ),
// // ),
// // ],
// // ),
// // const SizedBox(height: 20,)
// //
// //
// // ],
// // );
// // }
// // );
// }
// }
// },
// onCompleted:(text){
// if( text != controller.resendOtp){
// controller.otpController.clear();
// print('textonCompleted $text');
// print('otpCompleted ${controller.resendOtp}');
// Toast.showToast('Please Enter Valid Otp');
// }
//
// },
//
//
// ),
// ),
),
const SizedBox(
height: 20,
),
controller.authmode == 1 ?Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container()
],
):Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Didn't receive the code? ",
style: TextStyle(
fontWeight: FontWeight.w600,
fontFamily: "Lato",
color: Colors.grey[600])),
OtpTimerButton(
controller: controller.otpTimerController,
onPressed: () {
controller.otpTimerController.startTimer();
controller.textEditingController.clear();
controller.codeSent = true;
controller.sendSmsOtp(controller.loginPhoneNumberController.text.trim());
controller.update();
},
text: Text('Resend Again',style: TextStyle(
fontWeight: FontWeight.w600,
fontFamily: "Lato",
color: ColorConstants.primaryColor
),),
duration: 60,
buttonType: ButtonType.text_button,
textColor: ColorConstants.primaryColor,
// backgroundColor: ColorConstants.primaryColor,
)
],
),
const SizedBox(
height: 40,
),
//submit(),
],
),
),
),
// const Spacer(),
// Container(
// height: Get.height * 0.1,
// width: Get.width,
// decoration: const BoxDecoration(
// image: DecorationImage(
// image: AssetImage(
// AssetConstants.nearleAppbarBottom,
// ),
// fit: BoxFit.fill),
// // color: ColorConstants.primaryColor,
// borderRadius: BorderRadius.only(
// bottomLeft: Radius.elliptical(2, 2),
// bottomRight: Radius.elliptical(2, 2))),
// ),
],
),
);
}
);
}
}

View File

@@ -0,0 +1,446 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../Controller/Authentication/Createtenantusercontroller.dart';
import '../../../Globalwidgets/textwidget.dart';
import '../../../Helper/Constants/AssetConstants.dart';
import '../../../Helper/Constants/Colorconstants.dart';
import '../../../Helper/Logger.dart';
import '../../../Helper/custombutton.dart';
import '../../../Helper/customederaction.dart';
import 'package:flutter/services.dart';
import '../Logiview.dart';
class CreateUserView extends StatelessWidget {
final String? phNumber;
CreateUserView({super.key, this.phNumber});
final CreateUserController controller = Get.put(CreateUserController());
final ScrollController listScrollController = ScrollController();
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return SafeArea(
top: false,
child: Scaffold(
key: scaffoldKey,
appBar: AppBar(
automaticallyImplyLeading: true,
leading: InkWell(
onTap: () {
Get.to(() => LoginView());
},
child: Icon(
Icons.arrow_back,
color: ColorConstants.blackColor,
),
),
title: TextWidget(
text: 'Create Account',
fontSize: 20,
fontWeight: FontWeight.w700,
),
),
backgroundColor: Colors.white,
body: GetBuilder<CreateUserController>(
initState: (_) {
controller.contactNoController.text = phNumber ?? '';
logger.i('Phone Number: ${controller.contactNoController.text}');
controller.getAppLocations();
controller.getCurrentLocation();
controller.getAppCategory();
logger.i('Cat Name Is empty : ${controller.catName}');
},
builder: (controller) => Column(
children: [
// _buildHeader(),
// const SizedBox(height: 10,),
Expanded(
child: ListView(
controller: listScrollController,
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
children: [
SizedBox(height: 10,),
Center(
child: Stack(
children: [
InkWell(
onTap: () {
controller.getProfileImage();
},
child: Container(
width: 100,
// Set the size to match the CircleAvatar's diameter
height: 100,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: ColorConstants.primaryColor, // Border color
width: 2.0, // Border width
),
),
child: CircleAvatar(
radius: 30,
backgroundColor: ColorConstants.secondaryColor,
child: ClipOval(
child: controller.profileImage == null
? Image.asset(
AssetConstants.noProfile,
width: 70,
height: 70,
color: ColorConstants.primaryColor,
)
: Image.file(
width: 100,
height: 100,
File(controller.profileImage?.path ?? ''),
fit: BoxFit.cover,
),
),
),
),
),
const Positioned(
bottom: 0,
right: 0,
child: CircleAvatar(
radius: 15,
backgroundColor: ColorConstants.primaryColor,
child: Icon(
Icons.camera_alt_outlined,
color: Colors.white,
),
),
),
],
),
),
const SizedBox(
height: 8,
),
Center(
child: TextWidget(
text: 'Upload Company Logo',
)),
const SizedBox(height: 30,),
_buildTextField(
controller: controller.firstnameController,
label: 'Contact Name',
icon: Icons.person,
formatters: [UpperCaseTextFormatter()],
),
const SizedBox(height: 20),
_buildTextField(
controller: controller.companyNameController,
label: 'Company Name',
icon: Icons.business,
formatters: [UpperCaseTextFormatter()],
),
const SizedBox(height: 20),
_buildTextField(
controller: controller.emailController,
label: 'Email',
icon: Icons.email_outlined,
validator: _validateEmail,
),
const SizedBox(height: 20),
_buildSelectionField(
context: context,
label: controller.selectedCategoryName.isEmpty ? 'Select Category' : controller.selectedCategoryName,
icon: Icons.category,
onTap: () async {
var result = await SubCategoryService().fetchSubCategories();
if (result != null && result.details != null) {
final categories = result.details!
.map((e) => e.catgeoryname ?? '')
.toSet()
.toList();
if (context.mounted) {
showModalBottomSheet(
context: context,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (context) {
return ListView.builder(
itemCount: categories.length,
itemBuilder: (context, index) {
final categoryName = categories[index];
return ListTile(
title: Text(categoryName),
trailing: controller.selectedCategoryName == categoryName
? Icon(Icons.check, color: ColorConstants.primaryColor)
: null,
onTap: () {
// Update controller
controller.selectedCategoryName = categoryName;
controller.update(); // Trigger UI rebuild
Navigator.pop(context);
},
);
},
);
},
);
}
}
},
),
const SizedBox(height: 20),
_buildTextField(
controller: controller.gstinNumberController,
label: 'GSTIN',
icon: Icons.verified_user,
),
const SizedBox(height: 20),
_buildAddressSection(context, controller),
const SizedBox(height: 20),
if (controller.isEnterAddress) ...[
_buildTextField(controller: controller.suburbController, label: 'Suburb', icon: Icons.location_on),
const SizedBox(height: 15),
_buildTextField(controller: controller.cityController, label: 'City', icon: Icons.location_on),
const SizedBox(height: 15),
_buildTextField(controller: controller.stateController, label: 'State', icon: Icons.location_on),
const SizedBox(height: 15),
],
_buildTextField(controller: controller.postcodeController, label: 'Pincode', icon: Icons.location_on),
],
),
),
],
),
),
bottomNavigationBar: _buildBottomBar(controller),
),
);
}
Widget _buildTextField({
required TextEditingController controller,
required String label,
required IconData icon,
List<TextInputFormatter>? formatters,
String? Function(String?)? validator,
}) {
return Container(
height: Get.height * 0.07,
decoration: BoxDecoration(color: ColorConstants.secondaryColor),
child: TextFormField(
controller: controller,
textCapitalization: TextCapitalization.sentences,
inputFormatters: formatters,
validator: validator,
onFieldSubmitted: (_) {
FocusManager.instance.primaryFocus?.unfocus(); // Removes focus and hides keyboard
},
style: const TextStyle(fontFamily: 'Inter'),
decoration: CustomDecoration.textFieldStyle(labelTextStr: label, prefixIcon: Icon(icon, color: ColorConstants.darkGreyColor)),
onEditingComplete: () => FocusScope.of(Get.context!).requestFocus(FocusNode()),
),
);
}
Widget _buildSelectionField({
required BuildContext context,
required String label,
required IconData icon,
required VoidCallback onTap,
}) {
return InkWell(
onTap: onTap,
child: Container(
height: 60,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Colors.grey[200]!, width: 2),
),
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: Row(
children: [
Icon(icon, color: ColorConstants.darkGreyColor),
const SizedBox(width: 10),
Expanded(child: Text(label, style: TextStyle(fontSize: 17, color: Colors.grey[500]))),
Icon(Icons.arrow_drop_down, color: Colors.grey[600], size: 20),
],
),
),
),
);
}
Widget _buildAddressSection(BuildContext context, CreateUserController controller) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(Icons.location_on, color: ColorConstants.darkGreyColor, size: 23),
const SizedBox(width: 5),
const Text('Address', style: TextStyle(color: Colors.black54, fontSize: 16)),
const Spacer(),
InkWell(
onTap: () {
// Toggle the isEnterAddress state if needed for other UI logic
controller.isEnterAddress = !controller.isEnterAddress;
controller.update();
},
child: Icon(
controller.isEnterAddress ? Icons.check : Icons.keyboard_arrow_down_sharp,
color: Colors.grey[600],
size: 23,
),
),
],
),
const SizedBox(height: 5),
TextFormField(
controller: controller.addressController,
maxLines: 3,
cursorColor: ColorConstants.textFieldColor,
style: TextStyle(color: ColorConstants.textFieldColor),
decoration: CustomDecoration.textFieldStyle(),
readOnly: true, // Make it read-only to prevent direct editing
onTap: () async {
// Navigate to the address search screen and wait for the result
final selectedAddress = await Get.to(() => AddressSearchScreen(controller: controller));
if (selectedAddress != null) {
controller.addressController.text = selectedAddress['description'];
controller.getPlaceDetails(selectedAddress['place_id'], selectedAddress['description']);
controller.update();
}
},
),
],
);
}
Widget _buildBottomBar(CreateUserController controller) {
return Container(
height: Get.height * 0.1,
child: RoundedButton(
height: Get.height * 0.06,
width: Get.width * 0.9,
onPressed: controller.doSomething,
color: ColorConstants.primaryColor,
title: 'Create',
controller: controller.btnController,
textStyle: const TextStyle(fontSize: 18, fontFamily: 'Inter', color: Colors.white, fontWeight: FontWeight.bold),
),
);
}
String? _validateEmail(String? value) {
const simplePattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$';
final regex = RegExp(simplePattern);
return value!.isNotEmpty && !regex.hasMatch(value) ? 'Enter a valid email address' : null;
}
}
class UpperCaseTextFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
return TextEditingValue(text: capitalize(newValue.text), selection: newValue.selection);
}
}
String capitalize(String value) {
if (value.trim().isEmpty) return '';
return '${value[0].toUpperCase()}${value.substring(1)}';
}
class AddressSearchScreen extends StatelessWidget {
final CreateUserController controller;
const AddressSearchScreen({Key? key, required this.controller}) : super(key: key);
@override
Widget build(BuildContext context) {
// Initialize a new TextEditingController with the initial address
final searchController = TextEditingController(text: controller.addressController.text);
return Scaffold(
appBar: AppBar(
title: TextWidget(
text: 'Search Address',
fontWeight: FontWeight.bold,
fontSize: 20,
),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: ColorConstants.blackColor),
onPressed: () => Get.back(), // Return without selecting an address
),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
controller: searchController,
autofocus: true,
cursorColor: ColorConstants.textFieldColor,
style: TextStyle(color: ColorConstants.textFieldColor),
decoration: CustomDecoration.textFieldStyle().copyWith(
hintText: 'Enter address',
suffixIcon: IconButton(
icon: Icon(Icons.cancel, color: ColorConstants.blackColor),
onPressed: () {
searchController.clear(); // Clear the search field
controller.predictions.clear(); // Clear predictions
controller.update(); // Notify UI to update
},
),
),
onChanged: (text) {
if (text.isEmpty) {
controller.predictions.clear();
controller.update();
}
controller.onSearchTextChanged(text);
},
),
const SizedBox(height: 8),
Expanded(
child: Obx(
() => controller.predictions.isEmpty
? const Center(child: Text('No results found'))
: ListView.builder(
itemCount: controller.predictions.length,
itemBuilder: (context, index) {
final prediction = controller.predictions[index]['description'];
return ListTile(
title: Text(prediction),
onTap: () {
final selectedAddress = controller.predictions[index];
controller.addressController.text = selectedAddress['description'];
controller.getPlaceDetails(selectedAddress['place_id'], selectedAddress['description']);
Get.back(result: selectedAddress);
},
);
},
),
),
),
],
),
),
);
}
}