166 lines
6.9 KiB
Dart
166 lines
6.9 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import '../../data/models/player_model.dart';
|
|
import '../provider/active_players_provider.dart';
|
|
import '../provider/player_provider.dart'; // für awardWinToPlayers
|
|
import '../widgets/volleyball_field_widget.dart';
|
|
|
|
class FieldsScreen extends ConsumerWidget {
|
|
const FieldsScreen({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
final activePlayers = ref.watch(activePlayersProvider);
|
|
|
|
// Shuffle für Demo (später echter Algorithmus)
|
|
final shuffled = List<PlayerModel>.from(activePlayers)..shuffle();
|
|
|
|
// Maximal 36 Spieler auf Felder, Rest Aussetzer
|
|
final playersOnFields = shuffled.length > 36 ? shuffled.sublist(0, 36) : shuffled;
|
|
final bench = shuffled.length > 36 ? shuffled.sublist(36) : <PlayerModel>[];
|
|
|
|
// Felder aufteilen
|
|
final field1 = _slice(playersOnFields, 0, 12);
|
|
final field2 = _slice(playersOnFields, 12, 24);
|
|
final field3 = _slice(playersOnFields, 24, 36);
|
|
|
|
final fields = [field1, field2, field3];
|
|
|
|
return Scaffold(
|
|
body: Column(
|
|
children: [
|
|
// Swipe-Galerie
|
|
Expanded(
|
|
child: PageView.builder(
|
|
itemCount: 3,
|
|
itemBuilder: (context, index) {
|
|
final fieldPlayers = fields[index];
|
|
|
|
final teamA = fieldPlayers.sublist(0, fieldPlayers.length.clamp(0, 6));
|
|
final teamB = fieldPlayers.length > 6
|
|
? fieldPlayers.sublist(6, fieldPlayers.length.clamp(6, 12))
|
|
: <PlayerModel>[];
|
|
|
|
return Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
children: [
|
|
Expanded(child: VolleyballFieldWidget(teamA: teamA, teamB: teamB, fieldNumber: index + 1)),
|
|
|
|
const SizedBox(height: 20),
|
|
|
|
// Gewinner-Buttons
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: Colors.green.shade600,
|
|
padding: const EdgeInsets.symmetric(vertical: 20),
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(20),
|
|
bottomLeft: Radius.circular(20),
|
|
),
|
|
),
|
|
),
|
|
onPressed: teamA.isEmpty
|
|
? null
|
|
: () {
|
|
ref.read(playerListProvider.notifier).awardWinToPlayers(teamA);
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text('Oben gewinnt! +1 Schleifchen für ${teamA.length} Spieler'),
|
|
backgroundColor: Colors.green,
|
|
duration: const Duration(seconds: 2),
|
|
),
|
|
);
|
|
},
|
|
child: const Text('OBEN GEWINNT', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
|
),
|
|
),
|
|
Expanded(
|
|
child: ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: Colors.red.shade600,
|
|
padding: const EdgeInsets.symmetric(vertical: 20),
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
topRight: Radius.circular(20),
|
|
bottomRight: Radius.circular(20),
|
|
),
|
|
),
|
|
),
|
|
onPressed: teamB.isEmpty
|
|
? null
|
|
: () {
|
|
ref.read(playerListProvider.notifier).awardWinToPlayers(teamB);
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(
|
|
content: Text('Unten gewinnt! +1 Schleifchen für ${teamB.length} Spieler'),
|
|
backgroundColor: Colors.red,
|
|
duration: const Duration(seconds: 2),
|
|
),
|
|
);
|
|
},
|
|
child: const Text('UNTEN GEWINNT', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
|
|
// Aussetzer
|
|
if (bench.isNotEmpty)
|
|
Container(
|
|
padding: const EdgeInsets.all(16),
|
|
color: Colors.orange.shade100,
|
|
child: Column(
|
|
children: [
|
|
const Text('Aussetzer diese Runde:', style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
|
|
const SizedBox(height: 8),
|
|
Wrap(
|
|
spacing: 12,
|
|
runSpacing: 8,
|
|
children: bench
|
|
.map((p) => Chip(
|
|
label: Text(p.name),
|
|
backgroundColor: Colors.orange.shade300,
|
|
))
|
|
.toList(),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
|
|
// Shuffle Button unten
|
|
Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: ElevatedButton.icon(
|
|
icon: const Icon(Icons.shuffle),
|
|
label: const Text('Neu mischen', style: TextStyle(fontSize: 18)),
|
|
onPressed: () {
|
|
ref.invalidate(activePlayersProvider);
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
const SnackBar(content: Text('Neue Teams gemischt!'), duration: Duration(milliseconds: 100)),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
// Hilfsfunktion für sicheres Slicing
|
|
List<PlayerModel> _slice(List<PlayerModel> list, int start, int end) {
|
|
final actualEnd = end.clamp(0, list.length);
|
|
if (start >= actualEnd) return [];
|
|
return list.sublist(start, actualEnd);
|
|
}
|
|
} |