From e087eb147daa651c161df5d6d2766a19529974e2 Mon Sep 17 00:00:00 2001 From: PGAN-MIS Date: Thu, 16 Mar 2023 15:53:42 +0800 Subject: [PATCH] replacing selectdot2 --- ios/Podfile.lock | 6 + .../profile/eligibility/eligibility_bloc.dart | 1 + lib/bloc/profile/profile_bloc.dart | 3 +- .../profile/workHistory/workHistory_bloc.dart | 223 ++++- .../workHistory/workHistory_event.dart | 20 + .../workHistory/workHistory_state.dart | 22 + lib/model/utils/agency_position.dart | 53 ++ .../components/eligibility/add_modal.dart | 787 +++++++++--------- .../profile/components/loading_screen.dart | 270 +++--- .../components/work_history/add_modal.dart | 680 +++++++++++++++ .../components/work_history_screen.dart | 123 ++- lib/screens/profile/profile.dart | 41 +- .../homepage.dart/components/dashboard.dart | 58 +- .../profile/work_history_services.dart | 163 +++- lib/utils/custom_dropdown_button.dart | 149 ++++ lib/utils/urls.dart | 14 +- lib/utils/validators.dart | 4 + pubspec.lock | 48 ++ pubspec.yaml | 7 + 19 files changed, 2062 insertions(+), 610 deletions(-) create mode 100644 lib/model/utils/agency_position.dart create mode 100644 lib/screens/profile/components/work_history/add_modal.dart create mode 100644 lib/utils/custom_dropdown_button.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e6a0ac0..26d9bc2 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -22,6 +22,8 @@ PODS: - FlutterMacOS - permission_handler_apple (9.0.4): - Flutter + - search_choices (0.0.1): + - Flutter - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS @@ -40,6 +42,7 @@ DEPENDENCIES: - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - search_choices (from `.symlinks/plugins/search_choices/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) @@ -67,6 +70,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/path_provider_foundation/ios" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" + search_choices: + :path: ".symlinks/plugins/search_choices/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/ios" sqflite: @@ -83,6 +88,7 @@ SPEC CHECKSUMS: package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce + search_choices: b50731e8c425078048f681f39c34375c58d6ce8d shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1 diff --git a/lib/bloc/profile/eligibility/eligibility_bloc.dart b/lib/bloc/profile/eligibility/eligibility_bloc.dart index 13f14bc..9ce54ee 100644 --- a/lib/bloc/profile/eligibility/eligibility_bloc.dart +++ b/lib/bloc/profile/eligibility/eligibility_bloc.dart @@ -172,6 +172,7 @@ class EligibilityBloc extends Bloc { if (success) { event.eligibilities.removeWhere( ((EligibityCert element) => element.id == event.eligibilityId)); + List eligibilities = event.eligibilities; emit(DeletedState(success: success, eligibilities: eligibilities)); } else { diff --git a/lib/bloc/profile/profile_bloc.dart b/lib/bloc/profile/profile_bloc.dart index 6316746..162bb9e 100644 --- a/lib/bloc/profile/profile_bloc.dart +++ b/lib/bloc/profile/profile_bloc.dart @@ -9,8 +9,9 @@ class ProfileBloc extends Bloc { ProfileBloc() : super(ProfileInitial()) { ProfileInformation? globalProfileInformation; on((event, emit) async { + emit(ProfileLoading()); try { - emit(ProfileLoading()); + ProfileInformation? profileInformation = await ProfileService.instance.getProfile(event.token, event.userID); globalProfileInformation = profileInformation; diff --git a/lib/bloc/profile/workHistory/workHistory_bloc.dart b/lib/bloc/profile/workHistory/workHistory_bloc.dart index 3c8d4a5..bf5a416 100644 --- a/lib/bloc/profile/workHistory/workHistory_bloc.dart +++ b/lib/bloc/profile/workHistory/workHistory_bloc.dart @@ -1,23 +1,228 @@ import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; +import 'package:select2dot1/select2dot1.dart'; import 'package:unit2/model/profile/work_history.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/agency_position.dart'; import 'package:unit2/sevices/profile/work_history_services.dart'; +import '../../../model/utils/category.dart'; + part 'workHistory_event.dart'; part 'workHistory_state.dart'; class WorkHistoryBloc extends Bloc { - List workExperiences = []; + List workExperiences = []; + List agencyPositions = []; + List agencies = []; + List appointmentStatus = []; + List agencyCategory = []; WorkHistoryBloc() : super(EducationInitial()) { - on((event, emit)async { - emit(WorkHistoryLoadingState()); - // try{ - List works = await WorkHistoryService.instance.getWorkExperiences(event.profileId, event.token); - workExperiences = works; + on((event, emit) async { + emit(WorkHistoryLoadingState()); + try { + List works = await WorkHistoryService.instance + .getWorkExperiences(event.profileId, event.token); + workExperiences = works; + emit(WorkHistoryLoaded(workExperiences: workExperiences)); + } catch (e) { + emit(WorkHistoryErrorState(message: e.toString())); + } + }); + + on((event,emit){ + emit(WorkHistoryLoadingState()); + workExperiences = event.workHistories; emit(WorkHistoryLoaded(workExperiences: workExperiences)); - // }catch(e){ - // emit(WorkHistoryErrorState(message: e.toString())); - // } + }); + on((event,emit)async{ + emit(WorkHistoryLoadingState()); + try{ + final bool success = await WorkHistoryService.instance.delete(profileId: event.profileId,token: event.token, work: event.workHistory); + if(success){ + event.workHistories.removeWhere((WorkHistory element) => element.id == event.workHistory.id); + List newWorkHistories = event.workHistories; + emit(DeletedState(success: success,workHistories: newWorkHistories)); + }else{ + emit(DeletedState(success: success, workHistories: event.workHistories)); + } + + }catch(e){ + emit(WorkHistoryErrorState(message: e.toString())); + } + }); + on((event, emit) async { + emit(WorkHistoryLoadingState()); + try { + /////POSITIONS------------------------------------------ + List positions = + await WorkHistoryService.instance.getAgencyPosition(); + agencyPositions = positions; + + /////AGENCIES------------------------------------------ + List newAgencies = + await WorkHistoryService.instance.getAgecies(); + agencies = newAgencies; + + /////Category Agency------------------------------------------ + List categoryAgencies = + await WorkHistoryService.instance.agencyCategory(); + agencyCategory = categoryAgencies; + /////////------------------------------------- + List status = WorkHistoryService.instance.getAppointmentStatusList(); + appointmentStatus = status; + + +List agricultureList =[]; +List businessInfoList =[]; +List constructionList =[]; +List educationList =[]; +List financeList =[]; +List foodList =[]; +List gamingList =[]; +List healthList =[]; +List motorList =[]; +List naturalList =[]; +List otherList =[]; +List personalList =[]; +List publicList =[]; +List realStateList =[]; +List safetyList =[]; +List transportList =[]; + for (Category category in agencyCategory) { + if (category.industryClass!.name == "Agriculture & Forestry/Wildlife") { + agricultureList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Business & Information") { + businessInfoList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Construction/Utilities/Contracting") { + constructionList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Education") { + educationList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Finance & Insurance") { + financeList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Food & Hospitality") { + foodList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Gaming") { + gamingList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Health Services") { + healthList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Motor Vehicle") { + motorList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Natural Resources/Environmental") { + naturalList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Other") { + otherList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Personal Services") { + personalList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Public Governance") { + publicList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Real Estate & Housing") { + realStateList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Safety/Security & Legal") { + safetyList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + if (category.industryClass!.name == "Transportation") { + transportList + .add(SingleItemCategoryModel(nameSingleItem: category.name!)); + } + } + + SingleCategoryModel agricultureForestryWildlife = + SingleCategoryModel( + nameCategory: "Agriculture & Forestry/Wildlife", + singleItemCategoryList: agricultureList); + + SingleCategoryModel businessInformation = SingleCategoryModel( + nameCategory: "Business & Information", singleItemCategoryList: businessInfoList); + + SingleCategoryModel constructionUtilitiesContracting = + SingleCategoryModel( + nameCategory: "Construction/Utilities/Contracting", + singleItemCategoryList: constructionList); + SingleCategoryModel education = SingleCategoryModel( + nameCategory: "Education", singleItemCategoryList: educationList); + SingleCategoryModel financeInsurance = SingleCategoryModel( + nameCategory: "Finance & Insurance", singleItemCategoryList: financeList); + SingleCategoryModel foodHospitality = SingleCategoryModel( + nameCategory: "Food & Hospitality", singleItemCategoryList: foodList); + SingleCategoryModel gaming = SingleCategoryModel( + nameCategory: "Gaming", singleItemCategoryList: gamingList); + SingleCategoryModel healthServices = SingleCategoryModel( + nameCategory: "Health Services", singleItemCategoryList: healthList); + SingleCategoryModel motorVehicle = SingleCategoryModel( + nameCategory: "Motor Vehicle", singleItemCategoryList: motorList); + SingleCategoryModel naturalResourcesEnvironmental = + SingleCategoryModel( + nameCategory: "Natural Resources/Environmental", + singleItemCategoryList: naturalList); + SingleCategoryModel others = SingleCategoryModel( + nameCategory: "Others", singleItemCategoryList: otherList); + SingleCategoryModel personalServices = SingleCategoryModel( + nameCategory: "Personal Services", singleItemCategoryList: personalList); + SingleCategoryModel publicGovernance = SingleCategoryModel( + nameCategory: "Public Governance", singleItemCategoryList: publicList); + SingleCategoryModel realStateHousing = SingleCategoryModel( + nameCategory: "Real Estate & Housing", singleItemCategoryList: realStateList); + SingleCategoryModel safetySecurityLegal = SingleCategoryModel( + nameCategory: "Safety/Security & Legal", + singleItemCategoryList: safetyList); + SingleCategoryModel transportation = SingleCategoryModel( + nameCategory: "Transportation", singleItemCategoryList: transportList); + final List agencyCategoryDropdownData = [ + agricultureForestryWildlife, + businessInformation, + constructionUtilitiesContracting, + education, + financeInsurance, + foodHospitality, + gaming, + healthServices, + motorVehicle, + naturalResourcesEnvironmental, + others, + personalServices, + publicGovernance, + realStateHousing, + safetySecurityLegal, + transportation, + ]; + emit(AddWorkHistoryState( + agencyPositions:agencyPositions, + appointmentStatus: appointmentStatus, + agencyCategory: agencyCategoryDropdownData, + agencies: agencies)); + } catch (e) { + emit(WorkHistoryErrorState(message: e.toString())); + } }); } } diff --git a/lib/bloc/profile/workHistory/workHistory_event.dart b/lib/bloc/profile/workHistory/workHistory_event.dart index 7f3e066..5624086 100644 --- a/lib/bloc/profile/workHistory/workHistory_event.dart +++ b/lib/bloc/profile/workHistory/workHistory_event.dart @@ -17,4 +17,24 @@ class GetWorkHistories extends WorkHistorytEvent{ List get props => [profileId, token]; } +class LoadWorkHistories extends WorkHistorytEvent{ + final List workHistories; + const LoadWorkHistories({required this.workHistories}); + @override + List get props => [workHistories]; +} + +class ShowAddWorkHistoryForm extends WorkHistorytEvent{ + +} +class DeleteWorkHistory extends WorkHistorytEvent{ + final List workHistories; + final String token; + final int profileId; + final WorkHistory workHistory; + const DeleteWorkHistory({required this.profileId, required this.token, required this.workHistory, required this.workHistories}); + @override + List get props => [token, profileId,workHistory, workHistories]; +} + diff --git a/lib/bloc/profile/workHistory/workHistory_state.dart b/lib/bloc/profile/workHistory/workHistory_state.dart index 21158a9..ae4a74f 100644 --- a/lib/bloc/profile/workHistory/workHistory_state.dart +++ b/lib/bloc/profile/workHistory/workHistory_state.dart @@ -26,3 +26,25 @@ class WorkHistoryErrorState extends WorkHistoryState{ @override List get props => [message]; } + + + +class AddWorkHistoryState extends WorkHistoryState{ + final List agencyPositions; + final List agencies; + final List agencyCategory; + final List appointmentStatus; + + const AddWorkHistoryState({required this.agencyPositions, required this.appointmentStatus,required this.agencies,required this.agencyCategory}); + @override + List get props => [agencyPositions,appointmentStatus,agencies,agencyCategory]; + +} + +class DeletedState extends WorkHistoryState{ + final List workHistories; + final bool success; + const DeletedState({required this.success, required this.workHistories}); + @override + List get props => [workHistories,success]; +} diff --git a/lib/model/utils/agency_position.dart b/lib/model/utils/agency_position.dart new file mode 100644 index 0000000..3e6e48d --- /dev/null +++ b/lib/model/utils/agency_position.dart @@ -0,0 +1,53 @@ + +import 'dart:convert'; + +AgencyPosition agencyPositionFromJson(String str) => AgencyPosition.fromJson(json.decode(str)); + +String agencyPositionToJson(AgencyPosition data) => json.encode(data.toJson()); + +class AgencyPosition { + AgencyPosition({ + required this.id, + required this.title, + }); + + final int? id; + final String? title; + + factory AgencyPosition.fromJson(Map json) => AgencyPosition( + id: json["id"], + title: json["title"], + ); + + Map toJson() => { + "id": id, + "title": title, + }; +} +// To parse this JSON data, do +// +// final appoinemtStatus = appoinemtStatusFromJson(jsonString); +AppoinemtStatus appoinemtStatusFromJson(String str) => AppoinemtStatus.fromJson(json.decode(str)); + +String appoinemtStatusToJson(AppoinemtStatus data) => json.encode(data.toJson()); + +class AppoinemtStatus { + AppoinemtStatus({ + required this.value, + required this.label, + }); + + final String value; + final String label; + + factory AppoinemtStatus.fromJson(Map json) => AppoinemtStatus( + value: json["value"], + label: json["label"], + ); + + Map toJson() => { + "value": value, + "label": label, + }; +} + diff --git a/lib/screens/profile/components/eligibility/add_modal.dart b/lib/screens/profile/components/eligibility/add_modal.dart index 4e0fe91..7e7e9fc 100644 --- a/lib/screens/profile/components/eligibility/add_modal.dart +++ b/lib/screens/profile/components/eligibility/add_modal.dart @@ -62,427 +62,438 @@ class _AddEligibilityScreenState extends State { profileId = state.userData!.user!.login!.user!.profileId.toString(); return BlocBuilder( builder: (context, state) { - if(state is ProfileLoaded){ - return BlocBuilder( - buildWhen: (previous, current) { - if (state is EditEligibilityState) {} - return false; - }, - builder: (context, state) { - //EDIT ELIGIBILITY STATE - if (state is AddEligibilityState) { - return ProgressHUD( - child: Center( - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 25, horizontal: 18), - child: FormBuilder( - key: formKey, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - //ELIGIBILITIES DROPDOWN - FormBuilderDropdown( - onChanged: (Eligibility? eligibility) { - selectedEligibility = eligibility; - }, - autovalidateMode: - AutovalidateMode.onUserInteraction, - validator: (value) => - value == null ? 'required' : null, - items: state.eligibilities - .map>( - (Eligibility eligibility) { - return DropdownMenuItem( - value: eligibility, - child: Text(eligibility.title)); - }).toList(), - name: "eligibility", - decoration: normalTextFieldStyle( - "Eligibility", "Eligibility")), - const SizedBox( - height: 20, - ), - - SizedBox( - width: screenWidth, - child: Row( - children: [ - //LICENSE NUMBER - Flexible( - flex: 1, - child: FormBuilderTextField( - onChanged: (value) { - license = value; - }, - name: 'license_number', - decoration: normalTextFieldStyle( - "license number", - "license number"), - ), - ), - const SizedBox( - width: 12, - ), - //RATING - Flexible( - flex: 1, - child: FormBuilderTextField( - keyboardType: const TextInputType - .numberWithOptions(), - onChanged: (value) { - rating = value; - }, - name: 'rating', - decoration: normalTextFieldStyle( - 'rating %', 'rating'), - ), - ), - ], + if (state is ProfileLoaded) { + return BlocBuilder( + buildWhen: (previous, current) { + if (state is EditEligibilityState) {} + return false; + }, + builder: (context, state) { + //EDIT ELIGIBILITY STATE + if (state is AddEligibilityState) { + return ProgressHUD( + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 18), + child: FormBuilder( + key: formKey, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + //ELIGIBILITIES DROPDOWN + FormBuilderDropdown( + onChanged: (Eligibility? eligibility) { + selectedEligibility = eligibility; + }, + autovalidateMode: + AutovalidateMode.onUserInteraction, + validator: (value) => + value == null ? 'required' : null, + items: state.eligibilities + .map>( + (Eligibility eligibility) { + return DropdownMenuItem( + value: eligibility, + child: Text(eligibility.title)); + }).toList(), + name: "eligibility", + decoration: normalTextFieldStyle( + "Eligibility", "Eligibility")), + const SizedBox( + height: 20, ), - ), - const SizedBox( - height: 20, - ), - SizedBox( - width: screenWidth, - child: Row( - children: [ - //EXAM DATE - Flexible( + + SizedBox( + width: screenWidth, + child: Row( + children: [ + //LICENSE NUMBER + Flexible( + flex: 1, + child: FormBuilderTextField( + onChanged: (value) { + license = value; + }, + name: 'license_number', + decoration: normalTextFieldStyle( + "license number", + "license number"), + ), + ), + const SizedBox( + width: 12, + ), + //RATING + Flexible( + flex: 1, + child: FormBuilderTextField( + keyboardType: const TextInputType + .numberWithOptions(), + onChanged: (value) { + rating = value; + }, + name: 'rating', + decoration: normalTextFieldStyle( + 'rating %', 'rating'), + ), + ), + ], + ), + ), + const SizedBox( + height: 20, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + //EXAM DATE + Flexible( + flex: 1, + child: DateTimePicker( + use24HourFormat: false, + icon: const Icon( + Icons.date_range), + controller: examDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + timeHintText: + "Date of Examination/Conferment", + decoration: + normalTextFieldStyle( + "Exam date", "") + .copyWith( + prefixIcon: + const Icon( + Icons.date_range, + color: Colors.black87, + )), + initialValue: null, + )), + const SizedBox( + width: 12, + ), + //VALIDITY DATE + Flexible( flex: 1, child: DateTimePicker( - use24HourFormat: false, - icon: - const Icon(Icons.date_range), - controller: examDateController, + controller: + validityDateController, firstDate: DateTime(1970), lastDate: DateTime(2100), - timeHintText: - "Date of Examination/Conferment", decoration: normalTextFieldStyle( - "Exam date", "") + "Validity date", + "Validity date") .copyWith( prefixIcon: const Icon( Icons.date_range, color: Colors.black87, )), initialValue: null, - )), - const SizedBox( - width: 12, - ), - //VALIDITY DATE - Flexible( - flex: 1, - child: DateTimePicker( - controller: validityDateController, - firstDate: DateTime(1970), - lastDate: DateTime(2100), - decoration: normalTextFieldStyle( - "Validity date", - "Validity date") - .copyWith( - prefixIcon: const Icon( - Icons.date_range, - color: Colors.black87, - )), - initialValue: null, + ), ), - ), - ], + ], + ), ), - ), - const SizedBox( - height: 20, - ), - Text( - "Placement of Examination/Conferment", - style: Theme.of(context) - .textTheme - .displaySmall! - .copyWith( - fontSize: blockSizeVertical * 2), - ), - const SizedBox( - height: 12, - ), - //OVERSEAS ADDRESS SWITCH - Column( - children: [ - FormBuilderSwitch( - initialValue: overseas, - activeColor: second, - onChanged: (value) { - setState(() { - overseas = value; - }); - }, - decoration: - normalTextFieldStyle("", ''), - name: 'overseas', - title: const Text("Overseas Address?"), - ), - const SizedBox( - height: 20, - ), - //COUNTRY DROPDOWN - SizedBox( - child: overseas == true - ? FormBuilderDropdown( - initialValue: null, - validator: (value) => - value == null - ? 'required' - : null, - 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; - }, - ) - : Column( - children: [ - //REGION DROPDOWN - FormBuilderDropdown< - Region?>( - autovalidateMode: - AutovalidateMode - .onUserInteraction, - validator: (value) => - value == null - ? 'required' - : null, - onChanged: (Region? - region) async { - setState(() { - provinceCall = true; - }); - selectedRegion = region; - getProvinces(); - }, - initialValue: - selectedRegion, - 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: 20, - ), - //PROVINCE DROPDOWN - SizedBox( - height: 70, - child: ModalProgressHUD( - color: - Colors.transparent, - inAsyncCall: - provinceCall, - child: DropdownButtonFormField< - Province?>( - autovalidateMode: - AutovalidateMode - .onUserInteraction, + const SizedBox( + height: 20, + ), + Text( + "Placement of Examination/Conferment", + style: Theme.of(context) + .textTheme + .displaySmall! + .copyWith( + fontSize: blockSizeVertical * 2), + ), + const SizedBox( + height: 12, + ), + //OVERSEAS ADDRESS SWITCH + Column( + children: [ + FormBuilderSwitch( + initialValue: overseas, + activeColor: second, + onChanged: (value) { + setState(() { + overseas = value; + }); + }, + decoration: + normalTextFieldStyle("", ''), + name: 'overseas', + title: + const Text("Overseas Address?"), + ), + const SizedBox( + height: 20, + ), + //COUNTRY DROPDOWN + SizedBox( + child: overseas == true + ? FormBuilderDropdown( + initialValue: null, + validator: (value) => + value == null + ? 'required' + : null, + 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; + }, + ) + : Column( + children: [ + //REGION DROPDOWN + FormBuilderDropdown< + Region?>( + autovalidateMode: + AutovalidateMode + .onUserInteraction, + validator: (value) => + value == null + ? 'required' + : null, + onChanged: (Region? + region) async { + setState(() { + provinceCall = true; + }); + selectedRegion = + region; + getProvinces(); + }, + initialValue: + selectedRegion, + 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: 20, + ), + //PROVINCE DROPDOWN + SizedBox( + height: 70, + 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) { + 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")), + ), + ), + + // CityMunicipalities dropdown + SizedBox( + height: 70, + child: ModalProgressHUD( + color: Colors.white, + inAsyncCall: cityCall, + child: DropdownButtonFormField< + CityMunicipality>( validator: (value) => value == null ? 'required' : null, isExpanded: true, - value: - selectedProvince, onChanged: - (Province? - province) { - setState(() { - cityCall = true; - }); - selectedProvince = - province; - getCities(); + (CityMunicipality? + city) { + selectedMunicipality = + city; }, - items: provinces == + decoration: normalTextFieldStyle( + "Municipality*", + "Municipality"), + value: + selectedMunicipality, + items: citymuns == null ? [] - : provinces!.map< - DropdownMenuItem< - Province>>((Province - province) { + : citymuns!.map< + DropdownMenuItem< + CityMunicipality>>( + (CityMunicipality + c) { return DropdownMenuItem( value: - province, - child: - FittedBox( - child: - Text(province.description!), - )); + c, + child: Text( + c.description!)); }).toList(), - decoration: - normalTextFieldStyle( - "Province*", - "Province")), - ), - ), - - // CityMunicipalities dropdown - SizedBox( - height: 70, - child: ModalProgressHUD( - color: Colors.white, - inAsyncCall: cityCall, - child: - DropdownButtonFormField< - CityMunicipality>( - validator: (value) => - value == null - ? 'required' - : null, - isExpanded: true, - onChanged: - (CityMunicipality? - city) { - selectedMunicipality = - city; - }, - decoration: - normalTextFieldStyle( - "Municipality*", - "Municipality"), - value: - selectedMunicipality, - items: citymuns == - null - ? [] - : citymuns!.map< - DropdownMenuItem< - CityMunicipality>>( - (CityMunicipality - c) { - return DropdownMenuItem( - value: c, - child: Text( - c.description!)); - }).toList(), + ), ), ), - ), - const SizedBox( - height: 20, - ), - ], - )), - ], - ), + const SizedBox( + height: 20, + ), + ], + )), + ], + ), - const Expanded( - child: SizedBox(), - ), + const Expanded( + child: SizedBox(), + ), - SizedBox( - width: screenWidth, - height: 60, - child: ElevatedButton( - style: mainBtnStyle(primary, - Colors.transparent, second), - onPressed: () { - //rating - double? rate = rating == null - ? null - : double.parse(rating!); - //lisence - String? licenseNumber = license; - CityMunicipality? cityMunicipality = - selectedMunicipality; - DateTime? examDate = - examDateController.text.isEmpty - ? null - : DateTime.parse( - examDateController.text); - DateTime? validityDate = - validityDateController - .text.isEmpty - ? null - : DateTime.parse( - validityDateController - .text); + SizedBox( + width: screenWidth, + height: 60, + child: ElevatedButton( + style: mainBtnStyle(primary, + Colors.transparent, second), + onPressed: () { + //rating + double? rate = rating == null + ? null + : double.parse(rating!); + //lisence + String? licenseNumber = license; + CityMunicipality? cityMunicipality = + selectedMunicipality; + DateTime? examDate = + examDateController.text.isEmpty + ? null + : DateTime.parse( + examDateController + .text); + DateTime? validityDate = + validityDateController + .text.isEmpty + ? null + : DateTime.parse( + validityDateController + .text); - ExamAddress examAddress = ExamAddress( - barangay: null, - id: null, - addressCategory: null, - examAddressClass: null, - country: selectedCountry ?? - Country( - id: 175, - name: 'Philippines', - code: 'PH'), - cityMunicipality: - cityMunicipality); - EligibityCert eligibityCert = - EligibityCert( - id: null, - rating: rate, - examDate: examDate, - attachments: null, - eligibility: - selectedEligibility, - examAddress: examAddress, - validityDate: validityDate, - licenseNumber: licenseNumber, - overseas: overseas); - if (formKey.currentState! - .saveAndValidate()) { - context.read().add( - AddEligibility( - eligibityCert: - eligibityCert, - profileId: profileId!, - token: token!)); - } - // context.read().add(AddEligibility(eligibityCert: eligibityCert, profileId: profileId, token: token)) - }, - child: const Text(submit)), - ), - const SizedBox( - height: 20, - ), - ]), + ExamAddress examAddress = + ExamAddress( + barangay: null, + id: null, + addressCategory: null, + examAddressClass: null, + country: selectedCountry ?? + Country( + id: 175, + name: 'Philippines', + code: 'PH'), + cityMunicipality: + cityMunicipality); + EligibityCert eligibityCert = + EligibityCert( + id: null, + rating: rate, + examDate: examDate, + attachments: null, + eligibility: + selectedEligibility, + examAddress: examAddress, + validityDate: validityDate, + licenseNumber: + licenseNumber, + overseas: overseas); + if (formKey.currentState! + .saveAndValidate()) { + context + .read() + .add(AddEligibility( + eligibityCert: + eligibityCert, + profileId: profileId!, + token: token!)); + } + // context.read().add(AddEligibility(eligibityCert: eligibityCert, profileId: profileId, token: token)) + }, + child: const Text(submit)), + ), + const SizedBox( + height: 20, + ), + ]), + ), ), ), - ), - ); - } - return Container(); - }, - ); - } - return Container(); + ); + } + return Container(); + }, + ); + } + return Container(); }, ); } diff --git a/lib/screens/profile/components/loading_screen.dart b/lib/screens/profile/components/loading_screen.dart index e9ccf8b..f3078be 100644 --- a/lib/screens/profile/components/loading_screen.dart +++ b/lib/screens/profile/components/loading_screen.dart @@ -8,7 +8,7 @@ import 'package:fluttericon/modern_pictograms_icons.dart'; import 'package:unit2/screens/profile/components/main_menu.dart'; import 'package:unit2/screens/profile/components/submenu.dart'; import 'package:unit2/utils/global.dart'; - +import 'package:flutter_spinkit/flutter_spinkit.dart'; import '../../../theme-data.dart/colors.dart'; class LoadingScreen extends StatelessWidget { @@ -18,147 +18,143 @@ class LoadingScreen extends StatelessWidget { Widget build(BuildContext context) { return Stack( children: [ - + + Container( + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: ListView( + children: [ + const Text( + "View and Update your Profile Information", + textAlign: TextAlign.center, + ), + ExpandableGroup( + collapsedIcon: const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + Elusive.address_book, + color: primary, + ), + title: Text( + "Basic Information", + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + items: [ + subMenu(Icons.person, "Primary", () {}), + subMenu(Icons.home, "Home Addresses", () {}), + subMenu(Icons.contact_mail, "Identifications", () {}), + subMenu(Icons.contact_phone, "Contact Info", () {}), + subMenu(Icons.flag, "Citizenships", () {}), + ]), + const Divider(), + MainMenu( + icon: Elusive.group, + title: "Family", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.graduation_cap, + title: "Education", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: Icons.stars, + title: "Eligibility", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.shopping_bag, + title: "Work History", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: FontAwesome5.walking, + title: "Voluntary Work & Civic Services", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: Elusive.lightbulb, + title: "Learning & Development", + onTap: () {}, + ), + const Divider(), + MainMenu( + icon: Brandico.codepen, + title: "Personal References", + onTap: () {}, + ), + ExpandableGroup( + collapsedIcon: const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + Icons.info, + color: primary, + ), + title: Text( + "Other Information", + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + items: [ + subMenu(Icons.fitness_center, "Skills & Hobbies", () {}), + subMenu(FontAwesome5.certificate, + "Organization Memberships", () {}), + subMenu( + Entypo.doc_text, "Non-Academic Recognitions", () {}), + ]), + ExpandableGroup( + collapsedIcon: const Icon(Icons.keyboard_arrow_down), + expandedIcon: const Icon(Icons.keyboard_arrow_up), + header: const ListTile( + leading: Icon( + FontAwesome5.laptop_house, + color: primary, + ), + title: Text( + "Assets", + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + items: [ + subMenu(ModernPictograms.home, "Real Property Tax", () {}), + ]), + ], + ), + ), Container( - padding: const EdgeInsets.symmetric( - vertical: 12, horizontal: 12), - child: ListView( - children: [ - const Text( - "View and Update your Profile Information",textAlign: TextAlign.center,), - ExpandableGroup( - collapsedIcon: - const Icon(Icons.keyboard_arrow_down), - expandedIcon: - const Icon(Icons.keyboard_arrow_up), - header: const ListTile( - leading: Icon( - Elusive.address_book, - color: primary, - ), - title: Text( - "Basic Information", - style: - TextStyle(fontWeight: FontWeight.bold), - ), - ), - items: [ - subMenu(Icons.person, "Primary",(){}), - subMenu(Icons.home, "Home Addresses",(){}), - subMenu( - Icons.contact_mail, "Identifications",(){}), - subMenu(Icons.contact_phone, "Contact Info",(){}), - subMenu(Icons.flag, "Citizenships",(){}), - ]), - const Divider(), - MainMenu( - icon: Elusive.group, - title: "Family", - onTap: () { - - }, - ), - const Divider(), - MainMenu( - icon: FontAwesome5.graduation_cap, - title: "Education", - onTap: () { - - }, - ), - const Divider(), - MainMenu( - icon: Icons.stars, - title: "Eligibility", - onTap: () { - - }, - ), - const Divider(), - MainMenu( - icon: FontAwesome5.shopping_bag, - title: "Work History", - onTap: () { - - }, - ), - const Divider(), - MainMenu( - icon: FontAwesome5.walking, - title: "Voluntary Work & Civic Services", - onTap: () { - - }, - ), - const Divider(), - MainMenu( - icon: Elusive.lightbulb, - title: "Learning & Development", - onTap: () { - - }, - ), - const Divider(), - MainMenu( - icon: Brandico.codepen, - title: "Personal References", - onTap: () { - - }, - ), - ExpandableGroup( - collapsedIcon: - const Icon(Icons.keyboard_arrow_down), - expandedIcon: - const Icon(Icons.keyboard_arrow_up), - header: const ListTile( - leading: Icon( - Icons.info, - color: primary, - ), - title: Text( - "Other Information", - style: - TextStyle(fontWeight: FontWeight.bold), - ), - ), - items: [ - subMenu( - Icons.fitness_center, "Skills & Hobbies",(){}), - subMenu(FontAwesome5.certificate, - "Organization Memberships",(){}), - subMenu(Entypo.doc_text, - "Non-Academic Recognitions",(){}), - ]), - ExpandableGroup( - collapsedIcon: - const Icon(Icons.keyboard_arrow_down), - expandedIcon: - const Icon(Icons.keyboard_arrow_up), - header: const ListTile( - leading: Icon( - FontAwesome5.laptop_house, - color: primary, - ), - title: Text( - "Assets", - style: - TextStyle(fontWeight: FontWeight.bold), - ), - ), - items: [ - subMenu(ModernPictograms.home, - "Real Property Tax",(){}), - ]), - ], - ), - ), - Container( width: screenWidth, height: screenHeight, color: Colors.white70, ), + Center( + child: Container( + height: 150, + width: 150, + decoration:const BoxDecoration( + color: Colors.black87, + borderRadius: BorderRadius.all(Radius.circular(25)) + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const[ + SpinKitFadingCircle( + + color: Colors.white), + SizedBox(height: 10,), + Text("Loading Profile",textAlign: TextAlign.center, style: TextStyle(color: Colors.white),) + ], + ), + ), + ), ], ); } -} \ No newline at end of file +} diff --git a/lib/screens/profile/components/work_history/add_modal.dart b/lib/screens/profile/components/work_history/add_modal.dart new file mode 100644 index 0000000..522b6ac --- /dev/null +++ b/lib/screens/profile/components/work_history/add_modal.dart @@ -0,0 +1,680 @@ +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:fluttericon/font_awesome_icons.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:searchfield/searchfield.dart'; +import 'package:select2dot1/select2dot1.dart'; +import 'package:unit2/bloc/profile/profile_bloc.dart'; +import 'package:unit2/bloc/profile/workHistory/workHistory_bloc.dart'; +import 'package:unit2/bloc/user/user_bloc.dart'; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/agency_position.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/utils/validators.dart'; + +class AddWorkHistoryScreen extends StatefulWidget { + const AddWorkHistoryScreen({super.key}); + + @override + State createState() => _AddWorkHistoryScreenState(); +} + +class _AddWorkHistoryScreenState extends State { + final addAgencyController = TextEditingController(); + final addPositionController = TextEditingController(); + final toDateController = TextEditingController(); + final fromDateController = TextEditingController(); + final _formKey = GlobalKey(); + AgencyPosition? selectedPosition; + Agency? selectedAgency; + AppoinemtStatus? selectedStatus; + String? salary; + String? salaryGrade; + String? salaryGradeStep; + SingleItemCategoryModel selectedAgencyCategory = + const SingleItemCategoryModel(nameSingleItem: ""); + ScrollController agencyScrollController = ScrollController(); + bool showAgency = false; + bool showSalaryGradeAndSalaryStep = false; + bool? isPrivate = false; + bool showIsPrivateRadio = false; + bool currentlyEmployed = false; + final agencyFocusNode = FocusNode(); + final positionFocusNode = FocusNode(); + final appointmentStatusNode = FocusNode(); + @override + void dispose() { + addPositionController.dispose(); + addAgencyController.dispose(); + toDateController.dispose(); + fromDateController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + print("exc"); + return BlocBuilder( + builder: (context, state) { + if (state is UserLoggedIn) { + return BlocBuilder( + builder: (context, state) { + if (state is ProfileLoaded) { + return BlocConsumer( + listener: (context, state) { + if (state is AddWorkHistoryState) { + final progress = ProgressHUD.of(context); + progress!.dismiss(); + } + }, builder: (context, state) { + if (state is AddWorkHistoryState) { + return SingleChildScrollView( + child: SizedBox( + height: blockSizeVertical * 90, + child: FormBuilder( + key: _formKey, + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 25, horizontal: 18), + child: Column( + children: [ + ////POSITIONS + StatefulBuilder(builder: (context, setState) { + return SearchField( + suggestions: state.agencyPositions + .map((AgencyPosition position) => + SearchFieldListItem(position.title!, + item: position)) + .toList(), + focusNode: positionFocusNode, + searchInputDecoration: + normalTextFieldStyle("Position *", "") + .copyWith( + suffixIcon: const Icon( + Icons.arrow_drop_down)), + initialValue: selectedPosition != null + ? SearchFieldListItem( + selectedPosition!.title!, + item: selectedPosition) + : null, + onSuggestionTap: (position) { + setState(() { + selectedPosition = position.item; + positionFocusNode.unfocus(); + }); + }, + emptyWidget: Container( + color: Colors.white, + height: 100, + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 20, + ), + const Text("No result found"), + const SizedBox( + height: 10, + ), + TextButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext + context) { + return AlertDialog( + title: const Text( + "Add Position"), + content: SizedBox( + height: 130, + child: Column( + children: [ + TextFormField( + controller: + addPositionController, + decoration: + normalTextFieldStyle( + "", + ""), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: double + .infinity, + height: 50, + child: ElevatedButton( + style: mainBtnStyle(primary, Colors.transparent, second), + onPressed: () { + AgencyPosition + newAgencyPosition = + AgencyPosition(id: null, title: addPositionController.text.toUpperCase()); + + state.agencyPositions.insert( + 0, + newAgencyPosition); + selectedPosition = + newAgencyPosition; + addPositionController.text = + ""; + setState( + () {}); + Navigator.pop( + context); + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }, + child: + const Text("Add position")) + ]), + ), + validator: (position) { + if (position!.isEmpty) { + return "This field is required"; + } + return null; + }, + ); + }), + const SizedBox( + height: 12, + ), + ////APPOINTMENT STATUS' + SearchField( + suggestions: state.appointmentStatus + .map((AppoinemtStatus status) => + SearchFieldListItem(status.label, + item: status)) + .toList(), + focusNode: appointmentStatusNode, + validator: (value) { + if (value!.isEmpty) { + return "This field is required"; + } + return null; + }, + onSuggestionTap: (status) { + selectedStatus = status.item; + appointmentStatusNode.unfocus(); + }, + searchInputDecoration: normalTextFieldStyle( + "Appointment Status", "") + .copyWith( + suffixIcon: const Icon( + Icons.arrow_drop_down)), + ), + + const SizedBox( + height: 12, + ), + + ////AGENCY + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + SearchField( + itemHeight: 70, + focusNode: agencyFocusNode, + suggestions: state.agencies + .map((Agency agency) => + SearchFieldListItem( + agency.name!, + item: agency, + child: ListTile( + title: Text( + agency.name!, + overflow: TextOverflow + .ellipsis, + ), + subtitle: Text( + agency.privateEntity == + true + ? "Private" + : "Government"), + ))) + .toList(), + searchInputDecoration: + normalTextFieldStyle("Agency *", "") + .copyWith( + suffixIcon: const Icon( + Icons.arrow_drop_down)), + onSuggestionTap: (agency) { + setState(() { + selectedAgency = agency.item; + + if (selectedAgency!.privateEntity == + null) { + showIsPrivateRadio = true; + } else { + showIsPrivateRadio = false; + } + if (selectedAgency!.privateEntity == + true) { + showSalaryGradeAndSalaryStep = + false; + } + if (selectedAgency!.privateEntity == + false) { + showSalaryGradeAndSalaryStep = + true; + } + agencyFocusNode.unfocus(); + }); + }, + validator: (agency) { + if (agency!.isEmpty) { + return "This field is required"; + } + return null; + }, + emptyWidget: Container( + color: Colors.white, + height: 100, + child: Column( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + const SizedBox( + height: 20, + ), + const Text("No result found"), + const SizedBox( + height: 10, + ), + TextButton( + onPressed: () { + showDialog( + context: context, + builder: (BuildContext + context) { + return AlertDialog( + title: const Text( + "Add Position"), + content: SizedBox( + height: 130, + child: Column( + children: [ + TextFormField( + controller: + addAgencyController, + decoration: + normalTextFieldStyle( + "", + ""), + ), + const SizedBox( + height: + 12, + ), + SizedBox( + width: double + .infinity, + height: + 50, + child: ElevatedButton( + style: mainBtnStyle(primary, Colors.transparent, second), + onPressed: () { + setState(() { + Agency newAgency = Agency(id: null, name: addAgencyController.text.toUpperCase(), category: null, privateEntity: null); + + state.agencies.insert(0, newAgency); + selectedAgency = newAgency; + addAgencyController.text = ""; + showAgency = true; + + showIsPrivateRadio = true; + + Navigator.pop(context); + }); + }, + child: const Text("Add"))), + ], + ), + ), + ); + }); + }, + child: const Text( + "Add Agency")) + ]), + ), + ), + ////AGENCY CATEGORY + + SizedBox( + child: showAgency + ? Select2dot1( + selectEmptyInfoSettings: + const SelectEmptyInfoSettings( + text: + "Select Agency Category"), + + scrollController: + agencyScrollController, + selectDataController: + SelectDataController( + isMultiSelect: false, + data: state + .agencyCategory, + initSelected: [ + selectedAgencyCategory + ]), + onChanged: (value) { + print("sdasdsa"); + // print(value[0].nameSingleItem); + // setState(() { + // selectedAgencyCategory = + // value[0]; + // print(value[0].nameSingleItem); + // agencyFocusNode.unfocus(); + // }); + }, + ) + : const SizedBox(), + ), + + ////PRVIATE SECTOR + SizedBox( + child: showIsPrivateRadio + ? FormBuilderRadioGroup( + decoration: InputDecoration( + border: InputBorder.none, + label: Row( + children: [ + Text( + "Is this private sector? ", + style: Theme.of( + context) + .textTheme + .headlineSmall! + .copyWith( + fontSize: 24), + ), + const Icon(FontAwesome + .help_circled) + ], + ), + ), + + ////onvhange private sector + onChanged: (value) { + setState(() { + if (value.toString() == + "YES") { + isPrivate = true; + showSalaryGradeAndSalaryStep = + false; + } else { + isPrivate = false; + showSalaryGradeAndSalaryStep = + true; + } + agencyFocusNode.unfocus(); + }); + }, + + name: 'isPrivate', + validator: + FormBuilderValidators + .required(), + options: ["YES", "NO"] + .map((lang) => + FormBuilderFieldOption( + value: lang)) + .toList(growable: false), + ) + : const SizedBox()), + ////SALARY GRADE AND SALARY GRADE STEP + SizedBox( + child: showSalaryGradeAndSalaryStep + ? Column( + children: [ + Row( + children: [ + Flexible( + flex: 1, + child: + FormBuilderTextField( + name: + 'salary_grade', + keyboardType: + TextInputType + .number, + decoration: + normalTextFieldStyle( + "Salary Grade (SG)", + "0"), + onChanged: (value) { + salaryGrade = + value; + }, + ), + ), + const SizedBox( + width: 12, + ), + Flexible( + flex: 1, + child: + FormBuilderTextField( + name: 'salary_step', + keyboardType: + TextInputType + .number, + decoration: + normalTextFieldStyle( + "SG Step (SG)", + "0"), + onChanged: (value) { + setState(() { + salaryGradeStep = + value; + }); + }, + ), + ) + ], + ) + ], + ) + : null), + ], + ); + }), + const SizedBox( + height: 12, + ), + ////MONTHLY SALARY + FormBuilderTextField( + onChanged: (value) { + setState(() { + salary = value; + }); + }, + validator: numericRequired, + name: "salary", + decoration: normalTextFieldStyle( + "Monthly Salary *", "") + .copyWith(prefix: const Text("₱ ")), + ), + + const SizedBox( + height: 12, + ), + StatefulBuilder(builder: (context, setState) { + return Column( + children: [ + ////CURRENTLY EMPLOYED + FormBuilderSwitch( + initialValue: currentlyEmployed, + activeColor: second, + onChanged: (value) { + setState(() { + if (value == true) { + currentlyEmployed = true; + toDateController.text = "PRESENT"; + } else { + currentlyEmployed = false; + toDateController.text = ""; + } + }); + }, + decoration: + normalTextFieldStyle("", ''), + name: 'overseas', + title: + const Text("Currently Employed?"), + ), + const SizedBox( + height: 12, + ), + SizedBox( + width: screenWidth, + child: Row( + children: [ + //// FROM DATE + Flexible( + flex: 1, + child: DateTimePicker( + validator: (value) { + if (value == null) { + return "This field is required"; + } + return null; + }, + 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: currentlyEmployed + ? TextFormField( + enabled: false, + initialValue: "PRESENT", + style: const TextStyle( + color: + Colors.black45), + decoration: + normalTextFieldStyle( + "", "") + .copyWith(), + ) + : DateTimePicker( + validator: (val) { + print(val); + return null; + }, + controller: + toDateController, + firstDate: DateTime(1970), + lastDate: DateTime(2100), + decoration: normalTextFieldStyle( + "To *", "To *") + .copyWith( + prefixIcon: + const Icon( + Icons + .date_range, + color: Colors + .black87, + ), + prefixText: + currentlyEmployed + ? "PRESENT" + : ""), + initialValue: null, + ), + ), + ], + ), + ), + ], + ); + }), + const Expanded(child: SizedBox()), + ////SUBMIT BUTTON + SizedBox( + width: double.infinity, + height: 60, + child: ElevatedButton( + style: mainBtnStyle( + primary, Colors.transparent, second), + onPressed: () { + print(selectedPosition?.title); + print(selectedStatus?.label); + print(selectedAgency?.name); + print(salary); + print(fromDateController.text); + print(toDateController.text); + print(isPrivate); + print(salaryGrade); + print(salaryGradeStep); + if (_formKey.currentState! + .validate()) {} + }, + child: const Text(submit)), + ), + const SizedBox( + height: 20, + ), + ], + ), + ), + ), + ), + ); + } + return Container(); + }); + } + return Container(); + }, + ); + } + return const Center( + child: Text("Add Work History"), + ); + }, + ); + } +} diff --git a/lib/screens/profile/components/work_history_screen.dart b/lib/screens/profile/components/work_history_screen.dart index 87666fa..580d33a 100644 --- a/lib/screens/profile/components/work_history_screen.dart +++ b/lib/screens/profile/components/work_history_screen.dart @@ -1,11 +1,13 @@ +import 'package:app_popup_menu/app_popup_menu.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:fluttericon/font_awesome_icons.dart'; import 'package:intl/intl.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart'; -import 'package:unit2/model/profile/work_history.dart'; +import 'package:unit2/screens/profile/components/work_history/add_modal.dart'; import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/text_container.dart'; @@ -14,6 +16,7 @@ import 'package:unit2/widgets/empty_data.dart'; import 'package:unit2/widgets/error_state.dart'; import '../../../bloc/profile/workHistory/workHistory_bloc.dart'; +import '../../../utils/alerts.dart'; import '../../../utils/global.dart'; class WorkHistoryScreen extends StatelessWidget { @@ -22,24 +25,32 @@ class WorkHistoryScreen extends StatelessWidget { @override Widget build(BuildContext context) { DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); + String? token; + int profileId; return Scaffold( appBar: AppBar( title: const Text(workHistoryScreenTitle), backgroundColor: primary, centerTitle: true, - actions: [AddLeading(onPressed: () {})], + actions: [ + AddLeading(onPressed: () { + context.read().add(ShowAddWorkHistoryForm()); + }) + ], ), body: //UserBloc ProgressHUD( padding: const EdgeInsets.all(24), - backgroundColor: Colors.black87, + backgroundColor: Colors.black87, indicatorWidget: const SpinKitFadingCircle( color: Colors.white, ), 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) { //ProfileBloc @@ -51,10 +62,32 @@ class WorkHistoryScreen extends StatelessWidget { final progress = ProgressHUD.of(context); progress!.showWithText("Please wait..."); } - if (state is WorkHistoryLoaded || state is WorkHistoryErrorState) { + if (state is WorkHistoryLoaded || + state is WorkHistoryErrorState || + state is AddWorkHistoryState) { final progress = ProgressHUD.of(context); progress!.dismiss(); } + //DELETED STATE + if (state is DeletedState) { + if (state.success) { + successAlert(context, "Deletion Successfull", + "Work has been deleted successfully", () { + Navigator.of(context).pop(); + context.read().add( + LoadWorkHistories( + workHistories: state.workHistories)); + }); + } else { + errorAlert(context, "Deletion Failed", + "Error deleting Work History", () { + Navigator.of(context).pop(); + context.read().add( + LoadWorkHistories( + workHistories: state.workHistories)); + }); + } + } }, builder: (context, state) { if (state is WorkHistoryLoaded) { @@ -77,8 +110,9 @@ class WorkHistoryScreen extends StatelessWidget { state.workExperiences[index].toDate == null ? present.toUpperCase() - : dteFormat2.format( - state.workExperiences[index].toDate!); + : dteFormat2.format(state + .workExperiences[index] + .toDate!); return Column( children: [ Container( @@ -127,12 +161,55 @@ class WorkHistoryScreen extends StatelessWidget { ), ], )), - IconButton( - onPressed: () {}, - icon: const Icon( - Icons.more_vert, - color: Colors.grey, - )) + AppPopupMenu( + offset: const Offset(-10, -10), + elevation: 3, + onSelected: (value) { + final progress = + ProgressHUD.of(context); + progress! + .showWithText("Loading..."); + ////delete workhistory-= = = = = = = = =>> + if (value == 2) { + confirmAlert(context, () { + BlocProvider.of( + context) + .add(DeleteWorkHistory( + profileId: + profileId, + token: token!, + workHistory: state + .workExperiences[ + index], + workHistories: state + .workExperiences)); + }, "Delete?", + "Confirm Delete?"); + } + if (value == 1) { + ////edit eligibilty-= = = = = = = = =>> + } + }, + 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", + ) ]), ), const SizedBox( @@ -147,6 +224,9 @@ class WorkHistoryScreen extends StatelessWidget { "You don't have any work experience added. Please click + to add"); } } + if (state is AddWorkHistoryState) { + return const AddWorkHistoryScreen(); + } if (state is WorkHistoryErrorState) { return SomethingWentWrong( message: state.message, onpressed: () {}); @@ -165,3 +245,22 @@ class WorkHistoryScreen 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/profile.dart b/lib/screens/profile/profile.dart index 7d444dc..da19d56 100644 --- a/lib/screens/profile/profile.dart +++ b/lib/screens/profile/profile.dart @@ -43,18 +43,14 @@ import '../../bloc/user/user_bloc.dart'; import 'components/main_menu.dart'; import 'components/submenu.dart'; -class ProfileInfo extends StatefulWidget { +class ProfileInfo extends StatelessWidget { const ProfileInfo({super.key}); - @override - State createState() => _ProfileInfoState(); -} - -class _ProfileInfoState extends State { - int? profileId; - String? token; @override Widget build(BuildContext context) { + int? profileId; + + String? token; return Scaffold( appBar: AppBar( backgroundColor: primary, @@ -62,6 +58,7 @@ class _ProfileInfoState extends State { title: const Text('Profile'), ), body: ProgressHUD( + padding: const EdgeInsets.all(24), backgroundColor: Colors.black87, indicatorWidget: const SpinKitFadingCircle(color: Colors.white), child: BlocBuilder(builder: (context, state) { @@ -69,12 +66,10 @@ class _ProfileInfoState extends State { profileId = state.userData!.user!.login!.user!.profileId; token = state.userData!.user!.login!.token!; return BlocConsumer( - listener: (context, state) { + listener: (context, state,){ if (state is ProfileLoading) { final progress = ProgressHUD.of(context); - progress?.showWithText( - 'Loading Profile', - ); + progress!.showWithText("Please wait..."); } if (state is ProfileLoaded || state is ProfileErrorState) { final progress = ProgressHUD.of(context); @@ -147,15 +142,18 @@ class _ProfileInfoState extends State { }), subMenu(Icons.contact_phone, "Contact Info", () { - Navigator.push(context, MaterialPageRoute( - builder: (BuildContext context) { - return BlocProvider( - create: (context) => ContactBloc() - ..add(GetContacts( - contactInformations: state.profileInformation.basicInfo.contactInformation)), - child: ContactInformationScreen(), - ); - })); + Navigator.push(context, MaterialPageRoute( + builder: (BuildContext context) { + return BlocProvider( + create: (context) => ContactBloc() + ..add(GetContacts( + contactInformations: state + .profileInformation + .basicInfo + .contactInformation)), + child: const ContactInformationScreen(), + ); + })); }), subMenu(Icons.flag, "Citizenships", () { Navigator.push(context, MaterialPageRoute( @@ -361,6 +359,7 @@ class _ProfileInfoState extends State { ); } if (state is ProfileLoading) { + return const LoadingScreen(); } if (state is ProfileErrorState) { diff --git a/lib/screens/unit2/homepage.dart/components/dashboard.dart b/lib/screens/unit2/homepage.dart/components/dashboard.dart index f46b533..eed381c 100644 --- a/lib/screens/unit2/homepage.dart/components/dashboard.dart +++ b/lib/screens/unit2/homepage.dart/components/dashboard.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:unit2/screens/unit2/homepage.dart/module-screen.dart'; -import 'package:unit2/theme-data.dart/box_shadow.dart'; import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/utils/global.dart'; @@ -25,11 +24,11 @@ class DashBoard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - roles[index].name, + roles[index].name.toUpperCase(), style: Theme.of(context) .textTheme .labelLarge! - .copyWith(fontSize: 14), + .copyWith(fontSize: 12), ), const SizedBox( @@ -38,38 +37,51 @@ class DashBoard extends StatelessWidget { GridView.count( shrinkWrap: true, crossAxisCount: 4, - crossAxisSpacing: 5, - mainAxisSpacing: 2, + crossAxisSpacing: 8, + mainAxisSpacing: 10, physics: const BouncingScrollPhysics(), padding: const EdgeInsets.symmetric( vertical: 5, horizontal: 5), children: roles[index].roles.map((role) { return Container( - padding: const EdgeInsets.all(8), - decoration:box1(), + padding: const EdgeInsetsDirectional.fromSTEB(8,5,8,13), + alignment: Alignment.center, + + decoration:const BoxDecoration( + color: Colors.white, + boxShadow:[ BoxShadow(color: Colors.black12,spreadRadius: 2,blurRadius: 3)], + borderRadius: BorderRadius.all(Radius.circular(8)) + ), child: GestureDetector( onTap: () { }, - child: Column(children: [ - Icon( - role.icon, - size: 24, - color: second, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Icon( + + role.icon, + size: 20, + weight: 100, + grade: 100, + color:second, + ), ), const SizedBox( height: 5, ), - Expanded( - child: Text( - role.role.name!, - textAlign: TextAlign.center, - style: Theme.of(context) - .textTheme - .labelLarge! - .copyWith( - fontSize: blockSizeVertical*1.1, - fontWeight: FontWeight.bold), - ), + Text( + role.role.name!.toLowerCase() == "establishment point-person"?"Est. point-person": + role.role.name!, + textAlign: TextAlign.center, + style: Theme.of(context) + .textTheme + .labelLarge! + .copyWith( + fontSize: blockSizeVertical*1.1, + fontWeight: FontWeight.bold), ), ]), ), diff --git a/lib/sevices/profile/work_history_services.dart b/lib/sevices/profile/work_history_services.dart index b62f526..cb93409 100644 --- a/lib/sevices/profile/work_history_services.dart +++ b/lib/sevices/profile/work_history_services.dart @@ -2,38 +2,165 @@ import 'dart:convert'; import 'package:unit2/model/profile/work_history.dart'; - import 'package:http/http.dart' as http; +import 'package:unit2/model/utils/agency.dart'; +import 'package:unit2/model/utils/agency_position.dart'; +import 'package:unit2/model/utils/category.dart'; import 'package:unit2/utils/request.dart'; import '../../utils/urls.dart'; -class WorkHistoryService{ + +class WorkHistoryService { static final WorkHistoryService _instance = WorkHistoryService(); static WorkHistoryService get instance => _instance; - Future > getWorkExperiences( int profileId, String token)async{ - List workExperiences = []; - String authToken = "Token $token"; - Map headers = { + Future> getWorkExperiences( + int profileId, String token) async { + List workExperiences = []; + String authToken = "Token $token"; + Map headers = { 'Content-Type': 'application/json; charset=UTF-8', 'Authorization': authToken }; - String path= Url.instance.getWorkHistories()+profileId.toString(); - // try{ - http.Response response =await Request.instance.getRequest(path: path, headers: headers, param: {}); - if(response.statusCode == 200){ + String path = Url.instance.getWorkHistories() + profileId.toString(); + 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 workHistory){ + if (data['data'] != null) { + data['data'].forEach((var workHistory) { workExperiences.add(WorkHistory.fromJson(workHistory)); }); } - } - // }catch(e){ - // throw e.toString(); - // } + } catch (e) { + throw e.toString(); + } return workExperiences; - } -} \ No newline at end of file + + Future> getAgecies() async { + List agencies = []; + String path = Url.instance.getAgencies(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + 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 agency) { + Agency newAgency = Agency.fromJson(agency); + agencies.add(newAgency); + }); + } + } + } catch (e) { + throw e.toString(); + } + return agencies; + } + + Future delete( + {required int profileId, + required String token, + required WorkHistory work}) async { + bool? success; + Map params = {"force_mode": "true"}; + String authToken = "Token $token"; + String path = "${Url.instance.deleteWorkHistory()}$profileId/"; + Map body = { + "id": work.id, + "position_id": work.position!.id, + "agency_id": work.agency!.id, + "from_date": work.fromDate?.toString(), + "to_date": work.toDate?.toString(), + "monthly_salary": work.monthlySalary, + "appointment_status": work.appointmentStatus, + "salary_step": work.sgStep, + "salary_grade": work.salaryGrade, + }; + 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> agencyCategory() async { + List agencyCategory = []; + String path = Url.instance.getAgencyCategory(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var agency) { + Category category = Category.fromJson(agency); + agencyCategory.add(category); + }); + } + } + } catch (e) { + throw e.toString(); + } + return agencyCategory; + } + + Future> getAgencyPosition() async { + List agencyPositions = []; + String path = Url.instance.getPositions(); + Map headers = { + 'Content-Type': 'application/json; charset=UTF-8', + }; + try { + http.Response response = await Request.instance + .getRequest(param: {}, path: path, headers: headers); + if (response.statusCode == 200) { + Map data = jsonDecode(response.body); + if (data['data'] != null) { + data['data'].forEach((var agencyPosition) { + AgencyPosition position = AgencyPosition.fromJson(agencyPosition); + agencyPositions.add(position); + }); + } + } + } catch (e) { + throw (e.toString()); + } + return agencyPositions; + } + + List getAppointmentStatusList() { + return [ + AppoinemtStatus(value: "Appointed", label: "Appointed"), + AppoinemtStatus(value: "Casual", label: "Casual"), + AppoinemtStatus( + value: "Contact of Service", label: "Contract of Service"), + AppoinemtStatus(value: "Coterminous", label: "Coterminous"), + AppoinemtStatus(value: "Elected", label: "Elected"), + AppoinemtStatus(value: "Job Order", label: "Permanent"), + AppoinemtStatus(value: "Elected", label: "Elected"), + ]; + } +} diff --git a/lib/utils/custom_dropdown_button.dart b/lib/utils/custom_dropdown_button.dart new file mode 100644 index 0000000..11bf81d --- /dev/null +++ b/lib/utils/custom_dropdown_button.dart @@ -0,0 +1,149 @@ +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; + +class CustomDropdownButton2 extends StatelessWidget { + final String hint; + final String? value; + final List dropdownItems; + final ValueChanged? onChanged; + final DropdownButtonBuilder? selectedItemBuilder; + final Alignment? hintAlignment; + final Alignment? valueAlignment; + final double? buttonHeight, buttonWidth; + final EdgeInsetsGeometry? buttonPadding; + final BoxDecoration? buttonDecoration; + final int? buttonElevation; + final Widget? icon; + final double? iconSize; + final Color? iconEnabledColor; + final Color? iconDisabledColor; + final double? itemHeight; + final EdgeInsetsGeometry? itemPadding; + final double? dropdownHeight, dropdownWidth; + final EdgeInsetsGeometry? dropdownPadding; + final BoxDecoration? dropdownDecoration; + final int? dropdownElevation; + final Radius? scrollbarRadius; + final double? scrollbarThickness; + final bool? scrollbarAlwaysShow; + final Offset offset; + + const CustomDropdownButton2({ + required this.hint, + required this.value, + required this.dropdownItems, + required this.onChanged, + this.selectedItemBuilder, + this.hintAlignment, + this.valueAlignment, + this.buttonHeight, + this.buttonWidth, + this.buttonPadding, + this.buttonDecoration, + this.buttonElevation, + this.icon, + this.iconSize, + this.iconEnabledColor, + this.iconDisabledColor, + this.itemHeight, + this.itemPadding, + this.dropdownHeight, + this.dropdownWidth, + this.dropdownPadding, + this.dropdownDecoration, + this.dropdownElevation, + this.scrollbarRadius, + this.scrollbarThickness, + this.scrollbarAlwaysShow, + this.offset = const Offset(0, 0), + Key? key, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return DropdownButtonHideUnderline( + child: DropdownButton2( + //To avoid long text overflowing. + isExpanded: true, + hint: Container( + alignment: hintAlignment, + child: Text( + hint, + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).hintColor, + ), + ), + ), + value: value, + items: dropdownItems + .map((item) => DropdownMenuItem( + value: item, + child: Container( + alignment: valueAlignment, + child: Text( + item, + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: const TextStyle( + fontSize: 14, + ), + ), + ), + )) + .toList(), + onChanged: onChanged, + selectedItemBuilder: selectedItemBuilder, + buttonStyleData: ButtonStyleData( + height: buttonHeight ?? 40, + width: buttonWidth ?? 140, + padding: buttonPadding ?? const EdgeInsets.only(left: 14, right: 14), + decoration: buttonDecoration ?? + BoxDecoration( + borderRadius: BorderRadius.circular(14), + border: Border.all( + color: Colors.black45, + ), + ), + elevation: buttonElevation, + ), + iconStyleData: IconStyleData( + icon: icon ?? const Icon(Icons.arrow_forward_ios_outlined), + iconSize: iconSize ?? 12, + iconEnabledColor: iconEnabledColor, + iconDisabledColor: iconDisabledColor, + ), + dropdownStyleData: DropdownStyleData( + //Max height for the dropdown menu & becoming scrollable if there are more items. If you pass Null it will take max height possible for the items. + maxHeight: dropdownHeight ?? 200, + width: dropdownWidth ?? 140, + padding: dropdownPadding, + decoration: dropdownDecoration ?? + BoxDecoration( + borderRadius: BorderRadius.circular(14), + ), + elevation: dropdownElevation ?? 8, + //Null or Offset(0, 0) will open just under the button. You can edit as you want. + offset: offset, + //Default is false to show menu below button + isOverButton: false, + scrollbarTheme: ScrollbarThemeData( + radius: scrollbarRadius ?? const Radius.circular(40), + thickness: scrollbarThickness != null + ? MaterialStateProperty.all(scrollbarThickness!) + : null, + thumbVisibility: scrollbarAlwaysShow != null + ? MaterialStateProperty.all(scrollbarAlwaysShow!) + : null, + ), + ), + menuItemStyleData: MenuItemStyleData( + height: itemHeight ?? 40, + padding: itemPadding ?? const EdgeInsets.only(left: 14, right: 14), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/utils/urls.dart b/lib/utils/urls.dart index 79444f4..fb0fd90 100644 --- a/lib/utils/urls.dart +++ b/lib/utils/urls.dart @@ -3,7 +3,7 @@ class Url { static Url get instance => _instance; String host() { - // // return '192.168.10.221:3003'; + // // // return '192.168.10.221:3003'; // return 'agusandelnorte.gov.ph'; // return "192.168.10.219:3000"; return "devweb.agusandelnorte.gov.ph"; @@ -45,6 +45,18 @@ String updateEligibility(){ String getWorkHistories(){ return "/api/jobnet_app/profile/pds/work/"; } +String getPositions(){ + return "/api/jobnet_app/positions/"; +} +String getAgencies(){ + return "/api/jobnet_app/agencies/"; +} +String getAgencyCategory(){ + return "api/jobnet_app/agency_categories/"; +} +String deleteWorkHistory(){ + return "/api/jobnet_app/profile/pds/work/"; +} ////educational background paths String getEducationalBackgrounds(){ diff --git a/lib/utils/validators.dart b/lib/utils/validators.dart index 52f4c1f..fb4ab79 100644 --- a/lib/utils/validators.dart +++ b/lib/utils/validators.dart @@ -6,6 +6,10 @@ final mobileNumberValidator = FormBuilderValidators.compose([ FormBuilderValidators.required(errorText: mobileNumberRequired), FormBuilderValidators.numeric(errorText: numericValidator) ]); +final numericRequired = FormBuilderValidators.compose([ + FormBuilderValidators.required(errorText: "This field is required"), + FormBuilderValidators.numeric(errorText: numericValidator) +]); final registerPasswordValidator = FormBuilderValidators.compose([ FormBuilderValidators.required(errorText: "Password is required"), diff --git a/pubspec.lock b/pubspec.lock index 5132e7a..f3b631c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -201,6 +201,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.6" + dropdown_button2: + dependency: "direct main" + description: + name: dropdown_button2 + sha256: "4458d81bfd24207f3d58f66f78097064e02f810f94cf1bc80bf20fe7685ebc80" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + dropdown_plus: + dependency: "direct main" + description: + name: dropdown_plus + sha256: "707c364066dcfcd2f5b672116d5adee8e3454ede3ff6fc34f5b351bfbbfbecbe" + url: "https://pub.dev" + source: hosted + version: "0.0.9" easy_app_installer: dependency: "direct main" description: @@ -310,6 +326,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + flutter_dropdown_search: + dependency: "direct main" + description: + name: flutter_dropdown_search + sha256: ead6f0e5dc67ae20822b211d26e617efe1d8922159de9b07a8a2168805b541d1 + url: "https://pub.dev" + source: hosted + version: "0.0.2" flutter_form_builder: dependency: "direct main" description: @@ -773,6 +797,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.3" + search_choices: + dependency: "direct main" + description: + name: search_choices + sha256: "4c379407ea642613669f788ec9b41cfb156f55800e8f69c727478c37db025c47" + url: "https://pub.dev" + source: hosted + version: "2.2.5" + searchfield: + dependency: "direct main" + description: + name: searchfield + sha256: deb363c95b9e64ea9ffd1a3b69926b0fe0344daedab872fc42014755a8199de9 + url: "https://pub.dev" + source: hosted + version: "0.7.5" + select2dot1: + dependency: "direct main" + description: + name: select2dot1 + sha256: bce3cef060d48b9c728924aa76f2fbcefb887fe7219e370391696902739cb2ed + url: "https://pub.dev" + source: hosted + version: "1.0.2" shared_preferences: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index acba4dd..3b0fda0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -70,6 +70,13 @@ dependencies: badges: ^3.0.2 app_popup_menu: ^1.0.0 modal_progress_hud_nsn: ^0.3.0 + search_choices: ^2.2.5 + dropdown_button2: ^2.0.0 + flutter_dropdown_search: ^0.0.2 + select2dot1: ^1.0.2 + dropdown_plus: ^0.0.9 + searchfield: ^0.7.5 + dev_dependencies: flutter_test: