Perbarui model dan tampilan untuk mendukung perubahan struktur data pengguna. Ganti properti nama dan telepon dengan namaLengkap dan noHp di beberapa model, termasuk DonaturModel, PetugasDesaModel, dan WargaModel. Modifikasi tampilan dan controller untuk menggunakan properti baru ini. Tambahkan fungsionalitas baru untuk menampilkan nama lengkap dan nomor telepon dengan lebih baik di berbagai tampilan. Perbarui rute dan logika aplikasi untuk mencerminkan perubahan ini.

This commit is contained in:
Khafidh Fuadi
2025-03-25 10:43:21 +07:00
parent 54c4660302
commit 8e9553d1fc
39 changed files with 1819 additions and 704 deletions

View File

@ -54,12 +54,12 @@ class DetailPenyaluranController extends GetxController {
final user = _supabaseService.client.auth.currentUser;
if (user != null) {
final userData = await _supabaseService.client
.from('users')
.from('user_profile')
.select('role')
.eq('id', user.id)
.single();
if (userData['role'] == 'petugas_desa') {
if (userData['role'] == 'PETUGASDESA') {
isPetugasDesa.value = true;
}
}

View File

@ -275,7 +275,7 @@ class DonaturController extends GetxController {
try {
final donatur = daftarDonatur.firstWhere((d) => d.id == donaturId);
return donatur.nama;
return donatur.namaLengkap;
} catch (e) {
return null;
}

View File

@ -47,7 +47,7 @@ class JadwalPenyaluranController extends GetxController {
// Controller untuk pencarian
final TextEditingController searchController = TextEditingController();
UserModel? get user => _authController.user;
BaseUserModel? get user => _authController.baseUser;
@override
void onInit() {

View File

@ -32,7 +32,7 @@ class PenerimaBantuanController extends GetxController {
// Form key
final GlobalKey<FormState> penerimaFormKey = GlobalKey<FormState>();
UserModel? get user => _authController.user;
BaseUserModel? get user => _authController.baseUser;
@override
void onInit() {
@ -79,19 +79,21 @@ class PenerimaBantuanController extends GetxController {
isLoading.value = true;
try {
final penerima = WargaModel(
nama: namaController.text,
nik: nikController.text,
alamat: alamatController.text,
telepon: teleponController.text,
email: emailController.text,
catatan: catatanController.text,
status: 'AKTIF',
createdAt: DateTime.now(),
updatedAt: DateTime.now(),
);
// Biarkan Supabase yang akan menghasilkan ID saat insert
// Kita hanya perlu menyediakan data lainnya
final penerima = {
'nama_lengkap': namaController.text,
'nik': nikController.text,
'alamat': alamatController.text,
'no_hp': teleponController.text,
'email': emailController.text,
'catatan': catatanController.text,
'status': 'AKTIF',
'created_at': DateTime.now().toIso8601String(),
'updated_at': DateTime.now().toIso8601String(),
};
await _supabaseService.tambahPenerima(penerima.toJson());
await _supabaseService.tambahPenerima(penerima);
// Clear form
clearForm();
@ -125,18 +127,17 @@ class PenerimaBantuanController extends GetxController {
isLoading.value = true;
try {
final penerima = WargaModel(
id: penerimaId,
nama: namaController.text,
nik: nikController.text,
alamat: alamatController.text,
telepon: teleponController.text,
email: emailController.text,
catatan: catatanController.text,
updatedAt: DateTime.now(),
);
final penerima = {
'nama_lengkap': namaController.text,
'nik': nikController.text,
'alamat': alamatController.text,
'no_hp': teleponController.text,
'email': emailController.text,
'catatan': catatanController.text,
'updated_at': DateTime.now().toIso8601String(),
};
await _supabaseService.updatePenerima(penerimaId, penerima.toJson());
await _supabaseService.updatePenerima(penerimaId, penerima);
// Clear form
clearForm();
@ -218,10 +219,10 @@ class PenerimaBantuanController extends GetxController {
}
void setFormData(WargaModel penerima) {
namaController.text = penerima.nama ?? '';
namaController.text = penerima.namaLengkap ?? '';
nikController.text = penerima.nik ?? '';
alamatController.text = penerima.alamat ?? '';
teleponController.text = penerima.telepon ?? '';
teleponController.text = penerima.noHp ?? '';
emailController.text = penerima.email ?? '';
catatanController.text = penerima.catatan ?? '';
}

View File

@ -37,7 +37,7 @@ class PengaduanController extends GetxController {
// Image picker
final ImagePicker _imagePicker = ImagePicker();
UserModel? get user => _authController.user;
BaseUserModel? get user => _authController.baseUser;
@override
void onInit() {

View File

@ -53,7 +53,7 @@ class PenitipanBantuanController extends GetxController {
// Tambahkan properti untuk waktu terakhir update
final Rx<DateTime> lastUpdateTime = DateTime.now().obs;
UserModel? get user => _authController.user;
BaseUserModel? get user => _authController.baseUser;
// Getter untuk counter dari CounterService
RxInt get jumlahMenunggu => _counterService.jumlahMenunggu;
@ -72,10 +72,9 @@ class PenitipanBantuanController extends GetxController {
loadPenitipanData();
loadKategoriBantuanData();
// Tambahkan delay untuk memastikan data petugas desa dimuat setelah penitipan
Future.delayed(const Duration(seconds: 1), () {
loadAllPetugasDesaData();
});
// Hapus delay dan muat data petugas desa langsung
loadAllPetugasDesaData();
// Listener untuk pencarian donatur
donaturSearchController.addListener(() {
@ -123,25 +122,24 @@ class PenitipanBantuanController extends GetxController {
// Muat informasi petugas desa untuk item yang terverifikasi
print(
'Memuat informasi petugas desa untuk ${daftarPenitipan.length} penitipan');
List<Future> petugasLoaders = [];
for (var item in daftarPenitipan) {
if (item.status == 'TERVERIFIKASI' && item.petugasDesaId != null) {
print(
'Memuat informasi petugas desa untuk penitipan ID: ${item.id}, petugasDesaId: ${item.petugasDesaId}');
final petugasData = await getPetugasDesaInfo(item.petugasDesaId);
if (petugasData != null) {
print(
'Berhasil memuat data petugas desa: ${petugasData['name']} untuk ID: ${item.petugasDesaId}');
} else {
print(
'Gagal memuat data petugas desa untuk ID: ${item.petugasDesaId}');
}
petugasLoaders.add(getPetugasDesaInfo(item.petugasDesaId));
}
}
// Tunggu semua data petugas desa selesai dimuat
await Future.wait(petugasLoaders);
// Debug: print semua data petugas desa yang sudah dimuat
print('Data petugas desa yang sudah dimuat:');
petugasDesaCache.forEach((key, value) {
print('ID: $key, Nama: $value');
print('ID: $key, Nama: ${value['nama_lengkap']}');
});
// Update waktu terakhir refresh
@ -490,7 +488,8 @@ class PenitipanBantuanController extends GetxController {
final donaturId = item.donaturId;
String donaturNama = '';
if (donaturId != null && donaturCache.containsKey(donaturId)) {
donaturNama = donaturCache[donaturId]?.nama?.toLowerCase() ?? '';
donaturNama =
donaturCache[donaturId]?.namaLengkap?.toLowerCase() ?? '';
}
final donaturMatch = donaturNama.contains(searchText);
@ -551,25 +550,37 @@ class PenitipanBantuanController extends GetxController {
if (!petugasDesaCache.containsKey(petugasDesaId)) {
print(
'Data petugas desa tidak ditemukan di cache untuk ID: $petugasDesaId');
// Jadwalkan pengambilan data untuk nanti
// Muat data petugas dan perbarui UI
loadPetugasDesaData(petugasDesaId);
return 'Memuat...';
// Coba cek lagi setelah pemuatan
if (petugasDesaCache.containsKey(petugasDesaId)) {
// Akses nama dari struktur data petugas_desa
final nama = petugasDesaCache[petugasDesaId]?['nama_lengkap'];
return nama ?? 'Tidak diketahui';
}
return 'Memuat data...';
}
// Sekarang data seharusnya ada di cache
final nama = petugasDesaCache[petugasDesaId]?['name'];
// Akses nama dari struktur data petugas_desa
final nama = petugasDesaCache[petugasDesaId]?['nama_lengkap'];
print('Nama petugas desa: $nama untuk ID: $petugasDesaId');
return nama ?? 'Tidak diketahui';
}
// Fungsi untuk memuat data petugas desa dan memperbarui UI
void loadPetugasDesaData(String petugasDesaId) async {
Future<void> loadPetugasDesaData(String petugasDesaId) async {
try {
print('Memuat data petugas desa untuk ID: $petugasDesaId');
final petugasData = await getPetugasDesaInfo(petugasDesaId);
if (petugasData != null) {
// Data sudah dimasukkan ke cache oleh getPetugasDesaInfo
// Refresh UI
update();
print('Berhasil memuat data petugas: ${petugasData['nama_lengkap']}');
// Refresh UI segera
update(['petugas_data']);
} else {
print(
'Gagal mengambil data petugas desa dari server untuk ID: $petugasDesaId');
@ -597,7 +608,7 @@ class PenitipanBantuanController extends GetxController {
// Debug: print semua data petugas desa yang sudah dimuat
print('Data petugas desa yang sudah dimuat setelah reload:');
petugasDesaCache.forEach((key, value) {
print('ID: $key, Nama: $value');
print('ID: $key, Nama: ${value['nama_lengkap']}');
});
} catch (e) {
print('Error saat memuat ulang data petugas desa: $e');
@ -643,15 +654,15 @@ class PenitipanBantuanController extends GetxController {
Future<String?> tambahDonatur({
required String nama,
required String telepon,
required String noHp,
String? alamat,
String? email,
String? jenis,
}) async {
try {
final donaturData = {
'nama': nama,
'telepon': telepon,
'nama_lengkap': nama,
'no_hp': noHp,
'alamat': alamat,
'email': email,
'jenis': jenis,

View File

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.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/petugas_desa_model.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';
@ -49,9 +50,57 @@ class PetugasDesaController extends GetxController {
// Variabel untuk pencarian dan filter
final searchQuery = ''.obs;
UserModel? get user => _authController.user;
String get role => user?.role ?? 'PETUGASDESA';
String get nama => user?.name ?? 'Petugas Desa';
BaseUserModel? get user => _authController.baseUser;
String get role => user?.roleName ?? 'PETUGAS_DESA';
// Helper method untuk format role agar lebih rapi
String get formattedRole {
final roleText = role.toLowerCase();
if (roleText.contains('_')) {
return roleText
.split('_')
.map((word) =>
word.isNotEmpty ? word[0].toUpperCase() + word.substring(1) : '')
.join(' ');
}
return roleText.isNotEmpty
? roleText[0].toUpperCase() + roleText.substring(1)
: 'Petugas Desa';
}
String get nama {
// 1. Coba ambil dari AuthController displayName yang paling lengkap
final authDisplayName = _authController.displayName;
if (authDisplayName != null &&
authDisplayName != 'Pengguna' &&
authDisplayName != user?.email) {
return authDisplayName;
}
// 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.namaLengkap != null &&
petugasData.namaLengkap!.isNotEmpty) {
return petugasData.namaLengkap!;
}
}
// 3. Coba ambil dari user.name
if (user?.name != null && user!.name!.isNotEmpty) {
return user!.name!;
}
// 4. Fallback ke nama dari userProfile
if (userProfile['name'] != null &&
userProfile['name'].toString().isNotEmpty) {
return userProfile['name'];
}
// 5. Default fallback
return 'Petugas Desa';
}
// Getter untuk counter dari CounterService
RxInt get jumlahNotifikasiBelumDibaca =>
@ -64,6 +113,13 @@ class PetugasDesaController extends GetxController {
// Getter untuk nama desa dari profil pengguna
String get desa {
// Debug info
print('DEBUG: Memeriksa data desa...');
if (user != null) {
print('DEBUG: User ID: ${user!.id}, User email: ${user!.email}');
print('DEBUG: User desa: ${user!.desa}');
}
// Prioritaskan model desa dari user
if (user?.desa != null) {
print('DEBUG: Menggunakan desa dari user model: ${user!.desa!.nama}');
@ -77,9 +133,15 @@ class PetugasDesaController extends GetxController {
return desaNama;
}
// Jika masih tidak ada, coba dari desaModel
if (desaModel.value != null) {
print('DEBUG: Menggunakan desa dari desaModel: ${desaModel.value!.nama}');
return desaModel.value!.nama;
}
// Fallback ke nilai default
print('DEBUG: Menggunakan nilai default untuk desa');
return userProfile['desa_id'] != null ? 'Desa' : 'Desa';
return 'Desa';
}
@override
@ -109,34 +171,76 @@ class PetugasDesaController extends GetxController {
// Metode untuk memuat data profil pengguna dari cache
Future<void> loadUserProfile() async {
try {
// Jika user sudah ada di AuthController, tidak perlu mengambil data lagi
// Jika user sudah ada di AuthController, gunakan data yang ada
if (user != null) {
print('DEBUG: User ditemukan di AuthController: ${user!.email}');
print('DEBUG: User desa: ${user!.desa?.nama}');
// Ambil data tambahan jika diperlukan, tapi gunakan cache
final profileData = await _supabaseService.getUserProfile();
if (profileData != null) {
print('DEBUG: Profile data ditemukan: ${profileData['name']}');
userProfile.value = profileData;
// Tidak perlu mengambil data tambahan jika user.desa sudah ada
if (user!.desa != null) {
print(
'DEBUG: Menggunakan desa dari AuthController: ${user!.desa!.nama}');
desaModel.value = user!.desa;
// Parse data desa jika ada
if (profileData['desa'] != null &&
profileData['desa'] is Map<String, dynamic>) {
// Perbarui userProfile untuk konsistensi
if (userProfile.isEmpty) {
userProfile.value = {
'name': user!.name ?? _authController.displayName,
'desa': user!.desa?.toJson(),
};
}
return; // Data sudah lengkap, tidak perlu fetch lagi
}
print(
'DEBUG: Data desa tidak ditemukan di AuthController, mencoba ambil dari cache');
// Jika tidak ada desa di AuthController, coba ambil dari userData roleData
final userData = _authController.userData;
if (userData != null) {
if (userData.roleData is PetugasDesaModel) {
final petugasData = userData.roleData as PetugasDesaModel;
if (petugasData.desa != null) {
print(
'DEBUG: Menggunakan desa dari roleData: ${petugasData.desa!.nama}');
desaModel.value = petugasData.desa;
// Perbarui userProfile untuk konsistensi
userProfile.value = {
'name': petugasData.displayName,
'desa': petugasData.desa?.toJson(),
};
return; // Data sudah lengkap, tidak perlu fetch lagi
}
}
}
// Jika tidak ada di cache, ambil dari API hanya jika benar-benar diperlukan
print('DEBUG: Data desa tidak ditemukan di cache, mengambil dari API');
final baseProfile = await _supabaseService.getUserProfile();
if (baseProfile != null) {
userProfile.value = baseProfile;
if (baseProfile['desa'] != null &&
baseProfile['desa'] is Map<String, dynamic>) {
try {
final desaData = profileData['desa'] as Map<String, dynamic>;
print('DEBUG: Desa data ditemukan: $desaData');
final desaData = baseProfile['desa'] as Map<String, dynamic>;
print('DEBUG: Desa data ditemukan dari API: $desaData');
desaModel.value = DesaModel.fromJson(desaData);
} catch (e) {
print('Error parsing desa data: $e');
}
} else {
print('DEBUG: Desa data tidak ditemukan atau bukan Map');
print('DEBUG: Desa data tidak ditemukan di API');
}
} else {
print('DEBUG: Profile data tidak ditemukan');
print('DEBUG: Profile data tidak ditemukan dari API');
}
} else {
print('DEBUG: User tidak ditemukan di AuthController');
print(
'DEBUG: User tidak ditemukan di AuthController, mungkin belum login');
}
} catch (e) {
print('Error loading user profile: $e');

View File

@ -27,7 +27,7 @@ class PetugasDesaDashboardController extends GetxController {
// Controller untuk pencarian
final TextEditingController searchController = TextEditingController();
UserModel? get user => _authController.user;
BaseUserModel? get user => _authController.baseUser;
String get role => user?.role ?? 'PETUGASDESA';
String get nama => user?.name ?? 'Petugas Desa';

View File

@ -17,7 +17,7 @@ class RiwayatPengaduanController extends GetxController {
// Controller untuk pencarian
final TextEditingController searchController = TextEditingController();
UserModel? get user => _authController.user;
BaseUserModel? get user => _authController.baseUser;
@override
void onInit() {

View File

@ -36,7 +36,7 @@ class StokBantuanController extends GetxController {
// Tambahkan properti untuk waktu terakhir update
Rx<DateTime> lastUpdateTime = DateTime.now().obs;
UserModel? get user => _authController.user;
BaseUserModel? get user => _authController.baseUser;
@override
void onInit() {