Perbarui model dan tampilan untuk menambahkan properti fotoProfil di DonaturModel, PetugasDesaModel, dan WargaModel. Modifikasi controller dan tampilan untuk mendukung pengambilan dan penampilan foto profil pengguna. Tambahkan fungsionalitas baru untuk menampilkan foto profil di berbagai tampilan, termasuk detail penerima dan dashboard warga. Perbarui rute aplikasi untuk mencakup halaman profil pengguna.
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
import 'package:get/get.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:penyaluran_app/app/services/supabase_service.dart';
|
||||
import 'package:penyaluran_app/app/utils/date_time_helper.dart';
|
||||
|
||||
class PenerimaController extends GetxController {
|
||||
@ -7,6 +8,11 @@ class PenerimaController extends GetxController {
|
||||
<Map<String, dynamic>>[].obs;
|
||||
final RxBool isLoading = false.obs;
|
||||
|
||||
// Variabel untuk menyimpan daftar penyaluran bantuan untuk penerima tertentu
|
||||
final RxList<Map<String, dynamic>> daftarPenyaluran =
|
||||
<Map<String, dynamic>>[].obs;
|
||||
final RxBool isLoadingPenyaluran = false.obs;
|
||||
|
||||
// Variabel untuk halaman konfirmasi penerima
|
||||
final RxBool isKonfirmasiChecked = false.obs;
|
||||
final RxBool isIdentitasChecked = false.obs;
|
||||
@ -37,9 +43,30 @@ class PenerimaController extends GetxController {
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
void fetchDaftarPenerima() {
|
||||
void fetchDaftarPenerima() async {
|
||||
isLoading.value = true;
|
||||
|
||||
try {
|
||||
// Get data penerima dari database
|
||||
final penerimaBantuan = await SupabaseService.to.getPenerimaBantuan();
|
||||
|
||||
if (penerimaBantuan != null) {
|
||||
daftarPenerima.value = penerimaBantuan;
|
||||
} else {
|
||||
// Gunakan data dummy jika gagal mendapatkan data dari database
|
||||
_loadDummyData();
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching penerima: $e');
|
||||
// Gunakan data dummy sebagai fallback
|
||||
_loadDummyData();
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Metode untuk memuat data dummy
|
||||
void _loadDummyData() {
|
||||
// Simulasi data penerima
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
daftarPenerima.value = [
|
||||
@ -134,7 +161,6 @@ class PenerimaController extends GetxController {
|
||||
'terverifikasi': true,
|
||||
},
|
||||
];
|
||||
isLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
@ -167,6 +193,79 @@ class PenerimaController extends GetxController {
|
||||
}
|
||||
}
|
||||
|
||||
// Metode untuk mengambil daftar penyaluran bantuan berdasarkan ID warga
|
||||
Future<void> fetchPenyaluranByWargaId(String wargaId) async {
|
||||
isLoadingPenyaluran.value = true;
|
||||
daftarPenyaluran.clear();
|
||||
|
||||
try {
|
||||
final penyaluranBantuan =
|
||||
await SupabaseService.to.getPenyaluranBantuanByWargaId(wargaId);
|
||||
|
||||
if (penyaluranBantuan != null && penyaluranBantuan.isNotEmpty) {
|
||||
daftarPenyaluran.value = penyaluranBantuan;
|
||||
} else {
|
||||
// Gunakan data dummy jika tidak ada data dari database
|
||||
_loadDummyPenyaluran(wargaId);
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching penyaluran bantuan: $e');
|
||||
// Gunakan data dummy sebagai fallback
|
||||
_loadDummyPenyaluran(wargaId);
|
||||
} finally {
|
||||
isLoadingPenyaluran.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Metode untuk memuat data dummy penyaluran
|
||||
void _loadDummyPenyaluran(String wargaId) {
|
||||
// Data dummy penyaluran bantuan (hanya untuk demo)
|
||||
daftarPenyaluran.value = [
|
||||
{
|
||||
'id': '1',
|
||||
'penerima_id': wargaId,
|
||||
'tanggal_penyaluran':
|
||||
DateTime.now().subtract(const Duration(days: 5)).toIso8601String(),
|
||||
'status': 'TERLAKSANA',
|
||||
'stok_bantuan': {
|
||||
'nama': 'Paket Sembako',
|
||||
'jenis': 'Bahan Pokok',
|
||||
'kuantitas': '1 Paket',
|
||||
},
|
||||
'keterangan': 'Bantuan pangan rutin bulanan',
|
||||
'bukti_penyaluran': 'assets/images/bukti_penyaluran.jpg',
|
||||
},
|
||||
{
|
||||
'id': '2',
|
||||
'penerima_id': wargaId,
|
||||
'tanggal_penyaluran':
|
||||
DateTime.now().subtract(const Duration(days: 35)).toIso8601String(),
|
||||
'status': 'TERLAKSANA',
|
||||
'stok_bantuan': {
|
||||
'nama': 'Bantuan Pendidikan',
|
||||
'jenis': 'Alat Tulis',
|
||||
'kuantitas': '1 Paket',
|
||||
},
|
||||
'keterangan': 'Bantuan sekolah semester baru',
|
||||
'bukti_penyaluran': 'assets/images/bukti_penyaluran.jpg',
|
||||
},
|
||||
{
|
||||
'id': '3',
|
||||
'penerima_id': wargaId,
|
||||
'tanggal_penyaluran':
|
||||
DateTime.now().add(const Duration(days: 2)).toIso8601String(),
|
||||
'status': 'DIJADWALKAN',
|
||||
'stok_bantuan': {
|
||||
'nama': 'Paket Sembako',
|
||||
'jenis': 'Bahan Pokok',
|
||||
'kuantitas': '1 Paket',
|
||||
},
|
||||
'keterangan': 'Bantuan pangan rutin bulanan',
|
||||
'bukti_penyaluran': null,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// Fungsi untuk memilih tanggal penyaluran
|
||||
Future<void> pilihTanggalPenyaluran(BuildContext context) async {
|
||||
final DateTime? picked = await showDatePicker(
|
||||
|
@ -27,6 +27,9 @@ class PetugasDesaController extends GetxController {
|
||||
// Data profil pengguna dari cache
|
||||
final RxMap<String, dynamic> userProfile = RxMap<String, dynamic>({});
|
||||
|
||||
// Variabel untuk foto profil
|
||||
final RxString fotoProfil = ''.obs;
|
||||
|
||||
// Model desa dari cache
|
||||
final Rx<DesaModel?> desaModel = Rx<DesaModel?>(null);
|
||||
|
||||
@ -102,6 +105,33 @@ class PetugasDesaController extends GetxController {
|
||||
return 'Petugas Desa';
|
||||
}
|
||||
|
||||
// Getter untuk foto profil
|
||||
String? get profilePhotoUrl {
|
||||
// 1. Coba ambil dari fotoProfil yang sudah disimpan
|
||||
if (fotoProfil.isNotEmpty) {
|
||||
return fotoProfil.value;
|
||||
}
|
||||
|
||||
// 2. Coba ambil dari roleData jika merupakan PetugasDesaModel
|
||||
final userData = _authController.userData;
|
||||
if (userData != null && userData.roleData is PetugasDesaModel) {
|
||||
final petugasData = userData.roleData as PetugasDesaModel;
|
||||
if (petugasData.fotoProfil != null &&
|
||||
petugasData.fotoProfil!.isNotEmpty) {
|
||||
return petugasData.fotoProfil;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Coba ambil dari role_data di userProfile
|
||||
if (userProfile['role_data'] != null &&
|
||||
userProfile['role_data'] is Map<String, dynamic> &&
|
||||
userProfile['role_data']['foto_profil'] != null) {
|
||||
return userProfile['role_data']['foto_profil'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Getter untuk counter dari CounterService
|
||||
RxInt get jumlahNotifikasiBelumDibaca =>
|
||||
_counterService.jumlahNotifikasiBelumDibaca;
|
||||
@ -212,6 +242,14 @@ class PetugasDesaController extends GetxController {
|
||||
'desa': petugasData.desa?.toJson(),
|
||||
};
|
||||
|
||||
// Ambil foto profil jika ada
|
||||
if (petugasData.fotoProfil != null &&
|
||||
petugasData.fotoProfil!.isNotEmpty) {
|
||||
fotoProfil.value = petugasData.fotoProfil!;
|
||||
print(
|
||||
'DEBUG: Foto profil dari petugasData: ${fotoProfil.value}');
|
||||
}
|
||||
|
||||
return; // Data sudah lengkap, tidak perlu fetch lagi
|
||||
}
|
||||
}
|
||||
@ -223,6 +261,14 @@ class PetugasDesaController extends GetxController {
|
||||
if (baseProfile != null) {
|
||||
userProfile.value = baseProfile;
|
||||
|
||||
// Cek dan ambil foto profil
|
||||
if (baseProfile['role_data'] != null &&
|
||||
baseProfile['role_data'] is Map<String, dynamic> &&
|
||||
baseProfile['role_data']['foto_profil'] != null) {
|
||||
fotoProfil.value = baseProfile['role_data']['foto_profil'];
|
||||
print('DEBUG: Foto profil dari API: ${fotoProfil.value}');
|
||||
}
|
||||
|
||||
if (baseProfile['desa'] != null &&
|
||||
baseProfile['desa'] is Map<String, dynamic>) {
|
||||
try {
|
||||
@ -594,7 +640,9 @@ class PetugasDesaController extends GetxController {
|
||||
|
||||
// Metode untuk mengubah tab aktif
|
||||
void changeTab(int index) {
|
||||
print('Mengubah tab ke index: $index (dari: ${activeTabIndex.value})');
|
||||
activeTabIndex.value = index;
|
||||
print('activeTabIndex sekarang: ${activeTabIndex.value}');
|
||||
|
||||
// Jika tab penitipan dipilih, muat ulang data penitipan
|
||||
if (index == 2) {
|
||||
@ -621,6 +669,8 @@ class PetugasDesaController extends GetxController {
|
||||
print('Error saat memanggil onTabReactivated: $e');
|
||||
}
|
||||
}
|
||||
// Paksa update UI
|
||||
activeTabIndex.refresh();
|
||||
}
|
||||
|
||||
// Metode untuk logout
|
||||
|
Reference in New Issue
Block a user