import 'package:flutter/material.dart'; class PrintingStatusCard extends StatefulWidget { final bool isVisible; final VoidCallback? onDismiss; const PrintingStatusCard({ super.key, required this.isVisible, this.onDismiss, }); @override State createState() => _PrintingStatusCardState(); } class _PrintingStatusCardState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _scaleAnimation; late Animation _fadeAnimation; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 300), vsync: this, ); _scaleAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _controller, curve: Curves.elasticOut, )); _fadeAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _controller, curve: Curves.easeInOut, )); // Start animation when widget is visible if (widget.isVisible) { _controller.forward(); } } @override void didUpdateWidget(covariant PrintingStatusCard oldWidget) { super.didUpdateWidget(oldWidget); if (widget.isVisible && !oldWidget.isVisible) { _controller.forward(); } else if (!widget.isVisible && oldWidget.isVisible) { _controller.reverse(); } } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AnimatedBuilder( animation: _controller, builder: (context, child) { return Visibility( visible: widget.isVisible, child: Positioned( top: 100, left: MediaQuery.of(context).size.width * 0.1, right: MediaQuery.of(context).size.width * 0.1, child: IgnorePointer( ignoring: !_fadeAnimation.value.isNaN && _fadeAnimation.value < 0.5, child: Opacity( opacity: _fadeAnimation.value, child: Transform.scale( scale: _scaleAnimation.value, child: Card( elevation: 12, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), ), child: Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: const [ Color(0xFF6A11CB), Color(0xFF2575FC), ], ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ const SizedBox(width: 8), const Icon( Icons.print, color: Colors.white, size: 36, ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ const Text( 'Mencetak Struk', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), ), const SizedBox(height: 4), const Text( 'Mohon tunggu...', style: TextStyle( fontSize: 16, color: Colors.white70, ), ), const SizedBox(height: 12), LinearProgressIndicator( backgroundColor: Colors.white30, color: Colors.white, minHeight: 6, value: null, ), ], ), ), IconButton( icon: const Icon(Icons.close, color: Colors.white70), onPressed: widget.onDismiss, ), ], ), ), ), ), ), ), ), ); }, ); } }