import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:marco/helpers/widgets/my_spacing.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/helpers/widgets/my_snackbar.dart'; import 'package:marco/controller/employee/assign_projects_controller.dart'; import 'package:marco/model/global_project_model.dart'; import 'package:marco/helpers/utils/base_bottom_sheet.dart'; class AssignProjectBottomSheet extends StatefulWidget { final String employeeId; final String jobRoleId; const AssignProjectBottomSheet({ super.key, required this.employeeId, required this.jobRoleId, }); @override State createState() => _AssignProjectBottomSheetState(); } class _AssignProjectBottomSheetState extends State { late final AssignProjectController assignController; final ScrollController _scrollController = ScrollController(); @override void initState() { super.initState(); assignController = Get.put( AssignProjectController( employeeId: widget.employeeId, jobRoleId: widget.jobRoleId, ), tag: '${widget.employeeId}_${widget.jobRoleId}', ); } @override Widget build(BuildContext context) { return GetBuilder( tag: '${widget.employeeId}_${widget.jobRoleId}', builder: (_) { return BaseBottomSheet( title: "Assign to Project", onCancel: () => Navigator.pop(context), onSubmit: _handleAssign, submitText: "Assign", child: Obx(() { if (assignController.isLoading.value) { return const Center(child: CircularProgressIndicator()); } final projects = assignController.allProjects; if (projects.isEmpty) { return const Center(child: Text('No projects available.')); } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MyText.bodySmall( 'Select the projects to assign this employee.', color: Colors.grey[600], ), MySpacing.height(8), // Select All Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Projects (${projects.length})', style: const TextStyle( fontWeight: FontWeight.w600, fontSize: 16, ), ), TextButton( onPressed: () { assignController.toggleSelectAll(); }, child: Obx(() { return Text( assignController.areAllSelected() ? 'Deselect All' : 'Select All', style: const TextStyle( color: Colors.blueAccent, fontWeight: FontWeight.w600, ), ); }), ), ], ), // List of Projects SizedBox( height: 300, child: ListView.builder( controller: _scrollController, itemCount: projects.length, itemBuilder: (context, index) { final GlobalProjectModel project = projects[index]; return Obx(() { final bool isSelected = assignController.isProjectSelected( project.id.toString(), ); return Theme( data: Theme.of(context).copyWith( checkboxTheme: CheckboxThemeData( fillColor: WidgetStateProperty.resolveWith( (states) => states.contains(WidgetState.selected) ? Colors.blueAccent : Colors.white, ), side: const BorderSide( color: Colors.black, width: 2, ), checkColor: WidgetStateProperty.all(Colors.white), ), ), child: CheckboxListTile( dense: true, value: isSelected, title: Text( project.name, style: const TextStyle( fontWeight: FontWeight.w500, fontSize: 14, ), ), onChanged: (checked) { assignController.toggleProjectSelection( project.id.toString(), checked ?? false, ); }, activeColor: Colors.blueAccent, controlAffinity: ListTileControlAffinity.leading, contentPadding: EdgeInsets.zero, visualDensity: const VisualDensity( horizontal: -4, vertical: -4, ), ), ); }); }, ), ), ], ); }), ); }, ); } Future _handleAssign() async { if (assignController.selectedProjects.isEmpty) { showAppSnackbar( title: "Error", message: "Please select at least one project.", type: SnackbarType.error, ); return; } final success = await assignController.assignProjectsToEmployee(); if (success) { Get.back(); showAppSnackbar( title: "Success", message: "Employee assigned to selected projects.", type: SnackbarType.success, ); } else { showAppSnackbar( title: "Error", message: "Failed to assign employee.", type: SnackbarType.error, ); } } }