diff --git a/src/components/Carpool/Carpool.tsx b/src/components/Carpool/Carpool.tsx index f696f31..93d953c 100644 --- a/src/components/Carpool/Carpool.tsx +++ b/src/components/Carpool/Carpool.tsx @@ -1,4 +1,4 @@ -import { createContext, useCallback, useEffect } from 'react'; +import { createContext, useCallback, useEffect, useMemo } from 'react'; import { acceptCarpoolRequest, cancelCarpoolInvite, @@ -7,6 +7,7 @@ import { leaveCarpool, sendCarpoolInvite, } from '../api'; +import { useMe } from '../hooks'; import { ICarpool } from '../types'; import UILink from '../UI/UILink'; import UISecondaryBox from '../UI/UISecondaryBox'; @@ -25,6 +26,7 @@ type CarpoolState = { event: ICarpool['event']; members: { id: number; name: string }[]; invitations: Record; + creatorId: number; }; export const CarpoolContext = createContext({ @@ -49,6 +51,12 @@ export const CarpoolContext = createContext({ export default function Carpool({ id }: { id: number }) { const [carpool, setCarpool] = useImmutable(null); + const me = useMe(); + const isCreator = useMemo( + () => carpool?.creatorId === me?.id, + [carpool?.creatorId, me?.id] + ); + useEffect(() => { getCarpool(id).then((carpool) => { const invitationsMap: Record = {}; @@ -60,6 +68,7 @@ export default function Carpool({ id }: { id: number }) { name: carpool.name, event: carpool.event, members: carpool.members, + creatorId: carpool.creatorId, invitations: invitationsMap, }); }); @@ -67,6 +76,10 @@ export default function Carpool({ id }: { id: number }) { const acceptRequest = useCallback( async (userId: number) => { + if (!isCreator) { + console.error('Trying to accept request as noncreator'); + return; + } if (!carpool) { console.error( 'Trying to accept request when carpool has not been loaded.' @@ -79,11 +92,15 @@ export default function Carpool({ id }: { id: number }) { delete carpool.invitations[userId]; carpool.members.push({ id: userId, name }); }, - [carpool, id] + [carpool, id, isCreator] ); const denyRequest = useCallback( async (userId: number) => { + if (!isCreator) { + console.error('Trying to deny request as noncreator'); + return; + } if (!carpool) { console.error( 'Trying to deny request when carpool has not been loaded.' @@ -93,11 +110,15 @@ export default function Carpool({ id }: { id: number }) { await denyCarpoolRequest(id, userId); delete carpool.invitations[userId]; }, - [carpool, id] + [carpool, id, isCreator] ); const sendInvite = useCallback( async (user: { id: number; name: string }) => { + if (!isCreator) { + console.error('Trying to send invitation as noncreator'); + return; + } if (!carpool) { console.error( 'Trying to send invite when carpool has not been loaded.' @@ -111,11 +132,15 @@ export default function Carpool({ id }: { id: number }) { console.error(e); } }, - [carpool, id] + [carpool, id, isCreator] ); const cancelInvite = useCallback( async (user: { id: number; name: string }) => { + if (!isCreator) { + console.error('Trying to cancel invitation as noncreator'); + return; + } if (!carpool) { console.error( 'Trying to cancel invite when carpool has not been loaded.' @@ -129,7 +154,12 @@ export default function Carpool({ id }: { id: number }) { } delete carpool.invitations[user.id]; }, - [carpool, id] + [carpool, id, isCreator] + ); + + const creatorName = useMemo( + () => carpool?.members.find((m) => m.id === carpool.creatorId)?.name, + [carpool] ); const eventId = carpool?.event.id; @@ -164,6 +194,9 @@ export default function Carpool({ id }: { id: number }) { style={{ width: '45rem', maxWidth: '100vw', alignItems: 'center' }} >

{carpool.name}

+ {isCreator + ? 'You are the creator of this carpool.' + : `${creatorName} is the creator of this carpool`} {carpool.event.name} diff --git a/src/components/Carpool/CarpoolTopButtonsMembersOnly.tsx b/src/components/Carpool/CarpoolTopButtonsMembersOnly.tsx index d2f0574..471c9b5 100644 --- a/src/components/Carpool/CarpoolTopButtonsMembersOnly.tsx +++ b/src/components/Carpool/CarpoolTopButtonsMembersOnly.tsx @@ -6,6 +6,7 @@ import useToggle from '../useToggle'; import { CarpoolContext } from './Carpool'; import InvitationList from './InvitationList'; import RequestList from './RequestList'; +import useIsCreator from './useIsCreator'; const spanStyle = { padding: '0.5rem', @@ -19,6 +20,7 @@ export default function CarpoolTopButtonsMembersOnly() { const [invitationsOpen, toggleInvitationsOpen] = useToggle(false); const [requestsOpen, toggleRequestsOpen] = useToggle(false); const { leave } = useContext(CarpoolContext); + const isCreator = useIsCreator(); return ( <> @@ -29,12 +31,17 @@ export default function CarpoolTopButtonsMembersOnly() { margin: '0.5rem 0', }} > - - View requests - - - Invite - + {isCreator && ( + <> + + View + requests + + + Invite + + + )} Leave diff --git a/src/components/Carpool/useIsCreator.ts b/src/components/Carpool/useIsCreator.ts new file mode 100644 index 0000000..4fc5942 --- /dev/null +++ b/src/components/Carpool/useIsCreator.ts @@ -0,0 +1,14 @@ +import { useContext, useDebugValue, useMemo } from 'react'; +import { useMe } from '../hooks'; +import { CarpoolContext } from './Carpool'; + +export default function useIsCreator() { + const me = useMe(); + const carpool = useContext(CarpoolContext).carpool; + const isCreator = useMemo( + () => carpool?.creatorId === me?.id, + [carpool?.creatorId, me?.id] + ); + useDebugValue(isCreator); + return isCreator; +} diff --git a/src/components/Event/Event.tsx b/src/components/Event/Event.tsx index 6295d5d..1c0e9b9 100644 --- a/src/components/Event/Event.tsx +++ b/src/components/Event/Event.tsx @@ -53,7 +53,7 @@ export default function Event({ tentativeInvites, }} > - +
{name} {group && } diff --git a/src/components/types.ts b/src/components/types.ts index 106ddb5..66d7cf0 100644 --- a/src/components/types.ts +++ b/src/components/types.ts @@ -29,6 +29,7 @@ export type ICarpool = { // id: number; // name: string; // }; + creatorId: number; members: { id: number; name: string;