feat(diary): diet

This commit is contained in:
Alex
2024-12-24 16:52:06 +03:00
parent c6a60eccd9
commit 67d8bb58ee
13 changed files with 451 additions and 86 deletions

View File

@@ -102,15 +102,73 @@ class DiaryCubit extends Cubit<DiaryState> {
required String portion,
required int quantity,
int? productNutritionalValueId,
required PortionState portionState,
}) async {
await diaryRepository.updateProductInMeal(
if (portionState == PortionState.filled_diet || portionState == PortionState.eaten_from_diet) {
// await diaryRepository.deleteProductFromMeal(
// diaryId: diaryId,
// mealId: mealId,
// portionId: portionId,
// );
// todo delete product from diet
await diaryRepository.addPortionToMeal(
diaryId: diaryId,
mealId: mealId,
productName: productName,
portion: portion,
quantity: quantity,
productNutritionalValueId: productNutritionalValueId,
);
} else {
await diaryRepository.updateProductInMeal(
diaryId: diaryId,
mealId: mealId,
portionId: portionId,
productName: productName,
portion: portion,
quantity: quantity,
productNutritionalValueId: productNutritionalValueId,
portionState: portionState,
);
}
await fetchDiary();
}
markEaten({
required int diaryId,
required int mealId,
required int portionId,
}) async {
await diaryRepository.markEaten(
diaryId: diaryId,
mealId: mealId,
portionId: portionId,
);
await fetchDiary();
}
unmarkEaten({
required int diaryId,
required int mealId,
required int portionId,
}) async {
await diaryRepository.unmarkEaten(
diaryId: diaryId,
mealId: mealId,
portionId: portionId,
);
await fetchDiary();
}
restore({
required int diaryId,
required int mealId,
required int portionId,
}) async {
await diaryRepository.restore(
diaryId: diaryId,
mealId: mealId,
portionId: portionId,
productName: productName,
portion: portion,
quantity: quantity,
productNutritionalValueId: productNutritionalValueId,
);
await fetchDiary();
}

View File

@@ -35,7 +35,6 @@ class _DiaryScreenState extends State<DiaryScreen> {
CalendarWidget(),
if (state is DiaryStateLoading) const Loader(),
if (state is DiaryStateLoaded) MealWidget(),
const SizedBox(height: 12),
CaloriesChartWidget(),
],
),

View File

@@ -10,7 +10,7 @@ import 'package:eatvio_app/features/glossary/models/glossary_model.dart';
import 'package:flutter/material.dart';
class AddProductModal extends StatefulWidget {
final Portion? portion;
final PortionModel? portion;
final DiaryStateLoaded state;
final DiaryCubit diaryCubit;
@@ -221,6 +221,7 @@ class _AddProductModalState extends State<AddProductModal> {
: 'pcs',
quantity: int.parse(quantityController.text),
productNutritionalValueId: selectedGlossary?.id,
portionState: widget.portion!.portionState,
);
}
Navigator.of(context).pop();

View File

@@ -1,12 +1,15 @@
import 'package:dotted_border/dotted_border.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/presentation/bloc/diary_cubit.dart';
import 'package:eatvio_app/features/diary/presentation/bloc/diary_state.dart';
import 'package:eatvio_app/features/diary/presentation/widgets/add_product_modal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/flutter_svg.dart';
class ProductWidget extends StatefulWidget {
final Portion portion;
final PortionModel portion;
const ProductWidget({
super.key,
@@ -20,15 +23,17 @@ class ProductWidget extends StatefulWidget {
class _ProductWidgetState extends State<ProductWidget> {
late final DiaryCubit diaryCubit;
late String portionName;
late bool isEaten;
@override
void initState() {
super.initState();
diaryCubit = context.read<DiaryCubit>();
portionName = widget.portion == 'gr' ? 'гр' : 'шт';
isEaten = widget.portion.portionState == PortionState.eaten_from_diet ? true : false;
}
updateProductInMeal(DiaryStateLoaded state, Portion portion) {
updateProductInMeal(DiaryStateLoaded state, PortionModel portion) {
return showModalBottomSheet(
useRootNavigator: true,
context: context,
@@ -49,16 +54,80 @@ class _ProductWidgetState extends State<ProductWidget> {
return BlocBuilder<DiaryCubit, DiaryState>(
builder: (context, state) {
if (state is DiaryStateLoaded) {
return ListTile(
onTap: () => updateProductInMeal(state, widget.portion),
trailing: Icon(Icons.more_vert_rounded),
title: Text(widget.portion.productName),
subtitle: Text('${widget.portion.quantity} ${widget.portion.portion == 'gr' ? 'гр' : 'шт'}'),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
tileColor: Color(0xFFF6FAFF),
);
if (widget.portion.portionState == PortionState.eaten_deleted) {
return DottedBorder(
dashPattern: [6, 6],
padding: EdgeInsets.zero,
borderPadding: EdgeInsets.zero,
borderType: BorderType.RRect,
radius: Radius.circular(20),
color: Color(0xFF6D6F71),
child: ListTile(
onTap: () => diaryCubit.restore(
diaryId: state.diary.id,
mealId: state.selectedMeal,
portionId: widget.portion.id,
),
trailing: SvgPicture.asset(
'assets/icons/revert_product.svg',
),
horizontalTitleGap: 0,
contentPadding: widget.portion.fromDiet ? EdgeInsets.only(right: 24, left: 4) : null,
title: Text(widget.portion.productName),
subtitle: Text('${widget.portion.quantity} ${widget.portion.portion == 'gr' ? 'гр' : 'шт'}'),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
tileColor: Color(0xFFF6FAFF03).withValues(alpha: 0.01),
),
);
} else {
return ListTile(
onTap: () => updateProductInMeal(state, widget.portion),
trailing: Icon(Icons.more_vert_rounded),
leading: widget.portion.fromDiet
? Transform.scale(
scale: 1.2,
child: Checkbox(
value: isEaten,
onChanged: (value) {
setState(() {
isEaten = value!;
});
if (isEaten) {
diaryCubit.markEaten(
diaryId: state.diary.id,
mealId: state.selectedMeal,
portionId: widget.portion.id,
);
} else {
diaryCubit.unmarkEaten(
diaryId: state.diary.id,
mealId: state.selectedMeal,
portionId: widget.portion.id,
);
}
},
activeColor: appTheme.blueA400,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
side: BorderSide(
color: Color(0xFF809CB9),
),
),
)
: null,
horizontalTitleGap: 0,
contentPadding: widget.portion.fromDiet ? EdgeInsets.only(right: 24, left: 4) : null,
title: Text(widget.portion.productName),
subtitle: Text('${widget.portion.quantity} ${widget.portion.portion == 'gr' ? 'гр' : 'шт'}'),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
tileColor: Color(0xFFF6FAFF),
);
}
}
return const SizedBox.shrink();
},