diff --git a/lib/controller/dashboard/dashboard_controller.dart b/lib/controller/dashboard/dashboard_controller.dart index 2ce16bc..bf91723 100644 --- a/lib/controller/dashboard/dashboard_controller.dart +++ b/lib/controller/dashboard/dashboard_controller.dart @@ -7,7 +7,8 @@ final Logger log = Logger(); class DashboardController extends GetxController { // Observables - final RxList> roleWiseData = >[].obs; + final RxList> roleWiseData = + >[].obs; final RxBool isLoading = false.obs; final RxString selectedRange = '7D'.obs; final RxBool isChartView = true.obs; @@ -15,33 +16,32 @@ class DashboardController extends GetxController { // Inject the ProjectController final ProjectController projectController = Get.find(); - @override - void onInit() { - super.onInit(); + @override +void onInit() { + super.onInit(); - final selectedProjectIdRx = projectController.selectedProjectId; + // Log to verify order of controller initialization + log.i('DashboardController initialized with project ID: ${projectController.selectedProjectId.value}'); - if (selectedProjectIdRx != null) { - // Fix: explicitly cast and use ever with non-nullable type - ever(selectedProjectIdRx, (id) { - if (id.isNotEmpty) { - fetchRoleWiseAttendance(); - } - }); - - // Initial load if already has value - if (selectedProjectIdRx.value.isNotEmpty) { - fetchRoleWiseAttendance(); - } - } else { - log.w('selectedProjectId observable is null in ProjectController.'); - } - - ever(selectedRange, (_) { - fetchRoleWiseAttendance(); - }); + if (projectController.selectedProjectId.value.isNotEmpty) { + fetchRoleWiseAttendance(); } + // React to project change + ever(projectController.selectedProjectId, (id) { + if (id.isNotEmpty) { + log.i('Project changed to $id, fetching attendance'); + fetchRoleWiseAttendance(); + } + }); + + // React to range change + ever(selectedRange, (_) { + fetchRoleWiseAttendance(); + }); +} + + int get rangeDays => _getDaysFromRange(selectedRange.value); int _getDaysFromRange(String range) { @@ -69,10 +69,10 @@ class DashboardController extends GetxController { } Future fetchRoleWiseAttendance() async { - final String? projectId = projectController.selectedProjectId?.value; + final String projectId = projectController.selectedProjectId.value; - if (projectId == null || projectId.isEmpty) { - log.w('Project ID is null or empty, skipping API call.'); + if (projectId.isEmpty) { + log.w('Project ID is empty, skipping API call.'); return; } diff --git a/lib/controller/project_controller.dart b/lib/controller/project_controller.dart index b30bcdb..5a27f95 100644 --- a/lib/controller/project_controller.dart +++ b/lib/controller/project_controller.dart @@ -8,7 +8,7 @@ final Logger log = Logger(); class ProjectController extends GetxController { RxList projects = [].obs; - RxString? selectedProjectId; + RxString selectedProjectId = ''.obs; RxBool isProjectListExpanded = false.obs; RxBool isProjectSelectionExpanded = false.obs; @@ -17,9 +17,9 @@ class ProjectController extends GetxController { RxBool isLoadingProjects = true.obs; RxMap uploadingStates = {}.obs; GlobalProjectModel? get selectedProject { - if (selectedProjectId == null || selectedProjectId!.value.isEmpty) - return null; - return projects.firstWhereOrNull((p) => p.id == selectedProjectId!.value); + if (selectedProjectId.value.isEmpty) return null; + + return projects.firstWhereOrNull((p) => p.id == selectedProjectId.value); } @override @@ -30,7 +30,8 @@ class ProjectController extends GetxController { void clearProjects() { projects.clear(); - selectedProjectId = null; + selectedProjectId.value = ''; + isProjectSelectionExpanded.value = false; isProjectListExpanded.value = false; isProjectDropdownExpanded.value = false; @@ -54,11 +55,10 @@ class ProjectController extends GetxController { String? savedId = LocalStorage.getString('selectedProjectId'); if (savedId != null && projects.any((p) => p.id == savedId)) { - selectedProjectId = RxString(savedId); + selectedProjectId.value = savedId; // ✅ update value only } else { - selectedProjectId = RxString(projects.first.id.toString()); - LocalStorage.saveString( - 'selectedProjectId', projects.first.id.toString()); + selectedProjectId.value = projects.first.id.toString(); // ✅ + LocalStorage.saveString('selectedProjectId', selectedProjectId.value); } isProjectSelectionExpanded.value = false; @@ -73,10 +73,9 @@ class ProjectController extends GetxController { } Future updateSelectedProject(String projectId) async { - selectedProjectId?.value = projectId; + selectedProjectId.value = projectId; + await LocalStorage.saveString('selectedProjectId', projectId); - update([ - 'selected_project' - ]); + update(['selected_project']); } } diff --git a/lib/view/dashboard/dashboard_chart.dart b/lib/view/dashboard/dashboard_chart.dart index d4edec1..83150cc 100644 --- a/lib/view/dashboard/dashboard_chart.dart +++ b/lib/view/dashboard/dashboard_chart.dart @@ -62,6 +62,7 @@ class AttendanceDashboardChart extends StatelessWidget { @override Widget build(BuildContext context) { return Obx(() { + // Now this observes `controller.roleWiseData`, `isLoading`, `isChartView`, etc. final isChartView = controller.isChartView.value; final selectedRange = controller.selectedRange.value; final isLoading = controller.isLoading.value; @@ -226,6 +227,8 @@ class AttendanceDashboardChart extends StatelessWidget { name: role, legendIconType: LegendIconType.circle, dataLabelSettings: const DataLabelSettings(isVisible: true), + dataLabelMapper: (d, _) => + d['present'] == 0 ? '' : d['present'].toString(), color: _getRoleColor(role), ); }).toList(),