Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"use client";

import React, { useState } from "react";
import { Button } from "@/components/ui/button";
import { X } from "lucide-react";
import ConfirmationDialog from "@/components/common/ConfirmationDialog";
import callServerAction from "@/services/helpers/server/callServerAction";
import deleteSponsorJudging from "@/server/actions/dashboard/judging/deleteSponsorJudging";

type DeleteSponsorJudgingButtonProps = {
sponsorJudgingId: number;
};

const DeleteSponsorJudgingButton = ({
sponsorJudgingId,
}: DeleteSponsorJudgingButtonProps) => {
const [error, setError] = useState<string | null>(null);

return (
<>
<ConfirmationDialog
question="Remove this judging assignment?"
onAnswer={async (answer) => {
if (!answer) return;
const res = await callServerAction(deleteSponsorJudging, {
sponsorJudgingId,
});
if (!res.success) setError(res.message);
}}
>
<Button
variant="ghost"
size="small"
className="text-red-500 hover:text-red-700 p-0 h-auto"
>
<X className="h-3 w-3" />
</Button>
</ConfirmationDialog>
{error && <p className="text-xs text-red-500 mt-1">{error}</p>}
</>
);
};

export default DeleteSponsorJudgingButton;
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import AutoAssignButton from "./AutoAssignButton";
import AutoAssignSponsorButton from "./AutoAssignSponsorButton";
import ReassignJudgeDialog from "./ReassignJudgeDialog";
import DeleteTeamJudgingButton from "./DeleteTeamJudgingButton";
import DeleteSponsorJudgingButton from "./DeleteSponsorJudgingButton";
import ExternalJudgeManager from "./ExternalJudgeManager";
import AssignTeamDialog from "./AssignTeamDialog";

Expand All @@ -30,6 +31,7 @@ type TeamJudgingRow = {
slotEnd: Date;
hasVerdict: boolean;
teamJudgingId?: number;
sponsorJudgingId?: number;
type: "organizer" | "sponsor";
}[];
};
Expand Down Expand Up @@ -100,6 +102,7 @@ const JudgingOverview = ({ hackathonId, data }: JudgingOverviewProps) => {
slotStart: slot.startTime,
slotEnd: slot.endTime,
hasVerdict: assignment.hasVerdict,
sponsorJudgingId: assignment.sponsorJudgingId,
type: "sponsor",
});
}
Expand Down Expand Up @@ -323,19 +326,31 @@ const JudgingOverview = ({ hackathonId, data }: JudgingOverviewProps) => {
</span>
<span>{ja.label}</span>
<span>{ja.hasVerdict ? "✓" : "pending"}</span>
{ja.type === "sponsor" &&
ja.sponsorJudgingId && (
<DeleteSponsorJudgingButton
sponsorJudgingId={ja.sponsorJudgingId}
/>
)}
{ja.type === "organizer" &&
ja.teamJudgingId && (
<ReassignJudgeDialog
teamJudgingId={ja.teamJudgingId}
currentJudgeId={
judges.find((j) => j.name === ja.label)
?.id ?? 0
}
judges={judges.map((j) => ({
id: j.id,
name: j.name,
}))}
/>
<>
<ReassignJudgeDialog
teamJudgingId={ja.teamJudgingId}
currentJudgeId={
judges.find(
(j) => j.name === ja.label
)?.id ?? 0
}
judges={judges.map((j) => ({
id: j.id,
name: j.name,
}))}
/>
<DeleteTeamJudgingButton
teamJudgingId={ja.teamJudgingId}
/>
</>
)}
</div>
))}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const ReassignJudgeDialog = ({
<SelectTrigger>
<SelectValue placeholder="Select a judge" />
</SelectTrigger>
<SelectContent>
<SelectContent className="max-h-[300px] overflow-y-auto">
{otherJudges.map((judge) => (
<SelectItem key={judge.id} value={String(judge.id)}>
{judge.name}
Expand Down
11 changes: 11 additions & 0 deletions src/server/actions/dashboard/judging/createSponsorJudging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ const createSponsorJudging = async ({
);
}

const existingForTeam = await prisma.sponsorJudging.findFirst({
where: { sponsorId, teamId },
select: { id: true },
});

if (existingForTeam) {
throw new ExpectedServerActionError(
"Sponsor is already assigned to judge this team"
);
}

await prisma.sponsorJudging.create({
data: { sponsorId, teamId, judgingSlotId },
});
Expand Down
Loading