From 62f67f5a5f8250ff94ad4697fd9ce0c11eb0e08d Mon Sep 17 00:00:00 2001 From: Faris Armoush Date: Wed, 16 Jul 2025 11:16:41 +0300 Subject: [PATCH] Refactor CreateSpaceButton and CommunityStructureCanvas to utilize CommunityModel directly, enhancing data handling during space creation. Implement success callback for space creation to update community state in CommunitiesBloc, improving user experience and maintainability. --- .../widgets/community_structure_canvas.dart | 15 +++++- .../widgets/create_space_button.dart | 17 ++++-- .../space_management_community_structure.dart | 49 ++++++++++------- .../helpers/space_details_dialog_helper.dart | 54 ++++++++++++++++--- 4 files changed, 107 insertions(+), 28 deletions(-) diff --git a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart index 0fa5630b..63f8e8ec 100644 --- a/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart +++ b/lib/pages/space_management_v2/main_module/widgets/community_structure_canvas.dart @@ -268,7 +268,7 @@ class _CommunityStructureCanvasState extends State Positioned( left: createButtonX, top: createButtonY, - child: CreateSpaceButton(communityUuid: widget.community.uuid), + child: CreateSpaceButton(community: widget.community), ), ); @@ -327,6 +327,19 @@ class _CommunityStructureCanvasState extends State onTap: () => SpaceDetailsDialogHelper.showCreate( context, communityUuid: widget.community.uuid, + parentUuid: space.uuid, + onSuccess: (updatedSpaceModel) { + // TODO(FarisArmoush): insert the space under the parent, which is the space that was tapped + final newCommunity = widget.community.copyWith(); + final parentIndex = + newCommunity.spaces.indexWhere((s) => s.uuid == space.uuid); + if (parentIndex != -1) { + newCommunity.spaces.insert(parentIndex + 1, updatedSpaceModel); + } + context.read().add( + CommunitiesUpdateCommunity(newCommunity), + ); + }, ), ); diff --git a/lib/pages/space_management_v2/main_module/widgets/create_space_button.dart b/lib/pages/space_management_v2/main_module/widgets/create_space_button.dart index e6dfbb15..610962e5 100644 --- a/lib/pages/space_management_v2/main_module/widgets/create_space_button.dart +++ b/lib/pages/space_management_v2/main_module/widgets/create_space_button.dart @@ -1,14 +1,17 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/community_model.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/bloc/communities_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class CreateSpaceButton extends StatefulWidget { const CreateSpaceButton({ - required this.communityUuid, + required this.community, super.key, }); - final String communityUuid; + final CommunityModel community; @override State createState() => _CreateSpaceButtonState(); @@ -25,7 +28,15 @@ class _CreateSpaceButtonState extends State { child: InkWell( onTap: () => SpaceDetailsDialogHelper.showCreate( context, - communityUuid: widget.communityUuid, + communityUuid: widget.community.uuid, + onSuccess: (updatedSpaceModel) { + final newCommunity = widget.community.copyWith( + spaces: [updatedSpaceModel, ...widget.community.spaces], + ); + context.read().add( + CommunitiesUpdateCommunity(newCommunity), + ); + }, ), child: MouseRegion( onEnter: (_) => setState(() => _isHovered = true), diff --git a/lib/pages/space_management_v2/main_module/widgets/space_management_community_structure.dart b/lib/pages/space_management_v2/main_module/widgets/space_management_community_structure.dart index b325c1ec..11478fbe 100644 --- a/lib/pages/space_management_v2/main_module/widgets/space_management_community_structure.dart +++ b/lib/pages/space_management_v2/main_module/widgets/space_management_community_structure.dart @@ -5,6 +5,7 @@ import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/commun import 'package:syncrow_web/pages/space_management_v2/main_module/widgets/create_space_button.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/community_model.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/space_model.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/bloc/communities_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/presentation/communities_tree_selection_bloc/communities_tree_selection_bloc.dart'; class SpaceManagementCommunityStructure extends StatelessWidget { @@ -12,19 +13,35 @@ class SpaceManagementCommunityStructure extends StatelessWidget { @override Widget build(BuildContext context) { - final selectionBloc = context.watch().state; - final selectedCommunity = selectionBloc.selectedCommunity; - final selectedSpace = selectionBloc.selectedSpace; - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - const CommunityStructureHeader(), - Visibility( - visible: selectedCommunity!.spaces.isNotEmpty, - replacement: _buildEmptyWidget(selectedCommunity), - child: _buildCanvas(selectedCommunity, selectedSpace), - ), - ], + return BlocBuilder( + builder: (context, state) { + final selectedCommunity = state.selectedCommunity; + final selectedSpace = state.selectedSpace; + + if (selectedCommunity == null) { + return const SizedBox.shrink(); + } + + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + const CommunityStructureHeader(), + BlocBuilder( + builder: (context, state) { + final community = state.communities.firstWhere( + (element) => element.uuid == selectedCommunity.uuid, + orElse: () => selectedCommunity, + ); + return Visibility( + visible: community.spaces.isNotEmpty, + replacement: _buildEmptyWidget(community), + child: _buildCanvas(community, selectedSpace), + ); + }, + ), + ], + ); + }, ); } @@ -47,11 +64,7 @@ class SpaceManagementCommunityStructure extends StatelessWidget { child: Row( children: [ spacer, - Expanded( - child: CreateSpaceButton( - communityUuid: selectedCommunity.uuid, - ), - ), + Expanded(child: CreateSpaceButton(community: selectedCommunity)), spacer, ], ), diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart b/lib/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart index c5de7dad..45cb0e89 100644 --- a/lib/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart +++ b/lib/pages/space_management_v2/modules/space_details/presentation/helpers/space_details_dialog_helper.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/communities/domain/models/space_model.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/create_space/data/services/remote_create_space_service.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/create_space/domain/params/create_space_param.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/create_space/presentation/bloc/create_space_bloc.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/data/services/remote_space_details_service.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_bloc.dart'; @@ -14,6 +17,8 @@ abstract final class SpaceDetailsDialogHelper { static void showCreate( BuildContext context, { required String communityUuid, + required void Function(SpaceModel updatedSpaceModel)? onSuccess, + String? parentUuid, }) { showDialog( context: context, @@ -24,14 +29,41 @@ abstract final class SpaceDetailsDialogHelper { RemoteSpaceDetailsService(httpService: HTTPService()), ), ), + BlocProvider( + create: (context) => CreateSpaceBloc( + RemoteCreateSpaceService(HTTPService()), + ), + ), ], child: Builder( - builder: (context) => SpaceDetailsDialog( - context: context, - title: const SelectableText('Create Space'), - spaceModel: SpaceModel.empty(), - onSave: (space) {}, - communityUuid: communityUuid, + builder: (context) => BlocListener( + listener: (context, state) => switch (state) { + CreateSpaceInitial() => null, + CreateSpaceLoading() => _onLoading(context), + CreateSpaceSuccess() => _onCreateSuccess( + context, + state.space, + onSuccess, + ), + CreateSpaceFailure() => _onError(context, state.errorMessage), + }, + child: SpaceDetailsDialog( + context: context, + title: const SelectableText('Create Space'), + spaceModel: SpaceModel.empty(), + onSave: (space) { + context.read().add( + CreateSpace( + CreateSpaceParam( + communityUuid: communityUuid, + space: space, + parentUuid: parentUuid, + ), + ), + ); + }, + communityUuid: communityUuid, + ), ), ), ), @@ -135,4 +167,14 @@ abstract final class SpaceDetailsDialogHelper { ), ); } + + static void _onCreateSuccess( + BuildContext context, + SpaceModel space, + void Function(SpaceModel updatedSpaceModel)? onSuccess, + ) { + Navigator.of(context).pop(); + Navigator.of(context).pop(); + onSuccess?.call(space); + } }