Beta build

This commit is contained in:
Mercurio 2024-12-22 20:35:58 +01:00
parent c39796a40f
commit 25500ea134
7 changed files with 200 additions and 44 deletions

View file

@ -18,11 +18,11 @@ class _HomePageState extends State<HomePage> {
// Define the pages for each section // Define the pages for each section
final List<Widget> _pages = [ final List<Widget> _pages = [
LeaderboardPage(), // Use imported widget LeaderboardPage(),
JoinMatchPage(), // Use imported widget JoinMatchPage(),
CreateMatchPage(), // Use imported widget CreateMatchPage(),
AddFriendPage(), // Use imported widget AddFriendPage(),
PlaceholderPage(),//ProfilePage(), // Use imported widget ProfilePage(),
]; ];
void _onBottomNavTap(int index) { void _onBottomNavTap(int index) {
@ -33,7 +33,7 @@ class _HomePageState extends State<HomePage> {
Future<void> _logout(BuildContext context) async { Future<void> _logout(BuildContext context) async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
await prefs.remove('token'); // Remove the token to log out await prefs.remove('token');
Navigator.pushReplacement( Navigator.pushReplacement(
context, context,
MaterialPageRoute(builder: (context) => LoginPage()), MaterialPageRoute(builder: (context) => LoginPage()),
@ -53,7 +53,7 @@ class _HomePageState extends State<HomePage> {
), ),
], ],
), ),
body: _pages[_selectedIndex], // Display the selected page content body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBarCustom( bottomNavigationBar: BottomNavigationBarCustom(
currentIndex: _selectedIndex, currentIndex: _selectedIndex,
onTap: _onBottomNavTap, onTap: _onBottomNavTap,

View file

@ -18,7 +18,7 @@ class _LoginPageState extends State<LoginPage> {
bool _isLogin = true; bool _isLogin = true;
bool _isLoading = false; 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<void> _handleAuth() async { Future<void> _handleAuth() async {
final email = _emailController.text.trim(); final email = _emailController.text.trim();
@ -30,7 +30,6 @@ class _LoginPageState extends State<LoginPage> {
try { try {
if (_isLogin) { if (_isLogin) {
// Call login endpoint and save token
final token = await _login(email, password); final token = await _login(email, password);
if (token != null) { if (token != null) {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
@ -39,7 +38,6 @@ class _LoginPageState extends State<LoginPage> {
context, MaterialPageRoute(builder: (context) => HomePage())); context, MaterialPageRoute(builder: (context) => HomePage()));
} }
} else { } else {
// Call register endpoint
final uid = await _register(email, password, _displayNameController.text.trim()); final uid = await _register(email, password, _displayNameController.text.trim());
if (uid != null) { if (uid != null) {
setState(() { setState(() {

View file

@ -12,7 +12,7 @@ class _CreateMatchPageState extends State<CreateMatchPage> {
String? _matchId; String? _matchId;
bool _isLoading = false; 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 // Method to create a match
Future<void> _createMatch() async { Future<void> _createMatch() async {

View file

@ -13,8 +13,8 @@ class _AddFriendPageState extends State<AddFriendPage> {
List<dynamic> _friends = []; List<dynamic> _friends = [];
bool _isLoading = false; bool _isLoading = false;
final String _addFriendApiUrl = 'http://10.0.0.10:9134/add_friend'; final String _addFriendApiUrl = 'http://api.dthpp.mercurio.moe/add_friend';
final String _getFriendsApiUrl = 'http://10.0.0.10:9134/get_friends'; final String _getFriendsApiUrl = 'http://api.dthpp.mercurio.moe/get_friends';
// Method to add a friend // Method to add a friend
Future<void> _addFriend(String friendUid) async { Future<void> _addFriend(String friendUid) async {

View file

@ -14,9 +14,10 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
bool _isLoading = false; bool _isLoading = false;
int _player1Score = 0; int _player1Score = 0;
int _player2Score = 0; int _player2Score = 0;
String? _matchId;
final String _joinMatchApiUrl = 'http://10.0.0.10:9134/joinmatch'; final String _joinMatchApiUrl = 'http://api.dthpp.mercurio.moe/joinmatch'; // Replace with your API endpoint
final String _endMatchApiUrl = 'http://10.0.0.10:9134/endmatch'; // Replace with your API endpoint final String _endMatchApiUrl = 'http://api.dthpp.mercurio.moe/endmatch'; // Replace with your API endpoint
// Join Match Function // Join Match Function
Future<void> _joinMatch() async { Future<void> _joinMatch() async {
@ -46,8 +47,9 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
if (response.statusCode == 200) { if (response.statusCode == 200) {
setState(() { setState(() {
_isJoined = true; _isJoined = true;
_player1Score = 0; // Reset scores for the new match _player1Score = 0;
_player2Score = 0; _player2Score = 0;
_matchId = matchId;
}); });
_showToast('Joined match successfully!'); _showToast('Joined match successfully!');
} else { } else {
@ -95,7 +97,7 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
Uri.parse(_endMatchApiUrl), Uri.parse(_endMatchApiUrl),
headers: {'Content-Type': 'application/json'}, headers: {'Content-Type': 'application/json'},
body: json.encode({ body: json.encode({
'token': token, 'match_id': int.parse(_matchId!),
'player1_score': _player1Score, 'player1_score': _player1Score,
'player2_score': _player2Score, 'player2_score': _player2Score,
}), }),
@ -155,6 +157,7 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
], ],
), ),
SizedBox(height: 16), SizedBox(height: 16),
// Player 2 Score Controls
Row( Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
@ -173,6 +176,7 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
], ],
), ),
SizedBox(height: 32), SizedBox(height: 32),
// End Match Button
ElevatedButton( ElevatedButton(
onPressed: _endMatch, onPressed: _endMatch,
child: Text('End Match'), child: Text('End Match'),
@ -183,6 +187,7 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
// Match ID Text Field
TextField( TextField(
controller: _matchIdController, controller: _matchIdController,
decoration: InputDecoration( decoration: InputDecoration(
@ -191,6 +196,7 @@ class _JoinMatchPageState extends State<JoinMatchPage> {
), ),
), ),
SizedBox(height: 16), SizedBox(height: 16),
// Join Match Button
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
if (_matchIdController.text.isNotEmpty) { if (_matchIdController.text.isNotEmpty) {

View file

@ -11,7 +11,7 @@ class _LeaderboardPageState extends State<LeaderboardPage> {
List<dynamic> _leaderboard = []; List<dynamic> _leaderboard = [];
bool _isLoading = true; bool _isLoading = true;
final String _apiUrl = 'http://10.0.0.10:9134/leaderboards'; final String _apiUrl = 'http://api.dthpp.mercurio.moe/leaderboards';
Future<void> _fetchLeaderboard() async { Future<void> _fetchLeaderboard() async {
setState(() { setState(() {

View file

@ -1,38 +1,190 @@
import 'dart:convert';
import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
class PlaceholderPage extends StatelessWidget { class ProfilePage extends StatefulWidget {
final String description; @override
_ProfilePageState createState() => _ProfilePageState();
}
const PlaceholderPage({ class _ProfilePageState extends State<ProfilePage> {
Key? key, bool _isLoading = true;
this.description = 'This is a placeholder page. Work in progress!', String? _name;
}) : super(key: key); int? _uid;
int? _elo;
List<dynamic> _matches = [];
final String _getProfileApiUrl = 'http://api.dthpp.mercurio.moe/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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( 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( return Card(
child: Padding( margin: EdgeInsets.symmetric(
padding: const EdgeInsets.all(16.0), horizontal: 16.0, vertical: 8.0),
child: Column( child: Padding(
mainAxisAlignment: MainAxisAlignment.center, padding: const EdgeInsets.all(16.0),
crossAxisAlignment: CrossAxisAlignment.center, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
Icon( children: [
Icons.construction, Text(
size: 80, 'Match ID: ${match['match_id']}',
color: Colors.grey, 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),
],
),
), ),
), ),
); );