implemented delete,update, and edit in work history screen

feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
PGAN-MIS 2023-03-21 09:37:55 +08:00
parent e087eb147d
commit f1ed33a6c0
16 changed files with 1495 additions and 462 deletions

View File

@ -22,8 +22,6 @@ PODS:
- FlutterMacOS
- permission_handler_apple (9.0.4):
- Flutter
- search_choices (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
@ -42,7 +40,6 @@ 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`)
@ -70,8 +67,6 @@ 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:
@ -88,7 +83,6 @@ 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

View File

@ -1,9 +1,10 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:select2dot1/select2dot1.dart';
import 'package:unit2/bloc/profile/eligibility/eligibility_bloc.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/model/utils/position.dart';
import 'package:unit2/sevices/profile/work_history_services.dart';
import '../../../model/utils/category.dart';
@ -13,11 +14,12 @@ part 'workHistory_state.dart';
class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
List<WorkHistory> workExperiences = [];
List<AgencyPosition> agencyPositions = [];
List<Position> agencyPositions = [];
List<Agency> agencies = [];
List<AppoinemtStatus> appointmentStatus = [];
List<Category> agencyCategory = [];
WorkHistoryBloc() : super(EducationInitial()) {
////GET WORK HISTORIES
on<GetWorkHistories>((event, emit) async {
emit(WorkHistoryLoadingState());
try {
@ -29,196 +31,145 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
emit(WorkHistoryErrorState(message: e.toString()));
}
});
on<LoadWorkHistories>((event,emit){
///// LOAD WORK HISTORIES
on<LoadWorkHistories>((event, emit) {
emit(WorkHistoryLoadingState());
workExperiences = event.workHistories;
emit(WorkHistoryLoaded(workExperiences: workExperiences));
});
on<DeleteWorkHistory>((event,emit)async{
on<DeleteWorkHistory>((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);
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<WorkHistory> newWorkHistories = event.workHistories;
emit(DeletedState(success: success,workHistories: newWorkHistories));
}else{
emit(DeletedState(success: success, workHistories: event.workHistories));
emit(DeletedState(success: success, workHistories: newWorkHistories));
} else {
emit(DeletedState(
success: success, workHistories: event.workHistories));
}
}catch(e){
} catch (e) {
emit(WorkHistoryErrorState(message: e.toString()));
}
});
//// ADD WORK HISTORIES
on<AddWorkHostory>((event, emit) async {
try {
emit(WorkHistoryLoadingState());
Map<dynamic, dynamic> status = await WorkHistoryService.instance.add(
isPrivate: event.isPrivate,
workHistory: event.workHistory,
token: event.token,
profileId: event.profileId);
if (status['success']) {
WorkHistory workHistory = WorkHistory.fromJson(status['data']);
workExperiences.add(workHistory);
emit(WorkHistoryAddedState(
response: status, workExperiences: workExperiences));
} else {
emit(WorkHistoryAddedState(
response: status, workExperiences: workExperiences));
}
} catch (e) {
emit(WorkHistoryErrorState(message: e.toString()));
}
});
////UPDATE WORK HISTORY
on<UpdateWorkHistory>((event, emit)async{
emit(WorkHistoryLoadingState());
// try{
Map<dynamic,dynamic> status = await WorkHistoryService.instance.update(oldWorkHistory: event.oldWorkHistory, newWorkHistory: event.workHistory, token: event.token, profileId: event.profileId);
if(status['success']){
WorkHistory workHistory = WorkHistory.fromJson(status['data']);
workExperiences.removeWhere((WorkHistory work) {
return work.id == event.oldWorkHistory.id;
});
workExperiences.add(workHistory);
emit(WorkHistoryEditedState(workExperiences: workExperiences,response: status));
}else{
emit(WorkHistoryEditedState(response: status, workExperiences: workExperiences));
}
// }catch(e){
// emit(WorkHistoryErrorState(message: e.toString()));
// }
});
////SHOW EDIT WORK HISTORIES
on<ShowEditWorkHistoryForm>((event, emit) async {
try {
/////POSITIONS------------------------------------------
if (agencyPositions.isEmpty) {
List<Position> positions =
await WorkHistoryService.instance.getAgencyPosition();
agencyPositions = positions;
}
/////AGENCIES------------------------------------------
if (agencies.isEmpty) {
List<Agency> newAgencies =
await WorkHistoryService.instance.getAgecies();
agencies = newAgencies;
}
/////Category Agency------------------------------------------
if (agencyCategory.isEmpty) {
List<Category> categoryAgencies =
await WorkHistoryService.instance.agencyCategory();
agencyCategory = categoryAgencies;
}
/////////-------------------------------------
if (appointmentStatus.isEmpty) {
List<AppoinemtStatus> status =
WorkHistoryService.instance.getAppointmentStatusList();
appointmentStatus = status;
}
emit(EditWorkHistoryState(
workHistory: event.workHistory,
agencyPositions: agencyPositions,
appointmentStatus: appointmentStatus,
agencyCategory: agencyCategory,
agencies: agencies));
} catch (e) {
emit(WorkHistoryErrorState(message: e.toString()));
}
});
////SHOW ADD FORM WORK HISTORIES
on<ShowAddWorkHistoryForm>((event, emit) async {
emit(WorkHistoryLoadingState());
try {
/////POSITIONS------------------------------------------
List<AgencyPosition> positions =
List<Position> positions =
await WorkHistoryService.instance.getAgencyPosition();
agencyPositions = positions;
/////AGENCIES------------------------------------------
List<Agency> newAgencies =
await WorkHistoryService.instance.getAgecies();
agencies = newAgencies;
agencies = newAgencies;
/////Category Agency------------------------------------------
/////Category Agency------------------------------------------
List<Category> categoryAgencies =
await WorkHistoryService.instance.agencyCategory();
agencyCategory = categoryAgencies;
/////////-------------------------------------
List<AppoinemtStatus> status = WorkHistoryService.instance.getAppointmentStatusList();
appointmentStatus = status;
List<AppoinemtStatus> status =
WorkHistoryService.instance.getAppointmentStatusList();
appointmentStatus = status;
List<SingleItemCategoryModel> agricultureList =[];
List<SingleItemCategoryModel> businessInfoList =[];
List<SingleItemCategoryModel> constructionList =[];
List<SingleItemCategoryModel> educationList =[];
List<SingleItemCategoryModel> financeList =[];
List<SingleItemCategoryModel> foodList =[];
List<SingleItemCategoryModel> gamingList =[];
List<SingleItemCategoryModel> healthList =[];
List<SingleItemCategoryModel> motorList =[];
List<SingleItemCategoryModel> naturalList =[];
List<SingleItemCategoryModel> otherList =[];
List<SingleItemCategoryModel> personalList =[];
List<SingleItemCategoryModel> publicList =[];
List<SingleItemCategoryModel> realStateList =[];
List<SingleItemCategoryModel> safetyList =[];
List<SingleItemCategoryModel> 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<SingleCategoryModel> agencyCategoryDropdownData = [
agricultureForestryWildlife,
businessInformation,
constructionUtilitiesContracting,
education,
financeInsurance,
foodHospitality,
gaming,
healthServices,
motorVehicle,
naturalResourcesEnvironmental,
others,
personalServices,
publicGovernance,
realStateHousing,
safetySecurityLegal,
transportation,
];
emit(AddWorkHistoryState(
agencyPositions:agencyPositions,
agencyPositions: agencyPositions,
appointmentStatus: appointmentStatus,
agencyCategory: agencyCategoryDropdownData,
agencyCategory: agencyCategory,
agencies: agencies));
} catch (e) {
emit(WorkHistoryErrorState(message: e.toString()));

View File

@ -26,6 +26,13 @@ class LoadWorkHistories extends WorkHistorytEvent{
class ShowAddWorkHistoryForm extends WorkHistorytEvent{
}
class ShowEditWorkHistoryForm extends WorkHistorytEvent{
final WorkHistory workHistory;
const ShowEditWorkHistoryForm({required this.workHistory});
@override
List<Object> get props => [workHistory];
}
class DeleteWorkHistory extends WorkHistorytEvent{
final List<WorkHistory> workHistories;
@ -37,4 +44,24 @@ class DeleteWorkHistory extends WorkHistorytEvent{
List<Object> get props => [token, profileId,workHistory, workHistories];
}
class UpdateWorkHistory extends WorkHistorytEvent{
final WorkHistory workHistory;
final WorkHistory oldWorkHistory;
final String profileId;
final String token;
const UpdateWorkHistory({required this.oldWorkHistory, required this.profileId, required this.token, required this.workHistory});
@override
List<Object> get props => [profileId,token,workHistory,oldWorkHistory];
}
class AddWorkHostory extends WorkHistorytEvent{
final WorkHistory workHistory;
final bool isPrivate;
final int profileId;
final String token;
const AddWorkHostory({required this.workHistory, required this.isPrivate, required this.profileId, required this.token});
@override
List<Object> get props => [workHistory,profileId,token,isPrivate];
}

View File

@ -30,9 +30,9 @@ class WorkHistoryErrorState extends WorkHistoryState{
class AddWorkHistoryState extends WorkHistoryState{
final List<AgencyPosition> agencyPositions;
final List<Position> agencyPositions;
final List<Agency> agencies;
final List<SingleCategoryModel> agencyCategory;
final List<Category> agencyCategory;
final List<AppoinemtStatus> appointmentStatus;
const AddWorkHistoryState({required this.agencyPositions, required this.appointmentStatus,required this.agencies,required this.agencyCategory});
@ -41,6 +41,17 @@ class AddWorkHistoryState extends WorkHistoryState{
}
class EditWorkHistoryState extends WorkHistoryState{
final WorkHistory workHistory;
final List<Position> agencyPositions;
final List<Agency> agencies;
final List<Category> agencyCategory;
final List<AppoinemtStatus> appointmentStatus;
const EditWorkHistoryState({required this.workHistory, required this.agencies,required this.agencyCategory, required this.agencyPositions, required this.appointmentStatus});
@override
List<Object> get props => [workHistory, agencyPositions,appointmentStatus,agencies,agencyCategory];
}
class DeletedState extends WorkHistoryState{
final List<WorkHistory> workHistories;
final bool success;
@ -48,3 +59,19 @@ class DeletedState extends WorkHistoryState{
@override
List<Object> get props => [workHistories,success];
}
class WorkHistoryEditedState extends WorkHistoryState{
final List<WorkHistory> workExperiences;
final Map<dynamic,dynamic> response;
const WorkHistoryEditedState({required this.response, required this.workExperiences});
@override
List<Object> get props => [workExperiences,response];
}
class WorkHistoryAddedState extends WorkHistoryState{
final List<WorkHistory> workExperiences;
final Map<dynamic,dynamic> response;
const WorkHistoryAddedState({required this.response, required this.workExperiences});
@override
List<Object> get props => [workExperiences,response];
}

View File

@ -1,29 +1,7 @@
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<String, dynamic> json) => AgencyPosition(
id: json["id"],
title: json["title"],
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
};
}
// To parse this JSON data, do
//
// final appoinemtStatus = appoinemtStatusFromJson(jsonString);

View File

@ -99,7 +99,7 @@ class _EditEligibilityScreenState extends State<EditEligibilityScreen> {
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
//ELIGIBILITIES DROPDOWN
////ELIGIBILITIES DROPDOWN
DropdownButtonFormField<Eligibility>(
validator: (value) =>
value == null ? 'required' : null,
@ -125,7 +125,7 @@ class _EditEligibilityScreenState extends State<EditEligibilityScreen> {
width: screenWidth,
child: Row(
children: [
//LICENSE NUMBER
////LICENSE NUMBER
Flexible(
flex: 1,
child: FormBuilderTextField(
@ -142,7 +142,7 @@ class _EditEligibilityScreenState extends State<EditEligibilityScreen> {
const SizedBox(
width: 12,
),
//RATING
// //RATING
Flexible(
flex: 1,
child: FormBuilderTextField(
@ -169,7 +169,7 @@ class _EditEligibilityScreenState extends State<EditEligibilityScreen> {
width: screenWidth,
child: Row(
children: [
//EXAM DATE
// //EXAM DATE
Flexible(
flex: 1,
child: DateTimePicker(

View File

@ -135,8 +135,8 @@ class LoadingScreen extends StatelessWidget {
),
Center(
child: Container(
height: 150,
width: 150,
height: 120,
width: 120,
decoration:const BoxDecoration(
color: Colors.black87,
borderRadius: BorderRadius.all(Radius.circular(25))
@ -149,7 +149,7 @@ class LoadingScreen extends StatelessWidget {
color: Colors.white),
SizedBox(height: 10,),
Text("Loading Profile",textAlign: TextAlign.center, style: TextStyle(color: Colors.white),)
Text("Loading Profile",textAlign: TextAlign.center, style: TextStyle(color: Colors.white,fontSize: 10),)
],
),
),

View File

@ -6,12 +6,14 @@ 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/profile/work_history.dart';
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/theme-data.dart/box_shadow.dart';
import 'package:unit2/theme-data.dart/btn-style.dart';
import 'package:unit2/theme-data.dart/colors.dart';
import 'package:unit2/theme-data.dart/form-style.dart';
@ -19,6 +21,8 @@ import 'package:unit2/utils/global.dart';
import 'package:unit2/utils/text_container.dart';
import 'package:unit2/utils/validators.dart';
import '../../../../model/utils/position.dart';
class AddWorkHistoryScreen extends StatefulWidget {
const AddWorkHistoryScreen({super.key});
@ -32,15 +36,13 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
final toDateController = TextEditingController();
final fromDateController = TextEditingController();
final _formKey = GlobalKey<FormBuilderState>();
AgencyPosition? selectedPosition;
Position? selectedPosition;
Agency? selectedAgency;
AppoinemtStatus? selectedStatus;
Category? selectedAgencyCategory;
String? salary;
String? salaryGrade;
String? salaryGradeStep;
SingleItemCategoryModel selectedAgencyCategory =
const SingleItemCategoryModel(nameSingleItem: "");
ScrollController agencyScrollController = ScrollController();
bool showAgency = false;
bool showSalaryGradeAndSalaryStep = false;
bool? isPrivate = false;
@ -49,6 +51,9 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
final agencyFocusNode = FocusNode();
final positionFocusNode = FocusNode();
final appointmentStatusNode = FocusNode();
final agencyCategoryFocusNode = FocusNode();
int? profileId;
String? token;
@override
void dispose() {
addPositionController.dispose();
@ -60,10 +65,11 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
@override
Widget build(BuildContext context) {
print("exc");
return BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
if (state is UserLoggedIn) {
profileId = state.userData!.user!.login!.user!.profileId;
token = state.userData!.user!.login!.token;
return BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) {
if (state is ProfileLoaded) {
@ -88,10 +94,20 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
////POSITIONS
StatefulBuilder(builder: (context, setState) {
return SearchField(
itemHeight: 50,
suggestionsDecoration: box1(),
suggestions: state.agencyPositions
.map((AgencyPosition position) =>
.map((Position position) =>
SearchFieldListItem(position.title!,
item: position))
item: position,
child: Padding(
padding: const EdgeInsets
.symmetric(
horizontal: 10),
child: ListTile(
title:
Text(position.title!),
))))
.toList(),
focusNode: positionFocusNode,
searchInputDecoration:
@ -99,11 +115,6 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
.copyWith(
suffixIcon: const Icon(
Icons.arrow_drop_down)),
initialValue: selectedPosition != null
? SearchFieldListItem(
selectedPosition!.title!,
item: selectedPosition)
: null,
onSuggestionTap: (position) {
setState(() {
selectedPosition = position.item;
@ -111,7 +122,7 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
});
},
emptyWidget: Container(
color: Colors.white,
decoration: box1(),
height: 100,
child: Column(
mainAxisAlignment:
@ -122,7 +133,7 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
const SizedBox(
height: 20,
),
const Text("No result found"),
const Text("No result found..."),
const SizedBox(
height: 10,
),
@ -134,7 +145,7 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
context) {
return AlertDialog(
title: const Text(
"Add Position"),
"Add Position?"),
content: SizedBox(
height: 130,
child: Column(
@ -157,21 +168,20 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
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);
() {
Position
newAgencyPosition =
Position(id: null, title: addPositionController.text.toUpperCase());
state.agencyPositions.insert(0,
newAgencyPosition);
selectedPosition =
newAgencyPosition;
addPositionController.text =
"";
Navigator.pop(context);
});
},
child: const Text("Add"))),
],
@ -284,7 +294,7 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
return null;
},
emptyWidget: Container(
color: Colors.white,
decoration: box1(),
height: 100,
child: Column(
mainAxisAlignment:
@ -357,37 +367,70 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
]),
),
),
////AGENCY CATEGORY
SizedBox(
height: showAgency ? 12 : 0,
),
////SHOW CATEGORY AGENCY
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();
// });
? SearchField(
focusNode:
agencyCategoryFocusNode,
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(() {
selectedAgencyCategory =
agencyCategory.item;
agencyCategoryFocusNode
.unfocus();
selectedAgency = Agency(
id: null,
name: selectedAgency!
.name,
category:
selectedAgencyCategory,
privateEntity: null);
});
},
)
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(),
),
@ -427,7 +470,16 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
showSalaryGradeAndSalaryStep =
true;
}
selectedAgency = Agency(
id: null,
name: selectedAgency!
.name,
category:
selectedAgencyCategory,
privateEntity: value == "YES"?true:false);
agencyFocusNode.unfocus();
agencyCategoryFocusNode
.unfocus();
});
},
@ -466,6 +518,22 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
salaryGrade =
value;
},
validator:
FormBuilderValidators
.compose([
FormBuilderValidators
.integer(
radix: 10,
errorText:
"Please enter a number"),
FormBuilderValidators
.numeric(
errorText:
"Please enter a number")
]),
autovalidateMode:
AutovalidateMode
.onUserInteraction,
),
),
const SizedBox(
@ -483,6 +551,22 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
normalTextFieldStyle(
"SG Step (SG)",
"0"),
validator:
FormBuilderValidators
.compose([
FormBuilderValidators
.integer(
radix: 10,
errorText:
"Please enter a number"),
FormBuilderValidators
.numeric(
errorText:
"Please enter a number")
]),
autovalidateMode:
AutovalidateMode
.onUserInteraction,
onChanged: (value) {
setState(() {
salaryGradeStep =
@ -601,7 +685,6 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
)
: DateTimePicker(
validator: (val) {
print(val);
return null;
},
controller:
@ -646,11 +729,44 @@ class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
print(salary);
print(fromDateController.text);
print(toDateController.text);
print(isPrivate);
print(salaryGrade);
print(salaryGradeStep);
if (_formKey.currentState!
.validate()) {}
print(isPrivate);
if (_formKey.currentState!.validate()) {
WorkHistory workHistory = WorkHistory(
position: selectedPosition,
id: null,
agency: selectedAgency,
fromDate: fromDateController
.text.isEmpty
? null
: DateTime.parse(
fromDateController.text),
toDate: toDateController.text.isEmpty ||
toDateController.text
.toUpperCase() ==
"PRESENT"
? null
: DateTime.parse(
toDateController.text),
salaryGrade: salaryGrade == null
? null
: int.parse(salaryGrade!),
sgStep: salaryGradeStep == null
? null
: int.parse(salaryGradeStep!),
monthlySalary:
double.parse(salary!),
appointmentStatus:
selectedStatus!.value);
context.read<WorkHistoryBloc>().add(
AddWorkHostory(
workHistory: workHistory,
profileId: profileId!,
token: token!,
isPrivate: isPrivate!));
}
},
child: const Text(submit)),
),

View File

@ -0,0 +1,828 @@
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 '../../../../bloc/profile/profile_bloc.dart';
import '../../../../bloc/profile/workHistory/workHistory_bloc.dart';
import '../../../../bloc/user/user_bloc.dart';
import '../../../../model/profile/work_history.dart';
import '../../../../model/utils/agency.dart';
import '../../../../model/utils/agency_position.dart';
import '../../../../model/utils/category.dart';
import '../../../../model/utils/position.dart';
import '../../../../theme-data.dart/box_shadow.dart';
import '../../../../theme-data.dart/btn-style.dart';
import '../../../../theme-data.dart/colors.dart';
import '../../../../theme-data.dart/form-style.dart';
import '../../../../utils/global.dart';
import '../../../../utils/text_container.dart';
import '../../../../utils/validators.dart';
class EditWorkHistoryScreen extends StatefulWidget {
const EditWorkHistoryScreen({super.key});
@override
State<EditWorkHistoryScreen> createState() => _EditWorkHistoryScreenState();
}
class _EditWorkHistoryScreenState extends State<EditWorkHistoryScreen> {
final addAgencyController = TextEditingController();
final addPositionController = TextEditingController();
final toDateController = TextEditingController();
final fromDateController = TextEditingController();
final oldPositionController = TextEditingController();
final oldAppointmentStatusController = TextEditingController();
final oldAgencyController = TextEditingController();
final _formKey = GlobalKey<FormBuilderState>();
Position? selectedPosition;
Agency? selectedAgency;
AppoinemtStatus? selectedStatus;
Category? selectedAgencyCategory;
String? salary;
String? salaryGrade;
String? salaryGradeStep;
//show agency category is a variable to show adding of agency category if you add agency manually
bool showAgencyCategory = false;
//showSalaryGadeAndSalaryStep is a variable that will show salary
//and salary step if selected agency is government
bool showSalaryGradeAndSalaryStep = false;
//isPrivate is the value of the isPrivate radion button
bool? isPrivate = false;
//showIsPrivateRadion is a variable that will show isPrivate radio if you
//add agency manually
bool showIsPrivateRadio = false;
bool currentlyEmployed = false;
final agencyFocusNode = FocusNode();
final positionFocusNode = FocusNode();
final appointmentStatusNode = FocusNode();
final agencyCategoryFocusNode = FocusNode();
int? profileId;
String? token;
@override
void dispose() {
addPositionController.dispose();
addAgencyController.dispose();
toDateController.dispose();
fromDateController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
if (state is UserLoggedIn) {
profileId = state.userData!.user!.login!.user!.profileId;
token = state.userData!.user!.login!.token;
return BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) {
if (state is ProfileLoaded) {
return BlocConsumer<WorkHistoryBloc, WorkHistoryState>(
listener: (context, state) {
if (state is AddWorkHistoryState) {
final progress = ProgressHUD.of(context);
progress!.dismiss();
}
}, builder: (context, state) {
if (state is EditWorkHistoryState) {
oldPositionController.text =
state.workHistory.position!.title!;
oldAppointmentStatusController.text =
state.workHistory.appointmentStatus!;
oldAgencyController.text = state.workHistory.agency!.name!;
currentlyEmployed =
state.workHistory.toDate == null ? true : false;
showSalaryGradeAndSalaryStep =
!state.workHistory.agency!.privateEntity!;
fromDateController.text =
state.workHistory.fromDate.toString();
toDateController.text = state.workHistory.toDate.toString();
currentlyEmployed =
state.workHistory.toDate == null ? true : false;
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(
controller: oldPositionController,
itemHeight: 50,
suggestionsDecoration: box1(),
suggestions: state.agencyPositions
.map((Position position) =>
SearchFieldListItem(position.title!,
item: position,
child: Padding(
padding: const EdgeInsets
.symmetric(
horizontal: 10),
child: ListTile(
title:
Text(position.title!),
))))
.toList(),
focusNode: positionFocusNode,
searchInputDecoration:
normalTextFieldStyle("Position *", "")
.copyWith(
suffixIcon: const Icon(
Icons.arrow_drop_down)),
onSuggestionTap: (position) {
setState(() {
selectedPosition = position.item;
positionFocusNode.unfocus();
});
},
emptyWidget: Container(
decoration: box1(),
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: () {
setState(
() {
Position
newAgencyPosition =
Position(id: null, title: addPositionController.text.toUpperCase());
state.agencyPositions.insert(0,
newAgencyPosition);
selectedPosition =
newAgencyPosition;
addPositionController.text =
"";
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(
controller: oldAppointmentStatusController,
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(
controller: oldAgencyController,
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(
decoration: box1(),
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 = "";
showAgencyCategory = true;
showIsPrivateRadio = true;
Navigator.pop(context);
});
},
child: const Text("Add"))),
],
),
),
);
});
},
child: const Text(
"Add Agency"))
]),
),
),
SizedBox(
height: showAgencyCategory ? 12 : 0,
),
////SHOW AGENCY CATEGORY
SizedBox(
child: showAgencyCategory
? SearchField(
focusNode:
agencyCategoryFocusNode,
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(() {
selectedAgencyCategory =
agencyCategory.item;
agencyCategoryFocusNode
.unfocus();
selectedAgency = Agency(
id: null,
name: selectedAgency!
.name,
category:
selectedAgencyCategory,
privateEntity: null);
});
},
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(),
),
////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;
}
selectedAgency = Agency(
id: null,
name: selectedAgency!
.name,
category:
selectedAgencyCategory,
privateEntity:
value == "YES"
? true
: false);
agencyFocusNode.unfocus();
agencyCategoryFocusNode
.unfocus();
});
},
name: 'isPrivate',
validator:
FormBuilderValidators
.required(),
options: ["YES", "NO"]
.map((lang) =>
FormBuilderFieldOption(
value: lang))
.toList(growable: false),
)
: const SizedBox()),
SizedBox(
height: showSalaryGradeAndSalaryStep
? 12
: 0,
),
////SALARY GRADE AND SALARY GRADE STEP
SizedBox(
child: showSalaryGradeAndSalaryStep
? Column(
children: [
Row(
children: [
////SALARY GRADE
Flexible(
flex: 1,
child:
FormBuilderTextField(
initialValue: state
.workHistory
.salaryGrade
?.toString(),
name:
'salary_grade',
keyboardType:
TextInputType
.number,
decoration:
normalTextFieldStyle(
"Salary Grade (SG)",
"0"),
validator:
integerAndNumeric,
autovalidateMode:
AutovalidateMode
.onUserInteraction,
),
),
const SizedBox(
width: 12,
),
//// SALARY STEP
Flexible(
flex: 1,
child:
FormBuilderTextField(
initialValue: state
.workHistory
.sgStep
?.toString(),
name: 'salary_step',
keyboardType:
TextInputType
.number,
decoration:
normalTextFieldStyle(
"SG Step (SG)",
"0"),
validator:
integerAndNumeric,
autovalidateMode:
AutovalidateMode
.onUserInteraction,
),
)
],
)
],
)
: null),
],
);
}),
const SizedBox(
height: 12,
),
////MONTHLY SALARY
FormBuilderTextField(
initialValue: state.workHistory.monthlySalary
.toString(),
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(
prefixIcon:
const Icon(
Icons.date_range,
color: Colors.black45,
)),
)
: DateTimePicker(
validator: (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: () {
if (_formKey.currentState!
.saveAndValidate()) {
salary = _formKey
.currentState!.value['salary'];
selectedPosition ??=
state.workHistory.position;
salaryGrade = _formKey.currentState!
.value['salary_grade'];
salaryGradeStep = _formKey
.currentState!
.value['salary_step'];
selectedAgency ??=
state.workHistory.agency;
selectedStatus ??= AppoinemtStatus(
value: state.workHistory
.appointmentStatus!,
label: state.workHistory
.appointmentStatus!);
WorkHistory newWorkHistory =
WorkHistory(
id: state.workHistory.id,
position: selectedPosition,
agency: selectedAgency,
fromDate: fromDateController
.text.isEmpty
? null
: DateTime.parse(
fromDateController.text),
toDate: toDateController
.text.isEmpty ||
toDateController.text
.toUpperCase() ==
"PRESENT" ||
toDateController.text
.toLowerCase() ==
'null'
? null
: DateTime.parse(
toDateController.text),
monthlySalary:
double.parse(salary!),
appointmentStatus:
selectedStatus!.value,
salaryGrade: salaryGrade == null
? null
: int.parse(salaryGrade!),
sgStep: salaryGradeStep == null
? null
: int.parse(salaryGradeStep!),
);
context.read<WorkHistoryBloc>().add(
UpdateWorkHistory(
oldWorkHistory:
state.workHistory,
profileId:
profileId.toString(),
token: token!,
workHistory: newWorkHistory));
}
},
child: const Text(submit)),
),
const SizedBox(
height: 20,
),
],
),
),
),
),
);
}
return Container();
});
}
return Container();
},
);
}
return const Center(
child: Text("Add Work History"),
);
},
);
}
}

View File

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:app_popup_menu/app_popup_menu.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@ -8,6 +10,7 @@ import 'package:intl/intl.dart';
import 'package:unit2/bloc/profile/profile_bloc.dart';
import 'package:unit2/bloc/user/user_bloc.dart';
import 'package:unit2/screens/profile/components/work_history/add_modal.dart';
import 'package:unit2/screens/profile/components/work_history/edit_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';
@ -16,6 +19,7 @@ import 'package:unit2/widgets/empty_data.dart';
import 'package:unit2/widgets/error_state.dart';
import '../../../bloc/profile/workHistory/workHistory_bloc.dart';
import '../../../model/profile/work_history.dart';
import '../../../utils/alerts.dart';
import '../../../utils/global.dart';
@ -64,7 +68,7 @@ class WorkHistoryScreen extends StatelessWidget {
}
if (state is WorkHistoryLoaded ||
state is WorkHistoryErrorState ||
state is AddWorkHistoryState) {
state is AddWorkHistoryState ||state is WorkHistoryAddedState || state is EditWorkHistoryState) {
final progress = ProgressHUD.of(context);
progress!.dismiss();
}
@ -88,6 +92,44 @@ class WorkHistoryScreen extends StatelessWidget {
});
}
}
////ADDED STATE
if(state is WorkHistoryAddedState){
if (state.response['success']) {
successAlert(context, "Adding Successfull!",
state.response['message'], () {
Navigator.of(context).pop();
context.read<WorkHistoryBloc>().add(LoadWorkHistories(
workHistories: state.workExperiences));
});
} else {
errorAlert(context, "Adding Failed",
"Something went wrong. Please try again.",
() {
Navigator.of(context).pop();
context.read<WorkHistoryBloc>().add(LoadWorkHistories(
workHistories: state.workExperiences));
});
}
}
//// EDITED STATE
if(state is WorkHistoryEditedState){
if (state.response['success']) {
successAlert(context, "Update Successfull!",
state.response['message'], () {
Navigator.of(context).pop();
context.read<WorkHistoryBloc>().add(LoadWorkHistories(
workHistories: state.workExperiences));
});
} else {
errorAlert(context, "Update Failed",
"Something went wrong. Please try again.",
() {
Navigator.of(context).pop();
context.read<WorkHistoryBloc>().add(LoadWorkHistories(
workHistories: state.workExperiences));
});
}
}
},
builder: (context, state) {
if (state is WorkHistoryLoaded) {
@ -188,6 +230,8 @@ class WorkHistoryScreen extends StatelessWidget {
}
if (value == 1) {
////edit eligibilty-= = = = = = = = =>>
WorkHistory workHistory = state.workExperiences[index];
context.read<WorkHistoryBloc>().add(ShowEditWorkHistoryForm(workHistory: workHistory));
}
},
menuItems: [
@ -227,6 +271,9 @@ class WorkHistoryScreen extends StatelessWidget {
if (state is AddWorkHistoryState) {
return const AddWorkHistoryScreen();
}
if(state is EditWorkHistoryState){
return const EditWorkHistoryScreen();
}
if (state is WorkHistoryErrorState) {
return SomethingWentWrong(
message: state.message, onpressed: () {});

View File

@ -6,6 +6,7 @@ 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/model/utils/position.dart';
import 'package:unit2/utils/request.dart';
import '../../utils/urls.dart';
@ -14,6 +15,7 @@ class WorkHistoryService {
static final WorkHistoryService _instance = WorkHistoryService();
static WorkHistoryService get instance => _instance;
//get all workhistories
Future<List<WorkHistory>> getWorkExperiences(
int profileId, String token) async {
List<WorkHistory> workExperiences = [];
@ -40,6 +42,7 @@ class WorkHistoryService {
return workExperiences;
}
//get agencies
Future<List<Agency>> getAgecies() async {
List<Agency> agencies = [];
String path = Url.instance.getAgencies();
@ -64,6 +67,7 @@ class WorkHistoryService {
return agencies;
}
//delete workhistory
Future<bool> delete(
{required int profileId,
required String token,
@ -103,6 +107,7 @@ class WorkHistoryService {
return success!;
}
//get agency category
Future<List<Category>> agencyCategory() async {
List<Category> agencyCategory = [];
String path = Url.instance.getAgencyCategory();
@ -127,8 +132,89 @@ class WorkHistoryService {
return agencyCategory;
}
Future<List<AgencyPosition>> getAgencyPosition() async {
List<AgencyPosition> agencyPositions = [];
//edit work history
Future<Map<dynamic,dynamic>> update({required WorkHistory oldWorkHistory, required WorkHistory newWorkHistory, required String token, required String profileId})async{
Map<dynamic, dynamic>? statusResponse={};
String authtoken = "Token $token";
String path = '${Url.instance.updateWorkHistories()}$profileId/';
Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': authtoken
};
Map body = {
"id":newWorkHistory.id,
"position_id":newWorkHistory.position!.id,
"agency_id":newWorkHistory.agency!.id,
"from_date":newWorkHistory.fromDate?.toString(),
"to_date":newWorkHistory.toDate?.toString(),
"monthly_salary":newWorkHistory.monthlySalary,
"appointment_status":newWorkHistory.appointmentStatus,
"salary_grade":newWorkHistory.salaryGrade,
"sg_step":newWorkHistory.sgStep,
"_positionName":newWorkHistory.position!.title!,
"_agencyName":newWorkHistory.agency!.name!,
"_agencyCatId":newWorkHistory.agency!.category!.id!,
"_privateEntity":newWorkHistory.agency!.privateEntity,
"oldPosId":oldWorkHistory.position!.id,
"_oldAgencyId":oldWorkHistory.agency!.id,
"oldFromDate":oldWorkHistory.fromDate?.toString(),
};
// try{
http.Response response = await Request.instance.putRequest(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();
// }
}
//Add work history
Future<Map<dynamic, dynamic>>add({required WorkHistory workHistory, required String token, required int profileId , required bool isPrivate})async{
String authtoken = "Token $token";
String path = '${Url.instance.addWorkHistory()}$profileId/';
Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': authtoken
};
Map<dynamic,dynamic> statusResponse = {};
Map body = {
'position_id':workHistory.position?.id,
'agency_id': workHistory.agency?.id,
'from_date': workHistory.fromDate?.toString(),
'to_date': workHistory.toDate?.toString(),
'monthly_salary': workHistory.monthlySalary,
'appointment_status': workHistory.appointmentStatus,
'salary_grade': workHistory.salaryGrade,
'sg_step':workHistory.sgStep,
'_positionName':workHistory.position?.title,
'_agencyName':workHistory.agency?.name,
'_agencyCatId':workHistory.agency?.category?.id,
'_privateEntity':workHistory.agency?.privateEntity,
};
try{
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();
}
}
//get agency position
Future<List<Position>> getAgencyPosition() async {
List<Position> agencyPositions = [];
String path = Url.instance.getPositions();
Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
@ -140,7 +226,7 @@ class WorkHistoryService {
Map data = jsonDecode(response.body);
if (data['data'] != null) {
data['data'].forEach((var agencyPosition) {
AgencyPosition position = AgencyPosition.fromJson(agencyPosition);
Position position = Position.fromJson(agencyPosition);
agencyPositions.add(position);
});
}
@ -151,6 +237,7 @@ class WorkHistoryService {
return agencyPositions;
}
//get appointment status
List<AppoinemtStatus> getAppointmentStatusList() {
return [
AppoinemtStatus(value: "Appointed", label: "Appointed"),

View File

@ -1,149 +1,149 @@
import 'package:dropdown_button2/dropdown_button2.dart';
import 'package:flutter/material.dart';
// import 'package:dropdown_button2/dropdown_button2.dart';
// import 'package:flutter/material.dart';
class CustomDropdownButton2 extends StatelessWidget {
final String hint;
final String? value;
final List<String> dropdownItems;
final ValueChanged<String?>? 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;
// class CustomDropdownButton2 extends StatelessWidget {
// final String hint;
// final String? value;
// final List<String> dropdownItems;
// final ValueChanged<String?>? 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);
// 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<String>(
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<double>(scrollbarThickness!)
: null,
thumbVisibility: scrollbarAlwaysShow != null
? MaterialStateProperty.all<bool>(scrollbarAlwaysShow!)
: null,
),
),
menuItemStyleData: MenuItemStyleData(
height: itemHeight ?? 40,
padding: itemPadding ?? const EdgeInsets.only(left: 14, right: 14),
),
),
);
}
}
// @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<String>(
// 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<double>(scrollbarThickness!)
// : null,
// thumbVisibility: scrollbarAlwaysShow != null
// ? MaterialStateProperty.all<bool>(scrollbarAlwaysShow!)
// : null,
// ),
// ),
// menuItemStyleData: MenuItemStyleData(
// height: itemHeight ?? 40,
// padding: itemPadding ?? const EdgeInsets.only(left: 14, right: 14),
// ),
// ),
// );
// }
// }

View File

@ -3,10 +3,10 @@ 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";
// return "devweb.agusandelnorte.gov.ph";
// return 'devapi.agusandelnorte.gov.ph:3004';
}
@ -51,6 +51,13 @@ String getPositions(){
String getAgencies(){
return "/api/jobnet_app/agencies/";
}
String updateWorkHistories(){
return "/api/jobnet_app/profile/pds/work/";
}
String addWorkHistory(){
return "/api/jobnet_app/profile/pds/work/";
}
String getAgencyCategory(){
return "api/jobnet_app/agency_categories/";
}

View File

@ -16,3 +16,19 @@ final registerPasswordValidator = FormBuilderValidators.compose([
FormBuilderValidators.minLength(6,
errorText: "Password must be equal or greater than 6 characters"),
]);
final integerAndNumeric =
FormBuilderValidators
.compose([
FormBuilderValidators
.integer(
radix: 10,
errorText:
"Please enter a number"),
FormBuilderValidators
.numeric(
errorText:
"Please enter a number")
]);

View File

@ -201,22 +201,6 @@ 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:
@ -326,14 +310,6 @@ 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:
@ -797,14 +773,6 @@ 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:
@ -813,14 +781,6 @@ packages:
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:

View File

@ -70,11 +70,6 @@ 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