import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:marco/helpers/theme/app_theme.dart'; import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; import 'package:marco/helpers/utils/my_shadow.dart'; import 'package:marco/helpers/widgets/my_breadcrumb.dart'; import 'package:marco/helpers/widgets/my_breadcrumb_item.dart'; import 'package:marco/helpers/widgets/my_card.dart'; import 'package:marco/helpers/widgets/my_spacing.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/view/layouts/layout.dart'; import 'package:marco/controller/permission_controller.dart'; import 'package:marco/model/dailyTaskPlaning/daily_task_planing_filter.dart'; import 'package:marco/controller/task_planing/daily_task_planing_controller.dart'; import 'package:marco/model/dailyTaskPlaning/assign_task_bottom_sheet .dart'; class DailyTaskPlaningScreen extends StatefulWidget { DailyTaskPlaningScreen({super.key}); @override State createState() => _DailyTaskPlaningScreenState(); } class _DailyTaskPlaningScreenState extends State with UIMixin { final DailyTaskPlaningController dailyTaskPlaningController = Get.put(DailyTaskPlaningController()); final PermissionController permissionController = Get.put(PermissionController()); @override Widget build(BuildContext context) { return Layout( child: GetBuilder( init: dailyTaskPlaningController, tag: 'daily_task_planing_controller', builder: (controller) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: MySpacing.x(flexSpacing), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ MyText.titleMedium("Daily Task Planning", fontSize: 18, fontWeight: 600), MyBreadcrumb( children: [ MyBreadcrumbItem(name: 'Dashboard'), MyBreadcrumbItem( name: 'Daily Task Planning', active: true), ], ), ], ), ), MySpacing.height(flexSpacing), Padding( padding: MySpacing.x(flexSpacing), child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ MyText.bodyMedium( "Filter", fontWeight: 600, ), Tooltip( message: 'Project', child: InkWell( borderRadius: BorderRadius.circular(24), onTap: () async { final result = await showModalBottomSheet>( context: context, isScrollControlled: true, backgroundColor: Colors.white, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( top: Radius.circular(12)), ), builder: (context) => DailyTaskPlaningFilter( controller: dailyTaskPlaningController, permissionController: permissionController, ), ); if (result != null) { final selectedProjectId = result['projectId'] as String?; if (selectedProjectId != null && selectedProjectId != dailyTaskPlaningController .selectedProjectId) { // Update the controller's selected project ID dailyTaskPlaningController.selectedProjectId = selectedProjectId; try { // Fetch tasks for the new project await dailyTaskPlaningController .fetchTaskData(selectedProjectId); } catch (e) { debugPrint( 'Error fetching task data: ${e.toString()}'); } // Update the UI dailyTaskPlaningController .update(['daily_task_planing_controller']); } } }, child: MouseRegion( cursor: SystemMouseCursors.click, child: Padding( padding: const EdgeInsets.all(8.0), child: Icon( Icons.filter_list_alt, color: Colors.blueAccent, size: 28, ), ), ), ), ), const SizedBox(width: 8), MyText.bodyMedium( "Refresh", fontWeight: 600, ), Tooltip( message: 'Refresh Data', child: InkWell( borderRadius: BorderRadius.circular(24), onTap: () async { final projectId = dailyTaskPlaningController.selectedProjectId; if (projectId != null) { try { await dailyTaskPlaningController .fetchTaskData(projectId); } catch (e) { debugPrint( 'Error refreshing task data: ${e.toString()}'); } } }, child: MouseRegion( cursor: SystemMouseCursors.click, child: Padding( padding: const EdgeInsets.all(8.0), child: Icon( Icons.refresh, color: Colors.green, size: 28, ), ), ), ), ), ], ), ), Padding( padding: MySpacing.x(flexSpacing), child: dailyProgressReportTab(), ), ], ); }, ), ); } Widget dailyProgressReportTab() { return Obx(() { final isLoading = dailyTaskPlaningController.isLoading.value; final dailyTasks = dailyTaskPlaningController.dailyTasks; if (isLoading) { return Center(child: CircularProgressIndicator()); } if (dailyTasks.isEmpty) { return Center( child: MyText.bodySmall( "No Progress Report Found", fontWeight: 600, ), ); } final buildingExpansionState = {}; final floorExpansionState = {}; Widget buildExpandIcon(bool isExpanded) { return Container( width: 32, height: 32, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.grey.shade200, ), child: Icon( isExpanded ? Icons.remove : Icons.add, size: 20, color: Colors.black87, ), ); } return StatefulBuilder(builder: (context, setMainState) { final filteredBuildings = dailyTasks.expand((task) { return task.buildings.where((building) { return building.floors.any((floor) => floor.workAreas.any((area) => area.workItems.isNotEmpty)); }); }).toList(); if (filteredBuildings.isEmpty) { return Center( child: MyText.bodySmall( "No Progress Report Found", fontWeight: 600, ), ); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: filteredBuildings.map((building) { final buildingKey = building.id.toString(); return MyCard.bordered( borderRadiusAll: 12, paddingAll: 0, margin: MySpacing.bottom(12), shadow: MyShadow(elevation: 3), child: Theme( data: Theme.of(context) .copyWith(dividerColor: Colors.transparent), child: ExpansionTile( onExpansionChanged: (expanded) { setMainState(() { buildingExpansionState[buildingKey] = expanded; }); }, trailing: buildExpandIcon( buildingExpansionState[buildingKey] ?? false), tilePadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0), collapsedShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), leading: Container( decoration: BoxDecoration( color: Colors.blueAccent.withOpacity(0.1), shape: BoxShape.circle, ), padding: const EdgeInsets.all(8), child: Icon( Icons.location_city_rounded, color: Colors.blueAccent, size: 24, ), ), title: MyText.titleMedium( building.name, fontWeight: 700, maxLines: 1, overflow: TextOverflow.ellipsis, ), childrenPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0), children: building.floors.expand((floor) { final validWorkAreas = floor.workAreas .where((area) => area.workItems.isNotEmpty); // For each valid work area, return a Floor+WorkArea ExpansionTile return validWorkAreas.map((area) { final floorWorkAreaKey = "${buildingKey}_${floor.floorName}_${area.areaName}"; final isExpanded = floorExpansionState[floorWorkAreaKey] ?? false; return ExpansionTile( onExpansionChanged: (expanded) { setMainState(() { floorExpansionState[floorWorkAreaKey] = expanded; }); }, trailing: Icon( isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, size: 28, color: Colors.black54, ), tilePadding: const EdgeInsets.symmetric( horizontal: 16, vertical: 0), title: Wrap( spacing: 16, crossAxisAlignment: WrapCrossAlignment.center, children: [ MyText.titleSmall( "Floor: ${floor.floorName}", fontWeight: 600, color: Colors.teal, maxLines: null, overflow: TextOverflow.visible, softWrap: true, ), MyText.titleSmall( "Work Area: ${area.areaName}", fontWeight: 600, color: Colors.blueGrey, maxLines: null, overflow: TextOverflow.visible, softWrap: true, ), ], ), childrenPadding: const EdgeInsets.only( left: 16, right: 0, bottom: 8), children: area.workItems.map((wItem) { final item = wItem.workItem; final completed = item.completedWork ?? 0; final planned = item.plannedWork ?? 0; final progress = (planned == 0) ? 0.0 : (completed / planned).clamp(0.0, 1.0); return Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: MyText.bodyMedium( item.activityMaster?.name ?? "No Activity", fontWeight: 600, maxLines: 2, overflow: TextOverflow.visible, softWrap: true, ), ), MySpacing.width(8), if (item.workCategoryMaster?.name != null) Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 4), decoration: BoxDecoration( color: Colors.blue.shade100, borderRadius: BorderRadius.circular(20), ), child: MyText.bodySmall( item.workCategoryMaster!.name!, fontWeight: 500, color: Colors.blue.shade800, ), ), ], ), MySpacing.height(4), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( flex: 3, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MySpacing.height(8), MyText.bodySmall( "Completed: $completed / $planned", fontWeight: 600, color: const Color.fromARGB( 221, 0, 0, 0), ), ], ), ), MySpacing.width(16), if (progress < 1.0) IconButton( icon: Icon( Icons.person_add_alt_1_rounded, color: const Color.fromARGB( 255, 46, 161, 233), ), onPressed: () { final pendingTask = (planned - completed) .clamp(0, planned); showModalBottomSheet( context: context, isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.vertical( top: Radius.circular(16)), ), builder: (context) => AssignTaskBottomSheet( buildingName: building.name, floorName: floor.floorName, workAreaName: area.areaName, workLocation: area.areaName, activityName: item.activityMaster?.name ?? "Unknown Activity", pendingTask: pendingTask, workItemId: item.id.toString(), assignmentDate: DateTime.now(), ), ); }, ), ], ), MySpacing.height(8), Stack( children: [ Container( height: 5, decoration: BoxDecoration( color: Colors.grey[300], borderRadius: BorderRadius.circular(6), ), ), FractionallySizedBox( widthFactor: progress, child: Container( height: 5, decoration: BoxDecoration( color: progress >= 1.0 ? Colors.green : (progress >= 0.5 ? Colors.amber : Colors.red), borderRadius: BorderRadius.circular(6), ), ), ), ], ), SizedBox(height: 4), MyText.bodySmall( "${(progress * 100).toStringAsFixed(1)}%", fontWeight: 500, color: progress >= 1.0 ? Colors.green[700] : (progress >= 0.5 ? Colors.amber[800] : Colors.red[700]), ), ], ), ); }).toList(), ); }).toList(); }).toList(), ), ), ); }).toList(), ); }); }); } }