2023-05-30 17:10:53 +02:00
|
|
|
import 'package:basic_utils/basic_utils.dart';
|
2023-05-29 12:08:46 +02:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
2023-05-30 17:12:42 +02:00
|
|
|
import '../config/format_helper.dart';
|
2023-05-29 12:08:46 +02:00
|
|
|
import '../models/food.dart';
|
|
|
|
import '../pages/nav_pages/search_food.dart';
|
|
|
|
|
|
|
|
class CardComponent extends StatefulWidget {
|
|
|
|
final String eatingMealName;
|
|
|
|
final List<Food> selectedMeal;
|
2023-05-30 09:38:54 +02:00
|
|
|
final bool addButtonVisible;
|
2023-05-29 12:08:46 +02:00
|
|
|
|
|
|
|
const CardComponent(
|
2023-05-30 09:38:54 +02:00
|
|
|
{Key? key, required this.eatingMealName, required this.selectedMeal, this.addButtonVisible = true})
|
2023-05-29 12:08:46 +02:00
|
|
|
: super(key: key);
|
|
|
|
|
|
|
|
@override
|
|
|
|
State<CardComponent> createState() => _CardComponentState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _CardComponentState extends State<CardComponent> {
|
|
|
|
Route createRoute(String cardName) {
|
|
|
|
return PageRouteBuilder(
|
|
|
|
pageBuilder: (context, animation, secondaryAnimation) =>
|
|
|
|
SearchFoodPage(cardName),
|
|
|
|
transitionsBuilder: (context, animation, secondaryAnimation, child) {
|
|
|
|
const begin = Offset(0.0, 1.0);
|
|
|
|
const end = Offset.zero;
|
|
|
|
const curve = Curves.ease;
|
|
|
|
|
|
|
|
var tween =
|
|
|
|
Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
|
|
|
|
|
|
|
|
return SlideTransition(
|
|
|
|
position: animation.drive(tween),
|
|
|
|
child: child,
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
getImageOfMeal() {
|
2023-05-29 22:04:44 +02:00
|
|
|
if (widget.eatingMealName.toLowerCase() == dotenv.env['BREAKFAST_FIELD']!.toLowerCase()) {
|
2023-05-29 12:08:46 +02:00
|
|
|
return const Image(image: AssetImage('assets/images/tea.png'));
|
2023-05-29 22:04:44 +02:00
|
|
|
} else if (widget.eatingMealName.toLowerCase() == dotenv.env['LUNCH_FIELD']!.toLowerCase()) {
|
2023-05-29 12:08:46 +02:00
|
|
|
return const Image(image: AssetImage('assets/images/fries.png'));
|
2023-05-29 22:04:44 +02:00
|
|
|
} else if (widget.eatingMealName.toLowerCase() == dotenv.env['DINNER_FIELD']!.toLowerCase()) {
|
2023-05-29 12:08:46 +02:00
|
|
|
return const Image(image: AssetImage('assets/images/ice.png'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String capitalize(String s) => s[0].toUpperCase() + s.substring(1);
|
|
|
|
|
|
|
|
String listFoodAsString() {
|
|
|
|
String mealAsString = "";
|
|
|
|
for (final food in widget.selectedMeal) {
|
|
|
|
mealAsString = "${food.name} ";
|
|
|
|
}
|
|
|
|
return mealAsString;
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget getElevatedButton() {
|
2023-05-30 09:38:54 +02:00
|
|
|
if(widget.addButtonVisible){
|
|
|
|
return ElevatedButton(
|
|
|
|
onPressed: () async {
|
|
|
|
Navigator.of(context).push(createRoute(widget.eatingMealName));
|
|
|
|
},
|
|
|
|
style: ElevatedButton.styleFrom(
|
|
|
|
shape: const CircleBorder(),
|
|
|
|
padding: const EdgeInsets.all(0),
|
|
|
|
),
|
|
|
|
child: const Text(
|
|
|
|
'+',
|
|
|
|
style: TextStyle(fontSize: 28),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}else{
|
|
|
|
return const SizedBox.shrink();
|
|
|
|
}
|
|
|
|
|
2023-05-29 12:08:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int getCountedCalories() {
|
|
|
|
double calories = 0;
|
|
|
|
for (Food food in widget.selectedMeal) {
|
|
|
|
if (food.calories is int){
|
|
|
|
calories += food.calories as int;
|
|
|
|
}else if(food.calories is double){
|
|
|
|
calories += food.calories as double;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return calories.round();
|
|
|
|
}
|
|
|
|
|
2023-05-30 15:15:22 +02:00
|
|
|
Map<String,List<int>> getMapOfDistinctElementsWithCounterAndCalories(List<Food> foods){
|
|
|
|
Map<String,List<int>> resultMap = <String,List<int>>{};
|
|
|
|
for(int i = 0; i < foods.length;i++){
|
|
|
|
if(!resultMap.keys.contains(foods[i].name)){
|
|
|
|
resultMap.putIfAbsent(foods[i].name, () => [1,foods[i].calories]);
|
|
|
|
}else{
|
|
|
|
resultMap[foods[i].name]![0] = resultMap[foods[i].name]![0] + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return resultMap;
|
|
|
|
}
|
2023-05-29 12:08:46 +02:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return Card(
|
|
|
|
margin: const EdgeInsets.fromLTRB(0, 24, 0, 0),
|
|
|
|
child: Column(
|
|
|
|
children: [
|
|
|
|
Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
children: [
|
|
|
|
Row(
|
|
|
|
children: [
|
|
|
|
getImageOfMeal(),
|
|
|
|
Column(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
|
children: [
|
|
|
|
SizedBox(
|
|
|
|
width: MediaQuery.of(context).size.width * 0.6,
|
|
|
|
child: Text(
|
2023-05-30 17:10:53 +02:00
|
|
|
StringUtils.capitalize(widget.eatingMealName),
|
2023-05-29 12:08:46 +02:00
|
|
|
maxLines: 1,
|
|
|
|
overflow: TextOverflow.ellipsis,
|
|
|
|
softWrap: false,
|
|
|
|
style: const TextStyle(
|
|
|
|
color: Colors.black,
|
|
|
|
fontWeight: FontWeight.w500,
|
|
|
|
fontSize: 14),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
],
|
|
|
|
),
|
|
|
|
getElevatedButton(),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
SizedBox(
|
|
|
|
width: MediaQuery.of(context).size.width * 0.8,
|
|
|
|
child:ListView.builder(
|
|
|
|
primary: false,
|
|
|
|
shrinkWrap: true,
|
2023-05-30 15:15:22 +02:00
|
|
|
itemCount: getMapOfDistinctElementsWithCounterAndCalories(widget.selectedMeal).keys.length,
|
2023-05-29 12:08:46 +02:00
|
|
|
itemBuilder: (context, i) {
|
2023-05-30 15:15:22 +02:00
|
|
|
Map<String,List<int>> map = getMapOfDistinctElementsWithCounterAndCalories(widget.selectedMeal);
|
|
|
|
String foodName = map.keys.elementAt(i);
|
|
|
|
List<int> values = map.values.elementAt(i);
|
2023-05-29 12:08:46 +02:00
|
|
|
return Text(
|
2023-05-30 15:15:22 +02:00
|
|
|
getFoodListStringByFood(foodName, values[0], values[1])
|
2023-05-29 12:08:46 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
),
|
|
|
|
),
|
|
|
|
widget.selectedMeal.isNotEmpty
|
|
|
|
? const Divider()
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
widget.selectedMeal.isNotEmpty
|
|
|
|
? Text("${getCountedCalories()} kcal")
|
|
|
|
: const SizedBox.shrink(),
|
|
|
|
],
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|