diff --git a/lib/pages/space_management_v2/modules/space_details/data/services/remote_space_details_service.dart b/lib/pages/space_management_v2/modules/space_details/data/services/remote_space_details_service.dart new file mode 100644 index 00000000..5bcc5851 --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/data/services/remote_space_details_service.dart @@ -0,0 +1,27 @@ +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/params/load_spaces_param.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/services/space_details_service.dart'; +import 'package:syncrow_web/services/api/http_service.dart'; + +class RemoteSpaceDetailsService implements SpaceDetailsService { + final HTTPService _httpService; + + RemoteSpaceDetailsService({ + required HTTPService httpService, + }) : _httpService = httpService; + + @override + Future getSpaceDetails(LoadSpacesParam param) async { + try { + final response = await _httpService.get( + path: 'endpoint', + expectedResponseModel: (data) { + return SpaceDetailsModel.fromJson(data as Map); + }, + ); + return response; + } catch (e) { + throw Exception('Failed to fetch space details: $e'); + } + } +} 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 new file mode 100644 index 00000000..0d2ea80d --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/domain/models/space_details_model.dart @@ -0,0 +1,166 @@ +import 'package:equatable/equatable.dart'; + +class SpaceDetailsModel extends Equatable { + final String uuid; + final String spaceName; + final String icon; + final List productAllocations; + final List subspaces; + + const SpaceDetailsModel({ + required this.uuid, + required this.spaceName, + required this.icon, + required this.productAllocations, + required this.subspaces, + }); + + factory SpaceDetailsModel.fromJson(Map json) { + return SpaceDetailsModel( + uuid: json['uuid'] as String, + spaceName: json['spaceName'] as String, + icon: json['icon'] as String, + productAllocations: (json['productAllocations'] as List) + .map((e) => ProductAllocation.fromJson(e as Map)) + .toList(), + subspaces: (json['subspaces'] as List) + .map((e) => Subspace.fromJson(e as Map)) + .toList(), + ); + } + + Map toJson() { + return { + 'uuid': uuid, + 'spaceName': spaceName, + 'icon': icon, + 'productAllocations': productAllocations.map((e) => e.toJson()).toList(), + 'subspaces': subspaces.map((e) => e.toJson()).toList(), + }; + } + + @override + List get props => [uuid, spaceName, icon, productAllocations, subspaces]; +} + +class ProductAllocation extends Equatable { + final Product product; + final Tag tag; + + const ProductAllocation({ + required this.product, + required this.tag, + }); + + factory ProductAllocation.fromJson(Map json) { + return ProductAllocation( + product: Product.fromJson(json['product'] as Map), + tag: Tag.fromJson(json['tag'] as Map), + ); + } + + Map toJson() { + return { + 'product': product.toJson(), + 'tag': tag.toJson(), + }; + } + + @override + List get props => [product, tag]; +} + +class Product extends Equatable { + final String uuid; + final String name; + + const Product({ + required this.uuid, + required this.name, + }); + + factory Product.fromJson(Map json) { + return Product( + uuid: json['uuid'] as String, + name: json['name'] as String, + ); + } + + Map toJson() { + return { + 'uuid': uuid, + 'name': name, + }; + } + + @override + List get props => [uuid, name]; +} + +class Tag extends Equatable { + final String uuid; + final String name; + final String createdAt; + final String updatedAt; + + const Tag({ + required this.uuid, + required this.name, + required this.createdAt, + required this.updatedAt, + }); + + factory Tag.fromJson(Map json) { + return Tag( + uuid: json['uuid'] as String, + name: json['name'] as String, + createdAt: json['createdAt'] as String, + updatedAt: json['updatedAt'] as String, + ); + } + + Map toJson() { + return { + 'uuid': uuid, + 'name': name, + 'createdAt': createdAt, + 'updatedAt': updatedAt, + }; + } + + @override + List get props => [uuid, name, createdAt, updatedAt]; +} + +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['name'] as String, + productAllocations: (json['productAllocations'] as List) + .map((e) => ProductAllocation.fromJson(e as Map)) + .toList(), + ); + } + + Map toJson() { + return { + 'uuid': uuid, + 'name': name, + 'productAllocations': productAllocations.map((e) => e.toJson()).toList(), + }; + } + + @override + List get props => [uuid, name, productAllocations]; +} diff --git a/lib/pages/space_management_v2/modules/space_details/domain/params/load_spaces_param.dart b/lib/pages/space_management_v2/modules/space_details/domain/params/load_spaces_param.dart new file mode 100644 index 00000000..5324ed98 --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/domain/params/load_spaces_param.dart @@ -0,0 +1,3 @@ +class LoadSpacesParam { + const LoadSpacesParam(); +} diff --git a/lib/pages/space_management_v2/modules/space_details/domain/services/space_details_service.dart b/lib/pages/space_management_v2/modules/space_details/domain/services/space_details_service.dart new file mode 100644 index 00000000..b032560b --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/domain/services/space_details_service.dart @@ -0,0 +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/space_details/domain/params/load_spaces_param.dart'; + +abstract class SpaceDetailsService { + Future getSpaceDetails(LoadSpacesParam param); +} diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_bloc.dart b/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_bloc.dart new file mode 100644 index 00000000..59c1a06d --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_bloc.dart @@ -0,0 +1,34 @@ +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/space_details/domain/params/load_spaces_param.dart'; +import 'package:syncrow_web/pages/space_management_v2/modules/space_details/domain/services/space_details_service.dart'; +import 'package:syncrow_web/services/api/api_exception.dart'; + +part 'space_details_event.dart'; +part 'space_details_state.dart'; + +class SpaceDetailsBloc extends Bloc { + final SpaceDetailsService _spaceDetailsService; + + SpaceDetailsBloc(this._spaceDetailsService) : super(SpaceDetailsInitial()) { + on(_onLoadSpaceDetails); + } + + Future _onLoadSpaceDetails( + LoadSpaceDetails event, + Emitter emit, + ) async { + emit(SpaceDetailsLoading()); + try { + final spaceDetails = await _spaceDetailsService.getSpaceDetails( + event.param, + ); + emit(SpaceDetailsLoaded(spaceDetails)); + } on APIException catch (e) { + emit(SpaceDetailsFailure(e.message)); + } catch (e) { + emit(SpaceDetailsFailure(e.toString())); + } + } +} diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_event.dart b/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_event.dart new file mode 100644 index 00000000..fe559e26 --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_event.dart @@ -0,0 +1,17 @@ +part of 'space_details_bloc.dart'; + +sealed class SpaceDetailsEvent extends Equatable { + const SpaceDetailsEvent(); + + @override + List get props => []; +} + +class LoadSpaceDetails extends SpaceDetailsEvent { + const LoadSpaceDetails(this.param); + + final LoadSpacesParam param; + + @override + List get props => [param]; +} diff --git a/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_state.dart b/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_state.dart new file mode 100644 index 00000000..c7378f89 --- /dev/null +++ b/lib/pages/space_management_v2/modules/space_details/presentation/bloc/space_details_state.dart @@ -0,0 +1,30 @@ +part of 'space_details_bloc.dart'; + +sealed class SpaceDetailsState extends Equatable { + const SpaceDetailsState(); + + @override + List get props => []; +} + +final class SpaceDetailsInitial extends SpaceDetailsState {} + +final class SpaceDetailsLoading extends SpaceDetailsState {} + +final class SpaceDetailsLoaded extends SpaceDetailsState { + final SpaceDetailsModel spaceDetails; + + const SpaceDetailsLoaded(this.spaceDetails); + + @override + List get props => [spaceDetails]; +} + +final class SpaceDetailsFailure extends SpaceDetailsState { + final String message; + + const SpaceDetailsFailure(this.message); + + @override + List get props => [message]; +}