import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart' hide TextDirection; import 'package:provider/provider.dart'; import '../models/group_member_model.dart'; import '../models/user_model.dart'; import '../providers/group_provider.dart'; import '../providers/user_provider.dart'; import '../theme/app_theme.dart'; import '../widgets/app_sidebar.dart'; import '../widgets/responsive_layout.dart'; class GroupDetailScreen extends StatefulWidget { final String groupId; const GroupDetailScreen({super.key, required this.groupId}); @override State createState() => _GroupDetailScreenState(); } class _GroupDetailScreenState extends State { @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { final groups = context.read(); groups.loadGroupMembers(widget.groupId); if (groups.groups.isEmpty) groups.loadGroups(); context.read().loadUsers(); }); } @override Widget build(BuildContext context) { return Consumer(builder: (_, groupProvider, __) { final group = groupProvider.groups .where((g) => g.id == widget.groupId) .firstOrNull; return ResponsiveLayout( title: group?.name ?? 'جزئیات گروه', sidebar: const AppSidebar(), body: _GroupDetailBody( groupId: widget.groupId, groupName: group?.name ?? '...', groupDescription: group?.description, isActive: group?.isActive ?? true, createdAt: group?.createdAt, ), ); }); } } class _GroupDetailBody extends StatelessWidget { final String groupId; final String groupName; final String? groupDescription; final bool isActive; final DateTime? createdAt; const _GroupDetailBody({ required this.groupId, required this.groupName, required this.groupDescription, required this.isActive, required this.createdAt, }); @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // ── Back button + Header ────────────────────────────────── Row( children: [ IconButton( onPressed: () => context.go('/groups'), icon: const Icon(Icons.arrow_back_rounded), tooltip: 'بازگشت', ), const SizedBox(width: 8), Expanded( child: Text( groupName, style: const TextStyle( fontSize: 24, fontWeight: FontWeight.w800, color: AppTheme.textPrimary, ), ), ), ElevatedButton.icon( onPressed: () => _showAddMemberDialog(context), icon: const Icon(Icons.person_add_rounded, size: 18), label: const Text('افزودن عضو'), ), ], ), const SizedBox(height: 20), // ── Group info card ─────────────────────────────────────── Card( child: Padding( padding: const EdgeInsets.all(20), child: Row( children: [ Container( width: 56, height: 56, decoration: BoxDecoration( color: const Color(0xFF7C3AED).withValues(alpha: 0.12), borderRadius: BorderRadius.circular(14), ), child: const Icon( Icons.groups_rounded, color: Color(0xFF7C3AED), size: 28, ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( groupName, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w700, color: AppTheme.textPrimary, ), ), const SizedBox(width: 10), _StatusBadge(isActive: isActive), ], ), if (groupDescription != null) ...[ const SizedBox(height: 4), Text( groupDescription!, style: const TextStyle( color: AppTheme.textSecondary, fontSize: 14, ), ), ], const SizedBox(height: 4), Text( createdAt != null ? 'ایجاد شده در ${DateFormat('yyyy/MM/dd').format(createdAt!)}' : '', style: const TextStyle( color: AppTheme.textSecondary, fontSize: 12, ), ), ], ), ), ], ), ), ), const SizedBox(height: 24), // ── Members section ─────────────────────────────────────── const Text( 'اعضای گروه', style: TextStyle( fontSize: 18, fontWeight: FontWeight.w700, color: AppTheme.textPrimary, ), ), const SizedBox(height: 12), _MembersTable(groupId: groupId), ], ), ); } void _showAddMemberDialog(BuildContext context) { showDialog( context: context, builder: (_) => _AddMemberDialog(groupId: groupId), ); } } // ── Add Member Dialog ──────────────────────────────────────────────────────── class _AddMemberDialog extends StatefulWidget { final String groupId; const _AddMemberDialog({required this.groupId}); @override State<_AddMemberDialog> createState() => _AddMemberDialogState(); } class _AddMemberDialogState extends State<_AddMemberDialog> { UserModel? _selectedUser; GroupRole _role = GroupRole.member; bool _loading = false; String? _error; Future _submit() async { if (_selectedUser == null) { setState(() => _error = 'لطفاً یک کاربر انتخاب کنید'); return; } setState(() { _loading = true; _error = null; }); final provider = context.read(); final currentMembers = provider.membersOf(widget.groupId); if (currentMembers.any((m) => m.userId == _selectedUser!.id)) { setState(() { _loading = false; _error = 'این کاربر قبلاً عضو این گروه است'; }); return; } final result = await provider.addMember( widget.groupId, _selectedUser!.id, _role, _selectedUser!.username, ); if (!mounted) return; setState(() => _loading = false); if (result != null) { Navigator.of(context).pop(); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('«${_selectedUser!.username}» به گروه اضافه شد'), backgroundColor: AppTheme.success, ), ); } else { setState(() => _error = provider.error); } } @override Widget build(BuildContext context) { return Consumer(builder: (_, userProvider, __) { final users = userProvider.users; return AlertDialog( title: const Row( children: [ Icon(Icons.person_add_rounded, color: AppTheme.primary), SizedBox(width: 10), Text('افزودن عضو به گروه'), ], ), content: SizedBox( width: 400, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // User selector DropdownButtonFormField( initialValue: _selectedUser, decoration: const InputDecoration( labelText: 'انتخاب کاربر', prefixIcon: Icon(Icons.person_outline_rounded), ), hint: const Text('کاربر را انتخاب کنید'), items: users .map((u) => DropdownMenuItem( value: u, child: Text( '${u.username} (${u.role.label})', ), )) .toList(), onChanged: (v) => setState(() => _selectedUser = v), ), const SizedBox(height: 16), // Role selector DropdownButtonFormField( initialValue: _role, decoration: const InputDecoration( labelText: 'نقش در گروه', prefixIcon: Icon(Icons.badge_outlined), ), items: GroupRole.values .map((r) => DropdownMenuItem( value: r, child: Text(r.label), )) .toList(), onChanged: (v) => setState(() => _role = v!), ), if (_error != null) ...[ const SizedBox(height: 12), Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: AppTheme.danger.withValues(alpha: 0.08), borderRadius: BorderRadius.circular(8), border: Border.all( color: AppTheme.danger.withValues(alpha: 0.3)), ), child: Text( _error!, style: const TextStyle( color: AppTheme.danger, fontSize: 13), ), ), ], ], ), ), actions: [ TextButton( onPressed: _loading ? null : () => Navigator.of(context).pop(), child: const Text('انصراف'), ), ElevatedButton( onPressed: _loading ? null : _submit, child: _loading ? const SizedBox( width: 18, height: 18, child: CircularProgressIndicator( color: Colors.white, strokeWidth: 2)) : const Text('افزودن'), ), ], ); }); } } // ── Members Table ──────────────────────────────────────────────────────────── class _MembersTable extends StatelessWidget { final String groupId; const _MembersTable({required this.groupId}); @override Widget build(BuildContext context) { return Consumer(builder: (_, provider, __) { final members = provider.membersOf(groupId); if (members.isEmpty) { return Card( child: Padding( padding: const EdgeInsets.all(40), child: Center( child: Column( children: [ const Icon(Icons.people_outline_rounded, size: 56, color: AppTheme.border), const SizedBox(height: 12), const Text( 'هنوز عضوی به این گروه اضافه نشده است', style: TextStyle(color: AppTheme.textSecondary), ), const SizedBox(height: 16), ElevatedButton.icon( onPressed: () => showDialog( context: context, builder: (_) => _AddMemberDialog(groupId: groupId), ), icon: const Icon(Icons.person_add_rounded, size: 16), label: const Text('افزودن اولین عضو'), ), ], ), ), ), ); } return Card( child: ClipRRect( borderRadius: BorderRadius.circular(12), child: SingleChildScrollView( child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: DataTable( columns: const [ DataColumn(label: Text('کاربر')), DataColumn(label: Text('نقش در گروه')), DataColumn(label: Text('تاریخ عضویت')), ], rows: members.map((m) => _buildRow(m)).toList(), ), ), ), ), ); }); } DataRow _buildRow(GroupMemberModel member) { final color = member.role == GroupRole.manager ? const Color(0xFF0891B2) : AppTheme.textSecondary; return DataRow( cells: [ DataCell( Row( mainAxisSize: MainAxisSize.min, children: [ CircleAvatar( radius: 16, backgroundColor: AppTheme.primary.withValues(alpha: 0.12), child: Text( (member.username ?? member.userId)[0].toUpperCase(), style: const TextStyle( color: AppTheme.primary, fontSize: 13, fontWeight: FontWeight.w700, ), ), ), const SizedBox(width: 10), Text( member.username ?? member.userId, style: const TextStyle(fontWeight: FontWeight.w600), ), ], ), ), DataCell( Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: color.withValues(alpha: 0.12), borderRadius: BorderRadius.circular(20), ), child: Text( member.role.label, style: TextStyle( color: color, fontSize: 12, fontWeight: FontWeight.w600, ), ), ), ), DataCell( Text( member.joinedAt != null ? DateFormat('yyyy/MM/dd').format(member.joinedAt!) : '—', style: const TextStyle(color: AppTheme.textSecondary), ), ), ], ); } } // ── Status Badge ───────────────────────────────────────────────────────────── class _StatusBadge extends StatelessWidget { final bool isActive; const _StatusBadge({required this.isActive}); @override Widget build(BuildContext context) { final color = isActive ? AppTheme.success : AppTheme.danger; return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: color.withValues(alpha: 0.12), borderRadius: BorderRadius.circular(20), ), child: Text( isActive ? 'فعال' : 'غیرفعال', style: TextStyle( color: color, fontSize: 12, fontWeight: FontWeight.w600, ), ), ); } }