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/.gitea/workflows/test-flight-cd.yaml b/.gitea/workflows/test-flight-cd.yaml
index 2a4f5aec..70fbcd94 100644
--- a/.gitea/workflows/test-flight-cd.yaml
+++ b/.gitea/workflows/test-flight-cd.yaml
@@ -8,48 +8,7 @@ jobs:
build:
runs-on: [macos-arm64]
steps:
- - name: Checkout
- uses: actions/checkout@v2
-
- - name: Download provisioning
- uses: mso7nueh/apple-provisioning-profiles-downloader@v1.0.8
- with:
- profile-type: IOS_APP_STORE
- bundle-id: com.eatvioapp.app
- issuer-id: ${{ vars.APPSTORE_ISSUER_ID }}
- api-key-id: ${{ vars.APPSTORE_KEY_ID }}
- api-private-key: ${{ vars.APPSTORE_PRIVATE_KEY }}
-
- - name: Unlock keychain
+ - name: Run Fastlane
run: |
- security unlock-keychain -p "EeChahboo9Ei" login.keychain
- security set-key-partition-list -S apple-tool:,apple: -s -k "EeChahboo9Ei" login.keychain
-
- - name: Ensure private key access
- run: |
- security set-key-partition-list -S apple-tool:,apple: -s -k "EeChahboo9Ei" ~/Library/Keychains/login.keychain-db
-
- - name: List identities in keychain
- run: |
- security list-keychains
- security find-identity -v -p codesigning login.keychain
-
- - name: Set keychain default
- run: |
- security default-keychain -s login.keychain
-
- - name: Build with Flutter
- run: |
- flutter clean
- flutter pub get
- flutter pub upgrade
- flutter pub run build_runner build --delete-conflicting-outputs
- flutter build ipa --export-options-plist=Support/ExportOptions.plist --release
-
- - name: Upload to TestFlight
- uses: mso7nueh/upload-testflight-build@master
- with:
- app-path: ./build/ios/ipa/eatvio_app.ipa
- issuer-id: ${{ vars.APPSTORE_ISSUER_ID }}
- api-key-id: ${{ vars.APPSTORE_KEY_ID }}
- api-private-key: ${{ vars.APPSTORE_PRIVATE_KEY }}
+ cd ios
+ fastlane beta
\ No newline at end of file
diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml
index a98a1561..8c247e87 100644
--- a/.gitea/workflows/test.yml
+++ b/.gitea/workflows/test.yml
@@ -41,6 +41,8 @@ jobs:
wget https://dl.google.com/android/repository/commandlinetools-linux-7583922_latest.zip -O commandlinetools.zip
unzip commandlinetools.zip
mkdir -p ${{ env.my_local_cache_dir }}Android/Sdk/cmdline-tools/latest
+ rm -rf ${{ env.my_local_cache_dir }}Android/Sdk/cmdline-tools/latest
+ mkdir -p ${{ env.my_local_cache_dir }}Android/Sdk/cmdline-tools/latest
mv cmdline-tools/* ${{ env.my_local_cache_dir }}Android/Sdk/cmdline-tools/latest/
export ANDROID_SDK_ROOT=${{ env.my_local_cache_dir }}Android/Sdk
export PATH=$PATH:${{ env.my_local_cache_dir }}Android/Sdk/cmdline-tools/latest/bin
diff --git a/assets/icons/edit_paint.svg b/assets/icons/edit_paint.svg
new file mode 100644
index 00000000..e4a9eeef
--- /dev/null
+++ b/assets/icons/edit_paint.svg
@@ -0,0 +1,11 @@
+
diff --git a/assets/icons/red_trash.svg b/assets/icons/red_trash.svg
new file mode 100644
index 00000000..3864fb63
--- /dev/null
+++ b/assets/icons/red_trash.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/icons/remove_from_public.svg b/assets/icons/remove_from_public.svg
new file mode 100644
index 00000000..36213c53
--- /dev/null
+++ b/assets/icons/remove_from_public.svg
@@ -0,0 +1,5 @@
+
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/assets/images/logo_welcome.svg b/assets/images/logo_welcome.svg
new file mode 100644
index 00000000..37102693
--- /dev/null
+++ b/assets/images/logo_welcome.svg
@@ -0,0 +1,9 @@
+
diff --git a/assets/splash/bg.json b/assets/splash/bg.json
new file mode 100644
index 00000000..4e4acd76
--- /dev/null
+++ b/assets/splash/bg.json
@@ -0,0 +1 @@
+{"nm":"background","ddd":0,"h":1920,"w":1080,"meta":{"g":"@lottiefiles/toolkit-js 0.33.2"},"layers":[{"ty":4,"nm":"Shape Layer 1","sr":1,"st":0,"op":155,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0]},"s":{"a":0,"k":[100,100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[540,960,0]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Rectangle 1","ix":1,"cix":2,"np":3,"it":[{"ty":"rc","bm":0,"hd":false,"mn":"ADBE Vector Shape - Rect","nm":"Rectangle Path 1","d":1,"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[1160,880]}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100},"w":{"a":0,"k":6},"c":{"a":0,"k":[1,1,1]}},{"ty":"gf","bm":0,"hd":false,"mn":"ADBE Vector Graphic - G-Fill","nm":"Gradient Fill 1","e":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[374.412,342.611],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[22.822,357.191],"t":31},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[-420.714,389.994],"t":61},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[50.932,404.573],"t":91},{"s":[376.797,364.48],"t":120}]},"g":{"p":3,"k":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0.00784313725490196,0.4392156862745098,1,0.5,0.10196078431372549,0.4666666666666667,0.9411764705882353,1,0.9490196078431372,0.9490196078431372,0.9490196078431372],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0.3411764705882353,0.6039215686274509,0.9411764705882353,0.5,0.0392156862745098,0.4549019607843137,1,1,0.1568627450980392,0.42745098039215684,0.8823529411764706],"t":31},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0.3176470588235294,0.5568627450980392,0.8666666666666667,0.5,0.6392156862745098,0.796078431372549,1,1,1,1,1],"t":61},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[0,0.1843137254901961,0.5019607843137255,0.9294117647058824,0.5,0.0784313725490196,0.596078431372549,0.7529411764705882,1,0,0.43529411764705883,1],"t":91},{"s":[0,0.00784313725490196,0.4392156862745098,1,0.5,0.5686274509803921,0.7411764705882353,0.9686274509803922,1,0.29411764705882354,0.5529411764705883,0.8862745098039215],"t":120}]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"s":{"a":1,"k":[{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[-430.769,-404.573],"t":0},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[23.726,-364.48],"t":31},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[312.726,-353.48],"t":61},{"o":{"x":0.167,"y":0.167},"i":{"x":0.833,"y":0.833},"s":[29.739,-353.48],"t":91},{"s":[-407.606,-357.125],"t":120}]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[93.29,219.491],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[0,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1},{"ty":1,"nm":"Deep Red Solid 1","sr":1,"st":0,"op":155,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[540,960,0]},"s":{"a":0,"k":[100,100,100]},"sk":{"a":0,"k":0},"p":{"a":0,"k":[540,960,0]},"r":{"a":0,"k":0},"sa":{"a":0,"k":0},"o":{"a":0,"k":100}},"ef":[],"sc":"#5095ef","sh":1920,"sw":1080,"ind":2}],"v":"4.6.10","fr":15,"op":155,"ip":0,"assets":[]}
\ No newline at end of file
diff --git a/assets/splash/bg.lottie b/assets/splash/bg.lottie
new file mode 100644
index 00000000..b6974b15
Binary files /dev/null and b/assets/splash/bg.lottie differ
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 58ccde6e..63ec1094 100644
--- a/lib/core/app_router.dart
+++ b/lib/core/app_router.dart
@@ -1,3 +1,5 @@
+import 'package:dio/dio.dart';
+import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/websockets/ws_manager.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/features/auth/presentation/pages/auth_screen.dart';
@@ -52,16 +54,21 @@ import 'package:eatvio_app/features/settings/presentation/pages/physical_form_sc
import 'package:eatvio_app/features/settings/presentation/pages/pressure_screen.dart';
import 'package:eatvio_app/features/settings/presentation/pages/settings_screen.dart';
import 'package:eatvio_app/features/support/presentation/pages/support_screen.dart';
+import 'package:eatvio_app/features/update_screen/presentation/update_screen.dart';
import 'package:eatvio_app/features/user_details/presentation/user_details_screen.dart';
+import 'package:eatvio_app/features/welcome/presentation/pages/welcome_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+import 'package:version/version.dart';
class AppRouter {
static GlobalKey navigatorKey = GlobalKey();
static GoRouter appRouter = GoRouter(
- initialLocation: '/my-profile-screen',
+ initialLocation: '/update-screen',
navigatorKey: navigatorKey,
routes: [
GoRoute(
@@ -123,6 +130,37 @@ class AppRouter {
),
],
),
+ GoRoute(
+ path: '/welcome-screen',
+ name: 'welcomeScreen',
+ builder: (context, state) => const WelcomeScreen(),
+ redirect: (context, state) async {
+ final sharedPreferences = await SharedPreferences.getInstance();
+ final welcomeScreenWasShowed = sharedPreferences.getBool('welcomeScreenWasShowed');
+ if (welcomeScreenWasShowed == true) {
+ return '/my-profile-screen';
+ } else {
+ return null;
+ }
+ },
+ ),
+ GoRoute(
+ path: '/update-screen',
+ name: 'updateScreen',
+ builder: (context, state) => const UpdateScreen(),
+ redirect: (context, state) async {
+ final versions = (await sl().get('$baseUrl/api/app_versions')).data;
+ PackageInfo packageInfo = await PackageInfo.fromPlatform();
+ String version = packageInfo.version;
+ Version currentVersion = Version.parse(version);
+ Version latestVersion = Version.parse(versions['min_version']);
+ if (latestVersion > currentVersion) {
+ return null;
+ } else {
+ return '/welcome-screen';
+ }
+ },
+ ),
GoRoute(
path: '/consultant-finance-screen',
name: 'consultantFinanceScreen',
@@ -136,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',
@@ -182,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 4f38a54e..31c47e9c 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
new file mode 100644
index 00000000..a4167f11
--- /dev/null
+++ b/lib/core/widgets/custom_popup.dart
@@ -0,0 +1,230 @@
+import 'package:eatvio_app/core/const.dart';
+import 'package:eatvio_app/core/enums/complained_content.dart';
+import 'package:eatvio_app/core/locator_service.dart';
+import 'package:eatvio_app/core/theme/theme_helper.dart';
+import 'package:eatvio_app/core/utils/toasts.dart';
+import 'package:eatvio_app/core/widgets/show_error_dialog.dart';
+import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart';
+import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart';
+import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
+import 'package:eatvio_app/features/feed/presentation/bloc/diets_cubit/diets_cubit.dart';
+import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
+import 'package:eatvio_app/features/feed/presentation/bloc/recipes_cubit/recipes_cubit.dart';
+import 'package:eatvio_app/features/my_diets/presentation/cubit/my_diets_cubit.dart';
+import 'package:eatvio_app/features/my_plans/presentation/cubit/my_plans_cubit.dart';
+import 'package:eatvio_app/generated/l10n.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:go_router/go_router.dart';
+import 'package:share_plus/share_plus.dart';
+
+class CustomPopup extends StatelessWidget {
+ final bool isAuthor;
+ final ComplainedContent? complainedContentType;
+ final String path;
+ final String? slug;
+ final int? id;
+ final FeedBlogPostModel? feedBlogPostModel;
+
+ const CustomPopup({
+ super.key,
+ required this.isAuthor,
+ this.complainedContentType,
+ required this.path,
+ this.id,
+ this.slug,
+ this.feedBlogPostModel,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ final s = S.of(context);
+
+ return GestureDetector(
+ onTap: () async {
+ final RenderBox button = context.findRenderObject() as RenderBox;
+ final RenderBox overlay = Overlay.of(context).context.findRenderObject() as RenderBox;
+ final Offset position = button.localToGlobal(Offset.zero, ancestor: overlay);
+
+ await showMenu(
+ context: context,
+ position: RelativeRect.fromLTRB(
+ position.dx,
+ position.dy + button.size.height,
+ position.dx + button.size.width,
+ position.dy,
+ ),
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
+ color: Colors.white,
+ constraints: const BoxConstraints(minWidth: 260),
+ surfaceTintColor: Colors.transparent,
+ elevation: 2,
+ items: _buildMenuItems(s, context),
+ );
+ },
+ child: const Icon(
+ Icons.more_horiz_rounded,
+ ),
+ );
+ }
+
+ List _buildMenuItems(s, context) {
+ final entries = [];
+
+ void addItem(String icon, String text, Function() onTap) {
+ entries.add(_buildCompactItem(icon: icon, text: text, onTap: onTap));
+ entries.add(_buildDivider());
+ }
+
+ if (isAuthor) {
+ addItem('assets/icons/copy2.svg', 'Скопировать ссылку', () {
+ Clipboard.setData(ClipboardData(text: '$baseUrl/ru/$path'));
+ showInfoToast(s.link_was_copied);
+ });
+ addItem('assets/icons/share2.svg', 'Поделиться', () {
+ final box = context.findRenderObject() as RenderBox?;
+ Share.shareUri(
+ Uri.parse(
+ '$baseUrl/ru/$path',
+ ),
+ sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
+ );
+ });
+ 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', 'Снять с публикации', () async {
+ if (complainedContentType == ComplainedContent.diet) {
+ final result = await sl().unpublishDiet(id!);
+ if (!context.mounted) return;
+ context.read().loadFeedBlogPostList();
+ if (!result) {
+ showErrorDialog(context, title: S.current.could_not_delete_blog_post);
+ return;
+ }
+ showSuccessToast('Диета перенесена в архив, обновите ленту');
+ } else if (complainedContentType == ComplainedContent.plan) {
+ final result = await sl().unpublish(slug!);
+ if (!context.mounted) return;
+ context.read().loadFeedBlogPostList();
+ if (!result) {
+ showErrorDialog(context, title: S.current.could_not_delete_blog_post);
+ return;
+ }
+ showSuccessToast('План перенесен в архив, обновите ленту');
+ }
+ });
+ }
+ addItem('assets/icons/red_trash.svg', 'Удалить', () async {
+ if (complainedContentType == ComplainedContent.posts) {
+ final result = await sl().deleteBlogPost(id!);
+ if (!context.mounted) return;
+ context.read().loadFeedBlogPostList();
+ if (!result) {
+ showErrorDialog(context, title: S.current.could_not_delete_blog_post);
+ return;
+ }
+ showSuccessToast('Пост удален, обновите ленту');
+ } else if (complainedContentType == ComplainedContent.recipe) {
+ final result = await sl().deleteRecipe(slug!);
+ if (!context.mounted) return;
+ context.read().loadFeedBlogPostList();
+ if (!result) {
+ showErrorDialog(context, title: S.current.could_not_delete_blog_post);
+ return;
+ }
+ showSuccessToast('Рецепт удален, обновите ленту');
+ } else if (complainedContentType == ComplainedContent.diet) {
+ final result = await sl().deleteDiet(id!);
+ if (!context.mounted) return;
+ context.read().loadFeedBlogPostList();
+ if (!result) {
+ showErrorDialog(context, title: S.current.could_not_delete_blog_post);
+ return;
+ }
+ showSuccessToast('Диета удалена, обновите ленту');
+ } else if (complainedContentType == ComplainedContent.plan) {
+ final result = await sl().deletePlan(slug!);
+ if (!context.mounted) return;
+ context.read().loadFeedBlogPostList();
+ if (!result) {
+ showErrorDialog(context, title: S.current.could_not_delete_blog_post);
+ return;
+ }
+ showSuccessToast('План удален, обновите ленту');
+ }
+ });
+ } else {
+ addItem('assets/icons/copy2.svg', 'Скопировать ссылку', () {
+ Clipboard.setData(ClipboardData(text: '$baseUrl/ru/$path'));
+ showInfoToast(s.link_was_copied);
+ });
+ addItem('assets/icons/share2.svg', 'Поделиться', () {
+ final box = context.findRenderObject() as RenderBox?;
+ Share.shareUri(
+ Uri.parse(
+ '$baseUrl/ru/$path',
+ ),
+ sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
+ );
+ });
+ addItem('assets/icons/complain.svg', 'Пожаловаться', () {
+ if (complainedContentType != null) {
+ showModalBottomSheet(
+ context: context,
+ isScrollControlled: true,
+ builder: (context) => ComplainingBottomSheet(
+ complainedContentType: complainedContentType!,
+ id: id,
+ slug: slug,
+ ),
+ );
+ }
+ });
+ }
+
+ if (entries.isNotEmpty && entries.last is PopupMenuItem) {
+ entries.removeLast();
+ }
+
+ return entries;
+ }
+
+ PopupMenuItem _buildCompactItem({required String icon, required String text, required Function() onTap}) {
+ return PopupMenuItem(
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
+ height: 36,
+ onTap: onTap,
+ child: SizedBox(
+ width: double.infinity,
+ child: Row(
+ children: [
+ Text(text, style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
+ const Spacer(),
+ SvgPicture.asset(icon),
+ ],
+ ),
+ ),
+ );
+ }
+
+ PopupMenuItem _buildDivider() {
+ return PopupMenuItem(
+ enabled: false,
+ height: 1,
+ padding: EdgeInsets.zero,
+ child: Container(
+ margin: const EdgeInsets.symmetric(horizontal: 12),
+ height: 1,
+ color: appTheme.dividerColor,
+ ),
+ );
+ }
+}
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/blog_post/presentation/pages/blog_post_screen.dart b/lib/features/blog_post/presentation/pages/blog_post_screen.dart
index 4f6a0ad0..e963a812 100644
--- a/lib/features/blog_post/presentation/pages/blog_post_screen.dart
+++ b/lib/features/blog_post/presentation/pages/blog_post_screen.dart
@@ -3,10 +3,8 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/core/const.dart';
import 'package:eatvio_app/core/enums/complained_content.dart';
import 'package:eatvio_app/core/utils/date_time_utils.dart';
-import 'package:eatvio_app/core/widgets/show_error_dialog.dart';
-import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart';
+import 'package:eatvio_app/core/widgets/custom_popup.dart';
import 'package:eatvio_app/core/widgets/loader.dart';
-import 'package:eatvio_app/features/blog_post_create/bloc/blog_post_create_cubit/blog_post_create_cubit.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/comments_cubit/comments_state.dart';
@@ -14,7 +12,6 @@ import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit
import 'package:eatvio_app/features/feed/presentation/widgets/comments_widget.dart';
import 'package:eatvio_app/core/locator_service.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
-import 'package:eatvio_app/generated/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_html/flutter_html.dart';
@@ -104,8 +101,10 @@ class _BlogPostScreenState extends State {
height: 1.2,
),
decoration: InputDecoration(
- isDense: false, // убираем true, чтобы padding учитывался корректно
- contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), // вертикальный паддинг увеличен
+ isDense: false,
+ // убираем true, чтобы padding учитывался корректно
+ contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
+ // вертикальный паддинг увеличен
hintText: 'Комментарий',
hintStyle: const TextStyle(
fontSize: 16,
@@ -161,39 +160,14 @@ class _BlogPostScreenState extends State {
appBar: AppBar(
title: Text(widget.blogPost.title),
actions: [
- PopupMenuButton(
- onSelected: (value) async {
- if (value == 'delete') {
- final result = await sl().deleteBlogPost(widget.blogPost.id);
- if (!context.mounted) return;
- if (!result) {
- showErrorDialog(context, title: S.current.could_not_delete_blog_post);
- return;
- }
- context.read().loadFeedBlogPostList();
- Navigator.of(context).pop();
- }
- if (value == 'edit') {
- GoRouter.of(context).replaceNamed('blogPostCreateScreen', extra: widget.blogPost);
- }
- },
- itemBuilder: (context) => [
- if (widget.blogPost.author.authorIsMe) const PopupMenuItem(value: 'edit', child: Text('Редактировать')),
- if (widget.blogPost.author.authorIsMe) const PopupMenuItem(value: 'delete', child: Text('Удалить')),
- if (!widget.blogPost.author.authorIsMe)
- PopupMenuItem(
- value: 'report',
- child: const Text('Пожаловаться'),
- onTap: () {
- showModalBottomSheet(
- context: context,
- isScrollControlled: true,
- builder: (context) => ComplainingBottomSheet(complainedContentType: ComplainedContent.posts, id: widget.blogPost.id),
- );
- },
- ),
- ],
+ CustomPopup(
+ isAuthor: widget.blogPost.author.authorIsMe,
+ complainedContentType: ComplainedContent.posts,
+ path: 'blog_post/${(widget.blogPost.id)}',
+ id: widget.blogPost.id,
+ feedBlogPostModel: widget.blogPost,
),
+ const SizedBox(width: 16),
],
),
body: SingleChildScrollView(
@@ -209,7 +183,13 @@ class _BlogPostScreenState extends State {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
- CircleAvatar(radius: 16, backgroundImage: NetworkImage(widget.blogPost.author.authorProfileIcon)),
+ CircleAvatar(
+ radius: 16,
+ foregroundImage: NetworkImage(
+ widget.blogPost.author.authorProfileIcon,
+ ),
+ backgroundImage: const AssetImage('assets/images/no_avatar.png'),
+ ),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
diff --git a/lib/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart b/lib/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart
index 5fdf10c0..c0b5e16a 100644
--- a/lib/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart
+++ b/lib/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart
@@ -81,7 +81,8 @@ class _BottomNavigationBarWidgetState extends State {
BottomNavigationBarItem(
label: '',
icon: CircleAvatar(
- backgroundImage: NetworkImage(widget.profileModel.profilePhotoUrl),
+ foregroundImage: NetworkImage(widget.profileModel.profilePhotoUrl),
+ backgroundImage: const AssetImage('assets/images/no_avatar.png'),
radius: 16,
),
),
diff --git a/lib/features/cancel_plan_bottom_sheet/cubit/cancel_plan_state.freezed.dart b/lib/features/cancel_plan_bottom_sheet/cubit/cancel_plan_state.freezed.dart
deleted file mode 100644
index 90f3350c..00000000
--- a/lib/features/cancel_plan_bottom_sheet/cubit/cancel_plan_state.freezed.dart
+++ /dev/null
@@ -1,82 +0,0 @@
-// coverage:ignore-file
-// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
-
-part of 'cancel_plan_state.dart';
-
-// **************************************************************************
-// FreezedGenerator
-// **************************************************************************
-
-T _$identity(T value) => value;
-
-final _privateConstructorUsedError = UnsupportedError(
- 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
-
-/// @nodoc
-mixin _$CancelPlanState {}
-
-/// @nodoc
-abstract class $CancelPlanStateCopyWith<$Res> {
- factory $CancelPlanStateCopyWith(
- CancelPlanState value, $Res Function(CancelPlanState) then) =
- _$CancelPlanStateCopyWithImpl<$Res, CancelPlanState>;
-}
-
-/// @nodoc
-class _$CancelPlanStateCopyWithImpl<$Res, $Val extends CancelPlanState>
- implements $CancelPlanStateCopyWith<$Res> {
- _$CancelPlanStateCopyWithImpl(this._value, this._then);
-
- // ignore: unused_field
- final $Val _value;
- // ignore: unused_field
- final $Res Function($Val) _then;
-
- /// Create a copy of CancelPlanState
- /// with the given fields replaced by the non-null parameter values.
-}
-
-/// @nodoc
-abstract class _$$CancelPlanStateImplCopyWith<$Res> {
- factory _$$CancelPlanStateImplCopyWith(_$CancelPlanStateImpl value,
- $Res Function(_$CancelPlanStateImpl) then) =
- __$$CancelPlanStateImplCopyWithImpl<$Res>;
-}
-
-/// @nodoc
-class __$$CancelPlanStateImplCopyWithImpl<$Res>
- extends _$CancelPlanStateCopyWithImpl<$Res, _$CancelPlanStateImpl>
- implements _$$CancelPlanStateImplCopyWith<$Res> {
- __$$CancelPlanStateImplCopyWithImpl(
- _$CancelPlanStateImpl _value, $Res Function(_$CancelPlanStateImpl) _then)
- : super(_value, _then);
-
- /// Create a copy of CancelPlanState
- /// with the given fields replaced by the non-null parameter values.
-}
-
-/// @nodoc
-
-class _$CancelPlanStateImpl implements _CancelPlanState {
- _$CancelPlanStateImpl();
-
- @override
- String toString() {
- return 'CancelPlanState()';
- }
-
- @override
- bool operator ==(Object other) {
- return identical(this, other) ||
- (other.runtimeType == runtimeType && other is _$CancelPlanStateImpl);
- }
-
- @override
- int get hashCode => runtimeType.hashCode;
-}
-
-abstract class _CancelPlanState implements CancelPlanState {
- factory _CancelPlanState() = _$CancelPlanStateImpl;
-}
diff --git a/lib/features/cancel_plan_bottom_sheet/models/cancelation_model.freezed.dart b/lib/features/cancel_plan_bottom_sheet/models/cancelation_model.freezed.dart
deleted file mode 100644
index d68a42ba..00000000
--- a/lib/features/cancel_plan_bottom_sheet/models/cancelation_model.freezed.dart
+++ /dev/null
@@ -1,184 +0,0 @@
-// coverage:ignore-file
-// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
-
-part of 'cancelation_model.dart';
-
-// **************************************************************************
-// FreezedGenerator
-// **************************************************************************
-
-T _$identity(T value) => value;
-
-final _privateConstructorUsedError = UnsupportedError(
- 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
-
-CancelationModel _$CancelationModelFromJson(Map json) {
- return _CancelationModel.fromJson(json);
-}
-
-/// @nodoc
-mixin _$CancelationModel {
- String get description => throw _privateConstructorUsedError;
- int get price => throw _privateConstructorUsedError;
-
- /// Serializes this CancelationModel to a JSON map.
- Map toJson() => throw _privateConstructorUsedError;
-
- /// Create a copy of CancelationModel
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- $CancelationModelCopyWith get copyWith =>
- throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-abstract class $CancelationModelCopyWith<$Res> {
- factory $CancelationModelCopyWith(
- CancelationModel value, $Res Function(CancelationModel) then) =
- _$CancelationModelCopyWithImpl<$Res, CancelationModel>;
- @useResult
- $Res call({String description, int price});
-}
-
-/// @nodoc
-class _$CancelationModelCopyWithImpl<$Res, $Val extends CancelationModel>
- implements $CancelationModelCopyWith<$Res> {
- _$CancelationModelCopyWithImpl(this._value, this._then);
-
- // ignore: unused_field
- final $Val _value;
- // ignore: unused_field
- final $Res Function($Val) _then;
-
- /// Create a copy of CancelationModel
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? description = null,
- Object? price = null,
- }) {
- return _then(_value.copyWith(
- description: null == description
- ? _value.description
- : description // ignore: cast_nullable_to_non_nullable
- as String,
- price: null == price
- ? _value.price
- : price // ignore: cast_nullable_to_non_nullable
- as int,
- ) as $Val);
- }
-}
-
-/// @nodoc
-abstract class _$$CancelationModelImplCopyWith<$Res>
- implements $CancelationModelCopyWith<$Res> {
- factory _$$CancelationModelImplCopyWith(_$CancelationModelImpl value,
- $Res Function(_$CancelationModelImpl) then) =
- __$$CancelationModelImplCopyWithImpl<$Res>;
- @override
- @useResult
- $Res call({String description, int price});
-}
-
-/// @nodoc
-class __$$CancelationModelImplCopyWithImpl<$Res>
- extends _$CancelationModelCopyWithImpl<$Res, _$CancelationModelImpl>
- implements _$$CancelationModelImplCopyWith<$Res> {
- __$$CancelationModelImplCopyWithImpl(_$CancelationModelImpl _value,
- $Res Function(_$CancelationModelImpl) _then)
- : super(_value, _then);
-
- /// Create a copy of CancelationModel
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? description = null,
- Object? price = null,
- }) {
- return _then(_$CancelationModelImpl(
- description: null == description
- ? _value.description
- : description // ignore: cast_nullable_to_non_nullable
- as String,
- price: null == price
- ? _value.price
- : price // ignore: cast_nullable_to_non_nullable
- as int,
- ));
- }
-}
-
-/// @nodoc
-@JsonSerializable()
-class _$CancelationModelImpl implements _CancelationModel {
- _$CancelationModelImpl({required this.description, required this.price});
-
- factory _$CancelationModelImpl.fromJson(Map json) =>
- _$$CancelationModelImplFromJson(json);
-
- @override
- final String description;
- @override
- final int price;
-
- @override
- String toString() {
- return 'CancelationModel(description: $description, price: $price)';
- }
-
- @override
- bool operator ==(Object other) {
- return identical(this, other) ||
- (other.runtimeType == runtimeType &&
- other is _$CancelationModelImpl &&
- (identical(other.description, description) ||
- other.description == description) &&
- (identical(other.price, price) || other.price == price));
- }
-
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- int get hashCode => Object.hash(runtimeType, description, price);
-
- /// Create a copy of CancelationModel
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- @pragma('vm:prefer-inline')
- _$$CancelationModelImplCopyWith<_$CancelationModelImpl> get copyWith =>
- __$$CancelationModelImplCopyWithImpl<_$CancelationModelImpl>(
- this, _$identity);
-
- @override
- Map toJson() {
- return _$$CancelationModelImplToJson(
- this,
- );
- }
-}
-
-abstract class _CancelationModel implements CancelationModel {
- factory _CancelationModel(
- {required final String description,
- required final int price}) = _$CancelationModelImpl;
-
- factory _CancelationModel.fromJson(Map json) =
- _$CancelationModelImpl.fromJson;
-
- @override
- String get description;
- @override
- int get price;
-
- /// Create a copy of CancelationModel
- /// with the given fields replaced by the non-null parameter values.
- @override
- @JsonKey(includeFromJson: false, includeToJson: false)
- _$$CancelationModelImplCopyWith<_$CancelationModelImpl> get copyWith =>
- throw _privateConstructorUsedError;
-}
diff --git a/lib/features/cancel_plan_bottom_sheet/models/cancelation_model.g.dart b/lib/features/cancel_plan_bottom_sheet/models/cancelation_model.g.dart
deleted file mode 100644
index d7bd21e9..00000000
--- a/lib/features/cancel_plan_bottom_sheet/models/cancelation_model.g.dart
+++ /dev/null
@@ -1,21 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'cancelation_model.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-_$CancelationModelImpl _$$CancelationModelImplFromJson(
- Map json) =>
- _$CancelationModelImpl(
- description: json['description'] as String,
- price: (json['price'] as num).toInt(),
- );
-
-Map _$$CancelationModelImplToJson(
- _$CancelationModelImpl instance) =>
- {
- 'description': instance.description,
- 'price': instance.price,
- };
diff --git a/lib/features/cancel_plan_bottom_sheet/service/cancel_plan_service.g.dart b/lib/features/cancel_plan_bottom_sheet/service/cancel_plan_service.g.dart
deleted file mode 100644
index 943e9d25..00000000
--- a/lib/features/cancel_plan_bottom_sheet/service/cancel_plan_service.g.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'cancel_plan_service.dart';
-
-// **************************************************************************
-// RetrofitGenerator
-// **************************************************************************
-
-// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
-
-class _CancelPlanService implements CancelPlanService {
- _CancelPlanService(this._dio, {this.baseUrl, this.errorLogger});
-
- final Dio _dio;
-
- String? baseUrl;
-
- final ParseErrorLogger? errorLogger;
-
- @override
- Future cancelChosenPlan({
- required int id,
- CancelationModel? body,
- }) async {
- final _extra = {};
- final queryParameters = {};
- queryParameters.removeWhere((k, v) => v == null);
- final _headers = {};
- final _data = body;
- final _options = _setStreamType(
- Options(method: 'POST', headers: _headers, extra: _extra)
- .compose(
- _dio.options,
- '/api/chosen_plans/${id}/cancel',
- queryParameters: queryParameters,
- data: _data,
- )
- .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
- );
- await _dio.fetch(_options);
- }
-
- RequestOptions _setStreamType(RequestOptions requestOptions) {
- if (T != dynamic &&
- !(requestOptions.responseType == ResponseType.bytes ||
- requestOptions.responseType == ResponseType.stream)) {
- if (T == String) {
- requestOptions.responseType = ResponseType.plain;
- } else {
- requestOptions.responseType = ResponseType.json;
- }
- }
- return requestOptions;
- }
-
- String _combineBaseUrls(String dioBaseUrl, String? baseUrl) {
- if (baseUrl == null || baseUrl.trim().isEmpty) {
- return dioBaseUrl;
- }
-
- final url = Uri.parse(baseUrl);
-
- if (url.isAbsolute) {
- return url.toString();
- }
-
- return Uri.parse(dioBaseUrl).resolveUri(url).toString();
- }
-}
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 5f14e0bf..b20646b9 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() {
@@ -84,25 +86,37 @@ class _ChatScreenState extends State {
_buildChat(BuildContext context, ChatRoomStateLoaded state) {
final chosenPlan = state.chatRoom.chosenPlan;
final amIConsultant = chosenPlan?.consultantId == state.chatRoom.users.sender.id;
- final showUserDetailsButton = amIConsultant &&
- [
- ChosenPlanStateEnum.stateStartDateHasBeenSet,
- ChosenPlanStateEnum.statePendingPayment,
- ChosenPlanStateEnum.stateInCoordination,
- ].contains(chosenPlan?.chosenPlanState);
+ final showUserDetailsButton = [
+ ChosenPlanStateEnum.stateStartDateHasBeenSet,
+ ChosenPlanStateEnum.statePendingPayment,
+ ChosenPlanStateEnum.stateInCoordination,
+ ].contains(chosenPlan?.chosenPlanState);
final showAboutOrderButton =
state.chatRoom.chosenPlan != null && state.chatRoom.chosenPlan!.chosenPlanState != ChosenPlanStateEnum.stateCanceledByTheInitiator;
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,
@@ -128,6 +142,7 @@ class _ChatScreenState extends State {
CircleAvatar(
radius: 20,
foregroundImage: NetworkImage(state.chatRoom.users.receiver.profilePhotoUrl!),
+ backgroundImage: const AssetImage('assets/images/no_avatar.png'),
),
if (state.chatRoom.users.receiver.profilePhotoUrl == null)
Container(
@@ -288,7 +303,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/chat_entry_widget.dart b/lib/features/chat/presentation/widgets/chat_entry_widget.dart
index bde4f8fd..1338c60b 100644
--- a/lib/features/chat/presentation/widgets/chat_entry_widget.dart
+++ b/lib/features/chat/presentation/widgets/chat_entry_widget.dart
@@ -40,9 +40,10 @@ class _ChatEntryWidgetState extends State {
children: [
CircleAvatar(
radius: 24,
- backgroundImage: NetworkImage(
+ foregroundImage: NetworkImage(
widget.chatRoom.users.toChatUser.profilePhotoUrl,
),
+ backgroundImage: const AssetImage('assets/images/no_avatar.png'),
backgroundColor: Colors.white,
),
const SizedBox(width: 12),
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/models/consultation_model.freezed.dart b/lib/features/consultations/models/consultation_model.freezed.dart
deleted file mode 100644
index 0fba8726..00000000
--- a/lib/features/consultations/models/consultation_model.freezed.dart
+++ /dev/null
@@ -1,799 +0,0 @@
-// coverage:ignore-file
-// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
-
-part of 'consultation_model.dart';
-
-// **************************************************************************
-// FreezedGenerator
-// **************************************************************************
-
-T _$identity(T value) => value;
-
-final _privateConstructorUsedError = UnsupportedError(
- 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
-
-ConsultationModel _$ConsultationModelFromJson(Map json) {
- return _ConsultationModel.fromJson(json);
-}
-
-/// @nodoc
-mixin _$ConsultationModel {
- int get id => throw _privateConstructorUsedError;
- @JsonKey(name: 'last_state')
- ChosenPlanStateEnum get chosenPlanState => throw _privateConstructorUsedError;
- String get planTitle => throw _privateConstructorUsedError;
- String get userName => throw _privateConstructorUsedError;
- String get userSlug => throw _privateConstructorUsedError;
- double get consultantPayment => throw _privateConstructorUsedError;
- int get duration => throw _privateConstructorUsedError;
- int get currentDiaryDay => throw _privateConstructorUsedError;
- @JsonKey(name: 'start_date', fromJson: parseDate)
- DateTime get startDate => throw _privateConstructorUsedError;
- @JsonKey(name: 'end_date', fromJson: parseDate)
- DateTime get endDate => throw _privateConstructorUsedError;
- @JsonKey(name: 'consultant_id')
- int get consultantId => throw _privateConstructorUsedError;
- List get diaries => throw _privateConstructorUsedError;
-
- /// Serializes this ConsultationModel to a JSON map.
- Map toJson() => throw _privateConstructorUsedError;
-
- /// Create a copy of ConsultationModel
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- $ConsultationModelCopyWith get copyWith =>
- throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-abstract class $ConsultationModelCopyWith<$Res> {
- factory $ConsultationModelCopyWith(
- ConsultationModel value, $Res Function(ConsultationModel) then) =
- _$ConsultationModelCopyWithImpl<$Res, ConsultationModel>;
- @useResult
- $Res call(
- {int id,
- @JsonKey(name: 'last_state') ChosenPlanStateEnum chosenPlanState,
- String planTitle,
- String userName,
- String userSlug,
- double consultantPayment,
- int duration,
- int currentDiaryDay,
- @JsonKey(name: 'start_date', fromJson: parseDate) DateTime startDate,
- @JsonKey(name: 'end_date', fromJson: parseDate) DateTime endDate,
- @JsonKey(name: 'consultant_id') int consultantId,
- List diaries});
-}
-
-/// @nodoc
-class _$ConsultationModelCopyWithImpl<$Res, $Val extends ConsultationModel>
- implements $ConsultationModelCopyWith<$Res> {
- _$ConsultationModelCopyWithImpl(this._value, this._then);
-
- // ignore: unused_field
- final $Val _value;
- // ignore: unused_field
- final $Res Function($Val) _then;
-
- /// Create a copy of ConsultationModel
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? id = null,
- Object? chosenPlanState = null,
- Object? planTitle = null,
- Object? userName = null,
- Object? userSlug = null,
- Object? consultantPayment = null,
- Object? duration = null,
- Object? currentDiaryDay = null,
- Object? startDate = null,
- Object? endDate = null,
- Object? consultantId = null,
- Object? diaries = null,
- }) {
- return _then(_value.copyWith(
- id: null == id
- ? _value.id
- : id // ignore: cast_nullable_to_non_nullable
- as int,
- chosenPlanState: null == chosenPlanState
- ? _value.chosenPlanState
- : chosenPlanState // ignore: cast_nullable_to_non_nullable
- as ChosenPlanStateEnum,
- planTitle: null == planTitle
- ? _value.planTitle
- : planTitle // ignore: cast_nullable_to_non_nullable
- as String,
- userName: null == userName
- ? _value.userName
- : userName // ignore: cast_nullable_to_non_nullable
- as String,
- userSlug: null == userSlug
- ? _value.userSlug
- : userSlug // ignore: cast_nullable_to_non_nullable
- as String,
- consultantPayment: null == consultantPayment
- ? _value.consultantPayment
- : consultantPayment // ignore: cast_nullable_to_non_nullable
- as double,
- duration: null == duration
- ? _value.duration
- : duration // ignore: cast_nullable_to_non_nullable
- as int,
- currentDiaryDay: null == currentDiaryDay
- ? _value.currentDiaryDay
- : currentDiaryDay // ignore: cast_nullable_to_non_nullable
- as int,
- startDate: null == startDate
- ? _value.startDate
- : startDate // ignore: cast_nullable_to_non_nullable
- as DateTime,
- endDate: null == endDate
- ? _value.endDate
- : endDate // ignore: cast_nullable_to_non_nullable
- as DateTime,
- consultantId: null == consultantId
- ? _value.consultantId
- : consultantId // ignore: cast_nullable_to_non_nullable
- as int,
- diaries: null == diaries
- ? _value.diaries
- : diaries // ignore: cast_nullable_to_non_nullable
- as List,
- ) as $Val);
- }
-}
-
-/// @nodoc
-abstract class _$$ConsultationModelImplCopyWith<$Res>
- implements $ConsultationModelCopyWith<$Res> {
- factory _$$ConsultationModelImplCopyWith(_$ConsultationModelImpl value,
- $Res Function(_$ConsultationModelImpl) then) =
- __$$ConsultationModelImplCopyWithImpl<$Res>;
- @override
- @useResult
- $Res call(
- {int id,
- @JsonKey(name: 'last_state') ChosenPlanStateEnum chosenPlanState,
- String planTitle,
- String userName,
- String userSlug,
- double consultantPayment,
- int duration,
- int currentDiaryDay,
- @JsonKey(name: 'start_date', fromJson: parseDate) DateTime startDate,
- @JsonKey(name: 'end_date', fromJson: parseDate) DateTime endDate,
- @JsonKey(name: 'consultant_id') int consultantId,
- List diaries});
-}
-
-/// @nodoc
-class __$$ConsultationModelImplCopyWithImpl<$Res>
- extends _$ConsultationModelCopyWithImpl<$Res, _$ConsultationModelImpl>
- implements _$$ConsultationModelImplCopyWith<$Res> {
- __$$ConsultationModelImplCopyWithImpl(_$ConsultationModelImpl _value,
- $Res Function(_$ConsultationModelImpl) _then)
- : super(_value, _then);
-
- /// Create a copy of ConsultationModel
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? id = null,
- Object? chosenPlanState = null,
- Object? planTitle = null,
- Object? userName = null,
- Object? userSlug = null,
- Object? consultantPayment = null,
- Object? duration = null,
- Object? currentDiaryDay = null,
- Object? startDate = null,
- Object? endDate = null,
- Object? consultantId = null,
- Object? diaries = null,
- }) {
- return _then(_$ConsultationModelImpl(
- id: null == id
- ? _value.id
- : id // ignore: cast_nullable_to_non_nullable
- as int,
- chosenPlanState: null == chosenPlanState
- ? _value.chosenPlanState
- : chosenPlanState // ignore: cast_nullable_to_non_nullable
- as ChosenPlanStateEnum,
- planTitle: null == planTitle
- ? _value.planTitle
- : planTitle // ignore: cast_nullable_to_non_nullable
- as String,
- userName: null == userName
- ? _value.userName
- : userName // ignore: cast_nullable_to_non_nullable
- as String,
- userSlug: null == userSlug
- ? _value.userSlug
- : userSlug // ignore: cast_nullable_to_non_nullable
- as String,
- consultantPayment: null == consultantPayment
- ? _value.consultantPayment
- : consultantPayment // ignore: cast_nullable_to_non_nullable
- as double,
- duration: null == duration
- ? _value.duration
- : duration // ignore: cast_nullable_to_non_nullable
- as int,
- currentDiaryDay: null == currentDiaryDay
- ? _value.currentDiaryDay
- : currentDiaryDay // ignore: cast_nullable_to_non_nullable
- as int,
- startDate: null == startDate
- ? _value.startDate
- : startDate // ignore: cast_nullable_to_non_nullable
- as DateTime,
- endDate: null == endDate
- ? _value.endDate
- : endDate // ignore: cast_nullable_to_non_nullable
- as DateTime,
- consultantId: null == consultantId
- ? _value.consultantId
- : consultantId // ignore: cast_nullable_to_non_nullable
- as int,
- diaries: null == diaries
- ? _value._diaries
- : diaries // ignore: cast_nullable_to_non_nullable
- as List,
- ));
- }
-}
-
-/// @nodoc
-@JsonSerializable()
-class _$ConsultationModelImpl implements _ConsultationModel {
- _$ConsultationModelImpl(
- {required this.id,
- @JsonKey(name: 'last_state') required this.chosenPlanState,
- required this.planTitle,
- required this.userName,
- required this.userSlug,
- required this.consultantPayment,
- required this.duration,
- required this.currentDiaryDay,
- @JsonKey(name: 'start_date', fromJson: parseDate) required this.startDate,
- @JsonKey(name: 'end_date', fromJson: parseDate) required this.endDate,
- @JsonKey(name: 'consultant_id') required this.consultantId,
- required final List diaries})
- : _diaries = diaries;
-
- factory _$ConsultationModelImpl.fromJson(Map json) =>
- _$$ConsultationModelImplFromJson(json);
-
- @override
- final int id;
- @override
- @JsonKey(name: 'last_state')
- final ChosenPlanStateEnum chosenPlanState;
- @override
- final String planTitle;
- @override
- final String userName;
- @override
- final String userSlug;
- @override
- final double consultantPayment;
- @override
- final int duration;
- @override
- final int currentDiaryDay;
- @override
- @JsonKey(name: 'start_date', fromJson: parseDate)
- final DateTime startDate;
- @override
- @JsonKey(name: 'end_date', fromJson: parseDate)
- final DateTime endDate;
- @override
- @JsonKey(name: 'consultant_id')
- final int consultantId;
- final List _diaries;
- @override
- List get diaries {
- if (_diaries is EqualUnmodifiableListView) return _diaries;
- // ignore: implicit_dynamic_type
- return EqualUnmodifiableListView(_diaries);
- }
-
- @override
- String toString() {
- return 'ConsultationModel(id: $id, chosenPlanState: $chosenPlanState, planTitle: $planTitle, userName: $userName, userSlug: $userSlug, consultantPayment: $consultantPayment, duration: $duration, currentDiaryDay: $currentDiaryDay, startDate: $startDate, endDate: $endDate, consultantId: $consultantId, diaries: $diaries)';
- }
-
- @override
- bool operator ==(Object other) {
- return identical(this, other) ||
- (other.runtimeType == runtimeType &&
- other is _$ConsultationModelImpl &&
- (identical(other.id, id) || other.id == id) &&
- (identical(other.chosenPlanState, chosenPlanState) ||
- other.chosenPlanState == chosenPlanState) &&
- (identical(other.planTitle, planTitle) ||
- other.planTitle == planTitle) &&
- (identical(other.userName, userName) ||
- other.userName == userName) &&
- (identical(other.userSlug, userSlug) ||
- other.userSlug == userSlug) &&
- (identical(other.consultantPayment, consultantPayment) ||
- other.consultantPayment == consultantPayment) &&
- (identical(other.duration, duration) ||
- other.duration == duration) &&
- (identical(other.currentDiaryDay, currentDiaryDay) ||
- other.currentDiaryDay == currentDiaryDay) &&
- (identical(other.startDate, startDate) ||
- other.startDate == startDate) &&
- (identical(other.endDate, endDate) || other.endDate == endDate) &&
- (identical(other.consultantId, consultantId) ||
- other.consultantId == consultantId) &&
- const DeepCollectionEquality().equals(other._diaries, _diaries));
- }
-
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- int get hashCode => Object.hash(
- runtimeType,
- id,
- chosenPlanState,
- planTitle,
- userName,
- userSlug,
- consultantPayment,
- duration,
- currentDiaryDay,
- startDate,
- endDate,
- consultantId,
- const DeepCollectionEquality().hash(_diaries));
-
- /// Create a copy of ConsultationModel
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- @pragma('vm:prefer-inline')
- _$$ConsultationModelImplCopyWith<_$ConsultationModelImpl> get copyWith =>
- __$$ConsultationModelImplCopyWithImpl<_$ConsultationModelImpl>(
- this, _$identity);
-
- @override
- Map toJson() {
- return _$$ConsultationModelImplToJson(
- this,
- );
- }
-}
-
-abstract class _ConsultationModel implements ConsultationModel {
- factory _ConsultationModel(
- {required final int id,
- @JsonKey(name: 'last_state')
- required final ChosenPlanStateEnum chosenPlanState,
- required final String planTitle,
- required final String userName,
- required final String userSlug,
- required final double consultantPayment,
- required final int duration,
- required final int currentDiaryDay,
- @JsonKey(name: 'start_date', fromJson: parseDate)
- required final DateTime startDate,
- @JsonKey(name: 'end_date', fromJson: parseDate)
- required final DateTime endDate,
- @JsonKey(name: 'consultant_id') required final int consultantId,
- required final List diaries}) = _$ConsultationModelImpl;
-
- factory _ConsultationModel.fromJson(Map json) =
- _$ConsultationModelImpl.fromJson;
-
- @override
- int get id;
- @override
- @JsonKey(name: 'last_state')
- ChosenPlanStateEnum get chosenPlanState;
- @override
- String get planTitle;
- @override
- String get userName;
- @override
- String get userSlug;
- @override
- double get consultantPayment;
- @override
- int get duration;
- @override
- int get currentDiaryDay;
- @override
- @JsonKey(name: 'start_date', fromJson: parseDate)
- DateTime get startDate;
- @override
- @JsonKey(name: 'end_date', fromJson: parseDate)
- DateTime get endDate;
- @override
- @JsonKey(name: 'consultant_id')
- int get consultantId;
- @override
- List get diaries;
-
- /// Create a copy of ConsultationModel
- /// with the given fields replaced by the non-null parameter values.
- @override
- @JsonKey(includeFromJson: false, includeToJson: false)
- _$$ConsultationModelImplCopyWith<_$ConsultationModelImpl> get copyWith =>
- throw _privateConstructorUsedError;
-}
-
-DiaryModel _$DiaryModelFromJson(Map json) {
- return _DiaryModel.fromJson(json);
-}
-
-/// @nodoc
-mixin _$DiaryModel {
- int get id => throw _privateConstructorUsedError;
- DiaryStateEnum get state => throw _privateConstructorUsedError;
- @JsonKey(fromJson: parseUnformattedDate)
- DateTime get date => throw _privateConstructorUsedError;
-
- /// Serializes this DiaryModel to a JSON map.
- Map toJson() => throw _privateConstructorUsedError;
-
- /// Create a copy of DiaryModel
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- $DiaryModelCopyWith get copyWith =>
- throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-abstract class $DiaryModelCopyWith<$Res> {
- factory $DiaryModelCopyWith(
- DiaryModel value, $Res Function(DiaryModel) then) =
- _$DiaryModelCopyWithImpl<$Res, DiaryModel>;
- @useResult
- $Res call(
- {int id,
- DiaryStateEnum state,
- @JsonKey(fromJson: parseUnformattedDate) DateTime date});
-}
-
-/// @nodoc
-class _$DiaryModelCopyWithImpl<$Res, $Val extends DiaryModel>
- implements $DiaryModelCopyWith<$Res> {
- _$DiaryModelCopyWithImpl(this._value, this._then);
-
- // ignore: unused_field
- final $Val _value;
- // ignore: unused_field
- final $Res Function($Val) _then;
-
- /// Create a copy of DiaryModel
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? id = null,
- Object? state = null,
- Object? date = null,
- }) {
- return _then(_value.copyWith(
- id: null == id
- ? _value.id
- : id // ignore: cast_nullable_to_non_nullable
- as int,
- state: null == state
- ? _value.state
- : state // ignore: cast_nullable_to_non_nullable
- as DiaryStateEnum,
- date: null == date
- ? _value.date
- : date // ignore: cast_nullable_to_non_nullable
- as DateTime,
- ) as $Val);
- }
-}
-
-/// @nodoc
-abstract class _$$DiaryModelImplCopyWith<$Res>
- implements $DiaryModelCopyWith<$Res> {
- factory _$$DiaryModelImplCopyWith(
- _$DiaryModelImpl value, $Res Function(_$DiaryModelImpl) then) =
- __$$DiaryModelImplCopyWithImpl<$Res>;
- @override
- @useResult
- $Res call(
- {int id,
- DiaryStateEnum state,
- @JsonKey(fromJson: parseUnformattedDate) DateTime date});
-}
-
-/// @nodoc
-class __$$DiaryModelImplCopyWithImpl<$Res>
- extends _$DiaryModelCopyWithImpl<$Res, _$DiaryModelImpl>
- implements _$$DiaryModelImplCopyWith<$Res> {
- __$$DiaryModelImplCopyWithImpl(
- _$DiaryModelImpl _value, $Res Function(_$DiaryModelImpl) _then)
- : super(_value, _then);
-
- /// Create a copy of DiaryModel
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? id = null,
- Object? state = null,
- Object? date = null,
- }) {
- return _then(_$DiaryModelImpl(
- id: null == id
- ? _value.id
- : id // ignore: cast_nullable_to_non_nullable
- as int,
- state: null == state
- ? _value.state
- : state // ignore: cast_nullable_to_non_nullable
- as DiaryStateEnum,
- date: null == date
- ? _value.date
- : date // ignore: cast_nullable_to_non_nullable
- as DateTime,
- ));
- }
-}
-
-/// @nodoc
-@JsonSerializable()
-class _$DiaryModelImpl implements _DiaryModel {
- _$DiaryModelImpl(
- {required this.id,
- required this.state,
- @JsonKey(fromJson: parseUnformattedDate) required this.date});
-
- factory _$DiaryModelImpl.fromJson(Map json) =>
- _$$DiaryModelImplFromJson(json);
-
- @override
- final int id;
- @override
- final DiaryStateEnum state;
- @override
- @JsonKey(fromJson: parseUnformattedDate)
- final DateTime date;
-
- @override
- String toString() {
- return 'DiaryModel(id: $id, state: $state, date: $date)';
- }
-
- @override
- bool operator ==(Object other) {
- return identical(this, other) ||
- (other.runtimeType == runtimeType &&
- other is _$DiaryModelImpl &&
- (identical(other.id, id) || other.id == id) &&
- (identical(other.state, state) || other.state == state) &&
- (identical(other.date, date) || other.date == date));
- }
-
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- int get hashCode => Object.hash(runtimeType, id, state, date);
-
- /// Create a copy of DiaryModel
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- @pragma('vm:prefer-inline')
- _$$DiaryModelImplCopyWith<_$DiaryModelImpl> get copyWith =>
- __$$DiaryModelImplCopyWithImpl<_$DiaryModelImpl>(this, _$identity);
-
- @override
- Map toJson() {
- return _$$DiaryModelImplToJson(
- this,
- );
- }
-}
-
-abstract class _DiaryModel implements DiaryModel {
- factory _DiaryModel(
- {required final int id,
- required final DiaryStateEnum state,
- @JsonKey(fromJson: parseUnformattedDate)
- required final DateTime date}) = _$DiaryModelImpl;
-
- factory _DiaryModel.fromJson(Map json) =
- _$DiaryModelImpl.fromJson;
-
- @override
- int get id;
- @override
- DiaryStateEnum get state;
- @override
- @JsonKey(fromJson: parseUnformattedDate)
- DateTime get date;
-
- /// Create a copy of DiaryModel
- /// with the given fields replaced by the non-null parameter values.
- @override
- @JsonKey(includeFromJson: false, includeToJson: false)
- _$$DiaryModelImplCopyWith<_$DiaryModelImpl> get copyWith =>
- throw _privateConstructorUsedError;
-}
-
-ConsultationPaginationModel _$ConsultationPaginationModelFromJson(
- Map json) {
- return _ConsultationPaginationModel.fromJson(json);
-}
-
-/// @nodoc
-mixin _$ConsultationPaginationModel {
- List get data => throw _privateConstructorUsedError;
-
- /// Serializes this ConsultationPaginationModel to a JSON map.
- Map toJson() => throw _privateConstructorUsedError;
-
- /// Create a copy of ConsultationPaginationModel
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- $ConsultationPaginationModelCopyWith
- get copyWith => throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-abstract class $ConsultationPaginationModelCopyWith<$Res> {
- factory $ConsultationPaginationModelCopyWith(
- ConsultationPaginationModel value,
- $Res Function(ConsultationPaginationModel) then) =
- _$ConsultationPaginationModelCopyWithImpl<$Res,
- ConsultationPaginationModel>;
- @useResult
- $Res call({List data});
-}
-
-/// @nodoc
-class _$ConsultationPaginationModelCopyWithImpl<$Res,
- $Val extends ConsultationPaginationModel>
- implements $ConsultationPaginationModelCopyWith<$Res> {
- _$ConsultationPaginationModelCopyWithImpl(this._value, this._then);
-
- // ignore: unused_field
- final $Val _value;
- // ignore: unused_field
- final $Res Function($Val) _then;
-
- /// Create a copy of ConsultationPaginationModel
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? data = null,
- }) {
- return _then(_value.copyWith(
- data: null == data
- ? _value.data
- : data // ignore: cast_nullable_to_non_nullable
- as List,
- ) as $Val);
- }
-}
-
-/// @nodoc
-abstract class _$$ConsultationPaginationModelImplCopyWith<$Res>
- implements $ConsultationPaginationModelCopyWith<$Res> {
- factory _$$ConsultationPaginationModelImplCopyWith(
- _$ConsultationPaginationModelImpl value,
- $Res Function(_$ConsultationPaginationModelImpl) then) =
- __$$ConsultationPaginationModelImplCopyWithImpl<$Res>;
- @override
- @useResult
- $Res call({List data});
-}
-
-/// @nodoc
-class __$$ConsultationPaginationModelImplCopyWithImpl<$Res>
- extends _$ConsultationPaginationModelCopyWithImpl<$Res,
- _$ConsultationPaginationModelImpl>
- implements _$$ConsultationPaginationModelImplCopyWith<$Res> {
- __$$ConsultationPaginationModelImplCopyWithImpl(
- _$ConsultationPaginationModelImpl _value,
- $Res Function(_$ConsultationPaginationModelImpl) _then)
- : super(_value, _then);
-
- /// Create a copy of ConsultationPaginationModel
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? data = null,
- }) {
- return _then(_$ConsultationPaginationModelImpl(
- data: null == data
- ? _value._data
- : data // ignore: cast_nullable_to_non_nullable
- as List,
- ));
- }
-}
-
-/// @nodoc
-@JsonSerializable()
-class _$ConsultationPaginationModelImpl
- implements _ConsultationPaginationModel {
- _$ConsultationPaginationModelImpl(
- {required final List data})
- : _data = data;
-
- factory _$ConsultationPaginationModelImpl.fromJson(
- Map json) =>
- _$$ConsultationPaginationModelImplFromJson(json);
-
- final List _data;
- @override
- List get data {
- if (_data is EqualUnmodifiableListView) return _data;
- // ignore: implicit_dynamic_type
- return EqualUnmodifiableListView(_data);
- }
-
- @override
- String toString() {
- return 'ConsultationPaginationModel(data: $data)';
- }
-
- @override
- bool operator ==(Object other) {
- return identical(this, other) ||
- (other.runtimeType == runtimeType &&
- other is _$ConsultationPaginationModelImpl &&
- const DeepCollectionEquality().equals(other._data, _data));
- }
-
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- int get hashCode =>
- Object.hash(runtimeType, const DeepCollectionEquality().hash(_data));
-
- /// Create a copy of ConsultationPaginationModel
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- @pragma('vm:prefer-inline')
- _$$ConsultationPaginationModelImplCopyWith<_$ConsultationPaginationModelImpl>
- get copyWith => __$$ConsultationPaginationModelImplCopyWithImpl<
- _$ConsultationPaginationModelImpl>(this, _$identity);
-
- @override
- Map toJson() {
- return _$$ConsultationPaginationModelImplToJson(
- this,
- );
- }
-}
-
-abstract class _ConsultationPaginationModel
- implements ConsultationPaginationModel {
- factory _ConsultationPaginationModel(
- {required final List data}) =
- _$ConsultationPaginationModelImpl;
-
- factory _ConsultationPaginationModel.fromJson(Map json) =
- _$ConsultationPaginationModelImpl.fromJson;
-
- @override
- List get data;
-
- /// Create a copy of ConsultationPaginationModel
- /// with the given fields replaced by the non-null parameter values.
- @override
- @JsonKey(includeFromJson: false, includeToJson: false)
- _$$ConsultationPaginationModelImplCopyWith<_$ConsultationPaginationModelImpl>
- get copyWith => throw _privateConstructorUsedError;
-}
diff --git a/lib/features/consultations/models/consultation_model.g.dart b/lib/features/consultations/models/consultation_model.g.dart
deleted file mode 100644
index ff93e365..00000000
--- a/lib/features/consultations/models/consultation_model.g.dart
+++ /dev/null
@@ -1,100 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'consultation_model.dart';
-
-// **************************************************************************
-// JsonSerializableGenerator
-// **************************************************************************
-
-_$ConsultationModelImpl _$$ConsultationModelImplFromJson(
- Map json) =>
- _$ConsultationModelImpl(
- id: (json['id'] as num).toInt(),
- chosenPlanState:
- $enumDecode(_$ChosenPlanStateEnumEnumMap, json['last_state']),
- planTitle: json['planTitle'] as String,
- userName: json['userName'] as String,
- userSlug: json['userSlug'] as String,
- consultantPayment: (json['consultantPayment'] as num).toDouble(),
- duration: (json['duration'] as num).toInt(),
- currentDiaryDay: (json['currentDiaryDay'] as num).toInt(),
- startDate: parseDate(json['start_date'] as String),
- endDate: parseDate(json['end_date'] as String),
- consultantId: (json['consultant_id'] as num).toInt(),
- diaries: (json['diaries'] as List)
- .map((e) => DiaryModel.fromJson(e as Map))
- .toList(),
- );
-
-Map _$$ConsultationModelImplToJson(
- _$ConsultationModelImpl instance) =>
- {
- 'id': instance.id,
- 'last_state': _$ChosenPlanStateEnumEnumMap[instance.chosenPlanState]!,
- 'planTitle': instance.planTitle,
- 'userName': instance.userName,
- 'userSlug': instance.userSlug,
- 'consultantPayment': instance.consultantPayment,
- 'duration': instance.duration,
- 'currentDiaryDay': instance.currentDiaryDay,
- 'start_date': instance.startDate.toIso8601String(),
- 'end_date': instance.endDate.toIso8601String(),
- 'consultant_id': instance.consultantId,
- 'diaries': instance.diaries,
- };
-
-const _$ChosenPlanStateEnumEnumMap = {
- ChosenPlanStateEnum.stateInited: 'initied',
- ChosenPlanStateEnum.stateStartDateHasBeenSet: 'start_date_has_been_set',
- ChosenPlanStateEnum.stateInCoordination: 'in_coordination',
- ChosenPlanStateEnum.stateStarted: 'started',
- ChosenPlanStateEnum.stateInProgress: 'in_progress',
- ChosenPlanStateEnum.statePendingPayment: 'pending_payment',
- ChosenPlanStateEnum.stateConfirmedByConsultant: 'confirmed_by_consultant',
- ChosenPlanStateEnum.statePaid: 'paid',
- ChosenPlanStateEnum.stateCanceledByTheInitiator: 'canceled_by_the_initiator',
- ChosenPlanStateEnum.stateLastDayStarted: 'last_day_started',
- ChosenPlanStateEnum.stateLastDayFinished: 'last_day_finished',
- ChosenPlanStateEnum.stateComplained: 'complained',
- ChosenPlanStateEnum.stateDone: 'done',
- ChosenPlanStateEnum.stateChargeWasCollected: 'charge_was_collected',
-};
-
-_$DiaryModelImpl _$$DiaryModelImplFromJson(Map json) =>
- _$DiaryModelImpl(
- id: (json['id'] as num).toInt(),
- state: $enumDecode(_$DiaryStateEnumEnumMap, json['state']),
- date: parseUnformattedDate(json['date'] as String),
- );
-
-Map _$$DiaryModelImplToJson(_$DiaryModelImpl instance) =>
- {
- 'id': instance.id,
- 'state': _$DiaryStateEnumEnumMap[instance.state]!,
- 'date': instance.date.toIso8601String(),
- };
-
-const _$DiaryStateEnumEnumMap = {
- DiaryStateEnum.init: 'init',
- DiaryStateEnum.started: 'started',
- DiaryStateEnum.finished: 'finished',
- DiaryStateEnum.commented: 'commented',
- DiaryStateEnum.reviewedByUser: 'reviewed_by_user',
- DiaryStateEnum.lastDayStarted: 'last_day_started',
- DiaryStateEnum.lastDayFinished: 'last_day_finished',
- DiaryStateEnum.lastDayCommented: 'last_day_commented',
-};
-
-_$ConsultationPaginationModelImpl _$$ConsultationPaginationModelImplFromJson(
- Map json) =>
- _$ConsultationPaginationModelImpl(
- data: (json['data'] as List)
- .map((e) => ConsultationModel.fromJson(e as Map))
- .toList(),
- );
-
-Map _$$ConsultationPaginationModelImplToJson(
- _$ConsultationPaginationModelImpl instance) =>
- {
- 'data': instance.data,
- };
diff --git a/lib/features/consultations/presentation/cubit/consultations_state.freezed.dart b/lib/features/consultations/presentation/cubit/consultations_state.freezed.dart
deleted file mode 100644
index 7d4203e5..00000000
--- a/lib/features/consultations/presentation/cubit/consultations_state.freezed.dart
+++ /dev/null
@@ -1,175 +0,0 @@
-// coverage:ignore-file
-// GENERATED CODE - DO NOT MODIFY BY HAND
-// ignore_for_file: type=lint
-// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
-
-part of 'consultations_state.dart';
-
-// **************************************************************************
-// FreezedGenerator
-// **************************************************************************
-
-T _$identity(T value) => value;
-
-final _privateConstructorUsedError = UnsupportedError(
- 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
-
-/// @nodoc
-mixin _$ConsultationsState {
- BaseState get state => throw _privateConstructorUsedError;
- List get consultations =>
- throw _privateConstructorUsedError;
-
- /// Create a copy of ConsultationsState
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- $ConsultationsStateCopyWith get copyWith =>
- throw _privateConstructorUsedError;
-}
-
-/// @nodoc
-abstract class $ConsultationsStateCopyWith<$Res> {
- factory $ConsultationsStateCopyWith(
- ConsultationsState value, $Res Function(ConsultationsState) then) =
- _$ConsultationsStateCopyWithImpl<$Res, ConsultationsState>;
- @useResult
- $Res call({BaseState state, List consultations});
-}
-
-/// @nodoc
-class _$ConsultationsStateCopyWithImpl<$Res, $Val extends ConsultationsState>
- implements $ConsultationsStateCopyWith<$Res> {
- _$ConsultationsStateCopyWithImpl(this._value, this._then);
-
- // ignore: unused_field
- final $Val _value;
- // ignore: unused_field
- final $Res Function($Val) _then;
-
- /// Create a copy of ConsultationsState
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? state = null,
- Object? consultations = null,
- }) {
- return _then(_value.copyWith(
- state: null == state
- ? _value.state
- : state // ignore: cast_nullable_to_non_nullable
- as BaseState,
- consultations: null == consultations
- ? _value.consultations
- : consultations // ignore: cast_nullable_to_non_nullable
- as List,
- ) as $Val);
- }
-}
-
-/// @nodoc
-abstract class _$$ConsultationsStateImplCopyWith<$Res>
- implements $ConsultationsStateCopyWith<$Res> {
- factory _$$ConsultationsStateImplCopyWith(_$ConsultationsStateImpl value,
- $Res Function(_$ConsultationsStateImpl) then) =
- __$$ConsultationsStateImplCopyWithImpl<$Res>;
- @override
- @useResult
- $Res call({BaseState state, List consultations});
-}
-
-/// @nodoc
-class __$$ConsultationsStateImplCopyWithImpl<$Res>
- extends _$ConsultationsStateCopyWithImpl<$Res, _$ConsultationsStateImpl>
- implements _$$ConsultationsStateImplCopyWith<$Res> {
- __$$ConsultationsStateImplCopyWithImpl(_$ConsultationsStateImpl _value,
- $Res Function(_$ConsultationsStateImpl) _then)
- : super(_value, _then);
-
- /// Create a copy of ConsultationsState
- /// with the given fields replaced by the non-null parameter values.
- @pragma('vm:prefer-inline')
- @override
- $Res call({
- Object? state = null,
- Object? consultations = null,
- }) {
- return _then(_$ConsultationsStateImpl(
- state: null == state
- ? _value.state
- : state // ignore: cast_nullable_to_non_nullable
- as BaseState,
- consultations: null == consultations
- ? _value._consultations
- : consultations // ignore: cast_nullable_to_non_nullable
- as List,
- ));
- }
-}
-
-/// @nodoc
-
-class _$ConsultationsStateImpl implements _ConsultationsState {
- _$ConsultationsStateImpl(
- {this.state = BaseState.initial,
- final List consultations = const []})
- : _consultations = consultations;
-
- @override
- @JsonKey()
- final BaseState state;
- final List _consultations;
- @override
- @JsonKey()
- List get consultations {
- if (_consultations is EqualUnmodifiableListView) return _consultations;
- // ignore: implicit_dynamic_type
- return EqualUnmodifiableListView(_consultations);
- }
-
- @override
- String toString() {
- return 'ConsultationsState(state: $state, consultations: $consultations)';
- }
-
- @override
- bool operator ==(Object other) {
- return identical(this, other) ||
- (other.runtimeType == runtimeType &&
- other is _$ConsultationsStateImpl &&
- (identical(other.state, state) || other.state == state) &&
- const DeepCollectionEquality()
- .equals(other._consultations, _consultations));
- }
-
- @override
- int get hashCode => Object.hash(
- runtimeType, state, const DeepCollectionEquality().hash(_consultations));
-
- /// Create a copy of ConsultationsState
- /// with the given fields replaced by the non-null parameter values.
- @JsonKey(includeFromJson: false, includeToJson: false)
- @override
- @pragma('vm:prefer-inline')
- _$$ConsultationsStateImplCopyWith<_$ConsultationsStateImpl> get copyWith =>
- __$$ConsultationsStateImplCopyWithImpl<_$ConsultationsStateImpl>(
- this, _$identity);
-}
-
-abstract class _ConsultationsState implements ConsultationsState {
- factory _ConsultationsState(
- {final BaseState state,
- final List consultations}) = _$ConsultationsStateImpl;
-
- @override
- BaseState get state;
- @override
- List get consultations;
-
- /// Create a copy of ConsultationsState
- /// with the given fields replaced by the non-null parameter values.
- @override
- @JsonKey(includeFromJson: false, includeToJson: false)
- _$$ConsultationsStateImplCopyWith<_$ConsultationsStateImpl> get copyWith =>
- throw _privateConstructorUsedError;
-}
diff --git a/lib/features/consultations/services/consultation_service.dart b/lib/features/consultations/services/consultation_service.dart
index 25719f8a..e5236e0f 100644
--- a/lib/features/consultations/services/consultation_service.dart
+++ b/lib/features/consultations/services/consultation_service.dart
@@ -10,5 +10,4 @@ abstract class ConsultationService {
@GET('/api/consultations')
Future getConsultations();
-
}
diff --git a/lib/features/consultations/services/consultation_service.g.dart b/lib/features/consultations/services/consultation_service.g.dart
deleted file mode 100644
index ff0edd2b..00000000
--- a/lib/features/consultations/services/consultation_service.g.dart
+++ /dev/null
@@ -1,73 +0,0 @@
-// GENERATED CODE - DO NOT MODIFY BY HAND
-
-part of 'consultation_service.dart';
-
-// **************************************************************************
-// RetrofitGenerator
-// **************************************************************************
-
-// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element,unnecessary_string_interpolations
-
-class _ConsultationService implements ConsultationService {
- _ConsultationService(this._dio, {this.baseUrl, this.errorLogger});
-
- final Dio _dio;
-
- String? baseUrl;
-
- final ParseErrorLogger? errorLogger;
-
- @override
- Future getConsultations() async {
- final _extra = {};
- final queryParameters = {};
- final _headers = {};
- const Map? _data = null;
- final _options = _setStreamType(
- Options(method: 'GET', headers: _headers, extra: _extra)
- .compose(
- _dio.options,
- '/api/consultations',
- queryParameters: queryParameters,
- data: _data,
- )
- .copyWith(baseUrl: _combineBaseUrls(_dio.options.baseUrl, baseUrl)),
- );
- final _result = await _dio.fetch