link space model api integration

This commit is contained in:
mohammad
2025-03-05 14:37:52 +03:00
parent b134823551
commit 215dd9cfa4
8 changed files with 758 additions and 273 deletions

View File

@ -1,16 +1,241 @@
// import 'package:flutter/material.dart';
// import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
// import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_bloc.dart';
// import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_event.dart';
// import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
// import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart';
// import 'package:syncrow_web/utils/color_manager.dart';
// class LinkSpaceModelSpacesDialog extends StatefulWidget {
// final SpaceTemplateModel spaceModel;
// LinkSpaceModelSpacesDialog({super.key, required this.spaceModel});
// @override
// State<LinkSpaceModelSpacesDialog> createState() =>
// _LinkSpaceModelSpacesDialogState();
// }
// class _LinkSpaceModelSpacesDialogState
// extends State<LinkSpaceModelSpacesDialog> {
// TextEditingController searchController = TextEditingController();
// @override
// void initState() {
// context.read<SpaceModelBloc>().add(SpaceModelSelectedIdsEvent());
// super.initState();
// }
// @override
// Widget build(BuildContext context) {
// return AlertDialog(
// contentPadding: EdgeInsets.zero,
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
// backgroundColor: Colors.white,
// content: SizedBox(
// width: MediaQuery.of(context).size.width * 0.4,
// child: Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Expanded(
// child: Padding(
// padding: const EdgeInsets.all(15.0),
// child: Column(
// mainAxisSize: MainAxisSize.min,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// const Center(
// child: Text(
// "Link Space Model to Spaces",
// style: TextStyle(
// fontSize: 18,
// fontWeight: FontWeight.bold,
// color: Colors.blueAccent,
// ),
// ),
// ),
// const Divider(),
// const SizedBox(height: 16),
// _buildDetailRow(
// "Space model name:", widget.spaceModel.modelName),
// _buildDetailRow("Creation date and time:",
// widget.spaceModel.createdAt.toString()),
// _buildDetailRow("Created by:", "Admin"),
// const SizedBox(height: 12),
// const Text(
// "Link to:",
// style: TextStyle(fontWeight: FontWeight.bold),
// ),
// const Text(
// "Please select all the spaces where you would like to link the Routine.",
// style: TextStyle(fontSize: 12, color: Colors.grey),
// ),
// const SizedBox(height: 8),
// Expanded(
// child: SizedBox(
// child: Column(
// children: [
// Expanded(
// flex: 7,
// child: Container(
// color: ColorsManager.whiteColors,
// child: SpaceTreeView(
// isSide: true,
// onSelect: () {
// context.read<SpaceModelBloc>().add(
// SpaceModelSelectedIdsEvent());
// })))
// ],
// ),
// ),
// ),
// const SizedBox(
// height: 20,
// ),
// ],
// ),
// ),
// ),
// // Buttons
// Row(
// children: [
// Expanded(
// child: Container(
// height: 50,
// decoration: const BoxDecoration(
// border: Border(
// right: BorderSide(
// color: ColorsManager.grayColor,
// width: 0.5,
// ),
// top: BorderSide(
// color: ColorsManager.grayColor,
// width: 1,
// ),
// ),
// ),
// child: _buildButton("Cancel", Colors.grey, () {
// Navigator.of(context).pop();
// }),
// ),
// ),
// Expanded(
// child: Container(
// height: 50,
// decoration: const BoxDecoration(
// border: Border(
// left: BorderSide(
// color: ColorsManager.grayColor,
// width: 0.5,
// ),
// top: BorderSide(
// color: ColorsManager.grayColor,
// width: 1.0,
// ),
// ),
// ),
// child: _buildButton(
// "Confirm", ColorsManager.onSecondaryColor, () {
// final spaceModelBloc = context.read<SpaceModelBloc>();
// if (!spaceModelBloc.hasSelectedSpaces) {
// ScaffoldMessenger.of(context).showSnackBar(
// const SnackBar(
// content:
// Text("Please select at least one space")),
// );
// return;
// } else {
// // spaceModelBloc.add(LinkSpaceModelEvent(
// // selectedSpaceMode: widget.spaceModel.uuid));
// spaceModelBloc.add(ValidateSpaceModelEvent(context: context));
// }
// Future.delayed(const Duration(seconds: 3), () {
// Navigator.of(context).pop();
// Navigator.of(context).pop();
// // showDialog(
// // context: context,
// // builder: (BuildContext dialogContext) {
// // return const LinkingSuccessful();
// // },
// // );
// showDialog(
// context: context,
// builder: (BuildContext dialogContext) {
// return const ConfirmOverwriteDialog();
// },
// );
// });
// }),
// ),
// ),
// ],
// ),
// ],
// ),
// ),
// );
// }
// // Method to build a detail row
// Widget _buildDetailRow(String label, String value) {
// return Padding(
// padding: const EdgeInsets.symmetric(vertical: 4),
// child: Row(
// children: [
// Expanded(
// child: Text(
// label,
// style: TextStyle(fontWeight: FontWeight.bold),
// ),
// ),
// const SizedBox(width: 8),
// Expanded(
// child: Text(
// value,
// style:
// TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
// ),
// ),
// ],
// ),
// );
// }
// Widget _buildButton(String text, Color color, VoidCallback onPressed) {
// return InkWell(
// onTap: onPressed,
// child: Center(
// child: Text(
// text,
// style: TextStyle(
// color: color, fontWeight: FontWeight.w400, fontSize: 14),
// ),
// ),
// );
// }
// }
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:syncrow_web/pages/space_tree/view/space_tree_view.dart';
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_event.dart';
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_state.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/confirm_overwrite_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/custom_loading_dialog.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/overwrite_dialog.dart';
import 'package:syncrow_web/utils/color_manager.dart';
class LinkSpaceModelSpacesDialog extends StatefulWidget {
final SpaceTemplateModel spaceModel;
LinkSpaceModelSpacesDialog({super.key, required this.spaceModel});
const LinkSpaceModelSpacesDialog({super.key, required this.spaceModel});
@override
State<LinkSpaceModelSpacesDialog> createState() =>
@ -19,7 +244,8 @@ class LinkSpaceModelSpacesDialog extends StatefulWidget {
class _LinkSpaceModelSpacesDialogState
extends State<LinkSpaceModelSpacesDialog> {
TextEditingController searchController = TextEditingController();
final TextEditingController _searchController = TextEditingController();
bool _isLoading = false;
@override
void initState() {
@ -39,213 +265,253 @@ class _LinkSpaceModelSpacesDialogState
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Center(
child: Text(
"Link Space Model to Spaces",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.blueAccent,
),
),
),
const Divider(),
const SizedBox(height: 16),
_buildDetailRow(
"Space model name:", widget.spaceModel.modelName),
_buildDetailRow("Creation date and time:",
widget.spaceModel.createdAt.toString()),
_buildDetailRow("Created by:", "Admin"),
const SizedBox(height: 12),
const Text(
"Link to:",
style: TextStyle(fontWeight: FontWeight.bold),
),
const Text(
"Please select all the spaces where you would like to link the Routine.",
style: TextStyle(fontSize: 12, color: Colors.grey),
),
const SizedBox(height: 8),
Expanded(
child: SizedBox(
child: Column(
children: [
Expanded(
flex: 7,
child: Container(
color: ColorsManager.whiteColors,
child: SpaceTreeView(
isSide: true,
onSelect: () {
context.read<SpaceModelBloc>().add(
SpaceModelSelectedIdsEvent());
})))
],
),
),
),
const SizedBox(
height: 20,
),
],
),
),
),
// Buttons
Row(
children: [
Expanded(
child: Container(
height: 50,
decoration: const BoxDecoration(
border: Border(
right: BorderSide(
color: ColorsManager.grayColor,
width: 0.5,
),
top: BorderSide(
color: ColorsManager.grayColor,
width: 1,
),
),
),
child: _buildButton("Cancel", Colors.grey, () {
Navigator.of(context).pop();
}),
),
),
Expanded(
child: Container(
height: 50,
decoration: const BoxDecoration(
border: Border(
left: BorderSide(
color: ColorsManager.grayColor,
width: 0.5,
),
top: BorderSide(
color: ColorsManager.grayColor,
width: 1.0,
),
),
),
child: _buildButton(
"Confirm", ColorsManager.onSecondaryColor, () {
final spaceModelBloc = context.read<SpaceModelBloc>();
if (!spaceModelBloc.hasSelectedSpaces) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content:
Text("Please select at least one space")),
);
return;
}
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
elevation: 10,
backgroundColor: Colors.white,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 30, horizontal: 50),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CustomLoadingIndicator(),
const SizedBox(height: 20),
const Text(
"Linking in progress",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
],
),
),
);
},
).then(
(value) {},
);
Future.delayed(const Duration(seconds: 3), () {
Navigator.of(context).pop();
Navigator.of(context).pop();
// showDialog(
// context: context,
// builder: (BuildContext dialogContext) {
// return const LinkingSuccessful();
// },
// );
showDialog(
context: context,
builder: (BuildContext dialogContext) {
return const ConfirmOverwriteDialog();
},
);
});
}),
),
),
],
),
_buildDialogContent(),
_buildActionButtons(),
],
),
),
);
}
// Method to build a detail row
Widget _buildDetailRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Expanded(
child: Text(
label,
style: TextStyle(fontWeight: FontWeight.bold),
),
Widget _buildDialogContent() {
return Expanded(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.4,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Center(
child: Text(
"Link Space Model to Spaces",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.blueAccent,
),
),
),
const Divider(),
const SizedBox(height: 16),
_buildDetailRow(
"Space model name:", widget.spaceModel.modelName),
_buildDetailRow("Creation date and time:",
widget.spaceModel.createdAt.toString()),
_buildDetailRow("Created by:", "Admin"),
const SizedBox(height: 12),
const Text(
"Link to:",
style: TextStyle(fontWeight: FontWeight.bold),
),
const Text(
"Please select all the spaces where you would like to link the Routine.",
style: TextStyle(fontSize: 12, color: Colors.grey),
),
const SizedBox(height: 8),
Expanded(
child: SizedBox(
child: Column(
children: [
Expanded(
flex: 7,
child: Container(
color: ColorsManager.whiteColors,
child: SpaceTreeView(
isSide: true,
onSelect: () {
context.read<SpaceModelBloc>().add(
SpaceModelSelectedIdsEvent());
})))
],
),
),
),
const SizedBox(
height: 20,
),
],
),
),
),
],
),
const SizedBox(width: 8),
Expanded(
child: Text(
value,
style:
TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
),
],
),
),
);
}
// Button Widget
Widget _buildButton(String text, Color color, VoidCallback onPressed) {
return InkWell(
onTap: onPressed,
child: Center(
child: Text(
text,
style: TextStyle(
color: color, fontWeight: FontWeight.w400, fontSize: 14),
Widget _buildActionButtons() {
return Row(
children: [
Expanded(
child: Container(
height: 50,
decoration: const BoxDecoration(
border: Border(
right: BorderSide(
color: ColorsManager.grayColor,
width: 0.5,
),
top: BorderSide(
color: ColorsManager.grayColor,
width: 1,
),
),
),
child: _buildButton("Cancel", Colors.grey, () {
Navigator.of(context).pop();
}),
),
),
Expanded(
child: Container(
height: 50,
decoration: const BoxDecoration(
border: Border(
left: BorderSide(
color: ColorsManager.grayColor,
width: 0.5,
),
top: BorderSide(
color: ColorsManager.grayColor,
width: 1.0,
),
),
),
child: _buildButton(
"Confirm",
ColorsManager.onSecondaryColor,
() {
final spaceModelBloc = context.read<SpaceModelBloc>();
if (!spaceModelBloc.hasSelectedSpaces) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Please select at least one space")),
);
return;
} else {
spaceModelBloc.add(ValidateSpaceModelEvent(context: context));
}
},
),
),
),
],
);
}
void _handleConfirm() {
final bloc = context.read<SpaceModelBloc>();
if (!bloc.hasSelectedSpaces) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text("Please select at least one space")),
);
return;
}
// Trigger validation
bloc.add(ValidateSpaceModelEvent());
}
void _showLoadingDialog() {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) => const _LoadingDialog(),
);
}
void _handleValidationSuccess() {
Navigator.of(context).pop(); // Close loading dialog
// Show overwrite confirmation
showDialog(
context: context,
builder: (context) => const ConfirmOverwriteDialog(),
).then((_) {
// Close main dialog after confirmation
if (mounted) Navigator.of(context).pop();
});
}
void _handleValidationError(String message) {
Navigator.of(context).pop(); // Close loading dialog
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}
void _handleCancel() {
if (mounted) Navigator.of(context).pop();
}
// Rest of your helper methods (_buildDetailRow, _buildButton, etc.)
}
class _LoadingDialog extends StatelessWidget {
const _LoadingDialog();
@override
Widget build(BuildContext context) {
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
child: const Padding(
padding: EdgeInsets.all(20.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(),
SizedBox(height: 16),
Text("Linking in progress..."),
],
),
),
);
}
}
// Method to build a detail row
Widget _buildDetailRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4),
child: Row(
children: [
Expanded(
child: Text(
label,
style: TextStyle(fontWeight: FontWeight.bold),
),
),
const SizedBox(width: 8),
Expanded(
child: Text(
value,
style: TextStyle(fontWeight: FontWeight.bold, color: Colors.black),
),
),
],
),
);
}
Widget _buildButton(String text, Color color, VoidCallback onPressed) {
return InkWell(
onTap: onPressed,
child: Center(
child: Text(
text,
style:
TextStyle(color: color, fontWeight: FontWeight.w400, fontSize: 14),
),
),
);
}

View File

@ -1,24 +1,27 @@
import 'package:flutter/material.dart';
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_bloc.dart';
import 'package:syncrow_web/pages/spaces_management/link_space_model/bloc/link_space_model_event.dart';
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
void showOverwriteDialog(BuildContext context) {
void showOverwriteDialog(
BuildContext context, SpaceModelBloc bloc, SpaceTemplateModel model) {
showDialog(
context: context,
barrierDismissible: false,
barrierDismissible: false,
builder: (BuildContext context) {
return Container(
return SizedBox(
child: Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
elevation: 10,
backgroundColor: Colors.white,
child: Container(
child: SizedBox(
width: MediaQuery.of(context).size.width * 0.3,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 30, horizontal: 20),
padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 20),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Title
const Text(
"Overwrite",
style: TextStyle(
@ -27,15 +30,13 @@ void showOverwriteDialog(BuildContext context) {
color: Colors.black,
),
),
SizedBox(height: 15),
// Description
const SizedBox(height: 15),
const Text(
"Are you sure you want to overwrite?",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
textAlign: TextAlign.center,
),
SizedBox(height: 5),
const SizedBox(height: 5),
Text(
"Selected spaces already have linked space model / sub-spaces and devices",
style: TextStyle(
@ -44,25 +45,22 @@ void showOverwriteDialog(BuildContext context) {
),
textAlign: TextAlign.center,
),
SizedBox(height: 25),
// Buttons
const SizedBox(height: 25),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// Cancel Button
Expanded(
child: ElevatedButton(
onPressed: () => Navigator.of(context).pop(),
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 14),
padding: const EdgeInsets.symmetric(vertical: 14),
backgroundColor: Colors.grey[200],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 0,
),
child: Text(
child: const Text(
"Cancel",
style: TextStyle(
fontSize: 16,
@ -72,24 +70,24 @@ void showOverwriteDialog(BuildContext context) {
),
),
),
SizedBox(width: 10),
// OK Button
const SizedBox(width: 10),
Expanded(
child: ElevatedButton(
onPressed: () {
bloc.add(LinkSpaceModelEvent(
isOverWrite: true,
selectedSpaceMode: model.uuid));
Navigator.of(context).pop();
// Add action for OK button
},
style: ElevatedButton.styleFrom(
padding: EdgeInsets.symmetric(vertical: 14),
padding: const EdgeInsets.symmetric(vertical: 14),
backgroundColor: Colors.blue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 3,
),
child: Text(
child: const Text(
"OK",
style: TextStyle(
fontSize: 16,