mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
added subspace model events
This commit is contained in:
@ -59,10 +59,12 @@ class SpaceManagementPageState extends State<SpaceManagementPage> {
|
||||
selectedSpace: state.selectedSpace,
|
||||
products: state.products,
|
||||
);
|
||||
}else if(state is SpaceModelLoaded){
|
||||
return LoadedSpaceView(communities: state.communities, products: state.products, spaceModels: state.spaceModels);
|
||||
}
|
||||
else if (state is SpaceManagementError) {
|
||||
} else if (state is SpaceModelLoaded) {
|
||||
return LoadedSpaceView(
|
||||
communities: state.communities,
|
||||
products: state.products,
|
||||
spaceModels: state.spaceModels);
|
||||
} else if (state is SpaceManagementError) {
|
||||
return Center(child: Text('Error: ${state.errorMessage}'));
|
||||
}
|
||||
return Container();
|
||||
|
@ -0,0 +1,38 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||
|
||||
// Events
|
||||
abstract class SubSpaceModelEvent {}
|
||||
|
||||
class AddSubSpaceModel extends SubSpaceModelEvent {
|
||||
final SubspaceTemplateModel subSpace;
|
||||
AddSubSpaceModel(this.subSpace);
|
||||
}
|
||||
|
||||
class RemoveSubSpaceModel extends SubSpaceModelEvent {
|
||||
final SubspaceTemplateModel subSpace;
|
||||
RemoveSubSpaceModel(this.subSpace);
|
||||
}
|
||||
|
||||
// State
|
||||
class SubSpaceModelState {
|
||||
final List<SubspaceTemplateModel> subSpaces;
|
||||
SubSpaceModelState(this.subSpaces);
|
||||
}
|
||||
|
||||
// BLoC
|
||||
class SubSpaceModelBloc extends Bloc<SubSpaceModelEvent, SubSpaceModelState> {
|
||||
SubSpaceModelBloc() : super(SubSpaceModelState([])) {
|
||||
on<AddSubSpaceModel>((event, emit) {
|
||||
final updatedSubSpaces = List<SubspaceTemplateModel>.from(state.subSpaces)
|
||||
..add(event.subSpace);
|
||||
emit(SubSpaceModelState(updatedSubSpaces));
|
||||
});
|
||||
|
||||
on<RemoveSubSpaceModel>((event, emit) {
|
||||
final updatedSubSpaces = List<SubspaceTemplateModel>.from(state.subSpaces)
|
||||
..remove(event.subSpace);
|
||||
emit(SubSpaceModelState(updatedSubSpaces));
|
||||
});
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
|
||||
class SpaceTemplateModel {
|
||||
final String uuid;
|
||||
@ -6,28 +7,33 @@ class SpaceTemplateModel {
|
||||
final DateTime updatedAt;
|
||||
final String modelName;
|
||||
final bool disabled;
|
||||
final List<SubspaceModel> subspaceModels;
|
||||
final List<SubspaceTemplateModel> subspaceModels;
|
||||
final List<TagModel> tags;
|
||||
String internalId;
|
||||
|
||||
SpaceTemplateModel({
|
||||
required this.uuid,
|
||||
String? internalId,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
required this.modelName,
|
||||
required this.disabled,
|
||||
required this.subspaceModels,
|
||||
required this.tags,
|
||||
});
|
||||
}) : internalId = internalId ?? const Uuid().v4();
|
||||
|
||||
factory SpaceTemplateModel.fromJson(Map<String, dynamic> json) {
|
||||
final String internalId = json['internalId'] ?? const Uuid().v4();
|
||||
|
||||
return SpaceTemplateModel(
|
||||
uuid: json['uuid'] ?? '',
|
||||
internalId: internalId,
|
||||
createdAt: DateTime.parse(json['createdAt']),
|
||||
updatedAt: DateTime.parse(json['updatedAt']),
|
||||
modelName: json['modelName'] ?? '',
|
||||
disabled: json['disabled'] ?? false,
|
||||
subspaceModels: (json['subspaceModels'] as List)
|
||||
.map((item) => SubspaceModel.fromJson(item))
|
||||
.map((item) => SubspaceTemplateModel.fromJson(item))
|
||||
.toList(),
|
||||
tags: (json['tags'] as List)
|
||||
.map((item) => TagModel.fromJson(item))
|
||||
@ -48,28 +54,22 @@ class SpaceTemplateModel {
|
||||
}
|
||||
}
|
||||
|
||||
class SubspaceModel {
|
||||
final String uuid;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
class SubspaceTemplateModel {
|
||||
final String? uuid;
|
||||
final String subspaceName;
|
||||
final bool disabled;
|
||||
final List<TagModel> tags;
|
||||
final List<TagModel>? tags;
|
||||
|
||||
SubspaceModel({
|
||||
required this.uuid,
|
||||
required this.createdAt,
|
||||
required this.updatedAt,
|
||||
SubspaceTemplateModel({
|
||||
this.uuid,
|
||||
required this.subspaceName,
|
||||
required this.disabled,
|
||||
required this.tags,
|
||||
this.tags,
|
||||
});
|
||||
|
||||
factory SubspaceModel.fromJson(Map<String, dynamic> json) {
|
||||
return SubspaceModel(
|
||||
factory SubspaceTemplateModel.fromJson(Map<String, dynamic> json) {
|
||||
return SubspaceTemplateModel(
|
||||
uuid: json['uuid'] ?? '',
|
||||
createdAt: DateTime.parse(json['createdAt']),
|
||||
updatedAt: DateTime.parse(json['updatedAt']),
|
||||
subspaceName: json['subspaceName'] ?? '',
|
||||
disabled: json['disabled'] ?? false,
|
||||
tags: (json['tags'] as List)
|
||||
@ -81,11 +81,9 @@ class SubspaceModel {
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'uuid': uuid,
|
||||
'createdAt': createdAt.toIso8601String(),
|
||||
'updatedAt': updatedAt.toIso8601String(),
|
||||
'subspaceName': subspaceName,
|
||||
'disabled': disabled,
|
||||
'tags': tags.map((e) => e.toJson()).toList(),
|
||||
'tags': tags?.map((e) => e.toJson()).toList() ?? [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
import 'package:flutter/material.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/spaces_management/space_model/models/space_template_model.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_subspace_model_dialog.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CreateSpaceModelDialog extends StatelessWidget {
|
||||
@ -48,37 +50,58 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
SizedBox(
|
||||
width: screenWidth * 0.25,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.textFieldGreyColor,
|
||||
border: Border.all(
|
||||
color: ColorsManager.neutralGray,
|
||||
width: 3.0,
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
final result = await showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return CreateSubSpaceModelDialog(
|
||||
isEdit: true,
|
||||
dialogTitle: 'Create Sub-space',
|
||||
existingSubSpaces: [
|
||||
SubspaceTemplateModel(
|
||||
subspaceName: "Living Room",
|
||||
disabled: false,
|
||||
uuid: "mkmkl,",
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
if (result == true) {}
|
||||
},
|
||||
child: SizedBox(
|
||||
width: screenWidth * 0.25,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.textFieldGreyColor,
|
||||
border: Border.all(
|
||||
color: ColorsManager.neutralGray,
|
||||
width: 3.0,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: const Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.add,
|
||||
color: ColorsManager.spaceColor,
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Create sub space',
|
||||
style: TextStyle(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 16,
|
||||
child: const Padding(
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: 10.0, horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.add,
|
||||
color: ColorsManager.spaceColor,
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'Create sub space',
|
||||
style: TextStyle(
|
||||
color: ColorsManager.blackColor,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -0,0 +1,188 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.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/spaces_management/space_model/bloc/subspace_model_bloc.dart';
|
||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart';
|
||||
import 'package:syncrow_web/utils/color_manager.dart';
|
||||
|
||||
class CreateSubSpaceModelDialog extends StatefulWidget {
|
||||
final bool isEdit; // Flag to determine if it's edit or create
|
||||
final String dialogTitle; // Title for the dialog
|
||||
final List<SubspaceTemplateModel>? existingSubSpaces; // For edit mode
|
||||
|
||||
const CreateSubSpaceModelDialog({
|
||||
super.key,
|
||||
required this.isEdit,
|
||||
required this.dialogTitle,
|
||||
this.existingSubSpaces,
|
||||
});
|
||||
|
||||
@override
|
||||
_CreateSubSpaceModelDialogState createState() =>
|
||||
_CreateSubSpaceModelDialogState();
|
||||
}
|
||||
|
||||
class _CreateSubSpaceModelDialogState extends State<CreateSubSpaceModelDialog> {
|
||||
final TextEditingController textController = TextEditingController();
|
||||
final FocusNode focusNode = FocusNode();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
focusNode.requestFocus();
|
||||
});
|
||||
|
||||
if (widget.isEdit) {}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
textController.dispose();
|
||||
focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenWidth = MediaQuery.of(context).size.width;
|
||||
|
||||
return Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: BlocProvider(
|
||||
create: (_) => SubSpaceModelBloc(),
|
||||
child: BlocBuilder<SubSpaceModelBloc, SubSpaceModelState>(
|
||||
builder: (context, state) {
|
||||
return SizedBox(
|
||||
width: screenWidth * 0.35,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
widget.dialogTitle,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headlineLarge
|
||||
?.copyWith(color: ColorsManager.blackColor),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
width: screenWidth * 0.35,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 10.0, horizontal: 16.0),
|
||||
decoration: BoxDecoration(
|
||||
color: ColorsManager.boxColor,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Wrap(
|
||||
spacing: 8.0,
|
||||
runSpacing: 8.0,
|
||||
children: [
|
||||
...state.subSpaces.map(
|
||||
(subSpace) => Chip(
|
||||
label: Text(subSpace.subspaceName,
|
||||
style: const TextStyle(
|
||||
color: ColorsManager.spaceColor)),
|
||||
backgroundColor: ColorsManager.whiteColors,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: const BorderSide(
|
||||
color: ColorsManager.transparentColor,
|
||||
width: 0),
|
||||
),
|
||||
deleteIcon: Container(
|
||||
width: 24,
|
||||
height: 24,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: ColorsManager.lightGrayColor,
|
||||
width: 1.5,
|
||||
),
|
||||
),
|
||||
child: const Icon(
|
||||
Icons.close,
|
||||
size: 16,
|
||||
color: ColorsManager.lightGrayColor,
|
||||
),
|
||||
),
|
||||
onDeleted: () => context
|
||||
.read<SubSpaceModelBloc>()
|
||||
.add(RemoveSubSpaceModel(subSpace)),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 200,
|
||||
child: TextField(
|
||||
controller: textController,
|
||||
focusNode: focusNode,
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
hintText: state.subSpaces.isEmpty
|
||||
? 'Please enter the name'
|
||||
: null,
|
||||
hintStyle: const TextStyle(
|
||||
color: ColorsManager.lightGrayColor),
|
||||
),
|
||||
onSubmitted: (value) {
|
||||
if (value.trim().isNotEmpty) {
|
||||
context.read<SubSpaceModelBloc>().add(
|
||||
AddSubSpaceModel(SubspaceTemplateModel(
|
||||
subspaceName: value.trim(),
|
||||
disabled: false)));
|
||||
textController.clear();
|
||||
focusNode.requestFocus();
|
||||
}
|
||||
},
|
||||
style: const TextStyle(
|
||||
color: ColorsManager.blackColor),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CancelButton(
|
||||
label: 'Cancel',
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(
|
||||
child: DefaultButton(
|
||||
onPressed: () {
|
||||
final subSpaces = context
|
||||
.read<SubSpaceModelBloc>()
|
||||
.state
|
||||
.subSpaces;
|
||||
Navigator.of(context).pop(subSpaces);
|
||||
},
|
||||
backgroundColor: ColorsManager.secondaryColor,
|
||||
borderRadius: 10,
|
||||
foregroundColor: ColorsManager.whiteColors,
|
||||
child: const Text('OK'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -19,9 +19,11 @@ class SpaceModelCardWidget extends StatelessWidget {
|
||||
}
|
||||
|
||||
for (var subspace in model.subspaceModels) {
|
||||
for (var tag in subspace.tags) {
|
||||
final prodIcon = tag.product?.icon ?? 'Unknown';
|
||||
productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1;
|
||||
if (subspace.tags != null) {
|
||||
for (var tag in subspace.tags!) {
|
||||
final prodIcon = tag.product?.icon ?? 'Unknown';
|
||||
productTagCount[prodIcon] = (productTagCount[prodIcon] ?? 0) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
class TempConst {
|
||||
static const projectId = '0e62577c-06fa-41b9-8a92-99a21fbaf51c';
|
||||
static const projectId = '0685c781-df33-4cbf-bf65-9f4e835eb468';
|
||||
}
|
||||
|
Reference in New Issue
Block a user