import 'dart:convert'; import 'package:flutter/cupertino.dart'; import 'package:http/http.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/models/notification_filter_model.dart'; import 'package:test_sa/models/system_notification_model.dart'; import 'package:test_sa/models/user.dart'; class NotificationsProvider extends ChangeNotifier { // number of items call in each request final pageItemNumber = 12; // Store active filters NotificationFilterModel? activeFilters; // Store notification counts from API int totalAllNotifications = 0; int totalNotificationRead = 0; int totalNotificationUnread = 0; int totalRows = 0; // Total number of items available in the database //reset provider data void reset() { notifications = []; nextPage = true; stateCode = null; totalAllNotifications = 0; totalNotificationRead = 0; totalNotificationUnread = 0; totalRows = 0; } // state code of current request to defied error message // like 400 customer request failed// 500 service not available int? stateCode; // true if there is next page in product list and false if not bool nextPage = true; // Properly initialized // list of user requests List notifications = []; // when requests in-process _loading = true // done _loading = true // failed _loading = false bool isLoading = false; /// return -2 if request in progress /// return -1 if error happen when sending request /// return state code if request complete may be 200, 404 or 403 /// for more details check http state manager /// lib\controllers\http_status_manger\http_status_manger.dart Future getSystemNotifications({ required User user, bool resetProvider = false, NotificationFilterModel? filters, }) async { if (isLoading == true) return -2; if (resetProvider) { reset(); } // Store filters for pagination if (filters != null) { activeFilters = filters; } isLoading = true; notifyListeners(); late Response response; try { // Base request body with pagination final Map body = { "pageSize": pageItemNumber, "pageNumber": notifications.length ~/ pageItemNumber + 1, }; // Add filter parameters only if they have values if (activeFilters != null) { body.addAll(activeFilters!.toApiBody()); } // Don't add null values if no filters are active - just send pagination params only response = await ApiManager.instance.post(URLs.getNotificationInbox, body: body); // OLD API - Commented out but kept for reference // final Map body = {"pageSize": pageItemNumber, "pageNumber": notifications.length ~/ pageItemNumber + 1, "userId": user.userID}; // response = await ApiManager.instance.post(URLs.getSystemNotifications, body: body); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received final responseData = json.decode(response.body); List requestsListJson = responseData["data"]; List serviceRequestsPage = requestsListJson.map((request) => SystemNotificationModel.fromJson(request)).toList(); notifications.addAll(serviceRequestsPage); // Update notification counts from API response totalAllNotifications = responseData["totalAllNotifications"] ?? 0; totalNotificationRead = responseData["totalNotificationRead"] ?? 0; totalNotificationUnread = responseData["totalNotificationUnread"] ?? 0; totalRows = responseData["totalRows"] ?? 0; // Update nextPage based on totalRows comparison // If we've loaded all available notifications, there's no next page nextPage = notifications.length < totalRows; } isLoading = false; notifyListeners(); return response.statusCode; } catch (error) { print(error); isLoading = false; stateCode = -1; notifyListeners(); return -1; } } /// Mark all notifications as read /// Returns a map with success status and message from API Future> markAllAsRead({required String userId}) async { try { final Map body = {"userId": userId}; final response = await ApiManager.instance.post(URLs.markAllNotificationsAsRead, body: body); if (response.statusCode >= 200 && response.statusCode < 300) { // Update all notifications in the local list to read status for (var notification in notifications) { notification.readed = true; } // Update counts: Move all unread to read totalNotificationRead = totalNotificationRead + totalNotificationUnread; totalNotificationUnread = 0; notifyListeners(); // Parse response to get message final responseData = json.decode(response.body); final message = responseData['message'] ?? responseData['Message']; return {'success': true, 'message': message}; } else { // Parse error message from response try { final responseData = json.decode(response.body); final message = responseData['message'] ?? responseData['Message']; return {'success': false, 'message': message}; } catch (e) { return {'success': false, 'message': null}; } } } catch (error) { print('Error marking all as read: $error'); return {'success': false, 'message': null}; } } /// Mark one notification as read /// Returns true if successful, false otherwise Future markOneAsRead({required String notificationId}) async { try { final response = await ApiManager.instance.get("${URLs.markOneNotificationAsRead}?NotificationId=$notificationId", enableToastMessage: false); if (response.statusCode >= 200 && response.statusCode < 300) { // Update the specific notification in the local list to read status final index = notifications.indexWhere((n) => n.id == notificationId); if (index != -1 && notifications[index].readed == false) { notifications[index].readed = true; // Update counts: Move one from unread to read if (totalNotificationUnread > 0) { totalNotificationUnread--; totalNotificationRead++; } notifyListeners(); } return true; } return false; } catch (error) { print('Error marking notification as read: $error'); return false; } } /// return -2 if request in progress /// return -1 if error happen when sending request /// return state code if request complete may be 200, 404 or 403 /// for more details check http state manager /// lib\controllers\http_status_manger\http_status_manger.dart Future?> getRecentNotifications({ required String host, required User user, }) async { late Response response; //userId = 397.toString(); // testing id to view data try { response = await get(Uri.parse("${host + URLs.getNotificationInbox}?uid=${user.id}&token=${user.token}"), headers: {"Content-Type": "application/json; charset=utf-8"}); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received List requestsListJson = json.decode(utf8.decode(response.bodyBytes)); List recentNotifications = requestsListJson.map((request) => SystemNotificationModel.fromJson(request)).toList(); return recentNotifications; } return null; } catch (error) { return null; } } }