updated device management

This commit is contained in:
hannathkadher
2024-10-11 10:35:14 +04:00
parent b87bbb9a62
commit 29a1470428
19 changed files with 207 additions and 128 deletions

View File

@ -17,7 +17,7 @@ class CreateSpaceEvent extends SpaceManagementEvent {
final int? parentIndex; final int? parentIndex;
final String? direction; final String? direction;
CreateSpaceEvent({ const CreateSpaceEvent({
required this.name, required this.name,
required this.icon, required this.icon,
required this.position, required this.position,
@ -39,7 +39,7 @@ class UpdateSpacePositionEvent extends SpaceManagementEvent {
final int index; final int index;
final Offset newPosition; final Offset newPosition;
UpdateSpacePositionEvent(this.index, this.newPosition); const UpdateSpacePositionEvent(this.index, this.newPosition);
@override @override
List<Object> get props => [index, newPosition]; List<Object> get props => [index, newPosition];
@ -51,7 +51,7 @@ class CreateCommunityEvent extends SpaceManagementEvent {
final String description; final String description;
final String regionId; final String regionId;
CreateCommunityEvent({ const CreateCommunityEvent({
required this.name, required this.name,
required this.description, required this.description,
required this.regionId, required this.regionId,

View File

@ -1,4 +1,3 @@
import 'package:flutter/material.dart';
import 'space_model.dart'; import 'space_model.dart';

View File

@ -6,10 +6,10 @@ class CommunityListViewWidget extends StatelessWidget {
final Function(CommunityModel?) onCommunitySelected; final Function(CommunityModel?) onCommunitySelected;
const CommunityListViewWidget({ const CommunityListViewWidget({
Key? key, super.key,
required this.communities, required this.communities,
required this.onCommunitySelected, required this.onCommunitySelected,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -52,7 +52,7 @@ class CommunityListViewWidget extends StatelessWidget {
// Build the blank community container // Build the blank community container
Widget _buildBlankCommunityCard(Size size) { Widget _buildBlankCommunityCard(Size size) {
return Container( return SizedBox(
width: size.width * .18, width: size.width * .18,
height: size.height * .22, height: size.height * .22,
child: Column( child: Column(
@ -66,7 +66,7 @@ class CommunityListViewWidget extends StatelessWidget {
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
border: Border.all( border: Border.all(
color: Color(0xFFE5E5E5), color: const Color(0xFFE5E5E5),
width: 5, width: 5,
), ),
), ),
@ -92,7 +92,7 @@ class CommunityListViewWidget extends StatelessWidget {
// Build a single community container based on the format provided // Build a single community container based on the format provided
Widget _buildCommunityCard(CommunityModel community, Size size) { Widget _buildCommunityCard(CommunityModel community, Size size) {
return Container( return SizedBox(
width: size.width * .18, width: size.width * .18,
height: size.height * .22, height: size.height * .22,
child: Column( child: Column(
@ -106,7 +106,7 @@ class CommunityListViewWidget extends StatelessWidget {
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
border: Border.all( border: Border.all(
color: Color(0xFFE5E5E5), color: const Color(0xFFE5E5E5),
width: 5, width: 5,
), ),
), ),
@ -118,7 +118,7 @@ class CommunityListViewWidget extends StatelessWidget {
Text( Text(
community.name ?? 'Blank', // Display community name community.name ?? 'Blank', // Display community name
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: TextStyle( style: const TextStyle(
color: Colors.black, color: Colors.black,
fontSize: 18, fontSize: 18,
fontFamily: 'Aftika', fontFamily: 'Aftika',

View File

@ -23,15 +23,14 @@ class CurvedLinePainter extends CustomPainter {
for (var connection in connections) { for (var connection in connections) {
// Ensure positions are valid before drawing lines // Ensure positions are valid before drawing lines
if (connection.startSpace.position == null || if (connection.endSpace.position == null) {
connection.endSpace.position == null) {
continue; continue;
} }
Offset start = connection.startSpace.position + Offset start = connection.startSpace.position +
Offset(75, 60); // Center bottom of start space const Offset(75, 60); // Center bottom of start space
Offset end = connection.endSpace.position + Offset end = connection.endSpace.position +
Offset(75, 0); // Center top of end space const Offset(75, 0); // Center top of end space
if (connection.direction == 'down') { if (connection.direction == 'down') {
// Curved line for down connections // Curved line for down connections

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class CreateCommunityDialog extends StatefulWidget { class CreateCommunityDialog extends StatefulWidget {
final Function(String name, String description, String regionId) final Function(String name, String description, String regionId)
@ -120,7 +121,7 @@ class CreateCommunityDialogState extends State<CreateCommunityDialog> {
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16), padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: const Color(0xFF023DFE), backgroundColor: ColorsManager.secondaryColor,
foregroundColor: Colors.white, foregroundColor: Colors.white,
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),

View File

@ -138,7 +138,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
onPressed: () { onPressed: () {
showDialog( showDialog(
context: context, context: context,
builder: (context) => AddDeviceWidget(), builder: (context) => const AddDeviceWidget(),
); );
// Logic to assign devices or select a model // Logic to assign devices or select a model
}, },
@ -183,6 +183,7 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
], ],
), ),
), ),
], ],
), ),
), ),
@ -211,9 +212,9 @@ class CreateSpaceDialogState extends State<CreateSpaceDialog> {
Navigator.of(context).pop(); // Close the dialog Navigator.of(context).pop(); // Close the dialog
} }
}, },
child: const Text('OK'), backgroundColor: ColorsManager.secondaryColor,
backgroundColor: const Color(0xFF023DFE),
foregroundColor: Colors.white, foregroundColor: Colors.white,
child: const Text('OK'),
), ),
), ),
], ],

View File

@ -18,6 +18,8 @@ import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/web_layout/web_scaffold.dart'; import 'package:syncrow_web/web_layout/web_scaffold.dart';
class SpaceManagementPage extends StatefulWidget { class SpaceManagementPage extends StatefulWidget {
const SpaceManagementPage({super.key});
@override @override
SpaceManagementPageState createState() => SpaceManagementPageState(); SpaceManagementPageState createState() => SpaceManagementPageState();
} }
@ -127,14 +129,14 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
color: ColorsManager.shadowBlackColor, // Subtle shadow color: ColorsManager.shadowBlackColor, // Subtle shadow
spreadRadius: 0, // No spread spreadRadius: 0, // No spread
blurRadius: 8, // Softer shadow edges blurRadius: 8, // Softer shadow edges
offset: Offset(0, 4), // Shadow only on the bottom offset: const Offset(0, 4), // Shadow only on the bottom
), ),
], ],
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( const Text(
'Community Structure', 'Community Structure',
style: TextStyle( style: TextStyle(
fontSize: 24, fontSize: 24,
@ -144,7 +146,7 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
if (selectedCommunity != null) ...[ if (selectedCommunity != null) ...[
Text( Text(
selectedCommunity!.name, // Show community name selectedCommunity!.name, // Show community name
style: TextStyle( style: const TextStyle(
fontSize: 16, fontSize: 16,
color: ColorsManager.blackColor, // Slightly muted color color: ColorsManager.blackColor, // Slightly muted color
), ),
@ -176,7 +178,7 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
clipBehavior: Clip.none, clipBehavior: Clip.none,
children: [ children: [
CustomPaint( CustomPaint(
size: Size(4000, 4000), size: const Size(4000, 4000),
painter: CurvedLinePainter(connections), painter: CurvedLinePainter(connections),
), ),
...spaces.asMap().entries.map((entry) { ...spaces.asMap().entries.map((entry) {

View File

@ -1,11 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:syncrow_web/pages/common/buttons/cancel_button.dart';
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
import 'package:syncrow_web/pages/device_managment/all_devices/models/device_type_model.dart'; import 'package:syncrow_web/pages/device_managment/all_devices/models/device_type_model.dart';
import 'package:syncrow_web/pages/spaces_management/widgets/counter_widget.dart';
import 'package:syncrow_web/utils/color_manager.dart'; import 'package:syncrow_web/utils/color_manager.dart';
import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:syncrow_web/utils/constants/assets.dart';
class AddDeviceWidget extends StatefulWidget { class AddDeviceWidget extends StatefulWidget {
const AddDeviceWidget({Key? key}) : super(key: key); const AddDeviceWidget({super.key});
@override @override
_AddDeviceWidgetState createState() => _AddDeviceWidgetState(); _AddDeviceWidgetState createState() => _AddDeviceWidgetState();
@ -25,23 +28,28 @@ final List<DeviceTypeModel> staticDeviceTypes = [
class _AddDeviceWidgetState extends State<AddDeviceWidget> { class _AddDeviceWidgetState extends State<AddDeviceWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
return AlertDialog( return AlertDialog(
title: const Text('Add Devices'), title: const Text('Add Devices'),
backgroundColor: ColorsManager.whiteColors, backgroundColor: ColorsManager.whiteColors,
content: Container( content: Container(
width: 800, // Set width for the dialog width: size.width * 0.65, // Set width for the dialog
height: 600, // Set height for the dialog height: size.height * 0.57, // Set height for the dialog
color: Color(0xFFF4F4F4), color: ColorsManager.textFieldGreyColor,
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 16.0), const SizedBox(height: 16.0),
Expanded( Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20.0), // Add horizontal padding
child: GridView.builder( child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, // Adjust number of items per row crossAxisCount: 6, // Display 6 items in a row
mainAxisSpacing: 10, mainAxisSpacing: 10,
crossAxisSpacing: 10, crossAxisSpacing: 10,
childAspectRatio: 1.5, childAspectRatio: 0.7, // Adjust the aspect ratio
), ),
itemCount: staticDeviceTypes.length, itemCount: staticDeviceTypes.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
@ -50,20 +58,38 @@ class _AddDeviceWidgetState extends State<AddDeviceWidget> {
}, },
), ),
), ),
),
], ],
), ),
), ),
actions: [ actions: [
TextButton( Row(
onPressed: () => Navigator.of(context).pop(), mainAxisAlignment: MainAxisAlignment
child: const Text('Cancel'), .spaceBetween, // Align cancel to the left and continue to the right
), children: [
TextButton( SizedBox(
width: 200, // Define a specific width for the button
child: DefaultButton(
onPressed: () { onPressed: () {
// Logic to save or confirm selected devices
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: const Text('OK'), backgroundColor: ColorsManager.boxColor,
foregroundColor: ColorsManager.blackColor,
child: const Text('Cancel'),
),
),
SizedBox(
width: 200, // Define a specific width for the button
child: DefaultButton(
onPressed: () {
Navigator.of(context).pop();
},
backgroundColor: ColorsManager.secondaryColor,
foregroundColor: Colors.white,
child: const Text('Continue'),
),
),
],
), ),
], ],
); );
@ -71,8 +97,8 @@ class _AddDeviceWidgetState extends State<AddDeviceWidget> {
Widget _buildDeviceTypeTile(DeviceTypeModel deviceType) { Widget _buildDeviceTypeTile(DeviceTypeModel deviceType) {
return SizedBox( return SizedBox(
width: 90, // Set desired width width: 90,
height: 120, // Set desired height height: 150, // Increase height if needed
child: Card( child: Card(
elevation: 2, elevation: 2,
color: ColorsManager.whiteColors, color: ColorsManager.whiteColors,
@ -80,21 +106,13 @@ class _AddDeviceWidgetState extends State<AddDeviceWidget> {
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
), ),
child: Padding( child: Padding(
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(8.0),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
// Fixed height container for the icon
Container( Container(
width: 60, // Width for the circular container height: 70, // Fixed height for the icon
height: 60, // Height for the circular container
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: ColorsManager.textFieldGreyColor, // Border color
width: 2, // Border width
),
color: ColorsManager.textFieldGreyColor,
),
child: Center( child: Center(
child: SvgPicture.asset( child: SvgPicture.asset(
deviceType.icon, deviceType.icon,
@ -104,32 +122,27 @@ class _AddDeviceWidgetState extends State<AddDeviceWidget> {
), ),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( // Fixed height container for the name
Container(
height: 35, // Fixed height for the text (adjust as needed)
child: Text(
deviceType.name, deviceType.name,
style: const TextStyle( style: const TextStyle(
fontSize: 14, fontSize: 12,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
), ),
textAlign: TextAlign.center,
maxLines: 2, // Allow up to 2 lines for long names
overflow: TextOverflow.ellipsis, // Handle overflow
),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Row( // The custom counter widget aligned at the bottom
mainAxisAlignment: MainAxisAlignment.center, CounterWidget(),
children: [
IconButton(
onPressed: () {
setState(() {});
},
icon: const Icon(Icons.remove_circle_outline),
),
IconButton(
onPressed: () {},
icon: const Icon(Icons.add_circle_outline),
),
],
),
], ],
), ),
), ),
)); ),
);
} }
} }

View File

@ -8,12 +8,12 @@ class CommunityTile extends StatefulWidget {
final Function(String, bool) onExpansionChanged; final Function(String, bool) onExpansionChanged;
const CommunityTile({ const CommunityTile({
Key? key, super.key,
required this.title, required this.title,
required this.initiallyExpanded, required this.initiallyExpanded,
required this.onExpansionChanged, required this.onExpansionChanged,
this.children, this.children,
}) : super(key: key); });
@override @override
_CommunityTileState createState() => _CommunityTileState(); _CommunityTileState createState() => _CommunityTileState();

View File

@ -0,0 +1,67 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class CounterWidget extends StatefulWidget {
@override
_CounterWidgetState createState() => _CounterWidgetState();
}
class _CounterWidgetState extends State<CounterWidget> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
decoration: BoxDecoration(
color: ColorsManager
.counterBackgroundColor, // Background color for the counter
borderRadius: BorderRadius.circular(20), // Rounded corners
),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Decrement button
GestureDetector(
onTap: () {
setState(() {
if (_counter > 0) {
_counter--;
}
});
},
child: Icon(
Icons.remove,
color: ColorsManager.spaceColor, // Blue color
size: 18, // Icon size
),
),
const SizedBox(width: 8),
// Counter value display
Text(
'$_counter',
style: const TextStyle(
color: ColorsManager.spaceColor, // Blue color
fontSize: 16,
),
),
const SizedBox(width: 8),
// Increment button
GestureDetector(
onTap: () {
setState(() {
_counter++;
});
},
child: const Icon(
Icons.add,
color: ColorsManager.spaceColor, // Blue color
size: 18, // Icon size
),
),
],
),
);
}
}

View File

@ -8,12 +8,12 @@ class GradientCanvasBorderWidget extends StatelessWidget {
final double width; final double width;
const GradientCanvasBorderWidget({ const GradientCanvasBorderWidget({
Key? key, super.key,
this.top = 0, this.top = 0,
this.bottom = 0, this.bottom = 0,
this.left = 300, this.left = 300,
this.width = 8, this.width = 8,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -9,13 +9,13 @@ class PlusButtonWidget extends StatelessWidget {
final Function(int index, Offset newPosition, String direction) onButtonTap; final Function(int index, Offset newPosition, String direction) onButtonTap;
const PlusButtonWidget({ const PlusButtonWidget({
Key? key, super.key,
required this.index, required this.index,
required this.direction, required this.direction,
required this.offset, required this.offset,
required this.screenSize, required this.screenSize,
required this.onButtonTap, required this.onButtonTap,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -27,13 +27,13 @@ class PlusButtonWidget extends StatelessWidget {
Offset newPosition; Offset newPosition;
switch (direction) { switch (direction) {
case 'left': case 'left':
newPosition = Offset(-200, 0); newPosition = const Offset(-200, 0);
break; break;
case 'right': case 'right':
newPosition = Offset(200, 0); newPosition = const Offset(200, 0);
break; break;
case 'down': case 'down':
newPosition = Offset(0, 150); newPosition = const Offset(0, 150);
break; break;
default: default:
newPosition = Offset.zero; newPosition = Offset.zero;

View File

@ -17,7 +17,7 @@ class SidebarWidget extends StatefulWidget {
final Function(String)? onCommunitySelected; final Function(String)? onCommunitySelected;
final List<CommunityModel> communities; final List<CommunityModel> communities;
SidebarWidget({this.onCommunitySelected, required this.communities}); const SidebarWidget({super.key, this.onCommunitySelected, required this.communities});
@override @override
_SidebarWidgetState createState() => _SidebarWidgetState(); _SidebarWidgetState createState() => _SidebarWidgetState();

View File

@ -13,7 +13,7 @@ class SpaceCardWidget extends StatelessWidget {
final Widget Function(int index) buildSpaceContainer; final Widget Function(int index) buildSpaceContainer;
const SpaceCardWidget({ const SpaceCardWidget({
Key? key, super.key,
required this.index, required this.index,
required this.screenSize, required this.screenSize,
required this.position, required this.position,
@ -22,7 +22,7 @@ class SpaceCardWidget extends StatelessWidget {
required this.onHoverChanged, required this.onHoverChanged,
required this.onButtonTap, required this.onButtonTap,
required this.buildSpaceContainer, required this.buildSpaceContainer,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -9,11 +9,11 @@ class SpaceContainerWidget extends StatelessWidget {
final String name; final String name;
const SpaceContainerWidget({ const SpaceContainerWidget({
Key? key, super.key,
required this.index, required this.index,
required this.icon, required this.icon,
required this.name, required this.name,
}) : super(key: key); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {

View File

@ -8,12 +8,12 @@ class SpaceTile extends StatefulWidget {
final List<Widget>? children; final List<Widget>? children;
const SpaceTile({ const SpaceTile({
Key? key, super.key,
required this.title, required this.title,
required this.initiallyExpanded, required this.initiallyExpanded,
required this.onExpansionChanged, required this.onExpansionChanged,
this.children, this.children,
}) : super(key: key); });
@override @override
_SpaceTileState createState() => _SpaceTileState(); _SpaceTileState createState() => _SpaceTileState();

View File

@ -16,14 +16,10 @@ class CommunitySpaceManagementApi {
List<dynamic> jsonData = json['data']; List<dynamic> jsonData = json['data'];
// Check if jsonData is actually a List // Check if jsonData is actually a List
if (jsonData is List) {
List<CommunityModel> communityList = jsonData.map((jsonItem) { List<CommunityModel> communityList = jsonData.map((jsonItem) {
return CommunityModel.fromJson(jsonItem); return CommunityModel.fromJson(jsonItem);
}).toList(); }).toList();
return communityList; return communityList;
} else {
throw Exception('Expected a list but got something else.');
}
}, },
); );
return response; return response;

View File

@ -12,7 +12,7 @@ abstract class ColorsManager {
static const Color onSecondaryColor = Color(0xFF023DFE); static const Color onSecondaryColor = Color(0xFF023DFE);
static Color shadowBlackColor = Colors.black.withOpacity(0.2); static Color shadowBlackColor = Colors.black.withOpacity(0.2);
static Color dialogBlueTitle = Color(0xFF023DFE).withOpacity(0.6); static Color dialogBlueTitle = const Color(0xFF023DFE).withOpacity(0.6);
static const Color primaryTextColor = Colors.black; static const Color primaryTextColor = Colors.black;
@ -50,5 +50,6 @@ abstract class ColorsManager {
static const Color semiTransparentBlackColor = Color(0x3F000000); static const Color semiTransparentBlackColor = Color(0x3F000000);
static const Color transparentColor = Color(0x00000000); static const Color transparentColor = Color(0x00000000);
static const Color spaceColor = Color(0xB2023DFE); static const Color spaceColor = Color(0xB2023DFE);
static const Color counterBackgroundColor = Color(0xCCF4F4F4);
} }
//0036E6 //0036E6

View File

@ -21,11 +21,11 @@ InputDecoration? textBoxDecoration({bool suffixIcon = false}) =>
borderSide: BorderSide.none, // Remove the underline borderSide: BorderSide.none, // Remove the underline
), ),
errorBorder: OutlineInputBorder( errorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2), borderSide: const BorderSide(color: Colors.red, width: 2),
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
), ),
focusedErrorBorder: OutlineInputBorder( focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red, width: 2), borderSide: const BorderSide(color: Colors.red, width: 2),
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
), ),
); );