From 083a617c9596bb3fb837527f70f6ab07b937051c Mon Sep 17 00:00:00 2001 From: Alysson Date: Thu, 13 Apr 2023 23:10:48 +0200 Subject: [PATCH] feat(): navigate to meals'es category + meal card --- lib/models/Meal.dart | 9 ++++ lib/screens/CategoriesScreen.dart | 26 ++++++++++- lib/screens/MealsScreen.dart | 3 +- lib/widgets/CategoryGridItem.dart | 6 ++- lib/widgets/MealItem.dart | 75 +++++++++++++++++++++++++++++++ lib/widgets/meal_item treat.dart | 22 +++++++++ pubspec.lock | 8 ++++ pubspec.yaml | 1 + 8 files changed, 145 insertions(+), 5 deletions(-) create mode 100644 lib/widgets/MealItem.dart create mode 100644 lib/widgets/meal_item treat.dart diff --git a/lib/models/Meal.dart b/lib/models/Meal.dart index 3d91c6b..749ad02 100644 --- a/lib/models/Meal.dart +++ b/lib/models/Meal.dart @@ -40,4 +40,13 @@ class Meal { final bool isLactoseFree; final bool isVegan; final bool isVegetarian; + + String get beautifulComplexity { + return complexity.name[0].toUpperCase() + complexity.name.substring(1); + } + + String get beautifulAffordability { + return affordability.name[0].toUpperCase() + + affordability.name.substring(1); + } } diff --git a/lib/screens/CategoriesScreen.dart b/lib/screens/CategoriesScreen.dart index a0d2532..433af26 100644 --- a/lib/screens/CategoriesScreen.dart +++ b/lib/screens/CategoriesScreen.dart @@ -1,9 +1,24 @@ import 'package:flutter/material.dart'; import 'package:meals/data/dummy_categories.dart'; +import 'package:meals/models/Category.dart'; +import 'package:meals/models/Meal.dart'; +import 'package:meals/screens/MealsScreen.dart'; import 'package:meals/widgets/CategoryGridItem.dart'; class CategoriesScreen extends StatelessWidget { - const CategoriesScreen({Key? key}); + const CategoriesScreen({super.key}); + + void _selectCategory(BuildContext context, Category category) { + final meals = dummyMeals + .where((Meal meal) => meal.categories.contains(category.id)) + .toList(); + + Navigator.push( + context, + MaterialPageRoute( + builder: (ctx) => + MealsScreen(title: category.title, meals: meals))); + } @override Widget build(BuildContext context) { @@ -21,7 +36,14 @@ class CategoriesScreen extends StatelessWidget { ), children: [ for (final category in availableCategories) - CategoryGridItem(category: category) + CategoryGridItem( + category: category, + onClickCallback: () { + _selectCategory( + context, + category, + ); + }) ]), ); } diff --git a/lib/screens/MealsScreen.dart b/lib/screens/MealsScreen.dart index ac14129..d20c10f 100644 --- a/lib/screens/MealsScreen.dart +++ b/lib/screens/MealsScreen.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:meals/models/Meal.dart'; +import 'package:meals/widgets/MealItem.dart'; class MealsScreen extends StatelessWidget { final String title; @@ -33,7 +34,7 @@ class MealsScreen extends StatelessWidget { ) : ListView.builder( itemBuilder: (BuildContext context, int index) { - return Text(meals[index].title); + return MealItem(meal: meals[index]); }, itemCount: meals.length, ); diff --git a/lib/widgets/CategoryGridItem.dart b/lib/widgets/CategoryGridItem.dart index c5c76b3..dc05018 100644 --- a/lib/widgets/CategoryGridItem.dart +++ b/lib/widgets/CategoryGridItem.dart @@ -3,13 +3,15 @@ import 'package:meals/models/Category.dart'; class CategoryGridItem extends StatelessWidget { final Category category; + final void Function() onClickCallback; - const CategoryGridItem({super.key, required this.category}); + const CategoryGridItem( + {super.key, required this.category, required this.onClickCallback}); @override Widget build(BuildContext context) { return InkWell( - onTap: () {}, + onTap: onClickCallback, borderRadius: BorderRadius.circular(8), child: Container( padding: const EdgeInsets.all(16), diff --git a/lib/widgets/MealItem.dart b/lib/widgets/MealItem.dart new file mode 100644 index 0000000..df66c36 --- /dev/null +++ b/lib/widgets/MealItem.dart @@ -0,0 +1,75 @@ +import 'package:flutter/material.dart'; +import 'package:meals/models/Meal.dart'; +import 'package:meals/widgets/meal_item%20treat.dart'; +import 'package:transparent_image/transparent_image.dart'; + +class MealItem extends StatelessWidget { + final Meal meal; + const MealItem({Key? key, required this.meal}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Card( + margin: const EdgeInsets.all(8), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)), + clipBehavior: Clip.hardEdge, + elevation: 2, + child: InkWell( + onTap: () {}, + child: Stack( + children: [ + FadeInImage( + placeholder: MemoryImage(kTransparentImage), + image: NetworkImage(meal.imageUrl), + fit: BoxFit.cover, + height: 200, + width: double.infinity, + ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Container( + color: Colors.black54, + padding: + const EdgeInsets.symmetric(vertical: 6, horizontal: 44), + child: Column( + children: [ + Text( + meal.title, + maxLines: 2, + textAlign: TextAlign.center, + softWrap: true, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + const SizedBox( + height: 24, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + MealItemTreat( + icon: Icons.schedule, + label: '${meal.duration} mins.'), + MealItemTreat( + icon: Icons.work, label: meal.beautifulComplexity), + MealItemTreat( + icon: Icons.attach_money, + label: meal.beautifulAffordability), + ], + ) + ], + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/meal_item treat.dart b/lib/widgets/meal_item treat.dart new file mode 100644 index 0000000..4405651 --- /dev/null +++ b/lib/widgets/meal_item treat.dart @@ -0,0 +1,22 @@ +import 'package:flutter/material.dart'; + +class MealItemTreat extends StatelessWidget { + final IconData icon; + final String label; + const MealItemTreat({Key? key, required this.icon, required this.label}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Icon(icon, size: 17, color: Colors.white), + const SizedBox(width: 6), + Text( + label, + style: const TextStyle(color: Colors.white), + ) + ], + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 4f1cb0c..e15321e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -296,6 +296,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.4.16" + transparent_image: + dependency: "direct main" + description: + name: transparent_image + sha256: e8991d955a2094e197ca24c645efec2faf4285772a4746126ca12875e54ca02f + url: "https://pub.dev" + source: hosted + version: "2.0.1" typed_data: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d425350..30e9b07 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,7 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 google_fonts: ^4.0.3 + transparent_image: ^2.0.1 dev_dependencies: flutter_test: