|
|
|
@ -4,12 +4,42 @@ import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:supplier_new/common/settings.dart';
|
|
|
|
import 'package:supplier_new/common/settings.dart';
|
|
|
|
import 'package:supplier_new/resources/source_loctaions_model.dart';
|
|
|
|
import 'package:supplier_new/resources/source_loctaions_model.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;
|
|
|
|
|
|
|
|
|
|
|
|
// If you use the PlacePicker flow in the button below, make sure you have
|
|
|
|
class FirstCharUppercaseFormatter extends TextInputFormatter {
|
|
|
|
// the needed imports in your project (google_maps_flutter, place_picker, etc).
|
|
|
|
const FirstCharUppercaseFormatter();
|
|
|
|
// import 'package:google_maps_flutter/google_maps_flutter.dart';
|
|
|
|
|
|
|
|
// import 'package:place_picker/place_picker.dart';
|
|
|
|
@override
|
|
|
|
// import 'package:location/location.dart';
|
|
|
|
TextEditingValue formatEditUpdate(
|
|
|
|
|
|
|
|
TextEditingValue oldValue,
|
|
|
|
|
|
|
|
TextEditingValue newValue,
|
|
|
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
final text = newValue.text;
|
|
|
|
|
|
|
|
if (text.isEmpty) return newValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Find first non-space char
|
|
|
|
|
|
|
|
final i = text.indexOf(RegExp(r'\S'));
|
|
|
|
|
|
|
|
if (i == -1) return newValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final first = text[i];
|
|
|
|
|
|
|
|
final upper = first.toUpperCase();
|
|
|
|
|
|
|
|
if (first == upper) return newValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final newText = text.replaceRange(i, i + 1, upper);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return newValue.copyWith(
|
|
|
|
|
|
|
|
text: newText,
|
|
|
|
|
|
|
|
selection: newValue.selection,
|
|
|
|
|
|
|
|
composing: TextRange.empty,
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void main() => runApp(const MaterialApp(home: ResourcesSourceScreen()));
|
|
|
|
void main() => runApp(const MaterialApp(home: ResourcesSourceScreen()));
|
|
|
|
|
|
|
|
|
|
|
|
@ -20,6 +50,38 @@ class ResourcesSourceScreen extends StatefulWidget {
|
|
|
|
State<ResourcesSourceScreen> createState() => _ResourcesSourceScreenState();
|
|
|
|
State<ResourcesSourceScreen> createState() => _ResourcesSourceScreenState();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class _ResourcesSourceScreenState extends State<ResourcesSourceScreen> {
|
|
|
|
class _ResourcesSourceScreenState extends State<ResourcesSourceScreen> {
|
|
|
|
int selectedTab = 2;
|
|
|
|
int selectedTab = 2;
|
|
|
|
String search = '';
|
|
|
|
String search = '';
|
|
|
|
@ -35,9 +97,6 @@ class _ResourcesSourceScreenState extends State<ResourcesSourceScreen> {
|
|
|
|
String? selectedWaterType;
|
|
|
|
String? selectedWaterType;
|
|
|
|
final List<String> waterTypes = const ['Drinking water', 'Bore water', 'Both'];
|
|
|
|
final List<String> waterTypes = const ['Drinking water', 'Bore water', 'Both'];
|
|
|
|
|
|
|
|
|
|
|
|
// Optional: values used by your map flow
|
|
|
|
|
|
|
|
// final location = Location(); // from 'location' package
|
|
|
|
|
|
|
|
// PickResult? selectedPlace;
|
|
|
|
|
|
|
|
double? lat;
|
|
|
|
double? lat;
|
|
|
|
double? lng;
|
|
|
|
double? lng;
|
|
|
|
String? address;
|
|
|
|
String? address;
|
|
|
|
@ -146,12 +205,11 @@ class _ResourcesSourceScreenState extends State<ResourcesSourceScreen> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void _openSourceFormSheet(BuildContext context) {
|
|
|
|
Future<void> _openSourceFormSheet(BuildContext context)async {
|
|
|
|
_resetForm(); // fresh form each time you open
|
|
|
|
await showModalBottomSheet(
|
|
|
|
showModalBottomSheet(
|
|
|
|
context: context,
|
|
|
|
context: context,
|
|
|
|
isScrollControlled: true,
|
|
|
|
isScrollControlled: true,
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
|
|
|
builder: (context) {
|
|
|
|
builder: (context) {
|
|
|
|
final kbInset = MediaQuery.of(context).viewInsets.bottom;
|
|
|
|
final kbInset = MediaQuery.of(context).viewInsets.bottom;
|
|
|
|
return FractionallySizedBox(
|
|
|
|
return FractionallySizedBox(
|
|
|
|
@ -169,11 +227,33 @@ class _ResourcesSourceScreenState extends State<ResourcesSourceScreen> {
|
|
|
|
child: Column(
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
|
|
children: [
|
|
|
|
children: [
|
|
|
|
|
|
|
|
Row(
|
|
|
|
|
|
|
|
children: [
|
|
|
|
|
|
|
|
Expanded(
|
|
|
|
|
|
|
|
child: Center(
|
|
|
|
|
|
|
|
child: Container(
|
|
|
|
|
|
|
|
width: 86,
|
|
|
|
|
|
|
|
height: 4,
|
|
|
|
|
|
|
|
margin: const EdgeInsets.only(bottom: 12),
|
|
|
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
|
|
color: const Color(0xFFE0E0E0),
|
|
|
|
|
|
|
|
borderRadius: BorderRadius.circular(2),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
_LabeledField(
|
|
|
|
_LabeledField(
|
|
|
|
label: "Location Name *",
|
|
|
|
label: "Location Name *",
|
|
|
|
child: TextFormField(
|
|
|
|
child: TextFormField(
|
|
|
|
controller: _locationNameController,
|
|
|
|
controller: _locationNameController,
|
|
|
|
validator: (v) => _required(v, field: "Location Name"),
|
|
|
|
validator: (v) => _required(v, field: "Location Name"),
|
|
|
|
|
|
|
|
textCapitalization: TextCapitalization.none,
|
|
|
|
|
|
|
|
inputFormatters: const [
|
|
|
|
|
|
|
|
FirstCharUppercaseFormatter(), // << live first-letter caps
|
|
|
|
|
|
|
|
],
|
|
|
|
decoration: InputDecoration(
|
|
|
|
decoration: InputDecoration(
|
|
|
|
hintText: "Location Name",
|
|
|
|
hintText: "Location Name",
|
|
|
|
hintStyle: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400),
|
|
|
|
hintStyle: fontTextStyle(14, const Color(0xFF939495), FontWeight.w400),
|
|
|
|
@ -634,6 +714,13 @@ class _LabeledField extends StatelessWidget {
|
|
|
|
|
|
|
|
|
|
|
|
const _LabeledField({required this.label, required this.child});
|
|
|
|
const _LabeledField({required this.label, required this.child});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String _capFirstWord(String input) {
|
|
|
|
|
|
|
|
if (input.isEmpty) return input;
|
|
|
|
|
|
|
|
final i = input.indexOf(RegExp(r'\S'));
|
|
|
|
|
|
|
|
if (i == -1) return input;
|
|
|
|
|
|
|
|
return input.replaceRange(i, i + 1, input[i].toUpperCase());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Padding(
|
|
|
|
return Padding(
|
|
|
|
@ -641,7 +728,10 @@ class _LabeledField extends StatelessWidget {
|
|
|
|
child: Column(
|
|
|
|
child: Column(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
children: [
|
|
|
|
Text(label, style: fontTextStyle(12, const Color(0xFF515253), FontWeight.w600)),
|
|
|
|
Text(
|
|
|
|
|
|
|
|
_capFirstWord(label),
|
|
|
|
|
|
|
|
style: fontTextStyle(12, const Color(0xFF515253), FontWeight.w600),
|
|
|
|
|
|
|
|
),
|
|
|
|
const SizedBox(height: 6),
|
|
|
|
const SizedBox(height: 6),
|
|
|
|
child,
|
|
|
|
child,
|
|
|
|
],
|
|
|
|
],
|
|
|
|
|