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

View File

@ -1,39 +1,34 @@
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.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/eligibility.dart';
import 'package:unit2/model/profile/profileInfomation.dart'; import 'package:unit2/model/profile/profileInfomation.dart';
import 'package:unit2/model/utils/eligibility.dart'; import 'package:unit2/model/utils/eligibility.dart';
import 'package:unit2/sevices/profile/eligibility_services.dart'; import 'package:unit2/sevices/profile/eligibility_services.dart';
import 'package:unit2/sevices/profile/profile_service.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/location_utilities.dart';
import 'package:unit2/utils/profile_utilities.dart'; import 'package:unit2/utils/profile_utilities.dart';
import '../../model/location/country.dart'; import '../../model/location/country.dart';
import '../../model/location/region.dart'; import '../../model/location/region.dart';
import '../../model/location/provinces.dart'; import '../../model/location/provinces.dart';
import '../../model/location/city.dart'; import '../../model/location/city.dart';
import '../../model/location/barangay.dart';
part 'profile_event.dart'; part 'profile_event.dart';
part 'profile_state.dart'; part 'profile_state.dart';
class ProfileBloc extends Bloc<ProfileEvent, ProfileState> { class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
ProfileBloc() : super(ProfileInitial()) { ProfileBloc() : super(ProfileInitial()) {
ProfileInformation? _profileInformation; ProfileInformation? globalProfileInformation;
List<Country>? _countries; List<Country>? globalCountries;
List<Region>? _regions; List<Region>? globalRegions;
List<Eligibility>? _eligibilities; List<Eligibility>? globalEligibilities;
List<Province>? _provinces; List<EligibityCert>? eligibilities;
List<CityMunicipality>? _cities;
////========================================================================= ////=========================================================================
on<LoadProfile>((event, emit) async { on<LoadProfile>((event, emit) async {
// try { // try {
emit(ProfileLoading()); emit(ProfileLoading());
ProfileInformation? profileInformation = ProfileInformation? profileInformation =
await ProfileService.instance.getProfile(event.token, event.userID); await ProfileService.instance.getProfile(event.token, event.userID);
_profileInformation = profileInformation; globalProfileInformation = profileInformation;
emit(ProfileLoaded(profileInformation: _profileInformation!)); emit(ProfileLoaded(profileInformation: globalProfileInformation!));
// } catch (e) { // } catch (e) {
// emit(ProfileErrorState(mesage: e.toString())); // emit(ProfileErrorState(mesage: e.toString()));
// } // }
@ -41,46 +36,34 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
////===================================================================== ////=====================================================================
on<LoadEligibility>((event, emit) { on<LoadEligibility>((event, emit) {
emit(ProfileLoading()); emit(ProfileLoading());
eligibilities = event.eligibilities;
emit(EligibilityLoaded(eligibilities: event.eligibilities)); emit(EligibilityLoaded(eligibilities: event.eligibilities));
}); });
////==================================================================== ////====================================================================
on<EditEligibility>((event, emit) async { on<EditEligibility>((event, emit) async {
Region? currentRegion;
Province? currentProvince;
CityMunicipality? currentCity;
// try{ // try{
emit(ProfileLoading()); emit(ProfileLoading());
if (_countries == null) { if (globalCountries == null) {
List<Country> countries = await LocationUtils.instance.getCountries(); List<Country> countries = await LocationUtils.instance.getCountries();
_countries = countries; globalCountries = countries;
} }
if (_regions == null) { if (globalRegions == null) {
List<Region> regions = await LocationUtils.instance.getRegions(); List<Region> regions = await LocationUtils.instance.getRegions();
_regions = regions; globalRegions = regions;
} }
if (_eligibilities == null) { if (globalEligibilities == null) {
List<Eligibility> eligibilities = List<Eligibility> eligibilities =
await ProfileUtilities.instance.getEligibilities(); 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; bool? isOverseas = event.eligibityCert.overseas;
emit(EditEligibilityState( emit(EditEligibilityState(
isOverseas: isOverseas!, isOverseas: isOverseas!,
eligibityCert: event.eligibityCert, eligibityCert: event.eligibityCert,
countries: _countries!, countries: globalCountries!,
regions: _regions!, regions: globalRegions!,
eligibilities: _eligibilities!)); eligibilities: globalEligibilities!));
// }catch(e){ // }catch(e){
// emit(ProfileErrorState(mesage: e.toString())); // emit(ProfileErrorState(mesage: e.toString()));
@ -88,29 +71,26 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
////==================================================================== ////====================================================================
}); });
on<AddEligibility>((event, emit) async { on<ShowAddEligibilityForm>((event, emit) async {
List<CityMunicipality>? cities;
List<Province>? provinces;
Eligibility? currentEligibility;
emit(ProfileLoading()); emit(ProfileLoading());
if (_regions == null) { if (globalRegions == null) {
List<Region> regions = await LocationUtils.instance.getRegions(); List<Region> regions = await LocationUtils.instance.getRegions();
_regions = regions; globalRegions = regions;
} }
if (_eligibilities == null) { if (globalEligibilities == null) {
List<Eligibility> eligibilities = List<Eligibility> eligibilities =
await ProfileUtilities.instance.getEligibilities(); await ProfileUtilities.instance.getEligibilities();
_eligibilities = eligibilities; globalEligibilities = eligibilities;
} }
if (_countries == null) { if (globalCountries == null) {
List<Country> countries = await LocationUtils.instance.getCountries(); List<Country> countries = await LocationUtils.instance.getCountries();
_countries = countries; globalCountries = countries;
} }
emit(AddEligibilityState( emit(AddEligibilityState(
eligibilities: _eligibilities!, eligibilities: globalEligibilities!,
regions: _regions!, regions: globalRegions!,
countries: _countries!)); countries: globalCountries!));
}); });
////==================================================================== ////====================================================================
on<DeleteEligibility>((event, emit) async { on<DeleteEligibility>((event, emit) async {
@ -133,5 +113,28 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
emit(ProfileErrorState(mesage: e.toString())); 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

@ -13,7 +13,6 @@ final int userID;
const LoadProfile({required this.token, required this.userID}); const LoadProfile({required this.token, required this.userID});
@override @override
List<Object> get props => [token, userID]; List<Object> get props => [token, userID];
} }
class LoadProfileInformation extends ProfileEvent { class LoadProfileInformation extends ProfileEvent {
@ -40,13 +39,23 @@ class DeleteEligibility extends ProfileEvent{
final String profileId; final String profileId;
final int eligibilityId; final int eligibilityId;
final String token; final String token;
const DeleteEligibility({ required this.eligibilities, required this.eligibilityId, required this.profileId, required this.token}); const DeleteEligibility(
{required this.eligibilities,
required this.eligibilityId,
required this.profileId,
required this.token});
@override @override
List<Object> get props => [eligibilities, profileId, eligibilityId, token]; List<Object> get props => [eligibilities, profileId, eligibilityId, token];
} }
class AddEligibility extends ProfileEvent{ 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 @override
List<Object> get props => [eligibilities,countries,regions]; 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/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:unit2/bloc/user/user_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/app_router.dart';
import 'package:unit2/utils/global_context.dart'; import 'package:unit2/utils/global_context.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, // routeInformationParser: goRouter.routeInformationParser,
// routerDelegate: goRouter.routerDelegate, // routerDelegate: goRouter.routerDelegate,
// routeInformationProvider: goRouter.routeInformationProvider, // routeInformationProvider: goRouter.routeInformationProvider,
title: 'uniT2 - Universal Tracker and Tracer', title: 'uniT2 - Universal Tracker and Tracer',
theme: ThemeData( theme: ThemeData(
primarySwatch: Colors.red,
appBarTheme: const AppBarTheme( appBarTheme: const AppBarTheme(
systemOverlayStyle: SystemUiOverlayStyle( systemOverlayStyle: SystemUiOverlayStyle(
statusBarBrightness: Brightness.dark, statusBarBrightness: Brightness.dark,

View File

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

View File

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

View File

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

View File

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

View File

@ -12,7 +12,8 @@ import '../location/city.dart';
import '../location/country.dart'; import '../location/country.dart';
import '../utils/eligibility.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()); String eligibityToJson(EligibityCert data) => json.encode(data.toJson());
@ -41,10 +42,16 @@ class EligibityCert {
factory EligibityCert.fromJson(Map<String, dynamic> json) => EligibityCert( factory EligibityCert.fromJson(Map<String, dynamic> json) => EligibityCert(
id: json["id"], id: json["id"],
rating: json["rating"]?.toDouble(), 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, attachments: null,
eligibility: json['eligibility'] == null?null: Eligibility.fromJson(json["eligibility"]), eligibility: json['eligibility'] == null
examAddress: json['exam_address'] == null? null: ExamAddress.fromJson(json["exam_address"]), ? null
: Eligibility.fromJson(json["eligibility"]),
examAddress: json['exam_address'] == null
? null
: ExamAddress.fromJson(json["exam_address"]),
validityDate: json["validity_date"], validityDate: json["validity_date"],
licenseNumber: json["license_number"], licenseNumber: json["license_number"],
overseas: null, overseas: null,
@ -53,15 +60,19 @@ class EligibityCert {
Map<String, dynamic> toJson() => { Map<String, dynamic> toJson() => {
"id": id, "id": id,
"rating": rating, "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, "attachments": attachments,
"eligibility": eligibility!.toJson(), "eligibility": eligibility!.toJson(),
"exam_address": examAddress!.toJson(), "exam_address": examAddress!.toJson(),
"validity_date": validityDate, "validity_date": validityDate,
"license_number": licenseNumber, "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 { class ExamAddress {
ExamAddress({ ExamAddress({
@ -83,10 +94,15 @@ class ExamAddress {
factory ExamAddress.fromJson(Map<String, dynamic> json) => ExamAddress( factory ExamAddress.fromJson(Map<String, dynamic> json) => ExamAddress(
id: json["id"], id: json["id"],
examAddressClass: json["class"], examAddressClass: json["class"],
country:json["country"] == null? null: Country.fromJson(json["country"]), country:
json["country"] == null ? null : Country.fromJson(json["country"]),
barangay: json["barangay"], barangay: json["barangay"],
addressCategory: json["address_category"] == null?null: AddressCategory.fromJson(json["address_category"]), addressCategory: json["address_category"] == null
cityMunicipality: json["city_municipality"]==null? null: CityMunicipality.fromJson(json["city_municipality"]), ? 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() => {
@ -97,5 +113,9 @@ class ExamAddress {
"address_category": addressCategory!.toJson(), "address_category": addressCategory!.toJson(),
"city_municipality": cityMunicipality!.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, "title": title,
"type": type, "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_bloc/flutter_bloc.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_progress_hud/flutter_progress_hud.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:intl/intl.dart';
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
import 'package:unit2/bloc/profile/profile_bloc.dart'; import 'package:unit2/bloc/profile/profile_bloc.dart';
import 'package:unit2/bloc/user/user_bloc.dart'; import 'package:unit2/bloc/user/user_bloc.dart';
import 'package:unit2/model/profile/eligibility.dart';
import '../../../../model/location/city.dart'; import '../../../../model/location/city.dart';
import '../../../../model/location/country.dart'; import '../../../../model/location/country.dart';
@ -41,6 +43,12 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
List<CityMunicipality>? citymuns; List<CityMunicipality>? citymuns;
bool provinceCall = false; bool provinceCall = false;
bool cityCall = false; bool cityCall = false;
final examDateController = TextEditingController();
final validityDateController = TextEditingController();
String? token;
String? profileId;
String? rating;
String? license;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
//USERBLOC //USERBLOC
@ -49,6 +57,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
//LOGGED IN USER STATE //LOGGED IN USER STATE
if (state is UserLoggedIn) { if (state is UserLoggedIn) {
//PROFIILE BLOC //PROFIILE BLOC
token = state.userData!.user!.login!.token;
profileId = state.userData!.user!.login!.user!.profileId.toString();
return BlocBuilder<ProfileBloc, ProfileState>( return BlocBuilder<ProfileBloc, ProfileState>(
buildWhen: (previous, current) { buildWhen: (previous, current) {
if (state is EditEligibilityState) {} if (state is EditEligibilityState) {}
@ -73,7 +83,10 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
onChanged: (Eligibility? eligibility) { onChanged: (Eligibility? eligibility) {
selectedEligibility = eligibility; selectedEligibility = eligibility;
}, },
initialValue: state.eligibilities[0], autovalidateMode:
AutovalidateMode.onUserInteraction,
validator: (value) =>
value == null ? 'required' : null,
items: state.eligibilities items: state.eligibilities
.map<DropdownMenuItem<Eligibility>>( .map<DropdownMenuItem<Eligibility>>(
(Eligibility eligibility) { (Eligibility eligibility) {
@ -82,15 +95,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
child: Text(eligibility.title)); child: Text(eligibility.title));
}).toList(), }).toList(),
name: "eligibility", name: "eligibility",
decoration: decoration: normalTextFieldStyle(
normalTextFieldStyle("Eligibility", "") "Eligibility", "Eligibility")),
.copyWith(
hintStyle: const TextStyle(
color: Colors.black,
),
labelStyle: const TextStyle(
color: Colors.black)),
),
const SizedBox( const SizedBox(
height: 20, height: 20,
), ),
@ -103,9 +109,10 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible( Flexible(
flex: 1, flex: 1,
child: FormBuilderTextField( child: FormBuilderTextField(
onChanged: (value) {
license = value;
},
name: 'license_number', name: 'license_number',
initialValue:null,
decoration: normalTextFieldStyle( decoration: normalTextFieldStyle(
"license number", "license number"), "license number", "license number"),
), ),
@ -117,14 +124,12 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible( Flexible(
flex: 1, flex: 1,
child: FormBuilderTextField( child: FormBuilderTextField(
onChanged: (value) {
rating = value;
},
name: 'rating', name: 'rating',
// ignore: prefer_null_aware_operators
initialValue:null,
decoration: normalTextFieldStyle( decoration: normalTextFieldStyle(
'rating', 'rating'), 'rating %', 'rating'),
), ),
), ),
], ],
@ -141,11 +146,20 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible( Flexible(
flex: 1, flex: 1,
child: DateTimePicker( child: DateTimePicker(
// controller: examDateController, use24HourFormat: false,
firstDate: DateTime(2000), icon: const Icon(Icons.date_range),
controller: examDateController,
firstDate: DateTime(1970),
lastDate: DateTime(2100), lastDate: DateTime(2100),
timeHintText:
"Date of Examination/Conferment",
decoration: normalTextFieldStyle( decoration: normalTextFieldStyle(
"Exam date", "Exam date"), "Exam date", "")
.copyWith(
prefixIcon: const Icon(
Icons.date_range,
color: Colors.black87,
)),
initialValue: null, initialValue: null,
)), )),
const SizedBox( const SizedBox(
@ -155,11 +169,17 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
Flexible( Flexible(
flex: 1, flex: 1,
child: DateTimePicker( child: DateTimePicker(
// controller: validityDateController, controller: validityDateController,
firstDate: DateTime(2000), firstDate: DateTime(1970),
lastDate: DateTime(2100), lastDate: DateTime(2100),
decoration: normalTextFieldStyle( decoration: normalTextFieldStyle(
"Validity date", "Validity date"), "Validity date",
"Validity date")
.copyWith(
prefixIcon: const Icon(
Icons.date_range,
color: Colors.black87,
)),
initialValue: null, initialValue: null,
), ),
), ),
@ -170,7 +190,7 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
height: 20, height: 20,
), ),
Text( Text(
"Placement of Examination/Confinement", "Placement of Examination/Conferment",
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.displaySmall! .displaySmall!
@ -202,6 +222,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
child: overseas == true child: overseas == true
? FormBuilderDropdown<Country>( ? FormBuilderDropdown<Country>(
initialValue: null, initialValue: null,
validator: (value) =>
value == null ? 'required' : null,
items: state.countries.map< items: state.countries.map<
DropdownMenuItem< DropdownMenuItem<
Country>>( Country>>(
@ -224,6 +246,11 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
children: [ children: [
//REGION DROPDOWN //REGION DROPDOWN
FormBuilderDropdown<Region?>( FormBuilderDropdown<Region?>(
autovalidateMode:
AutovalidateMode
.onUserInteraction,
validator: (value) =>
value == null ? 'required' : null,
onChanged: onChanged:
(Region? region) async { (Region? region) async {
setState(() { setState(() {
@ -253,11 +280,17 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
), ),
//PROVINCE DROPDOWN //PROVINCE DROPDOWN
SizedBox( SizedBox(
height: 50, height: 70,
child: ModalProgressHUD( child: ModalProgressHUD(
color: Colors.transparent,
inAsyncCall: cityCall, inAsyncCall: cityCall,
child: DropdownButtonFormField< child: DropdownButtonFormField<
Province?>( Province?>(
autovalidateMode:
AutovalidateMode
.onUserInteraction,
validator: (value) =>
value == null ? 'required' : null,
isExpanded: true, isExpanded: true,
value: selectedProvince, value: selectedProvince,
onChanged: (Province? onChanged: (Province?
@ -265,7 +298,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
setState(() { setState(() {
cityCall = true; cityCall = true;
}); });
selectedProvince = province; selectedProvince =
province;
getCities(); getCities();
}, },
items: provinces == null items: provinces == null
@ -278,7 +312,8 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
return DropdownMenuItem( return DropdownMenuItem(
value: value:
province, province,
child: FittedBox( child:
FittedBox(
child: Text( child: Text(
province province
.description!), .description!),
@ -294,9 +329,13 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
height: 20, height: 20,
), ),
SizedBox( SizedBox(
height: 50, height: 70,
child: DropdownButtonFormField< child:
DropdownButtonFormField<
CityMunicipality>( CityMunicipality>(
validator: (value) =>
value == null ? 'required' : null,
isExpanded: true,
onChanged: onChanged:
(CityMunicipality? (CityMunicipality?
city) { city) {
@ -340,7 +379,56 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
child: ElevatedButton( child: ElevatedButton(
style: mainBtnStyle( style: mainBtnStyle(
primary, Colors.transparent, second), 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)), child: const Text(submit)),
), ),
const SizedBox( const SizedBox(
@ -362,20 +450,22 @@ class _AddEligibilityScreenState extends State<AddEligibilityScreen> {
} }
Future<void> getProvinces() async { Future<void> getProvinces() async {
List<Province> _provinces = await LocationUtils.instance List<Province> newProvinces = await LocationUtils.instance
.getProvinces(regionCode: selectedRegion!.code.toString()); .getProvinces(regionCode: selectedRegion!.code.toString());
setState(() { setState(() {
provinces = _provinces; provinces = newProvinces;
selectedProvince = provinces![0]; selectedProvince = provinces![0];
getCities(); getCities();
provinceCall = false; provinceCall = false;
}); });
} }
Future<void> getCities() async { Future<void> getCities() async {
List<CityMunicipality> _cities = await LocationUtils.instance.getCities(code: selectedProvince!.code.toString()); List<CityMunicipality> newCities = await LocationUtils.instance
citymuns = _cities; .getCities(code: selectedProvince!.code.toString());
citymuns = newCities;
setState(() { setState(() {
selectedMunicipality = _cities[0]; selectedMunicipality = newCities[0];
cityCall = false; 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/global.dart';
import 'package:unit2/utils/text_container.dart'; import 'package:unit2/utils/text_container.dart';
import 'package:unit2/widgets/add_leading.dart'; import 'package:unit2/widgets/add_leading.dart';
import 'package:unit2/widgets/empty_data.dart';
import '../../../utils/alerts.dart'; import '../../../utils/alerts.dart';
@ -28,9 +29,11 @@ class EligibiltyScreen extends StatelessWidget {
title: const Text(elibilityScreenTitle), title: const Text(elibilityScreenTitle),
centerTitle: true, centerTitle: true,
backgroundColor: primary, backgroundColor: primary,
actions: [AddLeading(onPressed: () { actions: [
context.read<ProfileBloc>().add( AddEligibility()); AddLeading(onPressed: () {
})], context.read<ProfileBloc>().add(ShowAddEligibilityForm());
})
],
), ),
body: BlocBuilder<UserBloc, UserState>( body: BlocBuilder<UserBloc, UserState>(
builder: (context, state) { builder: (context, state) {
@ -49,10 +52,9 @@ class EligibiltyScreen extends StatelessWidget {
final progress = ProgressHUD.of(context); final progress = ProgressHUD.of(context);
progress!.showWithText("Loading"); progress!.showWithText("Loading");
} }
if (state is EligibilityLoaded) { if (state is EligibilityLoaded ||
final progress = ProgressHUD.of(context); state is AddEligibilityState ||
progress!.dismiss(); state is ProfileErrorState) {
}if(state is AddEligibilityState){
final progress = ProgressHUD.of(context); final progress = ProgressHUD.of(context);
progress!.dismiss(); progress!.dismiss();
} }
@ -66,17 +68,35 @@ class EligibiltyScreen extends StatelessWidget {
} else { } else {
errorAlert(context, "Deletion Failed", errorAlert(context, "Deletion Failed",
"Error deleting eligibility", () { "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( context.read<ProfileBloc>().add(LoadEligibility(
eligibilities: state.eligibilities)); eligibilities: state.eligibilities));
}); });
} }
} }
// TODO: implement listener
}, },
builder: (context, state) { builder: (context, state) {
return BlocBuilder<ProfileBloc, ProfileState>( return BlocBuilder<ProfileBloc, ProfileState>(
builder: (context, state) { builder: (context, state) {
if (state is EligibilityLoaded) { if (state is EligibilityLoaded) {
if (state.eligibilities.isNotEmpty) {
return ListView.builder( return ListView.builder(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 10), vertical: 8, horizontal: 10),
@ -86,7 +106,8 @@ class EligibiltyScreen extends StatelessWidget {
.eligibilities[index].eligibility!.title; .eligibilities[index].eligibility!.title;
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment:
CrossAxisAlignment.start,
children: [ children: [
Container( Container(
width: screenWidth, width: screenWidth,
@ -138,7 +159,8 @@ class EligibiltyScreen extends StatelessWidget {
if (value == 2) { if (value == 2) {
confirmAlert(context, () { confirmAlert(context, () {
BlocProvider.of< BlocProvider.of<
ProfileBloc>(context) ProfileBloc>(
context)
.add(DeleteEligibility( .add(DeleteEligibility(
eligibilities: state eligibilities: state
.eligibilities, .eligibilities,
@ -146,14 +168,16 @@ class EligibiltyScreen extends StatelessWidget {
.eligibilities[ .eligibilities[
index] index]
.id!, .id!,
profileId: profileId!, profileId:
profileId!,
token: token!)); token: token!));
}, "Delete?", }, "Delete?",
"Confirm Delete?"); "Confirm Delete?");
} }
if (value == 1) { if (value == 1) {
EligibityCert eligibityCert = EligibityCert eligibityCert =
state.eligibilities[index]; state
.eligibilities[index];
bool overseas = eligibityCert bool overseas = eligibityCert
.examAddress! .examAddress!
.country! .country!
@ -168,11 +192,11 @@ class EligibiltyScreen extends StatelessWidget {
ProgressHUD.of(context); ProgressHUD.of(context);
eligibityCert.overseas = eligibityCert.overseas =
overseas; overseas;
progress! progress!.showWithText(
.showWithText("Loading..."); "Loading...");
context.read<ProfileBloc>().add( context
EditEligibility( .read<ProfileBloc>()
.add(EditEligibility(
eligibityCert: eligibityCert:
eligibityCert)); eligibityCert));
} }
@ -206,18 +230,18 @@ class EligibiltyScreen extends StatelessWidget {
], ],
); );
}); });
} else {
return const EmptyData(
message:
"You don't have any eligibilities added. Please click + to add");
}
} }
if (state is EditEligibilityState) { if (state is EditEligibilityState) {
return EditEligibilityScreen( return EditEligibilityScreen(
eligibityCert: state.eligibityCert); eligibityCert: state.eligibityCert);
}if(state is AddEligibilityState){
return const AddEligibilityScreen();
} }
if (state is DeletedState) { if (state is AddEligibilityState) {
return Center( return const AddEligibilityScreen();
child: Container(
child: Text(state.success.toString())),
);
} }
if (state is ProfileErrorState) { if (state is ProfileErrorState) {
return Center( return Center(

View File

@ -1,24 +1,30 @@
import 'dart:convert'; import 'dart:convert';
import 'package:unit2/model/profile/eligibility.dart';
import 'package:unit2/utils/request.dart'; import 'package:unit2/utils/request.dart';
import 'package:unit2/utils/urls.dart'; import 'package:unit2/utils/urls.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
class EligibilityService { class EligibilityService {
static final EligibilityService _instance = EligibilityService(); static final EligibilityService _instance = EligibilityService();
static EligibilityService get instance => _instance; static EligibilityService get instance => _instance;
Future<bool> delete({required int eligibilityId, required int profileId,required String token})async{ Future<bool> delete(
{required int eligibilityId,
required int profileId,
required String token}) async {
bool? success; bool? success;
String Authtoken = "Token $token"; String authtoken = "Token $token";
String path = "${Url.instance.deleteEligibility()}$profileId/"; String path = "${Url.instance.deleteEligibility()}$profileId/";
Map body = {"eligibility_id": eligibilityId}; Map body = {"eligibility_id": eligibilityId};
Map<String, dynamic> params = {"force_mode": "true"}; Map<String, dynamic> params = {"force_mode": "true"};
Map<String, String> headers = { Map<String, String> headers = {
'Content-Type': 'application/json; charset=UTF-8', 'Content-Type': 'application/json; charset=UTF-8',
'Authorization': "Token $token" 'Authorization': authtoken
}; };
// try{ // try{
http.Response response = await Request.instance.deleteRequest(path: path, headers: headers, body: body, param: params); http.Response response = await Request.instance
.deleteRequest(path: path, headers: headers, body: body, param: params);
if (response.statusCode == 200) { if (response.statusCode == 200) {
Map data = jsonDecode(response.body); Map data = jsonDecode(response.body);
success = data['success']; success = data['success'];
@ -32,4 +38,40 @@ class EligibilityService{
return success!; 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); filled: false);
} }
InputDecoration loginTextFieldStyle() { InputDecoration loginTextFieldStyle() {
return InputDecoration( return InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,

View File

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

View File

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