replacing selectdot2

feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
PGAN-MIS 2023-03-16 15:53:42 +08:00
parent 5bea76102c
commit e087eb147d
19 changed files with 2062 additions and 610 deletions

View File

@ -22,6 +22,8 @@ PODS:
- FlutterMacOS - FlutterMacOS
- permission_handler_apple (9.0.4): - permission_handler_apple (9.0.4):
- Flutter - Flutter
- search_choices (0.0.1):
- Flutter
- shared_preferences_foundation (0.0.1): - shared_preferences_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS - FlutterMacOS
@ -40,6 +42,7 @@ DEPENDENCIES:
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/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`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`)
@ -67,6 +70,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/path_provider_foundation/ios" :path: ".symlinks/plugins/path_provider_foundation/ios"
permission_handler_apple: permission_handler_apple:
:path: ".symlinks/plugins/permission_handler_apple/ios" :path: ".symlinks/plugins/permission_handler_apple/ios"
search_choices:
:path: ".symlinks/plugins/search_choices/ios"
shared_preferences_foundation: shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/ios" :path: ".symlinks/plugins/shared_preferences_foundation/ios"
sqflite: sqflite:
@ -83,6 +88,7 @@ SPEC CHECKSUMS:
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852 path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
search_choices: b50731e8c425078048f681f39c34375c58d6ce8d
shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca shared_preferences_foundation: 297b3ebca31b34ec92be11acd7fb0ba932c822ca
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1 SwiftProtobuf: b02b5075dcf60c9f5f403000b3b0c202a11b6ae1

View File

@ -172,6 +172,7 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
if (success) { if (success) {
event.eligibilities.removeWhere( event.eligibilities.removeWhere(
((EligibityCert element) => element.id == event.eligibilityId)); ((EligibityCert element) => element.id == event.eligibilityId));
List<EligibityCert> eligibilities = event.eligibilities; List<EligibityCert> eligibilities = event.eligibilities;
emit(DeletedState(success: success, eligibilities: eligibilities)); emit(DeletedState(success: success, eligibilities: eligibilities));
} else { } else {

View File

@ -9,8 +9,9 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
ProfileBloc() : super(ProfileInitial()) { ProfileBloc() : super(ProfileInitial()) {
ProfileInformation? globalProfileInformation; ProfileInformation? globalProfileInformation;
on<LoadProfile>((event, emit) async { on<LoadProfile>((event, emit) async {
try {
emit(ProfileLoading()); emit(ProfileLoading());
try {
ProfileInformation? profileInformation = ProfileInformation? profileInformation =
await ProfileService.instance.getProfile(event.token, event.userID); await ProfileService.instance.getProfile(event.token, event.userID);
globalProfileInformation = profileInformation; globalProfileInformation = profileInformation;

View File

@ -1,23 +1,228 @@
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:select2dot1/select2dot1.dart';
import 'package:unit2/model/profile/work_history.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 'package:unit2/sevices/profile/work_history_services.dart';
import '../../../model/utils/category.dart';
part 'workHistory_event.dart'; part 'workHistory_event.dart';
part 'workHistory_state.dart'; part 'workHistory_state.dart';
class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> { class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
List<WorkHistory> workExperiences = []; List<WorkHistory> workExperiences = [];
List<AgencyPosition> agencyPositions = [];
List<Agency> agencies = [];
List<AppoinemtStatus> appointmentStatus = [];
List<Category> agencyCategory = [];
WorkHistoryBloc() : super(EducationInitial()) { WorkHistoryBloc() : super(EducationInitial()) {
on<GetWorkHistories>((event, emit)async { on<GetWorkHistories>((event, emit) async {
emit(WorkHistoryLoadingState()); emit(WorkHistoryLoadingState());
// try{ try {
List<WorkHistory> works = await WorkHistoryService.instance.getWorkExperiences(event.profileId, event.token); List<WorkHistory> works = await WorkHistoryService.instance
.getWorkExperiences(event.profileId, event.token);
workExperiences = works; workExperiences = works;
emit(WorkHistoryLoaded(workExperiences: workExperiences)); emit(WorkHistoryLoaded(workExperiences: workExperiences));
// }catch(e){ } catch (e) {
// emit(WorkHistoryErrorState(message: e.toString())); emit(WorkHistoryErrorState(message: e.toString()));
// } }
});
on<LoadWorkHistories>((event,emit){
emit(WorkHistoryLoadingState());
workExperiences = event.workHistories;
emit(WorkHistoryLoaded(workExperiences: workExperiences));
});
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);
List<WorkHistory> 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<ShowAddWorkHistoryForm>((event, emit) async {
emit(WorkHistoryLoadingState());
try {
/////POSITIONS------------------------------------------
List<AgencyPosition> positions =
await WorkHistoryService.instance.getAgencyPosition();
agencyPositions = positions;
/////AGENCIES------------------------------------------
List<Agency> newAgencies =
await WorkHistoryService.instance.getAgecies();
agencies = newAgencies;
/////Category Agency------------------------------------------
List<Category> categoryAgencies =
await WorkHistoryService.instance.agencyCategory();
agencyCategory = categoryAgencies;
/////////-------------------------------------
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,
appointmentStatus: appointmentStatus,
agencyCategory: agencyCategoryDropdownData,
agencies: agencies));
} catch (e) {
emit(WorkHistoryErrorState(message: e.toString()));
}
}); });
} }
} }

View File

@ -17,4 +17,24 @@ class GetWorkHistories extends WorkHistorytEvent{
List<Object> get props => [profileId, token]; List<Object> get props => [profileId, token];
} }
class LoadWorkHistories extends WorkHistorytEvent{
final List<WorkHistory> workHistories;
const LoadWorkHistories({required this.workHistories});
@override
List<Object> get props => [workHistories];
}
class ShowAddWorkHistoryForm extends WorkHistorytEvent{
}
class DeleteWorkHistory extends WorkHistorytEvent{
final List<WorkHistory> 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<Object> get props => [token, profileId,workHistory, workHistories];
}

View File

@ -26,3 +26,25 @@ class WorkHistoryErrorState extends WorkHistoryState{
@override @override
List<Object> get props => [message]; List<Object> get props => [message];
} }
class AddWorkHistoryState extends WorkHistoryState{
final List<AgencyPosition> agencyPositions;
final List<Agency> agencies;
final List<SingleCategoryModel> agencyCategory;
final List<AppoinemtStatus> appointmentStatus;
const AddWorkHistoryState({required this.agencyPositions, required this.appointmentStatus,required this.agencies,required this.agencyCategory});
@override
List<Object> get props => [agencyPositions,appointmentStatus,agencies,agencyCategory];
}
class DeletedState extends WorkHistoryState{
final List<WorkHistory> workHistories;
final bool success;
const DeletedState({required this.success, required this.workHistories});
@override
List<Object> get props => [workHistories,success];
}

View File

@ -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<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);
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<String, dynamic> json) => AppoinemtStatus(
value: json["value"],
label: json["label"],
);
Map<String, dynamic> toJson() => {
"value": value,
"label": label,
};
}

View File

@ -62,7 +62,7 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
profileId = state.userData!.user!.login!.user!.profileId.toString(); profileId = state.userData!.user!.login!.user!.profileId.toString();
return BlocBuilder<ProfileBloc, ProfileState>( return BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) { builder: (context, state) {
if(state is ProfileLoaded){ if (state is ProfileLoaded) {
return BlocBuilder<EligibilityBloc, EligibilityState>( return BlocBuilder<EligibilityBloc, EligibilityState>(
buildWhen: (previous, current) { buildWhen: (previous, current) {
if (state is EditEligibilityState) {} if (state is EditEligibilityState) {}
@ -154,17 +154,19 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
flex: 1, flex: 1,
child: DateTimePicker( child: DateTimePicker(
use24HourFormat: false, use24HourFormat: false,
icon: icon: const Icon(
const Icon(Icons.date_range), Icons.date_range),
controller: examDateController, controller: examDateController,
firstDate: DateTime(1970), firstDate: DateTime(1970),
lastDate: DateTime(2100), lastDate: DateTime(2100),
timeHintText: timeHintText:
"Date of Examination/Conferment", "Date of Examination/Conferment",
decoration: normalTextFieldStyle( decoration:
normalTextFieldStyle(
"Exam date", "") "Exam date", "")
.copyWith( .copyWith(
prefixIcon: const Icon( prefixIcon:
const Icon(
Icons.date_range, Icons.date_range,
color: Colors.black87, color: Colors.black87,
)), )),
@ -177,7 +179,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible( Flexible(
flex: 1, flex: 1,
child: DateTimePicker( child: DateTimePicker(
controller: validityDateController, controller:
validityDateController,
firstDate: DateTime(1970), firstDate: DateTime(1970),
lastDate: DateTime(2100), lastDate: DateTime(2100),
decoration: normalTextFieldStyle( decoration: normalTextFieldStyle(
@ -222,7 +225,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
decoration: decoration:
normalTextFieldStyle("", ''), normalTextFieldStyle("", ''),
name: 'overseas', name: 'overseas',
title: const Text("Overseas Address?"), title:
const Text("Overseas Address?"),
), ),
const SizedBox( const SizedBox(
height: 20, height: 20,
@ -244,7 +248,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Country>( Country>(
value: country, value: country,
child: FittedBox( child: FittedBox(
child: Text(country child: Text(
country
.name!))); .name!)));
}).toList(), }).toList(),
name: 'country', name: 'country',
@ -252,7 +257,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
normalTextFieldStyle( normalTextFieldStyle(
"Country*", "Country*",
"Country"), "Country"),
onChanged: (Country? value) { onChanged:
(Country? value) {
selectedCountry = value; selectedCountry = value;
}, },
) )
@ -273,7 +279,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
setState(() { setState(() {
provinceCall = true; provinceCall = true;
}); });
selectedRegion = region; selectedRegion =
region;
getProvinces(); getProvinces();
}, },
initialValue: initialValue:
@ -285,8 +292,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
name: 'region', name: 'region',
items: state.regions.map< items: state.regions.map<
DropdownMenuItem< DropdownMenuItem<
Region>>( Region>>((Region
(Region region) { region) {
return DropdownMenuItem< return DropdownMenuItem<
Region>( Region>(
value: region, value: region,
@ -301,8 +308,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
SizedBox( SizedBox(
height: 70, height: 70,
child: ModalProgressHUD( child: ModalProgressHUD(
color: color: Colors
Colors.transparent, .transparent,
inAsyncCall: inAsyncCall:
provinceCall, provinceCall,
child: DropdownButtonFormField< child: DropdownButtonFormField<
@ -321,7 +328,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
(Province? (Province?
province) { province) {
setState(() { setState(() {
cityCall = true; cityCall =
true;
}); });
selectedProvince = selectedProvince =
province; province;
@ -356,8 +364,7 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
child: ModalProgressHUD( child: ModalProgressHUD(
color: Colors.white, color: Colors.white,
inAsyncCall: cityCall, inAsyncCall: cityCall,
child: child: DropdownButtonFormField<
DropdownButtonFormField<
CityMunicipality>( CityMunicipality>(
validator: (value) => validator: (value) =>
value == null value == null
@ -370,8 +377,7 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
selectedMunicipality = selectedMunicipality =
city; city;
}, },
decoration: decoration: normalTextFieldStyle(
normalTextFieldStyle(
"Municipality*", "Municipality*",
"Municipality"), "Municipality"),
value: value:
@ -385,7 +391,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
(CityMunicipality (CityMunicipality
c) { c) {
return DropdownMenuItem( return DropdownMenuItem(
value: c, value:
c,
child: Text( child: Text(
c.description!)); c.description!));
}).toList(), }).toList(),
@ -423,7 +430,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
examDateController.text.isEmpty examDateController.text.isEmpty
? null ? null
: DateTime.parse( : DateTime.parse(
examDateController.text); examDateController
.text);
DateTime? validityDate = DateTime? validityDate =
validityDateController validityDateController
.text.isEmpty .text.isEmpty
@ -432,7 +440,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
validityDateController validityDateController
.text); .text);
ExamAddress examAddress = ExamAddress( ExamAddress examAddress =
ExamAddress(
barangay: null, barangay: null,
id: null, id: null,
addressCategory: null, addressCategory: null,
@ -454,12 +463,14 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
selectedEligibility, selectedEligibility,
examAddress: examAddress, examAddress: examAddress,
validityDate: validityDate, validityDate: validityDate,
licenseNumber: licenseNumber, licenseNumber:
licenseNumber,
overseas: overseas); overseas: overseas);
if (formKey.currentState! if (formKey.currentState!
.saveAndValidate()) { .saveAndValidate()) {
context.read<EligibilityBloc>().add( context
AddEligibility( .read<EligibilityBloc>()
.add(AddEligibility(
eligibityCert: eligibityCert:
eligibityCert, eligibityCert,
profileId: profileId!, profileId: profileId!,

View File

@ -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/main_menu.dart';
import 'package:unit2/screens/profile/components/submenu.dart'; import 'package:unit2/screens/profile/components/submenu.dart';
import 'package:unit2/utils/global.dart'; import 'package:unit2/utils/global.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import '../../../theme-data.dart/colors.dart'; import '../../../theme-data.dart/colors.dart';
class LoadingScreen extends StatelessWidget { class LoadingScreen extends StatelessWidget {
@ -20,17 +20,16 @@ class LoadingScreen extends StatelessWidget {
children: [ children: [
Container( Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 12),
vertical: 12, horizontal: 12),
child: ListView( child: ListView(
children: [ children: [
const Text( const Text(
"View and Update your Profile Information",textAlign: TextAlign.center,), "View and Update your Profile Information",
textAlign: TextAlign.center,
),
ExpandableGroup( ExpandableGroup(
collapsedIcon: collapsedIcon: const Icon(Icons.keyboard_arrow_down),
const Icon(Icons.keyboard_arrow_down), expandedIcon: const Icon(Icons.keyboard_arrow_up),
expandedIcon:
const Icon(Icons.keyboard_arrow_up),
header: const ListTile( header: const ListTile(
leading: Icon( leading: Icon(
Elusive.address_book, Elusive.address_book,
@ -38,79 +37,61 @@ class LoadingScreen extends StatelessWidget {
), ),
title: Text( title: Text(
"Basic Information", "Basic Information",
style: style: TextStyle(fontWeight: FontWeight.bold),
TextStyle(fontWeight: FontWeight.bold),
), ),
), ),
items: [ items: [
subMenu(Icons.person, "Primary",(){}), subMenu(Icons.person, "Primary", () {}),
subMenu(Icons.home, "Home Addresses",(){}), subMenu(Icons.home, "Home Addresses", () {}),
subMenu( subMenu(Icons.contact_mail, "Identifications", () {}),
Icons.contact_mail, "Identifications",(){}), subMenu(Icons.contact_phone, "Contact Info", () {}),
subMenu(Icons.contact_phone, "Contact Info",(){}), subMenu(Icons.flag, "Citizenships", () {}),
subMenu(Icons.flag, "Citizenships",(){}),
]), ]),
const Divider(), const Divider(),
MainMenu( MainMenu(
icon: Elusive.group, icon: Elusive.group,
title: "Family", title: "Family",
onTap: () { onTap: () {},
},
), ),
const Divider(), const Divider(),
MainMenu( MainMenu(
icon: FontAwesome5.graduation_cap, icon: FontAwesome5.graduation_cap,
title: "Education", title: "Education",
onTap: () { onTap: () {},
},
), ),
const Divider(), const Divider(),
MainMenu( MainMenu(
icon: Icons.stars, icon: Icons.stars,
title: "Eligibility", title: "Eligibility",
onTap: () { onTap: () {},
},
), ),
const Divider(), const Divider(),
MainMenu( MainMenu(
icon: FontAwesome5.shopping_bag, icon: FontAwesome5.shopping_bag,
title: "Work History", title: "Work History",
onTap: () { onTap: () {},
},
), ),
const Divider(), const Divider(),
MainMenu( MainMenu(
icon: FontAwesome5.walking, icon: FontAwesome5.walking,
title: "Voluntary Work & Civic Services", title: "Voluntary Work & Civic Services",
onTap: () { onTap: () {},
},
), ),
const Divider(), const Divider(),
MainMenu( MainMenu(
icon: Elusive.lightbulb, icon: Elusive.lightbulb,
title: "Learning & Development", title: "Learning & Development",
onTap: () { onTap: () {},
},
), ),
const Divider(), const Divider(),
MainMenu( MainMenu(
icon: Brandico.codepen, icon: Brandico.codepen,
title: "Personal References", title: "Personal References",
onTap: () { onTap: () {},
},
), ),
ExpandableGroup( ExpandableGroup(
collapsedIcon: collapsedIcon: const Icon(Icons.keyboard_arrow_down),
const Icon(Icons.keyboard_arrow_down), expandedIcon: const Icon(Icons.keyboard_arrow_up),
expandedIcon:
const Icon(Icons.keyboard_arrow_up),
header: const ListTile( header: const ListTile(
leading: Icon( leading: Icon(
Icons.info, Icons.info,
@ -118,23 +99,19 @@ class LoadingScreen extends StatelessWidget {
), ),
title: Text( title: Text(
"Other Information", "Other Information",
style: style: TextStyle(fontWeight: FontWeight.bold),
TextStyle(fontWeight: FontWeight.bold),
), ),
), ),
items: [ items: [
subMenu( subMenu(Icons.fitness_center, "Skills & Hobbies", () {}),
Icons.fitness_center, "Skills & Hobbies",(){}),
subMenu(FontAwesome5.certificate, subMenu(FontAwesome5.certificate,
"Organization Memberships",(){}), "Organization Memberships", () {}),
subMenu(Entypo.doc_text, subMenu(
"Non-Academic Recognitions",(){}), Entypo.doc_text, "Non-Academic Recognitions", () {}),
]), ]),
ExpandableGroup( ExpandableGroup(
collapsedIcon: collapsedIcon: const Icon(Icons.keyboard_arrow_down),
const Icon(Icons.keyboard_arrow_down), expandedIcon: const Icon(Icons.keyboard_arrow_up),
expandedIcon:
const Icon(Icons.keyboard_arrow_up),
header: const ListTile( header: const ListTile(
leading: Icon( leading: Icon(
FontAwesome5.laptop_house, FontAwesome5.laptop_house,
@ -142,13 +119,11 @@ class LoadingScreen extends StatelessWidget {
), ),
title: Text( title: Text(
"Assets", "Assets",
style: style: TextStyle(fontWeight: FontWeight.bold),
TextStyle(fontWeight: FontWeight.bold),
), ),
), ),
items: [ items: [
subMenu(ModernPictograms.home, subMenu(ModernPictograms.home, "Real Property Tax", () {}),
"Real Property Tax",(){}),
]), ]),
], ],
), ),
@ -158,6 +133,27 @@ class LoadingScreen extends StatelessWidget {
height: screenHeight, height: screenHeight,
color: Colors.white70, 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),)
],
),
),
),
], ],
); );
} }

View File

@ -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<AddWorkHistoryScreen> createState() => _AddWorkHistoryScreenState();
}
class _AddWorkHistoryScreenState extends State<AddWorkHistoryScreen> {
final addAgencyController = TextEditingController();
final addPositionController = TextEditingController();
final toDateController = TextEditingController();
final fromDateController = TextEditingController();
final _formKey = GlobalKey<FormBuilderState>();
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<UserBloc, UserState>(
builder: (context, state) {
if (state is UserLoggedIn) {
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 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"),
);
},
);
}
}

View File

@ -1,11 +1,13 @@
import 'package:app_popup_menu/app_popup_menu.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:fluttericon/font_awesome_icons.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart';
import 'package:unit2/bloc/user/user_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/box_shadow.dart';
import 'package:unit2/theme-data.dart/colors.dart'; import 'package:unit2/theme-data.dart/colors.dart';
import 'package:unit2/utils/text_container.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 'package:unit2/widgets/error_state.dart';
import '../../../bloc/profile/workHistory/workHistory_bloc.dart'; import '../../../bloc/profile/workHistory/workHistory_bloc.dart';
import '../../../utils/alerts.dart';
import '../../../utils/global.dart'; import '../../../utils/global.dart';
class WorkHistoryScreen extends StatelessWidget { class WorkHistoryScreen extends StatelessWidget {
@ -22,12 +25,18 @@ class WorkHistoryScreen extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US'); DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
String? token;
int profileId;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: const Text(workHistoryScreenTitle), title: const Text(workHistoryScreenTitle),
backgroundColor: primary, backgroundColor: primary,
centerTitle: true, centerTitle: true,
actions: [AddLeading(onPressed: () {})], actions: [
AddLeading(onPressed: () {
context.read<WorkHistoryBloc>().add(ShowAddWorkHistoryForm());
})
],
), ),
body: body:
//UserBloc //UserBloc
@ -40,6 +49,8 @@ class WorkHistoryScreen extends StatelessWidget {
child: BlocBuilder<UserBloc, UserState>( child: BlocBuilder<UserBloc, UserState>(
builder: (context, state) { builder: (context, state) {
if (state is UserLoggedIn) { if (state is UserLoggedIn) {
token = state.userData!.user!.login!.token;
profileId = state.userData!.user!.login!.user!.profileId!;
return BlocBuilder<ProfileBloc, ProfileState>( return BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) { builder: (context, state) {
//ProfileBloc //ProfileBloc
@ -51,10 +62,32 @@ class WorkHistoryScreen extends StatelessWidget {
final progress = ProgressHUD.of(context); final progress = ProgressHUD.of(context);
progress!.showWithText("Please wait..."); 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); final progress = ProgressHUD.of(context);
progress!.dismiss(); 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<WorkHistoryBloc>().add(
LoadWorkHistories(
workHistories: state.workHistories));
});
} else {
errorAlert(context, "Deletion Failed",
"Error deleting Work History", () {
Navigator.of(context).pop();
context.read<WorkHistoryBloc>().add(
LoadWorkHistories(
workHistories: state.workHistories));
});
}
}
}, },
builder: (context, state) { builder: (context, state) {
if (state is WorkHistoryLoaded) { if (state is WorkHistoryLoaded) {
@ -77,8 +110,9 @@ class WorkHistoryScreen extends StatelessWidget {
state.workExperiences[index].toDate == state.workExperiences[index].toDate ==
null null
? present.toUpperCase() ? present.toUpperCase()
: dteFormat2.format( : dteFormat2.format(state
state.workExperiences[index].toDate!); .workExperiences[index]
.toDate!);
return Column( return Column(
children: [ children: [
Container( Container(
@ -127,12 +161,55 @@ class WorkHistoryScreen extends StatelessWidget {
), ),
], ],
)), )),
IconButton( AppPopupMenu<int>(
onPressed: () {}, 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<WorkHistoryBloc>(
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( icon: const Icon(
Icons.more_vert, Icons.more_vert,
color: Colors.grey, color: Colors.grey,
)) ),
tooltip: "Options",
)
]), ]),
), ),
const SizedBox( const SizedBox(
@ -147,6 +224,9 @@ class WorkHistoryScreen extends StatelessWidget {
"You don't have any work experience added. Please click + to add"); "You don't have any work experience added. Please click + to add");
} }
} }
if (state is AddWorkHistoryState) {
return const AddWorkHistoryScreen();
}
if (state is WorkHistoryErrorState) { if (state is WorkHistoryErrorState) {
return SomethingWentWrong( return SomethingWentWrong(
message: state.message, onpressed: () {}); message: state.message, onpressed: () {});
@ -165,3 +245,22 @@ class WorkHistoryScreen extends StatelessWidget {
)); ));
} }
} }
PopupMenuItem<int> popMenuItem({String? text, int? value, IconData? icon}) {
return PopupMenuItem(
value: value,
child: Row(
children: [
Icon(
icon,
),
const SizedBox(
width: 10,
),
Text(
text!,
),
],
),
);
}

View File

@ -43,18 +43,14 @@ import '../../bloc/user/user_bloc.dart';
import 'components/main_menu.dart'; import 'components/main_menu.dart';
import 'components/submenu.dart'; import 'components/submenu.dart';
class ProfileInfo extends StatefulWidget { class ProfileInfo extends StatelessWidget {
const ProfileInfo({super.key}); const ProfileInfo({super.key});
@override
State<ProfileInfo> createState() => _ProfileInfoState();
}
class _ProfileInfoState extends State<ProfileInfo> {
int? profileId;
String? token;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
int? profileId;
String? token;
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
backgroundColor: primary, backgroundColor: primary,
@ -62,6 +58,7 @@ class _ProfileInfoState extends State<ProfileInfo> {
title: const Text('Profile'), title: const Text('Profile'),
), ),
body: ProgressHUD( body: ProgressHUD(
padding: const EdgeInsets.all(24),
backgroundColor: Colors.black87, backgroundColor: Colors.black87,
indicatorWidget: const SpinKitFadingCircle(color: Colors.white), indicatorWidget: const SpinKitFadingCircle(color: Colors.white),
child: BlocBuilder<UserBloc, UserState>(builder: (context, state) { child: BlocBuilder<UserBloc, UserState>(builder: (context, state) {
@ -69,12 +66,10 @@ class _ProfileInfoState extends State<ProfileInfo> {
profileId = state.userData!.user!.login!.user!.profileId; profileId = state.userData!.user!.login!.user!.profileId;
token = state.userData!.user!.login!.token!; token = state.userData!.user!.login!.token!;
return BlocConsumer<ProfileBloc, ProfileState>( return BlocConsumer<ProfileBloc, ProfileState>(
listener: (context, state) { listener: (context, state,){
if (state is ProfileLoading) { if (state is ProfileLoading) {
final progress = ProgressHUD.of(context); final progress = ProgressHUD.of(context);
progress?.showWithText( progress!.showWithText("Please wait...");
'Loading Profile',
);
} }
if (state is ProfileLoaded || state is ProfileErrorState) { if (state is ProfileLoaded || state is ProfileErrorState) {
final progress = ProgressHUD.of(context); final progress = ProgressHUD.of(context);
@ -152,8 +147,11 @@ class _ProfileInfoState extends State<ProfileInfo> {
return BlocProvider( return BlocProvider(
create: (context) => ContactBloc() create: (context) => ContactBloc()
..add(GetContacts( ..add(GetContacts(
contactInformations: state.profileInformation.basicInfo.contactInformation)), contactInformations: state
child: ContactInformationScreen(), .profileInformation
.basicInfo
.contactInformation)),
child: const ContactInformationScreen(),
); );
})); }));
}), }),
@ -361,6 +359,7 @@ class _ProfileInfoState extends State<ProfileInfo> {
); );
} }
if (state is ProfileLoading) { if (state is ProfileLoading) {
return const LoadingScreen(); return const LoadingScreen();
} }
if (state is ProfileErrorState) { if (state is ProfileErrorState) {

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:unit2/screens/unit2/homepage.dart/module-screen.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/theme-data.dart/colors.dart';
import 'package:unit2/utils/global.dart'; import 'package:unit2/utils/global.dart';
@ -25,11 +24,11 @@ class DashBoard extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
roles[index].name, roles[index].name.toUpperCase(),
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.labelLarge! .labelLarge!
.copyWith(fontSize: 14), .copyWith(fontSize: 12),
), ),
const SizedBox( const SizedBox(
@ -38,29 +37,43 @@ class DashBoard extends StatelessWidget {
GridView.count( GridView.count(
shrinkWrap: true, shrinkWrap: true,
crossAxisCount: 4, crossAxisCount: 4,
crossAxisSpacing: 5, crossAxisSpacing: 8,
mainAxisSpacing: 2, mainAxisSpacing: 10,
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 5, horizontal: 5), vertical: 5, horizontal: 5),
children: roles[index].roles.map((role) { children: roles[index].roles.map((role) {
return Container( return Container(
padding: const EdgeInsets.all(8), padding: const EdgeInsetsDirectional.fromSTEB(8,5,8,13),
decoration:box1(), 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( child: GestureDetector(
onTap: () { onTap: () {
}, },
child: Column(children: [ child: Column(
Icon( mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Icon(
role.icon, role.icon,
size: 24, size: 20,
color: second, weight: 100,
grade: 100,
color:second,
),
), ),
const SizedBox( const SizedBox(
height: 5, height: 5,
), ),
Expanded( Text(
child: Text( role.role.name!.toLowerCase() == "establishment point-person"?"Est. point-person":
role.role.name!, role.role.name!,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context) style: Theme.of(context)
@ -70,7 +83,6 @@ class DashBoard extends StatelessWidget {
fontSize: blockSizeVertical*1.1, fontSize: blockSizeVertical*1.1,
fontWeight: FontWeight.bold), fontWeight: FontWeight.bold),
), ),
),
]), ]),
), ),
); );

View File

@ -2,38 +2,165 @@ import 'dart:convert';
import 'package:unit2/model/profile/work_history.dart'; import 'package:unit2/model/profile/work_history.dart';
import 'package:http/http.dart' as http; 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 'package:unit2/utils/request.dart';
import '../../utils/urls.dart'; import '../../utils/urls.dart';
class WorkHistoryService{
class WorkHistoryService {
static final WorkHistoryService _instance = WorkHistoryService(); static final WorkHistoryService _instance = WorkHistoryService();
static WorkHistoryService get instance => _instance; static WorkHistoryService get instance => _instance;
Future <List<WorkHistory>> getWorkExperiences( int profileId, String token)async{ Future<List<WorkHistory>> getWorkExperiences(
int profileId, String token) async {
List<WorkHistory> workExperiences = []; List<WorkHistory> workExperiences = [];
String authToken = "Token $token"; String authToken = "Token $token";
Map<String, String> headers = { Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8', 'Content-Type': 'application/json; charset=UTF-8',
'Authorization': authToken 'Authorization': authToken
}; };
String path= Url.instance.getWorkHistories()+profileId.toString(); String path = Url.instance.getWorkHistories() + profileId.toString();
// try{ try {
http.Response response =await Request.instance.getRequest(path: path, headers: headers, param: {}); http.Response response = await Request.instance
if(response.statusCode == 200){ .getRequest(path: path, headers: headers, param: {});
if (response.statusCode == 200) {
Map data = jsonDecode(response.body); Map data = jsonDecode(response.body);
if(data['data'] != null){ if (data['data'] != null) {
data['data'].forEach((var workHistory){ data['data'].forEach((var workHistory) {
workExperiences.add(WorkHistory.fromJson(workHistory)); workExperiences.add(WorkHistory.fromJson(workHistory));
}); });
} }
} }
// }catch(e){ } catch (e) {
// throw e.toString(); throw e.toString();
// } }
return workExperiences; return workExperiences;
}
Future<List<Agency>> getAgecies() async {
List<Agency> agencies = [];
String path = Url.instance.getAgencies();
Map<String, String> 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<bool> delete(
{required int profileId,
required String token,
required WorkHistory work}) async {
bool? success;
Map<String, dynamic> 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<String, String> 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<List<Category>> agencyCategory() async {
List<Category> agencyCategory = [];
String path = Url.instance.getAgencyCategory();
Map<String, String> 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<List<AgencyPosition>> getAgencyPosition() async {
List<AgencyPosition> agencyPositions = [];
String path = Url.instance.getPositions();
Map<String, String> 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<AppoinemtStatus> 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"),
];
} }
} }

View File

@ -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<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);
@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,7 +3,7 @@ class Url {
static Url get instance => _instance; static Url get instance => _instance;
String host() { String host() {
// // return '192.168.10.221:3003'; // // // return '192.168.10.221:3003';
// return 'agusandelnorte.gov.ph'; // return 'agusandelnorte.gov.ph';
// return "192.168.10.219:3000"; // return "192.168.10.219:3000";
return "devweb.agusandelnorte.gov.ph"; return "devweb.agusandelnorte.gov.ph";
@ -45,6 +45,18 @@ String updateEligibility(){
String getWorkHistories(){ String getWorkHistories(){
return "/api/jobnet_app/profile/pds/work/"; 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 ////educational background paths
String getEducationalBackgrounds(){ String getEducationalBackgrounds(){

View File

@ -6,6 +6,10 @@ final mobileNumberValidator = FormBuilderValidators.compose([
FormBuilderValidators.required(errorText: mobileNumberRequired), FormBuilderValidators.required(errorText: mobileNumberRequired),
FormBuilderValidators.numeric(errorText: numericValidator) FormBuilderValidators.numeric(errorText: numericValidator)
]); ]);
final numericRequired = FormBuilderValidators.compose([
FormBuilderValidators.required(errorText: "This field is required"),
FormBuilderValidators.numeric(errorText: numericValidator)
]);
final registerPasswordValidator = FormBuilderValidators.compose([ final registerPasswordValidator = FormBuilderValidators.compose([
FormBuilderValidators.required(errorText: "Password is required"), FormBuilderValidators.required(errorText: "Password is required"),

View File

@ -201,6 +201,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.6" 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: easy_app_installer:
dependency: "direct main" dependency: "direct main"
description: description:
@ -310,6 +326,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" 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: flutter_form_builder:
dependency: "direct main" dependency: "direct main"
description: description:
@ -773,6 +797,30 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.2.3" 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: shared_preferences:
dependency: transitive dependency: transitive
description: description:

View File

@ -70,6 +70,13 @@ dependencies:
badges: ^3.0.2 badges: ^3.0.2
app_popup_menu: ^1.0.0 app_popup_menu: ^1.0.0
modal_progress_hud_nsn: ^0.3.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: dev_dependencies:
flutter_test: flutter_test: