Files
philip b239ae3e5f Initial commit: Flutter app + PHP/MySQL backend on Hostinger
Replaces Firebase with a self-hosted PHP/MySQL API served from
winded.prymsolutions.com. Includes full backend (schema, auth, events,
teams, brackets, suggestions, stats, media, file upload) and updated
Flutter repositories and domain models.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 20:13:57 -07:00

175 lines
5.0 KiB
Dart

import 'player.dart';
class TeamStatus {
TeamStatus._();
static const String pending = 'pending';
static const String approved = 'approved';
static const String rejected = 'rejected';
static String normalize(String? raw) {
switch (raw) {
case pending:
case approved:
case rejected:
return raw!;
default:
return approved;
}
}
}
class Team {
const Team({
required this.id,
required this.name,
this.logoUrl,
this.description,
this.wins = 0,
this.losses = 0,
this.draws = 0,
this.players = const <Player>[],
this.primaryColor,
this.managerId,
this.managerEmail = '',
this.managerPhone,
this.status = TeamStatus.approved,
});
final String id;
final String name;
final String? logoUrl;
final String? description;
final int wins;
final int losses;
final int draws;
final List<Player> players;
final String? primaryColor;
final String? managerId;
final String managerEmail;
final String? managerPhone;
final String status;
bool get isApproved => status == TeamStatus.approved;
bool get isPending => status == TeamStatus.pending;
bool get isRejected => status == TeamStatus.rejected;
int get totalGames => wins + losses + draws;
String get record => '$wins-$losses-$draws';
double get winPercentage => totalGames == 0 ? 0 : wins / totalGames;
Player? get topScorer {
if (players.isEmpty) return null;
Player best = players.first;
for (final p in players) {
if (p.goalsScored > best.goalsScored) best = p;
}
return best;
}
Team copyWith({
String? id,
String? name,
String? logoUrl,
String? description,
int? wins,
int? losses,
int? draws,
List<Player>? players,
String? primaryColor,
String? managerId,
String? managerEmail,
String? managerPhone,
String? status,
}) {
return Team(
id: id ?? this.id,
name: name ?? this.name,
logoUrl: logoUrl ?? this.logoUrl,
description: description ?? this.description,
wins: wins ?? this.wins,
losses: losses ?? this.losses,
draws: draws ?? this.draws,
players: players ?? this.players,
primaryColor: primaryColor ?? this.primaryColor,
managerId: managerId ?? this.managerId,
managerEmail: managerEmail ?? this.managerEmail,
managerPhone: managerPhone ?? this.managerPhone,
status: status ?? this.status,
);
}
factory Team.fromJson(Map<String, dynamic> data) {
final rawPlayers = (data['players'] as List?) ?? const [];
return Team(
id: (data['id'] as String?) ?? '',
name: (data['name'] as String?) ?? '',
logoUrl: data['logo_url'] as String?,
description: data['description'] as String?,
wins: (data['wins'] as num?)?.toInt() ?? 0,
losses: (data['losses'] as num?)?.toInt() ?? 0,
draws: (data['draws'] as num?)?.toInt() ?? 0,
players: rawPlayers
.whereType<Map<String, dynamic>>()
.map(Player.fromMap)
.toList(growable: false),
primaryColor: data['primary_color'] as String?,
managerId: data['manager_id'] as String?,
managerEmail: (data['manager_email'] as String?) ?? '',
managerPhone: data['manager_phone'] as String?,
status: TeamStatus.normalize(data['status'] as String?),
);
}
Map<String, Object?> toJson() {
return <String, Object?>{
'name': name,
'logo_url': logoUrl,
'description': description,
'wins': wins,
'losses': losses,
'draws': draws,
'primary_color': primaryColor,
'manager_id': managerId,
'manager_email': managerEmail,
'manager_phone': managerPhone,
'status': status,
'players': players.map((p) => p.toMap()).toList(growable: false),
};
}
@override
bool operator ==(Object other) {
if (identical(this, other)) return true;
if (other is! Team) return false;
if (other.id != id) return false;
if (other.name != name) return false;
if (other.logoUrl != logoUrl) return false;
if (other.description != description) return false;
if (other.wins != wins) return false;
if (other.losses != losses) return false;
if (other.draws != draws) return false;
if (other.primaryColor != primaryColor) return false;
if (other.managerId != managerId) return false;
if (other.managerEmail != managerEmail) return false;
if (other.managerPhone != managerPhone) return false;
if (other.status != status) return false;
if (other.players.length != players.length) return false;
for (var i = 0; i < players.length; i++) {
if (other.players[i] != players[i]) return false;
}
return true;
}
@override
int get hashCode => Object.hash(
id, name, logoUrl, description, wins, losses, draws,
primaryColor, managerId, managerEmail, managerPhone,
status, Object.hashAll(players),
);
@override
String toString() =>
'Team(id: $id, name: $name, status: $status, record: $record, '
'players: ${players.length})';
}