diff --git a/.DS_Store b/.DS_Store
index 1ea62397..097b747a 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/assets/icons/star.svg b/assets/icons/star.svg
new file mode 100644
index 00000000..6a077d0e
--- /dev/null
+++ b/assets/icons/star.svg
@@ -0,0 +1,3 @@
+
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index c67b16dc..c2ccb23a 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -386,12 +386,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
- CODE_SIGN_IDENTITY = "Apple Distribution";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7;
- DEVELOPMENT_TEAM = "VL68C36HYS";
- "DEVELOPMENT_TEAM[sdk=iphoneos*]" = VL68C36HYS;
+ DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -411,8 +409,7 @@
MARKETING_VERSION = 1.0.50;
PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app;
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = "Distribution";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Distribution;
+ PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
@@ -539,12 +536,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
- CODE_SIGN_IDENTITY = "Apple Distribution";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7;
- DEVELOPMENT_TEAM = "VL68C36HYS";
- "DEVELOPMENT_TEAM[sdk=iphoneos*]" = VL68C36HYS;
+ DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -564,8 +559,7 @@
MARKETING_VERSION = 1.0.50;
PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app;
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = "Distribution";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Distribution;
+ PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
@@ -580,12 +574,10 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
- CODE_SIGN_IDENTITY = "Apple Distribution";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
- CODE_SIGN_STYLE = Manual;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 7;
- DEVELOPMENT_TEAM = "VL68C36HYS";
- "DEVELOPMENT_TEAM[sdk=iphoneos*]" = VL68C36HYS;
+ DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -605,8 +597,7 @@
MARKETING_VERSION = 1.0.50;
PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app;
PRODUCT_NAME = "$(TARGET_NAME)";
- PROVISIONING_PROFILE_SPECIFIER = "Distribution";
- "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = Distribution;
+ PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
diff --git a/lib/core/app_router.dart b/lib/core/app_router.dart
index 930ab4d0..63ec1094 100644
--- a/lib/core/app_router.dart
+++ b/lib/core/app_router.dart
@@ -174,7 +174,10 @@ class AppRouter {
GoRoute(
path: CardSettingsScreen.path,
name: CardSettingsScreen.name,
- builder: (context, state) => const CardSettingsScreen(),
+ builder: (context, state) {
+ final chosenPlanId = state.extra as int?;
+ return CardSettingsScreen(chosenPlanId: chosenPlanId);
+ },
),
GoRoute(
path: '/about-plan-screen',
@@ -220,7 +223,8 @@ class AppRouter {
builder: (context, state) {
final data = state.extra as Map;
final chatId = data['chatId'] as String;
- return ChatScreen(chatId: chatId);
+ final sendInitialMessage = data['sendInitialMessage'] as bool?;
+ return ChatScreen(chatId: chatId, sendInitialMessage: sendInitialMessage,);
},
),
GoRoute(
diff --git a/lib/core/const.dart b/lib/core/const.dart
index 31c47e9c..4f38a54e 100644
--- a/lib/core/const.dart
+++ b/lib/core/const.dart
@@ -1,5 +1,5 @@
-String baseUrl = 'https://eatvio.ru';
-// String baseUrl = 'https://dev2.eatvio.com';
+// String baseUrl = 'https://eatvio.ru';
+String baseUrl = 'https://dev2.eatvio.com';
const List durationValues = [7, 14, 21];
diff --git a/lib/core/locator_service.dart b/lib/core/locator_service.dart
index 8794ce95..c2c27015 100644
--- a/lib/core/locator_service.dart
+++ b/lib/core/locator_service.dart
@@ -19,6 +19,8 @@ import 'package:eatvio_app/features/create_diet/presentation/cubit/create_diet_c
import 'package:eatvio_app/features/create_diet/repositories/create_diet_repository.dart';
import 'package:eatvio_app/features/create_diet/services/create_diet_service.dart';
import 'package:eatvio_app/features/create_plan/presentation/cubit/create_plan_cubit.dart';
+import 'package:eatvio_app/features/create_plan/repositories/create_plan_repository.dart';
+import 'package:eatvio_app/features/create_plan/services/create_plan_service.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/consultant_comments_cubit/consultant_comments_cubit.dart';
import 'package:eatvio_app/features/diets/repositories/diet_repository.dart';
import 'package:eatvio_app/features/diets/services/diet_service.dart';
@@ -96,11 +98,11 @@ Future init() async {
sl.registerLazySingleton(() => WsManager(wsService: sl()));
sl.registerLazySingleton(() => NewMessagesCubit());
sl.registerLazySingleton(() => NotificationsCubit(wsManager: sl()));
- sl.registerLazySingleton(() => FeedCubit(feedRepository: sl()));
sl.registerLazySingleton(() => ProfileAvatarCubit(profileRepository: sl()));
sl.registerLazySingleton(() => ChatsCubit(chatRepository: sl(), wsManager: sl(), profileRepository: sl()));
// Cubit factories
+ sl.registerFactory(() => FeedCubit(feedRepository: sl()));
sl.registerFactory(() => RegistrationCubit(registrationRepository: sl()));
sl.registerFactory(() => ChatRoomCubit(cardsRepository: sl(), chatRepository: sl(), wsManager: sl()));
sl.registerFactory(() => RecipesCubit(feedRepository: sl(), recipeRepository: sl(), aboutRecipeRepository: sl()));
@@ -112,12 +114,12 @@ Future init() async {
sl.registerFactory(() => PlansCubit(feedRepository: sl(), planRepository: sl()));
sl.registerFactory(() => SettingsCubit(profileRepository: sl(), settingsRepository: sl()));
sl.registerFactory(() => RegisterConsultantCubit(consultantRepository: sl()));
- sl.registerFactory(() => DiaryCubit(diaryRepository: sl(), glossaryRepository: sl()));
+ sl.registerFactory(() => DiaryCubit(diaryRepository: sl(), glossaryRepository: sl(), profileRepository: sl()));
sl.registerFactory(() => AboutDietCubit(dietsRepository: sl(), profileRepository: sl()));
sl.registerFactory(() => BlogPostCreateCubit(blogPostRepository: sl()));
sl.registerFactory(() => SubCubit(profileRepository: sl()));
sl.registerFactory(() => CreateDietCubit(profileRepository: sl(), createDietRepository: sl(), glossaryRepository: sl()));
- sl.registerFactory(() => CreatePlanCubit());
+ sl.registerFactory(() => CreatePlanCubit(createPlanRepository: sl()));
sl.registerFactory(() => FeedProfileCubit(profileRepository: sl()));
sl.registerFactory(() => AboutPlanCubit(planRepository: sl()));
sl.registerFactory(() => CreateRecipeCubit(recipeRepository: sl()));
@@ -158,6 +160,7 @@ Future init() async {
sl.registerLazySingleton(() => CardsRepository(cardsService: sl()));
sl.registerLazySingleton(() => ConsultationsRepository(consultationService: sl()));
sl.registerLazySingleton(() => CancelPlanRepository(cancelService: sl()));
+ sl.registerLazySingleton(() => CreatePlanRepository(createPlanService: sl()));
// Services
sl.registerLazySingleton(() => ChatService(sl()));
@@ -184,6 +187,7 @@ Future init() async {
sl.registerLazySingleton(() => CardsService(sl()));
sl.registerLazySingleton(() => ConsultationService(sl()));
sl.registerLazySingleton(() => CancelPlanService(sl()));
+ sl.registerLazySingleton(() => CreatePlanService(sl()));
// External
sl.registerLazySingleton(
diff --git a/lib/core/theme/theme_helper.dart b/lib/core/theme/theme_helper.dart
index 9bed83fd..aa4e30a6 100644
--- a/lib/core/theme/theme_helper.dart
+++ b/lib/core/theme/theme_helper.dart
@@ -147,6 +147,8 @@ class PrimaryColors {
Color get greenA70001 => const Color(0XFF00BE13);
+ Color get green => const Color(0XFF0BB450);
+
// LightGreen
Color get lightGreen300 => const Color(0XFFB2DF8A);
diff --git a/lib/core/widgets/bottom_sheet_with_blur.dart b/lib/core/widgets/bottom_sheet_with_blur.dart
index f7cdf3df..57dc9026 100644
--- a/lib/core/widgets/bottom_sheet_with_blur.dart
+++ b/lib/core/widgets/bottom_sheet_with_blur.dart
@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
Future showBottomSheetWithBlur({
required BuildContext context,
required Widget child,
- double height = 200,
+ double? height = 200,
bool hasBlur = true,
bool enableDrag = true,
bool userRootNavigator = false,
diff --git a/lib/core/widgets/custom_popup.dart b/lib/core/widgets/custom_popup.dart
index 967f6fee..711995f2 100644
--- a/lib/core/widgets/custom_popup.dart
+++ b/lib/core/widgets/custom_popup.dart
@@ -90,10 +90,16 @@ class CustomPopup extends StatelessWidget {
addItem('assets/icons/edit_paint.svg', 'Редактировать', () {
if (complainedContentType == ComplainedContent.posts) {
GoRouter.of(context).pushNamed('blogPostCreateScreen', extra: feedBlogPostModel);
+ } else {
+ showInfoToast('В разработке');
+ return;
}
});
if (complainedContentType == ComplainedContent.plan || complainedContentType == ComplainedContent.diet) {
- addItem('assets/icons/remove_from_public.svg', 'Снять с публикации', () {});
+ addItem('assets/icons/remove_from_public.svg', 'Снять с публикации', () {
+ showInfoToast('В разработке');
+ return;
+ });
}
addItem('assets/icons/red_trash.svg', 'Удалить', () async {
if (complainedContentType == ComplainedContent.posts) {
@@ -104,6 +110,9 @@ class CustomPopup extends StatelessWidget {
return;
}
context.read().loadFeedBlogPostList();
+ } else {
+ showInfoToast('В разработке');
+ return;
}
});
} else {
diff --git a/lib/core/widgets/custom_text_form_field.dart b/lib/core/widgets/custom_text_form_field.dart
index aedfda0f..041bee70 100644
--- a/lib/core/widgets/custom_text_form_field.dart
+++ b/lib/core/widgets/custom_text_form_field.dart
@@ -99,7 +99,7 @@ class CustomTextFormField extends StatelessWidget {
controller: controller,
focusNode: focusNode,
autofocus: autofocus,
- style: const TextStyle(fontSize: 16, color: Colors.black, fontWeight: FontWeight.w500),
+ style: textStyle ?? const TextStyle(fontSize: 16, color: Colors.black, fontWeight: FontWeight.w500),
obscureText: obscureText!,
textInputAction: textInputAction,
maxLines: maxLines,
@@ -115,20 +115,17 @@ class CustomTextFormField extends StatelessWidget {
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
floatingLabelBehavior: FloatingLabelBehavior.always,
- suffixStyle: textStyle ?? const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xFF323F4B)),
+ suffixStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: Color(0xFF323F4B)),
suffixIconConstraints: suffixConstraints,
isDense: false,
contentPadding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
fillColor: const Color(0xFFF6F6F6),
filled: true,
- border:
- borderDecoration ??
+ border: borderDecoration ??
OutlineInputBorder(borderRadius: BorderRadius.circular(20), borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none),
- enabledBorder:
- borderDecoration ??
+ enabledBorder: borderDecoration ??
OutlineInputBorder(borderRadius: BorderRadius.circular(20), borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none),
- focusedBorder:
- borderDecoration ??
+ focusedBorder: borderDecoration ??
OutlineInputBorder(borderRadius: BorderRadius.circular(20), borderSide: hasError ? BorderSide(color: appTheme.red, width: 1) : BorderSide.none),
),
keyboardType: keyboardType,
diff --git a/lib/core/widgets/success_published_diet_bottom_sheet.dart b/lib/core/widgets/success_published_diet_bottom_sheet.dart
index 0145d041..223ed220 100644
--- a/lib/core/widgets/success_published_diet_bottom_sheet.dart
+++ b/lib/core/widgets/success_published_diet_bottom_sheet.dart
@@ -7,9 +7,10 @@ import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
-class SuccessPublishedDietBottomSheet extends StatelessWidget {
- const SuccessPublishedDietBottomSheet({super.key, required this.title});
+class SuccessPublishedDietOrPlanBottomSheet extends StatelessWidget {
+ const SuccessPublishedDietOrPlanBottomSheet({super.key, required this.title, this.isPlan = false});
final String title;
+ final bool isPlan;
@override
Widget build(BuildContext context) {
final s = S.of(context);
@@ -27,7 +28,7 @@ class SuccessPublishedDietBottomSheet extends StatelessWidget {
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
),
Text(
- 'опубликованна',
+ isPlan ? 'опубликован' : 'опубликованна',
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
),
const SizedBox(
diff --git a/lib/features/chat/models/plan_complain_model.dart b/lib/features/chat/models/plan_complain_model.dart
new file mode 100644
index 00000000..63e2af8e
--- /dev/null
+++ b/lib/features/chat/models/plan_complain_model.dart
@@ -0,0 +1,14 @@
+import 'package:freezed_annotation/freezed_annotation.dart';
+
+part 'plan_complain_model.freezed.dart';
+part 'plan_complain_model.g.dart';
+
+@freezed
+class PlanComplainModel with _$PlanComplainModel {
+
+ factory PlanComplainModel({
+ @JsonKey(name: 'description') required String description,
+ }) = _PlanComplainModel;
+
+ factory PlanComplainModel.fromJson(Map json) => _$PlanComplainModelFromJson(json);
+}
\ No newline at end of file
diff --git a/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart b/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart
index bb8e6d9f..3c522edb 100644
--- a/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart
+++ b/lib/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart
@@ -10,6 +10,7 @@ import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart';
import 'package:eatvio_app/core/utils/date_time_utils.dart';
import 'package:eatvio_app/core/websockets/ws_manager.dart';
import 'package:eatvio_app/features/chat/models/chat_message_model.dart';
+import 'package:eatvio_app/features/chat/models/plan_complain_model.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_state.dart';
import 'package:eatvio_app/features/chat/repositories/chat_repository.dart';
import 'package:eatvio_app/features/my_finance/models/card_model.dart';
@@ -72,7 +73,7 @@ class ChatRoomCubit extends Cubit {
}
}
- initChat(String chatId) async {
+ initChat(String chatId, {bool sendInitialMessage = false}) async {
try {
final chatRoom = await chatRepository.getChatRoom(chatId);
ChosenPlanModel? chosenPlan;
@@ -96,6 +97,10 @@ class ChatRoomCubit extends Cubit {
if (chatRoom.chosenPlan?.consultantId == chatRoom.users.receiver.id) {
await checkCards();
}
+
+ if (sendInitialMessage) {
+ await chatRepository.sendMessage(chatId: chatId, data: 'Здравствуйте, хочу заказать у вас: ${chosenPlan?.plan.name ?? 'план'}');
+ }
} catch (e) {
log(e.toString());
typingSubscription?.cancel();
@@ -205,6 +210,30 @@ class ChatRoomCubit extends Cubit {
}
}
+ Future complainAboutConsultation({required String description}) async {
+ try {
+ final planId = (state as ChatRoomStateLoaded).chatRoom.chosenPlan?.id;
+ if (planId == null) return false;
+ await chatRepository.complainAboutConsultation(id: planId, body: PlanComplainModel(description: description));
+ return true;
+ } catch (e) {
+ log(e.toString());
+ return false;
+ }
+ }
+
+ Future finishChosenPlan() async {
+ try {
+ final planId = (state as ChatRoomStateLoaded).chatRoom.chosenPlan?.id;
+ if (planId == null) return false;
+ await chatRepository.finishChosenPlan(id: planId);
+ return true;
+ } catch (e) {
+ log(e.toString());
+ return false;
+ }
+ }
+
@override
Future close() async {
wsManager.unsubscribeDirectChatChannel();
diff --git a/lib/features/chat/presentation/pages/chat_screen.dart b/lib/features/chat/presentation/pages/chat_screen.dart
index 6cf7c9da..d90aaa93 100644
--- a/lib/features/chat/presentation/pages/chat_screen.dart
+++ b/lib/features/chat/presentation/pages/chat_screen.dart
@@ -15,6 +15,7 @@ import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/notification_banner.dart';
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
+import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart';
import 'package:eatvio_app/features/order_info/presentation/info_by_order_screen.dart';
import 'package:eatvio_app/features/plans/enums/chosen_plan_state_enum.dart';
import 'package:eatvio_app/features/user_details/presentation/user_details_screen.dart';
@@ -28,7 +29,8 @@ import 'package:visibility_detector/visibility_detector.dart';
class ChatScreen extends StatefulWidget {
final String chatId;
- const ChatScreen({required this.chatId, super.key});
+ final bool? sendInitialMessage;
+ const ChatScreen({required this.chatId, super.key, required this.sendInitialMessage});
@override
State createState() => _ChatScreenState();
@@ -46,7 +48,7 @@ class _ChatScreenState extends State {
void initState() {
super.initState();
scrollController.addListener(_onScroll);
- chatRoomCubit.initChat(widget.chatId);
+ chatRoomCubit.initChat(widget.chatId, sendInitialMessage: widget.sendInitialMessage ?? false);
}
_onScroll() {
@@ -96,13 +98,26 @@ class _ChatScreenState extends State {
BannerType? bannerType;
if (chosenPlan == null) {
bannerType = null;
- } else if (amIConsultant && state.hasCard) {
+ } else if (amIConsultant && !state.hasCard) {
bannerType = BannerType.card;
} else if (amIConsultant && chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateInCoordination) {
bannerType = BannerType.date;
} else if (!amIConsultant &&
(chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateStartDateHasBeenSet || chosenPlan.chosenPlanState == ChosenPlanStateEnum.statePendingPayment)) {
bannerType = BannerType.payment;
+ } else if (chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateDone) {
+ bannerType = BannerType.collectCharge;
+ } else if (!(chosenPlan.chosenPlanState == ChosenPlanStateEnum.stateLastDayFinished) && !amIConsultant) {
+ bannerType = BannerType.finishPlan;
+ }
+
+ PacketOptions? chosenOption;
+ if (chosenPlan?.optionType == 'options1') {
+ chosenOption = chosenPlan?.plan.packet1Options;
+ } else if (chosenPlan?.optionType == 'options2') {
+ chosenOption = chosenPlan?.plan.packet2Options;
+ } else if (chosenPlan?.optionType == 'options3') {
+ chosenOption = chosenPlan?.plan.packet3Options;
}
return Scaffold(
resizeToAvoidBottomInset: true,
@@ -263,7 +278,7 @@ class _ChatScreenState extends State {
itemCount: state.chatMessages.length + (state.isLoading ? 1 : 0),
),
const SizedBox(height: 16),
- if (showUserDetailsButton) ...[
+ if (!showUserDetailsButton) ...[
// OrderCard(
// plan: chosenPlan.plan,
// isCustomerView: !amIConsultant,
@@ -289,7 +304,15 @@ class _ChatScreenState extends State {
),
),
if (bannerType != null)
- Padding(padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), child: NotificationBanner(bannerType: bannerType)),
+ Padding(
+ padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
+ child: NotificationBanner(
+ bannerType: bannerType,
+ chosenPlanId: chosenPlan?.id,
+ planName: chosenPlan?.plan.name,
+ planPrice: chosenOption?.price.toDouble(),
+ ),
+ ),
],
],
),
diff --git a/lib/features/chat/presentation/widgets/complete_plan_bottom_sheet.dart b/lib/features/chat/presentation/widgets/complete_plan_bottom_sheet.dart
new file mode 100644
index 00000000..ef950bc9
--- /dev/null
+++ b/lib/features/chat/presentation/widgets/complete_plan_bottom_sheet.dart
@@ -0,0 +1,102 @@
+import 'package:eatvio_app/core/theme/custom_text_style.dart';
+import 'package:eatvio_app/core/theme/theme_helper.dart';
+import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart';
+import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
+import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
+import 'package:eatvio_app/generated/l10n.dart';
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+
+class CompletePlanBottomSheet extends StatefulWidget {
+ const CompletePlanBottomSheet({super.key, required this.cubit});
+ final ChatRoomCubit cubit;
+
+ @override
+ State createState() => _CompletePlanBottomSheetState();
+}
+
+class _CompletePlanBottomSheetState extends State {
+ bool? isFailure;
+ @override
+ Widget build(BuildContext context) {
+ final s = S.of(context);
+ if (isFailure == true) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const SizedBox(
+ height: 8,
+ ),
+ const BottomSheetHandlerBar(),
+ const SizedBox(
+ height: 20,
+ ),
+ Text('Произошла ошибка, попробуйте позже', style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
+ const SizedBox(
+ height: 8,
+ ),
+ CustomOutlinedButton(
+ text: s.ok,
+ height: 52,
+ buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
+ buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
+ onPressed: () async {
+ context.pop();
+ },
+ ),
+ const SizedBox(
+ height: 40,
+ ),
+ ],
+ );
+ }
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 12.0),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const SizedBox(
+ height: 8,
+ ),
+ const BottomSheetHandlerBar(),
+ const SizedBox(
+ height: 20,
+ ),
+ Text('Подтверждение плана', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
+ const SizedBox(
+ height: 16,
+ ),
+ Text(
+ 'Вы уверенны что хотите подтвердить прохождения плана?',
+ style: TextStyles.textSMedium.copyWith(color: appTheme.black),
+ textAlign: TextAlign.center,
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ CustomOutlinedButton(
+ text: s.confirm,
+ height: 52,
+ buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
+ buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
+ onPressed: () async {
+ final result = await widget.cubit.finishChosenPlan();
+ if (result) {
+ if (context.mounted) {
+ context.pop();
+ return;
+ }
+ }
+ setState(() {
+ isFailure = true;
+ });
+ },
+ ),
+ const SizedBox(
+ height: 40,
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/features/chat/presentation/widgets/notification_banner.dart b/lib/features/chat/presentation/widgets/notification_banner.dart
index 0059f7cc..8828863f 100644
--- a/lib/features/chat/presentation/widgets/notification_banner.dart
+++ b/lib/features/chat/presentation/widgets/notification_banner.dart
@@ -1,10 +1,14 @@
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
+import 'package:eatvio_app/core/widgets/bottom_sheet_with_blur.dart';
+import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/core/widgets/loader.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_state.dart';
import 'package:eatvio_app/features/chat/presentation/pages/payment_screen.dart';
import 'package:eatvio_app/features/chat/presentation/widgets/chose_plan_date_widget.dart';
+import 'package:eatvio_app/features/chat/presentation/widgets/complete_plan_bottom_sheet.dart';
+import 'package:eatvio_app/features/chat/presentation/widgets/plan_complain_bottom_sheet.dart';
import 'package:eatvio_app/features/my_finance/presentation/pages/card_settings.dart';
import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
@@ -13,8 +17,11 @@ import 'package:flutter_svg/svg.dart';
import 'package:go_router/go_router.dart';
class NotificationBanner extends StatefulWidget {
- const NotificationBanner({super.key, required this.bannerType});
+ const NotificationBanner({super.key, required this.bannerType, this.planPrice, this.planName, this.chosenPlanId});
final BannerType bannerType;
+ final double? planPrice;
+ final String? planName;
+ final int? chosenPlanId;
@override
State createState() => _NotificationBannerState();
@@ -31,96 +38,208 @@ class _NotificationBannerState extends State {
color: appTheme.gray50,
borderRadius: BorderRadius.circular(20),
),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
+ child: Column(
children: [
- Padding(
- padding: const EdgeInsets.only(top: 12, right: 8, left: 12),
- child: SvgPicture.asset('assets/icons/reversed_exclamation_mark.svg', height: 68, width: 68),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ if (widget.bannerType != BannerType.collectCharge && widget.bannerType != BannerType.finishPlan)
+ Padding(
+ padding: const EdgeInsets.only(top: 12, right: 8, left: 12),
+ child: SvgPicture.asset('assets/icons/reversed_exclamation_mark.svg', height: 68, width: 68),
+ )
+ else
+ const Padding(
+ padding: EdgeInsets.only(top: 12, right: 8, left: 12),
+ child: _StarIcon(),
+ ),
+ if (isLoading)
+ const Padding(
+ padding: EdgeInsets.only(left: 40, top: 24),
+ child: Loader(),
+ )
+ else
+ Padding(
+ padding: const EdgeInsets.only(top: 16),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: switch (widget.bannerType) {
+ BannerType.date => [
+ SizedBox(
+ width: size.width * 0.6,
+ child: Text(s.choose_plan_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
+ ),
+ const SizedBox(height: 12),
+ GestureDetector(
+ onTap: () {
+ final cubit = context.read();
+ showModalBottomSheet(
+ context: context,
+ builder: (context) => ChosePlanDateWidget(
+ chatCubit: cubit,
+ ),
+ );
+ },
+ child: Text(s.choose_date, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
+ ),
+ const SizedBox(height: 16),
+ ],
+ BannerType.card => [
+ SizedBox(
+ width: size.width * 0.6,
+ child: Text(s.can_not_choose_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
+ ),
+ const SizedBox(height: 12),
+ GestureDetector(
+ onTap: () {
+ GoRouter.of(context).pushReplacement(
+ CardSettingsScreen.path,
+ );
+ },
+ child: Text(s.add_card, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
+ ),
+ const SizedBox(height: 16),
+ ],
+ BannerType.payment => [
+ SizedBox(
+ width: size.width * 0.6,
+ child: Text(s.tap_on_link_to_pay, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
+ ),
+ const SizedBox(height: 12),
+ GestureDetector(
+ onTap: () async {
+ final planId = (context.read().state as ChatRoomStateLoaded).chatRoom.chosenPlan?.id;
+ setState(() {
+ isLoading = true;
+ });
+ final paymentLink = await context.read().getPaymentLink();
+ setState(() {
+ isLoading = false;
+ });
+ if (paymentLink != null && planId != null) {
+ if (!context.mounted) return;
+ GoRouter.of(context).pushReplacement(
+ PaymentScreen.path,
+ extra: {'url': paymentLink, 'planId': planId},
+ );
+ }
+ },
+ child: Text(s.pay, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
+ ),
+ const SizedBox(height: 16),
+ ],
+ BannerType.collectCharge => [
+ SizedBox(
+ width: size.width * 0.6,
+ child:
+ Text('${s.congratsYouHaveFinishedPlan} «${widget.planName}»', style: TextStyles.textMSemibold.copyWith(color: appTheme.black)),
+ ),
+ const SizedBox(height: 8),
+ SizedBox(
+ width: size.width * 0.6,
+ child: Text('${s.userConfirmedPlanCompletion} ${widget.planPrice}₽', style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
+ ),
+ const SizedBox(height: 8),
+ ],
+ BannerType.finishPlan => [
+ SizedBox(
+ width: size.width * 0.6,
+ child: Text('${s.congratsYouHaveFinishedPlan} «${widget.planName}». ${s.pleaseConfirmPlan}',
+ style: TextStyles.textMMediumAuto.copyWith(color: appTheme.black)),
+ ),
+ const SizedBox(height: 8),
+ SizedBox(
+ width: size.width * 0.7,
+ child: Text(s.planWillBeConfirmedAfterThreeDays, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
+ ),
+ const SizedBox(height: 8),
+ ],
+ },
+ ),
+ ),
+ ],
),
- if (isLoading)
- const Padding(
- padding: EdgeInsets.only(left: 40, top: 24),
- child: Loader(),
- )
- else
+ if (widget.bannerType == BannerType.collectCharge)
Padding(
- padding: const EdgeInsets.only(top: 16),
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: switch (widget.bannerType) {
- BannerType.date => [
- SizedBox(
- width: size.width * 0.6,
- child: Text(s.choose_plan_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
- ),
- const SizedBox(height: 12),
- GestureDetector(
- onTap: () {
- final cubit = context.read();
- showModalBottomSheet(
- context: context,
- builder: (context) => ChosePlanDateWidget(
- chatCubit: cubit,
- ),
- );
- },
- child: Text(s.choose_date, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
- ),
- const SizedBox(height: 16),
- ],
- BannerType.card => [
- SizedBox(
- width: size.width * 0.6,
- child: Text(s.can_not_choose_start_date, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
- ),
- const SizedBox(height: 12),
- GestureDetector(
- onTap: () {
- GoRouter.of(context).pushReplacement(
- CardSettingsScreen.path,
- );
- },
- child: Text(s.add_card, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
- ),
- const SizedBox(height: 16),
- ],
- BannerType.payment => [
- SizedBox(
- width: size.width * 0.6,
- child: Text(s.tap_on_link_to_pay, style: TextStyles.textMMedium.copyWith(color: appTheme.black)),
- ),
- const SizedBox(height: 12),
- GestureDetector(
- onTap: () async {
- final planId = (context.read().state as ChatRoomStateLoaded).chatRoom.chosenPlan?.id;
- setState(() {
- isLoading = true;
- });
- final paymentLink = await context.read().getPaymentLink();
- setState(() {
- isLoading = false;
- });
- if (paymentLink != null && planId != null) {
- if (!context.mounted) return;
- GoRouter.of(context).pushReplacement(
- PaymentScreen.path,
- extra: {'url': paymentLink, 'planId': planId},
- );
- }
- },
- child: Text(s.pay, style: TextStyles.textLSemibold.copyWith(color: appTheme.blueA400)),
- ),
- const SizedBox(height: 16),
- ],
+ padding: const EdgeInsets.symmetric(horizontal: 12),
+ child: CustomOutlinedButton(
+ text: s.collectCharge,
+ height: 52,
+ buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
+ buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.green)),
+ onPressed: () async {
+ GoRouter.of(context).push(CardSettingsScreen.path, extra: widget.chosenPlanId);
},
),
),
+ if (widget.bannerType == BannerType.finishPlan) ...[
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 12),
+ child: CustomOutlinedButton(
+ text: s.confirm,
+ height: 52,
+ buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
+ buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
+ onPressed: () async {
+ final cubit = context.read();
+ showBottomSheetWithBlur(
+ userRootNavigator: true,
+ context: context,
+ height: null,
+ child: CompletePlanBottomSheet(
+ cubit: cubit,
+ ),
+ );
+ },
+ ),
+ ),
+ const SizedBox(height: 12),
+ Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: SizedBox(
+ child: Text(s.youCanComplain, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
+ ),
+ ),
+ const SizedBox(height: 8),
+ Align(
+ alignment: Alignment.centerLeft,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: GestureDetector(
+ onTap: () {
+ final cubit = context.read();
+ showBottomSheetWithBlur(
+ userRootNavigator: true,
+ context: context,
+ height: null,
+ child: PlanComplainBottomSheet(
+ cubit: cubit,
+ ),
+ );
+ },
+ child: Text(s.leaveComplainRequest, style: TextStyles.textSMedium.copyWith(color: appTheme.red))),
+ ),
+ ),
+ const SizedBox(height: 8),
+ ]
],
),
);
}
}
-enum BannerType { date, card, payment }
+class _StarIcon extends StatelessWidget {
+ const _StarIcon();
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: const EdgeInsets.all(12),
+ decoration: BoxDecoration(color: appTheme.whiteA700, shape: BoxShape.circle),
+ child: SvgPicture.asset('assets/icons/star.svg'),
+ );
+ }
+}
+
+enum BannerType { date, card, payment, collectCharge, finishPlan }
diff --git a/lib/features/chat/presentation/widgets/plan_complain_bottom_sheet.dart b/lib/features/chat/presentation/widgets/plan_complain_bottom_sheet.dart
new file mode 100644
index 00000000..34f500f7
--- /dev/null
+++ b/lib/features/chat/presentation/widgets/plan_complain_bottom_sheet.dart
@@ -0,0 +1,154 @@
+import 'package:eatvio_app/core/theme/custom_text_style.dart';
+import 'package:eatvio_app/core/theme/theme_helper.dart';
+import 'package:eatvio_app/core/widgets/bottom_sheet_handler_bar.dart';
+import 'package:eatvio_app/core/widgets/custom_outlined_button.dart';
+import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
+import 'package:eatvio_app/features/chat/presentation/bloc/chat_room_cubit/chat_room_cubit.dart';
+import 'package:eatvio_app/features/create_diet/presentation/widgets/error_widget.dart';
+import 'package:eatvio_app/generated/l10n.dart';
+import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
+
+class PlanComplainBottomSheet extends StatefulWidget {
+ const PlanComplainBottomSheet({super.key, required this.cubit});
+ final ChatRoomCubit cubit;
+
+ @override
+ State createState() => _PlanComplainBottomSheetState();
+}
+
+class _PlanComplainBottomSheetState extends State {
+ final controller = TextEditingController();
+ bool? result;
+ int? textLength;
+ @override
+ Widget build(BuildContext context) {
+ final s = S.of(context);
+ if (result == true) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const SizedBox(
+ height: 8,
+ ),
+ const BottomSheetHandlerBar(),
+ const SizedBox(
+ height: 20,
+ ),
+ Text('Подача жалобы', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
+ const SizedBox(
+ height: 16,
+ ),
+ Text('Жалоба отправлена на рассмотрение. Обычно это занимает до трёх рабочих дней.', style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
+ const SizedBox(
+ height: 8,
+ ),
+ CustomOutlinedButton(
+ text: s.ok,
+ height: 52,
+ buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
+ buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
+ onPressed: () async {
+ context.pop();
+ },
+ ),
+ const SizedBox(
+ height: 40,
+ ),
+ ],
+ );
+ } else if (result == false) {
+ return Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const SizedBox(
+ height: 8,
+ ),
+ const BottomSheetHandlerBar(),
+ const SizedBox(
+ height: 20,
+ ),
+ Text('Подача жалобы', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
+ const SizedBox(
+ height: 16,
+ ),
+ Text('Произошла ошибка, попробуйте позже', style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
+ const SizedBox(
+ height: 8,
+ ),
+ CustomOutlinedButton(
+ text: s.ok,
+ height: 52,
+ buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
+ buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
+ onPressed: () async {
+ context.pop();
+ },
+ ),
+ const SizedBox(
+ height: 40,
+ ),
+ ],
+ );
+ }
+ return Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 16),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ const SizedBox(
+ height: 8,
+ ),
+ const BottomSheetHandlerBar(),
+ const SizedBox(
+ height: 20,
+ ),
+ Text('Подача жалобы', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black)),
+ const SizedBox(
+ height: 16,
+ ),
+ Align(alignment: Alignment.centerLeft, child: Text('Опишите причину жалобы', style: TextStyles.textSMedium.copyWith(color: appTheme.black))),
+ const SizedBox(
+ height: 8,
+ ),
+ CustomTextFormField(
+ controller: controller,
+ hasError: textLength != null && textLength! < 3,
+ onChanged: (p0) {
+ setState(() {
+ textLength = p0.length;
+ });
+ },
+ ),
+ if (textLength != null && textLength! < 3) ...[
+ const SizedBox(
+ height: 4,
+ ),
+ ValidationErrorWidget(error: s.atLeast3Symbols),
+ ],
+ const SizedBox(
+ height: 8,
+ ),
+ CustomOutlinedButton(
+ text: s.confirm,
+ height: 52,
+ buttonTextStyle: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700),
+ buttonStyle: ButtonStyle(side: const WidgetStatePropertyAll(BorderSide.none), backgroundColor: WidgetStatePropertyAll(appTheme.blueA400)),
+ onPressed: () async {
+ if (controller.text.length < 3) {
+ return;
+ }
+ final result = await widget.cubit.complainAboutConsultation(description: controller.text);
+ setState(() {
+ this.result = result;
+ });
+ },
+ ),
+ const SizedBox(
+ height: 40,
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/features/chat/repositories/chat_repository.dart b/lib/features/chat/repositories/chat_repository.dart
index 30c34586..28f80a48 100644
--- a/lib/features/chat/repositories/chat_repository.dart
+++ b/lib/features/chat/repositories/chat_repository.dart
@@ -6,6 +6,7 @@ import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart';
import 'package:eatvio_app/features/chat/models/payment_model.dart';
+import 'package:eatvio_app/features/chat/models/plan_complain_model.dart';
import 'package:eatvio_app/features/chat/services/chat_service.dart';
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
import 'package:http_parser/http_parser.dart';
@@ -132,4 +133,25 @@ class ChatRepository {
rethrow;
}
}
+
+ Future finishChosenPlan({
+ required int id,
+ }) async {
+ try {
+ await chatService.finishChosenPlan(id: id);
+ } catch (e) {
+ rethrow;
+ }
+ }
+
+ Future complainAboutConsultation({
+ required int id,
+ required PlanComplainModel body,
+ }) async {
+ try {
+ await chatService.complainAboutConsultation(id: id, body: body);
+ } catch (e) {
+ rethrow;
+ }
+ }
}
diff --git a/lib/features/chat/services/chat_service.dart b/lib/features/chat/services/chat_service.dart
index 2e2a127e..6d4c992e 100644
--- a/lib/features/chat/services/chat_service.dart
+++ b/lib/features/chat/services/chat_service.dart
@@ -3,6 +3,7 @@ import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_pagination_model.dart';
import 'package:eatvio_app/features/chat/models/payment_model.dart';
+import 'package:eatvio_app/features/chat/models/plan_complain_model.dart';
import 'package:eatvio_app/features/plans/models/chosen_plan_model.dart';
import 'package:retrofit/retrofit.dart';
@@ -68,4 +69,15 @@ abstract class ChatService {
Future getChosenPlan({
@Path() required int id,
});
+
+ @POST('/api/chosen_plans/{id}/confirm_finish')
+ Future finishChosenPlan({
+ @Path() required int id,
+ });
+
+ @POST('/api/chosen_plans/{id}/complain')
+ Future complainAboutConsultation({
+ @Path() required int id,
+ @Body() required PlanComplainModel body,
+ });
}
diff --git a/lib/features/consultations/models/consultation_model.dart b/lib/features/consultations/models/consultation_model.dart
index 5e96cb68..4c9464bf 100644
--- a/lib/features/consultations/models/consultation_model.dart
+++ b/lib/features/consultations/models/consultation_model.dart
@@ -37,8 +37,9 @@ class DiaryModel with _$DiaryModel {
}
DateTime parseUnformattedDate(String date) {
- final dateChunks = date.split('/').map(int.parse).toList();
- return DateTime(dateChunks.last, dateChunks.first, dateChunks[1]);
+ final dateChunks = date.split('-').map(int.parse).toList();
+
+ return DateTime(dateChunks.first, dateChunks[1], dateChunks.last);
}
enum DiaryStateEnum {
diff --git a/lib/features/consultations/services/consultation_service.dart b/lib/features/consultations/services/consultation_service.dart
index 25719f8a..24881685 100644
--- a/lib/features/consultations/services/consultation_service.dart
+++ b/lib/features/consultations/services/consultation_service.dart
@@ -8,7 +8,6 @@ part 'consultation_service.g.dart';
abstract class ConsultationService {
factory ConsultationService(Dio dio, {String baseUrl}) = _ConsultationService;
- @GET('/api/consultations')
+ @GET('/api/consultations/in_progress')
Future getConsultations();
-
}
diff --git a/lib/features/create_diet/presentation/create_diet_screen.dart b/lib/features/create_diet/presentation/create_diet_screen.dart
index a8d2e019..48d1d27e 100644
--- a/lib/features/create_diet/presentation/create_diet_screen.dart
+++ b/lib/features/create_diet/presentation/create_diet_screen.dart
@@ -72,7 +72,7 @@ class _CreateDietScreenContentState extends State {
showBottomSheetWithBlur(
userRootNavigator: true,
context: context,
- child: SuccessPublishedDietBottomSheet(
+ child: SuccessPublishedDietOrPlanBottomSheet(
title: state.dietData.name ?? 'Диета',
),
);
@@ -83,7 +83,7 @@ class _CreateDietScreenContentState extends State {
context.pop();
showBottomSheetWithBlur(
context: context,
- child: SuccessPublishedDietBottomSheet(
+ child: SuccessPublishedDietOrPlanBottomSheet(
title: '${state.dietData.name ?? 'Диета'} сохраненна в черновиках',
),
);
@@ -193,8 +193,8 @@ class _CreateDietScreenContentState extends State {
context.read().setDietState(DietState.draft);
if (widget.diet != null) {
final result = await context.read().updateDiet(
- widget.diet!.id,
- );
+ widget.diet!.id,
+ );
if (result == 'error') {
if (!context.mounted) return;
showErrorDialog(context, title: '${s.could_not_update_diet} ${state.dietData.name}');
diff --git a/lib/features/create_plan/models/create_plan_model.dart b/lib/features/create_plan/models/create_plan_model.dart
index 75187284..4b85ffba 100644
--- a/lib/features/create_plan/models/create_plan_model.dart
+++ b/lib/features/create_plan/models/create_plan_model.dart
@@ -15,8 +15,8 @@ class CreatePlanModel with _$CreatePlanModel {
const factory CreatePlanModel({
String? name,
String? details,
- String? state,
- int? duration,
+ @Default('active') String? state,
+ int? duration,
required List type,
XFile? image,
required List options,
@@ -25,9 +25,12 @@ class CreatePlanModel with _$CreatePlanModel {
Future