diff --git a/trainerbox/.firebase/hosting.YnVpbGQvd2Vi.cache b/trainerbox/.firebase/hosting.YnVpbGQvd2Vi.cache index d2f67a1..935eab9 100644 --- a/trainerbox/.firebase/hosting.YnVpbGQvd2Vi.cache +++ b/trainerbox/.firebase/hosting.YnVpbGQvd2Vi.cache @@ -1,4 +1,9 @@ +version.json,1751119914966,beb53905e09aa026fbfd8544475307ac1cc8878b5eb8072f44b5b1b8dfe47caa manifest.json,1743682132309,5af3189cf93316f9249fce0ea2db87b269e704d42173e4fa0a2873bf5f448344 +main.dart.js,1751119914745,30f90f85410130f8f9fd74c721fed3f89032dca57deb58d3be42884428292fda +index.html,1751119898794,bd7b8ed757c3a9f61eb8e01f3f90724ff4aa03e200c15cd33d8653aa2b0cf31b +flutter_service_worker.js,1751119916329,85798f31ac6b4025d57bfa85f416d5024e79d4f0045bec83082ffbd7daf53e57 +flutter_bootstrap.js,1751119898791,6ae3e6cabe64d6cf6898d9078a97870c9d063e319f676117b733a63fa33f64d4 flutter.js,1749739662000,053adb95c9fd7e93f05fde87a56d68d3269388c2678826834ffd3ed7d292bf26 favicon.png,1743682132308,fcc7c4545d5b62ad01682589e6fdc7ea03d0a3b42069963c815c344b632eb5cf icons/Icon-maskable-512.png,1743682132309,e7983524dc70254adc61764657d7e03d19284de8da586b5818d737bc08c6d14e @@ -14,22 +19,17 @@ canvaskit/canvaskit.js,1749739786000,9b87a0d6c67ac68cbce3c8018ecc18f7d77811460b7 canvaskit/chromium/canvaskit.wasm,1749739852000,3b6125ac9e23794cf7f39985a7f21d8270fbdf5af7b30d1fa67a2b70061a1513 canvaskit/chromium/canvaskit.js.symbols,1749739852000,6e864727463607c5ed93d9197e943eee281b93d814115f14e114defd31359f65 canvaskit/chromium/canvaskit.js,1749739852000,98eed9e4311de4bc5e460d73ab0e034be11a0c0aded58733e94bf9971c8d1ecb +assets/NOTICES,1751119915043,2423be738108ad3cecb49273868c0853d6b60024fc565d67e59a66196f6b3a57 +assets/FontManifest.json,1751119915042,9ea504185602e57d97b7c3517d382b8627a13c0181c490c96a9b55a5d5c8810c +assets/AssetManifest.json,1751119915042,7d5ecba60e3a1f05f8dadca2094eb13090f8e9578d01c50037c02ab5c59ecfa4 +assets/AssetManifest.bin.json,1751119915042,77c62ce3fd7c494bed363e766dde46e5e86faaa47e2b3239137f8cb4eb7c30fb +assets/AssetManifest.bin,1751119915042,3838b71b15de7f587ccaac0e708e90e9e5eae28b02e743b4291899f4b688bf44 +assets/shaders/ink_sparkle.frag,1751119915133,80c6e65c75f1de434b1b22dba61e96ad82dba0f2fc5e8b3b59c2def46d794354 +assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1751119915931,12bc6bf55aad4657f62747b6c1c9b5c120a594ed3540db21729b6db3c847340d assets/images/training_bg.jpg,1744891568336,f159f5b1414e6310b5c5c705bcf21134e30765599cc14971864780950e9d7426 assets/images/arrowRechts.png,1745788948322,9305f0570a9dfcf285fb4efff389efa0492952746b728d7610594058e92edb37 assets/images/arrowLinks.png,1745788948322,7c2e6d924c8b21aba8e6b58b5998d964c2ff1ca6a2f7295cf877911130c1ec29 assets/images/prototype/prototype2.png,1745788948328,59863dcfc0eb346a4ddccde3ee5d31cbbc318e57fc1b9c82f34ce924c803f100 assets/images/prototype/prototype1.png,1745788948325,38856e73e8544f42c8550c249ab5d820a0b511a03b2ff5913a5c327e37bf5a23 assets/images/prototype/leancanvas1.png,1745788948324,2f6245b5ee908e682cf917905301510f7da5848d91373eea8f6d020bd2804478 -version.json,1751119914966,beb53905e09aa026fbfd8544475307ac1cc8878b5eb8072f44b5b1b8dfe47caa -index.html,1751119898794,bd7b8ed757c3a9f61eb8e01f3f90724ff4aa03e200c15cd33d8653aa2b0cf31b -flutter_service_worker.js,1751119916329,85798f31ac6b4025d57bfa85f416d5024e79d4f0045bec83082ffbd7daf53e57 -assets/AssetManifest.json,1751119915042,7d5ecba60e3a1f05f8dadca2094eb13090f8e9578d01c50037c02ab5c59ecfa4 -flutter_bootstrap.js,1751119898791,6ae3e6cabe64d6cf6898d9078a97870c9d063e319f676117b733a63fa33f64d4 -assets/FontManifest.json,1751119915042,9ea504185602e57d97b7c3517d382b8627a13c0181c490c96a9b55a5d5c8810c -assets/AssetManifest.bin.json,1751119915042,77c62ce3fd7c494bed363e766dde46e5e86faaa47e2b3239137f8cb4eb7c30fb -assets/AssetManifest.bin,1751119915042,3838b71b15de7f587ccaac0e708e90e9e5eae28b02e743b4291899f4b688bf44 -assets/shaders/ink_sparkle.frag,1751119915133,80c6e65c75f1de434b1b22dba61e96ad82dba0f2fc5e8b3b59c2def46d794354 -assets/packages/cupertino_icons/assets/CupertinoIcons.ttf,1751119915931,12bc6bf55aad4657f62747b6c1c9b5c120a594ed3540db21729b6db3c847340d assets/fonts/MaterialIcons-Regular.otf,1751119915932,7dbdfa332b0b3a613a4ceb55012089f0e9c332b0e29f3cd23aaeee14d40633ff -assets/NOTICES,1751119915043,2423be738108ad3cecb49273868c0853d6b60024fc565d67e59a66196f6b3a57 -main.dart.js,1751119914745,30f90f85410130f8f9fd74c721fed3f89032dca57deb58d3be42884428292fda diff --git a/trainerbox/lib/screens/calendar_tab.dart b/trainerbox/lib/screens/calendar_tab.dart index 6ea45bb..b47103b 100644 --- a/trainerbox/lib/screens/calendar_tab.dart +++ b/trainerbox/lib/screens/calendar_tab.dart @@ -499,36 +499,103 @@ class _CalendarTabState extends State { Future _deleteTraining(Map event) async { if (_userRole != 'trainer' || !event['isCurrentUser']) return; + + print('=== DEBUG: Starting _deleteTraining ==='); + print('DEBUG: Event to delete: $event'); + print('DEBUG: Training ID: ${event['id']}'); + print('DEBUG: Date: ${event['date']}'); + print('DEBUG: Is weekly training: ${event['id']?.toString().startsWith('weekly_')}'); + try { final userDoc = await FirebaseFirestore.instance.collection('User').doc(_currentUserId).get(); - if (!userDoc.exists) return; + if (!userDoc.exists) { + print('DEBUG: User document does not exist'); + return; + } + final data = userDoc.data() as Map; final trainings = Map.from(data['trainings'] ?? {}); final dateString = event['date'] as String; final trainingId = event['id'] as String?; final cancelledTrainings = List>.from(data['cancelledTrainings'] ?? []); + print('DEBUG: Current trainings in DB: $trainings'); + print('DEBUG: Current cancelledTrainings in DB: $cancelledTrainings'); + // Wenn es sich um ein regelmäßiges Training handelt (ID beginnt mit 'weekly_') if (trainingId != null && trainingId.startsWith('weekly_')) { - // Füge das Datum zu cancelledTrainings hinzu, wenn es noch nicht existiert - if (!cancelledTrainings.any((cancelled) => - //cancelled is Map && - cancelled['date'] == dateString - )) { - cancelledTrainings.add({ - 'date': dateString, - }); - } + print('DEBUG: Processing weekly training deletion'); + + // Für regelmäßige Trainings: Lösche alle Trainings dieser Serie + final weekdays = { + 'Montag': 1, + 'Dienstag': 2, + 'Mittwoch': 3, + 'Donnerstag': 4, + 'Freitag': 5, + 'Samstag': 6, + 'Sonntag': 7, + }; + + final date = DateTime.parse(dateString); + final weekday = date.weekday; + + print('DEBUG: Weekday to delete: $weekday'); + + // Lösche alle Trainings an diesem Wochentag + trainings.forEach((dateStr, trainingsList) { + final trainingDate = DateTime.tryParse(dateStr); + if (trainingDate != null && trainingDate.weekday == weekday) { + print('DEBUG: Checking date $dateStr (weekday: ${trainingDate.weekday})'); + final list = List>.from(trainingsList); + print('DEBUG: Trainings on this date before deletion: $list'); + + final beforeCount = list.length; + list.removeWhere((t) => t['id'] == trainingId); + final afterCount = list.length; + + print('DEBUG: Removed ${beforeCount - afterCount} trainings with ID $trainingId'); + + if (list.isEmpty) { + trainings.remove(dateStr); + print('DEBUG: Removed empty date $dateStr from trainings'); + } else { + trainings[dateStr] = list; + print('DEBUG: Updated trainings for date $dateStr: $list'); + } + } + }); + + // Entferne alle cancelledTrainings für diesen Wochentag + final beforeCancelledCount = cancelledTrainings.length; + cancelledTrainings.removeWhere((cancelled) => + cancelled.containsKey('date') && + DateTime.parse(cancelled['date'] as String).weekday == weekday + ); + final afterCancelledCount = cancelledTrainings.length; + + print('DEBUG: Removed ${beforeCancelledCount - afterCancelledCount} cancelled trainings for weekday $weekday'); + } else { - // Für spezifische Trainings: Entferne das Training aus der Liste + print('DEBUG: Processing specific training deletion'); + + // Für spezifische Trainings: Entferne nur das Training an diesem Tag if (trainings.containsKey(dateString)) { final trainingsList = List>.from(trainings[dateString]); + print('DEBUG: Trainings on date $dateString before deletion: $trainingsList'); + + final beforeCount = trainingsList.length; trainingsList.removeWhere((t) => t['id'] == trainingId); + final afterCount = trainingsList.length; + + print('DEBUG: Removed ${beforeCount - afterCount} trainings with ID $trainingId'); if (trainingsList.isEmpty) { trainings.remove(dateString); + print('DEBUG: Removed empty date $dateString from trainings'); } else { trainings[dateString] = trainingsList; + print('DEBUG: Updated trainings for date $dateString: $trainingsList'); } } @@ -549,45 +616,107 @@ class _CalendarTabState extends State { final weekdayName = weekdays.entries.firstWhere((entry) => entry.value == weekday).key; final trainingTimes = data['trainingTimes'] as Map? ?? {}; + print('DEBUG: Weekday name: $weekdayName'); + print('DEBUG: Training times: $trainingTimes'); + print('DEBUG: Has regular training on this weekday: ${trainingTimes.containsKey(weekdayName)}'); + // Wenn an diesem Tag kein regelmäßiges Training stattfindet, entferne den Eintrag aus cancelledTrainings if (!trainingTimes.containsKey(weekdayName)) { + final beforeCancelledCount = cancelledTrainings.length; cancelledTrainings.removeWhere((cancelled) => - //cancelled is Map && cancelled.containsKey('date') && cancelled['date'] == dateString ); + final afterCancelledCount = cancelledTrainings.length; + + print('DEBUG: Removed ${beforeCancelledCount - afterCancelledCount} cancelled trainings for date $dateString'); } } + print('DEBUG: Final trainings after deletion: $trainings'); + print('DEBUG: Final cancelledTrainings after deletion: $cancelledTrainings'); + // Aktualisiere die Datenbank final updates = {}; // Aktualisiere trainings nur, wenn es nicht leer ist if (trainings.isNotEmpty) { updates['trainings'] = trainings; + print('DEBUG: Will update trainings in DB'); } else { updates['trainings'] = null; + print('DEBUG: Will set trainings to null in DB'); } // Aktualisiere cancelledTrainings nur, wenn es nicht leer ist if (cancelledTrainings.isNotEmpty) { updates['cancelledTrainings'] = cancelledTrainings; + print('DEBUG: Will update cancelledTrainings in DB'); } else { updates['cancelledTrainings'] = null; + print('DEBUG: Will set cancelledTrainings to null in DB'); } + print('DEBUG: Final updates to DB: $updates'); + // Führe die Aktualisierung durch await FirebaseFirestore.instance.collection('User').doc(_currentUserId).update(updates); + print('DEBUG: Database update completed successfully'); // Aktualisiere die UI sofort setState(() { - final normalizedDate = DateTime.parse(dateString); - if (_events.containsKey(normalizedDate)) { - _events[normalizedDate]!.removeWhere((e) => e['id'] == trainingId); - if (_events[normalizedDate]!.isEmpty) { - _events.remove(normalizedDate); + print('DEBUG: Updating UI...'); + + // Für regelmäßige Trainings: Entferne alle Events an diesem Wochentag + if (trainingId != null && trainingId.startsWith('weekly_')) { + final date = DateTime.parse(dateString); + final weekday = date.weekday; + + print('DEBUG: Removing events from UI for weekday $weekday'); + + _events.forEach((eventDate, eventList) { + if (eventDate.weekday == weekday) { + print('DEBUG: Checking event date $eventDate (weekday: ${eventDate.weekday})'); + print('DEBUG: Events before removal: $eventList'); + + final beforeCount = eventList.length; + eventList.removeWhere((e) => e['id'] == trainingId); + final afterCount = eventList.length; + + print('DEBUG: Removed ${beforeCount - afterCount} events with ID $trainingId'); + print('DEBUG: Events after removal: $eventList'); + } + }); + + // Entferne leere Event-Listen + final beforeEmptyCount = _events.length; + _events.removeWhere((date, events) => events.isEmpty); + final afterEmptyCount = _events.length; + + print('DEBUG: Removed ${beforeEmptyCount - afterEmptyCount} empty event lists'); + + } else { + // Für spezifische Trainings: Entferne nur das Event an diesem Tag + final normalizedDate = DateTime.parse(dateString); + if (_events.containsKey(normalizedDate)) { + print('DEBUG: Removing specific event from UI for date $normalizedDate'); + print('DEBUG: Events before removal: ${_events[normalizedDate]}'); + + final beforeCount = _events[normalizedDate]!.length; + _events[normalizedDate]!.removeWhere((e) => e['id'] == trainingId); + final afterCount = _events[normalizedDate]!.length; + + print('DEBUG: Removed ${beforeCount - afterCount} events with ID $trainingId'); + print('DEBUG: Events after removal: ${_events[normalizedDate]}'); + + if (_events[normalizedDate]!.isEmpty) { + _events.remove(normalizedDate); + print('DEBUG: Removed empty date $normalizedDate from events'); + } } } + + print('DEBUG: UI update completed'); }); if (mounted) { @@ -595,7 +724,11 @@ class _CalendarTabState extends State { const SnackBar(content: Text('Training wurde gelöscht')), ); } + + print('=== DEBUG: _deleteTraining completed successfully ==='); + } catch (e) { + print('DEBUG: Error in _deleteTraining: $e'); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Fehler beim Löschen des Trainings')), diff --git a/trainerbox/lib/screens/login_screen.dart b/trainerbox/lib/screens/login_screen.dart index c737e09..e8ac2c9 100644 --- a/trainerbox/lib/screens/login_screen.dart +++ b/trainerbox/lib/screens/login_screen.dart @@ -44,14 +44,14 @@ class _LoginScreenState extends State { if (userDoc.exists) { widget.onLoginSuccess(); } else { - setState(() { _error = 'No user profile found in the database!'; }); + setState(() { _error = 'Kein Benutzerprofil in der Datenbank gefunden!'; }); await FirebaseAuth.instance.signOut(); } } catch (e) { rethrow; } } else { - // Registration + // Registration - Direct attempt to create user try { UserCredential cred = await FirebaseAuth.instance.createUserWithEmailAndPassword( email: _emailController.text.trim(), @@ -65,6 +65,11 @@ class _LoginScreenState extends State { 'name': _nameController.text.trim(), 'role': _isTrainer ? 'trainer' : 'player', 'createdAt': FieldValue.serverTimestamp(), + 'favorites': [], + 'trainings': {}, + 'cancelledTrainings': [], + 'trainingTimes': {}, + 'trainingDurations': {}, }); widget.onLoginSuccess(); @@ -89,7 +94,7 @@ class _LoginScreenState extends State { errorMessage = 'Dieses Konto wurde deaktiviert.'; break; case 'email-already-in-use': - errorMessage = 'Diese E-Mail-Adresse wird bereits verwendet.'; + errorMessage = 'Diese E-Mail-Adresse wird bereits verwendet. Bitte melde dich an oder verwende eine andere E-Mail-Adresse.'; break; case 'weak-password': errorMessage = 'Das Passwort ist zu schwach.';