import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:cached_network_image/cached_network_image.dart'; import '../models/review.dart'; import '../services/woocommerce_service.dart'; import '../widgets/loading_widget.dart'; import '../utils/error_handler.dart'; class ReviewsWidget extends StatefulWidget { final int productId; const ReviewsWidget({ super.key, required this.productId, }); @override State createState() => _ReviewsWidgetState(); } class _ReviewsWidgetState extends State { final WooCommerceService _wooCommerceService = WooCommerceService(); List _reviews = []; ProductRating? _rating; bool _isLoading = true; String? _error; @override void initState() { super.initState(); _loadReviews(); } Future _loadReviews() async { setState(() { _isLoading = true; _error = null; }); try { final reviews = await _wooCommerceService.getProductReviews(widget.productId); final rating = await _wooCommerceService.getProductRating(widget.productId); setState(() { _reviews = reviews; _rating = rating; _isLoading = false; }); } catch (e) { setState(() { _error = e.toString(); _isLoading = false; }); } } @override Widget build(BuildContext context) { if (_isLoading) { return const LoadingWidget(); } if (_error != null) { return Center( child: Column( children: [ Text('Fehler beim Laden der Bewertungen'), ElevatedButton( onPressed: _loadReviews, child: const Text('Erneut versuchen'), ), ], ), ); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (_rating != null) _buildRatingSummary(_rating!), const SizedBox(height: 16), Text( 'Bewertungen (${_reviews.length})', style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 12), if (_reviews.isEmpty) const Padding( padding: EdgeInsets.all(16.0), child: Text('Noch keine Bewertungen'), ) else ..._reviews.map((review) => _buildReviewCard(review)), ], ); } Widget _buildRatingSummary(ProductRating rating) { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.grey[100], borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Column( children: [ Text( rating.averageRating.toStringAsFixed(1), style: Theme.of(context).textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, color: const Color(0xFF8B6F47), ), ), _buildStars(rating.averageRating), Text( '${rating.ratingCount} Bewertungen', style: Theme.of(context).textTheme.bodySmall, ), ], ), ], ), ); } Widget _buildStars(double rating) { return Row( mainAxisSize: MainAxisSize.min, children: List.generate(5, (index) { return Icon( index < rating.floor() ? Icons.star : index < rating ? Icons.star_half : Icons.star_border, color: Colors.amber, size: 20, ); }), ); } Widget _buildReviewCard(Review review) { final dateFormat = DateFormat('dd.MM.yyyy'); return Card( margin: const EdgeInsets.only(bottom: 12), child: Padding( padding: const EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ if (review.reviewerAvatarUrl != null) CircleAvatar( radius: 20, backgroundImage: CachedNetworkImageProvider(review.reviewerAvatarUrl!), ) else CircleAvatar( radius: 20, child: Text(review.reviewer[0].toUpperCase()), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( review.reviewer, style: Theme.of(context).textTheme.titleSmall?.copyWith( fontWeight: FontWeight.bold, ), ), Text( dateFormat.format(review.dateCreated), style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Colors.grey[600], ), ), ], ), ), _buildStars(review.rating.toDouble()), ], ), const SizedBox(height: 8), Text( review.review, style: Theme.of(context).textTheme.bodyMedium, ), if (review.verified) Padding( padding: const EdgeInsets.only(top: 8), child: Row( children: [ Icon(Icons.verified, size: 16, color: Colors.green), const SizedBox(width: 4), Text( 'Verifizierter Kauf', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Colors.green, ), ), ], ), ), ], ), ), ); } }