import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../core/constants/app_colors.dart'; import '../../core/constants/app_text_styles.dart'; import '../../data/services/api_service.dart'; import '../widgets/dashboard_card.dart'; import '../widgets/chart_widget.dart'; import '../widgets/teacher_panel_scaffold.dart'; import 'course_page.dart'; import 'license_page.dart'; import 'plan_renewal_page.dart'; import 'ticket_page.dart'; import 'transaction_page.dart'; class DashboardPage extends StatefulWidget { const DashboardPage({super.key}); @override State createState() => _DashboardPageState(); } class _DashboardPageState extends State with TickerProviderStateMixin { Map? _dashboardData; bool _isLoading = true; late AnimationController _staggerController; @override void initState() { super.initState(); _staggerController = AnimationController( vsync: this, duration: const Duration(milliseconds: 1200), ); _loadData(); } Future _loadData() async { try { final apiService = Provider.of(context, listen: false); final data = await apiService.getDashboardData(); setState(() { _dashboardData = data; _isLoading = false; }); _staggerController.forward(); } catch (e) { setState(() { _isLoading = false; }); } } @override void dispose() { _staggerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TeacherPanelScaffold( selectedMenu: PanelMenu.dashboard, onDashboardTap: () {}, onCourseTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const CoursePage()), ); }, onLicenseTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const PanelLicensePage()), ); }, onTransactionTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const TransactionPage()), ); }, onTicketTap: () { Navigator.of(context).push( MaterialPageRoute(builder: (context) => const TicketPage()), ); }, child: _isLoading ? const Center(child: CircularProgressIndicator()) : SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ LayoutBuilder( builder: (context, constraints) { final cardWidth = constraints.maxWidth > 800 ? (constraints.maxWidth - 24) / 2 : constraints.maxWidth; return Wrap( spacing: 24, runSpacing: 24, alignment: WrapAlignment.start, children: [ _buildAnimatedCard( 0, cardWidth, DashboardCard( title: 'پلن فضا', borderColor: AppColors.planCardBorder, iconOrAction: Container( padding: const EdgeInsets.all(12), decoration: const BoxDecoration( color: AppColors.planCardBorder, shape: BoxShape.circle, ), child: const Icon( Icons.cloud, color: Colors.white, size: 32, ), ), content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${_dashboardData!['plan']['used']} / ${_dashboardData!['plan']['total']} GB', style: AppTextStyles.headlineMedium, ), Text( '${_dashboardData!['plan']['days_left']} روز', style: AppTextStyles.bodyMedium, ), const SizedBox(height: 8), OutlinedButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const PlanRenewalPage(), ), ); }, style: OutlinedButton.styleFrom( foregroundColor: AppColors.planCardBorder, side: const BorderSide( color: AppColors.planCardBorder, ), ), child: const Text('تغییر / تمدید'), ), ], ), ), ), _buildAnimatedCard( 1, cardWidth, DashboardCard( title: 'اعتبار', borderColor: AppColors.creditCardBorder, iconOrAction: Container( padding: const EdgeInsets.all(12), decoration: const BoxDecoration( color: AppColors.creditCardBorder, shape: BoxShape.circle, ), child: const Icon( Icons.attach_money, color: Colors.white, size: 32, ), ), content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '${_dashboardData!['credit']['amount']} تومان', style: AppTextStyles.headlineMedium, ), const SizedBox(height: 8), OutlinedButton( onPressed: () {}, style: OutlinedButton.styleFrom( foregroundColor: AppColors.creditCardBorder, side: const BorderSide( color: AppColors.creditCardBorder, ), ), child: const Text('افزایش اعتبار'), ), ], ), ), ), _buildAnimatedCard( 2, cardWidth, DashboardCard( title: 'کلید API', borderColor: AppColors.apiCardBorder, iconOrAction: Container( padding: const EdgeInsets.all(12), decoration: const BoxDecoration( color: AppColors.apiCardBorder, shape: BoxShape.circle, ), child: const Icon( Icons.vpn_key, color: Colors.white, size: 32, ), ), content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _dashboardData!['api_key']['key'], style: AppTextStyles.bodyMedium.copyWith( fontWeight: FontWeight.bold, ), ), Text( _dashboardData!['api_key']['secret'], style: AppTextStyles.bodyMedium, ), const SizedBox(height: 8), OutlinedButton( onPressed: () {}, style: OutlinedButton.styleFrom( foregroundColor: AppColors.apiCardBorder, side: const BorderSide( color: AppColors.apiCardBorder, ), ), child: const Text('کپی API'), ), ], ), ), ), _buildAnimatedCard( 3, cardWidth, DashboardCard( title: 'ریبرندینگ', borderColor: AppColors.rebrandingCardBorder, iconOrAction: Container( padding: const EdgeInsets.all(12), decoration: const BoxDecoration( color: AppColors.rebrandingCardBorder, shape: BoxShape.circle, ), child: const Icon( Icons.palette, color: Colors.white, size: 32, ), ), content: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _dashboardData!['rebranding']['status'], style: AppTextStyles.headlineMedium, ), const SizedBox(height: 8), OutlinedButton( onPressed: () {}, style: OutlinedButton.styleFrom( foregroundColor: AppColors.rebrandingCardBorder, side: const BorderSide( color: AppColors.rebrandingCardBorder, ), ), child: const Text('سفارش'), ), ], ), ), ), ], ); }, ), const SizedBox(height: 32), Text( 'عملکرد ۳۰ روز گذشته', style: AppTextStyles.headlineMedium, ), const SizedBox(height: 16), FadeTransition( opacity: CurvedAnimation( parent: _staggerController, curve: const Interval(0.6, 1.0, curve: Curves.easeOut), ), child: ActivityChart( data: List>.from( _dashboardData!['chart_data'], ), ), ), ], ), ), ); } Widget _buildAnimatedCard(int index, double width, Widget card) { final interval = Interval( index * 0.15, (index * 0.15) + 0.4, curve: Curves.easeOut, ); return SizedBox( width: width, child: SlideTransition( position: Tween( begin: const Offset(0, 0.3), end: Offset.zero, ).animate(CurvedAnimation(parent: _staggerController, curve: interval)), child: FadeTransition( opacity: CurvedAnimation(parent: _staggerController, curve: interval), child: card, ), ), ); } }