import 'package:flutter/material.dart'; import '../models/channel.dart'; import '../models/group_member.dart'; import '../services/api_service.dart'; import '../services/auth_service.dart'; class GroupMembersScreen extends StatefulWidget { final Channel channel; final String? currentUserId; const GroupMembersScreen({ super.key, required this.channel, this.currentUserId, }); @override State createState() => _GroupMembersScreenState(); } class _GroupMembersScreenState extends State { late final ApiService _api; List _members = []; bool _loading = true; bool _isManager = false; @override void initState() { super.initState(); _api = ApiService(AuthService()); _load(); } Future _load() async { setState(() => _loading = true); final list = await _api.getGroupMembers(widget.channel.id); if (!mounted) return; final isManager = list.any( (m) => m.userId == widget.currentUserId && m.isManager, ); setState(() { _members = list; _isManager = isManager; _loading = false; }); } Future _showInviteDialog() async { String username = ''; final confirmed = await showDialog( context: context, builder: (ctx) => _InviteDialog( onUsernameChanged: (v) => username = v, ), ); if (confirmed == true && username.trim().isNotEmpty) { final err = await _api.inviteMember(widget.channel.id, username.trim()); if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( err ?? 'دعوت‌نامه ارسال شد', style: const TextStyle(fontSize: 11), textAlign: TextAlign.center, ), backgroundColor: err == null ? const Color(0xFF1C1C1E) : const Color(0xFF333333), behavior: SnackBarBehavior.floating, duration: const Duration(seconds: 2), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 40), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), ), ); } } Future _removeMember(GroupMember member) async { final confirmed = await showDialog( context: context, builder: (ctx) => AlertDialog( backgroundColor: const Color(0xFF1C1C1E), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), contentPadding: const EdgeInsets.all(16), content: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.person_remove_outlined, color: Colors.red, size: 28), const SizedBox(height: 8), Text( 'حذف ${member.username}؟', style: const TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), const SizedBox(height: 12), Row( children: [ Expanded( child: TextButton( onPressed: () => Navigator.pop(ctx, false), child: const Text('انصراف', style: TextStyle(color: Colors.white54, fontSize: 11)), ), ), Expanded( child: TextButton( onPressed: () => Navigator.pop(ctx, true), child: const Text('حذف', style: TextStyle(color: Colors.red, fontSize: 11)), ), ), ], ), ], ), ), ); if (confirmed == true) { final err = await _api.removeMember(widget.channel.id, member.userId); if (!mounted) return; if (err != null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(err, style: const TextStyle(fontSize: 11), textAlign: TextAlign.center), backgroundColor: const Color(0xFF333333), behavior: SnackBarBehavior.floating, duration: const Duration(seconds: 2), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 40), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), ), ); } else { _load(); } } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.black, body: SafeArea( child: Column( children: [ // Header Padding( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), child: Row( children: [ IconButton( onPressed: () => Navigator.pop(context), padding: EdgeInsets.zero, constraints: const BoxConstraints(minWidth: 28, minHeight: 28), icon: const Icon(Icons.arrow_back_ios_new, color: Colors.white70, size: 14), ), const SizedBox(width: 4), const Icon(Icons.group_outlined, color: Color(0xFF00C853), size: 14), const SizedBox(width: 4), const Expanded( child: Text( 'اعضا', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold), ), ), // Invite button IconButton( onPressed: _showInviteDialog, padding: EdgeInsets.zero, constraints: const BoxConstraints(minWidth: 28, minHeight: 28), icon: const Icon(Icons.person_add_outlined, color: Color(0xFF00C853), size: 16), ), IconButton( onPressed: _loading ? null : _load, padding: EdgeInsets.zero, constraints: const BoxConstraints(minWidth: 28, minHeight: 28), icon: const Icon(Icons.refresh, color: Colors.white54, size: 16), ), ], ), ), // Group name chip Padding( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 2), child: Row( children: [ Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: const Color(0xFF00C853).withValues(alpha: 0.12), borderRadius: BorderRadius.circular(20), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( widget.channel.type == 'PUBLIC' ? Icons.public : Icons.lock_outline, color: const Color(0xFF00C853), size: 10, ), const SizedBox(width: 4), Text( widget.channel.name, style: const TextStyle(color: Color(0xFF00C853), fontSize: 10), ), ], ), ), if (!_loading) ...[ const SizedBox(width: 6), Text( '${_members.length} عضو', style: const TextStyle(color: Colors.white38, fontSize: 10), ), ], ], ), ), const SizedBox(height: 4), // Content Expanded( child: _loading ? const Center( child: CircularProgressIndicator(color: Color(0xFF00C853), strokeWidth: 2), ) : _members.isEmpty ? const Center( child: Text('عضوی یافت نشد', style: TextStyle(color: Colors.white38, fontSize: 11)), ) : ListView.builder( padding: const EdgeInsets.only(bottom: 4), itemCount: _members.length, itemBuilder: (ctx, i) { final m = _members[i]; final isMe = m.userId == widget.currentUserId; return _MemberTile( member: m, isMe: isMe, canRemove: _isManager && !isMe && !m.isManager, onRemove: () => _removeMember(m), ); }, ), ), ], ), ), ); } } class _MemberTile extends StatelessWidget { final GroupMember member; final bool isMe; final bool canRemove; final VoidCallback onRemove; const _MemberTile({ required this.member, required this.isMe, required this.canRemove, required this.onRemove, }); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), height: 40, decoration: BoxDecoration( color: const Color(0xFF1C1C1E), borderRadius: BorderRadius.circular(12), ), padding: const EdgeInsets.symmetric(horizontal: 10), child: Row( children: [ // Online indicator Container( width: 7, height: 7, decoration: BoxDecoration( shape: BoxShape.circle, color: member.isOnline ? const Color(0xFF00C853) : Colors.white24, ), ), const SizedBox(width: 8), // Username Expanded( child: Text( member.username + (isMe ? ' (من)' : ''), style: TextStyle( color: isMe ? const Color(0xFF00C853) : Colors.white, fontSize: 11, fontWeight: member.isManager ? FontWeight.bold : FontWeight.normal, ), overflow: TextOverflow.ellipsis, ), ), // Role badge if (member.isManager) Container( padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 2), decoration: BoxDecoration( color: const Color(0xFF00C853).withValues(alpha: 0.15), borderRadius: BorderRadius.circular(8), ), child: const Text( 'مدیر', style: TextStyle(color: Color(0xFF00C853), fontSize: 9), ), ), // Remove button if (canRemove) ...[ const SizedBox(width: 4), GestureDetector( onTap: onRemove, child: const Icon(Icons.remove_circle_outline, color: Colors.red, size: 16), ), ], ], ), ); } } // ── Invite Dialog ────────────────────────────────────────────────────────── class _InviteDialog extends StatefulWidget { final ValueChanged onUsernameChanged; const _InviteDialog({required this.onUsernameChanged}); @override State<_InviteDialog> createState() => _InviteDialogState(); } class _InviteDialogState extends State<_InviteDialog> { final _ctrl = TextEditingController(); @override void dispose() { _ctrl.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AlertDialog( backgroundColor: const Color(0xFF1C1C1E), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), contentPadding: const EdgeInsets.all(16), content: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.person_add_outlined, color: Color(0xFF00C853), size: 26), const SizedBox(height: 8), const Text( 'دعوت عضو', style: TextStyle(color: Colors.white, fontSize: 12, fontWeight: FontWeight.bold), ), const SizedBox(height: 10), TextField( controller: _ctrl, autofocus: true, textAlign: TextAlign.center, style: const TextStyle(color: Colors.white, fontSize: 12), decoration: InputDecoration( hintText: 'نام کاربری', hintStyle: const TextStyle(color: Colors.white38, fontSize: 11), filled: true, fillColor: Colors.white.withValues(alpha: 0.05), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide.none, ), contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), ), onChanged: widget.onUsernameChanged, ), const SizedBox(height: 12), Row( children: [ Expanded( child: TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('انصراف', style: TextStyle(color: Colors.white54, fontSize: 11)), ), ), Expanded( child: TextButton( onPressed: () => Navigator.pop(context, true), child: const Text('ارسال', style: TextStyle(color: Color(0xFF00C853), fontSize: 11, fontWeight: FontWeight.bold)), ), ), ], ), ], ), ); } }