-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implement duplicate contest (#1950)
* feat(be): add duplicate contest api * feat(fe): add duplicatecontest alertdialog component * fix(fe): change copyicon, copyCompleteIcon misusage * feat(fe): connect duplicateContest api * feat(fe): duplicate contest feature * feat(fe): fix duplicate contest modal design * fix(be): change groupId, contestId * feat(fe): reload after duplicate contest, toast * fix(fe): add newVisible to contest api * docs(be): add subquery to duplicatecontest api * feat(be): apply transaction * chore(be): disable duplicate contest test --------- Co-authored-by: Jaehyeon Kim <[email protected]> Co-authored-by: Jaehyeon Kim <[email protected]>
- Loading branch information
1 parent
a581ef5
commit 2544667
Showing
11 changed files
with
529 additions
and
52 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
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
16 changes: 16 additions & 0 deletions
16
apps/backend/apps/admin/src/contest/model/duplicated-contest-response.output.ts
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,16 @@ | ||
import { Field, ObjectType } from '@nestjs/graphql' | ||
import { Type } from 'class-transformer' | ||
import { Contest, ContestProblem, ContestRecord } from '@admin/@generated' | ||
|
||
@ObjectType() | ||
export class DuplicatedContestResponse { | ||
@Field(() => Contest) | ||
contest: Contest | ||
|
||
@Field(() => [ContestProblem]) | ||
problems: ContestProblem[] | ||
|
||
@Field(() => [ContestRecord]) | ||
@Type(() => ContestRecord) | ||
records: ContestRecord[] | ||
} |
124 changes: 124 additions & 0 deletions
124
apps/frontend/app/admin/contest/_components/DuplicateContest.tsx
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,124 @@ | ||
'use client' | ||
|
||
import { | ||
AlertDialog, | ||
AlertDialogTrigger, | ||
AlertDialogContent, | ||
AlertDialogHeader, | ||
AlertDialogTitle, | ||
AlertDialogDescription, | ||
AlertDialogFooter, | ||
AlertDialogCancel, | ||
AlertDialogAction | ||
} from '@/components/ui/alert-dialog' | ||
import { Button } from '@/components/ui/button' | ||
import { DUPLICATE_CONTEST } from '@/graphql/contest/mutations' | ||
import { useMutation } from '@apollo/client' | ||
import { CopyIcon } from 'lucide-react' | ||
import { useRouter } from 'next/navigation' | ||
import { toast } from 'sonner' | ||
|
||
export default function DuplicateContest({ | ||
groupId, | ||
contestId, | ||
contestStatus | ||
}: { | ||
groupId: number | ||
contestId: number | ||
contestStatus: string | ||
}) { | ||
const router = useRouter() | ||
const [duplicateContest, { error }] = useMutation(DUPLICATE_CONTEST) | ||
|
||
const duplicateContestById = async () => { | ||
if (error) { | ||
console.error(error) | ||
return | ||
} | ||
const toastId = toast.loading('Duplicating contest...') | ||
|
||
const res = await duplicateContest({ | ||
variables: { | ||
groupId, | ||
contestId | ||
} | ||
}) | ||
|
||
if (res.data?.duplicateContest.contest) { | ||
toast.success( | ||
`Contest duplicated completed.\n Duplicated contest title: ${res.data.duplicateContest.contest.title}`, | ||
{ | ||
id: toastId | ||
} | ||
) | ||
} | ||
router.refresh() | ||
} | ||
|
||
return ( | ||
<div> | ||
<AlertDialog> | ||
<AlertDialogTrigger asChild> | ||
<Button variant="default" size="default"> | ||
<CopyIcon className="mr-2 h-4 w-4" /> | ||
Duplicate | ||
</Button> | ||
</AlertDialogTrigger> | ||
<AlertDialogContent className="border-slate-80 border bg-white"> | ||
<AlertDialogHeader> | ||
<AlertDialogTitle className="text-xl font-bold text-black"> | ||
Duplicate {contestStatus === 'ongoing' ? 'Ongoing ' : ''}Contest | ||
</AlertDialogTitle> | ||
<AlertDialogDescription className="text-neutral-500"> | ||
<p className="font-semibold">Contents That Will Be Copied:</p> | ||
<ul className="mb-3 ml-5 list-disc"> | ||
<li>Title</li> | ||
<li>Start Time & End Time</li> | ||
<li>Description</li> | ||
<li> | ||
Contest Security Settings (invitation code, allow copy/paste) | ||
</li> | ||
<li>Contest Problems</li> | ||
<li className="text-red-500"> | ||
Participants of the selected contest <br /> | ||
<span className="text-xs"> | ||
(All participants of the selected contest will be | ||
automatically registered for the duplicated contest.) | ||
</span> | ||
</li> | ||
</ul> | ||
<p className="font-semibold">Contents That Will Not Be Copied:</p> | ||
<ul className="mb-3 ml-5 list-disc"> | ||
<li>Users' Submissions</li> | ||
</ul> | ||
{contestStatus === 'ongoing' ? ( | ||
<p className="mb-3 mt-4 text-red-500"> | ||
Caution: The new contest will be set to visible. | ||
</p> | ||
) : ( | ||
<p className="mb-3 mt-4 text-red-500"> | ||
Caution: The new contest will be set to invisible | ||
</p> | ||
)} | ||
<p className="mt-4"> | ||
Are you sure you want to proceed with duplicating the selected | ||
contest? | ||
</p> | ||
</AlertDialogDescription> | ||
</AlertDialogHeader> | ||
<AlertDialogFooter className="flex justify-end gap-2"> | ||
<AlertDialogCancel className="rounded-md px-4 py-2"> | ||
Cancel | ||
</AlertDialogCancel> | ||
<AlertDialogAction | ||
className="rounded-md bg-blue-500 px-4 py-2 text-white" | ||
onClick={duplicateContestById} | ||
> | ||
Duplicate | ||
</AlertDialogAction> | ||
</AlertDialogFooter> | ||
</AlertDialogContent> | ||
</AlertDialog> | ||
</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
Oops, something went wrong.