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

@ -1,44 +1,162 @@
import 'package:penyaluran_app/app/services/supabase_service.dart';
import 'package:penyaluran_app/app/data/models/user_model.dart';
import 'package:penyaluran_app/app/data/models/warga_model.dart';
import 'package:penyaluran_app/app/data/models/petugas_desa_model.dart';
import 'package:penyaluran_app/app/data/models/donatur_model.dart';
import 'package:penyaluran_app/app/data/models/desa_model.dart';
class AuthProvider {
final SupabaseService _supabaseService = SupabaseService.to;
// Cache untuk menyimpan data profil pengguna
UserModel? _cachedUser;
// Cache untuk menyimpan data pengguna
UserData? _cachedUserData;
// Metode untuk login
Future<UserModel?> signIn(String email, String password) async {
Future<UserData?> signIn(String email, String password) async {
try {
final response = await _supabaseService.signIn(email, password);
// Step 1: Login
final response = await _supabaseService.client.auth.signInWithPassword(
email: email,
password: password,
);
if (response.user != null && response.user?.email != null) {
// Ambil profil pengguna dari database
final profileData = await _supabaseService.getUserProfile();
print('DEBUG: Profile data dari signIn: $profileData');
if (profileData != null) {
// Buat UserModel dengan data yang ada
_cachedUser = UserModel.fromJson({
...profileData,
'id': response.user!.id,
'email': response.user!.email!,
});
print(
'DEBUG: User model dibuat: ${_cachedUser?.name}, desa: ${_cachedUser?.desa?.nama}');
return _cachedUser;
}
// Jika profil belum tersedia, gunakan data default
_cachedUser = UserModel(
id: response.user!.id,
email: response.user!.email!,
role: 'WARGA', // Default role
);
print('DEBUG: User model default dibuat: ${_cachedUser?.email}');
return _cachedUser;
final user = response.user;
if (user == null) {
print('Login gagal!');
return null;
}
return null;
final userId = user.id;
// Step 2: Ambil role dari view `users_with_roles` atau tabel roles
String roleName;
try {
final roleResponse = await _supabaseService.client
.from('users_with_roles')
.select('role_name')
.eq('id', userId)
.single();
roleName = roleResponse['role_name'];
} catch (e) {
print('Error mengambil role dari users_with_roles: $e');
print('Mencoba ambil role dari tabel roles...');
// Fallback ke cara lama jika view users_with_roles tidak tersedia
try {
// Ambil role_id dari user metadata
final roleId = user.userMetadata?['role_id'];
if (roleId == null) {
print('Tidak ada role_id di user metadata');
return null;
}
final roleResponse = await _supabaseService.client
.from('roles')
.select('role_name')
.eq('id', roleId)
.single();
roleName = roleResponse['role_name'];
} catch (e) {
print('Error mengambil role dari tabel roles: $e');
return null;
}
}
print('Role: $roleName');
// Step 3: Ambil profil user berdasarkan role
Map<String, dynamic>? profileResponse;
dynamic roleData;
DesaModel? desa;
// Buat BaseUserModel
final baseUser = BaseUserModel(
id: userId,
email: user.email ?? '',
roleId: user.userMetadata?['role_id'],
roleName: roleName,
createdAt: DateTime.parse(user.createdAt),
updatedAt:
user.updatedAt != null ? DateTime.parse(user.updatedAt!) : null,
);
if (roleName == 'warga') {
profileResponse = await _supabaseService.client
.from('warga')
.select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
.eq('id', userId)
.single();
if (profileResponse != null) {
// Ekstrak data desa jika ada
if (profileResponse['desa'] != null) {
desa = DesaModel.fromJson(profileResponse['desa']);
print('Data Desa: ${desa.nama}');
}
roleData = WargaModel.fromJson(profileResponse);
print('Data Warga: ${roleData.namaLengkap}');
} else {
print('Tidak menemukan data warga untuk ID: $userId');
return null;
}
} else if (roleName == 'petugas_desa') {
profileResponse = await _supabaseService.client
.from('petugas_desa')
.select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
.eq('id', userId)
.single();
if (profileResponse != null) {
// Ekstrak data desa jika ada
if (profileResponse['desa'] != null) {
desa = DesaModel.fromJson(profileResponse['desa']);
print('Data Desa: ${desa.nama}');
}
roleData = PetugasDesaModel.fromJson(profileResponse);
print(
'Data Petugas Desa: ${roleData.namaLengkap}, Desa: ${roleData.desa?.nama}');
}
} else if (roleName == 'donatur') {
profileResponse = await _supabaseService.client
.from('donatur')
.select('*')
.eq('id', userId)
.single();
roleData = DonaturModel.fromJson(profileResponse);
print('Data Donatur: ${roleData.namaLengkap}');
} else {
return null;
}
if (roleData == null) {
print('Tidak menemukan data profil untuk role: $roleName');
return null;
}
// Perbarui baseUser dengan data desa jika ada
final updatedBaseUser = BaseUserModel(
id: baseUser.id,
email: baseUser.email,
roleId: baseUser.roleId,
roleName: baseUser.roleName,
createdAt: baseUser.createdAt,
updatedAt: baseUser.updatedAt,
desa: desa, // Set desa dari data yang diambil
);
// Simpan cache user data
final userData = UserData(
baseUser: updatedBaseUser,
roleData: roleData,
);
_cachedUserData = userData;
return userData;
} catch (e) {
print('Error pada signIn: $e');
rethrow;
@ -49,57 +167,159 @@ class AuthProvider {
Future<void> signOut() async {
try {
await _supabaseService.signOut();
_cachedUser = null; // Hapus cache saat logout
_cachedUserData = null; // Hapus cache saat logout
} catch (e) {
rethrow;
}
}
// Metode untuk mendapatkan user saat ini
Future<UserModel?> getCurrentUser() async {
// Jika ada cache dan user masih terautentikasi, gunakan cache
if (_cachedUser != null && _supabaseService.isAuthenticated) {
print(
'DEBUG: Menggunakan data user dari cache: ${_cachedUser?.name}, desa: ${_cachedUser?.desa?.nama}');
return _cachedUser;
Future<UserData?> getCurrentUser({bool skipCache = false}) async {
// Jika ada cache dan user masih terautentikasi, gunakan cache kecuali skipCache = true
if (!skipCache &&
_cachedUserData != null &&
_supabaseService.isAuthenticated) {
print('DEBUG: Menggunakan data user dari cache');
return _cachedUserData;
}
final user = _supabaseService.currentUser;
if (user != null) {
if (_supabaseService.currentUser != null) {
try {
// Ambil profil pengguna dari database
final profileData = await _supabaseService.getUserProfile();
print('DEBUG: Profile data dari getCurrentUser: $profileData');
// Login berhasil, lakukan proses yang sama seperti di signIn
// tapi dengan user yang sudah ada
final user = _supabaseService.currentUser!;
final userId = user.id;
if (profileData != null) {
// Buat UserModel dengan data yang ada
_cachedUser = UserModel.fromJson({
...profileData,
'id': user.id,
'email': user.email!,
});
print(
'DEBUG: User model dibuat: ${_cachedUser?.name}, desa: ${_cachedUser?.desa?.nama}');
return _cachedUser;
// Step 2: Ambil role dari view `users_with_roles` atau tabel roles
String roleName;
try {
final roleResponse = await _supabaseService.client
.from('users_with_roles')
.select('role_name')
.eq('id', userId)
.single();
roleName = roleResponse['role_name'];
} catch (e) {
print('Error mengambil role dari users_with_roles: $e');
print('Mencoba ambil role dari tabel roles...');
// Fallback ke cara lama jika view users_with_roles tidak tersedia
try {
// Ambil role_id dari user metadata
final roleId = user.userMetadata?['role_id'];
if (roleId == null) {
print('Tidak ada role_id di user metadata');
return null;
}
final roleResponse = await _supabaseService.client
.from('roles')
.select('role_name')
.eq('id', roleId)
.single();
roleName = roleResponse['role_name'];
} catch (e) {
print('Error mengambil role dari tabel roles: $e');
return null;
}
}
// Jika profil belum tersedia, gunakan data default
_cachedUser = UserModel(
id: user.id,
email: user.email!,
role: 'WARGA', // Default role
print('Role: $roleName');
// Step 3: Ambil profil user berdasarkan role
Map<String, dynamic>? profileResponse;
dynamic roleData;
DesaModel? desa;
// Buat BaseUserModel
final baseUser = BaseUserModel(
id: userId,
email: user.email ?? '',
roleId: user.userMetadata?['role_id'],
roleName: roleName ?? '',
createdAt: DateTime.parse(user.createdAt),
updatedAt:
user.updatedAt != null ? DateTime.parse(user.updatedAt!) : null,
);
print('DEBUG: User model default dibuat: ${_cachedUser?.email}');
return _cachedUser;
if ((roleName ?? '').toLowerCase() == 'warga') {
profileResponse = await _supabaseService.client
.from('warga')
.select(
'*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
.eq('id', userId)
.single();
if (profileResponse != null) {
// Ekstrak data desa jika ada
if (profileResponse['desa'] != null) {
desa = DesaModel.fromJson(profileResponse['desa']);
print('Data Desa: ${desa.nama}');
}
roleData = WargaModel.fromJson(profileResponse);
print('Data Warga: ${roleData.namaLengkap}');
} else {
print('Tidak menemukan data warga untuk ID: $userId');
return null;
}
} else if (roleName.toLowerCase() == 'petugas_desa') {
profileResponse = await _supabaseService.client
.from('petugas_desa')
.select(
'*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
.eq('id', userId)
.single();
if (profileResponse != null) {
// Ekstrak data desa jika ada
if (profileResponse['desa'] != null) {
desa = DesaModel.fromJson(profileResponse['desa']);
print('Data Desa: ${desa.nama}');
}
roleData = PetugasDesaModel.fromJson(profileResponse);
}
} else if (roleName.toLowerCase() == 'donatur') {
profileResponse = await _supabaseService.client
.from('donatur')
.select('*')
.eq('id', userId)
.single();
if (profileResponse != null) {
roleData = DonaturModel.fromJson(profileResponse);
}
}
if (roleData == null) {
print('Tidak menemukan data profil untuk role: $roleName');
return null;
}
// Perbarui baseUser dengan data desa jika ada
final updatedBaseUser = BaseUserModel(
id: baseUser.id,
email: baseUser.email,
roleId: baseUser.roleId,
roleName: baseUser.roleName,
createdAt: baseUser.createdAt,
updatedAt: baseUser.updatedAt,
desa: desa, // Set desa dari data yang diambil
);
// Simpan cache user data
final userData = UserData(
baseUser: updatedBaseUser,
roleData: roleData,
);
_cachedUserData = userData;
return userData;
} catch (e) {
print('Error pada getCurrentUser: $e');
// Jika terjadi error, kembalikan model dengan data minimal
_cachedUser = UserModel(
id: user.id,
email: user.email!,
role: 'WARGA', // Default role
);
return _cachedUser;
}
}
return null;
@ -115,31 +335,49 @@ class AuthProvider {
return await _supabaseService.getWargaByUserId();
}
// Metode untuk membuat profil warga
Future<void> createWargaProfile({
required String nik,
required String namaLengkap,
required String jenisKelamin,
String? noHp,
String? alamat,
String? tempatLahir,
DateTime? tanggalLahir,
String? agama,
}) async {
await _supabaseService.createWargaProfile(
nik: nik,
namaLengkap: namaLengkap,
jenisKelamin: jenisKelamin,
noHp: noHp,
alamat: alamat,
tempatLahir: tempatLahir,
tanggalLahir: tanggalLahir,
agama: agama,
);
// // Metode untuk membuat profil donatur
// Future<void> createDonaturProfile({
// required String namaLengkap,
// String? instansi,
// String? jabatan,
// String? noHp,
// String? alamat,
// String? desaId,
// }) async {
// await _supabaseService.createDonaturProfile(
// namaLengkap: namaLengkap,
// instansi: instansi,
// jabatan: jabatan,
// noHp: noHp,
// alamat: alamat,
// desaId: desaId,
// );
// Invalidasi cache setelah membuat profil baru
_cachedUser = null;
}
// // Invalidasi cache setelah membuat profil baru
// _cachedUserData = null;
// }
// // Metode untuk membuat profil petugas desa
// Future<void> createPetugasDesaProfile({
// required String namaLengkap,
// String? nip,
// String? jabatan,
// String? noHp,
// String? alamat,
// String? desaId,
// }) async {
// await _supabaseService.createPetugasDesaProfile(
// namaLengkap: namaLengkap,
// nip: nip,
// jabatan: jabatan,
// noHp: noHp,
// alamat: alamat,
// desaId: desaId,
// );
// // Invalidasi cache setelah membuat profil baru
// _cachedUserData = null;
// }
// Metode untuk mendapatkan notifikasi pengguna
Future<List<Map<String, dynamic>>> getUserNotifications(