diff --git a/lib/pages/space_management_v2/modules/create_space/data/services/remote_create_space_service.dart b/lib/pages/space_management_v2/modules/create_space/data/services/remote_create_space_service.dart new file mode 100644 index 00000000..f8dba7dc --- /dev/null +++ b/lib/pages/space_management_v2/modules/create_space/data/services/remote_create_space_service.dart @@ -0,0 +1,63 @@ +import 'package:dio/dio.dart'; +import 'package:syncrow_web/pages/common/bloc/project_manager.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/domain/params/create_space_param.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/create_space/domain/services/create_space_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; +import 'package:syncrow_web/services/api/http_service.dart'; + +final class RemoteCreateSpaceService implements CreateSpaceService { + const RemoteCreateSpaceService(this._httpService); + + final HTTPService _httpService; + + static const _defaultErrorMessage = 'Failed to create space'; + + @override + Future createSpace(CreateSpaceParam param) async { + try { + final path = await _makeUrl(param); + final response = await _httpService.post( + path: path, + body: param.toJson(), + expectedResponseModel: (data) { + final response = data as Map; + final isSuccess = response['success'] as bool; + if (!isSuccess) { + throw APIException(response['error'] as String); + } + + return SpaceModel.fromJson(response['data'] as Map); + }, + ); + + return response; + } on DioException catch (e) { + final message = e.response?.data as Map?; + final error = message?['error'] as Map?; + final errorMessage = error?['error'] as String? ?? ''; + final formattedErrorMessage = [ + _defaultErrorMessage, + errorMessage, + ].join(': '); + throw APIException(formattedErrorMessage); + } catch (e) { + final formattedErrorMessage = [_defaultErrorMessage, '$e'].join(': '); + throw APIException(formattedErrorMessage); + } + } + + Future _makeUrl(CreateSpaceParam param) async { + final projectUuid = await ProjectManager.getProjectUUID(); + if (projectUuid == null || projectUuid.isEmpty) { + throw APIException('Project UUID is not set'); + } + + final communityUuid = param.communityUuid; + if (communityUuid.isEmpty) { + throw APIException('Community UUID is not set'); + } + + return '/projects/$projectUuid/communities/$communityUuid'; + } +} diff --git a/lib/pages/space_management_v2/modules/create_space/domain/params/create_space_param.dart b/lib/pages/space_management_v2/modules/create_space/domain/params/create_space_param.dart new file mode 100644 index 00000000..75c6d1d5 --- /dev/null +++ b/lib/pages/space_management_v2/modules/create_space/domain/params/create_space_param.dart @@ -0,0 +1,17 @@ +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart'; + +class CreateSpaceParam { + final String communityUuid; + final SpaceDetailsModel space; + final String? parentUuid; + + const CreateSpaceParam({ + required this.communityUuid, + required this.space, + required this.parentUuid, + }); + + Map toJson() { + return {'spaceModelUuid': parentUuid, ...space.toJson()}; + } +} diff --git a/lib/pages/space_management_v2/modules/create_space/domain/services/create_space_service.dart b/lib/pages/space_management_v2/modules/create_space/domain/services/create_space_service.dart new file mode 100644 index 00000000..553b87e7 --- /dev/null +++ b/lib/pages/space_management_v2/modules/create_space/domain/services/create_space_service.dart @@ -0,0 +1,6 @@ +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/domain/params/create_space_param.dart'; + +abstract interface class CreateSpaceService { + Future createSpace(CreateSpaceParam param); +} diff --git a/lib/pages/space_management_v2/modules/space_details/data/services/unique_space_details_spaces_decorator_service.dart b/lib/pages/space_management_v2/modules/space_details/data/services/unique_space_details_spaces_decorator_service.dart index 72cf8b89..da7fd4eb 100644 --- a/lib/pages/space_management_v2/modules/space_details/data/services/unique_space_details_spaces_decorator_service.dart +++ b/lib/pages/space_management_v2/modules/space_details/data/services/unique_space_details_spaces_decorator_service.dart @@ -1,4 +1,5 @@ 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/domain/models/subspace.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/params/load_space_details_param.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/services/space_details_service.dart'; diff --git a/lib/pages/space_management_v2/modules/space_details/domain/models/product_allocation.dart b/lib/pages/space_management_v2/modules/space_details/domain/models/product_allocation.dart new file mode 100644 index 00000000..250dad5c --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/domain/models/product_allocation.dart @@ -0,0 +1,47 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/products/domain/models/product.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/tags/domain/models/tag.dart'; +import 'package:uuid/uuid.dart'; + +class ProductAllocation extends Equatable { + final String uuid; + final Product product; + final Tag tag; + + const ProductAllocation({ + required this.uuid, + required this.product, + required this.tag, + }); + + factory ProductAllocation.fromJson(Map json) { + return ProductAllocation( + uuid: json['uuid'] as String? ?? const Uuid().v4(), + product: Product.fromJson(json['product'] as Map), + tag: Tag.fromJson(json['tag'] as Map), + ); + } + + ProductAllocation copyWith({ + String? uuid, + Product? product, + Tag? tag, + }) { + return ProductAllocation( + uuid: uuid ?? this.uuid, + product: product ?? this.product, + tag: tag ?? this.tag, + ); + } + + Map toJson() { + final isNewTag = tag.uuid.isEmpty; + return { + if (isNewTag) 'tagName': tag.name else 'tagUuid': tag.uuid, + 'productUuid': product.uuid, + }; + } + + @override + List get props => [uuid, product, tag]; +} diff --git a/lib/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart b/lib/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart index ec3c9f81..bd8ff714 100644 --- a/lib/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart +++ b/lib/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart @@ -1,8 +1,7 @@ import 'package:equatable/equatable.dart'; -import 'package:syncrow_web/pages/space_management_v2/modules/products/domain/models/product.dart'; -import 'package:syncrow_web/pages/space_management_v2/modules/tags/domain/models/tag.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/product_allocation.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/subspace.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; -import 'package:uuid/uuid.dart'; class SpaceDetailsModel extends Equatable { final String uuid; @@ -26,6 +25,7 @@ class SpaceDetailsModel extends Equatable { productAllocations: [], subspaces: [], ); + factory SpaceDetailsModel.fromJson(Map json) { return SpaceDetailsModel( uuid: json['uuid'] as String, @@ -56,78 +56,21 @@ class SpaceDetailsModel extends Equatable { ); } - @override - List get props => [uuid, spaceName, icon, productAllocations, subspaces]; -} - -class ProductAllocation extends Equatable { - final String uuid; - final Product product; - final Tag tag; - - const ProductAllocation({ - required this.uuid, - required this.product, - required this.tag, - }); - - factory ProductAllocation.fromJson(Map json) { - return ProductAllocation( - uuid: json['uuid'] as String? ?? const Uuid().v4(), - product: Product.fromJson(json['product'] as Map), - tag: Tag.fromJson(json['tag'] as Map), - ); - } - - ProductAllocation copyWith({ - String? uuid, - Product? product, - Tag? tag, - }) { - return ProductAllocation( - uuid: uuid ?? this.uuid, - product: product ?? this.product, - tag: tag ?? this.tag, - ); + Map toJson() { + return { + 'spaceName': spaceName, + 'icon': icon, + 'subspaces': subspaces.map((e) => e.toJson()).toList(), + 'productAllocations': productAllocations.map((e) => e.toJson()).toList(), + }; } @override - List get props => [uuid, product, tag]; -} - -class Subspace extends Equatable { - final String uuid; - final String name; - final List productAllocations; - - const Subspace({ - required this.uuid, - required this.name, - required this.productAllocations, - }); - - factory Subspace.fromJson(Map json) { - return Subspace( - uuid: json['uuid'] as String, - name: json['subspaceName'] as String, - productAllocations: (json['productAllocations'] as List) - .map((e) => ProductAllocation.fromJson(e as Map)) - .toList(), - ); - } - - Subspace copyWith({ - String? uuid, - String? name, - List? productAllocations, - }) { - return Subspace( - uuid: uuid ?? this.uuid, - name: name ?? this.name, - productAllocations: productAllocations ?? this.productAllocations, - ); - } - - @override - List get props => [uuid, name, productAllocations]; + List get props => [ + uuid, + spaceName, + icon, + productAllocations, + subspaces, + ]; } diff --git a/lib/pages/space_management_v2/modules/space_details/domain/models/subspace.dart b/lib/pages/space_management_v2/modules/space_details/domain/models/subspace.dart new file mode 100644 index 00000000..4a962eb3 --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/domain/models/subspace.dart @@ -0,0 +1,48 @@ +import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/product_allocation.dart'; + +class Subspace extends Equatable { + final String uuid; + final String name; + final List productAllocations; + + const Subspace({ + required this.uuid, + required this.name, + required this.productAllocations, + }); + + factory Subspace.fromJson(Map json) { + return Subspace( + uuid: json['uuid'] as String, + name: json['subspaceName'] as String, + productAllocations: (json['productAllocations'] as List) + .map((e) => ProductAllocation.fromJson(e as Map)) + .toList(), + ); + } + + Map toJson() { + final isNewSubspace = uuid.endsWith('-NewTag'); + return { + if (!isNewSubspace) 'uuid': uuid, + 'subspaceName': name, + 'productAllocations': productAllocations.map((e) => e.toJson()).toList(), + }; + } + + Subspace copyWith({ + String? uuid, + String? name, + List? productAllocations, + }) { + return Subspace( + uuid: uuid ?? this.uuid, + name: name ?? this.name, + productAllocations: productAllocations ?? this.productAllocations, + ); + } + + @override + List get props => [uuid, name, productAllocations]; +} diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_box.dart b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_box.dart index 68bf68bd..719988c6 100644 --- a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_box.dart +++ b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_box.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/common/edit_chip.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/domain/models/subspace.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/button_content_widget.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_dialog.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart'; diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_dialog.dart b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_dialog.dart index 8faac548..587c9ea7 100644 --- a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_dialog.dart +++ b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/space_sub_spaces_dialog.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.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/domain/models/subspace.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/space_details_action_buttons.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/sub_spaces_input.dart'; import 'package:uuid/uuid.dart'; diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/sub_spaces_input.dart b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/sub_spaces_input.dart index 854b79bc..591f741c 100644 --- a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/sub_spaces_input.dart +++ b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/sub_spaces_input.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.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/domain/models/subspace.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_chip.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_chip.dart b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_chip.dart index a80ddd15..6bc9f6d1 100644 --- a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_chip.dart +++ b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_chip.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.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/domain/models/subspace.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart index bf13ffd3..e72bffde 100644 --- a/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart +++ b/lib/pages/space_management_v2/modules/space_details/presentation/widgets/subspace_name_display_widget.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.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/domain/models/subspace.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart'; import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/extension/build_context_x.dart'; diff --git a/lib/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_dialog.dart b/lib/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_dialog.dart index 7a1002dc..d14a3923 100644 --- a/lib/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_dialog.dart +++ b/lib/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_dialog.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/products/domain/models/product.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/product_allocation.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/widgets/space_details_action_buttons.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/tags/domain/models/tag.dart'; diff --git a/lib/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_table.dart b/lib/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_table.dart index 6e7e2097..1711e019 100644 --- a/lib/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_table.dart +++ b/lib/pages/space_management_v2/modules/tags/presentation/widgets/assign_tags_table.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/common/dialog_dropdown.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/domain/models/product_allocation.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/subspace.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/tags/data/services/remote_tags_service.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/tags/domain/models/tag.dart'; import 'package:syncrow_web/pages/space_management_v2/modules/tags/presentation/bloc/tags_bloc.dart'; 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 index 5dd9106d..25d54caa 100644 --- 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 @@ -9,34 +9,5 @@ class UpdateSpaceParam { final SpaceDetailsModel space; final String communityUuid; - Map toJson() { - return { - 'spaceName': space.spaceName, - 'icon': space.icon, - 'subspaces': space.subspaces.map((e) => e._toJson()).toList(), - 'productAllocations': - space.productAllocations.map((e) => e._toJson()).toList(), - }; - } -} - -extension _ProductAllocationToJson on ProductAllocation { - Map _toJson() { - final isNewTag = tag.uuid.isEmpty; - return { - if (isNewTag) 'tagName': tag.name else 'tagUuid': tag.uuid, - 'productUuid': product.uuid, - }; - } -} - -extension _SubspaceToJson on Subspace { - Map _toJson() { - final isNewSubspace = uuid.endsWith('-NewTag'); - return { - if (!isNewSubspace) 'uuid': uuid, - 'subspaceName': name, - 'productAllocations': productAllocations.map((e) => e._toJson()).toList(), - }; - } + Map toJson() => space.toJson(); } diff --git a/lib/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart b/lib/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart index 15a22fda..4c11e694 100644 --- a/lib/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart +++ b/lib/pages/space_management_v2/modules/update_space/presentation/bloc/space_details_model_bloc/space_details_model_bloc.dart @@ -1,6 +1,8 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/models/product_allocation.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/domain/models/subspace.dart'; part 'space_details_model_event.dart';