diff --git a/lib/bloc/rbac/rbac_bloc.dart b/lib/bloc/rbac/rbac_bloc.dart new file mode 100644 index 0000000..8d8287a --- /dev/null +++ b/lib/bloc/rbac/rbac_bloc.dart @@ -0,0 +1,45 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/rbac/permission.dart'; +import 'package:unit2/sevices/roles/rbac_services.dart'; + +import '../../model/rbac/new_permission.dart'; +import '../../model/rbac/rbac.dart'; + +part 'rbac_event.dart'; +part 'rbac_state.dart'; + +class RbacBloc extends Bloc { + + RbacBloc() : super(RbacInitial()) { + List? modules; + List? objects; + List? roles; + List? permissions; + List? operations; + on((event, emit) async { + emit(RbacLoadingState()); + try { + modules = await RbacServices.instance.getModules(); + objects = await RbacServices.instance.getObjects(); + roles = await RbacServices.instance.getRole(); + permissions = await RbacServices.instance.getPermission(); + operations = await RbacServices.instance.getOperations(); + emit(RbacScreenSetted(modules: modules!, objects: objects!, operations: operations!, permission: permissions!, role: roles!)); + } catch (e) { + emit(RbacErrorState(message: e.toString())); + } + });on((event, emit)async{ + try{ + emit(RbacLoadingState()); + Map responseStatus = await RbacServices.instance.assignRBAC(assigneeId: event.assigneeId, assignerId: event.assignerId, selectedRole: event.selectedRole, selectedModule: event.selectedModule, permissionId: event.permissionId, newPermissions: event.newPermissions); + emit(RbacAssignedState(responseStatus: responseStatus)); + }catch(e){ + emit(RbacErrorState(message: e.toString())); + } + }); + on((event,emit){ + emit(RbacScreenSetted(modules: modules!, objects: objects!, operations: operations!, permission: permissions!, role: roles!)); + }); + } +} diff --git a/lib/bloc/rbac/rbac_event.dart b/lib/bloc/rbac/rbac_event.dart new file mode 100644 index 0000000..4daa43e --- /dev/null +++ b/lib/bloc/rbac/rbac_event.dart @@ -0,0 +1,29 @@ +part of 'rbac_bloc.dart'; + +abstract class RbacEvent extends Equatable { + const RbacEvent(); + + @override + List get props => []; +} + +class SetRbacScreen extends RbacEvent {} + +class AssignedRbac extends RbacEvent { + final int assigneeId; + final int assignerId; + final RBAC? selectedRole; + final RBAC? selectedModule; + final List permissionId; + final List newPermissions; + const AssignedRbac( + {required this.assigneeId, + required this.assignerId, + required this.newPermissions, + required this.permissionId, + required this.selectedModule, + required this.selectedRole}); +} +class LoadRbac extends RbacEvent{ + +} diff --git a/lib/bloc/rbac/rbac_operations/agency/agency_bloc.dart b/lib/bloc/rbac/rbac_operations/agency/agency_bloc.dart new file mode 100644 index 0000000..de3cc89 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/agency/agency_bloc.dart @@ -0,0 +1,47 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/utils/profile_utilities.dart'; +import '../../../../model/utils/category.dart'; +import '../../../../sevices/roles/rbac_operations/agency_services.dart'; + +part 'agency_event.dart'; +part 'agency_state.dart'; + +class AgencyBloc extends Bloc { + AgencyBloc() : super(AgencyInitial()) { + List agencies = []; + List agencyCategory = []; + on((event, emit) async { + emit(AgencyLoadingState()); + try { + if (agencies.isEmpty) { + agencies = await AgencyServices.instance.getAgencies(); + } + if (agencyCategory.isEmpty) { + agencyCategory = await ProfileUtilities.instance.agencyCategory(); + } + emit( + AgenciesLoaded(agencies: agencies, agencyCategory: agencyCategory)); + } catch (e) { + emit(AgencyErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(AgencyLoadingState()); + try { + Map statusResponse = + await AgencyServices.instance.add(agency: event.agency); + if (statusResponse['success']) { + Agency newAgency = Agency.fromJson(statusResponse['data']); + agencies.add(newAgency); + emit(AgencyAddesState(response: statusResponse)); + } else { + emit(AgencyAddesState(response: statusResponse)); + } + } catch (e) { + emit(AgencyErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/agency/agency_event.dart b/lib/bloc/rbac/rbac_operations/agency/agency_event.dart new file mode 100644 index 0000000..8371eba --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/agency/agency_event.dart @@ -0,0 +1,16 @@ +part of 'agency_bloc.dart'; + +abstract class AgencyEvent extends Equatable { + const AgencyEvent(); + + @override + List get props => []; +} + +class GetAgencies extends AgencyEvent{ + +} +class AddAgency extends AgencyEvent{ + final Agency agency; + const AddAgency({required this.agency}); +} diff --git a/lib/bloc/rbac/rbac_operations/agency/agency_state.dart b/lib/bloc/rbac/rbac_operations/agency/agency_state.dart new file mode 100644 index 0000000..22aadcb --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/agency/agency_state.dart @@ -0,0 +1,33 @@ +part of 'agency_bloc.dart'; + +abstract class AgencyState extends Equatable { + const AgencyState(); + + @override + List get props => []; +} + +class AgenciesLoaded extends AgencyState { + final List agencies; + final List agencyCategory; + const AgenciesLoaded({required this.agencies, required this.agencyCategory}); +} + +class AgencyErrorState extends AgencyState { + final String message; + const AgencyErrorState({required this.message}); +} + +class AgencyLoadingState extends AgencyState {} + +class AgencyAddesState extends AgencyState { + final Map response; + const AgencyAddesState({required this.response}); +} + +class AgencyDeletedState extends AgencyState { + final bool success; + const AgencyDeletedState({required this.success}); +} + +class AgencyInitial extends AgencyState {} diff --git a/lib/bloc/rbac/rbac_operations/module/module_bloc.dart b/lib/bloc/rbac/rbac_operations/module/module_bloc.dart new file mode 100644 index 0000000..6586411 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/module/module_bloc.dart @@ -0,0 +1,84 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/sevices/roles/rbac_operations/module_services.dart'; +import '../../../../model/rbac/rbac.dart'; +part 'module_event.dart'; +part 'module_state.dart'; + +class ModuleBloc extends Bloc { + ModuleBloc() : super(ModuleInitial()) { + List modules = []; + on((event, emit) async { + emit(ModuleLoadingState()); + try { + if (modules.isEmpty) { + modules = await RbacModuleServices.instance.getRbacModule(); + } + + emit(ModuleLoaded(module: modules)); + } catch (e) { + emit(ModuleErrorState(message: e.toString())); + } + }); ////Add + on((event, emit) async { + try { + emit(ModuleLoadingState()); + Map statusResponse = await RbacModuleServices.instance + .add( + name: event.name!, + slug: event.slug, + short: event.shorthand, + id: event.id); + if (statusResponse['success']) { + RBAC newRole = RBAC.fromJson(statusResponse['data']); + modules.add(newRole); + emit(ModuleAddedState(response: statusResponse)); + } else { + emit(ModuleAddedState(response: statusResponse)); + } + } catch (e) { + emit(ModuleErrorState(message: e.toString())); + } + }); + ////update + on((event, emit) async { + emit(ModuleLoadingState()); + try { + Map statusResponse = await RbacModuleServices.instance + .update( + name: event.name, + slug: event.slug, + short: event.short, + moduleId: event.moduleId, + createdBy: event.createdBy, + updatedBy: event.updatedBy); + + if (statusResponse['success']) { + modules.removeWhere((element) => element.id == event.moduleId); + RBAC newRole = RBAC.fromJson(statusResponse['data']); + modules.add(newRole); + emit(ModuleUpdatedState(response: statusResponse)); + } else { + emit(ModuleUpdatedState(response: statusResponse)); + } + } catch (e) { + emit(ModuleErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(ModuleLoadingState()); + try { + bool success = await RbacModuleServices.instance + .deleteRbacModule(moduleId: event.moduleId); + if (success) { + modules.removeWhere((element) => element.id == event.moduleId); + emit(ModuleDeletedState(success: success)); + } else { + emit(ModuleDeletedState(success: success)); + } + } catch (e) { + emit(ModuleErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/module/module_event.dart b/lib/bloc/rbac/rbac_operations/module/module_event.dart new file mode 100644 index 0000000..53b9ed9 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/module/module_event.dart @@ -0,0 +1,48 @@ +part of 'module_bloc.dart'; + +abstract class ModuleEvent extends Equatable { + const ModuleEvent(); + + @override + List get props => []; +} + + +class GetModule extends ModuleEvent{ + +} + +class AddRbacModule extends ModuleEvent { + final String? name; + final String? slug; + final String? shorthand; + final int id; + const AddRbacModule( + {required this.id, + required this.name, + required this.shorthand, + required this.slug}); +} + + +class UpdateRbacModule extends ModuleEvent { + final int moduleId; + final String name; + final String? slug; + final String? short; + final int? createdBy; + final int updatedBy; + const UpdateRbacModule({ + required this.moduleId, + required this.createdBy, + required this.name, + required this.short, + required this.slug, + required this.updatedBy, + }); +} + +class DeleteRbacModule extends ModuleEvent { + final int moduleId; + const DeleteRbacModule({required this.moduleId}); +} \ No newline at end of file diff --git a/lib/bloc/rbac/rbac_operations/module/module_state.dart b/lib/bloc/rbac/rbac_operations/module/module_state.dart new file mode 100644 index 0000000..7dcde63 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/module/module_state.dart @@ -0,0 +1,36 @@ +part of 'module_bloc.dart'; + +abstract class ModuleState extends Equatable { + const ModuleState(); + + @override + List get props => []; +} + +class ModuleInitial extends ModuleState {} + +class ModuleLoaded extends ModuleState{ + final List module; + const ModuleLoaded({required this.module}); +} + +class ModuleLoadingState extends ModuleState{ + +} +class ModuleErrorState extends ModuleState{ + final String message; + const ModuleErrorState({required this.message}); +} + +class ModuleAddedState extends ModuleState { + final Map response; + const ModuleAddedState({required this.response}); +} +class ModuleUpdatedState extends ModuleState { + final Map response; + const ModuleUpdatedState({required this.response}); +} +class ModuleDeletedState extends ModuleState{ + final bool success; + const ModuleDeletedState({required this.success}); +} diff --git a/lib/bloc/rbac/rbac_operations/module_objects/module_objects_bloc.dart b/lib/bloc/rbac/rbac_operations/module_objects/module_objects_bloc.dart new file mode 100644 index 0000000..0892399 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/module_objects/module_objects_bloc.dart @@ -0,0 +1,76 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/login_data/user_info/module.dart'; +import 'package:unit2/model/rbac/rbac_rbac.dart'; +import 'package:unit2/sevices/roles/rbac_operations/module_objects_services.dart'; +import 'package:unit2/sevices/roles/rbac_operations/object_services.dart'; + +import '../../../../model/rbac/rbac.dart'; +import '../../../../sevices/roles/rbac_operations/module_services.dart'; +part 'module_objects_event.dart'; +part 'module_objects_state.dart'; + +class ModuleObjectsBloc extends Bloc { + ModuleObjectsBloc() : super(ModuleObjectsInitial()) { + List moduleObjects = []; + List objects = []; + List modules = []; + on((event, emit) async { + emit(ModuleObjectLoadingState()); + try { + if (moduleObjects.isEmpty) { + moduleObjects = + await RbacModuleObjectsServices.instance.getModuleObjects(); + } + if (objects.isEmpty) { + objects = await RbacObjectServices.instance.getRbacObjects(); + } + if (modules.isEmpty) { + modules = await RbacModuleServices.instance.getRbacModule(); + } + emit(ModuleObjectLoadedState( + moduleObjects: moduleObjects, objecs: objects, modules: modules)); + } catch (e) { + emit(ModuleObjectsErrorState(message: e.toString())); + } + }); + on((event, emit) async { + try { + emit(ModuleObjectLoadingState()); + Map statusResponse = + await RbacModuleObjectsServices.instance.add( + assignerId: event.assignerId, + moduleId: event.moduleId, + objectsId: event.objectsId); + + if (statusResponse['success']) { + statusResponse['data'].forEach((var permission) { + ModuleObjects newModuleObject = ModuleObjects.fromJson(permission); + moduleObjects.add(newModuleObject); + emit(ModuleObjectAddedState(response: statusResponse)); + }); + } else { + emit(ModuleObjectAddedState(response: statusResponse)); + } + } catch (e) { + emit(ModuleObjectsErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(ModuleObjectLoadingState()); + try { + bool success = await RbacModuleObjectsServices.instance + .deleteRbacModuleObject(moduleObjectId: event.moduleObjectId); + if (success) { + moduleObjects + .removeWhere((element) => element.id == event.moduleObjectId); + emit(ModuleObjectDeletedState(success: success)); + } else { + emit(ModuleObjectDeletedState(success: success)); + } + } catch (e) { + emit(ModuleObjectsErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/module_objects/module_objects_event.dart b/lib/bloc/rbac/rbac_operations/module_objects/module_objects_event.dart new file mode 100644 index 0000000..65d9e89 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/module_objects/module_objects_event.dart @@ -0,0 +1,26 @@ +part of 'module_objects_bloc.dart'; + +abstract class ModuleObjectsEvent extends Equatable { + const ModuleObjectsEvent(); + + @override + List get props => []; +} + +class GetModuleObjects extends ModuleObjectsEvent {} + +class DeleteRbacModuleObject extends ModuleObjectsEvent { + final int moduleObjectId; + const DeleteRbacModuleObject({required this.moduleObjectId}); +} + +class AddRbacModuleObjects extends ModuleObjectsEvent { + final int moduleId; + final List objectsId; + final int assignerId; + const AddRbacModuleObjects( + {required this.assignerId, + required this.moduleId, + required this.objectsId}); +} + diff --git a/lib/bloc/rbac/rbac_operations/module_objects/module_objects_state.dart b/lib/bloc/rbac/rbac_operations/module_objects/module_objects_state.dart new file mode 100644 index 0000000..9028df0 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/module_objects/module_objects_state.dart @@ -0,0 +1,37 @@ +part of 'module_objects_bloc.dart'; + +abstract class ModuleObjectsState extends Equatable { + const ModuleObjectsState(); + + @override + List get props => []; +} + +class ModuleObjectsInitial extends ModuleObjectsState {} + +class ModuleObjectLoadedState extends ModuleObjectsState { + final List moduleObjects; + final List objecs; + final List modules; + const ModuleObjectLoadedState( + {required this.moduleObjects, + required this.modules, + required this.objecs}); +} + +class ModuleObjectsErrorState extends ModuleObjectsState { + final String message; + const ModuleObjectsErrorState({required this.message}); +} + +class ModuleObjectLoadingState extends ModuleObjectsState {} + +class ModuleObjectAddedState extends ModuleObjectsState { + final Map response; + const ModuleObjectAddedState({required this.response}); +} + +class ModuleObjectDeletedState extends ModuleObjectsState { + final bool success; + const ModuleObjectDeletedState({required this.success}); +} diff --git a/lib/bloc/rbac/rbac_operations/object/object_bloc.dart b/lib/bloc/rbac/rbac_operations/object/object_bloc.dart new file mode 100644 index 0000000..024aa4d --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/object/object_bloc.dart @@ -0,0 +1,87 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/sevices/roles/rbac_operations/object_services.dart'; + +import '../../../../model/rbac/rbac.dart'; + +part 'object_event.dart'; +part 'object_state.dart'; + +class ObjectBloc extends Bloc { + ObjectBloc() : super(ObjectInitial()) { + List objects = []; + on((event, emit) async { + emit(ObjectLoadingState()); + try { + if (objects.isEmpty) { + objects = await RbacObjectServices.instance.getRbacObjects(); + } + emit(ObjectLoaded(objects: objects)); + } catch (e) { + emit(ObjectErrorState(message: e.toString())); + } + }); + ////Add + on((event, emit) async { + try { + emit(ObjectLoadingState()); + Map statusResponse = await RbacObjectServices.instance + .add( + name: event.name!, + slug: event.slug, + short: event.shorthand, + id: event.id); + if (statusResponse['success']) { + RBAC newObject = RBAC.fromJson(statusResponse['data']); + objects.add(newObject); + emit(ObjectAddedState(response: statusResponse)); + } else { + emit(ObjectAddedState(response: statusResponse)); + } + } catch (e) { + emit(ObjectErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(ObjectLoadingState()); + try { + Map statusResponse = await RbacObjectServices.instance + .update( + name: event.name, + slug: event.slug, + short: event.short, + objectId: event.objectId, + createdBy: event.createdBy, + updatedBy: event.updatedBy); + + if (statusResponse['success']) { + objects.removeWhere((element) => element.id == event.objectId); + RBAC newObject = RBAC.fromJson(statusResponse['data']); + objects.add(newObject); + emit(ObjectUpdatedState(response: statusResponse)); + } else { + emit(ObjectUpdatedState(response: statusResponse)); + } + } catch (e) { + emit(ObjectErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(ObjectLoadingState()); + try { + bool success = await RbacObjectServices.instance + .deleteRbacRole(objectId: event.objectId); + if (success) { + objects.removeWhere((element) => element.id == event.objectId); + emit(ObjectDeletedState(success: success)); + } else { + emit(ObjectDeletedState(success: success)); + } + } catch (e) { + emit(ObjectErrorState(message: e.toString())); + } + }); + } + } + + diff --git a/lib/bloc/rbac/rbac_operations/object/object_event.dart b/lib/bloc/rbac/rbac_operations/object/object_event.dart new file mode 100644 index 0000000..a654e0d --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/object/object_event.dart @@ -0,0 +1,46 @@ +part of 'object_bloc.dart'; + +abstract class ObjectEvent extends Equatable { + const ObjectEvent(); + + @override + List get props => []; +} + +class GetObjects extends ObjectEvent{ + +} +class AddRbacObject extends ObjectEvent { + final String? name; + final String? slug; + final String? shorthand; + final int id; + const AddRbacObject( + {required this.id, + required this.name, + required this.shorthand, + required this.slug}); +} + + +class UpdateRbacObject extends ObjectEvent { + final int objectId; + final String name; + final String? slug; + final String? short; + final int? createdBy; + final int updatedBy; + const UpdateRbacObject({ + required this.objectId, + required this.createdBy, + required this.name, + required this.short, + required this.slug, + required this.updatedBy, + }); +} + +class DeleteRbacObject extends ObjectEvent { + final int objectId; + const DeleteRbacObject({required this.objectId}); +} diff --git a/lib/bloc/rbac/rbac_operations/object/object_state.dart b/lib/bloc/rbac/rbac_operations/object/object_state.dart new file mode 100644 index 0000000..1c45114 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/object/object_state.dart @@ -0,0 +1,36 @@ +part of 'object_bloc.dart'; + +abstract class ObjectState extends Equatable { + const ObjectState(); + + @override + List get props => []; +} + +class ObjectInitial extends ObjectState {} + +class ObjectLoaded extends ObjectState{ + final List objects; + const ObjectLoaded({required this.objects}); +} + +class ObjectLoadingState extends ObjectState{ + +} + +class ObjectErrorState extends ObjectState{ + final String message; + const ObjectErrorState({required this.message}); +} +class ObjectAddedState extends ObjectState { + final Map response; + const ObjectAddedState({required this.response}); +} +class ObjectUpdatedState extends ObjectState { + final Map response; + const ObjectUpdatedState({required this.response}); +} +class ObjectDeletedState extends ObjectState{ + final bool success; + const ObjectDeletedState({required this.success}); +} \ No newline at end of file diff --git a/lib/bloc/rbac/rbac_operations/operation/operation_bloc.dart b/lib/bloc/rbac/rbac_operations/operation/operation_bloc.dart new file mode 100644 index 0000000..5dcf5e8 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/operation/operation_bloc.dart @@ -0,0 +1,84 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/sevices/roles/rbac_operations/operation_services.dart'; + +part 'operation_event.dart'; +part 'operation_state.dart'; + +class OperationBloc extends Bloc { + OperationBloc() : super(OperationInitial()) { + List operations = []; + on((event, emit) async { + emit(OperationLoadingState()); + try { + if (operations.isEmpty) { + operations = await RbacOperationServices.instance.getRbacOperations(); + } + + emit(OperationsLoaded(operations: operations)); + } catch (e) { + emit(OperationErrorState(message: e.toString())); + } + }); + on((event, emit) async { + try { + emit(OperationLoadingState()); + Map statusResponse = + await RbacOperationServices.instance.add( + name: event.name!, + slug: event.slug, + short: event.shorthand, + id: event.id); + if (statusResponse['success']) { + RBAC newOperation = RBAC.fromJson(statusResponse['data']); + operations.add(newOperation); + emit(OperationAddedState(response: statusResponse)); + } else { + emit(OperationAddedState(response: statusResponse)); + } + } catch (e) { + emit(OperationErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(OperationLoadingState()); + try { + Map statusResponse = + await RbacOperationServices.instance.update( + name: event.name, + slug: event.slug, + short: event.short, + operationId: event.operationId, + createdBy: event.createdBy, + updatedBy: event.updatedBy); + + if (statusResponse['success']) { + operations.removeWhere((element) => element.id == event.operationId); + RBAC newRole = RBAC.fromJson(statusResponse['data']); + operations.add(newRole); + emit(OperationUpdatedState(response: statusResponse)); + } else { + emit(OperationUpdatedState(response: statusResponse)); + } + } catch (e) { + emit(OperationErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(OperationLoadingState()); + try { + bool success = await RbacOperationServices.instance + .delete(operation: event.operationId); + if (success) { + operations.removeWhere((element) => element.id == event.operationId); + emit(OperationDeletedState(success: success)); + } else { + emit(OperationDeletedState(success: success)); + } + } catch (e) { + emit(OperationErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/operation/operation_event.dart b/lib/bloc/rbac/rbac_operations/operation/operation_event.dart new file mode 100644 index 0000000..35bd990 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/operation/operation_event.dart @@ -0,0 +1,45 @@ +part of 'operation_bloc.dart'; + +abstract class OperationEvent extends Equatable { + const OperationEvent(); + + @override + List get props => []; +} +class GetOperations extends OperationEvent{ + +} +class AddRbacOperation extends OperationEvent { + final String? name; + final String? slug; + final String? shorthand; + final int id; + const AddRbacOperation( + {required this.id, + required this.name, + required this.shorthand, + required this.slug}); +} + + +class UpdateRbacOperation extends OperationEvent { + final int operationId; + final String name; + final String? slug; + final String? short; + final int? createdBy; + final int updatedBy; + const UpdateRbacOperation({ + required this.operationId, + required this.createdBy, + required this.name, + required this.short, + required this.slug, + required this.updatedBy, + }); +} + +class DeleteRbacOperation extends OperationEvent { + final int operationId; + const DeleteRbacOperation({required this.operationId}); +} diff --git a/lib/bloc/rbac/rbac_operations/operation/operation_state.dart b/lib/bloc/rbac/rbac_operations/operation/operation_state.dart new file mode 100644 index 0000000..4490f67 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/operation/operation_state.dart @@ -0,0 +1,34 @@ +part of 'operation_bloc.dart'; + +abstract class OperationState extends Equatable { + const OperationState(); + + @override + List get props => []; +} + +class OperationInitial extends OperationState {} + +class OperationsLoaded extends OperationState { + final List operations; + const OperationsLoaded({required this.operations}); +} + +class OperationLoadingState extends OperationState {} + +class OperationErrorState extends OperationState { + final String message; + const OperationErrorState({required this.message}); +} +class OperationAddedState extends OperationState { + final Map response; + const OperationAddedState({required this.response}); +} +class OperationUpdatedState extends OperationState { + final Map response; + const OperationUpdatedState({required this.response}); +} +class OperationDeletedState extends OperationState{ + final bool success; + const OperationDeletedState({required this.success}); +} diff --git a/lib/bloc/rbac/rbac_operations/permission/permission_bloc.dart b/lib/bloc/rbac/rbac_operations/permission/permission_bloc.dart new file mode 100644 index 0000000..fe14035 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/permission/permission_bloc.dart @@ -0,0 +1,81 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/rbac/permission.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/screens/unit2/roles/rbac/add_rbac.dart'; +import 'package:unit2/sevices/roles/rbac_operations/permission_service.dart'; + +import '../../../../sevices/roles/rbac_operations/object_services.dart'; +import '../../../../sevices/roles/rbac_operations/operation_services.dart'; + +part 'permission_event.dart'; +part 'permission_state.dart'; + +class PermissionBloc extends Bloc { + PermissionBloc() : super(PermissionInitial()) { + List permissions = []; + List objects = []; + List operations = []; + on((event, emit) async { + try { + emit(PermissonLoadingState()); + if (permissions.isEmpty) { + permissions = + await RbacPermissionServices.instance.getRbacPermission(); + } + if (objects.isEmpty) { + objects = await RbacObjectServices.instance.getRbacObjects(); + } + if (operations.isEmpty) { + operations = await RbacOperationServices.instance.getRbacOperations(); + } + emit(PermissionLoaded( + permissions: permissions, + objects: objects, + operations: operations)); + } catch (e) { + emit(PermissionErrorState(message: e.toString())); + } + }); + ////Add + on((event, emit) async { + try { + emit(PermissonLoadingState()); + Map statusResponse = + await RbacPermissionServices.instance.add( + assignerId: event.assignerId, + objectId: event.objectId, + operationsId: event.operationIds); + if (statusResponse['success']) { + statusResponse['data'].forEach((var permission) { + RBACPermission newPermission = RBACPermission.fromJson(permission); + permissions.add(newPermission); + }); + + emit(PermissionAddedState(response: statusResponse)); + } else { + emit(PermissionAddedState(response: statusResponse)); + } + } catch (e) { + emit(PermissionErrorState(message: e.toString())); + } + }); + ////Delete + on((event, emit) async { + emit(PermissonLoadingState()); + try { + bool success = await RbacPermissionServices.instance + .deletePermission(permissionId: event.permissionId); + if (success) { + permissions + .removeWhere((element) => element.id == event.permissionId); + emit(PermissionDeletedState(success: success)); + } else { + emit(PermissionDeletedState(success: success)); + } + } catch (e) { + emit(PermissionErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/permission/permission_event.dart b/lib/bloc/rbac/rbac_operations/permission/permission_event.dart new file mode 100644 index 0000000..c1c2cc3 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/permission/permission_event.dart @@ -0,0 +1,25 @@ +part of 'permission_bloc.dart'; + +abstract class PermissionEvent extends Equatable { + const PermissionEvent(); + + @override + List get props => []; +} + +class GetPermissions extends PermissionEvent {} + +class AddRbacPermission extends PermissionEvent { + final int objectId; + final List operationIds; + final int assignerId; + const AddRbacPermission( + {required this.assignerId, + required this.objectId, + required this.operationIds}); +} + +class DeleteRbacPermission extends PermissionEvent { + final int permissionId; + const DeleteRbacPermission({required this.permissionId}); +} diff --git a/lib/bloc/rbac/rbac_operations/permission/permission_state.dart b/lib/bloc/rbac/rbac_operations/permission/permission_state.dart new file mode 100644 index 0000000..c8d2487 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/permission/permission_state.dart @@ -0,0 +1,37 @@ +part of 'permission_bloc.dart'; + +abstract class PermissionState extends Equatable { + const PermissionState(); + + @override + List get props => []; +} + +class PermissionInitial extends PermissionState {} + +class PermissionLoaded extends PermissionState { + final List permissions; + final List objects; + final List operations; + const PermissionLoaded( + {required this.permissions, + required this.objects, + required this.operations}); +} + +class PermissionAddedState extends PermissionState { + final Map response; + const PermissionAddedState({required this.response}); +} + +class PermissonLoadingState extends PermissionState {} + +class PermissionErrorState extends PermissionState { + final String message; + const PermissionErrorState({required this.message}); +} + +class PermissionDeletedState extends PermissionState { + final bool success; + const PermissionDeletedState({required this.success}); +} diff --git a/lib/bloc/rbac/rbac_operations/role/role_bloc.dart b/lib/bloc/rbac/rbac_operations/role/role_bloc.dart new file mode 100644 index 0000000..5f9980b --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role/role_bloc.dart @@ -0,0 +1,83 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/sevices/roles/rbac_operations/role_services.dart'; +part 'role_event.dart'; +part 'role_state.dart'; + +class RoleBloc extends Bloc { + RoleBloc() : super(RoleInitial()) { + List roles = []; + on((event, emit) async { + try { + emit(RoleLoadingState()); + if (roles.isEmpty) { + roles = await RbacRoleServices.instance.getRbacRoles(); + } + emit(RoleLoadedState(roles: roles)); + } catch (e) { + emit(RoleErrorState(message: e.toString())); + } + ////Add + }); + on((event, emit) async { + try { + emit(RoleLoadingState()); + Map statusResponse = await RbacRoleServices.instance + .add( + name: event.name!, + slug: event.slug, + short: event.shorthand, + id: event.id); + if (statusResponse['success']) { + RBAC newRole = RBAC.fromJson(statusResponse['data']); + roles.add(newRole); + emit(RoleAddedState(response: statusResponse)); + } else { + emit(RoleAddedState(response: statusResponse)); + } + } catch (e) { + emit(RoleErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(RoleLoadingState()); + try { + Map statusResponse = await RbacRoleServices.instance + .update( + name: event.name, + slug: event.slug, + short: event.short, + roleId: event.roleId, + createdBy: event.createdBy, + updatedBy: event.updatedBy); + + if (statusResponse['success']) { + roles.removeWhere((element) => element.id == event.roleId); + RBAC newRole = RBAC.fromJson(statusResponse['data']); + roles.add(newRole); + emit(RoleUpdatedState(response: statusResponse)); + } else { + emit(RoleUpdatedState(response: statusResponse)); + } + } catch (e) { + emit(RoleErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(RoleLoadingState()); + try { + bool success = await RbacRoleServices.instance + .deleteRbacRole(roleId: event.roleId); + if (success) { + roles.removeWhere((element) => element.id == event.roleId); + emit(RoleDeletedState(success: success)); + } else { + emit(RoleDeletedState(success: success)); + } + } catch (e) { + emit(RoleErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/role/role_event.dart b/lib/bloc/rbac/rbac_operations/role/role_event.dart new file mode 100644 index 0000000..60987d9 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role/role_event.dart @@ -0,0 +1,45 @@ +part of 'role_bloc.dart'; + +abstract class RoleEvent extends Equatable { + const RoleEvent(); + + @override + List get props => []; +} + +class GetRoles extends RoleEvent {} + +class AddRbacRole extends RoleEvent { + final String? name; + final String? slug; + final String? shorthand; + final int id; + const AddRbacRole( + {required this.id, + required this.name, + required this.shorthand, + required this.slug}); +} + + +class UpdateRbacRole extends RoleEvent { + final int roleId; + final String name; + final String? slug; + final String? short; + final int? createdBy; + final int updatedBy; + const UpdateRbacRole({ + required this.roleId, + required this.createdBy, + required this.name, + required this.short, + required this.slug, + required this.updatedBy, + }); +} + +class DeleteRbacRole extends RoleEvent { + final int roleId; + const DeleteRbacRole({required this.roleId}); +} diff --git a/lib/bloc/rbac/rbac_operations/role/role_state.dart b/lib/bloc/rbac/rbac_operations/role/role_state.dart new file mode 100644 index 0000000..255ce6e --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role/role_state.dart @@ -0,0 +1,37 @@ +part of 'role_bloc.dart'; + +abstract class RoleState extends Equatable { + const RoleState(); + + @override + List get props => []; +} + +class RoleInitial extends RoleState {} + +class RoleLoadedState extends RoleState { + final List roles; + const RoleLoadedState({required this.roles}); +} + +class RoleLoadingState extends RoleState {} + +class RoleErrorState extends RoleState { + final String message; + const RoleErrorState({required this.message}); +} + +class RoleAddedState extends RoleState { + final Map response; + const RoleAddedState({required this.response}); +} +class RoleUpdatedState extends RoleState { + final Map response; + const RoleUpdatedState({required this.response}); +} +class RoleDeletedState extends RoleState{ + final bool success; + const RoleDeletedState({required this.success}); +} + + diff --git a/lib/bloc/rbac/rbac_operations/role_extend/role_extend_bloc.dart b/lib/bloc/rbac/rbac_operations/role_extend/role_extend_bloc.dart new file mode 100644 index 0000000..f4c75d8 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role_extend/role_extend_bloc.dart @@ -0,0 +1,75 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/roles_under/roles_under_bloc.dart'; +import 'package:unit2/model/rbac/role_extend.dart'; +import 'package:unit2/sevices/roles/rbac_operations/role_extend_services.dart'; + +import '../../../../model/rbac/rbac.dart'; +import '../../../../sevices/roles/rbac_operations/role_services.dart'; + +part 'role_extend_event.dart'; +part 'role_extend_state.dart'; + +class RoleExtendBloc extends Bloc { + RoleExtendBloc() : super(RoleExtendInitial()) { + List rolesExtend = []; + List roleExtendIds = []; + List roles = []; + on((event, emit) async { + emit(RoleExtendLoadingState()); + try { + if (rolesExtend.isEmpty) { + rolesExtend = await RbacRoleExtendServices.instance.getRolesExtend(); + } + + if (roles.isEmpty) { + roles = await RbacRoleServices.instance.getRbacRoles(); + } + for (var roleExt in rolesExtend) { + roleExtendIds.add(roleExt.id); + } + emit(RoleExtendLoadedState(rolesExtend: rolesExtend, roles: roles)); + } catch (e) { + emit(RoleExtendErrorState(message: e.toString())); + } + }); + on((event, emit) async { + try { + emit(RoleExtendLoadingState()); + Map statusResponse = await RbacRoleExtendServices + .instance + .add(roleId: event.roleId, rolesExtendsId: event.roleExtendsId); + + if (statusResponse['success']) { + statusResponse['data'].forEach((var roleExt) { + RolesExtend newRoleExtend = RolesExtend.fromJson(roleExt); + if(!roleExtendIds.contains(newRoleExtend.id)){ + rolesExtend.add(newRoleExtend); + } + }); + emit(RoleExtendAddedState(response: statusResponse)); + } else { + emit(RoleExtendAddedState(response: statusResponse)); + } + } catch (e) { + emit(RoleExtendErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(RoleExtendLoadingState()); + try { + bool success = await RbacRoleExtendServices.instance + .delete(roleExtendId: event.roleExtendId); + if (success) { + rolesExtend + .removeWhere((element) => element.id == event.roleExtendId); + emit(RoleExtendDeletedState(success: success)); + } else { + emit(RoleExtendDeletedState(success: success)); + } + } catch (e) { + emit(RoleExtendErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/role_extend/role_extend_event.dart b/lib/bloc/rbac/rbac_operations/role_extend/role_extend_event.dart new file mode 100644 index 0000000..c0b4637 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role_extend/role_extend_event.dart @@ -0,0 +1,21 @@ +part of 'role_extend_bloc.dart'; + +abstract class RoleExtendEvent extends Equatable { + const RoleExtendEvent(); + + @override + List get props => []; +} + +class GetRoleExtend extends RoleExtendEvent {} + +class DeleteRoleExtend extends RoleExtendEvent { + final int roleExtendId; + const DeleteRoleExtend({required this.roleExtendId}); +} + +class AddRoleExtend extends RoleExtendEvent { + final int roleId; + final List roleExtendsId; + const AddRoleExtend({required this.roleId, required this.roleExtendsId}); +} diff --git a/lib/bloc/rbac/rbac_operations/role_extend/role_extend_state.dart b/lib/bloc/rbac/rbac_operations/role_extend/role_extend_state.dart new file mode 100644 index 0000000..8e788cb --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role_extend/role_extend_state.dart @@ -0,0 +1,34 @@ +part of 'role_extend_bloc.dart'; + +abstract class RoleExtendState extends Equatable { + const RoleExtendState(); + + @override + List get props => []; +} + +class RoleExtendInitial extends RoleExtendState {} + +class RoleExtendLoadedState extends RoleExtendState { + final List rolesExtend; + final List roles; + + const RoleExtendLoadedState({required this.rolesExtend, required this.roles}); +} + +class RoleExtendLoadingState extends RoleExtendState {} + +class RoleExtendErrorState extends RoleExtendState { + final String message; + const RoleExtendErrorState({required this.message}); +} + +class RoleExtendAddedState extends RoleExtendState { + final Map response; + const RoleExtendAddedState({required this.response}); +} + +class RoleExtendDeletedState extends RoleExtendState { + final bool success; + const RoleExtendDeletedState({required this.success}); +} diff --git a/lib/bloc/rbac/rbac_operations/role_module/role_module_bloc.dart b/lib/bloc/rbac/rbac_operations/role_module/role_module_bloc.dart new file mode 100644 index 0000000..3f52bd4 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role_module/role_module_bloc.dart @@ -0,0 +1,72 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/sevices/roles/rbac_operations/role_module_services.dart'; +import 'package:unit2/sevices/roles/rbac_operations/role_services.dart'; +import '../../../../model/rbac/role_module.dart'; +import '../../../../sevices/roles/rbac_operations/module_services.dart'; +part 'role_module_event.dart'; +part 'role_module_state.dart'; + +class RoleModuleBloc extends Bloc { + RoleModuleBloc() : super(RoleModuleInitial()) { + List roleModules = []; + List roles = []; + List modules = []; + on((event, emit) async { + emit(RoleModuleLoadingState()); + try { + if (roleModules.isEmpty) { + roleModules = await RbacRoleModuleServices.instance.getRoleModules(); + } + if (modules.isEmpty) { + modules = await RbacModuleServices.instance.getRbacModule(); + } + if (roles.isEmpty) { + roles = await RbacRoleServices.instance.getRbacRoles(); + } + emit(RoleModuleLoadedState(roleModules: roleModules,modules: modules,roles: roles)); + } catch (e) { + emit(RoleModuleErrorState(message: e.toString())); + } + }); + on((event, emit) async { + try { + emit(RoleModuleLoadingState()); + Map statusResponse = + await RbacRoleModuleServices.instance.add( + assignerId: event.assignerId, + roleId: event.roleId, + moduleIds: event.moduleIds); + + if (statusResponse['success']) { + statusResponse['data'].forEach((var roleMod) { + RoleModules newRoleModule = RoleModules.fromJson(roleMod); + roleModules.add(newRoleModule); + emit(RoleModuleAddedState(response: statusResponse)); + }); + } else { + emit(RoleModuleAddedState(response: statusResponse)); + } + } catch (e) { + emit(RoleModuleErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(RoleModuleLoadingState()); + try { + bool success = await RbacRoleModuleServices.instance + .deleteRbacRoleModule(moduleObjectId: event.roleModuleId); + if (success) { + roleModules + .removeWhere((element) => element.id == event.roleModuleId); + emit(RoleModuleDeletedState(success: success)); + } else { + RoleModuleDeletedState(success: success); + } + } catch (e) { + emit(RoleModuleErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/role_module/role_module_event.dart b/lib/bloc/rbac/rbac_operations/role_module/role_module_event.dart new file mode 100644 index 0000000..b0cfa8a --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role_module/role_module_event.dart @@ -0,0 +1,25 @@ +part of 'role_module_bloc.dart'; + +abstract class RoleModuleEvent extends Equatable { + const RoleModuleEvent(); + + @override + List get props => []; +} + +class GetRoleModules extends RoleModuleEvent {} + +class DeleteRoleModule extends RoleModuleEvent { + final int roleModuleId; + const DeleteRoleModule({required this.roleModuleId}); +} + +class AddRoleModule extends RoleModuleEvent { + final int roleId; + final List moduleIds; + final int assignerId; + const AddRoleModule( + {required this.assignerId, + required this.roleId, + required this.moduleIds}); +} diff --git a/lib/bloc/rbac/rbac_operations/role_module/role_module_state.dart b/lib/bloc/rbac/rbac_operations/role_module/role_module_state.dart new file mode 100644 index 0000000..733d56c --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/role_module/role_module_state.dart @@ -0,0 +1,36 @@ +part of 'role_module_bloc.dart'; + +abstract class RoleModuleState extends Equatable { + const RoleModuleState(); + + @override + List get props => []; +} + +class RoleModuleInitial extends RoleModuleState {} + +class RoleModuleLoadedState extends RoleModuleState { + final List roleModules; + final List roles; + final List modules; + + const RoleModuleLoadedState( + {required this.roleModules, required this.modules, required this.roles}); +} + +class RoleModuleLoadingState extends RoleModuleState {} + +class RoleModuleErrorState extends RoleModuleState { + final String message; + const RoleModuleErrorState({required this.message}); +} + +class RoleModuleAddedState extends RoleModuleState { + final Map response; + const RoleModuleAddedState({required this.response}); +} + +class RoleModuleDeletedState extends RoleModuleState { + final bool success; + const RoleModuleDeletedState({required this.success}); +} diff --git a/lib/bloc/rbac/rbac_operations/roles_under/roles_under_bloc.dart b/lib/bloc/rbac/rbac_operations/roles_under/roles_under_bloc.dart new file mode 100644 index 0000000..f8fc508 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/roles_under/roles_under_bloc.dart @@ -0,0 +1,67 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/rbac/role_under.dart'; +import 'package:unit2/sevices/roles/rbac_operations/roles_under_services.dart'; + +import '../../../../model/rbac/rbac.dart'; +import '../../../../sevices/roles/rbac_operations/role_services.dart'; + +part 'roles_under_event.dart'; +part 'roles_under_state.dart'; + +class RolesUnderBloc extends Bloc { + RolesUnderBloc() : super(RolesUnderInitial()) { + List rolesUnder = []; + List roles = []; + on((event, emit) async { + emit(RoleUnderLoadingState()); + try { + if (rolesUnder.isEmpty) { + rolesUnder = await RbacRoleUnderServices.instance.getRolesUnder(); + } + + if (roles.isEmpty) { + roles = await RbacRoleServices.instance.getRbacRoles(); + } + emit(RoleUnderLoadedState(rolesUnder: rolesUnder, roles: roles)); + } catch (e) { + emit(RoleUnderErrorState(message: e.toString())); + } + }); + on((event, emit) async { + try { + emit(RoleUnderLoadingState()); + Map statusResponse = await RbacRoleUnderServices + .instance + .add(roleId: event.roleId, rolesId: event.roleUnderIds); + + if (statusResponse['success']) { + statusResponse['data'].forEach((var roleMod) { + RolesUnder newRoleUnder = RolesUnder.fromJson(roleMod); + rolesUnder.add(newRoleUnder); + emit(RoleUnderAddedState(response: statusResponse)); + }); + } else { + emit(RoleUnderAddedState(response: statusResponse)); + } + } catch (e) { + emit(RoleUnderErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(RoleUnderLoadingState()); + try { + bool success = await RbacRoleUnderServices.instance + .deleteRbacRoleUnder(roleUnderId: event.roleUnderId); + if (success) { + rolesUnder.removeWhere((element) => element.id == event.roleUnderId); + emit(RoleUnderDeletedState(success: success)); + } else { + emit(RoleUnderDeletedState(success: success)); + } + } catch (e) { + emit(RoleUnderErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/roles_under/roles_under_event.dart b/lib/bloc/rbac/rbac_operations/roles_under/roles_under_event.dart new file mode 100644 index 0000000..3c17f46 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/roles_under/roles_under_event.dart @@ -0,0 +1,21 @@ +part of 'roles_under_bloc.dart'; + +abstract class RolesUnderEvent extends Equatable { + const RolesUnderEvent(); + + @override + List get props => []; +} + +class GetRolesUnder extends RolesUnderEvent {} + +class DeleteRoleUnder extends RolesUnderEvent { + final int roleUnderId; + const DeleteRoleUnder({required this.roleUnderId}); +} + +class AddRoleUnder extends RolesUnderEvent{ + final int roleId; + final List roleUnderIds; + const AddRoleUnder({required this.roleId, required this.roleUnderIds}); +} diff --git a/lib/bloc/rbac/rbac_operations/roles_under/roles_under_state.dart b/lib/bloc/rbac/rbac_operations/roles_under/roles_under_state.dart new file mode 100644 index 0000000..0263414 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/roles_under/roles_under_state.dart @@ -0,0 +1,34 @@ +part of 'roles_under_bloc.dart'; + +abstract class RolesUnderState extends Equatable { + const RolesUnderState(); + + @override + List get props => []; +} + +class RolesUnderInitial extends RolesUnderState {} + +class RoleUnderLoadedState extends RolesUnderState { + final List rolesUnder; + final List roles; + + const RoleUnderLoadedState({required this.rolesUnder, required this.roles}); +} + +class RoleUnderLoadingState extends RolesUnderState {} + +class RoleUnderErrorState extends RolesUnderState { + final String message; + const RoleUnderErrorState({required this.message}); +} + +class RoleUnderAddedState extends RolesUnderState { + final Map response; + const RoleUnderAddedState({required this.response}); +} + +class RoleUnderDeletedState extends RolesUnderState { + final bool success; + const RoleUnderDeletedState({required this.success}); +} diff --git a/lib/bloc/rbac/rbac_operations/station/station_bloc.dart b/lib/bloc/rbac/rbac_operations/station/station_bloc.dart new file mode 100644 index 0000000..2dec814 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/station/station_bloc.dart @@ -0,0 +1,47 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/model/rbac/rbac_station.dart'; +import 'package:unit2/sevices/roles/rbac_operations/station_services.dart'; +import '../../../../model/utils/agency.dart'; +import '../../../../utils/profile_utilities.dart'; +part 'station_event.dart'; +part 'station_state.dart'; + +class StationBloc extends Bloc { + StationBloc() : super(StationInitial()) { + List stations = []; + List agencies = []; + on((event, emit) async { + emit(StationLoadingState()); + try { + stations = await RbacStationServices.instance + .getStations(agencyId: event.agencyId); + + if (agencies.isEmpty) { + List newAgencies = + await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + emit(StationLoadedState(stations: stations, agencies: agencies)); + } catch (e) { + emit(StationErrorState(message: e.toString())); + } + }); + on((event, emit)async { + // emit(StationLoadingState()); + try { + stations = await RbacStationServices.instance + .getStations(agencyId: event.agencyId); + + if (agencies.isEmpty) { + List newAgencies = + await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + emit(StationLoadedState(stations: stations, agencies: agencies)); + } catch (e) { + emit(StationErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/rbac/rbac_operations/station/station_event.dart b/lib/bloc/rbac/rbac_operations/station/station_event.dart new file mode 100644 index 0000000..ea2c989 --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/station/station_event.dart @@ -0,0 +1,18 @@ +part of 'station_bloc.dart'; + +abstract class StationEvent extends Equatable { + const StationEvent(); + + @override + List get props => []; +} + +class GetStations extends StationEvent { + final int agencyId; + const GetStations({required this.agencyId}); +} + +class FilterStation extends StationEvent { + final int agencyId; + const FilterStation({required this.agencyId}); +} diff --git a/lib/bloc/rbac/rbac_operations/station/station_state.dart b/lib/bloc/rbac/rbac_operations/station/station_state.dart new file mode 100644 index 0000000..7ab511f --- /dev/null +++ b/lib/bloc/rbac/rbac_operations/station/station_state.dart @@ -0,0 +1,32 @@ +part of 'station_bloc.dart'; + +abstract class StationState extends Equatable { + const StationState(); + + @override + List get props => []; +} + +class StationInitial extends StationState {} + +class StationLoadedState extends StationState { + final List agencies; + final List stations; + const StationLoadedState({required this.stations, required this.agencies}); + @override + List get props => [agencies,stations]; +} + +class StationLoadingState extends StationState {} + +class StationErrorState extends StationState { + final String message; + const StationErrorState({required this.message}); + @override + List get props => [message]; +} + +class FilterStationState extends StationState { + final int agencyId; + const FilterStationState({required this.agencyId}); +} diff --git a/lib/bloc/rbac/rbac_state.dart b/lib/bloc/rbac/rbac_state.dart new file mode 100644 index 0000000..6c793a5 --- /dev/null +++ b/lib/bloc/rbac/rbac_state.dart @@ -0,0 +1,36 @@ +part of 'rbac_bloc.dart'; + +abstract class RbacState extends Equatable { + const RbacState(); + + @override + List get props => []; +} + +class RbacInitial extends RbacState {} + +class RbacScreenSetted extends RbacState { + final List modules; + final List objects; + final List role; + final List permission; + final List operations; + const RbacScreenSetted( + {required this.modules, + required this.objects, + required this.operations, + required this.permission, + required this.role}); +} + +class RbacLoadingState extends RbacState {} + +class RbacErrorState extends RbacState { + final String message; + const RbacErrorState({required this.message}); +} + +class RbacAssignedState extends RbacState{ +final Map responseStatus; + const RbacAssignedState({required this.responseStatus}); +} diff --git a/lib/bloc/role/pass_check/pass_check_bloc.dart b/lib/bloc/role/pass_check/pass_check_bloc.dart index c1d157a..9458357 100644 --- a/lib/bloc/role/pass_check/pass_check_bloc.dart +++ b/lib/bloc/role/pass_check/pass_check_bloc.dart @@ -22,15 +22,15 @@ class PassCheckBloc extends Bloc { int? stationId; String? cpId; on((event, emit) async { - try { + // try { emit(PassCheckLoadingState()); List response = await PassCheckServices.instance .getPassCheckArea(roleId: event.roleId, userId: event.userId); roleId = event.roleId; emit(AssignAreaLoaded(assignedArea: response, roleId: roleId!)); - } catch (e) { - emit(PassCheckErrorState(message: e.toString())); - } + // } catch (e) { + // emit(PassCheckErrorState(message: e.toString())); + // } }); on((event, emit) { otherInputs = event.includeOtherInputs; diff --git a/lib/bloc/role_assignment/role_assignment_bloc.dart b/lib/bloc/role_assignment/role_assignment_bloc.dart new file mode 100644 index 0000000..2d75f2d --- /dev/null +++ b/lib/bloc/role_assignment/role_assignment_bloc.dart @@ -0,0 +1,96 @@ +import 'package:bloc/bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:unit2/sevices/roles/rbac_services.dart'; + +import '../../model/profile/basic_information/primary-information.dart'; +import '../../model/rbac/assigned_role.dart'; +import '../../model/rbac/rbac.dart'; +import '../../sevices/roles/rbac_operations/role_assignment_services.dart'; +import '../../sevices/roles/rbac_operations/role_services.dart'; + +part 'role_assignment_event.dart'; +part 'role_assignment_state.dart'; + +class RoleAssignmentBloc + extends Bloc { + RoleAssignmentBloc() : super(RoleAssignmentInitial()) { + List assignedRoles = []; + int userId; + String? fname; + String? lname; + String? fullname; + Profile? profile; + List roles = []; + on((event, emit) async { + emit(RoleAssignmentLoadingState()); + fname = event.firstname; + lname = event.lastname; + fullname = "${event.firstname} ${event.lastname}"; + + try { + profile = await RbacRoleAssignmentServices.instance.searchUser( + page: 1, name: event.firstname, lastname: event.lastname); + if (profile != null && profile?.id != null) { + assignedRoles = await RbacRoleAssignmentServices.instance + .getAssignedRoles( + firstname: event.firstname, lastname: event.lastname); + + if (roles.isEmpty) { + roles = await RbacRoleServices.instance.getRbacRoles(); + } + emit(AssignedRoleLoaded( + assignedRoles: assignedRoles, fullname: fullname!, roles: roles)); + } else { + emit(UserNotExistError()); + } + + + } catch (e) { + emit(RoleAssignmentErrorState(message: e.toString())); + } + }); + on((event, emit) { + emit(AssignedRoleLoaded( + assignedRoles: assignedRoles, fullname: fullname!, roles: roles)); + }); + on((event, emit) async { + emit(RoleAssignmentLoadingState()); + try { + bool success = await RbacRoleAssignmentServices.instance + .deleteAssignedRole(roleId: event.roleId); + if (success) { + assignedRoles.removeWhere((element) => element.id == event.roleId); + emit(AssignedRoleDeletedState(success: success)); + } else { + emit(AssignedRoleDeletedState(success: success)); + } + } catch (e) { + emit(RoleAssignmentErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(RoleAssignmentLoadingState()); + try { + Map statusResponse = + await RbacRoleAssignmentServices.instance.add( + userId: profile!.webuserId!, + assignerId: event.assignerId, + roles: event.roles); + if (statusResponse['success']) { + assignedRoles = []; + statusResponse['data'].forEach((var roles) { + AssignedRole newAssignRole = AssignedRole.fromJson(roles); + if (!event.roles.contains(newAssignRole.id)) { + assignedRoles.add(newAssignRole); + } + }); + emit(AssignedRoleAddedState(response: statusResponse)); + } else { + emit(AssignedRoleAddedState(response: statusResponse)); + } + } catch (e) { + emit(RoleAssignmentErrorState(message: e.toString())); + } + }); + } +} diff --git a/lib/bloc/role_assignment/role_assignment_event.dart b/lib/bloc/role_assignment/role_assignment_event.dart new file mode 100644 index 0000000..016ce40 --- /dev/null +++ b/lib/bloc/role_assignment/role_assignment_event.dart @@ -0,0 +1,28 @@ +part of 'role_assignment_bloc.dart'; + +abstract class RoleAssignmentEvent extends Equatable { + const RoleAssignmentEvent(); + + @override + List get props => []; +} + +class GetAssignedRoles extends RoleAssignmentEvent { + final String firstname; + final String lastname; + const GetAssignedRoles({required this.firstname, required this.lastname}); +} + +class DeleteAssignRole extends RoleAssignmentEvent { + final int roleId; + const DeleteAssignRole({required this.roleId}); +} + +class LoadAssignedRole extends RoleAssignmentEvent {} + +class AssignRole extends RoleAssignmentEvent { + final List roles; + final int assignerId; + const AssignRole( + {required this.assignerId, required this.roles}); +} diff --git a/lib/bloc/role_assignment/role_assignment_state.dart b/lib/bloc/role_assignment/role_assignment_state.dart new file mode 100644 index 0000000..98dc25a --- /dev/null +++ b/lib/bloc/role_assignment/role_assignment_state.dart @@ -0,0 +1,37 @@ +part of 'role_assignment_bloc.dart'; + +abstract class RoleAssignmentState extends Equatable { + const RoleAssignmentState(); + + @override + List get props => []; +} + +class RoleAssignmentInitial extends RoleAssignmentState {} + +class AssignedRoleLoaded extends RoleAssignmentState { + final String fullname; + final List assignedRoles; + final List roles; + const AssignedRoleLoaded( + {required this.assignedRoles, required this.fullname, required this.roles}); +} + +class RoleAssignmentLoadingState extends RoleAssignmentState {} + +class RoleAssignmentErrorState extends RoleAssignmentState { + final String message; + const RoleAssignmentErrorState({required this.message}); +} +class UserNotExistError extends RoleAssignmentState{ + +} +class AssignedRoleDeletedState extends RoleAssignmentState { + final bool success; + const AssignedRoleDeletedState({required this.success}); +} + +class AssignedRoleAddedState extends RoleAssignmentState { + final Map response; + const AssignedRoleAddedState({required this.response}); +} diff --git a/lib/model/login_data/user_info/module.dart b/lib/model/login_data/user_info/module.dart index 700d9a5..a72f278 100644 --- a/lib/model/login_data/user_info/module.dart +++ b/lib/model/login_data/user_info/module.dart @@ -11,7 +11,7 @@ class Module { String? icon; String? name; String? slug; - List? objects; + List? objects; factory Module.fromJson(Map json) => Module( id: json["id"], @@ -20,8 +20,8 @@ class Module { slug: json["slug"], objects: json["objects"] == null ? [] - : List.from( - json["objects"]!.map((x) => Object.fromJson(x))), + : List.from( + json["objects"]!.map((x) => ModuleObject.fromJson(x))), ); Map toJson() => { @@ -35,8 +35,8 @@ class Module { }; } -class Object { - Object({ +class ModuleObject { + ModuleObject({ this.id, this.name, this.slug, @@ -48,7 +48,7 @@ class Object { String? slug; List? operations; - factory Object.fromJson(Map json) => Object( + factory ModuleObject.fromJson(Map json) => ModuleObject( id: json["id"], name: json["name"], slug: json["slug"], diff --git a/lib/model/login_data/user_info/role.dart b/lib/model/login_data/user_info/role.dart index ef371f7..ff7c545 100644 --- a/lib/model/login_data/user_info/role.dart +++ b/lib/model/login_data/user_info/role.dart @@ -41,34 +41,4 @@ class Role { ? [] : List.from(assignedArea!.map((x) => x!.toJson())), }; -}class Object { - Object({ - this.id, - this.name, - this.slug, - this.operations, - }); - - int? id; - String? name; - String? slug; - List? operations; - - factory Object.fromJson(Map json) => Object( - id: json["id"], - name: json["name"], - slug: json["slug"], - operations: json["operations"] == null - ? [] - : List.from(json["operations"]!.map((x) => x)), - ); - - Map toJson() => { - "id": id, - "name": name, - "slug": slug, - "operations": operations == null - ? [] - : List.from(operations!.map((x) => x)), - }; } \ No newline at end of file diff --git a/lib/model/profile/basic_information/primary-information.dart b/lib/model/profile/basic_information/primary-information.dart index 80b7535..c936a39 100644 --- a/lib/model/profile/basic_information/primary-information.dart +++ b/lib/model/profile/basic_information/primary-information.dart @@ -14,6 +14,7 @@ Profile primaryInformationFromJson(String str) => Profile.fromJson(json.decode(s String primaryInformationToJson(Profile data) => json.encode(data.toJson()); class Profile { + int? webuserId; int? id; String? lastName; String? firstName; @@ -40,6 +41,7 @@ class Profile { String? ip; Profile({ + required this.webuserId, required this.id, required this.lastName, required this.firstName, @@ -67,13 +69,14 @@ class Profile { }); factory Profile.fromJson(Map json) => Profile( + webuserId: null, id: json["id"], lastName: json["last_name"], firstName: json["first_name"], middleName: json["middle_name"], nameExtension: json["name_extension"], sex: json["sex"], - birthdate: DateTime.parse(json["birthdate"]), + birthdate:json['birthdate'] ==null?null: DateTime.parse(json["birthdate"]), civilStatus: json["civil_status"], bloodType: json["blood_type"], heightM: json["height_m"]?.toDouble(), diff --git a/lib/model/rbac/assigned_role.dart b/lib/model/rbac/assigned_role.dart new file mode 100644 index 0000000..52a1b78 --- /dev/null +++ b/lib/model/rbac/assigned_role.dart @@ -0,0 +1,130 @@ +// To parse this JSON data, do +// +// final assignedRole = assignedRoleFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +AssignedRole assignedRoleFromJson(String str) => AssignedRole.fromJson(json.decode(str)); + +String assignedRoleToJson(AssignedRole data) => json.encode(data.toJson()); + +class AssignedRole { + final int? id; + final Role? role; + final CreatedBy? user; + final DateTime? createdAt; + final DateTime? updatedAt; + final CreatedBy? createdBy; + final CreatedBy? updatedBy; + + AssignedRole({ + required this.id, + required this.role, + required this.user, + required this.createdAt, + required this.updatedAt, + required this.createdBy, + required this.updatedBy, + }); + + factory AssignedRole.fromJson(Map json) => AssignedRole( + id: json["id"], + role: json['role'] == null?null: Role.fromJson(json["role"]), + user: json['role'] == null?null: CreatedBy.fromJson(json["user"]), + createdAt:json["created_at"] == null?null: DateTime.parse(json["created_at"]), + updatedAt: json["updated_at"] == null?null: DateTime.parse(json["updated_at"]), + createdBy: json["created_by"] == null? null: CreatedBy.fromJson(json["created_by"]), + updatedBy: json["updated_by"] == null? null: CreatedBy.fromJson(json["updated_by"]), + ); + + Map toJson() => { + "id": id, + "role": role?.toJson(), + "user": user?.toJson(), + "created_at": createdAt?.toIso8601String(), + "updated_at": updatedAt?.toIso8601String(), + "created_by": createdBy?.toJson(), + "updated_by": updatedBy?.toJson(), + }; +} + +class CreatedBy { + final int id; + final String username; + final String firstName; + final String lastName; + final String email; + final bool isActive; + + CreatedBy({ + required this.id, + required this.username, + required this.firstName, + required this.lastName, + required this.email, + required this.isActive, + }); + + factory CreatedBy.fromJson(Map json) => CreatedBy( + id: json["id"], + username: json["username"], + firstName: json["first_name"], + lastName: json["last_name"], + email: json["email"], + isActive: json["is_active"], + ); + + Map toJson() => { + "id": id, + "username": username, + "first_name": firstName, + "last_name": lastName, + "email": email, + "is_active": isActive, + }; +} + +class Role { + final int id; + final String name; + final String slug; + final String shorthand; + final DateTime createdAt; + final DateTime updatedAt; + final CreatedBy createdBy; + final CreatedBy updatedBy; + + Role({ + required this.id, + required this.name, + required this.slug, + required this.shorthand, + required this.createdAt, + required this.updatedAt, + required this.createdBy, + required this.updatedBy, + }); + + factory Role.fromJson(Map json) => Role( + id: json["id"], + name: json["name"], + slug: json["slug"], + shorthand: json["shorthand"], + createdAt: DateTime.parse(json["created_at"]), + updatedAt: DateTime.parse(json["updated_at"]), + createdBy: CreatedBy.fromJson(json["created_by"]), + updatedBy: CreatedBy.fromJson(json["updated_by"]), + ); + + Map toJson() => { + "id": id, + "name": name, + "slug": slug, + "shorthand": shorthand, + "created_at": createdAt.toIso8601String(), + "updated_at": updatedAt.toIso8601String(), + "created_by": createdBy.toJson(), + "updated_by": updatedBy.toJson(), + }; +} diff --git a/lib/model/rbac/new_permission.dart b/lib/model/rbac/new_permission.dart new file mode 100644 index 0000000..8c84b49 --- /dev/null +++ b/lib/model/rbac/new_permission.dart @@ -0,0 +1,70 @@ +// To parse this JSON data, do +// +// final newPermission = newPermissionFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +NewPermission newPermissionFromJson(String str) => NewPermission.fromJson(json.decode(str)); + +String newPermissionToJson(NewPermission data) => json.encode(data.toJson()); + +class NewPermission { + final int? newPermissionObjectId; + final String? newObjectName; + final String? newObjectSlug; + final String? newObjectShorthand; + final List newPermissionOperationIds; + final List newOperations; + + NewPermission({ + required this.newPermissionObjectId, + required this.newObjectName, + required this.newObjectSlug, + required this.newObjectShorthand, + required this.newPermissionOperationIds, + required this.newOperations, + }); + + factory NewPermission.fromJson(Map json) => NewPermission( + newPermissionObjectId: json["_new_permission_object_id"], + newObjectName: json["_new_object_name"], + newObjectSlug: json["_new_object_slug"], + newObjectShorthand: json["_new_object_shorthand"], + newPermissionOperationIds: List.from(json["_new_permission_operation_ids"].map((x) => x)), + newOperations: List.from(json["_new_operations"].map((x) => NewOperation.fromJson(x))), + ); + + Map toJson() => { + "_new_permission_object_id": newPermissionObjectId, + "_new_object_name": newObjectName, + "_new_object_slug": newObjectSlug, + "_new_object_shorthand": newObjectShorthand, + "_new_permission_operation_ids": List.from(newPermissionOperationIds.map((x) => x)), + "_new_operations": List.from(newOperations.map((x) => x.toJson())), + }; +} + +class NewOperation { + final String newOperationName; + final String newOperationSlug; + final String newOperationShorthand; + + NewOperation({ + required this.newOperationName, + required this.newOperationSlug, + required this.newOperationShorthand, + }); + + factory NewOperation.fromJson(Map json) => NewOperation( + newOperationName: json["_new_operation_name"], + newOperationSlug: json["_new_operation_slug"], + newOperationShorthand: json["_new_operation_shorthand"], + ); + + Map toJson() => { + "_new_operation_name": newOperationName, + "_new_operation_slug": newOperationSlug, + "_new_operation_shorthand": newOperationShorthand, + }; +} diff --git a/lib/model/rbac/permission.dart b/lib/model/rbac/permission.dart new file mode 100644 index 0000000..dd2c2e3 --- /dev/null +++ b/lib/model/rbac/permission.dart @@ -0,0 +1,79 @@ +import 'package:unit2/model/rbac/rbac.dart'; + +class RBACPermission { + final int? id; + final RBAC? object; + final RBAC? operation; + final DateTime? createdAt; + final dynamic updatedAt; + final CreatedBy? createdBy; + final dynamic updatedBy; + + RBACPermission({ + required this.id, + required this.object, + required this.operation, + required this.createdAt, + required this.updatedAt, + required this.createdBy, + required this.updatedBy, + }); + + factory RBACPermission.fromJson(Map json) => RBACPermission( + id: json["id"], + object: json['object'] == null?null:RBAC.fromJson(json["object"]), + operation: json['operation'] == null?null: RBAC.fromJson(json["operation"]), + createdAt: DateTime.parse(json["created_at"]), + updatedAt: json["updated_at"], + createdBy: CreatedBy.fromJson(json["created_by"]), + updatedBy: json["updated_by"], + ); + + Map toJson() => { + "id": id, + "object": object?.toJson(), + "operation": operation?.toJson(), + "created_at": createdAt?.toIso8601String(), + "updated_at": updatedAt, + "created_by": createdBy?.toJson(), + "updated_by": updatedBy, + }; +} + +class CreatedBy { + final int id; + final String username; + final String firstName; + final String lastName; + final String email; + final bool isActive; + + CreatedBy({ + required this.id, + required this.username, + required this.firstName, + required this.lastName, + required this.email, + required this.isActive, + }); + + factory CreatedBy.fromJson(Map json) => CreatedBy( + id: json["id"], + username: json["username"], + firstName: json["first_name"], + lastName: json["last_name"], + email: json["email"], + isActive: json["is_active"], + ); + + Map toJson() => { + "id": id, + "username": username, + "first_name": firstName, + "last_name": lastName, + "email": email, + "is_active": isActive, + }; +} + + diff --git a/lib/model/rbac/rbac.dart b/lib/model/rbac/rbac.dart new file mode 100644 index 0000000..9fb897d --- /dev/null +++ b/lib/model/rbac/rbac.dart @@ -0,0 +1,94 @@ +// To parse this JSON data, do +// +// final rbac = rbacFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +RBAC rbacFromJson(String str) => RBAC.fromJson(json.decode(str)); + +String rbacToJson(RBAC data) => json.encode(data.toJson()); + +class RBAC { + final int? id; + final String? name; + final String? slug; + final String? shorthand; + final String? fontawesomeIcon; + final DateTime? createdAt; + final dynamic updatedAt; + final CreatedBy? createdBy; + final dynamic updatedBy; + + RBAC({ + required this.id, + required this.name, + required this.slug, + required this.shorthand, + required this.fontawesomeIcon, + required this.createdAt, + required this.updatedAt, + required this.createdBy, + required this.updatedBy, + }); + + factory RBAC.fromJson(Map json) => RBAC( + id: json["id"], + name: json["name"], + slug: json["slug"], + shorthand: json["shorthand"], + fontawesomeIcon: json["fontawesome_icon"], + createdAt: json['created_at'] == null?null: DateTime.parse(json["created_at"]), + updatedAt: json["updated_at"], + createdBy: json['created_by']==null?null: CreatedBy.fromJson(json["created_by"]), + updatedBy: json["updated_by"], + ); + + Map toJson() => { + "id": id, + "name": name, + "slug": slug, + "shorthand": shorthand, + "fontawesome_icon": fontawesomeIcon, + "created_at": createdAt?.toIso8601String(), + "updated_at": updatedAt, + "created_by": createdBy?.toJson(), + "updated_by": updatedBy, + }; +} + +class CreatedBy { + final int id; + final String username; + final String firstName; + final String lastName; + final String email; + final bool isActive; + + CreatedBy({ + required this.id, + required this.username, + required this.firstName, + required this.lastName, + required this.email, + required this.isActive, + }); + + factory CreatedBy.fromJson(Map json) => CreatedBy( + id: json["id"], + username: json["username"], + firstName: json["first_name"], + lastName: json["last_name"], + email: json["email"], + isActive: json["is_active"], + ); + + Map toJson() => { + "id": id, + "username": username, + "first_name": firstName, + "last_name": lastName, + "email": email, + "is_active": isActive, + }; +} diff --git a/lib/model/rbac/rbac_rbac.dart b/lib/model/rbac/rbac_rbac.dart new file mode 100644 index 0000000..ec5bc5f --- /dev/null +++ b/lib/model/rbac/rbac_rbac.dart @@ -0,0 +1,122 @@ +class ModuleObjects { + final int id; + final Module object; + final Module module; + final DateTime? createdAt; + final dynamic updatedAt; + final AtedBy createdBy; + final dynamic updatedBy; + + ModuleObjects({ + required this.id, + required this.object, + required this.module, + required this.createdAt, + required this.updatedAt, + required this.createdBy, + required this.updatedBy, + }); + + factory ModuleObjects.fromJson(Map json) => ModuleObjects( + id:json['id'], + object: Module.fromJson(json["object"]), + module: Module.fromJson(json["module"]), + createdAt: DateTime.parse(json["created_at"]), + updatedAt: json["updated_at"], + createdBy: AtedBy.fromJson(json["created_by"]), + updatedBy: json["updated_by"], + ); + + Map toJson() => { + "object": object.toJson(), + "module": module.toJson(), + "created_at": createdAt?.toIso8601String(), + "updated_at": updatedAt, + "created_by": createdBy.toJson(), + "updated_by": updatedBy, + }; +} + +class AtedBy { + final int id; + final String username; + final String firstName; + final String lastName; + final String email; + final bool isActive; + + AtedBy({ + required this.id, + required this.username, + required this.firstName, + required this.lastName, + required this.email, + required this.isActive, + }); + + factory AtedBy.fromJson(Map json) => AtedBy( + id: json["id"], + username: json["username"], + firstName: json["first_name"], + lastName: json["last_name"], + email: json["email"], + isActive: json["is_active"], + ); + + Map toJson() => { + "id": id, + "username": username, + "first_name": firstName, + "last_name": lastName, + "email": email, + "is_active": isActive, + }; +} + +class Module { + final int id; + final String? name; + final String? slug; + final String? shorthand; + final String? fontawesomeIcon; + final DateTime? createdAt; + final DateTime? updatedAt; + final AtedBy? createdBy; + final AtedBy? updatedBy; + + Module({ + required this.id, + required this.name, + required this.slug, + required this.shorthand, + required this.fontawesomeIcon, + required this.createdAt, + required this.updatedAt, + required this.createdBy, + required this.updatedBy, + }); + + factory Module.fromJson(Map json) => Module( + id: json["id"], + name: json["name"], + slug: json["slug"], + shorthand: json["shorthand"], + fontawesomeIcon: json['fontawesome_icon'] == null?null: json["fontawesome_icon"], + createdAt:json["created_at"] == null? null: DateTime.parse(json["created_at"]), + updatedAt: json["updated_at"] == null? null: DateTime.parse(json["updated_at"]), + createdBy: json["created_by"] == null? null:AtedBy.fromJson(json["created_by"]), + updatedBy: json["updated_by"] == null? null:AtedBy.fromJson(json["updated_by"]), + ); + + Map toJson() => { + "id": id, + "name": name, + "slug": slug, + "shorthand": shorthand, + "fontawesome_icon": fontawesomeIcon, + "created_at": createdAt?.toIso8601String(), + "updated_at": updatedAt?.toIso8601String(), + "created_by": createdBy?.toJson(), + "updated_by": updatedBy?.toJson(), + }; +} diff --git a/lib/model/rbac/rbac_station.dart b/lib/model/rbac/rbac_station.dart new file mode 100644 index 0000000..2a73bd5 --- /dev/null +++ b/lib/model/rbac/rbac_station.dart @@ -0,0 +1,164 @@ +// To parse this JSON data, do +// +// final assignArea = assignAreaFromJson(jsonString); + + + +class RbacStation { + final int? id; + final String? stationName; + final StationType? stationType; + final int? hierarchyOrderNo; + final String? headPosition; + final GovernmentAgency? governmentAgency; + final String? acronym; + final int? parentStation; + final String? code; + final String? fullcode; + final List? childStationInfo; + final bool? islocationUnderParent; + final int? mainParentStation; + final String? description; + final bool? ishospital; + final bool? isactive; + final bool? sellingStation; + + RbacStation({ + required this.id, + required this.stationName, + required this.stationType, + required this.hierarchyOrderNo, + required this.headPosition, + required this.governmentAgency, + required this.acronym, + required this.parentStation, + required this.code, + required this.fullcode, + required this.childStationInfo, + required this.islocationUnderParent, + required this.mainParentStation, + required this.description, + required this.ishospital, + required this.isactive, + required this.sellingStation, + }); + + factory RbacStation.fromJson(Map json) => RbacStation( + id: json["id"], + stationName: json["station_name"], + stationType:json["station_type"] ==null?null: StationType.fromJson(json["station_type"]), + hierarchyOrderNo: json["hierarchy_order_no"], + headPosition: json["head_position"], + governmentAgency: json["government_agency"] == null?null:GovernmentAgency.fromJson(json["government_agency"]), + acronym: json["acronym"], + parentStation: json["parent_station"], + code: json["code"], + fullcode: json["fullcode"], + childStationInfo: null, + islocationUnderParent: json["islocation_under_parent"], + mainParentStation: json["main_parent_station"], + description: json["description"], + ishospital: json["ishospital"], + isactive: json["isactive"], + sellingStation: json["selling_station"], + ); + + Map toJson() => { + "id": id, + "station_name": stationName, + "station_type": stationType?.toJson(), + "hierarchy_order_no": hierarchyOrderNo, + "head_position": headPosition, + "government_agency": governmentAgency?.toJson(), + "acronym": acronym, + "parent_station": parentStation, + "code": code, + "fullcode": fullcode, + "child_station_info": List.from(childStationInfo!.map((x) => x.toJson())), + "islocation_under_parent": islocationUnderParent, + "main_parent_station": mainParentStation, + "description": description, + "ishospital": ishospital, + "isactive": isactive, + "selling_station": sellingStation, + }; +} + +class ChildStationInfo { + final int? id; + final String? stationName; + final String? acroym; + bool? motherStation; + + ChildStationInfo({ + required this.id, + required this.stationName, + required this.acroym, + this.motherStation + }); + + factory ChildStationInfo.fromJson(Map json) => ChildStationInfo( + id: json["id"], + stationName: json["station_name"], + acroym: json["acroym"], + + ); + + Map toJson() => { + "id": id, + "station_name": stationName, + "acroym": acroym, + }; +} + +class GovernmentAgency { + final int? agencyid; + final String? agencyname; + final int? agencycatid; + final bool? privateEntity; + final int? contactinfoid; + + GovernmentAgency({ + required this.agencyid, + required this.agencyname, + required this.agencycatid, + required this.privateEntity, + required this.contactinfoid, + }); + + factory GovernmentAgency.fromJson(Map json) => GovernmentAgency( + agencyid: json["agencyid"], + agencyname: json["agencyname"], + agencycatid: json["agencycatid"], + privateEntity: json["private_entity"], + contactinfoid: json["contactinfoid"], + ); + + Map toJson() => { + "agencyid": agencyid, + "agencyname": agencyname, + "agencycatid": agencycatid, + "private_entity": privateEntity, + "contactinfoid": contactinfoid, + }; +} + +class StationType { + final int? id; + final String? typeName; + + StationType({ + required this.id, + required this.typeName, + }); + + factory StationType.fromJson(Map json) => StationType( + id: json["id"], + typeName: json["type_name"], + ); + + Map toJson() => { + "id": id, + "type_name": typeName, + }; +} diff --git a/lib/model/rbac/role_extend.dart b/lib/model/rbac/role_extend.dart new file mode 100644 index 0000000..acd95fb --- /dev/null +++ b/lib/model/rbac/role_extend.dart @@ -0,0 +1,37 @@ +// To parse this JSON data, do +// +// final rolesExtend = rolesExtendFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +import 'package:unit2/model/rbac/rbac.dart'; + +RolesExtend rolesExtendFromJson(String str) => RolesExtend.fromJson(json.decode(str)); + +String rolesExtendToJson(RolesExtend data) => json.encode(data.toJson()); + +class RolesExtend { + final int id; + final RBAC roleExtendMain; + final RBAC roleExtendChild; + + RolesExtend({ + required this.id, + required this.roleExtendMain, + required this.roleExtendChild, + }); + + factory RolesExtend.fromJson(Map json) => RolesExtend( + id: json["id"], + roleExtendMain: RBAC.fromJson(json["role_extend_main"]), + roleExtendChild: RBAC.fromJson(json["role_extend_child"]), + ); + + Map toJson() => { + "id": id, + "role_extend_main": roleExtendMain.toJson(), + "role_extend_child": roleExtendChild.toJson(), + }; +} + diff --git a/lib/model/rbac/role_module.dart b/lib/model/rbac/role_module.dart new file mode 100644 index 0000000..295f1cf --- /dev/null +++ b/lib/model/rbac/role_module.dart @@ -0,0 +1,124 @@ + +class RoleModules { + final int? id; + final Module? role; + final Module? module; + final DateTime? createdAt; + final dynamic updatedAt; + final AtedBy? createdBy; + final dynamic updatedBy; + + RoleModules({ + required this.id, + required this.role, + required this.module, + required this.createdAt, + required this.updatedAt, + required this.createdBy, + required this.updatedBy, + }); + + factory RoleModules.fromJson(Map json) => RoleModules( + id: json["id"], + role:json['role'] == null?null: Module.fromJson(json["role"]), + module: json['module'] == null?null:Module.fromJson(json["module"]), + createdAt: json["created_at"] == null? null: DateTime.parse(json["created_at"]), + updatedAt: json["updated_at"], + createdBy: json["created_by"]==null? null: AtedBy.fromJson(json["created_by"]), + updatedBy: json["updated_by"], + ); + + Map toJson() => { + "id": id, + "role": role?.toJson(), + "module": module?.toJson(), + "created_at": createdAt?.toIso8601String(), + "updated_at": updatedAt, + "created_by": createdBy?.toJson(), + "updated_by": updatedBy, + }; +} + +class AtedBy { + final int id; + final String username; + final String firstName; + final String lastName; + final String email; + final bool isActive; + + AtedBy({ + required this.id, + required this.username, + required this.firstName, + required this.lastName, + required this.email, + required this.isActive, + }); + + factory AtedBy.fromJson(Map json) => AtedBy( + id: json["id"], + username: json["username"], + firstName: json["first_name"], + lastName: json["last_name"], + email: json["email"], + isActive: json["is_active"], + ); + + Map toJson() => { + "id": id, + "username": username, + "first_name": firstName, + "last_name": lastName, + "email": email, + "is_active": isActive, + }; +} + +class Module { + final int? id; + final String? name; + final String? slug; + final String? shorthand; + final String? fontawesomeIcon; + final DateTime? createdAt; + final DateTime? updatedAt; + final AtedBy? createdBy; + final AtedBy? updatedBy; + + Module({ + required this.id, + required this.name, + required this.slug, + required this.shorthand, + required this.fontawesomeIcon, + required this.createdAt, + required this.updatedAt, + required this.createdBy, + required this.updatedBy, + }); + + factory Module.fromJson(Map json) => Module( + id: json["id"], + name: json["name"], + slug: json["slug"], + shorthand: json["shorthand"], + fontawesomeIcon: null, + createdAt:json['created_at'] == null?null: DateTime.parse(json["created_at"]), + updatedAt:json["updated_at"] == null?null: DateTime.parse(json["updated_at"]), + createdBy:json["created_by"] ==null?null: AtedBy.fromJson(json["created_by"]), + updatedBy:json["updated_by"] == null?null: AtedBy.fromJson(json["updated_by"]), + ); + + Map toJson() => { + "id": id, + "name": name, + "slug": slug, + "shorthand": shorthand, + "fontawesome_icon": fontawesomeIcon, + "created_at": createdAt?.toIso8601String(), + "updated_at": updatedAt?.toIso8601String(), + "created_by": createdBy?.toJson(), + "updated_by": updatedBy?.toJson(), + }; +} diff --git a/lib/model/rbac/role_under.dart b/lib/model/rbac/role_under.dart new file mode 100644 index 0000000..dedc7c2 --- /dev/null +++ b/lib/model/rbac/role_under.dart @@ -0,0 +1,37 @@ +// To parse this JSON data, do +// +// final rolesUnder = rolesUnderFromJson(jsonString); + +import 'package:meta/meta.dart'; +import 'dart:convert'; + +import 'package:unit2/model/rbac/rbac.dart'; + +RolesUnder rolesUnderFromJson(String str) => RolesUnder.fromJson(json.decode(str)); + +String rolesUnderToJson(RolesUnder data) => json.encode(data.toJson()); + +class RolesUnder { + final int id; + final RBAC roleUnderMain; + final RBAC roleUnderChild; + + RolesUnder({ + required this.id, + required this.roleUnderMain, + required this.roleUnderChild, + }); + + factory RolesUnder.fromJson(Map json) => RolesUnder( + id: json["id"], + roleUnderMain: RBAC.fromJson(json["role_under_main"]), + roleUnderChild: RBAC.fromJson(json["role_under_child"]), + ); + + Map toJson() => { + "id": id, + "role_under_main": roleUnderMain.toJson(), + "role_under_child": roleUnderChild.toJson(), + }; +} + diff --git a/lib/model/roles/pass_check/station_assign_area.dart b/lib/model/roles/pass_check/station_assign_area.dart index 4251403..cbece06 100644 --- a/lib/model/roles/pass_check/station_assign_area.dart +++ b/lib/model/roles/pass_check/station_assign_area.dart @@ -4,7 +4,7 @@ class StationAssignArea { final bool? isactive; - final Area? area; + final Station? area; StationAssignArea({ required this.isactive, @@ -13,7 +13,7 @@ class StationAssignArea { factory StationAssignArea.fromJson(Map json) => StationAssignArea( isactive: json["isactive"], - area: json["area"] == null?null: Area.fromJson(json["area"]), + area: json["area"] == null?null: Station.fromJson(json["area"]), ); Map toJson() => { @@ -22,7 +22,7 @@ class StationAssignArea { }; } -class Area { +class Station { final int? id; final String? stationName; final StationType? stationType; @@ -41,7 +41,7 @@ class Area { final bool? isactive; final bool? sellingStation; - Area({ + Station({ required this.id, required this.stationName, required this.stationType, @@ -61,7 +61,7 @@ class Area { required this.sellingStation, }); - factory Area.fromJson(Map json) => Area( + factory Station.fromJson(Map json) => Station( id: json["id"], stationName: json["station_name"], stationType:json["station_type"] ==null?null: StationType.fromJson(json["station_type"]), @@ -72,7 +72,7 @@ class Area { parentStation: json["parent_station"], code: json["code"], fullcode: json["fullcode"], - childStationInfo: json['child_station_info']==null?[]:List.from(json["child_station_info"].map((x) => ChildStationInfo.fromJson(x))), + childStationInfo: json['child_station_info']==null || json['child_station_info'].isEmpty ?[]:List.from(json["child_station_info"].map((x) => ChildStationInfo.fromJson(x))), islocationUnderParent: json["islocation_under_parent"], mainParentStation: json["main_parent_station"], description: json["description"], @@ -81,7 +81,7 @@ class Area { sellingStation: json["selling_station"], ); - Map toJson() => { + Map toJson() => { "id": id, "station_name": stationName, "station_type": stationType?.toJson(), diff --git a/lib/screens/profile/components/basic_information/edit_basic_info_modal.dart b/lib/screens/profile/components/basic_information/edit_basic_info_modal.dart index 253ea7d..095ca78 100644 --- a/lib/screens/profile/components/basic_information/edit_basic_info_modal.dart +++ b/lib/screens/profile/components/basic_information/edit_basic_info_modal.dart @@ -493,6 +493,7 @@ class _EditBasicProfileInfoScreenState : double.tryParse( _formKey.currentState?.value['weigth']); Profile primaryInformation = Profile( + webuserId: null, id: state.primaryInformation.id, lastName: lastName, firstName: firstName, diff --git a/lib/screens/profile/components/education_screen.dart b/lib/screens/profile/components/education_screen.dart index 3da29ed..4514284 100644 --- a/lib/screens/profile/components/education_screen.dart +++ b/lib/screens/profile/components/education_screen.dart @@ -3,14 +3,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; -import 'package:fluttericon/font_awesome_icons.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart'; import 'package:unit2/model/profile/educational_background.dart'; import 'package:unit2/screens/profile/components/education/add_modal.dart'; import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/colors.dart'; -import 'package:unit2/utils/text_container.dart'; import 'package:unit2/widgets/Leadings/add_leading.dart'; import 'package:unit2/widgets/empty_data.dart'; import 'package:unit2/widgets/error_state.dart'; @@ -18,28 +16,37 @@ import '../../../bloc/profile/education/education_bloc.dart'; import '../../../utils/alerts.dart'; import '../../../widgets/Leadings/close_leading.dart'; import 'education/edit_modal.dart'; - class EducationScreen extends StatelessWidget { const EducationScreen({super.key}); - @override Widget build(BuildContext context) { int profileId; String? token; return Scaffold( appBar: AppBar( - title:context.watch().state is AddEducationState? const FittedBox(child: Text("Add Educational Background")): context.watch().state is EditEducationState?const FittedBox(child: Text("Edit Educational Background")):const Text("Education Background"), + title: context.watch().state is AddEducationState + ? const FittedBox(child: Text("Add Educational Background")) + : context.watch().state is EditEducationState + ? const FittedBox(child: Text("Edit Educational Background")) + : const Text("Education Background"), centerTitle: true, backgroundColor: primary, - actions: context.watch().state is EducationalBackgroundLoadedState?[ - AddLeading(onPressed: () { - context.read().add(ShowAddEducationForm()); - }) - ]:(context.watch().state is AddEducationState || context.watch().state is EditEducationState)?[ - CloseLeading(onPressed: () { - context.read().add( LoadEducations()); - }) - ]:[], + actions: context.watch().state + is EducationalBackgroundLoadedState + ? [ + AddLeading(onPressed: () { + context.read().add(ShowAddEducationForm()); + }) + ] + : (context.watch().state is AddEducationState || + context.watch().state + is EditEducationState) + ? [ + CloseLeading(onPressed: () { + context.read().add(LoadEducations()); + }) + ] + : [], ), //userbloc body: ProgressHUD( @@ -66,7 +73,8 @@ class EducationScreen extends StatelessWidget { state is EducationalBackgroundErrorState || state is AddEducationState || state is EditEducationState || - state is EducationDeletedState || state is EditedEducationState) { + state is EducationDeletedState || + state is EditedEducationState) { final progress = ProgressHUD.of(context); progress!.dismiss(); } @@ -92,7 +100,6 @@ class EducationScreen extends StatelessWidget { } } ////EDITED STATE - if (state is EditedEducationState) { if (state.response['success']) { successAlert(context, "Update Successfull!", @@ -188,14 +195,11 @@ class EducationScreen extends StatelessWidget { Row( children: [ Expanded( - child: Text( - level, - style: Theme.of( - context) - .textTheme - .titleSmall! - - )), + child: Text(level, + style: Theme.of( + context) + .textTheme + .titleSmall!)), Text( "$periodFrom - $periodTo", style: Theme.of( @@ -212,7 +216,12 @@ class EducationScreen extends StatelessWidget { school, style: Theme.of(context) .textTheme - .titleMedium!.copyWith(color: primary,fontWeight: FontWeight.w500), + .titleMedium! + .copyWith( + color: primary, + fontWeight: + FontWeight + .w500), ), Container( padding: @@ -228,7 +237,9 @@ class EducationScreen extends StatelessWidget { CrossAxisAlignment .start, children: [ - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), const Text( " honors: ", style: TextStyle( @@ -237,8 +248,10 @@ class EducationScreen extends StatelessWidget { ), Column( children: honors - .map((Honor honor) => - Text("-${honor.name!.trim()}",style: Theme.of(context).textTheme.labelMedium,)) + .map((Honor honor) => Text( + "-${honor.name!.trim()}", + style: Theme.of(context).textTheme.labelMedium, + )) .toList(), ), ], @@ -312,11 +325,10 @@ class EducationScreen extends StatelessWidget { text: "Remove", value: 2, icon: Icons.delete), - popMenuItem( + popMenuItem( text: "Attach", value: 2, icon: Icons.attach_file), - ], icon: const Icon( Icons.more_vert, @@ -341,8 +353,11 @@ class EducationScreen extends StatelessWidget { } if (state is EducationalBackgroundErrorState) { return SomethingWentWrong( - message: state.message, onpressed: () { - context.read().add(GetEducationalBackground(profileId: profileId, token: token!)); + message: state.message, + onpressed: () { + context.read().add( + GetEducationalBackground( + profileId: profileId, token: token!)); }); } if (state is AddEducationState) { diff --git a/lib/screens/profile/components/learning_development/add_modal.dart b/lib/screens/profile/components/learning_development/add_modal.dart index 5a0e4f7..9eed392 100644 --- a/lib/screens/profile/components/learning_development/add_modal.dart +++ b/lib/screens/profile/components/learning_development/add_modal.dart @@ -150,7 +150,6 @@ class _AddLearningAndDevelopmentScreenState setState(() { show = false; showOtherInputs = true; - selectedTrainingController .text = addTrainingController.text diff --git a/lib/screens/profile/components/work_history/add_modal.dart b/lib/screens/profile/components/work_history/add_modal.dart index 9f16525..f7ee97d 100644 --- a/lib/screens/profile/components/work_history/add_modal.dart +++ b/lib/screens/profile/components/work_history/add_modal.dart @@ -14,7 +14,7 @@ import 'package:unit2/model/utils/category.dart'; import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/btn-style.dart'; import 'package:unit2/theme-data.dart/colors.dart'; -import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; import 'package:unit2/utils/global.dart'; import 'package:unit2/utils/text_container.dart'; import 'package:unit2/utils/validators.dart'; diff --git a/lib/screens/profile/profile.dart b/lib/screens/profile/profile.dart index a7dc9f9..b601337 100644 --- a/lib/screens/profile/profile.dart +++ b/lib/screens/profile/profile.dart @@ -13,7 +13,6 @@ import 'package:unit2/bloc/profile/primary_information/citizenship/citizenship_b import 'package:unit2/bloc/profile/primary_information/contact/contact_bloc.dart'; import 'package:unit2/bloc/profile/primary_information/identification/identification_bloc.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart'; -import 'package:unit2/model/login_data/user_info/user_data.dart'; import 'package:unit2/screens/profile/components/basic_information/address_screen.dart'; import 'package:unit2/screens/profile/components/basic_information/citizenship_screen.dart'; import 'package:unit2/screens/profile/components/basic_information/contact_information_screen.dart'; diff --git a/lib/screens/profile/shared/add_for_empty_search.dart b/lib/screens/profile/shared/add_for_empty_search.dart index 8d90f98..2d67130 100644 --- a/lib/screens/profile/shared/add_for_empty_search.dart +++ b/lib/screens/profile/shared/add_for_empty_search.dart @@ -11,7 +11,10 @@ class EmptyWidget extends StatelessWidget { final Function()? onpressed; final String title; const EmptyWidget( - {super.key, required this.controller, required this.onpressed,required this.title}); + {super.key, + required this.controller, + required this.onpressed, + required this.title}); @override Widget build(BuildContext context) { @@ -36,15 +39,13 @@ class EmptyWidget extends StatelessWidget { context: context, builder: (BuildContext context) { return AlertDialog( - title: Text(title), + title: Text(title), content: SizedBox( height: 130, child: Column( children: [ TextFormField( - inputFormatters: [ - UpperCaseTextFormatter() - ], + inputFormatters: [UpperCaseTextFormatter()], controller: controller, decoration: normalTextFieldStyle("", ""), ), @@ -65,8 +66,8 @@ class EmptyWidget extends StatelessWidget { ); }); }, - child: Text(title)) + child: Text(title)) ]), ); } -} \ No newline at end of file +} diff --git a/lib/screens/superadmin/agency.dart/agency_screen.dart b/lib/screens/superadmin/agency.dart/agency_screen.dart new file mode 100644 index 0000000..909f387 --- /dev/null +++ b/lib/screens/superadmin/agency.dart/agency_screen.dart @@ -0,0 +1,267 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/agency/agency_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/object/object_bloc.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/category.dart'; +import 'package:unit2/screens/superadmin/role/shared_pop_up_menu.dart'; +import 'package:unit2/utils/global_context.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../theme-data.dart/box_shadow.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/formatters.dart'; +import '../../../utils/global.dart'; +import '../../../widgets/Leadings/add_leading.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacAgencyScreen extends StatelessWidget { + final int id; + const RbacAgencyScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final formKey = GlobalKey(); + List agencyCategory = []; + Category? selectedAgencyCategory; + bool? isPrivate; + final agencyCategoryFocusNode = FocusNode(); + BuildContext parent; + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + title: const Text("Agencies"), + actions: [ + AddLeading(onPressed: () { + parent = context; + showDialog( + context: NavigationService.navigatorKey.currentContext!, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Add Agency"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderTextField( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + name: "name", + decoration: normalTextFieldStyle( + "Agency name ", "Agency name"), + ), + const SizedBox( + height: 12, + ), + SearchField( + focusNode: agencyCategoryFocusNode, + itemHeight: 80, + suggestions: agencyCategory + .map((Category category) => + SearchFieldListItem(category.name!, + item: category, + child: ListTile( + title: Text(category.name!), + subtitle: Text( + category.industryClass!.name!), + ))) + .toList(), + emptyWidget: Container( + height: 100, + decoration: box1(), + child: const Center( + child: Text("No result found ...")), + ), + onSuggestionTap: (agencyCategory) { + selectedAgencyCategory = agencyCategory.item; + agencyCategoryFocusNode.unfocus(); + }, + searchInputDecoration: + normalTextFieldStyle("Category *", "") + .copyWith( + suffixIcon: IconButton( + icon: const Icon(Icons.arrow_drop_down), + onPressed: () { + agencyCategoryFocusNode.unfocus(); + }, + )), + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + ), + FormBuilderRadioGroup( + decoration: InputDecoration( + border: InputBorder.none, + label: Row( + children: [ + Text( + "Is this private sector? ", + style: Theme.of(context) + .textTheme + .headlineSmall! + .copyWith(fontSize: 24), + ), + const Icon(FontAwesome.help_circled) + ], + ), + ), + + ////onvhange private sector + onChanged: (value) { + if (value.toString() == "YES") { + isPrivate = true; + } else { + isPrivate = false; + } + }, + + name: 'isPrivate', + validator: FormBuilderValidators.required(), + options: ["YES", "NO"] + .map((lang) => + FormBuilderFieldOption(value: lang)) + .toList(growable: false), + ), + const SizedBox( + height: 12, + ), + SizedBox( + height: 50, + width: double.maxFinite, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate()) { + String name = + formKey.currentState!.value['name']; + parent.read().add(AddAgency( + agency: Agency( + category: selectedAgencyCategory, + id: null, + name: name, + privateEntity: isPrivate))); + Navigator.pop(context); + } + + }, + child: const Text("Add")), + ) + ], + )), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is AgencyLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is AgenciesLoaded || + state is AgencyAddesState || + state is AgencyErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + + ////Deleted State + if (state is AgencyDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Agency Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(GetAgencies()); + }); + } else { + errorAlert(context, "Delete Failed", "Object Delete Failed", + () { + Navigator.of(context).pop(); + context.read().add(GetObjects()); + }); + } + } + }, + builder: (context, state) { + final parent = context; + if (state is AgenciesLoaded) { + agencyCategory = state.agencyCategory; + if (state.agencies.isNotEmpty) { + return ListView.builder( + padding: + const EdgeInsets.symmetric(vertical: 8, horizontal: 10), + itemCount: state.agencies.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Expanded( + child: Row( + children: [ + CircleAvatar( + child: Text('${index + 1}'), + ), + const SizedBox( + width: 12, + ), + Flexible( + child: Text(state.agencies[index].name!, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: primary)), + ), + ], + )), + ), + const SizedBox( + height: 5, + ) + ], + ); + }); + } else { + return const EmptyData( + message: "No Object available. Please click + to add."); + } + } + if (state is AgencyErrorState) { + return SomethingWentWrong( + message: state.message, + onpressed: () { + context.read().add(GetObjects()); + }); + } + return Container(); + }, + ), + ), + ); + } +} diff --git a/lib/screens/superadmin/module/module_screen.dart b/lib/screens/superadmin/module/module_screen.dart new file mode 100644 index 0000000..7520f77 --- /dev/null +++ b/lib/screens/superadmin/module/module_screen.dart @@ -0,0 +1,373 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/module/module_bloc.dart'; +import 'package:unit2/screens/superadmin/role/shared_pop_up_menu.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../theme-data.dart/box_shadow.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacModuleScreen extends StatelessWidget { + final int id; + const RbacModuleScreen({super.key, required this.id}); + @override + Widget build(BuildContext context) { + final formKey = GlobalKey(); + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + title: const Text("Module Screen"), + actions: [ + AddLeading(onPressed: () { + BuildContext parent = context; + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Add New Module"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderTextField( + name: "object_name", + decoration: normalTextFieldStyle( + "Module name *", "Module name "), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + name: "slug", + decoration: normalTextFieldStyle("Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + validator: FormBuilderValidators.maxLength(50, + errorText: "Max characters only 50"), + name: "shorthand", + decoration: + normalTextFieldStyle("Shorthand ", "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate()) { + String name = formKey + .currentState!.value['object_name']; + String? slug = + formKey.currentState!.value['slug']; + String? short = formKey + .currentState!.value['shorthand']; + parent.read().add( + AddRbacModule( + id: id, + name: name, + shorthand: short, + slug: slug)); + Navigator.pop(context); + } + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is ModuleLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is ModuleLoaded || + state is ModuleErrorState || + state is ModuleAddedState || + state is ModuleDeletedState || + state is ModuleUpdatedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////Added State + if (state is ModuleAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetModule()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetModule()); + }); + } + } + ////Updated state + if (state is ModuleUpdatedState) { + if (state.response['success']) { + successAlert( + context, "Updated Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetModule()); + }); + } else { + errorAlert(context, "Update Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetModule()); + }); + } + } + ////Deleted State + if (state is ModuleDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Module Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(GetModule()); + }); + } else { + errorAlert(context, "Delete Failed", "Module Delete Failed", + () { + Navigator.of(context).pop(); + context.read().add(GetModule()); + }); + } + } + }, + builder: (context, state) { + final parent = context; + if (state is ModuleLoaded) { + if (state.module.isNotEmpty) { + return ListView.builder( + padding: + const EdgeInsets.symmetric(vertical: 8, horizontal: 10), + itemCount: state.module.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + CircleAvatar(child: Text('${index+1}'),), + const SizedBox(width: 12,), + Text(state.module[index].name!, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: primary)), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + if (value == 2) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Update Module"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: + MainAxisSize.min, + children: [ + FormBuilderTextField( + initialValue: state + .module[index].name, + name: "object_name", + decoration: + normalTextFieldStyle( + "Module name *", + "Module name "), + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + initialValue: state + .module[index].slug, + name: "slug", + decoration: + normalTextFieldStyle( + "Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + initialValue: state + .module[index] + .shorthand, + validator: + FormBuilderValidators + .maxLength(50, + errorText: + "Max characters only 50"), + name: "shorthand", + decoration: + normalTextFieldStyle( + "Shorthand ", + "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, + Colors + .transparent, + second), + onPressed: () { + if (formKey + .currentState! + .saveAndValidate()) { + String name = formKey + .currentState! + .value[ + 'object_name']; + String? slug = formKey + .currentState! + .value['slug']; + String? short = formKey + .currentState! + .value[ + 'shorthand']; + + ////Update + parent.read().add(UpdateRbacModule( + moduleId: state + .module[ + index] + .id!, + name: name, + slug: slug, + short: + short, + createdBy: state + .module[ + index] + .createdBy + ?.id, + updatedBy: + id)); + Navigator.pop( + context); + } + }, + child: const Text( + "Update"))), + ], + ), + ), + ); + }); + } + if (value == 1) { + ////delete + confirmAlert(context, () { + context.read().add( + DeleteRbacModule( + moduleId: + state.module[index].id!)); + }, "Delete?", "Confirm Delete?"); + } + }, + menuItems: [ + popMenuItem( + text: "Update", + value: 2, + icon: Icons.edit), + popMenuItem( + text: "Remove", + value: 1, + icon: Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ), + ], + ), + ), + const SizedBox( + height: 5, + ) + ], + ); + }); + } else { + return const EmptyData( + message: "No Role available. Please click + to add."); + } + } + if (state is ModuleErrorState) { + return SomethingWentWrong( + message: state.message, + onpressed: () { + context.read().add(GetModule()); + }); + } + return Container(); + }, + ), + ), + ); + } +} diff --git a/lib/screens/superadmin/module_objects/module_objects_screen.dart b/lib/screens/superadmin/module_objects/module_objects_screen.dart new file mode 100644 index 0000000..30ff430 --- /dev/null +++ b/lib/screens/superadmin/module_objects/module_objects_screen.dart @@ -0,0 +1,298 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:group_list_view/group_list_view.dart'; +import 'package:multi_dropdown/models/value_item.dart'; +import 'package:multi_dropdown/multiselect_dropdown.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/module/module_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/module_objects/module_objects_bloc.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../model/rbac/rbac.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global_context.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacModuleObjectsScreen extends StatelessWidget { + final int id; + const RbacModuleObjectsScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final parent = context; + Map> moduleObjects = {}; + List modules = []; + List objects = []; + RBAC? selectedModule; + List valueItemObjects = []; + List selectedValueItemObjects = []; + final formKey = GlobalKey(); + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + title: const Text("Module Object Screen"), + actions: [ + AddLeading(onPressed: () { + showDialog( + context: NavigationService.navigatorKey.currentState!.context, + builder: (BuildContext context) { + valueItemObjects = objects.map((e) { + return ValueItem(label: e.name!, value: e.name); + }).toList(); + return AlertDialog( + title: const Text("Add New Module Object"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderDropdown( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + name: "module", + decoration: + normalTextFieldStyle("Module", "Module"), + items: modules.isEmpty + ? [] + : modules.map((e) { + return DropdownMenuItem( + value: e, child: Text(e.name!)); + }).toList(), + onChanged: (RBAC? object) { + selectedModule = object; + }, + ), + const SizedBox( + height: 12, + ), + MultiSelectDropDown( + onOptionSelected: + (List selectedOptions) { + selectedValueItemObjects = selectedOptions; + }, + borderColor: Colors.grey, + borderWidth: 1, + borderRadius: 5, + hint: "Objects", + padding: const EdgeInsets.all(8), + options: valueItemObjects, + selectionType: SelectionType.multi, + chipConfig: + const ChipConfig(wrapType: WrapType.wrap), + dropdownHeight: 300, + optionTextStyle: const TextStyle(fontSize: 16), + selectedOptionIcon: + const Icon(Icons.check_circle), + ), + const SizedBox( + height: 12, + ), + SizedBox( + height: 50, + width: double.maxFinite, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate() && + selectedValueItemObjects.isNotEmpty) { + int assignerId = id; + int moduleId = selectedModule!.id!; + List objectId = []; + for (var object in objects) { + selectedValueItemObjects + .forEach((element) { + if (element.label.toLowerCase() == + object.name?.toLowerCase()) { + objectId.add(object.id!); + } + }); + } + Navigator.of(context).pop(); + parent.read().add( + AddRbacModuleObjects( + assignerId: assignerId, + moduleId: moduleId, + objectsId: objectId)); + } + }, + child: const Text("Submit")), + ) + ], + )), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + print(state); + if (state is ModuleObjectLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is ModuleObjectLoadedState || + state is ModuleObjectsErrorState || + state is ModuleObjectAddedState || + state is ModuleObjectDeletedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + + ////Deleted State + if (state is ModuleObjectDeletedState) { + if (state.success) { + successAlert( + context, "Delete Successfull!", "Role Deleted Successfully", + () { + Navigator.of(context).pop(); + context.read().add(GetModuleObjects()); + }); + } else { + errorAlert(context, "Delete Failed", "Role Delete Failed", () { + Navigator.of(context).pop(); + context.read().add(GetModuleObjects()); + }); + } + } + ////Added State + if (state is ModuleObjectAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetModuleObjects()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetModuleObjects()); + }); + } + } + }, + builder: (context, state) { + if (state is ModuleObjectLoadedState) { + modules = state.modules; + objects = state.objecs; + moduleObjects = {}; + if (state.moduleObjects.isNotEmpty) { + for (var modObjects in state.moduleObjects) { + if (!moduleObjects.keys + .contains(modObjects.module.name!.toLowerCase())) { + moduleObjects + .addAll({modObjects.module.name!.toLowerCase(): []}); + moduleObjects[modObjects.module.name!.toLowerCase()]!.add( + Content( + id: modObjects.id, name: modObjects.object.name!)); + } else { + moduleObjects[modObjects.module.name!.toLowerCase()]!.add( + Content( + id: modObjects.id, name: modObjects.object.name!)); + } + } + } + + if (state.moduleObjects.isNotEmpty) { + return GroupListView( + sectionsCount: moduleObjects.keys.toList().length, + countOfItemInSection: (int section) { + return moduleObjects.values.toList()[section].length; + }, + separatorBuilder: (context, index) { + return const Divider(); + }, + itemBuilder: (BuildContext context, IndexPath index) { + return ListTile( + trailing: IconButton( + color: Colors.grey.shade600, + icon: const Icon(Icons.delete), + onPressed: () { + confirmAlert(context, () { + context.read().add( + DeleteRbacModuleObject( + moduleObjectId: moduleObjects.values + .toList()[index.section][index.index] + .id)); + }, "Delete?", "Confirm Delete?"); + }, + ), + title: Row( + children: [ + CircleAvatar( + child: Text("${index.index + 1}", + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith(color: Colors.white))), + const SizedBox( + width: 20, + ), + Expanded( + child: Text( + moduleObjects.values + .toList()[index.section][index.index] + .name + .toUpperCase(), + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith( + fontWeight: FontWeight.w600, + color: primary), + ), + ), + ], + ), + ); + }, + groupHeaderBuilder: (BuildContext context, int section) { + return ListTile( + tileColor: second, + title: Text( + moduleObjects.keys.toList()[section].toUpperCase(), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(color: Colors.white), + ), + ); + }, + ); + } else { + return const EmptyData( + message: "No Role available. Please click + to add."); + } + } + if (state is ModuleObjectsErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () {}); + } + return Container(); + }, + ), + ), + ); + } +} + +class Content { + final int id; + final String name; + const Content({required this.id, required this.name}); +} diff --git a/lib/screens/superadmin/object/object_screen.dart b/lib/screens/superadmin/object/object_screen.dart new file mode 100644 index 0000000..98edea4 --- /dev/null +++ b/lib/screens/superadmin/object/object_screen.dart @@ -0,0 +1,376 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/object/object_bloc.dart'; +import 'package:unit2/screens/superadmin/role/shared_pop_up_menu.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../theme-data.dart/box_shadow.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global.dart'; +import '../../../widgets/Leadings/add_leading.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacObjectScreen extends StatelessWidget { + final int id; + const RbacObjectScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final formKey = GlobalKey(); + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + title: const Text("Objects Screen"), + actions: [ + AddLeading(onPressed: () { + BuildContext parent = context; + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Add New Object"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderTextField( + name: "object_name", + decoration: normalTextFieldStyle( + "Object name *", "Object name "), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + name: "slug", + decoration: normalTextFieldStyle("Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + validator: FormBuilderValidators.maxLength(50, + errorText: "Max characters only 50"), + name: "shorthand", + decoration: + normalTextFieldStyle("Shorthand ", "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate()) { + String name = formKey + .currentState!.value['object_name']; + String? slug = + formKey.currentState!.value['slug']; + String? short = formKey + .currentState!.value['shorthand']; + parent.read().add( + AddRbacObject( + id: id, + name: name, + shorthand: short, + slug: slug)); + Navigator.pop(context); + } + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is ObjectLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is ObjectLoaded || + state is ObjectAddedState || + state is ObjectErrorState || + state is ObjectUpdatedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////Added State + if (state is ObjectAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetObjects()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetObjects()); + }); + } + } + ////Updated state + if (state is ObjectUpdatedState) { + if (state.response['success']) { + successAlert( + context, "Updated Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetObjects()); + }); + } else { + errorAlert(context, "Update Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetObjects()); + }); + } + } + ////Deleted State + if (state is ObjectDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Object Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(GetObjects()); + }); + } else { + errorAlert(context, "Delete Failed", "Object Delete Failed", + () { + Navigator.of(context).pop(); + context.read().add(GetObjects()); + }); + } + } + }, + builder: (context, state) { + final parent = context; + if (state is ObjectLoaded) { + if (state.objects.isNotEmpty) { + return ListView.builder( + padding: + const EdgeInsets.symmetric(vertical: 8, horizontal: 10), + itemCount: state.objects.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + CircleAvatar( + child: Text('${index + 1}'), + ), + const SizedBox( + width: 12, + ), + Text(state.objects[index].name!, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: primary)), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + if (value == 2) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: + const Text("Update Object"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: + MainAxisSize.min, + children: [ + FormBuilderTextField( + initialValue: state + .objects[index].name, + name: "object_name", + decoration: + normalTextFieldStyle( + "Object name *", + "Object name "), + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + initialValue: state + .objects[index].slug, + name: "slug", + decoration: + normalTextFieldStyle( + "Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + initialValue: state + .objects[index] + .shorthand, + validator: + FormBuilderValidators + .maxLength(50, + errorText: + "Max characters only 50"), + name: "shorthand", + decoration: + normalTextFieldStyle( + "Shorthand ", + "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, + Colors + .transparent, + second), + onPressed: () { + if (formKey + .currentState! + .saveAndValidate()) { + String name = formKey + .currentState! + .value[ + 'object_name']; + String? slug = formKey + .currentState! + .value['slug']; + String? short = formKey + .currentState! + .value[ + 'shorthand']; + + parent.read().add(UpdateRbacObject( + objectId: state + .objects[ + index] + .id!, + name: name, + slug: slug, + short: + short, + createdBy: state + .objects[ + index] + .createdBy + ?.id, + updatedBy: + id)); + Navigator.pop( + context); + } + }, + child: const Text( + "Update"))), + ], + ), + ), + ); + }); + } + if (value == 1) { + confirmAlert(context, () { + context.read().add( + DeleteRbacObject( + objectId: + state.objects[index].id!)); + }, "Delete?", "Confirm Delete?"); + } + }, + menuItems: [ + popMenuItem( + text: "Update", + value: 2, + icon: Icons.edit), + popMenuItem( + text: "Remove", + value: 1, + icon: Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ), + ], + ), + ), + const SizedBox( + height: 5, + ) + ], + ); + }); + } else { + return const EmptyData( + message: "No Object available. Please click + to add."); + } + } + if (state is ObjectErrorState) { + return SomethingWentWrong( + message: state.message, + onpressed: () { + context.read().add(GetObjects()); + }); + } + return Container(); + }, + ), + ), + ); + } +} diff --git a/lib/screens/superadmin/operation/operation_screen.dart b/lib/screens/superadmin/operation/operation_screen.dart new file mode 100644 index 0000000..f9a9f8d --- /dev/null +++ b/lib/screens/superadmin/operation/operation_screen.dart @@ -0,0 +1,375 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/operation/operation_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role/role_bloc.dart'; +import 'package:unit2/screens/superadmin/role/shared_pop_up_menu.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../theme-data.dart/box_shadow.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global.dart'; +import '../../../widgets/Leadings/add_leading.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacOperationScreen extends StatelessWidget { + final int id; + const RbacOperationScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final formKey = GlobalKey(); + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + title: const Text("Operations Screen"), + actions: [ + AddLeading(onPressed: () { + BuildContext parent = context; + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Add New Operation"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderTextField( + name: "object_name", + decoration: normalTextFieldStyle( + "Operation name *", "Operation name "), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + name: "slug", + decoration: normalTextFieldStyle("Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + validator: FormBuilderValidators.maxLength(50, + errorText: "Max characters only 50"), + name: "shorthand", + decoration: + normalTextFieldStyle("Shorthand ", "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate()) { + String name = formKey + .currentState!.value['object_name']; + String? slug = + formKey.currentState!.value['slug']; + String? short = formKey + .currentState!.value['shorthand']; + parent.read().add( + AddRbacOperation( + id: id, + name: name, + shorthand: short, + slug: slug)); + Navigator.pop(context); + } + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is OperationLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is OperationsLoaded || + state is OperationErrorState || + state is OperationAddedState || + state is OperationUpdatedState || + state is OperationDeletedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////Added State + if (state is OperationAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetOperations()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetOperations()); + }); + } + } + ////Updated state + if (state is OperationUpdatedState) { + if (state.response['success']) { + successAlert( + context, "Updated Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetOperations()); + }); + } else { + errorAlert(context, "Update Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetOperations()); + }); + } + } + ////Deleted State + if (state is OperationDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Operation Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(GetOperations()); + }); + } else { + errorAlert(context, "Delete Failed", "Operation Delete Failed", + () { + Navigator.of(context).pop(); + context.read().add(GetOperations()); + }); + } + } + }, + builder: (context, state) { + final parent = context; + if (state is OperationsLoaded) { + if (state.operations.isNotEmpty) { + return ListView.builder( + padding: + const EdgeInsets.symmetric(vertical: 8, horizontal: 10), + itemCount: state.operations.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + CircleAvatar(child: Text('${index+1}'),), + const SizedBox(width: 12,), + Text(state.operations[index].name!, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: primary)), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + if (value == 2) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Update Operation"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: + MainAxisSize.min, + children: [ + FormBuilderTextField( + initialValue: state + .operations[index] + .name, + name: "object_name", + decoration: + normalTextFieldStyle( + "Operation name *", + "Operation name "), + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + initialValue: state + .operations[index] + .slug, + name: "slug", + decoration: + normalTextFieldStyle( + "Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + initialValue: state + .operations[index] + .shorthand, + validator: + FormBuilderValidators + .maxLength(50, + errorText: + "Max characters only 50"), + name: "shorthand", + decoration: + normalTextFieldStyle( + "Shorthand ", + "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, + Colors + .transparent, + second), + onPressed: () { + if (formKey + .currentState! + .saveAndValidate()) { + String name = formKey + .currentState! + .value[ + 'object_name']; + String? slug = formKey + .currentState! + .value['slug']; + String? short = formKey + .currentState! + .value[ + 'shorthand']; + + parent.read().add(UpdateRbacOperation( + operationId: state + .operations[ + index] + .id!, + name: name, + slug: slug, + short: + short, + createdBy: state + .operations[ + index] + .createdBy + ?.id, + updatedBy: + id)); + Navigator.pop( + context); + } + }, + child: const Text( + "Update"))), + ], + ), + ), + ); + }); + } + if (value == 1) { + confirmAlert(context, () { + context.read().add( + DeleteRbacOperation( + operationId: state + .operations[index].id!)); + }, "Delete?", "Confirm Delete?"); + } + }, + menuItems: [ + popMenuItem( + text: "Update", + value: 2, + icon: Icons.edit), + popMenuItem( + text: "Remove", + value: 1, + icon: Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ), + ], + ), + ), + const SizedBox( + height: 5, + ) + ], + ); + }); + } else { + return const EmptyData( + message: "No Role available. Please click + to add."); + } + } + if (state is OperationErrorState) { + return SomethingWentWrong( + message: state.toString(), + onpressed: () { + context.read().add(GetOperations()); + }); + } + return Container(); + }, + ), + ), + ); + } +} diff --git a/lib/screens/superadmin/permission/permission_screen.dart b/lib/screens/superadmin/permission/permission_screen.dart new file mode 100644 index 0000000..28e18c2 --- /dev/null +++ b/lib/screens/superadmin/permission/permission_screen.dart @@ -0,0 +1,283 @@ +import 'dart:math'; +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:multi_dropdown/multiselect_dropdown.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/permission/permission_bloc.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/screens/superadmin/role/shared_pop_up_menu.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import 'package:unit2/utils/global_context.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../theme-data.dart/box_shadow.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacPermissionScreen extends StatelessWidget { + final int id; + const RbacPermissionScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + List objects = []; + RBAC? selectedObject; + List operations = []; + List valueItemOperations = []; + List selectedValueItemOperations = []; + final formKey = GlobalKey(); + BuildContext? parent; + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + title: const Text("Permissions Screen"), + actions: [ + AddLeading(onPressed: () { + showDialog( + context: NavigationService.navigatorKey.currentState!.context, + builder: (BuildContext context) { + valueItemOperations = operations.map((e) { + return ValueItem(label: e.name!, value: e.name); + }).toList(); + return AlertDialog( + title: const Text("Add Permission"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderDropdown( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + name: "object", + decoration: + normalTextFieldStyle("Permission", "Permission"), + items: objects.isEmpty + ? [] + : objects.map((e) { + return DropdownMenuItem( + value: e, child: Text(e.name!)); + }).toList(), + onChanged: (RBAC? object) { + selectedObject = object; + }, + ), + const SizedBox( + height: 12, + ), + MultiSelectDropDown( + onOptionSelected: + (List selectedOptions) { + selectedValueItemOperations = selectedOptions; + }, + borderColor: Colors.grey, + borderWidth: 1, + borderRadius: 5, + hint: "Operations", + padding: const EdgeInsets.all(8), + options: valueItemOperations, + selectionType: SelectionType.multi, + chipConfig: + const ChipConfig(wrapType: WrapType.wrap), + dropdownHeight: 300, + optionTextStyle: const TextStyle(fontSize: 16), + selectedOptionIcon: + const Icon(Icons.check_circle), + ), + const SizedBox( + height: 12, + ), + SizedBox( + height: 50, + width: double.maxFinite, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate() && + selectedValueItemOperations + .isNotEmpty) { + int assignerId = id; + int objectId = selectedObject!.id!; + + List opIds = []; + for (var operation in operations) { + selectedValueItemOperations + .forEach((element) { + if (element.label.toLowerCase() == + operation.name?.toLowerCase()) { + opIds.add(operation.id!); + } + }); + } + opIds.forEach((element) { + print(element); + }); + Navigator.pop(context); + parent!.read().add( + AddRbacPermission( + assignerId: assignerId, + objectId: objectId, + operationIds: opIds)); + } + }, + child: const Text("Submit")), + ) + ], + )), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is PermissonLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is PermissionLoaded || + state is PermissionErrorState || + state is PermissionAddedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////Added State + if (state is PermissionAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetPermissions()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetPermissions()); + }); + } + } + ////Deleted State + if (state is PermissionDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Permission Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(GetPermissions()); + }); + } else { + errorAlert(context, "Delete Failed", "Permission Delete Failed", + () { + Navigator.of(context).pop(); + context.read().add(GetPermissions()); + }); + } + } + }, + builder: (context, state) { + parent = context; + if (state is PermissionLoaded) { + objects = state.objects; + operations = state.operations; + if (state.permissions.isNotEmpty) { + return ListView.builder( + padding: + const EdgeInsets.symmetric(vertical: 8, horizontal: 10), + itemCount: state.permissions.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + CircleAvatar( + child: Text('${index + 1}'), + ), + const SizedBox( + width: 12, + ), + Flexible( + child: Text( + "${state.permissions[index].object?.name} - ${state.permissions[index].operation?.name}", + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: primary)), + ), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + if (value == 1) { + + confirmAlert(context, () { + context.read().add( + DeleteRbacPermission( + permissionId: state.permissions[index].id!)); + }, "Delete?", "Confirm Delete?"); + + } + }, + menuItems: [ + + popMenuItem( + text: "Remove", + value: 1, + icon: Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ), + ], + ), + ), + const SizedBox( + height: 5, + ) + ], + ); + }); + } else { + return const EmptyData( + message: "No Permission available. Please click + to add."); + } + } + if (state is PermissionErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () {}); + } + return Container(); + }, + ), + ), + ); + } +} diff --git a/lib/screens/superadmin/role/role_screen.dart b/lib/screens/superadmin/role/role_screen.dart new file mode 100644 index 0000000..5c65a71 --- /dev/null +++ b/lib/screens/superadmin/role/role_screen.dart @@ -0,0 +1,373 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role/role_bloc.dart'; +import 'package:unit2/screens/superadmin/role/shared_pop_up_menu.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../theme-data.dart/box_shadow.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacRoleScreen extends StatelessWidget { + final int id; + const RbacRoleScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final formKey = GlobalKey(); + return Scaffold( + appBar: AppBar( + centerTitle: true, + backgroundColor: primary, + title: const Text("Role Screen"), + actions: [ + AddLeading(onPressed: () { + BuildContext parent = context; + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Add New Role"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderTextField( + name: "object_name", + decoration: normalTextFieldStyle( + "Role name *", "Role name "), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + name: "slug", + decoration: normalTextFieldStyle("Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + validator: FormBuilderValidators.maxLength(50, + errorText: "Max characters only 50"), + name: "shorthand", + decoration: + normalTextFieldStyle("Shorthand ", "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate()) { + String name = formKey + .currentState!.value['object_name']; + String? slug = + formKey.currentState!.value['slug']; + String? short = formKey + .currentState!.value['shorthand']; + parent.read().add(AddRbacRole( + id: id, + name: name, + shorthand: short, + slug: slug)); + Navigator.pop(context); + } + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is RoleLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is RoleLoadedState || + state is RoleErrorState || + state is RoleAddedState || + state is RoleDeletedState || + state is RoleUpdatedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////Added State + if (state is RoleAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRoles()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRoles()); + }); + } + } + ////Updated state + if (state is RoleUpdatedState) { + if (state.response['success']) { + successAlert( + context, "Updated Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRoles()); + }); + } else { + errorAlert(context, "Update Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRoles()); + }); + } + } + ////Deleted State + if (state is RoleDeletedState) { + if (state.success) { + successAlert( + context, "Delete Successfull!", "Role Deleted Successfully", + () { + Navigator.of(context).pop(); + context.read().add(GetRoles()); + }); + } else { + errorAlert(context, "Delete Failed", "Role Delete Failed", () { + Navigator.of(context).pop(); + context.read().add(GetRoles()); + }); + } + } + }, + builder: (context, state) { + final parent = context; + if (state is RoleLoadedState) { + if (state.roles.isNotEmpty) { + return ListView.builder( + padding: + const EdgeInsets.symmetric(vertical: 8, horizontal: 10), + itemCount: state.roles.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + CircleAvatar(child: Text('${index+1}'),), + const SizedBox(width: 12,), + Flexible( + child: Text(state.roles[index].name!, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: primary)), + ), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + if (value == 2) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text("Update Role"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: + MainAxisSize.min, + children: [ + FormBuilderTextField( + initialValue: state + .roles[index].name, + name: "object_name", + decoration: + normalTextFieldStyle( + "Role name *", + "Role name "), + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + initialValue: state + .roles[index].slug, + name: "slug", + decoration: + normalTextFieldStyle( + "Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + initialValue: state + .roles[index] + .shorthand, + validator: + FormBuilderValidators + .maxLength(50, + errorText: + "Max characters only 50"), + name: "shorthand", + decoration: + normalTextFieldStyle( + "Shorthand ", + "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, + Colors + .transparent, + second), + onPressed: () { + if (formKey + .currentState! + .saveAndValidate()) { + String name = formKey + .currentState! + .value[ + 'object_name']; + String? slug = formKey + .currentState! + .value['slug']; + String? short = formKey + .currentState! + .value[ + 'shorthand']; + + parent.read().add(UpdateRbacRole( + roleId: state + .roles[ + index] + .id!, + name: name, + slug: slug, + short: + short, + createdBy: state + .roles[ + index] + .createdBy + ?.id, + updatedBy: + id)); + Navigator.pop( + context); + } + }, + child: const Text( + "Update"))), + ], + ), + ), + ); + }); + } + if (value == 1) { + confirmAlert(context, () { + context.read().add( + DeleteRbacRole( + roleId: + state.roles[index].id!)); + }, "Delete?", "Confirm Delete?"); + } + }, + menuItems: [ + popMenuItem( + text: "Update", + value: 2, + icon: Icons.edit), + popMenuItem( + text: "Remove", + value: 1, + icon: Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ), + ], + ), + ), + const SizedBox( + height: 5, + ) + ], + ); + }); + } else { + return const EmptyData( + message: "No Role available. Please click + to add."); + } + } + if (state is RoleErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () { + context.read().add(GetRoles()); + }); + } + return Container(); + }, + ), + ), + ); + } +} diff --git a/lib/screens/superadmin/role/shared_pop_up_menu.dart b/lib/screens/superadmin/role/shared_pop_up_menu.dart new file mode 100644 index 0000000..3359c56 --- /dev/null +++ b/lib/screens/superadmin/role/shared_pop_up_menu.dart @@ -0,0 +1,21 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; + +PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { + return PopupMenuItem( + value: value, + child: Row( + children: [ + Icon( + icon, + ), + const SizedBox( + width: 10, + ), + Text( + text!, + ), + ], + ), + ); +} \ No newline at end of file diff --git a/lib/screens/superadmin/role_assignment.dart/role_assignment_screen.dart b/lib/screens/superadmin/role_assignment.dart/role_assignment_screen.dart new file mode 100644 index 0000000..a354473 --- /dev/null +++ b/lib/screens/superadmin/role_assignment.dart/role_assignment_screen.dart @@ -0,0 +1,289 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:fluttericon/font_awesome5_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:multi_dropdown/models/value_item.dart'; +import 'package:multi_dropdown/multiselect_dropdown.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role/role_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role_extend/role_extend_bloc.dart'; +import 'package:unit2/bloc/role_assignment/role_assignment_bloc.dart'; +import 'package:unit2/screens/superadmin/role/shared_pop_up_menu.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../model/rbac/rbac.dart'; +import '../../../theme-data.dart/box_shadow.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacRoleAssignment extends StatelessWidget { + final int id; + const RbacRoleAssignment({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final formKey = GlobalKey(); + List roles = []; + List valueItemRoles = []; + List selectedValueItemRoles = []; + return Scaffold( + appBar: AppBar( + centerTitle: true, + backgroundColor: primary, + title: const Text("User Roles Screen"), + actions: [ + AddLeading(onPressed: () { + BuildContext parent = context; + showDialog( + context: context, + builder: (BuildContext context) { + valueItemRoles = roles.map((e) { + return ValueItem(label: e.name!, value: e.name); + }).toList(); + return AlertDialog( + title: const Text("Add New Role"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + MultiSelectDropDown( + onOptionSelected: + (List selectedOptions) { + selectedValueItemRoles = selectedOptions; + }, + borderColor: Colors.grey, + borderWidth: 1, + borderRadius: 5, + hint: "Select Roles", + padding: const EdgeInsets.all(8), + options: valueItemRoles, + selectionType: SelectionType.multi, + chipConfig: + const ChipConfig(wrapType: WrapType.wrap), + dropdownHeight: 300, + optionTextStyle: const TextStyle(fontSize: 16), + selectedOptionIcon: const Icon(Icons.check_circle), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate()) { + List rolesId = []; + for (var role in roles) { + selectedValueItemRoles + .forEach((element) { + if (element.label.toLowerCase() == + role.name?.toLowerCase()) { + rolesId.add(role.id!); + } + }); + } + parent + .read() + .add(AssignRole( + assignerId: id, + roles: rolesId, + )); + Navigator.pop(context); + } + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is RoleAssignmentLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is AssignedRoleLoaded || + state is RoleAssignmentErrorState || + state is AssignedRoleDeletedState || + state is UserNotExistError || state is AssignedRoleAddedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + ////Deleted State + if (state is AssignedRoleDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Role Module Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(LoadAssignedRole()); + }); + } else { + errorAlert( + context, "Delete Failed", "Role Module Delete Failed", () { + Navigator.of(context).pop(); + context.read().add(LoadAssignedRole()); + }); + } + } + + ////Added State + if (state is AssignedRoleAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(LoadAssignedRole()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(LoadAssignedRole()); + }); + } + } + }, + builder: (context, state) { + final parent = context; + if (state is AssignedRoleLoaded) { + + roles = state.roles; + if (state.assignedRoles.isNotEmpty) { + return Column( + children: [ + ListTile( + tileColor: second, + leading: const Icon( + FontAwesome5.user_alt, + color: Colors.white, + ), + title: Text(state.fullname.toUpperCase(), + style: Theme.of(context) + .textTheme + .titleLarge! + .copyWith(color: Colors.white)), + subtitle: Text("Person full name", + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith(color: Colors.white)), + ), + Expanded( + child: ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.assignedRoles.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + width: screenWidth, + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + CircleAvatar( + child: Text('${index + 1}'), + ), + const SizedBox( + width: 12, + ), + Flexible( + child: Text( + state.assignedRoles[index].role! + .name, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight.w500, + color: primary)), + ), + ], + )), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + if (value == 1) { + confirmAlert(context, () { + context + .read() + .add(DeleteAssignRole( + roleId: state + .assignedRoles[index].id! + )); + }, "Delete?", "Confirm Delete?"); + } + }, + menuItems: [ + popMenuItem( + text: "Remove", + value: 1, + icon: Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ), + ], + ), + ), + const Divider(), + ], + ); + }), + ), + ], + ); + } else { + return const EmptyData( + message: "No Role available. Please click + to add."); + } + } + if (state is RoleAssignmentErrorState) { + return SomethingWentWrong( + message: state.message, + onpressed: () { + context.read().add(GetRoles()); + }); + } + if (state is UserNotExistError) { + return const Center( + child: Text("User Not Exsit"), + ); + } + return Container(); + }, + ), + ), + ); + } +} diff --git a/lib/screens/superadmin/role_extend/role_extend_screen.dart b/lib/screens/superadmin/role_extend/role_extend_screen.dart new file mode 100644 index 0000000..670c1d4 --- /dev/null +++ b/lib/screens/superadmin/role_extend/role_extend_screen.dart @@ -0,0 +1,296 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:group_list_view/group_list_view.dart'; +import 'package:multi_dropdown/multiselect_dropdown.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role_extend/role_extend_bloc.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../model/rbac/rbac.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global_context.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacRoleExtendScreen extends StatelessWidget { + final int id; + const RbacRoleExtendScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final parent = context; + Map> rolesExtend = {}; + List roles = []; + RBAC? selectedRole; + List valueItemRoles = []; + List selectedValueItemRoles = []; + final formKey = GlobalKey(); + return Scaffold( + appBar: AppBar( + elevation: 0, + backgroundColor: primary, + title: const Text("Role Extend"), + actions: [ + AddLeading(onPressed: () { + showDialog( + context: NavigationService.navigatorKey.currentState!.context, + builder: (BuildContext context) { + valueItemRoles = roles.map((e) { + return ValueItem(label: e.name!, value: e.name); + }).toList(); + return AlertDialog( + title: const Text("Add Role Extend"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderDropdown( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + name: "role", + decoration: normalTextFieldStyle( + "Role Extend Main", "Role Extend Main"), + items: roles.isEmpty + ? [] + : roles.map((e) { + return DropdownMenuItem( + value: e, child: Text(e.name!)); + }).toList(), + onChanged: (RBAC? role) { + selectedRole = role; + }, + ), + const SizedBox( + height: 12, + ), + MultiSelectDropDown( + onOptionSelected: + (List selectedOptions) { + selectedValueItemRoles = selectedOptions; + }, + borderColor: Colors.grey, + borderWidth: 1, + borderRadius: 5, + hint: "Roles Extend", + padding: const EdgeInsets.all(8), + options: valueItemRoles, + selectionType: SelectionType.multi, + chipConfig: + const ChipConfig(wrapType: WrapType.wrap), + dropdownHeight: 300, + optionTextStyle: const TextStyle(fontSize: 16), + selectedOptionIcon: + const Icon(Icons.check_circle), + ), + const SizedBox( + height: 12, + ), + SizedBox( + height: 50, + width: double.maxFinite, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate() && + selectedValueItemRoles.isNotEmpty) { + int roleId = selectedRole!.id!; + List rolesId = []; + for (var role in roles) { + selectedValueItemRoles + .forEach((element) { + if (element.label.toLowerCase() == + role.name?.toLowerCase()) { + rolesId.add(role.id!); + } + }); + } + Navigator.of(context).pop(); + rolesExtend = {}; + parent.read().add( + AddRoleExtend( + roleId: roleId, + roleExtendsId: rolesId)); + } + }, + child: const Text("Submit")), + ) + ], + )), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is RoleExtendLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is RoleExtendLoadedState || + state is RoleExtendAddedState || + state is RoleExtendDeletedState || + state is RoleExtendErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + + ////Deleted State + if (state is RoleExtendDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Role Module Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(GetRoleExtend()); + }); + } else { + errorAlert( + context, "Delete Failed", "Role Module Delete Failed", () { + Navigator.of(context).pop(); + context.read().add(GetRoleExtend()); + }); + } + } + ////Added State + if (state is RoleExtendAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRoleExtend()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRoleExtend()); + }); + } + } + }, + builder: (context, state) { + if (state is RoleExtendLoadedState) { + rolesExtend = {}; + roles = state.roles; + + if (state.rolesExtend.isNotEmpty) { + for (var roleExt in state.rolesExtend) { + if (!rolesExtend.keys + .contains(roleExt.roleExtendMain.name!.toLowerCase())) { + rolesExtend.addAll( + {roleExt.roleExtendMain.name!.toLowerCase(): []}); + rolesExtend[roleExt.roleExtendMain.name!.toLowerCase()]! + .add(Content( + id: roleExt.id, + name: roleExt.roleExtendChild.name!)); + } else { + rolesExtend[roleExt.roleExtendMain.name!.toLowerCase()]! + .add(Content( + id: roleExt.id, + name: roleExt.roleExtendChild.name!)); + } + } + } + + if (state.rolesExtend.isNotEmpty) { + return GroupListView( + padding: const EdgeInsets.all(0), + sectionsCount: rolesExtend.keys.toList().length, + countOfItemInSection: (int section) { + return rolesExtend.values.toList()[section].length; + }, + itemBuilder: (BuildContext context, IndexPath index) { + return ListTile( + dense: true, + trailing: IconButton( + color: Colors.grey.shade600, + icon: const Icon(Icons.delete), + onPressed: () { + confirmAlert(context, () { + context.read().add(DeleteRoleExtend( + roleExtendId: rolesExtend.values + .toList()[index.section][index.index] + .id)); + }, "Delete?", "Confirm Delete?"); + }, + ), + title: Row( + children: [ + CircleAvatar( + child: Text("${index.index + 1}", + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith(color: Colors.white))), + const SizedBox( + width: 20, + ), + Expanded( + child: Text( + rolesExtend.values + .toList()[index.section][index.index] + .name + .toUpperCase(), + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith( + fontWeight: FontWeight.w500, + color: primary), + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return const Divider(); + }, + groupHeaderBuilder: (BuildContext context, int section) { + return ListTile( + tileColor: second, + title: Text( + rolesExtend.keys.toList()[section].toUpperCase(), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(color: Colors.white), + ), + ); + }, + ); + } else { + return const EmptyData( + message: "No Role available. Please click + to add."); + } + } + if (state is RoleExtendErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () {}); + } + return Container(); + }, + ), + ), + ); + } +} + +class Content { + final int id; + final String name; + const Content({required this.id, required this.name}); +} diff --git a/lib/screens/superadmin/role_module/role_module_scree.dart b/lib/screens/superadmin/role_module/role_module_scree.dart new file mode 100644 index 0000000..58521bf --- /dev/null +++ b/lib/screens/superadmin/role_module/role_module_scree.dart @@ -0,0 +1,289 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:group_list_view/group_list_view.dart'; +import 'package:multi_dropdown/multiselect_dropdown.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/module_objects/module_objects_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role_module/role_module_bloc.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../model/rbac/rbac.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global_context.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacRoleModuleScreen extends StatelessWidget { + final int id; + const RbacRoleModuleScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final parent = context; + Map> roleModules = {}; + List modules = []; + List roles = []; + RBAC? selectedRole; + List valueItemModules = []; + List selectedValueItemModules = []; + final formKey = GlobalKey(); + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + title: const Text("Role Modules Screen"), + actions: [ + AddLeading(onPressed: () { + showDialog( + context: NavigationService.navigatorKey.currentState!.context, + builder: (BuildContext context) { + valueItemModules = modules.map((e) { + return ValueItem(label: e.name!, value: e.name); + }).toList(); + return AlertDialog( + title: const Text("Add Role Module"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderDropdown( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + name: "role", + decoration: normalTextFieldStyle("Role", "Role"), + items: roles.isEmpty + ? [] + : roles.map((e) { + return DropdownMenuItem( + value: e, child: Text(e.name!)); + }).toList(), + onChanged: (RBAC? role) { + selectedRole = role; + }, + ), + const SizedBox( + height: 12, + ), + MultiSelectDropDown( + onOptionSelected: + (List selectedOptions) { + selectedValueItemModules = selectedOptions; + }, + borderColor: Colors.grey, + borderWidth: 1, + borderRadius: 5, + hint: "Modules", + padding: const EdgeInsets.all(8), + options: valueItemModules, + selectionType: SelectionType.multi, + chipConfig: + const ChipConfig(wrapType: WrapType.wrap), + dropdownHeight: 300, + optionTextStyle: const TextStyle(fontSize: 16), + selectedOptionIcon: + const Icon(Icons.check_circle), + ), + const SizedBox( + height: 12, + ), + SizedBox( + height: 50, + width: double.maxFinite, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate() && + selectedValueItemModules.isNotEmpty) { + int assignerId = id; + int roleId = selectedRole!.id!; + List modulesId = []; + for (var module in modules) { + selectedValueItemModules + .forEach((element) { + if (element.label.toLowerCase() == + module.name?.toLowerCase()) { + modulesId.add(module.id!); + } + }); + } + Navigator.of(context).pop(); + parent.read().add( + AddRoleModule( + assignerId: assignerId, + roleId: roleId, + moduleIds: modulesId)); + } + }, + child: const Text("Submit")), + ) + ], + )), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is RoleModuleLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is RoleModuleLoadedState || + state is RoleModuleErrorState || + state is RoleModuleDeletedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + + ////Deleted State + if (state is RoleModuleDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Role Module Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(GetRoleModules()); + }); + } else { + errorAlert( + context, "Delete Failed", "Role Module Delete Failed", () { + Navigator.of(context).pop(); + context.read().add(GetRoleModules()); + }); + } + } + ////Added State + if (state is RoleModuleAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRoleModules()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRoleModules()); + }); + } + } + }, + builder: (context, state) { + if (state is RoleModuleLoadedState) { + modules = state.modules; + roles = state.roles; + roleModules = {}; + if (state.roleModules.isNotEmpty) { + for (var roleMod in state.roleModules) { + if (!roleModules.keys + .contains(roleMod.role!.name!.toLowerCase())) { + roleModules.addAll({roleMod.role!.name!.toLowerCase(): []}); + roleModules[roleMod.role!.name!.toLowerCase()]!.add( + Content(id: roleMod.id!, name: roleMod.module!.name!)); + } else { + roleModules[roleMod.role!.name!.toLowerCase()]!.add( + Content(id: roleMod.id!, name: roleMod.module!.name!)); + } + } + } + + if (state.roleModules.isNotEmpty) { + return GroupListView( + sectionsCount: roleModules.keys.toList().length, + countOfItemInSection: (int section) { + return roleModules.values.toList()[section].length; + }, + itemBuilder: (BuildContext context, IndexPath index) { + return ListTile( + dense: true, + trailing: IconButton( + color: Colors.grey.shade600, + icon: const Icon(Icons.delete), + onPressed: () { + confirmAlert(context, () { + context.read().add(DeleteRoleModule( + roleModuleId: roleModules.values + .toList()[index.section][index.index] + .id)); + }, "Delete?", "Confirm Delete?"); + }, + ), + title: Row( + children: [ + CircleAvatar( + child: Text("${index.index + 1}", + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith(color: Colors.white))), + const SizedBox( + width: 20, + ), + Expanded( + child: Text( + roleModules.values + .toList()[index.section][index.index] + .name + .toUpperCase(), + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith(color: primary), + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return const Divider(); + }, + groupHeaderBuilder: (BuildContext context, int section) { + return ListTile( + tileColor: second, + title: Text( + roleModules.keys.toList()[section].toUpperCase(), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(color: Colors.white), + ), + ); + }, + ); + } else { + return const EmptyData( + message: "No Role available. Please click + to add."); + } + } + if (state is RoleModuleErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () {}); + } + return Container(); + }, + ), + ), + ); + } +} + +class Content { + final int id; + final String name; + const Content({required this.id, required this.name}); +} diff --git a/lib/screens/superadmin/roles_under/roles_under_screen.dart b/lib/screens/superadmin/roles_under/roles_under_screen.dart new file mode 100644 index 0000000..a085fc5 --- /dev/null +++ b/lib/screens/superadmin/roles_under/roles_under_screen.dart @@ -0,0 +1,294 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:group_list_view/group_list_view.dart'; +import 'package:multi_dropdown/multiselect_dropdown.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role_module/role_module_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/roles_under/roles_under_bloc.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../model/rbac/rbac.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/global_context.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacRoleUnderScreen extends StatelessWidget { + final int id; + const RbacRoleUnderScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final parent = context; + Map> rolesUnder = {}; + List roles = []; + RBAC? selectedRole; + List valueItemRoles = []; + List selectedValueItemRoles = []; + final formKey = GlobalKey(); + return Scaffold( + appBar: AppBar( + backgroundColor: primary, + title: const Text("Role Module"), + actions: [ + AddLeading(onPressed: () { + showDialog( + context: NavigationService.navigatorKey.currentState!.context, + builder: (BuildContext context) { + valueItemRoles = roles.map((e) { + return ValueItem(label: e.name!, value: e.name); + }).toList(); + return AlertDialog( + title: const Text("Add Role Under"), + content: FormBuilder( + key: formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderDropdown( + validator: FormBuilderValidators.required( + errorText: "This field is required"), + name: "role", + decoration: normalTextFieldStyle( + "Main Role", "Main Role"), + items: roles.isEmpty + ? [] + : roles.map((e) { + return DropdownMenuItem( + value: e, child: Text(e.name!)); + }).toList(), + onChanged: (RBAC? role) { + selectedRole = role; + }, + ), + const SizedBox( + height: 12, + ), + MultiSelectDropDown( + onOptionSelected: + (List selectedOptions) { + selectedValueItemRoles = selectedOptions; + }, + borderColor: Colors.grey, + borderWidth: 1, + borderRadius: 5, + hint: "Roles Under", + padding: const EdgeInsets.all(8), + options: valueItemRoles, + selectionType: SelectionType.multi, + chipConfig: + const ChipConfig(wrapType: WrapType.wrap), + dropdownHeight: 300, + optionTextStyle: const TextStyle(fontSize: 16), + selectedOptionIcon: + const Icon(Icons.check_circle), + ), + const SizedBox( + height: 12, + ), + SizedBox( + height: 50, + width: double.maxFinite, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate() && + selectedValueItemRoles.isNotEmpty) { + int assignerId = id; + int roleId = selectedRole!.id!; + List rolesId = []; + for (var role in roles) { + selectedValueItemRoles + .forEach((element) { + if (element.label.toLowerCase() == + role.name?.toLowerCase()) { + rolesId.add(role.id!); + } + }); + } + Navigator.of(context).pop(); + parent.read().add( + AddRoleUnder( + roleId: roleId, + roleUnderIds: rolesId)); + } + }, + child: const Text("Submit")), + ) + ], + )), + ); + }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is RoleUnderLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is RoleUnderLoadedState || + state is RoleUnderErrorState || + state is RoleUnderDeletedState || + state is RoleUnderAddedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + + ////Deleted State + if (state is RoleUnderDeletedState) { + if (state.success) { + successAlert(context, "Delete Successfull!", + "Role Module Deleted Successfully", () { + Navigator.of(context).pop(); + context.read().add(GetRolesUnder()); + }); + } else { + errorAlert( + context, "Delete Failed", "Role Module Delete Failed", () { + Navigator.of(context).pop(); + context.read().add(GetRolesUnder()); + }); + } + } + ////Added State + if (state is RoleUnderAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRolesUnder()); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context.read().add(GetRolesUnder()); + }); + } + } + }, + builder: (context, state) { + if (state is RoleUnderLoadedState) { + rolesUnder = {}; + roles = state.roles; + + if (state.rolesUnder.isNotEmpty) { + for (var roleUnder in state.rolesUnder) { + if (!rolesUnder.keys + .contains(roleUnder.roleUnderMain.name!.toLowerCase())) { + rolesUnder.addAll( + {roleUnder.roleUnderMain.name!.toLowerCase(): []}); + rolesUnder[roleUnder.roleUnderMain.name!.toLowerCase()]! + .add(Content( + id: roleUnder.id, + name: roleUnder.roleUnderChild.name!)); + } else { + rolesUnder[roleUnder.roleUnderMain.name!.toLowerCase()]! + .add(Content( + id: roleUnder.id, + name: roleUnder.roleUnderChild.name!)); + } + } + } + + if (state.rolesUnder.isNotEmpty) { + return GroupListView( + sectionsCount: rolesUnder.keys.toList().length, + countOfItemInSection: (int section) { + return rolesUnder.values.toList()[section].length; + }, + itemBuilder: (BuildContext context, IndexPath index) { + return ListTile( + trailing: IconButton( + color: Colors.grey.shade500, + icon: const Icon(Icons.delete), + onPressed: () { + context.read().add(DeleteRoleUnder( + roleUnderId: rolesUnder.values + .toList()[index.section][index.index] + .id)); + }, + ), + title: Row( + children: [ + CircleAvatar( + child: Text("${index.index + 1}", + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith(color: Colors.white))), + const SizedBox( + width: 20, + ), + Expanded( + child: Text( + rolesUnder.values + .toList()[index.section][index.index] + .name + .toUpperCase(), + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith( + fontWeight: FontWeight.w500, + color: primary) + ), + ), + ], + ), + ); + }, + separatorBuilder: (context, index) { + return const Divider(); + }, + groupHeaderBuilder: (BuildContext context, int section) { + return ListTile( +tileColor: Colors.white, + dense: true, + title: Text( + rolesUnder.keys.toList()[section].toUpperCase(), + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith(color: primary,fontWeight: FontWeight.bold), + ), + ); + }, + ); + } else { + return const EmptyData( + message: "No Role available. Please click + to add."); + } + } + if (state is RoleUnderErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () {}); + } + return Container(); + }, + ), + ), + ); + } +} + +class Content { + final int id; + final String name; + const Content({required this.id, required this.name}); +} diff --git a/lib/screens/superadmin/stations/stations_screen.dart b/lib/screens/superadmin/stations/stations_screen.dart new file mode 100644 index 0000000..41f8ca3 --- /dev/null +++ b/lib/screens/superadmin/stations/stations_screen.dart @@ -0,0 +1,289 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role/role_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/station/station_bloc.dart'; +import 'package:unit2/model/rbac/rbac_station.dart'; +import 'package:unit2/screens/superadmin/role/shared_pop_up_menu.dart'; +import 'package:unit2/widgets/Leadings/add_leading.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../model/utils/agency.dart'; +import '../../../theme-data.dart/box_shadow.dart'; +import '../../../theme-data.dart/btn-style.dart'; +import '../../../theme-data.dart/colors.dart'; +import '../../../theme-data.dart/form-style.dart'; +import '../../../utils/alerts.dart'; +import '../../../utils/formatters.dart'; +import '../../../utils/global.dart'; +import '../../../widgets/empty_data.dart'; + +class RbacStationScreen extends StatelessWidget { + final int id; + const RbacStationScreen({super.key, required this.id}); + + @override + Widget build(BuildContext context) { + final agencyFocusNode = FocusNode(); + List stations = []; + final formKey = GlobalKey(); + Agency selectedAgency; + return Scaffold( + appBar: AppBar( + centerTitle: true, + backgroundColor: primary, + title: const Text("Station Screen"), + actions: [ + AddLeading(onPressed: () { + BuildContext parent = context; + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return AlertDialog( + // title: const Text("Add New Station"), + // content: FormBuilder( + // key: formKey, + // child: Column( + // mainAxisSize: MainAxisSize.min, + // children: [ + // FormBuilderTextField( + // name: "object_name", + // decoration: normalTextFieldStyle( + // "Role name *", "Role name "), + // validator: FormBuilderValidators.required( + // errorText: "This field is required"), + // ), + // const SizedBox( + // height: 8, + // ), + // FormBuilderTextField( + // name: "slug", + // decoration: normalTextFieldStyle("Slug ", "Slug"), + // ), + // const SizedBox( + // height: 8, + // ), + // FormBuilderTextField( + // validator: FormBuilderValidators.maxLength(50, + // errorText: "Max characters only 50"), + // name: "shorthand", + // decoration: + // normalTextFieldStyle("Shorthand ", "Shorthand"), + // ), + // const SizedBox( + // height: 12, + // ), + // SizedBox( + // width: double.infinity, + // height: 50, + // child: ElevatedButton( + // style: mainBtnStyle( + // primary, Colors.transparent, second), + // onPressed: () { + // if (formKey.currentState! + // .saveAndValidate()) { + // String name = formKey + // .currentState!.value['object_name']; + // String? slug = + // formKey.currentState!.value['slug']; + // String? short = formKey + // .currentState!.value['shorthand']; + // parent.read().add(AddRbacRole( + // id: id, + // name: name, + // shorthand: short, + // slug: slug)); + // Navigator.pop(context); + // } + // }, + // child: const Text("Add"))), + // ], + // ), + // ), + // ); + // }); + }) + ], + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) {}, + builder: (context, state) { + final parent = context; + if (state is StationLoadedState) { + stations = state.stations; + if (state.stations.isNotEmpty) { + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(8), + child: SearchField( + inputFormatters: [UpperCaseTextFormatter()], + itemHeight: 70, + focusNode: agencyFocusNode, + suggestions: state.agencies + .map((Agency agency) => + SearchFieldListItem(agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: TextOverflow.visible, + ), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle("Filter", "").copyWith( + prefixIcon: const Icon(Icons.filter_list), + suffixIcon: IconButton( + icon: const Icon(Icons.arrow_drop_down), + onPressed: () { + agencyFocusNode.unfocus(); + }, + )), + onSuggestionTap: (agency) { + agencyFocusNode.unfocus(); + selectedAgency = agency.item!; + parent.read().add( + FilterStation(agencyId: selectedAgency.id!)); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + emptyWidget: const Center( + child: Text("No result found..."), + )), + ), + Expanded( + child: ListView.builder( + padding: const EdgeInsets.symmetric( + vertical: 8, horizontal: 10), + itemCount: state.stations.length, + itemBuilder: (BuildContext context, int index) { + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 8), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + CircleAvatar( + child: Text('${index + 1}'), + ), + const SizedBox( + width: 12, + ), + Flexible( + child: Text( + state.stations[index] + .stationName!, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight.w500, + color: primary)), + ), + ], + )), + ], + ), + ), + const SizedBox( + height: 3, + ) + ], + ); + }), + ), + ], + ); + } else { + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(8), + child: SearchField( + + inputFormatters: [UpperCaseTextFormatter()], + itemHeight: 70, + focusNode: agencyFocusNode, + suggestions: state.agencies + .map((Agency agency) => + SearchFieldListItem(agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: TextOverflow.visible, + ), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle("Filter", "").copyWith( + prefixIcon: const Icon(Icons.filter_list), + suffixIcon: IconButton( + icon: const Icon(Icons.arrow_drop_down), + onPressed: () { + agencyFocusNode.unfocus(); + }, + )), + onSuggestionTap: (agency) { + agencyFocusNode.unfocus(); + selectedAgency = agency.item!; + parent.read().add( + FilterStation(agencyId: selectedAgency.id!)); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + emptyWidget: const Center( + child: Text("No result found..."), + )), + ), + const SizedBox( + height: 20, + ), + const EmptyData( + message: + "No Station available. Please click + to add."), + ], + ); + } + } + if (state is StationErrorState) { + return SomethingWentWrong( + message: state.message, + onpressed: () { + context.read().add(GetRoles()); + }); + } + if (state is StationLoadingState) { + return CircularProgressIndicator(); + } + return Container(); + }, + ), + ), + ); + } +} diff --git a/lib/screens/unit2/basic-info/basic-info.dart b/lib/screens/unit2/basic-info/basic-info.dart index 2194b21..07539a4 100644 --- a/lib/screens/unit2/basic-info/basic-info.dart +++ b/lib/screens/unit2/basic-info/basic-info.dart @@ -7,6 +7,7 @@ import 'package:intl/intl.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:signature/signature.dart'; import 'package:unit2/model/login_data/user_info/user_data.dart'; +import 'package:unit2/screens/unit2/basic-info/components/qr_image.dart'; import 'package:unit2/theme-data.dart/btn-style.dart'; import 'package:unit2/utils/global.dart'; import 'package:unit2/utils/text_container.dart'; @@ -115,8 +116,9 @@ class BuildInformation extends StatelessWidget { final String firstName = userData.user!.login!.user!.firstName!.toUpperCase(); final String lastname = userData.user!.login!.user!.lastName!.toUpperCase(); - final String? middlename = userData.employeeInfo == null?'': - userData.employeeInfo!.profile?.middleName?.toUpperCase(); + final String? middlename = userData.employeeInfo == null + ? '' + : userData.employeeInfo!.profile?.middleName?.toUpperCase(); final String sex = userData.employeeInfo!.profile!.sex!.toUpperCase(); final DateTime? bday = userData.employeeInfo!.profile!.birthdate; final uuid = userData.employeeInfo!.uuid; @@ -129,7 +131,7 @@ class BuildInformation extends StatelessWidget { height: 25, ), Text( - "$firstName ${middlename??''} $lastname", + "$firstName ${middlename ?? ''} $lastname", textAlign: TextAlign.center, style: Theme.of(context) .textTheme @@ -141,27 +143,37 @@ class BuildInformation extends StatelessWidget { ), Text( "${dteFormat2.format(bday!)} | $sex", - style: Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 18), + style: + Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 18), ), const SizedBox( height: 15, ), - QrImage( - data: uuid!, - size: blockSizeVertical * 30, + GestureDetector( + onTap: () { + Navigator.push(context, + MaterialPageRoute(builder: (BuildContext context) { + return QRFullScreenImage(uuid: uuid); + })); + }, + child: QrImage( + data: uuid!, + size: blockSizeVertical * 24, + ), ), const SizedBox( height: 25, ), SizedBox( width: screenWidth * .60, - height: blockSizeVertical * 6, + height: blockSizeVertical * 7, child: SizedBox( child: ElevatedButton.icon( style: mainBtnStyle(third, Colors.transparent, Colors.white54), onPressed: () { - Navigator.push(context, MaterialPageRoute(builder: (BuildContext context){ + Navigator.push(context, + MaterialPageRoute(builder: (BuildContext context) { return const SignaturePad(); })); }, diff --git a/lib/screens/unit2/basic-info/components/qr_image.dart b/lib/screens/unit2/basic-info/components/qr_image.dart new file mode 100644 index 0000000..6cd2d39 --- /dev/null +++ b/lib/screens/unit2/basic-info/components/qr_image.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:qr_flutter/qr_flutter.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/utils/global.dart'; + +class QRFullScreenImage extends StatelessWidget { + final String uuid; + const QRFullScreenImage({super.key, required this.uuid}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + centerTitle: true, + backgroundColor: primary,title: const Text("Profile QR Code"),), + body: Center( + child: QrImage( + data: uuid, + size: blockSizeVertical * 50 + ), + ),); + } +} \ No newline at end of file diff --git a/lib/screens/unit2/homepage.dart/components/dashboard.dart b/lib/screens/unit2/homepage.dart/components/dashboard.dart deleted file mode 100644 index e1056ac..0000000 --- a/lib/screens/unit2/homepage.dart/components/dashboard.dart +++ /dev/null @@ -1,272 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:fluttericon/font_awesome5_icons.dart'; -import 'package:unit2/screens/docsms/index.dart'; -import 'package:unit2/screens/unit2/homepage.dart/module-screen.dart'; -import 'package:unit2/theme-data.dart/colors.dart'; -import 'package:unit2/utils/global.dart'; -import 'package:unit2/utils/global_context.dart'; -import 'package:unit2/utils/qr_scanner.dart'; -import '../../../../bloc/docsms/docsms_bloc.dart'; - -class DashBoard extends StatelessWidget { - final List roles; - final int userId; - const DashBoard({super.key, required this.roles,required this.userId}); - @override - Widget build(BuildContext context) { - List finishRoles = []; - return Container( - padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 24), - height: MediaQuery.of(context).size.height, - ////listview builder - child: ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - itemCount: roles.length, - itemBuilder: (BuildContext context, int index) { - - //// gridview.count - return roles[index].roles.isNotEmpty - ? SizedBox( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - roles[index].name.toUpperCase(), - style: Theme.of(context) - .textTheme - .labelLarge! - .copyWith(fontSize: 12), - ), - const SizedBox( - height: 8, - ), - GridView.count( - shrinkWrap: true, - crossAxisCount: 4, - crossAxisSpacing: 8, - mainAxisSpacing: 10, - physics: const BouncingScrollPhysics(), - padding: const EdgeInsets.symmetric( - vertical: 5, horizontal: 5), - children: roles[index].roles.map((role) { - if (role.role.name!.toLowerCase() == - 'qr code scanner' && - !finishRoles.contains("security")) { - print("1 true"); - finishRoles.add('scanner'); - for (var element in role.role.modules!) { - if (element!.name!.toLowerCase() == 'unit2') { - for (var element in element.objects!) { - if (element!.id == 9 && - element.operations! - .contains("read")) { - return CardLabel( - ontap: () { - PassCheckArguments passCheckArguments = PassCheckArguments(roleId: role.role.id!, userId: userId); - Navigator.pushNamed(context, '/pass-check',arguments: passCheckArguments); - }, - icon: role.icon, - title: "Pass Check", - ); - } - } - } - } - return Container(); - } else if (role.role.name!.toLowerCase() == - 'security guard' && - !finishRoles.contains('scanner')) { - print("2 true"); - finishRoles.add('security'); - for (var element in role.role.modules!) { - if (element!.name!.toLowerCase() == 'unit2') { - for (var element in element.objects!) { - if (element!.id == 9 && - element.operations! - .contains("read")) { - return CardLabel( - ontap: () {}, - icon: role.icon, - title: "Pass Check", - ); - } - } - } - } - return Container(color: Colors.red,); - } else if (role.role.name!.toLowerCase() == - 'field surveyor') { - print("3 true"); - for (var element in role.role.modules!) { - if (element!.name!.toLowerCase() == 'rpass') { - for (var element in element.objects!) { - if (element!.id == 11 && - element.operations! - .contains("read")) { - return CardLabel( - ontap: () {}, - icon: role.icon, - title: "Field Surveyor", - ); - } - } - } - } - return Container(); - } else if (role.role.name!.toLowerCase() == - 'process server') { - print("4 true"); - for (var element in role.role.modules!) { - if (element!.name!.toLowerCase() == - 'document management') { - for (var element in element.objects!) { - if (element!.id == 3 && - element.operations! - .contains("read")) { - return CardLabel( - ontap: () async { - String? qrBarcode = - await qrScanner(); - if (qrBarcode != null) { - Navigator.push(NavigationService.navigatorKey.currentContext!, MaterialPageRoute(builder: - (BuildContext context) { - return BlocProvider( - create: (context) => DocsmsBloc() - ..add(LoadDocument( - documentId: qrBarcode)), - child: - const AutoReceiveDocument(), - ); - })); - } - }, - icon: role.icon, - title: "Process Server", - ); - } - } - } - } - return Container(); - } else if (role.role.name!.toLowerCase() == - 'establishment point-person' && - !finishRoles.contains('superadmin')) { - finishRoles.add('establishment point-person'); - for (var element in role.role.modules!) { - print("5 true"); - if (element!.name!.toLowerCase() == 'unit2') { - for (var element in element.objects!) { - if (element!.id == 7 && - element.operations! - .contains("upload")) { - return CardLabel( - ontap: () {}, - icon: FontAwesome5.building, - title: "Establishment", - ); - } - } - } - } - return Container(); - - } else if (role.role.name!.toLowerCase() == - 'establishment point-person' && - !finishRoles.contains('superadmin')) { - finishRoles.add('establishment point-person'); - for (var element in role.role.modules!) { - if (element!.name!.toLowerCase() == 'unit2') { - for (var element in element.objects!) { - if (element!.id == 7 && - element.operations! - .contains("upload")) { - return CardLabel( - ontap: () {}, - icon: FontAwesome5.building, - title: "Establishment", - ); - } - } - } - } - return Container(); - - } else{ - return Wrap(); - } - - - }).toList()), - const SizedBox( - height: 8, - ) - ], - ), - ) - : Container(); - }), - ); - } -} - -class PassCheckArguments{ - final int roleId; - final int userId; - const PassCheckArguments({required this.roleId, required this.userId}); -} - -// ignore: must_be_immutable -class CardLabel extends StatelessWidget { - final String title; - final IconData icon; - final Function()? ontap; - const CardLabel( - {super.key, - required this.icon, - required this.title, - required this.ontap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: ontap, - child: Container( - padding: const EdgeInsetsDirectional.fromSTEB(8, 5, 8, 13), - alignment: Alignment.center, - decoration: const BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(color: Colors.black12, spreadRadius: 2, blurRadius: 3) - ], - borderRadius: BorderRadius.all(Radius.circular(8))), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Expanded( - child: Icon( - icon, - size: 20, - weight: 100, - grade: 100, - color: second, - ), - ), - const SizedBox( - height: 5, - ), - Text( - title, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.labelLarge!.copyWith( - fontSize: blockSizeVertical * 1.2, - fontWeight: FontWeight.bold), - ), - ]), - ), - ); - } -} diff --git a/lib/screens/unit2/homepage.dart/components/dashboard/dashboard.dart b/lib/screens/unit2/homepage.dart/components/dashboard/dashboard.dart new file mode 100644 index 0000000..efeb14d --- /dev/null +++ b/lib/screens/unit2/homepage.dart/components/dashboard/dashboard.dart @@ -0,0 +1,479 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; +import 'package:fluttericon/font_awesome5_icons.dart'; +import 'package:unit2/screens/unit2/homepage.dart/components/dashboard/dashboard_icon_generator.dart'; +import 'package:unit2/screens/unit2/homepage.dart/components/dashboard/superadmin_expanded_menu.dart'; +import 'package:unit2/screens/unit2/homepage.dart/module-screen.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import './shared_card_label.dart'; + +class DashBoard extends StatefulWidget { + final List cards; + final int userId; + const DashBoard({super.key, required this.cards, required this.userId}); + + @override + State createState() => _DashBoardState(); +} + +List finishRoles = []; +List unit2Cards = []; +List superadminCards = []; +List rpassCards = []; +List docSmsCards = []; +List tempSuperAdminCards = []; +List tempUnit2Cards = []; + +class _DashBoardState extends State { + @override + Widget build(BuildContext context) { + setState(() { + finishRoles.clear(); + unit2Cards.clear(); + superadminCards.clear(); + rpassCards.clear(); + docSmsCards.clear(); + tempSuperAdminCards.clear(); + }); + widget.cards.forEach((e) { + if (e.moduleName == "unit2") { + if (!finishRoles.contains(e.object.name)) { + unit2Cards.add(e); + } + finishRoles.add(e.object.name!); + } + if (e.moduleName == 'superadmin') { + superadminCards.add(e); + } + if (e.moduleName == 'rpass') { + rpassCards.add(e); + } + if (e.moduleName == 'document management') { + docSmsCards.add(e); + } + }); + + if (superadminCards.length > 3) { + tempSuperAdminCards = superadminCards.sublist(0, 4); + } + if (unit2Cards.length > 3) { + tempUnit2Cards = unit2Cards.sublist(0, 4); + } + + return Container( + padding: + const EdgeInsetsDirectional.symmetric(vertical: 24, horizontal: 24), + child: ListView( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ////unit2 module operations + Container(child: unit2Cards.isEmpty?const SizedBox():Text( + "Unit2 module operations", + style: Theme.of(context).textTheme.displaySmall!.copyWith( + fontSize: 16, color: primary, fontWeight: FontWeight.w300), + ),), + SizedBox( + height: unit2Cards.isEmpty?0: 8, + ), + Container(child: unit2Cards.isEmpty?const SizedBox():GridView.count( + shrinkWrap: true, + crossAxisCount: 4, + crossAxisSpacing: 8, + mainAxisSpacing: 10, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5), + children: unit2Cards.length > 3 + ? tempUnit2Cards.map(( + e, + ) { + int index = tempUnit2Cards.indexOf(e); + //// if unit2 cards is less then 3 + return Container( + child: index == 3 + ? CardLabel( + icon: FontAwesome5.chevron_circle_right, + title: "See More", + ontap: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text( + "Unit2 Admin Module Operations", + textAlign: TextAlign.center, + ), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + SizedBox( + height: 200, + width: double.maxFinite, + child: GridView.count( + shrinkWrap: true, + crossAxisCount: 3, + crossAxisSpacing: 8, + mainAxisSpacing: 10, + physics: + const BouncingScrollPhysics(), + padding: + const EdgeInsets + .symmetric( + vertical: 5, + horizontal: 5), + children: + unit2Cards.map(( + e, + ) { + int index = unit2Cards + .indexOf(e); + //// if unit2 cards is less then 3 + return AnimationConfiguration + .staggeredGrid( + position: index, + columnCount: 3, + child: + ScaleAnimation( + child: + FadeInAnimation( + child: Container( + child: (e.roleName == 'superadmin' || e.roleName == 'qr code scanner' || e.roleName == 'security guard' || e.roleName == 'establishment point-person' || e.roleName == 'registration in-charge') && e.moduleName == 'unit2' + ? CardLabel( + icon: iconGenerator(name: e.object.name!), + title: e.object.name!.toLowerCase() == 'role based access control' + ? "RBAC" + : e.object.name!.toLowerCase() == "person basic information" + ? "Basic Info" + : e.object.name!, + ontap: () { + if (e.object.name!.toLowerCase() == 'pass check') { + PassCheckArguments passCheckArguments = PassCheckArguments(roleId: 10, userId: widget.userId); + Navigator.pushNamed(context, '/pass-check', arguments: passCheckArguments); + } + if (e.object.name!.toLowerCase() == 'role based access control') { + Navigator.pushNamed(context, '/rbac'); + } + }) + : Container( + color: + Colors.black, + )), + ), + ), + ); + }).toList()), + ), + ], + ), + ); + }); + }) + : (e.roleName == 'superadmin' || + e.roleName == 'qr code scanner' || + e.roleName == 'security guard' || + e.roleName == + 'establishment point-person' || + e.roleName == + 'registration in-charge') && + e.moduleName == 'unit2' + ? CardLabel( + icon: + iconGenerator(name: e.object.name!), + title: e.object.name!.toLowerCase() == + 'role based access control' + ? "RBAC" + : e.object.name!.toLowerCase() == + "person basic information" + ? "Basic Info" + : e.object.name!, + ontap: () { + if (e.object.name!.toLowerCase() == + 'pass check') { + PassCheckArguments + passCheckArguments = + PassCheckArguments( + roleId: 10, + userId: widget.userId); + Navigator.pushNamed( + context, '/pass-check', + arguments: passCheckArguments); + } + if (e.object.name!.toLowerCase() == + 'role based access control') { + Navigator.pushNamed( + context, '/rbac'); + } + }) + : Container( + color: Colors.black, + )); + }).toList() + : unit2Cards.map(( + e, + ) { + ////if unit2 cards is greater than 3 + return Container( + child: (e.roleName == 'superadmin' || + e.roleName == 'qr code scanner' || + e.roleName == 'security guard' || + e.roleName == + 'establishment point-person' || + e.roleName == + 'registration in-charge') && + e.moduleName == 'unit2' + ? CardLabel( + icon: iconGenerator(name: e.object.name!), + title: e.object.name!.toLowerCase() == + 'role based access control' + ? "RBAC" + : e.object.name!.toLowerCase() == + "person basic information" + ? "Basic Info" + : e.object.name!, + ontap: () { + if (e.object.name!.toLowerCase() == + 'pass check') { + PassCheckArguments passCheckArguments = + PassCheckArguments( + roleId: 10, + userId: widget.userId); + Navigator.pushNamed( + context, '/pass-check', + arguments: passCheckArguments); + } + if (e.object.name!.toLowerCase() == + 'role based access control') { + Navigator.pushNamed(context, '/rbac'); + } + }) + : Container( + color: Colors.black, + )); + }).toList(), + ),), + SizedBox( + height: unit2Cards.isEmpty?0:24, + ), + Container(child: superadminCards.isEmpty?const SizedBox(): Text( + "Superadmin module operations", + style: Theme.of(context).textTheme.displaySmall!.copyWith( + fontSize: 16, color: primary, fontWeight: FontWeight.w300), + ),), + SizedBox( + height: superadminCards.isEmpty? 0: 8, + ), + Container(child: superadminCards.isEmpty?const SizedBox():GridView.count( + shrinkWrap: true, + crossAxisCount: 4, + crossAxisSpacing: 8, + mainAxisSpacing: 10, + physics: const BouncingScrollPhysics(), + padding: + const EdgeInsets.symmetric(vertical: 5, horizontal: 5), + children: superadminCards.length > 3 + //// in superadmincards lenght is greaterthan 3 + ? tempSuperAdminCards.map((e) { + int index = tempSuperAdminCards.indexOf(e); + return Container( + child: index == 3 + ? CardLabel( + icon: FontAwesome5.chevron_circle_right, + title: "See More", + ontap: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text( + "Super Admin Module Operations", + textAlign: TextAlign.center, + ), + content: Column( + mainAxisSize: + MainAxisSize.min, + children: [ + SizedBox( + height: 480, + width: double.maxFinite, + child: GridView.count( + shrinkWrap: true, + crossAxisCount: 3, + crossAxisSpacing: 8, + mainAxisSpacing: 10, + physics: + const BouncingScrollPhysics(), + padding: + const EdgeInsets + .symmetric( + vertical: 5, + horizontal: 5), + children: + superadminCards + .map((e) { + int index = + superadminCards + .indexOf(e); + return SuperAdminMenu( + id: widget.userId, + columnCount: 3, + index: index, + object: e, + ); + }).toList(), + ), + ), + ], + ), + ); + }); + }) + : SuperAdminMenu( + id: widget.userId, + object: e, + index: index, + columnCount: 3, + )); + }).toList() + //// in superadmincards lenght is lessthan 3 + : superadminCards.map((e) { + int index = tempSuperAdminCards.indexOf(e); + return Container( + child: index == 3 + ? CardLabel( + icon: FontAwesome5.chevron_circle_right, + title: "See More", + ontap: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text( + "Super Admin Module Operations", + textAlign: TextAlign.center, + ), + content: Column( + mainAxisSize: + MainAxisSize.min, + children: [ + SizedBox( + height: 480, + width: double.maxFinite, + child: GridView.count( + shrinkWrap: true, + crossAxisCount: 3, + crossAxisSpacing: 8, + mainAxisSpacing: 10, + physics: + const BouncingScrollPhysics(), + padding: + const EdgeInsets + .symmetric( + vertical: 5, + horizontal: 5), + children: + superadminCards + .map((e) { + return SuperAdminMenu( + id: widget.userId, + columnCount: 4, + index: index, + object: e, + ); + }).toList(), + ), + ), + ], + ), + ); + }); + }) + : SuperAdminMenu( + id: widget.userId, + object: e, + index: index, + columnCount: 4, + )); + }).toList())), + const SizedBox( + height: 24, + ), + Container(child: rpassCards.isEmpty?const SizedBox(): Text( + "RPAss module operations", + style: Theme.of(context).textTheme.displaySmall!.copyWith( + fontSize: 16, color: primary, fontWeight: FontWeight.w300), + ),) +, SizedBox( + height:rpassCards.isEmpty?0: 8, + ), + Container(child: rpassCards.isEmpty?const SizedBox():GridView.count( + shrinkWrap: true, + crossAxisCount: 4, + crossAxisSpacing: 8, + mainAxisSpacing: 10, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5), + children: rpassCards.map((e) { + return Container( + child: (e.roleName == 'field surveyor') && + e.moduleName == 'rpass' + ? CardLabel( + icon: iconGenerator(name: e.object.name!), + title: e.object.name == 'Real Property' + ? "Field Surveyor" + : e.object.name!, + ontap: () {}) + : Container( + color: Colors.black, + )); + }).toList(), + ),), + const SizedBox( + height: 24, + ), + Container(child: docSmsCards.isEmpty?const SizedBox(): Text( + "DocSMS module operations", + style: Theme.of(context).textTheme.displaySmall!.copyWith( + fontSize: 16, color: primary, fontWeight: FontWeight.w300), + ),), + const SizedBox( + height: 8, + ), + GridView.count( + shrinkWrap: true, + crossAxisCount: 4, + crossAxisSpacing: 8, + mainAxisSpacing: 10, + physics: const BouncingScrollPhysics(), + padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 5), + children: docSmsCards.map((e) { + return Container( + child: (e.roleName == 'process server') && + e.moduleName == 'document management' + ? CardLabel( + icon: iconGenerator(name: e.object.name!), + title: e.object.name == "Document" + ? "Process Server" + : e.object.name!, + ontap: () { + + }) + : Container( + color: Colors.black, + )); + }).toList(), + ) + ], + ) + ], + ), + ); + } +} + +class PassCheckArguments { + final int roleId; + final int userId; + const PassCheckArguments({required this.roleId, required this.userId}); +} diff --git a/lib/screens/unit2/homepage.dart/components/dashboard/dashboard_icon_generator.dart b/lib/screens/unit2/homepage.dart/components/dashboard/dashboard_icon_generator.dart new file mode 100644 index 0000000..ff8e816 --- /dev/null +++ b/lib/screens/unit2/homepage.dart/components/dashboard/dashboard_icon_generator.dart @@ -0,0 +1,66 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:fluttericon/font_awesome5_icons.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; +import 'package:fluttericon/maki_icons.dart'; +import 'package:fluttericon/modern_pictograms_icons.dart'; +import 'package:fluttericon/octicons_icons.dart'; +import 'package:fluttericon/web_symbols_icons.dart'; + +IconData? iconGenerator({required String name}) { + if (name.toLowerCase() == 'agency') { + return FontAwesome5.building; + } else if (name.toLowerCase() == 'assignable role') { + return FontAwesome5.user_plus; + } else if (name.toLowerCase() == 'role') { + return FontAwesome5.user; + } else if (name.toLowerCase() == 'operation') { + return FontAwesome.export_alt; + } else if (name.toLowerCase() == 'module') { + return Icons.view_module; + } else if (name.toLowerCase() == 'area') { + return FontAwesome5.map_marked; + } else if (name.toLowerCase() == 'object') { + return FontAwesome.box; + } else if (name.toLowerCase() == 'permission') { + return FontAwesome5.door_open; + } else if (name.toLowerCase() == 'station') { + return ModernPictograms.home; + } else if (name.toLowerCase() == 'purok') { + return WebSymbols.list_numbered; + } else if (name.toLowerCase() == 'barangay') { + return Maki.industrial_building; + } else if (name.toLowerCase() == 'role module') { + return FontAwesome5.person_booth; + } else if (name.toLowerCase() == 'module object') { + return FontAwesome5.th_list; + } else if (name.toLowerCase() == 'roles extend') { + return FontAwesome5.external_link_square_alt; + } else if (name.toLowerCase() == 'real property') { + return FontAwesome5.eye; + } else if (name.toLowerCase() == 'document') { + return FontAwesome5.newspaper; + } else if (name.toLowerCase() == 'role based access control') { + return FontAwesome5.tasks; + } else if (name.toLowerCase() == 'pass check') { + return FontAwesome5.qrcode; + } else if (name.toLowerCase() == 'list of persons') { + return FontAwesome5.users; + } else if (name.toLowerCase() == 'person basic information') { + return FontAwesome5.info_circle; + }else if(name.toLowerCase() == "role member"){ + return FontAwesome5.users_cog; + } + + + + + + else if (name.toLowerCase() == 'security location') { + return FontAwesome5.location_arrow; + } + + else { + return null; + } +} diff --git a/lib/screens/unit2/homepage.dart/components/dashboard/shared_card_label.dart b/lib/screens/unit2/homepage.dart/components/dashboard/shared_card_label.dart new file mode 100644 index 0000000..9dd8c3d --- /dev/null +++ b/lib/screens/unit2/homepage.dart/components/dashboard/shared_card_label.dart @@ -0,0 +1,61 @@ +import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/material.dart'; + +import '../../../../../theme-data.dart/colors.dart'; +import '../../../../../utils/global.dart'; + +class CardLabel extends StatelessWidget { + final String title; + final IconData? icon; + final Function()? ontap; + const CardLabel( + {super.key, + required this.icon, + required this.title, + required this.ontap}); + + @override + Widget build(BuildContext context) { + return InkWell( + splashColor: second, + onTap: ontap, + child: Container( + padding: const EdgeInsetsDirectional.fromSTEB(8, 5, 8, 13), + alignment: Alignment.center, + decoration: const BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow(color: Colors.black12, spreadRadius: 1, blurRadius: 2) + ], + borderRadius: BorderRadius.all(Radius.circular(8))), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Flexible( + flex: 1, + child: Icon( + icon, + size: 20, + weight: 100, + grade: 100, + color: second, + ), + ), + const Expanded(child: SizedBox()), + Flexible( + flex: 2, + child: AutoSizeText( + minFontSize: 10, + title, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.labelLarge!.copyWith( + fontSize: blockSizeVertical * 1.2, + fontWeight: FontWeight.bold), + ), + ), + ]), + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/unit2/homepage.dart/components/dashboard/superadmin_expanded_menu.dart b/lib/screens/unit2/homepage.dart/components/dashboard/superadmin_expanded_menu.dart new file mode 100644 index 0000000..23d42ca --- /dev/null +++ b/lib/screens/unit2/homepage.dart/components/dashboard/superadmin_expanded_menu.dart @@ -0,0 +1,317 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/agency/agency_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/module/module_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/module_objects/module_objects_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/object/object_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/operation/operation_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/permission/permission_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role/role_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role_extend/role_extend_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/role_module/role_module_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/roles_under/roles_under_bloc.dart'; +import 'package:unit2/bloc/rbac/rbac_operations/station/station_bloc.dart'; +import 'package:unit2/bloc/role_assignment/role_assignment_bloc.dart'; +import 'package:unit2/screens/superadmin/module/module_screen.dart'; +import 'package:unit2/screens/superadmin/object/object_screen.dart'; +import 'package:unit2/screens/superadmin/operation/operation_screen.dart'; +import 'package:unit2/screens/superadmin/permission/permission_screen.dart'; +import 'package:unit2/screens/superadmin/role/role_screen.dart'; +import 'package:unit2/screens/superadmin/role_assignment.dart/role_assignment_screen.dart'; +import 'package:unit2/screens/superadmin/role_extend/role_extend_screen.dart'; +import 'package:unit2/screens/superadmin/roles_under/roles_under_screen.dart'; +import 'package:unit2/screens/superadmin/stations/stations_screen.dart'; +import 'package:unit2/screens/unit2/homepage.dart/module-screen.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/theme-data.dart/form-style.dart'; +import '../../../../superadmin/agency.dart/agency_screen.dart'; +import '../../../../superadmin/module_objects/module_objects_screen.dart'; +import '../../../../superadmin/role_module/role_module_scree.dart'; +import './shared_card_label.dart'; +import 'dashboard_icon_generator.dart'; + +class SuperAdminMenu extends StatelessWidget { + final int id; + final DisplayCard object; + final int index; + final int columnCount; + const SuperAdminMenu( + {super.key, + required this.id, + required this.object, + required this.index, + required this.columnCount}); + + @override + Widget build(BuildContext context) { + final roleAssignmentKey = GlobalKey(); + return AnimationConfiguration.staggeredGrid( + position: index, + columnCount: columnCount, + child: ScaleAnimation( + child: FadeInAnimation( + child: Container( + child: (object.roleName == 'superadmin' || + object.object.name == 'Agency' || + object.object.name == 'Assignable Role' || + object.object.name == 'Role' || + object.object.name == 'Module' || + object.object.name == 'Object' || + object.object.name == 'Operation' || + object.object.name == 'Permission' || + object.object.name == 'Area' || + object.object.name == 'Station' || + object.object.name == 'Purok' || + object.object.name == 'Barangay' || + object.object.name == 'Role Module' || + object.object.name == 'Module Object' || + object.object.name == 'Roles Extend' || + object.object.name == "Role Member") && + object.moduleName == 'superadmin' + ? CardLabel( + icon: iconGenerator(name: object.object.name!), + title: + object.object.name!.toLowerCase() == 'assignable role' + ? "Role Assignment" + : object.object.name!, + ontap: () { + if (object.object.name == 'Role') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => RoleBloc()..add(GetRoles()), + child: RbacRoleScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Operation') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + OperationBloc()..add(GetOperations()), + child: RbacOperationScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Module') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + ModuleBloc()..add(GetModule()), + child: RbacModuleScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Object') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + ObjectBloc()..add(GetObjects()), + child: RbacObjectScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Permission') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + PermissionBloc()..add(GetPermissions()), + child: RbacPermissionScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Module Object') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + ModuleObjectsBloc()..add(GetModuleObjects()), + child: RbacModuleObjectsScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Agency') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + AgencyBloc()..add(GetAgencies()), + child: RbacAgencyScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Role Module') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + RoleModuleBloc()..add(GetRoleModules()), + child: RbacRoleModuleScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Assignable Role') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + RolesUnderBloc()..add(GetRolesUnder()), + child: RbacRoleUnderScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Roles Extend') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => + RoleExtendBloc()..add(GetRoleExtend()), + child: RbacRoleExtendScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Station') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => StationBloc() + ..add(const GetStations(agencyId: 1)), + child: RbacStationScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Station') { + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => StationBloc() + ..add(const GetStations(agencyId: 1)), + child: RbacStationScreen( + id: id, + ), + ); + })); + } + if (object.object.name == 'Role Member') { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Row( + children: [ + const Expanded(child: Text("Search User")), + IconButton(onPressed: (){ + Navigator.pop(context); + }, icon: const Icon(Icons.close)) + ], + ), + content: FormBuilder( + key: roleAssignmentKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderTextField( + name: "firstname", + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + decoration: normalTextFieldStyle( + "First name", "first name"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + name: "lastname", + decoration: normalTextFieldStyle( + "Last name", "last tname"), + ), + const SizedBox( + height: 24, + ), + SizedBox( + height: 60, + width: double.maxFinite, + child: ElevatedButton( + onPressed: () { + if (roleAssignmentKey + .currentState! + .saveAndValidate()) { + + String fname = + roleAssignmentKey + .currentState! + .value['firstname']; + String lname = + roleAssignmentKey + .currentState! + .value['lastname']; + Navigator.push(context, + MaterialPageRoute(builder: + (BuildContext + context) { + return BlocProvider( + create: (context) => + RoleAssignmentBloc() + ..add(GetAssignedRoles( + firstname: + fname, + lastname: + lname),),child:RbacRoleAssignment(id:id) ,); + })); + } + }, + style: mainBtnStyle(primary, + Colors.transparent, second), + child: const Text("Submit"), + ), + ) + ], + )), + ); + }); + } + }) + : Container( + color: Colors.black, + )), + ), + ), + ); + } +} diff --git a/lib/screens/unit2/homepage.dart/module-screen.dart b/lib/screens/unit2/homepage.dart/module-screen.dart index e8a9585..a41389a 100644 --- a/lib/screens/unit2/homepage.dart/module-screen.dart +++ b/lib/screens/unit2/homepage.dart/module-screen.dart @@ -1,14 +1,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart'; -import 'package:fluttericon/font_awesome5_icons.dart'; -import 'package:fluttericon/font_awesome_icons.dart'; -import 'package:fluttericon/rpg_awesome_icons.dart'; -import 'package:fluttericon/typicons_icons.dart'; -import 'package:unit2/screens/unit2/homepage.dart/components/dashboard.dart'; +import 'package:unit2/screens/unit2/homepage.dart/components/dashboard/dashboard.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/text_container.dart'; import '../../../bloc/user/user_bloc.dart'; +import '../../../model/login_data/user_info/module.dart'; import '../../../model/login_data/user_info/role.dart'; import 'components/empty_module.dart'; @@ -20,14 +17,17 @@ class MainScreen extends StatefulWidget { } class _MainScreenState extends State { - List roles = [ - Module(name: 'UniT2 module operations', roles: []), - Module(name: 'DocSms module operations', roles: []), - Module(name: "RPAss module operations",roles:[] ) - ]; + List roles = []; + List cards = []; int? userId; @override Widget build(BuildContext context) { + setState(() { + cards.clear(); + cards=[]; + roles.clear(); + roles = []; + }); return WillPopScope( onWillPop: () async { return Future.value(true); @@ -35,85 +35,63 @@ class _MainScreenState extends State { child: BlocBuilder(builder: (context, state) { if (state is UserLoggedIn) { userId = state.userData!.user!.login!.user!.id; - for (var element in roles) { - element.roles.clear(); - } for (var role in state.userData!.user!.login!.user!.roles!) { Role? getRole = role; - for (var module in role!.modules!) { - if (module!.name!.toLowerCase() == 'unit2') { - IconData iconData = iconGenerator(getRole!.name!); - Roles newRole = Roles(role: getRole, icon: iconData); - roles[0].roles.add(newRole); - } - if (module.name!.toLowerCase() == 'document management') { - IconData iconData = iconGenerator(getRole!.name!); - Roles newRole = Roles(role: getRole, icon: iconData); - roles[1].roles.add(newRole); - } if (module.name!.toLowerCase() == 'rpass') { - IconData iconData = iconGenerator(getRole!.name!); - Roles newRole = Roles(role: getRole, icon: iconData); - roles[2].roles.add(newRole); + roles.add(getRole!); + } + for (var role in roles) { + for (var module in role.modules!) { + for (var object in module!.objects!) { + DisplayCard newCard = DisplayCard( + moduleName: module.name!.toLowerCase(), + object: object!, + roleName: role.name!.toLowerCase()); + cards.add(newCard); } } } + return Scaffold( appBar: AppBar( - backgroundColor: primary, - leading: IconButton( - onPressed: () { - ZoomDrawer.of(context)!.toggle(); - }, - icon: const Icon( - Icons.menu, - color: Colors.white, - ), - ), - centerTitle: true, - title: const Text( - unit2ModuleScreen, - style: TextStyle( - fontSize: 18.0, - color: Colors.white, - ), - ), + backgroundColor: primary, + leading: IconButton( + onPressed: () { + ZoomDrawer.of(context)!.toggle(); + }, + icon: const Icon( + Icons.menu, + color: Colors.white, + ), + ), + centerTitle: true, + title: const Text( + unit2ModuleScreen, + style: TextStyle( + fontSize: 18.0, + color: Colors.white, + ), + ), ), body: state.userData!.user!.login!.user!.roles!.isNotEmpty - ? DashBoard( - userId: userId!, - roles: roles, - ) - : const NoModule(), + ? DashBoard( + userId: userId!, + cards: cards, + ) + : const NoModule(), ); } return Container(); }), ); } +} - IconData iconGenerator(String roleName) { - IconData? iconData; - switch (roleName.toLowerCase()) { - case 'qr code scanner': - iconData = FontAwesome.qrcode; - break; - case 'security guard': - iconData = FontAwesome5.user_shield; - break; - case 'establishment point-person': - iconData = FontAwesome.building_filled; - break; - case 'registration in-charge': - iconData = FontAwesome.user_plus; - break; - case 'process server': - iconData = Typicons.doc_text; - break; - case 'field surveyor': - iconData = RpgAwesome.telescope; - } - return iconData!; - } +class DisplayCard { + final String roleName; + final String moduleName; + final ModuleObject object; + const DisplayCard( + {required this.moduleName, required this.object, required this.roleName}); } class Module { @@ -123,7 +101,7 @@ class Module { } class Roles { - final IconData icon; + final IconData? icon; final Role role; Roles({required this.role, required this.icon}); } diff --git a/lib/screens/unit2/login/login.dart b/lib/screens/unit2/login/login.dart index c0a0c03..ecd188a 100644 --- a/lib/screens/unit2/login/login.dart +++ b/lib/screens/unit2/login/login.dart @@ -1,4 +1,3 @@ -import 'package:barcode_scan2/barcode_scan2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; @@ -66,7 +65,9 @@ class _UniT2LoginState extends State { gravity: ToastGravity.BOTTOM, backgroundColor: Colors.black, ); - Navigator.pushReplacementNamed(context, '/module-screen'); + Navigator.pushReplacementNamed( + NavigationService.navigatorKey.currentContext!, + '/module-screen'); }, () => Navigator.pushReplacementNamed( context, '/module-screen'), @@ -85,8 +86,10 @@ class _UniT2LoginState extends State { Navigator.of(context).pop(); }); } - }if(state is UuidLoaded){ - Navigator.push(context, MaterialPageRoute(builder: (BuildContext context){ + } + if (state is UuidLoaded) { + Navigator.push(context, + MaterialPageRoute(builder: (BuildContext context) { return const QRLogin(); })); } @@ -367,15 +370,18 @@ class _UniT2LoginState extends State { if (state is SplashScreen) { return const UniTSplashScreen(); } - if(state is LoginErrorState){ - return SomethingWentWrong(message: state.message, onpressed: () { + if (state is LoginErrorState) { + return SomethingWentWrong( + message: state.message, + onpressed: () { BlocProvider.of( NavigationService.navigatorKey.currentContext!) .add(GetApkVersion()); return MaterialPageRoute(builder: (_) { return const UniT2Login(); }); - },); + }, + ); } return Container(); }), diff --git a/lib/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart b/lib/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart index 19df2b5..c150df6 100644 --- a/lib/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart +++ b/lib/screens/unit2/roles/qr_code_scanner.dart/settings_screen.dart @@ -9,7 +9,7 @@ import 'package:fluttericon/modern_pictograms_icons.dart'; import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:unit2/bloc/role/pass_check/pass_check_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart'; -import 'package:unit2/screens/unit2/homepage.dart/components/dashboard.dart'; +import 'package:unit2/screens/unit2/homepage.dart/components/dashboard/dashboard.dart'; import 'package:unit2/screens/unit2/roles/qr_code_scanner.dart/components/custom_switch.dart'; import 'package:unit2/screens/unit2/roles/qr_code_scanner.dart/scan.dart'; import 'package:unit2/utils/text_container.dart'; @@ -40,593 +40,591 @@ class _QRCodeScannerSettingsState extends State { final _formKey = GlobalKey(); @override Widget build(BuildContext context) { - return SafeArea( - child: Scaffold( - appBar: AppBar( - title: const Text(qrScannerTitle), - centerTitle: true, - backgroundColor: primary, + return Scaffold( + appBar: AppBar( + title: const Text(qrScannerTitle), + centerTitle: true, + backgroundColor: primary, + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + indicatorWidget: const SpinKitFadingCircle( + color: Colors.white, ), - body: ProgressHUD( - padding: const EdgeInsets.all(24), - indicatorWidget: const SpinKitFadingCircle( - color: Colors.white, - ), - backgroundColor: Colors.black87, - child: BlocBuilder( - builder: (context, state) { - if (state is UserLoggedIn) { - token = state.userData!.user!.login!.token; - checkerId = state.userData!.user!.login!.user!.id; - return BlocConsumer( - listener: (context, state) { - if (state is PassCheckLoadingState) { - final progress = ProgressHUD.of(context); - progress!.showWithText("Please wait..."); - } - if (state is AssignAreaLoaded || - state is PassCheckErrorState) { - final progress = ProgressHUD.of(context); - progress!.dismiss(); - } - }, - builder: (context, state) { - if (state is AssignAreaLoaded) { - return Container( - height: screenHeight * .90, - padding: const EdgeInsets.symmetric( - horizontal: 42, vertical: 10), - child: FormBuilder( - key: _formKey, - child: Column( - children: [ - Flexible( - child: ListView( - children: [ - const SizedBox( - height: 32, - ), - SvgPicture.asset( - 'assets/svgs/switch.svg', - height: blockSizeVertical * 14, - allowDrawingOutsideViewBox: true, - ), - ListTile( - title: Text( - setQRScannerSettings, - style: Theme.of(context) - .textTheme - .titleLarge! - .copyWith(color: third), - textAlign: TextAlign.center, - ), - ), - Text(includeOtherInputs, - style: Theme.of(context) - .textTheme - .titleMedium), - Text( - includeOtherInputsSubTitle, + backgroundColor: Colors.black87, + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + checkerId = state.userData!.user!.login!.user!.id; + return BlocConsumer( + listener: (context, state) { + if (state is PassCheckLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is AssignAreaLoaded || + state is PassCheckErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, + builder: (context, state) { + if (state is AssignAreaLoaded) { + return Container( + height: screenHeight * .90, + padding: const EdgeInsets.symmetric( + horizontal: 42, vertical: 10), + child: FormBuilder( + key: _formKey, + child: Column( + children: [ + Flexible( + child: ListView( + children: [ + const SizedBox( + height: 32, + ), + SvgPicture.asset( + 'assets/svgs/switch.svg', + height: blockSizeVertical * 14, + allowDrawingOutsideViewBox: true, + ), + ListTile( + title: Text( + setQRScannerSettings, style: Theme.of(context) .textTheme - .bodySmall, + .titleLarge! + .copyWith(color: third), + textAlign: TextAlign.center, ), - SizedBox( - child: FittedBox( - child: CostumToggleSwitch( - activeBGColors: [ - Colors.green[800]!, - Colors.red[800]! - ], - initialLabelIndex: - _includeOtherInputs ? 0 : 1, - icons: const [ - Entypo.check, - ModernPictograms.cancel - ], - labels: const ['YES', 'NO'], - onToggle: (value) { - value == 0 - ? _includeOtherInputs = true - : _includeOtherInputs = false; - }, - ), - ), - ), - // Incoming or outgoing - Text(incomingORoutgoing, - style: Theme.of(context) - .textTheme - .titleMedium), - Text( - incomingORoutgoingSubTitle, + ), + Text(includeOtherInputs, style: Theme.of(context) .textTheme - .bodySmall, - ), - FittedBox( + .titleMedium), + Text( + includeOtherInputsSubTitle, + style: Theme.of(context) + .textTheme + .bodySmall, + ), + SizedBox( + child: FittedBox( child: CostumToggleSwitch( activeBGColors: [ - Colors.red[800]!, - Colors.green[800]! + Colors.green[800]!, + Colors.red[800]! ], initialLabelIndex: - scanMode == 'INCOMING' ? 0 : 1, + _includeOtherInputs ? 0 : 1, icons: const [ - Entypo.down_bold, - Entypo.up_bold, - ], - labels: const [ - 'INCOMING', - 'OUTGOING' + Entypo.check, + ModernPictograms.cancel ], + labels: const ['YES', 'NO'], onToggle: (value) { value == 0 - ? scanMode = 'INCOMING' - : scanMode = 'OUTGOING'; + ? _includeOtherInputs = true + : _includeOtherInputs = false; }, ), ), - const SizedBox( - height: 24, - ), - - ////STATION - Container( - child: state.roleId == 41 - ? DropdownButtonFormField( - isExpanded: true, - validator: FormBuilderValidators - .required( - errorText: - fieldIsRequired), - decoration: - normalTextFieldStyle( - "station", "station"), - items: state.assignedArea - .map((station) { - if (station.motherStation) { - return DropdownMenuItem< - dynamic>( - enabled: false, - value: station, - child: Text( - station.stationName - .toUpperCase(), - style: - const TextStyle( - color: Colors - .grey), - ), - ); - } else { - return DropdownMenuItem< - dynamic>( - value: station, - child: Padding( - padding: - const EdgeInsets - .only( - left: 10), - child: Text(station - .stationName), - ), - ); - } - }).toList(), - // value: selectedLevel, - onChanged: (value) async { - assignedArea = value; - }, - ////BARANGAY - ) - : state.roleId == 7 - ? Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Text( - "Select Barangay", - textAlign: - TextAlign.start, - style: - Theme.of(context) - .textTheme - .titleMedium, - ), - const SizedBox( - height: 12, - ), - DropdownButtonFormField( - isExpanded: true, - decoration: - normalTextFieldStyle( - "Barangay", - "Barangay"), - items: state - .assignedArea - .map((barangay) { - return DropdownMenuItem< - dynamic>( - value: barangay, - child: Padding( - padding: - const EdgeInsets - .only( - left: - 5), - child: Text( - barangay - .brgydesc), - ), - ); - }).toList(), - onChanged: (value) { - assignedArea = - value; - }, - ), - ], - ) - : - ////PUROK - state.roleId == 10 - ? Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Text( - "Select Purok", - textAlign: - TextAlign - .start, - style: Theme.of( - context) - .textTheme - .titleMedium, - ), - const SizedBox( - height: 12, - ), - DropdownButtonFormField( - isExpanded: true, - decoration: - normalTextFieldStyle( - "Purok", - "Purok"), - items: state - .assignedArea - .map((purok) { - return DropdownMenuItem< - dynamic>( - value: purok, - child: - Padding( - padding: const EdgeInsets - .only( - left: - 5), - child: Text( - purok - .purokdesc), - ), - ); - }).toList(), - onChanged: - (value) { - assignedArea = - value; - }, - ), - ], - ) - : - ////Registration InCharge - state.roleId == 22 - ? Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Text( - "Select Station", - textAlign: - TextAlign - .start, - style: Theme.of( - context) - .textTheme - .titleMedium, - ), - const SizedBox( - height: 12, - ), - DropdownButtonFormField( - isExpanded: - true, - validator: FormBuilderValidators - .required( - errorText: - fieldIsRequired), - decoration: normalTextFieldStyle( - "station", - "station"), - items: state - .assignedArea - .map( - (station) { - if (station - .motherStation) { - return DropdownMenuItem< - dynamic>( - enabled: - false, - value: - station, - child: - Text( - station - .stationName - .toUpperCase(), - style: - const TextStyle(color: Colors.grey), - ), - ); - } else { - return DropdownMenuItem< - dynamic>( - value: - station, - child: - Padding( - padding: - const EdgeInsets.only(left: 5), - child: - Text(station.stationName), - ), - ); - } - }).toList(), - // value: selectedLevel, - onChanged: - (value) async { - assignedArea = - value; - }, - ), - ], - ) - : ////QR Code Scanner - state.roleId == 13 - ? Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Text( - "Select Station", - textAlign: - TextAlign - .start, - style: Theme.of( - context) - .textTheme - .titleMedium, - ), - const SizedBox( - height: - 12, - ), - DropdownButtonFormField( - isExpanded: - true, - validator: - FormBuilderValidators.required( - errorText: fieldIsRequired), - decoration: normalTextFieldStyle( - "station", - "station"), - items: state - .assignedArea - .map( - (station) { - if (station - .motherStation) { - return DropdownMenuItem< - dynamic>( - enabled: - false, - value: - station, - child: - Text( - station.stationName.toUpperCase(), - style: const TextStyle(color: Colors.grey), - ), - ); - } else { - return DropdownMenuItem< - dynamic>( - value: - station, - child: - Padding( - padding: const EdgeInsets.only(left: 5), - child: Text(station.stationName), - ), - ); - } - }).toList(), - // value: selectedLevel, - onChanged: - (value) async { - assignedArea = - value; - }, - ), - ], - ) - : - ////Establishment Point-Person - state.roleId == 16 - ? Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Text( - "Select Agency", - textAlign: - TextAlign.start, - style: Theme.of(context) - .textTheme - .titleMedium, - ), - const SizedBox( - height: - 12, - ), - DropdownButtonFormField( - isExpanded: - true, - validator: - FormBuilderValidators.required(errorText: fieldIsRequired), - decoration: normalTextFieldStyle( - "Agency", - "Agency"), - items: state - .assignedArea - .map((agency) { - return DropdownMenuItem( - value: agency, - child: Padding( - padding: const EdgeInsets.only(left: 5), - child: Text(agency.area.name), - ), - ); - }).toList(), - // value: selectedLevel, - onChanged: - (value) async { - assignedArea = - value; - }, - ), - ], - ) - : ////Office Branch Chief - state.roleId == - 17 - ? Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - "Select Station", - textAlign: TextAlign.start, - style: Theme.of(context).textTheme.titleMedium, - ), - const SizedBox( - height: 12, - ), - DropdownButtonFormField( - isExpanded: true, - validator: FormBuilderValidators.required(errorText: fieldIsRequired), - decoration: normalTextFieldStyle("station", "station"), - items: state.assignedArea.map((station) { - if (station.motherStation) { - return DropdownMenuItem( - enabled: false, - value: station, - child: Text( - station.stationName.toUpperCase(), - style: const TextStyle(color: Colors.grey), - ), - ); - } else { - return DropdownMenuItem( - value: station, - child: Padding( - padding: const EdgeInsets.only(left: 5), - child: Text(station.stationName), - ), - ); - } - }).toList(), - // value: selectedLevel, - onChanged: (value) async { - assignedArea = value; - }, - ), - ], - ) - : Container()) - ], - ), - ), - SizedBox( - width: double.infinity, - height: 60, - child: ElevatedButton( - style: mainBtnStyle(primary, - Colors.transparent, Colors.white54), - child: const Text( - submit, - style: TextStyle(color: Colors.white), ), - onPressed: () { - if (_formKey.currentState! - .saveAndValidate()) { - print(scanMode); - print(_includeOtherInputs); - print(checkerId); - print(assignedArea); - Navigator.push(context, - MaterialPageRoute(builder: - (BuildContext context) { - return BlocProvider< - PassCheckBloc>.value( - value: PassCheckBloc() - ..add(SetScannerSettings( - token: token!, - assignedArea: assignedArea, - checkerId: checkerId!, - entranceExit: scanMode, - includeOtherInputs: - _includeOtherInputs, - roleId: state.roleId)), - child: const QRCodeScanner(), - ); - })); - } - }, + // Incoming or outgoing + Text(incomingORoutgoing, + style: Theme.of(context) + .textTheme + .titleMedium), + Text( + incomingORoutgoingSubTitle, + style: Theme.of(context) + .textTheme + .bodySmall, + ), + FittedBox( + child: CostumToggleSwitch( + activeBGColors: [ + Colors.red[800]!, + Colors.green[800]! + ], + initialLabelIndex: + scanMode == 'INCOMING' ? 0 : 1, + icons: const [ + Entypo.down_bold, + Entypo.up_bold, + ], + labels: const [ + 'INCOMING', + 'OUTGOING' + ], + onToggle: (value) { + value == 0 + ? scanMode = 'INCOMING' + : scanMode = 'OUTGOING'; + }, + ), + ), + const SizedBox( + height: 24, + ), + + ////STATION + Container( + child: state.roleId == 41 + ? DropdownButtonFormField( + isExpanded: true, + validator: FormBuilderValidators + .required( + errorText: + fieldIsRequired), + decoration: + normalTextFieldStyle( + "station", "station"), + items: state.assignedArea + .map((station) { + if (station.motherStation) { + return DropdownMenuItem< + dynamic>( + enabled: false, + value: station, + child: Text( + station.stationName + .toUpperCase(), + style: + const TextStyle( + color: Colors + .grey), + ), + ); + } else { + return DropdownMenuItem< + dynamic>( + value: station, + child: Padding( + padding: + const EdgeInsets + .only( + left: 10), + child: Text(station + .stationName), + ), + ); + } + }).toList(), + // value: selectedLevel, + onChanged: (value) async { + assignedArea = value; + }, + ////BARANGAY + ) + : state.roleId == 7 + ? Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + "Select Barangay", + textAlign: + TextAlign.start, + style: + Theme.of(context) + .textTheme + .titleMedium, + ), + const SizedBox( + height: 12, + ), + DropdownButtonFormField( + isExpanded: true, + decoration: + normalTextFieldStyle( + "Barangay", + "Barangay"), + items: state + .assignedArea + .map((barangay) { + return DropdownMenuItem< + dynamic>( + value: barangay, + child: Padding( + padding: + const EdgeInsets + .only( + left: + 5), + child: Text( + barangay + .brgydesc), + ), + ); + }).toList(), + onChanged: (value) { + assignedArea = + value; + }, + ), + ], + ) + : + ////PUROK + state.roleId == 10 + ? Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + "Select Purok", + textAlign: + TextAlign + .start, + style: Theme.of( + context) + .textTheme + .titleMedium, + ), + const SizedBox( + height: 12, + ), + DropdownButtonFormField( + isExpanded: true, + decoration: + normalTextFieldStyle( + "Purok", + "Purok"), + items: state + .assignedArea + .map((purok) { + return DropdownMenuItem< + dynamic>( + value: purok, + child: + Padding( + padding: const EdgeInsets + .only( + left: + 5), + child: Text( + purok + .purokdesc), + ), + ); + }).toList(), + onChanged: + (value) { + assignedArea = + value; + }, + ), + ], + ) + : + ////Registration InCharge + state.roleId == 22 + ? Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + "Select Station", + textAlign: + TextAlign + .start, + style: Theme.of( + context) + .textTheme + .titleMedium, + ), + const SizedBox( + height: 12, + ), + DropdownButtonFormField( + isExpanded: + true, + validator: FormBuilderValidators + .required( + errorText: + fieldIsRequired), + decoration: normalTextFieldStyle( + "station", + "station"), + items: state + .assignedArea + .map( + (station) { + if (station + .motherStation) { + return DropdownMenuItem< + dynamic>( + enabled: + false, + value: + station, + child: + Text( + station + .stationName + .toUpperCase(), + style: + const TextStyle(color: Colors.grey), + ), + ); + } else { + return DropdownMenuItem< + dynamic>( + value: + station, + child: + Padding( + padding: + const EdgeInsets.only(left: 5), + child: + Text(station.stationName), + ), + ); + } + }).toList(), + // value: selectedLevel, + onChanged: + (value) async { + assignedArea = + value; + }, + ), + ], + ) + : ////QR Code Scanner + state.roleId == 13 + ? Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + "Select Station", + textAlign: + TextAlign + .start, + style: Theme.of( + context) + .textTheme + .titleMedium, + ), + const SizedBox( + height: + 12, + ), + DropdownButtonFormField( + isExpanded: + true, + validator: + FormBuilderValidators.required( + errorText: fieldIsRequired), + decoration: normalTextFieldStyle( + "station", + "station"), + items: state + .assignedArea + .map( + (station) { + if (station + .motherStation) { + return DropdownMenuItem< + dynamic>( + enabled: + false, + value: + station, + child: + Text( + station.stationName.toUpperCase(), + style: const TextStyle(color: Colors.grey), + ), + ); + } else { + return DropdownMenuItem< + dynamic>( + value: + station, + child: + Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(station.stationName), + ), + ); + } + }).toList(), + // value: selectedLevel, + onChanged: + (value) async { + assignedArea = + value; + }, + ), + ], + ) + : + ////Establishment Point-Person + state.roleId == 16 + ? Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + "Select Agency", + textAlign: + TextAlign.start, + style: Theme.of(context) + .textTheme + .titleMedium, + ), + const SizedBox( + height: + 12, + ), + DropdownButtonFormField( + isExpanded: + true, + validator: + FormBuilderValidators.required(errorText: fieldIsRequired), + decoration: normalTextFieldStyle( + "Agency", + "Agency"), + items: state + .assignedArea + .map((agency) { + return DropdownMenuItem( + value: agency, + child: Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(agency.area.name), + ), + ); + }).toList(), + // value: selectedLevel, + onChanged: + (value) async { + assignedArea = + value; + }, + ), + ], + ) + : ////Office Branch Chief + state.roleId == + 17 + ? Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + "Select Station", + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox( + height: 12, + ), + DropdownButtonFormField( + isExpanded: true, + validator: FormBuilderValidators.required(errorText: fieldIsRequired), + decoration: normalTextFieldStyle("station", "station"), + items: state.assignedArea.map((station) { + if (station.motherStation) { + return DropdownMenuItem( + enabled: false, + value: station, + child: Text( + station.stationName.toUpperCase(), + style: const TextStyle(color: Colors.grey), + ), + ); + } else { + return DropdownMenuItem( + value: station, + child: Padding( + padding: const EdgeInsets.only(left: 5), + child: Text(station.stationName), + ), + ); + } + }).toList(), + // value: selectedLevel, + onChanged: (value) async { + assignedArea = value; + }, + ), + ], + ) + : Container()) + ], + ), + ), + SizedBox( + width: double.infinity, + height: 60, + child: ElevatedButton( + style: mainBtnStyle(primary, + Colors.transparent, Colors.white54), + child: const Text( + submit, + style: TextStyle(color: Colors.white), ), + onPressed: () { + if (_formKey.currentState! + .saveAndValidate()) { + print(scanMode); + print(_includeOtherInputs); + print(checkerId); + print(assignedArea); + Navigator.push(context, + MaterialPageRoute(builder: + (BuildContext context) { + return BlocProvider< + PassCheckBloc>.value( + value: PassCheckBloc() + ..add(SetScannerSettings( + token: token!, + assignedArea: assignedArea, + checkerId: checkerId!, + entranceExit: scanMode, + includeOtherInputs: + _includeOtherInputs, + roleId: state.roleId)), + child: const QRCodeScanner(), + ); + })); + } + }, ), - const SizedBox( - height: 52, - ), - ], - ), + ), + const SizedBox( + height: 52, + ), + ], ), - ); - } - if (state is PassCheckErrorState) { - return SomethingWentWrong( - message: state.message, onpressed: () { - - context.read().add(GetPassCheckAreas(roleId: widget.roleId, userId: widget.userId)); - }); - } - return Container(); - }, - ); - } - return Container(); - }, - ), - )), - ); + ), + ); + } + if (state is PassCheckErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () { + + context.read().add(GetPassCheckAreas(roleId: widget.roleId, userId: widget.userId)); + }); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); } } diff --git a/lib/screens/unit2/roles/rbac/add_rbac.dart b/lib/screens/unit2/roles/rbac/add_rbac.dart new file mode 100644 index 0000000..bf7fd3c --- /dev/null +++ b/lib/screens/unit2/roles/rbac/add_rbac.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:unit2/theme-data.dart/box_shadow.dart'; + +import '../../../../theme-data.dart/btn-style.dart'; +import '../../../../theme-data.dart/colors.dart'; +import '../../../../theme-data.dart/form-style.dart'; + +class AddRbac extends StatefulWidget { + +final Function() onpressed; +final GlobalKey formKey; +final String title; + const AddRbac({super.key,required this.title,required this.onpressed, required this.formKey}); + + @override + State createState() => _AddRbacState(); +} + +class _AddRbacState extends State { + final formKey = GlobalKey(); + @override + Widget build(BuildContext context) { + return Container( + decoration: box1(), + child: Column(mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(height: 24,), + const Text("No result found"), + const SizedBox(height: 12,), + TextButton(onPressed: (){ + showDialog(context: context,builder: (BuildContext context) { + return AlertDialog( + title: Text(widget.title), + content: FormBuilder( + key: widget.formKey, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + FormBuilderTextField( + name: "object_name", + decoration: normalTextFieldStyle("Object name *", "Object name "), + validator: FormBuilderValidators.required(errorText: "This field is required"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + name: "slug", + decoration: normalTextFieldStyle("Slug ", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + name: "shorthand", + decoration: normalTextFieldStyle("Shorthand ", "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle(primary, Colors.transparent, second), + onPressed: widget.onpressed, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }, child: Text(widget.title)) + ], + ), + ); + } +} diff --git a/lib/screens/unit2/roles/rbac/rbac.dart b/lib/screens/unit2/roles/rbac/rbac.dart new file mode 100644 index 0000000..12fe372 --- /dev/null +++ b/lib/screens/unit2/roles/rbac/rbac.dart @@ -0,0 +1,746 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_progress_hud/flutter_progress_hud.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:multi_dropdown/multiselect_dropdown.dart'; +import 'package:searchable_paginated_dropdown/searchable_paginated_dropdown.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/rbac/rbac_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/rbac/new_permission.dart'; +import 'package:unit2/model/rbac/permission.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/widgets/error_state.dart'; +import '../../../../model/profile/basic_information/primary-information.dart'; +import '../../../../sevices/roles/rbac_services.dart'; +import '../../../../theme-data.dart/box_shadow.dart'; +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/alerts.dart'; +import 'add_rbac.dart'; + +class RBACScreen extends StatefulWidget { + const RBACScreen({super.key}); + + @override + State createState() => _RBACScreenState(); +} + +class _RBACScreenState extends State { + ////roles + final roleFocusNode = FocusNode(); + final roleController = TextEditingController(); + RBAC? selectedRole; + + ////modules + final moduleFocusNode = FocusNode(); + final moduleController = TextEditingController(); + RBAC? selectedModule; + +////permissions + final permissionFocusNode = FocusNode(); + final permissionController = TextEditingController(); + List valueItemSelectedPermissions = []; + List valueItemPermission = []; + +////Object + RBAC? selectedObject; + final objectFocusNode = FocusNode(); + final objectController = TextEditingController(); + + ////operations + List operationsId = []; + List newOperations = []; + List valueItemOperation = []; + List selectedValueItemOperation = []; + + String? token; + + ////new permission + List newPermissions = []; + + final formKey = GlobalKey(); + final addRbacFormKey = GlobalKey(); + final newOperationKey = GlobalKey(); + int? selectedWebUserId; + bool showAddOperations = false; + @override + void dispose() { + moduleFocusNode.dispose(); + moduleController.dispose(); + roleFocusNode.dispose(); + roleController.dispose(); + permissionFocusNode.dispose(); + permissionController.dispose(); + objectFocusNode.dispose(); + objectController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: false, + appBar: AppBar( + title: const FittedBox( + child: Text("Role Based Access Control"), + ), + backgroundColor: primary, + ), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token; + return BlocConsumer( + listener: (context, state) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + if (state is RbacScreenSetted || state is RbacErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + if (state is RbacAssignedState) { + if (state.responseStatus['success']) { + successAlert(context, "Assigning Successfull!", + state.responseStatus['message'], () { + Navigator.of(context).pop(); + context.read().add(LoadRbac()); + }); + } else { + errorAlert(context, "Assigning Failed!", + state.responseStatus['message'], () { + Navigator.of(context).pop(); + context.read().add(LoadRbac()); + }); + } + } + }, + builder: (context, state) { + if (state is RbacScreenSetted) { + //// permission value item + valueItemPermission = + state.permission.map((RBACPermission permission) { + return ValueItem( + label: + "${permission.operation?.name} - ${permission.object?.name!}", + value: permission.id.toString()); + }).toList(); + ////value item operation + valueItemOperation = + state.operations.map((RBAC operation) { + return ValueItem( + label: operation.name!, + value: operation.id.toString()); + }).toList(); + return Container( + padding: const EdgeInsets.symmetric( + vertical: 32, horizontal: 34), + child: FormBuilder( + key: formKey, + child: Column( + children: [ + const SizedBox( + height: 38, + ), + Flexible( + child: Column( + children: [ + ////users + SearchableDropdownFormField.paginated( + margin: const EdgeInsets.all(0), + trailingIcon: const Padding( + padding: EdgeInsets.only(right: 8), + child: Icon( + Icons.arrow_drop_down, + color: Colors.grey, + )), + hintText: const Padding( + padding: EdgeInsets.only(left: 8), + child: Text( + "Search User", + style: TextStyle( + color: Colors.grey, + fontSize: 16), + )), + searchHintText: "Search User", + backgroundDecoration: (child) { + return SizedBox( + width: double.infinity, + child: Container( + width: double.infinity, + height: 50, + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey), + borderRadius: + const BorderRadius.all( + Radius.circular(5))), + child: child, + )); + }, + paginatedRequest: + (int page, String? searchKey) async { + List users = await RbacServices + .instance + .searchUser( + page: page, + name: searchKey ??= "", + token: token!); + return users.map((e) { + String fullname = + "${e.firstName} ${e.lastName}"; + return SearchableDropdownMenuItem< + Profile>( + label: fullname, + child: ListTile( + title: Text(fullname), + subtitle: + Text(e.birthdate.toString()), + ), + onTap: () { + setState(() { + selectedWebUserId = e.webuserId; + }); + }, + ); + }).toList(); + }, + ), + + const SizedBox( + height: 12, + ), + ////Role + StatefulBuilder( + builder: (context, setState) { + return SearchField( + itemHeight: 40, + suggestionsDecoration: box1(), + suggestions: state.role + .map((RBAC role) => + SearchFieldListItem( + role.name!, + item: role, + child: Padding( + padding: + const EdgeInsets + .symmetric( + horizontal: 10), + child: ListTile( + title: Text( + role.name!, + overflow: TextOverflow + .visible, + )), + ))) + .toList(), + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + focusNode: roleFocusNode, + searchInputDecoration: + normalTextFieldStyle("Role *", "") + .copyWith( + suffixIcon: IconButton( + icon: const Icon( + Icons.arrow_drop_down), + onPressed: () { + roleFocusNode.unfocus(); + }, + )), + onSuggestionTap: (role) { + setState(() { + selectedRole = role.item; + roleFocusNode.unfocus(); + }); + }, + ////Add new role + emptyWidget: AddRbac( + formKey: addRbacFormKey, + title: "Add Role", + onpressed: () { + RBAC? newRole; + if (addRbacFormKey.currentState! + .saveAndValidate()) { + newRole = RBAC( + id: null, + name: addRbacFormKey + .currentState + ?.value['object_name'], + slug: addRbacFormKey + .currentState + ?.value['slug'], + shorthand: addRbacFormKey + .currentState + ?.value['shorthand'], + fontawesomeIcon: null, + createdAt: null, + updatedAt: null, + createdBy: null, + updatedBy: null); + } + setState(() { + state.role.insert(0, newRole!); + }); + roleFocusNode.unfocus(); + Navigator.pop(context); + }, + )); + }), + const SizedBox( + height: 12, + ), + // //// Modules + StatefulBuilder( + builder: (context, setState) { + return SearchField( + itemHeight: 40, + suggestionsDecoration: box1(), + suggestions: state.modules + .map((RBAC module) => + SearchFieldListItem( + module.name!, + item: module, + child: Padding( + padding: + const EdgeInsets + .symmetric( + horizontal: 10), + child: ListTile( + title: Text( + module.name!, + overflow: TextOverflow + .visible, + )), + ))) + .toList(), + validator: (module) { + if (module!.isEmpty) { + return "This field is required"; + } + return null; + }, + focusNode: moduleFocusNode, + searchInputDecoration: + normalTextFieldStyle( + "Module *", "") + .copyWith( + suffixIcon: IconButton( + icon: const Icon( + Icons.arrow_drop_down), + onPressed: () { + moduleFocusNode.unfocus(); + }, + )), + onSuggestionTap: (module) { + setState(() { + selectedModule = module.item; + moduleFocusNode.unfocus(); + }); + }, + // //// Add new module + + emptyWidget: AddRbac( + formKey: addRbacFormKey, + title: "Add Module", + onpressed: () { + RBAC? newModule; + if (addRbacFormKey.currentState! + .saveAndValidate()) { + newModule = RBAC( + id: null, + name: addRbacFormKey + .currentState + ?.value['object_name'], + slug: addRbacFormKey + .currentState + ?.value['slug'], + shorthand: addRbacFormKey + .currentState + ?.value['shorthand'], + fontawesomeIcon: null, + createdAt: null, + updatedAt: null, + createdBy: null, + updatedBy: null); + } + setState(() { + state.modules + .insert(0, newModule!); + }); + moduleFocusNode.unfocus(); + Navigator.pop(context); + }, + )); + }), + const SizedBox( + height: 12, + ), + //// Permission + + StatefulBuilder( + builder: (context, setState) { + return SizedBox( + width: double.infinity, + child: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(5), + border: Border.all( + color: Colors.grey)), + child: Row( + children: [ + Expanded( + child: MultiSelectDropDown( + onOptionSelected: + (List + selectedOptions) { + setState(() { + valueItemSelectedPermissions = + selectedOptions; + }); + }, + hint: "Permissions", + hintStyle: const TextStyle( + fontSize: 16, + color: Colors.grey), + padding: + const EdgeInsets.all(8), + options: valueItemPermission, + selectionType: + SelectionType.multi, + chipConfig: const ChipConfig( + wrapType: + WrapType.scroll), + dropdownHeight: 300, + optionTextStyle: + const TextStyle( + fontSize: 16), + selectedOptionIcon: + const Icon( + Icons.check_circle), + ), + ), + const SizedBox( + width: 6, + ), + IconButton( + ////Add Permission not the dialog add button + onPressed: () { + final addPermissionFormKey = + GlobalKey(); + showDialog( + context: context, + builder: (BuildContext + context) { + String? objectname; + String? slug; + String? shorthand; + return AlertDialog( + title: Row( + children: [ + Expanded( + child: + Container( + child: !showAddOperations + ? const Text( + "Add new Permission") + : const Text( + "Add new Operation"), + ), + ), + ////close button + IconButton( + onPressed: + () { + setState( + () { + showAddOperations = + false; + }); + Navigator.pop( + context); + }, + icon: const Icon( + Icons + .close)) + ], + ), + content: StatefulBuilder( + builder: (context, + stateSetter) { + return showAddOperations + ////add permission content if choice is in the choices + ? FormBuilder( + key: + newOperationKey, + child: + Column( + mainAxisSize: + MainAxisSize.min, + children: [ + FormBuilderTextField( + onChanged: (value) { + objectname = value!; + }, + autovalidateMode: AutovalidateMode.always, + validator: FormBuilderValidators.required(errorText: "This field is required"), + name: "object_name", + decoration: normalTextFieldStyle("Object name *", "Object name "), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + onChanged: (value) { + slug = value!; + }, + name: "slug", + decoration: normalTextFieldStyle("Slug *", "Slug"), + ), + const SizedBox( + height: 8, + ), + FormBuilderTextField( + onChanged: (value) { + shorthand = value!; + }, + name: "shorthand", + decoration: normalTextFieldStyle("Shorthand *", "Shorthand"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double.infinity, + height: 50, + /////Add new Operation submit button + child: ElevatedButton( + style: mainBtnStyle(primary, Colors.transparent, second), + onPressed: () async { + if (newOperationKey.currentState!.saveAndValidate()) { + RBAC newOperation = RBAC(id: null, name: objectname, slug: slug, shorthand: shorthand, fontawesomeIcon: null, createdAt: null, updatedAt: null, createdBy: null, updatedBy: null); + stateSetter(() { + newOperations.add(newOperation); + valueItemOperation.insert(0, ValueItem(label: newOperation.name!, value: newOperation.name)); + showAddOperations = false; + }); + } + }, + child: const Text("Add"))), + ], + ), + ) + ////add permission content if choice is in the choices + : Form( + key: + addPermissionFormKey, + child: + Column( + mainAxisSize: + MainAxisSize.min, + children: [ + ////Object + SizedBox( + width: double.infinity, + child: + ////Row ofr operation and add operation + Row( + children: [ + ////Operations + Expanded( + child: MultiSelectDropDown( + onOptionSelected: (List selectedOptions) { + stateSetter(() { + ////get operation ids + selectedValueItemOperation = selectedOptions; + }); + }, + borderColor: Colors.grey, + borderWidth: 1, + borderRadius: 5, + hint: "Operations", + hintStyle: const TextStyle(fontSize: 16, color: Colors.grey), + padding: const EdgeInsets.all(8), + options: valueItemOperation, + selectionType: SelectionType.multi, + chipConfig: const ChipConfig(wrapType: WrapType.wrap), + dropdownHeight: 300, + optionTextStyle: const TextStyle(fontSize: 16), + selectedOptionIcon: const Icon(Icons.check_circle), + ), + ), + const SizedBox( + width: 5, + ), + Container( + decoration: BoxDecoration(border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(5)), + child: IconButton( + ////Add Operation beside row button + onPressed: () { + stateSetter(() { + showAddOperations = true; + }); + }, + icon: const Icon(Icons.add)), + ) + ], + )), + const SizedBox( + height: 12, + ), + SearchField( + itemHeight: 40, + suggestionsDecoration: box1(), + suggestions: state.objects + .map((RBAC object) => SearchFieldListItem(object.name!, + item: object, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: ListTile( + title: Text( + object.name!, + overflow: TextOverflow.visible, + )), + ))) + .toList(), + validator: (module) { + if (module!.isEmpty) { + return "This field is required"; + } + return null; + }, + focusNode: objectFocusNode, + searchInputDecoration: normalTextFieldStyle("Object *", "").copyWith( + suffixIcon: IconButton( + icon: const Icon(Icons.arrow_drop_down), + onPressed: () { + objectFocusNode.unfocus(); + }, + )), + onSuggestionTap: (object) { + stateSetter(() { + selectedObject = object.item; + objectFocusNode.unfocus(); + }); + }, + ////Add new Object + emptyWidget: AddRbac( + formKey: addRbacFormKey, + title: "Add Add Object", + onpressed: () { + if (addRbacFormKey.currentState!.saveAndValidate()) { + RBAC? newObject; + + if (addRbacFormKey.currentState!.saveAndValidate()) { + newObject = RBAC(id: null, name: addRbacFormKey.currentState?.value['object_name'], slug: addRbacFormKey.currentState?.value['slug'], shorthand: addRbacFormKey.currentState?.value['shorthand'], fontawesomeIcon: null, createdAt: null, updatedAt: null, createdBy: null, updatedBy: null); + } + stateSetter(() { + state.objects.insert(0, newObject!); + }); + objectFocusNode.unfocus(); + Navigator.pop(context); + } + }, + )), + const SizedBox( + height: 20, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + onPressed: () { + ////Add Operation + if (addPermissionFormKey.currentState!.validate()) { + selectedValueItemOperation.forEach((e) { + setState(() { + // state.permission.insert(0, Permission(id: null, object: selectedObject!, operation: RBAC(id: null, name: e.label, slug: null, shorthand: null, fontawesomeIcon: null, createdAt: null, updatedAt: null, createdBy: null, updatedBy: null), createdAt: null, updatedAt: null, createdBy: null, updatedBy: null)); + valueItemPermission.insert(0, ValueItem(label: "${selectedObject!.name} - ${e.label}")); + valueItemPermission = valueItemPermission; + }); + }); + Navigator.pop(context); + setState(() {}); + } + }, + style: mainBtnStyle(primary, Colors.transparent, second), + child: const Text("Submit"), + )) + ], + )); + })); + }); + }, + icon: const Icon(Icons.add)), + ], + ), + ), + ); + }), + const SizedBox( + height: 12, + ), + ], + )), + SizedBox( + height: 50, + width: double.infinity, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + if (formKey.currentState! + .saveAndValidate()) { + ////existing permission + List permissions = + valueItemSelectedPermissions + .map((e) => + int.parse(e.value!)) + .toList(); + + context.read().add( + AssignedRbac( + assigneeId: + selectedWebUserId!, + assignerId: 63, + newPermissions: [], + permissionId: permissions, + selectedModule: + selectedModule, + selectedRole: selectedRole)); + } + print(valueItemSelectedPermissions + .length); + }, + child: const Text("submit")), + ) + ], + )), + ); + } + if (state is RbacErrorState) { + return SomethingWentWrong( + message: state.message, onpressed: () {}); + } + return Container(); + }, + ); + } + return Container(); + }, + ), + )); + } +} diff --git a/lib/screens/utils/formatters.dart b/lib/screens/utils/formatters.dart new file mode 100644 index 0000000..b9f78bb --- /dev/null +++ b/lib/screens/utils/formatters.dart @@ -0,0 +1 @@ +// TODO Implement this library. \ No newline at end of file diff --git a/lib/sevices/roles/pass_check_services.dart b/lib/sevices/roles/pass_check_services.dart index 3b076a6..8ff5c22 100644 --- a/lib/sevices/roles/pass_check_services.dart +++ b/lib/sevices/roles/pass_check_services.dart @@ -32,7 +32,7 @@ class PassCheckServices { 'X-Client-Key': xClientKey, 'X-Client-Secret': xClientSecret }; - try { + // try { http.Response response = await Request.instance .getRequest(param: params, headers: headers, path: path); if (response.statusCode == 200) { @@ -133,9 +133,9 @@ class PassCheckServices { statusResponse = assignedArea; } } - } catch (e) { - throw e.toString(); - } + // } catch (e) { + // throw e.toString(); + // } return statusResponse!; } diff --git a/lib/sevices/roles/rbac_operations/agency_services.dart b/lib/sevices/roles/rbac_operations/agency_services.dart new file mode 100644 index 0000000..3f8d713 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/agency_services.dart @@ -0,0 +1,73 @@ +import 'dart:convert'; + +import 'package:unit2/screens/profile/components/other_information/org_membership/add_modal.dart'; +import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/urls.dart'; + +import '../../../model/utils/agency.dart'; +import 'package:http/http.dart' as http; + +class AgencyServices { + static final AgencyServices _instance = AgencyServices(); + static AgencyServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getAgencies() async { + List agencies = []; + String path = Url.instance.agencies(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(path: path, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var element in data['data']) { + Agency newAgency = Agency.fromJson(element); + agencies.add(newAgency); + } + } + } + } catch (e) { + throw e.toString(); + } + return agencies; + } + Future>add({required Agency agency})async{ + Map statusResponse = {}; + String path = Url.instance.postAgencies(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + Map body = { + "name":agency.name, + "category_id":agency.category!.id, + "private_entity":agency.privateEntity, + "contact_info":null, + }; + try{ + http.Response response = await Request.instance.postRequest(param: {},path: path, body: body,headers: headers); + if(response.statusCode == 201){ + Map data = jsonDecode(response.body); + statusResponse = data; + }else{ + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + }catch(e){ + throw e.toString(); + } + return statusResponse; + } +} diff --git a/lib/sevices/roles/rbac_operations/module_objects_services.dart b/lib/sevices/roles/rbac_operations/module_objects_services.dart new file mode 100644 index 0000000..87e9890 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/module_objects_services.dart @@ -0,0 +1,98 @@ +import 'dart:convert'; + +import 'package:unit2/model/login_data/user_info/module.dart'; +import 'package:http/http.dart' as http; +import '../../../model/rbac/rbac_rbac.dart'; +import '../../../utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacModuleObjectsServices { + static final RbacModuleObjectsServices _instance = + RbacModuleObjectsServices(); + static RbacModuleObjectsServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + Future> getModuleObjects() async { + List moduleObjects = []; + String path = Url.instance.getModuleObjects(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var modObj in data['data']) { + ModuleObjects newModObj = ModuleObjects.fromJson(modObj); + moduleObjects.add(newModObj); + } + } + } + } catch (e) { + throw e.toString(); + } + return moduleObjects; + } + + ////Add + Future> add({ + required int assignerId, + required int? moduleId, + required List objectsId, + }) async { + String path = Url.instance.getModuleObjects(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + Map body = { + "module_id": moduleId, + "objects": objectsId, + "assigner_user_id": assignerId + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future deleteRbacModuleObject({required int moduleObjectId}) async { + bool success = false; + String path = "${Url.instance.getModuleObjects()}$moduleObjectId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/module_services.dart b/lib/sevices/roles/rbac_operations/module_services.dart new file mode 100644 index 0000000..76ea4a1 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/module_services.dart @@ -0,0 +1,146 @@ +import 'dart:convert'; + +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:http/http.dart' as http; +import 'package:unit2/utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacModuleServices { + static final RbacModuleServices _instance = RbacModuleServices(); + static RbacModuleServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getRbacModule() async { + List modules = []; + String path = Url.instance.getModules(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var rbac in data['data']) { + RBAC newModule = RBAC.fromJson(rbac); + modules.add(newModule); + } + } + } + } catch (e) { + throw e.toString(); + } + + return modules; + } + ////Add + Future> add( + {required String name, + required String? slug, + required String? short, + required int id}) async { + String path = Url.instance.getModules(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + String? newSlug = slug?.replaceAll(" ", "-"); + Map body = { + "name": name, + "slug": newSlug?.toLowerCase(), + "shorthand": short, + "fontawesome_icon":"mobile", + "created_by_id": id, + "updated_by_id": id + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + ////Update + Future> update({ + required int moduleId, + required String name, + required String? slug, + required String? short, + required int? createdBy, + required int updatedBy, + }) async { + String path = "${Url.instance.getModules()}$moduleId/"; + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + String? newSlug = slug?.replaceAll(" ", "-"); + Map body = { + "name": name, + "slug": newSlug?.toLowerCase(), + "shorthand": short, + "created_by_id": createdBy, + "updated_by_id": updatedBy, + "fontawesome_icon":"mobile", + }; + try { + http.Response response = await Request.instance + .putRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future deleteRbacModule({required int moduleId}) async { + bool success = false; + String path = "${Url.instance.getModules()}$moduleId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/object_services.dart b/lib/sevices/roles/rbac_operations/object_services.dart new file mode 100644 index 0000000..402b2ac --- /dev/null +++ b/lib/sevices/roles/rbac_operations/object_services.dart @@ -0,0 +1,144 @@ +import 'dart:convert'; + +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:http/http.dart' as http; +import 'package:unit2/utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacObjectServices { + static final RbacObjectServices _instance = RbacObjectServices(); + static RbacObjectServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getRbacObjects() async { + List objects = []; + String path = Url.instance.getObject(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var rbac in data['data']) { + RBAC newRbac = RBAC.fromJson(rbac); + objects.add(newRbac); + } + } + } + } catch (e) { + throw e.toString(); + } + + return objects; + } + ////Add + Future> add( + {required String name, + required String? slug, + required String? short, + required int id}) async { + String path = Url.instance.getObject(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + String? newSlug = slug?.replaceAll(" ", "-"); + Map body = { + "name": name, + "slug": newSlug?.toLowerCase(), + "shorthand": short, + "created_by_id": id, + "updated_by_id": id + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + ////Update + Future> update({ + required int objectId, + required String name, + required String? slug, + required String? short, + required int? createdBy, + required int updatedBy, + }) async { + String path = "${Url.instance.getObject()}$objectId/"; + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + String? newSlug = slug?.replaceAll(" ", "-"); + Map body = { + "name": name, + "slug": newSlug?.toLowerCase(), + "shorthand": short, + "created_by_id": createdBy, + "updated_by_id": updatedBy + }; + try { + http.Response response = await Request.instance + .putRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future deleteRbacRole({required int objectId}) async { + bool success = false; + String path = "${Url.instance.getObject()}$objectId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/operation_services.dart b/lib/sevices/roles/rbac_operations/operation_services.dart new file mode 100644 index 0000000..f737dc7 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/operation_services.dart @@ -0,0 +1,144 @@ +import 'dart:convert'; + +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:http/http.dart' as http; +import 'package:unit2/utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacOperationServices { + static final RbacOperationServices _instance = RbacOperationServices(); + static RbacOperationServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getRbacOperations() async { + List roles = []; + String path = Url.instance.getOperations(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var role in data['data']) { + RBAC newRole = RBAC.fromJson(role); + roles.add(newRole); + } + } + } + } catch (e) { + throw e.toString(); + } + + return roles; + } + ////Add + Future> add( + {required String name, + required String? slug, + required String? short, + required int id}) async { + String path = Url.instance.getOperations(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + String? newSlug = slug?.replaceAll(" ", "-"); + Map body = { + "name": name, + "slug": newSlug?.toLowerCase(), + "shorthand": short, + "created_by_id": id, + "updated_by_id": id + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + ////Update + Future> update({ + required int operationId, + required String name, + required String? slug, + required String? short, + required int? createdBy, + required int updatedBy, + }) async { + String path = "${Url.instance.getRbacOperations()}$operationId/"; + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + String? newSlug = slug?.replaceAll(" ", "-"); + Map body = { + "name": name, + "slug": newSlug?.toLowerCase(), + "shorthand": short, + "created_by_id": createdBy, + "updated_by_id": updatedBy + }; + try { + http.Response response = await Request.instance + .putRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future delete({required int operation}) async { + bool success = false; + String path = "${Url.instance.getRbacOperations()}$operation/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/permission_service.dart b/lib/sevices/roles/rbac_operations/permission_service.dart new file mode 100644 index 0000000..aa49ba5 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/permission_service.dart @@ -0,0 +1,100 @@ +import 'dart:convert'; + +import 'package:unit2/model/rbac/permission.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:http/http.dart' as http; +import 'package:unit2/utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacPermissionServices { + static final RbacPermissionServices _instance = RbacPermissionServices(); + static RbacPermissionServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getRbacPermission() async { + List permissions = []; + String path = Url.instance.getPersmissions(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var rbac in data['data']) { + RBACPermission newRbac = RBACPermission.fromJson(rbac); + permissions.add(newRbac); + } + } + } + } catch (e) { + throw e.toString(); + } + + return permissions; + } + + + ////Add + Future> add({ + required int assignerId, + required int? objectId, + required List operationsId, + }) async { + String path = Url.instance.getPersmissions(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + Map body = { + "object_id": objectId, + "operations": operationsId, + "assigner_user_id": assignerId + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future deletePermission ({required int permissionId}) async { + bool success = false; + String path = "${Url.instance.getPersmissions()}$permissionId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/role_assignment_services.dart b/lib/sevices/roles/rbac_operations/role_assignment_services.dart new file mode 100644 index 0000000..b9d6eae --- /dev/null +++ b/lib/sevices/roles/rbac_operations/role_assignment_services.dart @@ -0,0 +1,137 @@ +import 'dart:convert'; + +import 'package:unit2/model/rbac/assigned_role.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/urls.dart'; + +import 'package:http/http.dart' as http; + +import '../../../model/profile/basic_information/primary-information.dart'; + +class RbacRoleAssignmentServices { + static final RbacRoleAssignmentServices _instance = + RbacRoleAssignmentServices(); + static RbacRoleAssignmentServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getAssignedRoles( + {required String firstname, required String lastname}) async { + List assignedRoles = []; + String path = Url.instance.getRoleAssignment(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + Map param = { + "user__first_name__icontains": firstname, + "user__last_name__icontains": lastname + }; + try { + http.Response response = await Request.instance + .getRequest(param: param, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var role in data['data']) { + AssignedRole newRole = AssignedRole.fromJson(role); + assignedRoles.add(newRole); + } + } + } + } catch (e) { + throw e.toString(); + } + return assignedRoles; + } + + Future deleteAssignedRole({required int roleId}) async { + bool success = false; + String path = "${Url.instance.getRoleAssignment()}$roleId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } + ////Add + Future> add({ + required int userId, + required int? assignerId, + required List roles, + }) async { + String path = Url.instance.getRoleAssignment(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + Map body = { + "user_id": userId, + "roles": roles, + "assigner_user_id": assignerId, + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future searchUser( + {required int page, required String name, required String lastname}) async { + String path = Url.instance.searchUsers(); + Profile? user; + Map params = { + "profile__last_name__icontains": lastname, + "profile__first_name__icontains": name, + "page": page.toString(), + "is_paginated": "true", + }; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + + http.Response response = await Request.instance + .getRequest(param: params, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + for(var profile in data['data']) { + int websuerId = profile['webuserid']; + Profile newUser = Profile.fromJson(profile['profile']); + newUser.webuserId = websuerId; + user= newUser; + break; + } + } + + return user; + } + +} diff --git a/lib/sevices/roles/rbac_operations/role_extend_services.dart b/lib/sevices/roles/rbac_operations/role_extend_services.dart new file mode 100644 index 0000000..b5c0fc9 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/role_extend_services.dart @@ -0,0 +1,96 @@ +import 'dart:convert'; + +import 'package:unit2/model/rbac/role_extend.dart'; +import 'package:unit2/model/rbac/role_under.dart'; +import 'package:http/http.dart' as http; +import '../../../utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacRoleExtendServices { + static final RbacRoleExtendServices _instance = RbacRoleExtendServices(); + static RbacRoleExtendServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getRolesExtend() async { + List rolesextend = []; + String path = Url.instance.getRoleExtend(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + // try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var roleExt in data['data']) { + RolesExtend newRoleExtend = RolesExtend.fromJson(roleExt); + rolesextend.add(newRoleExtend); + } + } + } + // } catch (e) { + // throw e.toString(); + // } + return rolesextend; + } + + ////Add + Future> add({ + required int? roleId, + required List rolesExtendsId, + }) async { + String path = Url.instance.getRoleExtend(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + Map body = { + "role_main_id": roleId, + "roles_extend": rolesExtendsId, + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future delete({required int roleExtendId}) async { + bool success = false; + String path = "${Url.instance.getRoleExtend()}$roleExtendId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/role_module_services.dart b/lib/sevices/roles/rbac_operations/role_module_services.dart new file mode 100644 index 0000000..27a0779 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/role_module_services.dart @@ -0,0 +1,100 @@ +import 'dart:convert'; + +import 'package:unit2/model/login_data/user_info/module.dart'; +import 'package:http/http.dart' as http; +import 'package:unit2/model/rbac/role_module.dart'; +import '../../../model/rbac/rbac_rbac.dart'; +import '../../../utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacRoleModuleServices { + static final RbacRoleModuleServices _instance = + RbacRoleModuleServices(); + static RbacRoleModuleServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getRoleModules() async { + List roleModules = []; + String path = Url.instance.getRoleModules(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var roleMod in data['data']) { + RoleModules newRoleMod = RoleModules.fromJson(roleMod); + roleModules.add(newRoleMod); + } + } + } + } catch (e) { + throw e.toString(); + } + return roleModules; + } + + ////Add + Future> add({ + required int assignerId, + required int? roleId, + required List moduleIds, + }) async { + String path = Url.instance.getRoleModules(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + Map body = { + "role_id": roleId, + "modules": moduleIds, + "assigner_user_id": assignerId + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future deleteRbacRoleModule({required int moduleObjectId}) async { + bool success = false; + String path = "${Url.instance.getRoleModules()}$moduleObjectId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/role_services.dart b/lib/sevices/roles/rbac_operations/role_services.dart new file mode 100644 index 0000000..08a689c --- /dev/null +++ b/lib/sevices/roles/rbac_operations/role_services.dart @@ -0,0 +1,146 @@ +import 'dart:convert'; + +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/sevices/profile/education_services.dart'; +import 'package:http/http.dart' as http; +import 'package:unit2/utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacRoleServices { + static final RbacRoleServices _instance = RbacRoleServices(); + static RbacRoleServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getRbacRoles() async { + List roles = []; + String path = Url.instance.getRbacRoles(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var role in data['data']) { + RBAC newRole = RBAC.fromJson(role); + roles.add(newRole); + } + } + } + } catch (e) { + throw e.toString(); + } + + return roles; + } + +////Add + Future> add( + {required String name, + required String? slug, + required String? short, + required int id}) async { + String path = Url.instance.getRbacRoles(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + String? newSlug = slug?.replaceAll(" ", "-"); + Map body = { + "name": name, + "slug": newSlug?.toLowerCase(), + "shorthand": short, + "created_by_id": id, + "updated_by_id": id + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + ////Update + Future> update({ + required int roleId, + required String name, + required String? slug, + required String? short, + required int? createdBy, + required int updatedBy, + }) async { + String path = "${Url.instance.getRbacRoles()}$roleId/"; + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + String? newSlug = slug?.replaceAll(" ", "-"); + Map body = { + "name": name, + "slug": newSlug?.toLowerCase(), + "shorthand": short, + "created_by_id": createdBy, + "updated_by_id": updatedBy + }; + try { + http.Response response = await Request.instance + .putRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + Future deleteRbacRole({required int roleId}) async { + bool success = false; + String path = "${Url.instance.getRbacRoles()}$roleId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/roles_under_services.dart b/lib/sevices/roles/rbac_operations/roles_under_services.dart new file mode 100644 index 0000000..719dab4 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/roles_under_services.dart @@ -0,0 +1,96 @@ +import 'dart:convert'; + +import 'package:unit2/model/rbac/role_under.dart'; +import 'package:http/http.dart' as http; +import '../../../utils/request.dart'; +import '../../../utils/urls.dart'; + +class RbacRoleUnderServices { + static final RbacRoleUnderServices _instance = RbacRoleUnderServices(); + static RbacRoleUnderServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getRolesUnder() async { + List rolesUnder = []; + String path = Url.instance.getRolesUnder(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + for (var roleUnd in data['data']) { + RolesUnder newRoleUnder = RolesUnder.fromJson(roleUnd); + rolesUnder.add(newRoleUnder); + } + } + } + } catch (e) { + throw e.toString(); + } + return rolesUnder; + } + + ////Add + Future> add({ + required int? roleId, + required List rolesId, + }) async { + String path = Url.instance.getRolesUnder(); + Map statusResponse = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + Map body = { + "role_main_id": roleId, + "roles_under": rolesId, + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, body: body, headers: headers, param: {}); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + Map data = jsonDecode(response.body); + String message = data['message']; + statusResponse.addAll({'message': message}); + statusResponse.addAll( + {'success': false}, + ); + } + } catch (e) { + throw e.toString(); + } + return statusResponse; + } + + + Future deleteRbacRoleUnder({required int roleUnderId}) async { + bool success = false; + String path = "${Url.instance.getRolesUnder ()}$roleUnderId/"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try { + http.Response response = await Request.instance + .deleteRequest(path: path, headers: headers, body: {}, param: {}); + if (response.statusCode == 200) { + success = true; + } + } catch (e) { + throw e.toString(); + } + return success; + } +} diff --git a/lib/sevices/roles/rbac_operations/station_services.dart b/lib/sevices/roles/rbac_operations/station_services.dart new file mode 100644 index 0000000..9170583 --- /dev/null +++ b/lib/sevices/roles/rbac_operations/station_services.dart @@ -0,0 +1,39 @@ +import 'dart:convert'; +import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/urls.dart'; +import 'package:http/http.dart' as http; + +import '../../../model/rbac/rbac_station.dart'; +import '../../../model/roles/pass_check/station_assign_area.dart'; +class RbacStationServices{ + static final RbacStationServices _instance = RbacStationServices(); + static RbacStationServices get instance => _instance; + String xClientKey = "unitK3CQaXiWlPReDsBzmmwBZPd9Re1z"; + String xClientKeySecret = "unitcYqAN7GGalyz"; + + Future> getStations({required int agencyId})async{ + List stations = []; + String path = Url.instance.getStation(); + Map param = {"government_agency_id":agencyId.toString()}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientKeySecret + }; + try{ + http.Response response = await Request.instance.getRequest(param: param,path: path,headers: headers); + if(response.statusCode == 200){ + Map data = jsonDecode(response.body); + if(data['data'] != null){ + for(var station in data['data']){ + RbacStation area = RbacStation.fromJson(station); + stations.add(area); + } + } + } + }catch(e){ + throw e.toString(); + } + return stations; + } +} \ No newline at end of file diff --git a/lib/sevices/roles/rbac_services.dart b/lib/sevices/roles/rbac_services.dart new file mode 100644 index 0000000..da172e4 --- /dev/null +++ b/lib/sevices/roles/rbac_services.dart @@ -0,0 +1,218 @@ +import 'dart:convert'; + +import 'package:dio/dio.dart'; +import 'package:unit2/model/rbac/permission.dart'; +import 'package:unit2/model/rbac/rbac.dart'; +import 'package:unit2/utils/request.dart'; + +import '../../model/profile/basic_information/primary-information.dart'; +import '../../model/rbac/new_permission.dart'; +import '../../utils/global.dart'; +import '../../utils/urls.dart'; +import 'package:http/http.dart' as http; + +class RbacServices { + static final RbacServices _instance = RbacServices(); + static RbacServices get instance => _instance; + Future> getModules() async { + List modules = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientSecret + }; + String path = Url.instance.getModules(); + try { + http.Response response = await Request.instance + .getRequest(path: path, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + data['data'].forEach((var module) { + print(module); + RBAC newModule = RBAC.fromJson(module); + modules.add(newModule); + }); + } + } catch (e) { + throw e.toString(); + } + return modules; + } + + Future> getObjects() async { + List objects = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientSecret + }; + String path = Url.instance.getObject(); + try { + http.Response response = await Request.instance + .getRequest(path: path, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + data['data'].forEach((var object) { + RBAC newObject = RBAC.fromJson(object); + objects.add(newObject); + }); + } + } catch (e) { + throw e.toString(); + } + return objects; + } + + Future> getRole() async { + List roles = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientSecret + }; + String path = Url.instance.getRoles(); + try { + http.Response response = await Request.instance + .getRequest(path: path, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + data['data'].forEach((var role) { + RBAC newRole = RBAC.fromJson(role); + roles.add(newRole); + }); + } + } catch (e) { + throw e.toString(); + } + return roles; + } + + Future> getPermission() async { + List permissions = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientSecret + }; + String path = Url.instance.getPersmissions(); + try { + http.Response response = await Request.instance + .getRequest(path: path, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + data['data'].forEach((var permission) { + RBACPermission newPermission = RBACPermission.fromJson(permission); + permissions.add(newPermission); + }); + } + } catch (e) { + throw e.toString(); + } + return permissions; + } + + Future> getOperations() async { + List operations = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientSecret + }; + String path = Url.instance.getOperations(); + try { + http.Response response = await Request.instance + .getRequest(path: path, headers: headers, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + data['data'].forEach((var operation) { + RBAC newOperation = RBAC.fromJson(operation); + operations.add(newOperation); + }); + } + } catch (e) { + throw e.toString(); + } + return operations; + } + + Future> searchUser( + {required int page, required String name, required String token}) async { + List users = []; + String path = Url.instance.searchUsers(); + String authtoken = "Token $token"; + Map params = { + "profile__last_name__icontains": name, + "page": page.toString(), + "is_paginated": "true", + }; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + + http.Response response = await Request.instance + .getRequest(param: params, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + data['data'].forEach((profile) { + int websuerId = profile['webuserid']; + Profile newUsers = Profile.fromJson(profile['profile']); + newUsers.webuserId = websuerId; + users.add(newUsers); + }); + } + + return users; + } + + Future> assignRBAC( + {required int assigneeId, + required int assignerId, + required RBAC? selectedRole, + required RBAC? selectedModule, + required List permissionId, + required List newPermissions}) async { + bool success = false; + String path = Url.instance.assignRbac(); + Map responseStatus = {}; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'X-Client-Key': xClientKey, + 'X-Client-Secret': xClientSecret + }; + Map body = { + "assignee_user_id": assigneeId, + "assigner_user_id": assignerId, + "role_id": selectedRole?.id, + "_new_role_name": selectedRole?.name, + "_new_role_slug": selectedRole?.slug, + "_new_role_shorthand": selectedRole?.shorthand, + "module_id": selectedModule?.id, + "_new_module_name": selectedModule?.name, + "_new_module_slug": selectedModule?.slug, + "_new_module_shorthand": selectedModule?.shorthand, + "_new_module_icon": null, + "permission_ids": permissionId, + "_new_permissions": newPermissions, + "assigned_areas": [] + }; + try { + http.Response response = await Request.instance + .postRequest(path: path, param: {}, body: body, headers: headers); + Map data = jsonDecode(response.body); + if (response.statusCode == 201) { + success = true; + String message = data['message']; + responseStatus.addAll({"success": success, "message": message}); + } else { + success = false; + String message = data['message']; + responseStatus.addAll({"success": success, "message": message}); + } + } catch (e) { + throw e.toString(); + } + + return responseStatus; + } +} diff --git a/lib/utils/app_router.dart b/lib/utils/app_router.dart index 3bf9c9b..610fd3f 100644 --- a/lib/utils/app_router.dart +++ b/lib/utils/app_router.dart @@ -4,10 +4,12 @@ import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/bloc/role/pass_check/pass_check_bloc.dart'; import 'package:unit2/bloc/sos/sos_bloc.dart'; import 'package:unit2/screens/sos/index.dart'; -import 'package:unit2/screens/unit2/homepage.dart/components/dashboard.dart'; +import 'package:unit2/screens/unit2/homepage.dart/components/dashboard/dashboard.dart'; import 'package:unit2/screens/unit2/homepage.dart/components/menu.dart'; import 'package:unit2/screens/unit2/login/login.dart'; +import 'package:unit2/screens/unit2/roles/rbac/rbac.dart'; import 'package:unit2/utils/global_context.dart'; +import '../bloc/rbac/rbac_bloc.dart'; import '../bloc/user/user_bloc.dart'; import '../screens/profile/profile.dart'; import '../screens/unit2/basic-info/basic-info.dart'; @@ -62,6 +64,12 @@ class AppRouter { child: QRCodeScannerSettings(roleId: arguments.roleId, userId: arguments.userId,), ); }); + case '/rbac': + return MaterialPageRoute(builder: (BuildContext context){ + return BlocProvider( + create: (_) => RbacBloc()..add(SetRbacScreen()), + child:const RBACScreen(), + );}); default: return MaterialPageRoute(builder: (context) { return Container(); diff --git a/lib/utils/urls.dart b/lib/utils/urls.dart index 5dea2f3..9669a61 100644 --- a/lib/utils/urls.dart +++ b/lib/utils/urls.dart @@ -4,11 +4,11 @@ class Url { static Url get instance => _instance; String host() { - // return '192.168.10.183:3000'; - return 'agusandelnorte.gov.ph'; + // return '192.168.10.183:3000'; + // return 'agusandelnorte.gov.ph'; // return "192.168.10.219:3000"; // return "192.168.10.241"; - // return "192.168.10.221:3004"; + return "192.168.10.221:3004"; // return "playweb.agusandelnorte.gov.ph"; // return 'devapi.agusandelnorte.gov.ph:3004'; } @@ -17,211 +17,306 @@ class Url { return '/api/account/auth/login/'; } - String profileInformation(){ + String profileInformation() { return 'api/jobnet_app/profile/pds/'; } - String latestApk(){ + String latestApk() { return "/api/system_app/apk_version/latest"; } ////SOS paths - String sosRequest(){ + String sosRequest() { return "/api/sos_app/sos_request/"; } //// DOCSMS paths - String getDocument(){ + String getDocument() { return "/api/web_app/public/document_viewer/"; } ////ELIGIBILITIES PATHS -String eligibilities(){ - return "/api/jobnet_app/eligibilities/"; -} + String eligibilities() { + return "/api/jobnet_app/eligibilities/"; + } -String getEligibilities(){ - return "/api/jobnet_app/profile/pds/eligibility/"; -} + String getEligibilities() { + return "/api/jobnet_app/profile/pds/eligibility/"; + } -String addEligibility(){ - return "/api/jobnet_app/profile/pds/eligibility/"; -} -String deleteEligibility(){ - return "/api/jobnet_app/profile/pds/eligibility/"; -} + String addEligibility() { + return "/api/jobnet_app/profile/pds/eligibility/"; + } + + String deleteEligibility() { + return "/api/jobnet_app/profile/pds/eligibility/"; + } + + String updateEligibility() { + return "/api/jobnet_app/profile/pds/eligibility/"; + } -String updateEligibility(){ - return "/api/jobnet_app/profile/pds/eligibility/"; -} //// work history paths -String workhistory(){ - return "/api/jobnet_app/profile/pds/work/"; -} -String getPositions(){ - return "/api/jobnet_app/positions/"; -} -String getAgencies(){ + String workhistory() { + return "/api/jobnet_app/profile/pds/work/"; + } + + String getPositions() { + return "/api/jobnet_app/positions/"; + } + + String getAgencies() { return "/api/jobnet_app/agencies/"; -} + } -String getAgencyCategory(){ - return "api/jobnet_app/agency_categories/"; -} - -String identifications(){ - return "/api/jobnet_app/profile/pds/basic/identification/"; -} + String getAgencyCategory() { + return "api/jobnet_app/agency_categories/"; + } + String identifications() { + return "/api/jobnet_app/profile/pds/basic/identification/"; + } ////educational background paths -String educationalBackground(){ - return "/api/jobnet_app/profile/pds/education/"; -} -String getSchools(){ - return "/api/jobnet_app/schools/"; -} -String getPrograms(){ - return "api/jobnet_app/education_programs/"; -} -String getHonors(){ - return "/api/jobnet_app/honors"; -} + String educationalBackground() { + return "/api/jobnet_app/profile/pds/education/"; + } + + String getSchools() { + return "/api/jobnet_app/schools/"; + } + + String getPrograms() { + return "api/jobnet_app/education_programs/"; + } + + String getHonors() { + return "/api/jobnet_app/honors"; + } //// learning and development paths -String learningAndDevelopments(){ - return "api/jobnet_app/profile/pds/learning_development/"; -} -String conductedTrainings(){ - return "api/jobnet_app/conducted_trainings/"; -} -String learningAndDevelopmentType(){ - return "api/jobnet_app/learning_development/"; -} -String learningAndDevelopmentTopics(){ - return "api/jobnet_app/training_topics/"; -} + String learningAndDevelopments() { + return "api/jobnet_app/profile/pds/learning_development/"; + } + + String conductedTrainings() { + return "api/jobnet_app/conducted_trainings/"; + } + + String learningAndDevelopmentType() { + return "api/jobnet_app/learning_development/"; + } + + String learningAndDevelopmentTopics() { + return "api/jobnet_app/training_topics/"; + } //// references paths -String reference(){ - return "/api/jobnet_app/profile/pds/personal_reference/"; -} - + String reference() { + return "/api/jobnet_app/profile/pds/personal_reference/"; + } ////voluntary works -String getVoluntaryWorks(){ - return "/api/jobnet_app/profile/pds/voluntary_work/"; -} + String getVoluntaryWorks() { + return "/api/jobnet_app/profile/pds/voluntary_work/"; + } //// skills hobbies -String skillsHobbies(){ - return "/api/jobnet_app/profile/pds/other/skill_hobby/"; -} -String getAllSkillsHobbies(){ - return "/api/jobnet_app/skill_hobby/"; -} + String skillsHobbies() { + return "/api/jobnet_app/profile/pds/other/skill_hobby/"; + } + + String getAllSkillsHobbies() { + return "/api/jobnet_app/skill_hobby/"; + } + //// orgmemberships -String getOrgMemberShips(){ - return "/api/jobnet_app/profile/pds/other/org_membership/"; -} + String getOrgMemberShips() { + return "/api/jobnet_app/profile/pds/other/org_membership/"; + } ////non academic recognition -String getNonAcademicRecognition(){ - return "/api/jobnet_app/profile/pds/other/non_acad_recognition/"; -} + String getNonAcademicRecognition() { + return "/api/jobnet_app/profile/pds/other/non_acad_recognition/"; + } ////citizenship -String citizenship(){ - return "/api/jobnet_app/profile/pds/basic/citizenship/"; -} + String citizenship() { + return "/api/jobnet_app/profile/pds/basic/citizenship/"; + } ////family paths -String getFamilies(){ - return "/api/jobnet_app/profile/pds/family/"; -} -String addEmergency(){ - return "/api/profile_app/person_emergency/"; -} -String getRelationshipTypes(){ - return "/api/jobnet_app/relationship_types"; -} -String updatePersonalInfor(){ - return "/api/jobnet_app/profile/pds/basic/personal/"; -} + String getFamilies() { + return "/api/jobnet_app/profile/pds/family/"; + } + String addEmergency() { + return "/api/profile_app/person_emergency/"; + } + + String getRelationshipTypes() { + return "/api/jobnet_app/relationship_types"; + } + + String updatePersonalInfor() { + return "/api/jobnet_app/profile/pds/basic/personal/"; + } //// contacts path -String getServiceTypes(){ - return "/api/jobnet_app/comm_service_type/"; + String getServiceTypes() { + return "/api/jobnet_app/comm_service_type/"; + } -} //// address path -String addressPath(){ - return "/api/jobnet_app/profile/pds/basic/address/"; -} + String addressPath() { + return "/api/jobnet_app/profile/pds/basic/address/"; + } + + String contactPath() { + return "/api/jobnet_app/profile/pds/basic/contact/"; + } + + String getCommunicationProvider() { + return "/api/jobnet_app/comm_services/"; + } + + String deleteContact() { + return "/api/jobnet_app/profile/pds/basic/contact/"; + } -String contactPath(){ - return "/api/jobnet_app/profile/pds/basic/contact/"; -} -String getCommunicationProvider(){ - return "/api/jobnet_app/comm_services/"; -} -String deleteContact (){ - return "/api/jobnet_app/profile/pds/basic/contact/"; -} ////profile other info -String getReligions(){ - return "/api/profile_app/religion/"; -} -String getEthnicity(){ - return "/api/profile_app/ethnicity/"; -} + String getReligions() { + return "/api/profile_app/religion/"; + } -String getDisability(){ - return "api/profile_app/disability/"; -} + String getEthnicity() { + return "/api/profile_app/ethnicity/"; + } -String getIndigency(){ - return "/api/profile_app/indigenous/"; -} + String getDisability() { + return "api/profile_app/disability/"; + } -String getGenders(){ - return "/api/profile_app/gender/"; -} + String getIndigency() { + return "/api/profile_app/indigenous/"; + } + + String getGenders() { + return "/api/profile_app/gender/"; + } /////ROLES // pass check -String getAssignAreas(){ - return "/api/account/auth/assigned_role_area/"; -} + String getAssignAreas() { + return "/api/account/auth/assigned_role_area/"; + } -String getPasserInfo(){ - return "/api/profile_app/person_basicinfo/"; -} + String getPasserInfo() { + return "/api/profile_app/person_basicinfo/"; + } -String postLogs(){ - return "/api/unit2_app/monitoring/pass_check/"; -} + String postLogs() { + return "/api/unit2_app/monitoring/pass_check/"; + } + String passCheck() { + return "/api/unit2_app/monitoring/pass_check"; + } +////rbac + + String getRbacRoles() { + return "/api/account/auth/roles/"; + } + + String searchUsers() { + return "/api/hrms_app/employee_details/"; + } + + String assignRbac() { + return "/api/account/auth/rbac/"; + } + +////rbac operations + + String getRbacOperations() { + return "/api/account/auth/operations/"; + } + + String getPersmissions() { + return "/api/account/auth/permissionrbac/"; + } + + String getRoles() { + return "/api/account/auth/roles/"; + } + + String getOperations() { + return "/api/account/auth/operations/"; + } + + String getModules() { + return "/api/account/auth/modules/"; + } + + String getObject() { + return "/api/account/auth/objects/"; + } + + String getModuleObjects() { + return "/api/account/auth/moduleobject/"; + } + + String agencies() { + return "/api/jobnet_app/agencies/"; + } + + String postAgencies() { + return "/api/profile_app/agencies/"; + } + + String getRoleModules() { + return "/api/account/auth/rolemodules/"; + } + + String getRolesUnder() { + return "/api/account/auth/rolesunder/"; + } + + String getRoleExtend() { + return "/api/account/auth/rolesextend/"; + } + + String getStation() { + return "/api/hrms_app/station/"; + } + + String getRoleAssignment(){ + return "api/account/auth/role_assignment/"; + } //// location utils path - String getCounties(){ + String getCounties() { return "/api/jobnet_app/countries/"; } - String getRegions(){ + + String getRegions() { return "/api/web_app/location/region/"; } - String getProvinces(){ + + String getProvinces() { return "api/web_app/location/province/"; } - String getCities(){ + + String getCities() { return "/api/web_app/location/citymun/"; } - String getBarangays(){ + + String getBarangays() { return "/api/web_app/location/barangay/"; } - String getAddressCategory(){ + + String getAddressCategory() { return "/api/jobnet_app/address_categories/"; } -} \ No newline at end of file +} diff --git a/macos/Podfile.lock b/macos/Podfile.lock index d473e2f..9a31980 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1,4 +1,10 @@ PODS: + - assets_audio_player (0.0.1): + - FlutterMacOS + - assets_audio_player_web (0.0.1): + - FlutterMacOS + - audioplayers_darwin (0.0.1): + - FlutterMacOS - FlutterMacOS (1.0.0) - FMDB (2.7.5): - FMDB/standard (= 2.7.5) @@ -16,6 +22,8 @@ PODS: - FlutterMacOS - platform_device_id_macos (0.0.1): - FlutterMacOS + - rive_common (0.0.1): + - FlutterMacOS - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS @@ -24,6 +32,9 @@ PODS: - FMDB (>= 2.7.5) DEPENDENCIES: + - assets_audio_player (from `Flutter/ephemeral/.symlinks/plugins/assets_audio_player/macos`) + - assets_audio_player_web (from `Flutter/ephemeral/.symlinks/plugins/assets_audio_player_web/macos`) + - audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - location (from `Flutter/ephemeral/.symlinks/plugins/location/macos`) - modal_progress_hud_nsn (from `Flutter/ephemeral/.symlinks/plugins/modal_progress_hud_nsn/macos`) @@ -31,6 +42,7 @@ DEPENDENCIES: - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/macos`) - platform_device_id (from `Flutter/ephemeral/.symlinks/plugins/platform_device_id/macos`) - platform_device_id_macos (from `Flutter/ephemeral/.symlinks/plugins/platform_device_id_macos/macos`) + - rive_common (from `Flutter/ephemeral/.symlinks/plugins/rive_common/macos`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos`) - sqflite (from `Flutter/ephemeral/.symlinks/plugins/sqflite/macos`) @@ -39,6 +51,12 @@ SPEC REPOS: - FMDB EXTERNAL SOURCES: + assets_audio_player: + :path: Flutter/ephemeral/.symlinks/plugins/assets_audio_player/macos + assets_audio_player_web: + :path: Flutter/ephemeral/.symlinks/plugins/assets_audio_player_web/macos + audioplayers_darwin: + :path: Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/macos FlutterMacOS: :path: Flutter/ephemeral location: @@ -53,21 +71,27 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/platform_device_id/macos platform_device_id_macos: :path: Flutter/ephemeral/.symlinks/plugins/platform_device_id_macos/macos + rive_common: + :path: Flutter/ephemeral/.symlinks/plugins/rive_common/macos shared_preferences_foundation: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/macos sqflite: :path: Flutter/ephemeral/.symlinks/plugins/sqflite/macos SPEC CHECKSUMS: + assets_audio_player: be2578e6f11dd4d183412e97143673c3c4cb2e8a + assets_audio_player_web: 917101123b6db8f73156835c0fa266c11340ff15 + audioplayers_darwin: dcad41de4fbd0099cb3749f7ab3b0cb8f70b810c FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a location: 7cdb0665bd6577d382b0a343acdadbcb7f964775 modal_progress_hud_nsn: 8099d46c2cf9de7af8fe0a3f8f5d2aa32cf956c3 package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce - path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 + path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8 platform_device_id: 3e414428f45df149bbbfb623e2c0ca27c545b763 platform_device_id_macos: f763bb55f088be804d61b96eb4710b8ab6598e94 - shared_preferences_foundation: 986fc17f3d3251412d18b0265f9c64113a8c2472 + rive_common: fab8476ce8352bf54152a913f393a8696d3dc98c + shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c sqflite: a5789cceda41d54d23f31d6de539d65bb14100ea PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 diff --git a/pubspec.lock b/pubspec.lock index 43d40ba..9004766 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -518,6 +518,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + flutter_custom_selector: + dependency: "direct main" + description: + name: flutter_custom_selector + sha256: "4c42dcd6cc2de1574454f0fc86b324303d1bd30e4bc236d01071525342d51427" + url: "https://pub.dev" + source: hosted + version: "0.0.3" flutter_form_builder: dependency: "direct main" description: @@ -563,6 +571,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.2.0" + flutter_staggered_animations: + dependency: "direct main" + description: + name: flutter_staggered_animations + sha256: "81d3c816c9bb0dca9e8a5d5454610e21ffb068aedb2bde49d2f8d04f75538351" + url: "https://pub.dev" + source: hosted + version: "1.1.1" flutter_svg: dependency: "direct main" description: @@ -653,6 +669,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.1" + group_list_view: + dependency: "direct main" + description: + name: group_list_view + sha256: "58bfc7f4b818abff531c2b202fb18b08abfb503f1621b0e86137a4fa4b6d91dd" + url: "https://pub.dev" + source: hosted + version: "1.1.1" hive: dependency: "direct main" description: @@ -1181,6 +1205,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.3" + search_page: + dependency: "direct main" + description: + name: search_page + sha256: "675239c1ac17f999c37aea7f4c969dc2fc21b58eb61d78180ff0c16112aab49b" + url: "https://pub.dev" + source: hosted + version: "2.3.0" searchable_paginated_dropdown: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 8bdae44..fcaa5d5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -82,6 +82,10 @@ dependencies: searchable_paginated_dropdown: ^1.2.0 audioplayers: ^4.1.0 assets_audio_player: ^3.0.6 + flutter_custom_selector: ^0.0.3 + flutter_staggered_animations: ^1.1.1 + group_list_view: ^1.1.1 + search_page: ^2.3.0 dev_dependencies: