-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#12 Extract invite and join buttons and modals into components
- Loading branch information
1 parent
4817550
commit 8da1c5a
Showing
3 changed files
with
185 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
) | ||
} |