Merge pull request 'mso7nueh-feat(chat)' (#84) from mso7nueh-feat(chat) into main

Reviewed-on: maxxkim/eatvio_app#84
This commit is contained in:
mso7nueh
2024-07-15 14:37:45 +00:00
278 changed files with 6858 additions and 9916 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

2
.env
View File

@@ -1,2 +0,0 @@
SERVER_ROOT='https://mobile-stage.eatvio.ru/api'
STORAGE_URL='https://mobile-stage.eatvio.ru/storage/'

View File

@@ -78,7 +78,6 @@ jobs:
- name: Test
run: |
touch .env
flutter test
- name: Build apk

View File

@@ -89,7 +89,6 @@ jobs:
- name: Test
run: |
touch .env
flutter test
- name: Build apk

1
.gitignore vendored
View File

@@ -6,5 +6,4 @@
/.flutter-plugins
/.flutter-plugins-dependencies
/.packages
/.env
/node_modules/

97
flutter_01.log Normal file
View File

@@ -0,0 +1,97 @@
Flutter crash report.
Please report a bug at https://github.com/flutter/flutter/issues.
## command
flutter analyze
## exception
PathNotFoundException: PathNotFoundException: Cannot open file, path = '/home/alex/snap/flutter/common/flutter/version' (OS Error: No such file or directory, errno = 2)
```
#0 _File.throwIfError (dart:io/file_impl.dart:675:7)
#1 _File.openSync (dart:io/file_impl.dart:490:5)
#2 _File.readAsBytesSync (dart:io/file_impl.dart:574:18)
#3 _File.readAsStringSync (dart:io/file_impl.dart:624:18)
#4 ForwardingFile.readAsStringSync (package:file/src/forwarding/forwarding_file.dart:99:16)
#5 ErrorHandlingFile.readAsStringSync.<anonymous closure> (package:flutter_tools/src/base/error_handling_io.dart:217:22)
#6 _runSync (package:flutter_tools/src/base/error_handling_io.dart:587:14)
#7 ErrorHandlingFile.readAsStringSync (package:flutter_tools/src/base/error_handling_io.dart:216:12)
#8 _DefaultPub.get (package:flutter_tools/src/dart/pub.dart:302:58)
#9 FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:1724:17)
<asynchronous suspension>
#10 FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1394:27)
<asynchronous suspension>
#11 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:153:19)
<asynchronous suspension>
#12 CommandRunner.runCommand (package:args/command_runner.dart:212:13)
<asynchronous suspension>
#13 FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:372:9)
<asynchronous suspension>
#14 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:153:19)
<asynchronous suspension>
#15 FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:308:5)
<asynchronous suspension>
#16 run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:130:9)
<asynchronous suspension>
#17 AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:153:19)
<asynchronous suspension>
#18 main (package:flutter_tools/executable.dart:93:3)
<asynchronous suspension>
```
## flutter doctor
```
[!] Flutter (Channel [user-branch], 0.0.0-unknown, on Ubuntu 24.04 LTS 6.8.0-38-generic, locale ru_RU.UTF-8)
! Flutter version 0.0.0-unknown on channel [user-branch] at /home/alex/snap/flutter/common/flutter
Currently on an unknown channel. Run `flutter channel` to switch to an official channel.
If that doesn't fix the issue, reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
Cannot resolve current version, possibly due to local changes.
Reinstall Flutter by following instructions at https://flutter.dev/docs/get-started/install.
! Upstream repository unknown source is not a standard remote.
Set environment variable "FLUTTER_GIT_URL" to unknown source to dismiss this error.
• Framework revision (), 1970-01-01 03:00:00.000
• Engine revision edd8546116
• Dart version 3.4.3
• DevTools version 2.34.3
• If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
• Android SDK at /home/alex/Android/Sdk
• Platform android-35, build-tools 35.0.0
• Java binary at: /snap/android-studio/161/jbr/bin/java
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
• All Android licenses accepted.
[✓] Chrome - develop for the web
• Chrome at google-chrome
[✓] Linux toolchain - develop for Linux desktop
• clang version 10.0.0-4ubuntu1
• cmake version 3.16.3
• ninja version 1.10.0
• pkg-config version 0.29.1
[✓] Android Studio (version 2024.1)
• Android Studio at /snap/android-studio/161
• Flutter plugin version 80.0.2
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 17.0.10+0-17.0.10b1087.21-11609105)
[✓] VS Code (version 1.91.1)
• VS Code at /usr/share/code
• Flutter extension version 3.92.0
[✓] Connected device (3 available)
• sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64 • Android 15 (API 35) (emulator)
• Linux (desktop) • linux • linux-x64 • Ubuntu 24.04 LTS 6.8.0-38-generic
• Chrome (web) • chrome • web-javascript • Google Chrome 126.0.6478.126
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 1 category.
```

View File

@@ -1,37 +1,23 @@
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/features/blog_post/presentation/pages/blog_post_screen.dart';
import 'package:eatvio_app/features/blog_post_create/presentation/pages/blog_post_create_screen.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_screen.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart';
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
import 'package:eatvio_app/features/feed/presentation/pages/feed_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/registration_screen.dart';
import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
import 'package:eatvio_app/presentation/diary/diary_edit_screen/diary_edit_screen.dart';
import 'package:eatvio_app/presentation/diets/diet_create_screen/diet_create_screen.dart';
import 'package:eatvio_app/presentation/diets/diet_select_screen/diet_select_screen.dart';
import 'package:eatvio_app/features/blog_post_create/presentation/pages/blog_post_create_screen.dart';
import 'package:eatvio_app/presentation/feed/blog_post_edit_screen/blog_post_edit_screen.dart';
import 'package:eatvio_app/features/blog_post/presentation/pages/blog_post_screen.dart';
import 'package:eatvio_app/features/feed/presentation/pages/feed_screen.dart';
import 'package:eatvio_app/presentation/glossary/glossary_screen/glossary_screen.dart';
import 'package:eatvio_app/presentation/plans/plan_select_screen/plan_select_screen.dart';
import 'package:eatvio_app/presentation/profile/my_profile_screen/my_profile_screen.dart';
import 'package:eatvio_app/presentation/profile/my_profile_screen/my_settings_screen.dart';
import 'package:eatvio_app/presentation/recipe/recipe_select_screen/recipe_select_screen.dart';
import 'package:eatvio_app/presentation/registration/additional_information_screen/additional_information_screen.dart';
import 'package:eatvio_app/presentation/registration/allergies_screen/allergies_screen.dart';
import 'package:eatvio_app/presentation/registration/blood_pressure_screen/blood_pressure_screen.dart';
import 'package:eatvio_app/presentation/registration/body_circumferences_screen/body_circumferences_screen.dart';
import 'package:eatvio_app/presentation/registration/city_of_living_screen/city_of_living_screen.dart';
import 'package:eatvio_app/presentation/registration/credentials_screen/credentials_screen.dart';
import 'package:eatvio_app/presentation/registration/date_of_birth_screen/date_of_birth_screen.dart';
import 'package:eatvio_app/presentation/registration/favorite_foods_screen/favorite_foods_screen.dart';
import 'package:eatvio_app/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart';
import 'package:eatvio_app/presentation/registration/gender_screen/gender_screen.dart';
import 'package:eatvio_app/presentation/registration/height_screen/height_screen.dart';
import 'package:eatvio_app/presentation/registration/language_select_screen/language_select_screen.dart';
import 'package:eatvio_app/presentation/registration/medicine_intake_screen/medicine_intake_screen.dart';
import 'package:eatvio_app/presentation/registration/name_screen/name_screen.dart';
import 'package:eatvio_app/presentation/registration/weight_screen/weight_screen.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/widgets/bottom_navigation_bar_widget.dart';
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:go_router/go_router.dart';
@@ -48,7 +34,6 @@ class AppRouter {
name: 'authScreen',
redirect: (context, state) async {
if (await TokenStorage.haveTokenInStorage()) {
await context.read<InitializationCubit>().runInitialization();
return '/my-profile-screen';
}
return null;
@@ -56,105 +41,9 @@ class AppRouter {
builder: (context, state) => AuthScreen.builder(context),
routes: [
GoRoute(
path: 'language-select-screen',
name: 'languageSelectScreen',
builder: (context, state) => LanguageSelectScreen.builder(context),
routes: [
GoRoute(
path: 'credentials-screen',
name: 'credentialsScreen',
builder: (context, state) => CredentialsScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'name-screen',
name: 'nameScreen',
builder: (context, state) => NameScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'gender-screen',
name: 'genderScreen',
builder: (context, state) => GenderScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'date-of-birth-screen',
name: 'dateOfBirthScreen',
builder: (context, state) => DateOfBirthScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'city-of-living-screen',
name: 'cityOfLivingScreen',
builder: (context, state) => CityOfLivingScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'body-circumferences-screen',
name: 'bodyCircumferencesScreen',
builder: (context, state) => BodyCircumferencesScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'weight-screen',
name: 'weightScreen',
builder: (context, state) => WeightScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'height-screen',
name: 'heightScreen',
builder: (context, state) => HeightScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'blood-pressure-screen',
name: 'bloodPressureScreen',
builder: (context, state) => BloodPressureScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'favorite-sports-screen',
name: 'favoriteSportsScreen',
builder: (context, state) => FavoriteSportsScreen.builder(context, state.extra),
routes: [
GoRoute(
name: 'allergiesScreen',
path: 'allergiesScreen',
builder: (context, state) => AllergiesScreen.builder(context, state.extra),
routes: [
GoRoute(
name: 'medicineIntakeScreen',
path: 'medicine-intake-screen',
builder: (context, state) => MedicineIntakeScreen.builder(context, state.extra),
),
GoRoute(
name: 'favoriteFoodsScreen',
path: 'favorite-foods-screen',
builder: (context, state) => FavoriteFoodsScreen.builder(context, state.extra),
routes: [
GoRoute(
path: 'additional-information-screen',
name: 'additionalInformationScreen',
builder: (context, state) => AdditionalInformationScreen.builder(context, state.extra),
),
],
),
],
),
],
),
],
),
],
),
],
),
],
),
],
),
],
),
],
),
],
),
],
),
],
path: 'registration-screen',
name: 'registrationScreen',
builder: (context, state) => const RegistrationScreen(),
),
],
),
@@ -166,6 +55,10 @@ class AppRouter {
GoRoute(
path: '/my-profile-screen',
name: 'myProfileScreen',
redirect: (context, state) async {
await context.read<InitializationCubit>().runInitialization();
return null;
},
builder: (context, state) => MyProfileScreen(),
),
GoRoute(

View File

@@ -1,6 +1,6 @@
export 'package:flutter_bloc/flutter_bloc.dart';
export 'package:eatvio_app/core/constants/constants.dart';
export 'package:eatvio_app/core/errors/exceptions.dart';
export 'package:eatvio_app/core/utils/date_time_utils.dart';
export 'package:eatvio_app/core/utils/image_constant.dart';
export 'package:eatvio_app/core/utils/logger.dart';
export 'package:eatvio_app/core/utils/pref_utils.dart';
@@ -11,6 +11,7 @@ export 'package:eatvio_app/theme/app_decoration.dart';
export 'package:eatvio_app/theme/custom_text_style.dart';
export 'package:eatvio_app/theme/theme_helper.dart';
export 'package:eatvio_app/widgets/custom_image_view.dart';
export 'package:flutter_bloc/flutter_bloc.dart';
export '../theme/bloc/theme_bloc.dart';
export '../theme/custom_button_style.dart';
export 'package:eatvio_app/core/utils/date_time_utils.dart';

View File

@@ -1 +1 @@
const String baseUrl = 'https://mobile-stage.eatvio.ru';

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:eatvio_app/main.dart';
import 'package:flutter/material.dart';
class ServerException implements Exception {}
@@ -13,8 +13,7 @@ class NoInternetException implements Exception {
NoInternetException([String message = 'NoInternetException Occurred']) {
if (globalMessengerKey.currentState != null) {
globalMessengerKey.currentState!
.showSnackBar(SnackBar(content: Text(message)));
globalMessengerKey.currentState!.showSnackBar(SnackBar(content: Text(message)));
}
this._message = message;
}

View File

@@ -9,6 +9,7 @@ import 'package:eatvio_app/locator_service.dart';
class InitializationCubit extends Cubit<InitializationState> {
final ChatRepository chatRepository;
bool wasInitializated = false;
InitializationCubit({required this.chatRepository}) : super(const InitializationState.loading());
@@ -49,48 +50,51 @@ class InitializationCubit extends Cubit<InitializationState> {
}
Future<void> runInitialization() async {
try {
await TokenStorage.haveTokenInStorage();
final wsUrl = await chatRepository.getWebsocket();
final options = PusherChannelsOptions.fromHost(
scheme: 'wss',
key: wsUrl.key,
host: wsUrl.host,
shouldSupplyMetadataQueries: true,
metadata: PusherChannelsOptionsMetadata.byDefault(),
port: 443,
);
final client = PusherChannelsClient.websocket(
options: options,
connectionErrorHandler: (exception, trace, refresh) {
refresh();
},
minimumReconnectDelayDuration: const Duration(
seconds: 1,
),
defaultActivityDuration: const Duration(
seconds: 120,
),
activityDurationOverride: const Duration(
seconds: 120,
),
waitForPongDuration: const Duration(
seconds: 30,
),
);
await client.connect();
if (!wasInitializated) {
wasInitializated = true;
try {
await TokenStorage.haveTokenInStorage();
final wsUrl = await chatRepository.getWebsocket();
final options = PusherChannelsOptions.fromHost(
scheme: 'wss',
key: wsUrl.key,
host: wsUrl.host,
shouldSupplyMetadataQueries: true,
metadata: PusherChannelsOptionsMetadata.byDefault(),
port: 443,
);
final client = PusherChannelsClient.websocket(
options: options,
connectionErrorHandler: (exception, trace, refresh) {
refresh();
},
minimumReconnectDelayDuration: const Duration(
seconds: 1,
),
defaultActivityDuration: const Duration(
seconds: 120,
),
activityDurationOverride: const Duration(
seconds: 120,
),
waitForPongDuration: const Duration(
seconds: 30,
),
);
await client.connect();
await subscribeNotifications(wsUrl.userId, client);
await subscribeChatMessages(wsUrl.userId, client);
await subscribeNotifications(wsUrl.userId, client);
await subscribeChatMessages(wsUrl.userId, client);
emit(InitializationState.success(
client: client,
));
} catch (e) {
emit(InitializationState.error(
errorMessage: e.toString(),
));
rethrow;
emit(InitializationState.success(
client: client,
));
} catch (e) {
emit(InitializationState.error(
errorMessage: e.toString(),
));
rethrow;
}
}
}
}

View File

@@ -24,15 +24,13 @@ class ImageConstant {
// Блог images
static String imgRectangle14 = '$imagePath/img_rectangle_14.png';
static String imgRectangle14220x341 =
'$imagePath/img_rectangle_14_220x341.png';
static String imgRectangle14220x341 = '$imagePath/img_rectangle_14_220x341.png';
// Блог - Tab Container images
static String imgCrop = '$imagePath/img_crop.svg';
// Статья images
static String imgRectangle14220x375 =
'$imagePath/img_rectangle_14_220x375.png';
static String imgRectangle14220x375 = '$imagePath/img_rectangle_14_220x375.png';
static String imgVector = '$imagePath/img_vector.svg';
@@ -116,13 +114,11 @@ class ImageConstant {
static String imgNavBlueGray400 = '$imagePath/img_nav_blue_gray_400.svg';
static String imgNavBlueGray40024x23 =
'$imagePath/img_nav_blue_gray_400_24x23.svg';
static String imgNavBlueGray40024x23 = '$imagePath/img_nav_blue_gray_400_24x23.svg';
static String imgNavPrimary = '$imagePath/img_nav_primary.svg';
static String imgNavBlueGray40024x25 =
'$imagePath/img_nav_blue_gray_400_24x25.svg';
static String imgNavBlueGray40024x25 = '$imagePath/img_nav_blue_gray_400_24x25.svg';
static String imgEye = '$imagePath/img_eye.svg';
@@ -134,11 +130,9 @@ class ImageConstant {
static String imgEllipse142x42 = '$imagePath/img_ellipse_1_42x42.png';
static String imgIconMoreHorizontal =
'$imagePath/img_icon_more_horizontal.svg';
static String imgIconMoreHorizontal = '$imagePath/img_icon_more_horizontal.svg';
static String imgRectangle14250x311 =
'$imagePath/img_rectangle_14_250x311.png';
static String imgRectangle14250x311 = '$imagePath/img_rectangle_14_250x311.png';
static String imgIconMessageSquare = '$imagePath/img_icon_message_square.svg';

View File

@@ -8,18 +8,19 @@ class ProgressDialogUtils {
static void showProgressDialog({BuildContext? context, isCancellable = false}) async {
if (!isProgressVisible && AppRouter.navigatorKey.currentState?.overlay?.context != null) {
showDialog(
barrierDismissible: isCancellable,
context: AppRouter.navigatorKey.currentState!.overlay!.context,
builder: (BuildContext context) {
return Center(
child: CircularProgressIndicator.adaptive(
strokeWidth: 4,
valueColor: AlwaysStoppedAnimation<Color>(
Colors.white,
),
barrierDismissible: isCancellable,
context: AppRouter.navigatorKey.currentState!.overlay!.context,
builder: (BuildContext context) {
return Center(
child: CircularProgressIndicator.adaptive(
strokeWidth: 4,
valueColor: AlwaysStoppedAnimation<Color>(
Colors.white,
),
);
},);
),
);
},
);
isProgressVisible = true;
}
}

View File

@@ -3,7 +3,8 @@ import 'package:flutter/material.dart';
// This functions are responsible to make UI responsive across all the mobile devices.
MediaQueryData mediaQueryData = MediaQueryData.fromView(
WidgetsBinding.instance.platformDispatcher.views.single,);
WidgetsBinding.instance.platformDispatcher.views.single,
);
// These are the Viewport values of your Figma Design.
// These are used in the code as a reference to create your UI Responsively.
@@ -30,8 +31,7 @@ extension ResponsiveExtension on num {
double get h => ((this * _width) / FIGMA_DESIGN_WIDTH);
///This method is used to set padding/margin (for the top and bottom side) & height of the screen or widget according to the Viewport height.
double get v =>
(this * _height) / (FIGMA_DESIGN_HEIGHT - FIGMA_DESIGN_STATUS_BAR);
double get v => (this * _height) / (FIGMA_DESIGN_HEIGHT - FIGMA_DESIGN_STATUS_BAR);
///This method is used to set smallest px in image height and width
double get adaptSize {

View File

@@ -1,15 +1,13 @@
///SelectionPopupModel is common model
///used for setting data into dropdowns
class SelectionPopupModel {
int? id;
String title;
dynamic value;
bool isSelected;
import 'package:freezed_annotation/freezed_annotation.dart';
SelectionPopupModel({
this.id,
required this.title,
this.value,
this.isSelected = false,
});
part 'selection_popup_model.freezed.dart';
@freezed
class SelectionPopupModel with _$SelectionPopupModel {
const factory SelectionPopupModel({
int? id,
required String title,
dynamic value,
@Default(false) bool isSelected,
}) = _SelectionPopupModel;
}

View File

@@ -0,0 +1,189 @@
// 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 'selection_popup_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(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 _$SelectionPopupModel {
int? get id => throw _privateConstructorUsedError;
String get title => throw _privateConstructorUsedError;
dynamic get value => throw _privateConstructorUsedError;
bool get isSelected => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$SelectionPopupModelCopyWith<SelectionPopupModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $SelectionPopupModelCopyWith<$Res> {
factory $SelectionPopupModelCopyWith(
SelectionPopupModel value, $Res Function(SelectionPopupModel) then) =
_$SelectionPopupModelCopyWithImpl<$Res, SelectionPopupModel>;
@useResult
$Res call({int? id, String title, dynamic value, bool isSelected});
}
/// @nodoc
class _$SelectionPopupModelCopyWithImpl<$Res, $Val extends SelectionPopupModel>
implements $SelectionPopupModelCopyWith<$Res> {
_$SelectionPopupModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = freezed,
Object? title = null,
Object? value = freezed,
Object? isSelected = null,
}) {
return _then(_value.copyWith(
id: freezed == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as int?,
title: null == title
? _value.title
: title // ignore: cast_nullable_to_non_nullable
as String,
value: freezed == value
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as dynamic,
isSelected: null == isSelected
? _value.isSelected
: isSelected // ignore: cast_nullable_to_non_nullable
as bool,
) as $Val);
}
}
/// @nodoc
abstract class _$$SelectionPopupModelImplCopyWith<$Res>
implements $SelectionPopupModelCopyWith<$Res> {
factory _$$SelectionPopupModelImplCopyWith(_$SelectionPopupModelImpl value,
$Res Function(_$SelectionPopupModelImpl) then) =
__$$SelectionPopupModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({int? id, String title, dynamic value, bool isSelected});
}
/// @nodoc
class __$$SelectionPopupModelImplCopyWithImpl<$Res>
extends _$SelectionPopupModelCopyWithImpl<$Res, _$SelectionPopupModelImpl>
implements _$$SelectionPopupModelImplCopyWith<$Res> {
__$$SelectionPopupModelImplCopyWithImpl(_$SelectionPopupModelImpl _value,
$Res Function(_$SelectionPopupModelImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? id = freezed,
Object? title = null,
Object? value = freezed,
Object? isSelected = null,
}) {
return _then(_$SelectionPopupModelImpl(
id: freezed == id
? _value.id
: id // ignore: cast_nullable_to_non_nullable
as int?,
title: null == title
? _value.title
: title // ignore: cast_nullable_to_non_nullable
as String,
value: freezed == value
? _value.value
: value // ignore: cast_nullable_to_non_nullable
as dynamic,
isSelected: null == isSelected
? _value.isSelected
: isSelected // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
/// @nodoc
class _$SelectionPopupModelImpl implements _SelectionPopupModel {
const _$SelectionPopupModelImpl(
{this.id, required this.title, this.value, this.isSelected = false});
@override
final int? id;
@override
final String title;
@override
final dynamic value;
@override
@JsonKey()
final bool isSelected;
@override
String toString() {
return 'SelectionPopupModel(id: $id, title: $title, value: $value, isSelected: $isSelected)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$SelectionPopupModelImpl &&
(identical(other.id, id) || other.id == id) &&
(identical(other.title, title) || other.title == title) &&
const DeepCollectionEquality().equals(other.value, value) &&
(identical(other.isSelected, isSelected) ||
other.isSelected == isSelected));
}
@override
int get hashCode => Object.hash(runtimeType, id, title,
const DeepCollectionEquality().hash(value), isSelected);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$SelectionPopupModelImplCopyWith<_$SelectionPopupModelImpl> get copyWith =>
__$$SelectionPopupModelImplCopyWithImpl<_$SelectionPopupModelImpl>(
this, _$identity);
}
abstract class _SelectionPopupModel implements SelectionPopupModel {
const factory _SelectionPopupModel(
{final int? id,
required final String title,
final dynamic value,
final bool isSelected}) = _$SelectionPopupModelImpl;
@override
int? get id;
@override
String get title;
@override
dynamic get value;
@override
bool get isSelected;
@override
@JsonKey(ignore: true)
_$$SelectionPopupModelImplCopyWith<_$SelectionPopupModelImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -1,4 +1,5 @@
import 'package:hive/hive.dart';
/// https://pub.dev/packages/flutter_secure_storage TODO replace hive to secure_storage for token storage
@HiveType(typeId: 0)
class TokenModel {

View File

@@ -1,92 +1,40 @@
class UserRegistrationSheet {
String name;
String firstName;
String lastName;
String email;
String password;
String passwordConfirmation;
String termsAccepted;
String birthdate;
String gender;
String country;
String city;
String lang;
String weight;
String height;
String chestCircumference;
String waistCircumference;
String hipCircumference;
String bloodPressureUp;
String bloodPressureDown;
String hasHypo = '';
String hasHyper = '';
String aboutAllergy = '';
String aboutTakingPils = '';
String aboutSportHobbies = '';
String favoriteFoods = '';
String unfavoriteFoods = '';
String additionalInfo = '';
import 'package:freezed_annotation/freezed_annotation.dart';
UserRegistrationSheet({
required this.name,
required this.firstName,
required this.lastName,
required this.email,
required this.password,
required this.passwordConfirmation,
required this.termsAccepted,
required this.birthdate,
required this.gender,
required this.country,
required this.city,
required this.lang,
required this.weight,
required this.height,
required this.chestCircumference,
required this.waistCircumference,
required this.hipCircumference,
required this.bloodPressureUp,
required this.bloodPressureDown,
required this.hasHypo,
required this.hasHyper,
required this.aboutAllergy,
required this.aboutTakingPils,
required this.aboutSportHobbies,
required this.favoriteFoods,
required this.unfavoriteFoods,
required this.additionalInfo,
});
part 'user_registration_model.freezed.dart';
part 'user_registration_model.g.dart';
Map<String, dynamic> toJson() {
return {
'name': name,
'first_name': firstName,
'last_name': lastName,
'email': email,
'password': password,
'password_confirmation': passwordConfirmation,
'terms': termsAccepted,
'birthdate': birthdate.toString(),
'gender': gender,
'country': country,
'city': city,
'lang': lang,
'weight': weight,
'height': height,
'chest_circumference': chestCircumference,
'waist_circumference': waistCircumference,
'hip_circumference': hipCircumference,
'blood_pressure_up': bloodPressureUp,
'blood_pressure_down': bloodPressureDown,
'has_hypo': hasHypo,
'has_hyper': hasHyper,
'about_alergy': aboutAllergy,
'about_taking_pils': aboutTakingPils,
'about_sport_hobbies': aboutSportHobbies,
'favorite_foods': favoriteFoods,
'unfavorite_foods': unfavoriteFoods,
'additional_info': additionalInfo,
'activity_coefficient': '1.2',
};
}
@freezed
class UserRegistrationSheet with _$UserRegistrationSheet {
const factory UserRegistrationSheet({
required String name,
@JsonKey(name: 'first_name') required String firstName,
@JsonKey(name: 'last_name') required String lastName,
required String email,
required String password,
@JsonKey(name: 'password_confirmation') required String passwordConfirmation,
@Default('accepted') @JsonKey(name: 'terms') String termsAccepted,
required String birthdate,
required String gender,
required String country,
required String city,
required String lang,
required int weight,
required int height,
@JsonKey(name: 'chest_circumference') required int chestCircumference,
@JsonKey(name: 'waist_circumference') required int waistCircumference,
@JsonKey(name: 'hip_circumference') required int hipCircumference,
@JsonKey(name: 'blood_pressure_up') required int bloodPressureUp,
@JsonKey(name: 'blood_pressure_down') required int bloodPressureDown,
@JsonKey(name: 'has_hypo') required int hasHypo,
@JsonKey(name: 'has_hyper') required int hasHyper,
@JsonKey(name: 'about_alergy') required String aboutAllergy,
@JsonKey(name: 'about_taking_pils') required String aboutTakingPils,
@JsonKey(name: 'about_sport_hobbies') required String aboutSportHobbies,
@JsonKey(name: 'favorite_foods') required String favoriteFoods,
@JsonKey(name: 'unfavorite_foods') required String unfavoriteFoods,
@JsonKey(name: 'additional_info') required String additionalInfo,
@Default(1.2) @JsonKey(name: 'activity_coefficient') double activityCoefficient,
}) = _UserRegistrationSheet;
factory UserRegistrationSheet.fromJson(Map<String, Object?> json) => _$UserRegistrationSheetFromJson(json);
}

View File

@@ -0,0 +1,810 @@
// 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 'user_registration_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(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');
UserRegistrationSheet _$UserRegistrationSheetFromJson(
Map<String, dynamic> json) {
return _UserRegistrationSheet.fromJson(json);
}
/// @nodoc
mixin _$UserRegistrationSheet {
String get name => throw _privateConstructorUsedError;
@JsonKey(name: 'first_name')
String get firstName => throw _privateConstructorUsedError;
@JsonKey(name: 'last_name')
String get lastName => throw _privateConstructorUsedError;
String get email => throw _privateConstructorUsedError;
String get password => throw _privateConstructorUsedError;
@JsonKey(name: 'password_confirmation')
String get passwordConfirmation => throw _privateConstructorUsedError;
@JsonKey(name: 'terms')
String get termsAccepted => throw _privateConstructorUsedError;
String get birthdate => throw _privateConstructorUsedError;
String get gender => throw _privateConstructorUsedError;
String get country => throw _privateConstructorUsedError;
String get city => throw _privateConstructorUsedError;
String get lang => throw _privateConstructorUsedError;
int get weight => throw _privateConstructorUsedError;
int get height => throw _privateConstructorUsedError;
@JsonKey(name: 'chest_circumference')
int get chestCircumference => throw _privateConstructorUsedError;
@JsonKey(name: 'waist_circumference')
int get waistCircumference => throw _privateConstructorUsedError;
@JsonKey(name: 'hip_circumference')
int get hipCircumference => throw _privateConstructorUsedError;
@JsonKey(name: 'blood_pressure_up')
int get bloodPressureUp => throw _privateConstructorUsedError;
@JsonKey(name: 'blood_pressure_down')
int get bloodPressureDown => throw _privateConstructorUsedError;
@JsonKey(name: 'has_hypo')
int get hasHypo => throw _privateConstructorUsedError;
@JsonKey(name: 'has_hyper')
int get hasHyper => throw _privateConstructorUsedError;
@JsonKey(name: 'about_alergy')
String get aboutAllergy => throw _privateConstructorUsedError;
@JsonKey(name: 'about_taking_pils')
String get aboutTakingPils => throw _privateConstructorUsedError;
@JsonKey(name: 'about_sport_hobbies')
String get aboutSportHobbies => throw _privateConstructorUsedError;
@JsonKey(name: 'favorite_foods')
String get favoriteFoods => throw _privateConstructorUsedError;
@JsonKey(name: 'unfavorite_foods')
String get unfavoriteFoods => throw _privateConstructorUsedError;
@JsonKey(name: 'additional_info')
String get additionalInfo => throw _privateConstructorUsedError;
@JsonKey(name: 'activity_coefficient')
double get activityCoefficient => throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$UserRegistrationSheetCopyWith<UserRegistrationSheet> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $UserRegistrationSheetCopyWith<$Res> {
factory $UserRegistrationSheetCopyWith(UserRegistrationSheet value,
$Res Function(UserRegistrationSheet) then) =
_$UserRegistrationSheetCopyWithImpl<$Res, UserRegistrationSheet>;
@useResult
$Res call(
{String name,
@JsonKey(name: 'first_name') String firstName,
@JsonKey(name: 'last_name') String lastName,
String email,
String password,
@JsonKey(name: 'password_confirmation') String passwordConfirmation,
@JsonKey(name: 'terms') String termsAccepted,
String birthdate,
String gender,
String country,
String city,
String lang,
int weight,
int height,
@JsonKey(name: 'chest_circumference') int chestCircumference,
@JsonKey(name: 'waist_circumference') int waistCircumference,
@JsonKey(name: 'hip_circumference') int hipCircumference,
@JsonKey(name: 'blood_pressure_up') int bloodPressureUp,
@JsonKey(name: 'blood_pressure_down') int bloodPressureDown,
@JsonKey(name: 'has_hypo') int hasHypo,
@JsonKey(name: 'has_hyper') int hasHyper,
@JsonKey(name: 'about_alergy') String aboutAllergy,
@JsonKey(name: 'about_taking_pils') String aboutTakingPils,
@JsonKey(name: 'about_sport_hobbies') String aboutSportHobbies,
@JsonKey(name: 'favorite_foods') String favoriteFoods,
@JsonKey(name: 'unfavorite_foods') String unfavoriteFoods,
@JsonKey(name: 'additional_info') String additionalInfo,
@JsonKey(name: 'activity_coefficient') double activityCoefficient});
}
/// @nodoc
class _$UserRegistrationSheetCopyWithImpl<$Res,
$Val extends UserRegistrationSheet>
implements $UserRegistrationSheetCopyWith<$Res> {
_$UserRegistrationSheetCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? name = null,
Object? firstName = null,
Object? lastName = null,
Object? email = null,
Object? password = null,
Object? passwordConfirmation = null,
Object? termsAccepted = null,
Object? birthdate = null,
Object? gender = null,
Object? country = null,
Object? city = null,
Object? lang = null,
Object? weight = null,
Object? height = null,
Object? chestCircumference = null,
Object? waistCircumference = null,
Object? hipCircumference = null,
Object? bloodPressureUp = null,
Object? bloodPressureDown = null,
Object? hasHypo = null,
Object? hasHyper = null,
Object? aboutAllergy = null,
Object? aboutTakingPils = null,
Object? aboutSportHobbies = null,
Object? favoriteFoods = null,
Object? unfavoriteFoods = null,
Object? additionalInfo = null,
Object? activityCoefficient = null,
}) {
return _then(_value.copyWith(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
firstName: null == firstName
? _value.firstName
: firstName // ignore: cast_nullable_to_non_nullable
as String,
lastName: null == lastName
? _value.lastName
: lastName // ignore: cast_nullable_to_non_nullable
as String,
email: null == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String,
password: null == password
? _value.password
: password // ignore: cast_nullable_to_non_nullable
as String,
passwordConfirmation: null == passwordConfirmation
? _value.passwordConfirmation
: passwordConfirmation // ignore: cast_nullable_to_non_nullable
as String,
termsAccepted: null == termsAccepted
? _value.termsAccepted
: termsAccepted // ignore: cast_nullable_to_non_nullable
as String,
birthdate: null == birthdate
? _value.birthdate
: birthdate // ignore: cast_nullable_to_non_nullable
as String,
gender: null == gender
? _value.gender
: gender // ignore: cast_nullable_to_non_nullable
as String,
country: null == country
? _value.country
: country // ignore: cast_nullable_to_non_nullable
as String,
city: null == city
? _value.city
: city // ignore: cast_nullable_to_non_nullable
as String,
lang: null == lang
? _value.lang
: lang // ignore: cast_nullable_to_non_nullable
as String,
weight: null == weight
? _value.weight
: weight // ignore: cast_nullable_to_non_nullable
as int,
height: null == height
? _value.height
: height // ignore: cast_nullable_to_non_nullable
as int,
chestCircumference: null == chestCircumference
? _value.chestCircumference
: chestCircumference // ignore: cast_nullable_to_non_nullable
as int,
waistCircumference: null == waistCircumference
? _value.waistCircumference
: waistCircumference // ignore: cast_nullable_to_non_nullable
as int,
hipCircumference: null == hipCircumference
? _value.hipCircumference
: hipCircumference // ignore: cast_nullable_to_non_nullable
as int,
bloodPressureUp: null == bloodPressureUp
? _value.bloodPressureUp
: bloodPressureUp // ignore: cast_nullable_to_non_nullable
as int,
bloodPressureDown: null == bloodPressureDown
? _value.bloodPressureDown
: bloodPressureDown // ignore: cast_nullable_to_non_nullable
as int,
hasHypo: null == hasHypo
? _value.hasHypo
: hasHypo // ignore: cast_nullable_to_non_nullable
as int,
hasHyper: null == hasHyper
? _value.hasHyper
: hasHyper // ignore: cast_nullable_to_non_nullable
as int,
aboutAllergy: null == aboutAllergy
? _value.aboutAllergy
: aboutAllergy // ignore: cast_nullable_to_non_nullable
as String,
aboutTakingPils: null == aboutTakingPils
? _value.aboutTakingPils
: aboutTakingPils // ignore: cast_nullable_to_non_nullable
as String,
aboutSportHobbies: null == aboutSportHobbies
? _value.aboutSportHobbies
: aboutSportHobbies // ignore: cast_nullable_to_non_nullable
as String,
favoriteFoods: null == favoriteFoods
? _value.favoriteFoods
: favoriteFoods // ignore: cast_nullable_to_non_nullable
as String,
unfavoriteFoods: null == unfavoriteFoods
? _value.unfavoriteFoods
: unfavoriteFoods // ignore: cast_nullable_to_non_nullable
as String,
additionalInfo: null == additionalInfo
? _value.additionalInfo
: additionalInfo // ignore: cast_nullable_to_non_nullable
as String,
activityCoefficient: null == activityCoefficient
? _value.activityCoefficient
: activityCoefficient // ignore: cast_nullable_to_non_nullable
as double,
) as $Val);
}
}
/// @nodoc
abstract class _$$UserRegistrationSheetImplCopyWith<$Res>
implements $UserRegistrationSheetCopyWith<$Res> {
factory _$$UserRegistrationSheetImplCopyWith(
_$UserRegistrationSheetImpl value,
$Res Function(_$UserRegistrationSheetImpl) then) =
__$$UserRegistrationSheetImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{String name,
@JsonKey(name: 'first_name') String firstName,
@JsonKey(name: 'last_name') String lastName,
String email,
String password,
@JsonKey(name: 'password_confirmation') String passwordConfirmation,
@JsonKey(name: 'terms') String termsAccepted,
String birthdate,
String gender,
String country,
String city,
String lang,
int weight,
int height,
@JsonKey(name: 'chest_circumference') int chestCircumference,
@JsonKey(name: 'waist_circumference') int waistCircumference,
@JsonKey(name: 'hip_circumference') int hipCircumference,
@JsonKey(name: 'blood_pressure_up') int bloodPressureUp,
@JsonKey(name: 'blood_pressure_down') int bloodPressureDown,
@JsonKey(name: 'has_hypo') int hasHypo,
@JsonKey(name: 'has_hyper') int hasHyper,
@JsonKey(name: 'about_alergy') String aboutAllergy,
@JsonKey(name: 'about_taking_pils') String aboutTakingPils,
@JsonKey(name: 'about_sport_hobbies') String aboutSportHobbies,
@JsonKey(name: 'favorite_foods') String favoriteFoods,
@JsonKey(name: 'unfavorite_foods') String unfavoriteFoods,
@JsonKey(name: 'additional_info') String additionalInfo,
@JsonKey(name: 'activity_coefficient') double activityCoefficient});
}
/// @nodoc
class __$$UserRegistrationSheetImplCopyWithImpl<$Res>
extends _$UserRegistrationSheetCopyWithImpl<$Res,
_$UserRegistrationSheetImpl>
implements _$$UserRegistrationSheetImplCopyWith<$Res> {
__$$UserRegistrationSheetImplCopyWithImpl(_$UserRegistrationSheetImpl _value,
$Res Function(_$UserRegistrationSheetImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? name = null,
Object? firstName = null,
Object? lastName = null,
Object? email = null,
Object? password = null,
Object? passwordConfirmation = null,
Object? termsAccepted = null,
Object? birthdate = null,
Object? gender = null,
Object? country = null,
Object? city = null,
Object? lang = null,
Object? weight = null,
Object? height = null,
Object? chestCircumference = null,
Object? waistCircumference = null,
Object? hipCircumference = null,
Object? bloodPressureUp = null,
Object? bloodPressureDown = null,
Object? hasHypo = null,
Object? hasHyper = null,
Object? aboutAllergy = null,
Object? aboutTakingPils = null,
Object? aboutSportHobbies = null,
Object? favoriteFoods = null,
Object? unfavoriteFoods = null,
Object? additionalInfo = null,
Object? activityCoefficient = null,
}) {
return _then(_$UserRegistrationSheetImpl(
name: null == name
? _value.name
: name // ignore: cast_nullable_to_non_nullable
as String,
firstName: null == firstName
? _value.firstName
: firstName // ignore: cast_nullable_to_non_nullable
as String,
lastName: null == lastName
? _value.lastName
: lastName // ignore: cast_nullable_to_non_nullable
as String,
email: null == email
? _value.email
: email // ignore: cast_nullable_to_non_nullable
as String,
password: null == password
? _value.password
: password // ignore: cast_nullable_to_non_nullable
as String,
passwordConfirmation: null == passwordConfirmation
? _value.passwordConfirmation
: passwordConfirmation // ignore: cast_nullable_to_non_nullable
as String,
termsAccepted: null == termsAccepted
? _value.termsAccepted
: termsAccepted // ignore: cast_nullable_to_non_nullable
as String,
birthdate: null == birthdate
? _value.birthdate
: birthdate // ignore: cast_nullable_to_non_nullable
as String,
gender: null == gender
? _value.gender
: gender // ignore: cast_nullable_to_non_nullable
as String,
country: null == country
? _value.country
: country // ignore: cast_nullable_to_non_nullable
as String,
city: null == city
? _value.city
: city // ignore: cast_nullable_to_non_nullable
as String,
lang: null == lang
? _value.lang
: lang // ignore: cast_nullable_to_non_nullable
as String,
weight: null == weight
? _value.weight
: weight // ignore: cast_nullable_to_non_nullable
as int,
height: null == height
? _value.height
: height // ignore: cast_nullable_to_non_nullable
as int,
chestCircumference: null == chestCircumference
? _value.chestCircumference
: chestCircumference // ignore: cast_nullable_to_non_nullable
as int,
waistCircumference: null == waistCircumference
? _value.waistCircumference
: waistCircumference // ignore: cast_nullable_to_non_nullable
as int,
hipCircumference: null == hipCircumference
? _value.hipCircumference
: hipCircumference // ignore: cast_nullable_to_non_nullable
as int,
bloodPressureUp: null == bloodPressureUp
? _value.bloodPressureUp
: bloodPressureUp // ignore: cast_nullable_to_non_nullable
as int,
bloodPressureDown: null == bloodPressureDown
? _value.bloodPressureDown
: bloodPressureDown // ignore: cast_nullable_to_non_nullable
as int,
hasHypo: null == hasHypo
? _value.hasHypo
: hasHypo // ignore: cast_nullable_to_non_nullable
as int,
hasHyper: null == hasHyper
? _value.hasHyper
: hasHyper // ignore: cast_nullable_to_non_nullable
as int,
aboutAllergy: null == aboutAllergy
? _value.aboutAllergy
: aboutAllergy // ignore: cast_nullable_to_non_nullable
as String,
aboutTakingPils: null == aboutTakingPils
? _value.aboutTakingPils
: aboutTakingPils // ignore: cast_nullable_to_non_nullable
as String,
aboutSportHobbies: null == aboutSportHobbies
? _value.aboutSportHobbies
: aboutSportHobbies // ignore: cast_nullable_to_non_nullable
as String,
favoriteFoods: null == favoriteFoods
? _value.favoriteFoods
: favoriteFoods // ignore: cast_nullable_to_non_nullable
as String,
unfavoriteFoods: null == unfavoriteFoods
? _value.unfavoriteFoods
: unfavoriteFoods // ignore: cast_nullable_to_non_nullable
as String,
additionalInfo: null == additionalInfo
? _value.additionalInfo
: additionalInfo // ignore: cast_nullable_to_non_nullable
as String,
activityCoefficient: null == activityCoefficient
? _value.activityCoefficient
: activityCoefficient // ignore: cast_nullable_to_non_nullable
as double,
));
}
}
/// @nodoc
@JsonSerializable()
class _$UserRegistrationSheetImpl implements _UserRegistrationSheet {
const _$UserRegistrationSheetImpl(
{required this.name,
@JsonKey(name: 'first_name') required this.firstName,
@JsonKey(name: 'last_name') required this.lastName,
required this.email,
required this.password,
@JsonKey(name: 'password_confirmation')
required this.passwordConfirmation,
@JsonKey(name: 'terms') this.termsAccepted = 'accepted',
required this.birthdate,
required this.gender,
required this.country,
required this.city,
required this.lang,
required this.weight,
required this.height,
@JsonKey(name: 'chest_circumference') required this.chestCircumference,
@JsonKey(name: 'waist_circumference') required this.waistCircumference,
@JsonKey(name: 'hip_circumference') required this.hipCircumference,
@JsonKey(name: 'blood_pressure_up') required this.bloodPressureUp,
@JsonKey(name: 'blood_pressure_down') required this.bloodPressureDown,
@JsonKey(name: 'has_hypo') required this.hasHypo,
@JsonKey(name: 'has_hyper') required this.hasHyper,
@JsonKey(name: 'about_alergy') required this.aboutAllergy,
@JsonKey(name: 'about_taking_pils') required this.aboutTakingPils,
@JsonKey(name: 'about_sport_hobbies') required this.aboutSportHobbies,
@JsonKey(name: 'favorite_foods') required this.favoriteFoods,
@JsonKey(name: 'unfavorite_foods') required this.unfavoriteFoods,
@JsonKey(name: 'additional_info') required this.additionalInfo,
@JsonKey(name: 'activity_coefficient') this.activityCoefficient = 1.2});
factory _$UserRegistrationSheetImpl.fromJson(Map<String, dynamic> json) =>
_$$UserRegistrationSheetImplFromJson(json);
@override
final String name;
@override
@JsonKey(name: 'first_name')
final String firstName;
@override
@JsonKey(name: 'last_name')
final String lastName;
@override
final String email;
@override
final String password;
@override
@JsonKey(name: 'password_confirmation')
final String passwordConfirmation;
@override
@JsonKey(name: 'terms')
final String termsAccepted;
@override
final String birthdate;
@override
final String gender;
@override
final String country;
@override
final String city;
@override
final String lang;
@override
final int weight;
@override
final int height;
@override
@JsonKey(name: 'chest_circumference')
final int chestCircumference;
@override
@JsonKey(name: 'waist_circumference')
final int waistCircumference;
@override
@JsonKey(name: 'hip_circumference')
final int hipCircumference;
@override
@JsonKey(name: 'blood_pressure_up')
final int bloodPressureUp;
@override
@JsonKey(name: 'blood_pressure_down')
final int bloodPressureDown;
@override
@JsonKey(name: 'has_hypo')
final int hasHypo;
@override
@JsonKey(name: 'has_hyper')
final int hasHyper;
@override
@JsonKey(name: 'about_alergy')
final String aboutAllergy;
@override
@JsonKey(name: 'about_taking_pils')
final String aboutTakingPils;
@override
@JsonKey(name: 'about_sport_hobbies')
final String aboutSportHobbies;
@override
@JsonKey(name: 'favorite_foods')
final String favoriteFoods;
@override
@JsonKey(name: 'unfavorite_foods')
final String unfavoriteFoods;
@override
@JsonKey(name: 'additional_info')
final String additionalInfo;
@override
@JsonKey(name: 'activity_coefficient')
final double activityCoefficient;
@override
String toString() {
return 'UserRegistrationSheet(name: $name, firstName: $firstName, lastName: $lastName, email: $email, password: $password, passwordConfirmation: $passwordConfirmation, termsAccepted: $termsAccepted, birthdate: $birthdate, gender: $gender, country: $country, city: $city, lang: $lang, weight: $weight, height: $height, chestCircumference: $chestCircumference, waistCircumference: $waistCircumference, hipCircumference: $hipCircumference, bloodPressureUp: $bloodPressureUp, bloodPressureDown: $bloodPressureDown, hasHypo: $hasHypo, hasHyper: $hasHyper, aboutAllergy: $aboutAllergy, aboutTakingPils: $aboutTakingPils, aboutSportHobbies: $aboutSportHobbies, favoriteFoods: $favoriteFoods, unfavoriteFoods: $unfavoriteFoods, additionalInfo: $additionalInfo, activityCoefficient: $activityCoefficient)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$UserRegistrationSheetImpl &&
(identical(other.name, name) || other.name == name) &&
(identical(other.firstName, firstName) ||
other.firstName == firstName) &&
(identical(other.lastName, lastName) ||
other.lastName == lastName) &&
(identical(other.email, email) || other.email == email) &&
(identical(other.password, password) ||
other.password == password) &&
(identical(other.passwordConfirmation, passwordConfirmation) ||
other.passwordConfirmation == passwordConfirmation) &&
(identical(other.termsAccepted, termsAccepted) ||
other.termsAccepted == termsAccepted) &&
(identical(other.birthdate, birthdate) ||
other.birthdate == birthdate) &&
(identical(other.gender, gender) || other.gender == gender) &&
(identical(other.country, country) || other.country == country) &&
(identical(other.city, city) || other.city == city) &&
(identical(other.lang, lang) || other.lang == lang) &&
(identical(other.weight, weight) || other.weight == weight) &&
(identical(other.height, height) || other.height == height) &&
(identical(other.chestCircumference, chestCircumference) ||
other.chestCircumference == chestCircumference) &&
(identical(other.waistCircumference, waistCircumference) ||
other.waistCircumference == waistCircumference) &&
(identical(other.hipCircumference, hipCircumference) ||
other.hipCircumference == hipCircumference) &&
(identical(other.bloodPressureUp, bloodPressureUp) ||
other.bloodPressureUp == bloodPressureUp) &&
(identical(other.bloodPressureDown, bloodPressureDown) ||
other.bloodPressureDown == bloodPressureDown) &&
(identical(other.hasHypo, hasHypo) || other.hasHypo == hasHypo) &&
(identical(other.hasHyper, hasHyper) ||
other.hasHyper == hasHyper) &&
(identical(other.aboutAllergy, aboutAllergy) ||
other.aboutAllergy == aboutAllergy) &&
(identical(other.aboutTakingPils, aboutTakingPils) ||
other.aboutTakingPils == aboutTakingPils) &&
(identical(other.aboutSportHobbies, aboutSportHobbies) ||
other.aboutSportHobbies == aboutSportHobbies) &&
(identical(other.favoriteFoods, favoriteFoods) ||
other.favoriteFoods == favoriteFoods) &&
(identical(other.unfavoriteFoods, unfavoriteFoods) ||
other.unfavoriteFoods == unfavoriteFoods) &&
(identical(other.additionalInfo, additionalInfo) ||
other.additionalInfo == additionalInfo) &&
(identical(other.activityCoefficient, activityCoefficient) ||
other.activityCoefficient == activityCoefficient));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hashAll([
runtimeType,
name,
firstName,
lastName,
email,
password,
passwordConfirmation,
termsAccepted,
birthdate,
gender,
country,
city,
lang,
weight,
height,
chestCircumference,
waistCircumference,
hipCircumference,
bloodPressureUp,
bloodPressureDown,
hasHypo,
hasHyper,
aboutAllergy,
aboutTakingPils,
aboutSportHobbies,
favoriteFoods,
unfavoriteFoods,
additionalInfo,
activityCoefficient
]);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$UserRegistrationSheetImplCopyWith<_$UserRegistrationSheetImpl>
get copyWith => __$$UserRegistrationSheetImplCopyWithImpl<
_$UserRegistrationSheetImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$UserRegistrationSheetImplToJson(
this,
);
}
}
abstract class _UserRegistrationSheet implements UserRegistrationSheet {
const factory _UserRegistrationSheet(
{required final String name,
@JsonKey(name: 'first_name') required final String firstName,
@JsonKey(name: 'last_name') required final String lastName,
required final String email,
required final String password,
@JsonKey(name: 'password_confirmation')
required final String passwordConfirmation,
@JsonKey(name: 'terms') final String termsAccepted,
required final String birthdate,
required final String gender,
required final String country,
required final String city,
required final String lang,
required final int weight,
required final int height,
@JsonKey(name: 'chest_circumference')
required final int chestCircumference,
@JsonKey(name: 'waist_circumference')
required final int waistCircumference,
@JsonKey(name: 'hip_circumference') required final int hipCircumference,
@JsonKey(name: 'blood_pressure_up') required final int bloodPressureUp,
@JsonKey(name: 'blood_pressure_down')
required final int bloodPressureDown,
@JsonKey(name: 'has_hypo') required final int hasHypo,
@JsonKey(name: 'has_hyper') required final int hasHyper,
@JsonKey(name: 'about_alergy') required final String aboutAllergy,
@JsonKey(name: 'about_taking_pils') required final String aboutTakingPils,
@JsonKey(name: 'about_sport_hobbies')
required final String aboutSportHobbies,
@JsonKey(name: 'favorite_foods') required final String favoriteFoods,
@JsonKey(name: 'unfavorite_foods') required final String unfavoriteFoods,
@JsonKey(name: 'additional_info') required final String additionalInfo,
@JsonKey(name: 'activity_coefficient')
final double activityCoefficient}) = _$UserRegistrationSheetImpl;
factory _UserRegistrationSheet.fromJson(Map<String, dynamic> json) =
_$UserRegistrationSheetImpl.fromJson;
@override
String get name;
@override
@JsonKey(name: 'first_name')
String get firstName;
@override
@JsonKey(name: 'last_name')
String get lastName;
@override
String get email;
@override
String get password;
@override
@JsonKey(name: 'password_confirmation')
String get passwordConfirmation;
@override
@JsonKey(name: 'terms')
String get termsAccepted;
@override
String get birthdate;
@override
String get gender;
@override
String get country;
@override
String get city;
@override
String get lang;
@override
int get weight;
@override
int get height;
@override
@JsonKey(name: 'chest_circumference')
int get chestCircumference;
@override
@JsonKey(name: 'waist_circumference')
int get waistCircumference;
@override
@JsonKey(name: 'hip_circumference')
int get hipCircumference;
@override
@JsonKey(name: 'blood_pressure_up')
int get bloodPressureUp;
@override
@JsonKey(name: 'blood_pressure_down')
int get bloodPressureDown;
@override
@JsonKey(name: 'has_hypo')
int get hasHypo;
@override
@JsonKey(name: 'has_hyper')
int get hasHyper;
@override
@JsonKey(name: 'about_alergy')
String get aboutAllergy;
@override
@JsonKey(name: 'about_taking_pils')
String get aboutTakingPils;
@override
@JsonKey(name: 'about_sport_hobbies')
String get aboutSportHobbies;
@override
@JsonKey(name: 'favorite_foods')
String get favoriteFoods;
@override
@JsonKey(name: 'unfavorite_foods')
String get unfavoriteFoods;
@override
@JsonKey(name: 'additional_info')
String get additionalInfo;
@override
@JsonKey(name: 'activity_coefficient')
double get activityCoefficient;
@override
@JsonKey(ignore: true)
_$$UserRegistrationSheetImplCopyWith<_$UserRegistrationSheetImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,74 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'user_registration_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$UserRegistrationSheetImpl _$$UserRegistrationSheetImplFromJson(
Map<String, dynamic> json) =>
_$UserRegistrationSheetImpl(
name: json['name'] as String,
firstName: json['first_name'] as String,
lastName: json['last_name'] as String,
email: json['email'] as String,
password: json['password'] as String,
passwordConfirmation: json['password_confirmation'] as String,
termsAccepted: json['terms'] as String? ?? 'accepted',
birthdate: json['birthdate'] as String,
gender: json['gender'] as String,
country: json['country'] as String,
city: json['city'] as String,
lang: json['lang'] as String,
weight: (json['weight'] as num).toInt(),
height: (json['height'] as num).toInt(),
chestCircumference: (json['chest_circumference'] as num).toInt(),
waistCircumference: (json['waist_circumference'] as num).toInt(),
hipCircumference: (json['hip_circumference'] as num).toInt(),
bloodPressureUp: (json['blood_pressure_up'] as num).toInt(),
bloodPressureDown: (json['blood_pressure_down'] as num).toInt(),
hasHypo: (json['has_hypo'] as num).toInt(),
hasHyper: (json['has_hyper'] as num).toInt(),
aboutAllergy: json['about_alergy'] as String,
aboutTakingPils: json['about_taking_pils'] as String,
aboutSportHobbies: json['about_sport_hobbies'] as String,
favoriteFoods: json['favorite_foods'] as String,
unfavoriteFoods: json['unfavorite_foods'] as String,
additionalInfo: json['additional_info'] as String,
activityCoefficient:
(json['activity_coefficient'] as num?)?.toDouble() ?? 1.2,
);
Map<String, dynamic> _$$UserRegistrationSheetImplToJson(
_$UserRegistrationSheetImpl instance) =>
<String, dynamic>{
'name': instance.name,
'first_name': instance.firstName,
'last_name': instance.lastName,
'email': instance.email,
'password': instance.password,
'password_confirmation': instance.passwordConfirmation,
'terms': instance.termsAccepted,
'birthdate': instance.birthdate,
'gender': instance.gender,
'country': instance.country,
'city': instance.city,
'lang': instance.lang,
'weight': instance.weight,
'height': instance.height,
'chest_circumference': instance.chestCircumference,
'waist_circumference': instance.waistCircumference,
'hip_circumference': instance.hipCircumference,
'blood_pressure_up': instance.bloodPressureUp,
'blood_pressure_down': instance.bloodPressureDown,
'has_hypo': instance.hasHypo,
'has_hyper': instance.hasHyper,
'about_alergy': instance.aboutAllergy,
'about_taking_pils': instance.aboutTakingPils,
'about_sport_hobbies': instance.aboutSportHobbies,
'favorite_foods': instance.favoriteFoods,
'unfavorite_foods': instance.unfavoriteFoods,
'additional_info': instance.additionalInfo,
'activity_coefficient': instance.activityCoefficient,
};

View File

@@ -18,6 +18,5 @@ class BlogPostModel with _$BlogPostModel {
required String title,
}) = _BlogPostModel;
factory BlogPostModel.fromJson(Map<String, Object?> json) =>
_$BlogPostModelFromJson(json);
factory BlogPostModel.fromJson(Map<String, Object?> json) => _$BlogPostModelFromJson(json);
}

View File

@@ -5,8 +5,7 @@ import 'package:eatvio_app/features/blog_post/repositories/blog_post_repository.
class BlogPostCubit extends Cubit<BlogPostState> {
final BlogPostRepository blogPostRepository;
BlogPostCubit({required this.blogPostRepository})
: super(const BlogPostState.loading());
BlogPostCubit({required this.blogPostRepository}) : super(const BlogPostState.loading());
loadBlogPost(String blogPostID) async {
emit(const BlogPostState.loading());

View File

@@ -1,15 +1,14 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/features/blog_post/presentation/bloc/blog_post_cubit.dart';
import 'package:eatvio_app/features/blog_post/presentation/bloc/blog_post_state.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter/cupertino.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
class BlogPostScreen extends StatelessWidget {
final String blogPostID;
@@ -97,8 +96,7 @@ class BlogPostScreen extends StatelessWidget {
),
),
CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! +
(state.blogPost.author_avatar_path ?? ''),
imageUrl: baseUrl + '/storage/' + (state.blogPost.author_avatar_path ?? ''),
imageBuilder: (context, imageProvider) => CircleAvatar(
backgroundImage: imageProvider,
radius: 25,
@@ -221,7 +219,7 @@ class BlogPostScreen extends StatelessWidget {
_buildImage(BlogPostStateLoaded state) {
return CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! + (state.blogPost.image ?? ""),
imageUrl: baseUrl + '/storage/' + (state.blogPost.image ?? ""),
imageBuilder: (context, imageProvider) => Stack(
children: [
ClipRRect(

View File

@@ -8,6 +8,6 @@ part 'blog_post_service.g.dart';
abstract class BlogPostService {
factory BlogPostService(Dio dio, {String baseUrl}) = _BlogPostService;
@GET('/feed/show/{id}')
@GET('/api/feed/show/{id}')
Future<BlogPostModel> getBlogPost(@Path() String id);
}

View File

@@ -32,7 +32,7 @@ class _BlogPostService implements BlogPostService {
)
.compose(
_dio.options,
'/feed/show/${id}',
'/api/feed/show/${id}',
queryParameters: queryParameters,
data: _data,
)

View File

@@ -1,4 +1,5 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part '../../../presentation/feed/blog_post_create_screen/models/blog_post_create_credentials_model.freezed.dart';
part '../../../presentation/feed/blog_post_create_screen/models/blog_post_create_credentials_model.g.dart';

View File

@@ -1,11 +1,13 @@
import '../../../../presentation/feed/blog_post_create_screen/bloc/blog_post_create_bloc.dart';
import '../../../../presentation/feed/blog_post_create_screen/models/blog_post_create_model.dart';
import 'dart:io';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'dart:io';
import '../../../../presentation/feed/blog_post_create_screen/bloc/blog_post_create_bloc.dart';
import '../../../../presentation/feed/blog_post_create_screen/models/blog_post_create_model.dart';
class BlogPostCreateScreen extends StatelessWidget {
const BlogPostCreateScreen({Key? key}) : super(key: key);
@@ -13,9 +15,7 @@ class BlogPostCreateScreen extends StatelessWidget {
static Widget builder(BuildContext context) {
final blog_postID = ModalRoute.of(context)!.settings.arguments;
return BlocProvider<BlogPostCreateBloc>(
create: (context) => BlogPostCreateBloc(BlogPostCreateState(
blog_postModelObj:
BlogPostCreateModel(blog_postID: blog_postID.toString())))
create: (context) => BlogPostCreateBloc(BlogPostCreateState(blog_postModelObj: BlogPostCreateModel(blog_postID: blog_postID.toString())))
..add(BlogPostCreateInitialEvent()),
child: BlogPostCreateScreen(),
);
@@ -77,15 +77,13 @@ class BlogPostCreateScreen extends StatelessWidget {
children: [
Column(
children: <Widget>[
Text("Заголовок новости",
style: theme.textTheme.bodyLarge),
Text("Заголовок новости", style: theme.textTheme.bodyLarge),
CustomTextFormField(
controller: state.title,
validator: _validateTitle,
),
SizedBox(height: 8.0),
Text("Ссылка на YouTube",
style: theme.textTheme.bodyLarge),
Text("Ссылка на YouTube", style: theme.textTheme.bodyLarge),
CustomTextFormField(
controller: state.youtubeURL,
validator: _validateYouTubeLink,
@@ -102,8 +100,7 @@ class BlogPostCreateScreen extends StatelessWidget {
SizedBox(height: 16.0),
// Add widget for image upload here
CustomOutlinedButton(
onPressed: () => _submitForm(context, state.title!.text,
state.description!.text, state.youtubeURL!.text),
onPressed: () => _submitForm(context, state.title!.text, state.description!.text, state.youtubeURL!.text),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
text: 'Создать',
),
@@ -119,20 +116,16 @@ class BlogPostCreateScreen extends StatelessWidget {
}
}
_submitForm(
BuildContext context, String title, String description, String youtubeURL) {
_submitForm(BuildContext context, String title, String description, String youtubeURL) {
String? titleError = _validateTitle(title);
String? descriptionError = _validateDescription(description);
String? youtubeURLError = _validateYouTubeLink(youtubeURL);
if (titleError != null ||
descriptionError != null ||
youtubeURLError != null) {
if (titleError != null || descriptionError != null || youtubeURLError != null) {
// Display error messages or handle invalid input as needed
// For example, show a snackbar with the error message
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(titleError ?? descriptionError ?? youtubeURLError!)),
SnackBar(content: Text(titleError ?? descriptionError ?? youtubeURLError!)),
);
} else {
// Proceed with form submission
@@ -233,7 +226,6 @@ String? _validateYouTubeLink(value) {
}
bool _isValidUrl(String url) {
final RegExp urlRegExp =
new RegExp(r"^(http|https):\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$");
final RegExp urlRegExp = new RegExp(r"^(http|https):\/\/([\w-]+\.)+[\w-]+(\/[\w-./?%&=]*)?$");
return urlRegExp.hasMatch(url);
}

View File

@@ -8,8 +8,7 @@ class BlogRepository {
required this.blogService,
});
Future<BlogPostCreateCredentialsModel> createBlogPost(
BlogPostCreateCredentialsModel model) async {
Future<BlogPostCreateCredentialsModel> createBlogPost(BlogPostCreateCredentialsModel model) async {
try {
return (await blogService.createBlogPost(model));
} catch (e) {

View File

@@ -1,5 +1,5 @@
import 'package:eatvio_app/features/blog_post_create/models/blog_post_create_credentials_model.dart';
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/blog_post_create/models/blog_post_create_credentials_model.dart';
import 'package:retrofit/retrofit.dart';
part 'blog_service.g.dart';
@@ -8,7 +8,6 @@ part 'blog_service.g.dart';
abstract class BlogService {
factory BlogService(Dio dio, {String baseUrl}) = _BlogService;
@POST('/blog_post/create')
Future<BlogPostCreateCredentialsModel> createBlogPost(
BlogPostCreateCredentialsModel model);
@POST('/api/blog_post/create')
Future<BlogPostCreateCredentialsModel> createBlogPost(BlogPostCreateCredentialsModel model);
}

View File

@@ -33,7 +33,7 @@ class _BlogService implements BlogService {
)
.compose(
_dio.options,
'/blog_post/create',
'/api/blog_post/create',
queryParameters: queryParameters,
data: _data,
)

View File

@@ -1,13 +1,13 @@
import 'package:badges/badges.dart' as badges;
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_cubit.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_state.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_cubit.dart';
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_state.dart';
import 'package:flutter/material.dart';
import 'package:eatvio_app/widgets/custom_navigation_menu.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:go_router/go_router.dart';
import 'package:badges/badges.dart' as badges;
int currentBottomNavBarIndex = 0;

View File

@@ -1,7 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_message_model.freezed.dart';
part 'chat_message_model.g.dart';
@freezed

View File

@@ -3,7 +3,6 @@ import 'package:eatvio_app/features/chat/models/chat_meta_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_messages_model.freezed.dart';
part 'chat_messages_model.g.dart';
@freezed

View File

@@ -1,7 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_meta_model.freezed.dart';
part 'chat_meta_model.g.dart';
@freezed

View File

@@ -3,7 +3,6 @@ import 'package:eatvio_app/features/chat/models/chat_user_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_room_model.freezed.dart';
part 'chat_room_model.g.dart';
@freezed

View File

@@ -1,7 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_room_settings_model.freezed.dart';
part 'chat_room_settings_model.g.dart';
@freezed

View File

@@ -1,7 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'chat_user_model.freezed.dart';
part 'chat_user_model.g.dart';
@freezed
@@ -9,10 +8,8 @@ class ChatUserModel with _$ChatUserModel {
const factory ChatUserModel({
required int id,
required String name,
@JsonKey(name: 'profile_photo_path')
String? profilePhotoPath,
@JsonKey(name: 'profile_photo_url')
String? profilePhotoUrl,
@JsonKey(name: 'profile_photo_path') String? profilePhotoPath,
@JsonKey(name: 'profile_photo_url') String? profilePhotoUrl,
}) = _ChatUserModel;
factory ChatUserModel.fromJson(Map<String, Object?> json) => _$ChatUserModelFromJson(json);

View File

@@ -1,7 +1,6 @@
import 'package:freezed_annotation/freezed_annotation.dart';
part 'websocket_info_model.freezed.dart';
part 'websocket_info_model.g.dart';
@freezed
@@ -11,8 +10,7 @@ class WebsocketInfoModel with _$WebsocketInfoModel {
required String host,
required String port,
required String cluster,
@JsonKey(name: 'user_id')
required int userId,
@JsonKey(name: 'user_id') required int userId,
}) = _WebsocketInfoModel;
factory WebsocketInfoModel.fromJson(Map<String, Object?> json) => _$WebsocketInfoModelFromJson(json);

View File

@@ -1,9 +1,9 @@
import 'package:eatvio_app/core/app_export.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/widgets/chat_bubble_widget.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:flutter/cupertino.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter/material.dart';
import 'package:lazy_load_scrollview/lazy_load_scrollview.dart';
@@ -155,9 +155,7 @@ class _ChatScreenState extends State<ChatScreen> {
children: [
SizedBox(width: 8),
InkWell(
onTap: () {
},
onTap: () {},
borderRadius: BorderRadiusStyle.circleBorder17,
child: Ink(
height: 32,
@@ -179,7 +177,6 @@ class _ChatScreenState extends State<ChatScreen> {
keyboardType: TextInputType.multiline,
style: TextStyle(
fontSize: 16,
fontFamily: 'Mulish',
fontWeight: FontWeight.w400,
color: Colors.black,
),
@@ -188,7 +185,6 @@ class _ChatScreenState extends State<ChatScreen> {
hintText: 'Сообщение',
hintStyle: TextStyle(
fontSize: 16,
fontFamily: 'Mulish',
fontWeight: FontWeight.w400,
color: Color(0xFFAEAEB2),
),

View File

@@ -1,19 +1,19 @@
import 'dart:convert';
import 'package:eatvio_app/app_router.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:go_router/go_router.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'dart:convert';
import '/core/app_export.dart';
import 'package:go_router/go_router.dart';
part 'chat_select_event.dart';
part 'chat_select_state.dart';
/// A bloc that manages the state of a ChatSelect according to the event that is dispatched to it.
@@ -59,7 +59,7 @@ class ChatSelectBloc extends Bloc<ChatSelectEvent, ChatSelectState> {
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
}
final response = await http.get(
Uri.parse(dotenv.env['SERVER_ROOT']! + '/chat/index'),
Uri.parse(baseUrl + '/api/chat/index'),
headers: {
'Authorization': 'Bearer $token',
},

View File

@@ -20,8 +20,7 @@ class ChatSelectState extends Equatable {
}
class ChatSelectInitialState extends ChatSelectState {
ChatSelectInitialState({required ChatSelectModel chatSelectModelObj})
: super(chatSelectModelObj: chatSelectModelObj);
ChatSelectInitialState({required ChatSelectModel chatSelectModelObj}) : super(chatSelectModelObj: chatSelectModelObj);
}
class ChatSelectLoadedState extends ChatSelectState {

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter/material.dart';
class CustomSearchView extends StatelessWidget {
CustomSearchView({

View File

@@ -1,12 +1,13 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/widgets/chat_entry_widget.dart';
import 'package:flutter/cupertino.dart';
import 'bloc/chat_select_bloc.dart';
import 'models/chat_select_model.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'chat_search_view.dart';
import 'package:flutter/material.dart';
import 'bloc/chat_select_bloc.dart';
import 'chat_search_view.dart';
import 'models/chat_select_model.dart';
class ChatSelectScreen extends StatelessWidget {
const ChatSelectScreen({Key? key}) : super(key: key);
@@ -42,18 +43,24 @@ class ChatSelectScreen extends StatelessWidget {
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
automaticallyImplyLeading: false,
stretchTriggerOffset: 1,
forceMaterialTransparency: true,
floating: true,
snap: true,
title: CustomSearchView(
controller: state.searchController,
fillColor: Color(0xFFF0F2F5),
hintText: "Поиск",
hintStyle: TextStyle(
color: Color(0xFF7B8794),
SliverPadding(
padding: const EdgeInsets.only(top: 8),
sliver: SliverAppBar(
automaticallyImplyLeading: false,
stretchTriggerOffset: 1,
forceMaterialTransparency: true,
floating: true,
snap: true,
title: Padding(
padding: const EdgeInsets.only(top: 8),
child: CustomSearchView(
controller: state.searchController,
fillColor: Color(0xFFF0F2F5),
hintText: "Поиск",
hintStyle: TextStyle(
color: Color(0xFF7B8794),
),
),
),
),
),

View File

@@ -1,8 +1,8 @@
// ignore_for_file: must_be_immutable
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_entry.dart';
import 'package:flutter/material.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:go_router/go_router.dart';
class ChatEntryWidget extends StatelessWidget {

View File

@@ -2,7 +2,6 @@ import 'package:cached_network_image/cached_network_image.dart';
import 'package:dismissible_page/dismissible_page.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:go_router/go_router.dart';
import 'package:photo_view/photo_view.dart';
import 'package:photo_view/photo_view_gallery.dart';
@@ -84,7 +83,7 @@ class _PhotoViewScreenState extends State<PhotoViewScreen> {
color: Colors.white,
),
title: Text(
widget.imageUrls[index].replaceAll(dotenv.env['STORAGE_URL']! + 'chat_files/', ''),
widget.imageUrls[index].replaceAll(baseUrl + '/storage/' + 'chat_files/', ''),
style: TextStyle(
color: Colors.white,
fontSize: 12,

View File

@@ -1,9 +1,9 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:dismissible_page/dismissible_page.dart';
import 'package:eatvio_app/core/constants/constants.dart';
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
import 'package:eatvio_app/theme/app_decoration.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:url_launcher/url_launcher.dart';
class ChatBubbleWidget extends StatelessWidget {
@@ -48,7 +48,7 @@ class ChatBubbleWidget extends StatelessWidget {
contentPadding: EdgeInsets.zero,
horizontalTitleGap: 8,
onTap: () async {
if (!await launchUrl(Uri.parse(dotenv.env['STORAGE_URL']! + mediaData[index].toString()))) {
if (!await launchUrl(Uri.parse(baseUrl + '/storage/' + mediaData[index].toString()))) {
throw Exception('Could not launch ${mediaData[index].toString()}');
}
},
@@ -75,18 +75,18 @@ class ChatBubbleWidget extends StatelessWidget {
onTap: () {
context.pushTransparentRoute(
PhotoViewScreen(
imageUrls: mediaData.map((e) => dotenv.env['STORAGE_URL']! + e.toString()).toList(),
imageUrls: mediaData.map((e) => baseUrl + '/storage/' + e.toString()).toList(),
index: index,
),
);
},
child: Hero(
tag: dotenv.env['STORAGE_URL']! + '${mediaData[index]}',
tag: baseUrl + '/storage/' + '${mediaData[index]}',
transitionOnUserGestures: true,
child: ClipRRect(
borderRadius: BorderRadiusStyle.roundedBorder8,
child: CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! + '${mediaData[index]}',
imageUrl: baseUrl + '/storage/' + '${mediaData[index]}',
),
),
),

View File

@@ -1,8 +1,8 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/chat/models/chat_messages_model.dart';
import 'package:eatvio_app/features/chat/models/chat_room_model.dart';
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/chat/models/websocket_info_model.dart';
import 'package:retrofit/retrofit.dart';
@@ -12,24 +12,24 @@ part 'chat_service.g.dart';
abstract class ChatService {
factory ChatService(Dio dio, {String baseUrl}) = _ChatService;
@GET('/chat/show/{id}')
@GET('/api/chat/show/{id}')
Future<Map<String, ChatRoomModel>> getChatRoom({
@Path() required String id,
});
@POST('/chat/{id}/message/send')
@POST('/api/chat/{id}/message/send')
Future<void> sendMessage({
@Path() required String id,
@Part() String? data,
@Part() List<File>? filesList,
});
@GET('/chat/show/{id}/messages?page={page}')
@GET('/api/chat/show/{id}/messages?page={page}')
Future<ChatMessagesModel> getChatMessages({
@Path() required String id,
@Path() required int page,
});
@GET('/profile/ws/params')
@GET('/api/profile/ws/params')
Future<WebsocketInfoModel> getWebsocket();
}

View File

@@ -32,7 +32,7 @@ class _ChatService implements ChatService {
)
.compose(
_dio.options,
'/chat/show/${id}',
'/api/chat/show/${id}',
queryParameters: queryParameters,
data: _data,
)
@@ -78,7 +78,7 @@ class _ChatService implements ChatService {
)
.compose(
_dio.options,
'/chat/${id}/message/send',
'/api/chat/${id}/message/send',
queryParameters: queryParameters,
data: _data,
)
@@ -106,7 +106,7 @@ class _ChatService implements ChatService {
)
.compose(
_dio.options,
'/chat/show/${id}/messages?page=${page}',
'/api/chat/show/${id}/messages?page=${page}',
queryParameters: queryParameters,
data: _data,
)
@@ -133,7 +133,7 @@ class _ChatService implements ChatService {
)
.compose(
_dio.options,
'/profile/ws/params',
'/api/profile/ws/params',
queryParameters: queryParameters,
data: _data,
)

View File

@@ -19,4 +19,4 @@ class DiaryCubit extends Cubit<DiaryState> {
}
}
}
*/
*/

View File

@@ -17,4 +17,4 @@ abstract class DiaryState with _$DiaryState {
required String errorMessage,
}) = DiaryStateError;
}
*/
*/

View File

@@ -7,7 +7,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_edit_drop_down.dart';
@@ -731,7 +731,7 @@ class DiaryEditScreen extends StatelessWidget {
borderRadius: BorderRadiusStyle.roundedBorder5,
),
child: Image.network(
dotenv.env['STORAGE_URL']! + photo['path'],
baseUrl + '/storage/' + photo['path'],
),
),
Positioned(
@@ -1296,4 +1296,4 @@ bool checkConsumedValues(
// Если ни одно потребленное значение не превышает рекомендованное с соответствующим индексом
return false; // Возвращаем true
}
*/
*/

View File

@@ -14,4 +14,4 @@ class DiaryRepository {
}
}
}
*/
*/

View File

@@ -8,7 +8,7 @@ part 'diary_service.g.dart';
abstract class DiaryService {
factory DiaryService(Dio dio, {String baseUrl}) = _DiaryService;
@GET('/feed/show/{id}')
@GET('/api/feed/show/{id}')
Future<DiaryModel> getDiary(@Path() String id);
}
*/
*/

View File

@@ -0,0 +1,14 @@
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'feed_blog_post_settings_model.freezed.dart';
part 'feed_blog_post_settings_model.g.dart';
@freezed
class FeedBlogPostSettingsModel with _$FeedBlogPostSettingsModel {
const factory FeedBlogPostSettingsModel({
@JsonKey(name: 'data') required List<FeedBlogPostModel> feedBlogPostList,
}) = _FeedBlogPostSettingsModel;
factory FeedBlogPostSettingsModel.fromJson(Map<String, Object?> json) => _$FeedBlogPostSettingsModelFromJson(json);
}

View File

@@ -0,0 +1,175 @@
// 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 'feed_blog_post_settings_model.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(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');
FeedBlogPostSettingsModel _$FeedBlogPostSettingsModelFromJson(
Map<String, dynamic> json) {
return _FeedBlogPostSettingsModel.fromJson(json);
}
/// @nodoc
mixin _$FeedBlogPostSettingsModel {
@JsonKey(name: 'data')
List<FeedBlogPostModel> get feedBlogPostList =>
throw _privateConstructorUsedError;
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$FeedBlogPostSettingsModelCopyWith<FeedBlogPostSettingsModel> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $FeedBlogPostSettingsModelCopyWith<$Res> {
factory $FeedBlogPostSettingsModelCopyWith(FeedBlogPostSettingsModel value,
$Res Function(FeedBlogPostSettingsModel) then) =
_$FeedBlogPostSettingsModelCopyWithImpl<$Res, FeedBlogPostSettingsModel>;
@useResult
$Res call({@JsonKey(name: 'data') List<FeedBlogPostModel> feedBlogPostList});
}
/// @nodoc
class _$FeedBlogPostSettingsModelCopyWithImpl<$Res,
$Val extends FeedBlogPostSettingsModel>
implements $FeedBlogPostSettingsModelCopyWith<$Res> {
_$FeedBlogPostSettingsModelCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? feedBlogPostList = null,
}) {
return _then(_value.copyWith(
feedBlogPostList: null == feedBlogPostList
? _value.feedBlogPostList
: feedBlogPostList // ignore: cast_nullable_to_non_nullable
as List<FeedBlogPostModel>,
) as $Val);
}
}
/// @nodoc
abstract class _$$FeedBlogPostSettingsModelImplCopyWith<$Res>
implements $FeedBlogPostSettingsModelCopyWith<$Res> {
factory _$$FeedBlogPostSettingsModelImplCopyWith(
_$FeedBlogPostSettingsModelImpl value,
$Res Function(_$FeedBlogPostSettingsModelImpl) then) =
__$$FeedBlogPostSettingsModelImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({@JsonKey(name: 'data') List<FeedBlogPostModel> feedBlogPostList});
}
/// @nodoc
class __$$FeedBlogPostSettingsModelImplCopyWithImpl<$Res>
extends _$FeedBlogPostSettingsModelCopyWithImpl<$Res,
_$FeedBlogPostSettingsModelImpl>
implements _$$FeedBlogPostSettingsModelImplCopyWith<$Res> {
__$$FeedBlogPostSettingsModelImplCopyWithImpl(
_$FeedBlogPostSettingsModelImpl _value,
$Res Function(_$FeedBlogPostSettingsModelImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? feedBlogPostList = null,
}) {
return _then(_$FeedBlogPostSettingsModelImpl(
feedBlogPostList: null == feedBlogPostList
? _value._feedBlogPostList
: feedBlogPostList // ignore: cast_nullable_to_non_nullable
as List<FeedBlogPostModel>,
));
}
}
/// @nodoc
@JsonSerializable()
class _$FeedBlogPostSettingsModelImpl implements _FeedBlogPostSettingsModel {
const _$FeedBlogPostSettingsModelImpl(
{@JsonKey(name: 'data')
required final List<FeedBlogPostModel> feedBlogPostList})
: _feedBlogPostList = feedBlogPostList;
factory _$FeedBlogPostSettingsModelImpl.fromJson(Map<String, dynamic> json) =>
_$$FeedBlogPostSettingsModelImplFromJson(json);
final List<FeedBlogPostModel> _feedBlogPostList;
@override
@JsonKey(name: 'data')
List<FeedBlogPostModel> get feedBlogPostList {
if (_feedBlogPostList is EqualUnmodifiableListView)
return _feedBlogPostList;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_feedBlogPostList);
}
@override
String toString() {
return 'FeedBlogPostSettingsModel(feedBlogPostList: $feedBlogPostList)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$FeedBlogPostSettingsModelImpl &&
const DeepCollectionEquality()
.equals(other._feedBlogPostList, _feedBlogPostList));
}
@JsonKey(ignore: true)
@override
int get hashCode => Object.hash(
runtimeType, const DeepCollectionEquality().hash(_feedBlogPostList));
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$FeedBlogPostSettingsModelImplCopyWith<_$FeedBlogPostSettingsModelImpl>
get copyWith => __$$FeedBlogPostSettingsModelImplCopyWithImpl<
_$FeedBlogPostSettingsModelImpl>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$$FeedBlogPostSettingsModelImplToJson(
this,
);
}
}
abstract class _FeedBlogPostSettingsModel implements FeedBlogPostSettingsModel {
const factory _FeedBlogPostSettingsModel(
{@JsonKey(name: 'data')
required final List<FeedBlogPostModel> feedBlogPostList}) =
_$FeedBlogPostSettingsModelImpl;
factory _FeedBlogPostSettingsModel.fromJson(Map<String, dynamic> json) =
_$FeedBlogPostSettingsModelImpl.fromJson;
@override
@JsonKey(name: 'data')
List<FeedBlogPostModel> get feedBlogPostList;
@override
@JsonKey(ignore: true)
_$$FeedBlogPostSettingsModelImplCopyWith<_$FeedBlogPostSettingsModelImpl>
get copyWith => throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,21 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'feed_blog_post_settings_model.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
_$FeedBlogPostSettingsModelImpl _$$FeedBlogPostSettingsModelImplFromJson(
Map<String, dynamic> json) =>
_$FeedBlogPostSettingsModelImpl(
feedBlogPostList: (json['data'] as List<dynamic>)
.map((e) => FeedBlogPostModel.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$$FeedBlogPostSettingsModelImplToJson(
_$FeedBlogPostSettingsModelImpl instance) =>
<String, dynamic>{
'data': instance.feedBlogPostList,
};

View File

@@ -1,15 +1,14 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_state.dart';
import 'package:flutter/cupertino.dart';
import 'package:go_router/go_router.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/presentation/feed/feed_screen/widgets/feed_search_view.dart';
import 'package:eatvio_app/presentation/feed/feed_screen/widgets/feed_scroll_item.dart';
import 'package:eatvio_app/presentation/feed/feed_screen/widgets/feed_search_view.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
class FeedScreen extends StatelessWidget {
@@ -153,7 +152,7 @@ class FeedScreen extends StatelessWidget {
children: [
ListTile(
leading: CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! + (''),
imageUrl: baseUrl + '/storage/' + (''),
/// todo profile photo path
imageBuilder: (context, imageProvider) => CircleAvatar(
@@ -224,7 +223,7 @@ class FeedScreen extends StatelessWidget {
),
SizedBox(height: 16.0),
CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! + (post.image),
imageUrl: baseUrl + '/storage/' + (post.image),
imageBuilder: (context, imageProvider) => Stack(
children: [
ClipRRect(

View File

@@ -8,7 +8,7 @@ class FeedRepository {
Future<List<FeedBlogPostModel>> getFeedBlogPostList() async {
try {
return (await feedService.getBlocPostList()).entries.map((entry) => entry.value).toList();
return (await feedService.getBlocPostList()).feedBlogPostList;
} catch (e) {
rethrow;
}

View File

@@ -1,5 +1,5 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_model.dart';
import 'package:eatvio_app/features/feed/models/feed_blog_post_settings_model.dart';
import 'package:retrofit/retrofit.dart';
part 'feed_service.g.dart';
@@ -8,6 +8,6 @@ part 'feed_service.g.dart';
abstract class FeedService {
factory FeedService(Dio dio, {String baseUrl}) = _FeedService;
@GET('/feed/index')
Future<Map<String, FeedBlogPostModel>> getBlocPostList();
@GET('/api/blogPosts/index')
Future<FeedBlogPostSettingsModel> getBlocPostList();
}

View File

@@ -19,20 +19,20 @@ class _FeedService implements FeedService {
String? baseUrl;
@override
Future<Map<String, FeedBlogPostModel>> getBlocPostList() async {
Future<FeedBlogPostSettingsModel> getBlocPostList() async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
const Map<String, dynamic>? _data = null;
final _result = await _dio.fetch<Map<String, dynamic>>(
_setStreamType<Map<String, FeedBlogPostModel>>(Options(
_setStreamType<FeedBlogPostSettingsModel>(Options(
method: 'GET',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/feed/index',
'/api/blogPosts/index',
queryParameters: queryParameters,
data: _data,
)
@@ -41,8 +41,7 @@ class _FeedService implements FeedService {
_dio.options.baseUrl,
baseUrl,
))));
var _value = _result.data!.map((k, dynamic v) =>
MapEntry(k, FeedBlogPostModel.fromJson(v as Map<String, dynamic>)));
final _value = FeedBlogPostSettingsModel.fromJson(_result.data!);
return _value;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
import 'package:eatvio_app/app_router.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_state.dart';
import 'package:eatvio_app/features/registration/repositories/registration_repository.dart';
import 'package:go_router/go_router.dart';
class RegistrationCubit extends Cubit<RegistrationState> {
final RegistrationRepository registrationRepository;
RegistrationCubit({required this.registrationRepository})
: super(
RegistrationState(
sheet: UserRegistrationSheet(
name: '',
firstName: '',
lastName: '',
email: '',
password: '',
passwordConfirmation: '',
birthdate: DateTime.now().toString(),
gender: '',
country: '',
city: '',
lang: 'Русский',
weight: 0,
height: 0,
chestCircumference: 0,
waistCircumference: 0,
hipCircumference: 0,
bloodPressureUp: 0,
bloodPressureDown: 0,
hasHypo: 0,
hasHyper: 0,
aboutAllergy: '',
aboutTakingPils: '',
aboutSportHobbies: '',
favoriteFoods: '',
unfavoriteFoods: '',
additionalInfo: '',
),
),
);
updateSheet(UserRegistrationSheet sheet) => emit(RegistrationState(sheet: sheet));
Future<void> tryRegistration() async {
try {
final token = await registrationRepository.tryRegister(state.sheet);
await TokenStorage.saveTokenInStorage(token);
AppRouter.navigatorKey.currentContext?.go('/my-profile-screen');
} catch (e) {
rethrow;
}
}
}

View File

@@ -0,0 +1,11 @@
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'registration_state.freezed.dart';
@freezed
class RegistrationState with _$RegistrationState {
const factory RegistrationState({
required UserRegistrationSheet sheet,
}) = _RegistrationState;
}

View File

@@ -0,0 +1,147 @@
// 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 'registration_state.dart';
// **************************************************************************
// FreezedGenerator
// **************************************************************************
T _$identity<T>(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 _$RegistrationState {
UserRegistrationSheet get sheet => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
$RegistrationStateCopyWith<RegistrationState> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class $RegistrationStateCopyWith<$Res> {
factory $RegistrationStateCopyWith(
RegistrationState value, $Res Function(RegistrationState) then) =
_$RegistrationStateCopyWithImpl<$Res, RegistrationState>;
@useResult
$Res call({UserRegistrationSheet sheet});
$UserRegistrationSheetCopyWith<$Res> get sheet;
}
/// @nodoc
class _$RegistrationStateCopyWithImpl<$Res, $Val extends RegistrationState>
implements $RegistrationStateCopyWith<$Res> {
_$RegistrationStateCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
@pragma('vm:prefer-inline')
@override
$Res call({
Object? sheet = null,
}) {
return _then(_value.copyWith(
sheet: null == sheet
? _value.sheet
: sheet // ignore: cast_nullable_to_non_nullable
as UserRegistrationSheet,
) as $Val);
}
@override
@pragma('vm:prefer-inline')
$UserRegistrationSheetCopyWith<$Res> get sheet {
return $UserRegistrationSheetCopyWith<$Res>(_value.sheet, (value) {
return _then(_value.copyWith(sheet: value) as $Val);
});
}
}
/// @nodoc
abstract class _$$RegistrationStateImplCopyWith<$Res>
implements $RegistrationStateCopyWith<$Res> {
factory _$$RegistrationStateImplCopyWith(_$RegistrationStateImpl value,
$Res Function(_$RegistrationStateImpl) then) =
__$$RegistrationStateImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({UserRegistrationSheet sheet});
@override
$UserRegistrationSheetCopyWith<$Res> get sheet;
}
/// @nodoc
class __$$RegistrationStateImplCopyWithImpl<$Res>
extends _$RegistrationStateCopyWithImpl<$Res, _$RegistrationStateImpl>
implements _$$RegistrationStateImplCopyWith<$Res> {
__$$RegistrationStateImplCopyWithImpl(_$RegistrationStateImpl _value,
$Res Function(_$RegistrationStateImpl) _then)
: super(_value, _then);
@pragma('vm:prefer-inline')
@override
$Res call({
Object? sheet = null,
}) {
return _then(_$RegistrationStateImpl(
sheet: null == sheet
? _value.sheet
: sheet // ignore: cast_nullable_to_non_nullable
as UserRegistrationSheet,
));
}
}
/// @nodoc
class _$RegistrationStateImpl implements _RegistrationState {
const _$RegistrationStateImpl({required this.sheet});
@override
final UserRegistrationSheet sheet;
@override
String toString() {
return 'RegistrationState(sheet: $sheet)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$RegistrationStateImpl &&
(identical(other.sheet, sheet) || other.sheet == sheet));
}
@override
int get hashCode => Object.hash(runtimeType, sheet);
@JsonKey(ignore: true)
@override
@pragma('vm:prefer-inline')
_$$RegistrationStateImplCopyWith<_$RegistrationStateImpl> get copyWith =>
__$$RegistrationStateImplCopyWithImpl<_$RegistrationStateImpl>(
this, _$identity);
}
abstract class _RegistrationState implements RegistrationState {
const factory _RegistrationState(
{required final UserRegistrationSheet sheet}) = _$RegistrationStateImpl;
@override
UserRegistrationSheet get sheet;
@override
@JsonKey(ignore: true)
_$$RegistrationStateImplCopyWith<_$RegistrationStateImpl> get copyWith =>
throw _privateConstructorUsedError;
}

View File

@@ -0,0 +1,61 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class AdditionalInformationScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const AdditionalInformationScreen({super.key, required this.sheet});
@override
State<AdditionalInformationScreen> createState() => _AdditionalInformationScreenState();
}
class _AdditionalInformationScreenState extends State<AdditionalInformationScreen> {
final editTextController = TextEditingController();
@override
void initState() {
super.initState();
editTextController.text = widget.sheet.additionalInfo;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Container(
width: 294.h,
margin: EdgeInsets.only(left: 24.h, right: 23.h),
child: Text(
"enter_additional_information".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: CustomTextStyles.titleMediumSegoeUI,
),
),
SizedBox(height: 10.v),
CustomTextFormField(
controller: editTextController,
hintText: "У меня крепкое здоровье, но последнее время часто утомляюсь, однако, это мне не мешает радоваться жизни",
textInputAction: TextInputAction.done,
maxLines: 8,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(additionalInfo: newValue));
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,53 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class AllergiesScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const AllergiesScreen({super.key, required this.sheet});
@override
State<AllergiesScreen> createState() => _AllergiesScreenState();
}
class _AllergiesScreenState extends State<AllergiesScreen> {
final enterInformationController = TextEditingController();
@override
void initState() {
super.initState();
enterInformationController.text = widget.sheet.aboutAllergy;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text("allergies_presence".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 22.v),
Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI),
SizedBox(height: 2.v),
CustomTextFormField(
controller: enterInformationController,
hintText: "enter_information".tr,
textInputAction: TextInputAction.done,
maxLines: 8,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(aboutAllergy: newValue));
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,158 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class BloodPressureScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const BloodPressureScreen({super.key, required this.sheet});
@override
State<BloodPressureScreen> createState() => _BloodPressureScreenState();
}
class _BloodPressureScreenState extends State<BloodPressureScreen> {
final List<SelectionPopupModel> selectionPopupList = [
SelectionPopupModel(
id: 1,
title: "Да",
),
SelectionPopupModel(
id: 0,
title: "Нет",
),
];
late SelectionPopupModel selectedPopupHypo;
late SelectionPopupModel selectedPopupHyper;
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
final upPressureController = TextEditingController();
final downPressureController = TextEditingController();
@override
void initState() {
super.initState();
selectedPopupHypo = selectionPopupList[1];
selectedPopupHyper = selectionPopupList[1];
upPressureController.text = widget.sheet.bloodPressureUp.toString();
downPressureController.text = widget.sheet.bloodPressureDown.toString();
widget.sheet.hasHyper == '1' ? selectedPopupHyper = selectionPopupList[0] : selectedPopupHyper = selectionPopupList[1];
widget.sheet.hasHypo == '1' ? selectedPopupHypo = selectionPopupList[0] : selectedPopupHypo = selectionPopupList[1];
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 9.v),
child: Column(
children: [
SizedBox(
width: 224.h,
child: Text(
"your_blood_pressure".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: theme.textTheme.headlineSmall,
),
),
SizedBox(height: 21.v),
Container(
margin: EdgeInsets.only(right: 1.h),
padding: EdgeInsets.symmetric(horizontal: 3.h),
child: Column(
children: [
Text("up_pressure".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: upPressureController,
hintText: "90".tr,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(bloodPressureUp: int.parse(newValue)));
},
),
],
),
),
SizedBox(height: 21.v),
Container(
margin: EdgeInsets.only(right: 1.h),
padding: EdgeInsets.symmetric(horizontal: 3.h),
child: Column(
children: [
Text("down_pressure".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: downPressureController,
hintText: "90".tr,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(bloodPressureDown: int.parse(newValue)));
},
),
],
),
),
SizedBox(height: 22.v),
Text("do_you_have_hypotension_tendency".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.h),
child: CustomDropDown(
icon: Container(
margin: EdgeInsets.fromLTRB(30.h, 11.v, 13.h, 11.v),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize),
),
hintText: "Не выбрано".tr,
items: selectionPopupList,
value: selectedPopupHypo,
onChanged: (newPopup) {
setState(() {
selectedPopupHypo = newPopup;
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(hasHypo: selectedPopupHypo.id!));
});
},
),
),
SizedBox(height: 22.v),
Text("do_you_have_hypertension_tendency".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
Padding(
padding: EdgeInsets.symmetric(horizontal: 4.h),
child: CustomDropDown(
icon: Container(
margin: EdgeInsets.fromLTRB(30.h, 11.v, 13.h, 11.v),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize),
),
hintText: "Не выбрано".tr,
items: selectionPopupList,
value: selectedPopupHyper,
onChanged: (newPopup) {
setState(() {
selectedPopupHyper = newPopup;
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(hasHyper: selectedPopupHyper.id!));
});
},
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,87 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class BodyCircumferencesScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const BodyCircumferencesScreen({super.key, required this.sheet});
@override
State<BodyCircumferencesScreen> createState() => _BodyCircumferencesScreenState();
}
class _BodyCircumferencesScreenState extends State<BodyCircumferencesScreen> {
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
final chestCircumferenceController = TextEditingController();
final waistCircumferenceController = TextEditingController();
final hipCircumferenceController = TextEditingController();
@override
void initState() {
super.initState();
if (widget.sheet.chestCircumference != 0) chestCircumferenceController.text = widget.sheet.chestCircumference.toString();
if (widget.sheet.waistCircumference != 0) waistCircumferenceController.text = widget.sheet.waistCircumference.toString();
if (widget.sheet.hipCircumference != 0) hipCircumferenceController.text = widget.sheet.hipCircumference.toString();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text("initial_measurements".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 16.v),
Column(
children: [
Text("chest_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: chestCircumferenceController,
hintText: "90".tr,
onChanged: (value) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(chestCircumference: int.parse(value)));
},
),
],
),
SizedBox(height: 19.v),
Text("waist_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 5.v),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: waistCircumferenceController,
hintText: "60".tr,
onChanged: (value) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(waistCircumference: int.parse(value)));
},
),
SizedBox(height: 21.v),
Text("hip_circumference".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
CustomTextFormField(
inputFormatters: [digitsOnly],
controller: hipCircumferenceController,
hintText: "90".tr,
textInputAction: TextInputAction.done,
onChanged: (value) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(hipCircumference: int.parse(value)));
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,88 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/consts/cities_list.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:flutter/material.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
class CityOfLivingScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const CityOfLivingScreen({super.key, required this.sheet});
@override
State<CityOfLivingScreen> createState() => _CityOfLivingScreenState();
}
class _CityOfLivingScreenState extends State<CityOfLivingScreen> {
final dropdownItemList = [
SelectionPopupModel(id: 1, title: "Россия", isSelected: true),
];
late SelectionPopupModel selectedItem;
final cityController = TextEditingController();
@override
void initState() {
super.initState();
selectedItem = dropdownItemList[0];
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(country: selectedItem.title));
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text("place_of_living".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 39.v),
Text("country".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
CustomDropDown(
icon: Container(
margin: EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v),
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize),
),
hintText: "Не выбрано".tr,
items: dropdownItemList,
value: selectedItem,
onChanged: (newValue) {
setState(() {
selectedItem = newValue;
});
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(country: newValue.title));
},
),
SizedBox(height: 22.v),
Text("Населенный пункт", style: theme.textTheme.bodyLarge),
SizedBox(height: 2.v),
TypeAheadField(
controller: cityController,
itemBuilder: (BuildContext context, String item) {
return Text(item);
},
onSelected: (item) {
setState(() {
cityController.text = item;
});
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(city: item));
},
suggestionsCallback: (query) {
return citiesList.where((country) => country.toLowerCase().contains(query.toLowerCase())).toList();
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,95 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class CredentialsScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const CredentialsScreen({super.key, required this.sheet});
@override
State<CredentialsScreen> createState() => _CredentialsScreenState();
}
class _CredentialsScreenState extends State<CredentialsScreen> {
final emailController = TextEditingController();
final nameController = TextEditingController();
final passwordController = TextEditingController();
final passwordConfirmationController = TextEditingController();
@override
void initState() {
super.initState();
emailController.text = widget.sheet.email;
nameController.text = widget.sheet.name;
passwordController.text = widget.sheet.password;
passwordConfirmationController.text = widget.sheet.passwordConfirmation;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text("user_registration".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 16.v),
Text("email".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
CustomTextFormField(
controller: emailController,
textInputAction: TextInputAction.done,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(email: newValue));
},
),
SizedBox(height: 22.v),
Text("username".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
CustomTextFormField(
controller: nameController,
textInputAction: TextInputAction.done,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(name: newValue));
},
),
SizedBox(height: 19.v),
Text("password".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 5.v),
CustomTextFormField(
obscureText: true,
controller: passwordController,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(password: newValue));
},
),
SizedBox(height: 21.v),
Text("password_confirmation".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
CustomTextFormField(
obscureText: true,
controller: passwordConfirmationController,
textInputAction: TextInputAction.done,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(passwordConfirmation: newValue));
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,113 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart';
class DateOfBirthScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const DateOfBirthScreen({super.key, required this.sheet});
@override
State<DateOfBirthScreen> createState() => _DateOfBirthScreenState();
}
class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
late DateTime selectedDate;
@override
void initState() {
super.initState();
if (widget.sheet.birthdate.isNotEmpty) {
selectedDate = DateFormat('yyyy-mm-dd').parse(widget.sheet.birthdate);
} else {
selectedDate = DateTime.now();
}
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text("date_of_birth".tr, style: theme.textTheme.headlineSmall),
const SizedBox(height: 32),
_buildDateInput(context),
],
),
),
);
}
/// Section Widget
_buildDateInput(BuildContext context) {
return Container(
width: 343.h,
padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 1.v),
decoration: AppDecoration.outlineBlueA.copyWith(borderRadius: BorderRadiusStyle.circleBorder8),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize, radius: BorderRadius.circular(1.h)),
SizedBox(height: 6.v),
Align(
alignment: Alignment.center,
child: GestureDetector(
onTap: onTapCalendar(context),
child: Text('${selectedDate.day}.${selectedDate.month}.${selectedDate.year}', style: theme.textTheme.titleMedium),
),
),
SizedBox(height: 6.v),
],
),
);
}
onTapCalendar(BuildContext context) {
return () {
_showDialog(
CupertinoDatePicker(
initialDateTime: DateTime.now(),
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (DateTime newDateTime) {
setState(() {
selectedDate = newDateTime;
print(selectedDate);
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(birthdate: selectedDate.toString()));
});
},
),
);
};
}
void _showDialog(Widget child) {
showCupertinoModalPopup<void>(
context: context,
builder: (BuildContext context) => Container(
height: 216,
padding: const EdgeInsets.only(top: 6.0),
// The Bottom margin is provided to align the popup above the system
// navigation bar.
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom,
),
// Provide a background color for the popup.
color: CupertinoColors.systemBackground.resolveFrom(context),
// Use a SafeArea widget to avoid system overlaps.
child: SafeArea(
top: false,
child: child,
),
),
);
}
}

View File

@@ -0,0 +1,77 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class FavoriteFoodsScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const FavoriteFoodsScreen({super.key, required this.sheet});
@override
State<FavoriteFoodsScreen> createState() => _FavoriteFoodsScreenState();
}
class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
final favoriteFoodsController = TextEditingController();
final unFavoriteFoodsController = TextEditingController();
@override
void initState() {
super.initState();
favoriteFoodsController.text = widget.sheet.favoriteFoods;
unFavoriteFoodsController.text = widget.sheet.unfavoriteFoods;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Container(
width: 327.h,
margin: EdgeInsets.only(left: 8.h, right: 7.h),
child: Text(
"favorite_unfavorite_foods".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: theme.textTheme.headlineSmall,
),
),
SizedBox(height: 13.v),
Text("favorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI),
SizedBox(height: 2.v),
CustomTextFormField(
controller: favoriteFoodsController,
hintText: "enter_information".tr,
maxLines: 7,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(favoriteFoods: newValue));
},
),
SizedBox(height: 12.v),
Text("unfavorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI),
SizedBox(height: 2.v),
CustomTextFormField(
controller: unFavoriteFoodsController,
hintText: "enter_information".tr,
textInputAction: TextInputAction.done,
maxLines: 7,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(unfavoriteFoods: newValue));
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,55 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class FavoriteSportsScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const FavoriteSportsScreen({super.key, required this.sheet});
@override
State<FavoriteSportsScreen> createState() => _FavoriteSportsScreenState();
}
class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
final enterInformationController = TextEditingController();
@override
void initState() {
super.initState();
enterInformationController.text = widget.sheet.aboutSportHobbies;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 5.v),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("your_favorite_sports".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 22.v),
Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI),
SizedBox(height: 2.v),
CustomTextFormField(
controller: enterInformationController,
hintText:
"Я занимаюсь плаванием , почти каждый вечер прогулки на свежем воздухе, пару раз в месяц играю в волейбол. Стараюсь не сидеть на месте!",
textInputAction: TextInputAction.done,
maxLines: 8,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(aboutSportHobbies: newValue));
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,79 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:flutter/material.dart';
class GenderScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const GenderScreen({super.key, required this.sheet});
@override
State<GenderScreen> createState() => _GenderScreenState();
}
class _GenderScreenState extends State<GenderScreen> {
late String currentValue;
@override
void initState() {
super.initState();
currentValue = widget.sheet.gender;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text("your_gender".tr, style: theme.textTheme.headlineSmall),
RadioListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
title: Text('Мужской'),
value: 'male',
groupValue: currentValue,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(gender: 'male'));
setState(() {
currentValue = 'male';
});
},
secondary: Image.asset(
'assets/images/img_male.png',
width: 40,
height: 40,
),
),
RadioListTile(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
title: Text('Женский'),
value: 'female',
groupValue: currentValue,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(gender: 'female'));
setState(() {
currentValue = 'female';
});
},
secondary: Image.asset(
'assets/images/img_female.png',
width: 40,
height: 40,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,67 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class HeightScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const HeightScreen({super.key, required this.sheet});
@override
State<HeightScreen> createState() => _HeightScreenState();
}
class _HeightScreenState extends State<HeightScreen> {
final heightController = TextEditingController();
@override
void initState() {
super.initState();
if (widget.sheet.height != 0) heightController.text = widget.sheet.height.toString();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text(
"height_measurements".tr,
style: theme.textTheme.headlineSmall,
),
SizedBox(height: 16.v),
Column(
children: [
Text(
"your_height".tr,
style: theme.textTheme.bodyLarge,
),
SizedBox(height: 4.v),
CustomTextFormField(
width: 150.h,
textInputAction: TextInputAction.done,
controller: heightController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly,
],
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(height: int.parse(newValue)));
},
),
],
),
],
),
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_drop_down.dart';
import 'package:flutter/material.dart';
class LanguageSelectScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const LanguageSelectScreen({required this.sheet, super.key});
@override
State<LanguageSelectScreen> createState() => _LanguageSelectScreenState();
}
class _LanguageSelectScreenState extends State<LanguageSelectScreen> {
final List<SelectionPopupModel> dropdownItemList = [
SelectionPopupModel(id: 1, title: "Русский", isSelected: true),
];
SelectionPopupModel? value;
@override
void initState() {
super.initState();
if (widget.sheet.lang.isNotEmpty) {
value = dropdownItemList.first;
}
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Column(
children: [
Container(
width: 262.h,
margin: EdgeInsets.only(left: 41.h, right: 39.h),
child: Text(
"preferred_language".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: theme.textTheme.headlineSmall,
),
),
const SizedBox(height: 32),
CustomDropDown(
value: value,
hintText: "Не выбрано".tr,
items: dropdownItemList,
onChanged: (SelectionPopupModel newValue) => setState(() {
value = newValue;
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(lang: value!.title));
}),
),
],
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class MedicineIntakeScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const MedicineIntakeScreen({super.key, required this.sheet});
@override
State<MedicineIntakeScreen> createState() => _MedicineIntakeScreenState();
}
class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
final enterInformationController = TextEditingController();
@override
void initState() {
super.initState();
enterInformationController.text = widget.sheet.aboutTakingPils;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Container(
width: 271.h,
margin: EdgeInsets.only(left: 35.h, right: 36.h),
child: Text(
"do_you_take_pills".tr,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: theme.textTheme.headlineSmall,
),
),
SizedBox(height: 16.v),
Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI),
SizedBox(height: 2.v),
CustomTextFormField(
controller: enterInformationController,
hintText: "enter_information".tr,
textInputAction: TextInputAction.done,
maxLines: 8,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(aboutTakingPils: newValue));
},
),
],
),
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
class NameScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const NameScreen({required this.sheet, super.key});
@override
State<NameScreen> createState() => _NameScreenState();
}
class _NameScreenState extends State<NameScreen> {
final firstNameController = TextEditingController();
final lastNameController = TextEditingController();
@override
void initState() {
super.initState();
firstNameController.text = widget.sheet.firstName;
lastNameController.text = widget.sheet.lastName;
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text("what_is_your_name".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 16.v),
Text("first_name".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
CustomTextFormField(
controller: firstNameController,
textInputAction: TextInputAction.done,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(firstName: newValue));
},
),
SizedBox(height: 19.v),
Text("last_name".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 5.v),
CustomTextFormField(
controller: lastNameController,
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(lastName: newValue));
},
)
],
),
),
);
}
}

View File

@@ -0,0 +1,390 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_state.dart';
import 'package:eatvio_app/features/registration/presentation/pages/additional_information_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/allergies_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/blood_pressure_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/body_circumferences_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/city_of_living_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/credentials_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/date_of_birth_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/favorite_foods_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/favorite_sports_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/gender_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/height_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/language_select_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/medicine_intake_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/name_screen.dart';
import 'package:eatvio_app/features/registration/presentation/pages/weight_screen.dart';
import 'package:eatvio_app/locator_service.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:validators/validators.dart';
class RegistrationScreen extends StatefulWidget {
const RegistrationScreen({super.key});
@override
State<RegistrationScreen> createState() => _RegistrationScreenState();
}
class _RegistrationScreenState extends State<RegistrationScreen> {
double progressValue = 1 / 15;
int step = 1;
final pageController = PageController();
final RegistrationCubit registrationCubit = sl<RegistrationCubit>();
_showPopDialog() {
showDialog(
context: context,
builder: (context) => CupertinoAlertDialog(
content: Text('Отменить регистрацию? Заполненные данные не будут сохранены.'),
actions: [
CupertinoDialogAction(
onPressed: () {
Navigator.pop(context);
GoRouter.of(context).pop();
},
child: Text('Да'),
),
CupertinoDialogAction(
onPressed: () {
Navigator.pop(context);
},
isDefaultAction: true,
child: Text('Нет'),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return BlocProvider<RegistrationCubit>(
create: (BuildContext context) => registrationCubit,
child: BlocBuilder<RegistrationCubit, RegistrationState>(
builder: (BuildContext context, RegistrationState state) {
return PopScope(
canPop: false,
onPopInvoked: (_) => _showPopDialog(),
child: Scaffold(
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
floatingActionButton: Row(
children: [
Container(
height: 48,
width: MediaQuery.of(context).size.width * 0.2,
padding: EdgeInsets.only(left: 16, right: 4),
child: FloatingActionButton.extended(
heroTag: 'backButtonRegistration',
highlightElevation: 0,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: Color(0xFFEAF2FD),
onPressed: () {
if (pageController.page == 0) _showPopDialog();
setState(() {
pageController.previousPage(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
);
});
},
label: Icon(
Icons.arrow_back_ios_new_rounded,
color: appTheme.blueA400,
),
),
),
Container(
height: 48,
width: MediaQuery.of(context).size.width * 0.8,
padding: EdgeInsets.only(left: 4, right: 16),
child: FloatingActionButton.extended(
heroTag: 'nextButtonRegistration',
highlightElevation: 0,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
backgroundColor: appTheme.blueA400,
onPressed: () async {
if (await canGoNext(state)) {
setState(() {
pageController.nextPage(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
);
});
}
},
label: Text(
'Продолжить',
style: theme.textTheme.titleSmall,
),
),
),
],
),
appBar: AppBar(
automaticallyImplyLeading: true,
centerTitle: true,
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),
actions: [
Padding(
padding: const EdgeInsets.only(right: 16),
child: Text('шаг $step из 15'),
),
],
bottom: PreferredSize(
preferredSize: Size(MediaQuery.of(context).size.width, 32),
child: Padding(
padding: const EdgeInsets.all(16),
child: TweenAnimationBuilder<double>(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
tween: Tween<double>(
begin: 0,
end: progressValue,
),
builder: (context, value, _) => LinearProgressIndicator(
value: value,
borderRadius: BorderRadius.circular(16),
minHeight: 8,
backgroundColor: Colors.grey.shade100,
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
),
),
),
),
),
body: PageView(
physics: NeverScrollableScrollPhysics(),
controller: pageController,
onPageChanged: (index) {
setState(() {
step = index + 1;
progressValue = step / 15;
});
},
children: [
LanguageSelectScreen(sheet: state.sheet),
CredentialsScreen(sheet: state.sheet),
NameScreen(sheet: state.sheet),
GenderScreen(sheet: state.sheet),
DateOfBirthScreen(sheet: state.sheet),
CityOfLivingScreen(sheet: state.sheet), // todo refactor
BodyCircumferencesScreen(sheet: state.sheet),
WeightScreen(sheet: state.sheet),
HeightScreen(sheet: state.sheet),
BloodPressureScreen(sheet: state.sheet),
AllergiesScreen(sheet: state.sheet),
MedicineIntakeScreen(sheet: state.sheet),
FavoriteSportsScreen(sheet: state.sheet),
FavoriteFoodsScreen(sheet: state.sheet),
AdditionalInformationScreen(sheet: state.sheet),
],
),
),
);
},
),
);
}
Future<bool> canGoNext(state) async {
switch (step) {
case 2:
List<String> errors = validateCredentialsFields(state.sheet.email, state.sheet.name, state.sheet.password, state.sheet.passwordConfirmation);
if (errors.isEmpty) {
return true;
} else {
String errorMessage = '';
for (var error in errors) {
errorMessage += error + '\n\n';
}
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Ошибка'),
content: Text(errorMessage),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
return false;
}
case 3:
List<String> errors = validateNameFields(
state.sheet.firstName.toString(),
state.sheet.lastName.toString(),
);
if (errors.isEmpty) {
return true;
} else {
String errorMessage = '';
for (var error in errors) {
errorMessage += error + '\n\n';
}
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Ошибка'),
content: Text(errorMessage),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
return false;
}
case 7:
List<String> errors = validateCircumferencesFields(
state.sheet.chestCircumference.toString(),
state.sheet.waistCircumference.toString(),
state.sheet.hipCircumference.toString(),
);
if (errors.isEmpty) {
return true;
} else {
String errorMessage = '';
for (var error in errors) {
errorMessage += error + '\n\n';
}
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Ошибка'),
content: Text(errorMessage),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
return false;
}
case 15:
try {
showDialog(
barrierDismissible: false,
useSafeArea: false,
context: context,
builder: (context) => PopScope(
canPop: false,
child: Center(
child: CircularProgressIndicator(),
),
),
);
await registrationCubit.tryRegistration();
Navigator.pop(context);
} catch (e) {
Navigator.pop(context);
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Ошибка при попытке регистрации'),
),
);
}
return false;
default:
return true;
}
}
List<String> validateCircumferencesFields(
String chestCircumference,
String waistCircumference,
String hipCircumference,
) {
List<String> errors = [];
if (chestCircumference.isEmpty | waistCircumference.isEmpty | hipCircumference.isEmpty) {
errors.add('circumference_empty'.tr);
}
if (![chestCircumference, waistCircumference, hipCircumference].every((circumference) => int.tryParse(circumference) != null)) {
errors.add('circumference_is_not_a_number'.tr);
}
return errors;
}
List<String> validateCredentialsFields(String email, String name, String password, String passwordConfirmation) {
List<String> errors = [];
if (!isEmail(email)) {
errors.add('email_invalid'.tr);
}
if (email.isEmpty) {
errors.add('email_empty'.tr);
}
if (name.length < 6) {
errors.add('name_short'.tr);
}
if (name.isEmpty) {
errors.add('name_empty'.tr);
}
if (password.isEmpty) {
errors.add('name_empty'.tr);
}
if (password.length < 6) {
errors.add('password_short'.tr);
}
if (password != passwordConfirmation) {
errors.add('password_confirmation_mismatch'.tr);
}
return errors;
}
List<String> validateNameFields(String firstName, String lastName) {
List<String> errors = [];
if (firstName.isEmpty) {
errors.add('First name cannot be empty');
}
if (firstName.length < 1) {
errors.add('First name is too short');
}
if (lastName.isEmpty) {
errors.add('Last name cannot be empty');
}
if (lastName.length < 1) {
errors.add('Last name is too short');
}
return errors;
}
}

View File

@@ -0,0 +1,67 @@
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class WeightScreen extends StatefulWidget {
final UserRegistrationSheet sheet;
const WeightScreen({super.key, required this.sheet});
@override
State<WeightScreen> createState() => _WeightScreenState();
}
class _WeightScreenState extends State<WeightScreen> {
final weightController = TextEditingController();
@override
void initState() {
super.initState();
if (widget.sheet.weight != 0) weightController.text = widget.sheet.weight.toString();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
padding: EdgeInsets.only(bottom: 80),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
Text(
"weight_measurements".tr,
style: theme.textTheme.headlineSmall,
),
SizedBox(height: 16.v),
Column(
children: [
Text(
"your_weight".tr,
style: theme.textTheme.bodyLarge,
),
SizedBox(height: 4.v),
CustomTextFormField(
width: 150.h,
textInputAction: TextInputAction.done,
controller: weightController,
keyboardType: TextInputType.number,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.digitsOnly,
],
onChanged: (newValue) {
final registrationCubit = context.read<RegistrationCubit>();
registrationCubit.updateSheet(registrationCubit.state.sheet.copyWith(weight: int.parse(newValue)));
},
),
],
),
],
),
),
);
}
}

View File

@@ -0,0 +1,16 @@
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
import 'package:eatvio_app/features/registration/services/registration_service.dart';
class RegistrationRepository {
final RegistrationService registrationService;
RegistrationRepository({required this.registrationService});
Future<String> tryRegister(UserRegistrationSheet sheet) async {
try {
return (await registrationService.register(sheet: sheet.toJson()))['token']!;
} catch (e) {
rethrow;
}
}
}

View File

@@ -0,0 +1,14 @@
import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';
part 'registration_service.g.dart';
@RestApi()
abstract class RegistrationService {
factory RegistrationService(Dio dio, {String baseUrl}) = _RegistrationService;
@POST('/api/register')
Future<Map<String, String>> register({
@Body() required Map<String, dynamic> sheet,
});
}

View File

@@ -0,0 +1,79 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'registration_service.dart';
// **************************************************************************
// RetrofitGenerator
// **************************************************************************
// ignore_for_file: unnecessary_brace_in_string_interps,no_leading_underscores_for_local_identifiers,unused_element
class _RegistrationService implements RegistrationService {
_RegistrationService(
this._dio, {
this.baseUrl,
});
final Dio _dio;
String? baseUrl;
@override
Future<Map<String, String>> register(
{required Map<String, dynamic> sheet}) async {
final _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _headers = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(sheet);
final _result = await _dio.fetch<Map<String, dynamic>>(
_setStreamType<Map<String, String>>(Options(
method: 'POST',
headers: _headers,
extra: _extra,
)
.compose(
_dio.options,
'/api/register',
queryParameters: queryParameters,
data: _data,
)
.copyWith(
baseUrl: _combineBaseUrls(
_dio.options.baseUrl,
baseUrl,
))));
final _value = _result.data!.cast<String, String>();
return _value;
}
RequestOptions _setStreamType<T>(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();
}
}

View File

@@ -1,9 +1,9 @@
import 'package:eatvio_app/app_router.dart';
import 'ru/ru_translations.dart';
import 'package:flutter/cupertino.dart';
//import 'en_us/en_us_translations.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/cupertino.dart';
import 'ru/ru_translations.dart';
class AppLocalization {
AppLocalization(this.locale);
@@ -23,24 +23,24 @@ class AppLocalization {
return Localizations.of<AppLocalization>(context, AppLocalization)!;
} else {
// Обработка ситуации, когда context равен null
return AppLocalization(Locale(
'ru',
'',
),); // Возвращаем дефолтное значение или обработку ошибки
return AppLocalization(
Locale(
'ru',
'',
),
); // Возвращаем дефолтное значение или обработку ошибки
}
}
static List<String> languages() => _localizedValues.keys.toList();
String getString(String text) =>
_localizedValues[locale.languageCode]![text] ?? text;
String getString(String text) => _localizedValues[locale.languageCode]![text] ?? text;
}
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalization> {
const AppLocalizationDelegate();
@override
bool isSupported(Locale locale) =>
AppLocalization.languages().contains(locale.languageCode);
bool isSupported(Locale locale) => AppLocalization.languages().contains(locale.languageCode);
//Returning a SynchronousFuture here because an async "load" operation
//cause an async "load" operation

View File

@@ -27,8 +27,7 @@ final Map<String, String> enUs = {
// blood_pressure Screen
"no": "No",
"do_you_have_hypertension_tendency":
"Do you have a tendency for hypertension?",
"do_you_have_hypertension_tendency": "Do you have a tendency for hypertension?",
"your_blood_pressure": "Your blood pressure?",
"average_pressure": "Average pressure:",
"do_you_have_hypotension_tendency": "Do you have a tendency for hypotension?",
@@ -43,13 +42,11 @@ final Map<String, String> enUs = {
// schedule Screen
"your_schedule": "Your Daily Schedule?",
"tell_your_schedule":
"Tell us about your daily routine, when you wake up, eat, and go to sleep:",
"tell_your_schedule": "Tell us about your daily routine, when you wake up, eat, and go to sleep:",
// additional_information Screen
"additional_information": "Additional Information:",
"enter_additional_information":
"Enter any additional information you would like to share:",
"enter_additional_information": "Enter any additional information you would like to share:",
// language_select Screen
"lbl_english": "English",

View File

@@ -57,13 +57,11 @@ final Map<String, String> ru = {
// schedule Screen
"your_schedule": "Ваш режим дня?",
"tell_your_schedule":
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:",
"tell_your_schedule": "Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:",
// additional_information Screen
"additional_information": "Дополнительная информация",
"enter_additional_information":
"Введите любую дополнительную информацию на своё усмотрение:",
"enter_additional_information": "Введите любую дополнительную информацию на своё усмотрение:",
// language_select Screen
"lbl_english": "English",

View File

@@ -1,4 +1,5 @@
import 'package:dio/dio.dart';
import 'package:eatvio_app/core/constants/constants.dart';
import 'package:eatvio_app/core/initialization_cubit/initialization_cubit.dart';
import 'package:eatvio_app/features/blog_post/presentation/bloc/blog_post_cubit.dart';
import 'package:eatvio_app/features/blog_post/repositories/blog_post_repository.dart';
@@ -11,7 +12,9 @@ import 'package:eatvio_app/features/chat/services/chat_service.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
import 'package:eatvio_app/features/feed/repositories/feed_repository.dart';
import 'package:eatvio_app/features/feed/services/feed_service.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:eatvio_app/features/registration/presentation/bloc/registration_cubit/registration_cubit.dart';
import 'package:eatvio_app/features/registration/repositories/registration_repository.dart';
import 'package:eatvio_app/features/registration/services/registration_service.dart';
import 'package:get_it/get_it.dart';
final sl = GetIt.instance;
@@ -22,6 +25,7 @@ Future<void> init() async {
sl.registerLazySingleton<NewMessagesCubit>(() => NewMessagesCubit());
sl.registerLazySingleton<NotificationsCubit>(() => NotificationsCubit());
sl.registerFactory<RegistrationCubit>(() => RegistrationCubit(registrationRepository: sl()));
sl.registerFactory<ChatRoomCubit>(() => ChatRoomCubit(chatRepository: sl(), initializationCubit: sl()));
sl.registerFactory<FeedCubit>(() => FeedCubit(feedRepository: sl()));
sl.registerFactory<BlogPostCubit>(() => BlogPostCubit(blogPostRepository: sl()));
@@ -30,17 +34,19 @@ Future<void> init() async {
sl.registerLazySingleton<ChatRepository>(() => ChatRepository(chatService: sl()));
sl.registerLazySingleton<FeedRepository>(() => FeedRepository(feedService: sl()));
sl.registerLazySingleton<BlogPostRepository>(() => BlogPostRepository(blogPostService: sl()));
sl.registerLazySingleton<RegistrationRepository>(() => RegistrationRepository(registrationService: sl()));
// Services
sl.registerLazySingleton<ChatService>(() => ChatService(sl()));
sl.registerLazySingleton<FeedService>(() => FeedService(sl()));
sl.registerLazySingleton<BlogPostService>(() => BlogPostService(sl()));
sl.registerLazySingleton<RegistrationService>(() => RegistrationService(sl()));
// External
sl.registerLazySingleton(
() => Dio(
BaseOptions(
baseUrl: dotenv.env['SERVER_ROOT']!,
baseUrl: baseUrl,
),
),
);

View File

@@ -6,6 +6,7 @@ import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/noti
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/bloc/chat_select_bloc.dart';
import 'package:eatvio_app/features/chat/presentation/pages/chat_select_screen/models/chat_select_model.dart';
import 'package:eatvio_app/features/feed/presentation/bloc/feed_cubit/feed_cubit.dart';
import 'package:eatvio_app/locator_service.dart' as di;
import 'package:eatvio_app/locator_service.dart';
import 'package:eatvio_app/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart';
import 'package:eatvio_app/presentation/diary/diary_edit_screen/models/diary_edit_model.dart';
@@ -14,12 +15,11 @@ import 'package:eatvio_app/presentation/profile/my_profile_screen/models/my_prof
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'core/app_export.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:keyboard_dismisser/keyboard_dismisser.dart';
import 'package:eatvio_app/locator_service.dart' as di;
import 'package:path_provider/path_provider.dart';
import 'core/app_export.dart';
var globalMessengerKey = GlobalKey<ScaffoldMessengerState>();
@@ -28,7 +28,6 @@ void main() async {
await di.init();
final appDocumentDir = await getApplicationDocumentsDirectory();
final path = appDocumentDir.path;
await dotenv.load(fileName: ".env");
await Hive.initFlutter(path);
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeLeft,
@@ -47,7 +46,6 @@ class MyApp extends StatelessWidget {
BlocProvider<InitializationCubit>(create: (context) => sl<InitializationCubit>()),
BlocProvider<NewMessagesCubit>(create: (context) => sl<NewMessagesCubit>()),
BlocProvider<NotificationsCubit>(create: (context) => sl<NotificationsCubit>()),
BlocProvider<ThemeBloc>(create: (context) => ThemeBloc(ThemeState(themeType: PrefUtils().getThemeData()))),
BlocProvider<FeedCubit>(create: (context) => sl<FeedCubit>()..loadFeedBlogPostList()),
BlocProvider<MyProfileBloc>(create: (context) => MyProfileBloc(MyProfileState(myProfileModelObj: MyProfileModel()))..add(MyProfileInitialEvent())),

View File

@@ -1,21 +1,21 @@
import 'dart:convert';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/core/token_storage.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:eatvio_app/widgets/next_step_button.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'package:validators/validators.dart';
import 'bloc/auth_bloc.dart';
import 'models/auth_model.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
import 'package:validators/validators.dart';
import 'package:eatvio_app/widgets/next_step_button.dart';
import 'package:eatvio_app/widgets/custom_text_form_field.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'dart:convert';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
class AuthScreen extends StatelessWidget {
class AuthScreen extends StatefulWidget {
static Widget builder(BuildContext context) {
return BlocProvider<AuthBloc>(
create: (context) => AuthBloc(
@@ -29,47 +29,57 @@ class AuthScreen extends StatelessWidget {
);
}
@override
State<AuthScreen> createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
bool checkboxState = false;
@override
Widget build(BuildContext context) {
mediaQueryData = MediaQuery.of(context);
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(children: [
SizedBox(height: 36.v),
Text("user_authorization".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 60.v),
Text("email".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
selector: (state) => state.emailController,
builder: (context, emailController) {
return CustomTextFormField(controller: emailController, textInputAction: TextInputAction.done);
},),
SizedBox(height: 22.v),
Text("password".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 5.v),
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
selector: (state) => state.passwordController,
builder: (context, passwordController) {
return CustomTextFormField(
obscureText: true,
controller: passwordController,
);
},),
SizedBox(height: 50.v),
NextStepButton(
text: "no_account".tr.toUpperCase(),
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
onPressed: onTapNoAccount(context),
),
/*NextStepButton(
resizeToAvoidBottomInset: false,
appBar: _buildAppBar(context),
body: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Container(
width: double.maxFinite,
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
child: Column(
children: [
SizedBox(height: 36.v),
Text("user_authorization".tr, style: theme.textTheme.headlineSmall),
SizedBox(height: 60.v),
Text("email".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
selector: (state) => state.emailController,
builder: (context, emailController) {
return CustomTextFormField(controller: emailController, textInputAction: TextInputAction.done);
},
),
SizedBox(height: 22.v),
Text("password".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 5.v),
BlocSelector<AuthBloc, AuthState, TextEditingController?>(
selector: (state) => state.passwordController,
builder: (context, passwordController) {
return CustomTextFormField(
obscureText: true,
controller: passwordController,
);
},
),
SizedBox(height: 50.v),
NextStepButton(
text: "no_account".tr.toUpperCase(),
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
onPressed: onTapNoAccount(context),
),
/*NextStepButton(
text: "Тест дневника".toUpperCase(),
margin:
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
@@ -81,14 +91,21 @@ class AuthScreen extends StatelessWidget {
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
onPressed: onTapProfileTest(context)),*/
BlocBuilder<AuthBloc, AuthState>(builder: (context, state) {
return NextStepButton(
text: "authentificate".tr.toUpperCase(),
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
onPressed: onTapAuth(state, context),);
},),
],),),),);
BlocBuilder<AuthBloc, AuthState>(
builder: (context, state) {
return NextStepButton(
text: "authentificate".tr.toUpperCase(),
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 16.v),
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
onPressed: onTapAuth(state, context),
);
},
),
],
),
),
),
);
}
onTapAuth(AuthState state, BuildContext context) {
@@ -99,15 +116,19 @@ class AuthScreen extends StatelessWidget {
'email': state.emailController!.text,
'password': state.passwordController!.text,
};
final response = await http.post(Uri.parse(dotenv.env['SERVER_ROOT']! + '/login'),
headers: {'Content-Type': 'application/json'}, body: json.encode(credentials), encoding: utf8,);
final response = await http.post(
Uri.parse(baseUrl + '/api/login'),
headers: {'Content-Type': 'application/json'},
body: json.encode(credentials),
encoding: utf8,
);
print(response.statusCode);
if (response.statusCode == 200) {
var res = await jsonDecode(response.body);
final box = await Hive.openBox('token');
final token = res['token'];
box.put('token', token);
TokenStorage.saveTokenInStorage(token);
await TokenStorage.saveTokenInStorage(token);
GoRouter.of(context).go('/my-profile-screen');
} else {
showDialog(
@@ -168,8 +189,11 @@ class AuthScreen extends StatelessWidget {
onTapNoAccount(BuildContext context) {
return () {
GoRouter.of(context).goNamed('languageSelectScreen');
GoRouter.of(context).goNamed('registrationScreen');
};
// return () {
// GoRouter.of(context).goNamed('languageSelectScreen');
// };
}
/// Section Widget

View File

@@ -1,10 +1,10 @@
import 'package:eatvio_app/presentation/auth/auth_screen/models/auth_model.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import '/core/app_export.dart';
import 'package:eatvio_app/presentation/auth/auth_screen/models/auth_model.dart';
part 'auth_event.dart';
part 'auth_state.dart';
/// A bloc that manages the state of a Auth according to the event that is dispatched to it.

View File

@@ -1,14 +1,15 @@
import 'dart:async';
import 'package:intl/intl.dart';
import 'dart:convert';
import 'package:eatvio_app/presentation/diary/diary_edit_screen/models/diary_edit_model.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import '/core/app_export.dart';
import 'package:image_picker/image_picker.dart';
import 'package:eatvio_app/presentation/diary/diary_edit_screen/models/diary_edit_model.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:hive/hive.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'package:intl/intl.dart';
import '/core/app_export.dart';
part 'diary_edit_event.dart';
part 'diary_edit_state.dart';
@@ -148,7 +149,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
fetchDiaryId(String token, Emitter<DiaryEditState> emit) async {
final response = await http.get(
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/index'),
Uri.parse(baseUrl + '/api/diary/index'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
@@ -173,7 +174,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
fetchDiaryData(String token, int diaryId) async {
final response = await http.get(
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/$diaryId/show/'),
Uri.parse(baseUrl + '/api/diary/$diaryId/show/'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
@@ -191,7 +192,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
) async {
final responseChart = await http.get(
Uri.parse(
dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/dailyNutritionData/',
baseUrl + '/api/diary/$diaryID/dailyNutritionData/',
),
headers: {
'Content-Type': 'application/json',
@@ -234,7 +235,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
final box = await Hive.openBox('token');
final token = box.get('token');
final response = await http.get(
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/index'),
Uri.parse(baseUrl + '/api/diary/index'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
@@ -247,7 +248,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
final int diaryId = data['id'];
final diaryResponse = await http.get(
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/$diaryId/show/'),
Uri.parse(baseUrl + '/api/diary/$diaryId/show/'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $token',
@@ -260,7 +261,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
final String diaryDate = diary['date'] ?? DateTime.now().toString();
final responseChart = await http.get(
Uri.parse(
dotenv.env['SERVER_ROOT']! + '/diary/$diaryId/dailyNutritionData/',
baseUrl + '/api/diary/$diaryId/dailyNutritionData/',
),
headers: {
'Content-Type': 'application/json',
@@ -371,7 +372,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
int? mealID,
int diaryID,
) async {
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/meal/$mealID/satiety/fill';
String url = baseUrl + '/api/diary/$diaryID/meal/$mealID/satiety/fill';
final Map<String, dynamic> credentials = {
'satiety': selectedSatiety,
};
@@ -419,7 +420,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
int? mealID,
int diaryID,
) async {
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/meal/$mealID/mood/fill';
String url = baseUrl + '/api/diary/$diaryID/meal/$mealID/mood/fill';
final Map<String, dynamic> credentials = {
'mood': selectedMood,
};
@@ -484,7 +485,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
TimeOfDay wakeup,
int diaryID,
) async {
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/wakeUp/fill';
String url = baseUrl + '/api/diary/$diaryID/wakeUp/fill';
final formatter = DateFormat('HH:mm');
final wakeupString = formatter.format(DateTime(2022, 1, 1, wakeup.hour, wakeup.minute));
final Map<String, dynamic> credentials = {
@@ -509,7 +510,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
TimeOfDay retire,
int diaryID,
) async {
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/retire/fill';
String url = baseUrl + '/api/diary/$diaryID/retire/fill';
final formatter = DateFormat('HH:mm');
final retireString = formatter.format(DateTime(2022, 1, 1, retire.hour, retire.minute));
final Map<String, dynamic> credentials = {
@@ -547,7 +548,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
int? mealID,
int diaryID,
) async {
String url = dotenv.env['SERVER_ROOT']! + '/diary/???';
String url = baseUrl + '/api/diary/???';
final Map<String, dynamic> credentials = {
'time': mealTime,
'meal_id': mealID,
@@ -674,7 +675,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
int? mealID,
int diaryID,
) async {
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/portions/create';
String url = '${baseUrl}/api/diary/$diaryID/meal/$mealID/portions/create';
final Map<String, dynamic> credentials = {
'product_name': name,
@@ -705,7 +706,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
final Map<String, dynamic> credentials = {'name': event.input};
final uri = Uri.parse(
'${dotenv.env['SERVER_ROOT']!}/diary/product_nutritional_values/filter?${Uri(queryParameters: credentials).query}',
'${baseUrl}/api/diary/product_nutritional_values/filter?${Uri(queryParameters: credentials).query}',
);
final response = await http.get(
@@ -767,7 +768,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
int? mealID,
int diaryID,
) async {
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/portions/$portionID/delete';
String url = '${baseUrl}/api/diary/$diaryID/meal/$mealID/portions/$portionID/delete';
var response = await http.delete(
Uri.parse(url),
@@ -813,7 +814,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
int? mealID,
int diaryID,
) async {
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealID/photo/delete';
String url = '${baseUrl}/api/diary/$diaryID/meal/$mealID/photo/delete';
final Map<String, dynamic> credentials = {
'id': photoID,
'path': path,
@@ -866,7 +867,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
'comment': comment ?? " ",
};
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/finishDay';
String url = '${baseUrl}/api/diary/$diaryID/finishDay';
var response = await http.post(
Uri.parse(url),
@@ -905,7 +906,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
int mealId,
String? token,
) async {
String url = '${dotenv.env['SERVER_ROOT']!}/diary/$diaryID/meal/$mealId/photo/upload';
String url = '${baseUrl}/api/diary/$diaryID/meal/$mealId/photo/upload';
var request = http.MultipartRequest('POST', Uri.parse(url));
request.headers['Authorization'] = 'Bearer $token';
@@ -958,9 +959,9 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
String? token,
) async {
final Uri url = Uri.parse(
'${dotenv.env['SERVER_ROOT']!}/diary/product_nutritional_values/sendToModeration',
'${baseUrl}/api/diary/product_nutritional_values/sendToModeration',
);
final Uri serverURL = Uri.parse('${dotenv.env['SERVER_ROOT']!}');
final Uri serverURL = Uri.parse('${baseUrl}');
String host = serverURL.host;
final Map<String, String> credentials = {
'name': name,
@@ -1020,7 +1021,7 @@ class DiaryEditBloc extends Bloc<DiaryEditEvent, DiaryEditState> {
String comment,
int diaryID,
) async {
String url = dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/retire/fill';
String url = baseUrl + '/api/diary/$diaryID/retire/fill';
final Map<String, dynamic> credentials = {
'comment': comment,
};

View File

@@ -122,7 +122,6 @@ class ChangeMeal extends DiaryEditEvent {
List<Object?> get props => [value, meals];
}
class ClearInput extends DiaryEditEvent {
ClearInput({required this.value});
@@ -154,18 +153,18 @@ class RefreshEvent extends DiaryEditEvent {
}
class SendModeration extends DiaryEditEvent {
SendModeration(
{required this.name,
required this.energyOn100gr,
required this.proteinsOn100gr,
required this.fatsOn100gr,
required this.carbohydratesOn100gr,});
SendModeration({
required this.name,
required this.energyOn100gr,
required this.proteinsOn100gr,
required this.fatsOn100gr,
required this.carbohydratesOn100gr,
});
String name;
String energyOn100gr;
String proteinsOn100gr;
String fatsOn100gr;
String carbohydratesOn100gr;
@override
List<Object?> get props =>
[name, energyOn100gr, proteinsOn100gr, fatsOn100gr, carbohydratesOn100gr];
List<Object?> get props => [name, energyOn100gr, proteinsOn100gr, fatsOn100gr, carbohydratesOn100gr];
}

View File

@@ -1,19 +1,19 @@
// ignore_for_file: unused_local_variable
import 'bloc/diary_edit_bloc.dart';
import 'models/diary_edit_model.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/custom_edit_drop_down.dart';
import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/widgets/custom_scale_element.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart';
import 'package:eatvio_app/widgets/custom_edit_drop_down.dart';
import 'package:eatvio_app/widgets/custom_outlined_button.dart';
import 'package:eatvio_app/widgets/custom_scale_element.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'bloc/diary_edit_bloc.dart';
import 'models/diary_edit_model.dart';
// ignore: must_be_immutable
class DiaryEditScreen extends StatelessWidget {
@@ -711,7 +711,7 @@ class DiaryEditScreen extends StatelessWidget {
borderRadius: BorderRadiusStyle.roundedBorder5,
),
child: Image.network(
dotenv.env['STORAGE_URL']! + photo['path'],
baseUrl + '/storage/' + photo['path'],
),
),
Positioned(

View File

@@ -1,7 +1,7 @@
// ignore_for_file: must_be_immutable
import 'package:equatable/equatable.dart';
import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
import 'package:equatable/equatable.dart';
/// This class defines the variables used in the [k0_page],
/// and is typically used to hold data that is passed between different parts of the application.

View File

@@ -1,15 +1,15 @@
import 'dart:async';
import 'dart:convert';
import 'package:eatvio_app/app_router.dart';
import 'package:eatvio_app/presentation/diets/diet_create_screen/models/diet_create_model.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:go_router/go_router.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import '/core/app_export.dart';
import 'package:eatvio_app/presentation/diets/diet_create_screen/models/diet_create_model.dart';
part 'diet_create_event.dart';
part 'diet_create_state.dart';
@@ -32,21 +32,27 @@ class DietCreateBloc extends Bloc<DietCreateEvent, DietCreateState> {
}
if (state is DietCreateLoadedState) {
var currentState = state as DietCreateLoadedState;
emit(currentState.copyWith(
dietModelObj: currentState.dietModelObj,
name: currentState.name,
details: currentState.details,
),);
emit(
currentState.copyWith(
dietModelObj: currentState.dietModelObj,
name: currentState.name,
details: currentState.details,
),
);
} else {
emit(DietCreateLoadedState(
name: TextEditingController(),
details: TextEditingController(),
),);
emit(
DietCreateLoadedState(
name: TextEditingController(),
details: TextEditingController(),
),
);
}
}
FutureOr<void> _createDiet(
CreateDiet event, Emitter<DietCreateState> emit,) async {
CreateDiet event,
Emitter<DietCreateState> emit,
) async {
if (state is DietCreateLoadedState) {
var currentState = state as DietCreateLoadedState;
@@ -59,7 +65,8 @@ class DietCreateBloc extends Bloc<DietCreateEvent, DietCreateState> {
AppRouter.navigatorKey.currentContext?.goNamed('dietSelectScreen');
} else {
print(
'Failed to create blog post. Status Code: ${response.statusCode} ${response.body}',);
'Failed to create blog post. Status Code: ${response.statusCode} ${response.body}',
);
}
}
}
@@ -68,7 +75,7 @@ class DietCreateBloc extends Bloc<DietCreateEvent, DietCreateState> {
String? name,
String? details,
) async {
String url = '${dotenv.env['SERVER_ROOT']!}/diets/create';
String url = '${baseUrl}/api/diets/create';
final Map<String, dynamic> credentials = {
'name': name,

View File

@@ -60,6 +60,5 @@ class DietCreateErrorState extends DietCreateState {
}
class DietCreateInitialState extends DietCreateState {
DietCreateInitialState({required DietCreateModel dietModelObj})
: super(dietModelObj: dietModelObj);
DietCreateInitialState({required DietCreateModel dietModelObj}) : super(dietModelObj: dietModelObj);
}

View File

@@ -1,16 +1,18 @@
import 'bloc/diet_create_bloc.dart';
import 'models/diet_create_model.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter/material.dart';
import 'bloc/diet_create_bloc.dart';
import 'models/diet_create_model.dart';
class DietCreateScreen extends StatelessWidget {
const DietCreateScreen({Key? key}) : super(key: key);
static Widget builder(BuildContext context) {
final dietID = ModalRoute.of(context)!.settings.arguments;
return BlocProvider<DietCreateBloc>(
create: (context) => DietCreateBloc(DietCreateState(dietModelObj: DietCreateModel(dietID: dietID.toString())))..add(DietCreateInitialEvent()),
child: DietCreateScreen(),);
create: (context) => DietCreateBloc(DietCreateState(dietModelObj: DietCreateModel(dietID: dietID.toString())))..add(DietCreateInitialEvent()),
child: DietCreateScreen(),
);
}
Widget build(BuildContext context) {
@@ -43,47 +45,52 @@ class DietCreateScreen extends StatelessWidget {
body: Container(
width: double.maxFinite,
decoration: AppDecoration.fillGray,
child: ListView(children: [
SizedBox(height: 30.v),
Container(
margin: EdgeInsets.only(
left: 16.h,
right: 20.h,
bottom: 10.h,
child: ListView(
children: [
SizedBox(height: 30.v),
Container(
margin: EdgeInsets.only(
left: 16.h,
right: 20.h,
bottom: 10.h,
),
padding: EdgeInsets.all(12.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 16.0),
TextFormField(
controller: state.name,
decoration: InputDecoration(labelText: 'Заголовок'),
),
SizedBox(height: 16.0),
TextFormField(
controller: state.details,
decoration: InputDecoration(labelText: 'Описание'),
),
SizedBox(height: 16.0),
// Здесь нужно добавить виджет для загрузки картинки
ElevatedButton(
onPressed: () => context.read<DietCreateBloc>().add(CreateDiet()),
child: Text('Создать'),
),
],
),
),
padding: EdgeInsets.all(12.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: const BorderRadius.all(Radius.circular(12)),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 3),
),
],
),
child: Column(mainAxisSize: MainAxisSize.min, children: [
SizedBox(height: 16.0),
TextFormField(
controller: state.name,
decoration: InputDecoration(labelText: 'Заголовок'),
),
SizedBox(height: 16.0),
TextFormField(
controller: state.details,
decoration: InputDecoration(labelText: 'Описание'),
),
SizedBox(height: 16.0),
// Здесь нужно добавить виджет для загрузки картинки
ElevatedButton(
onPressed: () => context.read<DietCreateBloc>().add(CreateDiet()),
child: Text('Создать'),
),
],),
),
],),
],
),
),
),
);

View File

@@ -1,18 +1,17 @@
import 'dart:async';
import 'dart:convert';
import 'package:eatvio_app/app_router.dart';
import 'package:eatvio_app/presentation/diets/diet_edit_screen/models/diet_edit_model.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:go_router/go_router.dart';
import 'package:hive/hive.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import '/core/app_export.dart';
import 'package:eatvio_app/presentation/diets/diet_edit_screen/models/diet_edit_model.dart';
part 'diet_edit_event.dart';
part 'diet_edit_state.dart';
/// A bloc that manages the state of a DietEdit according to the event that is dispatched to it.
@@ -34,7 +33,7 @@ class DietEditBloc extends Bloc<DietEditEvent, DietEditState> {
}
final String? dietID = state.dietModelObj?.dietID;
final response = await http.get(
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diets/show/$dietID'),
Uri.parse(baseUrl + '/api/diets/show/$dietID'),
headers: {
'Authorization': 'Bearer $token',
},
@@ -44,18 +43,24 @@ class DietEditBloc extends Bloc<DietEditEvent, DietEditState> {
if (data is Map<String, dynamic>) {
if (state is DietEditLoadedState) {
var currentState = state as DietEditLoadedState;
emit(currentState.copyWith(
emit(
currentState.copyWith(
dietModelObj: currentState.dietModelObj,
diet: currentState.diet,
name: currentState.name,
duration: currentState.duration,
details: currentState.details,),);
details: currentState.details,
),
);
} else {
emit(DietEditLoadedState(
emit(
DietEditLoadedState(
diet: data,
name: TextEditingController(text: data['name']),
details: TextEditingController(text: data['details']),
duration: TextEditingController(text: data['duration']),),);
duration: TextEditingController(text: data['duration']),
),
);
}
} else {
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку
@@ -96,7 +101,7 @@ class DietEditBloc extends Bloc<DietEditEvent, DietEditState> {
String? duration,
) async {
int id = diet?['id'];
String url = '${dotenv.env['SERVER_ROOT']!}/diets/update/$id';
String url = '${baseUrl}/api/diets/update/$id';
final Map<String, dynamic> credentials = {
'id': id,

View File

@@ -22,8 +22,13 @@ class DietEditState extends Equatable {
}
class DietEditLoadedState extends DietEditState {
DietEditLoadedState(
{this.dietModelObj, this.diet, this.name, this.details, this.duration,});
DietEditLoadedState({
this.dietModelObj,
this.diet,
this.name,
this.details,
this.duration,
});
DietEditModel? dietModelObj;
Map<String, dynamic>? diet;
@@ -59,6 +64,5 @@ class DietEditErrorState extends DietEditState {
}
class DietEditInitialState extends DietEditState {
DietEditInitialState({required DietEditModel dietModelObj})
: super(dietModelObj: dietModelObj);
DietEditInitialState({required DietEditModel dietModelObj}) : super(dietModelObj: dietModelObj);
}

View File

@@ -1,9 +1,9 @@
import 'bloc/diet_edit_bloc.dart';
import 'models/diet_edit_model.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:eatvio_app/core/app_export.dart';
import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'bloc/diet_edit_bloc.dart';
import 'models/diet_edit_model.dart';
class DietEditScreen extends StatelessWidget {
const DietEditScreen({Key? key}) : super(key: key);
@@ -11,8 +11,9 @@ class DietEditScreen extends StatelessWidget {
static Widget builder(BuildContext context) {
final dietID = ModalRoute.of(context)!.settings.arguments;
return BlocProvider<DietEditBloc>(
create: (context) => DietEditBloc(DietEditState(dietModelObj: DietEditModel(dietID: dietID.toString())))..add(DietEditInitialEvent()),
child: DietEditScreen(),);
create: (context) => DietEditBloc(DietEditState(dietModelObj: DietEditModel(dietID: dietID.toString())))..add(DietEditInitialEvent()),
child: DietEditScreen(),
);
}
Widget build(BuildContext context) {
@@ -71,7 +72,7 @@ class DietEditScreen extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
CachedNetworkImage(
imageUrl: dotenv.env['STORAGE_URL']! + (state.diet?['image'] ?? ''),
imageUrl: baseUrl + '/storage/' + (state.diet?['image'] ?? ''),
imageBuilder: (context, imageProvider) => CircleAvatar(
backgroundImage: imageProvider,
radius: 25,

Some files were not shown because too many files have changed in this diff Show More