diff --git a/lib/view_models/notification_view_model.dart b/lib/view_models/notification_view_model.dart index 21bf51b..4f5836a 100644 --- a/lib/view_models/notification_view_model.dart +++ b/lib/view_models/notification_view_model.dart @@ -3,6 +3,7 @@ import 'package:tm_app/core/utils/app_toast.dart'; import 'package:tm_app/core/utils/result.dart'; import 'package:tm_app/data/repositories/notification_repository.dart'; import 'package:tm_app/data/services/model/notification__response/notification_response_model.dart'; +import 'package:tm_app/views/notification/strings/notification_strings.dart'; class NotificationViewModel with ChangeNotifier { final NotificationsRepository _repository; @@ -98,11 +99,15 @@ class NotificationViewModel with ChangeNotifier { final result = await _repository.markAllAsRead(); + if (!context.mounted) { + return; + } + switch (result) { case Ok>(): final response = result.value; final success = response['success'] as bool? ?? false; - final message = response['message'] as String? ?? 'Unknown response'; + final message = response['message'] as String? ?? NotificationStrings.unknownResponse; if (success) { if (_notificationResponseModel?.data?.notifications != null) { @@ -118,21 +123,28 @@ class NotificationViewModel with ChangeNotifier { ); } - await getNotifications(page: currentPage, ); + await getNotifications(page: currentPage); await getUnreadNotifications(); - - // toast success - AppToast.success(context, 'All notifications marked as read.'); + if (context.mounted) { + AppToast.success( + context, + NotificationStrings.allNotificationMarkedAsRead, + ); + } } else { _errorMessage = message; - AppToast.error(context, message); + if (context.mounted) { + AppToast.error(context, message); + } } break; case Error>(): _errorMessage = result.error.toString(); - AppToast.error(context, _errorMessage!); + if (context.mounted) { + AppToast.error(context, _errorMessage!); + } break; } @@ -146,15 +158,15 @@ class NotificationViewModel with ChangeNotifier { final difference = now.difference(createdAt); if (difference.inMinutes < 1) { - return 'Now'; + return NotificationStrings.now; } else if (difference.inMinutes < 60) { - return '${difference.inMinutes} Min '; + return '${difference.inMinutes} ${NotificationStrings.min} '; } else if (difference.inHours < 24) { - return '${difference.inHours} Hour '; + return '${difference.inHours} ${NotificationStrings.hour} '; } else if (difference.inDays == 1) { - return 'Yesterday'; + return NotificationStrings.yesterday; } else { - return '${difference.inDays} days ago'; + return '${difference.inDays} ${NotificationStrings.daysAgo}'; } } diff --git a/lib/views/notification/pages/d_notification_page.dart b/lib/views/notification/pages/d_notification_page.dart index 5e3417e..ec40cc1 100644 --- a/lib/views/notification/pages/d_notification_page.dart +++ b/lib/views/notification/pages/d_notification_page.dart @@ -40,162 +40,164 @@ class _DesktopNotificationPageState extends State Widget build(BuildContext context) { final viewModel = context.watch(); - return Scaffold( - backgroundColor: AppColors.backgroundColor, - body: Column( - children: [ - const DesktopNavigationWidget(currentIndex: 3), - SizedBox(height: 60.0.h()), - Expanded( - child: Center( - child: SizedBox( - width: 740, - child: 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: InkWell( - onTap: () { - viewModel.markAllAsRead(context); - }, - borderRadius: BorderRadius.circular(99), - child: Container( - width: 132.0.w(), - height: 32.0.h(), - decoration: BoxDecoration( - color: AppColors.primary20, - borderRadius: BorderRadius.circular(99), - ), - child: Center( - child: Text( - NotificationStrings.markAllAsReadButton, - style: TextStyle( - fontSize: 14.0.sp(), - fontWeight: FontWeight.w500, - color: AppColors.mainBlue, - ), - ), - ), - ), - ), + return SafeArea( + child: Scaffold( + backgroundColor: AppColors.backgroundColor, + body: Column( + children: [ + const DesktopNavigationWidget(currentIndex: 3), + SizedBox(height: 60.0.h()), + Expanded( + child: Center( + child: SizedBox( + width: 740, + child: Column( + children: [ + MainTabBar( + controller: controller, + titles: [ + NotificationStrings.all, + NotificationStrings.unread, + NotificationStrings.important, + ], ), - ), - SizedBox(height: 12.0.h()), - viewModel.isLoading - ? Container() - : Expanded( - child: TabBarView( - controller: controller, - children: const [ - NotificationAllTab(), - NotificationUnreadTab(), - NotificationImportantTab(), - ], - ), - ), - if (viewModel.isLoading) ...[ - const Spacer(), - const Center( - child: CircularProgressIndicator( - color: AppColors.secondary50, - ), - ), - const Spacer(), - ], - 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( - context: context, - builder: - (context) => PageSelectionDialog( - totalPages: viewModel.totalPages, - ), - ); - - if (selectedPage != null) { - viewModel.jumpToPage(selectedPage); - } - }, - child: Container( - decoration: BoxDecoration( - border: Border.all( - color: AppColors.grey30, - width: 1, + SizedBox(height: 12.0.h()), + Padding( + padding: EdgeInsetsDirectional.only(end: 24.0.w()), + child: Align( + alignment: Alignment.centerRight, + child: InkWell( + onTap: () { + viewModel.markAllAsRead(context); + }, + borderRadius: BorderRadius.circular(99), + child: Container( + width: 132.0.w(), + height: 32.0.h(), + decoration: BoxDecoration( + color: AppColors.primary20, + borderRadius: BorderRadius.circular(99), ), - borderRadius: BorderRadius.circular(4), - ), - child: Row( - children: [ - SizedBox(width: 5.0.w()), - Text( - viewModel.currentPage.toString(), + child: Center( + child: Text( + NotificationStrings.markAllAsReadButton, style: TextStyle( fontSize: 14.0.sp(), fontWeight: FontWeight.w500, - color: AppColors.grey70, + color: AppColors.mainBlue, ), ), - SizedBox(width: 5.0.w()), - Icon( - Icons.arrow_drop_down, - color: AppColors.grey80, - ), - 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( - viewModel.totalPages.toString(), - style: TextStyle( - fontSize: 13.0.sp(), - fontWeight: FontWeight.w400, - color: AppColors.grey60, + ), + SizedBox(height: 12.0.h()), + viewModel.isLoading + ? Container() + : Expanded( + child: TabBarView( + controller: controller, + children: const [ + NotificationAllTab(), + NotificationUnreadTab(), + NotificationImportantTab(), + ], + ), + ), + if (viewModel.isLoading) ...[ + const Spacer(), + const Center( + child: CircularProgressIndicator( + color: AppColors.secondary50, ), ), + const Spacer(), ], - ), - SizedBox(height: 30.0.h()), - ], + 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( + context: context, + builder: + (context) => PageSelectionDialog( + totalPages: viewModel.totalPages, + ), + ); + + if (selectedPage != null) { + 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.toString(), + style: TextStyle( + fontSize: 14.0.sp(), + fontWeight: FontWeight.w500, + color: AppColors.grey70, + ), + ), + SizedBox(width: 5.0.w()), + Icon( + Icons.arrow_drop_down, + color: AppColors.grey80, + ), + 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( + viewModel.totalPages.toString(), + style: TextStyle( + fontSize: 13.0.sp(), + fontWeight: FontWeight.w400, + color: AppColors.grey60, + ), + ), + ], + ), + SizedBox(height: 30.0.h()), + ], + ), ), ), ), - ), - ], + ], + ), ), ); } diff --git a/lib/views/notification/strings/notification_strings.dart b/lib/views/notification/strings/notification_strings.dart index 2fd9c3e..767128a 100644 --- a/lib/views/notification/strings/notification_strings.dart +++ b/lib/views/notification/strings/notification_strings.dart @@ -11,5 +11,14 @@ class NotificationStrings { static const String currentPage = 'currentPage'; static const String of = 'of'; static const String totalPages = 'totalPages'; - + static const String allNotificationMarkedAsRead = 'All notifications marked as read.'; + static const String unknownResponse = 'Unknown response'; + static const String now = 'Now'; + static const String min = 'Min'; + static const String hour = 'Hour'; + static const String yesterday = 'Yesterday'; + static const String daysAgo = 'days ago'; + static const String reject = 'reject'; + static const String info = 'info'; + static const String noUnreadNotifications = 'No unread notifications'; } diff --git a/lib/views/notification/widgets/notification_card.dart b/lib/views/notification/widgets/notification_card.dart index 7b65d94..ab98745 100644 --- a/lib/views/notification/widgets/notification_card.dart +++ b/lib/views/notification/widgets/notification_card.dart @@ -6,6 +6,7 @@ import 'package:tm_app/core/theme/colors.dart'; import 'package:tm_app/core/utils/size_config.dart'; import 'package:tm_app/data/services/model/notification_data/notification_data.dart'; import 'package:tm_app/view_models/notification_view_model.dart'; +import 'package:tm_app/views/notification/strings/notification_strings.dart'; class NotificationCard extends StatelessWidget { final NotificationItem notification; @@ -20,17 +21,17 @@ class NotificationCard extends StatelessWidget { padding: const EdgeInsets.all(16.0), decoration: BoxDecoration( color: - notification.type == 'reject' + notification.type == NotificationStrings.reject ? AppColors.orange10 - : notification.type == 'info' + : notification.type == NotificationStrings.info ? AppColors.primary10Light : AppColors.green0, borderRadius: BorderRadius.circular(4), border: Border.all( color: - notification.type! == 'reject' + notification.type! == NotificationStrings.reject ? AppColors.warningColor - : notification.type == 'info' ? AppColors.primary20 : AppColors.green20, + : notification.type == NotificationStrings.info ? AppColors.primary20 : AppColors.green20, ), ), child: Row( @@ -39,9 +40,9 @@ class NotificationCard extends StatelessWidget { Padding( padding: EdgeInsets.only(top: 3.0.h()), child: SvgPicture.asset( - notification.type! == 'info' + notification.type! == NotificationStrings.info ? AssetsManager.notification - : notification.type! == 'reject' + : notification.type! == NotificationStrings.reject ? AssetsManager.danger : AssetsManager.tickCircle, ), diff --git a/lib/views/notification/widgets/notification_unread_tab.dart b/lib/views/notification/widgets/notification_unread_tab.dart index efb980e..cc6afd5 100644 --- a/lib/views/notification/widgets/notification_unread_tab.dart +++ b/lib/views/notification/widgets/notification_unread_tab.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.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 'notification_card.dart'; @@ -21,7 +22,7 @@ class NotificationUnreadTab extends StatelessWidget { viewModel.unreadNotificationResponse?.data?.notifications ?? []; if (notifications.isEmpty) { - return const Center(child: Text('No unread notifications')); + return const Center(child: Text(NotificationStrings.noUnreadNotifications,)); } return ListView.builder(