forked from eatvio/eatvio_app
Merge pull request 'registration_logic' (#1) from registration_logic into main
Reviewed-on: maxxkim/eatvio_app#1
This commit is contained in:
BIN
assets/images/img_female.png
Normal file
BIN
assets/images/img_female.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
assets/images/img_male.png
Normal file
BIN
assets/images/img_male.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
1
devtools_options.yaml
Normal file
1
devtools_options.yaml
Normal file
@@ -0,0 +1 @@
|
||||
extensions:
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<String, dynamic> 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<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');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
final Map<String, String> 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<String, String> 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<String, String> ru = {
|
||||
|
||||
// language_select Screen
|
||||
"lbl_english": "English",
|
||||
"finish": "Завершить",
|
||||
"preferred_language": "Предпочетаемый язык общения?",
|
||||
|
||||
// Common String
|
||||
|
||||
@@ -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<AdditionalInformationBloc>(
|
||||
create: (context) => AdditionalInformationBloc(
|
||||
AdditionalInformationState(
|
||||
additionalInformationModelObj: AdditionalInformationModel()))
|
||||
additionalInformationModelObj:
|
||||
AdditionalInformationModel(userRegistrationSheet: sheet)))
|
||||
..add(AdditionalInformationInitialEvent()),
|
||||
child: AdditionalInformationScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<AdditionalInformationScreen> createState() =>
|
||||
_AdditionalInformationScreenState();
|
||||
}
|
||||
|
||||
class _AdditionalInformationScreenState
|
||||
extends State<AdditionalInformationScreen> {
|
||||
@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<Color>(
|
||||
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<AdditionalInformationBloc,
|
||||
AdditionalInformationState>(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: () {
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
List<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -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<AllergiesBloc>(
|
||||
create: (context) =>
|
||||
AllergiesBloc(AllergiesState(allergiesModelObj: AllergiesModel()))
|
||||
..add(AllergiesInitialEvent()),
|
||||
create: (context) => AllergiesBloc(AllergiesState(
|
||||
allergiesModelObj: AllergiesModel(userRegistrationSheet: sheet)))
|
||||
..add(AllergiesInitialEvent()),
|
||||
child: AllergiesScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<AllergiesScreen> createState() => _AllergiesScreenState();
|
||||
}
|
||||
|
||||
class _AllergiesScreenState extends State<AllergiesScreen> {
|
||||
@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<Color>(
|
||||
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<AllergiesBloc, AllergiesState>(
|
||||
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)
|
||||
]))));
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
List<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -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<AppNavigationScreen> createState() => _AppNavigationScreenState();
|
||||
}
|
||||
|
||||
class _AppNavigationScreenState extends State<AppNavigationScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -9,20 +9,41 @@ part 'blood_pressure_state.dart';
|
||||
class BloodPressureBloc extends Bloc<BloodPressureEvent, BloodPressureState> {
|
||||
BloodPressureBloc(BloodPressureState initialState) : super(initialState) {
|
||||
on<BloodPressureInitialEvent>(_onInitialize);
|
||||
on<ChangeDropDownEvent>(_changeDropDown);
|
||||
on<ChangeHypoDownEvent>(_changeHypoDropDown);
|
||||
on<ChangeHyperDropDownEvent>(_changeHyperDropDown);
|
||||
}
|
||||
|
||||
_changeDropDown(
|
||||
ChangeDropDownEvent event,
|
||||
_changeHyperDropDown(
|
||||
ChangeHyperDropDownEvent event,
|
||||
Emitter<BloodPressureState> 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<BloodPressureState> emit,
|
||||
) {
|
||||
if (event.value.id == 1) {
|
||||
state.bloodPressureModelObj!.userRegistrationSheet.hasHypo = true;
|
||||
} else {
|
||||
state.bloodPressureModelObj!.userRegistrationSheet.hasHypo = false;
|
||||
}
|
||||
emit(state.copyWith(selectedHypoValue: event.value));
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> 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<BloodPressureEvent, BloodPressureState> {
|
||||
Emitter<BloodPressureState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
valueController: TextEditingController(),
|
||||
valueController1: TextEditingController()));
|
||||
upPressureController: TextEditingController(),
|
||||
downPressureController: TextEditingController()));
|
||||
emit(state.copyWith(
|
||||
bloodPressureModelObj: state.bloodPressureModelObj
|
||||
?.copyWith(dropdownItemList: fillDropdownItemList())));
|
||||
|
||||
@@ -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<Object?> get props => [
|
||||
value,
|
||||
];
|
||||
}
|
||||
|
||||
class ChangeHypoDownEvent extends BloodPressureEvent {
|
||||
ChangeHypoDownEvent({required this.value});
|
||||
|
||||
SelectionPopupModel value;
|
||||
|
||||
|
||||
@@ -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<Object?> 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,
|
||||
);
|
||||
|
||||
@@ -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<BloodPressureBloc>(
|
||||
create: (context) => BloodPressureBloc(
|
||||
BloodPressureState(bloodPressureModelObj: BloodPressureModel()))
|
||||
create: (context) => BloodPressureBloc(BloodPressureState(
|
||||
bloodPressureModelObj:
|
||||
BloodPressureModel(userRegistrationSheet: sheet)))
|
||||
..add(BloodPressureInitialEvent()),
|
||||
child: BloodPressureScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<BloodPressureScreen> createState() => _BloodPressureScreenState();
|
||||
}
|
||||
|
||||
class _BloodPressureScreenState extends State<BloodPressureScreen> {
|
||||
@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<Color>(
|
||||
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<BloodPressureBloc, BloodPressureState,
|
||||
TextEditingController?>(
|
||||
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<BloodPressureBloc, BloodPressureState,
|
||||
TextEditingController?>(
|
||||
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<BloodPressureBloc>()
|
||||
.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<BloodPressureBloc>()
|
||||
.add(ChangeDropDownEvent(value: value));
|
||||
context.read<BloodPressureBloc>().add(
|
||||
ChangeHyperDropDownEvent(value: value));
|
||||
});
|
||||
})),
|
||||
Spacer(),
|
||||
CustomOutlinedButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.symmetric(horizontal: 4.h),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: () {
|
||||
navigateToSports(context);
|
||||
}),
|
||||
BlocBuilder<BloodPressureBloc, BloodPressureState>(
|
||||
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<BloodPressureBloc, BloodPressureState,
|
||||
TextEditingController?>(
|
||||
selector: (state) => state.valueController,
|
||||
builder: (context, valueController) {
|
||||
return CustomTextFormField(
|
||||
controller: valueController, hintText: "90".tr);
|
||||
})
|
||||
]));
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
|
||||
@@ -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<SelectionPopupModel> dropdownItemList;
|
||||
|
||||
BloodPressureModel copyWith({List<SelectionPopupModel>? dropdownItemList}) {
|
||||
return BloodPressureModel(
|
||||
userRegistrationSheet:
|
||||
userRegistrationSheet ?? this.userRegistrationSheet,
|
||||
dropdownItemList: dropdownItemList ?? this.dropdownItemList,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [dropdownItemList];
|
||||
List<Object?> get props => [dropdownItemList, userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -18,8 +18,8 @@ class BodyCircumferencesBloc
|
||||
Emitter<BodyCircumferencesState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
valueController: TextEditingController(),
|
||||
valueController1: TextEditingController(),
|
||||
valueController2: TextEditingController()));
|
||||
chestCircumferenceController: TextEditingController(),
|
||||
waistCircumferenceController: TextEditingController(),
|
||||
hipCircumferenceController: TextEditingController()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object?> 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,
|
||||
);
|
||||
|
||||
@@ -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<BodyCircumferencesBloc>(
|
||||
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<Color>(
|
||||
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<BodyCircumferencesBloc,
|
||||
BodyCircumferencesState, TextEditingController?>(
|
||||
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<BodyCircumferencesBloc, BodyCircumferencesState,
|
||||
TextEditingController?>(
|
||||
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<BodyCircumferencesBloc, BodyCircumferencesState,
|
||||
TextEditingController?>(
|
||||
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<BodyCircumferencesBloc, BodyCircumferencesState>(
|
||||
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<BodyCircumferencesBloc, BodyCircumferencesState,
|
||||
TextEditingController?>(
|
||||
selector: (state) => state.valueController,
|
||||
builder: (context, valueController) {
|
||||
return CustomTextFormField(
|
||||
controller: valueController, hintText: "90".tr);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
List<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ class CityOfLivingBloc extends Bloc<CityOfLivingEvent, CityOfLivingState> {
|
||||
Emitter<CityOfLivingState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedDropDownValue: event.value));
|
||||
state.cityOfLivingModelObj?.userRegistrationSheet.country =
|
||||
event.value.title;
|
||||
}
|
||||
|
||||
_changeDropDown1(
|
||||
@@ -35,6 +37,7 @@ class CityOfLivingBloc extends Bloc<CityOfLivingEvent, CityOfLivingState> {
|
||||
Emitter<CityOfLivingState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedDropDownValue1: event.value));
|
||||
state.cityOfLivingModelObj?.userRegistrationSheet.city = event.value.title;
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillDropdownItemList() {
|
||||
|
||||
@@ -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<CityOfLivingBloc>(
|
||||
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<Color>(
|
||||
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<CityOfLivingBloc, CityOfLivingState>(
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<SelectionPopupModel> dropdownItemList;
|
||||
|
||||
@@ -20,11 +23,14 @@ class CityOfLivingModel extends Equatable {
|
||||
List<SelectionPopupModel>? dropdownItemList1,
|
||||
}) {
|
||||
return CityOfLivingModel(
|
||||
userRegistrationSheet:
|
||||
userRegistrationSheet ?? this.userRegistrationSheet,
|
||||
dropdownItemList: dropdownItemList ?? this.dropdownItemList,
|
||||
dropdownItemList1: dropdownItemList1 ?? this.dropdownItemList1,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [dropdownItemList, dropdownItemList1];
|
||||
List<Object?> get props =>
|
||||
[dropdownItemList, dropdownItemList1, userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -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<CredentialsEvent, CredentialsState> {
|
||||
CredentialsBloc(CredentialsState initialState) : super(initialState) {
|
||||
on<CredentialsInitialEvent>(_onInitialize);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
CredentialsInitialEvent event,
|
||||
Emitter<CredentialsState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
valueController: TextEditingController(),
|
||||
passwordController: TextEditingController(),
|
||||
passwordConfirmationController: TextEditingController()));
|
||||
}
|
||||
}
|
||||
@@ -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<Object?> get props => [];
|
||||
}
|
||||
@@ -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<Object?> 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
136
lib/presentation/credentials_screen/credentials_screen.dart
Normal file
136
lib/presentation/credentials_screen/credentials_screen.dart
Normal file
@@ -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<CredentialsBloc>(
|
||||
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<Color>(
|
||||
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<CredentialsBloc, CredentialsState,
|
||||
TextEditingController?>(
|
||||
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<CredentialsBloc, CredentialsState,
|
||||
TextEditingController?>(
|
||||
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<CredentialsBloc, CredentialsState,
|
||||
TextEditingController?>(
|
||||
selector: (state) => state.passwordConfirmationController,
|
||||
builder: (context, passwordConfirmationController) {
|
||||
return CustomTextFormField(
|
||||
obscureText: true,
|
||||
controller: passwordConfirmationController,
|
||||
textInputAction: TextInputAction.done);
|
||||
}),
|
||||
Spacer(),
|
||||
BlocBuilder<CredentialsBloc, CredentialsState>(
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -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<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
@@ -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<DateOfBirthBloc>(
|
||||
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<DateOfBirthScreen> {
|
||||
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<Color>(
|
||||
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<DateOfBirthBloc, DateOfBirthState>(
|
||||
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<DateOfBirthScreen> {
|
||||
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<DateOfBirthScreen> {
|
||||
///
|
||||
/// This function returns a `Future` that completes with `void`.
|
||||
Future<void> openDatePickerDialog(BuildContext context) async {
|
||||
var initialState = BlocProvider.of<DateOfBirthBloc>(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<DateOfBirthScreen> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Navigates to the cityOfLivingScreen when the action is triggered.
|
||||
navigateToCity(BuildContext context) {
|
||||
NavigatorService.pushNamed(
|
||||
AppRoutes.cityOfLivingScreen,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
List<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class FavoriteFoodsBloc extends Bloc<FavoriteFoodsEvent, FavoriteFoodsState> {
|
||||
Emitter<FavoriteFoodsState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
enterinformationController: TextEditingController(),
|
||||
enterinformationController1: TextEditingController()));
|
||||
favoriteFoodsController: TextEditingController(),
|
||||
unfavoriteFoodsController: TextEditingController()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object?> 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,
|
||||
);
|
||||
|
||||
@@ -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<FavoriteFoodsBloc>(
|
||||
create: (context) => FavoriteFoodsBloc(
|
||||
FavoriteFoodsState(favoriteFoodsModelObj: FavoriteFoodsModel()))
|
||||
create: (context) => FavoriteFoodsBloc(FavoriteFoodsState(
|
||||
favoriteFoodsModelObj:
|
||||
FavoriteFoodsModel(userRegistrationSheet: sheet)))
|
||||
..add(FavoriteFoodsInitialEvent()),
|
||||
child: FavoriteFoodsScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<FavoriteFoodsScreen> createState() => _FavoriteFoodsScreenState();
|
||||
}
|
||||
|
||||
class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
|
||||
@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<Color>(
|
||||
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<FavoriteFoodsBloc, FavoriteFoodsState>(
|
||||
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<FavoriteFoodsBloc, FavoriteFoodsState,
|
||||
TextEditingController?>(
|
||||
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<FavoriteFoodsBloc, FavoriteFoodsState,
|
||||
TextEditingController?>(
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
List<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -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<FavoriteSportsBloc>(
|
||||
create: (context) => FavoriteSportsBloc(
|
||||
FavoriteSportsState(favoriteSportsModelObj: FavoriteSportsModel()))
|
||||
create: (context) => FavoriteSportsBloc(FavoriteSportsState(
|
||||
favoriteSportsModelObj:
|
||||
FavoriteSportsModel(userRegistrationSheet: sheet)))
|
||||
..add(FavoriteSportsInitialEvent()),
|
||||
child: FavoriteSportsScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<FavoriteSportsScreen> createState() => _FavoriteSportsScreenState();
|
||||
}
|
||||
|
||||
class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
|
||||
@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<Color>(
|
||||
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<FavoriteSportsBloc, FavoriteSportsState>(
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
List<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -9,10 +9,21 @@ part 'gender_state.dart';
|
||||
class GenderBloc extends Bloc<GenderEvent, GenderState> {
|
||||
GenderBloc(GenderState initialState) : super(initialState) {
|
||||
on<GenderInitialEvent>(_onInitialize);
|
||||
on<GenderSelectEvent>(_genderSelect);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
GenderInitialEvent event,
|
||||
Emitter<GenderState> emit,
|
||||
) async {}
|
||||
) async {
|
||||
emit(state.copyWith(genderModelObj: state.genderModelObj));
|
||||
}
|
||||
|
||||
_genderSelect(
|
||||
GenderSelectEvent event,
|
||||
Emitter<GenderState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedRadioValue: event.value));
|
||||
state.genderModelObj?.userRegistrationSheet.gender = event.value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
}
|
||||
|
||||
class GenderSelectEvent extends GenderEvent {
|
||||
GenderSelectEvent({required this.value});
|
||||
|
||||
String value;
|
||||
|
||||
@override
|
||||
List<Object?> get props => [
|
||||
value,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -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<Object?> get props => [
|
||||
selectedRadioValue,
|
||||
genderModelObj,
|
||||
];
|
||||
GenderState copyWith({GenderModel? genderModelObj}) {
|
||||
GenderState copyWith({
|
||||
String? selectedRadioValue,
|
||||
GenderModel? genderModelObj,
|
||||
}) {
|
||||
return GenderState(
|
||||
selectedRadioValue: selectedRadioValue ?? this.selectedRadioValue,
|
||||
genderModelObj: genderModelObj ?? this.genderModelObj,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<GenderBloc>(
|
||||
create: (context) =>
|
||||
GenderBloc(GenderState(genderModelObj: GenderModel()))
|
||||
..add(GenderInitialEvent()),
|
||||
create: (context) => GenderBloc(
|
||||
GenderState(
|
||||
genderModelObj: GenderModel(userRegistrationSheet: sheet),
|
||||
),
|
||||
)..add(GenderInitialEvent()),
|
||||
child: GenderScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<GenderScreen> createState() => _GenderScreenState();
|
||||
}
|
||||
|
||||
class _GenderScreenState extends State<GenderScreen> {
|
||||
@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<Color>(
|
||||
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<GenderBloc>(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<GenderBloc>(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<GenderBloc, GenderState>(
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
List<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ class HeightBloc extends Bloc<HeightEvent, HeightState> {
|
||||
Emitter<HeightState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedDropDownValue: event.value));
|
||||
state.heightModelObj?.userRegistrationSheet.height =
|
||||
int.tryParse(event.value.title)!;
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillDropdownItemList() {
|
||||
|
||||
@@ -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<HeightBloc>(
|
||||
create: (context) =>
|
||||
HeightBloc(HeightState(heightModelObj: HeightModel()))
|
||||
..add(HeightInitialEvent()),
|
||||
create: (context) => HeightBloc(HeightState(
|
||||
heightModelObj: HeightModel(userRegistrationSheet: sheet)))
|
||||
..add(HeightInitialEvent()),
|
||||
child: HeightScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<HeightScreen> createState() => _HeightScreenState();
|
||||
}
|
||||
|
||||
class _HeightScreenState extends State<HeightScreen> {
|
||||
@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<Color>(
|
||||
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<HeightBloc, HeightState, HeightModel?>(
|
||||
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<HeightBloc>()
|
||||
.add(ChangeDropDownEvent(value: value));
|
||||
});
|
||||
})
|
||||
])
|
||||
]),
|
||||
Spacer(),
|
||||
CustomOutlinedButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: () {
|
||||
navigateToAllergies(context);
|
||||
}),
|
||||
BlocBuilder<HeightBloc, HeightState>(
|
||||
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<HeightBloc, HeightState, HeightModel?>(
|
||||
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<HeightBloc>()
|
||||
.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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<SelectionPopupModel> dropdownItemList;
|
||||
|
||||
HeightModel copyWith({List<SelectionPopupModel>? dropdownItemList}) {
|
||||
return HeightModel(
|
||||
userRegistrationSheet:
|
||||
userRegistrationSheet ?? this.userRegistrationSheet,
|
||||
dropdownItemList: dropdownItemList ?? this.dropdownItemList,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [dropdownItemList];
|
||||
List<Object?> get props => [dropdownItemList, userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ class LanguageSelectBloc
|
||||
Emitter<LanguageSelectState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedDropDownValue: event.value));
|
||||
state.languageSelectModelObj?.userRegistrationSheet.lang =
|
||||
event.value.title;
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillDropdownItemList() {
|
||||
|
||||
@@ -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<LanguageSelectBloc>(
|
||||
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<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 20.v),
|
||||
Container(
|
||||
width: 262.h,
|
||||
@@ -44,7 +59,10 @@ class LanguageSelectScreen extends StatelessWidget {
|
||||
BlocSelector<LanguageSelectBloc, LanguageSelectState,
|
||||
LanguageSelectModel?>(
|
||||
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<LanguageSelectBloc, LanguageSelectState>(
|
||||
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,
|
||||
);
|
||||
});
|
||||
})));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<SelectionPopupModel> dropdownItemList;
|
||||
|
||||
LanguageSelectModel copyWith({List<SelectionPopupModel>? dropdownItemList}) {
|
||||
|
||||
@@ -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<MedicineIntakeBloc>(
|
||||
create: (context) => MedicineIntakeBloc(
|
||||
MedicineIntakeState(medicineIntakeModelObj: MedicineIntakeModel()))
|
||||
create: (context) => MedicineIntakeBloc(MedicineIntakeState(
|
||||
medicineIntakeModelObj:
|
||||
MedicineIntakeModel(userRegistrationSheet: sheet)))
|
||||
..add(MedicineIntakeInitialEvent()),
|
||||
child: MedicineIntakeScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<MedicineIntakeScreen> createState() => _MedicineIntakeScreenState();
|
||||
}
|
||||
|
||||
class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
|
||||
@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<Color>(
|
||||
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<MedicineIntakeBloc, MedicineIntakeState>(
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Object?> get props => [];
|
||||
List<Object?> get props => [userRegistrationSheet];
|
||||
}
|
||||
|
||||
22
lib/presentation/name_screen/bloc/name_bloc.dart
Normal file
22
lib/presentation/name_screen/bloc/name_bloc.dart
Normal file
@@ -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<NameEvent, NameState> {
|
||||
NameBloc(NameState initialState) : super(initialState) {
|
||||
on<NameInitialEvent>(_onInitialize);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
NameInitialEvent event,
|
||||
Emitter<NameState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
firstNameController: TextEditingController(),
|
||||
lastNameController: TextEditingController()));
|
||||
}
|
||||
}
|
||||
@@ -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<Object?> get props => [];
|
||||
}
|
||||
36
lib/presentation/name_screen/bloc/name_state.dart
Normal file
36
lib/presentation/name_screen/bloc/name_state.dart
Normal file
@@ -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<Object?> 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
21
lib/presentation/name_screen/models/name_model.dart
Normal file
21
lib/presentation/name_screen/models/name_model.dart
Normal file
@@ -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<Object?> get props => [];
|
||||
}
|
||||
119
lib/presentation/name_screen/name_screen.dart
Normal file
119
lib/presentation/name_screen/name_screen.dart
Normal file
@@ -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<NameBloc>(
|
||||
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<Color>(
|
||||
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<NameBloc, NameState, TextEditingController?>(
|
||||
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<NameBloc, NameState, TextEditingController?>(
|
||||
selector: (state) => state.lastNameController,
|
||||
builder: (context, lastNameController) {
|
||||
return CustomTextFormField(
|
||||
controller: lastNameController,
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 21.v),
|
||||
Spacer(),
|
||||
BlocBuilder<NameBloc, NameState>(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();
|
||||
}
|
||||
}
|
||||
@@ -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<ScheduleEvent, ScheduleState> {
|
||||
ScheduleBloc(ScheduleState initialState) : super(initialState) {
|
||||
on<ScheduleInitialEvent>(_onInitialize);
|
||||
}
|
||||
|
||||
_onInitialize(
|
||||
ScheduleInitialEvent event,
|
||||
Emitter<ScheduleState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(inputPlaceholderController: TextEditingController()));
|
||||
}
|
||||
}
|
||||
@@ -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<Object?> get props => [
|
||||
inputPlaceholderController,
|
||||
scheduleModelObj,
|
||||
];
|
||||
ScheduleState copyWith({
|
||||
TextEditingController? inputPlaceholderController,
|
||||
ScheduleModel? scheduleModelObj,
|
||||
}) {
|
||||
return ScheduleState(
|
||||
inputPlaceholderController:
|
||||
inputPlaceholderController ?? this.inputPlaceholderController,
|
||||
scheduleModelObj: scheduleModelObj ?? this.scheduleModelObj,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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<Object?> get props => [];
|
||||
}
|
||||
@@ -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<ScheduleBloc>(
|
||||
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<ScheduleBloc, ScheduleState, TextEditingController?>(
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -26,6 +26,8 @@ class WeightBloc extends Bloc<WeightEvent, WeightState> {
|
||||
Emitter<WeightState> emit,
|
||||
) {
|
||||
emit(state.copyWith(selectedDropDownValue: event.value));
|
||||
state.weightModelObj?.userRegistrationSheet.weight =
|
||||
int.tryParse(event.value.title)!;
|
||||
}
|
||||
|
||||
List<SelectionPopupModel> fillDropdownItemList() {
|
||||
|
||||
@@ -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<SelectionPopupModel> dropdownItemList;
|
||||
|
||||
WeightModel copyWith({List<SelectionPopupModel>? dropdownItemList}) {
|
||||
return WeightModel(
|
||||
userRegistrationSheet:
|
||||
userRegistrationSheet ?? this.userRegistrationSheet,
|
||||
dropdownItemList: dropdownItemList ?? this.dropdownItemList,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Object?> get props => [dropdownItemList];
|
||||
List<Object?> get props => [dropdownItemList, userRegistrationSheet];
|
||||
}
|
||||
|
||||
@@ -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<WeightBloc>(
|
||||
create: (context) =>
|
||||
WeightBloc(WeightState(weightModelObj: WeightModel()))
|
||||
..add(WeightInitialEvent()),
|
||||
create: (context) => WeightBloc(WeightState(
|
||||
weightModelObj: WeightModel(userRegistrationSheet: sheet)))
|
||||
..add(WeightInitialEvent()),
|
||||
child: WeightScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
State<WeightScreen> createState() => _WeightScreenState();
|
||||
}
|
||||
|
||||
class _WeightScreenState extends State<WeightScreen> {
|
||||
@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<Color>(
|
||||
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<WeightBloc, WeightState, WeightModel?>(
|
||||
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<WeightBloc>()
|
||||
.add(ChangeDropDownEvent(value: value));
|
||||
});
|
||||
})
|
||||
])
|
||||
]),
|
||||
Spacer(),
|
||||
CustomOutlinedButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: () {
|
||||
navigateToHeight(context);
|
||||
}),
|
||||
BlocBuilder<WeightBloc, WeightState>(
|
||||
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<WeightBloc, WeightState, WeightModel?>(
|
||||
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<WeightBloc>()
|
||||
.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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'dart:ui';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'dart:ui';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../core/app_export.dart';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BaseButton extends StatelessWidget {
|
||||
|
||||
@@ -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<TextInputFormatter>? inputFormatters;
|
||||
|
||||
final TextInputAction? textInputAction;
|
||||
|
||||
final TextInputType? textInputType;
|
||||
@@ -71,6 +76,8 @@ class CustomTextFormField extends StatelessWidget {
|
||||
|
||||
final FormFieldValidator<String>? 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(
|
||||
|
||||
@@ -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,
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user