repair river station name and code from local db
This commit is contained in:
parent
641c073d76
commit
d2b3ca2bb0
@ -38,8 +38,7 @@ class _RiverInSituStep1SamplingInfoState extends State<RiverInSituStep1SamplingI
|
|||||||
late final TextEditingController _currentLonController;
|
late final TextEditingController _currentLonController;
|
||||||
|
|
||||||
List<String> _statesList = [];
|
List<String> _statesList = [];
|
||||||
List<String> _categoriesForState = [];
|
List<Map<String, dynamic>> _stationsForState = [];
|
||||||
List<Map<String, dynamic>> _stationsForCategory = [];
|
|
||||||
final List<String> _samplingTypes = ['Schedule', 'Ad-Hoc', 'Complaint'];
|
final List<String> _samplingTypes = ['Schedule', 'Ad-Hoc', 'Complaint'];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -94,20 +93,8 @@ class _RiverInSituStep1SamplingInfoState extends State<RiverInSituStep1SamplingI
|
|||||||
states.sort();
|
states.sort();
|
||||||
|
|
||||||
if (widget.data.selectedStateName != null) {
|
if (widget.data.selectedStateName != null) {
|
||||||
final categories = allStations
|
_stationsForState = allStations
|
||||||
.where((s) => s['state_name'] == widget.data.selectedStateName)
|
.where((s) => s['state_name'] == widget.data.selectedStateName)
|
||||||
.map((s) => s['category_name'] as String?)
|
|
||||||
.whereType<String>()
|
|
||||||
.toSet()
|
|
||||||
.toList();
|
|
||||||
categories.sort();
|
|
||||||
_categoriesForState = categories;
|
|
||||||
}
|
|
||||||
if (widget.data.selectedCategoryName != null) {
|
|
||||||
_stationsForCategory = allStations
|
|
||||||
.where((s) =>
|
|
||||||
s['state_name'] == widget.data.selectedStateName &&
|
|
||||||
s['category_name'] == widget.data.selectedCategoryName)
|
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,8 +253,6 @@ class _RiverInSituStep1SamplingInfoState extends State<RiverInSituStep1SamplingI
|
|||||||
return Form(
|
return Form(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: ListView(
|
child: ListView(
|
||||||
// REMOVED: physics property to allow scrolling.
|
|
||||||
// shrinkWrap: true, // This can be kept or removed; it's less critical in PageView.
|
|
||||||
padding: const EdgeInsets.all(24.0),
|
padding: const EdgeInsets.all(24.0),
|
||||||
children: [
|
children: [
|
||||||
Text("Sampling Information", style: Theme.of(context).textTheme.headlineSmall),
|
Text("Sampling Information", style: Theme.of(context).textTheme.headlineSmall),
|
||||||
@ -298,6 +283,21 @@ class _RiverInSituStep1SamplingInfoState extends State<RiverInSituStep1SamplingI
|
|||||||
decoration: const InputDecoration(labelText: 'Sampling Type *'),
|
decoration: const InputDecoration(labelText: 'Sampling Type *'),
|
||||||
validator: (value) => value == null ? 'Please select a type' : null,
|
validator: (value) => value == null ? 'Please select a type' : null,
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
|
||||||
|
TextFormField(
|
||||||
|
controller: _barcodeController,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: 'Sample ID Code *',
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: const Icon(Icons.qr_code_scanner),
|
||||||
|
onPressed: _scanBarcode,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
validator: (val) => val == null || val.isEmpty ? "Sample ID is required" : null,
|
||||||
|
onSaved: (val) => widget.data.sampleIdCode = val,
|
||||||
|
onChanged: (val) => widget.data.sampleIdCode = val,
|
||||||
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
|
|
||||||
DropdownSearch<String>(
|
DropdownSearch<String>(
|
||||||
@ -308,64 +308,44 @@ class _RiverInSituStep1SamplingInfoState extends State<RiverInSituStep1SamplingI
|
|||||||
onChanged: (state) {
|
onChanged: (state) {
|
||||||
setState(() {
|
setState(() {
|
||||||
widget.data.selectedStateName = state;
|
widget.data.selectedStateName = state;
|
||||||
widget.data.selectedCategoryName = null;
|
|
||||||
widget.data.selectedStation = null;
|
widget.data.selectedStation = null;
|
||||||
_stationLatController.clear();
|
_stationLatController.clear();
|
||||||
_stationLonController.clear();
|
_stationLonController.clear();
|
||||||
widget.data.distanceDifferenceInKm = null;
|
widget.data.distanceDifferenceInKm = null;
|
||||||
|
|
||||||
final categories = state != null
|
_stationsForState = state != null
|
||||||
? allStations
|
? allStations
|
||||||
.where((s) => s['state_name'] == state)
|
.where((s) => s['state_name'] == state)
|
||||||
.map((s) => s['category_name'] as String?)
|
|
||||||
.whereType<String>()
|
|
||||||
.toSet()
|
|
||||||
.toList()
|
.toList()
|
||||||
: <String>[];
|
: [];
|
||||||
categories.sort();
|
|
||||||
_categoriesForState = categories;
|
|
||||||
|
|
||||||
_stationsForCategory = [];
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
validator: (val) => val == null ? "State is required" : null,
|
validator: (val) => val == null ? "State is required" : null,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
DropdownSearch<String>(
|
|
||||||
items: _categoriesForState,
|
|
||||||
selectedItem: widget.data.selectedCategoryName,
|
|
||||||
enabled: widget.data.selectedStateName != null,
|
|
||||||
popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search Category..."))),
|
|
||||||
dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select Category *")),
|
|
||||||
onChanged: (category) {
|
|
||||||
setState(() {
|
|
||||||
widget.data.selectedCategoryName = category;
|
|
||||||
widget.data.selectedStation = null;
|
|
||||||
_stationLatController.clear();
|
|
||||||
_stationLonController.clear();
|
|
||||||
widget.data.distanceDifferenceInKm = null;
|
|
||||||
_stationsForCategory = category != null ? allStations.where((s) => s['state_name'] == widget.data.selectedStateName && s['category_name'] == category).toList() : [];
|
|
||||||
});
|
|
||||||
},
|
|
||||||
validator: (val) => widget.data.selectedStateName != null && val == null ? "Category is required" : null,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
DropdownSearch<Map<String, dynamic>>(
|
DropdownSearch<Map<String, dynamic>>(
|
||||||
items: _stationsForCategory,
|
items: _stationsForState,
|
||||||
selectedItem: widget.data.selectedStation,
|
selectedItem: widget.data.selectedStation,
|
||||||
enabled: widget.data.selectedCategoryName != null,
|
enabled: widget.data.selectedStateName != null,
|
||||||
itemAsString: (station) => "${station['r_man_station_code']} - ${station['r_man_station_name']}",
|
itemAsString: (station) =>
|
||||||
popupProps: const PopupProps.menu(showSearchBox: true, searchFieldProps: TextFieldProps(decoration: InputDecoration(hintText: "Search Station..."))),
|
"${station['sampling_station_code']} | ${station['sampling_river']} | ${station['sampling_basin']}",
|
||||||
dropdownDecoratorProps: const DropDownDecoratorProps(dropdownSearchDecoration: InputDecoration(labelText: "Select Station *")),
|
popupProps: const PopupProps.menu(
|
||||||
|
showSearchBox: true,
|
||||||
|
searchFieldProps: TextFieldProps(
|
||||||
|
decoration: InputDecoration(hintText: "Search Station..."))),
|
||||||
|
dropdownDecoratorProps: const DropDownDecoratorProps(
|
||||||
|
dropdownSearchDecoration: InputDecoration(
|
||||||
|
labelText: "Select Station *")),
|
||||||
onChanged: (station) => setState(() {
|
onChanged: (station) => setState(() {
|
||||||
widget.data.selectedStation = station;
|
widget.data.selectedStation = station;
|
||||||
widget.data.stationLatitude = station?['r_man_latitude']?.toString();
|
widget.data.stationLatitude = station?['sampling_lat']?.toString();
|
||||||
widget.data.stationLongitude = station?['r_man_longitude']?.toString();
|
widget.data.stationLongitude = station?['sampling_long']?.toString();
|
||||||
_stationLatController.text = widget.data.stationLatitude ?? '';
|
_stationLatController.text = widget.data.stationLatitude ?? '';
|
||||||
_stationLonController.text = widget.data.stationLongitude ?? '';
|
_stationLonController.text = widget.data.stationLongitude ?? '';
|
||||||
_calculateDistance();
|
_calculateDistance();
|
||||||
}),
|
}),
|
||||||
validator: (val) => widget.data.selectedCategoryName != null && val == null ? "Station is required" : null,
|
validator: (val) => widget.data.selectedStateName != null && val == null ? "Station is required" : null,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
TextFormField(controller: _stationLatController, readOnly: true, decoration: const InputDecoration(labelText: 'Station Latitude')),
|
TextFormField(controller: _stationLatController, readOnly: true, decoration: const InputDecoration(labelText: 'Station Latitude')),
|
||||||
@ -412,21 +392,6 @@ class _RiverInSituStep1SamplingInfoState extends State<RiverInSituStep1SamplingI
|
|||||||
icon: _isLoadingLocation ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2)) : const Icon(Icons.location_searching),
|
icon: _isLoadingLocation ? const SizedBox(width: 20, height: 20, child: CircularProgressIndicator(strokeWidth: 2)) : const Icon(Icons.location_searching),
|
||||||
label: const Text("Get Current Location"),
|
label: const Text("Get Current Location"),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
|
||||||
|
|
||||||
TextFormField(
|
|
||||||
controller: _barcodeController,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: 'Sample ID Code *',
|
|
||||||
suffixIcon: IconButton(
|
|
||||||
icon: const Icon(Icons.qr_code_scanner),
|
|
||||||
onPressed: _scanBarcode,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
validator: (val) => val == null || val.isEmpty ? "Sample ID is required" : null,
|
|
||||||
onSaved: (val) => widget.data.sampleIdCode = val,
|
|
||||||
onChanged: (val) => widget.data.sampleIdCode = val,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 32),
|
const SizedBox(height: 32),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: _goToNextStep,
|
onPressed: _goToNextStep,
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
// lib/screens/river/manual/widgets/river_in_situ_step_2_site_info.dart
|
|
||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
@ -33,9 +31,8 @@ class _RiverInSituStep2SiteInfoState extends State<RiverInSituStep2SiteInfo> {
|
|||||||
late final TextEditingController _optionalRemark3Controller;
|
late final TextEditingController _optionalRemark3Controller;
|
||||||
late final TextEditingController _optionalRemark4Controller;
|
late final TextEditingController _optionalRemark4Controller;
|
||||||
|
|
||||||
final List<String> _weatherOptions = ['Clear', 'Rainy', 'Cloudy'];
|
final List<String> _weatherOptions = ['Clear', 'Rainy', 'Cloudy', 'Windy', 'Sunny', 'Drizzle'];
|
||||||
final List<String> _waterLevelOptions = ['Normal', 'High', 'Low'];
|
// MODIFIED: Removed _waterLevelOptions and _riverConditionOptions
|
||||||
final List<String> _riverConditionOptions = ['Calm', 'Moderate Flow', 'Fast Flow'];
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -113,7 +110,6 @@ class _RiverInSituStep2SiteInfoState extends State<RiverInSituStep2SiteInfo> {
|
|||||||
return Form(
|
return Form(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: ListView(
|
child: ListView(
|
||||||
// REMOVED: physics property to allow scrolling.
|
|
||||||
padding: const EdgeInsets.all(24.0),
|
padding: const EdgeInsets.all(24.0),
|
||||||
children: [
|
children: [
|
||||||
Text("On-Site Information", style: Theme.of(context).textTheme.headlineSmall),
|
Text("On-Site Information", style: Theme.of(context).textTheme.headlineSmall),
|
||||||
@ -126,22 +122,8 @@ class _RiverInSituStep2SiteInfoState extends State<RiverInSituStep2SiteInfo> {
|
|||||||
validator: (value) => value == null ? 'Weather is required' : null,
|
validator: (value) => value == null ? 'Weather is required' : null,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
DropdownButtonFormField<String>(
|
// MODIFIED: The DropdownButtonFormField for 'Water Level' has been removed.
|
||||||
value: widget.data.waterLevel,
|
// MODIFIED: The DropdownButtonFormField for 'River Condition' has been removed.
|
||||||
items: _waterLevelOptions.map((item) => DropdownMenuItem(value: item, child: Text(item))).toList(),
|
|
||||||
onChanged: (value) => setState(() => widget.data.waterLevel = value),
|
|
||||||
decoration: const InputDecoration(labelText: 'Water Level *'),
|
|
||||||
validator: (value) => value == null ? 'Water level is required' : null,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
DropdownButtonFormField<String>(
|
|
||||||
value: widget.data.riverCondition,
|
|
||||||
items: _riverConditionOptions.map((item) => DropdownMenuItem(value: item, child: Text(item))).toList(),
|
|
||||||
onChanged: (value) => setState(() => widget.data.riverCondition = value),
|
|
||||||
decoration: const InputDecoration(labelText: 'River Condition *'),
|
|
||||||
validator: (value) => value == null ? 'River condition is required' : null,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 24),
|
|
||||||
|
|
||||||
Text("Required Photos *", style: Theme.of(context).textTheme.titleLarge),
|
Text("Required Photos *", style: Theme.of(context).textTheme.titleLarge),
|
||||||
const Text("All photos must be taken in landscape (horizontal) orientation.", style: TextStyle(color: Colors.grey)),
|
const Text("All photos must be taken in landscape (horizontal) orientation.", style: TextStyle(color: Colors.grey)),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user