changed pagination in liked tenders tanlet and web

This commit is contained in:
llsajjad
2025-09-03 13:16:57 +03:30
parent ed80b54bef
commit faab29cd99
5 changed files with 344 additions and 210 deletions
@@ -19,39 +19,10 @@ class LikedTendersDesktopPage extends StatefulWidget {
}
class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
late ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController()..addListener(_onScroll);
}
void _onScroll() {
if (!_scrollController.hasClients) {
return;
}
final max = _scrollController.position.maxScrollExtent;
final pos = _scrollController.position.pixels;
const threshold = 200.0;
if (max - pos <= threshold) {
final vm = Provider.of<LikedTendersViewModel>(context, listen: false);
vm.loadMoreIfNeeded();
}
}
@override
void dispose() {
_scrollController.removeListener(_onScroll);
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.backgroundColor,
body: Column(
children: [
DesktopNavigationWidget(
@@ -72,93 +43,171 @@ class _LikedTendersDesktopPageState extends State<LikedTendersDesktopPage> {
Expanded(
child: SizedBox(
width: 740,
child: Column(
children: [
Expanded(
child: Consumer<LikedTendersViewModel>(
builder: (context, viewModel, child) {
if (viewModel.isLoading &&
(viewModel.data?.data?.feedback ?? []).isEmpty) {
return const Center(
child: CircularProgressIndicator(
color: AppColors.secondary50,
),
);
}
child: Consumer<LikedTendersViewModel>(
builder: (context, viewModel, child) {
if (viewModel.isLoading &&
(viewModel.data?.data?.feedback ?? []).isEmpty) {
return const Center(
child: CircularProgressIndicator(
color: AppColors.secondary50,
),
);
}
if (viewModel.errorMessage != null) {
return Center(child: Text(viewModel.errorMessage!));
}
if (viewModel.errorMessage != null) {
return Center(child: Text(viewModel.errorMessage!));
}
final feedback = viewModel.data?.data?.feedback ?? [];
final feedback = viewModel.data?.data?.feedback ?? [];
if (feedback.isEmpty) {
return const Center(
child: Text('Nothing to show'),
);
}
if (feedback.isEmpty) {
return const Center(child: Text('Nothing to show'));
}
final itemCount =
feedback.length + (viewModel.isLoadingMore ? 1 : 0);
final currentPage = viewModel.currentPage;
final totalPages = viewModel.data?.data?.meta?.pages ?? 1;
return RefreshIndicator(
return Column(
children: [
Expanded(
child: RefreshIndicator(
onRefresh: () async {
await viewModel.getLikedTenders(reset: true);
},
child: ListView.builder(
controller: _scrollController,
padding: EdgeInsets.symmetric(
horizontal: 24.0.w(),
vertical: 15.0.h(),
),
itemCount: itemCount,
itemCount: feedback.length,
itemBuilder: (context, index) {
if (index < feedback.length) {
final item = feedback[index];
return Padding(
padding: EdgeInsets.only(bottom: 20.0.h()),
child: Dismissible(
key: ValueKey(item.id ?? index),
direction: DismissDirection.endToStart,
background: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(
horizontal: 20.0.w(),
),
child: SvgPicture.asset(
AssetsManager.trash,
),
final item = feedback[index];
return Padding(
padding: EdgeInsets.only(bottom: 20.0.h()),
child: Dismissible(
key: ValueKey(item.id ?? index),
direction: DismissDirection.endToStart,
background: Container(
alignment: Alignment.centerRight,
padding: EdgeInsets.symmetric(
horizontal: 20.0.w(),
),
onDismissed: (_) {
if (item.id != null) {
viewModel.removeTenderById(item.id!);
}
},
child: LikedListItem(tender: item.tender!),
),
);
} else {
return Padding(
padding: EdgeInsets.symmetric(vertical: 20.0.h()),
child: Center(
child: SizedBox(
width: 24.0.w(),
height: 24.0.h(),
child: CircularProgressIndicator(
color: AppColors.secondary50,
strokeWidth: 2,
),
child: SvgPicture.asset(
AssetsManager.trash,
),
),
);
}
onDismissed: (_) {
if (item.id != null) {
viewModel.removeTenderById(item.id!);
}
},
child: LikedListItem(tender: item.tender!),
),
);
},
),
);
},
),
),
],
),
),
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()),
GestureDetector(
onTap: () async {
final selectedPage = await showDialog<int>(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Select Page'),
content: SizedBox(
width: 200,
height: 300,
child: ListView.builder(
itemCount: 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(
'$currentPage',
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w500,
color: AppColors.grey70,
),
),
SizedBox(width: 5.0.w()),
SvgPicture.asset(
AssetsManager.arrowdownSmall,
),
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(
'$totalPages',
style: TextStyle(
fontSize: 13.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
],
),
SizedBox(height: 30.0.h()),
],
);
},
),
),
),
@@ -21,34 +21,6 @@ class LikedTendersTabletPage extends StatefulWidget {
}
class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
late final ScrollController _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController()..addListener(_onScroll);
}
void _onScroll() {
if (!_scrollController.hasClients) {
return;
}
final max = _scrollController.position.maxScrollExtent;
final pos = _scrollController.position.pixels;
const threshold = 200.0;
if (max - pos <= threshold) {
final vm = Provider.of<LikedTendersViewModel>(context, listen: false);
vm.loadMoreIfNeeded();
}
}
@override
void dispose() {
_scrollController.removeListener(_onScroll);
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final GlobalKey<ScaffoldState> key = GlobalKey();
@@ -99,21 +71,23 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
return const Center(child: Text('Nothing to show'));
}
final itemCount =
feedback.length + (viewModel.isLoadingMore ? 1 : 0);
return RefreshIndicator(
onRefresh: () async {
await viewModel.getLikedTenders(reset: true);
},
child: ListView.builder(
controller: _scrollController,
padding: EdgeInsets.symmetric(
horizontal: 24.0.w(),
vertical: 15.0.h(),
),
itemCount: itemCount,
itemBuilder: (context, index) {
if (index < feedback.length) {
final currentPage = viewModel.currentPage;
final totalPages = viewModel.data?.data?.meta?.pages ?? 1;
return Column(
children: [
Expanded(
child: RefreshIndicator(
onRefresh: () async {
await viewModel.getLikedTenders(reset: true);
},
child: ListView.builder(
padding: EdgeInsets.symmetric(
horizontal: 24.0.w(),
vertical: 15.0.h(),
),
itemCount: feedback.length,
itemBuilder: (context, index) {
final item = feedback[index];
return Padding(
padding: EdgeInsets.only(bottom: 20.0.h()),
@@ -137,24 +111,114 @@ class _LikedTendersTabletPageState extends State<LikedTendersTabletPage> {
child: LikedListItem(tender: item.tender!),
),
);
} else {
return Padding(
padding: EdgeInsets.symmetric(vertical: 20.0.h()),
child: Center(
child: SizedBox(
width: 24.0.w(),
height: 24.0.h(),
child: CircularProgressIndicator(
color: AppColors.secondary50,
strokeWidth: 2,
},
),
),
),
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()),
GestureDetector(
onTap: () async {
final selectedPage = await showDialog<int>(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Select Page'),
content: SizedBox(
width: 200,
height: 300,
child: ListView.builder(
itemCount: 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(
'$currentPage',
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w500,
color: AppColors.grey70,
),
),
),
);
}
},
),
); },
SizedBox(width: 5.0.w()),
SvgPicture.asset(
AssetsManager.arrowdownSmall,
),
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(
'$totalPages',
style: TextStyle(
fontSize: 13.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
SizedBox(width: 30.0.w()),
],
),
SizedBox(height: 30.0.h()),
],
);
},
),
),
],