From 14dd524c717515432ad14a8bbcd74e421cfe28b6 Mon Sep 17 00:00:00 2001 From: PGAN-MIS Date: Thu, 17 Aug 2023 10:49:33 +0800 Subject: [PATCH] add station for establishment point person and superadmin --- .../rbac_operations/station/station_bloc.dart | 48 +- .../station/station_event.dart | 8 + .../station/station_state.dart | 21 +- .../est_point_person_station_bloc.dart | 14 +- lib/model/rbac/rbac_station.dart | 1 + lib/model/rbac/station_type.dart | 40 + .../roles/pass_check/station_assign_area.dart | 35 +- .../superadmin/stations/stations_screen.dart | 960 ++++++++++++++---- .../components/dashboard/dashboard.dart | 10 +- .../dashboard/superadmin_expanded_menu.dart | 17 +- .../est_point_person_station.dart | 23 +- .../rbac_operations/station_services.dart | 11 +- 12 files changed, 925 insertions(+), 263 deletions(-) diff --git a/lib/bloc/rbac/rbac_operations/station/station_bloc.dart b/lib/bloc/rbac/rbac_operations/station/station_bloc.dart index 3d1a12d..79a9597 100644 --- a/lib/bloc/rbac/rbac_operations/station/station_bloc.dart +++ b/lib/bloc/rbac/rbac_operations/station/station_bloc.dart @@ -2,7 +2,9 @@ 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/rbac/station_type.dart'; import '../../../../model/utils/agency.dart'; +import '../../../../model/utils/position.dart'; import '../../../../utils/profile_utilities.dart'; part 'station_event.dart'; part 'station_state.dart'; @@ -11,6 +13,8 @@ class StationBloc extends Bloc { StationBloc() : super(StationInitial()) { List stations = []; List agencies = []; + List stationTypes = []; + List positions = []; on((event, emit) async { emit(StationLoadingState()); try { @@ -22,14 +26,42 @@ class StationBloc extends Bloc { await ProfileUtilities.instance.getAgecies(); agencies = newAgencies; } - emit(StationLoadedState(stations: stations, agencies: agencies)); + if (stationTypes.isEmpty) { + stationTypes = await RbacStationServices.instance.getStationTypes(); + } + if (positions.isEmpty) { + positions = await RbacStationServices.instance.getPositionTitle(); + } + emit(StationLoadedState( + stations: stations, + agencies: agencies, + stationTypes: stationTypes, + positions: positions)); } catch (e) { emit(StationErrorState(message: e.toString())); } }); - on((event, emit)async { - // emit(StationLoadingState()); - try { + on((event, emit) async { + emit(StationLoadingState()); + try { + Map statusResponse = await RbacStationServices + .instance + .addStation(station: event.station); + if (statusResponse['success']) { + RbacStation newStation = RbacStation.fromJson(statusResponse['data']); + stations.add(newStation); + emit(RbacStationAddedState(response: statusResponse)); + } else { + emit(RbacStationAddedState(response: statusResponse)); + } + } catch (e) { + emit(StationErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(StationLoadingState()); + + try { stations = await RbacStationServices.instance .getStations(agencyId: event.agencyId.toString()); @@ -38,10 +70,16 @@ class StationBloc extends Bloc { await ProfileUtilities.instance.getAgecies(); agencies = newAgencies; } - emit(StationLoadedState(stations: stations, agencies: agencies)); + emit(StationLoadedState( + stations: stations, + agencies: agencies, + positions: positions, + stationTypes: stationTypes)); } 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 index ea2c989..bf26ec8 100644 --- a/lib/bloc/rbac/rbac_operations/station/station_event.dart +++ b/lib/bloc/rbac/rbac_operations/station/station_event.dart @@ -10,9 +10,17 @@ abstract class StationEvent extends Equatable { class GetStations extends StationEvent { final int agencyId; const GetStations({required this.agencyId}); + @override + List get props => [agencyId]; } class FilterStation extends StationEvent { final int agencyId; const FilterStation({required this.agencyId}); + @override + List get props => [agencyId]; +} +class AddRbacStation extends StationEvent { + final RbacStation station; + const AddRbacStation({required this.station}); } diff --git a/lib/bloc/rbac/rbac_operations/station/station_state.dart b/lib/bloc/rbac/rbac_operations/station/station_state.dart index 7ab511f..0494c90 100644 --- a/lib/bloc/rbac/rbac_operations/station/station_state.dart +++ b/lib/bloc/rbac/rbac_operations/station/station_state.dart @@ -12,9 +12,11 @@ class StationInitial extends StationState {} class StationLoadedState extends StationState { final List agencies; final List stations; - const StationLoadedState({required this.stations, required this.agencies}); + final List stationTypes; + final List positions; + const StationLoadedState({required this.stations, required this.agencies,required this.positions, required this.stationTypes}); @override - List get props => [agencies,stations]; + List get props => [agencies,stations,stationTypes,positions]; } class StationLoadingState extends StationState {} @@ -27,6 +29,17 @@ class StationErrorState extends StationState { } class FilterStationState extends StationState { - final int agencyId; - const FilterStationState({required this.agencyId}); + final List agencies; + final List stations; + final List stationTypes; + final List positions; + const FilterStationState({required this.stations, required this.agencies,required this.positions, required this.stationTypes}); + @override + List get props => [agencies,stations,stationTypes,positions]; } + +class RbacStationAddedState extends StationState{ + final Map response; + const RbacStationAddedState({required this.response}); +} + diff --git a/lib/bloc/role/pass_check/est_point_person/est_point_person_station/est_point_person_station_bloc.dart b/lib/bloc/role/pass_check/est_point_person/est_point_person_station/est_point_person_station_bloc.dart index 1e1a4f9..ea55a22 100644 --- a/lib/bloc/role/pass_check/est_point_person/est_point_person_station/est_point_person_station_bloc.dart +++ b/lib/bloc/role/pass_check/est_point_person/est_point_person_station/est_point_person_station_bloc.dart @@ -1,14 +1,10 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:unit2/model/login_data/user_info/assigned_area.dart'; -import 'package:unit2/model/roles/pass_check/station_assign_area.dart'; import 'package:unit2/model/utils/position.dart'; - import '../../../../../model/rbac/rbac_station.dart'; -import '../../../../../model/utils/agency.dart'; +import '../../../../../model/rbac/station_type.dart'; import '../../../../../sevices/roles/rbac_operations/station_services.dart'; -import '../../../../../utils/profile_utilities.dart'; - part 'est_point_person_station_event.dart'; part 'est_point_person_station_state.dart'; @@ -43,7 +39,7 @@ class EstPointPersonStationBloc }); on((event, emit) async { emit(EstPersonStationLoadingState()); - // try { + try { Map statusResponse = await RbacStationServices .instance .addStation(station: event.station); @@ -54,9 +50,9 @@ class EstPointPersonStationBloc } else { emit(EstPointPersonAddedState(response: statusResponse)); } - // } catch (e) { - // emit(EstPersonStationErrorState(message: e.toString())); - // } + } catch (e) { + emit(EstPersonStationErrorState(message: e.toString())); + } }); } } diff --git a/lib/model/rbac/rbac_station.dart b/lib/model/rbac/rbac_station.dart index fa345c3..9fa9272 100644 --- a/lib/model/rbac/rbac_station.dart +++ b/lib/model/rbac/rbac_station.dart @@ -4,6 +4,7 @@ +import 'package:unit2/model/rbac/station_type.dart'; import 'package:unit2/model/roles/pass_check/station_assign_area.dart'; class RbacStation { diff --git a/lib/model/rbac/station_type.dart b/lib/model/rbac/station_type.dart index e69de29..6254bd8 100644 --- a/lib/model/rbac/station_type.dart +++ b/lib/model/rbac/station_type.dart @@ -0,0 +1,40 @@ +// To parse this JSON data, do +// +// final rbacStationType = rbacStationTypeFromJson(jsonString); + + +class StationType { + final int? id; + final String? typeName; + final String? color; + final int? order; + final bool? isActive; + final String? group; + + StationType({ + required this.id, + required this.typeName, + required this.color, + required this.order, + required this.isActive, + required this.group, + }); + + factory StationType.fromJson(Map json) => StationType( + id: json["id"], + typeName: json["type_name"], + color: json["color"], + order: json["order"], + isActive: json["is_active"], + group: json["group"], + ); + + Map toJson() => { + "id": id, + "type_name": typeName, + "color": color, + "order": order, + "is_active": isActive, + "group": group, + }; +} diff --git a/lib/model/roles/pass_check/station_assign_area.dart b/lib/model/roles/pass_check/station_assign_area.dart index f620307..5b2c099 100644 --- a/lib/model/roles/pass_check/station_assign_area.dart +++ b/lib/model/roles/pass_check/station_assign_area.dart @@ -3,6 +3,7 @@ // final assignArea = assignAreaFromJson(jsonString); import '../../rbac/rbac_station.dart'; +import '../../rbac/station_type.dart'; class StationAssignArea { final bool? isactive; @@ -132,38 +133,4 @@ class ChildStationInfo { } -class StationType { - final int? id; - final String? typeName; - final String? color; - final int? order; - final bool? isActive; - final String? group; - StationType({ - required this.id, - required this.typeName, - required this.color, - required this.order, - required this.isActive, - required this.group, - }); - - factory StationType.fromJson(Map json) => StationType( - id: json["id"], - typeName: json["type_name"], - color: json["color"], - order: json["order"], - isActive: json["is_active"], - group: json["group"], - ); - - Map toJson() => { - "id": id, - "type_name": typeName, - "color": color, - "order": order, - "is_active": isActive, - "group": group, - }; -} diff --git a/lib/screens/superadmin/stations/stations_screen.dart b/lib/screens/superadmin/stations/stations_screen.dart index 6d21170..822feec 100644 --- a/lib/screens/superadmin/stations/stations_screen.dart +++ b/lib/screens/superadmin/stations/stations_screen.dart @@ -1,4 +1,3 @@ -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'; @@ -9,29 +8,57 @@ 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/model/roles/pass_check/station_assign_area.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/position.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 '../../../../bloc/role/pass_check/est_point_person/est_point_person_station/est_point_person_station_bloc.dart'; +import '../../../../model/rbac/station_type.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'; import '../../../utils/formatters.dart'; -import '../../../utils/global.dart'; -import '../../../widgets/empty_data.dart'; +import '../../profile/shared/add_for_empty_search.dart'; -class RbacStationScreen extends StatelessWidget { - final int id; - const RbacStationScreen({super.key, required this.id}); +class RbacStationScreen extends StatefulWidget { + final int agencyId; + const RbacStationScreen({ + required this.agencyId, + super.key, + }); + @override + State createState() => _RbacStationScreenState(); +} + +class _RbacStationScreenState extends State { @override Widget build(BuildContext context) { - final agencyFocusNode = FocusNode(); + final rbacStationBloc = BlocProvider.of(context); List stations = []; final formKey = GlobalKey(); - Agency selectedAgency; + List> hierarchy = []; + bool mainParent = false; + bool isWithinParent = true; + bool isHospital = false; + List stationTypes = []; + List positions = []; + List mainParentStations = []; + List parentStations = []; + List agencies = []; + RbacStation? selectedMainParentStation; + RbacStation? selectedParentStation; + StationType? selectedStationType; + PositionTitle? selectedPositiontitle; + int selectedAgencyId = widget.agencyId; + final addStationTypeController = TextEditingController(); + final stationTypeFocusNode = FocusNode(); + final agencyFocusNode = FocusNode(); return Scaffold( appBar: AppBar( centerTitle: true, @@ -40,73 +67,431 @@ class RbacStationScreen extends StatelessWidget { actions: [ AddLeading(onPressed: () { BuildContext parent = context; + mainParentStations = []; + mainParent = stations.isEmpty ? true : false; + for (RbacStation station in stations) { + if (station.hierarchyOrderNo == 1) { + mainParentStations.add(station); + } + } + + /////Add new tation 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"))), - ], + content: SingleChildScrollView( + child: FormBuilder( + key: formKey, + child: StatefulBuilder(builder: (context, setState) { + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + ////is main parent + FormBuilderSwitch( + initialValue: mainParent, + activeColor: second, + onChanged: (value) { + setState(() { + mainParent = !mainParent; + }); + }, + decoration: normalTextFieldStyle( + "is Main Parent?", 'is Main Parent?'), + name: 'main-parent', + title: Text(mainParent ? "YES" : "NO"), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + SizedBox( + height: mainParent ? 0 : 8, + ), + //// selected main parent + SizedBox( + child: mainParent == true + ? const SizedBox.shrink() + : FormBuilderDropdown( + decoration: normalTextFieldStyle( + "Main Parent Station", + "Main Parent Station"), + name: "parent-stations", + items: mainParentStations.isEmpty + ? [] + : mainParentStations.map((e) { + return DropdownMenuItem( + value: e, + child: Text(e.stationName!), + ); + }).toList(), + onChanged: (RbacStation? e) { + setState(() { + selectedMainParentStation = e; + parentStations = []; + for (RbacStation station + in stations) { + if (station.mainParentStation == + selectedMainParentStation! + .id) { + parentStations.add(station); + } + } + parentStations.add( + selectedMainParentStation!); + }); + }, + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + ), + ), + SizedBox( + height: mainParent ? 0 : 8, + ), + ////parent station + SizedBox( + child: mainParent == true + ? const SizedBox.shrink() + : FormBuilderDropdown( + decoration: normalTextFieldStyle( + "Parent Station", "Parent Station"), + name: "parent-stations", + onChanged: (RbacStation? e) { + setState(() { + selectedParentStation = e; + }); + }, + items: parentStations.isEmpty + ? [] + : parentStations.map((e) { + return DropdownMenuItem( + value: e, + child: Text(e.stationName!), + ); + }).toList(), + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + ), + ), + const SizedBox( + height: 12, + ), + ////Station Type + SearchField( + itemHeight: 50, + suggestionsDecoration: box1(), + suggestions: stationTypes + .map((StationType stationType) => + SearchFieldListItem( + stationType.typeName!, + item: stationType, + child: Padding( + padding: + const EdgeInsets.symmetric( + horizontal: 10), + child: ListTile( + title: Text( + stationType.typeName!, + overflow: TextOverflow.visible, + )), + ))) + .toList(), + validator: (station) { + if (station!.isEmpty) { + return "This field is required"; + } + return null; + }, + focusNode: stationTypeFocusNode, + searchInputDecoration: + normalTextFieldStyle("Station Type *", "") + .copyWith( + suffixIcon: GestureDetector( + onTap: () => stationTypeFocusNode.unfocus(), + child: const Icon(Icons.arrow_drop_down), + )), + onSuggestionTap: (position) { + setState(() { + selectedStationType = position.item!; + stationTypeFocusNode.unfocus(); + }); + }, + emptyWidget: EmptyWidget( + title: "Add StationType", + controller: addStationTypeController, + onpressed: () { + setState(() { + StationType stationType = StationType( + id: null, + typeName: + addStationTypeController.text, + color: null, + order: null, + isActive: null, + group: null); + stationTypes.add(stationType); + Navigator.pop(context); + }); + }), + ), + const SizedBox( + height: 12, + ), + ////Position title + FormBuilderDropdown( + decoration: normalTextFieldStyle( + "Head Position", "Head Position"), + name: "head-position", + items: positions.map((e) { + return DropdownMenuItem( + value: e, + child: Text(e.title!), + ); + }).toList(), + onChanged: (title) { + selectedPositiontitle = title; + }, + ), + const SizedBox( + height: 12, + ), + ////is within parent + FormBuilderSwitch( + initialValue: true, + activeColor: second, + onChanged: (value) { + setState(() { + isWithinParent = value!; + }); + }, + decoration: normalTextFieldStyle( + "Location of the station within this parent?", + 'Location of the station within this parent?'), + name: 'isWithinParent', + title: Text(isWithinParent ? "YES" : "NO"), + ), + const SizedBox( + height: 12, + ), + Row( + //// Station Name + children: [ + Flexible( + child: FormBuilderTextField( + validator: + FormBuilderValidators.required( + errorText: + "This Field is required"), + decoration: normalTextFieldStyle( + "Station name", "Station name"), + name: "station-name"), + ), + const SizedBox( + width: 12, + ), + //// Acronym + Flexible( + child: FormBuilderTextField( + validator: + FormBuilderValidators.required( + errorText: + "This Field is required"), + decoration: normalTextFieldStyle( + "Acronym", "Acronym"), + name: "acronym"), + ), + ], + ), + const SizedBox( + height: 12, + ), + FormBuilderTextField( + ////Description + decoration: normalTextFieldStyle( + "Station description", + "Station description"), + name: "station-description"), + const SizedBox( + height: 12, + ), + Row( + children: [ + Flexible( + ////Code + child: FormBuilderTextField( + decoration: normalTextFieldStyle( + "Code", "Code"), + name: "code"), + ), + const SizedBox( + width: 12, + ), + Flexible( + //// Full Code + child: FormBuilderTextField( + decoration: normalTextFieldStyle( + "Full Code", "Full Code"), + name: "fullcode"), + ), + ], + ), + const SizedBox( + height: 12, + ), + ////is Hospital + FormBuilderSwitch( + initialValue: isHospital, + activeColor: second, + onChanged: (value) { + setState(() { + isHospital = !isHospital; + }); + }, + decoration: + normalTextFieldStyle("Is Hospital", ''), + name: 'isHospital', + title: Text(isHospital == true ? "YES" : "NO"), + ), + const SizedBox( + height: 20, + ), + SizedBox( + width: double.infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + RbacStation? newStation; + if (formKey.currentState! + .saveAndValidate()) { + String? stationName = formKey + .currentState! + .value['station-name']; + String? acronym = formKey + .currentState!.value['acronym']; + String? code = formKey + .currentState!.value['code']; + String? fullcode = formKey + .currentState!.value['fullcode']; + String? description = formKey + .currentState! + .value['station-description']; + newStation = RbacStation( + id: null, + stationName: stationName, + stationType: selectedStationType, + hierarchyOrderNo: mainParent + ? 1 + : selectedParentStation! + .hierarchyOrderNo! + + 1, + headPosition: + selectedPositiontitle?.title, + governmentAgency: + GovernmentAgency( + agencyid: + selectedAgencyId, + agencyname: null, + agencycatid: null, + privateEntity: null, + contactinfoid: null), + acronym: acronym, + parentStation: mainParent + ? null + : selectedParentStation!.id!, + code: code, + fullcode: fullcode, + childStationInfo: null, + islocationUnderParent: + isWithinParent, + mainParentStation: mainParent + ? null + : selectedMainParentStation! + .id!, + description: description, + ishospital: isHospital, + isactive: true, + sellingStation: null); + Navigator.pop(context); + rbacStationBloc.add(AddRbacStation( + station: newStation)); + } + }, + child: const Text("Add"))), + ], + ); + }), ), ), ); }); - }) + }), + ////Filter + IconButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: const Text( + "Select agency to filter stations", + textAlign: TextAlign.center, + ), + content: SizedBox( + child: // //// Filter Agencies + Padding( + padding: const EdgeInsets.all(8), + child: SearchField( + inputFormatters: [UpperCaseTextFormatter()], + itemHeight: 100, + focusNode: agencyFocusNode, + suggestions: agencies + .map((Agency agency) => + SearchFieldListItem(agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: TextOverflow.visible, + ), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle("Filter", "").copyWith( + suffixIcon: IconButton( + icon: const Icon(Icons.arrow_drop_down), + onPressed: () { + agencyFocusNode.unfocus(); + }, + )), + onSuggestionTap: (agency) { + agencyFocusNode.unfocus(); + + selectedAgencyId = agency.item!.id!; + print(selectedAgencyId); + Navigator.pop(context); + rbacStationBloc.add(FilterStation( + agencyId: selectedAgencyId)); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + emptyWidget: const Center( + child: Text("No result found..."), + )), + ), + ), + ); + }); + }, + icon: const Icon(Icons.filter_list)) ], ), body: ProgressHUD( @@ -114,62 +499,85 @@ class RbacStationScreen extends StatelessWidget { backgroundColor: Colors.black87, indicatorWidget: const SpinKitFadingCircle(color: Colors.white), child: BlocConsumer( - listener: (context, state) {}, + listener: (context, state) { + if (state is StationLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is RbacStationAddedState) { + if (state.response['success']) { + successAlert( + context, "Adding Successfull!", state.response['message'], + () { + Navigator.of(context).pop(); + context + .read() + .add(GetStations(agencyId: selectedAgencyId)); + }); + } else { + errorAlert(context, "Adding Failed", state.response['message'], + () { + Navigator.of(context).pop(); + context + .read() + .add(GetStations(agencyId: selectedAgencyId)); + }); + } + } + if (state is StationLoadedState || + state is RbacStationAddedState || + state is StationErrorState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, builder: (context, state) { final parent = context; if (state is StationLoadedState) { stations = state.stations; - if (state.stations.isNotEmpty) { + stationTypes = state.stationTypes; + positions = state.positions; + agencies = state.agencies; + int max = 0; + hierarchy = []; + for (RbacStation station in stations) { + if (station.hierarchyOrderNo != null) { + if (max < station.hierarchyOrderNo!) { + max = station.hierarchyOrderNo!; + } + } + } + for (int i = 1; i <= max; i++) { + hierarchy.add({i: []}); + } + for (var station in stations) { + if (station.hierarchyOrderNo != null) { + for (int i = 0; i <= max; i++) { + if (station.hierarchyOrderNo == i + 1) { + hierarchy[i][i + 1].add(station); + } + } + } + } + + if (stations.isNotEmpty && hierarchy[0][1].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, + itemCount: hierarchy[0][1].length, itemBuilder: (BuildContext context, int index) { + List second = []; + if (max >= 2) { + for (var rbacStation in hierarchy[1][2]) { + if (rbacStation.parentStation == + hierarchy[0][1][index].id) { + second.add(rbacStation); + } + } + } return Column( children: [ Container( @@ -182,15 +590,15 @@ class RbacStationScreen extends StatelessWidget { Expanded( child: Row( children: [ - CircleAvatar( - child: Text('${index + 1}'), + const CircleAvatar( + child: Text('1'), ), const SizedBox( width: 12, ), Flexible( child: Text( - state.stations[index] + hierarchy[0][1][index] .stationName!, style: Theme.of(context) .textTheme @@ -205,69 +613,261 @@ class RbacStationScreen extends StatelessWidget { ], ), ), - const SizedBox( - height: 3, - ) + ////SECOND + SizedBox( + child: second.isNotEmpty + ? Column( + mainAxisSize: MainAxisSize.min, + children: second.map((e) { + List childs = []; + if (max >= 3) { + for (RbacStation station + in hierarchy[2][3]) { + if (station.parentStation == + e.id) { + childs.add(station); + } + } + } else { + childs = []; + } + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + child: Container( + width: screenWidth, + decoration: box1() + .copyWith( + boxShadow: []), + padding: + const EdgeInsets + .only( + left: 30), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + Padding( + padding: + const EdgeInsets.all( + 6), + child: + Text( + "2", + style: Theme.of(context) + .textTheme + .bodyLarge, + selectionColor: + Colors.redAccent, + )), + const SizedBox( + width: 12, + ), + Flexible( + child: Text( + e + .stationName!, + style: Theme.of(context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: FontWeight.w500, + color: primary)), + ), + ], + )), + ], + ), + ), + ), + ], + ), + ////THIRD + SizedBox( + child: childs.isNotEmpty + ? Column( + mainAxisSize: + MainAxisSize + .min, + children: childs + .map((e) { + List + childs = []; + if (max >= 4) { + for (RbacStation station + in hierarchy[ + 3] + [4]) { + if (station + .parentStation == + e.id) { + childs.add( + station); + } + } + } else { + childs = []; + } + return Column( + children: [ + Container( + width: + screenWidth, + decoration: + box1() + .copyWith(boxShadow: []), + padding: const EdgeInsets + .only( + left: + 50), + child: + Row( + children: [ + Expanded( + child: Row( + children: [ + Padding( + padding: const EdgeInsets.all(6), + child: Text( + "3", + style: Theme.of(context).textTheme.bodyLarge, + selectionColor: Colors.redAccent, + )), + const SizedBox( + width: 12, + ), + Flexible( + child: Text(e.stationName!, style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary)), + ), + ], + )), + ], + ), + ), + ////Fourth + SizedBox( + child: childs.isNotEmpty + ? Column( + mainAxisSize: MainAxisSize.min, + children: childs.map((e) { + List childs = []; + if (max > 4) { + for (RbacStation station in hierarchy[4][5]) { + if (station.parentStation == e.id) { + childs.add(station); + } + } + } else { + childs = []; + } + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1().copyWith(boxShadow: []), + padding: const EdgeInsets.only(left: 80), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + Padding( + padding: const EdgeInsets.all(6), + child: Text( + "4", + style: Theme.of(context).textTheme.bodyLarge, + selectionColor: Colors.redAccent, + )), + const SizedBox( + width: 12, + ), + Flexible( + child: Text(e.stationName!, style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary)), + ), + ], + )), + ], + ), + ), + ////Fifth + SizedBox( + child: childs.isNotEmpty + ? Column( + mainAxisSize: MainAxisSize.min, + children: childs.map((e) { + List childs = []; + if (max > 5) { + for (RbacStation station in hierarchy[5][6]) { + if (station.parentStation == e.id) { + childs.add(station); + } + } + } else { + childs = []; + } + + return Column( + children: [ + Container( + width: screenWidth, + decoration: box1(), + padding: const EdgeInsets.only(left: 80), + child: Row( + children: [ + Expanded( + child: Row( + children: [ + const CircleAvatar( + child: Text('5'), + ), + const SizedBox( + width: 12, + ), + Flexible( + child: Text(e.stationName!, style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary)), + ), + ], + )), + ], + ), + ), + ], + ); + }).toList(), + ) + : const SizedBox()), + ], + ); + }).toList(), + ) + : const SizedBox()), + ], + ); + }).toList(), + ) + : const SizedBox + .shrink()), + ], + ); + }).toList(), + ) + : const SizedBox()), + const Divider( + height: 5, + ), ], ); }), - ), + ) ], ); } 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."), - ], - ); + return const EmptyData( + message: "No Station available. Please click + to add."); } } if (state is StationErrorState) { @@ -277,9 +877,7 @@ class RbacStationScreen extends StatelessWidget { context.read().add(GetRoles()); }); } - if (state is StationLoadingState) { - return CircularProgressIndicator(); - } + return Container(); }, ), diff --git a/lib/screens/unit2/homepage.dart/components/dashboard/dashboard.dart b/lib/screens/unit2/homepage.dart/components/dashboard/dashboard.dart index d345097..4d90a08 100644 --- a/lib/screens/unit2/homepage.dart/components/dashboard/dashboard.dart +++ b/lib/screens/unit2/homepage.dart/components/dashboard/dashboard.dart @@ -204,6 +204,7 @@ class _DashBoardState extends State { ); })); } + ////Station if (e.object.name == 'Station') { showDialog( context: context, @@ -227,8 +228,13 @@ class _DashBoardState extends State { onChanged: (value) { Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) { return BlocProvider( - create: (context) => EstPointPersonStationBloc()..add( EstPointPersonGetStations(agencyId: value.areaid!,)), - child: EstPointPersonStationScreen(agencyId: value!.areaid!,), + create: (context) => EstPointPersonStationBloc() + ..add(EstPointPersonGetStations( + agencyId: value.areaid!, + )), + child: EstPointPersonStationScreen( + agencyId: value!.areaid!, + ), ); })); }) 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 index ffcd01b..d9d7fb7 100644 --- a/lib/screens/unit2/homepage.dart/components/dashboard/superadmin_expanded_menu.dart +++ b/lib/screens/unit2/homepage.dart/components/dashboard/superadmin_expanded_menu.dart @@ -198,26 +198,15 @@ class SuperAdminMenu extends StatelessWidget { ); })); } + 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, + child: const RbacStationScreen( + agencyId: 1, ), ); })); diff --git a/lib/screens/unit2/roles/establishment_point_person/est_point_person_station.dart b/lib/screens/unit2/roles/establishment_point_person/est_point_person_station.dart index 52cd05e..5193ef5 100644 --- a/lib/screens/unit2/roles/establishment_point_person/est_point_person_station.dart +++ b/lib/screens/unit2/roles/establishment_point_person/est_point_person_station.dart @@ -12,6 +12,7 @@ import 'package:unit2/model/utils/position.dart'; import 'package:unit2/widgets/Leadings/add_leading.dart'; import 'package:unit2/widgets/error_state.dart'; import '../../../../bloc/role/pass_check/est_point_person/est_point_person_station/est_point_person_station_bloc.dart'; +import '../../../../model/rbac/station_type.dart'; import '../../../../theme-data.dart/box_shadow.dart'; import '../../../../theme-data.dart/btn-style.dart'; import '../../../../theme-data.dart/colors.dart'; @@ -57,11 +58,13 @@ class EstPointPersonStationScreen extends StatelessWidget { AddLeading(onPressed: () { BuildContext parent = context; mainParentStations = []; + mainParent = stations.isEmpty?true:false; for (RbacStation station in stations) { if (station.hierarchyOrderNo == 1) { mainParentStations.add(station); } } + //// Add New Station showDialog( context: context, builder: (BuildContext context) { @@ -90,8 +93,8 @@ class EstPointPersonStationScreen extends StatelessWidget { validator: FormBuilderValidators.required( errorText: "This field is required"), ), - const SizedBox( - height: 8, + SizedBox( + height: mainParent?0: 8, ), //// selected main parent SizedBox( @@ -132,8 +135,8 @@ class EstPointPersonStationScreen extends StatelessWidget { "This field is required"), ), ), - const SizedBox( - height: 12, + SizedBox( + height: mainParent?0: 8, ), ////parent station SizedBox( @@ -370,7 +373,7 @@ class EstPointPersonStationScreen extends StatelessWidget { id: null, stationName: stationName, stationType: selectedStationType, - hierarchyOrderNo: + hierarchyOrderNo:mainParent?1: selectedParentStation! .hierarchyOrderNo! + 1, @@ -385,15 +388,15 @@ class EstPointPersonStationScreen extends StatelessWidget { privateEntity: null, contactinfoid: null), acronym: acronym, - parentStation: - selectedParentStation!.id!, + parentStation: mainParent?null: selectedParentStation!.id!, + code: code, fullcode: fullcode, childStationInfo: null, islocationUnderParent: isWithinParent, mainParentStation: - selectedMainParentStation! + mainParent?null:selectedMainParentStation! .id!, description: description, ishospital: isHospital, @@ -489,12 +492,14 @@ class EstPointPersonStationScreen extends StatelessWidget { itemCount: hierarchy[0][1].length, itemBuilder: (BuildContext context, int index) { List second = []; - for (var rbacStation in hierarchy[1][2]) { + if(max >=2){ + for (var rbacStation in hierarchy[1][2]) { if (rbacStation.parentStation == hierarchy[0][1][index].id) { second.add(rbacStation); } } + } return Column( children: [ Container( diff --git a/lib/sevices/roles/rbac_operations/station_services.dart b/lib/sevices/roles/rbac_operations/station_services.dart index 75dc6c3..977a1ee 100644 --- a/lib/sevices/roles/rbac_operations/station_services.dart +++ b/lib/sevices/roles/rbac_operations/station_services.dart @@ -4,6 +4,7 @@ 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/rbac/station_type.dart'; import '../../../model/roles/pass_check/station_assign_area.dart'; class RbacStationServices { @@ -99,12 +100,12 @@ class RbacStationServices { }; String path = Url.instance.postStation(); - // try { + try { Map body = { "station_name": station.stationName, "acronym": station.acronym, "station_type_id": station.stationType?.id, - "_station_type_name": station.stationType?.typeName, + "_station_type_name": station.stationType?.id != null?null:station.stationType?.typeName, "parent_station_id": station.parentStation, "hierarchy_order_no": station.hierarchyOrderNo, "agency_id": station.governmentAgency!.agencyid, @@ -129,9 +130,9 @@ class RbacStationServices { {'success': false}, ); } - // } catch (e) { - // throw e.toString(); - // } + } catch (e) { + throw e.toString(); + } return statusResponse; } }