vai te lixar github

This commit is contained in:
2026-03-16 22:09:01 +00:00
parent 1917b5fe10
commit cf0a9a9890
22 changed files with 1929 additions and 1290 deletions

View File

@@ -1,7 +1,8 @@
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:playmaker/classe/theme.dart';
import '../controllers/team_controller.dart';
import '../utils/size_extension.dart'; // 👇 A MAGIA DO SF!
import '../utils/size_extension.dart';
class StatusPage extends StatefulWidget {
const StatusPage({super.key});
@@ -21,6 +22,9 @@ class _StatusPageState extends State<StatusPage> {
@override
Widget build(BuildContext context) {
final bgColor = Theme.of(context).cardTheme.color ?? Colors.white;
final textColor = Theme.of(context).colorScheme.onSurface;
return Column(
children: [
Padding(
@@ -30,20 +34,20 @@ class _StatusPageState extends State<StatusPage> {
child: Container(
padding: EdgeInsets.all(12 * context.sf),
decoration: BoxDecoration(
color: Colors.white,
color: bgColor,
borderRadius: BorderRadius.circular(15 * context.sf),
border: Border.all(color: Colors.grey.shade300),
border: Border.all(color: Colors.grey.withOpacity(0.2)),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 5)]
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(children: [
Icon(Icons.shield, color: const Color(0xFFE74C3C), size: 24 * context.sf),
Icon(Icons.shield, color: AppTheme.primaryRed, size: 24 * context.sf),
SizedBox(width: 10 * context.sf),
Text(_selectedTeamName, style: TextStyle(fontSize: 16 * context.sf, fontWeight: FontWeight.bold))
Text(_selectedTeamName, style: TextStyle(fontSize: 16 * context.sf, fontWeight: FontWeight.bold, color: textColor))
]),
const Icon(Icons.arrow_drop_down),
Icon(Icons.arrow_drop_down, color: textColor),
],
),
),
@@ -63,7 +67,7 @@ class _StatusPageState extends State<StatusPage> {
stream: _supabase.from('members').stream(primaryKey: ['id']).eq('team_id', _selectedTeamId!),
builder: (context, membersSnapshot) {
if (statsSnapshot.connectionState == ConnectionState.waiting || gamesSnapshot.connectionState == ConnectionState.waiting || membersSnapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator(color: Color(0xFFE74C3C)));
return Center(child: CircularProgressIndicator(color: AppTheme.primaryRed));
}
final membersData = membersSnapshot.data ?? [];
@@ -82,7 +86,7 @@ class _StatusPageState extends State<StatusPage> {
return _isAscending ? valA.compareTo(valB) : valB.compareTo(valA);
});
return _buildStatsGrid(context, playerTotals, teamTotals);
return _buildStatsGrid(context, playerTotals, teamTotals, bgColor, textColor);
}
);
}
@@ -96,12 +100,10 @@ class _StatusPageState extends State<StatusPage> {
List<Map<String, dynamic>> _aggregateStats(List<dynamic> stats, List<dynamic> games, List<dynamic> members) {
Map<String, Map<String, dynamic>> aggregated = {};
for (var member in members) {
String name = member['name']?.toString() ?? "Desconhecido";
aggregated[name] = {'name': name, 'j': 0, 'pts': 0, 'ast': 0, 'rbs': 0, 'stl': 0, 'blk': 0, 'mvp': 0, 'def': 0};
}
for (var row in stats) {
String name = row['player_name']?.toString() ?? "Desconhecido";
if (!aggregated.containsKey(name)) aggregated[name] = {'name': name, 'j': 0, 'pts': 0, 'ast': 0, 'rbs': 0, 'stl': 0, 'blk': 0, 'mvp': 0, 'def': 0};
@@ -113,7 +115,6 @@ class _StatusPageState extends State<StatusPage> {
aggregated[name]!['stl'] += (row['stl'] ?? 0);
aggregated[name]!['blk'] += (row['blk'] ?? 0);
}
for (var game in games) {
String? mvp = game['mvp_name'];
String? defRaw = game['top_def_name'];
@@ -134,52 +135,53 @@ class _StatusPageState extends State<StatusPage> {
return {'name': 'TOTAL EQUIPA', 'j': teamGames, 'pts': tPts, 'ast': tAst, 'rbs': tRbs, 'stl': tStl, 'blk': tBlk, 'mvp': tMvp, 'def': tDef};
}
Widget _buildStatsGrid(BuildContext context, List<Map<String, dynamic>> players, Map<String, dynamic> teamTotals) {
Widget _buildStatsGrid(BuildContext context, List<Map<String, dynamic>> players, Map<String, dynamic> teamTotals, Color bgColor, Color textColor) {
return Container(
color: Colors.white,
color: Colors.transparent,
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
columnSpacing: 25 * context.sf,
headingRowColor: MaterialStateProperty.all(Colors.grey.shade100),
dataRowHeight: 60 * context.sf,
headingRowColor: WidgetStateProperty.all(Theme.of(context).colorScheme.surface),
dataRowMaxHeight: 60 * context.sf,
dataRowMinHeight: 60 * context.sf,
columns: [
DataColumn(label: const Text('JOGADOR')),
_buildSortableColumn(context, 'J', 'j'),
_buildSortableColumn(context, 'PTS', 'pts'),
_buildSortableColumn(context, 'AST', 'ast'),
_buildSortableColumn(context, 'RBS', 'rbs'),
_buildSortableColumn(context, 'STL', 'stl'),
_buildSortableColumn(context, 'BLK', 'blk'),
_buildSortableColumn(context, 'DEF 🛡️', 'def'),
_buildSortableColumn(context, 'MVP 🏆', 'mvp'),
DataColumn(label: Text('JOGADOR', style: TextStyle(color: textColor))),
_buildSortableColumn(context, 'J', 'j', textColor),
_buildSortableColumn(context, 'PTS', 'pts', textColor),
_buildSortableColumn(context, 'AST', 'ast', textColor),
_buildSortableColumn(context, 'RBS', 'rbs', textColor),
_buildSortableColumn(context, 'STL', 'stl', textColor),
_buildSortableColumn(context, 'BLK', 'blk', textColor),
_buildSortableColumn(context, 'DEF 🛡️', 'def', textColor),
_buildSortableColumn(context, 'MVP 🏆', 'mvp', textColor),
],
rows: [
...players.map((player) => DataRow(cells: [
DataCell(Row(children: [CircleAvatar(radius: 15 * context.sf, backgroundColor: Colors.grey.shade200, child: Icon(Icons.person, size: 18 * context.sf)), SizedBox(width: 10 * context.sf), Text(player['name'], style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13 * context.sf))])),
DataCell(Center(child: Text(player['j'].toString()))),
_buildStatCell(context, player['pts'], isHighlight: true),
_buildStatCell(context, player['ast']),
_buildStatCell(context, player['rbs']),
_buildStatCell(context, player['stl']),
_buildStatCell(context, player['blk']),
_buildStatCell(context, player['def'], isBlue: true),
_buildStatCell(context, player['mvp'], isGold: true),
DataCell(Row(children: [CircleAvatar(radius: 15 * context.sf, backgroundColor: Colors.grey.withOpacity(0.2), child: Icon(Icons.person, size: 18 * context.sf, color: Colors.grey)), SizedBox(width: 10 * context.sf), Text(player['name'], style: TextStyle(fontWeight: FontWeight.bold, fontSize: 13 * context.sf, color: textColor))])),
DataCell(Center(child: Text(player['j'].toString(), style: TextStyle(color: textColor)))),
_buildStatCell(context, player['pts'], textColor, isHighlight: true),
_buildStatCell(context, player['ast'], textColor),
_buildStatCell(context, player['rbs'], textColor),
_buildStatCell(context, player['stl'], textColor),
_buildStatCell(context, player['blk'], textColor),
_buildStatCell(context, player['def'], textColor, isBlue: true),
_buildStatCell(context, player['mvp'], textColor, isGold: true),
])),
DataRow(
color: MaterialStateProperty.all(Colors.grey.shade50),
color: WidgetStateProperty.all(Theme.of(context).colorScheme.surface.withOpacity(0.5)),
cells: [
DataCell(Text('TOTAL EQUIPA', style: TextStyle(fontWeight: FontWeight.w900, color: Colors.black, fontSize: 12 * context.sf))),
DataCell(Center(child: Text(teamTotals['j'].toString(), style: const TextStyle(fontWeight: FontWeight.bold)))),
_buildStatCell(context, teamTotals['pts'], isHighlight: true),
_buildStatCell(context, teamTotals['ast']),
_buildStatCell(context, teamTotals['rbs']),
_buildStatCell(context, teamTotals['stl']),
_buildStatCell(context, teamTotals['blk']),
_buildStatCell(context, teamTotals['def'], isBlue: true),
_buildStatCell(context, teamTotals['mvp'], isGold: true),
DataCell(Text('TOTAL EQUIPA', style: TextStyle(fontWeight: FontWeight.w900, color: textColor, fontSize: 12 * context.sf))),
DataCell(Center(child: Text(teamTotals['j'].toString(), style: TextStyle(fontWeight: FontWeight.bold, color: textColor)))),
_buildStatCell(context, teamTotals['pts'], textColor, isHighlight: true),
_buildStatCell(context, teamTotals['ast'], textColor),
_buildStatCell(context, teamTotals['rbs'], textColor),
_buildStatCell(context, teamTotals['stl'], textColor),
_buildStatCell(context, teamTotals['blk'], textColor),
_buildStatCell(context, teamTotals['def'], textColor, isBlue: true),
_buildStatCell(context, teamTotals['mvp'], textColor, isGold: true),
]
)
],
@@ -189,37 +191,37 @@ class _StatusPageState extends State<StatusPage> {
);
}
DataColumn _buildSortableColumn(BuildContext context, String title, String sortKey) {
DataColumn _buildSortableColumn(BuildContext context, String title, String sortKey, Color textColor) {
return DataColumn(label: InkWell(
onTap: () => setState(() {
if (_sortColumn == sortKey) _isAscending = !_isAscending;
else { _sortColumn = sortKey; _isAscending = false; }
}),
child: Row(children: [
Text(title, style: TextStyle(fontSize: 12 * context.sf, fontWeight: FontWeight.bold)),
if (_sortColumn == sortKey) Icon(_isAscending ? Icons.arrow_drop_up : Icons.arrow_drop_down, size: 18 * context.sf, color: const Color(0xFFE74C3C)),
Text(title, style: TextStyle(fontSize: 12 * context.sf, fontWeight: FontWeight.bold, color: textColor)),
if (_sortColumn == sortKey) Icon(_isAscending ? Icons.arrow_drop_up : Icons.arrow_drop_down, size: 18 * context.sf, color: AppTheme.primaryRed),
]),
));
}
DataCell _buildStatCell(BuildContext context, int value, {bool isHighlight = false, bool isGold = false, bool isBlue = false}) {
DataCell _buildStatCell(BuildContext context, int value, Color textColor, {bool isHighlight = false, bool isGold = false, bool isBlue = false}) {
return DataCell(Center(child: Container(
padding: EdgeInsets.symmetric(horizontal: 8 * context.sf, vertical: 4 * context.sf),
decoration: BoxDecoration(color: isGold && value > 0 ? Colors.amber.withOpacity(0.2) : (isBlue && value > 0 ? Colors.blue.withOpacity(0.1) : Colors.transparent), borderRadius: BorderRadius.circular(6)),
child: Text(value == 0 ? "-" : value.toString(), style: TextStyle(
fontWeight: (isHighlight || isGold || isBlue) ? FontWeight.w900 : FontWeight.w600,
fontSize: 14 * context.sf, color: isGold && value > 0 ? Colors.orange.shade900 : (isBlue && value > 0 ? Colors.blue.shade800 : (isHighlight ? Colors.green.shade700 : Colors.black87))
fontSize: 14 * context.sf, color: isGold && value > 0 ? Colors.orange.shade900 : (isBlue && value > 0 ? Colors.blue.shade800 : (isHighlight ? AppTheme.successGreen : textColor))
)),
)));
}
void _showTeamSelector(BuildContext context) {
showModalBottomSheet(context: context, builder: (context) => StreamBuilder<List<Map<String, dynamic>>>(
showModalBottomSheet(context: context, backgroundColor: Theme.of(context).colorScheme.surface, builder: (context) => StreamBuilder<List<Map<String, dynamic>>>(
stream: _teamController.teamsStream,
builder: (context, snapshot) {
final teams = snapshot.data ?? [];
return ListView.builder(itemCount: teams.length, itemBuilder: (context, i) => ListTile(
title: Text(teams[i]['name']),
title: Text(teams[i]['name'], style: TextStyle(color: Theme.of(context).colorScheme.onSurface)),
onTap: () { setState(() { _selectedTeamId = teams[i]['id']; _selectedTeamName = teams[i]['name']; }); Navigator.pop(context); },
));
},