From fbdbf2545fa1a721c8cffc803d78d5355974f1a4 Mon Sep 17 00:00:00 2001 From: maxxkim Date: Wed, 27 Dec 2023 16:10:36 +0300 Subject: [PATCH] Added 'validation' library, implemented client-sade validation for the first screen. Added error display as a dialog --- lib/localization/ru/ru_translations.dart | 19 +++- .../bloc/credentials_bloc.dart | 2 +- .../bloc/credentials_state.dart | 10 +- .../credentials_screen.dart | 95 ++++++++++++++++--- pubspec.yaml | 2 + 5 files changed, 105 insertions(+), 23 deletions(-) diff --git a/lib/localization/ru/ru_translations.dart b/lib/localization/ru/ru_translations.dart index ac7b6965..dc434c77 100644 --- a/lib/localization/ru/ru_translations.dart +++ b/lib/localization/ru/ru_translations.dart @@ -1,18 +1,21 @@ 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": "Обхват груди", @@ -69,7 +72,19 @@ final Map ru = { "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 }; diff --git a/lib/presentation/credentials_screen/bloc/credentials_bloc.dart b/lib/presentation/credentials_screen/bloc/credentials_bloc.dart index 433d3ff2..425186a9 100644 --- a/lib/presentation/credentials_screen/bloc/credentials_bloc.dart +++ b/lib/presentation/credentials_screen/bloc/credentials_bloc.dart @@ -16,7 +16,7 @@ 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 a909d064..e127da6e 100644 --- a/lib/presentation/credentials_screen/bloc/credentials_state.dart +++ b/lib/presentation/credentials_screen/bloc/credentials_state.dart @@ -5,14 +5,14 @@ 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; @@ -24,7 +24,7 @@ class CredentialsState extends Equatable { @override List get props => [ - valueController, + emailController, nameController, passwordController, passwordConfirmationController, @@ -32,13 +32,13 @@ class CredentialsState extends Equatable { ]; CredentialsState copyWith({ TextEditingController? nameController, - TextEditingController? valueController, + 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: diff --git a/lib/presentation/credentials_screen/credentials_screen.dart b/lib/presentation/credentials_screen/credentials_screen.dart index b329f509..6ab0eb61 100644 --- a/lib/presentation/credentials_screen/credentials_screen.dart +++ b/lib/presentation/credentials_screen/credentials_screen.dart @@ -3,6 +3,7 @@ import 'models/credentials_model.dart'; import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; +import 'package:validators/validators.dart'; import 'package:eatvio_app/widgets/next_step_button.dart'; import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:eatvio_app/widgets/custom_text_form_field.dart'; @@ -57,10 +58,10 @@ 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), @@ -108,18 +109,47 @@ 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.name = state.nameController!.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'), + ), + ], + ), + ); + } }); }), ])))); @@ -132,4 +162,39 @@ class CredentialsScreen extends StatelessWidget { centerTitle: true, title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); } + + 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/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