import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; class TrainingDetailScreen extends StatefulWidget { final String trainingId; const TrainingDetailScreen({super.key, required this.trainingId}); @override State createState() => _TrainingDetailScreenState(); } class _TrainingDetailScreenState extends State { double? _userRating; bool _isLoading = false; bool _isPlayer = false; bool _userRoleChecked = false; @override void initState() { super.initState(); _checkUserRole(); } Future _checkUserRole() async { final user = FirebaseAuth.instance.currentUser; if (user == null) return; try { final userDoc = await FirebaseFirestore.instance.collection('User').doc(user.uid).get(); if (userDoc.exists) { setState(() { _isPlayer = userDoc.data()?['role'] == 'player'; _userRoleChecked = true; }); } } catch (e) { print('Error checking user role: $e'); } } Future _submitRating(double rating) async { if (!_isPlayer) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Nur Spieler können Übungen bewerten')), ); return; } setState(() => _isLoading = true); try { final user = FirebaseAuth.instance.currentUser; if (user == null) { throw Exception('Nicht eingeloggt'); } final trainingRef = FirebaseFirestore.instance.collection('Training').doc(widget.trainingId); final trainingDoc = await trainingRef.get(); if (!trainingDoc.exists) { throw Exception('Training nicht gefunden'); } final data = trainingDoc.data() as Map; List ratings = List.from(data['ratings'] ?? []); // Entferne alte Bewertung des Users falls vorhanden ratings.removeWhere((r) => r['userId'] == user.uid); // Füge neue Bewertung hinzu ratings.add({ 'userId': user.uid, 'rating': rating, 'timestamp': DateTime.now().toIso8601String(), // Verwende ISO-String statt FieldValue }); // Berechne neue Gesamtbewertung double overallRating = 0; if (ratings.isNotEmpty) { overallRating = ratings.map((r) => (r['rating'] as num).toDouble()).reduce((a, b) => a + b) / ratings.length; } // Aktualisiere das Dokument await trainingRef.update({ 'ratings': ratings, 'rating overall': overallRating, }); setState(() => _userRating = rating); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Bewertung erfolgreich gespeichert')), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Fehler beim Speichern der Bewertung: ${e.toString()}')), ); } } finally { if (mounted) { setState(() => _isLoading = false); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Training Details'), ), body: FutureBuilder( future: FirebaseFirestore.instance.collection('Training').doc(widget.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; // Hole die Bewertung des aktuellen Users final user = FirebaseAuth.instance.currentUser; if (user != null && _userRating == null) { final ratings = List.from(data['ratings'] ?? []); final userRating = ratings.firstWhere( (r) => r['userId'] == user.uid, orElse: () => {'rating': null}, )['rating']; if (userRating != null) { _userRating = (userRating as num).toDouble(); } } 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: (data['picture'] is String && data['picture'] != '') ? Image.network( data['picture'], fit: BoxFit.cover, ) : 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: 16), Row( children: [ const Icon(Icons.star, color: Colors.amber), const SizedBox(width: 8), Text( 'Durchschnittliche Bewertung: ${(data['rating overall'] ?? 0.0).toStringAsFixed(1)}', style: const TextStyle(fontSize: 16), ), ], ), const SizedBox(height: 8), Text( 'Anzahl Bewertungen: ${(data['ratings'] ?? []).length}', style: TextStyle(color: Colors.grey[600]), ), if (_userRoleChecked && _isPlayer) ...[ const SizedBox(height: 16), const Text( 'Deine Bewertung:', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(5, (index) { return IconButton( icon: Icon( index < (_userRating ?? 0) ? Icons.star : Icons.star_border, color: Colors.amber, size: 32, ), onPressed: _isLoading ? null : () => _submitRating(index + 1.0), ); }), ), if (_isLoading) const Padding( padding: EdgeInsets.all(8.0), child: Center(child: CircularProgressIndicator()), ), ], const SizedBox(height: 8), Text( 'Kategorie: ${data['category'] ?? '-'}', style: TextStyle(color: Colors.grey[600]), ), ], ), ); }, ), ); } }