import 'package:flutter/material.dart'; import 'package:tm_app/core/utils/result.dart'; import 'package:tm_app/data/repositories/liked_tenders_repository.dart'; import 'package:tm_app/data/repositories/tenders_repository.dart'; import 'package:tm_app/data/services/model/liked_tender_feedback/liked_tender_feedback.dart'; import 'package:tm_app/data/services/model/liked_tenders_response/liked_tenders_response.dart'; import '../data/services/model/feedback_response/feedback_response.dart'; import '../data/services/model/request_models/tender_feedback_request_model/tender_feedback_request_model.dart'; class LikedTendersViewModel with ChangeNotifier { final LikedTendersRepository _likedTendersRepository; final TendersRepository _tendersRepository; LikedTendersViewModel({ required LikedTendersRepository likedTendersRepository, required TendersRepository tendersRepository, }) : _likedTendersRepository = likedTendersRepository, _tendersRepository = tendersRepository; bool isLoading = false; bool isLoadingMore = false; bool hasMore = true; String? errorMessage; LikedTendersResponse? data; int _offset = 0; final int _limit = 7; int currentPage = 1; // Approval status properties bool approvalStatus = false; final String _status = ''; String? _errorMessage; final bool _isSubmitApprovalLoading = false; final bool _isRejectApprovalLoading = false; String get status => _status; String? get approvalErrorMessage => _errorMessage; bool get isSubmitApprovalLoading => _isSubmitApprovalLoading; bool get isRejectApprovalLoading => _isRejectApprovalLoading; void clearApprovalErrorMessage() { _errorMessage = null; notifyListeners(); } Future getLikedTenders({bool reset = false}) async { if (!reset && (isLoadingMore || !hasMore)) { return; } if (reset) { _offset = (currentPage - 1) * _limit; hasMore = true; data = null; isLoading = true; notifyListeners(); } else { if (_offset == 0) { isLoading = true; } else { isLoadingMore = true; } notifyListeners(); } errorMessage = null; final requestModel = TenderFeedbackRequestModel( offset: _offset, limit: _limit, feedbackType: 'like', ); final result = await _likedTendersRepository.getLikedTenders( requestModel: requestModel, ); switch (result) { case Ok(): final incoming = result.value; final incomingList = incoming.data?.feedback ?? []; if (reset) { data = incoming; } else { final existingList = data?.data?.feedback ?? []; final combined = List.of(existingList) ..addAll(incomingList); data = data?.copyWith( data: data?.data?.copyWith( feedback: combined, meta: incoming.data?.meta ?? data!.data!.meta, ), ); } hasMore = incomingList.length == _limit; _offset += _limit; errorMessage = null; break; case Error(): errorMessage = result.error.toString(); break; } isLoading = false; isLoadingMore = false; notifyListeners(); } Future loadMoreIfNeeded() async { if (isLoadingMore || !hasMore) { return; } await getLikedTenders(reset: false); } Future jumpToPage(int page) async { currentPage = page; _offset = (page - 1) * _limit; hasMore = true; await getLikedTenders(reset: true); } void removeTenderById(String id) async { final current = data; final list = current?.data?.feedback; if (current == null || list == null) { return; } // Store original list to restore if error occurs final originalList = List.of(list); final updatedList = List.of(list) ..removeWhere((e) => e.tenderId == id); // Temporarily update UI data = current.copyWith( data: current.data?.copyWith(feedback: updatedList), ); notifyListeners(); final result = await _tendersRepository.toggleFeedback( tenderId: id, feedbackType: 'like', ); switch (result) { case Ok(): final updatedMeta = current.data?.meta?.copyWith( total: updatedList.length, ); data = current.copyWith( data: current.data?.copyWith( feedback: updatedList, meta: updatedMeta, ), ); break; case Error(): // Restore original list if error occurs data = current.copyWith( data: current.data?.copyWith(feedback: originalList), ); errorMessage = result.error.toString(); break; } notifyListeners(); } }