b239ae3e5f
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>
124 lines
3.1 KiB
Dart
124 lines
3.1 KiB
Dart
enum UserRole { viewer, player, manager, admin }
|
|
|
|
UserRole userRoleFromString(String? raw) {
|
|
switch (raw) {
|
|
case 'admin':
|
|
return UserRole.admin;
|
|
case 'manager':
|
|
return UserRole.manager;
|
|
case 'player':
|
|
return UserRole.player;
|
|
case 'viewer':
|
|
return UserRole.viewer;
|
|
default:
|
|
return UserRole.player;
|
|
}
|
|
}
|
|
|
|
class UserProfile {
|
|
const UserProfile({
|
|
required this.uid,
|
|
required this.email,
|
|
required this.displayName,
|
|
required this.role,
|
|
this.bio = '',
|
|
this.photoUrl,
|
|
this.position,
|
|
this.teamId,
|
|
required this.createdAt,
|
|
});
|
|
|
|
final String uid;
|
|
final String email;
|
|
final String displayName;
|
|
final UserRole role;
|
|
final String bio;
|
|
final String? photoUrl;
|
|
final String? position;
|
|
final String? teamId;
|
|
final DateTime createdAt;
|
|
|
|
bool get hasTeam => teamId != null && teamId!.isNotEmpty;
|
|
|
|
UserProfile copyWith({
|
|
String? uid,
|
|
String? email,
|
|
String? displayName,
|
|
UserRole? role,
|
|
String? bio,
|
|
String? photoUrl,
|
|
String? position,
|
|
String? teamId,
|
|
DateTime? createdAt,
|
|
}) {
|
|
return UserProfile(
|
|
uid: uid ?? this.uid,
|
|
email: email ?? this.email,
|
|
displayName: displayName ?? this.displayName,
|
|
role: role ?? this.role,
|
|
bio: bio ?? this.bio,
|
|
photoUrl: photoUrl ?? this.photoUrl,
|
|
position: position ?? this.position,
|
|
teamId: teamId ?? this.teamId,
|
|
createdAt: createdAt ?? this.createdAt,
|
|
);
|
|
}
|
|
|
|
UserProfile clearTeam() => copyWith(teamId: null);
|
|
|
|
factory UserProfile.fromJson(Map<String, dynamic> data) {
|
|
return UserProfile(
|
|
uid: (data['id'] as String?) ?? '',
|
|
email: (data['email'] as String?) ?? '',
|
|
displayName: (data['display_name'] as String?) ?? '',
|
|
role: userRoleFromString(data['role'] as String?),
|
|
bio: (data['bio'] as String?) ?? '',
|
|
photoUrl: data['photo_url'] as String?,
|
|
position: data['position'] as String?,
|
|
teamId: data['team_id'] as String?,
|
|
createdAt: _parseDate(data['created_at']) ?? DateTime.now(),
|
|
);
|
|
}
|
|
|
|
Map<String, Object?> toJson() {
|
|
return <String, Object?>{
|
|
'email': email,
|
|
'display_name': displayName,
|
|
'role': role.name,
|
|
'bio': bio,
|
|
'photo_url': photoUrl,
|
|
'position': position,
|
|
'team_id': teamId,
|
|
};
|
|
}
|
|
|
|
static DateTime? _parseDate(Object? v) {
|
|
if (v is String && v.isNotEmpty) return DateTime.tryParse(v);
|
|
return null;
|
|
}
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) return true;
|
|
return other is UserProfile &&
|
|
other.uid == uid &&
|
|
other.email == email &&
|
|
other.displayName == displayName &&
|
|
other.role == role &&
|
|
other.bio == bio &&
|
|
other.photoUrl == photoUrl &&
|
|
other.position == position &&
|
|
other.teamId == teamId &&
|
|
other.createdAt == createdAt;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => Object.hash(
|
|
uid, email, displayName, role, bio, photoUrl, position, teamId, createdAt,
|
|
);
|
|
|
|
@override
|
|
String toString() =>
|
|
'UserProfile(uid: $uid, role: ${role.name}, teamId: $teamId)';
|
|
}
|