import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; import 'edit_pemeriksaan_kehamilan.dart'; class RiwayatPemeriksaanKehamilanPage extends StatefulWidget { final String ibuHamilId; final String nama; const RiwayatPemeriksaanKehamilanPage({ super.key, required this.ibuHamilId, required this.nama, }); @override State createState() => _RiwayatPemeriksaanKehamilanPageState(); } class _RiwayatPemeriksaanKehamilanPageState extends State { List> _data = []; List> _dataFilter = []; bool _loading = true; final TextEditingController searchController = TextEditingController(); int _currentPage = 0; final int _rowsPerPage = 5; String _formatTanggalIndo(String? tanggal) { if (tanggal == null || tanggal.isEmpty) 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(); fetchRiwayat(); } Future fetchRiwayat() async { setState(() => _loading = true); final url = Uri.parse( "http://ta.myhost.id/E31230549/mposyandu_api/pemeriksaan_kehamilan/get_riwayat_pemeriksaan.php?ibu_hamil_id=${widget.ibuHamilId}"); try { final response = await http.get(url); if (response.statusCode == 200) { final jsonData = json.decode(response.body); if (jsonData["success"] == true) { List> data = List>.from(jsonData["data"]); data.sort((a, b) { DateTime dateA = DateTime.tryParse(a['tanggal_pemeriksaan'] ?? '') ?? DateTime(1900); DateTime dateB = DateTime.tryParse(b['tanggal_pemeriksaan'] ?? '') ?? DateTime(1900); return dateB.compareTo(dateA); }); setState(() { _data = data; _dataFilter = data; }); } } } catch (e) { debugPrint(e.toString()); } setState(() => _loading = false); } void _filterData(String keyword) { final key = keyword.toLowerCase(); setState(() { _dataFilter = _data.where((item) { return item['tanggal_pemeriksaan'] .toString() .toLowerCase() .contains(key) || item['keluhan'].toString().toLowerCase().contains(key) || item['tindakan'].toString().toLowerCase().contains(key); }).toList(); _currentPage = 0; }); } List> get _paginatedData { if (_dataFilter.isEmpty) return []; final start = _currentPage * _rowsPerPage; final end = start + _rowsPerPage; if (start >= _dataFilter.length) return []; return _dataFilter.sublist( start, end > _dataFilter.length ? _dataFilter.length : end); } Future hapusData(String id) async { final confirm = await showDialog( context: context, builder: (context) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)), title: Text("Konfirmasi", style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.bold)), content: Text("Yakin ingin menghapus data ini?", style: GoogleFonts.poppins(fontSize: 12)), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: Text("Batal", style: GoogleFonts.poppins(fontSize: 12, color: Colors.grey))), TextButton( onPressed: () => Navigator.pop(context, true), child: Text("Hapus", style: GoogleFonts.poppins(fontSize: 12, color: Colors.red))), ], ), ); if (confirm != true) return; final url = Uri.parse( "http://ta.myhost.id/E31230549/mposyandu_api/pemeriksaan_kehamilan/hapus_pemeriksaan.php"); try { final response = await http.post(url, body: {"id": id}); final result = json.decode(response.body); if (result["success"] == true) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text("Data berhasil dihapus", style: GoogleFonts.poppins(fontSize: 12))), ); fetchRiwayat(); } } catch (e) { debugPrint(e.toString()); } } @override Widget build(BuildContext context) { final totalPages = _dataFilter.isEmpty ? 1 : (_dataFilter.length / _rowsPerPage).ceil(); return Scaffold( backgroundColor: const Color(0xFFFDFDFD), appBar: AppBar( backgroundColor: Colors.blueAccent, elevation: 0, leading: IconButton( icon: const Icon(Icons.arrow_back, color: Colors.white), onPressed: () => Navigator.pop(context, true), ), ), body: _loading ? const Center(child: CircularProgressIndicator()) : Column( children: [ Padding( padding: const EdgeInsets.only(top: 20, bottom: 12), child: Center( child: Text( "Riwayat Pemeriksaan Kehamilan", style: GoogleFonts.poppins( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.black, ), ), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 20), child: TextField( controller: searchController, onChanged: _filterData, style: GoogleFonts.poppins(fontSize: 12), decoration: InputDecoration( hintText: "Cari berdasarkan tanggal, keluhan...", hintStyle: GoogleFonts.poppins(fontSize: 12, color: Colors.grey), prefixIcon: const Icon(Icons.search, size: 20, color: Colors.grey), contentPadding: const EdgeInsets.symmetric(vertical: 10), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: const BorderSide(color: Colors.grey), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: const BorderSide(color: Colors.grey), ), ), ), ), const SizedBox(height: 15), Expanded( child: _dataFilter.isEmpty ? Center( child: Text("Tidak ada riwayat pemeriksaan", style: GoogleFonts.poppins( fontSize: 12, color: Colors.grey))) : ListView.builder( itemCount: _paginatedData.length, itemBuilder: (context, index) { final data = _paginatedData[index]; return _buildCard(data); }, ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("Halaman ${_currentPage + 1} dari $totalPages", style: GoogleFonts.poppins( fontSize: 12, color: Colors.black)), Row( children: [ IconButton( iconSize: 20, icon: const Icon(Icons.chevron_left), onPressed: _currentPage == 0 ? null : () => setState(() => _currentPage--)), IconButton( iconSize: 20, icon: const Icon(Icons.chevron_right), onPressed: _currentPage >= totalPages - 1 ? null : () => setState(() => _currentPage++)), ], ) ], ), ) ], ), ); } Widget _buildCard(Map data) { return Center( child: Container( margin: const EdgeInsets.symmetric(horizontal: 25, vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(14), border: Border.all(color: Colors.grey.shade300), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.03), blurRadius: 5, offset: const Offset(0, 2)), ], ), child: Column( children: [ Container( width: double.infinity, padding: const EdgeInsets.all(12), decoration: const BoxDecoration( color: Colors.blueAccent, borderRadius: BorderRadius.vertical(top: Radius.circular(14)), ), child: Text( widget.nama, style: GoogleFonts.poppins( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12), ), ), Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _row("Tanggal", _formatTanggalIndo(data["tanggal_pemeriksaan"])), _row( "BB Sblm Hamil", "${data["bb_sebelum_hamil"] ?? '-'} kg"), _row("Berat Badan", "${data["berat_badan"] ?? '-'} kg"), _row("Tinggi Badan", "${data["tinggi_badan"] ?? '-'} cm"), _row("LILA", "${data["LILA"] ?? '-'} cm"), _row("Status Gizi", data["status_gizi"]), _row("Tekanan Darah", data["tekanan_darah"]), _row("Tinggi Fundus", "${data["tinggi_fundus"] ?? '-'} cm"), _row("DJJ", data["denyut_jantung_janin"]), _row("HB", data["hb"]), _row("Kaki Bengkak", data["kaki_bengkak"]), _row("Keluhan", data["keluhan"]), _row("Tindakan", data["tindakan"]), const SizedBox(height: 12), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ SizedBox( height: 32, child: OutlinedButton.icon( onPressed: () async { final result = await Navigator.push( context, MaterialPageRoute( builder: (_) => EditPemeriksaanKehamilanPage( data: data, nama: widget.nama), ), ); if (result == true) fetchRiwayat(); }, icon: const Icon(Icons.edit, size: 16, color: Colors.orange), label: Text("Edit", style: GoogleFonts.poppins( fontSize: 12, color: Colors.orange, fontWeight: FontWeight.w500)), style: OutlinedButton.styleFrom( side: const BorderSide(color: Colors.orange), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20)), padding: const EdgeInsets.symmetric(horizontal: 16), ), ), ), const SizedBox(width: 8), SizedBox( height: 32, child: OutlinedButton.icon( onPressed: () => hapusData(data["id"].toString()), icon: const Icon(Icons.delete, size: 16, color: Colors.redAccent), label: Text("Hapus", style: GoogleFonts.poppins( fontSize: 12, color: Colors.redAccent, fontWeight: FontWeight.w500)), style: OutlinedButton.styleFrom( side: const BorderSide(color: Colors.redAccent), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20)), padding: const EdgeInsets.symmetric(horizontal: 16), ), ), ), ], ) ], ), ) ], ), ), ); } Widget _row(String label, dynamic value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 110, // Sedikit diperlebar agar label panjang tidak terpotong child: Text(label, style: GoogleFonts.poppins( fontSize: 11, fontWeight: FontWeight.w600)), ), Text(" : ", style: GoogleFonts.poppins(fontSize: 11)), Expanded( child: Text("${value ?? '-'}", style: GoogleFonts.poppins(fontSize: 11)), ) ], ), ); } }