smilet/lib/Leaderboard/Leaderboard.dart
2024-06-03 10:39:47 +02:00

407 lines
14 KiB
Dart

// 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();
}
}
}