Tambahkan CounterService untuk manajemen counter di seluruh modul
- Buat CounterService untuk mengelola counter di berbagai controller - Refaktor PetugasDesaController dan PenitipanBantuanController untuk menggunakan CounterService - Perbarui binding untuk mendaftarkan CounterService - Tambahkan metode update untuk berbagai jenis counter - Sederhanakan manajemen state dengan menggunakan layanan pusat
This commit is contained in:
@ -8,6 +8,7 @@ import 'package:penyaluran_app/app/modules/petugas_desa/controllers/pengaduan_co
|
|||||||
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/penerima_bantuan_controller.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/penerima_bantuan_controller.dart';
|
||||||
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/laporan_controller.dart';
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/laporan_controller.dart';
|
||||||
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/counter_service.dart';
|
||||||
|
|
||||||
class PetugasDesaBinding extends Bindings {
|
class PetugasDesaBinding extends Bindings {
|
||||||
@override
|
@override
|
||||||
@ -17,6 +18,11 @@ class PetugasDesaBinding extends Bindings {
|
|||||||
Get.put(AuthController(), permanent: true);
|
Get.put(AuthController(), permanent: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Daftarkan CounterService terlebih dahulu
|
||||||
|
if (!Get.isRegistered<CounterService>()) {
|
||||||
|
Get.put(CounterService(), permanent: true);
|
||||||
|
}
|
||||||
|
|
||||||
// Main controller - gunakan put dengan permanent untuk controller utama
|
// Main controller - gunakan put dengan permanent untuk controller utama
|
||||||
if (!Get.isRegistered<PetugasDesaController>()) {
|
if (!Get.isRegistered<PetugasDesaController>()) {
|
||||||
Get.put(PetugasDesaController(), permanent: true);
|
Get.put(PetugasDesaController(), permanent: true);
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
/// Service untuk berbagi data counter antar controller
|
||||||
|
class CounterService extends GetxService {
|
||||||
|
static CounterService get to => Get.find<CounterService>();
|
||||||
|
|
||||||
|
// Counter untuk penitipan
|
||||||
|
final RxInt jumlahMenunggu = 0.obs;
|
||||||
|
final RxInt jumlahTerverifikasi = 0.obs;
|
||||||
|
final RxInt jumlahDitolak = 0.obs;
|
||||||
|
|
||||||
|
// Counter untuk pengaduan
|
||||||
|
final RxInt jumlahDiproses = 0.obs;
|
||||||
|
|
||||||
|
// Counter untuk notifikasi
|
||||||
|
final RxInt jumlahNotifikasiBelumDibaca = 0.obs;
|
||||||
|
|
||||||
|
// Counter untuk jadwal
|
||||||
|
final RxInt jumlahJadwalHariIni = 0.obs;
|
||||||
|
|
||||||
|
// Metode untuk memperbarui counter penitipan
|
||||||
|
void updatePenitipanCounters({
|
||||||
|
required int menunggu,
|
||||||
|
required int terverifikasi,
|
||||||
|
required int ditolak,
|
||||||
|
}) {
|
||||||
|
jumlahMenunggu.value = menunggu;
|
||||||
|
jumlahTerverifikasi.value = terverifikasi;
|
||||||
|
jumlahDitolak.value = ditolak;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metode untuk memperbarui counter pengaduan
|
||||||
|
void updatePengaduanCounter(int diproses) {
|
||||||
|
jumlahDiproses.value = diproses;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metode untuk memperbarui counter notifikasi
|
||||||
|
void updateNotifikasiCounter(int belumDibaca) {
|
||||||
|
jumlahNotifikasiBelumDibaca.value = belumDibaca;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metode untuk memperbarui counter jadwal
|
||||||
|
void updateJadwalCounter(int hariIni) {
|
||||||
|
jumlahJadwalHariIni.value = hariIni;
|
||||||
|
}
|
||||||
|
}
|
@ -3,16 +3,17 @@ import 'package:get/get.dart';
|
|||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:penyaluran_app/app/data/models/penitipan_bantuan_model.dart';
|
import 'package:penyaluran_app/app/data/models/penitipan_bantuan_model.dart';
|
||||||
import 'package:penyaluran_app/app/data/models/donatur_model.dart';
|
import 'package:penyaluran_app/app/data/models/donatur_model.dart';
|
||||||
import 'package:penyaluran_app/app/data/models/kategori_bantuan_model.dart';
|
|
||||||
import 'package:penyaluran_app/app/data/models/stok_bantuan_model.dart';
|
import 'package:penyaluran_app/app/data/models/stok_bantuan_model.dart';
|
||||||
import 'package:penyaluran_app/app/data/models/user_model.dart';
|
import 'package:penyaluran_app/app/data/models/user_model.dart';
|
||||||
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/counter_service.dart';
|
||||||
import 'package:penyaluran_app/app/services/supabase_service.dart';
|
import 'package:penyaluran_app/app/services/supabase_service.dart';
|
||||||
|
|
||||||
class PenitipanBantuanController extends GetxController {
|
class PenitipanBantuanController extends GetxController {
|
||||||
final AuthController _authController = Get.find<AuthController>();
|
final AuthController _authController = Get.find<AuthController>();
|
||||||
final SupabaseService _supabaseService = SupabaseService.to;
|
final SupabaseService _supabaseService = SupabaseService.to;
|
||||||
final ImagePicker _imagePicker = ImagePicker();
|
final ImagePicker _imagePicker = ImagePicker();
|
||||||
|
late final CounterService _counterService;
|
||||||
|
|
||||||
final RxBool isLoading = false.obs;
|
final RxBool isLoading = false.obs;
|
||||||
final RxBool isUploading = false.obs;
|
final RxBool isUploading = false.obs;
|
||||||
@ -26,9 +27,6 @@ class PenitipanBantuanController extends GetxController {
|
|||||||
// Data untuk penitipan
|
// Data untuk penitipan
|
||||||
final RxList<PenitipanBantuanModel> daftarPenitipan =
|
final RxList<PenitipanBantuanModel> daftarPenitipan =
|
||||||
<PenitipanBantuanModel>[].obs;
|
<PenitipanBantuanModel>[].obs;
|
||||||
final RxInt jumlahMenunggu = 0.obs;
|
|
||||||
final RxInt jumlahTerverifikasi = 0.obs;
|
|
||||||
final RxInt jumlahDitolak = 0.obs;
|
|
||||||
|
|
||||||
// Data untuk kategori bantuan
|
// Data untuk kategori bantuan
|
||||||
final RxMap<String, StokBantuanModel> stokBantuanMap =
|
final RxMap<String, StokBantuanModel> stokBantuanMap =
|
||||||
@ -46,9 +44,21 @@ class PenitipanBantuanController extends GetxController {
|
|||||||
|
|
||||||
UserModel? get user => _authController.user;
|
UserModel? get user => _authController.user;
|
||||||
|
|
||||||
|
// Getter untuk counter dari CounterService
|
||||||
|
RxInt get jumlahMenunggu => _counterService.jumlahMenunggu;
|
||||||
|
RxInt get jumlahTerverifikasi => _counterService.jumlahTerverifikasi;
|
||||||
|
RxInt get jumlahDitolak => _counterService.jumlahDitolak;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
|
||||||
|
// Inisialisasi CounterService jika belum ada
|
||||||
|
if (!Get.isRegistered<CounterService>()) {
|
||||||
|
Get.put(CounterService(), permanent: true);
|
||||||
|
}
|
||||||
|
_counterService = Get.find<CounterService>();
|
||||||
|
|
||||||
loadPenitipanData();
|
loadPenitipanData();
|
||||||
loadKategoriBantuanData();
|
loadKategoriBantuanData();
|
||||||
// Tambahkan delay untuk memastikan data petugas desa dimuat setelah penitipan
|
// Tambahkan delay untuk memastikan data petugas desa dimuat setelah penitipan
|
||||||
@ -73,14 +83,21 @@ class PenitipanBantuanController extends GetxController {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
// Hitung jumlah berdasarkan status
|
// Hitung jumlah berdasarkan status
|
||||||
jumlahMenunggu.value =
|
int menunggu =
|
||||||
daftarPenitipan.where((item) => item.status == 'MENUNGGU').length;
|
daftarPenitipan.where((item) => item.status == 'MENUNGGU').length;
|
||||||
jumlahTerverifikasi.value = daftarPenitipan
|
int terverifikasi = daftarPenitipan
|
||||||
.where((item) => item.status == 'TERVERIFIKASI')
|
.where((item) => item.status == 'TERVERIFIKASI')
|
||||||
.length;
|
.length;
|
||||||
jumlahDitolak.value =
|
int ditolak =
|
||||||
daftarPenitipan.where((item) => item.status == 'DITOLAK').length;
|
daftarPenitipan.where((item) => item.status == 'DITOLAK').length;
|
||||||
|
|
||||||
|
// Update counter di CounterService
|
||||||
|
_counterService.updatePenitipanCounters(
|
||||||
|
menunggu: menunggu,
|
||||||
|
terverifikasi: terverifikasi,
|
||||||
|
ditolak: ditolak,
|
||||||
|
);
|
||||||
|
|
||||||
// Muat informasi petugas desa untuk item yang terverifikasi
|
// Muat informasi petugas desa untuk item yang terverifikasi
|
||||||
print(
|
print(
|
||||||
'Memuat informasi petugas desa untuk ${daftarPenitipan.length} penitipan');
|
'Memuat informasi petugas desa untuk ${daftarPenitipan.length} penitipan');
|
||||||
@ -351,10 +368,32 @@ class PenitipanBantuanController extends GetxController {
|
|||||||
final stokBantuan = getKategoriNama(item.stokBantuanId).toLowerCase();
|
final stokBantuan = getKategoriNama(item.stokBantuanId).toLowerCase();
|
||||||
final stokBantuanMatch = stokBantuan.contains(searchText);
|
final stokBantuanMatch = stokBantuan.contains(searchText);
|
||||||
|
|
||||||
return deskripsiMatch || stokBantuanMatch;
|
// Cari berdasarkan nama donatur
|
||||||
|
final donaturId = item.donaturId;
|
||||||
|
String donaturNama = '';
|
||||||
|
if (donaturId != null && donaturCache.containsKey(donaturId)) {
|
||||||
|
donaturNama = donaturCache[donaturId]?.nama?.toLowerCase() ?? '';
|
||||||
|
}
|
||||||
|
final donaturMatch = donaturNama.contains(searchText);
|
||||||
|
|
||||||
|
// Cari berdasarkan tanggal penitipan
|
||||||
|
final tanggalMatch = item.tanggalPenitipan != null &&
|
||||||
|
item.tanggalPenitipan.toString().toLowerCase().contains(searchText);
|
||||||
|
|
||||||
|
return deskripsiMatch ||
|
||||||
|
stokBantuanMatch ||
|
||||||
|
donaturMatch ||
|
||||||
|
tanggalMatch;
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Urutkan berdasarkan tanggal terbaru
|
||||||
|
filteredList.sort((a, b) {
|
||||||
|
if (a.tanggalPenitipan == null) return 1;
|
||||||
|
if (b.tanggalPenitipan == null) return -1;
|
||||||
|
return b.tanggalPenitipan!.compareTo(a.tanggalPenitipan!);
|
||||||
|
});
|
||||||
|
|
||||||
return filteredList;
|
return filteredList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,13 @@ import 'package:get/get.dart';
|
|||||||
import 'package:penyaluran_app/app/data/models/desa_model.dart';
|
import 'package:penyaluran_app/app/data/models/desa_model.dart';
|
||||||
import 'package:penyaluran_app/app/data/models/user_model.dart';
|
import 'package:penyaluran_app/app/data/models/user_model.dart';
|
||||||
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
import 'package:penyaluran_app/app/modules/auth/controllers/auth_controller.dart';
|
||||||
|
import 'package:penyaluran_app/app/modules/petugas_desa/controllers/counter_service.dart';
|
||||||
import 'package:penyaluran_app/app/services/supabase_service.dart';
|
import 'package:penyaluran_app/app/services/supabase_service.dart';
|
||||||
|
|
||||||
class PetugasDesaController extends GetxController {
|
class PetugasDesaController extends GetxController {
|
||||||
final AuthController _authController = Get.find<AuthController>();
|
final AuthController _authController = Get.find<AuthController>();
|
||||||
final SupabaseService _supabaseService = SupabaseService.to;
|
final SupabaseService _supabaseService = SupabaseService.to;
|
||||||
|
late final CounterService _counterService;
|
||||||
|
|
||||||
// Indeks tab yang aktif di bottom navigation bar
|
// Indeks tab yang aktif di bottom navigation bar
|
||||||
final RxInt activeTabIndex = 0.obs;
|
final RxInt activeTabIndex = 0.obs;
|
||||||
@ -21,15 +23,6 @@ class PetugasDesaController extends GetxController {
|
|||||||
// Model desa dari cache
|
// Model desa dari cache
|
||||||
final Rx<DesaModel?> desaModel = Rx<DesaModel?>(null);
|
final Rx<DesaModel?> desaModel = Rx<DesaModel?>(null);
|
||||||
|
|
||||||
// Counter untuk notifikasi
|
|
||||||
final RxInt jumlahNotifikasiBelumDibaca = 0.obs;
|
|
||||||
|
|
||||||
// Counter untuk permintaan menunggu
|
|
||||||
final RxInt jumlahMenunggu = 0.obs;
|
|
||||||
|
|
||||||
// Counter untuk pengaduan yang diproses
|
|
||||||
final RxInt jumlahDiproses = 0.obs;
|
|
||||||
|
|
||||||
// Data jadwal hari ini
|
// Data jadwal hari ini
|
||||||
final RxList<dynamic> jadwalHariIni = <dynamic>[].obs;
|
final RxList<dynamic> jadwalHariIni = <dynamic>[].obs;
|
||||||
|
|
||||||
@ -37,6 +30,12 @@ class PetugasDesaController extends GetxController {
|
|||||||
String get role => user?.role ?? 'PETUGASDESA';
|
String get role => user?.role ?? 'PETUGASDESA';
|
||||||
String get nama => user?.name ?? 'Petugas Desa';
|
String get nama => user?.name ?? 'Petugas Desa';
|
||||||
|
|
||||||
|
// Getter untuk counter dari CounterService
|
||||||
|
RxInt get jumlahNotifikasiBelumDibaca =>
|
||||||
|
_counterService.jumlahNotifikasiBelumDibaca;
|
||||||
|
RxInt get jumlahMenunggu => _counterService.jumlahMenunggu;
|
||||||
|
RxInt get jumlahDiproses => _counterService.jumlahDiproses;
|
||||||
|
|
||||||
// Getter untuk nama lengkap dari profil pengguna
|
// Getter untuk nama lengkap dari profil pengguna
|
||||||
String get namaLengkap => userProfile['name'] ?? user?.name ?? 'Petugas Desa';
|
String get namaLengkap => userProfile['name'] ?? user?.name ?? 'Petugas Desa';
|
||||||
|
|
||||||
@ -63,6 +62,13 @@ class PetugasDesaController extends GetxController {
|
|||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
|
|
||||||
|
// Inisialisasi CounterService jika belum ada
|
||||||
|
if (!Get.isRegistered<CounterService>()) {
|
||||||
|
Get.put(CounterService(), permanent: true);
|
||||||
|
}
|
||||||
|
_counterService = Get.find<CounterService>();
|
||||||
|
|
||||||
loadUserProfile();
|
loadUserProfile();
|
||||||
loadNotifikasiData();
|
loadNotifikasiData();
|
||||||
loadJadwalData();
|
loadJadwalData();
|
||||||
@ -120,7 +126,7 @@ class PetugasDesaController extends GetxController {
|
|||||||
final notifikasiData =
|
final notifikasiData =
|
||||||
await _supabaseService.getNotifikasiBelumDibaca(user!.id);
|
await _supabaseService.getNotifikasiBelumDibaca(user!.id);
|
||||||
if (notifikasiData != null) {
|
if (notifikasiData != null) {
|
||||||
jumlahNotifikasiBelumDibaca.value = notifikasiData.length;
|
_counterService.updateNotifikasiCounter(notifikasiData.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -134,6 +140,7 @@ class PetugasDesaController extends GetxController {
|
|||||||
final jadwalHariIniData = await _supabaseService.getJadwalHariIni();
|
final jadwalHariIniData = await _supabaseService.getJadwalHariIni();
|
||||||
if (jadwalHariIniData != null) {
|
if (jadwalHariIniData != null) {
|
||||||
jadwalHariIni.value = jadwalHariIniData;
|
jadwalHariIni.value = jadwalHariIniData;
|
||||||
|
_counterService.updateJadwalCounter(jadwalHariIniData.length);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error loading jadwal data: $e');
|
print('Error loading jadwal data: $e');
|
||||||
@ -144,7 +151,27 @@ class PetugasDesaController extends GetxController {
|
|||||||
Future<void> loadPenitipanData() async {
|
Future<void> loadPenitipanData() async {
|
||||||
try {
|
try {
|
||||||
// Simulasi data untuk contoh
|
// Simulasi data untuk contoh
|
||||||
jumlahMenunggu.value = 3;
|
// Dalam implementasi nyata, Anda akan mengambil data dari API
|
||||||
|
final penitipanData = await _supabaseService.getPenitipanBantuan();
|
||||||
|
if (penitipanData != null) {
|
||||||
|
int menunggu = 0;
|
||||||
|
|
||||||
|
// Hitung jumlah penitipan dengan status MENUNGGU
|
||||||
|
for (var item in penitipanData) {
|
||||||
|
if (item['status'] == 'MENUNGGU') {
|
||||||
|
menunggu++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update counter
|
||||||
|
_counterService.updatePenitipanCounters(
|
||||||
|
menunggu: menunggu,
|
||||||
|
terverifikasi: 0, // Tidak digunakan di UI utama
|
||||||
|
ditolak: 0, // Tidak digunakan di UI utama
|
||||||
|
);
|
||||||
|
|
||||||
|
print('Jumlah penitipan menunggu: $menunggu');
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error loading penitipan data: $e');
|
print('Error loading penitipan data: $e');
|
||||||
}
|
}
|
||||||
@ -154,7 +181,25 @@ class PetugasDesaController extends GetxController {
|
|||||||
Future<void> loadPengaduanData() async {
|
Future<void> loadPengaduanData() async {
|
||||||
try {
|
try {
|
||||||
// Simulasi data untuk contoh
|
// Simulasi data untuk contoh
|
||||||
jumlahDiproses.value = 2;
|
// Dalam implementasi nyata, Anda akan mengambil data dari API
|
||||||
|
final pengaduanData = await _supabaseService.getPengaduan();
|
||||||
|
if (pengaduanData != null) {
|
||||||
|
int diproses = 0;
|
||||||
|
|
||||||
|
// Hitung jumlah pengaduan dengan status DIPROSES
|
||||||
|
for (var item in pengaduanData) {
|
||||||
|
if (item['status'] == 'DIPROSES') {
|
||||||
|
diproses++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update counter
|
||||||
|
_counterService.updatePengaduanCounter(diproses);
|
||||||
|
|
||||||
|
print('Jumlah pengaduan diproses: $diproses');
|
||||||
|
} else {
|
||||||
|
_counterService.updatePengaduanCounter(0);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error loading pengaduan data: $e');
|
print('Error loading pengaduan data: $e');
|
||||||
}
|
}
|
||||||
@ -172,6 +217,14 @@ class PetugasDesaController extends GetxController {
|
|||||||
// Metode untuk mengubah tab aktif
|
// Metode untuk mengubah tab aktif
|
||||||
void changeTab(int index) {
|
void changeTab(int index) {
|
||||||
activeTabIndex.value = index;
|
activeTabIndex.value = index;
|
||||||
|
|
||||||
|
// Jika tab penitipan dipilih, muat ulang data penitipan
|
||||||
|
if (index == 2) {
|
||||||
|
loadPenitipanData();
|
||||||
|
} else if (index == 3) {
|
||||||
|
// Jika tab pengaduan dipilih, muat ulang data pengaduan
|
||||||
|
loadPengaduanData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Metode untuk logout
|
// Metode untuk logout
|
||||||
|
@ -94,40 +94,7 @@ class PetugasDesaView extends GetView<PetugasDesaController> {
|
|||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Tombol tambah untuk jadwal dan stok bantuan
|
return notificationButton;
|
||||||
if (activeTab == 1) {
|
|
||||||
return Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.add),
|
|
||||||
tooltip: 'Tambah Jadwal',
|
|
||||||
onPressed: () {
|
|
||||||
// Implementasi untuk menambah jadwal baru
|
|
||||||
},
|
|
||||||
),
|
|
||||||
notificationButton,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
} else if (activeTab == 2) {
|
|
||||||
return Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
IconButton(
|
|
||||||
icon: const Icon(Icons.add),
|
|
||||||
tooltip: 'Tambah Stok Bantuan',
|
|
||||||
onPressed: () {
|
|
||||||
// Implementasi untuk menambah stok bantuan baru
|
|
||||||
},
|
|
||||||
),
|
|
||||||
notificationButton,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
} else if (activeTab == 4) {
|
|
||||||
return notificationButton;
|
|
||||||
} else {
|
|
||||||
return notificationButton;
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
Reference in New Issue
Block a user