import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:trainhub_flutter/core/constants/ui_constants.dart'; import 'package:trainhub_flutter/core/theme/app_colors.dart'; import 'package:trainhub_flutter/domain/entities/program.dart'; class ProgramSelector extends StatelessWidget { final List programs; final ProgramEntity? activeProgram; final ValueChanged onProgramSelected; final VoidCallback onCreateProgram; final VoidCallback onDuplicateProgram; final VoidCallback onDeleteProgram; const ProgramSelector({ super.key, required this.programs, required this.activeProgram, required this.onProgramSelected, required this.onCreateProgram, required this.onDuplicateProgram, required this.onDeleteProgram, }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric( horizontal: UIConstants.pagePadding, vertical: UIConstants.spacing12, ), decoration: const BoxDecoration( color: AppColors.surfaceContainer, border: Border( bottom: BorderSide(color: AppColors.border), ), ), child: Row( children: [ // Program icon Container( width: 36, height: 36, decoration: BoxDecoration( color: AppColors.accentMuted, borderRadius: BorderRadius.circular(UIConstants.smallBorderRadius), ), child: const Icon( Icons.calendar_month_rounded, color: AppColors.accent, size: 18, ), ), const SizedBox(width: UIConstants.spacing12), // Program dropdown Expanded( child: _ProgramDropdown( programs: programs, activeProgram: activeProgram, onProgramSelected: onProgramSelected, ), ), const SizedBox(width: UIConstants.spacing12), // Action buttons _ToolbarButton( icon: Icons.add_rounded, label: 'New Program', onPressed: onCreateProgram, isPrimary: true, ), const SizedBox(width: UIConstants.spacing8), _ToolbarButton( icon: Icons.copy_rounded, label: 'Duplicate', onPressed: activeProgram != null ? onDuplicateProgram : null, ), const SizedBox(width: UIConstants.spacing8), _ToolbarButton( icon: Icons.delete_outline_rounded, label: 'Delete', onPressed: activeProgram != null ? onDeleteProgram : null, isDestructive: true, ), ], ), ); } } class _ProgramDropdown extends StatelessWidget { final List programs; final ProgramEntity? activeProgram; final ValueChanged onProgramSelected; const _ProgramDropdown({ required this.programs, required this.activeProgram, required this.onProgramSelected, }); @override Widget build(BuildContext context) { return Container( height: 38, padding: const EdgeInsets.symmetric(horizontal: UIConstants.spacing12), decoration: BoxDecoration( color: AppColors.zinc950, borderRadius: BorderRadius.circular(UIConstants.smallBorderRadius), border: Border.all(color: AppColors.border), ), child: DropdownButtonHideUnderline( child: DropdownButton( value: activeProgram?.id, isExpanded: true, icon: const Icon( Icons.unfold_more_rounded, size: 18, color: AppColors.textMuted, ), dropdownColor: AppColors.surfaceContainer, borderRadius: BorderRadius.circular(UIConstants.smallBorderRadius), style: GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w500, color: AppColors.textPrimary, ), hint: Text( 'Select a program', style: GoogleFonts.inter( fontSize: 14, color: AppColors.textMuted, ), ), items: programs.map((p) { return DropdownMenuItem( value: p.id, child: Text( p.name, overflow: TextOverflow.ellipsis, ), ); }).toList(), onChanged: (id) { if (id != null) { final program = programs.firstWhere((p) => p.id == id); onProgramSelected(program); } }, ), ), ); } } class _ToolbarButton extends StatefulWidget { final IconData icon; final String label; final VoidCallback? onPressed; final bool isPrimary; final bool isDestructive; const _ToolbarButton({ required this.icon, required this.label, required this.onPressed, this.isPrimary = false, this.isDestructive = false, }); @override State<_ToolbarButton> createState() => _ToolbarButtonState(); } class _ToolbarButtonState extends State<_ToolbarButton> { bool _isHovered = false; @override Widget build(BuildContext context) { final isDisabled = widget.onPressed == null; Color bgColor; Color fgColor; Color borderColor; if (isDisabled) { bgColor = Colors.transparent; fgColor = AppColors.zinc600; borderColor = AppColors.border; } else if (widget.isPrimary) { bgColor = _isHovered ? AppColors.accent : AppColors.accentMuted; fgColor = _isHovered ? AppColors.zinc950 : AppColors.accent; borderColor = AppColors.accent.withValues(alpha: 0.3); } else if (widget.isDestructive) { bgColor = _isHovered ? AppColors.destructiveMuted : Colors.transparent; fgColor = _isHovered ? AppColors.destructive : AppColors.textSecondary; borderColor = _isHovered ? AppColors.destructive.withValues(alpha: 0.3) : AppColors.border; } else { bgColor = _isHovered ? AppColors.surfaceContainerHigh : Colors.transparent; fgColor = _isHovered ? AppColors.textPrimary : AppColors.textSecondary; borderColor = AppColors.border; } return MouseRegion( onEnter: (_) => setState(() => _isHovered = true), onExit: (_) => setState(() => _isHovered = false), child: Tooltip( message: widget.label, child: Material( color: Colors.transparent, child: InkWell( onTap: widget.onPressed, borderRadius: BorderRadius.circular(UIConstants.smallBorderRadius), child: AnimatedContainer( duration: UIConstants.animationDuration, height: 34, padding: const EdgeInsets.symmetric( horizontal: UIConstants.spacing12, ), decoration: BoxDecoration( color: bgColor, borderRadius: BorderRadius.circular(UIConstants.smallBorderRadius), border: Border.all(color: borderColor), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(widget.icon, size: 16, color: fgColor), const SizedBox(width: UIConstants.spacing4), Text( widget.label, style: GoogleFonts.inter( fontSize: 13, fontWeight: FontWeight.w500, color: fgColor, ), ), ], ), ), ), ), ), ); } }