Removed Groups

This commit is contained in:
Ceferino Patino 2022-03-12 11:59:39 -06:00
commit 3ae95cef00
18 changed files with 74 additions and 431 deletions

View file

@ -2,6 +2,7 @@ import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Header from './components/Header';
import MainPage from './components/MainPage';
import Form from './components/Form';
import Login from './components/Login';
@ -13,9 +14,6 @@ import Reset from './components/Reset';
import JoinedOrgs from './components/JoinedOrgs';
import OrgDashboard from './components/OrgDashboard';
import OwnedGroups from './components/OwnedGroups';
import GroupDashboard from './componenets/GroupDashboard';
import NotFound from './components/NotFound';
function App() {
@ -24,7 +22,7 @@ function App() {
<BrowserRouter>
<Routes>
<Route path='' element={<Header />}>
<Route index />
<Route index element={<MainPage />} />
<Route path='login' element={<Login />} />
<Route path='register' element={<Register />} />
@ -34,16 +32,11 @@ function App() {
<Route path=':id' element={<Reset />} />
</Route>
<Route path='org'>
<Route path=''>
<Route index element={<JoinedOrgs />} />
<Route path=':id' element={<OrgDashboard />} />
</Route>
<Route path='group'>
<Route index element={<OwnedGroups />} />
<Route path=':id' element={<GroupDashboard />} />
</Route>
<Route path='*' element={<NotFound />} />
</Route>
</Routes>

View file

@ -1,88 +0,0 @@
import React, { useState, useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import axios from 'axios';
import Cookies from 'js-cookie';
import { Typography, Grid, Stack, Box } from '@mui/material';
import Dashboard from './Dashboard';
function GroupDashboard() {
const navigate = useNavigate();
const { groupID } = useParams();
const [group, setGroup] = useState({
groupID: '',
groupName: '',
groupMembers: [],
createdAt: '',
});
const [rows, setRows] = useState([]);
useEffect(() => {
async function getData() {
await axios
.get(
`${
process.env.DOMAIN_ROOT
}/group/${groupID}?token=${Cookies.get('token')}`
)
.then((response) => {
const res = response.data;
setGroup(() => {
return {
groupID: res.groupID,
groupName: res.groupName,
groupMembers: res.groupMembers,
};
});
const groupMembers = res.groupMembers.map(
(member, index) => {
return {
id: index,
firstName: member.firstName,
lastName: member.lastName,
nickname: member.nickname,
namePronounciation: member.pronounciation,
pronouns: member.pronouns,
email: member.email,
};
}
);
setRows(() => groupMembers);
})
.catch((error) => {
navigate('/');
});
}
getData();
});
return (
<Dashboard rows={rows}>
<Typography variant='h6'>Groups/{group.groupName}</Typography>
<Box sx={{ marginTop: '1vh' }}>
<Grid container columns={{ xs: 3, md: 12 }}>
<Grid item xs={3}>
<Stack spacing={2}>
<Typography variant='body1'>
Group ID: {group.groupID}
</Typography>
<Typography variant='body1'>
Members: {group.groupMembers.length}
</Typography>
<Typography variant='body1'>
Created On: {group.createdAt}
</Typography>
</Stack>
</Grid>
</Grid>
</Box>
</Dashboard>
);
}
export default GroupDashboard;

View file

@ -8,18 +8,20 @@ import { Paper, Typography, Box, Stack } from '@mui/material';
import { useTheme } from '@mui/material/styles';
function OrgUnit({ org }) {
const { orgID, orgName, memberCount, orgCreatedAt } = org;
const { orgID, orgName, memberCount, createdAt } = org;
return (
<React.Fragment>
<Link to={orgID}>Name: {orgName}</Link>
<Typography variant='h6'>
<Link to={orgID}>Name: {orgName}</Link>
</Typography>
<Box>
<Stack spacing={2} direction={{ xs: 'column', md: 'row' }}>
<Typography variant='body1'>
Members: {memberCount}
</Typography>
<Typography variant='body1'>
Created On: {orgCreatedAt}
Created On: {createdAt}
</Typography>
</Stack>
</Box>
@ -47,7 +49,7 @@ function JoinedOrgs() {
orgID: org.orgID,
orgName: org.orgName,
memberCount: org.memberCount,
orgCreatedAt: org.createdAt,
createdAt: org.createdAt,
};
})
);

View file

@ -0,0 +1,65 @@
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import { Paper, Button, Typography, Stack, Box } from '@mui/material';
import { useTheme } from '@mui/material/styles';
function MainPage() {
const theme = useTheme();
const [org, setOrg] = useState({});
const linkStyle = { textDecoration: 'none', color: 'inherit' };
return (
<React.Fragment>
<Paper
sx={{
...theme.typography.body2,
padding: '2vh',
color: theme.palette.text.secondary,
flexGrow: 1,
height: '30vh',
margin: '2vh',
overflow: 'auto',
}}
>
{org && (
<React.Fragment>
<Typography variant='h6'>
<Link to={`orgs/${org.orgID}`} style={linkStyle}>
Your Organization: {org.orgName}
</Link>
</Typography>
<Box margin={2}>
<Stack spacing={2}>
<Typography variant='body1'>
Members: {org.memberCount}
</Typography>
<Typography variant='body1'>
Created On: {org.createdAt}
</Typography>
</Stack>
</Box>
</React.Fragment>
)}
</Paper>
<Paper
sx={{
...theme.typography.body2,
padding: '2vh',
textAlign: 'center',
color: theme.palette.text.secondary,
flexGrow: 1,
height: '57vh',
margin: '2vh',
overflow: 'auto',
}}
></Paper>
</React.Fragment>
);
}
export default MainPage;

View file

@ -1,80 +0,0 @@
import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios';
import Cookies from 'js-cookie';
import { Paper, Typography, Box, Stack } from '@mui/material';
import { useTheme } from '@mui/material/styles';
function GroupUnit({ group }) {
const { groupID, groupName, memberCount, groupCreatedAt } = group;
return (
<React.Fragment>
<Link to={groupID}>Name: {groupName}</Link>
<Box>
<Stack spacing={2} direction={{ xs: 'column', md: 'row' }}>
<Typography variant='body1'>
Members: {memberCount}
</Typography>
<Typography variant='body1'>
Created On: {groupCreatedAt}
</Typography>
</Stack>
</Box>
</React.Fragment>
);
}
function JoinedOrgs() {
const [groups, setGroups] = useState([]);
const theme = useTheme();
useEffect(() => {
async function getGroups() {
axios
.get(
`${process.env.DOMAIN_ROOT}/auth/orgs?token=${Cookies.get(
'token'
)}`
)
.then((response) => {
setGroups(() =>
response.data.map((group) => {
return {
groupID: group.groupID,
groupName: group.groupName,
memberCount: group.memberCount,
groupCreatedAt: group.createdAt,
};
})
);
});
}
getGroups();
});
return (
<Paper
sx={{
...theme.typography.body2,
padding: '2vh',
color: theme.palette.text.secondary,
flexGrow: 1,
height: '89vh',
margin: '2vh',
}}
>
<Typography variant='h6'>Groups</Typography>
<Box sx={{ overflowY: 'auto' }}>
{groups.map((group) => (
<GroupUnit group={group} />
))}
</Box>
</Paper>
);
}
export default JoinedOrgs;

View file

@ -23,7 +23,6 @@ app.use(express.static(path.join(__dirname, 'public')));
app.use(cors());
app.use('/api/auth', authRouter);
app.use('/api/group', groupRouter);
app.use('/api/org', orgRouter);
app.use(express.static(path.join(__dirname, '../client/build')));

View file

@ -1,26 +0,0 @@
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('Groups', {
groupID: {
type: Sequelize.UUID,
primaryKey: true,
},
groupName: {
type: Sequelize.STRING,
allowNull: false,
},
createdAt: {
type: Sequelize.DATE,
},
updatedAt: {
type: Sequelize.DATE,
},
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('Groups');
},
};

View file

@ -1,19 +0,0 @@
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.addColumn('Groups', 'ownerID', {
type: Sequelize.UUID,
references: {
model: 'Users',
key: 'userID',
},
onUpdate: 'CASCADE',
onDelete: 'SET NULL',
});
},
async down(queryInterface, Sequelize) {
await queryInterface.removeColumn('Groups', 'ownerID');
},
};

View file

@ -1,28 +0,0 @@
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('GroupMembers', {
groupID: {
type: Sequelize.UUID,
primaryKey: true,
},
ownerID: {
type: Sequelize.UUID,
primaryKey: true,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('GroupMembers');
},
};

View file

@ -1,39 +0,0 @@
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Group extends Model {
static associate(models) {
Group.belongsTo(models.User, {
as: 'groupOwner',
foreignKey: 'ownerID',
onDelete: 'CASCADE',
});
Group.belongsToMany(models.User, {
as: 'groupMembers',
through: 'GroupMembers',
foreignKey: 'groupID',
onDelete: 'CASCADE',
});
}
}
Group.init(
{
groupID: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
groupName: {
type: DataTypes.STRING,
allowNull: false,
},
createdAt: {
type: DataTypes.DATE,
},
},
{ sequelize }
);
return Group;
};

View file

@ -11,16 +11,6 @@ module.exports = (sequelize, DataTypes) => {
foreignKey: 'userID',
onDelete: 'CASCADE',
});
User.hasMany(models.Group, {
as: 'ownedGroups',
foreignKey: 'ownerID',
onDelete: 'CASCADE',
});
User.belongsToMany(models.Group, {
as: 'memberGroups',
through: 'groupUsers',
foreignKey: 'userID',
});
User.hasOne(models.Organization, {
as: 'ownedOrg',
foreignKey: 'ownerID',

View file

@ -1,20 +0,0 @@
const { User } = require('../../models/index');
async function AddGroupMember(req, res, next) {
const user = req.user;
const newUserID = req.body.newUserID;
const groupID = req.params.groupID;
const result = await user.getOwnedGroups({ where: { groupID: groupID } });
const newUser = await User.findByPk(newUserID);
if (result.length == 0) {
return res.status(500).send('No group exists with that id.');
}
await result[0].addGroupMember(newUser);
return res.send('User added to group.');
}
module.exports = AddGroupMember;

View file

@ -1,16 +0,0 @@
async function CreateGroup(req, res, next) {
const user = req.user;
const groupName = req.body.groupName;
if (!groupName) {
return res.status(400).send('Request missing required form fields.');
}
const group = await user.createOwnedGroup({
groupName: groupName,
});
return res.send(group);
}
module.exports = CreateGroup;

View file

@ -1,16 +0,0 @@
async function DeleteGroup(req, res, next) {
const user = req.user;
const groupID = req.params.groupID;
const result = await user.getOwnedGroups({ where: { groupID: groupID } });
if (!result) {
return res.status(400).send('You do not own a group with that ID.');
}
await result[0].destroy();
return res.send('Group deleted');
}
module.exports = DeleteGroup;

View file

@ -1,17 +0,0 @@
async function GetGroup(req, res, next) {
const user = req.user;
const groupID = req.params.groupID;
const result = await user.getOwnedGroups({
where: { groupID: groupID },
include: [{ association: 'groupMembers', required: false }],
});
if (result.length == 0) {
return res.status(500).send('No group exists with that id.');
}
return res.send(result[0]);
}
module.exports = GetGroup;

View file

@ -1,20 +0,0 @@
const { User } = require('../../models/index');
async function RemoveGroupMember(req, res, next) {
const user = req.user;
const doomedUserID = req.body.doomedUserID;
const groupID = req.params.groupID;
const result = await user.getOwnedGroups({ where: { groupID: groupID } });
const doomedUser = await User.findByPk(doomedUserID);
if (result.length == 0) {
return res.status(500).send('No group exists with that id.');
}
await result[0].removeGroupMember(doomedUser);
return res.send('User added to group.');
}
module.exports = RemoveGroupMember;

View file

@ -1,16 +0,0 @@
async function UpdateOrgDetails(req, res, next) {
const user = req.user;
const groupID = req.params.groupID;
const groupName = req.body.groupName;
if (!groupName) {
return res.status(400).send('Form missing required information.');
}
const result = await user.getOwnedGroups({ where: { groupID: groupID } });
await result[0].update({ groupName: groupName });
return res.send(result[0]);
}
module.exports = UpdateOrgDetails;

View file

@ -1,21 +0,0 @@
var express = require('express');
var router = express.Router();
const tokenAuth = require('../middleware/tokenAuth');
const checkKnownUser = require('../middleware/checkKnownUser');
const CreateGroup = require('./group/CreateGroup');
const DeleteGroup = require('./group/DeleteGroup');
const UpdateGroupDetails = require('./group/UpdateGroupDetails');
const GetGroup = require('./group/GetGroup');
const AddGroupMember = require('./group/AddGroupMember');
const RemoveGroupMember = require('./group/RemoveGroupMember');
router.post('/create', tokenAuth, CreateGroup);
router.delete('/:groupID/delete', tokenAuth, DeleteGroup);
router.patch('/:groupID/update', tokenAuth, UpdateGroupDetails);
router.get('/:groupID', tokenAuth, GetGroup);
router.post('/:groupID/add', tokenAuth, checkKnownUser, AddGroupMember);
router.post('/:groupID/remove', tokenAuth, RemoveGroupMember);
module.exports = router;