Skip to content

Commit

Permalink
allow Organizers to check in workshop leads if they are hackers/mento…
Browse files Browse the repository at this point in the history
…rs/volunteers as well (#607)
  • Loading branch information
waalbert authored Jan 26, 2025
1 parent 85308f2 commit 11afeeb
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 20 deletions.
10 changes: 4 additions & 6 deletions apps/api/src/admin/participant_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@

Checkin: TypeAlias = tuple[datetime, str]

NON_HACKER_ROLES = (
Role.MENTOR,
Role.VOLUNTEER,
OUTSIDE_ROLES = (
Role.SPONSOR,
Role.JUDGE,
Role.WORKSHOP_LEAD,
Expand Down Expand Up @@ -111,12 +109,12 @@ async def check_in_participant(uid: str, associate: User) -> None:
log.info(f"Applicant {uid} checked in by {associate.uid}")


async def confirm_attendance_non_hacker(uid: str, director: User) -> None:
"""Update status from WAIVER_SIGNED to ATTENDING for non-hackers."""
async def confirm_attendance_outside_participants(uid: str, director: User) -> None:
"""Update status from WAIVER_SIGNED to ATTENDING for outside participants."""

record: Optional[dict[str, object]] = await mongodb_handler.retrieve_one(
Collection.USERS,
{"_id": uid, "roles": {"$in": NON_HACKER_ROLES}},
{"_id": uid, "roles": {"$in": OUTSIDE_ROLES}},
["status"],
)

Expand Down
4 changes: 2 additions & 2 deletions apps/api/src/routers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -363,9 +363,9 @@ async def update_attendance(
User, Depends(require_role({Role.DIRECTOR, Role.CHECKIN_LEAD}))
],
) -> None:
"""Update status to Role.ATTENDING for non-hackers."""
"""Update status to Role.ATTENDING for outside participants."""
try:
await participant_manager.confirm_attendance_non_hacker(uid, director)
await participant_manager.confirm_attendance_outside_participants(uid, director)
except ValueError:
raise HTTPException(status.HTTP_404_NOT_FOUND)
except RuntimeError as err:
Expand Down
4 changes: 2 additions & 2 deletions apps/site/src/app/admin/participants/Participants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function Participants() {
loading,
checkInParticipant,
releaseParticipantFromWaitlist,
confirmNonHacker,
confirmOutsideParticipants,
} = useParticipants();
const [checkinParticipant, setCheckinParticipant] =
useState<Participant | null>(null);
Expand Down Expand Up @@ -129,7 +129,7 @@ function Participants() {
loading={loading}
initiateCheckIn={initiateCheckIn}
initiatePromotion={initiatePromotion}
initiateConfirm={confirmNonHacker}
initiateConfirm={confirmOutsideParticipants}
/>
<CheckInModal
onDismiss={() => setCheckinParticipant(null)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,25 @@ import { ParticipantRole, ReviewStatus, Status } from "@/lib/userRecord";

import ParticipantActionPopover from "./ParticipantActionPopover";

const OUTSIDE_ROLES = [ParticipantRole.Judge, ParticipantRole.Sponsor];
const JUDGE_SPONSOR_ROLES = [ParticipantRole.Judge, ParticipantRole.Sponsor];
const HACKER_MENTOR_VOLUNTEER_ROLES = [
ParticipantRole.Hacker,
ParticipantRole.Mentor,
ParticipantRole.Volunteer,
];

export function isOutsideParticipant(roles: ReadonlyArray<ParticipantRole>) {
return roles.some((role) => OUTSIDE_ROLES.includes(role));
export function isJudgeSponsorParticipant(
roles: ReadonlyArray<ParticipantRole>,
) {
return roles.some((role) => JUDGE_SPONSOR_ROLES.includes(role));
}

function isWorkshopLead(roles: ReadonlyArray<ParticipantRole>) {
return roles.includes(ParticipantRole.WorkshopLead);
}

function isHackerMentorVolunteer(roles: ReadonlyArray<ParticipantRole>) {
return roles.some((role) => HACKER_MENTOR_VOLUNTEER_ROLES.includes(role));
}

interface ParticipantActionProps {
Expand All @@ -33,7 +48,9 @@ function ParticipantAction({
const canPromote = isCheckInLead(roles);
const isWaiverSigned = participant.status === Status.signed;
const isAccepted = participant.status === Status.accepted;
const outsideParticipant = isOutsideParticipant(participant.roles);
const judgeSponsorParticipant = isJudgeSponsorParticipant(participant.roles);
const hackerMentorVolunteer = isHackerMentorVolunteer(participant.roles);
const workshopLead = isWorkshopLead(participant.roles);

const promoteButton = (
<Button
Expand Down Expand Up @@ -68,9 +85,9 @@ function ParticipantAction({
</Button>
);

if (outsideParticipant) {
if (judgeSponsorParticipant) {
const content = !canPromote
? "Only check-in leads can confirm outside participants."
? "Only check-in leads can confirm judges and sponsors."
: "Must sign waiver first.";
if (!canPromote || participant.status === ReviewStatus.reviewed) {
return (
Expand All @@ -91,7 +108,7 @@ function ParticipantAction({
);
}
return promoteButton;
} else if (isWaiverSigned || isAccepted) {
} else if (hackerMentorVolunteer && (isWaiverSigned || isAccepted)) {
const content = isWaiverSigned
? "Must confirm attendance in portal first"
: "Must sign waiver and confirm attendance in portal";
Expand All @@ -100,6 +117,21 @@ function ParticipantAction({
{checkinButton}
</ParticipantActionPopover>
);
} else if (!hackerMentorVolunteer && workshopLead) {
// participants that are just workshop leads
const content = !canPromote
? "Only check-in leads can confirm workshop leads without any other roles."
: "Must sign waiver first.";
if (!canPromote || participant.status === ReviewStatus.reviewed) {
return (
<ParticipantActionPopover content={content}>
{confirmButton}
</ParticipantActionPopover>
);
} else if (participant.status === Status.signed) {
return confirmButton;
}
return checkinButton;
}
return checkinButton;
}
Expand Down
6 changes: 3 additions & 3 deletions apps/site/src/lib/admin/useParticipants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ function useParticipants() {
mutate();
};

const confirmNonHacker = async (participant: Participant) => {
console.log("Confirmed attendance for non-hacker", participant);
const confirmOutsideParticipants = async (participant: Participant) => {
console.log("Confirmed attendance for outside participants", participant);
await axios.post(`/api/admin/update-attendance/${participant._id}`);
mutate();
};
Expand All @@ -54,7 +54,7 @@ function useParticipants() {
error,
checkInParticipant,
releaseParticipantFromWaitlist,
confirmNonHacker,
confirmOutsideParticipants,
};
}

Expand Down

0 comments on commit 11afeeb

Please sign in to comment.