diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 198e6f7b..668075b4 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -410,6 +410,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.eatvioapp.app 1747050044"; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; @@ -560,6 +561,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.eatvioapp.app 1747050044"; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -598,6 +600,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.eatvioapp.app; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = "match AppStore com.eatvioapp.app 1747050044"; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; VERSIONING_SYSTEM = "apple-generic"; diff --git a/lib/core/utils/date_time_utils.dart b/lib/core/utils/date_time_utils.dart index 701fa80e..9b3085c1 100644 --- a/lib/core/utils/date_time_utils.dart +++ b/lib/core/utils/date_time_utils.dart @@ -46,6 +46,17 @@ extension DateTimeExtension on DateTime { final now = DateTime.now(); return now.year == localDate.year && now.month == localDate.month && now.day == localDate.day; } + + String toISO8601WithTimeZoneOffset() { + final formatter = DateFormat("yyyy-MM-ddTHH:mm:ss"); + final formatted = formatter.format(this); + final offset = timeZoneOffset; + final hours = offset.inHours.abs().toString().padLeft(2, '0'); + final minutes = (offset.inMinutes.abs() % 60).toString().padLeft(2, '0'); + final sign = offset.isNegative ? '-' : '+'; + + return "$formatted$sign$hours:$minutes"; + } } String calculateDifference(DateTime dateTime, [String? format]) { diff --git a/lib/features/diary/entities/diary_day_entity.dart b/lib/features/diary/entities/diary_day_entity.dart new file mode 100644 index 00000000..65f45570 --- /dev/null +++ b/lib/features/diary/entities/diary_day_entity.dart @@ -0,0 +1,22 @@ +import 'package:eatvio_app/features/diary/models/diary_day_model.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'diary_day_entity.freezed.dart'; + +@freezed +abstract class DiaryDayEntity with _$DiaryDayEntity { + factory DiaryDayEntity({ + @JsonKey(name: "id") required int id, + @JsonKey(name: "date") required String date, + @JsonKey(name: "wakeup") String? wakeup, + @JsonKey(name: "retire") String? retire, + @JsonKey(name: "closed") required int closed, + @JsonKey(name: "comment") required String comment, + @JsonKey(name: "state") required TypeOfDiaryModel typeOfDiary, + @JsonKey(name: "meals") required List meals, + @JsonKey(name: "chosen_plan_id") required int? chosenPlanId, + @JsonKey(name: "day_of_chosen_diet") required int? dayOfChosenDiet, + @JsonKey(name: "chosen_diet", fromJson: parseDiet) required DiaryDietModel? diet, + }) = _DiaryDayEntity; + +} diff --git a/lib/features/diary/entities/diary_future_diet_day_entity.dart b/lib/features/diary/entities/diary_future_diet_day_entity.dart new file mode 100644 index 00000000..4247cecf --- /dev/null +++ b/lib/features/diary/entities/diary_future_diet_day_entity.dart @@ -0,0 +1,18 @@ +import 'package:eatvio_app/features/diary/models/diary_day_model.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'diary_future_diet_day_entity.freezed.dart'; + + + +@freezed +abstract class DiaryFutureDietDayEntity with _$DiaryFutureDietDayEntity { + const factory DiaryFutureDietDayEntity({ + required String date, + required TypeOfDiaryModel typeOfDiary, + required List meals, + required DiaryDietModel? diet, + required int? dayOfChosenDiet, + }) = _DiaryFutureDietDayEntity; + +} diff --git a/lib/features/diary/models/create_day_model.dart b/lib/features/diary/models/create_day_model.dart new file mode 100644 index 00000000..9d3eabbd --- /dev/null +++ b/lib/features/diary/models/create_day_model.dart @@ -0,0 +1,11 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'create_day_model.freezed.dart'; +part 'create_day_model.g.dart'; + +@freezed +abstract class CreateDayModel with _$CreateDayModel { + factory CreateDayModel({required String day}) = _CreateDayModel; + + factory CreateDayModel.fromJson(Map json) => _$CreateDayModelFromJson(json); +} diff --git a/lib/features/diary/models/diary_day_model.dart b/lib/features/diary/models/diary_day_model.dart index e1ad4572..19099ded 100644 --- a/lib/features/diary/models/diary_day_model.dart +++ b/lib/features/diary/models/diary_day_model.dart @@ -1,4 +1,6 @@ import 'package:eatvio_app/features/consultations/models/consultation_model.dart'; +import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart'; +import 'package:eatvio_app/features/diary/entities/diary_future_diet_day_entity.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'diary_day_model.freezed.dart'; @@ -30,7 +32,7 @@ abstract class DiaryDayWrapperModel with _$DiaryDayWrapperModel { @freezed abstract class DiaryDayModel with _$DiaryDayModel { const factory DiaryDayModel({ - @JsonKey(name: "id") required int id, + @JsonKey(name: "id") required int? id, @JsonKey(name: "date") required String date, @JsonKey(name: "wakeup") String? wakeup, @JsonKey(name: "retire") String? retire, @@ -40,26 +42,43 @@ abstract class DiaryDayModel with _$DiaryDayModel { @JsonKey(name: "meals") required List meals, @JsonKey(name: "chosen_plan_id") required int? chosenPlanId, @JsonKey(name: "day_of_chosen_diet") required int? dayOfChosenDiet, - @JsonKey(name: "chosen_diet", fromJson: _parseDiet) required DiaryDietModel? diet, + @JsonKey(name: "chosen_diet", fromJson: parseDiet) required DiaryDietModel? diet, }) = _DiaryDayModel; - + const DiaryDayModel._(); factory DiaryDayModel.fromJson(Map json) => _$DiaryDayModelFromJson(json); + + DiaryDayEntity? toEntity() { + if (id == null) { + return null; + } + return DiaryDayEntity( + id: id!, + date: date, + closed: closed, + comment: comment, + typeOfDiary: typeOfDiary, + meals: meals, + chosenPlanId: chosenPlanId, + dayOfChosenDiet: dayOfChosenDiet, + diet: diet, + ); + } + + DiaryFutureDietDayEntity toDiaryFutureDayEntity() { + + return DiaryFutureDietDayEntity( + date: date, + typeOfDiary: typeOfDiary, + meals: meals, + dayOfChosenDiet: dayOfChosenDiet, + diet: diet, + ); + } } -@freezed -abstract class DiaryFutureDietDayModel with _$DiaryFutureDietDayModel { - const factory DiaryFutureDietDayModel({ - @JsonKey(name: "date") required String date, - @JsonKey(name: "state", fromJson: _parseDayTypeForFutureDay) required TypeOfDiaryModel typeOfDiary, - @JsonKey(name: "meals") required List meals, - @JsonKey(name: "chosen_diet", fromJson: _parseDiet) required DiaryDietModel? diet, - @JsonKey(name: "day_of_chosen_diet") required int? dayOfChosenDiet, - }) = _DiaryFutureDietDayModel; - factory DiaryFutureDietDayModel.fromJson(Map json) => _$DiaryFutureDietDayModelFromJson(json); -} -DiaryDietModel? _parseDiet(dynamic json) { +DiaryDietModel? parseDiet(dynamic json) { if (json == null) return null; return DiaryDietModel.fromJson(json['diet']); } @@ -71,10 +90,6 @@ abstract class DiaryDietModel with _$DiaryDietModel { factory DiaryDietModel.fromJson(Map json) => _$DiaryDietModelFromJson(json); } -TypeOfDiaryModel _parseDayTypeForFutureDay(dynamic json) { - return TypeOfDiaryModel(hasChosenDiet: json['has_chosen_diet'] as bool, hasChosenPlan: json['has_chosen_plan'] as bool, diaryState: DiaryStateEnum.init); -} - @freezed abstract class MealModel with _$MealModel { const factory MealModel({ @@ -141,7 +156,7 @@ abstract class TypeOfDiaryModel with _$TypeOfDiaryModel { const factory TypeOfDiaryModel({ @JsonKey(name: "has_chosen_diet") required bool hasChosenDiet, @JsonKey(name: "has_chosen_plan") required bool hasChosenPlan, - @JsonKey(name: "last_state") required DiaryStateEnum diaryState, + @JsonKey(name: "last_state") required DiaryStateEnum? diaryState, }) = _TypeOfDiaryModel; factory TypeOfDiaryModel.fromJson(Map json) => _$TypeOfDiaryModelFromJson(json); diff --git a/lib/features/diary/models/get_day_model.dart b/lib/features/diary/models/get_day_model.dart new file mode 100644 index 00000000..bf9d285d --- /dev/null +++ b/lib/features/diary/models/get_day_model.dart @@ -0,0 +1,11 @@ +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'get_day_model.freezed.dart'; +part 'get_day_model.g.dart'; + +@freezed +abstract class GetDayModel with _$GetDayModel { + factory GetDayModel({required String day}) = _GetDayModel; + + factory GetDayModel.fromJson(Map json) => _$GetDayModelFromJson(json); +} diff --git a/lib/features/diary/presentation/bloc/diary_cubit.dart b/lib/features/diary/presentation/bloc/diary_cubit.dart index 6e6f8891..644837ac 100644 --- a/lib/features/diary/presentation/bloc/diary_cubit.dart +++ b/lib/features/diary/presentation/bloc/diary_cubit.dart @@ -1,10 +1,13 @@ import 'dart:developer'; import 'dart:io'; +import 'package:dio/dio.dart'; import 'package:eatvio_app/core/image_compressing/image_compress_utility.dart'; import 'package:eatvio_app/core/utils/date_time_utils.dart'; import 'package:eatvio_app/features/chat/repositories/chat_repository.dart'; import 'package:eatvio_app/features/consultations/models/consultation_model.dart'; +import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart'; +import 'package:eatvio_app/features/diary/entities/diary_future_diet_day_entity.dart'; import 'package:eatvio_app/features/diary/models/consultant_review_model.dart'; import 'package:eatvio_app/features/diary/models/diary_day_model.dart'; import 'package:eatvio_app/features/diary/models/nutrition_model.dart'; @@ -39,20 +42,50 @@ class DiaryCubit extends Cubit { today = DateTime.now(); selectedDay = today; diaryRepository.forceFetchStream.listen((_) { - fetchDiary(true, diaryId); + fetchDiaryV2(needLoading: true, diaryId: diaryId); }); } String comment = ''; - Future setSelectedDay(DateTime day, {bool? forDietOnly}) async { + Future setSelectedDay(DateTime day, {bool? forDietOnly}) async { selectedDay = day; if (forDietOnly ?? false) { - final result = await fetchDiaryForDietOnly(); + final result = await fetchDiaryV2(); return result; } - await fetchDiary(true); - return null; + await fetchDiaryV2(needLoading: true); + return true; + } + + Future fetchDiaryV2({bool needLoading = false, int? diaryId, int? currentDay}) async { + final (diaryDay, error) = await qwe(); + if (error != null) { + if (error == DiaryFetchingErrors.canNotCreateFutureDays) { + return false; + } + emit(DiaryState.error(errorMessage: error.toString())); + } + + if (diaryDay != null) { + final diaryEntity = diaryDay.toEntity(); + if (diaryEntity != null) { + setDiary(diaryDay: diaryEntity); + return true; + } + setDiaryForDietOnly(diaryDay.toDiaryFutureDayEntity()); + } + return true; + } + + Future<(DiaryDayModel?, DiaryFetchingErrors?)> qwe() async { + try { + final diaryDay = await diaryRepository.getDiaryDayV2(day: selectedDay.toISO8601WithTimeZoneOffset()); + } on DioException catch (e) { + + } + + return (null, null); } void setSelectedMeal(int meal) { @@ -65,9 +98,7 @@ class DiaryCubit extends Cubit { } } - Future fetchDiaryForDietOnly() async { - final stringDate = selectedDay.format('yyyy-MM-dd'); - final diaryDay = await diaryRepository.getDiaryByDateForDietOnly(stringDate); + Future setDiaryForDietOnly(DiaryFutureDietDayEntity diaryDay) async { if (!diaryDay.typeOfDiary.hasChosenDiet) { return false; } @@ -146,13 +177,9 @@ class DiaryCubit extends Cubit { return false; } - Future fetchDiary([bool needLoading = false, int? diaryId, int? currentDay]) async { + Future setDiary({int? diaryId, int? currentDay, required DiaryDayEntity diaryDay}) async { this.diaryId ??= diaryId; final isConsultantView = this.diaryId != null; - if (needLoading) { - emit(const DiaryState.loading()); - selectedMeal = 1; - } try { final DiaryDayModel diaryDay; bool isMoodEnabled = false; @@ -174,14 +201,14 @@ class DiaryCubit extends Cubit { final chosenPlanModel = await chatRepository.getChosenPlan(id: diaryDay.chosenPlanId!); if (!isConsultantView && (diaryDay.typeOfDiary.diaryState == DiaryStateEnum.lastDayCommented || diaryDay.typeOfDiary.diaryState == DiaryStateEnum.commented)) { - await diaryRepository.viewCommentOfDiaryDayByConsultant(diaryId: diaryDay.id); + await diaryRepository.viewCommentOfDiaryDayByConsultant(diaryId: diaryDay.id!); } - consultantReview = await diaryRepository.getDiaryComments(planId: diaryDay.chosenPlanId!, diaryId: diaryDay.id); + consultantReview = await diaryRepository.getDiaryComments(planId: diaryDay.chosenPlanId!, diaryId: diaryDay.id!); planDuration = chosenPlanModel.plan.duration; planName = chosenPlanModel.plan.name; currentPlanDay = consultantReview.currentPlanDay; } - final nutrition = await getNutrition(diaryDay.id); + final nutrition = await getNutrition(diaryDay.id!); final isDiaryFinished = diaryDay.typeOfDiary.diaryState == DiaryStateEnum.finished || diaryDay.typeOfDiary.diaryState == DiaryStateEnum.lastDayFinished; @@ -191,7 +218,7 @@ class DiaryCubit extends Cubit { diaryDay.typeOfDiary.diaryState == DiaryStateEnum.reviewedByUser; emit( DiaryState.loaded( - diary: diaryDay, + diary: diaryDay.toEntity()!, nutrition: nutrition, selectedDay: selectedDay, selectedMeal: selectedMeal, @@ -214,7 +241,7 @@ class DiaryCubit extends Cubit { Future finishDiaryDay({required int diaryId, required String wakeUp, required String retire}) async { await diaryRepository.finishDiaryDay(diaryId: diaryId, wakeUp: wakeUp, retire: retire, comment: comment.isEmpty ? null : comment); - await fetchDiary(); + await fetchDiaryV2(); } Future getNutrition(int index) async { @@ -238,7 +265,7 @@ class DiaryCubit extends Cubit { quantity: quantity, productNutritionalValueId: productNutritionalValueId, ); - await fetchDiary(); + await fetchDiaryV2(); } Future updateProductInMeal({ @@ -272,27 +299,27 @@ class DiaryCubit extends Cubit { portionState: portionState, ); } - await fetchDiary(); + await fetchDiaryV2(); } Future markEaten({required int diaryId, required int mealId, required int portionId}) async { await diaryRepository.markEaten(diaryId: diaryId, mealId: mealId, portionId: portionId); - await fetchDiary(); + await fetchDiaryV2(); } Future unmarkEaten({required int diaryId, required int mealId, required int portionId}) async { await diaryRepository.unmarkEaten(diaryId: diaryId, mealId: mealId, portionId: portionId); - await fetchDiary(); + await fetchDiaryV2(); } Future restore({required int diaryId, required int mealId, required int portionId}) async { await diaryRepository.restore(diaryId: diaryId, mealId: mealId, portionId: portionId); - await fetchDiary(); + await fetchDiaryV2(); } Future deleteProductFromMeal({required int diaryId, required int mealId, required int portionId}) async { await diaryRepository.deleteProductFromMeal(diaryId: diaryId, mealId: mealId, portionId: portionId); - await fetchDiary(); + await fetchDiaryV2(); } Future> getGlossaryListByQuery(String query) async { @@ -301,12 +328,12 @@ class DiaryCubit extends Cubit { Future uploadPhotos({required List files, required int diaryId}) async { await diaryRepository.uploadPhotos(files: await ImageCompressUtility.compressFilesList(files), diaryId: diaryId, mealId: selectedMeal); - await fetchDiary(); + await fetchDiaryV2(); } Future deletePhoto({required DiaryPhotoModel photo, required int diaryId}) async { await diaryRepository.deletePhoto(photo: photo, diaryId: diaryId, mealId: selectedMeal); - await fetchDiary(); + await fetchDiaryV2(); } Future sendProductToModeration({ @@ -326,30 +353,34 @@ class DiaryCubit extends Cubit { Future fillTime({required int diaryId, required String time}) async { await diaryRepository.fillTime(diaryId: diaryId, mealId: selectedMeal, time: time); - await fetchDiary(); + await fetchDiaryV2(); } Future fillWakeup({required int diaryId, required String time}) async { await diaryRepository.fillWakeup(diaryId: diaryId, time: time); - await fetchDiary(); + await fetchDiaryV2(); } Future fillRetire({required int diaryId, required String time}) async { await diaryRepository.fillRetire(diaryId: diaryId, time: time); - await fetchDiary(); + await fetchDiaryV2(); } Future fillSatiety({required int diaryId, required int satiety}) async { await diaryRepository.fillSatiety(diaryId: diaryId, mealId: selectedMeal, satiety: satiety); - await fetchDiary(); + await fetchDiaryV2(); } Future fillMood({required int diaryId, required int mood}) async { await diaryRepository.fillMood(diaryId: diaryId, mealId: selectedMeal, mood: mood); - await fetchDiary(); + await fetchDiaryV2(); } void fillComment(String comment) { this.comment = comment; } + + } + +enum DiaryFetchingErrors { canNotCreateFutureDays, dayAlreadyExists } diff --git a/lib/features/diary/presentation/bloc/diary_state.dart b/lib/features/diary/presentation/bloc/diary_state.dart index 4779e2ea..771ebb31 100644 --- a/lib/features/diary/presentation/bloc/diary_state.dart +++ b/lib/features/diary/presentation/bloc/diary_state.dart @@ -1,3 +1,5 @@ +import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart'; +import 'package:eatvio_app/features/diary/entities/diary_future_diet_day_entity.dart'; import 'package:eatvio_app/features/diary/models/consultant_review_model.dart'; import 'package:eatvio_app/features/diary/models/diary_day_model.dart'; import 'package:eatvio_app/features/diary/models/nutrition_model.dart'; @@ -11,12 +13,10 @@ abstract class DiaryState with _$DiaryState { const factory DiaryState.loading() = DiaryStateLoading; - const factory DiaryState.error({ - required String errorMessage, - }) = DiaryStateError; + const factory DiaryState.error({required String errorMessage}) = DiaryStateError; const factory DiaryState.loaded({ - required DiaryDayModel diary, + required DiaryDayEntity diary, required NutritionDataModel nutrition, required DateTime selectedDay, required int selectedMeal, @@ -32,9 +32,6 @@ abstract class DiaryState with _$DiaryState { @Default(false) bool isLoadingAddingProductInMeal, }) = DiaryStateLoaded; - const factory DiaryState.loadedTomorrowWithDiet({ - required DiaryFutureDietDayModel diary, - required DateTime selectedDay, - required int selectedMeal, - }) = DiaryStateLoadedTomorrowWithDiet; + const factory DiaryState.loadedTomorrowWithDiet({required DiaryFutureDietDayEntity diary, required DateTime selectedDay, required int selectedMeal}) = + DiaryStateLoadedTomorrowWithDiet; } diff --git a/lib/features/diary/presentation/pages/diary_screen.dart b/lib/features/diary/presentation/pages/diary_screen.dart index fb1987ef..4ec74e16 100644 --- a/lib/features/diary/presentation/pages/diary_screen.dart +++ b/lib/features/diary/presentation/pages/diary_screen.dart @@ -35,19 +35,12 @@ class DiaryScreen extends StatelessWidget { class UserDiaryScreen extends StatelessWidget { static const path = '/user-diary-screen'; static const name = 'userDiaryScreen'; - const UserDiaryScreen({ - super.key, - required this.diaryId, - required this.currentPlanDay, - }); + const UserDiaryScreen({super.key, required this.diaryId, required this.currentPlanDay}); final int diaryId; final int currentPlanDay; @override Widget build(BuildContext context) { - return DiaryScreenContent( - diaryId: diaryId, - currentPlanDay: currentPlanDay, - ); + return DiaryScreenContent(diaryId: diaryId, currentPlanDay: currentPlanDay); } } @@ -60,12 +53,8 @@ class DiaryScreenContent extends StatelessWidget { final s = S.of(context); return MultiBlocProvider( providers: [ - BlocProvider( - create: (BuildContext context) => sl()..fetchDiary(true, diaryId, currentPlanDay), - ), - BlocProvider( - create: (context) => sl(), - ), + BlocProvider(create: (BuildContext context) => sl()..fetchDiaryV2(needLoading: true, diaryId: diaryId, currentDay: currentPlanDay)), + BlocProvider(create: (context) => sl()), ], child: BlocBuilder( builder: (BuildContext context, DiaryState state) { @@ -73,17 +62,13 @@ class DiaryScreenContent extends StatelessWidget { log(state.diary.id.toString()); } if (state is DiaryStateError) { - return Scaffold( - body: DataErrorWidget(onReload: () => context.read().fetchDiary(false, diaryId)), - ); + return Scaffold(body: DataErrorWidget(onReload: () => context.read().fetchDiaryV2(needLoading: false, diaryId: diaryId))); } return Scaffold( backgroundColor: Colors.grey.shade200, appBar: diaryId == null - ? AppBar( - toolbarHeight: 0, - ) + ? AppBar(toolbarHeight: 0) : AppBar( title: Text( state is DiaryStateLoaded ? DateTime.parse(state.diary.date).toLocal().format('d MMMM') : '', @@ -97,12 +82,7 @@ class DiaryScreenContent extends StatelessWidget { child: Column( children: [ if (diaryId == null) const CalendarWidget(), - if (state is DiaryStateLoading) ...[ - const SizedBox( - height: 60, - ), - const Loader() - ], + if (state is DiaryStateLoading) ...[const SizedBox(height: 60), const Loader()], if (state is DiaryStateLoaded) WakeupAndRetireWidget( isEnabled: state.diary.typeOfDiary.hasChosenPlan || state.isConsultantView || state.isWakeUpAndRetireEnabled, @@ -114,40 +94,31 @@ class DiaryScreenContent extends StatelessWidget { showMood: state.diary.typeOfDiary.hasChosenPlan || state.isConsultantView || state.isMoodEnabled, showAddButton: !state.isConsultantView && !state.isDiaryFinished && !state.isDiaryCommented, ), - if (state is DiaryStateLoadedTomorrowWithDiet) - const MealWidget( - showMood: false, - showAddButton: false, - ), + if (state is DiaryStateLoadedTomorrowWithDiet) const MealWidget(showMood: false, showAddButton: false), if (state is DiaryStateLoaded) const CaloriesChartWidget(), const SizedBox(height: 12), - Builder(builder: (context) { - if (state is DiaryStateLoaded && state.diary.typeOfDiary.hasChosenPlan) { - if (state.diary.comment.isNotEmpty) { - return CommentForConsultantWidget( - comment: state.diary.comment, - ); + Builder( + builder: (context) { + if (state is DiaryStateLoaded && state.diary.typeOfDiary.hasChosenPlan) { + if (state.diary.comment.isNotEmpty) { + return CommentForConsultantWidget(comment: state.diary.comment); + } + if (state.isDiaryCommented || state.isDiaryFinished) { + return const SizedBox.shrink(); + } + return const CommentForConsultantWidget(); } - if (state.isDiaryCommented || state.isDiaryFinished) { - return const SizedBox.shrink(); - } - return const CommentForConsultantWidget(); - } - return const SizedBox.shrink(); - }), + return const SizedBox.shrink(); + }, + ), if (state is DiaryStateLoaded && !state.isConsultantView && !state.isDiaryFinished && !state.isDiaryCommented) Padding( padding: const EdgeInsets.only(top: 12), - child: FinishDayButtonWidget( - diaryDay: state.diary, - ), + child: FinishDayButtonWidget(diaryDay: state.diary), ), if (state is DiaryStateLoaded && state.isConsultantView && !state.isDiaryCommented) ...[ const SizedBox(height: 16), - const MainBackgroundBouble( - padding: EdgeInsets.all(16), - child: DayCommentWidget(), - ) + const MainBackgroundBouble(padding: EdgeInsets.all(16), child: DayCommentWidget()), ], if (state is DiaryStateLoaded && state.consultantReview?.consultantComments.dayComment != null) ...[ const SizedBox(height: 12), @@ -155,10 +126,7 @@ class DiaryScreenContent extends StatelessWidget { padding: const EdgeInsets.all(16), child: Column( children: [ - Text( - s.dayComment, - style: TextStyles.textLSemibold.copyWith(color: appTheme.black), - ), + Text(s.dayComment, style: TextStyles.textLSemibold.copyWith(color: appTheme.black)), const SizedBox(height: 12), CommentContainer(comment: state.consultantReview?.consultantComments.dayComment ?? ''), ], diff --git a/lib/features/diary/presentation/widgets/finish_day_button_widget.dart b/lib/features/diary/presentation/widgets/finish_day_button_widget.dart index 042c418c..b3f170ec 100644 --- a/lib/features/diary/presentation/widgets/finish_day_button_widget.dart +++ b/lib/features/diary/presentation/widgets/finish_day_button_widget.dart @@ -1,11 +1,11 @@ -import 'package:eatvio_app/features/diary/models/diary_day_model.dart'; +import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart'; import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class FinishDayButtonWidget extends StatefulWidget { - final DiaryDayModel diaryDay; + final DiaryDayEntity diaryDay; const FinishDayButtonWidget({super.key, required this.diaryDay}); diff --git a/lib/features/diary/presentation/widgets/photo_gallery_widget.dart b/lib/features/diary/presentation/widgets/photo_gallery_widget.dart index 352b6519..a058ba61 100644 --- a/lib/features/diary/presentation/widgets/photo_gallery_widget.dart +++ b/lib/features/diary/presentation/widgets/photo_gallery_widget.dart @@ -5,7 +5,7 @@ import 'package:eatvio_app/core/app_router.dart'; import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/permission_handler/permission_handler.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; -import 'package:eatvio_app/features/diary/models/diary_day_model.dart'; +import 'package:eatvio_app/features/diary/entities/diary_day_entity.dart'; import 'package:eatvio_app/features/diary/presentation/bloc/diary_cubit.dart'; import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart'; import 'package:eatvio_app/generated/l10n.dart'; @@ -34,7 +34,7 @@ class _PhotoGalleryWidgetState extends State { diaryCubit = context.read(); } - void showImagePicker(DiaryDayModel diaryDay) { + void showImagePicker(DiaryDayEntity diaryDay) { showCupertinoModalPopup( context: context, builder: (context) { diff --git a/lib/features/diary/repositories/diary_repository.dart b/lib/features/diary/repositories/diary_repository.dart index 0165ad7f..d385ed75 100644 --- a/lib/features/diary/repositories/diary_repository.dart +++ b/lib/features/diary/repositories/diary_repository.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:io'; import 'package:eatvio_app/features/diary/models/consultant_comment_model.dart'; import 'package:eatvio_app/features/diary/models/consultant_review_model.dart'; +import 'package:eatvio_app/features/diary/models/create_day_model.dart'; import 'package:eatvio_app/features/diary/models/diary_day_model.dart'; import 'package:eatvio_app/features/diary/models/finish_diary_day_model.dart'; import 'package:eatvio_app/features/diary/models/nutrition_model.dart'; @@ -69,14 +70,6 @@ class DiaryRepository { } } - Future getDiaryByDateForDietOnly(String date) async { - try { - return (await diaryService.getDiaryIndexByDateForDietOnly(date: date)).last; - } catch (e) { - rethrow; - } - } - Future> getDiaryIndexByDate(String date) async { return (await diaryService.getDiaryIndexByDate(date: date)); } @@ -254,4 +247,21 @@ class DiaryRepository { rethrow; } } + + Future getDiaryDayV2({required String day}) async { + try { + return await diaryService.getDiaryDayV2(day: day); + } catch (e) { + rethrow; + } + } + + Future createDiaryDay({required String day}) async { + try { + await diaryService.createDay(body: CreateDayModel(day: day)); + await getDiaryByDate(day); + } catch (e) { + rethrow; + } + } } diff --git a/lib/features/diary/services/diary_service.dart b/lib/features/diary/services/diary_service.dart index 8cba6f33..985fb885 100644 --- a/lib/features/diary/services/diary_service.dart +++ b/lib/features/diary/services/diary_service.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:dio/dio.dart'; import 'package:eatvio_app/features/diary/models/consultant_comment_model.dart'; import 'package:eatvio_app/features/diary/models/consultant_review_model.dart'; +import 'package:eatvio_app/features/diary/models/create_day_model.dart'; import 'package:eatvio_app/features/diary/models/diary_day_model.dart'; import 'package:eatvio_app/features/diary/models/finish_diary_day_model.dart'; import 'package:eatvio_app/features/diary/models/nutrition_model.dart'; @@ -17,8 +18,6 @@ abstract class DiaryService { @GET('/api/diary/index/{date}') Future> getDiaryIndexByDate({@Path('date') required String date}); - @GET('/api/diary/index/{date}') - Future> getDiaryIndexByDateForDietOnly({@Path('date') required String date}); @GET('/api/diary/{diary}/show') Future getDiaryDay({@Path('diary') required int diary}); @@ -103,4 +102,10 @@ abstract class DiaryService { @GET('/api/glossaries/index') Future getGlossariesIndex({@Queries() Map? filters}); + + @POST('/api/v2/diary/create/day') + Future createDay({@Body() required CreateDayModel body}); + + @GET('/api/v2/diary/index/{day?}') + Future getDiaryDayV2({@Query('day') required String day}); } diff --git a/lib/features/profile/presentation/pages/profile_screen.dart b/lib/features/profile/presentation/pages/profile_screen.dart index cc8f7245..0167fce9 100644 --- a/lib/features/profile/presentation/pages/profile_screen.dart +++ b/lib/features/profile/presentation/pages/profile_screen.dart @@ -110,6 +110,7 @@ class _ProfileScreenState extends State { Text( 'Пользователь ограничил доступ к своей странице', textAlign: TextAlign.center, + style: TextStyle(fontSize: 18, fontWeight: FontWeight.w500, color: Colors.grey[600]), ), ], diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 85f74918..6144d39c 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -28,9 +28,10 @@ class S { static const AppLocalizationDelegate delegate = AppLocalizationDelegate(); static Future load(Locale locale) { - final name = (locale.countryCode?.isEmpty ?? false) - ? locale.languageCode - : locale.toString(); + final name = + (locale.countryCode?.isEmpty ?? false) + ? locale.languageCode + : locale.toString(); final localeName = Intl.canonicalizedLocale(name); return initializeMessages(localeName).then((_) { Intl.defaultLocale = localeName;