From fd9457ee44f9af27511a5813a77aa00973d62a70 Mon Sep 17 00:00:00 2001 From: amirrezaghabeli Date: Sat, 30 Aug 2025 12:27:14 +0330 Subject: [PATCH 1/2] toggle feedack better handle --- lib/view_models/tenders_view_model.dart | 65 +++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/lib/view_models/tenders_view_model.dart b/lib/view_models/tenders_view_model.dart index 24d6971..36abd75 100644 --- a/lib/view_models/tenders_view_model.dart +++ b/lib/view_models/tenders_view_model.dart @@ -253,16 +253,62 @@ class TendersViewModel with ChangeNotifier { required String feedbackType, }) async { _feedbackErrorMessage = null; + + // Get current feedback for this tender + final existingFeedback = getFeedbackForTender(tenderId); + final existingFeedbackIndex = feedbacks.indexWhere( + (f) => f.tender == tenderId, + ); + + // Create optimistic feedback data + FeedbackData? optimisticFeedback; + + if (existingFeedback == null) { + // No existing feedback - create new optimistic feedback + optimisticFeedback = FeedbackData( + companyId: null, // Will be filled by server + createdAt: DateTime.now().millisecondsSinceEpoch, + customerId: null, // Will be filled by server + feedbackType: feedbackType, + id: null, // Will be filled by server + tender: tenderId, + updatedAt: DateTime.now().millisecondsSinceEpoch, + ); + feedbacks.add(optimisticFeedback); + } else { + // Existing feedback - update optimistically + if (existingFeedback.feedbackType == feedbackType) { + // Same feedback type - remove feedback (toggle off) + if (existingFeedbackIndex != -1) { + feedbacks.removeAt(existingFeedbackIndex); + } + optimisticFeedback = null; + } else { + // Different feedback type - update to new type + optimisticFeedback = existingFeedback.copyWith( + feedbackType: feedbackType, + updatedAt: DateTime.now().millisecondsSinceEpoch, + ); + if (existingFeedbackIndex != -1) { + feedbacks[existingFeedbackIndex] = optimisticFeedback; + } + } + } + + // Notify listeners immediately for optimistic update notifyListeners(); + // Call API final result = await _tendersRepository.toggleFeedback( tenderId: tenderId, feedbackType: feedbackType, ); + switch (result) { case Ok(): _feedbackData = result.value.data; if (_feedbackData != null) { + // Update with complete data from server final index = feedbacks.indexWhere( (f) => f.tender == _feedbackData!.tender, ); @@ -271,12 +317,31 @@ class TendersViewModel with ChangeNotifier { } else { feedbacks.add(_feedbackData!); } + } else { + // Server returned null data - remove feedback + feedbacks.removeWhere((f) => f.tender == tenderId); } break; case Error(): + // Revert optimistic update on error + if (existingFeedback == null) { + // Remove the optimistic feedback we added + feedbacks.removeWhere((f) => f.tender == tenderId); + } else { + // Restore the original feedback - find current index and update, or add if not found + final currentIndex = feedbacks.indexWhere( + (f) => f.tender == tenderId, + ); + if (currentIndex != -1) { + feedbacks[currentIndex] = existingFeedback; + } else { + feedbacks.add(existingFeedback); + } + } _feedbackErrorMessage = result.error.toString(); break; } + notifyListeners(); _feedbackErrorMessage = null; notifyListeners(); From a8eafc08151a5e64c0718914724a73dc1b4fcce5 Mon Sep 17 00:00:00 2001 From: amirrezaghabeli Date: Sun, 31 Aug 2025 10:51:40 +0330 Subject: [PATCH 2/2] handle approval in better way --- lib/view_models/tenders_view_model.dart | 65 +++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/lib/view_models/tenders_view_model.dart b/lib/view_models/tenders_view_model.dart index 36abd75..f2a9759 100644 --- a/lib/view_models/tenders_view_model.dart +++ b/lib/view_models/tenders_view_model.dart @@ -353,12 +353,58 @@ class TendersViewModel with ChangeNotifier { required String status, }) async { _tenderApprovalErrorMessage = null; + + // Get current approval for this tender + final existingApproval = getTenderApprovalForTender(tenderId); + final existingApprovalIndex = tenderApprovals.indexWhere( + (a) => a.tenderId == tenderId, + ); + + // Create optimistic approval data + TenderApprovalsData? optimisticApproval; + + if (existingApproval == null) { + // No existing approval - create new optimistic approval + optimisticApproval = TenderApprovalsData( + id: null, // Will be filled by server + status: status, + tenderId: tenderId, + companyId: null, // Will be filled by server + submissionMode: submissionMode, + createdAt: DateTime.now().millisecondsSinceEpoch, + tender: null, + ); + tenderApprovals.add(optimisticApproval); + } else { + // Existing approval - update optimistically + if (existingApproval.status == status) { + // Same status - remove approval (toggle off) + if (existingApprovalIndex != -1) { + tenderApprovals.removeAt(existingApprovalIndex); + } + optimisticApproval = null; + } else { + // Different status - update to new status + optimisticApproval = existingApproval.copyWith( + status: status, + submissionMode: submissionMode, + ); + if (existingApprovalIndex != -1) { + tenderApprovals[existingApprovalIndex] = optimisticApproval; + } + } + } + + // Notify listeners immediately for optimistic update notifyListeners(); + + // Call API final result = await _tendersRepository.toggleApprovals( tenderId: tenderId, submissionMode: submissionMode, status: status, ); + switch (result) { case Ok(): _tenderApprovalToggleData = result.value.data; @@ -382,12 +428,31 @@ class TendersViewModel with ChangeNotifier { } else { tenderApprovals.add(approvalData); } + } else { + // Server returned null data - remove approval + tenderApprovals.removeWhere((a) => a.tenderId == tenderId); } break; case Error(): + // Revert optimistic update on error + if (existingApproval == null) { + // Remove the optimistic approval we added + tenderApprovals.removeWhere((a) => a.tenderId == tenderId); + } else { + // Restore the original approval - find current index and update, or add if not found + final currentIndex = tenderApprovals.indexWhere( + (a) => a.tenderId == tenderId, + ); + if (currentIndex != -1) { + tenderApprovals[currentIndex] = existingApproval; + } else { + tenderApprovals.add(existingApproval); + } + } _tenderApprovalErrorMessage = result.error.toString(); break; } + notifyListeners(); _tenderApprovalErrorMessage = null; notifyListeners();