Warnung bei Wiederholenden Übungen

main
joschy2002 2025-06-20 22:23:16 +02:00
parent fb3b9027c5
commit 0923b85a20
3 changed files with 209 additions and 230 deletions

View File

@ -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'); 'id': result['id'],
print('trainingId: $trainingId'); 'name': result['title'],
print('Vorher - trainings: $trainings'); 'description': result['description'],
'duration': result['duration'],
};
// Finde das Training und füge die Übung hinzu final trainingsForDay = List<Map<String, dynamic>>.from(trainings[dateString] ?? []);
if (trainings.containsKey(dateString)) { final trainingIndex = trainingsForDay.indexWhere((t) => t['id'] == trainingId);
final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString]);
final trainingIndex = trainingsList.indexWhere((t) => t['id'] == trainingId); String finalTrainingId = trainingId;
if (trainingIndex != -1) { if (trainingIndex != -1) {
final exercises = List<Map<String, dynamic>>.from(trainingsList[trainingIndex]['exercises'] ?? []); // Fall 1: Training ist bereits spezifisch, füge die Übung hinzu
exercises.add({ final exercises = List<Map<String, dynamic>>.from(trainingsForDay[trainingIndex]['exercises'] ?? []);
'id': result['id'], exercises.add(newExerciseData);
'name': result['title'], trainingsForDay[trainingIndex]['exercises'] = exercises;
'description': result['description'], } else {
'duration': result['duration'], // Fall 2: Training ist wiederkehrend, erstelle eine neue spezifische Instanz
}); final newId = const Uuid().v4();
trainingsList[trainingIndex]['exercises'] = exercises; finalTrainingId = newId;
trainings[dateString] = trainingsList; trainingsForDay.add({
'id': newId,
'time': event['time'],
'duration': event['duration'],
'exercises': [newExerciseData],
});
}
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;
} }
} }
print('Nachher - trainings: $trainings');
// 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>{};

View File

@ -68,137 +68,121 @@ class _FavoritesTabState extends State<FavoritesTab> {
), ),
Expanded( Expanded(
child: StreamBuilder<DocumentSnapshot>( child: StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance.collection('User').doc(user.uid).snapshots(), stream: FirebaseFirestore.instance.collection('User').doc(user.uid).snapshots(),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) { if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} }
if (!snapshot.hasData || !snapshot.data!.exists) { if (!snapshot.hasData || !snapshot.data!.exists) {
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 return GridView.builder(
Future<List<Map<String, dynamic>>> getFilteredFavorites() async { padding: const EdgeInsets.all(8),
List<Map<String, dynamic>> filtered = []; gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
for (final favId in allFavorites) { maxCrossAxisExtent: 300,
final doc = await FirebaseFirestore.instance.collection('Training').doc(favId).get(); childAspectRatio: 0.75,
if (!doc.exists) continue; crossAxisSpacing: 10,
final trainingData = doc.data() as Map<String, dynamic>; mainAxisSpacing: 10,
if (_selectedCategory == null || trainingData['category'] == _selectedCategory) { ),
filtered.add({'id': favId, 'data': trainingData}); itemCount: favorites.length,
} itemBuilder: (context, index) {
return FutureBuilder<DocumentSnapshot>(
future: FirebaseFirestore.instance.collection('Training').doc(favorites[index]).get(),
builder: (context, trainingSnapshot) {
if (!trainingSnapshot.hasData || !trainingSnapshot.data!.exists) {
return const SizedBox.shrink();
} }
return filtered; final trainingData = trainingSnapshot.data!.data() as Map<String, dynamic>;
} // Filter nach Kategorie, falls gesetzt
if (_selectedCategory != null && trainingData['category'] != _selectedCategory) {
return FutureBuilder<List<Map<String, dynamic>>>( return const SizedBox.shrink();
future: getFilteredFavorites(), }
builder: (context, favSnapshot) { return Card(
if (!favSnapshot.hasData) { child: Stack(
return const Center(child: CircularProgressIndicator()); children: [
} InkWell(
final filteredFavorites = favSnapshot.data!; onTap: () {
if (filteredFavorites.isEmpty) { Navigator.push(
return const Center(child: Text('Keine Favoriten gefunden')); context,
} MaterialPageRoute(
return GridView.builder( builder: (context) => TrainingDetailScreen(trainingId: favorites[index]),
padding: const EdgeInsets.all(8), ),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( );
maxCrossAxisExtent: 300, },
childAspectRatio: 0.75, child: Column(
crossAxisSpacing: 10, crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisSpacing: 10,
),
itemCount: filteredFavorites.length,
itemBuilder: (context, index) {
final fav = filteredFavorites[index];
final trainingData = fav['data'] as Map<String, dynamic>;
final favId = fav['id'] as String;
return Card(
child: Stack(
children: [ children: [
InkWell( Expanded(
onTap: () { child: Container(
Navigator.push( color: Colors.grey[200],
context, child: const Center(
MaterialPageRoute( child: Icon(Icons.fitness_center, size: 50),
builder: (context) => TrainingDetailScreen(trainingId: favId), ),
), ),
); ),
}, Padding(
padding: const EdgeInsets.all(8.0),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Expanded( Text(
child: Container( trainingData['title'] ?? 'Unbekannt',
color: Colors.grey[200], style: const TextStyle(
child: const Center( fontWeight: FontWeight.bold,
child: Icon(Icons.fitness_center, size: 50), fontSize: 16,
),
), ),
maxLines: 2,
overflow: TextOverflow.ellipsis,
), ),
Padding( const SizedBox(height: 4),
padding: const EdgeInsets.all(8.0), Row(
child: Column( children: [
crossAxisAlignment: CrossAxisAlignment.start, const Icon(Icons.star, color: Colors.amber, size: 16),
children: [ const SizedBox(width: 4),
Text( Text(
trainingData['title'] ?? 'Unbekannt', (trainingData['rating overall'] ?? 0.0).toStringAsFixed(1),
style: const TextStyle( style: const TextStyle(fontSize: 12),
fontWeight: FontWeight.bold, ),
fontSize: 16, ],
), ),
maxLines: 2, const SizedBox(height: 4),
overflow: TextOverflow.ellipsis, Text(
),
const SizedBox(height: 4),
Row(
children: [
const Icon(Icons.star, color: Colors.amber, size: 16),
const SizedBox(width: 4),
Text(
(trainingData['rating overall'] ?? 0.0).toStringAsFixed(1),
style: const TextStyle(fontSize: 12),
),
],
),
const SizedBox(height: 4),
Text(
'Dauer: \t${trainingData['duration'] ?? '-'} Minuten', 'Dauer: \t${trainingData['duration'] ?? '-'} Minuten',
style: const TextStyle(fontSize: 12, color: Colors.grey), style: const TextStyle(fontSize: 12, color: Colors.grey),
),
],
),
), ),
], ],
), ),
), ),
Positioned(
top: 4,
right: 4,
child: IconButton(
icon: const Icon(Icons.favorite, color: Colors.red),
onPressed: () async {
await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
'favorites': FieldValue.arrayRemove([favId]),
});
},
),
),
], ],
), ),
); ),
}, Positioned(
); top: 4,
}, right: 4,
); child: 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]]),
});
},
),
),
],
),
);
},
);
},
);
},
), ),
), ),
], ],

View File

@ -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; });