Files
syncrow-web/lib/pages/spaces_management/widgets/sidebar_widget.dart
2024-10-11 13:21:30 +04:00

237 lines
8.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_svg/svg.dart';
import 'package:syncrow_web/common/search_bar.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/community_tile.dart';
import 'package:syncrow_web/pages/spaces_management/view/dialogs/create_community_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/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 SidebarWidget extends StatefulWidget {
final Function(CommunityModel)? onCommunitySelected;
final List<CommunityModel> communities;
const SidebarWidget(
{super.key, this.onCommunitySelected, required this.communities});
@override
_SidebarWidgetState createState() => _SidebarWidgetState();
}
class _SidebarWidgetState extends State<SidebarWidget> {
String _searchQuery = ''; // Track search query
String? _selectedCommunityUuid;
String? _selectedSpaceUuid;
@override
void initState() {
super.initState();
}
void _showCreateCommunityDialog(BuildContext parentContext) {
showDialog(
context: parentContext,
builder: (context) => CreateCommunityDialog(
onCreateCommunity:
(String communityName, String description, String regionId) {
parentContext.read<SpaceManagementBloc>().add(
CreateCommunityEvent(
name: communityName,
description: description,
regionId: regionId,
),
);
},
),
);
}
// Function to filter communities based on the search query
List<CommunityModel> _filterCommunities() {
if (_searchQuery.isEmpty) {
// Reset the selected community and space UUIDs if there's no query
_selectedCommunityUuid = null;
_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()));
if (containsQueryInCommunity || containsQueryInSpaces) {
_selectedCommunityUuid =
community.uuid; // Set the community to expanded
}
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,
),
GestureDetector(
onTap: () => _showCreateCommunityDialog(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(community);
}).toList(),
),
),
],
),
);
}
Widget _buildCommunityTile(CommunityModel community) {
bool hasChildren = community.spaces.isNotEmpty;
bool isSelectedCommunity = _selectedCommunityUuid ==
community.uuid; // Check if this community is selected
debugPrint('Building CommunityTile for ${community.name} with UUID: ${community.uuid}');
debugPrint('Currently selected community UUID: $_selectedCommunityUuid');
debugPrint('Is selected: $isSelectedCommunity');
return CommunityTile(
title: community.name,
isSelected: isSelectedCommunity,
isExpanded: false,
onItemSelected: () {
setState(() {
_selectedSpaceUuid = community.uuid; // Update the selected community
debugPrint(
'Selected community: ${community.name}, UUID: ${community.uuid}');
debugPrint(
'Updated selected community UUID: $_selectedCommunityUuid');
});
if (widget.onCommunitySelected != null) {
widget.onCommunitySelected!(community); // Pass the entire community
}
},
onExpansionChanged: (String title, bool expanded) {
debugPrint(
'CommunityTile onExpansionChanged called for $title, expanded: $expanded');
_handleExpansionChange(community.uuid, expanded);
},
children: hasChildren
? community.spaces.map((space) => _buildSpaceTile(space)).toList()
: null, // Render spaces within the community
);
}
Widget _buildSpaceTile(SpaceModel space) {
bool isSelectedSpace =
_isSpaceOrChildSelected(space); // Check if space should be expanded
debugPrint(
'Building SpaceTile for ${space.name}, hasChildren: ${space.children.isNotEmpty}');
return SpaceTile(
title: space.name,
initiallyExpanded: isSelectedSpace,
onExpansionChanged: (bool expanded) {
debugPrint(
'SpaceTile onExpansionChanged called for ${space.name}, expanded: $expanded');
_handleExpansionChange(space.uuid, expanded);
},
children: space.children.isNotEmpty
? space.children
.map((childSpace) => _buildSpaceTile(childSpace))
.toList()
: [], // Recursively render child spaces if available
);
}
void _handleExpansionChange(String uuid, bool expanded) {}
}