- Added a floating action button to the Layout widget for better accessibility. - Updated the left bar navigation items for clarity and consistency. - Introduced Daily Progress Report and Daily Task Planning screens with comprehensive UI. - Implemented filtering and refreshing functionalities in task planning. - Improved user experience with better spacing and layout adjustments. - Updated pubspec.yaml to include new dependencies for image handling and path management.
151 lines
4.3 KiB
Dart
151 lines
4.3 KiB
Dart
import 'package:get/get.dart';
|
|
import 'package:logger/logger.dart';
|
|
import 'package:marco/helpers/services/api_service.dart';
|
|
import 'package:marco/model/attendance_model.dart';
|
|
import 'package:marco/model/project_model.dart';
|
|
import 'package:marco/model/employee_model.dart';
|
|
import 'package:marco/model/employees/employee_details_model.dart';
|
|
|
|
final Logger log = Logger();
|
|
|
|
class EmployeesScreenController extends GetxController {
|
|
List<AttendanceModel> attendances = [];
|
|
List<ProjectModel> projects = [];
|
|
String? selectedProjectId;
|
|
List<EmployeeModel> employees = [];
|
|
List<EmployeeDetailsModel> employeeDetails = [];
|
|
|
|
RxBool isLoading = false.obs;
|
|
RxMap<String, RxBool> uploadingStates = <String, RxBool>{}.obs;
|
|
Rxn<EmployeeDetailsModel> selectedEmployeeDetails =
|
|
Rxn<EmployeeDetailsModel>();
|
|
RxBool isLoadingEmployeeDetails = false.obs;
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
fetchAllProjects();
|
|
fetchAllEmployees();
|
|
}
|
|
|
|
Future<void> fetchAllProjects() async {
|
|
isLoading.value = true;
|
|
await _handleApiCall(
|
|
ApiService.getProjects,
|
|
onSuccess: (data) {
|
|
projects = data.map((json) => ProjectModel.fromJson(json)).toList();
|
|
log.i("Projects fetched: ${projects.length} projects loaded.");
|
|
},
|
|
onEmpty: () => log.w("No project data found or API call failed."),
|
|
);
|
|
isLoading.value = false;
|
|
update();
|
|
}
|
|
|
|
Future<void> fetchAllEmployees() async {
|
|
isLoading.value = true;
|
|
await _handleApiCall(
|
|
ApiService.getAllEmployees,
|
|
onSuccess: (data) {
|
|
employees = data.map((json) => EmployeeModel.fromJson(json)).toList();
|
|
log.i("All Employees fetched: ${employees.length} employees loaded.");
|
|
},
|
|
onEmpty: () => log.w("No Employee data found or API call failed."),
|
|
);
|
|
isLoading.value = false;
|
|
update();
|
|
}
|
|
|
|
Future<void> fetchEmployeesByProject(String? projectId) async {
|
|
if (projectId == null || projectId.isEmpty) {
|
|
log.e("Project ID is required but was null or empty.");
|
|
return;
|
|
}
|
|
|
|
isLoading.value = true;
|
|
await _handleApiCall(
|
|
() => ApiService.getAllEmployeesByProject(projectId),
|
|
onSuccess: (data) {
|
|
employees = data.map((json) => EmployeeModel.fromJson(json)).toList();
|
|
for (var emp in employees) {
|
|
uploadingStates[emp.id] = false.obs;
|
|
}
|
|
log.i("Employees fetched: ${employees.length} for project $projectId");
|
|
update();
|
|
},
|
|
onEmpty: () {
|
|
log.w("No employees found for project $projectId.");
|
|
employees = [];
|
|
update();
|
|
},
|
|
onError: (e) =>
|
|
log.e("Error fetching employees for project $projectId: $e"),
|
|
);
|
|
isLoading.value = false;
|
|
}
|
|
|
|
Future<void> _handleApiCall(
|
|
Future<List<dynamic>?> Function() apiCall, {
|
|
required Function(List<dynamic>) onSuccess,
|
|
required Function() onEmpty,
|
|
Function(dynamic error)? onError,
|
|
}) async {
|
|
try {
|
|
final response = await apiCall();
|
|
if (response != null && response.isNotEmpty) {
|
|
onSuccess(response);
|
|
} else {
|
|
onEmpty();
|
|
}
|
|
} catch (e) {
|
|
if (onError != null) {
|
|
onError(e);
|
|
} else {
|
|
log.e("API call error: $e");
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> fetchEmployeeDetails(String? employeeId) async {
|
|
if (employeeId == null || employeeId.isEmpty) return;
|
|
|
|
isLoadingEmployeeDetails.value = true;
|
|
|
|
await _handleSingleApiCall(
|
|
() => ApiService.getEmployeeDetails(employeeId),
|
|
onSuccess: (data) {
|
|
selectedEmployeeDetails.value = EmployeeDetailsModel.fromJson(data);
|
|
},
|
|
onEmpty: () {
|
|
selectedEmployeeDetails.value = null;
|
|
},
|
|
onError: (e) {
|
|
selectedEmployeeDetails.value = null;
|
|
},
|
|
);
|
|
|
|
isLoadingEmployeeDetails.value = false;
|
|
}
|
|
|
|
Future<void> _handleSingleApiCall(
|
|
Future<Map<String, dynamic>?> Function() apiCall, {
|
|
required Function(Map<String, dynamic>) onSuccess,
|
|
required Function() onEmpty,
|
|
Function(dynamic error)? onError,
|
|
}) async {
|
|
try {
|
|
final response = await apiCall();
|
|
if (response != null && response.isNotEmpty) {
|
|
onSuccess(response);
|
|
} else {
|
|
onEmpty();
|
|
}
|
|
} catch (e) {
|
|
if (onError != null) {
|
|
onError(e);
|
|
} else {
|
|
log.e("API call error: $e");
|
|
}
|
|
}
|
|
}
|
|
}
|