343 lines
11 KiB
Dart
343 lines
11 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:http/http.dart' as http;
|
|
|
|
const String baseUrl = "http://ta.myhost.id/E31230549/mposyandu_api";
|
|
|
|
class RiwayatJadwalPosyanduPage extends StatefulWidget {
|
|
const RiwayatJadwalPosyanduPage({super.key});
|
|
|
|
@override
|
|
State<RiwayatJadwalPosyanduPage> createState() =>
|
|
_RiwayatJadwalPosyanduPageState();
|
|
}
|
|
|
|
class _RiwayatJadwalPosyanduPageState extends State<RiwayatJadwalPosyanduPage> {
|
|
List<Map<String, dynamic>> dataRiwayat = [];
|
|
List<Map<String, dynamic>> dataFilter = [];
|
|
bool isLoading = true;
|
|
final TextEditingController searchController = TextEditingController();
|
|
|
|
int _currentPage = 0;
|
|
final int _rowsPerPage = 5;
|
|
|
|
List<Map<String, dynamic>> 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
|
|
void initState() {
|
|
super.initState();
|
|
loadRiwayat();
|
|
}
|
|
|
|
Future<void> loadRiwayat() async {
|
|
try {
|
|
final res = await http.get(
|
|
Uri.parse("$baseUrl/jadwal_posyandu/get_all_jadwal.php"),
|
|
);
|
|
final data = jsonDecode(res.body);
|
|
if (data['success']) {
|
|
setState(() {
|
|
dataRiwayat = List<Map<String, dynamic>>.from(data['data']);
|
|
dataFilter = dataRiwayat;
|
|
isLoading = false;
|
|
});
|
|
}
|
|
} catch (e) {
|
|
debugPrint("Error riwayat : $e");
|
|
setState(() => isLoading = false);
|
|
}
|
|
}
|
|
|
|
String formatTanggal(String tanggal) {
|
|
try {
|
|
final parts = tanggal.split("-");
|
|
String tahun = parts[0];
|
|
int bulan = int.parse(parts[1]);
|
|
String hari = parts[2];
|
|
List<String> namaBulan = [
|
|
"",
|
|
"Januari",
|
|
"Februari",
|
|
"Maret",
|
|
"April",
|
|
"Mei",
|
|
"Juni",
|
|
"Juli",
|
|
"Agustus",
|
|
"September",
|
|
"Oktober",
|
|
"November",
|
|
"Desember"
|
|
];
|
|
return "$hari ${namaBulan[bulan]} $tahun";
|
|
} catch (e) {
|
|
return tanggal;
|
|
}
|
|
}
|
|
|
|
void searchData(String keyword) {
|
|
final key = keyword.toLowerCase();
|
|
setState(() {
|
|
dataFilter = dataRiwayat.where((item) {
|
|
return item['tanggal'].toString().toLowerCase().contains(key) ||
|
|
item['lokasi'].toString().toLowerCase().contains(key) ||
|
|
item['dusun'].toString().toLowerCase().contains(key);
|
|
}).toList();
|
|
_currentPage = 0;
|
|
});
|
|
}
|
|
|
|
Future<void> hapusJadwal(String id) async {
|
|
final res = await http.post(
|
|
Uri.parse("$baseUrl/jadwal_posyandu/hapus_jadwal_posyandu.php"),
|
|
body: {"id": id},
|
|
);
|
|
final data = jsonDecode(res.body);
|
|
if (data['success']) {
|
|
loadRiwayat();
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text("Jadwal berhasil dihapus",
|
|
style: GoogleFonts.poppins(fontSize: 12))),
|
|
);
|
|
}
|
|
}
|
|
|
|
void konfirmasiHapus(String id) {
|
|
showDialog(
|
|
context: context,
|
|
builder: (_) => AlertDialog(
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
|
|
title: Text("Hapus Jadwal",
|
|
style:
|
|
GoogleFonts.poppins(fontWeight: FontWeight.bold, fontSize: 14)),
|
|
content: Text("Apakah yakin ingin menghapus jadwal ini?",
|
|
style: GoogleFonts.poppins(fontSize: 12)),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.pop(context),
|
|
child: const Text("Batal", style: TextStyle(fontSize: 12))),
|
|
|
|
// Button Hapus di Dialog juga disesuaikan
|
|
OutlinedButton(
|
|
style: OutlinedButton.styleFrom(
|
|
side: const BorderSide(color: Colors.redAccent),
|
|
shape: const StadiumBorder(),
|
|
),
|
|
onPressed: () {
|
|
Navigator.pop(context);
|
|
hapusJadwal(id);
|
|
},
|
|
child: const Text("Hapus",
|
|
style: TextStyle(
|
|
color: Colors.redAccent,
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.bold)),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget rowData(String label, String value) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 2),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
SizedBox(
|
|
width: 70,
|
|
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), softWrap: true),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget cardJadwal(Map<String, dynamic> item) {
|
|
return Center(
|
|
child: Container(
|
|
margin: const EdgeInsets.symmetric(horizontal: 25, vertical: 8),
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(12),
|
|
border: Border.all(color: Colors.grey.shade300),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black.withOpacity(0.03),
|
|
blurRadius: 5,
|
|
offset: const Offset(0, 2)),
|
|
],
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
const Icon(Icons.event_note,
|
|
size: 16, color: Colors.blueAccent),
|
|
const SizedBox(width: 6),
|
|
Text("Data Jadwal Posyandu",
|
|
style: GoogleFonts.poppins(
|
|
fontWeight: FontWeight.bold, fontSize: 13)),
|
|
],
|
|
),
|
|
const Divider(height: 16, thickness: 1),
|
|
rowData("Tanggal", formatTanggal(item['tanggal'] ?? "-")),
|
|
rowData("Jam", "${item['jam_mulai']} - ${item['jam_selesai']}"),
|
|
rowData("Lokasi", item['lokasi'] ?? "-"),
|
|
rowData("Dusun", item['dusun'] ?? "-"),
|
|
rowData("Kader", item['kader'] ?? "-"),
|
|
rowData("Ket", item['keterangan'] ?? "-"),
|
|
const SizedBox(height: 8),
|
|
Align(
|
|
alignment: Alignment.centerRight,
|
|
child: SizedBox(
|
|
height: 32, // Sedikit disesuaikan untuk Outlined Style
|
|
|
|
// MENGUBAH GAYA BUTTON HAPUS DI SINI
|
|
child: OutlinedButton.icon(
|
|
onPressed: () => konfirmasiHapus(item['id'].toString()),
|
|
icon: const Icon(Icons.delete_outline,
|
|
size: 14, color: Colors.redAccent),
|
|
label: Text("Hapus",
|
|
style: GoogleFonts.poppins(
|
|
color: Colors.redAccent,
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.bold)),
|
|
style: OutlinedButton.styleFrom(
|
|
side: const BorderSide(color: Colors.redAccent),
|
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
|
shape: const StadiumBorder(), // Membuat bentuk lonjong
|
|
),
|
|
),
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
@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),
|
|
),
|
|
title: null,
|
|
),
|
|
body: Column(
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(top: 20, bottom: 12),
|
|
child: Center(
|
|
child: Text(
|
|
"Riwayat Jadwal Posyandu",
|
|
style: GoogleFonts.poppins(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.bold,
|
|
color: Colors.black,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 20),
|
|
child: TextField(
|
|
controller: searchController,
|
|
onChanged: searchData,
|
|
style: GoogleFonts.poppins(fontSize: 12),
|
|
decoration: InputDecoration(
|
|
hintText: "Cari berdasarkan tanggal, lokasi, a...",
|
|
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: isLoading
|
|
? const Center(child: CircularProgressIndicator())
|
|
: dataFilter.isEmpty
|
|
? Center(
|
|
child: Text("Data tidak ditemukan",
|
|
style: GoogleFonts.poppins(fontSize: 12)))
|
|
: ListView.builder(
|
|
itemCount: _paginatedData.length,
|
|
itemBuilder: (context, index) {
|
|
return cardJadwal(_paginatedData[index]);
|
|
},
|
|
),
|
|
),
|
|
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++),
|
|
),
|
|
],
|
|
)
|
|
],
|
|
),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|