mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-16 00:50:18 -04:00
161 lines
3.7 KiB
TypeScript
161 lines
3.7 KiB
TypeScript
import { useCallback, useEffect, useState } from 'react';
|
|
import { green, lightgrey } from '../../lib/colors';
|
|
import getPlaceDetails from '../../lib/getPlaceDetails';
|
|
import { addOrUpdateEventSignup, getEvent, removeEventSignup } from '../api';
|
|
import { useMe } from '../hooks';
|
|
import { IEvent } from '../types';
|
|
import UIButton from '../UI/UIButton';
|
|
import UILink from '../UI/UILink';
|
|
import UIPlacesAutocomplete from '../UI/UIPlacesAutocomplete';
|
|
import UISecondaryBox from '../UI/UISecondaryBox';
|
|
import UISecondaryHeader from '../UI/UISecondaryHeader';
|
|
import useImmutable from '../useImmutable';
|
|
import EventCarpools from './EventCarpools';
|
|
import EventContext from './EventContext';
|
|
import EventDetails from './EventDetails';
|
|
import EventSignups from './EventSignups';
|
|
|
|
function GroupName({ group }: { group: IEvent['group'] }) {
|
|
return <UILink href={`/groups/${group.id}`}>{group.name}</UILink>;
|
|
}
|
|
|
|
export default function Event({
|
|
id,
|
|
initial,
|
|
}: {
|
|
id: number;
|
|
initial?: IEvent;
|
|
}) {
|
|
const [event, setEvent] = useImmutable<IEvent>({
|
|
id,
|
|
name: '',
|
|
group: {
|
|
id: 0,
|
|
name: '',
|
|
},
|
|
signups: {},
|
|
carpools: [],
|
|
startTime: '',
|
|
endTime: '',
|
|
daysOfWeek: 0,
|
|
placeId: '',
|
|
formattedAddress: '',
|
|
latitude: 0,
|
|
longitude: 0,
|
|
duration: 0,
|
|
...(initial || {}),
|
|
});
|
|
|
|
const [found, setFound] = useState(false);
|
|
|
|
const me = useMe() || { id: 0, name: '' };
|
|
|
|
const [tentativeInvites] = useImmutable<Record<number, boolean>>({});
|
|
|
|
const refresh = useCallback(() => {
|
|
getEvent(id).then((e) => {
|
|
if (e) {
|
|
setFound(true);
|
|
setEvent(e);
|
|
} else {
|
|
setFound(false);
|
|
}
|
|
});
|
|
}, [id, setEvent]);
|
|
|
|
useEffect(refresh, [refresh]);
|
|
|
|
const updateSignup = useCallback(
|
|
async (placeId: string | null) => {
|
|
await addOrUpdateEventSignup(id, placeId);
|
|
|
|
if (placeId) {
|
|
const details = await getPlaceDetails(placeId);
|
|
|
|
event.signups[me.id] = {
|
|
user: { id: me.id, name: me.name },
|
|
placeId,
|
|
...details,
|
|
};
|
|
} else {
|
|
event.signups[me.id] = {
|
|
user: { id: me.id, name: me.name },
|
|
placeId: null,
|
|
latitude: null,
|
|
longitude: null,
|
|
formattedAddress: null,
|
|
};
|
|
}
|
|
},
|
|
[event.signups, id, me.id, me.name]
|
|
);
|
|
|
|
const removeSignup = useCallback(async () => {
|
|
await removeEventSignup(id);
|
|
|
|
if (event.signups[me.id]) {
|
|
delete event.signups[me.id];
|
|
}
|
|
}, [id, me.id, event.signups]);
|
|
|
|
const interested = !!event.signups[me.id];
|
|
|
|
if (!found) {
|
|
return (
|
|
<>
|
|
<h1>Event Not Found</h1>
|
|
</>
|
|
);
|
|
}
|
|
|
|
const { name, group, formattedAddress, startTime, endTime } = event;
|
|
|
|
return (
|
|
<EventContext.Provider
|
|
value={{
|
|
event,
|
|
refresh,
|
|
default: false,
|
|
tentativeInvites,
|
|
}}
|
|
>
|
|
<UISecondaryBox>
|
|
<div style={{ textAlign: 'center' }}>
|
|
<UISecondaryHeader>{name}</UISecondaryHeader>
|
|
{group && <GroupName group={group} />}
|
|
</div>
|
|
<EventDetails {...{ startTime, endTime, formattedAddress }} />
|
|
<UIButton
|
|
onClick={interested ? () => removeSignup() : () => updateSignup(null)}
|
|
style={{
|
|
backgroundColor: interested ? green : lightgrey,
|
|
color: interested ? 'white' : 'black',
|
|
transition: 'color 0.2s, background-color 0.2s',
|
|
}}
|
|
>
|
|
{interested ? 'Interested' : 'Not interested'}
|
|
</UIButton>
|
|
{interested && (
|
|
<>
|
|
<UIPlacesAutocomplete
|
|
placeholder="Pickup and dropoff location"
|
|
onSelected={(_address, placeId) => {
|
|
updateSignup(placeId);
|
|
}}
|
|
style={
|
|
event.signups[me.id]?.placeId != null
|
|
? { border: '2px solid ' + green }
|
|
: {}
|
|
}
|
|
placeId={event.signups[me.id]?.placeId}
|
|
/>
|
|
<br />
|
|
<EventCarpools />
|
|
{event.signups !== null && <EventSignups />}
|
|
</>
|
|
)}
|
|
</UISecondaryBox>
|
|
</EventContext.Provider>
|
|
);
|
|
}
|