marco.pms.mobileapp/lib/controller/employee/assign_projects_controller.dart
Vaibhav Surve 943c7c7b50 feat: Add employee assignment functionality and improve employee detail view
- Implemented employee skeleton card for loading states in the UI.
- Created AssignedProjectsResponse and AssignedProject models for handling project assignments.
- Enhanced EmployeeDetailBottomSheet to include project assignment button.
- Developed AssignProjectBottomSheet for selecting projects to assign to employees.
- Introduced EmployeeDetailPage for displaying detailed employee information.
- Updated EmployeesScreen to support searching and filtering employees.
- Improved layout and UI elements for better user experience.
2025-07-22 20:10:57 +05:30

146 lines
4.3 KiB
Dart

import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:marco/helpers/services/api_service.dart';
import 'package:marco/helpers/services/app_logger.dart';
import 'package:marco/model/global_project_model.dart';
import 'package:marco/model/employees/assigned_projects_model.dart';
import 'package:marco/controller/project_controller.dart';
class AssignProjectController extends GetxController {
final String employeeId;
final String jobRoleId;
AssignProjectController({
required this.employeeId,
required this.jobRoleId,
});
final ProjectController projectController = Get.put(ProjectController());
RxBool isLoading = false.obs;
RxBool isAssigning = false.obs;
RxList<String> assignedProjectIds = <String>[].obs;
RxList<String> selectedProjects = <String>[].obs;
RxList<GlobalProjectModel> allProjects = <GlobalProjectModel>[].obs;
RxList<GlobalProjectModel> filteredProjects = <GlobalProjectModel>[].obs;
@override
void onInit() {
super.onInit();
WidgetsBinding.instance.addPostFrameCallback((_) {
fetchAllProjectsAndAssignments();
});
}
/// Fetch all projects and assigned projects
Future<void> fetchAllProjectsAndAssignments() async {
isLoading.value = true;
try {
await projectController.fetchProjects();
allProjects.assignAll(projectController.projects);
filteredProjects.assignAll(allProjects); // initially show all
final responseList = await ApiService.getAssignedProjects(employeeId);
if (responseList != null) {
final assignedProjects =
responseList.map((e) => AssignedProject.fromJson(e)).toList();
assignedProjectIds.assignAll(
assignedProjects.map((p) => p.id).toList(),
);
selectedProjects.assignAll(assignedProjectIds);
}
logSafe("All Projects: ${allProjects.map((e) => e.id)}");
logSafe("Assigned Project IDs: $assignedProjectIds");
} catch (e, stack) {
logSafe("Error fetching projects or assignments: $e",
level: LogLevel.error);
logSafe("StackTrace: $stack", level: LogLevel.debug);
} finally {
isLoading.value = false;
}
}
/// Assign selected projects
Future<bool> assignProjectsToEmployee() async {
if (selectedProjects.isEmpty) {
logSafe("No projects selected for assignment.", level: LogLevel.warning);
return false;
}
final List<Map<String, dynamic>> projectPayload =
selectedProjects.map((id) {
return {"projectId": id, "jobRoleId": jobRoleId, "status": true};
}).toList();
isAssigning.value = true;
try {
final success = await ApiService.assignProjects(
employeeId: employeeId,
projects: projectPayload,
);
if (success) {
logSafe("Projects assigned successfully.");
assignedProjectIds.assignAll(selectedProjects);
return true;
} else {
logSafe("Failed to assign projects.", level: LogLevel.error);
return false;
}
} catch (e, stack) {
logSafe("Error assigning projects: $e", level: LogLevel.error);
logSafe("StackTrace: $stack", level: LogLevel.debug);
return false;
} finally {
isAssigning.value = false;
}
}
/// Toggle project selection
void toggleProjectSelection(String projectId, bool isSelected) {
if (isSelected) {
if (!selectedProjects.contains(projectId)) {
selectedProjects.add(projectId);
}
} else {
selectedProjects.remove(projectId);
}
}
/// Check if project is selected
bool isProjectSelected(String projectId) {
return selectedProjects.contains(projectId);
}
/// Select all / deselect all
void toggleSelectAll() {
if (areAllSelected()) {
selectedProjects.clear();
} else {
selectedProjects.assignAll(allProjects.map((p) => p.id.toString()));
}
}
/// Are all selected?
bool areAllSelected() {
return selectedProjects.length == allProjects.length &&
allProjects.isNotEmpty;
}
/// Filter projects by search text
void filterProjects(String query) {
if (query.isEmpty) {
filteredProjects.assignAll(allProjects);
} else {
filteredProjects.assignAll(
allProjects
.where((p) => p.name.toLowerCase().contains(query.toLowerCase()))
.toList(),
);
}
}
}