import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; import '../layout/main_layout.dart'; import 'bidan_drawer.dart'; import '../pages/login_page.dart'; import '../bidan/crud_kehamilan/tambah_pemeriksaan_kehamilan.dart'; import '../bidan/crud_kehamilan/riwayat_pemeriksaan_kehamilan.dart'; import '../bidan/dashboard_bidan.dart'; class DataPemeriksaanKehamilanPage extends StatefulWidget { const DataPemeriksaanKehamilanPage({super.key}); @override State createState() => _DataPemeriksaanKehamilanPageState(); } class _DataPemeriksaanKehamilanPageState extends State { List> _dataHamil = []; List> _allDataHamil = []; bool _loading = true; bool _checkingLogin = true; int _currentPage = 0; final int _rowsPerPage = 5; String _formatTanggalIndo(String? tanggal) { if (tanggal == null || tanggal.isEmpty || tanggal == "-" || tanggal == "0000-00-00") return "-"; try { DateTime dt = DateTime.parse(tanggal); List bulanIndo = [ "", "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember" ]; return "${dt.day.toString().padLeft(2, '0')} ${bulanIndo[dt.month]} ${dt.year}"; } catch (e) { return tanggal; } } @override void initState() { super.initState(); _checkLogin(); } Future _checkLogin() async { final prefs = await SharedPreferences.getInstance(); final isLogin = prefs.getBool('isLogin') ?? false; if (!isLogin) { if (!mounted) return; Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => const LoginPage()), ); return; } setState(() => _checkingLogin = false); _fetchDataKehamilan(); } Future _fetchDataKehamilan() async { setState(() => _loading = true); final url = Uri.parse( 'http://ta.myhost.id/E31230549/mposyandu_api/pemeriksaan_kehamilan/get_pemeriksaan_kehamilan.php', ); try { final response = await http.get(url); if (response.statusCode == 200) { final jsonData = json.decode(response.body); if (jsonData["success"] == true) { final List> data = List>.from(jsonData["data"]); // FITUR FIX: Mengurutkan list data berdasarkan nama ibu secara alfabetis A-Z data.sort((a, b) { String namaA = (a['nama'] ?? '').toString().trim().toLowerCase(); String namaB = (b['nama'] ?? '').toString().trim().toLowerCase(); return namaA.compareTo(namaB); }); setState(() { _allDataHamil = data; _dataHamil = data; _loading = false; }); } else { setState(() { _dataHamil = []; _loading = false; }); } } else { setState(() => _loading = false); } } catch (e) { debugPrint("ERROR FETCH: $e"); setState(() => _loading = false); } } // Fungsi Validasi Status bool _checkStatus(String? status) { String s = (status ?? "").toLowerCase(); if (s == "melahirkan" || s == "keguguran") { ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: Colors.red, content: Text( "Maaf ibu sudah melahirkan/keguguran", style: GoogleFonts.poppins(color: Colors.white, fontSize: 12), ), ), ); return false; } return true; } List> get _paginatedData { if (_dataHamil.isEmpty) return []; final start = _currentPage * _rowsPerPage; final end = start + _rowsPerPage; if (start >= _dataHamil.length) return []; return _dataHamil.sublist( start, end > _dataHamil.length ? _dataHamil.length : end, ); } @override Widget build(BuildContext context) { if (_checkingLogin) { return const Scaffold( body: Center(child: CircularProgressIndicator()), ); } final totalPages = _dataHamil.isEmpty ? 1 : (_dataHamil.length / _rowsPerPage).ceil(); return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) async { if (didPop) return; Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (_) => const DashboardBidanPage()), (route) => false, ); }, child: MainLayout( title: "", drawer: const BidanDrawer(), body: _loading ? const Center(child: CircularProgressIndicator()) : Padding( padding: const EdgeInsets.all(16), child: Column( children: [ Center( child: Text( "Data Pemeriksaan Kehamilan", style: GoogleFonts.poppins( fontSize: 18, fontWeight: FontWeight.w600, color: Colors.black87, ), ), ), const SizedBox(height: 12), TextField( style: GoogleFonts.poppins(fontSize: 12), decoration: InputDecoration( hintText: "Cari nama ibu...", hintStyle: GoogleFonts.poppins(fontSize: 12), prefixIcon: const Icon(Icons.search, size: 20), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), onChanged: (value) { setState(() { _dataHamil = _allDataHamil .where((b) => (b['nama'] ?? '') .toLowerCase() .contains(value.toLowerCase())) .toList(); _currentPage = 0; }); }, ), const SizedBox(height: 15), Expanded( child: _dataHamil.isEmpty ? Center( child: Text( "Tidak ada data pemeriksaan", style: GoogleFonts.poppins(fontSize: 12), ), ) : ListView.builder( itemCount: _paginatedData.length, itemBuilder: (context, index) { final ibu = _paginatedData[index]; String statusIbu = ibu['status_ibu_hamil'] ?? "aktif"; bool isInactive = (statusIbu.toLowerCase() == "melahirkan" || statusIbu.toLowerCase() == "keguguran"); String alamatLengkap = "Desa ${ibu['nama_desa'] ?? '-'}, Dusun ${ibu['nama_dusun'] ?? '-'}, ${ibu['alamat_detail'] ?? '-'}"; return Container( margin: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(14), boxShadow: const [ BoxShadow( color: Colors.black12, blurRadius: 8, offset: Offset(0, 4), ), ], ), child: Column( children: [ Container( width: double.infinity, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isInactive ? Colors.grey : Colors.blueAccent, borderRadius: const BorderRadius.vertical( top: Radius.circular(14), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( ibu["nama"] ?? "-", style: GoogleFonts.poppins( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 13, ), ), const SizedBox(height: 6), _rowWhite("Nama Suami", ibu["nama_suami"]), _rowWhite("Alamat", alamatLengkap), const Divider( color: Colors.white24), _rowWhite( "HPHT", _formatTanggalIndo( ibu["hpht"])), _rowWhite("Usia Kandungan", "${ibu["usia_kehamilan"] ?? '-'} Minggu"), _rowWhite("HPL", _formatTanggalIndo(ibu["hpl"])), _rowWhite("G-P-A", "${ibu["gravida"]}-${ibu["para"]}-${ibu["abortus"]}"), _rowWhite("Status Ibu", statusIbu.toUpperCase()), ], ), ), Container( width: double.infinity, padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Riwayat Pemeriksaan Terakhir", style: GoogleFonts.poppins( fontWeight: FontWeight.w600, fontSize: 13, color: Colors.black87, ), ), const Divider(), _riwayatList(ibu), const SizedBox(height: 12), Row( children: [ Expanded( child: OutlinedButton.icon( onPressed: () async { if (!_checkStatus( statusIbu)) return; final result = await Navigator.push( context, MaterialPageRoute( builder: (_) => TambahPemeriksaanKehamilanPage( ibuHamilId: ibu["id"] .toString(), nama: ibu["nama"], ), ), ); if (result == true) { _fetchDataKehamilan(); } }, icon: Icon(Icons.add, size: 16, color: isInactive ? Colors.grey : Colors.blue), label: Text("Input Data", style: GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight .bold, color: isInactive ? Colors .grey : Colors .blue)), style: OutlinedButton.styleFrom( side: BorderSide( color: isInactive ? Colors.grey : Colors.blue), shape: const StadiumBorder(), padding: const EdgeInsets .symmetric( vertical: 8)), ), ), const SizedBox(width: 8), Expanded( child: OutlinedButton.icon( onPressed: () async { if (!_checkStatus( statusIbu)) return; await Navigator.push( context, MaterialPageRoute( builder: (_) => RiwayatPemeriksaanKehamilanPage( ibuHamilId: ibu["id"] .toString(), nama: ibu["nama"], ), ), ); _fetchDataKehamilan(); }, icon: Icon(Icons.history, size: 16, color: isInactive ? Colors.grey : Colors .deepPurple), label: Text("Riwayat", style: GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight.bold, color: isInactive ? Colors.grey : Colors .deepPurple)), style: OutlinedButton.styleFrom( side: BorderSide( color: isInactive ? Colors.grey : Colors .deepPurple), shape: const StadiumBorder(), padding: const EdgeInsets .symmetric( vertical: 8)), ), ), ], ), ], ), ), ], ), ); }, ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("Halaman ${_currentPage + 1} dari $totalPages", style: GoogleFonts.poppins(fontSize: 12)), Row( children: [ IconButton( icon: const Icon(Icons.chevron_left), onPressed: _currentPage == 0 ? null : () => setState(() => _currentPage--)), IconButton( icon: const Icon(Icons.chevron_right), onPressed: _currentPage >= totalPages - 1 ? null : () => setState(() => _currentPage++)), ], ), ], ), ], ), ), ), ); } Widget _rowWhite(String label, dynamic value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 2), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 115, child: Text( label, style: GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight.w600, color: Colors.white), ), ), Text(" : ", style: GoogleFonts.poppins( color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold)), Expanded( child: Text( "${value ?? '-'}", style: GoogleFonts.poppins( fontSize: 12, color: Colors.white, fontWeight: FontWeight.w500), ), ), ], ), ); } Widget _riwayatList(Map data) { final items = { "Tgl Periksa": _formatTanggalIndo(data["tanggal_pemeriksaan"]), "BB Sblm Hamil": "${data["bb_sebelum_hamil"] ?? '-'} kg", "BB Sekarang": "${data["berat_badan"] ?? '-'} kg", "Tinggi Badan": "${data["tinggi_badan"] ?? '-'} cm", "LILA": "${data["lila_periksa"] ?? '-'} cm", "Status Gizi": data["status_gizi"], "Tekanan Darah": data["tekanan_darah"], "Tinggi Fundus": "${data["tinggi_fundus"] ?? '-'} cm", "DJJ (Jantung)": data["denyut_jantung_janin"], "HB": data["hb"], "Kaki Bengkak": data["kaki_bengkak"], "Keluhan": data["keluhan"], "Tindak Lanjut": data["tindakan"], }; return Column( children: items.entries.map((entry) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 115, child: Text( entry.key, style: GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight.w600, color: Colors.black), ), ), Text(" : ", style: GoogleFonts.poppins(fontSize: 12)), Expanded( child: Text( "${entry.value ?? '-'}", style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), ), ), ], ), ); }).toList(), ); } }