added subspace model events

This commit is contained in:
hannathkadher
2025-01-03 14:28:45 +04:00
parent e0ff139f30
commit 944b981ee0
7 changed files with 307 additions and 56 deletions

View File

@ -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();

View File

@ -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));
});
}
}

View File

@ -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() ?? [],
};
}
}

View File

@ -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,
),
),
),
),
],
],
),
),
),
),

View File

@ -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'),
),
),
],
),
],
),
),
);
},
),
),
);
}
}

View File

@ -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;
}
}
}

View File

@ -1,3 +1,3 @@
class TempConst {
static const projectId = '0e62577c-06fa-41b9-8a92-99a21fbaf51c';
static const projectId = '0685c781-df33-4cbf-bf65-9f4e835eb468';
}