forked from eatvio/eatvio_app
fix: show personal diet name and consultant notifications
This commit is contained in:
@@ -194,6 +194,7 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
: mapConsultationProgress(
|
||||
state: chosenPlan.chosenPlanState,
|
||||
hasPersonalDiet: chosenOption?.hasPersonalDiet ?? false,
|
||||
personalDietName: chosenPlan.personalDietName,
|
||||
);
|
||||
final bannerType = resolveChatBanner(
|
||||
progress: progress,
|
||||
|
||||
@@ -24,6 +24,7 @@ abstract class ConsultationModel with _$ConsultationModel {
|
||||
@JsonKey(name: 'consultant_id') required int consultantId,
|
||||
required List<DiaryModel> diaries,
|
||||
@JsonKey(name: 'personal_diet_id') required int? personalDietId,
|
||||
@JsonKey(name: 'personal_diet_name') String? personalDietName,
|
||||
}) = _ConsultationModel;
|
||||
|
||||
factory ConsultationModel.fromJson(Map<String, dynamic> json) => _$ConsultationModelFromJson(json);
|
||||
|
||||
@@ -10,12 +10,14 @@ class ConsultationProgress {
|
||||
required this.showProgressPlank,
|
||||
required this.dietStatus,
|
||||
required this.phase,
|
||||
this.personalDietName,
|
||||
});
|
||||
|
||||
final Set<ConsultationStep> completedSteps;
|
||||
final bool showProgressPlank;
|
||||
final PersonalDietStatus dietStatus;
|
||||
final ConsultationPhase phase;
|
||||
final String? personalDietName;
|
||||
|
||||
bool isStepCompleted(ConsultationStep step) => completedSteps.contains(step);
|
||||
|
||||
|
||||
@@ -97,7 +97,12 @@ class _ConsultationCardWidgetState extends State<ConsultationCardWidget> {
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
child: Text(
|
||||
s.personal_diet_proposed,
|
||||
widget.consultationsModel.personalDietName == null ||
|
||||
widget.consultationsModel.personalDietName!.isEmpty
|
||||
? s.personal_diet_proposed
|
||||
: s.personal_diet_proposed_named(
|
||||
widget.consultationsModel.personalDietName!,
|
||||
),
|
||||
style: TextStyles.textXSSemibold.copyWith(
|
||||
color: appTheme.greenA700,
|
||||
),
|
||||
|
||||
@@ -42,8 +42,12 @@ class PersonalDietStatusChip extends StatelessWidget {
|
||||
return (s.payment_failed, appTheme.lightRed, appTheme.red);
|
||||
}
|
||||
if (progress.dietStatus == PersonalDietStatus.proposed) {
|
||||
final dietName = progress.personalDietName;
|
||||
final label = dietName == null || dietName.isEmpty
|
||||
? s.personal_diet_proposed
|
||||
: s.personal_diet_proposed_named(dietName);
|
||||
return (
|
||||
s.personal_diet_proposed,
|
||||
label,
|
||||
appTheme.transparentGreen,
|
||||
appTheme.greenA700,
|
||||
);
|
||||
|
||||
@@ -4,12 +4,14 @@ import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart';
|
||||
ConsultationProgress mapConsultationProgress({
|
||||
required ChosenPlanStateEnum state,
|
||||
required bool hasPersonalDiet,
|
||||
String? personalDietName,
|
||||
}) {
|
||||
return ConsultationProgress(
|
||||
completedSteps: _completedSteps(state),
|
||||
showProgressPlank: _showProgressPlank(state),
|
||||
dietStatus: _dietStatus(state, hasPersonalDiet),
|
||||
phase: _phase(state),
|
||||
personalDietName: personalDietName,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2174,6 +2174,56 @@ class PersonalDietIsDefinedToCustomerNotification implements BaseNotificationMod
|
||||
}
|
||||
}
|
||||
|
||||
class PersonalDietIsDefinedToAuthorNotification implements BaseNotificationModel {
|
||||
@override
|
||||
final NotificationType type;
|
||||
@override
|
||||
final bool isRead;
|
||||
@override
|
||||
final DateTime createdAt;
|
||||
final int chosenPlanId;
|
||||
final int dietId;
|
||||
final String planName;
|
||||
final String userName;
|
||||
final String consultantName;
|
||||
final String dietName;
|
||||
final String role;
|
||||
final String peerSlug;
|
||||
final String peerImagePath;
|
||||
|
||||
PersonalDietIsDefinedToAuthorNotification({
|
||||
required this.type,
|
||||
required this.isRead,
|
||||
required this.createdAt,
|
||||
required this.chosenPlanId,
|
||||
required this.dietId,
|
||||
required this.planName,
|
||||
required this.userName,
|
||||
required this.consultantName,
|
||||
required this.dietName,
|
||||
required this.role,
|
||||
required this.peerSlug,
|
||||
required this.peerImagePath,
|
||||
});
|
||||
|
||||
factory PersonalDietIsDefinedToAuthorNotification.fromJson(Map<String, dynamic> json, NotificationType type, {bool? isRead, String? createdAt}) {
|
||||
return PersonalDietIsDefinedToAuthorNotification(
|
||||
type: type,
|
||||
isRead: isRead ?? false,
|
||||
createdAt: parseDate(createdAt ?? json['created_at'] ?? DateTime.now().toIso8601String()),
|
||||
chosenPlanId: json['chosen_plan_id'] ?? 0,
|
||||
dietId: json['diet_id'] ?? 0,
|
||||
planName: json['plan_name'] ?? '',
|
||||
userName: json['user_name'] ?? '',
|
||||
consultantName: json['consultant_name'] ?? '',
|
||||
dietName: json['diet_name'] ?? '',
|
||||
role: json['role']?.toString() ?? '',
|
||||
peerSlug: json['peer_slug'] ?? '',
|
||||
peerImagePath: json['peer_image_path'] ?? '',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// New Model Classes for Comprehensive Support
|
||||
|
||||
class ConsultantEducationUpdatedNotification implements BaseNotificationModel {
|
||||
@@ -2480,6 +2530,7 @@ enum NotificationType {
|
||||
chosenPlanFinishedToConsultant,
|
||||
stayOnTrackToCustomer,
|
||||
personalDietIsDefinedToCustomer,
|
||||
personalDietIsDefinedToAuthor,
|
||||
|
||||
// Comments
|
||||
entityCommented,
|
||||
@@ -2602,6 +2653,7 @@ enum NotificationType {
|
||||
'stay-on-track-to-customer' => NotificationType.stayOnTrackToCustomer,
|
||||
'diary-reminder-for-users' => NotificationType.diaryReminderForUsers,
|
||||
'personal-diet-is-defined-to-customer' => NotificationType.personalDietIsDefinedToCustomer,
|
||||
'personal-diet-is-defined-to-author' => NotificationType.personalDietIsDefinedToAuthor,
|
||||
|
||||
// New additions
|
||||
'consultant-education-updated' => NotificationType.consultantEducationUpdated,
|
||||
|
||||
@@ -277,6 +277,12 @@ class NotificationsCubit extends Cubit<NotificationsState> {
|
||||
isRead: isRead,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
NotificationType.personalDietIsDefinedToAuthor => PersonalDietIsDefinedToAuthorNotification.fromJson(
|
||||
notificationJson,
|
||||
type,
|
||||
isRead: isRead,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
NotificationType.consultantEducationUpdated => ConsultantEducationUpdatedNotification.fromJson(
|
||||
notificationJson,
|
||||
type,
|
||||
|
||||
@@ -122,6 +122,9 @@ class NotificationWidget extends StatelessWidget {
|
||||
PersonalDietIsDefinedToCustomerNotification() => _PersonalDietIsDefinedToCustomerWidget(
|
||||
notification: notification as PersonalDietIsDefinedToCustomerNotification,
|
||||
),
|
||||
PersonalDietIsDefinedToAuthorNotification() => _PersonalDietIsDefinedToAuthorWidget(
|
||||
notification: notification as PersonalDietIsDefinedToAuthorNotification,
|
||||
),
|
||||
// New Widgets
|
||||
ConsultantEducationUpdatedNotification() => _ConsultantEducationUpdatedWidget(notification: notification as ConsultantEducationUpdatedNotification),
|
||||
ComplaintRegisteredNotification() => _ComplaintRegisteredWidget(notification: notification as ComplaintRegisteredNotification),
|
||||
@@ -1273,6 +1276,27 @@ class _PersonalDietIsDefinedToCustomerWidget extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _PersonalDietIsDefinedToAuthorWidget extends StatelessWidget {
|
||||
const _PersonalDietIsDefinedToAuthorWidget({required this.notification});
|
||||
final PersonalDietIsDefinedToAuthorNotification notification;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final userName = notification.userName.isNotEmpty ? notification.userName : 'Пользователь';
|
||||
final dietName = notification.dietName.isNotEmpty ? ', выбранная диета: «${notification.dietName}»' : '';
|
||||
|
||||
return _BaseNotificationWidget(
|
||||
isRead: notification.isRead,
|
||||
notificationsText: 'Вы предложили персональную диету пользователю $userName$dietName',
|
||||
createdAt: notification.createdAt,
|
||||
onTap: notification.peerSlug.isEmpty
|
||||
? null
|
||||
: () {
|
||||
context.push(RouteConstants.profileScreen, extra: notification.peerSlug);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ConsultantEducationUpdatedWidget extends StatelessWidget {
|
||||
const _ConsultantEducationUpdatedWidget({required this.notification});
|
||||
final ConsultantEducationUpdatedNotification notification;
|
||||
|
||||
@@ -413,6 +413,12 @@ class NotificationsService {
|
||||
isRead: readDate != null,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
NotificationType.personalDietIsDefinedToAuthor => PersonalDietIsDefinedToAuthorNotification.fromJson(
|
||||
notificationJson['data'],
|
||||
type,
|
||||
isRead: readDate != null,
|
||||
createdAt: createdAt,
|
||||
),
|
||||
NotificationType.consultantEducationUpdated => ConsultantEducationUpdatedNotification.fromJson(
|
||||
notificationJson['data'],
|
||||
type,
|
||||
|
||||
@@ -15,6 +15,7 @@ abstract class ChosenPlanModel with _$ChosenPlanModel {
|
||||
@JsonKey(name: 'last_state') required ChosenPlanStateEnum chosenPlanState,
|
||||
@JsonKey(name: 'chat_id') required String chatId,
|
||||
@JsonKey(name: 'consultant_id') required int consultantId,
|
||||
@JsonKey(name: 'personal_diet_name') String? personalDietName,
|
||||
@JsonKey(name: 'plan') required PlanModel plan,
|
||||
}) = _ChosenPlanModel;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user