From bd89eba7722fc4074e6befc1b6d5d6d6d168308f Mon Sep 17 00:00:00 2001 From: 230404 <230404@epvc.pt> Date: Tue, 9 Dec 2025 17:19:35 +0000 Subject: [PATCH] pagina da dashboard com cards --- lib/classe/home.config.dart | 36 ++ .../controllers/contollers_grafico.dart | 29 ++ lib/grafico de pizza/dados_grafico.dart | 26 ++ lib/grafico de pizza/grafico.dart | 404 ++++++++++++++++++ .../widgets/grafico_widgets.dart | 144 +++++++ lib/pages/home.dart | 383 +++++++++-------- 6 files changed, 852 insertions(+), 170 deletions(-) create mode 100644 lib/classe/home.config.dart create mode 100644 lib/grafico de pizza/controllers/contollers_grafico.dart create mode 100644 lib/grafico de pizza/dados_grafico.dart create mode 100644 lib/grafico de pizza/grafico.dart create mode 100644 lib/grafico de pizza/widgets/grafico_widgets.dart diff --git a/lib/classe/home.config.dart b/lib/classe/home.config.dart new file mode 100644 index 0000000..17acc88 --- /dev/null +++ b/lib/classe/home.config.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +class HomeConfig { + // Dimensões dos cards + static const double cardwidthPadding = 400; + static const double cardheightPadding = 300; + + // Cores principais + static const Color primaryColor = Colors.orange; + static const Color secondaryColor = Colors.blue; + static const Color accentColor = Colors.green; + + // Estilos de texto + static TextStyle titleStyle = TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ); + + static TextStyle subtitleStyle = TextStyle( + fontSize: 14, + color: Colors.white.withOpacity(0.8), + ); + + static TextStyle statValueStyle = TextStyle( + fontSize: 36, + fontWeight: FontWeight.bold, + color: Colors.white, + ); + + static TextStyle statLabelStyle = TextStyle( + fontSize: 12, + color: Colors.white.withOpacity(0.8), + letterSpacing: 1.5, + ); +} \ No newline at end of file diff --git a/lib/grafico de pizza/controllers/contollers_grafico.dart b/lib/grafico de pizza/controllers/contollers_grafico.dart new file mode 100644 index 0000000..8dd9d67 --- /dev/null +++ b/lib/grafico de pizza/controllers/contollers_grafico.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:playmaker/grafico%20de%20pizza/dados_grafico.dart'; + +class PieChartController extends ChangeNotifier { + PieChartData _chartData = PieChartData(victories: 25, defeats: 10); + + PieChartData get chartData => _chartData; + + void updateData({int? victories, int? defeats, int? draws}) { + _chartData = PieChartData( + victories: victories ?? _chartData.victories, + defeats: defeats ?? _chartData.defeats, + draws: draws ?? _chartData.draws, + ); + notifyListeners(); + } + + void incrementVictories() { + updateData(victories: _chartData.victories + 1); + } + + void incrementDefeats() { + updateData(defeats: _chartData.defeats + 1); + } + + void reset() { + updateData(victories: 0, defeats: 0, draws: 0); + } +} \ No newline at end of file diff --git a/lib/grafico de pizza/dados_grafico.dart b/lib/grafico de pizza/dados_grafico.dart new file mode 100644 index 0000000..17b131f --- /dev/null +++ b/lib/grafico de pizza/dados_grafico.dart @@ -0,0 +1,26 @@ +class PieChartData { + final int victories; + final int defeats; + final int draws; + + const PieChartData({ + required this.victories, + required this.defeats, + this.draws = 0, + }); + + int get total => victories + defeats + draws; + + double get victoryPercentage => total > 0 ? victories / total : 0; + double get defeatPercentage => total > 0 ? defeats / total : 0; + double get drawPercentage => total > 0 ? draws / total : 0; + + Map toJson() => { + 'victories': victories, + 'defeats': defeats, + 'draws': draws, + 'total': total, + 'victoryPercentage': victoryPercentage, + 'defeatPercentage': defeatPercentage, + }; +} \ No newline at end of file diff --git a/lib/grafico de pizza/grafico.dart b/lib/grafico de pizza/grafico.dart new file mode 100644 index 0000000..a05f7e7 --- /dev/null +++ b/lib/grafico de pizza/grafico.dart @@ -0,0 +1,404 @@ +import 'package:flutter/material.dart'; +import 'package:playmaker/grafico%20de%20pizza/widgets/grafico_widgets.dart'; +import 'dados_grafico.dart'; +import 'controllers/contollers_grafico.dart'; +import 'package:playmaker/classe/home.config.dart'; + +class PieChartCard extends StatefulWidget { + final PieChartController? controller; + final String title; + final String subtitle; + final Color backgroundColor; + final VoidCallback? onTap; + + const PieChartCard({ + super.key, + this.controller, + this.title = 'DESEMPENHO', + this.subtitle = 'Vitórias vs Derrotas', + this.onTap, required this.backgroundColor, + }); + + @override + State createState() => _PieChartCardState(); +} + +class _PieChartCardState extends State with SingleTickerProviderStateMixin { + late PieChartController _controller; + late AnimationController _animationController; + late Animation _animation; + + @override + void initState() { + super.initState(); + _controller = widget.controller ?? PieChartController(); + + _animationController = AnimationController( + duration: const Duration(milliseconds: 600), + vsync: this, + ); + + _animation = Tween(begin: 0.0, end: 1.0).animate( + CurvedAnimation( + parent: _animationController, + curve: Curves.easeOutBack, + ), + ); + + _animationController.forward(); + } + + @override + void dispose() { + _animationController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final data = _controller.chartData; + + return AnimatedBuilder( + animation: _animation, + builder: (context, child) { + return Transform.scale( + scale: 0.95 + (_animation.value * 0.05), + child: Opacity( + opacity: _animation.value, + child: child, + ), + ); + }, + child: Container( + width: HomeConfig.cardwidthPadding, + height: HomeConfig.cardheightPadding, + child: Card( + elevation: 8, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + ), + child: InkWell( + onTap: widget.onTap, + borderRadius: BorderRadius.circular(20), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + widget.backgroundColor.withOpacity(0.9), + widget.backgroundColor.withOpacity(0.7), + ], + ), + ), + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Cabeçalho compacto + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.title, + style: TextStyle( + fontSize: 14, // Pequeno + fontWeight: FontWeight.bold, + color: Colors.white.withOpacity(0.9), + letterSpacing: 1.5, + ), + ), + SizedBox(height: 2), // Muito pequeno + Text( + widget.subtitle, + style: TextStyle( + fontSize: 16, // Moderado + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ], + ), + Container( + padding: EdgeInsets.all(6), // Pequeno + decoration: BoxDecoration( + color: Colors.orange.withOpacity(0.8), + shape: BoxShape.circle, + ), + child: Icon( + Icons.pie_chart, + size: 18, // Pequeno + color: Colors.white, + ), + ), + ], + ), + + SizedBox(height: 8), // Pequeno espaço + + // Conteúdo principal - COMPACTO E CONTROLADO + Expanded( + child: Row( + children: [ + // Gráfico de pizza + Expanded( + flex: 3, + child: Center( + child: PieChartWidget( + victoryPercentage: data.victoryPercentage, + defeatPercentage: data.defeatPercentage, + drawPercentage: data.drawPercentage, + size: 130, // Pequeno para caber + ), + ), + ), + + SizedBox(width: 8), // Pequeno espaço + + // Estatísticas - EXTREMAMENTE COMPACTAS + Expanded( + flex: 2, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Vitórias - Layout horizontal ultra compacto + Container( + margin: EdgeInsets.only(bottom: 6), // Muito pequeno + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Número + Text( + data.victories.toString(), + style: TextStyle( + fontSize: 26, // Pequeno mas legível + fontWeight: FontWeight.bold, + color: Colors.green, + height: 0.8, + ), + ), + SizedBox(width: 6), // Pequeno + // Info compacta + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Container( + width: 8, + height: 8, + margin: EdgeInsets.only(right: 4), + decoration: BoxDecoration( + color: Colors.green, + shape: BoxShape.circle, + ), + ), + Text( + 'VIT', + style: TextStyle( + fontSize: 10, // Muito pequeno + color: Colors.white.withOpacity(0.8), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + SizedBox(height: 2), + Text( + '${(data.victoryPercentage * 100).toStringAsFixed(0)}%', + style: TextStyle( + fontSize: 12, // Pequeno + color: Colors.green, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ], + ), + ), + + // Divisor sutil + Container( + height: 0.5, + color: Colors.white.withOpacity(0.1), + margin: EdgeInsets.symmetric(vertical: 4), + ), + + // Derrotas + Container( + margin: EdgeInsets.only(bottom: 6), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + data.defeats.toString(), + style: TextStyle( + fontSize: 26, + fontWeight: FontWeight.bold, + color: Colors.red, + height: 0.8, + ), + ), + SizedBox(width: 6), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Container( + width: 8, + height: 8, + margin: EdgeInsets.only(right: 4), + decoration: BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + ), + ), + Text( + 'DER', + style: TextStyle( + fontSize: 10, + color: Colors.white.withOpacity(0.8), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + SizedBox(height: 2), + Text( + '${(data.defeatPercentage * 100).toStringAsFixed(0)}%', + style: TextStyle( + fontSize: 12, + color: Colors.red, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ], + ), + ), + + // Divisor sutil + Container( + height: 0.5, + color: Colors.white.withOpacity(0.1), + margin: EdgeInsets.symmetric(vertical: 4), + ), + + // Total + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + data.total.toString(), + style: TextStyle( + fontSize: 26, + fontWeight: FontWeight.bold, + color: Colors.white, + height: 0.8, + ), + ), + SizedBox(width: 6), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Container( + width: 8, + height: 8, + margin: EdgeInsets.only(right: 4), + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.circle, + ), + ), + Text( + 'TOT', + style: TextStyle( + fontSize: 10, + color: Colors.white.withOpacity(0.8), + fontWeight: FontWeight.w600, + ), + ), + ], + ), + SizedBox(height: 2), + Text( + '100%', + style: TextStyle( + fontSize: 12, + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + + SizedBox(height: 10), // Espaço controlado + + // Win rate - Sempre visível e não sobreposto + Container( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.1), + borderRadius: BorderRadius.circular(12), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + data.victoryPercentage > 0.5 + ? Icons.trending_up + : Icons.trending_down, + color: data.victoryPercentage > 0.5 + ? Colors.green + : Colors.red, + size: 18, // Pequeno + ), + SizedBox(width: 8), + Text( + 'Win Rate: ${(data.victoryPercentage * 100).toStringAsFixed(1)}%', + style: TextStyle( + fontSize: 14, // Pequeno + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ], + ), + ), + ], + ), + ), + ), + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/grafico de pizza/widgets/grafico_widgets.dart b/lib/grafico de pizza/widgets/grafico_widgets.dart new file mode 100644 index 0000000..669a441 --- /dev/null +++ b/lib/grafico de pizza/widgets/grafico_widgets.dart @@ -0,0 +1,144 @@ +import 'package:flutter/material.dart'; +import 'dart:math' as math; + +class PieChartWidget extends StatelessWidget { + final double victoryPercentage; + final double defeatPercentage; + final double drawPercentage; + final double size; + + const PieChartWidget({ + super.key, + required this.victoryPercentage, + required this.defeatPercentage, + this.drawPercentage = 0, + this.size = 140, // Aumentado para 400x300 + }); + + @override + Widget build(BuildContext context) { + return SizedBox( + width: size, + height: size, + child: CustomPaint( + painter: _PieChartPainter( + victoryPercentage: victoryPercentage, + defeatPercentage: defeatPercentage, + drawPercentage: drawPercentage, + ), + child: _buildCenterLabels(), + ), + ); + } + + Widget _buildCenterLabels() { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '${(victoryPercentage * 100).toStringAsFixed(1)}%', + style: TextStyle( + fontSize: size * 0.2, // Tamanho responsivo (28px para 140px) + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + SizedBox(height: 4), + Text( + 'Vitórias', + style: TextStyle( + fontSize: size * 0.1, // Tamanho responsivo (14px para 140px) + color: Colors.white.withOpacity(0.8), + ), + ), + ], + ), + ); + } +} + +class _PieChartPainter extends CustomPainter { + final double victoryPercentage; + final double defeatPercentage; + final double drawPercentage; + + _PieChartPainter({ + required this.victoryPercentage, + required this.defeatPercentage, + required this.drawPercentage, + }); + + @override + void paint(Canvas canvas, Size size) { + final center = Offset(size.width / 2, size.height / 2); + final radius = size.width / 2 - 5; + + // Cores + const victoryColor = Colors.green; + const defeatColor = Colors.red; + const drawColor = Colors.yellow; + const borderColor = Colors.white30; + + double startAngle = 0; + + // Vitórias (verde) + if (victoryPercentage > 0) { + final sweepAngle = 2 * math.pi * victoryPercentage; + _drawSector(canvas, center, radius, startAngle, sweepAngle, victoryColor); + startAngle += sweepAngle; + } + + // Empates (amarelo) + if (drawPercentage > 0) { + final sweepAngle = 2 * math.pi * drawPercentage; + _drawSector(canvas, center, radius, startAngle, sweepAngle, drawColor); + startAngle += sweepAngle; + } + + // Derrotas (vermelho) + if (defeatPercentage > 0) { + final sweepAngle = 2 * math.pi * defeatPercentage; + _drawSector(canvas, center, radius, startAngle, sweepAngle, defeatColor); + } + + // Borda + final borderPaint = Paint() + ..color = borderColor + ..style = PaintingStyle.stroke + ..strokeWidth = 2; + + canvas.drawCircle(center, radius, borderPaint); + } + + void _drawSector(Canvas canvas, Offset center, double radius, + double startAngle, double sweepAngle, Color color) { + final paint = Paint() + ..color = color + ..style = PaintingStyle.fill; + + canvas.drawArc( + Rect.fromCircle(center: center, radius: radius), + startAngle, + sweepAngle, + true, + paint, + ); + + // Linha divisória + if (sweepAngle < 2 * math.pi) { + final linePaint = Paint() + ..color = Colors.white.withOpacity(0.5) + ..style = PaintingStyle.stroke + ..strokeWidth = 1.5; + + final lineX = center.dx + radius * math.cos(startAngle); + final lineY = center.dy + radius * math.sin(startAngle); + + canvas.drawLine(center, Offset(lineX, lineY), linePaint); + } + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +} \ No newline at end of file diff --git a/lib/pages/home.dart b/lib/pages/home.dart index 4c6d17b..bb4274c 100644 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:playmaker/classe/home.config.dart'; +import 'package:playmaker/grafico%20de%20pizza/grafico.dart'; class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); @@ -8,149 +10,75 @@ class HomeScreen extends StatelessWidget { return Scaffold( appBar: AppBar( title: const Text('PlayMaker'), - backgroundColor: Colors.orange, + backgroundColor: HomeConfig.primaryColor, foregroundColor: Colors.white, + leading: IconButton( + icon: const Icon(Icons.person), + onPressed: () {}, + ), ), body: SingleChildScrollView( child: Padding( - padding: const EdgeInsets.all(40.0), + padding: const EdgeInsets.all(20.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - // Título - const Text( - 'PLAYMAKER', - style: TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.orange, - letterSpacing: 2, - ), - ), - const SizedBox(height: 40), - - // Botão PRINCIPAL para iniciar jogo - SizedBox( - width: double.infinity, - height: 250, - child: ElevatedButton( - onPressed: () { - // Navegar para tela de novo jogo - print('Iniciar novo jogo!'); - // Navigator.push(context, MaterialPageRoute( - // builder: (context) => NovoJogoScreen() - // )); - }, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.orange, - foregroundColor: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(25), - ), - elevation: 10, - shadowColor: Colors.orange.withOpacity(0.5), - ), - child: const Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.sports_basketball, - size: 80, - color: Colors.white, - ), - SizedBox(height: 20), - Text( - 'NOVO JOGO', - style: TextStyle( - fontSize: 38, - fontWeight: FontWeight.w900, - color: Colors.white, - letterSpacing: 2, - ), - ), - ], - ), - ), - ), - - const SizedBox(height: 40), - - // Texto explicativo - const Text( - 'Toque para iniciar uma nova partida', - style: TextStyle( - fontSize: 16, - color: Colors.grey, - fontStyle: FontStyle.italic, - ), - ), - - const SizedBox(height: 50), - - // Seção de opções rápidas - const Text( - 'Acesso Rápido', - style: TextStyle( - fontSize: 22, - fontWeight: FontWeight.bold, - color: Colors.orange, - ), - ), - - const SizedBox(height: 20), - - // Grid de opções - GridView.count( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - crossAxisCount: 2, - childAspectRatio: 1.3, - mainAxisSpacing: 20, - crossAxisSpacing: 20, + // Primeira linha com 2 cards + Row( + mainAxisAlignment: MainAxisAlignment.center, children: [ - // Estatísticas - _buildQuickOption( - icon: Icons.insights, - title: 'Estatísticas', - subtitle: 'Ver desempenho', - color: Colors.green, - onTap: () { - print('Ver estatísticas'); - // Pode navegar para estatísticas ou mudar para índice 3 no navigation - }, + // Card 1 - Estatísticas de Basquete + _buildStatCard( + title: 'Mais Pontos', + playerName: 'Michael Jordan', + statValue: '34.5', + statLabel: 'PPG', + color: Colors.blue[800]!, + icon: Icons.sports_basketball, + isHighlighted: true, ), - // Equipas - _buildQuickOption( - icon: Icons.people, - title: 'Minhas Equipas', - subtitle: 'Gerir equipas', - color: Colors.blue, - onTap: () { - print('Ver equipas'); - // Pode navegar para equipas ou mudar para índice 2 no navigation - }, + SizedBox(width: 20), + + // Card 2 - Estatísticas de Futebol + _buildStatCard( + title: 'Mais Assistências', + playerName: 'magic Johnson', + statValue: '12.8', + statLabel: 'APG', + color: Colors.green[800]!, + icon: Icons.sports_soccer, + isHighlighted: false, + ), + ], + ), + + SizedBox(height: 20), + + // Segunda linha com 2 cards + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + // Card 3 - Estatísticas de Tênis + _buildStatCard( + title: 'Mais Rebotes', + playerName: 'Denis Rodman', + statValue: '15.3', + statLabel: 'RPG', + color: Colors.purple[800]!, + icon: Icons.sports_tennis, + isHighlighted: false, ), - // Histórico - _buildQuickOption( - icon: Icons.history, - title: 'Histórico', - subtitle: 'Jogos anteriores', - color: Colors.purple, - onTap: () { - print('Ver histórico'); - }, - ), + SizedBox(width: 20), - // Configurações - _buildQuickOption( - icon: Icons.settings, - title: 'Configurações', - subtitle: 'Ajustar app', - color: Colors.grey, + // Card 4 - Estatísticas de Vôlei + PieChartCard( + title: 'DESEMPENHO', + subtitle: 'Vitórias vs Derrotas', + backgroundColor: Colors.red[800]!, onTap: () { - print('Abrir configurações'); + print('Gráfico clicado!'); }, ), ], @@ -162,53 +90,168 @@ class HomeScreen extends StatelessWidget { ); } - // Widget para construir opções rápidas - Widget _buildQuickOption({ - required IconData icon, + // Método para criar cards de estatísticas + Widget _buildStatCard({ required String title, - required String subtitle, + required String playerName, + required String statValue, + required String statLabel, required Color color, - required VoidCallback onTap, + required IconData icon, + bool isHighlighted = false, }) { - return Card( - elevation: 5, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(15), - ), - child: InkWell( - borderRadius: BorderRadius.circular(15), - onTap: onTap, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - icon, - size: 40, - color: color, - ), - const SizedBox(height: 10), - Text( - title, - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: color, - ), - textAlign: TextAlign.center, - ), - const SizedBox(height: 5), - Text( - subtitle, - style: const TextStyle( - fontSize: 12, - color: Colors.grey, - ), - textAlign: TextAlign.center, + return Container( + width: HomeConfig.cardwidthPadding, + height: HomeConfig.cardheightPadding, + child: Card( + elevation: isHighlighted ? 12 : 8, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20), + side: isHighlighted + ? BorderSide(color: Colors.amber, width: 2) + : BorderSide.none, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + gradient: LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + color.withOpacity(0.9), + color.withOpacity(0.7), + ], + ), + boxShadow: [ + BoxShadow( + color: color.withOpacity(0.3), + blurRadius: 15, + spreadRadius: 2, ), ], ), + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // Cabeçalho com título e ícone + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title.toUpperCase(), + style: TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.white.withOpacity(0.9), + letterSpacing: 1.5, + ), + ), + SizedBox(height: 5), + Text( + playerName, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + if (isHighlighted) + Container( + padding: EdgeInsets.all(8), + decoration: BoxDecoration( + color: Colors.amber, + shape: BoxShape.circle, + ), + child: Icon( + Icons.star, + size: 20, + color: Colors.white, + ), + ), + ], + ), + + SizedBox(height: 10), + + // Ícone do esporte + Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.2), + shape: BoxShape.circle, + ), + child: Icon( + icon, + size: 30, + color: Colors.white, + ), + ), + + Spacer(), + + // Estatística central + Center( + child: Column( + children: [ + Text( + statValue, + style: TextStyle( + fontSize: 42, + fontWeight: FontWeight.bold, + color: Colors.white, + height: 1, + ), + ), + SizedBox(height: 5), + Text( + statLabel.toUpperCase(), + style: TextStyle( + fontSize: 14, + color: Colors.white.withOpacity(0.8), + letterSpacing: 2, + ), + ), + ], + ), + ), + + Spacer(), + + // Rodapé com botão + Container( + width: double.infinity, + padding: EdgeInsets.symmetric(vertical: 12), + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.2), + borderRadius: BorderRadius.circular(15), + ), + child: Center( + child: Text( + 'VER DETALHES', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 14, + letterSpacing: 1, + ), + ), + ), + ), + ], + ), + ), ), ), );