From a1bd9a3108ae78a73a590de9798c64da3c07f3fc Mon Sep 17 00:00:00 2001 From: Vaibhav Surve Date: Wed, 1 Oct 2025 16:59:15 +0530 Subject: [PATCH] resolved the email and has application acccess is not populated on edit --- .../directory/add_contact_bottom_sheet.dart | 253 +++++++++--------- .../employees/add_employee_bottom_sheet.dart | 23 +- .../employees/employee_details_model.dart | 67 +++-- .../employees/employee_detail_screen.dart | 3 + 4 files changed, 187 insertions(+), 159 deletions(-) diff --git a/lib/model/directory/add_contact_bottom_sheet.dart b/lib/model/directory/add_contact_bottom_sheet.dart index 358b913..cd2ae68 100644 --- a/lib/model/directory/add_contact_bottom_sheet.dart +++ b/lib/model/directory/add_contact_bottom_sheet.dart @@ -72,42 +72,41 @@ class _AddContactBottomSheetState extends State { controller.enteredTags.assignAll(c.tags.map((e) => e.name)); - ever(controller.isInitialized, (bool ready) { - if (ready) { - final projectIds = c.projectIds; - final bucketId = c.bucketIds.firstOrNull; - final category = c.contactCategory?.name; - - if (category != null) controller.selectedCategory.value = category; - - if (projectIds != null) { - controller.selectedProjects.assignAll( - projectIds - .map((id) => controller.projectsMap.entries - .firstWhereOrNull((e) => e.value == id) - ?.key) - .whereType() - .toList(), - ); - } - - if (bucketId != null) { - final name = controller.bucketsMap.entries - .firstWhereOrNull((e) => e.value == bucketId) + ever(controller.isInitialized, (bool 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; - if (name != null && !controller.selectedBuckets.contains(name)) { - controller.selectedBuckets.add(name); - } - } + }).whereType().toList(); + controller.selectedBuckets.assignAll(names); } - }); - } else { - emailCtrls.add(TextEditingController()); - emailLabels.add('Office'.obs); - phoneCtrls.add(TextEditingController()); - phoneLabels.add('Work'.obs); - } + // Projects and Category mapping - as before + final projectIds = c.projectIds; + if (projectIds != null) { + controller.selectedProjects.assignAll( + projectIds + .map((id) => controller.projectsMap.entries + .firstWhereOrNull((e) => e.value == id) + ?.key) + .whereType() + .toList(), + ); + } + final category = c.contactCategory?.name; + if (category != null) controller.selectedCategory.value = category; + } + }); + } else { + showAdvanced.value = false; // Optional + emailCtrls.add(TextEditingController()); + emailLabels.add('Office'.obs); + phoneCtrls.add(TextEditingController()); + phoneLabels.add('Work'.obs); } +} @override void dispose() { @@ -375,112 +374,110 @@ class _AddContactBottomSheetState extends State { ); } - Widget _multiSelectField({ - required List items, - required String fallback, - required RxList selectedValues, - }) { - if (items.isEmpty) return const SizedBox.shrink(); + Widget _multiSelectField({ + required List items, + required String fallback, + required RxList selectedValues, +}) { + if (items.isEmpty) return const SizedBox.shrink(); - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Obx(() { - final selectedNames = items - .where((f) => selectedValues.contains(f.id)) - .map((f) => f.name) - .join(", "); - final displayText = - selectedNames.isNotEmpty ? selectedNames : fallback; + return Obx(() { + final selectedNames = items + .where((f) => selectedValues.contains(f.id)) + .map((f) => f.name) + .join(", "); + final displayText = selectedNames.isNotEmpty ? selectedNames : fallback; - return Builder( - builder: (context) { - return GestureDetector( - onTap: () async { - final RenderBox button = - context.findRenderObject() as RenderBox; - final RenderBox overlay = Overlay.of(context) - .context - .findRenderObject() as RenderBox; + return Builder( + builder: (context) { + return GestureDetector( + onTap: () async { + final RenderBox button = + context.findRenderObject() as RenderBox; + final RenderBox overlay = + Overlay.of(context).context.findRenderObject() as RenderBox; + final position = button.localToGlobal(Offset.zero); - final position = button.localToGlobal(Offset.zero); - - await showMenu( - context: context, - position: RelativeRect.fromLTRB( - position.dx, - position.dy + button.size.height, - overlay.size.width - position.dx - button.size.width, - 0, - ), - items: items.map((f) { - return PopupMenuItem( - enabled: false, - child: StatefulBuilder( - builder: (context, setState) { - final isChecked = selectedValues.contains(f.id); - return CheckboxListTile( - dense: true, - value: isChecked, - contentPadding: EdgeInsets.zero, - controlAffinity: ListTileControlAffinity.leading, - title: MyText(f.name), - checkColor: Colors.white, - side: const BorderSide( - color: Colors.black, width: 1.5), - fillColor: - MaterialStateProperty.resolveWith( - (states) { + await showMenu( + context: context, + position: RelativeRect.fromLTRB( + position.dx, + position.dy + button.size.height, + overlay.size.width - position.dx - button.size.width, + 0, + ), + items: [ + PopupMenuItem( + enabled: false, + child: StatefulBuilder( + builder: (context, setState) { + return SizedBox( + width: 250, + child: SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.min, + children: items.map((f) { + final isChecked = selectedValues.contains(f.id); + return CheckboxListTile( + dense: true, + title: Text(f.name), + value: isChecked, + contentPadding: EdgeInsets.zero, + controlAffinity: ListTileControlAffinity.leading, + side: const BorderSide(color: Colors.black, width: 1.5), + fillColor: MaterialStateProperty.resolveWith((states) { 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) { + if (val == true) { + selectedValues.add(f.id); + } else { + selectedValues.remove(f.id); + } + setState(() {}); }, - ), - onChanged: (val) { - if (val == true) { - selectedValues.add(f.id); - } else { - selectedValues.remove(f.id); - } - setState(() {}); - }, - ); - }, + ); + }).toList(), + ), ), ); - }).toList(), - ); - }, - child: Container( - padding: MySpacing.all(12), - decoration: BoxDecoration( - color: Colors.grey.shade100, - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(12), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: MyText( - displayText, - style: const TextStyle(color: Colors.black87), - overflow: TextOverflow.ellipsis, - ), - ), - const Icon(Icons.arrow_drop_down, color: Colors.grey), - ], + }, ), ), - ); - }, - ); - }), - MySpacing.height(16), - ], + ], + ); + }, + child: Container( + padding: MySpacing.all(12), + decoration: BoxDecoration( + color: Colors.grey.shade100, + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(12), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: MyText( + displayText, + style: const TextStyle(color: Colors.black87), + overflow: TextOverflow.ellipsis, + ), + ), + const Icon(Icons.arrow_drop_down, color: Colors.grey), + ], + ), + ), + ); + }, ); - } + }); +} + void _handleSubmit() { bool valid = formKey.currentState?.validate() ?? false; diff --git a/lib/model/employees/add_employee_bottom_sheet.dart b/lib/model/employees/add_employee_bottom_sheet.dart index 4ad02f9..0af5173 100644 --- a/lib/model/employees/add_employee_bottom_sheet.dart +++ b/lib/model/employees/add_employee_bottom_sheet.dart @@ -36,7 +36,7 @@ class _AddEmployeeBottomSheetState extends State @override void initState() { super.initState(); - + _orgFieldController = TextEditingController(); _joiningDateController = TextEditingController(); _genderController = TextEditingController(); _roleController = TextEditingController(); @@ -46,17 +46,33 @@ class _AddEmployeeBottomSheetState extends State if (widget.employeeData != null) { _controller.editingEmployeeData = widget.employeeData; _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) { _joiningDateController.text = DateFormat('dd MMM yyyy').format(_controller.joiningDate!); } + + // Gender if (_controller.selectedGender != null) { _genderController.text = _controller.selectedGender!.name.capitalizeFirst ?? ''; } - // ✅ Important part: fetch roles, then set roleController + // Role _controller.fetchRoles().then((_) { if (_controller.selectedRoleId != null) { final roleName = _controller.roles.firstWhereOrNull( @@ -65,6 +81,7 @@ class _AddEmployeeBottomSheetState extends State if (roleName != null) { _roleController.text = roleName; } + _controller.update(); } }); } else { diff --git a/lib/model/employees/employee_details_model.dart b/lib/model/employees/employee_details_model.dart index cd0ea65..7adf7fc 100644 --- a/lib/model/employees/employee_details_model.dart +++ b/lib/model/employees/employee_details_model.dart @@ -12,15 +12,17 @@ class EmployeeDetailsModel { final String phoneNumber; final String? emergencyPhoneNumber; final String? emergencyContactPerson; - final String? aadharNumber; final bool isActive; - final String? panNumber; - final String? photo; - final String? applicationUserId; - final String jobRoleId; + final bool isRootUser; final bool isSystem; 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({ required this.id, required this.firstName, @@ -35,14 +37,17 @@ class EmployeeDetailsModel { required this.phoneNumber, this.emergencyPhoneNumber, this.emergencyContactPerson, - this.aadharNumber, required this.isActive, - this.panNumber, - this.photo, - this.applicationUserId, - required this.jobRoleId, + required this.isRootUser, required this.isSystem, required this.jobRole, + required this.jobRoleId, + this.photo, + this.applicationUserId, + required this.hasApplicationAccess, + this.organizationId, + this.aadharNumber, + this.panNumber, }); factory EmployeeDetailsModel.fromJson(Map json) { @@ -60,24 +65,20 @@ class EmployeeDetailsModel { phoneNumber: json['phoneNumber'], emergencyPhoneNumber: json['emergencyPhoneNumber'], emergencyContactPerson: json['emergencyContactPerson'], - aadharNumber: json['aadharNumber'], isActive: json['isActive'], - panNumber: json['panNumber'], - photo: json['photo'], - applicationUserId: json['applicationUserId'], - jobRoleId: json['jobRoleId'], + isRootUser: json['isRootUser'], isSystem: json['isSystem'], 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 toJson() { return { 'id': id, @@ -93,14 +94,24 @@ class EmployeeDetailsModel { 'phoneNumber': phoneNumber, 'emergencyPhoneNumber': emergencyPhoneNumber, 'emergencyContactPerson': emergencyContactPerson, - 'aadharNumber': aadharNumber, 'isActive': isActive, - 'panNumber': panNumber, - 'photo': photo, - 'applicationUserId': applicationUserId, - 'jobRoleId': jobRoleId, + 'isRootUser': isRootUser, 'isSystem': isSystem, '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); + } } diff --git a/lib/view/employees/employee_detail_screen.dart b/lib/view/employees/employee_detail_screen.dart index bbb0b98..367c58c 100644 --- a/lib/view/employees/employee_detail_screen.dart +++ b/lib/view/employees/employee_detail_screen.dart @@ -261,6 +261,9 @@ class _EmployeeDetailPageState extends State { 'first_name': employee.firstName, 'last_name': employee.lastName, 'phone_number': employee.phoneNumber, + 'email': employee.email, + 'hasApplicationAccess': + employee.hasApplicationAccess, 'gender': employee.gender.toLowerCase(), 'job_role_id': employee.jobRoleId, 'joining_date':