Added 'validation' library, implemented client-sade validation for the first screen. Added error display as a dialog

This commit is contained in:
2023-12-27 16:10:36 +03:00
parent 17dc6aba51
commit fbdbf2545f
5 changed files with 105 additions and 23 deletions

View File

@@ -1,18 +1,21 @@
final Map<String, String> 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<String, String> 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
};

View File

@@ -16,7 +16,7 @@ class CredentialsBloc extends Bloc<CredentialsEvent, CredentialsState> {
Emitter<CredentialsState> emit,
) async {
emit(state.copyWith(
valueController: TextEditingController(),
emailController: TextEditingController(),
nameController: TextEditingController(),
passwordController: TextEditingController(),
passwordConfirmationController: TextEditingController()));

View File

@@ -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<Object?> 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:

View File

@@ -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<CredentialsBloc, CredentialsState,
TextEditingController?>(
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<String> 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<String> validateFields(
String email, String name, String password, String passwordConfirmation) {
List<String> errors = [];
if (!isEmail(email)) {
errors.add('email_invalid'.tr);
}
if (email.isEmpty) {
errors.add('email_empty'.tr);
}
if (name.length < 6) {
errors.add('name_short'.tr);
}
if (name.isEmpty) {
errors.add('name_empty'.tr);
}
if (password.isEmpty) {
errors.add('name_empty'.tr);
}
if (password.length < 6) {
errors.add('password_short'.tr);
}
if (password != passwordConfirmation) {
errors.add('password_confirmation_mismatch'.tr);
}
return errors;
}
}

View File

@@ -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