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

Big patch #120

Merged
merged 9 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
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.
2 changes: 2 additions & 0 deletions webapp/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ 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';

function App() {
// const isAuthenticated = useIsAuthenticated() // True if user has logged in
Expand All @@ -23,6 +24,7 @@ function App() {
<Route path='/register' element={<AddUser />} />
<Route path='/rankings' element={<RankingsLayout />} />
<Route path='/play' element={<Game />} />
<Route path='/squads' element={<Squads />} />
</Routes>
</BrowserRouter>
)
Expand Down
110 changes: 56 additions & 54 deletions webapp/src/components/AddUser.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// src/components/AddUser.js
import React, { useState } from 'react';
import axios from 'axios';
import { Container, Typography, TextField, Button, Snackbar } from '@mui/material';
import { Snackbar } from '@mui/material';
import { Link } from 'react-router-dom';
import { useNavigate } from 'react-router-dom';
const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';
Expand All @@ -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,57 +40,58 @@ const AddUser = () => {
};

return (
<Container component="main" maxWidth="xs" sx={{ marginTop: 4 }}>
<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>

<div class="bg-[#453873] w-full h-screen justify-center content-center">
<div class="flex flex-col w-full md:w-1/2 xl:w-2/5 2xl:w-2/5 3xl:w-1/3 mx-auto p-8 md:p-10 2xl:p-12 3xl:p-14 bg-[#ffffff] rounded-2xl shadow-xl pt-3">
<div class="flex flex-row gap-3 pb-4">
<div>
<img src="/favicon.ico" width="50" alt="Logo"></img>
</div>
<h1 class="text-3xl font-bold text-[#4B5563] text-[#4B5563] my-auto">WIQ</h1>

</div>
<div class="text-sm font-light text-[#6B7280] pb-8 ">Sign up for an account on WIQ.</div>
<form class="flex flex-col">
<div class="pb-2">
<label for="username" class="block mb-2 text-sm font-medium text-[#111827]">Username</label>
<div class="relative text-gray-400"><span class="absolute inset-y-0 left-0 flex items-center p-1 pl-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mail"><rect width="20" height="16" x="2" y="4" rx="2"></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path></svg></span>
<input type="text" name="username" id="username" label="Username" value={username} onChange={(e) => setUsername(e.target.value)} class="pl-12 mb-2 bg-gray-50 text-gray-600 border focus:border-transparent border-gray-300 sm:text-sm rounded-lg ring ring-transparent focus:ring-1 focus:outline-none focus:ring-gray-400 block w-full p-2.5 rounded-l-lg py-3 px-4" placeholder="Username" />
</div>
</div>
<div class="pb-2">
<label for="email" class="block mb-2 text-sm font-medium text-[#111827]">Email</label>
<div class="relative text-gray-400"><span class="absolute inset-y-0 left-0 flex items-center p-1 pl-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mail"><rect width="20" height="16" x="2" y="4" rx="2"></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path></svg></span>
<input name="email" type='email' margin="normal" label="Email" value={email} onChange={(e) => setEmail(e.target.value)} class="pl-12 mb-2 bg-gray-50 text-gray-600 border focus:border-transparent border-gray-300 sm:text-sm rounded-lg ring ring-transparent focus:ring-1 focus:outline-none focus:ring-gray-400 block w-full p-2.5 rounded-l-lg py-3 px-4" placeholder="[email protected]" />
</div>
</div>
<div class="pb-6">
<label for="password" class="block mb-2 text-sm font-medium text-[#111827]">Password</label>
<div class="relative text-gray-400"><span class="absolute inset-y-0 left-0 flex items-center p-1 pl-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-asterisk"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M12 8v8"></path><path d="m8.5 14 7-4"></path><path d="m8.5 10 7 4"></path></svg></span>
<input name="password" label="Password" type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="••••••••••" class="pl-12 mb-2 bg-gray-50 text-gray-600 border focus:border-transparent border-gray-300 sm:text-sm rounded-lg ring ring-transparent focus:ring-1 focus:outline-none focus:ring-gray-400 block w-full p-2.5 rounded-l-lg py-3 px-4" autocomplete="new-password" />
</div>
</div>
<div class="pb-6">
<label for="cpassword" class="block mb-2 text-sm font-medium text-[#111827]">Confirm Password</label>
<div class="relative text-gray-400"><span class="absolute inset-y-0 left-0 flex items-center p-1 pl-3"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-asterisk"><rect width="18" height="18" x="3" y="3" rx="2"></rect><path d="M12 8v8"></path><path d="m8.5 14 7-4"></path><path d="m8.5 10 7 4"></path></svg></span>
<input name="cpassword" margin="normal" label="Confirm Password" type="password" value={cpassword} onChange={(e) => setcPassword(e.target.value)} placeholder="••••••••••" class="pl-12 mb-2 bg-gray-50 text-gray-600 border focus:border-transparent border-gray-300 sm:text-sm rounded-lg ring ring-transparent focus:ring-1 focus:outline-none focus:ring-gray-400 block w-full p-2.5 rounded-l-lg py-3 px-4" autocomplete="new-password" />
</div>
</div>
<button type="submit" class="w-full text-[#FFFFFF] bg-[#453873] focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mb-6"onClick={addUser}>Sign Up</button>
<div class="text-sm font-light text-[#6B7280] ">Already have an account? <Link to="/login" class="font-medium text-[#453873] hover:underline">Login</Link>

</div>
</form>
</div >

<Snackbar open={openSnackbar} autoHideDuration={6000} onClose={handleCloseSnackbar} message="User added successfully" />
{error && (
<Snackbar open={!!error} autoHideDuration={6000} onClose={() => setError('')} message={`Error: ${error}`} />
)}
</Container>
{
error && (
<Snackbar open={!!error} autoHideDuration={6000} onClose={() => setError('')} message={`Error: ${error}`} />
)
}
</div>
//</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;
Loading
Loading