resolved the email and has application acccess is not populated on edit

This commit is contained in:
Vaibhav Surve 2025-10-01 16:59:15 +05:30
parent 843f394ebe
commit a1bd9a3108
4 changed files with 187 additions and 159 deletions

View File

@ -74,12 +74,17 @@ class _AddContactBottomSheetState extends State<AddContactBottomSheet> {
ever(controller.isInitialized, (bool ready) { ever(controller.isInitialized, (bool ready) {
if (ready) { if (ready) {
// Buckets - map all
if (c.bucketIds.isNotEmpty) {
final names = c.bucketIds.map((id) {
return controller.bucketsMap.entries
.firstWhereOrNull((e) => e.value == id)
?.key;
}).whereType<String>().toList();
controller.selectedBuckets.assignAll(names);
}
// Projects and Category mapping - as before
final projectIds = c.projectIds; final projectIds = c.projectIds;
final bucketId = c.bucketIds.firstOrNull;
final category = c.contactCategory?.name;
if (category != null) controller.selectedCategory.value = category;
if (projectIds != null) { if (projectIds != null) {
controller.selectedProjects.assignAll( controller.selectedProjects.assignAll(
projectIds projectIds
@ -90,24 +95,18 @@ class _AddContactBottomSheetState extends State<AddContactBottomSheet> {
.toList(), .toList(),
); );
} }
final category = c.contactCategory?.name;
if (bucketId != null) { if (category != null) controller.selectedCategory.value = category;
final name = controller.bucketsMap.entries
.firstWhereOrNull((e) => e.value == bucketId)
?.key;
if (name != null && !controller.selectedBuckets.contains(name)) {
controller.selectedBuckets.add(name);
}
}
} }
}); });
} else { } else {
showAdvanced.value = false; // Optional
emailCtrls.add(TextEditingController()); emailCtrls.add(TextEditingController());
emailLabels.add('Office'.obs); emailLabels.add('Office'.obs);
phoneCtrls.add(TextEditingController()); phoneCtrls.add(TextEditingController());
phoneLabels.add('Work'.obs); phoneLabels.add('Work'.obs);
} }
} }
@override @override
void dispose() { void dispose() {
@ -379,19 +378,15 @@ class _AddContactBottomSheetState extends State<AddContactBottomSheet> {
required List<FilterItem> items, required List<FilterItem> items,
required String fallback, required String fallback,
required RxList<String> selectedValues, required RxList<String> selectedValues,
}) { }) {
if (items.isEmpty) return const SizedBox.shrink(); if (items.isEmpty) return const SizedBox.shrink();
return Column( return Obx(() {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Obx(() {
final selectedNames = items final selectedNames = items
.where((f) => selectedValues.contains(f.id)) .where((f) => selectedValues.contains(f.id))
.map((f) => f.name) .map((f) => f.name)
.join(", "); .join(", ");
final displayText = final displayText = selectedNames.isNotEmpty ? selectedNames : fallback;
selectedNames.isNotEmpty ? selectedNames : fallback;
return Builder( return Builder(
builder: (context) { builder: (context) {
@ -399,10 +394,8 @@ class _AddContactBottomSheetState extends State<AddContactBottomSheet> {
onTap: () async { onTap: () async {
final RenderBox button = final RenderBox button =
context.findRenderObject() as RenderBox; context.findRenderObject() as RenderBox;
final RenderBox overlay = Overlay.of(context) final RenderBox overlay =
.context Overlay.of(context).context.findRenderObject() as RenderBox;
.findRenderObject() as RenderBox;
final position = button.localToGlobal(Offset.zero); final position = button.localToGlobal(Offset.zero);
await showMenu( await showMenu(
@ -413,30 +406,32 @@ class _AddContactBottomSheetState extends State<AddContactBottomSheet> {
overlay.size.width - position.dx - button.size.width, overlay.size.width - position.dx - button.size.width,
0, 0,
), ),
items: items.map((f) { items: [
return PopupMenuItem<String>( PopupMenuItem(
enabled: false, enabled: false,
child: StatefulBuilder( child: StatefulBuilder(
builder: (context, setState) { builder: (context, setState) {
return SizedBox(
width: 250,
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: items.map((f) {
final isChecked = selectedValues.contains(f.id); final isChecked = selectedValues.contains(f.id);
return CheckboxListTile( return CheckboxListTile(
dense: true, dense: true,
title: Text(f.name),
value: isChecked, value: isChecked,
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
controlAffinity: ListTileControlAffinity.leading, controlAffinity: ListTileControlAffinity.leading,
title: MyText(f.name), side: const BorderSide(color: Colors.black, width: 1.5),
checkColor: Colors.white, fillColor: MaterialStateProperty.resolveWith<Color>((states) {
side: const BorderSide(
color: Colors.black, width: 1.5),
fillColor:
MaterialStateProperty.resolveWith<Color>(
(states) {
if (states.contains(MaterialState.selected)) { if (states.contains(MaterialState.selected)) {
return Colors.indigo; return Colors.indigo; // selected color
} }
return Colors.white; return Colors.white; // unselected background
}, }),
), checkColor: Colors.white, // tick color
onChanged: (val) { onChanged: (val) {
if (val == true) { if (val == true) {
selectedValues.add(f.id); selectedValues.add(f.id);
@ -446,10 +441,14 @@ class _AddContactBottomSheetState extends State<AddContactBottomSheet> {
setState(() {}); setState(() {});
}, },
); );
}, }).toList(),
),
), ),
); );
}).toList(), },
),
),
],
); );
}, },
child: Container( child: Container(
@ -476,11 +475,9 @@ class _AddContactBottomSheetState extends State<AddContactBottomSheet> {
); );
}, },
); );
}), });
MySpacing.height(16), }
],
);
}
void _handleSubmit() { void _handleSubmit() {
bool valid = formKey.currentState?.validate() ?? false; bool valid = formKey.currentState?.validate() ?? false;

View File

@ -36,7 +36,7 @@ class _AddEmployeeBottomSheetState extends State<AddEmployeeBottomSheet>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_orgFieldController = TextEditingController();
_joiningDateController = TextEditingController(); _joiningDateController = TextEditingController();
_genderController = TextEditingController(); _genderController = TextEditingController();
_roleController = TextEditingController(); _roleController = TextEditingController();
@ -46,17 +46,33 @@ class _AddEmployeeBottomSheetState extends State<AddEmployeeBottomSheet>
if (widget.employeeData != null) { if (widget.employeeData != null) {
_controller.editingEmployeeData = widget.employeeData; _controller.editingEmployeeData = widget.employeeData;
_controller.prefillFields(); _controller.prefillFields();
// 👇 joining date & gender already handled in your code
// Prepopulate hasApplicationAccess and email
_hasApplicationAccess =
widget.employeeData?['hasApplicationAccess'] ?? false;
final email = widget.employeeData?['email'];
if (email != null && email.toString().isNotEmpty) {
_controller.basicValidator.getController('email')?.text =
email.toString();
}
// Trigger UI rebuild to reflect email & checkbox
setState(() {});
// Joining date
if (_controller.joiningDate != null) { if (_controller.joiningDate != null) {
_joiningDateController.text = _joiningDateController.text =
DateFormat('dd MMM yyyy').format(_controller.joiningDate!); DateFormat('dd MMM yyyy').format(_controller.joiningDate!);
} }
// Gender
if (_controller.selectedGender != null) { if (_controller.selectedGender != null) {
_genderController.text = _genderController.text =
_controller.selectedGender!.name.capitalizeFirst ?? ''; _controller.selectedGender!.name.capitalizeFirst ?? '';
} }
// Important part: fetch roles, then set roleController // Role
_controller.fetchRoles().then((_) { _controller.fetchRoles().then((_) {
if (_controller.selectedRoleId != null) { if (_controller.selectedRoleId != null) {
final roleName = _controller.roles.firstWhereOrNull( final roleName = _controller.roles.firstWhereOrNull(
@ -65,6 +81,7 @@ class _AddEmployeeBottomSheetState extends State<AddEmployeeBottomSheet>
if (roleName != null) { if (roleName != null) {
_roleController.text = roleName; _roleController.text = roleName;
} }
_controller.update();
} }
}); });
} else { } else {

View File

@ -12,15 +12,17 @@ class EmployeeDetailsModel {
final String phoneNumber; final String phoneNumber;
final String? emergencyPhoneNumber; final String? emergencyPhoneNumber;
final String? emergencyContactPerson; final String? emergencyContactPerson;
final String? aadharNumber;
final bool isActive; final bool isActive;
final String? panNumber; final bool isRootUser;
final String? photo;
final String? applicationUserId;
final String jobRoleId;
final bool isSystem; final bool isSystem;
final String jobRole; final String jobRole;
final String jobRoleId;
final String? photo;
final String? applicationUserId;
final bool hasApplicationAccess;
final String? organizationId;
final String? aadharNumber;
final String? panNumber;
EmployeeDetailsModel({ EmployeeDetailsModel({
required this.id, required this.id,
required this.firstName, required this.firstName,
@ -35,14 +37,17 @@ class EmployeeDetailsModel {
required this.phoneNumber, required this.phoneNumber,
this.emergencyPhoneNumber, this.emergencyPhoneNumber,
this.emergencyContactPerson, this.emergencyContactPerson,
this.aadharNumber,
required this.isActive, required this.isActive,
this.panNumber, required this.isRootUser,
this.photo,
this.applicationUserId,
required this.jobRoleId,
required this.isSystem, required this.isSystem,
required this.jobRole, required this.jobRole,
required this.jobRoleId,
this.photo,
this.applicationUserId,
required this.hasApplicationAccess,
this.organizationId,
this.aadharNumber,
this.panNumber,
}); });
factory EmployeeDetailsModel.fromJson(Map<String, dynamic> json) { factory EmployeeDetailsModel.fromJson(Map<String, dynamic> json) {
@ -60,24 +65,20 @@ class EmployeeDetailsModel {
phoneNumber: json['phoneNumber'], phoneNumber: json['phoneNumber'],
emergencyPhoneNumber: json['emergencyPhoneNumber'], emergencyPhoneNumber: json['emergencyPhoneNumber'],
emergencyContactPerson: json['emergencyContactPerson'], emergencyContactPerson: json['emergencyContactPerson'],
aadharNumber: json['aadharNumber'],
isActive: json['isActive'], isActive: json['isActive'],
panNumber: json['panNumber'], isRootUser: json['isRootUser'],
photo: json['photo'],
applicationUserId: json['applicationUserId'],
jobRoleId: json['jobRoleId'],
isSystem: json['isSystem'], isSystem: json['isSystem'],
jobRole: json['jobRole'], jobRole: json['jobRole'],
jobRoleId: json['jobRoleId'],
photo: json['photo'],
applicationUserId: json['applicationUserId'],
hasApplicationAccess: json['hasApplicationAccess'],
organizationId: json['organizationId'],
aadharNumber: json['aadharNumber'],
panNumber: json['panNumber'],
); );
} }
static DateTime? _parseDate(String? dateStr) {
if (dateStr == null || dateStr == "0001-01-01T00:00:00") {
return null;
}
return DateTime.tryParse(dateStr);
}
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
return { return {
'id': id, 'id': id,
@ -93,14 +94,24 @@ class EmployeeDetailsModel {
'phoneNumber': phoneNumber, 'phoneNumber': phoneNumber,
'emergencyPhoneNumber': emergencyPhoneNumber, 'emergencyPhoneNumber': emergencyPhoneNumber,
'emergencyContactPerson': emergencyContactPerson, 'emergencyContactPerson': emergencyContactPerson,
'aadharNumber': aadharNumber,
'isActive': isActive, 'isActive': isActive,
'panNumber': panNumber, 'isRootUser': isRootUser,
'photo': photo,
'applicationUserId': applicationUserId,
'jobRoleId': jobRoleId,
'isSystem': isSystem, 'isSystem': isSystem,
'jobRole': jobRole, 'jobRole': jobRole,
'jobRoleId': jobRoleId,
'photo': photo,
'applicationUserId': applicationUserId,
'hasApplicationAccess': hasApplicationAccess,
'organizationId': organizationId,
'aadharNumber': aadharNumber,
'panNumber': panNumber,
}; };
} }
static DateTime? _parseDate(String? dateStr) {
if (dateStr == null || dateStr == "0001-01-01T00:00:00") {
return null;
}
return DateTime.tryParse(dateStr);
}
} }

View File

@ -261,6 +261,9 @@ class _EmployeeDetailPageState extends State<EmployeeDetailPage> {
'first_name': employee.firstName, 'first_name': employee.firstName,
'last_name': employee.lastName, 'last_name': employee.lastName,
'phone_number': employee.phoneNumber, 'phone_number': employee.phoneNumber,
'email': employee.email,
'hasApplicationAccess':
employee.hasApplicationAccess,
'gender': employee.gender.toLowerCase(), 'gender': employee.gender.toLowerCase(),
'job_role_id': employee.jobRoleId, 'job_role_id': employee.jobRoleId,
'joining_date': 'joining_date':