fix(notifications): Issue-191

This commit is contained in:
mso7nueh
2025-08-15 13:28:12 +03:00
parent 2f74387df2
commit 4f249499a9
4 changed files with 1876 additions and 35 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -66,12 +66,6 @@ class NotificationsCubit extends Cubit<NotificationsState> {
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanFinishedToClient => ChosenPlanFinishedToClientNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.planSubscriptionCanceledToCustomer => PlanSubscriptionCanceledToAuthorNotification.fromJson(
notificationJson,
type,
@@ -96,12 +90,6 @@ class NotificationsCubit extends Cubit<NotificationsState> {
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanFinishedToConsultant => ChosenPlanFinishedToConsultantNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanLastDayFinishedForUser => ChosenPlanLastDayFinishedForUser.fromJson(
notificationJson,
type,
@@ -123,6 +111,156 @@ class NotificationsCubit extends Cubit<NotificationsState> {
NotificationType.goalAchieved => GoalAchievedNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.workoutReminder => WorkoutReminderNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.mealReminder => MealReminderNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
// New notification types
NotificationType.dietCancelled => DietCancelledNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.dietStarted => DietStartedNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.dietExpired => DietExpiredNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.dietWillStartedIn => DietWillStartedInNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.dietCanNotBeStarted => DietCanNotBeStartedNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.personalDietCreationNeeded => PersonalDietCreationNeededNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanClientLastDayFinished => ChosenPlanClientLastDayFinishedNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanClientLastDayStarted => ChosenPlanClientLastDayStartedNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.stayOnTrackToAuthor => StayOnTrackToAuthorNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.chosenPlanStartedToClient => ChosenPlanStartedToClientNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.clientStartPlanSubscriptionToSubscriber => ClientStartPlanSubscriptionToSubscriberNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.consultantConfirmPlanSubscriptionToSubscriber => ConsultantConfirmPlanSubscriptionToSubscriberNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.clientPaidPlanSubscriptionToAuthor => ClientPaidPlanSubscriptionToAuthorNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanTomorrowReminderToClient => ChosenPlanTomorrowReminderToClientNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanTomorrowReminderToConsultant => ChosenPlanTomorrowReminderToConsultantNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanStartedToConsultant => ChosenPlanStartedToConsultantNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.consultantLeftDiaryComment => ConsultantLeftDiaryCommentNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanFinishedToClient => ChosenPlanFinishedToClientNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.consultantConfirmPlanSubscriptionToAuthor => ConsultantConfirmPlanSubscriptionToAuthorNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.clientPaidPlanSubscriptionToSubscriber => ClientPaidPlanSubscriptionToSubscriberNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.clientStartPlanSubscriptionToAuthor => ClientStartPlanSubscriptionToAuthorNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.clientCancelPlanSubscriptionToAuthor => ClientCancelPlanSubscriptionToAuthorNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.clientCancelPlanSubscriptionToSubscriber => ClientCancelPlanSubscriptionToSubscriberNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.userDailyReportCompleted => UserDailyReportCompletedNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.chosenPlanFinishedToConsultant => ChosenPlanFinishedToConsultantNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.stayOnTrackToCustomer => StayOnTrackToCustomerNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.phoneChanged => PhoneChangedNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.subscription => SubscriptionNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.badgeAwarded => BadgeAwardedNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.badgeRevoked => BadgeRevokedNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.consultantRequestStarted => ConsultantRequestStartedNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.clientCloseComplaintSuccess => ClientCloseComplaintSuccessNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.clientRefundSuccess => ClientRefundSuccessNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.consultantRefundSuccess => ConsultantRefundSuccessNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.clientRejectSuccess => ClientRejectSuccessNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.consultantRejectSuccess => ConsultantRejectSuccessNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.scoreSubstracted => ScoreSubstractedNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.productStatusUpdatedForAuthor => ProductStatusUpdatedForAuthorNotification.fromJson(
notificationJson,
type,
isRead: isRead,
createdAt: createdAt,
),
NotificationType.diaryReminderForUsers => DiaryReminderForUsersNotification.fromJson(notificationJson, type, isRead: isRead, createdAt: createdAt),
NotificationType.unknown => UnknownNotification(type: type),
};
} catch (e) {
@@ -132,8 +270,36 @@ class NotificationsCubit extends Cubit<NotificationsState> {
void _handleNotification(String notificationData) {
final json = jsonDecode(notificationData) as Map<String, dynamic>;
final stringifiedType = json['notification_class_name'];
final type = NotificationType.getTypeFromString(stringifiedType);
// Улучшенная логика определения типа уведомления
String? stringifiedType;
// Сначала проверяем поле 'type' в корне JSON
if (json.containsKey('type') && json['type'] != null) {
stringifiedType = json['type'].toString();
log('Found type in root: $stringifiedType');
}
// Затем проверяем поле 'notification_class_name' в корне JSON
else if (json.containsKey('notification_class_name') && json['notification_class_name'] != null) {
stringifiedType = json['notification_class_name'].toString();
log('Found notification_class_name in root: $stringifiedType');
}
// Если есть поле 'data', проверяем внутри него
else if (json.containsKey('data') && json['data'] is Map<String, dynamic>) {
final data = json['data'] as Map<String, dynamic>;
if (data.containsKey('type') && data['type'] != null) {
stringifiedType = data['type'].toString();
log('Found type in data: $stringifiedType');
} else if (data.containsKey('notification_class_name') && data['notification_class_name'] != null) {
stringifiedType = data['notification_class_name'].toString();
log('Found notification_class_name in data: $stringifiedType');
}
}
// Если тип не найден, используем unknown
final type = stringifiedType != null ? NotificationType.getTypeFromString(stringifiedType) : NotificationType.unknown;
log('Final type: $type, stringifiedType: $stringifiedType');
final notification = _parseNotification(json, type);
_notifications.insert(0, notification);

View File

@@ -57,6 +57,62 @@ class NotificationWidget extends StatelessWidget {
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),
UnknownNotification() => _UnknownNotificationWidget(notification: notification as UnknownNotification),
};
}
@@ -571,3 +627,429 @@ class _MealReminderWidget extends StatelessWidget {
);
}
}
// 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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
class _ConsultantConfirmPlanSubscriptionToSubscriberWidget extends StatelessWidget {
const _ConsultantConfirmPlanSubscriptionToSubscriberWidget({required this.notification});
final ConsultantConfirmPlanSubscriptionToSubscriberNotification notification;
@override
Widget build(BuildContext context) {
return _BaseNotificationWidget(
isRead: notification.isRead,
notificationsText: 'Консультант ${notification.consultantName} подтвердил подписку на план "${notification.planName}"',
createdAt: notification.createdAt,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
class _PhoneChangedWidget extends StatelessWidget {
const _PhoneChangedWidget({required this.notification});
final PhoneChangedNotification notification;
@override
Widget build(BuildContext context) {
return _BaseNotificationWidget(
isRead: notification.isRead,
notificationsText: 'Номер телефона изменен с ${notification.oldPhone} на ${notification.newPhone}',
createdAt: notification.createdAt,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
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,
);
}
}
class _ProductStatusUpdatedForAuthorWidget extends StatelessWidget {
const _ProductStatusUpdatedForAuthorWidget({required this.notification});
final ProductStatusUpdatedForAuthorNotification notification;
@override
Widget build(BuildContext context) {
return _BaseNotificationWidget(
isRead: notification.isRead,
notificationsText: 'Статус продукта "${notification.productName}" изменен с ${notification.oldStatus} на ${notification.newStatus}',
createdAt: notification.createdAt,
);
}
}
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);
}
}

View File

@@ -13,10 +13,30 @@ class NotificationsService {
final notifications = data.map((notificationJson) {
try {
final stringifiedType = notificationJson['data']['notification_class_name'];
// Улучшенная логика определения типа уведомления
String? stringifiedType;
// Сначала проверяем поле 'type' в корне JSON
if (notificationJson.containsKey('type') && notificationJson['type'] != null) {
stringifiedType = notificationJson['type'].toString();
}
// Затем проверяем поле 'notification_class_name' в корне JSON
else if (notificationJson.containsKey('notification_class_name') && notificationJson['notification_class_name'] != null) {
stringifiedType = notificationJson['notification_class_name'].toString();
}
// Если есть поле 'data', проверяем внутри него
else if (notificationJson.containsKey('data') && notificationJson['data'] is Map<String, dynamic>) {
final data = notificationJson['data'] as Map<String, dynamic>;
if (data.containsKey('type') && data['type'] != null) {
stringifiedType = data['type'].toString();
} else if (data.containsKey('notification_class_name') && data['notification_class_name'] != null) {
stringifiedType = data['notification_class_name'].toString();
}
}
final readDate = notificationJson['read_at'];
final createdAt = notificationJson['created_at'];
final type = NotificationType.getTypeFromString(stringifiedType);
final type = stringifiedType != null ? NotificationType.getTypeFromString(stringifiedType) : NotificationType.unknown;
return switch (type) {
NotificationType.planSubscriptionStartedToAuthor => PlanSubscriptionStartedToAuthorNotification.fromJson(
@@ -174,6 +194,219 @@ class NotificationsService {
isRead: readDate != null,
createdAt: createdAt,
),
// New notification types
NotificationType.dietCancelled => DietCancelledNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.dietStarted => DietStartedNotification.fromJson(notificationJson['data'], type, isRead: readDate != null, createdAt: createdAt),
NotificationType.dietExpired => DietExpiredNotification.fromJson(notificationJson['data'], type, isRead: readDate != null, createdAt: createdAt),
NotificationType.dietWillStartedIn => DietWillStartedInNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.dietCanNotBeStarted => DietCanNotBeStartedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.personalDietCreationNeeded => PersonalDietCreationNeededNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.chosenPlanClientLastDayFinished => ChosenPlanClientLastDayFinishedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.chosenPlanClientLastDayStarted => ChosenPlanClientLastDayStartedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.stayOnTrackToAuthor => StayOnTrackToAuthorNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.chosenPlanStartedToClient => ChosenPlanStartedToClientNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientStartPlanSubscriptionToSubscriber => ClientStartPlanSubscriptionToSubscriberNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.consultantConfirmPlanSubscriptionToSubscriber => ConsultantConfirmPlanSubscriptionToSubscriberNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientPaidPlanSubscriptionToAuthor => ClientPaidPlanSubscriptionToAuthorNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.chosenPlanTomorrowReminderToClient => ChosenPlanTomorrowReminderToClientNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.chosenPlanTomorrowReminderToConsultant => ChosenPlanTomorrowReminderToConsultantNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.chosenPlanStartedToConsultant => ChosenPlanStartedToConsultantNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.consultantLeftDiaryComment => ConsultantLeftDiaryCommentNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.consultantConfirmPlanSubscriptionToAuthor => ConsultantConfirmPlanSubscriptionToAuthorNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientPaidPlanSubscriptionToSubscriber => ClientPaidPlanSubscriptionToSubscriberNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientStartPlanSubscriptionToAuthor => ClientStartPlanSubscriptionToAuthorNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientCancelPlanSubscriptionToAuthor => ClientCancelPlanSubscriptionToAuthorNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientCancelPlanSubscriptionToSubscriber => ClientCancelPlanSubscriptionToSubscriberNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.userDailyReportCompleted => UserDailyReportCompletedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.stayOnTrackToCustomer => StayOnTrackToCustomerNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.phoneChanged => PhoneChangedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.subscription => SubscriptionNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.badgeAwarded => BadgeAwardedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.badgeRevoked => BadgeRevokedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.consultantRequestStarted => ConsultantRequestStartedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientCloseComplaintSuccess => ClientCloseComplaintSuccessNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientRefundSuccess => ClientRefundSuccessNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.consultantRefundSuccess => ConsultantRefundSuccessNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.clientRejectSuccess => ClientRejectSuccessNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.consultantRejectSuccess => ConsultantRejectSuccessNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.scoreSubstracted => ScoreSubstractedNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.productStatusUpdatedForAuthor => ProductStatusUpdatedForAuthorNotification.fromJson(
notificationJson['data'],
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.diaryReminderForUsers => DiaryReminderForUsersNotification.fromJson(
notificationJson,
type,
isRead: readDate != null,
createdAt: createdAt,
),
NotificationType.unknown => UnknownNotification(type: type, createdAt: parseDate(createdAt)),
};
} catch (e) {