import 'package:eatvio_app/core/routing/route_constants.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/core/utils/date_time_utils.dart'; import 'package:eatvio_app/core/widgets/custom_outlined_button.dart'; import 'package:eatvio_app/features/my_finance/presentation/pages/card_settings.dart'; import 'package:eatvio_app/features/notifications/models/notification_model.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:eatvio_app/features/notifications/presentation/notifications_cubit/notifications_cubit.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class NotificationWidget extends StatelessWidget { const NotificationWidget({super.key, required this.notification}); final BaseNotificationModel notification; void _onTap(BuildContext context) { // Mark as read first context.read().markNotificationsAsRead(); switch (notification) { case CommentReplied n: _navigateToEntity(context, n.commentedEntityType, n.commentedEntityId, n.commentId); case EntityCommented n: _navigateToEntity(context, n.entityType, n.entityId, n.commentId); case PersonalDietIsDefinedToCustomerNotification n: context.push(RouteConstants.aboutDietScreen, extra: {'id': n.dietId}); case PlanSubscriptionStartedToAuthorNotification n: if (n.chatId.isNotEmpty && n.chatId != '0') { context.push(RouteConstants.chatScreen, extra: int.tryParse(n.chatId) ?? 0); } else { // Fallback if no chat ID context.push(RouteConstants.profileScreen); } case ConsultantAssignedNotification n: context.push(RouteConstants.aboutPlanScreen, extra: {'id': n.planId}); case StayOnTrackToAuthorNotification n: context.push(RouteConstants.aboutPlanScreen, extra: {'id': n.planId}); case StayOnTrackToCustomerNotification n: context.push(RouteConstants.aboutPlanScreen, extra: {'id': n.planId}); case ChosenPlanStartedToClientNotification n: context.push(RouteConstants.aboutPlanScreen, extra: {'id': n.planId}); case ChosenPlanStartedToConsultantNotification n: context.push(RouteConstants.aboutPlanScreen, extra: {'id': n.planId}); case ProductStatusUpdatedForAuthorNotification(): context.push(RouteConstants.profileScreen); // New Cases with Safety Checks case NewChatMessageNotification n: if (n.chatId != 0) context.push(RouteConstants.chatScreen, extra: n.chatId); case FinanceQuestionCreatedNotification(): context.push(RouteConstants.userFinanceScreen); case ChosenDietExpiredNotification(): context.push(RouteConstants.myDietsScreen); case ContentUnpublishedNotification(): context.push(RouteConstants.profileScreen); case CompleteRegistrationNotification(): context.push(RouteConstants.profileScreen); // Or edit profile case ConsultantEducationUpdatedNotification(): context.push(RouteConstants.profileScreen); case ComplaintRegisteredNotification(): context.push(RouteConstants.profileScreen); case ConsultantRequestStartedNotification(): // Navigate to where requests are shown context.push(RouteConstants.profileScreen); case ClientCloseComplaintSuccessNotification(): context.push(RouteConstants.profileScreen); case ClientRefundSuccessNotification(): context.push(RouteConstants.userFinanceScreen); case ConsultantRefundSuccessNotification(): context.push(RouteConstants.userFinanceScreen); case ClientRejectSuccessNotification(): context.push(RouteConstants.aboutPlanScreen); // Best guess case ConsultantRejectSuccessNotification(): context.push(RouteConstants.aboutPlanScreen); case ScoreSubstractedNotification(): context.push(RouteConstants.profileScreen); case ScoreAdded(): context.push(RouteConstants.profileScreen); case DiaryReminderForUsersNotification(): context.push(RouteConstants.myDietsScreen); // Likely where diary is case MotivateUserNotification(): context.push(RouteConstants.myDietsScreen); case CommentComplaintNotification(): context.push(RouteConstants.profileScreen); case CommentDeletedNotification(): context.push(RouteConstants.profileScreen); case UserSubscribedNotification(): context.push(RouteConstants.profileScreen); case BadgeAwardedNotification(): context.push(RouteConstants.profileScreen); case BadgeRevokedNotification(): context.push(RouteConstants.profileScreen); case SubscriptionNotification(): context.push(RouteConstants.userFinanceScreen); case PhoneChangedNotification(): context.push(RouteConstants.profileScreen); case UserDailyReportCompletedNotification(): // Attempt to go to plan if we had ID, but we don't in this model. Go to plans list. context.push(RouteConstants.myPlansScreen); case ClientCancelPlanSubscriptionToSubscriberNotification(): context.push(RouteConstants.myPlansScreen); case ClientCancelPlanSubscriptionToAuthorNotification(): context.push(RouteConstants.myPlansScreen); case ClientStartPlanSubscriptionToAuthorNotification(): context.push(RouteConstants.myPlansScreen); case ClientPaidPlanSubscriptionToSubscriberNotification(): context.push(RouteConstants.userFinanceScreen); case ConsultantConfirmPlanSubscriptionToAuthorNotification(): context.push(RouteConstants.myPlansScreen); case ConsultantLeftDiaryCommentNotification(): // Needs planID to go to specific plan, model has planName. // Optimally we'd go to the diary. For now plans screen. context.push(RouteConstants.myPlansScreen); case ClientPaidPlanSubscriptionToAuthorNotification(): context.push(RouteConstants.userFinanceScreen); case ConsultantConfirmPlanSubscriptionToSubscriberNotification(): context.push(RouteConstants.myPlansScreen); case ClientStartPlanSubscriptionToSubscriberNotification(): context.push(RouteConstants.myPlansScreen); case ChosenPlanClientLastDayStartedNotification(): context.push(RouteConstants.myPlansScreen); case ChosenPlanClientLastDayFinishedNotification(): context.push(RouteConstants.myPlansScreen); case PersonalDietCreationNeededNotification(): context.push(RouteConstants.myPlansScreen); case DietCanNotBeStartedNotification(): context.push(RouteConstants.myDietsScreen); case DietWillStartedInNotification(): context.push(RouteConstants.myDietsScreen); case DietExpiredNotification(): context.push(RouteConstants.myDietsScreen); case DietStartedNotification(): context.push(RouteConstants.myDietsScreen); case DietCancelledNotification(): context.push(RouteConstants.myDietsScreen); case MealReminderNotification(): context.push(RouteConstants.myDietsScreen); case WorkoutReminderNotification(): context.push(RouteConstants.myDietsScreen); case GoalAchievedNotification(): context.push(RouteConstants.profileScreen); case PaymentSuccessfulNotification(): context.push(RouteConstants.userFinanceScreen); case PaymentFailedNotification(): context.push(RouteConstants.userFinanceScreen); case ConsultantUnassignedNotification n: context.push(RouteConstants.aboutPlanScreen, extra: {'id': n.planId}); case PlanSubscriptionRenewedNotification(): context.push(RouteConstants.userFinanceScreen); case PlanSubscriptionExpiredNotification(): context.push(RouteConstants.userFinanceScreen); case ComplaintToModerationForUser(): context.push(RouteConstants.profileScreen); case ChosenPlanConsultantLastDayStarted n: context.push(RouteConstants.aboutPlanScreen, extra: {'id': n.planId}); case ChosenPlanLastDayFinishedForUser(): context.push(RouteConstants.myPlansScreen); case ChosenPlanFinishedToConsultantNotification n: context.push(RouteConstants.aboutPlanScreen, extra: {'id': n.planId}); case PlanSubscriptionPaidToAuthorNotification(): context.push(RouteConstants.userFinanceScreen); case ChosenPlanTomorrowReminderToConsultantNotification(): context.push(RouteConstants.myPlansScreen); case ChosenPlanTomorrowReminderToClientNotification(): context.push(RouteConstants.myPlansScreen); case PlanSubscriptionCanceledToCustomerNotification(): context.push(RouteConstants.myPlansScreen); case ChosenPlanFinishedToClientNotification(): context.push(RouteConstants.myPlansScreen); case PersonalizedDietIsDefinedNotification(): context.push(RouteConstants.myDietsScreen); case ConsultantLeftCommentNotification(): context.push(RouteConstants.myPlansScreen); case DiaryReminderNotification(): context.push(RouteConstants.myDietsScreen); case PlanSubscriptionCanceledToAuthorNotification(): context.push(RouteConstants.myPlansScreen); default: // Do nothing if no logical destination break; } } void _navigateToEntity(BuildContext context, String type, int id, int? commentId) { if (type.contains('BlogPost')) { context.push(RouteConstants.blogPostScreen, extra: {'id': id, 'highlightedCommentId': commentId}); } else if (type.contains('Recipe')) { context.push(RouteConstants.aboutRecipesScreen, extra: {'id': id, 'highlightedCommentId': commentId}); } else if (type.contains('Plan')) { context.push(RouteConstants.aboutPlanScreen, extra: {'id': id, 'highlightedCommentId': commentId}); } else if (type.contains('Diet')) { context.push(RouteConstants.aboutDietScreen, extra: {'id': id, 'highlightedCommentId': commentId}); } } // }; // } @override Widget build(BuildContext context) { return switch (notification) { PlanSubscriptionStartedToAuthorNotification() => _PlanSubscriptionStartedToAuthorWidget( notification: notification as PlanSubscriptionStartedToAuthorNotification, ), PlanSubscriptionCanceledToAuthorNotification() => _PlanSubscriptionCanceledToAuthorWidget( notification: notification as PlanSubscriptionCanceledToAuthorNotification, ), ChosenPlanStartedToClientNotification() => _ChosenPlanStartedToClientWidget(notification: notification as ChosenPlanStartedToClientNotification), ChosenPlanTomorrowReminderToClientNotification() => _ChosenPlanTomorrowReminderToClientWidget( notification: notification as ChosenPlanTomorrowReminderToClientNotification, ), DiaryReminderNotification() => _DiaryReminderWidget(notification: notification as DiaryReminderNotification), ConsultantLeftCommentNotification() => _ConsultantLeftCommentWidget(notification: notification as ConsultantLeftCommentNotification), PersonalizedDietIsDefinedNotification() => _PersonalizedDietIsDefinedWidget(notification: notification as PersonalizedDietIsDefinedNotification), ChosenPlanFinishedToClientNotification() => _ChosenPlanFinishedToClientWidget(notification: notification as ChosenPlanFinishedToClientNotification), PlanSubscriptionCanceledToCustomerNotification() => _PlanSubscriptionCanceledToCustomerWidget( notification: notification as PlanSubscriptionCanceledToCustomerNotification, ), ChosenPlanStartedToConsultantNotification() => _ChosenPlanStartedToConsultantWidget( notification: notification as ChosenPlanStartedToConsultantNotification, ), ChosenPlanTomorrowReminderToConsultantNotification() => _ChosenPlanTomorrowReminderToConsultantWidget( notification: notification as ChosenPlanTomorrowReminderToConsultantNotification, ), PlanSubscriptionPaidToAuthorNotification() => _PlanSubscriptionPaidToAuthorWidget(notification: notification as PlanSubscriptionPaidToAuthorNotification), ChosenPlanFinishedToConsultantNotification() => _ChosenPlanFinishedToConsultantWidget( notification: notification as ChosenPlanFinishedToConsultantNotification, ), ChosenPlanLastDayFinishedForUser() => _ChosenPlanLastDayFinishedForUserWidget(notification: notification as ChosenPlanLastDayFinishedForUser), ChosenPlanConsultantLastDayStarted() => _ChosenPlanConsultantLastDayStartedWidget(notification: notification as ChosenPlanConsultantLastDayStarted), ComplaintToModerationForUser() => _ComplaintToModerationForUserWidget(notification: notification as ComplaintToModerationForUser), CommentReplied() => _CommentRepliedWidget(notification: notification as CommentReplied), ScoreAdded() => _ScoreAddedWidget(notification: notification as ScoreAdded), EntityCommented() => _EntityCommentedWidget(notification: notification as EntityCommented), // Новые типы уведомлений PlanSubscriptionExpiredNotification() => _PlanSubscriptionExpiredWidget(notification: notification as PlanSubscriptionExpiredNotification), PlanSubscriptionRenewedNotification() => _PlanSubscriptionRenewedWidget(notification: notification as PlanSubscriptionRenewedNotification), ConsultantAssignedNotification() => _ConsultantAssignedWidget(notification: notification as ConsultantAssignedNotification), ConsultantUnassignedNotification() => _ConsultantUnassignedWidget(notification: notification as ConsultantUnassignedNotification), PaymentFailedNotification() => _PaymentFailedWidget(notification: notification as PaymentFailedNotification), PaymentSuccessfulNotification() => _PaymentSuccessfulWidget(notification: notification as PaymentSuccessfulNotification), GoalAchievedNotification() => _GoalAchievedWidget(notification: notification as GoalAchievedNotification), WorkoutReminderNotification() => _WorkoutReminderWidget(notification: notification as WorkoutReminderNotification), MealReminderNotification() => _MealReminderWidget(notification: notification as MealReminderNotification), // New notification types DietCancelledNotification() => _DietCancelledWidget(notification: notification as DietCancelledNotification), DietStartedNotification() => _DietStartedWidget(notification: notification as DietStartedNotification), DietExpiredNotification() => _DietExpiredWidget(notification: notification as DietExpiredNotification), DietWillStartedInNotification() => _DietWillStartedInWidget(notification: notification as DietWillStartedInNotification), DietCanNotBeStartedNotification() => _DietCanNotBeStartedWidget(notification: notification as DietCanNotBeStartedNotification), PersonalDietCreationNeededNotification() => _PersonalDietCreationNeededWidget(notification: notification as PersonalDietCreationNeededNotification), ChosenPlanClientLastDayFinishedNotification() => _ChosenPlanClientLastDayFinishedWidget( notification: notification as ChosenPlanClientLastDayFinishedNotification, ), ChosenPlanClientLastDayStartedNotification() => _ChosenPlanClientLastDayStartedWidget( notification: notification as ChosenPlanClientLastDayStartedNotification, ), StayOnTrackToAuthorNotification() => _StayOnTrackToAuthorWidget(notification: notification as StayOnTrackToAuthorNotification), ClientStartPlanSubscriptionToSubscriberNotification() => _ClientStartPlanSubscriptionToSubscriberWidget( notification: notification as ClientStartPlanSubscriptionToSubscriberNotification, ), ConsultantConfirmPlanSubscriptionToSubscriberNotification() => _ConsultantConfirmPlanSubscriptionToSubscriberWidget( notification: notification as ConsultantConfirmPlanSubscriptionToSubscriberNotification, ), ClientPaidPlanSubscriptionToAuthorNotification() => _ClientPaidPlanSubscriptionToAuthorWidget( notification: notification as ClientPaidPlanSubscriptionToAuthorNotification, ), ConsultantLeftDiaryCommentNotification() => _ConsultantLeftDiaryCommentWidget(notification: notification as ConsultantLeftDiaryCommentNotification), ConsultantConfirmPlanSubscriptionToAuthorNotification() => _ConsultantConfirmPlanSubscriptionToAuthorWidget( notification: notification as ConsultantConfirmPlanSubscriptionToAuthorNotification, ), ClientPaidPlanSubscriptionToSubscriberNotification() => _ClientPaidPlanSubscriptionToSubscriberWidget( notification: notification as ClientPaidPlanSubscriptionToSubscriberNotification, ), ClientStartPlanSubscriptionToAuthorNotification() => _ClientStartPlanSubscriptionToAuthorWidget( notification: notification as ClientStartPlanSubscriptionToAuthorNotification, ), ClientCancelPlanSubscriptionToAuthorNotification() => _ClientCancelPlanSubscriptionToAuthorWidget( notification: notification as ClientCancelPlanSubscriptionToAuthorNotification, ), ClientCancelPlanSubscriptionToSubscriberNotification() => _ClientCancelPlanSubscriptionToSubscriberWidget( notification: notification as ClientCancelPlanSubscriptionToSubscriberNotification, ), UserDailyReportCompletedNotification() => _UserDailyReportCompletedWidget(notification: notification as UserDailyReportCompletedNotification), StayOnTrackToCustomerNotification() => _StayOnTrackToCustomerWidget(notification: notification as StayOnTrackToCustomerNotification), PhoneChangedNotification() => _PhoneChangedWidget(notification: notification as PhoneChangedNotification), SubscriptionNotification() => _SubscriptionWidget(notification: notification as SubscriptionNotification), BadgeAwardedNotification() => _BadgeAwardedWidget(notification: notification as BadgeAwardedNotification), BadgeRevokedNotification() => _BadgeRevokedWidget(notification: notification as BadgeRevokedNotification), ConsultantRequestStartedNotification() => _ConsultantRequestStartedWidget(notification: notification as ConsultantRequestStartedNotification), ClientCloseComplaintSuccessNotification() => _ClientCloseComplaintSuccessWidget(notification: notification as ClientCloseComplaintSuccessNotification), ClientRefundSuccessNotification() => _ClientRefundSuccessWidget(notification: notification as ClientRefundSuccessNotification), ConsultantRefundSuccessNotification() => _ConsultantRefundSuccessWidget(notification: notification as ConsultantRefundSuccessNotification), ClientRejectSuccessNotification() => _ClientRejectSuccessWidget(notification: notification as ClientRejectSuccessNotification), ConsultantRejectSuccessNotification() => _ConsultantRejectSuccessWidget(notification: notification as ConsultantRejectSuccessNotification), ScoreSubstractedNotification() => _ScoreSubstractedWidget(notification: notification as ScoreSubstractedNotification), ProductStatusUpdatedForAuthorNotification() => _ProductStatusUpdatedForAuthorWidget( notification: notification as ProductStatusUpdatedForAuthorNotification, ), DiaryReminderForUsersNotification() => _DiaryReminderForUsersWidget(notification: notification as DiaryReminderForUsersNotification), PersonalDietIsDefinedToCustomerNotification() => _PersonalDietIsDefinedToCustomerWidget( notification: notification as PersonalDietIsDefinedToCustomerNotification, ), // New Widgets ConsultantEducationUpdatedNotification() => _ConsultantEducationUpdatedWidget( notification: notification as ConsultantEducationUpdatedNotification, ), ComplaintRegisteredNotification() => _ComplaintRegisteredWidget(notification: notification as ComplaintRegisteredNotification), ContentUnpublishedNotification() => _ContentUnpublishedWidget(notification: notification as ContentUnpublishedNotification), FinanceQuestionCreatedNotification() => _FinanceQuestionCreatedWidget(notification: notification as FinanceQuestionCreatedNotification), NewChatMessageNotification() => _NewChatMessageWidget(notification: notification as NewChatMessageNotification), CompleteRegistrationNotification() => _CompleteRegistrationWidget(notification: notification as CompleteRegistrationNotification), ChosenDietExpiredNotification() => _ChosenDietExpiredWidget(notification: notification as ChosenDietExpiredNotification), MotivateUserNotification() => _MotivateUserWidget(notification: notification as MotivateUserNotification), CommentComplaintNotification() => _CommentComplaintWidget(notification: notification as CommentComplaintNotification), CommentDeletedNotification() => _CommentDeletedWidget(notification: notification as CommentDeletedNotification), UserSubscribedNotification() => _UserSubscribedWidget(notification: notification as UserSubscribedNotification), UnknownNotification() => _UnknownNotificationWidget(notification: notification as UnknownNotification), }; } } class _PlanSubscriptionStartedToAuthorWidget extends StatelessWidget { const _PlanSubscriptionStartedToAuthorWidget({required this.notification}); final PlanSubscriptionStartedToAuthorNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: '${s.userSubscribedToPlan(notification.customerName, notification.planName)}! 🎉', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PlanSubscriptionCanceledToAuthorWidget extends StatelessWidget { const _PlanSubscriptionCanceledToAuthorWidget({required this.notification}); final PlanSubscriptionCanceledToAuthorNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Отмена подписки. Клиент ${notification.customerName} отказался от плана "${notification.planName}"', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenPlanStartedToClientWidget extends StatelessWidget { const _ChosenPlanStartedToClientWidget({required this.notification}); final ChosenPlanStartedToClientNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваш план "${notification.planName}" начался! Удачи! 🚀', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenPlanTomorrowReminderToClientWidget extends StatelessWidget { const _ChosenPlanTomorrowReminderToClientWidget({required this.notification}); final ChosenPlanTomorrowReminderToClientNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Напоминание: Завтра старт плана "${notification.planName}"', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _DiaryReminderWidget extends StatelessWidget { const _DiaryReminderWidget({required this.notification}); final DiaryReminderNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Не забудьте заполнить дневник за вчера! 📝', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantLeftCommentWidget extends StatelessWidget { const _ConsultantLeftCommentWidget({required this.notification}); final ConsultantLeftCommentNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Новый комментарий от консультанта (за ${notification.date.format('dd.MM.yyyy')})', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PersonalizedDietIsDefinedWidget extends StatelessWidget { const _PersonalizedDietIsDefinedWidget({required this.notification}); final PersonalizedDietIsDefinedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Персональная диета определена', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenPlanFinishedToClientWidget extends StatelessWidget { const _ChosenPlanFinishedToClientWidget({required this.notification}); final ChosenPlanFinishedToClientNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Поздравляем! План «${notification.planName}» успешно завершен! 🏆', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PlanSubscriptionCanceledToCustomerWidget extends StatelessWidget { const _PlanSubscriptionCanceledToCustomerWidget({required this.notification}); final PlanSubscriptionCanceledToCustomerNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Подписка на план "${notification.planName}" отменена.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenPlanStartedToConsultantWidget extends StatelessWidget { const _ChosenPlanStartedToConsultantWidget({required this.notification}); final ChosenPlanStartedToConsultantNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Начало работы: План "${notification.planName}" с клиентом ${notification.customerName}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenPlanTomorrowReminderToConsultantWidget extends StatelessWidget { const _ChosenPlanTomorrowReminderToConsultantWidget({required this.notification}); final ChosenPlanTomorrowReminderToConsultantNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Напоминание: Завтра старт работы с ${notification.customerName} по плану "${notification.planName}"', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PlanSubscriptionPaidToAuthorWidget extends StatelessWidget { const _PlanSubscriptionPaidToAuthorWidget({required this.notification}); final PlanSubscriptionPaidToAuthorNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Оплата получена! Клиент ${notification.customerName} оплатил план "${notification.planName}" 💰', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenPlanFinishedToConsultantWidget extends StatelessWidget { const _ChosenPlanFinishedToConsultantWidget({required this.notification}); final ChosenPlanFinishedToConsultantNotification notification; @override Widget build(BuildContext context) { final s = S.of(context); return GestureDetector( onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), behavior: HitTestBehavior.opaque, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('План «${notification.planName}» завершен! Поздравляем! 🎉', style: TextStyles.textMSemibold.copyWith(color: appTheme.black)), const SizedBox(height: 12), Text(s.userConfirmedPlanCompletionWithoutSum, style: TextStyles.textSMedium.copyWith(color: appTheme.black)), const SizedBox(height: 12), CustomOutlinedButton( text: s.collectCharge, buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700), buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.green)), onPressed: () { GoRouter.of(context).push(CardSettingsScreen.path, extra: notification.planId); }, ), ], ), ), if (!notification.isRead) Container( decoration: BoxDecoration(color: appTheme.blueA400, shape: BoxShape.circle), width: 8, height: 8, ), ], ), const SizedBox(height: 4), Text( '${notification.createdAt.day} ${_getMonthName(notification.createdAt.month)} ${notification.createdAt.hour.toString().padLeft(2, '0')}:${notification.createdAt.minute.toString().padLeft(2, '0')}', style: TextStyles.textSMedium.copyWith(color: appTheme.gray600), ), ], ), ); } String _getMonthName(int month) { switch (month) { case 1: return 'янв'; case 2: return 'фев'; case 3: return 'мар'; case 4: return 'апр'; case 5: return 'май'; case 6: return 'июн'; case 7: return 'июл'; case 8: return 'авг'; case 9: return 'сен'; case 10: return 'окт'; case 11: return 'ноя'; case 12: return 'дек'; default: return ''; } } } // CardSettingsScreen class _BaseNotificationWidget extends StatelessWidget { const _BaseNotificationWidget({required this.notificationsText, required this.isRead, required this.createdAt, this.onTap}); final String notificationsText; final bool isRead; final DateTime createdAt; final void Function()? onTap; @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, behavior: HitTestBehavior.opaque, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text(notificationsText, style: TextStyles.textMMedium.copyWith(color: appTheme.black)), ), if (onTap != null) Padding( padding: const EdgeInsets.only(left: 8), child: Icon(Icons.chevron_right, color: appTheme.gray500, size: 20), ), if (!isRead) Container( margin: const EdgeInsets.only(left: 8), decoration: BoxDecoration(color: appTheme.blueA400, shape: BoxShape.circle), width: 8, height: 8, ), ], ), const SizedBox(height: 4), Text( '${createdAt.day} ${_getMonthName(createdAt.month)} ${createdAt.hour.toString().padLeft(2, '0')}:${createdAt.minute.toString().padLeft(2, '0')}', style: TextStyles.textSMedium.copyWith(color: appTheme.gray600), ), ], ), ); } String _getMonthName(int month) { switch (month) { case 1: return 'янв'; case 2: return 'фев'; case 3: return 'мар'; case 4: return 'апр'; case 5: return 'май'; case 6: return 'июн'; case 7: return 'июл'; case 8: return 'авг'; case 9: return 'сен'; case 10: return 'окт'; case 11: return 'ноя'; case 12: return 'дек'; default: return ''; } } } class _ChosenPlanLastDayFinishedForUserWidget extends StatelessWidget { const _ChosenPlanLastDayFinishedForUserWidget({required this.notification}); final ChosenPlanLastDayFinishedForUser notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget(isRead: notification.isRead, notificationsText: 'Финишная прямая! Последний день плана завершен.', createdAt: notification.createdAt); } } class _ChosenPlanConsultantLastDayStartedWidget extends StatelessWidget { const _ChosenPlanConsultantLastDayStartedWidget({required this.notification}); final ChosenPlanConsultantLastDayStarted notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Внимание: Начался последний день плана "${notification.planName}"', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ComplaintToModerationForUserWidget extends StatelessWidget { const _ComplaintToModerationForUserWidget({required this.notification}); final ComplaintToModerationForUser notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваша жалоба принята и находится на модерации.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _CommentRepliedWidget extends StatelessWidget { const _CommentRepliedWidget({required this.notification}); final CommentReplied notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Вам ответили в комментариях к: ${notification.entityName}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ScoreAddedWidget extends StatelessWidget { const _ScoreAddedWidget({required this.notification}); final ScoreAdded notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Поздравляем! Вам начислены баллы: ${notification.scoreValue} ⭐', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _EntityCommentedWidget extends StatelessWidget { const _EntityCommentedWidget({required this.notification}); final EntityCommented notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Новый комментарий к вашей публикации "${notification.entityTranslatedType}": ${notification.entityName}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _UnknownNotificationWidget extends StatelessWidget { const _UnknownNotificationWidget({required this.notification}); final UnknownNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'У вас новое уведомление! Пожалуйста, обновите приложение, чтобы увидеть детали.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } // Новые виджеты для дополнительных типов уведомлений class _PlanSubscriptionExpiredWidget extends StatelessWidget { const _PlanSubscriptionExpiredWidget({required this.notification}); final PlanSubscriptionExpiredNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Срок действия подписки на план "${notification.planName}" истек. Продлите, чтобы продолжить! ⏳', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PlanSubscriptionRenewedWidget extends StatelessWidget { const _PlanSubscriptionRenewedWidget({required this.notification}); final PlanSubscriptionRenewedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Успешное продление! Подписка на план "${notification.planName}" активна до ${notification.renewalDate} ✅', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantAssignedWidget extends StatelessWidget { const _ConsultantAssignedWidget({required this.notification}); final ConsultantAssignedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Вам назначен консультант ${notification.consultantName} по плану "${notification.planName}". Приветствуйте! 👋', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantUnassignedWidget extends StatelessWidget { const _ConsultantUnassignedWidget({required this.notification}); final ConsultantUnassignedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Изменение в плане "${notification.planName}": консультант ${notification.consultantName} отстранен.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PaymentFailedWidget extends StatelessWidget { const _PaymentFailedWidget({required this.notification}); final PaymentFailedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Не удалось провести оплату за план "${notification.planName}". Причина: ${notification.errorMessage} ❌', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PaymentSuccessfulWidget extends StatelessWidget { const _PaymentSuccessfulWidget({required this.notification}); final PaymentSuccessfulNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Оплата прошла успешно! План "${notification.planName}" оплачен на сумму ${notification.amount} ${notification.currency} 💳', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _GoalAchievedWidget extends StatelessWidget { const _GoalAchievedWidget({required this.notification}); final GoalAchievedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Цель достигнута! "${notification.goalName}": ${notification.achievedValue}/${notification.targetValue} 🎯', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _WorkoutReminderWidget extends StatelessWidget { const _WorkoutReminderWidget({required this.notification}); final WorkoutReminderNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Время тренировки! "${notification.workoutName}" ждет вас (${notification.duration} мин) 💪', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _MealReminderWidget extends StatelessWidget { const _MealReminderWidget({required this.notification}); final MealReminderNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Пора подкрепиться! "${notification.mealName}" (${notification.calories} ккал) 🍎', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } // New notification widget classes class _DietCancelledWidget extends StatelessWidget { const _DietCancelledWidget({required this.notification}); final DietCancelledNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Диета "${notification.dietName}" была отменена.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _DietStartedWidget extends StatelessWidget { const _DietStartedWidget({required this.notification}); final DietStartedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Старт диеты "${notification.dietName}"! Успехов! 🥗', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _DietExpiredWidget extends StatelessWidget { const _DietExpiredWidget({required this.notification}); final DietExpiredNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Срок действия диеты "${notification.dietName}" подошел к концу.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _DietWillStartedInWidget extends StatelessWidget { const _DietWillStartedInWidget({required this.notification}); final DietWillStartedInNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Скоро старт! Диета "${notification.dietName}" начнется ${notification.startDate} ⏰', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _DietCanNotBeStartedWidget extends StatelessWidget { const _DietCanNotBeStartedWidget({required this.notification}); final DietCanNotBeStartedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Внимание: Не удалось начать диету "${notification.dietName}". Причина: ${notification.reason}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PersonalDietCreationNeededWidget extends StatelessWidget { const _PersonalDietCreationNeededWidget({required this.notification}); final PersonalDietCreationNeededNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Задача: Создать персональную диету для клиента ${notification.clientName} (План "${notification.planName}")', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenPlanClientLastDayFinishedWidget extends StatelessWidget { const _ChosenPlanClientLastDayFinishedWidget({required this.notification}); final ChosenPlanClientLastDayFinishedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Поздравляем с завершением плана "${notification.planName}"! 🎉', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenPlanClientLastDayStartedWidget extends StatelessWidget { const _ChosenPlanClientLastDayStartedWidget({required this.notification}); final ChosenPlanClientLastDayStartedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Сегодня последний день плана "${notification.planName}"! Финиш близко! 🏁', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _StayOnTrackToAuthorWidget extends StatelessWidget { const _StayOnTrackToAuthorWidget({required this.notification}); final StayOnTrackToAuthorNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Клиент ${notification.clientName} продолжает уверенно идти по плану "${notification.planName}" 🔥', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientStartPlanSubscriptionToSubscriberWidget extends StatelessWidget { const _ClientStartPlanSubscriptionToSubscriberWidget({required this.notification}); final ClientStartPlanSubscriptionToSubscriberNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'У вас новая подписка на план "${notification.planName}"! 🌟', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantConfirmPlanSubscriptionToSubscriberWidget extends StatelessWidget { const _ConsultantConfirmPlanSubscriptionToSubscriberWidget({required this.notification}); final ConsultantConfirmPlanSubscriptionToSubscriberNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваша подписка на план "${notification.planName}" подтверждена консультантом ${notification.consultantName} ✅', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientPaidPlanSubscriptionToAuthorWidget extends StatelessWidget { const _ClientPaidPlanSubscriptionToAuthorWidget({required this.notification}); final ClientPaidPlanSubscriptionToAuthorNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Поступление средств: Клиент ${notification.clientName} оплатил подписку на план "${notification.planName}" (${notification.amount}) 💸', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantLeftDiaryCommentWidget extends StatelessWidget { const _ConsultantLeftDiaryCommentWidget({required this.notification}); final ConsultantLeftDiaryCommentNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваш консультант ${notification.consultantName} прокомментировал дневник по плану "${notification.planName}" 💬', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantConfirmPlanSubscriptionToAuthorWidget extends StatelessWidget { const _ConsultantConfirmPlanSubscriptionToAuthorWidget({required this.notification}); final ConsultantConfirmPlanSubscriptionToAuthorNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Консультант ${notification.consultantName} подтвердил подписку на план "${notification.planName}" 🤝', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientPaidPlanSubscriptionToSubscriberWidget extends StatelessWidget { const _ClientPaidPlanSubscriptionToSubscriberWidget({required this.notification}); final ClientPaidPlanSubscriptionToSubscriberNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Оплата подписки на план "${notification.planName}" прошла успешно (${notification.amount}) ✅', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientStartPlanSubscriptionToAuthorWidget extends StatelessWidget { const _ClientStartPlanSubscriptionToAuthorWidget({required this.notification}); final ClientStartPlanSubscriptionToAuthorNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Новый подписчик! Клиент ${notification.clientName} начал подписку на план "${notification.planName}" 🎈', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientCancelPlanSubscriptionToAuthorWidget extends StatelessWidget { const _ClientCancelPlanSubscriptionToAuthorWidget({required this.notification}); final ClientCancelPlanSubscriptionToAuthorNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Отмена подписки: Клиент ${notification.clientName} отказался от плана "${notification.planName}"', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientCancelPlanSubscriptionToSubscriberWidget extends StatelessWidget { const _ClientCancelPlanSubscriptionToSubscriberWidget({required this.notification}); final ClientCancelPlanSubscriptionToSubscriberNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваша подписка на план "${notification.planName}" была отменена.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _UserDailyReportCompletedWidget extends StatelessWidget { const _UserDailyReportCompletedWidget({required this.notification}); final UserDailyReportCompletedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Отчет получен: Клиент ${notification.clientName} заполнил дневник по плану "${notification.planName}" 📝', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _StayOnTrackToCustomerWidget extends StatelessWidget { const _StayOnTrackToCustomerWidget({required this.notification}); final StayOnTrackToCustomerNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Консультант ${notification.consultantName} продолжает работу с вами по плану "${notification.planName}" 💪', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PhoneChangedWidget extends StatelessWidget { const _PhoneChangedWidget({required this.notification}); final PhoneChangedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваш номер телефона был успешно изменен на ${notification.newPhone} 📱', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _SubscriptionWidget extends StatelessWidget { const _SubscriptionWidget({required this.notification}); final SubscriptionNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Оформлена подписка ${notification.subscriptionType} на план "${notification.planName}" 🎉', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _BadgeAwardedWidget extends StatelessWidget { const _BadgeAwardedWidget({required this.notification}); final BadgeAwardedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Новая награда! Вы получили значок "${notification.badgeName}": ${notification.badgeDescription} 🏅', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _BadgeRevokedWidget extends StatelessWidget { const _BadgeRevokedWidget({required this.notification}); final BadgeRevokedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Значок "${notification.badgeName}" был отозван. Причина: ${notification.reason}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantRequestStartedWidget extends StatelessWidget { const _ConsultantRequestStartedWidget({required this.notification}); final ConsultantRequestStartedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Запрос отправлен консультанту ${notification.consultantName} 📩', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientCloseComplaintSuccessWidget extends StatelessWidget { const _ClientCloseComplaintSuccessWidget({required this.notification}); final ClientCloseComplaintSuccessNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваша жалоба на ${notification.complaintType} "${notification.entityName}" была рассмотрена и закрыта.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientRefundSuccessWidget extends StatelessWidget { const _ClientRefundSuccessWidget({required this.notification}); final ClientRefundSuccessNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Вам одобрен возврат средств по плану "${notification.planName}" (${notification.amount}). Причина: ${notification.reason}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantRefundSuccessWidget extends StatelessWidget { const _ConsultantRefundSuccessWidget({required this.notification}); final ConsultantRefundSuccessNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Выполнен возврат средств клиенту ${notification.clientName} по плану "${notification.planName}" (${notification.amount})', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ClientRejectSuccessWidget extends StatelessWidget { const _ClientRejectSuccessWidget({required this.notification}); final ClientRejectSuccessNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Отказ по плану "${notification.planName}" принят: ${notification.reason}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantRejectSuccessWidget extends StatelessWidget { const _ConsultantRejectSuccessWidget({required this.notification}); final ConsultantRejectSuccessNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Клиент ${notification.clientName} отказался от плана "${notification.planName}": ${notification.reason}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ScoreSubstractedWidget extends StatelessWidget { const _ScoreSubstractedWidget({required this.notification}); final ScoreSubstractedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Списание баллов: -${notification.scoreValue} за ${notification.scorableName}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ProductStatusUpdatedForAuthorWidget extends StatelessWidget { const _ProductStatusUpdatedForAuthorWidget({required this.notification}); final ProductStatusUpdatedForAuthorNotification notification; @override Widget build(BuildContext context) { String text; if (notification.oldStatus.isNotEmpty && notification.newStatus.isNotEmpty) { text = 'Статус продукта "${notification.productName}" изменен с ${notification.oldStatus} на ${notification.newStatus}'; } else if (notification.newStatus.isNotEmpty) { text = 'Статус продукта "${notification.productName}" изменен на ${notification.newStatus}'; } else if (notification.status.isNotEmpty) { text = 'Статус продукта "${notification.productName}": ${notification.status}'; } else { text = 'Статус продукта "${notification.productName}" обновлен'; } return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: text, createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _DiaryReminderForUsersWidget extends StatelessWidget { const _DiaryReminderForUsersWidget({required this.notification}); final DiaryReminderForUsersNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Не забудьте заполнить дневник сегодня! 📓', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _PersonalDietIsDefinedToCustomerWidget extends StatelessWidget { const _PersonalDietIsDefinedToCustomerWidget({required this.notification}); final PersonalDietIsDefinedToCustomerNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Для вас составлена персональная диета "${notification.dietName}"! 🥗', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ConsultantEducationUpdatedWidget extends StatelessWidget { const _ConsultantEducationUpdatedWidget({required this.notification}); final ConsultantEducationUpdatedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Консультант ${notification.consultantName} обновил данные об образовании.', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ComplaintRegisteredWidget extends StatelessWidget { const _ComplaintRegisteredWidget({required this.notification}); final ComplaintRegisteredNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Мы получили вашу жалобу на ${notification.entityName}. Спасибо за сигнал!', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ContentUnpublishedWidget extends StatelessWidget { const _ContentUnpublishedWidget({required this.notification}); final ContentUnpublishedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваша публикация ${notification.entityName} была скрыта. Причина: ${notification.reason}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _FinanceQuestionCreatedWidget extends StatelessWidget { const _FinanceQuestionCreatedWidget({required this.notification}); final FinanceQuestionCreatedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Служба поддержки: Новый вопрос по финансам: ${notification.questionText}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _NewChatMessageWidget extends StatelessWidget { const _NewChatMessageWidget({required this.notification}); final NewChatMessageNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Входящее сообщение от ${notification.senderName}: "${notification.messagePreview}"', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _CompleteRegistrationWidget extends StatelessWidget { const _CompleteRegistrationWidget({required this.notification}); final CompleteRegistrationNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Завершите регистрацию, чтобы получить доступ ко всем функциям! 🚀', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _ChosenDietExpiredWidget extends StatelessWidget { const _ChosenDietExpiredWidget({required this.notification}); final ChosenDietExpiredNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Диета "${notification.dietName}" завершена. Время подвести итоги!', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _MotivateUserWidget extends StatelessWidget { const _MotivateUserWidget({required this.notification}); final MotivateUserNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: notification.message, createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _CommentComplaintWidget extends StatelessWidget { const _CommentComplaintWidget({required this.notification}); final CommentComplaintNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Поступила жалоба на ваш комментарий: "${notification.commentPreview}". Причина: ${notification.reason}', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _CommentDeletedWidget extends StatelessWidget { const _CommentDeletedWidget({required this.notification}); final CommentDeletedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'Ваш комментарий был удален по правилам сообщества: "${notification.commentPreview}"', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } } class _UserSubscribedWidget extends StatelessWidget { const _UserSubscribedWidget({required this.notification}); final UserSubscribedNotification notification; @override Widget build(BuildContext context) { return _BaseNotificationWidget( isRead: notification.isRead, notificationsText: 'У вас новый подписчик: ${notification.subscriberName}! 👋', createdAt: notification.createdAt, onTap: () => (context.findAncestorWidgetOfExactType() as NotificationWidget)._onTap(context), ); } }