From 82eca66ae4879fd4e57fd6b6c4f399c4fa2796e9 Mon Sep 17 00:00:00 2001 From: maxxkim Date: Mon, 12 Feb 2024 15:02:43 +0300 Subject: [PATCH] feat(diary) Improved layouts and TimePicker --- .../bloc/diary_edit_bloc.dart | 12 +- .../bloc/diary_edit_state.dart | 14 ++- .../diary_edit_screen/diary_edit_screen.dart | 108 ++++++++---------- lib/widgets/custom_expandable_list_card.dart | 99 ++++++++++++++++ 4 files changed, 167 insertions(+), 66 deletions(-) create mode 100644 lib/widgets/custom_expandable_list_card.dart diff --git a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart index 7254d633..a4ad140c 100644 --- a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart +++ b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart @@ -39,11 +39,17 @@ class DiaryEditBloc extends Bloc { // Если текущее состояние уже загружено, обновляем его var currentState = state as DiaryEditLoadedState; // Обновляем значения контроллеров только если они уже были созданы - - emit((currentState).copyWith()); + print(currentState.wakeupController); + emit((currentState).copyWith( + wakeupController: currentState.wakeupController, + retireController: currentState.retireController, + )); } else { // Если текущее состояние - начальное, создаем новое загруженное состояние - emit(DiaryEditLoadedState()); + emit(DiaryEditLoadedState( + wakeupController: TimeOfDay.now(), + retireController: TimeOfDay.now(), + )); } } else { // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку diff --git a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_state.dart b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_state.dart index 7b9da4ab..9c82ff9a 100644 --- a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_state.dart +++ b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_state.dart @@ -18,19 +18,25 @@ class DiaryEditInitialState extends DiaryEditState { /// Represents the state of DiaryEdit in the application. class DiaryEditLoadedState extends DiaryEditState { - DiaryEditLoadedState({this.diaryEditModelObj}) + DiaryEditLoadedState( + {this.diaryEditModelObj, this.wakeupController, this.retireController}) : super(diaryEditModelObj: null); DiaryEditModel? diaryEditModelObj; + TimeOfDay? wakeupController; + TimeOfDay? retireController; @override - List get props => [ - diaryEditModelObj, - ]; + List get props => + [diaryEditModelObj, wakeupController, retireController]; DiaryEditLoadedState copyWith({ DiaryEditModel? diaryEditModelObj, + TimeOfDay? wakeupController, + TimeOfDay? retireController, }) { return DiaryEditLoadedState( diaryEditModelObj: diaryEditModelObj ?? this.diaryEditModelObj, + wakeupController: wakeupController ?? this.wakeupController, + retireController: retireController ?? this.retireController, ); } } diff --git a/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart b/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart index 7d19300e..34ac3cc4 100644 --- a/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart +++ b/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart @@ -6,6 +6,7 @@ import 'package:eatvio_app/widgets/custom_text_form_field.dart'; import 'package:eatvio_app/widgets/custom_edit_drop_down.dart'; import 'package:eatvio_app/widgets/custom_outlined_button.dart'; import 'package:eatvio_app/widgets/custom_icon_button.dart'; +import 'package:eatvio_app/widgets/custom_expandable_list_card.dart'; // ignore: must_be_immutable class DiaryEditScreen extends StatelessWidget { @@ -26,20 +27,19 @@ class DiaryEditScreen extends StatelessWidget { "Item Three", ]; - TextEditingController enterProductNameController = TextEditingController(); - - TextEditingController quantityController = TextEditingController(); - List dropdownItemList2 = [ "Item One", "Item Two", "Item Three", ]; - List dropdownItemList3 = [ - "Item One", - "Item Two", - "Item Three", + List moodList = [ + "Ужасное", + "Плохое", + "Удовлетворительное", + "Нормальное", + "Хорошее", + "Прекрасное", ]; static Widget builder(BuildContext context) { @@ -91,43 +91,11 @@ class DiaryEditScreen extends StatelessWidget { children: [ _buildHeaderRow(context), SizedBox(height: 30.v), - Padding( - padding: EdgeInsets.symmetric(horizontal: 16.h), - child: CustomDropDown( - icon: Container( - margin: - EdgeInsets.fromLTRB(30.h, 24.v, 20.h, 22.v), - child: CustomImageView( - imagePath: ImageConstant.imgArrowLeft, - height: 10.v, - width: 18.h, - ), - ), - hintText: "Подъём \\ уход ко сну", - items: dropdownItemList, - onChanged: (value) {}, - ), - ), + _buildWakupRetire(), SizedBox(height: 30.v), _buildImageStack(context), SizedBox(height: 20.v), - Padding( - padding: EdgeInsets.symmetric(horizontal: 16.h), - child: CustomDropDown( - icon: Container( - margin: - EdgeInsets.fromLTRB(30.h, 30.v, 20.h, 30.v), - child: CustomImageView( - imagePath: ImageConstant.imgArrowLeft, - height: 10.v, - width: 18.h, - ), - ), - hintText: "Ваше настроение после приема пищи", - items: dropdownItemList3, - onChanged: (value) {}, - ), - ), + _buildMood(moodList), SizedBox(height: 30.v), _buildHeaderColumn(context), SizedBox(height: 30.v), @@ -148,7 +116,7 @@ class DiaryEditScreen extends StatelessWidget { /// Section Widget Widget _buildHeaderRow(BuildContext context) { return Container( - margin: EdgeInsets.symmetric(horizontal: 16.h), + margin: EdgeInsets.symmetric(horizontal: 16.h, vertical: 16.h), padding: EdgeInsets.symmetric( horizontal: 24.h, vertical: 12.v, @@ -160,14 +128,10 @@ class DiaryEditScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CustomImageView( - imagePath: ImageConstant.imgArrowLeft, - height: 2.v, - width: 20.h, - margin: EdgeInsets.only( - top: 19.v, - bottom: 17.v, - ), - ), + imagePath: ImageConstant.imgArrowLeft, + onTap: () { + NavigatorService.goBack(); + }), Padding( padding: EdgeInsets.only(top: 1.v), child: Column( @@ -193,19 +157,20 @@ class DiaryEditScreen extends StatelessWidget { } /// Section Widget - Widget _buildHeaderButton1(BuildContext context) { - return CustomOutlinedButton( - width: 73.h, - text: "14:52", + Widget _buildMealTime(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 10.h), + child: CustomTextFormField( + hintText: "14:52", + ), ); } /// Section Widget Widget _buildEnterProductName(BuildContext context) { return Padding( - padding: EdgeInsets.symmetric(horizontal: 10.h), + padding: EdgeInsets.symmetric(horizontal: 8.h), child: CustomTextFormField( - controller: enterProductNameController, hintText: "Введите названия продукта", ), ); @@ -215,7 +180,6 @@ class DiaryEditScreen extends StatelessWidget { Widget _buildQuantity(BuildContext context) { return CustomTextFormField( width: 146.h, - controller: quantityController, hintText: "Кол-во", textInputAction: TextInputAction.done, ); @@ -285,7 +249,7 @@ class DiaryEditScreen extends StatelessWidget { style: CustomTextStyles.bodyMediumBlack900, ), ), - _buildHeaderButton1(context), + _buildMealTime(context), ], ), ), @@ -815,3 +779,29 @@ class DiaryEditScreen extends StatelessWidget { ); } } + +Widget _buildWakupRetire() { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 16.h), + child: ExpandableList(r'Подъем \ уход ко сну'), + ); +} + +Widget _buildMood(List moodList) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 16.h), + child: CustomDropDown( + icon: Container( + margin: EdgeInsets.fromLTRB(30.h, 30.v, 20.h, 30.v), + child: CustomImageView( + imagePath: ImageConstant.imgArrowLeft, + height: 10.v, + width: 18.h, + ), + ), + hintText: "Ваше настроение после приема пищи", + items: moodList, + onChanged: (value) {}, + ), + ); +} diff --git a/lib/widgets/custom_expandable_list_card.dart b/lib/widgets/custom_expandable_list_card.dart new file mode 100644 index 00000000..4ac3be56 --- /dev/null +++ b/lib/widgets/custom_expandable_list_card.dart @@ -0,0 +1,99 @@ +import 'package:eatvio_app/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart'; +import 'package:flutter/material.dart'; +import 'package:eatvio_app/core/app_export.dart'; + +class ExpandableList extends StatefulWidget { + final String title; + + ExpandableList(this.title); + @override + _ExpandableListState createState() => _ExpandableListState(); +} + +class _ExpandableListState extends State { + bool isExpanded = false; + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + return Container( + padding: EdgeInsets.symmetric( + horizontal: 24.h, + vertical: 12.v, + ), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder12, + ), + child: Column( + children: [ + GestureDetector( + onTap: () { + setState(() { + isExpanded = !isExpanded; + }); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + widget.title, + style: CustomTextStyles.bodyMediumBlack900, + ), + Icon(isExpanded + ? Icons.arrow_drop_up + : Icons.arrow_drop_down), + ], + ), + ), + if (isExpanded) + Padding( + padding: const EdgeInsets.only(left: 16.0), + child: Column( + children: [ + GestureDetector( + onTap: () => _selectTime(context), + child: AbsorbPointer( + child: TextFormField( + decoration: InputDecoration( + labelText: 'Во сколько вы просунились?', + suffixIcon: Icon(Icons.access_time), + ), + initialValue: + '${TimeOfDay.now().hour}:${TimeOfDay.now().minute.toString().padLeft(2, '0')}', + ), + ), + ), + GestureDetector( + onTap: () => _selectTime(context), + child: AbsorbPointer( + child: TextFormField( + decoration: InputDecoration( + labelText: 'о сколько вы легли спать?', + suffixIcon: Icon(Icons.access_time), + ), + initialValue: + '${TimeOfDay.now().hour}:${TimeOfDay.now().minute.toString().padLeft(2, '0')}', + ), + ), + ) + ], + ), + ), + ], + )); + }); + } + + Future _selectTime( + BuildContext context, DiaryEditLoadedState state) async { + final TimeOfDay? pickedTime = await showTimePicker( + context: context, + initialTime: state.wakeupController ?? TimeOfDay.now(), + ); + if (pickedTime != null && pickedTime != state.wakeupController) { + setState(() { + state.wakeupController = pickedTime; + }); + } + } +}