forked from eatvio/eatvio_app
118 lines
4.0 KiB
Dart
118 lines
4.0 KiB
Dart
import 'package:eatvio_app/features/diary/models/diary_day_model.dart';
|
||
import 'package:flutter/material.dart';
|
||
|
||
class MealSummaryWidget extends StatelessWidget {
|
||
final List<PortionModel> portions;
|
||
final int mealNumber;
|
||
|
||
const MealSummaryWidget({super.key, required this.portions, required this.mealNumber});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final totals = _calculateTotals();
|
||
|
||
if (totals['calories'] == 0 && totals['proteins'] == 0 && totals['fats'] == 0 && totals['carbohydrates'] == 0) {
|
||
return const SizedBox.shrink();
|
||
}
|
||
|
||
return Container(
|
||
margin: const EdgeInsets.only(top: 8),
|
||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(16),
|
||
border: Border.all(color: const Color(0xFF2F80ED), width: 2),
|
||
),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
Text(
|
||
'Прием $mealNumber',
|
||
style: const TextStyle(color: Color(0xFF323F4B), fontSize: 16, fontWeight: FontWeight.w600),
|
||
),
|
||
Row(
|
||
children: [
|
||
_buildNutritionChip('К', totals['calories']!.round()),
|
||
const SizedBox(width: 4),
|
||
_buildNutritionChip('Б', totals['proteins']!.round()),
|
||
const SizedBox(width: 4),
|
||
_buildNutritionChip('Ж', totals['fats']!.round()),
|
||
const SizedBox(width: 4),
|
||
_buildNutritionChip('У', totals['carbohydrates']!.round()),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _buildNutritionChip(String label, int value) {
|
||
return Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 6),
|
||
decoration: BoxDecoration(color: const Color(0xFFF6FAFF), borderRadius: BorderRadius.circular(12)),
|
||
child: RichText(
|
||
text: TextSpan(
|
||
children: [
|
||
TextSpan(
|
||
text: '$label ',
|
||
style: const TextStyle(color: Color(0xFF2F80ED), fontSize: 12, fontWeight: FontWeight.w600),
|
||
),
|
||
TextSpan(
|
||
text: '$value',
|
||
style: const TextStyle(color: Color(0xFF6D6F71), fontSize: 12, fontWeight: FontWeight.w600),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Map<String, double> _calculateTotals() {
|
||
return calculateMealTotals(portions);
|
||
}
|
||
|
||
static Map<String, double> calculateMealTotals(List<PortionModel> portions) {
|
||
double totalCalories = 0;
|
||
double totalProteins = 0;
|
||
double totalFats = 0;
|
||
double totalCarbohydrates = 0;
|
||
|
||
for (final portion in portions) {
|
||
if (portion.portionState == PortionState.eatenDeleted) {
|
||
continue;
|
||
}
|
||
|
||
// Для продуктов из диеты учитываем только съеденные (с галочкой)
|
||
if (portion.fromDiet && portion.portionState != PortionState.eatenFromDiet) {
|
||
continue;
|
||
}
|
||
|
||
final caloriesInfo = portion.productCaloriesInfo;
|
||
if (caloriesInfo == null) {
|
||
continue;
|
||
}
|
||
|
||
double calories, proteins, fats, carbohydrates;
|
||
|
||
if (portion.portion == 'gr') {
|
||
calories = (caloriesInfo.calories * portion.quantity) / 100;
|
||
proteins = (caloriesInfo.proteins * portion.quantity) / 100;
|
||
fats = (caloriesInfo.fats * portion.quantity) / 100;
|
||
carbohydrates = (caloriesInfo.carbohydrates * portion.quantity) / 100;
|
||
} else {
|
||
calories = caloriesInfo.energyOnPortion * portion.quantity;
|
||
proteins = caloriesInfo.proteinsOnPortion * portion.quantity;
|
||
fats = caloriesInfo.fatsOnPortion * portion.quantity;
|
||
carbohydrates = caloriesInfo.carbohydratesOnPortion * portion.quantity;
|
||
}
|
||
|
||
totalCalories += calories;
|
||
totalProteins += proteins;
|
||
totalFats += fats;
|
||
totalCarbohydrates += carbohydrates;
|
||
}
|
||
|
||
return {'calories': totalCalories, 'proteins': totalProteins, 'fats': totalFats, 'carbohydrates': totalCarbohydrates};
|
||
}
|
||
}
|