import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State with SingleTickerProviderStateMixin { late AnimationController _animationController; late Animation _slideAnimation; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 250), ); _slideAnimation = Tween(begin: -1.0, end: 0.0).animate( CurvedAnimation(parent: _animationController, curve: Curves.easeOutCubic), ); _animationController.forward(); } @override void dispose() { _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: CustomScrollView( slivers: [ SliverAppBar( floating: true, title: const Text('QPay'), actions: [ IconButton( icon: const Icon(Icons.notifications_outlined), onPressed: () {}, ), ], ), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Welcome back,', style: TextStyle(fontSize: 16, color: Colors.grey), ), const SizedBox(height: 4), const Text( 'John Doe', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 24), SlideTransition( position: Tween( begin: const Offset(0, 0), end: const Offset(0, 1), ).animate(_slideAnimation), child: _buildBalanceCard(context), ), const SizedBox(height: 24), const Text( 'Quick Actions', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), _buildQuickActions(context), const SizedBox(height: 24), const Text( 'Recent Transactions', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, ), ), const SizedBox(height: 16), _buildRecentTransactions(), ], ), ), ), ], ), ), ); } Widget _buildBalanceCard(BuildContext context) { return Card( child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary.withValues(alpha: 0.2), borderRadius: BorderRadius.circular(16), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Available Balance', style: TextStyle(color: Colors.black87, fontSize: 14), ), const SizedBox(height: 4), const Text( '\$0.00', style: TextStyle( color: Colors.black, fontSize: 24, fontWeight: FontWeight.bold, ), ), ], ), _buildActionButton( context, 'Add', Icons.add_circle_outline, () {}, ), ], ), ], ), ), ); } Widget _buildActionButton( BuildContext context, String label, IconData icon, VoidCallback onTap, ) { return InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), decoration: BoxDecoration( color: Colors.black87.withOpacity(0.2), borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon(icon, color: Colors.white, size: 18), const SizedBox(width: 4), Text( label, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.w500, fontSize: 14, ), ), ], ), ), ); } Widget _buildQuickActions(BuildContext context) { return GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 2, mainAxisSpacing: 8, crossAxisSpacing: 8, childAspectRatio: 2, children: [ _buildAnimatedQuickActionItem( context, 'Electricity', Icons.electric_bolt_outlined, () {}, 0, ), _buildAnimatedQuickActionItem( context, 'Airtime', Icons.phone_android_outlined, () {}, 1, ), ], ); } Widget _buildAnimatedQuickActionItem( BuildContext context, String label, IconData icon, VoidCallback onTap, int index, ) { return SlideTransition( position: Tween( begin: const Offset(-1, 0), end: const Offset(0, 0), ).animate( CurvedAnimation( parent: _animationController, curve: Interval(0.4 + (index * 0.1), 0.8 + (index * 0.1)), ), ), child: _buildQuickActionItem(context, label, icon, onTap), ); } Widget _buildQuickActionItem( BuildContext context, String label, IconData icon, VoidCallback onTap, ) { return InkWell( onTap: onTap, borderRadius: BorderRadius.circular(12), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Icon( icon, color: Theme.of(context).colorScheme.secondary, size: 28, ), ), const SizedBox(height: 8), Text( label, style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Theme.of(context).colorScheme.tertiary, ), ), ], ), ); } Widget _buildRecentTransactions() { return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: 3, itemBuilder: (context, index) { return SlideTransition( position: Tween( begin: const Offset(-1, 0), end: Offset.zero, ).animate( CurvedAnimation( parent: _animationController, curve: Interval( 0.5 + (index * 0.1), 0.7 + (index * 0.1), curve: Curves.easeOutCubic, ), ), ), child: ListTile( leading: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.tertiary.withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: Icon( index == 0 ? Icons.phone_android : index == 1 ? Icons.wifi : Icons.receipt_long, color: Theme.of(context).colorScheme.tertiary, ), ), title: Text( index == 0 ? 'Mobile Bill' : index == 1 ? 'Internet Bill' : 'Electricity Bill', ), subtitle: Text( index == 0 ? 'Yesterday' : index == 1 ? '2 days ago' : '3 days ago', style: const TextStyle(fontSize: 12), ), trailing: Text( index == 0 ? '-\$50.00' : index == 1 ? '-\$75.00' : '-\$120.00', style: TextStyle( color: Theme.of(context).colorScheme.error, fontWeight: FontWeight.bold, ), ), ), ); }, ); } }