Commit 891c5ba4 authored by Vincent Seyller's avatar Vincent Seyller
Browse files

Showing members and colocations

parent a0831593
......@@ -1880,6 +1880,25 @@
}
}
},
"@popperjs/core": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.6.0.tgz",
"integrity": "sha512-cPqjjzuFWNK3BSKLm0abspP0sp/IGOli4p5I5fKFAzdS8fvjdOwDCfZqAaIiXd9lPkOWi3SUUfZof3hEb7J/uw=="
},
"@restart/context": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@restart/context/-/context-2.1.4.tgz",
"integrity": "sha512-INJYZQJP7g+IoDUh/475NlGiTeMfwTXUEr3tmRneckHIxNolGOW9CTq83S8cxq0CgJwwcMzMJFchxvlwe7Rk8Q=="
},
"@restart/hooks": {
"version": "0.3.26",
"resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.3.26.tgz",
"integrity": "sha512-7Hwk2ZMYm+JLWcb7R9qIXk1OoUg1Z+saKWqZXlrvFwT3w6UArVNWgxYOzf+PJoK9zZejp8okPAKTctthhXLt5g==",
"requires": {
"lodash": "^4.17.20",
"lodash-es": "^4.17.20"
}
},
"@rollup/plugin-node-resolve": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz",
......@@ -2260,6 +2279,11 @@
"@babel/types": "^7.3.0"
}
},
"@types/classnames": {
"version": "2.2.11",
"resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.11.tgz",
"integrity": "sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw=="
},
"@types/eslint": {
"version": "7.2.6",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.2.6.tgz",
......@@ -2296,6 +2320,11 @@
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz",
"integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA=="
},
"@types/invariant": {
"version": "2.2.34",
"resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.34.tgz",
"integrity": "sha512-lYUtmJ9BqUN688fGY1U1HZoWT1/Jrmgigx2loq4ZcJpICECm/Om3V314BxdzypO0u5PORKGMM6x0OXaljV1YFg=="
},
"@types/istanbul-lib-coverage": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
......@@ -2441,6 +2470,11 @@
}
}
},
"@types/warning": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.0.tgz",
"integrity": "sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI="
},
"@types/webpack": {
"version": "4.41.26",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz",
......@@ -3672,6 +3706,11 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"bootstrap": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.6.0.tgz",
"integrity": "sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
......@@ -4061,6 +4100,11 @@
}
}
},
"classnames": {
"version": "2.2.6",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz",
"integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q=="
},
"clean-css": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
......@@ -7665,6 +7709,14 @@
}
}
},
"invariant": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
"integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"requires": {
"loose-envify": "^1.0.0"
}
},
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
......@@ -9866,6 +9918,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
},
"lodash-es": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.20.tgz",
"integrity": "sha512-JD1COMZsq8maT6mnuz1UMV0jvYD0E0aUsSOdrr1/nAG3dhqQXwRRgeW0cSqH1U43INKcqxaiVIQNOUDld7gRDA=="
},
"lodash._reinterpolate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
......@@ -12265,6 +12322,15 @@
"react-is": "^16.8.1"
}
},
"prop-types-extra": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
"integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
"requires": {
"react-is": "^16.3.2",
"warning": "^4.0.0"
}
},
"proxy-addr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
......@@ -12443,6 +12509,31 @@
"whatwg-fetch": "^3.4.1"
}
},
"react-bootstrap": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.4.3.tgz",
"integrity": "sha512-4tYhk26KRnK0myMEp2wvNjOvnHMwWfa6pWFIiCtj9wewYaTxP7TrCf7MwcIMBgUzyX0SJXx6UbbDG0+hObiXNg==",
"requires": {
"@babel/runtime": "^7.4.2",
"@restart/context": "^2.1.4",
"@restart/hooks": "^0.3.21",
"@types/classnames": "^2.2.10",
"@types/invariant": "^2.2.33",
"@types/prop-types": "^15.7.3",
"@types/react": ">=16.9.35",
"@types/react-transition-group": "^4.4.0",
"@types/warning": "^3.0.0",
"classnames": "^2.2.6",
"dom-helpers": "^5.1.2",
"invariant": "^2.2.4",
"prop-types": "^15.7.2",
"prop-types-extra": "^1.1.0",
"react-overlays": "^4.1.0",
"react-transition-group": "^4.4.1",
"uncontrollable": "^7.0.0",
"warning": "^4.0.3"
}
},
"react-dev-utils": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-11.0.1.tgz",
......@@ -12569,6 +12660,26 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react-overlays": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-4.1.1.tgz",
"integrity": "sha512-WtJifh081e6M24KnvTQoNjQEpz7HoLxqt8TwZM7LOYIkYJ8i/Ly1Xi7RVte87ZVnmqQ4PFaFiNHZhSINPSpdBQ==",
"requires": {
"@babel/runtime": "^7.12.1",
"@popperjs/core": "^2.5.3",
"@restart/hooks": "^0.3.25",
"@types/warning": "^3.0.0",
"dom-helpers": "^5.2.0",
"prop-types": "^15.7.2",
"uncontrollable": "^7.0.0",
"warning": "^4.0.3"
}
},
"react-query": {
"version": "2.26.4",
"resolved": "https://registry.npmjs.org/react-query/-/react-query-2.26.4.tgz",
......@@ -14951,6 +15062,33 @@
"is-typedarray": "^1.0.0"
}
},
"uncontrollable": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.1.1.tgz",
"integrity": "sha512-EcPYhot3uWTS3w00R32R2+vS8Vr53tttrvMj/yA1uYRhf8hbTG2GyugGqWDY0qIskxn0uTTojVd6wPYW9ZEf8Q==",
"requires": {
"@babel/runtime": "^7.6.3",
"@types/react": "^16.9.11",
"invariant": "^2.2.4",
"react-lifecycles-compat": "^3.0.4"
},
"dependencies": {
"@types/react": {
"version": "16.14.2",
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.2.tgz",
"integrity": "sha512-BzzcAlyDxXl2nANlabtT4thtvbbnhee8hMmH/CcJrISDBVcJS1iOsP1f0OAgSdGE0MsY9tqcrb9YoZcOFv9dbQ==",
"requires": {
"@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
"csstype": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz",
"integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw=="
}
}
},
"unicode-canonical-property-names-ecmascript": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
......@@ -15293,6 +15431,14 @@
"makeerror": "1.0.x"
}
},
"warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"requires": {
"loose-envify": "^1.0.0"
}
},
"watchpack": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
......
......@@ -2,6 +2,7 @@ import { BrowserRouter as Router } from 'react-router-dom';
import './App.css';
import ShareLoc from './ShareLoc'
import 'bootstrap/dist/css/bootstrap.min.css';
let App = () => {
return (
......
import {useQuery, useMutation, useQueryCache} from 'react-query';
import {useState} from 'react';
import {Route, useHistory} from 'react-router-dom';
import {Button, TextField} from '@material-ui/core/'
import {TextField} from '@material-ui/core/'
import {ListGroup, Button, Container, Card} from 'react-bootstrap';
let Colocations = () => {
const queryCache = useQueryCache();
let ApiURL = 'http://localhost:8080/ShareLoc/api';
let user = JSON.parse(window.localStorage.getItem('user'));
let history = useHistory();
let ApiURL = 'http://localhost:8080/ShareLoc/api';
let createColocation = colocation => {
let URL = ApiURL + '/colocation/create?name=' + colocation.name;
return fetch(URL, {
......@@ -32,8 +34,8 @@ let Colocations = () => {
};
return <form onSubmit={handleSubmit}>
<TextField id="name" label="New colocation name" size="small" variant="outlined"
onChange={(e)=>{setName(e.target.value)}}/> <Button variant="contained" color="primary" type='submit'>Add</Button>
<TextField id='name' label='New colocation name' size='small' variant='outlined'
onChange={(e)=>{setName(e.target.value)}}/> <Button as='input' type='submit' value='Add'></Button>
</form>;
};
......@@ -49,26 +51,46 @@ let Colocations = () => {
const {data, status} = useQuery('Colocations', fetchColocation);
return <div>
<h1>Colocations</h1>
{status === 'loading' && (<div>Loading data...</div>)}
{status === 'error' && (<div>Error fetching data</div>)}
{status === 'success' && (
<Route path='/colocations' exact>
<AddColocationForm />
<div>
<ul>
{data.map((colocation, idx) => {
return <li key={idx}>
{colocation.name}
<button onClick={() => history.push("/colocation/" + colocation.id)}>Details</button>
</li>
})}
</ul>
</div>
</Route>
)}
</div>;
if(user != null) {
return <Container>
<br/>
<h1>Colocations</h1>
<br/>
{status === 'loading' && (<div>Loading data...</div>)}
{status === 'error' && (<div>Error fetching data</div>)}
{status === 'success' && (
<>
<Route path='/colocations' exact>
<AddColocationForm />
<br/>
<ListGroup horizontal>
{data.map((colocation, idx) => {
return <ListGroup.Item key={idx}>
<Card style={{ width: '18rem' }}>
<Card.Body>
<Card.Title>{colocation.name}</Card.Title>
<Card.Text>
Owned by {colocation.administrator.email}
</Card.Text>
{ colocation.administrator.email === user.email ?
<Button variant='danger' onClick={() => history.push('/colocation/' + colocation.id)}>Manage/View</Button> :
<Button variant='primary' onClick={() => history.push('/colocation/' + colocation.id)}>View</Button> }
</Card.Body>
</Card>
</ListGroup.Item>
})}
</ListGroup>
</Route>
</>
)}
</Container>;
} else {
return <>
<br/>
<h1>Sign in to access this page</h1>
<br/>
</>;
}
}
export default Colocations;
\ No newline at end of file
import {useQuery, useMutation, useQueryCache} from 'react-query';
import {useParams} from 'react-router-dom';
import {ListGroup, Button, Container} from 'react-bootstrap';
import {TextField, Typography} from '@material-ui/core/'
import {useState} from 'react';
let Details = () => {
const queryCache = useQueryCache();
let id = parseInt(useParams().id);
let ApiURL = 'http://localhost:8080/ShareLoc/api';
let [error, setError] = useState('');
let fetchMembers = async () =>{
let URL = ApiURL + '/colocation/' + id + '/members'
let res = await fetch(URL, {
headers: {
'Authorization': 'Bearer ' + window.localStorage.getItem('token')
}
});
return res.json();
};
let createMember = user => {
let URL = ApiURL + '/colocation/' + id + '/members/add?email=' + user.email;
return fetch(URL, {
method:'POST',
headers: {
'Authorization': 'Bearer ' + window.localStorage.getItem('token'),
}
});
};
let AddMemberForm = () => {
let [email, setEmail] = useState(null);
const [mutationCreate] = useMutation(createMember, {
onSuccess: (data, variables, context) => {
if(data.status == 404) {
setError('User doesn\'t exist');
}
if(data.status == 409) {
setError('User already in colocation');
}
queryCache.invalidateQueries('Members')
}
});
const handleSubmit = event => {
event.preventDefault();
mutationCreate({ email: email });
};
return <form onSubmit={handleSubmit}>
<TextField id='email' label='New member email' size='small' variant='outlined'
onChange={(e)=>{setEmail(e.target.value)}}/> <Button as='input' type='submit' value='Add'></Button>
</form>;
};
const {data, status} = useQuery('Members', fetchMembers);
return <Container>
<br/>
<br/>
{status === 'loading' && (<div>Loading data...</div>)}
{status === 'error' && (<div>Error fetching data</div>)}
{status === 'success' && (
<>
<h1>{data[0].colocation.name}</h1>
<h2>Members</h2>
<br/>
<AddMemberForm />
<Typography color="error"><br/>{error}</Typography>
<br/>
<ListGroup>
{data.map((member, idx) => {
return <ListGroup.Item key={idx}>
<Typography variant="h6" color="primary">{member.user.email}</Typography>
<Typography color="primary">{member.user.firstName} {member.user.lastName}</Typography>
{member.sold < 0 ?
<Typography color="error">Sold : {member.sold}</Typography> :
<Typography color="primary">Sold : {member.sold}</Typography>
}
</ListGroup.Item>
})}
</ListGroup>
</>
)}
</Container>;
}
export default Details;
......@@ -13,6 +13,7 @@ import './App.css'
import Signin from './Signin'
import Signup from './Signup'
import Colocations from './Colocation'
import Details from './Details';
let useStyles = makeStyles((theme) => ({
root: {
......@@ -30,7 +31,7 @@ let ShareLoc = () => {
let history = useHistory();
let [user, setUser] = useState(null);
let [userCheck, setUserCheck] = useState(false);
let [token, setToken] = useState('');
let [token, setToken] = useState(null);
let classes = useStyles();
......@@ -75,17 +76,20 @@ let ShareLoc = () => {
let signout = () => {
setUser(null);
setToken(null);
window.localStorage.removeItem('token');
window.localStorage.removeItem('user');
history.push('/');
}
useEffect(() => {
console.log("check");
setUserCheck(true);
let token = window.localStorage.getItem('token');
if(token) {
let user = window.localStorage.getItem('user');
if(user) {
setUser(JSON.parse(user));
} else if(token) {
fetch('http://localhost:8080/ShareLoc/api/whoami', {
method: 'GET',
headers: {
......@@ -97,7 +101,8 @@ let ShareLoc = () => {
.then(res => res.json())
.then(data => {
setUser(data);
window.localStorage.setItem('user', data);
console.log(data);
window.localStorage.setItem('user', JSON.stringify(data));
})
.catch(err => { console.log(err) });
}
......@@ -135,6 +140,9 @@ let ShareLoc = () => {
<Route path='/colocations'>
<Colocations />
</Route>
<Route path='/colocation/:id'>
<Details />
</Route>
<Route path='/signin'>
<Signin signin={signin}/>
</Route>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment