diff --git a/statsservice/model/stats-getter.js b/statsservice/model/stats-getter.js index cf47411d..04d2ccae 100644 --- a/statsservice/model/stats-getter.js +++ b/statsservice/model/stats-getter.js @@ -58,16 +58,39 @@ class StatsForUser { ratioCorrect: newRatioCorrect, avgTime: newAvgTime }; - } + }; - async getRanking(gamemode) { + async getRanking(gamemode, filterBy) { try { - var stats = await Stats.find({gamemode:gamemode}).sort({ avgPoints: -1 }).limit(10); + let sortBy, displayField; + + switch (filterBy) { + case "avgPoints": + sortBy = { avgPoints: -1 }; + displayField = "avgPoints"; + break; + case "totalPoints": + sortBy = { totalPoints: -1 }; + displayField = "totalPoints"; + break; + case "ratioCorrect": + sortBy = { ratioCorrect: -1 }; + displayField = "ratioCorrect"; + break; + case "avgTime": + sortBy = { avgTime: -1 }; + displayField = "avgTime"; + break; + default: + return null; + } + + const stats = await Stats.find({ gamemode: gamemode }).sort(sortBy).limit(10); if (stats && stats.length > 0) { return stats.map(stat => ({ username: stat.username, - avgPoints: stat.avgPoints + [displayField]: stat[displayField] })); } else { return null; @@ -78,6 +101,7 @@ class StatsForUser { } } + } module.exports = StatsForUser; diff --git a/statsservice/stats-service.js b/statsservice/stats-service.js index 88ee82be..b0c3c2e9 100644 --- a/statsservice/stats-service.js +++ b/statsservice/stats-service.js @@ -88,7 +88,7 @@ app.get("/stats", async (req, res) => { app.get("/ranking", async (req, res) => { try { - var data = await statsGetter.getRanking(req.query.gamemode); + var data = await statsGetter.getRanking(req.query.gamemode,req.query.filterBy); res.json(data); } catch (error) { diff --git a/webapp/src/App.js b/webapp/src/App.js index dee6ef63..08eab810 100644 --- a/webapp/src/App.js +++ b/webapp/src/App.js @@ -5,6 +5,7 @@ import Clasico from "./pages/Clasico/Clasico.js"; import Bateria from "./pages/Bateria/Bateria.js"; import WrongRoute from "./pages/WrongRoute/WrongRoute.js"; import Stats from "./pages/Stats/Stats.js"; +import Ranking from "./pages/Ranking/Ranking.js"; import "./App.css"; import { BrowserRouter, Routes, Route } from "react-router-dom"; import { ProtectedRoute } from "./routers/ProtectedRoute.js"; @@ -26,6 +27,7 @@ function App() { } /> } /> } /> + } /> } /> diff --git a/webapp/src/pages/Bateria/Bateria.js b/webapp/src/pages/Bateria/Bateria.js index ff6a7a64..324ae408 100644 --- a/webapp/src/pages/Bateria/Bateria.js +++ b/webapp/src/pages/Bateria/Bateria.js @@ -54,7 +54,11 @@ const JuegoPreguntas = () => { useEffect(() => { if (tiempoRestante === 0) { setJuegoTerminado(true); - + if(preguntasCorrectas+preguntasFalladas>0){ + const preguntasTotales=preguntasCorrectas+preguntasFalladas; + const tMedio=180/preguntasTotales; + setTiempoMedio(tMedio); + } guardarPartida(); } const timer = setInterval(() => { @@ -64,9 +68,7 @@ const JuegoPreguntas = () => { }, [tiempoRestante]); const guardarPartida = async () => { - if(preguntasCorrectas+preguntasFalladas>0){ - setTiempoMedio(180/(preguntasCorrectas+preguntasFalladas)); - } + const username = localStorage.getItem("username"); const newGame = { username: username, diff --git a/webapp/src/pages/Clasico/Clasico.js b/webapp/src/pages/Clasico/Clasico.js index a1a83a32..bb7fff29 100644 --- a/webapp/src/pages/Clasico/Clasico.js +++ b/webapp/src/pages/Clasico/Clasico.js @@ -56,7 +56,8 @@ const JuegoPreguntas = () => { }, []); useEffect(() => { - setProgressPercent((tiempoRestante / SECS_PER_QUESTION) * 100); + const roundedProgressPercent = ((tiempoRestante / SECS_PER_QUESTION) * 100).toFixed(2); + setProgressPercent(roundedProgressPercent); const timer = setInterval(() => { setTiempoRestante((prevTiempo) => @@ -111,34 +112,46 @@ const JuegoPreguntas = () => { }; const handleSiguientePregunta = () => { - if (respuestaSeleccionada === preguntaActual.correcta) { + if (respuestaSeleccionada === preguntaActual.correcta) { + const newCorrectQuestions=preguntasCorrectas+1; setPuntuacion(puntuacion + 1); - setPreguntasCorrectas(preguntasCorrectas + 1); - console.log("bien"); + setPreguntasCorrectas(newCorrectQuestions); + console.log("bien") } else { - setPreguntasFalladas(preguntasFalladas + 1); - console.log("mal"); + const newIncorrectQuestions=preguntasFalladas+1; + setPreguntasFalladas(newIncorrectQuestions); + console.log("mal") } setTiempoTotal(tiempoTotal+tiempoRestante); setRespuestaSeleccionada(null); setTiempoRestante(10); setProgressPercent(100); - if (indicePregunta + 1 < preguntas.length) { + if (indicePregunta+1 < preguntas.length) { setIndicePregunta(indicePregunta + 1); setPreguntaActual(preguntas[indicePregunta + 1]); } else { setJuegoTerminado(true); if (preguntasCorrectas + preguntasFalladas > 0) { - setTiempoMedio(tiempoTotal / (preguntasCorrectas + preguntasFalladas)); + const preguntasTotales=preguntasCorrectas+preguntasFalladas; + console.log(preguntasCorrectas); + console.log(preguntasFalladas); + const tMedio=tiempoTotal/preguntasTotales; + setTiempoMedio(tMedio); + } - guardarPartida(); } + }; + useEffect(() => { + if (juegoTerminado) { + guardarPartida(); + } + }, [juegoTerminado]); + const guardarPartida = async () => { - //Now we store the game in the stats DB const username = localStorage.getItem("username"); const newGame = { @@ -215,17 +228,17 @@ const JuegoPreguntas = () => {
-
Tiempo restante: {tiempoRestante}
-
- Tiempo restante: {Math.floor(tiempoRestante)} -
+
Tiempo restante: {parseFloat(tiempoRestante).toFixed(2).toString()}
Puntuación: {puntuacion}
{ + const gatewayUrl = process.env.GATEWAY_SERVICE_URL || "http://localhost:8000"; + + const [ranking, setRanking] = useState([]); + const [filterBy, setFilterBy] = useState("avgPoints"); + const [displayOptions] = useState([ + { value: "avgPoints", label: "Puntos promedio" }, + { value: "totalPoints", label: "Puntos totales" }, + { value: "ratioCorrect", label: "Ratio de aciertos" }, + { value: "avgTime", label: "Tiempo por pregunta (s)" }, + { value: "avgPoints", label: "Reestablecer por defecto" } + ]); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(null); + const [gamemode, setGamemode] = useState("clasico"); + + const fetchRanking = () => { + setIsLoading(true); + fetch(gatewayUrl + `/ranking?gamemode=${gamemode}&filterBy=${filterBy}`) + .then((response) => response.json()) + .then((data) => { + setRanking(data); + setIsLoading(false); + }) + .catch((error) => { + console.error('Error al obtener el ranking:', error); + setError(error.message || 'Ha ocurrido un error al obtener el ranking'); + setIsLoading(false); + }); + }; + + const getModeName = () => { + if(gamemode=="clasico"){ + return "Clásico"; + }else if(gamemode=="bateria"){ + return "Batería de sabios"; + } + return gamemode; + }; + + useEffect(() => { + fetchRanking(); + }, [gamemode, filterBy]); + + const handleDisplayChange = (event) => { + setFilterBy(event.target.value); + }; + + const getDisplayedField = () => { + switch (filterBy) { + case "avgPoints": + return "Puntos promedio"; + case "totalPoints": + return "Puntos totales"; + case "ratioCorrect": + return "Ratio de aciertos (%)"; + case "avgTime": + return "Tiempo por pregunta (s)"; + default: + return ""; + } + }; + + const getDisplayValue = (stat) => { + switch (filterBy) { + case "avgPoints": + return Math.round(stat.avgPoints * 100) / 100; + case "totalPoints": + return stat.totalPoints; + case "ratioCorrect": + return Math.round(stat.ratioCorrect * 100) / 100; + case "avgTime": + return Math.round(stat.avgTime * 100) / 100; + default: + return ""; + } + }; + + const handleGamemodeChange = (mode) => { + setGamemode(mode); + fetchRanking(); + }; + + if (isLoading) { + return ( +
+

Cargando ...

+

Se está consultando el ranking, espere unos instantes.

+
+ ); + } + + if (error) { + return ( +
+

Error: {error}

+

Ha ocurrido un error al obtener el ranking

+
+ ); + } + + return ( + <> +
)} - {ranking && ranking.length > 0 && ( -
-

Ranking - Modo {getModeName()}

- - - - - - - - - {ranking.map((stat, index) => ( - - - - - ))} - -
UsuarioPuntos promedio
{stat.username}{stat.avgPoints.toFixed(2)}
-
- )}