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'));
}
}
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: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 {
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 {
final int index;
final Offset newPosition;
@ -45,7 +59,6 @@ class UpdateSpacePositionEvent extends SpaceManagementEvent {
List<Object> get props => [index, newPosition];
}
class CreateCommunityEvent extends SpaceManagementEvent {
final String name;
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 {
final SpaceData startSpace;
final SpaceData endSpace;
final SpaceModel startSpace;
final SpaceModel endSpace;
final String direction;
Connection(

View File

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

View File

@ -38,14 +38,13 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => SpaceManagementBloc(CommunitySpaceManagementApi())
..add(LoadCommunityAndSpacesEvent()),
create: (context) =>
SpaceManagementBloc(CommunitySpaceManagementApi())..add(LoadCommunityAndSpacesEvent()),
child: WebScaffold(
appBarTitle: Text('Space Management',
style: Theme.of(context).textTheme.headlineLarge),
appBarTitle: Text('Space Management', style: Theme.of(context).textTheme.headlineLarge),
enableMenuSidebar: false,
scaffoldBody: BlocBuilder<SpaceManagementBloc, SpaceManagementState>(
builder: (context, state) {
scaffoldBody:
BlocBuilder<SpaceManagementBloc, SpaceManagementState>(builder: (context, state) {
if (state is SpaceManagementLoading) {
return const Center(child: CircularProgressIndicator());
} 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: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/widgets/curved_line_painter.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/space_data_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/utils/color_manager.dart';
@ -21,7 +21,7 @@ class CommunityStructureArea extends StatefulWidget {
class _CommunityStructureAreaState extends State<CommunityStructureArea> {
double canvasWidth = 1000;
double canvasHeight = 1000;
List<SpaceData> spaces = [];
List<SpaceModel> spaces = [];
List<Connection> connections = [];
@override
@ -81,7 +81,7 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
buildSpaceContainer: (int index) {
return SpaceContainerWidget(
index: index,
icon: spaces[index].icon,
icon: spaces[index].icon ?? '',
name: spaces[index].name,
);
},
@ -122,25 +122,51 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Community Structure',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
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)
Text(
widget.selectedCommunity!.name,
style: const TextStyle(
fontSize: 16, color: ColorsManager.blackColor),
// Show "Save" button only if there are spaces
if (spaces.isNotEmpty && widget.selectedCommunity != null )
ElevatedButton.icon(
onPressed: () {
_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(() {
node.position = newPosition;
@ -188,15 +214,15 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
50, // Slightly above the center vertically
);
SpaceData newSpace =
SpaceData(name: name, icon: icon, position: centerPosition);
SpaceModel newSpace =
SpaceModel(name: name, icon: icon, position: centerPosition, isPrivate: false, children: []);
spaces.add(newSpace);
_updateNodePosition(newSpace, newSpace.position);
// Add connection for down-button
if (parentIndex != null && direction != null) {
SpaceData parentSpace = spaces[parentIndex];
SpaceModel parentSpace = spaces[parentIndex];
connections.add(Connection(
startSpace: parentSpace,
endSpace: newSpace,
@ -215,4 +241,10 @@ class _CommunityStructureAreaState extends State<CommunityStructureArea> {
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,
initiallyExpanded: isSelectedSpace,
onExpansionChanged: (bool expanded) {
_handleExpansionChange(space.uuid, expanded);
_handleExpansionChange(space.uuid ?? '', expanded);
},
children: space.children.isNotEmpty
? space.children

View File

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