Favoriten hinzufügen ermöglicht

main
joschy2002 2025-05-21 12:09:41 +02:00
parent 59b13d21e2
commit a15259ecd2
4 changed files with 126 additions and 199 deletions

View File

@ -17,9 +17,9 @@ class _CalendarTabState extends State<CalendarTab> {
@override
void initState() {
super.initState();
_selectedDay = DateTime.now();
final now = DateTime.now();
_focusedDay = DateTime(now.year, now.month, now.day);
_selectedDay = _focusedDay;
// Beispiel-Events
_events = {
@ -43,8 +43,8 @@ class _CalendarTabState extends State<CalendarTab> {
@override
Widget build(BuildContext context) {
final firstDay = DateTime.utc(2024, 1, 1);
final lastDay = DateTime.utc(2024, 12, 31);
final firstDay = DateTime.utc(1900, 1, 1);
final lastDay = DateTime.utc(2999, 12, 31);
if (_focusedDay.isBefore(firstDay)) {
_focusedDay = firstDay;

View File

@ -1,179 +1,98 @@
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
class FavoritesTab extends StatelessWidget {
const FavoritesTab({super.key});
@override
Widget build(BuildContext context) {
// Beispiel-Daten für favorisierte Trainings
final List<Map<String, dynamic>> favoriteWorkouts = [
{
'title': 'Ganzkörper Workout',
'duration': '45 Minuten',
'level': 'Fortgeschritten',
'category': 'Krafttraining',
'isFavorite': true,
},
{
'title': 'Yoga Flow',
'duration': '30 Minuten',
'level': 'Anfänger',
'category': 'Yoga',
'isFavorite': true,
},
{
'title': 'HIIT Session',
'duration': '20 Minuten',
'level': 'Mittel',
'category': 'HIIT',
'isFavorite': true,
},
];
final user = FirebaseAuth.instance.currentUser;
if (user == null) {
return const Center(child: Text('Nicht eingeloggt'));
}
return Scaffold(
appBar: AppBar(
title: const Text('Favoriten'),
actions: [
IconButton(
icon: const Icon(Icons.sort),
onPressed: () {
// TODO: Implement sorting functionality
},
),
],
),
body:
favoriteWorkouts.isEmpty
? const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.favorite_border, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text(
'Noch keine Favoriten',
style: TextStyle(fontSize: 18, color: Colors.grey),
),
SizedBox(height: 8),
Text(
'Füge Trainings zu deinen Favoriten hinzu',
style: TextStyle(fontSize: 14, color: Colors.grey),
),
],
),
)
: ListView.builder(
padding: const EdgeInsets.all(16),
itemCount: favoriteWorkouts.length,
body: StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance.collection('User').doc(user.uid).snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (!snapshot.hasData || !snapshot.data!.exists) {
return const Center(child: Text('Keine Favoriten gefunden'));
}
final data = snapshot.data!.data() as Map<String, dynamic>;
final favorites = List<String>.from(data['favorites'] ?? []);
if (favorites.isEmpty) {
return const Center(child: Text('Keine Favoriten gefunden'));
}
return ListView.builder(
itemCount: favorites.length,
itemBuilder: (context, index) {
final workout = favoriteWorkouts[index];
return FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance.collection('Training').doc(favorites[index]).get(),
builder: (context, trainingSnapshot) {
if (!trainingSnapshot.hasData || !trainingSnapshot.data!.exists) {
return const ListTile(title: Text('Training nicht gefunden'));
}
final trainingData = trainingSnapshot.data!.data() as Map<String, dynamic>;
return Card(
margin: const EdgeInsets.only(bottom: 16),
child: InkWell(
onTap: () {
// TODO: Navigate to workout details
},
margin: const EdgeInsets.all(8.0),
child: Padding(
padding: const EdgeInsets.all(16),
child: Row(
children: [
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(8),
),
child: const Icon(
Icons.fitness_center,
size: 32,
color: Colors.grey,
),
),
const SizedBox(width: 16),
Expanded(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
workout['title'],
trainingData['title'] ?? 'Unbekannt',
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 4),
const SizedBox(height: 8),
Text(
workout['duration'],
trainingData['description'] ?? 'Keine Beschreibung',
style: TextStyle(color: Colors.grey[600]),
),
const SizedBox(height: 4),
const SizedBox(height: 8),
Text(
'Dauer: ${trainingData['duration'] ?? '-'} Minuten',
style: TextStyle(color: Colors.grey[600]),
),
const SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
),
decoration: BoxDecoration(
color: Colors.blue[100],
borderRadius: BorderRadius.circular(
12,
),
),
child: Text(
workout['level'],
style: TextStyle(
color: Colors.blue[700],
fontSize: 12,
),
),
),
const SizedBox(width: 8),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 8,
vertical: 4,
),
decoration: BoxDecoration(
color: Colors.green[100],
borderRadius: BorderRadius.circular(
12,
),
),
child: Text(
workout['category'],
style: TextStyle(
color: Colors.green[700],
fontSize: 12,
),
),
),
],
),
],
),
Text(
'Level: ${trainingData['year'] ?? '-'}',
style: TextStyle(color: Colors.grey[600]),
),
IconButton(
icon: Icon(
workout['isFavorite']
? Icons.favorite
: Icons.favorite_border,
color:
workout['isFavorite']
? Colors.red
: Colors.grey,
),
onPressed: () {
// TODO: Implement favorite toggle
icon: const Icon(Icons.favorite, color: Colors.red),
onPressed: () async {
await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
'favorites': FieldValue.arrayRemove([favorites[index]]),
});
},
),
],
),
],
),
),
);
},
);
},
);
},
),
);
}

View File

@ -76,25 +76,6 @@ class ProfileTab extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildInfoCard(
title: 'Statistiken',
child: Column(
children: [
_buildStatisticRow(
'Trainings absolviert',
userData['workoutsCompleted'].toString(),
Icons.fitness_center,
),
const Divider(),
_buildStatisticRow(
'Gesamtzeit',
'${userData['totalMinutes']} Minuten',
Icons.timer,
),
],
),
),
const SizedBox(height: 16),
_buildInfoCard(
title: 'Persönliche Informationen',
child: Column(
@ -183,20 +164,6 @@ class ProfileTab extends StatelessWidget {
);
}
Widget _buildStatisticRow(String label, String value, IconData icon) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),
child: Row(
children: [
Icon(icon, color: Colors.blue),
const SizedBox(width: 16),
Expanded(child: Text(label)),
Text(value, style: const TextStyle(fontWeight: FontWeight.bold)),
],
),
);
}
Widget _buildInfoRow(String label, String value, IconData icon) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0),

View File

@ -12,17 +12,18 @@ class SearchTab extends StatefulWidget {
class _SearchTabState extends State<SearchTab> {
final TextEditingController _searchController = TextEditingController();
final List<String> _categories = [
'Krafttraining',
'Ausdauer',
'Yoga',
'HIIT',
'Mobility',
'Rehabilitation',
'Aufwärmen & Mobilisation',
'Wurf- & Torabschluss',
'Torwarttraining',
'Athletik',
'Pass',
'Koordination',
];
String? _selectedCategory;
String _searchTerm = '';
bool _isTrainer = false;
bool _trainerChecked = false;
Set<String> _favorites = {};
@override
void initState() {
@ -33,6 +34,7 @@ class _SearchTabState extends State<SearchTab> {
});
});
_checkIfTrainer();
_loadFavorites();
}
Future<void> _checkIfTrainer() async {
@ -45,6 +47,18 @@ class _SearchTabState extends State<SearchTab> {
});
}
Future<void> _loadFavorites() async {
final user = FirebaseAuth.instance.currentUser;
if (user == null) return;
final doc = await FirebaseFirestore.instance.collection('User').doc(user.uid).get();
final data = doc.data();
if (data != null && data['favorites'] != null) {
setState(() {
_favorites = Set<String>.from(data['favorites']);
});
}
}
void _showCreateTrainingDialog() {
showDialog(
context: context,
@ -52,6 +66,21 @@ class _SearchTabState extends State<SearchTab> {
).then((_) => setState(() {})); // Refresh nach Hinzufügen
}
Future<void> _toggleFavorite(String trainingId, bool isFavorite) async {
final user = FirebaseAuth.instance.currentUser;
if (user == null) return;
if (isFavorite) {
await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
'favorites': FieldValue.arrayRemove([trainingId]),
});
} else {
await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
'favorites': FieldValue.arrayUnion([trainingId]),
});
}
await _loadFavorites(); // Aktualisiere die Favoriten nach dem Toggle
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -148,6 +177,7 @@ class _SearchTabState extends State<SearchTab> {
),
delegate: SliverChildBuilderDelegate((context, index) {
final data = docs[index].data() as Map<String, dynamic>;
final isFavorite = _favorites.contains(docs[index].id);
return Card(
clipBehavior: Clip.antiAlias,
child: Column(
@ -207,6 +237,17 @@ class _SearchTabState extends State<SearchTab> {
),
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),
),
),
],
),
),