import 'dart:ui'; import 'package:flutter/material.dart'; import '../../theme/app_colors.dart'; import '../../theme/app_theme.dart'; /// Glassmorphism card widget with blur effect class GlassCard extends StatelessWidget { final Widget child; final EdgeInsetsGeometry padding; final double borderRadius; final VoidCallback? onTap; final bool showBorder; const GlassCard({ super.key, required this.child, this.padding = const EdgeInsets.all(16), this.borderRadius = 12, this.onTap, this.showBorder = true, }); @override Widget build(BuildContext context) { return ClipRRect( borderRadius: BorderRadius.circular(borderRadius), child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), child: Material( color: AppColors.glassBackground, child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(borderRadius), child: Container( padding: padding, decoration: BoxDecoration( borderRadius: BorderRadius.circular(borderRadius), border: showBorder ? Border.all(color: AppColors.glassBorder, width: 1) : null, ), child: child, ), ), ), ), ); } } /// Animated gradient button class GradientButton extends StatefulWidget { final String label; final VoidCallback? onPressed; final IconData? icon; final bool isLoading; final bool isExpanded; const GradientButton({ super.key, required this.label, this.onPressed, this.icon, this.isLoading = false, this.isExpanded = false, }); @override State createState() => _GradientButtonState(); } class _GradientButtonState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _scaleAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: AppTheme.durationFast, vsync: this, ); _scaleAnimation = Tween(begin: 1.0, end: 0.95).animate( CurvedAnimation(parent: _controller, curve: AppTheme.curveDefault), ); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final button = AnimatedBuilder( animation: _scaleAnimation, builder: (context, child) { return Transform.scale( scale: _scaleAnimation.value, child: child, ); }, child: Container( decoration: BoxDecoration( gradient: AppColors.primaryGradient, borderRadius: BorderRadius.circular(AppTheme.radiusSm), boxShadow: [ BoxShadow( color: AppColors.primary.withOpacity(0.3), blurRadius: 12, offset: const Offset(0, 4), ), ], ), child: Material( color: Colors.transparent, child: InkWell( onTap: widget.isLoading ? null : widget.onPressed, onTapDown: (_) => _controller.forward(), onTapUp: (_) => _controller.reverse(), onTapCancel: () => _controller.reverse(), borderRadius: BorderRadius.circular(AppTheme.radiusSm), child: Padding( padding: const EdgeInsets.symmetric( horizontal: 24, vertical: 14, ), child: widget.isLoading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.black, ), ) : Row( mainAxisSize: widget.isExpanded ? MainAxisSize.max : MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ if (widget.icon != null) ...[ Icon(widget.icon, color: Colors.black, size: 20), const SizedBox(width: 8), ], Text( widget.label, style: const TextStyle( color: Colors.black, fontWeight: FontWeight.w600, fontSize: 14, ), ), ], ), ), ), ), ), ); return widget.isExpanded ? SizedBox(width: double.infinity, child: button) : button; } } /// Shimmer loading effect widget class ShimmerLoading extends StatefulWidget { final double width; final double height; final double borderRadius; const ShimmerLoading({ super.key, this.width = double.infinity, required this.height, this.borderRadius = 8, }); @override State createState() => _ShimmerLoadingState(); } class _ShimmerLoadingState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _animation; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 1500), vsync: this, )..repeat(); _animation = Tween(begin: -2, end: 2).animate(_controller); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _animation, builder: (context, child) { return Container( width: widget.width, height: widget.height, decoration: BoxDecoration( borderRadius: BorderRadius.circular(widget.borderRadius), gradient: LinearGradient( begin: Alignment(_animation.value - 1, 0), end: Alignment(_animation.value + 1, 0), colors: const [ AppColors.surfaceVariant, AppColors.surface, AppColors.surfaceVariant, ], ), ), ); }, ); } } /// Live indicator badge class LiveBadge extends StatelessWidget { const LiveBadge({super.key}); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: AppColors.live, borderRadius: BorderRadius.circular(4), ), child: const Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.circle, size: 6, color: Colors.white), SizedBox(width: 4), Text( 'LIVE', style: TextStyle( color: Colors.white, fontSize: 10, fontWeight: FontWeight.w700, ), ), ], ), ); } } /// Category chip with color class CategoryChip extends StatelessWidget { final String label; final bool isSelected; final VoidCallback? onTap; const CategoryChip({ super.key, required this.label, this.isSelected = false, this.onTap, }); @override Widget build(BuildContext context) { return Material( color: isSelected ? AppColors.primary.withOpacity(0.2) : AppColors.surfaceVariant, borderRadius: BorderRadius.circular(AppTheme.radiusFull), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(AppTheme.radiusFull), child: Container( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(AppTheme.radiusFull), border: Border.all( color: isSelected ? AppColors.primary : AppColors.border, ), ), child: Text( label, style: TextStyle( fontSize: 13, fontWeight: isSelected ? FontWeight.w600 : FontWeight.w500, color: isSelected ? AppColors.primary : AppColors.textSecondary, ), ), ), ), ); } }