MIF_E31222656/lib/screens/calendar/add_field_bottom_sheet.dart

1140 lines
38 KiB
Dart

import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:uuid/uuid.dart';
import 'package:tugas_akhir_supabase/core/theme/app_colors.dart';
import 'dart:async'; // Tambahkan import untuk TimeoutException
import 'dart:convert';
import 'package:tugas_akhir_supabase/domain/entities/field.dart';
import 'package:tugas_akhir_supabase/screens/calendar/location_picker_dialog.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class AddFieldBottomSheet extends StatefulWidget {
final Function? onFieldAdded;
final Field? fieldToEdit;
const AddFieldBottomSheet({super.key, this.onFieldAdded, this.fieldToEdit});
@override
State<AddFieldBottomSheet> createState() => _AddFieldBottomSheetState();
}
class _AddFieldBottomSheetState extends State<AddFieldBottomSheet> {
final _formKey = GlobalKey<FormState>();
final _nameController = TextEditingController();
final _locationController = TextEditingController();
final _areaSizeController = TextEditingController();
final _plotCountController = TextEditingController(text: '1');
final _ownerNameController = TextEditingController();
final _customRegionController = TextEditingController();
final _customSystemTypeController = TextEditingController();
final _customLandFeatureController = TextEditingController();
final _previousCropController = TextEditingController();
final _riverDistanceController = TextEditingController();
bool _isLoading = false;
bool _isEditMode = false;
String? _fieldId;
// Koordinat lokasi
double? _latitude;
double? _longitude;
// Focus nodes untuk setiap field
final _fieldNameFocus = FocusNode();
final _locationFocus = FocusNode();
final _areaSizeFocus = FocusNode();
final _plotCountFocus = FocusNode();
final _ownerNameFocus = FocusNode();
final _customRegionFocus = FocusNode();
final _customSystemTypeFocus = FocusNode();
final _customLandFeatureFocus = FocusNode();
final _previousCropFocus = FocusNode();
final _riverDistanceFocus = FocusNode();
// Region selection
String _selectedRegion = 'Jawa';
final List<String> _regions = [
'Jawa',
'Sumatera',
'Kalimantan',
'Sulawesi',
'Bali & Nusa Tenggara',
'Maluku & Papua',
'Lainnya',
];
// Ownership type selection
String _selectedOwnershipType = 'Milik Sendiri';
final List<String> _ownershipTypes = [
'Milik Sendiri',
'Sewa',
'Bagi Hasil',
'Lainnya',
];
// Topografi selection
String _selectedTopography = 'Dataran rendah (0-100m)';
final List<String> _topographies = [
'Dataran rendah (0-100m)',
'Dataran sedang (100-500m)',
'Dataran tinggi (>500m)',
];
// Kemiringan lahan selection
String _selectedSlope = 'Datar (0-8%)';
final List<String> _slopes = [
'Datar (0-8%)',
'Landai (8-15%)',
'Miring (15-25%)',
'Curam (>25%)',
];
// Jenis tanah selection
String _selectedSoilType = 'Lempung';
final List<String> _soilTypes = [
'Lempung',
'Aluvial',
'Andosol',
'Latosol',
'Regosol',
'Podsolik',
'Grumusol',
'Litosol',
'Organosol',
'Gambut',
];
// Sumber air selection
String _selectedWaterSource = 'Irigasi';
final List<String> _waterSources = [
'Irigasi',
'Tadah Hujan',
'Sumur',
'Sungai',
'Mata Air',
];
// Jenis irigasi selection
String _selectedIrrigationType = 'Irigasi Teknis';
final List<String> _irrigationTypes = [
'Irigasi Teknis',
'Semi Teknis',
'Sederhana',
'Irigasi permukaan',
'Irigasi tetes',
'Irigasi sprinkler',
];
// Region-specific form fields
Map<String, dynamic> _regionSpecificData = {};
// Jawa specific fields
String _selectedPetakSystem = 'Petak Sawah';
final List<String> _petakSystems = [
'Petak Sawah',
'Tegal',
'Kebun',
'Campuran',
];
// Sumatera specific fields
String _selectedBlokSystem = 'Ladang';
final List<String> _blokSystems = ['Ladang', 'Kebun', 'Plasma', 'Campuran'];
// Kalimantan specific fields
String _selectedLadangSystem = 'Tetap';
final List<String> _ladangSystems = ['Tetap', 'Berpindah', 'Semi Permanen'];
// Sulawesi specific fields
String _selectedKebunSystem = 'Permanen';
final List<String> _kebunSystems = ['Permanen', 'Rotasi', 'Campuran'];
String _selectedTerrainType = 'Datar';
final List<String> _terrainTypes = [
'Datar',
'Berbukit',
'Terasering',
'Lereng',
];
// Bali & Nusa Tenggara specific fields
String _selectedSubakSystem = 'Subak Tradisional';
final List<String> _subakSystems = [
'Subak Tradisional',
'Subak Modern',
'Non-Subak',
'Campuran',
];
// Maluku & Papua specific fields
String _selectedGardenSystem = 'Kebun Sagu';
final List<String> _gardenSystems = [
'Kebun Sagu',
'Perkebunan Kelapa',
'Agroforestri',
'Ladang',
];
String _selectedForestType = 'Hutan Primer';
final List<String> _forestTypes = [
'Hutan Primer',
'Hutan Sekunder',
'Bekas Tebangan',
'Lahan Konversi',
];
@override
void initState() {
super.initState();
// Pastikan keyboard tidak terbuka saat dialog muncul
WidgetsBinding.instance.addPostFrameCallback((_) {
FocusScope.of(context).unfocus();
});
// Inisialisasi data jika dalam mode edit
if (widget.fieldToEdit != null) {
_isEditMode = true;
_fieldId = widget.fieldToEdit!.id;
_nameController.text = widget.fieldToEdit!.name;
_locationController.text = widget.fieldToEdit!.location ?? '';
_latitude = widget.fieldToEdit!.latitude;
_longitude = widget.fieldToEdit!.longitude;
if (widget.fieldToEdit!.areaSize != null) {
_areaSizeController.text = widget.fieldToEdit!.areaSize.toString();
}
_plotCountController.text = widget.fieldToEdit!.plotCount.toString();
_selectedRegion = widget.fieldToEdit!.region ?? 'Jawa';
_selectedOwnershipType =
widget.fieldToEdit!.ownershipType ?? 'Milik Sendiri';
_ownerNameController.text = widget.fieldToEdit!.ownerName ?? '';
// Inisialisasi data spesifik region jika ada
if (widget.fieldToEdit!.regionSpecificData != null) {
final data = widget.fieldToEdit!.regionSpecificData!;
// Data umum
_selectedTopography = data['topografi'] ?? 'Dataran rendah (0-100m)';
_selectedSlope = data['kemiringan_lahan'] ?? 'Datar (0-8%)';
_selectedSoilType = data['jenis_tanah'] ?? 'Lempung';
_selectedWaterSource = data['sumber_air'] ?? 'Irigasi';
_selectedIrrigationType = data['jenis_irigasi'] ?? 'Irigasi Teknis';
_previousCropController.text = data['tanaman_sebelumnya'] ?? '';
// Data spesifik region
switch (_selectedRegion) {
case 'Jawa':
_selectedPetakSystem = data['sistem_petak'] ?? 'Petak Sawah';
break;
case 'Sumatera':
_selectedBlokSystem = data['sistem_blok'] ?? 'Ladang';
break;
case 'Kalimantan':
_selectedLadangSystem = data['sistem_ladang'] ?? 'Tetap';
_riverDistanceController.text = data['jarak_sungai'] ?? '';
break;
case 'Sulawesi':
_selectedKebunSystem = data['sistem_kebun'] ?? 'Permanen';
_selectedTerrainType = data['kontur_lahan'] ?? 'Datar';
break;
case 'Bali & Nusa Tenggara':
_selectedSubakSystem = data['sistem_subak'] ?? 'Subak Tradisional';
break;
case 'Maluku & Papua':
_selectedGardenSystem = data['sistem_kebun'] ?? 'Kebun Sagu';
_selectedForestType = data['tipe_hutan'] ?? 'Hutan Primer';
break;
case 'Lainnya':
_customRegionController.text = data['nama_wilayah'] ?? '';
_customSystemTypeController.text = data['sistem_lahan'] ?? '';
_customLandFeatureController.text = data['fitur_lahan'] ?? '';
break;
}
}
}
}
@override
void dispose() {
_nameController.dispose();
_locationController.dispose();
_areaSizeController.dispose();
_plotCountController.dispose();
_ownerNameController.dispose();
_customRegionController.dispose();
_customSystemTypeController.dispose();
_customLandFeatureController.dispose();
_previousCropController.dispose();
_riverDistanceController.dispose();
_fieldNameFocus.dispose();
_locationFocus.dispose();
_areaSizeFocus.dispose();
_plotCountFocus.dispose();
_ownerNameFocus.dispose();
_customRegionFocus.dispose();
_customSystemTypeFocus.dispose();
_customLandFeatureFocus.dispose();
_previousCropFocus.dispose();
_riverDistanceFocus.dispose();
super.dispose();
}
// Update region-specific data based on selected region
void _updateRegionSpecificData() {
// Tambahkan data umum untuk semua wilayah
_regionSpecificData = {
'topografi': _selectedTopography,
'kemiringan_lahan': _selectedSlope,
'jenis_tanah': _selectedSoilType,
'sumber_air': _selectedWaterSource,
'jenis_irigasi': _selectedIrrigationType,
'tanaman_sebelumnya': _previousCropController.text,
};
// Tambahkan data spesifik wilayah
switch (_selectedRegion) {
case 'Jawa':
_regionSpecificData['sistem_petak'] = _selectedPetakSystem;
break;
case 'Sumatera':
_regionSpecificData['sistem_blok'] = _selectedBlokSystem;
break;
case 'Kalimantan':
_regionSpecificData['sistem_ladang'] = _selectedLadangSystem;
_regionSpecificData['jarak_sungai'] = _riverDistanceController.text;
break;
case 'Sulawesi':
_regionSpecificData['sistem_kebun'] = _selectedKebunSystem;
_regionSpecificData['kontur_lahan'] = _selectedTerrainType;
break;
case 'Bali & Nusa Tenggara':
_regionSpecificData['sistem_subak'] = _selectedSubakSystem;
break;
case 'Maluku & Papua':
_regionSpecificData['sistem_kebun'] = _selectedGardenSystem;
_regionSpecificData['tipe_hutan'] = _selectedForestType;
break;
case 'Lainnya':
_regionSpecificData['nama_wilayah'] = _customRegionController.text;
_regionSpecificData['sistem_lahan'] = _customSystemTypeController.text;
_regionSpecificData['fitur_lahan'] = _customLandFeatureController.text;
break;
}
}
// Tambahkan metode untuk memilih lokasi
Future<void> _showLocationPicker() async {
final result = await showDialog<LocationResult>(
context: context,
builder:
(context) => LocationPickerDialog(
initialAddress: _locationController.text,
initialLatitude: _latitude,
initialLongitude: _longitude,
),
);
if (result != null) {
setState(() {
_locationController.text = result.address;
_latitude = result.latitude;
_longitude = result.longitude;
});
}
}
Future<void> _submit() async {
if (!_formKey.currentState!.validate()) return;
// Dismiss keyboard immediately when saving
FocusScope.of(context).unfocus();
final userId = Supabase.instance.client.auth.currentUser?.id;
if (userId == null) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('User tidak ditemukan, silakan login ulang.'),
backgroundColor: Colors.red,
),
);
return;
}
setState(() => _isLoading = true);
try {
// Update region-specific data
_updateRegionSpecificData();
final id = _fieldId ?? const Uuid().v4();
final fieldData = {
'id': id,
'user_id': userId,
'name': _nameController.text,
'plot_count': int.parse(_plotCountController.text),
'region':
_selectedRegion == 'Lainnya'
? _customRegionController.text
: _selectedRegion,
'location': _locationController.text,
'latitude': _latitude,
'longitude': _longitude,
'area_size':
_areaSizeController.text.isNotEmpty
? double.parse(_areaSizeController.text)
: null,
'area_unit': '',
'ownership_type': _selectedOwnershipType,
'owner_name':
_selectedOwnershipType != 'Milik Sendiri'
? _ownerNameController.text
: null,
'region_specific_data': _regionSpecificData,
};
if (_isEditMode) {
// Update existing field
final response =
await Supabase.instance.client
.from('fields')
.update(fieldData)
.eq('id', id)
.select();
print('Update response: $response');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Lahan berhasil diperbarui'),
backgroundColor: Colors.green,
),
);
} else {
// Create new field
final response =
await Supabase.instance.client
.from('fields')
.insert(fieldData)
.select();
print('Insert response: $response');
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Lahan berhasil ditambahkan'),
backgroundColor: Colors.green,
),
);
}
if (widget.onFieldAdded != null) {
widget.onFieldAdded!();
}
if (mounted) {
Navigator.pop(context, true);
}
} catch (e) {
print('Error saving field: ${e.toString()}');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Gagal menyimpan lahan: ${e.toString()}'),
backgroundColor: Colors.red,
),
);
}
} finally {
if (mounted) {
setState(() => _isLoading = false);
}
}
}
// UI Components
Widget _buildHeader() {
return Container(
padding: const EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [const Color.fromARGB(255, 0, 79, 39), Colors.green.shade900],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
child: Center(
child: Column(
children: [
Container(
width: 50,
height: 5,
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.5),
borderRadius: BorderRadius.circular(2.5),
),
margin: const EdgeInsets.only(bottom: 16),
),
Text(
_isEditMode ? 'Edit Lahan' : 'Tambah Lahan Baru',
style: const TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
Text(
_isEditMode
? 'Perbarui informasi lahan Anda'
: 'Lengkapi informasi lahan pertanian Anda',
style: TextStyle(
color: Colors.white.withOpacity(0.8),
fontSize: 14,
),
),
],
),
),
);
}
Widget _buildTextField({
required String label,
required TextEditingController controller,
required IconData icon,
required FocusNode focusNode,
TextInputType keyboardType = TextInputType.text,
String? Function(String?)? validator,
String? hintText,
bool readOnly = false,
}) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: TextFormField(
controller: controller,
focusNode: focusNode,
decoration: InputDecoration(
labelText: label,
hintText: hintText,
prefixIcon: Icon(icon),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
),
keyboardType: keyboardType,
validator: validator,
readOnly: readOnly,
),
);
}
Widget _buildDropdown({
required String label,
required String value,
required List<String> items,
required Function(String?) onChanged,
required IconData icon,
}) {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: DropdownButtonFormField<String>(
value: value,
decoration: InputDecoration(
labelText: label,
prefixIcon: Icon(icon),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
),
items:
items.map((String item) {
return DropdownMenuItem<String>(value: item, child: Text(item));
}).toList(),
onChanged: _isLoading ? null : onChanged,
),
);
}
Widget _buildSectionTitle(String title) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Row(
children: [
Container(
width: 4,
height: 20,
decoration: BoxDecoration(
color: Colors.green,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(width: 8),
Text(
title,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
],
),
);
}
Widget _buildRegionSpecificFields() {
switch (_selectedRegion) {
case 'Jawa':
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Pulau Jawa'),
_buildDropdown(
label: 'Sistem Petak',
value: _selectedPetakSystem,
items: _petakSystems,
icon: Icons.grid_on,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedPetakSystem = value;
});
}
},
),
],
);
case 'Sumatera':
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Pulau Sumatera'),
_buildDropdown(
label: 'Sistem Blok',
value: _selectedBlokSystem,
items: _blokSystems,
icon: Icons.dashboard,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedBlokSystem = value;
});
}
},
),
],
);
case 'Kalimantan':
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Pulau Kalimantan'),
_buildDropdown(
label: 'Sistem Ladang',
value: _selectedLadangSystem,
items: _ladangSystems,
icon: Icons.agriculture,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedLadangSystem = value;
});
}
},
),
_buildTextField(
label: 'Jarak dari Sungai (meter)',
controller: _riverDistanceController,
icon: Icons.waves,
focusNode: _riverDistanceFocus,
keyboardType: TextInputType.number,
hintText: 'Contoh: 500',
),
],
);
case 'Sulawesi':
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Pulau Sulawesi'),
_buildDropdown(
label: 'Sistem Kebun',
value: _selectedKebunSystem,
items: _kebunSystems,
icon: Icons.eco,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedKebunSystem = value;
});
}
},
),
_buildDropdown(
label: 'Kontur Lahan',
value: _selectedTerrainType,
items: _terrainTypes,
icon: Icons.terrain,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedTerrainType = value;
});
}
},
),
],
);
case 'Bali & Nusa Tenggara':
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Pulau Bali & Nusa Tenggara'),
_buildDropdown(
label: 'Sistem Subak',
value: _selectedSubakSystem,
items: _subakSystems,
icon: Icons.water_damage,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedSubakSystem = value;
});
}
},
),
],
);
case 'Maluku & Papua':
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Pulau Maluku & Papua'),
_buildDropdown(
label: 'Sistem Kebun',
value: _selectedGardenSystem,
items: _gardenSystems,
icon: Icons.forest,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedGardenSystem = value;
});
}
},
),
_buildDropdown(
label: 'Tipe Hutan',
value: _selectedForestType,
items: _forestTypes,
icon: Icons.park,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedForestType = value;
});
}
},
),
],
);
case 'Lainnya':
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildSectionTitle('Informasi Wilayah Kustom'),
_buildTextField(
label: 'Nama Wilayah',
controller: _customRegionController,
icon: Icons.location_city,
focusNode: _customRegionFocus,
validator: (value) {
if (_selectedRegion == 'Lainnya' &&
(value == null || value.isEmpty)) {
return 'Nama wilayah harus diisi';
}
return null;
},
),
_buildTextField(
label: 'Sistem Pengelolaan Lahan',
controller: _customSystemTypeController,
icon: Icons.agriculture,
focusNode: _customSystemTypeFocus,
validator: (value) {
if (_selectedRegion == 'Lainnya' &&
(value == null || value.isEmpty)) {
return 'Sistem pengelolaan lahan harus diisi';
}
return null;
},
),
_buildTextField(
label: 'Fitur Khusus Lahan',
controller: _customLandFeatureController,
icon: Icons.landscape,
focusNode: _customLandFeatureFocus,
),
],
);
default:
return Container();
}
}
// Modifikasi metode _buildTextField untuk lokasi agar menggunakan tombol pilih lokasi
Widget _buildLocationField() {
return Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Lokasi',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.grey[700],
),
),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: TextFormField(
controller: _locationController,
focusNode: _locationFocus,
readOnly: true,
decoration: InputDecoration(
hintText: 'Pilih lokasi di peta',
prefixIcon: const Icon(Icons.location_on),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 14,
),
),
),
),
const SizedBox(width: 8),
ElevatedButton(
onPressed: _isLoading ? null : _showLocationPicker,
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primary,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.all(12),
),
child: const Icon(Icons.map),
),
],
),
if (_latitude != null && _longitude != null)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
'Koordinat: ${_latitude!.toStringAsFixed(6)}, ${_longitude!.toStringAsFixed(6)}',
style: TextStyle(color: Colors.grey[600], fontSize: 12),
),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.9,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
),
child: Column(
children: [
_buildHeader(),
Expanded(
child: Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Informasi Dasar
_buildSectionTitle('Informasi Dasar'),
_buildTextField(
label: 'Nama Lahan',
controller: _nameController,
icon: Icons.agriculture,
focusNode: _fieldNameFocus,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Nama lahan wajib diisi';
}
return null;
},
hintText: 'Contoh: Lahan Cabai',
),
_buildDropdown(
label: 'Wilayah',
value: _selectedRegion,
items: _regions,
icon: Icons.map,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedRegion = value;
});
}
},
),
// Ganti TextField lokasi dengan custom widget
_buildLocationField(),
_buildTextField(
label: 'Jumlah Petak',
controller: _plotCountController,
icon: Icons.grid_4x4,
focusNode: _plotCountFocus,
keyboardType: TextInputType.number,
validator: (value) {
if (value == null || value.isEmpty) {
return 'Jumlah petak wajib diisi';
}
if (int.tryParse(value) == null ||
int.parse(value) < 1) {
return 'Jumlah petak harus berupa angka positif';
}
return null;
},
),
_buildTextField(
label: 'Luas Lahan (m²)',
controller: _areaSizeController,
icon: Icons.straighten,
focusNode: _areaSizeFocus,
keyboardType: TextInputType.number,
validator: (value) {
if (value != null && value.isNotEmpty) {
if (double.tryParse(value) == null) {
return 'Luas lahan harus berupa angka';
}
}
return null;
},
hintText: 'Contoh: 1000',
),
// Kepemilikan
_buildSectionTitle('Informasi Kepemilikan'),
_buildDropdown(
label: 'Jenis Kepemilikan',
value: _selectedOwnershipType,
items: _ownershipTypes,
icon: Icons.person,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedOwnershipType = value;
});
}
},
),
if (_selectedOwnershipType != 'Milik Sendiri')
_buildTextField(
label: 'Nama Pemilik',
controller: _ownerNameController,
icon: Icons.person_outline,
focusNode: _ownerNameFocus,
validator: (value) {
if (_selectedOwnershipType != 'Milik Sendiri' &&
(value == null || value.isEmpty)) {
return 'Nama pemilik wajib diisi';
}
return null;
},
),
// Karakteristik Lahan
_buildSectionTitle('Karakteristik Lahan'),
_buildDropdown(
label: 'Topografi',
value: _selectedTopography,
items: _topographies,
icon: Icons.terrain,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedTopography = value;
});
}
},
),
_buildDropdown(
label: 'Kemiringan Lahan',
value: _selectedSlope,
items: _slopes,
icon: Icons.line_axis,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedSlope = value;
});
}
},
),
_buildDropdown(
label: 'Jenis Tanah',
value: _selectedSoilType,
items: _soilTypes,
icon: Icons.layers,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedSoilType = value;
});
}
},
),
_buildDropdown(
label: 'Sumber Air',
value: _selectedWaterSource,
items: _waterSources,
icon: Icons.water,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedWaterSource = value;
});
}
},
),
_buildDropdown(
label: 'Jenis Irigasi',
value: _selectedIrrigationType,
items: _irrigationTypes,
icon: Icons.water_drop,
onChanged: (value) {
if (value != null) {
setState(() {
_selectedIrrigationType = value;
});
}
},
),
_buildTextField(
label: 'Tanaman Sebelumnya',
controller: _previousCropController,
icon: Icons.history,
focusNode: _previousCropFocus,
hintText: 'Contoh: Padi, Jagung',
),
// Region-specific fields
_buildRegionSpecificFields(),
// Buttons
const SizedBox(height: 24),
Row(
children: [
Expanded(
child: OutlinedButton(
onPressed:
_isLoading
? null
: () => Navigator.pop(context),
style: OutlinedButton.styleFrom(
padding: const EdgeInsets.symmetric(
vertical: 12,
),
side: BorderSide(color: Colors.grey.shade400),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child: Text(
'Batal',
style: TextStyle(color: Colors.grey.shade700),
),
),
),
const SizedBox(width: 16),
Expanded(
child: ElevatedButton(
onPressed: _isLoading ? null : _submit,
style: ElevatedButton.styleFrom(
backgroundColor: const Color.fromARGB(
255,
0,
69,
1,
),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
vertical: 12,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
child:
_isLoading
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
color: Colors.white,
strokeWidth: 2,
),
)
: Text(
_isEditMode
? 'Simpan Perubahan'
: 'Tambah Lahan',
),
),
),
],
),
const SizedBox(height: 16),
],
),
),
),
),
),
],
),
);
}
}
// Helper method to show the bottom sheet
Future<void> showAddFieldBottomSheet({
required BuildContext context,
Function? onFieldAdded,
}) async {
await showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (context) => AddFieldBottomSheet(onFieldAdded: onFieldAdded),
);
}