Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

105 añadir enlace a openapi y a la info de las preguntas #112

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions gatewayservice/gateway-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ app.get("/friends", async (req, res) => {
handleRequest(req, res, userServiceUrl + "/friends");
});

app.get("/userGames", async (req, res) => {
handleRequest(req, res, userServiceUrl + "/userGames");
});

app.post("/saveGameList", async (req, res) => {
try {
// Forward the save game request to the stats service
Expand Down
13 changes: 12 additions & 1 deletion users/userservice/user-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,18 @@ const userSchema = new mongoose.Schema({
correctAnswers: Number,
incorrectAnswers: Number,
points: Number,
avgTime: Number
avgTime: Number,
questions: [{
pregunta: String,
respuestas: [
String,
String,
String,
String
],
correcta: String,
respuesta: String
}]
}],
friends: [{
type: String,
Expand Down
22 changes: 21 additions & 1 deletion users/userservice/user-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,18 +208,38 @@
}
});

app.get("/userGames", async (req, res) => {
try {
const username = req.query.user;
if(!username){
return res.status(400).json({ error: "Nombre inválido" });
}
const user = await User.findOne({ username:
Dismissed Show dismissed Hide dismissed
username,
});
if (!user) {
return res.status(404).json({ error: "Usuario no encontrado" });
}
res.json(user.games);
} catch (error) {
res.status(400).json({ error: error.message });
}
});

app.post("/saveGameList", async (req, res) => {
try {
const username = checkInput(req.body.username);
const gamemode = checkInput(req.body.gameMode);
const gameData = req.body.gameData;
const questions = req.body.questions;

let user = await User.findOne({ username: username });

if (!user) {
return res.status(404).json({ error: "Usuario no encontrado" });
}
const gameDataWithGamemode = { ...gameData, gamemode };
const gameDataWithGamemode = { ...gameData, gamemode, questions };
console.log(gameDataWithGamemode);
user.games.push(gameDataWithGamemode);

await user.save();
Expand Down
1 change: 1 addition & 0 deletions webapp/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
text-align: center;
justify-content: space-between;
}

2 changes: 2 additions & 0 deletions webapp/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Perfil from "./pages/Perfil/Perfil.js";
import CalculadoraHumana from "./pages/Calculadora/Calculadora.js";
import UsersPage from "./pages/Social/UsersPage.js";
import FriendList from "./pages/Social/FriendsList.js";
import History from "./pages/History/History.js";

function App() {
useEffect(() => {
Expand All @@ -40,6 +41,7 @@ function App() {
<Route path="/social/usuarios" element={<UsersPage />} />
<Route path="/social/amigos" element={<FriendList />} />
<Route path="/perfil" element={<Perfil />} />
<Route path="/history" element={<History />} />
<Route path="/config" element={<Config />} />
</Route>

Expand Down
21 changes: 17 additions & 4 deletions webapp/src/components/Footer/Footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,23 @@ const Footer = () => {
const bgColor = { light: 'gray.200', dark: 'gray.700' };
const textColor = { light: 'black', dark: 'white' };

return(
<Box as="footer" textAlign="center" p={4} bg={bgColor[colorMode]} color={textColor[colorMode]} position="sticky" bottom="0" width="100%">
<Heading as="h2" fontSize="xl">WIQ!</Heading>
<Text fontSize="sm" mt={2}>{t('components.footer.copyright')}</Text>
return (
<Box
as="footer"
textAlign="center"
position="relative"
bottom="0"
width="100%"
p={4}
bg={bgColor[colorMode]}
color={textColor[colorMode]}
>
<Heading as="h2" fontSize="xl">
WIQ!
</Heading>
<Text fontSize="sm" mt={2}>
{t('components.footer.copyright')}
</Text>
</Box>
);
}
Expand Down
3 changes: 3 additions & 0 deletions webapp/src/components/Nav/Nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,9 @@ const Nav = () => {
<MenuItem onClick={() => handleNavigate("/perfil")}>
{t("components.nav.myprofile")}
</MenuItem>
<MenuItem onClick={() => handleNavigate("/history")}>
{t("components.nav.history")}
</MenuItem>
<MenuItem onClick={() => handleNavigate("/config")}>
{t("components.nav.options")}
</MenuItem>
Expand Down
9 changes: 8 additions & 1 deletion webapp/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"about": "About Us",
"options": "Options",
"disconnect": "Disconnect",
"api": "API docs"
"api": "API docs",
"history": "History"
},
"register": {
"title": "Sign up",
Expand Down Expand Up @@ -124,6 +125,12 @@
"seconds": "seconds",
"noGames": "You haven't played any games yet."
},
"history": {
"title": "Game history",
"name": "Username",
"dateLabel": "Account creation date:",
"ngame": "Game"
},
"ranking": {
"loading": "Loading...",
"loadingText": "Ranking is being queried, please wait a moment.",
Expand Down
9 changes: 8 additions & 1 deletion webapp/src/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"about": "Sobre nosotros",
"options": "Opciones",
"disconnect": "Desconectar",
"api": "API docs"
"api": "API docs",
"history": "Historial"
},
"register": {
"title": "Regístrate",
Expand Down Expand Up @@ -124,6 +125,12 @@
"seconds": "segundos",
"noGames": "No has jugado ninguna partida aún."
},
"history": {
"title": "Historial de partidas",
"name": "Nombre de usuario",
"dateLabel": "Fecha de creación de la cuenta:",
"ngame": "Partida"
},
"ranking": {
"loading": "Cargando ...",
"loadingText": "Se está consultando el ranking, espere unos instantes.",
Expand Down
95 changes: 74 additions & 21 deletions webapp/src/pages/Bateria/Bateria.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Nav from "../../components/Nav/Nav.js";
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 axios from "axios";
import { useTranslation } from "react-i18next";

const JuegoPreguntas = () => {
Expand All @@ -27,13 +27,42 @@ const JuegoPreguntas = () => {
const [preguntasFalladas, setPreguntasFalladas] = useState(0);
const [tiempoMedio, setTiempoMedio] = useState(0);

const questionsToSave = [];

useEffect(() => {
setProgressPercent(100);
fetchQuestions();
handleTimer();
// eslint-disable-next-line
}, []);

useEffect(() => {
const roundedProgressPercent = (
(tiempoRestante / TIME) *
100
).toFixed(2);
setProgressPercent(roundedProgressPercent);

const timer = setInterval(() => {
setTiempoRestante((prevTiempo) =>
prevTiempo <= 0 ? 0 : prevTiempo - 0.01
);
}, 10);

return () => clearInterval(timer);
// eslint-disable-next-line
}, [tiempoRestante]);

useEffect(() => {
if (tiempoRestante === 0) {
setJuegoTerminado(true);
}
const timer = setInterval(() => {
setTiempoRestante((prevTiempo) => (prevTiempo <= 0 ? 0 : prevTiempo - 1));
}, 1000);
return () => clearInterval(timer);
// eslint-disable-next-line
}, [tiempoRestante]);

useEffect(() => {
if (juegoTerminado && tiempoMedio !== 0) {
guardarPartida();
Expand All @@ -44,7 +73,7 @@ const JuegoPreguntas = () => {
useEffect(() => {
if (tiempoRestante === 0) {
setJuegoTerminado(true);
if(preguntasCorrectas + preguntasFalladas > 0) {
if (preguntasCorrectas + preguntasFalladas > 0) {
const preguntasTotales = preguntasCorrectas + preguntasFalladas;
const tMedio = TIME / preguntasTotales;
setTiempoMedio(tMedio);
Expand All @@ -59,7 +88,11 @@ const JuegoPreguntas = () => {
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ tematicas: localStorage.getItem("selectedThemes") || "paises", n: 9000, locale: i18n.language }),
body: JSON.stringify({
tematicas: localStorage.getItem("selectedThemes") || "paises",
n: 9000,
locale: i18n.language,
}),
})
.then((response) => {
if (!response.ok) {
Expand All @@ -81,7 +114,7 @@ const JuegoPreguntas = () => {

const handleTimer = () => {
const timer = setInterval(() => {
setTiempoRestante(prevTiempo => (prevTiempo <= 0 ? 0 : prevTiempo - 1));
setTiempoRestante((prevTiempo) => (prevTiempo <= 0 ? 0 : prevTiempo - 1));
}, 1000);
return () => clearInterval(timer);
};
Expand All @@ -97,6 +130,7 @@ const JuegoPreguntas = () => {
points: puntuacion,
avgTime: tiempoMedio,
},
questions: questionsToSave,
};

saveGame("/saveGame", newGame);
Expand All @@ -108,9 +142,9 @@ const JuegoPreguntas = () => {
const response = await axios.post(URL + endpoint, newGame);
console.log("Solicitud exitosa:", response.data);
} catch (error) {
console.error('Error al guardar el juego:', error);
console.error("Error al guardar el juego:", error);
}
}
};

const handleSiguientePregunta = async (respuesta) => {
if (respuesta === preguntaActual.correcta) {
Expand All @@ -119,6 +153,15 @@ const JuegoPreguntas = () => {
} else {
setPreguntasFalladas(preguntasFalladas + 1);
}

const pregunta = {
pregunta: preguntaActual.pregunta,
respuestas: preguntaActual.respuestas,
correcta: preguntaActual.correcta,
respuesta: respuesta,
};
questionsToSave.push(pregunta);

if (indicePregunta + 1 < preguntas.length) {
setIndicePregunta(indicePregunta + 1);
setPreguntaActual(preguntas[indicePregunta + 1]);
Expand All @@ -140,12 +183,12 @@ const JuegoPreguntas = () => {
<Nav />
<Spinner
data-testid="spinner"
thickness='4px'
speed='0.65s'
emptyColor='gray.200'
color='teal.500'
size='xl'
margin='auto'
thickness="4px"
speed="0.65s"
emptyColor="gray.200"
color="teal.500"
size="xl"
margin="auto"
/>
<Footer />
</>
Expand All @@ -156,26 +199,32 @@ const JuegoPreguntas = () => {
<>
<Nav />
<Flex justify="center" align="center" h="70vh">
<Box p={6} borderWidth="1px" maxWidth={"90%"} borderRadius="lg" boxShadow="lg">
<Box
p={6}
borderWidth="1px"
maxWidth={"90%"}
borderRadius="lg"
boxShadow="lg"
>
{juegoTerminado ? (
<Box textAlign="center">
<Heading as="h2">{t('pages.wisebattery.finished')}</Heading>
<Heading as="h2">{t("pages.wisebattery.finished")}</Heading>
<p p={2}>
{t('pages.wisebattery.score')} {puntuacion}
{t("pages.wisebattery.score")} {puntuacion}
</p>
<Flex flexDirection={"column"}>
<Button onClick={handleRepetirJuego} colorScheme="teal" m={2}>
{t('pages.wisebattery.playAgain')}
{t("pages.wisebattery.playAgain")}
</Button>
<Link to="/home" style={{ marginLeft: "10px" }}>
{t('pages.wisebattery.back')}
{t("pages.wisebattery.back")}
</Link>
</Flex>
</Box>
) : (
<Box>
<Heading as="h2" mb={4}>
{t('pages.wisebattery.question')} {indicePregunta + 1}
{t("pages.wisebattery.question")} {indicePregunta + 1}
</Heading>
<p>{preguntaActual.pregunta}</p>
<Grid templateColumns="repeat(2, 1fr)" gap={4} mt={4}>
Expand All @@ -195,8 +244,12 @@ const JuegoPreguntas = () => {
</Grid>

<Box textAlign="center" mt={4}>
<p>{t('pages.wisebattery.time')} {Math.floor(tiempoRestante)}</p>
<p>{t('pages.wisebattery.score')} {puntuacion}</p>
<p>
{t("pages.wisebattery.time")} {Math.floor(tiempoRestante)}
</p>
<p>
{t("pages.wisebattery.score")} {puntuacion}
</p>
<Box w="100%" bg="gray.100" borderRadius="lg" mt={4}>
<Box
bg="teal.500"
Expand Down
23 changes: 23 additions & 0 deletions webapp/src/pages/Bateria/a.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Box p={6} borderWidth="1px" maxWidth={"90%"} borderRadius="lg" boxShadow="lg">
<Box>
<Heading as="h2" mb={4}>
{t("pages.wisebattery.question")} {indicePregunta + 1}
</Heading>
<p>{preguntaActual.pregunta}</p>
<Grid templateColumns="repeat(2, 1fr)" gap={4} mt={4}>
{preguntaActual.respuestas.map((respuesta, index) => (
<Button
key={index}
onClick={() => handleSiguientePregunta(respuesta)}
disabled={tiempoRestante === 0 || juegoTerminado}
whiteSpace={"normal"}
padding={"1rem"}
height={"fit-content"}
minHeight={"3rem"}
>
{respuesta}
</Button>
))}
</Grid>
</Box>
</Box>;
Loading