Skip to content

Commit

Permalink
#12 Extract invite and join buttons and modals into components
Browse files Browse the repository at this point in the history
  • Loading branch information
varunsingh87 committed Jan 17, 2024
1 parent 4817550 commit 8da1c5a
Show file tree
Hide file tree
Showing 3 changed files with 185 additions and 130 deletions.
146 changes: 16 additions & 130 deletions Components/Teams.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,12 @@
import {
Button,
Col,
Input,
Label,
List,
ListInlineItem,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
Row,
} from 'reactstrap'
import { useMutation, useQuery } from 'convex/react'
import { Col, List, ListInlineItem, Row } from 'reactstrap'
import { useQuery } from 'convex/react'
import { api } from '../convex/_generated/api'
import { useState } from 'react'
import InvitesAndJoinRequests from './authenticated/UserInvites'
import { Id } from '../convex/_generated/dataModel'
import InviteButton from './team/InviteButton'
import JoinRequestButton from './team/JoinRequestButton'

export default function Teams(props: any) {
const teamList = useQuery(api.team.list, props)
const participant = useQuery(api.participant.readParticipant, props)
const requestJoin = useMutation(api.participant.requestJoin)
const invite = useMutation(api.participant.inviteToTeam)
const [joinButtonMessage, setJoinButtonMessage] = useState('Join Team')
const [inviteButtonMessage, setInviteBtnMsg] = useState('Invite to Team')

const handleJoinClick = (id: Id<'teams'>) => {
setRequestJoinModal(false)
requestJoin({ id })
setJoinButtonMessage('Join requested!')
}

const handleJoinModalOpen = () => {
setRequestJoinModal(true)
}

const [modal, setModal] = useState(false)
const [requestJoinModal, setRequestJoinModal] = useState(false)

const handleInviteClick = (joinerId: Id<'users'>) => {
setModal(false)
invite({ joinerId, competitionId: props.competitionId })
setInviteBtnMsg('Invite sent!')
}

const handleInviteModalOpen = () => {
setModal(true)
}

const toggle = () => setModal(!modal)

const toggleJoinRequestModal = () => setRequestJoinModal(!requestJoinModal)

return (
<Row>
Expand All @@ -59,99 +15,29 @@ export default function Teams(props: any) {
</Col>
<Col md={6}>
<List className="p-0">
{teamList?.map((item) => (
<li key={item._id} className="border p-2 m-1 list-unstyled">
{teamList?.map((team) => (
<li key={team._id} className="border p-2 m-1 list-unstyled">
<List className="mb-4">
{item.members.map((member) => (
{team.members.map((member) => (
<ListInlineItem>
<img
src={member.pictureURL}
width={50}
alt={'Profile picture of ' + member.name}
/>{' '}
{member.name}
<Button
className="ms-2"
color="primary"
hidden={
participant &&
participant.userMembership.team == item._id
}
onClick={handleInviteModalOpen}
>
{inviteButtonMessage}
</Button>
<Modal isOpen={modal} toggle={toggle}>
<ModalHeader toggle={toggle}>
Invite {member.name}
</ModalHeader>
<ModalBody>
<Label>
A polite, helpful message will help this participant
decide if this team is a good fit
</Label>
<Input
type="text"
placeholder="Make sure to include contact information"
/>
</ModalBody>
<ModalFooter>
<Button
color="primary"
onClick={() => handleInviteClick(member.user._id)}
>
Invite
</Button>{' '}
<Button color="secondary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
<Modal
isOpen={requestJoinModal}
toggle={toggleJoinRequestModal}
>
<ModalHeader toggle={toggleJoinRequestModal}>
Request to Join
</ModalHeader>
<ModalBody>
<Label>
Pitch your skills and interests to this team to
persuade them to let you join them
</Label>
<Input
type="text"
placeholder="Make sure to include contact information"
/>
</ModalBody>
<ModalFooter>
<Button
color="primary"
onClick={() => handleJoinClick(item._id)}
>
Join
</Button>{' '}
<Button
color="secondary"
onClick={toggleJoinRequestModal}
>
Cancel
</Button>
</ModalFooter>
</Modal>
<InviteButton
competitionId={props.competitionId}
joiner={member}
teamOfJoiner={team}
/>
</ListInlineItem>
))}
</List>
<Button
hidden={
participant && participant.userMembership.team == item._id
}
disabled={!participant}
color="primary"
onClick={handleJoinModalOpen}
>
{joinButtonMessage}
</Button>
<JoinRequestButton
competitionId={props.competitionId}
teamId={team._id}
/>
</li>
))}
</List>
Expand Down
89 changes: 89 additions & 0 deletions Components/team/InviteButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {
Button,
Input,
Label,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
} from 'reactstrap'
import { Doc, Id } from '../../convex/_generated/dataModel'
import { useState } from 'react'
import { useMutation, useQuery } from 'convex/react'
import { api } from '../../convex/_generated/api'
import { PersonFill, PersonPlus } from 'react-bootstrap-icons'

/**
* Invite button for team joining in competitions
* @param competitionId The competition in which this team switch request is getting made
* @param inviter The team and user data corresponding to the user who is sending the invitation
* @param joiner The user who is getting invited to a new team
* @param teamOfJoiner The team of the joiner
* @constructor
*/
export default function InviteButton({
competitionId,
joiner,
teamOfJoiner,
}: {
competitionId: Id<'competitions'>
joiner: Doc<'users'>
teamOfJoiner: any
}) {
const invite = useMutation(api.participant.inviteToTeam)
const [inviteButtonMessage, setInviteBtnMsg] = useState('Invite to Team')

const [modal, setModal] = useState(false)
const handleInviteClick = (joinerId: Id<'users'>) => {
setModal(false)
invite({ joinerId, competitionId })
setInviteBtnMsg('Invite sent!')
}
const inviter = useQuery(api.participant.readParticipant, {
competitionId,
})

const handleInviteModalOpen = () => {
setModal(true)
}

const toggle = () => setModal(!modal)

return (
<div>
<Button
className="mt-2"
color="primary"
hidden={
!inviter ||
teamOfJoiner._id == inviter._id ||
teamOfJoiner.members.length > 1
}
onClick={handleInviteModalOpen}
>
<PersonPlus />
</Button>
<Modal isOpen={modal} toggle={toggle}>
<ModalHeader toggle={toggle}>Invite {joiner.name}</ModalHeader>
<ModalBody>
<Label>
A polite, helpful message will help this participant decide if this
team is a good fit
</Label>
<Input
type="text"
placeholder="Make sure to include contact information"
/>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleInviteClick(joiner._id)}>
Invite
</Button>{' '}
<Button color="secondary" onClick={toggle}>
Cancel
</Button>
</ModalFooter>
</Modal>
</div>
)
}
80 changes: 80 additions & 0 deletions Components/team/JoinRequestButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
Button,
Input,
Label,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
} from 'reactstrap'
import { useState } from 'react'
import { Id } from '../../convex/_generated/dataModel'
import { useMutation, useQuery } from 'convex/react'
import { api } from '../../convex/_generated/api'

export default function JoinRequestButton({
competitionId,
teamId,
}: {
competitionId: Id<'competitions'>
teamId: Id<'teams'>
}) {
const [joinButtonMessage, setJoinButtonMessage] = useState('Join Team')
const joiner = useQuery(api.participant.readParticipant, {
competitionId,
})
const requestJoin = useMutation(api.participant.requestJoin)

const [requestJoinModal, setRequestJoinModal] = useState(false)

const toggleJoinRequestModal = () => setRequestJoinModal(!requestJoinModal)
const handleJoinClick = (id: Id<'teams'>) => {
setRequestJoinModal(false)
requestJoin({ id })
setJoinButtonMessage('Join requested!')
}

const handleJoinModalOpen = () => {
setRequestJoinModal(true)
}
return (
<div>
<Modal isOpen={requestJoinModal} toggle={toggleJoinRequestModal}>
<ModalHeader toggle={toggleJoinRequestModal}>
Request to Join
</ModalHeader>
<ModalBody>
<Label>
Pitch your skills and interests to this team to persuade them to let
you join them
</Label>
<Input
type="text"
placeholder="Make sure to include contact information"
/>
</ModalBody>
<ModalFooter>
<Button color="primary" onClick={() => handleJoinClick(teamId)}>
Join
</Button>{' '}
<Button color="secondary" onClick={toggleJoinRequestModal}>
Cancel
</Button>
</ModalFooter>
</Modal>
<Button
hidden={
!joiner ||
/* Can't join his/her own team */
joiner.userMembership.team == teamId ||
/* Can't join another team when the current user is committed to a team */
joiner.members.length > 1
}
color="primary"
onClick={handleJoinModalOpen}
>
{joinButtonMessage}
</Button>
</div>
)
}

0 comments on commit 8da1c5a

Please sign in to comment.