diff --git a/lib/pages/space_management_v2/main_module/widgets/community_structure_header.dart b/lib/pages/space_management_v2/main_module/widgets/community_structure_header.dart index 4f71075b..5b790514 100644 --- a/lib/pages/space_management_v2/main_module/widgets/community_structure_header.dart +++ b/lib/pages/space_management_v2/main_module/widgets/community_structure_header.dart @@ -97,6 +97,7 @@ class CommunityStructureHeader extends StatelessWidget { SpaceDetailsDialogHelper.showEdit( context, spaceModel: selectedSpace!, + communityUuid: selectedCommunity.uuid, ); }, selectedSpace: selectedSpace, diff --git a/lib/pages/space_management_v2/modules/communities/presentation/widgets/communities_tree_failure_widget.dart b/lib/pages/space_management_v2/modules/communities/presentation/widgets/communities_tree_failure_widget.dart index cfd32f52..277347df 100644 --- a/lib/pages/space_management_v2/modules/communities/presentation/widgets/communities_tree_failure_widget.dart +++ b/lib/pages/space_management_v2/modules/communities/presentation/widgets/communities_tree_failure_widget.dart @@ -13,14 +13,14 @@ class CommunitiesTreeFailureWidget extends StatelessWidget { return Expanded( child: Center( child: Column( + spacing: 16, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( + SelectableText( errorMessage ?? 'Something went wrong', textAlign: TextAlign.center, ), - const SizedBox(height: 16), - ElevatedButton( + FilledButton( onPressed: () => context.read().add( LoadCommunities( LoadCommunitiesParam( 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 6b95556a..229d0dca 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 @@ -2,23 +2,38 @@ 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/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'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_details_dialog.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/update_space/data/services/remote_update_space_service.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/update_space/domain/params/update_space_param.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_bloc.dart'; import 'package:syncrow_web/services/api/http_service.dart'; abstract final class SpaceDetailsDialogHelper { static void showCreate(BuildContext context) { showDialog( context: context, - builder: (_) => BlocProvider( - create: (context) => SpaceDetailsBloc( - RemoteSpaceDetailsService(httpService: HTTPService()), - ), - child: SpaceDetailsDialog( - context: context, - title: const SelectableText('Create Space'), - spaceModel: SpaceModel.empty(), - onSave: print, + builder: (_) => MultiBlocProvider( + providers: [ + BlocProvider( + create: (context) => SpaceDetailsBloc( + RemoteSpaceDetailsService(httpService: HTTPService()), + ), + ), + BlocProvider( + create: (context) => UpdateSpaceBloc( + RemoteUpdateSpaceService(HTTPService()), + ), + ), + ], + child: Builder( + builder: (context) => SpaceDetailsDialog( + context: context, + title: const SelectableText('Create Space'), + spaceModel: SpaceModel.empty(), + onSave: (space) {}, + ), ), ), ); @@ -27,20 +42,81 @@ abstract final class SpaceDetailsDialogHelper { static void showEdit( BuildContext context, { required SpaceModel spaceModel, + required String communityUuid, }) { showDialog( context: context, - builder: (_) => BlocProvider( - create: (context) => SpaceDetailsBloc( - RemoteSpaceDetailsService(httpService: HTTPService()), - ), - child: SpaceDetailsDialog( - context: context, - title: const SelectableText('Edit Space'), - spaceModel: spaceModel, - onSave: (space) {}, + builder: (_) => MultiBlocProvider( + providers: [ + BlocProvider( + create: (context) => SpaceDetailsBloc( + RemoteSpaceDetailsService(httpService: HTTPService()), + ), + ), + BlocProvider( + create: (context) => UpdateSpaceBloc( + RemoteUpdateSpaceService(HTTPService()), + ), + ), + ], + child: Builder( + builder: (context) => BlocListener( + listener: _updateListener, + child: SpaceDetailsDialog( + context: context, + title: const SelectableText('Edit Space'), + spaceModel: spaceModel, + onSave: (space) => context.read().add( + UpdateSpace( + UpdateSpaceParam( + communityUuid: communityUuid, + space: space, + ), + ), + ), + ), + ), ), ), ); } + + static void _updateListener(BuildContext context, UpdateSpaceState state) { + return switch (state) { + UpdateSpaceInitial() => null, + UpdateSpaceLoading() => _onLoading(context), + UpdateSpaceSuccess(:final space) => _onUpdateSuccess(context, space), + UpdateSpaceFailure(:final errorMessage) => _onError(context, errorMessage), + }; + } + + static void _onUpdateSuccess(BuildContext context, SpaceDetailsModel space) { + Navigator.of(context).pop(); + } + + static void _onLoading(BuildContext context) { + showDialog( + context: context, + barrierDismissible: false, + builder: (_) => const Center(child: CircularProgressIndicator()), + ); + } + + static void _onError(BuildContext context, String errorMessage) { + Navigator.of(context).pop(); + showDialog( + context: context, + barrierDismissible: false, + builder: (_) => AlertDialog( + title: const Text('Error'), + content: Text(errorMessage), + actions: [ + TextButton( + onPressed: Navigator.of(context).pop, + child: const Text('OK'), + ), + ], + ), + ); + } } diff --git a/lib/pages/space_management_v2/modules/update_space/data/services/remote_update_space_service.dart b/lib/pages/space_management_v2/modules/update_space/data/services/remote_update_space_service.dart index b15e6095..9f6f65a6 100644 --- a/lib/pages/space_management_v2/modules/update_space/data/services/remote_update_space_service.dart +++ b/lib/pages/space_management_v2/modules/update_space/data/services/remote_update_space_service.dart @@ -1,5 +1,7 @@ import 'package:dio/dio.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.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/update_space/domain/params/update_space_param.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/update_space/domain/services/update_space_service.dart'; import 'package:syncrow_web/services/api/api_exception.dart'; import 'package:syncrow_web/services/api/http_service.dart'; @@ -12,14 +14,19 @@ class RemoteUpdateSpaceService implements UpdateSpaceService { static const _defaultErrorMessage = 'Failed to update space'; @override - Future updateSpace(SpaceDetailsModel space) async { + Future updateSpace(UpdateSpaceParam param) async { try { + final path = await _makeUrl(param); final response = await _httpService.put( - path: 'endpoint', - body: space.toJson(), - expectedResponseModel: (data) => SpaceDetailsModel.fromJson( - data as Map, - ), + path: path, + body: param.space.toJson(), + expectedResponseModel: (data) { + final response = data as Map; + final space = SpaceDetailsModel.fromJson( + response['data'] as Map, + ); + return space; + }, ); return response; @@ -37,4 +44,13 @@ class RemoteUpdateSpaceService implements UpdateSpaceService { throw APIException(formattedErrorMessage); } } + + Future _makeUrl(UpdateSpaceParam param) async { + final projectUuid = await ProjectManager.getProjectUUID(); + if (projectUuid == null || projectUuid.isEmpty) { + throw APIException('Project UUID is not set'); + } + + return '/projects/$projectUuid/communities/${param.communityUuid}/spaces/${param.space.uuid}'; + } } diff --git a/lib/pages/space_management_v2/modules/update_space/domain/params/update_space_param.dart b/lib/pages/space_management_v2/modules/update_space/domain/params/update_space_param.dart new file mode 100644 index 00000000..884976f7 --- /dev/null +++ b/lib/pages/space_management_v2/modules/update_space/domain/params/update_space_param.dart @@ -0,0 +1,11 @@ +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart'; + +class UpdateSpaceParam { + UpdateSpaceParam({ + required this.space, + required this.communityUuid, + }); + + final SpaceDetailsModel space; + final String communityUuid; +} diff --git a/lib/pages/space_management_v2/modules/update_space/domain/services/update_space_service.dart b/lib/pages/space_management_v2/modules/update_space/domain/services/update_space_service.dart index 29bc9419..c75fc0d4 100644 --- a/lib/pages/space_management_v2/modules/update_space/domain/services/update_space_service.dart +++ b/lib/pages/space_management_v2/modules/update_space/domain/services/update_space_service.dart @@ -1,5 +1,6 @@ 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/update_space/domain/params/update_space_param.dart'; -abstract class UpdateSpaceService { - Future updateSpace(SpaceDetailsModel space); +abstract interface class UpdateSpaceService { + Future updateSpace(UpdateSpaceParam param); } diff --git a/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_bloc.dart b/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_bloc.dart index 3bc4e187..0920b547 100644 --- a/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_bloc.dart +++ b/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_bloc.dart @@ -1,6 +1,7 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.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/update_space/domain/params/update_space_param.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/update_space/domain/services/update_space_service.dart'; import 'package:syncrow_web/services/api/api_exception.dart'; @@ -20,7 +21,7 @@ class UpdateSpaceBloc extends Bloc { ) async { emit(UpdateSpaceLoading()); try { - final updatedSpace = await _updateSpaceService.updateSpace(event.space); + final updatedSpace = await _updateSpaceService.updateSpace(event.param); emit(UpdateSpaceSuccess(updatedSpace)); } on APIException catch (e) { emit(UpdateSpaceFailure(e.message)); diff --git a/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_event.dart b/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_event.dart index b7d476af..ec08cdd2 100644 --- a/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_event.dart +++ b/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_event.dart @@ -8,10 +8,10 @@ sealed class UpdateSpaceEvent extends Equatable { } final class UpdateSpace extends UpdateSpaceEvent { - const UpdateSpace(this.space); + const UpdateSpace(this.param); - final SpaceDetailsModel space; + final UpdateSpaceParam param; @override - List get props => [space]; + List get props => [param]; } diff --git a/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_state.dart b/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_state.dart index f0bc5a2b..437cca60 100644 --- a/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_state.dart +++ b/lib/pages/space_management_v2/modules/update_space/presentation/bloc/update_space_state.dart @@ -21,10 +21,10 @@ final class UpdateSpaceSuccess extends UpdateSpaceState { } final class UpdateSpaceFailure extends UpdateSpaceState { - final String message; + final String errorMessage; - const UpdateSpaceFailure(this.message); + const UpdateSpaceFailure(this.errorMessage); @override - List get props => [message]; + List get props => [errorMessage]; }