TKK_E32230859/lib/app/modules/notification/controllers/notification_controller.dart

208 lines
5.7 KiB
Dart

// lib/app/modules/notification/controllers/notification_controller.dart
import 'package:get/get.dart';
import 'package:flutter/material.dart';
import 'dart:async';
import '../../../services/firestore_service.dart';
import '../../../models/notification_model.dart';
import '../../../models/patient_model.dart';
import '../../../models/room_model.dart';
class NotificationItem {
final String id;
final String title;
final String message;
final String room;
final String patientName;
final DateTime time;
final String deviceId;
final bool isRead;
NotificationItem({
required this.id,
required this.title,
required this.message,
required this.room,
required this.deviceId,
required this.patientName,
required this.time,
this.isRead = false,
});
NotificationItem copyWith({
String? id,
String? title,
String? message,
String? room,
String? patientName,
DateTime? time,
String? deviceId,
bool? isRead,
}) {
return NotificationItem(
id: id ?? this.id,
title: title ?? this.title,
message: message ?? this.message,
room: room ?? this.room,
deviceId: deviceId ?? this.deviceId,
patientName: patientName ?? this.patientName,
time: time ?? this.time,
isRead: isRead ?? this.isRead,
);
}
}
class NotificationController extends GetxController {
final FirestoreService _firestoreService = FirestoreService();
final selectedTab = 0.obs;
final _allNotifications = <NotificationItem>[].obs;
final isLoading = true.obs;
StreamSubscription? _notificationsSubscription;
@override
void onInit() {
super.onInit();
_initializeNotifications();
}
@override
void onClose() {
_notificationsSubscription?.cancel();
super.onClose();
}
/// Initialize notifications dari Firestore
void _initializeNotifications() {
isLoading.value = true;
_notificationsSubscription = _firestoreService
.getNotificationsStream()
.listen((notificationModels) async {
final List<NotificationItem> items = [];
for (var notifModel in notificationModels) {
// Get patient info
final patient = await _firestoreService.getPatientById(
notifModel.patientId,
);
// Get room name from patient's roomId
String roomName = 'Unknown Room';
if (patient != null && patient.roomId.isNotEmpty) {
final rooms = await _firestoreService.getRoomsStream().first;
final room = rooms.firstWhereOrNull(
(r) => r.roomName.toLowerCase() == patient.roomId.toLowerCase(),
);
roomName = room?.roomName ?? patient.roomId;
}
items.add(
NotificationItem(
id: notifModel.id,
title: notifModel.title,
message: notifModel.message,
room: roomName,
deviceId: notifModel.deviceId,
patientName: patient?.namePatient ?? 'Unknown Patient',
time: notifModel.createdAt,
isRead: notifModel.isRead,
),
);
}
_allNotifications.value = items;
isLoading.value = false;
}, onError: (error) {
print('Error listening to notifications: $error');
isLoading.value = false;
});
}
// Computed property untuk notifikasi yang difilter
List<NotificationItem> get notifications {
if (selectedTab.value == 0) {
// Tab "Baru" - notifikasi yang belum dibaca
return _allNotifications.where((notif) => !notif.isRead).toList();
} else {
// Tab "Sudah dibaca" - notifikasi yang sudah dibaca
return _allNotifications.where((notif) => notif.isRead).toList();
}
}
void changeTab(int index) {
selectedTab.value = index;
}
Future<void> deleteNotification(String id) async {
try {
await _firestoreService.deleteNotification(id);
// Local update akan dilakukan otomatis oleh stream
} catch (e) {
Get.snackbar(
'Error',
'Gagal menghapus notifikasi: $e',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.redAccent,
colorText: Colors.white,
margin: const EdgeInsets.all(16),
);
}
}
Future<void> markAsRead(String id) async {
try {
await _firestoreService.markNotificationAsRead(id);
// Local update akan dilakukan otomatis oleh stream
} catch (e) {
Get.snackbar(
'Error',
'Gagal menandai notifikasi: $e',
snackPosition: SnackPosition.BOTTOM,
backgroundColor: Colors.redAccent,
colorText: Colors.white,
margin: const EdgeInsets.all(16),
);
}
}
String getTimeAgo(DateTime time) {
final difference = DateTime.now().difference(time);
if (difference.inMinutes < 60) {
return '${difference.inMinutes}min ago';
} else if (difference.inHours < 24) {
return '${difference.inHours}h ago';
} else {
return '${difference.inDays}d ago';
}
}
// Method untuk menghitung jumlah notifikasi baru
int get unreadCount {
return _allNotifications.where((notif) => !notif.isRead).length;
}
/// Method untuk menambahkan notifikasi baru (bisa dipanggil dari monitoring)
Future<void> addNotification({
required String patientId,
required String deviceId,
required String title,
required String message,
}) async {
try {
final notification = NotificationModel(
id: '', // Will be auto-generated by Firestore
patientId: patientId,
deviceId: deviceId,
title: title,
message: message,
isRead: false,
createdAt: DateTime.now(),
);
await _firestoreService.addNotification(notification);
} catch (e) {
print('Error adding notification: $e');
}
}
}