Brought app up to modern standards
This commit is contained in:
parent
9e8e074181
commit
f6c739bfe1
50 changed files with 812 additions and 794 deletions
|
|
@ -12,6 +12,7 @@
|
|||
"@testing-library/react": "^12.1.3",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^0.26.1",
|
||||
"buffer": "^6.0.3",
|
||||
"js-cookie": "^3.0.1",
|
||||
"mic-recorder-to-mp3": "^2.2.2",
|
||||
"react": "^17.0.2",
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
||||
|
||||
import { Layout } from './containers';
|
||||
import {
|
||||
Layout,
|
||||
Login,
|
||||
Register,
|
||||
MainPage,
|
||||
EditUser,
|
||||
Recover,
|
||||
Reset,
|
||||
OwnedOrgs,
|
||||
MemberOrgs,
|
||||
OrgDashboard,
|
||||
} from './containers';
|
||||
import { ContextProvider } from './contexts';
|
||||
import MainPage from './controllers/MainPage';
|
||||
|
||||
import Form from './components/Form';
|
||||
import Login from './controllers/Login';
|
||||
import Register from './controllers/Register';
|
||||
import EditUser from './controllers/EditUser';
|
||||
import Recover from './controllers/Recover';
|
||||
import Reset from './controllers/Reset';
|
||||
|
||||
import OwnedOrgs from './controllers/OwnedOrgs';
|
||||
import MemberOrgs from './controllers/MemberOrgs';
|
||||
import OrgDashboard from './controllers/OrgDashboard';
|
||||
import UpdateOrganization from './controllers/UpdateOrganization';
|
||||
import UpdateOrganization from './controllers/UpdateOrganizationFormController';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
|
@ -22,24 +22,24 @@ function App() {
|
|||
<ContextProvider>
|
||||
<Routes>
|
||||
<Route path='' element={<Layout />}>
|
||||
{/* <Route index element={<MainPage />} /> */}
|
||||
<Route index element={<MainPage />} />
|
||||
|
||||
<Route path='/login' element={<Login />} />
|
||||
<Route path='/register' element={<Register />} />
|
||||
{/* <Route path='update' element={<EditUser />} /> */}
|
||||
{/* <Route path='recover' element={<Form />}>
|
||||
<Route path='/update' element={<EditUser />} />
|
||||
<Route path='recover'>
|
||||
<Route index element={<Recover />} />
|
||||
<Route path=':id' element={<Reset />} />
|
||||
</Route> */}
|
||||
</Route>
|
||||
|
||||
{/* <Route path='org'>
|
||||
<Route path='org'>
|
||||
<Route index element={<OwnedOrgs />} />
|
||||
<Route path='joined' element={<MemberOrgs />} />
|
||||
<Route path=':orgID'>
|
||||
<Route index element={<OrgDashboard />} />
|
||||
<Route path='update' element={<UpdateOrganization />} />
|
||||
</Route>
|
||||
</Route> */}
|
||||
</Route>
|
||||
|
||||
<Route path='*' element={<Navigate to='' />} />
|
||||
</Route>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {
|
||||
Accordion,
|
||||
|
|
@ -18,11 +17,13 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
|||
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
|
||||
import { DataGrid } from '@mui/x-data-grid';
|
||||
|
||||
import MemberUnit from './MemberUnit';
|
||||
import { MemberUnit } from '.';
|
||||
import { DynamicPaper, DynamicStack } from './StyledElements';
|
||||
|
||||
function Dashboard({
|
||||
rows,
|
||||
open,
|
||||
handleOpen,
|
||||
setSelection,
|
||||
onClick,
|
||||
org,
|
||||
|
|
@ -37,8 +38,6 @@ function Dashboard({
|
|||
const sm = useMediaQuery((theme) => theme.breakpoints.only('sm'));
|
||||
const md = useMediaQuery((theme) => theme.breakpoints.only('md'));
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const linkStyle = { textDecoration: 'none', color: 'inherit' };
|
||||
const columns = [
|
||||
{ field: 'id', headerName: 'ID', flex: 1 },
|
||||
|
|
@ -67,10 +66,6 @@ function Dashboard({
|
|||
{ field: 'email', headerName: 'Email', flex: 10, sortable: false },
|
||||
];
|
||||
|
||||
function handleOpen() {
|
||||
setOpen((initial) => (initial ? false : true));
|
||||
}
|
||||
|
||||
const buttonGroupOrientation = () => {
|
||||
if (xs) return 'vertical';
|
||||
};
|
||||
|
|
@ -86,25 +81,19 @@ function Dashboard({
|
|||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<Box sx={{ padding: '2vh' }}>
|
||||
<Accordion expanded={open} onChange={handleOpen}>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant='h6'>
|
||||
Organizations/{org.name}
|
||||
</Typography>
|
||||
<Typography variant='h6'>Organizations / {org.name}</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Box sx={{ marginTop: '1vh' }} fullWidth>
|
||||
<Grid
|
||||
container
|
||||
columns={{ xs: 3, sm: 12, md: 12 }}
|
||||
spacing={1}
|
||||
>
|
||||
<Grid container columns={{ xs: 3, sm: 12, md: 12 }} spacing={1}>
|
||||
<Grid item xs={3}>
|
||||
<Stack>
|
||||
<Typography variant='body1'>
|
||||
Organization ID: {org.orgID}
|
||||
Organization ID: {org.id}
|
||||
</Typography>
|
||||
<Typography variant='body1'>
|
||||
Members: {org.memberCount}
|
||||
|
|
@ -117,8 +106,7 @@ function Dashboard({
|
|||
<Grid item xs={3}>
|
||||
<Stack>
|
||||
<Typography variant='body1'>
|
||||
Owner:{' '}
|
||||
{`${org.owner.firstName} ${org.owner.lastName}`}
|
||||
Owner: {`${org.owner.firstName} ${org.owner.lastName}`}
|
||||
</Typography>
|
||||
<Typography variant='body1'>
|
||||
Email: {org.owner.email}
|
||||
|
|
@ -128,23 +116,17 @@ function Dashboard({
|
|||
<Grid item xs={3} sm={6} md={6}>
|
||||
<DynamicStack spacing={1}>
|
||||
{status ? (
|
||||
<React.Fragment>
|
||||
<>
|
||||
<ButtonGroup
|
||||
variant='outlined'
|
||||
orientation={buttonGroupOrientation()}
|
||||
>
|
||||
<Button color='warning'>
|
||||
<Link
|
||||
to='update'
|
||||
style={linkStyle}
|
||||
>
|
||||
<Link to='update' style={linkStyle}>
|
||||
Edit {org.name}
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
color='error'
|
||||
onClick={handleDelete}
|
||||
>
|
||||
<Button color='error' onClick={handleDelete}>
|
||||
Delete {org.name}
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
|
|
@ -152,31 +134,19 @@ function Dashboard({
|
|||
variant='outlined'
|
||||
orientation={buttonGroupOrientation()}
|
||||
>
|
||||
<Button
|
||||
color='success'
|
||||
onClick={copyID}
|
||||
>
|
||||
<Button color='success' onClick={copyID}>
|
||||
Copy Org ID
|
||||
</Button>
|
||||
<Button
|
||||
color='success'
|
||||
onClick={copyJoinLink}
|
||||
>
|
||||
<Button color='success' onClick={copyJoinLink}>
|
||||
Copy Org Join Link
|
||||
</Button>
|
||||
<Button
|
||||
color='error'
|
||||
onClick={removeSelected}
|
||||
>
|
||||
<Button color='error' onClick={removeSelected}>
|
||||
Remove People
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</React.Fragment>
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
color='error'
|
||||
onClick={leaveOrg}
|
||||
>
|
||||
<Button color='error' onClick={leaveOrg}>
|
||||
Leave Org
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -187,16 +157,11 @@ function Dashboard({
|
|||
</AccordionDetails>
|
||||
</Accordion>
|
||||
</Box>
|
||||
<Collapse
|
||||
collapsedSize={calculateCollapsedSize()}
|
||||
in={open ? false : true}
|
||||
>
|
||||
<Collapse collapsedSize={calculateCollapsedSize()} in={open ? false : true}>
|
||||
<DynamicPaper>
|
||||
{(xs || sm) &&
|
||||
rows.map((member) => {
|
||||
return (
|
||||
<MemberUnit member={member} onClick={onClick} />
|
||||
);
|
||||
return <MemberUnit member={member} onClick={onClick} />;
|
||||
})}
|
||||
{md && (
|
||||
<Box height={calculateTableHeight()}>
|
||||
|
|
@ -214,7 +179,7 @@ function Dashboard({
|
|||
)}
|
||||
</DynamicPaper>
|
||||
</Collapse>
|
||||
</React.Fragment>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import React from 'react';
|
|||
import { Link } from 'react-router-dom';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
|
||||
import Form from './Form';
|
||||
import RecordMp3 from './RecordMp3';
|
||||
import { Form } from '.';
|
||||
import { RecordMp3 } from '../controllers';
|
||||
import { FormSubmit, FormTextField } from './StyledElements';
|
||||
|
||||
function EditUserForm({ form, error, handleSubmit, handleChange }) {
|
||||
|
|
|
|||
|
|
@ -1,22 +1,17 @@
|
|||
import React from 'react';
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import { Box, Grid, Paper, Typography } from '@mui/material';
|
||||
import { Box, Grid, Card, Typography, CardContent, Alert } from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
function Form({ children, text }) {
|
||||
function Form({ children, text, error }) {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
alignItems='center'
|
||||
style={{ height: '95vh' }}
|
||||
>
|
||||
<Grid container spacing={2} alignItems='center' style={{ height: '95vh' }}>
|
||||
<Grid item xs={0.5} sm={2} md={4} />
|
||||
<Grid item xs={11} sm={8} md={4}>
|
||||
<Paper
|
||||
<Card
|
||||
sx={{
|
||||
...theme.typography.body2,
|
||||
padding: '2vh',
|
||||
|
|
@ -24,17 +19,20 @@ function Form({ children, text }) {
|
|||
color: theme.palette.text.secondary,
|
||||
}}
|
||||
>
|
||||
{text && (
|
||||
<Typography
|
||||
variant='h4'
|
||||
sx={{ marginTop: '1vh 0vh' }}
|
||||
>
|
||||
{text}
|
||||
</Typography>
|
||||
)}
|
||||
{children}
|
||||
<Outlet />
|
||||
</Paper>
|
||||
<CardContent>
|
||||
{text && (
|
||||
<Typography
|
||||
variant='h5'
|
||||
sx={{ margin: '1vh 0vh', fontWeight: 'bold' }}
|
||||
>
|
||||
{text}
|
||||
</Typography>
|
||||
)}
|
||||
{children}
|
||||
<Outlet />
|
||||
{error && <Alert severity='error'>{error}</Alert>}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
<Grid item xs={0.5} sm={2} md={4} />
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -1,17 +1,14 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Box, Checkbox, FormControlLabel, Typography } from '@mui/material';
|
||||
import { Checkbox, FormControlLabel, Typography } from '@mui/material';
|
||||
|
||||
import Form from './Form';
|
||||
import { Form } from '.';
|
||||
import { FormSubmit, FormTextField } from './StyledElements';
|
||||
|
||||
function Login({ form, error, handleSubmit, handleChange, handleCheckboxChange }) {
|
||||
function Login({ form, handleSubmit, handleChange, handleCheckboxChange, error }) {
|
||||
return (
|
||||
<Form>
|
||||
<Form text='Login' error={error}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Typography variant='h5' sx={{ margin: '1vh 0vh', fontWeight: 'bold' }}>
|
||||
Login
|
||||
</Typography>
|
||||
<FormTextField
|
||||
required
|
||||
label='Email'
|
||||
|
|
@ -42,13 +39,6 @@ function Login({ form, error, handleSubmit, handleChange, handleCheckboxChange }
|
|||
onChange={handleCheckboxChange}
|
||||
/>
|
||||
</div>
|
||||
{error && (
|
||||
<Box textAlign='right'>
|
||||
<Typography variant='body2' color='error'>
|
||||
{error}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
<FormSubmit color='primary' type='submit'>
|
||||
Login
|
||||
</FormSubmit>
|
||||
|
|
|
|||
|
|
@ -6,24 +6,12 @@ import OrgUnit from './OrgUnit';
|
|||
import StackItem from './StackItem';
|
||||
import { Form, FormButton, FormField } from './StyledElements';
|
||||
|
||||
function MainPageBase({
|
||||
form,
|
||||
orgs,
|
||||
ownedOrgs,
|
||||
joinOrg,
|
||||
createOrg,
|
||||
handleChange,
|
||||
}) {
|
||||
function MainPageBase({ form, orgs, ownedOrgs, joinOrg, createOrg, handleChange }) {
|
||||
const linkStyle = { textDecoration: 'none', color: 'inherit' };
|
||||
|
||||
return (
|
||||
<Box sx={{ flexGrow: 1 }}>
|
||||
<Grid
|
||||
container
|
||||
spacing={2}
|
||||
alignItems='center'
|
||||
style={{ height: '95vh' }}
|
||||
>
|
||||
<Grid container spacing={2} alignItems='center' style={{ height: '95vh' }}>
|
||||
<Grid item xs={0.5} sm={2} md={4} />
|
||||
<Grid item xs={11} sm={8} md={4}>
|
||||
<Stack spacing={2}>
|
||||
|
|
@ -36,10 +24,7 @@ function MainPageBase({
|
|||
value={form.id}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<FormButton
|
||||
type='submit'
|
||||
variant='outlined'
|
||||
>
|
||||
<FormButton type='submit' variant='outlined'>
|
||||
Join Organization
|
||||
</FormButton>
|
||||
</Form>
|
||||
|
|
@ -54,10 +39,7 @@ function MainPageBase({
|
|||
value={form.name}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<FormButton
|
||||
type='submit'
|
||||
variant='outlined'
|
||||
>
|
||||
<FormButton type='submit' variant='outlined'>
|
||||
Create Organization
|
||||
</FormButton>
|
||||
</Form>
|
||||
|
|
@ -76,7 +58,7 @@ function MainPageBase({
|
|||
)}
|
||||
|
||||
{ownedOrgs.map((org) => (
|
||||
<OrgUnit org={org} />
|
||||
<OrgUnit org={org} key={org.id} />
|
||||
))}
|
||||
</StackItem>
|
||||
<StackItem>
|
||||
|
|
@ -92,7 +74,7 @@ function MainPageBase({
|
|||
)}
|
||||
|
||||
{orgs.map((org) => (
|
||||
<OrgUnit org={org} />
|
||||
<OrgUnit org={org} key={org.id} />
|
||||
))}
|
||||
</StackItem>
|
||||
</Stack>
|
||||
|
|
|
|||
|
|
@ -1,22 +1,26 @@
|
|||
import DarkModeIcon from '@mui/icons-material/DarkMode';
|
||||
import LightModeIcon from '@mui/icons-material/LightMode';
|
||||
import MailIcon from '@mui/icons-material/Mail';
|
||||
import MenuIcon from '@mui/icons-material/Menu';
|
||||
import { AppBar, Box, Button, IconButton, Toolbar, Typography } from '@mui/material';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export default function Navbar({ logout, userData, mode, toggleMode }) {
|
||||
function NavbarControls() {
|
||||
return userData.username ? (
|
||||
<Button
|
||||
color='inherit'
|
||||
component={Link}
|
||||
to='/login'
|
||||
onClick={logout}
|
||||
sx={{ margin: '0 1vh' }}
|
||||
>
|
||||
Logout
|
||||
</Button>
|
||||
return userData.email ? (
|
||||
<>
|
||||
<Button color='inherit' component={Link} to='/update'>
|
||||
Account
|
||||
</Button>
|
||||
<Button
|
||||
color='inherit'
|
||||
component={Link}
|
||||
to='/login'
|
||||
onClick={logout}
|
||||
sx={{ margin: '0 1vh' }}
|
||||
>
|
||||
Logout
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Button color='inherit' component={Link} to='/login'>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import {
|
||||
Accordion,
|
||||
AccordionDetails,
|
||||
AccordionSummary,
|
||||
Typography,
|
||||
} from '@mui/material';
|
||||
import { Accordion, AccordionDetails, AccordionSummary, Typography } from '@mui/material';
|
||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
|
||||
|
||||
function OrgUnit({ org }) {
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ import React from 'react';
|
|||
import { Box, Paper, Typography } from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
import OrgUnit from './OrgUnit';
|
||||
import { OrgUnit } from '.';
|
||||
|
||||
function Organizations({ orgs }) {
|
||||
function OrganizationList({ orgs }) {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
|
|
@ -29,4 +29,4 @@ function Organizations({ orgs }) {
|
|||
);
|
||||
}
|
||||
|
||||
export default Organizations;
|
||||
export default OrganizationList;
|
||||
|
|
@ -1,107 +1,10 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
import MicRecorder from 'mic-recorder-to-mp3';
|
||||
import Mic from '@mui/icons-material/Mic';
|
||||
import PlayArrow from '@mui/icons-material/PlayArrow';
|
||||
import SaveAs from '@mui/icons-material/SaveAs';
|
||||
import Upload from '@mui/icons-material/Upload';
|
||||
import { IconButton } from '@mui/material';
|
||||
|
||||
function RecordMp3() {
|
||||
const [recorder] = useState(
|
||||
new MicRecorder({
|
||||
bitRate: 128,
|
||||
})
|
||||
);
|
||||
const [recording, setRecording] = useState(false);
|
||||
const [uploadedFile, setUploadedFile] = useState(null);
|
||||
const [audio, setAudio] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
axios
|
||||
.get(
|
||||
`${
|
||||
process.env.REACT_APP_DOMAIN_ROOT
|
||||
}/public/audio/${Cookies.get('userID')}.mp3`,
|
||||
{
|
||||
responseType: 'blob',
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
setUploadedFile(() => {
|
||||
// Retrieve audio file of user if exists
|
||||
return new File([res.data], 'userAudio.mp3', {
|
||||
type: res.data.type,
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
|
||||
function togglePlay() {
|
||||
if (audio && !audio.ended) {
|
||||
// Reset audio and reset if track is playing
|
||||
audio.pause();
|
||||
audio.currentTime = 0;
|
||||
setAudio(() => null);
|
||||
} else {
|
||||
// Set audio to file and play
|
||||
const audioFile = new Audio(URL.createObjectURL(uploadedFile));
|
||||
setAudio(() => audioFile);
|
||||
audioFile.play();
|
||||
}
|
||||
}
|
||||
|
||||
function record() {
|
||||
if (recording) {
|
||||
// Stop recording then set uploaded file to mp3 instance
|
||||
setRecording(() => false);
|
||||
recorder
|
||||
.stop()
|
||||
.getMp3()
|
||||
.then(([buffer, blob]) => {
|
||||
setUploadedFile(() => {
|
||||
return new File(buffer, 'userAudio.mp3', {
|
||||
type: blob.type,
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Start recording
|
||||
setRecording(() => true);
|
||||
recorder.start().catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function uploadRecord() {
|
||||
setUploadedFile(() => {
|
||||
return document.getElementById('icon-button-file').files[0];
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Create form data object and attach file and user token
|
||||
var formData = new FormData();
|
||||
formData.append('audioFile', uploadedFile, 'userAudio.mp3');
|
||||
formData.append('token', Cookies.get('token'));
|
||||
|
||||
await axios.post(
|
||||
`${process.env.REACT_APP_API_ROOT}/auth/audio`,
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function RecordMp3({ togglePlay, record, uploadRecord, handleSubmit }) {
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<IconButton onClick={togglePlay}>
|
||||
|
|
|
|||
|
|
@ -1,39 +1,22 @@
|
|||
import React from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
|
||||
import { Form } from '.';
|
||||
import { FormSubmit, FormTextField } from './StyledElements';
|
||||
|
||||
function RecoverForm({ form, error, success, handleSubmit, handleChange }) {
|
||||
function RecoverForm({ form, error, handleSubmit, handleChange }) {
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Typography variant='h4' sx={{ marginTop: '1vh 0vh' }}>
|
||||
Recover my Password
|
||||
</Typography>
|
||||
<FormTextField
|
||||
required
|
||||
label='Email'
|
||||
name='email'
|
||||
onChange={handleChange}
|
||||
value={form.email}
|
||||
/>
|
||||
{error && (
|
||||
<Box textAlign='right'>
|
||||
<Typography variant='body2' color='error'>
|
||||
{error}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
{success && (
|
||||
<Box textAlign='right'>
|
||||
<Typography variant='body2' color='primary'>
|
||||
{success}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
<FormSubmit color='primary' type='submit'>
|
||||
Recover my password
|
||||
</FormSubmit>
|
||||
</form>
|
||||
<Form text='Recover Password' error={error}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<FormTextField
|
||||
required
|
||||
label='Email'
|
||||
name='email'
|
||||
onChange={handleChange}
|
||||
value={form.email}
|
||||
/>
|
||||
<FormSubmit color='primary' type='submit'>
|
||||
Recover my password
|
||||
</FormSubmit>
|
||||
</form>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { FormSubmit, FormTextField } from './StyledElements';
|
|||
|
||||
function RegisterForm({ form, handleSubmit, handleChange, error }) {
|
||||
return (
|
||||
<Form text='Create an Account'>
|
||||
<Form text='Create an Account' error={error}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<FormTextField
|
||||
required
|
||||
|
|
@ -52,13 +52,6 @@ function RegisterForm({ form, handleSubmit, handleChange, error }) {
|
|||
value={form.confirmPassword}
|
||||
other={{ type: 'password' }}
|
||||
/>
|
||||
{error && (
|
||||
<Box textAlign='right'>
|
||||
<Typography variant='body2' color='secondary'>
|
||||
{error}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
<FormSubmit
|
||||
color='primary'
|
||||
type='submit'
|
||||
|
|
|
|||
|
|
@ -1,45 +1,35 @@
|
|||
import React from 'react';
|
||||
import { Box, Typography } from '@mui/material';
|
||||
|
||||
import { Form } from '.';
|
||||
import { FormSubmit, FormTextField } from './StyledElements';
|
||||
|
||||
function ResetForm({ form, handleSubmit, handleChange, error }) {
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Typography variant='h4' sx={{ marginTop: '1vh 0vh' }}>
|
||||
Reset my Password
|
||||
</Typography>
|
||||
<FormTextField
|
||||
required
|
||||
label='Password'
|
||||
name='password'
|
||||
onChange={handleChange}
|
||||
value={form.password}
|
||||
other={{ type: 'password' }}
|
||||
/>
|
||||
<FormTextField
|
||||
required
|
||||
label='Confirm Password'
|
||||
name='confirmPassword'
|
||||
onChange={handleChange}
|
||||
value={form.confirmPassword}
|
||||
other={{ type: 'password' }}
|
||||
/>
|
||||
{error && (
|
||||
<Box textAlign='right'>
|
||||
<Typography variant='body2' color='error'>
|
||||
{error}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
<FormSubmit
|
||||
color='primary'
|
||||
type='submit'
|
||||
other={{ disabled: form.password !== form.confirmPassword }}
|
||||
>
|
||||
Reset my Password
|
||||
</FormSubmit>
|
||||
</form>
|
||||
<Form text='Reset Password' error={error}>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<FormTextField
|
||||
required
|
||||
label='Password'
|
||||
name='password'
|
||||
onChange={handleChange}
|
||||
value={form.password}
|
||||
other={{ type: 'password' }}
|
||||
/>
|
||||
<FormTextField
|
||||
required
|
||||
label='Confirm Password'
|
||||
name='confirmPassword'
|
||||
onChange={handleChange}
|
||||
value={form.confirmPassword}
|
||||
other={{ type: 'password' }}
|
||||
/>
|
||||
<FormSubmit
|
||||
color='primary'
|
||||
type='submit'
|
||||
other={{ disabled: form.password !== form.confirmPassword }}
|
||||
>
|
||||
Reset my Password
|
||||
</FormSubmit>
|
||||
</form>
|
||||
</Form>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react';
|
||||
import { Paper, Typography } from '@mui/material';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,10 @@
|
|||
import React from 'react';
|
||||
import { Typography } from '@mui/material';
|
||||
|
||||
import Form from './Form';
|
||||
import { Form } from '.';
|
||||
import { FormSubmit, FormTextField } from './StyledElements';
|
||||
|
||||
function UpdateOrganizationForm({ name, handleSubmit, handleChange }) {
|
||||
return (
|
||||
<Form text='Rename Organization'>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<Typography variant='h4' sx={{ marginTop: '1vh 0vh' }}>
|
||||
Rename Organization
|
||||
</Typography>
|
||||
<FormTextField
|
||||
required
|
||||
label='Name'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,33 @@
|
|||
import Navbar from './Navbar';
|
||||
import MobileNavbar from './MobileNavbar';
|
||||
import LoginForm from './LoginForm';
|
||||
import MainPageBase from './MainPageBase';
|
||||
import EditUserForm from './EditUserForm';
|
||||
import Form from './Form';
|
||||
import OrgUnit from './OrgUnit';
|
||||
import StackItem from './StackItem';
|
||||
import RecordMp3 from './RecordMp3';
|
||||
import RecoverForm from './RecoverForm';
|
||||
import ResetForm from './ResetForm';
|
||||
import OrganizationList from './OrganizationList';
|
||||
import MemberUnit from './MemberUnit';
|
||||
import Dashboard from './Dashboard';
|
||||
import UpdateOrganizationForm from './UpdateOrganizationForm';
|
||||
|
||||
export { Navbar, MobileNavbar };
|
||||
export {
|
||||
Navbar,
|
||||
MobileNavbar,
|
||||
LoginForm,
|
||||
MainPageBase,
|
||||
EditUserForm,
|
||||
Form,
|
||||
OrgUnit,
|
||||
StackItem,
|
||||
RecordMp3,
|
||||
RecoverForm,
|
||||
ResetForm,
|
||||
OrganizationList,
|
||||
MemberUnit,
|
||||
Dashboard,
|
||||
UpdateOrganizationForm,
|
||||
};
|
||||
|
|
|
|||
16
client/src/containers/EditUser.jsx
Normal file
16
client/src/containers/EditUser.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { EditUserForm } from '../controllers';
|
||||
|
||||
function Login() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Edit User | KnowItAll</title>
|
||||
</Helmet>
|
||||
<EditUserForm />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Login;
|
||||
16
client/src/containers/Login.jsx
Normal file
16
client/src/containers/Login.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { LoginForm } from '../controllers';
|
||||
|
||||
function Login() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Login | KnowItAll</title>
|
||||
</Helmet>
|
||||
<LoginForm />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Login;
|
||||
27
client/src/containers/MainPage.jsx
Normal file
27
client/src/containers/MainPage.jsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import Cookies from 'js-cookie';
|
||||
import { useEffect } from 'react';
|
||||
import Helmet from 'react-helmet';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { MainPageDisplay } from '../controllers';
|
||||
|
||||
function MainPage() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
if (!Cookies.get('token')) {
|
||||
navigate('/login');
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>KnowItAll</title>
|
||||
</Helmet>
|
||||
<MainPageDisplay />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default MainPage;
|
||||
16
client/src/containers/MemberOrgs.jsx
Normal file
16
client/src/containers/MemberOrgs.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { MemberOrgsDashboard } from '../controllers';
|
||||
|
||||
function MemberOrgs() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Member Organizations | KnowItAll</title>
|
||||
</Helmet>
|
||||
<MemberOrgsDashboard />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default MemberOrgs;
|
||||
16
client/src/containers/OrgDashboard.jsx
Normal file
16
client/src/containers/OrgDashboard.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { Dashboard } from '../controllers';
|
||||
|
||||
function OrgDashboard() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Dashboard | KnowItAll</title>
|
||||
</Helmet>
|
||||
<Dashboard />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default OrgDashboard;
|
||||
16
client/src/containers/OwnedOrgs.jsx
Normal file
16
client/src/containers/OwnedOrgs.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { OwnedOrgsDashboard } from '../controllers';
|
||||
|
||||
function OwnedOrgs() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Owned Organizations | KnowItAll</title>
|
||||
</Helmet>
|
||||
<OwnedOrgsDashboard />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default OwnedOrgs;
|
||||
16
client/src/containers/Recover.jsx
Normal file
16
client/src/containers/Recover.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { RecoverForm } from '../controllers';
|
||||
|
||||
function Login() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Recover Password | KnowItAll</title>
|
||||
</Helmet>
|
||||
<RecoverForm />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Login;
|
||||
16
client/src/containers/Register.jsx
Normal file
16
client/src/containers/Register.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { RegisterForm } from '../controllers';
|
||||
|
||||
function Register() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Register | KnowItAll</title>
|
||||
</Helmet>
|
||||
<RegisterForm />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Register;
|
||||
16
client/src/containers/Reset.jsx
Normal file
16
client/src/containers/Reset.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { ResetForm } from '../controllers';
|
||||
|
||||
function Reset() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Reset | KnowItAll</title>
|
||||
</Helmet>
|
||||
<ResetForm />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Reset;
|
||||
16
client/src/containers/UpdateOrganization.jsx
Normal file
16
client/src/containers/UpdateOrganization.jsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import Helmet from 'react-helmet';
|
||||
|
||||
import { UpdateOrganizationForm } from '../controllers';
|
||||
|
||||
function UpdateOrganization() {
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>Update Organization | KnowItAll</title>
|
||||
</Helmet>
|
||||
<UpdateOrganizationForm />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default UpdateOrganization;
|
||||
|
|
@ -1,3 +1,25 @@
|
|||
import Layout from './Layout';
|
||||
import Login from './Login';
|
||||
import Register from './Register';
|
||||
import MainPage from './MainPage';
|
||||
import EditUser from './EditUser';
|
||||
import Recover from './Recover';
|
||||
import Reset from './Reset';
|
||||
import OwnedOrgs from './OwnedOrgs';
|
||||
import MemberOrgs from './MemberOrgs';
|
||||
import OrgDashboard from './OrgDashboard';
|
||||
import UpdateOrganization from './UpdateOrganization';
|
||||
|
||||
export { Layout };
|
||||
export {
|
||||
Layout,
|
||||
Login,
|
||||
Register,
|
||||
MainPage,
|
||||
EditUser,
|
||||
Recover,
|
||||
Reset,
|
||||
OwnedOrgs,
|
||||
MemberOrgs,
|
||||
OrgDashboard,
|
||||
UpdateOrganization,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import { remember } from '../services/userServices';
|
||||
|
||||
const initialUserData = { loading: true };
|
||||
|
|
@ -14,12 +16,15 @@ export default function UserProvider({ children }) {
|
|||
useEffect(() => {
|
||||
const loadUserData = async () => {
|
||||
const { user, error } = await remember();
|
||||
|
||||
if (error) {
|
||||
navigate('/login');
|
||||
Cookies.remove('token');
|
||||
} else {
|
||||
setUserData(user || { loading: false });
|
||||
}
|
||||
};
|
||||
|
||||
if (userData.loading) loadUserData();
|
||||
}, [userData.loading]);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import Dashboard from '../components/Dashboard';
|
||||
import { Dashboard } from '../components';
|
||||
import { getAudio } from '../services/userServices';
|
||||
import { getOrg, deleteOrg, removeMember } from '../services/orgServices';
|
||||
|
||||
function OrgDashboard() {
|
||||
function DashboardController() {
|
||||
const { orgID } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
|
@ -24,24 +24,18 @@ function OrgDashboard() {
|
|||
const [rows, setRows] = useState([]);
|
||||
const [status, setStatus] = useState(true);
|
||||
const [selection, setSelection] = useState(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
async function getData() {
|
||||
await axios
|
||||
.get(
|
||||
`${
|
||||
process.env.REACT_APP_API_ROOT
|
||||
}/org/${orgID}?token=${Cookies.get('token')}`
|
||||
)
|
||||
.then((response) => {
|
||||
const res = response.data;
|
||||
|
||||
await getOrg(orgID)
|
||||
.then((res) => {
|
||||
setOrg(() => {
|
||||
return { ...res.org, memberCount: res.memberCount };
|
||||
});
|
||||
|
||||
setRows(() => res.org.member);
|
||||
setStatus(() => res.status);
|
||||
setStatus(() => res.owner);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
|
|
@ -52,15 +46,12 @@ function OrgDashboard() {
|
|||
getData();
|
||||
}, [navigate, orgID]);
|
||||
|
||||
function handleOpen() {
|
||||
setOpen((initial) => (initial ? false : true));
|
||||
}
|
||||
|
||||
async function handleDelete() {
|
||||
await axios
|
||||
.delete(`${process.env.REACT_APP_API_ROOT}/org/delete`, {
|
||||
params: {
|
||||
token: Cookies.get('token'),
|
||||
orgID,
|
||||
},
|
||||
})
|
||||
.then(navigate('/'));
|
||||
await deleteOrg(orgID).then(navigate('/'));
|
||||
}
|
||||
|
||||
function copyID() {
|
||||
|
|
@ -76,51 +67,30 @@ function OrgDashboard() {
|
|||
async function removeSelected() {
|
||||
const doomedUserIDs = selection.map((row) => row.id);
|
||||
|
||||
await axios.post(
|
||||
`${process.env.REACT_APP_API_ROOT}/org/${orgID}/delete`,
|
||||
{
|
||||
token: Cookies.get('token'),
|
||||
orgID,
|
||||
doomedUserIDs,
|
||||
}
|
||||
);
|
||||
await removeMember(orgID, doomedUserIDs);
|
||||
}
|
||||
|
||||
async function leaveOrg() {
|
||||
await axios
|
||||
.post(`${process.env.REACT_APP_API_ROOT}/org/${orgID}/delete`, {
|
||||
token: Cookies.get('token'),
|
||||
orgID,
|
||||
})
|
||||
.then(() => navigate('/'))
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
navigate('/');
|
||||
});
|
||||
await removeMember(orgID, {}).then(navigate('/'));
|
||||
}
|
||||
|
||||
async function play(id) {
|
||||
await axios
|
||||
.get(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/public/audio/${id}.mp3`,
|
||||
{
|
||||
responseType: 'blob',
|
||||
}
|
||||
)
|
||||
.then((res) => {
|
||||
const uploadedFile = new File([res.data], 'userAudio.mp3', {
|
||||
type: res.data.type,
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
const audioFile = new Audio(URL.createObjectURL(uploadedFile));
|
||||
audioFile.play();
|
||||
await getAudio(id).then((res) => {
|
||||
const uploadedFile = new File([res], 'userAudio.mp3', {
|
||||
type: res.type,
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
const audioFile = new Audio(URL.createObjectURL(uploadedFile));
|
||||
audioFile.play();
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<Dashboard
|
||||
org={org}
|
||||
rows={rows}
|
||||
open={open}
|
||||
handleOpen={handleOpen}
|
||||
setSelection={setSelection}
|
||||
onClick={play}
|
||||
status={status}
|
||||
|
|
@ -133,4 +103,4 @@ function OrgDashboard() {
|
|||
);
|
||||
}
|
||||
|
||||
export default OrgDashboard;
|
||||
export default DashboardController;
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import EditUserForm from '../components/EditUserForm';
|
||||
|
||||
function EditUser() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [form, setForm] = useState({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
pronouns: '',
|
||||
});
|
||||
const [error, setError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
async function getInfo() {
|
||||
axios
|
||||
.get(
|
||||
`${process.env.REACT_APP_API_ROOT}/auth/${Cookies.get(
|
||||
'userID'
|
||||
)}?token=${Cookies.get('token')}`
|
||||
)
|
||||
.then((response) => {
|
||||
const user = response.data;
|
||||
|
||||
setForm(() => {
|
||||
return {
|
||||
firstName: user.firstName,
|
||||
lastName: user.lastName,
|
||||
email: user.email,
|
||||
pronouns: user.pronouns,
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
getInfo();
|
||||
}, []);
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
setForm((form) => {
|
||||
return { ...form, [name]: value };
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios
|
||||
.patch(`${process.env.REACT_APP_API_ROOT}/auth/update`, {
|
||||
...form,
|
||||
token: Cookies.get('token'),
|
||||
})
|
||||
.then(() => {
|
||||
navigate('/');
|
||||
})
|
||||
.catch((e) => setError(() => e.response.data));
|
||||
}
|
||||
|
||||
return (
|
||||
<EditUserForm
|
||||
form={form}
|
||||
error={error}
|
||||
handleSubmit={handleSubmit}
|
||||
handleChange={handleChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditUser;
|
||||
62
client/src/controllers/EditUserFormController.jsx
Normal file
62
client/src/controllers/EditUserFormController.jsx
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { EditUserForm } from '../components';
|
||||
import { useUser } from '../contexts';
|
||||
import { updateUserDetails } from '../services/userServices';
|
||||
|
||||
function EditUserFormController() {
|
||||
const navigate = useNavigate();
|
||||
const { userData } = useUser();
|
||||
|
||||
const [form, setForm] = useState({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
pronouns: '',
|
||||
});
|
||||
|
||||
const [error, setError] = useState('');
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
setForm((form) => {
|
||||
return { ...form, [name]: value };
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
const { error } = await updateUserDetails(form);
|
||||
|
||||
if (error) {
|
||||
setError(() => error);
|
||||
} else {
|
||||
navigate('/');
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!userData.loading) {
|
||||
setForm(() => ({
|
||||
firstName: userData.firstName,
|
||||
lastName: userData.lastName,
|
||||
email: userData.email,
|
||||
pronouns: userData.pronouns,
|
||||
}));
|
||||
}
|
||||
}, [userData]);
|
||||
|
||||
return (
|
||||
<EditUserForm
|
||||
form={form}
|
||||
error={error}
|
||||
handleSubmit={handleSubmit}
|
||||
handleChange={handleChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditUserFormController;
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import LoginForm from '../components/LoginForm';
|
||||
|
||||
function Login({ setToken }) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [form, setForm] = useState({
|
||||
email: '',
|
||||
password: '',
|
||||
remember: false,
|
||||
});
|
||||
const [error, setError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
async function logout() {
|
||||
await axios
|
||||
.post(`${process.env.REACT_APP_API_ROOT}/auth/logout`, {
|
||||
token: Cookies.get('token'),
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
|
||||
Cookies.remove('token');
|
||||
Cookies.remove('userID');
|
||||
|
||||
setToken(() => false);
|
||||
}
|
||||
|
||||
if (Cookies.get('token')) {
|
||||
logout();
|
||||
}
|
||||
}, [setToken]);
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
setForm((form) => {
|
||||
return { ...form, [name]: value };
|
||||
});
|
||||
}
|
||||
|
||||
function handleCheckboxChange(e) {
|
||||
const name = e.target.name;
|
||||
const checked = e.target.checked;
|
||||
|
||||
setForm(() => {
|
||||
return { ...form, [name]: checked };
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios
|
||||
.post(`${process.env.REACT_APP_API_ROOT}/auth/login`, form)
|
||||
.then((response) => {
|
||||
Cookies.set('token', response.data.token, {
|
||||
expires: form.remember ? 3650 : 1,
|
||||
});
|
||||
Cookies.set('userID', response.data.userID, {
|
||||
expires: form.remember ? 3650 : 1,
|
||||
});
|
||||
setToken(true);
|
||||
navigate('/');
|
||||
})
|
||||
.catch((e) => setError(() => e.response.data));
|
||||
}
|
||||
|
||||
return (
|
||||
<LoginForm
|
||||
form={form}
|
||||
error={error}
|
||||
handleSubmit={handleSubmit}
|
||||
handleChange={handleChange}
|
||||
handleCheckboxChange={handleCheckboxChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default Login;
|
||||
51
client/src/controllers/LoginFormController.jsx
Normal file
51
client/src/controllers/LoginFormController.jsx
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { LoginForm } from '../components';
|
||||
import { useError } from '../contexts';
|
||||
import { login } from '../services/userServices';
|
||||
|
||||
function LoginFormController({ setToken }) {
|
||||
const navigate = useNavigate();
|
||||
const { error, setError } = useError();
|
||||
|
||||
const [form, setForm] = useState({
|
||||
email: '',
|
||||
password: '',
|
||||
remember: false,
|
||||
});
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
setForm((form) => {
|
||||
return { ...form, [name]: value };
|
||||
});
|
||||
}
|
||||
|
||||
function handleCheckboxChange(e) {
|
||||
const name = e.target.name;
|
||||
const checked = e.target.checked;
|
||||
|
||||
setForm(() => {
|
||||
return { ...form, [name]: checked };
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const { error } = await login(form);
|
||||
|
||||
if (error) {
|
||||
setError(() => error);
|
||||
} else {
|
||||
navigate('/');
|
||||
}
|
||||
}
|
||||
|
||||
return <LoginForm {...{ form, handleSubmit, handleChange, handleCheckboxChange, error }} />;
|
||||
}
|
||||
|
||||
export default LoginFormController;
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import MainPageBase from '../components/MainPageBase';
|
||||
|
||||
function MainPage() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [ownedOrgs, setOwnedOrgs] = useState([]);
|
||||
const [orgs, setOrgs] = useState([]);
|
||||
const [form, setForm] = useState({
|
||||
name: '',
|
||||
id: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (Cookies.get('token')) {
|
||||
getMemberOrgs();
|
||||
getOwnedOrgs();
|
||||
} else {
|
||||
navigate('/login');
|
||||
}
|
||||
}, [navigate]);
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
setForm((form) => {
|
||||
return { ...form, [name]: value };
|
||||
});
|
||||
}
|
||||
|
||||
async function getOwnedOrgs() {
|
||||
await axios
|
||||
.get(
|
||||
`${process.env.REACT_APP_API_ROOT}/auth?token=${Cookies.get(
|
||||
'token'
|
||||
)}`
|
||||
)
|
||||
.then((response) => {
|
||||
setOwnedOrgs(() => response.data);
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
}
|
||||
|
||||
async function getMemberOrgs() {
|
||||
await axios
|
||||
.get(
|
||||
`${
|
||||
process.env.REACT_APP_API_ROOT
|
||||
}/auth/orgs?token=${Cookies.get('token')}`
|
||||
)
|
||||
.then((response) => {
|
||||
setOrgs(() => response.data);
|
||||
});
|
||||
}
|
||||
|
||||
async function createOrg(e) {
|
||||
e.preventDefault();
|
||||
console.log('create');
|
||||
|
||||
await axios
|
||||
.post(`${process.env.REACT_APP_API_ROOT}/org/create`, {
|
||||
token: Cookies.get('token'),
|
||||
orgName: form.name,
|
||||
})
|
||||
.then(() => {
|
||||
getOwnedOrgs();
|
||||
});
|
||||
}
|
||||
|
||||
async function joinOrg(e) {
|
||||
e.preventDefault();
|
||||
|
||||
await axios
|
||||
.post(`${process.env.REACT_APP_API_ROOT}/org/${form.id}/add`, {
|
||||
token: Cookies.get('token'),
|
||||
})
|
||||
.then(() => {
|
||||
getMemberOrgs();
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<MainPageBase
|
||||
form={form}
|
||||
orgs={orgs}
|
||||
ownedOrgs={ownedOrgs}
|
||||
joinOrg={joinOrg}
|
||||
createOrg={createOrg}
|
||||
handleChange={handleChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default MainPage;
|
||||
75
client/src/controllers/MainPageController.jsx
Normal file
75
client/src/controllers/MainPageController.jsx
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import { MainPageBase } from '../components';
|
||||
import { getMemberOrgs, getOwnedOrgs } from '../services/userServices';
|
||||
import { createOrg, addMember } from '../services/orgServices';
|
||||
|
||||
function MainPageController() {
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [ownedOrgs, setOwnedOrgs] = useState([]);
|
||||
const [orgs, setOrgs] = useState([]);
|
||||
const [form, setForm] = useState({
|
||||
name: '',
|
||||
id: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (Cookies.get('token')) {
|
||||
retrieveMemberOrgs();
|
||||
retrieveOwnedOrgs();
|
||||
} else {
|
||||
navigate('/login');
|
||||
}
|
||||
}, [navigate]);
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
const value = e.target.value;
|
||||
|
||||
setForm((form) => {
|
||||
return { ...form, [name]: value };
|
||||
});
|
||||
}
|
||||
|
||||
async function retrieveOwnedOrgs() {
|
||||
const { orgs } = await getOwnedOrgs().catch((e) => console.log(e));
|
||||
|
||||
setOwnedOrgs(() => orgs);
|
||||
}
|
||||
|
||||
async function retrieveMemberOrgs() {
|
||||
const { orgs } = await getMemberOrgs().catch((e) => console.log(e));
|
||||
|
||||
setOrgs(() => orgs);
|
||||
}
|
||||
|
||||
async function makeOrg(e) {
|
||||
e.preventDefault();
|
||||
|
||||
await createOrg({ orgName: form.name })
|
||||
.then(retrieveOwnedOrgs)
|
||||
.catch((e) => console.log(e));
|
||||
}
|
||||
|
||||
async function joinOrg(e) {
|
||||
e.preventDefault();
|
||||
|
||||
await addMember.then(retrieveMemberOrgs).catch((e) => console.log(e));
|
||||
}
|
||||
|
||||
return (
|
||||
<MainPageBase
|
||||
form={form}
|
||||
orgs={orgs}
|
||||
ownedOrgs={ownedOrgs}
|
||||
handleChange={handleChange}
|
||||
joinOrg={joinOrg}
|
||||
createOrg={makeOrg}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default MainPageController;
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import Organizations from '../components/Organizations';
|
||||
|
||||
function JoinedOrgs() {
|
||||
const [orgs, setOrgs] = useState([]);
|
||||
|
||||
async function getOrgs() {
|
||||
axios
|
||||
.get(
|
||||
`${
|
||||
process.env.REACT_APP_API_ROOT
|
||||
}/auth/orgs?token=${Cookies.get('token')}`
|
||||
)
|
||||
.then((response) => {
|
||||
setOrgs(() => response.data);
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(getOrgs);
|
||||
|
||||
return <Organizations orgs={orgs} />;
|
||||
}
|
||||
|
||||
export default JoinedOrgs;
|
||||
20
client/src/controllers/MemberOrgsDashboard.jsx
Normal file
20
client/src/controllers/MemberOrgsDashboard.jsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { OrganizationList } from '../components';
|
||||
import { getMemberOrgs } from '../services/userServices';
|
||||
|
||||
function MemberOrgsDashboard() {
|
||||
const [orgs, setOrgs] = useState([]);
|
||||
|
||||
async function getOrgs() {
|
||||
getMemberOrgs().then((res) => {
|
||||
setOrgs(() => res.orgs);
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(getOrgs);
|
||||
|
||||
return <OrganizationList orgs={orgs} />;
|
||||
}
|
||||
|
||||
export default MemberOrgsDashboard;
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import Organizations from '../components/Organizations';
|
||||
|
||||
function JoinedOrgs() {
|
||||
const [orgs, setOrgs] = useState([]);
|
||||
|
||||
async function getOrgs() {
|
||||
axios
|
||||
.get(
|
||||
`${process.env.REACT_APP_API_ROOT}/auth?token=${Cookies.get(
|
||||
'token'
|
||||
)}`
|
||||
)
|
||||
.then((response) => {
|
||||
setOrgs(() => response.data);
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(getOrgs);
|
||||
|
||||
return <Organizations orgs={orgs} />;
|
||||
}
|
||||
|
||||
export default JoinedOrgs;
|
||||
20
client/src/controllers/OwnedOrgsDashboard.jsx
Normal file
20
client/src/controllers/OwnedOrgsDashboard.jsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { OrganizationList } from '../components';
|
||||
import { getOwnedOrgs } from '../services/userServices';
|
||||
|
||||
function OwnedOrgsDashboard() {
|
||||
const [orgs, setOrgs] = useState([]);
|
||||
|
||||
async function getOrgs() {
|
||||
getOwnedOrgs().then((res) => {
|
||||
setOrgs(() => res.orgs);
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(getOrgs);
|
||||
|
||||
return <OrganizationList orgs={orgs} />;
|
||||
}
|
||||
|
||||
export default OwnedOrgsDashboard;
|
||||
94
client/src/controllers/RecordMp3Controller.jsx
Normal file
94
client/src/controllers/RecordMp3Controller.jsx
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
import MicRecorder from 'mic-recorder-to-mp3';
|
||||
|
||||
import { useUser } from '../contexts';
|
||||
import { RecordMp3 } from '../components';
|
||||
import { setAudio, getAudio } from '../services/userServices';
|
||||
|
||||
function RecordMp3Controller() {
|
||||
const { userData } = useUser();
|
||||
|
||||
const [recorder] = useState(
|
||||
new MicRecorder({
|
||||
bitRate: 128,
|
||||
})
|
||||
);
|
||||
const [recording, setRecording] = useState(false);
|
||||
const [uploadedFile, setUploadedFile] = useState(null);
|
||||
const [audioRecording, setAudioRecording] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!userData.loading) {
|
||||
getAudio(userData.id).then((data) => {
|
||||
setUploadedFile(() => {
|
||||
// Retrieve audio file of user if exists
|
||||
return new File([data], 'userAudio.mp3', {
|
||||
type: data.type,
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}, [userData]);
|
||||
|
||||
function togglePlay() {
|
||||
if (audioRecording && !audioRecording.ended) {
|
||||
// Reset audio and reset if track is playing
|
||||
audioRecording.pause();
|
||||
audioRecording.currentTime = 0;
|
||||
setAudioRecording(() => null);
|
||||
} else {
|
||||
// Set audio to file and play
|
||||
const audioFile = new Audio(URL.createObjectURL(uploadedFile));
|
||||
setAudioRecording(() => audioFile);
|
||||
audioFile.play();
|
||||
}
|
||||
}
|
||||
|
||||
function record() {
|
||||
if (recording) {
|
||||
// Stop recording then set uploaded file to mp3 instance
|
||||
setRecording(() => false);
|
||||
recorder
|
||||
.stop()
|
||||
.getMp3()
|
||||
.then(([buffer, blob]) => {
|
||||
setUploadedFile(() => {
|
||||
return new File(buffer, 'userAudio.mp3', {
|
||||
type: blob.type,
|
||||
lastModified: Date.now(),
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Start recording
|
||||
setRecording(() => true);
|
||||
recorder.start().catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function uploadRecord() {
|
||||
setUploadedFile(() => {
|
||||
return document.getElementById('icon-button-file').files[0];
|
||||
});
|
||||
}
|
||||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Create form data object and attach file and user token
|
||||
var formData = new FormData();
|
||||
formData.append('audioFile', uploadedFile, 'userAudio.mp3');
|
||||
formData.append('token', Cookies.get('token'));
|
||||
|
||||
await setAudio(formData);
|
||||
}
|
||||
|
||||
return <RecordMp3 {...{ togglePlay, record, uploadRecord, handleSubmit }} />;
|
||||
}
|
||||
|
||||
export default RecordMp3Controller;
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
|
||||
import RecoverForm from '../components/RecoverForm';
|
||||
import { RecoverForm } from '../components';
|
||||
import { requestReset } from '../services/userServices';
|
||||
|
||||
function Recover() {
|
||||
function RecoverFormController() {
|
||||
const [form, setForm] = useState({
|
||||
email: '',
|
||||
});
|
||||
const [error, setError] = useState('');
|
||||
const [success, setSuccess] = useState('');
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
|
|
@ -21,25 +20,17 @@ function Recover() {
|
|||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios
|
||||
.get(
|
||||
`${process.env.REACT_APP_API_ROOT}/auth/reset-password?${form.email}`
|
||||
)
|
||||
.then((response) => {
|
||||
setSuccess(() => response.data);
|
||||
})
|
||||
.catch((e) => setError(() => e.response.data));
|
||||
await requestReset(form);
|
||||
}
|
||||
|
||||
return (
|
||||
<RecoverForm
|
||||
form={form}
|
||||
error={error}
|
||||
success={success}
|
||||
handleChange={handleChange}
|
||||
handleSubmit={handleSubmit}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default Recover;
|
||||
export default RecoverFormController;
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
|
||||
import RegisterForm from '../components/RegisterForm';
|
||||
import { useError } from '../contexts';
|
||||
import { register } from '../services/userServices';
|
||||
|
||||
function Register() {
|
||||
function RegisterFormController() {
|
||||
const navigate = useNavigate();
|
||||
const [params] = useSearchParams();
|
||||
const { error, setError } = useError();
|
||||
|
||||
const [form, setForm] = useState({
|
||||
firstName: '',
|
||||
|
|
@ -16,7 +18,6 @@ function Register() {
|
|||
password: '',
|
||||
confirmPassword: '',
|
||||
});
|
||||
const [error, setError] = useState('');
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
|
|
@ -31,25 +32,16 @@ function Register() {
|
|||
e.preventDefault();
|
||||
|
||||
const { confirmPassword, ...filteredForm } = form;
|
||||
await axios
|
||||
.post(`${process.env.REACT_APP_API_ROOT}/auth/register`, {
|
||||
...filteredForm,
|
||||
orgID: params.orgID,
|
||||
})
|
||||
.then(() => {
|
||||
navigate('/login');
|
||||
})
|
||||
.catch((e) => setError(() => e.response.data));
|
||||
const { error } = await register({ ...filteredForm, orgID: params.get('orgID') });
|
||||
|
||||
if (error) {
|
||||
setError(() => error);
|
||||
} else {
|
||||
navigate('/login');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<RegisterForm
|
||||
form={form}
|
||||
handleSubmit={handleSubmit}
|
||||
handleChange={handleChange}
|
||||
error={error}
|
||||
/>
|
||||
);
|
||||
return <RegisterForm {...{ form, handleSubmit, handleChange, error }} />;
|
||||
}
|
||||
|
||||
export default Register;
|
||||
export default RegisterFormController;
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
|
||||
import ResetForm from '../components/ResetForm';
|
||||
import { ResetForm } from '../components';
|
||||
import { resetPassword } from '../services/userServices';
|
||||
import { useError } from '../contexts';
|
||||
|
||||
function Reset() {
|
||||
function ResetFormController() {
|
||||
const navigate = useNavigate();
|
||||
const { id } = useParams();
|
||||
|
||||
|
|
@ -12,7 +13,7 @@ function Reset() {
|
|||
password: '',
|
||||
confirmPassword: '',
|
||||
});
|
||||
const [error, setError] = useState('');
|
||||
const { error, setError } = useError();
|
||||
|
||||
function handleChange(e) {
|
||||
const name = e.target.name;
|
||||
|
|
@ -25,17 +26,14 @@ function Reset() {
|
|||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios
|
||||
.patch(
|
||||
`${process.env.REACT_APP_API_ROOT}/auth/reset-password/${id}`,
|
||||
{
|
||||
password: form.password,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
navigate('/login');
|
||||
})
|
||||
.catch((e) => setError(() => e.response.data));
|
||||
|
||||
const error = await resetPassword(id, { password: form.password });
|
||||
|
||||
if (error) {
|
||||
setError(() => error);
|
||||
} else {
|
||||
navigate('/login');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -48,4 +46,4 @@ function Reset() {
|
|||
);
|
||||
}
|
||||
|
||||
export default Reset;
|
||||
export default ResetFormController;
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
import React, { useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
import UpdateOrganizationForm from '../components/UpdateOrganizationForm';
|
||||
import { UpdateOrganizationForm } from '../components';
|
||||
import { updateOrgDetails } from '../services/orgServices';
|
||||
|
||||
function UpdateOrganization() {
|
||||
function UpdateOrganizationFormController() {
|
||||
const { orgID } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
|
@ -19,15 +18,10 @@ function UpdateOrganization() {
|
|||
|
||||
async function handleSubmit(e) {
|
||||
e.preventDefault();
|
||||
await axios
|
||||
.patch(`${process.env.REACT_APP_API_ROOT}/org/update`, {
|
||||
token: Cookies.get('token'),
|
||||
orgName: name,
|
||||
orgID,
|
||||
})
|
||||
.then(() => {
|
||||
navigate(`/org/${orgID}`);
|
||||
});
|
||||
|
||||
await updateOrgDetails(orgID, { orgName: name }).then(() => {
|
||||
navigate(`/org/${orgID}`);
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
|
|
@ -39,4 +33,4 @@ function UpdateOrganization() {
|
|||
);
|
||||
}
|
||||
|
||||
export default UpdateOrganization;
|
||||
export default UpdateOrganizationFormController;
|
||||
|
|
@ -1,3 +1,27 @@
|
|||
import Navbar from './NavbarController';
|
||||
import LoginForm from './LoginFormController';
|
||||
import RegisterForm from './RegisterFormController';
|
||||
import MainPageDisplay from './MainPageController';
|
||||
import EditUserForm from './EditUserFormController';
|
||||
import RecordMp3 from './RecordMp3Controller';
|
||||
import RecoverForm from './RecoverFormController';
|
||||
import ResetForm from './ResetFormController';
|
||||
import OwnedOrgsDashboard from './OwnedOrgsDashboard';
|
||||
import MemberOrgsDashboard from './MemberOrgsDashboard';
|
||||
import Dashboard from './DashboardController';
|
||||
import UpdateOrganizationForm from './UpdateOrganizationFormController';
|
||||
|
||||
export { Navbar };
|
||||
export {
|
||||
Navbar,
|
||||
LoginForm,
|
||||
RegisterForm,
|
||||
MainPageDisplay,
|
||||
EditUserForm,
|
||||
RecordMp3,
|
||||
RecoverForm,
|
||||
ResetForm,
|
||||
OwnedOrgsDashboard,
|
||||
MemberOrgsDashboard,
|
||||
Dashboard,
|
||||
UpdateOrganizationForm,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ async function getOrg(id) {
|
|||
instance.defaults.headers.common['Authorization'] = `bearer ${Cookies.get('token')}`;
|
||||
|
||||
try {
|
||||
await instance.delete('/logout');
|
||||
const response = await instance.get(`/${id}`);
|
||||
console.log(response.data);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error;
|
||||
|
|
@ -73,3 +75,5 @@ async function updateOrgDetails(id, data) {
|
|||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
export { addMember, createOrg, deleteOrg, getOrg, removeMember, updateOrgDetails };
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
import Cookies from 'js-cookie';
|
||||
import { Buffer } from 'buffer';
|
||||
|
||||
import { createRequest } from './requests';
|
||||
import axios from 'axios';
|
||||
|
||||
async function login({ username, password, remember }) {
|
||||
const encoded = Buffer.from(`${username}:${password}`).toString('base64');
|
||||
async function login({ email, password, remember }) {
|
||||
const encoded = Buffer.from(`${email}:${password}`).toString('base64');
|
||||
|
||||
const instance = createRequest('/auth');
|
||||
instance.defaults.headers.common['Authorization'] = `basic ${encoded}`;
|
||||
|
|
@ -28,7 +30,7 @@ async function register(data) {
|
|||
const instance = createRequest('/auth');
|
||||
|
||||
try {
|
||||
await instance.post('/register', { data });
|
||||
await instance.post('/register', data);
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error;
|
||||
|
|
@ -40,7 +42,7 @@ async function logout() {
|
|||
instance.defaults.headers.common['Authorization'] = `bearer ${Cookies.get('token')}`;
|
||||
|
||||
try {
|
||||
await instance.delete('/logout');
|
||||
await instance.post('/logout');
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error;
|
||||
|
|
@ -53,9 +55,9 @@ async function remember() {
|
|||
|
||||
if (Cookies.get('token')) {
|
||||
try {
|
||||
const { data } = await instance.get('/remember');
|
||||
const { data } = await instance.post('/remember');
|
||||
|
||||
return data.user;
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error.response.data;
|
||||
|
|
@ -80,7 +82,7 @@ async function requestReset(data) {
|
|||
const instance = createRequest('/auth');
|
||||
|
||||
try {
|
||||
await instance.post(`/reset`);
|
||||
await instance.post(`/reset`, data);
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error.response.data;
|
||||
|
|
@ -91,7 +93,7 @@ async function resetPassword(id, data) {
|
|||
const instance = createRequest('/auth');
|
||||
|
||||
try {
|
||||
await instance.post(`/reset/${id}`, data);
|
||||
await instance.patch(`/reset/${id}`, data);
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error.response.data;
|
||||
|
|
@ -104,13 +106,24 @@ async function setAudio(data) {
|
|||
instance.defaults.headers.common['Authorization'] = `bearer ${Cookies.get('token')}`;
|
||||
|
||||
try {
|
||||
await instance.post(`/update/audio`, data);
|
||||
await instance.post('/audio', data);
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error.response.data;
|
||||
}
|
||||
}
|
||||
|
||||
async function getAudio(userID) {
|
||||
const response = await axios.get(
|
||||
`${process.env.REACT_APP_DOMAIN_ROOT}/public/audio/${userID}.mp3`,
|
||||
{
|
||||
responseType: 'blob',
|
||||
}
|
||||
);
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
async function updateUserDetails(data) {
|
||||
const instance = createRequest('/auth');
|
||||
instance.defaults.headers.common['Authorization'] = `bearer ${Cookies.get('token')}`;
|
||||
|
|
@ -128,9 +141,9 @@ async function getMemberOrgs() {
|
|||
instance.defaults.headers.common['Authorization'] = `bearer ${Cookies.get('token')}`;
|
||||
|
||||
try {
|
||||
const { data } = await instance.get(`/orgs`);
|
||||
const { data } = await instance.get(`/orgs/member`);
|
||||
|
||||
return data.orgs;
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error.response.data;
|
||||
|
|
@ -142,9 +155,9 @@ async function getOwnedOrgs() {
|
|||
instance.defaults.headers.common['Authorization'] = `bearer ${Cookies.get('token')}`;
|
||||
|
||||
try {
|
||||
const { data } = await instance.get(`/orgs/member`);
|
||||
const { data } = await instance.get(`/orgs`);
|
||||
|
||||
return data.orgs;
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.log(error.response.data);
|
||||
return error.response.data;
|
||||
|
|
@ -160,6 +173,7 @@ export {
|
|||
requestReset,
|
||||
resetPassword,
|
||||
setAudio,
|
||||
getAudio,
|
||||
updateUserDetails,
|
||||
getMemberOrgs,
|
||||
getOwnedOrgs,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const config = require('../../config/error.json');
|
|||
async function RequestReset(req, res, next) {
|
||||
try {
|
||||
// Make sure that the request contains an email
|
||||
const email = req.query.email;
|
||||
const email = req.body.email;
|
||||
if (!email) {
|
||||
return res.status(400).send(config.errorIncomplete);
|
||||
}
|
||||
|
|
@ -27,10 +27,11 @@ async function RequestReset(req, res, next) {
|
|||
await courier.send({
|
||||
message: {
|
||||
to: { email: result.email },
|
||||
template: 'FSTM4WF60KM570KS9DBQRH0T41GJ',
|
||||
template: '484W41FM494HX6H1RFRNAXNGQ28C',
|
||||
data: {
|
||||
email: result.email,
|
||||
resetRequest: resetRequest.id,
|
||||
apiDomainRoot: process.env.CLIENT_DOMAIN_ROOT,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ router.post('/remember', tokenAuth, Remember);
|
|||
router.patch('/update', tokenAuth, UpdateUserDetails);
|
||||
router.post('/audio', parseFormData, tokenAuth, SetAudio);
|
||||
|
||||
router.get('/reset', RequestReset);
|
||||
router.post('/reset', RequestReset);
|
||||
router.patch('/reset/:id', ResetPassword);
|
||||
|
||||
router.get('/orgs', tokenAuth, GetOwnedOrgs);
|
||||
|
|
|
|||
Reference in a new issue