agency areaType selection
parent
749bd30fab
commit
8fea765258
|
@ -59,9 +59,18 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
|||
}
|
||||
});
|
||||
on<GetPrimaryBasicInfo>((event, emit) {
|
||||
currentProfileInformation = event.primaryBasicInformation;
|
||||
emit(BasicInformationProfileLoaded(
|
||||
primaryBasicInformation: event.primaryBasicInformation));
|
||||
if(currentProfileInformation != null){
|
||||
emit(BasicInformationProfileLoaded(
|
||||
primaryBasicInformation: currentProfileInformation!));
|
||||
}else{
|
||||
currentProfileInformation = event.primaryBasicInformation;
|
||||
emit(BasicInformationProfileLoaded(
|
||||
primaryBasicInformation: currentProfileInformation!));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
on<LoadBasicPrimaryInfo>((event, emit) {
|
||||
emit(BasicInformationProfileLoaded(
|
||||
|
@ -132,6 +141,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
|
|||
if (status['success']) {
|
||||
Profile profile = Profile.fromJson(status['data']);
|
||||
currentProfileInformation = profile;
|
||||
|
||||
emit(BasicProfileInfoEditedState(response: status));
|
||||
}
|
||||
emit(BasicProfileInfoEditedState(response: status));
|
||||
|
|
|
@ -29,8 +29,10 @@ class AssignAreaBloc extends Bloc<AssignAreaEvent, AssignAreaState> {
|
|||
fullname = profile!.lastName;
|
||||
fullname = "${fname!} ${lname!}";
|
||||
id = profile!.webuserId!;
|
||||
userAssignedAreas = await RbacAssignedAreaServices.instance.getAssignedArea(id: profile!.webuserId!);
|
||||
emit(AssignedAreaLoadedState(userAssignedAreas: userAssignedAreas, fullname: fullname!));
|
||||
userAssignedAreas = await RbacAssignedAreaServices.instance
|
||||
.getAssignedArea(id: profile!.webuserId!);
|
||||
emit(AssignedAreaLoadedState(
|
||||
userAssignedAreas: userAssignedAreas, fullname: fullname!));
|
||||
} else {
|
||||
emit(UserNotExistError());
|
||||
}
|
||||
|
@ -38,5 +40,26 @@ class AssignAreaBloc extends Bloc<AssignAreaEvent, AssignAreaState> {
|
|||
emit(AssignAreaErorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
on<LoadAssignedAreas>((event, emit) async {
|
||||
emit(AssignedAreaLoadedState(
|
||||
userAssignedAreas: userAssignedAreas, fullname: fullname!));
|
||||
});
|
||||
on<DeleteAssignedArea>((event, emit) async {
|
||||
emit(AssignAreaLoadingState());
|
||||
try {
|
||||
bool success = await RbacRoleAssignmentServices.instance
|
||||
.deleteAssignedRole(roleId: event.areaId);
|
||||
if (success) {
|
||||
emit(AssignedAreaDeletedState(success: success));
|
||||
} else {
|
||||
emit(AssignedAreaDeletedState(success: success));
|
||||
}
|
||||
} catch (e) {
|
||||
emit(AssignAreaErorState(message: e.toString()));
|
||||
}
|
||||
});
|
||||
on<CallErrorState>((event, emit) {
|
||||
emit(AssignAreaErorState(message: event.message));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,5 +10,22 @@ class GetAssignArea extends AssignAreaEvent{
|
|||
final String firstname;
|
||||
final String lastname;
|
||||
const GetAssignArea({required this.firstname, required this.lastname});
|
||||
@override
|
||||
List<Object> get props => [firstname,lastname];
|
||||
}
|
||||
class DeleteAssignedArea extends AssignAreaEvent{
|
||||
final int areaId;
|
||||
const DeleteAssignedArea({required this.areaId});
|
||||
@override
|
||||
List<Object> get props => [areaId];
|
||||
}
|
||||
|
||||
class LoadAssignedAreas extends AssignAreaEvent{
|
||||
|
||||
}
|
||||
class CallErrorState extends AssignAreaEvent{
|
||||
final String message;
|
||||
const CallErrorState({required this.message});
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
|
@ -17,6 +17,8 @@ class AssignedAreaLoadedState extends AssignAreaState{
|
|||
class AssignAreaErorState extends AssignAreaState {
|
||||
final String message;
|
||||
const AssignAreaErorState({required this.message});
|
||||
@override
|
||||
List<Object> get props => [message];
|
||||
}
|
||||
class AssignAreaLoadingState extends AssignAreaState{
|
||||
|
||||
|
@ -26,3 +28,9 @@ class UserNotExistError extends AssignAreaState{
|
|||
|
||||
}
|
||||
class AssignAreaInitial extends AssignAreaState {}
|
||||
class AssignedAreaDeletedState extends AssignAreaState{
|
||||
final bool success;
|
||||
const AssignedAreaDeletedState({required this.success});
|
||||
@override
|
||||
List<Object> get props => [success];
|
||||
}
|
|
@ -30,7 +30,7 @@ class RoleAssignmentBloc
|
|||
lname = profile!.lastName;
|
||||
fullname = "${fname!} ${lname!}";
|
||||
assignedRoles = await RbacRoleAssignmentServices.instance
|
||||
.getAssignedRoles(firstname: fname!, lastname: lname!);
|
||||
.getAssignedRoles(firstname: event.firstname, lastname: event.lastname);
|
||||
|
||||
if (roles.isEmpty) {
|
||||
roles = await RbacRoleServices.instance.getRbacRoles();
|
||||
|
|
|
@ -40,6 +40,8 @@ class UserBloc extends Bloc<UserEvent, UserState> {
|
|||
final String? saved = CREDENTIALS?.get('saved');
|
||||
username = CREDENTIALS?.get('username');
|
||||
password = CREDENTIALS?.get('password');
|
||||
print(username);
|
||||
print(password);
|
||||
if (saved != null) {
|
||||
save = true;
|
||||
add(UserLogin(username: username, password: password));
|
||||
|
|
|
@ -36,7 +36,7 @@ class MyApp extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
_appRouter = AppRouter();
|
||||
final mediaQueryData =
|
||||
MediaQueryData.fromWindow(WidgetsBinding.instance.window);
|
||||
MediaQueryData.fromView(WidgetsBinding.instance.window);
|
||||
screenWidth = mediaQueryData.size.width;
|
||||
screenHeight = mediaQueryData.size.height;
|
||||
blockSizeHorizontal = screenWidth / 100;
|
||||
|
|
|
@ -3,27 +3,23 @@ import 'package:unit2/model/rbac/rbac.dart';
|
|||
import '../roles/pass_check/assign_role_area_type.dart';
|
||||
|
||||
class UserAssignedArea {
|
||||
final int id;
|
||||
final AssignedRole? assignedRole;
|
||||
final AssignRoleAreaType? assignedRoleAreaType;
|
||||
final dynamic assignedArea;
|
||||
|
||||
UserAssignedArea({
|
||||
required this.id,
|
||||
required this.assignedRole,
|
||||
required this.assignedRoleAreaType,
|
||||
required this.assignedArea,
|
||||
});
|
||||
|
||||
factory UserAssignedArea.fromJson(Map<String, dynamic> json) => UserAssignedArea(
|
||||
id: json["id"],
|
||||
assignedRole: json['assigned_role'] == null? null: AssignedRole.fromJson(json["assigned_role"]),
|
||||
assignedRoleAreaType: json['assigned_role_area_type'] == null? null : AssignRoleAreaType.fromJson(json["assigned_role_area_type"]),
|
||||
assignedArea: json["assigned_area"],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
"id": id,
|
||||
"assigned_role": assignedRole?.toJson(),
|
||||
"assigned_role_area_type": assignedRoleAreaType?.toJson(),
|
||||
"assigned_area": assignedArea,
|
||||
|
|
|
@ -87,13 +87,13 @@ class CreatedBy {
|
|||
|
||||
class Role {
|
||||
final int id;
|
||||
final String name;
|
||||
final String slug;
|
||||
final String shorthand;
|
||||
final DateTime createdAt;
|
||||
final DateTime updatedAt;
|
||||
final CreatedBy createdBy;
|
||||
final CreatedBy updatedBy;
|
||||
final String? name;
|
||||
final String? slug;
|
||||
final String? shorthand;
|
||||
final DateTime? createdAt;
|
||||
final DateTime? updatedAt;
|
||||
final CreatedBy? createdBy;
|
||||
final CreatedBy? updatedBy;
|
||||
|
||||
Role({
|
||||
required this.id,
|
||||
|
@ -111,10 +111,10 @@ class Role {
|
|||
name: json["name"],
|
||||
slug: json["slug"],
|
||||
shorthand: json["shorthand"],
|
||||
createdAt: DateTime.parse(json["created_at"]),
|
||||
updatedAt: DateTime.parse(json["updated_at"]),
|
||||
createdBy: CreatedBy.fromJson(json["created_by"]),
|
||||
updatedBy: CreatedBy.fromJson(json["updated_by"]),
|
||||
createdAt:json["created_at"] ==null?null: DateTime.parse(json["created_at"]),
|
||||
updatedAt:json["updated_at"] == null?null: DateTime.parse(json["updated_at"]),
|
||||
createdBy:json["created_by"] == null?null: CreatedBy.fromJson(json["created_by"]),
|
||||
updatedBy:json["updated_by"] == null?null: CreatedBy.fromJson(json["updated_by"]),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
|
@ -122,9 +122,9 @@ class Role {
|
|||
"name": name,
|
||||
"slug": slug,
|
||||
"shorthand": shorthand,
|
||||
"created_at": createdAt.toIso8601String(),
|
||||
"updated_at": updatedAt.toIso8601String(),
|
||||
"created_by": createdBy.toJson(),
|
||||
"updated_by": updatedBy.toJson(),
|
||||
"created_at": createdAt?.toIso8601String(),
|
||||
"updated_at": updatedAt?.toIso8601String(),
|
||||
"created_by": createdBy?.toJson(),
|
||||
"updated_by": updatedBy?.toJson(),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ class EditBasicProfileInfoScreen extends StatefulWidget {
|
|||
State<EditBasicProfileInfoScreen> createState() =>
|
||||
_EditBasicProfileInfoScreenState();
|
||||
}
|
||||
|
||||
final bdayController = TextEditingController();
|
||||
ProfileOtherInfo? selectedIndigency;
|
||||
ProfileOtherInfo? selectedEthnicity;
|
||||
|
@ -36,13 +37,13 @@ String? selectedStatus;
|
|||
String? selectedExtension;
|
||||
final _formKey = GlobalKey<FormBuilderState>();
|
||||
|
||||
|
||||
class _EditBasicProfileInfoScreenState
|
||||
extends State<EditBasicProfileInfoScreen> {
|
||||
@override
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ProfileBloc, ProfileState>(
|
||||
|
@ -52,7 +53,8 @@ class _EditBasicProfileInfoScreenState
|
|||
selectedSex = state.sexes.firstWhere((element) =>
|
||||
element.toLowerCase() ==
|
||||
state.primaryInformation.sex!.toLowerCase());
|
||||
if (state.primaryInformation.bloodType != null && state.primaryInformation.bloodType != "N/A") {
|
||||
if (state.primaryInformation.bloodType != null &&
|
||||
state.primaryInformation.bloodType != "N/A") {
|
||||
selectedBloodType = state.bloodTypes.firstWhere((element) =>
|
||||
element.toLowerCase() ==
|
||||
state.primaryInformation.bloodType?.toLowerCase());
|
||||
|
@ -99,9 +101,6 @@ class _EditBasicProfileInfoScreenState
|
|||
state.primaryInformation.disability!.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 32),
|
||||
child: FormBuilder(
|
||||
|
@ -116,9 +115,7 @@ class _EditBasicProfileInfoScreenState
|
|||
),
|
||||
FormBuilderTextField(
|
||||
name: "lastname",
|
||||
inputFormatters: [
|
||||
UpperCaseTextFormatter()
|
||||
],
|
||||
inputFormatters: [UpperCaseTextFormatter()],
|
||||
initialValue: state.primaryInformation.lastName,
|
||||
decoration: normalTextFieldStyle("Last name *", ""),
|
||||
validator: FormBuilderValidators.required(
|
||||
|
@ -129,9 +126,7 @@ class _EditBasicProfileInfoScreenState
|
|||
),
|
||||
FormBuilderTextField(
|
||||
name: "firstname",
|
||||
inputFormatters: [
|
||||
UpperCaseTextFormatter()
|
||||
],
|
||||
inputFormatters: [UpperCaseTextFormatter()],
|
||||
initialValue: state.primaryInformation.firstName,
|
||||
decoration: normalTextFieldStyle("First name *", ""),
|
||||
validator: FormBuilderValidators.required(
|
||||
|
@ -146,12 +141,12 @@ class _EditBasicProfileInfoScreenState
|
|||
Flexible(
|
||||
flex: 2,
|
||||
child: FormBuilderTextField(
|
||||
inputFormatters: [
|
||||
UpperCaseTextFormatter()
|
||||
],
|
||||
inputFormatters: [UpperCaseTextFormatter()],
|
||||
name: "middlename",
|
||||
initialValue: state.primaryInformation.middleName??'',
|
||||
decoration: normalTextFieldStyle("Middle name", ""),
|
||||
initialValue:
|
||||
state.primaryInformation.middleName ?? '',
|
||||
decoration:
|
||||
normalTextFieldStyle("Middle name", ""),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
|
@ -164,13 +159,11 @@ class _EditBasicProfileInfoScreenState
|
|||
value: selectedExtension,
|
||||
decoration:
|
||||
normalTextFieldStyle("Name Extension", ""),
|
||||
|
||||
items: state.extensions
|
||||
.map((element) => DropdownMenuItem<String>(
|
||||
value: element, child: Text(element)))
|
||||
.toList(),
|
||||
onChanged: (e) {
|
||||
|
||||
selectedExtension = e;
|
||||
},
|
||||
),
|
||||
|
@ -193,8 +186,9 @@ class _EditBasicProfileInfoScreenState
|
|||
errorText: "This field is required"),
|
||||
timeHintText: "Birthdate",
|
||||
decoration:
|
||||
normalTextFieldStyle("Birthdate *", "*").copyWith(
|
||||
prefixIcon: const Icon(
|
||||
normalTextFieldStyle("Birthdate *", "*")
|
||||
.copyWith(
|
||||
prefixIcon: const Icon(
|
||||
Icons.date_range,
|
||||
color: Colors.black87,
|
||||
)),
|
||||
|
@ -206,7 +200,7 @@ class _EditBasicProfileInfoScreenState
|
|||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
|
||||
|
||||
////sex
|
||||
Flexible(
|
||||
flex: 1,
|
||||
|
@ -221,7 +215,7 @@ class _EditBasicProfileInfoScreenState
|
|||
value: element, child: Text(element)))
|
||||
.toList(),
|
||||
onChanged: (e) {
|
||||
selectedSex= e;
|
||||
selectedSex = e;
|
||||
},
|
||||
),
|
||||
)
|
||||
|
@ -238,9 +232,10 @@ class _EditBasicProfileInfoScreenState
|
|||
flex: 1,
|
||||
child: FormBuilderDropdown<String>(
|
||||
initialValue: selectedBloodType,
|
||||
validator: FormBuilderValidators.required(
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
decoration: normalTextFieldStyle("Blood type *", ""),
|
||||
decoration:
|
||||
normalTextFieldStyle("Blood type *", ""),
|
||||
name: "bloodtype",
|
||||
items: state.bloodTypes
|
||||
.map((element) => DropdownMenuItem<String>(
|
||||
|
@ -259,8 +254,9 @@ class _EditBasicProfileInfoScreenState
|
|||
flex: 1,
|
||||
child: FormBuilderDropdown<String>(
|
||||
initialValue: selectedStatus,
|
||||
decoration: normalTextFieldStyle("Civil status *", ""),
|
||||
validator: FormBuilderValidators.required(
|
||||
decoration:
|
||||
normalTextFieldStyle("Civil status *", ""),
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: "This field is required"),
|
||||
name: "extension",
|
||||
items: state.civilStatus
|
||||
|
@ -305,11 +301,12 @@ class _EditBasicProfileInfoScreenState
|
|||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: "height",
|
||||
validator: numericRequired,
|
||||
validator: numericRequired,
|
||||
initialValue: state.primaryInformation.heightM
|
||||
.toString()
|
||||
.toString(),
|
||||
decoration: normalTextFieldStyle("Height (Meter) *", ""),
|
||||
decoration: normalTextFieldStyle(
|
||||
"Height (Meter) *", ""),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
|
@ -317,13 +314,13 @@ class _EditBasicProfileInfoScreenState
|
|||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
|
||||
child: FormBuilderTextField(
|
||||
validator: numericRequired,
|
||||
validator: numericRequired,
|
||||
name: "weigth",
|
||||
initialValue:
|
||||
state.primaryInformation.weightKg!.toString(),
|
||||
decoration: normalTextFieldStyle("Weight (Kg) *", ""),
|
||||
initialValue: state.primaryInformation.weightKg!
|
||||
.toString(),
|
||||
decoration:
|
||||
normalTextFieldStyle("Weight (Kg) *", ""),
|
||||
),
|
||||
),
|
||||
]),
|
||||
|
@ -338,7 +335,8 @@ class _EditBasicProfileInfoScreenState
|
|||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: "prefix",
|
||||
initialValue: state.primaryInformation.titlePrefix
|
||||
initialValue: state
|
||||
.primaryInformation.titlePrefix
|
||||
.toString()
|
||||
.toString(),
|
||||
decoration: normalTextFieldStyle(
|
||||
|
@ -352,7 +350,8 @@ class _EditBasicProfileInfoScreenState
|
|||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
name: "suffix",
|
||||
initialValue: state.primaryInformation.titleSuffix,
|
||||
initialValue:
|
||||
state.primaryInformation.titleSuffix,
|
||||
decoration: normalTextFieldStyle(
|
||||
"Title Suffix", "PhD.,MD.,MS.,CE"),
|
||||
),
|
||||
|
@ -368,10 +367,11 @@ class _EditBasicProfileInfoScreenState
|
|||
////Indigency
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: DropdownButtonFormField<ProfileOtherInfo>(
|
||||
child: DropdownButtonFormField<ProfileOtherInfo>(
|
||||
isExpanded: true,
|
||||
value: selectedIndigency,
|
||||
decoration: normalTextFieldStyle("Indigency", ""),
|
||||
decoration:
|
||||
normalTextFieldStyle("Indigency", ""),
|
||||
items: state.indigenous
|
||||
.map((element) =>
|
||||
DropdownMenuItem<ProfileOtherInfo>(
|
||||
|
@ -392,7 +392,8 @@ class _EditBasicProfileInfoScreenState
|
|||
child: DropdownButtonFormField<ProfileOtherInfo>(
|
||||
isExpanded: true,
|
||||
value: selectedEthnicity,
|
||||
decoration: normalTextFieldStyle("Ethnicity", ""),
|
||||
decoration:
|
||||
normalTextFieldStyle("Ethnicity", ""),
|
||||
items: state.ethnicity
|
||||
.map((element) =>
|
||||
DropdownMenuItem<ProfileOtherInfo>(
|
||||
|
@ -402,8 +403,7 @@ class _EditBasicProfileInfoScreenState
|
|||
onChanged: (e) {
|
||||
selectedEthnicity = e;
|
||||
print(selectedEthnicity!.name);
|
||||
print(selectedEthnicity!
|
||||
.id);
|
||||
print(selectedEthnicity!.id);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
@ -421,7 +421,8 @@ class _EditBasicProfileInfoScreenState
|
|||
child: DropdownButtonFormField<ProfileOtherInfo>(
|
||||
isExpanded: true,
|
||||
value: selectedReligion,
|
||||
decoration: normalTextFieldStyle("Religion", ""),
|
||||
decoration:
|
||||
normalTextFieldStyle("Religion", ""),
|
||||
items: state.religion
|
||||
.map((element) =>
|
||||
DropdownMenuItem<ProfileOtherInfo>(
|
||||
|
@ -440,10 +441,10 @@ class _EditBasicProfileInfoScreenState
|
|||
Flexible(
|
||||
flex: 1,
|
||||
child: DropdownButtonFormField<ProfileOtherInfo>(
|
||||
|
||||
isExpanded: true,
|
||||
value: selectedDisability,
|
||||
decoration: normalTextFieldStyle("Disability", ""),
|
||||
decoration:
|
||||
normalTextFieldStyle("Disability", ""),
|
||||
items: state.disability
|
||||
.map((element) =>
|
||||
DropdownMenuItem<ProfileOtherInfo>(
|
||||
|
@ -464,33 +465,36 @@ class _EditBasicProfileInfoScreenState
|
|||
width: double.infinity,
|
||||
height: 60,
|
||||
child: ElevatedButton(
|
||||
style:
|
||||
mainBtnStyle(primary, Colors.transparent, second),
|
||||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
if (_formKey.currentState!.saveAndValidate()) {
|
||||
String lastName =
|
||||
_formKey.currentState!.value['lastname'];
|
||||
String firstName =
|
||||
_formKey.currentState!.value['firstname'];
|
||||
String? middleName =
|
||||
_formKey.currentState?.value['middlename'];
|
||||
String? middleName = _formKey
|
||||
.currentState?.value['middlename'];
|
||||
String? pref =
|
||||
_formKey.currentState?.value['prefix'];
|
||||
String suf = _formKey.currentState?.value['suffix'];
|
||||
String suf =
|
||||
_formKey.currentState?.value['suffix'];
|
||||
DateTime birthdate =
|
||||
DateTime.parse(bdayController.text);
|
||||
double? hM =
|
||||
_formKey.currentState!.value['height'] == null
|
||||
_formKey.currentState!.value['height'] ==
|
||||
null
|
||||
? null
|
||||
: double.tryParse(
|
||||
_formKey.currentState?.value['height']);
|
||||
: double.tryParse(_formKey
|
||||
.currentState?.value['height']);
|
||||
double? wKg =
|
||||
_formKey.currentState!.value['weigth'] == null
|
||||
_formKey.currentState!.value['weigth'] ==
|
||||
null
|
||||
? null
|
||||
: double.tryParse(
|
||||
_formKey.currentState?.value['weigth']);
|
||||
: double.tryParse(_formKey
|
||||
.currentState?.value['weigth']);
|
||||
Profile primaryInformation = Profile(
|
||||
webuserId: null,
|
||||
webuserId: null,
|
||||
id: state.primaryInformation.id,
|
||||
lastName: lastName,
|
||||
firstName: firstName,
|
||||
|
@ -499,14 +503,21 @@ class _EditBasicProfileInfoScreenState
|
|||
sex: selectedSex,
|
||||
birthdate: birthdate,
|
||||
civilStatus: selectedStatus,
|
||||
bloodType: selectedBloodType =="NONE"?null:selectedBloodType,
|
||||
bloodType: selectedBloodType == "NONE"
|
||||
? null
|
||||
: selectedBloodType,
|
||||
heightM: hM,
|
||||
weightKg: wKg,
|
||||
photoPath: state.primaryInformation.photoPath,
|
||||
esigPath: state.primaryInformation.esigPath,
|
||||
maidenName: state.primaryInformation.maidenName,
|
||||
deceased: state.primaryInformation.deceased,
|
||||
uuidQrcode: state.primaryInformation.uuidQrcode,
|
||||
photoPath:
|
||||
state.primaryInformation.photoPath,
|
||||
esigPath:
|
||||
state.primaryInformation.esigPath,
|
||||
maidenName:
|
||||
state.primaryInformation.maidenName,
|
||||
deceased:
|
||||
state.primaryInformation.deceased,
|
||||
uuidQrcode:
|
||||
state.primaryInformation.uuidQrcode,
|
||||
titlePrefix: pref,
|
||||
titleSuffix: suf,
|
||||
showTitleId:
|
||||
|
@ -525,7 +536,8 @@ class _EditBasicProfileInfoScreenState
|
|||
genderId: selectedGender?.id,
|
||||
indigencyId: selectedIndigency?.id,
|
||||
profileId: widget.profileId,
|
||||
profileInformation: primaryInformation,
|
||||
profileInformation:
|
||||
primaryInformation,
|
||||
religionId: selectedReligion?.id,
|
||||
token: widget.token));
|
||||
}
|
||||
|
@ -540,7 +552,7 @@ class _EditBasicProfileInfoScreenState
|
|||
),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
|
@ -6,6 +5,8 @@ import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
|||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:unit2/bloc/profile/profile_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/model/profile/basic_information/primary-information.dart';
|
||||
import 'package:unit2/screens/profile/components/basic_information/edit_basic_info_modal.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/theme-data.dart/form-style.dart';
|
||||
|
@ -30,6 +31,7 @@ class _PrimaryInfoState extends State<PrimaryInfo> {
|
|||
Widget build(BuildContext context) {
|
||||
bool enabled = false;
|
||||
DateFormat dteFormat2 = DateFormat.yMMMMd('en_US');
|
||||
Profile? profile;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: context.watch<ProfileBloc>().state
|
||||
|
@ -62,300 +64,421 @@ class _PrimaryInfoState extends State<PrimaryInfo> {
|
|||
padding: const EdgeInsets.all(24),
|
||||
backgroundColor: Colors.black87,
|
||||
indicatorWidget: const SpinKitFadingCircle(color: Colors.white),
|
||||
child: BlocConsumer<ProfileBloc, ProfileState>(
|
||||
listener: (context, state) {
|
||||
if (state is BasicPrimaryInformationLoadingState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
if (state is BasicInformationProfileLoaded ||
|
||||
state is BasicInformationEditingState ||
|
||||
state is BasicPrimaryInformationErrorState ||
|
||||
state is BasicProfileInfoEditedState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
if (state is BasicProfileInfoEditedState) {
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Updated Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context.read<ProfileBloc>().add(LoadBasicPrimaryInfo());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Update Failed",
|
||||
"Something went wrong. Please try again.", () {
|
||||
Navigator.of(context).pop();
|
||||
context.read<ProfileBloc>().add(LoadBasicPrimaryInfo());
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
child: BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
if (state is BasicInformationProfileLoaded) {
|
||||
return Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 24, horizontal: 24),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 28,
|
||||
),
|
||||
FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: lastname,
|
||||
initialValue: state.primaryBasicInformation.lastName!,
|
||||
decoration: normalTextFieldStyle("Last name", ""),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: firstname,
|
||||
initialValue: state.primaryBasicInformation.firstName!,
|
||||
decoration: normalTextFieldStyle("First name", ""),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: middlename,
|
||||
initialValue: state.primaryBasicInformation.middleName??''
|
||||
,
|
||||
decoration:
|
||||
normalTextFieldStyle("Middle name", ""),
|
||||
if (state is UserLoggedIn) {
|
||||
state.userData?.employeeInfo?.profile = profile;
|
||||
return BlocConsumer<ProfileBloc, ProfileState>(
|
||||
listener: (context, state) {
|
||||
if (state is BasicPrimaryInformationLoadingState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
if (state is BasicInformationProfileLoaded ||
|
||||
state is BasicInformationEditingState ||
|
||||
state is BasicPrimaryInformationErrorState ||
|
||||
state is BasicProfileInfoEditedState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
if (state is BasicProfileInfoEditedState) {
|
||||
profile = Profile.fromJson(state.response['data']);
|
||||
if (state.response['success']) {
|
||||
successAlert(context, "Updated Successfull!",
|
||||
state.response['message'], () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<ProfileBloc>()
|
||||
.add(LoadBasicPrimaryInfo());
|
||||
});
|
||||
} else {
|
||||
errorAlert(context, "Update Failed",
|
||||
"Something went wrong. Please try again.", () {
|
||||
Navigator.of(context).pop();
|
||||
context
|
||||
.read<ProfileBloc>()
|
||||
.add(LoadBasicPrimaryInfo());
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is BasicInformationProfileLoaded) {
|
||||
profile = state.primaryBasicInformation;
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 24, horizontal: 24),
|
||||
child: Column(
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 28,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: extensionName,
|
||||
initialValue: state.primaryBasicInformation
|
||||
.nameExtension ??= 'N/A',
|
||||
decoration:
|
||||
normalTextFieldStyle("Name extension", ""),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: extensionName,
|
||||
initialValue: dteFormat2.format(
|
||||
state.primaryBasicInformation.birthdate!),
|
||||
decoration:
|
||||
normalTextFieldStyle("Birth date", ""),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: sex,
|
||||
initialValue: state.primaryBasicInformation.sex!,
|
||||
decoration: normalTextFieldStyle("Sex", ""),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: "bloodType",
|
||||
FormBuilderTextField(
|
||||
enabled: false,
|
||||
name: lastname,
|
||||
initialValue:
|
||||
state.primaryBasicInformation.bloodType!,
|
||||
decoration:
|
||||
normalTextFieldStyle("Blood type", ""),
|
||||
state.primaryBasicInformation.lastName!,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: normalTextFieldStyle("Last name", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle:
|
||||
const TextStyle(color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: "civilStatus",
|
||||
name: firstname,
|
||||
initialValue:
|
||||
state.primaryBasicInformation.civilStatus!,
|
||||
decoration:
|
||||
normalTextFieldStyle("Civil Status", ""),
|
||||
state.primaryBasicInformation.firstName!,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: normalTextFieldStyle("First name", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle:
|
||||
const TextStyle(color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: "gender",
|
||||
initialValue: state
|
||||
.primaryBasicInformation.gender ??= "N/A",
|
||||
decoration: normalTextFieldStyle("Gender", ""),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
maxLines: 2,
|
||||
enabled: enabled,
|
||||
name: height,
|
||||
initialValue: state
|
||||
.primaryBasicInformation.heightM!
|
||||
.toString(),
|
||||
decoration: normalTextFieldStyle("Height", ""),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 2,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: middlename,
|
||||
initialValue: state.primaryBasicInformation
|
||||
.middleName ??
|
||||
'',
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Middle name", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: extensionName,
|
||||
initialValue: state.primaryBasicInformation
|
||||
.nameExtension ??= 'N/A',
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: normalTextFieldStyle(
|
||||
"Name extension", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: width,
|
||||
initialValue: state
|
||||
.primaryBasicInformation.weightKg!
|
||||
.toString(),
|
||||
decoration: normalTextFieldStyle("Weight", ""),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: prefixSuffix,
|
||||
initialValue:
|
||||
"${state.primaryBasicInformation.titlePrefix ??= "NA"} | ${state.primaryBasicInformation.titleSuffix ??= "N/A"}",
|
||||
decoration: normalTextFieldStyle(
|
||||
"Title Prefix and Suffix", ""),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: extensionName,
|
||||
initialValue: dteFormat2.format(state
|
||||
.primaryBasicInformation.birthdate!),
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Birth date", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: sex,
|
||||
initialValue:
|
||||
state.primaryBasicInformation.sex!,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: normalTextFieldStyle("Sex", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
maxLines: 2,
|
||||
enabled: enabled,
|
||||
name: height,
|
||||
initialValue: state.primaryBasicInformation.ip ??=
|
||||
"N/A",
|
||||
decoration:
|
||||
normalTextFieldStyle("Indigenous", ""),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: width,
|
||||
initialValue: state
|
||||
.primaryBasicInformation.ethnicity ??= "N/A",
|
||||
decoration: normalTextFieldStyle("Ethnicity", ""),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: "bloodType",
|
||||
initialValue: state
|
||||
.primaryBasicInformation.bloodType!,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Blood type", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: "civilStatus",
|
||||
initialValue: state
|
||||
.primaryBasicInformation.civilStatus!,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Civil Status", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: "gender",
|
||||
initialValue: state.primaryBasicInformation
|
||||
.gender ??= "N/A",
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Gender", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
maxLines: 2,
|
||||
enabled: enabled,
|
||||
name: height,
|
||||
initialValue: state
|
||||
.primaryBasicInformation.religion ??= "N/A",
|
||||
decoration: normalTextFieldStyle("Religion", ""),
|
||||
const SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
maxLines: 2,
|
||||
enabled: enabled,
|
||||
name: width,
|
||||
initialValue: state
|
||||
.primaryBasicInformation.disability ??= "N/A",
|
||||
decoration:
|
||||
normalTextFieldStyle("Disability", ""),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
maxLines: 2,
|
||||
enabled: enabled,
|
||||
name: height,
|
||||
initialValue: state
|
||||
.primaryBasicInformation.heightM!
|
||||
.toString(),
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Height", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: width,
|
||||
initialValue: state
|
||||
.primaryBasicInformation.weightKg!
|
||||
.toString(),
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Weight", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: prefixSuffix,
|
||||
initialValue:
|
||||
"${state.primaryBasicInformation.titlePrefix ??= "NA"} | ${state.primaryBasicInformation.titleSuffix ??= "N/A"}",
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration: normalTextFieldStyle(
|
||||
"Title Prefix and Suffix", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
maxLines: 2,
|
||||
enabled: enabled,
|
||||
name: height,
|
||||
initialValue: state
|
||||
.primaryBasicInformation.ip ??= "N/A",
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Indigenous", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
enabled: enabled,
|
||||
name: width,
|
||||
initialValue: state.primaryBasicInformation
|
||||
.ethnicity ??= "N/A",
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Ethnicity", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
width: screenWidth,
|
||||
child: Row(children: [
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
maxLines: 2,
|
||||
enabled: enabled,
|
||||
name: height,
|
||||
initialValue: state.primaryBasicInformation
|
||||
.religion ??= "N/A",
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Religion", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Flexible(
|
||||
flex: 1,
|
||||
child: FormBuilderTextField(
|
||||
maxLines: 2,
|
||||
enabled: enabled,
|
||||
name: width,
|
||||
initialValue: state.primaryBasicInformation
|
||||
.disability ??= "N/A",
|
||||
style: const TextStyle(color: Colors.black),
|
||||
decoration:
|
||||
normalTextFieldStyle("Disability", "")
|
||||
.copyWith(
|
||||
disabledBorder:
|
||||
const OutlineInputBorder(),
|
||||
labelStyle: const TextStyle(
|
||||
color: Colors.black)),
|
||||
),
|
||||
),
|
||||
]),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
if (state is BasicPrimaryInformationErrorState) {
|
||||
return SomethingWentWrong(
|
||||
message: state.message,
|
||||
onpressed: () {
|
||||
context
|
||||
.read<ProfileBloc>()
|
||||
.add(LoadBasicPrimaryInfo());
|
||||
});
|
||||
}
|
||||
if (state is BasicInformationEditingState) {
|
||||
return EditBasicProfileInfoScreen(
|
||||
profileId: widget.profileId, token: widget.token);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
}
|
||||
if (state is BasicPrimaryInformationErrorState) {
|
||||
return SomethingWentWrong(
|
||||
message: state.message,
|
||||
onpressed: () {
|
||||
context.read<ProfileBloc>().add(LoadBasicPrimaryInfo());
|
||||
});
|
||||
}
|
||||
if (state is BasicInformationEditingState) {
|
||||
return EditBasicProfileInfoScreen(
|
||||
profileId: widget.profileId, token: widget.token);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
|
|
|
@ -70,7 +70,6 @@ class ProfileInfo extends StatelessWidget {
|
|||
profileId = state.userData!.user!.login!.user!.profileId;
|
||||
token = state.userData!.user!.login!.token!;
|
||||
profile = state.userData!.employeeInfo!.profile!;
|
||||
|
||||
return BlocConsumer<ProfileBloc, ProfileState>(
|
||||
listener: (
|
||||
context,
|
||||
|
|
|
@ -1,12 +1,422 @@
|
|||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/src/widgets/framework.dart';
|
||||
import 'package:flutter/src/widgets/placeholder.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:fluttericon/font_awesome5_icons.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
import 'package:group_list_view/group_list_view.dart';
|
||||
import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart';
|
||||
import 'package:searchfield/searchfield.dart';
|
||||
import 'package:unit2/bloc/rbac/rbac_operations/assign_area/assign_area_bloc.dart';
|
||||
import 'package:unit2/bloc/user/user_bloc.dart';
|
||||
import 'package:unit2/model/login_data/user_info/assigned_area.dart';
|
||||
import 'package:unit2/model/profile/assigned_area.dart';
|
||||
import 'package:unit2/model/rbac/rbac.dart';
|
||||
import 'package:unit2/model/utils/agency.dart';
|
||||
import 'package:unit2/theme-data.dart/btn-style.dart';
|
||||
import 'package:unit2/theme-data.dart/colors.dart';
|
||||
import 'package:unit2/theme-data.dart/form-style.dart';
|
||||
import 'package:unit2/utils/alerts.dart';
|
||||
import 'package:unit2/utils/formatters.dart';
|
||||
import 'package:unit2/utils/global_context.dart';
|
||||
import 'package:unit2/utils/profile_utilities.dart';
|
||||
import 'package:unit2/widgets/Leadings/add_leading.dart';
|
||||
import 'package:unit2/widgets/empty_data.dart';
|
||||
|
||||
class RbacAssignedAreaScreen extends StatelessWidget {
|
||||
const RbacAssignedAreaScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(child: Text("dsadasdas"),);
|
||||
Map<String, List<Content>> assignedAreas = {};
|
||||
final formKey = GlobalKey<FormBuilderState>();
|
||||
List<RBAC> roles = [];
|
||||
bool async = false;
|
||||
List<UserAssignedArea> userAssignedAreas = [];
|
||||
final bloc = BlocProvider.of<AssignAreaBloc>(context);
|
||||
RBAC? selectedRole;
|
||||
String? areaType;
|
||||
List<Agency> agencies = [];
|
||||
FocusNode agencyFocusNode = FocusNode();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: primary,
|
||||
centerTitle: true,
|
||||
title: const Text("Assigned Area"),
|
||||
actions: [
|
||||
AddLeading(onPressed: () {
|
||||
roles.clear();
|
||||
for (var area in userAssignedAreas) {
|
||||
roles.add(area.assignedRole!.role!);
|
||||
}
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: const Text("Add New Role"),
|
||||
content: FormBuilder(
|
||||
key: formKey,
|
||||
child: StatefulBuilder(builder: (context, setState) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
FormBuilderDropdown<RBAC>(
|
||||
decoration: normalTextFieldStyle(
|
||||
"Select Role", "Select Role"),
|
||||
name: 'role',
|
||||
items: roles.map<DropdownMenuItem<RBAC>>((e) {
|
||||
return DropdownMenuItem(
|
||||
value: e,
|
||||
child: Text(e.name!),
|
||||
onTap: () async {
|
||||
setState(() {
|
||||
async = true;
|
||||
});
|
||||
//// barangay
|
||||
if (e.name!.toLowerCase() == "barangay chairperson" ||
|
||||
e.name!.toLowerCase() ==
|
||||
"barangay councilor" ||
|
||||
e.name!.toLowerCase() ==
|
||||
"barangay nurse" ||
|
||||
e.name!.toLowerCase() ==
|
||||
"health officer in-charge" ||
|
||||
e.name!.toLowerCase() ==
|
||||
"health monitoring in-charge" ||
|
||||
e.name!.toLowerCase() ==
|
||||
"health nurse") {
|
||||
////===========
|
||||
//// purok
|
||||
} else if (e.name!.toLowerCase() ==
|
||||
"purok president") {
|
||||
////===============
|
||||
//// station
|
||||
} else if (e.name!.toLowerCase() == "qr code scanner" ||
|
||||
e.name!.toLowerCase() ==
|
||||
"security guard" ||
|
||||
e.name!.toLowerCase() ==
|
||||
"checkpoint in-charge" ||
|
||||
e.name!.toLowerCase() ==
|
||||
'office/branch chief' ||
|
||||
e.name!.toLowerCase() ==
|
||||
"process server") {
|
||||
//// agency
|
||||
} else if (e.name!.toLowerCase() ==
|
||||
"establishment point-person" ||
|
||||
e.name!.toLowerCase() ==
|
||||
'registration in-charge' ||
|
||||
e.name!.toLowerCase() ==
|
||||
"provincial/city drrm officer in-charge") {
|
||||
try {
|
||||
areaType = "agency";
|
||||
agencies = await ProfileUtilities
|
||||
.instance
|
||||
.getAgecies();
|
||||
} catch (e) {
|
||||
bloc.add(CallErrorState(
|
||||
message: e.toString()));
|
||||
}
|
||||
setState(() {
|
||||
async = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
SizedBox(
|
||||
height: 75,
|
||||
width: double.maxFinite,
|
||||
child: ModalProgressHUD(
|
||||
inAsyncCall: async,
|
||||
child: SizedBox(
|
||||
child: areaType == "agency"
|
||||
? SearchField(
|
||||
inputFormatters: [
|
||||
UpperCaseTextFormatter()
|
||||
],
|
||||
focusNode: agencyFocusNode,
|
||||
itemHeight: 100,
|
||||
suggestions: agencies
|
||||
.map((Agency agency) =>
|
||||
SearchFieldListItem(
|
||||
agency.name!,
|
||||
item: agency,
|
||||
child: ListTile(
|
||||
title:
|
||||
AutoSizeText(
|
||||
agency.name!
|
||||
.toUpperCase(),
|
||||
minFontSize:
|
||||
12,
|
||||
),
|
||||
subtitle: Text(agency
|
||||
.privateEntity ==
|
||||
true
|
||||
? "Private"
|
||||
: agency.privateEntity ==
|
||||
false
|
||||
? "Government"
|
||||
: ""),
|
||||
)))
|
||||
.toList(),
|
||||
validator: FormBuilderValidators
|
||||
.required(
|
||||
errorText:
|
||||
"This field is required"),
|
||||
searchInputDecoration:
|
||||
normalTextFieldStyle(
|
||||
"Agency *", "")
|
||||
.copyWith(
|
||||
suffixIcon:
|
||||
GestureDetector(
|
||||
onTap: () => agencyFocusNode
|
||||
.unfocus(),
|
||||
child: const Icon(
|
||||
Icons.arrow_drop_down,
|
||||
),
|
||||
)),
|
||||
////agency suggestion tap
|
||||
onSuggestionTap: (agency) {
|
||||
setState(() {
|
||||
agencyFocusNode.unfocus();
|
||||
});
|
||||
},
|
||||
emptyWidget: const Text(
|
||||
"No Result Found.."))
|
||||
: areaType == "station"?Container():Container()))),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
height: 50,
|
||||
child: ElevatedButton(
|
||||
style: mainBtnStyle(
|
||||
primary, Colors.transparent, second),
|
||||
onPressed: () {
|
||||
if (formKey.currentState!
|
||||
.saveAndValidate()) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
},
|
||||
child: const Text("Add"))),
|
||||
],
|
||||
);
|
||||
}),
|
||||
));
|
||||
});
|
||||
})
|
||||
],
|
||||
),
|
||||
body: ProgressHUD(
|
||||
padding: const EdgeInsets.all(24),
|
||||
backgroundColor: Colors.black87,
|
||||
indicatorWidget: const SpinKitFadingCircle(color: Colors.white),
|
||||
child: BlocBuilder<UserBloc, UserState>(
|
||||
builder: (context, state) {
|
||||
if (state is UserLoggedIn) {
|
||||
return BlocConsumer<AssignAreaBloc, AssignAreaState>(
|
||||
listener: (context, state) {
|
||||
if (state is AssignAreaLoadingState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.showWithText("Please wait...");
|
||||
}
|
||||
if (state is AssignAreaErorState ||
|
||||
state is AssignedAreaLoadedState ||
|
||||
state is UserNotExistError ||
|
||||
state is AssignedAreaDeletedState) {
|
||||
final progress = ProgressHUD.of(context);
|
||||
progress!.dismiss();
|
||||
}
|
||||
|
||||
////Deleted State
|
||||
if (state is AssignedAreaDeletedState) {
|
||||
if (state.success) {
|
||||
successAlert(context, "Delete Successfull!",
|
||||
"Role Module Deleted Successfully", () {
|
||||
Navigator.of(context).pop();
|
||||
context.read<AssignAreaBloc>().add(LoadAssignedAreas());
|
||||
});
|
||||
} else {
|
||||
errorAlert(
|
||||
context, "Delete Failed", "Role Module Delete Failed",
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
context.read<AssignAreaBloc>().add(LoadAssignedAreas());
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is AssignedAreaLoadedState) {
|
||||
assignedAreas = {};
|
||||
userAssignedAreas = state.userAssignedAreas;
|
||||
if (state.userAssignedAreas.isNotEmpty) {
|
||||
for (var roleMod in state.userAssignedAreas) {
|
||||
assignedAreas.addAll({
|
||||
roleMod.assignedRole!.role!.name!.toLowerCase(): []
|
||||
});
|
||||
String areaType = roleMod
|
||||
.assignedRoleAreaType!.areaTypeName
|
||||
.toLowerCase();
|
||||
for (var area in roleMod.assignedArea) {
|
||||
if (areaType == 'baranggay') {
|
||||
assignedAreas[roleMod.assignedRole!.role!.name!
|
||||
.toLowerCase()]!
|
||||
.add(Content(
|
||||
id: area['id'],
|
||||
name: area['area']['brgydesc']));
|
||||
} else if (areaType == 'purok') {
|
||||
assignedAreas[roleMod.assignedRole!.role!.name!
|
||||
.toLowerCase()]!
|
||||
.add(Content(
|
||||
id: area['id'],
|
||||
name: area['area']['purokdesc']));
|
||||
} else if (areaType == 'station') {
|
||||
assignedAreas[roleMod.assignedRole!.role!.name!
|
||||
.toLowerCase()]!
|
||||
.add(Content(
|
||||
id: area['id'],
|
||||
name: area['area']["station_name"]));
|
||||
} else if (areaType == 'agency') {
|
||||
assignedAreas[roleMod.assignedRole!.role!.name!
|
||||
.toLowerCase()]!
|
||||
.add(Content(
|
||||
id: area['id'],
|
||||
name: area['area']['name']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state.userAssignedAreas.isNotEmpty) {
|
||||
return Column(
|
||||
children: [
|
||||
ListTile(
|
||||
tileColor: second,
|
||||
leading: const Icon(
|
||||
FontAwesome5.user_alt,
|
||||
color: Colors.white,
|
||||
),
|
||||
title: Text(state.fullname.toUpperCase(),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleLarge!
|
||||
.copyWith(color: Colors.white)),
|
||||
subtitle: Text("Person full name",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelLarge!
|
||||
.copyWith(color: Colors.white)),
|
||||
),
|
||||
Expanded(
|
||||
child: GroupListView(
|
||||
sectionsCount: assignedAreas.keys.toList().length,
|
||||
countOfItemInSection: (int section) {
|
||||
return assignedAreas.values
|
||||
.toList()[section]
|
||||
.length;
|
||||
},
|
||||
itemBuilder:
|
||||
(BuildContext context, IndexPath index) {
|
||||
return ListTile(
|
||||
dense: true,
|
||||
trailing: IconButton(
|
||||
color: Colors.grey.shade600,
|
||||
icon: const Icon(Icons.delete),
|
||||
onPressed: () {
|
||||
confirmAlert(context, () {
|
||||
context.read<AssignAreaBloc>().add(
|
||||
DeleteAssignedArea(
|
||||
areaId: assignedAreas.values
|
||||
.toList()[index.section]
|
||||
[index.index]
|
||||
.id));
|
||||
}, "Delete?", "Confirm Delete?");
|
||||
},
|
||||
),
|
||||
title: Row(
|
||||
children: [
|
||||
Text("${index.index + 1}",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelLarge!
|
||||
.copyWith(color: Colors.white)),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
assignedAreas.values
|
||||
.toList()[index.section]
|
||||
[index.index]
|
||||
.name
|
||||
.toUpperCase(),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.labelLarge!
|
||||
.copyWith(color: primary),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (context, index) {
|
||||
return const Divider();
|
||||
},
|
||||
groupHeaderBuilder:
|
||||
(BuildContext context, int section) {
|
||||
return ListTile(
|
||||
tileColor: Colors.white,
|
||||
title: Text(
|
||||
assignedAreas.keys
|
||||
.toList()[section]
|
||||
.toUpperCase(),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
color: primary,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return EmptyData(
|
||||
message:
|
||||
"No Assigned Area available for ${state.fullname}. Please click + to add.");
|
||||
}
|
||||
}
|
||||
if (state is AssignAreaErorState) {
|
||||
print("error state");
|
||||
}
|
||||
if (state is UserNotExistError) {
|
||||
return const Center(
|
||||
child: Text("User Not Exsit"),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Content {
|
||||
final int id;
|
||||
final String name;
|
||||
const Content({required this.id, required this.name});
|
||||
}
|
||||
|
|
|
@ -213,7 +213,7 @@ class RbacRoleAssignment extends StatelessWidget {
|
|||
Flexible(
|
||||
child: Text(
|
||||
state.assignedRoles[index].role!
|
||||
.name,
|
||||
.name!,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
|
@ -262,8 +262,8 @@ class RbacRoleAssignment extends StatelessWidget {
|
|||
],
|
||||
);
|
||||
} else {
|
||||
return const EmptyData(
|
||||
message: "No Role available. Please click + to add.");
|
||||
return EmptyData(
|
||||
message: "No Role available for ${state.fullname}. Please click + to add.");
|
||||
}
|
||||
}
|
||||
if (state is RoleAssignmentErrorState) {
|
||||
|
|
|
@ -76,9 +76,6 @@ class _DashBoardState extends State<DashBoard> {
|
|||
tempUnit2Cards = unit2Cards.sublist(0, 4);
|
||||
}
|
||||
|
||||
superadminCards.forEach((el) {
|
||||
print(el.object.name);
|
||||
});
|
||||
|
||||
return Container(
|
||||
padding:
|
||||
|
|
|
@ -209,6 +209,7 @@ class SuperAdminMenu extends StatelessWidget {
|
|||
);
|
||||
}));
|
||||
}
|
||||
////////////////////////////////
|
||||
if (object.object.name == 'Area') {
|
||||
Navigator.of(context).pop();
|
||||
showDialog(
|
||||
|
|
|
@ -393,7 +393,7 @@ class _UniT2LoginState extends State<UniT2Login> {
|
|||
},
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
return const UniTSplashScreen();
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -158,11 +158,11 @@ class EstPointPersonRoleAssignmentScreen extends StatelessWidget {
|
|||
if (!assignedRoles.keys.contains(fullName)) {
|
||||
assignedRoles.addAll({fullName: []});
|
||||
assignedRoles[fullName]!.add(Content(
|
||||
id: assignedRole.id!, name: assignedRole.role!.name));
|
||||
id: assignedRole.id!, name: assignedRole.role!.name!));
|
||||
} else {
|
||||
assignedRoles[fullName]!.add(Content(
|
||||
id: assignedRole.id!,
|
||||
name: assignedRole.role!.name));
|
||||
name: assignedRole.role!.name!));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,4 +39,23 @@ class RbacAssignedAreaServices {
|
|||
}
|
||||
return userAssignedAreas;
|
||||
}
|
||||
Future<bool> deleteAssignedArea({required int areaId}) async {
|
||||
bool success = false;
|
||||
String path = "${Url.instance.getAssignAreas()}$areaId/";
|
||||
Map<String, String> headers = {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
'X-Client-Key': xClientKey,
|
||||
'X-Client-Secret': xClientKeySecret
|
||||
};
|
||||
try {
|
||||
http.Response response = await Request.instance
|
||||
.deleteRequest(path: path, headers: headers, body: {}, param: {});
|
||||
if (response.statusCode == 200) {
|
||||
success = true;
|
||||
}
|
||||
} catch (e) {
|
||||
throw e.toString();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,8 @@ class Url {
|
|||
}
|
||||
|
||||
String prefixHost() {
|
||||
// return "https";
|
||||
return "http";
|
||||
return "https";
|
||||
// return "http";
|
||||
}
|
||||
|
||||
String authentication() {
|
||||
|
|
16
pubspec.lock
16
pubspec.lock
|
@ -25,6 +25,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
animated_splash_screen:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: animated_splash_screen
|
||||
sha256: f45634db6ec4e8cf034c53e03f3bd83898a16fe3c9286bf5510b6831dfcf2124
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
app_popup_menu:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -973,6 +981,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
page_transition:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: page_transition
|
||||
sha256: dee976b1f23de9bbef5cd512fe567e9f6278caee11f5eaca9a2115c19dc49ef6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -97,6 +97,7 @@ dependencies:
|
|||
url_launcher: ^6.1.11
|
||||
url_launcher_android: ^6.0.38
|
||||
share_plus: ^7.1.0
|
||||
animated_splash_screen: ^1.3.0
|
||||
|
||||
dependency_overrides:
|
||||
intl: ^0.18.0
|
||||
|
|
Loading…
Reference in New Issue