From 451a27c6a486f1eeb030af8dcdcf20b4456968fb Mon Sep 17 00:00:00 2001 From: Niklas Date: Thu, 10 Oct 2024 23:21:46 +0200 Subject: [PATCH] Anzahl an Events werden angezeigt. --- devtools_options.yaml | 3 + lib/main.dart | 11 +- lib/screens/detail_widget.dart | 3 +- lib/screens/home.dart | 100 +++++++----------- lib/utils/class.dart | 23 ++--- lib/utils/data.dart | 179 +++++++++++++++++---------------- lib/utils/widgets.dart | 92 ----------------- pubspec.lock | 16 +++ pubspec.yaml | 1 + 9 files changed, 168 insertions(+), 260 deletions(-) create mode 100644 devtools_options.yaml delete mode 100644 lib/utils/widgets.dart diff --git a/devtools_options.yaml b/devtools_options.yaml new file mode 100644 index 0000000..fa0b357 --- /dev/null +++ b/devtools_options.yaml @@ -0,0 +1,3 @@ +description: This file stores settings for Dart & Flutter DevTools. +documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states +extensions: diff --git a/lib/main.dart b/lib/main.dart index 25ead22..8c24583 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:Emma_home/screens/home.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'screens/MainScreen.dart'; +import 'utils/data.dart'; +import 'package:provider/provider.dart'; //import 'package:learn_project/screens/account_page.dart'; //import 'package:learn_project/screens/login_page.dart'; //import 'package:learn_project/screens/splash_page.dart'; @@ -19,7 +21,14 @@ Future main() async { //url:'http://192.168.179.86:8000/',// // annonKey: //Constants.supabaseAnnonKey,//'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ2dGVmcWRxYWhjcHpnb2x2dXB2Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3MTYwMjE2NTIsImV4cCI6MjAzMTU5NzY1Mn0.1bp5V61Oguo5zLUhCFJmCabUY1sujeISr_CR2XUKvh4',// ); - runApp(MyApp()); + var singleCategories = Categories.instance; + singleCategories.updateCategoryAmount('Ingosltadt'); + runApp( + ChangeNotifierProvider( + create: (context) => Categories.instance, + child: MyApp(), + ), + ); } /// Supabase client diff --git a/lib/screens/detail_widget.dart b/lib/screens/detail_widget.dart index d6aed57..9efa943 100644 --- a/lib/screens/detail_widget.dart +++ b/lib/screens/detail_widget.dart @@ -136,7 +136,8 @@ String extractTime24h(String timestamp) { // Dann den richtigen Eintrag in Data identifizieren udn die Farbe auswählen Color extractColor(String categoryID) { - final result = Data.recipes.where((recipe) => recipe.category == categoryID).firstOrNull; + var single_categories = Categories.instance; + final result = single_categories.categories.where((recipe) => recipe.category == categoryID).firstOrNull; Color categorie_color= Color.fromARGB(255, 255, 255, 255); if (result!=null) { diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 12ce2e6..7fbb8ed 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -3,11 +3,22 @@ import 'package:Emma_home/screens/details_db.dart'; import 'package:Emma_home/utils/data.dart'; import 'package:Emma_home/screens/subheader_Datepicker.dart'; import 'package:Emma_home/screens/detail_widget.dart'; +import 'package:provider/provider.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:Emma_home/main.dart'; +import 'package:Emma_home/utils/data.dart'; -class HomePage extends StatelessWidget { - const HomePage({super.key}); +class HomePage extends StatefulWidget { + @override + _HomePage createState() => _HomePage(); +} +class _HomePage extends State { + late Future _fetchDataFuture; + @override + void initState() { + super.initState(); + _fetchDataFuture = Categories.instance.updateCategoryAmount('Ingolstadt'); + } Future>> _loadData() async { final _data = await supabase.from('events').select(); @@ -84,12 +95,14 @@ class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { var size = MediaQuery.of(context).size; - + //var single_categories = Categories.instance; + //single_categories.updateCategoryAmount('Ingolstadt'); /*24 is for notification bar on Android*/ - final double itemHeight = (size.height - kToolbarHeight - 140) / 5; - final double itemWidth = size.width / 2.3; + final double itemHeight = (size.height - kToolbarHeight - 180) / 5; + final double itemWidth = (size.width-40)/ 2; MediaQueryData queryData; queryData = MediaQuery.of(context); + var appBar = AppBar( leading: SizedBox( height: 60, @@ -157,7 +170,9 @@ class HomePage extends StatelessWidget { flexibleSpace: Container(), ); var body = SafeArea( - child: Column( + child:Consumer( + builder: (context, single_categories, child) {return + Column( children: [ //Header Container //HeaderSection(), @@ -189,7 +204,7 @@ class HomePage extends StatelessWidget { itemHeight), // Anzahl der Spalten im Grid ), itemCount: - Data.recipes.length, // Anzahl der Elemente im Grid + single_categories.categories.length, // Anzahl der Elemente im Grid itemBuilder: (BuildContext context, int index) { return Padding( padding: const EdgeInsets.all(6.0), @@ -198,13 +213,13 @@ class HomePage extends StatelessWidget { /* List> events = await _loadData(); */ List> events2 = - await fetchEvents(Data.recipes[index].category); + await fetchEvents(single_categories.categories[index].category); Navigator.push( context, MaterialPageRoute( builder: (context) => Frame28( events: events2, - color: Data.recipes[index].color, + color: single_categories.categories[index].color, screen_size: queryData, ))); }, @@ -223,14 +238,14 @@ class HomePage extends StatelessWidget { decoration: ShapeDecoration( image: DecorationImage( image: - AssetImage(Data.recipes[index].imageUrl), + AssetImage(single_categories.categories[index].imageUrl), fit: BoxFit.cover, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8)), shadows: [ BoxShadow( - color: Data.recipes[index].color, + color: single_categories.categories[index].color, blurRadius: 0, offset: Offset(0, 10), spreadRadius: 0, @@ -243,7 +258,7 @@ class HomePage extends StatelessWidget { left: 16, top: 15, child: Text( - '64', + single_categories.categories[index].amount.toString(), style: TextStyle( color: Colors.white, fontSize: 18, @@ -255,14 +270,14 @@ class HomePage extends StatelessWidget { ), Positioned( left: 13, - top: Data.recipes[index].textheight, //86, //TODO Bootom? + top: single_categories.categories[index].textheight, //86, //TODO Bootom? child: Container( width: itemWidth-20,// Set a fixed width or use constraints child: Wrap( children: [ Text( - Data.recipes[index].title, + single_categories.categories[index].title, style: TextStyle( color: Colors.white, fontSize: 24, @@ -272,8 +287,6 @@ class HomePage extends StatelessWidget { ), ), ], ),), - - ), Positioned( right:20, @@ -283,7 +296,7 @@ class HomePage extends StatelessWidget { width: 32, height: 32, child: Image.asset( - Data.recipes[index].iconUrl, + single_categories.categories[index].iconUrl, ), ), ), @@ -299,53 +312,7 @@ class HomePage extends StatelessWidget { ), ], ), - ), - - /* Card( - color: Data.recipes[index].color, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(6.0), - ), - child: Container( - //width: (MediaQuery.of(context).size.width / 2), - //height: 20, - child: Column( - children: [ - Expanded( - child: ClipRRect( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(6.0), - topRight: Radius.circular(6.0), - ), - child: Hero( - tag: Data.recipes[index].id, - child: FadeInImage( - image: AssetImage( - Data.recipes[index].imageUrl, - ), - fit: BoxFit.cover, - placeholder: AssetImage( - 'assets/images/loading.gif', - ), - ), - ), - ), - ), - Text( - Data.recipes[index].title, - style: TextStyle( - color: Colors.white, - fontSize: 20, - fontWeight: FontWeight.bold), - ), - Padding( - padding: const EdgeInsets.all(1.0), - ), - ], - ), - ), - ), */ - ), + ), ), ); }, ), @@ -361,13 +328,14 @@ class HomePage extends StatelessWidget { ), ), ], - ), + );}) ); return Scaffold( backgroundColor: Colors.white, appBar: appBar, - body: body, + body: Consumer( + builder: (context, single_categories, child) {return body;}), ); } } diff --git a/lib/utils/class.dart b/lib/utils/class.dart index e30b551..30913ce 100644 --- a/lib/utils/class.dart +++ b/lib/utils/class.dart @@ -1,28 +1,21 @@ import 'dart:ui'; -class Nutrients { - String name; - String weight; - double percent; - Nutrients({required this.name, required this.weight, required this.percent}); -} -class Recipe { +class Category { String id, imageUrl, iconUrl,title,category; Color color; double? textheight; - //List steps; - //List ingredients; - //List nutrients; - Recipe( + int amount; + + Category( {required this.id, required this.title, required this.imageUrl, required this.iconUrl, - //required this.steps, - //required this.ingredients, - //required this.nutrients, required this.color, required this.category, - required this.textheight}); + required this.textheight, + required this.amount}); + + void add(Category category) {} } diff --git a/lib/utils/data.dart b/lib/utils/data.dart index d4ba072..d55a84a 100644 --- a/lib/utils/data.dart +++ b/lib/utils/data.dart @@ -8,9 +8,20 @@ import 'package:intl/intl.dart' as intl; import 'package:supabase_flutter/supabase_flutter.dart'; const Duration fakeAPIDuration = Duration(milliseconds: 50); const Duration debounceDuration = Duration(milliseconds: 50); -class Data { - static List recipes = [ - Recipe( + +class Categories extends ChangeNotifier{ + // Private constructor + Categories._privateConstructor(); + + // Static instance + static final Categories _instance = Categories._privateConstructor(); + + // Static method to access the instance + static Categories get instance => _instance; + + // Your singleton methods and properties + static List _categories = [ + Category( id: '1', title: 'Musik', imageUrl: 'assets/images/Musik.png', @@ -18,23 +29,9 @@ class Data { color: Color.fromARGB(255, 249, 171, 21), //FD4949 //Musik category: '34725c49-740b-45c5-8a51-7c742f92a621', textheight: 86, - /* nutrients: [ - Nutrients(name: 'Calories', weight: '200', percent: 0.7), - Nutrients(name: 'Protein', weight: '10gm', percent: 0.5), - Nutrients(name: 'Carb', weight: '50gm', percent: 0.9), - ], - steps: [ - 'Gather the ingredients.', - 'Pull a double shot of espresso into a cappuccino cup.', - 'Foam the milk to double its original volume.' - 'Top the espresso with foamed milk right after foaming. When initially poured, cappuccinos are only espresso and foam, but the liquid milk quickly settles out of the foam to create the (roughly) equal parts foam, steamed milk, and espresso for which cappuccino is known.', - 'Serve immediately.' - ], - ingredients: [ - '2 shots espresso (a double shot)', - '4 ounces milk' - ] */), - Recipe( + amount:0, + ), + Category( id: '2', title: 'Nachtleben', imageUrl: 'assets/images/Nachtleben.png', @@ -42,8 +39,9 @@ class Data { color: Color.fromARGB(255, 253, 73, 73), //FD4949 //Nachtleben category: '2d8c714e-3290-4d8c-8a95-e3b100ad8599', textheight: 86, + amount:0, ), - Recipe( + Category( id: '3', title: 'Kunst & Kultur', imageUrl: 'assets/images/Kultur.png', @@ -51,73 +49,128 @@ class Data { color: Color.fromARGB(255, 80, 168, 250), //50A8FA//Kunst category: '09d1f862-2b56-47af-8ee6-3c50056e3fa2', textheight: 58, + amount:0, ), - Recipe( + Category( id: '4', title: 'Sport & Verein', imageUrl: 'assets/images/Sport.png', iconUrl:'assets/images/Icons/Icon_Sport.png', color: Color.fromARGB(255, 80, 240, 250), //50F0FA //Sport category: '15119876-9ff0-41e5-8fe5-c3675af5e054', - textheight: 58, + textheight: 58, + amount:0, ), - Recipe( + Category( id: '5', title: 'Gesundheit', imageUrl: 'assets/images/Gesundheit.png', iconUrl:'assets/images/Icons/Icon_Gesundheit.png', color: Color.fromARGB(255,130, 73, 253), //8249FD //Gesundheit category: '4ad3ac2d-04fc-4aa1-afae-17ec7bfc1714', - textheight: 86, + textheight: 86, + amount:0, ), - Recipe( + Category( id: '6', title: 'Essen & Trinken', imageUrl: 'assets/images/Essen.png', iconUrl:'assets/images/Icons/Icon_Essen.png', color: Color.fromARGB(255,253, 73,73), //FD4949//Essen category: 'ef83c4d3-228a-44e1-8a5d-8b47d2dfc351', - textheight: 58, -), -Recipe( + textheight: 58, + amount:0, + ), + Category( id: '7', title: 'Soziales', imageUrl: 'assets/images/Soziales.png', iconUrl:'assets/images/Icons/Icon_Soziales.png', color: Color.fromARGB(255,255,0,199), //FF00C7//Essen category: '53a1782b-e07b-491d-b778-d99ef9cf57e2', - textheight: 86, + textheight: 86, + amount:0, ), - Recipe( + Category( id: '8', title: 'Familie', imageUrl: 'assets/images/Familie.png', iconUrl:'assets/images/Icons/Icon_Familie.png', color: Color.fromARGB(255,66,255,0), //42FF00//Essen //HSL 104 100 50 100 category: '30cb3481-c425-4068-9714-adc86df85d3f', - textheight: 86, + textheight: 86, + amount:0, ), ]; -//color: Color.fromARGB(255, 255, 0, 199), //FF00C7//Soziales - //color: Color.fromARGB(255, 66, 255, 0), //42FF00//Familie, + void addCategory(Category category) { + category.add(category); + notifyListeners(); + } - + void updateCategory(int index, Category updatedCategory) { + if (index >= 0 && index < _categories.length) { + _categories[index] = updatedCategory; + notifyListeners(); + } + } + + void removeCategory(int index) { + if (index >= 0 && index < _categories.length) { + _categories.removeAt(index); + notifyListeners(); + }} + + Future updateCategoryAmount (String cityName) async{ + try { + for (var index = 0; index < _categories.length; index++) { + final response = await supabase + .from("events") + .select( + 'id,name,main_category_id,location(name),event_category!inner(event_id)') + .eq('event_category.category_id', _categories[index].category); + var temp =(response.length); + _categories[index].amount= temp; + notifyListeners(); + + }return; } catch (e) { + throw Exception('Failed to fetch data: $e'); + } + return; } + // Method to get all items + List get categories => List.unmodifiable(_categories); + + // Method to clear all items + void clearItems() { + _categories.clear(); + } + + // Method to get item count + int get itemCount => _categories.length; +} + + class SupabaseDataService { + - Future>> fetchEvents(String cathegory) async { + Future>> fetchEvents(String category) async { try { + final today = DateTime.now().toUtc().toString().split(' ')[0]; final response = await supabase - .from("events") - .select('id,name,description,detail,subheader,location(name),time(startdate)') - .eq('category(id)',cathegory); - //select('id, name, cities(id, name)') - //find all events mit Ort und zusatzinfos die die Kathegorie haben welche ausgewählt wurde am heutigen Tag dann kommender Tag usw. + .from("events") + .select( + 'id,name,description,detail,subheader,main_category_id,location(name),time!inner(*),event_category!inner(event_id)') + .eq('event_category.category_id', category); + //.gte('time.start_date', DateTime.now().toIso8601String().split('T')[0]) // Beginn des heutigen Tages + //.lt('time.start_date', DateTime.now().add(Duration(days: 1)).toIso8601String().split('T')[0]); // Morgen; + //select('id, name, cities(id, name)') + //find all events mit Ort und zusatzinfos die die Kathegorie haben welche ausgewählt wurde am heutigen Tag dann kommender Tag usw. + //final test = response[0]['time'][0]['start_date']; return (response as List).cast>(); } catch (e) { throw Exception('Failed to fetch data: $e'); @@ -138,50 +191,6 @@ class SupabaseDataService { throw Exception('Failed to fetch record: $e'); } } - - /* Future insertData(String tableName, Map data) async { - try { - final response = await supabase - .from(tableName) - .insert(data); - - if (response.error != null) { - throw response.error!; - } - } catch (e) { - throw Exception('Failed to insert data: $e'); - } - } - - Future updateData(String tableName, String id, Map data) async { - try { - final response = await supabase - .from(tableName) - .update(data) - .eq('id', id); - - if (response.error != null) { - throw response.error!; - } - } catch (e) { - throw Exception('Failed to update data: $e'); - } - } - - Future deleteData(String tableName, String id) async { - try { - final response = await _supabase - .from(tableName) - .delete() - .eq('id', id); - - if (response.error != null) { - throw response.error!; - } - } catch (e) { - throw Exception('Failed to delete data: $e'); - } - } */ } /* class _AsyncAutocomplete extends StatefulWidget { const _AsyncAutocomplete(); diff --git a/lib/utils/widgets.dart b/lib/utils/widgets.dart deleted file mode 100644 index dfa1e48..0000000 --- a/lib/utils/widgets.dart +++ /dev/null @@ -1,92 +0,0 @@ -import 'dart:math'; -import 'package:flutter/material.dart'; -import 'package:Emma_home/utils/class.dart'; - -class CircleIndicator extends StatefulWidget { - final double percent; - final Nutrients nutrient; - - CircleIndicator({this.percent = 0.5, required this.nutrient}); - @override - _CircleIndicatorState createState() => _CircleIndicatorState(); -} - -class _CircleIndicatorState extends State - with SingleTickerProviderStateMixin { - double fraction = 0.0; - late Animation animation; - @override - void initState() { - super.initState(); - var controller = AnimationController( - duration: Duration(milliseconds: 1000), vsync: this); - - animation = Tween(begin: 0.0, end: widget.percent).animate(controller) - ..addListener(() { - setState(() { - fraction = animation.value; - }); - }); - - controller.forward(); - } - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.all(8.0), - child: Stack( - children: [ - Container( - width: 70, - height: 70, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - widget.nutrient.name, - style: TextStyle(color: Colors.white), - ), - Text( - widget.nutrient.weight, - style: TextStyle(color: Colors.white), - ), - ], - ), - ), - Container( - width: 70, - height: 70, - child: CustomPaint( - foregroundPainter: CirclePainter(fraction), - ), - ), - ], - ), - ); - } -} - -class CirclePainter extends CustomPainter { - late Paint _paint; - double _fraction; - - CirclePainter(this._fraction) { - _paint = Paint() - ..color = Color(0xff8DB646) - ..strokeWidth = 5.0 - ..strokeCap = StrokeCap.round - ..style = PaintingStyle.stroke; - } - - @override - void paint(Canvas canvas, Size size) { - var rect = Offset(0.0, 0.0) & size; - canvas.drawArc(rect, -pi / 2, pi * 2 * _fraction, false, _paint); - } - - @override - bool shouldRepaint(CirclePainter oldDelegate) { - return oldDelegate._fraction != _fraction; - } -} diff --git a/pubspec.lock b/pubspec.lock index b98a613..6979d9d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -368,6 +368,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.5" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" path: dependency: transitive description: @@ -448,6 +456,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.0" + provider: + dependency: "direct main" + description: + name: provider + sha256: c8a055ee5ce3fd98d6fc872478b03823ffdb448699c6ebdbbc71d59b596fd48c + url: "https://pub.dev" + source: hosted + version: "6.1.2" realtime_client: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 669fbaa..46ec23a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -38,6 +38,7 @@ dependencies: supabase_flutter: ^2.7.0 timeago: ^3.1.0 image_picker: ^1.1.2 + provider: ^6.0.5 dev_dependencies: