import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:gap/gap.dart'; import '../../../../core/utils/extensions.dart'; import '../../../../shared/widgets/chart_widgets/bar_chart_widget.dart'; import '../../../../shared/widgets/chart_widgets/pie_chart_widget.dart'; import '../widgets/monitoring_panel.dart'; import '../widgets/realtime_chart.dart'; import '../widgets/stats_card.dart'; class DashboardScreen extends StatelessWidget { const DashboardScreen({super.key}); @override Widget build(BuildContext context) { return SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '대시보드', style: context.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const Gap(8), Text( '실시간 데이터와 시스템 현황을 모니터링하세요', style: context.textTheme.bodyLarge?.copyWith( color: context.colorScheme.onSurfaceVariant, ), ), const Gap(24), // 통계 카드 LayoutBuilder( builder: (context, constraints) { final crossAxisCount = context.isDesktop ? 4 : context.isTablet ? 2 : 1; return GridView.count( crossAxisCount: crossAxisCount, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), mainAxisSpacing: 16, crossAxisSpacing: 16, childAspectRatio: 1.8, children: const [ StatsCard( title: '총 사용자', value: '1,234', icon: Icons.people, iconColor: Colors.blue, change: '+12%', isPositive: true, subtitle: '전월 대비', ), StatsCard( title: '활성 세션', value: '89', icon: Icons.devices, iconColor: Colors.green, change: '+5', isPositive: true, subtitle: '현재 접속', ), StatsCard( title: '요청 수', value: '24.5K', icon: Icons.trending_up, iconColor: Colors.orange, change: '+18%', isPositive: true, subtitle: '오늘', ), StatsCard( title: '평균 응답시간', value: '142ms', icon: Icons.speed, iconColor: Colors.purple, change: '-8ms', isPositive: true, subtitle: '지난 1시간', ), ], ); }, ), const Gap(24), // 실시간 차트 + 모니터링 패널 LayoutBuilder( builder: (context, constraints) { if (context.isDesktop) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Expanded( flex: 2, child: SizedBox( height: 350, child: RealtimeChart( title: '실시간 트래픽', ), ), ), const Gap(16), const Expanded( child: MonitoringPanel(), ), ], ); } return Column( children: const [ SizedBox( height: 350, child: RealtimeChart( title: '실시간 트래픽', ), ), Gap(16), MonitoringPanel(), ], ); }, ), const Gap(24), // 바 차트 + 파이 차트 LayoutBuilder( builder: (context, constraints) { final charts = [ SizedBox( height: 300, child: Card( child: Padding( padding: const EdgeInsets.all(20), child: BarChartWidget( title: '일별 API 요청', maxY: 100, barGroups: List.generate( 7, (i) => BarChartGroupData( x: i, barRods: [ BarChartRodData( toY: [30, 45, 60, 38, 72, 55, 40][i] .toDouble(), color: context.colorScheme.primary, width: 16, borderRadius: const BorderRadius.vertical( top: Radius.circular(4), ), ), ], ), ), bottomTitles: (value, meta) => SideTitleWidget( meta: meta, child: Text( ['월', '화', '수', '목', '금', '토', '일'] [value.toInt() % 7], style: Theme.of(context).textTheme.bodySmall, ), ), ), ), ), ), SizedBox( height: 300, child: Card( child: Padding( padding: const EdgeInsets.all(20), child: PieChartWidget( title: '사용자 분포', sections: [ PieChartSectionData( value: 45, color: Colors.blue, title: '45%', radius: 50, titleStyle: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12, ), ), PieChartSectionData( value: 30, color: Colors.green, title: '30%', radius: 50, titleStyle: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12, ), ), PieChartSectionData( value: 15, color: Colors.orange, title: '15%', radius: 50, titleStyle: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12, ), ), PieChartSectionData( value: 10, color: Colors.purple, title: '10%', radius: 50, titleStyle: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 12, ), ), ], legendItems: const [ LegendItem(label: '웹', color: Colors.blue), LegendItem(label: 'Android', color: Colors.green), LegendItem(label: 'iOS', color: Colors.orange), LegendItem(label: '기타', color: Colors.purple), ], ), ), ), ), ]; if (context.isDesktop) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(child: charts[0]), const Gap(16), Expanded(child: charts[1]), ], ); } return Column( children: [ charts[0], const Gap(16), charts[1], ], ); }, ), ], ), ); } }