Enhance AttendanceController: add separate loading states for projects, employees, attendance logs, and regularization logs; adjust default date range logic; improve date range picker functionality, restricted todays date selection #29

Merged
vaibhav.surve merged 1 commits from Vaibhav_Enhancement-#313 into main 2025-05-21 12:13:46 +00:00

View File

@ -20,7 +20,7 @@ class AttendanceController extends GetxController {
List<ProjectModel> projects = [];
String? selectedProjectId;
List<EmployeeModel> employees = [];
String selectedTab = 'Employee List';
DateTime? startDateAttendance;
DateTime? endDateAttendance;
@ -28,7 +28,15 @@ class AttendanceController extends GetxController {
List<RegularizationLogModel> regularizationLogs = [];
List<AttendanceLogViewModel> attendenceLogsView = [];
RxBool isLoading = false.obs;
RxBool isLoading = true.obs;
// New separate loading states per feature
RxBool isLoadingProjects = true.obs;
RxBool isLoadingEmployees = true.obs;
RxBool isLoadingAttendanceLogs = true.obs;
RxBool isLoadingRegularizationLogs = true.obs;
RxBool isLoadingLogView = true.obs;
RxMap<String, RxBool> uploadingStates = <String, RxBool>{}.obs;
@override
@ -45,7 +53,7 @@ class AttendanceController extends GetxController {
void _setDefaultDateRange() {
final today = DateTime.now();
startDateAttendance = today.subtract(const Duration(days: 7));
endDateAttendance = today;
endDateAttendance = today.subtract(const Duration(days: 1));
log.i("Default date range set: $startDateAttendance to $endDateAttendance");
}
@ -70,8 +78,13 @@ class AttendanceController extends GetxController {
}
Future<void> fetchProjects() async {
// Both old and new loading state set for safety
isLoading.value = true;
isLoadingProjects.value = true;
final response = await ApiService.getProjects();
isLoadingProjects.value = false;
isLoading.value = false;
if (response != null && response.isNotEmpty) {
@ -89,12 +102,14 @@ class AttendanceController extends GetxController {
if (projectId == null) return;
isLoading.value = true;
await Future.wait([
fetchEmployeesByProject(projectId),
fetchAttendanceLogs(projectId,
dateFrom: startDateAttendance, dateTo: endDateAttendance),
fetchRegularizationLogs(projectId),
]);
isLoading.value = false;
log.i("Project data fetched for project ID: $projectId");
}
@ -103,7 +118,11 @@ class AttendanceController extends GetxController {
if (projectId == null) return;
isLoading.value = true;
isLoadingEmployees.value = true;
final response = await ApiService.getEmployeesByProject(projectId);
isLoadingEmployees.value = false;
isLoading.value = false;
if (response != null) {
@ -114,7 +133,8 @@ class AttendanceController extends GetxController {
uploadingStates[emp.id] = false.obs;
}
log.i("Employees fetched: ${employees.length} employees for project $projectId");
log.i(
"Employees fetched: ${employees.length} employees for project $projectId");
update();
} else {
log.e("Failed to fetch employees for project $projectId");
@ -188,15 +208,26 @@ class AttendanceController extends GetxController {
BuildContext context,
AttendanceController controller,
) async {
final today = DateTime.now();
final todayDateOnly = DateTime(today.year, today.month, today.day);
final picked = await showDateRangePicker(
context: context,
firstDate: DateTime(2022),
lastDate: DateTime.now(),
lastDate: todayDateOnly.subtract(const Duration(days: 1)),
initialDateRange: DateTimeRange(
start: startDateAttendance ??
DateTime.now().subtract(const Duration(days: 7)),
end: endDateAttendance ?? DateTime.now(),
end: endDateAttendance ??
todayDateOnly.subtract(const Duration(days: 1)),
),
selectableDayPredicate: (DateTime day, DateTime? start, DateTime? end) {
final dayDateOnly = DateTime(day.year, day.month, day.day);
if (dayDateOnly == todayDateOnly) {
return false;
}
return true;
},
);
if (picked != null) {
@ -221,11 +252,15 @@ class AttendanceController extends GetxController {
if (projectId == null) return;
isLoading.value = true;
isLoadingAttendanceLogs.value = true;
final response = await ApiService.getAttendanceLogs(
projectId,
dateFrom: dateFrom,
dateTo: dateTo,
);
isLoadingAttendanceLogs.value = false;
isLoading.value = false;
if (response != null) {
@ -275,12 +310,17 @@ class AttendanceController extends GetxController {
if (projectId == null) return;
isLoading.value = true;
isLoadingRegularizationLogs.value = true;
final response = await ApiService.getRegularizationLogs(projectId);
isLoadingRegularizationLogs.value = false;
isLoading.value = false;
if (response != null) {
regularizationLogs =
response.map((json) => RegularizationLogModel.fromJson(json)).toList();
regularizationLogs = response
.map((json) => RegularizationLogModel.fromJson(json))
.toList();
log.i("Regularization logs fetched: ${regularizationLogs.length}");
update();
} else {
@ -292,7 +332,11 @@ class AttendanceController extends GetxController {
if (id == null) return;
isLoading.value = true;
isLoadingLogView.value = true;
final response = await ApiService.getAttendanceLogView(id);
isLoadingLogView.value = false;
isLoading.value = false;
if (response != null) {
@ -302,8 +346,8 @@ class AttendanceController extends GetxController {
// Sort by activityTime field (latest first)
attendenceLogsView.sort((a, b) {
if (a.activityTime == null || b.activityTime == null) return 0; // Handle null values if any
return b.activityTime!.compareTo(a.activityTime!); // Sort descending (latest first)
if (a.activityTime == null || b.activityTime == null) return 0;
return b.activityTime!.compareTo(a.activityTime!);
});
log.i("Attendance log view fetched for ID: $id");