From 2a18dbe2048a0caaa9789552418744f37e40d471 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 20 Apr 2024 23:29:02 +0200 Subject: [PATCH 01/16] =?UTF-8?q?Cambiadas=20im=C3=A1genes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/Game.js | 2 +- .../src/components/images/ronnie-comiendo.png | Bin 18630 -> 157303 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index 148c7cbe..ce6155ee 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -163,7 +163,7 @@ const Game = () => {
{options.map((option, index) => ( - - - - - diff --git a/webapp/src/index.js b/webapp/src/index.js index f6ee72c7..e3ebbff4 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -22,6 +22,7 @@ import PantallaInicioAdmin from './components/PantallaInicioAdmin'; import Login from './components/Login'; import AddUser from './components/AddUser'; import Game from './components/Game'; +import EndGame from './components/EndGame'; import Gamehistory from './components/Gamehistory'; import Perfil from './components/Perfil'; import AllUsers from './components/AllUsers'; @@ -58,6 +59,7 @@ root.render( } /> } /> } /> + } /> } /> } /> } /> From a1d8f902065d1efdcef82fb130aeddcc7802ac9b Mon Sep 17 00:00:00 2001 From: David Date: Mon, 22 Apr 2024 01:30:54 +0200 Subject: [PATCH 03/16] =?UTF-8?q?Implementaci=C3=B3n=20tabla=20ranking?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gamehistoryservice/gamehistory.js | 25 +++++++ gatewayservice/gateway-service.js | 9 +++ webapp/src/components/Ranking.js | 106 +++++++++++++++++++++++++++++- 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/gamehistoryservice/gamehistory.js b/gamehistoryservice/gamehistory.js index 9f716f0d..769cf811 100644 --- a/gamehistoryservice/gamehistory.js +++ b/gamehistoryservice/gamehistory.js @@ -201,6 +201,31 @@ async function getEndGameStats(userId) { } } +app.get('/ranking', async (req, res) => { + try { + const sortBy = req.query.sortBy || 'ratio'; // Campo por el cual ordenar + const limit = parseInt(req.query.limit) || 10; // Número de usuarios a devolver + + const topUsers = await GameHistory.find() + .sort({ [sortBy]: -1 }) // Siempre ordena de mayor a menor + .limit(limit); // Limita el número de usuarios devueltos + + const response = topUsers.map(user => ({ + userId: user.userId, + totalGamesPlayed: user.totalGamesPlayed, + totalQuestionsAnswered: user.totalQuestionsAnswered, + totalRightQuestions: user.totalRightQuestions, + ratio: `${user.ratio}%`, + totalTime: `${user.totalTime}s` + })); + + res.json(response); + + } catch (error) { + res.status(400).json({ error: `Error al obtener el ranking: ${error.message}` }); + } +}); + const server = app.listen(port, () => { console.log(`Stats Service listening at http://localhost:${port}`); diff --git a/gatewayservice/gateway-service.js b/gatewayservice/gateway-service.js index 8bd82923..47f28621 100644 --- a/gatewayservice/gateway-service.js +++ b/gatewayservice/gateway-service.js @@ -141,6 +141,15 @@ app.get('/topUsers', async (req, res) => { } }); +app.get('/ranking', async (req, res) => { + try { + const response = await axios.get(gamehistoryUrl+'/ranking', req.body); + res.json(response.data); + } catch (error) { + res.status(error.response.status).json({ error: error.response.data.error }); + } +}); + app.get('/endgamestats', async (req, res) => { try { const URL = gamehistoryUrl + '/endgamestats?username=' + req.query.username; diff --git a/webapp/src/components/Ranking.js b/webapp/src/components/Ranking.js index e7608810..f600f0ea 100644 --- a/webapp/src/components/Ranking.js +++ b/webapp/src/components/Ranking.js @@ -1,6 +1,21 @@ import React, { useState, useEffect, useCallback } from 'react'; import axios from 'axios'; -import { Container, Box, Typography, Grid} from '@mui/material'; +import { + Container, + Box, + Typography, + Grid, + Select, + MenuItem, + FormControl, + InputLabel, + TextField, + Table, + TableBody, + TableCell, + TableHead, + TableRow, +} from '@mui/material'; import { useUser } from './UserContext'; import '../App.css'; import { useTranslation } from 'react-i18next'; @@ -14,6 +29,9 @@ const Ranking = () => { const { usernameGlobal } = useUser(); const [ranking, setRanking] = useState(''); const [error, setError] = useState(''); + const [rankingTable, setRankingTable] = useState([]); + const [sortBy, setSortBy] = useState('ratio'); + const [userLimit, setUserLimit] = useState(10); const getRanking = useCallback(async () => { try { @@ -24,8 +42,24 @@ const Ranking = () => { } }, [usernameGlobal]) + const getRankingGlobal = useCallback(async () => { + try { + const response = await axios.get( + `${apiEndpoint}/ranking`, { + params: { + sortBy: sortBy, + userLimit: userLimit + } + }); + setRankingTable(response.data); + } catch (error) { + setError(error.response.data.error); + } + }, [sortBy, userLimit]); + useEffect(() => { getRanking(); + getRankingGlobal(); }, [getRanking]); return ( @@ -71,6 +105,76 @@ const Ranking = () => { + + + + + + Ordenar por + + + + + + setUserLimit(parseInt(e.target.value))} + inputProps={{ min: 1, max: 10 }} + /> + + + + + + + + Usuario + + {sortBy === "ratio" ? "Ratio" : + sortBy === "totalQuestionsAnswered" ? "Preguntas respondidas" : + sortBy === "totalRightQuestions" ? "Aciertos" : + sortBy === "totalGamesPlayed" ? "Partidas jugadas" : + sortBy === "totalTime" ? "Tiempo total" : ""} + + + + + {rankingTable.map((user, index) => ( + + {user.userId} + + {sortBy === "ratio" ? user.ratio : + sortBy === "totalQuestionsAnswered" ? user.totalQuestionsAnswered : + sortBy === "totalRightQuestions" ? user.totalRightQuestions : + sortBy === "totalGamesPlayed" ? user.totalGamesPlayed : + sortBy === "totalTime" ? user.totalTime : ""} + + + ))} + +
+
); }; From 6ebd7590619e41b725128a730f342d509282113a Mon Sep 17 00:00:00 2001 From: David Date: Mon, 22 Apr 2024 02:06:46 +0200 Subject: [PATCH 04/16] Cambio proporciones --- gamehistoryservice/gamehistory.js | 2 +- webapp/src/components/GameConfiguration.js | 24 +- webapp/src/components/Ranking.js | 249 ++++++++++++--------- 3 files changed, 157 insertions(+), 118 deletions(-) diff --git a/gamehistoryservice/gamehistory.js b/gamehistoryservice/gamehistory.js index 769cf811..214f9007 100644 --- a/gamehistoryservice/gamehistory.js +++ b/gamehistoryservice/gamehistory.js @@ -204,7 +204,7 @@ async function getEndGameStats(userId) { app.get('/ranking', async (req, res) => { try { const sortBy = req.query.sortBy || 'ratio'; // Campo por el cual ordenar - const limit = parseInt(req.query.limit) || 10; // Número de usuarios a devolver + const limit = parseInt(req.query.userLimit) || 10; // Número de usuarios a devolver const topUsers = await GameHistory.find() .sort({ [sortBy]: -1 }) // Siempre ordena de mayor a menor diff --git a/webapp/src/components/GameConfiguration.js b/webapp/src/components/GameConfiguration.js index 5032235c..fbf89608 100644 --- a/webapp/src/components/GameConfiguration.js +++ b/webapp/src/components/GameConfiguration.js @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import axios from 'axios'; import { useNavigate} from 'react-router-dom'; -import { Container, Typography, TextField, Button, Snackbar, skeletonClasses } from '@mui/material'; +import { Container, Typography, TextField, Button, Snackbar, skeletonClasses, FormControl, InputLabel, Select, MenuItem} from '@mui/material'; import '../App.css'; import { useTranslation } from 'react-i18next'; @@ -113,15 +113,19 @@ const GameConfiguration = () => { {t("textoTematicas")} -
- -
+ + Temáticas + + - - - - -
- {error && ( - setError('')} message={`Error: ${error}`} /> - )} -
- - ); -}; - -export default NavigationBar_Game; \ No newline at end of file