import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:pvt15/api/backend_api.dart'; import 'package:pvt15/hop_colors.dart'; class GameEndedPage extends StatefulWidget { final String sessionID; const GameEndedPage({super.key, required this.sessionID}); @override State createState() => _GameEndedPageState(); } class _GameEndedPageState extends State { List> winners = []; List> participants = []; bool isLoading = true; String? errorMessage; @override void initState() { super.initState(); handleFetchParticipants(); } void handleFetchParticipants() async { await fetchParticipants(); } Future fetchParticipants() async { try { final response = await authHttpRequest( context: context, url: 'https://group-1-15.pvt.dsv.su.se/api/participants/${widget.sessionID}', method: 'GET', ); if (response.statusCode == 200) { final List data = jsonDecode(utf8.decode(response.bodyBytes)); setState(() { participants = data .map>( (participant) => { 'name': participant['username'], 'points': participant['score'] ?? 0, }, ) .toList() ..sort( (a, b) => (b['points'] as int).compareTo(a['points'] as int), ); print('Participants: $participants'); // för debug if (participants.isNotEmpty) { final maxScore = participants.first['points'] as int; winners = participants.where((p) => p['points'] == maxScore).toList(); } isLoading = false; }); } else { setState(() { isLoading = false; errorMessage = 'Misslyckades att hämta poäng (Status: ${response.statusCode})'; }); } } catch (e) { setState(() { isLoading = false; errorMessage = 'Misslyckades att hämta poäng: $e'; }); } } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (bool didPop, dynamic result) { if (!didPop) { _goBackToGameCategoryPage(); } }, child: Scaffold( body: Container( decoration: HopColors.hopBackgroundDecoration, child: SafeArea( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildHeader(), Expanded( child: isLoading ? const Center(child: CircularProgressIndicator()) : errorMessage != null ? Center( child: Text( errorMessage!, style: const TextStyle(color: Colors.white), ), ) : _buildContent(), ), ], ), ), ), ), ), ); } Widget _buildHeader() { return const Padding( padding: EdgeInsets.only(bottom: 24.0), child: Align( alignment: Alignment.center, child: Text( 'Spelet är avslutat!', style: TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, ), ), ), ); } Widget _buildContent() { return Container( decoration: BoxDecoration( color: const Color(0xFFF3E5F5).withValues(alpha: 0.6), borderRadius: BorderRadius.circular(24.0), ), child: Column( children: [ if (winners.isNotEmpty) _buildWinnerCard(), const SizedBox(height: 16), _buildColumnHeaders(), Expanded( child: ListView.builder( padding: const EdgeInsets.symmetric(horizontal: 8.0), itemCount: participants.length, itemBuilder: (context, index) => _buildParticipantItem(participants[index], index), ), ), Padding( padding: const EdgeInsets.symmetric( horizontal: 16.0, vertical: 16.0, ), child: ElevatedButton( onPressed: () { _goBackToGameCategoryPage(); }, style: ElevatedButton.styleFrom( backgroundColor: Color(0xFFB39DDB), foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 16.0), minimumSize: const Size(200, 0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(32.0), ), textStyle: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white, ), ), child: const Text('Tillbaka'), ), ), const SizedBox(height: 16), ], ), ); } void _goBackToGameCategoryPage() { Navigator.popUntil( context, (route) => route.settings.name == '/gameCategory', ); } Widget _buildWinnerCard() { return Container( margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), padding: const EdgeInsets.all(16.0), decoration: BoxDecoration( color: const Color(0xFFFCE4EC).withValues(alpha: 0.9), borderRadius: BorderRadius.circular(24.0), border: Border.all(color: HopColors.hopPurplePrimary, width: 2), ), child: Column( children: [ Text( winners.length > 1 ? 'Delade vinnare!' : 'Vinnare!', style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.black, fontSize: 24, ), ), const SizedBox(height: 8), ...winners.map( (winner) => Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( winner['name'], style: const TextStyle( fontWeight: FontWeight.bold, color: Colors.black, fontSize: 20, ), ), Text( '${winner['points']} poäng', style: const TextStyle( color: Colors.black, fontSize: 16, ), ), ], ), ], ), ), ), ], ), ); } Widget _buildColumnHeaders() { return const Padding( padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 12.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'Namn', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black, fontSize: 16, ), ), Text( 'Poäng', style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black, fontSize: 16, ), ), ], ), ); } Widget _buildParticipantItem(Map participant, int index) { return Container( margin: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0), padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 12.0), decoration: BoxDecoration( color: const Color(0xFFFCE4EC).withValues(alpha: 0.7), borderRadius: BorderRadius.circular(24.0), ), child: Row( children: [ SizedBox( width: 32, child: Text( '${index + 1}', style: const TextStyle(color: Colors.black, fontSize: 18), ), ), const SizedBox(width: 12), Expanded( child: Text( participant['name'], style: const TextStyle(color: Colors.black, fontSize: 16), ), ), SizedBox( width: 60, child: Text( participant['points'].toString(), textAlign: TextAlign.right, style: const TextStyle(color: Colors.black, fontSize: 16), ), ), ], ), ); } }