updated api

This commit is contained in:
hannathkadher
2024-11-18 15:36:33 +04:00
parent e33a07ac56
commit 836c44fd95
8 changed files with 125 additions and 75 deletions

View File

@ -94,4 +94,35 @@ class SpaceManagementBloc
emit(SpaceManagementError('Error creating community: $e')); emit(SpaceManagementError('Error creating community: $e'));
} }
} }
void _onSaveSpaces(
SaveSpacesEvent event,
Emitter<SpaceManagementState> emit,
) async {
final previousState = state;
emit(SpaceManagementLoading());
try {
// Save spaces one by one
for (var space in event.spaces) {
await _api.createSpace(
communityId: event.communityUuid,
name: space.name,
parentId: space.parent?.uuid,
isPrivate: space.isPrivate,
position: space.position,
);
}
emit(SpaceCreationSuccess());
} catch (e) {
emit(SpaceManagementError('Error saving spaces: $e'));
// Revert back to the previous state if an error occurs
if (previousState is SpaceManagementLoaded) {
emit(previousState);
}
}
}
} }

View File

@ -1,5 +1,6 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart'; // Import for Offset import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; // Import for Offset
abstract class SpaceManagementEvent extends Equatable { abstract class SpaceManagementEvent extends Equatable {
const SpaceManagementEvent(); const SpaceManagementEvent();
@ -35,6 +36,19 @@ class CreateSpaceEvent extends SpaceManagementEvent {
]; ];
} }
class SaveSpacesEvent extends SpaceManagementEvent {
final List<SpaceModel> spaces;
final String communityUuid;
const SaveSpacesEvent({
required this.spaces,
required this.communityUuid,
});
@override
List<Object> get props => [spaces, communityUuid];
}
class UpdateSpacePositionEvent extends SpaceManagementEvent { class UpdateSpacePositionEvent extends SpaceManagementEvent {
final int index; final int index;
final Offset newPosition; final Offset newPosition;
@ -45,7 +59,6 @@ class UpdateSpacePositionEvent extends SpaceManagementEvent {
List<Object> get props => [index, newPosition]; List<Object> get props => [index, newPosition];
} }
class CreateCommunityEvent extends SpaceManagementEvent { class CreateCommunityEvent extends SpaceManagementEvent {
final String name; final String name;
final String description; final String description;

View File

@ -1,8 +1,8 @@
import 'package:syncrow_web/pages/spaces_management/model/space_data_model.dart'; import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
class Connection { class Connection {
final SpaceData startSpace; final SpaceModel startSpace;
final SpaceData endSpace; final SpaceModel endSpace;
final String direction; final String direction;
Connection( Connection(

View File

@ -2,9 +2,8 @@ import 'dart:ui';
import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/model/community_model.dart';
class SpaceModel { class SpaceModel {
final String uuid; final String? uuid;
final DateTime createdAt; final String? icon;
final DateTime updatedAt;
final String? spaceTuyaUuid; final String? spaceTuyaUuid;
final String name; final String name;
final bool isPrivate; final bool isPrivate;
@ -12,31 +11,26 @@ class SpaceModel {
final SpaceModel? parent; final SpaceModel? parent;
final CommunityModel? community; final CommunityModel? community;
final List<SpaceModel> children; final List<SpaceModel> children;
final String? icon;
Offset position; Offset position;
bool isHovered; bool isHovered;
SpaceModel({ SpaceModel({
required this.uuid, this.uuid,
required this.createdAt,
required this.updatedAt,
this.spaceTuyaUuid, this.spaceTuyaUuid,
required this.icon,
required this.name, required this.name,
required this.isPrivate, required this.isPrivate,
this.invitationCode, this.invitationCode,
this.parent, this.parent,
this.community, this.community,
required this.children, required this.children,
required this.icon,
required this.position, required this.position,
this.isHovered = false, this.isHovered = false,
}); });
factory SpaceModel.fromJson(Map<String, dynamic> json) { factory SpaceModel.fromJson(Map<String, dynamic> json) {
return SpaceModel( return SpaceModel(
uuid: json['uuid'], uuid: json['uuid'] ?? '',
createdAt: DateTime.parse(json['createdAt']),
updatedAt: DateTime.parse(json['updatedAt']),
spaceTuyaUuid: json['spaceTuyaUuid'], spaceTuyaUuid: json['spaceTuyaUuid'],
name: json['spaceName'], name: json['spaceName'],
isPrivate: json['isPrivate'] ?? false, isPrivate: json['isPrivate'] ?? false,
@ -46,11 +40,11 @@ class SpaceModel {
community: json['community'] != null community: json['community'] != null
? CommunityModel.fromJson(json['community']) ? CommunityModel.fromJson(json['community'])
: null, : null,
children: json['children'] != null children: json['children'] != null
? (json['children'] as List) ? (json['children'] as List)
.map((child) => SpaceModel.fromJson(child)) .map((child) => SpaceModel.fromJson(child))
.toList() .toList()
: [], : [],
icon: json['icon'] as String?, icon: json['icon'] as String?,
position: json['position'] != null position: json['position'] != null
? Offset(json['position']['dx'], json['position']['dy']) ? Offset(json['position']['dx'], json['position']['dy'])
@ -61,9 +55,7 @@ class SpaceModel {
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
return { return {
'uuid': uuid, 'uuid': uuid ?? '',
'createdAt': createdAt.toIso8601String(),
'updatedAt': updatedAt.toIso8601String(),
'spaceTuyaUuid': spaceTuyaUuid, 'spaceTuyaUuid': spaceTuyaUuid,
'name': name, 'name': name,
'isPrivate': isPrivate, 'isPrivate': isPrivate,

View File

@ -38,14 +38,13 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocProvider( return BlocProvider(
create: (context) => SpaceManagementBloc(CommunitySpaceManagementApi()) create: (context) =>
..add(LoadCommunityAndSpacesEvent()), SpaceManagementBloc(CommunitySpaceManagementApi())..add(LoadCommunityAndSpacesEvent()),
child: WebScaffold( child: WebScaffold(
appBarTitle: Text('Space Management', appBarTitle: Text('Space Management', style: Theme.of(context).textTheme.headlineLarge),
style: Theme.of(context).textTheme.headlineLarge),
enableMenuSidebar: false, enableMenuSidebar: false,
scaffoldBody: BlocBuilder<SpaceManagementBloc, SpaceManagementState>( scaffoldBody:
builder: (context, state) { BlocBuilder<SpaceManagementBloc, SpaceManagementState>(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 SpaceManagementLoaded) { } else if (state is SpaceManagementLoaded) {
@ -66,27 +65,4 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
), ),
); );
} }
Widget _buildLoadedState(
BuildContext context, List<CommunityModel> communities) {
return Stack(
clipBehavior: Clip.none,
children: [
Row(
children: [
SidebarWidget(
communities: communities,
onCommunitySelected: (community) {
setState(() {
selectedCommunity = community;
});
},
),
CommunityStructureArea(selectedCommunity: selectedCommunity),
],
),
const GradientCanvasBorderWidget()
],
);
}
} }

View File

@ -1,10 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/common/buttons/add_space_button.dart'; import 'package:syncrow_web/pages/common/buttons/add_space_button.dart';
import 'package:syncrow_web/pages/spaces_management/model/space_model.dart';
import 'package:syncrow_web/pages/spaces_management/view/dialogs/create_space_dialog.dart'; import 'package:syncrow_web/pages/spaces_management/view/dialogs/create_space_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/curved_line_painter.dart'; import 'package:syncrow_web/pages/spaces_management/widgets/curved_line_painter.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/space_card_widget.dart'; import 'package:syncrow_web/pages/spaces_management/widgets/space_card_widget.dart';
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_data_model.dart';
import 'package:syncrow_web/pages/spaces_management/model/connection_model.dart'; import 'package:syncrow_web/pages/spaces_management/model/connection_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/space_container_widget.dart'; import 'package:syncrow_web/pages/spaces_management/widgets/space_container_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
@ -21,7 +21,7 @@ class CommunityStructureArea extends StatefulWidget {
class _CommunityStructureAreaState extends State<CommunityStructureArea> { class _CommunityStructureAreaState extends State<CommunityStructureArea> {
double canvasWidth = 1000; double canvasWidth = 1000;
double canvasHeight = 1000; double canvasHeight = 1000;
List<SpaceData> spaces = []; List<SpaceModel> spaces = [];
List<Connection> connections = []; List<Connection> connections = [];
@override @override
@ -81,7 +81,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
buildSpaceContainer: (int index) { buildSpaceContainer: (int index) {
return SpaceContainerWidget( return SpaceContainerWidget(
index: index, index: index,
icon: spaces[index].icon, icon: spaces[index].icon ?? '',
name: spaces[index].name, name: spaces[index].name,
); );
}, },
@ -122,25 +122,51 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
), ),
], ],
), ),
child: Column( child: Row(
crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
const Text( Column(
'Community Structure', crossAxisAlignment: CrossAxisAlignment.start,
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), children: [
const Text(
'Community Structure',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
if (widget.selectedCommunity != null)
Text(
widget.selectedCommunity!.name,
style: const TextStyle(
fontSize: 16, color: ColorsManager.blackColor),
),
],
), ),
if (widget.selectedCommunity != null) // Show "Save" button only if there are spaces
Text( if (spaces.isNotEmpty && widget.selectedCommunity != null )
widget.selectedCommunity!.name, ElevatedButton.icon(
style: const TextStyle( onPressed: () {
fontSize: 16, color: ColorsManager.blackColor), _saveSpaces();
},
icon: const Icon(Icons.save, size: 18),
label: const Text("Save"),
style: ElevatedButton.styleFrom(
backgroundColor: ColorsManager.whiteColors,
foregroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
padding:
const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
side: BorderSide(color: Colors.grey.shade300),
elevation: 0,
),
), ),
], ],
), ),
); );
} }
void _updateNodePosition(SpaceData node, Offset newPosition) { void _updateNodePosition(SpaceModel node, Offset newPosition) {
setState(() { setState(() {
node.position = newPosition; node.position = newPosition;
@ -188,15 +214,15 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
50, // Slightly above the center vertically 50, // Slightly above the center vertically
); );
SpaceData newSpace = SpaceModel newSpace =
SpaceData(name: name, icon: icon, position: centerPosition); SpaceModel(name: name, icon: icon, position: centerPosition, isPrivate: false, children: []);
spaces.add(newSpace); spaces.add(newSpace);
_updateNodePosition(newSpace, newSpace.position); _updateNodePosition(newSpace, newSpace.position);
// Add connection for down-button // Add connection for down-button
if (parentIndex != null && direction != null) { if (parentIndex != null && direction != null) {
SpaceData parentSpace = spaces[parentIndex]; SpaceModel parentSpace = spaces[parentIndex];
connections.add(Connection( connections.add(Connection(
startSpace: parentSpace, startSpace: parentSpace,
endSpace: newSpace, endSpace: newSpace,
@ -215,4 +241,10 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
spaces[index].isHovered = isHovered; spaces[index].isHovered = isHovered;
}); });
} }
void _saveSpaces() {
// Implement your save functionality here
print("Spaces saved: ${spaces.length}");
}
} }

View File

@ -206,7 +206,7 @@ class _SidebarWidgetState extends State<SidebarWidget> {
title: space.name, title: space.name,
initiallyExpanded: isSelectedSpace, initiallyExpanded: isSelectedSpace,
onExpansionChanged: (bool expanded) { onExpansionChanged: (bool expanded) {
_handleExpansionChange(space.uuid, expanded); _handleExpansionChange(space.uuid ?? '', expanded);
}, },
children: space.children.isNotEmpty children: space.children.isNotEmpty
? space.children ? space.children

View File

@ -20,7 +20,7 @@ class CommunitySpaceManagementApi {
return CommunityModel.fromJson(jsonItem); return CommunityModel.fromJson(jsonItem);
}).toList(); }).toList();
return communityList; return communityList;
}, },
); );
return response; return response;
} catch (e) { } catch (e) {
@ -141,12 +141,19 @@ class CommunitySpaceManagementApi {
} }
} }
Future<SpaceModel?> createSpace(String communityId, String name, Future<SpaceModel?> createSpace({
{String? parentId, bool isPrivate = false}) async { required String communityId,
required String name,
String? parentId,
bool isPrivate = false,
required Offset position,
}) async {
try { try {
final body = { final body = {
'name': name, 'name': name,
'isPrivate': isPrivate, 'isPrivate': isPrivate,
'x': position.dx,
'y': position.dy,
}; };
if (parentId != null) { if (parentId != null) {
body['parentId'] = parentId; body['parentId'] = parentId;
@ -219,5 +226,4 @@ class CommunitySpaceManagementApi {
return []; return [];
} }
} }
} }