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 { createContext, useCallback, useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
|
acceptCarpoolRequest,
|
||||||
cancelCarpoolInvite,
|
cancelCarpoolInvite,
|
||||||
|
denyCarpoolRequest,
|
||||||
getCarpool,
|
getCarpool,
|
||||||
leaveCarpool,
|
leaveCarpool,
|
||||||
sendCarpoolInvite,
|
sendCarpoolInvite,
|
||||||
|
@ -25,13 +27,19 @@ type CarpoolState = {
|
||||||
|
|
||||||
export const CarpoolContext = createContext({
|
export const CarpoolContext = createContext({
|
||||||
carpool: {} as CarpoolState,
|
carpool: {} as CarpoolState,
|
||||||
sendInvite: (user: { id: number; name: string }) => {
|
async sendInvite(user: { id: number; name: string }) {
|
||||||
console.error('not implemented: sendInvite');
|
console.error('not implemented: sendInvite');
|
||||||
},
|
},
|
||||||
cancelInvite: (user: { id: number; name: string }) => {
|
async cancelInvite(user: { id: number; name: string }) {
|
||||||
console.error('not implemented: cancelInvite');
|
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');
|
console.error('not implemented: leave');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -55,46 +63,83 @@ export default function Carpool({ id }: { id: number }) {
|
||||||
});
|
});
|
||||||
}, [id, setCarpool]);
|
}, [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(
|
const sendInvite = useCallback(
|
||||||
(user: { id: number; name: string }) => {
|
async (user: { id: number; name: string }) => {
|
||||||
if (carpool) {
|
if (!carpool) {
|
||||||
sendCarpoolInvite(id, user.id)
|
|
||||||
.then(() => {
|
|
||||||
carpool.invitations[user.id] = { isRequest: false, user };
|
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
} else {
|
|
||||||
console.error(
|
console.error(
|
||||||
'Trying to send invite when carpool has not been loaded.'
|
'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]
|
[carpool, id]
|
||||||
);
|
);
|
||||||
|
|
||||||
const cancelInvite = useCallback(
|
const cancelInvite = useCallback(
|
||||||
(user: { id: number; name: string }) => {
|
async (user: { id: number; name: string }) => {
|
||||||
if (!carpool) {
|
if (!carpool) {
|
||||||
return null;
|
console.error(
|
||||||
|
'Trying to cancel invite when carpool has not been loaded.'
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
cancelCarpoolInvite(id, user.id)
|
try {
|
||||||
.then(() => {
|
await cancelCarpoolInvite(id, user.id);
|
||||||
delete carpool.invitations[user.id];
|
} catch (e) {
|
||||||
})
|
console.error(e);
|
||||||
.catch(console.error);
|
}
|
||||||
|
delete carpool.invitations[user.id];
|
||||||
},
|
},
|
||||||
[carpool, id]
|
[carpool, id]
|
||||||
);
|
);
|
||||||
|
|
||||||
const eventId = carpool?.event.id;
|
const eventId = carpool?.event.id;
|
||||||
|
|
||||||
const leave = useCallback(() => {
|
const leave = useCallback(async () => {
|
||||||
if (eventId) {
|
if (eventId) {
|
||||||
leaveCarpool(id)
|
try {
|
||||||
.then(() => {
|
await leaveCarpool(id);
|
||||||
window.location.href = '/events/' + eventId;
|
window.location.href = '/events/' + eventId;
|
||||||
})
|
} catch (e) {
|
||||||
.catch(console.error);
|
console.error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [eventId, id]);
|
}, [eventId, id]);
|
||||||
|
|
||||||
|
@ -108,6 +153,8 @@ export default function Carpool({ id }: { id: number }) {
|
||||||
carpool,
|
carpool,
|
||||||
sendInvite,
|
sendInvite,
|
||||||
cancelInvite,
|
cancelInvite,
|
||||||
|
acceptRequest,
|
||||||
|
denyRequest,
|
||||||
leave,
|
leave,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -5,16 +5,19 @@ import { useContext } from 'react';
|
||||||
import useToggle from '../useToggle';
|
import useToggle from '../useToggle';
|
||||||
import { CarpoolContext } from './Carpool';
|
import { CarpoolContext } from './Carpool';
|
||||||
import InvitationList from './InvitationList';
|
import InvitationList from './InvitationList';
|
||||||
|
import RequestList from './RequestList';
|
||||||
|
|
||||||
const spanStyle = {
|
const spanStyle = {
|
||||||
padding: '0.5rem',
|
padding: '0.5rem',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
};
|
userSelect: 'none',
|
||||||
|
} as const;
|
||||||
|
|
||||||
export default function CarpoolTopButtonsMembersOnly() {
|
export default function CarpoolTopButtonsMembersOnly() {
|
||||||
const [invitationsOpen, toggleInvitationsOpen] = useToggle(false);
|
const [invitationsOpen, toggleInvitationsOpen] = useToggle(false);
|
||||||
|
const [requestsOpen, toggleRequestsOpen] = useToggle(false);
|
||||||
const { leave } = useContext(CarpoolContext);
|
const { leave } = useContext(CarpoolContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -26,8 +29,8 @@ export default function CarpoolTopButtonsMembersOnly() {
|
||||||
margin: '0.5rem 0',
|
margin: '0.5rem 0',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span style={spanStyle} onClick={console.log}>
|
<span style={spanStyle} onClick={toggleRequestsOpen}>
|
||||||
<MailOutlineIcon style={{ marginRight: '0.5rem' }} /> 1 request
|
<MailOutlineIcon style={{ marginRight: '0.5rem' }} /> View requests
|
||||||
</span>
|
</span>
|
||||||
<span style={spanStyle} onClick={toggleInvitationsOpen}>
|
<span style={spanStyle} onClick={toggleInvitationsOpen}>
|
||||||
<PersonAddIcon style={{ marginRight: '0.5rem' }} /> Invite
|
<PersonAddIcon style={{ marginRight: '0.5rem' }} /> Invite
|
||||||
|
@ -38,6 +41,7 @@ export default function CarpoolTopButtonsMembersOnly() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{invitationsOpen && <InvitationList />}
|
{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 { useCallback } from 'react';
|
||||||
import { acceptInvite, acceptRequest, denyInvite, denyRequest } from '../api';
|
import {
|
||||||
|
acceptInvite,
|
||||||
|
acceptCarpoolRequest,
|
||||||
|
denyInvite,
|
||||||
|
denyCarpoolRequest,
|
||||||
|
} from '../api';
|
||||||
import { IInvitation } from '../types';
|
import { IInvitation } from '../types';
|
||||||
import UIButton from '../UI/UIButton';
|
import UIButton from '../UI/UIButton';
|
||||||
|
|
||||||
|
@ -11,11 +16,11 @@ export default function Notification({
|
||||||
const carpoolId = notification.carpool.id;
|
const carpoolId = notification.carpool.id;
|
||||||
|
|
||||||
const acceptReq = useCallback(() => {
|
const acceptReq = useCallback(() => {
|
||||||
acceptRequest(carpoolId, notification.user.id);
|
acceptCarpoolRequest(carpoolId, notification.user.id);
|
||||||
}, [carpoolId, notification.user.id]);
|
}, [carpoolId, notification.user.id]);
|
||||||
|
|
||||||
const rejectReq = useCallback(() => {
|
const rejectReq = useCallback(() => {
|
||||||
denyRequest(carpoolId, notification.user.id);
|
denyCarpoolRequest(carpoolId, notification.user.id);
|
||||||
}, [carpoolId, notification.user.id]);
|
}, [carpoolId, notification.user.id]);
|
||||||
|
|
||||||
const acceptInv = useCallback(() => {
|
const acceptInv = useCallback(() => {
|
||||||
|
@ -30,12 +35,12 @@ export default function Notification({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="notification">
|
<div className="notification">
|
||||||
{notification.user.name}
|
{notification.user.name}{' '}
|
||||||
{notification.isRequest ? (
|
{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.carpool.name + ' at ' + sentTime.toLocaleString()}
|
||||||
{notification.isRequest ? (
|
{notification.isRequest ? (
|
||||||
<div className="notification-buttons" style={{ display: 'flex' }}>
|
<div className="notification-buttons" style={{ display: 'flex' }}>
|
||||||
|
|
|
@ -5,7 +5,7 @@ const baseStyle: CSSProperties = {
|
||||||
borderRadius: '0.5em',
|
borderRadius: '0.5em',
|
||||||
textTransform: 'uppercase',
|
textTransform: 'uppercase',
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
marginTop: '0.5em',
|
margin: '0.5em',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
};
|
};
|
||||||
|
|
|
@ -148,7 +148,7 @@ export async function getNotifications() {
|
||||||
return await get('/users/@me/received_requests_and_invites');
|
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 });
|
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`, {});
|
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 });
|
return await post(`/carpools/${carpoolId}/deny_request`, { userId });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user