From 75efb1e414e5cd266f3a22029ae77ecb15f61850 Mon Sep 17 00:00:00 2001 From: maxxkim Date: Tue, 19 Dec 2023 15:09:52 +0300 Subject: [PATCH] Added height screen for registration & set adequate options and initial parameters for height/weight --- .../en_us/en_us_translations.dart | 2 +- lib/localization/ru/ru_translations.dart | 2 +- .../date_of_birth_screen.dart | 2 +- .../height_screen/bloc/height_bloc.dart | 40 ++++++ .../height_screen/bloc/height_event.dart | 28 ++++ .../height_screen/bloc/height_state.dart | 31 +++++ .../height_screen/height_screen.dart | 124 ++++++++++++++++++ .../height_screen/models/height_model.dart | 21 +++ .../weight_screen/bloc/weight_bloc.dart | 12 +- .../weight_screen/weight_screen.dart | 8 +- lib/routes/app_routes.dart | 6 + 11 files changed, 264 insertions(+), 12 deletions(-) create mode 100644 lib/presentation/height_screen/bloc/height_bloc.dart create mode 100644 lib/presentation/height_screen/bloc/height_event.dart create mode 100644 lib/presentation/height_screen/bloc/height_state.dart create mode 100644 lib/presentation/height_screen/height_screen.dart create mode 100644 lib/presentation/height_screen/models/height_model.dart diff --git a/lib/localization/en_us/en_us_translations.dart b/lib/localization/en_us/en_us_translations.dart index 04c0fc1..282c4c7 100644 --- a/lib/localization/en_us/en_us_translations.dart +++ b/lib/localization/en_us/en_us_translations.dart @@ -14,7 +14,7 @@ final Map enUs = { // weight Screen "weight_measurements": "Weight measurements", "your_weight": "Your weight:", - "lbl_70": "70", + "height_measurements": "Height measurements", "your_height": "Your height:", // allergies Screen "allergies_presence": "Allergies presence", diff --git a/lib/localization/ru/ru_translations.dart b/lib/localization/ru/ru_translations.dart index d653273..25637d8 100644 --- a/lib/localization/ru/ru_translations.dart +++ b/lib/localization/ru/ru_translations.dart @@ -13,7 +13,7 @@ final Map ru = { // weight Screen "weight_measurements": "Замер веса", "your_weight": "Ваш вес:", - "lbl_70": "70", + "height_measurements": "Замер роста", "your_height": "Ваш рост:", // allergies Screen "allergies_presence": "Наличие аллергии", diff --git a/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart b/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart index 1b40a85..f7ec213 100644 --- a/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart +++ b/lib/presentation/date_of_birth_screen/date_of_birth_screen.dart @@ -109,7 +109,7 @@ class DateOfBirthScreen extends StatelessWidget { onTap: () { openDatePickerDialog(context); }, - child: Text("lbl_01_01_2000".tr, + child: Text('ТУТ БУДЕТ ДАТА'.tr, style: theme.textTheme.titleMedium))), SizedBox(height: 6.v) ])); diff --git a/lib/presentation/height_screen/bloc/height_bloc.dart b/lib/presentation/height_screen/bloc/height_bloc.dart new file mode 100644 index 0000000..481fd77 --- /dev/null +++ b/lib/presentation/height_screen/bloc/height_bloc.dart @@ -0,0 +1,40 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/height_screen/models/height_model.dart'; +part 'height_event.dart'; +part 'height_state.dart'; + +/// A bloc that manages the state of a Height according to the event that is dispatched to it. +class HeightBloc extends Bloc { + HeightBloc(HeightState initialState) : super(initialState) { + on(_onInitialize); + on(_changeDropDown); + } + + _onInitialize( + HeightInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + heightModelObj: state.heightModelObj + ?.copyWith(dropdownItemList: fillDropdownItemList()))); + } + + _changeDropDown( + ChangeDropDownEvent event, + Emitter emit, + ) { + emit(state.copyWith(selectedDropDownValue: event.value)); + } + + List fillDropdownItemList() { + List selectionPopupModels = []; + + for (int i = 140; i <= 220; i++) { + selectionPopupModels + .add(SelectionPopupModel(id: i - 34, title: i.toString())); + } + return selectionPopupModels; + } +} diff --git a/lib/presentation/height_screen/bloc/height_event.dart b/lib/presentation/height_screen/bloc/height_event.dart new file mode 100644 index 0000000..80d209c --- /dev/null +++ b/lib/presentation/height_screen/bloc/height_event.dart @@ -0,0 +1,28 @@ +// ignore_for_file: must_be_immutable + +part of 'height_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///Height widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class HeightEvent extends Equatable {} + +/// Event that is dispatched when the Height widget is first created. +class HeightInitialEvent extends HeightEvent { + @override + List get props => []; +} + +///event for dropdown selection +class ChangeDropDownEvent extends HeightEvent { + ChangeDropDownEvent({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} diff --git a/lib/presentation/height_screen/bloc/height_state.dart b/lib/presentation/height_screen/bloc/height_state.dart new file mode 100644 index 0000000..d0e3f45 --- /dev/null +++ b/lib/presentation/height_screen/bloc/height_state.dart @@ -0,0 +1,31 @@ +// ignore_for_file: must_be_immutable + +part of 'height_bloc.dart'; + +/// Represents the state of Height in the application. +class HeightState extends Equatable { + HeightState({ + this.selectedDropDownValue, + this.heightModelObj, + }); + + SelectionPopupModel? selectedDropDownValue; + + HeightModel? heightModelObj; + + @override + List get props => [ + selectedDropDownValue, + heightModelObj, + ]; + HeightState copyWith({ + SelectionPopupModel? selectedDropDownValue, + HeightModel? heightModelObj, + }) { + return HeightState( + selectedDropDownValue: + selectedDropDownValue ?? this.selectedDropDownValue, + heightModelObj: heightModelObj ?? this.heightModelObj, + ); + } +} diff --git a/lib/presentation/height_screen/height_screen.dart b/lib/presentation/height_screen/height_screen.dart new file mode 100644 index 0000000..9d24720 --- /dev/null +++ b/lib/presentation/height_screen/height_screen.dart @@ -0,0 +1,124 @@ +import 'bloc/height_bloc.dart'; +import 'models/height_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:flutter/material.dart'; + +class HeightScreen extends StatelessWidget { + const HeightScreen({Key? key}) : super(key: key); + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => + HeightBloc(HeightState(heightModelObj: HeightModel())) + ..add(HeightInitialEvent()), + child: HeightScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + 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.35, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400)))), + SizedBox(height: 39.v), + _buildTwentySix(context), + Spacer(), + CustomOutlinedButton( + text: "continue".tr.toUpperCase(), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: () { + navigateToAllergies(context); + }), + SizedBox(height: 17.v), + Text("skip".tr, style: theme.textTheme.bodyLarge) + ])))); + } + + /// 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)); + } + + /// Section Widget + Widget _buildTwentySixWidget(BuildContext context) { + return Column(children: [ + Text("your_height".tr, style: theme.textTheme.bodyLarge), + SizedBox(height: 4.v), + BlocSelector( + 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() + .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, + ); + } +} diff --git a/lib/presentation/height_screen/models/height_model.dart b/lib/presentation/height_screen/models/height_model.dart new file mode 100644 index 0000000..0a9a444 --- /dev/null +++ b/lib/presentation/height_screen/models/height_model.dart @@ -0,0 +1,21 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; +import 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_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 []}) {} + + List dropdownItemList; + + HeightModel copyWith({List? dropdownItemList}) { + return HeightModel( + dropdownItemList: dropdownItemList ?? this.dropdownItemList, + ); + } + + @override + List get props => [dropdownItemList]; +} diff --git a/lib/presentation/weight_screen/bloc/weight_bloc.dart b/lib/presentation/weight_screen/bloc/weight_bloc.dart index 70440b6..37ce090 100644 --- a/lib/presentation/weight_screen/bloc/weight_bloc.dart +++ b/lib/presentation/weight_screen/bloc/weight_bloc.dart @@ -29,10 +29,12 @@ class WeightBloc extends Bloc { } List fillDropdownItemList() { - return [ - SelectionPopupModel(id: 1, title: "Item One", isSelected: true), - SelectionPopupModel(id: 2, title: "Item Two"), - SelectionPopupModel(id: 3, title: "Item Three") - ]; + List selectionPopupModels = []; + + for (int i = 35; i <= 200; i++) { + selectionPopupModels + .add(SelectionPopupModel(id: i - 34, title: i.toString())); + } + return selectionPopupModels; } } diff --git a/lib/presentation/weight_screen/weight_screen.dart b/lib/presentation/weight_screen/weight_screen.dart index 01f84f0..78a00e2 100644 --- a/lib/presentation/weight_screen/weight_screen.dart +++ b/lib/presentation/weight_screen/weight_screen.dart @@ -52,7 +52,7 @@ class WeightScreen extends StatelessWidget { text: "continue".tr.toUpperCase(), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, onPressed: () { - navigateToAllergies(context); + navigateToHeight(context); }), SizedBox(height: 17.v), Text("skip".tr, style: theme.textTheme.bodyLarge) @@ -90,7 +90,7 @@ class WeightScreen extends StatelessWidget { imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize)), - hintText: "lbl_70".tr, + hintText: "70", items: weightModelObj?.dropdownItemList ?? [], onChanged: (value) { context @@ -116,9 +116,9 @@ class WeightScreen extends StatelessWidget { } /// Navigates to the allergiesScreen when the action is triggered. - navigateToAllergies(BuildContext context) { + navigateToHeight(BuildContext context) { NavigatorService.pushNamed( - AppRoutes.allergiesScreen, + AppRoutes.heightScreen, ); } } diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index d0a33cd..50e3bdf 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -13,9 +13,12 @@ import 'package:eatvio_app/presentation/favorite_foods_screen/favorite_foods_scr 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/app_navigation_screen/app_navigation_screen.dart'; class AppRoutes { + // REGISTRATION + static const String dateOfBirthScreen = '/date_of_birth_screen'; static const String cityOfLivingScreen = '/city_of_living_screen'; @@ -24,6 +27,8 @@ class AppRoutes { static const String weightScreen = '/weight_screen'; + static const String heightScreen = '/height_screen'; + static const String allergiesScreen = '/allergies_screen'; static const String medicineIntakeScreen = '/medicine_intake_screen'; @@ -54,6 +59,7 @@ class AppRoutes { cityOfLivingScreen: CityOfLivingScreen.builder, bodyCircumferencesScreen: BodyCircumferencesScreen.builder, weightScreen: WeightScreen.builder, + heightScreen: HeightScreen.builder, allergiesScreen: AllergiesScreen.builder, medicineIntakeScreen: MedicineIntakeScreen.builder, splashScreen: SplashScreen.builder,