Merge pull request #55 from SyncrowIOT/bugfix/community-flow

Bugfix/community flow
This commit is contained in:
Abdullah
2024-11-29 18:36:03 +03:00
committed by GitHub
10 changed files with 206 additions and 94 deletions

View File

@ -25,6 +25,7 @@ class SpaceManagementBloc
on<SaveSpacesEvent>(_onSaveSpaces); on<SaveSpacesEvent>(_onSaveSpaces);
on<FetchProductsEvent>(_onFetchProducts); on<FetchProductsEvent>(_onFetchProducts);
on<SelectSpaceEvent>(_onSelectSpace); on<SelectSpaceEvent>(_onSelectSpace);
on<NewCommunityEvent>(_onNewCommunity);
} }
void _onUpdateCommunity( void _onUpdateCommunity(
@ -83,6 +84,25 @@ class SpaceManagementBloc
return await _api.getSpaceHierarchy(communityUuid); return await _api.getSpaceHierarchy(communityUuid);
} }
void _onNewCommunity(
NewCommunityEvent event,
Emitter<SpaceManagementState> emit,
) {
try {
if (event.communities.isEmpty) {
emit(const SpaceManagementError('No communities provided.'));
return;
}
emit(BlankState(
communities: event.communities,
products: _cachedProducts ?? [],
));
} catch (error) {
emit(SpaceManagementError('Error loading communities: $error'));
}
}
void _onLoadCommunityAndSpaces( void _onLoadCommunityAndSpaces(
LoadCommunityAndSpacesEvent event, LoadCommunityAndSpacesEvent event,
Emitter<SpaceManagementState> emit, Emitter<SpaceManagementState> emit,
@ -151,14 +171,16 @@ class SpaceManagementBloc
await _api.createCommunity(event.name, event.description); await _api.createCommunity(event.name, event.description);
if (newCommunity != null) { if (newCommunity != null) {
if (previousState is SpaceManagementLoaded) { if (previousState is SpaceManagementLoaded ||
final updatedCommunities = previousState is BlankState) {
List<CommunityModel>.from(previousState.communities) final prevCommunities = List<CommunityModel>.from(
..add(newCommunity); (previousState as dynamic).communities,
);
final updatedCommunities = prevCommunities..add(newCommunity);
emit(SpaceManagementLoaded( emit(SpaceManagementLoaded(
communities: updatedCommunities, communities: updatedCommunities,
products: _cachedProducts ?? [], products: _cachedProducts ?? [],
selectedCommunity: null, selectedCommunity: newCommunity,
selectedSpace: null)); selectedSpace: null));
} }
} else { } else {
@ -200,7 +222,8 @@ class SpaceManagementBloc
emit(SpaceManagementLoading()); emit(SpaceManagementLoading());
try { try {
if (previousState is SpaceManagementLoaded) { if (previousState is SpaceManagementLoaded ||
previousState is BlankState) {
final communities = List<CommunityModel>.from( final communities = List<CommunityModel>.from(
(previousState as dynamic).communities, (previousState as dynamic).communities,
); );

View File

@ -108,6 +108,15 @@ class SelectCommunityEvent extends SpaceManagementEvent {
List<Object> get props => []; List<Object> get props => [];
} }
class NewCommunityEvent extends SpaceManagementEvent {
final List<CommunityModel> communities;
const NewCommunityEvent({required this.communities});
@override
List<Object> get props => [communities];
}
class SelectSpaceEvent extends SpaceManagementEvent { class SelectSpaceEvent extends SpaceManagementEvent {
final CommunityModel? selectedCommunity; final CommunityModel? selectedCommunity;
final SpaceModel? selectedSpace; final SpaceModel? selectedSpace;

View File

@ -27,6 +27,16 @@ class SpaceManagementLoaded extends SpaceManagementState {
this.selectedSpace}); this.selectedSpace});
} }
class BlankState extends SpaceManagementState {
final List<CommunityModel> communities;
final List<ProductModel> products;
BlankState({
required this.communities,
required this.products,
});
}
class SpaceCreationSuccess extends SpaceManagementState { class SpaceCreationSuccess extends SpaceManagementState {
final List<SpaceModel> spaces; final List<SpaceModel> spaces;

View File

@ -45,6 +45,13 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
builder: (context, state) { builder: (context, state) {
if (state is SpaceManagementLoading) { if (state is SpaceManagementLoading) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} else if (state is BlankState) {
return LoadedSpaceView(
communities: state.communities,
selectedCommunity: null,
selectedSpace: null,
products: state.products,
);
} else if (state is SpaceManagementLoaded) { } else if (state is SpaceManagementLoaded) {
return LoadedSpaceView( return LoadedSpaceView(
communities: state.communities, communities: state.communities,

View File

@ -2,12 +2,20 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.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/bloc/space_management_event.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/create_community_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/create_community_dialog.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
class BlankCommunityWidget extends StatelessWidget { class BlankCommunityWidget extends StatefulWidget {
const BlankCommunityWidget({Key? key}) : super(key: key); final List<CommunityModel> communities;
BlankCommunityWidget({required this.communities});
@override
_BlankCommunityWidgetState createState() => _BlankCommunityWidgetState();
}
class _BlankCommunityWidgetState extends State<BlankCommunityWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Expanded( return Expanded(
@ -17,11 +25,10 @@ class BlankCommunityWidget extends StatelessWidget {
child: GridView.builder( child: GridView.builder(
padding: const EdgeInsets.only(left: 40.0, top: 20.0), padding: const EdgeInsets.only(left: 40.0, top: 20.0),
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 400, // Each item's width will be 400 or less maxCrossAxisExtent: 400,
mainAxisSpacing: 10, // Spacing between items mainAxisSpacing: 10,
crossAxisSpacing: 10, // Spacing between items crossAxisSpacing: 10,
childAspectRatio: childAspectRatio: 2.0,
2.0, // Aspect ratio for width:height (e.g., 300:150 = 2.0)
), ),
itemCount: 1, // Only one item itemCount: 1, // Only one item
itemBuilder: (context, index) { itemBuilder: (context, index) {
@ -48,9 +55,8 @@ class BlankCommunityWidget extends StatelessWidget {
), ),
), ),
), ),
const SizedBox(height: 9),
const SizedBox(height: 9), // Space between item and text Text('Blank',
Text('Blank', // Text below the item
style: Theme.of(context).textTheme.bodyLarge?.copyWith( style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: ColorsManager.blackColor, color: ColorsManager.blackColor,
)), )),
@ -66,6 +72,7 @@ class BlankCommunityWidget extends StatelessWidget {
showDialog( showDialog(
context: parentContext, context: parentContext,
builder: (context) => CreateCommunityDialog( builder: (context) => CreateCommunityDialog(
communities: widget.communities,
onCreateCommunity: (String communityName, String description) { onCreateCommunity: (String communityName, String description) {
parentContext.read<SpaceManagementBloc>().add( parentContext.read<SpaceManagementBloc>().add(
CreateCommunityEvent( CreateCommunityEvent(

View File

@ -24,12 +24,13 @@ class CommunityStructureArea extends StatefulWidget {
SpaceModel? selectedSpace; SpaceModel? selectedSpace;
final List<ProductModel>? products; final List<ProductModel>? products;
final ValueChanged<SpaceModel?>? onSpaceSelected; final ValueChanged<SpaceModel?>? onSpaceSelected;
final List<CommunityModel> communities;
final List<SpaceModel> spaces; final List<SpaceModel> spaces;
CommunityStructureArea({ CommunityStructureArea({
this.selectedCommunity, this.selectedCommunity,
this.selectedSpace, this.selectedSpace,
required this.communities,
this.products, this.products,
required this.spaces, required this.spaces,
this.onSpaceSelected, this.onSpaceSelected,
@ -97,7 +98,9 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.selectedCommunity == null) { if (widget.selectedCommunity == null) {
return BlankCommunityWidget(); return BlankCommunityWidget(
communities: widget.communities,
);
} }
Size screenSize = MediaQuery.of(context).size; Size screenSize = MediaQuery.of(context).size;
@ -328,6 +331,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
products: widget.products, products: widget.products,
name: space.name, name: space.name,
icon: space.icon, icon: space.icon,
editSpace: space,
isEdit: true, isEdit: true,
selectedProducts: space.selectedProducts, selectedProducts: space.selectedProducts,
onCreateSpace: (String name, String icon, onCreateSpace: (String name, String icon,

View File

@ -1,37 +1,47 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
class CreateCommunityDialog extends StatefulWidget { class CreateCommunityDialog extends StatefulWidget {
final Function(String name, String description) onCreateCommunity; final Function(String name, String description) onCreateCommunity;
final List<CommunityModel> communities;
const CreateCommunityDialog({super.key, required this.onCreateCommunity}); const CreateCommunityDialog(
{super.key, required this.onCreateCommunity, required this.communities});
@override @override
CreateCommunityDialogState createState() => CreateCommunityDialogState(); CreateCommunityDialogState createState() => CreateCommunityDialogState();
} }
class CreateCommunityDialogState extends State<CreateCommunityDialog> { class CreateCommunityDialogState extends State<CreateCommunityDialog> {
String enteredName = ''; // Store the entered community name String enteredName = '';
bool isNameFieldExist = false;
bool isNameEmpty = false;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return Dialog( return Dialog(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
), ),
backgroundColor: Colors.transparent, // Transparent for shadow effect backgroundColor:
ColorsManager.transparentColor, // Transparent for shadow effect
child: Stack( child: Stack(
children: [ children: [
// Background container with shadow and rounded corners // Background container with shadow and rounded corners
Container( Container(
width: 490, width: screenWidth * 0.3,
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: ColorsManager.whiteColors,
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Colors.black.withOpacity(0.25), color: ColorsManager.blackColor.withOpacity(0.25),
blurRadius: 20, blurRadius: 20,
spreadRadius: 5, spreadRadius: 5,
offset: const Offset(0, 5), offset: const Offset(0, 5),
@ -53,10 +63,20 @@ class CreateCommunityDialogState extends State<CreateCommunityDialog> {
// Input field for the community name // Input field for the community name
TextField( TextField(
onChanged: (value) { onChanged: (value) {
enteredName = value; // Capture entered name setState(() {
enteredName = value.trim();
isNameFieldExist = widget.communities.any(
(community) => community.name == enteredName,
);
if (value.isEmpty) {
isNameEmpty = true;
} else {
isNameEmpty = false;
}
});
}, },
style: const TextStyle( style: const TextStyle(
color: Colors.black, color: ColorsManager.blackColor,
), ),
decoration: InputDecoration( decoration: InputDecoration(
hintText: 'Please enter the community name', hintText: 'Please enter the community name',
@ -68,45 +88,68 @@ class CreateCommunityDialogState extends State<CreateCommunityDialog> {
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
), ),
border: OutlineInputBorder( border: OutlineInputBorder(
borderSide: const BorderSide(color: ColorsManager.boxColor, width: 1), borderSide: BorderSide(
color: isNameFieldExist || isNameEmpty
? ColorsManager.red
: ColorsManager.boxColor,
width: 1),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: const BorderSide(color: ColorsManager.boxColor, width: 1), borderSide: BorderSide(
color: isNameFieldExist || isNameEmpty
? ColorsManager.red
: ColorsManager.boxColor, width: 1),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: ColorsManager.boxColor, width: 1), borderSide: BorderSide(
color: isNameFieldExist || isNameEmpty
? ColorsManager.red
: ColorsManager.boxColor,
width: 1),
), ),
), ),
), ),
if (isNameFieldExist)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'*Name already exists.',
style: Theme.of(context)
.textTheme
.bodySmall
?.copyWith(color: ColorsManager.red),
),
),
if (isNameEmpty)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(
'*Name should not be empty.',
style: Theme.of(context)
.textTheme
.bodySmall
?.copyWith(color: ColorsManager.red),
),
),
const SizedBox(height: 24), const SizedBox(height: 24),
// Action buttons // Action buttons
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Expanded( Expanded(
child: TextButton( child: CancelButton(
label: 'Cancel',
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
style: TextButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: ColorsManager.boxColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: const Text(
'Cancel',
style: TextStyle(color: Colors.black),
),
), ),
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded( Expanded(
child: ElevatedButton( child: DefaultButton(
onPressed: () { onPressed: () {
if (enteredName.isNotEmpty) { if (enteredName.isNotEmpty && !isNameFieldExist) {
widget.onCreateCommunity( widget.onCreateCommunity(
enteredName, enteredName,
"", "",
@ -114,14 +157,11 @@ class CreateCommunityDialogState extends State<CreateCommunityDialog> {
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
}, },
style: ElevatedButton.styleFrom( backgroundColor: isNameFieldExist || isNameEmpty
padding: const EdgeInsets.symmetric(vertical: 16), ? ColorsManager.lightGrayColor
backgroundColor: ColorsManager.secondaryColor, : ColorsManager.secondaryColor,
foregroundColor: Colors.white, borderRadius: 10,
shape: RoundedRectangleBorder( foregroundColor: ColorsManager.whiteColors,
borderRadius: BorderRadius.circular(10),
),
),
child: const Text('OK'), child: const Text('OK'),
), ),
), ),

View File

@ -13,13 +13,15 @@ import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/constants/space_icon_const.dart'; import 'package:syncrow_web/utils/constants/space_icon_const.dart';
class CreateSpaceDialog extends StatefulWidget { class CreateSpaceDialog extends StatefulWidget {
final Function(String, String, List<SelectedProduct> selectedProducts) onCreateSpace; final Function(String, String, List<SelectedProduct> selectedProducts)
onCreateSpace;
final List<ProductModel>? products; final List<ProductModel>? products;
final String? name; final String? name;
final String? icon; final String? icon;
final bool isEdit; final bool isEdit;
final List<SelectedProduct> selectedProducts; final List<SelectedProduct> selectedProducts;
final SpaceModel? parentSpace; final SpaceModel? parentSpace;
final SpaceModel? editSpace;
const CreateSpaceDialog( const CreateSpaceDialog(
{super.key, {super.key,
@ -29,6 +31,7 @@ class CreateSpaceDialog extends StatefulWidget {
this.name, this.name,
this.icon, this.icon,
this.isEdit = false, this.isEdit = false,
this.editSpace,
this.selectedProducts = const []}); this.selectedProducts = const []});
@override @override
@ -49,8 +52,10 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
super.initState(); super.initState();
selectedIcon = widget.icon ?? Assets.location; selectedIcon = widget.icon ?? Assets.location;
nameController = TextEditingController(text: widget.name ?? ''); nameController = TextEditingController(text: widget.name ?? '');
selectedProducts = widget.selectedProducts.isNotEmpty ? widget.selectedProducts : []; selectedProducts =
isOkButtonEnabled = enteredName.isNotEmpty || nameController.text.isNotEmpty; widget.selectedProducts.isNotEmpty ? widget.selectedProducts : [];
isOkButtonEnabled =
enteredName.isNotEmpty || nameController.text.isNotEmpty;
} }
@override @override
@ -59,7 +64,9 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
final screenWidth = MediaQuery.of(context).size.width; final screenWidth = MediaQuery.of(context).size.width;
return AlertDialog( return AlertDialog(
title: widget.isEdit ? const Text('Edit Space') : const Text('Create New Space'), title: widget.isEdit
? const Text('Edit Space')
: const Text('Create New Space'),
backgroundColor: ColorsManager.whiteColors, backgroundColor: ColorsManager.whiteColors,
content: SizedBox( content: SizedBox(
width: screenWidth * 0.5, // Limit dialog width width: screenWidth * 0.5, // Limit dialog width
@ -126,11 +133,17 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
isNameFieldInvalid = value.isEmpty; isNameFieldInvalid = value.isEmpty;
if (!isNameFieldInvalid) { if (!isNameFieldInvalid) {
if (widget.parentSpace?.children if ((widget.parentSpace?.children.any(
.any((child) => child.name == value) ?? (child) => child.name == value) ??
false) { false) ||
(widget.parentSpace?.name == value) ||
(widget.editSpace?.children.any(
(child) => child.name == value) ??
false)) {
isNameFieldExist = true; isNameFieldExist = true;
isOkButtonEnabled = false;
} else { } else {
isNameFieldExist = false;
isOkButtonEnabled = true; isOkButtonEnabled = true;
} }
} }
@ -218,7 +231,8 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
padding: const EdgeInsets.only(left: 6.0), padding: const EdgeInsets.only(left: 6.0),
child: SvgPicture.asset( child: SvgPicture.asset(
Assets.addIcon, Assets.addIcon,
width: screenWidth * 0.015, // Adjust icon size width: screenWidth *
0.015, // Adjust icon size
height: screenWidth * 0.015, height: screenWidth * 0.015,
), ),
), ),
@ -226,8 +240,11 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
Flexible( Flexible(
child: Text( child: Text(
'Add devices / Assign a space model', 'Add devices / Assign a space model',
overflow: TextOverflow.ellipsis, // Prevent overflow overflow: TextOverflow
style: Theme.of(context).textTheme.bodyMedium, .ellipsis, // Prevent overflow
style: Theme.of(context)
.textTheme
.bodyMedium,
), ),
), ),
], ],
@ -262,16 +279,20 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
}); });
return; return;
} else { } else {
String newName = enteredName.isNotEmpty ? enteredName : (widget.name ?? ''); String newName = enteredName.isNotEmpty
? enteredName
: (widget.name ?? '');
if (newName.isNotEmpty) { if (newName.isNotEmpty) {
widget.onCreateSpace(newName, selectedIcon, selectedProducts); widget.onCreateSpace(
newName, selectedIcon, selectedProducts);
Navigator.of(context).pop(); Navigator.of(context).pop();
} }
} }
}, },
borderRadius: 10, borderRadius: 10,
backgroundColor: backgroundColor: isOkButtonEnabled
isOkButtonEnabled ? ColorsManager.secondaryColor : ColorsManager.grayColor, ? ColorsManager.secondaryColor
: ColorsManager.grayColor,
foregroundColor: ColorsManager.whiteColors, foregroundColor: ColorsManager.whiteColors,
child: const Text('OK'), child: const Text('OK'),
), ),
@ -318,7 +339,8 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
children: [ children: [
for (var i = 0; i < selectedProducts.length; i++) ...[ for (var i = 0; i < selectedProducts.length; i++) ...[
HoverableButton( HoverableButton(
iconPath: _mapIconToProduct(selectedProducts[i].productId, products), iconPath:
_mapIconToProduct(selectedProducts[i].productId, products),
text: 'x${selectedProducts[i].count}', text: 'x${selectedProducts[i].count}',
onTap: () { onTap: () {
setState(() { setState(() {
@ -328,7 +350,8 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
}, },
), ),
if (i < selectedProducts.length - 1) if (i < selectedProducts.length - 1)
const SizedBox(width: 2), // Add space except after the last button const SizedBox(
width: 2), // Add space except after the last button
], ],
const SizedBox(width: 2), const SizedBox(width: 2),
GestureDetector( GestureDetector(
@ -364,6 +387,8 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
); );
} }
String _mapIconToProduct(String uuid, List<ProductModel> products) { String _mapIconToProduct(String uuid, List<ProductModel> products) {
// Find the product with the matching UUID // Find the product with the matching UUID
final product = products.firstWhere( final product = products.firstWhere(

View File

@ -34,13 +34,16 @@ class _LoadedStateViewState extends State<LoadedSpaceView> {
children: [ children: [
SidebarWidget( SidebarWidget(
communities: widget.communities, communities: widget.communities,
selectedSpaceUuid: widget.selectedSpace?.uuid, selectedSpaceUuid: widget.selectedSpace?.uuid ??
widget.selectedCommunity?.uuid ??
'',
), ),
CommunityStructureArea( CommunityStructureArea(
selectedCommunity: widget.selectedCommunity, selectedCommunity: widget.selectedCommunity,
selectedSpace: widget.selectedSpace, selectedSpace: widget.selectedSpace,
spaces: widget.selectedCommunity?.spaces ?? [], spaces: widget.selectedCommunity?.spaces ?? [],
products: widget.products, products: widget.products,
communities: widget.communities,
), ),
], ],
), ),

View File

@ -7,25 +7,17 @@ import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.
import 'package:syncrow_web/pages/spaces_management/model/community_model.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/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/community_tile.dart'; import 'package:syncrow_web/pages/spaces_management/widgets/community_tile.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/dialogs/create_community_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/space_tile_widget.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/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
import 'package:syncrow_web/utils/style.dart'; import 'package:syncrow_web/utils/style.dart';
class SidebarWidget extends StatefulWidget { class SidebarWidget extends StatefulWidget {
final Function(CommunityModel)? onCommunitySelected;
final Function(SpaceModel?)? onSpaceSelected;
final List<CommunityModel> communities; final List<CommunityModel> communities;
final Function(String?)? onSelectedSpaceChanged; // New callback
final String? selectedSpaceUuid; final String? selectedSpaceUuid;
const SidebarWidget({ const SidebarWidget({
super.key, super.key,
this.onCommunitySelected,
this.onSpaceSelected,
this.onSelectedSpaceChanged,
required this.communities, required this.communities,
this.selectedSpaceUuid, this.selectedSpaceUuid,
}); });
@ -56,22 +48,6 @@ class _SidebarWidgetState extends State<SidebarWidget> {
} }
} }
void _showCreateCommunityDialog(BuildContext parentContext) {
showDialog(
context: parentContext,
builder: (context) => CreateCommunityDialog(
onCreateCommunity: (String communityName, String description) {
parentContext.read<SpaceManagementBloc>().add(
CreateCommunityEvent(
name: communityName,
description: description,
),
);
},
),
);
}
// Function to filter communities based on the search query // Function to filter communities based on the search query
List<CommunityModel> _filterCommunities() { List<CommunityModel> _filterCommunities() {
if (_searchQuery.isEmpty) { if (_searchQuery.isEmpty) {
@ -145,7 +121,7 @@ class _SidebarWidgetState extends State<SidebarWidget> {
color: Colors.black, color: Colors.black,
)), )),
GestureDetector( GestureDetector(
onTap: () => _showCreateCommunityDialog(context), onTap: () => _navigateToBlank(context),
child: Container( child: Container(
width: 30, width: 30,
height: 30, height: 30,
@ -187,6 +163,15 @@ class _SidebarWidgetState extends State<SidebarWidget> {
); );
} }
void _navigateToBlank(BuildContext context) {
setState(() {
_selectedId = '';
});
context.read<SpaceManagementBloc>().add(
NewCommunityEvent(communities: widget.communities),
);
}
Widget _buildCommunityTile(BuildContext context, CommunityModel community) { Widget _buildCommunityTile(BuildContext context, CommunityModel community) {
bool hasChildren = community.spaces.isNotEmpty; bool hasChildren = community.spaces.isNotEmpty;
@ -218,7 +203,6 @@ class _SidebarWidgetState extends State<SidebarWidget> {
Widget _buildSpaceTile(SpaceModel space, CommunityModel community) { Widget _buildSpaceTile(SpaceModel space, CommunityModel community) {
bool isExpandedSpace = _isSpaceOrChildSelected(space); bool isExpandedSpace = _isSpaceOrChildSelected(space);
// Check if space should be expanded
return SpaceTile( return SpaceTile(
title: space.name, title: space.name,
key: ValueKey(space.uuid), key: ValueKey(space.uuid),