MIF_E31222596/website/lib/screens/features/pembayaran_screen.dart

247 lines
10 KiB
Dart

import 'package:flutter/material.dart';
import 'package:dio/dio.dart';
import 'package:monitoring/config.dart';
// import halaman tambah pembayaran jika ada
import 'tambah_pembayaran_screen.dart';
class Pembayaran {
final int id;
final int santriId;
final int? kelasId;
final String tanggal;
final int jumlah;
final String jenis;
final String? keterangan;
final String? bukti;
final String status;
final String? santriName;
Pembayaran({
required this.id,
required this.santriId,
this.kelasId,
required this.tanggal,
required this.jumlah,
required this.jenis,
this.keterangan,
this.bukti,
required this.status,
this.santriName,
});
factory Pembayaran.fromJson(Map<String, dynamic> json) {
return Pembayaran(
id: json['id'],
santriId: json['santri_id'],
kelasId: json['kelas_id'],
tanggal: json['tanggal'],
jumlah: json['jumlah'],
jenis: json['jenis_pembayaran'],
keterangan: json['keterangan'],
bukti: json['bukti_pembayaran'],
status: json['status'],
santriName: json['santri_name'],
);
}
}
class PembayaranScreen extends StatefulWidget {
final String token;
const PembayaranScreen({super.key, required this.token});
@override
State<PembayaranScreen> createState() => _PembayaranScreenState();
}
class _PembayaranScreenState extends State<PembayaranScreen> {
List<Pembayaran> pembayaranList = [];
bool loading = true;
@override
void initState() {
super.initState();
fetchPembayaran();
}
Future<void> fetchPembayaran() async {
try {
final dio = Dio(
BaseOptions(
baseUrl: '$baseUrl',
headers: {
'Accept': 'application/json',
'Authorization': 'Bearer ${widget.token}',
},
),
);
final response = await dio.get('/pembayaran');
final data = response.data as List;
setState(() {
pembayaranList = data.map((e) => Pembayaran.fromJson(e)).toList();
loading = false;
});
} catch (e) {
debugPrint('Error fetch pembayaran: $e');
setState(() => loading = false);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Data Pembayaran')),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => TambahPembayaranScreen(token: widget.token),
),
).then((_) => fetchPembayaran()); // refresh setelah kembali
},
backgroundColor: Colors.teal,
child: const Icon(Icons.add),
),
body:
loading
? const Center(child: CircularProgressIndicator())
: pembayaranList.isEmpty
? const Center(child: Text('Belum ada data pembayaran'))
: ListView.builder(
padding: const EdgeInsets.all(12),
itemCount: pembayaranList.length,
itemBuilder: (context, index) {
final bayar = pembayaranList[index];
return Card(
elevation: 2,
margin: const EdgeInsets.only(bottom: 12),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
bayar.jenis,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
const SizedBox(height: 4),
Text('Tanggal: ${bayar.tanggal}'),
Text('Jumlah: Rp${bayar.jumlah}'),
if (bayar.keterangan != null)
Text('Keterangan: ${bayar.keterangan}'),
Text('Status: ${bayar.status}'),
if (bayar.bukti != null)
Padding(
padding: const EdgeInsets.only(top: 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Bukti Pembayaran:',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 8),
if (bayar.bukti != null)
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: () {
showDialog(
context: context,
builder:
(_) => AlertDialog(
title: const Text(
'Bukti Pembayaran',
),
content: ClipRRect(
borderRadius:
BorderRadius.circular(
8,
),
child: Image.network(
bayar.bukti!,
fit: BoxFit.cover,
errorBuilder:
(
context,
error,
stackTrace,
) => const Text(
'Gagal memuat gambar',
style: TextStyle(
color: Colors.red,
),
),
loadingBuilder: (
context,
child,
loadingProgress,
) {
if (loadingProgress ==
null)
return child;
return const SizedBox(
height: 100,
child: Center(
child:
CircularProgressIndicator(),
),
);
},
),
),
actions: [
TextButton(
onPressed:
() => Navigator.pop(
context,
),
child: const Text(
'Tutup',
),
),
],
),
);
},
icon: const Icon(
Icons.image,
color: Colors.white,
),
label: const Text(
'Lihat Bukti Pembayaran',
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.teal,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 10,
),
),
),
),
],
),
),
],
),
),
);
},
),
);
}
}