773 lines
28 KiB
Dart
773 lines
28 KiB
Dart
import 'package:posyandu/services/api_service.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:posyandu/services/auth_service.dart';
|
|
import 'dart:convert';
|
|
import 'dart:math';
|
|
|
|
class AnakService {
|
|
final ApiService _apiService = ApiService();
|
|
|
|
// Singleton pattern
|
|
static final AnakService _instance = AnakService._internal();
|
|
|
|
factory AnakService() {
|
|
return _instance;
|
|
}
|
|
|
|
AnakService._internal();
|
|
|
|
/// Mendapatkan daftar anak milik pengguna yang sedang login
|
|
Future<List<dynamic>> getAnakList({bool useLocalOnly = false, bool skipLocal = false}) async {
|
|
try {
|
|
// Dapatkan user_id dari SharedPreferences
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final userId = prefs.getInt('user_id');
|
|
final nik = prefs.getString('nik');
|
|
final token = prefs.getString('token');
|
|
|
|
print('Mencoba mendapatkan data anak: user_id=$userId, nik=$nik, token=${token != null ? "ada" : "tidak ada"}');
|
|
|
|
if (userId == null) {
|
|
throw Exception('User ID tidak ditemukan. Silakan login terlebih dahulu.');
|
|
}
|
|
|
|
List<dynamic> anakList = [];
|
|
bool success = false;
|
|
|
|
// Dapatkan data lokal hanya jika tidak skip
|
|
List<dynamic> localAnakList = skipLocal ? [] : await getLocalAnakList();
|
|
if (!skipLocal) {
|
|
print('Data anak lokal: ${localAnakList.length} item');
|
|
|
|
// Jika ada data lokal, tampilkan info debug
|
|
if (localAnakList.isNotEmpty) {
|
|
print('Contoh data lokal pertama: ${localAnakList[0]['nama_anak']} (${localAnakList[0]['tanggal_lahir']})');
|
|
}
|
|
}
|
|
|
|
// Jika diminta hanya menggunakan data lokal
|
|
if (useLocalOnly) {
|
|
print('Hanya menggunakan data lokal sesuai permintaan');
|
|
return localAnakList;
|
|
}
|
|
|
|
// Jika tidak ada koneksi atau token, gunakan data lokal saja
|
|
if (token == null) {
|
|
print('Tidak ada token, menggunakan data lokal saja');
|
|
return localAnakList;
|
|
}
|
|
|
|
// Opsi 1: Coba endpoint standard
|
|
try {
|
|
print('Mencoba endpoint standard: anak');
|
|
final response = await _apiService.get('anak');
|
|
|
|
if (response['status'] == 'success' || response['success'] == true) {
|
|
anakList = response['data'] ?? [];
|
|
print('Berhasil mendapatkan ${anakList.length} data anak dari endpoint standard');
|
|
|
|
// Tampilkan contoh data dari API
|
|
if (anakList.isNotEmpty) {
|
|
print('Contoh data API pertama: ${anakList[0]['nama_anak']} (${anakList[0]['tanggal_lahir']})');
|
|
}
|
|
|
|
success = true;
|
|
}
|
|
} catch (e) {
|
|
print('Endpoint standard gagal: $e');
|
|
}
|
|
|
|
// Opsi 2: Jika opsi 1 gagal, coba endpoint mobile
|
|
if (!success) {
|
|
try {
|
|
print('Mencoba endpoint mobile: mobile/anak/pengguna/$userId');
|
|
final response = await _apiService.get('mobile/anak/pengguna/$userId');
|
|
|
|
if (response['status'] == 'success' || response['success'] == true) {
|
|
anakList = response['data'] ?? [];
|
|
print('Berhasil mendapatkan ${anakList.length} data anak dari endpoint mobile');
|
|
success = true;
|
|
}
|
|
} catch (e) {
|
|
print('Endpoint mobile gagal: $e');
|
|
}
|
|
}
|
|
|
|
// Opsi 3: Jika semua gagal dan kita memiliki NIK, coba endpoint berdasarkan NIK
|
|
if (!success && nik != null) {
|
|
try {
|
|
print('Mencoba endpoint berdasarkan NIK: anak/pengguna/nik/$nik');
|
|
final response = await _apiService.get('anak/pengguna/nik/$nik');
|
|
|
|
if (response['status'] == 'success' || response['success'] == true) {
|
|
anakList = response['data'] ?? [];
|
|
print('Berhasil mendapatkan ${anakList.length} data anak dari endpoint NIK');
|
|
success = true;
|
|
}
|
|
} catch (e) {
|
|
print('Endpoint NIK gagal: $e');
|
|
}
|
|
}
|
|
|
|
// Jika berhasil mendapatkan data dari API dan skipLocal=true, langsung kembalikan data API
|
|
if (success && anakList.isNotEmpty && skipLocal) {
|
|
print('Mengembalikan hanya data dari API: ${anakList.length} data');
|
|
return anakList;
|
|
}
|
|
|
|
// Gabungkan data dari API dan lokal jika API berhasil dan tidak skip lokal
|
|
if (success && anakList.isNotEmpty && !skipLocal) {
|
|
print('Menggabungkan ${anakList.length} data dari API dengan ${localAnakList.length} data lokal');
|
|
final combinedList = await _combineAnakLists(anakList, localAnakList);
|
|
|
|
print('Setelah penggabungan: ${combinedList.length} data anak');
|
|
|
|
// Debug: tampilkan beberapa data setelah penggabungan
|
|
if (combinedList.isNotEmpty) {
|
|
for (int i = 0; i < min(3, combinedList.length); i++) {
|
|
print('Data #${i+1}: ${combinedList[i]['nama_anak']} (${combinedList[i]['tanggal_lahir']})');
|
|
}
|
|
}
|
|
|
|
// Jika ada data dari API, tambahkan informasi pengguna
|
|
if (anakList.isNotEmpty) {
|
|
print('Sample anak data API: ${anakList[0]}');
|
|
|
|
if (anakList[0]['pengguna'] != null) {
|
|
print('Pengguna data available: ${anakList[0]['pengguna']}');
|
|
} else {
|
|
print('Pengguna data not available in response');
|
|
|
|
// Coba ambil data parent secara terpisah
|
|
try {
|
|
final penggunaData = await getPenggunaById(userId);
|
|
print('Berhasil mendapatkan data parent: $penggunaData');
|
|
|
|
// Simpan ke SharedPreferences untuk digunakan di seluruh aplikasi
|
|
if (penggunaData != null) {
|
|
await prefs.setString('nik', penggunaData['nik'] ?? '');
|
|
await prefs.setString('nama_ibu', penggunaData['nama'] ?? '');
|
|
print('Data parent disimpan ke SharedPreferences');
|
|
}
|
|
} catch (e) {
|
|
print('Gagal mendapatkan data parent: $e');
|
|
}
|
|
}
|
|
}
|
|
|
|
return combinedList;
|
|
}
|
|
|
|
// Jika semua endpoint gagal, gunakan data lokal
|
|
if (!success) {
|
|
print('Semua endpoint API gagal, menggunakan data lokal: ${localAnakList.length} item');
|
|
return localAnakList;
|
|
}
|
|
|
|
return anakList;
|
|
} catch (e) {
|
|
print('Error saat mengambil data anak: $e');
|
|
|
|
// Jika terjadi error, coba gunakan data lokal
|
|
try {
|
|
final localAnakList = await getLocalAnakList();
|
|
print('Menggunakan data lokal karena error: ${localAnakList.length} item');
|
|
return localAnakList;
|
|
} catch (localError) {
|
|
print('Error saat mengakses data lokal: $localError');
|
|
return [];
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Mendapatkan detail data anak berdasarkan ID
|
|
Future<Map<String, dynamic>> getAnakDetail(int anakId) async {
|
|
try {
|
|
// Endpoint sudah menggunakan with('pengguna') di Laravel
|
|
final response = await _apiService.get('anak/$anakId');
|
|
|
|
if (response['status'] == 'success' || response['success'] == true) {
|
|
final anakData = response['data'];
|
|
print('Detail anak: $anakData');
|
|
|
|
return anakData;
|
|
} else {
|
|
throw Exception(response['message'] ?? 'Gagal mendapatkan detail anak');
|
|
}
|
|
} catch (e) {
|
|
throw Exception('Error: $e');
|
|
}
|
|
}
|
|
|
|
/// Menambahkan data anak baru
|
|
Future<Map<String, dynamic>> createAnak({
|
|
required String namaAnak,
|
|
required String tempatLahir,
|
|
required DateTime tanggalLahir,
|
|
required String jenisKelamin,
|
|
}) async {
|
|
try {
|
|
// Dapatkan ID pengguna dari SharedPreferences
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final userId = prefs.getInt('user_id'); // Pastikan menyimpan sebagai int
|
|
|
|
print('Menyimpan data anak...');
|
|
print('UserId from SharedPreferences: $userId');
|
|
|
|
int? penggunaId;
|
|
|
|
// Pastikan user_id tersedia
|
|
if (userId == null) {
|
|
print('User ID tidak ditemukan di SharedPreferences - mencoba get user data');
|
|
try {
|
|
// Menggunakan /api/user endpoint untuk mendapatkan data user yang terautentikasi
|
|
final userData = await _apiService.get('user');
|
|
print('User data response: $userData');
|
|
|
|
if ((userData['status'] == 'success' || userData['success'] == true) && userData['pengguna'] != null) {
|
|
penggunaId = userData['pengguna']['id'];
|
|
// Simpan user_id untuk penggunaan selanjutnya
|
|
await prefs.setInt('user_id', penggunaId!);
|
|
print('ID pengguna berhasil didapatkan dari API: $penggunaId');
|
|
} else {
|
|
throw Exception('Gagal mendapatkan data pengguna dari API');
|
|
}
|
|
} catch (e) {
|
|
print('Gagal mendapatkan data pengguna: $e');
|
|
|
|
// Jika masih gagal, coba tambahkan alternatif login:
|
|
print('Mencoba login ulang secara otomatis');
|
|
try {
|
|
final nik = prefs.getString('nik');
|
|
final authService = AuthService();
|
|
if (nik != null) {
|
|
print('Mencoba login otomatis dengan NIK: $nik');
|
|
// Coba login ulang dengan password default (misal 'password')
|
|
// CATATAN: Ini hanya solusi sementara dan tidak aman untuk produksi
|
|
// Alternatif lain adalah mengarahkan pengguna ke layar login
|
|
// await authService.login(nik: nik, password: 'password');
|
|
throw Exception('Silakan login kembali');
|
|
} else {
|
|
throw Exception('Data login tidak tersedia');
|
|
}
|
|
} catch (loginError) {
|
|
throw Exception('Gagal mendapatkan ID pengguna, silakan login kembali');
|
|
}
|
|
}
|
|
} else {
|
|
penggunaId = userId;
|
|
}
|
|
|
|
// Hitung usia dalam bulan dan hari
|
|
String usia = _calculateAge(tanggalLahir);
|
|
|
|
// Format data untuk API
|
|
final Map<String, dynamic> data = {
|
|
'pengguna_id': penggunaId,
|
|
'nama_anak': namaAnak,
|
|
'tempat_lahir': tempatLahir,
|
|
'tanggal_lahir': DateFormat('yyyy-MM-dd').format(tanggalLahir),
|
|
'jenis_kelamin': jenisKelamin,
|
|
'usia': usia,
|
|
};
|
|
|
|
print('Mengirim data anak: $data');
|
|
|
|
try {
|
|
// Gunakan metode post khusus dengan header tambahan
|
|
final response = await _apiService.post('anak', data);
|
|
|
|
// Debug informasi respons
|
|
print('Response full: $response');
|
|
print('Response keys: ${response.keys.toList()}');
|
|
|
|
// API bisa menggunakan 'status' atau 'success'
|
|
if (response['status'] == 'success' || response['success'] == true) {
|
|
// Jika API berhasil, JANGAN simpan data lokal, karena nanti saat getAnakList
|
|
// data ini sudah akan diambil dari server
|
|
// HAPUS: await _saveAnakToLocalStorage(data);
|
|
|
|
// Hapus data duplikat dengan nama dan tanggal lahir yang sama
|
|
await _removeDuplicateLocalAnak(data['nama_anak'], data['tanggal_lahir']);
|
|
|
|
return response;
|
|
} else if (response['status'] == 'error' && response['message'] == 'Gagal autentikasi untuk endpoint anak') {
|
|
// Jika autentikasi gagal tapi data valid, simpan secara lokal dan beri tahu user
|
|
print('Menyimpan data anak secara lokal karena autentikasi gagal');
|
|
await _saveAnakToLocalStorage(data);
|
|
|
|
// Kembalikan respons berhasil (simulasi) dengan informasi tambahan
|
|
return {
|
|
'status': 'success',
|
|
'message': 'Data disimpan secara lokal, akan tersinkronisasi saat terhubung ke server',
|
|
'data': data,
|
|
'is_local_only': true,
|
|
};
|
|
} else {
|
|
throw Exception(response['message'] ?? 'Gagal menyimpan data anak');
|
|
}
|
|
} catch (apiError) {
|
|
print('Error dari API: $apiError');
|
|
|
|
// Jika API error tapi data valid, simpan secara lokal
|
|
await _saveAnakToLocalStorage(data);
|
|
|
|
return {
|
|
'status': 'success',
|
|
'message': 'Data disimpan secara lokal, akan tersinkronisasi saat terhubung ke server',
|
|
'data': data,
|
|
'is_local_only': true,
|
|
};
|
|
}
|
|
} catch (e) {
|
|
print('Error dari API: $e');
|
|
throw Exception('Gagal mengirim data ke server: $e');
|
|
}
|
|
}
|
|
|
|
/// Menghapus data anak yang duplikat dari storage lokal berdasarkan nama dan tanggal lahir
|
|
Future<void> _removeDuplicateLocalAnak(String namaAnak, String tanggalLahir) async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final anakListJson = prefs.getString('local_anak_list') ?? '[]';
|
|
List<dynamic> anakList = jsonDecode(anakListJson);
|
|
|
|
// Filter out anak dengan nama dan tanggal lahir yang sama
|
|
final filteredList = anakList.where((anak) =>
|
|
!(anak['nama_anak'] == namaAnak &&
|
|
anak['tanggal_lahir'].toString().startsWith(tanggalLahir))).toList();
|
|
|
|
if (anakList.length != filteredList.length) {
|
|
print('Menghapus ${anakList.length - filteredList.length} data duplikat dari penyimpanan lokal');
|
|
await prefs.setString('local_anak_list', jsonEncode(filteredList));
|
|
}
|
|
} catch (e) {
|
|
print('Error saat menghapus data duplikat: $e');
|
|
}
|
|
}
|
|
|
|
/// Menyimpan data anak ke storage lokal sebagai fallback
|
|
Future<void> _saveAnakToLocalStorage(Map<String, dynamic> anakData) async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final anakListJson = prefs.getString('local_anak_list') ?? '[]';
|
|
List<dynamic> anakList = jsonDecode(anakListJson);
|
|
|
|
// Generate ID lokal jika tidak ada
|
|
if (!anakData.containsKey('id')) {
|
|
anakData['id'] = DateTime.now().millisecondsSinceEpoch;
|
|
}
|
|
|
|
// Tandai sebagai disimpan secara lokal
|
|
anakData['is_local'] = true;
|
|
anakData['created_at'] = DateTime.now().toIso8601String();
|
|
|
|
// Periksa apakah data sudah ada (berdasarkan nama dan tanggal lahir)
|
|
bool isDuplicate = anakList.any((anak) =>
|
|
anak['nama_anak'] == anakData['nama_anak'] &&
|
|
anak['tanggal_lahir'].toString().startsWith(anakData['tanggal_lahir'].toString()));
|
|
|
|
if (isDuplicate) {
|
|
print('Data dengan nama "${anakData['nama_anak']}" dan tanggal lahir "${anakData['tanggal_lahir']}" sudah ada, tidak disimpan ulang');
|
|
return;
|
|
}
|
|
|
|
// Tambahkan ke list
|
|
anakList.add(anakData);
|
|
|
|
// Simpan kembali ke SharedPreferences
|
|
await prefs.setString('local_anak_list', jsonEncode(anakList));
|
|
print('Data anak berhasil disimpan secara lokal: ${anakData['nama_anak']}');
|
|
} catch (e) {
|
|
print('Error menyimpan data anak secara lokal: $e');
|
|
}
|
|
}
|
|
|
|
/// Mendapatkan daftar anak dari storage lokal
|
|
Future<List<dynamic>> getLocalAnakList() async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final anakListJson = prefs.getString('local_anak_list') ?? '[]';
|
|
List<dynamic> anakList = jsonDecode(anakListJson);
|
|
|
|
print('Mendapatkan ${anakList.length} data anak dari penyimpanan lokal');
|
|
return anakList;
|
|
} catch (e) {
|
|
print('Error mendapatkan data anak lokal: $e');
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/// Menggabungkan data anak dari API dan local storage
|
|
Future<List<dynamic>> _combineAnakLists(List<dynamic> apiList, List<dynamic> localList) async {
|
|
// Gabungkan kedua list, prioritaskan data dari API
|
|
final Map<String, dynamic> combinedMap = {};
|
|
|
|
// Tambahkan data dari API terlebih dahulu (prioritas utama)
|
|
for (var anak in apiList) {
|
|
// Gunakan ID sebagai kunci untuk menghindari duplikasi
|
|
if (anak['id'] != null) {
|
|
String key = 'id_${anak['id']}';
|
|
combinedMap[key] = anak;
|
|
} else {
|
|
// Jika tidak ada ID, gunakan kombinasi nama dan tanggal
|
|
String tanggalKey = anak['tanggal_lahir'].toString().split('T')[0]; // Ambil hanya bagian tanggal
|
|
String key = 'name_${anak['nama_anak']}_${tanggalKey}';
|
|
combinedMap[key] = anak;
|
|
}
|
|
}
|
|
|
|
// Tambahkan data lokal HANYA jika belum ada data yang sama dari API
|
|
for (var anak in localList) {
|
|
// Periksa apakah anak ini sudah ada di API berdasarkan nama dan tanggal
|
|
bool alreadyExists = false;
|
|
|
|
// Jika ada ID di data lokal (mungkin dari sinkronisasi sebelumnya)
|
|
if (anak['id'] != null) {
|
|
String idKey = 'id_${anak['id']}';
|
|
if (combinedMap.containsKey(idKey)) {
|
|
alreadyExists = true;
|
|
}
|
|
}
|
|
|
|
// Jika belum ada, periksa berdasarkan nama dan tanggal
|
|
if (!alreadyExists) {
|
|
String tanggalKey = anak['tanggal_lahir'].toString().split('T')[0];
|
|
bool found = false;
|
|
|
|
for (var key in combinedMap.keys) {
|
|
var existingAnak = combinedMap[key];
|
|
String existingTanggal = existingAnak['tanggal_lahir'].toString().split('T')[0];
|
|
|
|
if (existingAnak['nama_anak'] == anak['nama_anak'] &&
|
|
existingTanggal == tanggalKey) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Jika benar-benar tidak ada di API, tambahkan dari lokal
|
|
if (!found) {
|
|
String key = 'local_${DateTime.now().millisecondsSinceEpoch}_${anak['nama_anak']}';
|
|
combinedMap[key] = anak;
|
|
}
|
|
}
|
|
}
|
|
|
|
print('Total data setelah penggabungan: ${combinedMap.length}');
|
|
return combinedMap.values.toList();
|
|
}
|
|
|
|
/// Memperbarui data anak yang sudah ada
|
|
Future<Map<String, dynamic>> updateAnak({
|
|
required int anakId,
|
|
required String namaAnak,
|
|
required String tempatLahir,
|
|
required DateTime tanggalLahir,
|
|
required String jenisKelamin,
|
|
}) async {
|
|
try {
|
|
// Dapatkan ID pengguna dari SharedPreferences untuk logging
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final userId = prefs.getInt('user_id');
|
|
|
|
print('Updating anak with ID: $anakId by user ID: $userId');
|
|
|
|
// Hitung usia dalam bulan dan hari
|
|
String usia = _calculateAge(tanggalLahir);
|
|
|
|
// Format data untuk API
|
|
final Map<String, dynamic> data = {
|
|
'nama_anak': namaAnak,
|
|
'tempat_lahir': tempatLahir,
|
|
'tanggal_lahir': DateFormat('yyyy-MM-dd').format(tanggalLahir),
|
|
'jenis_kelamin': jenisKelamin,
|
|
'usia': usia,
|
|
};
|
|
|
|
final response = await _apiService.put('anak/$anakId', data);
|
|
|
|
// API menggunakan 'status' bukan 'success'
|
|
if (response['status'] == 'success' || response['success'] == true) {
|
|
return response;
|
|
} else {
|
|
throw Exception(response['message'] ?? 'Gagal memperbarui data anak');
|
|
}
|
|
} catch (e) {
|
|
throw Exception('Error: $e');
|
|
}
|
|
}
|
|
|
|
/// Menghapus data anak
|
|
Future<bool> deleteAnak(int anakId) async {
|
|
try {
|
|
final response = await _apiService.delete('anak/$anakId');
|
|
|
|
// API menggunakan 'status' bukan 'success'
|
|
if (response['status'] == 'success' || response['success'] == true) {
|
|
return true;
|
|
} else {
|
|
throw Exception(response['message'] ?? 'Gagal menghapus data anak');
|
|
}
|
|
} catch (e) {
|
|
throw Exception('Error: $e');
|
|
}
|
|
}
|
|
|
|
/// Mengaitkan anak dengan orang tua berdasarkan NIK
|
|
Future<Map<String, dynamic>> linkAnakToParent({
|
|
required int anakId,
|
|
required String nik,
|
|
}) async {
|
|
try {
|
|
final Map<String, dynamic> data = {
|
|
'anak_id': anakId,
|
|
'nik': nik,
|
|
};
|
|
|
|
final response = await _apiService.post('anak/link-to-parent', data);
|
|
|
|
if (response['status'] == 'success' || response['success'] == true) {
|
|
return response;
|
|
} else {
|
|
throw Exception(response['message'] ?? 'Gagal mengaitkan anak dengan orang tua');
|
|
}
|
|
} catch (e) {
|
|
throw Exception('Error: $e');
|
|
}
|
|
}
|
|
|
|
/// Fungsi untuk menghitung usia dalam bulan dari tanggal lahir
|
|
String _calculateAge(DateTime birthDate) {
|
|
DateTime currentDate = DateTime.now();
|
|
|
|
// Hitung total usia dalam hari
|
|
int totalDays = currentDate.difference(birthDate).inDays;
|
|
|
|
// Konversi ke bulan dan hari
|
|
int months = totalDays ~/ 30; // Aproximasi 1 bulan = 30 hari
|
|
int days = totalDays % 30;
|
|
|
|
return '$months bulan $days hari'; // Return format bulan dan hari
|
|
}
|
|
|
|
/// Memperbaiki data ibu yang kosong
|
|
Future<void> fixParentData() async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final nik = prefs.getString('nik');
|
|
final namaIbu = prefs.getString('nama_ibu');
|
|
|
|
// Jika nama ibu kosong tapi NIK ada, coba dapatkan dari API
|
|
if ((namaIbu == null || namaIbu.isEmpty) && nik != null && nik.isNotEmpty) {
|
|
print('Nama ibu kosong, mencoba dapatkan dari API berdasarkan NIK: $nik');
|
|
|
|
try {
|
|
// Coba cari pengguna berdasarkan NIK
|
|
final response = await _apiService.get('user');
|
|
|
|
if (response['success'] == true || response['status'] == 'success') {
|
|
final pengguna = response['pengguna'] ?? response['data'];
|
|
if (pengguna != null) {
|
|
// Nama bisa berupa nama atau nama_ibu
|
|
final nama = pengguna['nama'] ?? pengguna['nama_ibu'] ?? 'Ibu';
|
|
|
|
// Update SharedPreferences
|
|
await prefs.setString('nama_ibu', nama);
|
|
print('Berhasil update nama ibu: $nama');
|
|
|
|
// Juga update NIK jika kosong
|
|
if (nik.isEmpty && pengguna.containsKey('nik')) {
|
|
await prefs.setString('nik', pengguna['nik']);
|
|
}
|
|
|
|
// Juga update user_id jika belum ada
|
|
if (pengguna.containsKey('id') && prefs.getInt('user_id') == null) {
|
|
await prefs.setInt('user_id', pengguna['id']);
|
|
}
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print('Gagal mendapatkan data ibu dari API: $e');
|
|
|
|
// Fallback: gunakan default jika masih kosong
|
|
if (namaIbu == null || namaIbu.isEmpty) {
|
|
await prefs.setString('nama_ibu', 'Ibu');
|
|
print('Menggunakan nama default: Ibu');
|
|
}
|
|
}
|
|
} else if (namaIbu == null || namaIbu.isEmpty) {
|
|
// Jika nama ibu masih kosong, tetapkan ke "Ibu"
|
|
await prefs.setString('nama_ibu', 'Ibu');
|
|
print('Menggunakan nama default: Ibu karena nama_ibu kosong');
|
|
}
|
|
} catch (e) {
|
|
print('Error saat memperbaiki data ibu: $e');
|
|
}
|
|
}
|
|
|
|
/// Mendapatkan data pengguna (parent) dari SharedPreferences
|
|
Future<Map<String, dynamic>> getParentFromPrefs() async {
|
|
try {
|
|
// Coba perbaiki data yang kosong terlebih dahulu
|
|
await fixParentData();
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final userId = prefs.getInt('user_id');
|
|
final nik = prefs.getString('nik') ?? 'Tidak tersedia';
|
|
final namaIbu = prefs.getString('nama_ibu') ?? 'Ibu';
|
|
|
|
print('Data parent dari SharedPreferences setelah perbaikan: userId=$userId, nik=$nik, nama=$namaIbu');
|
|
|
|
// Pastikan namaIbu tidak kosong
|
|
if (namaIbu.isEmpty) {
|
|
await prefs.setString('nama_ibu', 'Ibu');
|
|
}
|
|
|
|
return {
|
|
'id': userId ?? 0,
|
|
'nik': nik,
|
|
'nama': namaIbu.isEmpty ? 'Ibu' : namaIbu,
|
|
};
|
|
} catch (e) {
|
|
print('Error mendapatkan data parent dari SharedPreferences: $e');
|
|
return {
|
|
'id': 0,
|
|
'nik': 'Tidak tersedia',
|
|
'nama': 'Ibu',
|
|
};
|
|
}
|
|
}
|
|
|
|
/// Mendapatkan data pengguna berdasarkan ID
|
|
Future<Map<String, dynamic>?> getPenggunaById(int penggunaId) async {
|
|
try {
|
|
// Ubah endpoint dari pengguna/{id} menjadi pengguna/detail/{id}
|
|
// Sesuaikan dengan path yang benar dari Laravel API
|
|
print('Mencoba mendapatkan data pengguna dengan ID: $penggunaId');
|
|
|
|
// Coba langsung endpoint user yang sudah terbukti berfungsi
|
|
try {
|
|
print('Menggunakan endpoint user untuk mendapatkan data pengguna');
|
|
final response = await _apiService.get('user');
|
|
|
|
if (response['success'] == true || response['status'] == 'success') {
|
|
// Data pengguna mungkin berada di 'pengguna' atau 'data'
|
|
final penggunaData = response['pengguna'] ?? response['data'];
|
|
|
|
if (penggunaData != null) {
|
|
print('Response pengguna dari endpoint user: $penggunaData');
|
|
|
|
// Normalkan nama field yang berbeda-beda
|
|
// Field nama bisa berupa 'nama' atau 'nama_ibu'
|
|
final Map<String, dynamic> normalizedData = {
|
|
'id': penggunaData['id'],
|
|
'nik': penggunaData['nik'],
|
|
'nama': penggunaData['nama'] ?? penggunaData['nama_ibu'] ?? 'Ibu',
|
|
};
|
|
|
|
print('Data pengguna yang dinormalisasi: $normalizedData');
|
|
return normalizedData;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print('Error saat mengakses endpoint user: $e');
|
|
}
|
|
|
|
// Endpoint alternatif jika user tidak berhasil
|
|
print('Tidak bisa mendapatkan data pengguna dari endpoint utama, mencoba alternatif');
|
|
|
|
// Coba gunakan beberapa alternatif endpoint
|
|
final endpoints = [
|
|
'pengguna/detail/$penggunaId',
|
|
'user/profile',
|
|
'profile'
|
|
];
|
|
|
|
for (String endpoint in endpoints) {
|
|
try {
|
|
print('Mencoba endpoint: $endpoint');
|
|
final response = await _apiService.get(endpoint);
|
|
|
|
if (response['success'] == true || response['status'] == 'success') {
|
|
// Data pengguna mungkin berada di 'pengguna' atau 'data'
|
|
final penggunaData = response['pengguna'] ?? response['data'];
|
|
|
|
if (penggunaData != null) {
|
|
print('Berhasil mendapatkan data pengguna dari endpoint $endpoint: $penggunaData');
|
|
|
|
// Normalkan nama field
|
|
final Map<String, dynamic> normalizedData = {
|
|
'id': penggunaData['id'],
|
|
'nik': penggunaData['nik'],
|
|
'nama': penggunaData['nama'] ?? penggunaData['nama_ibu'] ?? 'Ibu',
|
|
};
|
|
|
|
return normalizedData;
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print('Endpoint $endpoint error: $e');
|
|
continue;
|
|
}
|
|
}
|
|
|
|
print('Semua endpoint gagal, gunakan default data');
|
|
// Return default data jika tidak bisa mendapatkan dari server
|
|
return {
|
|
'id': penggunaId,
|
|
'nik': 'Data tidak tersedia',
|
|
'nama': 'Ibu', // Default ke 'Ibu' bukan 'Data tidak tersedia'
|
|
};
|
|
} catch (e) {
|
|
print('Error mendapatkan data pengguna: $e');
|
|
return {
|
|
'id': penggunaId,
|
|
'nik': 'Data tidak tersedia',
|
|
'nama': 'Ibu', // Default ke 'Ibu'
|
|
};
|
|
}
|
|
}
|
|
|
|
/// Mendapatkan detail pengguna berdasarkan ID
|
|
Future<Map<String, dynamic>> getPenggunaDetail(int penggunaId) async {
|
|
try {
|
|
// Coba gunakan method getPenggunaById yang lebih robust
|
|
Map<String, dynamic>? data = await getPenggunaById(penggunaId);
|
|
|
|
if (data != null) {
|
|
return data;
|
|
}
|
|
|
|
// Fallback jika gagal
|
|
return {
|
|
'id': penggunaId,
|
|
'nama': 'Data tidak tersedia',
|
|
'nik': 'Data tidak tersedia',
|
|
};
|
|
} catch (e) {
|
|
print('Error mendapatkan detail pengguna: $e');
|
|
// Return minimal data jika gagal
|
|
return {
|
|
'id': penggunaId,
|
|
'nama': 'Data tidak tersedia',
|
|
'nik': 'Data tidak tersedia',
|
|
};
|
|
}
|
|
}
|
|
|
|
// Tambahkan fungsi untuk menghapus semua data anak lokal
|
|
Future<bool> clearAllLocalAnakData() async {
|
|
try {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString('local_anak_list', '[]');
|
|
print('Semua data anak lokal telah dihapus');
|
|
return true;
|
|
} catch (e) {
|
|
print('Error saat menghapus data lokal: $e');
|
|
return false;
|
|
}
|
|
}
|
|
}
|