From 2e3b4122b739aa92288d072eb4c085d6d4340c1b Mon Sep 17 00:00:00 2001 From: uo289689 Date: Tue, 23 Apr 2024 13:42:15 +0200 Subject: [PATCH 01/24] Updated The Challange Game look and feel --- webapp/src/pages/TheChallengeGame.js | 213 ++++++++++++++------------- 1 file changed, 108 insertions(+), 105 deletions(-) diff --git a/webapp/src/pages/TheChallengeGame.js b/webapp/src/pages/TheChallengeGame.js index 9a5126e2..9e357e67 100644 --- a/webapp/src/pages/TheChallengeGame.js +++ b/webapp/src/pages/TheChallengeGame.js @@ -10,9 +10,9 @@ import { useContext } from 'react'; import Confetti from 'react-confetti'; import { CountdownCircleTimer } from "react-countdown-circle-timer"; import Card from '@mui/material/Card'; -import CardContent from '@mui/material/CardContent'; import { useTranslation } from 'react-i18next'; import i18n from '../localize/i18n'; +import { PlayArrow, Pause } from '@mui/icons-material'; const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; @@ -51,6 +51,8 @@ const Game = () => { const [questionCountdownRunning, setQuestionCountdownRunning] = React.useState(false); //property to start and stop question timer const [userResponses, setUserResponses] = React.useState([]); const [language, setCurrentLanguage] = React.useState(i18n.language); + const [paused, setPaused] = React.useState(false); + const [passNewRound, setPassNewRound] = React.useState(false); const [questionHistorial, setQuestionHistorial] = React.useState(Array(numRounds).fill(null)); @@ -89,16 +91,25 @@ const Game = () => { setShowConfetti(false); } }, [correctlyAnsweredQuestions, incorrectlyAnsweredQuestions]); + + React.useEffect(() => { + if (passNewRound && !paused) { + setRound(prevRound => { + return prevRound + 1; + }); + setButtonStates([]); + } + }, [paused, passNewRound]); const startGame = () => { setConfigModalOpen(false); startNewRound(); }; - - // gets a random question from the database and initializes button states to null + const startNewRound = async () => { setAnswered(false); + setPassNewRound(false); // It works deploying using git repo from machine with: axios.get(`http://20.80.235.188:8000/questions`) setCurrentLanguage(i18n.language); axios.get(`${apiEndpoint}/questions/${language}/${category}`) @@ -211,28 +222,11 @@ const Game = () => { setButtonStates(newButtonStates); setTimeout(async() => { - setRound(round + 1); - setButtonStates([]); + setPassNewRound(true); setCurrentLanguage(i18n.language); }, 4000); }; - const questionHistorialBar = () => { - return questionHistorial.map((isCorrect, index) => ( - - {index + 1} - - )); - }; - // Render the configuration window before starting the game if (configModalOpen) { @@ -287,6 +281,22 @@ const Game = () => { ); } + const questionHistorialBar = () => { + return questionHistorial.map((isCorrect, index) => ( + + + )); + }; + + const togglePause = () => { + setTimerRunning(!timerRunning); + setPaused(!paused); + } + // circular loading if (!questionData) { @@ -307,9 +317,9 @@ const Game = () => { ); } - // redirect to / if game over -if (shouldRedirect) { - // Redirect after 3 seconds + // redirect to / if game over + if (shouldRedirect) { + // Redirect after 4 seconds setTimeout(() => { navigate('/homepage'); }, 4000); @@ -317,109 +327,96 @@ if (shouldRedirect) { return ( - incorrectlyAnsweredQuestions ? 'green' : 'red', - fontSize: '4rem', // Tamaño de fuente - marginTop: '20px', // Espaciado superior - marginBottom: '50px', // Espaciado inferior - }} - > - {correctlyAnsweredQuestions > incorrectlyAnsweredQuestions ? "Great Job!" : "Game Over"} - -
- Correct Answers: {correctlyAnsweredQuestions} - Incorrect Answers: {incorrectlyAnsweredQuestions} - Total money: {totalScore} - Game time: {totalTimePlayed} seconds -
+ incorrectlyAnsweredQuestions ? theme.palette.success.main : theme.palette.error.main }}> + {correctlyAnsweredQuestions > incorrectlyAnsweredQuestions ? t("Game.win_msg") : t("Game.lose_msg") } + + + { t("Game.correct") }: {correctlyAnsweredQuestions} + { t("Game.incorrect") }: {incorrectlyAnsweredQuestions} + { t("Game.money") }: {totalScore} + { t("Game.time") }: {totalTimePlayed} + {showConfetti && }
); } - return ( - - - - - {questionHistorialBar()} - - - - - {round} / {numRounds} - - - {questionData.question} +return ( + + + + + { answered ? + // Pausa + + : + // Cronómetro selectResponse(0, "FAILED")} //when time ends always fail question - > - {({ remainingTime }) => { - return ( -
-
{remainingTime}
-
- ); - }} + data-testid="circleTimer" + key={questionCountdownKey} + isPlaying = {questionCountdownRunning} + duration={timerConfig} + colors={[theme.palette.success.main, "#F7B801", "#f50707", theme.palette.error.main]} + size={100} + colorsTime={[10, 6, 3, 0]} + onComplete={() => selectResponse(-1, "FAILED")} //when time ends always fail question + > + {({ remainingTime }) => { + return ( +
+
{remainingTime}
+
+ ); + }}
+ } +
+ + + + {questionData.question.toUpperCase()} {questionData.options.map((option, index) => ( {renderStatistics()} @@ -307,7 +307,7 @@ const Statistics = () => { variant="contained" sx={{ marginBottom: '0.5em', marginTop: '0.5em', backgroundColor: 'green', color: theme.palette.secondary.main, borderColor: theme.palette.primary.main, '&:hover': { backgroundColor: theme.palette.secondary.main, color: theme.palette.primary.main, borderColor: theme.palette.primary.main } }} > - {showQuestionsRecord ? 'Hide Questions Record' : 'Show Questions Record'} + {showQuestionsRecord ? t("Statistics.button.hide_record") : t("Statistics.button.show_record")} {renderQuestions()} From 78e0ac588a695a8fb0a300b6b5a52a7d0d65d5be Mon Sep 17 00:00:00 2001 From: uo289689 Date: Tue, 23 Apr 2024 17:26:18 +0200 Subject: [PATCH 03/24] Internacionalized view of homePage --- webapp/src/pages/Homepage.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/webapp/src/pages/Homepage.js b/webapp/src/pages/Homepage.js index ee5b0f6f..79915623 100644 --- a/webapp/src/pages/Homepage.js +++ b/webapp/src/pages/Homepage.js @@ -3,10 +3,12 @@ import { Button, Box, Grid, Typography } from '@mui/material'; import data from "../data/gameInfo.json"; import CardComponent from "../components/CardComponent.js"; import useMediaQuery from '@mui/material/useMediaQuery'; +import { useTranslation } from 'react-i18next'; const Homepage = () => { const xxl = useMediaQuery('(min-width:1920px)'); + const { t } = useTranslation(); const styles = React.useMemo(() => ({ cardButton:{ @@ -175,7 +177,7 @@ const Homepage = () => { GAME MODES {games} - + ); }; From 6050d482c7f6530c65386a733b64922a41b1a327 Mon Sep 17 00:00:00 2001 From: uo289689 Date: Tue, 23 Apr 2024 17:36:25 +0200 Subject: [PATCH 04/24] Internacionalized view of instrucctions --- webapp/src/data/gameInfo.json | 10 +++++----- webapp/src/localize/en.json | 5 ----- webapp/src/localize/es.json | 14 +++++--------- webapp/src/localize/fr.json | 14 +++++--------- webapp/src/pages/Homepage.js | 12 ++++++------ webapp/src/pages/Instructions.js | 5 ++++- webapp/src/pages/Statistics.js | 4 ++-- 7 files changed, 27 insertions(+), 37 deletions(-) diff --git a/webapp/src/data/gameInfo.json b/webapp/src/data/gameInfo.json index 27a8397e..89053297 100644 --- a/webapp/src/data/gameInfo.json +++ b/webapp/src/data/gameInfo.json @@ -1,6 +1,6 @@ [ { - "nombre": "WISE MEN STACK", + "nombre": "Wise Men Stack", "descripcion": "The player chooses a topic from five available options and must answer a battery of questions related to it within 60 seconds. For each question, the host provides two options. If the contestant guesses correctly, they move on to the next question.", "foto": "../instructions/foto0.png", @@ -8,21 +8,21 @@ "cardFoto": "../homePage/foto0.png" }, { - "nombre": "WARM QUESTION", + "nombre": "Warm Question", "descripcion": "It consists of ten topics of varied themes. For each correct answer, €100 is earned, and €10 are lost if the contestant passes, does not respond, or answers incorrectly.", "foto": "../instructions/foto1.jpg", "card":"It consists of ten topics of varied themes.", "cardFoto": "../homePage/foto1.jpg" }, { - "nombre": "DISCOVERING CITIES", + "nombre": "Discovering Cities", "descripcion": "In the 'Discovering Cities' game mode, the contestant will face a challenge where they will be repeatedly asked questions referring to different cities around the world. To successfully overcome the challenge, the contestant must answer as many questions as possible correctly throughout the test..", "foto": "../instructions/foto2.png", "card":"The contestant will face a challenge where they will be repeatedly asked questions referring to different cities around the world.", "cardFoto": "../homePage/foto2.png" }, { - "nombre": "THE CHALLENGE", + "nombre": "Challenge", "descripcion": "The 'Challenge' game mode is the quintessential game mode, as it allows you to customize the match to your liking. This game mode is tailored for those who wish to practice certain game formats before engaging in our various other game modes.", "foto": "../instructions/foto3.jpg", "card":"The 'Challenge' game mode is the quintessential game mode, as it allows you to customize the match to your liking.", @@ -30,7 +30,7 @@ }, { - "nombre": "MULTIPLAYER MODE", + "nombre": "Multiplayer", "descripcion": "Create a room and share the room code with other players to play. It also has a room chat.", "foto": "../instructions/online-photo.jpg", "card":"Create a room and share the room code with other players to play. It also has a room chat.", diff --git a/webapp/src/localize/en.json b/webapp/src/localize/en.json index 9c3d8b1a..4d511c5c 100644 --- a/webapp/src/localize/en.json +++ b/webapp/src/localize/en.json @@ -44,12 +44,7 @@ "multiplayer": { "name": "Multiplayer", "desc": "Create a room for other player to join and play 1vs1" - }, - "online": { - "name": "Online Game", - "desc": "" } - }, "Game": { diff --git a/webapp/src/localize/es.json b/webapp/src/localize/es.json index 25171e73..5af8d516 100644 --- a/webapp/src/localize/es.json +++ b/webapp/src/localize/es.json @@ -26,28 +26,24 @@ "Games": { "wise_men": { - "name": "Hombres Sabiondos", + "name": "Wise Men Stack", "desc": "El jugador elige un tema entre cinco opciones disponibles y debe responder una batería de preguntas relacionadas con él en un plazo de 60 segundos. Para cada pregunta, el presentador proporciona dos opciones. Si el concursante acierta, gana €20; de lo contrario, pasa a la siguiente pregunta (ya que la respuesta correcta sería la otra opción). Si el tiempo se agota antes de que se formule por completo la pregunta y se proporcionen ambas posibles respuestas, el concursante aún puede responderla; sin embargo, si la afirmación no se ha completado (o las opciones no se proporcionaron), no pueden responder." }, "warm_quest": { - "name": "Pregunta Calentorra", + "name": "Warm Question", "desc": "Consta de diez temas de diferentes temáticas. Por cada respuesta correcta, se ganan €100, y se pierden €10 si el concursante pasa, no responde o responde incorrectamente." }, "discover": { - "name": "Descubriendo Ciudades", + "name": "Discovering Cities", "desc": "En el modo de juego 'Descubriendo Ciudades', el concursante enfrentará un desafío donde se le harán preguntas repetidas referentes a diferentes ciudades de todo el mundo. Para superar con éxito el desafío, el concursante debe responder tantas preguntas como sea posible correctamente a lo largo de la prueba." }, "challenge": { - "name": "Desafío", + "name": "Challenge", "desc": "El modo de juego 'Desafío' es el modo de juego por excelencia, ya que te permite personalizar el enfrentamiento a tu gusto. Este modo de juego está diseñado para aquellos que deseen practicar ciertos formatos de juego antes de participar en nuestros diversos otros modos de juego." }, "multiplayer": { - "name": "Multijugador", + "name": "Multiplayer", "desc": "Crea una sala para que otros jugadores se unan y jueguen 1 contra 1." - }, - "online": { - "name": "Partida en línea", - "desc": "" } }, diff --git a/webapp/src/localize/fr.json b/webapp/src/localize/fr.json index e940adb8..2b75edcf 100644 --- a/webapp/src/localize/fr.json +++ b/webapp/src/localize/fr.json @@ -26,28 +26,24 @@ "Games": { "wise_men": { - "name": "Pile de Sages", + "name": "Wise Men Stack", "desc": "Le joueur choisit un sujet parmi cinq options disponibles et doit répondre à une batterie de questions qui y sont liées dans un délai de 60 secondes. Pour chaque question, l'hôte fournit deux options. Si le participant devine correctement, il gagne 20 € ; sinon, il passe à la question suivante (car la bonne réponse serait l'autre option). Si le temps s'écoule avant que la question ne soit entièrement posée et que les deux réponses possibles soient fournies, le participant peut toujours y répondre ; cependant, si l'énoncé n'a pas été complété (ou si les options n'ont pas été fournies), il ne peut pas répondre." }, "warm_quest": { - "name": "Question Chaleureuse", + "name": "Warm Question", "desc": "Il se compose de dix sujets de thèmes variés. Pour chaque réponse correcte, 100 € sont gagnés, et 10 € sont perdus si le participant passe, ne répond pas ou répond incorrectement." }, "discover": { - "name": "Découverte des Villes", + "name": "Discovering Cities", "desc": "Dans le mode de jeu 'Découverte des Villes', le participant sera confronté à un défi où il lui sera posé à plusieurs reprises des questions se référant à différentes villes du monde entier. Pour surmonter avec succès le défi, le participant doit répondre correctement à autant de questions que possible tout au long du test." }, "challenge": { - "name": "Défi", + "name": "Challenge", "desc": "Le mode de jeu 'Défi' est le mode de jeu par excellence, car il vous permet de personnaliser le match à votre guise. Ce mode de jeu est adapté à ceux qui souhaitent s'entraîner à certains formats de jeu avant de s'engager dans nos divers autres modes de jeu." }, "multiplayer": { - "name": "Multijoueur", + "name": "Multiplayer", "desc": "Créez une salle pour que d'autres joueurs se joignent et jouent en 1 contre 1." - }, - "online": { - "name": "Jeu en ligne", - "desc": "" } }, diff --git a/webapp/src/pages/Homepage.js b/webapp/src/pages/Homepage.js index 79915623..6df790e9 100644 --- a/webapp/src/pages/Homepage.js +++ b/webapp/src/pages/Homepage.js @@ -108,19 +108,19 @@ const Homepage = () => { //if online mode -> change link to go to online room const changeGameLink = React.useCallback((index) => { switch (info[index].nombre) { - case "WISE MEN STACK": + case "Wise Men Stack": setGameLink("/wiseMenStackGame"); break; - case "WARM QUESTION": + case "Warm Question": setGameLink("/warmQuestionGame"); break; - case "DISCOVERING CITIES": + case "Discovering Cities": setGameLink("/discoveringCitiesGame"); break; - case "THE CHALLENGE": + case "Challenge": setGameLink("/theChallengeGame"); break; - case "MULTIPLAYER MODE": + case "Multiplayer": setGameLink("/multiplayerRoom"); break; default: @@ -177,7 +177,7 @@ const Homepage = () => { GAME MODES {games} - + ); }; diff --git a/webapp/src/pages/Instructions.js b/webapp/src/pages/Instructions.js index 7143217e..e416610f 100644 --- a/webapp/src/pages/Instructions.js +++ b/webapp/src/pages/Instructions.js @@ -1,10 +1,12 @@ import * as React from "react"; import { Button, Typography, Grid, Box , CssBaseline, useMediaQuery } from "@mui/material"; import data from "../data/gameInfo.json"; +import { useTranslation } from 'react-i18next'; const Instructions = () => { const lg = useMediaQuery('(min-width: 1200px)'); + const { t } = useTranslation(); const styles = { @@ -143,7 +145,8 @@ const Instructions = () => { Foto del minijuego {info[index].nombre} - {info[index].descripcion} + {t("Games." + + info[index].nombre +".desc")} ); diff --git a/webapp/src/pages/Statistics.js b/webapp/src/pages/Statistics.js index 3fa49f9c..adac2491 100644 --- a/webapp/src/pages/Statistics.js +++ b/webapp/src/pages/Statistics.js @@ -228,7 +228,7 @@ const Statistics = () => { {currentItems.map((record, index) => (
- t("Statistics.game") {formatCreatedAt(record.createdAt)} + {t("Statistics.game")} {formatCreatedAt(record.createdAt)} @@ -298,7 +298,7 @@ const Statistics = () => { { t("Games.discover.name") }
{renderStatistics()} From ba2e452516806dd8a5e414dee5d791f3f42374aa Mon Sep 17 00:00:00 2001 From: uo289689 Date: Tue, 23 Apr 2024 17:38:07 +0200 Subject: [PATCH 05/24] Internacionalized view of home --- webapp/src/pages/Home.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/webapp/src/pages/Home.js b/webapp/src/pages/Home.js index 381a6c74..fcfa9336 100644 --- a/webapp/src/pages/Home.js +++ b/webapp/src/pages/Home.js @@ -1,10 +1,11 @@ import * as React from "react"; import {Box, Button} from "@mui/material"; import useMediaQuery from '@mui/material/useMediaQuery'; - +import { useTranslation } from 'react-i18next'; const Home = () => { const xxl = useMediaQuery('(min-width:1920px)'); + const { t } = useTranslation(); const styles = { logo:{ @@ -96,7 +97,7 @@ const Home = () => { Logo - +