Skip to content

Commit

Permalink
Merge pull request #113 from Arquisoft/Social
Browse files Browse the repository at this point in the history
Implementado sistema de grupos completo
  • Loading branch information
iyanfdezz authored Apr 11, 2024
2 parents 4dee312 + 6a0a028 commit 9d750ba
Show file tree
Hide file tree
Showing 11 changed files with 456 additions and 21 deletions.
62 changes: 62 additions & 0 deletions gatewayservice/gateway-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,68 @@ app.post("/saveGameList", async (req, res) => {
}
});

app.get("/friends", async (req, res) => {
try {
// Forward the question request to the user service
const userResponse = await axios.get(
userServiceUrl + "/friends",
{ params: req.query }
);
res.json(userResponse.data);
} catch (error) {
returnError(res, error);
}
});

app.post("/group/add", async (req, res) => {
try {
// Forward the save game request to the stats service
const gameResponse = await axios.post(
userServiceUrl + "/group/add",
req.body
);
res.json(gameResponse.data);
} catch (error) {
returnError(res, error);
}
});

app.post("/group/join", async (req, res) => {
try {
// Forward the save game request to the stats service
const gameResponse = await axios.post(
userServiceUrl + "/group/join",
req.body
);
res.json(gameResponse.data);
} catch (error) {
returnError(res, error);
}
});

app.get("/group/list", async (req, res) => {
try {
// Forward the question request to the user service
const userResponse = await axios.get(
userServiceUrl + "/group/list",
{ params: req.query }
);
res.json(userResponse.data);
} catch (error) {
returnError(res, error);
}
});

app.get('/group/:groupName', async (req, res) => {
try {
const groupName = req.params.groupName;
const userResponse = await axios.get(`${userServiceUrl}/group/${groupName}`);
res.json(userResponse.data);
} catch (error) {
res.status(400).json({ error: error.message });
}
});

app.get("/users/search", async (req, res) => {
try {
// Forward the question request to the user service
Expand Down
20 changes: 5 additions & 15 deletions users/userservice/user-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,14 @@ const groupSchema = new mongoose.Schema({
type: Date,
default: Date.now
},
members: [{
type: String,
required: true
}]
});

const Group = mongoose.model('Group', groupSchema);

// Modelo para la relación entre usuarios y grupos
const userGroupSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
group: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Group',
required: true
},
});

const UserGroup = mongoose.model('UserGroup', userGroupSchema);

module.exports = { User, Group, UserGroup };
module.exports = { User, Group };
94 changes: 88 additions & 6 deletions users/userservice/user-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const bodyParser = require("body-parser");
const jwt = require("jsonwebtoken");
const { User } = require("./user-model");
const { User, Group } = require("./user-model");

const app = express();
const port = 8001;
Expand Down Expand Up @@ -246,14 +246,96 @@ app.post("/saveGameList", async (req, res) => {

res.json({ message: "Partida guardada exitosamente" });
} catch (error) {
res
.status(400)
.json({
error: "Error al guardar partida en la lista: " + error.message,
});
res.status(400).json({ error: "Error al guardar partida en la lista: " + error.message });
}
});

app.get('/group/list', async (req, res) => {
try {
const allGroups = await Group.find();
res.json({ groups: allGroups });
} catch (error) {
res.status(500).json({ error: 'Internal Server Error' });
}
});

// Obtener un grupo por su nombre
app.get('/group/:groupName', async (req, res) => {
try {
const groupName = req.params.groupName;
const group = await Group.findOne({ name: groupName });

if (!group) {
return res.status(404).json({ error: 'Group not found' });
}

res.json({ group });
} catch (error) {
res.status(400).json({ error: error.message });
}
});


// Crear un nuevo grupo
app.post('/group/add', async (req, res) => {
try {
const name= req.body.name;
const username= req.body.username;

if (!name) {
return res.status(400).json({ error: 'Group name cannot be empty' });
}

const existingGroup = await Group.findOne({ name: name });
if (existingGroup) {
return res.status(400).json({ error: 'Group name already exists' });
}

const user = await User.findOne({ username:username });
if (!user) {
return res.status(404).json({ error: 'User not found' });
}

const newGroup = new Group({ name: name,
members: [username] });
await newGroup.save();

res.json({ message: 'Group created successfully' });
} catch (error) {
res.status(400).json({ error: error.message });
}
});

// Unirse a un grupo existente
app.post('/group/join', async (req, res) => {
try {
const groupId=req.body.groupId;
const username=req.body.username;

const user = await User.findOne({ username });
if (!user) {
return res.status(404).json({ error: 'User not found' });
}

const group = await Group.findById(groupId);
if (!group) {
return res.status(404).json({ error: 'Group not found' });
}

if (group.members.includes(username)) {
return res.status(400).json({ error: 'User already a member of this group' });
}

group.members.push(username);
await group.save();

res.json({ message: 'User joined the group successfully' });
} catch (error) {
res.status(400).json({ error: error.message });
}
});


const server = app.listen(port, () => {
console.log(`User Service listening at http://localhost:${port}`);
});
Expand Down
8 changes: 8 additions & 0 deletions webapp/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ 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 Groups from "./pages/Social/Groups.js";
import UserGroups from "./pages/Social/UserGroups.js";
import GroupDetails from "./pages/Social/GroupDetails.js";
import History from "./pages/History/History.js";


function App() {
useEffect(() => {
document.title = "WIQ!";
Expand All @@ -40,6 +44,10 @@ function App() {
<Route path="/ranking" element={<Ranking />} />
<Route path="/social/usuarios" element={<UsersPage />} />
<Route path="/social/amigos" element={<FriendList />} />
<Route path="/social/grupos" element={<Groups />} />
<Route path="/social/misgrupos" element={<UserGroups />} />
<Route path="/social/grupo/:groupName" element={<GroupDetails />} />

<Route path="/perfil" element={<Perfil />} />
<Route path="/history" element={<History />} />
<Route path="/config" element={<Config />} />
Expand Down
16 changes: 16 additions & 0 deletions webapp/src/components/Nav/Nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,22 @@ const Nav = () => {
>
{t("components.nav.friends")}
</Text>
<Text
data-testid="groups"
cursor="pointer"
onClick={() => handleNavigate("/social/grupos")}
color={textColor}
>
Grupos
</Text>
<Text
data-testid="mygroups"
cursor="pointer"
onClick={() => handleNavigate("/social/misgrupos")}
color={textColor}
>
Mis grupos
</Text>
</PopoverBody>
</PopoverContent>
</Popover>
Expand Down
76 changes: 76 additions & 0 deletions webapp/src/pages/Social/GroupDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React, { useState, useEffect } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import axios from 'axios';
import { Container, Box, Text, Heading, Table, Thead, Tbody, Tr, Th, Td, Avatar, Link } from '@chakra-ui/react';
import Nav from "../../components/Nav/Nav.js";
import Footer from "../../components/Footer/Footer.js";

const GroupDetails = () => {
const [group, setGroup] = useState(null);
const { groupName } = useParams();
const apiEndpoint = process.env.REACT_APP_API_ENDPOINT || 'http://localhost:8000';
const navigate = useNavigate();

useEffect(() => {
const fetchGroupDetails = async () => {
try {
const response = await axios.get(`${apiEndpoint}/group/${encodeURIComponent(groupName)}`);
setGroup(response.data.group);
} catch (error) {
console.error('Error fetching group details:', error);
}
};

fetchGroupDetails();
}, [groupName]);

const redirectToProfile = (username) => {
navigate(`/perfil?user=${username}`);
};

return (
<>
<Nav/>
<Container maxW="md" mt="5">
<Heading as="h1" mb="5">Detalles del grupo: {groupName}</Heading>
{group ? (
<Box>
<Text fontSize="lg" fontWeight="bold" mb="4">
Creado por {group.members.length > 0 ? group.members[0] : ''} el {new Date(group.createdAt).toLocaleDateString()}
</Text>

<Text fontSize="lg" fontWeight="bold" mb="2">Participantes ({group.members.length}) :</Text>
<Table variant="striped">
<Thead>
<Tr>
<Th>Avatar</Th>
<Th>Nombre</Th>
<Th>Ver perfil</Th>
</Tr>
</Thead>
<Tbody>
{group.members.map((member, index) => (
<Tr key={index}>
<Td>
<Avatar size="sm" name={member} />
</Td>
<Td>{member}</Td>
<Td>
<Link color="blue.500" onClick={() => redirectToProfile(member)}>Ver perfil</Link>
</Td>
</Tr>
))}
</Tbody>
</Table>
</Box>
) : (
<Text>Loading...</Text>
)}
</Container>
<Footer/>
</>
);
};

export default GroupDetails;

Empty file.
Loading

0 comments on commit 9d750ba

Please sign in to comment.