From 60c5a295f40be581456d0940ff7fb5fb706e6651 Mon Sep 17 00:00:00 2001 From: PGAN-MIS Date: Mon, 22 May 2023 10:23:56 +0800 Subject: [PATCH] Successfully implmented Profile API --- ios/Runner.xcodeproj/project.pbxproj | 15 + .../learning_development_bloc.dart | 268 ++- .../learning_development_event.dart | 51 + .../learning_development_state.dart | 111 +- lib/bloc/profile/profile_bloc.dart | 120 +- lib/bloc/profile/profile_event.dart | 23 + lib/bloc/profile/profile_state.dart | 33 + .../voluntary_works/voluntary_work_state.dart | 2 +- .../employee_info/employee_info.dart | 102 +- lib/model/profile/basic_info.dart | 3 +- .../primary-information.dart | 137 +- lib/model/profile/learning_development.dart | 71 +- .../edit_basic_info_modal.dart | 523 ++++++ .../primary_information_screen.dart | 449 +++-- .../basic_information/profile_other_info.dart | 25 + .../components/family_background_screen.dart | 594 ++++--- .../learning_and_development_screen.dart | 224 ++- .../learning_development/add_modal.dart | 1435 ++++++++++++++++ .../learning_development/display_details.dart | 150 ++ .../learning_development/edit_modal.dart | 1451 +++++++++++++++++ .../search_field_widget.dart | 0 .../training_details.dart | 73 + .../profile/components/loading_screen.dart | 8 +- .../components/voluntary_works/add_modal.dart | 2 +- lib/screens/profile/profile.dart | 21 +- .../unit2/homepage.dart/components/menu.dart | 1 + .../profile/learningDevelopment_service.dart | 260 ++- lib/sevices/profile/profile_other_info.dart | 137 ++ lib/sevices/profile/profile_service.dart | 255 ++- lib/utils/global.dart | 2 + lib/utils/request.dart | 2 +- lib/utils/urls.dart | 43 +- pubspec.lock | 8 + pubspec.yaml | 1 + 34 files changed, 5712 insertions(+), 888 deletions(-) create mode 100644 lib/screens/profile/components/basic_information/edit_basic_info_modal.dart create mode 100644 lib/screens/profile/components/basic_information/profile_other_info.dart create mode 100644 lib/screens/profile/components/learning_development/add_modal.dart create mode 100644 lib/screens/profile/components/learning_development/display_details.dart create mode 100644 lib/screens/profile/components/learning_development/edit_modal.dart create mode 100644 lib/screens/profile/components/learning_development/search_field_widget.dart create mode 100644 lib/screens/profile/components/learning_development/training_details.dart create mode 100644 lib/sevices/profile/profile_other_info.dart diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 4cf4c30..230f8d3 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -364,10 +364,15 @@ "$(inherited)", "@executable_path/Frameworks", ); + MARKETING_VERSION = "1.0.0 "; PRODUCT_BUNDLE_IDENTIFIER = "uniT-App"; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; @@ -493,11 +498,16 @@ "$(inherited)", "@executable_path/Frameworks", ); + MARKETING_VERSION = "1.0.0 "; PRODUCT_BUNDLE_IDENTIFIER = "uniT-App"; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -516,10 +526,15 @@ "$(inherited)", "@executable_path/Frameworks", ); + MARKETING_VERSION = "1.0.0 "; PRODUCT_BUNDLE_IDENTIFIER = "uniT-App"; PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 1; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; diff --git a/lib/bloc/profile/learningDevelopment/learning_development_bloc.dart b/lib/bloc/profile/learningDevelopment/learning_development_bloc.dart index de39dac..b91e8ef 100644 --- a/lib/bloc/profile/learningDevelopment/learning_development_bloc.dart +++ b/lib/bloc/profile/learningDevelopment/learning_development_bloc.dart @@ -1,8 +1,22 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import 'package:unit2/model/location/country.dart'; +import 'package:unit2/model/location/region.dart'; +import 'package:unit2/screens/profile/components/other_information/org_membership/add_modal.dart'; +import 'package:unit2/screens/unit2/login/components/update_required.dart'; import 'package:unit2/sevices/profile/learningDevelopment_service.dart'; +import 'package:unit2/test_data.dart'; +import 'package:unit2/utils/text_container.dart'; +import '../../../model/location/barangay.dart'; +import '../../../model/location/city.dart'; +import '../../../model/location/provinces.dart'; import '../../../model/profile/learning_development.dart'; +import '../../../model/utils/agency.dart'; +import '../../../model/utils/category.dart'; +import '../../../utils/location_utilities.dart'; +import '../../../utils/profile_utilities.dart'; part 'learning_development_event.dart'; part 'learning_development_state.dart'; @@ -10,19 +24,251 @@ part 'learning_development_state.dart'; class LearningDevelopmentBloc extends Bloc { LearningDevelopmentBloc() : super(LearningDevelopmentInitial()) { - List learningsAndDevelopments; + List learningsAndDevelopments = []; + List types = []; + List topics = []; + List globalCountries = []; + List globalRegions = []; + List globalProvinces = []; + List globalCities = []; + List globalBarangay = []; + List agencies = []; + List agencyCategory = []; + + Region? currentRegion; + Country? currentCountry; + Province? currentProvince; + CityMunicipality? currentCity; + Barangay? currentBarangay; on((event, emit) async { - // try { + try { + emit(LearningDevelopmentLoadingState()); + List learnings = await LearningDevelopmentServices + .instance + .getLearningDevelopments(event.profileId, event.token); + learningsAndDevelopments = learnings; + emit(LearningDevelopmentLoadedState( + learningsAndDevelopment: learningsAndDevelopments)); + } catch (e) { + emit(LeaningDevelopmentErrorState(message: e.toString())); + } + }); + ////load + on((event, emit) { + emit(LearningDevelopmentLoadedState( + learningsAndDevelopment: learningsAndDevelopments)); + }); + //// show add form + on((event, emit) async { + try { emit(LearningDevelopmentLoadingState()); - List learnings = await LearningDevelopmentServices - .instance - .getLearningDevelopments(event.profileId, event.token); - learningsAndDevelopments = learnings; - emit(LearningDevelopmentLoadedState( - learningsAndDevelopment: learningsAndDevelopments)); - // } catch (e) { - // emit(LeaningDevelopmentErrorState(message: e.toString())); - // } + if (types.isEmpty) { + List newTypes = + await LearningDevelopmentServices.instance + .getLearningDevelopmentType(); + types = newTypes; + } + if (topics.isEmpty) { + List newTopics = + await LearningDevelopmentServices.instance.getTrainingTopics(); + topics = newTopics; + } + if (globalRegions.isEmpty) { + List regions = await LocationUtils.instance.getRegions(); + globalRegions = regions; + } + if (globalCountries.isEmpty) { + List countries = await LocationUtils.instance.getCountries(); + globalCountries = countries; + } + if (agencies.isEmpty) { + List newAgencies = + await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + if (agencyCategory.isEmpty) { + List categoryAgencies = + await ProfileUtilities.instance.agencyCategory(); + agencyCategory = categoryAgencies; + } + + emit(LearningDevelopmentAddingState( + types: types, + topics: topics, + countries: globalCountries, + regions: globalRegions, + conductedBy: agencies, + sponsorAgencies: agencies, + agencyCategory: agencyCategory)); + } catch (e) { + emit(LeaningDevelopmentErrorState(message: e.toString())); + } + }); + ////Show edit form + on((event, emit) async { + try{ + if (globalRegions.isEmpty) { + List regions = await LocationUtils.instance.getRegions(); + globalRegions = regions; + } + if (globalCountries.isEmpty) { + List countries = await LocationUtils.instance.getCountries(); + globalCountries = countries; + } + currentCountry = globalCountries.firstWhere((Country country) => + event.learningDevelopment.conductedTraining!.venue!.country!.code == + country.code); + if (!event.isOverseas) { + //// if not overseas + currentRegion = globalRegions.firstWhere((Region region) => + event.learningDevelopment.conductedTraining!.venue! + .cityMunicipality!.province!.region!.code == + region.code); + + globalProvinces = await LocationUtils.instance + .getProvinces(regionCode: currentRegion!.code.toString()); + currentProvince = globalProvinces.firstWhere((Province province) => + event.learningDevelopment.conductedTraining!.venue! + .cityMunicipality!.province!.code == + province.code); + + globalCities = await LocationUtils.instance + .getCities(code: currentProvince!.code.toString()); + + currentCity = globalCities.firstWhere( + (CityMunicipality cityMunicipality) => + event.learningDevelopment.conductedTraining!.venue! + .cityMunicipality!.code == + cityMunicipality.code); + globalBarangay = await LocationUtils.instance + .getBarangay(code: currentCity!.code.toString()); + + if (event.learningDevelopment.conductedTraining?.venue?.barangay?.cityMunicipality != + null) { + currentBarangay = globalBarangay.firstWhere((Barangay barangay) => + event.learningDevelopment.conductedTraining!.venue!.barangay! + .code == + barangay.code); + } else { + currentBarangay = null; + } + } + if (topics.isEmpty) { + List newTopics = + await LearningDevelopmentServices.instance.getTrainingTopics(); + topics = newTopics; + } + if (types.isEmpty) { + List newTypes = + await LearningDevelopmentServices.instance + .getLearningDevelopmentType(); + types = newTypes; + } + if (agencies.isEmpty) { + List newAgencies = await ProfileUtilities.instance.getAgecies(); + agencies = newAgencies; + } + if (agencyCategory.isEmpty) { + List categoryAgencies = + await ProfileUtilities.instance.agencyCategory(); + agencyCategory = categoryAgencies; + } + emit(LearningDevelopmentUpdatingState( + cities: globalCities, + currentBarangay: currentBarangay, + barangay: globalBarangay, + + provinces: globalProvinces, + types: types, + topics: topics, + training: event.learningDevelopment.conductedTraining!.title!, + learningDevelopement: event.learningDevelopment, + currentConductedBy: + event.learningDevelopment.conductedTraining!.conductedBy!, + currentSponsor: event.learningDevelopment.sponsoredBy, + conductedBy: agencies, + sponsorAgencies: agencies, + agencyCategory: agencyCategory, + countries: globalCountries, + regions: globalRegions, + currentRegion: currentRegion, + currentCountry: currentCountry!, + currentProvince: currentProvince, + currentCity: currentCity, + overseas: event.isOverseas)); + }catch(e){ + emit(LearningDevelopmentErrorState(message: e.toString())); + } + }); + + ////Add + on((event, emit) async { + try { + Map status = + await LearningDevelopmentServices.instance.add( + learningDevelopement: event.learningDevelopement, + token: event.token, + profileId: event.profileId); + if (status['success']) { + LearningDevelopement learningDevelopement = + LearningDevelopement.fromJson(status['data']); + learningsAndDevelopments.add(learningDevelopement); + emit(LearningDevelopmentAddedState(response: status)); + } else { + emit(LearningDevelopmentAddedState(response: status)); + } + } catch (e) { + emit(LearningDevelopmentErrorState(message: e.toString())); + } + }); + + ////Update + on((event, emit) async { + try { + Map status = + await LearningDevelopmentServices.instance.update( + learningDevelopement: event.learningDevelopement, + token: event.token, + profileId: event.profileId); + if (status['success']) { + learningsAndDevelopments.removeWhere((LearningDevelopement element) => + element.conductedTraining!.id == event.learningDevelopement.conductedTraining!.id && + element.conductedTraining!.totalHours == event.learningDevelopement.conductedTraining!.totalHours); + LearningDevelopement learningDevelopement = + LearningDevelopement.fromJson(status['data']); + learningsAndDevelopments.add(learningDevelopement); + emit(LearningDevelopmentUpdatedState(response: status)); + } else { + emit(LearningDevelopmentUpdatedState(response: status)); + } + } catch (e) { + emit(LearningDevelopmentErrorState(message: e.toString())); + } + }); + ////delete + on((event, emit) async { + try { + final bool success = await LearningDevelopmentServices.instance.delete( + profileId: event.profileId, + token: event.token, + sponsorId: event.sponsorId, + totalHours: event.hours, + trainingId: event.trainingId); + if (success) { + learningsAndDevelopments.removeWhere((LearningDevelopement element) => + element.conductedTraining!.id == event.trainingId && + element.conductedTraining!.totalHours == event.hours); + emit(DeleteLearningDevelopmentState(success: success)); + } else { + emit(DeleteLearningDevelopmentState(success: success)); + } + } catch (e) { + emit(LearningDevelopmentErrorState(message: e.toString())); + } + }); + //// call errror + on((event, emit) { + emit(LeaningDevelopmentErrorState(message: event.message)); }); } } diff --git a/lib/bloc/profile/learningDevelopment/learning_development_event.dart b/lib/bloc/profile/learningDevelopment/learning_development_event.dart index 9aedc7d..1b1453f 100644 --- a/lib/bloc/profile/learningDevelopment/learning_development_event.dart +++ b/lib/bloc/profile/learningDevelopment/learning_development_event.dart @@ -15,3 +15,54 @@ class GetLearningDevelopments extends LearningDevelopmentEvent { @override List get props => [profileId, token]; } + +class ShowAddLearningDevelopmentForm extends LearningDevelopmentEvent{ + +} +class ShowEditLearningDevelopmentForm extends LearningDevelopmentEvent{ + final LearningDevelopement learningDevelopment; + final int profileId; + final String token; + final bool isOverseas; + const ShowEditLearningDevelopmentForm({required this.isOverseas, required this.learningDevelopment, required this.profileId, required this.token}); +} +class LoadLearniningDevelopment extends LearningDevelopmentEvent{ + +} +////delete +class DeleteLearningDevelopment extends LearningDevelopmentEvent { + final String token; + final int profileId; + final int? sponsorId; + final int trainingId; + final double hours; + const DeleteLearningDevelopment( + {required this.profileId, required this.token, required this.hours,required this.sponsorId, required this.trainingId}); + @override + List get props => [profileId, token, hours,trainingId]; +} + +////add +class AddLearningAndDevelopment extends LearningDevelopmentEvent{ + final LearningDevelopement learningDevelopement; + final int profileId; + final String token; + const AddLearningAndDevelopment({required this.learningDevelopement, required this.profileId, required this.token}); + @override + List get props => [profileId, token,learningDevelopement]; +} + +////update +class UpdateLearningDevelopment extends LearningDevelopmentEvent{ + final LearningDevelopement learningDevelopement; + final int profileId; + final String token; + const UpdateLearningDevelopment({required this.learningDevelopement, required this.profileId, required this.token}); + @override + List get props => [profileId, token,learningDevelopement]; +} + +class CallErrorState extends LearningDevelopmentEvent{ + final String message; + const CallErrorState({required this.message}); +} diff --git a/lib/bloc/profile/learningDevelopment/learning_development_state.dart b/lib/bloc/profile/learningDevelopment/learning_development_state.dart index c4b2337..bf0276b 100644 --- a/lib/bloc/profile/learningDevelopment/learning_development_state.dart +++ b/lib/bloc/profile/learningDevelopment/learning_development_state.dart @@ -2,27 +2,120 @@ part of 'learning_development_bloc.dart'; abstract class LearningDevelopmentState extends Equatable { const LearningDevelopmentState(); - + @override List get props => []; } class LearningDevelopmentInitial extends LearningDevelopmentState {} -class LearningDevelopmentLoadedState extends LearningDevelopmentState{ - final List learningsAndDevelopment; - const LearningDevelopmentLoadedState({required this.learningsAndDevelopment}); - @override +class LearningDevelopmentLoadedState extends LearningDevelopmentState { + final List learningsAndDevelopment; + const LearningDevelopmentLoadedState({required this.learningsAndDevelopment}); + @override List get props => [learningsAndDevelopment]; } -class LeaningDevelopmentErrorState extends LearningDevelopmentState{ +class LeaningDevelopmentErrorState extends LearningDevelopmentState { final String message; const LeaningDevelopmentErrorState({required this.message}); - @override + @override List get props => [message]; } -class LearningDevelopmentLoadingState extends LearningDevelopmentState{ - +class LearningDevelopmentLoadingState extends LearningDevelopmentState {} + +////added State +class LearningDevelopmentAddedState extends LearningDevelopmentState { + final Map response; + const LearningDevelopmentAddedState({required this.response}); + @override + List get props => [response]; +} + +////Updated State +class LearningDevelopmentUpdatedState extends LearningDevelopmentState { + final Map response; + const LearningDevelopmentUpdatedState({required this.response}); + @override + List get props => [response]; +} + +//// Deleted State +class DeleteLearningDevelopmentState extends LearningDevelopmentState { + final bool success; + const DeleteLearningDevelopmentState({required this.success}); + @override + List get props => [success]; +} + +////Update State +class LearningDevelopmentUpdatingState extends LearningDevelopmentState { + final List types; + final List topics; + final LearningDevelopmentType training; + final LearningDevelopement learningDevelopement; + final Agency currentConductedBy; + final Agency? currentSponsor; + final List conductedBy; + final List sponsorAgencies; + final List agencyCategory; + final List countries; + final List regions; + final List provinces; + final List barangay; + final List cities; + final Region? currentRegion; + final Country currentCountry; + final Province? currentProvince; + final CityMunicipality? currentCity; + final Barangay? currentBarangay; + final bool overseas; + + const LearningDevelopmentUpdatingState( + {required this.currentBarangay, + required this.cities, + required this.barangay, + required this.provinces, + required this.types, + required this.topics, + required this.training, + required this.learningDevelopement, + required this.currentConductedBy, + required this.currentSponsor, + required this.conductedBy, + required this.sponsorAgencies, + required this.agencyCategory, + required this.countries, + required this.regions, + required this.currentRegion, + required this.currentCountry, + required this.currentProvince, + required this.currentCity, + required this.overseas}); +} + +////Adding State +class LearningDevelopmentAddingState extends LearningDevelopmentState { + final List types; + final List topics; + final List conductedBy; + final List sponsorAgencies; + final List countries; + final List regions; + final List agencyCategory; + + const LearningDevelopmentAddingState( + {required this.types, + required this.topics, + required this.countries, + required this.regions, + required this.conductedBy, + required this.sponsorAgencies, + required this.agencyCategory}); +} + +class LearningDevelopmentErrorState extends LearningDevelopmentState { + final String message; + const LearningDevelopmentErrorState({required this.message}); } diff --git a/lib/bloc/profile/profile_bloc.dart b/lib/bloc/profile/profile_bloc.dart index 162bb9e..eb2ca08 100644 --- a/lib/bloc/profile/profile_bloc.dart +++ b/lib/bloc/profile/profile_bloc.dart @@ -1,17 +1,62 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:unit2/model/profile/profileInfomation.dart'; +import 'package:unit2/sevices/profile/profile_other_info.dart'; import 'package:unit2/sevices/profile/profile_service.dart'; + +import '../../model/profile/basic_information/primary-information.dart'; +import '../../screens/profile/components/basic_information/profile_other_info.dart'; part 'profile_event.dart'; part 'profile_state.dart'; class ProfileBloc extends Bloc { ProfileBloc() : super(ProfileInitial()) { + Profile? currentProfileInformation; + List religions = []; + List ethnicities = []; + List indigencies = []; + List disabilities = []; + List genders = []; + List bloodType = [ + "NONE", + "A+", + "B+", + "A-", + "B-", + "AB+", + "AB-", + "0+", + "0-" + ]; + List nameExtensions = [ + "NONE", + "N/A", + "SR.", + "JR.", + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII", + "IX", + "X" + ]; + List sexes = ["MALE", "FEMALE"]; + List civilStatus = [ + "NONE", + "SINGLE", + "MARRIED", + "SEPARATED", + "WIDOWED" + ]; + ProfileInformation? globalProfileInformation; on((event, emit) async { - emit(ProfileLoading()); + emit(ProfileLoading()); try { - ProfileInformation? profileInformation = await ProfileService.instance.getProfile(event.token, event.userID); globalProfileInformation = profileInformation; @@ -20,7 +65,74 @@ class ProfileBloc extends Bloc { emit(ProfileErrorState(mesage: e.toString())); } }); - - + on((event, emit) { + currentProfileInformation = event.primaryBasicInformation; + emit(BasicInformationProfileLoaded( + primaryBasicInformation: event.primaryBasicInformation)); + }); + on((event,emit){ + emit(BasicInformationProfileLoaded( + primaryBasicInformation: currentProfileInformation!)); + }); + on((event, emit) async { + try { + emit(BasicPrimaryInformationLoadingState()); + if (religions.isEmpty) { + religions = await ProfileOtherInfoServices.instace + .getReligions(token: event.token); + } + if (genders.isEmpty) { + genders = await ProfileOtherInfoServices.instace + .getGenders(token: event.token); + } + if (ethnicities.isEmpty) { + ethnicities = await ProfileOtherInfoServices.instace + .getEthnicity(token: event.token); + } + if (disabilities.isEmpty) { + disabilities = await ProfileOtherInfoServices.instace + .getDisability(token: event.token); + } + if (indigencies.isEmpty) { + indigencies = await ProfileOtherInfoServices.instace + .getIndigency(token: event.token); + } + emit(BasicInformationEditingState( + primaryInformation: currentProfileInformation!, + extensions: nameExtensions, + sexes: sexes, + bloodTypes: bloodType, + genders: genders, + civilStatus: civilStatus, + disability: disabilities, + ethnicity: ethnicities, + indigenous: indigencies, + religion: religions)); + } catch (e) { + emit(BasicPrimaryInformationErrorState(message: e.toString())); + } + }); + on((event, emit) async { + try { + Map status = await ProfileService.instance + .updateBasicProfileInfo( + token: event.token, + profileId: event.profileId, + profileInfo: event.profileInformation, + genderId: event.genderId, + indigencyId: event.indigencyId, + disabilityId: event.disabilityId, + ethnicityId: event.ethnicityId, + reqligionId: event.religionId); + if (status['success']) { + Profile profile = Profile.fromJson(status['data']); + currentProfileInformation = profile; + emit(BasicProfileInfoEditedState(response: status)); + } + emit(BasicProfileInfoEditedState(response: status)); + } catch (e) { + emit(BasicPrimaryInformationErrorState(message: e.toString())); + } + }); } } diff --git a/lib/bloc/profile/profile_event.dart b/lib/bloc/profile/profile_event.dart index 218cb3e..864edc2 100644 --- a/lib/bloc/profile/profile_event.dart +++ b/lib/bloc/profile/profile_event.dart @@ -19,6 +19,29 @@ class LoadProfileInformation extends ProfileEvent { @override List get props => []; } +class GetPrimaryBasicInfo extends ProfileEvent{ + final Profile primaryBasicInformation; + const GetPrimaryBasicInfo({required this.primaryBasicInformation}); +} +class LoadBasicPrimaryInfo extends ProfileEvent{ + +} + +class ShowPrimaryInfoEditForm extends ProfileEvent{ + final String token; + const ShowPrimaryInfoEditForm({required this.token}); +} +class EditBasicProfileInformation extends ProfileEvent{ +final Profile profileInformation; +final int profileId; +final String token; +final int? genderId; +final int? indigencyId; +final int? disabilityId; +final int? religionId; +final int? ethnicityId; +const EditBasicProfileInformation({required this.disabilityId,required this.ethnicityId, required this.genderId, required this.indigencyId, required this.profileId,required this.profileInformation,required this.religionId,required this.token}); +} diff --git a/lib/bloc/profile/profile_state.dart b/lib/bloc/profile/profile_state.dart index 7c2bddb..811c9a1 100644 --- a/lib/bloc/profile/profile_state.dart +++ b/lib/bloc/profile/profile_state.dart @@ -22,6 +22,39 @@ class ProfileErrorState extends ProfileState { @override List get props => [mesage]; } +class BasicInformationEditingState extends ProfileState{ + final Profile primaryInformation; + final List religion; +final List ethnicity; +final List disability; +final List indigenous; +final List genders; +final Listsexes; +final List bloodTypes; +final List civilStatus; +final List extensions; +const BasicInformationEditingState( {required this.genders, required this.extensions, required this.primaryInformation, required this.sexes, required this.bloodTypes, required this.civilStatus, required this.disability,required this.ethnicity,required this.indigenous,required this.religion}); +} +////Edited State +class BasicProfileInfoEditedState extends ProfileState{ + final Map response; + const BasicProfileInfoEditedState({required this.response}); + @override + List get props => [response]; +} + +class BasicInformationProfileLoaded extends ProfileState{ + final Profile primaryBasicInformation; + const BasicInformationProfileLoaded({required this.primaryBasicInformation}); + +} +class BasicPrimaryInformationLoadingState extends ProfileState{ + +} +class BasicPrimaryInformationErrorState extends ProfileState{ + final String message; + const BasicPrimaryInformationErrorState({required this.message}); +} class ProfileLoading extends ProfileState {} diff --git a/lib/bloc/profile/voluntary_works/voluntary_work_state.dart b/lib/bloc/profile/voluntary_works/voluntary_work_state.dart index a5baeeb..efa0fd7 100644 --- a/lib/bloc/profile/voluntary_works/voluntary_work_state.dart +++ b/lib/bloc/profile/voluntary_works/voluntary_work_state.dart @@ -33,7 +33,7 @@ class VoluntaryWorkAddedState extends VoluntaryWorkState{ @override List get props => [response]; } -////Added State +////Edited State class VoluntaryWorkEditedState extends VoluntaryWorkState{ final Map response; const VoluntaryWorkEditedState({required this.response}); diff --git a/lib/model/login_data/employee_info/employee_info.dart b/lib/model/login_data/employee_info/employee_info.dart index da8b94a..20166df 100644 --- a/lib/model/login_data/employee_info/employee_info.dart +++ b/lib/model/login_data/employee_info/employee_info.dart @@ -1,4 +1,7 @@ import 'package:unit2/model/login_data/employee_info/office.dart'; +import 'package:unit2/model/profile/profileInfomation.dart'; + +import '../../profile/basic_information/primary-information.dart'; class EmployeeInfo { EmployeeInfo({ @@ -35,103 +38,4 @@ class EmployeeInfo { "profile": profile!.toJson(), }; } -class Profile { - Profile({ - this.id, - this.sex, - this.gender, - this.deceased, - this.heightM, - this.birthdate, - this.esigPath, - this.fullName, - this.lastName, - this.weightKg, - this.bloodType, - this.firstName, - this.photoPath, - this.maidenName, - this.middleName, - this.uuidQrcode, - this.civilStatus, - this.titlePrefix, - this.titleSuffix, - this.showTitleId, - this.lastFullName, - this.nameExtension, - }); - int? id; - String? sex; - String? gender; - bool? deceased; - double? heightM; - DateTime? birthdate; - String? esigPath; - String? fullName; - String? lastName; - int? weightKg; - String? bloodType; - String? firstName; - String? photoPath; - String? maidenName; - String? middleName; - String? uuidQrcode; - String? civilStatus; - String? titlePrefix; - String? titleSuffix; - bool? showTitleId; - String? lastFullName; - String? nameExtension; - - factory Profile.fromJson(Map json) => Profile( - id: json["id"], - sex: json["sex"], - gender: json["gender"], - deceased: json["deceased"], - heightM: json["height_m"].toDouble(), - birthdate: DateTime.parse(json["birthdate"]), - esigPath: json["esig_path"], - fullName: json["full_name"], - lastName: json["last_name"], - weightKg: json["weight_kg"], - bloodType: json["blood_type"], - firstName: json["first_name"], - photoPath: json["photo_path"], - maidenName: json["maiden_name"], - middleName: json["middle_name"], - uuidQrcode: json["uuid_qrcode"], - civilStatus: json["civil_status"], - titlePrefix: json["title_prefix"], - titleSuffix: json["title_suffix"], - showTitleId: json["show_title_id"], - lastFullName: json["last_full_name"], - nameExtension: json["name_extension"], - ); - - Map toJson() => { - "id": id, - "sex": sex, - "gender": gender, - "deceased": deceased, - "height_m": heightM, - "birthdate": - "${birthdate!.year.toString().padLeft(4, '0')}-${birthdate!.month.toString().padLeft(2, '0')}-${birthdate!.day.toString().padLeft(2, '0')}", - "esig_path": esigPath, - "full_name": fullName, - "last_name": lastName, - "weight_kg": weightKg, - "blood_type": bloodType, - "first_name": firstName, - "photo_path": photoPath, - "maiden_name": maidenName, - "middle_name": middleName, - "uuid_qrcode": uuidQrcode, - "civil_status": civilStatus, - "title_prefix": titlePrefix, - "title_suffix": titleSuffix, - "show_title_id": showTitleId, - "last_full_name": lastFullName, - "name_extension": nameExtension, - }; -} diff --git a/lib/model/profile/basic_info.dart b/lib/model/profile/basic_info.dart index 243070e..c2a9b31 100644 --- a/lib/model/profile/basic_info.dart +++ b/lib/model/profile/basic_info.dart @@ -5,11 +5,10 @@ import 'package:unit2/model/profile/basic_information/identification_information import 'package:unit2/model/profile/basic_information/primary-information.dart'; class BasicInfo{ - PrimaryInformation? primaryInformation; List contactInformation; List identifications; List citizenships; List addresses; - BasicInfo({required this.addresses, required this.contactInformation, required this.primaryInformation,required this.identifications,required this.citizenships}); + BasicInfo({required this.addresses, required this.contactInformation,required this.identifications,required this.citizenships}); } \ 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 adb26f8..80b7535 100644 --- a/lib/model/profile/basic_information/primary-information.dart +++ b/lib/model/profile/basic_information/primary-information.dart @@ -1,83 +1,106 @@ +// To parse this JSON data, do +// +// final primaryInformation = primaryInformationFromJson(jsonString); + +import 'package:meta/meta.dart'; import 'dart:convert'; -class PrimaryInformation { - PrimaryInformation({ - required this.id, - required this.lastName, - required this.firstName, - required this.middleName, - required this.nameExtension, - required this.sex, - required this.birthdate, - required this.civilStatus, - required this.bloodType, - required this.heightM, - required this.weightKg, - required this.photoPath, - required this.esigPath, - required this.maidenName, - required this.deceased, - required this.gender, - required this.uuidQrcode, - required this.titlePrefix, - required this.titleSuffix, - required this.showTitleId, - }); +import 'package:unit2/model/profile/family_backround.dart'; - int? id; - String? lastName; - String? firstName; - String? middleName; - String? nameExtension; - String? sex; - DateTime? birthdate; - String? civilStatus; - String? bloodType; - double? heightM; - double? weightKg; - String? photoPath; - String? esigPath; - String? maidenName; - bool? deceased; - String? gender; - String? uuidQrcode; - String? titlePrefix; - String? titleSuffix; - bool? showTitleId; +import '../../../screens/profile/components/basic_information/profile_other_info.dart'; - factory PrimaryInformation.fromJson(Map json) => - PrimaryInformation( +Profile primaryInformationFromJson(String str) => Profile.fromJson(json.decode(str)); + +String primaryInformationToJson(Profile data) => json.encode(data.toJson()); + +class Profile { + int? id; + String? lastName; + String? firstName; + String? middleName; + String? nameExtension; + String? sex; + DateTime? birthdate; + String? civilStatus; + String? bloodType; + double? heightM; + double? weightKg; + String? photoPath; + String? esigPath; + MaidenName? maidenName; + bool? deceased; + String? uuidQrcode; + String? titlePrefix; + String? titleSuffix; + bool? showTitleId; + String? ethnicity; + String? disability; + String? gender; + String? religion; + String? ip; + + Profile({ + required this.id, + required this.lastName, + required this.firstName, + required this.middleName, + required this.nameExtension, + required this.sex, + required this.birthdate, + required this.civilStatus, + required this.bloodType, + required this.heightM, + required this.weightKg, + required this.photoPath, + required this.esigPath, + required this.maidenName, + required this.deceased, + required this.uuidQrcode, + required this.titlePrefix, + required this.titleSuffix, + required this.showTitleId, + required this.ethnicity, + required this.disability, + required this.gender, + required this.religion, + required this.ip, + }); + + factory Profile.fromJson(Map json) => Profile( id: json["id"], lastName: json["last_name"], firstName: json["first_name"], middleName: json["middle_name"], nameExtension: json["name_extension"], sex: json["sex"], - birthdate: json['birthdate']==null?null:DateTime.parse(json["birthdate"]), + birthdate: DateTime.parse(json["birthdate"]), civilStatus: json["civil_status"], bloodType: json["blood_type"], heightM: json["height_m"]?.toDouble(), - weightKg: json["weight_kg"], + weightKg: json["weight_kg"]?.toDouble(), photoPath: json["photo_path"], esigPath: json["esig_path"], - maidenName: json["maiden_name"], + maidenName: json["maiden_name"]==null?null:MaidenName.fromJson(json["maiden_name"]), deceased: json["deceased"], - gender: json["gender"], uuidQrcode: json["uuid_qrcode"], titlePrefix: json["title_prefix"], titleSuffix: json["title_suffix"], showTitleId: json["show_title_id"], - ); + ethnicity: json["ethnicity"]== null?null:json["ethnicity"]['name'], + disability: json["disability"] == null?null:json['disability']['name'], + gender: json["gender"] == null?null:json['gender']['name'], + religion: json["religion"] == null?null:json['religion']['name'], + ip: json["ip"]==null?null:json['ip']['name'], + ); - Map toJson() => { + Map toJson() => { "id": id, "last_name": lastName, "first_name": firstName, "middle_name": middleName, "name_extension": nameExtension, "sex": sex, - "birthdate": - "${birthdate!.year.toString().padLeft(4, '0')}-${birthdate!.month.toString().padLeft(2, '0')}-${birthdate!.day.toString().padLeft(2, '0')}", + "birthdate": "${birthdate?.year.toString().padLeft(4, '0')}-${birthdate?.month.toString().padLeft(2, '0')}-${birthdate?.day.toString().padLeft(2, '0')}", "civil_status": civilStatus, "blood_type": bloodType, "height_m": heightM, @@ -86,10 +109,14 @@ class PrimaryInformation { "esig_path": esigPath, "maiden_name": maidenName, "deceased": deceased, - "gender": gender, "uuid_qrcode": uuidQrcode, "title_prefix": titlePrefix, "title_suffix": titleSuffix, "show_title_id": showTitleId, - }; + "ethnicity": ethnicity, + "disability": disability, + "gender": gender, + "religion": religion, + "ip": ip, + }; } diff --git a/lib/model/profile/learning_development.dart b/lib/model/profile/learning_development.dart index ce7a045..c00f276 100644 --- a/lib/model/profile/learning_development.dart +++ b/lib/model/profile/learning_development.dart @@ -4,8 +4,11 @@ import 'dart:convert'; +import 'package:unit2/model/location/barangay.dart'; + import '../location/city.dart'; import '../location/country.dart'; +import '../utils/agency.dart'; import '../utils/industry_class.dart'; LearningDevelopement learningDevelopementFromJson(String str) => LearningDevelopement.fromJson(json.decode(str)); @@ -21,13 +24,13 @@ class LearningDevelopement { }); final dynamic attachments; - final EdBy? sponsoredBy; + final Agency? sponsoredBy; final ConductedTraining? conductedTraining; final double? totalHoursAttended; factory LearningDevelopement.fromJson(Map json) => LearningDevelopement( attachments: json["attachments"], - sponsoredBy: json["sponsored_by"] == null ? null : EdBy.fromJson(json["sponsored_by"]), + sponsoredBy: json["sponsored_by"] == null ? null : Agency.fromJson(json["sponsored_by"]), conductedTraining: json["conducted_training"] == null ? null : ConductedTraining.fromJson(json["conducted_training"]), totalHoursAttended: json["total_hours_attended"], ); @@ -62,8 +65,8 @@ class ConductedTraining { final bool? locked; final DateTime? toDate; final DateTime? fromDate; - final int? totalHours; - final EdBy? conductedBy; + final double? totalHours; + final Agency? conductedBy; final List? sessionsAttended; final LearningDevelopmentType? learningDevelopmentType; @@ -75,8 +78,8 @@ class ConductedTraining { locked: json["locked"], toDate: json["to_date"] == null ? null : DateTime.parse(json["to_date"]), fromDate: json["from_date"] == null ? null : DateTime.parse(json["from_date"]), - totalHours: json["total_hours"], - conductedBy: json["conducted_by"] == null ? null : EdBy.fromJson(json["conducted_by"]), + totalHours: double.parse(json["total_hours"].toString()), + conductedBy: json["conducted_by"] == null ? null : Agency.fromJson(json["conducted_by"]), sessionsAttended: json["sessions_attended"] == null ? [] : List.from(json["sessions_attended"]!.map((x) => x)), learningDevelopmentType: json["learning_development_type"] == null ? null : LearningDevelopmentType.fromJson(json["learning_development_type"]), ); @@ -96,58 +99,6 @@ class ConductedTraining { }; } -class EdBy { - EdBy({ - this.id, - this.name, - this.category, - this.privateEntity, - }); - - final int? id; - final String? name; - final SponsoredByCategory? category; - final bool? privateEntity; - - factory EdBy.fromJson(Map json) => EdBy( - id: json["id"], - name: json["name"], - category: json["category"] == null ? null : SponsoredByCategory.fromJson(json["category"]), - privateEntity: json["private_entity"], - ); - - Map toJson() => { - "id": id, - "name": name, - "category": category?.toJson(), - "private_entity": privateEntity, - }; -} - -class SponsoredByCategory { - SponsoredByCategory({ - this.id, - this.name, - this.industryClass, - }); - - final int? id; - final String? name; - final IndustryClass? industryClass; - - factory SponsoredByCategory.fromJson(Map json) => SponsoredByCategory( - id: json["id"], - name: json["name"], - industryClass: json["industry_class"] == null ? null : IndustryClass.fromJson(json["industry_class"]), - ); - - Map toJson() => { - "id": id, - "name": name, - "industry_class": industryClass?.toJson(), - }; -} - class LearningDevelopmentType { LearningDevelopmentType({ @@ -181,7 +132,7 @@ class Venue { final int? id; final Country? country; - final dynamic barangay; + final Barangay? barangay; final VenueCategory? category; final dynamic areaClass; final CityMunicipality? cityMunicipality; @@ -189,7 +140,7 @@ class Venue { factory Venue.fromJson(Map json) => Venue( id: json["id"], country: json["country"] == null ? null : Country.fromJson(json["country"]), - barangay: json["barangay"], + barangay:json["barangay"] == null ? null : Barangay.fromJson(json["country"]), category: json["category"] == null ? null : VenueCategory.fromJson(json["category"]), areaClass: json["area_class"], cityMunicipality: json["city_municipality"] == null ? null : CityMunicipality.fromJson(json["city_municipality"]), 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 new file mode 100644 index 0000000..2cb6160 --- /dev/null +++ b/lib/screens/profile/components/basic_information/edit_basic_info_modal.dart @@ -0,0 +1,523 @@ +import 'package:date_time_picker/date_time_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.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:form_builder_validators/form_builder_validators.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/model/profile/basic_information/primary-information.dart'; +import 'package:unit2/screens/profile/components/basic_information/profile_other_info.dart'; +import 'package:unit2/screens/unit2/roles/qr_code_scanner.dart/components/save_settings.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; + +import '../../../../theme-data.dart/colors.dart'; +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/global.dart'; + +class EditBasicProfileInfoScreen extends StatefulWidget { + final int profileId; + final String token; + const EditBasicProfileInfoScreen( + {super.key, required this.profileId, required this.token}); + + @override + State createState() => + _EditBasicProfileInfoScreenState(); +} + +final bdayController = TextEditingController(); +ProfileOtherInfo? selectedIndigency; +ProfileOtherInfo? selectedEthnicity; +ProfileOtherInfo? selectedReligion; +ProfileOtherInfo? selectedDisability; +ProfileOtherInfo? selectedGender; +String? selectedSex; +String? selectedBloodType; +String? selectedStatus; +String? selectedExtension; +final _formKey = GlobalKey(); + +class _EditBasicProfileInfoScreenState + extends State { + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is BasicInformationEditingState) { + bdayController.text = state.primaryInformation.birthdate.toString(); + selectedSex = state.sexes.firstWhere((element) => + element.toLowerCase() == + state.primaryInformation.sex!.toLowerCase()); + if (state.primaryInformation.bloodType != null) { + selectedBloodType = state.bloodTypes.firstWhere((element) => + element.toLowerCase() == + state.primaryInformation.bloodType?.toLowerCase()); + } + if (state.primaryInformation.nameExtension != null && + state.primaryInformation.nameExtension != "N/A") { + selectedExtension = state.extensions.firstWhere((element) => + element.toLowerCase() == + state.primaryInformation.nameExtension?.toLowerCase()); + } + if (state.primaryInformation.civilStatus != null) { + selectedStatus = state.civilStatus.firstWhere((element) => + element.toLowerCase() == + state.primaryInformation.civilStatus?.toLowerCase()); + } + if (state.primaryInformation.gender != null && + state.primaryInformation.gender != "N/A") { + selectedGender = state.genders.firstWhere((element) => + element.name!.toLowerCase() == + state.primaryInformation.gender?.toLowerCase()); + } + if (state.primaryInformation.ip != null && + state.primaryInformation.ip != "N/A") { + selectedIndigency = state.indigenous.firstWhere((element) => + element.name!.toLowerCase() == + state.primaryInformation.ip!.toLowerCase()); + } + if (state.primaryInformation.ethnicity != null && + state.primaryInformation.ethnicity != "N/A") { + selectedEthnicity = state.ethnicity.firstWhere((element) => + element.name!.toLowerCase() == + state.primaryInformation.ethnicity!.toLowerCase()); + } + if (state.primaryInformation.religion != null && + state.primaryInformation.religion != "N/A") { + selectedReligion = state.religion.firstWhere((element) => + element.name!.toLowerCase() == + state.primaryInformation.religion!.toLowerCase()); + } + if (state.primaryInformation.disability != null && + state.primaryInformation.disability != "N/A") { + selectedDisability = state.disability.firstWhere((element) => + element.name!.toLowerCase() == + state.primaryInformation.disability!.toLowerCase()); + } + + state.genders.insert( + 0, ProfileOtherInfo(id: null, name: "NONE", description: null)); + state.indigenous.insert( + 0, ProfileOtherInfo(id: null, name: "NONE", description: null)); + state.disability.insert( + 0, ProfileOtherInfo(id: null, name: "NONE", description: null)); + state.ethnicity.insert( + 0, ProfileOtherInfo(id: null, name: "NONE", description: null)); + state.religion.insert( + 0, ProfileOtherInfo(id: null, name: "NONE", description: null)); + return Container( + padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32), + child: FormBuilder( + key: _formKey, + child: Column( + children: [ + const SizedBox( + height: 28, + ), + FormBuilderTextField( + name: "lastname", + initialValue: state.primaryInformation.lastName, + decoration: normalTextFieldStyle("Last name", ""), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + const SizedBox( + height: 15, + ), + FormBuilderTextField( + name: "firstname", + initialValue: state.primaryInformation.firstName, + decoration: normalTextFieldStyle("First name", ""), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 2, + child: FormBuilderTextField( + name: "middlename", + initialValue: state.primaryInformation.middleName!, + decoration: normalTextFieldStyle("Middle name", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + //// name extension + child: DropdownButtonFormField( + value: selectedExtension, + decoration: + normalTextFieldStyle("Name Extension", ""), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + items: state.extensions + .map((element) => DropdownMenuItem( + value: element, child: Text(element))) + .toList(), + onChanged: (e) { + print(e); + print(selectedExtension); + selectedExtension = e; + }, + ), + ) + ]), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + ////Bday + Flexible( + flex: 1, + child: DateTimePicker( + controller: bdayController, + use24HourFormat: false, + validator: FormBuilderValidators.required( + errorText: "This field is required"), + timeHintText: "Birthdate", + decoration: + normalTextFieldStyle("Birthdate *", "*").copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + )), + firstDate: DateTime(1970), + lastDate: DateTime(2100), + icon: const Icon(Icons.date_range), + ), + ), + const SizedBox( + width: 10, + ), + + ////sex + Flexible( + flex: 1, + child: FormBuilderDropdown( + initialValue: selectedSex, + decoration: normalTextFieldStyle("Sex", ""), + name: "sex", + validator: FormBuilderValidators.required( + errorText: "This field is required"), + items: state.sexes + .map((element) => DropdownMenuItem( + value: element, child: Text(element))) + .toList(), + onChanged: (e) {}, + ), + ) + ]), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + ////blood type + Flexible( + flex: 1, + child: FormBuilderDropdown( + initialValue: selectedBloodType, + decoration: normalTextFieldStyle("Blood type", ""), + name: "bloodtype", + items: state.bloodTypes + .map((element) => DropdownMenuItem( + value: element, child: Text(element))) + .toList(), + onChanged: (e) {}, + ), + ), + const SizedBox( + width: 10, + ), + //// civil status + Flexible( + flex: 1, + child: FormBuilderDropdown( + initialValue: selectedStatus, + decoration: normalTextFieldStyle("Civil status", ""), + name: "extension", + items: state.civilStatus + .map((element) => DropdownMenuItem( + value: element, child: Text(element))) + .toList(), + onChanged: (e) { + selectedStatus = e; + }, + ), + ), + const SizedBox( + width: 10, + ), + //// gender + Flexible( + flex: 1, + child: DropdownButtonFormField( + isExpanded: true, + value: selectedGender, + decoration: normalTextFieldStyle("Gender", ""), + items: state.genders + .map((element) => + DropdownMenuItem( + value: element, + child: Text(element.name!))) + .toList(), + onChanged: (e) { + selectedGender = e; + }, + ), + ), + ]), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + name: "height", + initialValue: state.primaryInformation.heightM + .toString() + .toString(), + decoration: normalTextFieldStyle("Height", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + name: "weigth", + initialValue: + state.primaryInformation.weightKg!.toString(), + decoration: normalTextFieldStyle("Weight", ""), + ), + ), + ]), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + name: "prefix", + initialValue: state.primaryInformation.titlePrefix + .toString() + .toString(), + decoration: normalTextFieldStyle( + "Title Prefix", "Dr.,Atty.,Engr."), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + name: "suffix", + initialValue: state.primaryInformation.titleSuffix, + decoration: normalTextFieldStyle( + "Title Suffix", "PhD.,MD.,MS.,CE"), + ), + ), + ]), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + ////Indigency + Flexible( + flex: 1, + child: DropdownButtonFormField( + isExpanded: true, + value: selectedIndigency, + decoration: normalTextFieldStyle("Indigency", ""), + items: state.indigenous + .map((element) => + DropdownMenuItem( + value: element, + child: Text(element.name!))) + .toList(), + onChanged: (e) { + selectedIndigency = e; + }, + ), + ), + const SizedBox( + width: 10, + ), + ////Ethnicity + Flexible( + flex: 1, + child: DropdownButtonFormField( + isExpanded: true, + value: selectedEthnicity, + decoration: normalTextFieldStyle("Ethnicity", ""), + items: state.ethnicity + .map((element) => + DropdownMenuItem( + value: element, + child: Text(element.name!))) + .toList(), + onChanged: (e) { + selectedEthnicity = e; + }, + ), + ), + ]), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + ////religion + Flexible( + flex: 1, + child: DropdownButtonFormField( + isExpanded: true, + value: selectedReligion, + decoration: normalTextFieldStyle("Religion", ""), + items: state.religion + .map((element) => + DropdownMenuItem( + value: element, + child: Text(element.name!))) + .toList(), + onChanged: (e) { + selectedReligion = e; + }, + ), + ), + const SizedBox( + width: 10, + ), + ////disabilty + Flexible( + flex: 1, + child: DropdownButtonFormField( + isExpanded: true, + value: selectedDisability, + decoration: normalTextFieldStyle("Disability", ""), + items: state.disability + .map((element) => + DropdownMenuItem( + value: element, + child: Text(element.name!))) + .toList(), + onChanged: (e) { + selectedDisability = e; + }, + ), + ), + ]), + ), + const SizedBox( + height: 32, + ), + SizedBox( + width: double.infinity, + height: 60, + child: ElevatedButton( + style: + mainBtnStyle(primary, Colors.transparent, second), + onPressed: () { + if (_formKey.currentState!.saveAndValidate()) { + String lastName = + _formKey.currentState!.value['lastname']; + String firstName = + _formKey.currentState!.value['firstname']; + String? middleName = + _formKey.currentState?.value['middlename']; + String? pref = + _formKey.currentState?.value['prefix']; + String suf = _formKey.currentState?.value['suffix']; + DateTime birthdate = + DateTime.parse(bdayController.text); + double? hM = + _formKey.currentState!.value['height'] == null + ? null + : double.parse( + _formKey.currentState?.value['height']); + double? wKg = + _formKey.currentState!.value['weigth'] == null + ? null + : double.parse( + _formKey.currentState?.value['weigth']); + Profile primaryInformation = Profile( + id: state.primaryInformation.id, + lastName: lastName, + firstName: firstName, + middleName: middleName, + nameExtension: selectedExtension, + sex: selectedSex, + birthdate: birthdate, + civilStatus: selectedStatus, + bloodType: selectedBloodType, + heightM: hM, + weightKg: wKg, + photoPath: state.primaryInformation.photoPath, + esigPath: state.primaryInformation.esigPath, + maidenName: state.primaryInformation.maidenName, + deceased: state.primaryInformation.deceased, + uuidQrcode: state.primaryInformation.uuidQrcode, + titlePrefix: pref, + titleSuffix: suf, + showTitleId: + state.primaryInformation.showTitleId, + ethnicity: selectedEthnicity?.name, + disability: selectedDisability?.name, + gender: selectedGender?.name, + religion: selectedReligion?.name, + ip: selectedIndigency?.name); + final progress = ProgressHUD.of(context); + progress!.showWithText("Loading..."); + context.read().add( + EditBasicProfileInformation( + disabilityId: selectedDisability?.id, + ethnicityId: selectedDisability?.id, + genderId: selectedGender?.id, + indigencyId: selectedIndigency?.id, + profileId: widget.profileId, + profileInformation: primaryInformation, + religionId: selectedReligion?.id, + token: widget.token)); + } + }, + child: const Text("Submit")), + ) + ], + ), + ), + ); + } + return Placeholder(); + }, + ); + } +} diff --git a/lib/screens/profile/components/basic_information/primary_information_screen.dart b/lib/screens/profile/components/basic_information/primary_information_screen.dart index 3dddc42..b506f04 100644 --- a/lib/screens/profile/components/basic_information/primary_information_screen.dart +++ b/lib/screens/profile/components/basic_information/primary_information_screen.dart @@ -1,15 +1,31 @@ +import 'package:date_time_picker/date_time_picker.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:intl/intl.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/model/profile/basic_information/primary-information.dart'; +import 'package:unit2/screens/profile/components/basic_information/edit_basic_info_modal.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/utils/global.dart'; import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/widgets/error_state.dart'; + +import '../../../../utils/alerts.dart'; class PrimaryInfo extends StatefulWidget { - final PrimaryInformation primaryInformation; - const PrimaryInfo({super.key, required this.primaryInformation}); + final int profileId; + final String token; + const PrimaryInfo({ + super.key, + required this.profileId, + required this.token + }); @override State createState() => _PrimaryInfoState(); @@ -19,141 +35,316 @@ class _PrimaryInfoState extends State { @override Widget build(BuildContext context) { final _formKey = GlobalKey(); + bool enabled = false; - DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); return Scaffold( appBar: AppBar( title: const Text(primaryInformationScreenTitle), centerTitle: true, backgroundColor: primary, + actions: [ + IconButton( + onPressed: () { + context.read().add(ShowPrimaryInfoEditForm(token: widget.token)); + }, + icon: const Icon(Icons.edit)) + ], ), - body: Container( - padding: const EdgeInsets.symmetric(vertical: 24, horizontal: 24), - child: FormBuilder( - child: Column( - children: [ - FormBuilderTextField( - enabled: enabled, - name: lastname, - initialValue: widget.primaryInformation.lastName!, - decoration: normalTextFieldStyle("Last name", ""), + body: ProgressHUD( + padding: const EdgeInsets.all(24), + backgroundColor: Colors.black87, + indicatorWidget: const SpinKitFadingCircle(color: Colors.white), + child: BlocConsumer( + listener: (context, state) { + if (state is BasicPrimaryInformationLoadingState) { + final progress = ProgressHUD.of(context); + progress!.showWithText("Please wait..."); + } + if (state is BasicInformationProfileLoaded || + state is BasicInformationEditingState || state is BasicPrimaryInformationErrorState || state is BasicProfileInfoEditedState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + if (state is BasicProfileInfoEditedState) { + if (state.response['success']) { + successAlert(context, "Updated Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context + .read() + .add(LoadBasicPrimaryInfo()); + }); + } else { + errorAlert(context, "Update Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context + .read() + .add(LoadBasicPrimaryInfo()); + }); + } + } + }, + builder: (context, state) { + if (state is BasicInformationProfileLoaded) { + return Container( + padding: + const EdgeInsets.symmetric(vertical: 24, horizontal: 24), + child: Column( + children: [ + const SizedBox( + height: 28, + ), + FormBuilderTextField( + enabled: enabled, + name: lastname, + initialValue: state.primaryBasicInformation.lastName!, + decoration: normalTextFieldStyle("Last name", ""), + ), + const SizedBox( + height: 15, + ), + FormBuilderTextField( + enabled: enabled, + name: firstname, + initialValue: state.primaryBasicInformation.firstName!, + decoration: normalTextFieldStyle("First name", ""), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 2, + child: FormBuilderTextField( + enabled: enabled, + name: middlename, + initialValue: + state.primaryBasicInformation.middleName!, + decoration: + normalTextFieldStyle("Middle name", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: extensionName, + initialValue: state.primaryBasicInformation + .nameExtension ??= 'N/A', + decoration: + normalTextFieldStyle("Name extension", ""), + ), + ) + ]), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: extensionName, + initialValue: dteFormat2.format( + state.primaryBasicInformation.birthdate!), + decoration: + normalTextFieldStyle("Birth date", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: sex, + initialValue: state.primaryBasicInformation.sex!, + decoration: normalTextFieldStyle("Sex", ""), + ), + ) + ]), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: "bloodType", + initialValue: + state.primaryBasicInformation.bloodType!, + decoration: + normalTextFieldStyle("Blood type", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: "civilStatus", + initialValue: + state.primaryBasicInformation.civilStatus!, + decoration: + normalTextFieldStyle("Civil Status", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: "gender", + initialValue: state + .primaryBasicInformation.gender ??= "N/A", + decoration: normalTextFieldStyle("Gender", ""), + ), + ), + ]), + ), + const SizedBox( + height: 15, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: height, + initialValue: state + .primaryBasicInformation.heightM! + .toString(), + decoration: normalTextFieldStyle("Height", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: width, + initialValue: state + .primaryBasicInformation.weightKg! + .toString(), + decoration: normalTextFieldStyle("Weight", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: prefixSuffix, + initialValue: + "${state.primaryBasicInformation.titlePrefix ??= "NA"} | ${state.primaryBasicInformation.titleSuffix ??= "N/A"}", + decoration: normalTextFieldStyle( + "Title Prefix and Suffix", ""), + ), + ), + ]), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: height, + initialValue: state.primaryBasicInformation.ip ??= + "N/A", + decoration: + normalTextFieldStyle("Indigenous", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: width, + initialValue: state + .primaryBasicInformation.ethnicity ??= "N/A", + decoration: normalTextFieldStyle("Ethnicity", ""), + ), + ), + ]), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row(children: [ + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: height, + initialValue: state + .primaryBasicInformation.religion ??= "N/A", + decoration: normalTextFieldStyle("Religion", ""), + ), + ), + const SizedBox( + width: 10, + ), + Flexible( + flex: 1, + child: FormBuilderTextField( + enabled: enabled, + name: width, + initialValue: state + .primaryBasicInformation.disability ??= "N/A", + decoration: + normalTextFieldStyle("Disability", ""), + ), + ), + ]), + ), + ], + ), + ); + }if(state is BasicPrimaryInformationErrorState){ + return SomethingWentWrong(message: state.message, onpressed: (){}); - ), - const SizedBox(height: 15,), - FormBuilderTextField( - enabled: enabled, - name: firstname, - initialValue: widget.primaryInformation.firstName!, - decoration: normalTextFieldStyle("First name", ""), - ), - const SizedBox(height: 15,), - SizedBox( - width: screenWidth, - child: Row(children: [ - Flexible( - flex: 2, - child: FormBuilderTextField( - enabled: enabled, - name: middlename, - initialValue: widget.primaryInformation.middleName!, - decoration: normalTextFieldStyle("Middle name", ""), - ),), - const SizedBox(width: 10,), - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: extensionName, - initialValue: widget.primaryInformation.nameExtension??='N/A', - decoration: normalTextFieldStyle("Name extension", ""), - ),) - ]), - - ), - const SizedBox(height: 15,), - SizedBox(width: screenWidth, - child: Row(children: [ - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: extensionName, - initialValue: dteFormat2.format(widget.primaryInformation.birthdate!), - decoration: normalTextFieldStyle("Birth date", ""), - ),), - const SizedBox(width: 10,), - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: sex, - initialValue: widget.primaryInformation.sex!, - decoration: normalTextFieldStyle("Sex", ""), - ),) - ]),), - const SizedBox(height: 15,), - SizedBox(width: screenWidth, - child: Row(children: [ - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: bloodType, - initialValue:widget.primaryInformation.bloodType!, - decoration: normalTextFieldStyle("Blood type", ""), - ),), - const SizedBox(width: 10,), - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: civilStatus, - initialValue: widget.primaryInformation.civilStatus!, - decoration: normalTextFieldStyle("Civil Status", ""), - ),), - const SizedBox(width: 10,), - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: gender, - initialValue:widget.primaryInformation.gender??="N/A", - decoration: normalTextFieldStyle("Gender", ""), - ),), - ]),), - - const SizedBox(height: 15,), - SizedBox(width: screenWidth, - child: Row(children: [ - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: height, - initialValue:widget.primaryInformation.heightM!.toString(), - decoration: normalTextFieldStyle("Height", ""), - ),), - const SizedBox(width: 10,), - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: width, - initialValue: widget.primaryInformation.weightKg!.toString(), - decoration: normalTextFieldStyle("Weight", ""), - ),), - const SizedBox(width: 10,), - Flexible( - flex: 1, - child: FormBuilderTextField( - enabled: enabled, - name: prefixSuffix, - initialValue:"${widget.primaryInformation.titlePrefix??="NA"} | ${widget.primaryInformation.titleSuffix??="N/A"}", - decoration: normalTextFieldStyle("Title Prefix and Suffix", ""), - ),), - ]),), - ], - )), + }if(state is BasicInformationEditingState){ + return EditBasicProfileInfoScreen(profileId: widget.profileId, token: widget.token); + } + return Container(); + }, + ), )); } } diff --git a/lib/screens/profile/components/basic_information/profile_other_info.dart b/lib/screens/profile/components/basic_information/profile_other_info.dart new file mode 100644 index 0000000..79f75da --- /dev/null +++ b/lib/screens/profile/components/basic_information/profile_other_info.dart @@ -0,0 +1,25 @@ + + +class ProfileOtherInfo { + final int? id; + final String? name; + final String? description; + + ProfileOtherInfo({ + required this.id, + required this.name, + required this.description, + }); + + factory ProfileOtherInfo.fromJson(Map json) => ProfileOtherInfo( + id: json["id"], + name: json["name"], + description: json["description"], + ); + + Map toJson() => { + "id": id, + "name": name, + "description": description, + }; +} diff --git a/lib/screens/profile/components/family_background_screen.dart b/lib/screens/profile/components/family_background_screen.dart index b7b9109..95de086 100644 --- a/lib/screens/profile/components/family_background_screen.dart +++ b/lib/screens/profile/components/family_background_screen.dart @@ -921,347 +921,307 @@ class _FamilyBackgroundScreenState extends State { Container( child: spouse != null ? Row( - children: [ - Expanded( - child: Column(children: [ - const SizedBox( - height: 5, - ), - ListTile( - dense: true, - visualDensity: - const VisualDensity( - horizontal: -4, - vertical: -4), - title: Text( - "${spouse?.relatedPerson?.firstName} ${spouse?.relatedPerson?.middleName} ${spouse?.relatedPerson!.lastName} ${spouse?.relatedPerson?.nameExtension ?? ''}", - style: Theme.of(context) - .textTheme - .titleMedium! - .copyWith( - fontWeight: - FontWeight - .w500), - ), - subtitle: const Text( - "fullname"), - ), - Row( + children: [ + Expanded( + child: Column( children: [ - Checkbox( - visualDensity: - const VisualDensity( + const SizedBox( + height: 5, + ), + ListTile( + dense: true, + visualDensity: + const VisualDensity( + horizontal: + -4, + vertical: + -4), + title: Text( + "${spouse?.relatedPerson?.firstName} ${spouse?.relatedPerson?.middleName} ${spouse?.relatedPerson!.lastName} ${spouse?.relatedPerson?.nameExtension ?? ''}", + style: Theme.of( + context) + .textTheme + .titleMedium! + .copyWith( + fontWeight: + FontWeight.w500), + ), + subtitle: + const Text( + "fullname"), + ), + Row( + children: [ + Checkbox( + visualDensity: const VisualDensity( horizontal: 0, vertical: -4), - value: spouse! - .incaseOfEmergency!, - onChanged: (value) { - confirmAlertWithCancel( - context, () { - final progress = - ProgressHUD.of( - context); - progress! - .showWithText( - "Loading..."); - - context.read().add(AddEmergencyEvent( - contactInfoId: spouse!.emergencyContact!.isNotEmpty - ? spouse! - .emergencyContact! - .first - .contactinfoid - : null, - numberMail: spouse! - .emergencyContact! - .isNotEmpty - ? spouse! - .emergencyContact! - .first - .numbermail - : null, - profileId: - profileId!, - relatedPersonId: - spouse! - .relatedPerson! - .id!, - token: - token!, - requestType: - "CHECKBOX")); - }, - () {}, - "Emergency Contact Information?", - spouse!.incaseOfEmergency == - true - ? "Remove as emergency contact information?" - : "Add as emergency contact information?"); - }), - const Text( - incaseOfEmergency), - ////Add mobile icon - Container( - child: spouse! - .incaseOfEmergency! && - spouse! - .emergencyContact! - .isEmpty - ? IconButton( - visualDensity: const VisualDensity( - horizontal: - -4, - vertical: - -4), - onPressed: - () { - showDialog( - context: - context, - builder: - (BuildContext context) { - return AddMobileNumber( - onPressed: () { - Navigator.of(_scaffoldKey.currentContext!).pop(); - familyBloc.add(AddEmergencyEvent(contactInfoId: spouse!.emergencyContact!.isNotEmpty ? spouse!.emergencyContact!.first.contactinfoid : null, numberMail: formKey.currentState!.value['number_mail'], profileId: profileId!, relatedPersonId: spouse!.relatedPerson!.id!, token: token!, requestType: "CONTACT")); - }, - formKey: formKey); - }); - }, - icon: - const Icon( - Entypo - .plus_circled, - color: - third, - size: 18, - )) - : Container()), - ], - ), - Visibility( - visible: spouse! - .incaseOfEmergency!, - child: Container( - child: spouse! - .emergencyContact! - .isNotEmpty - ? Row( - children: [ - //// edit mobile - GestureDetector( - onTap: - () { + value: spouse! + .incaseOfEmergency!, + onChanged: + (value) { + confirmAlertWithCancel( + context, + () { + final progress = + ProgressHUD.of(context); + progress! + .showWithText("Loading..."); + + context.read().add(AddEmergencyEvent( + contactInfoId: spouse!.emergencyContact!.isNotEmpty ? spouse!.emergencyContact!.first.contactinfoid : null, + numberMail: spouse!.emergencyContact!.isNotEmpty ? spouse!.emergencyContact!.first.numbermail : null, + profileId: profileId!, + relatedPersonId: spouse!.relatedPerson!.id!, + token: token!, + requestType: "CHECKBOX")); + }, + () {}, + "Emergency Contact Information?", + spouse!.incaseOfEmergency == true + ? "Remove as emergency contact information?" + : "Add as emergency contact information?"); + }), + const Text( + incaseOfEmergency), + ////Add mobile icon + Container( + child: spouse!.incaseOfEmergency! && + spouse!.emergencyContact!.isEmpty + ? IconButton( + visualDensity: const VisualDensity(horizontal: -4, vertical: -4), + onPressed: () { showDialog( context: context, builder: (BuildContext context) { return AddMobileNumber( - formKey: formKey, onPressed: () { Navigator.of(_scaffoldKey.currentContext!).pop(); familyBloc.add(AddEmergencyEvent(contactInfoId: spouse!.emergencyContact!.isNotEmpty ? spouse!.emergencyContact!.first.contactinfoid : null, numberMail: formKey.currentState!.value['number_mail'], profileId: profileId!, relatedPersonId: spouse!.relatedPerson!.id!, token: token!, requestType: "CONTACT")); - }); + }, + formKey: formKey); }); }, - child: - Row( - children: [ - const SizedBox( - width: 16, + icon: const Icon( + Entypo.plus_circled, + color: third, + size: 18, + )) + : Container()), + ], + ), + Visibility( + visible: spouse! + .incaseOfEmergency!, + child: Container( + child: spouse!.emergencyContact!.isNotEmpty + ? Row( + children: [ + //// edit mobile + GestureDetector( + onTap: () { + showDialog( + context: context, + builder: (BuildContext context) { + return AddMobileNumber( + formKey: formKey, + onPressed: () { + Navigator.of(_scaffoldKey.currentContext!).pop(); + familyBloc.add(AddEmergencyEvent(contactInfoId: spouse!.emergencyContact!.isNotEmpty ? spouse!.emergencyContact!.first.contactinfoid : null, numberMail: formKey.currentState!.value['number_mail'], profileId: profileId!, relatedPersonId: spouse!.relatedPerson!.id!, token: token!, requestType: "CONTACT")); + }); + }); + }, + child: Row( + children: [ + const SizedBox( + width: 16, + ), + Badge( + backgroundColor: third, + textColor: Colors.white, + label: Text(spouse!.emergencyContact!.first.numbermail!), + ), + ], ), - Badge( - backgroundColor: third, - textColor: Colors.white, - label: Text(spouse!.emergencyContact!.first.numbermail!), - ), - ], - ), - ), - ], - ) - : Container())), - Container( - padding: - const EdgeInsets.only( - left: 12), - alignment: - Alignment.topLeft, - child: spouse?.position != - null - ? Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - const SizedBox( - height: 12, - ), - Text( - "OCCUPATION", - textAlign: - TextAlign - .start, - style: Theme.of( - context) - .textTheme - .titleMedium! - .copyWith( - fontWeight: - FontWeight.w500, - color: primary)), - Column( - mainAxisAlignment: - MainAxisAlignment - .start, + ), + ], + ) + : Container())), + Container( + padding: + const EdgeInsets + .only( + left: + 12), + alignment: + Alignment + .topLeft, + child: spouse + ?.position != + null + ? Column( crossAxisAlignment: - CrossAxisAlignment - .start, + CrossAxisAlignment.start, children: [ const SizedBox( - height: 3, + height: + 12, ), Text( - spouse! - .position! - .title!, - style: Theme.of( - context) - .textTheme - .titleMedium, - ), - Text( - spouse! - .company! - .name!, - style: Theme.of( - context) - .textTheme - .titleMedium, - ), - Text( - spouse! - .companyAddress!, - style: Theme.of( - context) - .textTheme - .labelMedium, - ), - Text( - spouse! - .companyContactNumber!, - style: Theme.of( - context) - .textTheme - .labelMedium, - ), + "OCCUPATION", + textAlign: TextAlign.start, + style: Theme.of(context).textTheme.titleMedium!.copyWith(fontWeight: FontWeight.w500, color: primary)), + Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + const SizedBox( + height: 3, + ), + Text( + spouse!.position!.title!, + style: Theme.of(context).textTheme.titleMedium, + ), + Text( + spouse!.company!.name!, + style: Theme.of(context).textTheme.titleMedium, + ), + Text( + spouse!.companyAddress!, + style: Theme.of(context).textTheme.labelMedium, + ), + Text( + spouse!.companyContactNumber!, + style: Theme.of(context).textTheme.labelMedium, + ), + ], + ) ], ) - ], - ) - : const SizedBox(), - ) - ]), - ), - AppPopupMenu( - offset: const Offset(-10, -10), - elevation: 3, - onSelected: (value)async { - ////delete -= = = = = = = = =>> - if (value == 2) { - confirmAlert(context, () { - final progress = - ProgressHUD.of(context); - progress!.showWithText("Loading..."); - context.read().add( - DeleteFamily( - id: mother! - .relatedPerson!.id!, - profileId: profileId!, - token: token!)); - }, "Delete?", "Confirm Delete?"); - } - if (value == 1) { - ////edit eligibilty-= = = = = = = = =>> + : const SizedBox(), + ) + ]), + ), + AppPopupMenu( + offset: const Offset( + -10, -10), + elevation: 3, + onSelected: + (value) async { + ////delete -= = = = = = = = =>> + if (value == 2) { + confirmAlert( + context, () { + final progress = + ProgressHUD.of( + context); + progress! + .showWithText( + "Loading..."); + context + .read< + FamilyBloc>() + .add(DeleteFamily( + id: mother! + .relatedPerson! + .id!, + profileId: + profileId!, + token: + token!)); + }, "Delete?", + "Confirm Delete?"); + } + if (value == 1) { + ////edit eligibilty-= = = = = = = = =>> - final progress = - ProgressHUD.of( - context); - progress!.showWithText( - "Loading..."); - if (positions.isEmpty) { - positions = - await ProfileUtilities - .instance - .getAgencyPosition(); - } + final progress = + ProgressHUD.of( + context); + progress! + .showWithText( + "Loading..."); + if (positions + .isEmpty) { + positions = + await ProfileUtilities + .instance + .getAgencyPosition(); + } - if (agencices.isEmpty) { - agencices = - await ProfileUtilities - .instance - .getAgecies(); - } - if (categories - .isEmpty) { - categories = - await ProfileUtilities - .instance - .agencyCategory(); - } - progress.dismiss(); - showDialog( - context: NavigationService - .navigatorKey - .currentContext!, - builder: - (BuildContext - context) { - return SpouseEditAlert( - familyBackground: spouse!, - familyBloc: - familyBloc, - token: token!, - profileId: - profileId!, - positions: - positions, - agencies: - agencices, - category: - categories, - bloodType: - bloodType, - civilStatus: - civilStatus, - gender: - gender, - nameExtensions: - nameExtensions, - sexes: sexes); - }); - - } - }, - menuItems: [ - popMenuItem( - text: "Update", - value: 1, - icon: Icons.edit), - popMenuItem( - text: "Reset", - value: 2, - icon: Icons.delete), - ], - icon: const Icon( - Icons.more_vert, - color: Colors.grey, - ), - tooltip: "Options", - ) - ], - ) + if (agencices + .isEmpty) { + agencices = + await ProfileUtilities + .instance + .getAgecies(); + } + if (categories + .isEmpty) { + categories = + await ProfileUtilities + .instance + .agencyCategory(); + } + progress.dismiss(); + showDialog( + context: NavigationService + .navigatorKey + .currentContext!, + builder: + (BuildContext + context) { + return SpouseEditAlert( + familyBackground: + spouse!, + familyBloc: + familyBloc, + token: + token!, + profileId: + profileId!, + positions: + positions, + agencies: + agencices, + category: + categories, + bloodType: + bloodType, + civilStatus: + civilStatus, + gender: + gender, + nameExtensions: + nameExtensions, + sexes: + sexes); + }); + } + }, + menuItems: [ + popMenuItem( + text: "Update", + value: 1, + icon: Icons.edit), + popMenuItem( + text: "Reset", + value: 2, + icon: + Icons.delete), + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ) + ], + ) : SizedBox( width: screenWidth, child: const Padding( diff --git a/lib/screens/profile/components/learning_and_development_screen.dart b/lib/screens/profile/components/learning_and_development_screen.dart index f2e8aa1..ae6add0 100644 --- a/lib/screens/profile/components/learning_and_development_screen.dart +++ b/lib/screens/profile/components/learning_and_development_screen.dart @@ -1,13 +1,16 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter/src/widgets/placeholder.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:intl/intl.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart'; import 'package:unit2/model/profile/learning_development.dart'; +import 'package:unit2/screens/profile/components/learning_development/edit_modal.dart'; import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/global.dart'; @@ -15,33 +18,44 @@ 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'; - import '../../../bloc/profile/learningDevelopment/learning_development_bloc.dart'; +import '../../../utils/alerts.dart'; +import 'learning_development/add_modal.dart'; class LearningAndDevelopmentScreen extends StatelessWidget { - - const LearningAndDevelopmentScreen( - {super.key,}); + const LearningAndDevelopmentScreen({ + super.key, + }); @override Widget build(BuildContext context) { + String token; + int profileId; DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); return Scaffold( appBar: AppBar( title: const Text(learningAndDevelopmentScreenTitle), centerTitle: true, backgroundColor: primary, - actions: [AddLeading(onPressed: () {})], + actions: [ + AddLeading(onPressed: () { + context + .read() + .add(ShowAddLearningDevelopmentForm()); + }) + ], ), body: ProgressHUD( padding: const EdgeInsets.all(24), indicatorWidget: const SpinKitFadingCircle( color: Colors.white, ), - backgroundColor: Colors.black87, + backgroundColor: Colors.black87, child: BlocBuilder( builder: (context, state) { if (state is UserLoggedIn) { + token = state.userData!.user!.login!.token!; + profileId = state.userData!.user!.login!.user!.profileId!; return BlocBuilder( builder: (context, state) { if (state is ProfileLoaded) { @@ -53,10 +67,76 @@ class LearningAndDevelopmentScreen extends StatelessWidget { progress!.showWithText("Please wait..."); } if (state is LearningDevelopmentLoadedState || - state is LeaningDevelopmentErrorState) { + state is LearningDevelopmentErrorState || + state is LearningDevelopmentAddingState || + state is LearningDevelopmentAddedState || + state is LearningDevelopmentUpdatingState) { final progress = ProgressHUD.of(context); progress!.dismiss(); } + //// Added State + if (state is LearningDevelopmentAddedState) { + if (state.response['success']) { + successAlert(context, "Adding Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context + .read() + .add(LoadLearniningDevelopment()); + }); + } else { + errorAlert(context, "Adding Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context + .read() + .add(LoadLearniningDevelopment()); + }); + } + } + ////Updated State + if (state is LearningDevelopmentUpdatedState) { + if (state.response['success']) { + successAlert(context, "Update Successfull!", + state.response['message'], () { + Navigator.of(context).pop(); + context + .read() + .add(LoadLearniningDevelopment()); + }); + } else { + errorAlert(context, "Update Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context + .read() + .add(LoadLearniningDevelopment()); + }); + } + } + ////Deleted State + if (state is DeleteLearningDevelopmentState) { + if (state.success) { + successAlert(context, "Deletion Successfull!", + "Deleted Successfully", () { + Navigator.of(context).pop(); + context + .read() + .add(LoadLearniningDevelopment()); + }); + } else { + errorAlert(context, "Deletion Failed", + "Something went wrong. Please try again.", + () { + Navigator.of(context).pop(); + context + .read() + .add(LoadLearniningDevelopment()); + }); + } + } // TODO: implement listener }, builder: (context, state) { @@ -141,13 +221,98 @@ class LearningAndDevelopmentScreen extends StatelessWidget { const SizedBox( height: 5, ), - ]), ), - IconButton( - onPressed: () {}, - icon: const Icon( - Icons.more_vert)), + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + ////delete -= = = = = = = = =>> + if (value == 2) { + confirmAlert(context, () { + final progress = + ProgressHUD.of( + context); + progress!.showWithText( + "Loading..."); + BlocProvider.of< + LearningDevelopmentBloc>( + context) + .add(DeleteLearningDevelopment( + trainingId: state + .learningsAndDevelopment[ + index] + .conductedTraining! + .id!, + hours: state + .learningsAndDevelopment[ + index] + .conductedTraining! + .totalHours!, + sponsorId: state + .learningsAndDevelopment[ + index] + .sponsoredBy + ?.id, + profileId: + profileId, + token: token)); + }, "Delete?", + "Confirm Delete?"); + } + if (value == 1) { + bool isOverseas; + ////edit = = = = = = = =>> + final progress = + ProgressHUD.of(context); + progress!.showWithText( + "Loading..."); + + if (state + .learningsAndDevelopment[ + index] + .conductedTraining + ?.venue + ?.cityMunicipality == + null) { + isOverseas = true; + } else { + isOverseas = false; + } + context + .read< + LearningDevelopmentBloc>() + .add(ShowEditLearningDevelopmentForm( + profileId: + profileId, + token: token, + learningDevelopment: + state.learningsAndDevelopment[ + index], + isOverseas: + isOverseas)); + } + }, + menuItems: [ + popMenuItem( + text: "Edit", + value: 1, + icon: Icons.edit), + popMenuItem( + text: "Delete", + value: 2, + icon: Icons.delete), + popMenuItem( + text: "Attachment", + value: 3, + icon: FontAwesome.attach) + ], + icon: const Icon( + Icons.more_vert, + color: Colors.grey, + ), + tooltip: "Options", + ) ], ), ), @@ -158,15 +323,27 @@ class LearningAndDevelopmentScreen extends StatelessWidget { ); }); } else { - const EmptyData( + return const EmptyData( message: "You don't have any Learning and Development added. Please click + to add."); } } - if (state is LeaningDevelopmentErrorState) { + if (state is LearningDevelopmentErrorState) { return (SomethingWentWrong( message: state.message, onpressed: () {})); } + if (state is LearningDevelopmentAddingState) { + return AddLearningAndDevelopmentScreen( + token: token, + profileId: profileId, + ); + } + if (state is LearningDevelopmentUpdatingState) { + return EditLearningAndDevelopmentScreen( + token: token, + profileId: profileId, + ); + } return Container(); }, ); @@ -180,4 +357,23 @@ class LearningAndDevelopmentScreen extends StatelessWidget { ), )); } + + PopupMenuItem popMenuItem({String? text, int? value, IconData? icon}) { + return PopupMenuItem( + value: value, + child: Row( + children: [ + Icon( + icon, + ), + const SizedBox( + width: 10, + ), + Text( + text!, + ), + ], + ), + ); + } } diff --git a/lib/screens/profile/components/learning_development/add_modal.dart b/lib/screens/profile/components/learning_development/add_modal.dart new file mode 100644 index 0000000..52fe09b --- /dev/null +++ b/lib/screens/profile/components/learning_development/add_modal.dart @@ -0,0 +1,1435 @@ +import 'package:date_time_picker/date_time_picker.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:form_builder_validators/form_builder_validators.dart'; +import 'package:intl/intl.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import 'package:searchable_paginated_dropdown/searchable_paginated_dropdown.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/profile/learningDevelopment/learning_development_bloc.dart'; +import 'package:unit2/model/profile/learning_development.dart'; +import 'package:unit2/screens/profile/components/learning_development/display_details.dart'; +import 'package:unit2/screens/profile/components/learning_development/training_details.dart'; +import 'package:unit2/sevices/profile/learningDevelopment_service.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/utils/validators.dart'; + +import '../../../../model/location/barangay.dart'; +import '../../../../model/location/city.dart'; +import '../../../../model/location/country.dart'; +import '../../../../model/location/provinces.dart'; +import '../../../../model/location/region.dart'; +import '../../../../model/utils/agency.dart'; +import '../../../../model/utils/category.dart'; +import '../../../../theme-data.dart/box_shadow.dart'; +import '../../../../theme-data.dart/colors.dart'; +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/global.dart'; +import '../../../../utils/location_utilities.dart'; +import '../../shared/add_for_empty_search.dart'; + +class AddLearningAndDevelopmentScreen extends StatefulWidget { + final int profileId; + final String token; + const AddLearningAndDevelopmentScreen( + {super.key, required this.profileId, required this.token}); + + @override + State createState() => + _AddLearningAndDevelopmentScreenState(); +} + +class _AddLearningAndDevelopmentScreenState + extends State { + final formKey = GlobalKey(); + + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + + bool isPrivate = false; + + bool showSponsorByAgency = false; + bool showOtherInputs = false; + bool showTrainingDetails = false; + bool hasSponsor = false; + + LearningDevelopmentType? selectedLearningDevelopmentType; + final fromDateController = TextEditingController(); + final toDateController = TextEditingController(); +////Training + bool show = true; + final addTrainingController = TextEditingController(); + ConductedTraining? selectedConductedTraining; + LearningDevelopmentType? selectedTraining; + +////Topic + final topicFocusNode = FocusNode(); + final addTopicController = TextEditingController(); + LearningDevelopmentType? selectedTopic; + + +////address + Barangay? selectedBarangay; + Country? selectedCountry; + Region? selectedRegion; + Province? selectedProvince; + CityMunicipality? selectedMunicipality; + bool overseas = false; + bool provinceCall = false; + bool cityCall = false; + bool barangayCall = false; + List? provinces; + List? citymuns; + List? barangays; + + ////Sponsor Agency Searchfield + Agency? selectedSponsorAgency; + Category? selectedSponsorAgencyCategory; + bool showSponsorCategoryAgency = false; + bool showSponsorAgencyPrivateRadio = false; + bool sponsorAgencyIsPrivate = false; + final addSponsorAgencyController = TextEditingController(); + final sponsorByFocusNode = FocusNode(); + final sponsorAgencyCategoryFocusNode = FocusNode(); + +////Conducted By + Agency? selectedConductedByAgency; + Category? selectedConductedByAgencyCategory; + bool showConductedByAgencyPrivateRadio = false; + final conductedByFocusNode = FocusNode(); + final conductedByAgencyCategoryFocusNode = FocusNode(); + final addConductedByController = TextEditingController(); + bool showConductedByAgencyCategory = false; + bool conductedByCategoryIsPrivate = false; + + final selectedTrainingController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is LearningDevelopmentAddingState) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 24), + child: FormBuilder( + key: formKey, + child: ListView( + children: [ + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + ////Training SearchField + SizedBox( + child: show + ? SearchableDropdownFormField.paginated( + noRecordTex: SizedBox( + width: double.infinity, + height: 300, + child: EmptyWidget( + controller: addTrainingController, + onpressed: () { + setState(() { + show = false; + showOtherInputs = true; + + selectedTrainingController.text = + addTrainingController.text.toUpperCase(); + selectedTraining = + LearningDevelopmentType( + id: null, + title: + selectedTrainingController + .text); + addTrainingController.text =""; + Navigator.of(context).pop(); + Navigator.of(context).pop(); + }); + }, + title: "Add Training"), + ), + isDialogExpanded: false, + hintText: const Text('Search Training'), + margin: const EdgeInsets.all(15), + backgroundDecoration: (child) { + return SizedBox( + width: double.infinity, + child: Card( + child: Padding( + padding: const EdgeInsets.all(16), + child: child), + ), + ); + }, + validator: FormBuilderValidators.required( + errorText: "This field is required"), + paginatedRequest: + (int page, String? searchKey) async { + List paginatedList = + await LearningDevelopmentServices + .instance + .getConductedTrainings( + page: page, + key: searchKey ??= ""); + return paginatedList.map((e) { + return SearchableDropdownMenuItem( + value: e, + onTap: () {}, + label: e.title!.title!, + child: TrainingDisplayDetails( + ////not what you are looking for + notWhatYourLookingFor: () { + setState(() { + if (e.learningDevelopmentType + ?.id != + null) { + selectedTraining = + LearningDevelopmentType( + id: e.title!.id, + title: null); + } else { + selectedTraining = + LearningDevelopmentType( + id: null, + title: + e.title!.title); + } + show = false; + showOtherInputs = true; + + selectedTrainingController + .text = e.title!.title!; + Navigator.of(context).pop(); + }); + }, + e: e, + )); + }).toList(); + }, + dropDownMaxHeight: 500, + requestItemCount: 5, + //// on chage + onChanged: (ConductedTraining? value) { + setState(() { + selectedConductedTraining = value; + selectedTrainingController.text = + selectedConductedTraining! + .title!.title!; + show = false; + showTrainingDetails = true; + }); + }, + ) + : const SizedBox(), + ), + const SizedBox( + height: 10, + ), + SizedBox( + ////Training selected Textfield + child: !show + ? FormBuilderTextField( + maxLines: 5, + readOnly: true, + controller: selectedTrainingController, + name: "", + decoration: normalTextFieldStyle("", "") + .copyWith( + labelText: "Training", + suffixIcon: IconButton( + onPressed: () { + setState(() { + selectedConductedTraining = + null; + selectedTrainingController + .text = ""; + show = true; + showTrainingDetails = + false; + showOtherInputs = false; + selectedTraining = null; + }); + }, + icon: + const Icon(Icons.close))), + ) + : const SizedBox()), + + ////ShowTraining Details + SizedBox( + child: showTrainingDetails + ? TrainingDetails( + trainingTitle: selectedConductedTraining! + .learningDevelopmentType!.title!, + totalHours: + selectedConductedTraining!.totalHours!, + trainingTopic: selectedConductedTraining! + .topic!.title!, + toDate: selectedConductedTraining!.toDate + .toString(), + fromDate: selectedConductedTraining! + .fromDate! + .toString(), + conductedBy: selectedConductedTraining! + .conductedBy!.name!) + : const SizedBox(), + ), + ///// end show training details + //// show other inputs + SizedBox( + child: showOtherInputs + ? SizedBox( + child: Column(children: [ + const SizedBox( + height: 12, + ), + ////learning development type + FormBuilderDropdown< + LearningDevelopmentType>( + decoration: normalTextFieldStyle( + "Learning Development Type *", + ""), + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + name: "types", + items: state.types + .map((e) => DropdownMenuItem< + LearningDevelopmentType>( + value: e, + child: Text(e.title!))) + .toList(), + onChanged: (value) { + selectedLearningDevelopmentType = + value; + }, + ), + + //// learning development topics + const SizedBox( + height: 12, + ), + StatefulBuilder( + builder: (context, setState) { + return SearchField( + focusNode: topicFocusNode, + itemHeight: 100, + suggestionsDecoration: box1(), + suggestions: state.topics + .map((LearningDevelopmentType + topic) => + SearchFieldListItem( + topic.title!, + item: topic, + child: Padding( + padding: + const EdgeInsets + .symmetric( + horizontal: + 10), + child: ListTile( + title: Text( + topic.title!, + softWrap: true, + ), + )))) + .toList(), + + searchInputDecoration: + normalTextFieldStyle( + "Topic *", "") + .copyWith( + suffixIcon: const Icon( + Icons + .arrow_drop_down)), + onSuggestionTap: (topic) { + if (topic.item?.id != null) { + selectedTopic = + LearningDevelopmentType( + id: topic.item!.id, + title: null); + } else { + selectedTopic = + LearningDevelopmentType( + id: null, + title: + topic.item!.title); + } + setState(() { + topicFocusNode.unfocus(); + }); + }, + ////EMPTY WIDGET + emptyWidget: EmptyWidget( + title: "Add Topic", + controller: addTopicController, + onpressed: () { + setState(() { + LearningDevelopmentType + newTopic = + LearningDevelopmentType( + id: null, + title: addTopicController + .text + .toUpperCase()); + state.topics + .insert(0, newTopic); + topicFocusNode.unfocus(); + addTopicController.text = + ""; + Navigator.pop(context); + }); + }), + validator: (position) { + if (position!.isEmpty) { + return "This field is required"; + } + return null; + }, + ); + }), + + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + //// FROM DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + use24HourFormat: false, + icon: const Icon( + Icons.date_range), + controller: + fromDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + timeHintText: + "Date of Examination/Conferment", + decoration: + normalTextFieldStyle( + "From *", + "From *") + .copyWith( + prefixIcon: + const Icon( + Icons.date_range, + color: Colors.black87, + )), + initialValue: null, + )), + const SizedBox( + width: 12, + ), + //// TO DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + controller: toDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: + normalTextFieldStyle( + "To *", "To *") + .copyWith( + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + ), + ), + initialValue: null, + ), + ), + ], + ), + ), + const SizedBox( + height: 12, + ), + //// total hours conducted + FormBuilderTextField( + validator: numericRequired, + name: "total_hours", + decoration: normalTextFieldStyle( + "Total Hours Conducted *", "0"), + keyboardType: TextInputType.number, + ), + const SizedBox( + height: 12, + ), + ////Address + StatefulBuilder( + builder: (context, setState) { + return Column( + children: [ + ////overseas textformfield + FormBuilderSwitch( + initialValue: overseas, + activeColor: second, + onChanged: (value) { + setState(() { + overseas = value!; + }); + }, + decoration: + normalTextFieldStyle( + "Overseas Address?", + ''), + name: 'overseas', + title: Text( + overseas ? "YES" : "NO"), + ), + SizedBox( + height: + overseas == true ? 8 : 0, + ), + SizedBox( + child: overseas == false + ? Column( + children: [ + const SizedBox( + height: 12, + ), + ////REGION DROPDOWN + FormBuilderDropdown< + Region?>( + autovalidateMode: + AutovalidateMode + .onUserInteraction, + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + onChanged: (Region? + region) async { + if (selectedRegion != + region) { + setState(() { + provinceCall = + true; + }); + selectedRegion = + region; + getProvinces(); + } + }, + initialValue: null, + decoration: + normalTextFieldStyle( + "Region*", + "Region"), + name: 'region', + items: state.regions.map< + DropdownMenuItem< + Region>>((Region + region) { + return DropdownMenuItem< + Region>( + value: region, + child: Text(region + .description!)); + }).toList(), + ), + const SizedBox( + height: 8, + ), + //// PROVINCE DROPDOWN + SizedBox( + height: 60, + child: + ModalProgressHUD( + color: Colors + .transparent, + inAsyncCall: + provinceCall, + child: DropdownButtonFormField< + Province?>( + autovalidateMode: + AutovalidateMode + .onUserInteraction, + validator: (value) => + value == + null + ? 'required' + : null, + isExpanded: + true, + value: + selectedProvince, + onChanged: + (Province? + province) { + if (selectedProvince != + province) { + setState( + () { + cityCall = + true; + }); + selectedProvince = + province; + getCities(); + } + }, + items: provinces == + null + ? [] + : provinces!.map< + DropdownMenuItem< + Province>>((Province + province) { + return DropdownMenuItem( + value: province, + child: FittedBox( + child: Text(province.description!), + )); + }).toList(), + decoration: normalTextFieldStyle( + "Province*", + "Province")), + ), + ), + ////CITY MUNICIPALITY + SizedBox( + height: 60, + child: + ModalProgressHUD( + color: + Colors.white, + inAsyncCall: + cityCall, + child: DropdownButtonFormField< + CityMunicipality>( + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + isExpanded: + true, + onChanged: + (CityMunicipality? + city) { + if (selectedMunicipality != + city) { + setState( + () { + barangayCall = + true; + }); + selectedMunicipality = + city; + getBarangays(); + } + }, + decoration: normalTextFieldStyle( + "Municipality*", + "Municipality"), + value: + selectedMunicipality, + items: citymuns == + null + ? [] + : citymuns!.map< + DropdownMenuItem>( + (CityMunicipality + c) { + return DropdownMenuItem( + value: + c, + child: + Text(c.description!)); + }).toList(), + ), + ), + ), + //// BARANGAY + SizedBox( + height: 60, + child: + ModalProgressHUD( + color: + Colors.white, + inAsyncCall: + barangayCall, + child: + DropdownButtonFormField< + Barangay>( + isExpanded: + true, + onChanged: + (Barangay? + baragay) { + selectedBarangay = + baragay; + }, + decoration: normalTextFieldStyle( + "Barangay*", + "Barangay"), + value: + selectedBarangay, + items: barangays == + null + ? [] + : barangays!.map< + DropdownMenuItem< + Barangay>>((Barangay + barangay) { + return DropdownMenuItem( + value: + barangay, + child: + Text(barangay.description!)); + }).toList(), + ), + ), + ), + ], + ) + //// COUNTRY DROPDOWN + : SizedBox( + height: 60, + child: + FormBuilderDropdown< + Country>( + initialValue: null, + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + items: state.countries.map< + DropdownMenuItem< + Country>>( + (Country + country) { + return DropdownMenuItem< + Country>( + value: country, + child: FittedBox( + child: Text( + country + .name!))); + }).toList(), + name: 'country', + decoration: + normalTextFieldStyle( + "Country*", + "Country"), + onChanged: + (Country? value) { + selectedCountry = + value; + }, + ), + ), + ), + ], + ); + }), + + ////Conducted By + StatefulBuilder( + builder: (context, setState) { + ////has sponsor switch + return Column( + children: [ + ////Add Conducted Agency============ + SizedBox( + child: SizedBox( + child: Column(children: [ + SearchField( + suggestionDirection: + SuggestionDirection + .up, + itemHeight: 70, + focusNode: + conductedByFocusNode, + suggestions: state + .conductedBy + .map((Agency + agency) => + SearchFieldListItem( + agency.name!, + item: agency, + child: + ListTile( + title: Text( + agency + .name!, + overflow: + TextOverflow + .ellipsis, + ), + subtitle: Text(agency.privateEntity == + true + ? "Private" + : agency.privateEntity == + false + ? "Government" + : ""), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle( + " Conducted By *", + "") + .copyWith( + suffixIcon: + GestureDetector( + child: const Icon( + Icons.arrow_drop_down, + ), + onTap: () => + conductedByFocusNode + .unfocus(), + )), + ////SELETECTED + onSuggestionTap: + (agency) { + setState(() { + if (agency.item?.id != + null) { + selectedConductedByAgency = + Agency( + name: null, + id: agency + .item! + .id); + } else { + selectedConductedByAgency = + Agency( + id: null, + name: agency + .item! + .name); + } + + if (agency.item! + .privateEntity == + null) { + showConductedByAgencyCategory = + true; + showConductedByAgencyPrivateRadio = + true; + } else { + showConductedByAgencyCategory = + false; + showConductedByAgencyPrivateRadio = + false; + } + conductedByFocusNode + .unfocus(); + }); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + ////conducter empty widget + emptyWidget: EmptyWidget( + controller: + addConductedByController, + onpressed: () { + setState(() { + Agency newAgency = Agency( + id: null, + name: addConductedByController + .text + .toUpperCase(), + category: + null, + privateEntity: + null); + state.conductedBy + .insert(0, + newAgency); + + addConductedByController + .text = ""; + Navigator.pop( + context); + }); + }, + title: + "Add Conducted By Agency")), + SizedBox( + height: + showConductedByAgencyCategory + ? 12 + : 0, + ), + ////Sponsor Agency Category + SizedBox( + child: + showConductedByAgencyCategory + ? SearchField( + suggestionDirection: + SuggestionDirection + .up, + focusNode: + conductedByAgencyCategoryFocusNode, + itemHeight: 70, + suggestions: state + .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) { + setState(() { + selectedConductedByAgencyCategory = + agencyCategory + .item; + selectedConductedByAgency = Agency( + id: selectedConductedByAgency + ?.id, + name: selectedConductedByAgency! + .name, + category: + selectedConductedByAgencyCategory, + privateEntity: + showConductedByAgencyPrivateRadio); + conductedByAgencyCategoryFocusNode + .unfocus(); + }); + }, + searchInputDecoration: normalTextFieldStyle( + "Category *", + "") + .copyWith( + suffixIcon: + const Icon(Icons.arrow_drop_down)), + validator: + (value) { + if (value! + .isEmpty) { + return "This field is required"; + } + return null; + }, + ) + : const SizedBox(), + ), + + ////Sponsor Agency Private Radio + SizedBox( + height: + showConductedByAgencyPrivateRadio + ? 12 + : 0), + SizedBox( + child: showConductedByAgencyPrivateRadio + ? FormBuilderSwitch( + initialValue: + conductedByCategoryIsPrivate, + title: Text( + conductedByCategoryIsPrivate + ? "YES" + : "NO"), + decoration: normalTextFieldStyle( + "Private Entity?", + 'Private Entity?'), + + ////onvhange private sector + onChanged: + (value) { + setState(() { + conductedByCategoryIsPrivate = + value!; + selectedConductedByAgency = Agency( + category: + selectedConductedByAgency + ?.category, + id: selectedConductedByAgency + ?.id, + name: selectedConductedByAgency! + .name, + privateEntity: + conductedByCategoryIsPrivate); + conductedByAgencyCategoryFocusNode + .unfocus(); + }); + }, + name: + 'sponsorAgencyPrivate', + validator: + FormBuilderValidators + .required(), + ) + : const SizedBox()), + ]), + )), + ], + ); + }), + ]), + ) + : const SizedBox()), + const SizedBox( + height: 12, + ), + + ////Sponsor + StatefulBuilder(builder: (context, setState) { + ////has sponsor switch + return Column( + children: [ + FormBuilderSwitch( + initialValue: hasSponsor, + activeColor: second, + onChanged: (value) { + setState(() { + hasSponsor = value!; + }); + }, + decoration: + normalTextFieldStyle("Has Sponsor?", ''), + name: 'sponsor', + title: Text(hasSponsor ? "YES" : "NO"), + ), + ////Add Sponsor Agency============ + SizedBox( + child: hasSponsor + ? SizedBox( + child: Column(children: [ + const SizedBox( + height: 12, + ), + SearchField( + suggestionDirection: + SuggestionDirection.up, + itemHeight: 70, + focusNode: sponsorByFocusNode, + suggestions: state + .sponsorAgencies + .map((Agency agency) => + SearchFieldListItem( + agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: + TextOverflow + .ellipsis, + ), + subtitle: Text(agency + .privateEntity == + true + ? "Private" + : agency.privateEntity == + false + ? "Government" + : ""), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle( + " Sponsor Agency *", + "") + .copyWith( + suffixIcon: + GestureDetector( + child: const Icon( + Icons.arrow_drop_down, + ), + onTap: () => + sponsorByFocusNode + .unfocus(), + )), + ////SELETECTED + onSuggestionTap: (agency) { + setState(() { + if (agency.item?.id != + null) { + selectedSponsorAgency = + Agency( + name: null, + id: agency + .item!.id); + } else { + selectedSponsorAgency = + Agency( + id: null, + name: agency + .item!.name); + } + if (agency.item! + .privateEntity == + null) { + showSponsorCategoryAgency = + true; + showSponsorAgencyPrivateRadio = + true; + } else { + showSponsorCategoryAgency = + false; + showSponsorAgencyPrivateRadio = + false; + } + sponsorByFocusNode + .unfocus(); + }); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + ////sponsor empty widget + emptyWidget: EmptyWidget( + controller: + addSponsorAgencyController, + onpressed: () { + setState(() { + Agency newAgency = Agency( + id: null, + name: addSponsorAgencyController + .text + .toUpperCase(), + category: null, + privateEntity: + null); + state.sponsorAgencies + .insert( + 0, newAgency); + + addSponsorAgencyController + .text = ""; + Navigator.pop(context); + }); + }, + title: + "Add Sponsor Agency")), + SizedBox( + height: showSponsorCategoryAgency + ? 12 + : 0, + ), + ////Sponsor Agency Category + SizedBox( + child: showSponsorCategoryAgency + ? SearchField( + suggestionDirection: + SuggestionDirection + .up, + focusNode: + sponsorAgencyCategoryFocusNode, + itemHeight: 70, + suggestions: state + .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) { + setState(() { + selectedSponsorAgencyCategory = + agencyCategory + .item; + selectedSponsorAgency = Agency( + id: selectedSponsorAgency + ?.id, + name: + selectedSponsorAgency! + .name, + category: + selectedSponsorAgencyCategory, + privateEntity: + sponsorAgencyIsPrivate); + sponsorAgencyCategoryFocusNode + .unfocus(); + }); + }, + searchInputDecoration: + normalTextFieldStyle( + "Category *", + "") + .copyWith( + suffixIcon: + const Icon( + Icons + .arrow_drop_down)), + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + ) + : const SizedBox(), + ), + + ////Sponsor Agency Private Radio + SizedBox( + height: + showSponsorAgencyPrivateRadio + ? 12 + : 0), + SizedBox( + child: + showSponsorAgencyPrivateRadio + ? FormBuilderSwitch( + initialValue: + sponsorAgencyIsPrivate, + title: Text( + sponsorAgencyIsPrivate + ? "YES" + : "NO"), + decoration: normalTextFieldStyle( + "Private Entity?", + 'Private Entity?'), + + ////onvhange private sector + onChanged: (value) { + setState(() { + sponsorAgencyIsPrivate = + value!; + selectedSponsorAgency = Agency( + category: + selectedSponsorAgency + ?.category, + id: selectedSponsorAgency + ?.id, + name: selectedSponsorAgency! + .name, + privateEntity: + selectedSponsorAgency + ?.privateEntity); + sponsorAgencyCategoryFocusNode + .unfocus(); + }); + }, + + name: + 'sponsorAgencyPrivate', + validator: + FormBuilderValidators + .required(), + ) + : const SizedBox()), + ]), + ) + : const SizedBox(), + ), + ], + ); + }), + const SizedBox( + height: 12, + ), + const SizedBox( + height: 12, + ), + FormBuilderTextField( + validator: numericRequired, + name: "total_hours_attended", + keyboardType: TextInputType.number, + decoration: normalTextFieldStyle( + "Total Hours Attended *", + "Total Hours Attended *"), + ), + ], + ); + }), + const SizedBox( + height: 12, + ), + SizedBox( + height: 60, + child: ElevatedButton( + style: + mainBtnStyle(primary, Colors.transparent, second), + child: const Text(submit), + onPressed: () { + if (formKey.currentState!.saveAndValidate()) { + ConductedTraining? training; + Agency? sponsor; + Venue venue; + ////Address + if (overseas) { + venue = Venue( + id: null, + country: selectedCountry, + barangay: null, + category: null, + areaClass: null, + cityMunicipality: null); + } else { + venue = Venue( + id: null, + country: Country( + id: 175, name: 'Philippines', code: 'PH'), + barangay: selectedBarangay, + areaClass: null, + category: null, + cityMunicipality: selectedMunicipality); + } + if (showTrainingDetails) { + training = ConductedTraining( + locked: false, + id: selectedConductedTraining!.id, + venue: Venue( + country: selectedConductedTraining! + .venue!.country)); + } else { + training = ConductedTraining( + title: selectedTraining, + topic: selectedTopic, + id: null, + locked: false, + venue: venue, + toDate: DateTime.parse(toDateController.text), + fromDate: + DateTime.parse(fromDateController.text), + totalHours: double.parse(formKey + .currentState!.value['total_hours']), + conductedBy: selectedConductedByAgency, + sessionsAttended: [], + learningDevelopmentType: + selectedLearningDevelopmentType); + } + if (hasSponsor) { + sponsor = selectedSponsorAgency; + } + LearningDevelopement learningDevelopement = + LearningDevelopement( + attachments: null, + sponsoredBy: sponsor, + conductedTraining: training, + totalHoursAttended: double.parse(formKey + .currentState! + .value['total_hours_attended'])); + final progress = ProgressHUD.of(context); + progress!.showWithText("Loading..."); + context.read().add( + AddLearningAndDevelopment( + learningDevelopement: learningDevelopement, + profileId: widget.profileId, + token: widget.token)); + } + }, + ), + ) + ], + )), + ); + } + return const Center( + child: Text("ds"), + ); + }, + ); + } + + Future getProvinces() async { + try { + List newProvinces = await LocationUtils.instance + .getProvinces(regionCode: selectedRegion!.code.toString()); + setState(() { + provinces = newProvinces; + selectedProvince = provinces![0]; + provinceCall = false; + cityCall = true; + getCities(); + }); + } catch (e) { + context + .read() + .add(CallErrorState(message: e.toString())); + } + } + + Future getCities() async { + try { + List newCities = await LocationUtils.instance + .getCities(code: selectedProvince!.code.toString()); + citymuns = newCities; + setState(() { + selectedMunicipality = newCities[0]; + cityCall = false; + barangayCall = true; + getBarangays(); + }); + } catch (e) { + context + .read() + .add(CallErrorState(message: e.toString())); + } + } + + Future getBarangays() async { + try { + List newBarangays = await LocationUtils.instance + .getBarangay(code: selectedMunicipality!.code.toString()); + barangays = newBarangays; + setState(() { + selectedBarangay = newBarangays[0]; + barangayCall = false; + }); + } catch (e) { + context + .read() + .add(CallErrorState(message: e.toString())); + } + } +} diff --git a/lib/screens/profile/components/learning_development/display_details.dart b/lib/screens/profile/components/learning_development/display_details.dart new file mode 100644 index 0000000..b946a1d --- /dev/null +++ b/lib/screens/profile/components/learning_development/display_details.dart @@ -0,0 +1,150 @@ +import 'package:date_time_picker/date_time_picker.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; + +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/global.dart'; + +class TrainingDetails extends StatelessWidget { + final String trainingTitle; + final double totalHours; + final String trainingTopic; + final String toDate; + final String fromDate; + final String conductedBy; + + const TrainingDetails({super.key, required this.trainingTitle, required this.totalHours, required this.trainingTopic, required this.toDate, required this.fromDate, required this.conductedBy}); + + @override + Widget build(BuildContext context) { + return SizedBox( + child: Column( + children: [ + const SizedBox( + height: 12, + ), + SizedBox( + child: Row( + children: [ + Flexible( + child: TextFormField( + enabled: false, + initialValue: trainingTitle, + decoration: + normalTextFieldStyle("", "") + .copyWith( + labelText: "Type", + fillColor: Colors + .grey.shade200, + filled: true)), + ), + const SizedBox( + width: 6, + ), + Flexible( + child: TextFormField( + enabled: false, + initialValue: totalHours + .toString(), + decoration: normalTextFieldStyle( + "", "") + .copyWith( + labelText: + "Total Hours Conducted", + fillColor: Colors + .grey.shade200, + filled: true))), + ], + ), + ), + const SizedBox( + height: 12, + ), + TextFormField( + enabled: false, + maxLines: 3, + initialValue: + trainingTopic, + decoration: normalTextFieldStyle("", "") + .copyWith( + labelText: "Topic", + fillColor: Colors.grey.shade200, + filled: true)), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + //// FROM DATE + Flexible( + flex: 1, + child: DateTimePicker( + enabled: false, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + initialValue:fromDate, + use24HourFormat: false, + icon: const Icon( + Icons.date_range), + timeHintText: + "Date of Examination/Conferment", + decoration: + normalTextFieldStyle( + "From", "From") + .copyWith( + fillColor: Colors + .grey.shade200, + filled: true, + prefixIcon: + const Icon( + Icons.date_range, + color: Colors + .black87, + )), + )), + const SizedBox( + width: 6, + ), + //// TO DATE + Flexible( + flex: 1, + child: DateTimePicker( + enabled: false, + initialValue:toDate, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: normalTextFieldStyle( + "To", "To") + .copyWith( + fillColor: Colors.grey.shade200, + filled: true, + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + ), + ), + ), + ), + ], + ), + ), + const SizedBox( + height: 12, + ), + TextFormField( + enabled: false, + maxLines: 3, + initialValue:conductedBy, + decoration: normalTextFieldStyle("", "") + .copyWith( + labelText: "Conducted By", + fillColor: Colors.grey.shade200, + filled: true)), + ], + ), + ); + } +} \ No newline at end of file diff --git a/lib/screens/profile/components/learning_development/edit_modal.dart b/lib/screens/profile/components/learning_development/edit_modal.dart new file mode 100644 index 0000000..58f5426 --- /dev/null +++ b/lib/screens/profile/components/learning_development/edit_modal.dart @@ -0,0 +1,1451 @@ +import 'package:date_time_picker/date_time_picker.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:form_builder_validators/form_builder_validators.dart'; +import 'package:intl/intl.dart'; +import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; +import 'package:searchable_paginated_dropdown/searchable_paginated_dropdown.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:unit2/bloc/profile/learningDevelopment/learning_development_bloc.dart'; +import 'package:unit2/model/profile/learning_development.dart'; +import 'package:unit2/screens/profile/components/learning_development/display_details.dart'; +import 'package:unit2/screens/profile/components/learning_development/training_details.dart'; +import 'package:unit2/sevices/profile/learningDevelopment_service.dart'; +import 'package:unit2/theme-data.dart/btn-style.dart'; +import 'package:unit2/utils/text_container.dart'; +import 'package:unit2/utils/validators.dart'; + +import '../../../../model/location/barangay.dart'; +import '../../../../model/location/city.dart'; +import '../../../../model/location/country.dart'; +import '../../../../model/location/provinces.dart'; +import '../../../../model/location/region.dart'; +import '../../../../model/utils/agency.dart'; +import '../../../../model/utils/category.dart'; +import '../../../../theme-data.dart/box_shadow.dart'; +import '../../../../theme-data.dart/colors.dart'; +import '../../../../theme-data.dart/form-style.dart'; +import '../../../../utils/global.dart'; +import '../../../../utils/location_utilities.dart'; +import '../../shared/add_for_empty_search.dart'; + +class EditLearningAndDevelopmentScreen extends StatefulWidget { + final int profileId; + final String token; + const EditLearningAndDevelopmentScreen( + {super.key, required this.profileId, required this.token}); + + @override + State createState() => + _EditLearningAndDevelopmentScreenState(); +} + +class _EditLearningAndDevelopmentScreenState + extends State { + final formKey = GlobalKey(); + + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + + bool isPrivate = false; + + bool showSponsorByAgency = false; + bool showOtherInputs = false; + bool showTrainingDetails = false; + bool hasSponsor = false; + + LearningDevelopmentType? selectedLearningDevelopmentType; + final fromDateController = TextEditingController(); + final toDateController = TextEditingController(); +////Training + bool show = true; + final addTrainingController = TextEditingController(); + ConductedTraining? selectedConductedTraining; + LearningDevelopmentType? selectedTraining; + +////Topic + final topicFocusNode = FocusNode(); + final addTopicController = TextEditingController(); + LearningDevelopmentType? selectedTopic; + final currentTopicController = TextEditingController(); + +////address + Barangay? selectedBarangay; + Country? selectedCountry; + Region? selectedRegion; + Province? selectedProvince; + CityMunicipality? selectedMunicipality; + bool overseas = false; + bool provinceCall = false; + bool cityCall = false; + bool barangayCall = false; + List? provinces; + List? citymuns; + List? barangays; + + ////Sponsor Agency Searchfield + Agency? selectedSponsorAgency; + Category? selectedSponsorAgencyCategory; + bool showSponsorCategoryAgency = false; + bool showSponsorAgencyPrivateRadio = false; + bool sponsorAgencyIsPrivate = false; + final addSponsorAgencyController = TextEditingController(); + final sponsorByFocusNode = FocusNode(); + final sponsorAgencyCategoryFocusNode = FocusNode(); + final selectedSponsorAgencyController = TextEditingController(); + +////Conducted By + Agency? selectedConductedByAgency; + Category? selectedConductedByAgencyCategory; + bool showConductedByAgencyPrivateRadio = false; + final conductedByFocusNode = FocusNode(); + final conductedByAgencyCategoryFocusNode = FocusNode(); + final addConductedByController = TextEditingController(); + bool showConductedByAgencyCategory = false; + bool conductedByCategoryIsPrivate = false; + final selectedConductedByController = TextEditingController(); + + final selectedTrainingController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return BlocBuilder( + builder: (context, state) { + if (state is LearningDevelopmentUpdatingState) { + selectedTrainingController.text = + state.learningDevelopement.conductedTraining!.title!.title!; + selectedTraining = LearningDevelopmentType( + id: state.learningDevelopement.conductedTraining!.title!.id, + title: selectedTrainingController.text); + selectedConductedByAgency = Agency( + id: state.learningDevelopement.conductedTraining!.conductedBy!.id, + name: null); + selectedConductedByController.text = + state.learningDevelopement.conductedTraining!.conductedBy!.name!; + selectedLearningDevelopmentType = state.types.firstWhere((element) => + element.id == + state.learningDevelopement.conductedTraining! + .learningDevelopmentType!.id); + currentTopicController.text = + state.learningDevelopement.conductedTraining!.topic!.title!; + selectedTopic = LearningDevelopmentType( + id: state.learningDevelopement.conductedTraining!.topic!.id, + title: null); + fromDateController.text = + state.learningDevelopement.conductedTraining!.fromDate.toString(); + toDateController.text = + state.learningDevelopement.conductedTraining!.toDate.toString(); + overseas = state.overseas; + if (!overseas) { + selectedRegion = state.currentRegion; + provinces = state.provinces; + selectedProvince = state.currentProvince; + citymuns = state.cities; + selectedMunicipality = state.currentCity; + barangays = state.barangay; + selectedBarangay = state.currentBarangay; + } else { + selectedCountry = state.currentCountry; + } + hasSponsor = state.learningDevelopement.sponsoredBy != null; + if (hasSponsor) { + selectedSponsorAgency = Agency( + id: state.learningDevelopement.sponsoredBy!.id, name: null); + selectedSponsorAgencyController.text = + state.learningDevelopement.sponsoredBy!.name!; + } + bool enabled; + if (state.learningDevelopement.conductedTraining?.locked != null && + state.learningDevelopement.conductedTraining!.locked == true) { + enabled = false; + } else { + enabled = true; + } + return Padding( + padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 24), + child: FormBuilder( + key: formKey, + child: ListView( + children: [ + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + const SizedBox( + height: 10, + ), + SizedBox( + ////Training selected Textfield + child: FormBuilderTextField( + onChanged: (value) { + selectedTraining = LearningDevelopmentType( + id: null, title: selectedTrainingController.text); + }, + enabled: enabled, + maxLines: 5, + controller: selectedTrainingController, + name: "", + decoration: normalTextFieldStyle("", "").copyWith( + labelText: "Training", + filled: !enabled, + fillColor: Colors.grey.shade300), + )), + SizedBox( + child: SizedBox( + child: Column(children: [ + const SizedBox( + height: 12, + ), + ////learning development type + FormBuilderDropdown( + enabled: enabled, + name: "types", + decoration: normalTextFieldStyle( + "Learning Development Type *", "") + .copyWith( + filled: !enabled, + fillColor: Colors.grey.shade300), + validator: FormBuilderValidators.required( + errorText: "This field is required"), + items: state.types + .map((e) => DropdownMenuItem< + LearningDevelopmentType>( + value: e, child: Text(e.title!))) + .toList(), + onChanged: (value) { + selectedLearningDevelopmentType = value; + }, + initialValue: selectedLearningDevelopmentType, + ), + + //// learning development topics + const SizedBox( + height: 12, + ), + StatefulBuilder(builder: (context, setState) { + return SearchField( + enabled: enabled, + controller: currentTopicController, + focusNode: topicFocusNode, + itemHeight: 100, + suggestionsDecoration: box1(), + suggestions: state.topics + .map((LearningDevelopmentType topic) => + SearchFieldListItem(topic.title!, + item: topic, + child: Padding( + padding: const EdgeInsets + .symmetric( + horizontal: 10), + child: ListTile( + title: Text( + topic.title!, + softWrap: true, + ), + )))) + .toList(), + + searchInputDecoration: + normalTextFieldStyle("Topic *", "") + .copyWith( + filled: !enabled, + fillColor: Colors.grey.shade300, + suffixIcon: const Icon( + Icons.arrow_drop_down)), + onSuggestionTap: (topic) { + if (topic.item?.id != null) { + selectedTopic = LearningDevelopmentType( + id: topic.item!.id, title: null); + } else { + selectedTopic = LearningDevelopmentType( + id: null, title: topic.item!.title); + } + setState(() { + topicFocusNode.unfocus(); + }); + }, + ////EMPTY WIDGET + emptyWidget: EmptyWidget( + title: "Add Topic", + controller: addTopicController, + onpressed: () { + setState(() { + LearningDevelopmentType newTopic = + LearningDevelopmentType( + id: null, + title: addTopicController.text + .toUpperCase()); + state.topics.insert(0, newTopic); + topicFocusNode.unfocus(); + addTopicController.text = ""; + Navigator.pop(context); + }); + }), + validator: (position) { + if (position!.isEmpty) { + return "This field is required"; + } + return null; + }, + ); + }), + + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + //// FROM DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + use24HourFormat: false, + icon: const Icon(Icons.date_range), + controller: fromDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + timeHintText: + "Date of Examination/Conferment", + decoration: normalTextFieldStyle( + "From *", "From *") + .copyWith( + filled: !enabled, + fillColor: + Colors.grey.shade300, + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + )), + initialValue: null, + )), + const SizedBox( + width: 12, + ), + //// TO DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: + FormBuilderValidators.required( + errorText: + "This field is required"), + controller: toDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: + normalTextFieldStyle("To *", "To *") + .copyWith( + filled: !enabled, + fillColor: Colors.grey.shade300, + prefixIcon: const Icon( + Icons.date_range, + color: Colors.black87, + ), + ), + initialValue: null, + ), + ), + ], + ), + ), + const SizedBox( + height: 12, + ), + //// total hours conducted + FormBuilderTextField( + initialValue: state.learningDevelopement + .conductedTraining!.totalHours + .toString(), + validator: numericRequired, + name: "total_hours", + decoration: normalTextFieldStyle( + "Total Hours Conducted *", + "0", + ).copyWith( + filled: !enabled, + fillColor: Colors.grey.shade300), + keyboardType: TextInputType.number, + ), + const SizedBox( + height: 12, + ), + ////Address + + const SizedBox( + height: 12, + ), + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + FormBuilderSwitch( + initialValue: overseas, + activeColor: second, + onChanged: (value) { + setState(() { + overseas = value!; + }); + }, + decoration: normalTextFieldStyle( + "Overseas Address?", ''), + name: 'overseas', + title: Text(overseas ? "YES" : "NO"), + ), + SizedBox( + height: overseas == true ? 8 : 0, + ), + SizedBox( + child: overseas == false + ? Column( + children: [ + const SizedBox( + height: 12, + ), + ////REGION DROPDOWN + FormBuilderDropdown( + enabled: !enabled + ? overseas + : true, + name: "region", + isExpanded: true, + initialValue: selectedRegion, + autovalidateMode: + AutovalidateMode + .onUserInteraction, + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + onChanged: + (Region? region) async { + if (selectedRegion != + region) { + setState(() { + provinceCall = true; + }); + selectedRegion = region; + //// GET PROVINCES + provinces = await LocationUtils + .instance + .getProvinces( + regionCode: + selectedRegion! + .code + .toString()); + selectedProvince = + provinces![0]; + setState(() { + provinceCall = false; + cityCall = true; + }); + //// GET CITIES + citymuns = await LocationUtils + .instance + .getCities( + code: + selectedProvince! + .code!); + selectedMunicipality = + citymuns![0]; + setState(() { + cityCall = false; + barangayCall = true; + }); + //// GET BARANGAY + barangays = await LocationUtils + .instance + .getBarangay( + code: + selectedMunicipality! + .code!); + selectedBarangay = + barangays![0]; + setState(() { + barangayCall = false; + }); + ////GET CITY MUNICIPALITY + citymuns = await LocationUtils + .instance + .getCities( + code: + selectedProvince! + .code!); + selectedMunicipality = + citymuns![0]; + setState(() { + cityCall = false; + barangayCall = true; + }); + //// GET BARANGAYS + barangays = await LocationUtils + .instance + .getBarangay( + code: + selectedMunicipality! + .code!); + selectedBarangay = + barangays![0]; + setState(() { + barangayCall = false; + }); + } + }, + decoration: + normalTextFieldStyle( + "Region*", + "Region") + .copyWith( + filled: !enabled + ? !overseas + : false, + fillColor: Colors + .grey + .shade300), + items: state.regions.map< + DropdownMenuItem< + Region>>( + (Region region) { + return DropdownMenuItem< + Region>( + value: region, + child: Text(region + .description!)); + }).toList(), + ), + const SizedBox( + height: 8, + ), + //// PROVINCE DROPDOWN + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.transparent, + inAsyncCall: provinceCall, + child: FormBuilderDropdown< + Province?>( + enabled: !enabled + ? overseas + : true, + name: "province", + autovalidateMode: + AutovalidateMode + .onUserInteraction, + validator: (value) => + value == null + ? 'required' + : null, + isExpanded: true, + initialValue: + selectedProvince, + onChanged: (Province? + province) async { + if (selectedProvince != + province) { + selectedProvince = + province; + setState(() { + cityCall = true; + }); + + //// GET CITIES + citymuns = await LocationUtils + .instance + .getCities( + code: selectedProvince! + .code!); + selectedMunicipality = + citymuns![0]; + setState(() { + cityCall = false; + barangayCall = + true; + }); + //// GET BARANGAY + barangays = await LocationUtils + .instance + .getBarangay( + code: selectedMunicipality! + .code!); + selectedBarangay = + barangays![0]; + setState(() { + barangayCall = + false; + }); + } + }, + items: provinces == null + ? [] + : provinces! + .map>( + (Province + province) { + return DropdownMenuItem( + value: + province, + child: + FittedBox( + child: Text( + province + .description!), + )); + }).toList(), + decoration: normalTextFieldStyle( + "Province*", "Province") + .copyWith( + filled: !enabled + ? !overseas + : false, + fillColor: Colors + .grey + .shade300)), + ), + ), + ////CITY MUNICIPALITY + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.white, + inAsyncCall: cityCall, + child: FormBuilderDropdown< + CityMunicipality>( + enabled: !enabled + ? overseas + : true, + name: "city", + validator: + FormBuilderValidators + .required( + errorText: + "This field is required"), + isExpanded: true, + onChanged: + (CityMunicipality? + city) async { + if (selectedMunicipality != + city) { + setState(() { + barangayCall = true; + }); + selectedMunicipality = + city; + selectedMunicipality = + city; + //// GET BARANGAYS + barangays = + await LocationUtils + .instance + .getBarangay( + code: selectedMunicipality! + .code!); + selectedBarangay = + barangays![0]; + setState(() { + barangayCall = + false; + }); + } + }, + decoration: normalTextFieldStyle( + "Municipality*", + "Municipality") + .copyWith( + filled: !enabled + ? !overseas + : false, + fillColor: Colors + .grey + .shade300), + initialValue: + selectedMunicipality, + items: citymuns == null + ? [] + : citymuns!.map< + DropdownMenuItem< + CityMunicipality>>( + (CityMunicipality + c) { + return DropdownMenuItem( + value: c, + child: Text(c + .description!)); + }).toList(), + ), + ), + ), + //// BARANGAY + SizedBox( + height: 60, + child: ModalProgressHUD( + color: Colors.white, + inAsyncCall: barangayCall, + child: FormBuilderDropdown< + Barangay>( + enabled: !enabled + ? overseas + : true, + name: "barangay", + isExpanded: true, + onChanged: + (Barangay? baragay) { + selectedBarangay = + baragay; + }, + decoration: normalTextFieldStyle( + "Barangay*", + "Barangay") + .copyWith( + filled: !enabled + ? !overseas + : false, + fillColor: Colors + .grey + .shade300), + initialValue: + selectedBarangay, + items: barangays == null + ? [] + : barangays!.map< + DropdownMenuItem< + Barangay>>( + (Barangay + barangay) { + return DropdownMenuItem( + value: + barangay, + child: Text( + barangay + .description!)); + }).toList(), + ), + ), + ), + ], + ) + //// COUNTRY DROPDOWN + : SizedBox( + height: 60, + child: + FormBuilderDropdown( + enabled: overseas, + initialValue: selectedCountry, + validator: FormBuilderValidators + .required( + errorText: + "This field is required"), + items: state.countries.map< + DropdownMenuItem< + Country>>( + (Country country) { + return DropdownMenuItem< + Country>( + value: country, + child: FittedBox( + child: Text( + country.name!))); + }).toList(), + name: 'country', + decoration: + normalTextFieldStyle( + "Country*", + "Country") + .copyWith( + filled: !overseas, + fillColor: Colors + .grey.shade300), + onChanged: (Country? value) { + selectedCountry = value; + }, + ), + ), + ), + ], + ); + }), + + ////Conducted By + StatefulBuilder(builder: (context, setState) { + ////has sponsor switch + return Column( + children: [ + ////Add Conducted Agency============ + SizedBox( + child: SizedBox( + child: Column(children: [ + SearchField( + enabled: enabled, + controller: + selectedConductedByController, + suggestionDirection: + SuggestionDirection.up, + itemHeight: 70, + focusNode: conductedByFocusNode, + suggestions: state.conductedBy + .map((Agency agency) => + SearchFieldListItem( + agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: + TextOverflow + .ellipsis, + ), + subtitle: Text(agency + .privateEntity == + true + ? "Private" + : agency.privateEntity == + false + ? "Government" + : ""), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle( + " Conducted By *", "") + .copyWith( + suffixIcon: + GestureDetector( + child: const Icon( + Icons + .arrow_drop_down, + ), + onTap: () => + conductedByFocusNode + .unfocus(), + ), + filled: !enabled, + fillColor: Colors + .grey.shade300), + ////SELETECTED + onSuggestionTap: (agency) { + setState(() { + if (agency.item?.id != null) { + selectedConductedByAgency = + Agency( + name: null, + id: agency.item!.id); + } else { + selectedConductedByAgency = + Agency( + id: null, + name: agency + .item!.name); + } + + if (agency + .item!.privateEntity == + null) { + showConductedByAgencyCategory = + true; + showConductedByAgencyPrivateRadio = + true; + } else { + showConductedByAgencyCategory = + false; + showConductedByAgencyPrivateRadio = + false; + } + conductedByFocusNode.unfocus(); + }); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + ////conducter empty widget + emptyWidget: EmptyWidget( + controller: + addConductedByController, + onpressed: () { + setState(() { + Agency newAgency = Agency( + id: null, + name: + addConductedByController + .text + .toUpperCase(), + category: null, + privateEntity: null); + state.conductedBy + .insert(0, newAgency); + + addConductedByController + .text = ""; + Navigator.pop(context); + }); + }, + title: + "Add Conducted By Agency")), + SizedBox( + height: showConductedByAgencyCategory + ? 12 + : 0, + ), + ////Sponsor Agency Category + SizedBox( + child: showConductedByAgencyCategory + ? SearchField( + suggestionDirection: + SuggestionDirection.up, + focusNode: + conductedByAgencyCategoryFocusNode, + itemHeight: 70, + suggestions: state + .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) { + setState(() { + selectedConductedByAgencyCategory = + agencyCategory.item; + selectedConductedByAgency = Agency( + id: selectedConductedByAgency + ?.id, + name: + selectedConductedByAgency! + .name, + category: + selectedConductedByAgencyCategory, + privateEntity: + showConductedByAgencyPrivateRadio); + conductedByAgencyCategoryFocusNode + .unfocus(); + }); + }, + searchInputDecoration: + normalTextFieldStyle( + "Category *", "") + .copyWith( + suffixIcon: + const Icon(Icons + .arrow_drop_down)), + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + ) + : const SizedBox(), + ), + + ////Sponsor Agency Private Radio + SizedBox( + height: + showConductedByAgencyPrivateRadio + ? 12 + : 0), + SizedBox( + child: + showConductedByAgencyPrivateRadio + ? FormBuilderSwitch( + initialValue: + conductedByCategoryIsPrivate, + title: Text( + conductedByCategoryIsPrivate + ? "YES" + : "NO"), + decoration: + normalTextFieldStyle( + "Private Entity?", + 'Private Entity?'), + + ////onvhange private sector + onChanged: (value) { + setState(() { + conductedByCategoryIsPrivate = + value!; + selectedConductedByAgency = Agency( + category: + selectedConductedByAgency + ?.category, + id: selectedConductedByAgency + ?.id, + name: + selectedConductedByAgency! + .name, + privateEntity: + conductedByCategoryIsPrivate); + conductedByAgencyCategoryFocusNode + .unfocus(); + }); + }, + name: + 'sponsorAgencyPrivate', + validator: + FormBuilderValidators + .required(), + ) + : const SizedBox()), + ]), + )), + ], + ); + }), + ]), + )), + const SizedBox( + height: 12, + ), + + ////Sponsor + StatefulBuilder(builder: (context, setState) { + ////has sponsor switch + return Column( + children: [ + FormBuilderSwitch( + initialValue: hasSponsor, + activeColor: second, + onChanged: (value) { + setState(() { + hasSponsor = value!; + }); + }, + decoration: + normalTextFieldStyle("Has Sponsor?", ''), + name: 'sponsor', + title: Text(hasSponsor ? "YES" : "NO"), + ), + ////Add Sponsor Agency============ + SizedBox( + child: hasSponsor + ? SizedBox( + child: Column(children: [ + const SizedBox( + height: 12, + ), + SearchField( + controller: + selectedSponsorAgencyController, + suggestionDirection: + SuggestionDirection.up, + itemHeight: 70, + focusNode: sponsorByFocusNode, + suggestions: state + .sponsorAgencies + .map((Agency agency) => + SearchFieldListItem( + agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: + TextOverflow + .ellipsis, + ), + subtitle: Text(agency + .privateEntity == + true + ? "Private" + : agency.privateEntity == + false + ? "Government" + : ""), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle( + " Sponsor Agency *", + "") + .copyWith( + suffixIcon: + GestureDetector( + child: const Icon( + Icons.arrow_drop_down, + ), + onTap: () => + sponsorByFocusNode + .unfocus(), + )), + ////SELETECTED + onSuggestionTap: (agency) { + setState(() { + if (agency.item?.id != + null) { + selectedSponsorAgency = + Agency( + name: null, + id: agency + .item!.id); + } else { + selectedSponsorAgency = + Agency( + id: null, + name: agency + .item!.name); + } + if (agency.item! + .privateEntity == + null) { + showSponsorCategoryAgency = + true; + showSponsorAgencyPrivateRadio = + true; + } else { + showSponsorCategoryAgency = + false; + showSponsorAgencyPrivateRadio = + false; + } + sponsorByFocusNode + .unfocus(); + }); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + ////sponsor empty widget + emptyWidget: EmptyWidget( + controller: + addSponsorAgencyController, + onpressed: () { + setState(() { + Agency newAgency = Agency( + id: null, + name: addSponsorAgencyController + .text + .toUpperCase(), + category: null, + privateEntity: + null); + state.sponsorAgencies + .insert( + 0, newAgency); + + addSponsorAgencyController + .text = ""; + Navigator.pop(context); + }); + }, + title: + "Add Sponsor Agency")), + SizedBox( + height: showSponsorCategoryAgency + ? 12 + : 0, + ), + ////Sponsor Agency Category + SizedBox( + child: showSponsorCategoryAgency + ? SearchField( + suggestionDirection: + SuggestionDirection + .up, + focusNode: + sponsorAgencyCategoryFocusNode, + itemHeight: 70, + suggestions: state + .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) { + setState(() { + selectedSponsorAgencyCategory = + agencyCategory + .item; + selectedSponsorAgency = Agency( + id: selectedSponsorAgency + ?.id, + name: + selectedSponsorAgency! + .name, + category: + selectedSponsorAgencyCategory, + privateEntity: + sponsorAgencyIsPrivate); + sponsorAgencyCategoryFocusNode + .unfocus(); + }); + }, + searchInputDecoration: + normalTextFieldStyle( + "Category *", + "") + .copyWith( + suffixIcon: + const Icon( + Icons + .arrow_drop_down)), + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + ) + : const SizedBox(), + ), + + ////Sponsor Agency Private Radio + SizedBox( + height: + showSponsorAgencyPrivateRadio + ? 12 + : 0), + SizedBox( + child: + showSponsorAgencyPrivateRadio + ? FormBuilderSwitch( + initialValue: + sponsorAgencyIsPrivate, + title: Text( + sponsorAgencyIsPrivate + ? "YES" + : "NO"), + decoration: normalTextFieldStyle( + "Private Entity?", + 'Private Entity?'), + + ////onvhange private sector + onChanged: (value) { + setState(() { + sponsorAgencyIsPrivate = + value!; + selectedSponsorAgency = Agency( + category: + selectedSponsorAgency + ?.category, + id: selectedSponsorAgency + ?.id, + name: selectedSponsorAgency! + .name, + privateEntity: + selectedSponsorAgency + ?.privateEntity); + sponsorAgencyCategoryFocusNode + .unfocus(); + }); + }, + + name: + 'sponsorAgencyPrivate', + validator: + FormBuilderValidators + .required(), + ) + : const SizedBox()), + ]), + ) + : const SizedBox(), + ), + ], + ); + }), + const SizedBox( + height: 12, + ), + const SizedBox( + height: 12, + ), + FormBuilderTextField( + initialValue: state + .learningDevelopement.totalHoursAttended + .toString(), + validator: numericRequired, + name: "total_hours_attended", + keyboardType: TextInputType.number, + decoration: normalTextFieldStyle( + "Total Hours Attended *", + "Total Hours Attended *"), + ), + ], + ); + }), + const SizedBox( + height: 12, + ), + SizedBox( + height: 60, + child: ElevatedButton( + style: + mainBtnStyle(primary, Colors.transparent, second), + child: const Text(submit), + onPressed: () { + if (formKey.currentState!.saveAndValidate()) { + ConductedTraining? training; + Agency? sponsor; + Venue venue; + ////Address + if (overseas) { + venue = Venue( + id: state.learningDevelopement + .conductedTraining!.venue!.id, + country: selectedCountry, + barangay: null, + category: null, + areaClass: null, + cityMunicipality: null); + } else { + venue = Venue( + id: state.learningDevelopement + .conductedTraining!.venue!.id, + country: Country( + id: 175, name: 'Philippines', code: 'PH'), + barangay: selectedBarangay, + areaClass: null, + category: null, + cityMunicipality: selectedMunicipality); + } + + training = ConductedTraining( + title: selectedTraining, + topic: selectedTopic, + id: state + .learningDevelopement.conductedTraining!.id, + locked: state.learningDevelopement + .conductedTraining?.locked, + venue: venue, + toDate: DateTime.parse(toDateController.text), + fromDate: + DateTime.parse(fromDateController.text), + totalHours: double.parse( + formKey.currentState!.value['total_hours']), + conductedBy: selectedConductedByAgency, + sessionsAttended: [], + learningDevelopmentType: + selectedLearningDevelopmentType); + + if (hasSponsor) { + sponsor = selectedSponsorAgency; + } + LearningDevelopement learningDevelopement = + LearningDevelopement( + attachments: null, + sponsoredBy: sponsor, + conductedTraining: training, + totalHoursAttended: double.parse(formKey + .currentState! + .value['total_hours_attended'])); + final progress = ProgressHUD.of(context); + progress!.showWithText("Loading..."); + context.read().add( + UpdateLearningDevelopment( + learningDevelopement: learningDevelopement, + profileId: widget.profileId, + token: widget.token)); + } + }, + ), + ) + ], + )), + ); + } + return const Center( + child: Text("ds"), + ); + }, + ); + } + + Future getProvinces() async { + try { + List newProvinces = await LocationUtils.instance + .getProvinces(regionCode: selectedRegion!.code.toString()); + setState(() { + provinces = newProvinces; + selectedProvince = provinces![0]; + provinceCall = false; + cityCall = true; + getCities(); + }); + } catch (e) { + context + .read() + .add(CallErrorState(message: e.toString())); + } + } + + Future getCities() async { + try { + List newCities = await LocationUtils.instance + .getCities(code: selectedProvince!.code.toString()); + citymuns = newCities; + setState(() { + selectedMunicipality = newCities[0]; + cityCall = false; + barangayCall = true; + getBarangays(); + }); + } catch (e) { + context + .read() + .add(CallErrorState(message: e.toString())); + } + } + + Future getBarangays() async { + try { + List newBarangays = await LocationUtils.instance + .getBarangay(code: selectedMunicipality!.code.toString()); + barangays = newBarangays; + setState(() { + selectedBarangay = newBarangays[0]; + barangayCall = false; + }); + } catch (e) { + context + .read() + .add(CallErrorState(message: e.toString())); + } + } +} diff --git a/lib/screens/profile/components/learning_development/search_field_widget.dart b/lib/screens/profile/components/learning_development/search_field_widget.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/screens/profile/components/learning_development/training_details.dart b/lib/screens/profile/components/learning_development/training_details.dart new file mode 100644 index 0000000..4b216ef --- /dev/null +++ b/lib/screens/profile/components/learning_development/training_details.dart @@ -0,0 +1,73 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/src/widgets/placeholder.dart'; +import 'package:intl/intl.dart'; + +import '../../../../model/profile/learning_development.dart'; + +class TrainingDisplayDetails extends StatelessWidget { + final ConductedTraining e; + final Function() notWhatYourLookingFor; + const TrainingDisplayDetails({super.key, required this.e, required this.notWhatYourLookingFor}); + + @override + Widget build(BuildContext context) { + DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + return Card( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + e.title!.title!.toUpperCase(), + style: const TextStyle(fontSize: 12, fontWeight: FontWeight.bold), + ), + const SizedBox( + height: 6, + ), + Text( + "CONDUCTED BY:", + style: + Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 8), + ), + Text(e.conductedBy!.name!, style: const TextStyle(fontSize: 12)), + const SizedBox( + height: 6, + ), + Row( + children: [ + Flexible( + child: Text( + dteFormat2.format(e.fromDate!), + style: Theme.of(context).textTheme.labelSmall, + )), + const Text(" - "), + Flexible( + child: Text( + dteFormat2.format(e.toDate!), + style: Theme.of(context).textTheme.labelSmall, + )) + ], + ), + Text("Total (hours): ${e.totalHours}", + style: Theme.of(context).textTheme.labelSmall), + Align( + alignment: Alignment.centerRight, + child: GestureDetector( + onTap: notWhatYourLookingFor, + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Text( + "NOT WHAT LOOKING FOR?", + style: TextStyle(fontSize: 10, color: Colors.black), + ), + ), + )), + ], + ), + ), + ); + } +} diff --git a/lib/screens/profile/components/loading_screen.dart b/lib/screens/profile/components/loading_screen.dart index 0d469b9..2747101 100644 --- a/lib/screens/profile/components/loading_screen.dart +++ b/lib/screens/profile/components/loading_screen.dart @@ -135,8 +135,8 @@ class LoadingScreen extends StatelessWidget { ), Center( child: Container( - height: 80, - width: 80, + height: 120, + width: 120, decoration:const BoxDecoration( color: Colors.black87, borderRadius: BorderRadius.all(Radius.circular(8)) @@ -145,9 +145,13 @@ class LoadingScreen extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: const[ + SpinKitFadingCircle( size: 42, color: Colors.white), + + SizedBox(height: 12,), + Text("Please wait..",style: TextStyle(color: Colors.white),), ], ), diff --git a/lib/screens/profile/components/voluntary_works/add_modal.dart b/lib/screens/profile/components/voluntary_works/add_modal.dart index 58fedba..a2b9c7e 100644 --- a/lib/screens/profile/components/voluntary_works/add_modal.dart +++ b/lib/screens/profile/components/voluntary_works/add_modal.dart @@ -124,7 +124,7 @@ class _AddVoluntaryWorkScreenState extends State { state.positions.insert(0, newAgencyPosition); addPositionController.text = ""; - Navigator.pop(context); + }); }), validator: (position) { diff --git a/lib/screens/profile/profile.dart b/lib/screens/profile/profile.dart index da19d56..9788394 100644 --- a/lib/screens/profile/profile.dart +++ b/lib/screens/profile/profile.dart @@ -12,6 +12,7 @@ import 'package:unit2/bloc/profile/primary_information/address/address_bloc.dart 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'; @@ -29,6 +30,7 @@ import 'package:unit2/screens/profile/components/references_screen.dart'; import 'package:unit2/screens/profile/components/work_history_screen.dart'; import 'package:unit2/screens/profile/components/voluntary_works_screen.dart'; import 'package:unit2/theme-data.dart/colors.dart'; +import 'package:unit2/widgets/error_state.dart'; import '../../bloc/profile/eligibility/eligibility_bloc.dart'; import '../../bloc/profile/family/family_bloc.dart'; import '../../bloc/profile/education/education_bloc.dart'; @@ -40,6 +42,8 @@ import '../../bloc/profile/references/references_bloc.dart'; import '../../bloc/profile/voluntary_works/voluntary_work_bloc.dart'; import '../../bloc/profile/workHistory/workHistory_bloc.dart'; import '../../bloc/user/user_bloc.dart'; +import '../../model/profile/basic_information/primary-information.dart'; +import '../unit2/homepage.dart/components/menu.dart'; import 'components/main_menu.dart'; import 'components/submenu.dart'; @@ -49,8 +53,8 @@ class ProfileInfo extends StatelessWidget { @override Widget build(BuildContext context) { int? profileId; - String? token; + Profile profile; return Scaffold( appBar: AppBar( backgroundColor: primary, @@ -65,13 +69,15 @@ class ProfileInfo extends StatelessWidget { if (state is UserLoggedIn) { profileId = state.userData!.user!.login!.user!.profileId; token = state.userData!.user!.login!.token!; + profile = state.userData!.employeeInfo!.profile!; + return BlocConsumer( listener: (context, state,){ if (state is ProfileLoading) { final progress = ProgressHUD.of(context); progress!.showWithText("Please wait..."); } - if (state is ProfileLoaded || state is ProfileErrorState) { + if (state is ProfileLoaded || state is ProfileErrorState || state is BasicInformationEditingState) { final progress = ProgressHUD.of(context); progress?.dismiss(); } @@ -104,13 +110,10 @@ class ProfileInfo extends StatelessWidget { ), items: [ subMenu(Icons.person, "Primary", () { + Navigator.push(context, MaterialPageRoute( builder: (BuildContext context) { - return PrimaryInfo( - primaryInformation: state - .profileInformation - .basicInfo - .primaryInformation!); + return BlocProvider.value(value: ProfileBloc()..add(GetPrimaryBasicInfo(primaryBasicInformation: profile)),child: PrimaryInfo(token: token!,profileId: profileId!,),); })); }), subMenu(Icons.home, "Home Addresses", () { @@ -363,7 +366,9 @@ class ProfileInfo extends StatelessWidget { return const LoadingScreen(); } if (state is ProfileErrorState) { - return Text(state.mesage); + return SomethingWentWrong(message: state.mesage, onpressed: (){ BlocProvider.of( + context) + .add(LoadProfile(token:token!, userID: profileId!));}); } return Container(); diff --git a/lib/screens/unit2/homepage.dart/components/menu.dart b/lib/screens/unit2/homepage.dart/components/menu.dart index 10103f7..d001e80 100644 --- a/lib/screens/unit2/homepage.dart/components/menu.dart +++ b/lib/screens/unit2/homepage.dart/components/menu.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:unit2/model/login_data/employee_info/employee_info.dart'; import 'package:unit2/model/login_data/user_info/user_data.dart'; import 'package:unit2/utils/alerts.dart'; +import '../../../../model/profile/basic_information/primary-information.dart'; import '../../../../theme-data.dart/colors.dart'; import '../../../../utils/global.dart'; diff --git a/lib/sevices/profile/learningDevelopment_service.dart b/lib/sevices/profile/learningDevelopment_service.dart index 9cf8154..c8775d3 100644 --- a/lib/sevices/profile/learningDevelopment_service.dart +++ b/lib/sevices/profile/learningDevelopment_service.dart @@ -1,6 +1,8 @@ import 'dart:convert'; +import 'package:flutter/material.dart'; import 'package:unit2/utils/request.dart'; +import 'package:unit2/utils/text_container.dart'; import '../../model/profile/learning_development.dart'; import '../../utils/urls.dart'; @@ -15,27 +17,265 @@ class LearningDevelopmentServices { int profileId, String token) async { List learningsAndDevelopments = []; String authToken = "Token $token"; - String path = "${Url.instance.getLearningAndDevelopments()}$profileId/"; + String path = "${Url.instance.learningAndDevelopments()}$profileId/"; Map headers = { 'Content-Type': 'application/json; charset=UTF-8', 'Authorization': authToken }; - // try { + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var learnings) { + LearningDevelopement learningDevelopement = + LearningDevelopement.fromJson(learnings); + learningsAndDevelopments.add(learningDevelopement); + }); + } + } + } catch (e) { + throw e.toString(); + } + return learningsAndDevelopments; + } + + ////Add + Future> add( + {required LearningDevelopement learningDevelopement, + required String token, + required int profileId}) async { + String authtoken = "Token $token"; + String path = '${Url.instance.learningAndDevelopments()}$profileId/'; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + Map statusResponse = {}; + try { + Map body = { + "training_conduct_id": learningDevelopement.conductedTraining?.id, + "total_hours_attended": + learningDevelopement.totalHoursAttended.toString(), + "sponsor_id": learningDevelopement.sponsoredBy?.id, + "sponsor_name": learningDevelopement.sponsoredBy?.name, + "sponsor_category": learningDevelopement.sponsoredBy?.category?.id, + "sponsor_private": learningDevelopement.sponsoredBy?.privateEntity, + "training_id": learningDevelopement.conductedTraining?.title?.id, + "training_title": learningDevelopement.conductedTraining?.title?.title, + "topic_id": learningDevelopement.conductedTraining?.topic?.id, + "topic_title": learningDevelopement.conductedTraining?.topic?.title, + "conductor_id": learningDevelopement.conductedTraining?.conductedBy?.id, + "conductor_name": + learningDevelopement.conductedTraining?.conductedBy?.name, + "conductor_category": + learningDevelopement.conductedTraining?.conductedBy?.category?.id!, + "conductor_private": + learningDevelopement.conductedTraining?.conductedBy?.privateEntity, + "venue_city_municipality": learningDevelopement + .conductedTraining?.venue?.cityMunicipality?.code, + "venue_barangay": + learningDevelopement.conductedTraining?.venue?.barangay?.code, + "learning_development_type": + learningDevelopement.conductedTraining?.learningDevelopmentType?.id, + "from_date": + learningDevelopement.conductedTraining?.fromDate?.toString(), + "to_date": learningDevelopement.conductedTraining?.toDate?.toString(), + "total_hours": learningDevelopement.conductedTraining?.totalHours, + "locked": false, + "venue_country": + learningDevelopement.conductedTraining!.venue!.country!.id + }; + http.Response response = await Request.instance + .postRequest(path: path, param: {}, body: body, headers: headers); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + statusResponse.addAll({'success': false}); + } + return statusResponse; + } catch (e) { + throw e.toString(); + } + } + + ////Add + Future> update( + {required LearningDevelopement learningDevelopement, + required String token, + required int profileId}) async { + String authtoken = "Token $token"; + String path = '${Url.instance.learningAndDevelopments()}$profileId/'; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + Map statusResponse = {}; + try { + Map body = { + "training_conduct_id": learningDevelopement.conductedTraining?.id, + "total_hours_attended": + learningDevelopement.totalHoursAttended.toString(), + "sponsor_id": learningDevelopement.sponsoredBy?.id, + "sponsor_name": learningDevelopement.sponsoredBy?.name, + "sponsor_category": learningDevelopement.sponsoredBy?.category?.id, + "sponsor_private": learningDevelopement.sponsoredBy?.privateEntity, + "training_id": learningDevelopement.conductedTraining?.title?.id, + "training_title": learningDevelopement.conductedTraining?.title?.title, + "topic_id": learningDevelopement.conductedTraining?.topic?.id, + "topic_title": learningDevelopement.conductedTraining?.topic?.title, + "conductor_id": learningDevelopement.conductedTraining?.conductedBy?.id, + "conductor_name": + learningDevelopement.conductedTraining?.conductedBy?.name, + "conductor_category": + learningDevelopement.conductedTraining?.conductedBy?.category?.id!, + "conductor_private": + learningDevelopement.conductedTraining?.conductedBy?.privateEntity, + "venue_city_municipality": learningDevelopement + .conductedTraining?.venue?.cityMunicipality?.code, + "venue_barangay": + learningDevelopement.conductedTraining?.venue?.barangay?.code, + "learning_development_type": + learningDevelopement.conductedTraining?.learningDevelopmentType?.id, + "from_date": + learningDevelopement.conductedTraining?.fromDate?.toString(), + "to_date": learningDevelopement.conductedTraining?.toDate?.toString(), + "total_hours": learningDevelopement.conductedTraining?.totalHours, + "locked": learningDevelopement.conductedTraining?.locked, + "venue_country": + learningDevelopement.conductedTraining!.venue!.country!.id + }; + http.Response response = await Request.instance + .putRequest(path: path, param: {}, body: body, headers: headers); + if (response.statusCode == 201) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + statusResponse.addAll({'success': false}); + } + return statusResponse; + } catch (e) { + throw e.toString(); + } + } + + ////Delete + Future delete( + {required int profileId, + required String token, + required int? sponsorId, + required double totalHours, + required int trainingId}) async { + bool? success; + Map params = {"force_mode": "true"}; + String authToken = "Token $token"; + String path = '${Url.instance.learningAndDevelopments()}$profileId/'; + Map body = { + "sponsor_id": sponsorId, + "total_hours_attended": totalHours, + "training_conduct_id": trainingId + }; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + try { + http.Response response = await Request.instance.deleteRequest( + path: path, headers: headers, body: body, param: params); + + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + success = data['success']; + } else { + success = false; + } + } catch (e) { + throw e.toString(); + } + return success!; + } + + Future> getConductedTrainings( + {required String key, required int page}) async { + List trainings = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + Map params = { + "title__title___ilike": key, + "page": page.toString() + }; + + String path = Url.instance.conductedTrainings(); + try { + http.Response response = await Request.instance + .getRequest(path: path, param: params, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var element) { + ConductedTraining training = ConductedTraining.fromJson(element); + trainings.add(training); + }); + } + } + } catch (e) { + throw e.toString(); + } + return trainings; + } + + Future> getLearningDevelopmentType() async { + List types = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + + String path = Url.instance.learningAndDevelopmentType(); + try { http.Response response = await Request.instance .getRequest(path: path, param: {}, headers: headers); if (response.statusCode == 200) { Map data = jsonDecode(response.body); if (data['data'] != null) { - data['data'].forEach((var learnings) { - LearningDevelopement learningDevelopement = - LearningDevelopement.fromJson(learnings); - learningsAndDevelopments.add(learningDevelopement); + data['data'].forEach((var element) { + LearningDevelopmentType type = + LearningDevelopmentType.fromJson(element); + types.add(type); }); } } - // } catch (e) { - // throw e.toString(); - // } - return learningsAndDevelopments; + } catch (e) { + throw e.toString(); + } + return types; + } + + Future> getTrainingTopics() async { + List topics = []; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + + String path = Url.instance.learningAndDevelopmentTopics(); + try { + http.Response response = await Request.instance + .getRequest(path: path, param: {}, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var element) { + LearningDevelopmentType type = + LearningDevelopmentType.fromJson(element); + topics.add(type); + }); + } + } + } catch (e) { + throw e.toString(); + } + return topics; } } diff --git a/lib/sevices/profile/profile_other_info.dart b/lib/sevices/profile/profile_other_info.dart new file mode 100644 index 0000000..8945835 --- /dev/null +++ b/lib/sevices/profile/profile_other_info.dart @@ -0,0 +1,137 @@ +import 'dart:convert'; + +import 'package:unit2/screens/profile/components/basic_information/profile_other_info.dart'; +import 'package:unit2/utils/urls.dart'; +import 'package:http/http.dart' as http; + +import '../../utils/request.dart'; +class ProfileOtherInfoServices{ + static final ProfileOtherInfoServices _instance = ProfileOtherInfoServices(); + + static ProfileOtherInfoServices get instace => _instance; + + Future>getReligions({String? token})async{ + String path = Url.instance.getReligions(); + List religions = []; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + 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) { + data['data'].forEach((var e) { + religions.add(ProfileOtherInfo.fromJson(e)); + }); + } + } + } catch (e) { + throw e.toString(); + } + return religions; + } + Future>getEthnicity({String? token})async{ + String path = Url.instance.getEthnicity(); + List ethnicity = []; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + 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) { + data['data'].forEach((var e) { + ethnicity.add(ProfileOtherInfo.fromJson(e)); + }); + } + } + } catch (e) { + throw e.toString(); + } + return ethnicity; + } + + Future>getDisability({required token})async{ + String path = Url.instance.getDisability(); + List disabilities = []; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + 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) { + data['data'].forEach((var e) { + disabilities.add(ProfileOtherInfo.fromJson(e)); + }); + } + } + } catch (e) { + throw e.toString(); + } + return disabilities; + } + Future>getGenders({required token})async{ + String path = Url.instance.getGenders(); + List genders = []; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + 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) { + data['data'].forEach((var e) { + genders.add(ProfileOtherInfo.fromJson(e)); + }); + } + } + } catch (e) { + throw e.toString(); + } + return genders; + } + + Future>getIndigency({required String? token})async{ + String path = Url.instance.getIndigency(); + List indigencies = []; + String authToken = "Token $token"; + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authToken + }; + 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) { + data['data'].forEach((var e) { + indigencies.add(ProfileOtherInfo.fromJson(e)); + }); + } + } + } catch (e) { + throw e.toString(); + } + return indigencies; + } + + +} \ No newline at end of file diff --git a/lib/sevices/profile/profile_service.dart b/lib/sevices/profile/profile_service.dart index d085a98..7ff4b12 100644 --- a/lib/sevices/profile/profile_service.dart +++ b/lib/sevices/profile/profile_service.dart @@ -30,7 +30,7 @@ class ProfileService { String url = Url.instance.profileInformation(); String path = url + id.toString(); ProfileInformation? profileInformation0; - PrimaryInformation? primaryInformation; + List addresses = []; List identificationInformation = []; List contactInformation = []; @@ -39,172 +39,107 @@ class ProfileService { 'Content-Type': 'application/json; charset=UTF-8', 'Authorization': "Token $token" }; - Map param={"basic":"true"}; - // try{ - http.Response response = await Request.instance - .getRequest(path: path, param: param, headers: headers); - if (response.statusCode == 200) { - Map data = jsonDecode(response.body); + Map param = {"basic": "true"}; + try { + http.Response response = await Request.instance + .getRequest(path: path, param: param, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); - // get primary information - if (data['data']['basic_information']['primary_information'] != null) { - primaryInformation = PrimaryInformation.fromJson( - data['data']['basic_information']['primary_information']); - } else { - primaryInformation = null; - } + // get all contacts + if (data['data']['basic_information']['contact_information'] != null) { + data['data']['basic_information']['contact_information'] + .forEach((var contact) { + ContactInfo contactInfo = + ContactInfo.fromJson(contact['contact_info']); + contactInformation.add(contactInfo); + }); + } - // get all contacts - if (data['data']['basic_information']['contact_information'] != null) { - data['data']['basic_information']['contact_information'] - .forEach((var contact) { - ContactInfo contactInfo = - ContactInfo.fromJson(contact['contact_info']); - contactInformation.add(contactInfo); - }); - } + // get all addresses + if (data['data']['basic_information']['addresses'] != null) { + data['data']['basic_information']['addresses'].forEach((var address) { + MainAdress mainAdress = MainAdress.fromJson(address); + addresses.add(mainAdress); + }); + } - // get all addresses - if (data['data']['basic_information']['addresses'] != null) { - data['data']['basic_information']['addresses'].forEach((var address) { - MainAdress mainAdress = MainAdress.fromJson(address); - addresses.add(mainAdress); - }); - } + // get all identifications + if (data['data']['basic_information']['identification_records'] != + null) { + data['data']['basic_information']['identification_records']! + .forEach((var identity) { + Identification identification = Identification.fromJson(identity); + identificationInformation.add(identification); + }); + } - // get all identifications - if (data['data']['basic_information']['identification_records'] != null) { - data['data']['basic_information']['identification_records']! - .forEach((var identity) { - Identification identification = Identification.fromJson(identity); - identificationInformation.add(identification); - }); - } + BasicInfo basicInfo = BasicInfo( + contactInformation: contactInformation, + identifications: identificationInformation, + citizenships: citizenships, + addresses: addresses); - // get all family background - // if(data['data']['family_background'] != null){ - // data['data']['family_background'].forEach((var family){ - // FamilyBackground familyBackground = FamilyBackground.fromJson(family); - // families.add(familyBackground); - // }); - // } - - //get all eligibilities - // if (data['data']['eligibilities'] != null) { - // data['data']['eligibilities']!.forEach((var cert) { - // EligibityCert eligibility = EligibityCert.fromJson(cert); - // eligibilities.add(eligibility); - // }); - // } - - // get all citizenships - // if (data['data']['citizenship'] != null) { - // data['data']['citizenships']!.forEach((var citizenship) { - // Citizenship person = Citizenship.fromJson(citizenship); - // citizenships.add(person); - // }); - // } - // get all references; - // if (data['data']['personal_references'] != null) { - // data['data']['personal_references'].forEach((var person) { - // PersonalReference reference = PersonalReference.fromJson(person); - // references.add(reference); - // }); - // } - - //get all learning and developments - // if (data['data']['learning_development'] != null) { - // data['data']['learning_development'].forEach((var training) { - // LearningDevelopement learnings = - // LearningDevelopement.fromJson(training); - // learningsDevelopments.add(learnings); - // }); - // } - - //get all educational background - // if (data['data']['education_background'] != null) { - // data['data']['education_background'].forEach((var education) { - // EducationalBackground educationalBackground = - // EducationalBackground.fromJson(education); - // educationalBackgrounds.add(educationalBackground); - // }); - // } - - // get all work history - // if (data['data']['work_experiences'] != null) { - // data['data']['work_experiences'].forEach((var work) { - // WorkHistory experience = WorkHistory.fromJson(work); - // workExperiences.add(experience); - // }); - // } - - // get all voluntary works - // if (data['data']['voluntary_works'] != null) { - // data['data']['voluntary_works'].forEach((var work) { - // VoluntaryWork vwork = VoluntaryWork.fromJson(work); - // voluntaryWorks.add(vwork); - // }); - // } - - // get all hobbies - // if (data['data']['other_information']['skills_hobbies'] != null) { - // data['data']['other_information']['skills_hobbies'] - // .forEach((var skills_hobbies) { - // SkillsHobbies skillsAndHobbies = - // SkillsHobbies.fromJson(skills_hobbies); - // skillsHobbies.add(skillsAndHobbies); - // }); - // } - - //get all organization memberships - // if (data['data']['other_information']['organization_memberships'] != - // null) { - // data['data']['other_information']['organization_memberships'] - // .forEach((var org) { - // OrganizationMembership organization = - // OrganizationMembership.fromJson(org); - // orgMemberships.add(organization); - // }); - // } - -//get all non academic recognition - // if (data['data']['other_information']['non_academic_records'] != null) { - // data['data']['other_information']['non_academic_records'] - // .forEach((var recognition) { - // NonAcademicRecognition nonAcademicRecognition = - // NonAcademicRecognition.fromJson(recognition); - // nonAcademicRecognitions.add(nonAcademicRecognition); - // }); - // } - - BasicInfo basicInfo = BasicInfo( - contactInformation: contactInformation, - primaryInformation: primaryInformation, - identifications: identificationInformation, - citizenships: citizenships, - addresses: addresses); - // OtherInformation otherInformation = OtherInformation( - // skillsAndHobbies: skillsHobbies, - // orgMemberships: orgMemberships, - // nonAcademicRecognition: nonAcademicRecognitions); - ProfileInformation profileInformation = ProfileInformation( - // families: families, - // otherInformation: otherInformation, - // workExperiences: workExperiences, + ProfileInformation profileInformation = ProfileInformation( basicInfo: basicInfo, - // eligibilities: eligibilities, - // references: references, - // learningsAndDevelopment: learningsDevelopments, - // educationalBackgrounds: educationalBackgrounds, - // voluntaryWorks: voluntaryWorks - ); - profileInformation0 = profileInformation; + ); + profileInformation0 = profileInformation; + } + } catch (e) { + throw (e.toString()); } - // }catch(e){ - // throw(e.toString()); - // } return profileInformation0; } + + ////Update Profile info + Future> updateBasicProfileInfo( + {required String token, + required int profileId, + required Profile profileInfo, + required int? genderId, + required int? indigencyId, + required int? disabilityId, + required int? ethnicityId, + required int? reqligionId}) async { + String authtoken = "Token $token"; + String path = Url.instance.updatePersonalInfor(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': authtoken + }; + Map? statusResponse = {}; + Map body = { + "profile_id": profileId, + "first_name": profileInfo.firstName, + "middle_name": profileInfo.middleName, + "last_name": profileInfo.lastName, + "name_extension": profileInfo.nameExtension, + "birthdate": profileInfo.birthdate.toString(), + "sex": profileInfo.sex, + "blood_type": profileInfo.bloodType, + "civil_status": profileInfo.civilStatus, + "height": profileInfo.heightM, + "weight": profileInfo.weightKg, + "ethnicity_id": ethnicityId, + "disability_id": disabilityId, + "gender_id": genderId, + "religion_id": reqligionId, + "ip_id": indigencyId, + "title_prefix": profileInfo.titlePrefix, + "title_suffix": profileInfo.titleSuffix + }; + // try { + http.Response response = await Request.instance + .postRequest(path: path, headers: headers, body: body, param: {}); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + statusResponse = data; + } else { + statusResponse.addAll({'success': false}); + } + return statusResponse; + // } catch (e) { + // throw e.toString(); + // } + } } - - diff --git a/lib/utils/global.dart b/lib/utils/global.dart index 65b6eaf..a58ef4a 100644 --- a/lib/utils/global.dart +++ b/lib/utils/global.dart @@ -10,6 +10,8 @@ double safeBlockHorizontal = 0; double safeBlockVertical = 0; + + //// hive boxes Box? CREDENTIALS; Box? SOS; \ No newline at end of file diff --git a/lib/utils/request.dart b/lib/utils/request.dart index 329b3c4..3771b9a 100644 --- a/lib/utils/request.dart +++ b/lib/utils/request.dart @@ -10,7 +10,7 @@ import 'package:unit2/utils/urls.dart'; class Request { static final Request _instance = Request(); static Request get instance => _instance; - int requestTimeout = 25; + int requestTimeout = 30; String host = Url.instance.host(); Future getRequest( diff --git a/lib/utils/urls.dart b/lib/utils/urls.dart index 4f41d94..932de80 100644 --- a/lib/utils/urls.dart +++ b/lib/utils/urls.dart @@ -4,9 +4,10 @@ class Url { String host() { // return '192.168.10.183:3000'; - // return 'agusandelnorte.gov.ph'; - // return "192.168.10.219:3000"; - return "playweb.agusandelnorte.gov.ph"; + return 'agusandelnorte.gov.ph'; + // // return "192.168.10.219:3000"; + // return "192.168.10.241"; + // return "playweb.agusandelnorte.gov.ph"; // return 'devapi.agusandelnorte.gov.ph:3004'; } @@ -87,9 +88,18 @@ String getHonors(){ //// learning and development paths -String getLearningAndDevelopments(){ +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(){ @@ -129,6 +139,9 @@ String addEmergency(){ String getRelationshipTypes(){ return "/api/jobnet_app/relationship_types"; } +String updatePersonalInfor(){ + return "/api/jobnet_app/profile/pds/basic/personal/"; +} //// contacts path @@ -150,8 +163,28 @@ String getCommunicationProvider(){ 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/"; +} - // location utils path +String getDisability(){ + return "api/profile_app/disability/"; +} + +String getIndigency(){ + return "/api/profile_app/indigenous/"; +} + +String getGenders(){ + return "/api/profile_app/gender/"; +} + + + //// location utils path String getCounties(){ return "/api/jobnet_app/countries/"; } diff --git a/pubspec.lock b/pubspec.lock index 1f2ef3f..b586442 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1101,6 +1101,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.3" + searchable_paginated_dropdown: + dependency: "direct main" + description: + name: searchable_paginated_dropdown + sha256: "289a40f7b0964f91b3d8123b4654a8397ec9df9fd1a6bc8ab545ec33c81a9eb2" + url: "https://pub.dev" + source: hosted + version: "1.2.0" searchfield: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 5a652da..4bcf5cc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -79,6 +79,7 @@ dependencies: location: ^4.3.0 platform_device_id: ^1.0.1 multi_dropdown: ^1.0.9 + searchable_paginated_dropdown: ^1.2.0 dev_dependencies: flutter_test: