Files
eatvio_app/lib/features/notifications/presentation/widgets/notification_widget.dart
2025-08-06 11:28:02 +03:00

446 lines
17 KiB
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';
class NotificationWidget extends StatelessWidget {
const NotificationWidget({super.key, required this.notification});
final BaseNotificationModel notification;
@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),
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,
);
}
}
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: s.userCanceldThePlanSubscription(notification.customerName, notification.planName),
createdAt: notification.createdAt,
);
}
}
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: s.planStarted(notification.planName), createdAt: notification.createdAt);
}
}
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: s.tomorrowYourPlanWillStart(notification.planName),
createdAt: notification.createdAt,
);
}
}
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: s.fillYasterday, createdAt: notification.createdAt);
}
}
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: s.consultantLeftComment(notification.date.format('dd.MM.yyyy')),
createdAt: notification.createdAt,
);
}
}
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);
}
}
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: '${s.congratsYouHaveFinishedPlan} «${notification.planName}»',
createdAt: notification.createdAt,
);
}
}
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: s.youCanceledSubscriptionToPlan(notification.planName),
createdAt: notification.createdAt,
);
}
}
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: s.planWithUserStarted(notification.planName, notification.customerName),
createdAt: notification.createdAt,
);
}
}
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: s.tommorowPlanWithUserWillStart(notification.planName, notification.customerName),
createdAt: notification.createdAt,
);
}
}
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: s.userPaidThePlan(notification.customerName, notification.planName),
createdAt: notification.createdAt,
);
}
}
class _ChosenPlanFinishedToConsultantWidget extends StatelessWidget {
const _ChosenPlanFinishedToConsultantWidget({required this.notification});
final ChosenPlanFinishedToConsultantNotification notification;
@override
Widget build(BuildContext context) {
final s = S.of(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('${s.congratsYouHaveFinishedPlan} «${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).pushNamed(CardSettingsScreen.name, 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});
final String notificationsText;
final bool isRead;
final DateTime createdAt;
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(notificationsText, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
),
if (!isRead)
Container(
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,
);
}
}
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);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
class _UnknownNotificationWidget extends StatelessWidget {
const _UnknownNotificationWidget({required this.notification});
final UnknownNotification notification;
@override
Widget build(BuildContext context) {
return _BaseNotificationWidget(
isRead: notification.isRead,
notificationsText: 'Неизвестное уведомление: ${notification.type.toString()}',
createdAt: notification.createdAt,
);
}
}