From 2eea5f0dc554e0433dfd11ba826794450f1f658d Mon Sep 17 00:00:00 2001 From: Michael Fatemi Date: Thu, 15 Jul 2021 14:15:01 -0400 Subject: [PATCH] Accepting carpools on the frontend works! --- src/components/Carpool/MemberList.tsx | 40 ++++++++++++++-- src/components/Event/Event.tsx | 21 +++++++-- src/components/Group/Group.tsx | 13 ++++-- src/components/Notifications/Notification.tsx | 8 ++-- src/components/api.ts | 8 ++-- .../Notifications/NotificationsProvider.tsx | 46 +++++++++++++++---- 6 files changed, 107 insertions(+), 29 deletions(-) diff --git a/src/components/Carpool/MemberList.tsx b/src/components/Carpool/MemberList.tsx index ef7296b..559ff5d 100644 --- a/src/components/Carpool/MemberList.tsx +++ b/src/components/Carpool/MemberList.tsx @@ -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() { Request to join ) : ( - You've been invited, we need to make it so you can accept the invite + You've been invited to this carpool! +
+ + Accept + + + Deny + +
)} diff --git a/src/components/Event/Event.tsx b/src/components/Event/Event.tsx index d1fb3e4..f84c824 100644 --- a/src/components/Event/Event.tsx +++ b/src/components/Event/Event.tsx @@ -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>({}); 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 Loading...; + if (!found) { + return ( + <> +

Event Not Found

+ + ); } const { name, group, formattedAddress, startTime, endTime } = event; diff --git a/src/components/Group/Group.tsx b/src/components/Group/Group.tsx index beb2a75..77a47f5 100644 --- a/src/components/Group/Group.tsx +++ b/src/components/Group/Group.tsx @@ -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(DEFAULT_GROUP()); + const [found, setFound] = useState(false); useEffect(() => { - getGroup(id).then(setGroup); + getGroup(id) + .then(setGroup) + .catch(() => setFound(false)); }, [id, setGroup]); - return ( + return found ? (
+ ) : ( + <> +

Group not found

+ ); } diff --git a/src/components/Notifications/Notification.tsx b/src/components/Notifications/Notification.tsx index a10d538..58a927b 100644 --- a/src/components/Notifications/Notification.tsx +++ b/src/components/Notifications/Notification.tsx @@ -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); diff --git a/src/components/api.ts b/src/components/api.ts index b8c9de0..2ef6b22 100644 --- a/src/components/api.ts +++ b/src/components/api.ts @@ -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() { diff --git a/src/state/Notifications/NotificationsProvider.tsx b/src/state/Notifications/NotificationsProvider.tsx index 4556f09..7afe2b0 100644 --- a/src/state/Notifications/NotificationsProvider.tsx +++ b/src/state/Notifications/NotificationsProvider.tsx @@ -7,11 +7,17 @@ export const NotificationsContext = createContext({ invitedCarpoolIds: {} as Record, requestedCarpoolIds: {} as Record, - 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 ( {children}