changed pagination to selectPage in t d yourTenders

This commit is contained in:
llsajjad
2025-09-13 16:33:05 +03:30
parent 6ae6f38137
commit c7fc74a153
7 changed files with 321 additions and 85 deletions
+36 -6
View File
@@ -19,6 +19,7 @@ class YourTendersViewModel with ChangeNotifier {
String? errorMessage;
TenderApprovalsResponse? data;
LikedTendersResponse? likedTendersData;
// Pagination state for feedback lists
bool isLoadingMore = false;
bool hasMore = true;
@@ -31,6 +32,7 @@ class YourTendersViewModel with ChangeNotifier {
bool hasMoreTenders = true;
int _tendersOffset = 0;
final int _tendersLimit = 10;
// Filter States
DateTimeRange? selectedDateRange;
String selectedStatus = 'All';
@@ -119,11 +121,12 @@ class YourTendersViewModel with ChangeNotifier {
bool reset = false,
}) async {
if (reset) {
_offset = 0;
_offset = (currentPage - 1) * _limit;
hasMore = true;
_currentFeedbackType = feedbackType;
}
if (!reset && (isLoadingMore || !hasMore)) {
return;
}
@@ -259,17 +262,18 @@ class YourTendersViewModel with ChangeNotifier {
}
Future<void> callWithFilter() async {
// Clear data before applying filter
_clearAllData();
likedTendersData = null;
data = null;
isLoading = true;
notifyListeners();
// Make fresh request based on selected status
if (selectedStatus == YourTendersStrings.all) {
final requestModel = GetTendersRequestModel(
status: '',
createdFrom: startDateUnix,
createdTo: endDateUnix,
limit: _tendersLimit,
offset: 0,
offset: _tendersOffset,
);
await getTenders(requestModel: requestModel, reset: true);
} else if (selectedStatus == YourTendersStrings.tendersSubmitted) {
@@ -278,7 +282,7 @@ class YourTendersViewModel with ChangeNotifier {
createdFrom: startDateUnix,
createdTo: endDateUnix,
limit: _tendersLimit,
offset: 0,
offset: _tendersOffset,
);
await getTenders(requestModel: requestModel, reset: true);
} else if (selectedStatus == YourTendersStrings.likeTenders) {
@@ -293,4 +297,30 @@ class YourTendersViewModel with ChangeNotifier {
);
}
}
int currentPage = 1;
int get totalPages {
if (likedTendersData?.data?.meta?.pages != null) {
return likedTendersData!.data!.meta!.pages!;
}
if (data?.data?.metadata?.pages != null) {
return data!.data!.metadata!.pages!;
}
return 1;
}
Future<void> jumpToPage(int page) async {
currentPage = page;
_offset = (page - 1) * _limit;
_tendersOffset = (page - 1) * _tendersLimit;
likedTendersData = null;
data = null;
hasMore = true;
hasMoreTenders = true;
await callWithFilter();
}
}
+1 -2
View File
@@ -128,8 +128,7 @@ class TabletHomePage extends StatelessWidget {
width: double.infinity,
height: 148,
onTap: () {
//YourTendersRouteData().push(context);
NotificationRouteData().push(context);
YourTendersRouteData().push(context);
},
),
),
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:tm_app/core/constants/tender_feedback.dart';
import 'package:tm_app/core/theme/colors.dart';
import 'package:tm_app/core/utils/size_config.dart';
import 'package:tm_app/view_models/your_tenders_view_model.dart';
import 'package:tm_app/views/your_tenders/strings/your_tenders_strings.dart';
import 'package:tm_app/views/your_tenders/widgets/filter_button.dart';
@@ -38,26 +39,25 @@ class _YourTendersDesktopPageState extends State<YourTendersDesktopPage>
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.backgroundColor,
body: Column(
children: [
DesktopNavigationWidget(
currentIndex: 1, // Tenders index
),
DesktopNavigationWidget(currentIndex: 1), // Tenders index
Expanded(
child: SizedBox(
width: 740,
child: Column(
children: [
SizedBox(height: 64.0),
TabletDesktopAppbar(),
SizedBox(height: 20.0),
FilterButton(platformType: PlatformType.tabletDesktop),
SizedBox(height: 64.0.h()),
const TabletDesktopAppbar(),
SizedBox(height: 20.0.h()),
const FilterButton(platformType: PlatformType.tabletDesktop),
Expanded(
child: Consumer<YourTendersViewModel>(
builder: (context, viewModel, child) {
if (viewModel.isLoading) {
if (viewModel.isLoading &&
(viewModel.data == null &&
viewModel.likedTendersData == null)) {
return const Center(
child: CircularProgressIndicator(
color: AppColors.secondary50,
@@ -69,32 +69,140 @@ class _YourTendersDesktopPageState extends State<YourTendersDesktopPage>
return Center(child: Text(viewModel.errorMessage!));
}
Widget content;
if (viewModel.selectedStatus ==
YourTendersStrings.likeTenders &&
viewModel.likedTendersData != null) {
return LikedDislikedTendersList(
content = LikedDislikedTendersList(
data: viewModel.likedTendersData!,
status: TenderFeedback.liked.value,
isDesctop: true,
isDesktop: true,
);
} else if (viewModel.selectedStatus ==
YourTendersStrings.dislikeTenders &&
viewModel.likedTendersData != null) {
return LikedDislikedTendersList(
content = LikedDislikedTendersList(
data: viewModel.likedTendersData!,
status: TenderFeedback.disliked.value,
isDesctop: true,
);
} else if (viewModel.data != null) {
return TendersSubmitted(
approvedTenders: viewModel.data!,
isDesktop: true,
);
} else if (viewModel.data != null) {
content = TendersSubmitted(
approvedTenders: viewModel.data!,
isDesktop: true,
isMobile: false,
);
} else {
return const Center(
content = const Center(
child: Text(YourTendersStrings.noTenders),
);
}
return Column(
children: [
Expanded(child: content),
SizedBox(height: 10.0.h()),
Row(
children: [
const Spacer(),
Text(
'Page',
style: TextStyle(
fontSize: 13.0.sp(),
fontWeight: FontWeight.w300,
color: AppColors.grey60,
),
),
SizedBox(width: 10.0.w()),
InkWell(
onTap: () async {
final selectedPage = await showDialog<int>(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor:
AppColors.backgroundColor,
title: const Text('Select Page'),
content: SizedBox(
width: 200.0.w(),
height: 300.0.h(),
child: ListView.builder(
itemCount: viewModel.totalPages,
itemBuilder: (context, index) {
final pageNumber = index + 1;
return ListTile(
title: Text(
'Page $pageNumber',
),
onTap:
() => Navigator.pop(
context,
pageNumber,
),
);
},
),
),
);
},
);
if (selectedPage != null) {
await viewModel.jumpToPage(selectedPage);
}
},
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: AppColors.grey30,
width: 1,
),
borderRadius: BorderRadius.circular(4),
),
child: Row(
children: [
SizedBox(width: 5.0.w()),
Text(
'${viewModel.currentPage}',
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w500,
color: AppColors.grey70,
),
),
SizedBox(width: 5.0.w()),
const Icon(Icons.arrow_drop_down),
SizedBox(width: 5.0.w()),
],
),
),
),
SizedBox(width: 5.0.w()),
Text(
'of',
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
SizedBox(width: 5.0.w()),
Text(
'${viewModel.totalPages}',
style: TextStyle(
fontSize: 13.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
],
),
SizedBox(height: 30.0.h()),
],
);
},
),
),
@@ -68,7 +68,7 @@ class _YourTendersMobilePageState extends State<YourTendersMobilePage> {
child: LikedDislikedTendersList(
data: viewModel.likedTendersData!,
status: TenderFeedback.liked.value,
isDesctop: false,
isDesktop: false,
),
)
else if (viewModel.selectedStatus ==
@@ -78,7 +78,7 @@ class _YourTendersMobilePageState extends State<YourTendersMobilePage> {
child: LikedDislikedTendersList(
data: viewModel.likedTendersData!,
status: TenderFeedback.disliked.value,
isDesctop: false,
isDesktop: false,
),
)
else if (viewModel.data != null)
@@ -86,6 +86,7 @@ class _YourTendersMobilePageState extends State<YourTendersMobilePage> {
child: TendersSubmitted(
approvedTenders: viewModel.data!,
isDesktop: false,
isMobile: true,
),
)
else
@@ -7,7 +7,6 @@ import 'package:tm_app/views/your_tenders/widgets/filter_button.dart';
import 'package:tm_app/views/your_tenders/widgets/liked_disliked_tenders_list.dart';
import 'package:tm_app/views/your_tenders/widgets/tablet_desktop_appbar.dart';
import 'package:tm_app/views/your_tenders/widgets/tenders_submitted.dart';
import '../../../core/constants/tender_feedback.dart';
import '../../shared/tablet_navigation_widget.dart';
import '../../shared/tender_app_bar.dart';
@@ -43,9 +42,7 @@ class _YourTendersTabletPageState extends State<YourTendersTabletPage>
key: key,
backgroundColor: AppColors.backgroundColor,
appBar: tabletAppBar(title: YourTendersStrings.yourTenders, key: key),
drawer: TabletNavigationWidget(
currentIndex: 1, // Home is index 0
),
drawer: TabletNavigationWidget(currentIndex: 1),
body: Center(
child: SizedBox(
width: 720,
@@ -57,19 +54,14 @@ class _YourTendersTabletPageState extends State<YourTendersTabletPage>
child: TabletDesktopAppbar(),
),
SizedBox(height: 24.0.h()),
// MainTabBar(
// controller: controller,
// titles: [
// AppStrings.approvedTenders,
// AppStrings.tenderSubmitted,
// ],
// ),
FilterButton(platformType: PlatformType.tabletDesktop),
Expanded(
child: Consumer<YourTendersViewModel>(
builder: (context, viewModel, child) {
if (viewModel.isLoading) {
if (viewModel.isLoading &&
(viewModel.data == null &&
viewModel.likedTendersData == null)) {
return const Center(
child: CircularProgressIndicator(
color: AppColors.secondary50,
@@ -81,32 +73,136 @@ class _YourTendersTabletPageState extends State<YourTendersTabletPage>
return Center(child: Text(viewModel.errorMessage!));
}
Widget content;
if (viewModel.selectedStatus ==
YourTendersStrings.likeTenders &&
viewModel.likedTendersData != null) {
return LikedDislikedTendersList(
content = LikedDislikedTendersList(
data: viewModel.likedTendersData!,
status: TenderFeedback.liked.value,
isDesctop: false,
isDesktop: false,
);
} else if (viewModel.selectedStatus ==
YourTendersStrings.dislikeTenders &&
viewModel.likedTendersData != null) {
return LikedDislikedTendersList(
content = LikedDislikedTendersList(
data: viewModel.likedTendersData!,
status: TenderFeedback.disliked.value,
isDesctop: false,
);
} else if (viewModel.data != null) {
return TendersSubmitted(
approvedTenders: viewModel.data!,
isDesktop: false,
);
} else if (viewModel.data != null) {
content = TendersSubmitted(
approvedTenders: viewModel.data!,
isDesktop: false,
isMobile: false,
);
} else {
return const Center(
content = const Center(
child: Text(YourTendersStrings.noTenders),
);
}
return Column(
children: [
Expanded(child: content),
SizedBox(height: 10.0.h()),
Row(
children: [
const Spacer(),
Text(
'Page',
style: TextStyle(
fontSize: 13.0,
fontWeight: FontWeight.w300,
color: AppColors.grey60,
),
),
SizedBox(width: 10.0.w()),
InkWell(
onTap: () async {
final selectedPage = await showDialog<int>(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: AppColors.backgroundColor,
title: const Text('Select Page'),
content: SizedBox(
width: 200.0.w(),
height: 300.0.h(),
child: ListView.builder(
itemCount: viewModel.totalPages,
itemBuilder: (context, index) {
final pageNumber = index + 1;
return ListTile(
title: Text('Page $pageNumber'),
onTap: () => Navigator.pop(
context,
pageNumber,
),
);
},
),
),
);
},
);
if (selectedPage != null) {
await viewModel.jumpToPage(selectedPage);
}
},
child: Container(
decoration: BoxDecoration(
border: Border.all(
color: AppColors.grey30,
width: 1,
),
borderRadius: BorderRadius.circular(4),
),
child: Row(
children: [
SizedBox(width: 5.0.w()),
Text(
'${viewModel.currentPage}',
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w500,
color: AppColors.grey70,
),
),
SizedBox(width: 5.0.w()),
const Icon(Icons.arrow_drop_down),
SizedBox(width: 5.0.w()),
],
),
),
),
SizedBox(width: 5.0),
Text(
'of',
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
SizedBox(width: 5.0.w()),
Text(
'${viewModel.totalPages}',
style: TextStyle(
fontSize: 13.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
],
),
const SizedBox(height: 30.0),
],
);
},
),
),
@@ -12,12 +12,12 @@ import '../../../core/constants/tender_feedback.dart';
class LikedDislikedTendersList extends StatefulWidget {
final LikedTendersResponse data;
final String status;
final bool isDesctop;
final bool isDesktop;
const LikedDislikedTendersList({
required this.data,
required this.status,
required this.isDesctop,
required this.isDesktop,
super.key,
});
@@ -86,7 +86,7 @@ class _LikedDislikedTendersListState extends State<LikedDislikedTendersList> {
padding: EdgeInsets.only(bottom: 16.0.h()),
child: TenderCard(
tender: feedback.tender!,
isDesktop: widget.isDesctop,
isDesktop: widget.isDesktop,
status: widget.status,
submissionMode: '',
),
@@ -11,11 +11,13 @@ class TendersSubmitted extends StatefulWidget {
const TendersSubmitted({
required this.approvedTenders,
required this.isDesktop,
required this.isMobile,
super.key,
});
final TenderApprovalsResponse approvedTenders;
final bool isDesktop;
final bool isMobile;
@override
State<TendersSubmitted> createState() => _TendersSubmittedState();
@@ -67,7 +69,7 @@ class _TendersSubmittedState extends State<TendersSubmitted> {
tenders.length + (viewModel.isLoadingMoreTenders ? 1 : 0);
return ListView.builder(
controller: _scrollController,
controller: widget.isMobile ? _scrollController : null,
padding: EdgeInsets.symmetric(
// horizontal: 24.0.w(),
vertical: 15.0.h(),