Implemnent Voluntary works and civic API
parent
7f39bd5cd9
commit
1c6b291889
|
@ -1,6 +1,8 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:unit2/bloc/profile/eligibility/eligibility_bloc.dart';
|
||||
import 'package:unit2/model/location/barangay.dart';
|
||||
import 'package:unit2/model/profile/voluntary_works.dart';
|
||||
|
||||
import '../../../../model/location/city.dart';
|
||||
import '../../../../model/location/country.dart';
|
||||
|
|
|
@ -23,3 +23,12 @@ class ShowEditAddressForm extends AddressEvent{
|
|||
class CallErrorState extends AddressEvent{
|
||||
|
||||
}
|
||||
|
||||
class AddAddress extends EligibilityEvent{
|
||||
final MainAdress address;
|
||||
final String token;
|
||||
final int profileId;
|
||||
const AddAddress({required this.address, required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [address,token,profileId];
|
||||
}
|
||||
|
|
|
@ -37,6 +37,15 @@ class AddAddressState extends AddressState {
|
|||
List<Object> get props => [countries, regions,];
|
||||
}
|
||||
|
||||
////AddedState
|
||||
class AddressAddedState extends AddressState{
|
||||
final Map<dynamic,dynamic> response;
|
||||
const AddressAddedState({required this.response});
|
||||
@override
|
||||
List<Object> get props => [response];
|
||||
|
||||
}
|
||||
|
||||
class EditAddressState extends AddressState{
|
||||
final MainAdress address;
|
||||
final List<Country> countries;
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:unit2/sevices/profile/volunatary_services.dart';
|
||||
import 'package:unit2/utils/profile_utilities.dart';
|
||||
|
||||
import '../../../model/location/city.dart';
|
||||
import '../../../model/location/country.dart';
|
||||
import '../../../model/location/provinces.dart';
|
||||
import '../../../model/location/region.dart';
|
||||
import '../../../model/profile/voluntary_works.dart';
|
||||
import '../../../model/utils/agency.dart';
|
||||
import '../../../model/utils/category.dart';
|
||||
import '../../../model/utils/position.dart';
|
||||
import '../../../utils/location_utilities.dart';
|
||||
|
||||
part 'voluntary_work_event.dart';
|
||||
part 'voluntary_work_state.dart';
|
||||
|
@ -16,27 +21,42 @@ part 'voluntary_work_state.dart';
|
|||
class VoluntaryWorkBloc extends Bloc<VoluntaryWorkEvent, VoluntaryWorkState> {
|
||||
VoluntaryWorkBloc() : super(VoluntaryWorkInitial()) {
|
||||
List<VoluntaryWork> voluntaryWorks = [];
|
||||
List<Country> globalCountries=[];
|
||||
List<Category> agencyCategory = [];
|
||||
List<Region> globalRegions=[];
|
||||
List<Position> agencyPositions = [];
|
||||
List<Agency> agencies = [];
|
||||
////Get Voluntary Works
|
||||
on<GetVoluntarWorks>((event, emit) async{
|
||||
List<Country> globalCountries = [];
|
||||
List<Category> agencyCategory = [];
|
||||
List<Region> globalRegions = [];
|
||||
List<Position> agencyPositions = [];
|
||||
List<Agency> agencies = [];
|
||||
List<Province> provinces = [];
|
||||
List<CityMunicipality> cities = [];
|
||||
///// current
|
||||
Position currentPosition;
|
||||
Agency currentAgency;
|
||||
Region? currentRegion;
|
||||
Country currentCountry;
|
||||
Province? currentProvince;
|
||||
CityMunicipality? currentCity;
|
||||
////Get Voluntary Works
|
||||
on<GetVoluntarWorks>((event, emit) async {
|
||||
emit(VoluntaryWorkLoadingState());
|
||||
try{
|
||||
List<VoluntaryWork> works = await VoluntaryService.instance.getVoluntaryWorks(event.profileId, event.token);
|
||||
voluntaryWorks = works;
|
||||
emit(VoluntaryWorkLoadedState(voluntaryWorks: voluntaryWorks));
|
||||
}catch(e){
|
||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||
}
|
||||
try {
|
||||
List<VoluntaryWork> works = await VoluntaryService.instance
|
||||
.getVoluntaryWorks(event.profileId, event.token);
|
||||
voluntaryWorks = works;
|
||||
emit(VoluntaryWorkLoadedState(voluntaryWorks: voluntaryWorks));
|
||||
} catch (e) {
|
||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
//// Load
|
||||
on<LoadVoluntaryWorks>((event, emit) {
|
||||
emit(VoluntaryWorkLoadedState(voluntaryWorks: voluntaryWorks));
|
||||
});
|
||||
//// Show Add form Event
|
||||
on<ShowAddVoluntaryWorks>((event,emit)async{
|
||||
try{
|
||||
on<ShowAddVoluntaryWorks>((event, emit) async {
|
||||
try {
|
||||
emit(VoluntaryWorkLoadingState());
|
||||
if (agencyPositions.isEmpty) {
|
||||
//// POSITIONS
|
||||
if (agencyPositions.isEmpty) {
|
||||
List<Position> positions =
|
||||
await ProfileUtilities.instance.getAgencyPosition();
|
||||
agencyPositions = positions;
|
||||
|
@ -55,12 +75,177 @@ class VoluntaryWorkBloc extends Bloc<VoluntaryWorkEvent, VoluntaryWorkState> {
|
|||
await ProfileUtilities.instance.agencyCategory();
|
||||
agencyCategory = categoryAgencies;
|
||||
}
|
||||
emit(AddVoluntaryWorkState(agencies: agencies,positions: agencyPositions,agencyCategory: agencyCategory,regions: globalRegions,countries: globalCountries));
|
||||
|
||||
////regions
|
||||
if (globalRegions.isEmpty) {
|
||||
List<Region> regions = await LocationUtils.instance.getRegions();
|
||||
globalRegions = regions;
|
||||
}
|
||||
|
||||
//// country
|
||||
if (globalCountries.isEmpty) {
|
||||
List<Country> countries = await LocationUtils.instance.getCountries();
|
||||
globalCountries = countries;
|
||||
}
|
||||
|
||||
emit(AddVoluntaryWorkState(
|
||||
agencies: agencies,
|
||||
positions: agencyPositions,
|
||||
agencyCategory: agencyCategory,
|
||||
regions: globalRegions,
|
||||
countries: globalCountries));
|
||||
} catch (e) {
|
||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
on<ShowErrorState>((event, emit) {
|
||||
emit(VoluntaryWorkErrorState(message: event.message));
|
||||
});
|
||||
//// Add Voluntary Work
|
||||
on<AddVoluntaryWork>((event, emit) async {
|
||||
try {
|
||||
Map<dynamic, dynamic> status = await VoluntaryService.instance.add(
|
||||
voluntaryWork: event.work,
|
||||
profileId: event.profileId,
|
||||
token: event.token);
|
||||
if (status['success']) {
|
||||
VoluntaryWork work = VoluntaryWork.fromJson(status['data']);
|
||||
voluntaryWorks.add(work);
|
||||
emit(VoluntaryWorkAddedState(response: status));
|
||||
} else {
|
||||
emit(VoluntaryWorkAddedState(response: status));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
////Update
|
||||
on<UpdateVolunataryWork>((event, emit) async {
|
||||
final DateFormat formatter = DateFormat('yyyy-MM-dd');
|
||||
try{
|
||||
Map<dynamic, dynamic> status = await VoluntaryService.instance.update(
|
||||
voluntaryWork: event.work,
|
||||
profileId: event.profileId,
|
||||
token: event.token,
|
||||
oldPosId: event.oldPosId,
|
||||
oldAgencyId: event.oldAgencyId,
|
||||
oldFromDate: formatter.format(DateTime.parse(event.oldFromDate)));
|
||||
if (status['success']) {
|
||||
VoluntaryWork work = VoluntaryWork.fromJson(status['data']);
|
||||
voluntaryWorks.removeWhere((VoluntaryWork element) =>
|
||||
element.position!.id == event.oldPosId &&
|
||||
element.agency!.id == event.oldAgencyId &&
|
||||
element.fromDate.toString() == event.oldFromDate.toString());
|
||||
voluntaryWorks.add(work);
|
||||
emit(VoluntaryWorkEditedState(response: status));
|
||||
} else {
|
||||
emit(VoluntaryWorkEditedState(response: status));
|
||||
}
|
||||
}catch(e){
|
||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||
}
|
||||
});on<ShowErrorState>((event,emit){
|
||||
emit(VoluntaryWorkErrorState(message: event.message));
|
||||
});
|
||||
/////SHOW EDIT FORM
|
||||
on<ShowEditVoluntaryWorks>((event, emit) async {
|
||||
try {
|
||||
//// POSITIONS
|
||||
if (agencyPositions.isEmpty) {
|
||||
List<Position> positions =
|
||||
await ProfileUtilities.instance.getAgencyPosition();
|
||||
agencyPositions = positions;
|
||||
}
|
||||
currentPosition = event.work.position!;
|
||||
|
||||
/////AGENCIES------------------------------------------
|
||||
if (agencies.isEmpty) {
|
||||
List<Agency> newAgencies =
|
||||
await ProfileUtilities.instance.getAgecies();
|
||||
agencies = newAgencies;
|
||||
}
|
||||
currentAgency = event.work.agency!;
|
||||
|
||||
/////Category Agency------------------------------------------
|
||||
if (agencyCategory.isEmpty) {
|
||||
List<Category> categoryAgencies =
|
||||
await ProfileUtilities.instance.agencyCategory();
|
||||
agencyCategory = categoryAgencies;
|
||||
}
|
||||
|
||||
////regions
|
||||
if (globalRegions.isEmpty) {
|
||||
List<Region> regions = await LocationUtils.instance.getRegions();
|
||||
globalRegions = regions;
|
||||
}
|
||||
|
||||
//// country
|
||||
if (globalCountries.isEmpty) {
|
||||
List<Country> countries = await LocationUtils.instance.getCountries();
|
||||
globalCountries = countries;
|
||||
}
|
||||
currentCountry = globalCountries.firstWhere((Country country) =>
|
||||
event.work.address!.country!.code == country.code);
|
||||
////If overseas
|
||||
if (!event.isOverseas) {
|
||||
//// if not overseas
|
||||
currentRegion = globalRegions.firstWhere((Region region) =>
|
||||
event.work.address!.cityMunicipality!.province!.region!.code ==
|
||||
region.code);
|
||||
provinces = await LocationUtils.instance
|
||||
.getProvinces(regionCode: currentRegion!.code.toString());
|
||||
currentProvince = provinces.firstWhere((Province province) =>
|
||||
event.work.address!.cityMunicipality!.province!.code ==
|
||||
province.code);
|
||||
|
||||
cities = await LocationUtils.instance
|
||||
.getCities(code: currentProvince!.code.toString());
|
||||
|
||||
currentCity = cities.firstWhere((CityMunicipality cityMunicipality) =>
|
||||
event.work.address!.cityMunicipality!.code ==
|
||||
cityMunicipality.code);
|
||||
}
|
||||
emit(EditVoluntaryWorks(
|
||||
overseas: event.isOverseas,
|
||||
agencies: agencies,
|
||||
agencyCategory: agencyCategory,
|
||||
cities: cities,
|
||||
countries: globalCountries,
|
||||
positions: agencyPositions,
|
||||
provinces: provinces,
|
||||
regions: globalRegions,
|
||||
work: event.work,
|
||||
currentAgency: currentAgency,
|
||||
currentCity: currentCity,
|
||||
currentCountry: currentCountry,
|
||||
currentPosition: currentPosition,
|
||||
currentProvince: currentProvince,
|
||||
currentRegion: currentRegion));
|
||||
} catch (e) {
|
||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
//// Delete
|
||||
on<DeleteVoluntaryWork>((event, emit) async {
|
||||
try {
|
||||
final DateFormat formatter = DateFormat('yyyy-MM-dd');
|
||||
|
||||
final bool success = await VoluntaryService.instance.delete(
|
||||
agencyId: event.work.agency!.id!,
|
||||
positionId: event.work.position!.id!,
|
||||
fromDate: formatter.format(event.work.fromDate!),
|
||||
token: event.token,
|
||||
profileId: event.profileId);
|
||||
if (success) {
|
||||
voluntaryWorks.removeWhere((VoluntaryWork element) =>
|
||||
element.position!.id == event.work.position!.id &&
|
||||
element.agency!.id == event.work.agency!.id &&
|
||||
element.fromDate == event.work.fromDate);
|
||||
emit(VoluntaryWorkDeletedState(success: success));
|
||||
} else {
|
||||
emit(VoluntaryWorkDeletedState(success: success));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,18 +7,68 @@ abstract class VoluntaryWorkEvent extends Equatable {
|
|||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class GetVoluntarWorks extends VoluntaryWorkEvent{
|
||||
class GetVoluntarWorks extends VoluntaryWorkEvent {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const GetVoluntarWorks({required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [profileId,token];
|
||||
}
|
||||
class ShowAddVoluntaryWorks extends VoluntaryWorkEvent{
|
||||
|
||||
@override
|
||||
List<Object> get props => [profileId, token];
|
||||
}
|
||||
|
||||
class ShowErrorState extends VoluntaryWorkEvent{
|
||||
class ShowAddVoluntaryWorks extends VoluntaryWorkEvent {}
|
||||
|
||||
class ShowEditVoluntaryWorks extends VoluntaryWorkEvent {
|
||||
final VoluntaryWork work;
|
||||
final int profileId;
|
||||
final String token;
|
||||
final bool isOverseas;
|
||||
// final int oldPosId;
|
||||
// final int oldAgencyId;
|
||||
// final String oldFromDate;
|
||||
const ShowEditVoluntaryWorks(
|
||||
{required this.profileId,
|
||||
required this.token,
|
||||
required this.work,
|
||||
// required this.oldAgencyId,
|
||||
// required this.oldFromDate,
|
||||
// required this.oldPosId,
|
||||
required this.isOverseas});
|
||||
@override
|
||||
List<Object> get props => [profileId, token, work];
|
||||
}
|
||||
|
||||
class LoadVoluntaryWorks extends VoluntaryWorkEvent {}
|
||||
|
||||
class ShowErrorState extends VoluntaryWorkEvent {
|
||||
final String message;
|
||||
const ShowErrorState({required this.message});
|
||||
}
|
||||
|
||||
class UpdateVolunataryWork extends VoluntaryWorkEvent{
|
||||
final int oldPosId;
|
||||
final int oldAgencyId;
|
||||
final String oldFromDate;
|
||||
final VoluntaryWork work;
|
||||
final int profileId;
|
||||
final String token;
|
||||
const UpdateVolunataryWork({required this.oldAgencyId, required this.oldFromDate, required this.oldPosId, required this.profileId, required this.token, required this.work});
|
||||
}
|
||||
class AddVoluntaryWork extends VoluntaryWorkEvent {
|
||||
final int profileId;
|
||||
final String token;
|
||||
final VoluntaryWork work;
|
||||
const AddVoluntaryWork(
|
||||
{required this.profileId, required this.token, required this.work});
|
||||
@override
|
||||
List<Object> get props => [profileId, token, work];
|
||||
}
|
||||
|
||||
class DeleteVoluntaryWork extends VoluntaryWorkEvent {
|
||||
final String token;
|
||||
final int profileId;
|
||||
final VoluntaryWork work;
|
||||
const DeleteVoluntaryWork(
|
||||
{required this.profileId, required this.token, required this.work});
|
||||
@override
|
||||
List<Object> get props => [profileId, token, work];
|
||||
}
|
||||
|
|
|
@ -26,8 +26,41 @@ class VoluntaryWorkErrorState extends VoluntaryWorkState{
|
|||
class VoluntaryWorkLoadingState extends VoluntaryWorkState{
|
||||
|
||||
}
|
||||
////Added State
|
||||
class VoluntaryWorkAddedState extends VoluntaryWorkState{
|
||||
final Map<dynamic,dynamic> response;
|
||||
const VoluntaryWorkAddedState({required this.response});
|
||||
@override
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
////Added State
|
||||
class VoluntaryWorkEditedState extends VoluntaryWorkState{
|
||||
final Map<dynamic,dynamic> response;
|
||||
const VoluntaryWorkEditedState({required this.response});
|
||||
@override
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
class EditVoluntaryWorks extends VoluntaryWorkState{
|
||||
final VoluntaryWork work;
|
||||
final List<Position> positions;
|
||||
final List<Agency> agencies;
|
||||
final List<Category> agencyCategory;
|
||||
final List<Country> countries;
|
||||
final List<Region> regions;
|
||||
final List<Province> provinces;
|
||||
final List<CityMunicipality> cities;
|
||||
final Position currentPosition;
|
||||
final Agency currentAgency;
|
||||
final Region? currentRegion;
|
||||
final Country currentCountry;
|
||||
final Province? currentProvince;
|
||||
final CityMunicipality? currentCity;
|
||||
final bool overseas;
|
||||
const EditVoluntaryWorks({required this.agencies, required this.agencyCategory, required this.cities, required this.countries,required this.positions, required this.provinces, required this.regions, required this.work, required this.currentAgency, required this.currentCity,required this.currentCountry, required this.currentPosition, required this.currentProvince, required this.currentRegion,required this.overseas});
|
||||
|
||||
}
|
||||
|
||||
////Adding State
|
||||
class AddVoluntaryWorkState extends VoluntaryWorkState{
|
||||
final List<Position> positions;
|
||||
final List<Agency> agencies;
|
||||
|
@ -37,4 +70,11 @@ class AddVoluntaryWorkState extends VoluntaryWorkState{
|
|||
const AddVoluntaryWorkState({required this.agencies,required this.countries, required this.positions, required this.regions,required this.agencyCategory});
|
||||
@override
|
||||
List<Object> get props => [positions,agencies,countries,regions];
|
||||
}
|
||||
}
|
||||
//// Deleted State
|
||||
class VoluntaryWorkDeletedState extends VoluntaryWorkState{
|
||||
final bool success;
|
||||
const VoluntaryWorkDeletedState({required this.success});
|
||||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
||||
|
|
|
@ -29,12 +29,12 @@ class VoluntaryWork {
|
|||
final DateTime? toDate;
|
||||
final Position? position;
|
||||
final DateTime? fromDate;
|
||||
final int? totalHours;
|
||||
final double? totalHours;
|
||||
|
||||
factory VoluntaryWork.fromJson(Map<String, dynamic> json) => VoluntaryWork(
|
||||
agency: json["agency"] == null ? null : Agency.fromJson(json["agency"]),
|
||||
address: json["address"] == null ? null : Address.fromJson(json["address"]),
|
||||
toDate: json["to_date"] == null? null : DateTime.parse(json['to_data']),
|
||||
toDate: json["to_date"] == null? null : DateTime.parse(json['to_date']),
|
||||
position: json["position"] == null ? null : Position.fromJson(json["position"]),
|
||||
fromDate: json["from_date"] == null ? null : DateTime.parse(json["from_date"]),
|
||||
totalHours: json["total_hours"],
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
|
|||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:unit2/bloc/profile/primary_information/address/address_bloc.dart';
|
||||
import 'package:unit2/model/location/address_category.dart';
|
||||
import 'package:unit2/model/utils/category.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
|
||||
|
@ -38,6 +39,8 @@ class _AddAddressScreenState extends State<AddAddressScreen> {
|
|||
bool cityCall = false;
|
||||
bool barangayCall = false;
|
||||
////selected
|
||||
AddressCategory? selectedAddressCategory;
|
||||
String? selectedAreaClass;
|
||||
Region? selectedRegion;
|
||||
Province? selectedProvince;
|
||||
CityMunicipality? selectedMunicipality;
|
||||
|
@ -54,7 +57,7 @@ class _AddAddressScreenState extends State<AddAddressScreen> {
|
|||
const Area(value: "Metropolis", group: 1),
|
||||
const Area(value: "Megacity", group: 1),
|
||||
];
|
||||
final List<String> category = ["Permanent", "Residential", "Birthplace"];
|
||||
final List<AddressCategory> category = [AddressCategory(id: 1, name: "Permanent", type: "home"), AddressCategory(id: 2, name: "Residential", type: "home"), AddressCategory(id: 3, name: "Birthplace", type: "home")];
|
||||
List<Province>? provinces;
|
||||
List<CityMunicipality>? citymuns;
|
||||
List<Barangay>? barangays;
|
||||
|
@ -75,17 +78,17 @@ class _AddAddressScreenState extends State<AddAddressScreen> {
|
|||
child: Column(
|
||||
children: [
|
||||
//// category
|
||||
FormBuilderDropdown<String>(
|
||||
FormBuilderDropdown(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
decoration:
|
||||
normalTextFieldStyle("Category*", "Category"),
|
||||
name: "category",
|
||||
onChanged: (String? category) {},
|
||||
items: category.map<DropdownMenuItem<String>>(
|
||||
(String category) {
|
||||
onChanged: (AddressCategory? category) {},
|
||||
items: category.map<DropdownMenuItem<AddressCategory>>(
|
||||
(AddressCategory category) {
|
||||
return DropdownMenuItem(
|
||||
value: category, child: Text(category));
|
||||
value: category, child: Text(category.name!));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
|
@ -97,7 +100,9 @@ class _AddAddressScreenState extends State<AddAddressScreen> {
|
|||
decoration: normalTextFieldStyle(
|
||||
"Area class *", "Area class"),
|
||||
name: "area_class",
|
||||
onChanged: (Area? area) {},
|
||||
onChanged: (Area? area) {
|
||||
selectedAreaClass = area!.value;
|
||||
},
|
||||
items: areaClass
|
||||
.map<DropdownMenuItem<Area>>((Area area) {
|
||||
return area.group == 0
|
||||
|
|
|
@ -448,6 +448,9 @@ class _AddEducationScreenState extends State<AddEducationScreen> {
|
|||
if (!graduated) {
|
||||
unitsEarned = int.parse(formKey
|
||||
.currentState!.value['units_earned']);
|
||||
yearGraduated.text = '';
|
||||
}else{
|
||||
|
||||
}
|
||||
////education
|
||||
Education newEducation = Education(
|
||||
|
|
|
@ -92,7 +92,6 @@ class _EditEducationScreenState extends State<EditEducationScreen> {
|
|||
}
|
||||
fromController.text = state.educationalBackground.periodFrom!;
|
||||
untilController.text = state.educationalBackground.periodTo!;
|
||||
////honors
|
||||
|
||||
////get all honors
|
||||
valueItemHonorList = state.honors.map((Honor honor) {
|
||||
|
@ -147,6 +146,10 @@ class _EditEducationScreenState extends State<EditEducationScreen> {
|
|||
////school
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return SearchField(
|
||||
suggestionAction: SuggestionAction.next,
|
||||
onSubmit: (p0) {
|
||||
schoolFocusNode.unfocus();
|
||||
},
|
||||
controller: currentSchoolController,
|
||||
itemHeight: 50,
|
||||
suggestionsDecoration: box1(),
|
||||
|
@ -171,7 +174,9 @@ class _EditEducationScreenState extends State<EditEducationScreen> {
|
|||
searchInputDecoration:
|
||||
normalTextFieldStyle("School *", "").copyWith(
|
||||
suffixIcon:
|
||||
const Icon(Icons.arrow_drop_down)),
|
||||
GestureDetector(child: const Icon(Icons.arrow_drop_down),onTap: (){
|
||||
schoolFocusNode.unfocus();
|
||||
},)),
|
||||
onSuggestionTap: (school) {
|
||||
setState(() {
|
||||
selectedSchool = school.item;
|
||||
|
@ -497,10 +502,12 @@ class _EditEducationScreenState extends State<EditEducationScreen> {
|
|||
selectedLevel!.value == "Junior High" ||
|
||||
selectedLevel!.value == "Senior High") {
|
||||
selectedProgram = null;
|
||||
}else{
|
||||
selectedProgram ??= state.educationalBackground.education!.course;
|
||||
} else {
|
||||
selectedProgram ??= state
|
||||
.educationalBackground.education!.course;
|
||||
}
|
||||
selectedSchool ??= state.educationalBackground.education!.school;
|
||||
selectedSchool ??=
|
||||
state.educationalBackground.education!.school;
|
||||
////education
|
||||
Education newEducation = Education(
|
||||
id: null,
|
||||
|
|
|
@ -18,6 +18,7 @@ import 'package:unit2/widgets/error_state.dart';
|
|||
|
||||
import '../../../bloc/profile/education/education_bloc.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
import '../../../widgets/Leadings/close_leading.dart';
|
||||
import 'education/edit_modal.dart';
|
||||
|
||||
class EducationScreen extends StatelessWidget {
|
||||
|
@ -32,11 +33,15 @@ class EducationScreen extends StatelessWidget {
|
|||
title: const Text(educationScreenTitle),
|
||||
centerTitle: true,
|
||||
backgroundColor: primary,
|
||||
actions: [
|
||||
actions: context.watch<EducationBloc>().state is EducationalBackgroundLoadedState?[
|
||||
AddLeading(onPressed: () {
|
||||
context.read<EducationBloc>().add(ShowAddEducationForm());
|
||||
})
|
||||
],
|
||||
]:(context.watch<EducationBloc>().state is AddEducationState || context.watch<EducationBloc>().state is EditEducationState)?[
|
||||
CloseLeading(onPressed: () {
|
||||
context.read<EducationBloc>().add( LoadEducations());
|
||||
})
|
||||
]:[],
|
||||
),
|
||||
//userbloc
|
||||
body: ProgressHUD(
|
||||
|
|
|
@ -398,11 +398,11 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
|
|||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
//rating
|
||||
////rating
|
||||
double? rate = rating == null
|
||||
? null
|
||||
: double.parse(rating!);
|
||||
//lisence
|
||||
////lisence
|
||||
String? licenseNumber = license;
|
||||
CityMunicipality? cityMunicipality =
|
||||
selectedMunicipality;
|
||||
|
|
|
@ -0,0 +1,685 @@
|
|||
import 'package:date_time_picker/date_time_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter/src/widgets/placeholder.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:searchfield/searchfield.dart';
|
||||
import 'package:unit2/bloc/profile/voluntary_works/voluntary_work_bloc.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
|
||||
import '../../../../model/location/barangay.dart';
|
||||
import '../../../../model/location/city.dart';
|
||||
import '../../../../model/location/country.dart';
|
||||
import '../../../../model/location/provinces.dart';
|
||||
import '../../../../model/location/region.dart';
|
||||
import '../../../../model/profile/voluntary_works.dart';
|
||||
import '../../../../model/utils/agency.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/location_utilities.dart';
|
||||
import '../../../../utils/text_container.dart';
|
||||
import '../../shared/add_for_empty_search.dart';
|
||||
|
||||
class AddVoluntaryWorkScreen extends StatefulWidget {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const AddVoluntaryWorkScreen(
|
||||
{super.key, required this.profileId, required this.token});
|
||||
|
||||
@override
|
||||
State<AddVoluntaryWorkScreen> createState() => _AddVoluntaryWorkScreenState();
|
||||
}
|
||||
|
||||
class _AddVoluntaryWorkScreenState extends State<AddVoluntaryWorkScreen> {
|
||||
final formKey = GlobalKey<FormBuilderState>();
|
||||
////controllers
|
||||
final addPositionController = TextEditingController();
|
||||
final addAgencyController = TextEditingController();
|
||||
final toDateController = TextEditingController();
|
||||
final fromDateController = TextEditingController();
|
||||
////focus nodes
|
||||
final positionFocusNode = FocusNode();
|
||||
final agencyFocusNode = FocusNode();
|
||||
final agencyCategoryFocusNode = FocusNode();
|
||||
////booleans
|
||||
bool showAgency = false;
|
||||
bool showIsPrivateRadio = false;
|
||||
bool currentlyInvolved = false;
|
||||
bool overseas = false;
|
||||
bool provinceCall = false;
|
||||
bool cityCall = false;
|
||||
bool isPrivate = false;
|
||||
////Lists
|
||||
List<Province>? provinces;
|
||||
List<CityMunicipality>? citymuns;
|
||||
////Selected
|
||||
Position? selectedPosition;
|
||||
Agency? selectedAgency;
|
||||
Category? selectedCategoty;
|
||||
Region? selectedRegion;
|
||||
Province? selectedProvince;
|
||||
CityMunicipality? selectedMunicipality;
|
||||
Country? selectedCountry;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<VoluntaryWorkBloc, VoluntaryWorkState>(
|
||||
builder: (context, state) {
|
||||
if (state is AddVoluntaryWorkState) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 18),
|
||||
child: FormBuilder(
|
||||
key: formKey,
|
||||
child: ListView(
|
||||
children: [
|
||||
////POSITIONS
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return SearchField(
|
||||
itemHeight: 50,
|
||||
suggestionsDecoration: box1(),
|
||||
suggestions: state.positions
|
||||
.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: GestureDetector(
|
||||
child: const Icon(Icons.arrow_drop_down),
|
||||
onTap: () => positionFocusNode.unfocus(),
|
||||
)),
|
||||
onSuggestionTap: (position) {
|
||||
setState(() {
|
||||
selectedPosition = position.item;
|
||||
positionFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
////EMPTY WIDGET
|
||||
emptyWidget: EmptyWidget(
|
||||
title: "Add Position",
|
||||
controller: addPositionController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Position newAgencyPosition = Position(
|
||||
id: null,
|
||||
title: addPositionController.text
|
||||
.toUpperCase());
|
||||
|
||||
state.positions.insert(0, newAgencyPosition);
|
||||
|
||||
addPositionController.text = "";
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}),
|
||||
validator: (position) {
|
||||
if (position!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
}),
|
||||
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"
|
||||
: agency.privateEntity ==
|
||||
false
|
||||
? "Government"
|
||||
: ""),
|
||||
)))
|
||||
.toList(),
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("Agency *", "")
|
||||
.copyWith(
|
||||
suffixIcon: GestureDetector(
|
||||
child: const Icon(
|
||||
Icons.arrow_drop_down,
|
||||
),
|
||||
onTap: () => agencyFocusNode.unfocus(),
|
||||
)),
|
||||
////SELETECTED
|
||||
onSuggestionTap: (agency) {
|
||||
setState(() {
|
||||
selectedAgency = agency.item;
|
||||
if (selectedAgency!.privateEntity == null) {
|
||||
showAgency = true;
|
||||
showIsPrivateRadio = true;
|
||||
} else {
|
||||
showAgency = false;
|
||||
showIsPrivateRadio = false;
|
||||
}
|
||||
agencyFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
emptyWidget: EmptyWidget(
|
||||
controller: addAgencyController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Agency newAgency = Agency(
|
||||
id: null,
|
||||
name: addAgencyController.text
|
||||
.toUpperCase(),
|
||||
category: null,
|
||||
privateEntity: null);
|
||||
state.agencies.insert(0, newAgency);
|
||||
|
||||
addAgencyController.text = "";
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
title: "Add Agency")),
|
||||
|
||||
SizedBox(
|
||||
height: showAgency ? 12 : 0,
|
||||
),
|
||||
////SHOW CATEGORY AGENCY
|
||||
SizedBox(
|
||||
child: showAgency
|
||||
? 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(() {
|
||||
selectedCategoty =
|
||||
agencyCategory.item;
|
||||
agencyCategoryFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("Category *", "")
|
||||
.copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down)),
|
||||
validator: (value) {
|
||||
if (value!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
)
|
||||
: const SizedBox(),
|
||||
),
|
||||
SizedBox(
|
||||
height: showIsPrivateRadio ? 12 : 0,
|
||||
),
|
||||
////PRVIATE SECTOR
|
||||
SizedBox(
|
||||
child: showIsPrivateRadio
|
||||
? FormBuilderSwitch(
|
||||
initialValue: false,
|
||||
title: Text(isPrivate ? "YES" : "NO"),
|
||||
decoration: normalTextFieldStyle(
|
||||
"Private Entity?",
|
||||
'Private Entity?'),
|
||||
|
||||
////onvhange private sector
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
isPrivate = value!;
|
||||
agencyCategoryFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
|
||||
name: 'isPrivate',
|
||||
validator:
|
||||
FormBuilderValidators.required(),
|
||||
)
|
||||
: const SizedBox()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// total hours
|
||||
FormBuilderTextField(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This Field is required"),
|
||||
name: "total_hours",
|
||||
keyboardType: TextInputType.number,
|
||||
decoration:
|
||||
normalTextFieldStyle("Total Hours*", "0"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////Currently Involved
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
FormBuilderSwitch(
|
||||
initialValue: currentlyInvolved,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
currentlyInvolved = value!;
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"Currently Involved?", 'Graduated?'),
|
||||
name: 'currently_involved',
|
||||
title:
|
||||
Text(currentlyInvolved ? "YES" : "NO"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
//// FROM DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: DateTimePicker(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
use24HourFormat: false,
|
||||
icon:
|
||||
const Icon(Icons.date_range),
|
||||
controller: fromDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
timeHintText:
|
||||
"Date of Examination/Conferment",
|
||||
decoration: normalTextFieldStyle(
|
||||
"From *", "From *")
|
||||
.copyWith(
|
||||
prefixIcon: const Icon(
|
||||
Icons.date_range,
|
||||
color: Colors.black87,
|
||||
)),
|
||||
initialValue: null,
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
//// TO DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: currentlyInvolved
|
||||
? TextFormField(
|
||||
enabled: false,
|
||||
initialValue: "PRESENT",
|
||||
style: const TextStyle(
|
||||
color: Colors.black45),
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"", "")
|
||||
.copyWith(),
|
||||
)
|
||||
: DateTimePicker(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
controller: toDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
decoration: normalTextFieldStyle(
|
||||
"To *", "To *")
|
||||
.copyWith(
|
||||
prefixIcon:
|
||||
const Icon(
|
||||
Icons.date_range,
|
||||
color:
|
||||
Colors.black87,
|
||||
),
|
||||
prefixText:
|
||||
currentlyInvolved
|
||||
? "PRESENT"
|
||||
: ""),
|
||||
initialValue: null,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// OVERSEAS
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
FormBuilderSwitch(
|
||||
initialValue: overseas,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
overseas = value!;
|
||||
});
|
||||
},
|
||||
decoration:
|
||||
normalTextFieldStyle("Overseas Address?", ''),
|
||||
name: 'overseas',
|
||||
title: Text(overseas ? "YES" : "NO"),
|
||||
),
|
||||
SizedBox(
|
||||
height: overseas == true ? 8 : 0,
|
||||
),
|
||||
SizedBox(
|
||||
child: overseas == false
|
||||
? Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////REGION DROPDOWN
|
||||
FormBuilderDropdown<Region?>(
|
||||
autovalidateMode: AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
onChanged: (Region? region) async {
|
||||
if (selectedRegion != region) {
|
||||
setState(() {
|
||||
provinceCall = true;
|
||||
});
|
||||
selectedRegion = region;
|
||||
getProvinces();
|
||||
}
|
||||
},
|
||||
initialValue: null,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Region*", "Region"),
|
||||
name: 'region',
|
||||
items: state.regions
|
||||
.map<DropdownMenuItem<Region>>(
|
||||
(Region region) {
|
||||
return DropdownMenuItem<Region>(
|
||||
value: region,
|
||||
child:
|
||||
Text(region.description!));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
//// PROVINCE DROPDOWN
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.transparent,
|
||||
inAsyncCall: provinceCall,
|
||||
child: DropdownButtonFormField<
|
||||
Province?>(
|
||||
autovalidateMode:
|
||||
AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator: (value) =>
|
||||
value == null
|
||||
? 'required'
|
||||
: null,
|
||||
isExpanded: true,
|
||||
value: selectedProvince,
|
||||
onChanged:
|
||||
(Province? province) {
|
||||
if (selectedProvince !=
|
||||
province) {
|
||||
setState(() {
|
||||
cityCall = true;
|
||||
});
|
||||
selectedProvince = province;
|
||||
getCities();
|
||||
}
|
||||
},
|
||||
items: provinces == null
|
||||
? []
|
||||
: provinces!.map<
|
||||
DropdownMenuItem<
|
||||
Province>>(
|
||||
(Province province) {
|
||||
return DropdownMenuItem(
|
||||
value: province,
|
||||
child: FittedBox(
|
||||
child: Text(province
|
||||
.description!),
|
||||
));
|
||||
}).toList(),
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Province*",
|
||||
"Province")),
|
||||
),
|
||||
),
|
||||
////CITY MUNICIPALITY
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.white,
|
||||
inAsyncCall: cityCall,
|
||||
child: DropdownButtonFormField<
|
||||
CityMunicipality>(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
isExpanded: true,
|
||||
onChanged:
|
||||
(CityMunicipality? city) {
|
||||
if (selectedMunicipality !=
|
||||
city) {
|
||||
selectedMunicipality = city;
|
||||
}
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"Municipality*",
|
||||
"Municipality"),
|
||||
value: selectedMunicipality,
|
||||
items: citymuns == null
|
||||
? []
|
||||
: citymuns!.map<
|
||||
DropdownMenuItem<
|
||||
CityMunicipality>>(
|
||||
(CityMunicipality c) {
|
||||
return DropdownMenuItem(
|
||||
value: c,
|
||||
child: Text(
|
||||
c.description!));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
//// COUNTRY DROPDOWN
|
||||
: SizedBox(
|
||||
height: 60,
|
||||
child: FormBuilderDropdown<Country>(
|
||||
initialValue: null,
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
items: state.countries
|
||||
.map<DropdownMenuItem<Country>>(
|
||||
(Country country) {
|
||||
return DropdownMenuItem<Country>(
|
||||
value: country,
|
||||
child: FittedBox(
|
||||
child: Text(country.name!)));
|
||||
}).toList(),
|
||||
name: 'country',
|
||||
decoration: normalTextFieldStyle(
|
||||
"Country*", "Country"),
|
||||
onChanged: (Country? value) {
|
||||
selectedCountry = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: blockSizeVertical * 8,
|
||||
)),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
if (formKey.currentState!.saveAndValidate()) {
|
||||
Country country = selectedCountry ??=
|
||||
Country(
|
||||
id: 175,
|
||||
name: 'Philippines',
|
||||
code: 'PH');
|
||||
Address address = Address(
|
||||
barangay: null,
|
||||
id: null,
|
||||
addressCategory: null,
|
||||
addressClass: null,
|
||||
cityMunicipality: selectedMunicipality,
|
||||
country: country);
|
||||
if (selectedCategoty != null) {
|
||||
selectedAgency = Agency(
|
||||
id: selectedAgency?.id,
|
||||
name: selectedAgency!.name,
|
||||
category: selectedCategoty,
|
||||
privateEntity: isPrivate);
|
||||
}
|
||||
VoluntaryWork work = VoluntaryWork(
|
||||
////address
|
||||
address: address,
|
||||
//// agency
|
||||
agency: selectedAgency,
|
||||
////
|
||||
position: selectedPosition,
|
||||
////total hours
|
||||
totalHours: double.parse(formKey
|
||||
.currentState!.value["total_hours"]),
|
||||
////to date
|
||||
toDate: toDateController.text.isEmpty ||
|
||||
toDateController.text.toUpperCase() ==
|
||||
"PRESENT"
|
||||
? null
|
||||
: DateTime.parse(toDateController.text),
|
||||
////from date
|
||||
fromDate:
|
||||
DateTime.parse(fromDateController.text),
|
||||
);
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Loading...");
|
||||
context.read<VoluntaryWorkBloc>().add(
|
||||
AddVoluntaryWork(
|
||||
profileId: widget.profileId,
|
||||
token: widget.token,
|
||||
work: work));
|
||||
}
|
||||
},
|
||||
child: const Text(submit)),
|
||||
)
|
||||
],
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const Placeholder();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> getProvinces() async {
|
||||
try {
|
||||
List<Province> newProvinces = await LocationUtils.instance
|
||||
.getProvinces(regionCode: selectedRegion!.code.toString());
|
||||
setState(() {
|
||||
provinces = newProvinces;
|
||||
selectedProvince = provinces![0];
|
||||
provinceCall = false;
|
||||
cityCall = true;
|
||||
getCities();
|
||||
});
|
||||
} catch (e) {
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(ShowErrorState(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getCities() async {
|
||||
try {
|
||||
List<CityMunicipality> newCities = await LocationUtils.instance
|
||||
.getCities(code: selectedProvince!.code.toString());
|
||||
citymuns = newCities;
|
||||
setState(() {
|
||||
selectedMunicipality = newCities[0];
|
||||
cityCall = false;
|
||||
});
|
||||
} catch (e) {
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(ShowErrorState(message: e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,754 @@
|
|||
import 'package:date_time_picker/date_time_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter/src/widgets/placeholder.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:searchfield/searchfield.dart';
|
||||
import 'package:unit2/bloc/profile/voluntary_works/voluntary_work_bloc.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
import 'package:unit2/utils/global_context.dart';
|
||||
|
||||
import '../../../../model/location/barangay.dart';
|
||||
import '../../../../model/location/city.dart';
|
||||
import '../../../../model/location/country.dart';
|
||||
import '../../../../model/location/provinces.dart';
|
||||
import '../../../../model/location/region.dart';
|
||||
import '../../../../model/profile/voluntary_works.dart';
|
||||
import '../../../../model/utils/agency.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/location_utilities.dart';
|
||||
import '../../../../utils/text_container.dart';
|
||||
import '../../shared/add_for_empty_search.dart';
|
||||
|
||||
class EditVoluntaryWorkScreen extends StatefulWidget {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const EditVoluntaryWorkScreen(
|
||||
{super.key, required this.profileId, required this.token});
|
||||
|
||||
@override
|
||||
State<EditVoluntaryWorkScreen> createState() =>
|
||||
_EditVoluntaryWorkScreenState();
|
||||
}
|
||||
|
||||
class _EditVoluntaryWorkScreenState extends State<EditVoluntaryWorkScreen> {
|
||||
final formKey = GlobalKey<FormBuilderState>();
|
||||
////controllers
|
||||
final addPositionController = TextEditingController();
|
||||
final addAgencyController = TextEditingController();
|
||||
final toDateController = TextEditingController();
|
||||
final fromDateController = TextEditingController();
|
||||
final positionController = TextEditingController();
|
||||
final agencyController = TextEditingController();
|
||||
////focus nodes
|
||||
final positionFocusNode = FocusNode();
|
||||
final agencyFocusNode = FocusNode();
|
||||
final agencyCategoryFocusNode = FocusNode();
|
||||
////booleans
|
||||
bool showAgency = false;
|
||||
bool showIsPrivateRadio = false;
|
||||
bool currentlyInvolved = false;
|
||||
bool overseas = false;
|
||||
bool provinceCall = false;
|
||||
bool cityCall = false;
|
||||
bool isPrivate = false;
|
||||
////Lists
|
||||
List<Province>? provinces;
|
||||
List<CityMunicipality>? citymuns;
|
||||
|
||||
////Selected
|
||||
Position? selectedPosition;
|
||||
Agency? selectedAgency;
|
||||
Category? selectedCategoty;
|
||||
Region? selectedRegion;
|
||||
Province? selectedProvince;
|
||||
CityMunicipality? selectedMunicipality;
|
||||
Country? selectedCountry;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<VoluntaryWorkBloc, VoluntaryWorkState>(
|
||||
buildWhen: (previous, current) {
|
||||
return false;
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is EditVoluntaryWorks) {
|
||||
////config
|
||||
String? todate = state.work.toDate?.toString();
|
||||
provinces = state.provinces;
|
||||
citymuns = state.cities;
|
||||
positionController.text = state.currentPosition.title!;
|
||||
agencyController.text = state.currentAgency.name!;
|
||||
fromDateController.text = state.work.fromDate.toString();
|
||||
toDateController.text = todate ??= "";
|
||||
currentlyInvolved = todate.isEmpty || todate == "null" ? true : false;
|
||||
overseas = state.overseas;
|
||||
selectedCountry = state.currentCountry;
|
||||
selectedPosition = state.currentPosition;
|
||||
selectedAgency = state.currentAgency;
|
||||
selectedRegion = state.currentRegion;
|
||||
selectedProvince = state.currentProvince;
|
||||
selectedMunicipality = state.currentCity;
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 18),
|
||||
child: FormBuilder(
|
||||
key: formKey,
|
||||
child: ListView(
|
||||
children: [
|
||||
////POSITIONS
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return SearchField(
|
||||
controller: positionController,
|
||||
itemHeight: 50,
|
||||
suggestionsDecoration: box1(),
|
||||
suggestions: state.positions
|
||||
.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: GestureDetector(
|
||||
child: const Icon(Icons.arrow_drop_down),
|
||||
onTap: () => positionFocusNode.unfocus(),
|
||||
)),
|
||||
onSuggestionTap: (position) {
|
||||
setState(() {
|
||||
selectedPosition = position.item;
|
||||
positionFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
////EMPTY WIDGET
|
||||
emptyWidget: EmptyWidget(
|
||||
title: "Add Position",
|
||||
controller: addPositionController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Position newAgencyPosition = Position(
|
||||
id: null,
|
||||
title: addPositionController.text
|
||||
.toUpperCase());
|
||||
|
||||
state.positions.insert(0, newAgencyPosition);
|
||||
|
||||
addPositionController.text = "";
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}),
|
||||
validator: (position) {
|
||||
if (position!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////AGENCY
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
SearchField(
|
||||
controller: agencyController,
|
||||
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"
|
||||
: agency.privateEntity ==
|
||||
false
|
||||
? "Government"
|
||||
: ""),
|
||||
)))
|
||||
.toList(),
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("Agency *", "")
|
||||
.copyWith(
|
||||
suffixIcon: GestureDetector(
|
||||
child: const Icon(
|
||||
Icons.arrow_drop_down,
|
||||
),
|
||||
onTap: () => agencyFocusNode.unfocus(),
|
||||
)),
|
||||
////SELETECTED
|
||||
onSuggestionTap: (agency) {
|
||||
setState(() {
|
||||
selectedAgency = agency.item;
|
||||
if (selectedAgency!.privateEntity == null) {
|
||||
showAgency = true;
|
||||
showIsPrivateRadio = true;
|
||||
} else {
|
||||
showAgency = false;
|
||||
showIsPrivateRadio = false;
|
||||
}
|
||||
agencyFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
emptyWidget: EmptyWidget(
|
||||
controller: addAgencyController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Agency newAgency = Agency(
|
||||
id: null,
|
||||
name: addAgencyController.text
|
||||
.toUpperCase(),
|
||||
category: null,
|
||||
privateEntity: null);
|
||||
state.agencies.insert(0, newAgency);
|
||||
|
||||
addAgencyController.text = "";
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
title: "Add Agency")),
|
||||
|
||||
SizedBox(
|
||||
height: showAgency ? 12 : 0,
|
||||
),
|
||||
////SHOW CATEGORY AGENCY
|
||||
SizedBox(
|
||||
child: showAgency
|
||||
? 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(() {
|
||||
selectedCategoty =
|
||||
agencyCategory.item;
|
||||
agencyCategoryFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("Category *", "")
|
||||
.copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down)),
|
||||
validator: (value) {
|
||||
if (value!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
)
|
||||
: const SizedBox(),
|
||||
),
|
||||
SizedBox(
|
||||
height: showIsPrivateRadio ? 12 : 0,
|
||||
),
|
||||
////PRVIATE SECTOR
|
||||
SizedBox(
|
||||
child: showIsPrivateRadio
|
||||
? FormBuilderSwitch(
|
||||
initialValue: false,
|
||||
title: Text(isPrivate ? "YES" : "NO"),
|
||||
decoration: normalTextFieldStyle(
|
||||
"Private Entity?",
|
||||
'Private Entity?'),
|
||||
|
||||
////onvhange private sector
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
isPrivate = value!;
|
||||
agencyCategoryFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
|
||||
name: 'isPrivate',
|
||||
validator:
|
||||
FormBuilderValidators.required(),
|
||||
)
|
||||
: const SizedBox()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// total hours
|
||||
FormBuilderTextField(
|
||||
initialValue: state.work.totalHours.toString(),
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This Field is required"),
|
||||
name: "total_hours",
|
||||
keyboardType: TextInputType.number,
|
||||
decoration:
|
||||
normalTextFieldStyle("Total Hours*", "0"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////Currently Involved
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
FormBuilderSwitch(
|
||||
initialValue: currentlyInvolved,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
currentlyInvolved = value!;
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"Currently Involved?", 'Graduated?'),
|
||||
name: 'currently_involved',
|
||||
title:
|
||||
Text(currentlyInvolved ? "YES" : "NO"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
//// FROM DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: DateTimePicker(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
use24HourFormat: false,
|
||||
icon:
|
||||
const Icon(Icons.date_range),
|
||||
controller: fromDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
timeHintText:
|
||||
"Date of Examination/Conferment",
|
||||
decoration: normalTextFieldStyle(
|
||||
"From *", "From *")
|
||||
.copyWith(
|
||||
prefixIcon: const Icon(
|
||||
Icons.date_range,
|
||||
color: Colors.black87,
|
||||
)),
|
||||
initialValue: null,
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
//// TO DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: currentlyInvolved
|
||||
? TextFormField(
|
||||
enabled: false,
|
||||
initialValue: "PRESENT",
|
||||
style: const TextStyle(
|
||||
color: Colors.black45),
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"", "")
|
||||
.copyWith(),
|
||||
)
|
||||
: DateTimePicker(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
controller: toDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
decoration: normalTextFieldStyle(
|
||||
"To *", "To *")
|
||||
.copyWith(
|
||||
prefixIcon:
|
||||
const Icon(
|
||||
Icons.date_range,
|
||||
color:
|
||||
Colors.black87,
|
||||
),
|
||||
prefixText:
|
||||
currentlyInvolved
|
||||
? "PRESENT"
|
||||
: ""),
|
||||
initialValue: null,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// OVERSEAS
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
FormBuilderSwitch(
|
||||
initialValue: overseas,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
overseas = value!;
|
||||
});
|
||||
},
|
||||
decoration:
|
||||
normalTextFieldStyle("Overseas Address?", ''),
|
||||
name: 'overseas',
|
||||
title: Text(overseas ? "YES" : "NO"),
|
||||
),
|
||||
SizedBox(
|
||||
height: overseas == true ? 8 : 0,
|
||||
),
|
||||
SizedBox(
|
||||
child: overseas == false
|
||||
? Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////REGION DROPDOWN
|
||||
DropdownButtonFormField<Region?>(
|
||||
isExpanded: true,
|
||||
autovalidateMode: AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
onChanged: (Region? region) async {
|
||||
if (selectedRegion != region) {
|
||||
setState(() {
|
||||
provinceCall = true;
|
||||
});
|
||||
selectedRegion = region;
|
||||
try {
|
||||
provinces = await LocationUtils
|
||||
.instance
|
||||
.getProvinces(
|
||||
regionCode:
|
||||
selectedRegion!.code
|
||||
.toString());
|
||||
selectedProvince =
|
||||
provinces![0];
|
||||
setState(() {
|
||||
provinceCall = false;
|
||||
cityCall = true;
|
||||
});
|
||||
try {
|
||||
citymuns = await LocationUtils
|
||||
.instance
|
||||
.getCities(
|
||||
code:
|
||||
selectedProvince!
|
||||
.code
|
||||
.toString());
|
||||
selectedMunicipality =
|
||||
citymuns![0];
|
||||
setState(() {
|
||||
cityCall = false;
|
||||
});
|
||||
} catch (e) {
|
||||
NavigationService.navigatorKey
|
||||
.currentContext
|
||||
?.read<
|
||||
VoluntaryWorkBloc>()
|
||||
.add(ShowErrorState(
|
||||
message:
|
||||
e.toString()));
|
||||
}
|
||||
} catch (e) {
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(ShowErrorState(
|
||||
message: e.toString()));
|
||||
}
|
||||
}
|
||||
},
|
||||
value: selectedRegion,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Region*", "Region"),
|
||||
items: state.regions
|
||||
.map<DropdownMenuItem<Region>>(
|
||||
(Region region) {
|
||||
return DropdownMenuItem<Region>(
|
||||
value: region,
|
||||
child:
|
||||
Text(region.description!));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
//// PROVINCE DROPDOWN
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.transparent,
|
||||
inAsyncCall: provinceCall,
|
||||
child: DropdownButtonFormField<
|
||||
Province?>(
|
||||
autovalidateMode:
|
||||
AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator: (value) =>
|
||||
value == null
|
||||
? 'required'
|
||||
: null,
|
||||
isExpanded: true,
|
||||
value: selectedProvince,
|
||||
onChanged:
|
||||
(Province? province) async {
|
||||
if (selectedProvince !=
|
||||
province) {
|
||||
setState(() {
|
||||
cityCall = true;
|
||||
});
|
||||
selectedProvince = province;
|
||||
try {
|
||||
citymuns = await LocationUtils
|
||||
.instance
|
||||
.getCities(
|
||||
code: selectedProvince!
|
||||
.code
|
||||
.toString());
|
||||
selectedMunicipality =
|
||||
citymuns![0];
|
||||
setState(() {
|
||||
cityCall = false;
|
||||
});
|
||||
} catch (e) {
|
||||
context
|
||||
.read<
|
||||
VoluntaryWorkBloc>()
|
||||
.add(ShowErrorState(
|
||||
message: e
|
||||
.toString()));
|
||||
}
|
||||
}
|
||||
},
|
||||
items: provinces == null
|
||||
? []
|
||||
: provinces!.map<
|
||||
DropdownMenuItem<
|
||||
Province>>(
|
||||
(Province province) {
|
||||
return DropdownMenuItem(
|
||||
value: province,
|
||||
child: FittedBox(
|
||||
child: Text(province
|
||||
.description!),
|
||||
));
|
||||
}).toList(),
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Province*",
|
||||
"Province")),
|
||||
),
|
||||
),
|
||||
////CITY MUNICIPALITY
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.white,
|
||||
inAsyncCall: cityCall,
|
||||
child: DropdownButtonFormField<
|
||||
CityMunicipality>(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
isExpanded: true,
|
||||
onChanged:
|
||||
(CityMunicipality? city) {
|
||||
if (selectedMunicipality !=
|
||||
city) {
|
||||
selectedMunicipality = city;
|
||||
}
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"Municipality*",
|
||||
"Municipality"),
|
||||
value: selectedMunicipality,
|
||||
items: citymuns == null
|
||||
? []
|
||||
: citymuns!.map<
|
||||
DropdownMenuItem<
|
||||
CityMunicipality>>(
|
||||
(CityMunicipality c) {
|
||||
return DropdownMenuItem(
|
||||
value: c,
|
||||
child: Text(
|
||||
c.description!));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
//// COUNTRY DROPDOWN
|
||||
: SizedBox(
|
||||
height: 60,
|
||||
child: DropdownButtonFormField<Country>(
|
||||
isExpanded: true,
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
items: state.countries
|
||||
.map<DropdownMenuItem<Country>>(
|
||||
(Country country) {
|
||||
return DropdownMenuItem<Country>(
|
||||
value: country,
|
||||
child: FittedBox(
|
||||
child: Text(country.name!)));
|
||||
}).toList(),
|
||||
value: selectedCountry,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Country*", "Country"),
|
||||
onChanged: (Country? value) {
|
||||
selectedCountry = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: blockSizeVertical * 8,
|
||||
)),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
if (formKey.currentState!.saveAndValidate()) {
|
||||
Address address;
|
||||
//// if not overseas
|
||||
if (!overseas) {
|
||||
address = Address(
|
||||
barangay: null,
|
||||
id: state.work.address?.id,
|
||||
addressCategory:
|
||||
state.work.address?.addressCategory,
|
||||
addressClass:
|
||||
state.work.address?.addressClass ,
|
||||
cityMunicipality: selectedMunicipality,
|
||||
country: selectedCountry);
|
||||
} else {
|
||||
////if overseas
|
||||
address = Address(
|
||||
barangay: null,
|
||||
id: state.work.address?.id,
|
||||
addressCategory:
|
||||
state.work.address?.addressCategory,
|
||||
addressClass:
|
||||
state.work.address?.addressClass,
|
||||
cityMunicipality: null,
|
||||
country: selectedCountry);
|
||||
}
|
||||
|
||||
if (selectedCategoty != null) {
|
||||
selectedAgency = Agency(
|
||||
id: selectedAgency?.id,
|
||||
name: selectedAgency!.name,
|
||||
category: selectedCategoty,
|
||||
privateEntity: isPrivate);
|
||||
}
|
||||
VoluntaryWork work = VoluntaryWork(
|
||||
////address
|
||||
address: address,
|
||||
//// agency
|
||||
agency: selectedAgency,
|
||||
////
|
||||
position: selectedPosition,
|
||||
////total hours
|
||||
totalHours: double.parse(formKey
|
||||
.currentState!.value["total_hours"]),
|
||||
////to date
|
||||
toDate: toDateController.text.isEmpty ||
|
||||
toDateController.text.toUpperCase() ==
|
||||
"PRESENT"
|
||||
? null
|
||||
: DateTime.parse(toDateController.text),
|
||||
////from date
|
||||
fromDate:
|
||||
DateTime.parse(fromDateController.text),
|
||||
);
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Loading...");
|
||||
context.read<VoluntaryWorkBloc>().add(
|
||||
UpdateVolunataryWork(
|
||||
oldAgencyId: state.work.agency!.id!,
|
||||
oldFromDate:
|
||||
state.work.fromDate.toString(),
|
||||
oldPosId: state.work.position!.id!,
|
||||
profileId: widget.profileId,
|
||||
token: widget.token,
|
||||
work: work));
|
||||
}
|
||||
},
|
||||
child: const Text(submit)),
|
||||
)
|
||||
],
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const Placeholder();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,34 +1,41 @@
|
|||
import 'package:app_popup_menu/app_popup_menu.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/screens/profile/components/work_history/voluntary_works/add_modal.dart';
|
||||
import 'package:unit2/screens/profile/components/voluntary_works/add_modal.dart';
|
||||
import 'package:unit2/screens/profile/components/voluntary_works/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';
|
||||
import 'package:unit2/widgets/Leadings/add_leading.dart';
|
||||
import 'package:unit2/widgets/empty_data.dart';
|
||||
import 'package:unit2/widgets/error_state.dart';
|
||||
|
||||
import '../../../bloc/profile/voluntary_works/voluntary_work_bloc.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
|
||||
class VolunataryWorkScreen extends StatelessWidget {
|
||||
const VolunataryWorkScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String? token;
|
||||
String? token;
|
||||
int? profileId;
|
||||
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text(voluntaryScreenTitle),
|
||||
backgroundColor: primary,
|
||||
actions: [AddLeading(onPressed: () {
|
||||
context.read<VoluntaryWorkBloc>().add(ShowAddVoluntaryWorks());
|
||||
})],
|
||||
actions: [
|
||||
AddLeading(onPressed: () {
|
||||
context.read<VoluntaryWorkBloc>().add(ShowAddVoluntaryWorks());
|
||||
})
|
||||
],
|
||||
),
|
||||
body: ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
|
@ -37,9 +44,8 @@ class VolunataryWorkScreen extends StatelessWidget {
|
|||
child: BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
if (state is UserLoggedIn) {
|
||||
token = state.userData!.user!.login!.token;
|
||||
profileId =
|
||||
state.userData!.user!.login!.user!.profileId;
|
||||
token = state.userData!.user!.login!.token;
|
||||
profileId = state.userData!.user!.login!.user!.profileId;
|
||||
return BlocBuilder<ProfileBloc, ProfileState>(
|
||||
builder: (context, state) {
|
||||
if (state is ProfileLoaded) {
|
||||
|
@ -51,10 +57,78 @@ class VolunataryWorkScreen extends StatelessWidget {
|
|||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
if (state is VoluntaryWorkLoadedState ||
|
||||
state is VoluntaryWorkErrorState|| state is AddVoluntaryWorkState) {
|
||||
state is VoluntaryWorkErrorState ||
|
||||
state is AddVoluntaryWorkState ||
|
||||
state is VoluntaryWorkAddedState ||
|
||||
state is VoluntaryWorkDeletedState ||
|
||||
state is EditVoluntaryWorks) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
//// Added State
|
||||
if (state is VoluntaryWorkAddedState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Adding Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(LoadVoluntaryWorks());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Adding Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(LoadVoluntaryWorks());
|
||||
});
|
||||
}
|
||||
}
|
||||
//// Updated State
|
||||
|
||||
if (state is VoluntaryWorkEditedState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Updated Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(LoadVoluntaryWorks());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Update Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(LoadVoluntaryWorks());
|
||||
});
|
||||
}
|
||||
}
|
||||
////Deleted State
|
||||
if (state is VoluntaryWorkDeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Deletion Successfull!",
|
||||
"Deleted Successfully", () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(LoadVoluntaryWorks());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Deletion Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<VoluntaryWorkBloc>()
|
||||
.add(LoadVoluntaryWorks());
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is VoluntaryWorkLoadedState) {
|
||||
|
@ -128,10 +202,84 @@ class VolunataryWorkScreen extends StatelessWidget {
|
|||
"$numberOfHours : $hours hours"),
|
||||
]),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(
|
||||
Icons.more_vert))
|
||||
AppPopupMenu<int>(
|
||||
offset: const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete eligibilty-= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context, () {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
BlocProvider.of<
|
||||
VoluntaryWorkBloc>(
|
||||
context)
|
||||
.add(DeleteVoluntaryWork(
|
||||
work: state
|
||||
.voluntaryWorks[
|
||||
index],
|
||||
profileId:
|
||||
profileId!,
|
||||
token: token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
bool isOverseas;
|
||||
////edit voluntary work-= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
|
||||
if (state
|
||||
.voluntaryWorks[
|
||||
index]
|
||||
.address?.cityMunicipality == null
|
||||
) {
|
||||
isOverseas = true;
|
||||
}else{
|
||||
isOverseas = false;
|
||||
}
|
||||
|
||||
|
||||
context
|
||||
.read<
|
||||
VoluntaryWorkBloc>()
|
||||
.add(ShowEditVoluntaryWorks(
|
||||
profileId:
|
||||
profileId!,
|
||||
token: token!,
|
||||
work: state
|
||||
.voluntaryWorks[
|
||||
index],
|
||||
isOverseas:
|
||||
isOverseas));
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Edit",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Delete",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attachment",
|
||||
value: 3,
|
||||
icon: FontAwesome.attach)
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -146,8 +294,22 @@ class VolunataryWorkScreen extends StatelessWidget {
|
|||
message:
|
||||
"You don't have any Voluntary Works added. Please click + to add.");
|
||||
}
|
||||
}if(state is AddVoluntaryWorkState){
|
||||
return AddVoluntaryWorkScreen(profileId: profileId!,token: token!,);
|
||||
}
|
||||
if (state is AddVoluntaryWorkState) {
|
||||
return AddVoluntaryWorkScreen(
|
||||
profileId: profileId!,
|
||||
token: token!,
|
||||
);
|
||||
}
|
||||
if (state is VoluntaryWorkErrorState) {
|
||||
return SomethingWentWrong(
|
||||
message: state.toString(), onpressed: () {});
|
||||
}
|
||||
if (state is EditVoluntaryWorks) {
|
||||
return EditVoluntaryWorkScreen(
|
||||
profileId: profileId!,
|
||||
token: token!,
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
|
@ -162,4 +324,23 @@ class VolunataryWorkScreen 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!,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,597 +0,0 @@
|
|||
import 'package:date_time_picker/date_time_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter/src/widgets/placeholder.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:searchfield/searchfield.dart';
|
||||
import 'package:unit2/bloc/profile/voluntary_works/voluntary_work_bloc.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
|
||||
import '../../../../../model/location/barangay.dart';
|
||||
import '../../../../../model/location/city.dart';
|
||||
import '../../../../../model/location/country.dart';
|
||||
import '../../../../../model/location/provinces.dart';
|
||||
import '../../../../../model/location/region.dart';
|
||||
import '../../../../../model/utils/agency.dart';
|
||||
import '../../../../../model/utils/category.dart';
|
||||
import '../../../../../model/utils/position.dart';
|
||||
import '../../../../../theme-data.dart/box_shadow.dart';
|
||||
import '../../../../../theme-data.dart/colors.dart';
|
||||
import '../../../../../theme-data.dart/form-style.dart';
|
||||
import '../../../../../utils/location_utilities.dart';
|
||||
import '../../../shared/add_for_empty_search.dart';
|
||||
|
||||
class AddVoluntaryWorkScreen extends StatefulWidget {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const AddVoluntaryWorkScreen(
|
||||
{super.key, required this.profileId, required this.token});
|
||||
|
||||
@override
|
||||
State<AddVoluntaryWorkScreen> createState() => _AddVoluntaryWorkScreenState();
|
||||
}
|
||||
|
||||
class _AddVoluntaryWorkScreenState extends State<AddVoluntaryWorkScreen> {
|
||||
final formKey = GlobalKey<FormBuilderState>();
|
||||
////controllers
|
||||
final addPositionController = TextEditingController();
|
||||
final addAgencyController = TextEditingController();
|
||||
final toDateController = TextEditingController();
|
||||
final fromDateController = TextEditingController();
|
||||
////focus nodes
|
||||
final positionFocusNode = FocusNode();
|
||||
final agencyFocusNode = FocusNode();
|
||||
final agencyCategoryFocusNode = FocusNode();
|
||||
////booleans
|
||||
bool showAgency = false;
|
||||
bool showIsPrivateRadio = false;
|
||||
bool currentlyInvolved = false;
|
||||
bool overseas = false;
|
||||
bool provinceCall = false;
|
||||
bool cityCall = false;
|
||||
////Lists
|
||||
List<Province>? provinces;
|
||||
List<CityMunicipality>? citymuns;
|
||||
////Selected
|
||||
Region? selectedRegion;
|
||||
Province? selectedProvince;
|
||||
CityMunicipality? selectedMunicipality;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<VoluntaryWorkBloc, VoluntaryWorkState>(
|
||||
builder: (context, state) {
|
||||
if (state is AddVoluntaryWorkState) {
|
||||
return SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: screenHeight * .90,
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 25, horizontal: 18),
|
||||
child: FormBuilder(
|
||||
child: Column(
|
||||
children: [
|
||||
////POSITIONS
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return SearchField(
|
||||
itemHeight: 50,
|
||||
suggestionsDecoration: box1(),
|
||||
suggestions: state.positions
|
||||
.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(() {
|
||||
positionFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
////EMPTY WIDGET
|
||||
emptyWidget: EmptyWidget(
|
||||
title: "Add Position",
|
||||
controller: addPositionController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}),
|
||||
validator: (position) {
|
||||
if (position!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
);
|
||||
}),
|
||||
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"
|
||||
: agency.privateEntity ==
|
||||
false
|
||||
? "Government"
|
||||
: ""),
|
||||
)))
|
||||
.toList(),
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("Agency *", "")
|
||||
.copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down)),
|
||||
onSuggestionTap: (agency) {
|
||||
setState(() {
|
||||
agencyFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
emptyWidget: EmptyWidget(
|
||||
controller: addAgencyController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
title: "Add Agency")),
|
||||
|
||||
SizedBox(
|
||||
height: showAgency ? 12 : 0,
|
||||
),
|
||||
////SHOW CATEGORY AGENCY
|
||||
SizedBox(
|
||||
child: showAgency
|
||||
? 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(() {});
|
||||
},
|
||||
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(() {
|
||||
agencyCategoryFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
|
||||
name: 'isPrivate',
|
||||
validator:
|
||||
FormBuilderValidators.required(),
|
||||
options: ["YES", "NO"]
|
||||
.map((lang) =>
|
||||
FormBuilderFieldOption(
|
||||
value: lang))
|
||||
.toList(growable: false),
|
||||
)
|
||||
: const SizedBox()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
FormBuilderTextField(
|
||||
name: "total_hours",
|
||||
keyboardType: TextInputType.number,
|
||||
decoration:
|
||||
normalTextFieldStyle("Total Hours*", "0"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////Currently Involved
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
FormBuilderSwitch(
|
||||
initialValue: currentlyInvolved,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
currentlyInvolved = value!;
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"Currently Involved?", 'Graduated?'),
|
||||
name: 'currently_involved',
|
||||
title: Text(
|
||||
currentlyInvolved ? "YES" : "NO"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
//// FROM DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: DateTimePicker(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
use24HourFormat: false,
|
||||
icon: const Icon(
|
||||
Icons.date_range),
|
||||
controller: fromDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
timeHintText:
|
||||
"Date of Examination/Conferment",
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"From *", "From *")
|
||||
.copyWith(
|
||||
prefixIcon:
|
||||
const Icon(
|
||||
Icons.date_range,
|
||||
color: Colors.black87,
|
||||
)),
|
||||
initialValue: null,
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
//// TO DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: currentlyInvolved
|
||||
? TextFormField(
|
||||
enabled: false,
|
||||
initialValue: "PRESENT",
|
||||
style: const TextStyle(
|
||||
color: Colors.black45),
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"", "")
|
||||
.copyWith(),
|
||||
)
|
||||
: DateTimePicker(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
controller:
|
||||
toDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
decoration: normalTextFieldStyle(
|
||||
"To *", "To *")
|
||||
.copyWith(
|
||||
prefixIcon:
|
||||
const Icon(
|
||||
Icons.date_range,
|
||||
color: Colors
|
||||
.black87,
|
||||
),
|
||||
prefixText:
|
||||
currentlyInvolved
|
||||
? "PRESENT"
|
||||
: ""),
|
||||
initialValue: null,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
],
|
||||
);
|
||||
}),
|
||||
const SizedBox(height: 12,),
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
FormBuilderSwitch(
|
||||
initialValue: overseas,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
overseas = value!;
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"Overseas Address?", ''),
|
||||
name: 'overseas',
|
||||
title: Text(overseas ? "YES" : "NO"),
|
||||
),
|
||||
SizedBox(
|
||||
height: overseas == true ? 8 : 0,
|
||||
),
|
||||
SizedBox(
|
||||
child: overseas == false
|
||||
? Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////REGION DROPDOWN
|
||||
FormBuilderDropdown<Region?>(
|
||||
autovalidateMode: AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
onChanged: (Region? region) async {
|
||||
if (selectedRegion != region) {
|
||||
setState(() {
|
||||
provinceCall = true;
|
||||
});
|
||||
selectedRegion = region;
|
||||
getProvinces();
|
||||
}
|
||||
},
|
||||
initialValue: null,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Region*", "Region"),
|
||||
name: 'region',
|
||||
items: state.regions
|
||||
.map<DropdownMenuItem<Region>>(
|
||||
(Region region) {
|
||||
return DropdownMenuItem<Region>(
|
||||
value: region,
|
||||
child: Text(
|
||||
region.description!));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
//// PROVINCE DROPDOWN
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.transparent,
|
||||
inAsyncCall: provinceCall,
|
||||
child: DropdownButtonFormField<
|
||||
Province?>(
|
||||
autovalidateMode:
|
||||
AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator: (value) =>
|
||||
value == null
|
||||
? 'required'
|
||||
: null,
|
||||
isExpanded: true,
|
||||
value: selectedProvince,
|
||||
onChanged:
|
||||
(Province? province) {
|
||||
if (selectedProvince !=
|
||||
province) {
|
||||
setState(() {
|
||||
cityCall = true;
|
||||
});
|
||||
selectedProvince =
|
||||
province;
|
||||
getCities();
|
||||
}
|
||||
},
|
||||
items: provinces == null
|
||||
? []
|
||||
: provinces!.map<
|
||||
DropdownMenuItem<
|
||||
Province>>(
|
||||
(Province province) {
|
||||
return DropdownMenuItem(
|
||||
value: province,
|
||||
child: FittedBox(
|
||||
child: Text(province
|
||||
.description!),
|
||||
));
|
||||
}).toList(),
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Province*",
|
||||
"Province")),
|
||||
),
|
||||
),
|
||||
////CITY MUNICIPALITY
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.white,
|
||||
inAsyncCall: cityCall,
|
||||
child: DropdownButtonFormField<
|
||||
CityMunicipality>(
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
isExpanded: true,
|
||||
onChanged:
|
||||
(CityMunicipality? city) {
|
||||
if (selectedMunicipality !=
|
||||
city) {
|
||||
|
||||
selectedMunicipality = city;
|
||||
|
||||
}
|
||||
},
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Municipality*",
|
||||
"Municipality"),
|
||||
value: selectedMunicipality,
|
||||
items: citymuns == null
|
||||
? []
|
||||
: citymuns!.map<
|
||||
DropdownMenuItem<
|
||||
CityMunicipality>>(
|
||||
(CityMunicipality c) {
|
||||
return DropdownMenuItem(
|
||||
value: c,
|
||||
child: Text(c
|
||||
.description!));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
)
|
||||
//// COUNTRY DROPDOWN
|
||||
: SizedBox(
|
||||
height: 60,
|
||||
child: FormBuilderDropdown<Country>(
|
||||
initialValue: null,
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
items: state.countries
|
||||
.map<DropdownMenuItem<Country>>(
|
||||
(Country country) {
|
||||
return DropdownMenuItem<Country>(
|
||||
value: country,
|
||||
child: FittedBox(
|
||||
child:
|
||||
Text(country.name!)));
|
||||
}).toList(),
|
||||
name: 'country',
|
||||
decoration: normalTextFieldStyle(
|
||||
"Country*", "Country"),
|
||||
onChanged: (Country? value) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
);
|
||||
}),
|
||||
],
|
||||
)),
|
||||
),
|
||||
)),
|
||||
);
|
||||
}
|
||||
return const Placeholder();
|
||||
},
|
||||
);
|
||||
}
|
||||
Future<void> getProvinces() async {
|
||||
try {
|
||||
List<Province> newProvinces = await LocationUtils.instance
|
||||
.getProvinces(regionCode: selectedRegion!.code.toString());
|
||||
setState(() {
|
||||
provinces = newProvinces;
|
||||
selectedProvince = provinces![0];
|
||||
provinceCall = false;
|
||||
cityCall = true;
|
||||
getCities();
|
||||
});
|
||||
} catch (e) {
|
||||
context.read<VoluntaryWorkBloc>().add(ShowErrorState(message: e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getCities() async {
|
||||
try {
|
||||
List<CityMunicipality> newCities = await LocationUtils.instance
|
||||
.getCities(code: selectedProvince!.code.toString());
|
||||
citymuns = newCities;
|
||||
setState(() {
|
||||
selectedMunicipality = newCities[0];
|
||||
cityCall = false;
|
||||
});
|
||||
} catch (e) {
|
||||
context.read<VoluntaryWorkBloc>().add(ShowErrorState(message: e.toString()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
@ -6,34 +5,156 @@ import 'package:unit2/utils/request.dart';
|
|||
import '../../model/profile/voluntary_works.dart';
|
||||
import '../../utils/urls.dart';
|
||||
|
||||
class VoluntaryService{
|
||||
class VoluntaryService {
|
||||
static final VoluntaryService _instance = VoluntaryService();
|
||||
static VoluntaryService get instance => _instance;
|
||||
|
||||
Future< List<VoluntaryWork>> getVoluntaryWorks(int profileId, String token)async{
|
||||
Future<List<VoluntaryWork>> getVoluntaryWorks(
|
||||
int profileId, String token) async {
|
||||
List<VoluntaryWork> voluntaryWorks = [];
|
||||
String authToken = "Token $token";
|
||||
String path = "${Url.instance.getVoluntaryWorks()}$profileId/";
|
||||
String authToken = "Token $token";
|
||||
String path = "${Url.instance.getVoluntaryWorks()}$profileId/";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authToken
|
||||
};
|
||||
|
||||
try{
|
||||
http.Response response = await Request.instance.getRequest(path: path,param: {},headers: headers);
|
||||
if(response.statusCode == 200){
|
||||
// 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 work){
|
||||
VoluntaryWork voluntaryWork = VoluntaryWork.fromJson(work);
|
||||
voluntaryWorks.add(voluntaryWork);
|
||||
if (data['data'] != null) {
|
||||
data['data'].forEach((var work) {
|
||||
VoluntaryWork voluntaryWork = VoluntaryWork.fromJson(work);
|
||||
voluntaryWorks.add(voluntaryWork);
|
||||
});
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
throw(e.toString());
|
||||
}
|
||||
// } catch (e) {
|
||||
// throw (e.toString());
|
||||
// }
|
||||
|
||||
return voluntaryWorks;
|
||||
}
|
||||
}
|
||||
return voluntaryWorks;
|
||||
}
|
||||
|
||||
Future<Map<dynamic, dynamic>> add(
|
||||
{required VoluntaryWork voluntaryWork,
|
||||
required int profileId,
|
||||
required String token}) async {
|
||||
Map<dynamic, dynamic>? responseData = {};
|
||||
String authToken = "Token $token";
|
||||
String path = "${Url.instance.getVoluntaryWorks()}$profileId/";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authToken
|
||||
};
|
||||
Map body = {
|
||||
"position_id": voluntaryWork.position?.id,
|
||||
"agency_id": voluntaryWork.agency?.id,
|
||||
"address_id": voluntaryWork.address?.id,
|
||||
"from_date": voluntaryWork.fromDate.toString(),
|
||||
"to_date": voluntaryWork.toDate == null?null:voluntaryWork.toDate.toString(),
|
||||
"total_hours": voluntaryWork.totalHours,
|
||||
"_positionName": voluntaryWork.position!.title,
|
||||
"_agencyName": voluntaryWork.agency!.name,
|
||||
"_agencyCatId": voluntaryWork.agency!.category!.id,
|
||||
"_privateEntity": voluntaryWork.agency!.privateEntity,
|
||||
"_citymunCode": voluntaryWork.address?.cityMunicipality?.code,
|
||||
"_countryId": voluntaryWork.address?.country?.id
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.postRequest(param: {}, path: path, body: body, headers: headers);
|
||||
if (response.statusCode == 201) {
|
||||
Map data = jsonDecode(response.body);
|
||||
responseData = data;
|
||||
} else {
|
||||
responseData.addAll({'success': false});
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return responseData;
|
||||
}
|
||||
|
||||
////update
|
||||
Future<Map<dynamic, dynamic>> update(
|
||||
{required VoluntaryWork voluntaryWork,
|
||||
required int profileId,
|
||||
required String token,
|
||||
required int oldPosId,
|
||||
required int oldAgencyId,
|
||||
required String oldFromDate}) async {
|
||||
Map<dynamic, dynamic>? responseData = {};
|
||||
String authToken = "Token $token";
|
||||
String path = "${Url.instance.getVoluntaryWorks()}$profileId/";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authToken
|
||||
};
|
||||
Map body = {
|
||||
"position_id": voluntaryWork.position?.id,
|
||||
"agency_id": voluntaryWork.agency?.id,
|
||||
"address_id": voluntaryWork.address!.id,
|
||||
"from_date": voluntaryWork.fromDate.toString(),
|
||||
"to_date": voluntaryWork.toDate == null?null:voluntaryWork.toDate.toString(),
|
||||
"total_hours": voluntaryWork.totalHours,
|
||||
"_positionName": voluntaryWork.position!.title,
|
||||
"_agencyName": voluntaryWork.agency!.name,
|
||||
"_agencyCatId": voluntaryWork.agency!.category!.id,
|
||||
"_privateEntity": voluntaryWork.agency!.privateEntity,
|
||||
"_citymunCode": voluntaryWork.address?.cityMunicipality?.code,
|
||||
"_countryId": voluntaryWork.address!.country!.id,
|
||||
"_oldPosId": oldPosId,
|
||||
"_oldAgencyId": oldAgencyId,
|
||||
"_oldFromDate": oldFromDate
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.putRequest(param: {}, path: path, body: body, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
responseData = data;
|
||||
} else {
|
||||
responseData.addAll({'success': false});
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return responseData;
|
||||
}
|
||||
|
||||
////delete
|
||||
Future<bool> delete(
|
||||
{required int agencyId,
|
||||
required int positionId,
|
||||
required String fromDate,
|
||||
required String token,
|
||||
required int profileId}) async {
|
||||
bool success = false;
|
||||
String authToken = "Token $token";
|
||||
String path = "${Url.instance.getVoluntaryWorks()}$profileId/";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authToken
|
||||
};
|
||||
Map<String, dynamic> params = {"force_mode": "true"};
|
||||
Map body = {
|
||||
"agency_id": agencyId,
|
||||
"position_id": positionId,
|
||||
"from_date": fromDate,
|
||||
};
|
||||
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'];
|
||||
}
|
||||
} catch (e) {
|
||||
throw (e.toString());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ class Url {
|
|||
// return '192.168.10.183:3000';
|
||||
// return 'agusandelnorte.gov.ph';
|
||||
// return "192.168.10.219:3000";
|
||||
// return "devweb.agusandelnorte.gov.ph";
|
||||
return 'devapi.agusandelnorte.gov.ph:3004';
|
||||
return "devweb.agusandelnorte.gov.ph";
|
||||
// return 'devapi.agusandelnorte.gov.ph:3004';
|
||||
}
|
||||
|
||||
String authentication() {
|
||||
|
|
|
@ -77,7 +77,8 @@ dependencies:
|
|||
hive_flutter: ^1.1.0
|
||||
mask_text_input_formatter: ^2.4.0
|
||||
location: ^4.3.0
|
||||
platform_device_id: ^1.0.1,
|
||||
platform_device_id: ^1.0.1
|
||||
multi_dropdown: ^1.0.9
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in New Issue