updateProfile
This commit is contained in:
466
lib/src/ui/map/add_locations.dart
Normal file
466
lib/src/ui/map/add_locations.dart
Normal file
@@ -0,0 +1,466 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:geocoding/geocoding.dart';
|
||||
import 'package:grocery_app/src/logic/provider/addTocart_provider.dart';
|
||||
import 'package:grocery_app/src/logic/provider/address_provider.dart';
|
||||
import 'package:grocery_app/utils/constants/color_constant.dart';
|
||||
import 'package:grocery_app/utils/extensions/uicontext.dart';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
const String googleApiKey = "AIzaSyAi3_Dls63iGs7Nccgdm-4FkS0rhT03-4U";
|
||||
|
||||
class AddLocationAddress extends StatefulWidget {
|
||||
@override
|
||||
_AddLocationAddressState createState() => _AddLocationAddressState();
|
||||
}
|
||||
|
||||
class _AddLocationAddressState extends State<AddLocationAddress> {
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
late GoogleMapController mapController;
|
||||
LatLng _selectedLocation = LatLng(20.5937, 78.9629);
|
||||
|
||||
TextEditingController _pincodeController = TextEditingController();
|
||||
TextEditingController _fullNameController = TextEditingController();
|
||||
TextEditingController _PhoneNumberController = TextEditingController();
|
||||
TextEditingController _addressTypeController = TextEditingController();
|
||||
TextEditingController _HouseNoController = TextEditingController();
|
||||
TextEditingController _RoadController = TextEditingController();
|
||||
TextEditingController _AlterNativeNumberController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_determinePosition();
|
||||
}
|
||||
|
||||
Future<void> _determinePosition() async {
|
||||
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
if (!serviceEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
LocationPermission permission = await Geolocator.requestPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
return;
|
||||
}
|
||||
|
||||
Position position = await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy: LocationAccuracy.high,
|
||||
);
|
||||
LatLng currentLatLng = LatLng(position.latitude, position.longitude);
|
||||
|
||||
setState(() {
|
||||
_selectedLocation = currentLatLng;
|
||||
});
|
||||
|
||||
_getAddressFromLatLng(position.latitude, position.longitude);
|
||||
}
|
||||
|
||||
Future<void> _getAddressFromLatLng(double lat, double lng) async {
|
||||
final String url =
|
||||
"https://maps.googleapis.com/maps/api/geocode/json?latlng=$lat,$lng&key=$googleApiKey";
|
||||
|
||||
try {
|
||||
final response = await http.get(Uri.parse(url));
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
if (data["status"] == "OK") {
|
||||
var result = data["results"][0]; // First result is most accurate
|
||||
|
||||
_RoadController.text = result["formatted_address"];
|
||||
List components = result["address_components"];
|
||||
|
||||
String roadName = "";
|
||||
String colony = "";
|
||||
String buildingName = "";
|
||||
String pincode = "";
|
||||
|
||||
for (var component in components) {
|
||||
List types = component["types"];
|
||||
if (types.contains("route")) {
|
||||
roadName = component["long_name"]; // Road Name
|
||||
} else if (types.contains("sublocality_level_1") ||
|
||||
types.contains("locality")) {
|
||||
colony = component["long_name"]; // Colony Name
|
||||
} else if (types.contains("premise") ||
|
||||
types.contains("street_number")) {
|
||||
buildingName = component["long_name"]; // Building Name
|
||||
} else if (types.contains("postal_code")) {
|
||||
pincode = component["long_name"]; // Extract Pin Code
|
||||
}
|
||||
}
|
||||
|
||||
// setState(() {
|
||||
// // _address = formattedAddress;
|
||||
// _roadName = roadName;
|
||||
// _colony = colony;
|
||||
// _buildingName = buildingName;
|
||||
// });
|
||||
|
||||
_pincodeController.text = pincode;
|
||||
_RoadController.text = result["formatted_address"];
|
||||
|
||||
print(
|
||||
"Full Address: ${result["formatted_address"]} ${response.body} sdfsgd ${pincode}");
|
||||
print("Road Name: $roadName");
|
||||
print("Colony: $colony");
|
||||
print("Building Name: $buildingName");
|
||||
} else {}
|
||||
} else {}
|
||||
} catch (e) {
|
||||
print("Error fetching address: $e");
|
||||
}
|
||||
}
|
||||
|
||||
void _onMapTapped(LatLng tappedPoint) {
|
||||
setState(() {
|
||||
_selectedLocation = tappedPoint;
|
||||
});
|
||||
_getAddressFromLatLng(tappedPoint.latitude, tappedPoint.longitude);
|
||||
}
|
||||
|
||||
Future<void> _updateLocationFromPincode(String enteredPincode) async {
|
||||
if (enteredPincode.isEmpty) return;
|
||||
|
||||
try {
|
||||
List<Location> locations = await locationFromAddress(enteredPincode);
|
||||
if (locations.isNotEmpty) {
|
||||
Location location = locations.first;
|
||||
LatLng newLatLng = LatLng(location.latitude, location.longitude);
|
||||
|
||||
setState(() {
|
||||
_selectedLocation = newLatLng;
|
||||
});
|
||||
|
||||
_getAddressFromLatLng(location.latitude, location.longitude);
|
||||
mapController.animateCamera(CameraUpdate.newLatLng(newLatLng));
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error fetching location from pincode: $e");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text("Add Delivery address")),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
height: 200.h,
|
||||
child: GoogleMap(
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: _selectedLocation,
|
||||
zoom: 14,
|
||||
),
|
||||
onMapCreated: (controller) {
|
||||
mapController = controller;
|
||||
},
|
||||
|
||||
myLocationEnabled: true, // Enable current location button
|
||||
myLocationButtonEnabled: true,
|
||||
markers: {
|
||||
Marker(
|
||||
markerId: MarkerId("selected Location"),
|
||||
position: _selectedLocation,
|
||||
)
|
||||
},
|
||||
onTap: _onMapTapped,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 10)],
|
||||
),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 10),
|
||||
TextFormField(
|
||||
controller: _fullNameController,
|
||||
keyboardType: TextInputType.text,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Full Name (Required)*",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Full Name";
|
||||
}
|
||||
return null; // ✅ Valid input
|
||||
},
|
||||
|
||||
// Auto-update on enter
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
TextFormField(
|
||||
controller: _PhoneNumberController,
|
||||
keyboardType: TextInputType.number,
|
||||
maxLength: 10,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Phone Number (Required)*",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Phone Number ";
|
||||
}
|
||||
return null; // ✅ Valid input
|
||||
},
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: _pincodeController,
|
||||
keyboardType: TextInputType.number,
|
||||
maxLength: 6,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Enter Pincode",
|
||||
border: OutlineInputBorder(),
|
||||
counterText: ""),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Please enter a pincode";
|
||||
} else if (value.length != 6) {
|
||||
return "Pincode must be exactly 6 digits";
|
||||
} else if (!RegExp(r'^[1-9][0-9]{5}$')
|
||||
.hasMatch(value)) {
|
||||
return "Enter a valid Indian pincode";
|
||||
}
|
||||
return null; // ✅ Valid input
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
// Expanded(
|
||||
// child: TextFormField(
|
||||
// controller: _addressTypeController,
|
||||
// keyboardType: TextInputType.text,
|
||||
// decoration: InputDecoration(
|
||||
// labelText: "Address Type",
|
||||
// border: OutlineInputBorder(),
|
||||
// ),
|
||||
// validator: (value) {
|
||||
// if (value == null || value.isEmpty) {
|
||||
// return "Enter address Home or Work ";
|
||||
// }
|
||||
// return null; // ✅ Valid input
|
||||
// },
|
||||
// ),
|
||||
// ),\
|
||||
Expanded(
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: _addressTypeController.text.isNotEmpty
|
||||
? _addressTypeController.text
|
||||
: null,
|
||||
items:
|
||||
["HOME", "WORK", "OTHER"].map((String type) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: type,
|
||||
child: Text(type),
|
||||
);
|
||||
}).toList(),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Address Type",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
onChanged: (value) {
|
||||
if (value != null) {
|
||||
_addressTypeController.text = value;
|
||||
}
|
||||
},
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Select Address Type (Home, Work, Other)";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
TextFormField(
|
||||
controller: _HouseNoController,
|
||||
keyboardType: TextInputType.text,
|
||||
decoration: InputDecoration(
|
||||
labelText: "House No, Building Name (Required)*",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Enter House No, Building ";
|
||||
}
|
||||
return null; // ✅ Valid input
|
||||
},
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
TextFormField(
|
||||
controller: _RoadController,
|
||||
keyboardType: TextInputType.text,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Road Name, Area , Colony(Required)*",
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Enter Road Name, Area , Colony(Required)";
|
||||
}
|
||||
return null; // ✅ Valid input
|
||||
},
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
||||
Consumer<AddressProvider>(
|
||||
builder: (context, addressProvider, child)
|
||||
{
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
var status = await addressProvider.checkPin(
|
||||
context, _pincodeController.text);
|
||||
|
||||
if (status) {
|
||||
var state = await addressProvider.addAddress(
|
||||
context,
|
||||
_fullNameController.text,
|
||||
_pincodeController.text,
|
||||
_PhoneNumberController.text,
|
||||
_PhoneNumberController.text,
|
||||
_HouseNoController.text,
|
||||
_RoadController.text,
|
||||
_addressTypeController.text);
|
||||
if (state) {
|
||||
context .read<AddtocartProvider>()
|
||||
.getAddress(context);
|
||||
Fluttertoast.showToast(
|
||||
msg: "Address Added!",
|
||||
backgroundColor: Colors.lightGreen);
|
||||
Navigator.pop(context);
|
||||
}
|
||||
} else {
|
||||
Fluttertoast.showToast(
|
||||
msg:
|
||||
"Delivery is not available for this pincode. Please try another pincode!",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.BOTTOM,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
fontSize: 14.0,
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(
|
||||
left: 15, right: 15, top: 10, bottom: 10),
|
||||
height: 50,
|
||||
width: MediaQuery.sizeOf(context).width,
|
||||
decoration: BoxDecoration(
|
||||
color: APPCOLOR.lightGreen,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
if (addressProvider.ischeckpin)
|
||||
const CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
)
|
||||
else
|
||||
Text(
|
||||
"Save Address",
|
||||
style: context.customMedium(
|
||||
Colors.white, 20),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
// InkWell(
|
||||
// onTap: () async {
|
||||
// if (_formKey.currentState!.validate()) {
|
||||
// var status = await Provider.of<AddressProvider>(
|
||||
// context,
|
||||
// listen: false)
|
||||
// .checkPin(context, _pincodeController.text);
|
||||
// if (status) {
|
||||
// // var status = await Provider.of<AddressProvider>(
|
||||
// // context,
|
||||
// // listen: false)
|
||||
// // .addAddress(context, _pincodeController.text);
|
||||
// } else {
|
||||
// // Delivery is not available for this pincode. Please try another pincode.
|
||||
|
||||
// Fluttertoast.showToast(
|
||||
// msg:
|
||||
// "Delivery is not available for this pincode. Please try another pincode!",
|
||||
// toastLength: Toast.LENGTH_SHORT,
|
||||
// gravity: ToastGravity.BOTTOM,
|
||||
// backgroundColor: Colors.red,
|
||||
// textColor: Colors.white,
|
||||
// fontSize: 14.0,
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// child: Container(
|
||||
// margin: const EdgeInsets.only(
|
||||
// left: 15, right: 15, top: 10, bottom: 10),
|
||||
// height: 50,
|
||||
// width: MediaQuery.sizeOf(context).width,
|
||||
// decoration: BoxDecoration(
|
||||
// color: APPCOLOR.lightGreen,
|
||||
// borderRadius: BorderRadius.circular(10)),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// crossAxisAlignment: CrossAxisAlignment.center,
|
||||
// children: [
|
||||
// const SizedBox(
|
||||
// width: 10,
|
||||
// ),
|
||||
// Text(
|
||||
// "Save Address",
|
||||
// style: context.customMedium(Colors.white, 20),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user