import 'package:flutter/material.dart'; import 'package:uto_manager/domain/entities/personnel_record.dart'; import 'package:uto_manager/presentation/widgets/position_slot_card.dart' show PositionSlotCard; /// A draggable list tile representing a soldier in the personnel panel. /// /// Can be dragged onto a [PositionSlotCard] to assign the soldier. /// Tap to edit; long-press for a context menu with edit/delete options. class PersonnelListTile extends StatelessWidget { const PersonnelListTile({ required this.record, super.key, this.onTap, this.onDelete, }); final PersonnelRecord record; /// Called when the tile is tapped (opens edit dialog). final VoidCallback? onTap; /// Called when the user selects Delete from the context menu. final VoidCallback? onDelete; @override Widget build(BuildContext context) { final theme = Theme.of(context); return Draggable( data: record, feedback: Material( elevation: 6, borderRadius: BorderRadius.circular(8), child: Container( width: 220, padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: theme.colorScheme.primaryContainer, borderRadius: BorderRadius.circular(8), ), child: Row( children: [ Icon(Icons.person, color: theme.colorScheme.onPrimaryContainer, size: 20), const SizedBox(width: 8), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( record.displayLabel, style: theme.textTheme.bodySmall?.copyWith( fontWeight: FontWeight.bold, color: theme.colorScheme.onPrimaryContainer, ), ), Text( '${record.payGrade.payGrade} • ${record.primaryMos.code}', style: theme.textTheme.labelSmall?.copyWith( color: theme.colorScheme.onPrimaryContainer.withValues(alpha: 0.8), ), ), ], ), ), ], ), ), ), childWhenDragging: Opacity( opacity: 0.4, child: _buildTile(theme), ), child: _buildTile(theme), ); } Widget _buildTile(ThemeData theme) { return ListTile( dense: true, onTap: onTap, leading: CircleAvatar( radius: 16, backgroundColor: _readinessColor(record.readinessState).withValues(alpha: 0.2), child: Text( record.payGrade.payGrade, style: TextStyle( fontSize: 9, fontWeight: FontWeight.bold, color: _readinessColor(record.readinessState), ), ), ), title: Text( record.displayLabel, style: theme.textTheme.bodySmall?.copyWith(fontWeight: FontWeight.w600), ), subtitle: Text( '${record.primaryMos.code} • ${record.readinessState.displayName}', style: theme.textTheme.labelSmall?.copyWith( color: _readinessColor(record.readinessState), ), ), trailing: Icon( Icons.drag_indicator, size: 16, color: theme.colorScheme.onSurfaceVariant, ), ); } Color _readinessColor(ReadinessState state) { switch (state) { case ReadinessState.fullyMissionCapable: return const Color(0xFF4CAF50); case ReadinessState.partiallyMissionCapable: return const Color(0xFFFF9800); case ReadinessState.notMissionCapable: return const Color(0xFFF44336); case ReadinessState.unknown: return Colors.grey; } } }