Skip to content

Commit

Permalink
Merge pull request #55 from Arquisoft/webapp_interface
Browse files Browse the repository at this point in the history
Más adelante se eliminará la conexión directa con el Question Generator Service y se realizarán las peticiones a través del Gateway.
  • Loading branch information
AbelMH1 authored Mar 13, 2024
2 parents 6f7a9f8 + 38ada23 commit c2bf00b
Show file tree
Hide file tree
Showing 14 changed files with 450 additions and 10 deletions.
Binary file modified docs/images/QualityTree.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/src/10_quality_requirements.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ occurs.
|The user must correctly answer questions on different topics. This will improve the user experience and maintain the interest of the participants.
|High

|Integrity
|Fiability
|The game must be played without errors.
|The answer determined as correct for each question by the system shall be the one that is actually correct.
|Medium
Expand Down
1 change: 1 addition & 0 deletions questionsservice/questiongeneratorservice/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
},
"homepage": "https://github.com/arquisoft/wiq_es6c#readme",
"dependencies": {
"cors": "^2.8.5",
"express": "^4.18.2",
"axios": "^1.6.5",
"cors": "^2.8.5",
Expand Down
88 changes: 88 additions & 0 deletions webapp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.2",
"axios": "^1.6.5",
"fetch": "^1.1.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.1",
"react-circular-progressbar": "^2.1.0",
"react-scripts": "5.0.1",
"web-vitals": "^3.5.1"
},
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function App() {
<Container component="main" maxWidth="xs">
<CssBaseline />
<Typography component="h1" variant="h5" align="center" sx={{ marginTop: 2 }}>
Welcome to wiq_0
Welcome to wiq_06c
</Typography>
{showLogin ? <Login /> : <AddUser />}
<Typography component="div" align="center" sx={{ marginTop: 2 }}>
Expand Down
11 changes: 10 additions & 1 deletion webapp/src/App.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { render, screen } from '@testing-library/react';
import App from './App';
import { ContextFun } from './components/Context';
import { BrowserRouter as Router } from 'react-router-dom';


test('renders learn react link', () => {
render(<App />);
render(
<ContextFun>
<Router>
<App />
</Router>
</ContextFun>
);
const linkElement = screen.getByText(/Welcome to wiq_0/i);
expect(linkElement).toBeInTheDocument();
});
17 changes: 17 additions & 0 deletions webapp/src/components/Context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { createContext, useContext, useState } from 'react';

const Context = createContext();

export function ContextFun({ children }) {
const [usernameGlobal, setUsernameGlobal] = useState('');

return (
<Context.Provider value={{ usernameGlobal, setUsernameGlobal }}>
{children}
</Context.Provider>
);
}

export function useUser() {
return useContext(Context);
}
41 changes: 41 additions & 0 deletions webapp/src/components/FirstGame.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
button {
font-size: 20px;
width: 200px;
height: 50px;
justify-content: center;
margin-bottom: 15px;
}

.questionStructure .answers {
display: flex;
justify-content: center; /* Alinea los elementos en el centro horizontal /
align-items: center; / Alinea los elementos en el centro vertical /
height: 100vh; / Ajusta la altura al 100% del viewport */
}

.allAnswers {
width:100%;
display: block;
}

.asnwers {
width:100%;
}
.progressBar {
height: 100%;
margin-top: 10;
width:10%;
display: inline-block;
}

.question {
height: 100%;
width: 90%;
display: inline-block;
}

.questionText {
display: flex;
margin-bottom: 25px;

}
130 changes: 130 additions & 0 deletions webapp/src/components/FirstGame.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import React, { useState, useEffect } from 'react';
import { Container, Typography } from '@mui/material';
import './FirstGame.css';
import { CircularProgressbar } from 'react-circular-progressbar';
import 'react-circular-progressbar/dist/styles.css';
import axios from 'axios';
import { json } from 'react-router-dom';
import { useLocation } from 'react-router-dom';

const apiEndpoint = 'http://localhost:8007';
const Quiz = () => {
var questions = useLocation().state.questions;

const [currentQuestionIndex, setCurrentQuestionIndex] = React.useState(0);
const [selectedOption, setSelectedOption] = React.useState(null);
const [isCorrect, setIsCorrect] = React.useState(null);

const esperar = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms));
};

function secureRandomNumber(max) {
const randomBytes = new Uint32Array(1);
window.crypto.getRandomValues(randomBytes);
return randomBytes[0] % max;
}

function shuffleArray(array) {
// Crea una copia del array original
const shuffledArray = [...array];

// Recorre el array desde el último elemento hasta el primero
for (let i = shuffledArray.length - 1; i > 0; i--) {
// Genera un índice aleatorio entre 0 y el índice actual
//const randomIndex = Math.floor(Math.random() * (i + 1));
const randomIndex = secureRandomNumber(i + 1);

// Intercambia el elemento actual con el elemento del índice aleatorio
const temp = shuffledArray[i];
shuffledArray[i] = shuffledArray[randomIndex];
shuffledArray[randomIndex] = temp;
}

// Devuelve el array barajado
return shuffledArray;
}


const getQuestions = async () => {
try {
const response = await axios.get(`${apiEndpoint}/questions?n_preguntas=${1}`);
console.log(response.data.length)
for (var i = 0; i < response.data.length; i++) {
var possibleAnswers = [response.data[i].respuesta_correcta, response.data[i].respuestas_incorrectas[0], response.data[i].respuestas_incorrectas[1], response.data[i].respuestas_incorrectas[2]]
possibleAnswers = shuffleArray(possibleAnswers)
questions.push({
question: response.data[i].pregunta,
options: possibleAnswers,
correctAnswer: response.data[i].respuesta_correcta
})
}
} catch (error) {
console.error(error);
}
console.log(questions)
};

const checkAnswer = async (option) => {
getQuestions()
setIsCorrect(option === questions[currentQuestionIndex].correctAnswer);
setSelectedOption(option);

const botonIncorrecta = document.getElementById('option-' + questions[currentQuestionIndex].options.indexOf(option))
if (!isCorrect) {
botonIncorrecta.style.backgroundColor = 'red'
}

const numberAnswer = questions[currentQuestionIndex].options.indexOf(questions[currentQuestionIndex].correctAnswer)
const botonCorrecta = document.getElementById('option-' + numberAnswer)
botonCorrecta.style.backgroundColor = 'green'
// Pasar a la siguiente pregunta después de responder

await esperar(2000); // Espera 2000 milisegundos (2 segundos)
botonIncorrecta.style.backgroundColor = 'lightgrey'
botonCorrecta.style.backgroundColor = 'lightgrey'
if (questions.length-1 !== currentQuestionIndex) {
setCurrentQuestionIndex((prevIndex) => prevIndex + 1);
}
setIsCorrect(false)


};

return (
<Container component="main" maxWidth="xl" sx={{ marginTop: 4 }}>
<div className="questionStructure">
<div class="question">
<Typography class="questionText" component="h1" variant="h5" sx={{ textAlign: 'center' }}>
{questions[currentQuestionIndex].question}
</Typography>
</div>

<div class="progressBar">
{/* {MiCircularProgressbar} */}
</div>
<div class="allAnswers">
{questions[currentQuestionIndex].options.map((option, index) => (
<div key={index} className="answers">
<button
id={`option-${index}`}
name="quiz"
value={option}
onClick={() => checkAnswer(option)}
style={{backgroundColor: 'lightgrey'}}
>
{option}
</button>
</div>
)
)}
</div>
</div>
{/* {isCorrect !== null && (
<p>{isCorrect ? '¡Respuesta correcta!' : 'Respuesta incorrecta.'}</p>
)} */}
</Container>
);
};

export default Quiz;
Loading

0 comments on commit c2bf00b

Please sign in to comment.