add eligibility implemented

feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
PGAN-MIS 2023-02-27 14:26:27 +08:00
parent 424b1f3b47
commit 66adcf924f
17 changed files with 599 additions and 363 deletions

View File

@ -12,6 +12,8 @@ PODS:
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- modal_progress_hud_nsn (0.0.1):
- Flutter
- MTBBarcodeScanner (5.0.11)
- package_info_plus (0.4.5):
- Flutter
@ -34,6 +36,7 @@ DEPENDENCIES:
- easy_app_installer (from `.symlinks/plugins/easy_app_installer/ios`)
- Flutter (from `Flutter`)
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
- modal_progress_hud_nsn (from `.symlinks/plugins/modal_progress_hud_nsn/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`)
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
@ -56,6 +59,8 @@ EXTERNAL SOURCES:
:path: Flutter
fluttertoast:
:path: ".symlinks/plugins/fluttertoast/ios"
modal_progress_hud_nsn:
:path: ".symlinks/plugins/modal_progress_hud_nsn/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
@ -73,6 +78,7 @@ SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
fluttertoast: eb263d302cc92e04176c053d2385237e9f43fad0
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
modal_progress_hud_nsn: f6fb744cd060653d66ed8f325360ef3650eb2fde
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e
path_provider_foundation: 37748e03f12783f9de2cb2c4eadfaa25fe6d4852

View File

@ -1,39 +1,34 @@
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:unit2/model/profile/basic_info.dart';
import 'package:unit2/model/profile/basic_information/primary-information.dart';
import 'package:unit2/model/profile/eligibility.dart';
import 'package:unit2/model/profile/profileInfomation.dart';
import 'package:unit2/model/utils/eligibility.dart';
import 'package:unit2/sevices/profile/eligibility_services.dart';
import 'package:unit2/sevices/profile/profile_service.dart';
import 'package:unit2/test_data.dart';
import 'package:unit2/utils/location_utilities.dart';
import 'package:unit2/utils/profile_utilities.dart';
import '../../model/location/country.dart';
import '../../model/location/region.dart';
import '../../model/location/provinces.dart';
import '../../model/location/city.dart';
import '../../model/location/barangay.dart';
part 'profile_event.dart';
part 'profile_state.dart';
class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
ProfileBloc() : super(ProfileInitial()) {
ProfileInformation? _profileInformation;
List<Country>? _countries;
List<Region>? _regions;
List<Eligibility>? _eligibilities;
List<Province>? _provinces;
List<CityMunicipality>? _cities;
ProfileInformation? globalProfileInformation;
List<Country>? globalCountries;
List<Region>? globalRegions;
List<Eligibility>? globalEligibilities;
List<EligibityCert>? eligibilities;
////=========================================================================
on<LoadProfile>((event, emit) async {
// try {
emit(ProfileLoading());
ProfileInformation? profileInformation =
await ProfileService.instance.getProfile(event.token, event.userID);
_profileInformation = profileInformation;
emit(ProfileLoaded(profileInformation: _profileInformation!));
globalProfileInformation = profileInformation;
emit(ProfileLoaded(profileInformation: globalProfileInformation!));
// } catch (e) {
// emit(ProfileErrorState(mesage: e.toString()));
// }
@ -41,46 +36,34 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
////=====================================================================
on<LoadEligibility>((event, emit) {
emit(ProfileLoading());
eligibilities = event.eligibilities;
emit(EligibilityLoaded(eligibilities: event.eligibilities));
});
////====================================================================
on<EditEligibility>((event, emit) async {
Region? currentRegion;
Province? currentProvince;
CityMunicipality? currentCity;
// try{
emit(ProfileLoading());
if (_countries == null) {
if (globalCountries == null) {
List<Country> countries = await LocationUtils.instance.getCountries();
_countries = countries;
globalCountries = countries;
}
if (_regions == null) {
if (globalRegions == null) {
List<Region> regions = await LocationUtils.instance.getRegions();
_regions = regions;
globalRegions = regions;
}
if (_eligibilities == null) {
if (globalEligibilities == null) {
List<Eligibility> eligibilities =
await ProfileUtilities.instance.getEligibilities();
_eligibilities = eligibilities;
globalEligibilities = eligibilities;
}
// get current country
Country? currentCountry = _countries!.firstWhere((Country country) =>
country.code == event.eligibityCert.examAddress?.country!.code);
// get current eligibility
Eligibility currentEligibility = _eligibilities!.firstWhere(
(Eligibility eligibility) =>
event.eligibityCert.eligibility!.id == eligibility.id);
bool? isOverseas = event.eligibityCert.overseas;
emit(EditEligibilityState(
isOverseas: isOverseas!,
eligibityCert: event.eligibityCert,
countries: _countries!,
regions: _regions!,
eligibilities: _eligibilities!));
countries: globalCountries!,
regions: globalRegions!,
eligibilities: globalEligibilities!));
// }catch(e){
// emit(ProfileErrorState(mesage: e.toString()));
@ -88,29 +71,26 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
////====================================================================
});
on<AddEligibility>((event, emit) async {
List<CityMunicipality>? cities;
List<Province>? provinces;
Eligibility? currentEligibility;
on<ShowAddEligibilityForm>((event, emit) async {
emit(ProfileLoading());
if (_regions == null) {
if (globalRegions == null) {
List<Region> regions = await LocationUtils.instance.getRegions();
_regions = regions;
globalRegions = regions;
}
if (_eligibilities == null) {
if (globalEligibilities == null) {
List<Eligibility> eligibilities =
await ProfileUtilities.instance.getEligibilities();
_eligibilities = eligibilities;
globalEligibilities = eligibilities;
}
if (_countries == null) {
if (globalCountries == null) {
List<Country> countries = await LocationUtils.instance.getCountries();
_countries = countries;
globalCountries = countries;
}
emit(AddEligibilityState(
eligibilities: _eligibilities!,
regions: _regions!,
countries: _countries!));
eligibilities: globalEligibilities!,
regions: globalRegions!,
countries: globalCountries!));
});
////====================================================================
on<DeleteEligibility>((event, emit) async {
@ -133,5 +113,28 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
emit(ProfileErrorState(mesage: e.toString()));
}
});
on<AddEligibility>(
(event, emit) async {
try {
emit(ProfileLoading());
Map<dynamic, dynamic> status = await EligibilityService.instance.add(
eligibityCert: event.eligibityCert,
token: event.token,
profileId: int.parse(event.profileId));
if (status['success']) {
EligibityCert? eligibityCert =
EligibityCert.fromJson(status['data']);
eligibilities!.add(eligibityCert);
emit(EligibilityAddedState(
eligibilities: eligibilities!, response: status));
} else {
emit(EligibilityAddedState(
eligibilities: eligibilities!, response: status));
}
} catch (e) {
emit(ProfileErrorState(mesage: e.toString()));
}
},
);
}
}

View File

@ -7,46 +7,55 @@ abstract class ProfileEvent extends Equatable {
List<Object> get props => [];
}
class LoadProfile extends ProfileEvent{
final String token;
final int userID;
const LoadProfile({required this.token, required this.userID});
@override
List<Object> get props => [token,userID];
class LoadProfile extends ProfileEvent {
final String token;
final int userID;
const LoadProfile({required this.token, required this.userID});
@override
List<Object> get props => [token, userID];
}
class LoadProfileInformation extends ProfileEvent{
class LoadProfileInformation extends ProfileEvent {
@override
List<Object> get props => [];
}
class LoadEligibility extends ProfileEvent{
class LoadEligibility extends ProfileEvent {
final List<EligibityCert> eligibilities;
const LoadEligibility({required this.eligibilities});
@override
@override
List<Object> get props => [];
}
class EditEligibility extends ProfileEvent{
class EditEligibility extends ProfileEvent {
final EligibityCert eligibityCert;
const EditEligibility({required this.eligibityCert});
@override
@override
List<Object> get props => [];
}
class DeleteEligibility extends ProfileEvent{
class DeleteEligibility extends ProfileEvent {
final List<EligibityCert> eligibilities;
final String profileId;
final int eligibilityId;
final String token;
const DeleteEligibility({ required this.eligibilities, required this.eligibilityId, required this.profileId, required this.token});
@override
List<Object> get props => [eligibilities,profileId,eligibilityId,token];
const DeleteEligibility(
{required this.eligibilities,
required this.eligibilityId,
required this.profileId,
required this.token});
@override
List<Object> get props => [eligibilities, profileId, eligibilityId, token];
}
class ShowAddEligibilityForm extends ProfileEvent {
}
class AddEligibility extends ProfileEvent{
final EligibityCert eligibityCert;
final String profileId;
final String token;
const AddEligibility({required this.eligibityCert, required this.profileId, required this.token});
@override
List<Object> get props => [eligibityCert, profileId, token];
}

View File

@ -69,3 +69,12 @@ class AddEligibilityState extends ProfileState {
@override
List<Object> get props => [eligibilities,countries,regions];
}
class EligibilityAddedState extends ProfileState{
final List<EligibityCert> eligibilities;
final Map<dynamic,dynamic> response;
const EligibilityAddedState({required this.eligibilities, required this.response});
@override
List<Object> get props =>[eligibilities,response];
}

View File

@ -4,6 +4,7 @@ import 'package:device_preview/device_preview.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:unit2/bloc/user/user_bloc.dart';
import 'package:unit2/theme-data.dart/colors.dart';
import 'package:unit2/utils/app_router.dart';
import 'package:unit2/utils/global_context.dart';
import 'package:unit2/utils/global_context.dart';
@ -55,8 +56,10 @@ class MyApp extends StatelessWidget {
// routeInformationParser: goRouter.routeInformationParser,
// routerDelegate: goRouter.routerDelegate,
// routeInformationProvider: goRouter.routeInformationProvider,
title: 'uniT2 - Universal Tracker and Tracer',
theme: ThemeData(
primarySwatch: Colors.red,
appBarTheme: const AppBarTheme(
systemOverlayStyle: SystemUiOverlayStyle(
statusBarBrightness: Brightness.dark,

View File

@ -38,10 +38,14 @@ class CityMunicipality {
Map<String, dynamic> toJson() => {
"code": code,
"description": description,
"province": province!.toJson(),
"province": province?.toJson(),
"psgc_code": psgcCode,
"zipcode": zipcode,
};
@override
String toString(){
return 'CityMunicipality{code:$code, description:$description, provice:${province.toString()} }';
}
}

View File

@ -31,4 +31,10 @@ class Country {
"name": name,
"code": code,
};
@override
String toString() {
return '$id $name $code ';
}
}

View File

@ -41,4 +41,9 @@ class Province {
"psgc_code": psgcCode,
"shortname": shortname,
};
@override
String toString(){
return 'Province(name:$description ${region.toString()})';
}
}

View File

@ -31,4 +31,9 @@ class Region {
"description": description,
"psgc_code": psgcCode,
};
@override
String toString(){
return 'Region(name:$description)';
}
}

View File

@ -12,90 +12,110 @@ import '../location/city.dart';
import '../location/country.dart';
import '../utils/eligibility.dart';
EligibityCert eligibityFromJson(String str) => EligibityCert.fromJson(json.decode(str));
EligibityCert eligibityFromJson(String str) =>
EligibityCert.fromJson(json.decode(str));
String eligibityToJson(EligibityCert data) => json.encode(data.toJson());
class EligibityCert {
EligibityCert({
required this.id,
required this.rating,
required this.examDate,
required this.attachments,
required this.eligibility,
required this.examAddress,
required this.validityDate,
required this.licenseNumber,
required this.overseas,
});
bool? overseas;
final int? id;
final double? rating;
final DateTime? examDate;
final dynamic attachments;
final Eligibility? eligibility;
final ExamAddress? examAddress;
final DateTime? validityDate;
final String? licenseNumber;
EligibityCert({
required this.id,
required this.rating,
required this.examDate,
required this.attachments,
required this.eligibility,
required this.examAddress,
required this.validityDate,
required this.licenseNumber,
required this.overseas,
});
bool? overseas;
final int? id;
final double? rating;
final DateTime? examDate;
final dynamic attachments;
final Eligibility? eligibility;
final ExamAddress? examAddress;
final DateTime? validityDate;
final String? licenseNumber;
factory EligibityCert.fromJson(Map<String, dynamic> json) => EligibityCert(
factory EligibityCert.fromJson(Map<String, dynamic> json) => EligibityCert(
id: json["id"],
rating: json["rating"]?.toDouble(),
examDate: json['exam_date'] == null? null: DateTime.parse(json["exam_date"]),
examDate: json['exam_date'] == null
? null
: DateTime.parse(json["exam_date"]),
attachments: null,
eligibility: json['eligibility'] == null?null: Eligibility.fromJson(json["eligibility"]),
examAddress: json['exam_address'] == null? null: ExamAddress.fromJson(json["exam_address"]),
eligibility: json['eligibility'] == null
? null
: Eligibility.fromJson(json["eligibility"]),
examAddress: json['exam_address'] == null
? null
: ExamAddress.fromJson(json["exam_address"]),
validityDate: json["validity_date"],
licenseNumber: json["license_number"],
overseas: null,
);
);
Map<String, dynamic> toJson() => {
Map<String, dynamic> toJson() => {
"id": id,
"rating": rating,
"exam_date": "${examDate!.year.toString().padLeft(4, '0')}-${examDate!.month.toString().padLeft(2, '0')}-${examDate!.day.toString().padLeft(2, '0')}",
"exam_date":
"${examDate!.year.toString().padLeft(4, '0')}-${examDate!.month.toString().padLeft(2, '0')}-${examDate!.day.toString().padLeft(2, '0')}",
"attachments": attachments,
"eligibility": eligibility!.toJson(),
"exam_address": examAddress!.toJson(),
"validity_date": validityDate,
"license_number": licenseNumber,
};
};
@override
String toString() {
return 'eligibility:${eligibility.toString()}, rating:$rating, examDate:${examDate.toString()},validydate:${validityDate.toString()}, lisence:$licenseNumber, examAddress:${examAddress.toString()}';
}
}
class ExamAddress {
ExamAddress({
required this.id,
required this.examAddressClass,
required this.country,
required this.barangay,
required this.addressCategory,
required this.cityMunicipality,
});
ExamAddress({
required this.id,
required this.examAddressClass,
required this.country,
required this.barangay,
required this.addressCategory,
required this.cityMunicipality,
});
final int? id;
final dynamic examAddressClass;
final Country? country;
final dynamic barangay;
final AddressCategory? addressCategory;
final CityMunicipality? cityMunicipality;
final int? id;
final dynamic examAddressClass;
final Country? country;
final dynamic barangay;
final AddressCategory? addressCategory;
final CityMunicipality? cityMunicipality;
factory ExamAddress.fromJson(Map<String, dynamic> json) => ExamAddress(
factory ExamAddress.fromJson(Map<String, dynamic> json) => ExamAddress(
id: json["id"],
examAddressClass: json["class"],
country:json["country"] == null? null: Country.fromJson(json["country"]),
country:
json["country"] == null ? null : Country.fromJson(json["country"]),
barangay: json["barangay"],
addressCategory: json["address_category"] == null?null: AddressCategory.fromJson(json["address_category"]),
cityMunicipality: json["city_municipality"]==null? null: CityMunicipality.fromJson(json["city_municipality"]),
);
addressCategory: json["address_category"] == null
? null
: AddressCategory.fromJson(json["address_category"]),
cityMunicipality: json["city_municipality"] == null
? null
: CityMunicipality.fromJson(json["city_municipality"]),
);
Map<String, dynamic> toJson() => {
Map<String, dynamic> toJson() => {
"id": id,
"class": examAddressClass,
"country": country!.toJson(),
"barangay": barangay,
"address_category": addressCategory!.toJson(),
"city_municipality": cityMunicipality!.toJson(),
};
}
};
@override
String toString() {
return 'country:${country.toString()} , address:${cityMunicipality.toString()}';
}
}

View File

@ -31,4 +31,9 @@ class Eligibility {
"title": title,
"type": type,
};
@override
String toString() {
return title;
}
}

View File

@ -3,10 +3,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:intl/intl.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:unit2/bloc/profile/profile_bloc.dart';
import 'package:unit2/bloc/user/user_bloc.dart';
import 'package:unit2/model/profile/eligibility.dart';
import '../../../../model/location/city.dart';
import '../../../../model/location/country.dart';
@ -28,7 +30,7 @@ class AddEligibilityScreen extends StatefulWidget {
}
class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
final formKey = GlobalKey<FormBuilderState>();
final formKey = GlobalKey<FormBuilderState>();
final provinceKey = GlobalKey<FormBuilderState>();
bool? overseas;
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
@ -41,6 +43,12 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
List<CityMunicipality>? citymuns;
bool provinceCall = false;
bool cityCall = false;
final examDateController = TextEditingController();
final validityDateController = TextEditingController();
String? token;
String? profileId;
String? rating;
String? license;
@override
Widget build(BuildContext context) {
//USERBLOC
@ -49,6 +57,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
//LOGGED IN USER STATE
if (state is UserLoggedIn) {
//PROFIILE BLOC
token = state.userData!.user!.login!.token;
profileId = state.userData!.user!.login!.user!.profileId.toString();
return BlocBuilder<ProfileBloc, ProfileState>(
buildWhen: (previous, current) {
if (state is EditEligibilityState) {}
@ -70,27 +80,23 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
children: [
//ELIGIBILITIES DROPDOWN
FormBuilderDropdown<Eligibility>(
onChanged: (Eligibility? eligibility) {
selectedEligibility = eligibility;
},
initialValue: state.eligibilities[0],
items: state.eligibilities
.map<DropdownMenuItem<Eligibility>>(
(Eligibility eligibility) {
return DropdownMenuItem<Eligibility>(
value: eligibility,
child: Text(eligibility.title));
}).toList(),
name: "eligibility",
decoration:
normalTextFieldStyle("Eligibility", "")
.copyWith(
hintStyle: const TextStyle(
color: Colors.black,
),
labelStyle: const TextStyle(
color: Colors.black)),
),
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: 20,
),
@ -103,9 +109,10 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible(
flex: 1,
child: FormBuilderTextField(
onChanged: (value) {
license = value;
},
name: 'license_number',
initialValue:null,
decoration: normalTextFieldStyle(
"license number", "license number"),
),
@ -117,14 +124,12 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible(
flex: 1,
child: FormBuilderTextField(
onChanged: (value) {
rating = value;
},
name: 'rating',
// ignore: prefer_null_aware_operators
initialValue:null,
decoration: normalTextFieldStyle(
'rating', 'rating'),
'rating %', 'rating'),
),
),
],
@ -141,12 +146,21 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible(
flex: 1,
child: DateTimePicker(
// controller: examDateController,
firstDate: DateTime(2000),
lastDate: DateTime(2100),
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", "Exam date"),
initialValue:null,
"Exam date", "")
.copyWith(
prefixIcon: const Icon(
Icons.date_range,
color: Colors.black87,
)),
initialValue: null,
)),
const SizedBox(
width: 12,
@ -155,12 +169,18 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible(
flex: 1,
child: DateTimePicker(
// controller: validityDateController,
firstDate: DateTime(2000),
controller: validityDateController,
firstDate: DateTime(1970),
lastDate: DateTime(2100),
decoration: normalTextFieldStyle(
"Validity date", "Validity date"),
initialValue:null,
"Validity date",
"Validity date")
.copyWith(
prefixIcon: const Icon(
Icons.date_range,
color: Colors.black87,
)),
initialValue: null,
),
),
],
@ -170,7 +190,7 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
height: 20,
),
Text(
"Placement of Examination/Confinement",
"Placement of Examination/Conferment",
style: Theme.of(context)
.textTheme
.displaySmall!
@ -202,6 +222,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
child: overseas == true
? FormBuilderDropdown<Country>(
initialValue: null,
validator: (value) =>
value == null ? 'required' : null,
items: state.countries.map<
DropdownMenuItem<
Country>>(
@ -224,6 +246,11 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
children: [
//REGION DROPDOWN
FormBuilderDropdown<Region?>(
autovalidateMode:
AutovalidateMode
.onUserInteraction,
validator: (value) =>
value == null ? 'required' : null,
onChanged:
(Region? region) async {
setState(() {
@ -253,19 +280,26 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
),
//PROVINCE DROPDOWN
SizedBox(
height: 50,
height: 70,
child: ModalProgressHUD(
color: Colors.transparent,
inAsyncCall: cityCall,
child: DropdownButtonFormField<
Province?>(
isExpanded: true,
autovalidateMode:
AutovalidateMode
.onUserInteraction,
validator: (value) =>
value == null ? 'required' : null,
isExpanded: true,
value: selectedProvince,
onChanged: (Province?
province) {
setState(() {
cityCall = true;
cityCall = true;
});
selectedProvince = province;
selectedProvince =
province;
getCities();
},
items: provinces == null
@ -278,7 +312,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
return DropdownMenuItem(
value:
province,
child: FittedBox(
child:
FittedBox(
child: Text(
province
.description!),
@ -294,33 +329,37 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
height: 20,
),
SizedBox(
height: 50,
child: DropdownButtonFormField<
height: 70,
child:
DropdownButtonFormField<
CityMunicipality>(
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(),
),
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 SizedBox(
height: 20,
@ -340,7 +379,56 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
child: ElevatedButton(
style: mainBtnStyle(
primary, Colors.transparent, second),
onPressed: () {},
onPressed: () {
double? rate = rating == null
? null
: double.parse(rating!);
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()) {
context.read<ProfileBloc>().add(
AddEligibility(
eligibityCert: eligibityCert,
profileId: profileId!,
token: token!));
}
// context.read<ProfileBloc>().add(AddEligibility(eligibityCert: eligibityCert, profileId: profileId, token: token))
},
child: const Text(submit)),
),
const SizedBox(
@ -362,21 +450,23 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
}
Future<void> getProvinces() async {
List<Province> _provinces = await LocationUtils.instance
List<Province> newProvinces = await LocationUtils.instance
.getProvinces(regionCode: selectedRegion!.code.toString());
setState(() {
provinces = _provinces;
provinces = newProvinces;
selectedProvince = provinces![0];
getCities();
provinceCall = false;
});
}
Future<void> getCities()async{
List<CityMunicipality> _cities = await LocationUtils.instance.getCities(code: selectedProvince!.code.toString());
citymuns = _cities;
setState(() {
selectedMunicipality = _cities[0];
cityCall = false;
});
Future<void> getCities() async {
List<CityMunicipality> newCities = await LocationUtils.instance
.getCities(code: selectedProvince!.code.toString());
citymuns = newCities;
setState(() {
selectedMunicipality = newCities[0];
cityCall = false;
});
}
}

View File

@ -13,6 +13,7 @@ import 'package:unit2/theme-data.dart/colors.dart';
import 'package:unit2/utils/global.dart';
import 'package:unit2/utils/text_container.dart';
import 'package:unit2/widgets/add_leading.dart';
import 'package:unit2/widgets/empty_data.dart';
import '../../../utils/alerts.dart';
@ -28,9 +29,11 @@ class EligibiltyScreen extends StatelessWidget {
title: const Text(elibilityScreenTitle),
centerTitle: true,
backgroundColor: primary,
actions: [AddLeading(onPressed: () {
context.read<ProfileBloc>().add( AddEligibility());
})],
actions: [
AddLeading(onPressed: () {
context.read<ProfileBloc>().add(ShowAddEligibilityForm());
})
],
),
body: BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
@ -49,12 +52,11 @@ class EligibiltyScreen extends StatelessWidget {
final progress = ProgressHUD.of(context);
progress!.showWithText("Loading");
}
if (state is EligibilityLoaded) {
if (state is EligibilityLoaded ||
state is AddEligibilityState ||
state is ProfileErrorState) {
final progress = ProgressHUD.of(context);
progress!.dismiss();
}if(state is AddEligibilityState){
final progress = ProgressHUD.of(context);
progress!.dismiss();
}
if (state is DeletedState) {
if (state.success) {
@ -66,158 +68,180 @@ class EligibiltyScreen extends StatelessWidget {
} else {
errorAlert(context, "Deletion Failed",
"Error deleting eligibility", () {
Navigator.of(context).pop();
context.read<ProfileBloc>().add(LoadEligibility(
eligibilities: state.eligibilities));
});
}
}
if (state is EligibilityAddedState) {
if (state.response['success']) {
Navigator.of(context).pop();
successAlert(context, "Adding Successfull!",
state.response['message'], () {
context.read<ProfileBloc>().add(LoadEligibility(
eligibilities: state.eligibilities));
});
} else {
errorAlert(context, "Adding Failed",
"Something went wrong. Please try again.", () {
Navigator.of(context).pop();
context.read<ProfileBloc>().add(LoadEligibility(
eligibilities: state.eligibilities));
});
}
}
// TODO: implement listener
},
builder: (context, state) {
return BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) {
if (state is EligibilityLoaded) {
return ListView.builder(
padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 10),
itemCount: state.eligibilities.length,
itemBuilder: (BuildContext context, int index) {
String title = state
.eligibilities[index].eligibility!.title;
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: screenWidth,
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 8),
decoration: box1(),
child: Row(
children: [
Expanded(
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(
fontWeight:
FontWeight
.w500),
),
const Divider(),
const SizedBox(
height: 5,
),
Text(
"$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}",
if (state.eligibilities.isNotEmpty) {
return ListView.builder(
padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 10),
itemCount: state.eligibilities.length,
itemBuilder: (BuildContext context, int index) {
String title = state
.eligibilities[index].eligibility!.title;
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Container(
width: screenWidth,
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 8),
decoration: box1(),
child: Row(
children: [
Expanded(
child: Column(
mainAxisAlignment:
MainAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context)
.textTheme
.titleSmall),
const SizedBox(
height: 3,
),
Text(
"Rating : ${state.eligibilities[index].rating ?? 'N/A'}.",
style: Theme.of(context)
.textTheme
.titleSmall)
]),
),
AppPopupMenu<int>(
offset: const Offset(-10, -10),
elevation: 3,
onSelected: (value) {
if (value == 2) {
confirmAlert(context, () {
BlocProvider.of<
ProfileBloc>(context)
.add(DeleteEligibility(
eligibilities: state
.eligibilities,
eligibilityId: state
.eligibilities[
index]
.id!,
profileId: profileId!,
token: token!));
}, "Delete?",
"Confirm Delete?");
}
if (value == 1) {
EligibityCert eligibityCert =
state.eligibilities[index];
bool overseas = eligibityCert
.examAddress!
.country!
.id
.toString() ==
'175'
? false
: true;
eligibityCert.overseas =
overseas;
final progress =
ProgressHUD.of(context);
eligibityCert.overseas =
overseas;
progress!
.showWithText("Loading...");
context.read<ProfileBloc>().add(
EditEligibility(
eligibityCert:
eligibityCert));
}
},
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,
.titleMedium!
.copyWith(
fontWeight:
FontWeight
.w500),
),
const Divider(),
const SizedBox(
height: 5,
),
Text(
"$licenseNumber: ${state.eligibilities[index].licenseNumber == null ? 'N/A' : state.eligibilities[index].licenseNumber.toString()}",
style: Theme.of(context)
.textTheme
.titleSmall),
const SizedBox(
height: 3,
),
Text(
"Rating : ${state.eligibilities[index].rating ?? 'N/A'}.",
style: Theme.of(context)
.textTheme
.titleSmall)
]),
),
tooltip: "Options",
)
],
AppPopupMenu<int>(
offset: const Offset(-10, -10),
elevation: 3,
onSelected: (value) {
if (value == 2) {
confirmAlert(context, () {
BlocProvider.of<
ProfileBloc>(
context)
.add(DeleteEligibility(
eligibilities: state
.eligibilities,
eligibilityId: state
.eligibilities[
index]
.id!,
profileId:
profileId!,
token: token!));
}, "Delete?",
"Confirm Delete?");
}
if (value == 1) {
EligibityCert eligibityCert =
state
.eligibilities[index];
bool overseas = eligibityCert
.examAddress!
.country!
.id
.toString() ==
'175'
? false
: true;
eligibityCert.overseas =
overseas;
final progress =
ProgressHUD.of(context);
eligibityCert.overseas =
overseas;
progress!.showWithText(
"Loading...");
context
.read<ProfileBloc>()
.add(EditEligibility(
eligibityCert:
eligibityCert));
}
},
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",
)
],
),
),
),
const SizedBox(
height: 5,
)
],
);
});
const SizedBox(
height: 5,
)
],
);
});
} else {
return const EmptyData(
message:
"You don't have any eligibilities added. Please click + to add");
}
}
if (state is EditEligibilityState) {
return EditEligibilityScreen(
eligibityCert: state.eligibityCert);
}if(state is AddEligibilityState){
return const AddEligibilityScreen();
}
if (state is DeletedState) {
return Center(
child: Container(
child: Text(state.success.toString())),
);
if (state is AddEligibilityState) {
return const AddEligibilityScreen();
}
if (state is ProfileErrorState) {
return Center(

View File

@ -1,35 +1,77 @@
import 'dart:convert';
import 'package:unit2/model/profile/eligibility.dart';
import 'package:unit2/utils/request.dart';
import 'package:unit2/utils/urls.dart';
import 'package:http/http.dart' as http;
class EligibilityService{
class EligibilityService {
static final EligibilityService _instance = EligibilityService();
static EligibilityService get instance => _instance;
Future<bool> delete({required int eligibilityId, required int profileId,required String token})async{
bool? success;
String Authtoken = "Token $token";
String path = "${Url.instance.deleteEligibility()}$profileId/";
Map body = { "eligibility_id": eligibilityId};
Map<String, dynamic> params ={"force_mode":"true"};
Map<String, String> headers = {
Future<bool> delete(
{required int eligibilityId,
required int profileId,
required String token}) async {
bool? success;
String authtoken = "Token $token";
String path = "${Url.instance.deleteEligibility()}$profileId/";
Map body = {"eligibility_id": eligibilityId};
Map<String, dynamic> params = {"force_mode": "true"};
Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': "Token $token"
'Authorization': authtoken
};
// try{
http.Response response = await Request.instance.deleteRequest(path: path, headers: headers, body: body, param: params);
if(response.statusCode == 200){
Map data = jsonDecode(response.body);
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{
} else {
success = false;
}
}
// }catch(e){
// throw(e.toString());
// }
return success!;
}
}
Future<Map<dynamic, dynamic>> add(
{required EligibityCert eligibityCert,
required String token,
required int profileId}) async {
Map<dynamic, dynamic>? _response={};
String authtoken = "Token $token+1";
String path = '${Url.instance.addEligibility()}$profileId/';
Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': authtoken
};
Map body = {
'eligibility_id': eligibityCert.eligibility!.id,
'license_number': eligibityCert.licenseNumber,
'exam_date': eligibityCert.examDate?.toString(),
'validity_date': eligibityCert.validityDate?.toString(),
'rating': eligibityCert.rating,
'_citymunCode': eligibityCert.examAddress?.cityMunicipality?.code,
'_countryId': eligibityCert.examAddress?.country!.id
};
try {
http.Response response = await Request.instance
.postRequest(path: path, body: body, headers: headers, param: {});
if (response.statusCode == 201) {
Map data = jsonDecode(response.body);
_response = data;
} else {
_response.addAll({'success':false});
}
return _response;
} catch (e) {
throw e.toString();
}
}
}

View File

@ -49,6 +49,8 @@ InputDecoration normalTextFieldStyle(String labelText, String hintText) {
filled: false);
}
InputDecoration loginTextFieldStyle() {
return InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.never,

View File

@ -1,5 +1,6 @@
import 'package:awesome_dialog/awesome_dialog.dart';
import 'package:flutter/material.dart';
import 'package:unit2/theme-data.dart/btn-style.dart';
import 'package:unit2/theme-data.dart/colors.dart';
import 'package:unit2/utils/global.dart';
@ -45,8 +46,7 @@ errorAlert(context, title, description,Function() func) {
headerAnimationLoop: false,
title: title,
desc: description,
btnOkOnPress: func,
btnOkColor: Colors.red,
btnOk: SizedBox(height: 50,child: ElevatedButton(onPressed:func, style: mainBtnStyle(primary, Colors.transparent, second), child: const Text("OK")), )
).show();
}
successAlert(context, title, description,Function() func) {
@ -58,7 +58,6 @@ successAlert(context, title, description,Function() func) {
headerAnimationLoop: false,
title: title,
desc: description,
btnOkOnPress: func,
btnOkColor: Colors.red,
btnOk: SizedBox(height: 50,child: ElevatedButton(style: mainBtnStyle(primary, Colors.transparent, second), onPressed: func, child: const Text("OK")), )
).show();
}

View File

@ -5,8 +5,8 @@ class Url {
String host() {
// return '192.168.10.221:3003';
// return 'agusandelnorte.gov.ph';
return "192.168.10.219:3000";
// return 'devweb.agusandelnorte.gov.ph';
// return "192.168.10.219:3000";
return 'devweb.agusandelnorte.gov.ph';
}
String authentication() {
@ -24,6 +24,10 @@ class Url {
String eligibilities(){
return "/api/jobnet_app/eligibilities/";
}
String addEligibility(){
return "/api/jobnet_app/profile/pds/eligibility/";
}
String deleteEligibility(){
return "/api/jobnet_app/profile/pds/eligibility/";
}