Fixed major bug with frontend not hissint correct routes
This commit is contained in:
parent
f2f962a37e
commit
a44f8a6503
22 changed files with 318 additions and 149 deletions
8
client/package-lock.json
generated
8
client/package-lock.json
generated
|
|
@ -17,7 +17,6 @@
|
|||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^0.26.0",
|
||||
"perfect-scrollbar": "^1.5.5",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^6.2.2",
|
||||
|
|
@ -10996,10 +10995,6 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/perfect-scrollbar": {
|
||||
"version": "1.5.5",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/performance-now": {
|
||||
"version": "2.1.0",
|
||||
"license": "MIT"
|
||||
|
|
@ -21663,9 +21658,6 @@
|
|||
"path-type": {
|
||||
"version": "4.0.0"
|
||||
},
|
||||
"perfect-scrollbar": {
|
||||
"version": "1.5.5"
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,46 +1,45 @@
|
|||
{
|
||||
"name": "client",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.8.1",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@mui/icons-material": "^5.4.4",
|
||||
"@mui/material": "^5.4.4",
|
||||
"@mui/x-data-grid": "^5.6.0",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^0.26.0",
|
||||
"perfect-scrollbar": "^1.5.5",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^6.2.2",
|
||||
"react-scripts": "5.0.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
"name": "client",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.8.1",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@mui/icons-material": "^5.4.4",
|
||||
"@mui/material": "^5.4.4",
|
||||
"@mui/x-data-grid": "^5.6.0",
|
||||
"@testing-library/jest-dom": "^5.16.2",
|
||||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^0.26.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^6.2.2",
|
||||
"react-scripts": "5.0.0",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<script>
|
||||
const ps = new PerfectScrollbar('root');
|
||||
</script>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ import EditUser from './components/forms/EditUser';
|
|||
import Recover from './components/forms/Recover';
|
||||
import Reset from './components/forms/Reset';
|
||||
|
||||
import JoinedOrgs from './components/orgs/JoinedOrgs';
|
||||
import OwnedOrgs from './components/orgs/OwnedOrgs';
|
||||
import MemberOrgs from './components/orgs/MemberOrgs';
|
||||
import OrgDashboard from './components/orgs/OrgDashboard';
|
||||
import UpdateOrganization from './components/forms/UpdateOrganization';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
|
@ -30,10 +32,16 @@ function App() {
|
|||
<Route path=':id' element={<Reset />} />
|
||||
</Route>
|
||||
|
||||
<Route path='org' element={<JoinedOrgs />} />
|
||||
<Route path='org' element={<OwnedOrgs />} />
|
||||
<Route path='joined'>
|
||||
<Route index element={<JoinedOrgs />} />
|
||||
<Route path=':id' element={<OrgDashboard />} />
|
||||
<Route index element={<MemberOrgs />} />
|
||||
<Route path=':id'>
|
||||
<Route index element={<OrgDashboard />} />
|
||||
<Route
|
||||
path='update'
|
||||
element={<UpdateOrganization />}
|
||||
/>
|
||||
</Route>
|
||||
</Route>
|
||||
|
||||
<Route path='*' element={<Navigate to='' />} />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
|
@ -18,22 +18,30 @@ import OrgUnit from './utils/OrgUnit';
|
|||
import StackItem from './utils/StackItem';
|
||||
|
||||
function MainPage() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [ownedOrgs, setOwnedOrgs] = useState([]);
|
||||
const [orgs, setOrgs] = useState([]);
|
||||
const [form, setForm] = useState({
|
||||
name: '',
|
||||
value: '',
|
||||
id: '',
|
||||
});
|
||||
|
||||
const linkStyle = { textDecoration: 'none', color: 'inherit' };
|
||||
|
||||
useEffect(() => {
|
||||
if (!Cookies.get('token')) {
|
||||
navigate('/login');
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
async function getOwnedOrgs() {
|
||||
await axios
|
||||
.get(
|
||||
`${process.env.DOMAIN_ROOT}/auth?token=${Cookies.get(
|
||||
'token'
|
||||
)}`
|
||||
`${
|
||||
process.env.REACT_APP_DOMAIN_ROOT
|
||||
}/auth?token=${Cookies.get('token')}`
|
||||
)
|
||||
.then((response) => {
|
||||
setOwnedOrgs(() =>
|
||||
|
|
@ -55,9 +63,9 @@ function MainPage() {
|
|||
async function getOrgs() {
|
||||
await axios
|
||||
.get(
|
||||
`${process.env.DOMAIN_ROOT}/auth/orgs?token=${Cookies.get(
|
||||
'token'
|
||||
)}`
|
||||
`${
|
||||
process.env.REACT_APP_DOMAIN_ROOT
|
||||
}/auth/orgs?token=${Cookies.get('token')}`
|
||||
)
|
||||
.then((response) => {
|
||||
setOrgs(() =>
|
||||
|
|
@ -84,6 +92,26 @@ function MainPage() {
|
|||
});
|
||||
}
|
||||
|
||||
async function joinOrg(e) {
|
||||
e.preventDefault();
|
||||
|
||||
await axios.post(`${process.env.REACT_APP_DOMAIN_ROOT}/org/create`, {
|
||||
token: Cookies.get('token'),
|
||||
orgName: form.name,
|
||||
});
|
||||
}
|
||||
|
||||
async function createOrg(e) {
|
||||
e.preventDefault();
|
||||
|
||||
await axios.post(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/org/${form.id}`,
|
||||
{
|
||||
token: Cookies.get('token'),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
|
|
@ -97,13 +125,13 @@ function MainPage() {
|
|||
<Grid item xs={10} sm={6} md={5}>
|
||||
<Stack spacing={2}>
|
||||
<StackItem text='Join an Organization'>
|
||||
<form>
|
||||
<form onSubmit={joinOrg}>
|
||||
<FormGroup row>
|
||||
<TextField
|
||||
id='standard-name'
|
||||
label='Organization ID'
|
||||
name='orgID'
|
||||
value={form.orgID}
|
||||
name='id'
|
||||
value={form.id}
|
||||
onChange={handleChange}
|
||||
sx={{ width: '75%' }}
|
||||
/>
|
||||
|
|
@ -120,7 +148,7 @@ function MainPage() {
|
|||
</form>
|
||||
</StackItem>
|
||||
<StackItem text='Create an Organization'>
|
||||
<form>
|
||||
<form onSubmit={createOrg}>
|
||||
<FormGroup row>
|
||||
<TextField
|
||||
id='standard-name'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Link, Outlet, useNavigate } from 'react-router-dom';
|
||||
import { Link, Outlet } from 'react-router-dom';
|
||||
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
|
@ -16,7 +16,6 @@ import MenuIcon from '@mui/icons-material/Menu';
|
|||
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
||||
|
||||
function Navbar() {
|
||||
const navigate = useNavigate();
|
||||
const [token, setToken] = useState('');
|
||||
|
||||
const linkStyle = { textDecoration: 'none', color: 'inherit' };
|
||||
|
|
@ -28,17 +27,15 @@ function Navbar() {
|
|||
|
||||
useEffect(() => {
|
||||
setToken(() => Cookies.get('token'));
|
||||
if (!token) {
|
||||
navigate('login');
|
||||
}
|
||||
}, [navigate, token]);
|
||||
}, []);
|
||||
|
||||
async function handleLogout() {
|
||||
await axios.post(`${process.env.DOMAIN_ROOT}/auth/logout`, {
|
||||
await axios.post(`${process.env.REACT_APP_DOMAIN_ROOT}/auth/logout`, {
|
||||
token: Cookies.get('token'),
|
||||
});
|
||||
Cookies.remove('token');
|
||||
Cookies.remove('userID');
|
||||
setToken(() => '');
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ function EditUser() {
|
|||
async function getInfo() {
|
||||
axios
|
||||
.get(
|
||||
`${process.env.DOMAIN_ROOT}/auth/${Cookies.get(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/auth/${Cookies.get(
|
||||
'userID'
|
||||
)}?token=${Cookies.get('token')}`
|
||||
)
|
||||
|
|
@ -59,7 +59,10 @@ function EditUser() {
|
|||
|
||||
const { confirmPassword, ...filteredForm } = form;
|
||||
await axios
|
||||
.post(`${process.env.DOMAIN_ROOT}/auth/register`, filteredForm)
|
||||
.post(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/auth/register`,
|
||||
filteredForm
|
||||
)
|
||||
.then(() => {
|
||||
navigate('/login');
|
||||
})
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ function Login() {
|
|||
if (Cookies.get('token')) {
|
||||
async function logout() {
|
||||
await axios
|
||||
.post(`${process.env.DOMAIN_ROOT}/auth/logout`, {
|
||||
.post(`${process.env.REACT_APP_DOMAIN_ROOT}/auth/logout`, {
|
||||
token: Cookies.get('token'),
|
||||
})
|
||||
.catch((e) => console.log(e));
|
||||
|
|
@ -38,7 +38,7 @@ function Login() {
|
|||
Cookies.remove('token');
|
||||
Cookies.remove('userID');
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
|
|
@ -61,7 +61,7 @@ function Login() {
|
|||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios
|
||||
.post(`${process.env.DOMAIN_ROOT}/auth/login`, form)
|
||||
.post(`${process.env.REACT_APP_DOMAIN_ROOT}/auth/login`, form)
|
||||
.then((response) => {
|
||||
Cookies.set('token', response.data.token, {
|
||||
expires: form.remember ? 3650 : 1,
|
||||
|
|
|
|||
|
|
@ -24,7 +24,9 @@ function Recover() {
|
|||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios
|
||||
.get(`${process.env.DOMAIN_ROOT}/auth/reset-password?${form.email}`)
|
||||
.get(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/auth/reset-password?${form.email}`
|
||||
)
|
||||
.then((response) => {
|
||||
setSuccess(() => response.data);
|
||||
})
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ function Register() {
|
|||
|
||||
const { confirmPassword, ...filteredForm } = form;
|
||||
await axios
|
||||
.post(`${process.env.DOMAIN_ROOT}/auth/register`, filteredForm)
|
||||
.post(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/auth/register`,
|
||||
filteredForm
|
||||
)
|
||||
.then(() => {
|
||||
navigate('/login');
|
||||
})
|
||||
|
|
|
|||
|
|
@ -29,9 +29,12 @@ function Reset() {
|
|||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios
|
||||
.patch(`${process.env.DOMAIN_ROOT}/auth/reset-password/${id}`, {
|
||||
password: form.password,
|
||||
})
|
||||
.patch(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/auth/reset-password/${id}`,
|
||||
{
|
||||
password: form.password,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
navigate('/login');
|
||||
})
|
||||
|
|
|
|||
60
client/src/components/forms/UpdateOrganization.jsx
Normal file
60
client/src/components/forms/UpdateOrganization.jsx
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
import { Typography, TextField, Button } from '@mui/material';
|
||||
|
||||
import Form from '../utils/Form';
|
||||
|
||||
function UpdateOrganization() {
|
||||
const { orgID } = useParams();
|
||||
|
||||
const [name, setName] = useState('');
|
||||
|
||||
function handleChange(e) {
|
||||
const value = e.target.value;
|
||||
|
||||
setName(() => value);
|
||||
}
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios.patch(`${process.env.REACT_APP_DOMAIN_ROOT}/org/update`, {
|
||||
orgName: name,
|
||||
orgID,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Form>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Typography variant='h4' sx={{ marginTop: '1vh 0vh' }}>
|
||||
Rename Organization
|
||||
</Typography>
|
||||
<TextField
|
||||
required
|
||||
fullWidth
|
||||
id='outline-required'
|
||||
label='name'
|
||||
name='name'
|
||||
variant='outlined'
|
||||
onChange={handleChange}
|
||||
value={name}
|
||||
sx={{ margin: '1vh 0vh' }}
|
||||
/>
|
||||
<Button
|
||||
variant='contained'
|
||||
color='primary'
|
||||
sx={{ margin: '1vh 0vh' }}
|
||||
type='submit'
|
||||
fullWidth
|
||||
>
|
||||
Rename
|
||||
</Button>
|
||||
</form>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
export default UpdateOrganization;
|
||||
|
|
@ -9,9 +9,9 @@ function JoinedOrgs() {
|
|||
async function getOrgs(setOrgs) {
|
||||
axios
|
||||
.get(
|
||||
`${process.env.DOMAIN_ROOT}/auth/orgs?token=${Cookies.get(
|
||||
'token'
|
||||
)}`
|
||||
`${
|
||||
process.env.REACT_APP_DOMAIN_ROOT
|
||||
}/auth/orgs?token=${Cookies.get('token')}`
|
||||
)
|
||||
.then((response) => {
|
||||
setOrgs(() =>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useNavigate, useParams, Link } from 'react-router-dom';
|
||||
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
|
@ -19,26 +19,19 @@ function OrgDashboard() {
|
|||
const { orgID } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [org, setOrg] = useState({
|
||||
orgID: '',
|
||||
orgName: '',
|
||||
orgOwner: {
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
},
|
||||
orgMembers: [],
|
||||
createdAt: '',
|
||||
});
|
||||
|
||||
const [org, setOrg] = useState({});
|
||||
const [rows, setRows] = useState([]);
|
||||
const [status, setStatus] = useState('');
|
||||
const [selection, setSelection] = useState();
|
||||
|
||||
const linkStyle = { textDecoration: 'none', color: 'inherit' };
|
||||
|
||||
useEffect(() => {
|
||||
async function getData() {
|
||||
await axios
|
||||
.get(
|
||||
`${
|
||||
process.env.DOMAIN_ROOT
|
||||
process.env.REACT_APP_DOMAIN_ROOT
|
||||
}/org/${orgID}?token=${Cookies.get('token')}`
|
||||
)
|
||||
.then((response) => {
|
||||
|
|
@ -59,18 +52,15 @@ function OrgDashboard() {
|
|||
|
||||
const orgMembers = res.orgMembers.map((member, index) => {
|
||||
return {
|
||||
id: index,
|
||||
firstName: member.firstName,
|
||||
lastName: member.lastName,
|
||||
nickname: member.nickname,
|
||||
namePronounciation: member.pronounciation,
|
||||
pronouns: member.pronouns,
|
||||
email: member.email,
|
||||
id: member.userID,
|
||||
...member,
|
||||
};
|
||||
});
|
||||
setRows(() => orgMembers);
|
||||
|
||||
setStatus(() => res.status);
|
||||
})
|
||||
.catch((error) => {
|
||||
.catch(() => {
|
||||
navigate('/');
|
||||
});
|
||||
}
|
||||
|
|
@ -78,8 +68,46 @@ function OrgDashboard() {
|
|||
getData();
|
||||
});
|
||||
|
||||
async function handleDelete() {
|
||||
await axios
|
||||
.delete(`${process.env.REACT_APP_DOMAIN_ROOT}/org/delete`, {
|
||||
params: {
|
||||
token: Cookies.get('token'),
|
||||
orgID,
|
||||
},
|
||||
})
|
||||
.then(navigate(''));
|
||||
}
|
||||
|
||||
function copyID() {
|
||||
navigator.clipboard.writeText(orgID);
|
||||
}
|
||||
|
||||
async function removeSelected() {
|
||||
const doomedUserIDs = selection.map((row) => row.id);
|
||||
|
||||
await axios.post(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/org/${orgID}/delete`,
|
||||
{
|
||||
token: Cookies.get('token'),
|
||||
orgID,
|
||||
doomedUserIDs,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function leaveOrg() {
|
||||
await axios.post(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/org/${orgID}/delete`,
|
||||
{
|
||||
token: Cookies.get('token'),
|
||||
orgID,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Dashboard rows={rows}>
|
||||
<Dashboard rows={rows} setSelection={setSelection}>
|
||||
<Typography variant='h6'>Organizations/{org.orgName}</Typography>
|
||||
<Box sx={{ marginTop: '1vh' }}>
|
||||
<Grid container columns={{ xs: 3, md: 12 }}>
|
||||
|
|
@ -116,25 +144,48 @@ function OrgDashboard() {
|
|||
xs
|
||||
>
|
||||
<Stack spacing={2} alignItems='flex-end'>
|
||||
<ButtonGroup
|
||||
variant='outlined'
|
||||
aria-label='outlined button group'
|
||||
>
|
||||
<Button color='warning'>
|
||||
Edit {org.orgName}
|
||||
{status && (
|
||||
<React.Fragment>
|
||||
<ButtonGroup
|
||||
variant='outlined'
|
||||
aria-label='outlined button group'
|
||||
>
|
||||
<Button color='warning'>
|
||||
<Link to='update' style={linkStyle}>
|
||||
Edit {org.orgName}
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
color='error'
|
||||
onClick={handleDelete}
|
||||
>
|
||||
Delete {org.orgName}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup
|
||||
variant='outlined'
|
||||
aria-label='outlined button group'
|
||||
>
|
||||
<Button
|
||||
color='success'
|
||||
onClick={copyID}
|
||||
>
|
||||
Copy Org ID
|
||||
</Button>
|
||||
<Button
|
||||
color='error'
|
||||
onClick={removeSelected}
|
||||
>
|
||||
Remove People
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{!status && (
|
||||
<Button color='error' onClick={leaveOrg}>
|
||||
Leave Org
|
||||
</Button>
|
||||
<Button color='error'>
|
||||
Delete {org.orgName}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
<ButtonGroup
|
||||
variant='outlined'
|
||||
aria-label='outlined button group'
|
||||
>
|
||||
<Button color='primary'>Refresh</Button>
|
||||
<Button color='success'>Add People</Button>
|
||||
<Button color='error'>Remove People</Button>
|
||||
</ButtonGroup>
|
||||
)}
|
||||
</Stack>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ function JoinedOrgs() {
|
|||
async function getOrgs(setOrgs) {
|
||||
axios
|
||||
.get(
|
||||
`${process.env.DOMAIN_ROOT}/auth?token=${Cookies.get('token')}`
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/auth?token=${Cookies.get(
|
||||
'token'
|
||||
)}`
|
||||
)
|
||||
.then((response) => {
|
||||
setOrgs(() =>
|
||||
|
|
@ -6,7 +6,7 @@ import { useTheme } from '@mui/material/styles';
|
|||
import { DataGrid } from '@mui/x-data-grid';
|
||||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||
|
||||
function Dashboard({ children, rows }) {
|
||||
function Dashboard({ children, rows, setSelection }) {
|
||||
const theme = useTheme();
|
||||
|
||||
const columns = [
|
||||
|
|
@ -69,6 +69,9 @@ function Dashboard({ children, rows }) {
|
|||
columns={columns}
|
||||
pageSize={5}
|
||||
rowsPerPageOptions={[5]}
|
||||
onSelectionModelChange={(newSelection) => {
|
||||
setSelection(newSelection.rows);
|
||||
}}
|
||||
checkboxSelection
|
||||
/>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ module.exports = (sequelize, DataTypes) => {
|
|||
onDelete: 'CASCADE',
|
||||
});
|
||||
User.hasMany(models.Organization, {
|
||||
as: 'ownedOrgs',
|
||||
as: 'ownedOrg',
|
||||
foreignKey: 'ownerID',
|
||||
onDelete: 'CASCADE',
|
||||
});
|
||||
User.belongsToMany(models.Organization, {
|
||||
as: 'memberOrgs',
|
||||
as: 'memberOrg',
|
||||
through: 'orgUsers',
|
||||
foreignKey: 'userID',
|
||||
onDelete: 'CASCADE',
|
||||
|
|
|
|||
|
|
@ -6,8 +6,11 @@ async function CreateOrg(req, res, next) {
|
|||
return res.status(400).send('Form missing necessary fields');
|
||||
}
|
||||
|
||||
const existing = await user.getOwnedOrgs();
|
||||
if (existing.map((org) => org.orgName).includes(orgName)) {
|
||||
console.log(user);
|
||||
const existing = await user.countOwnedOrg({
|
||||
where: { orgName: orgName },
|
||||
});
|
||||
if (existing > 0) {
|
||||
return res
|
||||
.status(500)
|
||||
.send(
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
async function DeleteOrg(req, res, next) {
|
||||
const user = req.user;
|
||||
const orgID = req.query.orgID;
|
||||
|
||||
const result = await user.getOwnedOrg();
|
||||
await result.destroy();
|
||||
await user.removeOwnedOrg({ where: { orgID: orgID } });
|
||||
|
||||
return res.send('Organization deleted');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,15 @@ async function GetOrg(req, res, next) {
|
|||
include: [
|
||||
{
|
||||
association: 'orgOwner',
|
||||
attributes: { exclude: ['password', 'createdAt', 'updatedAt'] },
|
||||
attributes: {
|
||||
exclude: ['userID', 'password', 'createdAt', 'updatedAt'],
|
||||
},
|
||||
},
|
||||
{
|
||||
association: 'orgMembers',
|
||||
attributes: { exclude: ['password', 'createdAt', 'updatedAt'] },
|
||||
attributes: {
|
||||
exclude: ['password', 'createdAt', 'updatedAt'],
|
||||
},
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -1,18 +1,31 @@
|
|||
const { Organization } = require('../../models/index');
|
||||
|
||||
async function AddOrgMember(req, res, next) {
|
||||
async function RemoveOrgMember(req, res, next) {
|
||||
const user = req.user;
|
||||
const orgID = req.params.orgID;
|
||||
const doomedUserIDs = req.body.doomedUsers;
|
||||
|
||||
const result = await Organization.findOne({ where: { orgID: orgID } });
|
||||
const result = await Organization.findByPk(orgID, {
|
||||
include: { association: 'orgOwner' },
|
||||
});
|
||||
|
||||
if (!result) {
|
||||
return res.status(500).send('No organization exists with that id.');
|
||||
}
|
||||
|
||||
await result.removeOrgMember(user);
|
||||
if (!doomedUserIDs) {
|
||||
await result.removeOrgMember({ where: { userID: user.userID } });
|
||||
} else {
|
||||
if (user.userID == result.orgOwner.userID) {
|
||||
await result.removeOrgMembers({
|
||||
where: { userID: { [Op.in]: doomedUserIDs } },
|
||||
});
|
||||
} else {
|
||||
res.status(403).send('You do not have permission to do that.');
|
||||
}
|
||||
}
|
||||
|
||||
return res.send('User removed from organization.');
|
||||
return res.send('User(s) removed from organization.');
|
||||
}
|
||||
|
||||
module.exports = AddOrgMember;
|
||||
module.exports = RemoveOrgMember;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
async function UpdateOrgDetails(req, res, next) {
|
||||
const user = req.user;
|
||||
const orgName = req.body.orgName;
|
||||
const orgID = req.body.orgID;
|
||||
|
||||
if (!orgName) {
|
||||
return res.status(400).send('Form missing required information.');
|
||||
}
|
||||
|
||||
const result = await user.getOwnedOrg();
|
||||
result.update({ orgName: orgName });
|
||||
const result = await user.getOwnedOrgs({ where: { orgID: orgID } });
|
||||
result[0].update({ orgName: orgName });
|
||||
|
||||
return res.send(result);
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue