mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-21 11:20:17 -04:00
Make it possible to request a carpool directly from the event page
This commit is contained in:
parent
bafc26fb06
commit
66ec0019c1
|
@ -1,10 +1,11 @@
|
|||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { green, lightgrey } from '../../lib/colors';
|
||||
import {
|
||||
addOrUpdateEventSignup,
|
||||
getEvent,
|
||||
getEventSignups,
|
||||
removeEventSignup,
|
||||
} from '../api';
|
||||
import { green, lightgrey } from '../../lib/colors';
|
||||
import { useMe } from '../hooks';
|
||||
import { IEvent, IEventSignup } from '../types';
|
||||
import UIButton from '../UI/UIButton';
|
||||
|
@ -14,6 +15,7 @@ import UISecondaryBox from '../UI/UISecondaryBox';
|
|||
import UISecondaryHeader from '../UI/UISecondaryHeader';
|
||||
import useThrottle from '../useThrottle';
|
||||
import EventCarpools from './EventCarpools';
|
||||
import EventContext from './EventContext';
|
||||
import EventDetails from './EventDetails';
|
||||
import EventSignups from './EventSignups';
|
||||
|
||||
|
@ -21,8 +23,14 @@ function GroupName({ group }: { group: IEvent['group'] }) {
|
|||
return <UILink href={`/groups/${group.id}`}>{group.name}</UILink>;
|
||||
}
|
||||
|
||||
export default function Event({ event }: { event: IEvent }) {
|
||||
const { name, group, formattedAddress, startTime, endTime } = event;
|
||||
export default function Event({
|
||||
id,
|
||||
initial,
|
||||
}: {
|
||||
id: number;
|
||||
initial?: IEvent;
|
||||
}) {
|
||||
const [event, setEvent] = useState<IEvent | null>(initial || null);
|
||||
const [placeId, setPlaceId] = useState<string | null>(null);
|
||||
const [interested, setInterested] = useState(false);
|
||||
const [updating, setUpdating] = useState(false);
|
||||
|
@ -36,6 +44,12 @@ export default function Event({ event }: { event: IEvent }) {
|
|||
});
|
||||
const me = useMe();
|
||||
|
||||
const refresh = useCallback(() => {
|
||||
getEvent(id).then(setEvent);
|
||||
}, [id]);
|
||||
|
||||
useEffect(refresh, [refresh]);
|
||||
|
||||
useEffect(() => {
|
||||
if (signups === null) {
|
||||
return;
|
||||
|
@ -43,7 +57,7 @@ export default function Event({ event }: { event: IEvent }) {
|
|||
|
||||
const removeSignup = () => {
|
||||
if (prev.interested) {
|
||||
removeEventSignup(event.id)
|
||||
removeEventSignup(id)
|
||||
.then(() => {
|
||||
prev.interested = false;
|
||||
})
|
||||
|
@ -56,13 +70,13 @@ export default function Event({ event }: { event: IEvent }) {
|
|||
console.log('Adding or updating signup.', prev, {
|
||||
interested,
|
||||
placeId,
|
||||
eventId: event.id,
|
||||
eventId: id,
|
||||
signups,
|
||||
});
|
||||
addOrUpdateEventSignup(event.id, placeId)
|
||||
addOrUpdateEventSignup(id, placeId)
|
||||
.then(() => {
|
||||
prev.placeId = placeId;
|
||||
prev.eventId = event.id;
|
||||
prev.eventId = id;
|
||||
prev.interested = true;
|
||||
})
|
||||
.finally(() => setUpdating(false));
|
||||
|
@ -76,16 +90,16 @@ export default function Event({ event }: { event: IEvent }) {
|
|||
} else {
|
||||
addOrUpdateSignup();
|
||||
}
|
||||
}, [event.id, interested, placeId, signups, updating]);
|
||||
}, [id, interested, placeId, signups, updating]);
|
||||
|
||||
useEffect(() => {
|
||||
getEventSignups(event.id)
|
||||
getEventSignups(id)
|
||||
.then((signups) => {
|
||||
for (let signup of signups) {
|
||||
if (signup.user.id === me?.id) {
|
||||
setInterested(true);
|
||||
setPlaceId(signup.placeId);
|
||||
existingSignup.current.eventId = event.id;
|
||||
existingSignup.current.eventId = id;
|
||||
existingSignup.current.placeId = signup.placeId;
|
||||
existingSignup.current.interested = true;
|
||||
}
|
||||
|
@ -93,9 +107,16 @@ export default function Event({ event }: { event: IEvent }) {
|
|||
setSignups(signups);
|
||||
})
|
||||
.catch(console.error);
|
||||
}, [event.id, me?.id]);
|
||||
}, [id, me?.id]);
|
||||
|
||||
if (!event) {
|
||||
return <UISecondaryBox>Loading...</UISecondaryBox>;
|
||||
}
|
||||
|
||||
const { name, group, formattedAddress, startTime, endTime } = event;
|
||||
|
||||
return (
|
||||
<EventContext.Provider value={{ event, refresh, default: false }}>
|
||||
<UISecondaryBox>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<UISecondaryHeader>{name}</UISecondaryHeader>
|
||||
|
@ -123,12 +144,17 @@ export default function Event({ event }: { event: IEvent }) {
|
|||
placeId={placeId}
|
||||
/>
|
||||
<br />
|
||||
<EventCarpools event={event} />
|
||||
<EventCarpools />
|
||||
{signups !== null && (
|
||||
<EventSignups event={event} myPlaceId={placeId} signups={signups} />
|
||||
<EventSignups
|
||||
event={event}
|
||||
myPlaceId={placeId}
|
||||
signups={signups}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</UISecondaryBox>
|
||||
</EventContext.Provider>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,41 @@
|
|||
// import CallMergeIcon from '@material-ui/icons/CallMerge';
|
||||
import CancelIcon from '@material-ui/icons/Cancel';
|
||||
import CheckIcon from '@material-ui/icons/Check';
|
||||
import EmojiPeopleIcon from '@material-ui/icons/EmojiPeople';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { useCallback, useContext, useMemo, useState } from 'react';
|
||||
import { createCarpool } from '../api';
|
||||
import { lightgrey } from '../../lib/colors';
|
||||
import { useMe } from '../hooks';
|
||||
import { IEvent } from '../types';
|
||||
import UIButton from '../UI/UIButton';
|
||||
import UILink from '../UI/UILink';
|
||||
import EventContext from './EventContext';
|
||||
import {
|
||||
useCancelCarpoolRequest,
|
||||
useInvitationState,
|
||||
useSendCarpoolRequest,
|
||||
} from '../../state/Notifications/NotificationsHooks';
|
||||
|
||||
function CarpoolRow({ carpool }: { carpool: IEvent['carpools'][0] }) {
|
||||
function CarpoolRow({
|
||||
carpool,
|
||||
inCarpoolAlready,
|
||||
}: {
|
||||
carpool: IEvent['carpools'][0];
|
||||
inCarpoolAlready: boolean;
|
||||
}) {
|
||||
const PADDING = '1rem';
|
||||
const inviteState = useInvitationState(carpool.id);
|
||||
|
||||
const cancelCarpoolRequest = useCancelCarpoolRequest();
|
||||
const sendCarpoolRequest = useSendCarpoolRequest();
|
||||
|
||||
const sendButton = useCallback(() => {
|
||||
sendCarpoolRequest(carpool.id);
|
||||
}, [sendCarpoolRequest, carpool.id]);
|
||||
|
||||
const cancelButton = useCallback(() => {
|
||||
cancelCarpoolRequest(carpool.id);
|
||||
}, [cancelCarpoolRequest, carpool.id]);
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
|
@ -40,14 +66,32 @@ function CarpoolRow({ carpool }: { carpool: IEvent['carpools'][0] }) {
|
|||
<b>{carpool.extraDistance} miles</b>
|
||||
</div> */}
|
||||
{/* </div> */}
|
||||
<EmojiPeopleIcon style={{ fontSize: '2em' }} />
|
||||
{!inCarpoolAlready && (
|
||||
<>
|
||||
{inviteState === 'none' ? (
|
||||
<EmojiPeopleIcon
|
||||
style={{ fontSize: '2em', cursor: 'pointer' }}
|
||||
onClick={sendButton}
|
||||
/>
|
||||
) : inviteState === 'requested' ? (
|
||||
<CancelIcon
|
||||
style={{ fontSize: '2em', cursor: 'pointer' }}
|
||||
onClick={cancelButton}
|
||||
/>
|
||||
) : (
|
||||
// inviteState === 'invited
|
||||
<CheckIcon style={{ fontSize: '2em', cursor: 'pointer' }} />
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
type CreationStatus = null | 'pending' | 'completed' | 'errored';
|
||||
|
||||
export default function Carpools({ event }: { event: IEvent }) {
|
||||
export default function Carpools() {
|
||||
const { event } = useContext(EventContext);
|
||||
const [creationStatus, setCreationStatus] = useState<CreationStatus>(null);
|
||||
const [createdCarpoolId, setCreatedCarpoolId] = useState<null | number>(null);
|
||||
|
||||
|
@ -59,7 +103,8 @@ export default function Carpools({ event }: { event: IEvent }) {
|
|||
),
|
||||
[event.carpools, me.id]
|
||||
);
|
||||
const alreadyInCarpool = myCarpool !== undefined;
|
||||
const alreadyInCarpool =
|
||||
myCarpool !== undefined || creationStatus === 'completed';
|
||||
|
||||
const createEmptyCarpool = useCallback(() => {
|
||||
setCreationStatus('pending');
|
||||
|
@ -107,7 +152,11 @@ export default function Carpools({ event }: { event: IEvent }) {
|
|||
</>
|
||||
)}
|
||||
{event.carpools.map((carpool) => (
|
||||
<CarpoolRow carpool={carpool} key={carpool.id} />
|
||||
<CarpoolRow
|
||||
carpool={carpool}
|
||||
key={carpool.id}
|
||||
inCarpoolAlready={alreadyInCarpool}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
|
12
src/components/Event/EventContext.tsx
Normal file
12
src/components/Event/EventContext.tsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { createContext } from 'react';
|
||||
import { IEvent } from '../types';
|
||||
|
||||
const EventContext = createContext({
|
||||
refresh: () => {
|
||||
console.error('not implemented: refresh');
|
||||
},
|
||||
event: null! as IEvent,
|
||||
default: true,
|
||||
});
|
||||
|
||||
export default EventContext;
|
|
@ -16,7 +16,7 @@ export default function EventPage() {
|
|||
return (
|
||||
<>
|
||||
<Header />
|
||||
{event ? <Event event={event} /> : <span>Loading...</span>}
|
||||
{event ? <Event id={id} /> : <span>Loading...</span>}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ export default function EventStream({ events }: { events: IEvent[] }) {
|
|||
return (
|
||||
<div style={{ display: 'flex', flexDirection: 'column', width: '100%' }}>
|
||||
{events.map((event) => (
|
||||
<Event event={event} key={event.name} />
|
||||
<Event id={event.id} initial={event} key={event.name} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -2,6 +2,14 @@ import { useMemo } from 'react';
|
|||
import { useContext } from 'react';
|
||||
import { NotificationsContext } from './NotificationsProvider';
|
||||
|
||||
export function useSendCarpoolRequest() {
|
||||
return useContext(NotificationsContext).sendCarpoolRequest;
|
||||
}
|
||||
|
||||
export function useCancelCarpoolRequest() {
|
||||
return useContext(NotificationsContext).cancelCarpoolRequest;
|
||||
}
|
||||
|
||||
export function useInvitationState(
|
||||
carpoolId: number
|
||||
): 'invited' | 'requested' | 'none' {
|
||||
|
|
Loading…
Reference in New Issue
Block a user