implemented education profile API
parent
cf7902f923
commit
7f39bd5cd9
|
@ -0,0 +1,28 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:unit2/sevices/docsms/docsms_service.dart';
|
||||
|
||||
import '../../model/docsms/document.dart';
|
||||
|
||||
part 'docsms_event.dart';
|
||||
part 'docsms_state.dart';
|
||||
|
||||
class DocsmsBloc extends Bloc<DocsmsEvent, DocsmsState> {
|
||||
DocsmsBloc() : super(DocsmsInitial()) {
|
||||
Document? document;
|
||||
on<LoadDocument>((event, emit)async {
|
||||
emit(DocSmsLoadingState());
|
||||
try {
|
||||
document = await AutoReceiveDocumentServices.instance.getDocument(event.documentId);
|
||||
if(document != null){
|
||||
emit(DocumentLoaded(document: document!));
|
||||
}else{
|
||||
emit(const DocSmsErrorState(message: "Invalid Qr code"));
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
emit(DocSmsErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
part of 'docsms_bloc.dart';
|
||||
|
||||
abstract class DocsmsEvent extends Equatable {
|
||||
const DocsmsEvent();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class LoadDocument extends DocsmsEvent{
|
||||
final String documentId;
|
||||
const LoadDocument({required this.documentId});
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
part of 'docsms_bloc.dart';
|
||||
|
||||
abstract class DocsmsState extends Equatable {
|
||||
const DocsmsState();
|
||||
|
||||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
|
||||
class DocsmsInitial extends DocsmsState {}
|
||||
|
||||
class DocSmsLoadingState extends DocsmsState{
|
||||
|
||||
}
|
||||
class DocumentLoaded extends DocsmsState{
|
||||
final Document document;
|
||||
const DocumentLoaded({required this.document});
|
||||
@override
|
||||
List<Object> get props => [document];
|
||||
|
||||
}
|
||||
|
||||
class DocSmsErrorState extends DocsmsState{
|
||||
final String message;
|
||||
const DocSmsErrorState({required this.message});
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
|
@ -8,10 +8,13 @@ part 'education_state.dart';
|
|||
|
||||
class EducationBloc extends Bloc<EducationEvent, EducationState> {
|
||||
List<EducationalBackground> educationalBackgrounds = [];
|
||||
List<School> schools = [];
|
||||
List<Course> programs = [];
|
||||
List<Honor> honors = [];
|
||||
EducationBloc() : super(EducationInitial()) {
|
||||
on<GetEducationalBackground>((event, emit) async {
|
||||
emit(EducationalBackgroundLoadingState());
|
||||
try {
|
||||
try {
|
||||
List<EducationalBackground> educations = await EducationService.instace
|
||||
.getEducationalBackground(event.profileId, event.token);
|
||||
educationalBackgrounds = educations;
|
||||
|
@ -21,5 +24,108 @@ class EducationBloc extends Bloc<EducationEvent, EducationState> {
|
|||
emit(EducationalBackgroundErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
//// SHOW ADD FORM
|
||||
on<ShowAddEducationForm>((event, emit) async {
|
||||
emit(EducationalBackgroundLoadingState());
|
||||
try {
|
||||
if (schools.isEmpty) {
|
||||
List<School> newSchools = await EducationService.instace.getSchools();
|
||||
schools = newSchools;
|
||||
}
|
||||
if (programs.isEmpty) {
|
||||
List<Course> newPrograms =
|
||||
await EducationService.instace.getPrograms();
|
||||
programs = newPrograms;
|
||||
}
|
||||
if (honors.isEmpty) {
|
||||
List<Honor> newHonors = await EducationService.instace.getHonors();
|
||||
honors = newHonors;
|
||||
}
|
||||
emit(AddEducationState(
|
||||
schools: schools, programs: programs, honors: honors));
|
||||
} catch (e) {
|
||||
emit(EducationalBackgroundErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
////Add
|
||||
on<AddEducation>((event, emit) async {
|
||||
Map<dynamic, dynamic> status = await EducationService.instace.add(
|
||||
honors: event.honors,
|
||||
educationalBackground: event.educationalBackground,
|
||||
token: event.token,
|
||||
profileId: event.profileId);
|
||||
if (status['success']) {
|
||||
EducationalBackground educationalBackground =
|
||||
EducationalBackground.fromJson(status['data']);
|
||||
educationalBackgrounds.add(educationalBackground);
|
||||
emit(EducationAddedState(response: status));
|
||||
} else {
|
||||
emit(EducationAddedState(response: status));
|
||||
}
|
||||
});
|
||||
////Update
|
||||
on<UpdateEducation>((event, emit) async {
|
||||
Map<dynamic, dynamic> status = await EducationService.instace.edit(
|
||||
honors: event.honors,
|
||||
educationalBackground: event.educationalBackground,
|
||||
token: event.token,
|
||||
profileId: event.profileId);
|
||||
if (status['success']) {
|
||||
EducationalBackground educationalBackground =
|
||||
EducationalBackground.fromJson(status['data']);
|
||||
educationalBackgrounds.add(educationalBackground);
|
||||
emit(EditedEducationState(response: status));
|
||||
} else {
|
||||
emit(EditedEducationState(response: status));
|
||||
}
|
||||
});
|
||||
////LOAD
|
||||
on<LoadEducations>((event, emit) {
|
||||
emit(EducationalBackgroundLoadedState(
|
||||
educationalBackground: educationalBackgrounds));
|
||||
});
|
||||
//// SHOW EDIT FORM
|
||||
on<ShowEditEducationForm>((event, emit) async {
|
||||
try {
|
||||
if (schools.isEmpty) {
|
||||
List<School> newSchools = await EducationService.instace.getSchools();
|
||||
schools = newSchools;
|
||||
}
|
||||
if (programs.isEmpty) {
|
||||
List<Course> newPrograms =
|
||||
await EducationService.instace.getPrograms();
|
||||
programs = newPrograms;
|
||||
}
|
||||
if (honors.isEmpty) {
|
||||
List<Honor> newHonors = await EducationService.instace.getHonors();
|
||||
honors = newHonors;
|
||||
}
|
||||
emit(EditEducationState(
|
||||
schools: schools,
|
||||
programs: programs,
|
||||
honors: honors,
|
||||
educationalBackground: event.educationalBackground));
|
||||
} catch (e) {
|
||||
emit(EducationalBackgroundErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
////delete
|
||||
on<DeleteEducation>((event, emit) async {
|
||||
try {
|
||||
final bool success = await EducationService.instace.delete(
|
||||
profileId: event.profileId,
|
||||
token: event.token,
|
||||
educationalBackground: event.educationalBackground);
|
||||
if (success) {
|
||||
educationalBackgrounds.removeWhere(
|
||||
(element) => element.id == event.educationalBackground.id);
|
||||
emit(EducationDeletedState(success: success));
|
||||
} else {
|
||||
emit(EducationDeletedState(success: success));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(EducationalBackgroundErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,60 @@ abstract class EducationEvent extends Equatable {
|
|||
@override
|
||||
List<Object> get props => [];
|
||||
}
|
||||
class GetEducationalBackground extends EducationEvent{
|
||||
|
||||
class GetEducationalBackground extends EducationEvent {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const GetEducationalBackground({required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [profileId,token];
|
||||
const GetEducationalBackground(
|
||||
{required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [profileId, token];
|
||||
}
|
||||
////show add form
|
||||
class ShowAddEducationForm extends EducationEvent {}
|
||||
////show edit form
|
||||
class ShowEditEducationForm extends EducationEvent {
|
||||
final EducationalBackground educationalBackground;
|
||||
final int profileId;
|
||||
final String token;
|
||||
const ShowEditEducationForm({required this.educationalBackground,required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [educationalBackground];
|
||||
}
|
||||
////load
|
||||
class LoadEducations extends EducationEvent {}
|
||||
////add
|
||||
class AddEducation extends EducationEvent {
|
||||
final List<Honor> honors;
|
||||
final EducationalBackground educationalBackground;
|
||||
final int profileId;
|
||||
final String token;
|
||||
const AddEducation(
|
||||
{required this.educationalBackground,
|
||||
required this.profileId,
|
||||
required this.token, required this.honors});
|
||||
@override
|
||||
List<Object> get props => [educationalBackground, profileId, token];
|
||||
}
|
||||
////update education
|
||||
class UpdateEducation extends EducationEvent{
|
||||
final List<Honor> honors;
|
||||
final EducationalBackground educationalBackground;
|
||||
final int profileId;
|
||||
final String token;
|
||||
const UpdateEducation(
|
||||
{required this.educationalBackground,
|
||||
required this.profileId,
|
||||
required this.token,required this.honors});
|
||||
@override
|
||||
List<Object> get props => [educationalBackground, profileId, token];
|
||||
}
|
||||
////delete
|
||||
class DeleteEducation extends EducationEvent{
|
||||
final int profileId;
|
||||
final String token;
|
||||
final EducationalBackground educationalBackground;
|
||||
const DeleteEducation({required this.educationalBackground, required this.profileId, required this.token});
|
||||
@override
|
||||
List<Object> get props => [educationalBackground, profileId, token];
|
||||
}
|
||||
|
|
|
@ -9,21 +9,66 @@ abstract class EducationState extends Equatable {
|
|||
|
||||
class EducationInitial extends EducationState {}
|
||||
|
||||
|
||||
|
||||
class EducationalBackgroundLoadedState extends EducationState{
|
||||
class EducationalBackgroundLoadedState extends EducationState {
|
||||
final List<EducationalBackground> educationalBackground;
|
||||
const EducationalBackgroundLoadedState({required this.educationalBackground});
|
||||
@override
|
||||
@override
|
||||
List<Object> get props => [educationalBackground];
|
||||
}
|
||||
|
||||
class EducationalBackgroundErrorState extends EducationState{
|
||||
class EducationalBackgroundErrorState extends EducationState {
|
||||
final String message;
|
||||
const EducationalBackgroundErrorState({required this.message});
|
||||
@override
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
class EducationalBackgroundLoadingState extends EducationState{
|
||||
|
||||
class EducationalBackgroundLoadingState extends EducationState {}
|
||||
|
||||
////Add
|
||||
class AddEducationState extends EducationState {
|
||||
final List<School> schools;
|
||||
final List<Course> programs;
|
||||
final List<Honor> honors;
|
||||
const AddEducationState(
|
||||
{required this.honors, required this.programs, required this.schools});
|
||||
@override
|
||||
List<Object> get props => [schools, programs, honors];
|
||||
}
|
||||
|
||||
////Edit
|
||||
class EditEducationState extends EducationState {
|
||||
final EducationalBackground educationalBackground;
|
||||
final List<School> schools;
|
||||
final List<Course> programs;
|
||||
final List<Honor> honors;
|
||||
const EditEducationState({
|
||||
required this.educationalBackground,
|
||||
required this.honors,
|
||||
required this.programs,
|
||||
required this.schools,
|
||||
});
|
||||
}
|
||||
|
||||
//// Added State
|
||||
class EducationAddedState extends EducationState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
const EducationAddedState({required this.response});
|
||||
@override
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
//// Edited State
|
||||
class EditedEducationState extends EducationState {
|
||||
final Map<dynamic, dynamic> response;
|
||||
const EditedEducationState({required this.response});
|
||||
@override
|
||||
List<Object> get props => [response];
|
||||
}
|
||||
|
||||
////deleted State
|
||||
class EducationDeletedState extends EducationState {
|
||||
final bool success;
|
||||
const EducationDeletedState({required this.success});
|
||||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ part 'eligibility_state.dart';
|
|||
|
||||
class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
||||
EligibilityBloc() : super(EligibilityInitial()) {
|
||||
List<Country>? globalCountries;
|
||||
List<Region>? globalRegions;
|
||||
List<Country> globalCountries = [];
|
||||
List<Region> globalRegions = [];
|
||||
List<Eligibility> globalEligibilities = [];
|
||||
List<EligibityCert> eligibilities = [];
|
||||
//// LOAD ELIGIBILTY
|
||||
|
@ -67,11 +67,11 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
//// SHOW EDIT FORM
|
||||
on<ShowEditEligibilityForm>((event, emit) async {
|
||||
try {
|
||||
if (globalCountries == null) {
|
||||
if (globalCountries.isEmpty) {
|
||||
List<Country> countries = await LocationUtils.instance.getCountries();
|
||||
globalCountries = countries;
|
||||
}
|
||||
if (globalRegions == null) {
|
||||
if (globalRegions.isEmpty) {
|
||||
List<Region> regions = await LocationUtils.instance.getRegions();
|
||||
globalRegions = regions;
|
||||
}
|
||||
|
@ -84,13 +84,13 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
(Eligibility eligibility) =>
|
||||
event.eligibityCert.eligibility!.id == eligibility.id);
|
||||
bool? isOverseas = event.eligibityCert.overseas;
|
||||
Country currentCountry = globalCountries!.firstWhere(
|
||||
Country currentCountry = globalCountries.firstWhere(
|
||||
(Country country) =>
|
||||
event.eligibityCert.examAddress!.country!.code == country.code);
|
||||
if (event.eligibityCert.examAddress?.cityMunicipality?.province
|
||||
?.region !=
|
||||
null) {
|
||||
Region currrentRegion = globalRegions!.firstWhere((Region region) =>
|
||||
Region currrentRegion = globalRegions.firstWhere((Region region) =>
|
||||
event.eligibityCert.examAddress!.cityMunicipality!.province!
|
||||
.region!.code ==
|
||||
region.code);
|
||||
|
@ -117,8 +117,8 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
cities: cities,
|
||||
isOverseas: isOverseas!,
|
||||
eligibityCert: event.eligibityCert,
|
||||
countries: globalCountries!,
|
||||
regions: globalRegions!,
|
||||
countries: globalCountries,
|
||||
regions: globalRegions,
|
||||
eligibilities: globalEligibilities));
|
||||
} else {
|
||||
emit(EditEligibilityState(
|
||||
|
@ -131,8 +131,8 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
currentEligibility: currentEligibility,
|
||||
isOverseas: isOverseas!,
|
||||
eligibityCert: event.eligibityCert,
|
||||
countries: globalCountries!,
|
||||
regions: globalRegions!,
|
||||
countries: globalCountries,
|
||||
regions: globalRegions,
|
||||
eligibilities: globalEligibilities));
|
||||
}
|
||||
} catch (e) {
|
||||
|
@ -164,7 +164,7 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
//// SHOW ADD FORM
|
||||
on<ShowAddEligibilityForm>((event, emit) async {
|
||||
emit(EligibilityLoadingState());
|
||||
if (globalRegions == null) {
|
||||
if (globalRegions.isEmpty) {
|
||||
List<Region> regions = await LocationUtils.instance.getRegions();
|
||||
globalRegions = regions;
|
||||
}
|
||||
|
@ -173,15 +173,15 @@ class EligibilityBloc extends Bloc<EligibilityEvent, EligibilityState> {
|
|||
await ProfileUtilities.instance.getEligibilities();
|
||||
globalEligibilities = eligibilities;
|
||||
}
|
||||
if (globalCountries == null) {
|
||||
if (globalCountries.isEmpty) {
|
||||
List<Country> countries = await LocationUtils.instance.getCountries();
|
||||
globalCountries = countries;
|
||||
}
|
||||
|
||||
emit(AddEligibilityState(
|
||||
eligibilities: globalEligibilities,
|
||||
regions: globalRegions!,
|
||||
countries: globalCountries!));
|
||||
regions: globalRegions,
|
||||
countries: globalCountries));
|
||||
});
|
||||
|
||||
//// ADD
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:unit2/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/basic_information/adress.dart';
|
||||
import '../../../../utils/location_utilities.dart';
|
||||
|
||||
part 'address_event.dart';
|
||||
part 'address_state.dart';
|
||||
|
||||
class AddressBloc extends Bloc<AddressEvent, AddressState> {
|
||||
AddressBloc() : super(AddressInitial()) {
|
||||
List<Country> globalCountries=[];
|
||||
List<Region> globalRegions=[];
|
||||
List<MainAdress> addresses = [];
|
||||
on<GetAddress>((event, emit) {
|
||||
emit(AddressLoadingState());
|
||||
|
@ -17,6 +25,46 @@ class AddressBloc extends Bloc<AddressEvent, AddressState> {
|
|||
}catch(e){
|
||||
emit(AddressErrorState(message: e.toString()));
|
||||
}
|
||||
//// show add form
|
||||
});on<ShowAddAddressForm>((event,emit)async{
|
||||
emit(AddressLoadingState());
|
||||
try{
|
||||
if (globalRegions.isEmpty) {
|
||||
List<Region> regions = await LocationUtils.instance.getRegions();
|
||||
globalRegions = regions;
|
||||
}
|
||||
if (globalCountries.isEmpty) {
|
||||
List<Country> countries = await LocationUtils.instance.getCountries();
|
||||
globalCountries = countries;
|
||||
}
|
||||
emit(AddAddressState(countries: globalCountries, regions: globalRegions));
|
||||
}catch(e){
|
||||
emit(AddressErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
|
||||
//// Show Edit Form
|
||||
on<ShowEditAddressForm>((event,emit)async{
|
||||
|
||||
try{
|
||||
if (globalRegions.isEmpty) {
|
||||
List<Region> regions = await LocationUtils.instance.getRegions();
|
||||
globalRegions = regions;
|
||||
}
|
||||
if (globalCountries.isEmpty) {
|
||||
List<Country> countries = await LocationUtils.instance.getCountries();
|
||||
globalCountries = countries;
|
||||
}
|
||||
emit(EditAddressState(countries: globalCountries, regions: globalRegions,address: event.address));
|
||||
}catch(e){
|
||||
emit(AddressErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
|
||||
////call error state
|
||||
on<CallErrorState>((event, emit) {
|
||||
emit(const AddressErrorState(
|
||||
message: "Something went wrong. Please try again"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,3 +13,13 @@ class GetAddress extends AddressEvent{
|
|||
@override
|
||||
List<Object> get props => [addresses];
|
||||
}
|
||||
class ShowAddAddressForm extends AddressEvent{
|
||||
|
||||
}
|
||||
class ShowEditAddressForm extends AddressEvent{
|
||||
final MainAdress address;
|
||||
const ShowEditAddressForm({required this.address});
|
||||
}
|
||||
class CallErrorState extends AddressEvent{
|
||||
|
||||
}
|
||||
|
|
|
@ -8,20 +8,40 @@ abstract class AddressState extends Equatable {
|
|||
}
|
||||
|
||||
class AddressInitial extends AddressState {}
|
||||
|
||||
class AddressLoadedState extends AddressState{
|
||||
final List<MainAdress> addresses;
|
||||
const AddressLoadedState({required this.addresses});
|
||||
@override
|
||||
//// LOADED STATE
|
||||
class AddressLoadedState extends AddressState {
|
||||
final List<MainAdress> addresses;
|
||||
const AddressLoadedState({required this.addresses});
|
||||
@override
|
||||
List<Object> get props => [addresses];
|
||||
}
|
||||
|
||||
class AddressErrorState extends AddressState{
|
||||
////ERROR STATE
|
||||
class AddressErrorState extends AddressState {
|
||||
final String message;
|
||||
const AddressErrorState({required this.message});
|
||||
@override
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
class AddressLoadingState extends AddressState{
|
||||
//// LOADING STATE
|
||||
class AddressLoadingState extends AddressState {}
|
||||
|
||||
////ADD ADDRESS STATE
|
||||
class AddAddressState extends AddressState {
|
||||
final List<Country> countries;
|
||||
final List<Region> regions;
|
||||
const AddAddressState(
|
||||
{
|
||||
required this.countries,
|
||||
required this.regions});
|
||||
@override
|
||||
List<Object> get props => [countries, regions,];
|
||||
}
|
||||
|
||||
class EditAddressState extends AddressState{
|
||||
final MainAdress address;
|
||||
final List<Country> countries;
|
||||
final List<Region> regions;
|
||||
const EditAddressState({required this.address, required this.countries, required this.regions});
|
||||
@override
|
||||
List<Object> get props => [countries, regions,address];
|
||||
}
|
|
@ -1,8 +1,14 @@
|
|||
import 'package:bloc/bloc.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:unit2/sevices/profile/volunatary_services.dart';
|
||||
import 'package:unit2/utils/profile_utilities.dart';
|
||||
|
||||
import '../../../model/location/country.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';
|
||||
|
||||
part 'voluntary_work_event.dart';
|
||||
part 'voluntary_work_state.dart';
|
||||
|
@ -10,6 +16,12 @@ part 'voluntary_work_state.dart';
|
|||
class VoluntaryWorkBloc extends Bloc<VoluntaryWorkEvent, VoluntaryWorkState> {
|
||||
VoluntaryWorkBloc() : super(VoluntaryWorkInitial()) {
|
||||
List<VoluntaryWork> voluntaryWorks = [];
|
||||
List<Country> globalCountries=[];
|
||||
List<Category> agencyCategory = [];
|
||||
List<Region> globalRegions=[];
|
||||
List<Position> agencyPositions = [];
|
||||
List<Agency> agencies = [];
|
||||
////Get Voluntary Works
|
||||
on<GetVoluntarWorks>((event, emit) async{
|
||||
emit(VoluntaryWorkLoadingState());
|
||||
try{
|
||||
|
@ -20,5 +32,35 @@ class VoluntaryWorkBloc extends Bloc<VoluntaryWorkEvent, VoluntaryWorkState> {
|
|||
emit(VoluntaryWorkErrorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
//// Show Add form Event
|
||||
on<ShowAddVoluntaryWorks>((event,emit)async{
|
||||
try{
|
||||
emit(VoluntaryWorkLoadingState());
|
||||
if (agencyPositions.isEmpty) {
|
||||
List<Position> positions =
|
||||
await ProfileUtilities.instance.getAgencyPosition();
|
||||
agencyPositions = positions;
|
||||
}
|
||||
|
||||
/////AGENCIES------------------------------------------
|
||||
if (agencies.isEmpty) {
|
||||
List<Agency> newAgencies =
|
||||
await ProfileUtilities.instance.getAgecies();
|
||||
agencies = newAgencies;
|
||||
}
|
||||
|
||||
/////Category Agency------------------------------------------
|
||||
if (agencyCategory.isEmpty) {
|
||||
List<Category> categoryAgencies =
|
||||
await ProfileUtilities.instance.agencyCategory();
|
||||
agencyCategory = categoryAgencies;
|
||||
}
|
||||
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));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,3 +14,11 @@ class GetVoluntarWorks extends VoluntaryWorkEvent{
|
|||
@override
|
||||
List<Object> get props => [profileId,token];
|
||||
}
|
||||
class ShowAddVoluntaryWorks extends VoluntaryWorkEvent{
|
||||
|
||||
}
|
||||
|
||||
class ShowErrorState extends VoluntaryWorkEvent{
|
||||
final String message;
|
||||
const ShowErrorState({required this.message});
|
||||
}
|
||||
|
|
|
@ -8,20 +8,33 @@ abstract class VoluntaryWorkState extends Equatable {
|
|||
}
|
||||
|
||||
class VoluntaryWorkInitial extends VoluntaryWorkState {}
|
||||
////Loaded State
|
||||
class VoluntaryWorkLoadedState extends VoluntaryWorkState{
|
||||
final List<VoluntaryWork> voluntaryWorks;
|
||||
const VoluntaryWorkLoadedState({required this.voluntaryWorks});
|
||||
@override
|
||||
List<Object> get props => [voluntaryWorks];
|
||||
}
|
||||
|
||||
////Error State
|
||||
class VoluntaryWorkErrorState extends VoluntaryWorkState{
|
||||
final String message;
|
||||
const VoluntaryWorkErrorState({required this.message});
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
|
||||
////Loading State
|
||||
class VoluntaryWorkLoadingState extends VoluntaryWorkState{
|
||||
|
||||
}
|
||||
|
||||
|
||||
class AddVoluntaryWorkState extends VoluntaryWorkState{
|
||||
final List<Position> positions;
|
||||
final List<Agency> agencies;
|
||||
final List<Category> agencyCategory;
|
||||
final List<Country> countries;
|
||||
final List<Region> regions;
|
||||
const AddVoluntaryWorkState({required this.agencies,required this.countries, required this.positions, required this.regions,required this.agencyCategory});
|
||||
@override
|
||||
List<Object> get props => [positions,agencies,countries,regions];
|
||||
}
|
|
@ -26,7 +26,7 @@ class WorkHistoryBloc extends Bloc<WorkHistorytEvent, WorkHistoryState> {
|
|||
try {
|
||||
if (workExperiences.isEmpty) {
|
||||
List<WorkHistory> works = await WorkHistoryService.instance
|
||||
.getWorkExperiences(event.profileId!, event.token!);
|
||||
.getWorkExperiences(event.profileId, event.token);
|
||||
workExperiences = works;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,207 @@
|
|||
// To parse this JSON data, do
|
||||
//
|
||||
// final document = documentFromJson(jsonString);
|
||||
|
||||
class Document {
|
||||
Document({
|
||||
required this.id,
|
||||
required this.sk,
|
||||
required this.dsk,
|
||||
required this.slug,
|
||||
required this.files,
|
||||
required this.title,
|
||||
required this.agency,
|
||||
required this.office,
|
||||
required this.subject,
|
||||
required this.fileType,
|
||||
required this.isPublic,
|
||||
required this.createdAt,
|
||||
required this.createdBy,
|
||||
required this.validatedAt,
|
||||
required this.validatedBy,
|
||||
required this.documentType,
|
||||
required this.documentRoutes,
|
||||
required this.alternateMobile,
|
||||
required this.attachedDocument,
|
||||
required this.enableNotification,
|
||||
required this.createdByPersonId,
|
||||
});
|
||||
|
||||
final int? id;
|
||||
final String? sk;
|
||||
final String? dsk;
|
||||
final String? slug;
|
||||
final List<FileElement>? files;
|
||||
final String? title;
|
||||
final String? agency;
|
||||
final String? office;
|
||||
final String? subject;
|
||||
final FileType? fileType;
|
||||
final bool? isPublic;
|
||||
final String? createdAt;
|
||||
final String? createdBy;
|
||||
final String? validatedAt;
|
||||
final String? validatedBy;
|
||||
final DocumentType? documentType;
|
||||
final dynamic documentRoutes;
|
||||
final AlternateMobile? alternateMobile;
|
||||
final dynamic attachedDocument;
|
||||
final bool? enableNotification;
|
||||
final int? createdByPersonId;
|
||||
|
||||
factory Document.fromJson(Map<String, dynamic> json) => Document(
|
||||
id: json["id"],
|
||||
sk: json["sk"],
|
||||
dsk: json["dsk"],
|
||||
slug: json["slug"],
|
||||
files: List<FileElement>.from(json["files"].map((x) => FileElement.fromJson(x))),
|
||||
title: json["title"],
|
||||
agency: json["agency"],
|
||||
office: json["office"],
|
||||
subject: json["subject"],
|
||||
fileType: FileType.fromJson(json["file_type"]),
|
||||
isPublic: json["is_public"],
|
||||
createdAt: json["created_at"],
|
||||
createdBy: json["created_by"],
|
||||
validatedAt: json["validated_at"],
|
||||
validatedBy: json["validated_by"],
|
||||
documentType: DocumentType.fromJson(json["document_type"]),
|
||||
documentRoutes: json["document_routes"],
|
||||
alternateMobile: AlternateMobile.fromJson(json["alternate_mobile"]),
|
||||
attachedDocument: json["attached_document"],
|
||||
enableNotification: json["enable_notification"],
|
||||
createdByPersonId: json["created_by_person_id"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"sk": sk,
|
||||
"dsk": dsk,
|
||||
"slug": slug,
|
||||
"files": List<dynamic>.from(files!.map((x) => x.toJson())),
|
||||
"title": title,
|
||||
"agency": agency,
|
||||
"office": office,
|
||||
"subject": subject,
|
||||
"file_type": fileType?.toJson(),
|
||||
"is_public": isPublic,
|
||||
"created_at": createdAt,
|
||||
"created_by": createdBy,
|
||||
"validated_at": validatedAt,
|
||||
"validated_by": validatedBy,
|
||||
"document_type": documentType?.toJson(),
|
||||
"document_routes": documentRoutes,
|
||||
"alternate_mobile": alternateMobile?.toJson(),
|
||||
"attached_document": attachedDocument,
|
||||
"enable_notification": enableNotification,
|
||||
"created_by_person_id": createdByPersonId,
|
||||
};
|
||||
}
|
||||
|
||||
class AlternateMobile {
|
||||
AlternateMobile({
|
||||
required this.id,
|
||||
required this.mobileNo,
|
||||
required this.documentId,
|
||||
});
|
||||
|
||||
final dynamic id;
|
||||
final dynamic mobileNo;
|
||||
final dynamic documentId;
|
||||
|
||||
factory AlternateMobile.fromJson(Map<String, dynamic> json) => AlternateMobile(
|
||||
id: json["id"],
|
||||
mobileNo: json["mobile_no"],
|
||||
documentId: json["document_id"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"mobile_no": mobileNo,
|
||||
"document_id": documentId,
|
||||
};
|
||||
}
|
||||
|
||||
class DocumentType {
|
||||
DocumentType({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.slug,
|
||||
required this.categoryId,
|
||||
required this.priorityNumber,
|
||||
});
|
||||
|
||||
final int id;
|
||||
final String name;
|
||||
final dynamic slug;
|
||||
final int categoryId;
|
||||
final dynamic priorityNumber;
|
||||
|
||||
factory DocumentType.fromJson(Map<String, dynamic> json) => DocumentType(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
slug: json["slug"],
|
||||
categoryId: json["category_id"],
|
||||
priorityNumber: json["priority_number"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"slug": slug,
|
||||
"category_id": categoryId,
|
||||
"priority_number": priorityNumber,
|
||||
};
|
||||
}
|
||||
|
||||
class FileType {
|
||||
FileType({
|
||||
required this.id,
|
||||
required this.name,
|
||||
required this.isActive,
|
||||
required this.extensions,
|
||||
});
|
||||
|
||||
final int id;
|
||||
final String name;
|
||||
final bool isActive;
|
||||
final List<String> extensions;
|
||||
|
||||
factory FileType.fromJson(Map<String, dynamic> json) => FileType(
|
||||
id: json["id"],
|
||||
name: json["name"],
|
||||
isActive: json["is_active"],
|
||||
extensions: List<String>.from(json["extensions"].map((x) => x)),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"name": name,
|
||||
"is_active": isActive,
|
||||
"extensions": List<dynamic>.from(extensions.map((x) => x)),
|
||||
};
|
||||
}
|
||||
|
||||
class FileElement {
|
||||
FileElement({
|
||||
required this.path,
|
||||
required this.extnsn,
|
||||
required this.dateTime,
|
||||
});
|
||||
|
||||
final String path;
|
||||
final String extnsn;
|
||||
final String dateTime;
|
||||
|
||||
factory FileElement.fromJson(Map<String, dynamic> json) => FileElement(
|
||||
path: json["path"],
|
||||
extnsn: json["extnsn"],
|
||||
dateTime: json["date_time"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"path": path,
|
||||
"extnsn": extnsn,
|
||||
"date_time": dateTime,
|
||||
};
|
||||
}
|
|
@ -26,7 +26,7 @@ class EducationalBackground {
|
|||
final String? periodTo;
|
||||
final dynamic attachments;
|
||||
final String? periodFrom;
|
||||
final dynamic unitsEarned;
|
||||
final int? unitsEarned;
|
||||
final String? yearGraduated;
|
||||
|
||||
factory EducationalBackground.fromJson(Map<String, dynamic> json) => EducationalBackground(
|
||||
|
|
|
@ -9,10 +9,10 @@ import 'package:unit2/utils/text_container.dart';
|
|||
import 'package:unit2/widgets/costum_divider.dart';
|
||||
import 'package:unit2/widgets/text_icon.dart';
|
||||
|
||||
import '../../test_data.dart';
|
||||
import '../../theme-data.dart/btn-style.dart';
|
||||
import '../../theme-data.dart/form-style.dart';
|
||||
import '../../utils/global.dart';
|
||||
import '../../../test_data.dart';
|
||||
import '../../../theme-data.dart/btn-style.dart';
|
||||
import '../../../theme-data.dart/form-style.dart';
|
||||
import '../../../utils/global.dart';
|
||||
|
||||
class RequetAutoReceipt extends StatefulWidget {
|
||||
RequetAutoReceipt({super.key});
|
||||
|
@ -124,7 +124,7 @@ class _RequetAutoReceiptState extends State<RequetAutoReceipt> {
|
|||
height: screenHeight * .06,
|
||||
child: ElevatedButton(
|
||||
style: secondaryBtnStyle(
|
||||
second, Colors.transparent, Colors.white54),
|
||||
primary, Colors.transparent, Colors.white54),
|
||||
child: const Text(
|
||||
requestAutoReceipt,
|
||||
style: TextStyle(color: Colors.white),
|
|
@ -0,0 +1,52 @@
|
|||
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_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:unit2/bloc/docsms/docsms_bloc.dart';
|
||||
import 'package:unit2/screens/docsms/components/request_receipt.dart';
|
||||
import 'package:unit2/widgets/error_state.dart';
|
||||
|
||||
class AutoReceiveDocument extends StatefulWidget {
|
||||
const AutoReceiveDocument({super.key});
|
||||
|
||||
@override
|
||||
State<AutoReceiveDocument> createState() => _AutoReceiveDocumentState();
|
||||
}
|
||||
|
||||
class _AutoReceiveDocumentState extends State<AutoReceiveDocument> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
backgroundColor: Colors.black87,
|
||||
indicatorWidget: const SpinKitFadingCircle(
|
||||
color: Colors.white,
|
||||
|
||||
),
|
||||
child: BlocConsumer<DocsmsBloc, DocsmsState>(
|
||||
listener: (context, state) {
|
||||
if (state is DocSmsLoadingState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
if (state is DocSmsErrorState || state is DocumentLoaded) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is DocumentLoaded) {
|
||||
return RequetAutoReceipt();
|
||||
}if(state is DocSmsErrorState){
|
||||
return SomethingWentWrong(message: state.message.toString(), onpressed: (){});
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,474 @@
|
|||
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:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:unit2/bloc/profile/primary_information/address/address_bloc.dart';
|
||||
import 'package:unit2/model/utils/category.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 '../../../../../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';
|
||||
|
||||
class AddAddressScreen extends StatefulWidget {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const AddAddressScreen(
|
||||
{super.key, required this.profileId, required this.token});
|
||||
|
||||
@override
|
||||
State<AddAddressScreen> createState() => _AddAddressScreenState();
|
||||
}
|
||||
|
||||
class _AddAddressScreenState extends State<AddAddressScreen> {
|
||||
////boolean
|
||||
bool hasLotandBlock = false;
|
||||
bool overseas = false;
|
||||
bool provinceCall = false;
|
||||
bool cityCall = false;
|
||||
bool barangayCall = false;
|
||||
////selected
|
||||
Region? selectedRegion;
|
||||
Province? selectedProvince;
|
||||
CityMunicipality? selectedMunicipality;
|
||||
Barangay? selectedBarangay;
|
||||
Country? selectedCountry;
|
||||
////Lists
|
||||
final List<Area> areaClass = [
|
||||
const Area(value: "Rural Area", group: 0),
|
||||
const Area(value: "Sitio", group: 1),
|
||||
const Area(value: "Village", group: 1),
|
||||
const Area(value: "Urban Area", group: 0),
|
||||
const Area(value: "Town", group: 1),
|
||||
const Area(value: "City", group: 1),
|
||||
const Area(value: "Metropolis", group: 1),
|
||||
const Area(value: "Megacity", group: 1),
|
||||
];
|
||||
final List<String> category = ["Permanent", "Residential", "Birthplace"];
|
||||
List<Province>? provinces;
|
||||
List<CityMunicipality>? citymuns;
|
||||
List<Barangay>? barangays;
|
||||
final formKey = GlobalKey<FormBuilderState>();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<AddressBloc, AddressState>(
|
||||
builder: (context, state) {
|
||||
if (state is AddAddressState) {
|
||||
return SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: screenHeight * .90,
|
||||
child: FormBuilder(
|
||||
key: formKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 25, horizontal: 18),
|
||||
child: Column(
|
||||
children: [
|
||||
//// category
|
||||
FormBuilderDropdown<String>(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
decoration:
|
||||
normalTextFieldStyle("Category*", "Category"),
|
||||
name: "category",
|
||||
onChanged: (String? category) {},
|
||||
items: category.map<DropdownMenuItem<String>>(
|
||||
(String category) {
|
||||
return DropdownMenuItem(
|
||||
value: category, child: Text(category));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////Area Class
|
||||
FormBuilderDropdown(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
decoration: normalTextFieldStyle(
|
||||
"Area class *", "Area class"),
|
||||
name: "area_class",
|
||||
onChanged: (Area? area) {},
|
||||
items: areaClass
|
||||
.map<DropdownMenuItem<Area>>((Area area) {
|
||||
return area.group == 0
|
||||
? DropdownMenuItem(
|
||||
enabled: false,
|
||||
value: area,
|
||||
child: Text(area.value.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Colors.black38)))
|
||||
: DropdownMenuItem(
|
||||
value: area,
|
||||
enabled: true,
|
||||
child: Text(
|
||||
" ${area.value.toUpperCase()}"));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////stateful builder
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
////with block & Lot Switch
|
||||
FormBuilderSwitch(
|
||||
initialValue: hasLotandBlock,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
hasLotandBlock = value!;
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"With Lot and Block?", 'Graduated?'),
|
||||
name: 'graudated',
|
||||
title: Text(hasLotandBlock ? "YES" : "NO"),
|
||||
),
|
||||
SizedBox(
|
||||
height: hasLotandBlock ? 12 : 0,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: hasLotandBlock
|
||||
? Row(
|
||||
children: [
|
||||
////block #
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: "block_number",
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Block #*", "Block #"),
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
//// lot #
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: "lot_number",
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Lot #*", "Lot #"),
|
||||
)),
|
||||
],
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// Address Line
|
||||
FormBuilderTextField(
|
||||
name: "address_line",
|
||||
decoration: normalTextFieldStyle(
|
||||
"Address Line *", "Address Line"),
|
||||
),
|
||||
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) {
|
||||
setState(() {
|
||||
barangayCall = true;
|
||||
});
|
||||
selectedMunicipality = city;
|
||||
getBarangays();
|
||||
}
|
||||
},
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Municipality*",
|
||||
"Municipality"),
|
||||
value: selectedMunicipality,
|
||||
items: citymuns == null
|
||||
? []
|
||||
: citymuns!.map<
|
||||
DropdownMenuItem<
|
||||
CityMunicipality>>(
|
||||
(CityMunicipality c) {
|
||||
return DropdownMenuItem(
|
||||
value: c,
|
||||
child: Text(c
|
||||
.description!));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
//// BARANGAY
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.white,
|
||||
inAsyncCall: barangayCall,
|
||||
child: DropdownButtonFormField<
|
||||
Barangay>(
|
||||
isExpanded: true,
|
||||
onChanged: (Barangay? baragay) {
|
||||
selectedBarangay = baragay;
|
||||
},
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Barangay*",
|
||||
"Barangay"),
|
||||
value: selectedBarangay,
|
||||
items: barangays == null
|
||||
? []
|
||||
: barangays!.map<
|
||||
DropdownMenuItem<
|
||||
Barangay>>(
|
||||
(Barangay barangay) {
|
||||
return DropdownMenuItem(
|
||||
value: barangay,
|
||||
child: Text(barangay
|
||||
.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) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
);
|
||||
}),
|
||||
////sumit button
|
||||
const Expanded(child: SizedBox()),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {},
|
||||
child: const Text(submit)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
return 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<AddressBloc>().add(CallErrorState());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getCities() async {
|
||||
try {
|
||||
List<CityMunicipality> newCities = await LocationUtils.instance
|
||||
.getCities(code: selectedProvince!.code.toString());
|
||||
citymuns = newCities;
|
||||
setState(() {
|
||||
selectedMunicipality = newCities[0];
|
||||
cityCall = false;
|
||||
barangayCall = true;
|
||||
getBarangays();
|
||||
});
|
||||
} catch (e) {
|
||||
context.read<AddressBloc>().add(CallErrorState());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getBarangays() async {
|
||||
try {
|
||||
List<Barangay> newBarangays = await LocationUtils.instance
|
||||
.getBarangay(code: selectedMunicipality!.code.toString());
|
||||
barangays = newBarangays;
|
||||
setState(() {
|
||||
selectedBarangay = newBarangays[0];
|
||||
barangayCall = false;
|
||||
});
|
||||
} catch (e) {
|
||||
context.read<AddressBloc>().add(CallErrorState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Area {
|
||||
final int group;
|
||||
final String value;
|
||||
const Area({required this.group, required this.value});
|
||||
}
|
|
@ -0,0 +1,474 @@
|
|||
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:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:unit2/bloc/profile/primary_information/address/address_bloc.dart';
|
||||
import 'package:unit2/model/utils/category.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 '../../../../../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';
|
||||
|
||||
class EditAddressScreen extends StatefulWidget {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const EditAddressScreen(
|
||||
{super.key, required this.profileId, required this.token});
|
||||
|
||||
@override
|
||||
State<EditAddressScreen> createState() => _EditAddressScreenState();
|
||||
}
|
||||
|
||||
class _EditAddressScreenState extends State<EditAddressScreen> {
|
||||
////boolean
|
||||
bool hasLotandBlock = false;
|
||||
bool overseas = false;
|
||||
bool provinceCall = false;
|
||||
bool cityCall = false;
|
||||
bool barangayCall = false;
|
||||
////selected
|
||||
Region? selectedRegion;
|
||||
Province? selectedProvince;
|
||||
CityMunicipality? selectedMunicipality;
|
||||
Barangay? selectedBarangay;
|
||||
Country? selectedCountry;
|
||||
////Lists
|
||||
final List<Area> areaClass = [
|
||||
const Area(value: "Rural Area", group: 0),
|
||||
const Area(value: "Sitio", group: 1),
|
||||
const Area(value: "Village", group: 1),
|
||||
const Area(value: "Urban Area", group: 0),
|
||||
const Area(value: "Town", group: 1),
|
||||
const Area(value: "City", group: 1),
|
||||
const Area(value: "Metropolis", group: 1),
|
||||
const Area(value: "Megacity", group: 1),
|
||||
];
|
||||
final List<String> category = ["Permanent", "Residential", "Birthplace"];
|
||||
List<Province>? provinces;
|
||||
List<CityMunicipality>? citymuns;
|
||||
List<Barangay>? barangays;
|
||||
final formKey = GlobalKey<FormBuilderState>();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<AddressBloc, AddressState>(
|
||||
builder: (context, state) {
|
||||
if (state is EditAddressState) {
|
||||
return SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: screenHeight * .90,
|
||||
child: FormBuilder(
|
||||
key: formKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 25, horizontal: 18),
|
||||
child: Column(
|
||||
children: [
|
||||
//// category
|
||||
FormBuilderDropdown<String>(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
decoration:
|
||||
normalTextFieldStyle("Category*", "Category"),
|
||||
name: "category",
|
||||
onChanged: (String? category) {},
|
||||
items: category.map<DropdownMenuItem<String>>(
|
||||
(String category) {
|
||||
return DropdownMenuItem(
|
||||
value: category, child: Text(category));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////Area Class
|
||||
FormBuilderDropdown(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
decoration: normalTextFieldStyle(
|
||||
"Area class *", "Area class"),
|
||||
name: "area_class",
|
||||
onChanged: (Area? area) {},
|
||||
items: areaClass
|
||||
.map<DropdownMenuItem<Area>>((Area area) {
|
||||
return area.group == 0
|
||||
? DropdownMenuItem(
|
||||
enabled: false,
|
||||
value: area,
|
||||
child: Text(area.value.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Colors.black38)))
|
||||
: DropdownMenuItem(
|
||||
value: area,
|
||||
enabled: true,
|
||||
child: Text(
|
||||
" ${area.value.toUpperCase()}"));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////stateful builder
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
////with block & Lot Switch
|
||||
FormBuilderSwitch(
|
||||
initialValue: hasLotandBlock,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
hasLotandBlock = value!;
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"With Lot and Block?", 'Graduated?'),
|
||||
name: 'graudated',
|
||||
title: Text(hasLotandBlock ? "YES" : "NO"),
|
||||
),
|
||||
SizedBox(
|
||||
height: hasLotandBlock ? 12 : 0,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: hasLotandBlock
|
||||
? Row(
|
||||
children: [
|
||||
////block #
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: "block_number",
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Block #*", "Block #"),
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
//// lot #
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: "lot_number",
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Lot #*", "Lot #"),
|
||||
)),
|
||||
],
|
||||
)
|
||||
: Container(),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// Address Line
|
||||
FormBuilderTextField(
|
||||
name: "address_line",
|
||||
decoration: normalTextFieldStyle(
|
||||
"Address Line *", "Address Line"),
|
||||
),
|
||||
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) {
|
||||
setState(() {
|
||||
barangayCall = true;
|
||||
});
|
||||
selectedMunicipality = city;
|
||||
getBarangays();
|
||||
}
|
||||
},
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Municipality*",
|
||||
"Municipality"),
|
||||
value: selectedMunicipality,
|
||||
items: citymuns == null
|
||||
? []
|
||||
: citymuns!.map<
|
||||
DropdownMenuItem<
|
||||
CityMunicipality>>(
|
||||
(CityMunicipality c) {
|
||||
return DropdownMenuItem(
|
||||
value: c,
|
||||
child: Text(c
|
||||
.description!));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
//// BARANGAY
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.white,
|
||||
inAsyncCall: barangayCall,
|
||||
child: DropdownButtonFormField<
|
||||
Barangay>(
|
||||
isExpanded: true,
|
||||
onChanged: (Barangay? baragay) {
|
||||
selectedBarangay = baragay;
|
||||
},
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Barangay*",
|
||||
"Barangay"),
|
||||
value: selectedBarangay,
|
||||
items: barangays == null
|
||||
? []
|
||||
: barangays!.map<
|
||||
DropdownMenuItem<
|
||||
Barangay>>(
|
||||
(Barangay barangay) {
|
||||
return DropdownMenuItem(
|
||||
value: barangay,
|
||||
child: Text(barangay
|
||||
.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) {},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
);
|
||||
}),
|
||||
////sumit button
|
||||
const Expanded(child: SizedBox()),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {},
|
||||
child: const Text(submit)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
)),
|
||||
),
|
||||
);
|
||||
}
|
||||
return 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<AddressBloc>().add(CallErrorState());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getCities() async {
|
||||
try {
|
||||
List<CityMunicipality> newCities = await LocationUtils.instance
|
||||
.getCities(code: selectedProvince!.code.toString());
|
||||
citymuns = newCities;
|
||||
setState(() {
|
||||
selectedMunicipality = newCities[0];
|
||||
cityCall = false;
|
||||
barangayCall = true;
|
||||
getBarangays();
|
||||
});
|
||||
} catch (e) {
|
||||
context.read<AddressBloc>().add(CallErrorState());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getBarangays() async {
|
||||
try {
|
||||
List<Barangay> newBarangays = await LocationUtils.instance
|
||||
.getBarangay(code: selectedMunicipality!.code.toString());
|
||||
barangays = newBarangays;
|
||||
setState(() {
|
||||
selectedBarangay = newBarangays[0];
|
||||
barangayCall = false;
|
||||
});
|
||||
} catch (e) {
|
||||
context.read<AddressBloc>().add(CallErrorState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Area {
|
||||
final int group;
|
||||
final String value;
|
||||
const Area({required this.group, required this.value});
|
||||
}
|
|
@ -1,10 +1,15 @@
|
|||
import 'package:app_popup_menu/app_popup_menu.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:unit2/bloc/profile/primary_information/address/address_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/model/profile/basic_information/adress.dart';
|
||||
import 'package:unit2/screens/profile/components/basic_information/address/add_modal.dart';
|
||||
import 'package:unit2/screens/profile/components/basic_information/address/edit_modal.dart';
|
||||
import 'package:unit2/theme-data.dart/box_shadow.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
|
@ -13,23 +18,37 @@ import 'package:unit2/widgets/Leadings/add_leading.dart';
|
|||
import 'package:unit2/widgets/empty_data.dart';
|
||||
import 'package:unit2/widgets/error_state.dart';
|
||||
|
||||
class AddressScreen extends StatelessWidget {
|
||||
import '../../../../utils/alerts.dart';
|
||||
|
||||
class AddressScreen extends StatelessWidget {
|
||||
const AddressScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
int? profileId;
|
||||
String? token;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text(adressScreenTitle),
|
||||
centerTitle: true,
|
||||
backgroundColor: primary,
|
||||
actions: [AddLeading(onPressed: () {})],
|
||||
actions: [
|
||||
AddLeading(onPressed: () {
|
||||
context.read<AddressBloc>().add(ShowAddAddressForm());
|
||||
})
|
||||
],
|
||||
),
|
||||
body: ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
indicatorWidget: const SpinKitFadingCircle(
|
||||
color: Colors.white,
|
||||
),
|
||||
backgroundColor: Colors.black87,
|
||||
child: BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
if (state is UserLoggedIn) {
|
||||
token = state.userData!.user!.login!.token;
|
||||
profileId = state.userData!.user!.login!.user!.profileId;
|
||||
return BlocBuilder<ProfileBloc, ProfileState>(
|
||||
builder: (context, state) {
|
||||
if (state is ProfileLoaded) {
|
||||
|
@ -40,7 +59,9 @@ class AddressScreen extends StatelessWidget {
|
|||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
if (state is AddressLoadedState ||
|
||||
state is AddressErrorState) {
|
||||
state is AddressErrorState ||
|
||||
state is AddAddressState ||
|
||||
state is EditAddressState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
|
@ -48,7 +69,7 @@ class AddressScreen extends StatelessWidget {
|
|||
builder: (context, state) {
|
||||
if (state is AddressLoadedState) {
|
||||
if (state.addresses.isNotEmpty) {
|
||||
return ListView.builder(
|
||||
return ListView.builder(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8, horizontal: 10),
|
||||
itemCount: state.addresses.length,
|
||||
|
@ -57,25 +78,25 @@ class AddressScreen extends StatelessWidget {
|
|||
String? subdivision =
|
||||
state.addresses[index].details ?? '';
|
||||
String category = state.addresses[index]
|
||||
.address!
|
||||
.category!
|
||||
.name!;
|
||||
.address!.category!.name!;
|
||||
String? barangay = state.addresses[index]
|
||||
.address!
|
||||
.barangay !=
|
||||
.address!.barangay !=
|
||||
null
|
||||
? '${state.addresses[index].address!.barangay!.description!.toUpperCase()},'
|
||||
: '';
|
||||
String cityMunicipality = state.addresses[index]
|
||||
String cityMunicipality = state
|
||||
.addresses[index]
|
||||
.address!
|
||||
.cityMunicipality!
|
||||
.description!;
|
||||
String province = state.addresses[index]
|
||||
String province = state
|
||||
.addresses[index]
|
||||
.address!
|
||||
.cityMunicipality!
|
||||
.province!
|
||||
.description!;
|
||||
String region = state.addresses[index]
|
||||
String region = state
|
||||
.addresses[index]
|
||||
.address!
|
||||
.cityMunicipality!
|
||||
.province!
|
||||
|
@ -128,12 +149,59 @@ class AddressScreen extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
)),
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
))
|
||||
AppPopupMenu<int>(
|
||||
offset:
|
||||
const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete eligibilty-= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context, () {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
////edit eligibilty-= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
|
||||
context
|
||||
.read<AddressBloc>()
|
||||
.add(ShowEditAddressForm(
|
||||
address: state
|
||||
.addresses[
|
||||
index]));
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Edit",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Delete",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attachment",
|
||||
value: 3,
|
||||
icon:
|
||||
FontAwesome.attach)
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
]),
|
||||
),
|
||||
],
|
||||
|
@ -150,6 +218,16 @@ class AddressScreen extends StatelessWidget {
|
|||
"You don't have address added. Please click + to add.");
|
||||
}
|
||||
}
|
||||
if (state is AddressErrorState) {
|
||||
return SomethingWentWrong(
|
||||
message: state.message, onpressed: () {});
|
||||
}
|
||||
if (state is AddAddressState) {
|
||||
return AddAddressScreen(
|
||||
profileId: profileId!, token: token!);
|
||||
}if(state is EditAddressState){
|
||||
return EditAddressScreen(profileId: profileId!, token: token!);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
|
@ -163,4 +241,23 @@ class AddressScreen 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!,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,510 @@
|
|||
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:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:searchfield/searchfield.dart';
|
||||
import 'package:unit2/bloc/profile/education/education_bloc.dart';
|
||||
import 'package:unit2/model/profile/educational_background.dart';
|
||||
import 'package:unit2/theme-data.dart/box_shadow.dart';
|
||||
import 'package:unit2/theme-data.dart/form-style.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
import 'package:multi_dropdown/multiselect_dropdown.dart';
|
||||
|
||||
import '../../../../theme-data.dart/btn-style.dart';
|
||||
import '../../../../theme-data.dart/colors.dart';
|
||||
import '../../../../utils/text_container.dart';
|
||||
import '../../shared/add_for_empty_search.dart';
|
||||
|
||||
class AddEducationScreen extends StatefulWidget {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const AddEducationScreen(
|
||||
{super.key, required this.profileId, required this.token});
|
||||
|
||||
@override
|
||||
State<AddEducationScreen> createState() => _AddEducationScreenState();
|
||||
}
|
||||
|
||||
class _AddEducationScreenState extends State<AddEducationScreen> {
|
||||
final List<EducationLevel> educationLevel = [
|
||||
const EducationLevel(type: "label", value: "Basic Education", group: 1),
|
||||
const EducationLevel(type: "level", value: "Elementary", group: 1),
|
||||
const EducationLevel(type: "level", value: "Secondary (non-K12)", group: 1),
|
||||
const EducationLevel(type: "level", value: "Junior High", group: 1),
|
||||
const EducationLevel(type: "level", value: "Senior High", group: 1),
|
||||
const EducationLevel(type: "label", value: "Higher Education", group: 2),
|
||||
const EducationLevel(type: "level", value: "Collegiate", group: 2),
|
||||
const EducationLevel(type: "level", value: "Vocational", group: 2),
|
||||
const EducationLevel(type: "label", value: "Post Graduate", group: 2),
|
||||
const EducationLevel(type: "level", value: "Masteral", group: 2),
|
||||
const EducationLevel(type: "level", value: "Doctorate", group: 2),
|
||||
];
|
||||
List<ValueItem> valueItemHonorList = [];
|
||||
////selected
|
||||
EducationLevel? selectedLevel;
|
||||
School? selectedSchool;
|
||||
Course? selectedProgram;
|
||||
List<Honor> selectedHonors = [];
|
||||
List<ValueItem>? selectedValueItem;
|
||||
final formKey = GlobalKey<FormBuilderState>();
|
||||
////congrollers
|
||||
final addProgramController = TextEditingController();
|
||||
final addSchoolController = TextEditingController();
|
||||
final fromController = TextEditingController();
|
||||
final untilController = TextEditingController();
|
||||
final yearGraduated = TextEditingController();
|
||||
////focus node
|
||||
final programFocusNode = FocusNode();
|
||||
final schoolFocusNode = FocusNode();
|
||||
final honorFocusNode = FocusNode();
|
||||
////booleans
|
||||
bool graduated = true;
|
||||
int? unitsEarned;
|
||||
////
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<EducationBloc, EducationState>(
|
||||
builder: (context, state) {
|
||||
if (state is AddEducationState) {
|
||||
valueItemHonorList = state.honors.map((Honor honor) {
|
||||
return ValueItem(label: honor.name!, value: honor.name);
|
||||
}).toList();
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 18),
|
||||
child: FormBuilder(
|
||||
key: formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: blockSizeVertical * 85,
|
||||
child: Column(children: [
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// LEVEL
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
FormBuilderDropdown(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
decoration:
|
||||
normalTextFieldStyle("level*", "level"),
|
||||
name: "education_level",
|
||||
onChanged: (EducationLevel? level) {
|
||||
setState(() {
|
||||
selectedLevel = level;
|
||||
});
|
||||
},
|
||||
items: educationLevel
|
||||
.map<DropdownMenuItem<EducationLevel>>(
|
||||
(EducationLevel level) {
|
||||
return level.type == "label"
|
||||
? DropdownMenuItem(
|
||||
enabled: false,
|
||||
value: level,
|
||||
child: Text(level.value.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Colors.black38)))
|
||||
: DropdownMenuItem(
|
||||
value: level,
|
||||
enabled: true,
|
||||
child: Text(
|
||||
" ${level.value.toUpperCase()}"));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////school
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return SearchField(
|
||||
itemHeight: 50,
|
||||
suggestionsDecoration: box1(),
|
||||
suggestions: state.schools
|
||||
.map((School school) =>
|
||||
SearchFieldListItem(school.name!,
|
||||
item: school,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10),
|
||||
child: ListTile(
|
||||
title: Text(school.name!)),
|
||||
)))
|
||||
.toList(),
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
focusNode: schoolFocusNode,
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("School *", "").copyWith(
|
||||
suffixIcon:
|
||||
const Icon(Icons.arrow_drop_down)),
|
||||
onSuggestionTap: (school) {
|
||||
setState(() {
|
||||
selectedSchool = school.item;
|
||||
schoolFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
emptyWidget: EmptyWidget(
|
||||
title: "Add School",
|
||||
controller: addSchoolController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
School newSchool = School(
|
||||
id: null,
|
||||
name: addSchoolController.text.toUpperCase());
|
||||
state.schools.insert(0, newSchool);
|
||||
addSchoolController.text = "";
|
||||
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}),
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////Programs
|
||||
Container(
|
||||
child: selectedLevel != null &&
|
||||
selectedLevel!.group != 1
|
||||
? SearchField(
|
||||
itemHeight: 50,
|
||||
suggestionsDecoration: box1(),
|
||||
suggestions: state.programs
|
||||
.map((Course program) =>
|
||||
SearchFieldListItem(
|
||||
program.program!,
|
||||
item: program,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets
|
||||
.symmetric(
|
||||
horizontal: 10),
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
program.program!)),
|
||||
)))
|
||||
.toList(),
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
focusNode: programFocusNode,
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle(
|
||||
"Course/Programs *", "")
|
||||
.copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down)),
|
||||
onSuggestionTap: (position) {
|
||||
setState(() {
|
||||
selectedProgram = position.item;
|
||||
programFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
emptyWidget: EmptyWidget(
|
||||
title: "Add Program",
|
||||
controller: addProgramController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Course newProgram = Course(
|
||||
id: null,
|
||||
program: addProgramController
|
||||
.text.toUpperCase());
|
||||
state.programs.insert(0,newProgram);
|
||||
addProgramController.text = "";
|
||||
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}),
|
||||
)
|
||||
: Container())
|
||||
],
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
//// GRADUATED SWITCH
|
||||
FormBuilderSwitch(
|
||||
initialValue: graduated,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
graduated = value!;
|
||||
if (graduated) {
|
||||
unitsEarned = null;
|
||||
} else {
|
||||
yearGraduated.text = "";
|
||||
}
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"Graduated?", 'Graduated?'),
|
||||
name: 'graudated',
|
||||
title: Text(graduated ? "YES" : "NO"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////FROM
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This fied is required"),
|
||||
decoration:
|
||||
normalTextFieldStyle("from *", "from"),
|
||||
name: "",
|
||||
controller: fromController,
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: 300,
|
||||
height: 300,
|
||||
child: YearPicker(
|
||||
firstDate: DateTime(
|
||||
DateTime.now().year - 100,
|
||||
1),
|
||||
lastDate: DateTime(
|
||||
DateTime.now().year + 100,
|
||||
1),
|
||||
initialDate: DateTime.now(),
|
||||
selectedDate: DateTime.now(),
|
||||
onChanged: (DateTime dateTime) {
|
||||
fromController.text =
|
||||
dateTime.year.toString();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
////UNTIL
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This fied is required"),
|
||||
decoration: normalTextFieldStyle(
|
||||
"until *", "until"),
|
||||
name: "",
|
||||
controller: untilController,
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: 300,
|
||||
height: 300,
|
||||
child: YearPicker(
|
||||
firstDate: DateTime(
|
||||
DateTime.now().year - 100,
|
||||
1),
|
||||
lastDate: DateTime(
|
||||
DateTime.now().year + 100,
|
||||
1),
|
||||
initialDate: DateTime.now(),
|
||||
selectedDate: DateTime.now(),
|
||||
onChanged: (DateTime dateTime) {
|
||||
untilController.text =
|
||||
dateTime.year.toString();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
child: graduated
|
||||
////GRADUATED YEAR
|
||||
? FormBuilderTextField(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This fied is required"),
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: 300,
|
||||
height: 300,
|
||||
child: YearPicker(
|
||||
firstDate: DateTime(
|
||||
DateTime.now().year - 100,
|
||||
1),
|
||||
lastDate: DateTime(
|
||||
DateTime.now().year + 100,
|
||||
1),
|
||||
initialDate: DateTime.now(),
|
||||
selectedDate: DateTime.now(),
|
||||
onChanged: (DateTime dateTime) {
|
||||
yearGraduated.text =
|
||||
dateTime.year.toString();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
name: "year_graduated",
|
||||
controller: yearGraduated,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Year Graduated *", "Year Graduated *"),
|
||||
)
|
||||
//// HIGHEST UNITS EARNED
|
||||
: FormBuilderTextField(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This fied is required"),
|
||||
name: "units_earned",
|
||||
decoration: normalTextFieldStyle(
|
||||
"Highest Level/Units Earned *",
|
||||
"Highest Level/Units Earned *")),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// HONORS
|
||||
MultiSelectDropDown(
|
||||
onOptionSelected: (List<ValueItem> selectedOptions) {
|
||||
selectedValueItem = selectedOptions;
|
||||
},
|
||||
borderColor: Colors.grey,
|
||||
borderWidth: 1,
|
||||
borderRadius: 5,
|
||||
hint: "Honors",
|
||||
padding: const EdgeInsets.all(8),
|
||||
options: valueItemHonorList,
|
||||
selectionType: SelectionType.multi,
|
||||
chipConfig: const ChipConfig(wrapType: WrapType.wrap),
|
||||
dropdownHeight: 300,
|
||||
optionTextStyle: const TextStyle(fontSize: 16),
|
||||
selectedOptionIcon: const Icon(Icons.check_circle),
|
||||
),
|
||||
////sumit button
|
||||
const Expanded(child: SizedBox()),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style:
|
||||
mainBtnStyle(primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
if (formKey.currentState!.saveAndValidate()) {
|
||||
//// program
|
||||
if (selectedLevel!.value == "Elementary" ||
|
||||
selectedLevel!.value ==
|
||||
"Secondary (non-K12)" ||
|
||||
selectedLevel!.value == "Junior High" ||
|
||||
selectedLevel!.value == "Senior High") {
|
||||
selectedProgram = null;
|
||||
}
|
||||
if (!graduated) {
|
||||
unitsEarned = int.parse(formKey
|
||||
.currentState!.value['units_earned']);
|
||||
}
|
||||
////education
|
||||
Education newEducation = Education(
|
||||
id: null,
|
||||
level: selectedLevel!.value,
|
||||
course: selectedProgram,
|
||||
school: selectedSchool);
|
||||
////honors
|
||||
if (selectedValueItem != null) {
|
||||
for (var honor in selectedValueItem!) {
|
||||
Honor newHonor = state.honors.firstWhere((element) => element.name == honor.value);
|
||||
selectedHonors.add(newHonor);
|
||||
}
|
||||
}
|
||||
|
||||
EducationalBackground educationalBackground =
|
||||
EducationalBackground(
|
||||
id: null,
|
||||
honors: null,
|
||||
education: newEducation,
|
||||
periodTo: untilController.text,
|
||||
periodFrom: fromController.text,
|
||||
yearGraduated:
|
||||
graduated ? yearGraduated.text : null,
|
||||
unitsEarned: !graduated ? unitsEarned : null,
|
||||
attachments: null,
|
||||
);
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Loading...");
|
||||
context.read<EducationBloc>().add(AddEducation(
|
||||
educationalBackground: educationalBackground,
|
||||
profileId: widget.profileId,
|
||||
token: widget.token,
|
||||
honors: selectedHonors));
|
||||
}
|
||||
},
|
||||
child: const Text(submit)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EducationLevel {
|
||||
final String value;
|
||||
final String type;
|
||||
final int group;
|
||||
const EducationLevel(
|
||||
{required this.type, required this.value, required this.group});
|
||||
}
|
|
@ -0,0 +1,564 @@
|
|||
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:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:searchfield/searchfield.dart';
|
||||
import 'package:unit2/bloc/profile/education/education_bloc.dart';
|
||||
import 'package:unit2/model/profile/educational_background.dart';
|
||||
import 'package:unit2/theme-data.dart/box_shadow.dart';
|
||||
import 'package:unit2/theme-data.dart/form-style.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
|
||||
import '../../../../theme-data.dart/btn-style.dart';
|
||||
import '../../../../theme-data.dart/colors.dart';
|
||||
import '../../../../utils/text_container.dart';
|
||||
import '../../shared/add_for_empty_search.dart';
|
||||
import 'package:multi_dropdown/multiselect_dropdown.dart';
|
||||
|
||||
class EditEducationScreen extends StatefulWidget {
|
||||
final int profileId;
|
||||
final String token;
|
||||
const EditEducationScreen(
|
||||
{super.key, required this.profileId, required this.token});
|
||||
|
||||
@override
|
||||
State<EditEducationScreen> createState() => _EditEducationScreenState();
|
||||
}
|
||||
|
||||
class _EditEducationScreenState extends State<EditEducationScreen> {
|
||||
final List<EducationLevel> educationLevel = [
|
||||
const EducationLevel(type: "label", value: "Basic Education", group: 1),
|
||||
const EducationLevel(type: "level", value: "Elementary", group: 1),
|
||||
const EducationLevel(type: "level", value: "Secondary (non-K12)", group: 1),
|
||||
const EducationLevel(type: "level", value: "Junior High", group: 1),
|
||||
const EducationLevel(type: "level", value: "Senior High", group: 1),
|
||||
const EducationLevel(type: "label", value: "Higher Education", group: 2),
|
||||
const EducationLevel(type: "level", value: "Collegiate", group: 2),
|
||||
const EducationLevel(type: "level", value: "Vocational", group: 2),
|
||||
const EducationLevel(type: "label", value: "Post Graduate", group: 2),
|
||||
const EducationLevel(type: "level", value: "Masteral", group: 2),
|
||||
const EducationLevel(type: "level", value: "Doctorate", group: 2),
|
||||
];
|
||||
List<ValueItem> valueItemHonorList = [];
|
||||
List<ValueItem> selectedValueItem = [];
|
||||
////selected
|
||||
EducationLevel? selectedLevel;
|
||||
School? selectedSchool;
|
||||
Course? selectedProgram;
|
||||
List<Honor> selectedHonors = [];
|
||||
final formKey = GlobalKey<FormBuilderState>();
|
||||
////congrollers
|
||||
final addProgramController = TextEditingController();
|
||||
final addSchoolController = TextEditingController();
|
||||
final fromController = TextEditingController();
|
||||
final untilController = TextEditingController();
|
||||
final yearGraduated = TextEditingController();
|
||||
final currentSchoolController = TextEditingController();
|
||||
final currentProgramController = TextEditingController();
|
||||
final unitsController = TextEditingController(); ////focus node
|
||||
final programFocusNode = FocusNode();
|
||||
final schoolFocusNode = FocusNode();
|
||||
final honorFocusNode = FocusNode();
|
||||
////booleans
|
||||
bool graduated = true;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<EducationBloc, EducationState>(
|
||||
builder: (context, state) {
|
||||
if (state is EditEducationState) {
|
||||
////selected level
|
||||
selectedLevel = educationLevel.firstWhere((element) =>
|
||||
element.value.toUpperCase() ==
|
||||
state.educationalBackground.education!.level);
|
||||
|
||||
currentSchoolController.text =
|
||||
state.educationalBackground.education!.school!.name!;
|
||||
if (selectedLevel != null && selectedLevel!.group != 1) {
|
||||
currentProgramController.text =
|
||||
state.educationalBackground.education!.course!.program!;
|
||||
}
|
||||
////year grduated and units earned
|
||||
if (state.educationalBackground.yearGraduated != null) {
|
||||
graduated = true;
|
||||
yearGraduated.text = state.educationalBackground.yearGraduated!;
|
||||
} else {
|
||||
unitsController.text =
|
||||
state.educationalBackground.unitsEarned.toString();
|
||||
graduated = false;
|
||||
}
|
||||
fromController.text = state.educationalBackground.periodFrom!;
|
||||
untilController.text = state.educationalBackground.periodTo!;
|
||||
////honors
|
||||
|
||||
////get all honors
|
||||
valueItemHonorList = state.honors.map((Honor honor) {
|
||||
return ValueItem(label: honor.name!, value: honor.name);
|
||||
}).toList();
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 25, horizontal: 18),
|
||||
child: FormBuilder(
|
||||
key: formKey,
|
||||
child: SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: blockSizeVertical * 85,
|
||||
child: Column(children: [
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// LEVEL
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
FormBuilderDropdown(
|
||||
initialValue: selectedLevel,
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
decoration:
|
||||
normalTextFieldStyle("level*", "level"),
|
||||
name: "education_level",
|
||||
onChanged: (EducationLevel? level) {
|
||||
setState(() {
|
||||
selectedLevel = level;
|
||||
});
|
||||
},
|
||||
items: educationLevel
|
||||
.map<DropdownMenuItem<EducationLevel>>(
|
||||
(EducationLevel level) {
|
||||
return level.type == "label"
|
||||
? DropdownMenuItem(
|
||||
enabled: false,
|
||||
value: level,
|
||||
child: Text(level.value.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
color: Colors.black38)))
|
||||
: DropdownMenuItem(
|
||||
value: level,
|
||||
enabled: true,
|
||||
child: Text(
|
||||
" ${level.value.toUpperCase()}"));
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////school
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return SearchField(
|
||||
controller: currentSchoolController,
|
||||
itemHeight: 50,
|
||||
suggestionsDecoration: box1(),
|
||||
suggestions: state.schools
|
||||
.map((School school) =>
|
||||
SearchFieldListItem(school.name!,
|
||||
item: school,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10),
|
||||
child: ListTile(
|
||||
title: Text(school.name!)),
|
||||
)))
|
||||
.toList(),
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
focusNode: schoolFocusNode,
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("School *", "").copyWith(
|
||||
suffixIcon:
|
||||
const Icon(Icons.arrow_drop_down)),
|
||||
onSuggestionTap: (school) {
|
||||
setState(() {
|
||||
selectedSchool = school.item;
|
||||
schoolFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
emptyWidget: EmptyWidget(
|
||||
title: "Add School",
|
||||
controller: addSchoolController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
School newSchool = School(
|
||||
id: null,
|
||||
name: addSchoolController.text
|
||||
.toUpperCase());
|
||||
state.schools.insert(0, newSchool);
|
||||
addSchoolController.text = "";
|
||||
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}),
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////Programs
|
||||
Container(
|
||||
child: selectedLevel != null &&
|
||||
selectedLevel!.group != 1
|
||||
? SearchField(
|
||||
suggestionAction:
|
||||
SuggestionAction.unfocus,
|
||||
controller: currentProgramController,
|
||||
itemHeight: 50,
|
||||
suggestionsDecoration: box1(),
|
||||
suggestions: state.programs
|
||||
.map((Course program) =>
|
||||
SearchFieldListItem(
|
||||
program.program!,
|
||||
item: program,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets
|
||||
.symmetric(
|
||||
horizontal: 10),
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
program.program!)),
|
||||
)))
|
||||
.toList(),
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
focusNode: programFocusNode,
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle(
|
||||
"Course/Programs *", "")
|
||||
.copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down)),
|
||||
onSuggestionTap: (position) {
|
||||
setState(() {
|
||||
selectedProgram = position.item;
|
||||
programFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
emptyWidget: EmptyWidget(
|
||||
title: "Add Program",
|
||||
controller: addProgramController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Course newProgram = Course(
|
||||
id: null,
|
||||
program: addProgramController
|
||||
.text
|
||||
.toUpperCase());
|
||||
state.programs
|
||||
.insert(0, newProgram);
|
||||
addProgramController.text = "";
|
||||
|
||||
Navigator.pop(context);
|
||||
});
|
||||
}),
|
||||
)
|
||||
: Container())
|
||||
],
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
children: [
|
||||
//// GRADUATED SWITCH
|
||||
FormBuilderSwitch(
|
||||
initialValue: graduated,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
graduated = value!;
|
||||
if (graduated) {
|
||||
unitsController.text = "";
|
||||
} else {
|
||||
yearGraduated.text = "";
|
||||
}
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle(
|
||||
"Graduated?", 'Graduated?'),
|
||||
name: 'graudated',
|
||||
title: Text(graduated ? "YES" : "NO"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
////FROM
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This fied is required"),
|
||||
decoration:
|
||||
normalTextFieldStyle("from *", "from"),
|
||||
name: "",
|
||||
controller: fromController,
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: 300,
|
||||
height: 300,
|
||||
child: YearPicker(
|
||||
firstDate: DateTime(
|
||||
DateTime.now().year - 100,
|
||||
1),
|
||||
lastDate: DateTime(
|
||||
DateTime.now().year + 100,
|
||||
1),
|
||||
initialDate: DateTime.now(),
|
||||
selectedDate: DateTime.now(),
|
||||
onChanged: (DateTime dateTime) {
|
||||
fromController.text =
|
||||
dateTime.year.toString();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
////UNTIL
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This fied is required"),
|
||||
decoration: normalTextFieldStyle(
|
||||
"until *", "until"),
|
||||
name: "",
|
||||
controller: untilController,
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: 300,
|
||||
height: 300,
|
||||
child: YearPicker(
|
||||
firstDate: DateTime(
|
||||
DateTime.now().year - 100,
|
||||
1),
|
||||
lastDate: DateTime(
|
||||
DateTime.now().year + 100,
|
||||
1),
|
||||
initialDate: DateTime.now(),
|
||||
selectedDate: DateTime.now(),
|
||||
onChanged: (DateTime dateTime) {
|
||||
untilController.text =
|
||||
dateTime.year.toString();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: graduated
|
||||
////GRADUATED YEAR
|
||||
? FormBuilderTextField(
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This fied is required"),
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: 300,
|
||||
height: 300,
|
||||
child: YearPicker(
|
||||
firstDate: DateTime(
|
||||
DateTime.now().year -
|
||||
100,
|
||||
1),
|
||||
lastDate: DateTime(
|
||||
DateTime.now().year +
|
||||
100,
|
||||
1),
|
||||
initialDate:
|
||||
DateTime.now(),
|
||||
selectedDate:
|
||||
DateTime.now(),
|
||||
onChanged:
|
||||
(DateTime dateTime) {
|
||||
yearGraduated.text =
|
||||
dateTime.year
|
||||
.toString();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
name: "year_graduated",
|
||||
controller: yearGraduated,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Year Graduated *",
|
||||
"Year Graduated *"),
|
||||
)
|
||||
//// HIGHEST UNITS EARNED
|
||||
: FormBuilderTextField(
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This fied is required"),
|
||||
controller: unitsController,
|
||||
name: "units_earned",
|
||||
decoration: normalTextFieldStyle(
|
||||
"Highest Level/Units Earned *",
|
||||
"Highest Level/Units Earned *")),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
//// HONORS
|
||||
|
||||
StatefulBuilder(builder: (context, setState) {
|
||||
return MultiSelectDropDown(
|
||||
onOptionSelected: (List<ValueItem> selectedOptions) {
|
||||
selectedValueItem = selectedOptions;
|
||||
},
|
||||
borderColor: Colors.grey,
|
||||
borderWidth: 1,
|
||||
borderRadius: 5,
|
||||
hint: "Honors",
|
||||
padding: const EdgeInsets.all(8),
|
||||
options: valueItemHonorList,
|
||||
selectionType: SelectionType.multi,
|
||||
chipConfig: const ChipConfig(wrapType: WrapType.wrap),
|
||||
dropdownHeight: 300,
|
||||
optionTextStyle: const TextStyle(fontSize: 16),
|
||||
selectedOptionIcon: const Icon(Icons.check_circle),
|
||||
selectedOptions:
|
||||
(state.educationalBackground.honors!.isNotEmpty &&
|
||||
state.educationalBackground.honors != null)
|
||||
? selectedValueItem = state
|
||||
.educationalBackground.honors!
|
||||
.map((Honor honor) => ValueItem(
|
||||
label: honor.name!, value: honor.name))
|
||||
.toList()
|
||||
: [],
|
||||
);
|
||||
}),
|
||||
////sumit button
|
||||
const Expanded(child: SizedBox()),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style:
|
||||
mainBtnStyle(primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
if (formKey.currentState!.saveAndValidate()) {
|
||||
//// program
|
||||
if (selectedLevel!.value == "Elementary" ||
|
||||
selectedLevel!.value ==
|
||||
"Secondary (non-K12)" ||
|
||||
selectedLevel!.value == "Junior High" ||
|
||||
selectedLevel!.value == "Senior High") {
|
||||
selectedProgram = null;
|
||||
}else{
|
||||
selectedProgram ??= state.educationalBackground.education!.course;
|
||||
}
|
||||
selectedSchool ??= state.educationalBackground.education!.school;
|
||||
////education
|
||||
Education newEducation = Education(
|
||||
id: null,
|
||||
level: selectedLevel!.value,
|
||||
course: selectedProgram,
|
||||
school: selectedSchool);
|
||||
////honors
|
||||
if (selectedValueItem.isNotEmpty) {
|
||||
for (var honor in selectedValueItem) {
|
||||
Honor newHonor = state.honors.firstWhere(
|
||||
(element) => element.name == honor.value);
|
||||
selectedHonors.add(newHonor);
|
||||
}
|
||||
}
|
||||
EducationalBackground educationalBackground =
|
||||
EducationalBackground(
|
||||
id: state.educationalBackground.id,
|
||||
honors: null,
|
||||
education: newEducation,
|
||||
periodTo: untilController.text,
|
||||
periodFrom: fromController.text,
|
||||
yearGraduated:
|
||||
graduated ? yearGraduated.text : null,
|
||||
unitsEarned: !graduated
|
||||
? int.parse(unitsController.text)
|
||||
: null,
|
||||
attachments: null,
|
||||
);
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Loading...");
|
||||
context.read<EducationBloc>().add(UpdateEducation(
|
||||
educationalBackground: educationalBackground,
|
||||
profileId: widget.profileId,
|
||||
token: widget.token,
|
||||
honors: selectedHonors));
|
||||
}
|
||||
},
|
||||
child: const Text(submit)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class EducationLevel {
|
||||
final String value;
|
||||
final String type;
|
||||
final int group;
|
||||
const EducationLevel(
|
||||
{required this.type, required this.value, required this.group});
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
import 'package:app_popup_menu/app_popup_menu.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
|
||||
import 'package:unit2/model/profile/educational_background.dart';
|
||||
import 'package:unit2/screens/profile/components/education/add_modal.dart';
|
||||
import 'package:unit2/theme-data.dart/box_shadow.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/utils/text_container.dart';
|
||||
|
@ -14,18 +17,26 @@ import 'package:unit2/widgets/empty_data.dart';
|
|||
import 'package:unit2/widgets/error_state.dart';
|
||||
|
||||
import '../../../bloc/profile/education/education_bloc.dart';
|
||||
import '../../../utils/alerts.dart';
|
||||
import 'education/edit_modal.dart';
|
||||
|
||||
class EducationScreen extends StatelessWidget {
|
||||
const EducationScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
int profileId;
|
||||
String? token;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text(educationScreenTitle),
|
||||
centerTitle: true,
|
||||
backgroundColor: primary,
|
||||
actions: [AddLeading(onPressed: () {})],
|
||||
actions: [
|
||||
AddLeading(onPressed: () {
|
||||
context.read<EducationBloc>().add(ShowAddEducationForm());
|
||||
})
|
||||
],
|
||||
),
|
||||
//userbloc
|
||||
body: ProgressHUD(
|
||||
|
@ -35,6 +46,8 @@ class EducationScreen extends StatelessWidget {
|
|||
child: BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
if (state is UserLoggedIn) {
|
||||
token = state.userData!.user!.login!.token;
|
||||
profileId = state.userData!.user!.login!.user!.profileId!;
|
||||
//profilebloc
|
||||
return BlocBuilder<ProfileBloc, ProfileState>(
|
||||
builder: (context, state) {
|
||||
|
@ -47,10 +60,77 @@ class EducationScreen extends StatelessWidget {
|
|||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
if (state is EducationalBackgroundLoadedState ||
|
||||
state is EducationalBackgroundErrorState) {
|
||||
state is EducationalBackgroundErrorState ||
|
||||
state is AddEducationState ||
|
||||
state is EditEducationState ||
|
||||
state is EducationDeletedState || state is EditedEducationState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
////ADDED STATE
|
||||
if (state is EducationAddedState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Adding Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Adding Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
}
|
||||
}
|
||||
////EDITED STATE
|
||||
|
||||
if (state is EditedEducationState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Update Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Updated Failed",
|
||||
"Something went wrong. Please try again.",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
}
|
||||
}
|
||||
////DELETED STATE
|
||||
if (state is EducationDeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Deletion Successfull",
|
||||
"Educational Background has been deleted successfully",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Deletion Failed",
|
||||
"Error deleting Education Background", () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(LoadEducations());
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is EducationalBackgroundLoadedState) {
|
||||
|
@ -181,12 +261,67 @@ class EducationScreen extends StatelessWidget {
|
|||
),
|
||||
]),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {},
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
))
|
||||
AppPopupMenu<int>(
|
||||
offset: const Offset(-10, -10),
|
||||
elevation: 3,
|
||||
onSelected: (value) {
|
||||
////delete -= = = = = = = = =>>
|
||||
if (value == 2) {
|
||||
confirmAlert(context, () {
|
||||
final progress =
|
||||
ProgressHUD.of(
|
||||
context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(DeleteEducation(
|
||||
educationalBackground:
|
||||
state.educationalBackground[
|
||||
index],
|
||||
profileId:
|
||||
profileId,
|
||||
token: token!));
|
||||
}, "Delete?",
|
||||
"Confirm Delete?");
|
||||
}
|
||||
if (value == 1) {
|
||||
////edit -= = = = = = = = =>>
|
||||
final progress =
|
||||
ProgressHUD.of(context);
|
||||
progress!.showWithText(
|
||||
"Loading...");
|
||||
context
|
||||
.read<EducationBloc>()
|
||||
.add(ShowEditEducationForm(
|
||||
profileId:
|
||||
profileId,
|
||||
token: token!,
|
||||
educationalBackground:
|
||||
state.educationalBackground[
|
||||
index]));
|
||||
}
|
||||
},
|
||||
menuItems: [
|
||||
popMenuItem(
|
||||
text: "Edit",
|
||||
value: 1,
|
||||
icon: Icons.edit),
|
||||
popMenuItem(
|
||||
text: "Delete",
|
||||
value: 2,
|
||||
icon: Icons.delete),
|
||||
popMenuItem(
|
||||
text: "Attachment",
|
||||
value: 3,
|
||||
icon: FontAwesome.attach)
|
||||
],
|
||||
icon: const Icon(
|
||||
Icons.more_vert,
|
||||
color: Colors.grey,
|
||||
),
|
||||
tooltip: "Options",
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -206,6 +341,18 @@ class EducationScreen extends StatelessWidget {
|
|||
return SomethingWentWrong(
|
||||
message: state.message, onpressed: () {});
|
||||
}
|
||||
if (state is AddEducationState) {
|
||||
return AddEducationScreen(
|
||||
token: token!,
|
||||
profileId: profileId,
|
||||
);
|
||||
}
|
||||
if (state is EditEducationState) {
|
||||
return EditEducationScreen(
|
||||
token: token!,
|
||||
profileId: profileId,
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
|
@ -219,4 +366,23 @@ class EducationScreen 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!,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,383 +64,399 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
|
|||
return SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
height: screenHeight * .95,
|
||||
child: ProgressHUD(
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 25, horizontal: 18),
|
||||
child: FormBuilder(
|
||||
key: formKey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
////ELIGIBILITIES DROPDOWN
|
||||
FormBuilderDropdown<Eligibility>(
|
||||
onChanged: (Eligibility? eligibility) {
|
||||
selectedEligibility = eligibility;
|
||||
},
|
||||
autovalidateMode:
|
||||
AutovalidateMode.onUserInteraction,
|
||||
validator: (value) =>
|
||||
value == null ? 'required' : null,
|
||||
items: state.eligibilities
|
||||
.map<DropdownMenuItem<Eligibility>>(
|
||||
(Eligibility eligibility) {
|
||||
return DropdownMenuItem<Eligibility>(
|
||||
value: eligibility,
|
||||
child: Text(eligibility.title));
|
||||
}).toList(),
|
||||
name: "eligibility",
|
||||
decoration: normalTextFieldStyle(
|
||||
"Eligibility", "Eligibility")),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
child: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 25, horizontal: 18),
|
||||
child: FormBuilder(
|
||||
key: formKey,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
////ELIGIBILITIES DROPDOWN
|
||||
FormBuilderDropdown<Eligibility>(
|
||||
onChanged: (Eligibility? eligibility) {
|
||||
selectedEligibility = eligibility;
|
||||
},
|
||||
autovalidateMode:
|
||||
AutovalidateMode.onUserInteraction,
|
||||
validator: (value) =>
|
||||
value == null ? 'required' : null,
|
||||
items: state.eligibilities
|
||||
.map<DropdownMenuItem<Eligibility>>(
|
||||
(Eligibility eligibility) {
|
||||
return DropdownMenuItem<Eligibility>(
|
||||
value: eligibility,
|
||||
child: Text(eligibility.title));
|
||||
}).toList(),
|
||||
name: "eligibility",
|
||||
decoration: normalTextFieldStyle(
|
||||
"Eligibility", "Eligibility")),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
////LICENSE NUMBER
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
onChanged: (value) {
|
||||
license = value;
|
||||
},
|
||||
name: 'license_number',
|
||||
decoration: normalTextFieldStyle(
|
||||
"license number", "license number"),
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
////LICENSE NUMBER
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
onChanged: (value) {
|
||||
license = value;
|
||||
},
|
||||
name: 'license_number',
|
||||
decoration: normalTextFieldStyle(
|
||||
"license number", "license number"),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
////RATING
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
keyboardType: const TextInputType
|
||||
.numberWithOptions(),
|
||||
onChanged: (value) {
|
||||
rating = value;
|
||||
},
|
||||
name: 'rating',
|
||||
decoration: normalTextFieldStyle(
|
||||
'rating %', 'rating'),
|
||||
),
|
||||
////RATING
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
keyboardType:
|
||||
const TextInputType.numberWithOptions(),
|
||||
onChanged: (value) {
|
||||
rating = value;
|
||||
},
|
||||
name: 'rating',
|
||||
decoration: normalTextFieldStyle(
|
||||
'rating %', 'rating'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
////EXAM DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: DateTimePicker(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
use24HourFormat: false,
|
||||
icon: const Icon(Icons.date_range),
|
||||
controller: examDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
timeHintText:
|
||||
"Date of Examination/Conferment",
|
||||
decoration:
|
||||
normalTextFieldStyle("Exam date", "")
|
||||
.copyWith(
|
||||
prefixIcon: const Icon(
|
||||
Icons.date_range,
|
||||
color: Colors.black87,
|
||||
)),
|
||||
initialValue: null,
|
||||
)),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
////VALIDITY DATE
|
||||
Flexible(
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(
|
||||
children: [
|
||||
////EXAM DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: DateTimePicker(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
controller: validityDateController,
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
use24HourFormat: false,
|
||||
icon: const Icon(Icons.date_range),
|
||||
controller: examDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
timeHintText:
|
||||
"Date of Examination/Conferment",
|
||||
decoration: normalTextFieldStyle(
|
||||
"Validity date", "Validity date")
|
||||
"Exam date", "")
|
||||
.copyWith(
|
||||
prefixIcon: const Icon(
|
||||
Icons.date_range,
|
||||
color: Colors.black87,
|
||||
)),
|
||||
initialValue: null,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(
|
||||
"Placement of Examination/Conferment",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.displaySmall!
|
||||
.copyWith(fontSize: blockSizeVertical * 2),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
////OVERSEAS ADDRESS SWITCH
|
||||
Column(
|
||||
children: [
|
||||
FormBuilderSwitch(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: 'This field is required'),
|
||||
initialValue: overseas,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
overseas = value;
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle("", ''),
|
||||
name: 'overseas',
|
||||
title: const Text("Overseas Address?"),
|
||||
),
|
||||
)),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
width: 8,
|
||||
),
|
||||
////COUNTRY DROPDOWN
|
||||
SizedBox(
|
||||
child: overseas == true
|
||||
? 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;
|
||||
},
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
////REGION DROPDOWN
|
||||
FormBuilderDropdown<Region?>(
|
||||
autovalidateMode: AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator:
|
||||
FormBuilderValidators.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
//// region onchange
|
||||
onChanged: (Region? region) async {
|
||||
|
||||
if(selectedRegion != region){
|
||||
setState(() {
|
||||
////VALIDITY DATE
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: DateTimePicker(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
controller: validityDateController,
|
||||
firstDate: DateTime(1970),
|
||||
lastDate: DateTime(2100),
|
||||
decoration: normalTextFieldStyle(
|
||||
"Validity date", "Validity date")
|
||||
.copyWith(
|
||||
prefixIcon: const Icon(
|
||||
Icons.date_range,
|
||||
color: Colors.black87,
|
||||
)),
|
||||
initialValue: null,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Text(
|
||||
"Placement of Examination/Conferment",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.displaySmall!
|
||||
.copyWith(fontSize: blockSizeVertical * 2),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
////OVERSEAS ADDRESS SWITCH
|
||||
Column(
|
||||
children: [
|
||||
FormBuilderSwitch(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: 'This field is required'),
|
||||
initialValue: overseas,
|
||||
activeColor: second,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
overseas = value;
|
||||
});
|
||||
},
|
||||
decoration: normalTextFieldStyle("", ''),
|
||||
name: 'overseas',
|
||||
title: const Text("Overseas Address?"),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
////COUNTRY DROPDOWN
|
||||
SizedBox(
|
||||
child: overseas == true
|
||||
? 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;
|
||||
},
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
////REGION DROPDOWN
|
||||
FormBuilderDropdown<Region?>(
|
||||
autovalidateMode:
|
||||
AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
//// region onchange
|
||||
onChanged:
|
||||
(Region? region) async {
|
||||
if (selectedRegion !=
|
||||
region) {
|
||||
setState(() {
|
||||
provinceCall = true;
|
||||
});
|
||||
selectedRegion = region;
|
||||
selectedRegion = region;
|
||||
getProvinces();
|
||||
}
|
||||
},
|
||||
initialValue: selectedRegion,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Region*", "Region"),
|
||||
name: 'region',
|
||||
items: state.regions
|
||||
.map<DropdownMenuItem<Region>>(
|
||||
(Region region) {
|
||||
return DropdownMenuItem<Region>(
|
||||
value: region,
|
||||
child: Text(
|
||||
region.description!));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
////PROVINCE DROPDOWN
|
||||
SizedBox(
|
||||
height: 70,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.transparent,
|
||||
inAsyncCall: provinceCall,
|
||||
child: DropdownButtonFormField<
|
||||
Province?>(
|
||||
autovalidateMode:
|
||||
AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator: (value) =>
|
||||
value == null
|
||||
? 'required'
|
||||
: null,
|
||||
isExpanded: true,
|
||||
value: selectedProvince,
|
||||
onChanged:
|
||||
(Province? province) {
|
||||
|
||||
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")),
|
||||
),
|
||||
),
|
||||
|
||||
//// CityMunicipalities dropdown
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.white,
|
||||
inAsyncCall: cityCall,
|
||||
child: DropdownButtonFormField<
|
||||
CityMunicipality>(
|
||||
}
|
||||
},
|
||||
initialValue: selectedRegion,
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Region*", "Region"),
|
||||
name: 'region',
|
||||
items: state.regions.map<
|
||||
DropdownMenuItem<
|
||||
Region>>(
|
||||
(Region region) {
|
||||
return DropdownMenuItem<
|
||||
Region>(
|
||||
value: region,
|
||||
child: Text(
|
||||
region.description!));
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
////PROVINCE DROPDOWN
|
||||
SizedBox(
|
||||
height: 70,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.transparent,
|
||||
inAsyncCall: provinceCall,
|
||||
child: DropdownButtonFormField<
|
||||
Province?>(
|
||||
autovalidateMode:
|
||||
AutovalidateMode
|
||||
.onUserInteraction,
|
||||
validator: (value) =>
|
||||
value == null
|
||||
? 'required'
|
||||
: null,
|
||||
isExpanded: true,
|
||||
value: selectedProvince,
|
||||
onChanged:
|
||||
(CityMunicipality? city) {
|
||||
selectedMunicipality = city;
|
||||
(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(
|
||||
"Municipality*",
|
||||
"Municipality"),
|
||||
value: selectedMunicipality,
|
||||
items: citymuns == null
|
||||
? []
|
||||
: citymuns!.map<
|
||||
DropdownMenuItem<
|
||||
CityMunicipality>>(
|
||||
(CityMunicipality c) {
|
||||
return DropdownMenuItem(
|
||||
value: c,
|
||||
child: Text(c
|
||||
.description!));
|
||||
}).toList(),
|
||||
),
|
||||
"Province*",
|
||||
"Province")),
|
||||
),
|
||||
),
|
||||
|
||||
//// CityMunicipalities dropdown
|
||||
SizedBox(
|
||||
height: 60,
|
||||
child: ModalProgressHUD(
|
||||
color: Colors.white,
|
||||
inAsyncCall: cityCall,
|
||||
child:
|
||||
DropdownButtonFormField<
|
||||
CityMunicipality>(
|
||||
validator: (value) =>
|
||||
value == null
|
||||
? 'required'
|
||||
: null,
|
||||
isExpanded: true,
|
||||
onChanged:
|
||||
(CityMunicipality?
|
||||
city) {
|
||||
selectedMunicipality =
|
||||
city;
|
||||
},
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"Municipality*",
|
||||
"Municipality"),
|
||||
value: selectedMunicipality,
|
||||
items: citymuns == null
|
||||
? []
|
||||
: citymuns!.map<
|
||||
DropdownMenuItem<
|
||||
CityMunicipality>>(
|
||||
(CityMunicipality
|
||||
c) {
|
||||
return DropdownMenuItem(
|
||||
value: c,
|
||||
child: Text(c
|
||||
.description!));
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
|
||||
],
|
||||
)),
|
||||
],
|
||||
),
|
||||
const Expanded(
|
||||
child: SizedBox(),
|
||||
),
|
||||
|
||||
const Expanded(
|
||||
child: SizedBox(),
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
//rating
|
||||
double? rate = rating == null
|
||||
? null
|
||||
: double.parse(rating!);
|
||||
//lisence
|
||||
String? licenseNumber = license;
|
||||
CityMunicipality? cityMunicipality =
|
||||
selectedMunicipality;
|
||||
DateTime? examDate =
|
||||
examDateController.text.isEmpty
|
||||
? null
|
||||
: DateTime.parse(
|
||||
examDateController.text);
|
||||
DateTime? validityDate =
|
||||
validityDateController.text.isEmpty
|
||||
? null
|
||||
: DateTime.parse(
|
||||
validityDateController.text);
|
||||
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
//rating
|
||||
double? rate = rating == null
|
||||
? null
|
||||
: double.parse(rating!);
|
||||
//lisence
|
||||
String? licenseNumber = license;
|
||||
CityMunicipality? cityMunicipality =
|
||||
selectedMunicipality;
|
||||
DateTime? examDate = examDateController
|
||||
.text.isEmpty
|
||||
? null
|
||||
: DateTime.parse(examDateController.text);
|
||||
DateTime? validityDate =
|
||||
validityDateController.text.isEmpty
|
||||
? null
|
||||
: DateTime.parse(
|
||||
validityDateController.text);
|
||||
|
||||
ExamAddress examAddress = ExamAddress(
|
||||
barangay: null,
|
||||
id: null,
|
||||
addressCategory: null,
|
||||
examAddressClass: null,
|
||||
country: selectedCountry ??
|
||||
Country(
|
||||
id: 175,
|
||||
name: 'Philippines',
|
||||
code: 'PH'),
|
||||
cityMunicipality: cityMunicipality);
|
||||
EligibityCert eligibityCert = EligibityCert(
|
||||
id: null,
|
||||
rating: rate,
|
||||
examDate: examDate,
|
||||
attachments: null,
|
||||
eligibility: selectedEligibility,
|
||||
examAddress: examAddress,
|
||||
validityDate: validityDate,
|
||||
licenseNumber: licenseNumber,
|
||||
overseas: overseas);
|
||||
if (formKey.currentState!.saveAndValidate()) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Loading...");
|
||||
context.read<EligibilityBloc>().add(
|
||||
AddEligibility(
|
||||
eligibityCert: eligibityCert,
|
||||
profileId:
|
||||
widget.profileId.toString(),
|
||||
token: widget.token));
|
||||
}
|
||||
// context.read<ProfileBloc>().add(AddEligibility(eligibityCert: eligibityCert, profileId: profileId, token: token))
|
||||
},
|
||||
child: const Text(submit)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
]),
|
||||
),
|
||||
ExamAddress examAddress = ExamAddress(
|
||||
barangay: null,
|
||||
id: null,
|
||||
addressCategory: null,
|
||||
examAddressClass: null,
|
||||
country: selectedCountry ??
|
||||
Country(
|
||||
id: 175,
|
||||
name: 'Philippines',
|
||||
code: 'PH'),
|
||||
cityMunicipality: cityMunicipality);
|
||||
EligibityCert eligibityCert = EligibityCert(
|
||||
id: null,
|
||||
rating: rate,
|
||||
examDate: examDate,
|
||||
attachments: null,
|
||||
eligibility: selectedEligibility,
|
||||
examAddress: examAddress,
|
||||
validityDate: validityDate,
|
||||
licenseNumber: licenseNumber,
|
||||
overseas: overseas);
|
||||
if (formKey.currentState!
|
||||
.saveAndValidate()) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Loading...");
|
||||
context.read<EligibilityBloc>().add(
|
||||
AddEligibility(
|
||||
eligibityCert: eligibityCert,
|
||||
profileId:
|
||||
widget.profileId.toString(),
|
||||
token: widget.token));
|
||||
}
|
||||
// context.read<ProfileBloc>().add(AddEligibility(eligibityCert: eligibityCert, profileId: profileId, token: token))
|
||||
},
|
||||
child: const Text(submit)),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter_spinkit/flutter_spinkit.dart';
|
|||
import 'package:intl/intl.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/screens/profile/components/work_history/voluntary_works/add_modal.dart';
|
||||
import 'package:unit2/theme-data.dart/box_shadow.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/utils/text_container.dart';
|
||||
|
@ -18,12 +19,16 @@ class VolunataryWorkScreen extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String? token;
|
||||
int? profileId;
|
||||
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text(voluntaryScreenTitle),
|
||||
backgroundColor: primary,
|
||||
actions: [AddLeading(onPressed: () {})],
|
||||
actions: [AddLeading(onPressed: () {
|
||||
context.read<VoluntaryWorkBloc>().add(ShowAddVoluntaryWorks());
|
||||
})],
|
||||
),
|
||||
body: ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
|
@ -32,6 +37,9 @@ class VolunataryWorkScreen extends StatelessWidget {
|
|||
child: BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
if (state is UserLoggedIn) {
|
||||
token = state.userData!.user!.login!.token;
|
||||
profileId =
|
||||
state.userData!.user!.login!.user!.profileId;
|
||||
return BlocBuilder<ProfileBloc, ProfileState>(
|
||||
builder: (context, state) {
|
||||
if (state is ProfileLoaded) {
|
||||
|
@ -43,7 +51,7 @@ class VolunataryWorkScreen extends StatelessWidget {
|
|||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
if (state is VoluntaryWorkLoadedState ||
|
||||
state is VoluntaryWorkErrorState) {
|
||||
state is VoluntaryWorkErrorState|| state is AddVoluntaryWorkState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
|
@ -138,6 +146,8 @@ class VolunataryWorkScreen extends StatelessWidget {
|
|||
message:
|
||||
"You don't have any Voluntary Works added. Please click + to add.");
|
||||
}
|
||||
}if(state is AddVoluntaryWorkState){
|
||||
return AddVoluntaryWorkScreen(profileId: profileId!,token: token!,);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,6 +6,7 @@ import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
|||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:searchfield/searchfield.dart';
|
||||
import 'package:unit2/screens/profile/shared/add_for_empty_search.dart';
|
||||
import '../../../../bloc/profile/profile_bloc.dart';
|
||||
import '../../../../bloc/profile/workHistory/workHistory_bloc.dart';
|
||||
import '../../../../bloc/user/user_bloc.dart';
|
||||
|
@ -129,84 +130,22 @@ class _EditWorkHistoryScreenState extends State<EditWorkHistoryScreen> {
|
|||
positionFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
emptyWidget: Container(
|
||||
decoration: box1(),
|
||||
height: 100,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const Text("No result found..."),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text(
|
||||
"Add Position?"),
|
||||
content: SizedBox(
|
||||
height: 130,
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
controller:
|
||||
addPositionController,
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"", ""),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width:
|
||||
double.infinity,
|
||||
height: 50,
|
||||
child:
|
||||
ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary,
|
||||
Colors
|
||||
.transparent,
|
||||
second),
|
||||
onPressed:
|
||||
() {
|
||||
setState(
|
||||
() {
|
||||
Position
|
||||
newAgencyPosition =
|
||||
Position(
|
||||
id: null,
|
||||
title: addPositionController.text.toUpperCase());
|
||||
state.agencyPositions.insert(
|
||||
0,
|
||||
newAgencyPosition);
|
||||
selectedPosition =
|
||||
newAgencyPosition;
|
||||
addPositionController.text =
|
||||
"";
|
||||
Navigator.pop(
|
||||
context);
|
||||
});
|
||||
},
|
||||
child: const Text(
|
||||
"Add"))),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
child: const Text("Add position"))
|
||||
]),
|
||||
),
|
||||
emptyWidget: EmptyWidget(
|
||||
controller: addPositionController,
|
||||
onpressed: () {
|
||||
setState(() {
|
||||
Position newAgencyPosition = Position(
|
||||
id: null,
|
||||
title: addPositionController.text
|
||||
.toUpperCase());
|
||||
state.agencyPositions
|
||||
.insert(0, newAgencyPosition);
|
||||
selectedPosition = newAgencyPosition;
|
||||
addPositionController.text = "";
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
title: "Add Position"),
|
||||
validator: (position) {
|
||||
if (position!.isEmpty) {
|
||||
return "This field is required";
|
||||
|
@ -253,139 +192,77 @@ class _EditWorkHistoryScreenState extends State<EditWorkHistoryScreen> {
|
|||
return Column(
|
||||
children: [
|
||||
SearchField(
|
||||
controller: oldAgencyController,
|
||||
itemHeight: 70,
|
||||
focusNode: agencyFocusNode,
|
||||
suggestions: state.agencies
|
||||
.map((Agency agency) =>
|
||||
SearchFieldListItem(agency.name!,
|
||||
item: agency,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
agency.name!,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
subtitle: Text(
|
||||
agency.privateEntity == true
|
||||
? "Private"
|
||||
: "Government"),
|
||||
)))
|
||||
.toList(),
|
||||
searchInputDecoration: normalTextFieldStyle(
|
||||
"Agency *", "")
|
||||
.copyWith(
|
||||
suffixIcon:
|
||||
const Icon(Icons.arrow_drop_down)),
|
||||
onSuggestionTap: (agency) {
|
||||
setState(() {
|
||||
selectedAgency = agency.item;
|
||||
if (selectedAgency!.privateEntity == null) {
|
||||
showIsPrivateRadio = true;
|
||||
} else {
|
||||
showIsPrivateRadio = false;
|
||||
controller: oldAgencyController,
|
||||
itemHeight: 70,
|
||||
focusNode: agencyFocusNode,
|
||||
suggestions: state.agencies
|
||||
.map((Agency agency) =>
|
||||
SearchFieldListItem(agency.name!,
|
||||
item: agency,
|
||||
child: ListTile(
|
||||
title: Text(
|
||||
agency.name!,
|
||||
overflow:
|
||||
TextOverflow.ellipsis,
|
||||
),
|
||||
subtitle: Text(
|
||||
agency.privateEntity == true
|
||||
? "Private"
|
||||
: "Government"),
|
||||
)))
|
||||
.toList(),
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle("Agency *", "")
|
||||
.copyWith(
|
||||
suffixIcon: const Icon(
|
||||
Icons.arrow_drop_down)),
|
||||
onSuggestionTap: (agency) {
|
||||
setState(() {
|
||||
selectedAgency = agency.item;
|
||||
if (selectedAgency!.privateEntity ==
|
||||
null) {
|
||||
showIsPrivateRadio = true;
|
||||
} else {
|
||||
showIsPrivateRadio = false;
|
||||
}
|
||||
if (selectedAgency!.privateEntity ==
|
||||
true) {
|
||||
showSalaryGradeAndSalaryStep = false;
|
||||
}
|
||||
if (selectedAgency!.privateEntity ==
|
||||
false) {
|
||||
showSalaryGradeAndSalaryStep = true;
|
||||
}
|
||||
agencyFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
if (selectedAgency!.privateEntity == true) {
|
||||
showSalaryGradeAndSalaryStep = false;
|
||||
}
|
||||
if (selectedAgency!.privateEntity ==
|
||||
false) {
|
||||
showSalaryGradeAndSalaryStep = true;
|
||||
}
|
||||
agencyFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
validator: (agency) {
|
||||
if (agency!.isEmpty) {
|
||||
return "This field is required";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
emptyWidget: Container(
|
||||
decoration: box1(),
|
||||
height: 100,
|
||||
child: Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const Text("No result found"),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder:
|
||||
(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text(
|
||||
"Add Position"),
|
||||
content: SizedBox(
|
||||
height: 130,
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
controller:
|
||||
addAgencyController,
|
||||
decoration:
|
||||
normalTextFieldStyle(
|
||||
"", ""),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: double
|
||||
.infinity,
|
||||
height: 50,
|
||||
child:
|
||||
ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary,
|
||||
Colors
|
||||
.transparent,
|
||||
second),
|
||||
onPressed:
|
||||
() {
|
||||
setState(
|
||||
() {
|
||||
Agency newAgency = Agency(
|
||||
id: null,
|
||||
name: addAgencyController.text.toUpperCase(),
|
||||
category: null,
|
||||
privateEntity: null);
|
||||
state.agencies.insert(0,
|
||||
newAgency);
|
||||
selectedAgency =
|
||||
newAgency;
|
||||
addAgencyController.text =
|
||||
"";
|
||||
showAgencyCategory =
|
||||
true;
|
||||
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);
|
||||
selectedAgency = newAgency;
|
||||
addAgencyController.text = "";
|
||||
showAgencyCategory = true;
|
||||
|
||||
showIsPrivateRadio =
|
||||
true;
|
||||
showIsPrivateRadio = true;
|
||||
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
child: const Text(
|
||||
"Add"))),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
child: const Text("Add Agency"))
|
||||
]),
|
||||
),
|
||||
),
|
||||
Navigator.pop(context);
|
||||
});
|
||||
},
|
||||
title: "Add Agency")),
|
||||
|
||||
SizedBox(
|
||||
height: showAgencyCategory ? 12 : 0,
|
||||
|
|
|
@ -0,0 +1,597 @@
|
|||
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()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
import 'package:flutter/material.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';
|
||||
|
||||
class EmptyWidget extends StatelessWidget {
|
||||
final TextEditingController controller;
|
||||
final Function()? onpressed;
|
||||
final String title;
|
||||
const EmptyWidget(
|
||||
{super.key, required this.controller, required this.onpressed,required this.title});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: box1(),
|
||||
height: 100,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
const Text("No result found..."),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
////ADD POSITION DIALOG
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(title),
|
||||
content: SizedBox(
|
||||
height: 130,
|
||||
child: Column(
|
||||
children: [
|
||||
TextFormField(
|
||||
controller: controller,
|
||||
decoration: normalTextFieldStyle("", ""),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(primary,
|
||||
Colors.transparent, second),
|
||||
onPressed: onpressed,
|
||||
child: const Text("Add"))),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
},
|
||||
child: Text(title))
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,97 +1,224 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:unit2/screens/docsms/components/request_receipt.dart';
|
||||
import 'package:unit2/screens/docsms/index.dart';
|
||||
import 'package:unit2/screens/unit2/homepage.dart/module-screen.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/utils/global.dart';
|
||||
import 'package:unit2/utils/global_context.dart';
|
||||
import 'package:unit2/utils/qr_scanner.dart';
|
||||
import 'package:unit2/utils/text_container.dart';
|
||||
|
||||
import '../../../../bloc/docsms/docsms_bloc.dart';
|
||||
|
||||
class DashBoard extends StatelessWidget {
|
||||
final List<Module> roles;
|
||||
const DashBoard({super.key, required this.roles});
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<String> finishRoles = [];
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 24),
|
||||
height: MediaQuery.of(context).size.height,
|
||||
//listview builder
|
||||
////listview builder
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.vertical,
|
||||
shrinkWrap: true,
|
||||
itemCount: roles.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
// gridview.count
|
||||
return SizedBox(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
roles[index].name.toUpperCase(),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelLarge!
|
||||
.copyWith(fontSize: 12),
|
||||
),
|
||||
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
GridView.count(
|
||||
shrinkWrap: true,
|
||||
crossAxisCount: 4,
|
||||
crossAxisSpacing: 8,
|
||||
mainAxisSpacing: 10,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 5, horizontal: 5),
|
||||
children: roles[index].roles.map((role) {
|
||||
return Container(
|
||||
padding: const EdgeInsetsDirectional.fromSTEB(8,5,8,13),
|
||||
alignment: Alignment.center,
|
||||
|
||||
decoration:const BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow:[ BoxShadow(color: Colors.black12,spreadRadius: 2,blurRadius: 3)],
|
||||
borderRadius: BorderRadius.all(Radius.circular(8))
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
},
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Icon(
|
||||
|
||||
role.icon,
|
||||
size: 20,
|
||||
weight: 100,
|
||||
grade: 100,
|
||||
color:second,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
role.role.name!.toLowerCase() == "establishment point-person"?"Est. point-person":
|
||||
role.role.name!,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelLarge!
|
||||
.copyWith(
|
||||
fontSize: blockSizeVertical*1.1,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}).toList()),
|
||||
const SizedBox(height: 8,)
|
||||
],
|
||||
),
|
||||
);
|
||||
//// gridview.count
|
||||
return roles[index].roles.isNotEmpty
|
||||
? SizedBox(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
roles[index].name.toUpperCase(),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelLarge!
|
||||
.copyWith(fontSize: 12),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
GridView.count(
|
||||
shrinkWrap: true,
|
||||
crossAxisCount: 4,
|
||||
crossAxisSpacing: 8,
|
||||
mainAxisSpacing: 10,
|
||||
physics: const BouncingScrollPhysics(),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 5, horizontal: 5),
|
||||
children: roles[index].roles.map((role) {
|
||||
//// if role name is qr code && finishRoles not contain security
|
||||
//// this card will visible if the user has qr code scanner or security role
|
||||
if (role.role.name!.toLowerCase() ==
|
||||
'qr code scanner' &&
|
||||
!finishRoles.contains("security")) {
|
||||
finishRoles.add('scanner');
|
||||
//// loop thru module to find unit module exist
|
||||
for (var element in role.role.modules!) {
|
||||
if (element!.name!.toLowerCase() == 'unit2') {
|
||||
for (var element in element.objects!) {
|
||||
//// loop thru objects to find pass check exist
|
||||
if (element!.id == 9 &&
|
||||
//// check if operations contains read and write
|
||||
element.operations!
|
||||
.contains("read")) {
|
||||
//// if all conditions are true return card
|
||||
return CardLabel(
|
||||
ontap: () {},
|
||||
icon: role.icon,
|
||||
title: "Pass Check",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Container();
|
||||
//// if role name is security
|
||||
//// this card will visible if the user has qr code scanner or security role
|
||||
} else if (role.role.name!.toLowerCase() ==
|
||||
'security guard' &&
|
||||
!finishRoles.contains('scanner')) {
|
||||
finishRoles.add('security');
|
||||
for (var element in role.role.modules!) {
|
||||
if (element!.name!.toLowerCase() == 'unit2') {
|
||||
for (var element in element.objects!) {
|
||||
if (element!.id == 9 &&
|
||||
element.operations!
|
||||
.contains("read")) {
|
||||
return CardLabel(
|
||||
ontap: () {},
|
||||
icon: role.icon,
|
||||
title: "Pass Check",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Container();
|
||||
//// if role name is field surveyor
|
||||
} else if (role.role.name!.toLowerCase() ==
|
||||
'field surveyor') {
|
||||
for (var element in role.role.modules!) {
|
||||
if (element!.name!.toLowerCase() == 'rpass') {
|
||||
for (var element in element.objects!) {
|
||||
if (element!.id == 11 &&
|
||||
element.operations!
|
||||
.contains("read")) {
|
||||
return CardLabel(
|
||||
ontap: () {},
|
||||
icon: role.icon,
|
||||
title: "Field Surveyor",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Container();
|
||||
//// if role name is process server
|
||||
} else if (role.role.name!.toLowerCase() ==
|
||||
'process server') {
|
||||
for (var element in role.role.modules!) {
|
||||
if (element!.name!.toLowerCase() ==
|
||||
'document management') {
|
||||
for (var element in element.objects!) {
|
||||
if (element!.id == 3 &&
|
||||
element.operations!
|
||||
.contains("read")) {
|
||||
return CardLabel(
|
||||
ontap: () async {
|
||||
String? qrBarcode =
|
||||
await qrScanner();
|
||||
if (qrBarcode != null) {
|
||||
Navigator.push(NavigationService.navigatorKey.currentContext!, MaterialPageRoute(builder:
|
||||
(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => DocsmsBloc()
|
||||
..add(LoadDocument(
|
||||
documentId: qrBarcode)),
|
||||
child:
|
||||
const AutoReceiveDocument(),
|
||||
);
|
||||
}));
|
||||
}
|
||||
},
|
||||
icon: role.icon,
|
||||
title: "Process Server",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Container();
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}).toList()),
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
: Container();
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CardLabel extends StatelessWidget {
|
||||
final String title;
|
||||
final IconData icon;
|
||||
final Function()? ontap;
|
||||
const CardLabel(
|
||||
{super.key,
|
||||
required this.icon,
|
||||
required this.title,
|
||||
required this.ontap});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: ontap,
|
||||
child: Container(
|
||||
padding: const EdgeInsetsDirectional.fromSTEB(8, 5, 8, 13),
|
||||
alignment: Alignment.center,
|
||||
decoration: const BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(color: Colors.black12, spreadRadius: 2, blurRadius: 3)
|
||||
],
|
||||
borderRadius: BorderRadius.all(Radius.circular(8))),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Icon(
|
||||
icon,
|
||||
size: 20,
|
||||
weight: 100,
|
||||
grade: 100,
|
||||
color: second,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||
fontSize: blockSizeVertical * 1.2,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
]),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||
import 'package:flutter_zoom_drawer/flutter_zoom_drawer.dart';
|
||||
import 'package:fluttericon/font_awesome5_icons.dart';
|
||||
import 'package:fluttericon/font_awesome_icons.dart';
|
||||
import 'package:fluttericon/rpg_awesome_icons.dart';
|
||||
import 'package:fluttericon/typicons_icons.dart';
|
||||
import 'package:unit2/screens/unit2/homepage.dart/components/dashboard.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
|
@ -21,7 +22,8 @@ class MainScreen extends StatefulWidget {
|
|||
class _MainScreenState extends State<MainScreen> {
|
||||
List<Module> roles = [
|
||||
Module(name: 'UniT2 module operations', roles: []),
|
||||
Module(name: 'DocSms module operations', roles: [])
|
||||
Module(name: 'DocSms module operations', roles: []),
|
||||
Module(name: "RPAss module operations",roles:[] )
|
||||
];
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -43,6 +45,10 @@ class _MainScreenState extends State<MainScreen> {
|
|||
IconData iconData = iconGenerator(getRole!.name!);
|
||||
Roles newRole = Roles(role: getRole, icon: iconData);
|
||||
roles[1].roles.add(newRole);
|
||||
} if (module.name!.toLowerCase() == 'rpass') {
|
||||
IconData iconData = iconGenerator(getRole!.name!);
|
||||
Roles newRole = Roles(role: getRole, icon: iconData);
|
||||
roles[2].roles.add(newRole);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,6 +103,8 @@ class _MainScreenState extends State<MainScreen> {
|
|||
case 'process server':
|
||||
iconData = Typicons.doc_text;
|
||||
break;
|
||||
case 'field surveyor':
|
||||
iconData = RpgAwesome.telescope;
|
||||
}
|
||||
return iconData!;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:unit2/utils/request.dart';
|
||||
import 'package:unit2/utils/urls.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../../model/docsms/document.dart';
|
||||
|
||||
class AutoReceiveDocumentServices{
|
||||
static final AutoReceiveDocumentServices _instance = AutoReceiveDocumentServices();
|
||||
static AutoReceiveDocumentServices get instance => _instance;
|
||||
|
||||
Future<Document?> getDocument(String documentId) async {
|
||||
String path = Url.instance.getDocument();
|
||||
Document? document;
|
||||
Map<String, String> params = {"t1.id": documentId.toString()};
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance.getRequest(param: params,path:path,headers:headers);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
Map data = json.decode(response.body);
|
||||
if(data['message'].toString().toLowerCase() == "data successfully fetched."){
|
||||
document = Document.fromJson(data['data']);
|
||||
}else{
|
||||
document = null;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw (e.toString());
|
||||
}
|
||||
return document;
|
||||
}
|
||||
|
||||
}
|
|
@ -9,12 +9,12 @@ import 'package:http/http.dart' as http;
|
|||
class EducationService {
|
||||
static final EducationService _instance = EducationService();
|
||||
static EducationService get instace => _instance;
|
||||
|
||||
////get educational background
|
||||
Future<List<EducationalBackground>> getEducationalBackground(
|
||||
int profileId, String token) async {
|
||||
List<EducationalBackground> educationalBackgrounds = [];
|
||||
String authToken = "Token $token";
|
||||
String path = "${Url.instance.getEducationalBackgrounds()}$profileId/";
|
||||
String path = "${Url.instance.educationalBackground()}$profileId/";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authToken
|
||||
|
@ -38,4 +38,201 @@ class EducationService {
|
|||
|
||||
return educationalBackgrounds;
|
||||
}
|
||||
|
||||
////Add
|
||||
Future<Map<dynamic, dynamic>> add(
|
||||
{required EducationalBackground educationalBackground,
|
||||
required String token,
|
||||
required int profileId,
|
||||
required List<Honor> honors}) async {
|
||||
String authtoken = "Token $token";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authtoken
|
||||
};
|
||||
String path = '${Url.instance.educationalBackground()}$profileId/';
|
||||
Map<dynamic, dynamic> statusResponse = {};
|
||||
Map body = {
|
||||
"_level": educationalBackground.education!.level,
|
||||
"_schoolId": educationalBackground.education?.school?.id,
|
||||
"_schoolName": educationalBackground.education!.school!.name,
|
||||
"_programId": educationalBackground.education?.course?.id,
|
||||
"_programName": educationalBackground.education?.course?.program,
|
||||
"_course": null,
|
||||
"period_from": educationalBackground.periodFrom.toString(),
|
||||
"period_to": educationalBackground.periodTo.toString(),
|
||||
"units_earned": educationalBackground.unitsEarned,
|
||||
"year_graduated": educationalBackground.yearGraduated,
|
||||
"honors": honors.isEmpty ? [] : honors,
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.postRequest(path: path, param: {}, body: body, headers: headers);
|
||||
if (response.statusCode == 201) {
|
||||
Map data = jsonDecode(response.body);
|
||||
statusResponse = data;
|
||||
} else {
|
||||
statusResponse.addAll({'success': false});
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return statusResponse;
|
||||
}
|
||||
|
||||
////Edit
|
||||
Future<Map<dynamic, dynamic>> edit(
|
||||
{required EducationalBackground educationalBackground,
|
||||
required String token,
|
||||
required int profileId,
|
||||
required List<Honor> honors}) async {
|
||||
String authtoken = "Token $token";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authtoken
|
||||
};
|
||||
String path = '${Url.instance.educationalBackground()}$profileId/';
|
||||
Map<dynamic, dynamic> statusResponse = {};
|
||||
Map body = {
|
||||
"id": educationalBackground.id,
|
||||
"_level": educationalBackground.education!.level,
|
||||
"_schoolId": educationalBackground.education?.school?.id,
|
||||
"_schoolName": educationalBackground.education!.school!.name,
|
||||
"_programId": educationalBackground.education?.course?.id,
|
||||
"_programName": educationalBackground.education?.course?.program,
|
||||
"_course": null,
|
||||
"period_from": educationalBackground.periodFrom.toString(),
|
||||
"period_to": educationalBackground.periodTo.toString(),
|
||||
"units_earned": educationalBackground.unitsEarned,
|
||||
"year_graduated": educationalBackground.yearGraduated,
|
||||
"honors": honors.isEmpty ? [] : honors,
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.putRequest(path: path, param: {}, body: body, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
statusResponse = data;
|
||||
} else {
|
||||
statusResponse.addAll({'success': false});
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return statusResponse;
|
||||
}
|
||||
|
||||
//// delete
|
||||
Future<bool> delete(
|
||||
{required int profileId,
|
||||
required String token,
|
||||
required EducationalBackground educationalBackground}) async {
|
||||
String authToken = "Token $token";
|
||||
String path = "${Url.instance.educationalBackground()}$profileId/";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'Authorization': authToken
|
||||
};
|
||||
bool? success;
|
||||
Map<String, dynamic> params = {"force_mode": "true"};
|
||||
Map body = {
|
||||
"id": educationalBackground.id,
|
||||
"_level": educationalBackground.education!.level,
|
||||
"_schoolId": educationalBackground.education!.school!.id,
|
||||
"education_id": educationalBackground.education!.id,
|
||||
"period_from": educationalBackground.periodFrom,
|
||||
"period_to": educationalBackground.periodTo,
|
||||
"units_earned": educationalBackground.unitsEarned,
|
||||
"year_graduated": educationalBackground.yearGraduated,
|
||||
"honors": educationalBackground.honors
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance.deleteRequest(
|
||||
path: path, headers: headers, body: body, param: params);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
success = data['success'];
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return success!;
|
||||
}
|
||||
|
||||
//// get schools
|
||||
Future<List<School>> getSchools() async {
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
List<School> schools = [];
|
||||
String path = Url.instance.getSchools();
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.getRequest(param: {}, path: path, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
if (data['data'] != null) {
|
||||
data['data'].forEach((school) {
|
||||
School newSchool = School.fromJson(school);
|
||||
schools.add(newSchool);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return schools;
|
||||
}
|
||||
|
||||
Future<List<Course>> getPrograms() async {
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
List<Course> programs = [];
|
||||
String path = Url.instance.getPrograms();
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.getRequest(param: {}, path: path, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
if (data['data'] != null) {
|
||||
data['data'].forEach((course) {
|
||||
Course newCourse = Course.fromJson(course);
|
||||
programs.add(newCourse);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return programs;
|
||||
}
|
||||
|
||||
////get honors
|
||||
Future<List<Honor>> getHonors() async {
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
List<Honor> honors = [];
|
||||
String path = Url.instance.getHonors();
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.getRequest(param: {}, path: path, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
if (data['data'] != null) {
|
||||
data['data'].forEach((honor) {
|
||||
Honor newHonor = Honor.fromJson(honor);
|
||||
honors.add(newHonor);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return honors;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ class WorkHistoryService {
|
|||
|
||||
}
|
||||
|
||||
//get agency position
|
||||
////get agency position
|
||||
Future<List<Position>> getAgencyPosition() async {
|
||||
List<Position> agencyPositions = [];
|
||||
String path = Url.instance.getPositions();
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:unit2/bloc/docsms/docsms_bloc.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/sos/sos_bloc.dart';
|
||||
import 'package:unit2/screens/docsms/index.dart';
|
||||
import 'package:unit2/screens/sos/index.dart';
|
||||
import 'package:unit2/screens/unit2/homepage.dart/components/menu.dart';
|
||||
import 'package:unit2/screens/unit2/login/login.dart';
|
||||
|
@ -51,6 +53,7 @@ class AppRouter {
|
|||
child: const SosScreen(),
|
||||
);
|
||||
});
|
||||
|
||||
default:
|
||||
return MaterialPageRoute(builder: (context) {
|
||||
return Container();
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:unit2/model/location/country.dart';
|
||||
|
@ -11,35 +10,63 @@ import 'package:unit2/utils/urls.dart';
|
|||
import '../model/profile/basic_information/contact_information.dart';
|
||||
import '../model/utils/agency.dart';
|
||||
import '../model/utils/category.dart';
|
||||
import '../model/utils/position.dart';
|
||||
|
||||
class ProfileUtilities {
|
||||
static final ProfileUtilities _instance = ProfileUtilities();
|
||||
static ProfileUtilities get instance => _instance;
|
||||
|
||||
Future<List<Eligibility>>getEligibilities()async{
|
||||
List<Eligibility> eligibilities=[];
|
||||
Future<List<Eligibility>> getEligibilities() async {
|
||||
List<Eligibility> eligibilities = [];
|
||||
String path = Url.instance.eligibilities();
|
||||
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
try{
|
||||
http.Response response = await Request.instance.getRequest(path: path, param: {},headers: headers);
|
||||
if(response.statusCode == 200){
|
||||
Map data = jsonDecode(response.body);
|
||||
if(data['data'] != null){
|
||||
data['data'].forEach((var eligibility){
|
||||
Eligibility newEligibilities = Eligibility.fromJson(eligibility);
|
||||
eligibilities.add(newEligibilities);
|
||||
});
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.getRequest(path: path, param: {}, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
if (data['data'] != null) {
|
||||
data['data'].forEach((var eligibility) {
|
||||
Eligibility newEligibilities = Eligibility.fromJson(eligibility);
|
||||
eligibilities.add(newEligibilities);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw (e.toString());
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
throw(e.toString());
|
||||
}
|
||||
return eligibilities;
|
||||
return eligibilities;
|
||||
}
|
||||
|
||||
//get agencies
|
||||
////get agency position
|
||||
Future<List<Position>> getAgencyPosition() async {
|
||||
List<Position> agencyPositions = [];
|
||||
String path = Url.instance.getPositions();
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.getRequest(param: {}, path: path, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
if (data['data'] != null) {
|
||||
data['data'].forEach((var agencyPosition) {
|
||||
Position position = Position.fromJson(agencyPosition);
|
||||
agencyPositions.add(position);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw (e.toString());
|
||||
}
|
||||
return agencyPositions;
|
||||
}
|
||||
|
||||
////get agencies
|
||||
Future<List<Agency>> getAgecies() async {
|
||||
List<Agency> agencies = [];
|
||||
String path = Url.instance.getAgencies();
|
||||
|
@ -64,8 +91,7 @@ class ProfileUtilities {
|
|||
return agencies;
|
||||
}
|
||||
|
||||
|
||||
//get agency category
|
||||
////get agency category
|
||||
Future<List<Category>> agencyCategory() async {
|
||||
List<Category> agencyCategory = [];
|
||||
String path = Url.instance.getAgencyCategory();
|
||||
|
@ -91,28 +117,28 @@ class ProfileUtilities {
|
|||
}
|
||||
|
||||
//// get service type
|
||||
Future<List<ServiceType>> getServiceType()async{
|
||||
Future<List<ServiceType>> getServiceType() async {
|
||||
List<ServiceType> serviceTypes = [];
|
||||
Map<String, String> headers = {
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
};
|
||||
String path = Url.instance.getServiceTypes();
|
||||
|
||||
try{
|
||||
http.Response response = await Request.instance.getRequest(param: {},path:path,headers: headers );
|
||||
if(response.statusCode == 200){
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.getRequest(param: {}, path: path, headers: headers);
|
||||
if (response.statusCode == 200) {
|
||||
Map data = jsonDecode(response.body);
|
||||
if(data['data'] != null){
|
||||
for(var element in data['data']){
|
||||
if (data['data'] != null) {
|
||||
for (var element in data['data']) {
|
||||
ServiceType newServiceType = ServiceType.fromJson(element);
|
||||
serviceTypes.add(newServiceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return serviceTypes;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import 'package:barcode_scan2/barcode_scan2.dart';
|
||||
import 'package:unit2/utils/scanner.dart';
|
||||
|
||||
Future<String?> qrScanner() async {
|
||||
String? result;
|
||||
try {
|
||||
ScanResult afterScan = await QRCodeBarCodeScanner.instance.scanner();
|
||||
if (afterScan.type == ResultType.Barcode) {
|
||||
result = afterScan.rawContent;
|
||||
return result;
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
|
@ -6,8 +6,8 @@ class Url {
|
|||
// return '192.168.10.183:3000';
|
||||
// return 'agusandelnorte.gov.ph';
|
||||
// return "192.168.10.219:3000";
|
||||
return "devweb.agusandelnorte.gov.ph";
|
||||
// return 'devapi.agusandelnorte.gov.ph:3004';
|
||||
// return "devweb.agusandelnorte.gov.ph";
|
||||
return 'devapi.agusandelnorte.gov.ph:3004';
|
||||
}
|
||||
|
||||
String authentication() {
|
||||
|
@ -27,6 +27,11 @@ class Url {
|
|||
return "/api/sos_app/sos_request/";
|
||||
}
|
||||
|
||||
//// DOCSMS paths
|
||||
String getDocument(){
|
||||
return "/api/web_app/public/document_viewer/";
|
||||
}
|
||||
|
||||
////ELIGIBILITIES PATHS
|
||||
String eligibilities(){
|
||||
return "/api/jobnet_app/eligibilities/";
|
||||
|
@ -57,17 +62,24 @@ String getAgencies(){
|
|||
return "/api/jobnet_app/agencies/";
|
||||
}
|
||||
|
||||
|
||||
|
||||
String getAgencyCategory(){
|
||||
return "api/jobnet_app/agency_categories/";
|
||||
}
|
||||
|
||||
|
||||
////educational background paths
|
||||
String getEducationalBackgrounds(){
|
||||
String educationalBackground(){
|
||||
return "/api/jobnet_app/profile/pds/education/";
|
||||
}
|
||||
String getSchools(){
|
||||
return "/api/jobnet_app/schools/";
|
||||
}
|
||||
String getPrograms(){
|
||||
return "api/jobnet_app/education_programs/";
|
||||
}
|
||||
String getHonors(){
|
||||
return "/api/jobnet_app/honors";
|
||||
}
|
||||
|
||||
//// learning and development paths
|
||||
|
||||
|
|
32
pubspec.lock
32
pubspec.lock
|
@ -677,6 +677,30 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
location:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: location
|
||||
sha256: "9051959f6f2ccadd887b28b66e9cbbcc25b6838e37cf9e894c421ccc0ebf80b5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.4.0"
|
||||
location_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: location_platform_interface
|
||||
sha256: "62eeaf1658e92e4459b727f55a3c328eccbac8ba043fa6d262ac5286ad48384c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
location_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: location_web
|
||||
sha256: "6c08c408a040534c0269c4ff9fe17eebb5a36dea16512fbaf116b9c8bc21545b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -741,6 +765,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
multi_dropdown:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: multi_dropdown
|
||||
sha256: "65b8f505b251c5173e8eff64c09cd37460d8f8be906c2069a03815ad2641dcd1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.9"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -77,7 +77,7 @@ dependencies:
|
|||
hive_flutter: ^1.1.0
|
||||
mask_text_input_formatter: ^2.4.0
|
||||
location: ^4.3.0
|
||||
platform_device_id: ^1.0.1
|
||||
platform_device_id: ^1.0.1,
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
Loading…
Reference in New Issue