diff --git a/lib/data/apiClient/api_client.dart b/lib/data/apiClient/api_client.dart index cd1bf912..d629b311 100644 --- a/lib/data/apiClient/api_client.dart +++ b/lib/data/apiClient/api_client.dart @@ -1,3 +1,3 @@ -import 'package:eatvio_app/core/app_export.dart'; +//import 'package:eatvio_app/core/app_export.dart'; class ApiClient {} diff --git a/lib/data/models/userRegistrationModel/user_registration_model.dart b/lib/data/models/userRegistrationModel/user_registration_model.dart index 7f32d56c..0001f9ec 100644 --- a/lib/data/models/userRegistrationModel/user_registration_model.dart +++ b/lib/data/models/userRegistrationModel/user_registration_model.dart @@ -1,27 +1,25 @@ -import 'dart:convert'; -import 'package:http/http.dart' as http; - class UserRegistrationSheet { + String name; String firstName; String lastName; String email; String password; String passwordConfirmation; - bool termsAccepted; - DateTime birthdate; + String termsAccepted; + String 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 weight; + String height; + String chestCircumference; + String waistCircumference; + String hipCircumference; + String bloodPressureUp; + String bloodPressureDown; + String hasHypo = ''; + String hasHyper = ''; String aboutAllergy = ''; String aboutTakingPils = ''; String aboutSportHobbies = ''; @@ -30,6 +28,7 @@ class UserRegistrationSheet { String additionalInfo = ''; UserRegistrationSheet({ + required this.name, required this.firstName, required this.lastName, required this.email, @@ -60,13 +59,14 @@ class UserRegistrationSheet { Map toJson() { return { + 'name': name, 'first_name': firstName, 'last_name': lastName, 'email': email, 'password': password, 'password_confirmation': passwordConfirmation, 'terms': termsAccepted, - 'birthdate': birthdate.toIso8601String(), + 'birthdate': birthdate.toString(), 'gender': gender, 'country': country, 'city': city, @@ -88,15 +88,4 @@ class UserRegistrationSheet { '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/app_localization.dart b/lib/localization/app_localization.dart index d711fa4b..51b4b1aa 100644 --- a/lib/localization/app_localization.dart +++ b/lib/localization/app_localization.dart @@ -1,5 +1,5 @@ import 'ru/ru_translations.dart'; -import 'en_us/en_us_translations.dart'; +//import 'en_us/en_us_translations.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/cupertino.dart'; import '../core/app_export.dart'; @@ -9,10 +9,12 @@ class AppLocalization { Locale locale; - static final Map> _localizedValues = {'ru': ru}; - static final Map> __localizedValues = { - 'en': enUs + static final Map> _localizedValues = { + 'ru': ru, }; + /*static final Map> __localizedValues = { + 'en': enUs + };*/ static AppLocalization of() { return Localizations.of( diff --git a/lib/localization/ru/ru_translations.dart b/lib/localization/ru/ru_translations.dart index 40badc28..3d328fe0 100644 --- a/lib/localization/ru/ru_translations.dart +++ b/lib/localization/ru/ru_translations.dart @@ -1,20 +1,24 @@ final Map ru = { + //credentials Screen "user_registration": "Регистрация пользователя", "email": "Элетронная почта", + "username": "Имя пользователя", "password": "Пароль", "password_confirmation": "Подтвердите пароль", + + //name Screen "first_name": "Имя", "last_name": "Фамилия", + "what_is_your_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": "Обхват груди", + "hip_circumference": "Обхват бедер", "chest_circumference": "Обхват груди", "waist_circumference": "Обхват талии", "initial_measurements": "Первичные замеры", @@ -61,14 +65,38 @@ final Map ru = { // language_select Screen "lbl_english": "English", "finish": "Завершить", - "preferred_language": "Предпочетаемый язык общения?", + "preferred_language": "Предпочитаемый язык общения?", // Common String "continue": "Продолжить", "skip": "Пропустить", "fill_in_information": "Заполните информацию:", "enter_information": "Введите информацию...", -// Network Error String + // Network Error String "msg_network_err": "Сетевая ошибка!", "msg_something_went_wrong": "Что то пошло не так!", + + // Errors + // Credentials + "email_empty": "Необходимо ввести адрес электронной почты", + "email_invalid": "Некорректный адрес электронной почты", + "password_empty": "Пароль обязателен для заполнения", + "password_short": "В пароле должно быть минимум 6 символов", + "name_empty": "Имя пользователя обязательно для заполнения", + "name_short": "В имени пользователя должно быть минимум 6 символов", + "password_confirmation_mismatch": "Пароли не совпадают", + + // Name + "first_name_empty": "Имя обязательно для заполнения", + "first_name_short": "В имени должен быть минимум 1 символ", + "last_name_empty": "Фамилия обязательна для заполнения", + "last_name_short": "В фамилии должен быть минимум 6 символов", + + // Body Circumference + "circumference_empty": "Все замеры обязательны к заполнению", + "circumference_is_not_a_number": "Все замеры должны быть числами", + + // Body Circumference + "pressure_empty": "Все показатели давления обязательны к заполнению", + "pressure_is_not_a_number": "Все показатели давления должны быть числами", }; diff --git a/lib/presentation/additional_information_screen/additional_information_screen.dart b/lib/presentation/additional_information_screen/additional_information_screen.dart index 4ee525de..f534bf14 100644 --- a/lib/presentation/additional_information_screen/additional_information_screen.dart +++ b/lib/presentation/additional_information_screen/additional_information_screen.dart @@ -9,8 +9,9 @@ import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_m import 'package:eatvio_app/widgets/custom_text_form_field.dart'; import 'package:flutter/material.dart'; import 'dart:convert'; +import 'package:http/http.dart' as http; -class AdditionalInformationScreen extends StatefulWidget { +class AdditionalInformationScreen extends StatelessWidget { const AdditionalInformationScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { @@ -25,13 +26,6 @@ class AdditionalInformationScreen extends StatefulWidget { child: AdditionalInformationScreen()); } - @override - State createState() => - _AdditionalInformationScreenState(); -} - -class _AdditionalInformationScreenState - extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); @@ -70,17 +64,19 @@ class _AdditionalInformationScreenState margin: EdgeInsets.only( left: 16.h, right: 16.h, bottom: 50.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () { - var message; + onPressed: () async { UserRegistrationSheet sheet = state .additionalInformationModelObj! .userRegistrationSheet; sheet.additionalInfo = state.editTextController!.text; - message = sheet.toJson(); - print(message); + final response = await http.post( + Uri.parse('http://10.55.5.126:1092/api/register'), + headers: {'Content-Type': 'application/json'}, + body: json.encode(sheet), + ); + print(response.body); }); }), - SizedBox(height: 17.v), ])))); } @@ -140,7 +136,7 @@ class _AdditionalInformationScreenState context: context, builder: (_) => AlertDialog( title: const Text('Регистрация завершена!'), - content: const Text(text), + content: const Text('1'), 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 3e5243d2..ff001d96 100644 --- a/lib/presentation/additional_information_screen/models/additional_information_model.dart +++ b/lib/presentation/additional_information_screen/models/additional_information_model.dart @@ -11,8 +11,7 @@ class AdditionalInformationModel extends Equatable { AdditionalInformationModel copyWith() { return AdditionalInformationModel( - userRegistrationSheet: - userRegistrationSheet ?? this.userRegistrationSheet, + userRegistrationSheet: userRegistrationSheet, ); } diff --git a/lib/presentation/allergies_screen/allergies_screen.dart b/lib/presentation/allergies_screen/allergies_screen.dart index 0e4de30d..ee78724c 100644 --- a/lib/presentation/allergies_screen/allergies_screen.dart +++ b/lib/presentation/allergies_screen/allergies_screen.dart @@ -50,16 +50,16 @@ class _AllergiesScreenState extends State { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.62, + value: 0.76, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400)))), SizedBox(height: 22.v), Text("allergies_presence".tr, - style: CustomTextStyles.headlineSmallMulish), + style: theme.textTheme.headlineSmall), Spacer(flex: 36), _buildTextFormField(context), - Spacer(flex: 63), + Spacer(flex: 54), BlocBuilder( builder: (context, state) { return NextStepButton( @@ -79,8 +79,21 @@ class _AllergiesScreenState extends State { ); }); }), - SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) + BlocBuilder( + builder: (context, state) { + return GestureDetector( + onTap: () { + UserRegistrationSheet sheet = + state.allergiesModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.medicineIntakeScreen, + arguments: sheet, + ); + }, + child: Text("skip".tr, style: theme.textTheme.bodyLarge), + ); + }), ])))); } @@ -120,11 +133,4 @@ class _AllergiesScreenState extends State { onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); } - - /// Navigates to the medicineIntakeScreen when the action is triggered. - navigateToMedicine(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.medicineIntakeScreen, - ); - } } diff --git a/lib/presentation/allergies_screen/models/allergies_model.dart b/lib/presentation/allergies_screen/models/allergies_model.dart index 5553fa4e..ebd20063 100644 --- a/lib/presentation/allergies_screen/models/allergies_model.dart +++ b/lib/presentation/allergies_screen/models/allergies_model.dart @@ -11,8 +11,7 @@ class AllergiesModel extends Equatable { AllergiesModel copyWith() { return AllergiesModel( - userRegistrationSheet: - userRegistrationSheet ?? this.userRegistrationSheet, + userRegistrationSheet: userRegistrationSheet, ); } 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 c2c3632c..9ff02aeb 100644 --- a/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart +++ b/lib/presentation/blood_pressure_screen/bloc/blood_pressure_bloc.dart @@ -18,9 +18,9 @@ class BloodPressureBloc extends Bloc { Emitter emit, ) { if (event.value.id == 1) { - state.bloodPressureModelObj!.userRegistrationSheet.hasHyper = true; + state.bloodPressureModelObj!.userRegistrationSheet.hasHyper = '1'; } else { - state.bloodPressureModelObj!.userRegistrationSheet.hasHyper = false; + state.bloodPressureModelObj!.userRegistrationSheet.hasHyper = '0'; } emit(state.copyWith(selectedHyperValue: event.value)); } @@ -30,9 +30,9 @@ class BloodPressureBloc extends Bloc { Emitter emit, ) { if (event.value.id == 1) { - state.bloodPressureModelObj!.userRegistrationSheet.hasHypo = true; + state.bloodPressureModelObj!.userRegistrationSheet.hasHypo = '1'; } else { - state.bloodPressureModelObj!.userRegistrationSheet.hasHypo = false; + state.bloodPressureModelObj!.userRegistrationSheet.hasHypo = '0'; } emit(state.copyWith(selectedHypoValue: event.value)); } diff --git a/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart b/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart index f5c10e1d..47c83a35 100644 --- a/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart +++ b/lib/presentation/blood_pressure_screen/blood_pressure_screen.dart @@ -57,7 +57,7 @@ class _BloodPressureScreenState extends State { child: ClipRRect( borderRadius: BorderRadius.circular(8.h), child: LinearProgressIndicator( - value: 0.76, + value: 0.62, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation( appTheme.blueA400))))), @@ -175,21 +175,61 @@ class _BloodPressureScreenState extends State { 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, - ); + List errors = validateFields( + state.upPressureController!.text, + state.downPressureController!.text); + if (errors.isEmpty) { + UserRegistrationSheet sheet = state + .bloodPressureModelObj!.userRegistrationSheet; + sheet.bloodPressureUp = + state.upPressureController!.text; + sheet.bloodPressureDown = + state.downPressureController!.text; + Navigator.pushNamed( + context, + AppRoutes.favoriteSportsScreen, + arguments: sheet, + ); + } else { + String errorMessage = ''; + + for (var error in errors) { + errorMessage += error + '\n\n'; + } + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Ошибка'), + content: Text(errorMessage), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('OK'), + ), + ], + ), + ); + } }); }), - SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) + BlocBuilder( + builder: (context, state) { + return GestureDetector( + onTap: () { + UserRegistrationSheet sheet = + state.bloodPressureModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.allergiesScreen, + arguments: sheet, + ); + }, + child: Text("skip".tr, style: theme.textTheme.bodyLarge), + ); + }), ])))); } @@ -212,10 +252,21 @@ class _BloodPressureScreenState extends State { NavigatorService.goBack(); } - /// Navigates to the favoriteSportsScreen when the action is triggered. - navigateToSports(BuildContext context) { - NavigatorService.pushNamed( - AppRoutes.favoriteSportsScreen, - ); + List validateFields( + String bloodPressureUp, + String bloodPressureDown, + ) { + List errors = []; + + if (bloodPressureUp.isEmpty | bloodPressureDown.isEmpty) { + errors.add('pressure_empty'.tr); + } + + if (![bloodPressureUp, bloodPressureDown] + .every((pressure) => int.tryParse(pressure) != null)) { + errors.add('pressure_is_not_a_number'.tr); + } + + return errors; } } diff --git a/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart b/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart index c6e75bce..77f48b43 100644 --- a/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart +++ b/lib/presentation/body_circumferences_screen/body_circumferences_screen.dart @@ -106,23 +106,50 @@ class BodyCircumferencesScreen extends StatelessWidget { 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, - ); + List errors = validateFields( + state.chestCircumferenceController!.text, + state.waistCircumferenceController!.text, + state.hipCircumferenceController!.text); + if (errors.isEmpty) { + UserRegistrationSheet sheet = state + .bodyCircumferencesModelObj! + .userRegistrationSheet; + sheet.chestCircumference = + state.chestCircumferenceController!.text; + sheet.waistCircumference = + state.waistCircumferenceController!.text; + sheet.hipCircumference = + state.hipCircumferenceController!.text; + Navigator.pushNamed( + context, + AppRoutes.weightScreen, + arguments: sheet, + ); + } else { + String errorMessage = ''; + + for (var error in errors) { + errorMessage += error + '\n\n'; + } + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Ошибка'), + content: Text(errorMessage), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('OK'), + ), + ], + ), + ); + } }); }), - SizedBox(height: 17.v), ])))); } @@ -151,4 +178,25 @@ class BodyCircumferencesScreen extends StatelessWidget { AppRoutes.weightScreen, ); } + + List validateFields( + String chestCircumference, + String waistCircumference, + String hipCircumference, + ) { + List errors = []; + + if (chestCircumference.isEmpty | + waistCircumference.isEmpty | + hipCircumference.isEmpty) { + errors.add('circumference_empty'.tr); + } + + if (![chestCircumference, waistCircumference, hipCircumference] + .every((circumference) => int.tryParse(circumference) != null)) { + errors.add('circumference_is_not_a_number'.tr); + } + + return errors; + } } 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 bc684a03..2af76f9d 100644 --- a/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart +++ b/lib/presentation/body_circumferences_screen/models/body_circumferences_model.dart @@ -11,8 +11,7 @@ class BodyCircumferencesModel extends Equatable { BodyCircumferencesModel copyWith() { return BodyCircumferencesModel( - userRegistrationSheet: - userRegistrationSheet ?? this.userRegistrationSheet, + userRegistrationSheet: userRegistrationSheet, ); } 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 2f2e8655..1e14a9c1 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 @@ -121,7 +121,6 @@ class CityOfLivingScreen extends StatelessWidget { ); }); }), - SizedBox(height: 17.v), ])))); } 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 1b32e6e0..048621df 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 @@ -23,8 +23,7 @@ class CityOfLivingModel extends Equatable { List? dropdownItemList1, }) { return CityOfLivingModel( - userRegistrationSheet: - userRegistrationSheet ?? this.userRegistrationSheet, + userRegistrationSheet: userRegistrationSheet, dropdownItemList: dropdownItemList ?? this.dropdownItemList, dropdownItemList1: dropdownItemList1 ?? this.dropdownItemList1, ); diff --git a/lib/presentation/credentials_screen/bloc/credentials_bloc.dart b/lib/presentation/credentials_screen/bloc/credentials_bloc.dart index 6fab34bb..425186a9 100644 --- a/lib/presentation/credentials_screen/bloc/credentials_bloc.dart +++ b/lib/presentation/credentials_screen/bloc/credentials_bloc.dart @@ -16,7 +16,8 @@ class CredentialsBloc extends Bloc { Emitter emit, ) async { emit(state.copyWith( - valueController: TextEditingController(), + emailController: TextEditingController(), + nameController: TextEditingController(), passwordController: TextEditingController(), passwordConfirmationController: TextEditingController())); } diff --git a/lib/presentation/credentials_screen/bloc/credentials_state.dart b/lib/presentation/credentials_screen/bloc/credentials_state.dart index 2d50f0f9..e127da6e 100644 --- a/lib/presentation/credentials_screen/bloc/credentials_state.dart +++ b/lib/presentation/credentials_screen/bloc/credentials_state.dart @@ -5,13 +5,16 @@ part of 'credentials_bloc.dart'; /// Represents the state of Credentials in the application. class CredentialsState extends Equatable { CredentialsState({ - this.valueController, + this.emailController, + this.nameController, this.passwordController, this.passwordConfirmationController, this.credentialsModelObj, }); - TextEditingController? valueController; + TextEditingController? emailController; + + TextEditingController? nameController; TextEditingController? passwordController; @@ -21,19 +24,22 @@ class CredentialsState extends Equatable { @override List get props => [ - valueController, + emailController, + nameController, passwordController, passwordConfirmationController, credentialsModelObj, ]; CredentialsState copyWith({ - TextEditingController? valueController, + TextEditingController? nameController, + TextEditingController? emailController, TextEditingController? passwordController, TextEditingController? passwordConfirmationController, CredentialsModel? credentialsModelObj, }) { return CredentialsState( - valueController: valueController ?? this.valueController, + emailController: emailController ?? this.emailController, + nameController: nameController ?? this.nameController, passwordController: passwordController ?? this.passwordController, passwordConfirmationController: passwordConfirmationController ?? this.passwordConfirmationController, diff --git a/lib/presentation/credentials_screen/credentials_screen.dart b/lib/presentation/credentials_screen/credentials_screen.dart index 978aea11..6ab0eb61 100644 --- a/lib/presentation/credentials_screen/credentials_screen.dart +++ b/lib/presentation/credentials_screen/credentials_screen.dart @@ -1,9 +1,9 @@ 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:validators/validators.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'; @@ -58,10 +58,21 @@ class CredentialsScreen extends StatelessWidget { SizedBox(height: 3.v), BlocSelector( - selector: (state) => state.valueController, - builder: (context, valueController) { + selector: (state) => state.emailController, + builder: (context, emailController) { return CustomTextFormField( - controller: valueController, + controller: emailController, + textInputAction: TextInputAction.done); + }), + SizedBox(height: 22.v), + Text("username".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 3.v), + BlocSelector( + selector: (state) => state.nameController, + builder: (context, nameController) { + return CustomTextFormField( + controller: nameController, textInputAction: TextInputAction.done); }), SizedBox(height: 19.v), @@ -98,20 +109,49 @@ class CredentialsScreen extends StatelessWidget { 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, - ); + List errors = validateFields( + state.emailController!.text, + state.nameController!.text, + state.passwordController!.text, + state.passwordConfirmationController!.text); + if (errors.isEmpty) { + UserRegistrationSheet sheet = state + .credentialsModelObj!.userRegistrationSheet; + sheet.email = state.emailController!.text; + sheet.name = state.nameController!.text; + sheet.password = state.passwordController!.text; + sheet.passwordConfirmation = + state.passwordConfirmationController!.text; + Navigator.pushNamed( + context, + AppRoutes.nameScreen, + arguments: sheet, + ); + } else { + String errorMessage = ''; + + for (var error in errors) { + errorMessage += error + '\n\n'; + } + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Ошибка'), + content: Text(errorMessage), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('OK'), + ), + ], + ), + ); + } }); }), - SizedBox(height: 17.v), ])))); } @@ -119,18 +159,42 @@ class CredentialsScreen extends StatelessWidget { 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(); + List validateFields( + String email, String name, String password, String passwordConfirmation) { + List errors = []; + + if (!isEmail(email)) { + errors.add('email_invalid'.tr); + } + + if (email.isEmpty) { + errors.add('email_empty'.tr); + } + + if (name.length < 6) { + errors.add('name_short'.tr); + } + + if (name.isEmpty) { + errors.add('name_empty'.tr); + } + + if (password.isEmpty) { + errors.add('name_empty'.tr); + } + + if (password.length < 6) { + errors.add('password_short'.tr); + } + + if (password != passwordConfirmation) { + errors.add('password_confirmation_mismatch'.tr); + } + + return errors; } } 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 5c3dcb6e..49ef2848 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 @@ -72,7 +72,7 @@ class _DateOfBirthScreenState extends State { onPressed: () { UserRegistrationSheet sheet = state .dateOfBirthModelObj!.userRegistrationSheet; - sheet.birthdate = selectedDate; + sheet.birthdate = selectedDate.toString(); Navigator.pushNamed( context, AppRoutes.cityOfLivingScreen, @@ -80,7 +80,6 @@ class _DateOfBirthScreenState extends State { ); }); }), - SizedBox(height: 17.v), ])))); }); } 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 98700d4c..121b10d6 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 @@ -12,8 +12,7 @@ class DateOfBirthModel extends Equatable { DateOfBirthModel copyWith() { return DateOfBirthModel( - userRegistrationSheet: - userRegistrationSheet ?? this.userRegistrationSheet, + userRegistrationSheet: userRegistrationSheet, ); } diff --git a/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart b/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart index 625d221d..7db73fbd 100644 --- a/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart +++ b/lib/presentation/favorite_foods_screen/favorite_foods_screen.dart @@ -74,7 +74,7 @@ class _FavoriteFoodsScreenState extends State { return NextStepButton( text: "continue".tr.toUpperCase(), margin: EdgeInsets.only( - left: 16.h, right: 16.h, bottom: 50.v), + left: 16.h, right: 16.h, bottom: 40.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, onPressed: () { UserRegistrationSheet sheet = state @@ -90,8 +90,21 @@ class _FavoriteFoodsScreenState extends State { ); }); }), - SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) + BlocBuilder( + builder: (context, state) { + return GestureDetector( + onTap: () { + UserRegistrationSheet sheet = + state.favoriteFoodsModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.additionalInformationScreen, + arguments: sheet, + ); + }, + child: Text("skip".tr, style: theme.textTheme.bodyLarge), + ); + }), ])))); } 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 2084cade..3aeeee20 100644 --- a/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart +++ b/lib/presentation/favorite_foods_screen/models/favorite_foods_model.dart @@ -11,8 +11,7 @@ class FavoriteFoodsModel extends Equatable { FavoriteFoodsModel copyWith() { return FavoriteFoodsModel( - userRegistrationSheet: - userRegistrationSheet ?? this.userRegistrationSheet, + userRegistrationSheet: userRegistrationSheet, ); } diff --git a/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart b/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart index 2d531bea..8374c74b 100644 --- a/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart +++ b/lib/presentation/favorite_sports_screen/favorite_sports_screen.dart @@ -84,9 +84,22 @@ class _FavoriteSportsScreenState extends State { ); }); }), - SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge), - SizedBox(height: 4.v) + BlocBuilder( + builder: (context, state) { + return GestureDetector( + onTap: () { + UserRegistrationSheet sheet = state + .favoriteSportsModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.favoriteFoodsScreen, + arguments: sheet, + ); + }, + child: + Text("skip".tr, style: theme.textTheme.bodyLarge), + ); + }), ])))); } diff --git a/lib/presentation/gender_screen/gender_screen.dart b/lib/presentation/gender_screen/gender_screen.dart index be2c3f42..34dcc859 100644 --- a/lib/presentation/gender_screen/gender_screen.dart +++ b/lib/presentation/gender_screen/gender_screen.dart @@ -106,7 +106,6 @@ class _GenderScreenState extends State { ); }); }), - SizedBox(height: 17.v), ])))); }); } diff --git a/lib/presentation/height_screen/bloc/height_bloc.dart b/lib/presentation/height_screen/bloc/height_bloc.dart index 629778fe..7136a21a 100644 --- a/lib/presentation/height_screen/bloc/height_bloc.dart +++ b/lib/presentation/height_screen/bloc/height_bloc.dart @@ -26,8 +26,7 @@ class HeightBloc extends Bloc { Emitter emit, ) { emit(state.copyWith(selectedDropDownValue: event.value)); - state.heightModelObj?.userRegistrationSheet.height = - int.tryParse(event.value.title)!; + state.heightModelObj?.userRegistrationSheet.height = event.value.title; } List fillDropdownItemList() { diff --git a/lib/presentation/height_screen/height_screen.dart b/lib/presentation/height_screen/height_screen.dart index 17a5a9ab..574bf488 100644 --- a/lib/presentation/height_screen/height_screen.dart +++ b/lib/presentation/height_screen/height_screen.dart @@ -98,12 +98,11 @@ class _HeightScreenState extends State { state.heightModelObj!.userRegistrationSheet; Navigator.pushNamed( context, - AppRoutes.allergiesScreen, + AppRoutes.bloodPressureScreen, arguments: sheet, ); }); }), - SizedBox(height: 17.v), ])))); } 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 1df7f8aa..465a8ac8 100644 --- a/lib/presentation/language_select_screen/models/language_select_model.dart +++ b/lib/presentation/language_select_screen/models/language_select_model.dart @@ -9,26 +9,27 @@ import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model class LanguageSelectModel extends Equatable { LanguageSelectModel({this.dropdownItemList = const []}); UserRegistrationSheet userRegistrationSheet = UserRegistrationSheet( + name: '', firstName: '', lastName: '', email: '', password: '', passwordConfirmation: '', - termsAccepted: false, - birthdate: DateTime.now(), + termsAccepted: 'accepted', + birthdate: DateTime.now().toString(), gender: '', country: '', city: '', lang: '', - weight: 0, - height: 0, - chestCircumference: 0, - waistCircumference: 0, - hipCircumference: 0, - bloodPressureUp: 0, - bloodPressureDown: 0, - hasHypo: false, - hasHyper: false, + weight: '', + height: '', + chestCircumference: '', + waistCircumference: '', + hipCircumference: '', + bloodPressureUp: '', + bloodPressureDown: '', + hasHypo: '', + hasHyper: '', aboutAllergy: '', aboutTakingPils: '', aboutSportHobbies: '', diff --git a/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart b/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart index 5b8fdb95..fc0766f6 100644 --- a/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart +++ b/lib/presentation/medicine_intake_screen/medicine_intake_screen.dart @@ -63,7 +63,7 @@ class _MedicineIntakeScreenState extends State { maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, - style: CustomTextStyles.headlineSmallMulish)), + style: theme.textTheme.headlineSmall)), SizedBox(height: 86.v), _buildTextFormField(context), Spacer(), @@ -86,8 +86,21 @@ class _MedicineIntakeScreenState extends State { ); }); }), - SizedBox(height: 17.v), - Text("skip".tr, style: theme.textTheme.bodyLarge) + BlocBuilder( + builder: (context, state) { + return GestureDetector( + onTap: () { + UserRegistrationSheet sheet = + state.medicineIntakeModelObj!.userRegistrationSheet; + Navigator.pushNamed( + context, + AppRoutes.bloodPressureScreen, + arguments: sheet, + ); + }, + child: Text("skip".tr, style: theme.textTheme.bodyLarge), + ); + }), ])))); } diff --git a/lib/presentation/name_screen/name_screen.dart b/lib/presentation/name_screen/name_screen.dart index 2e7bc8ab..cc234a77 100644 --- a/lib/presentation/name_screen/name_screen.dart +++ b/lib/presentation/name_screen/name_screen.dart @@ -83,18 +83,44 @@ class NameScreen extends StatelessWidget { 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, - ); + List errors = validateFields( + state.firstNameController!.text, + state.lastNameController!.text); + if (errors.isEmpty) { + UserRegistrationSheet sheet = + state.nameModelObj!.userRegistrationSheet; + sheet.firstName = state.firstNameController!.text; + sheet.lastName = state.lastNameController!.text; + Navigator.pushNamed( + context, + AppRoutes.genderScreen, + arguments: sheet, + ); + } else { + String errorMessage = ''; + + for (var error in errors) { + errorMessage += error + '\n\n'; + } + + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Ошибка'), + content: Text(errorMessage), + actions: [ + TextButton( + onPressed: () { + Navigator.pop(context); + }, + child: Text('OK'), + ), + ], + ), + ); + } }); }), - SizedBox(height: 17.v), ])))); } @@ -116,4 +142,29 @@ class NameScreen extends StatelessWidget { onTapArrowLeft(BuildContext context) { NavigatorService.goBack(); } + + List validateFields( + String firstName, + String lastName, + ) { + List errors = []; + + if (firstName.isEmpty) { + errors.add('first_name_empty'.tr); + } + + if (firstName.length < 1) { + errors.add('first_name_short'.tr); + } + + if (lastName.isEmpty) { + errors.add('last_name_empty'.tr); + } + + if (lastName.length < 1) { + errors.add('last_name_short'.tr); + } + + return errors; + } } diff --git a/lib/presentation/weight_screen/bloc/weight_bloc.dart b/lib/presentation/weight_screen/bloc/weight_bloc.dart index 94091376..507220a4 100644 --- a/lib/presentation/weight_screen/bloc/weight_bloc.dart +++ b/lib/presentation/weight_screen/bloc/weight_bloc.dart @@ -26,8 +26,7 @@ class WeightBloc extends Bloc { Emitter emit, ) { emit(state.copyWith(selectedDropDownValue: event.value)); - state.weightModelObj?.userRegistrationSheet.weight = - int.tryParse(event.value.title)!; + state.weightModelObj?.userRegistrationSheet.weight = event.value.title; } List fillDropdownItemList() { diff --git a/lib/presentation/weight_screen/weight_screen.dart b/lib/presentation/weight_screen/weight_screen.dart index 8e606e1c..ab936350 100644 --- a/lib/presentation/weight_screen/weight_screen.dart +++ b/lib/presentation/weight_screen/weight_screen.dart @@ -103,7 +103,6 @@ class _WeightScreenState extends State { ); }); }), - SizedBox(height: 17.v), ])))); } diff --git a/pubspec.yaml b/pubspec.yaml index 295bc454..79669938 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,6 +14,8 @@ dependencies: cached_network_image: ^3.2.1 flutter_svg: ^2.0.9 equatable: ^2.0.0 + validators: ^3.0.0 + dev_dependencies: flutter_test: sdk: flutter