dth-pingpong-mobileapp/lib/pages/views/myprofile.dart
2024-12-23 21:48:34 +01:00

196 lines
7 KiB
Dart

import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import '../../globals.dart';
class ProfilePage extends StatefulWidget {
@override
_ProfilePageState createState() => _ProfilePageState();
}
class _ProfilePageState extends State<ProfilePage> {
bool _isLoading = true;
String? _name;
int? _uid;
int? _elo;
List<dynamic> _matches = [];
final String _getProfileApiUrl = '$apiurl/getprofile';
@override
void initState() {
super.initState();
_fetchProfileData();
}
Future<void> _fetchProfileData() async {
final prefs = await SharedPreferences.getInstance();
final String? token = prefs.getString('token');
if (token == null) {
_showToast('No token found. Please login again.');
return;
}
try {
final response = await http.post(
Uri.parse(_getProfileApiUrl),
headers: {'Content-Type': 'application/json'},
body: json.encode({'token': token}),
);
if (response.statusCode == 200) {
final data = json.decode(response.body);
setState(() {
_name = data['name'];
_uid = data['uid'];
_elo = data['elo'];
_matches = data['matches'];
_isLoading = false;
});
} else {
_showToast('Failed to fetch profile data.');
}
} catch (e) {
_showToast('Error: $e');
}
}
Color _generateRandomColor() {
final random = Random();
return Color.fromARGB(
255,
random.nextInt(256),
random.nextInt(256),
random.nextInt(256),
);
}
void _showToast(String message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _isLoading
? Center(child: CircularProgressIndicator())
: RefreshIndicator(
onRefresh: _fetchProfileData,
child: Column(
children: [
// Profile Details
Container(
padding: EdgeInsets.all(16.0),
child: Row(
children: [
// Profile Icon
CircleAvatar(
backgroundColor: _generateRandomColor(),
child: Text(
_name != null && _name!.isNotEmpty
? _name![0].toUpperCase()
: '?',
style: TextStyle(fontSize: 24, color: Colors.white),
),
radius: 40,
),
SizedBox(width: 16),
// Profile Info
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_name ?? 'Name not available',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 8),
Text('UID: ${_uid ?? 'N/A'}'),
Text('ELO: ${_elo ?? 'N/A'}'),
],
),
],
),
),
SizedBox(height: 16),
// Recent Matches
Expanded(
child: _matches.isEmpty
? Center(
child: Text(
"You haven't played any matches yet",
style: TextStyle(
fontSize: 16,
color: Colors.grey,
),
),
)
: ListView.builder(
itemCount: _matches.length,
itemBuilder: (context, index) {
final match = _matches[index];
final result = match['result'];
final eloChange = match['elo_change'];
return Card(
margin: EdgeInsets.symmetric(
horizontal: 16.0, vertical: 8.0),
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'Match ID: ${match['match_id']}',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
Text(
'Opponent: ${match['opponent_name']}'),
Row(
children: [
Text(
'$result',
style: TextStyle(
fontWeight: FontWeight.bold,
color: result == 'Win'
? Colors.green
: Colors.red,
),
),
SizedBox(width: 16),
if (eloChange != null)
Text(
'ELO Change: ${eloChange > 0 ? '+' : ''}$eloChange',
style: TextStyle(
color: eloChange > 0
? Colors.green
: Colors.red,
),
),
],
),
],
),
),
);
},
),
),
],
),
),
);
}
}