tenders pagination added
This commit is contained in:
@@ -8,8 +8,11 @@ class TendersRepository {
|
||||
: _tendersService = tendersService;
|
||||
final TendersService _tendersService;
|
||||
|
||||
Future<Result<TendersResponse>> getTenders() async {
|
||||
return _tendersService.getTenders();
|
||||
Future<Result<TendersResponse>> getTenders({
|
||||
required int limit,
|
||||
required int offset,
|
||||
}) async {
|
||||
return _tendersService.getTenders(limit: limit, offset: offset);
|
||||
}
|
||||
|
||||
Future<Result<FeedbackResponse>> getTenderFeedback({
|
||||
|
||||
@@ -11,9 +11,12 @@ class TendersService {
|
||||
: _networkManager = networkManager;
|
||||
final NetworkManager _networkManager;
|
||||
|
||||
Future<Result<TendersResponse>> getTenders() async {
|
||||
Future<Result<TendersResponse>> getTenders({
|
||||
required int limit,
|
||||
required int offset,
|
||||
}) async {
|
||||
final result = await _networkManager.makeRequest(
|
||||
'/api/v1/tenders',
|
||||
'/api/v1/tenders?limit=$limit&offset=$offset',
|
||||
method: 'GET',
|
||||
(json) => TendersResponse.fromJson(json),
|
||||
);
|
||||
|
||||
@@ -19,11 +19,13 @@ class TendersViewModel with ChangeNotifier {
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -31,6 +33,11 @@ class TendersViewModel with ChangeNotifier {
|
||||
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) {
|
||||
@@ -49,13 +56,24 @@ class TendersViewModel with ChangeNotifier {
|
||||
Future<void> getTenders() async {
|
||||
_isLoading = true;
|
||||
_errorMessage = null;
|
||||
_currentOffset = 0;
|
||||
_hasMoreData = true;
|
||||
notifyListeners();
|
||||
|
||||
final result = await _tendersRepository.getTenders();
|
||||
final result = await _tendersRepository.getTenders(
|
||||
limit: _pageSize,
|
||||
offset: _currentOffset,
|
||||
);
|
||||
switch (result) {
|
||||
case Ok<TendersResponse>():
|
||||
_tendersResponse = result.value;
|
||||
getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!);
|
||||
// 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();
|
||||
@@ -67,6 +85,54 @@ class TendersViewModel with ChangeNotifier {
|
||||
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;
|
||||
|
||||
@@ -94,11 +94,19 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
||||
setState(() {
|
||||
currentPage = index + 1;
|
||||
});
|
||||
|
||||
// Fetch feedback for the new tender if not already loaded
|
||||
final viewModel = context.read<TendersViewModel>();
|
||||
if (!viewModel.hasFeedbackForTender(widget.tenders[index].id!)) {
|
||||
viewModel.getTenderFeedback(widget.tenders[index].id!);
|
||||
}
|
||||
|
||||
// Check if we need to load more tenders (when user reaches near the end)
|
||||
if (index >= widget.tenders.length - 1 &&
|
||||
viewModel.hasMoreData &&
|
||||
!viewModel.isLoadingMore) {
|
||||
viewModel.loadMoreTenders();
|
||||
}
|
||||
},
|
||||
itemBuilder: (context, index) {
|
||||
final tender = widget.tenders[index];
|
||||
@@ -142,13 +150,31 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
||||
}
|
||||
|
||||
Widget _pageNumberText() {
|
||||
return Text(
|
||||
'$currentPage/${widget.tenders.length}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0.sp(),
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.grey,
|
||||
),
|
||||
final viewModel = context.watch<TendersViewModel>();
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'$currentPage/${widget.tenders.length}',
|
||||
style: TextStyle(
|
||||
fontSize: 14.0.sp(),
|
||||
fontWeight: FontWeight.w500,
|
||||
color: AppColors.grey,
|
||||
),
|
||||
),
|
||||
if (viewModel.isLoadingMore)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 4.0.h()),
|
||||
child: SizedBox(
|
||||
width: 16.0.w(),
|
||||
height: 16.0.w(),
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2.0,
|
||||
color: AppColors.jellyBean,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user