Implemnent Voluntary works and civic API
parent
7f39bd5cd9
commit
1c6b291889
|
@ -1,6 +1,8 @@
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.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/location/barangay.dart';
|
||||||
|
import 'package:unit2/model/profile/voluntary_works.dart';
|
||||||
|
|
||||||
import '../../../../model/location/city.dart';
|
import '../../../../model/location/city.dart';
|
||||||
import '../../../../model/location/country.dart';
|
import '../../../../model/location/country.dart';
|
||||||
|
|
|
@ -23,3 +23,12 @@ class ShowEditAddressForm extends AddressEvent{
|
||||||
class CallErrorState 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,];
|
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{
|
class EditAddressState extends AddressState{
|
||||||
final MainAdress address;
|
final MainAdress address;
|
||||||
final List<Country> countries;
|
final List<Country> countries;
|
||||||
|
|
|
@ -1,14 +1,19 @@
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.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/sevices/profile/volunatary_services.dart';
|
||||||
import 'package:unit2/utils/profile_utilities.dart';
|
import 'package:unit2/utils/profile_utilities.dart';
|
||||||
|
|
||||||
|
import '../../../model/location/city.dart';
|
||||||
import '../../../model/location/country.dart';
|
import '../../../model/location/country.dart';
|
||||||
|
import '../../../model/location/provinces.dart';
|
||||||
import '../../../model/location/region.dart';
|
import '../../../model/location/region.dart';
|
||||||
import '../../../model/profile/voluntary_works.dart';
|
import '../../../model/profile/voluntary_works.dart';
|
||||||
import '../../../model/utils/agency.dart';
|
import '../../../model/utils/agency.dart';
|
||||||
import '../../../model/utils/category.dart';
|
import '../../../model/utils/category.dart';
|
||||||
import '../../../model/utils/position.dart';
|
import '../../../model/utils/position.dart';
|
||||||
|
import '../../../utils/location_utilities.dart';
|
||||||
|
|
||||||
part 'voluntary_work_event.dart';
|
part 'voluntary_work_event.dart';
|
||||||
part 'voluntary_work_state.dart';
|
part 'voluntary_work_state.dart';
|
||||||
|
@ -16,26 +21,41 @@ part 'voluntary_work_state.dart';
|
||||||
class VoluntaryWorkBloc extends Bloc<VoluntaryWorkEvent, VoluntaryWorkState> {
|
class VoluntaryWorkBloc extends Bloc<VoluntaryWorkEvent, VoluntaryWorkState> {
|
||||||
VoluntaryWorkBloc() : super(VoluntaryWorkInitial()) {
|
VoluntaryWorkBloc() : super(VoluntaryWorkInitial()) {
|
||||||
List<VoluntaryWork> voluntaryWorks = [];
|
List<VoluntaryWork> voluntaryWorks = [];
|
||||||
List<Country> globalCountries=[];
|
List<Country> globalCountries = [];
|
||||||
List<Category> agencyCategory = [];
|
List<Category> agencyCategory = [];
|
||||||
List<Region> globalRegions=[];
|
List<Region> globalRegions = [];
|
||||||
List<Position> agencyPositions = [];
|
List<Position> agencyPositions = [];
|
||||||
List<Agency> agencies = [];
|
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
|
////Get Voluntary Works
|
||||||
on<GetVoluntarWorks>((event, emit) async{
|
on<GetVoluntarWorks>((event, emit) async {
|
||||||
emit(VoluntaryWorkLoadingState());
|
emit(VoluntaryWorkLoadingState());
|
||||||
try{
|
try {
|
||||||
List<VoluntaryWork> works = await VoluntaryService.instance.getVoluntaryWorks(event.profileId, event.token);
|
List<VoluntaryWork> works = await VoluntaryService.instance
|
||||||
|
.getVoluntaryWorks(event.profileId, event.token);
|
||||||
voluntaryWorks = works;
|
voluntaryWorks = works;
|
||||||
emit(VoluntaryWorkLoadedState(voluntaryWorks: voluntaryWorks));
|
emit(VoluntaryWorkLoadedState(voluntaryWorks: voluntaryWorks));
|
||||||
}catch(e){
|
} catch (e) {
|
||||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
//// Load
|
||||||
|
on<LoadVoluntaryWorks>((event, emit) {
|
||||||
|
emit(VoluntaryWorkLoadedState(voluntaryWorks: voluntaryWorks));
|
||||||
|
});
|
||||||
//// Show Add form Event
|
//// Show Add form Event
|
||||||
on<ShowAddVoluntaryWorks>((event,emit)async{
|
on<ShowAddVoluntaryWorks>((event, emit) async {
|
||||||
try{
|
try {
|
||||||
emit(VoluntaryWorkLoadingState());
|
emit(VoluntaryWorkLoadingState());
|
||||||
|
//// POSITIONS
|
||||||
if (agencyPositions.isEmpty) {
|
if (agencyPositions.isEmpty) {
|
||||||
List<Position> positions =
|
List<Position> positions =
|
||||||
await ProfileUtilities.instance.getAgencyPosition();
|
await ProfileUtilities.instance.getAgencyPosition();
|
||||||
|
@ -55,12 +75,177 @@ class VoluntaryWorkBloc extends Bloc<VoluntaryWorkEvent, VoluntaryWorkState> {
|
||||||
await ProfileUtilities.instance.agencyCategory();
|
await ProfileUtilities.instance.agencyCategory();
|
||||||
agencyCategory = categoryAgencies;
|
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){
|
}catch(e){
|
||||||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
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 => [];
|
List<Object> get props => [];
|
||||||
}
|
}
|
||||||
|
|
||||||
class GetVoluntarWorks extends VoluntaryWorkEvent{
|
class GetVoluntarWorks extends VoluntaryWorkEvent {
|
||||||
final int profileId;
|
final int profileId;
|
||||||
final String token;
|
final String token;
|
||||||
const GetVoluntarWorks({required this.profileId, required this.token});
|
const GetVoluntarWorks({required this.profileId, required this.token});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [profileId,token];
|
List<Object> get props => [profileId, token];
|
||||||
}
|
|
||||||
class ShowAddVoluntaryWorks extends VoluntaryWorkEvent{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
final String message;
|
||||||
const ShowErrorState({required this.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{
|
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{
|
class AddVoluntaryWorkState extends VoluntaryWorkState{
|
||||||
final List<Position> positions;
|
final List<Position> positions;
|
||||||
final List<Agency> agencies;
|
final List<Agency> agencies;
|
||||||
|
@ -38,3 +71,10 @@ class AddVoluntaryWorkState extends VoluntaryWorkState{
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [positions,agencies,countries,regions];
|
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 DateTime? toDate;
|
||||||
final Position? position;
|
final Position? position;
|
||||||
final DateTime? fromDate;
|
final DateTime? fromDate;
|
||||||
final int? totalHours;
|
final double? totalHours;
|
||||||
|
|
||||||
factory VoluntaryWork.fromJson(Map<String, dynamic> json) => VoluntaryWork(
|
factory VoluntaryWork.fromJson(Map<String, dynamic> json) => VoluntaryWork(
|
||||||
agency: json["agency"] == null ? null : Agency.fromJson(json["agency"]),
|
agency: json["agency"] == null ? null : Agency.fromJson(json["agency"]),
|
||||||
address: json["address"] == null ? null : Address.fromJson(json["address"]),
|
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"]),
|
position: json["position"] == null ? null : Position.fromJson(json["position"]),
|
||||||
fromDate: json["from_date"] == null ? null : DateTime.parse(json["from_date"]),
|
fromDate: json["from_date"] == null ? null : DateTime.parse(json["from_date"]),
|
||||||
totalHours: json["total_hours"],
|
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:form_builder_validators/form_builder_validators.dart';
|
||||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.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/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/model/utils/category.dart';
|
||||||
import 'package:unit2/utils/global.dart';
|
import 'package:unit2/utils/global.dart';
|
||||||
|
|
||||||
|
@ -38,6 +39,8 @@ class _AddAddressScreenState extends State<AddAddressScreen> {
|
||||||
bool cityCall = false;
|
bool cityCall = false;
|
||||||
bool barangayCall = false;
|
bool barangayCall = false;
|
||||||
////selected
|
////selected
|
||||||
|
AddressCategory? selectedAddressCategory;
|
||||||
|
String? selectedAreaClass;
|
||||||
Region? selectedRegion;
|
Region? selectedRegion;
|
||||||
Province? selectedProvince;
|
Province? selectedProvince;
|
||||||
CityMunicipality? selectedMunicipality;
|
CityMunicipality? selectedMunicipality;
|
||||||
|
@ -54,7 +57,7 @@ class _AddAddressScreenState extends State<AddAddressScreen> {
|
||||||
const Area(value: "Metropolis", group: 1),
|
const Area(value: "Metropolis", group: 1),
|
||||||
const Area(value: "Megacity", 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<Province>? provinces;
|
||||||
List<CityMunicipality>? citymuns;
|
List<CityMunicipality>? citymuns;
|
||||||
List<Barangay>? barangays;
|
List<Barangay>? barangays;
|
||||||
|
@ -75,17 +78,17 @@ class _AddAddressScreenState extends State<AddAddressScreen> {
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
//// category
|
//// category
|
||||||
FormBuilderDropdown<String>(
|
FormBuilderDropdown(
|
||||||
validator: FormBuilderValidators.required(
|
validator: FormBuilderValidators.required(
|
||||||
errorText: "This field is required"),
|
errorText: "This field is required"),
|
||||||
decoration:
|
decoration:
|
||||||
normalTextFieldStyle("Category*", "Category"),
|
normalTextFieldStyle("Category*", "Category"),
|
||||||
name: "category",
|
name: "category",
|
||||||
onChanged: (String? category) {},
|
onChanged: (AddressCategory? category) {},
|
||||||
items: category.map<DropdownMenuItem<String>>(
|
items: category.map<DropdownMenuItem<AddressCategory>>(
|
||||||
(String category) {
|
(AddressCategory category) {
|
||||||
return DropdownMenuItem(
|
return DropdownMenuItem(
|
||||||
value: category, child: Text(category));
|
value: category, child: Text(category.name!));
|
||||||
}).toList()),
|
}).toList()),
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
height: 12,
|
height: 12,
|
||||||
|
@ -97,7 +100,9 @@ class _AddAddressScreenState extends State<AddAddressScreen> {
|
||||||
decoration: normalTextFieldStyle(
|
decoration: normalTextFieldStyle(
|
||||||
"Area class *", "Area class"),
|
"Area class *", "Area class"),
|
||||||
name: "area_class",
|
name: "area_class",
|
||||||
onChanged: (Area? area) {},
|
onChanged: (Area? area) {
|
||||||
|
selectedAreaClass = area!.value;
|
||||||
|
},
|
||||||
items: areaClass
|
items: areaClass
|
||||||
.map<DropdownMenuItem<Area>>((Area area) {
|
.map<DropdownMenuItem<Area>>((Area area) {
|
||||||
return area.group == 0
|
return area.group == 0
|
||||||
|
|
|
@ -448,6 +448,9 @@ class _AddEducationScreenState extends State<AddEducationScreen> {
|
||||||
if (!graduated) {
|
if (!graduated) {
|
||||||
unitsEarned = int.parse(formKey
|
unitsEarned = int.parse(formKey
|
||||||
.currentState!.value['units_earned']);
|
.currentState!.value['units_earned']);
|
||||||
|
yearGraduated.text = '';
|
||||||
|
}else{
|
||||||
|
|
||||||
}
|
}
|
||||||
////education
|
////education
|
||||||
Education newEducation = Education(
|
Education newEducation = Education(
|
||||||
|
|
|
@ -92,7 +92,6 @@ class _EditEducationScreenState extends State<EditEducationScreen> {
|
||||||
}
|
}
|
||||||
fromController.text = state.educationalBackground.periodFrom!;
|
fromController.text = state.educationalBackground.periodFrom!;
|
||||||
untilController.text = state.educationalBackground.periodTo!;
|
untilController.text = state.educationalBackground.periodTo!;
|
||||||
////honors
|
|
||||||
|
|
||||||
////get all honors
|
////get all honors
|
||||||
valueItemHonorList = state.honors.map((Honor honor) {
|
valueItemHonorList = state.honors.map((Honor honor) {
|
||||||
|
@ -147,6 +146,10 @@ class _EditEducationScreenState extends State<EditEducationScreen> {
|
||||||
////school
|
////school
|
||||||
StatefulBuilder(builder: (context, setState) {
|
StatefulBuilder(builder: (context, setState) {
|
||||||
return SearchField(
|
return SearchField(
|
||||||
|
suggestionAction: SuggestionAction.next,
|
||||||
|
onSubmit: (p0) {
|
||||||
|
schoolFocusNode.unfocus();
|
||||||
|
},
|
||||||
controller: currentSchoolController,
|
controller: currentSchoolController,
|
||||||
itemHeight: 50,
|
itemHeight: 50,
|
||||||
suggestionsDecoration: box1(),
|
suggestionsDecoration: box1(),
|
||||||
|
@ -171,7 +174,9 @@ class _EditEducationScreenState extends State<EditEducationScreen> {
|
||||||
searchInputDecoration:
|
searchInputDecoration:
|
||||||
normalTextFieldStyle("School *", "").copyWith(
|
normalTextFieldStyle("School *", "").copyWith(
|
||||||
suffixIcon:
|
suffixIcon:
|
||||||
const Icon(Icons.arrow_drop_down)),
|
GestureDetector(child: const Icon(Icons.arrow_drop_down),onTap: (){
|
||||||
|
schoolFocusNode.unfocus();
|
||||||
|
},)),
|
||||||
onSuggestionTap: (school) {
|
onSuggestionTap: (school) {
|
||||||
setState(() {
|
setState(() {
|
||||||
selectedSchool = school.item;
|
selectedSchool = school.item;
|
||||||
|
@ -497,10 +502,12 @@ class _EditEducationScreenState extends State<EditEducationScreen> {
|
||||||
selectedLevel!.value == "Junior High" ||
|
selectedLevel!.value == "Junior High" ||
|
||||||
selectedLevel!.value == "Senior High") {
|
selectedLevel!.value == "Senior High") {
|
||||||
selectedProgram = null;
|
selectedProgram = null;
|
||||||
}else{
|
} else {
|
||||||
selectedProgram ??= state.educationalBackground.education!.course;
|
selectedProgram ??= state
|
||||||
|
.educationalBackground.education!.course;
|
||||||
}
|
}
|
||||||
selectedSchool ??= state.educationalBackground.education!.school;
|
selectedSchool ??=
|
||||||
|
state.educationalBackground.education!.school;
|
||||||
////education
|
////education
|
||||||
Education newEducation = Education(
|
Education newEducation = Education(
|
||||||
id: null,
|
id: null,
|
||||||
|
|
|
@ -18,6 +18,7 @@ import 'package:unit2/widgets/error_state.dart';
|
||||||
|
|
||||||
import '../../../bloc/profile/education/education_bloc.dart';
|
import '../../../bloc/profile/education/education_bloc.dart';
|
||||||
import '../../../utils/alerts.dart';
|
import '../../../utils/alerts.dart';
|
||||||
|
import '../../../widgets/Leadings/close_leading.dart';
|
||||||
import 'education/edit_modal.dart';
|
import 'education/edit_modal.dart';
|
||||||
|
|
||||||
class EducationScreen extends StatelessWidget {
|
class EducationScreen extends StatelessWidget {
|
||||||
|
@ -32,11 +33,15 @@ class EducationScreen extends StatelessWidget {
|
||||||
title: const Text(educationScreenTitle),
|
title: const Text(educationScreenTitle),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
backgroundColor: primary,
|
backgroundColor: primary,
|
||||||
actions: [
|
actions: context.watch<EducationBloc>().state is EducationalBackgroundLoadedState?[
|
||||||
AddLeading(onPressed: () {
|
AddLeading(onPressed: () {
|
||||||
context.read<EducationBloc>().add(ShowAddEducationForm());
|
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
|
//userbloc
|
||||||
body: ProgressHUD(
|
body: ProgressHUD(
|
||||||
|
|
|
@ -398,11 +398,11 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
|
||||||
style: mainBtnStyle(
|
style: mainBtnStyle(
|
||||||
primary, Colors.transparent, second),
|
primary, Colors.transparent, second),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
//rating
|
////rating
|
||||||
double? rate = rating == null
|
double? rate = rating == null
|
||||||
? null
|
? null
|
||||||
: double.parse(rating!);
|
: double.parse(rating!);
|
||||||
//lisence
|
////lisence
|
||||||
String? licenseNumber = license;
|
String? licenseNumber = license;
|
||||||
CityMunicipality? cityMunicipality =
|
CityMunicipality? cityMunicipality =
|
||||||
selectedMunicipality;
|
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,18 +1,23 @@
|
||||||
|
import 'package:app_popup_menu/app_popup_menu.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
import 'package:fluttericon/font_awesome_icons.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||||
import 'package:unit2/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/box_shadow.dart';
|
||||||
import 'package:unit2/theme-data.dart/colors.dart';
|
import 'package:unit2/theme-data.dart/colors.dart';
|
||||||
import 'package:unit2/utils/text_container.dart';
|
import 'package:unit2/utils/text_container.dart';
|
||||||
import 'package:unit2/widgets/Leadings/add_leading.dart';
|
import 'package:unit2/widgets/Leadings/add_leading.dart';
|
||||||
import 'package:unit2/widgets/empty_data.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 '../../../bloc/profile/voluntary_works/voluntary_work_bloc.dart';
|
||||||
|
import '../../../utils/alerts.dart';
|
||||||
|
|
||||||
class VolunataryWorkScreen extends StatelessWidget {
|
class VolunataryWorkScreen extends StatelessWidget {
|
||||||
const VolunataryWorkScreen({super.key});
|
const VolunataryWorkScreen({super.key});
|
||||||
|
@ -26,9 +31,11 @@ class VolunataryWorkScreen extends StatelessWidget {
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text(voluntaryScreenTitle),
|
title: const Text(voluntaryScreenTitle),
|
||||||
backgroundColor: primary,
|
backgroundColor: primary,
|
||||||
actions: [AddLeading(onPressed: () {
|
actions: [
|
||||||
|
AddLeading(onPressed: () {
|
||||||
context.read<VoluntaryWorkBloc>().add(ShowAddVoluntaryWorks());
|
context.read<VoluntaryWorkBloc>().add(ShowAddVoluntaryWorks());
|
||||||
})],
|
})
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: ProgressHUD(
|
body: ProgressHUD(
|
||||||
padding: const EdgeInsets.all(24),
|
padding: const EdgeInsets.all(24),
|
||||||
|
@ -38,8 +45,7 @@ class VolunataryWorkScreen extends StatelessWidget {
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is UserLoggedIn) {
|
if (state is UserLoggedIn) {
|
||||||
token = state.userData!.user!.login!.token;
|
token = state.userData!.user!.login!.token;
|
||||||
profileId =
|
profileId = state.userData!.user!.login!.user!.profileId;
|
||||||
state.userData!.user!.login!.user!.profileId;
|
|
||||||
return BlocBuilder<ProfileBloc, ProfileState>(
|
return BlocBuilder<ProfileBloc, ProfileState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
if (state is ProfileLoaded) {
|
if (state is ProfileLoaded) {
|
||||||
|
@ -51,10 +57,78 @@ class VolunataryWorkScreen extends StatelessWidget {
|
||||||
progress!.showWithText("Please wait...");
|
progress!.showWithText("Please wait...");
|
||||||
}
|
}
|
||||||
if (state is VoluntaryWorkLoadedState ||
|
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);
|
final progress = ProgressHUD.of(context);
|
||||||
progress!.dismiss();
|
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) {
|
builder: (context, state) {
|
||||||
if (state is VoluntaryWorkLoadedState) {
|
if (state is VoluntaryWorkLoadedState) {
|
||||||
|
@ -128,10 +202,84 @@ class VolunataryWorkScreen extends StatelessWidget {
|
||||||
"$numberOfHours : $hours hours"),
|
"$numberOfHours : $hours hours"),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
IconButton(
|
AppPopupMenu<int>(
|
||||||
onPressed: () {},
|
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(
|
icon: const Icon(
|
||||||
Icons.more_vert))
|
Icons.more_vert,
|
||||||
|
color: Colors.grey,
|
||||||
|
),
|
||||||
|
tooltip: "Options",
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -146,8 +294,22 @@ class VolunataryWorkScreen extends StatelessWidget {
|
||||||
message:
|
message:
|
||||||
"You don't have any Voluntary Works added. Please click + to add.");
|
"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();
|
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 'dart:convert';
|
||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
@ -6,11 +5,12 @@ import 'package:unit2/utils/request.dart';
|
||||||
import '../../model/profile/voluntary_works.dart';
|
import '../../model/profile/voluntary_works.dart';
|
||||||
import '../../utils/urls.dart';
|
import '../../utils/urls.dart';
|
||||||
|
|
||||||
class VoluntaryService{
|
class VoluntaryService {
|
||||||
static final VoluntaryService _instance = VoluntaryService();
|
static final VoluntaryService _instance = VoluntaryService();
|
||||||
static VoluntaryService get instance => _instance;
|
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 = [];
|
List<VoluntaryWork> voluntaryWorks = [];
|
||||||
String authToken = "Token $token";
|
String authToken = "Token $token";
|
||||||
String path = "${Url.instance.getVoluntaryWorks()}$profileId/";
|
String path = "${Url.instance.getVoluntaryWorks()}$profileId/";
|
||||||
|
@ -19,21 +19,142 @@ class VoluntaryService{
|
||||||
'Authorization': authToken
|
'Authorization': authToken
|
||||||
};
|
};
|
||||||
|
|
||||||
try{
|
// try {
|
||||||
http.Response response = await Request.instance.getRequest(path: path,param: {},headers: headers);
|
http.Response response = await Request.instance
|
||||||
if(response.statusCode == 200){
|
.getRequest(path: path, param: {}, headers: headers);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
Map data = jsonDecode(response.body);
|
Map data = jsonDecode(response.body);
|
||||||
if(data['data'] != null){
|
if (data['data'] != null) {
|
||||||
data['data'].forEach((var work){
|
data['data'].forEach((var work) {
|
||||||
VoluntaryWork voluntaryWork = VoluntaryWork.fromJson(work);
|
VoluntaryWork voluntaryWork = VoluntaryWork.fromJson(work);
|
||||||
voluntaryWorks.add(voluntaryWork);
|
voluntaryWorks.add(voluntaryWork);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch(e){
|
// } catch (e) {
|
||||||
throw(e.toString());
|
// 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 '192.168.10.183:3000';
|
||||||
// return 'agusandelnorte.gov.ph';
|
// return 'agusandelnorte.gov.ph';
|
||||||
// return "192.168.10.219:3000";
|
// return "192.168.10.219:3000";
|
||||||
// return "devweb.agusandelnorte.gov.ph";
|
return "devweb.agusandelnorte.gov.ph";
|
||||||
return 'devapi.agusandelnorte.gov.ph:3004';
|
// return 'devapi.agusandelnorte.gov.ph:3004';
|
||||||
}
|
}
|
||||||
|
|
||||||
String authentication() {
|
String authentication() {
|
||||||
|
|
|
@ -77,7 +77,8 @@ dependencies:
|
||||||
hive_flutter: ^1.1.0
|
hive_flutter: ^1.1.0
|
||||||
mask_text_input_formatter: ^2.4.0
|
mask_text_input_formatter: ^2.4.0
|
||||||
location: ^4.3.0
|
location: ^4.3.0
|
||||||
platform_device_id: ^1.0.1,
|
platform_device_id: ^1.0.1
|
||||||
|
multi_dropdown: ^1.0.9
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in New Issue