pdf e exel

This commit is contained in:
2026-05-06 12:47:17 +01:00
parent c3a90f2816
commit 60656d77e8
14 changed files with 1512 additions and 951 deletions

View File

@@ -1,13 +1,15 @@
import 'package:supabase_flutter/supabase_flutter.dart';
import '../models/game_model.dart';
import 'package:flutter/material.dart';
import 'package:playmaker/pages/PlacarPage.dart';
import 'package:playmaker/classe/theme.dart';
import 'package:cached_network_image/cached_network_image.dart';
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';
import 'excel_export_service.dart';
class GameResultCard extends StatelessWidget {
final String gameId, myTeam, opponentTeam, myScore, opponentScore, status, season;
@@ -21,6 +23,67 @@ class GameResultCard extends StatelessWidget {
this.myTeamLogo, this.opponentTeamLogo, required this.sf, required this.onDelete,
});
void _showTeamSelectionDialog(BuildContext context, String format) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
backgroundColor: Theme.of(context).colorScheme.surface,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15 * sf)),
title: Text('Gerar ${format.toUpperCase()}', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16 * sf, color: Theme.of(context).colorScheme.onSurface)),
content: Text('De qual equipa pretende exportar as estatísticas?', style: TextStyle(fontSize: 14 * sf, color: Theme.of(context).colorScheme.onSurface)),
actions: [
TextButton(
onPressed: () {
Navigator.pop(ctx);
_exportDocument(context, format, myTeam);
},
child: Text(myTeam, style: TextStyle(color: AppTheme.primaryRed, fontSize: 14 * sf))
),
TextButton(
onPressed: () {
Navigator.pop(ctx);
_exportDocument(context, format, opponentTeam);
},
child: Text(opponentTeam, style: TextStyle(color: AppTheme.primaryRed, fontSize: 14 * sf))
),
TextButton(
onPressed: () {
Navigator.pop(ctx);
_exportDocument(context, format, 'Ambas');
},
child: Text('Ambas', style: TextStyle(color: AppTheme.primaryRed, fontWeight: FontWeight.bold, fontSize: 14 * sf))
),
],
)
);
}
Future<void> _exportDocument(BuildContext context, String format, String targetTeam) async {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('A gerar ${format.toUpperCase()}...'), duration: const Duration(seconds: 1)));
if (format == 'pdf') {
await PdfExportService.generateAndPrintBoxScore(
gameId: gameId,
myTeam: myTeam,
opponentTeam: opponentTeam,
myScore: myScore,
opponentScore: opponentScore,
season: season,
targetTeam: targetTeam,
);
} else if (format == 'excel') {
await ExcelExportService.generateAndPrintBoxScoreExcel(
gameId: gameId,
myTeam: myTeam,
opponentTeam: opponentTeam,
myScore: myScore,
opponentScore: opponentScore,
season: season,
targetTeam: targetTeam,
);
}
}
@override
Widget build(BuildContext context) {
final bgColor = Theme.of(context).cardTheme.color ?? Theme.of(context).colorScheme.surface;
@@ -46,32 +109,71 @@ class GameResultCard extends StatelessWidget {
],
),
// 👇 MENU DOS 3 PONTOS (MAIS NÍTIDO E MODERNO)
Positioned(
top: -10 * sf,
right: -10 * sf,
child: Row(
children: [
IconButton(
icon: Icon(Icons.picture_as_pdf, color: AppTheme.primaryRed.withOpacity(0.8), size: 22 * sf),
splashRadius: 20 * sf,
tooltip: 'Gerar PDF',
onPressed: () async {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('A gerar PDF...'), duration: Duration(seconds: 1)));
await PdfExportService.generateAndPrintBoxScore(
gameId: gameId,
myTeam: myTeam,
opponentTeam: opponentTeam,
myScore: myScore,
opponentScore: opponentScore,
season: season,
);
},
top: -12 * sf,
right: -12 * sf,
child: PopupMenuButton<String>(
icon: Icon(Icons.more_vert, color: Colors.grey.shade600, size: 26 * sf), // Ícone um pouco maior
splashRadius: 24 * sf,
elevation: 8, // Adiciona sombra para não se misturar com o fundo
shadowColor: Colors.black45,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16 * sf)),
color: Theme.of(context).colorScheme.surface,
surfaceTintColor: Theme.of(context).colorScheme.surface, // Previne que o material 3 mude a cor
onSelected: (value) {
if (value == 'pdf' || value == 'excel') {
_showTeamSelectionDialog(context, value);
} else if (value == 'delete') {
_showDeleteConfirmation(context);
}
},
itemBuilder: (context) => [
PopupMenuItem(
value: 'pdf',
child: Row(
children: [
// Ícone com fundo arredondado
Container(
padding: EdgeInsets.all(8 * sf),
decoration: BoxDecoration(color: AppTheme.primaryRed.withOpacity(0.1), shape: BoxShape.circle),
child: Icon(Icons.picture_as_pdf, color: AppTheme.primaryRed, size: 20 * sf),
),
SizedBox(width: 14 * sf),
Text('Gerar PDF', style: TextStyle(fontSize: 15 * sf, color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold)),
],
),
),
IconButton(
icon: Icon(Icons.delete_outline, color: Colors.grey.shade400, size: 22 * sf),
splashRadius: 20 * sf,
tooltip: 'Eliminar Jogo',
onPressed: () => _showDeleteConfirmation(context),
PopupMenuItem(
value: 'excel',
child: Row(
children: [
// Ícone com fundo arredondado
Container(
padding: EdgeInsets.all(8 * sf),
decoration: BoxDecoration(color: Colors.green.shade600.withOpacity(0.1), shape: BoxShape.circle),
child: Icon(Icons.table_chart, color: Colors.green.shade600, size: 20 * sf),
),
SizedBox(width: 14 * sf),
Text('Gerar Excel', style: TextStyle(fontSize: 15 * sf, color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold)),
],
),
),
const PopupMenuDivider(height: 1),
PopupMenuItem(
value: 'delete',
child: Row(
children: [
// Ícone com fundo arredondado
Container(
padding: EdgeInsets.all(8 * sf),
decoration: BoxDecoration(color: Colors.grey.shade500.withOpacity(0.1), shape: BoxShape.circle),
child: Icon(Icons.delete_outline, color: Colors.grey.shade700, size: 20 * sf),
),
SizedBox(width: 14 * sf),
Text('Eliminar Jogo', style: TextStyle(fontSize: 15 * sf, color: Theme.of(context).colorScheme.onSurface, fontWeight: FontWeight.bold)),
],
),
),
],
),