mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-21 11:20:17 -04:00
updated design for groups
This commit is contained in:
commit
7fc9f17f44
|
@ -5,6 +5,7 @@
|
|||
"dependencies": {
|
||||
"@material-ui/core": "^4.11.3",
|
||||
"@material-ui/icons": "^4.11.2",
|
||||
"@react-google-maps/api": "^2.1.1",
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
|
|
|
@ -16,6 +16,7 @@ import Main from './components/Main';
|
|||
import './App.css';
|
||||
import Authenticator from './components/Authenticator';
|
||||
import AuthenticationWrapper from './components/AuthenticationWrapper';
|
||||
import Logout from './components/Logout';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
|
@ -27,12 +28,13 @@ function App() {
|
|||
<Route component={Authenticator} path="/auth/:provider/callback" />
|
||||
<Route component={CreatePool} path="/create_pool" />
|
||||
<Route component={CreateGroup} path="/create_group" />
|
||||
<Route component={Groups} path="/groups" />
|
||||
<Route component={MyGroups} path="/mygroups" />
|
||||
<Route component={UpdatePool} path="/update_pool" />
|
||||
<Route component={Group} path="/group/:id" />
|
||||
<Route component={Pool} path="/pool/:id" />
|
||||
<Route component={Group} path="/groups/:id" />
|
||||
<Route component={Pool} path="/pools/:id" />
|
||||
<Route component={Groups} path="/groups" />
|
||||
<Route component={Profile} path="/profile" />
|
||||
<Route component={Logout} path="/logout" />
|
||||
<Route component={Home} path="/" />
|
||||
</Switch>
|
||||
</BrowserRouter>
|
||||
|
|
|
@ -32,11 +32,11 @@ export async function createSession(
|
|||
}
|
||||
|
||||
export async function getMe(): Promise<Carpool.User> {
|
||||
let result = await makeAPIGetCall('/user', { userID: '@me' });
|
||||
let result = await makeAPIGetCall('/users/@me');
|
||||
return result.data.data;
|
||||
}
|
||||
|
||||
export async function getPublicUser(id: string): Promise<Carpool.PublicUser> {
|
||||
let result = await makeAPIGetCall('/user', { userID: id });
|
||||
let result = await makeAPIGetCall(`/users/${id}`);
|
||||
return result.data.data;
|
||||
}
|
||||
|
|
16
src/api/google.ts
Normal file
16
src/api/google.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
export const GOOGLE_MAPS_API_KEY = 'AIzaSyDUnWIrt-H4RuP2YFLpVPz4oAjBhpOOoyI';
|
||||
|
||||
export async function searchForPlaces(query: string) {
|
||||
const url = new URL(
|
||||
'https://maps.googleapis.com/maps/api/place/findplacefromtext/json'
|
||||
);
|
||||
url.searchParams.set('key', GOOGLE_MAPS_API_KEY);
|
||||
url.searchParams.set('input', query);
|
||||
url.searchParams.set('inputtype', 'textquery');
|
||||
url.searchParams.set('fields', 'place_id,name,formatted_address');
|
||||
|
||||
let res = await fetch(url.toString(), { mode: 'no-cors' });
|
||||
let json = await res.json();
|
||||
|
||||
return json;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import { useContext, useEffect, useState } from 'react';
|
||||
import { Redirect, useLocation, useParams } from 'react-router-dom';
|
||||
import { API_ENDPOINT } from '../api/api';
|
||||
import { makeAPIPostCall } from '../api/utils';
|
||||
import AuthenticationContext from './AuthenticationContext';
|
||||
|
||||
export default function Authenticator() {
|
||||
|
@ -13,26 +13,15 @@ export default function Authenticator() {
|
|||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`${API_ENDPOINT}/create_session`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
code,
|
||||
provider,
|
||||
}),
|
||||
})
|
||||
makeAPIPostCall('/create_session', { code, provider })
|
||||
.then((response) => {
|
||||
response.json().then((json) => {
|
||||
if (json.status === 'success') {
|
||||
localStorage.setItem('session_token', json.token);
|
||||
refreshAuthState && refreshAuthState();
|
||||
setStatus('authenticated');
|
||||
} else {
|
||||
setStatus('errored');
|
||||
}
|
||||
});
|
||||
if (response.data.status === 'success') {
|
||||
localStorage.setItem('session_token', response.data.token);
|
||||
refreshAuthState && refreshAuthState();
|
||||
setStatus('authenticated');
|
||||
} else {
|
||||
setStatus('errored');
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
setStatus('errored');
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import { useCallback } from 'react';
|
||||
import { makeAPIPostCall } from '../api/utils';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Card from '@material-ui/core/Card';
|
||||
import CardContent from '@material-ui/core/CardContent';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { useState, useEffect } from 'react';
|
||||
import CloudUploadIcon from '@material-ui/icons/CloudUpload';
|
||||
import { useState } from 'react';
|
||||
import { makeAPIPostCall } from '../api/utils';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -22,14 +21,9 @@ const useStyles = makeStyles((theme) => ({
|
|||
const CreateGroup = () => {
|
||||
const [title, setTitle] = useState('No Title');
|
||||
const classes = useStyles();
|
||||
useEffect(() => {}, []);
|
||||
|
||||
const onClick = () => {
|
||||
console.log({
|
||||
title: title,
|
||||
});
|
||||
makeAPIPostCall('/group', {
|
||||
title,
|
||||
});
|
||||
makeAPIPostCall('/groups/', { title });
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { makeAPIPostCall } from '../api/utils';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Card from '@material-ui/core/Card';
|
||||
import CardContent from '@material-ui/core/CardContent';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import CloudUploadIcon from '@material-ui/icons/CloudUpload';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { searchForPlaces } from '../api/google';
|
||||
import { makeAPIPostCall } from '../api/utils';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
maxWidth: 345,
|
||||
|
@ -30,7 +31,7 @@ const CreatePool = () => {
|
|||
const [group, setGroup] = useState('');
|
||||
|
||||
const onClick = () => {
|
||||
makeAPIPostCall('/pool', {
|
||||
makeAPIPostCall('/pools/', {
|
||||
title,
|
||||
description,
|
||||
start_time: start,
|
||||
|
@ -49,128 +50,140 @@ const CreatePool = () => {
|
|||
style={{ margin: '0.5rem', background: '#F3F5F4' }}
|
||||
>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="h5" component="h2"></Typography>
|
||||
<Typography variant="body2" color="textSecondary" component="p">
|
||||
<form>
|
||||
<div className="form-group">
|
||||
<h1 className="form-title" style={{ fontFamily: 'Impact' }}>
|
||||
Create Pool
|
||||
</h1>
|
||||
<label className="" htmlFor="title">
|
||||
Pool Title:{' '}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
className="form-control d-flex"
|
||||
placeholder="Enter title here..."
|
||||
onChange={(event) => setTitle(event.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="capacity">
|
||||
Pool Capacity:
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id="capacity"
|
||||
name="capacity"
|
||||
className="form-control d-flex"
|
||||
placeholder="0"
|
||||
onChange={(event) =>
|
||||
setCapacity(parseInt(event.target.value))
|
||||
}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_start">
|
||||
Start Time:
|
||||
</label>
|
||||
<input
|
||||
type="datetime-local"
|
||||
id="pool_start"
|
||||
name="pool_start"
|
||||
className="form-control"
|
||||
placeholder=""
|
||||
onChange={(event) => setStart(event.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_end">
|
||||
End Time:
|
||||
</label>
|
||||
<input
|
||||
type="datetime-local"
|
||||
id="pool_end"
|
||||
name="pool_end"
|
||||
className="form-control"
|
||||
placeholder="Enter text here..."
|
||||
onChange={(event) => setEnd(event.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_direction">
|
||||
Direction:
|
||||
</label>
|
||||
<select
|
||||
id="direction"
|
||||
name="direction"
|
||||
onChange={(event) => setDirection(event.target.value)}
|
||||
>
|
||||
<option value="pickup">Picking Up</option>
|
||||
<option value="dropoff">Dropping Off</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_type">
|
||||
Type:
|
||||
</label>
|
||||
<select
|
||||
id="type"
|
||||
name="type"
|
||||
onChange={(event) => setType(event.target.value)}
|
||||
>
|
||||
<option value="offer">Offering carpool</option>
|
||||
<option value="request">Requesting carpooll</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="title">
|
||||
Pool Description:
|
||||
</label>
|
||||
<textarea
|
||||
onChange={(event) => setDescription(event.target.value)}
|
||||
id="Pool-text"
|
||||
name="Pool-text"
|
||||
style={{ height: '200px' }}
|
||||
className="form-control"
|
||||
placeholder="Enter text here..."
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_start">
|
||||
Group:
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder=""
|
||||
onChange={(event) => setGroup(event.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={classes.button}
|
||||
onClick={onClick}
|
||||
startIcon={<CloudUploadIcon />}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
<br />
|
||||
</form>
|
||||
</Typography>
|
||||
<div className="form-group">
|
||||
<h1 className="form-title">Create Pool</h1>
|
||||
<label className="" htmlFor="title">
|
||||
Pool Title:{' '}
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="title"
|
||||
name="title"
|
||||
className="form-control d-flex"
|
||||
placeholder="Enter title here..."
|
||||
onChange={(event) => setTitle(event.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="capacity">
|
||||
Pool Capacity:
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
id="capacity"
|
||||
name="capacity"
|
||||
className="form-control d-flex"
|
||||
placeholder="0"
|
||||
onChange={(event) => setCapacity(parseInt(event.target.value))}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_start">
|
||||
Start Time:
|
||||
</label>
|
||||
<input
|
||||
type="datetime-local"
|
||||
id="pool_start"
|
||||
name="pool_start"
|
||||
className="form-control"
|
||||
placeholder=""
|
||||
onChange={(event) => setStart(event.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_end">
|
||||
End Time:
|
||||
</label>
|
||||
<input
|
||||
type="datetime-local"
|
||||
id="pool_end"
|
||||
name="pool_end"
|
||||
className="form-control"
|
||||
placeholder="Enter text here..."
|
||||
onChange={(event) => setEnd(event.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_direction">
|
||||
Direction:
|
||||
</label>
|
||||
<select
|
||||
id="direction"
|
||||
name="direction"
|
||||
onChange={(event) => setDirection(event.target.value)}
|
||||
>
|
||||
<option value="pickup">Picking Up</option>
|
||||
<option value="dropoff">Dropping Off</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_type">
|
||||
Type:
|
||||
</label>
|
||||
<select
|
||||
id="type"
|
||||
name="type"
|
||||
onChange={(event) => setType(event.target.value)}
|
||||
>
|
||||
<option value="offer">Offering carpool</option>
|
||||
<option value="request">Requesting carpool</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="title">
|
||||
Pool Description:
|
||||
</label>
|
||||
<textarea
|
||||
onChange={(event) => setDescription(event.target.value)}
|
||||
id="Pool-text"
|
||||
name="Pool-text"
|
||||
style={{ height: '200px' }}
|
||||
className="form-control"
|
||||
placeholder="Enter text here..."
|
||||
/>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="pool_start">
|
||||
Group:
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
placeholder=""
|
||||
onChange={(event) => setGroup(event.target.value)}
|
||||
></input>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="" htmlFor="location">
|
||||
Location:
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="location_input"
|
||||
></input>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
let input = document.getElementById(
|
||||
'location_input'
|
||||
) as HTMLInputElement;
|
||||
let places = searchForPlaces(input.value);
|
||||
console.log(places);
|
||||
}}
|
||||
>
|
||||
Search
|
||||
</button>
|
||||
</div>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
className={classes.button}
|
||||
onClick={onClick}
|
||||
startIcon={<CloudUploadIcon />}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
|
|
@ -10,7 +10,7 @@ const maybePluralize = (count: number, noun: string, suffix = 's') =>
|
|||
|
||||
const SAMPLE_POOLS: Carpool.Pool[] = [
|
||||
{
|
||||
id: '1234',
|
||||
_id: '1234',
|
||||
title: 'TJ Carpool',
|
||||
description: 'Carpool from TJ track to homes',
|
||||
start_time: '4/10/2021 3:00 PM',
|
||||
|
@ -43,7 +43,7 @@ export default function Group() {
|
|||
const [pools, setPools] = useState<Carpool.Pool[]>(SAMPLE_POOLS);
|
||||
|
||||
useEffect(() => {
|
||||
makeAPIGetCall('/group', { groupID: id }).then((res) => {
|
||||
makeAPIGetCall(`/groups/${id}`).then((res) => {
|
||||
if ('error' in res.data) {
|
||||
setError(true);
|
||||
} else {
|
||||
|
@ -51,7 +51,7 @@ export default function Group() {
|
|||
}
|
||||
});
|
||||
|
||||
makeAPIGetCall('/group_pools', { groupID: id }).then((res) => {
|
||||
makeAPIGetCall(`/groups/${id}/pools`).then((res) => {
|
||||
setPools(res.data.data);
|
||||
});
|
||||
}, [id]);
|
||||
|
@ -90,7 +90,7 @@ export default function Group() {
|
|||
{pools.map((pool, index) => {
|
||||
return (
|
||||
<Card style={{ margin: '0.5em' }} key={index}>
|
||||
<a href={'/Pool/' + pool.id} className="card-title">
|
||||
<a href={'/pools/' + pool._id} className="card-title">
|
||||
{pool.title}
|
||||
</a>
|
||||
<p className="text-left">
|
||||
|
|
|
@ -8,6 +8,7 @@ import { makeStyles } from '@material-ui/core/styles';
|
|||
import Typography from '@material-ui/core/Typography';
|
||||
import CloudUploadIcon from '@material-ui/icons/CloudUpload';
|
||||
import Box from '@material-ui/core/Box';
|
||||
import { makeAPIGetCall } from '../api/utils';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -45,10 +46,23 @@ const Groups = () => {
|
|||
}
|
||||
});
|
||||
};
|
||||
const [groups, setGroups] = useState<Carpool.Group[]>([
|
||||
{
|
||||
_id: '1234',
|
||||
name: 'TJ',
|
||||
creator_id: 'michael',
|
||||
member_ids: [],
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
callAPI();
|
||||
makeAPIGetCall('/browse/groups').then((res) => {
|
||||
if (res.data.data) {
|
||||
setGroups(res.data.data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className=""
|
||||
|
@ -72,22 +86,17 @@ const Groups = () => {
|
|||
</Box>
|
||||
<div className="container" style={{ fontFamily: 'Courier New' }}>
|
||||
<br></br>
|
||||
{state.MyGroups.map((group, index) => {
|
||||
let background;
|
||||
if (index % 2 === 0) {
|
||||
background = '#F1EAE8';
|
||||
} else {
|
||||
background = '#FFFFFF';
|
||||
}
|
||||
|
||||
{groups.map((group, index) => {
|
||||
return (
|
||||
<Card
|
||||
className={classes.root + 'd-inline-flex'}
|
||||
style={{ margin: '0.5rem' }}
|
||||
>
|
||||
<CardActionArea href={'/group/' + group.id}>
|
||||
<CardActionArea href={'/group/' + group._id}>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="h5" component="h2">
|
||||
{group.group_title}
|
||||
{group.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
|
@ -102,19 +111,27 @@ const Groups = () => {
|
|||
size="small"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
let link: string = 'localhost:3000/group/' + group.id;
|
||||
alert('Copied to Clipboard');
|
||||
let link: string = 'localhost:3000/group/' + group._id;
|
||||
navigator.clipboard.writeText(link);
|
||||
}}
|
||||
>
|
||||
Share
|
||||
</Button>
|
||||
<Button
|
||||
href={'/group/' + group.id}
|
||||
href={'/group/' + group._id}
|
||||
size="small"
|
||||
color="primary"
|
||||
>
|
||||
Learn More
|
||||
</Button>
|
||||
<form action={'/requestgroup/' + group._id} method="POST">
|
||||
<input
|
||||
type="submit"
|
||||
value="Request to Join"
|
||||
className="btn btn-success d-flex"
|
||||
/>
|
||||
</form>
|
||||
</CardActions>
|
||||
</Card>
|
||||
);
|
||||
|
|
|
@ -8,6 +8,7 @@ import { makeStyles } from '@material-ui/core/styles';
|
|||
import Typography from '@material-ui/core/Typography';
|
||||
import CloudUploadIcon from '@material-ui/icons/CloudUpload';
|
||||
import Box from '@material-ui/core/Box';
|
||||
import { makeAPIGetCall } from '../api/utils';
|
||||
|
||||
const useStyles = makeStyles((theme) => ({
|
||||
root: {
|
||||
|
@ -45,10 +46,23 @@ const MyGroups = () => {
|
|||
}
|
||||
});
|
||||
};
|
||||
const [groups, setGroups] = useState<Carpool.Group[]>([
|
||||
{
|
||||
_id: '1234',
|
||||
name: 'TJ',
|
||||
creator_id: '12345Q',
|
||||
member_ids: [],
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
callAPI();
|
||||
makeAPIGetCall('/browse/groups').then((res) => {
|
||||
if (res.data.data) {
|
||||
setGroups(res.data.data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div
|
||||
className=""
|
||||
|
@ -72,7 +86,7 @@ const MyGroups = () => {
|
|||
</Box>
|
||||
<div className="container" style={{ fontFamily: 'Courier New' }}>
|
||||
<br></br>
|
||||
{state.MyGroups.map((group, index) => {
|
||||
{groups.map((group, index) => {
|
||||
let background;
|
||||
if (index % 2 === 0) {
|
||||
background = '#F1EAE8';
|
||||
|
@ -84,10 +98,10 @@ const MyGroups = () => {
|
|||
className={classes.root + 'd-inline-flex'}
|
||||
style={{ margin: '0.5rem' }}
|
||||
>
|
||||
<CardActionArea href={'/group/' + group.id}>
|
||||
<CardActionArea href={'/group/' + group._id}>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="h5" component="h2">
|
||||
{group.group_title}
|
||||
{group.name}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="body2"
|
||||
|
@ -102,14 +116,15 @@ const MyGroups = () => {
|
|||
size="small"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
let link: string = 'localhost:3000/group/' + group.id;
|
||||
alert('Copied to Clipboard');
|
||||
let link: string = 'localhost:3000/group/' + group._id;
|
||||
navigator.clipboard.writeText(link);
|
||||
}}
|
||||
>
|
||||
Share
|
||||
</Button>
|
||||
<Button
|
||||
href={'/group/' + group.id}
|
||||
href={'/group/' + group._id}
|
||||
size="small"
|
||||
color="primary"
|
||||
>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { API_ENDPOINT } from '../api/api';
|
||||
import { makeAPIGetCall } from '../api/utils';
|
||||
|
||||
const MyPools = () => {
|
||||
// const id = props.match.params.id;
|
||||
|
@ -55,14 +56,11 @@ const MyPools = () => {
|
|||
]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(process.env);
|
||||
fetch(`${API_ENDPOINT}/my_pools`)
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
if (json) {
|
||||
setPools(json.data);
|
||||
}
|
||||
});
|
||||
makeAPIGetCall('/users/@me/pools').then((res) => {
|
||||
if (res.data.data) {
|
||||
setPools(res.data.data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
const maybePluralize = (count: number, noun: string, suffix = 's') =>
|
||||
|
@ -96,7 +94,7 @@ const MyPools = () => {
|
|||
className="card card-body text-left"
|
||||
style={{ backgroundColor: background }}
|
||||
>
|
||||
<a href={'/Pool/' + pool.id} className="card-title">
|
||||
<a href={'/pools/' + pool.id} className="card-title">
|
||||
{pool.pool_title}
|
||||
</a>
|
||||
<p className="text-left">
|
||||
|
|
|
@ -5,7 +5,7 @@ import Card from '@material-ui/core/Card';
|
|||
import Textarea from '@material-ui/core/TextareaAutosize';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Comment from './Comment';
|
||||
import { makeAPIPostCall } from '../api/utils';
|
||||
import { makeAPIGetCall, makeAPIPostCall } from '../api/utils';
|
||||
import AuthenticationContext from './AuthenticationContext';
|
||||
|
||||
// eslint-disable-next-line
|
||||
|
@ -76,8 +76,8 @@ export default function Pool() {
|
|||
|
||||
const onRegister = useCallback(() => {
|
||||
if (user) {
|
||||
let userID = user.id;
|
||||
makeAPIPostCall('/join_pool', { id }).then(() => {
|
||||
let userID = user._id;
|
||||
makeAPIPostCall(`/pools/${id}/join`).then(() => {
|
||||
if (pool) {
|
||||
setPool({
|
||||
...pool,
|
||||
|
@ -89,13 +89,11 @@ export default function Pool() {
|
|||
}, [user, id, pool]);
|
||||
|
||||
useEffect(() => {
|
||||
fetch(`${process.env.REACT_APP_API_ENDPOINT}/pool/${id}`)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data !== undefined) {
|
||||
setPool(data);
|
||||
}
|
||||
});
|
||||
makeAPIGetCall(`/pools/${id}`).then((response) => {
|
||||
if (response.data.data) {
|
||||
setPool(response.data.data);
|
||||
}
|
||||
});
|
||||
}, [id]);
|
||||
|
||||
return (
|
||||
|
@ -106,7 +104,7 @@ export default function Pool() {
|
|||
{pool.title}
|
||||
</Typography>
|
||||
<Typography variant="subtitle1">
|
||||
<b>Capacity</b>: {pool.participant_ids.length} / {pool.capacity}
|
||||
<b>Capacity</b>: {pool.participant_ids?.length} / {pool.capacity}
|
||||
</Typography>
|
||||
<Typography variant="subtitle1">
|
||||
<b>Start Time</b>: {pool.start_time}
|
||||
|
@ -122,7 +120,7 @@ export default function Pool() {
|
|||
style={{ marginTop: '0.5rem' }}
|
||||
onClick={onRegister}
|
||||
>
|
||||
{pool.participant_ids.includes(user.id)
|
||||
{pool.participant_ids?.includes(user._id)
|
||||
? 'Unregister'
|
||||
: 'Register'}
|
||||
</Button>
|
||||
|
|
3
src/components/PoolMap.tsx
Normal file
3
src/components/PoolMap.tsx
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function PoolMap() {
|
||||
//
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import { API_ENDPOINT } from '../api/api';
|
||||
import { makeAPIGetCall } from '../api/utils';
|
||||
|
||||
const maybePluralize = (count: number, noun: string, suffix = 's') =>
|
||||
`${count} ${noun}${count !== 1 ? suffix : ''}`;
|
||||
|
@ -58,14 +59,11 @@ const Pools = () => {
|
|||
]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(process.env);
|
||||
fetch(`${API_ENDPOINT}/my_pools`)
|
||||
.then((response) => response.json())
|
||||
.then((json) => {
|
||||
if (json) {
|
||||
setPools(json.data);
|
||||
}
|
||||
});
|
||||
makeAPIGetCall(`/users/@me/pools`).then((res) => {
|
||||
if (res.data.data) {
|
||||
setPools(res.data.data);
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
@ -97,7 +95,7 @@ const Pools = () => {
|
|||
className="card card-body text-left"
|
||||
style={{ backgroundColor: background }}
|
||||
>
|
||||
<a href={'/Pool/' + pool.id} className="card-title">
|
||||
<a href={'/pools/' + pool._id} className="card-title">
|
||||
{pool.title}
|
||||
</a>
|
||||
<p className="text-left">
|
||||
|
@ -105,7 +103,7 @@ const Pools = () => {
|
|||
</p>
|
||||
<p className="text-left">Start Time: {pool.start_time}</p>
|
||||
<p className="text-left">End Time: {pool.end_time}</p>
|
||||
<p className="" style={{color: '#9E6105'}}>
|
||||
<p className="" style={{ color: '#9E6105' }}>
|
||||
{maybePluralize(pool.comments.length, 'comment')}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -20,14 +20,18 @@ const useStyles = makeStyles({
|
|||
|
||||
const Profile = () => {
|
||||
const { user } = useContext(AuthenticationContext);
|
||||
// const [groups, setGroups] = useState<Carpool.Group[]>([]);
|
||||
const [groups, setGroups] = useState<Carpool.Group[]>([]);
|
||||
const [pools, setPools] = useState<Carpool.Pool[]>([]);
|
||||
const classes = useStyles();
|
||||
|
||||
useEffect(() => {
|
||||
makeAPIGetCall('/my_pools').then((res) => {
|
||||
makeAPIGetCall('/users/@me/pools').then((res) => {
|
||||
if (res.data.data) setPools(res.data.data);
|
||||
});
|
||||
|
||||
makeAPIGetCall('/users/@me/groups').then((res) => {
|
||||
if (res.data.data) setGroups(res.data.data);
|
||||
});
|
||||
}, []);
|
||||
|
||||
if (!user) {
|
||||
|
@ -47,16 +51,16 @@ const Profile = () => {
|
|||
</h1>
|
||||
<div className="container">
|
||||
<h2>
|
||||
<u>{user.username}'s Pools</u>
|
||||
<u>My Pools (private)</u>
|
||||
</h2>
|
||||
<div className="">
|
||||
<div>
|
||||
{pools.map((pool) => {
|
||||
return (
|
||||
<Card
|
||||
className={classes.root + 'd-inline-flex'}
|
||||
style={{ margin: '0.5rem' }}
|
||||
>
|
||||
<CardActionArea href={'/pool/' + pool.id}>
|
||||
<CardActionArea href={'/pools/' + pool._id}>
|
||||
<CardContent>
|
||||
<Typography gutterBottom variant="h5" component="h2">
|
||||
{pool.title}
|
||||
|
@ -75,14 +79,14 @@ const Profile = () => {
|
|||
size="small"
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
let link: string = 'localhost:3000/pool/' + pool.id;
|
||||
let link: string = 'localhost:3000/pools/' + pool._id;
|
||||
navigator.clipboard.writeText(link);
|
||||
}}
|
||||
>
|
||||
Share
|
||||
</Button>
|
||||
<Button
|
||||
href={'/pool/' + pool.id}
|
||||
href={'/pools/' + pool._id}
|
||||
size="small"
|
||||
color="primary"
|
||||
>
|
||||
|
@ -93,6 +97,24 @@ const Profile = () => {
|
|||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<h2>
|
||||
<u>My Groups (private)</u>
|
||||
<div>
|
||||
{groups.map((group) => {
|
||||
return (
|
||||
<Card
|
||||
key={group._id}
|
||||
style={{ padding: '0.5rem', margin: '0.5rem' }}
|
||||
>
|
||||
<h1>
|
||||
<a href={'/groups/' + group._id}>{group.name}</a>
|
||||
</h1>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import React, {
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
FormEventHandler,
|
||||
} from 'react';
|
||||
import { useState, useEffect, FormEventHandler } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { makeAPIGetCall } from '../api/utils';
|
||||
|
||||
const UpdatePool = () => {
|
||||
const id = useParams<{ id: string }>().id;
|
||||
|
@ -21,26 +17,17 @@ const UpdatePool = () => {
|
|||
comments: ['What is the covid vaccination status of all the participants?'],
|
||||
});
|
||||
|
||||
const callAPI = useCallback(() => {
|
||||
fetch(`${process.env.REACT_APP_API_ENDPOINT}/pool/${id}`)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
if (data !== undefined) {
|
||||
setPool(data);
|
||||
}
|
||||
});
|
||||
}, [id]);
|
||||
const onSubmit: FormEventHandler<HTMLFormElement> = (e) => {
|
||||
e.preventDefault();
|
||||
fetch(`${process.env.REACT_APP_API_ENDPOINT}/update_pool`)
|
||||
.then((response) => response.json())
|
||||
.then((data) => {
|
||||
console.log(data);
|
||||
});
|
||||
makeAPIGetCall(`/pools/${id}`).then((res) => {
|
||||
console.log(res);
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
callAPI();
|
||||
}, [callAPI]);
|
||||
makeAPIGetCall(`/pools/${id}`).then((res) => {
|
||||
if (res.data.data) setPool(res.data.data);
|
||||
});
|
||||
}, [id]);
|
||||
return (
|
||||
<div
|
||||
className="bg-dark"
|
||||
|
|
8
src/types.d.ts
vendored
8
src/types.d.ts
vendored
|
@ -1,6 +1,6 @@
|
|||
declare namespace Carpool {
|
||||
export interface Group {
|
||||
id: string;
|
||||
_id: string;
|
||||
name: string;
|
||||
member_ids: string[];
|
||||
creator_id: string;
|
||||
|
@ -8,14 +8,14 @@ declare namespace Carpool {
|
|||
|
||||
// Omits the email attribute
|
||||
export interface PublicUser {
|
||||
id: string;
|
||||
_id: string;
|
||||
username: string;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: string;
|
||||
_id: string;
|
||||
email: string;
|
||||
username: string;
|
||||
first_name: string;
|
||||
|
@ -31,7 +31,7 @@ declare namespace Carpool {
|
|||
export type Status = 'pending' | 'cancelled' | 'completed' | 'interrupted';
|
||||
|
||||
export interface Pool {
|
||||
id: string;
|
||||
_id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
participant_ids: string[];
|
||||
|
|
Loading…
Reference in New Issue
Block a user