import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:onufitness/constants/asset_constants.dart'; import 'package:onufitness/constants/color_constant.dart'; import 'package:onufitness/constants/text_constant.dart'; import 'package:onufitness/routes/route_constant.dart'; import 'package:onufitness/screens/chat/views/chat_inside_screen.dart'; import 'package:onufitness/screens/echoboard/controllers/connection_and_tribe_controller.dart'; import 'package:onufitness/screens/echoboard/controllers/profile_controller.dart'; import 'package:onufitness/screens/echoboard/controllers/tribe_member_controller.dart'; import 'package:onufitness/screens/echoboard/views/tribe_echoboard/tribe_member_add_screen.dart'; import 'package:onufitness/screens/echoboard/widget/friend_request_send_user_card.dart'; import 'package:onufitness/screens/echoboard/widget/pagination_widget.dart'; import 'package:onufitness/services/local_storage_services/shared_services.dart'; import 'package:onufitness/widgets/others/button_action_bottom_sheet.dart'; class TribeMemberDetailsScreen extends StatefulWidget { final String tribeName; final int tribeId; final String tribeImage; const TribeMemberDetailsScreen({ super.key, required this.tribeName, required this.tribeImage, required this.tribeId, }); @override State createState() => _TribeMemberDetailsScreenState(); } class _TribeMemberDetailsScreenState extends State { late final ProfileController profileController; late final SocialConnectionController controller; late final TribeMemberController tribeMemberController; @override void initState() { super.initState(); //Initialize Tribe Member Controller.................................................. if (!Get.isRegistered()) { Get.put(TribeMemberController()); } tribeMemberController = Get.find(); // Initialize profile controller.................................................. if (!Get.isRegistered()) { Get.put(ProfileController()); } profileController = Get.find(); // Initialize social connection controller.................................................. if (!Get.isRegistered()) { controller = Get.put(SocialConnectionController()); } else { controller = Get.find(); } // ✅ Set tab and fetch data after build.................................................. WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) { controller.currentTab.value = "TribeMembers"; controller.clearCurrentTabData(); // Clear any old data controller.searchUsers(tribeId: widget.tribeId); controller.getSingleTribeDetails(tribeId: widget.tribeId); } }); } @override void dispose() { super.dispose(); } // Handle search with proper data clearing void _handleSearch() { controller.clearCurrentTabData(); controller.searchUsers(tribeId: widget.tribeId); } // Handle clear search void _handleClearSearch() { controller.clearSearch(); // Manually trigger search for tribe members WidgetsBinding.instance.addPostFrameCallback((_) { if (mounted) { controller.currentTab.value = "TribeMembers"; controller.searchUsers(tribeId: widget.tribeId); } }); } void navigateToAddMembers() async { final result = await Get.to( () => AddTribeMembersScreen( tribeName: widget.tribeName, tribeId: widget.tribeId, tribeImage: widget.tribeImage, adminUserId: controller.usersData.value!.data!.items![0].tribAdminUserId!, ), ); // Refresh the member list if members were added if (result == true && mounted) { controller.clearCurrentTabData(); controller.searchUsers(tribeId: widget.tribeId); } } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { if (didPop) return; controller.searchValue.value = ""; controller.searchController.clear(); controller.currentTab.value = "Friends"; controller.searchUsers(clearOldData: true); Get.back(result: result); }, child: Scaffold( backgroundColor: pageBackGroundColor, appBar: AppBar( elevation: 0, backgroundColor: Colors.white, automaticallyImplyLeading: true, titleSpacing: 0, leading: IconButton( onPressed: () { controller.searchValue.value = ""; controller.searchController.clear(); controller.currentTab.value = "Friends"; controller.searchUsers(clearOldData: true); Get.back(); }, icon: const Icon(Icons.arrow_back_ios), ), title: Row( children: [ // Tribe profile image CircleAvatar( radius: 18, backgroundImage: widget.tribeImage.isNotEmpty ? NetworkImage(widget.tribeImage) : null, child: widget.tribeImage.isEmpty ? const Icon(Icons.group, size: 18) : null, ), const SizedBox(width: 10), // Tribe name + member count Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( widget.tribeName, style: const TextStyle( fontWeight: FontWeight.w600, fontSize: 16, color: Colors.black, ), overflow: TextOverflow.ellipsis, ), Row( children: [ Icon( Icons.group_outlined, size: 16.sp, color: Colors.grey, ), const SizedBox(width: 4), Obx( () => controller.isSingleTribeLoading.value ? Text( "Loading...", style: TextStyle( fontSize: verySmallSizeText, color: Colors.grey, ), ) : Text( '${controller.singleTribeDetails.value?.data?.totalMembers ?? 0} Members', style: TextStyle( fontSize: verySmallSizeText, color: Colors.grey, ), ), ), ], ), ], ), ), ], ), actions: [ Obx(() { final items = controller.usersData.value?.data?.items; final currentUserId = SharedServices.getUserDetails()?.data?.userId; final isAdmin = items != null && items.isNotEmpty && items.first.tribAdminUserId == currentUserId; return isAdmin ? Padding( padding: EdgeInsets.only(right: 10.w), child: IconButton( onPressed: navigateToAddMembers, icon: const Icon(Icons.add), tooltip: 'Add Members', ), ) : const SizedBox.shrink(); }), ], ), body: Column( children: [ Padding( padding: EdgeInsets.symmetric(horizontal: 15.sp, vertical: 15.h), child: TextField( controller: controller.searchController, decoration: InputDecoration( hintText: 'Search for members', hintStyle: TextStyle( fontWeight: FontWeight.w600, color: greyBorderColor, ), prefixIcon: const Padding( padding: EdgeInsets.only(left: 20), child: Icon(Icons.search), ), suffixIcon: IconButton( icon: const Padding( padding: EdgeInsets.only(right: 10), child: Icon(Icons.close), ), onPressed: _handleClearSearch, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30), borderSide: BorderSide(color: lightGreyColor, width: 1), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30), borderSide: const BorderSide( color: lightGreyColor, width: 1.2, ), ), filled: true, fillColor: Colors.white, ), onChanged: (value) => controller.onSearchChanged(value), onSubmitted: (_) => _handleSearch(), ), ), Expanded( child: Obx(() { // Show loading indicator if (controller.isLoading.value) { return const Center( child: CircularProgressIndicator(color: Colors.black), ); } // Safely access users with null checks final usersData = controller.usersData.value; final data = usersData?.data; final users = data?.items; // Show empty state if (users == null || users.isEmpty) { return Center( child: Text( controller.searchValue.value.isNotEmpty ? 'No members found matching "${controller.searchValue.value}"' : 'No members found', textAlign: TextAlign.center, style: TextStyle( fontSize: regularSizeText, color: Colors.grey[600], ), ), ); } // Check if current user is admin final currentUserId = SharedServices.getUserDetails()?.data?.userId; final adminUserId = users.isNotEmpty ? users.first.tribAdminUserId : null; final isAdmin = currentUserId != null && currentUserId == adminUserId; return ListView.builder( itemCount: users.length, padding: const EdgeInsets.all(10), itemBuilder: (context, index) { final user = users[index]; final isCurrentUserAdmin = isAdmin; final canDeleteMember = isCurrentUserAdmin && user.userId != adminUserId; return InkWell( onTap: () { if (user.userId != null) { profileController.selectedUserId.value = user.userId.toString(); Get.toNamed(RouteConstant.userSocialProfileScreen); } }, // long press for admin delete functionality onLongPress: canDeleteMember ? () { if (user.userId != null) { actionButtonBottomSheet( context: context, title: "Delete Member", subtitle: "Are you sure you want to delete this user ?", submitButtonText: "Delete Member", onPressed: () async { final success = await tribeMemberController .deleteTribeMember( tribeId: widget.tribeId, memberId: user.userId!, ); if (success && mounted) { // Refresh the member list after deletion Get.back(); controller.clearCurrentTabData(); controller.currentTab.value = "TribeMembers"; controller.searchUsers( tribeId: widget.tribeId, ); controller.getSingleTribeDetails( tribeId: widget.tribeId, ); } }, cancelButtonText: "Cancel", onCancelPressed: () { Get.back(); }, assetPath: AssetConstants.delete, primaryColor: Color(primaryColor), cancelBorderColor: lightGreyColor, isLoading: tribeMemberController .deleteTribeMemberLoading, ); } } : null, child: ConnectUserCard( user: user, onConnect: () async {}, onMessageUser: () { final agoraUserId = user.userId!.replaceAll("-", ""); Get.to( () => ChatDetailScreen( targetUserId: agoraUserId, targetUserName: user.fullName ?? "Unknown user", targetUserAvatar: user.userProfileImage, isGroupMessage: false, ), ); }, connectionStatus: user.connectionStatus ?? 'Accepted', loadingContains: controller.sendConnectionRequestLoading, isYourFriend: true, isTribeMemberPage: true, ), ); }, ); }), ), // Pagination widget showsUserListPagination(controller), ], ), ), ); } }