diff --git a/lib/components/dishCard.dart b/lib/components/dishCard.dart new file mode 100644 index 0000000..54e5c41 --- /dev/null +++ b/lib/components/dishCard.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import '../services.dart'; + +class DishCard extends StatelessWidget { + final Dish dish; + + DishCard({@required this.dish}); + + @override + Widget build(BuildContext context) { + return Card( + color: Colors.grey[800], + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + margin: EdgeInsets.symmetric(horizontal: 12, vertical: 5), + child: InkWell( + onTap: () {}, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + child: ClipRRect( + child: Image.network( + dish.imgUrl, + width: 80, + height: 80, + fit: BoxFit.cover, + ), + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(12), + topLeft: Radius.circular(12)), + ), + padding: EdgeInsets.only(right: 8), + ), + Expanded( + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + dish.name, + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: TextStyle(color: Colors.orange[600], fontSize: 16), + ), + Text( + '${dish.price} zł', + style: TextStyle(color: Colors.grey[300], fontSize: 14), + ), + ], + )), + Container( + child: Icon( + Icons.arrow_right, + color: Colors.white, + size: 24, + ), + ) + ], + ), + ), + ); + } +} diff --git a/lib/components/dishList.dart b/lib/components/dishList.dart new file mode 100644 index 0000000..8320d06 --- /dev/null +++ b/lib/components/dishList.dart @@ -0,0 +1,152 @@ +import 'package:flutter/material.dart'; +import '../services.dart'; +import 'dishCard.dart'; + +class DishList extends StatelessWidget { + final String id; + final List categories; + DishList({@required this.id, @required this.categories}); + + final MenuiServices services = new MenuiServices(); + + @override + Widget build(BuildContext context) { + return Stack(children: [ + ListView(children: [ + SizedBox(height: 24), + FutureBuilder>( + future: services.fetchAllDishes(id), + builder: + (BuildContext context, AsyncSnapshot> snapshot) { + if (snapshot.hasData) { + final List dishes = snapshot.data; + return ListView.builder( + controller: ScrollController(), + shrinkWrap: true, + itemCount: categories.length, + itemBuilder: (context, index) { + final filteredDishes = + filterDishesByCategory(dishes, categories[index]); + return ExpansionTile( + leading: Icon( + Icons.fastfood_rounded, + color: Colors.orange, + ), + title: Text( + categories[index], + style: TextStyle(color: Colors.grey[300]), + ), + children: [ + ListView.builder( + primary: false, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: filteredDishes.length, + itemBuilder: (context, index) { + return Container( + child: DishCard(dish: filteredDishes[index]), + ); + }, + ) + ], + ); + }, + ); + } else { + return Center( + child: CircularProgressIndicator(), + ); + } + }), + ]), + Positioned.fill( + bottom: 20, + child: Align( + alignment: Alignment.bottomCenter, + child: FloatingActionButton.extended( + backgroundColor: Colors.grey[900], + onPressed: () { + Navigator.pop(context); + }, + icon: Icon( + Icons.keyboard_arrow_down_rounded, + color: Colors.orange, + ), + label: Text( + 'Zamknij', + style: + TextStyle(color: Colors.white, fontWeight: FontWeight.w400), + ), + ), + )) + ]); + } + + List filterDishesByCategory(List dishes, String category) { + List result = []; + for (var dish in dishes) { + if (dish.category == category) { + result.add(dish); + } + } + return result; + } +} + +/* +class DishList extends StatelessWidget { + final String id; + final List categories; + DishList({@required this.id, @required this.categories}); + + final MenuiServices services = new MenuiServices(); + + @override + Widget build(BuildContext context) { + return ListView(children: [ + FutureBuilder>( + future: services.fetchAllDishes(id), + builder: (BuildContext context, AsyncSnapshot> snapshot) { + if (snapshot.hasData) { + final List dishes = snapshot.data; + return ListView.builder( + controller: ScrollController(), + shrinkWrap: true, + itemCount: categories.length, + itemBuilder: (context, index) { + final filteredDishes = + filterDishesByCategory(dishes, categories[index]); + return ExpansionTile( + leading: Icon( + Icons.fastfood_rounded, + color: Colors.orange, + ), + title: Text( + categories[index], + style: TextStyle(color: Colors.grey[300]), + ), + children: [ + ListView.builder( + primary: false, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + itemCount: filteredDishes.length, + itemBuilder: (context, index) { + return Container( + child: DishCard(dish: filteredDishes[index]), + ); + }, + ) + ], + ); + }, + ); + } else { + return Center( + child: CircularProgressIndicator(), + ); + } + }), + + ]); + } */ diff --git a/lib/components/mapWithMarkers.dart b/lib/components/mapWithMarkers.dart new file mode 100644 index 0000000..1b3e2e0 --- /dev/null +++ b/lib/components/mapWithMarkers.dart @@ -0,0 +1,10 @@ +/* import 'package:flutter/material.dart'; +import '../services.dart'; */ +/* +class MapWithMarkers extends StatelessWidget { + @override + Widget build(BuildContext context) { + return + } +} + */ diff --git a/lib/components/restaurantView.dart b/lib/components/restaurantView.dart index bc47ac0..8335f6c 100644 --- a/lib/components/restaurantView.dart +++ b/lib/components/restaurantView.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import '../services.dart'; import 'lineOfIcons.dart'; +import 'dishList.dart'; class RestaurantView extends StatelessWidget { final String id; @@ -10,6 +11,8 @@ class RestaurantView extends StatelessWidget { @override Widget build(BuildContext context) { + services.fetchAllDishes(id); + List categories = []; return Scaffold( body: Container( decoration: BoxDecoration(color: Colors.grey[850]), @@ -19,6 +22,7 @@ class RestaurantView extends StatelessWidget { (BuildContext context, AsyncSnapshot snapshot) { if (snapshot.hasData) { final Restaurant restaurant = snapshot.data; + categories = restaurant.categories; return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.stretch, @@ -154,11 +158,11 @@ class RestaurantView extends StatelessWidget { floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, floatingActionButton: FloatingActionButton.extended( onPressed: () { - showMenu(context); + showMenu(context, categories); }, label: Text( - 'Pokaż menu', - style: TextStyle(color: Colors.white), + 'Menu', + style: TextStyle(color: Colors.white, fontWeight: FontWeight.w400), ), icon: Icon( Icons.arrow_upward_rounded, @@ -168,17 +172,19 @@ class RestaurantView extends StatelessWidget { )); } - showMenu(BuildContext context) { - showModalBottomSheet( - context: context, - builder: (BuildContext context) { - return Container( - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage("img/bg_tile.jpg"), fit: BoxFit.cover)), - child: Text('qweqweqweqweqweqw'), - ); - }); + showMenu(BuildContext context, List categories) { + if (categories.isNotEmpty) { + showModalBottomSheet( + backgroundColor: Colors.grey[850], + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return DishList( + categories: categories, + id: id, + ); + }); + } } } diff --git a/lib/services.dart b/lib/services.dart index 90dd37a..a0c8ca1 100644 --- a/lib/services.dart +++ b/lib/services.dart @@ -38,6 +38,46 @@ class MenuiServices { } } + Future> fetchAllDishes(String id) async { + final response = + await http.get('${backendURL}restaurant/dishes?restaurantId=$id'); + if (response.statusCode != 400 && + response.statusCode != 404 && + response.statusCode != 500) { + final List decodedResponse = json.decode(response.body); + List dishes = []; + if (decodedResponse.isNotEmpty && decodedResponse != null) { + for (var dish in decodedResponse) { + final thisAllergens = dish['allergens']; + final Dish thisDish = new Dish( + id: dish['_id'], + restaurantId: dish['restaurantId'], + name: dish['name'], + category: dish['category'], + price: dish['price'], + notes: dish['notes'], + imgUrl: dish['imgUrl'], + weight: dish['weight'], + ingredients: dish['ingredients'], + vegetarian: dish['vegetarian'], + vegan: dish['vegan'], + glicemicIndex: dish['glicemicIndex'], + kCal: dish['kCal'], + allergens: new MenuiAllergens( + thisAllergens['gluten'], + thisAllergens['lactose'], + thisAllergens['soy'], + thisAllergens['eggs'], + thisAllergens['seaFood'], + thisAllergens['peanuts'], + thisAllergens['sesame'])); + dishes.add(thisDish); + } + } + return dishes; + } + } + Future fetchRestaurant(String id) async { final response = await http.get('${backendURL}restaurant?restaurantId=$id'); if (response.statusCode == 200 || response.statusCode == 304) { @@ -45,6 +85,7 @@ class MenuiServices { final workingHours = decoded['workingHours']; final tags = decoded['tags']; final links = decoded['links']; + final List categories = decoded['categories'].cast(); final List responseLunchMenu = decoded['lunchMenu']; List lunchMenu = []; if (responseLunchMenu != null) { @@ -77,7 +118,7 @@ class MenuiServices { description: decoded['description'], links: new MenuiLinks( links['facebook'], links['instagram'], links['www']), - categories: decoded['categories'], + categories: categories, tags: new MenuiTags( tags['cardPayments'], tags['petFriendly'], @@ -204,7 +245,7 @@ class Restaurant { MenuiTags tags; MenuiLinks links; String phone; - List categories; + List categories; String lunchHours; List lunchMenu; List dishes;