modified function create hama in backend controller

This commit is contained in:
unknown 2025-06-11 00:30:41 +07:00
parent 151a3f055a
commit 213eb6273c
6 changed files with 56 additions and 44 deletions

View File

@ -54,20 +54,26 @@ exports.createHama = async (req, res) => {
const { nama, deskripsi, penanganan, nilai_pakar } = req.body; 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']] }); const lastHama = await Hama.findOne({ order: [['id', 'DESC']] });
let newKode = 'H01'; // Default kode awal let newKode = 'H01';
if (lastHama) { if (lastHama) {
const lastNumber = parseInt(lastHama.kode.substring(1)) + 1; const lastNumber = parseInt(lastHama.kode.substring(1)) + 1;
newKode = `H${lastNumber.toString().padStart(2, '0')}`; newKode = `H${lastNumber.toString().padStart(2, '0')}`;
} }
// Cek kalau ada file yang diupload // Tangani upload file
let fotoPath = ''; let fotoPath = '';
if (file) { 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({ const newHama = await Hama.create({
kode: newKode, kode: newKode,
nama, nama,
@ -75,7 +81,7 @@ exports.createHama = async (req, res) => {
deskripsi, deskripsi,
penanganan, penanganan,
foto: fotoPath, foto: fotoPath,
nilai_pakar nilai_pakar: nilaiPakar
}); });
res.status(201).json({ message: 'Hama berhasil ditambahkan', data: newHama }); 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 // 🔹 Fungsi untuk mengupdate hama berdasarkan ID
exports.updateHama = async (req, res) => { exports.updateHama = async (req, res) => {
try { try {

View File

@ -38,31 +38,36 @@ class _TambahHamaPageState extends State<TambahHamaPage> {
} }
Future<void> _simpanHama() async { Future<void> _simpanHama() async {
if (namaController.text.isNotEmpty && if (namaController.text.isNotEmpty &&
deskripsiController.text.isNotEmpty && deskripsiController.text.isNotEmpty &&
penangananController.text.isNotEmpty && penangananController.text.isNotEmpty) {
nilaiPakarController.text.isNotEmpty) { try {
try { double? nilaipakar;
if (nilaiPakarController.text.isNotEmpty) {
String nilaiInput = nilaiPakarController.text.replaceAll(',', '.'); String nilaiInput = nilaiPakarController.text.replaceAll(',', '.');
double nilaiPakar = double.parse(nilaiInput); 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");
} }
} 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) { void _showDialog(String title, String message) {
showDialog( showDialog(
@ -142,11 +147,11 @@ class _TambahHamaPageState extends State<TambahHamaPage> {
maxLines: 3, maxLines: 3,
), ),
SizedBox(height: 15), SizedBox(height: 15),
TextField( // TextField(
controller: nilaiPakarController, // controller: nilaiPakarController,
decoration: InputDecoration(labelText: 'Nilai Pakar'), // decoration: InputDecoration(labelText: 'Nilai Pakar'),
maxLines: 3, // maxLines: 3,
), // ),
SizedBox(height: 15), SizedBox(height: 15),
Text('Foto'), Text('Foto'),
(_webImage != null) (_webImage != null)

View File

@ -596,7 +596,7 @@ Future<List<Map<String, dynamic>>> getAllHistori() async {
String deskripsi, String deskripsi,
String penanganan, String penanganan,
XFile? pickedFile, XFile? pickedFile,
double nilai_pakar double? nilai_pakar
) async { ) async {
try { try {
var uri = Uri.parse(hamaUrl); var uri = Uri.parse(hamaUrl);

View File

@ -57,10 +57,10 @@ class _DiagnosaPageState extends State<DiagnosaPage> {
void prosesHasilDiagnosa() async { void prosesHasilDiagnosa() async {
// Validasi minimal 3 gejala // Validasi minimal 3 gejala
if (gejalaTerpilihIds.length < 3) { if (gejalaTerpilihIds.length < 2) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text('Silakan pilih minimal 3 gejala untuk melakukan diagnosa'), content: Text('Silakan pilih minimal 2 gejala untuk melakukan diagnosa'),
backgroundColor: Color(0xFF9DC08D), backgroundColor: Color(0xFF9DC08D),
duration: Duration(seconds: 3), duration: Duration(seconds: 3),
), ),
@ -194,7 +194,7 @@ class _DiagnosaPageState extends State<DiagnosaPage> {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
), ),
child: Text( child: Text(
"${gejalaTerpilihIds.length}/min 3", "${gejalaTerpilihIds.length}/min 2",
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 12, fontSize: 12,
@ -227,16 +227,16 @@ class _DiagnosaPageState extends State<DiagnosaPage> {
height: 30, height: 30,
child: ElevatedButton( child: ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: gejalaTerpilihIds.length >= 3 ? Colors.green : Colors.grey, backgroundColor: gejalaTerpilihIds.length >= 2 ? Colors.green : Colors.grey,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15), borderRadius: BorderRadius.circular(15),
), ),
), ),
onPressed: gejalaTerpilihIds.length >= 3 ? prosesHasilDiagnosa : null, onPressed: gejalaTerpilihIds.length >= 2 ? prosesHasilDiagnosa : null,
child: Text( child: Text(
gejalaTerpilihIds.length >= 3 gejalaTerpilihIds.length >= 2
? "Lihat Hasil Diagnosa" ? "Lihat Hasil Diagnosa"
: "Pilih minimal 3 gejala", : "Pilih minimal 2 gejala",
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 16, fontSize: 16,

View File

@ -913,7 +913,7 @@ class _HasilDiagnosaPageState extends State<HasilDiagnosaPage> {
), ),
child: Center( child: Center(
child: Text( child: Text(
'${(probabilitas * 100).toStringAsFixed(0)}%', '${(probabilitas * 100).toStringAsFixed(1)}%',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

View File

@ -29,7 +29,7 @@ class _HomePageState extends State<HomePage> {
void _startAutoLogoutTimer() { void _startAutoLogoutTimer() {
_logoutTimer?.cancel(); // Pastikan timer sebelumnya di-cancel _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 // Hapus semua data login
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
await prefs.clear(); await prefs.clear();