import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/svg.dart'; import 'package:syncrow_web/common/widgets/search_bar.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_bloc.dart'; import 'package:syncrow_web/pages/space_tree/bloc/space_tree_event.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/community_tile.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/widgets/space_tile_widget.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/style.dart'; class SpaceTreeView extends StatefulWidget { final List communities; final String? selectedCommunityId; final String? selectedSpaceUuid; final BuildContext buildContext; final Function action; final bool isLoading; const SpaceTreeView( {super.key, this.selectedCommunityId, required this.communities, this.selectedSpaceUuid, required this.buildContext, required this.action, required this.isLoading}); @override State createState() => _SpaceTreeViewState(); } class _SpaceTreeViewState extends State { String _searchQuery = ''; // Track search query String? _selectedSpaceUuid; String? _selectedCommunityId; String? _expandedId; @override void initState() { super.initState(); // _selectedId = widget.selectedSpaceUuid; // Initialize with the passed selected space UUID _selectedCommunityId = widget.selectedCommunityId; _selectedSpaceUuid = widget.selectedSpaceUuid; } @override void didUpdateWidget(covariant SpaceTreeView oldWidget) { super.didUpdateWidget(oldWidget); if (widget.selectedSpaceUuid != oldWidget.selectedSpaceUuid || widget.selectedCommunityId != oldWidget.selectedCommunityId) { setState(() { // _selectedId = widget.selectedSpaceUuid; _selectedCommunityId = widget.selectedCommunityId; _selectedSpaceUuid = widget.selectedSpaceUuid; }); } } // Function to filter communities based on the search query List _filterCommunities() { _expandedId = null; if (_searchQuery.isEmpty) { // Reset the selected community and space UUIDs if there's no query // _selectedSpaceUuid = null; // _selectedCommunityId = null; return widget.communities; } // Filter communities and expand only those that match the query return widget.communities.where((community) { final containsQueryInCommunity = community.name.toLowerCase().contains(_searchQuery.toLowerCase()); final containsQueryInSpaces = community.spaces.any((space) => _containsQuery(space, _searchQuery.toLowerCase())); return containsQueryInCommunity || containsQueryInSpaces; }).toList(); } // Helper function to determine if any space or its children match the search query bool _containsQuery(SpaceModel space, String query) { final matchesSpace = space.name.toLowerCase().contains(query); final matchesChildren = space.children.any((child) => _containsQuery(child, query)); // Recursive check for children // If the space or any of its children match the query, expand this space if (matchesSpace || matchesChildren) { _expandedId = space.uuid; } return matchesSpace || matchesChildren; } bool _isSpaceOrChildSelected(SpaceModel space) { // Return true if the current space or any of its child spaces is selected if (_expandedId == space.uuid) { return true; } // Recursively check if any child spaces match the query for (var child in space.children) { if (_isSpaceOrChildSelected(child)) { return true; } } return false; } @override Widget build(BuildContext context) { final filteredCommunities = _filterCommunities(); return Container( // width: MediaQuery.sizeOf(context).width * 0.25, height: MediaQuery.sizeOf(context).height, margin: const EdgeInsets.only(right: 24), decoration: subSectionContainerDecoration, child: widget.isLoading ? const Center(child: CircularProgressIndicator()) : Column( mainAxisSize: MainAxisSize.min, // Ensures the Column only takes necessary height crossAxisAlignment: CrossAxisAlignment.start, children: [ // Communities title with the add button Container( decoration: subSectionContainerDecoration, padding: const EdgeInsets.all(16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Communities', style: Theme.of(context).textTheme.titleMedium?.copyWith( color: Colors.black, )), GestureDetector( onTap: () => _navigateToBlank(context), child: Container( width: 30, height: 30, decoration: const BoxDecoration( color: ColorsManager.whiteColors, shape: BoxShape.circle, ), child: Center( child: SvgPicture.asset( Assets.roundedAddIcon, width: 24, height: 24, ), ), ), ), ], ), ), // Search bar CustomSearchBar( onSearchChanged: (query) { setState(() { _selectedSpaceUuid = null; _searchQuery = query; }); }, ), const SizedBox(height: 16), // Community list Expanded( child: ListView( children: filteredCommunities.map((community) { return _buildCommunityTile(context, community); }).toList(), ), ), ], ), ); } void _navigateToBlank(BuildContext context) { setState(() { // _selectedId = ''; _selectedSpaceUuid = ''; }); // context.read().add( // NewCommunityEvent(communities: widget.communities), // ); } Widget _buildCommunityTile(BuildContext context, CommunityModel community) { bool hasChildren = community.spaces.isNotEmpty; return CommunityTile( title: community.name, key: ValueKey(community.uuid), isSelected: _selectedCommunityId == community.uuid, isExpanded: false, onItemSelected: () { setState(() { _selectedCommunityId = community.uuid; _selectedSpaceUuid = null; }); widget.buildContext.read().add( OnSelectSpaceEvent(community.uuid, ''), ); widget.action(community.uuid, ''); }, onExpansionChanged: (String title, bool expanded) { _handleExpansionChange(community.uuid, expanded); }, children: hasChildren ? community.spaces.map((space) => _buildSpaceTile(space, community)).toList() : null, ); } Widget _buildSpaceTile(SpaceModel space, CommunityModel community) { return SpaceTile( title: space.name, key: ValueKey(space.uuid), isSelected: _selectedSpaceUuid == space.uuid, initiallyExpanded: _isSpaceOrChildSelected(space), onExpansionChanged: (bool expanded) { _handleExpansionChange(space.uuid ?? '', expanded); }, onItemSelected: () { setState(() { _selectedSpaceUuid = space.uuid; _selectedCommunityId = community.uuid; }); widget.buildContext.read().add( OnSelectSpaceEvent(community.uuid, space.uuid ?? ''), ); widget.action(community.uuid, space.uuid); }, children: space.children.isNotEmpty ? space.children.map((childSpace) => _buildSpaceTile(childSpace, community)).toList() : [], ); } void _handleExpansionChange(String uuid, bool expanded) {} }