From 64c25f11fea7d1d86aba9f22f8275aeedd827a4a Mon Sep 17 00:00:00 2001 From: maxxkim Date: Wed, 3 Apr 2024 14:03:06 +0300 Subject: [PATCH] feat(diary): Nutrition chart API methods implemented --- .../bloc/diary_edit_bloc.dart | 248 +++++++++++------- .../bloc/diary_edit_state.dart | 11 + .../diary_edit_screen/diary_edit_screen.dart | 16 +- .../bloc/my_profile_bloc.dart | 2 +- lib/widgets/custom_expandable_list.dart | 4 +- test/diary_test.dart | 2 + 6 files changed, 170 insertions(+), 113 deletions(-) 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 82bafe8..d3d9d29 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 @@ -70,70 +70,97 @@ class DiaryEditBloc extends Bloc { if (diary is Map) { final String diaryDate = diary['date'] ?? DateTime.now().toString(); - // Продолжайте обработку данных дневника - if (state is DiaryEditLoadedState) { - // Если текущее состояние уже загружено, обновляем его - var currentState = state as DiaryEditLoadedState; - emit((currentState).copyWith( - currentMeal: currentState.currentMeal, - wakeupExpanded: currentState.wakeupExpanded, - moodExpanded: currentState.moodExpanded, - moderationExpanded: currentState.moderationExpanded, - token: currentState.token, - meals: currentState.meals, - portions: currentState.portions, - photos: currentState.photos, - wakeupController: currentState.wakeupController, - retireController: currentState.retireController, - commentController: currentState.commentController, - mealTimeController: currentState.mealTimeController, - productNameController: currentState.productNameController, - caloriesController: currentState.caloriesController, - proteinsController: currentState.proteinsController, - fatsController: currentState.fatsController, - carbsController: currentState.carbsController, - selectedSatiety: currentState.selectedSatiety, - selectedMood: currentState.selectedMood, - diaryDate: currentState.diaryDate, - diaryId: currentState.diaryId, - productQuantityController: - currentState.productQuantityController, - autocompleteList: currentState.autocompleteList, - diaryEditModelObj: currentState.diaryEditModelObj)); + final responseChart = await http.get( + Uri.parse(dotenv.env['SERVER_ROOT']! + + '/diary/$diaryId/dailyNutritionData/'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $token', + }, + ); + if (responseChart.statusCode == 200) { + final recommendedChartValues = jsonDecode( + responseChart.body)['dailyNutritionRecommendation']; + final consumedChartValues = + jsonDecode(responseChart.body)['dailyNutritionIntake']; + + if (state is DiaryEditLoadedState) { + // Если текущее состояние уже загружено, обновляем его + var currentState = state as DiaryEditLoadedState; + emit((currentState).copyWith( + currentMeal: currentState.currentMeal, + wakeupExpanded: currentState.wakeupExpanded, + moodExpanded: currentState.moodExpanded, + moderationExpanded: currentState.moderationExpanded, + token: currentState.token, + meals: currentState.meals, + portions: currentState.portions, + photos: currentState.photos, + wakeupController: currentState.wakeupController, + retireController: currentState.retireController, + commentController: currentState.commentController, + mealTimeController: currentState.mealTimeController, + productNameController: currentState.productNameController, + caloriesController: currentState.caloriesController, + proteinsController: currentState.proteinsController, + fatsController: currentState.fatsController, + carbsController: currentState.carbsController, + selectedSatiety: currentState.selectedSatiety, + selectedMood: currentState.selectedMood, + diaryDate: currentState.diaryDate, + diaryId: currentState.diaryId, + productQuantityController: + currentState.productQuantityController, + recommendedChartValues: + currentState.recommendedChartValues, + consumedChartValues: currentState.consumedChartValues, + autocompleteList: currentState.autocompleteList, + diaryEditModelObj: currentState.diaryEditModelObj)); + } else { + // Если текущее состояние - начальное, создаем новое загруженное состояние + emit(DiaryEditLoadedState( + currentMeal: SelectionPopupModel( + id: 1, title: "Прием пищи 1", isSelected: true), + portionController: SelectionPopupModel( + id: 0, title: "порций", isSelected: true), + wakeupExpanded: true, + moodExpanded: true, + moderationExpanded: false, + token: token, + recommendedChartValues: recommendedChartValues.values + .map((value) => value as int) + .toList(), + consumedChartValues: consumedChartValues.values + .map((value) => value as int) + .toList() ?? + [0, 0, 0, 0], + meals: diary['meals'], + portions: diary['meals'][0]['portions'], + photos: diary['meals'][0]['photos'], + wakeupController: toTime(diary['wakeup'] ?? "09:00"), + retireController: toTime(diary['retire'] ?? "23:00"), + mealTimeController: + toTime(diary['meals'][0]['time'] ?? "10:00"), + selectedSatiety: diary['meals'][0]['satiety'], + selectedMood: diary['meals'][0]['mood'], + commentController: + TextEditingController(text: diary['comment']), + productNameController: TextEditingController(), + productQuantityController: TextEditingController(), + caloriesController: TextEditingController(), + proteinsController: TextEditingController(), + fatsController: TextEditingController(), + carbsController: TextEditingController(), + diaryId: diaryId, + diaryDate: diaryDate, + autocompleteList: [], + diaryEditModelObj: state.diaryEditModelObj?.copyWith( + mealList: fillMealList(), + portionList: fillPortions()))); + } } else { - // Если текущее состояние - начальное, создаем новое загруженное состояние - emit(DiaryEditLoadedState( - currentMeal: SelectionPopupModel( - id: 1, title: "Прием пищи 1", isSelected: true), - portionController: SelectionPopupModel( - id: 0, title: "порций", isSelected: true), - wakeupExpanded: true, - moodExpanded: true, - moderationExpanded: false, - token: token, - meals: diary['meals'], - portions: diary['meals'][0]['portions'], - photos: diary['meals'][0]['photos'], - wakeupController: toTime(diary['wakeup'] ?? "09:00"), - retireController: toTime(diary['retire'] ?? "23:00"), - mealTimeController: - toTime(diary['meals'][0]['time'] ?? "10:00"), - selectedSatiety: diary['meals'][0]['satiety'], - selectedMood: diary['meals'][0]['mood'], - commentController: - TextEditingController(text: diary['comment']), - productNameController: TextEditingController(), - productQuantityController: TextEditingController(), - caloriesController: TextEditingController(), - proteinsController: TextEditingController(), - fatsController: TextEditingController(), - carbsController: TextEditingController(), - diaryId: diaryId, - diaryDate: diaryDate, - autocompleteList: [], - diaryEditModelObj: state.diaryEditModelObj?.copyWith( - mealList: fillMealList(), - portionList: fillPortions()))); + emit(DiaryEditErrorState( + 'Ошибка при декодировании данных КБЖУ')); } } else { // Ошибка при декодировании JSON @@ -191,44 +218,65 @@ class DiaryEditBloc extends Bloc { if (diary is Map) { final String diaryDate = diary['date'] ?? DateTime.now().toString(); - // Продолжайте обработку данных дневника - // Если текущее состояние - начальное, создаем новое загруженное состояние - try { - await Future(() => emit(DiaryEditLoadedState( - currentMeal: SelectionPopupModel( - id: 1, title: "Прием пищи 1", isSelected: true), - portionController: SelectionPopupModel( - id: 0, title: "порций", isSelected: true), - wakeupExpanded: true, - moodExpanded: true, - moderationExpanded: false, - token: token, - meals: diary['meals'], - portions: diary['meals'][0]['portions'], - photos: diary['meals'][0]['photos'], - wakeupController: toTime(diary['wakeup'] ?? "09:00"), - retireController: toTime(diary['retire'] ?? "23:00"), - mealTimeController: - toTime(diary['meals'][0]['time'] ?? "10:00"), - selectedSatiety: diary['meals'][0]['satiety'], - selectedMood: diary['meals'][0]['mood'], - commentController: - TextEditingController(text: diary['comment']), - productNameController: TextEditingController(), - productQuantityController: TextEditingController(), - caloriesController: TextEditingController(), - proteinsController: TextEditingController(), - fatsController: TextEditingController(), - carbsController: TextEditingController(), - diaryId: diaryId, - diaryDate: diaryDate, - autocompleteList: [], - diaryEditModelObj: state.diaryEditModelObj?.copyWith( - mealList: fillMealList(), portionList: fillPortions())))); + final responseChart = await http.get( + Uri.parse(dotenv.env['SERVER_ROOT']! + + '/diary/$diaryId/dailyNutritionData/'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $token', + }, + ); + if (responseChart.statusCode == 200) { + final recommendedChartValues = jsonDecode( + responseChart.body)['dailyNutritionRecommendation']; + final consumedChartValues = + jsonDecode(responseChart.body)['dailyNutritionIntake']; + try { + await Future(() => emit(DiaryEditLoadedState( + currentMeal: SelectionPopupModel( + id: 1, title: "Прием пищи 1", isSelected: true), + portionController: SelectionPopupModel( + id: 0, title: "порций", isSelected: true), + wakeupExpanded: true, + moodExpanded: true, + moderationExpanded: false, + token: token, + recommendedChartValues: recommendedChartValues.values + .map((value) => value as int) + .toList(), + consumedChartValues: consumedChartValues.values + .map((value) => value as int) + .toList(), + meals: diary['meals'], + portions: diary['meals'][0]['portions'], + photos: diary['meals'][0]['photos'], + wakeupController: toTime(diary['wakeup'] ?? "09:00"), + retireController: toTime(diary['retire'] ?? "23:00"), + mealTimeController: + toTime(diary['meals'][0]['time'] ?? "10:00"), + selectedSatiety: diary['meals'][0]['satiety'], + selectedMood: diary['meals'][0]['mood'], + commentController: + TextEditingController(text: diary['comment']), + productNameController: TextEditingController(), + productQuantityController: TextEditingController(), + caloriesController: TextEditingController(), + proteinsController: TextEditingController(), + fatsController: TextEditingController(), + carbsController: TextEditingController(), + diaryId: diaryId, + diaryDate: diaryDate, + autocompleteList: [], + diaryEditModelObj: state.diaryEditModelObj?.copyWith( + mealList: fillMealList(), + portionList: fillPortions())))); - print("Updated"); - } catch (e) { - print("Ошибка при создании нового состояния $e"); + print("Updated"); + } catch (e) { + print("Ошибка при создании нового состояния $e"); + } + } else { + emit(DiaryEditErrorState('Ошибка при декодировании данных КБЖУ')); } } else { emit(DiaryEditErrorState( 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 470b326..58c6fd2 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 @@ -39,6 +39,8 @@ class DiaryEditLoadedState extends DiaryEditState { this.fatsController, this.proteinsController, this.carbsController, + required this.recommendedChartValues, + required this.consumedChartValues, required this.diaryId, required this.selectedSatiety, required this.moderationExpanded, @@ -53,6 +55,8 @@ class DiaryEditLoadedState extends DiaryEditState { List? portions; List? photos; List? autocompleteList; + List recommendedChartValues; + List consumedChartValues; SelectionPopupModel? currentMeal; SelectionPopupModel? portionController; TimeOfDay? wakeupController; @@ -79,6 +83,8 @@ class DiaryEditLoadedState extends DiaryEditState { meals, portions, photos, + recommendedChartValues, + consumedChartValues, autocompleteList, wakeupController, retireController, @@ -105,6 +111,8 @@ class DiaryEditLoadedState extends DiaryEditState { SelectionPopupModel? portionController, String? diaryDate, String? token, + List? recommendedChartValues, + List? consumedChartValues, List? meals, List? portions, List? photos, @@ -133,6 +141,9 @@ class DiaryEditLoadedState extends DiaryEditState { meals: meals ?? this.meals, autocompleteList: autocompleteList ?? this.autocompleteList, portions: portions ?? this.portions, + recommendedChartValues: + recommendedChartValues ?? this.recommendedChartValues, + consumedChartValues: consumedChartValues ?? this.consumedChartValues, wakeupController: wakeupController ?? this.wakeupController, retireController: retireController ?? this.retireController, mealTimeController: mealTimeController ?? this.mealTimeController, 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 52dffb5..e2bdbee 100644 --- a/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart +++ b/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart @@ -79,7 +79,7 @@ class DiaryEditScreen extends StatelessWidget { SizedBox(height: 20.v), _buildMood(context, state), SizedBox(height: 30.v), - _buildNutritionChart(context), + _buildNutritionChart(context, state), SizedBox(height: 30.v), _buildComment(context, state), ], @@ -700,14 +700,10 @@ class DiaryEditScreen extends StatelessWidget { }; } - _buildNutritionChart(BuildContext context) { - final List recommendedValues = [ - 2000, - 70, - 50, - 300 - ]; // Рекомендуемые значения: калории, жиры, белки, углеводы - final List consumedValues = [1800, 60, 40, 250]; // + _buildNutritionChart(BuildContext context, DiaryEditLoadedState state) { + final List recommendedValues = state + .recommendedChartValues; // Рекомендуемые значения: калории, жиры, белки, углеводы + final List consumedValues = state.consumedChartValues; // return Container( margin: EdgeInsets.symmetric(horizontal: 16.h), padding: EdgeInsets.symmetric( @@ -1210,7 +1206,7 @@ class DiaryEditScreen extends StatelessWidget { } bool checkConsumedValues( - List recommendedValues, List consumedValues) { + List recommendedValues, List consumedValues) { for (int i = 0; i < recommendedValues.length; i++) { if (consumedValues[i] > recommendedValues[i]) { // Если хотя бы одно потребленное значение превышает рекомендованное diff --git a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart index dad1ce9..474e470 100644 --- a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart +++ b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart @@ -4,7 +4,7 @@ import '/core/app_export.dart'; import 'package:eatvio_app/presentation/profile/my_profile_screen/models/my_profile_model.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; -import 'package:hive/hive.dart'; +//import 'package:hive/hive.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; part 'my_profile_event.dart'; diff --git a/lib/widgets/custom_expandable_list.dart b/lib/widgets/custom_expandable_list.dart index 786ed6b..bf29976 100644 --- a/lib/widgets/custom_expandable_list.dart +++ b/lib/widgets/custom_expandable_list.dart @@ -81,7 +81,7 @@ class _ExpandableListState extends State { } _buildForm(BuildContext context, MyProfileLoadedState state) { - List cities = [ + /*List cities = [ 'Москва', 'Санкт-Петербург', 'Новосибирск', @@ -115,7 +115,7 @@ class _ExpandableListState extends State { ]; List countries = [ 'Россия', - ]; + ];*/ final digitsOnly = FilteringTextInputFormatter.digitsOnly; return Column(children: [ TextField( diff --git a/test/diary_test.dart b/test/diary_test.dart index 722c457..b539eb3 100644 --- a/test/diary_test.dart +++ b/test/diary_test.dart @@ -27,6 +27,8 @@ void main() { portions: [], wakeupExpanded: false, moderationExpanded: false, + recommendedChartValues: [10, 10, 10, 10], + consumedChartValues: [1, 2, 3, 4], moodExpanded: false); await tester.pumpWidget(