diff --git a/lib/presentation/auth/auth_screen/auth_screen.dart b/lib/presentation/auth/auth_screen/auth_screen.dart index 15f2d909..19bcac26 100644 --- a/lib/presentation/auth/auth_screen/auth_screen.dart +++ b/lib/presentation/auth/auth_screen/auth_screen.dart @@ -95,7 +95,7 @@ class AuthScreen extends StatelessWidget { box.put('token', token); Navigator.pushNamed( context, - AppRoutes.myProfile, + AppRoutes.diaryEdit, ); } else { showDialog( diff --git a/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_bloc.dart b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_bloc.dart new file mode 100644 index 00000000..98d6b5e3 --- /dev/null +++ b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_bloc.dart @@ -0,0 +1,246 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/diary/diary_edit_screen/models/diary_edit_model.dart'; +import 'package:http/http.dart' as http; +import 'dart:convert'; +import 'package:hive/hive.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; + +part 'diary_edit_event.dart'; +part 'diary_edit_state.dart'; + +/// A bloc that manages the state of a DiaryEdit according to the event that is dispatched to it. +class DiaryEditBloc extends Bloc { + DiaryEditBloc(DiaryEditState initialState) : super(initialState) { + on(_onInitialize); + } + + Future _onInitialize( + DiaryEditInitialEvent event, + Emitter emit, + ) async { + try { + final box = await Hive.openBox('token'); + final token = box.get('token'); + final response = await http.get( + Uri.parse(dotenv.env['SERVER_ROOT']! + '/profile/index'), + headers: { + 'Authorization': 'Bearer $token', + }, + ); + + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + // Проверка наличия ключевых полей в JSON + if (data is Map && + data.containsKey('user') && + data.containsKey('userDetails') && + data.containsKey('chartPoints') && + data.containsKey('circumferences')) { + // Все ключевые поля присутствуют, продолжаем обработку + if (state is DiaryEditLoadedState) { + // Если текущее состояние уже загружено, обновляем его + var currentState = state as DiaryEditLoadedState; + var plans = [] + ..addAll(data["finishedPlans"]) + ..addAll(data["rejectedPlans"]) + ..addAll(data["startedPlan"]) + ..addAll(data["paidPlan"]) + ..addAll(data["requestedPlan"]) + ..addAll(data["initedPlan"]); + + // Обновляем значения контроллеров только если они уже были созданы + + emit((currentState).copyWith( + chartPoints: currentState.chartPoints, + chartDates: currentState.chartDates, + circumferences: currentState.circumferences, + user: data['user'], + userDetails: data['userDetails'], + plans: plans, + token: token, + chestCircumferenceController: TextEditingController(), + waistCircumferenceController: TextEditingController(), + hipCircumferenceController: TextEditingController(), + weightController: TextEditingController(), + chestCircumferenceFormController: + currentState.chestCircumferenceFormController, + waistCircumferenceFormController: + currentState.waistCircumferenceFormController, + hipCircumferenceFormController: + currentState.hipCircumferenceFormController, + firstNameFormController: currentState.firstNameFormController, + lastNameFormController: currentState.lastNameFormController, + countryFormController: currentState.countryFormController, + cityFormController: currentState.cityFormController, + heightFormController: currentState.heightFormController, + upPressureFormController: currentState.upPressureFormController, + downPressureFormController: + currentState.downPressureFormController, + allergiesFormController: currentState.allergiesFormController, + pillsFormController: currentState.pillsFormController, + favoriteFormController: currentState.favoriteFormController, + unfavoriteFormController: currentState.unfavoriteFormController, + additionalFormController: currentState.additionalFormController, + sportsFormController: currentState.sportsFormController, + dateFormController: currentState.dateFormController, + hypoFormController: currentState.hypoFormController, + hyperFormController: currentState.hyperFormController, + selectedCity: currentState.selectedCity, + selectedCountry: currentState.selectedCountry, + )); + } else { + var plans = [] + ..addAll(data["finishedPlans"]) + ..addAll(data["rejectedPlans"]) + ..addAll(data["startedPlan"]) + ..addAll(data["paidPlan"]) + ..addAll(data["requestedPlan"]) + ..addAll(data["initedPlan"]); + + /*print(data["chartPoints"].length); + print(data["chartPoints"].runtimeType); + print(data["circumferences"].length); + print(data["circumferences"].runtimeType);*/ + if (data["chartPoints"].length == 1) { + data["chartPoints"] = []; + } + if (data["circumferences"].length == 1) { + data["circumferences"] = []; + } + var circumferences = data["circumferences"].isEmpty + ? data["circumferences"].asMap().map((index, value) { + return MapEntry(index.toString(), value); + }) + : data["circumferences"]; + var chartPoints = data["chartPoints"].isEmpty + ? data["chartPoints"].asMap().map((index, value) { + return MapEntry(index.toString(), value); + }) + : data["chartPoints"]; + + /*List weights = [0.0, 0.0, 0.0, 0.0]; + List dates = [ + "0000-00-00 00:00:00", + "0000-00-00 00:00:00", + "0000-00-00 00:00:00", + "0000-00-00 00:00:00" + ]; + for (int i = 0; i < data["chartPoints"].length; i++) { + weights[i] = data["chartPoints"][i]["weight"].toDouble(); + dates[i] = data["chartPoints"][i]["created_at"].toString(); + } + print(data);*/ + List dates = [ + "0000-00-00 00:00:00", + "0000-00-00 00:00:00", + "0000-00-00 00:00:00", + "0000-00-00 00:00:00" + ]; + for (int i = 0; i < data["circumferences"].length; i++) { + dates[i] = data["circumferences"]['$i']["created_at"]; + } + if (chartPoints.length < 4) { + for (int i = chartPoints.length; i < 4; i++) { + chartPoints["$i"] = { + "id": 0, + "user_id": 0, + "weight": 0, + "created_at": "0000-00-00 00:00:00", + "updated_at": "0000-00-00 00:00:00" + }; + } + } + + if (circumferences.length < 4) { + for (int i = circumferences.length; i < 4; i++) { + circumferences["$i"] = { + "id": 0, + "user_id": 0, + "chest_circumference": 0, + "waist_circumference": 0, + "hip_circumference": 0, + "created_at": "0000-00-00 00:00:00", + "updated_at": "0000-00-00 00:00:00" + }; + } + } + + /*print(chartPoints); + print(circumferences);*/ + /*print(weights); + print(weights.runtimeType); + print(circumferences); + print(circumferences.runtimeType);*/ + // Если текущее состояние - начальное, создаем новое загруженное состояние + emit(DiaryEditLoadedState( + chartPoints: chartPoints, + chartDates: dates, + circumferences: circumferences, + user: data['user'], + userDetails: data['userDetails'], + plans: plans, + token: token, + chestCircumferenceController: TextEditingController(), + waistCircumferenceController: TextEditingController(), + hipCircumferenceController: TextEditingController(), + hypoFormController: data['userDetails']['has_hypo'].toString(), + hyperFormController: data['userDetails']['has_hyper'].toString(), + chestCircumferenceFormController: TextEditingController( + text: data['userDetails']['chest_circumference']?.toString()), + waistCircumferenceFormController: TextEditingController( + text: data['userDetails']['waist_circumference']?.toString()), + hipCircumferenceFormController: TextEditingController( + text: data['userDetails']['hip_circumference']?.toString()), + weightController: TextEditingController( + text: data['userDetails']['weight']?.toString()), + weightFormController: TextEditingController( + text: data['userDetails']['weight']?.toString()), + firstNameFormController: TextEditingController( + text: data['userDetails']['first_name']), + lastNameFormController: + TextEditingController(text: data['userDetails']['last_name']), + countryFormController: + TextEditingController(text: data['userDetails']['country']), + cityFormController: + TextEditingController(text: data['userDetails']['city']), + heightFormController: TextEditingController( + text: data['userDetails']['height']?.toString()), + upPressureFormController: TextEditingController( + text: data['userDetails']['blood_pressure_up']?.toString()), + downPressureFormController: TextEditingController( + text: data['userDetails']['blood_pressure_down']?.toString()), + allergiesFormController: TextEditingController( + text: data['userDetails']['about_alergy']), + pillsFormController: TextEditingController( + text: data['userDetails']['about_taking_pils']), + sportsFormController: TextEditingController( + text: data['userDetails']['about_sport_hobbies']), + favoriteFormController: TextEditingController( + text: data['userDetails']['favorite_foods']), + unfavoriteFormController: TextEditingController( + text: data['userDetails']['unfavorite_foods']), + additionalFormController: TextEditingController( + text: data['userDetails']['additional_info']), + dateFormController: + TextEditingController(text: data['userDetails']['birthdate']), + selectedCity: data['userDetails']['city'], + selectedCountry: data['userDetails']['country'], + )); + } + } else { + // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку + emit( + DiaryEditErrorState('Некоторые необходимые данные отсутствуют.')); + } + } else { + // Статус ответа не равен 200, обрабатываем ошибку + emit(DiaryEditErrorState('Ошибка сервера: ${response.statusCode}')); + } + } catch (e) { + // Ошибка при декодировании JSON или другая ошибка выполнения + emit(DiaryEditErrorState('Ошибка при получении данных профиля: $e')); + } + } +} diff --git a/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_event.dart b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_event.dart new file mode 100644 index 00000000..ea52a649 --- /dev/null +++ b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_event.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +part of 'diary_edit_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///DiaryEdit widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class DiaryEditEvent extends Equatable {} + +/// Event that is dispatched when the DiaryEdit widget is first created. +class DiaryEditInitialEvent extends DiaryEditEvent { + @override + List get props => []; +} diff --git a/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_state.dart b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_state.dart new file mode 100644 index 00000000..a512813f --- /dev/null +++ b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/bloc/diary_edit_state.dart @@ -0,0 +1,225 @@ +// ignore_for_file: must_be_immutable + +part of 'diary_edit_bloc.dart'; + +class DiaryEditState extends Equatable { + const DiaryEditState({this.diaryEditModelObj}); + + final DiaryEditModel? diaryEditModelObj; + + @override + List get props => [diaryEditModelObj]; +} + +class DiaryEditInitialState extends DiaryEditState { + DiaryEditInitialState({required DiaryEditModel diaryEditModelObj}) + : super(diaryEditModelObj: diaryEditModelObj); +} + +/// Represents the state of DiaryEdit in the application. +class DiaryEditLoadedState extends DiaryEditState { + DiaryEditLoadedState( + {this.chestCircumferenceController, + this.waistCircumferenceController, + this.hipCircumferenceController, + this.diaryEditModelObj, + this.weightController, + this.user, + this.userDetails, + this.chartPoints, + this.chartDates, + this.plans, + this.token, + this.selectedCountry, + this.selectedCity, + this.chestCircumferenceFormController, + this.waistCircumferenceFormController, + this.hipCircumferenceFormController, + this.firstNameFormController, + this.lastNameFormController, + this.countryFormController, + this.dateFormController, + this.cityFormController, + this.heightFormController, + this.weightFormController, + this.upPressureFormController, + this.downPressureFormController, + this.allergiesFormController, + this.pillsFormController, + this.sportsFormController, + this.favoriteFormController, + this.unfavoriteFormController, + this.additionalFormController, + this.hypoFormController, + this.hyperFormController, + this.circumferences}) + : super(diaryEditModelObj: null); + + DiaryEditModel? diaryEditModelObj; + Map? user; + Map? userDetails; + Map? circumferences; + Map? chartPoints; + List? chartDates; + List? plans; + TextEditingController? weightController; + TextEditingController? chestCircumferenceController; + TextEditingController? waistCircumferenceController; + TextEditingController? hipCircumferenceController; + TextEditingController? weightFormController; + TextEditingController? chestCircumferenceFormController; + TextEditingController? waistCircumferenceFormController; + TextEditingController? hipCircumferenceFormController; + TextEditingController? firstNameFormController; + TextEditingController? lastNameFormController; + TextEditingController? countryFormController; + TextEditingController? dateFormController; + TextEditingController? cityFormController; + TextEditingController? heightFormController; + TextEditingController? upPressureFormController; + TextEditingController? downPressureFormController; + TextEditingController? allergiesFormController; + TextEditingController? pillsFormController; + TextEditingController? sportsFormController; + TextEditingController? favoriteFormController; + TextEditingController? unfavoriteFormController; + TextEditingController? additionalFormController; + String? token; + String? selectedCountry; + String? selectedCity; + String? hypoFormController; + String? hyperFormController; + @override + List get props => [ + diaryEditModelObj, + user, + chartPoints, + chartDates, + circumferences, + plans, + weightController, + chestCircumferenceController, + waistCircumferenceController, + hipCircumferenceController, + token, + chestCircumferenceFormController, + waistCircumferenceFormController, + hipCircumferenceFormController, + firstNameFormController, + lastNameFormController, + countryFormController, + dateFormController, + cityFormController, + heightFormController, + weightFormController, + upPressureFormController, + downPressureFormController, + allergiesFormController, + pillsFormController, + sportsFormController, + favoriteFormController, + unfavoriteFormController, + additionalFormController, + selectedCountry, + selectedCity, + hypoFormController, + hyperFormController, + ]; + DiaryEditLoadedState copyWith({ + DiaryEditModel? diaryEditModelObj, + Map? user, + Map? userDetails, + List? plans, + Map? chartPoints, + List? chartDates, + Map? circumferences, + TextEditingController? weightController, + TextEditingController? chestCircumferenceController, + TextEditingController? waistCircumferenceController, + TextEditingController? hipCircumferenceController, + TextEditingController? chestCircumferenceFormController, + TextEditingController? waistCircumferenceFormController, + TextEditingController? hipCircumferenceFormController, + TextEditingController? firstNameFormController, + TextEditingController? lastNameFormController, + TextEditingController? countryFormController, + TextEditingController? dateFormController, + TextEditingController? cityFormController, + TextEditingController? heightFormController, + TextEditingController? weightFormeFormController, + TextEditingController? allergiesFormController, + TextEditingController? pillsFormController, + TextEditingController? sportsFormController, + TextEditingController? favoriteFormController, + TextEditingController? unfavoriteFormController, + TextEditingController? additionalFormController, + TextEditingController? downPressureFormController, + TextEditingController? upPressureFormController, + String? token, + String? selectedCountry, + String? selectedCity, + String? hypoFormController, + String? hyperFormController, + }) { + return DiaryEditLoadedState( + diaryEditModelObj: diaryEditModelObj ?? this.diaryEditModelObj, + user: user ?? this.user, + plans: plans ?? this.plans, + userDetails: userDetails ?? this.userDetails, + circumferences: circumferences ?? this.circumferences, + chartPoints: chartPoints ?? this.chartPoints, + chartDates: chartDates ?? this.chartDates, + weightController: weightController ?? this.weightController, + chestCircumferenceController: + chestCircumferenceController ?? this.chestCircumferenceController, + waistCircumferenceController: + waistCircumferenceController ?? this.waistCircumferenceController, + hipCircumferenceController: + hipCircumferenceController ?? this.hipCircumferenceController, + chestCircumferenceFormController: chestCircumferenceFormController ?? + this.chestCircumferenceFormController, + waistCircumferenceFormController: waistCircumferenceFormController ?? + this.waistCircumferenceFormController, + hipCircumferenceFormController: + hipCircumferenceFormController ?? this.hipCircumferenceFormController, + firstNameFormController: + firstNameFormController ?? this.firstNameFormController, + lastNameFormController: + lastNameFormController ?? this.lastNameFormController, + countryFormController: + countryFormController ?? this.countryFormController, + dateFormController: dateFormController ?? this.dateFormController, + cityFormController: cityFormController ?? this.cityFormController, + heightFormController: heightFormController ?? this.heightFormController, + weightFormController: weightFormController ?? this.weightFormController, + upPressureFormController: + upPressureFormController ?? this.upPressureFormController, + downPressureFormController: + downPressureFormController ?? this.downPressureFormController, + allergiesFormController: + allergiesFormController ?? this.allergiesFormController, + pillsFormController: pillsFormController ?? this.pillsFormController, + sportsFormController: sportsFormController ?? this.sportsFormController, + favoriteFormController: + favoriteFormController ?? this.favoriteFormController, + unfavoriteFormController: + unfavoriteFormController ?? this.unfavoriteFormController, + additionalFormController: + additionalFormController ?? this.additionalFormController, + token: token ?? this.token, + selectedCountry: selectedCountry ?? this.selectedCountry, + selectedCity: selectedCity ?? this.selectedCity, + hypoFormController: hypoFormController ?? this.hypoFormController, + hyperFormController: hyperFormController ?? this.hyperFormController, + ); + } +} + +class DiaryEditErrorState extends DiaryEditState { + final String errorMessage; + + const DiaryEditErrorState(this.errorMessage); + + @override + List get props => [errorMessage]; +} diff --git a/lib/presentation/auth/auth_screen/diary/diary_edit_screen/diary_edit_screen.dart b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/diary_edit_screen.dart new file mode 100644 index 00000000..7d19300e --- /dev/null +++ b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/diary_edit_screen.dart @@ -0,0 +1,817 @@ +import 'bloc/diary_edit_bloc.dart'; +import 'models/diary_edit_model.dart'; +import 'package:flutter/material.dart'; +import 'package:eatvio_app/core/app_export.dart'; +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'; + +// ignore: must_be_immutable +class DiaryEditScreen extends StatelessWidget { + DiaryEditScreen({Key? key}) + : super( + key: key, + ); + + List dropdownItemList = [ + "Item One", + "Item Two", + "Item Three", + ]; + + List dropdownItemList1 = [ + "Item One", + "Item Two", + "Item Three", + ]; + + TextEditingController enterProductNameController = TextEditingController(); + + TextEditingController quantityController = TextEditingController(); + + List dropdownItemList2 = [ + "Item One", + "Item Two", + "Item Three", + ]; + + List dropdownItemList3 = [ + "Item One", + "Item Two", + "Item Three", + ]; + + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => + DiaryEditBloc(DiaryEditState(diaryEditModelObj: DiaryEditModel())) + ..add(DiaryEditInitialEvent()), + child: DiaryEditScreen()); + } + + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is DiaryEditInitialState) { + // Это начальное состояние, данные ещё не загружены. + return CircularProgressIndicator( + color: Colors.white, + backgroundColor: Colors.white, + ); + } else if (state is DiaryEditLoadedState) { + // Данные загружены, можно строить экран. + return _buildDiaryEditScreen(context, state); + } else if (state is DiaryEditErrorState) { + // Произошла ошибка при загрузке данных. + return Center(child: Text(state.errorMessage)); + } else { + // Другие состояния, если они есть. + return Container(); // Пустой контейнер для необработанных состояний. + } + }, + ); + } + + Widget _buildDiaryEditScreen( + BuildContext context, DiaryEditLoadedState state) { + mediaQueryData = MediaQuery.of(context); + return SafeArea( + child: Scaffold( + resizeToAvoidBottomInset: false, + body: SizedBox( + width: double.maxFinite, + child: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.only(bottom: 5.v), + child: Column( + 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) {}, + ), + ), + 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) {}, + ), + ), + SizedBox(height: 30.v), + _buildHeaderColumn(context), + SizedBox(height: 30.v), + _buildHeaderStack(context), + ], + ), + ), + ), + ), + ], + ), + ), + bottomNavigationBar: _buildEndDay(context), + ), + ); + } + + /// Section Widget + Widget _buildHeaderRow(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric(horizontal: 16.h), + padding: EdgeInsets.symmetric( + horizontal: 24.h, + vertical: 12.v, + ), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder12, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CustomImageView( + imagePath: ImageConstant.imgArrowLeft, + height: 2.v, + width: 20.h, + margin: EdgeInsets.only( + top: 19.v, + bottom: 17.v, + ), + ), + Padding( + padding: EdgeInsets.only(top: 1.v), + child: Column( + children: [ + Align( + alignment: Alignment.centerRight, + child: Text( + "10 день", + style: CustomTextStyles.titleMediumBlack, + ), + ), + SizedBox(height: 2.v), + Text( + "03-08-2023", + style: CustomTextStyles.bodyMediumBluegray800, + ), + ], + ), + ), + ], + ), + ); + } + + /// Section Widget + Widget _buildHeaderButton1(BuildContext context) { + return CustomOutlinedButton( + width: 73.h, + text: "14:52", + ); + } + + /// Section Widget + Widget _buildEnterProductName(BuildContext context) { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 10.h), + child: CustomTextFormField( + controller: enterProductNameController, + hintText: "Введите названия продукта", + ), + ); + } + + /// Section Widget + Widget _buildQuantity(BuildContext context) { + return CustomTextFormField( + width: 146.h, + controller: quantityController, + hintText: "Кол-во", + textInputAction: TextInputAction.done, + ); + } + + /// Section Widget + Widget _buildAddProduct(BuildContext context) { + return CustomOutlinedButton( + text: "Добавить продукт", + margin: EdgeInsets.symmetric(horizontal: 10.h), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + ); + } + + /// Section Widget + Widget _buildAddPhoto(BuildContext context) { + return CustomOutlinedButton( + width: 195.h, + text: "Добавить фото", + rightIcon: Container( + margin: EdgeInsets.only(left: 14.h), + child: CustomImageView( + imagePath: ImageConstant.imgVector, + height: 30.v, + width: 34.h, + ), + ), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + buttonTextStyle: theme.textTheme.bodyMedium!, + ); + } + + /// Section Widget + Widget _buildImageStack(BuildContext context) { + return SizedBox( + height: 790.v, + width: 374.h, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + Align( + alignment: Alignment.center, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 15.h), + padding: EdgeInsets.symmetric( + horizontal: 10.h, + vertical: 13.v, + ), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder12, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.h), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.only( + top: 11.v, + bottom: 7.v, + ), + child: Text( + "Время приема пищи", + style: CustomTextStyles.bodyMediumBlack900, + ), + ), + _buildHeaderButton1(context), + ], + ), + ), + SizedBox(height: 20.v), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.h), + child: CustomDropDown( + hintText: "Прием пищи", + items: dropdownItemList1, + contentPadding: EdgeInsets.symmetric( + horizontal: 15.h, + vertical: 9.v, + ), + onChanged: (value) {}, + ), + ), + SizedBox(height: 20.v), + _buildEnterProductName(context), + SizedBox(height: 20.v), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10.h), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildQuantity(context), + Padding( + padding: EdgeInsets.only(left: 10.h), + child: CustomDropDown( + width: 146.h, + hintText: "Порция", + items: dropdownItemList2, + contentPadding: EdgeInsets.symmetric( + horizontal: 15.h, + vertical: 9.v, + ), + onChanged: (value) {}, + ), + ), + ], + ), + ), + SizedBox(height: 30.v), + Container( + margin: EdgeInsets.symmetric(horizontal: 10.h), + padding: EdgeInsets.symmetric( + horizontal: 8.h, + vertical: 6.v, + ), + decoration: AppDecoration.fillGray.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder5, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: EdgeInsets.only( + left: 7.h, + top: 5.v, + ), + child: Text( + "Сырный суп", + style: CustomTextStyles.titleMedium16, + ), + ), + Padding( + padding: EdgeInsets.only( + left: 20.h, + top: 3.v, + bottom: 3.v, + ), + child: Text( + "400мл", + style: CustomTextStyles.titleMedium16, + ), + ), + Spacer(), + CustomImageView( + imagePath: ImageConstant.imgSearch, + height: 24.adaptSize, + width: 24.adaptSize, + ), + CustomImageView( + imagePath: ImageConstant.imgClose, + height: 28.adaptSize, + width: 28.adaptSize, + margin: EdgeInsets.only(left: 10.h), + ), + ], + ), + ), + SizedBox(height: 30.v), + _buildAddProduct(context), + SizedBox(height: 249.v), + _buildAddPhoto(context), + SizedBox(height: 29.v), + Text( + "Ваша сытость после приёма пищи", + style: CustomTextStyles.bodyMediumBlack900, + ), + SizedBox(height: 15.v), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + CustomImageView( + imagePath: ImageConstant.imgEdit, + height: 30.adaptSize, + width: 30.adaptSize, + ), + CustomImageView( + height: 13.v, + width: 243.h, + margin: EdgeInsets.only( + left: 10.h, + top: 9.v, + bottom: 8.v, + ), + ), + CustomImageView( + height: 30.adaptSize, + width: 30.adaptSize, + margin: EdgeInsets.only(left: 10.h), + ), + ], + ), + SizedBox(height: 7.v), + ], + ), + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: EdgeInsets.only(bottom: 342.v), + child: SizedBox( + width: 374.h, + child: Divider(), + ), + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: Container( + height: 203.v, + width: 303.h, + margin: EdgeInsets.only(bottom: 178.v), + child: Stack( + alignment: Alignment.topRight, + children: [ + CustomImageView( + height: 203.v, + width: 303.h, + radius: BorderRadius.circular( + 5.h, + ), + alignment: Alignment.center, + ), + Align( + alignment: Alignment.topRight, + child: Padding( + padding: EdgeInsets.only( + left: 265.h, + top: 10.v, + right: 10.h, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CustomIconButton( + height: 18.adaptSize, + width: 18.adaptSize, + padding: EdgeInsets.all(4.h), + alignment: Alignment.centerRight, + child: CustomImageView( + imagePath: ImageConstant.imgCloseBlueGray900, + ), + ), + SizedBox(height: 60.v), + CustomIconButton( + height: 28.adaptSize, + width: 28.adaptSize, + padding: EdgeInsets.all(9.h), + decoration: IconButtonStyleHelper.fillBlueA, + child: CustomImageView( + imagePath: ImageConstant.imageNotFound, + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + /// Section Widget + Widget _buildHeaderColumn(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric(horizontal: 16.h), + padding: EdgeInsets.symmetric( + horizontal: 10.h, + vertical: 16.v, + ), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder12, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 3.v), + Text( + "Ваш КБЖУ", + style: theme.textTheme.titleMedium, + ), + SizedBox(height: 8.v), + Text( + "От дневной суточной нормы", + style: CustomTextStyles.bodyMediumBluegray800, + ), + SizedBox(height: 19.v), + Align( + alignment: Alignment.centerRight, + child: Padding( + padding: EdgeInsets.only( + left: 30.h, + right: 12.h, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Container( + margin: EdgeInsets.only(top: 7.v), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder1, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + SizedBox(height: 101.v), + Container( + height: 47.v, + width: 12.h, + decoration: BoxDecoration( + color: theme.colorScheme.errorContainer, + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(1.h), + ), + ), + ), + ], + ), + ), + Spacer( + flex: 33, + ), + Container( + margin: EdgeInsets.only(top: 7.v), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder1, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 66.v), + Container( + height: 82.v, + width: 12.h, + decoration: BoxDecoration( + color: appTheme.lightGreenA700, + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(1.h), + ), + ), + ), + ], + ), + ), + Spacer( + flex: 33, + ), + Container( + margin: EdgeInsets.only(top: 7.v), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder1, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox(height: 14.v), + Container( + height: 134.v, + width: 12.h, + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.vertical( + bottom: Radius.circular(1.h), + ), + ), + ), + ], + ), + ), + Spacer( + flex: 33, + ), + Container( + margin: EdgeInsets.only(top: 7.v), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder1, + ), + child: Container( + height: 148.v, + width: 12.h, + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular( + 1.h, + ), + ), + ), + ), + Padding( + padding: EdgeInsets.only( + left: 6.h, + bottom: 128.v, + ), + child: Text( + "*", + style: theme.textTheme.titleLarge, + ), + ), + ], + ), + ), + ), + SizedBox(height: 8.v), + Padding( + padding: EdgeInsets.only(left: 4.h), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + "Калории", + style: theme.textTheme.titleSmall, + ), + Padding( + padding: EdgeInsets.only(left: 28.h), + child: Text( + "Белки", + style: theme.textTheme.titleSmall, + ), + ), + Spacer(), + Text( + "Жиры", + style: theme.textTheme.titleSmall, + ), + Padding( + padding: EdgeInsets.only(left: 25.h), + child: Text( + "Углеводы", + style: theme.textTheme.titleSmall, + ), + ), + ], + ), + ), + SizedBox(height: 2.v), + Padding( + padding: EdgeInsets.only( + left: 10.h, + right: 2.h, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "255 из 250Ккал", + style: theme.textTheme.bodySmall, + ), + Padding( + padding: EdgeInsets.only( + left: 25.h, + bottom: 11.v, + ), + child: Text( + "50 из 250 гр", + style: theme.textTheme.bodySmall, + ), + ), + Padding( + padding: EdgeInsets.only( + left: 19.h, + bottom: 11.v, + ), + child: Text( + "270 из 250 гр", + style: theme.textTheme.bodySmall, + ), + ), + Padding( + padding: EdgeInsets.only( + left: 16.h, + bottom: 11.v, + ), + child: Text( + "400 из 250 гр", + style: theme.textTheme.bodySmall, + ), + ), + ], + ), + ), + SizedBox(height: 19.v), + Text( + "*Превышенная суточная норма углеводов", + style: theme.textTheme.labelLarge, + ), + ], + ), + ); + } + + /// Section Widget + Widget _buildHeaderColumn1(BuildContext context) { + return Align( + alignment: Alignment.center, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 15.h), + padding: EdgeInsets.symmetric( + horizontal: 50.h, + vertical: 28.v, + ), + decoration: AppDecoration.outlinePrimary.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder12, + ), + child: SizedBox( + width: 240.h, + child: Text( + "Дополнительная информация для консультанта", + maxLines: 2, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: CustomTextStyles.bodyMediumBlack900, + ), + ), + ), + ); + } + + /// Section Widget + Widget _buildHeaderStack(BuildContext context) { + return SizedBox( + height: 235.v, + width: 374.h, + child: Stack( + alignment: Alignment.bottomCenter, + children: [ + _buildHeaderColumn1(context), + Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: EdgeInsets.only(bottom: 103.v), + child: SizedBox( + width: 374.h, + child: Divider(), + ), + ), + ), + Align( + alignment: Alignment.bottomCenter, + child: Container( + margin: EdgeInsets.only( + left: 35.h, + right: 35.h, + bottom: 20.v, + ), + padding: EdgeInsets.symmetric( + horizontal: 14.h, + vertical: 9.v, + ), + decoration: AppDecoration.outlineBlueGray.copyWith( + borderRadius: BorderRadiusStyle.roundedBorder5, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 63.v), + Container( + width: 245.h, + margin: EdgeInsets.only(right: 27.h), + child: Text( + "Введите дополнитльеную информацию для консультанта", + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: theme.textTheme.bodyLarge, + ), + ), + ], + ), + ), + ), + ], + ), + ); + } + + /// Section Widget + Widget _buildEndDay(BuildContext context) { + return CustomOutlinedButton( + text: "Закончить день", + margin: EdgeInsets.only( + left: 16.h, + right: 16.h, + bottom: 41.v, + ), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + ); + } +} diff --git a/lib/presentation/auth/auth_screen/diary/diary_edit_screen/models/diary_edit_model.dart b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/models/diary_edit_model.dart new file mode 100644 index 00000000..b2aaf181 --- /dev/null +++ b/lib/presentation/auth/auth_screen/diary/diary_edit_screen/models/diary_edit_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [k0_page], +/// and is typically used to hold data that is passed between different parts of the application. +class DiaryEditModel extends Equatable { + DiaryEditModel(); + + DiaryEditModel copyWith() { + return DiaryEditModel(); + } + + @override + List get props => []; +} diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index b83e7ff9..c754e47b 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -19,6 +19,7 @@ import 'package:eatvio_app/presentation/registration/app_navigation_screen/app_n import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart'; import 'package:eatvio_app/presentation/profile/my_profile_screen/my_profile_screen.dart'; import 'package:eatvio_app/presentation/profile/my_profile_screen/my_settings_screen.dart'; +import 'package:eatvio_app/presentation/diary/diary_edit_screen/diary_edit_screen.dart'; class AppRoutes { // REGISTRATION @@ -69,6 +70,8 @@ class AppRoutes { static const String mySettings = '/mySettings'; + static const String diaryEdit = '/diaryEdit'; + static Map get routes => { dateOfBirthScreen: DateOfBirthScreen.builder, cityOfLivingScreen: CityOfLivingScreen.builder, @@ -91,5 +94,6 @@ class AppRoutes { initialRoute: SplashScreen.builder, myProfile: MyProfileScreen.builder, mySettings: MySettingsScreen.builder, + diaryEdit: DiaryEditScreen.builder, }; }