From dff741e527e94afe919f6f21312a78bbf57f503b Mon Sep 17 00:00:00 2001 From: CANCI0 Date: Fri, 5 Apr 2024 21:01:10 +0200 Subject: [PATCH 01/11] =?UTF-8?q?Creada=20estructura=20para=20la=20interna?= =?UTF-8?q?cionalizaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/package-lock.json | 91 ++++++++++++++++++++++++++ webapp/package.json | 2 + webapp/src/components/Footer/Footer.js | 5 +- webapp/src/i18n.js | 25 +++++++ webapp/src/index.js | 1 + webapp/src/locales/en.json | 16 +++++ webapp/src/locales/es.json | 16 +++++ webapp/src/pages/Config/Config.js | 16 ++++- 8 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 webapp/src/i18n.js create mode 100644 webapp/src/locales/en.json create mode 100644 webapp/src/locales/es.json diff --git a/webapp/package-lock.json b/webapp/package-lock.json index f93cbfe5..b9fe9ee3 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -19,8 +19,10 @@ "@tsparticles/slim": "^3.3.0", "axios": "^1.6.5", "framer-motion": "^11.0.19", + "i18next": "^23.10.1", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-i18next": "^14.1.0", "react-router-dom": "^6.22.0", "react-scripts": "^5.0.1", "web-vitals": "^3.5.1" @@ -11337,6 +11339,14 @@ "node": ">= 12" } }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "dependencies": { + "void-elements": "3.1.0" + } + }, "node_modules/html-webpack-plugin": { "version": "5.6.0", "license": "MIT", @@ -11471,6 +11481,28 @@ "node": ">=10.17.0" } }, + "node_modules/i18next": { + "version": "23.10.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.10.1.tgz", + "integrity": "sha512-NDiIzFbcs3O9PXpfhkjyf7WdqFn5Vq6mhzhtkXzj51aOcNuPNcTwuYNuXCpHsanZGHlHKL35G7huoFeVic1hng==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "dependencies": { + "@babel/runtime": "^7.23.2" + } + }, "node_modules/iconv-lite": { "version": "0.6.3", "license": "MIT", @@ -18568,6 +18600,27 @@ } } }, + "node_modules/react-i18next": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.0.tgz", + "integrity": "sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==", + "dependencies": { + "@babel/runtime": "^7.23.9", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 23.2.3", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/react-is": { "version": "17.0.2", "license": "MIT" @@ -23216,6 +23269,14 @@ "node": ">= 0.8" } }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/w3c-hr-time": { "version": "1.0.2", "license": "MIT", @@ -31280,6 +31341,14 @@ } } }, + "html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "requires": { + "void-elements": "3.1.0" + } + }, "html-webpack-plugin": { "version": "5.6.0", "requires": { @@ -31352,6 +31421,14 @@ "human-signals": { "version": "2.1.0" }, + "i18next": { + "version": "23.10.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.10.1.tgz", + "integrity": "sha512-NDiIzFbcs3O9PXpfhkjyf7WdqFn5Vq6mhzhtkXzj51aOcNuPNcTwuYNuXCpHsanZGHlHKL35G7huoFeVic1hng==", + "requires": { + "@babel/runtime": "^7.23.2" + } + }, "iconv-lite": { "version": "0.6.3", "requires": { @@ -35760,6 +35837,15 @@ "use-sidecar": "^1.1.2" } }, + "react-i18next": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.0.tgz", + "integrity": "sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==", + "requires": { + "@babel/runtime": "^7.23.9", + "html-parse-stringify": "^3.0.1" + } + }, "react-is": { "version": "17.0.2" }, @@ -38783,6 +38869,11 @@ "vary": { "version": "1.1.2" }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==" + }, "w3c-hr-time": { "version": "1.0.2", "requires": { diff --git a/webapp/package.json b/webapp/package.json index eba63178..cd317f9c 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -14,8 +14,10 @@ "@tsparticles/slim": "^3.3.0", "axios": "^1.6.5", "framer-motion": "^11.0.19", + "i18next": "^23.10.1", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-i18next": "^14.1.0", "react-router-dom": "^6.22.0", "react-scripts": "^5.0.1", "web-vitals": "^3.5.1" diff --git a/webapp/src/components/Footer/Footer.js b/webapp/src/components/Footer/Footer.js index 5124286a..8aeab19e 100644 --- a/webapp/src/components/Footer/Footer.js +++ b/webapp/src/components/Footer/Footer.js @@ -1,7 +1,10 @@ import React from 'react'; import { Box, Heading, Text, useColorMode } from '@chakra-ui/react'; +import { useTranslation } from "react-i18next"; const Footer = () => { + const { t } = useTranslation(); + const { colorMode } = useColorMode(); const bgColor = { light: 'gray.200', dark: 'gray.700' }; const textColor = { light: 'black', dark: 'white' }; @@ -9,7 +12,7 @@ const Footer = () => { return( WIQ! - Copyright 2024 ® Grupo 1A de Arquitectura del Software + {t('components.footer.copyright')} ); } diff --git a/webapp/src/i18n.js b/webapp/src/i18n.js new file mode 100644 index 00000000..b084dda8 --- /dev/null +++ b/webapp/src/i18n.js @@ -0,0 +1,25 @@ +import i18n from 'i18next'; +import { initReactI18next } from 'react-i18next'; + +import translationEN from './locales/en.json'; +import translationES from './locales/es.json'; + +i18n + .use(initReactI18next) + .init({ + resources: { + en: { + translation: translationEN + }, + es: { + translation: translationES + } + }, + lng: 'es', + fallbackLng: 'en', + interpolation: { + escapeValue: false + } + }); + +export default i18n; diff --git a/webapp/src/index.js b/webapp/src/index.js index ab8af0e0..a2e9e08e 100644 --- a/webapp/src/index.js +++ b/webapp/src/index.js @@ -5,6 +5,7 @@ import reportWebVitals from "./reportWebVitals"; import { ChakraProvider } from "@chakra-ui/react"; import './themes.js'; import './index.css'; +import i18n from './i18n'; var r = document.getElementById("root"); const root = ReactDOM.createRoot(r); diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json new file mode 100644 index 00000000..88e6a358 --- /dev/null +++ b/webapp/src/locales/en.json @@ -0,0 +1,16 @@ +{ + "components": { + "footer":{ + "copyright": "Copyright 2024 ® Grupo 1A de Arquitectura del Software" + }, + "login":{ + + }, + "nav":{ + + }, + "register":{ + + } + } +} \ No newline at end of file diff --git a/webapp/src/locales/es.json b/webapp/src/locales/es.json new file mode 100644 index 00000000..88e6a358 --- /dev/null +++ b/webapp/src/locales/es.json @@ -0,0 +1,16 @@ +{ + "components": { + "footer":{ + "copyright": "Copyright 2024 ® Grupo 1A de Arquitectura del Software" + }, + "login":{ + + }, + "nav":{ + + }, + "register":{ + + } + } +} \ No newline at end of file diff --git a/webapp/src/pages/Config/Config.js b/webapp/src/pages/Config/Config.js index 2f75ad19..55168857 100644 --- a/webapp/src/pages/Config/Config.js +++ b/webapp/src/pages/Config/Config.js @@ -12,15 +12,20 @@ import { NumberInputStepper, NumberIncrementStepper, NumberDecrementStepper, + Select, } from "@chakra-ui/react"; import Nav from "../../components/Nav/Nav.js"; import Footer from "../../components/Footer/Footer.js"; import { useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; const Config = () => { + const { i18n } = useTranslation(); + useEffect(() => { // Obtener el estado de los checkboxes desde el localStorage - const selectedThemes = JSON.parse(localStorage.getItem("selectedThemes")) || []; + const selectedThemes = + JSON.parse(localStorage.getItem("selectedThemes")) || []; const checkboxes = document.querySelectorAll('input[type="checkbox"]'); checkboxes.forEach((checkbox) => { @@ -86,6 +91,15 @@ const Config = () => { Configuración + Idioma + Temáticas de preguntas Date: Fri, 5 Apr 2024 21:21:50 +0200 Subject: [PATCH 02/11] Login register y Nav internacionalizados --- webapp/src/components/Login/Login.js | 18 +++++---- webapp/src/components/Nav/Nav.js | 27 +++++++------ webapp/src/components/Register/Register.js | 27 +++++++------ webapp/src/locales/en.json | 44 ++++++++++++++++++---- webapp/src/locales/es.json | 34 +++++++++++++++-- 5 files changed, 107 insertions(+), 43 deletions(-) diff --git a/webapp/src/components/Login/Login.js b/webapp/src/components/Login/Login.js index 0e2c2c91..de509c01 100644 --- a/webapp/src/components/Login/Login.js +++ b/webapp/src/components/Login/Login.js @@ -16,8 +16,10 @@ import { Flex } from "@chakra-ui/react"; import Footer from "../Footer/Footer"; +import { useTranslation } from "react-i18next"; const Login = () => { + const { t } = useTranslation(); const { colorMode, toggleColorMode } = useColorMode(); const isDarkTheme = colorMode === "dark"; @@ -77,28 +79,28 @@ const Login = () => { {!loginSuccess && ( <> - Identifícate + {t('components.login.title')} - Introduce tu nombre: + {t('components.login.nameLabel')} setUsername(e.target.value)} /> - Introduce tu contraseña: + {t('components.login.passwordLabel')} setPassword(e.target.value)} /> @@ -107,15 +109,15 @@ const Login = () => { Login - ¿No tienes cuenta?{" "} + {t('components.login.registerText')}{" "} - Regístrate + {t('components.login.registerLink')} {openSnackbar && ( - Login successful + {t('components.login.loginAlert')} )} {error && ( diff --git a/webapp/src/components/Nav/Nav.js b/webapp/src/components/Nav/Nav.js index b79c9bf9..127b5a65 100644 --- a/webapp/src/components/Nav/Nav.js +++ b/webapp/src/components/Nav/Nav.js @@ -1,8 +1,11 @@ import React from "react"; import { Box, Button, Heading, Switch, Popover, PopoverTrigger, PopoverContent, PopoverArrow, PopoverCloseButton, PopoverHeader, PopoverBody, Text, Flex, useColorMode } from "@chakra-ui/react"; import { useNavigate } from "react-router-dom"; +import { useTranslation } from "react-i18next"; const Nav = () => { + const { t } = useTranslation(); + const navigate = useNavigate(); const { colorMode, toggleColorMode } = useColorMode(); const isDarkTheme = colorMode === "dark"; @@ -28,32 +31,32 @@ const Nav = () => { WIQ - + - Modos de Juego + {t("components.nav.gameModes")} - handleNavigate("/home/clasico")} color={textColor}>Clásico - handleNavigate("/home/bateria")} color={textColor}>Batería de sabios - {/* Agrega más modos de juego aquí */} + handleNavigate("/home/clasico")} color={textColor}>{t('components.nav.classic')} + handleNavigate("/home/bateria")} color={textColor}>{t('components.nav.wisebattery')} + handleNavigate("/home/calculadora")} color={textColor}>{t('components.nav.humancalculator')} - - - + + + - - - + + + diff --git a/webapp/src/components/Register/Register.js b/webapp/src/components/Register/Register.js index 421efdf5..f5360322 100644 --- a/webapp/src/components/Register/Register.js +++ b/webapp/src/components/Register/Register.js @@ -16,11 +16,14 @@ import { } from "@chakra-ui/react"; import { useNavigate } from "react-router-dom"; import Footer from "../Footer/Footer"; +import { useTranslation } from "react-i18next"; const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || "http://localhost:8000"; const AddUser = () => { + const { t } = useTranslation(); + const { colorMode, toggleColorMode } = useColorMode(); const isDarkTheme = colorMode === "dark"; @@ -33,7 +36,7 @@ const AddUser = () => { const handleRegister = () => { if (password !== passwordR) { - setError("Las contraseñas no coinciden"); + setError(t('components.register.registerError')); return; } axios @@ -71,59 +74,59 @@ const AddUser = () => { boxShadow="lg" > - Regístrate + {t('components.register.title')} - Introduce tu nombre: + {t('components.register.nameLabel')} setUsername(e.target.value)} /> - Introduce tu contraseña: + {t('components.register.passwordLabel')} setPassword(e.target.value)} /> - Vuelve a introducir la contraseña: + {t('components.register.password2Placeholder')} setPasswordR(e.target.value)} /> - ¿Ya tienes cuenta?{" "} + {t('components.register.loginText')}{" "} - Inicia sesión + {t('components.register.loginLink')} {openSnackbar && ( - Usuario registrado exitosamente + {t('components.register.registerAlert')} )} {error && ( diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 88e6a358..c39e1c36 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -1,16 +1,44 @@ { "components": { - "footer":{ - "copyright": "Copyright 2024 ® Grupo 1A de Arquitectura del Software" + "footer": { + "copyright": "Copyright 2024 ® Group 1A of Software Architecture" }, - "login":{ - + "login": { + "title": "Log in", + "nameLabel": "Enter your name", + "namePlaceholder": "Name", + "passwordPlaceholder": "Password", + "passwordLabel": "Enter your password", + "loginButton": "Log in", + "registerText": "Don't have an account?", + "registerLink": "Register", + "loginAlert": "Login successful" }, - "nav":{ - + "nav": { + "home": "Home", + "gameModes": "Game Modes", + "classic": "Classic", + "wisebattery": "Wise Battery", + "humancalculator": "Human Calculator", + "stats": "Statistics", + "ranking": "Ranking", + "profile": "Profile", + "about": "About Us", + "options": "Options", + "disconnect": "Disconnect" }, - "register":{ - + "register": { + "title": "Register", + "nameLabel": "Enter your name", + "namePlaceholder": "Name", + "passwordPlaceholder": "Password", + "passwordLabel": "Enter your password", + "password2Label": "Re-enter the password", + "registerButton": "Register", + "loginText": "Already have an account?", + "loginLink": "Log in", + "registerAlert": "User registered successfully", + "registerError": "Passwords do not match" } } } \ No newline at end of file diff --git a/webapp/src/locales/es.json b/webapp/src/locales/es.json index 88e6a358..17979463 100644 --- a/webapp/src/locales/es.json +++ b/webapp/src/locales/es.json @@ -4,13 +4,41 @@ "copyright": "Copyright 2024 ® Grupo 1A de Arquitectura del Software" }, "login":{ - + "title": "Identifícate", + "nameLabel": "Introduce tu nombre", + "namePlaceholder": "Nombre", + "passwordPlaceholder": "Contraseña", + "passwordLabel": "Introduce tu contraseña", + "loginButton": "Iniciar sesión", + "registerText": "¿No tienes cuenta?", + "registerLink": "Regístrate", + "loginAlert": "Inicio de sesión exitoso" }, "nav":{ - + "home": "Inicio", + "gameModes": "Modos de juego", + "classic": "Clásico", + "wisebattery": "Batería de sabios", + "humancalculator": "Calculadora humana", + "stats": "Estadísticas", + "ranking": "Ranking", + "profile": "Perfil", + "about": "Sobre nosotros", + "options": "Opciones", + "desconnect": "Desconectar" }, "register":{ - + "title": "Regístrate", + "nameLabel": "Introduce tu nombre", + "namePlaceholder": "Nombre", + "passwordPlaceholder": "Contraseña", + "passwordLabel": "Introduce tu contraseña", + "password2Label": "Vuelve a introducir la contraseña", + "registerButton": "Registrarse", + "loginText": "¿Ya tienes cuenta?", + "loginLink": "Inicia sesión", + "registerAlert": "Usuario registrado exitosamente", + "registerError": "Las contraseñas no coinciden" } } } \ No newline at end of file From 9f2caf96dbc3ad60a83388800a61599425561725 Mon Sep 17 00:00:00 2001 From: CANCI0 Date: Fri, 5 Apr 2024 21:34:06 +0200 Subject: [PATCH 03/11] =?UTF-8?q?Bater=C3=ADa=20y=20calculadora=20internac?= =?UTF-8?q?ionalizados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/components/Nav/Nav.js | 2 +- webapp/src/locales/es.json | 20 +++++++++++++++++++- webapp/src/pages/Bateria/Bateria.js | 17 ++++++++++------- webapp/src/pages/Calculadora/Calculadora.js | 13 ++++++++----- webapp/src/pages/Config/Config.js | 12 ++++-------- 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/webapp/src/components/Nav/Nav.js b/webapp/src/components/Nav/Nav.js index 127b5a65..b24503d2 100644 --- a/webapp/src/components/Nav/Nav.js +++ b/webapp/src/components/Nav/Nav.js @@ -56,7 +56,7 @@ const Nav = () => { - + diff --git a/webapp/src/locales/es.json b/webapp/src/locales/es.json index 17979463..633218c8 100644 --- a/webapp/src/locales/es.json +++ b/webapp/src/locales/es.json @@ -25,7 +25,7 @@ "profile": "Perfil", "about": "Sobre nosotros", "options": "Opciones", - "desconnect": "Desconectar" + "disconnect": "Desconectar" }, "register":{ "title": "Regístrate", @@ -40,5 +40,23 @@ "registerAlert": "Usuario registrado exitosamente", "registerError": "Las contraseñas no coinciden" } + }, + "pages": { + "wisebattery": { + "finished": "¡Juego terminado!", + "score": "Tu puntuación:", + "playAgain": "Jugar de nuevo", + "back": "Volver al menú", + "question": "Pregunta", + "time": "Tiempo restante:" + }, + "humancalculator": { + "finished": "¡Juego terminado!", + "score": "Tu puntuación:", + "playAgain": "Jugar de nuevo", + "back": "Volver al menú", + "question": "Pregunta", + "time": "Tiempo restante:" + } } } \ No newline at end of file diff --git a/webapp/src/pages/Bateria/Bateria.js b/webapp/src/pages/Bateria/Bateria.js index aa952d7f..d8af429b 100644 --- a/webapp/src/pages/Bateria/Bateria.js +++ b/webapp/src/pages/Bateria/Bateria.js @@ -4,11 +4,14 @@ import Footer from "../../components/Footer/Footer.js"; import { Link, useNavigate } from "react-router-dom"; import { Box, Flex, Heading, Button, Grid, Spinner } from "@chakra-ui/react"; import axios from 'axios'; +import { useTranslation } from "react-i18next"; const JuegoPreguntas = () => { const URL = process.env.REACT_APP_API_ENDPOINT || "http://localhost:8000" const TIME = localStorage.getItem("bateriaTime"); + const { t } = useTranslation(); + const [isLoading, setIsLoading] = useState(true); const [indicePregunta, setIndicePregunta] = useState(0); const [puntuacion, setPuntuacion] = useState(0); @@ -164,21 +167,21 @@ const JuegoPreguntas = () => { {juegoTerminado ? ( - ¡Juego terminado! + {t('pages.wisebattery.finished')}

- Tu puntuación: {puntuacion} + {t('pages.wisebattery.score')} {puntuacion}

- Volver al Menú Principal + {t('pages.wisebattery.back')}
) : ( - Pregunta {indicePregunta + 1} + {t('pages.wisebattery.question')} {indicePregunta + 1}

{preguntaActual.pregunta}

@@ -194,8 +197,8 @@ const JuegoPreguntas = () => { -

Tiempo restante: {Math.floor(tiempoRestante)}

-

Puntuación: {puntuacion}

+

{t('pages.wisebattery.time')} {Math.floor(tiempoRestante)}

+

{t('pages.wisebattery.score')} {puntuacion}

{ let operators = ["+", "-", "*", "/"]; @@ -39,6 +40,8 @@ const CalculadoraHumana = () => { const TIME = 60; const URL = process.env.REACT_APP_API_ENDPOINT || "http://localhost:8000"; + const { t } = useTranslation(); + const [valSubmit, setValSubmit] = useState(""); const [puntuacion, setPuntuacion] = useState(0); const [operation, setOperation] = useState(generateRandomOperation()); @@ -168,13 +171,13 @@ const CalculadoraHumana = () => { {juegoTerminado ? ( - ¡Juego terminado! + {t('pages.humancalculator.finished')}

Tu puntuación: {puntuacion}

- Volver al Menú Principal + {t('pages.humancalculator.again')}
) : ( @@ -194,8 +197,8 @@ const CalculadoraHumana = () => { Enviar{" "} -

Tiempo restante: {Math.floor(tiempoRestante)}

-

Puntuación: {puntuacion}

+

{t('pages.humancalculator.time')} {Math.floor(tiempoRestante)}

+

{t('pages.humancalculator.score')} {puntuacion}

{ Configuración Idioma - + + + + Temáticas de preguntas Date: Fri, 5 Apr 2024 21:48:09 +0200 Subject: [PATCH 04/11] =?UTF-8?q?Cl=C3=A1sico,=20config=20y=20Home=20inter?= =?UTF-8?q?nacionalizados?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/src/locales/es.json | 153 +++++++++++++++++----------- webapp/src/pages/Clasico/Clasico.js | 19 ++-- webapp/src/pages/Config/Config.js | 25 +++-- webapp/src/pages/Home/Home.js | 30 +++--- 4 files changed, 129 insertions(+), 98 deletions(-) diff --git a/webapp/src/locales/es.json b/webapp/src/locales/es.json index 633218c8..d8d61f6f 100644 --- a/webapp/src/locales/es.json +++ b/webapp/src/locales/es.json @@ -1,62 +1,97 @@ { - "components": { - "footer":{ - "copyright": "Copyright 2024 ® Grupo 1A de Arquitectura del Software" - }, - "login":{ - "title": "Identifícate", - "nameLabel": "Introduce tu nombre", - "namePlaceholder": "Nombre", - "passwordPlaceholder": "Contraseña", - "passwordLabel": "Introduce tu contraseña", - "loginButton": "Iniciar sesión", - "registerText": "¿No tienes cuenta?", - "registerLink": "Regístrate", - "loginAlert": "Inicio de sesión exitoso" - }, - "nav":{ - "home": "Inicio", - "gameModes": "Modos de juego", - "classic": "Clásico", - "wisebattery": "Batería de sabios", - "humancalculator": "Calculadora humana", - "stats": "Estadísticas", - "ranking": "Ranking", - "profile": "Perfil", - "about": "Sobre nosotros", - "options": "Opciones", - "disconnect": "Desconectar" - }, - "register":{ - "title": "Regístrate", - "nameLabel": "Introduce tu nombre", - "namePlaceholder": "Nombre", - "passwordPlaceholder": "Contraseña", - "passwordLabel": "Introduce tu contraseña", - "password2Label": "Vuelve a introducir la contraseña", - "registerButton": "Registrarse", - "loginText": "¿Ya tienes cuenta?", - "loginLink": "Inicia sesión", - "registerAlert": "Usuario registrado exitosamente", - "registerError": "Las contraseñas no coinciden" - } + "components": { + "footer": { + "copyright": "Copyright 2024 ® Grupo 1A de Arquitectura del Software" }, - "pages": { - "wisebattery": { - "finished": "¡Juego terminado!", - "score": "Tu puntuación:", - "playAgain": "Jugar de nuevo", - "back": "Volver al menú", - "question": "Pregunta", - "time": "Tiempo restante:" - }, - "humancalculator": { - "finished": "¡Juego terminado!", - "score": "Tu puntuación:", - "playAgain": "Jugar de nuevo", - "back": "Volver al menú", - "question": "Pregunta", - "time": "Tiempo restante:" - } + "login": { + "title": "Identifícate", + "nameLabel": "Introduce tu nombre", + "namePlaceholder": "Nombre", + "passwordPlaceholder": "Contraseña", + "passwordLabel": "Introduce tu contraseña", + "loginButton": "Iniciar sesión", + "registerText": "¿No tienes cuenta?", + "registerLink": "Regístrate", + "loginAlert": "Inicio de sesión exitoso" + }, + "nav": { + "home": "Inicio", + "gameModes": "Modos de juego", + "classic": "Clásico", + "wisebattery": "Batería de sabios", + "humancalculator": "Calculadora humana", + "stats": "Estadísticas", + "ranking": "Ranking", + "profile": "Perfil", + "about": "Sobre nosotros", + "options": "Opciones", + "disconnect": "Desconectar" + }, + "register": { + "title": "Regístrate", + "nameLabel": "Introduce tu nombre", + "namePlaceholder": "Nombre", + "passwordPlaceholder": "Contraseña", + "passwordLabel": "Introduce tu contraseña", + "password2Label": "Vuelve a introducir la contraseña", + "registerButton": "Registrarse", + "loginText": "¿Ya tienes cuenta?", + "loginLink": "Inicia sesión", + "registerAlert": "Usuario registrado exitosamente", + "registerError": "Las contraseñas no coinciden" + } + }, + "pages": { + "classic": { + "finished": "¡Juego terminado!", + "score": "Tu puntuación:", + "playAgain": "Jugar de nuevo", + "back": "Volver al menú", + "question": "Pregunta", + "time": "Tiempo restante:", + "easterEgg": "¡Has acertado todas! Eres la cuenta secundaria de Jordi Hurtado.", + "answer": "Responder" + }, + "wisebattery": { + "finished": "¡Juego terminado!", + "score": "Tu puntuación:", + "playAgain": "Jugar de nuevo", + "back": "Volver al menú", + "question": "Pregunta", + "time": "Tiempo restante:" + }, + "humancalculator": { + "finished": "¡Juego terminado!", + "score": "Tu puntuación:", + "playAgain": "Jugar de nuevo", + "back": "Volver al menú", + "question": "Pregunta", + "time": "Tiempo restante:" + }, + "config": { + "title": "Configuración", + "language": "Idioma", + "topics": "Temáticas de preguntas", + "countries": "Países", + "literature": "Literatura", + "cinema": "Cine", + "art": "Arte", + "programming": "Programación", + "save": "Aplicar cambios", + "timeBetweenClassic": "Tiempo entre preguntas (Clásico)", + "questionCountClassic": "Número de preguntas (Clásico)", + "totalTimeBattery": "Tiempo total (Batería de sabios)" + }, + "home": { + "title": "¡Bienvenido a WIQ!", + "choose": "Elige el modo de juego", + "classic": "Modo clásico", + "classicDescription": "En el modo Clásico, tendrás que responder un número determinado de preguntas en un tiempo limitado. ¡Demuestra tus conocimientos y rapidez para superar este desafío!", + "wisebattery": "Batería de sabios", + "wisebatteryDescription": "En el modo Batería de Sabios, pondrás a prueba tu conocimiento respondiendo todas las preguntas que puedas en un tiempo fijo. Cuantas más preguntas aciertes, ¡mejor será tu puntuación! ¿Estás listo para este desafío cronometrado?", + "humancalculator": "Calculadora humana", + "humancalculatorDescription": "En el modo Calculadora Humana, tendrás que resolver operaciones matemáticas en un tiempo limitado. ¡Demuestra tus habilidades matemáticas y rapidez para superar este desafío!", + "error": "Hubo un error al cargar las preguntas. Por favor, inténtalo más tarde." } -} \ No newline at end of file + } +} diff --git a/webapp/src/pages/Clasico/Clasico.js b/webapp/src/pages/Clasico/Clasico.js index 8f371aca..918c8ca4 100644 --- a/webapp/src/pages/Clasico/Clasico.js +++ b/webapp/src/pages/Clasico/Clasico.js @@ -4,6 +4,7 @@ import { Link, useNavigate } from "react-router-dom"; import Footer from "../../components/Footer/Footer.js"; import { Box, Flex, Heading, Button, Grid, useColorMode, Text, Image, Spinner } from "@chakra-ui/react"; import axios from "axios"; +import { useTranslation } from "react-i18next"; const JuegoPreguntas = () => { const URL = process.env.REACT_APP_API_ENDPOINT || "http://localhost:8000"; @@ -11,6 +12,8 @@ const JuegoPreguntas = () => { const { colorMode } = useColorMode(); const isDarkTheme = colorMode === "dark"; + const { t } = useTranslation(); + const [isLoading, setIsLoading] = useState(true); const [indicePregunta, setIndicePregunta] = useState(0); const [puntuacion, setPuntuacion] = useState(0); @@ -220,27 +223,27 @@ const JuegoPreguntas = () => { {mostrarMenu ? ( - ¡Juego terminado! + {t('pages.classic.finished')}

- Tu puntuación: {puntuacion}/{preguntas.length} + {t('pages.classic.score')} {puntuacion}/{preguntas.length}

{preguntasFalladas === 0 ? ( Jordi Hurtado - ¡Has acertado todas! Eres la cuenta secundaria de Jordi Hurtado. + {t('pages.classic.easterEgg')} ) : null} - Volver al Menú Principal + {t('pages.classic.back')}
) : ( - Pregunta {indicePregunta + 1} + {t('pages.classic.question')} {indicePregunta + 1}

{preguntaActual.pregunta}

@@ -266,11 +269,11 @@ const JuegoPreguntas = () => { colorScheme="teal" m={2} > - Responder + {t('pages.classic.answer')} -

Tiempo restante: {Math.floor(tiempoRestante)}

+

{t('pages.classic.time')} {Math.floor(tiempoRestante)}

Puntuación: {puntuacion}

diff --git a/webapp/src/pages/Config/Config.js b/webapp/src/pages/Config/Config.js index eb0788a7..cf365016 100644 --- a/webapp/src/pages/Config/Config.js +++ b/webapp/src/pages/Config/Config.js @@ -12,7 +12,6 @@ import { NumberInputStepper, NumberIncrementStepper, NumberDecrementStepper, - Select, } from "@chakra-ui/react"; import Nav from "../../components/Nav/Nav.js"; import Footer from "../../components/Footer/Footer.js"; @@ -89,14 +88,14 @@ const Config = () => { - Configuración + {i18n('pages.config.title')} - Idioma + {i18n('pages.config.language')} - Temáticas de preguntas + {i18n('pages.config.topics')} { > - Países + {i18n('pages.config.countries')} - Literatura + {i18n('pages.config.literature')} - Cine + {i18n('pages.config.cinema')} - Arte + {i18n('pages.config.art')} - Programación + {i18n('pages.config.programming')} @@ -125,7 +124,7 @@ const Config = () => { {" "} - Tiempo entre preguntas (Clásico) + {i18n('pages.config.timeBetweenClassic')} { {" "} - Número de preguntas (Clásico) + {i18n('pages.config.questionCountClassic')} { - Tiempo total (Batería de sabios) + {i18n('pages.config.totalTimeBattery')} { diff --git a/webapp/src/pages/Home/Home.js b/webapp/src/pages/Home/Home.js index aa17b5f9..b1721941 100644 --- a/webapp/src/pages/Home/Home.js +++ b/webapp/src/pages/Home/Home.js @@ -5,10 +5,13 @@ import CustomModal from "../../components/CustomModal/CustomModal.js"; import { Box, Heading, Flex } from "@chakra-ui/react"; import { useLocation } from "react-router-dom"; import Background from "../../components/Background/Background.js"; +import { useTranslation } from "react-i18next"; const Home = () => { const testEnvironment = process.env.NODE_ENV === "test"; + const { t } = useTranslation(); + const location = useLocation(); const queryParams = new URLSearchParams(location.search); const error = queryParams.get("error"); @@ -19,44 +22,35 @@ const Home = () => { {!testEnvironment && } - ¡Bienvenido a WIQ! + {t('pages.home.title')} - Elige el modo de juego + {t('pages.home.choose')} {error && ( - Hubo un error al cargar las preguntas. Por favor, inténtalo más tarde. + {t('pages.home.error')} )} From 050917e3cc8c79d62ab18eae8bbf955c0193e6bf Mon Sep 17 00:00:00 2001 From: CANCI0 Date: Fri, 5 Apr 2024 22:25:18 +0200 Subject: [PATCH 05/11] Todo internacionalizado --- .../src/components/Background/Background.js | 2 +- webapp/src/locales/en.json | 199 ++++++++++++++---- webapp/src/locales/es.json | 63 ++++++ webapp/src/pages/Config/Config.js | 26 +-- webapp/src/pages/Perfil/Perfil.js | 25 ++- webapp/src/pages/Ranking/Ranking.js | 42 ++-- webapp/src/pages/Sobre/Sobre.js | 15 +- webapp/src/pages/Stats/Stats.js | 42 ++-- webapp/src/pages/WrongRoute/WrongRoute.js | 10 +- 9 files changed, 309 insertions(+), 115 deletions(-) diff --git a/webapp/src/components/Background/Background.js b/webapp/src/components/Background/Background.js index cfda93c9..713e40c2 100644 --- a/webapp/src/components/Background/Background.js +++ b/webapp/src/components/Background/Background.js @@ -6,7 +6,7 @@ import "./Background.css"; const Background = () => { const [ init, setInit ] = useState(false); - const { colorMode, toggleColorMode } = useColorMode(); + const { colorMode } = useColorMode(); const isDarkTheme = colorMode === "dark"; const particlesColor = isDarkTheme ? "#FFFFFF" : "#000000"; const bgColor = isDarkTheme ? '#1A202C' : '#FFFFFF'; diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index c39e1c36..e8adddbf 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -1,44 +1,161 @@ { "components": { - "footer": { - "copyright": "Copyright 2024 ® Group 1A of Software Architecture" - }, - "login": { - "title": "Log in", - "nameLabel": "Enter your name", - "namePlaceholder": "Name", - "passwordPlaceholder": "Password", - "passwordLabel": "Enter your password", - "loginButton": "Log in", - "registerText": "Don't have an account?", - "registerLink": "Register", - "loginAlert": "Login successful" - }, - "nav": { - "home": "Home", - "gameModes": "Game Modes", - "classic": "Classic", - "wisebattery": "Wise Battery", - "humancalculator": "Human Calculator", - "stats": "Statistics", - "ranking": "Ranking", - "profile": "Profile", - "about": "About Us", - "options": "Options", - "disconnect": "Disconnect" - }, - "register": { - "title": "Register", - "nameLabel": "Enter your name", - "namePlaceholder": "Name", - "passwordPlaceholder": "Password", - "passwordLabel": "Enter your password", - "password2Label": "Re-enter the password", - "registerButton": "Register", - "loginText": "Already have an account?", - "loginLink": "Log in", - "registerAlert": "User registered successfully", - "registerError": "Passwords do not match" - } + "footer": { + "copyright": "Copyright 2024 ® Grupo 1A de Arquitectura del Software" + }, + "login": { + "title": "Log In", + "nameLabel": "Enter your name", + "namePlaceholder": "Name", + "passwordPlaceholder": "Password", + "passwordLabel": "Enter your password", + "loginButton": "Log In", + "registerText": "Don't have an account?", + "registerLink": "Register", + "loginAlert": "Login successful" + }, + "nav": { + "home": "Home", + "gameModes": "Game Modes", + "classic": "Classic", + "wisebattery": "Wise Battery", + "humancalculator": "Human Calculator", + "stats": "Statistics", + "ranking": "Ranking", + "profile": "Profile", + "about": "About Us", + "options": "Options", + "disconnect": "Disconnect" + }, + "register": { + "title": "Register", + "nameLabel": "Enter your name", + "namePlaceholder": "Name", + "passwordPlaceholder": "Password", + "passwordLabel": "Enter your password", + "password2Label": "Re-enter password", + "registerButton": "Register", + "loginText": "Already have an account?", + "loginLink": "Log In", + "registerAlert": "User registered successfully", + "registerError": "Passwords do not match" + } + }, + "pages": { + "classic": { + "finished": "Game Over!", + "score": "Your score:", + "playAgain": "Play Again", + "back": "Back to Menu", + "question": "Question", + "time": "Time remaining:", + "easterEgg": "You've got them all right! You're Jordi Hurtado's alternate account.", + "answer": "Answer" + }, + "wisebattery": { + "finished": "Game Over!", + "score": "Your score:", + "playAgain": "Play Again", + "back": "Back to Menu", + "question": "Question", + "time": "Time remaining:" + }, + "humancalculator": { + "finished": "Game Over!", + "score": "Your score:", + "playAgain": "Play Again", + "back": "Back to Menu", + "question": "Question", + "time": "Time remaining:" + }, + "config": { + "title": "Settings", + "language": "Language", + "topics": "Question Topics", + "countries": "Countries", + "literature": "Literature", + "cinema": "Cinema", + "art": "Art", + "programming": "Programming", + "save": "Apply Changes", + "timeBetweenClassic": "Time between questions (Classic)", + "questionCountClassic": "Number of questions (Classic)", + "totalTimeBattery": "Total time (Wise Battery)" + }, + "home": { + "title": "Welcome to WIQ!", + "choose": "Choose game mode", + "classic": "Classic Mode", + "classicDescription": "In Classic mode, you have to answer a set number of questions within a limited time. Show your knowledge and speed to overcome this challenge!", + "wisebattery": "Wise Battery", + "wisebatteryDescription": "In Wise Battery mode, test your knowledge by answering as many questions as you can within a fixed time. The more questions you answer correctly, the higher your score! Are you ready for this timed challenge?", + "humancalculator": "Human Calculator", + "humancalculatorDescription": "In Human Calculator mode, you have to solve mathematical operations within a limited time. Show off your math skills and speed to overcome this challenge!", + "error": "There was an error loading questions. Please try again later." + }, + "profile": { + "title": "Profile", + "nameLabel": "Username:", + "dateLabel": "Account creation date:", + "recentGames": "Recent Games", + "gameMode": "Game Mode", + "correct": "Correct Answers", + "incorrect": "Incorrect Answers", + "score": "Score", + "avgTime": "Average Time", + "seconds": "seconds", + "noGames": "You haven't played any games yet." + }, + "ranking": { + "loading": "Loading...", + "loadingText": "Retrieving ranking, please wait a moment.", + "error": "Error:", + "errorLabel": "An error occurred while retrieving ranking", + "rank-mode": "Ranking - Mode", + "classic": "Classic", + "wisebattery": "Wise Battery", + "humancalculator": "Human Calculator", + "user": "User", + "avgPoints": "Average Points", + "totalPoints": "Total Points", + "ratioCorrect": "Correct Ratio (%)", + "avgTime": "Time per Question (s):", + "reboot": "Reset to Default", + "errorText": "An error occurred while retrieving ranking" + }, + "about": { + "title": "WIQ_es1a Team", + "description": "Our development team", + "name": "Name", + "uo": "University", + "github": "GitHub", + "mygithub": "My GitHub" + }, + "stats": { + "loading": "Loading...", + "loadingText": "Retrieving statistics, please wait a moment.", + "username": "Username", + "search": "Search", + "searchText": "Please check if the form values are correct and try again", + "classic": "Classic", + "wisebattery": "Wise Battery", + "humancalculator": "Human Calculator", + "noStats": "The user hasn't played any games.", + "stats": "Statistics for", + "mode": "Mode", + "gamesPlayed": "Games Played", + "pointsPerGame": "Points per Game", + "totalpoints": "Total Points", + "totalCorrect": "Total Correct Answers", + "totalIncorrect": "Total Incorrect Answers", + "correctRatio": "Correct Percentage", + "avgTime": "Time per Question (s)" + }, + "wrongroute": { + "title": "Page Not Found", + "message": "The page you were looking for is not available", + "home": "Back to Home" + } } -} \ No newline at end of file + } + \ No newline at end of file diff --git a/webapp/src/locales/es.json b/webapp/src/locales/es.json index d8d61f6f..4ebd9f23 100644 --- a/webapp/src/locales/es.json +++ b/webapp/src/locales/es.json @@ -92,6 +92,69 @@ "humancalculator": "Calculadora humana", "humancalculatorDescription": "En el modo Calculadora Humana, tendrás que resolver operaciones matemáticas en un tiempo limitado. ¡Demuestra tus habilidades matemáticas y rapidez para superar este desafío!", "error": "Hubo un error al cargar las preguntas. Por favor, inténtalo más tarde." + }, + "profile": { + "title": "Perfil", + "nameLabel": "Nombre de usuario:", + "dateLabel": "Fecha de creación de la cuenta:", + "recentGames": "Partidas recientes", + "gameMode": "Modo de juego", + "correct": "Respuestas correctas", + "incorrect": "Respuestas incorrectas", + "score": "Puntos", + "avgTime": "Tiempo promedio", + "seconds": "segundos", + "noGames": "No has jugado ninguna partida aún." + }, + "ranking": { + "loading": "Cargando ...", + "loadingText": "Se está consultando el ranking, espere unos instantes.", + "error": "Error:", + "errorLabel": "Ha ocurrido un error al obtener el ranking", + "rank-mode": "Ranking - modo", + "classic": "Clásico", + "wisebattery": "Batería de sabios", + "humancalculator": "Calculadora humana", + "user": "Usuario", + "avgPoints": "Puntos promedio", + "totalPoints": "Puntos totales", + "ratioCorrect": "Ratio de aciertos (%)", + "avgTime": "Tiempo por pregunta (s):", + "reboot": "Restablecer por defecto", + "errorText": "Ha ocurrido un error al obtener el ranking" + }, + "about": { + "title": "Equipo WIQ_es1a", + "description": "Nuestro equipo de desarrollo", + "name": "Nombre", + "uo": "UO", + "github": "GitHub", + "mygithub": "Mi GitHub" + }, + "stats": { + "loading": "Cargando ...", + "loadingText": "Se están consultando las estadísticas, espere unos instantes.", + "username": "Nombre de usuario", + "search": "Buscar", + "searchText": "Por favor compruebe si los valores del formulario son correctos e inténtelo de nuevo", + "classic": "Clásico", + "wisebattery": "Batería de sabios", + "humancalculator": "Calculadora humana", + "noStats": "El usuario no ha jugado ninguna partida.", + "stats": "Estadísticas de", + "mode": "Modo", + "gamesPlayed": "Partidas jugadas", + "pointsPerGame": "Puntos por partida", + "totalpoints": "Puntos totales", + "totalCorrect": "Preguntas correctas totales", + "totalIncorrect": "Preguntas incorrectas totales", + "correctRatio": "Porcentaje de aciertos", + "avgTime": "Tiempo por pregunta (s)" + }, + "wrongroute": { + "title": "Página no encontrada", + "message": "La página que estabas buscando no está disponible", + "home": "Volver al inicio" } } } diff --git a/webapp/src/pages/Config/Config.js b/webapp/src/pages/Config/Config.js index cf365016..f8197f00 100644 --- a/webapp/src/pages/Config/Config.js +++ b/webapp/src/pages/Config/Config.js @@ -19,7 +19,7 @@ import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; const Config = () => { - const { i18n } = useTranslation(); + const { t, i18n} = useTranslation(); useEffect(() => { // Obtener el estado de los checkboxes desde el localStorage @@ -88,14 +88,14 @@ const Config = () => { - {i18n('pages.config.title')} + {t('pages.config.title')} - {i18n('pages.config.language')} + {t('pages.config.language')} - {i18n('pages.config.topics')} + {t('pages.config.topics')} { > - {i18n('pages.config.countries')} + {t('pages.config.countries')} - {i18n('pages.config.literature')} + {t('pages.config.literature')} - {i18n('pages.config.cinema')} + {t('pages.config.cinema')} - {i18n('pages.config.art')} + {t('pages.config.art')} - {i18n('pages.config.programming')} + {t('pages.config.programming')} @@ -124,7 +124,7 @@ const Config = () => { {" "} - {i18n('pages.config.timeBetweenClassic')} + {t('pages.config.timeBetweenClassic')} { {" "} - {i18n('pages.config.questionCountClassic')} + {t('pages.config.questionCountClassic')} { - {i18n('pages.config.totalTimeBattery')} + {t('pages.config.totalTimeBattery')} { diff --git a/webapp/src/pages/Perfil/Perfil.js b/webapp/src/pages/Perfil/Perfil.js index 31c31cca..0fcb68a5 100644 --- a/webapp/src/pages/Perfil/Perfil.js +++ b/webapp/src/pages/Perfil/Perfil.js @@ -2,6 +2,7 @@ import { Box, VStack, Heading, Text, Center, Spinner, Table, Thead, Tbody, Tr, T import React, { useEffect, useState } from "react"; import Nav from "../../components/Nav/Nav.js"; import Footer from "../../components/Footer/Footer.js"; +import { useTranslation } from "react-i18next"; const Perfil = () => { const gatewayUrl = process.env.REACT_APP_API_ENDPOINT || "http://localhost:8000"; @@ -9,6 +10,8 @@ const Perfil = () => { const [userData, setUserData] = useState(null); const [loading, setLoading] = useState(true); + const { t } = useTranslation(); + const [error, setError] = useState(null); useEffect(() => { @@ -33,7 +36,7 @@ const Perfil = () => { - Perfil del usuario + {t('pages.profile.title')} {loading ? (
@@ -46,25 +49,25 @@ const Perfil = () => { {userData && ( <> - Nombre de usuario: {userData.username} + {t('pages.profile.nameLabel')} {userData.username} - Fecha de creación de la cuenta:{" "} + {t('pages.profile.dateLabel')}{" "} {new Date(userData.createdAt).toLocaleString()} - Partidas Recientes + {t('pages.profile.recentGames')}
{userData.games.length > 0 ? ( - - - - - + + + + + @@ -74,13 +77,13 @@ const Perfil = () => { - + ))}
Modo de juegoRespuestas correctasRespuestas incorrectasPuntosTiempo promedio{t('pages.profile.gameMode')}{t('pages.profile.correct')}{t('pages.profile.incorrect')}{t('pages.profile.score')}{t('pages.profile.avgTime')}
{game.gamemode === 'calculadora' ? '-' : game.correctAnswers} {game.gamemode === 'calculadora' ? '-' : game.incorrectAnswers} {game.points}{parseFloat(game.avgTime).toFixed(2)} segundos{parseFloat(game.avgTime).toFixed(2)} {t('pages.profile.seconds')}
) : ( - No hay partidas recientes. + {t('pages.profile.nogames')} )}
diff --git a/webapp/src/pages/Ranking/Ranking.js b/webapp/src/pages/Ranking/Ranking.js index b7b05589..a71a3c3f 100644 --- a/webapp/src/pages/Ranking/Ranking.js +++ b/webapp/src/pages/Ranking/Ranking.js @@ -2,18 +2,21 @@ import React, { useState, useEffect } from "react"; import { Select, Button, Heading, Table, Thead, Tbody, Tr, Th, Td, Flex } from "@chakra-ui/react"; import Nav from "../../components/Nav/Nav.js"; import Footer from "../../components/Footer/Footer.js"; +import { useTranslation } from "react-i18next"; const Ranking = () => { const gatewayUrl = process.env.REACT_APP_API_ENDPOINT || "http://localhost:8000"; + const { t } = useTranslation(); + 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" } + { value: "avgPoints", label: `${t('pages.ranking.avgPoints')}` }, + { value: "totalPoints", label: `${t('pages.ranking.totalPoints')}` }, + { value: "ratioCorrect", label: `${t('pages.ranking.ratioCorrect')}` }, + { value: "avgTime", label: `${t('pages.ranking.avgTime')}` }, + { value: "avgPoints", label: `${t('pages.ranking.reboot')}` }, ]); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); @@ -28,8 +31,7 @@ const Ranking = () => { setIsLoading(false); }) .catch((error) => { - console.error('Error al obtener el ranking:', error); - setError(error.message || 'Ha ocurrido un error al obtener el ranking'); + setError(error.message || `${t('pages.ranking.errorText')}`); setIsLoading(false); }); }; @@ -57,14 +59,14 @@ const Ranking = () => { const getDisplayedField = () => { switch (filterBy) { case "avgPoints": - return "Puntos promedio"; + return `${t('pages.ranking.avgPoints')}`; case "totalPoints": - return "Puntos totales"; + return `${t('pages.ranking.totalPoints')}`; case "ratioCorrect": if (gamemode === "calculadora") return null; - return "Ratio de aciertos (%)"; + return `${t('pages.ranking.ratioCorrect')}`; case "avgTime": - return "Tiempo por pregunta (s)"; + return `${t('pages.ranking.avgTime')}`; default: return ""; } @@ -94,8 +96,8 @@ const Ranking = () => { if (isLoading) { return (
- Cargando ... -

Se está consultando el ranking, espere unos instantes.

+ {t('pages.ranking.loading')} +

{t('pages.ranking.loadingText')}

); } @@ -103,8 +105,8 @@ const Ranking = () => { if (error) { return (
- Error: {error} -

Ha ocurrido un error al obtener el ranking

+ {t('pages.ranking.error')} {error} +

{t('pages.ranking.errorLabel')}

); } @@ -113,7 +115,7 @@ const Ranking = () => { <>