import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../teams/domain/team.dart'; import '../../../teams/infrastructure/teams_repository.dart'; import '../../application/admin_teams_notifier.dart'; /// Admin panel tab listing teams awaiting approval. Approve and reject /// actions are surfaced as a row of buttons per card. class AdminPendingScreen extends ConsumerWidget { const AdminPendingScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); final async = ref.watch(adminTeamsStreamProvider); return Scaffold( body: async.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center( child: Padding( padding: const EdgeInsets.all(32), child: Text('Could not load teams: $e'), ), ), data: (teams) { final pending = teams.where((t) => t.isPending).toList(); if (pending.isEmpty) { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.pending_actions_outlined, size: 64, color: theme.colorScheme.onSurfaceVariant, ), const SizedBox(height: 16), Text( 'No pending teams', style: theme.textTheme.titleMedium, ), const SizedBox(height: 8), Text( 'New manager-submitted teams will appear here for ' 'review.', style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), textAlign: TextAlign.center, ), ], ), ), ); } return ListView.builder( padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), itemCount: pending.length, itemBuilder: (context, i) => _PendingTeamCard(team: pending[i]), ); }, ), ); } } class _PendingTeamCard extends ConsumerStatefulWidget { const _PendingTeamCard({required this.team}); final Team team; @override ConsumerState<_PendingTeamCard> createState() => _PendingTeamCardState(); } class _PendingTeamCardState extends ConsumerState<_PendingTeamCard> { bool _busy = false; Future _setStatus(String status) async { setState(() => _busy = true); try { await ref .read(teamsRepositoryProvider) .updateTeamStatus(widget.team.id, status); if (!mounted) return; final label = status == TeamStatus.approved ? 'approved' : 'rejected'; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('${widget.team.name} $label')), ); } catch (e) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Action failed: $e')), ); } finally { if (mounted) setState(() => _busy = false); } } @override Widget build(BuildContext context) { final theme = Theme.of(context); final scheme = theme.colorScheme; final t = widget.team; return Card( margin: const EdgeInsets.symmetric(vertical: 6), child: Padding( padding: const EdgeInsets.all(14), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ CircleAvatar( backgroundColor: scheme.primaryContainer, child: Text( t.name.isEmpty ? '?' : t.name.characters.first, style: TextStyle( color: scheme.onPrimaryContainer, fontWeight: FontWeight.w800, ), ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( t.name.isEmpty ? 'Unnamed team' : t.name, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w800, ), ), const SizedBox(height: 2), Text( t.managerEmail.isEmpty ? 'No manager email' : t.managerEmail, style: theme.textTheme.bodySmall?.copyWith( color: scheme.onSurfaceVariant, ), ), ], ), ), Container( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 4, ), decoration: BoxDecoration( color: Colors.amber.withValues(alpha: 0.18), borderRadius: BorderRadius.circular(12), ), child: Text( 'PENDING', style: theme.textTheme.labelSmall?.copyWith( color: Colors.amber.shade300, fontWeight: FontWeight.w800, letterSpacing: 1.0, ), ), ), ], ), if (t.description != null && t.description!.isNotEmpty) ...[ const SizedBox(height: 10), Text( t.description!, style: theme.textTheme.bodyMedium, ), ], const SizedBox(height: 10), Row( children: [ Icon( Icons.group_outlined, size: 16, color: scheme.onSurfaceVariant, ), const SizedBox(width: 6), Text( '${t.players.length} ' '${t.players.length == 1 ? "player" : "players"}', style: theme.textTheme.bodySmall?.copyWith( color: scheme.onSurfaceVariant, ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: OutlinedButton.icon( onPressed: _busy ? null : () => _setStatus(TeamStatus.rejected), icon: const Icon(Icons.close, size: 18), label: const Text('REJECT'), ), ), const SizedBox(width: 8), Expanded( child: FilledButton.icon( onPressed: _busy ? null : () => _setStatus(TeamStatus.approved), icon: _busy ? const SizedBox( width: 16, height: 16, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.check, size: 18), label: const Text('APPROVE'), ), ), ], ), ], ), ), ); } }