This commit is contained in:
2026-03-22 01:40:29 +00:00
parent 6c89b7ab8c
commit 00fee30792
23 changed files with 1717 additions and 2081 deletions

View File

@@ -1,38 +1,71 @@
class Game {
final String id;
final String userId;
final String myTeam;
final String opponentTeam;
final String? myTeamLogo; // URL da imagem
final String? opponentTeamLogo; // URL da imagem
final String myScore;
final String myScore;
final String opponentScore;
final String status;
final String season;
final String status;
final DateTime gameDate;
// Novos campos que estão na tua base de dados
final int remainingSeconds;
final int myTimeouts;
final int oppTimeouts;
final int currentQuarter;
final String topPtsName;
final String topAstName;
final String topRbsName;
final String topDefName;
final String mvpName;
Game({
required this.id,
required this.userId,
required this.myTeam,
required this.opponentTeam,
this.myTeamLogo,
this.opponentTeamLogo,
required this.myScore,
required this.opponentScore,
required this.status,
required this.season,
required this.status,
required this.gameDate,
required this.remainingSeconds,
required this.myTimeouts,
required this.oppTimeouts,
required this.currentQuarter,
required this.topPtsName,
required this.topAstName,
required this.topRbsName,
required this.topDefName,
required this.mvpName,
});
// No seu factory, certifique-se de mapear os campos da tabela (ou de um JOIN)
factory Game.fromMap(Map<String, dynamic> map) {
// 👇 A MÁGICA ACONTECE AQUI: Lemos os dados e protegemos os NULLs
factory Game.fromMap(Map<String, dynamic> json) {
return Game(
id: map['id'],
myTeam: map['my_team_name'],
opponentTeam: map['opponent_team_name'],
myTeamLogo: map['my_team_logo'], // Certifique-se que o Supabase retorna isto
opponentTeamLogo: map['opponent_team_logo'],
myScore: map['my_score'].toString(),
opponentScore: map['opponent_score'].toString(),
status: map['status'],
season: map['season'],
id: json['id']?.toString() ?? '',
userId: json['user_id']?.toString() ?? '',
myTeam: json['my_team']?.toString() ?? 'Minha Equipa',
opponentTeam: json['opponent_team']?.toString() ?? 'Adversário',
myScore: (json['my_score'] ?? 0).toString(), // Protege NULL e converte Int4 para String
opponentScore: (json['opponent_score'] ?? 0).toString(),
season: json['season']?.toString() ?? '---',
status: json['status']?.toString() ?? 'Decorrer',
gameDate: json['game_date'] != null ? DateTime.tryParse(json['game_date']) ?? DateTime.now() : DateTime.now(),
// Proteção para os Inteiros (se for NULL, assume 0)
remainingSeconds: json['remaining_seconds'] as int? ?? 600, // 600s = 10 minutos
myTimeouts: json['my_timeouts'] as int? ?? 0,
oppTimeouts: json['opp_timeouts'] as int? ?? 0,
currentQuarter: json['current_quarter'] as int? ?? 1,
// Proteção para os Nomes (se for NULL, assume '---')
topPtsName: json['top_pts_name']?.toString() ?? '---',
topAstName: json['top_ast_name']?.toString() ?? '---',
topRbsName: json['top_rbs_name']?.toString() ?? '---',
topDefName: json['top_def_name']?.toString() ?? '---',
mvpName: json['mvp_name']?.toString() ?? '---',
);
}
}

View File

@@ -3,24 +3,43 @@ class Person {
final String teamId;
final String name;
final String type; // 'Jogador' ou 'Treinador'
final String number;
final String? number; // O número é opcional (Treinadores não têm)
// 👇 A NOVA PROPRIEDADE AQUI!
final String? imageUrl;
Person({
required this.id,
required this.teamId,
required this.name,
required this.type,
required this.number,
this.number,
this.imageUrl, // 👇 ADICIONADO AO CONSTRUTOR
});
// Converte o JSON do Supabase para o objeto Person
// Lê os dados do Supabase e converte para a classe Person
factory Person.fromMap(Map<String, dynamic> map) {
return Person(
id: map['id'] ?? '',
teamId: map['team_id'] ?? '',
name: map['name'] ?? '',
type: map['type'] ?? 'Jogador',
number: map['number']?.toString() ?? '',
id: map['id']?.toString() ?? '',
teamId: map['team_id']?.toString() ?? '',
name: map['name']?.toString() ?? 'Desconhecido',
type: map['type']?.toString() ?? 'Jogador',
number: map['number']?.toString(),
// 👇 AGORA ELE JÁ SABE LER O LINK DA IMAGEM DA TUA BASE DE DADOS!
imageUrl: map['image_url']?.toString(),
);
}
// Prepara os dados para enviar para o Supabase (se necessário)
Map<String, dynamic> toMap() {
return {
'id': id,
'team_id': teamId,
'name': name,
'type': type,
'number': number,
'image_url': imageUrl, // 👇 TAMBÉM GUARDA A IMAGEM
};
}
}

View File

@@ -4,26 +4,33 @@ class Team {
final String season;
final String imageUrl;
final bool isFavorite;
final String createdAt;
final int playerCount; // 👇 NOVA VARIÁVEL AQUI
Team({
required this.id,
required this.name,
required this.season,
required this.imageUrl,
this.isFavorite = false
required this.isFavorite,
required this.createdAt,
this.playerCount = 0, // 👇 VALOR POR DEFEITO
});
// Mapeia o JSON que vem do Supabase (id costuma ser UUID ou String)
factory Team.fromMap(Map<String, dynamic> map) {
return Team(
id: map['id']?.toString() ?? '',
name: map['name'] ?? '',
season: map['season'] ?? '',
imageUrl: map['image_url'] ?? '',
name: map['name']?.toString() ?? 'Sem Nome',
season: map['season']?.toString() ?? '',
imageUrl: map['image_url']?.toString() ?? '',
isFavorite: map['is_favorite'] ?? false,
createdAt: map['created_at']?.toString() ?? '',
// 👇 AGORA ELE LÊ A CONTAGEM DA TUA NOVA VIEW!
playerCount: map['player_count'] != null ? int.tryParse(map['player_count'].toString()) ?? 0 : 0,
);
}
Map<String, dynamic> toMap() {
return {
'name': name,