Warnung bei Wiederholenden Übungen
parent
fb3b9027c5
commit
0923b85a20
|
|
@ -127,12 +127,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
final trainingTimes = trainerData['trainingTimes'] as Map<String, dynamic>? ?? {};
|
final trainingTimes = trainerData['trainingTimes'] as Map<String, dynamic>? ?? {};
|
||||||
final trainingDurations = trainerData['trainingDurations'] as Map<String, dynamic>? ?? {};
|
final trainingDurations = trainerData['trainingDurations'] as Map<String, dynamic>? ?? {};
|
||||||
|
|
||||||
print('Lade Events:');
|
|
||||||
print('trainings: $trainings');
|
|
||||||
print('cancelledTrainings: $cancelledTrainings');
|
|
||||||
print('trainingTimes: $trainingTimes');
|
|
||||||
print('trainingDurations: $trainingDurations');
|
|
||||||
|
|
||||||
// Lade alle Trainings für das Datum
|
// Lade alle Trainings für das Datum
|
||||||
trainings.forEach((dateString, trainingsList) {
|
trainings.forEach((dateString, trainingsList) {
|
||||||
final date = DateTime.tryParse(dateString);
|
final date = DateTime.tryParse(dateString);
|
||||||
|
|
@ -191,8 +185,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
.map((cancelled) => DateTime.parse((cancelled as Map<String, dynamic>)['date'] as String))
|
.map((cancelled) => DateTime.parse((cancelled as Map<String, dynamic>)['date'] as String))
|
||||||
.toSet();
|
.toSet();
|
||||||
|
|
||||||
print('Gecancelte Daten: $cancelledDates');
|
|
||||||
|
|
||||||
trainingTimes.forEach((day, timeStr) {
|
trainingTimes.forEach((day, timeStr) {
|
||||||
if (timeStr == null) return;
|
if (timeStr == null) return;
|
||||||
final timeParts = (timeStr as String).split(':');
|
final timeParts = (timeStr as String).split(':');
|
||||||
|
|
@ -252,7 +244,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error loading events: $e');
|
|
||||||
setState(() => _isLoading = false);
|
setState(() => _isLoading = false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -273,39 +264,84 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
// Wenn eine Übung ausgewählt wurde
|
// Wenn eine Übung ausgewählt wurde
|
||||||
if (result != null && result is Map<String, dynamic>) {
|
if (result != null && result is Map<String, dynamic>) {
|
||||||
try {
|
try {
|
||||||
print('Übung ausgewählt:');
|
|
||||||
print('ID: ${result['id']}');
|
|
||||||
print('Titel: ${result['title']}');
|
|
||||||
print('Vollständige Übungsdaten: $result');
|
|
||||||
|
|
||||||
bool shouldAddExercise = true;
|
bool shouldAddExercise = true;
|
||||||
|
|
||||||
// Prüfe die Bewertungen der Übung in der Training-Collection
|
// Prüfe die Bewertungen der Übung in der Training-Collection
|
||||||
print('Suche Übung in der Datenbank...');
|
|
||||||
final exerciseDoc = await FirebaseFirestore.instance
|
final exerciseDoc = await FirebaseFirestore.instance
|
||||||
.collection('Training')
|
.collection('Training')
|
||||||
.doc(result['id'])
|
.doc(result['id'])
|
||||||
.get();
|
.get();
|
||||||
|
|
||||||
print('Übungsdokument gefunden: ${exerciseDoc.exists}');
|
// NEU: Prüfe, ob die Übung in den letzten 4 Wochen schon einmal durchgeführt wurde
|
||||||
print('Collection-Pfad: Training/${result['id']}');
|
final userDocForCheck = await FirebaseFirestore.instance
|
||||||
|
.collection('User')
|
||||||
|
.doc(_currentUserId)
|
||||||
|
.get();
|
||||||
|
if (userDocForCheck.exists) {
|
||||||
|
final userData = userDocForCheck.data() as Map<String, dynamic>;
|
||||||
|
final trainings = Map<String, dynamic>.from(userData['trainings'] ?? {});
|
||||||
|
final trainingDate = DateTime.tryParse(event['date'] as String) ?? DateTime.now();
|
||||||
|
final fourWeeksAgo = trainingDate.subtract(const Duration(days: 28));
|
||||||
|
bool foundInLast4Weeks = false;
|
||||||
|
trainings.forEach((dateString, trainingsList) {
|
||||||
|
final date = DateTime.tryParse(dateString);
|
||||||
|
// Prüfe: im Zeitraum [fourWeeksAgo, trainingDate) (also vor dem aktuellen Training)
|
||||||
|
if (date != null && date.isAfter(fourWeeksAgo) && date.isBefore(trainingDate)) {
|
||||||
|
final list = List<Map<String, dynamic>>.from(trainingsList);
|
||||||
|
for (final training in list) {
|
||||||
|
final exercises = List<Map<String, dynamic>>.from(training['exercises'] ?? []);
|
||||||
|
for (final exercise in exercises) {
|
||||||
|
if (exercise['id'] == result['id']) {
|
||||||
|
foundInLast4Weeks = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (foundInLast4Weeks) {
|
||||||
|
shouldAddExercise = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
barrierDismissible: false,
|
||||||
|
builder: (context) => AlertDialog(
|
||||||
|
title: const Text('Übung kürzlich verwendet'),
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text('Die Übung "${result['title']}" wurde in den 4 Wochen vor diesem Training bereits durchgeführt.'),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
const Text('Möchten Sie diese Übung trotzdem zu Ihrem Training hinzufügen?'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, false),
|
||||||
|
child: const Text('Abbrechen'),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, true),
|
||||||
|
child: const Text('Trotzdem hinzufügen'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
) ?? false;
|
||||||
|
if (!shouldAddExercise) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (exerciseDoc.exists) {
|
if (exerciseDoc.exists) {
|
||||||
final exerciseData = exerciseDoc.data() as Map<String, dynamic>;
|
final exerciseData = exerciseDoc.data() as Map<String, dynamic>;
|
||||||
print('Übungsdaten: $exerciseData');
|
|
||||||
|
|
||||||
// Versuche die Bewertungen aus verschiedenen möglichen Feldern zu lesen
|
// Versuche die Bewertungen aus verschiedenen möglichen Feldern zu lesen
|
||||||
List<Map<String, dynamic>> ratings = [];
|
List<Map<String, dynamic>> ratings = [];
|
||||||
if (exerciseData.containsKey('ratings')) {
|
if (exerciseData.containsKey('ratings')) {
|
||||||
ratings = List<Map<String, dynamic>>.from(exerciseData['ratings'] ?? []);
|
ratings = List<Map<String, dynamic>>.from(exerciseData['ratings'] ?? []);
|
||||||
print('Bewertungen aus Feld "ratings" gefunden: $ratings');
|
|
||||||
} else if (exerciseData.containsKey('rating')) {
|
} else if (exerciseData.containsKey('rating')) {
|
||||||
ratings = List<Map<String, dynamic>>.from(exerciseData['rating'] ?? []);
|
ratings = List<Map<String, dynamic>>.from(exerciseData['rating'] ?? []);
|
||||||
print('Bewertungen aus Feld "rating" gefunden: $ratings');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Gefundene Bewertungen: $ratings');
|
|
||||||
|
|
||||||
if (ratings.isNotEmpty) {
|
if (ratings.isNotEmpty) {
|
||||||
// Berechne den Durchschnitt der Bewertungen
|
// Berechne den Durchschnitt der Bewertungen
|
||||||
double totalRating = 0;
|
double totalRating = 0;
|
||||||
|
|
@ -316,13 +352,10 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
}
|
}
|
||||||
final averageRating = totalRating / ratings.length;
|
final averageRating = totalRating / ratings.length;
|
||||||
|
|
||||||
print('Durchschnittliche Bewertung: $averageRating');
|
|
||||||
|
|
||||||
// Wenn die durchschnittliche Bewertung unter 3 liegt, zeige eine Warnung
|
// Wenn die durchschnittliche Bewertung unter 3 liegt, zeige eine Warnung
|
||||||
if (averageRating < 3) {
|
if (averageRating < 3) {
|
||||||
print('Zeige Warnung für schlechte Bewertung');
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
shouldAddExercise = await showDialog<bool>(
|
showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (context) => AlertDialog(
|
builder: (context) => AlertDialog(
|
||||||
|
|
@ -348,21 +381,12 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
) ?? false;
|
) ?? false;
|
||||||
|
|
||||||
print('Benutzer hat entschieden: ${shouldAddExercise ? "Hinzufügen" : "Abbrechen"}');
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
print('Bewertung ist gut genug, keine Warnung nötig');
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
print('Keine Bewertungen vorhanden');
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
print('Warnung: Übungsdokument nicht gefunden');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shouldAddExercise) {
|
if (!shouldAddExercise) {
|
||||||
print('Übung wird nicht hinzugefügt (Benutzer hat abgebrochen)');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -379,38 +403,53 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
final dateString = event['date'] as String;
|
final dateString = event['date'] as String;
|
||||||
final trainingId = event['id'] as String;
|
final trainingId = event['id'] as String;
|
||||||
|
|
||||||
print('Füge Übung zum Training hinzu:');
|
final newExerciseData = {
|
||||||
print('dateString: $dateString');
|
|
||||||
print('trainingId: $trainingId');
|
|
||||||
print('Vorher - trainings: $trainings');
|
|
||||||
|
|
||||||
// Finde das Training und füge die Übung hinzu
|
|
||||||
if (trainings.containsKey(dateString)) {
|
|
||||||
final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString]);
|
|
||||||
final trainingIndex = trainingsList.indexWhere((t) => t['id'] == trainingId);
|
|
||||||
|
|
||||||
if (trainingIndex != -1) {
|
|
||||||
final exercises = List<Map<String, dynamic>>.from(trainingsList[trainingIndex]['exercises'] ?? []);
|
|
||||||
exercises.add({
|
|
||||||
'id': result['id'],
|
'id': result['id'],
|
||||||
'name': result['title'],
|
'name': result['title'],
|
||||||
'description': result['description'],
|
'description': result['description'],
|
||||||
'duration': result['duration'],
|
'duration': result['duration'],
|
||||||
|
};
|
||||||
|
|
||||||
|
final trainingsForDay = List<Map<String, dynamic>>.from(trainings[dateString] ?? []);
|
||||||
|
final trainingIndex = trainingsForDay.indexWhere((t) => t['id'] == trainingId);
|
||||||
|
|
||||||
|
String finalTrainingId = trainingId;
|
||||||
|
|
||||||
|
if (trainingIndex != -1) {
|
||||||
|
// Fall 1: Training ist bereits spezifisch, füge die Übung hinzu
|
||||||
|
final exercises = List<Map<String, dynamic>>.from(trainingsForDay[trainingIndex]['exercises'] ?? []);
|
||||||
|
exercises.add(newExerciseData);
|
||||||
|
trainingsForDay[trainingIndex]['exercises'] = exercises;
|
||||||
|
} else {
|
||||||
|
// Fall 2: Training ist wiederkehrend, erstelle eine neue spezifische Instanz
|
||||||
|
final newId = const Uuid().v4();
|
||||||
|
finalTrainingId = newId;
|
||||||
|
trainingsForDay.add({
|
||||||
|
'id': newId,
|
||||||
|
'time': event['time'],
|
||||||
|
'duration': event['duration'],
|
||||||
|
'exercises': [newExerciseData],
|
||||||
});
|
});
|
||||||
trainingsList[trainingIndex]['exercises'] = exercises;
|
|
||||||
trainings[dateString] = trainingsList;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Nachher - trainings: $trainings');
|
trainings[dateString] = trainingsForDay;
|
||||||
|
|
||||||
|
final updates = <String, dynamic>{'trainings': trainings};
|
||||||
|
|
||||||
|
// Wenn das Original-Event wiederkehrend war, unterdrücke es für diesen Tag
|
||||||
|
if (trainingId.startsWith('weekly_')) {
|
||||||
|
final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);
|
||||||
|
if (!cancelledTrainings.any((c) => c['date'] == dateString)) {
|
||||||
|
cancelledTrainings.add({'date': dateString});
|
||||||
|
updates['cancelledTrainings'] = cancelledTrainings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Aktualisiere die Datenbank
|
// Aktualisiere die Datenbank
|
||||||
await FirebaseFirestore.instance
|
await FirebaseFirestore.instance
|
||||||
.collection('User')
|
.collection('User')
|
||||||
.doc(_currentUserId)
|
.doc(_currentUserId)
|
||||||
.update({
|
.update(updates);
|
||||||
'trainings': trainings,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Aktualisiere die UI sofort
|
// Aktualisiere die UI sofort
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -418,17 +457,16 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
if (_events.containsKey(normalizedDate)) {
|
if (_events.containsKey(normalizedDate)) {
|
||||||
final eventIndex = _events[normalizedDate]!.indexWhere((e) => e['id'] == trainingId);
|
final eventIndex = _events[normalizedDate]!.indexWhere((e) => e['id'] == trainingId);
|
||||||
if (eventIndex != -1) {
|
if (eventIndex != -1) {
|
||||||
final exercises = List<Map<String, dynamic>>.from(_events[normalizedDate]![eventIndex]['exercises'] ?? []);
|
final oldEvent = _events[normalizedDate]![eventIndex];
|
||||||
exercises.add({
|
final exercises = List<Map<String, dynamic>>.from(oldEvent['exercises'] ?? []);
|
||||||
'id': result['id'],
|
exercises.add(newExerciseData);
|
||||||
'name': result['title'],
|
|
||||||
'description': result['description'],
|
oldEvent['exercises'] = exercises;
|
||||||
'duration': result['duration'],
|
oldEvent['remainingTime'] = (oldEvent['duration'] as int) - exercises.fold<int>(0, (sum, exercise) => sum + (exercise['duration'] as int));
|
||||||
});
|
|
||||||
_events[normalizedDate]![eventIndex]['exercises'] = exercises;
|
if (trainingId.startsWith('weekly_')) {
|
||||||
_events[normalizedDate]![eventIndex]['remainingTime'] =
|
oldEvent['id'] = finalTrainingId;
|
||||||
(_events[normalizedDate]![eventIndex]['duration'] as int) -
|
}
|
||||||
exercises.fold<int>(0, (sum, exercise) => sum + (exercise['duration'] as int));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -439,7 +477,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error adding exercise: $e');
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Fehler beim Hinzufügen der Übung')),
|
const SnackBar(content: Text('Fehler beim Hinzufügen der Übung')),
|
||||||
|
|
@ -460,12 +497,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
final trainingId = event['id'] as String?;
|
final trainingId = event['id'] as String?;
|
||||||
final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);
|
final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);
|
||||||
|
|
||||||
print('Lösche Training:');
|
|
||||||
print('dateString: $dateString');
|
|
||||||
print('trainingId: $trainingId');
|
|
||||||
print('Vorher - trainings: $trainings');
|
|
||||||
print('Vorher - cancelledTrainings: $cancelledTrainings');
|
|
||||||
|
|
||||||
// Wenn es sich um ein regelmäßiges Training handelt (ID beginnt mit 'weekly_')
|
// Wenn es sich um ein regelmäßiges Training handelt (ID beginnt mit 'weekly_')
|
||||||
if (trainingId != null && trainingId.startsWith('weekly_')) {
|
if (trainingId != null && trainingId.startsWith('weekly_')) {
|
||||||
// Füge das Datum zu cancelledTrainings hinzu, wenn es noch nicht existiert
|
// Füge das Datum zu cancelledTrainings hinzu, wenn es noch nicht existiert
|
||||||
|
|
@ -517,9 +548,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Nachher - trainings: $trainings');
|
|
||||||
print('Nachher - cancelledTrainings: $cancelledTrainings');
|
|
||||||
|
|
||||||
// Aktualisiere die Datenbank
|
// Aktualisiere die Datenbank
|
||||||
final updates = <String, dynamic>{};
|
final updates = <String, dynamic>{};
|
||||||
|
|
||||||
|
|
@ -557,7 +585,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error deleting training: $e');
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Fehler beim Löschen des Trainings')),
|
const SnackBar(content: Text('Fehler beim Löschen des Trainings')),
|
||||||
|
|
@ -582,11 +609,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
final dateString = event['date'] as String;
|
final dateString = event['date'] as String;
|
||||||
final trainingId = event['id'] as String;
|
final trainingId = event['id'] as String;
|
||||||
|
|
||||||
print('Entferne Übung:');
|
|
||||||
print('dateString: $dateString');
|
|
||||||
print('trainingId: $trainingId');
|
|
||||||
print('Vorher - trainings: $trainings');
|
|
||||||
|
|
||||||
// Finde das Training und entferne die Übung
|
// Finde das Training und entferne die Übung
|
||||||
if (trainings.containsKey(dateString)) {
|
if (trainings.containsKey(dateString)) {
|
||||||
final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString]);
|
final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString]);
|
||||||
|
|
@ -600,8 +622,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Nachher - trainings: $trainings');
|
|
||||||
|
|
||||||
// Aktualisiere die Datenbank
|
// Aktualisiere die Datenbank
|
||||||
await FirebaseFirestore.instance
|
await FirebaseFirestore.instance
|
||||||
.collection('User')
|
.collection('User')
|
||||||
|
|
@ -632,7 +652,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error removing exercise: $e');
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Fehler beim Entfernen der Übung')),
|
const SnackBar(content: Text('Fehler beim Entfernen der Übung')),
|
||||||
|
|
@ -1068,12 +1087,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);
|
final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);
|
||||||
final trainingTimes = data['trainingTimes'] as Map<String, dynamic>? ?? {};
|
final trainingTimes = data['trainingTimes'] as Map<String, dynamic>? ?? {};
|
||||||
|
|
||||||
print('Füge/Bearbeite Training:');
|
|
||||||
print('dateString: $dateString');
|
|
||||||
print('trainingId: $trainingId');
|
|
||||||
print('Vorher - trainings: $trainings');
|
|
||||||
print('Vorher - cancelledTrainings: $cancelledTrainings');
|
|
||||||
|
|
||||||
// Trainingsliste für das Datum holen oder neu anlegen
|
// Trainingsliste für das Datum holen oder neu anlegen
|
||||||
final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString] ?? []);
|
final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString] ?? []);
|
||||||
|
|
||||||
|
|
@ -1133,9 +1146,6 @@ class _CalendarTabState extends State<CalendarTab> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
print('Nachher - trainings: $trainings');
|
|
||||||
print('Nachher - cancelledTrainings: $cancelledTrainings');
|
|
||||||
|
|
||||||
// Aktualisiere die Datenbank
|
// Aktualisiere die Datenbank
|
||||||
final updates = <String, dynamic>{};
|
final updates = <String, dynamic>{};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,36 +77,12 @@ class _FavoritesTabState extends State<FavoritesTab> {
|
||||||
return const Center(child: Text('Keine Favoriten gefunden'));
|
return const Center(child: Text('Keine Favoriten gefunden'));
|
||||||
}
|
}
|
||||||
final data = snapshot.data!.data() as Map<String, dynamic>;
|
final data = snapshot.data!.data() as Map<String, dynamic>;
|
||||||
final allFavorites = List<String>.from(data['favorites'] ?? []);
|
final favorites = List<String>.from(data['favorites'] ?? []);
|
||||||
|
|
||||||
if (allFavorites.isEmpty) {
|
if (favorites.isEmpty) {
|
||||||
return const Center(child: Text('Keine Favoriten gefunden'));
|
return const Center(child: Text('Keine Favoriten gefunden'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filtere Favoriten nach Kategorie
|
|
||||||
Future<List<Map<String, dynamic>>> getFilteredFavorites() async {
|
|
||||||
List<Map<String, dynamic>> filtered = [];
|
|
||||||
for (final favId in allFavorites) {
|
|
||||||
final doc = await FirebaseFirestore.instance.collection('Training').doc(favId).get();
|
|
||||||
if (!doc.exists) continue;
|
|
||||||
final trainingData = doc.data() as Map<String, dynamic>;
|
|
||||||
if (_selectedCategory == null || trainingData['category'] == _selectedCategory) {
|
|
||||||
filtered.add({'id': favId, 'data': trainingData});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return filtered;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FutureBuilder<List<Map<String, dynamic>>>(
|
|
||||||
future: getFilteredFavorites(),
|
|
||||||
builder: (context, favSnapshot) {
|
|
||||||
if (!favSnapshot.hasData) {
|
|
||||||
return const Center(child: CircularProgressIndicator());
|
|
||||||
}
|
|
||||||
final filteredFavorites = favSnapshot.data!;
|
|
||||||
if (filteredFavorites.isEmpty) {
|
|
||||||
return const Center(child: Text('Keine Favoriten gefunden'));
|
|
||||||
}
|
|
||||||
return GridView.builder(
|
return GridView.builder(
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
|
|
@ -115,11 +91,19 @@ class _FavoritesTabState extends State<FavoritesTab> {
|
||||||
crossAxisSpacing: 10,
|
crossAxisSpacing: 10,
|
||||||
mainAxisSpacing: 10,
|
mainAxisSpacing: 10,
|
||||||
),
|
),
|
||||||
itemCount: filteredFavorites.length,
|
itemCount: favorites.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final fav = filteredFavorites[index];
|
return FutureBuilder<DocumentSnapshot>(
|
||||||
final trainingData = fav['data'] as Map<String, dynamic>;
|
future: FirebaseFirestore.instance.collection('Training').doc(favorites[index]).get(),
|
||||||
final favId = fav['id'] as String;
|
builder: (context, trainingSnapshot) {
|
||||||
|
if (!trainingSnapshot.hasData || !trainingSnapshot.data!.exists) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
final trainingData = trainingSnapshot.data!.data() as Map<String, dynamic>;
|
||||||
|
// Filter nach Kategorie, falls gesetzt
|
||||||
|
if (_selectedCategory != null && trainingData['category'] != _selectedCategory) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
return Card(
|
return Card(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
|
|
@ -128,7 +112,7 @@ class _FavoritesTabState extends State<FavoritesTab> {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => TrainingDetailScreen(trainingId: favId),
|
builder: (context) => TrainingDetailScreen(trainingId: favorites[index]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -186,7 +170,7 @@ class _FavoritesTabState extends State<FavoritesTab> {
|
||||||
icon: const Icon(Icons.favorite, color: Colors.red),
|
icon: const Icon(Icons.favorite, color: Colors.red),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
|
await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
|
||||||
'favorites': FieldValue.arrayRemove([favId]),
|
'favorites': FieldValue.arrayRemove([favorites[index]]),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -23,49 +23,38 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||||
Future<void> _submit() async {
|
Future<void> _submit() async {
|
||||||
setState(() { _loading = true; _error = null; });
|
setState(() { _loading = true; _error = null; });
|
||||||
try {
|
try {
|
||||||
print('Login-Versuch gestartet...'); // Debug
|
|
||||||
if (_isLogin) {
|
if (_isLogin) {
|
||||||
print('Login-Modus: E-Mail: ${_emailController.text.trim()}'); // Debug
|
|
||||||
// Login
|
// Login
|
||||||
try {
|
try {
|
||||||
UserCredential cred = await FirebaseAuth.instance.signInWithEmailAndPassword(
|
UserCredential cred = await FirebaseAuth.instance.signInWithEmailAndPassword(
|
||||||
email: _emailController.text.trim(),
|
email: _emailController.text.trim(),
|
||||||
password: _passwordController.text.trim(),
|
password: _passwordController.text.trim(),
|
||||||
);
|
);
|
||||||
print('Firebase Auth erfolgreich: ${cred.user?.uid}'); // Debug
|
|
||||||
|
|
||||||
// Firestore-Check
|
// Firestore-Check
|
||||||
final uid = cred.user!.uid;
|
final uid = cred.user!.uid;
|
||||||
print('Firestore-Check für UID: $uid'); // Debug
|
|
||||||
|
|
||||||
final userDoc = await FirebaseFirestore.instance.collection('User').doc(uid).get();
|
final userDoc = await FirebaseFirestore.instance.collection('User').doc(uid).get();
|
||||||
print('Firestore-Dokument existiert: ${userDoc.exists}'); // Debug
|
|
||||||
|
|
||||||
if (userDoc.exists) {
|
if (userDoc.exists) {
|
||||||
print('Login erfolgreich, Benutzer gefunden'); // Debug
|
|
||||||
widget.onLoginSuccess();
|
widget.onLoginSuccess();
|
||||||
} else {
|
} else {
|
||||||
print('Kein Benutzerprofil in Firestore gefunden'); // Debug
|
|
||||||
setState(() { _error = 'Kein Benutzerprofil in der Datenbank gefunden!'; });
|
setState(() { _error = 'Kein Benutzerprofil in der Datenbank gefunden!'; });
|
||||||
await FirebaseAuth.instance.signOut();
|
await FirebaseAuth.instance.signOut();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Fehler beim Firebase Auth: $e'); // Debug
|
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print('Registrierungs-Modus: E-Mail: ${_emailController.text.trim()}'); // Debug
|
|
||||||
// Registrierung
|
// Registrierung
|
||||||
try {
|
try {
|
||||||
UserCredential cred = await FirebaseAuth.instance.createUserWithEmailAndPassword(
|
UserCredential cred = await FirebaseAuth.instance.createUserWithEmailAndPassword(
|
||||||
email: _emailController.text.trim(),
|
email: _emailController.text.trim(),
|
||||||
password: _passwordController.text.trim(),
|
password: _passwordController.text.trim(),
|
||||||
);
|
);
|
||||||
print('Firebase Auth Registrierung erfolgreich: ${cred.user?.uid}'); // Debug
|
|
||||||
|
|
||||||
// User-Datensatz in Firestore anlegen
|
// User-Datensatz in Firestore anlegen
|
||||||
final uid = cred.user!.uid;
|
final uid = cred.user!.uid;
|
||||||
print('Erstelle Firestore-Dokument für UID: $uid'); // Debug
|
|
||||||
|
|
||||||
await FirebaseFirestore.instance.collection('User').doc(uid).set({
|
await FirebaseFirestore.instance.collection('User').doc(uid).set({
|
||||||
'email': _emailController.text.trim(),
|
'email': _emailController.text.trim(),
|
||||||
|
|
@ -73,16 +62,13 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||||
'role': _isTrainer ? 'trainer' : 'player',
|
'role': _isTrainer ? 'trainer' : 'player',
|
||||||
'createdAt': FieldValue.serverTimestamp(),
|
'createdAt': FieldValue.serverTimestamp(),
|
||||||
});
|
});
|
||||||
print('Firestore-Dokument erstellt'); // Debug
|
|
||||||
|
|
||||||
widget.onLoginSuccess();
|
widget.onLoginSuccess();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Fehler bei der Registrierung: $e'); // Debug
|
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} on FirebaseAuthException catch (e) {
|
} on FirebaseAuthException catch (e) {
|
||||||
print('FirebaseAuthException: ${e.code} - ${e.message}'); // Debug
|
|
||||||
String errorMessage;
|
String errorMessage;
|
||||||
switch (e.code) {
|
switch (e.code) {
|
||||||
case 'user-not-found':
|
case 'user-not-found':
|
||||||
|
|
@ -111,7 +97,6 @@ class _LoginScreenState extends State<LoginScreen> {
|
||||||
}
|
}
|
||||||
setState(() { _error = errorMessage; });
|
setState(() { _error = errorMessage; });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Unerwarteter Fehler: $e'); // Debug
|
|
||||||
setState(() { _error = 'Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.'; });
|
setState(() { _error = 'Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut.'; });
|
||||||
} finally {
|
} finally {
|
||||||
setState(() { _loading = false; });
|
setState(() { _loading = false; });
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue