tenders pagination added
This commit is contained in:
@@ -8,8 +8,11 @@ class TendersRepository {
|
|||||||
: _tendersService = tendersService;
|
: _tendersService = tendersService;
|
||||||
final TendersService _tendersService;
|
final TendersService _tendersService;
|
||||||
|
|
||||||
Future<Result<TendersResponse>> getTenders() async {
|
Future<Result<TendersResponse>> getTenders({
|
||||||
return _tendersService.getTenders();
|
required int limit,
|
||||||
|
required int offset,
|
||||||
|
}) async {
|
||||||
|
return _tendersService.getTenders(limit: limit, offset: offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Result<FeedbackResponse>> getTenderFeedback({
|
Future<Result<FeedbackResponse>> getTenderFeedback({
|
||||||
|
|||||||
@@ -11,9 +11,12 @@ class TendersService {
|
|||||||
: _networkManager = networkManager;
|
: _networkManager = networkManager;
|
||||||
final 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(
|
final result = await _networkManager.makeRequest(
|
||||||
'/api/v1/tenders',
|
'/api/v1/tenders?limit=$limit&offset=$offset',
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
(json) => TendersResponse.fromJson(json),
|
(json) => TendersResponse.fromJson(json),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -19,11 +19,13 @@ class TendersViewModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool _isLoading = false;
|
bool _isLoading = false;
|
||||||
|
bool _isLoadingMore = false;
|
||||||
String? _errorMessage;
|
String? _errorMessage;
|
||||||
TendersResponse? _tendersResponse;
|
TendersResponse? _tendersResponse;
|
||||||
FeedbackData? _feedbackData;
|
FeedbackData? _feedbackData;
|
||||||
|
|
||||||
bool get isLoading => _isLoading;
|
bool get isLoading => _isLoading;
|
||||||
|
bool get isLoadingMore => _isLoadingMore;
|
||||||
String? get errorMessage => _errorMessage;
|
String? get errorMessage => _errorMessage;
|
||||||
TendersResponse? get tendersResponse => _tendersResponse;
|
TendersResponse? get tendersResponse => _tendersResponse;
|
||||||
FeedbackData? get feedbackData => _feedbackData;
|
FeedbackData? get feedbackData => _feedbackData;
|
||||||
@@ -31,6 +33,11 @@ class TendersViewModel with ChangeNotifier {
|
|||||||
List<FeedbackData> feedbacks = [];
|
List<FeedbackData> feedbacks = [];
|
||||||
|
|
||||||
int currentPage = 1;
|
int currentPage = 1;
|
||||||
|
int _currentOffset = 0;
|
||||||
|
static const int _pageSize = 10;
|
||||||
|
bool _hasMoreData = true;
|
||||||
|
|
||||||
|
bool get hasMoreData => _hasMoreData;
|
||||||
|
|
||||||
/// Get feedback for a specific tender
|
/// Get feedback for a specific tender
|
||||||
FeedbackData? getFeedbackForTender(String tenderId) {
|
FeedbackData? getFeedbackForTender(String tenderId) {
|
||||||
@@ -49,13 +56,24 @@ class TendersViewModel with ChangeNotifier {
|
|||||||
Future<void> getTenders() async {
|
Future<void> getTenders() async {
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
_errorMessage = null;
|
_errorMessage = null;
|
||||||
|
_currentOffset = 0;
|
||||||
|
_hasMoreData = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|
||||||
final result = await _tendersRepository.getTenders();
|
final result = await _tendersRepository.getTenders(
|
||||||
|
limit: _pageSize,
|
||||||
|
offset: _currentOffset,
|
||||||
|
);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case Ok<TendersResponse>():
|
case Ok<TendersResponse>():
|
||||||
_tendersResponse = result.value;
|
_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!);
|
getTenderFeedback(_tendersResponse!.data!.tenders!.first.id!);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Error<TendersResponse>():
|
case Error<TendersResponse>():
|
||||||
_errorMessage = result.error.toString();
|
_errorMessage = result.error.toString();
|
||||||
@@ -67,6 +85,54 @@ class TendersViewModel with ChangeNotifier {
|
|||||||
notifyListeners();
|
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 {
|
Future<void> getTenderFeedback(String tenderId) async {
|
||||||
// _isLoading = true;
|
// _isLoading = true;
|
||||||
_errorMessage = null;
|
_errorMessage = null;
|
||||||
|
|||||||
@@ -94,11 +94,19 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
currentPage = index + 1;
|
currentPage = index + 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fetch feedback for the new tender if not already loaded
|
// Fetch feedback for the new tender if not already loaded
|
||||||
final viewModel = context.read<TendersViewModel>();
|
final viewModel = context.read<TendersViewModel>();
|
||||||
if (!viewModel.hasFeedbackForTender(widget.tenders[index].id!)) {
|
if (!viewModel.hasFeedbackForTender(widget.tenders[index].id!)) {
|
||||||
viewModel.getTenderFeedback(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) {
|
itemBuilder: (context, index) {
|
||||||
final tender = widget.tenders[index];
|
final tender = widget.tenders[index];
|
||||||
@@ -142,13 +150,31 @@ class _MainTendersSliderState extends State<MainTendersSlider> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _pageNumberText() {
|
Widget _pageNumberText() {
|
||||||
return Text(
|
final viewModel = context.watch<TendersViewModel>();
|
||||||
|
return Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
'$currentPage/${widget.tenders.length}',
|
'$currentPage/${widget.tenders.length}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 14.0.sp(),
|
fontSize: 14.0.sp(),
|
||||||
fontWeight: FontWeight.w500,
|
fontWeight: FontWeight.w500,
|
||||||
color: AppColors.grey,
|
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