diff --git a/frontend/static/js/api/Profile.js b/frontend/static/js/api/Profile.js
index faeef20..68b8ea4 100644
--- a/frontend/static/js/api/Profile.js
+++ b/frontend/static/js/api/Profile.js
@@ -75,14 +75,14 @@ export class Profile extends AExchangeable
}
/**
- * @returns {[Object]}
+ * @returns {Promise<[Object]>}
*/
async getGameHistory()
{
- let response = await this.client._get(`/api/games/history/${this.id}`);
- let response_data = await response.json();
+ const response = await this.client._get(`/api/games/history/${this.id}`);
+ const response_data = await response.json();
- let games = [];
+ const games = [];
response_data.forEach(game_data => {
games.push(game_data);
diff --git a/frontend/static/js/index.js b/frontend/static/js/index.js
index 9a62e1e..bea273b 100644
--- a/frontend/static/js/index.js
+++ b/frontend/static/js/index.js
@@ -20,7 +20,6 @@ import TournamentPageView from "./views/tournament/TournamentPageView.js";
import TournamentsListView from "./views/tournament/TournamentsListView.js";
import TournamentCreateView from "./views/tournament/TournamentCreateView.js";
import AuthenticationView from "./views/accounts/AuthenticationView.js";
-import GameHistoryView from "./views/GameHistoryView.js";
let client = new Client(location.origin);
let lang = client.lang;
@@ -79,7 +78,6 @@ const router = async(uri) => {
const routes = [
{ path: "/", view: HomeView},
- { path: "/profiles/:id/history", view: GameHistoryView },
{ path: "/profiles/:username", view: ProfilePageView },
{ path: "/tournaments/create", view: TournamentCreateView },
{ path: "/tournaments/:id", view: TournamentPageView },
diff --git a/frontend/static/js/views/GameHistoryView.js b/frontend/static/js/views/GameHistoryView.js
deleted file mode 100644
index 60e7850..0000000
--- a/frontend/static/js/views/GameHistoryView.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import { client, lang } from "../index.js";
-import AbstractAuthenticatedView from "./abstracts/AbstractAuthenticatedView.js";
-
-export default class extends AbstractAuthenticatedView
-{
- constructor(params)
- {
- super(params, 'homeWindowTitle');
- this.id = params.id;
- }
-
- async postInit()
- {
- this.profile = await client.profiles.getProfileId(this.id);
-
- if (this.profile === null)
- return 404;
-
- await this.fillHistory();
- }
-
- async fillHistory()
- {
- let games = await this.profile.getGameHistory();
-
- let game_list = document.getElementById("game-list");
-
- games.forEach(game => {
-
- let a = document.createElement("a");
- a.href = `/games/${game.id}/0`;
- a.setAttribute("data-link", true);
-
- let game_item = document.createElement("div");
- game_item.className = "game-item";
- game_item.style.backgroundColor = "grey";
- if (game.started)
- game_item.style.backgroundColor = "yellow";
- if (game.finished)
- game_item.style.backgroundColor = this.profile.id === game.winner_id ? "green" : "red";
-
- game.players.forEach(player => {
- let player_score = document.createElement("a");
-
- player_score.href = `/profiles/${player.username}`;
- player_score.innerText = `${player.username}: ${player.score.length}`;
- player_score.setAttribute("data-link", true);
-
- game_item.appendChild(player_score);
- });
-
- a.appendChild(game_item);
- game_list.appendChild(a);
- });
- }
-
- async getHtml()
- {
- return /* HTML */ `
-
-
Game History
-
-
- `;
- }
-}
diff --git a/frontend/static/js/views/ProfilePageView.js b/frontend/static/js/views/ProfilePageView.js
index 7ebc850..41405c8 100644
--- a/frontend/static/js/views/ProfilePageView.js
+++ b/frontend/static/js/views/ProfilePageView.js
@@ -16,6 +16,13 @@ export default class extends AbstractView {
if (!this.profile)
return 404;
+ const games = await this.profile.getGameHistory();
+
+ console.log(games)
+
+ await this.fillHistory(games);
+ await this.fillStatistics(games);
+
if (this.profile.id === client.me.id)
return;
@@ -68,13 +75,69 @@ export default class extends AbstractView {
statusIndicator.classList.add('bg-danger');
}
+ /**
+ * @param {[Object]} games
+ */
+ async fillStatistics(games)
+ {
+ const winrateDiv = document.getElementById("winrate");
+
+ const win = 0;
+ const lose = 0;
+
+ games.forEach(game => {
+ if (game.finished === false)
+ return
+
+ if (client.me.id === game.winner.id)
+ win++;
+ else
+ lose++;
+ });
+
+ winrateDiv.innerText = `winrate: ${win + lose === 0 ? "🤓" : win / (win + lose)}`
+ }
+
+ async fillHistory(games)
+ {
+ const game_list = document.getElementById("game-list");
+
+ games.forEach(game => {
+
+ let a = document.createElement("a");
+ a.href = `/games/${game.game_type}/${game.id}`;
+ a.setAttribute("data-link", true);
+
+ let game_item = document.createElement("div");
+ game_item.className = "game-item";
+ game_item.style.backgroundColor = "grey";
+ if (game.started)
+ game_item.style.backgroundColor = "yellow";
+ if (game.finished)
+ game_item.style.backgroundColor = this.profile.id === game.winner.id ? "green" : "red";
+
+ game.players.forEach(player => {
+ let player_score = document.createElement("a");
+
+ player_score.href = `/profiles/${player.username}`;
+ player_score.innerText = `${player.username}`;
+ player_score.setAttribute("data-link", true);
+
+ game_item.appendChild(player_score);
+ });
+
+ a.appendChild(game_item);
+ game_list.appendChild(a);
+ });
+ }
+
async getHtml() {
this.profile = await client.profiles.getProfile(this.username);
if (!this.profile)
return '';
- return `
+ return /* HTML */ `
${this.username}
@@ -88,6 +151,14 @@ export default class extends AbstractView {
+
Games
+
+
+
+
`;
}
diff --git a/games/GameHistoryView.py b/games/GameHistoryView.py
deleted file mode 100644
index b7a1a10..0000000
--- a/games/GameHistoryView.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from rest_framework.views import APIView
-from rest_framework.response import Response
-from rest_framework import permissions, status
-
-from django.http import HttpRequest
-
-from .models import GameMembersModel, GameModel
-from .serializers import GameSerializer
-
-from . import config
-
-class GameHistoryView(APIView):
-
- permission_classes = (permissions.AllowAny,)
-
- def get(self, request: HttpRequest, pk: int = None):
-
- member_game_model_list: list[GameMembersModel] = GameMembersModel.objects.filter(player_id = pk)
-
- game_model_list: list[GameModel] = []
-
- for member_game_model in member_game_model_list:
- game_model_list.append(GameModel.objects.get(pk = member_game_model.game_id))
-
- games_data: list[dict] = [GameSerializer(game_model).data for game_model in game_model_list]
-
- return Response(games_data)
\ No newline at end of file
diff --git a/games/GameHistoryViewSet.py b/games/GameHistoryViewSet.py
new file mode 100644
index 0000000..52560b8
--- /dev/null
+++ b/games/GameHistoryViewSet.py
@@ -0,0 +1,28 @@
+from rest_framework.viewsets import ViewSet
+from rest_framework.response import Response
+from rest_framework import permissions
+
+from django.http import HttpRequest
+from django.contrib.auth.models import User
+from django.shortcuts import get_object_or_404
+
+from .models import GameMembersModel, GameModel
+from .serializers import GameSerializer
+
+class GameHistoryView(ViewSet):
+
+ queryset = User.objects.all()
+ serializer_class = GameSerializer
+ permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
+
+ def retrive(self, request: HttpRequest, pk: int = None):
+
+ user: User = get_object_or_404(User, pk=pk)
+
+ member_game_model_list: list[GameMembersModel] = GameMembersModel.objects.filter(player=user)
+
+ game_model_list: list[GameModel] = [member_game_model.game for member_game_model in member_game_model_list]
+
+ games_data: list[dict] = self.serializer_class(game_model_list, many=True).data
+
+ return Response(games_data)
\ No newline at end of file
diff --git a/games/models.py b/games/models.py
index edd26f7..b708a72 100644
--- a/games/models.py
+++ b/games/models.py
@@ -38,11 +38,11 @@ class GameModel(models.Model):
self.stop_timestamp = round(time.time() * 1000, 1)
self.save()
- def get_players(self) -> set[User]:
- return {game_player.player for game_player in GameMembersModel.objects.filter(game = self)}
+ def get_players(self) -> list[User]:
+ return [game_player.player for game_player in GameMembersModel.objects.filter(game = self)]
- def get_players_profiles(self) -> set[User]:
- return {game_player.player.profilemodel for game_player in GameMembersModel.objects.filter(game = self)}
+ def get_players_profiles(self) -> list[User]:
+ return [game_player.player.profilemodel for game_player in GameMembersModel.objects.filter(game = self)]
def get_score_by_player_id(self, player_id: int) -> list[int]:
query: QuerySet = GameGoalModel.objects.filter(game_id = self.pk, player_id = player_id)
diff --git a/games/serializers.py b/games/serializers.py
index 746b02d..2c8200c 100644
--- a/games/serializers.py
+++ b/games/serializers.py
@@ -9,7 +9,7 @@ from profiles.serializers import ProfileSerializer
class GameSerializer(serializers.ModelSerializer):
players = serializers.SerializerMethodField()
- winner_id = serializers.ReadOnlyField()
+ winner = serializers.ReadOnlyField()
state = serializers.SerializerMethodField()
started = serializers.ReadOnlyField()
finished = serializers.ReadOnlyField()
@@ -19,7 +19,7 @@ class GameSerializer(serializers.ModelSerializer):
class Meta:
model = GameModel
- fields = ["id", "winner_id", "state", "started", "finished", "players", "start_timestamp", "stop_timestamp", "game_type"]
+ fields = ["id", "winner", "state", "started", "finished", "players", "start_timestamp", "stop_timestamp", "game_type"]
def get_state(self, instance: GameModel):
if (instance.finished):
diff --git a/games/urls.py b/games/urls.py
index 34e28c2..ebceaac 100644
--- a/games/urls.py
+++ b/games/urls.py
@@ -3,11 +3,11 @@ from django.conf import settings
from django.conf.urls.static import static
from .GameViewSet import GameViewSet
-from .GameHistoryView import GameHistoryView
+from .GameHistoryViewSet import GameHistoryView
from .GameConfigView import GameConfigView
urlpatterns = [
path("", GameViewSet.as_view({"get": "retrieve"}), name="game_page"),
- path("history/", GameHistoryView.as_view(), name="history_page"),
+ path("history/", GameHistoryView.as_view({"get": "retrive"}), name="history_page"),
path("", GameConfigView.as_view(), name = "game_config")
]
\ No newline at end of file