From e180ff16b60cb91222ea35a1fde020c7632f9ffb Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 9 Jul 2024 17:50:32 +0300 Subject: [PATCH] refactor(all): refactor --- lib/app_router.dart | 41 +- .../initialization_cubit.dart | 84 ++-- .../chat/presentation/pages/chat_screen.dart | 2 - .../chat_select_screen.dart | 30 +- .../models/feed_blog_post_settings_model.dart | 15 + ...feed_blog_post_settings_model.freezed.dart | 175 ++++++++ .../feed_blog_post_settings_model.g.dart | 21 + .../feed/repositories/feed_repository.dart | 2 +- lib/features/feed/services/feed_service.dart | 6 +- .../feed/services/feed_service.g.dart | 9 +- lib/main.dart | 1 - .../auth/auth_screen/auth_screen.dart | 2 +- .../bloc/my_profile_bloc.dart | 28 +- .../my_profile_screen/my_profile_screen.dart | 382 ++++++++++-------- .../bloc/recipe_edit_bloc.dart | 42 +- .../bloc/recipe_select_bloc.dart | 26 +- .../bloc/recipe_select_state.dart | 6 +- .../recipe_select_screen.dart | 1 + .../bloc/recipe_show_bloc.dart | 49 ++- .../additional_information_screen.dart | 166 +++++--- .../allergies_screen/allergies_screen.dart | 116 +++--- .../blood_pressure_screen.dart | 255 +++++++----- .../body_circumferences_screen.dart | 137 ++++--- .../city_of_living_screen.dart | 124 +++--- .../credentials_screen.dart | 143 ++++--- .../date_of_birth_screen.dart | 94 +++-- .../favorite_foods_screen.dart | 151 ++++--- .../favorite_sports_screen.dart | 124 +++--- .../gender_screen/gender_screen.dart | 70 ++-- .../height_screen/height_screen.dart | 42 +- .../language_select_screen.dart | 45 ++- .../medicine_intake_screen.dart | 136 ++++--- .../registration/name_screen/name_screen.dart | 125 +++--- .../weight_screen/weight_screen.dart | 42 +- lib/theme/theme_helper.dart | 113 +++--- lib/widgets/custom_navigation_menu_item.dart | 8 +- pubspec.yaml | 16 +- 37 files changed, 1706 insertions(+), 1123 deletions(-) create mode 100644 lib/features/feed/models/feed_blog_post_settings_model.dart create mode 100644 lib/features/feed/models/feed_blog_post_settings_model.freezed.dart create mode 100644 lib/features/feed/models/feed_blog_post_settings_model.g.dart diff --git a/lib/app_router.dart b/lib/app_router.dart index 02c517f..20905a6 100644 --- a/lib/app_router.dart +++ b/lib/app_router.dart @@ -48,7 +48,6 @@ class AppRouter { name: 'authScreen', redirect: (context, state) async { if (await TokenStorage.haveTokenInStorage()) { - await context.read().runInitialization(); return '/my-profile-screen'; } return null; @@ -106,29 +105,31 @@ class AppRouter { builder: (context, state) => BloodPressureScreen.builder(context, state.extra), routes: [ GoRoute( - path: 'favorite-sports-screen', - name: 'favoriteSportsScreen', - builder: (context, state) => FavoriteSportsScreen.builder(context, state.extra), + name: 'allergiesScreen', + path: 'allergiesScreen', + builder: (context, state) => AllergiesScreen.builder(context, state.extra), routes: [ GoRoute( - name: 'allergiesScreen', - path: 'allergiesScreen', - builder: (context, state) => AllergiesScreen.builder(context, state.extra), + name: 'medicineIntakeScreen', + path: 'medicine-intake-screen', + builder: (context, state) => MedicineIntakeScreen.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), + path: 'favorite-sports-screen', + name: 'favoriteSportsScreen', + builder: (context, state) => FavoriteSportsScreen.builder(context, state.extra), routes: [ GoRoute( - path: 'additional-information-screen', - name: 'additionalInformationScreen', - builder: (context, state) => AdditionalInformationScreen.builder(context, state.extra), + 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), + ), + ], ), ], ), @@ -166,6 +167,10 @@ class AppRouter { GoRoute( path: '/my-profile-screen', name: 'myProfileScreen', + redirect: (context, state) async { + await context.read().runInitialization(); + return null; + }, builder: (context, state) => MyProfileScreen(), ), GoRoute( diff --git a/lib/core/initialization_cubit/initialization_cubit.dart b/lib/core/initialization_cubit/initialization_cubit.dart index a7034e2..2052a25 100644 --- a/lib/core/initialization_cubit/initialization_cubit.dart +++ b/lib/core/initialization_cubit/initialization_cubit.dart @@ -9,6 +9,7 @@ import 'package:eatvio_app/locator_service.dart'; class InitializationCubit extends Cubit { final ChatRepository chatRepository; + bool wasInitializated = false; InitializationCubit({required this.chatRepository}) : super(const InitializationState.loading()); @@ -49,48 +50,51 @@ class InitializationCubit extends Cubit { } Future 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; + } } } } diff --git a/lib/features/chat/presentation/pages/chat_screen.dart b/lib/features/chat/presentation/pages/chat_screen.dart index d3ecef8..208ff96 100644 --- a/lib/features/chat/presentation/pages/chat_screen.dart +++ b/lib/features/chat/presentation/pages/chat_screen.dart @@ -179,7 +179,6 @@ class _ChatScreenState extends State { keyboardType: TextInputType.multiline, style: TextStyle( fontSize: 16, - fontFamily: 'Mulish', fontWeight: FontWeight.w400, color: Colors.black, ), @@ -188,7 +187,6 @@ class _ChatScreenState extends State { hintText: 'Сообщение', hintStyle: TextStyle( fontSize: 16, - fontFamily: 'Mulish', fontWeight: FontWeight.w400, color: Color(0xFFAEAEB2), ), diff --git a/lib/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart b/lib/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart index d98ea7f..dc3f3d2 100644 --- a/lib/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart +++ b/lib/features/chat/presentation/pages/chat_select_screen/chat_select_screen.dart @@ -42,18 +42,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), + ), + ), ), ), ), diff --git a/lib/features/feed/models/feed_blog_post_settings_model.dart b/lib/features/feed/models/feed_blog_post_settings_model.dart new file mode 100644 index 0000000..fa72e97 --- /dev/null +++ b/lib/features/feed/models/feed_blog_post_settings_model.dart @@ -0,0 +1,15 @@ +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 feedBlogPostList, + }) = _FeedBlogPostSettingsModel; + + factory FeedBlogPostSettingsModel.fromJson(Map json) => _$FeedBlogPostSettingsModelFromJson(json); +} diff --git a/lib/features/feed/models/feed_blog_post_settings_model.freezed.dart b/lib/features/feed/models/feed_blog_post_settings_model.freezed.dart new file mode 100644 index 0000000..7fd8a12 --- /dev/null +++ b/lib/features/feed/models/feed_blog_post_settings_model.freezed.dart @@ -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 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 json) { + return _FeedBlogPostSettingsModel.fromJson(json); +} + +/// @nodoc +mixin _$FeedBlogPostSettingsModel { + @JsonKey(name: 'data') + List get feedBlogPostList => + throw _privateConstructorUsedError; + + Map toJson() => throw _privateConstructorUsedError; + @JsonKey(ignore: true) + $FeedBlogPostSettingsModelCopyWith 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 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, + ) 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 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, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$FeedBlogPostSettingsModelImpl implements _FeedBlogPostSettingsModel { + const _$FeedBlogPostSettingsModelImpl( + {@JsonKey(name: 'data') + required final List feedBlogPostList}) + : _feedBlogPostList = feedBlogPostList; + + factory _$FeedBlogPostSettingsModelImpl.fromJson(Map json) => + _$$FeedBlogPostSettingsModelImplFromJson(json); + + final List _feedBlogPostList; + @override + @JsonKey(name: 'data') + List 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 toJson() { + return _$$FeedBlogPostSettingsModelImplToJson( + this, + ); + } +} + +abstract class _FeedBlogPostSettingsModel implements FeedBlogPostSettingsModel { + const factory _FeedBlogPostSettingsModel( + {@JsonKey(name: 'data') + required final List feedBlogPostList}) = + _$FeedBlogPostSettingsModelImpl; + + factory _FeedBlogPostSettingsModel.fromJson(Map json) = + _$FeedBlogPostSettingsModelImpl.fromJson; + + @override + @JsonKey(name: 'data') + List get feedBlogPostList; + @override + @JsonKey(ignore: true) + _$$FeedBlogPostSettingsModelImplCopyWith<_$FeedBlogPostSettingsModelImpl> + get copyWith => throw _privateConstructorUsedError; +} diff --git a/lib/features/feed/models/feed_blog_post_settings_model.g.dart b/lib/features/feed/models/feed_blog_post_settings_model.g.dart new file mode 100644 index 0000000..3f48be1 --- /dev/null +++ b/lib/features/feed/models/feed_blog_post_settings_model.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'feed_blog_post_settings_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$FeedBlogPostSettingsModelImpl _$$FeedBlogPostSettingsModelImplFromJson( + Map json) => + _$FeedBlogPostSettingsModelImpl( + feedBlogPostList: (json['data'] as List) + .map((e) => FeedBlogPostModel.fromJson(e as Map)) + .toList(), + ); + +Map _$$FeedBlogPostSettingsModelImplToJson( + _$FeedBlogPostSettingsModelImpl instance) => + { + 'data': instance.feedBlogPostList, + }; diff --git a/lib/features/feed/repositories/feed_repository.dart b/lib/features/feed/repositories/feed_repository.dart index 50799a0..319ac32 100644 --- a/lib/features/feed/repositories/feed_repository.dart +++ b/lib/features/feed/repositories/feed_repository.dart @@ -8,7 +8,7 @@ class FeedRepository { Future> getFeedBlogPostList() async { try { - return (await feedService.getBlocPostList()).entries.map((entry) => entry.value).toList(); + return (await feedService.getBlocPostList()).feedBlogPostList; } catch (e) { rethrow; } diff --git a/lib/features/feed/services/feed_service.dart b/lib/features/feed/services/feed_service.dart index d4f728f..a961037 100644 --- a/lib/features/feed/services/feed_service.dart +++ b/lib/features/feed/services/feed_service.dart @@ -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> getBlocPostList(); + @GET('/blogPosts/index') + Future getBlocPostList(); } diff --git a/lib/features/feed/services/feed_service.g.dart b/lib/features/feed/services/feed_service.g.dart index 03aa238..2ef8381 100644 --- a/lib/features/feed/services/feed_service.g.dart +++ b/lib/features/feed/services/feed_service.g.dart @@ -19,20 +19,20 @@ class _FeedService implements FeedService { String? baseUrl; @override - Future> getBlocPostList() async { + Future getBlocPostList() async { final _extra = {}; final queryParameters = {}; final _headers = {}; const Map? _data = null; final _result = await _dio.fetch>( - _setStreamType>(Options( + _setStreamType(Options( method: 'GET', headers: _headers, extra: _extra, ) .compose( _dio.options, - '/feed/index', + '/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))); + final _value = FeedBlogPostSettingsModel.fromJson(_result.data!); return _value; } diff --git a/lib/main.dart b/lib/main.dart index e73bd42..7faced2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -47,7 +47,6 @@ class MyApp extends StatelessWidget { BlocProvider(create: (context) => sl()), BlocProvider(create: (context) => sl()), BlocProvider(create: (context) => sl()), - BlocProvider(create: (context) => ThemeBloc(ThemeState(themeType: PrefUtils().getThemeData()))), BlocProvider(create: (context) => sl()..loadFeedBlogPostList()), BlocProvider(create: (context) => MyProfileBloc(MyProfileState(myProfileModelObj: MyProfileModel()))..add(MyProfileInitialEvent())), diff --git a/lib/presentation/auth/auth_screen/auth_screen.dart b/lib/presentation/auth/auth_screen/auth_screen.dart index 4a74ba3..c435f2d 100644 --- a/lib/presentation/auth/auth_screen/auth_screen.dart +++ b/lib/presentation/auth/auth_screen/auth_screen.dart @@ -107,7 +107,7 @@ class AuthScreen extends StatelessWidget { 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( diff --git a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart index 806768c..af1c558 100644 --- a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart +++ b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart @@ -74,20 +74,16 @@ class MyProfileBloc extends Bloc { waistCircumferenceController: TextEditingController(), hipCircumferenceController: TextEditingController(), weightController: TextEditingController(), - chestCircumferenceFormController: - currentState.chestCircumferenceFormController, - waistCircumferenceFormController: - currentState.waistCircumferenceFormController, - hipCircumferenceFormController: - currentState.hipCircumferenceFormController, + chestCircumferenceFormController: currentState.chestCircumferenceFormController, + waistCircumferenceFormController: currentState.waistCircumferenceFormController, + hipCircumferenceFormController: currentState.hipCircumferenceFormController, firstNameFormController: currentState.firstNameFormController, lastNameFormController: currentState.lastNameFormController, countryFormController: currentState.countryFormController, cityFormController: currentState.cityFormController, heightFormController: currentState.heightFormController, upPressureFormController: currentState.upPressureFormController, - downPressureFormController: - currentState.downPressureFormController, + downPressureFormController: currentState.downPressureFormController, allergiesFormController: currentState.allergiesFormController, pillsFormController: currentState.pillsFormController, favoriteFormController: currentState.favoriteFormController, @@ -181,8 +177,7 @@ class MyProfileBloc extends Bloc { waistCircumferenceController: TextEditingController(), hipCircumferenceController: TextEditingController(), hypoFormController: data['userDetails']['has_hypo'].toString(), - hyperFormController: - data['userDetails']['has_hyper'].toString(), + hyperFormController: data['userDetails']['has_hyper'].toString(), chestCircumferenceFormController: TextEditingController( text: data['userDetails']['chest_circumference']?.toString(), ), @@ -201,12 +196,9 @@ class MyProfileBloc extends Bloc { firstNameFormController: TextEditingController( text: data['userDetails']['first_name'], ), - lastNameFormController: TextEditingController( - text: data['userDetails']['last_name']), - countryFormController: - TextEditingController(text: data['userDetails']['country']), - cityFormController: - TextEditingController(text: data['userDetails']['city']), + lastNameFormController: TextEditingController(text: data['userDetails']['last_name']), + countryFormController: TextEditingController(text: data['userDetails']['country']), + cityFormController: TextEditingController(text: data['userDetails']['city']), heightFormController: TextEditingController( text: data['userDetails']['height']?.toString(), ), @@ -234,8 +226,7 @@ class MyProfileBloc extends Bloc { additionalFormController: TextEditingController( text: data['userDetails']['additional_info'], ), - dateFormController: TextEditingController( - text: data['userDetails']['birthdate']), + dateFormController: TextEditingController(text: data['userDetails']['birthdate']), selectedCity: data['userDetails']['city'], selectedCountry: data['userDetails']['country'], selectedActivity: determineActivityLevel( @@ -282,6 +273,7 @@ class MyProfileBloc extends Bloc { var currentState = state as MyProfileLoadedState; await uploadImageToServer(event.image.path, currentState.token); + this.add(MyProfileInitialEvent()); } } diff --git a/lib/presentation/profile/my_profile_screen/my_profile_screen.dart b/lib/presentation/profile/my_profile_screen/my_profile_screen.dart index 8df3294..9aeb496 100644 --- a/lib/presentation/profile/my_profile_screen/my_profile_screen.dart +++ b/lib/presentation/profile/my_profile_screen/my_profile_screen.dart @@ -96,6 +96,27 @@ class MyProfileScreen extends StatelessWidget { ), SizedBox(height: 15.v), Container( + padding: EdgeInsets.symmetric( + horizontal: 24.h, + vertical: 12.v, + ), + 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: _buildCarousel(context, state), + ), + SizedBox(height: 15.v), + if (!state.plans!.isEmpty) + Container( padding: EdgeInsets.symmetric( horizontal: 24.h, vertical: 12.v, @@ -112,32 +133,13 @@ class MyProfileScreen extends StatelessWidget { ), ], ), - child: _buildCarousel(context, state),), - SizedBox(height: 15.v), - if (!state.plans!.isEmpty) - Container( - padding: EdgeInsets.symmetric( - horizontal: 24.h, - vertical: 12.v, - ), - 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: _buildPlans( - context, - state.plans?.map((plan) => plan['name']).toList(), - state.plans?.map((plan) => plan['image']).toList(), - state.plans?.map((plan) => plan['state']).toList(), - ),), + child: _buildPlans( + context, + state.plans?.map((plan) => plan['name']).toList(), + state.plans?.map((plan) => plan['image']).toList(), + state.plans?.map((plan) => plan['state']).toList(), + ), + ), SizedBox(height: 5.v), ], ), @@ -176,11 +178,9 @@ class MyProfileScreen extends StatelessWidget { addImage(BuildContext context) async { final picker = ImagePicker(); - List? images = await picker.pickMultiImage(); - if (images.isNotEmpty) { - for (var image in images) { - context.read().add(UploadAvatar(image)); - } + XFile? image = await picker.pickImage(source: ImageSource.gallery); + if (image != null) { + context.read().add(UploadAvatar(image)); } } @@ -199,8 +199,9 @@ class MyProfileScreen extends StatelessWidget { switch (chartType) { case 1: // График веса return GestureDetector( - onTap: () => _editWeight(context, state), - child: Column(children: [ + onTap: () => _editWeight(context, state), + child: Column( + children: [ Text( "weight_chart".tr, style: CustomTextStyles.titleMediumBlack.copyWith( @@ -213,26 +214,34 @@ class MyProfileScreen extends StatelessWidget { state.chartPoints?.values.map((e) => e['weight']).toList().map((i) => i.toDouble()).toList() ?? [0.0, 0.0, 0.0, 0.0], state.chartDates, ), - ],),); - case 2: // График ИМТ - return Column(children: [ - Text( - "bodymass_chart".tr, - style: CustomTextStyles.titleMediumBlack.copyWith( - color: appTheme.black900, - ), + ], ), - SizedBox(height: 50.v), - _buildChart( + ); + case 2: // График ИМТ + return Column( + children: [ + Text( + "bodymass_chart".tr, + style: CustomTextStyles.titleMediumBlack.copyWith( + color: appTheme.black900, + ), + ), + SizedBox(height: 50.v), + _buildChart( context, - _bodyMassIndex(state.chartPoints?.values.map((e) => e['weight']).toList().map((i) => i.toDouble()).toList() ?? [0.0, 0.0, 0.0, 0.0], - state.userDetails?['height'].toInt() ?? 160,), - state.chartDates,), - ],); + _bodyMassIndex( + state.chartPoints?.values.map((e) => e['weight']).toList().map((i) => i.toDouble()).toList() ?? [0.0, 0.0, 0.0, 0.0], + state.userDetails?['height'].toInt() ?? 160, + ), + state.chartDates, + ), + ], + ); case 3: //График обхватов return GestureDetector( - onTap: () => _editCircumference(context, state), - child: Column(children: [ + onTap: () => _editCircumference(context, state), + child: Column( + children: [ Text( "circumferences_chart".tr, style: CustomTextStyles.titleMediumBlack.copyWith( @@ -242,7 +251,9 @@ class MyProfileScreen extends StatelessWidget { SizedBox(height: 30.v), _buildCircumferenceChart(context, state.circumferences, state.chartDates), _buildChartLegend(), - ],),); + ], + ), + ); default: return Text('text', style: TextStyle(fontSize: 16.0)); } @@ -636,79 +647,108 @@ class MyProfileScreen extends StatelessWidget { /// Section Widget _buildPlans(BuildContext context, List? plans, List? imagePaths, List? states) { return Padding( - padding: EdgeInsets.only(left: 7.h), - child: Column(children: [ + padding: EdgeInsets.only(left: 7.h), + child: Column( + children: [ Padding( - padding: EdgeInsets.only(left: 15.h), - child: Text("plans_complete".tr, style: CustomTextStyles.titleMediumBlack.copyWith(color: appTheme.black900)),), + padding: EdgeInsets.only(left: 15.h), + child: Text("plans_complete".tr, style: CustomTextStyles.titleMediumBlack.copyWith(color: appTheme.black900)), + ), SizedBox(height: 5.v), Container( - decoration: AppDecoration.outlineBlueGray.copyWith(borderRadius: BorderRadiusStyle.roundedBorder5), - child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + decoration: AppDecoration.outlineBlueGray.copyWith(borderRadius: BorderRadiusStyle.roundedBorder5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ SizedBox( - height: 105.v, - width: 343.h, - child: Stack(alignment: Alignment.bottomCenter, children: [ + height: 105.v, + width: 343.h, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ Align( - alignment: Alignment.topCenter, - child: ListView.builder( - itemCount: plans?.length ?? 0, - itemBuilder: (context, i) { - String state = states?[i]; - var boxColor = appTheme.greenA700; - switch (states?[i]) { - case 'active': - boxColor = appTheme.greenA700; - break; - case 'archived': // График ИМТ - boxColor = appTheme.gray400; - break; - case 'draft': - boxColor = appTheme.deepOrange900; - break; - case 'in_progress': //График обхватов - boxColor = appTheme.lightGreen300; - break; - } - return SizedBox( - height: 40.v, - width: 343.h, - child: Stack(alignment: Alignment.bottomRight, children: [ - Align( - alignment: Alignment.topCenter, - child: Container( - margin: EdgeInsets.only(bottom: 11.v), - padding: EdgeInsets.symmetric(horizontal: 6.h, vertical: 4.v), - decoration: AppDecoration.fillGray.copyWith(borderRadius: BorderRadiusStyle.roundedBorder5), - child: Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Padding( - padding: EdgeInsets.only(bottom: 1.v), - child: Text(plans![i], style: CustomTextStyles.titleSmallBluegray800Bold),), - Container( - height: 19.v, - width: 100.h, - decoration: BoxDecoration(color: boxColor, borderRadius: BorderRadius.circular(5.h)),), - ],),),), - Align( - alignment: Alignment.center, - child: Container( - margin: EdgeInsets.only(bottom: 12.h), - child: Image.network( - dotenv.env['STORAGE_URL']! + imagePaths?[i], - height: 25.adaptSize, - width: 25.adaptSize, - ),),), - Align( - alignment: Alignment.bottomRight, - child: Container( - width: 70.h, - margin: EdgeInsets.only(bottom: 14.h, right: 22.h), - child: Text("$state".tr, maxLines: 3, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleSmall),),), - ],),); - },),), - ],),), - ],),), - ],),); + alignment: Alignment.topCenter, + child: ListView.builder( + itemCount: plans?.length ?? 0, + itemBuilder: (context, i) { + String state = states?[i]; + var boxColor = appTheme.greenA700; + switch (states?[i]) { + case 'active': + boxColor = appTheme.greenA700; + break; + case 'archived': // График ИМТ + boxColor = appTheme.gray400; + break; + case 'draft': + boxColor = appTheme.deepOrange900; + break; + case 'in_progress': //График обхватов + boxColor = appTheme.lightGreen300; + break; + } + return SizedBox( + height: 40.v, + width: 343.h, + child: Stack( + alignment: Alignment.bottomRight, + children: [ + Align( + alignment: Alignment.topCenter, + child: Container( + margin: EdgeInsets.only(bottom: 11.v), + padding: EdgeInsets.symmetric(horizontal: 6.h, vertical: 4.v), + decoration: AppDecoration.fillGray.copyWith(borderRadius: BorderRadiusStyle.roundedBorder5), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.only(bottom: 1.v), + child: Text(plans![i], style: CustomTextStyles.titleSmallBluegray800Bold), + ), + Container( + height: 19.v, + width: 100.h, + decoration: BoxDecoration(color: boxColor, borderRadius: BorderRadius.circular(5.h)), + ), + ], + ), + ), + ), + Align( + alignment: Alignment.center, + child: Container( + margin: EdgeInsets.only(bottom: 12.h), + child: Image.network( + dotenv.env['STORAGE_URL']! + imagePaths?[i], + height: 25.adaptSize, + width: 25.adaptSize, + ), + ), + ), + Align( + alignment: Alignment.bottomRight, + child: Container( + width: 70.h, + margin: EdgeInsets.only(bottom: 14.h, right: 22.h), + child: Text("$state".tr, maxLines: 3, overflow: TextOverflow.ellipsis, style: theme.textTheme.titleSmall), + ), + ), + ], + ), + ); + }, + ), + ), + ], + ), + ), + ], + ), + ), + ], + ), + ); } List _bodyMassIndex(List weightPoints, int height) { @@ -729,48 +769,49 @@ class MyProfileScreen extends StatelessWidget { title: Center(child: Text("Добавить замер")), content: SizedBox( - width: 200, // Ширина диалогового окна - height: 300, // Высота диалогового окна - child: ListView( - children: [ - Padding( - padding: EdgeInsets.symmetric(vertical: 5.v), - child: Text("chest_circumference".tr, style: theme.textTheme.bodyLarge), - ), - SizedBox(height: 5.v), - CustomTextFormField( - controller: state.chestCircumferenceController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, // Ограничение ввода только цифрами - ], - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 15.v), - child: Text("waist_circumference".tr, style: theme.textTheme.bodyLarge), - ), - SizedBox(height: 5.v), - CustomTextFormField( - controller: state.waistCircumferenceController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, // Ограничение ввода только цифрами - ], - ), - Padding( - padding: EdgeInsets.symmetric(vertical: 15.v), - child: Text("hip_circumference".tr, style: theme.textTheme.bodyLarge), - ), - SizedBox(height: 5.v), - CustomTextFormField( - controller: state.hipCircumferenceController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, // Ограничение ввода только цифрами - ], - ), - ], - ),), + width: 200, // Ширина диалогового окна + height: 300, // Высота диалогового окна + child: ListView( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 5.v), + child: Text("chest_circumference".tr, style: theme.textTheme.bodyLarge), + ), + SizedBox(height: 5.v), + CustomTextFormField( + controller: state.chestCircumferenceController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, // Ограничение ввода только цифрами + ], + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 15.v), + child: Text("waist_circumference".tr, style: theme.textTheme.bodyLarge), + ), + SizedBox(height: 5.v), + CustomTextFormField( + controller: state.waistCircumferenceController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, // Ограничение ввода только цифрами + ], + ), + Padding( + padding: EdgeInsets.symmetric(vertical: 15.v), + child: Text("hip_circumference".tr, style: theme.textTheme.bodyLarge), + ), + SizedBox(height: 5.v), + CustomTextFormField( + controller: state.hipCircumferenceController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, // Ограничение ввода только цифрами + ], + ), + ], + ), + ), actions: [ TextButton( onPressed: onTapOk(context), @@ -778,10 +819,12 @@ class MyProfileScreen extends StatelessWidget { ), TextButton( onPressed: sendEditData(state, context), - child: Text("Изменить", - style: CustomTextStyles.titleMediumBlack.copyWith( - color: Colors.blue, - ),), + child: Text( + "Изменить", + style: CustomTextStyles.titleMediumBlack.copyWith( + color: Colors.blue, + ), + ), ), ], backgroundColor: Colors.white, @@ -824,6 +867,7 @@ class MyProfileScreen extends StatelessWidget { // Обработка ошибок при отправке запроса print("Ошибка при отправке запроса: $e"); } + Navigator.pop(context); }; } @@ -859,10 +903,12 @@ class MyProfileScreen extends StatelessWidget { ), TextButton( onPressed: () => saveWeight(state, context), - child: Text("Изменить", - style: CustomTextStyles.titleMediumBlack.copyWith( - color: Colors.blue, - ),), + child: Text( + "Изменить", + style: CustomTextStyles.titleMediumBlack.copyWith( + color: Colors.blue, + ), + ), ), ], backgroundColor: Colors.white, diff --git a/lib/presentation/recipe/recipe_edit_screen/bloc/recipe_edit_bloc.dart b/lib/presentation/recipe/recipe_edit_screen/bloc/recipe_edit_bloc.dart index 00dbfcd..0fbc048 100644 --- a/lib/presentation/recipe/recipe_edit_screen/bloc/recipe_edit_bloc.dart +++ b/lib/presentation/recipe/recipe_edit_screen/bloc/recipe_edit_bloc.dart @@ -37,7 +37,7 @@ class RecipeEditBloc extends Bloc { } final String? recipeID = state.recipeModelObj?.recipeID; final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/show/$recipeID'), + Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipes/show/$recipeID'), headers: { 'Authorization': 'Bearer $token', }, @@ -47,7 +47,8 @@ class RecipeEditBloc extends Bloc { if (data is Map) { if (state is RecipeEditLoadedState) { var currentState = state as RecipeEditLoadedState; - emit(currentState.copyWith( + emit( + currentState.copyWith( recipeModelObj: currentState.recipeModelObj, title: currentState.title, token: currentState.token, @@ -56,7 +57,9 @@ class RecipeEditBloc extends Bloc { video_url: currentState.video_url, steps: currentState.steps, stepDescriptions: currentState.stepDescriptions, - tags: currentState.tags,),); + tags: currentState.tags, + ), + ); } else { final Map defaultStep = { 'description': '', @@ -75,17 +78,19 @@ class RecipeEditBloc extends Bloc { } } - emit(RecipeEditLoadedState( - token: token, - recipe: data, - title: TextEditingController(text: data['title']), - description: TextEditingController(text: data['description']), - video_url: TextEditingController(text: data['video_url']), - tagsController: TextEditingController(), - tags: await _fetchTags(data['id']), - stepDescriptions: stepDescriptions, - steps: steps, - ),); + emit( + RecipeEditLoadedState( + token: token, + recipe: data, + title: TextEditingController(text: data['title']), + description: TextEditingController(text: data['description']), + video_url: TextEditingController(text: data['video_url']), + tagsController: TextEditingController(), + tags: await _fetchTags(data['id']), + stepDescriptions: stepDescriptions, + steps: steps, + ), + ); } } else { // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку @@ -195,7 +200,7 @@ class RecipeEditBloc extends Bloc { } final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/getTags/$id'), + Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipes/getTags/$id'), headers: { 'Authorization': 'Bearer $token', }, @@ -213,7 +218,8 @@ class RecipeEditBloc extends Bloc { } if (state is RecipeEditLoadedState) { var currentState = state as RecipeEditLoadedState; - emit(currentState.copyWith( + emit( + currentState.copyWith( recipeModelObj: currentState.recipeModelObj, recipe: currentState.recipe, title: currentState.title, @@ -222,7 +228,9 @@ class RecipeEditBloc extends Bloc { video_url: currentState.video_url, steps: currentState.steps, stepDescriptions: currentState.stepDescriptions, - tags: currentState.tags,),); + tags: currentState.tags, + ), + ); } } } diff --git a/lib/presentation/recipe/recipe_select_screen/bloc/recipe_select_bloc.dart b/lib/presentation/recipe/recipe_select_screen/bloc/recipe_select_bloc.dart index 6f5bdfd..ab26247 100644 --- a/lib/presentation/recipe/recipe_select_screen/bloc/recipe_select_bloc.dart +++ b/lib/presentation/recipe/recipe_select_screen/bloc/recipe_select_bloc.dart @@ -1,6 +1,8 @@ import 'dart:async'; +import 'package:dio/dio.dart'; import 'package:eatvio_app/app_router.dart'; +import 'package:eatvio_app/locator_service.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import '/core/app_export.dart'; @@ -31,27 +33,29 @@ class RecipeSelectBloc extends Bloc { if (token == null) { AppRouter.navigatorKey.currentContext?.goNamed('authScreen'); } - final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/index'), - ); + final response = await sl().get(dotenv.env['SERVER_ROOT']! + '/recipes/index'); print('Got response'); if (response.statusCode == 200) { print('Got 200'); - final data = jsonDecode(response.body); + final data = response.data['data']; if (data is List) { print('Got List'); if (state is RecipeSelectLoadedState) { print('Got loaded'); var currentState = state as RecipeSelectLoadedState; - emit((currentState).copyWith( - posts: data, - myProfileModelObj: currentState.myProfileModelObj, - ),); + emit( + (currentState).copyWith( + posts: data, + myProfileModelObj: currentState.myProfileModelObj, + ), + ); } else { print('Got unloaded'); - emit(RecipeSelectLoadedState( - posts: data, - ),); + emit( + RecipeSelectLoadedState( + posts: data, + ), + ); } } else { // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку diff --git a/lib/presentation/recipe/recipe_select_screen/bloc/recipe_select_state.dart b/lib/presentation/recipe/recipe_select_screen/bloc/recipe_select_state.dart index feb87b2..d320f90 100644 --- a/lib/presentation/recipe/recipe_select_screen/bloc/recipe_select_state.dart +++ b/lib/presentation/recipe/recipe_select_screen/bloc/recipe_select_state.dart @@ -12,14 +12,12 @@ class RecipeSelectState extends Equatable { } class RecipeSelectInitialState extends RecipeSelectState { - RecipeSelectInitialState({required RecipeSelectModel myProfileModelObj}) - : super(myProfileModelObj: myProfileModelObj); + RecipeSelectInitialState({required RecipeSelectModel myProfileModelObj}) : super(myProfileModelObj: myProfileModelObj); } /// Represents the state of RecipeSelect in the application. class RecipeSelectLoadedState extends RecipeSelectState { - RecipeSelectLoadedState({this.myProfileModelObj, this.posts}) - : super(myProfileModelObj: null); + RecipeSelectLoadedState({this.myProfileModelObj, this.posts}) : super(myProfileModelObj: null); RecipeSelectModel? myProfileModelObj; List? posts; diff --git a/lib/presentation/recipe/recipe_select_screen/recipe_select_screen.dart b/lib/presentation/recipe/recipe_select_screen/recipe_select_screen.dart index fa0a950..33b59af 100644 --- a/lib/presentation/recipe/recipe_select_screen/recipe_select_screen.dart +++ b/lib/presentation/recipe/recipe_select_screen/recipe_select_screen.dart @@ -112,6 +112,7 @@ class RecipeSelectScreen extends StatelessWidget { _buildRecipeList(BuildContext context, RecipeSelectLoadedState state) { return ListView.builder( + physics: NeverScrollableScrollPhysics(), shrinkWrap: true, // Add this line itemCount: state.posts?.length ?? 0, itemBuilder: (context, index) { diff --git a/lib/presentation/recipe/recipe_show_screen/bloc/recipe_show_bloc.dart b/lib/presentation/recipe/recipe_show_screen/bloc/recipe_show_bloc.dart index ed9b6ef..e8ef6e3 100644 --- a/lib/presentation/recipe/recipe_show_screen/bloc/recipe_show_bloc.dart +++ b/lib/presentation/recipe/recipe_show_screen/bloc/recipe_show_bloc.dart @@ -37,7 +37,7 @@ class RecipeBloc extends Bloc { } final String? recipeID = state.recipeModelObj?.recipeID; final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/show/$recipeID'), + Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipes/show/$recipeID'), headers: { 'Authorization': 'Bearer $token', }, @@ -47,23 +47,29 @@ class RecipeBloc extends Bloc { if (data is Map) { if (state is RecipeLoadedState) { var currentState = state as RecipeLoadedState; - emit(currentState.copyWith( + emit( + currentState.copyWith( recipeModelObj: currentState.recipeModelObj, recipe: currentState.recipe, token: currentState.token, commentController: currentState.commentController, comments: currentState.comments, steps: currentState.steps, - author: currentState.author,),); + author: currentState.author, + ), + ); } else { - emit(RecipeLoadedState( + emit( + RecipeLoadedState( token: token, recipe: data, steps: data['steps'], author: await _fetchAuthor(data['id']), comments: fillCommentList(await _fetchComments(data['id'])), tags: await _fetchTags(data['id']), - commentController: TextEditingController(),),); + commentController: TextEditingController(), + ), + ); } } else { // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку @@ -87,7 +93,7 @@ class RecipeBloc extends Bloc { } final int id = event.id; final response = await http.post( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/delete/$id'), + Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipes/delete/$id'), headers: { 'Authorization': 'Bearer $token', }, @@ -125,7 +131,7 @@ class RecipeBloc extends Bloc { } final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/getAuthor/$id'), + Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipes/getAuthor/$id'), headers: { 'Authorization': 'Bearer $token', }, @@ -141,7 +147,7 @@ class RecipeBloc extends Bloc { AppRouter.navigatorKey.currentContext?.goNamed('authScreen'); } final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/getComments/$id'), + Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipes/getComments/$id'), headers: { 'Authorization': 'Bearer $token', }, @@ -159,7 +165,7 @@ class RecipeBloc extends Bloc { } final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/getTags/$id'), + Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipes/getTags/$id'), headers: { 'Authorization': 'Bearer $token', }, @@ -171,30 +177,35 @@ class RecipeBloc extends Bloc { List fillCommentList(List comments) { List list = []; for (int i = 0; i < comments.length; i++) { - list.add(CommentModel( + list.add( + CommentModel( id: comments[i]['id'].toString(), userImage: comments[i]['profile_photo_path'], username: comments[i]['name'], dateText: DateFormat('dd.MM').format(DateTime.parse(comments[i]['updated_at'])), - greetingText: comments[i]['body'],),); + greetingText: comments[i]['body'], + ), + ); } return list; } Future _sendCommentData(String? token, String body, int id) async { - String url = dotenv.env['SERVER_ROOT']! + '/recipe/createComment/$id'; + String url = dotenv.env['SERVER_ROOT']! + '/recipes/createComment/$id'; final Map credentials = { 'id': id, 'body': body, }; - var response = await http.post(Uri.parse(url), - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer $token', - }, - body: json.encode(credentials), - encoding: utf8,); + var response = await http.post( + Uri.parse(url), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $token', + }, + body: json.encode(credentials), + encoding: utf8, + ); return response; } diff --git a/lib/presentation/registration/additional_information_screen/additional_information_screen.dart b/lib/presentation/registration/additional_information_screen/additional_information_screen.dart index 1ade582..1543cd5 100644 --- a/lib/presentation/registration/additional_information_screen/additional_information_screen.dart +++ b/lib/presentation/registration/additional_information_screen/additional_information_screen.dart @@ -20,45 +20,59 @@ class AdditionalInformationScreen extends StatelessWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => - AdditionalInformationBloc(AdditionalInformationState(additionalInformationModelObj: AdditionalInformationModel(userRegistrationSheet: sheet))) - ..add(AdditionalInformationInitialEvent()), - child: AdditionalInformationScreen(),); + create: (context) => + AdditionalInformationBloc(AdditionalInformationState(additionalInformationModelObj: AdditionalInformationModel(userRegistrationSheet: sheet))) + ..add(AdditionalInformationInitialEvent()), + child: AdditionalInformationScreen(), + ); } @override Widget build(BuildContext context) { return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 1, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 20.v), - SizedBox(height: 73.v), - _buildTextFormField(context), - Spacer(), - BlocBuilder(builder: (context, state) { + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (14 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 20.v), + SizedBox(height: 73.v), + _buildTextFormField(context), + Spacer(), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "finish".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapFinish(state, context),); - },), - ],),),); + text: "finish".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapFinish(state, context), + ); + }, + ), + ], + ), + ), + ); } onTapFinish(AdditionalInformationState state, BuildContext context) { @@ -66,8 +80,12 @@ class AdditionalInformationScreen extends StatelessWidget { UserRegistrationSheet sheet = state.additionalInformationModelObj!.userRegistrationSheet; sheet.additionalInfo = state.editTextController!.text; - final response = await http.post(Uri.parse(dotenv.env['SERVER_ROOT']! + '/register'), - headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, body: jsonEncode(sheet.toJson()), encoding: utf8,); + final response = await http.post( + Uri.parse(dotenv.env['SERVER_ROOT']! + '/register'), + headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, + body: jsonEncode(sheet.toJson()), + encoding: utf8, + ); var res = await jsonDecode(response.body); if (response.statusCode == 200) { @@ -84,11 +102,12 @@ class AdditionalInformationScreen extends StatelessWidget { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 31.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 31.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } onTapBack(BuildContext context) { @@ -100,29 +119,45 @@ class AdditionalInformationScreen extends StatelessWidget { /// Section Widget _buildTextFormField(BuildContext context) { return SizedBox( - height: 315.v, - width: 343.h, - child: Stack(alignment: Alignment.center, children: [ + height: 315.v, + width: 343.h, + child: Stack( + alignment: Alignment.center, + children: [ Align( - alignment: Alignment.center, - child: Column(mainAxisSize: MainAxisSize.min, children: [ + alignment: Alignment.center, + child: Column( + mainAxisSize: MainAxisSize.min, + 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,),), + 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), BlocSelector( - selector: (state) => state.editTextController, - builder: (context, editTextController) { - return CustomTextFormField( - controller: editTextController, - hintText: "У меня крепкое здоровье, но последнее время часто утомляюсь, однако, это мне не мешает радоваться жизни", - textInputAction: TextInputAction.done, - maxLines: 8,); - },), - ],),), - ],),); + selector: (state) => state.editTextController, + builder: (context, editTextController) { + return CustomTextFormField( + controller: editTextController, + hintText: "У меня крепкое здоровье, но последнее время часто утомляюсь, однако, это мне не мешает радоваться жизни", + textInputAction: TextInputAction.done, + maxLines: 8, + ); + }, + ), + ], + ), + ), + ], + ), + ); } /// Navigates to the previous screen. @@ -134,12 +169,13 @@ class AdditionalInformationScreen extends StatelessWidget { /// The dialog box contains a title and a message with the `Теперь вы можете пользоваться полным функционалом приложения` showErrorMessage(BuildContext context, String text) { showDialog( - context: context, - builder: (_) => AlertDialog( - title: const Text('Ошибка'), - content: Text(text), - actions: [TextButton(onPressed: onTapOk(context), child: const Text('Ok'))], - ),); + context: context, + builder: (_) => AlertDialog( + title: const Text('Ошибка'), + content: Text(text), + actions: [TextButton(onPressed: onTapOk(context), child: const Text('Ok'))], + ), + ); } onTapOk(BuildContext context) { diff --git a/lib/presentation/registration/allergies_screen/allergies_screen.dart b/lib/presentation/registration/allergies_screen/allergies_screen.dart index 30e218c..0c5fac4 100644 --- a/lib/presentation/registration/allergies_screen/allergies_screen.dart +++ b/lib/presentation/registration/allergies_screen/allergies_screen.dart @@ -16,8 +16,9 @@ class AllergiesScreen extends StatefulWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => AllergiesBloc(AllergiesState(allergiesModelObj: AllergiesModel(userRegistrationSheet: sheet)))..add(AllergiesInitialEvent()), - child: AllergiesScreen(),); + create: (context) => AllergiesBloc(AllergiesState(allergiesModelObj: AllergiesModel(userRegistrationSheet: sheet)))..add(AllergiesInitialEvent()), + child: AllergiesScreen(), + ); } @override @@ -28,43 +29,58 @@ class _AllergiesScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.76, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 22.v), - Text("allergies_presence".tr, style: theme.textTheme.headlineSmall), - Spacer(flex: 36), - _buildTextFormField(context), - Spacer(flex: 54), - BlocBuilder(builder: (context, state) { + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (10 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 22.v), + Text("allergies_presence".tr, style: theme.textTheme.headlineSmall), + Spacer(flex: 36), + _buildTextFormField(context), + Spacer(flex: 54), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapContinue(state, context),); - },), - BlocBuilder(builder: (context, state) { + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapContinue(state, context), + ); + }, + ), + BlocBuilder( + builder: (context, state) { return GestureDetector( onTap: onTapSkip(state, context), child: Text("skip".tr, style: theme.textTheme.bodyLarge), ); - },), - ],),),); + }, + ), + ], + ), + ), + ); } onTapSkip(AllergiesState state, BuildContext context) { @@ -85,11 +101,12 @@ class _AllergiesScreenState extends State { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 31.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 31.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } onTapBack(BuildContext context) { @@ -100,16 +117,23 @@ class _AllergiesScreenState extends State { /// Section Widget _buildTextFormField(BuildContext context) { - return Column(children: [ - Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI), - SizedBox(height: 2.v), - BlocSelector( + return Column( + children: [ + Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( selector: (state) => state.enterInformationController, builder: (context, enterInformationController) { return CustomTextFormField( - controller: enterInformationController, hintText: "enter_information".tr, textInputAction: TextInputAction.done, maxLines: 8,); - },), - ],); + controller: enterInformationController, + hintText: "enter_information".tr, + textInputAction: TextInputAction.done, + maxLines: 8, + ); + }, + ), + ], + ); } /// Navigates to the previous screen. diff --git a/lib/presentation/registration/blood_pressure_screen/blood_pressure_screen.dart b/lib/presentation/registration/blood_pressure_screen/blood_pressure_screen.dart index 1aabdbd..afce1b8 100644 --- a/lib/presentation/registration/blood_pressure_screen/blood_pressure_screen.dart +++ b/lib/presentation/registration/blood_pressure_screen/blood_pressure_screen.dart @@ -19,9 +19,10 @@ class BloodPressureScreen extends StatefulWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => - BloodPressureBloc(BloodPressureState(bloodPressureModelObj: BloodPressureModel(userRegistrationSheet: sheet)))..add(BloodPressureInitialEvent()), - child: BloodPressureScreen(),); + create: (context) => + BloodPressureBloc(BloodPressureState(bloodPressureModelObj: BloodPressureModel(userRegistrationSheet: sheet)))..add(BloodPressureInitialEvent()), + child: BloodPressureScreen(), + ); } @override @@ -33,115 +34,146 @@ class _BloodPressureScreenState extends State { Widget build(BuildContext context) { final digitsOnly = FilteringTextInputFormatter.digitsOnly; return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - padding: EdgeInsets.symmetric(horizontal: 4.h), - // Apply padding directly to the Container - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all( - color: theme.colorScheme.primary, - width: 1.h, - ), - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.62, - backgroundColor: theme.colorScheme.onPrimary, - valueColor: AlwaysStoppedAnimation(appTheme.blueA400), - ), + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + padding: EdgeInsets.symmetric(horizontal: 4.h), + // Apply padding directly to the Container + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, + width: 1.h, ), ), - SizedBox(height: 21.v), - 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), - BlocSelector( - selector: (state) => state.upPressureController, - builder: (context, upPressureController) { - return CustomTextFormField(inputFormatters: [digitsOnly], controller: upPressureController, hintText: "90".tr); - },), - ],),), - 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), - BlocSelector( - selector: (state) => state.downPressureController, - builder: (context, downPressureController) { - return CustomTextFormField(inputFormatters: [digitsOnly], controller: downPressureController, hintText: "90".tr); - },), - ],),), - 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: BlocSelector( - selector: (state) => state.bloodPressureModelObj, - builder: (context, bloodPressureModelObj) { - return 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: bloodPressureModelObj?.dropdownItemList ?? [], - onChanged: onChangeHyper(context),); - },),), - 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: BlocSelector( - selector: (state) => state.bloodPressureModelObj, - builder: (context, bloodPressureModelObj) { - return 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: bloodPressureModelObj?.dropdownItemList ?? [], - onChanged: onChangeHypo(context),); - },),), - Spacer(), - BlocBuilder(builder: (context, state) { + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (9 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 21.v), + 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), + BlocSelector( + selector: (state) => state.upPressureController, + builder: (context, upPressureController) { + return CustomTextFormField(inputFormatters: [digitsOnly], controller: upPressureController, hintText: "90".tr); + }, + ), + ], + ), + ), + 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), + BlocSelector( + selector: (state) => state.downPressureController, + builder: (context, downPressureController) { + return CustomTextFormField(inputFormatters: [digitsOnly], controller: downPressureController, hintText: "90".tr); + }, + ), + ], + ), + ), + 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: BlocSelector( + selector: (state) => state.bloodPressureModelObj, + builder: (context, bloodPressureModelObj) { + return 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: bloodPressureModelObj?.dropdownItemList ?? [], + onChanged: onChangeHyper(context), + ); + }, + ), + ), + 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: BlocSelector( + selector: (state) => state.bloodPressureModelObj, + builder: (context, bloodPressureModelObj) { + return 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: bloodPressureModelObj?.dropdownItemList ?? [], + onChanged: onChangeHypo(context), + ); + }, + ), + ), + Spacer(), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapContinue(state, context),); - },), - BlocBuilder(builder: (context, state) { + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapContinue(state, context), + ); + }, + ), + BlocBuilder( + builder: (context, state) { return GestureDetector( onTap: onTapSkip(state, context), child: Text("skip".tr, style: theme.textTheme.bodyLarge), ); - },), - ],),),); + }, + ), + ], + ), + ), + ); } onTapSkip(BloodPressureState state, BuildContext context) { @@ -158,7 +190,7 @@ class _BloodPressureScreenState extends State { UserRegistrationSheet sheet = state.bloodPressureModelObj!.userRegistrationSheet; sheet.bloodPressureUp = state.upPressureController!.text; sheet.bloodPressureDown = state.downPressureController!.text; - AppRouter.navigatorKey.currentContext?.goNamed('favoriteSportsScreen', extra: sheet); + AppRouter.navigatorKey.currentContext?.goNamed('allergiesScreen', extra: sheet); } else { String errorMessage = ''; @@ -204,11 +236,12 @@ class _BloodPressureScreenState extends State { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 29.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 29.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { diff --git a/lib/presentation/registration/body_circumferences_screen/body_circumferences_screen.dart b/lib/presentation/registration/body_circumferences_screen/body_circumferences_screen.dart index 3326d45..b4b696d 100644 --- a/lib/presentation/registration/body_circumferences_screen/body_circumferences_screen.dart +++ b/lib/presentation/registration/body_circumferences_screen/body_circumferences_screen.dart @@ -28,62 +28,84 @@ class BodyCircumferencesScreen extends StatelessWidget { final digitsOnly = FilteringTextInputFormatter.digitsOnly; mediaQueryData = MediaQuery.of(context); return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.40, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 39.v), - Text("initial_measurements".tr, style: theme.textTheme.headlineSmall), - SizedBox(height: 93.v), - Column(children: [ + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (6 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 39.v), + Text("initial_measurements".tr, style: theme.textTheme.headlineSmall), + SizedBox(height: 93.v), + Column( + children: [ Text("chest_circumference".tr, style: theme.textTheme.bodyLarge), SizedBox(height: 3.v), BlocSelector( - selector: (state) => state.chestCircumferenceController, - builder: (context, chestCircumferenceController) { - return CustomTextFormField(inputFormatters: [digitsOnly], controller: chestCircumferenceController, hintText: "90".tr); - },), - ],), - SizedBox(height: 19.v), - Text("waist_circumference".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 5.v), - BlocSelector( - selector: (state) => state.waistCircumferenceController, - builder: (context, waistCircumferenceController) { - return CustomTextFormField(inputFormatters: [digitsOnly], controller: waistCircumferenceController, hintText: "60".tr); - },), - SizedBox(height: 21.v), - Text("hip_circumference".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 3.v), - BlocSelector( - selector: (state) => state.hipCircumferenceController, - builder: (context, hipCircumferenceController) { - return CustomTextFormField( - inputFormatters: [digitsOnly], controller: hipCircumferenceController, hintText: "90".tr, textInputAction: TextInputAction.done,); - },), - Spacer(), - BlocBuilder(builder: (context, state) { + selector: (state) => state.chestCircumferenceController, + builder: (context, chestCircumferenceController) { + return CustomTextFormField(inputFormatters: [digitsOnly], controller: chestCircumferenceController, hintText: "90".tr); + }, + ), + ], + ), + SizedBox(height: 19.v), + Text("waist_circumference".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 5.v), + BlocSelector( + selector: (state) => state.waistCircumferenceController, + builder: (context, waistCircumferenceController) { + return CustomTextFormField(inputFormatters: [digitsOnly], controller: waistCircumferenceController, hintText: "60".tr); + }, + ), + SizedBox(height: 21.v), + Text("hip_circumference".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.hipCircumferenceController, + builder: (context, hipCircumferenceController) { + return CustomTextFormField( + inputFormatters: [digitsOnly], + controller: hipCircumferenceController, + hintText: "90".tr, + textInputAction: TextInputAction.done, + ); + }, + ), + Spacer(), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapContinue(state, context),); - },), - ],),),); + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapContinue(state, context), + ); + }, + ), + ], + ), + ), + ); } onTapContinue(BodyCircumferencesState state, BuildContext context) { @@ -129,11 +151,12 @@ class BodyCircumferencesScreen extends StatelessWidget { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 29.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 29.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { diff --git a/lib/presentation/registration/city_of_living_screen/city_of_living_screen.dart b/lib/presentation/registration/city_of_living_screen/city_of_living_screen.dart index 82da493..cd862cd 100644 --- a/lib/presentation/registration/city_of_living_screen/city_of_living_screen.dart +++ b/lib/presentation/registration/city_of_living_screen/city_of_living_screen.dart @@ -1144,45 +1144,57 @@ class CityOfLivingScreen extends StatelessWidget { "Ясный", "Яхрома", ]; + return Scaffold( - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.32, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 39.v), - Text("place_of_living".tr, style: theme.textTheme.headlineSmall), - Spacer(flex: 34), - Text("country".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 2.v), - BlocSelector( - selector: (state) => state.cityOfLivingModelObj, - builder: (context, cityOfLivingModelObj) { - return 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: cityOfLivingModelObj?.dropdownItemList ?? [], - onChanged: onDropDownChange(context),); - },), - SizedBox(height: 22.v), - Text("Населенный пункт", style: theme.textTheme.bodyLarge), - SizedBox(height: 2.v), - BlocBuilder(builder: (context, state) { + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (5 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 39.v), + Text("place_of_living".tr, style: theme.textTheme.headlineSmall), + Spacer(flex: 34), + Text("country".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 2.v), + BlocSelector( + selector: (state) => state.cityOfLivingModelObj, + builder: (context, cityOfLivingModelObj) { + return 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: cityOfLivingModelObj?.dropdownItemList ?? [], + onChanged: onDropDownChange(context), + ); + }, + ), + SizedBox(height: 22.v), + Text("Населенный пункт", style: theme.textTheme.bodyLarge), + SizedBox(height: 2.v), + BlocBuilder( + builder: (context, state) { return RawAutocomplete( optionsBuilder: (TextEditingValue textEditingValue) => _options.where((String option) { return option.toLowerCase().startsWith(textEditingValue.text.toLowerCase()); @@ -1228,16 +1240,23 @@ class CityOfLivingScreen extends StatelessWidget { ); }, ); - },), - Spacer(flex: 65), - BlocBuilder(builder: (context, state) { + }, + ), + Spacer(flex: 65), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapContinue(state, context),); - },), - ],),),); + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapContinue(state, context), + ); + }, + ), + ], + ), + ), + ); } onTapContinue(CityOfLivingState state, BuildContext context) { @@ -1256,11 +1275,12 @@ class CityOfLivingScreen extends StatelessWidget { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 29.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 29.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { diff --git a/lib/presentation/registration/credentials_screen/credentials_screen.dart b/lib/presentation/registration/credentials_screen/credentials_screen.dart index cbf3171..23517a0 100644 --- a/lib/presentation/registration/credentials_screen/credentials_screen.dart +++ b/lib/presentation/registration/credentials_screen/credentials_screen.dart @@ -27,70 +27,87 @@ class CredentialsScreen extends StatelessWidget { Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.05, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 39.v), - Text("user_registration".tr, style: theme.textTheme.headlineSmall), - SizedBox(height: 16.v), - Text("email".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 3.v), - BlocSelector( - selector: (state) => state.emailController, - builder: (context, emailController) { - return CustomTextFormField(controller: emailController, textInputAction: TextInputAction.done); - },), - SizedBox(height: 22.v), - Text("username".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 3.v), - BlocSelector( - selector: (state) => state.nameController, - builder: (context, nameController) { - return CustomTextFormField(controller: nameController, textInputAction: TextInputAction.done); - },), - SizedBox(height: 19.v), - Text("password".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 5.v), - BlocSelector( - selector: (state) => state.passwordController, - builder: (context, passwordController) { - return CustomTextFormField( - obscureText: true, - controller: passwordController, - ); - },), - SizedBox(height: 21.v), - Text("password_confirmation".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 3.v), - BlocSelector( - selector: (state) => state.passwordConfirmationController, - builder: (context, passwordConfirmationController) { - return CustomTextFormField(obscureText: true, controller: passwordConfirmationController, textInputAction: TextInputAction.done); - },), - Spacer(), - BlocBuilder(builder: (context, state) { + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (1 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 39.v), + Text("user_registration".tr, style: theme.textTheme.headlineSmall), + SizedBox(height: 16.v), + Text("email".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.emailController, + builder: (context, emailController) { + return CustomTextFormField(controller: emailController, textInputAction: TextInputAction.done); + }, + ), + SizedBox(height: 22.v), + Text("username".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.nameController, + builder: (context, nameController) { + return CustomTextFormField(controller: nameController, textInputAction: TextInputAction.done); + }, + ), + SizedBox(height: 19.v), + Text("password".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 5.v), + BlocSelector( + selector: (state) => state.passwordController, + builder: (context, passwordController) { + return CustomTextFormField( + obscureText: true, + controller: passwordController, + ); + }, + ), + SizedBox(height: 21.v), + Text("password_confirmation".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.passwordConfirmationController, + builder: (context, passwordConfirmationController) { + return CustomTextFormField(obscureText: true, controller: passwordConfirmationController, textInputAction: TextInputAction.done); + }, + ), + Spacer(), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapContinue(state, context),); - },), - ],),),); + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapContinue(state, context), + ); + }, + ), + ], + ), + ), + ); } onTapContinue(CredentialsState state, BuildContext context) { diff --git a/lib/presentation/registration/date_of_birth_screen/date_of_birth_screen.dart b/lib/presentation/registration/date_of_birth_screen/date_of_birth_screen.dart index a6b2da0..e6a223f 100644 --- a/lib/presentation/registration/date_of_birth_screen/date_of_birth_screen.dart +++ b/lib/presentation/registration/date_of_birth_screen/date_of_birth_screen.dart @@ -36,38 +36,53 @@ class _DateOfBirthScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); - return BlocBuilder(builder: (context, state) { - return Scaffold( + return BlocBuilder( + builder: (context, state) { + return Scaffold( appBar: _buildAppBar(context), body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.24, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (4 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), SizedBox(height: 38.v), Text("date_of_birth".tr, style: theme.textTheme.headlineSmall), Spacer(flex: 39), _buildDateInput(context), Spacer(flex: 60), - BlocBuilder(builder: (context, state) { - return NextStepButton( + BlocBuilder( + builder: (context, state) { + return NextStepButton( text: "continue".tr.toUpperCase(), margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapContinue(state, context),); - },), - ],),),); - },); + onPressed: onTapContinue(state, context), + ); + }, + ), + ], + ), + ), + ); + }, + ); } onTapContinue(DateOfBirthState state, BuildContext context) { @@ -81,11 +96,12 @@ class _DateOfBirthScreenState extends State { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 29.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 29.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { @@ -97,19 +113,27 @@ class _DateOfBirthScreenState extends State { /// 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: [ + 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),),), + 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) { diff --git a/lib/presentation/registration/favorite_foods_screen/favorite_foods_screen.dart b/lib/presentation/registration/favorite_foods_screen/favorite_foods_screen.dart index ea90d98..7660118 100644 --- a/lib/presentation/registration/favorite_foods_screen/favorite_foods_screen.dart +++ b/lib/presentation/registration/favorite_foods_screen/favorite_foods_screen.dart @@ -16,9 +16,10 @@ class FavoriteFoodsScreen extends StatefulWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => - FavoriteFoodsBloc(FavoriteFoodsState(favoriteFoodsModelObj: FavoriteFoodsModel(userRegistrationSheet: sheet)))..add(FavoriteFoodsInitialEvent()), - child: FavoriteFoodsScreen(),); + create: (context) => + FavoriteFoodsBloc(FavoriteFoodsState(favoriteFoodsModelObj: FavoriteFoodsModel(userRegistrationSheet: sheet)))..add(FavoriteFoodsInitialEvent()), + child: FavoriteFoodsScreen(), + ); } @override @@ -29,49 +30,70 @@ class _FavoriteFoodsScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.90, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 19.v), - 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), - _buildTextFormFieldFav(context), - SizedBox(height: 12.v), - _buildTextFormFieldUnfav(context), - Spacer(), - BlocBuilder(builder: (context, state) { + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (13 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 19.v), + 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), + _buildTextFormFieldFav(context), + SizedBox(height: 12.v), + _buildTextFormFieldUnfav(context), + Spacer(), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 40.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapContinue(state, context),); - },), - BlocBuilder(builder: (context, state) { + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 40.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapContinue(state, context), + ); + }, + ), + BlocBuilder( + builder: (context, state) { return GestureDetector( onTap: onTapSkip(state, context), child: Text("skip".tr, style: theme.textTheme.bodyLarge), ); - },), - ],),),); + }, + ), + ], + ), + ), + ); } onTapSkip(FavoriteFoodsState state, BuildContext context) { @@ -93,11 +115,12 @@ class _FavoriteFoodsScreenState extends State { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 31.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 31.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { @@ -108,29 +131,39 @@ class _FavoriteFoodsScreenState extends State { /// Section Widget _buildTextFormFieldFav(BuildContext context) { - return Column(children: [ - Text("favorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI), - SizedBox(height: 2.v), - BlocSelector( + return Column( + children: [ + Text("favorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( selector: (state) => state.favoriteFoodsController, builder: (context, favoriteFoodsController) { return CustomTextFormField(controller: favoriteFoodsController, hintText: "enter_information".tr, maxLines: 7); - },), - ],); + }, + ), + ], + ); } /// Section Widget _buildTextFormFieldUnfav(BuildContext context) { - return Column(children: [ - Text("unfavorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI), - SizedBox(height: 2.v), - BlocSelector( + return Column( + children: [ + Text("unfavorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( selector: (state) => state.unfavoriteFoodsController, builder: (context, unfavoriteFoodsController) { return CustomTextFormField( - controller: unfavoriteFoodsController, hintText: "enter_information".tr, textInputAction: TextInputAction.done, maxLines: 7,); - },), - ],); + controller: unfavoriteFoodsController, + hintText: "enter_information".tr, + textInputAction: TextInputAction.done, + maxLines: 7, + ); + }, + ), + ], + ); } /// Navigates to the previous screen. diff --git a/lib/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart b/lib/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart index 498b24c..187a284 100644 --- a/lib/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart +++ b/lib/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart @@ -16,9 +16,10 @@ class FavoriteSportsScreen extends StatefulWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => FavoriteSportsBloc(FavoriteSportsState(favoriteSportsModelObj: FavoriteSportsModel(userRegistrationSheet: sheet))) - ..add(FavoriteSportsInitialEvent()), - child: FavoriteSportsScreen(),); + create: (context) => + FavoriteSportsBloc(FavoriteSportsState(favoriteSportsModelObj: FavoriteSportsModel(userRegistrationSheet: sheet)))..add(FavoriteSportsInitialEvent()), + child: FavoriteSportsScreen(), + ); } @override @@ -29,43 +30,59 @@ class _FavoriteSportsScreenState extends State { @override Widget build(BuildContext context) { return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 5.v), - child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [ - SizedBox(height: 20.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.83, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 38.v), - Text("your_favorite_sports".tr, style: theme.textTheme.headlineSmall), - Spacer(flex: 32), - _buildTextFormFieldSection(context), - Spacer(flex: 67), - BlocBuilder(builder: (context, state) { + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 5.v), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 20.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (12 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 38.v), + Text("your_favorite_sports".tr, style: theme.textTheme.headlineSmall), + Spacer(flex: 32), + _buildTextFormFieldSection(context), + Spacer(flex: 67), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapContinue(state, context),); - },), - BlocBuilder(builder: (context, state) { + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapContinue(state, context), + ); + }, + ), + BlocBuilder( + builder: (context, state) { return GestureDetector( onTap: onTapSkip(state, context), child: Text("skip".tr, style: theme.textTheme.bodyLarge), ); - },), - ],),),); + }, + ), + ], + ), + ), + ); } onTapSkip(FavoriteSportsState state, BuildContext context) { @@ -85,11 +102,12 @@ class _FavoriteSportsScreenState extends State { _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 29.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 29.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { @@ -100,20 +118,24 @@ class _FavoriteSportsScreenState extends State { /// Section Widget _buildTextFormFieldSection(BuildContext context) { - return Column(children: [ - Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI), - SizedBox(height: 2.v), - BlocSelector( + return Column( + children: [ + Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( selector: (state) => state.enterinformationController, builder: (context, enterinformationController) { return CustomTextFormField( - controller: enterinformationController, - hintText: - "Я занимаюсь плаванием , почти каждый вечер прогулки на свежем воздухе, пару раз в месяц играю в волейбол. Стараюсь не сидеть на месте!", - textInputAction: TextInputAction.done, - maxLines: 8,); - },), - ],); + controller: enterinformationController, + hintText: + "Я занимаюсь плаванием , почти каждый вечер прогулки на свежем воздухе, пару раз в месяц играю в волейбол. Стараюсь не сидеть на месте!", + textInputAction: TextInputAction.done, + maxLines: 8, + ); + }, + ), + ], + ); } onTapArrowLeft(BuildContext context) { diff --git a/lib/presentation/registration/gender_screen/gender_screen.dart b/lib/presentation/registration/gender_screen/gender_screen.dart index d6a9b63..8fc7d23 100644 --- a/lib/presentation/registration/gender_screen/gender_screen.dart +++ b/lib/presentation/registration/gender_screen/gender_screen.dart @@ -15,12 +15,13 @@ class GenderScreen extends StatefulWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => GenderBloc( - GenderState( - genderModelObj: GenderModel(userRegistrationSheet: sheet), - ), - )..add(GenderInitialEvent()), - child: GenderScreen(),); + create: (context) => GenderBloc( + GenderState( + genderModelObj: GenderModel(userRegistrationSheet: sheet), + ), + )..add(GenderInitialEvent()), + child: GenderScreen(), + ); } @override @@ -31,25 +32,33 @@ class _GenderScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); - return BlocBuilder(builder: (context, state) { - return Scaffold( + return BlocBuilder( + builder: (context, state) { + return Scaffold( appBar: _buildAppBar(context), body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ SizedBox(height: 7.v), Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.16, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (3 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), SizedBox(height: 36.v), Text("your_gender".tr, style: theme.textTheme.headlineSmall), RadioListTile( @@ -75,15 +84,22 @@ class _GenderScreenState extends State { ), ), Spacer(flex: 66), - BlocBuilder(builder: (context, state) { - return NextStepButton( + BlocBuilder( + builder: (context, state) { + return NextStepButton( text: "continue".tr.toUpperCase(), margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapNext(state, context),); - },), - ],),),); - },); + onPressed: onTapNext(state, context), + ); + }, + ), + ], + ), + ), + ); + }, + ); } onTapNext(GenderState state, BuildContext context) { diff --git a/lib/presentation/registration/height_screen/height_screen.dart b/lib/presentation/registration/height_screen/height_screen.dart index 22ada6c..c990dc9 100644 --- a/lib/presentation/registration/height_screen/height_screen.dart +++ b/lib/presentation/registration/height_screen/height_screen.dart @@ -17,8 +17,9 @@ class HeightScreen extends StatelessWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => HeightBloc(HeightState(heightModelObj: HeightModel(userRegistrationSheet: sheet)))..add(HeightInitialEvent()), - child: HeightScreen(),); + create: (context) => HeightBloc(HeightState(heightModelObj: HeightModel(userRegistrationSheet: sheet)))..add(HeightInitialEvent()), + child: HeightScreen(), + ); } @override @@ -46,7 +47,7 @@ class HeightScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.55, + value: (8 / 15).toDouble(), backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400, @@ -69,17 +70,19 @@ class HeightScreen extends StatelessWidget { style: theme.textTheme.bodyLarge, ), SizedBox(height: 4.v), - BlocBuilder(builder: (context, state) { - return CustomTextFormField( - width: 150.h, - textInputAction: TextInputAction.done, - controller: state.heightController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, - ], - ); - },), + BlocBuilder( + builder: (context, state) { + return CustomTextFormField( + width: 150.h, + textInputAction: TextInputAction.done, + controller: state.heightController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + ); + }, + ), ], ), ], @@ -115,11 +118,12 @@ class HeightScreen extends StatelessWidget { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 29.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 29.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { diff --git a/lib/presentation/registration/language_select_screen/language_select_screen.dart b/lib/presentation/registration/language_select_screen/language_select_screen.dart index a682d9d..884281f 100644 --- a/lib/presentation/registration/language_select_screen/language_select_screen.dart +++ b/lib/presentation/registration/language_select_screen/language_select_screen.dart @@ -46,7 +46,7 @@ class LanguageSelectScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0, + value: (0 / 15).toDouble(), backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400), ), @@ -66,28 +66,29 @@ class LanguageSelectScreen extends StatelessWidget { ), Spacer(flex: 36), BlocSelector( - selector: (state) => state.languageSelectModelObj, - builder: ( - context, - languageSelectModelObj, - ) { - return 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, - ), + selector: (state) => state.languageSelectModelObj, + builder: ( + context, + languageSelectModelObj, + ) { + return CustomDropDown( + icon: Container( + margin: EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(1.h), ), - hintText: "Не выбрано".tr, - items: languageSelectModelObj?.dropdownItemList ?? [], - onChanged: (value) => _onDropDownChanged(context, value), - ); - },), + child: CustomImageView( + imagePath: ImageConstant.imgFavorite, + height: 12.adaptSize, + width: 12.adaptSize, + ), + ), + hintText: "Не выбрано".tr, + items: languageSelectModelObj?.dropdownItemList ?? [], + onChanged: (value) => _onDropDownChanged(context, value), + ); + }, + ), Spacer(flex: 63), ], ), diff --git a/lib/presentation/registration/medicine_intake_screen/medicine_intake_screen.dart b/lib/presentation/registration/medicine_intake_screen/medicine_intake_screen.dart index bce9049..2a55586 100644 --- a/lib/presentation/registration/medicine_intake_screen/medicine_intake_screen.dart +++ b/lib/presentation/registration/medicine_intake_screen/medicine_intake_screen.dart @@ -16,9 +16,10 @@ class MedicineIntakeScreen extends StatefulWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => MedicineIntakeBloc(MedicineIntakeState(medicineIntakeModelObj: MedicineIntakeModel(userRegistrationSheet: sheet))) - ..add(MedicineIntakeInitialEvent()), - child: MedicineIntakeScreen(),); + create: (context) => + MedicineIntakeBloc(MedicineIntakeState(medicineIntakeModelObj: MedicineIntakeModel(userRegistrationSheet: sheet)))..add(MedicineIntakeInitialEvent()), + child: MedicineIntakeScreen(), + ); } @override @@ -30,54 +31,75 @@ class _MedicineIntakeScreenState extends State { Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.69, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 20.v), - 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: 86.v), - _buildTextFormField(context), - Spacer(), - BlocBuilder(builder: (context, state) { + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (11 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 20.v), + 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: 86.v), + _buildTextFormField(context), + Spacer(), + BlocBuilder( + builder: (context, state) { return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapNext(state, context),); - },), - BlocBuilder(builder: (context, state) { + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapNext(state, context), + ); + }, + ), + BlocBuilder( + builder: (context, state) { return GestureDetector( onTap: onTapSkip(state, context), child: Text("skip".tr, style: theme.textTheme.bodyLarge), ); - },), - ],),),); + }, + ), + ], + ), + ), + ); } onTapSkip(MedicineIntakeState state, BuildContext context) { return () { UserRegistrationSheet sheet = state.medicineIntakeModelObj!.userRegistrationSheet; GoRouter.of(context).goNamed( - 'bloodPressureScreen', + 'favoriteSportsScreen', extra: sheet, ); }; @@ -88,7 +110,7 @@ class _MedicineIntakeScreenState extends State { UserRegistrationSheet sheet = state.medicineIntakeModelObj!.userRegistrationSheet; sheet.aboutTakingPils = state.enterInformationController!.text; GoRouter.of(context).goNamed( - 'bloodPressureScreen', + 'favoriteSportsScreen', extra: sheet, ); }; @@ -97,11 +119,12 @@ class _MedicineIntakeScreenState extends State { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 31.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 31.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { @@ -112,16 +135,23 @@ class _MedicineIntakeScreenState extends State { /// Section Widget _buildTextFormField(BuildContext context) { - return Column(children: [ - Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI), - SizedBox(height: 2.v), - BlocSelector( + return Column( + children: [ + Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI), + SizedBox(height: 2.v), + BlocSelector( selector: (state) => state.enterInformationController, builder: (context, enterInformationController) { return CustomTextFormField( - controller: enterInformationController, hintText: "enter_information".tr, textInputAction: TextInputAction.done, maxLines: 8,); - },), - ],); + controller: enterInformationController, + hintText: "enter_information".tr, + textInputAction: TextInputAction.done, + maxLines: 8, + ); + }, + ), + ], + ); } /// Navigates to the previous screen. diff --git a/lib/presentation/registration/name_screen/name_screen.dart b/lib/presentation/registration/name_screen/name_screen.dart index 880c3ae..4fb599d 100644 --- a/lib/presentation/registration/name_screen/name_screen.dart +++ b/lib/presentation/registration/name_screen/name_screen.dart @@ -17,76 +17,95 @@ class NameScreen extends StatelessWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => NameBloc( - NameState( - nameModelObj: NameModel(userRegistrationSheet: sheet), - ), - )..add(NameInitialEvent()), - child: NameScreen(),); + create: (context) => NameBloc( + NameState( + nameModelObj: NameModel(userRegistrationSheet: sheet), + ), + )..add(NameInitialEvent()), + child: NameScreen(), + ); } @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); return Scaffold( - resizeToAvoidBottomInset: false, - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all(color: theme.colorScheme.primary, width: 1.h),), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.1, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation(appTheme.blueA400),),),), - SizedBox(height: 39.v), - Text("what_is_your_name".tr, style: theme.textTheme.headlineSmall), - SizedBox(height: 93.v), - Text("first_name".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 3.v), - BlocSelector( - selector: (state) => state.firstNameController, - builder: (context, firstNameController) { - return CustomTextFormField(controller: firstNameController, textInputAction: TextInputAction.done); - },), - SizedBox(height: 19.v), - Text("last_name".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 5.v), - BlocSelector( - selector: (state) => state.lastNameController, - builder: (context, lastNameController) { - return CustomTextFormField( - controller: lastNameController, - ); - },), - Spacer(), - BlocBuilder(builder: (context, state) { + resizeToAvoidBottomInset: false, + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all(color: theme.colorScheme.primary, width: 1.h), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: (2 / 15).toDouble(), + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation(appTheme.blueA400), + ), + ), + ), + SizedBox(height: 39.v), + Text("what_is_your_name".tr, style: theme.textTheme.headlineSmall), + SizedBox(height: 93.v), + Text("first_name".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.firstNameController, + builder: (context, firstNameController) { + return CustomTextFormField(controller: firstNameController, textInputAction: TextInputAction.done); + }, + ), + SizedBox(height: 19.v), + Text("last_name".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 5.v), + BlocSelector( + selector: (state) => state.lastNameController, + builder: (context, lastNameController) { + return CustomTextFormField( + controller: lastNameController, + ); + }, + ), + Spacer(), + BlocBuilder( + builder: (context, state) { return NextStepButton( text: "continue".tr.toUpperCase(), margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, onPressed: () => _onTapNext(context, state), // Assign callback function here ); - },), - ],),),); + }, + ), + ], + ), + ), + ); } /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 29.h, - leading: AppbarLeadingImage( - imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: () => onTapArrowLeft(context),), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 29.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), + onTap: () => onTapArrowLeft(context), + ), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } /// Navigates to the previous screen. diff --git a/lib/presentation/registration/weight_screen/weight_screen.dart b/lib/presentation/registration/weight_screen/weight_screen.dart index 5d47e8d..caad9e7 100644 --- a/lib/presentation/registration/weight_screen/weight_screen.dart +++ b/lib/presentation/registration/weight_screen/weight_screen.dart @@ -17,8 +17,9 @@ class WeightScreen extends StatelessWidget { static Widget builder(BuildContext context, sheet) { return BlocProvider( - create: (context) => WeightBloc(WeightState(weightModelObj: WeightModel(userRegistrationSheet: sheet)))..add(WeightInitialEvent()), - child: WeightScreen(),); + create: (context) => WeightBloc(WeightState(weightModelObj: WeightModel(userRegistrationSheet: sheet)))..add(WeightInitialEvent()), + child: WeightScreen(), + ); } @override @@ -45,7 +46,7 @@ class WeightScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.55, + value: (7 / 15).toDouble(), backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400, @@ -68,17 +69,19 @@ class WeightScreen extends StatelessWidget { style: theme.textTheme.bodyLarge, ), SizedBox(height: 4.v), - BlocBuilder(builder: (context, state) { - return CustomTextFormField( - width: 150.h, - textInputAction: TextInputAction.done, - controller: state.weightController, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, - ], - ); - },), + BlocBuilder( + builder: (context, state) { + return CustomTextFormField( + width: 150.h, + textInputAction: TextInputAction.done, + controller: state.weightController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + ); + }, + ), ], ), ], @@ -114,11 +117,12 @@ class WeightScreen extends StatelessWidget { /// Section Widget _buildAppBar(BuildContext context) { return CustomAppBar( - leadingWidth: 29.h, - leading: - AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio),); + leadingWidth: 29.h, + leading: + AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio), + ); } Function onTapBack(BuildContext context) { diff --git a/lib/theme/theme_helper.dart b/lib/theme/theme_helper.dart index c912cb2..f9f64aa 100644 --- a/lib/theme/theme_helper.dart +++ b/lib/theme/theme_helper.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:google_fonts/google_fonts.dart'; import '../../core/app_export.dart'; /// Helper class for managing themes and colors. @@ -22,7 +23,8 @@ class ThemeHelper { //throw exception to notify given theme is not found or not generated by the generator if (!_supportedCustomColor.containsKey(_appTheme)) { throw Exception( - "$_appTheme is not found.Make sure you have added this theme class in JSON Try running flutter pub run build_runner",); + "$_appTheme is not found.Make sure you have added this theme class in JSON Try running flutter pub run build_runner", + ); } //return theme from map @@ -34,13 +36,50 @@ class ThemeHelper { //throw exception to notify given theme is not found or not generated by the generator if (!_supportedColorScheme.containsKey(_appTheme)) { throw Exception( - "$_appTheme is not found.Make sure you have added this theme class in JSON Try running flutter pub run build_runner",); + "$_appTheme is not found.Make sure you have added this theme class in JSON Try running flutter pub run build_runner", + ); } //return theme from map - var colorScheme = - _supportedColorScheme[_appTheme] ?? ColorSchemes.primaryColorScheme; + var colorScheme = _supportedColorScheme[_appTheme] ?? ColorSchemes.primaryColorScheme; return ThemeData( + textTheme: GoogleFonts.mulishTextTheme().copyWith( + bodyLarge: TextStyle( + color: appTheme.blueGray400, + fontSize: 18, + fontWeight: FontWeight.w400, + ), + headlineSmall: TextStyle( + color: colorScheme.primary, + fontWeight: FontWeight.w600, + fontSize: 24, + ), + titleMedium: TextStyle( + color: colorScheme.primary, + fontWeight: FontWeight.w700, + fontSize: 18, + ), + titleSmall: TextStyle( + color: colorScheme.onPrimary, + fontWeight: FontWeight.w700, + fontSize: 15, + ), + bodyMedium: TextStyle( + color: appTheme.blueGray400, + fontWeight: FontWeight.w400, + fontSize: 14, + ), + bodySmall: TextStyle( + color: appTheme.gray500, + fontWeight: FontWeight.w400, + fontSize: 10, + ), + labelLarge: TextStyle( + color: appTheme.blueGray800, + fontWeight: FontWeight.w600, + fontSize: 12, + ), + ), pageTransitionsTheme: PageTransitionsTheme( builders: { TargetPlatform.android: CupertinoPageTransitionsBuilder(), @@ -49,7 +88,6 @@ class ThemeHelper { ), visualDensity: VisualDensity.standard, colorScheme: colorScheme, - textTheme: TextThemes.textTheme(colorScheme), scaffoldBackgroundColor: colorScheme.onPrimary, appBarTheme: AppBarTheme( systemOverlayStyle: SystemUiOverlayStyle( @@ -85,54 +123,6 @@ class ThemeHelper { ThemeData themeData() => _getThemeData(); } -/// Class containing the supported text theme styles. -class TextThemes { - static TextTheme textTheme(ColorScheme colorScheme) => TextTheme( - bodyLarge: TextStyle( - color: appTheme.blueGray400, - fontSize: 18.fSize, - fontFamily: 'Mulish', - fontWeight: FontWeight.w400, - ), - headlineSmall: TextStyle( - color: colorScheme.primary, - fontSize: 24.fSize, - fontFamily: 'Segoe UI', - fontWeight: FontWeight.w600, - ), - titleMedium: TextStyle( - color: colorScheme.primary, - fontSize: 18.fSize, - fontFamily: 'Mulish', - fontWeight: FontWeight.w700, - ), - titleSmall: TextStyle( - color: colorScheme.onPrimary, - fontSize: 15.fSize, - fontFamily: 'Mulish', - fontWeight: FontWeight.w700, - ), - bodyMedium: TextStyle( - color: appTheme.blueGray400, - fontSize: 14.fSize, - fontFamily: 'Mulish', - fontWeight: FontWeight.w400, - ), - bodySmall: TextStyle( - color: appTheme.gray500, - fontSize: 10.fSize, - fontFamily: 'Mulish', - fontWeight: FontWeight.w400, - ), - labelLarge: TextStyle( - color: appTheme.blueGray800, - fontSize: 12.fSize, - fontFamily: 'Mulish', - fontWeight: FontWeight.w600, - ), - ); -} - /// Class containing the supported color schemes. class ColorSchemes { static final primaryColorScheme = ColorScheme.light( @@ -149,10 +139,12 @@ class ColorSchemes { class PrimaryColors { // Blue Color get blue400 => Color(0XFF43A6F2); + Color get blueA400 => Color(0XFF2F80ED); // BlueGray Color get blueGray400 => Color(0XFF7B8794); + Color get black900 => Color(0XFF000000); // Blue @@ -160,7 +152,9 @@ class PrimaryColors { // BlueGray Color get blueGray300 => Color(0XFF9AA5B1); + Color get blueGray800 => Color(0XFF323F4B); + Color get blueGray900 => Color(0XFF2A2F4C); // DeepOrange @@ -168,22 +162,33 @@ class PrimaryColors { // Gray Color get gray100 => Color(0XFFF0F2F5); + Color get gray200 => Color(0XFFF0F0F0); + Color get gray400 => Color(0XFFC1C1C1); + Color get gray40001 => Color(0XFFC8C8C8); + Color get gray50 => Color(0XFFF6FAFF); + Color get gray500 => Color(0XFFA3A3A3); + Color get gray600 => Color(0XFF6D6D6D); + Color get gray60001 => Color(0XFF848484); + Color get gray60002 => Color(0XFF757575); + Color get gray60003 => Color(0XFF707070); // Green Color get greenA700 => Color(0XFF019A3E); + Color get greenA70001 => Color(0XFF00BE13); // LightGreen Color get lightGreen300 => Color(0XFFB2DF8A); + Color get lightGreenA700 => Color(0XFF18FF14); // Red @@ -191,6 +196,7 @@ class PrimaryColors { // Teal Color get teal100 => Color(0XFFA6CEE3); + Color get teal900 => Color(0XFF0B3F56); // White @@ -200,4 +206,5 @@ class PrimaryColors { } PrimaryColors get appTheme => ThemeHelper().themeColor(); + ThemeData get theme => ThemeHelper().themeData(); diff --git a/lib/widgets/custom_navigation_menu_item.dart b/lib/widgets/custom_navigation_menu_item.dart index 2ee47a8..9d7d161 100644 --- a/lib/widgets/custom_navigation_menu_item.dart +++ b/lib/widgets/custom_navigation_menu_item.dart @@ -1,3 +1,4 @@ +import 'package:eatvio_app/core/app_export.dart'; import 'package:flutter/material.dart'; import 'package:eatvio_app/widgets/custom_image_view.dart'; @@ -20,13 +21,12 @@ class MenuItem extends StatelessWidget { padding: const EdgeInsets.all(8.0), child: Row( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.center, // Выравнивание по центру вертикально + crossAxisAlignment: CrossAxisAlignment.center, // Выравнивание по центру вертикально children: [ CustomImageView(imagePath: icon), SizedBox( - width: - 8.0,), // Добавляем небольшой отступ между иконкой и текстом + width: 8.0, + ), // Добавляем небольшой отступ между иконкой и текстом Text(text), ], ), diff --git a/pubspec.yaml b/pubspec.yaml index 87ed29e..36031fc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: easy_debounce: ^2.0.3 lazy_load_scrollview: ^1.3.0 badges: ^3.1.2 + google_fonts: ^6.2.1 dev_dependencies: build_runner: ^2.4.11 @@ -59,17 +60,4 @@ flutter: assets: - assets/ - assets/images/ - - .env - fonts: - - family: Segoe UI - fonts: - - asset: assets/fonts/SegoeUISemibold.ttf - weight: 600 - - family: Mulish - fonts: - - asset: assets/fonts/MulishBold.ttf - weight: 700 - - asset: assets/fonts/MulishRegular.ttf - weight: 400 - - asset: assets/fonts/MulishSemiBold.ttf - weight: 600 + - .env \ No newline at end of file