mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-16 00:50:18 -04:00
add component for accepting/denying requests
This commit is contained in:
parent
6f2d53270d
commit
54ed65a037
|
@ -1,6 +1,8 @@
|
|||
import { createContext, useCallback, useEffect } from 'react';
|
||||
import {
|
||||
acceptCarpoolRequest,
|
||||
cancelCarpoolInvite,
|
||||
denyCarpoolRequest,
|
||||
getCarpool,
|
||||
leaveCarpool,
|
||||
sendCarpoolInvite,
|
||||
|
@ -25,13 +27,19 @@ type CarpoolState = {
|
|||
|
||||
export const CarpoolContext = createContext({
|
||||
carpool: {} as CarpoolState,
|
||||
sendInvite: (user: { id: number; name: string }) => {
|
||||
async sendInvite(user: { id: number; name: string }) {
|
||||
console.error('not implemented: sendInvite');
|
||||
},
|
||||
cancelInvite: (user: { id: number; name: string }) => {
|
||||
async cancelInvite(user: { id: number; name: string }) {
|
||||
console.error('not implemented: cancelInvite');
|
||||
},
|
||||
leave: () => {
|
||||
async acceptRequest(userId: number) {
|
||||
console.error('not implemented: acceptRequest');
|
||||
},
|
||||
async denyRequest(userId: number) {
|
||||
console.error('not implemented: denyRequest');
|
||||
},
|
||||
leave() {
|
||||
console.error('not implemented: leave');
|
||||
},
|
||||
});
|
||||
|
@ -55,46 +63,83 @@ export default function Carpool({ id }: { id: number }) {
|
|||
});
|
||||
}, [id, setCarpool]);
|
||||
|
||||
const acceptRequest = useCallback(
|
||||
async (userId: number) => {
|
||||
if (!carpool) {
|
||||
console.error(
|
||||
'Trying to accept request when carpool has not been loaded.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
await acceptCarpoolRequest(id, userId);
|
||||
const invite = carpool.invitations[userId];
|
||||
const name = invite.user.name;
|
||||
delete carpool.invitations[userId];
|
||||
carpool.members.push({ id: userId, name });
|
||||
},
|
||||
[carpool, id]
|
||||
);
|
||||
|
||||
const denyRequest = useCallback(
|
||||
async (userId: number) => {
|
||||
if (!carpool) {
|
||||
console.error(
|
||||
'Trying to deny request when carpool has not been loaded.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
await denyCarpoolRequest(id, userId);
|
||||
delete carpool.invitations[userId];
|
||||
},
|
||||
[carpool, id]
|
||||
);
|
||||
|
||||
const sendInvite = useCallback(
|
||||
(user: { id: number; name: string }) => {
|
||||
if (carpool) {
|
||||
sendCarpoolInvite(id, user.id)
|
||||
.then(() => {
|
||||
carpool.invitations[user.id] = { isRequest: false, user };
|
||||
})
|
||||
.catch(console.error);
|
||||
} else {
|
||||
async (user: { id: number; name: string }) => {
|
||||
if (!carpool) {
|
||||
console.error(
|
||||
'Trying to send invite when carpool has not been loaded.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await sendCarpoolInvite(id, user.id);
|
||||
carpool.invitations[user.id] = { isRequest: false, user };
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
},
|
||||
[carpool, id]
|
||||
);
|
||||
|
||||
const cancelInvite = useCallback(
|
||||
(user: { id: number; name: string }) => {
|
||||
async (user: { id: number; name: string }) => {
|
||||
if (!carpool) {
|
||||
return null;
|
||||
console.error(
|
||||
'Trying to cancel invite when carpool has not been loaded.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
cancelCarpoolInvite(id, user.id)
|
||||
.then(() => {
|
||||
delete carpool.invitations[user.id];
|
||||
})
|
||||
.catch(console.error);
|
||||
try {
|
||||
await cancelCarpoolInvite(id, user.id);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
delete carpool.invitations[user.id];
|
||||
},
|
||||
[carpool, id]
|
||||
);
|
||||
|
||||
const eventId = carpool?.event.id;
|
||||
|
||||
const leave = useCallback(() => {
|
||||
const leave = useCallback(async () => {
|
||||
if (eventId) {
|
||||
leaveCarpool(id)
|
||||
.then(() => {
|
||||
window.location.href = '/events/' + eventId;
|
||||
})
|
||||
.catch(console.error);
|
||||
try {
|
||||
await leaveCarpool(id);
|
||||
window.location.href = '/events/' + eventId;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}, [eventId, id]);
|
||||
|
||||
|
@ -108,6 +153,8 @@ export default function Carpool({ id }: { id: number }) {
|
|||
carpool,
|
||||
sendInvite,
|
||||
cancelInvite,
|
||||
acceptRequest,
|
||||
denyRequest,
|
||||
leave,
|
||||
}}
|
||||
>
|
||||
|
|
|
@ -5,16 +5,19 @@ import { useContext } from 'react';
|
|||
import useToggle from '../useToggle';
|
||||
import { CarpoolContext } from './Carpool';
|
||||
import InvitationList from './InvitationList';
|
||||
import RequestList from './RequestList';
|
||||
|
||||
const spanStyle = {
|
||||
padding: '0.5rem',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
cursor: 'pointer',
|
||||
};
|
||||
userSelect: 'none',
|
||||
} as const;
|
||||
|
||||
export default function CarpoolTopButtonsMembersOnly() {
|
||||
const [invitationsOpen, toggleInvitationsOpen] = useToggle(false);
|
||||
const [requestsOpen, toggleRequestsOpen] = useToggle(false);
|
||||
const { leave } = useContext(CarpoolContext);
|
||||
|
||||
return (
|
||||
|
@ -26,8 +29,8 @@ export default function CarpoolTopButtonsMembersOnly() {
|
|||
margin: '0.5rem 0',
|
||||
}}
|
||||
>
|
||||
<span style={spanStyle} onClick={console.log}>
|
||||
<MailOutlineIcon style={{ marginRight: '0.5rem' }} /> 1 request
|
||||
<span style={spanStyle} onClick={toggleRequestsOpen}>
|
||||
<MailOutlineIcon style={{ marginRight: '0.5rem' }} /> View requests
|
||||
</span>
|
||||
<span style={spanStyle} onClick={toggleInvitationsOpen}>
|
||||
<PersonAddIcon style={{ marginRight: '0.5rem' }} /> Invite
|
||||
|
@ -38,6 +41,7 @@ export default function CarpoolTopButtonsMembersOnly() {
|
|||
</div>
|
||||
|
||||
{invitationsOpen && <InvitationList />}
|
||||
{requestsOpen && <RequestList />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
77
src/components/Carpool/RequestList.tsx
Normal file
77
src/components/Carpool/RequestList.tsx
Normal file
|
@ -0,0 +1,77 @@
|
|||
import { useMemo, useState } from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { useContext } from 'react';
|
||||
import { lightgrey } from '../../lib/colors';
|
||||
import UIButton from '../UI/UIButton';
|
||||
import { CarpoolContext } from './Carpool';
|
||||
|
||||
function RequestRow({ user }: { user: { id: number; name: string } }) {
|
||||
const { acceptRequest, denyRequest } = useContext(CarpoolContext);
|
||||
const [pending, setPending] = useState(false);
|
||||
|
||||
const acceptCallback = useCallback(() => {
|
||||
if (pending) {
|
||||
return;
|
||||
}
|
||||
setPending(true);
|
||||
acceptRequest(user.id)
|
||||
.catch(console.error)
|
||||
.finally(() => setPending(false));
|
||||
}, [acceptRequest, pending, user.id]);
|
||||
|
||||
const denyCallback = useCallback(() => {
|
||||
if (pending) {
|
||||
return;
|
||||
}
|
||||
setPending(true);
|
||||
denyRequest(user.id)
|
||||
.catch(console.error)
|
||||
.finally(() => setPending(false));
|
||||
}, [denyRequest, pending, user.id]);
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<div style={{ flex: 2 }}>{user.name}</div>
|
||||
|
||||
<div style={{ flex: 1 }}>
|
||||
<UIButton
|
||||
onClick={acceptCallback}
|
||||
style={{ backgroundColor: lightgrey, padding: '0.5rem' }}
|
||||
>
|
||||
Accept
|
||||
</UIButton>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: 1 }}>
|
||||
<UIButton
|
||||
onClick={denyCallback}
|
||||
style={{ backgroundColor: lightgrey, padding: '0.5rem' }}
|
||||
>
|
||||
Decline
|
||||
</UIButton>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function RequestList() {
|
||||
const { carpool } = useContext(CarpoolContext);
|
||||
const requestingUsers = useMemo(() => {
|
||||
return Object.keys(carpool.invitations)
|
||||
.filter((key) => carpool.invitations[key as unknown as number].isRequest)
|
||||
.map((key) => carpool.invitations[key as unknown as number].user);
|
||||
}, [carpool.invitations]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>Requests</h1>
|
||||
{requestingUsers.length > 0 ? (
|
||||
requestingUsers.map((user) => <RequestRow key={user.id} user={user} />)
|
||||
) : (
|
||||
<>Nobody's requested to join yet</>
|
||||
)}
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,5 +1,10 @@
|
|||
import { useCallback } from 'react';
|
||||
import { acceptInvite, acceptRequest, denyInvite, denyRequest } from '../api';
|
||||
import {
|
||||
acceptInvite,
|
||||
acceptCarpoolRequest,
|
||||
denyInvite,
|
||||
denyCarpoolRequest,
|
||||
} from '../api';
|
||||
import { IInvitation } from '../types';
|
||||
import UIButton from '../UI/UIButton';
|
||||
|
||||
|
@ -11,11 +16,11 @@ export default function Notification({
|
|||
const carpoolId = notification.carpool.id;
|
||||
|
||||
const acceptReq = useCallback(() => {
|
||||
acceptRequest(carpoolId, notification.user.id);
|
||||
acceptCarpoolRequest(carpoolId, notification.user.id);
|
||||
}, [carpoolId, notification.user.id]);
|
||||
|
||||
const rejectReq = useCallback(() => {
|
||||
denyRequest(carpoolId, notification.user.id);
|
||||
denyCarpoolRequest(carpoolId, notification.user.id);
|
||||
}, [carpoolId, notification.user.id]);
|
||||
|
||||
const acceptInv = useCallback(() => {
|
||||
|
@ -30,12 +35,12 @@ export default function Notification({
|
|||
|
||||
return (
|
||||
<div className="notification">
|
||||
{notification.user.name}
|
||||
{notification.user.name}{' '}
|
||||
{notification.isRequest ? (
|
||||
<span> request you to join </span>
|
||||
<span>requested to join</span>
|
||||
) : (
|
||||
<span> invited you to join </span>
|
||||
)}
|
||||
<span>invited you to join</span>
|
||||
)}{' '}
|
||||
{notification.carpool.name + ' at ' + sentTime.toLocaleString()}
|
||||
{notification.isRequest ? (
|
||||
<div className="notification-buttons" style={{ display: 'flex' }}>
|
||||
|
|
|
@ -5,7 +5,7 @@ const baseStyle: CSSProperties = {
|
|||
borderRadius: '0.5em',
|
||||
textTransform: 'uppercase',
|
||||
fontWeight: 500,
|
||||
marginTop: '0.5em',
|
||||
margin: '0.5em',
|
||||
cursor: 'pointer',
|
||||
userSelect: 'none',
|
||||
};
|
||||
|
|
|
@ -148,7 +148,7 @@ export async function getNotifications() {
|
|||
return await get('/users/@me/received_requests_and_invites');
|
||||
}
|
||||
|
||||
export async function acceptRequest(carpoolId: number, userId: number) {
|
||||
export async function acceptCarpoolRequest(carpoolId: number, userId: number) {
|
||||
return await post(`/carpools/${carpoolId}/accept_request`, { userId });
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ export async function acceptInvite(carpoolId: number) {
|
|||
return await post(`/carpools/${carpoolId}/accept_invite`, {});
|
||||
}
|
||||
|
||||
export async function denyRequest(carpoolId: number, userId: number) {
|
||||
export async function denyCarpoolRequest(carpoolId: number, userId: number) {
|
||||
return await post(`/carpools/${carpoolId}/deny_request`, { userId });
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user