Skip to content

Commit

Permalink
Merge branch 'develop' into user_profile
Browse files Browse the repository at this point in the history
  • Loading branch information
uo287841 committed Apr 22, 2024
2 parents 3093b89 + c0c91c7 commit c972a55
Show file tree
Hide file tree
Showing 16 changed files with 565 additions and 293 deletions.
35 changes: 21 additions & 14 deletions questionservice/question-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -212,26 +212,33 @@ app.get('/imgs/foods/question', async (req, res) => {
app.post('/imgs/answer', async (req, res) => {
try {
const obj = req.body;

if (obj.question == answerToQuestionMap.get(obj.answer)) {
await axios.post(userServiceUrl + '/addpoints',
{ username: obj.username, category: obj.category, correct: "true" });
res.status(200).json({
correct: "true",
})
if (obj.answer !== "TimeOut1234;") {
if (obj.question == answerToQuestionMap.get(obj.answer)) {
await axios.post(userServiceUrl + '/addpoints',
{ username: obj.username, category: obj.category, correct: "true" });
res.status(200).json({
correct: "true",
})
} else {
await axios.post(userServiceUrl + '/addpoints',
{ username: obj.username, category: obj.category, correct: "false" });
res.status(200).json({
correct: "false",
correctImg: `${[...answerToQuestionMap].find(([key, val]) => val == obj.question)[0]}`
})
}
} else {
await axios.post(userServiceUrl + '/addpoints',
{ username: obj.username, category: obj.category, correct: "false" });

res.status(200).json({
correct: "false",
associate: `${imgToAssociatedMap.get(obj.answer)}`
correctImg: `${[...answerToQuestionMap].find(([key, val]) => val == obj.question)[0]}`
})
}
} catch (e) { //SIEMPRE RODEAR CON TRY CATCH
res.status(500).json({ error: e.message })
}
});
} catch (e) { //SIEMPRE RODEAR CON TRY CATCH
console.error(e)
res.status(500).json({ error: e.message })
}
});

const server = app.listen(port, () => {
console.log(`Questions service listening on http://localhost:${port}`);
Expand Down
3 changes: 3 additions & 0 deletions webapp/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
src/
*.js
365 changes: 200 additions & 165 deletions webapp/package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions webapp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@mui/material": "^5.15.3",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@mui/icons-material": "^5.15.15",
"@mui/material": "^5.15.15",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.2",
Expand Down
Binary file added webapp/public/WIQProvFondo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added webapp/public/WIQProvSin.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified webapp/public/favicon.ico
Binary file not shown.
3 changes: 3 additions & 0 deletions webapp/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import Login from './components/Login';
import RankingsLayout from './components/ranking/RankingLayout';
import Game from './components/Game';
import MainPage from './components/MainPage';
import Squads from './components/Squads';
import UserProfile from './components/UserProfile';


function App() {
// const isAuthenticated = useIsAuthenticated() // True if user has logged in
// const auth = useAuthUser(); // User data: {username,emial,createdAt} To add fields go to Login
Expand All @@ -24,6 +26,7 @@ function App() {
<Route path='/register' element={<AddUser />} />
<Route path='/rankings' element={<RankingsLayout />} />
<Route path='/play' element={<Game />} />
<Route path='/squads' element={<Squads />} />
<Route path='/userprofile' element={<UserProfile />} />
</Routes>
</BrowserRouter>
Expand Down
21 changes: 14 additions & 7 deletions webapp/src/components/AddUser.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@ const AddUser = () => {

const addUser = async () => {
try {
if(password!==cpassword){
if (password !== cpassword) {
setError("Passwords do not match");
return;
}
await axios.post(`${apiEndpoint}/adduser`, { username, email, password });
setOpenSnackbar(true);
navigate('/login');

} catch (error) {
if(error.response===undefined){
if (error.response === undefined) {
setError("There was a problem...");
}
else{
else {
setError(error.response.data.error);
}
}
Expand All @@ -39,6 +40,7 @@ const AddUser = () => {
};

return (

<Container component="main" maxWidth="xs" sx={{ marginTop: 4 }}>
<Typography component="h1" variant="h5">
Register
Expand Down Expand Up @@ -71,7 +73,7 @@ const AddUser = () => {
/>
<TextField
name="cpassword"

margin="normal"
fullWidth
label="Confirm Password"
Expand All @@ -85,11 +87,16 @@ const AddUser = () => {
<Typography component="div" align="center" sx={{ marginTop: 2 }}>
<Link to="/login">Already have an account? Log in here.</Link>
</Typography>

<Snackbar open={openSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar} message="User added successfully" />
{error && (
<Snackbar open={!!error} autoHideDuration={6000} onClose={() => setError('')} message={`Error: ${error}`} />
)}
{
error && (
<Snackbar open={!!error} autoHideDuration={6000} onClose={() => setError('')} message={`Error: ${error}`} />
)
}
</Container>


);
};

Expand Down
67 changes: 67 additions & 0 deletions webapp/src/components/ImgGameReport.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useEffect } from "react";
import CheckIcon from '@mui/icons-material/Check';
import ClearIcon from '@mui/icons-material/Clear';
import { useNavigate } from "react-router-dom";
const ImgGameReport = (props) => {
const answers = props.answers;
const navigate = useNavigate();
const loadRankings = () => {
navigate("/rankings");
}
return (
<div >
<div class=" bg-gradient-to-br from-purple-900 via-indigo-900 to-blue-900">
<div class=" justify-center mx-auto max-w-3xl px-6 py-12">
<div class="justify-center text-center">
<h1 class="text-4xl font-bold text-white mb-4">Game Over!</h1>
<p class="text-xl text-white mb-8">
You answered {props.score} {props.score === 1 ? "question" : "questions"} correctly
</p>

<div class="sm:flex lg:justify-center">
<div class="rounded-md shadow">
<a href=""
onClick={props.restartGame}
class="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 md:py-4 md:text-lg md:px-10">
Restart Game
</a>
</div>



<div class="mt-3 sm:mt-0 sm:ml-3">
<a href=""
onClick={loadRankings}
class="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base font-medium rounded-md text-indigo-700 bg-indigo-100 hover:bg-indigo-200 md:py-4 md:text-lg md:px-10">
See Rankings
</a>
</div>
</div>
</div>
</div>
</div>
<div class="mt-16 grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 p-4">


{answers.map((answer) => {
return (
<div class="flex flex-col rounded-2xl w-80 bg-[#ffffff] shadow-xl" key={answer.associate}>
<figure class="flex justify-center items-center rounded-2xl">
<img src={answer.associate} alt="Card Preview" class="rounded-t-2xl"></img>
</figure>
<div class="flex flex-col p-8">
<div class="text-2xl font-bold text-center text-[#374151] pb-6">{answer.question}</div>
<div class=" text-base text-center text-[#374151]">
You answered the question {answer.correct === "true" ? "correctly" : "wrongly"}
{answer.correct === "true" ? <CheckIcon fontSize="large" style={{ color: 'green' }} /> : <ClearIcon fontSize="large" style={{ color: 'red' }} />}
</div>
</div>
</div>
);
})}
</div>
</div>
);
}

export default ImgGameReport;
107 changes: 62 additions & 45 deletions webapp/src/components/Login.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
// src/components/Login.js
import React, { useState } from 'react';
import axios from 'axios';
import { Container, Typography, TextField, Button, Snackbar } from '@mui/material';

import useSignIn from 'react-auth-kit/hooks/useSignIn';
import { Container, Typography, TextField, Button, Snackbar } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import { Link } from 'react-router-dom';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const signIn = useSignIn();
const navigate = useNavigate();
const navigate = useNavigate();
const [openSnackbar, setOpenSnackbar] = useState(false);

const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';

const loginUser = async () => {
try {
const response = await axios.post(`${apiEndpoint}/login`, { username, password }).then((res) => {
await axios.post(`${apiEndpoint}/login`, { username, password }).then((res) => {

if (res.status === 200) {
if (signIn({
auth: {
Expand All @@ -33,22 +34,23 @@ const Login = () => {
}
})) { // Only if you are using refreshToken feature
// Redirect or do-something
navigate('/');
navigate('/');
//window.location.href = '/';
} else {
//Throw error

throw new Error('Error while signing in');
}

}
}
});

setOpenSnackbar(true);
} catch (error) {
if(error.response===undefined){
if (error.response === undefined) {
setError("Error: There was a problem...");
}
else{
else {
setError(error.response.data.error);
}

Expand All @@ -60,46 +62,61 @@ const Login = () => {
};

return (

<Container component="main" maxWidth="xs" sx={{ marginTop: 4 }}>
<div>
<Typography component="h1" variant="h5">
Login
</Typography>
<TextField
name = "username"
margin="normal"
fullWidth
label="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<TextField
name = "password"
margin="normal"
fullWidth
label="Password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>

<Button variant="contained" color="primary" onClick={loginUser}>
Login
</Button>

<Typography component="div" align="center" sx={{ marginTop: 2 }}>
<Link to="/register">Don't have an account? Register here.</Link>
</Typography>



<Snackbar open={openSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar} message="Login successful" />
{error && (
<Snackbar open={!!error} autoHideDuration={6000} onClose={() => setError('')} message={`Error: ${error}`} />
)}
</div>
<Typography component="h1" variant="h5">
Register
</Typography>
<TextField
name="username"
margin="normal"
fullWidth
label="Username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
<TextField
name="email"
type='email'
margin="normal"
fullWidth
label="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<TextField
name="password"
margin="normal"
fullWidth
label="Password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<TextField
name="cpassword"

margin="normal"
fullWidth
label="Confirm Password"
type="password"
value={cpassword}
onChange={(e) => setcPassword(e.target.value)}
/>
<Button variant="contained" color="primary" onClick={addUser}>
Register
</Button>
<Typography component="div" align="center" sx={{ marginTop: 2 }}>
<Link to="/login">Already have an account? Log in here.</Link>
</Typography>


<Snackbar open={openSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar} message="Login successful" />
{error && (
<Snackbar open={!!error} autoHideDuration={6000} onClose={() => setError('')} message={`Error: ${error}`} />
)}
</Container>

);
};

Expand Down
Loading

0 comments on commit c972a55

Please sign in to comment.