diff --git a/docs/src/add20Users.png b/docs/images/add20Users.png similarity index 100% rename from docs/src/add20Users.png rename to docs/images/add20Users.png diff --git a/docs/src/playGame100.png b/docs/images/playGame100.png similarity index 100% rename from docs/src/playGame100.png rename to docs/images/playGame100.png diff --git a/package-lock.json b/package-lock.json index 29b2e41a..9319c1ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "WIQ_ES2B", + "name": "wiq_es2b", "lockfileVersion": 2, "requires": true, "packages": { @@ -12,6 +12,7 @@ "axios": "^1.6.8", "cors": "^2.8.5", "express": "^4.19.2", + "history": "^5.3.0", "jest": "^29.7.0", "supertest": "^6.3.4" }, @@ -3232,6 +3233,14 @@ "node": ">=8" } }, + "node_modules/history": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", + "dependencies": { + "@babel/runtime": "^7.7.6" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -8699,6 +8708,14 @@ "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz", "integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==" }, + "history": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", + "requires": { + "@babel/runtime": "^7.7.6" + } + }, "hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", diff --git a/package.json b/package.json index 614537ff..8d5a7fad 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "axios": "^1.6.8", "cors": "^2.8.5", "express": "^4.19.2", + "history": "^5.3.0", "jest": "^29.7.0", "supertest": "^6.3.4" }, diff --git a/resources/WIQ 2024 ES2B.gif b/resources/WIQ 2024 ES2B.gif new file mode 100644 index 00000000..c933c761 Binary files /dev/null and b/resources/WIQ 2024 ES2B.gif differ diff --git a/resources/wiq2024.png b/resources/wiq2024.png new file mode 100644 index 00000000..84a1357c Binary files /dev/null and b/resources/wiq2024.png differ diff --git a/webapp/public/winners.png b/webapp/public/winners.png new file mode 100644 index 00000000..f9a68b39 Binary files /dev/null and b/webapp/public/winners.png differ diff --git a/webapp/src/App.css b/webapp/src/App.css index 6524432d..0ac53da8 100644 --- a/webapp/src/App.css +++ b/webapp/src/App.css @@ -45,3 +45,11 @@ } +h1{ + color: #4C8DBF; + font-size: 2rem; + font-weight: 900; + text-decoration: none; +} + + diff --git a/webapp/src/App.js b/webapp/src/App.js index c6f85bc3..87247327 100644 --- a/webapp/src/App.js +++ b/webapp/src/App.js @@ -21,19 +21,26 @@ function App() {
- - Bienvenido a WIQ 2024 del curso de Arquitectura del Software +
+ + Bienvenido a + + WIQ 2024 + +
+ {showLogin ? : } + {showLogin ? ( - + ¿No tienes una cuenta? Regístrate aquí. - + ) : ( - + ¿Ya tienes cuenta? Inicia sesión aquí. - + )} diff --git a/webapp/src/App.test.js b/webapp/src/App.test.js index 8602a898..6dbfc0d2 100644 --- a/webapp/src/App.test.js +++ b/webapp/src/App.test.js @@ -8,8 +8,12 @@ test('renders learn react link', () => { ); - const linkElement = screen.getByText(/Bienvenido a WIQ 2024 del curso de Arquitectura del Software/i); - expect(linkElement).toBeInTheDocument(); + const welcomeText = screen.getByText(/Bienvenido a/i); + + const wiqText = screen.getByText(/WIQ 2024/i); + + expect(welcomeText).toBeInTheDocument(); + expect(wiqText).toBeInTheDocument(); }); diff --git a/webapp/src/components/AddUser.js b/webapp/src/components/AddUser.js index de0ffe5a..d3c835d5 100644 --- a/webapp/src/components/AddUser.js +++ b/webapp/src/components/AddUser.js @@ -1,30 +1,32 @@ -// src/components/AddUser.js import React, { useState } from 'react'; import axios from 'axios'; import { Container, Typography, TextField, Button, Snackbar } from '@mui/material'; +import { useNavigate } from 'react-router-dom'; const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; -const AddUser = () => { +const AddUser = ({ onCloseSnackbar }) => { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [openSnackbar, setOpenSnackbar] = useState(false); + const navigate = useNavigate(); const addUser = async () => { try { await axios.post(`${apiEndpoint}/adduser`, { username, password }); + await axios.post(`${apiEndpoint}/login`, { username, password }); + localStorage.setItem('username', username); setOpenSnackbar(true); - + + // Redirige a la página de juego después de 3 segundos + navigate("/Game"); } catch (error) { - setError(error.response.data.error); + setError("Error al crear usuario"); + setOpenSnackbar(true); // Abre el Snackbar en caso de error } }; - const handleCloseSnackbar = () => { - setOpenSnackbar(false); - }; - return ( @@ -34,7 +36,7 @@ const AddUser = () => { name="username" margin="normal" fullWidth - label="Username" + label="Nombre de usuario" value={username} onChange={(e) => setUsername(e.target.value)} /> @@ -42,7 +44,7 @@ const AddUser = () => { name="password" margin="normal" fullWidth - label="Password" + label="Contraseña" type="password" value={password} onChange={(e) => setPassword(e.target.value)} @@ -50,7 +52,7 @@ const AddUser = () => { - + {error && ( setError('')} message={`Error: ${error}`} /> )} diff --git a/webapp/src/components/AddUser.test.js b/webapp/src/components/AddUser.test.js index f9c55b41..4eaa9d2b 100644 --- a/webapp/src/components/AddUser.test.js +++ b/webapp/src/components/AddUser.test.js @@ -3,16 +3,21 @@ import { render, fireEvent, screen, waitFor } from '@testing-library/react'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import AddUser from './AddUser'; +import { BrowserRouter } from 'react-router-dom'; const mockAxios = new MockAdapter(axios); const renderAddUserComponent = () => { - render(); + return render( + + + + ); }; const addUser = async () => { - const usernameInput = screen.getByLabelText(/Username/i); - const passwordInput = screen.getByLabelText(/Password/i); + const usernameInput = screen.getByLabelText(/Nombre de usuario/i); + const passwordInput = screen.getByLabelText(/Contraseña/i); const addUserButton = screen.getByRole('button', { name: /Crear usuario/i }); fireEvent.change(usernameInput, { target: { value: 'testUser' } }); @@ -35,7 +40,7 @@ describe('AddUser component', () => { await addUser(); await waitFor(() => { - expect(screen.getByText(/User added successfully/i)).toBeInTheDocument(); + expect(screen.getByText(/Usuario añadido correctamente/i)).toBeInTheDocument(); }); }); @@ -47,15 +52,15 @@ describe('AddUser component', () => { await addUser(); await waitFor(() => { - expect(screen.getByText(/Error: Internal Server Error/i)).toBeInTheDocument(); + expect(screen.getByText(/Error: Error al crear usuario/i)).toBeInTheDocument(); }); }); it('should display proper labels and inputs', () => { renderAddUserComponent(); - expect(screen.getByLabelText(/Username/i)).toBeInTheDocument(); - expect(screen.getByLabelText(/Password/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/Nombre de usuario/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/Contraseña/i)).toBeInTheDocument(); expect(screen.getByRole('button', { name: /Crear usuario/i })).toBeInTheDocument(); }); @@ -68,10 +73,10 @@ describe('AddUser component', () => { jest.runAllTimers(); - expect(screen.queryByText(/User added successfully/i)).toBeNull(); + expect(screen.queryByText(/Usuario añadido correctamente/i)).toBeNull(); await waitFor(() => { - expect(screen.getByText(/User added successfully/i)).toBeInTheDocument(); + expect(screen.getByText(/Usuario añadido correctamente/i)).toBeInTheDocument(); }); }); @@ -87,7 +92,7 @@ describe('AddUser component', () => { expect(screen.queryByText(/Error: Internal Server Error/i)).toBeNull(); await waitFor(() => { - expect(screen.getByText(/Error: Internal Server Error/i)).toBeInTheDocument(); + expect(screen.getByText(/Error: Error al crear usuario/i)).toBeInTheDocument(); }); }); }); diff --git a/webapp/src/components/Footer.css b/webapp/src/components/Footer.css index c64e75ff..a8c87eb3 100644 --- a/webapp/src/components/Footer.css +++ b/webapp/src/components/Footer.css @@ -1,12 +1,15 @@ .footer { - position: absolute; + position: fixed; width: 100%; background-color: #f5f5f5; padding: 0.5rem; text-align: center; - margin-top: 90vh; - height: auto; bottom: 0; + margin-top: 20rem; +} + +.footer p{ + font-size: 1rem; } .footer a { @@ -17,4 +20,20 @@ .footer a:hover { text-decoration: underline; -} \ No newline at end of file +} + +.footer-wiq { + background-color: #333; + font-size: 1rem; + color: white; +} + +.footer-text { + font-size: 1rem; +} + +.footer-text a { + color: #4C8DBF; + font-weight: 700; + text-decoration: underline; +} diff --git a/webapp/src/components/Footer.js b/webapp/src/components/Footer.js index 904473f0..8a4fb8b7 100644 --- a/webapp/src/components/Footer.js +++ b/webapp/src/components/Footer.js @@ -4,13 +4,13 @@ import { AppBar, Toolbar, Typography } from '@mui/material'; const Footer = () => { return ( - +
- +

© {new Date().getFullYear()} Hecho con ❤️ por Coral, Carlos, Pablo y Raymond. ASW - Curso 2023-24 - +

- +
); }; diff --git a/webapp/src/components/Game.js b/webapp/src/components/Game.js index feab3620..9c3a1d27 100644 --- a/webapp/src/components/Game.js +++ b/webapp/src/components/Game.js @@ -325,7 +325,7 @@ const getQuestions = () => { setGameData(newGame); - axios.post(`${apiEndpoint}/addgame`, gameData) + axios.post(`${apiEndpoint}/addgame`, newGame) .then(response => { console.log("Respuesta del servidor:", response.data); }) diff --git a/webapp/src/components/HistoricalData.css b/webapp/src/components/HistoricalData.css index adba9ab8..35a4dbe3 100644 --- a/webapp/src/components/HistoricalData.css +++ b/webapp/src/components/HistoricalData.css @@ -30,7 +30,8 @@ table { th, td { padding: 0.25em; text-align: center; - border: 0.1em solid #000; + border: #000 solid 0.5rem; + font-weight: 600; } th[title='pregunta'] { @@ -47,9 +48,5 @@ table { td{ background-color: rgba(61, 178, 224, 0.764); + border: #000 solid 0.5rem; } - - - - - diff --git a/webapp/src/components/HistoricalData.js b/webapp/src/components/HistoricalData.js index fc6eaaa3..fa793d5b 100644 --- a/webapp/src/components/HistoricalData.js +++ b/webapp/src/components/HistoricalData.js @@ -14,7 +14,7 @@ const HistoricalData = () => { useEffect(() => { handleShowHistory(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); // No es necesario deshabilitar eslint, ya que no hay dependencias externas + }, []); const handleShowHistory = async () => { try { @@ -31,7 +31,7 @@ const HistoricalData = () => { const handleChangeRowsPerPage = (event) => { setRowsPerPage(parseInt(event.target.value, 10)); - setPage(0); // Reiniciar a la primera página cuando cambia el número de filas por página + setPage(0); }; @@ -59,12 +59,12 @@ const HistoricalData = () => { {paginatedData.map((row, rowIndex) => ( - - {row[0]} - {row[1]} - {row[2]} - {row[3]} - {row[4]} + + {row[0]} + {row[1]} + {row[2]} + {row[3]} + {row[4]} ))} diff --git a/webapp/src/components/HistoricalData.test.js b/webapp/src/components/HistoricalData.test.js index a8841eea..68b4b099 100644 --- a/webapp/src/components/HistoricalData.test.js +++ b/webapp/src/components/HistoricalData.test.js @@ -6,41 +6,35 @@ import HistoricalData from './HistoricalData'; import { BrowserRouter as Router } from 'react-router-dom'; const mockAxios = new MockAdapter(axios); - describe('HistoricalData component', () => { - beforeEach(() => { + afterEach(() => { mockAxios.reset(); }); it('muestra la página con el histórico de preguntas generadas', async () => { - const question1 = ['¿Cual es la capital de Venezuela?', 'Caracas', 'Doha', 'Barcelona', 'Nasáu']; const question2 = ['¿Cual es la capital de Francia?', 'París', 'Londres', 'Madrid', 'Roma']; const mockUsers = [question1, question2]; mockAxios.onGet("http://localhost:8000/getquestionshistory").reply(200, mockUsers); render( - - ); + + ); await waitFor(() => { - - expect(screen.getByText('¿Cual es la capital de Venezuela?')).toBeInTheDocument(); - expect(screen.getByText('Caracas')).toBeInTheDocument(); - expect(screen.getByText('Doha')).toBeInTheDocument(); - expect(screen.getByText('Barcelona')).toBeInTheDocument(); - expect(screen.getByText('Nasáu')).toBeInTheDocument(); - - expect(screen.getByText('¿Cual es la capital de Francia?')).toBeInTheDocument(); - expect(screen.getByText('París')).toBeInTheDocument(); - expect(screen.getByText('Londres')).toBeInTheDocument(); - expect(screen.getByText('Madrid')).toBeInTheDocument(); - expect(screen.getByText('Roma')).toBeInTheDocument(); - - expect(screen.getByText('Rows per page:')).toBeInTheDocument(); - - }); + expect(screen.getByText('¿Cual es la capital de Venezuela?')).toBeInTheDocument(); + expect(screen.getByText('Caracas')).toBeInTheDocument(); + expect(screen.getByText('Doha')).toBeInTheDocument(); + expect(screen.getByText('Barcelona')).toBeInTheDocument(); + expect(screen.getByText('Nasáu')).toBeInTheDocument(); + + expect(screen.getByText('¿Cual es la capital de Francia?')).toBeInTheDocument(); + expect(screen.getByText('París')).toBeInTheDocument(); + expect(screen.getByText('Londres')).toBeInTheDocument(); + expect(screen.getByText('Madrid')).toBeInTheDocument(); + expect(screen.getByText('Roma')).toBeInTheDocument(); + + expect(screen.getByText('Rows per page:')).toBeInTheDocument(); + }); }); }); - - diff --git a/webapp/src/components/HistoricalUserData.css b/webapp/src/components/HistoricalUserData.css index f1a9f8aa..45a10ddd 100644 --- a/webapp/src/components/HistoricalUserData.css +++ b/webapp/src/components/HistoricalUserData.css @@ -16,7 +16,7 @@ div[title="botones"]{ button{ margin: 1em; padding: 0.25em; - background-color: rgba(31, 60, 134, 0.764); + background-color: #1f3c86c3; color: white; font-size: 0.75em; } @@ -30,7 +30,6 @@ table { th, td { padding: 0.25em; text-align: center; - border: 0.1em solid #000; } th[title='pregunta'] { @@ -46,10 +45,12 @@ th[title='incorrecta'] { } td{ - background-color: rgba(61, 178, 224, 0.764); + background-color: #3db2e0c3; } - - +h2{ + color: #1f3c86c3; + padding-bottom: 1rem; +} \ No newline at end of file diff --git a/webapp/src/components/HistoricalUserData.js b/webapp/src/components/HistoricalUserData.js index a42c3be9..dc03d750 100644 --- a/webapp/src/components/HistoricalUserData.js +++ b/webapp/src/components/HistoricalUserData.js @@ -90,13 +90,13 @@ const HistoricalUserData = () => { {paginatedGameHistory.map((game, index) => ( - - {formatDate(game.date)} - {game.duration} segundos - {game.percentage.toFixed(2)}% - {game.totalQuestions} - {game.correctAnswers} - {game.incorrectAnswers} + + {formatDate(game.date)} + {game.duration} segundos + {game.percentage.toFixed(2)}% + {game.totalQuestions} + {game.correctAnswers} + {game.incorrectAnswers} {expandedRows.includes(index) && game.questions && game.questions.map((question, qIndex) => ( diff --git a/webapp/src/components/Login.js b/webapp/src/components/Login.js index 084d4b25..76b7e870 100644 --- a/webapp/src/components/Login.js +++ b/webapp/src/components/Login.js @@ -5,7 +5,7 @@ import { useNavigate } from 'react-router-dom'; const Login = () => { const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000'; - + const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); @@ -20,14 +20,10 @@ const Login = () => { setOpenSnackbar(true); navigate("/MainPage"); } catch (error) { - setError(error.response.data.error); + setError('Error: Credenciales inválidas') } }; - const handleCloseSnackbar = () => { - setOpenSnackbar(false); - }; - return (
@@ -37,14 +33,14 @@ const Login = () => { setUsername(e.target.value)} /> setPassword(e.target.value)} @@ -52,9 +48,9 @@ const Login = () => { - + {setOpenSnackbar(false);}} message="Inicio de sesión exitoso" /> {error && ( - setError('')} message={`Error: ${error}`} /> + {{setOpenSnackbar(true);setError('Error: Credenciales inválidas');}}} message={error} /> )}
diff --git a/webapp/src/components/Login.test.js b/webapp/src/components/Login.test.js index 51963ada..7429b970 100644 --- a/webapp/src/components/Login.test.js +++ b/webapp/src/components/Login.test.js @@ -2,12 +2,19 @@ import React from 'react'; import { render, fireEvent, screen, waitFor, act } from '@testing-library/react'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; -import { BrowserRouter as Router } from "react-router-dom"; // No necesitas el alias aquí +import { BrowserRouter as Router } from "react-router-dom"; import Login from './Login'; import { createMemoryHistory } from 'history'; const mockAxios = new MockAdapter(axios); +function getLoginElements() { + const usernameInput = screen.getByLabelText(/Nombre de usuario/i); + const passwordInput = screen.getByLabelText(/Contraseña/i); + const loginButton = screen.getByRole('button', { name: /Iniciar sesión/i }); + return { usernameInput, passwordInput, loginButton }; +} + describe('Login component', () => { beforeEach(() => { mockAxios.reset(); @@ -20,14 +27,10 @@ describe('Login component', () => { ); - const usernameInput = screen.getByLabelText(/Username/i); - const passwordInput = screen.getByLabelText(/Password/i); - const loginButton = screen.getByRole('button', { name: /Iniciar sesión/i }); + const { usernameInput, passwordInput, loginButton } = getLoginElements(); - // Mock the axios.post request to simulate a successful response mockAxios.onPost('http://localhost:8000/login').reply(200, { createdAt: '2024-01-01T12:34:56Z' }); - // Simulate user input await act(async () => { fireEvent.change(usernameInput, { target: { value: 'testUser' } }); fireEvent.change(passwordInput, { target: { value: 'testPassword' } }); @@ -41,12 +44,11 @@ describe('Login component', () => { ); - const usernameInput = screen.getByLabelText(/Username/i); - const passwordInput = screen.getByLabelText(/Password/i); - const loginButton = screen.getByRole('button', { name: /Iniciar sesión/i }); + const { usernameInput, passwordInput, loginButton } = getLoginElements(); + - // Mock the axios.post request to simulate an error response - mockAxios.onPost('http://localhost:8000/login').reply(401, { error: 'Invalid credentials' }); + // Mock del request axios.post para simular una respuesta de error + mockAxios.onPost('http://localhost:8000/login').reply(401, { error: 'Error: Credenciales inválidas' }); fireEvent.change(usernameInput, { target: { value: 'testUser' } }); fireEvent.change(passwordInput, { target: { value: 'testPassword' } }); @@ -54,7 +56,7 @@ describe('Login component', () => { fireEvent.click(loginButton); await waitFor(() => { - expect(screen.getByText(/Error: Invalid credentials/i)).toBeInTheDocument(); + expect(screen.getByText(/Error: Credenciales inválidas/i)).toBeInTheDocument(); }); }); @@ -66,11 +68,10 @@ describe('Login component', () => { ); - const usernameInput = screen.getByLabelText(/Username/i); - const passwordInput = screen.getByLabelText(/Password/i); - const loginButton = screen.getByRole('button', { name: /Iniciar sesión/i }); + const { usernameInput, passwordInput, loginButton } = getLoginElements(); - // Mock the axios.post request to simulate a successful response + + // Mock del request axios.post para simular una respuesta exitosa mockAxios.onPost('http://localhost:8000/login').reply(200, { createdAt: '2024-01-01T12:34:56Z' }); fireEvent.change(usernameInput, { target: { value: 'testUser' } }); @@ -79,10 +80,10 @@ describe('Login component', () => { fireEvent.click(loginButton); await waitFor(() => { - expect(screen.getByText(/Login successful/i)).toBeInTheDocument(); + expect(screen.getByText(/Inicio de sesión exitoso/i)).toBeInTheDocument(); }); - // Check if the redirection happens after the successful login expect(history.location.pathname).toBe('/'); }); + }); diff --git a/webapp/src/components/MainPage.css b/webapp/src/components/MainPage.css index 58569311..97970849 100644 --- a/webapp/src/components/MainPage.css +++ b/webapp/src/components/MainPage.css @@ -12,8 +12,7 @@ div[title="main-title"]>h1 { } div[title="main-title"]>h2 { - /* margin-bottom: 2rem; */ - color: #4c8dbf; + color: #0155B7; font-size: 4rem; font-weight: bold; font-family: Verdana, Geneva, Tahoma, sans-serif; @@ -58,7 +57,7 @@ div[title="main"]>button { } .img-container img { - width: 70rem; + width: 70%; height: auto; animation: slide 3s ease infinite alternate; } @@ -88,4 +87,9 @@ div[title="main"]>button { .dialogImage img { width: 18rem; +} + + +.dialogContainer { + margin-bottom: 40%; } \ No newline at end of file diff --git a/webapp/src/components/MainPage.js b/webapp/src/components/MainPage.js index d444c689..bad92bca 100644 --- a/webapp/src/components/MainPage.js +++ b/webapp/src/components/MainPage.js @@ -1,6 +1,6 @@ // MainPage.js import React, { createContext, useContext, useState } from 'react'; -import { Container, Typography, Button, Grid, Dialog, DialogTitle, DialogContent, TextField, DialogActions } from '@mui/material'; +import { Container, Typography, Button, Grid, Dialog, DialogTitle, DialogContent, TextField, DialogActions, Snackbar } from '@mui/material'; import { useNavigate } from 'react-router-dom'; import './MainPage.css'; @@ -19,25 +19,18 @@ const MainPage = () => { const [open, setOpen] = useState(false); const [numQuestions, setNumQuestions] = useState(5); const [timePerQuestion, setTimePerQuestion] = useState(10); - - const handleNumQuestionsChange = (event) => { - setNumQuestions(event.target.value); - }; - - const handleTimePerQuestionChange = (event) => { - setTimePerQuestion(event.target.value); - }; - - const handleOpenDialog = () => { - setOpen(true); - }; + const [error, setError] = useState(''); + const [openSnackbar, setOpenSnackbar] = useState(false); const handleCloseDialog = () => { - setOpen(false); - }; + // Validar que el valor de preguntas sea al menos 5 y el tiempo por pregunta sea al menos 10 + if (numQuestions < 5 || timePerQuestion < 10) { + setError('El número de preguntas debe ser al menos 5 y el tiempo por pregunta debe ser al menos 10 segundos.'); + setOpenSnackbar(true); + return; + } - const handleInputChange = (event) => { - event.preventDefault(); + setOpen(false); }; const handleShowGame = () => { @@ -52,11 +45,6 @@ const MainPage = () => { navigate(path, { state: { gameConfig } }); }; - const handleRanking = () => { - let path = '/ScoreBoard'; - navigate(path); - }; - // Valor del contexto para la configuración del juego const configValue = { numQuestions, @@ -65,6 +53,7 @@ const MainPage = () => { updateTimePerQuestion: setTimePerQuestion, }; + return ( @@ -83,7 +72,7 @@ const MainPage = () => {
- Imagen de prueba + Imagen de prueba
@@ -91,10 +80,10 @@ const MainPage = () => { - -
@@ -120,8 +109,11 @@ const MainPage = () => { type="number" fullWidth value={numQuestions} - onChange={handleNumQuestionsChange} - inputProps={{ min: 5, onKeyDown: handleInputChange }} + onChange={(event) => { + let newValue = parseInt(event.target.value, 10); + setNumQuestions(newValue); + }} + inputProps={{ min: 5 }} className="dialogTextField" /> @@ -133,8 +125,12 @@ const MainPage = () => { type="number" fullWidth value={timePerQuestion} - onChange={handleTimePerQuestionChange} - inputProps={{ min: 10, onKeyDown: handleInputChange }} + onChange={(event) => { + let newValue = parseInt(event.target.value, 10); + setTimePerQuestion(newValue); + + }} + inputProps={{ min: 10 }} className="dialogTextField" /> @@ -144,6 +140,13 @@ const MainPage = () => { + +