2023-02-23 00:53:14 +00:00
|
|
|
import 'package:date_time_picker/date_time_picker.dart';
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
|
|
|
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
2023-02-27 06:26:27 +00:00
|
|
|
import 'package:form_builder_validators/form_builder_validators.dart';
|
2023-02-23 05:51:53 +00:00
|
|
|
import 'package:intl/intl.dart';
|
|
|
|
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
2023-02-23 00:53:14 +00:00
|
|
|
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
|
|
|
import 'package:unit2/bloc/user/user_bloc.dart';
|
2023-02-27 06:26:27 +00:00
|
|
|
import 'package:unit2/model/profile/eligibility.dart';
|
2023-02-23 00:53:14 +00:00
|
|
|
|
2023-03-07 02:31:28 +00:00
|
|
|
import '../../../../bloc/profile/eligibility/eligibility_bloc.dart';
|
2023-02-23 00:53:14 +00:00
|
|
|
import '../../../../model/location/city.dart';
|
|
|
|
import '../../../../model/location/country.dart';
|
|
|
|
import '../../../../model/location/provinces.dart';
|
|
|
|
import '../../../../model/location/region.dart';
|
|
|
|
import '../../../../model/utils/eligibility.dart';
|
|
|
|
import '../../../../theme-data.dart/btn-style.dart';
|
|
|
|
import '../../../../theme-data.dart/colors.dart';
|
|
|
|
import '../../../../theme-data.dart/form-style.dart';
|
|
|
|
import '../../../../utils/global.dart';
|
2023-02-23 05:51:53 +00:00
|
|
|
import '../../../../utils/location_utilities.dart';
|
2023-02-23 00:53:14 +00:00
|
|
|
import '../../../../utils/text_container.dart';
|
|
|
|
|
|
|
|
class AddEligibilityScreen extends StatefulWidget {
|
2023-04-11 01:27:53 +00:00
|
|
|
const AddEligibilityScreen(
|
|
|
|
{super.key, required this.profileId, required this.token});
|
|
|
|
final int profileId;
|
|
|
|
final String token;
|
2023-02-23 00:53:14 +00:00
|
|
|
|
|
|
|
@override
|
|
|
|
State<AddEligibilityScreen> createState() => _AddEligibilityScreenState();
|
|
|
|
}
|
|
|
|
|
|
|
|
class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
|
2023-02-27 06:26:27 +00:00
|
|
|
final formKey = GlobalKey<FormBuilderState>();
|
2023-04-11 01:27:53 +00:00
|
|
|
bool? overseas = false;
|
2023-02-23 05:51:53 +00:00
|
|
|
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
|
|
|
|
Region? selectedRegion;
|
|
|
|
Province? selectedProvince;
|
|
|
|
CityMunicipality? selectedMunicipality;
|
|
|
|
Country? selectedCountry;
|
|
|
|
Eligibility? selectedEligibility;
|
|
|
|
List<Province>? provinces;
|
|
|
|
List<CityMunicipality>? citymuns;
|
|
|
|
bool provinceCall = false;
|
|
|
|
bool cityCall = false;
|
2023-02-27 06:26:27 +00:00
|
|
|
final examDateController = TextEditingController();
|
|
|
|
final validityDateController = TextEditingController();
|
|
|
|
String? token;
|
|
|
|
String? profileId;
|
|
|
|
String? rating;
|
|
|
|
String? license;
|
2023-02-23 00:53:14 +00:00
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
2023-04-11 01:27:53 +00:00
|
|
|
return BlocBuilder<EligibilityBloc, EligibilityState>(
|
|
|
|
buildWhen: (previous, current) {
|
|
|
|
return false;
|
|
|
|
},
|
2023-02-23 00:53:14 +00:00
|
|
|
builder: (context, state) {
|
2023-04-11 01:27:53 +00:00
|
|
|
////ADD ELIGIBILITY STATE
|
|
|
|
if (state is AddEligibilityState) {
|
|
|
|
return SingleChildScrollView(
|
|
|
|
child: SizedBox(
|
|
|
|
height: screenHeight * .95,
|
2023-04-25 07:50:36 +00:00
|
|
|
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"),
|
2023-04-11 01:27:53 +00:00
|
|
|
),
|
2023-04-25 07:50:36 +00:00
|
|
|
),
|
|
|
|
const SizedBox(
|
|
|
|
width: 8,
|
|
|
|
),
|
|
|
|
////RATING
|
|
|
|
Flexible(
|
|
|
|
flex: 1,
|
|
|
|
child: FormBuilderTextField(
|
|
|
|
keyboardType: const TextInputType
|
|
|
|
.numberWithOptions(),
|
|
|
|
onChanged: (value) {
|
|
|
|
rating = value;
|
|
|
|
},
|
|
|
|
name: 'rating',
|
|
|
|
decoration: normalTextFieldStyle(
|
|
|
|
'rating %', 'rating'),
|
2023-04-11 01:27:53 +00:00
|
|
|
),
|
2023-04-25 07:50:36 +00:00
|
|
|
),
|
|
|
|
],
|
2023-04-11 01:27:53 +00:00
|
|
|
),
|
2023-04-25 07:50:36 +00:00
|
|
|
),
|
|
|
|
const SizedBox(
|
|
|
|
height: 8,
|
|
|
|
),
|
|
|
|
SizedBox(
|
|
|
|
width: screenWidth,
|
|
|
|
child: Row(
|
|
|
|
children: [
|
|
|
|
////EXAM DATE
|
|
|
|
Flexible(
|
2023-04-11 01:27:53 +00:00
|
|
|
flex: 1,
|
|
|
|
child: DateTimePicker(
|
2023-04-25 07:50:36 +00:00
|
|
|
validator:
|
|
|
|
FormBuilderValidators.required(
|
|
|
|
errorText:
|
|
|
|
"This field is required"),
|
|
|
|
use24HourFormat: false,
|
|
|
|
icon: const Icon(Icons.date_range),
|
|
|
|
controller: examDateController,
|
2023-04-11 01:27:53 +00:00
|
|
|
firstDate: DateTime(1970),
|
|
|
|
lastDate: DateTime(2100),
|
2023-04-25 07:50:36 +00:00
|
|
|
timeHintText:
|
|
|
|
"Date of Examination/Conferment",
|
2023-04-11 01:27:53 +00:00
|
|
|
decoration: normalTextFieldStyle(
|
2023-04-25 07:50:36 +00:00
|
|
|
"Exam date", "")
|
2023-03-16 07:53:42 +00:00
|
|
|
.copyWith(
|
2023-04-11 01:27:53 +00:00
|
|
|
prefixIcon: const Icon(
|
|
|
|
Icons.date_range,
|
|
|
|
color: Colors.black87,
|
|
|
|
)),
|
|
|
|
initialValue: null,
|
2023-04-25 07:50:36 +00:00
|
|
|
)),
|
2023-04-11 01:27:53 +00:00
|
|
|
const SizedBox(
|
2023-04-25 07:50:36 +00:00
|
|
|
width: 8,
|
2023-04-11 01:27:53 +00:00
|
|
|
),
|
2023-04-25 07:50:36 +00:00
|
|
|
////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(() {
|
2023-04-11 01:27:53 +00:00
|
|
|
provinceCall = true;
|
|
|
|
});
|
2023-04-25 07:50:36 +00:00
|
|
|
selectedRegion = region;
|
2023-04-11 01:27:53 +00:00
|
|
|
getProvinces();
|
2023-04-25 07:50:36 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
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,
|
2023-04-11 01:27:53 +00:00
|
|
|
validator: (value) =>
|
|
|
|
value == null
|
|
|
|
? 'required'
|
|
|
|
: null,
|
|
|
|
isExpanded: true,
|
2023-04-25 07:50:36 +00:00
|
|
|
value: selectedProvince,
|
2023-03-16 07:53:42 +00:00
|
|
|
onChanged:
|
2023-04-25 07:50:36 +00:00
|
|
|
(Province? province) {
|
|
|
|
if (selectedProvince !=
|
|
|
|
province) {
|
|
|
|
setState(() {
|
|
|
|
cityCall = true;
|
|
|
|
});
|
|
|
|
selectedProvince =
|
|
|
|
province;
|
|
|
|
getCities();
|
|
|
|
}
|
2023-03-16 07:53:42 +00:00
|
|
|
},
|
2023-04-25 07:50:36 +00:00
|
|
|
items: provinces == null
|
2023-04-11 01:27:53 +00:00
|
|
|
? []
|
2023-04-25 07:50:36 +00:00
|
|
|
: provinces!.map<
|
2023-04-11 01:27:53 +00:00
|
|
|
DropdownMenuItem<
|
2023-04-25 07:50:36 +00:00
|
|
|
Province>>(
|
|
|
|
(Province
|
|
|
|
province) {
|
2023-04-11 01:27:53 +00:00
|
|
|
return DropdownMenuItem(
|
2023-04-25 07:50:36 +00:00
|
|
|
value:
|
|
|
|
province,
|
|
|
|
child:
|
|
|
|
FittedBox(
|
|
|
|
child: Text(
|
|
|
|
province
|
|
|
|
.description!),
|
|
|
|
));
|
2023-04-11 01:27:53 +00:00
|
|
|
}).toList(),
|
2023-04-25 07:50:36 +00:00
|
|
|
decoration:
|
|
|
|
normalTextFieldStyle(
|
|
|
|
"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(),
|
2023-04-11 01:27:53 +00:00
|
|
|
),
|
|
|
|
),
|
2023-04-25 07:50:36 +00:00
|
|
|
),
|
|
|
|
],
|
|
|
|
)),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
|
|
|
|
const Expanded(
|
|
|
|
child: SizedBox(),
|
|
|
|
),
|
|
|
|
|
|
|
|
SizedBox(
|
|
|
|
width: screenWidth,
|
|
|
|
height: 60,
|
|
|
|
child: ElevatedButton(
|
|
|
|
style: mainBtnStyle(
|
|
|
|
primary, Colors.transparent, second),
|
|
|
|
onPressed: () {
|
2023-05-02 00:26:42 +00:00
|
|
|
////rating
|
2023-04-25 07:50:36 +00:00
|
|
|
double? rate = rating == null
|
|
|
|
? null
|
|
|
|
: double.parse(rating!);
|
2023-05-02 00:26:42 +00:00
|
|
|
////lisence
|
2023-04-25 07:50:36 +00:00
|
|
|
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,
|
|
|
|
),
|
|
|
|
]),
|
2023-04-11 01:27:53 +00:00
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
2023-02-23 05:51:53 +00:00
|
|
|
);
|
2023-02-23 00:53:14 +00:00
|
|
|
}
|
2023-04-11 01:27:53 +00:00
|
|
|
|
2023-02-23 00:53:14 +00:00
|
|
|
return Container();
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
2023-02-23 05:51:53 +00:00
|
|
|
|
|
|
|
Future<void> getProvinces() async {
|
2023-03-02 00:40:47 +00:00
|
|
|
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) {
|
2023-03-02 05:28:33 +00:00
|
|
|
context.read<EligibilityBloc>().add(CallErrorState());
|
2023-03-02 00:40:47 +00:00
|
|
|
}
|
2023-02-23 05:51:53 +00:00
|
|
|
}
|
2023-02-27 06:26:27 +00:00
|
|
|
|
|
|
|
Future<void> getCities() async {
|
2023-03-02 00:40:47 +00:00
|
|
|
try {
|
|
|
|
List<CityMunicipality> newCities = await LocationUtils.instance
|
|
|
|
.getCities(code: selectedProvince!.code.toString());
|
|
|
|
citymuns = newCities;
|
|
|
|
setState(() {
|
|
|
|
selectedMunicipality = newCities[0];
|
|
|
|
cityCall = false;
|
|
|
|
});
|
|
|
|
} catch (e) {
|
2023-03-02 05:28:33 +00:00
|
|
|
context.read<EligibilityBloc>().add(CallErrorState());
|
2023-03-02 00:40:47 +00:00
|
|
|
}
|
2023-02-23 05:51:53 +00:00
|
|
|
}
|
2023-02-23 00:53:14 +00:00
|
|
|
}
|