|
|
|
|
@ -1,5 +1,6 @@
|
|
|
|
|
import 'dart:convert';
|
|
|
|
|
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/profile/service_locations_radius.dart';
|
|
|
|
|
@ -19,12 +20,13 @@ class _ServiceLocationState extends State<ServiceLocation> {
|
|
|
|
|
final _formKey = GlobalKey<FormState>();
|
|
|
|
|
String _deliveryFrom = 'business';
|
|
|
|
|
final TextEditingController _radiusController =
|
|
|
|
|
TextEditingController(text: "10");
|
|
|
|
|
TextEditingController(text: "10");
|
|
|
|
|
bool _customizeEachSource = false;
|
|
|
|
|
bool isLoading = false;
|
|
|
|
|
int currentStep = 3;
|
|
|
|
|
List<SourceLocationsModel> sourceLocationsList = [];
|
|
|
|
|
|
|
|
|
|
Map<int, TextEditingController> radiusControllers = {};
|
|
|
|
|
Map<int, ValueNotifier<double>> radiusNotifiers = {};
|
|
|
|
|
// 🔹 Notifier for dynamic map radius
|
|
|
|
|
late final ValueNotifier<double> _radiusKmNotifier;
|
|
|
|
|
|
|
|
|
|
@ -64,25 +66,48 @@ class _ServiceLocationState extends State<ServiceLocation> {
|
|
|
|
|
|
|
|
|
|
Future<void> _fetchSources() 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;
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < data.length; i++) {
|
|
|
|
|
|
|
|
|
|
_expandedMap[i] = false;
|
|
|
|
|
|
|
|
|
|
// ✅ CREATE CONTROLLERS FOR EACH LOCATION
|
|
|
|
|
radiusControllers[i] = TextEditingController(text: "10");
|
|
|
|
|
|
|
|
|
|
radiusNotifiers[i] = ValueNotifier<double>(10);
|
|
|
|
|
|
|
|
|
|
// 🔁 update map when radius changes
|
|
|
|
|
radiusControllers[i]!.addListener(() {
|
|
|
|
|
|
|
|
|
|
final value = double.tryParse(radiusControllers[i]!.text);
|
|
|
|
|
|
|
|
|
|
radiusNotifiers[i]!.value =
|
|
|
|
|
(value == null || value <= 0) ? 10 : value;
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
debugPrint("⚠️ Error fetching source locations: $e");
|
|
|
|
|
setState(() => isLoading = false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
return Scaffold(
|
|
|
|
|
@ -184,6 +209,13 @@ class _ServiceLocationState extends State<ServiceLocation> {
|
|
|
|
|
TextFormField(
|
|
|
|
|
controller: _radiusController,
|
|
|
|
|
keyboardType: TextInputType.number,
|
|
|
|
|
|
|
|
|
|
inputFormatters: [
|
|
|
|
|
FilteringTextInputFormatter.digitsOnly,
|
|
|
|
|
FilteringTextInputFormatter.deny(RegExp(r'^0')),
|
|
|
|
|
LengthLimitingTextInputFormatter(3), // optional (max 999 km)
|
|
|
|
|
],
|
|
|
|
|
|
|
|
|
|
decoration: InputDecoration(
|
|
|
|
|
hintText: "Enter radius in kms",
|
|
|
|
|
hintStyle: fontTextStyle(
|
|
|
|
|
@ -194,6 +226,19 @@ class _ServiceLocationState extends State<ServiceLocation> {
|
|
|
|
|
contentPadding: const EdgeInsets.symmetric(
|
|
|
|
|
horizontal: 12, vertical: 12),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
validator: (value) {
|
|
|
|
|
|
|
|
|
|
if (value == null || value.isEmpty) {
|
|
|
|
|
return "Enter radius";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (int.tryParse(value)! <= 0) {
|
|
|
|
|
return "Radius must be greater than 0";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
Container(
|
|
|
|
|
@ -325,58 +370,66 @@ class _ServiceLocationState extends State<ServiceLocation> {
|
|
|
|
|
border: Border.all(
|
|
|
|
|
color: const Color(0xFFE5E5E5)),
|
|
|
|
|
),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Text("Delivery Radius (in Kms) *",
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
|
|
|
|
|
Text(
|
|
|
|
|
"Delivery Radius (in Kms) *",
|
|
|
|
|
style: fontTextStyle(
|
|
|
|
|
12,
|
|
|
|
|
const Color(0xFF2F3036),
|
|
|
|
|
FontWeight.w600)),
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
TextFormField(
|
|
|
|
|
controller: _radiusController,
|
|
|
|
|
keyboardType: TextInputType.number,
|
|
|
|
|
decoration: InputDecoration(
|
|
|
|
|
hintText: "Enter radius in kms",
|
|
|
|
|
hintStyle: fontTextStyle(
|
|
|
|
|
14,
|
|
|
|
|
const Color(0xFF939495),
|
|
|
|
|
FontWeight.w400),
|
|
|
|
|
border: OutlineInputBorder(
|
|
|
|
|
borderRadius:
|
|
|
|
|
BorderRadius.circular(8),
|
|
|
|
|
),
|
|
|
|
|
contentPadding:
|
|
|
|
|
const EdgeInsets.symmetric(
|
|
|
|
|
horizontal: 12, vertical: 12),
|
|
|
|
|
12, const Color(0xFF2F3036), FontWeight.w600),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
Container(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
height: 180,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
borderRadius:
|
|
|
|
|
BorderRadius.circular(8),
|
|
|
|
|
border: Border.all(
|
|
|
|
|
color: const Color(0xFFE6E6E6)),
|
|
|
|
|
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
|
|
|
|
|
TextFormField(
|
|
|
|
|
controller: radiusControllers[index],
|
|
|
|
|
keyboardType: TextInputType.number,
|
|
|
|
|
onChanged: (value) {
|
|
|
|
|
|
|
|
|
|
double radius = double.tryParse(value) ?? 0;
|
|
|
|
|
|
|
|
|
|
radiusNotifiers[index]!.value = radius;
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
decoration: InputDecoration(
|
|
|
|
|
hintText: "Enter radius in kms",
|
|
|
|
|
hintStyle: fontTextStyle(
|
|
|
|
|
14, const Color(0xFF939495), FontWeight.w400),
|
|
|
|
|
border: OutlineInputBorder(
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
),
|
|
|
|
|
contentPadding:
|
|
|
|
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 12),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
child: ClipRRect(
|
|
|
|
|
borderRadius:
|
|
|
|
|
BorderRadius.circular(8),
|
|
|
|
|
child: ServiceLocationsRadiusScreen(
|
|
|
|
|
initialPosition: LatLng(
|
|
|
|
|
d.latitude ?? 17.3850,
|
|
|
|
|
d.longitude ?? 78.4867,
|
|
|
|
|
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
|
|
|
|
|
Container(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
height: 180,
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
border: Border.all(color: const Color(0xFFE6E6E6)),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
child: ClipRRect(
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
|
|
|
|
|
child: ServiceLocationsRadiusScreen(
|
|
|
|
|
initialPosition: LatLng(
|
|
|
|
|
d.latitude ?? 17.3850,
|
|
|
|
|
d.longitude ?? 78.4867,
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
radiusKmListenable: radiusNotifiers[index]!,
|
|
|
|
|
|
|
|
|
|
),
|
|
|
|
|
radiusKmListenable:
|
|
|
|
|
_radiusKmNotifier,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
@ -391,15 +444,17 @@ class _ServiceLocationState extends State<ServiceLocation> {
|
|
|
|
|
const SizedBox(height: 16),
|
|
|
|
|
Container(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
height: 250,
|
|
|
|
|
height: 220, // 👈 small map fits neatly
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
border: Border.all(color: const Color(0xFFE6E6E6)),
|
|
|
|
|
border:
|
|
|
|
|
Border.all(color: const Color(0xFFE6E6E6)),
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
),
|
|
|
|
|
child: ClipRRect(
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
child: ServiceLocationsRadiusScreen(
|
|
|
|
|
initialPosition: const LatLng(20.5937, 78.9629),
|
|
|
|
|
initialPosition:
|
|
|
|
|
const LatLng(17.381597, 78.481791),
|
|
|
|
|
radiusKmListenable: _radiusKmNotifier,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|