diff --git a/backend/controller/hamaController.js b/backend/controller/hamaController.js index 28f04fc..a2d4653 100644 --- a/backend/controller/hamaController.js +++ b/backend/controller/hamaController.js @@ -52,30 +52,36 @@ exports.getHamaById = async (req, res) => { exports.createHama = async (req, res) => { try { const { nama, deskripsi, penanganan, nilai_pakar } = req.body; - const file = req.file; + const file = req.file; - // Cek kode terakhir + // Generate kode otomatis const lastHama = await Hama.findOne({ order: [['id', 'DESC']] }); - let newKode = 'H01'; // Default kode awal + let newKode = 'H01'; if (lastHama) { const lastNumber = parseInt(lastHama.kode.substring(1)) + 1; newKode = `H${lastNumber.toString().padStart(2, '0')}`; } - // Cek kalau ada file yang diupload + // Tangani upload file let fotoPath = ''; if (file) { - fotoPath = file.filename; + fotoPath = file.filename; + } + + // Konversi nilai_pakar agar null jika kosong + let nilaiPakar = null; + if (nilai_pakar !== undefined && nilai_pakar !== '') { + nilaiPakar = parseFloat(nilai_pakar); } const newHama = await Hama.create({ kode: newKode, nama, - kategori: 'hama', + kategori: 'hama', deskripsi, penanganan, - foto: fotoPath, - nilai_pakar + foto: fotoPath, + nilai_pakar: nilaiPakar }); res.status(201).json({ message: 'Hama berhasil ditambahkan', data: newHama }); @@ -85,6 +91,7 @@ exports.createHama = async (req, res) => { }; + // 🔹 Fungsi untuk mengupdate hama berdasarkan ID exports.updateHama = async (req, res) => { try { diff --git a/frontend/lib/admin/tambah_hama_page.dart b/frontend/lib/admin/tambah_hama_page.dart index e548771..342a165 100644 --- a/frontend/lib/admin/tambah_hama_page.dart +++ b/frontend/lib/admin/tambah_hama_page.dart @@ -38,31 +38,36 @@ class _TambahHamaPageState extends State { } Future _simpanHama() async { - if (namaController.text.isNotEmpty && - deskripsiController.text.isNotEmpty && - penangananController.text.isNotEmpty && - nilaiPakarController.text.isNotEmpty) { - try { + if (namaController.text.isNotEmpty && + deskripsiController.text.isNotEmpty && + penangananController.text.isNotEmpty) { + try { + double? nilaipakar; + if (nilaiPakarController.text.isNotEmpty) { String nilaiInput = nilaiPakarController.text.replaceAll(',', '.'); - double nilaiPakar = double.parse(nilaiInput); - await apiService.createHama( - namaController.text, - deskripsiController.text, - penangananController.text, - _pickedFile, - nilaiPakar, - ); - widget.onHamaAdded(); - Navigator.pop(context); - _showDialog('Berhasil', 'Data hama berhasil ditambahkan.'); - } catch (e) { - _showDialog('Gagal', 'Gagal menambahkan data hama.'); - print("Error adding hama: $e"); + nilaipakar = double.parse(nilaiInput); } - } else { - _showDialog('Error', 'Semua field harus diisi.'); + + await apiService.createHama( + namaController.text, + deskripsiController.text, + penangananController.text, + _pickedFile, + nilaipakar, // boleh null + ); + + widget.onHamaAdded(); + Navigator.pop(context); + _showDialog('Berhasil', 'Data hama berhasil ditambahkan.'); + } catch (e) { + _showDialog('Gagal', 'Gagal menambahkan data hama.'); + print("Error adding hama: $e"); } + } else { + _showDialog('Error', 'Semua field harus diisi (kecuali nilai pakar).'); } +} + void _showDialog(String title, String message) { showDialog( @@ -142,11 +147,11 @@ class _TambahHamaPageState extends State { maxLines: 3, ), SizedBox(height: 15), - TextField( - controller: nilaiPakarController, - decoration: InputDecoration(labelText: 'Nilai Pakar'), - maxLines: 3, - ), + // TextField( + // controller: nilaiPakarController, + // decoration: InputDecoration(labelText: 'Nilai Pakar'), + // maxLines: 3, + // ), SizedBox(height: 15), Text('Foto'), (_webImage != null) diff --git a/frontend/lib/api_services/api_services.dart b/frontend/lib/api_services/api_services.dart index 5cafd23..01fcf31 100644 --- a/frontend/lib/api_services/api_services.dart +++ b/frontend/lib/api_services/api_services.dart @@ -596,7 +596,7 @@ Future>> getAllHistori() async { String deskripsi, String penanganan, XFile? pickedFile, - double nilai_pakar + double? nilai_pakar ) async { try { var uri = Uri.parse(hamaUrl); diff --git a/frontend/lib/user/diagnosa_page.dart b/frontend/lib/user/diagnosa_page.dart index 645bbf8..b0efd85 100644 --- a/frontend/lib/user/diagnosa_page.dart +++ b/frontend/lib/user/diagnosa_page.dart @@ -57,10 +57,10 @@ class _DiagnosaPageState extends State { void prosesHasilDiagnosa() async { // Validasi minimal 3 gejala - if (gejalaTerpilihIds.length < 3) { + if (gejalaTerpilihIds.length < 2) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( - content: Text('Silakan pilih minimal 3 gejala untuk melakukan diagnosa'), + content: Text('Silakan pilih minimal 2 gejala untuk melakukan diagnosa'), backgroundColor: Color(0xFF9DC08D), duration: Duration(seconds: 3), ), @@ -194,7 +194,7 @@ class _DiagnosaPageState extends State { borderRadius: BorderRadius.circular(12), ), child: Text( - "${gejalaTerpilihIds.length}/min 3", + "${gejalaTerpilihIds.length}/min 2", style: TextStyle( color: Colors.white, fontSize: 12, @@ -227,16 +227,16 @@ class _DiagnosaPageState extends State { height: 30, child: ElevatedButton( style: ElevatedButton.styleFrom( - backgroundColor: gejalaTerpilihIds.length >= 3 ? Colors.green : Colors.grey, + backgroundColor: gejalaTerpilihIds.length >= 2 ? Colors.green : Colors.grey, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), ), - onPressed: gejalaTerpilihIds.length >= 3 ? prosesHasilDiagnosa : null, + onPressed: gejalaTerpilihIds.length >= 2 ? prosesHasilDiagnosa : null, child: Text( - gejalaTerpilihIds.length >= 3 + gejalaTerpilihIds.length >= 2 ? "Lihat Hasil Diagnosa" - : "Pilih minimal 3 gejala", + : "Pilih minimal 2 gejala", style: TextStyle( color: Colors.white, fontSize: 16, diff --git a/frontend/lib/user/hasil_diagnosa_page.dart b/frontend/lib/user/hasil_diagnosa_page.dart index d798df4..ba36ae2 100644 --- a/frontend/lib/user/hasil_diagnosa_page.dart +++ b/frontend/lib/user/hasil_diagnosa_page.dart @@ -913,7 +913,7 @@ class _HasilDiagnosaPageState extends State { ), child: Center( child: Text( - '${(probabilitas * 100).toStringAsFixed(0)}%', + '${(probabilitas * 100).toStringAsFixed(1)}%', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, diff --git a/frontend/lib/user/home_page.dart b/frontend/lib/user/home_page.dart index e952886..f53e202 100644 --- a/frontend/lib/user/home_page.dart +++ b/frontend/lib/user/home_page.dart @@ -29,7 +29,7 @@ class _HomePageState extends State { void _startAutoLogoutTimer() { _logoutTimer?.cancel(); // Pastikan timer sebelumnya di-cancel - _logoutTimer = Timer(const Duration(minutes: 5), () async { + _logoutTimer = Timer(const Duration(hours: 12), () async { // Hapus semua data login final prefs = await SharedPreferences.getInstance(); await prefs.clear();