Files
penyaluran_app/lib/app/services/supabase_service.dart

1158 lines
32 KiB
Dart

import 'package:get/get.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'dart:io';
class SupabaseService extends GetxService {
static SupabaseService get to => Get.find<SupabaseService>();
late final SupabaseClient client;
// Cache untuk profil pengguna
Map<String, dynamic>? _cachedUserProfile;
// Flag untuk menandai apakah sesi sudah diinisialisasi
bool _isSessionInitialized = false;
// Ganti dengan URL dan API key Supabase Anda
static const String supabaseUrl = String.fromEnvironment('SUPABASE_URL',
defaultValue: 'http://labulabs.net:8000');
static const String supabaseKey = String.fromEnvironment('SUPABASE_KEY',
defaultValue:
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewogICJyb2xlIjogImFub24iLAogICJpc3MiOiAic3VwYWJhc2UiLAogICJpYXQiOiAxNzMxODYyODAwLAogICJleHAiOiAxODg5NjI5MjAwCn0.4IpwhwCVbfYXxb8JlZOLSBzCt6kQmypkvuso7N8Aicc');
Future<SupabaseService> init() async {
try {
await Supabase.initialize(
url: supabaseUrl,
anonKey: supabaseKey,
debug: true, // Aktifkan debug untuk melihat log autentikasi
);
client = Supabase.instance.client;
// Tambahkan listener untuk perubahan autentikasi
client.auth.onAuthStateChange.listen((data) {
final AuthChangeEvent event = data.event;
print('DEBUG: Auth state changed: $event');
if (event == AuthChangeEvent.signedIn) {
print('DEBUG: User signed in');
_isSessionInitialized = true;
} else if (event == AuthChangeEvent.signedOut) {
print('DEBUG: User signed out');
_cachedUserProfile = null;
_isSessionInitialized = false;
} else if (event == AuthChangeEvent.tokenRefreshed) {
print('DEBUG: Token refreshed');
_isSessionInitialized = true;
}
});
// Periksa apakah ada sesi yang aktif
final session = client.auth.currentSession;
if (session != null) {
print('DEBUG: Session aktif ditemukan saat inisialisasi');
_isSessionInitialized = true;
} else {
print('DEBUG: Tidak ada session aktif saat inisialisasi');
}
return this;
} catch (e) {
print('ERROR: Gagal inisialisasi Supabase: $e');
rethrow;
}
}
// Metode untuk mendaftar pengguna baru
Future<AuthResponse> signUp(String email, String password) async {
return await client.auth.signUp(
email: email,
password: password,
data: {'autoconfirm': true},
);
}
// Metode untuk login
Future<AuthResponse> signIn(String email, String password) async {
final response = await client.auth.signInWithPassword(
email: email,
password: password,
);
if (response.user != null) {
_isSessionInitialized = true;
print('DEBUG: Login berhasil, sesi diinisialisasi');
}
return response;
}
// Metode untuk logout
Future<void> signOut() async {
_cachedUserProfile = null; // Hapus cache saat logout
_isSessionInitialized = false;
await client.auth.signOut();
print('DEBUG: Logout berhasil, sesi dihapus');
}
// Metode untuk mendapatkan user saat ini
User? get currentUser => client.auth.currentUser;
// Metode untuk memeriksa apakah user sudah login
bool get isAuthenticated {
final user = currentUser;
final session = client.auth.currentSession;
if (user != null && session != null) {
// Periksa apakah token masih valid
final now = DateTime.now().millisecondsSinceEpoch / 1000;
final isValid = session.expiresAt != null && session.expiresAt! > now;
if (isValid) {
print('DEBUG: Sesi valid, user terautentikasi');
return true;
} else {
print('DEBUG: Sesi kedaluwarsa, user tidak terautentikasi');
return false;
}
}
print('DEBUG: Tidak ada user atau sesi, user tidak terautentikasi');
return false;
}
// Metode untuk mendapatkan profil pengguna
Future<Map<String, dynamic>?> getUserProfile() async {
final user = currentUser;
if (user == null) return null;
try {
// Gunakan cache jika tersedia
if (_cachedUserProfile != null && _cachedUserProfile!['id'] == user.id) {
print('Menggunakan data profil dari cache');
return _cachedUserProfile;
}
final response = await client
.from('user_profile')
.select('*, desa:desa_id(id, nama, kecamatan, kabupaten, provinsi)')
.eq('id', user.id)
.maybeSingle();
print('response: $response');
// Simpan ke cache
_cachedUserProfile = response;
// Log untuk debugging
if (response != null && response['desa'] != null) {
print('Desa data: ${response['desa']}');
print('Desa type: ${response['desa'].runtimeType}');
}
return response;
} catch (e) {
print('Error pada getUserProfile: $e');
return null;
}
}
// Metode untuk mendapatkan role pengguna
Future<String?> getUserRole() async {
final profile = await getUserProfile();
return profile?['role'];
}
// ==================== PETUGAS DESA METHODS ====================
// Dashboard methods
Future<int?> getTotalPenerima() async {
try {
final response =
await client.from('warga').select('id').eq('status', 'AKTIF');
return response.length;
} catch (e) {
print('Error getting total penerima: $e');
return null;
}
}
Future<int?> getTotalBantuan() async {
try {
final response = await client.from('stok_bantuan').select('jumlah');
double total = 0;
for (var item in response) {
total += (item['jumlah'] ?? 0);
}
return total.toInt();
} catch (e) {
print('Error getting total bantuan: $e');
return null;
}
}
Future<int?> getTotalPenyaluran() async {
try {
final response = await client
.from('penyaluran_bantuan')
.select('id')
.eq('status', 'TERLAKSANA');
return response.length;
} catch (e) {
print('Error getting total penyaluran: $e');
return null;
}
}
Future<List<Map<String, dynamic>>?> getNotifikasiBelumDibaca(
String userId) async {
try {
final response = await client
.from('notifikasi')
.select('*')
.eq('user_id', userId)
.eq('dibaca', false)
.order('created_at', ascending: false);
return response;
} catch (e) {
print('Error getting notifikasi belum dibaca: $e');
return null;
}
}
// Jadwal penyaluran methods
Future<List<Map<String, dynamic>>?> getJadwalHariIni() async {
try {
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
final tomorrow = today.add(const Duration(days: 1));
// Konversi ke UTC untuk query ke database
final todayUtc = today.toUtc().toIso8601String();
final tomorrowUtc = tomorrow.toUtc().toIso8601String();
final response = await client
.from('penyaluran_bantuan')
.select('*')
.gte('tanggal_penyaluran', todayUtc)
.lt('tanggal_penyaluran', tomorrowUtc)
.inFilter('status', ['AKTIF', 'DIJADWALKAN']);
print("hari ini $response");
return response;
} catch (e) {
print('Error getting jadwal hari ini: $e');
return null;
}
}
Future<List<Map<String, dynamic>>?> getJadwalMendatang() async {
try {
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
final tomorrow = today.add(const Duration(days: 1));
final week = today.add(const Duration(days: 7));
// Konversi ke UTC untuk query ke database
final tomorrowUtc = tomorrow.toUtc().toIso8601String();
final weekUtc = week.toUtc().toIso8601String();
final response = await client
.from('penyaluran_bantuan')
.select('*')
.gte('tanggal_penyaluran', tomorrowUtc)
.lt('tanggal_penyaluran', weekUtc)
.inFilter('status', ['DIJADWALKAN']);
return response;
} catch (e) {
print('Error getting jadwal mendatang: $e');
return null;
}
}
Future<List<Map<String, dynamic>>?> getJadwalTerlaksana() async {
try {
final response = await client
.from('penyaluran_bantuan')
.select('*')
.inFilter('status', ['TERLAKSANA', 'BATALTERLAKSANA']).order(
'tanggal_penyaluran',
ascending: false);
return response;
} catch (e) {
print('Error getting jadwal selesai: $e');
return null;
}
}
Future<List<Map<String, dynamic>>?> getPermintaanPenjadwalan() async {
try {
final response = await client
.from('penyaluran_bantuan')
.select('*')
.eq('status', 'DIJADWALKAN');
return response;
} catch (e) {
print('Error getting permintaan penjadwalan: $e');
return null;
}
}
Future<void> approveJadwal(String jadwalId) async {
try {
await client.from('penyaluran_bantuan').update({
'status': 'AKTIF',
'updated_at': DateTime.now().toIso8601String(),
}).eq('id', jadwalId);
} catch (e) {
print('Error approving jadwal: $e');
throw e.toString();
}
}
Future<void> rejectJadwal(String jadwalId, String alasan) async {
try {
await client.from('penyaluran_bantuan').update({
'status': 'BATALTERLAKSANA',
'alasan_penolakan': alasan,
'updated_at': DateTime.now().toIso8601String(),
}).eq('id', jadwalId);
} catch (e) {
print('Error rejecting jadwal: $e');
throw e.toString();
}
}
Future<void> completeJadwal(String jadwalId) async {
try {
await client.from('penyaluran_bantuan').update({
'status': 'TERLAKSANA',
'updated_at': DateTime.now().toIso8601String(),
}).eq('id', jadwalId);
} catch (e) {
print('Error completing jadwal: $e');
throw e.toString();
}
}
// Metode untuk memperbarui status jadwal
Future<void> updateJadwalStatus(String jadwalId, String status) async {
try {
await client.from('penyaluran_bantuan').update({
'status': status,
'updated_at': DateTime.now().toUtc().toIso8601String(),
}).eq('id', jadwalId);
} catch (e) {
print('Error updating jadwal status: $e');
throw e.toString();
}
}
// Stok bantuan methods
Future<List<Map<String, dynamic>>?> getStokBantuan() async {
try {
final response = await client
.from('stok_bantuan')
.select('*, kategori_bantuan:kategori_bantuan_id(*, nama)');
return response;
} catch (e) {
print('Error getting stok bantuan: $e');
return null;
}
}
Future<Map<String, dynamic>?> getStokStatistics() async {
try {
// Get stok masuk
final masukResponse = await client.from('stok_bantuan').select('jumlah');
double masuk = 0;
for (var item in masukResponse) {
masuk += (item['jumlah'] ?? 0);
}
// Get stok keluar
final keluarResponse =
await client.from('detail_penyaluran').select('jumlah');
double keluar = 0;
for (var item in keluarResponse) {
keluar += (item['jumlah'] ?? 0);
}
return {
'masuk': masuk,
'keluar': keluar,
};
} catch (e) {
print('Error getting stok statistics: $e');
return null;
}
}
Future<List<Map<String, dynamic>>?> getBentukBantuan() async {
try {
final response = await client.from('bentuk_bantuan').select('*');
return response;
} catch (e) {
print('Error getting bentuk bantuan: $e');
return null;
}
}
Future<List<Map<String, dynamic>>?> getKategoriBantuan() async {
try {
final response = await client.from('kategori_bantuan').select('*');
return response;
} catch (e) {
print('Error getting kategori bantuan: $e');
return null;
}
}
Future<void> addStok(Map<String, dynamic> stokData) async {
try {
print('stokData: $stokData');
// Hapus id dari stokData jika ada, biarkan Supabase yang menghasilkan id
if (stokData.containsKey('id')) {
stokData.remove('id');
}
await client.from('stok_bantuan').insert(stokData);
} catch (e) {
print('Error adding stok: $e');
throw e.toString();
}
}
Future<void> updateStok(String stokId, Map<String, dynamic> stok) async {
try {
await client.from('stok_bantuan').update(stok).eq('id', stokId);
} catch (e) {
print('Error updating stok: $e');
throw e.toString();
}
}
Future<void> deleteStok(String stokId) async {
try {
await client.from('stok_bantuan').delete().eq('id', stokId);
} catch (e) {
print('Error deleting stok: $e');
throw e.toString();
}
}
// Penitipan bantuan methods
Future<List<Map<String, dynamic>>?> getPenitipanBantuan() async {
try {
final response = await client
.from('penitipan_bantuan')
.select('*, donatur:donatur_id(*), stok_bantuan:stok_bantuan_id(*)')
.order('tanggal_penitipan', ascending: false);
return response;
} catch (e) {
print('Error getting penitipan bantuan: $e');
return null;
}
}
// Metode untuk mengambil data penitipan bantuan dengan status TERVERIFIKASI
Future<List<Map<String, dynamic>>?> getPenitipanBantuanTerverifikasi() async {
try {
final response = await client
.from('penitipan_bantuan')
.select('*, donatur:donatur_id(*), stok_bantuan:stok_bantuan_id(*)')
.eq('status', 'TERVERIFIKASI')
.order('tanggal_penitipan', ascending: false);
return response;
} catch (e) {
print('Error getting penitipan bantuan terverifikasi: $e');
return null;
}
}
// Upload file methods
Future<String?> uploadFile(
String filePath, String bucket, String folder) async {
try {
final fileName = filePath.split('/').last;
final fileExt = fileName.split('.').last;
final fileKey =
'$folder/${DateTime.now().millisecondsSinceEpoch}.$fileExt';
await client.storage.from(bucket).upload(
fileKey,
File(filePath),
fileOptions: const FileOptions(cacheControl: '3600', upsert: true),
);
final fileUrl = client.storage.from(bucket).getPublicUrl(fileKey);
print('File uploaded: $fileUrl');
return fileUrl;
} catch (e) {
print('Error uploading file: $e');
return null;
}
}
Future<List<String>?> uploadMultipleFiles(
List<String> filePaths, String bucket, String folder) async {
try {
final List<String> fileUrls = [];
for (final filePath in filePaths) {
final fileUrl = await uploadFile(filePath, bucket, folder);
if (fileUrl != null) {
fileUrls.add(fileUrl);
}
}
return fileUrls;
} catch (e) {
print('Error uploading multiple files: $e');
return null;
}
}
Future<void> verifikasiPenitipan(
String penitipanId, String fotoBuktiSerahTerimaPath) async {
try {
// Upload bukti serah terima
final fotoBuktiSerahTerimaUrl = await uploadFile(
fotoBuktiSerahTerimaPath, 'bantuan', 'foto_bukti_serah_terima');
if (fotoBuktiSerahTerimaUrl == null) {
throw 'Gagal mengupload bukti serah terima';
}
final petugasDesaId = client.auth.currentUser?.id;
print(
'Verifikasi penitipan dengan ID: $penitipanId oleh petugas desa ID: $petugasDesaId');
final updateData = {
'status': 'TERVERIFIKASI',
'tanggal_verifikasi': DateTime.now().toIso8601String(),
'updated_at': DateTime.now().toIso8601String(),
'foto_bukti_serah_terima': fotoBuktiSerahTerimaUrl,
'petugas_desa_id': petugasDesaId,
};
print('Data yang akan diupdate: $updateData');
await client
.from('penitipan_bantuan')
.update(updateData)
.eq('id', penitipanId);
print('Penitipan berhasil diverifikasi dan data petugas desa disimpan');
} catch (e) {
print('Error verifying penitipan: $e');
throw e.toString();
}
}
Future<void> tolakPenitipan(String penitipanId, String alasan) async {
try {
await client.from('penitipan_bantuan').update({
'status': 'DITOLAK',
'alasan_penolakan': alasan,
'updated_at': DateTime.now().toIso8601String(),
}).eq('id', penitipanId);
} catch (e) {
print('Error rejecting penitipan: $e');
throw e.toString();
}
}
// Metode untuk menambahkan penitipan bantuan baru
Future<void> tambahPenitipanBantuan({
required String stokBantuanId,
required double jumlah,
required String deskripsi,
required List<String> fotoBantuanPaths,
String? donaturId,
bool isUang = false,
}) async {
try {
final petugasDesaId = client.auth.currentUser?.id;
if (petugasDesaId == null) {
throw 'User tidak ditemukan';
}
// Upload foto bantuan
final fotoBantuanUrls = await uploadMultipleFiles(
fotoBantuanPaths, 'bantuan', 'foto_bantuan');
if (fotoBantuanUrls == null || fotoBantuanUrls.isEmpty) {
throw 'Gagal mengupload foto bantuan';
}
// Data penitipan
final penitipanData = {
'stok_bantuan_id': stokBantuanId,
'jumlah': jumlah,
'deskripsi': deskripsi,
'status':
'TERVERIFIKASI', // Langsung terverifikasi karena diinput oleh petugas desa
'foto_bantuan': fotoBantuanUrls,
'tanggal_penitipan': DateTime.now().toIso8601String(),
'tanggal_verifikasi': DateTime.now().toIso8601String(),
'created_at': DateTime.now().toIso8601String(),
'updated_at': DateTime.now().toIso8601String(),
'petugas_desa_id': petugasDesaId,
'is_uang': isUang,
};
// Tambahkan donatur_id jika ada
if (donaturId != null && donaturId.isNotEmpty) {
penitipanData['donatur_id'] = donaturId;
}
await client.from('penitipan_bantuan').insert(penitipanData);
} catch (e) {
print('Error adding penitipan bantuan: $e');
throw e.toString();
}
}
Future<Map<String, dynamic>?> getDonaturById(String donaturId) async {
try {
final response =
await client.from('donatur').select('*').eq('id', donaturId).single();
return response;
} catch (e) {
print('Error getting donatur by id: $e');
return null;
}
}
// Metode untuk mencari donatur berdasarkan keyword
Future<List<Map<String, dynamic>>?> searchDonatur(String keyword) async {
try {
if (keyword.length < 3) {
return [];
}
final response = await client
.from('donatur')
.select('*')
.ilike('nama', '%$keyword%')
.limit(10);
return response;
} catch (e) {
print('Error searching donatur: $e');
return null;
}
}
// Metode untuk mendapatkan daftar donatur
Future<List<Map<String, dynamic>>?> getDaftarDonatur() async {
try {
final response = await client
.from('donatur')
.select('*')
.order('nama', ascending: true);
return response;
} catch (e) {
print('Error getting daftar donatur: $e');
return null;
}
}
// Metode untuk menambahkan donatur baru
Future<String?> tambahDonatur(Map<String, dynamic> donaturData) async {
try {
final response =
await client.from('donatur').insert(donaturData).select('id');
if (response.isNotEmpty) {
return response[0]['id'];
}
return null;
} catch (e) {
print('Error adding donatur: $e');
throw e.toString();
}
}
// Pengaduan methods
Future<List<Map<String, dynamic>>?> getPengaduan() async {
try {
final response = await client.from('pengaduan').select('*');
return response;
} catch (e) {
print('Error getting pengaduan: $e');
return null;
}
}
Future<void> prosesPengaduan(String pengaduanId) async {
try {
await client.from('pengaduan').update({
'status': 'DIPROSES',
'updated_at': DateTime.now().toIso8601String(),
}).eq('id', pengaduanId);
} catch (e) {
print('Error processing pengaduan: $e');
throw e.toString();
}
}
Future<void> tambahTindakanPengaduan(Map<String, dynamic> tindakan) async {
try {
await client.from('tindakan_pengaduan').insert(tindakan);
} catch (e) {
print('Error adding tindakan pengaduan: $e');
throw e.toString();
}
}
Future<void> updateStatusPengaduan(String pengaduanId, String status) async {
try {
await client.from('pengaduan').update({
'status': status,
'updated_at': DateTime.now().toIso8601String(),
}).eq('id', pengaduanId);
} catch (e) {
print('Error updating status pengaduan: $e');
throw e.toString();
}
}
Future<List<Map<String, dynamic>>?> getTindakanPengaduan(
String pengaduanId) async {
try {
final response = await client
.from('tindakan_pengaduan')
.select('*')
.eq('pengaduan_id', pengaduanId)
.order('created_at', ascending: false);
return response;
} catch (e) {
print('Error getting tindakan pengaduan: $e');
return null;
}
}
// Penerima bantuan methods
Future<List<Map<String, dynamic>>?> getPenerimaBantuan() async {
try {
final response = await client.from('warga').select('*');
return response;
} catch (e) {
print('Error getting penerima bantuan: $e');
return null;
}
}
Future<void> tambahPenerima(Map<String, dynamic> penerima) async {
try {
await client.from('warga').insert(penerima);
} catch (e) {
print('Error adding penerima: $e');
throw e.toString();
}
}
Future<void> updatePenerima(
String penerimaId, Map<String, dynamic> penerima) async {
try {
await client.from('warga').update(penerima).eq('id', penerimaId);
} catch (e) {
print('Error updating penerima: $e');
throw e.toString();
}
}
Future<void> updateStatusPenerima(String penerimaId, String status) async {
try {
await client.from('warga').update({
'status': status,
'updated_at': DateTime.now().toIso8601String(),
}).eq('id', penerimaId);
} catch (e) {
print('Error updating status penerima: $e');
throw e.toString();
}
}
// Laporan methods
Future<List<Map<String, dynamic>>?> getLaporan(
DateTime? tanggalMulai, DateTime? tanggalSelesai) async {
try {
var query = client.from('laporan').select('*');
if (tanggalMulai != null) {
query = query.gte('created_at', tanggalMulai.toIso8601String());
}
if (tanggalSelesai != null) {
query = query.lte('created_at', tanggalSelesai.toIso8601String());
}
final response = await query.order('created_at', ascending: false);
return response;
} catch (e) {
print('Error getting laporan: $e');
return null;
}
}
Future<String?> generateLaporan(Map<String, dynamic> laporan) async {
try {
final response = await client.from('laporan').insert(laporan);
return response[0]['id'];
} catch (e) {
print('Error generating laporan: $e');
throw e.toString();
}
}
Future<String?> downloadLaporan(String laporanId) async {
try {
final response = await client
.from('laporan')
.select('file_urls')
.eq('id', laporanId)
.single();
final fileUrls = response['file_urls'];
if (fileUrls != null && fileUrls.isNotEmpty) {
return fileUrls[0];
}
return null;
} catch (e) {
print('Error downloading laporan: $e');
return null;
}
}
Future<void> deleteLaporan(String laporanId) async {
try {
await client.from('laporan').delete().eq('id', laporanId);
} catch (e) {
print('Error deleting laporan: $e');
throw e.toString();
}
}
// Metode untuk mendapatkan data warga berdasarkan user ID
Future<Map<String, dynamic>?> getWargaByUserId() async {
try {
final user = currentUser;
if (user == null) return null;
final response = await client
.from('warga')
.select('*')
.eq('user_id', user.id)
.maybeSingle();
return response;
} catch (e) {
print('Error getting warga data: $e');
return null;
}
}
// 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 {
try {
final user = currentUser;
if (user == null) throw 'User tidak ditemukan';
await client.from('warga').insert({
'user_id': user.id,
'nik': nik,
'nama_lengkap': namaLengkap,
'jenis_kelamin': jenisKelamin,
'no_hp': noHp,
'alamat': alamat,
'tempat_lahir': tempatLahir,
'tanggal_lahir': tanggalLahir?.toIso8601String(),
'agama': agama,
'status': 'MENUNGGU_VERIFIKASI',
'created_at': DateTime.now().toIso8601String(),
'updated_at': DateTime.now().toIso8601String(),
});
// Update user profile role
await client.from('user_profile').upsert({
'id': user.id,
'role': 'WARGA',
'updated_at': DateTime.now().toIso8601String(),
});
} catch (e) {
print('Error creating warga profile: $e');
throw e.toString();
}
}
// Metode untuk mendapatkan notifikasi pengguna
Future<List<Map<String, dynamic>>> getUserNotifications(
{bool unreadOnly = false}) async {
try {
final user = currentUser;
if (user == null) return [];
final query = unreadOnly
? client
.from('notifikasi')
.select('*')
.eq('user_id', user.id)
.eq('dibaca', false)
.order('created_at', ascending: false)
: client
.from('notifikasi')
.select('*')
.eq('user_id', user.id)
.order('created_at', ascending: false);
final response = await query;
return response;
} catch (e) {
print('Error getting user notifications: $e');
return [];
}
}
// Metode untuk menandai notifikasi sebagai telah dibaca
Future<void> markNotificationAsRead(int notificationId) async {
try {
await client.from('notifikasi').update({
'dibaca': true,
'updated_at': DateTime.now().toIso8601String(),
}).eq('id', notificationId);
} catch (e) {
print('Error marking notification as read: $e');
throw e.toString();
}
}
// Metode untuk mendapatkan informasi petugas desa berdasarkan ID
Future<Map<String, dynamic>?> getPetugasDesaById(String petugasDesaId) async {
try {
print('Mengambil data petugas desa dengan ID: $petugasDesaId');
// Coba ambil dari tabel user_profile dulu
final response = await client
.from('user_profile')
.select('*')
.eq('id', petugasDesaId)
.eq('role', 'PETUGASDESA')
.maybeSingle();
print('Response: $response');
if (response != null) {
print(
'Berhasil mendapatkan data petugas desa dari user_profile: $response');
return response;
}
print('Data petugas desa tidak ditemukan untuk ID: $petugasDesaId');
return null;
} catch (e) {
print('Error getting petugas desa by ID: $e');
return null;
}
}
// Metode untuk mendapatkan semua lokasi penyaluran
Future<List<Map<String, dynamic>>?> getAllLokasiPenyaluran() async {
try {
final response = await client.from('lokasi_penyaluran').select('*');
return response;
} catch (e) {
print('Error getting all lokasi penyaluran: $e');
return null;
}
}
// Metode untuk mendapatkan daftar penerima penyaluran berdasarkan ID penyaluran
Future<List<Map<String, dynamic>>?> getPenerimaPenyaluran(
String penyaluranId) async {
// Metode ini tidak lagi mengambil data dari database
// Gunakan data dummy dari controller
return [];
}
// Metode untuk memperbarui status penerimaan bantuan
Future<bool> updateStatusPenerimaan(int penerimaId, String status,
{DateTime? tanggalPenerimaan,
String? buktiPenerimaan,
String? keterangan}) async {
try {
final Map<String, dynamic> updateData = {
'status_penerimaan': status,
};
if (tanggalPenerimaan != null) {
updateData['tanggal_penerimaan'] = tanggalPenerimaan.toIso8601String();
}
if (buktiPenerimaan != null) {
updateData['bukti_penerimaan'] = buktiPenerimaan;
}
if (keterangan != null) {
updateData['keterangan'] = keterangan;
}
await client
.from('penerima_penyaluran')
.update(updateData)
.eq('id', penerimaId);
return true;
} catch (e) {
print('Error updating status penerimaan: $e');
return false;
}
}
// Metode untuk mendapatkan semua kategori bantuan
Future<List<Map<String, dynamic>>?> getAllKategoriBantuan() async {
try {
final response = await client
.from('kategori_bantuan')
.select('*')
.order('nama', ascending: true);
return response;
} catch (e) {
print('Error getting all kategori bantuan: $e');
return null;
}
}
// Metode untuk memeriksa koneksi ke Supabase
Future<bool> checkConnection() async {
try {
print('DEBUG SERVICE: Memeriksa koneksi ke Supabase...');
// Coba melakukan query sederhana
final response =
await client.from('penerima_penyaluran').select('count').limit(1);
print('DEBUG SERVICE: Koneksi berhasil, response: $response');
return true;
} catch (e) {
print('DEBUG SERVICE: Error saat memeriksa koneksi: $e');
return false;
}
}
// Metode untuk mendapatkan data warga berdasarkan ID
Future<Map<String, dynamic>?> getWargaById(String wargaId) async {
// Metode ini tidak lagi mengambil data dari database
// Gunakan data dummy
return {
'id': wargaId,
'nama_lengkap': 'Warga Dummy',
'nik': '1234567890123456',
'alamat': 'Alamat Dummy',
'jenis_kelamin': 'L',
'tanggal_lahir': '1990-01-01',
};
}
// Metode untuk mencetak struktur data ke konsol
void printDataStructure(dynamic data, {String prefix = ''}) {
if (data == null) {
print('$prefix Data: null');
return;
}
if (data is List) {
print('$prefix Data adalah List dengan ${data.length} item');
if (data.isNotEmpty) {
print('$prefix Contoh item pertama:');
printDataStructure(data.first, prefix: '$prefix ');
}
return;
}
if (data is Map<String, dynamic>) {
print(
'$prefix Data adalah Map dengan keys: ${data.keys.toList().join(', ')}');
// Cek apakah ada key warga
if (data.containsKey('warga')) {
print('$prefix Data memiliki key "warga"');
print('$prefix Tipe data warga: ${data['warga'].runtimeType}');
printDataStructure(data['warga'], prefix: '$prefix warga: ');
}
// Cek apakah ada key warga_id
if (data.containsKey('warga_id')) {
print('$prefix Data memiliki key "warga_id": ${data['warga_id']}');
}
return;
}
// Tipe data lainnya
print('$prefix Data: $data (${data.runtimeType})');
}
// Fungsi untuk menambahkan penyaluran baru
Future<Map<String, dynamic>> tambahPenyaluran(
Map<String, dynamic> penyaluran) async {
try {
final response = await client
.from('penyaluran_bantuan')
.insert(penyaluran)
.select()
.single();
return response;
} catch (e) {
print('Error menambahkan penyaluran: $e');
throw e.toString();
}
}
Future<List<Map<String, dynamic>>?> getAllSkemaBantuan() async {
try {
final response = await client
.from('xx02_skema_bantuan')
.select('*')
.order('created_at', ascending: false);
return response;
} catch (e) {
print('Error getting all skema bantuan: $e');
return null;
}
}
}