Billing Stripe, link regia mobile e staff solo trasmissione.
Aggiunge fatturazione club, pagina regia condivisibile senza account, roster squadre e rimuove la modalità controller dall'app (v1.1.0). Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,10 +1,30 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../core/team_selection_storage.dart';
|
||||
import '../../providers/auth_provider.dart';
|
||||
import '../../shared/api_client.dart';
|
||||
import '../../shared/models/match.dart';
|
||||
import '../../shared/models/recording_item.dart';
|
||||
import '../../shared/models/team.dart';
|
||||
|
||||
final matchesProvider = FutureProvider<List<MatchModel>>((ref) async {
|
||||
final auth = ref.watch(authProvider);
|
||||
if (!auth.isAuthenticated) return [];
|
||||
final team = await ref.watch(activeTeamProvider.future);
|
||||
if (team == null) return [];
|
||||
final client = ref.read(apiClientProvider);
|
||||
final list = await client.fetchMatches(team.id);
|
||||
list.sort((a, b) {
|
||||
final sa = a.scheduledAt;
|
||||
final sb = b.scheduledAt;
|
||||
if (sa == null && sb == null) return 0;
|
||||
if (sa == null) return 1;
|
||||
if (sb == null) return -1;
|
||||
return sa.compareTo(sb);
|
||||
});
|
||||
return list;
|
||||
});
|
||||
|
||||
final teamsProvider = FutureProvider<List<Team>>((ref) async {
|
||||
final auth = ref.watch(authProvider);
|
||||
if (!auth.isAuthenticated) return [];
|
||||
@@ -12,12 +32,38 @@ final teamsProvider = FutureProvider<List<Team>>((ref) async {
|
||||
return client.fetchTeams();
|
||||
});
|
||||
|
||||
final primaryTeamProvider = FutureProvider<Team?>((ref) async {
|
||||
final selectedTeamIdProvider =
|
||||
AsyncNotifierProvider<SelectedTeamIdNotifier, String?>(SelectedTeamIdNotifier.new);
|
||||
|
||||
class SelectedTeamIdNotifier extends AsyncNotifier<String?> {
|
||||
@override
|
||||
Future<String?> build() => TeamSelectionStorage.load();
|
||||
|
||||
Future<void> select(String teamId) async {
|
||||
await TeamSelectionStorage.save(teamId);
|
||||
state = AsyncData(teamId);
|
||||
}
|
||||
}
|
||||
|
||||
/// Squadra attiva: preferisce la selezione salvata, altrimenti la prima disponibile.
|
||||
final activeTeamProvider = FutureProvider<Team?>((ref) async {
|
||||
final teams = await ref.watch(teamsProvider.future);
|
||||
if (teams.isEmpty) return null;
|
||||
return teams.first;
|
||||
|
||||
var selectedId = ref.watch(selectedTeamIdProvider).valueOrNull;
|
||||
final valid = selectedId != null && teams.any((t) => t.id == selectedId);
|
||||
|
||||
if (!valid) {
|
||||
selectedId = teams.first.id;
|
||||
await ref.read(selectedTeamIdProvider.notifier).select(selectedId);
|
||||
}
|
||||
|
||||
return teams.firstWhere((t) => t.id == selectedId);
|
||||
});
|
||||
|
||||
/// Compatibilità con codice esistente.
|
||||
final primaryTeamProvider = activeTeamProvider;
|
||||
|
||||
final teamByIdProvider = FutureProvider.family<Team?, String>((ref, teamId) async {
|
||||
final teams = await ref.watch(teamsProvider.future);
|
||||
for (final t in teams) {
|
||||
|
||||
Reference in New Issue
Block a user