Merge pull request 'registration_validation' (#2) from registration_validation into main

Reviewed-on: maxxkim/eatvio_app#2
This commit is contained in:
2023-12-27 14:15:29 +00:00
31 changed files with 454 additions and 183 deletions

View File

@@ -1,3 +1,3 @@
import 'package:eatvio_app/core/app_export.dart';
//import 'package:eatvio_app/core/app_export.dart';
class ApiClient {}

View File

@@ -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<String, dynamic> 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<void> 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');
}
}
}

View File

@@ -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<String, Map<String, String>> _localizedValues = {'ru': ru};
static final Map<String, Map<String, String>> __localizedValues = {
'en': enUs
static final Map<String, Map<String, String>> _localizedValues = {
'ru': ru,
};
/*static final Map<String, Map<String, String>> __localizedValues = {
'en': enUs
};*/
static AppLocalization of() {
return Localizations.of<AppLocalization>(

View File

@@ -1,20 +1,24 @@
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": "Обхват груди",
"hip_circumference": "Обхват бедер", "chest_circumference": "Обхват груди",
"waist_circumference": "Обхват талии",
"initial_measurements": "Первичные замеры",
@@ -61,14 +65,38 @@ final Map<String, String> 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": "Все показатели давления должны быть числами",
};

View File

@@ -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<AdditionalInformationScreen> createState() =>
_AdditionalInformationScreenState();
}
class _AdditionalInformationScreenState
extends State<AdditionalInformationScreen> {
@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: () {

View File

@@ -11,8 +11,7 @@ class AdditionalInformationModel extends Equatable {
AdditionalInformationModel copyWith() {
return AdditionalInformationModel(
userRegistrationSheet:
userRegistrationSheet ?? this.userRegistrationSheet,
userRegistrationSheet: userRegistrationSheet,
);
}

View File

@@ -50,16 +50,16 @@ class _AllergiesScreenState extends State<AllergiesScreen> {
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: 0.62,
value: 0.76,
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(
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<AllergiesBloc, AllergiesState>(
builder: (context, state) {
return NextStepButton(
@@ -79,8 +79,21 @@ class _AllergiesScreenState extends State<AllergiesScreen> {
);
});
}),
SizedBox(height: 17.v),
Text("skip".tr, style: theme.textTheme.bodyLarge)
BlocBuilder<AllergiesBloc, AllergiesState>(
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<AllergiesScreen> {
onTapArrowLeft(BuildContext context) {
NavigatorService.goBack();
}
/// Navigates to the medicineIntakeScreen when the action is triggered.
navigateToMedicine(BuildContext context) {
NavigatorService.pushNamed(
AppRoutes.medicineIntakeScreen,
);
}
}

View File

@@ -11,8 +11,7 @@ class AllergiesModel extends Equatable {
AllergiesModel copyWith() {
return AllergiesModel(
userRegistrationSheet:
userRegistrationSheet ?? this.userRegistrationSheet,
userRegistrationSheet: userRegistrationSheet,
);
}

View File

@@ -18,9 +18,9 @@ class BloodPressureBloc extends Bloc<BloodPressureEvent, BloodPressureState> {
Emitter<BloodPressureState> 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<BloodPressureEvent, BloodPressureState> {
Emitter<BloodPressureState> 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));
}

View File

@@ -57,7 +57,7 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
child: ClipRRect(
borderRadius: BorderRadius.circular(8.h),
child: LinearProgressIndicator(
value: 0.76,
value: 0.62,
backgroundColor: theme.colorScheme.onPrimary,
valueColor: AlwaysStoppedAnimation<Color>(
appTheme.blueA400))))),
@@ -175,21 +175,61 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
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<String> 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<BloodPressureBloc, BloodPressureState>(
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<BloodPressureScreen> {
NavigatorService.goBack();
}
/// Navigates to the favoriteSportsScreen when the action is triggered.
navigateToSports(BuildContext context) {
NavigatorService.pushNamed(
AppRoutes.favoriteSportsScreen,
);
List<String> validateFields(
String bloodPressureUp,
String bloodPressureDown,
) {
List<String> 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;
}
}

View File

@@ -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<String> 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<String> validateFields(
String chestCircumference,
String waistCircumference,
String hipCircumference,
) {
List<String> 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;
}
}

View File

@@ -11,8 +11,7 @@ class BodyCircumferencesModel extends Equatable {
BodyCircumferencesModel copyWith() {
return BodyCircumferencesModel(
userRegistrationSheet:
userRegistrationSheet ?? this.userRegistrationSheet,
userRegistrationSheet: userRegistrationSheet,
);
}

View File

@@ -121,7 +121,6 @@ class CityOfLivingScreen extends StatelessWidget {
);
});
}),
SizedBox(height: 17.v),
]))));
}

View File

@@ -23,8 +23,7 @@ class CityOfLivingModel extends Equatable {
List<SelectionPopupModel>? dropdownItemList1,
}) {
return CityOfLivingModel(
userRegistrationSheet:
userRegistrationSheet ?? this.userRegistrationSheet,
userRegistrationSheet: userRegistrationSheet,
dropdownItemList: dropdownItemList ?? this.dropdownItemList,
dropdownItemList1: dropdownItemList1 ?? this.dropdownItemList1,
);

View File

@@ -16,7 +16,8 @@ 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,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<Object?> 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,

View File

@@ -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<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),
Text("username".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 3.v),
BlocSelector<CredentialsBloc, CredentialsState,
TextEditingController?>(
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<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'),
),
],
),
);
}
});
}),
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<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

@@ -72,7 +72,7 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
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<DateOfBirthScreen> {
);
});
}),
SizedBox(height: 17.v),
]))));
});
}

View File

@@ -12,8 +12,7 @@ class DateOfBirthModel extends Equatable {
DateOfBirthModel copyWith() {
return DateOfBirthModel(
userRegistrationSheet:
userRegistrationSheet ?? this.userRegistrationSheet,
userRegistrationSheet: userRegistrationSheet,
);
}

View File

@@ -74,7 +74,7 @@ class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
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<FavoriteFoodsScreen> {
);
});
}),
SizedBox(height: 17.v),
Text("skip".tr, style: theme.textTheme.bodyLarge)
BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(
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),
);
}),
]))));
}

View File

@@ -11,8 +11,7 @@ class FavoriteFoodsModel extends Equatable {
FavoriteFoodsModel copyWith() {
return FavoriteFoodsModel(
userRegistrationSheet:
userRegistrationSheet ?? this.userRegistrationSheet,
userRegistrationSheet: userRegistrationSheet,
);
}

View File

@@ -84,9 +84,22 @@ class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
);
});
}),
SizedBox(height: 17.v),
Text("skip".tr, style: theme.textTheme.bodyLarge),
SizedBox(height: 4.v)
BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(
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),
);
}),
]))));
}

View File

@@ -106,7 +106,6 @@ class _GenderScreenState extends State<GenderScreen> {
);
});
}),
SizedBox(height: 17.v),
]))));
});
}

View File

@@ -26,8 +26,7 @@ class HeightBloc extends Bloc<HeightEvent, HeightState> {
Emitter<HeightState> emit,
) {
emit(state.copyWith(selectedDropDownValue: event.value));
state.heightModelObj?.userRegistrationSheet.height =
int.tryParse(event.value.title)!;
state.heightModelObj?.userRegistrationSheet.height = event.value.title;
}
List<SelectionPopupModel> fillDropdownItemList() {

View File

@@ -98,12 +98,11 @@ class _HeightScreenState extends State<HeightScreen> {
state.heightModelObj!.userRegistrationSheet;
Navigator.pushNamed(
context,
AppRoutes.allergiesScreen,
AppRoutes.bloodPressureScreen,
arguments: sheet,
);
});
}),
SizedBox(height: 17.v),
]))));
}

View File

@@ -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: '',

View File

@@ -63,7 +63,7 @@ class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
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<MedicineIntakeScreen> {
);
});
}),
SizedBox(height: 17.v),
Text("skip".tr, style: theme.textTheme.bodyLarge)
BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(
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),
);
}),
]))));
}

View File

@@ -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<String> 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<String> validateFields(
String firstName,
String lastName,
) {
List<String> 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;
}
}

View File

@@ -26,8 +26,7 @@ class WeightBloc extends Bloc<WeightEvent, WeightState> {
Emitter<WeightState> emit,
) {
emit(state.copyWith(selectedDropDownValue: event.value));
state.weightModelObj?.userRegistrationSheet.weight =
int.tryParse(event.value.title)!;
state.weightModelObj?.userRegistrationSheet.weight = event.value.title;
}
List<SelectionPopupModel> fillDropdownItemList() {

View File

@@ -103,7 +103,6 @@ class _WeightScreenState extends State<WeightScreen> {
);
});
}),
SizedBox(height: 17.v),
]))));
}

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