Files
tm_app/lib/view_models/tenders_view_model.dart
T
2025-08-19 08:08:31 +03:30

206 lines
6.1 KiB
Dart

import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:tm_app/data/repositories/tenders_repository.dart';
import 'package:tm_app/data/services/model/feedback_data/feedback_data.dart';
import 'package:tm_app/data/services/model/feedback_response/feedback_response.dart';
import 'package:tm_app/data/services/model/tenders/tenders_response/tenders_response.dart';
import '../core/utils/result.dart';
class TendersViewModel with ChangeNotifier {
final TendersRepository _tendersRepository;
TendersViewModel({required TendersRepository tendersRepository})
: _tendersRepository = tendersRepository {
WidgetsBinding.instance.addPostFrameCallback((_) {
getTenders();
});
}
bool _isLoading = false;
bool _isLoadingMore = false;
String? _errorMessage;
TendersResponse? _tendersResponse;
FeedbackData? _feedbackData;
bool get isLoading => _isLoading;
bool get isLoadingMore => _isLoadingMore;
String? get errorMessage => _errorMessage;
TendersResponse? get tendersResponse => _tendersResponse;
FeedbackData? get feedbackData => _feedbackData;
List<FeedbackData> feedbacks = [];
int currentPage = 1;
int _currentOffset = 0;
static const int _pageSize = 10;
bool _hasMoreData = true;
bool get hasMoreData => _hasMoreData;
/// Get feedback for a specific tender
FeedbackData? getFeedbackForTender(String tenderId) {
try {
return feedbacks.firstWhere((f) => f.tender == tenderId);
} catch (e) {
return null;
}
}
/// Check if feedback exists for a specific tender
bool hasFeedbackForTender(String tenderId) {
return feedbacks.any((f) => f.tender == tenderId);
}
Future<void> getTenders() async {
_isLoading = true;
_errorMessage = null;
_currentOffset = 0;
_hasMoreData = true;
notifyListeners();
final result = await _tendersRepository.getTenders(
limit: _pageSize,
offset: _currentOffset,
);
switch (result) {
case Ok<TendersResponse>():
_tendersResponse = result.value;
// Check if we have more data
if (_tendersResponse?.data?.tenders != null) {
_hasMoreData = _tendersResponse!.data!.tenders!.length >= _pageSize;
}
if (_tendersResponse?.data?.tenders?.isNotEmpty == true) {
getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!);
}
break;
case Error<TendersResponse>():
_errorMessage = result.error.toString();
break;
}
_isLoading = false;
notifyListeners();
_errorMessage = null;
notifyListeners();
}
Future<void> loadMoreTenders() async {
if (_isLoadingMore || !_hasMoreData) return;
_isLoadingMore = true;
_errorMessage = null;
notifyListeners();
_currentOffset += _pageSize;
final result = await _tendersRepository.getTenders(
limit: _pageSize,
offset: _currentOffset,
);
switch (result) {
case Ok<TendersResponse>():
if (result.value.data?.tenders != null &&
result.value.data!.tenders!.isNotEmpty) {
// Create a new modifiable list by combining existing and new tenders
if (_tendersResponse?.data?.tenders != null) {
final existingTenders = _tendersResponse!.data!.tenders!;
final newTenders = result.value.data!.tenders!;
final combinedTenders = [...existingTenders, ...newTenders];
// Create a new TendersData with the combined list
_tendersResponse = _tendersResponse!.copyWith(
data: _tendersResponse!.data!.copyWith(tenders: combinedTenders),
);
} else {
_tendersResponse = result.value;
}
// Check if we have more data
_hasMoreData = result.value.data!.tenders!.length >= _pageSize;
} else {
_hasMoreData = false;
}
break;
case Error<TendersResponse>():
_errorMessage = result.error.toString();
_currentOffset -= _pageSize; // Revert offset on error
break;
}
_isLoadingMore = false;
notifyListeners();
_errorMessage = null;
notifyListeners();
}
Future<void> getTenderFeedback(String tenderId) async {
// _isLoading = true;
_errorMessage = null;
notifyListeners();
final result = await _tendersRepository.getTenderFeedback(
tenderId: tenderId,
);
switch (result) {
case Ok<FeedbackResponse>():
_feedbackData = result.value.data;
// Add or update _feedbackData in feedbacks list by tender id
if (_feedbackData != null) {
final index = feedbacks.indexWhere(
(f) => f.tender == _feedbackData!.tender,
);
if (index != -1) {
feedbacks[index] = _feedbackData!;
log('Updated feedback for tender: ${_feedbackData!.tender}');
} else {
feedbacks.add(_feedbackData!);
log('Added new feedback for tender: ${_feedbackData!.tender}');
}
log('Total feedbacks: ${feedbacks.length}');
}
break;
case Error<FeedbackResponse>():
_errorMessage = result.error.toString();
break;
}
// _isLoading = false;
notifyListeners();
_errorMessage = null;
notifyListeners();
}
Future<void> feedback({
required String tenderId,
required String feedbackType,
}) async {
_errorMessage = null;
notifyListeners();
final result = await _tendersRepository.feedback(
tenderId: tenderId,
feedbackType: feedbackType,
);
switch (result) {
case Ok<FeedbackResponse>():
_feedbackData = result.value.data;
if (_feedbackData != null) {
final index = feedbacks.indexWhere(
(f) => f.tender == _feedbackData!.tender,
);
if (index != -1) {
feedbacks[index] = _feedbackData!;
} else {
feedbacks.add(_feedbackData!);
}
}
break;
case Error<FeedbackResponse>():
_errorMessage = result.error.toString();
break;
}
notifyListeners();
_errorMessage = null;
notifyListeners();
}
}