// lib/features/reviews/widgets/review_section.dart import 'package:flutter/material.dart'; import '../../../core/storage/token_storage.dart'; import '../../../core/utils/error_utils.dart'; import '../models/review_models.dart'; import '../services/review_service.dart'; import 'review_summary.dart'; import 'review_form.dart'; import 'review_card.dart'; class ReviewSection extends StatefulWidget { final int eventId; const ReviewSection({Key? key, required this.eventId}) : super(key: key); @override State createState() => _ReviewSectionState(); } class _ReviewSectionState extends State { final ReviewService _service = ReviewService(); List _reviews = []; ReviewStatsModel? _stats; ReviewModel? _userReview; String? _currentUsername; bool _loading = true; String? _error; int _page = 1; int _total = 0; bool _loadingMore = false; @override void initState() { super.initState(); _init(); } Future _init() async { _currentUsername = await TokenStorage.getUsername(); await _loadReviews(); } Future _loadReviews() async { setState(() { _loading = true; _error = null; }); try { final response = await _service.getReviews(widget.eventId, page: 1); if (mounted) { setState(() { _reviews = response.reviews; _stats = response.stats; _userReview = response.userReview; _total = response.total; _page = 1; _loading = false; }); } } catch (e) { if (mounted) setState(() { _loading = false; _error = userFriendlyError(e); }); } } Future _loadMore() async { if (_loadingMore || _reviews.length >= _total) return; setState(() => _loadingMore = true); try { final response = await _service.getReviews(widget.eventId, page: _page + 1); if (mounted) { setState(() { _reviews.addAll(response.reviews); _page = response.page; _total = response.total; _loadingMore = false; }); } } catch (_) { if (mounted) setState(() => _loadingMore = false); } } Future _handleSubmit(int rating, String? comment) async { await _service.submitReview(widget.eventId, rating, comment); await _loadReviews(); // Refresh to get updated stats + review list } Future _handleHelpful(int reviewId) async { return _service.markHelpful(reviewId); } Future _handleFlag(int reviewId) async { await _service.flagReview(reviewId); } @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Section header const Text( 'Reviews & Ratings', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Color(0xFF1E293B), ), ), const SizedBox(height: 16), if (_loading) const Center( child: Padding( padding: EdgeInsets.all(32), child: CircularProgressIndicator(color: Color(0xFF0F45CF)), ), ) else if (_error != null) Padding( padding: const EdgeInsets.all(16), child: Column( children: [ Text(_error!, style: const TextStyle(color: Color(0xFF94A3B8), fontSize: 13)), const SizedBox(height: 8), TextButton.icon( onPressed: _loadReviews, icon: const Icon(Icons.refresh, size: 16), label: const Text('Retry'), ), ], ), ) else ...[ // Summary card if (_stats != null && _stats!.reviewCount > 0) ...[ ReviewSummary(stats: _stats!), const SizedBox(height: 16), ], // Review form ReviewForm( eventId: widget.eventId, existingReview: _userReview, onSubmit: _handleSubmit, ), const SizedBox(height: 16), // Divider if (_reviews.isNotEmpty) const Divider(color: Color(0xFFF1F5F9), thickness: 1), // Reviews list if (_reviews.isEmpty && (_stats == null || _stats!.reviewCount == 0)) const Padding( padding: EdgeInsets.symmetric(vertical: 24), child: Center( child: Text( 'No reviews yet. Be the first to share your experience!', style: TextStyle(color: Color(0xFF94A3B8), fontSize: 14), textAlign: TextAlign.center, ), ), ) else ...[ const SizedBox(height: 12), ...List.generate(_reviews.length, (i) => Padding( padding: const EdgeInsets.only(bottom: 12), child: ReviewCard( review: _reviews[i], currentUsername: _currentUsername, onHelpful: _handleHelpful, onFlag: _handleFlag, ), )), ], // Load more if (_reviews.length < _total) Center( child: _loadingMore ? const Padding( padding: EdgeInsets.all(16), child: SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2, color: Color(0xFF0F45CF))), ) : TextButton( onPressed: _loadMore, child: const Text( 'Show more reviews', style: TextStyle(color: Color(0xFF0F45CF), fontWeight: FontWeight.w600), ), ), ), ], ], ); } }