import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:marco/helpers/services/api_service.dart'; import 'package:marco/model/employees/employee_model.dart'; import 'package:marco/helpers/services/app_logger.dart'; import 'package:marco/helpers/widgets/my_snackbar.dart'; class AddServiceProjectJobController extends GetxController { // Form Controllers final titleCtrl = TextEditingController(); final descCtrl = TextEditingController(); final tagCtrl = TextEditingController(); final FocusNode searchFocusNode = FocusNode(); final RxBool showEmployeePicker = true.obs; // Observables final startDate = Rx(DateTime.now()); final dueDate = Rx(DateTime.now().add(const Duration(days: 1))); final enteredTags = [].obs; final employees = [].obs; final selectedAssignees = [].obs; final isSearchingEmployees = false.obs; // Loading states final isLoading = false.obs; final isAllEmployeeLoading = false.obs; final allEmployees = [].obs; final employeeSearchResults = [].obs; @override void onInit() { super.onInit(); searchEmployees(""); // pass empty string safely } @override void onClose() { titleCtrl.dispose(); descCtrl.dispose(); tagCtrl.dispose(); super.onClose(); } Future searchEmployees(String query) async { if (query.trim().isEmpty) { employeeSearchResults.clear(); return; } isSearchingEmployees.value = true; try { final data = await ApiService.searchEmployeesBasic(searchString: query.trim()); if (data is List) { employeeSearchResults.assignAll( data .map((e) => EmployeeModel.fromJson(e as Map)) .toList(), ); } else { employeeSearchResults.clear(); } } catch (e) { logSafe("Error searching employees: $e", level: LogLevel.error); employeeSearchResults.clear(); } finally { isSearchingEmployees.value = false; } } /// Toggle employee selection void toggleAssignee(EmployeeModel employee) { if (selectedAssignees.contains(employee)) { selectedAssignees.remove(employee); } else { selectedAssignees.add(employee); } } /// Create Service Project Job API call Future createJob(String projectId) async { if (titleCtrl.text.trim().isEmpty || descCtrl.text.trim().isEmpty) { showAppSnackbar( title: "Validation", message: "Title and Description are required", type: SnackbarType.warning, ); return; } final assigneeIds = selectedAssignees.map((e) => e.id).toList(); final success = await ApiService.createServiceProjectJobApi( title: titleCtrl.text.trim(), description: descCtrl.text.trim(), projectId: projectId, assignees: assigneeIds.map((id) => {"id": id}).toList(), startDate: startDate.value!, dueDate: dueDate.value!, tags: enteredTags.map((tag) => {"name": tag}).toList(), ); if (success) { Get.back(); showAppSnackbar( title: "Success", message: "Job created successfully", type: SnackbarType.success, ); } else { showAppSnackbar( title: "Error", message: "Failed to create job", type: SnackbarType.error, ); } } }