import 'package:flutter/material.dart'; import 'package:syncrow_web/pages/common/buttons/add_space_button.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/services/space_mana_api.dart'; import 'package:syncrow_web/utils/color_manager.dart'; class SpaceManagementPage extends StatefulWidget { @override SpaceManagementPageState createState() => SpaceManagementPageState(); } class SpaceManagementPageState extends State { // Store created spaces List spaces = []; List connections = []; // API instance final CommunitySpaceManagementApi _api = CommunitySpaceManagementApi(); // Data structure to store community and associated spaces Map> communitySpaces = {}; @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'), ), 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 ), ), // 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 ), ], ), child: Text( 'Community Structure', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, ), ), ), // 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); }, ) : 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(), ), ), ], ), ), ), ), ], ), ), ), ], ), 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( context: context, builder: (BuildContext context) { return CreateSpaceDialog( onCreateSpace: (String name, String icon) { setState(() { // Set the first space in the center or use passed position Offset centerPosition = position ?? Offset( screenSize.width / 2 - 75, // Center horizontally screenSize.height / 2 - 100, // Slightly above the center vertically ); SpaceData newSpace = SpaceData(name: name, icon: icon, position: centerPosition); spaces.add(newSpace); // Add connection for down-button if (parentIndex != null && direction != null) { connections.add(Connection( startSpace: spaces[parentIndex], endSpace: newSpace, direction: direction, )); } }); }, ); }, ); } } // Model for storing space information class SpaceData { final String name; final String icon; Offset position; bool isHovered; SpaceData({ required this.name, required this.icon, required this.position, this.isHovered = false, }); } // Class for connection lines between spaces class Connection { final SpaceData startSpace; final SpaceData endSpace; final String direction; Connection( {required this.startSpace, required this.endSpace, required this.direction}); }