import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:http/http.dart' as http; class RiwayatPemeriksaanAncPage extends StatefulWidget { final String ibuHamilId; final String nama; const RiwayatPemeriksaanAncPage({ super.key, required this.ibuHamilId, required this.nama, }); @override State createState() => _RiwayatPemeriksaanAncPageState(); } class _RiwayatPemeriksaanAncPageState extends State { List> _data = []; List> _dataFilter = []; bool _loading = true; final TextEditingController searchController = TextEditingController(); int _currentPage = 0; final int _rowsPerPage = 5; @override void initState() { super.initState(); fetchRiwayat(); } 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; } } Future fetchRiwayat() async { setState(() => _loading = true); debugPrint("IBU HAMIL ID = ${widget.ibuHamilId}"); final url = Uri.parse( "http://ta.myhost.id/E31230549/mposyandu_api/pemeriksaan_anc/get_riwayat_pemeriksaan_anc.php?ibu_hamil_id=${widget.ibuHamilId}"); debugPrint("URL = $url"); 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); } @override Widget build(BuildContext context) { final totalPages = _dataFilter.isEmpty ? 1 : (_dataFilter.length / _rowsPerPage).ceil(); return Scaffold( backgroundColor: const Color(0xFFFDFDFD), appBar: AppBar( backgroundColor: Colors.blue, elevation: 0, leading: IconButton( icon: const Icon(Icons.arrow_back, color: Colors.white), onPressed: () => Navigator.pop(context), ), ), body: _loading ? const Center(child: CircularProgressIndicator()) : Column( children: [ /// TITLE Padding( padding: const EdgeInsets.only(top: 20, bottom: 12), child: Center( child: Text( "Riwayat Pemeriksaan ANC", style: GoogleFonts.poppins( fontSize: 18, fontWeight: FontWeight.bold, ), ), ), ), /// SEARCH 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...", prefixIcon: const Icon( Icons.search, size: 20, color: Colors.grey, ), contentPadding: const EdgeInsets.symmetric( vertical: 10, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), ), ), ), const SizedBox(height: 15), /// LIST DATA Expanded( child: _dataFilter.isEmpty ? Center( child: Text( "Tidak ada riwayat pemeriksaan ANC", style: GoogleFonts.poppins( fontSize: 12, color: Colors.grey, ), )) : ListView.builder( itemCount: _paginatedData.length, itemBuilder: (context, index) { final data = _paginatedData[index]; return _buildCard(data); }, ), ), /// PAGINATION 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, ), ), 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: [ /// HEADER CARD Container( width: double.infinity, padding: const EdgeInsets.all(12), decoration: const BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.vertical( top: Radius.circular(14), ), ), child: Text( widget.nama, style: GoogleFonts.poppins( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12, ), ), ), /// BODY Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _row("Tanggal", _formatTanggalIndo(data["tanggal_pemeriksaan"])), _row("Berat Badan", "${data["berat_badan"]} kg"), _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"]), ], ), ) ], ), ), ); } Widget _row(String label, dynamic value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 100, child: Text( label, style: GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight.w600, ), ), ), Text(" : ", style: GoogleFonts.poppins(fontSize: 12)), Expanded( child: Text( "${value ?? '-'}", style: GoogleFonts.poppins(fontSize: 12), ), ) ], ), ); } }