import 'package:basic_utils/basic_utils.dart'; import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import '../models/food.dart'; import '../pages/nav_pages/search_food.dart'; class CardComponent extends StatefulWidget { final String eatingMealName; final List selectedMeal; final bool addButtonVisible; const CardComponent( {Key? key, required this.eatingMealName, required this.selectedMeal, this.addButtonVisible = true}) : super(key: key); @override State createState() => _CardComponentState(); } class _CardComponentState extends State { 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() { if (widget.eatingMealName.toLowerCase() == dotenv.env['BREAKFAST_FIELD']!.toLowerCase()) { return const Image(image: AssetImage('assets/images/tea.png')); } else if (widget.eatingMealName.toLowerCase() == dotenv.env['LUNCH_FIELD']!.toLowerCase()) { return const Image(image: AssetImage('assets/images/fries.png')); } else if (widget.eatingMealName.toLowerCase() == dotenv.env['DINNER_FIELD']!.toLowerCase()) { 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() { 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(); } } 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(); } Map> getMapOfDistinctElementsWithCounterAndCalories(List foods){ Map> resultMap = >{}; 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; } String getFoodListStringByFood(String foodName, int count, int calories){ int maxWidth = 35; String limitedText = foodName.length > maxWidth ? "${foodName.substring(0, maxWidth - 3)} ... $count x $calories kcal" : "$foodName $count x $calories kcal"; return limitedText; } @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( StringUtils.capitalize(widget.eatingMealName), 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, itemCount: getMapOfDistinctElementsWithCounterAndCalories(widget.selectedMeal).keys.length, itemBuilder: (context, i) { Map> map = getMapOfDistinctElementsWithCounterAndCalories(widget.selectedMeal); String foodName = map.keys.elementAt(i); List values = map.values.elementAt(i); return Text( getFoodListStringByFood(foodName, values[0], values[1]) ); } ), ), widget.selectedMeal.isNotEmpty ? const Divider() : const SizedBox.shrink(), widget.selectedMeal.isNotEmpty ? Text("${getCountedCalories()} kcal") : const SizedBox.shrink(), ], )); } }