diff --git a/assets/images/img_female.png b/assets/images/img_female.png new file mode 100644 index 00000000..39e3e4a3 Binary files /dev/null and b/assets/images/img_female.png differ diff --git a/assets/images/img_male.png b/assets/images/img_male.png new file mode 100644 index 00000000..eba4ee26 Binary files /dev/null and b/assets/images/img_male.png differ diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 00000000..7e7e7f67 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1 @@ +extensions: diff --git a/lib/core/utils/pref_utils.dart b/lib/core/utils/pref_utils.dart index 5a7f1b98..5238073f 100644 --- a/lib/core/utils/pref_utils.dart +++ b/lib/core/utils/pref_utils.dart @@ -1,7 +1,5 @@ //ignore: unused_import import 'dart:convert'; -import 'dart:ui'; -import 'package:flutter/scheduler.dart'; import 'package:shared_preferences/shared_preferences.dart'; class PrefUtils { diff --git a/lib/data/models/userRegistrationModel/user_registration_model.dart b/lib/data/models/userRegistrationModel/user_registration_model.dart new file mode 100644 index 00000000..7f32d56c --- /dev/null +++ b/lib/data/models/userRegistrationModel/user_registration_model.dart @@ -0,0 +1,102 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; + +class UserRegistrationSheet { + String firstName; + String lastName; + String email; + String password; + String passwordConfirmation; + bool termsAccepted; + DateTime birthdate; + String gender; + String country; + String city; + String lang; + int weight; + int height; + int chestCircumference; + int waistCircumference; + int hipCircumference; + int bloodPressureUp; + int bloodPressureDown; + bool hasHypo = false; + bool hasHyper = false; + String aboutAllergy = ''; + String aboutTakingPils = ''; + String aboutSportHobbies = ''; + String favoriteFoods = ''; + String unfavoriteFoods = ''; + String additionalInfo = ''; + + UserRegistrationSheet({ + required this.firstName, + required this.lastName, + required this.email, + required this.password, + required this.passwordConfirmation, + required this.termsAccepted, + required this.birthdate, + required this.gender, + required this.country, + required this.city, + required this.lang, + required this.weight, + required this.height, + required this.chestCircumference, + required this.waistCircumference, + required this.hipCircumference, + required this.bloodPressureUp, + required this.bloodPressureDown, + required this.hasHypo, + required this.hasHyper, + required this.aboutAllergy, + required this.aboutTakingPils, + required this.aboutSportHobbies, + required this.favoriteFoods, + required this.unfavoriteFoods, + required this.additionalInfo, + }); + + Map toJson() { + return { + 'first_name': firstName, + 'last_name': lastName, + 'email': email, + 'password': password, + 'password_confirmation': passwordConfirmation, + 'terms': termsAccepted, + 'birthdate': birthdate.toIso8601String(), + 'gender': gender, + 'country': country, + 'city': city, + 'lang': lang, + 'weight': weight, + 'height': height, + 'chest_circumference': chestCircumference, + 'waist_circumference': waistCircumference, + 'hip_circumference': hipCircumference, + 'blood_pressure_up': bloodPressureUp, + 'blood_pressure_down': bloodPressureDown, + 'has_hypo': hasHypo, + 'has_hyper': hasHyper, + 'about_alergy': aboutAllergy, + 'about_taking_pils': aboutTakingPils, + 'about_sport_hobbies': aboutSportHobbies, + 'favorite_foods': favoriteFoods, + 'unfavorite_foods': unfavoriteFoods, + 'additional_info': additionalInfo, + }; + } + + Future sendJson(Uri url) async { + final response = await http.post( + url, + headers: {'Content-Type': 'application/json'}, + body: jsonEncode(toJson()), + ); + if (response.statusCode != 200) { + throw Exception('Failed to send data'); + } + } +} diff --git a/lib/localization/ru/ru_translations.dart b/lib/localization/ru/ru_translations.dart index 38eb83b7..40badc28 100644 --- a/lib/localization/ru/ru_translations.dart +++ b/lib/localization/ru/ru_translations.dart @@ -1,10 +1,17 @@ final Map ru = { + "user_registration": "Регистрация пользователя", + "email": "Элетронная почта", + "password": "Пароль", + "password_confirmation": "Подтвердите пароль", + "first_name": "Имя", + "last_name": "Фамилия", + // date_of_birth Screen "date_of_birth": "Дата рождения", - // city_of_living Screen "country": "Страна", "Russia": "Россия", "city": "Город", "Moscow": "Москва", "place_of_living": "Место проживания", + "what_is_your_name": "Как вас зовут?", // body_circumferences Screen "hip_circumference": "Обхват бедр", "chest_circumference": "Обхват груди", @@ -29,6 +36,8 @@ final Map ru = { "do_you_have_hypertension_tendency": "Есть ли у вас склонность к гипертонии?", "your_blood_pressure": "Ваше артериальное давление?", "average_pressure": "Средние показатели давления:", + "up_pressure": "Верхние показатели давления:", + "down_pressure": "Нижние показатели давления:", "do_you_have_hypotension_tendency": "Есть ли у вас склонность к гипотонии?", // favorite_sports Screen @@ -51,6 +60,7 @@ final Map ru = { // language_select Screen "lbl_english": "English", + "finish": "Завершить", "preferred_language": "Предпочетаемый язык общения?", // Common String diff --git a/lib/presentation/additional_information_screen/additional_information_screen.dart b/lib/presentation/additional_information_screen/additional_information_screen.dart index 96559903..4ee525de 100644 --- a/lib/presentation/additional_information_screen/additional_information_screen.dart +++ b/lib/presentation/additional_information_screen/additional_information_screen.dart @@ -4,22 +4,34 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/widgets/custom_text_form_field.dart'; import 'package:flutter/material.dart'; +import 'dart:convert'; -class AdditionalInformationScreen extends StatelessWidget { +class AdditionalInformationScreen extends StatefulWidget { const AdditionalInformationScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( create: (context) => AdditionalInformationBloc( AdditionalInformationState( - additionalInformationModelObj: AdditionalInformationModel())) + additionalInformationModelObj: + AdditionalInformationModel(userRegistrationSheet: sheet))) ..add(AdditionalInformationInitialEvent()), child: AdditionalInformationScreen()); } + @override + State createState() => + _AdditionalInformationScreenState(); +} + +class _AdditionalInformationScreenState + extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -32,26 +44,43 @@ class AdditionalInformationScreen extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), child: Column(children: [ SizedBox(height: 7.v), - _buildProgressIndicator(context), + 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( - width: 192.h, - child: Text("additional_information".tr, - maxLines: 2, - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center, - style: theme.textTheme.headlineSmall)), SizedBox(height: 73.v), _buildTextFormField(context), Spacer(), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - showSuccessMessage(context); - }), + 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: () { + var message; + UserRegistrationSheet sheet = state + .additionalInformationModelObj! + .userRegistrationSheet; + sheet.additionalInfo = state.editTextController!.text; + message = sheet.toJson(); + print(message); + }); + }), SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); } @@ -69,34 +98,12 @@ class AdditionalInformationScreen extends StatelessWidget { title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } - /// Section Widget - Widget _buildProgressIndicator(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), - decoration: AppDecoration.outlinePrimary - .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), - child: Container( - height: 8.v, - width: 332.h, - decoration: BoxDecoration( - color: appTheme.blueA400, - borderRadius: BorderRadius.circular(4.h), - border: - Border.all(color: theme.colorScheme.primary, width: 1.h)))); - } - /// Section Widget Widget _buildTextFormField(BuildContext context) { return SizedBox( height: 257.v, width: 343.h, child: Stack(alignment: Alignment.center, children: [ - Align( - alignment: Alignment.topLeft, - child: Padding( - padding: EdgeInsets.only(left: 10.h, top: 69.v), - child: Text("enter_information".tr, - style: theme.textTheme.bodyLarge))), Align( alignment: Alignment.center, child: Column(mainAxisSize: MainAxisSize.min, children: [ @@ -128,13 +135,12 @@ class AdditionalInformationScreen extends StatelessWidget { /// Displays an alert dialog when the action is triggered. /// The dialog box contains a title and a message with the `Теперь вы можете пользоваться полным функционалом приложения` - showSuccessMessage(BuildContext context) { + showSuccessMessage(BuildContext context, String text) { showDialog( context: context, builder: (_) => AlertDialog( title: const Text('Регистрация завершена!'), - content: const Text( - 'Теперь вы можете пользоваться полным функционалом приложения'), + content: const Text(text), actions: [ TextButton( onPressed: () { diff --git a/lib/presentation/additional_information_screen/models/additional_information_model.dart b/lib/presentation/additional_information_screen/models/additional_information_model.dart index bc31be45..3e5243d2 100644 --- a/lib/presentation/additional_information_screen/models/additional_information_model.dart +++ b/lib/presentation/additional_information_screen/models/additional_information_model.dart @@ -1,16 +1,21 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [additional_information_screen], /// and is typically used to hold data that is passed between different parts of the application. class AdditionalInformationModel extends Equatable { - AdditionalInformationModel() {} + UserRegistrationSheet userRegistrationSheet; + AdditionalInformationModel({required this.userRegistrationSheet}); AdditionalInformationModel copyWith() { - return AdditionalInformationModel(); + return AdditionalInformationModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); } @override - List get props => []; + List get props => [userRegistrationSheet]; } diff --git a/lib/presentation/allergies_screen/allergies_screen.dart b/lib/presentation/allergies_screen/allergies_screen.dart index 01d732de..0e4de30d 100644 --- a/lib/presentation/allergies_screen/allergies_screen.dart +++ b/lib/presentation/allergies_screen/allergies_screen.dart @@ -4,21 +4,29 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/widgets/custom_text_form_field.dart'; import 'package:flutter/material.dart'; -class AllergiesScreen extends StatelessWidget { +class AllergiesScreen extends StatefulWidget { const AllergiesScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => - AllergiesBloc(AllergiesState(allergiesModelObj: AllergiesModel())) - ..add(AllergiesInitialEvent()), + create: (context) => AllergiesBloc(AllergiesState( + allergiesModelObj: AllergiesModel(userRegistrationSheet: sheet))) + ..add(AllergiesInitialEvent()), child: AllergiesScreen()); } + @override + State createState() => _AllergiesScreenState(); +} + +class _AllergiesScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -42,7 +50,7 @@ class AllergiesScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.41, + value: 0.62, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400)))), @@ -52,12 +60,25 @@ class AllergiesScreen extends StatelessWidget { Spacer(flex: 36), _buildTextFormField(context), Spacer(flex: 63), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToMedicine(context); - }), + 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: () { + UserRegistrationSheet sheet = + state.allergiesModelObj!.userRegistrationSheet; + sheet.aboutAllergy = + state.enterInformationController!.text; + Navigator.pushNamed( + context, + AppRoutes.medicineIntakeScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); diff --git a/lib/presentation/allergies_screen/models/allergies_model.dart b/lib/presentation/allergies_screen/models/allergies_model.dart index 64649efe..5553fa4e 100644 --- a/lib/presentation/allergies_screen/models/allergies_model.dart +++ b/lib/presentation/allergies_screen/models/allergies_model.dart @@ -1,16 +1,21 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [allergies_screen], /// and is typically used to hold data that is passed between different parts of the application. class AllergiesModel extends Equatable { - AllergiesModel() {} + UserRegistrationSheet userRegistrationSheet; + AllergiesModel({required this.userRegistrationSheet}); AllergiesModel copyWith() { - return AllergiesModel(); + return AllergiesModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); } @override - List get props => []; + List get props => [userRegistrationSheet]; } diff --git a/lib/presentation/app_navigation_screen/app_navigation_screen.dart b/lib/presentation/app_navigation_screen/app_navigation_screen.dart index a04ad84a..0a485d18 100644 --- a/lib/presentation/app_navigation_screen/app_navigation_screen.dart +++ b/lib/presentation/app_navigation_screen/app_navigation_screen.dart @@ -3,7 +3,7 @@ import 'models/app_navigation_model.dart'; import 'package:eatvio_app/core/app_export.dart'; import 'package:flutter/material.dart'; -class AppNavigationScreen extends StatelessWidget { +class AppNavigationScreen extends StatefulWidget { const AppNavigationScreen({Key? key}) : super( key: key, @@ -19,6 +19,11 @@ class AppNavigationScreen extends StatelessWidget { ); } + @override + State createState() => _AppNavigationScreenState(); +} + +class _AppNavigationScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); diff --git a/lib/presentation/app_navigation_screen/models/app_navigation_model.dart b/lib/presentation/app_navigation_screen/models/app_navigation_model.dart index 405bdc8a..73fd71d7 100644 --- a/lib/presentation/app_navigation_screen/models/app_navigation_model.dart +++ b/lib/presentation/app_navigation_screen/models/app_navigation_model.dart @@ -5,7 +5,7 @@ import 'package:equatable/equatable.dart'; /// This class defines the variables used in the [app_navigation_screen], /// and is typically used to hold data that is passed between different parts of the application. class AppNavigationModel extends Equatable { - AppNavigationModel() {} + AppNavigationModel(); AppNavigationModel copyWith() { return AppNavigationModel(); diff --git a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart index 9d0a083d..c2c3632c 100644 --- a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart +++ b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart @@ -9,20 +9,41 @@ part 'blood_pressure_state.dart'; class BloodPressureBloc extends Bloc { BloodPressureBloc(BloodPressureState initialState) : super(initialState) { on(_onInitialize); - on(_changeDropDown); + on(_changeHypoDropDown); + on(_changeHyperDropDown); } - _changeDropDown( - ChangeDropDownEvent event, + _changeHyperDropDown( + ChangeHyperDropDownEvent event, Emitter emit, ) { - emit(state.copyWith(selectedDropDownValue: event.value)); + if (event.value.id == 1) { + state.bloodPressureModelObj!.userRegistrationSheet.hasHyper = true; + } else { + state.bloodPressureModelObj!.userRegistrationSheet.hasHyper = false; + } + emit(state.copyWith(selectedHyperValue: event.value)); + } + + _changeHypoDropDown( + ChangeHypoDownEvent event, + Emitter emit, + ) { + if (event.value.id == 1) { + state.bloodPressureModelObj!.userRegistrationSheet.hasHypo = true; + } else { + state.bloodPressureModelObj!.userRegistrationSheet.hasHypo = false; + } + emit(state.copyWith(selectedHypoValue: event.value)); } List fillDropdownItemList() { return [ - SelectionPopupModel(id: 1, title: "Да", isSelected: true), - SelectionPopupModel(id: 2, title: "Нет"), + SelectionPopupModel( + id: 1, + title: "Да", + ), + SelectionPopupModel(id: 2, title: "Нет", isSelected: true), ]; } @@ -31,8 +52,8 @@ class BloodPressureBloc extends Bloc { Emitter emit, ) async { emit(state.copyWith( - valueController: TextEditingController(), - valueController1: TextEditingController())); + upPressureController: TextEditingController(), + downPressureController: TextEditingController())); emit(state.copyWith( bloodPressureModelObj: state.bloodPressureModelObj ?.copyWith(dropdownItemList: fillDropdownItemList()))); diff --git a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_event.dart b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_event.dart index 98e86810..677d2436 100644 --- a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_event.dart +++ b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_event.dart @@ -16,8 +16,19 @@ class BloodPressureInitialEvent extends BloodPressureEvent { } ///event for dropdown selection -class ChangeDropDownEvent extends BloodPressureEvent { - ChangeDropDownEvent({required this.value}); +class ChangeHyperDropDownEvent extends BloodPressureEvent { + ChangeHyperDropDownEvent({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} + +class ChangeHypoDownEvent extends BloodPressureEvent { + ChangeHypoDownEvent({required this.value}); SelectionPopupModel value; diff --git a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_state.dart b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_state.dart index e43ee812..d1db1c49 100644 --- a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_state.dart +++ b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_state.dart @@ -5,38 +5,44 @@ part of 'blood_pressure_bloc.dart'; /// Represents the state of BloodPressure in the application. class BloodPressureState extends Equatable { BloodPressureState({ - this.valueController, - this.valueController1, - this.selectedDropDownValue, + this.upPressureController, + this.downPressureController, + this.selectedHyperValue, + this.selectedHypoValue, this.bloodPressureModelObj, }); - TextEditingController? valueController; + TextEditingController? upPressureController; - TextEditingController? valueController1; + TextEditingController? downPressureController; - SelectionPopupModel? selectedDropDownValue; + SelectionPopupModel? selectedHypoValue; + + SelectionPopupModel? selectedHyperValue; BloodPressureModel? bloodPressureModelObj; @override List get props => [ - valueController, - valueController1, - selectedDropDownValue, + upPressureController, + downPressureController, + selectedHyperValue, + selectedHypoValue, bloodPressureModelObj, ]; BloodPressureState copyWith({ - TextEditingController? valueController, - TextEditingController? valueController1, - SelectionPopupModel? selectedDropDownValue, + TextEditingController? upPressureController, + TextEditingController? downPressureController, + SelectionPopupModel? selectedHyperValue, + SelectionPopupModel? selectedHypoValue, BloodPressureModel? bloodPressureModelObj, }) { return BloodPressureState( - valueController: valueController ?? this.valueController, - valueController1: valueController1 ?? this.valueController1, - selectedDropDownValue: - selectedDropDownValue ?? this.selectedDropDownValue, + upPressureController: upPressureController ?? this.upPressureController, + downPressureController: + downPressureController ?? this.downPressureController, + selectedHyperValue: selectedHyperValue ?? this.selectedHyperValue, + selectedHypoValue: selectedHypoValue ?? this.selectedHypoValue, bloodPressureModelObj: bloodPressureModelObj ?? this.bloodPressureModelObj, ); diff --git a/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart b/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart index 4e849559..f5c10e1d 100644 --- a/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart +++ b/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart @@ -1,27 +1,38 @@ import 'bloc/blood_pressure_bloc.dart'; +import 'package:flutter/services.dart'; import 'models/blood_pressure_model.dart'; import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; import 'package:eatvio_app/widgets/custom_drop_down.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; -class BloodPressureScreen extends StatelessWidget { +class BloodPressureScreen extends StatefulWidget { const BloodPressureScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => BloodPressureBloc( - BloodPressureState(bloodPressureModelObj: BloodPressureModel())) + create: (context) => BloodPressureBloc(BloodPressureState( + bloodPressureModelObj: + BloodPressureModel(userRegistrationSheet: sheet))) ..add(BloodPressureInitialEvent()), child: BloodPressureScreen()); } + @override + State createState() => _BloodPressureScreenState(); +} + +class _BloodPressureScreenState extends State { @override Widget build(BuildContext context) { + final digitsOnly = FilteringTextInputFormatter.digitsOnly; mediaQueryData = MediaQuery.of(context); return SafeArea( child: Scaffold( @@ -46,7 +57,7 @@ class BloodPressureScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.63, + value: 0.76, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400))))), @@ -58,8 +69,42 @@ class BloodPressureScreen extends StatelessWidget { overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: theme.textTheme.headlineSmall)), - SizedBox(height: 77.v), - _buildThirtyThree(context), + 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), @@ -81,14 +126,14 @@ class BloodPressureScreen extends StatelessWidget { imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize)), - hintText: "no".tr, + hintText: "Не выбрано".tr, items: bloodPressureModelObj?.dropdownItemList ?? [], onChanged: (value) { context .read() - .add(ChangeDropDownEvent(value: value)); + .add(ChangeHypoDownEvent(value: value)); }); })), SizedBox(height: 22.v), @@ -112,24 +157,37 @@ class BloodPressureScreen extends StatelessWidget { imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize)), - hintText: "no".tr, + hintText: "Не выбрано".tr, items: bloodPressureModelObj?.dropdownItemList ?? [], onChanged: (value) { - context - .read() - .add(ChangeDropDownEvent(value: value)); + context.read().add( + ChangeHyperDropDownEvent(value: value)); }); })), Spacer(), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.symmetric(horizontal: 4.h), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToSports(context); - }), + 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: () { + UserRegistrationSheet sheet = state + .bloodPressureModelObj!.userRegistrationSheet; + sheet.bloodPressureUp = + int.tryParse(state.upPressureController!.text)!; + sheet.bloodPressureDown = + int.tryParse(state.downPressureController!.text)!; + Navigator.pushNamed( + context, + AppRoutes.favoriteSportsScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); @@ -149,24 +207,6 @@ class BloodPressureScreen extends StatelessWidget { title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } - /// Section Widget - Widget _buildThirtyThree(BuildContext context) { - return Container( - margin: EdgeInsets.only(right: 1.h), - padding: EdgeInsets.symmetric(horizontal: 3.h), - child: Column(children: [ - Text("average_pressure".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 2.v), - BlocSelector( - selector: (state) => state.valueController, - builder: (context, valueController) { - return CustomTextFormField( - controller: valueController, hintText: "90".tr); - }) - ])); - } - /// Navigates to the previous screen. onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); diff --git a/lib/presentation/blood_pressure_screen/models/blood_pressure_model.dart b/lib/presentation/blood_pressure_screen/models/blood_pressure_model.dart index 1e6c2fa3..c002b0a9 100644 --- a/lib/presentation/blood_pressure_screen/models/blood_pressure_model.dart +++ b/lib/presentation/blood_pressure_screen/models/blood_pressure_model.dart @@ -2,20 +2,25 @@ import 'package:equatable/equatable.dart'; import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [blood_pressure_screen], /// and is typically used to hold data that is passed between different parts of the application. class BloodPressureModel extends Equatable { - BloodPressureModel({this.dropdownItemList = const []}) {} + UserRegistrationSheet userRegistrationSheet; + BloodPressureModel( + {required this.userRegistrationSheet, this.dropdownItemList = const []}); List dropdownItemList; BloodPressureModel copyWith({List? dropdownItemList}) { return BloodPressureModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, dropdownItemList: dropdownItemList ?? this.dropdownItemList, ); } @override - List get props => [dropdownItemList]; + List get props => [dropdownItemList, userRegistrationSheet]; } diff --git a/lib/presentation/body_circumferences_screen/bloc/body_circumferences_bloc.dart b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_bloc.dart index 5b626c60..30e0097c 100644 --- a/lib/presentation/body_circumferences_screen/bloc/body_circumferences_bloc.dart +++ b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_bloc.dart @@ -18,8 +18,8 @@ class BodyCircumferencesBloc Emitter emit, ) async { emit(state.copyWith( - valueController: TextEditingController(), - valueController1: TextEditingController(), - valueController2: TextEditingController())); + chestCircumferenceController: TextEditingController(), + waistCircumferenceController: TextEditingController(), + hipCircumferenceController: TextEditingController())); } } diff --git a/lib/presentation/body_circumferences_screen/bloc/body_circumferences_state.dart b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_state.dart index 9c952fb0..df28755c 100644 --- a/lib/presentation/body_circumferences_screen/bloc/body_circumferences_state.dart +++ b/lib/presentation/body_circumferences_screen/bloc/body_circumferences_state.dart @@ -5,37 +5,40 @@ part of 'body_circumferences_bloc.dart'; /// Represents the state of BodyCircumferences in the application. class BodyCircumferencesState extends Equatable { BodyCircumferencesState({ - this.valueController, - this.valueController1, - this.valueController2, + this.chestCircumferenceController, + this.waistCircumferenceController, + this.hipCircumferenceController, this.bodyCircumferencesModelObj, }); - TextEditingController? valueController; + TextEditingController? chestCircumferenceController; - TextEditingController? valueController1; + TextEditingController? waistCircumferenceController; - TextEditingController? valueController2; + TextEditingController? hipCircumferenceController; BodyCircumferencesModel? bodyCircumferencesModelObj; @override List get props => [ - valueController, - valueController1, - valueController2, + chestCircumferenceController, + waistCircumferenceController, + hipCircumferenceController, bodyCircumferencesModelObj, ]; BodyCircumferencesState copyWith({ - TextEditingController? valueController, - TextEditingController? valueController1, - TextEditingController? valueController2, + TextEditingController? chestCircumferenceController, + TextEditingController? waistCircumferenceController, + TextEditingController? hipCircumferenceController, BodyCircumferencesModel? bodyCircumferencesModelObj, }) { return BodyCircumferencesState( - valueController: valueController ?? this.valueController, - valueController1: valueController1 ?? this.valueController1, - valueController2: valueController2 ?? this.valueController2, + chestCircumferenceController: + chestCircumferenceController ?? this.chestCircumferenceController, + waistCircumferenceController: + waistCircumferenceController ?? this.waistCircumferenceController, + hipCircumferenceController: + hipCircumferenceController ?? this.hipCircumferenceController, bodyCircumferencesModelObj: bodyCircumferencesModelObj ?? this.bodyCircumferencesModelObj, ); diff --git a/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart b/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart index dfc414e1..c6e75bce 100644 --- a/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart +++ b/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart @@ -1,10 +1,12 @@ import 'bloc/body_circumferences_bloc.dart'; +import 'package:flutter/services.dart'; import 'models/body_circumferences_model.dart'; import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/widgets/custom_text_form_field.dart'; import 'package:flutter/material.dart'; @@ -12,15 +14,19 @@ class BodyCircumferencesScreen extends StatelessWidget { const BodyCircumferencesScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( create: (context) => BodyCircumferencesBloc(BodyCircumferencesState( - bodyCircumferencesModelObj: BodyCircumferencesModel())) + bodyCircumferencesModelObj: + BodyCircumferencesModel(userRegistrationSheet: sheet))) ..add(BodyCircumferencesInitialEvent()), child: BodyCircumferencesScreen()); } @override Widget build(BuildContext context) { + final digitsOnly = FilteringTextInputFormatter.digitsOnly; mediaQueryData = MediaQuery.of(context); return SafeArea( child: Scaffold( @@ -42,7 +48,7 @@ class BodyCircumferencesScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.29, + value: 0.40, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400)))), @@ -50,17 +56,32 @@ class BodyCircumferencesScreen extends StatelessWidget { Text("initial_measurements".tr, style: theme.textTheme.headlineSmall), SizedBox(height: 93.v), - _buildTwentySeven(context), + 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.valueController1, - builder: (context, valueController1) { + selector: (state) => state.waistCircumferenceController, + builder: (context, waistCircumferenceController) { return CustomTextFormField( - controller: valueController1, hintText: "60".tr); + inputFormatters: [digitsOnly], + controller: waistCircumferenceController, + hintText: "60".tr); }), SizedBox(height: 21.v), Text("hip_circumference".tr, @@ -68,22 +89,40 @@ class BodyCircumferencesScreen extends StatelessWidget { SizedBox(height: 3.v), BlocSelector( - selector: (state) => state.valueController2, - builder: (context, valueController2) { + selector: (state) => state.hipCircumferenceController, + builder: (context, hipCircumferenceController) { return CustomTextFormField( - controller: valueController2, + inputFormatters: [digitsOnly], + controller: hipCircumferenceController, hintText: "90".tr, textInputAction: TextInputAction.done); }), Spacer(), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToWeight(context); - }), + 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: () { + UserRegistrationSheet sheet = state + .bodyCircumferencesModelObj! + .userRegistrationSheet; + sheet.chestCircumference = int.tryParse( + state.chestCircumferenceController!.text)!; + sheet.waistCircumference = int.tryParse( + state.waistCircumferenceController!.text)!; + sheet.hipCircumference = int.tryParse( + state.hipCircumferenceController!.text)!; + Navigator.pushNamed( + context, + AppRoutes.weightScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); } @@ -101,21 +140,6 @@ class BodyCircumferencesScreen extends StatelessWidget { title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } - /// Section Widget - Widget _buildTwentySeven(BuildContext context) { - return Column(children: [ - Text("chest_circumference".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 3.v), - BlocSelector( - selector: (state) => state.valueController, - builder: (context, valueController) { - return CustomTextFormField( - controller: valueController, hintText: "90".tr); - }) - ]); - } - /// Navigates to the previous screen. onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); diff --git a/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart b/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart index 3d6dd7c9..bc684a03 100644 --- a/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart +++ b/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart @@ -1,16 +1,21 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [body_circumferences_screen], /// and is typically used to hold data that is passed between different parts of the application. class BodyCircumferencesModel extends Equatable { - BodyCircumferencesModel() {} + UserRegistrationSheet userRegistrationSheet; + BodyCircumferencesModel({required this.userRegistrationSheet}); BodyCircumferencesModel copyWith() { - return BodyCircumferencesModel(); + return BodyCircumferencesModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); } @override - List get props => []; + List get props => [userRegistrationSheet]; } diff --git a/lib/presentation/city_of_living_screen/bloc/city_of_living_bloc.dart b/lib/presentation/city_of_living_screen/bloc/city_of_living_bloc.dart index c7cf389f..c0cad702 100644 --- a/lib/presentation/city_of_living_screen/bloc/city_of_living_bloc.dart +++ b/lib/presentation/city_of_living_screen/bloc/city_of_living_bloc.dart @@ -28,6 +28,8 @@ class CityOfLivingBloc extends Bloc { Emitter emit, ) { emit(state.copyWith(selectedDropDownValue: event.value)); + state.cityOfLivingModelObj?.userRegistrationSheet.country = + event.value.title; } _changeDropDown1( @@ -35,6 +37,7 @@ class CityOfLivingBloc extends Bloc { Emitter emit, ) { emit(state.copyWith(selectedDropDownValue1: event.value)); + state.cityOfLivingModelObj?.userRegistrationSheet.city = event.value.title; } List fillDropdownItemList() { diff --git a/lib/presentation/city_of_living_screen/city_of_living_screen.dart b/lib/presentation/city_of_living_screen/city_of_living_screen.dart index 92099dd9..2f2e8655 100644 --- a/lib/presentation/city_of_living_screen/city_of_living_screen.dart +++ b/lib/presentation/city_of_living_screen/city_of_living_screen.dart @@ -5,16 +5,20 @@ import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; import 'package:eatvio_app/widgets/custom_drop_down.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; class CityOfLivingScreen extends StatelessWidget { const CityOfLivingScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => CityOfLivingBloc( - CityOfLivingState(cityOfLivingModelObj: CityOfLivingModel())) + create: (context) => CityOfLivingBloc(CityOfLivingState( + cityOfLivingModelObj: + CityOfLivingModel(userRegistrationSheet: sheet))) ..add(CityOfLivingInitialEvent()), child: CityOfLivingScreen()); } @@ -41,12 +45,13 @@ class CityOfLivingScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.23, + value: 0.32, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400)))), SizedBox(height: 39.v), - Text("Moscow".tr, style: theme.textTheme.headlineSmall), + Text("place_of_living".tr, + style: theme.textTheme.headlineSmall), Spacer(flex: 34), Text("country".tr, style: theme.textTheme.bodyLarge), SizedBox(height: 2.v), @@ -64,7 +69,7 @@ class CityOfLivingScreen extends StatelessWidget { imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize)), - hintText: "Russia".tr, + hintText: "Не выбрано".tr, items: cityOfLivingModelObj?.dropdownItemList ?? [], onChanged: (value) { context @@ -89,7 +94,7 @@ class CityOfLivingScreen extends StatelessWidget { imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize)), - hintText: "Moscow".tr, + hintText: "Не выбрано".tr, items: cityOfLivingModelObj?.dropdownItemList1 ?? [], onChanged: (value) { @@ -99,14 +104,24 @@ class CityOfLivingScreen extends StatelessWidget { }); }), Spacer(flex: 65), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToCircumferences(context); - }), + 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: () { + UserRegistrationSheet sheet = + state.cityOfLivingModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.bodyCircumferencesScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); } @@ -128,11 +143,4 @@ class CityOfLivingScreen extends StatelessWidget { onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); } - - /// Navigates to the bodyCircumferencesScreen when the action is triggered. - navigateToCircumferences(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.bodyCircumferencesScreen, - ); - } } diff --git a/lib/presentation/city_of_living_screen/models/city_of_living_model.dart b/lib/presentation/city_of_living_screen/models/city_of_living_model.dart index a20b013c..1b32e6e0 100644 --- a/lib/presentation/city_of_living_screen/models/city_of_living_model.dart +++ b/lib/presentation/city_of_living_screen/models/city_of_living_model.dart @@ -2,14 +2,17 @@ import 'package:equatable/equatable.dart'; import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [city_of_living_screen], /// and is typically used to hold data that is passed between different parts of the application. class CityOfLivingModel extends Equatable { + UserRegistrationSheet userRegistrationSheet; CityOfLivingModel({ + required this.userRegistrationSheet, this.dropdownItemList = const [], this.dropdownItemList1 = const [], - }) {} + }); List dropdownItemList; @@ -20,11 +23,14 @@ class CityOfLivingModel extends Equatable { List? dropdownItemList1, }) { return CityOfLivingModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, dropdownItemList: dropdownItemList ?? this.dropdownItemList, dropdownItemList1: dropdownItemList1 ?? this.dropdownItemList1, ); } @override - List get props => [dropdownItemList, dropdownItemList1]; + List get props => + [dropdownItemList, dropdownItemList1, userRegistrationSheet]; } diff --git a/lib/presentation/credentials_screen/bloc/credentials_bloc.dart b/lib/presentation/credentials_screen/bloc/credentials_bloc.dart new file mode 100644 index 00000000..6fab34bb --- /dev/null +++ b/lib/presentation/credentials_screen/bloc/credentials_bloc.dart @@ -0,0 +1,23 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/credentials_screen/models/credentials_model.dart'; +part 'credentials_event.dart'; +part 'credentials_state.dart'; + +/// A bloc that manages the state of a Credentials according to the event that is dispatched to it. +class CredentialsBloc extends Bloc { + CredentialsBloc(CredentialsState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + CredentialsInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + valueController: TextEditingController(), + passwordController: TextEditingController(), + passwordConfirmationController: TextEditingController())); + } +} diff --git a/lib/presentation/credentials_screen/bloc/credentials_event.dart b/lib/presentation/credentials_screen/bloc/credentials_event.dart new file mode 100644 index 00000000..3001076a --- /dev/null +++ b/lib/presentation/credentials_screen/bloc/credentials_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'credentials_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///Credentials widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class CredentialsEvent extends Equatable {} + +/// Event that is dispatched when the Credentials widget is first created. +class CredentialsInitialEvent extends CredentialsEvent { + @override + List get props => []; +} diff --git a/lib/presentation/credentials_screen/bloc/credentials_state.dart b/lib/presentation/credentials_screen/bloc/credentials_state.dart new file mode 100644 index 00000000..2d50f0f9 --- /dev/null +++ b/lib/presentation/credentials_screen/bloc/credentials_state.dart @@ -0,0 +1,43 @@ +// ignore_for_file: must_be_immutable + +part of 'credentials_bloc.dart'; + +/// Represents the state of Credentials in the application. +class CredentialsState extends Equatable { + CredentialsState({ + this.valueController, + this.passwordController, + this.passwordConfirmationController, + this.credentialsModelObj, + }); + + TextEditingController? valueController; + + TextEditingController? passwordController; + + TextEditingController? passwordConfirmationController; + + CredentialsModel? credentialsModelObj; + + @override + List get props => [ + valueController, + passwordController, + passwordConfirmationController, + credentialsModelObj, + ]; + CredentialsState copyWith({ + TextEditingController? valueController, + TextEditingController? passwordController, + TextEditingController? passwordConfirmationController, + CredentialsModel? credentialsModelObj, + }) { + return CredentialsState( + valueController: valueController ?? this.valueController, + passwordController: passwordController ?? this.passwordController, + passwordConfirmationController: + passwordConfirmationController ?? this.passwordConfirmationController, + credentialsModelObj: credentialsModelObj ?? this.credentialsModelObj, + ); + } +} diff --git a/lib/presentation/credentials_screen/credentials_screen.dart b/lib/presentation/credentials_screen/credentials_screen.dart new file mode 100644 index 00000000..978aea11 --- /dev/null +++ b/lib/presentation/credentials_screen/credentials_screen.dart @@ -0,0 +1,136 @@ +import 'bloc/credentials_bloc.dart'; +import 'models/credentials_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class CredentialsScreen extends StatelessWidget { + static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; + return BlocProvider( + create: (context) => CredentialsBloc( + CredentialsState( + credentialsModelObj: CredentialsModel(userRegistrationSheet: sheet), + ), + )..add(CredentialsInitialEvent()), + child: CredentialsScreen(), + ); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: 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: 93.v), + Text("email".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.valueController, + builder: (context, valueController) { + return CustomTextFormField( + controller: valueController, + 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: () { + UserRegistrationSheet sheet = + state.credentialsModelObj!.userRegistrationSheet; + sheet.email = state.valueController!.text; + sheet.password = state.passwordController!.text; + sheet.passwordConfirmation = + state.passwordConfirmationController!.text; + Navigator.pushNamed( + context, + AppRoutes.nameScreen, + arguments: sheet, + ); + }); + }), + SizedBox(height: 17.v), + ])))); + } + + /// Section Widget + PreferredSizeWidget _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)); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/credentials_screen/models/credentials_model.dart b/lib/presentation/credentials_screen/models/credentials_model.dart new file mode 100644 index 00000000..ae6c3201 --- /dev/null +++ b/lib/presentation/credentials_screen/models/credentials_model.dart @@ -0,0 +1,22 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; + +/// This class defines the variables used in the [credentials_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class CredentialsModel extends Equatable { + UserRegistrationSheet userRegistrationSheet; + + CredentialsModel({required this.userRegistrationSheet}); + + CredentialsModel copyWith({UserRegistrationSheet? userRegistrationSheet}) { + return CredentialsModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); + } + + @override + List get props => [userRegistrationSheet]; +} diff --git a/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart b/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart index 26b3a1ab..5c3dcb6e 100644 --- a/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart +++ b/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart @@ -4,16 +4,20 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; class DateOfBirthScreen extends StatefulWidget { const DateOfBirthScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => DateOfBirthBloc( - DateOfBirthState(dateOfBirthModelObj: DateOfBirthModel())) + create: (context) => DateOfBirthBloc(DateOfBirthState( + dateOfBirthModelObj: + DateOfBirthModel(userRegistrationSheet: sheet))) ..add(DateOfBirthInitialEvent()), child: DateOfBirthScreen()); } @@ -37,25 +41,46 @@ class _DateOfBirthScreenState extends State { padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), child: Column(children: [ - SizedBox(height: 7.v), - _buildProgressIndicator(context), + 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)))), SizedBox(height: 38.v), Text("date_of_birth".tr, style: theme.textTheme.headlineSmall), Spacer(flex: 39), _buildDateInput(context), Spacer(flex: 60), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToCity(context); - }), + 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: () { + UserRegistrationSheet sheet = state + .dateOfBirthModelObj!.userRegistrationSheet; + sheet.birthdate = selectedDate; + Navigator.pushNamed( + context, + AppRoutes.cityOfLivingScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), - Padding( - padding: EdgeInsets.only(left: 8.h), - child: - Text("skip".tr, style: theme.textTheme.bodyLarge)) ])))); }); } @@ -74,23 +99,6 @@ class _DateOfBirthScreenState extends State { title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } - /// Section Widget - Widget _buildProgressIndicator(BuildContext context) { - return Container( - width: 343.h, - padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), - decoration: AppDecoration.outlinePrimary - .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), - child: Container( - height: 8.v, - width: 60.h, - decoration: BoxDecoration( - color: appTheme.blueA400, - borderRadius: BorderRadius.circular(4.h), - border: - Border.all(color: theme.colorScheme.primary, width: 1.h)))); - } - /// Section Widget Widget _buildDateInput(BuildContext context) { return Container( @@ -131,11 +139,10 @@ class _DateOfBirthScreenState extends State { /// /// This function returns a `Future` that completes with `void`. Future openDatePickerDialog(BuildContext context) async { - var initialState = BlocProvider.of(context).state; DateTime? dateTime = await showDatePicker( context: context, initialDate: DateTime.now(), - firstDate: DateTime(1970), + firstDate: DateTime(1924), lastDate: DateTime( DateTime.now().year, DateTime.now().month, DateTime.now().day)); if (dateTime != null) { @@ -144,11 +151,4 @@ class _DateOfBirthScreenState extends State { }); } } - - /// Navigates to the cityOfLivingScreen when the action is triggered. - navigateToCity(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.cityOfLivingScreen, - ); - } } diff --git a/lib/presentation/date_of_birth_screen/models/date_of_birth_model.dart b/lib/presentation/date_of_birth_screen/models/date_of_birth_model.dart index 3cc83943..98700d4c 100644 --- a/lib/presentation/date_of_birth_screen/models/date_of_birth_model.dart +++ b/lib/presentation/date_of_birth_screen/models/date_of_birth_model.dart @@ -1,16 +1,22 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [date_of_birth_screen], /// and is typically used to hold data that is passed between different parts of the application. class DateOfBirthModel extends Equatable { - DateOfBirthModel() {} + UserRegistrationSheet userRegistrationSheet; + + DateOfBirthModel({required this.userRegistrationSheet}); DateOfBirthModel copyWith() { - return DateOfBirthModel(); + return DateOfBirthModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); } @override - List get props => []; + List get props => [userRegistrationSheet]; } diff --git a/lib/presentation/favorite_foods_screen/bloc/favorite_foods_bloc.dart b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_bloc.dart index 95c740fe..3fcb2c5b 100644 --- a/lib/presentation/favorite_foods_screen/bloc/favorite_foods_bloc.dart +++ b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_bloc.dart @@ -16,7 +16,7 @@ class FavoriteFoodsBloc extends Bloc { Emitter emit, ) async { emit(state.copyWith( - enterinformationController: TextEditingController(), - enterinformationController1: TextEditingController())); + favoriteFoodsController: TextEditingController(), + unfavoriteFoodsController: TextEditingController())); } } diff --git a/lib/presentation/favorite_foods_screen/bloc/favorite_foods_state.dart b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_state.dart index fd14b209..aa4fc3b8 100644 --- a/lib/presentation/favorite_foods_screen/bloc/favorite_foods_state.dart +++ b/lib/presentation/favorite_foods_screen/bloc/favorite_foods_state.dart @@ -5,33 +5,33 @@ part of 'favorite_foods_bloc.dart'; /// Represents the state of FavoriteFoods in the application. class FavoriteFoodsState extends Equatable { FavoriteFoodsState({ - this.enterinformationController, - this.enterinformationController1, + this.favoriteFoodsController, + this.unfavoriteFoodsController, this.favoriteFoodsModelObj, }); - TextEditingController? enterinformationController; + TextEditingController? favoriteFoodsController; - TextEditingController? enterinformationController1; + TextEditingController? unfavoriteFoodsController; FavoriteFoodsModel? favoriteFoodsModelObj; @override List get props => [ - enterinformationController, - enterinformationController1, + favoriteFoodsController, + unfavoriteFoodsController, favoriteFoodsModelObj, ]; FavoriteFoodsState copyWith({ - TextEditingController? enterinformationController, - TextEditingController? enterinformationController1, + TextEditingController? favoriteFoodsController, + TextEditingController? unfavoriteFoodsController, FavoriteFoodsModel? favoriteFoodsModelObj, }) { return FavoriteFoodsState( - enterinformationController: - enterinformationController ?? this.enterinformationController, - enterinformationController1: - enterinformationController1 ?? this.enterinformationController1, + favoriteFoodsController: + favoriteFoodsController ?? this.favoriteFoodsController, + unfavoriteFoodsController: + unfavoriteFoodsController ?? this.unfavoriteFoodsController, favoriteFoodsModelObj: favoriteFoodsModelObj ?? this.favoriteFoodsModelObj, ); diff --git a/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart b/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart index 2d0a0a34..625d221d 100644 --- a/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart +++ b/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart @@ -4,21 +4,30 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/widgets/custom_text_form_field.dart'; import 'package:flutter/material.dart'; -class FavoriteFoodsScreen extends StatelessWidget { +class FavoriteFoodsScreen extends StatefulWidget { const FavoriteFoodsScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => FavoriteFoodsBloc( - FavoriteFoodsState(favoriteFoodsModelObj: FavoriteFoodsModel())) + create: (context) => FavoriteFoodsBloc(FavoriteFoodsState( + favoriteFoodsModelObj: + FavoriteFoodsModel(userRegistrationSheet: sheet))) ..add(FavoriteFoodsInitialEvent()), child: FavoriteFoodsScreen()); } + @override + State createState() => _FavoriteFoodsScreenState(); +} + +class _FavoriteFoodsScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -31,7 +40,21 @@ class FavoriteFoodsScreen extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), child: Column(children: [ SizedBox(height: 7.v), - _buildProgressIndicator(context), + 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, @@ -42,16 +65,31 @@ class FavoriteFoodsScreen extends StatelessWidget { textAlign: TextAlign.center, style: theme.textTheme.headlineSmall)), SizedBox(height: 23.v), - _buildTextFormField(context), + _buildTextFormFieldFav(context), SizedBox(height: 22.v), - _buildTextFormField1(context), + _buildTextFormFieldUnfav(context), SizedBox(height: 27.v), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToSchedule(context); - }), + 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: () { + UserRegistrationSheet sheet = state + .favoriteFoodsModelObj!.userRegistrationSheet; + sheet.favoriteFoods = + state.favoriteFoodsController!.text; + sheet.unfavoriteFoods = + state.unfavoriteFoodsController!.text; + Navigator.pushNamed( + context, + AppRoutes.additionalInformationScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); @@ -72,33 +110,16 @@ class FavoriteFoodsScreen extends StatelessWidget { } /// Section Widget - Widget _buildProgressIndicator(BuildContext context) { - return Container( - width: 343.h, - padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), - decoration: AppDecoration.outlinePrimary - .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), - child: Container( - height: 8.v, - width: 279.h, - decoration: BoxDecoration( - color: appTheme.blueA400, - borderRadius: BorderRadius.circular(4.h), - border: - Border.all(color: theme.colorScheme.primary, width: 1.h)))); - } - - /// Section Widget - Widget _buildTextFormField(BuildContext context) { + Widget _buildTextFormFieldFav(BuildContext context) { return Column(children: [ Text("favorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI), SizedBox(height: 2.v), BlocSelector( - selector: (state) => state.enterinformationController, - builder: (context, enterinformationController) { + selector: (state) => state.favoriteFoodsController, + builder: (context, favoriteFoodsController) { return CustomTextFormField( - controller: enterinformationController, + controller: favoriteFoodsController, hintText: "enter_information".tr, maxLines: 7); }) @@ -106,16 +127,16 @@ class FavoriteFoodsScreen extends StatelessWidget { } /// Section Widget - Widget _buildTextFormField1(BuildContext context) { + Widget _buildTextFormFieldUnfav(BuildContext context) { return Column(children: [ Text("unfavorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI), SizedBox(height: 2.v), BlocSelector( - selector: (state) => state.enterinformationController1, - builder: (context, enterinformationController1) { + selector: (state) => state.unfavoriteFoodsController, + builder: (context, unfavoriteFoodsController) { return CustomTextFormField( - controller: enterinformationController1, + controller: unfavoriteFoodsController, hintText: "enter_information".tr, textInputAction: TextInputAction.done, maxLines: 7); @@ -129,9 +150,9 @@ class FavoriteFoodsScreen extends StatelessWidget { } /// Navigates to the scheduleScreen when the action is triggered. - navigateToSchedule(BuildContext context) { + navigateToAdditionalInformationScreen(BuildContext context) { NavigatorService.pushNamed( - AppRoutes.scheduleScreen, + AppRoutes.additionalInformationScreen, ); } } diff --git a/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart b/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart index 3df7820b..2084cade 100644 --- a/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart +++ b/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart @@ -1,16 +1,21 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [favorite_foods_screen], /// and is typically used to hold data that is passed between different parts of the application. class FavoriteFoodsModel extends Equatable { - FavoriteFoodsModel() {} + UserRegistrationSheet userRegistrationSheet; + FavoriteFoodsModel({required this.userRegistrationSheet}); FavoriteFoodsModel copyWith() { - return FavoriteFoodsModel(); + return FavoriteFoodsModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); } @override - List get props => []; + List get props => [userRegistrationSheet]; } diff --git a/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart b/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart index 0ebdf9d6..2d531bea 100644 --- a/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart +++ b/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart @@ -4,21 +4,30 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/widgets/custom_text_form_field.dart'; import 'package:flutter/material.dart'; -class FavoriteSportsScreen extends StatelessWidget { +class FavoriteSportsScreen extends StatefulWidget { const FavoriteSportsScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => FavoriteSportsBloc( - FavoriteSportsState(favoriteSportsModelObj: FavoriteSportsModel())) + create: (context) => FavoriteSportsBloc(FavoriteSportsState( + favoriteSportsModelObj: + FavoriteSportsModel(userRegistrationSheet: sheet))) ..add(FavoriteSportsInitialEvent()), child: FavoriteSportsScreen()); } + @override + State createState() => _FavoriteSportsScreenState(); +} + +class _FavoriteSportsScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -33,19 +42,48 @@ class FavoriteSportsScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox(height: 20.v), - _buildProgressIndicatorSection(context), + 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), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToFoods(context); - }), + 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: () { + UserRegistrationSheet sheet = state + .favoriteSportsModelObj! + .userRegistrationSheet; + sheet.aboutSportHobbies = + state.enterinformationController!.text; + Navigator.pushNamed( + context, + AppRoutes.favoriteFoodsScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), Text("skip".tr, style: theme.textTheme.bodyLarge), SizedBox(height: 4.v) @@ -65,23 +103,6 @@ class FavoriteSportsScreen extends StatelessWidget { title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } - /// Section Widget - Widget _buildProgressIndicatorSection(BuildContext context) { - return Container( - width: 343.h, - padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), - decoration: AppDecoration.outlinePrimary - .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), - child: Container( - height: 8.v, - width: 259.h, - decoration: BoxDecoration( - color: appTheme.blueA400, - borderRadius: BorderRadius.circular(4.h), - border: - Border.all(color: theme.colorScheme.primary, width: 1.h)))); - } - /// Section Widget Widget _buildTextFormFieldSection(BuildContext context) { return Column(children: [ @@ -104,11 +125,4 @@ class FavoriteSportsScreen extends StatelessWidget { onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); } - - /// Navigates to the favoriteFoodsScreen when the action is triggered. - navigateToFoods(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.favoriteFoodsScreen, - ); - } } diff --git a/lib/presentation/favorite_sports_screen/models/favorite_sports_model.dart b/lib/presentation/favorite_sports_screen/models/favorite_sports_model.dart index aa5c41b0..11a1e288 100644 --- a/lib/presentation/favorite_sports_screen/models/favorite_sports_model.dart +++ b/lib/presentation/favorite_sports_screen/models/favorite_sports_model.dart @@ -1,16 +1,21 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [favorite_sports_screen], /// and is typically used to hold data that is passed between different parts of the application. class FavoriteSportsModel extends Equatable { - FavoriteSportsModel() {} + UserRegistrationSheet userRegistrationSheet; + FavoriteSportsModel({required this.userRegistrationSheet}); FavoriteSportsModel copyWith() { - return FavoriteSportsModel(); + return FavoriteSportsModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); } @override - List get props => []; + List get props => [userRegistrationSheet]; } diff --git a/lib/presentation/gender_screen/bloc/gender_bloc.dart b/lib/presentation/gender_screen/bloc/gender_bloc.dart index 2d2b2618..7a2d4092 100644 --- a/lib/presentation/gender_screen/bloc/gender_bloc.dart +++ b/lib/presentation/gender_screen/bloc/gender_bloc.dart @@ -9,10 +9,21 @@ part 'gender_state.dart'; class GenderBloc extends Bloc { GenderBloc(GenderState initialState) : super(initialState) { on(_onInitialize); + on(_genderSelect); } _onInitialize( GenderInitialEvent event, Emitter emit, - ) async {} + ) async { + emit(state.copyWith(genderModelObj: state.genderModelObj)); + } + + _genderSelect( + GenderSelectEvent event, + Emitter emit, + ) { + emit(state.copyWith(selectedRadioValue: event.value)); + state.genderModelObj?.userRegistrationSheet.gender = event.value; + } } diff --git a/lib/presentation/gender_screen/bloc/gender_event.dart b/lib/presentation/gender_screen/bloc/gender_event.dart index 3660a87c..f6b9f69c 100644 --- a/lib/presentation/gender_screen/bloc/gender_event.dart +++ b/lib/presentation/gender_screen/bloc/gender_event.dart @@ -9,8 +9,18 @@ part of 'gender_bloc.dart'; @immutable abstract class GenderEvent extends Equatable {} -/// Event that is dispatched when the Gender widget is first created. class GenderInitialEvent extends GenderEvent { @override List get props => []; } + +class GenderSelectEvent extends GenderEvent { + GenderSelectEvent({required this.value}); + + String value; + + @override + List get props => [ + value, + ]; +} diff --git a/lib/presentation/gender_screen/bloc/gender_state.dart b/lib/presentation/gender_screen/bloc/gender_state.dart index 16109442..996082e8 100644 --- a/lib/presentation/gender_screen/bloc/gender_state.dart +++ b/lib/presentation/gender_screen/bloc/gender_state.dart @@ -4,16 +4,26 @@ part of 'gender_bloc.dart'; /// Represents the state of Gender in the application. class GenderState extends Equatable { - GenderState({this.genderModelObj}); + GenderState({ + this.selectedRadioValue, + this.genderModelObj, + }); + + String? selectedRadioValue; GenderModel? genderModelObj; @override List get props => [ + selectedRadioValue, genderModelObj, ]; - GenderState copyWith({GenderModel? genderModelObj}) { + GenderState copyWith({ + String? selectedRadioValue, + GenderModel? genderModelObj, + }) { return GenderState( + selectedRadioValue: selectedRadioValue ?? this.selectedRadioValue, genderModelObj: genderModelObj ?? this.genderModelObj, ); } diff --git a/lib/presentation/gender_screen/gender_screen.dart b/lib/presentation/gender_screen/gender_screen.dart index 31b0596a..be2c3f42 100644 --- a/lib/presentation/gender_screen/gender_screen.dart +++ b/lib/presentation/gender_screen/gender_screen.dart @@ -1,23 +1,33 @@ import 'bloc/gender_bloc.dart'; import 'models/gender_model.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; import 'package:flutter/material.dart'; -class GenderScreen extends StatelessWidget { +class GenderScreen extends StatefulWidget { const GenderScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => - GenderBloc(GenderState(genderModelObj: GenderModel())) - ..add(GenderInitialEvent()), + create: (context) => GenderBloc( + GenderState( + genderModelObj: GenderModel(userRegistrationSheet: sheet), + ), + )..add(GenderInitialEvent()), child: GenderScreen()); } + @override + State createState() => _GenderScreenState(); +} + +class _GenderScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -31,23 +41,72 @@ class GenderScreen extends StatelessWidget { EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), child: Column(children: [ SizedBox(height: 7.v), - _buildProgressIndicator(context), + 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)))), SizedBox(height: 36.v), Text("your_gender".tr, style: theme.textTheme.headlineSmall), - Spacer(flex: 33), - Text(""), - SizedBox(height: 20.v), - Text(""), + RadioListTile( + title: Text('Мужской'), + value: 'male', + groupValue: state.selectedRadioValue, + onChanged: (value) { + BlocProvider.of(context) + .add(GenderSelectEvent(value: 'male')); + }, + secondary: Image.asset( + 'assets/images/img_male.png', + width: 40, + height: 40, + ), + ), + RadioListTile( + title: Text('Женский'), + value: 'female', + groupValue: state.selectedRadioValue, + onChanged: (value) { + BlocProvider.of(context) + .add(GenderSelectEvent(value: 'female')); + }, + secondary: Image.asset( + 'assets/images/img_female.png', + width: 40, + height: 40, + ), + ), Spacer(flex: 66), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToDate(context); - }), + 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: () { + UserRegistrationSheet sheet = + state.genderModelObj!.userRegistrationSheet; + sheet.gender = state.selectedRadioValue!; + Navigator.pushNamed( + context, + AppRoutes.dateOfBirthScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); }); } @@ -60,38 +119,16 @@ class GenderScreen extends StatelessWidget { imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: () { - onTapArrowLeft(context); + NavigatorService.pushNamed( + AppRoutes.dateOfBirthScreen, + ); }), centerTitle: true, title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } - /// Section Widget - Widget _buildProgressIndicator(BuildContext context) { - return Container( - width: 343.h, - padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), - decoration: AppDecoration.outlinePrimary - .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), - child: Container( - height: 8.v, - width: 40.h, - decoration: BoxDecoration( - color: appTheme.blueA400, - borderRadius: BorderRadius.circular(4.h), - border: - Border.all(color: theme.colorScheme.primary, width: 1.h)))); - } - /// Navigates to the previous screen. onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); } - - /// Navigates to the dateOfBirthScreen when the action is triggered. - navigateToDate(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.dateOfBirthScreen, - ); - } } diff --git a/lib/presentation/gender_screen/models/gender_model.dart b/lib/presentation/gender_screen/models/gender_model.dart index 1ba38218..b314fba5 100644 --- a/lib/presentation/gender_screen/models/gender_model.dart +++ b/lib/presentation/gender_screen/models/gender_model.dart @@ -1,16 +1,20 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [gender_screen], /// and is typically used to hold data that is passed between different parts of the application. class GenderModel extends Equatable { - GenderModel() {} + UserRegistrationSheet userRegistrationSheet; + GenderModel({required this.userRegistrationSheet}); - GenderModel copyWith() { - return GenderModel(); + GenderModel copyWith({UserRegistrationSheet? userRegistrationSheet, gender}) { + return GenderModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet); } @override - List get props => []; + List get props => [userRegistrationSheet]; } diff --git a/lib/presentation/height_screen/bloc/height_bloc.dart b/lib/presentation/height_screen/bloc/height_bloc.dart index 481fd778..629778fe 100644 --- a/lib/presentation/height_screen/bloc/height_bloc.dart +++ b/lib/presentation/height_screen/bloc/height_bloc.dart @@ -26,6 +26,8 @@ class HeightBloc extends Bloc { Emitter emit, ) { emit(state.copyWith(selectedDropDownValue: event.value)); + state.heightModelObj?.userRegistrationSheet.height = + int.tryParse(event.value.title)!; } List fillDropdownItemList() { diff --git a/lib/presentation/height_screen/height_screen.dart b/lib/presentation/height_screen/height_screen.dart index 9d247207..17a5a9ab 100644 --- a/lib/presentation/height_screen/height_screen.dart +++ b/lib/presentation/height_screen/height_screen.dart @@ -5,20 +5,28 @@ import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; import 'package:eatvio_app/widgets/custom_drop_down.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; -class HeightScreen extends StatelessWidget { +class HeightScreen extends StatefulWidget { const HeightScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => - HeightBloc(HeightState(heightModelObj: HeightModel())) - ..add(HeightInitialEvent()), + create: (context) => HeightBloc(HeightState( + heightModelObj: HeightModel(userRegistrationSheet: sheet))) + ..add(HeightInitialEvent()), child: HeightScreen()); } + @override + State createState() => _HeightScreenState(); +} + +class _HeightScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -41,21 +49,61 @@ class HeightScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.35, + value: 0.55, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400)))), SizedBox(height: 39.v), - _buildTwentySix(context), + Column(children: [ + Text("height_measurements".tr, + style: theme.textTheme.headlineSmall), + SizedBox(height: 174.v), + Column(children: [ + Text("your_height".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 4.v), + BlocSelector( + selector: (state) => state.heightModelObj, + builder: (context, heightModelObj) { + 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: "170", + items: heightModelObj?.dropdownItemList ?? [], + onChanged: (value) { + context + .read() + .add(ChangeDropDownEvent(value: value)); + }); + }) + ]) + ]), Spacer(), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToAllergies(context); - }), + 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: () { + UserRegistrationSheet sheet = + state.heightModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.allergiesScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); } @@ -73,52 +121,8 @@ class HeightScreen extends StatelessWidget { title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } - /// Section Widget - Widget _buildTwentySixWidget(BuildContext context) { - return Column(children: [ - Text("your_height".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 4.v), - BlocSelector( - selector: (state) => state.heightModelObj, - builder: (context, heightModelObj) { - 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: "170", - items: heightModelObj?.dropdownItemList ?? [], - onChanged: (value) { - context - .read() - .add(ChangeDropDownEvent(value: value)); - }); - }) - ]); - } - - /// Section Widget - Widget _buildTwentySix(BuildContext context) { - return Column(children: [ - Text("height_measurements".tr, style: theme.textTheme.headlineSmall), - SizedBox(height: 174.v), - _buildTwentySixWidget(context) - ]); - } - /// Navigates to the previous screen. onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); } - - /// Navigates to the allergiesScreen when the action is triggered. - navigateToAllergies(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.allergiesScreen, - ); - } } diff --git a/lib/presentation/height_screen/models/height_model.dart b/lib/presentation/height_screen/models/height_model.dart index 0a9a4448..b108d7d9 100644 --- a/lib/presentation/height_screen/models/height_model.dart +++ b/lib/presentation/height_screen/models/height_model.dart @@ -2,20 +2,25 @@ import 'package:equatable/equatable.dart'; import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [height_screen], /// and is typically used to hold data that is passed between different parts of the application. class HeightModel extends Equatable { - HeightModel({this.dropdownItemList = const []}) {} + UserRegistrationSheet userRegistrationSheet; + HeightModel( + {this.dropdownItemList = const [], required this.userRegistrationSheet}); List dropdownItemList; HeightModel copyWith({List? dropdownItemList}) { return HeightModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, dropdownItemList: dropdownItemList ?? this.dropdownItemList, ); } @override - List get props => [dropdownItemList]; + List get props => [dropdownItemList, userRegistrationSheet]; } diff --git a/lib/presentation/language_select_screen/bloc/language_select_bloc.dart b/lib/presentation/language_select_screen/bloc/language_select_bloc.dart index 8560203b..d6ae042c 100644 --- a/lib/presentation/language_select_screen/bloc/language_select_bloc.dart +++ b/lib/presentation/language_select_screen/bloc/language_select_bloc.dart @@ -27,6 +27,8 @@ class LanguageSelectBloc Emitter emit, ) { emit(state.copyWith(selectedDropDownValue: event.value)); + state.languageSelectModelObj?.userRegistrationSheet.lang = + event.value.title; } List fillDropdownItemList() { diff --git a/lib/presentation/language_select_screen/language_select_screen.dart b/lib/presentation/language_select_screen/language_select_screen.dart index 2cc0e368..9bae529d 100644 --- a/lib/presentation/language_select_screen/language_select_screen.dart +++ b/lib/presentation/language_select_screen/language_select_screen.dart @@ -1,13 +1,14 @@ +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; + import 'bloc/language_select_bloc.dart'; import 'models/language_select_model.dart'; import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/custom_drop_down.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; import 'package:flutter/material.dart'; class LanguageSelectScreen extends StatelessWidget { const LanguageSelectScreen({Key? key}) : super(key: key); - static Widget builder(BuildContext context) { return BlocProvider( create: (context) => LanguageSelectBloc( @@ -30,7 +31,21 @@ class LanguageSelectScreen extends StatelessWidget { height: 50.adaptSize, width: 50.adaptSize), SizedBox(height: 20.v), - _buildProgressIndicatorSection(context), + 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, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400)))), SizedBox(height: 20.v), Container( width: 262.h, @@ -44,7 +59,10 @@ class LanguageSelectScreen extends StatelessWidget { BlocSelector( selector: (state) => state.languageSelectModelObj, - builder: (context, languageSelectModelObj) { + builder: ( + context, + languageSelectModelObj, + ) { return CustomDropDown( icon: Container( margin: @@ -55,7 +73,7 @@ class LanguageSelectScreen extends StatelessWidget { imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize)), - hintText: "Русский".tr, + hintText: "Не выбрано".tr, items: languageSelectModelObj?.dropdownItemList ?? [], onChanged: (value) { @@ -66,41 +84,23 @@ class LanguageSelectScreen extends StatelessWidget { }), Spacer(flex: 63) ])), - bottomNavigationBar: _buildContinueButtonSection(context))); - } - - /// Section Widget - Widget _buildProgressIndicatorSection(BuildContext context) { - return Container( - width: 343.h, - padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), - decoration: AppDecoration.outlinePrimary - .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), - child: Container( - height: 8.v, - width: 20.h, - decoration: BoxDecoration( - color: appTheme.blueA400, - borderRadius: BorderRadius.circular(4.h), - border: - Border.all(color: theme.colorScheme.primary, width: 1.h)))); - } - - /// Section Widget - Widget _buildContinueButtonSection(BuildContext context) { - return CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigteToGender(context); - }); - } - - /// Navigates to the genderScreen when the action is triggered. - navigteToGender(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.genderScreen, - ); + bottomNavigationBar: + 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: () { + UserRegistrationSheet sheet = + state.languageSelectModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.credentialsScreen, + arguments: sheet, + ); + }); + }))); } } diff --git a/lib/presentation/language_select_screen/models/language_select_model.dart b/lib/presentation/language_select_screen/models/language_select_model.dart index 0b9cb205..1df7f8aa 100644 --- a/lib/presentation/language_select_screen/models/language_select_model.dart +++ b/lib/presentation/language_select_screen/models/language_select_model.dart @@ -1,13 +1,41 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; /// This class defines the variables used in the [language_select_screen], /// and is typically used to hold data that is passed between different parts of the application. class LanguageSelectModel extends Equatable { - LanguageSelectModel({this.dropdownItemList = const []}) {} - + LanguageSelectModel({this.dropdownItemList = const []}); + UserRegistrationSheet userRegistrationSheet = UserRegistrationSheet( + firstName: '', + lastName: '', + email: '', + password: '', + passwordConfirmation: '', + termsAccepted: false, + birthdate: DateTime.now(), + gender: '', + country: '', + city: '', + lang: '', + weight: 0, + height: 0, + chestCircumference: 0, + waistCircumference: 0, + hipCircumference: 0, + bloodPressureUp: 0, + bloodPressureDown: 0, + hasHypo: false, + hasHyper: false, + aboutAllergy: '', + aboutTakingPils: '', + aboutSportHobbies: '', + favoriteFoods: '', + unfavoriteFoods: '', + additionalInfo: '', + ); List dropdownItemList; LanguageSelectModel copyWith({List? dropdownItemList}) { diff --git a/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart b/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart index 51f7e73c..5b8fdb95 100644 --- a/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart +++ b/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart @@ -4,21 +4,30 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; -class MedicineIntakeScreen extends StatelessWidget { +class MedicineIntakeScreen extends StatefulWidget { const MedicineIntakeScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => MedicineIntakeBloc( - MedicineIntakeState(medicineIntakeModelObj: MedicineIntakeModel())) + create: (context) => MedicineIntakeBloc(MedicineIntakeState( + medicineIntakeModelObj: + MedicineIntakeModel(userRegistrationSheet: sheet))) ..add(MedicineIntakeInitialEvent()), child: MedicineIntakeScreen()); } + @override + State createState() => _MedicineIntakeScreenState(); +} + +class _MedicineIntakeScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -42,7 +51,7 @@ class MedicineIntakeScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.47, + value: 0.69, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400)))), @@ -58,12 +67,25 @@ class MedicineIntakeScreen extends StatelessWidget { SizedBox(height: 86.v), _buildTextFormField(context), Spacer(), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToPressure(context); - }), + 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: () { + UserRegistrationSheet sheet = state + .medicineIntakeModelObj!.userRegistrationSheet; + sheet.aboutTakingPils = + state.enterInformationController!.text; + Navigator.pushNamed( + context, + AppRoutes.bloodPressureScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); @@ -106,11 +128,4 @@ class MedicineIntakeScreen extends StatelessWidget { onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); } - - /// Navigates to the bloodPressureScreen when the action is triggered. - navigateToPressure(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.bloodPressureScreen, - ); - } } diff --git a/lib/presentation/medicine_intake_screen/models/medicine_intake_model.dart b/lib/presentation/medicine_intake_screen/models/medicine_intake_model.dart index 29323f2d..9828f2d8 100644 --- a/lib/presentation/medicine_intake_screen/models/medicine_intake_model.dart +++ b/lib/presentation/medicine_intake_screen/models/medicine_intake_model.dart @@ -1,16 +1,21 @@ // ignore_for_file: must_be_immutable import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [medicine_intake_screen], /// and is typically used to hold data that is passed between different parts of the application. class MedicineIntakeModel extends Equatable { - MedicineIntakeModel() {} + UserRegistrationSheet userRegistrationSheet; + MedicineIntakeModel({required this.userRegistrationSheet}); MedicineIntakeModel copyWith() { - return MedicineIntakeModel(); + return MedicineIntakeModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); } @override - List get props => []; + List get props => [userRegistrationSheet]; } diff --git a/lib/presentation/name_screen/bloc/name_bloc.dart b/lib/presentation/name_screen/bloc/name_bloc.dart new file mode 100644 index 00000000..00baf316 --- /dev/null +++ b/lib/presentation/name_screen/bloc/name_bloc.dart @@ -0,0 +1,22 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/name_screen/models/name_model.dart'; +part 'name_event.dart'; +part 'name_state.dart'; + +/// A bloc that manages the state of a Name according to the event that is dispatched to it. +class NameBloc extends Bloc { + NameBloc(NameState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + NameInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + firstNameController: TextEditingController(), + lastNameController: TextEditingController())); + } +} diff --git a/lib/presentation/schedule_screen/bloc/schedule_event.dart b/lib/presentation/name_screen/bloc/name_event.dart similarity index 51% rename from lib/presentation/schedule_screen/bloc/schedule_event.dart rename to lib/presentation/name_screen/bloc/name_event.dart index 711e4eaf..7e102994 100644 --- a/lib/presentation/schedule_screen/bloc/schedule_event.dart +++ b/lib/presentation/name_screen/bloc/name_event.dart @@ -1,16 +1,16 @@ // ignore_for_file: must_be_immutable -part of 'schedule_bloc.dart'; +part of 'name_bloc.dart'; /// Abstract class for all events that can be dispatched from the -///Schedule widget. +///Name widget. /// /// Events must be immutable and implement the [Equatable] interface. @immutable -abstract class ScheduleEvent extends Equatable {} +abstract class NameEvent extends Equatable {} -/// Event that is dispatched when the Schedule widget is first created. -class ScheduleInitialEvent extends ScheduleEvent { +/// Event that is dispatched when the Name widget is first created. +class NameInitialEvent extends NameEvent { @override List get props => []; } diff --git a/lib/presentation/name_screen/bloc/name_state.dart b/lib/presentation/name_screen/bloc/name_state.dart new file mode 100644 index 00000000..b3e0980b --- /dev/null +++ b/lib/presentation/name_screen/bloc/name_state.dart @@ -0,0 +1,36 @@ +// ignore_for_file: must_be_immutable + +part of 'name_bloc.dart'; + +/// Represents the state of Name in the application. +class NameState extends Equatable { + NameState({ + this.firstNameController, + this.lastNameController, + this.nameModelObj, + }); + + TextEditingController? firstNameController; + + TextEditingController? lastNameController; + + NameModel? nameModelObj; + + @override + List get props => [ + firstNameController, + lastNameController, + nameModelObj, + ]; + NameState copyWith({ + TextEditingController? firstNameController, + TextEditingController? lastNameController, + NameModel? nameModelObj, + }) { + return NameState( + firstNameController: firstNameController ?? this.firstNameController, + lastNameController: lastNameController ?? this.lastNameController, + nameModelObj: nameModelObj ?? this.nameModelObj, + ); + } +} diff --git a/lib/presentation/name_screen/models/name_model.dart b/lib/presentation/name_screen/models/name_model.dart new file mode 100644 index 00000000..6fa44b07 --- /dev/null +++ b/lib/presentation/name_screen/models/name_model.dart @@ -0,0 +1,21 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; + +/// This class defines the variables used in the [name_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class NameModel extends Equatable { + UserRegistrationSheet userRegistrationSheet; + NameModel({required this.userRegistrationSheet}); + + NameModel copyWith({UserRegistrationSheet? userRegistrationSheet}) { + return NameModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, + ); + } + + @override + List get props => []; +} diff --git a/lib/presentation/name_screen/name_screen.dart b/lib/presentation/name_screen/name_screen.dart new file mode 100644 index 00000000..2e7bc8ab --- /dev/null +++ b/lib/presentation/name_screen/name_screen.dart @@ -0,0 +1,119 @@ +import 'bloc/name_bloc.dart'; +import 'models/name_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; +import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/material.dart'; + +class NameScreen extends StatelessWidget { + const NameScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; + return BlocProvider( + create: (context) => NameBloc( + NameState( + nameModelObj: NameModel(userRegistrationSheet: sheet), + ), + )..add(NameInitialEvent()), + child: NameScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: 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, + ); + }), + SizedBox(height: 21.v), + 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: () { + UserRegistrationSheet sheet = + state.nameModelObj!.userRegistrationSheet; + sheet.firstName = state.firstNameController!.text; + sheet.lastName = state.lastNameController!.text; + Navigator.pushNamed( + context, + AppRoutes.genderScreen, + arguments: sheet, + ); + }); + }), + SizedBox(height: 17.v), + ])))); + } + + /// Section Widget + PreferredSizeWidget _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)); + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); + } +} diff --git a/lib/presentation/schedule_screen/bloc/schedule_bloc.dart b/lib/presentation/schedule_screen/bloc/schedule_bloc.dart deleted file mode 100644 index 6dedad4a..00000000 --- a/lib/presentation/schedule_screen/bloc/schedule_bloc.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:equatable/equatable.dart'; -import 'package:flutter/material.dart'; -import '/core/app_export.dart'; -import 'package:eatvio_app/presentation/schedule_screen/models/schedule_model.dart'; -part 'schedule_event.dart'; -part 'schedule_state.dart'; - -/// A bloc that manages the state of a Schedule according to the event that is dispatched to it. -class ScheduleBloc extends Bloc { - ScheduleBloc(ScheduleState initialState) : super(initialState) { - on(_onInitialize); - } - - _onInitialize( - ScheduleInitialEvent event, - Emitter emit, - ) async { - emit(state.copyWith(inputPlaceholderController: TextEditingController())); - } -} diff --git a/lib/presentation/schedule_screen/bloc/schedule_state.dart b/lib/presentation/schedule_screen/bloc/schedule_state.dart deleted file mode 100644 index 4c345db8..00000000 --- a/lib/presentation/schedule_screen/bloc/schedule_state.dart +++ /dev/null @@ -1,31 +0,0 @@ -// ignore_for_file: must_be_immutable - -part of 'schedule_bloc.dart'; - -/// Represents the state of Schedule in the application. -class ScheduleState extends Equatable { - ScheduleState({ - this.inputPlaceholderController, - this.scheduleModelObj, - }); - - TextEditingController? inputPlaceholderController; - - ScheduleModel? scheduleModelObj; - - @override - List get props => [ - inputPlaceholderController, - scheduleModelObj, - ]; - ScheduleState copyWith({ - TextEditingController? inputPlaceholderController, - ScheduleModel? scheduleModelObj, - }) { - return ScheduleState( - inputPlaceholderController: - inputPlaceholderController ?? this.inputPlaceholderController, - scheduleModelObj: scheduleModelObj ?? this.scheduleModelObj, - ); - } -} diff --git a/lib/presentation/schedule_screen/models/schedule_model.dart b/lib/presentation/schedule_screen/models/schedule_model.dart deleted file mode 100644 index 6eb1022f..00000000 --- a/lib/presentation/schedule_screen/models/schedule_model.dart +++ /dev/null @@ -1,16 +0,0 @@ -// ignore_for_file: must_be_immutable - -import 'package:equatable/equatable.dart'; - -/// This class defines the variables used in the [schedule_screen], -/// and is typically used to hold data that is passed between different parts of the application. -class ScheduleModel extends Equatable { - ScheduleModel() {} - - ScheduleModel copyWith() { - return ScheduleModel(); - } - - @override - List get props => []; -} diff --git a/lib/presentation/schedule_screen/schedule_screen.dart b/lib/presentation/schedule_screen/schedule_screen.dart deleted file mode 100644 index 3e29f648..00000000 --- a/lib/presentation/schedule_screen/schedule_screen.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'bloc/schedule_bloc.dart'; -import 'models/schedule_model.dart'; -import 'package:eatvio_app/core/app_export.dart'; -import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; -import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; -import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; -import 'package:eatvio_app/widgets/custom_text_form_field.dart'; -import 'package:flutter/material.dart'; - -class ScheduleScreen extends StatelessWidget { - const ScheduleScreen({Key? key}) : super(key: key); - - static Widget builder(BuildContext context) { - return BlocProvider( - create: (context) => - ScheduleBloc(ScheduleState(scheduleModelObj: ScheduleModel())) - ..add(ScheduleInitialEvent()), - child: ScheduleScreen()); - } - - @override - Widget build(BuildContext context) { - mediaQueryData = MediaQuery.of(context); - return SafeArea( - child: 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), - _buildProgressIndicator(context), - SizedBox(height: 38.v), - Text("your_schedule".tr, - style: theme.textTheme.headlineSmall), - SizedBox(height: 67.v), - _buildTextFormField(context), - Spacer(), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToAdditional(context); - }), - SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) - ])))); - } - - /// Section Widget - PreferredSizeWidget _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: () { - onTapArrowLeft(context); - }), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); - } - - /// Section Widget - Widget _buildProgressIndicator(BuildContext context) { - return Container( - width: 343.h, - padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 3.v), - decoration: AppDecoration.outlinePrimary - .copyWith(borderRadius: BorderRadiusStyle.circleBorder8), - child: Container( - height: 8.v, - width: 297.h, - decoration: BoxDecoration( - color: appTheme.blueA400, - borderRadius: BorderRadius.circular(4.h), - border: - Border.all(color: theme.colorScheme.primary, width: 1.h)))); - } - - /// Section Widget - Widget _buildTextFormField(BuildContext context) { - return Column(children: [ - Container( - width: 324.h, - margin: EdgeInsets.symmetric(horizontal: 9.h), - child: Text("tell_your_schedule".tr, - maxLines: 3, - overflow: TextOverflow.ellipsis, - textAlign: TextAlign.center, - style: CustomTextStyles.titleMediumSegoeUI)), - SizedBox(height: 12.v), - BlocSelector( - selector: (state) => state.inputPlaceholderController, - builder: (context, inputPlaceholderController) { - return CustomTextFormField( - controller: inputPlaceholderController, - hintText: "enter_information".tr, - textInputAction: TextInputAction.done, - maxLines: 8); - }) - ]); - } - - /// Navigates to the previous screen. - onTapArrowLeft(BuildContext context) { - NavigatorService.goBack(); - } - - /// Navigates to the additionalInformationScreen when the action is triggered. - navigateToAdditional(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.additionalInformationScreen, - ); - } -} diff --git a/lib/presentation/splash_screen/models/splash_model.dart b/lib/presentation/splash_screen/models/splash_model.dart index a2d44d6c..6ad8f8f1 100644 --- a/lib/presentation/splash_screen/models/splash_model.dart +++ b/lib/presentation/splash_screen/models/splash_model.dart @@ -5,7 +5,7 @@ import 'package:equatable/equatable.dart'; /// This class defines the variables used in the [splash_screen], /// and is typically used to hold data that is passed between different parts of the application. class SplashModel extends Equatable { - SplashModel() {} + SplashModel(); SplashModel copyWith() { return SplashModel(); diff --git a/lib/presentation/weight_screen/bloc/weight_bloc.dart b/lib/presentation/weight_screen/bloc/weight_bloc.dart index 37ce0901..94091376 100644 --- a/lib/presentation/weight_screen/bloc/weight_bloc.dart +++ b/lib/presentation/weight_screen/bloc/weight_bloc.dart @@ -26,6 +26,8 @@ class WeightBloc extends Bloc { Emitter emit, ) { emit(state.copyWith(selectedDropDownValue: event.value)); + state.weightModelObj?.userRegistrationSheet.weight = + int.tryParse(event.value.title)!; } List fillDropdownItemList() { diff --git a/lib/presentation/weight_screen/models/weight_model.dart b/lib/presentation/weight_screen/models/weight_model.dart index 1ebdb828..e91ceb10 100644 --- a/lib/presentation/weight_screen/models/weight_model.dart +++ b/lib/presentation/weight_screen/models/weight_model.dart @@ -2,20 +2,25 @@ import 'package:equatable/equatable.dart'; import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; /// This class defines the variables used in the [weight_screen], /// and is typically used to hold data that is passed between different parts of the application. class WeightModel extends Equatable { - WeightModel({this.dropdownItemList = const []}) {} + UserRegistrationSheet userRegistrationSheet; + WeightModel( + {this.dropdownItemList = const [], required this.userRegistrationSheet}); List dropdownItemList; WeightModel copyWith({List? dropdownItemList}) { return WeightModel( + userRegistrationSheet: + userRegistrationSheet ?? this.userRegistrationSheet, dropdownItemList: dropdownItemList ?? this.dropdownItemList, ); } @override - List get props => [dropdownItemList]; + List get props => [dropdownItemList, userRegistrationSheet]; } diff --git a/lib/presentation/weight_screen/weight_screen.dart b/lib/presentation/weight_screen/weight_screen.dart index 78a00e21..8e606e1c 100644 --- a/lib/presentation/weight_screen/weight_screen.dart +++ b/lib/presentation/weight_screen/weight_screen.dart @@ -5,20 +5,28 @@ import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; import 'package:eatvio_app/widgets/custom_drop_down.dart'; -import 'package:eatvio_app/widgets/custom_outlined_button.dart'; +import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; -class WeightScreen extends StatelessWidget { +class WeightScreen extends StatefulWidget { const WeightScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { + final sheet = + ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet; return BlocProvider( - create: (context) => - WeightBloc(WeightState(weightModelObj: WeightModel())) - ..add(WeightInitialEvent()), + create: (context) => WeightBloc(WeightState( + weightModelObj: WeightModel(userRegistrationSheet: sheet))) + ..add(WeightInitialEvent()), child: WeightScreen()); } + @override + State createState() => _WeightScreenState(); +} + +class _WeightScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -41,21 +49,61 @@ class WeightScreen extends StatelessWidget { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.35, + value: 0.48, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400)))), SizedBox(height: 39.v), - _buildTwentySix(context), + Column(children: [ + Text("weight_measurements".tr, + style: theme.textTheme.headlineSmall), + SizedBox(height: 174.v), + Column(children: [ + Text("your_weight".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 4.v), + BlocSelector( + selector: (state) => state.weightModelObj, + builder: (context, weightModelObj) { + 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: "Не выбрано", + items: weightModelObj?.dropdownItemList ?? [], + onChanged: (value) { + context + .read() + .add(ChangeDropDownEvent(value: value)); + }); + }) + ]) + ]), Spacer(), - CustomOutlinedButton( - text: "continue".tr.toUpperCase(), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - navigateToHeight(context); - }), + 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: () { + UserRegistrationSheet sheet = + state.weightModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.heightScreen, + arguments: sheet, + ); + }); + }), SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) ])))); } @@ -73,43 +121,6 @@ class WeightScreen extends StatelessWidget { title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } - /// Section Widget - Widget _buildTwentySixWidget(BuildContext context) { - return Column(children: [ - Text("your_weight".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 4.v), - BlocSelector( - selector: (state) => state.weightModelObj, - builder: (context, weightModelObj) { - 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: "70", - items: weightModelObj?.dropdownItemList ?? [], - onChanged: (value) { - context - .read() - .add(ChangeDropDownEvent(value: value)); - }); - }) - ]); - } - - /// Section Widget - Widget _buildTwentySix(BuildContext context) { - return Column(children: [ - Text("weight_measurements".tr, style: theme.textTheme.headlineSmall), - SizedBox(height: 174.v), - _buildTwentySixWidget(context) - ]); - } - /// Navigates to the previous screen. onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 50e3bdfd..0fd6f29e 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -10,10 +10,11 @@ import 'package:eatvio_app/presentation/gender_screen/gender_screen.dart'; import 'package:eatvio_app/presentation/blood_pressure_screen/blood_pressure_screen.dart'; import 'package:eatvio_app/presentation/favorite_sports_screen/favorite_sports_screen.dart'; import 'package:eatvio_app/presentation/favorite_foods_screen/favorite_foods_screen.dart'; -import 'package:eatvio_app/presentation/schedule_screen/schedule_screen.dart'; import 'package:eatvio_app/presentation/additional_information_screen/additional_information_screen.dart'; import 'package:eatvio_app/presentation/language_select_screen/language_select_screen.dart'; import 'package:eatvio_app/presentation/height_screen/height_screen.dart'; +import 'package:eatvio_app/presentation/credentials_screen/credentials_screen.dart'; +import 'package:eatvio_app/presentation/name_screen/name_screen.dart'; import 'package:eatvio_app/presentation/app_navigation_screen/app_navigation_screen.dart'; class AppRoutes { @@ -50,6 +51,10 @@ class AppRoutes { static const String languageSelectScreen = '/language_select_screen'; + static const String nameScreen = '/name_screen'; + + static const String credentialsScreen = '/credentials_screen'; + static const String appNavigationScreen = '/app_navigation_screen'; static const String initialRoute = '/initialRoute'; @@ -60,6 +65,8 @@ class AppRoutes { bodyCircumferencesScreen: BodyCircumferencesScreen.builder, weightScreen: WeightScreen.builder, heightScreen: HeightScreen.builder, + nameScreen: NameScreen.builder, + credentialsScreen: CredentialsScreen.builder, allergiesScreen: AllergiesScreen.builder, medicineIntakeScreen: MedicineIntakeScreen.builder, splashScreen: SplashScreen.builder, @@ -67,7 +74,6 @@ class AppRoutes { bloodPressureScreen: BloodPressureScreen.builder, favoriteSportsScreen: FavoriteSportsScreen.builder, favoriteFoodsScreen: FavoriteFoodsScreen.builder, - scheduleScreen: ScheduleScreen.builder, additionalInformationScreen: AdditionalInformationScreen.builder, languageSelectScreen: LanguageSelectScreen.builder, appNavigationScreen: AppNavigationScreen.builder, diff --git a/lib/theme/custom_button_style.dart b/lib/theme/custom_button_style.dart index ed9839fe..95a5581e 100644 --- a/lib/theme/custom_button_style.dart +++ b/lib/theme/custom_button_style.dart @@ -1,4 +1,3 @@ -import 'dart:ui'; import 'package:eatvio_app/core/app_export.dart'; import 'package:flutter/material.dart'; diff --git a/lib/theme/theme_helper.dart b/lib/theme/theme_helper.dart index db1b9984..e7fb2e95 100644 --- a/lib/theme/theme_helper.dart +++ b/lib/theme/theme_helper.dart @@ -1,4 +1,3 @@ -import 'dart:ui'; import 'package:flutter/material.dart'; import '../../core/app_export.dart'; diff --git a/lib/widgets/base_button.dart b/lib/widgets/base_button.dart index 51da7f6c..0a572009 100644 --- a/lib/widgets/base_button.dart +++ b/lib/widgets/base_button.dart @@ -1,4 +1,3 @@ -import 'package:eatvio_app/core/app_export.dart'; import 'package:flutter/material.dart'; class BaseButton extends StatelessWidget { diff --git a/lib/widgets/custom_text_form_field.dart b/lib/widgets/custom_text_form_field.dart index fed08e3f..00bfdf3c 100644 --- a/lib/widgets/custom_text_form_field.dart +++ b/lib/widgets/custom_text_form_field.dart @@ -1,5 +1,6 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; class CustomTextFormField extends StatelessWidget { CustomTextFormField({ @@ -21,10 +22,12 @@ class CustomTextFormField extends StatelessWidget { this.suffix, this.suffixConstraints, this.contentPadding, + this.inputFormatters, this.borderDecoration, this.fillColor, this.filled = true, this.validator, + this.onSaved, }) : super( key: key, ); @@ -43,6 +46,8 @@ class CustomTextFormField extends StatelessWidget { final bool? obscureText; + final List? inputFormatters; + final TextInputAction? textInputAction; final TextInputType? textInputType; @@ -71,6 +76,8 @@ class CustomTextFormField extends StatelessWidget { final FormFieldValidator? validator; + final void Function(String?)? onSaved; + @override Widget build(BuildContext context) { return alignment != null @@ -94,6 +101,8 @@ class CustomTextFormField extends StatelessWidget { maxLines: maxLines ?? 1, decoration: decoration, validator: validator, + onSaved: onSaved, + inputFormatters: inputFormatters, ), ); InputDecoration get decoration => InputDecoration( diff --git a/lib/widgets/custom_outlined_button.dart b/lib/widgets/next_step_button.dart similarity index 96% rename from lib/widgets/custom_outlined_button.dart rename to lib/widgets/next_step_button.dart index d498755c..ce972835 100644 --- a/lib/widgets/custom_outlined_button.dart +++ b/lib/widgets/next_step_button.dart @@ -2,8 +2,8 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/base_button.dart'; import 'package:flutter/material.dart'; -class CustomOutlinedButton extends BaseButton { - CustomOutlinedButton({ +class NextStepButton extends BaseButton { + NextStepButton({ Key? key, this.decoration, this.leftIcon, diff --git a/pubspec.yaml b/pubspec.yaml index 3b441985..295bc454 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -9,10 +9,10 @@ dependencies: flutter_localizations: sdk: flutter flutter_bloc: ^8.0.0 - connectivity_plus: ^2.3.6 + connectivity_plus: ^5.0.2 shared_preferences: ^2.0.15 cached_network_image: ^3.2.1 - flutter_svg: ^1.1.6 + flutter_svg: ^2.0.9 equatable: ^2.0.0 dev_dependencies: flutter_test: