fix: add pagination to draw list of played game in profile page

This commit is contained in:
kmitresse
2024-06-14 09:35:48 +02:00
parent 96fc8a2c11
commit 01c1793c48
10 changed files with 232 additions and 44 deletions
@@ -6,6 +6,11 @@
package uppa.project.database.dao;
import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import java.util.List;
import uppa.project.database.pojo.Player;
/**
* DAO abstrait et générique pour tout type de données
*
@@ -79,4 +84,14 @@ public abstract class DAO<D> {
* @see D
*/
public abstract D[] findByField(String field, Object value) throws DAOException;
public Player[] findPlayerForPagination(int userId, int firstData) throws DAOException {
EntityManager entityManager = EntityManagerProvider.getInstance();
TypedQuery<Player> query = entityManager.createQuery("SELECT p FROM Player p WHERE p.user.id = (:user) ORDER BY p.id DESC", Player.class);
query.setParameter("user", userId);
query.setFirstResult(firstData);
query.setMaxResults(5);
List<Player> results = query.getResultList();
return results.toArray(new Player[0]);
}
}
@@ -1,13 +1,19 @@
package uppa.project.json.websocket;
import java.text.SimpleDateFormat;
import java.util.Date;
import uppa.project.database.pojo.Card;
import uppa.project.database.pojo.Player;
import uppa.project.web.translation.Translator;
public class SimplePlayer {
private final SimpleUser user;
private final int gameId;
private final int score;
private final boolean winner;
private final String winnerUsername;
private final String createdDate;
private final int clickCount;
private final int rightClickCount;
private final int partialRightClickCount;
@@ -18,11 +24,48 @@ public class SimplePlayer {
this.user = new SimpleUser(player.getUser());
this.score = player.getScore();
this.winner = player.isWinner();
this.winnerUsername = "";
this.clickCount = player.getClickCount();
this.rightClickCount = player.getRightClickCount();
this.rapidClickCount = player.getRapidClickCount();
this.partialRightClickCount = player.getPartialRightClickCount();
this.currentCard = player.getDeck().getCards().get((partialRightClickCount+rightClickCount) % player.getDeck().getCards().size());
this.createdDate = "";
this.gameId = -1;
}
/**
* Constructeur pour la pagination
*
* @param player le joueur
* @param translator le traducteur
*/
public SimplePlayer(Player player, Translator translator) {
this.user = new SimpleUser(player.getUser());
this.gameId = player.getGame().getId().intValue();
this.score = player.getScore();
this.winner = player.isWinner();
this.winnerUsername = player.getGame().getWinner().getUser().getUsername();
this.clickCount = player.getClickCount();
this.rightClickCount = player.getRightClickCount();
this.rapidClickCount = player.getRapidClickCount();
this.partialRightClickCount = player.getPartialRightClickCount();
this.currentCard = null;
Date date = player.getGame().getCreatedAt();
String language = translator.getLanguage();
SimpleDateFormat sdfDay;
SimpleDateFormat sdfHour;
if (translator.getLanguage().equals("EN")) {
sdfDay = new SimpleDateFormat("MM/dd/yyyy");
sdfHour = new SimpleDateFormat("HH:mm");
} else {
sdfDay = new SimpleDateFormat("dd/MM/yyyy");
sdfHour = new SimpleDateFormat("HH:mm");
}
String day = sdfDay.format(date);
String hour = sdfHour.format(date);
this.createdDate = day + ',' + hour ;
}
public SimplePlayer(Player player) {
@@ -34,6 +77,10 @@ public class SimplePlayer {
this.partialRightClickCount = player.getPartialRightClickCount();
this.rapidClickCount = player.getRapidClickCount();
this.currentCard = null;
this.winnerUsername = "";
this.createdDate = "" ;
this.gameId = -1;
}
public Card getCurrentCard() {
@@ -22,6 +22,7 @@ import uppa.project.database.pojo.Player;
import uppa.project.database.pojo.User;
import uppa.project.json.HttpResponse;
import uppa.project.json.HttpResponseCode;
import uppa.project.json.websocket.SimplePlayer;
import uppa.project.web.translation.Translator;
@WebServlet(name = "profileServlet", value = "/profile")
@@ -96,6 +97,37 @@ public class ProfileServlet extends HttpServlet {
out.flush();
}
public void doPut(HttpServletRequest request, HttpServletResponse response) throws IOException {
Translator translator = (Translator) request.getSession().getAttribute("translator");
int userID =Integer.parseInt(request.getParameter("userId"));
int firstData = Integer.parseInt(request.getParameter("pageNumber")) * 5;
try {
DAO<Player> playerDAO = new Game_JPA_DAO_Factory().getDAOPlayer();
Player[] players = playerDAO.findPlayerForPagination(userID, firstData);
SimplePlayer[] simplePlayers = new SimplePlayer[players.length];
for (int i = 0; i < players.length; i++) {
simplePlayers[i] = new SimplePlayer(players[i], translator);
}
Gson gson = new Gson();
System.out.println("players");
String jsonPlayers = gson.toJson(simplePlayers);
System.out.println("players");
System.out.println("json: "+jsonPlayers);
// Configurer la réponse
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
// Envoyer la réponse JSON
PrintWriter out = response.getWriter();
out.println(jsonPlayers);
out.flush();
} catch (DAOException e) {
throw new RuntimeException(e);
}
}
public void destroy() {
}
}
@@ -9,6 +9,7 @@
<layout:base title="${translator.translate('profile_title')}">
<jsp:attribute name="head">
<script defer type="module" src="${pageContext.request.contextPath}/static/js/form/profile.js"></script>
<script defer type="module" src="${pageContext.request.contextPath}/static/js/pagination/statistics-pagination.js"></script>
</jsp:attribute>
<jsp:body>
<component:hero>
@@ -1,11 +1,10 @@
<%@ tag import="uppa.project.database.pojo.Player" %>
<%@ tag import="uppa.project.web.translation.Translator" %>
<%@ tag import="java.util.Date" %>
<%@ tag import="java.text.SimpleDateFormat" %>
<%@tag description="component/statistics" pageEncoding="UTF-8" %>
<% Translator translator = (Translator) request.getSession().getAttribute("translator"); %>
<% int currentPage = request.getParameter("currentPage") == null ? 1 : Integer.parseInt(request.getParameter("currentPage")); %>
<jsp:useBean id="user" class="uppa.project.database.pojo.User" scope="session"/>
<input type="hidden" id="current-page" value="<%=currentPage%>"/>
<input type="hidden" id="nb-pages" value="<%=(int) Math.ceil((double) user.getNbPlayedGame() / 5)%>"/>
<h4 class="title is-4">${translator.translate("global_statistics")}</h4>
<div class="level">
<div class="level-item has-text-centered">
@@ -35,7 +34,7 @@
</div>
<h4 class="title is-4">${translator.translate("statistics_games_played")} </h4>
<table class="table is-fullwidth">
<table id="pagination-players" class="table is-fullwidth">
<thead>
<tr>
<th>${translator.translate("statistics_game_date")}</th>
@@ -44,31 +43,12 @@
<th></th>
</tr>
</thead>
<tbody>
<% for (int i = 0; i < user.getPlayedGames().size(); i++) {
Player player = user.getPlayedGames().get(i);
%>
<tr>
<% Date date = player.getGame().getCreatedAt();
String language = translator.getLanguage();
SimpleDateFormat sdfDay;
SimpleDateFormat sdfHour;
if (language.equals("EN")) {
sdfDay = new SimpleDateFormat("MM/dd/yyyy");
sdfHour = new SimpleDateFormat("HH:mm");
} else {
sdfDay = new SimpleDateFormat("dd/MM/yyyy");
sdfHour = new SimpleDateFormat("HH:mm");
}
String day = sdfDay.format(date);
String hour = sdfHour.format(date);
%>
<td><%=day%>, <%=hour%> </td>
<td><%= player.getScore() %></td>
<td><%= player.getGame().getWinner().getUser().getUsername() %></td>
<td><a href="${pageContext.request.contextPath}/game-statistics?id=<%= player.getGame().getId() %>">${translator.translate("statistics_game_show")}</a></td>
</tr>
<% } %>
</tbody>
<tbody></tbody>
</table>
<nav class="pagination is-rounded" role="navigation" aria-label="pagination">
<ul class="pagination-list">
<li><a class="pagination-previous">${translator.translate('pagination_previous')}</a></li>
<li><a class="pagination-link pagination-current" aria-label="Goto page 1"><%=currentPage%></a></li>
<li><a class="pagination-next">${translator.translate('pagination_next')}</a></li>
</ul>
</nav>
@@ -7,6 +7,7 @@
<form id="profile-form" action="${pageContext.request.contextPath}/profile" method="post">
<jsp:useBean id="user" class="uppa.project.database.pojo.User" scope="session"/>
<input id="user-id" type="hidden" name="user-id" value="${user.id}"/>
<div class="field">
<label class="label" for="username">${translator.translate('user_username')}</label>
<div class="control has-icons-left">
@@ -630,5 +630,13 @@
"game_statistics_win": {
"EN": "Win",
"FR": "Victoire"
},
"pagination_previous": {
"EN": "Previous",
"FR": "Précédent"
},
"pagination_next": {
"EN": "Next",
"FR": "Suivant"
}
}
@@ -22,6 +22,7 @@ languageSelector.addEventListener('change', function() {
const action = contextPath + "/translate";
console.log(action);
const method = "PUT";
const pagination = document.querySelector('#current-page');
const url = new URL(action);
url.searchParams.append("language", languageSelector.value);
@@ -0,0 +1,109 @@
const table = document.querySelector('#pagination-players tbody');
const userId = document.querySelector('#user-id');
const url = new URL(window.location.href);
const contextPath = url.pathname.substring(0, url.pathname.indexOf("/", 1) + 1)
const languageSelector = document.getElementById('language-select');
const currentPage = document.querySelector('input#current-page');
const nbPages = document.querySelector('#nb-pages');
console.log("nbPages:" + nbPages.value);
let showLabel;
if (languageSelector.value === 'EN') {
showLabel = 'Show';
} else {
showLabel = 'Voir';
}
const paginationPrevious = document.querySelector('.pagination-previous');
const paginationNext = document.querySelector('.pagination-next');
const paginationCurrent = document.querySelector('.pagination-current');
function updatePagination(pageNumber) {
document.querySelectorAll('.played-game-row').forEach(row => table.removeChild(row));
const url = new URL(window.location.href);
url.searchParams.set('userId', userId.value);
url.searchParams.set('pageNumber', pageNumber-1);
const method = 'PUT';
fetch(url, {headers: {"Content-Type": "application/json"}, method})
.then(res => res.json())
.then(data => {
for (let i = 0; i < 5; i++) {
if (data[i] === undefined) {
const row = document.createElement('tr');
row.classList.add('played-game-row');
row.innerHTML = `
<td></td>
<td></td>
<td></td>
<td></td>
`
table.appendChild(row);
} else {
const row = document.createElement('tr');
row.classList.add('played-game-row');
row.innerHTML = `
<td>${data[i].createdDate}</td>
<td>${data[i].score}</td>
<td>${data[i].winnerUsername}</td>
<td><a href="${contextPath}game-statistics?id=${data[i].gameId}">${showLabel}</a></td>`
table.appendChild(row);
}
}
// data.forEach(player => {
// const row = document.createElement('tr');
// row.classList.add('played-game-row');
// row.innerHTML = `
// <td>${player.createdDate}</td>
// <td>${player.score}</td>
// <td>${player.winnerUsername}</td>
// <td><a href="${contextPath}game-statistics?id=${player.gameId}">${showLabel}</a></td>`
// table.appendChild(row);
// });
})
}
function updateButtons(oldPageNumber,newPageNumber) {
console.log("old: " + oldPageNumber +", new: " + newPageNumber)
if (oldPageNumber === "1") {
console.log("previous - not disable")
paginationPrevious.classList.remove('is-disable');
}
if (newPageNumber === "1") {
console.log("previous - disable")
paginationPrevious.classList.add('is-disable');
}
if (oldPageNumber === nbPages.value.toString()) {
console.log("next - not disable")
paginationNext.classList.remove('is-disable');
}
if (newPageNumber === nbPages.value.toString()) {
console.log("next - disable")
paginationNext.classList.add('is-disable');
}
paginationCurrent.textContent = `${newPageNumber}`;
console.log(paginationCurrent)
}
updatePagination(currentPage.value);
updateButtons(currentPage.value, currentPage.value)
paginationPrevious.addEventListener('click', () => {
const newPageNumber = (parseInt(currentPage.value) - 1).toString();
const oldPageNumber = currentPage.value.toString();
currentPage.value = newPageNumber;
updatePagination(newPageNumber);
updateButtons(oldPageNumber, newPageNumber);
})
paginationNext.addEventListener('click', () => {
const newPageNumber = (parseInt(currentPage.value) + 1).toString();
const oldPageNumber = currentPage.value.toString();
currentPage.value = newPageNumber;
updatePagination(newPageNumber);
updateButtons(oldPageNumber, newPageNumber);
})
@@ -20,11 +20,9 @@ const buttons = document.querySelectorAll('a#start-game-button, a#invite-player'
function updateButtons(user) {
buttons.forEach(button => {
if (user.id !== gameAdminID ) {
console.log("not admin" + user.username)
button.classList.add('is-disable');
button.setAttribute('title', 'Accessible uniquement par l\'admin');
} else {
console.log("is admin" + user.username)
button.classList.remove('is-disable');
button.removeAttribute('title');
}
@@ -44,7 +42,6 @@ function updateAdmin(user) {
}
onInfo(titleInfo, messageInfo)
}
console.log("admin:" + user.username)
gameAdminID = user.id;
}
let havePlayed = false;
@@ -102,15 +99,11 @@ wsgame.onOpen(() => {
});
wsgame.onMessage("updatePlayerList", (data) => {
players = data;
console.log(players)
if (gameAdminID === -1 || players[0].user.id !== gameAdminID) {
updateAdmin(players[0].user)
}
players.forEach((player) => {
console.log("player:" + player.user.id)
console.log("user:" + userSessionId.value)
console.log( player.user.id.toString() == userSessionId.value)
if (player.user.id.toString() === userSessionId.value) {
updateButtons(player.user)
}
@@ -141,7 +134,7 @@ wsgame.onMessage("start", (game) => {
// Show other player cards
game.players
.filter(p => p.user.id !== userSessionId.value)
.filter(p => p.user.id.toString() !== userSessionId.value)
.forEach(p => {
const playerHand = new PlayerHand(p);
otherCards.innerHTML += playerHand.render({
@@ -151,7 +144,7 @@ wsgame.onMessage("start", (game) => {
});
// Show my card
const me = game.players.find(p => p.user.id === userSessionId.value);
const me = game.players.find(p => p.user.id.toString() === userSessionId.value);
const playerHand = new PlayerHand(me);
myCard.innerHTML += playerHand.render({
@@ -206,8 +199,9 @@ wsgame.onMessage("nextRound", (game) => {
// Show other player cards
game.players
.filter(p => p.user.id !== userSessionId.value)
.filter(p => p.user.id.toString() !== userSessionId.value)
.forEach(p => {
console.log('adversaire:', p)
const playerHand = new PlayerHand(p);
otherCards.innerHTML += playerHand.render({
textPosition: PlayerHand.TextPosition.TOP,
@@ -216,7 +210,7 @@ wsgame.onMessage("nextRound", (game) => {
});
// Show my card
const me = game.players.find(p => p.user.id === userSessionId.value);
const me = game.players.find(p => p.user.id.toString() === userSessionId.value);
const playerHand = new PlayerHand(me);
myCard.innerHTML += playerHand.render({
@@ -231,7 +225,7 @@ wsgame.onMessage("nextRound", (game) => {
wsgame.onMessage("end", (game) => {
clearInterval(timerInterval);
window.location.href = "${pageContext.request.contextPath}/game-statistics?id=${game.id}&endGame=true";
window.location.href = contextPath+"/game-statistics?id="+gameId.value+"&endGame=true";
})
// Close handling