mirror of
https://github.com/myfatemi04/wheelshare-frontend.git
synced 2025-04-21 11:20:17 -04:00
use immutable for Carpools
This commit is contained in:
parent
9d34b89ffe
commit
3a761ffc8b
|
@ -1,5 +1,11 @@
|
||||||
import { useMemo } from 'react';
|
import * as immutable from 'immutable';
|
||||||
import { createContext, useCallback, useEffect, useState } from 'react';
|
import {
|
||||||
|
createContext,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
import {
|
import {
|
||||||
cancelCarpoolInvite,
|
cancelCarpoolInvite,
|
||||||
getCarpool,
|
getCarpool,
|
||||||
|
@ -7,14 +13,33 @@ import {
|
||||||
sendCarpoolInvite,
|
sendCarpoolInvite,
|
||||||
} from '../api';
|
} from '../api';
|
||||||
import { useMe } from '../hooks';
|
import { useMe } from '../hooks';
|
||||||
import { ICarpool } from '../types';
|
|
||||||
import UISecondaryBox from '../UI/UISecondaryBox';
|
import UISecondaryBox from '../UI/UISecondaryBox';
|
||||||
import CarpoolDetails from './CarpoolDetails';
|
import CarpoolDetails from './CarpoolDetails';
|
||||||
import InvitationsAndRequests from './InvitationsAndRequests';
|
import InvitationsAndRequests from './InvitationsAndRequests';
|
||||||
import MemberList from './MemberList';
|
import MemberList from './MemberList';
|
||||||
|
|
||||||
|
class CarpoolState extends immutable.Record({
|
||||||
|
id: 0,
|
||||||
|
name: '',
|
||||||
|
eventId: -1,
|
||||||
|
event: {
|
||||||
|
id: -1,
|
||||||
|
name: '',
|
||||||
|
formattedAddress: '',
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
placeId: '',
|
||||||
|
},
|
||||||
|
members: immutable.List<{ id: number; name: string }>(),
|
||||||
|
invitations:
|
||||||
|
immutable.Map<
|
||||||
|
number,
|
||||||
|
{ isRequest: boolean; user: { id: number; name: string } }
|
||||||
|
>(),
|
||||||
|
}) {}
|
||||||
|
|
||||||
export const CarpoolContext = createContext({
|
export const CarpoolContext = createContext({
|
||||||
carpool: null! as ICarpool,
|
carpool: new CarpoolState(),
|
||||||
sendInvite: (user: { id: number; name: string }) => {
|
sendInvite: (user: { id: number; name: string }) => {
|
||||||
console.error('not implemented: sendInvite');
|
console.error('not implemented: sendInvite');
|
||||||
},
|
},
|
||||||
|
@ -27,10 +52,23 @@ export const CarpoolContext = createContext({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function Carpool({ id }: { id: number }) {
|
export default function Carpool({ id }: { id: number }) {
|
||||||
const [carpool, setCarpool] = useState<ICarpool | null>(null);
|
const [carpool, setCarpool] = useState(new CarpoolState());
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getCarpool(id).then(setCarpool);
|
getCarpool(id).then((carpool) => {
|
||||||
|
setCarpool(
|
||||||
|
new CarpoolState({
|
||||||
|
id: carpool.id,
|
||||||
|
name: carpool.name,
|
||||||
|
eventId: carpool.eventId || carpool.event.id,
|
||||||
|
event: carpool.event,
|
||||||
|
members: immutable.List(carpool.members),
|
||||||
|
invitations: immutable.Map(
|
||||||
|
carpool.invitations.map((invite) => [invite.user.id, invite])
|
||||||
|
),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
const sendInvite = useCallback(
|
const sendInvite = useCallback(
|
||||||
|
@ -38,15 +76,11 @@ export default function Carpool({ id }: { id: number }) {
|
||||||
if (carpool) {
|
if (carpool) {
|
||||||
sendCarpoolInvite(id, user.id)
|
sendCarpoolInvite(id, user.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
setCarpool(
|
setCarpool((carpool) =>
|
||||||
(carpool) =>
|
carpool.set(
|
||||||
carpool && {
|
'invitations',
|
||||||
...carpool,
|
carpool.invitations.set(user.id, { isRequest: false, user })
|
||||||
invitations: [
|
)
|
||||||
...carpool.invitations,
|
|
||||||
{ isRequest: false, user },
|
|
||||||
],
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
|
@ -78,7 +112,7 @@ export default function Carpool({ id }: { id: number }) {
|
||||||
[id]
|
[id]
|
||||||
);
|
);
|
||||||
|
|
||||||
const eventId = carpool?.eventId;
|
const eventId = carpool.eventId;
|
||||||
|
|
||||||
const leave = useCallback(() => {
|
const leave = useCallback(() => {
|
||||||
if (eventId) {
|
if (eventId) {
|
||||||
|
@ -93,8 +127,8 @@ export default function Carpool({ id }: { id: number }) {
|
||||||
const me = useMe();
|
const me = useMe();
|
||||||
|
|
||||||
const isMember = useMemo(
|
const isMember = useMemo(
|
||||||
() => carpool?.members.some((m) => m.id === me?.id),
|
() => carpool.members.some((m) => m.id === me?.id),
|
||||||
[carpool?.members, me?.id]
|
[carpool.members, me?.id]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!carpool) {
|
if (!carpool) {
|
||||||
|
@ -116,8 +150,8 @@ export default function Carpool({ id }: { id: number }) {
|
||||||
<h1 style={{ marginBottom: '0rem' }}>{carpool.name}</h1>
|
<h1 style={{ marginBottom: '0rem' }}>{carpool.name}</h1>
|
||||||
<h2 style={{ marginBottom: '0rem' }}>{carpool.event.name}</h2>
|
<h2 style={{ marginBottom: '0rem' }}>{carpool.event.name}</h2>
|
||||||
{isMember && <InvitationsAndRequests />}
|
{isMember && <InvitationsAndRequests />}
|
||||||
<CarpoolDetails carpool={carpool} />
|
<CarpoolDetails />
|
||||||
<MemberList members={carpool.members} />
|
<MemberList />
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<h2>Loading</h2>
|
<h2>Loading</h2>
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import EventIcon from '@material-ui/icons/Event';
|
import EventIcon from '@material-ui/icons/Event';
|
||||||
import LocationOnIcon from '@material-ui/icons/LocationOn';
|
import LocationOnIcon from '@material-ui/icons/LocationOn';
|
||||||
|
import { useContext } from 'react';
|
||||||
|
|
||||||
import { ICarpool } from '../types';
|
import { CarpoolContext } from './Carpool';
|
||||||
|
|
||||||
export default function CarpoolDetails({ carpool }: { carpool: ICarpool }) {
|
export default function CarpoolDetails() {
|
||||||
|
const { carpool } = useContext(CarpoolContext);
|
||||||
return (
|
return (
|
||||||
<div style={{ fontSize: '1.5rem', fontWeight: 400 }}>
|
<div style={{ fontSize: '1.5rem', fontWeight: 400 }}>
|
||||||
<div
|
<div
|
||||||
|
|
|
@ -61,6 +61,7 @@ export default function InvitationList() {
|
||||||
new Set(
|
new Set(
|
||||||
carpool.invitations
|
carpool.invitations
|
||||||
.filter((invitation) => !invitation.isRequest)
|
.filter((invitation) => !invitation.isRequest)
|
||||||
|
.valueSeq()
|
||||||
.map((invitation) => invitation.user.id)
|
.map((invitation) => invitation.user.id)
|
||||||
),
|
),
|
||||||
[carpool.invitations]
|
[carpool.invitations]
|
||||||
|
@ -68,11 +69,9 @@ export default function InvitationList() {
|
||||||
|
|
||||||
const availableSignupsAlreadyInvited = useMemo(
|
const availableSignupsAlreadyInvited = useMemo(
|
||||||
() =>
|
() =>
|
||||||
availableSignups
|
availableSignups?.filter((signup) =>
|
||||||
? availableSignups.filter((signup) =>
|
|
||||||
invitedUserIDs.has(signup.user.id)
|
invitedUserIDs.has(signup.user.id)
|
||||||
)
|
) ?? null,
|
||||||
: null,
|
|
||||||
[availableSignups, invitedUserIDs]
|
[availableSignups, invitedUserIDs]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -18,22 +18,13 @@ function MemberRow({ member }: { member: { id: number; name: string } }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function MemberList({
|
const shownMembersCount = 2;
|
||||||
members,
|
|
||||||
}: {
|
|
||||||
members: {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
}[];
|
|
||||||
}) {
|
|
||||||
const { leave, carpool } = useContext(CarpoolContext);
|
|
||||||
const membersToShow = members.slice(0, 2);
|
|
||||||
const hiddenMemberCount = members.length - membersToShow.length;
|
|
||||||
const me = useMe()!;
|
|
||||||
|
|
||||||
const isMember = useMemo(() => {
|
export default function MemberList() {
|
||||||
return members.some(({ id }) => id === me.id);
|
const { leave, carpool } = useContext(CarpoolContext);
|
||||||
}, [me.id, members]);
|
const members = carpool.members;
|
||||||
|
const membersToShow = members.slice(0, shownMembersCount);
|
||||||
|
const hiddenMemberCount = members.size - membersToShow.size;
|
||||||
|
|
||||||
const { sendCarpoolRequest, cancelCarpoolRequest } =
|
const { sendCarpoolRequest, cancelCarpoolRequest } =
|
||||||
useContext(NotificationsContext);
|
useContext(NotificationsContext);
|
||||||
|
@ -47,6 +38,12 @@ export default function MemberList({
|
||||||
cancelCarpoolRequest(carpool.id);
|
cancelCarpoolRequest(carpool.id);
|
||||||
}, [carpool.id, cancelCarpoolRequest]);
|
}, [carpool.id, cancelCarpoolRequest]);
|
||||||
|
|
||||||
|
const me = useMe()!;
|
||||||
|
|
||||||
|
const isMember = useMemo(() => {
|
||||||
|
return members.some(({ id }) => id === me?.id);
|
||||||
|
}, [me?.id, members]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
|
@ -57,7 +54,7 @@ export default function MemberList({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<h3 style={{ marginBlockEnd: '0' }}>Members</h3>
|
<h3 style={{ marginBlockEnd: '0' }}>Members</h3>
|
||||||
{members.length > 0 ? (
|
{members.size > 0 ? (
|
||||||
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
||||||
{membersToShow.map((member) => (
|
{membersToShow.map((member) => (
|
||||||
<MemberRow member={member} key={member.id} />
|
<MemberRow member={member} key={member.id} />
|
||||||
|
|
Loading…
Reference in New Issue
Block a user