NIM_E31222534/Androidnya/lib/controllers/vitamin_controller.dart

248 lines
7.0 KiB
Dart

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../models/vitamin_model.dart';
import '../services/vitamin_service.dart';
class VitaminController {
final VitaminService _vitaminService = VitaminService();
List<Vitamin> _vitaminList = [];
Map<String, dynamic>? _anakData;
int? anakId;
bool _isLoading = false;
String? _error;
// Key for caching data
static const String _cacheKeyPrefix = 'vitamin_data_';
static const String _anakDataCacheKeyPrefix = 'anak_data_';
// Getters
List<Vitamin> get vitaminList => _vitaminList;
Map<String, dynamic>? get anakData => _anakData;
bool get isLoading => _isLoading;
String? get error => _error;
// Constructor
VitaminController() {
// Tidak perlu inisialisasi data default
}
// Fetch vitamin data for a specific child
Future<void> fetchVitaminData(int childId) async {
_isLoading = true;
_error = null;
anakId = childId;
try {
// Cek dulu apakah anak ada
try {
await fetchAnakData(childId);
} catch (e) {
_isLoading = false;
throw Exception('Silakan tambahkan data anak terlebih dahulu');
}
final vitaminData = await _vitaminService.getVitaminByAnakId(childId);
_vitaminList = vitaminData.map((data) {
return Vitamin(
id: data['id'] ?? 0,
jenis: data['jenis_vitamin']?['nama'] ?? 'Tidak diketahui',
tanggal: data['tanggal'] ?? '',
status: data['status'] ?? 'Belum',
lokasi: data['lokasi'] ?? 'Posyandu',
usia: data['usia'] ?? 'Tidak diketahui',
color: _getColorForVitamin(data['jenis_vitamin']?['nama'] ?? ''),
deskripsi: data['deskripsi'] ?? 'Tidak ada deskripsi',
manfaat: data['manfaat'] ?? 'Tidak ada informasi manfaat',
);
}).toList();
_isLoading = false;
} catch (e) {
print('Error fetching vitamin data: $e');
_isLoading = false;
_error = e.toString();
_vitaminList = [];
throw e;
}
}
// Fetch anak data
Future<void> fetchAnakData(int childId) async {
try {
_anakData = await _vitaminService.getAnakData(childId);
} catch (e) {
_anakData = null;
throw e;
}
}
// Update vitamin status
Future<bool> updateVitaminStatus(int vitaminId, String newStatus) async {
try {
final updatedVitamin = await _vitaminService.updateVitaminStatus(
vitaminId,
newStatus
);
// Update local list
final index = _vitaminList.indexWhere((v) => v.id == vitaminId);
if (index != -1) {
_vitaminList[index] = Vitamin.fromJson(updatedVitamin);
}
// Update cache
if (anakId != null) {
await _refreshCachedVitaminData(anakId!);
}
return true;
} catch (e) {
print('Error updating vitamin status: $e');
return false;
}
}
// Get count by status
int getCountByStatus(String status) {
if (_vitaminList.isEmpty) return 0;
try {
if (status == 'Sudah') {
return _vitaminList.where((v) =>
v.status == 'Sudah' ||
v.status.toLowerCase().contains('sudah') ||
v.status.toLowerCase().contains('selesai')
).length;
}
return _vitaminList.where((v) => v.status == status).length;
} catch (e) {
print('Error in getCountByStatus: $e');
return 0;
}
}
// Get child age from anak data
String getChildAge() {
if (_anakData == null) return '';
if (_anakData!.containsKey('umur_bulan') && _anakData!['umur_bulan'] != null) {
return '${_anakData!['umur_bulan']} bulan';
}
if (_anakData!.containsKey('umur_hari') && _anakData!['umur_hari'] != null) {
final hari = _anakData!['umur_hari'];
if (hari >= 30) {
final bulan = (hari / 30).floor();
return '$bulan bulan';
}
return '$hari hari';
}
return '';
}
// Helper method to get color based on vitamin type
Color _getColorForVitamin(String jenis) {
if (jenis.isEmpty) return Colors.grey;
switch (jenis.toLowerCase()) {
case 'vitamin a':
case 'a biru':
case 'a merah':
return Colors.orange.shade700;
case 'vitamin b':
case 'b kompleks':
return Colors.green.shade700;
case 'vitamin c':
return Colors.yellow.shade700;
case 'vitamin d':
return Colors.purple.shade700;
case 'zat besi':
return Colors.red.shade700;
default:
return Colors.blue.shade700;
}
}
// Cache vitamin data
Future<void> _cacheVitaminData(int childId, List<dynamic> data) async {
try {
final prefs = await SharedPreferences.getInstance();
final cacheKey = '$_cacheKeyPrefix$childId';
// Convert data to JSON string
final dataStr = jsonEncode(data);
// Save to SharedPreferences
await prefs.setString(cacheKey, dataStr);
print('Cached vitamin data for child ID: $childId');
} catch (e) {
print('Error caching vitamin data: $e');
}
}
// Get cached vitamin data
Future<List<dynamic>?> _getCachedVitaminData(int childId) async {
try {
final prefs = await SharedPreferences.getInstance();
final cacheKey = '$_cacheKeyPrefix$childId';
final dataStr = prefs.getString(cacheKey);
if (dataStr != null) {
// Parse the string back to list of maps
return jsonDecode(dataStr) as List<dynamic>;
}
return null;
} catch (e) {
print('Error retrieving cached vitamin data: $e');
return null;
}
}
// Update cached vitamin data after a change
Future<void> _refreshCachedVitaminData(int childId) async {
try {
final apiData = await _vitaminService.getVitaminByAnakId(childId);
await _cacheVitaminData(childId, apiData);
} catch (e) {
print('Error refreshing cached vitamin data: $e');
}
}
// Cache anak data
Future<void> _cacheAnakData(int childId, Map<String, dynamic> data) async {
try {
final prefs = await SharedPreferences.getInstance();
final cacheKey = '$_anakDataCacheKeyPrefix$childId';
// Convert data to JSON string
final dataStr = jsonEncode(data);
// Save to SharedPreferences
await prefs.setString(cacheKey, dataStr);
print('Cached anak data for child ID: $childId');
} catch (e) {
print('Error caching anak data: $e');
}
}
// Get cached anak data
Future<Map<String, dynamic>?> _getCachedAnakData(int childId) async {
try {
final prefs = await SharedPreferences.getInstance();
final cacheKey = '$_anakDataCacheKeyPrefix$childId';
final dataStr = prefs.getString(cacheKey);
if (dataStr != null) {
// Parse the string back to map
return jsonDecode(dataStr) as Map<String, dynamic>;
}
return null;
} catch (e) {
print('Error retrieving cached anak data: $e');
return null;
}
}
}