import 'package:flutter/material.dart'; import 'package:hesabix_ui/l10n/app_localizations.dart'; import 'dart:async'; class ProgressSplashScreen extends StatefulWidget { final String? message; final bool showLogo; final Color? backgroundColor; final Color? primaryColor; final Duration minimumDisplayDuration; final VoidCallback? onComplete; const ProgressSplashScreen({ super.key, this.message, this.showLogo = true, this.backgroundColor, this.primaryColor, this.minimumDisplayDuration = const Duration(seconds: 2), this.onComplete, }); @override State createState() => _ProgressSplashScreenState(); } class _ProgressSplashScreenState extends State with TickerProviderStateMixin { late AnimationController _fadeController; late AnimationController _scaleController; late AnimationController _progressController; late Animation _fadeAnimation; late Animation _scaleAnimation; late Animation _progressAnimation; Timer? _countdownTimer; int _remainingSeconds = 0; @override void initState() { super.initState(); _remainingSeconds = widget.minimumDisplayDuration.inSeconds; _fadeController = AnimationController( duration: const Duration(milliseconds: 800), vsync: this, ); _scaleController = AnimationController( duration: const Duration(milliseconds: 600), vsync: this, ); _progressController = AnimationController( duration: widget.minimumDisplayDuration, vsync: this, ); _fadeAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _fadeController, curve: Curves.easeInOut, )); _scaleAnimation = Tween( begin: 0.8, end: 1.0, ).animate(CurvedAnimation( parent: _scaleController, curve: Curves.elasticOut, )); _progressAnimation = Tween( begin: 0.0, end: 1.0, ).animate(CurvedAnimation( parent: _progressController, curve: Curves.easeInOut, )); // Start animations _fadeController.forward(); _scaleController.forward(); _progressController.forward(); // Start countdown timer _startCountdown(); } void _startCountdown() { _countdownTimer = Timer.periodic(const Duration(seconds: 1), (timer) { if (mounted) { setState(() { _remainingSeconds = widget.minimumDisplayDuration.inSeconds - timer.tick; if (_remainingSeconds <= 0) { timer.cancel(); widget.onComplete?.call(); } }); } }); } @override void dispose() { _fadeController.dispose(); _scaleController.dispose(); _progressController.dispose(); _countdownTimer?.cancel(); super.dispose(); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; final isDark = theme.brightness == Brightness.dark; final bgColor = widget.backgroundColor ?? colorScheme.surface; final primary = widget.primaryColor ?? colorScheme.primary; return Scaffold( backgroundColor: bgColor, body: Container( width: double.infinity, height: double.infinity, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: isDark ? [ bgColor, bgColor.withOpacity(0.95), ] : [ bgColor, bgColor.withOpacity(0.98), ], ), ), child: AnimatedBuilder( animation: Listenable.merge([_fadeAnimation, _scaleAnimation, _progressAnimation]), builder: (context, child) { return Transform.scale( scale: _scaleAnimation.value, child: Opacity( opacity: _fadeAnimation.value, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Logo Section if (widget.showLogo) ...[ Container( width: 120, height: 120, decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: primary.withOpacity(0.2), blurRadius: 20, spreadRadius: 2, ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(20), child: Image.asset( isDark ? 'assets/images/logo-light.png' : 'assets/images/logo-blue.png', fit: BoxFit.contain, errorBuilder: (context, error, stackTrace) { return Container( decoration: BoxDecoration( color: primary, borderRadius: BorderRadius.circular(20), ), child: Icon( Icons.account_balance, size: 60, color: colorScheme.onPrimary, ), ); }, ), ), ), const SizedBox(height: 32), ], // App Name Text( 'Hesabix', style: theme.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, color: colorScheme.onSurface, letterSpacing: 1.2, ), ), const SizedBox(height: 8), // Subtitle Text( AppLocalizations.of(context)?.businessManagementPlatform ?? 'Business Management Platform', style: theme.textTheme.bodyLarge?.copyWith( color: colorScheme.onSurfaceVariant, fontWeight: FontWeight.w400, ), ), const SizedBox(height: 48), // Loading Indicator with Progress Column( children: [ SizedBox( width: 40, height: 40, child: CircularProgressIndicator( strokeWidth: 3, valueColor: AlwaysStoppedAnimation(primary), ), ), const SizedBox(height: 24), // Progress Bar Container( width: 200, height: 4, decoration: BoxDecoration( borderRadius: BorderRadius.circular(2), color: colorScheme.surfaceContainerHighest, ), child: AnimatedBuilder( animation: _progressAnimation, builder: (context, child) { return FractionallySizedBox( alignment: Alignment.centerLeft, widthFactor: _progressAnimation.value, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(2), gradient: LinearGradient( colors: [primary, primary.withOpacity(0.8)], ), ), ), ); }, ), ), const SizedBox(height: 16), // Loading Message Text( widget.message ?? AppLocalizations.of(context)?.loading ?? 'Loading...', style: theme.textTheme.bodyMedium?.copyWith( color: colorScheme.onSurfaceVariant, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 8), // Countdown Timer if (_remainingSeconds > 0) Text( '${_remainingSeconds}s', style: theme.textTheme.bodySmall?.copyWith( color: colorScheme.onSurfaceVariant.withOpacity(0.7), fontWeight: FontWeight.w400, ), ), ], ), const SizedBox(height: 80), // Version Info Text( 'Version 1.0.0', style: theme.textTheme.bodySmall?.copyWith( color: colorScheme.onSurfaceVariant.withOpacity(0.6), ), ), ], ), ), ); }, ), ), ); } }