mirror of
https://github.com/SyncrowIOT/web.git
synced 2025-07-10 15:17:31 +00:00
space model creation
This commit is contained in:
@ -24,7 +24,7 @@ class AssignTagModelBloc
|
|||||||
AssignTagModelLoaded(tags: tags, isSaveEnabled: _validateTags(tags)));
|
AssignTagModelLoaded(tags: tags, isSaveEnabled: _validateTags(tags)));
|
||||||
});
|
});
|
||||||
|
|
||||||
on<UpdateTagModel>((event, emit) {
|
on<UpdateTag>((event, emit) {
|
||||||
final currentState = state;
|
final currentState = state;
|
||||||
|
|
||||||
if (currentState is AssignTagModelLoaded &&
|
if (currentState is AssignTagModelLoaded &&
|
||||||
|
@ -22,11 +22,11 @@ class InitializeTagModels extends AssignTagModelEvent {
|
|||||||
List<Object> get props => [initialTags ?? [], addedProducts];
|
List<Object> get props => [initialTags ?? [], addedProducts];
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdateTagModel extends AssignTagModelEvent {
|
class UpdateTag extends AssignTagModelEvent {
|
||||||
final int index;
|
final int index;
|
||||||
final String tag;
|
final String tag;
|
||||||
|
|
||||||
const UpdateTagModel({required this.index, required this.tag});
|
const UpdateTag({required this.index, required this.tag});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [index, tag];
|
List<Object> get props => [index, tag];
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.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/all_spaces/model/product_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/selected_product_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_model_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/assign_tag_models/bloc/assign_tag_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/models/subspace_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/tag_model.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/dialog/create_space_model_dialog.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
||||||
class AssignTagModelsDialog extends StatelessWidget {
|
class AssignTagModelsDialog extends StatelessWidget {
|
||||||
@ -16,6 +20,7 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
final ValueChanged<List<TagModel>>? onTagsAssigned;
|
final ValueChanged<List<TagModel>>? onTagsAssigned;
|
||||||
final List<SelectedProduct> addedProducts;
|
final List<SelectedProduct> addedProducts;
|
||||||
final List<String>? allTags;
|
final List<String>? allTags;
|
||||||
|
final String spaceName;
|
||||||
|
|
||||||
const AssignTagModelsDialog({
|
const AssignTagModelsDialog({
|
||||||
Key? key,
|
Key? key,
|
||||||
@ -25,6 +30,7 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
this.initialTags,
|
this.initialTags,
|
||||||
this.onTagsAssigned,
|
this.onTagsAssigned,
|
||||||
this.allTags,
|
this.allTags,
|
||||||
|
required this.spaceName,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -40,9 +46,6 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
child: BlocBuilder<AssignTagModelBloc, AssignTagModelState>(
|
child: BlocBuilder<AssignTagModelBloc, AssignTagModelState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is AssignTagModelLoaded) {
|
if (state is AssignTagModelLoaded) {
|
||||||
print(
|
|
||||||
"Rebuilding UI with updated locations: ${state.tags.map((e) => e.location)}");
|
|
||||||
|
|
||||||
final controllers = List.generate(
|
final controllers = List.generate(
|
||||||
state.tags.length,
|
state.tags.length,
|
||||||
(index) => TextEditingController(text: state.tags[index].tag),
|
(index) => TextEditingController(text: state.tags[index].tag),
|
||||||
@ -143,7 +146,7 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
context
|
context
|
||||||
.read<AssignTagModelBloc>()
|
.read<AssignTagModelBloc>()
|
||||||
.add(UpdateTagModel(
|
.add(UpdateTag(
|
||||||
index: index,
|
index: index,
|
||||||
tag: value.trim(),
|
tag: value.trim(),
|
||||||
));
|
));
|
||||||
@ -172,7 +175,7 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
controller.text = value;
|
controller.text = value;
|
||||||
context
|
context
|
||||||
.read<AssignTagModelBloc>()
|
.read<AssignTagModelBloc>()
|
||||||
.add(UpdateTagModel(
|
.add(UpdateTag(
|
||||||
index: index,
|
index: index,
|
||||||
tag: value,
|
tag: value,
|
||||||
));
|
));
|
||||||
@ -274,16 +277,47 @@ class AssignTagModelsDialog extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
actions: [
|
actions: [
|
||||||
ElevatedButton(
|
Row(
|
||||||
onPressed: state.isSaveEnabled
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
? () {
|
children: [
|
||||||
if (onTagsAssigned != null) {
|
const SizedBox(width: 10),
|
||||||
onTagsAssigned!(state.tags);
|
Expanded(
|
||||||
}
|
child: CancelButton(
|
||||||
Navigator.pop(context);
|
label: 'Cancel',
|
||||||
}
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
: null,
|
),
|
||||||
child: const Text('Save'),
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
Expanded(
|
||||||
|
child: DefaultButton(
|
||||||
|
borderRadius: 10,
|
||||||
|
backgroundColor: state.isSaveEnabled
|
||||||
|
? ColorsManager.secondaryColor
|
||||||
|
: ColorsManager.grayColor,
|
||||||
|
foregroundColor: ColorsManager.whiteColors,
|
||||||
|
onPressed: state.isSaveEnabled
|
||||||
|
? () async {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
|
await showDialog(
|
||||||
|
barrierDismissible: false,
|
||||||
|
context: context,
|
||||||
|
builder: (context) => CreateSpaceModelDialog(
|
||||||
|
products: products,
|
||||||
|
allTags: allTags,
|
||||||
|
spaceModel: SpaceTemplateModel(
|
||||||
|
modelName: spaceName,
|
||||||
|
subspaceModels: subspaces,
|
||||||
|
tags: state.tags),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
child: const Text('Save'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(width: 10),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/subspace_model/bloc/subspace_model_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/subspace_model/bloc/subspace_model_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_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/models/space_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
||||||
import 'package:syncrow_web/utils/constants/action_enum.dart';
|
import 'package:syncrow_web/utils/constants/action_enum.dart';
|
@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.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/cancel_button.dart';
|
||||||
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
import 'package:syncrow_web/pages/common/buttons/default_button.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/subspace_model/bloc/subspace_model_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_bloc.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/subspace_model/bloc/subspace_model_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/subspace_model/bloc/subspace_model_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/bloc/subspace_model_state.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
|
|
@ -24,6 +24,16 @@ class CreateSpaceModelBloc
|
|||||||
emit(CreateSpaceModelLoaded(_space!));
|
emit(CreateSpaceModelLoaded(_space!));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
on<UpdateSpaceTemplateName>((event, emit) {
|
||||||
|
if (_space != null) {
|
||||||
|
_space = _space!.copyWith(modelName: event.name); // Use copyWith for immutability
|
||||||
|
emit(CreateSpaceModelLoaded(_space!));
|
||||||
|
} else {
|
||||||
|
emit(CreateSpaceModelError("Space template not initialized"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
on<AddSubspacesToSpaceTemplate>((event, emit) {
|
on<AddSubspacesToSpaceTemplate>((event, emit) {
|
||||||
if (_space != null) {
|
if (_space != null) {
|
||||||
final updatedSpace = _space!.copyWith(
|
final updatedSpace = _space!.copyWith(
|
||||||
|
@ -11,6 +11,15 @@ class UpdateSpaceTemplate extends CreateSpaceModelEvent {
|
|||||||
UpdateSpaceTemplate(this.spaceTemplate);
|
UpdateSpaceTemplate(this.spaceTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class UpdateSpaceTemplateName extends CreateSpaceModelEvent {
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
UpdateSpaceTemplateName({required this.name});
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object> get props => [name];
|
||||||
|
}
|
||||||
|
|
||||||
class AddSubspacesToSpaceTemplate extends CreateSpaceModelEvent {
|
class AddSubspacesToSpaceTemplate extends CreateSpaceModelEvent {
|
||||||
final List<SubspaceTemplateModel> subspaces;
|
final List<SubspaceTemplateModel> subspaces;
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import 'package:uuid/uuid.dart';
|
|||||||
|
|
||||||
class SpaceTemplateModel {
|
class SpaceTemplateModel {
|
||||||
final String? uuid;
|
final String? uuid;
|
||||||
final String modelName;
|
String modelName;
|
||||||
final List<SubspaceTemplateModel>? subspaceModels;
|
final List<SubspaceTemplateModel>? subspaceModels;
|
||||||
final List<TagModel>? tags;
|
final List<TagModel>? tags;
|
||||||
String internalId;
|
String internalId;
|
||||||
@ -35,15 +35,6 @@ class SpaceTemplateModel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return {
|
|
||||||
'uuid': uuid,
|
|
||||||
'modelName': modelName,
|
|
||||||
'subspaceModels': subspaceModels?.map((e) => e.toJson()).toList(),
|
|
||||||
'tags': tags?.map((e) => e.toJson()).toList(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
SpaceTemplateModel copyWith({
|
SpaceTemplateModel copyWith({
|
||||||
String? uuid,
|
String? uuid,
|
||||||
String? modelName,
|
String? modelName,
|
||||||
@ -59,6 +50,15 @@ class SpaceTemplateModel {
|
|||||||
internalId: internalId ?? this.internalId,
|
internalId: internalId ?? this.internalId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'uuid': uuid,
|
||||||
|
'modelName': modelName,
|
||||||
|
'subspaceModels': subspaceModels?.map((e) => e.toJson()).toList(),
|
||||||
|
'tags': tags?.map((e) => e.toJson()).toList(),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class UpdateSubspaceTemplateModel {
|
class UpdateSubspaceTemplateModel {
|
||||||
|
@ -4,6 +4,7 @@ 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/common/buttons/default_button.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/all_spaces/model/product_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart';
|
||||||
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_state.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_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/models/space_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart';
|
||||||
@ -17,13 +18,17 @@ import '../../models/subspace_template_model.dart';
|
|||||||
class CreateSpaceModelDialog extends StatelessWidget {
|
class CreateSpaceModelDialog extends StatelessWidget {
|
||||||
final List<ProductModel>? products;
|
final List<ProductModel>? products;
|
||||||
final List<String>? allTags;
|
final List<String>? allTags;
|
||||||
|
final SpaceTemplateModel? spaceModel;
|
||||||
|
|
||||||
const CreateSpaceModelDialog({Key? key, this.products, this.allTags}) : super(key: key);
|
const CreateSpaceModelDialog(
|
||||||
|
{Key? key, this.products, this.allTags, this.spaceModel})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
List<SubspaceTemplateModel>? subspaces = []; // Store subspaces here
|
List<SubspaceTemplateModel>? subspaces = [];
|
||||||
|
final TextEditingController spaceNameController = TextEditingController();
|
||||||
|
|
||||||
return AlertDialog(
|
return AlertDialog(
|
||||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||||
@ -33,6 +38,14 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
|||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (_) {
|
create: (_) {
|
||||||
final bloc = CreateSpaceModelBloc();
|
final bloc = CreateSpaceModelBloc();
|
||||||
|
if (spaceModel != null) {
|
||||||
|
bloc.add(UpdateSpaceTemplate(spaceModel!));
|
||||||
|
} else {
|
||||||
|
bloc.add(UpdateSpaceTemplate(SpaceTemplateModel(
|
||||||
|
modelName: '',
|
||||||
|
subspaceModels: [],
|
||||||
|
)));
|
||||||
|
}
|
||||||
return bloc;
|
return bloc;
|
||||||
},
|
},
|
||||||
child: BlocBuilder<CreateSpaceModelBloc, CreateSpaceModelState>(
|
child: BlocBuilder<CreateSpaceModelBloc, CreateSpaceModelState>(
|
||||||
@ -51,6 +64,7 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: screenWidth * 0.25,
|
width: screenWidth * 0.25,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
controller: spaceNameController,
|
||||||
style: const TextStyle(color: ColorsManager.blackColor),
|
style: const TextStyle(color: ColorsManager.blackColor),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
filled: true,
|
filled: true,
|
||||||
@ -81,12 +95,10 @@ class CreateSpaceModelDialog extends StatelessWidget {
|
|||||||
products: products,
|
products: products,
|
||||||
subspaces: subspaces,
|
subspaces: subspaces,
|
||||||
allTags: allTags,
|
allTags: allTags,
|
||||||
|
spaceName: spaceNameController.text,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (result == true) {
|
if (result == true) {}
|
||||||
// Handle the result if necessary
|
|
||||||
print('Devices added successfully');
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
style: TextButton.styleFrom(
|
style: TextButton.styleFrom(
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
|
@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_event.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_event.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/models/subspace_template_model.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/widgets/button_content_widget.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/subspace_model/views/create_subspace_model_dialog.dart';
|
import 'package:syncrow_web/pages/spaces_management/create_subspace_model/views/create_subspace_model_dialog.dart';
|
||||||
import 'package:syncrow_web/utils/color_manager.dart';
|
import 'package:syncrow_web/utils/color_manager.dart';
|
||||||
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart';
|
import 'package:syncrow_web/pages/spaces_management/space_model/bloc/create_space_model_bloc.dart';
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ class AddDeviceTypeModelWidget extends StatelessWidget {
|
|||||||
final List<SelectedProduct>? initialSelectedProducts;
|
final List<SelectedProduct>? initialSelectedProducts;
|
||||||
final List<SubspaceTemplateModel>? subspaces;
|
final List<SubspaceTemplateModel>? subspaces;
|
||||||
final List<String>? allTags;
|
final List<String>? allTags;
|
||||||
|
final String spaceName;
|
||||||
|
|
||||||
const AddDeviceTypeModelWidget(
|
const AddDeviceTypeModelWidget(
|
||||||
{super.key,
|
{super.key,
|
||||||
@ -23,7 +24,9 @@ class AddDeviceTypeModelWidget extends StatelessWidget {
|
|||||||
this.initialSelectedProducts,
|
this.initialSelectedProducts,
|
||||||
this.onProductsSelected,
|
this.onProductsSelected,
|
||||||
this.subspaces,
|
this.subspaces,
|
||||||
this.allTags});
|
this.allTags,
|
||||||
|
required this.spaceName
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -85,6 +88,7 @@ class AddDeviceTypeModelWidget extends StatelessWidget {
|
|||||||
subspaces: subspaces,
|
subspaces: subspaces,
|
||||||
addedProducts: currentState,
|
addedProducts: currentState,
|
||||||
allTags: allTags,
|
allTags: allTags,
|
||||||
|
spaceName: spaceName,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user