Files
tm_app/lib/views/notification/pages/t_notification_page.dart
T
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

241 lines
8.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:provider/provider.dart';
import 'package:tm_app/core/constants/assets.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/page_selection_dialog.dart';
import 'package:tm_app/views/shared/tablet_navigation_widget.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 TabletNotificationPage extends StatefulWidget {
const TabletNotificationPage({super.key});
@override
State<TabletNotificationPage> createState() => _TabletNotificationPageState();
}
class _TabletNotificationPageState extends State<TabletNotificationPage>
with SingleTickerProviderStateMixin {
late TabController controller;
final GlobalKey<ScaffoldState> key = GlobalKey();
@override
void initState() {
super.initState();
controller = TabController(length: 3, vsync: this);
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
final viewModel = context.watch<NotificationViewModel>();
final activeIndex = controller.index;
int currentPage = 1;
int totalPages = 1;
bool isLoading = false;
if (activeIndex == 0) {
currentPage = viewModel.currentPageAll;
totalPages = viewModel.totalPagesAll;
isLoading = viewModel.isLoadingAll;
} else if (activeIndex == 1) {
currentPage = viewModel.currentPageUnread;
totalPages = viewModel.totalPagesUnread;
isLoading = viewModel.isLoadingUnread;
} else {
currentPage = viewModel.currentPageImportant;
totalPages = viewModel.totalPagesImportant;
isLoading = viewModel.isLoadingImportant;
}
return Scaffold(
key: key,
backgroundColor: AppColors.backgroundColor,
appBar: tabletAppBar(
title: NotificationStrings.notificationTitle,
key: key,
context: context,
),
drawer: const TabletNavigationWidget(currentIndex: 2),
body: Center(
child: SizedBox(
width: 720,
child: Column(
children: [
MainTabBar(
controller: controller,
titles: [
NotificationStrings.all,
NotificationStrings.unread,
NotificationStrings.important,
],
onTap: (_) => setState(() {}),
),
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()),
if (isLoading)
const Expanded(
child: Center(
child: CircularProgressIndicator(color: AppColors.cyanTeal),
),
)
else
Expanded(
child: TabBarView(
controller: controller,
children: const [
NotificationAllTab(),
NotificationUnreadTab(),
NotificationImportantTab(),
],
),
),
SizedBox(height: 10.0.h()),
Row(
children: [
const Spacer(),
Text(
NotificationStrings.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) => PageSelectionDialog(
totalPages: totalPages,
currentPage: currentPage,
),
);
if (selectedPage != null) {
if (activeIndex == 0) {
viewModel.jumpToPageAll(selectedPage);
} else if (activeIndex == 1) {
viewModel.jumpToPageUnread(selectedPage);
} else {
viewModel.jumpToPageImportant(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.toString(),
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w500,
color: AppColors.grey70,
),
),
SizedBox(width: 5.0.w()),
SvgPicture.asset(
AssetsManager.arrowDownSmall,
colorFilter: ColorFilter.mode(
AppColors.grey80,
BlendMode.srcIn,
),
),
SizedBox(width: 5.0.w()),
],
),
),
),
SizedBox(width: 5.0.w()),
Text(
NotificationStrings.of,
style: TextStyle(
fontSize: 14.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
SizedBox(width: 5.0.w()),
Text(
totalPages.toString(),
style: TextStyle(
fontSize: 13.0.sp(),
fontWeight: FontWeight.w400,
color: AppColors.grey60,
),
),
],
),
SizedBox(height: 30.0.h()),
],
),
),
),
);
}
}