Accepting carpools on the frontend works!

This commit is contained in:
Michael Fatemi 2021-07-15 14:15:01 -04:00
parent 9f7c40c7df
commit 2eea5f0dc5
6 changed files with 107 additions and 29 deletions

View File

@ -20,16 +20,24 @@ function MemberRow({ member }: { member: { id: number; name: string } }) {
const shownMembersCount = 2;
const defaultMe = { id: 0, name: '' };
export default function MemberList() {
const { leave, carpool } = useContext(CarpoolContext);
const members = carpool.members;
const membersToShow = members.slice(0, shownMembersCount);
const hiddenMemberCount = members.length - membersToShow.length;
const { sendCarpoolRequest, cancelCarpoolRequest } =
useContext(NotificationsContext);
const {
sendCarpoolRequest,
cancelCarpoolRequest,
acceptCarpoolInvite,
denyCarpoolInvite,
} = useContext(NotificationsContext);
const invitationState = useInvitationState(carpool.id);
const me = useMe() || defaultMe;
const sendRequest = useCallback(() => {
sendCarpoolRequest(carpool.id);
}, [carpool.id, sendCarpoolRequest]);
@ -38,7 +46,17 @@ export default function MemberList() {
cancelCarpoolRequest(carpool.id);
}, [carpool.id, cancelCarpoolRequest]);
const me = useMe() || { id: 0, name: '' };
const acceptInvitation = useCallback(() => {
acceptCarpoolInvite(carpool.id).then(() => {
members.push(me);
});
}, [acceptCarpoolInvite, carpool.id, members, me]);
const denyInvitation = useCallback(() => {
denyCarpoolInvite(carpool.id).then(() => {
members.push(me);
});
}, [carpool.id, denyCarpoolInvite, me, members]);
const isMember = useMemo(() => {
return members.some(({ id }) => id === me?.id);
@ -78,7 +96,21 @@ export default function MemberList() {
<UIButton onClick={sendRequest}>Request to join</UIButton>
) : (
<span>
You've been invited, we need to make it so you can accept the invite
You've been invited to this carpool!
<div style={{ display: 'flex', width: '100%', textAlign: 'center' }}>
<UIButton
onClick={acceptInvitation}
style={{ backgroundColor: lightgrey, flex: 1, margin: '0.5rem' }}
>
Accept
</UIButton>
<UIButton
onClick={denyInvitation}
style={{ backgroundColor: lightgrey, flex: 1, margin: '0.5rem' }}
>
Deny
</UIButton>
</div>
</span>
)}
</div>

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { green, lightgrey } from '../../lib/colors';
import getPlaceDetails from '../../lib/getPlaceDetails';
import { addOrUpdateEventSignup, getEvent, removeEventSignup } from '../api';
@ -46,12 +46,21 @@ export default function Event({
...(initial || {}),
});
const [found, setFound] = useState(false);
const me = useMe() || { id: 0, name: '' };
const [tentativeInvites] = useImmutable<Record<number, boolean>>({});
const refresh = useCallback(() => {
getEvent(id).then(setEvent);
getEvent(id).then((e) => {
if (e) {
setFound(true);
setEvent(e);
} else {
setFound(false);
}
});
}, [id, setEvent]);
useEffect(refresh, [refresh]);
@ -91,8 +100,12 @@ export default function Event({
const interested = !!event.signups[me.id];
if (!event) {
return <UISecondaryBox>Loading...</UISecondaryBox>;
if (!found) {
return (
<>
<h1>Event Not Found</h1>
</>
);
}
const { name, group, formattedAddress, startTime, endTime } = event;

View File

@ -1,4 +1,4 @@
import { createContext, useEffect } from 'react';
import { createContext, useEffect, useState } from 'react';
import { getGroup } from '../api';
import EventCreatorLink from '../EventCreator/EventCreatorLink';
import EventStream from '../EventStream';
@ -20,12 +20,15 @@ export const GroupContext = createContext({ group: DEFAULT_GROUP() });
export default function Group({ id }: { id: number }) {
const [group, setGroup] = useImmutable<IGroup>(DEFAULT_GROUP());
const [found, setFound] = useState(false);
useEffect(() => {
getGroup(id).then(setGroup);
getGroup(id)
.then(setGroup)
.catch(() => setFound(false));
}, [id, setGroup]);
return (
return found ? (
<GroupContext.Provider value={{ group }}>
<div
style={{
@ -55,5 +58,9 @@ export default function Group({ id }: { id: number }) {
)}
</div>
</GroupContext.Provider>
) : (
<>
<h1>Group not found</h1>
</>
);
}

View File

@ -19,12 +19,12 @@ export default function Notification({
}, [carpoolId, notification.user.id]);
const acceptInv = useCallback(() => {
acceptInvite(carpoolId, notification.user.id);
}, [carpoolId, notification.user.id]);
acceptInvite(carpoolId);
}, [carpoolId]);
const rejectInv = useCallback(() => {
denyInvite(carpoolId, notification.user.id);
}, [carpoolId, notification.user.id]);
denyInvite(carpoolId);
}, [carpoolId]);
const sentTime = new Date(notification.sentTime);

View File

@ -138,16 +138,16 @@ export async function acceptRequest(carpoolId: number, userId: number) {
return await post(`/carpools/${carpoolId}/accept_request`, { userId });
}
export async function acceptInvite(carpoolId: number, userId: number) {
return await post(`/carpools/${carpoolId}/accept_invite`, { userId });
export async function acceptInvite(carpoolId: number) {
return await post(`/carpools/${carpoolId}/accept_invite`, {});
}
export async function denyRequest(carpoolId: number, userId: number) {
return await post(`/carpools/${carpoolId}/deny_request`, { userId });
}
export async function denyInvite(carpoolId: number, userId: number) {
return await post(`/carpools/${carpoolId}/deny_invite`, { userId });
export async function denyInvite(carpoolId: number) {
return await post(`/carpools/${carpoolId}/deny_invite`, {});
}
export async function getMe() {

View File

@ -7,11 +7,17 @@ export const NotificationsContext = createContext({
invitedCarpoolIds: {} as Record<number, boolean>,
requestedCarpoolIds: {} as Record<number, boolean>,
sendCarpoolRequest: (carpoolId: number) =>
sendCarpoolRequest: async (carpoolId: number) =>
console.error('not implemented: sendCarpoolRequest'),
cancelCarpoolRequest: (carpoolId: number) =>
cancelCarpoolRequest: async (carpoolId: number) =>
console.error('not implemented: cancelCarpoolRequest'),
acceptCarpoolInvite: async (carpoolId: number) =>
console.error('not implemented: acceptCarpoolInvite'),
denyCarpoolInvite: async (carpoolId: number) =>
console.error('not implemented: denyCarpoolInvite'),
});
export default function NotificationsProvider({
@ -44,23 +50,41 @@ export default function NotificationsProvider({
}, [setInvitedCarpoolIds, setRequestedCarpoolIds]);
const sendCarpoolRequest = useCallback(
(carpoolId: number) => {
api.sendCarpoolRequest(carpoolId).then(() => {
requestedCarpoolIds[carpoolId] = true;
});
async (carpoolId: number) => {
await api.sendCarpoolRequest(carpoolId);
requestedCarpoolIds[carpoolId] = true;
},
[requestedCarpoolIds]
);
const cancelCarpoolRequest = useCallback(
(carpoolId: number) => {
api.cancelCarpoolRequest(carpoolId).then(() => {
delete requestedCarpoolIds[carpoolId];
});
async (carpoolId: number) => {
await api.cancelCarpoolRequest(carpoolId);
delete requestedCarpoolIds[carpoolId];
},
[requestedCarpoolIds]
);
const acceptCarpoolInvite = useCallback(
async (carpoolId: number) => {
await api.acceptInvite(carpoolId);
delete invitedCarpoolIds[carpoolId];
},
[invitedCarpoolIds]
);
const denyCarpoolInvite = useCallback(
async (carpoolId: number) => {
await api.denyInvite(carpoolId);
delete invitedCarpoolIds[carpoolId];
},
[invitedCarpoolIds]
);
return (
<NotificationsContext.Provider
value={{
@ -68,6 +92,8 @@ export default function NotificationsProvider({
requestedCarpoolIds,
sendCarpoolRequest,
cancelCarpoolRequest,
acceptCarpoolInvite,
denyCarpoolInvite,
}}
>
{children}