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/extension/build_context_x.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 State createState() => _SidebarWidgetState(); } class _SidebarWidgetState extends State { String _searchQuery = ''; String? _selectedSpaceUuid; String? _selectedId; @override void initState() { super.initState(); _selectedId = widget.selectedSpaceUuid; } @override void didUpdateWidget(covariant SidebarWidget oldWidget) { super.didUpdateWidget(oldWidget); if (widget.selectedSpaceUuid != oldWidget.selectedSpaceUuid) { setState(() { _selectedId = widget.selectedSpaceUuid; }); } } List _filterCommunities() { if (_searchQuery.isEmpty) { _selectedSpaceUuid = null; return widget.communities; } 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(); } bool _containsQuery(SpaceModel space, String query) { final matchesSpace = space.name.toLowerCase().contains(query); final matchesChildren = space.children.any( (child) => _containsQuery(child, query), ); if (matchesSpace || matchesChildren) { _selectedSpaceUuid = space.uuid; } return matchesSpace || matchesChildren; } bool _isSpaceOrChildSelected(SpaceModel space) { if (_selectedSpaceUuid == space.uuid) { return true; } 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, crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: subSectionContainerDecoration, padding: const EdgeInsets.all(16.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Communities', style: 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, ), ), ), ), ], ), ), CustomSearchBar( onSearchChanged: (query) => setState(() => _searchQuery = query), ), const SizedBox(height: 16), Expanded( child: ListView( children: filteredCommunities .map((community) => _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; }); context.read().add(CommunitySelectedEvent()); context.read().add( SelectCommunityEvent(selectedCommunity: community), ); }, onExpansionChanged: (title, 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 spaceIsExpanded = _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: spaceIsExpanded, onExpansionChanged: (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() : [], ), ); } }