mudar na tabela

This commit is contained in:
2026-04-20 15:02:00 +01:00
parent ce25fe6499
commit cc753b395d
3 changed files with 138 additions and 90 deletions

View File

@@ -252,8 +252,7 @@ class _PlacarPageState extends State<PlacarPage> {
children: [
_buildCornerBtn(heroTag: 'btn_heatmap', icon: Icons.local_fire_department, color: Colors.orange.shade800, size: cornerBtnSize, onTap: () => _showHeatmap(context)),
SizedBox(height: 10 * sf),
_buildCornerBtn(heroTag: 'btn_boxscore', icon: Icons.table_chart, color: Colors.indigo, size: cornerBtnSize, onTap: () => showDialog(context: context, builder: (ctx) => BoxScoreDialog(controller: _controller))),
],
_buildCornerBtn(heroTag: 'btn_boxscore', icon: Icons.table_chart, color: Colors.indigo, size: cornerBtnSize, onTap: () => showDialog(context: context, builder: (ctx) => BoxScoreDialog(controller: _controller, sf: sf))), ],
),
),
@@ -1335,7 +1334,9 @@ class PlayByPlayDialog extends StatelessWidget {
class BoxScoreDialog extends StatelessWidget {
final PlacarController controller;
const BoxScoreDialog({super.key, required this.controller});
final double sf;
const BoxScoreDialog({super.key, required this.controller, required this.sf});
@override
Widget build(BuildContext context) {
@@ -1344,38 +1345,62 @@ class BoxScoreDialog extends StatelessWidget {
builder: (context, child) {
return Dialog(
backgroundColor: AppTheme.placarDarkSurface,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Container(
width: MediaQuery.of(context).size.width * 0.9,
height: MediaQuery.of(context).size.height * 0.9,
padding: const EdgeInsets.all(16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12 * sf),
side: BorderSide(color: Colors.white24, width: 1 * sf),
),
// 👇 REDUZIMOS AS MARGENS PARA O POP-UP FICAR GIGANTE
insetPadding: EdgeInsets.all(8 * sf),
clipBehavior: Clip.antiAlias,
child: SizedBox(
// 👇 FORÇAMOS A LARGURA E ALTURA PARA 98% DO ECRÃ
width: MediaQuery.of(context).size.width * 0.98,
height: MediaQuery.of(context).size.height * 0.98,
child: DefaultTabController(
length: 2,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("BOX SCORE", style: TextStyle(color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold)),
IconButton(icon: const Icon(Icons.close, color: Colors.white), onPressed: () => Navigator.pop(context))
],
Padding(
padding: EdgeInsets.fromLTRB(16 * sf, 16 * sf, 8 * sf, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("BOX SCORE", style: TextStyle(color: Colors.white, fontSize: 20 * sf, fontWeight: FontWeight.bold)),
IconButton(
icon: Icon(Icons.close, color: Colors.white, size: 24 * sf),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () => Navigator.pop(context)
)
],
),
),
SizedBox(height: 8 * sf),
TabBar(
indicatorColor: AppTheme.warningAmber,
labelColor: Colors.white,
unselectedLabelColor: Colors.white54,
// 👇 LETRAS DAS ABAS MAIORES
labelStyle: TextStyle(fontSize: 14 * sf, fontWeight: FontWeight.bold),
indicatorWeight: 3 * sf,
dividerColor: Colors.white10,
tabs: [
Tab(text: controller.myTeam.toUpperCase()),
Tab(text: controller.opponentTeam.toUpperCase()),
Tab(text: controller.myTeam.toUpperCase(), height: 40 * sf),
Tab(text: controller.opponentTeam.toUpperCase(), height: 40 * sf),
],
),
const SizedBox(height: 10),
Expanded(
child: TabBarView(
children: [
_buildStatsTable(controller.myCourt + controller.myBench, controller),
_buildStatsTable(controller.oppCourt + controller.oppBench, controller),
],
child: Container(
width: double.infinity,
color: Colors.black12,
child: TabBarView(
children: [
_buildStatsTable(controller.myCourt + controller.myBench, controller, sf),
_buildStatsTable(controller.oppCourt + controller.oppBench, controller, sf),
],
),
),
),
],
@@ -1387,66 +1412,85 @@ class BoxScoreDialog extends StatelessWidget {
);
}
Widget _buildStatsTable(List<String> teamPlayers, PlacarController ctrl) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: DataTable(
headingRowColor: WidgetStateProperty.all(Colors.black26),
columns: const [
DataColumn(label: Text('JOGADOR', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('MIN', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('PTS', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('REB', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('AST', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('STL', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('BLK', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('TOV', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('FLS', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('SO', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('IL', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('LI', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('PA', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('3S', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('DR', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
DataColumn(label: Text('FG', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold))),
],
rows: teamPlayers.where((id) => !id.startsWith("fake_")).map((id) {
final name = ctrl.playerNames[id] ?? "---";
final s = ctrl.playerStats[id]!;
int totalSecs = s['sec'] ?? 0;
int minutes = totalSecs ~/ 60;
int seconds = totalSecs % 60;
String timeStr = '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
final rebs = s['orb']! + s['drb']!;
final fgText = "${s['fgm']}/${s['fga']}";
return DataRow(
cells: [
DataCell(Text(name, style: const TextStyle(color: Colors.white))),
DataCell(Text(timeStr, style: const TextStyle(color: Colors.white70))),
DataCell(Text(s['pts'].toString(), style: const TextStyle(color: AppTheme.warningAmber, fontWeight: FontWeight.bold))),
DataCell(Text(rebs.toString(), style: const TextStyle(color: Colors.white))),
DataCell(Text(s['ast'].toString(), style: const TextStyle(color: Colors.white))),
DataCell(Text(s['stl'].toString(), style: const TextStyle(color: Colors.white))),
DataCell(Text(s['blk'].toString(), style: const TextStyle(color: Colors.white))),
DataCell(Text(s['tov'].toString(), style: const TextStyle(color: Colors.redAccent))),
DataCell(Text(s['fls'].toString(), style: const TextStyle(color: Colors.white))),
DataCell(Text((s['so'] ?? 0).toString(), style: const TextStyle(color: Colors.greenAccent))),
DataCell(Text((s['il'] ?? 0).toString(), style: const TextStyle(color: Colors.lightBlue))),
DataCell(Text((s['li'] ?? 0).toString(), style: const TextStyle(color: Colors.orangeAccent))),
DataCell(Text((s['pa'] ?? 0).toString(), style: const TextStyle(color: Colors.redAccent))),
DataCell(Text((s['tres_s'] ?? 0).toString(), style: const TextStyle(color: Colors.redAccent))),
DataCell(Text((s['dr'] ?? 0).toString(), style: const TextStyle(color: Colors.redAccent))),
DataCell(Text(fgText, style: const TextStyle(color: Colors.white54))),
],
);
}).toList(),
),
),
Widget _buildStatsTable(List<String> teamPlayers, PlacarController ctrl, double sf) {
return LayoutBuilder(
builder: (context, constraints) {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
// 👇 O SEGREDO ESTÁ AQUI: Este BouncingScrollPhysics permite que o gesto de "swipe"
// passe para as abas quando chegas ao fim da tabela!
physics: const BouncingScrollPhysics(),
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
// 👇 E AQUI TAMBÉM
physics: const BouncingScrollPhysics(),
child: ConstrainedBox(
constraints: BoxConstraints(minWidth: constraints.maxWidth),
child: DataTable(
headingRowColor: WidgetStateProperty.all(AppTheme.placarListCard),
columnSpacing: 18 * sf,
horizontalMargin: 16 * sf,
headingRowHeight: 45 * sf,
dataRowMinHeight: 40 * sf,
dataRowMaxHeight: 45 * sf,
headingTextStyle: TextStyle(color: Colors.white70, fontWeight: FontWeight.bold, fontSize: 13 * sf),
dataTextStyle: TextStyle(color: Colors.white, fontSize: 13 * sf),
columns: const [
DataColumn(label: Text('JOGADOR')),
DataColumn(label: Text('MIN')),
DataColumn(label: Text('PTS')),
DataColumn(label: Text('REB')),
DataColumn(label: Text('AST')),
DataColumn(label: Text('STL')),
DataColumn(label: Text('BLK')),
DataColumn(label: Text('TOV')),
DataColumn(label: Text('FLS')),
DataColumn(label: Text('SO')),
DataColumn(label: Text('IL')),
DataColumn(label: Text('LI')),
DataColumn(label: Text('PA')),
DataColumn(label: Text('3S')),
DataColumn(label: Text('DR')),
DataColumn(label: Text('FG')),
],
rows: teamPlayers.where((id) => !id.startsWith("fake_")).map((id) {
final name = ctrl.playerNames[id] ?? "---";
final s = ctrl.playerStats[id]!;
int totalSecs = s['sec'] ?? 0;
int minutes = totalSecs ~/ 60;
int seconds = totalSecs % 60;
String timeStr = '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
final rebs = s['orb']! + s['drb']!;
final fgText = "${s['fgm']}/${s['fga']}";
return DataRow(
cells: [
DataCell(Text(name, style: const TextStyle(fontWeight: FontWeight.bold))),
DataCell(Text(timeStr, style: const TextStyle(color: Colors.white70))),
DataCell(Text(s['pts'].toString(), style: TextStyle(color: AppTheme.warningAmber, fontWeight: FontWeight.bold, fontSize: 14 * sf))),
DataCell(Text(rebs.toString())),
DataCell(Text(s['ast'].toString())),
DataCell(Text(s['stl'].toString())),
DataCell(Text(s['blk'].toString())),
DataCell(Text(s['tov'].toString(), style: const TextStyle(color: Colors.redAccent))),
DataCell(Text(s['fls'].toString())),
DataCell(Text((s['so'] ?? 0).toString(), style: const TextStyle(color: Colors.greenAccent))),
DataCell(Text((s['il'] ?? 0).toString(), style: const TextStyle(color: Colors.lightBlue))),
DataCell(Text((s['li'] ?? 0).toString(), style: const TextStyle(color: Colors.orangeAccent))),
DataCell(Text((s['pa'] ?? 0).toString(), style: const TextStyle(color: Colors.redAccent))),
DataCell(Text((s['tres_s'] ?? 0).toString(), style: const TextStyle(color: Colors.redAccent))),
DataCell(Text((s['dr'] ?? 0).toString(), style: const TextStyle(color: Colors.redAccent))),
DataCell(Text(fgText, style: const TextStyle(color: Colors.white54))),
],
);
}).toList(),
),
),
),
);
}
);
}
}

View File

@@ -6,6 +6,7 @@ import '../controllers/team_controller.dart';
import '../controllers/game_controller.dart';
import '../models/game_model.dart';
import '../utils/size_extension.dart';
import 'pdf_export_service.dart';
class GameResultCard extends StatelessWidget {