diff --git a/lib/pages/home.dart b/lib/pages/home.dart index 5393906..0049f83 100644 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -18,11 +18,11 @@ class _HomePageState extends State { // Define the pages for each section final List _pages = [ - LeaderboardPage(), // Use imported widget - JoinMatchPage(), // Use imported widget - CreateMatchPage(), // Use imported widget - AddFriendPage(), // Use imported widget - PlaceholderPage(),//ProfilePage(), // Use imported widget + LeaderboardPage(), + JoinMatchPage(), + CreateMatchPage(), + AddFriendPage(), + ProfilePage(), ]; void _onBottomNavTap(int index) { @@ -33,7 +33,7 @@ class _HomePageState extends State { Future _logout(BuildContext context) async { final prefs = await SharedPreferences.getInstance(); - await prefs.remove('token'); // Remove the token to log out + await prefs.remove('token'); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => LoginPage()), @@ -53,7 +53,7 @@ class _HomePageState extends State { ), ], ), - body: _pages[_selectedIndex], // Display the selected page content + body: _pages[_selectedIndex], bottomNavigationBar: BottomNavigationBarCustom( currentIndex: _selectedIndex, onTap: _onBottomNavTap, diff --git a/lib/pages/login.dart b/lib/pages/login.dart index e15f3ac..8e29c70 100644 --- a/lib/pages/login.dart +++ b/lib/pages/login.dart @@ -18,7 +18,7 @@ class _LoginPageState extends State { bool _isLogin = true; bool _isLoading = false; - final String baseUrl = 'http://10.0.0.10:9134'; // Replace with your actual API base URL + final String baseUrl = 'http://api.dthpp.mercurio.moe'; Future _handleAuth() async { final email = _emailController.text.trim(); @@ -30,7 +30,6 @@ class _LoginPageState extends State { try { if (_isLogin) { - // Call login endpoint and save token final token = await _login(email, password); if (token != null) { final prefs = await SharedPreferences.getInstance(); @@ -39,7 +38,6 @@ class _LoginPageState extends State { context, MaterialPageRoute(builder: (context) => HomePage())); } } else { - // Call register endpoint final uid = await _register(email, password, _displayNameController.text.trim()); if (uid != null) { setState(() { diff --git a/lib/pages/views/creatematch.dart b/lib/pages/views/creatematch.dart index a36561d..c26ebd8 100644 --- a/lib/pages/views/creatematch.dart +++ b/lib/pages/views/creatematch.dart @@ -12,7 +12,7 @@ class _CreateMatchPageState extends State { String? _matchId; bool _isLoading = false; - final String _createMatchApiUrl = 'http://10.0.0.10:9134/creatematch'; // Replace with your API endpoint + final String _createMatchApiUrl = 'http://api.dthpp.mercurio.moe/creatematch'; // Replace with your API endpoint // Method to create a match Future _createMatch() async { diff --git a/lib/pages/views/friendlist.dart b/lib/pages/views/friendlist.dart index 859f9ec..a8f7d44 100644 --- a/lib/pages/views/friendlist.dart +++ b/lib/pages/views/friendlist.dart @@ -13,8 +13,8 @@ class _AddFriendPageState extends State { List _friends = []; bool _isLoading = false; - final String _addFriendApiUrl = 'http://10.0.0.10:9134/add_friend'; - final String _getFriendsApiUrl = 'http://10.0.0.10:9134/get_friends'; + final String _addFriendApiUrl = 'http://api.dthpp.mercurio.moe/add_friend'; + final String _getFriendsApiUrl = 'http://api.dthpp.mercurio.moe/get_friends'; // Method to add a friend Future _addFriend(String friendUid) async { diff --git a/lib/pages/views/joinmatch.dart b/lib/pages/views/joinmatch.dart index efc395a..f68bce5 100644 --- a/lib/pages/views/joinmatch.dart +++ b/lib/pages/views/joinmatch.dart @@ -14,9 +14,10 @@ class _JoinMatchPageState extends State { bool _isLoading = false; int _player1Score = 0; int _player2Score = 0; + String? _matchId; - final String _joinMatchApiUrl = 'http://10.0.0.10:9134/joinmatch'; - final String _endMatchApiUrl = 'http://10.0.0.10:9134/endmatch'; // Replace with your API endpoint + final String _joinMatchApiUrl = 'http://api.dthpp.mercurio.moe/joinmatch'; // Replace with your API endpoint + final String _endMatchApiUrl = 'http://api.dthpp.mercurio.moe/endmatch'; // Replace with your API endpoint // Join Match Function Future _joinMatch() async { @@ -46,8 +47,9 @@ class _JoinMatchPageState extends State { if (response.statusCode == 200) { setState(() { _isJoined = true; - _player1Score = 0; // Reset scores for the new match + _player1Score = 0; _player2Score = 0; + _matchId = matchId; }); _showToast('Joined match successfully!'); } else { @@ -95,7 +97,7 @@ class _JoinMatchPageState extends State { Uri.parse(_endMatchApiUrl), headers: {'Content-Type': 'application/json'}, body: json.encode({ - 'token': token, + 'match_id': int.parse(_matchId!), 'player1_score': _player1Score, 'player2_score': _player2Score, }), @@ -155,6 +157,7 @@ class _JoinMatchPageState extends State { ], ), SizedBox(height: 16), + // Player 2 Score Controls Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -173,6 +176,7 @@ class _JoinMatchPageState extends State { ], ), SizedBox(height: 32), + // End Match Button ElevatedButton( onPressed: _endMatch, child: Text('End Match'), @@ -183,6 +187,7 @@ class _JoinMatchPageState extends State { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ + // Match ID Text Field TextField( controller: _matchIdController, decoration: InputDecoration( @@ -191,6 +196,7 @@ class _JoinMatchPageState extends State { ), ), SizedBox(height: 16), + // Join Match Button ElevatedButton( onPressed: () { if (_matchIdController.text.isNotEmpty) { diff --git a/lib/pages/views/leaderboard.dart b/lib/pages/views/leaderboard.dart index 26c2fc0..52984b1 100644 --- a/lib/pages/views/leaderboard.dart +++ b/lib/pages/views/leaderboard.dart @@ -11,7 +11,7 @@ class _LeaderboardPageState extends State { List _leaderboard = []; bool _isLoading = true; - final String _apiUrl = 'http://10.0.0.10:9134/leaderboards'; + final String _apiUrl = 'http://api.dthpp.mercurio.moe/leaderboards'; Future _fetchLeaderboard() async { setState(() { diff --git a/lib/pages/views/myprofile.dart b/lib/pages/views/myprofile.dart index 759ca6d..3e429df 100644 --- a/lib/pages/views/myprofile.dart +++ b/lib/pages/views/myprofile.dart @@ -1,38 +1,190 @@ +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'; -class PlaceholderPage extends StatelessWidget { - final String description; +class ProfilePage extends StatefulWidget { + @override + _ProfilePageState createState() => _ProfilePageState(); +} - const PlaceholderPage({ - Key? key, - this.description = 'This is a placeholder page. Work in progress!', - }) : super(key: key); +class _ProfilePageState extends State { + bool _isLoading = true; + String? _name; + int? _uid; + int? _elo; + List _matches = []; + + final String _getProfileApiUrl = 'http://api.dthpp.mercurio.moe/getprofile'; + + @override + void initState() { + super.initState(); + _fetchProfileData(); + } + + Future _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']; - body: Center( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Icon( - Icons.construction, - size: 80, - color: Colors.grey, + 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, + ), + ), + ], + ), + ], + ), + ), + ); + }, ), - SizedBox(height: 25), - Text( - description, - style: TextStyle(fontSize: 16, color: Colors.grey), - textAlign: TextAlign.center, - ), - SizedBox(height: 16), - ], - ), + ), + ], ), ), );