From 402c9a88358d6eac1d3a42da8e33c8bd010123a5 Mon Sep 17 00:00:00 2001 From: joschy2002 Date: Wed, 21 May 2025 12:21:00 +0200 Subject: [PATCH] Training kann nun angeklickt werden --- trainerbox/lib/screens/favorites_tab.dart | 91 ++++++----- trainerbox/lib/screens/search_tab.dart | 153 ++++++++++-------- .../lib/screens/training_detail_screen.dart | 78 +++++++++ 3 files changed, 211 insertions(+), 111 deletions(-) create mode 100644 trainerbox/lib/screens/training_detail_screen.dart diff --git a/trainerbox/lib/screens/favorites_tab.dart b/trainerbox/lib/screens/favorites_tab.dart index 93a4b49..d2e2eef 100644 --- a/trainerbox/lib/screens/favorites_tab.dart +++ b/trainerbox/lib/screens/favorites_tab.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'training_detail_screen.dart'; class FavoritesTab extends StatelessWidget { const FavoritesTab({super.key}); @@ -44,47 +45,57 @@ class FavoritesTab extends StatelessWidget { final trainingData = trainingSnapshot.data!.data() as Map; return Card( margin: const EdgeInsets.all(8.0), - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - trainingData['title'] ?? 'Unbekannt', - style: const TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, + child: InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TrainingDetailScreen(trainingId: favorites[index]), + ), + ); + }, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + trainingData['title'] ?? 'Unbekannt', + style: const TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), ), - ), - const SizedBox(height: 8), - Text( - trainingData['description'] ?? 'Keine Beschreibung', - style: TextStyle(color: Colors.grey[600]), - ), - const SizedBox(height: 8), - Text( - 'Dauer: ${trainingData['duration'] ?? '-'} Minuten', - style: TextStyle(color: Colors.grey[600]), - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - 'Level: ${trainingData['year'] ?? '-'}', - style: TextStyle(color: Colors.grey[600]), - ), - IconButton( - icon: const Icon(Icons.favorite, color: Colors.red), - onPressed: () async { - await FirebaseFirestore.instance.collection('User').doc(user.uid).update({ - 'favorites': FieldValue.arrayRemove([favorites[index]]), - }); - }, - ), - ], - ), - ], + const SizedBox(height: 8), + Text( + trainingData['description'] ?? 'Keine Beschreibung', + style: TextStyle(color: Colors.grey[600]), + ), + const SizedBox(height: 8), + Text( + 'Dauer: ${trainingData['duration'] ?? '-'} Minuten', + style: TextStyle(color: Colors.grey[600]), + ), + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + 'Level: ${trainingData['year'] ?? '-'}', + style: TextStyle(color: Colors.grey[600]), + ), + IconButton( + icon: const Icon(Icons.favorite, color: Colors.red), + onPressed: () async { + await FirebaseFirestore.instance.collection('User').doc(user.uid).update({ + 'favorites': FieldValue.arrayRemove([favorites[index]]), + }); + }, + ), + ], + ), + ], + ), ), ), ); diff --git a/trainerbox/lib/screens/search_tab.dart b/trainerbox/lib/screens/search_tab.dart index a474a04..81eaf08 100644 --- a/trainerbox/lib/screens/search_tab.dart +++ b/trainerbox/lib/screens/search_tab.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'training_detail_screen.dart'; class SearchTab extends StatefulWidget { const SearchTab({super.key}); @@ -180,78 +181,88 @@ class _SearchTabState extends State { final isFavorite = _favorites.contains(docs[index].id); return Card( clipBehavior: Clip.antiAlias, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Expanded( - child: (data['picture'] is String && data['picture'] != '') - ? Image.network( - data['picture'], - width: double.infinity, - fit: BoxFit.cover, - ) - : Container( - color: Colors.grey[300], - child: const Center( - child: Icon(Icons.fitness_center, size: 40), - ), - ), - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - data['title'] ?? '-', - style: const TextStyle( - fontWeight: FontWeight.bold, - fontSize: 16, - ), - ), - const SizedBox(height: 4), - Text( - data['description'] ?? '-', - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Colors.grey[600], - fontSize: 13, - ), - ), - const SizedBox(height: 4), - Text( - '${data['duration'] ?? '-'} Minuten', - style: TextStyle( - color: Colors.grey[600], - fontSize: 13, - ), - ), - const SizedBox(height: 4), - Row( - children: [ - const Icon(Icons.star, size: 16, color: Colors.amber), - const SizedBox(width: 4), - Text('${data['rating overall'] ?? '-'}'), - ], - ), - const SizedBox(height: 4), - Text('Level: ${data['year'] ?? '-'}'), - const SizedBox(height: 4), - Align( - alignment: Alignment.bottomRight, - child: IconButton( - icon: Icon( - isFavorite ? Icons.favorite : Icons.favorite_border, - color: isFavorite ? Colors.red : null, - ), - onPressed: () => _toggleFavorite(docs[index].id, isFavorite), - ), - ), - ], + child: InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => TrainingDetailScreen(trainingId: docs[index].id), ), - ), - ], + ); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Expanded( + child: (data['picture'] is String && data['picture'] != '') + ? Image.network( + data['picture'], + width: double.infinity, + fit: BoxFit.cover, + ) + : Container( + color: Colors.grey[300], + child: const Center( + child: Icon(Icons.fitness_center, size: 40), + ), + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + data['title'] ?? '-', + style: const TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + const SizedBox(height: 4), + Text( + data['description'] ?? '-', + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.grey[600], + fontSize: 13, + ), + ), + const SizedBox(height: 4), + Text( + '${data['duration'] ?? '-'} Minuten', + style: TextStyle( + color: Colors.grey[600], + fontSize: 13, + ), + ), + const SizedBox(height: 4), + Row( + children: [ + const Icon(Icons.star, size: 16, color: Colors.amber), + const SizedBox(width: 4), + Text('${data['rating overall'] ?? '-'}'), + ], + ), + const SizedBox(height: 4), + Text('Level: ${data['year'] ?? '-'}'), + const SizedBox(height: 4), + Align( + alignment: Alignment.bottomRight, + child: IconButton( + icon: Icon( + isFavorite ? Icons.favorite : Icons.favorite_border, + color: isFavorite ? Colors.red : null, + ), + onPressed: () => _toggleFavorite(docs[index].id, isFavorite), + ), + ), + ], + ), + ), + ], + ), ), ); }, childCount: docs.length), diff --git a/trainerbox/lib/screens/training_detail_screen.dart b/trainerbox/lib/screens/training_detail_screen.dart new file mode 100644 index 0000000..99f358c --- /dev/null +++ b/trainerbox/lib/screens/training_detail_screen.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; + +class TrainingDetailScreen extends StatelessWidget { + final String trainingId; + + const TrainingDetailScreen({super.key, required this.trainingId}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Training Details'), + ), + body: FutureBuilder( + future: FirebaseFirestore.instance.collection('Training').doc(trainingId).get(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } + if (!snapshot.hasData || !snapshot.data!.exists) { + return const Center(child: Text('Training nicht gefunden')); + } + final data = snapshot.data!.data() as Map; + return SingleChildScrollView( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + height: 200, + color: Colors.grey[300], + child: const Center( + child: Icon(Icons.image, size: 64, color: Colors.grey), + ), + ), + const SizedBox(height: 16), + Text( + data['title'] ?? 'Unbekannt', + style: const TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox(height: 8), + Text( + data['description'] ?? 'Keine Beschreibung', + style: TextStyle(color: Colors.grey[600]), + ), + const SizedBox(height: 16), + Text( + 'Dauer: ${data['duration'] ?? '-'} Minuten', + style: TextStyle(color: Colors.grey[600]), + ), + const SizedBox(height: 8), + Text( + 'Level: ${data['year'] ?? '-'}', + style: TextStyle(color: Colors.grey[600]), + ), + const SizedBox(height: 8), + Text( + 'Bewertung: ${data['rating overall'] ?? '-'}', + style: TextStyle(color: Colors.grey[600]), + ), + const SizedBox(height: 8), + Text( + 'Kategorie: ${data['category'] ?? '-'}', + style: TextStyle(color: Colors.grey[600]), + ), + ], + ), + ); + }, + ), + ); + } +} \ No newline at end of file