diff --git a/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/DeleteSponsorJudgingButton.tsx b/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/DeleteSponsorJudgingButton.tsx new file mode 100644 index 0000000..f342886 --- /dev/null +++ b/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/DeleteSponsorJudgingButton.tsx @@ -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(null); + + return ( + <> + { + if (!answer) return; + const res = await callServerAction(deleteSponsorJudging, { + sponsorJudgingId, + }); + if (!res.success) setError(res.message); + }} + > + + + {error &&

{error}

} + + ); +}; + +export default DeleteSponsorJudgingButton; diff --git a/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/JudgingOverview.tsx b/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/JudgingOverview.tsx index 70144b8..2e887be 100644 --- a/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/JudgingOverview.tsx +++ b/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/JudgingOverview.tsx @@ -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"; @@ -30,6 +31,7 @@ type TeamJudgingRow = { slotEnd: Date; hasVerdict: boolean; teamJudgingId?: number; + sponsorJudgingId?: number; type: "organizer" | "sponsor"; }[]; }; @@ -100,6 +102,7 @@ const JudgingOverview = ({ hackathonId, data }: JudgingOverviewProps) => { slotStart: slot.startTime, slotEnd: slot.endTime, hasVerdict: assignment.hasVerdict, + sponsorJudgingId: assignment.sponsorJudgingId, type: "sponsor", }); } @@ -323,19 +326,31 @@ const JudgingOverview = ({ hackathonId, data }: JudgingOverviewProps) => { {ja.label} {ja.hasVerdict ? "✓" : "pending"} + {ja.type === "sponsor" && + ja.sponsorJudgingId && ( + + )} {ja.type === "organizer" && ja.teamJudgingId && ( - j.name === ja.label) - ?.id ?? 0 - } - judges={judges.map((j) => ({ - id: j.id, - name: j.name, - }))} - /> + <> + j.name === ja.label + )?.id ?? 0 + } + judges={judges.map((j) => ({ + id: j.id, + name: j.name, + }))} + /> + + )} ))} diff --git a/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/ReassignJudgeDialog.tsx b/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/ReassignJudgeDialog.tsx index dbcffad..74f0fde 100644 --- a/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/ReassignJudgeDialog.tsx +++ b/src/scenes/Dashboard/scenes/Judging/scenes/JudgingOverview/ReassignJudgeDialog.tsx @@ -86,7 +86,7 @@ const ReassignJudgeDialog = ({ - + {otherJudges.map((judge) => ( {judge.name} diff --git a/src/server/actions/dashboard/judging/createSponsorJudging.ts b/src/server/actions/dashboard/judging/createSponsorJudging.ts index 4bde742..8f82fcf 100644 --- a/src/server/actions/dashboard/judging/createSponsorJudging.ts +++ b/src/server/actions/dashboard/judging/createSponsorJudging.ts @@ -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 }, });