diff --git a/lib/common/settings.dart b/lib/common/settings.dart index 099adda..46b517e 100644 --- a/lib/common/settings.dart +++ b/lib/common/settings.dart @@ -145,6 +145,9 @@ class AppSettings{ static String addTankerUrl = host + 'addTankers'; static String getDriversUrl = host + 'getalldeliveryboys'; static String addDriversUrl = host + 'addDeliveryboys'; + static String addSourceLocationsUrl = host + 'addSource'; + static String getSourceLoctaionsUrl = host + 'getallsourcesofsupplier'; + static String formDouble(dynamic s) { @@ -552,6 +555,61 @@ class AppSettings{ } } + static Future getSourceLoctaions() async { + var uri = Uri.parse(getSourceLoctaionsUrl+'/'+supplierId); + //uri = uri.replace(query: 'supplierId=$supplierId'); + + var response = await http.get(uri, headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return response.body; + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.get(uri, headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return response.body; + } else { + return ''; + } + } else { + return ''; + } + } else { + return ''; + } + } + + static Future addSourceLocations(payload) async { + var response = await http.post(Uri.parse(addSourceLocationsUrl + '/' + supplierId), + body: json.encode(payload), headers: await buildRequestHeaders()); + + if (response.statusCode == 200) { + try { + var _response = json.decode(response.body); + print(_response); + return true; + } catch (e) { + // display error toast + return false; + } + } else if (response.statusCode == 401) { + bool status = await AppSettings.resetToken(); + if (status) { + response = await http.post(Uri.parse(addTankerUrl + '/' + supplierId), + body: json.encode(payload), headers: await buildRequestHeaders()); + if (response.statusCode == 200) { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + } + /*Apis ends here*/ @@ -569,7 +627,7 @@ class AppSettings{ await saveData('email', input['simplydata']['email'][0]['email'], 'STRING'); await saveData('supplierId', input['simplydata']['supplierId'], 'STRING'); await saveData('profile', input['simplydata']['picture'], 'STRING'); - await saveData('user_address', input['simplydata']['address1'], 'STRING'); + await saveData('user_address', input['simplydata']['office_address'], 'STRING'); if(input['simplydata']['latitude']==0){ input['simplydata']['latitude']=0.0; } diff --git a/lib/resources/employees.dart b/lib/resources/employees.dart index e54eabd..a1bc2db 100644 --- a/lib/resources/employees.dart +++ b/lib/resources/employees.dart @@ -92,7 +92,6 @@ class _FleetEmployeesState extends State { return; } var payload = new Map(); - payload["tankerName"] = _nameCtrl.text.toString(); payload["Name"] = _nameCtrl.text.toString(); payload["license_number"] =selectedLicense.toString(); payload["address"] = AppSettings.userAddress; diff --git a/lib/resources/resources_drivers.dart b/lib/resources/resources_drivers.dart index 0c4da92..9f1d52c 100644 --- a/lib/resources/resources_drivers.dart +++ b/lib/resources/resources_drivers.dart @@ -1,17 +1,9 @@ import 'dart:convert'; - import 'package:flutter/material.dart'; import 'package:supplier_new/common/settings.dart'; import 'package:supplier_new/resources/drivers_model.dart'; -import 'package:supplier_new/resources/resources_sources.dart'; -import 'fleet.dart'; -import 'resources_drivers.dart'; -import 'resources_sources.dart'; - - import 'employees.dart'; -void main() => runApp(const MaterialApp(home: ResourcesDriverScreen())); class ResourcesDriverScreen extends StatefulWidget { const ResourcesDriverScreen({super.key}); diff --git a/lib/resources/resources_sources.dart b/lib/resources/resources_sources.dart index 371a467..b0e5491 100644 --- a/lib/resources/resources_sources.dart +++ b/lib/resources/resources_sources.dart @@ -1,6 +1,9 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:supplier_new/common/settings.dart'; import 'package:supplier_new/resources/source_location.dart'; +import 'package:supplier_new/resources/source_loctaions_model.dart'; import 'fleet.dart'; import 'resources_drivers.dart'; import 'resources_sources.dart'; @@ -18,6 +21,34 @@ class ResourcesSourceScreen extends StatefulWidget { class _ResourcesSourceScreenState extends State { int selectedTab = 2; String search = ''; + bool isLoading = false; + List sourceLocationsList = []; + + @override + void initState() { + // TODO: implement initState + super.initState(); + _fetchDrivers(); + } + + Future _fetchDrivers() async { + setState(() => isLoading = true); + + try { + final response = await AppSettings.getSourceLoctaions(); + final data = (jsonDecode(response)['data'] as List) + .map((e) => SourceLocationsModel.fromJson(e)) + .toList(); + if (!mounted) return; + setState(() { + sourceLocationsList = data; + isLoading = false; + }); + } catch (e) { + debugPrint("⚠️ Error fetching orders: $e"); + setState(() => isLoading = false); + } + } final List> items = [ { @@ -44,12 +75,11 @@ class _ResourcesSourceScreenState extends State { @override Widget build(BuildContext context) { - final filtered = items.where((it) { + final filtered = sourceLocationsList.where((it) { final q = search.trim().toLowerCase(); if (q.isEmpty) return true; - return it['title'].toLowerCase().contains(q) || - it['subtitle'].toLowerCase().contains(q) || - (it['owner']?.toLowerCase() ?? '').contains(q); + return it.source_name.toLowerCase().contains(q) || + it.address.toLowerCase().contains(q); }).toList(); return Scaffold( @@ -106,7 +136,7 @@ class _ResourcesSourceScreenState extends State { mainAxisSize: MainAxisSize.min, children: [ Text( - '04', + '${sourceLocationsList.length.toString()}', style: fontTextStyle(24, const Color(0xFF0D3771), FontWeight.w500), ), const SizedBox(height: 6), @@ -218,8 +248,8 @@ class _ResourcesSourceScreenState extends State { itemBuilder: (context, idx) { final it = filtered[idx]; return TankCard( - title: it['title'], - subtitle: it['subtitle'], + title: it.source_name, + subtitle: it.address, ); }, ), diff --git a/lib/resources/source_location.dart b/lib/resources/source_location.dart index e50c742..a5eaa84 100644 --- a/lib/resources/source_location.dart +++ b/lib/resources/source_location.dart @@ -1,9 +1,18 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:supplier_new/common/settings.dart'; -import 'package:supplier_new/resources/source_location1.dart'; +import '../common/keys.dart'; +import '../google_maps_place_picker_mb/src/models/pick_result.dart'; +import '../google_maps_place_picker_mb/src/place_picker.dart'; +import 'package:supplier_new/google_maps_place_picker_mb/google_maps_place_picker.dart'; +import 'dart:io' show File, Platform; +import 'package:google_maps_flutter_android/google_maps_flutter_android.dart'; +import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart'; +import 'package:location/location.dart' as locationmap; -import 'Fleet_1.dart'; void main() => runApp(const MaterialApp(home: SourceLocation())); class SourceLocation extends StatefulWidget { @@ -17,24 +26,61 @@ class _SourceLocationState extends State { final _formKey = GlobalKey(); // Controllers - final _nameCtrl = TextEditingController(); + final _locationNameController = TextEditingController(); final _mobileCtrl = TextEditingController(); - final _altMobileCtrl = TextEditingController(); + String address=''; + + String address1 = ''; + String address2 = ''; + String city = ''; + String state = ''; + String zip = ''; + String country = ''; + double lat=0; + double lng=0; + + PickResult? selectedPlace; + + bool _mapsInitialized = false; + final String _mapsRenderer = "latest"; + + var kInitialPosition = const LatLng(15.462477, 78.717401); + + locationmap.Location location = locationmap.Location(); + + final GoogleMapsFlutterPlatform mapsImplementation = + GoogleMapsFlutterPlatform.instance; + + void initRenderer() { + if (_mapsInitialized) return; + if (mapsImplementation is GoogleMapsFlutterAndroid) { + switch (_mapsRenderer) { + case "legacy": + (mapsImplementation as GoogleMapsFlutterAndroid) + .initializeWithRenderer(AndroidMapRenderer.legacy); + break; + case "latest": + (mapsImplementation as GoogleMapsFlutterAndroid) + .initializeWithRenderer(AndroidMapRenderer.latest); + break; + } + } + setState(() { + _mapsInitialized = true; + }); + } + // Dropdowns final List waterTypes = [ "Drinking Water", + "Bore Water", "Industrial", "Construction", "Non-potable", ]; String? selectedWaterType; - String? selectedLicense; - - final List yearOptions = ["1", "2", "3", "4", "5"]; - String? selectedExperience; - // Data bucket final List> _drivers = []; @@ -56,46 +102,71 @@ class _SourceLocationState extends State { @override void dispose() { - _nameCtrl.dispose(); + _locationNameController.dispose(); _mobileCtrl.dispose(); - _altMobileCtrl.dispose(); super.dispose(); } bool addBusinessAsSource = false; - Map _buildPayload() => { - "driver_name": _nameCtrl.text.trim(), - "license_number": selectedLicense, - "experience_years": selectedExperience, - "phone": _mobileCtrl.text.trim(), - "alt_phone": _altMobileCtrl.text.trim(), - }; void _clearForm() { - _nameCtrl.clear(); + _locationNameController.clear(); _mobileCtrl.clear(); - _altMobileCtrl.clear(); - selectedLicense = null; - selectedExperience = null; + selectedWaterType = null; setState(() {}); } - void _addDriver() { + void _addSourceLocation() async{ final ok = _formKey.currentState?.validate() ?? false; + + if(addBusinessAsSource){ + setState(() { + address=AppSettings.userAddress; + lat=AppSettings.supplierLatitude; + lng=AppSettings.supplierLongitude; + }); + } + setState(() {}); // ensure error texts render if (!ok || - selectedLicense == null || - selectedExperience == null || - selectedLicense!.isEmpty || - selectedExperience!.isEmpty) { - if (selectedLicense == null || selectedExperience == null) { + selectedWaterType == null || + selectedWaterType!.isEmpty) { + if (selectedWaterType == null) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar(content: Text("Please select License & Experience")), + const SnackBar(content: Text("Please select Water type")), ); } return; } - _drivers.add(_buildPayload()); + var payload = new Map(); + payload["location_name"] = _locationNameController.text.toString(); + payload["phone"] = _mobileCtrl.text.toString(); + payload["water_type"] =selectedWaterType.toString(); + payload["status"] ='string'; + payload["address"] = address; + payload["city"] = ''; + payload["state"] = ''; + payload["zip"] =''; + payload["latitude"] = lat; + payload["longitude"] = lng; + + + + bool tankStatus = await AppSettings.addSourceLocations(payload); + + try { + if (tankStatus) { + AppSettings.longSuccessToast("Source location added Successfully"); + _locationNameController.text = ''; + Navigator.pop(context,true); + + } + else { + AppSettings.longFailedToast("Tanker Creation failed"); + } + } catch (exception) { + print(exception); + } _clearForm(); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text("Driver added (${_drivers.length})")), @@ -141,7 +212,7 @@ class _SourceLocationState extends State { children: [ // Step indicator Text( - "Step 1/5", + "Step 3/5", style: fontTextStyle(16, const Color(0xFFC3C4C4), FontWeight.w500), ), const SizedBox(height: 16), @@ -216,7 +287,7 @@ class _SourceLocationState extends State { _LabeledField( label: "Location Name *", child: TextFormField( - controller: _nameCtrl, + controller: _locationNameController, validator: (v) => _required(v, field: "Location Name"), decoration: InputDecoration( hintText: "Location Name", @@ -249,13 +320,106 @@ class _SourceLocationState extends State { textInputAction: TextInputAction.next, ), ), - Column( + Visibility( + visible: !addBusinessAsSource, + child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SizedBox( width: double.infinity, child: OutlinedButton.icon( - onPressed: _addDriver, + onPressed: (){ + location.serviceEnabled().then((value) { + if (value) { + initRenderer(); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return PlacePicker( + resizeToAvoidBottomInset: false, + hintText: "Find a place ...", + searchingText: "Please wait ...", + selectText: "Select place", + outsideOfPickAreaText: "Place not in area", + initialPosition: kInitialPosition, + useCurrentLocation: true, + selectInitialPosition: true, + usePinPointingSearch: true, + usePlaceDetailSearch: true, + zoomGesturesEnabled: true, + zoomControlsEnabled: true, + onMapCreated: (GoogleMapController controller) {}, + onPlacePicked: (PickResult result) { + setState(() { + selectedPlace = result; + lat=selectedPlace!.geometry!.location.lat; + lng=selectedPlace!.geometry!.location.lng; + if(selectedPlace!.types!.length==1){ + address = + selectedPlace!.formattedAddress!; + } + else{ + address =selectedPlace!.name!+', '+selectedPlace!.formattedAddress!; + } + Navigator.of(context).pop(); + }); + }, + onMapTypeChanged: (MapType mapType) {}, + apiKey: Platform.isAndroid + ? APIKeys.androidApiKey + : APIKeys.iosApiKey, + forceAndroidLocationManager: true, + ); + }, + ), + ); + } else { + showGeneralDialog( + context: context, + pageBuilder: (context, x, y) { + return Scaffold( + backgroundColor: Colors.grey.withOpacity(.5), + body: Center( + child: Container( + width: double.infinity, + height: 150, + padding: + const EdgeInsets.symmetric(horizontal: 20), + child: Card( + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + "Please enable the location", + style: TextStyle( + fontSize:18, + fontWeight: FontWeight.w500, + ), + ), + const SizedBox( + height: 20, + ), + ElevatedButton( + onPressed: () { + Navigator.pop(context); + }, + child: const Text("Cancel"), + ), + ], + ), + ), + ), + ), + ), + ); + }, + ); + } + }); + }, icon: Image.asset('images/Add_icon.png', width: 16, height: 16), label: Text( "Add Location on map", @@ -266,7 +430,7 @@ class _SourceLocationState extends State { const SizedBox(height: 12), ], - ), + ),), _LabeledField( label: "Water Type *", child: DropdownButtonFormField( @@ -301,7 +465,7 @@ class _SourceLocationState extends State { SizedBox( width: double.infinity, child: OutlinedButton.icon( - onPressed: _addDriver, + onPressed: _addSourceLocation, icon: Image.asset('images/Add_icon.png', width: 16, height: 16), label: Text( "Add Location", diff --git a/lib/resources/source_loctaions_model.dart b/lib/resources/source_loctaions_model.dart new file mode 100644 index 0000000..487f997 --- /dev/null +++ b/lib/resources/source_loctaions_model.dart @@ -0,0 +1,24 @@ +class SourceLocationsModel { + String source_name=''; + String supplierId=''; + String status=''; + String address=''; + String deliveries='13'; + String commision=''; + String phone=''; + List availability= ['filled', 'available']; + SourceLocationsModel(); + + factory SourceLocationsModel.fromJson(Map json){ + SourceLocationsModel rtvm = new SourceLocationsModel(); + + + rtvm.source_name = json['location_name'] ?? ''; + rtvm.supplierId = json['supplierId'] ?? ''; + rtvm.status = json['status'] ?? ''; + rtvm.address = json['address'] ?? ''; + rtvm.phone = json['phone'] ?? ''; + + return rtvm; + } +} \ No newline at end of file