historico de jogos
This commit is contained in:
@@ -23,6 +23,9 @@ class PlacarController {
|
||||
|
||||
bool isLoading = true;
|
||||
bool isSaving = false;
|
||||
|
||||
// 👇 TRINCO DE SEGURANÇA: Evita contar vitórias duas vezes se clicares no Guardar repetidamente!
|
||||
bool gameWasAlreadyFinished = false;
|
||||
|
||||
int myScore = 0;
|
||||
int opponentScore = 0;
|
||||
@@ -62,7 +65,6 @@ class PlacarController {
|
||||
try {
|
||||
await Future.delayed(const Duration(milliseconds: 1500));
|
||||
|
||||
// 1. Limpar estados para evitar duplicação
|
||||
myCourt.clear();
|
||||
myBench.clear();
|
||||
oppCourt.clear();
|
||||
@@ -73,7 +75,6 @@ class PlacarController {
|
||||
myFouls = 0;
|
||||
opponentFouls = 0;
|
||||
|
||||
// 2. Buscar dados básicos do JOGO
|
||||
final gameResponse = await supabase.from('games').select().eq('id', gameId).single();
|
||||
|
||||
myScore = int.tryParse(gameResponse['my_score']?.toString() ?? '0') ?? 0;
|
||||
@@ -85,25 +86,24 @@ class PlacarController {
|
||||
myTimeoutsUsed = int.tryParse(gameResponse['my_timeouts']?.toString() ?? '0') ?? 0;
|
||||
opponentTimeoutsUsed = int.tryParse(gameResponse['opp_timeouts']?.toString() ?? '0') ?? 0;
|
||||
currentQuarter = int.tryParse(gameResponse['current_quarter']?.toString() ?? '1') ?? 1;
|
||||
|
||||
// 👇 Verifica se o jogo já tinha acabado noutra sessão
|
||||
gameWasAlreadyFinished = gameResponse['status'] == 'Terminado';
|
||||
|
||||
// 3. Buscar os IDs das equipas
|
||||
final teamsResponse = await supabase.from('teams').select('id, name').inFilter('name', [myTeam, opponentTeam]);
|
||||
for (var t in teamsResponse) {
|
||||
if (t['name'] == myTeam) myTeamDbId = t['id'];
|
||||
if (t['name'] == opponentTeam) oppTeamDbId = t['id'];
|
||||
}
|
||||
|
||||
// 4. Buscar os Jogadores
|
||||
List<dynamic> myPlayers = myTeamDbId != null ? await supabase.from('members').select().eq('team_id', myTeamDbId!).eq('type', 'Jogador') : [];
|
||||
List<dynamic> oppPlayers = oppTeamDbId != null ? await supabase.from('members').select().eq('team_id', oppTeamDbId!).eq('type', 'Jogador') : [];
|
||||
|
||||
// 5. BUSCAR ESTATÍSTICAS JÁ SALVAS
|
||||
final statsResponse = await supabase.from('player_stats').select().eq('game_id', gameId);
|
||||
final Map<String, dynamic> savedStats = {
|
||||
for (var item in statsResponse) item['member_id'].toString(): item
|
||||
};
|
||||
|
||||
// 6. Registar a tua equipa
|
||||
for (int i = 0; i < myPlayers.length; i++) {
|
||||
String dbId = myPlayers[i]['id'].toString();
|
||||
String name = myPlayers[i]['name'].toString();
|
||||
@@ -116,14 +116,13 @@ class PlacarController {
|
||||
"pts": s['pts'] ?? 0, "rbs": s['rbs'] ?? 0, "ast": s['ast'] ?? 0,
|
||||
"stl": s['stl'] ?? 0, "tov": s['tov'] ?? 0, "blk": s['blk'] ?? 0,
|
||||
"fls": s['fls'] ?? 0, "fgm": s['fgm'] ?? 0, "fga": s['fga'] ?? 0,
|
||||
"ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0, // <-- VARIÁVEIS NOVAS AQUI!
|
||||
"ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0,
|
||||
};
|
||||
myFouls += (s['fls'] as int? ?? 0);
|
||||
}
|
||||
}
|
||||
_padTeam(myCourt, myBench, "Jogador", isMyTeam: true);
|
||||
|
||||
// 7. Registar a equipa adversária
|
||||
for (int i = 0; i < oppPlayers.length; i++) {
|
||||
String dbId = oppPlayers[i]['id'].toString();
|
||||
String name = oppPlayers[i]['name'].toString();
|
||||
@@ -136,7 +135,7 @@ class PlacarController {
|
||||
"pts": s['pts'] ?? 0, "rbs": s['rbs'] ?? 0, "ast": s['ast'] ?? 0,
|
||||
"stl": s['stl'] ?? 0, "tov": s['tov'] ?? 0, "blk": s['blk'] ?? 0,
|
||||
"fls": s['fls'] ?? 0, "fgm": s['fgm'] ?? 0, "fga": s['fga'] ?? 0,
|
||||
"ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0, // <-- VARIÁVEIS NOVAS AQUI!
|
||||
"ftm": s['ftm'] ?? 0, "fta": s['fta'] ?? 0, "orb": s['orb'] ?? 0, "drb": s['drb'] ?? 0,
|
||||
};
|
||||
opponentFouls += (s['fls'] as int? ?? 0);
|
||||
}
|
||||
@@ -159,7 +158,6 @@ class PlacarController {
|
||||
playerNumbers[name] = number;
|
||||
if (dbId != null) playerDbIds[name] = dbId;
|
||||
|
||||
// 👇 ADICIONEI AS 4 VARIÁVEIS NOVAS AQUI!
|
||||
playerStats[name] = {
|
||||
"pts": 0, "rbs": 0, "ast": 0, "stl": 0, "tov": 0, "blk": 0,
|
||||
"fls": 0, "fgm": 0, "fga": 0, "ftm": 0, "fta": 0, "orb": 0, "drb": 0
|
||||
@@ -178,7 +176,6 @@ class PlacarController {
|
||||
}
|
||||
}
|
||||
|
||||
// --- TEMPO E TIMEOUTS ---
|
||||
void toggleTimer(BuildContext context) {
|
||||
if (isRunning) {
|
||||
timer?.cancel();
|
||||
@@ -194,12 +191,11 @@ class PlacarController {
|
||||
duration = const Duration(minutes: 10);
|
||||
myFouls = 0;
|
||||
opponentFouls = 0;
|
||||
// 👇 ESTAS DUAS LINHAS ZERAM OS TIMEOUTS NO NOVO PERÍODO
|
||||
myTimeoutsUsed = 0;
|
||||
opponentTimeoutsUsed = 0;
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Período $currentQuarter iniciado. Faltas e Timeouts resetados!'), backgroundColor: Colors.blue));
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('FIM DO JOGO!'), backgroundColor: Colors.red));
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('FIM DO JOGO! Clica em Guardar para fechar a partida.'), backgroundColor: Colors.red));
|
||||
}
|
||||
}
|
||||
onUpdate();
|
||||
@@ -222,7 +218,6 @@ class PlacarController {
|
||||
|
||||
String formatTime() => "${duration.inMinutes.toString().padLeft(2, '0')}:${duration.inSeconds.remainder(60).toString().padLeft(2, '0')}";
|
||||
|
||||
// --- LÓGICA DE JOGO & VALIDAÇÃO GEOMÉTRICA DE ZONAS ---
|
||||
void handleActionDrag(BuildContext context, String action, String playerData) {
|
||||
String name = playerData.replaceAll("player_my_", "").replaceAll("player_opp_", "");
|
||||
final stats = playerStats[name]!;
|
||||
@@ -268,21 +263,13 @@ class PlacarController {
|
||||
|
||||
void registerShotLocation(BuildContext context, Offset position, Size size) {
|
||||
if (pendingAction == null || pendingPlayer == null) return;
|
||||
|
||||
bool is3Pt = pendingAction!.contains("_3");
|
||||
bool is2Pt = pendingAction!.contains("_2");
|
||||
|
||||
if (is3Pt || is2Pt) {
|
||||
bool isValid = _validateShotZone(position, size, is3Pt);
|
||||
|
||||
if (!isValid) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('🛑Local de lançamento incompatível com a pontuação.'),
|
||||
backgroundColor: Colors.red,
|
||||
duration: Duration(seconds: 2),
|
||||
)
|
||||
);
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('🛑 Local de lançamento incompatível com a pontuação.'), backgroundColor: Colors.red, duration: Duration(seconds: 2)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -298,31 +285,20 @@ class PlacarController {
|
||||
}
|
||||
|
||||
bool _validateShotZone(Offset pos, Size size, bool is3Pt) {
|
||||
double w = size.width;
|
||||
double h = size.height;
|
||||
|
||||
double w = size.width; double h = size.height;
|
||||
Offset leftHoop = Offset(w * 0.12, h * 0.5);
|
||||
Offset rightHoop = Offset(w * 0.88, h * 0.5);
|
||||
double threePointRadius = w * 0.28;
|
||||
|
||||
Offset activeHoop = pos.dx < w / 2 ? leftHoop : rightHoop;
|
||||
double distanceToHoop = (pos - activeHoop).distance;
|
||||
bool isCorner3 = (pos.dy < h * 0.15 || pos.dy > h * 0.85) && (pos.dx < w * 0.20 || pos.dx > w * 0.80);
|
||||
|
||||
bool isCorner3 = (pos.dy < h * 0.15 || pos.dy > h * 0.85) &&
|
||||
(pos.dx < w * 0.20 || pos.dx > w * 0.80);
|
||||
|
||||
if (is3Pt) {
|
||||
return distanceToHoop >= threePointRadius || isCorner3;
|
||||
} else {
|
||||
return distanceToHoop < threePointRadius && !isCorner3;
|
||||
}
|
||||
if (is3Pt) return distanceToHoop >= threePointRadius || isCorner3;
|
||||
else return distanceToHoop < threePointRadius && !isCorner3;
|
||||
}
|
||||
|
||||
void cancelShotLocation() {
|
||||
isSelectingShotLocation = false;
|
||||
pendingAction = null;
|
||||
pendingPlayer = null;
|
||||
onUpdate();
|
||||
isSelectingShotLocation = false; pendingAction = null; pendingPlayer = null; onUpdate();
|
||||
}
|
||||
|
||||
void commitStat(String action, String playerData) {
|
||||
@@ -335,7 +311,7 @@ class PlacarController {
|
||||
if (isOpponent) opponentScore += pts; else myScore += pts;
|
||||
stats["pts"] = stats["pts"]! + pts;
|
||||
if (pts == 2 || pts == 3) { stats["fgm"] = stats["fgm"]! + 1; stats["fga"] = stats["fga"]! + 1; }
|
||||
if (pts == 1) { stats["ftm"] = stats["ftm"]! + 1; stats["fta"] = stats["fta"]! + 1; } // ADICIONADO LANCE LIVRE (FTM/FTA)
|
||||
if (pts == 1) { stats["ftm"] = stats["ftm"]! + 1; stats["fta"] = stats["fta"]! + 1; }
|
||||
}
|
||||
else if (action.startsWith("sub_pts_")) {
|
||||
int pts = int.parse(action.split("_").last);
|
||||
@@ -346,15 +322,15 @@ class PlacarController {
|
||||
if (stats["fgm"]! > 0) stats["fgm"] = stats["fgm"]! - 1;
|
||||
if (stats["fga"]! > 0) stats["fga"] = stats["fga"]! - 1;
|
||||
}
|
||||
if (pts == 1) { // ADICIONADO SUBTRAÇÃO LANCE LIVRE
|
||||
if (pts == 1) {
|
||||
if (stats["ftm"]! > 0) stats["ftm"] = stats["ftm"]! - 1;
|
||||
if (stats["fta"]! > 0) stats["fta"] = stats["fta"]! - 1;
|
||||
}
|
||||
}
|
||||
else if (action == "miss_1") { stats["fta"] = stats["fta"]! + 1; } // ADICIONADO BOTAO M1
|
||||
else if (action == "miss_1") { stats["fta"] = stats["fta"]! + 1; }
|
||||
else if (action == "miss_2" || action == "miss_3") { stats["fga"] = stats["fga"]! + 1; }
|
||||
else if (action == "add_orb") { stats["orb"] = stats["orb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; } // SEPARAÇÃO ORB
|
||||
else if (action == "add_drb") { stats["drb"] = stats["drb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; } // SEPARAÇÃO DRB
|
||||
else if (action == "add_orb") { stats["orb"] = stats["orb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; }
|
||||
else if (action == "add_drb") { stats["drb"] = stats["drb"]! + 1; stats["rbs"] = stats["rbs"]! + 1; }
|
||||
else if (action == "add_ast") { stats["ast"] = stats["ast"]! + 1; }
|
||||
else if (action == "add_stl") { stats["stl"] = stats["stl"]! + 1; }
|
||||
else if (action == "add_tov") { stats["tov"] = stats["tov"]! + 1; }
|
||||
@@ -376,6 +352,10 @@ class PlacarController {
|
||||
onUpdate();
|
||||
|
||||
try {
|
||||
bool isGameFinishedNow = currentQuarter >= 4 && duration.inSeconds == 0;
|
||||
String newStatus = isGameFinishedNow ? 'Terminado' : 'Pausado';
|
||||
|
||||
// 1. Atualizar o Jogo na BD
|
||||
await supabase.from('games').update({
|
||||
'my_score': myScore,
|
||||
'opponent_score': opponentScore,
|
||||
@@ -383,47 +363,69 @@ class PlacarController {
|
||||
'my_timeouts': myTimeoutsUsed,
|
||||
'opp_timeouts': opponentTimeoutsUsed,
|
||||
'current_quarter': currentQuarter,
|
||||
'status': currentQuarter >= 4 && duration.inSeconds == 0 ? 'Terminado' : 'Pausado',
|
||||
'status': newStatus,
|
||||
}).eq('id', gameId);
|
||||
|
||||
List<Map<String, dynamic>> batchStats = [];
|
||||
// 👇 2. LÓGICA DE VITÓRIAS, DERROTAS E EMPATES 👇
|
||||
if (isGameFinishedNow && !gameWasAlreadyFinished && myTeamDbId != null && oppTeamDbId != null) {
|
||||
|
||||
// Vai buscar os dados atuais das equipas
|
||||
final teamsData = await supabase.from('teams').select('id, wins, losses, draws').inFilter('id', [myTeamDbId, oppTeamDbId]);
|
||||
|
||||
Map<String, dynamic> myTeamUpdate = {};
|
||||
Map<String, dynamic> oppTeamUpdate = {};
|
||||
|
||||
for(var t in teamsData) {
|
||||
if(t['id'].toString() == myTeamDbId) myTeamUpdate = Map.from(t);
|
||||
if(t['id'].toString() == oppTeamDbId) oppTeamUpdate = Map.from(t);
|
||||
}
|
||||
|
||||
// Calcula os resultados
|
||||
if (myScore > opponentScore) {
|
||||
myTeamUpdate['wins'] = (myTeamUpdate['wins'] ?? 0) + 1;
|
||||
oppTeamUpdate['losses'] = (oppTeamUpdate['losses'] ?? 0) + 1;
|
||||
} else if (myScore < opponentScore) {
|
||||
myTeamUpdate['losses'] = (myTeamUpdate['losses'] ?? 0) + 1;
|
||||
oppTeamUpdate['wins'] = (oppTeamUpdate['wins'] ?? 0) + 1;
|
||||
} else {
|
||||
// Empate
|
||||
myTeamUpdate['draws'] = (myTeamUpdate['draws'] ?? 0) + 1;
|
||||
oppTeamUpdate['draws'] = (oppTeamUpdate['draws'] ?? 0) + 1;
|
||||
}
|
||||
|
||||
// Envia as atualizações para a tabela 'teams'
|
||||
await supabase.from('teams').update({
|
||||
'wins': myTeamUpdate['wins'], 'losses': myTeamUpdate['losses'], 'draws': myTeamUpdate['draws']
|
||||
}).eq('id', myTeamDbId!);
|
||||
|
||||
await supabase.from('teams').update({
|
||||
'wins': oppTeamUpdate['wins'], 'losses': oppTeamUpdate['losses'], 'draws': oppTeamUpdate['draws']
|
||||
}).eq('id', oppTeamDbId!);
|
||||
|
||||
// Bloqueia o trinco para não contar 2 vezes se o utilizador clicar "Guardar" outra vez
|
||||
gameWasAlreadyFinished = true;
|
||||
}
|
||||
|
||||
// 3. Atualizar as Estatísticas dos Jogadores
|
||||
List<Map<String, dynamic>> batchStats = [];
|
||||
playerStats.forEach((playerName, stats) {
|
||||
String? memberDbId = playerDbIds[playerName];
|
||||
|
||||
if (memberDbId != null && stats.values.any((val) => val > 0)) {
|
||||
bool isMyTeamPlayer = myCourt.contains(playerName) || myBench.contains(playerName);
|
||||
String teamId = isMyTeamPlayer ? myTeamDbId! : oppTeamDbId!;
|
||||
|
||||
batchStats.add({
|
||||
'game_id': gameId,
|
||||
'member_id': memberDbId,
|
||||
'team_id': teamId,
|
||||
'pts': stats['pts'],
|
||||
'rbs': stats['rbs'],
|
||||
'ast': stats['ast'],
|
||||
'stl': stats['stl'],
|
||||
'blk': stats['blk'],
|
||||
'tov': stats['tov'],
|
||||
'fls': stats['fls'],
|
||||
'fgm': stats['fgm'],
|
||||
'fga': stats['fga'],
|
||||
'ftm': stats['ftm'], // <-- GRAVAR NA BD
|
||||
'fta': stats['fta'], // <-- GRAVAR NA BD
|
||||
'orb': stats['orb'], // <-- GRAVAR NA BD
|
||||
'drb': stats['drb'], // <-- GRAVAR NA BD
|
||||
'game_id': gameId, 'member_id': memberDbId, 'team_id': isMyTeamPlayer ? myTeamDbId! : oppTeamDbId!,
|
||||
'pts': stats['pts'], 'rbs': stats['rbs'], 'ast': stats['ast'], 'stl': stats['stl'], 'blk': stats['blk'], 'tov': stats['tov'], 'fls': stats['fls'], 'fgm': stats['fgm'], 'fga': stats['fga'], 'ftm': stats['ftm'], 'fta': stats['fta'], 'orb': stats['orb'], 'drb': stats['drb'],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
await supabase.from('player_stats').delete().eq('game_id', gameId);
|
||||
|
||||
if (batchStats.isNotEmpty) {
|
||||
await supabase.from('player_stats').insert(batchStats);
|
||||
}
|
||||
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Estatísticas guardadas com Sucesso!'), backgroundColor: Colors.green));
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Estatísticas e Resultados guardados com Sucesso!'), backgroundColor: Colors.green));
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
/*import 'package:flutter/material.dart';
|
||||
import 'package:supabase_flutter/supabase_flutter.dart';
|
||||
import '../models/person_model.dart';
|
||||
|
||||
class StatsController {
|
||||
final SupabaseClient _supabase = Supabase.instance.client;
|
||||
|
||||
// 1. LER
|
||||
Stream<List<Person>> getMembers(String teamId) {
|
||||
return _supabase
|
||||
.from('members')
|
||||
.stream(primaryKey: ['id'])
|
||||
.eq('team_id', teamId)
|
||||
.order('name', ascending: true)
|
||||
.map((data) => data.map((json) => Person.fromMap(json)).toList());
|
||||
}
|
||||
|
||||
// 2. APAGAR
|
||||
Future<void> deletePerson(String personId) async {
|
||||
try {
|
||||
await _supabase.from('members').delete().eq('id', personId);
|
||||
} catch (e) {
|
||||
debugPrint("Erro ao eliminar: $e");
|
||||
}
|
||||
}
|
||||
|
||||
// 3. DIÁLOGOS
|
||||
void showAddPersonDialog(BuildContext context, String teamId) {
|
||||
_showForm(context, teamId: teamId);
|
||||
}
|
||||
|
||||
void showEditPersonDialog(BuildContext context, String teamId, Person person) {
|
||||
_showForm(context, teamId: teamId, person: person);
|
||||
}
|
||||
|
||||
// --- O POPUP ESTÁ AQUI ---
|
||||
void _showForm(BuildContext context, {required String teamId, Person? person}) {
|
||||
final isEdit = person != null;
|
||||
final nameCtrl = TextEditingController(text: person?.name ?? '');
|
||||
final numCtrl = TextEditingController(text: person?.number ?? '');
|
||||
|
||||
// Define o valor inicial
|
||||
String selectedType = person?.type ?? 'Jogador';
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => StatefulBuilder(
|
||||
builder: (ctx, setState) => AlertDialog(
|
||||
title: Text(isEdit ? "Editar" : "Adicionar"),
|
||||
content: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// NOME
|
||||
TextField(
|
||||
controller: nameCtrl,
|
||||
decoration: const InputDecoration(labelText: "Nome"),
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
|
||||
// FUNÇÃO
|
||||
DropdownButtonFormField<String>(
|
||||
value: selectedType,
|
||||
decoration: const InputDecoration(labelText: "Função"),
|
||||
items: ["Jogador", "Treinador"]
|
||||
.map((e) => DropdownMenuItem(value: e, child: Text(e)))
|
||||
.toList(),
|
||||
onChanged: (v) {
|
||||
if (v != null) setState(() => selectedType = v);
|
||||
},
|
||||
),
|
||||
|
||||
// NÚMERO (Só aparece se for Jogador)
|
||||
if (selectedType == "Jogador") ...[
|
||||
const SizedBox(height: 10),
|
||||
TextField(
|
||||
controller: numCtrl,
|
||||
decoration: const InputDecoration(labelText: "Número da Camisola"),
|
||||
keyboardType: TextInputType.text, // Aceita texto para evitar erros
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx),
|
||||
child: const Text("Cancelar")
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(backgroundColor: const Color(0xFF00C853)),
|
||||
onPressed: () async {
|
||||
print("--- 1. CLICOU EM GUARDAR ---");
|
||||
|
||||
// Validação Simples
|
||||
if (nameCtrl.text.trim().isEmpty) {
|
||||
print("ERRO: Nome vazio");
|
||||
return;
|
||||
}
|
||||
|
||||
// Lógica do Número:
|
||||
// Se for Treinador -> envia NULL
|
||||
// Se for Jogador e estiver vazio -> envia NULL
|
||||
// Se tiver texto -> envia o Texto
|
||||
String? numeroFinal;
|
||||
if (selectedType == "Treinador") {
|
||||
numeroFinal = null;
|
||||
} else {
|
||||
numeroFinal = numCtrl.text.trim().isEmpty ? null : numCtrl.text.trim();
|
||||
}
|
||||
|
||||
print("--- 2. DADOS A ENVIAR ---");
|
||||
print("Nome: ${nameCtrl.text}");
|
||||
print("Tipo: $selectedType");
|
||||
print("Número: $numeroFinal");
|
||||
|
||||
try {
|
||||
if (isEdit) {
|
||||
await _supabase.from('members').update({
|
||||
'name': nameCtrl.text.trim(),
|
||||
'type': selectedType,
|
||||
'number': numeroFinal,
|
||||
}).eq('id', person!.id);
|
||||
} else {
|
||||
await _supabase.from('members').insert({
|
||||
'team_id': teamId, // Verifica se este teamId é válido!
|
||||
'name': nameCtrl.text.trim(),
|
||||
'type': selectedType,
|
||||
'number': numeroFinal,
|
||||
});
|
||||
}
|
||||
|
||||
print("--- 3. SUCESSO! FECHANDO DIÁLOGO ---");
|
||||
if (ctx.mounted) Navigator.pop(ctx);
|
||||
|
||||
} catch (e) {
|
||||
print("--- X. ERRO AO GUARDAR ---");
|
||||
print(e.toString());
|
||||
|
||||
// MOSTRA O ERRO NO TELEMÓVEL
|
||||
if (ctx.mounted) {
|
||||
ScaffoldMessenger.of(ctx).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text("Erro: $e"),
|
||||
backgroundColor: Colors.red,
|
||||
duration: const Duration(seconds: 4),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: const Text("Guardar", style: TextStyle(color: Colors.white)),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}*/
|
||||
Reference in New Issue
Block a user