diff --git a/lib/pages/spaces_management/view/spaces_management_page.dart b/lib/pages/spaces_management/view/spaces_management_page.dart index 026e9d50..b69b440c 100644 --- a/lib/pages/spaces_management/view/spaces_management_page.dart +++ b/lib/pages/spaces_management/view/spaces_management_page.dart @@ -1,14 +1,19 @@ import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:syncrow_web/pages/common/buttons/add_space_button.dart'; +import 'package:syncrow_web/pages/spaces_management/bloc/space_management_bloc.dart'; +import 'package:syncrow_web/pages/spaces_management/bloc/space_management_event.dart'; +import 'package:syncrow_web/pages/spaces_management/bloc/space_management_state.dart'; import 'package:syncrow_web/pages/spaces_management/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/model/space_model.dart'; import 'package:syncrow_web/pages/spaces_management/view/curved_line_painter.dart'; import 'package:syncrow_web/pages/spaces_management/view/dialogs/create_space_dialog.dart'; -import 'package:syncrow_web/pages/spaces_management/view/sidebar_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/view/space_card_widget.dart'; -import 'package:syncrow_web/pages/spaces_management/view/space_container_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/widgets/sidebar_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/widgets/space_card_widget.dart'; +import 'package:syncrow_web/pages/spaces_management/widgets/space_container_widget.dart'; import 'package:syncrow_web/services/space_mana_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; +import 'package:syncrow_web/web_layout/web_scaffold.dart'; class SpaceManagementPage extends StatefulWidget { @override @@ -29,213 +34,207 @@ class SpaceManagementPageState extends State { @override void initState() { super.initState(); - _loadCommunityAndSpacesData(); } - // Function to load all communities and their respective spaces - void _loadCommunityAndSpacesData() async { - try { - // Fetch all communities - List communities = await _api.fetchCommunities(); - - for (CommunityModel community in communities) { - // Fetch spaces hierarchy for each community - List spaces = await _api.getSpaceHierarchy(community.uuid); - - // Store the result in the communitySpaces map - community.spaces = spaces; - } - - // Update the state to reflect loaded data - setState(() { - // Optionally, you can initialize something here based on the loaded data - }); - } catch (e) { - debugPrint('Error loading communities and spaces: $e'); - } - } - - void _handleCommunitySelection(String community) { - // Handle community selection here - print("Selected Community: $community"); - } @override Widget build(BuildContext context) { Size screenSize = MediaQuery.of(context).size; - return Scaffold( - backgroundColor: ColorsManager.whiteColors, - appBar: AppBar( - title: const Text('Space Management'), + return BlocProvider( + create: (context) => SpaceManagementBloc(CommunitySpaceManagementApi()) + ..add(LoadCommunityAndSpacesEvent()), + child: WebScaffold( + appBarTitle: Text( + 'Space Management', + style: Theme.of(context).textTheme.headlineLarge, + ), + enableMenuSideba: false, + scaffoldBody: BlocBuilder( + builder: (context, state) { + if (state is SpaceManagementLoading) { + return const Center(child: CircularProgressIndicator()); + } else if (state is SpaceManagementLoaded) { + return _buildLoadedState( + context, screenSize, state.communitySpaces); + } else if (state is SpaceManagementError) { + return Center(child: Text('Error: ${state.errorMessage}')); + } + return Container(); + }, + ), ), - body: Stack( - clipBehavior: Clip.none, - children: [ - Row( - children: [ - // Sidebar for navigation and community list - SidebarWidget( - communitySpaces: communitySpaces, // Pass communitySpaces here - onCommunitySelected: _handleCommunitySelection, - ), - // Right Side: Community Structure Area - Expanded( - child: Container( - decoration: const BoxDecoration( - color: ColorsManager.whiteColors, - border: Border( - left: BorderSide( - color: ColorsManager.whiteColors, - width: 1.0), // Light left border to match - ), + ); + } + + Widget _buildLoadedState(BuildContext context, Size screenSize, + Map> communitySpaces) { + return Stack( + clipBehavior: Clip.none, + children: [ + Row( + children: [ + SidebarWidget( + communitySpaces: communitySpaces, + onCommunitySelected: (community) { + context.read().add( + LoadCommunityAndSpacesEvent(), // Re-fetch or perform community-specific actions + ); + }, + ), + Expanded( + child: _buildCommunityStructureArea(context, screenSize), + ), + ], + ), + _buildGradientBorder(), + ], + ); + } + + Widget _buildCommunityStructureArea(BuildContext context, Size screenSize) { + return Expanded( + child: Container( + decoration: const BoxDecoration( + color: ColorsManager.whiteColors, + border: Border( + left: BorderSide( + color: ColorsManager.whiteColors, + width: 1.0), // Light left border to match + ), + ), + // Background color for canvas + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 27.0), + width: double.infinity, + decoration: BoxDecoration( + color: ColorsManager.whiteColors, + boxShadow: [ + BoxShadow( + color: ColorsManager.shadowBlackColor, // Subtle shadow + spreadRadius: 0, // No spread + blurRadius: 8, // Softer shadow edges + offset: Offset(0, 4), // Shadow only on the bottom ), - // Background color for canvas - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + ], + ), + child: Text( + 'Community Structure', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + ), + ), + ), + // Use Expanded to ensure InteractiveViewer takes the available space + Flexible( + child: InteractiveViewer( + boundaryMargin: const EdgeInsets.all(500), // Adjusted to 500 + minScale: 0.5, // Minimum zoom scale + maxScale: 2.5, // Maximum zoom scale + panEnabled: true, // Enable panning + scaleEnabled: true, // Enable zooming + child: Container( + width: 2000, // Large canvas + height: 2000, // Large canvas + color: + ColorsManager.transparentColor, // Transparent background + child: Stack( + clipBehavior: Clip.none, children: [ - Container( - padding: - const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 27.0), - width: double.infinity, - decoration: BoxDecoration( - color: ColorsManager.whiteColors, - boxShadow: [ - BoxShadow( - color: ColorsManager - .shadowBlackColor, // Subtle shadow - spreadRadius: 0, // No spread - blurRadius: 8, // Softer shadow edges - offset: Offset(0, 4), // Shadow only on the bottom - ), - ], - ), - child: Text( - 'Community Structure', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - ), - ), + // Draw lines using a CustomPaint widget + CustomPaint( + size: Size(2000, 2000), // Explicit canvas size + painter: CurvedLinePainter(connections), ), - // Use Expanded to ensure InteractiveViewer takes the available space - Expanded( - child: InteractiveViewer( - boundaryMargin: - const EdgeInsets.all(500), // Adjusted to 500 - minScale: 0.5, // Minimum zoom scale - maxScale: 2.5, // Maximum zoom scale - panEnabled: true, // Enable panning - scaleEnabled: true, // Enable zooming - child: Container( - width: 2000, // Large canvas - height: 2000, // Large canvas - color: ColorsManager - .transparentColor, // Transparent background - child: Stack( - clipBehavior: Clip.none, - children: [ - // Draw lines using a CustomPaint widget - CustomPaint( - size: - Size(2000, 2000), // Explicit canvas size - painter: CurvedLinePainter(connections), - ), - Center( - child: spaces.isEmpty - ? AddSpaceButton( - onTap: () { - _showCreateSpaceDialog(screenSize); + Center( + child: spaces.isEmpty + ? AddSpaceButton( + onTap: () { + _showCreateSpaceDialog(screenSize); + }, + ) + : Stack( + children: spaces + .asMap() + .entries + .map((entry) => SpaceCardWidget( + index: entry.key, + screenSize: screenSize, + position: spaces[entry.key].position, + isHovered: + spaces[entry.key].isHovered, + onPanUpdate: + (int index, Offset delta) { + setState(() { + spaces[index].position += delta; + }); }, - ) - : Stack( - children: spaces - .asMap() - .entries - .map((entry) => SpaceCardWidget( - index: entry.key, - screenSize: screenSize, - position: spaces[entry.key] - .position, - isHovered: spaces[entry.key] - .isHovered, - onPanUpdate: (int index, - Offset delta) { - setState(() { - spaces[index] - .position += delta; - }); - }, - onHoverChanged: (int index, - bool isHovered) { - setState(() { - spaces[index] - .isHovered = - isHovered; - }); - }, - onButtonTap: (int index, - Offset newPosition, - String direction) { - _showCreateSpaceDialog( - screenSize, - position: spaces[index] - .position + - newPosition, - parentIndex: index, - direction: direction, - ); - }, - buildSpaceContainer: - (int index) { - return SpaceContainerWidget( - index: index, - icon: - spaces[index].icon, - name: - spaces[index].name, - ); - }, - )) - .toList(), - ), - ), - ], - ), - ), - ), + onHoverChanged: + (int index, bool isHovered) { + setState(() { + spaces[index].isHovered = + isHovered; + }); + }, + onButtonTap: (int index, + Offset newPosition, + String direction) { + _showCreateSpaceDialog( + screenSize, + position: spaces[index].position + + newPosition, + parentIndex: index, + direction: direction, + ); + }, + buildSpaceContainer: (int index) { + return SpaceContainerWidget( + index: index, + icon: spaces[index].icon, + name: spaces[index].name, + ); + }, + )) + .toList(), + ), ), ], ), ), ), + ), + ], + ), + ), + + ); + } + + Widget _buildGradientBorder() { + return Positioned( + top: 0, + bottom: 0, + left: 300, + width: 8, + child: Container( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + ColorsManager.semiTransparentBlackColor.withOpacity(0.1), + ColorsManager.transparentColor, ], ), - Positioned( - top: 0, - bottom: 0, - left: 300, // Align with the sidebar's width - width: 8, // Width of the gradient border - child: Container( - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.centerLeft, - end: Alignment.centerRight, - colors: [ - ColorsManager.semiTransparentBlackColor - .withOpacity(0.1), // Light gray - ColorsManager.transparentColor, // Transparent fade - ], - ), - ), - ), - ), - ], + ), ), ); } - // Function to open the Create Space dialog void _showCreateSpaceDialog(Size screenSize, {Offset? position, int? parentIndex, String? direction}) { showDialog( @@ -272,6 +271,8 @@ class SpaceManagementPageState extends State { } } +// Function to open the Create Space dialog + // Model for storing space information class SpaceData { final String name; @@ -298,4 +299,3 @@ class Connection { required this.endSpace, required this.direction}); } -