Files
syncrow-web/lib/pages/spaces_management/view/spaces_management_page.dart
2024-09-05 12:11:35 +04:00

204 lines
6.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/common/buttons/add_space_button.dart';
import 'package:syncrow_web/pages/spaces_management/view/dialogs/create_space_dialog.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class SpaceManagementPage extends StatefulWidget {
@override
SpaceManagementPageState createState() => SpaceManagementPageState();
}
class SpaceManagementPageState extends State<SpaceManagementPage> {
// Store created spaces
List<SpaceData> spaces = [];
@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(
children: [
Center(
child: spaces.isEmpty
? AddSpaceButton(
onTap: () {
_showCreateSpaceDialog(screenSize);
},
)
: Stack(
children: spaces
.asMap()
.entries
.map((entry) => _buildSpaceCard(entry.key, screenSize))
.toList(),
),
),
],
),
);
}
// Function to open the Create Space dialog
void _showCreateSpaceDialog(Size screenSize, {Offset? position}) {
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
);
spaces.add(SpaceData(name: name, icon: icon, position: centerPosition));
});
},
);
},
);
}
// Function to build a draggable space card
Widget _buildSpaceCard(int index, Size screenSize) {
return Positioned(
left: spaces[index].position.dx,
top: spaces[index].position.dy,
child: GestureDetector(
onPanUpdate: (details) {
// Update the position of the space card while dragging
setState(() {
spaces[index].position += details.delta;
});
},
child: MouseRegion(
onEnter: (_) {
// Show plus buttons on hover
setState(() {
spaces[index].isHovered = true;
});
},
onExit: (_) {
// Hide plus buttons when not hovered
setState(() {
spaces[index].isHovered = false;
});
},
child: Stack(
clipBehavior: Clip.none,
children: [
_buildSpaceContainer(index),
if (spaces[index].isHovered) ...[
_buildPlusButton(index, 'left', const Offset(-21, 20), screenSize),
_buildPlusButton(index, 'right', const Offset(140, 20), screenSize),
_buildPlusButton(index, 'down', const Offset(63, 55), screenSize),
],
],
),
),
),
);
}
// Function to build the space container with the styled format
Widget _buildSpaceContainer(int index) {
return Container(
width: 150,
height: 60,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.5),
spreadRadius: 2,
blurRadius: 5,
offset: const Offset(0, 3),
),
],
),
child: Row(
children: [
Container(
width: 40,
height: 60,
decoration: const BoxDecoration(
color: Color(0xFF023DFE),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(15),
bottomLeft: Radius.circular(15),
),
),
child: Center(
child: SvgPicture.asset(spaces[index].icon, width: 24, height: 24, color: Colors.white),
),
),
const SizedBox(width: 10),
Text(
spaces[index].name,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
],
),
);
}
// Function to build plus buttons for new space creation
Widget _buildPlusButton(int index, String direction, Offset offset, Size screenSize) {
return Positioned(
left: offset.dx,
top: offset.dy,
child: GestureDetector(
onTap: () {
Offset newPosition;
switch (direction) {
case 'left':
newPosition = spaces[index].position + const Offset(-200, 0);
break;
case 'right':
newPosition = spaces[index].position + const Offset(200, 0);
break;
case 'down':
newPosition = spaces[index].position + const Offset(0, 150);
break;
default:
newPosition = spaces[index].position;
}
_showCreateSpaceDialog(screenSize, position: newPosition);
},
child: Container(
width: 30,
height: 30,
decoration: const BoxDecoration(
color: Color(0xFF023DFE),
shape: BoxShape.circle,
),
child: const Icon(Icons.add, color: Colors.white, size: 20),
),
),
);
}
}
// 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});
}