mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-18 18:10:16 -04:00
233 lines
5.8 KiB
TypeScript
233 lines
5.8 KiB
TypeScript
import { useState, useCallback, useRef, useContext } from 'react';
|
|
import Button from '@material-ui/core/Button';
|
|
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 AuthenticationContext from './AuthenticationContext';
|
|
import PoolMap from './PoolMap';
|
|
|
|
import PlacesAutocomplete, {
|
|
geocodeByAddress,
|
|
getLatLng,
|
|
} from 'react-places-autocomplete';
|
|
|
|
// eslint-disable-next-line
|
|
const SAMPLE_POOL = {
|
|
id: '123',
|
|
title: 'TJ Carpool',
|
|
description: 'Carpool from TJ track to homes',
|
|
start_time: '4/10/2021 3:00 PM',
|
|
end_time: '4/10/2021 4:00 PM',
|
|
capacity: 2,
|
|
participant_ids: [],
|
|
comments: [
|
|
{
|
|
author_id: 'myfatemi04',
|
|
id: '1234',
|
|
body: "what's the vaccination status of everyone?",
|
|
},
|
|
],
|
|
driver_id: 'None',
|
|
create_time: '1234',
|
|
update_time: '1234',
|
|
group_id: 'tj',
|
|
status: 'pending',
|
|
direction: 'dropoff',
|
|
author_id: 'michael',
|
|
type: 'offer',
|
|
};
|
|
|
|
export default function Pool({
|
|
pool,
|
|
triggerUpdate,
|
|
}: {
|
|
pool: Carpool.Pool;
|
|
triggerUpdate: Function;
|
|
}) {
|
|
const { user } = useContext(AuthenticationContext);
|
|
const [address, setAddress] = useState('');
|
|
const handleChange = (address: string) => {
|
|
setAddress(address);
|
|
};
|
|
|
|
const handleSelect = (address: string) => {
|
|
setAddress(address);
|
|
};
|
|
const commentTextareaRef = useRef<HTMLTextAreaElement>(null);
|
|
const [commentStatus, setCommentStatus] = useState<
|
|
null | 'pending' | 'errored'
|
|
>(null);
|
|
|
|
const onComment = useCallback<React.MouseEventHandler<HTMLButtonElement>>(
|
|
(e) => {
|
|
e.preventDefault();
|
|
|
|
if (!commentTextareaRef.current) {
|
|
// Wait for ref to be ready
|
|
return;
|
|
}
|
|
|
|
if (commentTextareaRef.current.value.length === 0) {
|
|
// Noop, no comment to send
|
|
return;
|
|
}
|
|
|
|
setCommentStatus('pending');
|
|
|
|
makeAPIPostCall('/comment', {
|
|
body: commentTextareaRef.current!.value,
|
|
})
|
|
.then(() => {
|
|
setCommentStatus(null);
|
|
commentTextareaRef.current!.value = '';
|
|
})
|
|
.catch(() => {
|
|
setCommentStatus('errored');
|
|
});
|
|
},
|
|
[]
|
|
);
|
|
|
|
const onRegister = useCallback(() => {
|
|
makeAPIPostCall(`/pools/${pool._id}/join`)
|
|
.then(() => geocodeByAddress(address))
|
|
.then((results) => getLatLng(results[0]))
|
|
.then(({ lat, lng }) =>
|
|
makeAPIPostCall(`/addresses`, {
|
|
pool: pool._id,
|
|
location: address,
|
|
lat: lat,
|
|
lng: lng,
|
|
})
|
|
)
|
|
.then(() => triggerUpdate());
|
|
}, [pool._id, address, triggerUpdate]);
|
|
|
|
const onUnregister = useCallback(() => {
|
|
makeAPIPostCall(`/pools/${pool._id}/leave`)
|
|
.then(() =>
|
|
makeAPIPostCall(`/addresses/remove`, {
|
|
pool: pool._id,
|
|
})
|
|
)
|
|
.then(() => triggerUpdate());
|
|
}, [pool._id, triggerUpdate]);
|
|
|
|
const mapField = (
|
|
<div className="form-group">
|
|
<PlacesAutocomplete
|
|
value={address}
|
|
onChange={handleChange}
|
|
onSelect={handleSelect}
|
|
>
|
|
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
|
|
<div>
|
|
<label className="" htmlFor="address">
|
|
Address:
|
|
</label>
|
|
<input
|
|
name="address"
|
|
id="address"
|
|
{...getInputProps({
|
|
placeholder: 'Search Places ...',
|
|
className: 'location-search-input form-control',
|
|
})}
|
|
/>
|
|
<div className="autocomplete-dropdown-container">
|
|
{loading && <div>Loading...</div>}
|
|
{suggestions.map((suggestion) => {
|
|
const className = suggestion.active
|
|
? 'suggestion-item--active'
|
|
: 'suggestion-item';
|
|
// inline style for demonstration purpose
|
|
const style = suggestion.active
|
|
? { backgroundColor: '#fafafa', cursor: 'pointer' }
|
|
: { backgroundColor: '#ffffff', cursor: 'pointer' };
|
|
return (
|
|
<div
|
|
{...getSuggestionItemProps(suggestion, {
|
|
className,
|
|
style,
|
|
})}
|
|
>
|
|
<span>{suggestion.description}</span>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</PlacesAutocomplete>
|
|
</div>
|
|
);
|
|
|
|
return (
|
|
<Card style={{ margin: '3rem auto', padding: '1rem 1rem', width: '50%' }}>
|
|
{pool && (
|
|
<>
|
|
<Typography variant="h2" align="center">
|
|
{pool.title}
|
|
</Typography>
|
|
<Typography variant="subtitle1">
|
|
<b>Capacity</b>: {pool.participant_ids?.length} / {pool.capacity}
|
|
</Typography>
|
|
<Typography variant="subtitle1">
|
|
<b>Start Time</b>: {pool.start_time || '3:00 PM'}
|
|
</Typography>
|
|
<Typography variant="subtitle1">
|
|
<b>End Time</b>: {pool.end_time || '3:30 PM'}
|
|
</Typography>
|
|
<Typography variant="body1">{pool.description}</Typography>
|
|
{user && pool.participant_ids?.includes(user._id)
|
|
? undefined
|
|
: mapField}
|
|
{user && (
|
|
<Button
|
|
variant="contained"
|
|
color="primary"
|
|
style={{ marginTop: '0.5rem' }}
|
|
onClick={
|
|
pool.participant_ids?.includes(user._id)
|
|
? onUnregister
|
|
: onRegister
|
|
}
|
|
>
|
|
{pool.participant_ids?.includes(user._id)
|
|
? 'Unregister'
|
|
: 'Register'}
|
|
</Button>
|
|
)}
|
|
<hr />
|
|
<PoolMap pool={pool} />
|
|
<hr />
|
|
<Textarea
|
|
cols={80}
|
|
ref={commentTextareaRef}
|
|
placeholder="Post a comment..."
|
|
disabled={commentStatus === 'pending'}
|
|
style={{ margin: '0.5rem 0rem' }}
|
|
/>
|
|
<Button
|
|
variant="contained"
|
|
onClick={onComment}
|
|
style={{ margin: '0.5rem 0rem' }}
|
|
disabled={commentStatus === 'pending'}
|
|
>
|
|
Post Comment
|
|
</Button>
|
|
<Typography variant="subtitle1">
|
|
{commentStatus === 'errored' && 'Error posting comment'}
|
|
</Typography>
|
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
|
{pool.comments.map((comment) => (
|
|
<Comment comment={comment} key={comment.id} />
|
|
))}
|
|
</div>
|
|
</>
|
|
)}
|
|
</Card>
|
|
);
|
|
}
|