248 lines
7.0 KiB
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;
|
|
}
|
|
}
|
|
} |