Files
MatchLiveTv/mobile/lib/features/matches/team_picker.dart
Emiliano Frascaro f4b7be0f80 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>
2026-05-29 07:23:13 +02:00

126 lines
4.4 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../app/theme.dart';
import '../../shared/models/team.dart';
import 'team_providers.dart';
/// Selettore squadra quando l'utente ne gestisce più di una (staff trasmissione / società).
class TeamPickerBar extends ConsumerWidget {
const TeamPickerBar({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final teamsAsync = ref.watch(teamsProvider);
final activeAsync = ref.watch(activeTeamProvider);
return teamsAsync.when(
loading: () => const SizedBox.shrink(),
error: (_, _) => const SizedBox.shrink(),
data: (teams) {
if (teams.length <= 1) return const SizedBox.shrink();
final active = activeAsync.valueOrNull;
final theme = Theme.of(context);
return Padding(
padding: const EdgeInsets.only(top: 8),
child: Material(
color: AppTheme.surface,
borderRadius: BorderRadius.circular(12),
child: InkWell(
onTap: () => _showTeamSheet(context, ref, teams, active?.id),
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 12),
child: Row(
children: [
const Icon(Icons.groups_outlined, color: AppTheme.primaryRed, size: 22),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Squadra per la diretta',
style: theme.textTheme.labelMedium?.copyWith(
color: AppTheme.textSecondary,
),
),
Text(
active?.name ?? 'Seleziona squadra',
style: theme.textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.w700,
),
),
if (active?.clubName != null && active!.clubName!.isNotEmpty)
Text(
active.clubName!,
style: theme.textTheme.bodySmall,
),
],
),
),
const Icon(Icons.expand_more, color: AppTheme.textSecondary),
],
),
),
),
),
);
},
);
}
Future<void> _showTeamSheet(
BuildContext context,
WidgetRef ref,
List<Team> teams,
String? selectedId,
) async {
final picked = await showModalBottomSheet<String>(
context: context,
backgroundColor: AppTheme.surface,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
),
builder: (ctx) {
return SafeArea(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 8),
child: Text(
'Scegli squadra',
style: Theme.of(ctx).textTheme.titleLarge,
),
),
...teams.map((team) {
final selected = team.id == selectedId;
return ListTile(
leading: Icon(
selected ? Icons.check_circle : Icons.circle_outlined,
color: selected ? AppTheme.primaryRed : AppTheme.textSecondary,
),
title: Text(team.name),
subtitle: team.clubName != null && team.clubName!.isNotEmpty
? Text(team.clubName!)
: null,
onTap: () => Navigator.pop(ctx, team.id),
);
}),
const SizedBox(height: 8),
],
),
);
},
);
if (picked == null) return;
await ref.read(selectedTeamIdProvider.notifier).select(picked);
ref.invalidate(matchesProvider);
}
}