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/spaces_management/all_spaces/bloc/space_management_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/bloc/space_management_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/pages/spaces_management/structure_selector/bloc/center_body_bloc.dart'; import 'package:syncrow_web/pages/spaces_management/structure_selector/bloc/center_body_event.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 SidebarWidget extends StatefulWidget { final List communities; final String? selectedSpaceUuid; const SidebarWidget({ super.key, required this.communities, this.selectedSpaceUuid, }); @override _SidebarWidgetState createState() => _SidebarWidgetState(); } class _SidebarWidgetState extends State { String _searchQuery = ''; // Track search query String? _selectedSpaceUuid; String? _selectedId; @override void initState() { super.initState(); _selectedId = widget.selectedSpaceUuid; // Initialize with the passed selected space UUID } @override void didUpdateWidget(covariant SidebarWidget oldWidget) { super.didUpdateWidget(oldWidget); if (widget.selectedSpaceUuid != oldWidget.selectedSpaceUuid) { setState(() { _selectedId = widget.selectedSpaceUuid; }); } } // Function to filter communities based on the search query List _filterCommunities() { if (_searchQuery.isEmpty) { // Reset the selected community and space UUIDs if there's no query _selectedSpaceUuid = 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) { _selectedSpaceUuid = space.uuid; } return matchesSpace || matchesChildren; } bool _isSpaceOrChildSelected(SpaceModel space) { // Return true if the current space or any of its child spaces is selected if (_selectedSpaceUuid == 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: 300, decoration: subSectionContainerDecoration, child: 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: ColorsManager.blackColor, )), 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(() { _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 = ''; }); 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: _selectedId == community.uuid, isExpanded: false, onItemSelected: () { setState(() { _selectedId = community.uuid; _selectedSpaceUuid = null; // Update the selected community }); context.read().add(CommunitySelectedEvent()); context.read().add( SelectCommunityEvent(selectedCommunity: community), ); }, onExpansionChanged: (String title, bool expanded) { _handleExpansionChange(community.uuid, expanded); }, children: hasChildren ? community.spaces .where((space) => (space.status != SpaceStatus.deleted || space.status != SpaceStatus.parentDeleted)) .map((space) => _buildSpaceTile(space, community)) .toList() : null, ); } Widget _buildSpaceTile(SpaceModel space, CommunityModel community, {int depth = 1}) { bool isExpandedSpace = _isSpaceOrChildSelected(space); return Padding( padding: EdgeInsets.only(left: depth * 16.0), child: SpaceTile( title: space.name, key: ValueKey(space.uuid), isSelected: _selectedId == space.uuid, initiallyExpanded: isExpandedSpace, onExpansionChanged: (bool expanded) { _handleExpansionChange(space.uuid ?? '', expanded); }, onItemSelected: () { setState(() { _selectedId = space.uuid; _selectedSpaceUuid = space.uuid; }); context.read().add( SelectSpaceEvent(selectedCommunity: community, selectedSpace: space), ); }, children: space.children.isNotEmpty ? space.children.map((childSpace) => _buildSpaceTile(childSpace, community)).toList() : [], // Recursively render child spaces if available )); } void _handleExpansionChange(String uuid, bool expanded) {} }