// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables, file_names, use_build_context_synchronously, library_private_types_in_public_api import 'package:flutter/material.dart'; import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:smilet/LoginPage.dart'; class Leaderboard extends StatefulWidget { const Leaderboard({super.key}); @override _LeaderboardState createState() => _LeaderboardState(); } class _LeaderboardState extends State<Leaderboard> with TickerProviderStateMixin { late final TabController _tabController; String schoolCode = user.getSchoolCode(); @override void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); } @override void dispose() { _tabController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { var futureBuilder = FutureBuilder( future: _getLeaderboard(), builder: (BuildContext context, AsyncSnapshot snapshot) { switch (snapshot.connectionState) { case ConnectionState.none: return Text('connectionstate none'); case ConnectionState.waiting: return _emptyCreateTab(context, snapshot); default: if (snapshot.hasError) { return Text('snapshot error ${snapshot.error.toString()}'); } else if (snapshot.hasData) { return _createTab(context, snapshot); } else { return Text('snapshot null'); } } }, ); var userFutureBuilder = FutureBuilder( future: _schoolLeaderboard(schoolCode), builder: (BuildContext context, AsyncSnapshot snapshot) { switch (snapshot.connectionState) { case ConnectionState.none: return Text('connectionstate none'); case ConnectionState.waiting: return _emptyCreateTab(context, snapshot); default: if (snapshot.hasError) { return Text('snapshot error ${snapshot.error.toString()}'); } else if (snapshot.hasData) { return _createUsersTab(context, snapshot); } else { return Text('snapshot null'); } } }, ); return DefaultTabController( initialIndex: 1, length: 2, child: Scaffold( appBar: AppBar( automaticallyImplyLeading: false, toolbarHeight: 0.0, centerTitle: true, bottom: TabBar( controller: _tabController, dividerColor: Colors.transparent, tabs: <Widget>[ Tab( text: 'Lag', ), Tab( text: 'Enskild', ), ]), ), body: TabBarView( controller: _tabController, children: <Widget>[ futureBuilder, userFutureBuilder, ], ), ), ); } Widget _createTab(BuildContext context, AsyncSnapshot snapshot) { List<dynamic> items = snapshot.data; return ListView.separated( padding: const EdgeInsets.all(8), itemCount: items.length + 1, itemBuilder: (BuildContext context, int index) { if (index == 0) { return Column( children: [ Text( 'Slutförd aktivitet ger 5 poäng och 1 poäng per deltagare', textAlign: TextAlign.left, ), SizedBox(height: 7), Container( decoration: BoxDecoration( color: Colors.blueGrey, borderRadius: BorderRadius.all(Radius.circular(10))), padding: const EdgeInsets.all(8), height: 40, child: Row( textDirection: TextDirection.ltr, children: <Widget>[ Padding( padding: const EdgeInsets.only(left: 8), child: Text( 'Plats', style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), Expanded( child: Text( 'Lag', textAlign: TextAlign.center, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), Padding( padding: const EdgeInsets.only(right: 10), child: Text( 'Poäng', style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), ], ), ), ], ); } else { String str = items[index - 1].toString(); int schoolIndex = str.indexOf('school: '); int instIndex = str.indexOf('institution: '); int instIndexEnd = str.indexOf('activities: ['); int pointsIndex = str.indexOf('points: '); int pointsEndIndex = str.length - 1; String skola = '${str.substring(schoolIndex + 8, instIndex - 2).toUpperCase()}: '; skola += str.substring(instIndex + 13, instIndexEnd - 2); String points = str.substring(pointsIndex + 8, pointsEndIndex); return Container( decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.all(Radius.circular(10))), padding: const EdgeInsets.all(8), height: 60, child: Row( textDirection: TextDirection.ltr, children: <Widget>[ Padding( padding: const EdgeInsets.only(right: 20.0, left: 10.0), child: Text( '$index', textAlign: TextAlign.right, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.amber), ), ), Expanded( child: Text( skola, textAlign: TextAlign.center, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white), ), ), Padding( padding: const EdgeInsets.only(left: 15.0, right: 12.0), child: Text( points, textAlign: TextAlign.left, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.amber), ), ), ], ), ); } }, separatorBuilder: (BuildContext context, int index) => const Divider(), ); } Widget _emptyCreateTab(BuildContext context, AsyncSnapshot snapshot) { return Column( children: [ Container( decoration: BoxDecoration( color: Colors.blueGrey, borderRadius: BorderRadius.all(Radius.circular(10))), padding: const EdgeInsets.all(8), height: 40, child: Row( textDirection: TextDirection.ltr, children: <Widget>[ Padding( padding: const EdgeInsets.only(left: 8), child: Text( 'Plats', style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), Expanded( child: Text( 'Lag', textAlign: TextAlign.center, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), Padding( padding: const EdgeInsets.only(right: 10), child: Text( 'Poäng', style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), ], ), ), SizedBox( height: 220, ), CircularProgressIndicator() ], ); } Widget _createUsersTab(BuildContext context, AsyncSnapshot snapshot) { List<dynamic> items = snapshot.data; return ListView.separated( padding: const EdgeInsets.all(8), itemCount: items.length + 1, itemBuilder: (BuildContext context, int index) { if (index == 0) { return Container( decoration: BoxDecoration( color: Colors.blueGrey, borderRadius: BorderRadius.all(Radius.circular(10))), padding: const EdgeInsets.all(8), height: 40, child: Row( textDirection: TextDirection.ltr, children: <Widget>[ Padding( padding: const EdgeInsets.only(left: 8), child: Text( 'Plats', style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), Expanded( child: Text( 'Användare', textAlign: TextAlign.center, style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), Padding( padding: const EdgeInsets.only(right: 10), child: Text( 'Poäng', style: TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.amber), ), ), ], ), ); } else { Map map = items[index - 1]; String username = map.keys.elementAt(0).toString(); int points = map.values.elementAt(0); return Container( decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.all(Radius.circular(10))), padding: const EdgeInsets.all(8), height: 60, child: Row( textDirection: TextDirection.ltr, children: <Widget>[ Padding( padding: const EdgeInsets.only(right: 20.0, left: 10.0), child: Text( '$index', textAlign: TextAlign.right, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.amber), ), ), Expanded( child: Text( username, textAlign: TextAlign.center, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white), ), ), Padding( padding: const EdgeInsets.only(left: 15.0, right: 12.0), child: Text( points.toString(), textAlign: TextAlign.left, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: Colors.amber), ), ), ], ), ); } }, separatorBuilder: (BuildContext context, int index) => const Divider(), ); } Future<List> _getLeaderboard() async { var response = await http .get(Uri.parse('https://group-15-3.pvt.dsv.su.se/leaderboard')); if (response.statusCode == 200) { // If the server did return a 200 OK response, // then parse the JSON. return jsonDecode(utf8.decode(response.bodyBytes)) as List<dynamic>; } else { // If the server did not return a 200 OK response, // then throw an exception. throw Exception(); } } Future<List> _schoolLeaderboard(String schoolCode) async { var response = await http.get(Uri.parse( 'https://group-15-3.pvt.dsv.su.se/leaderboard/school/$schoolCode')); if (response.statusCode == 200) { // If the server did return a 200 OK response, // then parse the JSON. return jsonDecode(utf8.decode(response.bodyBytes)) as List<dynamic>; } else { // If the server did not return a 200 OK response, // then throw an exception. throw Exception(); } } }