Tambahkan rute dan tampilan untuk daftar donatur
- Tambahkan tampilan DaftarDonaturView dan binding DonaturBinding - Perbarui AppPages untuk menambahkan rute ke daftar donatur - Tambahkan item menu 'Daftar Donatur' di PetugasDesaView untuk navigasi
This commit is contained in:
11
lib/app/modules/petugas_desa/bindings/donatur_binding.dart
Normal file
11
lib/app/modules/petugas_desa/bindings/donatur_binding.dart
Normal file
@ -0,0 +1,11 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/donatur_controller.dart';
|
||||
|
||||
class DonaturBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
Get.lazyPut<DonaturController>(
|
||||
() => DonaturController(),
|
||||
);
|
||||
}
|
||||
}
|
234
lib/app/modules/petugas_desa/controllers/donatur_controller.dart
Normal file
234
lib/app/modules/petugas_desa/controllers/donatur_controller.dart
Normal file
@ -0,0 +1,234 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:penyaluran_app/app/services/supabase_service.dart';
|
||||
import 'package:penyaluran_app/app/data/models/donatur_model.dart';
|
||||
import 'package:penyaluran_app/app/data/models/penitipan_bantuan_model.dart';
|
||||
|
||||
class DonaturController extends GetxController {
|
||||
final RxList<DonaturModel> daftarDonatur = <DonaturModel>[].obs;
|
||||
final RxMap<String, List<PenitipanBantuanModel>> penitipanPerDonatur =
|
||||
<String, List<PenitipanBantuanModel>>{}.obs;
|
||||
final RxBool isLoading = false.obs;
|
||||
final SupabaseService _supabaseService = SupabaseService.to;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
fetchDaftarDonatur();
|
||||
}
|
||||
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
// Pastikan data dimuat saat controller siap
|
||||
if (daftarDonatur.isEmpty) {
|
||||
fetchDaftarDonatur();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchDaftarDonatur() async {
|
||||
isLoading.value = true;
|
||||
|
||||
try {
|
||||
final result = await _supabaseService.getDaftarDonatur();
|
||||
|
||||
if (result != null) {
|
||||
// Konversi data ke model Donatur
|
||||
daftarDonatur.value =
|
||||
result.map((data) => DonaturModel.fromJson(data)).toList();
|
||||
|
||||
// Ambil data penitipan bantuan
|
||||
await fetchPenitipanBantuan();
|
||||
} else {
|
||||
// Jika result null, tampilkan daftar kosong
|
||||
daftarDonatur.value = [];
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error saat mengambil data donatur: $e');
|
||||
// Tampilkan pesan error jika diperlukan
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchPenitipanBantuan() async {
|
||||
try {
|
||||
final result = await _supabaseService.getPenitipanBantuan();
|
||||
|
||||
if (result != null) {
|
||||
// Reset map penitipan per donatur
|
||||
penitipanPerDonatur.clear();
|
||||
|
||||
// Konversi data ke model PenitipanBantuan dan kelompokkan berdasarkan donatur_id
|
||||
for (var data in result) {
|
||||
final penitipan = PenitipanBantuanModel.fromJson(data);
|
||||
if (penitipan.donaturId != null) {
|
||||
if (!penitipanPerDonatur.containsKey(penitipan.donaturId)) {
|
||||
penitipanPerDonatur[penitipan.donaturId!] = [];
|
||||
}
|
||||
penitipanPerDonatur[penitipan.donaturId]!.add(penitipan);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error saat mengambil data penitipan bantuan: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Mendapatkan jumlah donasi untuk donatur tertentu
|
||||
int getJumlahDonasi(String? donaturId) {
|
||||
if (donaturId == null || !penitipanPerDonatur.containsKey(donaturId)) {
|
||||
return 0;
|
||||
}
|
||||
return penitipanPerDonatur[donaturId]!.length;
|
||||
}
|
||||
|
||||
// Mendapatkan total nilai donasi untuk donatur tertentu
|
||||
double getTotalNilaiDonasi(String? donaturId) {
|
||||
if (donaturId == null || !penitipanPerDonatur.containsKey(donaturId)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double total = 0;
|
||||
for (var penitipan in penitipanPerDonatur[donaturId]!) {
|
||||
if (penitipan.jumlah != null) {
|
||||
// Untuk donasi uang, kita gunakan nilai jumlah langsung
|
||||
// Untuk donasi barang, kita perlu implementasi lain jika ada nilai barang
|
||||
if (penitipan.isUang == true) {
|
||||
total += penitipan.jumlah!;
|
||||
}
|
||||
// Jika ingin menambahkan nilai barang, tambahkan logika di sini
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// Mendapatkan total nilai donasi uang untuk donatur tertentu
|
||||
double getTotalNilaiDonasiUang(String? donaturId) {
|
||||
if (donaturId == null || !penitipanPerDonatur.containsKey(donaturId)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
double total = 0;
|
||||
for (var penitipan in penitipanPerDonatur[donaturId]!) {
|
||||
if (penitipan.jumlah != null && penitipan.isUang == true) {
|
||||
total += penitipan.jumlah!;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
// Mendapatkan jumlah donasi uang untuk donatur tertentu
|
||||
int getJumlahDonasiUang(String? donaturId) {
|
||||
if (donaturId == null || !penitipanPerDonatur.containsKey(donaturId)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return penitipanPerDonatur[donaturId]!
|
||||
.where((penitipan) => penitipan.isUang == true)
|
||||
.length;
|
||||
}
|
||||
|
||||
// Mendapatkan jumlah donasi barang untuk donatur tertentu
|
||||
int getJumlahDonasiBarang(String? donaturId) {
|
||||
if (donaturId == null || !penitipanPerDonatur.containsKey(donaturId)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return penitipanPerDonatur[donaturId]!
|
||||
.where((penitipan) => penitipan.isUang != true)
|
||||
.length;
|
||||
}
|
||||
|
||||
// Format nilai donasi ke format Rupiah
|
||||
String formatRupiah(double nominal) {
|
||||
return 'Rp ${nominal.toStringAsFixed(0).replaceAllMapped(RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]}.')}';
|
||||
}
|
||||
|
||||
DonaturModel? getDonaturById(String id) {
|
||||
try {
|
||||
if (daftarDonatur.isEmpty) {
|
||||
// Jika data belum dimuat, muat data terlebih dahulu
|
||||
fetchDaftarDonatur();
|
||||
return null;
|
||||
}
|
||||
return daftarDonatur.firstWhere((donatur) => donatur.id == id);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Fungsi untuk mengambil data donatur langsung dari database
|
||||
Future<DonaturModel?> fetchDonaturById(String id) async {
|
||||
try {
|
||||
final data = await _supabaseService.getDonaturById(id);
|
||||
if (data != null) {
|
||||
return DonaturModel.fromJson(data);
|
||||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
print('Error saat mengambil data donatur by ID: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Mendapatkan daftar penitipan bantuan untuk donatur tertentu
|
||||
List<PenitipanBantuanModel> getPenitipanBantuanByDonaturId(
|
||||
String? donaturId) {
|
||||
if (donaturId == null || !penitipanPerDonatur.containsKey(donaturId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Urutkan berdasarkan tanggal penitipan terbaru
|
||||
final penitipanList =
|
||||
List<PenitipanBantuanModel>.from(penitipanPerDonatur[donaturId]!);
|
||||
penitipanList.sort((a, b) {
|
||||
if (a.tanggalPenitipan == null) return 1;
|
||||
if (b.tanggalPenitipan == null) return -1;
|
||||
return b.tanggalPenitipan!.compareTo(a.tanggalPenitipan!);
|
||||
});
|
||||
|
||||
return penitipanList;
|
||||
}
|
||||
|
||||
// Mendapatkan daftar penitipan bantuan uang untuk donatur tertentu
|
||||
List<PenitipanBantuanModel> getPenitipanBantuanUangByDonaturId(
|
||||
String? donaturId) {
|
||||
if (donaturId == null || !penitipanPerDonatur.containsKey(donaturId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Filter penitipan uang dan urutkan berdasarkan tanggal penitipan terbaru
|
||||
final penitipanList = penitipanPerDonatur[donaturId]!
|
||||
.where((penitipan) => penitipan.isUang == true)
|
||||
.toList();
|
||||
|
||||
penitipanList.sort((a, b) {
|
||||
if (a.tanggalPenitipan == null) return 1;
|
||||
if (b.tanggalPenitipan == null) return -1;
|
||||
return b.tanggalPenitipan!.compareTo(a.tanggalPenitipan!);
|
||||
});
|
||||
|
||||
return penitipanList;
|
||||
}
|
||||
|
||||
// Mendapatkan daftar penitipan bantuan barang untuk donatur tertentu
|
||||
List<PenitipanBantuanModel> getPenitipanBantuanBarangByDonaturId(
|
||||
String? donaturId) {
|
||||
if (donaturId == null || !penitipanPerDonatur.containsKey(donaturId)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Filter penitipan barang dan urutkan berdasarkan tanggal penitipan terbaru
|
||||
final penitipanList = penitipanPerDonatur[donaturId]!
|
||||
.where((penitipan) => penitipan.isUang != true)
|
||||
.toList();
|
||||
|
||||
penitipanList.sort((a, b) {
|
||||
if (a.tanggalPenitipan == null) return 1;
|
||||
if (b.tanggalPenitipan == null) return -1;
|
||||
return b.tanggalPenitipan!.compareTo(a.tanggalPenitipan!);
|
||||
});
|
||||
|
||||
return penitipanList;
|
||||
}
|
||||
}
|
514
lib/app/modules/petugas_desa/views/daftar_donatur_view.dart
Normal file
514
lib/app/modules/petugas_desa/views/daftar_donatur_view.dart
Normal file
@ -0,0 +1,514 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/donatur_controller.dart';
|
||||
import 'package:penyaluran_app/app/theme/app_theme.dart';
|
||||
import 'package:penyaluran_app/app/data/models/donatur_model.dart';
|
||||
|
||||
class DaftarDonaturView extends GetView<DonaturController> {
|
||||
const DaftarDonaturView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Daftar Donatur'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.search),
|
||||
onPressed: () {
|
||||
// Implementasi pencarian
|
||||
showSearch(
|
||||
context: context,
|
||||
delegate: DonaturSearchDelegate(controller),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Obx(() {
|
||||
if (controller.isLoading.value) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
);
|
||||
}
|
||||
|
||||
if (controller.daftarDonatur.isEmpty) {
|
||||
return const Center(
|
||||
child: Text('Tidak ada data donatur'),
|
||||
);
|
||||
}
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
_buildDonaturSummary(context),
|
||||
const SizedBox(height: 16),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: controller.daftarDonatur.length,
|
||||
itemBuilder: (context, index) {
|
||||
final donatur = controller.daftarDonatur[index];
|
||||
return _buildDonaturCard(context, donatur);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
// Ringkasan daftar donatur
|
||||
Widget _buildDonaturSummary(BuildContext context) {
|
||||
// Hitung jumlah donatur berdasarkan jenis
|
||||
final jumlahPerusahaan =
|
||||
controller.daftarDonatur.where((d) => d.jenis == 'Perusahaan').length;
|
||||
final jumlahOrganisasi =
|
||||
controller.daftarDonatur.where((d) => d.jenis == 'Organisasi').length;
|
||||
final jumlahIndividu =
|
||||
controller.daftarDonatur.where((d) => d.jenis == 'Individu').length;
|
||||
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(16),
|
||||
margin: const EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
gradient: AppTheme.primaryGradient,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Ringkasan Donatur',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: _buildSummaryItem(
|
||||
context,
|
||||
icon: Icons.business,
|
||||
title: 'Perusahaan',
|
||||
value: '$jumlahPerusahaan',
|
||||
color: Colors.blue,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: _buildSummaryItem(
|
||||
context,
|
||||
icon: Icons.groups,
|
||||
title: 'Organisasi',
|
||||
value: '$jumlahOrganisasi',
|
||||
color: Colors.green,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: _buildSummaryItem(
|
||||
context,
|
||||
icon: Icons.person,
|
||||
title: 'Individu',
|
||||
value: '$jumlahIndividu',
|
||||
color: Colors.orange,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSummaryItem(
|
||||
BuildContext context, {
|
||||
required IconData icon,
|
||||
required String title,
|
||||
required String value,
|
||||
required Color color,
|
||||
}) {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white.withOpacity(0.2),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: Colors.white,
|
||||
size: 24,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
value,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Colors.white,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDonaturCard(BuildContext context, DonaturModel donatur) {
|
||||
// Pilih ikon berdasarkan jenis donatur
|
||||
IconData jenisIcon;
|
||||
switch (donatur.jenis) {
|
||||
case 'Perusahaan':
|
||||
jenisIcon = Icons.business;
|
||||
break;
|
||||
case 'Organisasi':
|
||||
jenisIcon = Icons.groups;
|
||||
break;
|
||||
case 'Individu':
|
||||
jenisIcon = Icons.person;
|
||||
break;
|
||||
default:
|
||||
jenisIcon = Icons.help_outline;
|
||||
}
|
||||
|
||||
// Hitung jumlah donasi dan total nilai donasi
|
||||
final jumlahDonasi = controller.getJumlahDonasi(donatur.id);
|
||||
final jumlahDonasiUang = controller.getJumlahDonasiUang(donatur.id);
|
||||
final jumlahDonasiBarang = controller.getJumlahDonasiBarang(donatur.id);
|
||||
final totalNilaiDonasiUang = controller.getTotalNilaiDonasiUang(donatur.id);
|
||||
final totalNilaiDonasiUangFormatted =
|
||||
controller.formatRupiah(totalNilaiDonasiUang);
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// Navigasi ke halaman detail donatur (akan diimplementasikan nanti)
|
||||
// Get.toNamed('/daftar-donatur/detail', arguments: donatur.id);
|
||||
},
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Row(
|
||||
children: [
|
||||
// Foto profil atau ikon
|
||||
CircleAvatar(
|
||||
radius: 30,
|
||||
backgroundColor: AppTheme.primaryColor.withOpacity(0.1),
|
||||
child: Icon(
|
||||
jenisIcon,
|
||||
size: 30,
|
||||
color: AppTheme.primaryColor,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
// Informasi donatur
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
donatur.nama ?? '',
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
_buildStatusBadge(donatur.status),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
jenisIcon,
|
||||
size: 14,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
donatur.jenis ?? '',
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 8),
|
||||
// Informasi donasi
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.attach_money,
|
||||
size: 14,
|
||||
color: Color.fromARGB(255, 210, 158, 4),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'${jumlahDonasiUang}x Donasi Uang',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Color.fromARGB(255, 210, 158, 4),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.inventory_2,
|
||||
size: 14,
|
||||
color: Colors.purple,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'${jumlahDonasiBarang}x Donasi Barang',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.purple,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusBadge(String? status) {
|
||||
Color backgroundColor;
|
||||
Color textColor;
|
||||
String label;
|
||||
|
||||
switch (status) {
|
||||
case 'AKTIF':
|
||||
backgroundColor = Colors.green.withOpacity(0.1);
|
||||
textColor = Colors.green;
|
||||
label = 'Aktif';
|
||||
break;
|
||||
case 'NONAKTIF':
|
||||
backgroundColor = Colors.red.withOpacity(0.1);
|
||||
textColor = Colors.red;
|
||||
label = 'Non Aktif';
|
||||
break;
|
||||
default:
|
||||
backgroundColor = Colors.grey.withOpacity(0.1);
|
||||
textColor = Colors.grey;
|
||||
label = 'Tidak diketahui';
|
||||
}
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DonaturSearchDelegate extends SearchDelegate {
|
||||
final DonaturController controller;
|
||||
|
||||
DonaturSearchDelegate(this.controller);
|
||||
|
||||
@override
|
||||
List<Widget> buildActions(BuildContext context) {
|
||||
return [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.clear),
|
||||
onPressed: () {
|
||||
query = '';
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildLeading(BuildContext context) {
|
||||
return IconButton(
|
||||
icon: const Icon(Icons.arrow_back),
|
||||
onPressed: () {
|
||||
close(context, null);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildResults(BuildContext context) {
|
||||
return _buildSearchResults();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget buildSuggestions(BuildContext context) {
|
||||
return _buildSearchResults();
|
||||
}
|
||||
|
||||
Widget _buildSearchResults() {
|
||||
final filteredList = controller.daftarDonatur.where((donatur) {
|
||||
final nama = donatur.nama?.toLowerCase() ?? '';
|
||||
final jenis = donatur.jenis?.toLowerCase() ?? '';
|
||||
final alamat = donatur.alamat?.toLowerCase() ?? '';
|
||||
final searchLower = query.toLowerCase();
|
||||
|
||||
return nama.contains(searchLower) ||
|
||||
jenis.contains(searchLower) ||
|
||||
alamat.contains(searchLower);
|
||||
}).toList();
|
||||
|
||||
if (filteredList.isEmpty) {
|
||||
return const Center(
|
||||
child: Text('Tidak ada hasil yang ditemukan'),
|
||||
);
|
||||
}
|
||||
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemCount: filteredList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final donatur = filteredList[index];
|
||||
|
||||
// Pilih ikon berdasarkan jenis donatur
|
||||
IconData jenisIcon;
|
||||
switch (donatur.jenis) {
|
||||
case 'Perusahaan':
|
||||
jenisIcon = Icons.business;
|
||||
break;
|
||||
case 'Organisasi':
|
||||
jenisIcon = Icons.groups;
|
||||
break;
|
||||
case 'Individu':
|
||||
jenisIcon = Icons.person;
|
||||
break;
|
||||
default:
|
||||
jenisIcon = Icons.help_outline;
|
||||
}
|
||||
|
||||
// Hitung jumlah donasi dan total nilai donasi
|
||||
final jumlahDonasi = controller.getJumlahDonasi(donatur.id);
|
||||
final jumlahDonasiUang = controller.getJumlahDonasiUang(donatur.id);
|
||||
final jumlahDonasiBarang = controller.getJumlahDonasiBarang(donatur.id);
|
||||
final totalNilaiDonasiUang =
|
||||
controller.getTotalNilaiDonasiUang(donatur.id);
|
||||
final totalNilaiDonasiUangFormatted =
|
||||
controller.formatRupiah(totalNilaiDonasiUang);
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(bottom: 16),
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: ListTile(
|
||||
onTap: () {
|
||||
close(context, null);
|
||||
// Get.toNamed('/daftar-donatur/detail', arguments: donatur.id);
|
||||
},
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: AppTheme.primaryColor.withOpacity(0.1),
|
||||
child: Icon(
|
||||
jenisIcon,
|
||||
color: AppTheme.primaryColor,
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
donatur.nama ?? '',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(donatur.jenis ?? ''),
|
||||
const SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.monetization_on,
|
||||
size: 12,
|
||||
color: Colors.green,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
totalNilaiDonasiUangFormatted,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.green,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
const Icon(
|
||||
Icons.volunteer_activism,
|
||||
size: 12,
|
||||
color: Colors.blue,
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
Text(
|
||||
'$jumlahDonasi Donasi',
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.blue,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
isThreeLine: true,
|
||||
trailing: donatur.status == 'AKTIF'
|
||||
? const Icon(
|
||||
Icons.verified,
|
||||
color: Colors.green,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -297,6 +297,14 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
|
||||
Get.toNamed('/daftar-penerima');
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.volunteer_activism),
|
||||
title: const Text('Daftar Donatur'),
|
||||
onTap: () {
|
||||
Navigator.pop(context); // Tutup drawer terlebih dahulu
|
||||
Get.toNamed('/daftar-donatur');
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
leading: Stack(
|
||||
alignment: Alignment.center,
|
||||
|
Reference in New Issue
Block a user