import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:collection/collection.dart'; import 'package:on_field_work/controller/directory/manage_bucket_controller.dart'; import 'package:on_field_work/controller/directory/directory_controller.dart'; import 'package:on_field_work/helpers/utils/base_bottom_sheet.dart'; import 'package:on_field_work/helpers/widgets/my_text.dart'; import 'package:on_field_work/helpers/widgets/my_spacing.dart'; import 'package:on_field_work/helpers/widgets/my_snackbar.dart'; import 'package:on_field_work/model/employees/employee_model.dart'; import 'package:on_field_work/model/directory/contact_bucket_list_model.dart'; import 'package:on_field_work/model/employees/multiple_select_bottomsheet.dart'; class EditBucketBottomSheet { static void show( BuildContext context, ContactBucket bucket, List allEmployees, { required String ownerId, }) { final ManageBucketController controller = Get.find(); final nameController = TextEditingController(text: bucket.name); final descController = TextEditingController(text: bucket.description); final selectedIds = RxSet({...bucket.employeeIds}); InputDecoration _inputDecoration(String label) { return InputDecoration( labelText: label, filled: true, fillColor: Colors.grey.shade100, border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade300), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade300), ), focusedBorder: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(12)), borderSide: BorderSide(color: Colors.blueAccent, width: 1.5), ), contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), isDense: true, ); } Future _handleSubmit() async { final newName = nameController.text.trim(); final newDesc = descController.text.trim(); final newEmployeeIds = selectedIds.toList()..sort(); final originalEmployeeIds = [...bucket.employeeIds]..sort(); final nameChanged = newName != bucket.name; final descChanged = newDesc != bucket.description; final employeeChanged = !(const ListEquality().equals(newEmployeeIds, originalEmployeeIds)); if (!nameChanged && !descChanged && !employeeChanged) { showAppSnackbar( title: "No Changes", message: "No changes were made to update the bucket.", type: SnackbarType.warning, ); return; } final success = await controller.updateBucket( id: bucket.id, name: newName, description: newDesc, employeeIds: newEmployeeIds, originalEmployeeIds: originalEmployeeIds, ); if (success) { final directoryController = Get.find(); await directoryController.fetchBuckets(); Navigator.of(context).pop(); } } Future _handleSubmitBottomSheet(BuildContext sheetContext) async { await _handleSubmit(); // close bottom sheet safely if (Navigator.of(sheetContext).canPop()) { Navigator.of(sheetContext).pop(); } } Widget _formContent() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ TextField( controller: nameController, decoration: _inputDecoration('Bucket Name'), ), MySpacing.height(16), TextField( controller: descController, maxLines: 2, decoration: _inputDecoration('Description'), ), MySpacing.height(20), MyText.labelLarge('Shared With', fontWeight: 600), MySpacing.height(8), Obx(() { if (selectedIds.isEmpty) return const SizedBox.shrink(); final selectedEmployees = allEmployees.where((e) => selectedIds.contains(e.id)).toList(); return Wrap( spacing: 8, children: selectedEmployees.map((emp) { final fullName = '${emp.firstName} ${emp.lastName}'.trim(); return Chip( label: Text(fullName), onDeleted: emp.id == ownerId ? null : () => selectedIds.remove(emp.id), ); }).toList(), ); }), MySpacing.height(8), // --- Open new EmployeeSelectionBottomSheet --- GestureDetector( onTap: () async { final initiallySelected = allEmployees .where((e) => selectedIds.contains(e.id)) .toList(); final result = await showModalBottomSheet>( context: context, isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(22)), ), builder: (_) => EmployeeSelectionBottomSheet( initiallySelected: initiallySelected, multipleSelection: true, title: "Shared With", ), ); if (result != null) { selectedIds ..clear() ..addAll(result.map((e) => e.id)); } }, child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), decoration: BoxDecoration( color: Colors.grey.shade100, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.grey.shade300), ), child: Row( children: const [ Icon(Icons.search, color: Colors.grey), SizedBox(width: 8), Expanded(child: Text("Search & Select Employees")), ], ), ), ), MySpacing.height(8), const SizedBox.shrink(), ], ); } showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) { return BaseBottomSheet( title: "Edit Bucket", onCancel: () => Navigator.pop(context), onSubmit: () => _handleSubmitBottomSheet(context), child: _formContent(), ); }, ); } }