Files
AmirReza Jamali ae08b946f6 Refactor tenders pagination and enhance API integration
- Updated TendersRepository and TendersService to support cursor-based pagination.
- Modified TendersViewModel to manage pagination state and handle API responses more effectively.
- Replaced existing pagination UI components with a new WindowedPagination widget across desktop, mobile, and tablet views.
- Improved notification handling in the UI to reflect the presence of notifications dynamically.
- Adjusted main tenders slider to ensure proper rendering based on the current page index.
2026-05-26 18:30:46 +03:30

181 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:tm_app/core/theme/colors.dart';
import 'package:tm_app/core/utils/size_config.dart';
import 'package:tm_app/view_models/notification_view_model.dart';
import 'package:tm_app/views/notification/strings/notification_strings.dart';
import 'package:tm_app/views/shared/tender_app_bar.dart';
import '../../shared/main_tab_bar.dart';
import '../widgets/notification_all_tab.dart';
import '../widgets/notification_important_tab.dart';
import '../widgets/notification_unread_tab.dart';
class MobileNotificationPage extends StatefulWidget {
const MobileNotificationPage({super.key});
@override
State<MobileNotificationPage> createState() => _MobileNotificationPageState();
}
class _MobileNotificationPageState extends State<MobileNotificationPage>
with SingleTickerProviderStateMixin {
late TabController controller;
final ScrollController _scrollAll = ScrollController();
final ScrollController _scrollUnread = ScrollController();
final ScrollController _scrollImportant = ScrollController();
@override
void initState() {
super.initState();
controller = TabController(length: 3, vsync: this);
final viewModel = context.read<NotificationViewModel>();
_scrollAll.addListener(() {
if (_scrollAll.position.pixels >=
_scrollAll.position.maxScrollExtent - 100 &&
!viewModel.isLoadingAll &&
viewModel.hasMoreAll) {
viewModel.getNotifications(
page: viewModel.currentPageAll + 1,
isPagination: true,
);
}
});
_scrollUnread.addListener(() {
if (_scrollUnread.position.pixels >=
_scrollUnread.position.maxScrollExtent - 100 &&
!viewModel.isLoadingUnread &&
viewModel.hasMoreUnread) {
viewModel.getUnreadNotifications(
page: viewModel.currentPageUnread + 1,
isPagination: true,
);
}
});
_scrollImportant.addListener(() {
if (_scrollImportant.position.pixels >=
_scrollImportant.position.maxScrollExtent - 100 &&
!viewModel.isLoadingImportant &&
viewModel.hasMoreImportant) {
viewModel.getImportantNotifications(
page: viewModel.currentPageImportant + 1,
isPagination: true,
);
}
});
}
@override
void dispose() {
controller.dispose();
_scrollAll.dispose();
_scrollUnread.dispose();
_scrollImportant.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final viewModel = context.watch<NotificationViewModel>();
return Scaffold(
backgroundColor: AppColors.backgroundColor,
appBar: tenderMobileAppBar(title: NotificationStrings.notificationTitle),
body: Column(
children: [
MainTabBar(
controller: controller,
titles: [
NotificationStrings.all,
NotificationStrings.unread,
NotificationStrings.important,
],
),
SizedBox(height: 12.0.h()),
Padding(
padding: EdgeInsetsDirectional.only(end: 24.0.w()),
child: Align(
alignment: Alignment.centerRight,
child: Builder(
builder: (context) {
final hasNotifications =
(viewModel.allNotificationResponse?.data?.isNotEmpty ??
false);
return InkWell(
onTap: hasNotifications
? () => viewModel.markAllAsRead(context)
: null,
borderRadius: BorderRadius.circular(99),
child: Container(
width: 132.0.w(),
height: 32.0.h(),
decoration: BoxDecoration(
color: hasNotifications
? AppColors.primary20
: AppColors.grey20,
borderRadius: BorderRadius.circular(99),
),
child: Center(
child: Text(
NotificationStrings.markAllAsReadButton,
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w500,
color: hasNotifications
? AppColors.mainBlue
: AppColors.grey50,
),
),
),
),
);
},
),
),
),
SizedBox(height: 12.0.h()),
Expanded(
child: TabBarView(
controller: controller,
children: [
NotificationAllTab(scrollController: _scrollAll),
NotificationUnreadTab(scrollController: _scrollUnread),
NotificationImportantTab(scrollController: _scrollImportant),
],
),
),
if (viewModel.isMoreLoadingAll)
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Center(
child: CircularProgressIndicator(color: AppColors.cyanTeal),
),
),
if (viewModel.isMoreLoadingUnread)
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Center(
child: CircularProgressIndicator(color: AppColors.cyanTeal),
),
),
if (viewModel.isMoreLoadingImportant)
const Padding(
padding: EdgeInsets.symmetric(vertical: 16),
child: Center(
child: CircularProgressIndicator(color: AppColors.cyanTeal),
),
),
],
),
);
}
}