import 'package:flutter/material.dart'; import 'dart:ui' as ui; import '../models/delivery_route.dart'; import '../theme/spacing_system.dart'; import '../theme/size_system.dart'; import '../theme/animation_system.dart'; import '../theme/color_system.dart'; /// Modern glassmorphic route card with status-based gradient and animated progress class GlassmorphicRouteCard extends StatefulWidget { final DeliveryRoute route; final bool isSelected; final VoidCallback onTap; final bool isCollapsed; const GlassmorphicRouteCard({ super.key, required this.route, required this.isSelected, required this.onTap, this.isCollapsed = false, }); @override State createState() => _GlassmorphicRouteCardState(); } class _GlassmorphicRouteCardState extends State with SingleTickerProviderStateMixin { late AnimationController _hoverController; @override void initState() { super.initState(); _hoverController = AnimationController( duration: Duration(milliseconds: AppAnimations.durationFast.inMilliseconds), vsync: this, ); } @override void dispose() { _hoverController.dispose(); super.dispose(); } /// Calculate color based on completion percentage Color _getProgressColor(double progress) { if (progress < 0.3) { // Red to orange (0-30%) return Color.lerp( SvrntyColors.crimsonRed, const Color(0xFFFF9800), (progress / 0.3), )!; } else if (progress < 0.7) { // Orange to yellow (30-70%) return Color.lerp( const Color(0xFFFF9800), const Color(0xFFFFC107), ((progress - 0.3) / 0.4), )!; } else { // Yellow to green (70-100%) return Color.lerp( const Color(0xFFFFC107), const Color(0xFF4CAF50), ((progress - 0.7) / 0.3), )!; } } void _setHovered(bool hovered) { if (hovered) { _hoverController.forward(); } else { _hoverController.reverse(); } } @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; final progress = widget.route.deliveredCount / widget.route.deliveriesCount; final progressColor = _getProgressColor(progress); if (widget.isCollapsed) { return _buildCollapsedCard(context, isDarkMode, progress, progressColor); } return _buildExpandedCard(context, isDarkMode, progress, progressColor); } Widget _buildCollapsedCard(BuildContext context, bool isDarkMode, double progress, Color progressColor) { return MouseRegion( onEnter: (_) => _setHovered(true), onExit: (_) => _setHovered(false), child: GestureDetector( onTap: widget.onTap, child: AnimatedContainer( duration: Duration( milliseconds: AppAnimations.durationFast.inMilliseconds, ), height: AppSizes.buttonHeightMd, decoration: BoxDecoration( borderRadius: BorderRadius.circular(AppSpacing.md), ), child: Stack( alignment: Alignment.center, children: [ // Glassmorphic background ClipRRect( borderRadius: BorderRadius.circular(AppSpacing.md), child: BackdropFilter( filter: ui.ImageFilter.blur(sigmaX: 8, sigmaY: 8), child: Container( decoration: BoxDecoration( color: (isDarkMode ? SvrntyColors.darkSlate : Colors.white) .withValues(alpha: 0.7), border: Border.all( color: (isDarkMode ? Colors.white : Colors.white) .withValues(alpha: 0.2), width: 1.5, ), ), ), ), ), // Progress indicator at bottom Positioned( bottom: 0, left: 0, right: 0, child: ClipRRect( borderRadius: BorderRadius.only( bottomLeft: Radius.circular(AppSpacing.md - AppSpacing.xs), bottomRight: Radius.circular(AppSpacing.md - AppSpacing.xs), ), child: LinearProgressIndicator( value: progress, minHeight: 3, backgroundColor: progressColor.withValues(alpha: 0.2), valueColor: AlwaysStoppedAnimation(progressColor), ), ), ), // Content Center( child: Text( widget.route.name.substring(0, 1).toUpperCase(), style: Theme.of(context).textTheme.labelLarge?.copyWith( fontWeight: FontWeight.bold, fontSize: 16, color: widget.isSelected ? progressColor : null, ), ), ), ], ), ), ), ); } Widget _buildExpandedCard(BuildContext context, bool isDarkMode, double progress, Color progressColor) { return MouseRegion( onEnter: (_) => _setHovered(true), onExit: (_) => _setHovered(false), child: GestureDetector( onTap: widget.onTap, child: AnimatedBuilder( animation: _hoverController, builder: (context, child) { final hoverValue = _hoverController.value; final blurSigma = 8 + (hoverValue * 3); final bgOpacity = 0.7 + (hoverValue * 0.1); return AnimatedContainer( duration: Duration( milliseconds: AppAnimations.durationFast.inMilliseconds, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(AppSpacing.lg), boxShadow: [ BoxShadow( color: progressColor.withValues(alpha: 0.1 + (hoverValue * 0.2)), blurRadius: 12 + (hoverValue * 8), offset: Offset(0, 2 + (hoverValue * 2)), ), ], ), child: Stack( children: [ // Glassmorphic background ClipRRect( borderRadius: BorderRadius.circular(AppSpacing.lg), child: BackdropFilter( filter: ui.ImageFilter.blur(sigmaX: blurSigma, sigmaY: blurSigma), child: Container( decoration: BoxDecoration( color: (isDarkMode ? SvrntyColors.darkSlate : Colors.white) .withValues(alpha: bgOpacity), border: Border.all( color: (isDarkMode ? Colors.white : Colors.white) .withValues(alpha: 0.2 + (hoverValue * 0.15)), width: 1.5, ), borderRadius: BorderRadius.circular(AppSpacing.lg), ), ), ), ), // Content Padding( padding: EdgeInsets.all(AppSpacing.md), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ // Route name Text( widget.route.name, style: Theme.of(context) .textTheme .labelLarge ?.copyWith( color: widget.isSelected ? progressColor : null, fontWeight: FontWeight.bold, fontSize: 14, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), SizedBox(height: AppSpacing.xs), // Delivery count RichText( text: TextSpan( children: [ TextSpan( text: '${widget.route.deliveredCount}', style: Theme.of(context) .textTheme .bodySmall ?.copyWith( color: progressColor, fontWeight: FontWeight.w600, fontSize: 11, ), ), TextSpan( text: '/${widget.route.deliveriesCount}', style: Theme.of(context) .textTheme .bodySmall ?.copyWith( fontSize: 11, color: (Theme.of(context).brightness == Brightness.dark ? Colors.white : Colors.black) .withValues(alpha: 0.6), ), ), ], ), ), SizedBox(height: AppSpacing.sm), // Animated gradient progress bar ClipRRect( borderRadius: BorderRadius.circular(3), child: Stack( children: [ // Background Container( height: 6, decoration: BoxDecoration( color: progressColor .withValues(alpha: 0.15), ), ), // Progress fill with gradient ClipRRect( borderRadius: BorderRadius.circular(3), child: Container( height: 6, width: 100 * progress, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ SvrntyColors.crimsonRed, progressColor, ], ), borderRadius: BorderRadius.circular(3), boxShadow: [ BoxShadow( color: progressColor .withValues(alpha: 0.4), blurRadius: 4, ), ], ), ), ), ], ), ), ], ), ), ], ), ); }, ), ), ); } }