import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; class TambahDusunPage extends StatefulWidget { const TambahDusunPage({super.key}); @override State createState() => _TambahDusunPageState(); } class _TambahDusunPageState extends State { final _namaDusun = TextEditingController(); bool _loading = false; List desaList = []; String? selectedDesaId; final String url = "http://ta.myhost.id/E31230549/mposyandu_api/dusun/tambah_dusun.php"; final String urlDesa = "http://ta.myhost.id/E31230549/mposyandu_api/desa/get_desa.php"; @override void initState() { super.initState(); _fetchDesa(); } Future _fetchDesa() async { try { final res = await http.get(Uri.parse(urlDesa)); if (!mounted) return; final data = json.decode(res.body); if (data["success"] == true) { setState(() => desaList = data["data"]); } } catch (e) { debugPrint("DESA ERROR: $e"); } } bool _isValid() { if (selectedDesaId == null) { _snack("Desa wajib dipilih"); return false; } if (_namaDusun.text.isEmpty) { _snack("Nama dusun wajib diisi"); return false; } return true; } Future _simpan() async { if (!_isValid()) return; setState(() => _loading = true); try { final res = await http.post( Uri.parse(url), headers: {"Content-Type": "application/x-www-form-urlencoded"}, body: { "desa_id": selectedDesaId!, "nama_dusun": _namaDusun.text, }, ); if (!mounted) return; // Penting untuk menghilangkan garis kuning final data = json.decode(res.body); if (data["success"] == true) { _snack("Berhasil tambah dusun"); Navigator.pop(context, true); } else { _snack(data["message"] ?? "Gagal"); } } catch (e) { if (mounted) _snack("Error koneksi"); } finally { if (mounted) setState(() => _loading = false); } } // PERBAIKAN: Menambahkan pengecekan mounted agar tidak bergaris kuning void _snack(String msg) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( msg, style: GoogleFonts.poppins(fontSize: 12), ), ), ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xfff5f6fa), appBar: AppBar( leading: const BackButton(color: Colors.white), title: Text( "", style: GoogleFonts.poppins(color: Colors.white, fontSize: 14), ), backgroundColor: Colors.blue, ), body: Center( child: SingleChildScrollView( child: Container( width: 500, margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: const [ BoxShadow(color: Colors.black12, blurRadius: 12) ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _label("Pilih Desa"), _dropdownDesa(), const SizedBox(height: 16), _label("Nama Dusun"), _input(_namaDusun), const SizedBox(height: 24), SizedBox( width: double.infinity, child: OutlinedButton( onPressed: _loading ? null : _simpan, style: OutlinedButton.styleFrom( backgroundColor: Colors.white, side: const BorderSide(color: Colors.blue, width: 1.5), padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), child: _loading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.blue), ) : Text( "Simpan", style: GoogleFonts.poppins( color: Colors.blue, fontWeight: FontWeight.bold, fontSize: 12, ), ), ), ), ], ), ), ), ), ); } Widget _label(String text) => Padding( padding: const EdgeInsets.only(bottom: 6), child: Text( text, style: GoogleFonts.poppins(fontWeight: FontWeight.w600, fontSize: 12), ), ); Widget _input(TextEditingController c) => TextField( controller: c, style: GoogleFonts.poppins(fontSize: 12), decoration: InputDecoration( hintText: "Masukkan nama dusun...", hintStyle: GoogleFonts.poppins(fontSize: 12, color: Colors.grey), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)), ), ); Widget _dropdownDesa() => DropdownButtonFormField( value: selectedDesaId, style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), items: desaList.map>((e) { return DropdownMenuItem( value: e["id"].toString(), child: Text( e["nama_desa"] ?? "", style: GoogleFonts.poppins(fontSize: 12), ), ); }).toList(), onChanged: (v) => setState(() => selectedDesaId = v), decoration: InputDecoration( hintText: "Pilih desa", hintStyle: GoogleFonts.poppins(fontSize: 12), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), border: OutlineInputBorder(borderRadius: BorderRadius.circular(10)), ), ); }