diff --git a/assets/images/money.svg b/assets/images/money.svg new file mode 100644 index 0000000..5a498c5 --- /dev/null +++ b/assets/images/money.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/no.svg b/assets/images/no.svg new file mode 100644 index 0000000..b7ea926 --- /dev/null +++ b/assets/images/no.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/plus.svg b/assets/images/plus.svg new file mode 100644 index 0000000..bac4bea --- /dev/null +++ b/assets/images/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/timer.svg b/assets/images/timer.svg new file mode 100644 index 0000000..7f53ce2 --- /dev/null +++ b/assets/images/timer.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/yes.svg b/assets/images/yes.svg new file mode 100644 index 0000000..092bb11 --- /dev/null +++ b/assets/images/yes.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/screens/attendence_screen.dart b/lib/screens/attendence_screen.dart index 40b13d1..cfa4f48 100644 --- a/lib/screens/attendence_screen.dart +++ b/lib/screens/attendence_screen.dart @@ -105,10 +105,11 @@ class AttendanceScreen extends StatelessWidget { // Navigate to LoginAnimationScreen with success state Navigator.of(context).push( MaterialPageRoute( - builder: (context) => LoginAnimationScreen( - isLogin: true, - isSuccess: true, // Set to true for success, false for error - ), + builder: + (context) => LoginAnimationScreen( + isLogin: true, + isSuccess: true, + ), ), ); }, @@ -124,24 +125,24 @@ class AttendanceScreen extends StatelessWidget { shadow: const [ // Strong BLACK shadow bottom-right BoxShadow( - color: Color(0xABCECECE), - blurRadius: 5, - spreadRadius: 3, - offset: Offset(-6, -6), - ), + color: Color(0xABCECECE), + blurRadius: 5, + spreadRadius: 3, + offset: Offset(-6, -6), + ), - // LIGHT GLOBAL GLOW - BoxShadow( - color: Color(0x92014221), - blurRadius: 10, - offset: Offset(-5, -5), - ), - BoxShadow( - color: Color(0x7D1A1A1A), - blurRadius: 10, - spreadRadius: 3, - offset: Offset(5, 5), - ), + // LIGHT GLOBAL GLOW + BoxShadow( + color: Color(0x92014221), + blurRadius: 10, + offset: Offset(-5, -5), + ), + BoxShadow( + color: Color(0x7D1A1A1A), + blurRadius: 10, + spreadRadius: 3, + offset: Offset(5, 5), + ), ], child: _FingerButton( icon: "assets/images/logout.svg", @@ -150,10 +151,11 @@ class AttendanceScreen extends StatelessWidget { // Navigate to LoginAnimationScreen with success state Navigator.of(context).push( MaterialPageRoute( - builder: (context) => LoginAnimationScreen( - isLogin: false, - isSuccess: true, // Set to true for success, false for error - ), + builder: + (context) => LoginAnimationScreen( + isLogin: true, + isSuccess: false, + ), ), ); }, @@ -200,7 +202,7 @@ class _FingerButton extends StatelessWidget { final VoidCallback onTap; // Added onTap callback const _FingerButton({ - required this.icon, + required this.icon, required this.label, required this.onTap, // Added this parameter }); @@ -234,4 +236,4 @@ class _FingerButton extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/lib/widgets/login_animation_screen.dart b/lib/widgets/login_animation_screen.dart index 812dda7..928590d 100644 --- a/lib/widgets/login_animation_screen.dart +++ b/lib/widgets/login_animation_screen.dart @@ -87,6 +87,50 @@ class _LoginAnimationScreenState extends State super.dispose(); } + // FIXED: Simplified _buildIcon method that returns the appropriate SVG + Widget _buildIcon() { + if (!showResult) { + // Loading state - fingerprint + return SvgPicture.asset( + "assets/images/finger_print.svg", + key: const ValueKey('fingerprint'), + width: 70, + height: 70, + placeholderBuilder: (context) => Icon( + Icons.fingerprint, + size: 70, + color: const Color(0xFF102D25), + ), + ); + } else if (widget.isSuccess) { + // Success state - tick mark + return SvgPicture.asset( + "assets/images/tick.svg", + key: const ValueKey('success'), + width: 70, + height: 70, + placeholderBuilder: (context) => Icon( + Icons.check_circle, + size: 70, + color: const Color(0xFF32C59A), + ), + ); + } else { + // Error state - error icon + return SvgPicture.asset( + "assets/images/error.svg", + key: const ValueKey('error'), + width: 70, + height: 70, + placeholderBuilder: (context) => Icon( + Icons.error, + size: 70, + color: Colors.red, + ), + ); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -138,16 +182,31 @@ class _LoginAnimationScreenState extends State shape: BoxShape.circle, ), ), + + // FIXED: AnimatedSwitcher with proper key handling AnimatedSwitcher( duration: const Duration(milliseconds: 500), - child: _buildIcon( - showResult, - widget.isSuccess, - key: ValueKey( - "icon_${showResult}_${widget.isSuccess}", - ), - ), + child: _buildIcon(), + layoutBuilder: (currentChild, previousChildren) { + return Stack( + alignment: Alignment.center, + children: [ + ...previousChildren, + if (currentChild != null) currentChild, + ], + ); + }, + transitionBuilder: (child, animation) { + return FadeTransition( + opacity: animation, + child: ScaleTransition( + scale: animation, + child: child, + ), + ); + }, ), + if (!showResult) Positioned.fill( child: AnimatedBuilder( @@ -181,29 +240,29 @@ class _LoginAnimationScreenState extends State const SizedBox(height: 40), + // Text AnimatedSwitcher with proper key handling AnimatedSwitcher( duration: const Duration(milliseconds: 500), - child: - showResult - ? Text( - widget.isSuccess - ? "تم تسجيل دخولك بنجاح" - : "تم رفض تسجيل الدخول ", - key: ValueKey("text_${widget.isSuccess}"), - style: const TextStyle( - fontSize: 17, - fontWeight: FontWeight.w600, - decoration: TextDecoration.none, - ), - ) - : const Text( - "يتم تسجيل الدخول ...", - key: ValueKey("loading_text"), - style: TextStyle( - fontSize: 16, - decoration: TextDecoration.none, - ), + child: showResult + ? Text( + widget.isSuccess + ? "تم تسجيل دخولك بنجاح" + : "تم رفض تسجيل الدخول ", + key: ValueKey("text_${widget.isSuccess}"), + style: const TextStyle( + fontSize: 17, + fontWeight: FontWeight.w600, + decoration: TextDecoration.none, ), + ) + : const Text( + "يتم تسجيل الدخول ...", + key: ValueKey("loading_text"), + style: TextStyle( + fontSize: 16, + decoration: TextDecoration.none, + ), + ), ), ], ), @@ -214,60 +273,6 @@ class _LoginAnimationScreenState extends State ), ); } - - /// >>> FIXED ICON BUILDER <<< - Widget _buildIcon(bool showResult, bool isSuccess, {required Key key}) { - if (showResult) { - if (isSuccess) { - return SizedBox( - key: key, - width: 70, - height: 70, - child: SvgPicture.asset( - "assets/images/tick.svg", - width: 70, - height: 70, - placeholderBuilder: - (context) => Icon( - Icons.check_circle, - size: 70, - color: const Color(0xFF32C59A), - ), - ), - ); - } else { - return SizedBox( - key: key, - width: 70, - height: 70, - child: SvgPicture.asset( - "assets/images/error.svg", - width: 70, - height: 70, - placeholderBuilder: - (context) => Icon(Icons.error, size: 70, color: Colors.red), - ), - ); - } - } - - return SizedBox( - key: key, - width: 70, - height: 70, - child: SvgPicture.asset( - "assets/images/finger_print.svg", - width: 70, - height: 70, - placeholderBuilder: - (context) => Icon( - Icons.fingerprint, - size: 70, - color: const Color(0xFF102D25), - ), - ), - ); - } } class _ProgressRingPainter extends CustomPainter { @@ -283,21 +288,19 @@ class _ProgressRingPainter extends CustomPainter { final radius = 50.0; // background circle (very subtle) - final bgPaint = - Paint() - ..color = const Color(0x0032C599) - ..style = PaintingStyle.stroke - ..strokeWidth = 3.0; + final bgPaint = Paint() + ..color = const Color(0x0032C599) + ..style = PaintingStyle.stroke + ..strokeWidth = 3.0; canvas.drawCircle(center, radius, bgPaint); // foreground arc that animates - final progressPaint = - Paint() - ..color = const Color(0xC40A4433) - ..style = PaintingStyle.stroke - ..strokeWidth = 3.0 - ..strokeCap = StrokeCap.round; + final progressPaint = Paint() + ..color = const Color(0xC40A4433) + ..style = PaintingStyle.stroke + ..strokeWidth = 3.0 + ..strokeCap = StrokeCap.round; const startAngle = -1.5708; // -90° in radians final sweepAngle = 2 * 3.1415926 * progress; @@ -337,11 +340,10 @@ class _PulseRingsPainter extends CustomPainter { final radius = baseRadius + (maxRadius - baseRadius) * ringProgress; final opacity = (1.0 - ringProgress) * 0.45; - final paint = - Paint() - ..color = const Color(0xFF32C59A).withOpacity(opacity) - ..style = PaintingStyle.stroke - ..strokeWidth = 2; + final paint = Paint() + ..color = const Color(0xFF32C59A).withOpacity(opacity) + ..style = PaintingStyle.stroke + ..strokeWidth = 2; canvas.drawCircle(center, radius, paint); } @@ -351,4 +353,4 @@ class _PulseRingsPainter extends CustomPainter { @override bool shouldRepaint(_PulseRingsPainter oldDelegate) => oldDelegate.progress != progress; -} +} \ No newline at end of file